diff --git a/.dir-locals.el b/.dir-locals.el index bd65e5345441f..feea22ea295c1 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -2,7 +2,7 @@ ; ; This source file is part of the Swift.org open source project ; -; Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +; Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ; Licensed under Apache License v2.0 with Runtime Library Exception ; ; See http://swift.org/LICENSE.txt for license information diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000..46ccb95c0fde1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5342 @@ +Latest +------ + +* The ++ and -- operators have been deprecated, and are slated to be removed in + Swift 3.0. As a replacement, please use "x += 1" on integer or floating point + types, and "x = x.successor()" on Index types. + +* The operator identifier lexer grammar has been revised to simplify the rules + for operators that start with a dot ("."). The new rule is that an operator + that starts with a dot may contain other dots in it, but operators that start + with some other character may not contain dots. For example: + + ``` + x....foo --> "x" "...." "foo" + x&%^.foo --> "x" "&%^" ".foo" + ``` + + This eliminates a special case for the ..< operator, folding it into a simple + and consistent rule. + +* The "C-style for loop", which is spelled `for init; comparison; increment {}` + has been deprecated and is slated for removal in Swift 3.0. See + [SE-0007](https://github.com/apple/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md) + for more information. + +* Three new doc comment fields, namely `- keyword:`, `- recommended:` + and `- recommendedover:`, allow Swift users to cooperate with code + completion engine to deliver more effective code completion results. + The `- keyword:` field specifies concepts that are not fully manifested in + declaration names. `- recommended:` indicates other declarations are preferred + to the one decorated; to the contrary, `- recommendedover:` indicates + the decorated declaration is preferred to those declarations whose names + are specified. + +* Designated class initializers declared as failable or throwing may now + return nil or throw an error, respectively, before the object has been + fully initialized. For example: + + ```swift + class Widget : Gadget { + let complexity: Int + + init(complexity: Int, elegance: Int) throws { + if complexity > 3 { throw WidgetError.TooComplex } + self.complexity = complexity + + try super.init(elegance: elegance) + } + } + ``` + +* All slice types now have `removeFirst()` and `removeLast()` methods. + +* `ArraySlice.removeFirst()` now preserves element indices. + +* Global `anyGenerator()` functions have been changed into initializers on + `AnyGenerator`, making the API more intuitive and idiomatic. They have been + deprecated in Swift 2.2, and will be removed in Swift 3. + +* Closures appearing inside generic types and generic methods can now be + converted to C function pointers as long as no generic type parameters + are referenced in the closure's argument list or body. A conversion of + a closure that references generic type parameters now produces a + diagnostic instead of crashing. + + **(rdar://problem/22204968)** + +* Anonymously-typed members of C structs and unions can now be accessed + from Swift. For example, given the following struct 'Pie', the 'crust' + and 'filling' members are now imported: + + ```swift + struct Pie { + struct { bool crispy; } crust; + union { int fruit; } filling; + } + ``` + + Since Swift does not support anonymous structs, these fields are + imported as properties named `crust` and `filling` having nested types + named `Pie.__Unnamed_crust` and `Pie.__Unnamed_filling`. + + **(rdar://problem/21683348)** + +* Argument labels and parameter names can now be any keyword except + `var`, `let`, or `inout`. For example: + + NSURLProtectionSpace(host: "somedomain.com", port: 443, protocol: "https", realm: "Some Domain", authenticationMethod: "Basic") + + would previously have required `protocol` to be surrounded in + back-ticks. For more information, see + [SE-0001](https://github.com/apple/swift-evolution/blob/master/proposals/0001-keywords-as-argument-labels.md). + +* Tuples (up to arity 6) whose elements are all `Comparable` or `Equatable` now + implement the full set of comparison/equality operators. The comparison + operators are defined in terms of [lexicographical order][]. See [SE-0015][] + for more information. + +[lexicographical order]: https://en.wikipedia.org/wiki/Lexicographical_order +[SE-0015]: https://github.com/apple/swift-evolution/blob/master/proposals/0015-tuple-comparison-operators.md + +* The `@objc(SomeName)` attribute is now supported on enums and enum cases to + rename the generated Objective-C declaration. + + **(rdar://problem/21930334)** + +2015-09-17 [Xcode 7.1, Swift 2.1] +---------- + +* Enums imported from C now automatically conform to the `Equatable` protocol, + including a default implementation of the `==` operator. This conformance + allows you to use C enum pattern matching in switch statements with no + additional code. **(17287720)** + +* The `NSNumber.unsignedIntegerValue` property now has the type `UInt` instead + of `Int`, as do other methods and properties that use the `NSUInteger` type + in Objective-C and whose names contain `unsigned..`. Most other uses of + `NSUInteger` in system frameworks are imported as `Int` as they were in + Xcode 7. **(19134055)** + +* Field getters and setters are now created for named unions imported from C. + In addition, an initializer with a named parameter for the field is provided. + For example, given the following Objective-C `typedef`: + + ```objc + typedef union IntOrFloat { + int intField; + float floatField; + } IntOrFloat; + ``` + + Importing this `typedef` into Swift generates the following interface: + + ```swift + struct IntOrFloat { + var intField: Int { get set } + init(intField: Int) + + var floatField: Float { get set } + init(floatField: Float) + } + ``` + + **(19660119)** + +* Bitfield members of C structs are now imported into Swift. **(21702107)** + +* The type `dispatch_block_t` now refers to the type + `@convention(block) () -> Void`, as it did in Swift 1.2. + This change allows programs using `dispatch_block_create` to work as expected, + solving an issue that surfaced in Xcode 7.0 with Swift 2.0. + + **Note:** Converting to a Swift closure value and back is not guaranteed to + preserve the identity of a `dispatch_block_t`. + **(22432170)** + +* Editing a file does not trigger a recompile of files that depend upon it if + the edits only modify declarations marked private. **(22239821)** + +* Expressions interpolated in strings may now contain string literals. + For example, `My name is \(attributes["name"]!)` is now a valid expression. + **(14050788)** + +* Error messages produced when the type checker cannot solve its constraint + system continue to improve in many cases. + + For example, errors in the body of generic closures (for instance, the + argument closure to `map`) are much more usefully diagnosed. **(18835890)** + +* Conversions between function types are supported, exhibiting covariance in + function result types and contravariance in function parameter types. + For example, it is legal to assign a function of type `Any -> Int` to a + variable of type `String -> Any`. **(19517003)** + + +2015-09-17 [Xcode 7.0, Swift 2] +---------- + +## Swift Language Features + +* New `defer` statement. This statement runs cleanup code when the scope is + exited, which is particularly useful in conjunction with the new error + handling model. For example: + + ```swift + func xyz() throws { + let f = fopen("x.txt", "r") + defer { fclose(f) } + try foo(f) // f is closed if an error is propagated. + let f2 = fopen("y.txt", "r") + defer { fclose(f2) } + try bar(f, f2) // f2 is closed, then f is closed if an error is propagated. + } // f2 is closed, then f is closed on a normal path + ``` + + **(17302850)** + +* Printing values of certain `enum` types shows the enum `case` and payload, if + any. This is not supported for `@objc` enums or certain enums with multiple + payloads. **(18334936)** + +* You can specify availability information on your own declarations with the + `@available()` attribute. + + For example: + + ```swift + @available(iOS 8.0, OSX 10.10, *) + func startUserActivity() -> NSUserActivity { + ... + } + ``` + + This code fragment indicates that the `startUserActivity()` method is + available on iOS 8.0+, on OS X v10.10+, and on all versions of any other + platform. **(20938565)** + +* A new `@nonobjc` attribute is introduced to selectively suppress ObjC export + for instance members that would otherwise be `@objc`. **(16763754)** + +* Nongeneric classes may now inherit from generic classes. **(15520519)** + +* Public extensions of generic types are now permitted. + + ```swift + public extension Array { … } + ``` + + **(16974298)** + +* Enums now support multiple generic associated values, for example: + + ```swift + enum Either { + case Left(T), Right(U) + } + ``` + + **(15666173)** + +* **Protocol extensions**: Extensions can be written for protocol types. + With these extensions, methods and properties can be added to any type that + conforms to a particular protocol, allowing you to reuse more of your code. + This leads to more natural caller side "dot" method syntax that follows the + principle of "fluent interfaces" and that makes the definition of generic + code simpler (reducing "angle bracket blindness"). **(11735843)** + +* **Protocol default implementations**: Protocols can have default + implementations for requirements specified in a protocol extension, allowing + "mixin" or "trait" like patterns. + +* **Availability checking**. Swift reports an error at compile time if you call an + API that was introduced in a version of the operating system newer than the + currently selected deployment target. + + To check whether a potentially unavailable API is available at runtime, use + the new `#available()` condition in an if or guard statement. For example: + + ```swift + if #available(iOS 8.0, OSX 10.10, *) { + // Use Handoff APIs when available. + let activity = + NSUserActivity(activityType:"com.example.ShoppingList.view") + activity.becomeCurrent() + } else { + // Fall back when Handoff APIs not available. + } + ``` + + **(14586648)** + +* Native support for C function pointers: C functions that take function pointer + arguments can be called using closures or global functions, with the + restriction that the closure must not capture any of its local context. + For example, the standard C qsort function can be invoked as follows: + + ```swift + var array = [3, 14, 15, 9, 2, 6, 5] + qsort(&array, array.count, sizeofValue(array[0])) { a, b in + return Int32(UnsafePointer(a).memory - UnsafePointer(b).memory) + } + print(array) + ``` + + **(16339559)** + +* **Error handling**. You can create functions that `throw`, `catch`, and manage + errors in Swift. + + Using this capability, you can surface and deal with recoverable + errors, such as "file-not-found" or network timeouts. Swift's error handling + interoperates with `NSError`. **(17158652)** + +* **Testability**: Tests of Swift 2.0 frameworks and apps are written without + having to make internal routines public. + + Use `@testable import {ModuleName}` in your test source code to make all + public and internal routines usable. The app or framework target needs to be + compiled with the `Enable Testability` build setting set to `Yes`. The `Enable + Testability` build setting should be used only in your Debug configuration, + because it prohibits optimizations that depend on not exporting internal + symbols from the app or framework. **(17732115)** + +* if statements can be labeled, and labeled break statements can be used as a + jump out of the matching if statement. + + An unlabeled break does not exit the if statement. It exits the enclosing + loop or switch statement, or it is illegal if none exists. (19150249) + +* A new `x?` pattern can be used to pattern match against optionals as a + synonym for `.Some(x)`. **(19382878)** + +* Concatenation of Swift string literals, including across multiple lines, is + now a guaranteed compile-time optimization, even at `-Onone`. **(19125926)** + +* Nested functions can now recursively reference themselves and other nested + functions. **(11266246)** + +* Improved diagnostics: + - A warning has been introduced to encourage the use of let instead of var + when appropriate. + - A warning has been introduced to signal unused variables. + - Invalid mutation diagnostics are more precise. + - Unreachable switch cases cause a warning. + - The switch statement "exhaustiveness checker" is smarter. + **(15975935,20130240)** + +* Failable convenience initializers are allowed to return `nil` before calling + `self.init`. + + Designated initializers still must initialize all stored properties before + returning `nil`; this is a known limitation. **(20193929)** + +* A new `readLine()` function has been added to the standard library. + **(15911365)** + +* **SIMD Support**: Clang extended vectors are imported and usable in Swift. + + This capability enables many graphics and other low-level numeric APIs + (for example, `simd.h`) to be usable in Swift. + +* New `guard` statement: This statement allows you to model an early exit out + of a scope. + + For example: + + ```swift + guard let z = bar() else { return } + use(z) + ``` + + The `else` block is required to exit the scope (for example, with `return`, + `throw`, `break`, `continue`, and so forth) or end in a call to a `@noreturn` + function. **(20109722)** + +* Improved pattern matching: `switch`/`case` pattern matching is available to + many new conditional control flow statements, including `if`/`case`, + `while`/`case`, `guard`/`case`, and `for-in`/`case`. `for-in` statements can + also have `where` clauses, which combine to support many of the features of + list comprehensions in other languages. + +* A new `do` statement allows scopes to be introduced with the `do` statement. + + For example: + + ```swift + do { + //new scope + do { + //another scope + } + } + ``` + +## Swift Enhancements and Changes + +* A new keyword `try?` has been added to Swift. + + `try?` attempts to perform an operation that may throw. If the operation + succeeds, the result is wrapped in an optional; if it fails (that is, if an + error is thrown), the result is `nil` and the error is discarded. + + For example: + + ```swift + func produceGizmoUsingTechnology() throws -> Gizmo { … } + func produceGizmoUsingMagic() throws -> Gizmo { … } + + if let result = try? produceGizmoUsingTechnology() { return result } + if let result = try? produceGizmoUsingMagic() { return result } + print("warning: failed to produce a Gizmo in any way") + return nil + ``` + + `try?` always adds an extra level of `Optional` to the result type of the + expression being evaluated. If a throwing function's normal return type is + `Int?`, the result of calling it with `try?` will be `Int??`, or + `Optional>`. **(21692467)** + +* Type names and enum cases now print and convert to `String` without + qualification by default. `debugPrint` or `String(reflecting:)` can still be + used to get fully qualified names. For example: + + ```swift + enum Fruit { case Apple, Banana, Strawberry } + print(Fruit.Apple) // "Apple" + debugPrint(Fruit.Apple) // "MyApp.Fruit.Apple") + ``` + + **(21788604)** + +* C `typedef`s of block types are imported as `typealias`s for Swift closures. + + The primary result of this is that `typedef`s for blocks with a parameter of + type `BOOL` are imported as closures with a parameter of type `Bool` (rather + than `ObjCBool` as in the previous release). This matches the behavior of + block parameters to imported Objective-C methods. **(22013912)** + +* The type `Boolean` in `MacTypes.h` is imported as `Bool` in contexts that allow + bridging between Swift and Objective-C types. + + In cases where the representation is significant, `Boolean` is imported as a + distinct `DarwinBoolean` type, which is `BooleanLiteralConvertible` and can be + used in conditions (much like the `ObjCBool` type). **(19013551)** + +* Fields of C structs that are marked `__unsafe_unretained` are presented in + Swift using `Unmanaged`. + + It is not possible for the Swift compiler to know if these references are + really intended to be strong (+1) or unretained (+0). **(19790608)** + +* The `NS_REFINED_FOR_SWIFT` macro can be used to move an Objective-C + declaration aside to provide a better version of the same API in Swift, + while still having the original implementation available. (For example, an + Objective-C API that takes a `Class` could offer a more precise parameter + type in Swift.) + + The `NS_REFINED_FOR_SWIFT` macro operates differently on different declarations: + + - `init` methods will be imported with the resulting Swift initializer having + `__` prepended to its first external parameter name. + + ```objc + // Objective-C + - (instancetype)initWithClassName:(NSString *)name NS_REFINED_FOR_SWIFT; + ``` + + ```swift + // Swift + init(__className: String) + ``` + + - Other methods will be imported with `__` prepended to their base name. + + ```objc + // Objective-C + - (NSString *)displayNameForMode:(DisplayMode)mode NS_REFINED_FOR_SWIFT; + ``` + + ```swift + // Swift + func __displayNameForMode(mode: DisplayMode) -> String + ``` + + - Subscript methods will be treated like any other methods and will not be + imported as subscripts. + + - Other declarations will have `__` prepended to their name. + + ```objc + // Objective-C + @property DisplayMode mode NS_REFINED_FOR_SWIFT; + ``` + + ```swift + // Swift + var __mode: DisplayMode { get set } + ``` + + **(20070465)** + +* Xcode provides context-sensitive code completions for enum elements and + option sets when using the shorter dot syntax. **(16659653)** + +* The `NSManaged` attribute can be used with methods as well as properties, + for access to Core Data's automatically generated Key-Value-Coding-compliant + to-many accessors. + + ```swift + @NSManaged var employees: NSSet + + @NSManaged func addEmployeesObject(employee: Employee) + @NSManaged func removeEmployeesObject(employee: Employee) + @NSManaged func addEmployees(employees: NSSet) + @NSManaged func removeEmployees(employees: NSSet) + ``` + + These can be declared in your `NSManagedObject` subclass. **(17583057)** + +* The grammar has been adjusted so that lines beginning with '.' are always + parsed as method or property lookups following the previous line, allowing + for code formatted like this to work: + + ```swift + foo + .bar + .bas = 68000 + ``` + + It is no longer possible to begin a line with a contextual static member + lookup (for example, to say `.staticVar = MyType()`). **(20238557)** + +* Code generation for large `struct` and `enum` types has been improved to reduce + code size. **(20598289)** + +* Nonmutating methods of structs, enums, and protocols may now be partially + applied to their self parameter: + + ```swift + let a: Set = [1, 2, 3] + let b: [Set] = [[1], [4]] + b.map(a.union) // => [[1, 2, 3], [1, 2, 3, 4]] + ``` + + **(21091944)** + +* Swift documentation comments recognize a new top-level list + item: `- Throws: ...` + + This item is used to document what errors can be thrown and why. The + documentation appears alongside parameters and return descriptions in Xcode + QuickHelp. **(21621679)** + +* Unnamed parameters now require an explicit `_:` to indicate that they are + unnamed. For example, the following is now an error: + + ```swift + func f(Int) { } + ``` + + and must be written as: + + ```swift + func f(_: Int) { } + ``` + + This simplifies the argument label model and also clarifies why cases like + `func f((a: Int, b: Int))` do not have parameters named `a` and `b`. + **(16737312)** + +* It is now possible to append a tuple to an array. **(17875634)** + +* The ability to refer to the 0 element of a scalar value (producing the + scalar value itself) has been removed. **(17963034)** + +* Variadic parameters can now appear anywhere in the parameter list for a + function or initializer. For example: + + ```swift + func doSomethingToValues(values: Int... , options: MyOptions = [], fn: (Int) -> Void) { … } + ``` + + **(20127197)** + +* Generic subclasses of Objective-C classes are now supported. **(18505295)** + +* If an element of an enum with string raw type does not have an explicit raw + value, it will default to the text of the enum's name. For example: + + ```swift + enum WorldLayer : String { + case Ground, BelowCharacter, Character + } + ``` + + is equivalent to: + + ```swift + enum WorldLayer : String { + case Ground = "Ground" + case BelowCharacter = "BelowCharacter" + case Character = "Character" + } + ``` + + **(15819953)** + +* The `performSelector` family of APIs is now available for Swift code. + **(17227475)** + +* When delegating or chaining to a failable initializer (for example, with + `self.init(…)` or `super.init(…)`), one can now force-unwrap the result with + `!`. For example: + + ```swift + extension UIImage { + enum AssetIdentifier: String { + case Isabella + case William + case Olivia + } + + convenience init(assetIdentifier: AssetIdentifier) { + self.init(named: assetIdentifier.rawValue)! + } + } + ``` + + **(18497407)** + +* Initializers can now be referenced like static methods by referring to + `.init` on a static type reference or type object. For example: + + ```swift + let x = String.init(5) + let stringType = String.self + let y = stringType.init(5) + + let oneTwoThree = [1, 2, 3].map(String.init).reduce("", combine: +) + ``` + + `.init` is still implicit when constructing using a static type, as in + `String(5)`. `.init` is required when using dynamic type objects or when + referring to the initializer as a function value. **(21375845)** + +* Enums and cases can now be marked indirect, which causes the associated + value for the enum to be stored indirectly, allowing for recursive data + structures to be defined. For example: + + ```swift + enum List { + case Nil + indirect case Cons(head: T, tail: List) + } + + indirect enum Tree { + case Leaf(T) + case Branch(left: Tree, right: Tree) + } + ``` + + **(21643855)** + +* Formatting for Swift expression results has changed significantly when + using `po` or `expr -O`. Customization that was introduced has been refined + in the following ways: + + - The formatted summary provided by either `debugDescription` or + `description` methods will always be used for types that conform to + `CustomDebugStringConvertible` or `CustomStringConvertible` respectively. + When neither conformance is present, the type name is displayed and + reference types also display the referenced address to more closely mimic + existing behavior for Objective-C classes. + + - Value types such as enums, tuples, and structs display all members + indented below the summary by default, while reference types will not. This + behavior can be customized for all types by implementing + `CustomReflectable`. + + These output customizations can be bypassed by using `p` or `expr` without + the `-O` argument to provide a complete list of all fields and their values. + **(21463866)** + +* Properties and methods using `Unmanaged` can now be exposed to Objective-C. + **(16832080)** + +* Applying the `@objc` attribute to a class changes that class's compile-time + name in the target's generated Objective-C header as well as changing its + runtime name. This applies to protocols as well. For example: + + ```swift + // Swift + @objc(MyAppDelegate) + class AppDelegate : NSObject, UIApplicationDelegate { + // ... + } + ``` + + ```objc + // Objective-C + @interface MyAppDelegate : NSObject + // ... + @end + ``` + + **(17469485)** + +* Collections containing types that are not Objective-C compatible are no + longer considered Objective-C compatible types themselves. + + For example, previously `Array` was permitted as the type + of a property marked `@objc`; this is no longer the case. **(19787270)** + +* Generic subclasses of Objective-C classes, as well as nongeneric classes + that inherit from such a class, require runtime metadata instantiation and + cannot be directly named from Objective-C code. + + When support for generic subclasses of Objective-C classes was first added, + the generated Objective-C bridging header erroneously listed such classes, + which, when used, could lead to incorrect runtime behavior or compile-time + errors. This has been fixed. + + The behavior of the `@objc` attribute on a class has been clarified such that + applying `@objc` to a class which cannot appear in a bridging header is now + an error. + + Note that this change does not result in a change of behavior with valid + code because members of a class are implicitly `@objc` if any superclass of + the class is an `@objc` class, and all `@objc` classes must inherit from + NSObject. **(21342574)** + +* The performance of `-Onone` (debug) builds has been improved by using + prespecialized instances of generics in the standard library. It produces + significantly faster executables in debug builds in many cases, without + impacting compile time. **(20486658)** + +* `AnyObject` and `NSObject` variables that refer to class objects can be cast + back to class object types. For example, this code succeeds: + + ```swift + let x: AnyObject = NSObject.self + let y = x as! NSObject.Type + ``` + + Arrays, dictionaries, and sets that contain class objects successfully + bridge with `NSArray`, `NSDictionary`, and `NSSet` as well. Objective-C APIs + that provide `NSArray *` objects, such as `-[NSURLSessionConfiguration + protocolClasses]`, now work correctly when used in Swift. **(16238475)** + +* `print()` and reflection via Mirrors is able to report both the current + case and payload for all enums with multiple payload types. The only + remaining enum types that do not support reflection are `@objc` enums and + enums imported from C. **(21739870)** + +* Enum cases with payloads can be used as functions. For example: + + ```swift + enum Either { case Left(T), Right(U) } + let lefts: [Either] = [1, 2, 3].map(Either.Left) + let rights: [Either] = ["one", "two", "three"].map(Either.Right) + ``` + + **(19091028)** + +* `ExtensibleCollectionType` has been folded into + `RangeReplaceableCollectionType`. In addition, default implementations have + been added as methods, which should be used instead of the free Swift + module functions related to these protocols. **(18220295)** + +## Swift Standard Library + +* The standard library moved many generic global functions (such as `map`, + `filter`, and `sort`) to be methods written with protocol extensions. This + allows those methods to be pervasively available on all sequence and + collection types and allowed the removal of the global functions. + +* Deprecated enum elements no longer affect the names of nondeprecated + elements when an Objective-C enum is imported into Swift. This may cause + the Swift names of some enum elements to change. **(17686122)** + +* All enums imported from C are `RawRepresentable`, including those not + declared with `NS_ENUM` or `NS_OPTIONS`. As part of this change, the value + property of such enums has been renamed `rawValue`. **(18702016)** + +* Swift documentation comments use a syntax based on the Markdown format, + aligning them with rich comments in playgrounds. + + - Outermost list items are interpreted as special fields and are highlighted + in Xcode QuickHelp. + + - There are two methods of documenting parameters: parameter outlines and + separate parameter fields. You can mix and match these forms as you see + fit in any order or continuity throughout the doc comment. Because these + are parsed as list items, you can nest arbitrary content underneath them. + + - Parameter outline syntax: + + ```swift + - Parameters: + - x: ... + - y: ... + ``` + + - Separate parameter fields: + + ```swift + - parameter x: ... + - parameter y: ... + ``` + + - Documenting return values: + + ```swift + - returns: ... + ``` + + Other special fields are highlighted in QuickHelp, as well as rendering + support for all of Markdown. (20180161) + +* The `CFunctionPointer U>` type has been removed. C function types are + specified using the new `@convention(c)` attribute. Like other function + types, `@convention(c) T -> U` is not nullable unless made optional. The + `@objc_block` attribute for specifying block types has also been removed and + replaced with `@convention(block)`. + +* Methods and functions have the same rules for parameter names. You can omit + providing an external parameter name with `_`. To further simplify the model, + the shorthand `#` for specifying a parameter name has been removed, as have + the special rules for default arguments. + + ```swift + // Declaration + func printFunction(str: String, newline: Bool) + func printMethod(str: String, newline: Bool) + func printFunctionOmitParameterName(str: String, _ newline: Bool) + + // Call + printFunction("hello", newline: true) + printMethod("hello", newline: true) + printFunctionOmitParameterName("hello", true) + ``` + + **(17218256)** + +* `NS_OPTIONS` types get imported as conforming to the `OptionSetType` protocol, + which presents a set-like interface for options. Instead of using bitwise + operations such as: + + ```swift + // Swift 1.2: + object.invokeMethodWithOptions(.OptionA | .OptionB) + object.invokeMethodWithOptions(nil) + + if options @ .OptionC == .OptionC { + // .OptionC is set + } + ``` + + Option sets support set literal syntax, and set-like methods such as contains: + + ```swift + object.invokeMethodWithOptions([.OptionA, .OptionB]) + object.invokeMethodWithOptions([]) + + if options.contains(.OptionC) { + // .OptionC is set + } + ``` + + A new option set type can be written in Swift as a struct that conforms to + the `OptionSetType` protocol. If the type specifies a `rawValue` property and + option constants as `static let` constants, the standard library will provide + default implementations of the rest of the option set API: + + ```swift + struct MyOptions: OptionSetType { + let rawValue: Int + + static let TuringMachine = MyOptions(rawValue: 1) + static let LambdaCalculus = MyOptions(rawValue: 2) + static let VonNeumann = MyOptions(rawValue: 4) + } + + let churchTuring: MyOptions = [.TuringMachine, .LambdaCalculus] + ``` + + **(18069205)** + +* Type annotations are no longer allowed in patterns and are considered part + of the outlying declaration. This means that code previously written as: + + ```swift + var (a : Int, b : Float) = foo() + ``` + + needs to be written as: + + ```swift + var (a,b) : (Int, Float) = foo() + ``` + + if an explicit type annotation is needed. The former syntax was ambiguous + with tuple element labels. **(20167393)** + +* The `do`/`while` loop is renamed to `repeat`/`while` to make it obvious + whether a statement is a loop from its leading keyword. + + In Swift 1.2: + + ```swift + do { + ... + } while + In Swift 2.0: + repeat { + ... + } while + ``` + + **(20336424)** + +* `forEach` has been added to `SequenceType`. This lets you iterate over + elements of a sequence, calling a body closure on each. For example: + + ```swift + (0..<10).forEach { + print($0) + } + ``` + + This is very similar to the following: + + ```swift + for x in 0..<10 { + print(x) + } + ``` + + But take note of the following differences: + + - Unlike for-in loops, you can't use `break` or `continue` to exit the current + call of the body closure or skip subsequent calls. + + - Also unlike for-in loops, using `return` in the body closure only exits from + the current call to the closure, not any outer scope, and won't skip + subsequent calls. + + **(18231840)** + +* The `Word` and `UWord` types have been removed from the standard library; use + `Int` and `UInt` instead. **(18693488)** + +* Most standard library APIs that take closures or `@autoclosure` parameters + now use `rethrows`. This allows the closure parameters to methods like `map` + and `filter` to throw errors, and allows short-circuiting operators like `&&`, + `||`, and `??` to work with expressions that may produce errors. + **(21345565)** + +* SIMD improvements: Integer vector types in the simd module now only support + unchecked arithmetic with wraparound semantics using the `&+`, `&-`, and `&*` + operators, in order to better support the machine model for vectors. + The `+`, `-`, and `*` operators are unavailable on integer vectors, and Xcode + automatically suggests replacing them with the wrapping operators. + + Code generation for vector types in the simd module has been improved to + better utilize vector hardware, leading to dramatically improved performance + in many cases. **(21574425)** + +* All `CollectionType` objects are now sliceable. `SequenceType` now has a notion + of `SubSequence`, which is a type that represents only some of the values but + in the same order. For example, the `ArraySubSequence` type is `ArraySlice`, + which is an efficient view on the `Array` type's buffer that avoids copying as + long as it uniquely references the `Array` from which it came. + + The following free Swift functions for splitting/slicing sequences have been + removed and replaced by method requirements on the `SequenceType` protocol + with default implementations in protocol extensions. `CollectionType` has + specialized implementations, where possible, to take advantage of efficient + access of its elements. + + ```swift + /// Returns the first `maxLength` elements of `self`, + /// or all the elements if `self` has fewer than `maxLength` elements. + prefix(maxLength: Int) -> SubSequence + + /// Returns the last `maxLength` elements of `self`, + /// or all the elements if `self` has fewer than `maxLength` elements. + suffix(maxLength: Int) -> SubSequence + + /// Returns all but the first `n` elements of `self`. + dropFirst(n: Int) -> SubSequence + + /// Returns all but the last `n` elements of `self`. + dropLast(n: Int) -> SubSequence + + /// Returns the maximal `SubSequence`s of `self`, in order, that + /// don't contain elements satisfying the predicate `isSeparator`. + split(maxSplits maxSplits: Int, allowEmptySlices: Bool, @noescape isSeparator: (Generator.Element) -> Bool) -> [SubSequence] + ``` + + The following convenience extension is provided for `split`: + + ```swift + split(separator: Generator.Element, maxSplit: Int, allowEmptySlices: Bool) -> [SubSequence] + ``` + + Also, new protocol requirements and default implementations on + `CollectionType` are now available: + + ```swift + /// Returns `self[startIndex.. SubSequence + + /// Returns `self[start.. SubSequence + + /// Returns `prefixUpTo(position.successor())` + prefixThrough(position: Index) -> SubSequence + ``` + + **(21663830)** + +* The `print` and `debugPrint` functions are improved: + - Both functions have become variadic, and you can print any number of items + with a single call. + - `separator: String = " "` was added so you can control how the items are + separated. + - `terminator: String = "\n"` replaced `appendNewline: bool = true.` With + this change, `print(x, appendNewline: false)` is expressed as + `print(x, terminator: "")`. + + - For the variants that take an output stream, the argument label `toStream` + was added to the stream argument. + + The `println` function from Swift 1.2 has been removed. **(21788540)** + +* For consistency and better composition of generic code, `ArraySlice` indices + are no longer always zero-based but map directly onto the indices of the + collection they are slicing and maintain that mapping even after mutations. + + Before: + + ```swift + var a = Array(0..<10) + var s = a[5..<10] + s.indices // 0..<5 + s[0] = 111 + s // [111, 6, 7, 8, 9] + s.removeFirst() + s.indices // 1..<5 + ``` + + After: + + ```swift + var a = Array(0..<10) + var s = a[5..<10] + s.indices // 5..<10 + s[5] = 99 + s // [99, 6, 7, 8, 9] + s.removeFirst() + s.indices // 6..<10 + ``` + + Rather than define variants of collection algorithms that take explicit + subrange arguments, such as `a.sortSubrangeInPlace(3..<7)`, the Swift + standard library provides "slicing," which composes well with algorithms. + This enables you to write `a[3..<7].sortInPlace()`, for example. With most + collections, these algorithms compose naturally. + + For example, before this change was incorporated: + + ```swift + extension MyIntCollection { + func prefixThroughFirstNegativeSubrange() -> SubSequence { + // Find the first negative element + let firstNegative = self.indexOf { $0 < 0 } ?? endIndex + + // Slice off non-negative prefix + let startsWithNegative = self.suffixFrom(firstNegative) + + // Find the first non-negative position in the slice + let end = startsWithNegative.indexOf { $0 >= 0 } ?? endIndex + return self[startIndex..`. Unfortunately, when array slice indices are zero-based, + the last two lines of the method need to change to: + + ```swift + let end = startsWithNegative.indexOf { $0 >= 0 } + ?? startsWithNegative.endIndex + return self[startIndex..() { } // error: generic parameter 'T' is not used in function signature + ``` + +* The `Dictionary.removeAtIndex(_:)` method now returns the key-value pair + being removed as a two-element tuple (rather than returning `Void`). + Similarly, the `Set.removeAtIndex(_:)` method returns the element being + removed. **(20299881)** + +* Generic parameters on types in the Swift standard library have been renamed + to reflect the role of the types in the API. For example, `Array` became + `Array`, `UnsafePointer` became `UnsafePointer`, and so + forth. **(21429126)** + +* The `SinkType` protocol and `SinkOf` struct have been removed from the standard + library in favor of `(T) -> ()` closures. **(21663799)** + + +2015-04-08 [Xcode 6.3, Swift 1.2] +---------- + +## Swift Language Changes + +* The notions of guaranteed conversion and "forced failable" conversion are now + separated into two operators. Forced failable conversion now uses the `as!` + operator. The `!` makes it clear to readers of code that the cast may fail and + produce a runtime error. The `as` operator remains for upcasts + (e.g. `someDerivedValue as Base`) and type annotations (`0 as Int8`) which + are guaranteed to never fail. **(19031957)** + +* Immutable (`let`) properties in `struct` and `class` initializers have been + revised to standardize on a general "`let`s are singly initialized but never + reassigned or mutated" model. Previously, they were completely mutable + within the body of initializers. Now, they are only allowed to be assigned + to once to provide their value. If the property has an initial value in its + declaration, that counts as the initial value for all initializers. + **(19035287)** + +* The implicit conversions from bridged Objective-C classes + (`NSString`/`NSArray`/`NSDictionary`) to their corresponding Swift value types + (`String`/`Array`/`Dictionary`) have been removed, making the Swift type + system simpler and more predictable. + + This means that the following code will no longer work: + + ```swift + import Foundation + func log(s: String) { println(x) } + let ns: NSString = "some NSString" // okay: literals still work + log(ns) // fails with the error + // "'NSString' is not convertible to 'String'" + ``` + + In order to perform such a bridging conversion, make the conversion explicit + with the as keyword: + + ```swift + log(ns as String) // succeeds + ``` + + Implicit conversions from Swift value types to their bridged Objective-C + classes are still permitted. For example: + + ```swift + func nsLog(ns: NSString) { println(ns) } + let s: String = "some String" + nsLog(s) // okay: implicit conversion from String to NSString is permitted + ``` + + Note that these Cocoa types in Objective-C headers are still automatically + bridged to their corresponding Swift type, which means that code is only + affected if it is explicitly referencing (for example) `NSString` in a Swift + source file. It is recommended you use the corresponding Swift types (for + example, `String`) directly unless you are doing something advanced, like + implementing a subclass in the class cluster. **(18311362)** + +* The `@autoclosure` attribute is now an attribute on a parameter, not an + attribute on the parameter's type. + + Where before you might have used: + + ```swift + func assert(predicate : @autoclosure () -> Bool) {...} + you now write this as: + func assert(@autoclosure predicate : () -> Bool) {...} + ``` + + **(15217242)** + +* The `@autoclosure` attribute on parameters now implies the new `@noescape` + attribute. + +* Curried function parameters can now specify argument labels. + + For example: + + ```swift + func curryUnnamed(a: Int)(_ b: Int) { return a + b } + curryUnnamed(1)(2) + + func curryNamed(first a: Int)(second b: Int) -> Int { return a + b } + curryNamed(first: 1)(second: 2) + ``` + + **(17237268)** + +* Swift now detects discrepancies between overloading and overriding in the + Swift type system and the effective behavior seen via the Objective-C runtime. + + For example, the following conflict between the Objective-C setter for + `property` in a class and the method `setProperty` in its extension is now + diagnosed: + + ```swift + class A : NSObject { + var property: String = "Hello" // note: Objective-C method 'setProperty:' + // previously declared by setter for + // 'property' here + } + + extension A { + func setProperty(str: String) { } // error: method 'setProperty' + // redeclares Objective-C method + //'setProperty:' + } + Similar checking applies to accidental overrides in the Objective-C runtime: + class B : NSObject { + func method(arg: String) { } // note: overridden declaration + // here has type '(String) -> ()' + } + + class C : B { + func method(arg: [String]) { } // error: overriding method with + // selector 'method:' has incompatible + // type '([String]) -> ()' + } + as well as protocol conformances: + class MyDelegate : NSObject, NSURLSessionDelegate { + func URLSession(session: NSURLSession, didBecomeInvalidWithError: + Bool){ } // error: Objective-C method 'URLSession:didBecomeInvalidWithError:' + // provided by method 'URLSession(_:didBecomeInvalidWithError:)' + // conflicts with optional requirement method + // 'URLSession(_:didBecomeInvalidWithError:)' in protocol + // 'NSURLSessionDelegate' + } + ``` + + **(18391046, 18383574)** + +* The precedence of the Nil Coalescing Operator (`??`) has been raised to bind + tighter than short-circuiting logical and comparison operators, but looser + than as conversions and range operators. This provides more useful behavior + for expressions like: + + ```swift + if allowEmpty || items?.count ?? 0 > 0 {...} + ``` + +* The `&/` and `&%` operators were removed, to simplify the language and + improve consistency. + + Unlike the `&+`, `&-`, and `&*` operators, these operators did not provide + two's-complement arithmetic behavior; they provided special case behavior + for division, remainder by zero, and `Int.min/-1`. These tests should be + written explicitly in the code as comparisons if needed. **(17926954)** + +* Constructing a `UInt8` from an ASCII value now requires the ascii keyword + parameter. Using non-ASCII unicode scalars will cause this initializer to + trap. **(18509195)** + +* The C `size_t` family of types are now imported into Swift as `Int`, since + Swift prefers sizes and counts to be represented as signed numbers, even if + they are non-negative. + + This change decreases the amount of explicit type conversion between `Int` + and `UInt`, better aligns with `sizeof` returning `Int`, and provides safer + arithmetic properties. **(18949559)** + +* Classes that do not inherit from `NSObject` but do adopt an `@objc` protocol + will need to explicitly mark those methods, properties, and initializers + used to satisfy the protocol requirements as `@objc`. + + For example: + + ```swift + @objc protocol SomethingDelegate { + func didSomething() + } + + class MySomethingDelegate : SomethingDelegate { + @objc func didSomething() { … } + } + ``` + +## Swift Language Fixes + +* Dynamic casts (`as!`, `as?` and `is`) now work with Swift protocol types, so + long as they have no associated types. **(18869156)** + +* Adding conformances within a Playground now works as expected. + + For example: + + ```swift + struct Point { + var x, y: Double + } + + extension Point : Printable { + var description: String { + return "(\(x), \(y))" + } + } + + var p1 = Point(x: 1.5, y: 2.5) + println(p1) // prints "(1.5, 2.5)" + ``` + +* Imported `NS_ENUM` types with undocumented values, such as + `UIViewAnimationCurve`, can now be converted from their raw integer values + using the `init(rawValue:)` initializer without being reset to `nil`. Code + that used `unsafeBitCast` as a workaround for this issue can be written to + use the raw value initializer. + + For example: + + ```swift + let animationCurve = + unsafeBitCast(userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue, + UIViewAnimationCurve.self) + can now be written instead as: + let animationCurve = UIViewAnimationCurve(rawValue: + userInfo[UIKeyboardAnimationCurveUserInfoKey].integerValue)! + ``` + + **(19005771)** + +* Negative floating-point literals are now accepted as raw values in enums. + **(16504472)** + +* Unowned references to Objective-C objects, or Swift objects inheriting from + Objective-C objects, no longer cause a crash if the object holding the + unowned reference is deallocated after the referenced object has been + released. **(18091547)** + +* Variables and properties with observing accessors no longer require an + explicit type if it can be inferred from the initial value expression. + **(18148072)** + +* Generic curried functions no longer produce random results when fully + applied. **(18988428)** + +* Comparing the result of a failed `NSClassFromString` lookup against `nil` now + behaves correctly. **(19318533)** + +* Subclasses that override base class methods with co- or contravariance in + Optional types no longer cause crashes at runtime. + + For example: + + ```swift + class Base { + func foo(x: String) -> String? { return x } + } + class Derived: Base { + override func foo(x: String?) -> String { return x! } + } + ``` + + **(19321484)** + +## Swift Language Enhancements + +* Swift now supports building targets incrementally, i.e. not rebuilding + every Swift source file in a target when a single file is changed. + + The incremental build capability is based on a conservative dependency + analysis, so you may still see more files rebuilding than absolutely + necessary. If you find any cases where a file is not rebuilt when it should + be, please file a bug report. Running Clean on your target afterwards should + allow you to complete your build normally. **(18248514)** + +* A new `Set` data structure is included which provides a generic collection of + unique elements with full value semantics. It bridges with `NSSet`, providing + functionality analogous to `Array` and `Dictionary`. **(14661754)** + +* The `if–let` construct has been expanded to allow testing multiple optionals + and guarding conditions in a single `if` (or `while`) statement using syntax + similar to generic constraints: + + ```swift + if let a = foo(), b = bar() where a < b, + let c = baz() { + } + ``` + + This allows you to test multiple optionals and include intervening boolean + conditions, without introducing undesirable nesting (for instance, to avoid + the optional unwrapping _"pyramid of doom"_). + + Further, `if–let` now also supports a single leading boolean condition along + with optional binding `let` clauses. For example: + + ```swift + if someValue > 42 && someOtherThing < 19, let a = getOptionalThing() where a > someValue { + } + ``` + + **(19797158, 19382942)** + +* The `if–let` syntax has been extended to support a single leading boolean + condition along with optional binding `let` clauses. + + For example: + + ```swift + if someValue > 42 && someOtherThing < 19, let a = getOptionalThing() where a > someValue { + } + ``` + + **(19797158)** + +* `let` constants have been generalized to no longer require immediate + initialization. The new rule is that a `let` constant must be initialized + before use (like a `var`), and that it may only be initialized: not + reassigned or mutated after initialization. This enables patterns such as: + + ```swift + let x: SomeThing + if condition { + x = foo() + } else { + x = bar() + } + use(x) + ``` + + which formerly required the use of a `var`, even though there is no mutation + taking place. **(16181314)** + +* `static` methods and properties are now allowed in classes (as an alias for + `class final`). You are now allowed to declare static stored properties in + classes, which have global storage and are lazily initialized on first + access (like global variables). Protocols now declare type requirements as + static requirements instead of declaring them as class requirements. + **(17198298)** + +* Type inference for single-expression closures has been improved in several ways: + - Closures that are comprised of a single return statement are now type + checked as single-expression closures. + - Unannotated single-expression closures with non-`Void` return types can now + be used in `Void` contexts. + - Situations where a multi-statement closure's type could not be inferred + because of a missing return-type annotation are now properly diagnosed. + +* Swift enums can now be exported to Objective-C using the `@objc` attribute. + `@objc` enums must declare an integer raw type, and cannot be generic or use + associated values. Because Objective-C enums are not namespaced, enum cases + are imported into Objective-C as the concatenation of the enum name and + case name. + + For example, this Swift declaration: + + ```swift + // Swift + @objc + enum Bear: Int { + case Black, Grizzly, Polar + } + ``` + + imports into Objective-C as: + + ```objc + // Objective-C + typedef NS_ENUM(NSInteger, Bear) { + BearBlack, BearGrizzly, BearPolar + }; + ``` + + **(16967385)** + +* Objective-C language extensions are now available to indicate the nullability + of pointers and blocks in Objective-C APIs, allowing your Objective-C APIs + to be imported without `ImplicitlyUnwrappedOptional`. (See items below for + more details.) **(18868820)** + +* Swift can now partially import C aggregates containing unions, bitfields, + SIMD vector types, and other C language features that are not natively + supported in Swift. The unsupported fields will not be accessible from + Swift, but C and Objective-C APIs that have arguments and return values of + these types can be used in Swift. This includes the Foundation `NSDecimal` + type and the `GLKit` `GLKVector` and `GLKMatrix` types, among others. + **(15951448)** + +* Imported C structs now have a default initializer in Swift that initializes + all of the struct's fields to zero. + + For example: + + ```swift + import Darwin + var devNullStat = stat() + stat("/dev/null", &devNullStat) + ``` + + If a structure contains fields that cannot be correctly zero initialized + (i.e. pointer fields marked with the new `__nonnull` modifier), this default + initializer will be suppressed. **(18338802)** + +* New APIs for converting among the `Index` types for `String`, + `String.UnicodeScalarView`, `String.UTF16View`, and `String.UTF8View` are + available, as well as APIs for converting each of the `String` views into + `String`s. **(18018911)** + +* Type values now print as the full demangled type name when used with + `println` or string interpolation. + + ```swift + toString(Int.self) // prints "Swift.Int" + println([Float].self) // prints "Swift.Array<Swift.Float>" + println((Int, String).self) // prints "(Swift.Int, Swift.String)" + ``` + + **(18947381)** + +* A new `@noescape` attribute may be used on closure parameters to functions. + This indicates that the parameter is only ever called (or passed as an + `@noescape` parameter in a call), which means that it cannot outlive the + lifetime of the call. This enables some minor performance optimizations, + but more importantly disables the `self.` requirement in closure arguments. + This enables control-flow-like functions to be more transparent about their + behavior. In a future beta, the standard library will adopt this attribute + in functions like `autoreleasepool()`. + + ```swift + func autoreleasepool(@noescape code: () -> ()) { + pushAutoreleasePool() + code() + popAutoreleasePool() + } + ``` + + **(16323038)** + +* Performance is substantially improved over Swift 1.1 in many cases. For + example, multidimensional arrays are algorithmically faster in some cases, + unoptimized code is much faster in many cases, and many other improvements + have been made. + +* The diagnostics emitted for expression type check errors are greatly + improved in many cases. **(18869019)** + +* Type checker performance for many common expression kinds has been greatly + improved. This can significantly improve build times and reduces the number + of "expression too complex" errors. **(18868985)** + +* The `@autoclosure` attribute has a second form, `@autoclosure(escaping)`, that + provides the same caller-side syntax as `@autoclosure` but allows the + resulting closure to escape in the implementation. + + For example: + + ```swift + func lazyAssertion(@autoclosure(escaping) condition: () -> Bool, + message: String = "") { + lazyAssertions.append(condition) // escapes + } + lazyAssertion(1 == 2, message: "fail eventually") + ``` + + **(19499207)** + +## Swift Performance + +* A new compilation mode has been introduced for Swift called Whole Module + Optimization. This option optimizes all of the files in a target together + and enables better performance (at the cost of increased compile time). The + new flag can be enabled in Xcode using the `Whole Module Optimization` build + setting or by using the `swiftc` command line tool with the flag + `-whole-module-optimization`. **(18603795)** + +## Swift Standard Library Enhancements and Changes + +* `flatMap` was added to the standard library. `flatMap` is the function that + maps a function over something and returns the result flattened one level. + `flatMap` has many uses, such as to flatten an array: + + ```swift + [[1,2],[3,4]].flatMap { $0 } + ``` + + or to chain optionals with functions: + + ```swift + [[1,2], [3,4]].first.flatMap { find($0, 1) } + ``` + + **(19881534)** + +* The function `zip` was added. It joins two sequences together into one + sequence of tuples. **(17292393)** + +* `utf16Count` is removed from `String`. Instead use count on the `UTF16` view + of the `String`. + + For example: + + ```swift + count(string.utf16) + ``` + + **(17627758)** + + +2014-12-02 [Xcode 6.1.1] +---------- + +* Class methods and initializers that satisfy protocol requirements now properly + invoke subclass overrides when called in generic contexts. For example: + + ```swift + protocol P { + class func foo() + } + + class C: P { + class func foo() { println("C!") } + } + + class D: C { + override class func foo() { println("D!") } + } + + func foo(x: T) { + x.dynamicType.foo() + } + + foo(C()) // Prints "C!" + foo(D()) // Used to incorrectly print "C!", now prints "D!" + ``` + + **(18828217)** + +2014-10-09 [Xcode 6.1 Release Notes, Swift 1.1] +---------- + +* Values of type `Any` can now contain values of function type. **(16406907)** + +* Documentation for the standard library (displayed in quick help and in the + synthesized header for the Swift module) is improved. **(16462500)** + +* Class properties don't need to be marked final to avoid `O(n)` mutations on + value semantic types. **(17416120)** + +* Casts can now be performed between `CF` types (such as `CFString`, `CGImage`, + and `SecIdentity`) and AnyObject. Such casts will always succeed at run-time. + For example: + + ```swift + var cfStr: CFString = ... + var obj: AnyObject = cfStr as AnyObject + var cfStr = obj as CFString + ``` + + **(18088474)** + + +2014-10-09 [Roughly Xcode 6.1, and Swift 1.1] +---------- + +* `HeapBuffer`, `HeapBufferStorage`, and + `OnHeap` were never really useful, because their APIs were + insufficiently public. They have been replaced with a single class, + `ManagedBuffer`. See also the new function + `isUniquelyReferenced(x)` which is often useful in conjunction with + `ManagedBuffer`. + +* The `Character` enum has been turned into a struct, to avoid + exposing its internal implementation details. + +* The `countElements` function has been renamed `count`, for better + consistency with our naming conventions. + +* Mixed-sign addition and subtraction operations, that were + unintentionally allowed in previous versions, now cause a + compilation error. + +* OS X apps can now apply the `@NSApplicationMain` attribute to their app delegate + class in order to generate an implicit `main` for the app. This works like + the `@UIApplicationMain` attribute for iOS apps. + +* Objective-C `init` and factory methods are now imported as failable + initializers when they can return `nil`. In the absence of information + about a potentially-`nil` result, an Objective-C `init` or factory + method will be imported as `init!`. + + As part of this change, factory methods that have NSError** + parameters, such as `+[NSString + stringWithContentsOfFile:encoding:error:]`, will now be imported as + (failable) initializers, e.g., + + ```swift + init?(contentsOfFile path: String, + encoding: NSStringEncoding, + error: NSErrorPointer) + ``` + +* Nested classes explicitly marked `@objc` will now properly be included in a + target's generated header as long as the containing context is also + (implicitly or explicitly) `@objc`. Nested classes not explicitly marked + `@objc` will never be printed in the generated header, even if they extend an + Objective-C class. + +* All of the `*LiteralConvertible` protocols, as well as + `StringInterpolationConvertible`, now use initializers for their + requirements rather than static methods starting with + `convertFrom`. For example, `IntegerLiteralConvertible` now has the + following initializer requirement: + + ```swift + init(integerLiteral value: IntegerLiteralType) + ``` + Any type that previously conformed to one of these protocols will + need to replace its `convertFromXXX` static methods with the + corresponding initializer. + +2014-09-15 +---------- + +* Initializers can now fail by returning `nil`. A failable initializer is + declared with `init?` (to return an explicit optional) or `init!` (to return + an implicitly-unwrapped optional). For example, you could implement + `String.toInt` as a failable initializer of `Int` like this: + + ```swift + extension Int { + init?(fromString: String) { + if let i = fromString.toInt() { + // Initialize + self = i + } else { + // Discard self and return 'nil'. + return nil + } + } + } + ``` + + The result of constructing a value using a failable initializer then becomes + optional: + + ```swift + if let twentytwo = Int(fromString: "22") { + println("the number is \(twentytwo)") + } else { + println("not a number") + } + ``` + + In the current implementation, struct and enum initializers can return nil + at any point inside the initializer, but class initializers can only return + nil after all of the stored properties of the object have been initialized + and `self.init` or `super.init` has been called. If `self.init` or + `super.init` is used to delegate to a failable initializer, then the `nil` + return is implicitly propagated through the current initializer if the + called initializer fails. + +* The `RawRepresentable` protocol that enums with raw types implicitly conform + to has been redefined to take advantage of failable initializers. The + `fromRaw(RawValue)` static method has been replaced with an initializer + `init?(rawValue: RawValue)`, and the `toRaw()` method has been replaced with + a `rawValue` property. Enums with raw types can now be used like this: + + ```swift + enum Foo: Int { case A = 0, B = 1, C = 2 } + let foo = Foo(rawValue: 2)! // formerly 'Foo.fromRaw(2)!' + println(foo.rawValue) // formerly 'foo.toRaw()' + ``` + +2014-09-02 +---------- + +* Characters can no longer be concatenated using `+`. Use `String(c1) + + String(c2)` instead. + +2014-08-18 +--------- + +* When force-casting between arrays of class or `@objc` protocol types + using `a as [C]`, type checking is now deferred until the moment + each element is accessed. Because bridging conversions from NSArray + are equivalent to force-casts from `[NSArray]`, this makes certain + Array round-trips through Objective-C code `O(1)` instead of `O(N)`. + +2014-08-04 +---------- + +* `RawOptionSetType` now implements `BitwiseOperationsType`, so imported + `NS_OPTIONS` now support the bitwise assignment operators `|=`, `&=`, + and `^=`. It also no longer implements `BooleanType`; to check if an option + set is empty, compare it to `nil`. + +* Types implementing `BitwiseOperationsType` now automatically support + the bitwise assignment operators `|=`, `&=`, and `^=`. + +* Optionals can now be coalesced with default values using the `??` operator. + `??` is a short-circuiting operator that takes an optional on the left and + a non-optional expression on the right. If the optional has a value, its + value is returned as a non-optional; otherwise, the expression on the right + is evaluated and returned: + + ```swift + var sequence: [Int] = [] + sequence.first ?? 0 // produces 0, because sequence.first is nil + sequence.append(22) + sequence.first ?? 0 // produces 22, the value of sequence.first + ``` + +* The optional chaining `?` operator can now be mutated through, like `!`. + The assignment and the evaluation of the right-hand side of the operator + are conditional on the presence of the optional value: + + ```swift + var sequences = ["fibonacci": [1, 1, 2, 3, 4], "perfect": [6, 28, 496]] + sequences["fibonacci"]?[4]++ // Increments element 4 of key "fibonacci" + sequences["perfect"]?.append(8128) // Appends to key "perfect" + + sequences["cubes"]?[3] = 3*3*3 // Does nothing; no "cubes" key + ``` + + Note that optional chaining still flows to the right, so prefix increment + operators are *not* included in the chain, so this won't type-check: + + ```swift + ++sequences["fibonacci"]?[4] // Won't type check, can't '++' Int? + ``` + +2014-07-28 +---------- + +* The swift command line interface is now divided into an interactive driver + `swift`, and a batch compiler `swiftc`: + + ``` + swift [options] input-file [program-arguments] + Runs the script 'input-file' immediately, passing any program-arguments + to the script. Without any input files, invokes the repl. + + swiftc [options] input-filenames + The familiar swift compiler interface: compiles the input-files according + to the mode options like -emit-object, -emit-executable, etc. + ``` + +* For greater clarity and explicitness when bypassing the type system, + `reinterpretCast` has been renamed `unsafeBitCast`, and it has acquired + a (required) explicit type parameter. So + + ```swift + let x: T = reinterpretCast(y) + ``` + + becomes + + ```swift + let x = unsafeBitCast(y, T.self) + ``` + +* Because their semantics were unclear, the methods `asUnsigned` (on + the signed integer types) and `asSigned` (on the unsigned integer + types) have been replaced. The new idiom is explicit construction + of the target type using the `bitPattern:` argument label. So, + + ```swift + myInt.asUnsigned() + ``` + + has become + + ```swift + UInt(bitPattern: myInt) + ``` + +* To better follow Cocoa naming conventions and to encourage + immutability, The following pointer types were renamed: + + | Old Name | New Name | + |---------------------------------|----------------------------------------| + | `UnsafePointer` | `UnsafeMutablePointer` | + | `ConstUnsafePointer` | `UnsafePointer` | + | `AutoreleasingUnsafePointer` | `AutoreleasingUnsafeMutablePointer` | + + Note that the meaning of `UnsafePointer` has changed from mutable to + immutable. As a result, some of your code may fail to compile when + assigning to an `UnsafePointer.memory` property. The fix is to + change your `UnsafePointer` into an `UnsafeMutablePointer`. + +* The optional unwrapping operator `x!` can now be assigned through, and + mutating methods and operators can be applied through it: + + ```swift + var x: Int! = 0 + x! = 2 + x!++ + + // Nested dictionaries can now be mutated directly: + var sequences = ["fibonacci": [1, 1, 2, 3, 0]] + sequences["fibonacci"]![4] = 5 + sequences["fibonacci"]!.append(8) + ``` + +* The `@auto_closure` attribute has been renamed to `@autoclosure`. + +* There is a new `dynamic` declaration modifier. When applied to a method, + property, subscript, or initializer, it guarantees that references to the + declaration are always dynamically dispatched and never inlined or + devirtualized, and that the method binding can be reliably changed at runtime. + The implementation currently relies on the Objective-C runtime, so `dynamic` + can only be applied to `@objc-compatible` declarations for now. `@objc` now + only makes a declaration visible to Objective-C; the compiler may now use + vtable lookup or direct access to access (non-dynamic) `@objc` declarations. + + ```swift + class Foo { + // Always accessed by objc_msgSend + dynamic var x: Int + + // Accessed by objc_msgSend from ObjC; may be accessed by vtable + // or by static reference in Swift + @objc var y: Int + + // Not exposed to ObjC (unless Foo inherits NSObject) + var z: Int + } + ``` + + `dynamic` enables KVO, proxying, and other advanced Cocoa features to work + reliably with Swift declarations. + +* Clang submodules can now be imported: + + ```swift + import UIKit.UIGestureRecognizerSubclass + ``` + +* The numeric optimization levels `-O[0-3]` have been removed in favor of the + named levels `-Onone` and `-O`. + +* The `-Ofast` optimization flag has been renamed to `-Ounchecked`. We will accept + both names for now and remove `-Ofast` in a later build. + +* An initializer that overrides a designated initializer from its + superclass must be marked with the `override` keyword, so that all + overrides in the language consistently require the use of + `override`. For example: + + ```swift + class A { + init() { } + } + + class B : A { + override init() { super.init() } + } + ``` + +* Required initializers are now more prominent in several ways. First, + a (non-final) class that conforms to a protocol that contains an + initializer requirement must provide a required initializer to + satisfy that requirement. This ensures that subclasses will also + conform to the protocol, and will be most visible with classes that + conform to `NSCoding`: + + ```swift + class MyClass : NSObject, NSCoding { + required init(coder aDecoder: NSCoder!) { /*... */ } + func encodeWithCoder(aCoder: NSCoder!) { /* ... */ } + } + ``` + Second, because `required` places a significant requirement on all + subclasses, the `required` keyword must be placed on overrides of a + required initializer: + + ```swift + class MySubClass : MyClass { + var title: String = "Untitled" + + required init(coder aDecoder: NSCoder!) { /*... */ } + override func encodeWithCoder(aCoder: NSCoder!) { /* ... */ } + } + ``` + Finally, required initializers can now be inherited like any other + initializer: + + ```swift + class MySimpleSubClass : MyClass { } // inherits the required init(coder:). + ``` + +2014-07-21 +---------- + +* Access control has been implemented. + + - `public` declarations can be accessed from any module. + - `internal` declarations (the default) can be accessed from within the + current module. + - `private` declarations can be accessed only from within the current file. + + There are still details to iron out here, but the model is in place. + The general principle is that an entity cannot be defined in terms of another + entity with less accessibility. + + Along with this, the generated header for a framework will only include + public declarations. Generated headers for applications will include public + and internal declarations. + +* `CGFloat` is now a distinct floating-point type that wraps either a + `Float` (on 32-bit architectures) or a `Double` (on 64-bit + architectures). It provides all of the same comparison and + arithmetic operations of Float and Double, and can be created using + numeric literals. + +* The immediate mode `swift -i` now works for writing `#!` scripts that take + command line arguments. The `-i` option to the swift driver must now come at + the end of the compiler arguments, directly before the input filename. Any + arguments that come after `-i` and the input filename are treated as arguments + to the interpreted file and forwarded to `Process.arguments`. + +* Type inference for `for..in` loops has been improved to consider the + sequence along with the element pattern. For example, this accepts + the following loops that were previously rejected: + + ```swift + for i: Int8 in 0..<10 { } + for i: Float in 0.0...10.0 { } + ``` + +* Introduced the new `BooleanLiteralConvertible` protocol, which allows + user-defined types to support Boolean literals. `true` and `false` + are now `Boolean` constants and keywords. + +* The `@final`, `@lazy`, `@required` and `@optional` attributes are now + considered to be declaration modifiers - they no longer require (or allow) an + `@` sign. + +* The `@prefix`, `@infix`, and `@postfix` attributes have been changed to + declaration modifiers, so they are no longer spelled with an `@` sign. + Operator declarations have been rearranged from `operator prefix +` to + `prefix operator +` for consistency. + +2014-07-03 +---------- + +* C function pointer types are now imported as `CFunctionPointer`, where `T` + is a Swift function type. `CFunctionPointer` and `COpaquePointer` can be + explicitly constructed from one another, but they do not freely convert, nor + is `CFunctionPointer` compatible with Swift closures. + + Example: `int (*)(void)` becomes `CFunctionPointer<(Int) -> Void>`. + +* The interop model for pointers in C APIs has been simplified. Most code that + calls C functions by passing arrays, UnsafePointers, or the addresses of + variables with `&x` does not need to change. However, the `CConstPointer` and + `CMutablePointer` bridging types have been removed, and functions and methods + are now imported as and overridden by taking UnsafePointer and + `ConstUnsafePointer` directly. `Void` pointers are now imported as + `(Const)UnsafePointer`; `COpaquePointer` is only imported for opaque + types now. + +* `Array` types are now spelled with the brackets surrounding the + element type. For example, an array of `Int` is written as: + + ```swift + var array: [Int] + ``` + +* `Dictionary` types can now be spelled with the syntax `[K : V]`, where `K` + is the key type and `V` is the value type. For example: + + ```swift + var dict: [String : Int] = ["Hello" : 1, "World" : 2] + ``` + + The type `[K : V]` is syntactic sugar for `Dictionary`; nothing + else has changed. + +* The `@IBOutlet` attribute no longer implicitly (and invisibly) changes the type + of the declaration it is attached to. It no longer implicitly makes variables + be an implicitly unwrapped optional and no longer defaults them to weak. + +* The `\x`, `\u` and `\U` escape sequences in string literals have been + consolidated into a single and less error prone `\u{123456}` syntax. + + +2014-06-23 +--------- + +* The half-open range operator has been renamed from `..` to `..<` to reduce + confusion. The `..<` operator is precedented in Groovy (among other languages) + and makes it much more clear that it doesn't include the endpoint. + +* Class objects such as `NSObject.self` can now be converted to `AnyObject` and + used as object values. + +* Objective-C protocol objects such as `NSCopying.self` can now be used as + instances of the `Protocol` class, such as in APIs such as XPC. + +* Arrays now have full value semantics: both assignment and + initialization create a logically-distinct object + +* The `sort` function and array method modify the target in-place. A + new `sorted` function and array method are non-mutating, creating + and returning a new collection. + +2014-05-19 +---------- + +* `sort`, `map`, `filter`, and `reduce` methods on `Array`s accept trailing + closures: + + ```swift + let a = [5, 6, 1, 3, 9] + a.sort{ $0 > $1 } + println(a) // [9, 6, 5, 3, 1] + println(a.map{ $0 * 2 }) // [18, 12, 10, 6, 2] + println(a.map{ $0 * 2 }.filter{ $0 < 10}) // [6, 2] + println(a.reduce(1000){ $0 + $1 }) // 1024 (no kidding) + ``` + +* A lazy `map()` function in the standard library works on any `Sequence`. + Example: + + ```swift + class X { + var value: Int + + init(_ value: Int) { + self.value = value + println("created X(\(value))") + } + } + + // logically, this sequence is X(0), X(1), X(2), ... X(50) + let lazyXs = map(0..50){ X($0) } + + // Prints "created X(...)" 4 times + for x in lazyXs { + if x.value == 4 { + break + } + } + ``` + +* There's a similar lazy `filter()` function: + + ```swift + // 0, 10, 20, 30, 40 + let tens = filter(0..50) { $0 % 10 == 0 } + let tenX = map(tens){ X($0) } // 5 lazy Xs + let tenXarray = Array(tenX) // Actually creates those Xs + ``` + +* Weak pointers of classbound protocol type work now. + +* `IBOutlets` now default to weak pointers with implicit optional type (`T!`). + +* `NSArray*` parameters and result types of Objective-C APIs are now + imported as `AnyObject[]!`, i.e., an implicitly unwrapped optional + array storing `AnyObject` values. For example, `NSView`'s constraints + property + + ```objc + @property (readonly) NSArray *constraints; + ``` + + is now imported as + + ```swift + var constraints: AnyObject[]! + ``` + + Note that one can implicitly convert between an `AnyObject[]` and an + `NSArray` (in both directions), so (for example) one can still + explicitly use `NSArray` if desired: + + ```swift + var array: NSArray = view.constraints + ``` + + Swift arrays bridge to `NSArray` similarly to the way Swift + strings bridge to `NSString`. + +* `ObjCMutablePointer` has been renamed `AutoreleasingUnsafePointer`. + +* `UnsafePointer` (and `AutoreleasingUnsafePointer`)'s `set()` and `get()` + have been replaced with a property called `memory`. + + - Previously you would write: + + ```swift + val = p.get() + p.set(val) + ``` + + - Now you write: + + ```swift + val = p.memory + p.memory = val + ``` + +* Removed shorthand `x as T!`; instead use `(x as T)!` + + - `x as T!` now means "x as implicitly unwrapped optional". + +* Range operators `..` and `...` have been switched. + + - `1..3` now means 1,2 + - `1...3` now means 1,2,3 + +* The pound sign (`#`) is now used instead of the back-tick (\`) to mark + an argument name as a keyword argument, e.g., + + ```swift + func moveTo(#x: Int, #y: Int) { ... } + moveTo(x: 5, y: 7) + ``` + +* Objective-C factory methods are now imported as initializers. For + example, `NSColor`'s `+colorWithRed:green:blue:alpha` becomes + + ```swift + init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) + ``` + + which allows an `NSColor` to be created as, e.g., + + ```swift + NSColor(red: 0.5, green: 0.25, blue: 0.25, alpha: 0.5) + ``` + + Factory methods are identified by their kind (class methods), name + (starts with words that match the words that end the class name), + and result type (`instancetype` or the class type). + +* Objective-C properties of some `CF` type are no longer imported as `Unmanaged`. + +* REPL mode now uses LLDB, for a greatly-expanded set of features. The colon + prefix now treats the rest of the line as a command for LLDB, and entering + a single colon will drop you into the debugging command prompt. Most + importantly, crashes in the REPL will now drop you into debugging mode to + see what went wrong. + + If you do have a need for the previous REPL, pass `-integrated-repl`. + +* In a UIKit-based application, you can now eliminate your 'main.swift' file + and instead apply the `@UIApplicationMain` attribute to your + `UIApplicationDelegate` class. This will cause the `main` entry point to the + application to be automatically generated as follows: + + ```swift + UIApplicationMain(argc, argv, nil, + NSStringFromClass(YourApplicationDelegate.self)) + ``` + + If you need nontrivial logic in your application entry point, you can still + write out a `main.swift`. Note that `@UIApplicationMain` and `main.swift` are + mutually exclusive. + +2014-05-13 +---------- + +* weak pointers now work with implicitly unchecked optionals, enabling usecases + where you don't want to `!` every use of a weak pointer. For example: + + ```swift + weak var myView : NSView! + ``` + + of course, they still work with explicitly checked optionals like `NSView?` + +* Dictionary subscripting now takes/returns an optional type. This allows + querying a dictionary via subscripting to gracefully fail. It also enables + the idiom of removing values from a dictionary using `dict[key] = nil`. + As part of this, `deleteKey` is no longer available. + +* Stored properties may now be marked with the `@lazy` attribute, which causes + their initializer to be evaluated the first time the property is touched + instead of when the enclosing type is initialized. For example: + + ```swift + func myInitializer() -> Int { println("hello\n"); return 42 } + class MyClass { + @lazy var aProperty = myInitializer() + } + + var c = MyClass() // doesn't print hello + var tmp = c.aProperty // prints hello on first access + tmp = c.aProperty // doesn't print on subsequent loads. + + c = MyClass() // doesn't print hello + c.aProperty = 57 // overwriting the value prevents it from ever running + ``` + + Because lazy properties inherently rely on mutation of the property, they + cannot be `let`s. They are currently also limited to being members of structs + and classes (they aren't allowed as local or global variables yet) and cannot + be observed with `willSet`/`didSet` yet. + +* Closures can now specify a capture list to indicate with what strength they + want to capture a value, and to bind a particular field value if they want to. + + Closure capture lists are square-bracket delimited and specified before the + (optional) argument list in a closure. Each entry may be specified as `weak` + or `unowned` to capture the value with a weak or unowned pointer, and may + contain an explicit expression if desired. Some examples: + + ```swift + takeClosure { print(self.title) } // strong capture + takeClosure { [weak self] in print(self!.title) } // weak capture + takeClosure { [unowned self] in print(self.title) } // unowned capture + ``` + + You can also bind arbitrary expression to named values in the capture list. + The expression is evaluated when the closure is formed, and captured with the + specified strength. For example: + + ```swift + // weak capture of "self.parent" + takeClosure { [weak tmp = self.parent] in print(tmp!.title) } + ``` + + The full form of a closure can take a signature (an argument list and + optionally a return type) if needed. To use either the capture list or the + signature, you must specify the context sensitive `in` keyword. Here is a + (weird because there is no need for `unowned`) example of a closure with both: + + ```swift + myNSSet.enumerateObjectsUsingBlock { [unowned self] (obj, stop) in + self.considerWorkingWith(obj) + } + ``` + +* The word `with` is now removed from the first keyword argument name + if an initialized imported from Objective-C. For example, instead of + building `UIColor` as: + + ```swift + UIColor(withRed: r, green: g, blue: b, alpha: a) + ``` + + it will now be: + + ```swift + UIColor(red: r, green: g, blue: b, alpha: a) + ``` + +* `Dictionary` can be bridged to `NSDictionary` and vice versa: + + - `NSDictionary` has an implicit conversion to `Dictionary`. It bridges in O(1), without memory allocation. + + - `Dictionary` has an implicit conversion to `NSDictionary`. + `Dictionary` bridges to `NSDictionary` iff both `K` and `V` are + bridged. Otherwise, a runtime error is raised. + + Depending on `K` and `V` the operation can be `O(1)` without memory + allocation, or `O(N)` with memory allocation. + +* Single-quoted literals are no longer recognized. Use double-quoted literals + and an explicit type annotation to define `Characters` and `UnicodeScalars`: + + ```swift + var ch: Character = "a" + var us: UnicodeScalar = "a" + ``` + +2014-05-09 +---------- + +* The use of keyword arguments is now strictly enforced at the call + site. For example, consider this method along with a call to it: + + ```swift + class MyColor { + func mixColorWithRed(red: Float, green: Float, blue: Float) { /* ... */ } + } + + func mix(color: MyColor, r: Float, g: Float, b: Float) { + color.mixColorWithRed(r, g, b) + } + ``` + + The compiler will now complain about the missing `green:` and + `blue:` labels, with a Fix-It to correct the code: + + ``` + color.swift:6:24: error: missing argument labels 'green:blue:' in call + color.mixColorWithRed(r, g, b) + ^ + green: blue: + ``` + + The compiler handles missing, extraneous, and incorrectly-typed + argument labels in the same manner. Recall that one can make a + parameter a keyword argument with the back-tick or remove a keyword + argument with the underscore. + + ```swift + class MyColor { + func mixColor(`red: Float, green: Float, blue: Float) { /* ... */ } + func mixColorGuess(red: Float, _ green: Float, _ blue: Float) { /* ... */ } + } + + func mix(color: MyColor, r: Float, g: Float, b: Float) { + color.mixColor(red: r, green: g, blue: b) // okay: all keyword arguments + color.mixColorGuess(r, g, b) // okay: no keyword arguments + } + ``` + + Arguments cannot be re-ordered unless the corresponding parameters + have default arguments. For example, given: + + ```swift + func printNumber(`number: Int, radix: Int = 10, separator: String = ",") { } + ``` + + The following three calls are acceptable because only the arguments for + defaulted parameters are re-ordered relative to each other: + + ```swift + printNumber(number: 256, radix: 16, separator: "_") + printNumber(number: 256, separator: "_") + printNumber(number: 256, separator: ",", radix: 16) + ``` + + However, this call: + + ```swift + printNumber(separator: ",", radix: 16, number: 256) + ``` + + results in an error due to the re-ordering: + + ``` + printnum.swift:7:40: error: argument 'number' must precede argument 'separator' + printNumber(separator: ",", radix: 16, number: 256) + ~~~~~~~~~~~~~~ ^ ~~~ + ``` + +* `;` can no longer be used to demarcate an empty case in a switch statement, + use `break` instead. + +2014-05-07 +---------- + +* The compiler's ability to diagnose many common kinds of type check errors has + improved. (`expression does not type-check` has been retired.) + +* Ranges can be formed with floating point numbers, e.g. `0.0 .. 100.0`. + +* Convenience initializers are now spelled as `convenience init` instead of with + the `-> Self` syntax. For example: + + ```swift + class Foo { + init(x : Int) {} // designated initializer + + convenience init() { self.init(42) } // convenience initializer + } + ``` + + You still cannot declare designated initializers in extensions, only + convenience initializers are allowed. + +* Reference types using the CoreFoundation runtime are now imported as + class types. This means that Swift will automatically manage the + lifetime of a `CFStringRef` the same way that it manages the lifetime + of an `NSString`. + + In many common cases, this will just work. Unfortunately, values + are returned from `CF`-style APIs in a wide variety of ways, and + unlike Objective C methods, there simply isn't enough consistency + for Swift to be able to safely apply the documented conventions + universally. The framework teams have already audited many of the + most important `CF`-style APIs, and those APIs should be imported + without a hitch into Swift. For all the APIs which haven't yet + been audited, we must import return types using the `Unmanaged` type. + This type allows the programmer to control exactly how the object + is passed. + + For example: + + ```swift + // CFBundleGetAllBundles() returns an Unmanaged. + // From the documentation, we know that it returns a +0 value. + let bundles = CFBundleGetAllBundles().takeUnretainedValue() + + // CFRunLoopCopyAllModes() returns an Unmanaged. + // From the documentation, we know that it returns a +1 value. + let modes = CFRunLoopCopyAllModes(CFRunLoopGetMain()).takeRetainedValue() + ``` + + You can also use `Unmanaged` types to pass and return objects + indirectly, as well as to generate unbalanced retains and releases + if you really require them. + + The API of the Unmanaged type is still in flux, and your feedback + would be greatly appreciated. + +2014-05-03 +---------- + +* The `@NSManaged` attribute can be applied to the properties of an + `NSManagedObject` subclass to indicate that they should be handled by + CoreData: + + ```swift + class Employee : NSManagedObject { + @NSManaged var name: String + @NSManaged var department: Department + } + ``` + +* The `@weak` and `@unowned` attributes have become context sensitive keywords + instead of attributes. To declare a `weak` or `unowned` pointer, use: + + ```swift + weak var someOtherWindow : NSWindow? + unowned var someWindow : NSWindow + ``` + ... with no `@` on the `weak`/`unowned`. + +2014-04-30 +---------- + +* Swift now supports a `#elseif` form for build configurations, e.g.: + + ```swift + #if os(OSX) + typealias SKColor = NSColor + #elseif os(iOS) + typealias SKColor = UIColor + #else + typealias SKColor = Green + #endif + ``` + +* You can now use the `true` and `false` constants in build configurations, + allowing you to emulate the C idioms of `#if 0` (but spelled `#if false`). + +* `break` now breaks out of switch statements. + +* It is no longer possible to specify `@mutating` as an attribute, you may only + use it as a keyword, e.g.: + + ```swift + struct Pair { + var x, y : Int + mutating func nuke() { x = 0; y = 0 } + } + ``` + The former `@!mutating` syntax used to mark setters as non-mutating is now + spelled with the `nonmutating` keyword. Both mutating and nonmutating are + context sensitive keywords. + +* `NSLog` is now available from Swift code. + +* The parser now correctly handles expressions like `var x = Int[]()` to + create an empty array of integers. Previously you'd have to use syntax like + `Array()` to get this. Now that this is all working, please prefer to + use `Int[]` consistently instead of `Array`. + +* `Character` is the new character literal type: + + ```swift + var x = 'a' // Infers 'Character' type + ``` + + You can force inference of `UnicodeScalar` like this: + + ```swift + var scalar: UnicodeScalar = 'a' + ``` + + `Character` type represents a Unicode extended grapheme cluster (to put it + simply, a grapheme cluster is what users think of as a character: a base plus + any combining marks, or other cases explained in + [Unicode Standard Annex #29](http://unicode.org/reports/tr29/)). + +2014-04-22 +---------- + +* Loops and switch statements can now carry labels, and you can + `break`/`continue` to those labels. These use conventional C-style label + syntax, and should be dedented relative to the code they are in. An example: + + ```swift + func breakContinue(x : Int) -> Int { + Outer: + for a in 0..1000 { + + Switch: + switch x { + case 42: break Outer + case 97: continue Outer + case 102: break Switch + case 13: continue // continue always works on loops. + case 139: break // break will break out of the switch (but see below) + } + } + } + ``` + +* We are changing the behavior of `break` to provide C-style semantics, to allow + breaking out of a switch statement. Previously, break completely ignored + switches so that it would break out of the nearest loop. In the example above, + `case 139` would break out of the `Outer` loop, not the `Switch`. + + In order to avoid breaking existing code, we're making this a compile time + error instead of a silent behavior change. If you need a solution for the + previous behavior, use labeled break. + + This error will be removed in a week or two. + +* Cocoa methods and properties that are annotated with the + `NS_RETURNS_INNER_POINTER` attribute, including `-[NSData bytes]` and + `-[{NS,UI}Color CGColor]`, are now safe to use and follow the same lifetime + extension semantics as ARC. + +2014-04-18 +---------- +* Enabling/disabling of asserts + + ```swift + assert(condition, msg) + ``` + + is enabled/disabled dependent on the optimization level. In debug mode at + `-O0` asserts are enabled. At higher optimization levels asserts are disabled + and no code is generated for them. However, asserts are always type checked + even at higher optimization levels. + + Alternatively, assertions can be disabled/enabled by using the frontend flag + `-assert-config Debug`, or `-assert-config Release`. + +* Added optimization flag `-Ofast`. It disables all assertions (`assert`), and + runtime overflow and type checks. + +* The "selector-style" function and initializer declaration syntax is + being phased out. For example, this: + + ``` + init withRed(red: CGFloat) green(CGFloat) blue(CGFloat) alpha(CGFloat) + ``` + + will now be written as: + + ```swift + init(withRed red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) + ``` + + For each parameter, one can have both an argument API name (i.e., + `withRed`, which comes first and is used at the call site) and an + internal parameter name that follows it (i.e. `red`, which comes + second and is used in the implementation). When the two names are + the same, one can simply write the name once and it will be used for + both roles (as with `green`, `blue`, and `alpha` above). The + underscore (`_`) can be used to mean "no name", as when the + following function/method: + + ``` + func murderInRoom(room:String) withWeapon(weapon: String) + ``` + + is translated to: + + ```swift + func murderInRoom(_ room: String, withWeapon weapon: String) + ``` + + The compiler now complains when it sees the selector-style syntax + and will provide Fix-Its to rewrite to the newer syntax. + + Note that the final form of selector syntax is still being hammered + out, but only having one declaration syntax, which will be very + close to this, is a known. + +* Stored properties can now be marked with the `@NSCopying` attribute, which + causes their setter to be synthesized with a copy to `copyWithZone:`. This may + only be used with types that conform to the `NSCopying` protocol, or option + types thereof. For example: + + ```swift + @NSCopying var myURL : NSURL + ``` + + This fills the same niche as the (`copy`) attribute on Objective-C properties. + + +2014-04-16 +---------- + +* Optional variables and properties are now default-initialized to `nil`: + + ```swift + class MyClass { + var cachedTitle: String? // "= nil" is implied + } + ``` + +* `@IBOutlet` has been improved in a few ways: + + - `IBOutlets` can now be `@unchecked` optional. + + - An `IBOutlet` declared as non-optional, i.e., + + ```swift + @IBOutlet var button: NSButton + ``` + + will be treated as an `@unchecked` optional. This is considered to + be the best practice way to write an outlet, unless you want to explicitly + handle the null case - in which case, use `NSButton?` as the type. Either + way, the `= nil` that was formerly required is now implicit. + +* The precedence of `is` and `as` is now higher than comparisons, allowing the + following sorts of things to be written without parens: + + ```swift + if x is NSButton && y is NSButtonCell { ... } + + if 3/4 as Float == 6/8 as Float { ... } + ``` + +* Objective-C blocks are now transparently bridged to Swift closures. You never + have to write `@objc_block` when writing Objective-C-compatible methods anymore. + Block parameters are now imported as unchecked optional closure types, + allowing `nil` to be passed. + +2014-04-09 +---------- + +* `Dictionary` changes: + + - `Elements` are now tuples, so you can write + + ```swift + for (k, v) in d { + // ... + } + ``` + + - `keys` and `values` properties, which are `Collections` projecting + the corresponding aspect of each element. `Dictionary` indices are + usable with their `keys` and `values` properties, so: + + ```swift + for i in indices(d) { + let (k, v) = d[i] + assert(k == d.keys[i]) + assert(v == d.values[i]) + } + ``` + +* Semicolon can be used as a single no-op statement in otherwise empty cases in + `switch` statements: + + ```swift + switch x { + case 1, 2, 3: + print("x is 1, 2 or 3") + default: + ; + } + ``` + +* `override` is now a context sensitive keyword, instead of an attribute: + + ```swift + class Base { + var property: Int { return 0 } + func instanceFunc() {} + class func classFunc() {} + } + class Derived : Base { + override var property: Int { return 1 } + override func instanceFunc() {} + override class func classFunc() {} + } + ``` + +2014-04-02 +---------- + +* Prefix splitting for imported enums has been revised again due to feedback: + - If stripping off a prefix would leave an invalid identifier (like `10_4`), + leave one more word in the result than would otherwise be there + (`Behavior10_4`). + - If all enumerators have a `k` prefix (for `constant`) and the enum doesn't, + the `k` should not be considered when finding the common prefix. + - If the enum name is a plural (like `NSSomethingOptions`) and the enumerator + names use the singular form (`NSSomethingOptionMagic`), this is considered + a matching prefix (but only if nothing follows the plural). + +* Cocoa APIs that take pointers to plain C types as arguments now get imported + as taking the new `CMutablePointer` and `CConstPointer` types instead + of `UnsafePointer`. These new types allow implicit conversions from + Swift `inout` parameters and from Swift arrays: + + ```swift + let rgb = CGColorSpaceCreateDeviceRGB() + // CGColorRef CGColorCreate(CGColorSpaceRef, const CGFloat*); + let white = CGColorCreate(rgb, [1.0, 1.0, 1.0]) + + var s = 0.0, c = 0.0 + // void sincos(double, double*, double*); + sincos(M_PI/2, &s, &c) + ``` + + Pointers to pointers to ObjC classes, such as `NSError**`, get imported as + `ObjCMutablePointer`. This type doesn't work with arrays, but + accepts inouts or `nil`: + + ```swift + var error: NSError? = nil + let words = NSString.stringWithContentsOfFile("/usr/share/dict/words", + encoding: .UTF8StringEncoding, + error: &error) + ``` + + `Void` pointer parameters can be passed an array or inout of any type: + + ```swift + // + (NSData*)dataWithBytes:(const void*)bytes length:(NSUInteger)length; + let data = NSData.dataWithBytes([1.5, 2.25, 3.125], + length: sizeof(Double.self) * 3) + var fromData = [0.0, 0.0, 0.0] + // - (void)getBytes:(void*)bytes length:(NSUInteger)length; + data.getBytes(&fromData, length: sizeof(Double.self) * 3) + ``` + + Note that we don't know whether an API reads or writes the C pointer, so + you need to explicitly initialize values (like `s` and `c` above) even if + you know that the API overwrites them. + + This pointer bridging only applies to arguments, and only works with well- + behaved C and ObjC APIs that don't keep the pointers they receive as + arguments around or do other dirty pointer tricks. Nonstandard use of pointer + arguments still requires `UnsafePointer`. + +* Objective-C pointer types now get imported by default as the `@unchecked T?` + optional type. Swift class types no longer implicitly include `nil`. + + A value of `@unchecked T?` can be implicitly used as a value of `T`. + Swift will implicitly cause a reliable failure if the value is `nil`, + rather than introducing undefined behavior (as in Objective-C ivar + accesses or everything in C/C++) or silently ignoring the operation + (as in Objective-C message sends). + + A value of `@unchecked T?` can also be implicitly used as a value of `T?`, + allowing you explicitly handle the case of a `nil` value. For example, + if you would like to just silently ignore a message send a la Objective-C, + you can use the postfix `?` operator like so: + + ```swift + fieldsForKeys[kHeroFieldKey]?.setEditable(true) + ``` + + This design allows you to isolate and handle `nil` values in Swift code + without requiring excessive "bookkeeping" boilerplate to use values that + you expect to be non-`nil`. + + For now, we will continue to import C pointers as non-optional + `UnsafePointer` and `C*Pointer` types; that will be evaluated separately. + + We intend to provide attributes for Clang to allow APIs to opt in to + importing specific parameters, return types, etc. as either the + explicit optional type `T?` or the simple non-optional type `T`. + +* The "separated" call syntax, i.e., + + ``` + NSColor.colorWithRed(r) green(g) blue(b) alpha(a) + UIColor.init withRed(r) green(g) blue(b) alpha(a) + ``` + + is being removed. The compiler will now produce an error and provide + Fix-Its to rewrite calls to the "keyword-argument" syntax: + + ```swift + NSColor.colorWithRed(r, green: g, blue: b, alpha: a) + UIColor(withRed: r, green:g, blue:b, alpha: a) + ``` + +* The `objc` attribute now optionally accepts a name, which can be + used to provide the name for an entity as seen in Objective-C. For + example: + + ```swift + class MyType { + var enabled: Bool { + @objc(isEnabled) get { + // ... + } + } + } + ``` + + The `@objc` attribute can be used to name initializers, methods, + getters, setters, classes, and protocols. + +* Methods, properties and subscripts in classes can now be marked with the + `@final` attribute. This attribute prevents overriding the declaration in any + subclass, and provides better performance (since dynamic dispatch is avoided + in many cases). + + +2014-03-26 +---------- + +* Attributes on declarations are no longer comma separated. + + Old syntax: + + ``` + @_silgen_name("foo"), @objc func bar() {} + ``` + + New syntax: + + ```swift + @_silgen_name("foo") @objc + ``` + + The `,` was vestigial when the attribute syntax consisted of bracket lists. + +* `switch` now always requires a statement after a `case` or `default`. + + Old syntax: + + ```swift + switch x { + case .A: + case .B(1): + println(".A or .B(1)") + default: + // Ignore it. + } + ``` + + New syntax: + + ```swift + switch x { + case .A, .B(1): + println(".A or .B(1)") + default: + () // Ignore it. + } + ``` + + The following syntax can be used to introduce guard expressions for patterns + inside the `case`: + + ```swift + switch x { + case .A where isFoo(), + .B(1) where isBar(): + ... + } + ``` + +* Observing properties can now `@override` properties in a base class, so you + can observe changes that happen to them. + + ```swift + class MyAwesomeView : SomeBasicView { + @override + var enabled : Bool { + didSet { + println("Something changed") + } + } + ... + } + ``` + + Observing properties still invoke the base class getter/setter (or storage) + when accessed. + + +* An `as` cast can now be forced using the postfix `!` operator without using + parens: + + ```swift + class B {} + class D {} + + let b: B = D() + + // Before + let d1: D = (b as D)! + // After + let d2: D = b as D! + ``` + + Casts can also be chained without parens: + + ```swift + // Before + let b2: B = (((D() as B) as D)!) as B + // After + let b3: B = D() as B as D! as B + ``` + +* `as` can now be used in `switch` cases to match the result of a checked cast: + + ```swift + func printHand(hand: Any) { + switch hand { + case 1 as Int: + print("ace") + case 11 as Int: + print("jack") + case 12 as Int: + print("queen") + case 13 as Int: + print("king") + case let numberCard as Int: + print("\(numberCard)") + case let (a, b) as (Int, Int) where a == b: + print("two ") + printHand(a) + print("s") + case let (a, b) as (Int, Int): + printHand(a) + print(" and a ") + printHand(b) + case let (a, b, c) as (Int, Int, Int) where a == b && b == c: + print("three ") + printHand(a) + print("s") + case let (a, b, c) as (Int, Int, Int): + printHand(a) + print(", ") + printHand(b) + print(", and a ") + printHand(c) + default: + print("unknown hand") + } + } + printHand(1, 1, 1) // prints "three aces" + printHand(12, 13) // prints "queen and a king" + ``` + +* Enums and option sets imported from C/Objective-C still strip common + prefixes, but the name of the enum itself is now taken into consideration as + well. This keeps us from dropping important parts of a name that happen to be + shared by all members. + + ```objc + // NSFileManager.h + typedef NS_OPTIONS(NSUInteger, NSDirectoryEnumerationOptions) { + NSDirectoryEnumerationSkipsSubdirectoryDescendants = 1UL << 0, + NSDirectoryEnumerationSkipsPackageDescendants = 1UL << 1, + NSDirectoryEnumerationSkipsHiddenFiles = 1UL << 2 + } NS_ENUM_AVAILABLE(10_6, 4_0); + ``` + + ```swift + // Swift + let opts: NSDirectoryEnumerationOptions = .SkipsPackageDescendants + ``` + +* `init` methods in Objective-C protocols are now imported as + initializers. To conform to `NSCoding`, you will now need to provide + + ```swift + init withCoder(aDecoder: NSCoder) { ... } + ``` + + rather than + + ```swift + func initWithCoder(aDecoder: NSCoder) { ... } + ``` + +2014-03-19 +---------- + +* When a class provides no initializers of its own but has default + values for all of its stored properties, it will automatically + inherit all of the initializers of its superclass. For example: + + ```swift + class Document { + var title: String + + init() -> Self { + self.init(withTitle: "Default title") + } + + init withTitle(title: String) { + self.title = title + } + } + + class VersionedDocument : Document { + var version = 0 + + // inherits 'init' and 'init withTitle:' from Document + } + ``` + + When one does provide a designated initializer in a subclass, as in + the following example: + + ```swift + class SecureDocument : Document { + var key: CryptoKey + + init withKey(key: CryptoKey) -> Self { + self.init(withKey: key, title: "Default title") + } + + init withKey(key: CryptoKey) title(String) { + self.key = key + super.init(withTitle: title) + } + } + ``` + + the compiler emits Objective-C method stubs for all of the + designated initializers of the parent class that will abort at + runtime if called, and which indicate which initializer needs to be + implemented. This provides memory safety for cases where an + Objective-C initializer (such as `-[Document init]` in this example) + appears to be inherited, but isn't actually implemented. + +* `nil` may now be used as a Selector value. This allows calls to Cocoa methods + that accept `nil` selectors. + +* `[]` and `[:]` can now be used as the empty array and dictionary literal, + respectively. Because these carry no information about their element types, + they may only be used in a context that provides this information through type + inference (e.g. when passing a function argument). + +* Properties defined in classes are now dynamically dispatched and can be + overridden with `@override`. Currently `@override` only works with computed properties + overriding other computed properties, but this will be enhanced in coming weeks. + + +2014-03-12 +---------- + +* The `didSet` accessor of an observing property now gets passed in the old value, + so you can easily implement an action for when a property changes value. For + example: + + ```swift + class MyAwesomeView : UIView { + var enabled : Bool = false { + didSet(oldValue): + if oldValue != enabled { + self.needsDisplay = true + } + } + ... + } + ``` + +* The implicit argument name for set and willSet property specifiers has been + renamed from `(value)` to `(newValue)`. For example: + + ```swift + var i : Int { + get { + return 42 + } + set { // defaults to (newValue) instead of (value) + print(newValue) + } + } + ``` + +* The magic identifier `__FUNCTION__` can now be used to get the name of the + current function as a string. Like `__FILE__` and `__LINE__`, if + `__FUNCTION__` is used as a default argument, the function name of the caller + is passed as the argument. + + ```swift + func malkovich() { + println(__FUNCTION__) + } + malkovich() // prints "malkovich" + + func nameCaller(name: String = __FUNCTION__) -> String { + return name + } + + func foo() { + println(nameCaller()) // prints "foo" + } + + func foo(x: Int) bar(y: Int) { + println(nameCaller()) // prints "foo:bar:" + } + ``` + + At top level, `__FUNCTION__` gives the module name: + + ```swift + println(nameCaller()) // prints your module name + ``` + +* Selector-style methods can now be referenced without applying arguments + using member syntax `foo.bar:bas:`, for instance, to test for the availability + of an optional protocol method: + + ```swift + func getFrameOfObjectValueForColumn(ds: NSTableViewDataSource, + tableView: NSTableView, + column: NSTableColumn, + row: Int) -> AnyObject? { + if let getObjectValue = ds.tableView:objectValueForTableColumn:row: { + return getObjectValue(tableView, column, row) + } + return nil + } + ``` + +* The compiler now warns about cases where a variable is inferred to have + `AnyObject`, `AnyClass`, or `()` type, since type inference can turn a simple + mistake (e.g. failing to cast an `AnyObject` when you meant to) into something + with ripple effects. Here is a simple example: + + ``` + t.swift:4:5: warning: variable 'fn' inferred to have type '()', which may be unexpected + var fn = abort() + ^ + t.swift:4:5: note: add an explicit type annotation to silence this warning + var fn = abort() + ^ + : () + ``` + + If you actually did intend to declare a variable of one of these types, you + can silence this warning by adding an explicit type (indicated by the Fixit). + See **rdar://15263687 and rdar://16252090** for more rationale. + +* `x.type` has been renamed to `x.dynamicType`, and you can use `type` as a + regular identifier again. + +2014-03-05 +---------- + +* C macros that expand to a single constant string are now imported as global + constants. Normal string literals are imported as `CString`; `NSString` literals + are imported as `String`. + +* All values now have a `self` property, exactly equivalent to the value + itself: + + ```swift + let x = 0 + let x2 = x.self + ``` + + Types also have a `self` property that is the type object for that + type: + + ```swift + let theClass = NSObject.self + let theObj = theClass() + ``` + + References to type names are now disallowed outside of a constructor call + or member reference; to get a type object as a value, `T.self` is required. + This prevents the mistake of intending to construct an instance of a + class but forgetting the parens and ending up with the class object instead: + + ```swift + let x = MyObject // oops, I meant MyObject()... + return x.description() // ...and I accidentally called +description + // instead of -description + ``` + +* Initializers are now classified as **designated initializers**, which + are responsible for initializing the current class object and + chaining via `super.init`, and **convenience initializers**, which + delegate to another initializer and can be inherited. For example: + + ```swift + class A { + var str: String + + init() -> Self { // convenience initializer + self.init(withString: "hello") + } + + init withString(str: String) { // designated initializer + self.str = str + } + } + ``` + + When a subclass overrides all of its superclass's designated + initializers, the convenience initializers are inherited: + + ```swift + class B { + init withString(str: String) { // designated initializer + super.init(withString: str) + } + + // inherits A.init() + } + ``` + + Objective-C classes that provide `NS_DESIGNATED_INITIALIZER` + annotations will have their init methods mapped to designated + initializers or convenience initializers as appropriate; Objective-C + classes without `NS_DESIGNATED_INITIALIZER` annotations have all of + their `init` methods imported as designated initializers, which is + safe (but can be verbose for subclasses). Note that the syntax and + terminology is still somewhat in flux. + +* Initializers can now be marked as `required` with an attribute, + meaning that every subclass is required to provide that initializer + either directly or by inheriting it from a superclass. To construct + + ```swift + class View { + @required init withFrame(frame: CGRect) { ... } + } + + func buildView(subclassObj: View.Type, frame: CGRect) -> View { + return subclassObj(withFrame: frame) + } + + class MyView : View { + @required init withFrame(frame: CGRect) { + super.init(withFrame: frame) + } + } + + class MyOtherView : View { + // error: must override init withFrame(CGRect). + } + ``` + +* Properties in Objective-C protocols are now correctly imported as properties. + (Previously the getter and setter were imported as methods.) + +* Simple enums with no payloads, including `NS_ENUM`s imported + from Cocoa, now implicitly conform to the Equatable and Hashable protocols. + This means they can be compared with the `==` and `!=` operators and can + be used as `Dictionary` keys: + + ```swift + enum Flavor { + case Lemon, Banana, Cherry + } + + assert(Flavor.Lemon == .Lemon) + assert(Flavor.Banana != .Lemon) + + struct Profile { + var sweet, sour: Bool + } + + let flavorProfiles: Dictionary = [ + .Lemon: Profile(sweet: false, sour: true ), + .Banana: Profile(sweet: true, sour: false), + .Cherry: Profile(sweet: true, sour: true ), + ] + assert(flavorProfiles[.Lemon].sour) + ``` + +* `val` has been removed. Long live `let`! + +* Values whose names clash with Swift keywords, such as Cocoa methods or + properties named `class`, `protocol`, `type`, etc., can now be defined and + accessed by wrapping reserved keywords in backticks to suppress their builtin + meaning: + + ```swift + let `class` = 0 + let `type` = 1 + let `protocol` = 2 + println(`class`) + println(`type`) + println(`protocol`) + + func foo(Int) `class`(Int) {} + foo(0, `class`: 1) + ``` + +2014-02-26 +---------- + +* The `override` attribute is now required when overriding a method, + property, or subscript from a superclass. For example: + + ```swift + class A { + func foo() { } + } + + class B : A { + @override func foo() { } // 'override' is required here + } + ``` + +* We're renaming `val` back to `let`. The compiler accepts both for this week, + next week it will just accept `let`. Please migrate your code this week, sorry + for the back and forth on this. + +* Swift now supports `#if`, `#else` and `#endif` blocks, along with target + configuration expressions, to allow for conditional compilation within + declaration and statement contexts. + + Target configurations represent certain static information about the + compile-time build environment. They are implicit, hard-wired into the + compiler, and can only be referenced within the conditional expression of an + `#if` block. + + Target configurations are tested against their values via a pseudo-function + invocation expression, taking a single argument expressed as an identifier. + The argument represents certain static build-time information. + + There are currently two supported target configurations: + `os`, which can have the values `OSX` or `iOS` + `arch`, which can have the values `i386`, `x86_64`, `arm` and `arm64` + + Within the context of an `#if` block's conditional expression, a target + configuration expression can evaluate to either `true` or `false`. + + For example: + + ```swift + #if arch(x86_64) + println("Building for x86_64") + #else + println("Not building for x86_64") + #endif + + class C { + #if os(OSX) + func foo() { + // OSX stuff goes here + } + #else + func foo() { + // non-OSX stuff goes here + } + #endif + } + ``` + + The conditional expression of an `#if` block can be composed of one or more of + the following expression types: + - A unary expression, using `!` + - A binary expression, using `&&` or `||` + - A parenthesized expression + - A target configuration expression + + For example: + + ```swift + #if os(iOS) && !arch(I386) + ... + #endif + ``` + + Note that `#if`/`#else`/`#endif` blocks do not constitute a preprocessor, and + must form valid and complete expressions or statements. Hence, the following + produces a parser error: + + ```swift + class C { + + #if os(iOS) + func foo() {} + } + #else + func bar() {} + func baz() {} + } + #endif + ``` + + Also note that "active" code will be parsed, typechecked and emitted, while + "inactive" code will only be parsed. This is why code in an inactive `#if` or + `#else` block will produce parser errors for malformed code. This allows the + compiler to detect basic errors in inactive regions. + + This is the first step to getting functionality parity with the important + subset of the C preprocessor. Further refinements are planned for later. + +* Swift now has both fully-closed ranges, which include their endpoint, and + half-open ranges, which don't. + + ```swift + (swift) for x in 0...5 { print(x) } ; print('\n') // half-open range + 01234 + (swift) for x in 0..5 { print(x) } ; print('\n') // fully-closed range + 012345 + ``` + +* Property accessors have a new brace-based syntax, instead of using the former + "label like" syntax. The new syntax is: + + ```swift + var computedProperty: Int { + get { + return _storage + } + set { + _storage = value + } + } + + var implicitGet: Int { // This form still works. + return 42 + } + + var storedPropertyWithObservingAccessors: Int = 0 { + willSet { ... } + didSet { ... } + } + ``` + +* Properties and subscripts now work in protocols, allowing you to do things + like: + + ```swift + protocol Subscriptable { + subscript(idx1: Int, idx2: Int) -> Int { get set } + var prop: Int { get } + } + + func foo(s: Subscriptable) { + return s.prop + s[42, 19] + } + ``` + + These can be used for generic algorithms now as well. + +* The syntax for referring to the type of a type, `T.metatype`, has been + changed to `T.Type`. The syntax for getting the type of a value, `typeof(x)`, + has been changed to `x.type`. + +* `DynamicSelf` is now called `Self`; the semantics are unchanged. + +* `destructor` has been replaced with `deinit`, to emphasize that it + is related to `init`. We will refer to these as + `deinitializers`. We've also dropped the parentheses, i.e.: + + ```swift + class MyClass { + deinit { + // release any resources we might have acquired, etc. + } + } + ``` + +* Class methods defined within extensions of Objective-C classes can + now refer to `self`, including using `instancetype` methods. As a + result, `NSMutableString`, `NSMutableArray`, and `NSMutableDictionary` + objects can now be created with their respective literals, i.e., + + ```swift + var dict: NSMutableDictionary = ["a" : 1, "b" : 2] + ``` + +2014-02-19 +---------- + +* The `Stream` protocol has been renamed back to `Generator,` which is + precedented in other languages and causes less confusion with I/O + streaming. + +* The `type` keyword was split into two: `static` and `class`. One can define + static functions and static properties in structs and enums like this: + + ```swift + struct S { + static func foo() {} + static var bar: Int = 0 + } + enum E { + static func foo() {} + } + ``` + + `class` keyword allows one to define class properties and class methods in + classes and protocols: + + ```swift + class C { + class func foo() {} + class var bar: Int = 0 + } + protocol P { + class func foo() {} + class var bar: Int = 0 + } + ``` + + When using `class` and `static` in the extension, the choice of keyword + depends on the type being extended: + + ```swift + extension S { + static func baz() {} + } + extension C { + class func baz() {} + } + ``` + +* The `let` keyword is no longer recognized. Please move to `val`. + +* The standard library has been renamed to `Swift` (instead of `swift`) to be + more consistent with other modules on our platforms. + +* `NSInteger` and other types that are layout-compatible with Swift standard + library types are now imported directly as those standard library types. + +* Optional types now support a convenience method named "cache" to cache the + result of a closure. For example: + + ```swift + class Foo { + var _lazyProperty: Int? + var property: Int { + return _lazyProperty.cache { computeLazyProperty() } + } + } + ``` + +2014-02-12 +---------- + +* We are experimenting with a new message send syntax. For example: + + ```swift + SKAction.colorizeWithColor(SKColor.whiteColor()) colorBlendFactor(1.0) duration(0.0) + ``` + + When the message send is too long to fit on a single line, subsequent lines + must be indented from the start of the statement or declaration. For + example, this is a single message send: + + ```swift + SKAction.colorizeWithColor(SKColor.whiteColor()) + colorBlendFactor(1.0) + duration(0.0) + ``` + + while this is a message send to colorizeWithColor: followed by calls + to `colorBlendFactor` and `duration` (on self or to a global function): + + ```swift + SKAction.colorizeWithColor(SKColor.whiteColor()) + colorBlendFactor(1.0) // call to 'colorBlendFactor' + duration(0.0) // call to 'duration' + ``` + +* We are renaming the `let` keyword to `val`. The `let` keyword didn't work + out primarily because it is not a noun, so "defining a let" never sounded + right. We chose `val` over `const` and other options because `var` and `val` + have similar semantics (making syntactic similarity useful), because `const` + has varied and sordid connotations in C that we don't want to bring over, and + because we don't want to punish the "preferred" case with a longer keyword. + + For migration purposes, the compiler now accepts `let` and `val` as synonyms, + `let` will be removed next week. + +* Selector arguments in function arguments with only a type are now implicitly + named after the selector chunk that contains them. For example, instead of: + + ```swift + func addIntsWithFirst(first : Int) second(second : Int) -> Int { + return first+second + } + ``` + + you can now write: + + ```swift + func addIntsWithFirst(first : Int) second(Int) -> Int { + return first+second + } + ``` + + if you want to explicitly want to ignore an argument, it is recommended that + you continue to use the `_` to discard it, as in: + + ```swift + func addIntsWithFirst(first : Int) second(_ : Int) -> Int {...} + ``` + +* The `@inout` attribute in argument lists has been promoted to a + context-sensitive keyword. Where before you might have written: + + ```swift + func swap(a : @inout T, b : @inout T) { + (a,b) = (b,a) + } + ``` + + You are now required to write: + + ```swift + func swap(inout a : T, inout b : T) { + (a,b) = (b,a) + } + ``` + + We made this change because `inout` is a fundamental part of the type + system, which attributes are a poor match for. The inout keyword is + also orthogonal to the `var` and `let` keywords (which may be specified in + the same place), so it fits naturally there. + +* The `@mutating` attribute (which can be used on functions in structs, + enums, and protocols) has been promoted to a context-sensitive keyword. + Mutating struct methods are now written as: + + ```swift + struct SomeStruct { + mutating func f() {} + } + ``` + +* Half-open ranges (those that don't include their endpoint) are now + spelled with three `.`s instead of two, for consistency with Ruby. + + ```swift + (swift) for x in 0...5 { print(x) } ; print('\n') // new syntax + 01234 + ``` + + Next week, we'll introduce a fully-closed range which does include + its endpoint. This will provide: + + ```swift + (swift) for x in 0..5 { print(x) } ; print('\n') // coming soon + 012345 + ``` + + These changes are being released separately so that users have a + chance to update their code before its semantics changes. + +* Objective-C properties with custom getters/setters are now imported + into Swift as properties. For example, the Objective-C property + + ```swift + @property (getter=isEnabled) BOOL enabled; + ``` + + was previously imported as getter (`isEnabled`) and setter + (`setEnabled`) methods. Now, it is imported as a property (`enabled`). + +* `didSet`/`willSet` properties may now have an initial value specified: + + ```swift + class MyAwesomeView : UIView { + var enabled : Bool = false { // Initial value. + didSet: self.needsDisplay = true + } + ... + } + ``` + + they can also be used as non-member properties now, e.g. as a global + variable or a local variable in a function. + +* Objective-C instancetype methods are now imported as methods that + return Swift's `DynamicSelf` type. While `DynamicSelf` is not + generally useful for defining methods in Swift, importing to it + eliminates the need for casting with the numerous `instancetype` APIs, + e.g., + + ```swift + let tileNode: SKSpriteNode = SKSpriteNode.spriteNodeWithTexture(tileAtlas.textureNamed("tile\(tileNumber).png"))! + ``` + + becomes + + ```swift + let tileNode = SKSpriteNode.spriteNodeWithTexture(tileAtlas.textureNamed("tile\(tileNumber).png")) + ``` + + `DynamicSelf` will become more interesting in the coming weeks. + +2014-02-05 +---------- + +* `if` and `while` statements can now conditionally bind variables. If the + condition of an `if` or `while` statement is a `let` declaration, then the + right-hand expression is evaluated as an `Optional` value, and control flow + proceeds by considering the binding to be `true` if the `Optional` contains a + value, or `false` if it is empty, and the variables are available in the true + branch. This allows for elegant testing of dynamic types, methods, nullable + pointers, and other Optional things: + + ```swift + class B : NSObject {} + class D : B { + func foo() { println("we have a D") } + } + var b: B = D() + if let d = b as D { + d.foo() + } + var id: AnyObject = D() + if let foo = id.foo { + foo() + } + ``` + +* When referring to a member of an `AnyObject` (or `AnyClass`) object + and using it directly (such as calling it, subscripting, or + accessing a property on it), one no longer has to write the `?` or + `!`. The run-time check will be performed implicitly. For example: + + ```swift + func doSomethingOnViews(views: NSArray) { + for view in views { + view.updateLayer() // no '!' needed + } + } + ``` + + Note that one can still test whether the member is available at + runtime using `?`, testing the optional result, or conditionally + binding a variable to the resulting member. + +* The `swift` command line tool can now create executables and libraries + directly, just like Clang. Use `swift main.swift` to create an executable and + `swift -emit-library -o foo.dylib foo.swift` to create a library. + +* Object files emitted by Swift are not debuggable on their own, even if you + compiled them with the `-g` option. This was already true if you had multiple + files in your project. To produce a debuggable Swift binary from the command + line, you must compile and link in a single step with `swift`, or pass object + files AND swiftmodule files back into `swift` after compilation. + (Or use Xcode.) + +* `import` will no longer import other source files, only built modules. + +* The current directory is no longer implicitly an import path. Use `-I .` if + you have modules in your current directory. + + +2014-01-29 +---------- + +* Properties in structs and classes may now have `willSet:` and `didSet:` + observing accessors defined on them: + + For example, where before you may have written something like this in a class: + + ```swift + class MyAwesomeView : UIView { + var _enabled : Bool // storage + var enabled : Bool { // computed property + get: + return _enabled + set: + _enabled = value + self.needDisplay = true + } + ... + } + ``` + + you can now simply write: + + ```swift + class MyAwesomeView : UIView { + var enabled : Bool { // Has storage & observing methods + didSet: self.needDisplay = true + } + ... + } + ``` + + Similarly, if you want notification before the value is stored, you can use + `willSet`, which gets the incoming value before it is stored: + + ```swift + var x : Int { + willSet(value): // value is the default and may be elided, as with set: + println("changing from \(x) to \(value)") + didSet: + println("we've got a value of \(x) now.\n") + } + ``` + + The `willSet`/`didSet` observers are triggered on any store to the property, + except stores from `init()`, destructors, or from within the observers + themselves. + + Overall, a property now may either be "stored" (the default), "computed" + (have a `get:` and optionally a `set:` specifier), or an observed + (`willSet`/`didSet`) property. It is not possible to have a custom getter + or setter on an observed property, since they have storage. + + Two known-missing bits are: + - **(rdar://problem/15920332) didSet/willSet variables need to allow initializers** + - **(rdar://problem/15922884) support non-member didset/willset properties** + + Because of the first one, for now, you need to explicitly store an initial + value to the property in your `init()` method. + +* Objective-C properties with custom getter or setter names are (temporarily) + not imported into Swift; the getter and setter will be imported individually + as methods instead. Previously, they would appear as properties within the + Objective-C class, but attempting to use the accessor with the customized + name would result in a crash. + + The long-term fix is tracked as **(rdar://problem/15877160)**. + +* Computed 'type' properties (that is, properties of types, rather + than of values of the type) are now permitted on classes, on generic + structs and enums, and in extensions. Stored 'type' properties in + these contexts remain unimplemented. + + The implementation of stored 'type' properties is tracked as + **(rdar://problem/15915785)** (for classes) and **(rdar://problem/15915867)** + (for generic types). + +* The following command-line flags have been deprecated in favor of new + spellings. The old spellings will be removed in the following week's build: + + | Old Spelling | New Spelling | + |--------------------------|-------------------------------| + | `-emit-llvm` | `-emit-ir` | + | `-triple` | `-target` | + | `-serialize-diagnostics` | `-serialize-diagnostics-path` | + +* Imported `NS_OPTIONS` types now have a default initializer which produces a + value with no options set. They can also be initialized to the empty set with + `nil`. These are equivalent: + + ```swift + var x = NSMatchingOptions() + var y: NSMatchingOptions = nil + ``` + + +2014-01-22 +---------- + +* The swift binary no longer has an SDK set by default. Instead, you must do + one of the following: + - pass an explicit `-sdk /path/to/sdk` + - set `SDKROOT` in your environment + - run `swift` through `xcrun`, which sets `SDKROOT` for you + +* `let` declarations can now be used as struct/class properties. A `let` + property is mutable within `init()`, and immutable everywhere else. + + ```swift + class C { + let x = 42 + let y : Int + init(y : Int) { + self.y = y // ok, self.y is mutable in init() + } + + func test() { + y = 42 // error: 'y' isn't mutable + } + } + ``` + +* The immutability model for structs and enums is complete, and arguments are + immutable by default. This allows the compiler to reject mutations of + temporary objects, catching common bugs. For example, this is rejected: + + ```swift + func setTo4(a : Double[]) { + a[10] = 4.0 // error: 'a' isn't mutable + } + ... + setTo4(someArray) + ``` + + since `a` is semantically a copy of the array passed into the function. The + proper fix in this case is to mark the argument is `@inout`, so the effect is + visible in the caller: + + ```swift + func setTo4(a : @inout Double[]) { + a[10] = 4.0 // ok: 'a' is a mutable reference + } + ... + setTo4(&someArray) + ``` + + Alternatively, if you really just want a local copy of the argument, you can + mark it `var`. The effects aren't visible in the caller, but this can be + convenient in some cases: + + ```swift + func doStringStuff(var s : String) { + s += "foo" + print(s) + } + ``` + +* Objective-C instance variables are no longer imported from headers written in + Objective-C. Previously, they would appear as properties within the + Objective-C class, but trying to access them would result in a crash. + Additionally, their names can conflict with property names, which confuses + the Swift compiler, and there are no patterns in our frameworks that expect + you to access a parent or other class's instance variables directly. Use + properties instead. + +* The `NSObject` protocol is now imported under the name + `NSObjectProtocol` (rather than `NSObjectProto`). + +2014-01-15 +---------- + +* Improved deallocation of Swift classes that inherit from Objective-C + classes: Swift destructors are implemented as `-dealloc` methods that + automatically call the superclass's `-dealloc`. Stored properties are + released right before the object is deallocated (using the same + mechanism as ARC), allowing properties to be safely used in + destructors. + +* Subclasses of `NSManagedObject` are now required to provide initial + values for each of their stored properties. This permits + initialization of these stored properties directly after +alloc to + provide memory safety with CoreData's dynamic subclassing scheme. + +* `let` declarations are continuing to make slow progress. Curried + and selector-style arguments are now immutable by default, and + `let` declarations now get proper debug information. + +2014-01-08 +---------- + +* The `static` keyword changed to `type`. One can now define "type + functions" and "type variables" which are functions and variables + defined on a type (rather than on an instance of the type), e.g., + + ```swift + class X { + type func factory() -> X { ... } + + type var version: Int + } + ``` + + The use of `static` was actively misleading, since type methods + on classes are dynamically dispatched (the same as Objective-C + `+` methods). + + Note that `type` is a context-sensitive keyword; it can still be + used as an identifier. + +* Strings have a new native UTF-16 representation that can be + converted back and forth to `NSString` at minimal cost. String + literals are emitted as UTF-16 for string types that support it + (including Swift's `String`). + +* Initializers can now delegate to other initializers within the same + class by calling `self.init`. For example: + + ```swift + class A { } + + class B : A { + var title: String + + init() { + // note: cannot access self before delegating + self.init(withTitle: "My Title") + } + + init withTitle(title: String) { + self.title = title + super.init() + } + } + ``` + +* Objective-C protocols no longer have the `Proto` suffix unless there + is a collision with a class name. For example, `UITableViewDelegate` is + now imported as `UITableViewDelegate` rather than + `UITableViewDelegateProto`. Where there is a conflict with a class, + the protocol will be suffixed with `Proto`, as in `NSObject` (the + class) and `NSObjectProto` (the protocol). + +2014-01-01 +---------- + +* Happy New Year + +* Division and remainder arithmetic now trap on overflow. Like with the other + operators, one can use the "masking" alternatives to get non-trapping + behavior. The behavior of the non-trapping masking operators is defined: + + ```swift + x &/ 0 == 0 + x &% 0 == 0 + SIGNED_MIN_FOR_TYPE &/ -1 == -1 // i.e. Int8: -0x80 / -1 == -0x80 + SIGNED_MIN_FOR_TYPE &% -1 == 0 + ``` + +* Protocol conformance checking for `@mutating` methods is now implemented: an + `@mutating` struct method only fulfills a protocol requirement if the protocol + method was itself marked `@mutating`: + + ```swift + protocol P { + func nonmutating() + @mutating + func mutating() + } + + struct S : P { + // Error, @mutating method cannot implement non-@mutating requirement. + @mutating + func nonmutating() {} + + // Ok, mutating allowed, but not required. + func mutating() {} + } + ``` + + As before, class methods never need to be marked `@mutating` (and indeed, they + aren't allowed to be marked as such). + + +2013-12-25 +---------- + +* Merry Christmas + +* The setters of properties on value types (structs/enums) are now `@mutating` by + default. To mark a setter non-mutating, use the `@!mutating` attribute. + +* Compiler inserts calls to `super.init()` into the class initializers that do + not call any initializers explicitly. + +* A `map` method with the semantics of Haskell's `fmap` was added to + `Array`. Map applies a function `f: T->U` to the values stored in + the array and returns an Array. So, + + ```swift + (swift) func names(x: Int[]) -> String[] { + return x.map { "<" + String($0) + ">" } + } + (swift) names(Array()) + // r0 : String[] = [] + (swift) names([3, 5, 7, 9]) + // r1 : String[] = ["<3>", "<5>", "<7>", "<9>"] + ``` + +2013-12-18 +---------- + +* Global variables and static properties are now lazily initialized on first + use. Where you would use `dispatch_once` to lazily initialize a singleton + object in Objective-C, you can simply declare a global variable with an + initializer in Swift. Like `dispatch_once`, this lazy initialization is thread + safe. + + Unlike C++ global variable constructors, Swift global variables and + static properties now never emit static constructors (and thereby don't + raise build warnings). Also unlike C++, lazy initialization naturally follows + dependency order, so global variable initializers that cross module + boundaries don't have undefined behavior or fragile link order dependencies. + +* Swift has the start of an immutability model for value types. As part of this, + you can now declare immutable value bindings with a new `let` declaration, + which is semantically similar to defining a get-only property: + + ```swift + let x = foo() + print(x) // ok + x = bar() // error: cannot modify an immutable value + swap(&x, &y) // error: cannot pass an immutable value as @inout parameter + x.clear() // error: cannot call mutating method on immutable value + getX().clear() // error: cannot mutate a temporary + ``` + + In the case of bindings of class type, the bound object itself is still + mutable, but you cannot change the binding. + + ```swift + let r = Rocket() + r.blastOff() // Ok, your rocket is mutable. + r = Rocket() // error: cannot modify an immutable binding. + ``` + + In addition to the `let` declaration itself, `self` on classes, and a few + other minor things have switched to immutable bindings. + + A pivotal part of this is that methods of value types (structs and enums) need + to indicate whether they can mutate self - mutating methods need to be + disallowed on let values (and get-only property results, temporaries, etc) but + non-mutating methods need to be allowed. The default for a method is that it + does not mutate `self`, though you can opt into mutating behavior with a new + `@mutating` attribute: + + ```swift + struct MyWeirdCounter { + var count : Int + + func empty() -> Bool { return count == 0 } + + @mutating + func reset() { + count = 0 + } + ... + } + + let x = MyWeirdCounter() + x.empty() // ok + x.reset() // error, cannot mutate immutable 'let' value + ``` + + One missing piece is that the compiler does not yet reject mutations of self + in a method that isn't marked `@mutating`. That will be coming soon. Related + to methods are properties. Getters and setters can be marked mutating as + well: + + ```swift + extension MyWeirdCounter { + var myproperty : Int { + get: + return 42 + + @mutating + set: + count = value*2 + } + } + ``` + + The intention is for setters to default to mutating, but this has not been + implemented yet. There is more to come here. + +* A `map` method with the semantics of Haskell's `fmap` was added to + `Optional`. Map applies a function `f: T->U` to any value stored in + an `Optional`, and returns an `Optional`. So, + + ```swift + (swift) func nameOf(x: Int?) -> String? { + return x.map { "<" + String($0) + ">" } + } + (swift) + (swift) var no = nameOf(.None) // Empty optional in... + // no : String? = + (swift) no ? "yes" : "no" // ...empty optional out + // r0 : String = "no" + (swift) + (swift) nameOf(.Some(42)) // Non-empty in + // r1 : String? = + (swift) nameOf(.Some(42))! // Non-empty out + // r2 : String = "<42>" + ``` + +* Cocoa types declared with the `NS_OPTIONS` macro are now available in Swift. + Like `NS_ENUM` types, their values are automatically shortened based + on the common prefix of the value names in Objective-C, and the name can + be elided when type context provides it. They can be used in `if` statements + using the `&`, `|`, `^`, and `~` operators as in C: + + ```swift + var options: NSJSONWritingOptions = .PrettyPrinted + if options & .PrettyPrinted { + println("pretty-printing enabled") + } + ``` + + We haven't yet designed a convenient way to author `NS_OPTIONS`-like types + in Swift. + +2013-12-11 +---------- + +* Objective-C `id` is now imported as `AnyObject` (formerly known as + `DynamicLookup`), Objective-C `Class` is imported as `AnyClass`. + +* The casting syntax `x as T` now permits both implicit conversions + (in which case it produces a value of type `T`) and for + runtime-checked casts (in which case it produces a value of type `T?` + that will be `.Some(casted x)` on success and `.None` on failure). An + example: + + ```swift + func f(x: AnyObject, y: NSControl) { + var view = y as NSView // has type 'NSView' + var maybeView = x as NSView // has type NSView? + } + ``` + +* The precedence levels of binary operators has been redefined, with a much + simpler model than C's. This is with a goal to define away classes of bugs + such as those caught by Clang's `-Wparentheses` warnings, and to make it + actually possible for normal humans to reason about the precedence + relationships without having to look them up. + + We ended up with 6 levels, from tightest binding to loosest: + ``` + exponentiative: <<, >> + multiplicative: *, /, %, & + additive: +, -, |, ^ + comparative: ==, !=, <, <=, >=, > + conjunctive: && + disjunctive: || + ``` + +* The `Enumerable` protocol has been renamed `Sequence`. + +* The `Char` type has been renamed `UnicodeScalar`. The preferred + unit of string fragments for users is called `Character`. + +* Initialization semantics for classes, structs and enums init methods are now + properly diagnosed by the compiler. Instance variables now follow the same + initialization rules as local variables: they must be defined before use. The + initialization model requires that all properties with storage in the current + class be initialized before `super.init` is called (or, in a root class, before + any method is called on `self,` and before the final return). + + For example, this will yield an error: + + ```swift + class SomeClass : SomeBase { + var x : Int + + init() { + // error: property 'self.x' not initialized at super.init call + super.init() + } + } + ``` + + A simple fix for this is to change the property definition to `var x = 0`, + or to explicitly assign to it before calling `super.init()`. + +* Relatedly, the compiler now diagnoses incorrect calls to `super.init()`. It + validates that any path through an initializer calls `super.init()` exactly once, + that all ivars are defined before the call to super.init, and that any uses + which require the entire object to be initialized come after the `super.init` + call. + +* Type checker performance has improved considerably (but we still + have much work to do here). + +2013-12-04 +---------- + +* The "slice" versus "array" subtlety is now dead. `Slice` has been folded + into `Array` and `T[]` is just sugar for `Array`. + + +2013-11-20 +---------- +* Unreachable code warning has been added: + + ```swift + var y: Int = 1 + if y == 1 { // note: condition always evaluates to true + return y + } + return 1 // warning: will never be executed + ``` + +* Overflows on integer type conversions are now detected at runtime and, when + dealing with constants, at compile time: + + ```swift + var i: Int = -129 + var i8 = Int8(i) + // error: integer overflows when converted from 'Int' to 'Int8' + + var si = Int8(-1) + var ui = UInt8(si) + // error: negative integer cannot be converted to unsigned type 'UInt8' + ``` + +* `def` keyword was changed back to `func`. + +2013-11-13 +---------- + +* Objective-C-compatible protocols can now contain optional + requirements, indicated by the `@optional` attribute: + + ```swift + @class_protocol @objc protocol NSWobbling { + @optional def wobble() + } + ``` + + A class that conforms to the `NSWobbling` protocol above can (but does + not have to) implement `wobble`. When referring to the `wobble` + method for a value of type `NSWobbling` (or a value of generic type + that is bounded by `NSWobbling`), the result is an optional value + indicating whether the underlying object actually responds to the + given selector, using the same mechanism as messaging `id`. One can + use `!` to assume that the method is always there, `?` to chain the + optional, or conditional branches to handle each case distinctly: + + ```swift + def tryToWobble(w : NSWobbling) { + w.wobble() // error: cannot call a value of optional type + w.wobble!() // okay: calls -wobble, but fails at runtime if not there + w.wobble?() // okay: calls -wobble only if it's there, otherwise no-op + if w.wobble { + // okay: we know -wobble is there + } else { + // okay: we know -wobble is not there + } + } + ``` + +* Enums from Cocoa that are declared with the `NS_ENUM` macro are now imported + into Swift as Swift enums. Like all Swift enums, the constants of the Cocoa + enum are scoped as members of the enum type, so the importer strips off the + common prefix of all of the constant names in the enum when forming the Swift + interface. For example, this Objective-C declaration: + + ```objc + typedef NS_ENUM(NSInteger, NSComparisonResult) { + NSOrderedAscending, + NSOrderedSame, + NSOrderedDescending, + }; + ``` + + shows up in Swift as: + + ```swift + enum NSComparisonResult : Int { + case Ascending, Same, Descending + } + ``` + + The `enum` cases can then take advantage of type inference from context. + In Objective-C, you would write: + + ```objc + NSNumber *foo = [NSNumber numberWithInt: 1]; + NSNumber *bar = [NSNumber numberWithInt: 2]; + + switch ([foo compare: bar]) { + case NSOrderedAscending: + NSLog(@"ascending\n"); + break; + case NSOrderedSame: + NSLog(@"same\n"); + break; + case NSOrderedDescending: + NSLog(@"descending\n"); + break; + } + ``` + + In Swift, this becomes: + + ```swift + var foo: NSNumber = 1 + var bar: NSNumber = 2 + + switch foo.compare(bar) { + case .Ascending: + println("ascending") + case .Same: + println("same") + case .Descending: + println("descending") + } + ``` + +* Work has begun on implementing static properties. Currently they are supported + for nongeneric structs and enums. + + ```swift + struct Foo { + static var foo: Int = 2 + } + enum Bar { + static var bar: Int = 3 + } + println(Foo.foo) + println(Bar.bar) + ``` + +2013-11-06 +---------- + +* `func` keyword was changed to `def`. + +* Implicit conversions are now allowed from an optional type `T?` to another + optional type `U?` if `T` is implicitly convertible to `U`. For example, + optional subclasses convert to their optional base classes: + + ```swift + class Base {} + class Derived : Base {} + + var d: Derived? = Derived() + var b: Base? = d + ``` + +2013-10-30 +---------- + +* Type inference for variables has been improved, allowing any + variable to have its type inferred from its initializer, including + global and instance variables: + + ```swift + class MyClass { + var size = 0 // inferred to Int + } + + var name = "Swift" + ``` + + Additionally, the arguments of a generic type can also be inferred + from the initializer: + + ```swift + // infers Dictionary + var dict: Dictionary = ["Hello": 1, "World": 2] + ``` + + +2013-10-23 +---------- + +* Missing return statement from a non-`Void` function is diagnosed as an error. + +* `Vector` has been replaced with `Array`. This is a complete rewrite to use + value-semantics and copy-on-write behavior. The former means that you never + need to defensively copy again (or remember to attribute a property as "copy") + and the latter yields better performance than defensive copying. `Dictionary` + is next. + +* `switch` can now pattern-match into structs and classes, using the syntax + `case Type(property1: pattern1, property2: pattern2, ...):`. + + ```swift + struct Point { var x, y: Double } + struct Size { var w, h: Double } + struct Rect { var origin: Point; var size: Size } + + var square = Rect(Point(0, 0), Size(10, 10)) + + switch square { + case Rect(size: Size(w: var w, h: var h)) where w == h: + println("square") + case Rect(size: Size(w: var w, h: var h)) where w > h: + println("long rectangle") + default: + println("tall rectangle") + } + ``` + + Currently only stored properties ("ivars" in ObjC terminology) are + supported by the implementation. + +* Array and dictionary literals allow an optional trailing comma: + + ```swift + var a = [ 1, 2, ] + var d = [ "a": 1, "b": 2, ] + ``` + +2013-10-16 +---------- +* Unlike in Objective-C, objects of type `id` in Swift do not + implicitly convert to any class type. For example, the following + code is ill-formed: + + ```swift + func getContentViewBounds(window : NSWindow) -> NSRect { + var view : NSView = window.contentView() // error: 'id' doesn't implicitly convert to NSView + return view.bounds() + } + ``` + + because `contentView()` returns an `id`. One can now use the postfix + `!` operator to allow an object of type `id` to convert to any class + type, e.g., + + ```swift + func getContentViewBounds(window : NSWindow) -> NSRect { + var view : NSView = window.contentView()! // ok: checked conversion to NSView + return view.bounds() + } + ``` + + The conversion is checked at run-time, and the program will fail if + the object is not an NSView. This is shorthand for + + ```swift + var view : NSView = (window.contentView() as NSView)! + ``` + + which checks whether the content view is an `NSView` (via the `as + NSView`). That operation returns an optional `NSView` (written + `NSView?`) and the `!` operation assumes that the cast succeeded, + i.e., that the optional has a value in it. + +* The unconditional checked cast syntax `x as! T` has been removed. Many cases + where conversion from `id` is necessary can now be handled by postfix `!` + (see above). Fully general unconditional casts can still be expressed using + `as` and postfix `!` together, `(x as T)!`. + +* The old "square bracket" attribute syntax has been removed. + +* Overflows on construction of integer and floating point values from integer + literals that are too large to fit the type are now reported by the compiler. + Here are some examples: + + ```swift + var x = Int8(-129) + // error: integer literal overflows when stored into 'Int8' + + var y : Int = 0xFFFF_FFFF_FFFF_FFFF_F + // error: integer literal overflows when stored into 'Int' + ``` + + Overflows in constant integer expressions are also reported by the compiler. + + ```swift + var x : Int8 = 125 + var y : Int8 = x + 125 + // error: arithmetic operation '125 + 125' (on type 'Int8') results in + // an overflow + ``` + +* Division by zero in constant expressions is now detected by the compiler: + + ```swift + var z: Int = 0 + var x = 5 / z // error: division by zero + ``` + +* Generic structs with type parameters as field types are now fully supported. + + ```swift + struct Pair { + var first: T + var second: U + } + ``` + +2013-10-09 +---------- +* Autorelease pools can now be created using the `autoreleasepool` function. + + ```swift + autoreleasepool { + // code + } + ``` + + Note that the wrapped code is a closure, so constructs like `break` and + `continue` and `return` do not behave as they would inside an Objective-C + `@autoreleasepool` statement. + +* Enums can now declare a "raw type", and cases can declare "raw values", + similar to the integer underlying type of C enums: + + ```swift + // Declare the underlying type as in Objective-C or C++11, with + // ': Type' + enum AreaCode : Int { + // Assign explicit values to cases with '=' + case SanFrancisco = 415 + case EastBay = 510 + case Peninsula = 650 + case SanJose = 408 + // Values are also assignable by implicit auto-increment + case Galveston // = 409 + case Baltimore // = 410 + } + ``` + + This introduces `fromRaw` and `toRaw` methods on the enum to perform + conversions from and to the raw type: + + ```swift + /* As if declared: + extension AreaCode { + // Take a raw value, and produce the corresponding enum value, + // or None if there is no corresponding enum value + static func fromRaw(raw:Int) -> AreaCode? + + + // Return the corresponding raw value for 'self' + func toRaw() -> Int + } + */ + + AreaCode.fromRaw(415) // => .Some(.SanFrancisco) + AreaCode.fromRaw(111) // => .None + AreaCode.SanJose.toRaw() // => 408 + ``` + + Raw types are not limited to integer types--they can additionally be + character, floating-point, or string values: + + ```swift + enum State : String { + case CA = "California" + case OR = "Oregon" + case WA = "Washington" + } + + enum SquareRootOfInteger : Float { + case One = 1.0 + case Two = 1.414 + case Three = 1.732 + case Four = 2.0 + } + ``` + + Raw types are currently limited to simple C-like enums with no payload cases. + The raw values are currently restricted to simple literal values; expressions + such as `1 + 1` or references to other enum cases are not yet supported. + Raw values are also currently required to be unique for each case in an enum. + + Enums with raw types implicitly conform to the `RawRepresentable` protocol, + which exposes the fromRaw and toRaw methods to generics: + + ```swift + protocol RawRepresentable { + typealias RawType + static func fromRaw(raw: RawType) -> Self? + func toRaw() -> RawType + } + ``` + +* Attribute syntax has been redesigned (see **(rdar://10700853)** and + **(rdar://14462729)**) so that attributes now precede the declaration and use + the `@` character to signify them. Where before you might have written: + + ```swift + func [someattribute=42] foo(a : Int) {} + ``` + + you now write: + + ```swift + @someattribute=42 + func foo(a : Int) {} + ``` + + This flows a lot better (attributes don't push the name for declarations away), + and means that square brackets are only used for array types, collection + literals, and subscripting operations. + +* The `for` loop now uses the Generator protocol instead of the `Enumerator` + protocol to iterate a sequence. This protocol looks like this: + + ```swift + protocol Generator { + typealias Element + func next() -> Element? + } + ``` + + The single method `next()` advances the generator and returns an + Optional, which is either `.Some(value)`, wrapping the next value out + of the underlying sequence, or `.None` to signal that there are no + more elements. This is an improvement over the previous Enumerator + protocol because it eliminates the separate `isEmpty()` query and + better reflects the semantics of ephemeral sequences like + un-buffered input streams. + +2013-10-02 +---------- +* The `[byref]` attribute has been renamed to `[inout]`. When applied to a logical + property, the getter is invoked before a call and the setter is applied to + write back the result. `inout` conveys this better and aligns with existing + Objective-C practice better. + +* `[inout]` arguments can now be captured into closures. The semantics of a + inout capture are that the captured variable is an independent local variable + of the callee, and the inout is updated to contain the value of that local + variable at function exit. + + In the common case, most closure arguments do not outlive the duration of + their callee, and the observable behavior is unchanged. However, if the + captured variable outlives the function, you can observe this. For example, + this code: + + ```swift + func foo(x : [inout] Int) -> () -> Int { + func bar() -> Int { + x += 1 + return x + } + // Call 'bar' once while the inout is active. + bar() + return bar + } + + var x = 219 + var f = foo(&x) + // x is updated to the value of foo's local x at function exit. + println("global x = \(x)") + // These calls only update the captured local 'x', which is now independent + // of the inout parameter. + println("local x = \(f())") + println("local x = \(f())") + println("local x = \(f())") + + println("global x = \(x)") + ``` + + will print: + + ``` + global x = 220 + local x = 221 + local x = 222 + local x = 223 + global x = 220 + ``` + + In no case will you end up with a dangling pointer or other unsafe construct. + +* `x as T` now performs a checked cast to `T?`, producing `.Some(t)` if the + cast succeeds, or `.None` if the cast fails. + +* The ternary expression (`x ? y : z`) now requires whitespace between the + first expression and the question mark. This permits `?` to be used + as a postfix operator. + +* A significant new piece of syntactic sugar has been added to ease working + with optional values. The `?` postfix operator is analogous to `!`, but + instead of asserting on None, it causes all the following postfix + operators to get skipped and return `None`. + + In a sense, this generalizes (and makes explicit) the Objective-C behavior + where message sends to `nil` silently produce the zero value of the result. + + For example, this code + + ```swift + object?.parent.notifyChildEvent?(object!, .didExplode) + ``` + + first checks whether `object` has a value; if so, it drills to its + parent and checks whether that object implements the `notifyChildEvent` + method; if so, it calls that method. (Note that we do not yet have + generalized optional methods.) + + This code: + + ```swift + var titleLength = object?.title.length + ``` + + checks whether `object` has a value and, if so, asks for the length of + its title. `titleLength` will have type `Int?`, and if `object` was + missing, the variable will be initialized to None. + +* Objects with type `id` can now be used as the receiver of property + accesses and subscript operations to get (but not set) values. The + result is of optional type. For example, for a variable `obj` of + type `id`, the expression + + ```swift + obj[0] + ``` + + will produce a value of type `id`, which will either contain the + result of the message send objectAtIndexedSubscript(0) (wrapped in an + optional type) or, if the object does not respond to + `objectAtIndexedSubscript:`, an empty optional. The same approach + applies to property accesses. + +* `_` can now be used not only in `var` bindings, but in assignments as well, + to ignore elements of a tuple assignment, or to explicitly ignore values. + + ```swift + var a = (1, 2.0, 3) + var x = 0, y = 0 + _ = a // explicitly load and discard 'a' + (x, _, y) = a // assign a.0 to x and a.2 to y + ``` + +2013-09-24 +---------- +* The `union` keyword has been replaced with `enum`. Unions and enums + are semantically identical in swift (the former just has data + associated with its discriminators) and `enum` is the vastly more + common case. For more rationale, please see + [docs/proposals/Enums.rst](https://github.com/apple/swift/blob/master/docs/proposals/Enums.rst) + +* The Optional type `T?` is now represented as an `enum`: + + ```swift + enum Optional { + case None + case Some(T) + } + ``` + + This means that, in addition to the existing Optional APIs, it can be + pattern-matched with switch: + + ```swift + var x : X?, y : Y? + switch (x, y) { + // Both are present + case (.Some(var a), .Some(var b)): + println("both") + + // One is present + case (.Some, .None): + case (.None, .Some): + println("one") + + // Neither is present + case (.None, .None): + println("neither") + } + ``` + +* Enums now allow multiple cases to be declared in a comma-separated list + in a single `case` declaration: + + ```swift + enum Color { + case Red, Green, Blue + } + ``` + +* The Objective-C `id` and `Class` types now support referring to + methods declared in any class or protocol without a downcast. For + example, given a variable `sender` of type `id`, one can refer to + `-isEqual: with:` + + ```swift + sender.isEqual + ``` + + The actual object may or may not respond to `-isEqual`, so this + expression returns result of optional type whose value is determined via a + compiler-generated `-respondsToSelector` send. When it succeeds, the + optional contains the method; when it fails, the optional is empty. + + To safely test the optional, one can use, e.g., + + ```swift + var senderIsEqual = sender.isEqual + if senderIsEqual { + // this will never trigger an "unrecognized selector" failure + var equal = senderIsEqual!(other) + } else { + // sender does not respond to -isEqual: + } + ``` + + When you *know* that the method is there, you can use postfix `!` to + force unwrapping of the optional, e.g., + + ```swift + sender.isEqual!(other) + ``` + + This will fail at runtime if in fact sender does not respond to `-isEqual:`. + We have some additional syntactic optimizations planned for testing + an optional value and handling both the success and failure cases + concisely. Watch this space. + +* Weak references now always have optional type. If a weak variable + has an explicit type, it must be an optional type: + + ```swift + var [weak] x : NSObject? + ``` + + If the variable is not explicitly typed, its type will still be + inferred to be an optional type. + +* There is now an implicit conversion from `T` to `T?`. + +2013-09-17 +---------- +* Constructor syntax has been improved to align better with + Objective-C's `init` methods. The `constructor` keyword has been + replaced with `init`, and the selector style of declaration used for + func declarations is now supported. For example: + + ```swift + class Y : NSObject { + init withInt(i : Int) string(s : String) { + super.init() // call superclass initializer + } + } + ``` + + One can use this constructor to create a `Y` object with, e.g., + + ```swift + Y(withInt:17, string:"Hello") + ``` + + Additionally, the rules regarding the selector corresponding to such + a declaration have been revised. The selector for the above + initializer is `initWithInt:string:`; the specific rules are + described in the documentation. + + Finally, Swift initializers now introduce Objective-C entry points, + so a declaration such as: + + ```swift + class X : NSObject { + init() { + super.init() + } + } + ``` + + Overrides `NSObject`'s `-init` method (which it calls first) as well + as introducing the 'allocating' entry point so that one can create a + new `X` instance with the syntax `X()`. + +* Variables in top-level code (i.e. scripts, but not global variables in + libraries) that lack an initializer now work just like local variables: + they must be explicitly assigned-to sometime before any use, instead of + being default constructed. Instance variables are still on the TODO + list. + +* Generic unions with a single payload case and any number of empty cases + are now implemented, for example: + + ```swift + union Maybe { + case Some(T) + case None + } + + union Tristate { + case Initialized(T) + case Initializing + case Uninitialized + } + ``` + + Generic unions with multiple payload cases are still not yet implemented. + +2013-09-11 +---------- +* The implementation now supports partial application of class and struct + methods: + + ```swift + (swift) class B { func foo() { println("B") } } + (swift) class D : B { func foo() { println("D") } } + (swift) var foo = B().foo + // foo : () -> () = + (swift) foo() + B + (swift) foo = D().foo + (swift) foo() + D + ``` + + Support for partial application of Objective-C class methods and methods in + generic contexts is still incomplete. + +2013-09-04 +---------- +* Local variable declarations without an initializer are no longer implicitly + constructed. The compiler now verifies that they are initialized on all + paths leading to a use of the variable. This means that constructs like this + are now allowed: + + ```swift + var p : SomeProtocol + if whatever { + p = foo() + } else { + p = bar() + } + ``` + + where before, the compiler would reject the definition of `p` saying that it + needed an initializer expression. + + Since all local variables must be initialized before use, simple things like + this are now rejected as well: + + ```swift + var x : Int + print(x) + ``` + + The fix is to initialize the value on all paths, or to explicitly default + initialize the value in the declaration, e.g. with `var x = 0` or with + `var x = Int()` (which works for any default-constructible type). + +* The implementation now supports unions containing protocol types and weak + reference types. + +* The type annotation syntax, `x as T`, has been removed from the language. + The checked cast operations `x as! T` and `x is T` still remain. + +2013-08-28 +---------- +* `this` has been renamed to `self`. Similarly, `This` has been renamed to + `Self`. + +* Swift now supports unions. Unlike C unions, Swift's `union` is type-safe + and always knows what type it contains at runtime. Union members are labeled + using `case` declarations; each case may have a different set of + types or no type: + + ```swift + union MaybeInt { + case Some(Int) + case None + } + + union HTMLTag { + case A(href:String) + case IMG(src:String, alt:String) + case BR + } + ``` + + Each `case` with a type defines a static constructor function for the union + type. `case` declarations without types become static members: + + ```swift + var br = HTMLTag.BR + var a = HTMLTag.A(href:"http://www.apple.com/") + // 'HTMLTag' scope deduced for '.IMG' from context + var img : HTMLTag = .IMG(src:"http://www.apple.com/mac-pro.png", + alt:"The new Mac Pro") + ``` + + Cases can be pattern-matched using `switch`: + + ```swift + switch tag { + case .BR: + println("
") + case .IMG(var src, var alt): + println("\"\(escape(alt))\"") + case .A(var href): + println("") + } + ``` + + Due to implementation limitations, recursive unions are not yet supported. + +* Swift now supports autolinking, so importing frameworks or Swift libraries + should no longer require adding linker flags or modifying your project file. + +2013-08-14 +---------- +* Swift now supports weak references by applying the `[weak]` attribute to a + variable declaration. + + ```swift + (swift) var x = NSObject() + // x : NSObject = + (swift) var [weak] w = x + // w : NSObject = + (swift) w == nil + // r2 : Bool = false + (swift) x = NSObject() + (swift) w == nil + // r3 : Bool = true + ``` + + Swift also supports a special form of weak reference, called `[unowned]`, for + references that should never be nil but are required to be weak to break + cycles, such as parent or sibling references. Accessing an `[unowned]` + reference asserts that the reference is still valid and implicitly promotes + the loaded reference to a strong reference, so it does not need to be loaded + and checked for nullness before use like a true `[weak]` reference. + + ```swift + class Parent { + var children : Array + + func addChild(c:Child) { + c.parent = this + children.append(c) + } + } + + class Child { + var [unowned] parent : Parent + } + ``` + +2013-07-31 +---------- +* Numeric literals can now use underscores as separators. For example: + + ```swift + var billion = 1_000_000_000 + var crore = 1_00_00_000 + var MAXINT = 0x7FFF_FFFF_FFFF_FFFF + var SMALLEST_DENORM = 0x0.0000_0000_0000_1p-1022 + ``` + +* Types conforming to protocols now must always declare the conformance in + their inheritance clause. + +* The build process now produces serialized modules for the standard library, + greatly improving build times. + +2013-07-24 +---------- +* Arithmetic operators `+`, `-`, `*`, and `/` on integer types now do + overflow checking and trap on overflow. A parallel set of masking operators, + `&+`, `&-`, `&*`, and `&/`, are defined to perform two's complement wrapping + arithmetic for all signed and unsigned integer types. + +* Debugger support. Swift has a `-g` command line switch that turns on + debug info for the compiled output. Using the standard lldb debugger + this will allow single-stepping through Swift programs, printing + backtraces, and navigating through stack frames; all in sync with + the corresponding Swift source code. An unmodified lldb cannot + inspect any variables. + + Example session: + + ``` + $ echo 'println("Hello World")' >hello.swift + $ swift hello.swift -c -g -o hello.o + $ ld hello.o "-dynamic" "-arch" "x86_64" "-macosx_version_min" "10.9.0" \ + -framework Foundation lib/swift/libswift_stdlib_core.dylib \ + lib/swift/libswift_stdlib_posix.dylib -lSystem -o hello + $ lldb hello + Current executable set to 'hello' (x86_64). + (lldb) b top_level_code + Breakpoint 1: where = hello`top_level_code + 26 at hello.swift:1, addre... + (lldb) r + Process 38592 launched: 'hello' (x86_64) + Process 38592 stopped + * thread #1: tid = 0x1599fb, 0x0000000100000f2a hello`top_level_code + ... + frame #0: 0x0000000100000f2a hello`top_level_code + 26 at hello.shi... + -> 1 println("Hello World") + (lldb) bt + * thread #1: tid = 0x1599fb, 0x0000000100000f2a hello`top_level_code + ... + frame #0: 0x0000000100000f2a hello`top_level_code + 26 at hello.shi... + frame #1: 0x0000000100000f5c hello`main + 28 + frame #2: 0x00007fff918605fd libdyld.dylib`start + 1 + frame #3: 0x00007fff918605fd libdyld.dylib`start + 1 + ``` + + Also try `s`, `n`, `up`, `down`. + +2013-07-17 +---------- +* Swift now has a `switch` statement, supporting pattern matching of + multiple values with variable bindings, guard expressions, and range + comparisons. For example: + + ```swift + func classifyPoint(point:(Int, Int)) { + switch point { + case (0, 0): + println("origin") + + case (_, 0): + println("on the x axis") + + case (0, _): + println("on the y axis") + + case (var x, var y) where x == y: + println("on the y = x diagonal") + + case (var x, var y) where -x == y: + println("on the y = -x diagonal") + + case (-10..10, -10..10): + println("close to the origin") + + case (var x, var y): + println("length \(sqrt(x*x + y*y))") + } + } + ``` + +2013-07-10 +---------- +* Swift has a new closure syntax. The new syntax eliminates the use of + pipes. Instead, the closure signature is written the same way as a + function type and is separated from the body by the `in` + keyword. For example: + + ```swift + sort(fruits) { (lhs : String, rhs : String) -> Bool in + return lhs > rhs + } + ``` + + When the types are omitted, one can also omit the parentheses, e.g., + + ```swift + sort(fruits) { lhs, rhs in lhs > rhs } + ``` + + Closures with no parameters or that use the anonymous parameters + (`$0`, `$1`, etc.) don't need the `in`, e.g., + + ```swift + sort(fruits) { $0 > $1 } + ``` + +* `nil` can now be used without explicit casting. Previously, `nil` had + type `NSObject`, so one would have to write (e.g.) `nil as! NSArray` + to create a `nil` `NSArray`. Now, `nil` picks up the type of its + context. + +* `POSIX.EnvironmentVariables` and `swift.CommandLineArguments` global variables + were merged into a `swift.Process` variable. Now you can access command line + arguments with `Process.arguments`. In order to access environment variables + add `import POSIX` and use `Process.environmentVariables`. diff --git a/CMakeLists.txt b/CMakeLists.txt index 0acafae8e4864..8a96d44f4c37e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,9 +44,9 @@ option(SWIFT_BUILD_STATIC_STDLIB "Build static variants of the Swift standard library and SDK overlay" FALSE) -option(SWIFT_INCLUDE_BENCHMARKS - "Create targets for running swift benchmarks" - TRUE) +option(SWIFT_BUILD_PERF_TESTSUITE + "Create targets for swift performance benchmarks." + FALSE) option(SWIFT_INCLUDE_TESTS "Create targets for building/running tests." TRUE) @@ -54,10 +54,6 @@ option(SWIFT_INCLUDE_DOCS "Create targets for building docs." TRUE) -option(SWIFT_ENABLE_TARGET_LINUX - "Enable compiler support for targeting Linux" - TRUE) - set(SWIFT_VERSION "2.2" CACHE STRING "The user-visible version of the Swift compiler") set(SWIFT_VENDOR "" CACHE STRING @@ -73,7 +69,7 @@ set(SWIFT_ENABLE_GOLD_LINKER FALSE CACHE BOOL "Enable using the gold linker when available") set(_SWIFT_KNOWN_INSTALL_COMPONENTS - "compiler;clang-builtin-headers;clang-resource-dir-symlink;clang-builtin-headers-in-clang-resource-dir;stdlib;stdlib-experimental;sdk-overlay;editor-integration;tools;testsuite-tools;dev;sourcekit-xpc-service;sourcekit-inproc") + "compiler;clang-builtin-headers;clang-resource-dir-symlink;clang-builtin-headers-in-clang-resource-dir;stdlib;stdlib-experimental;sdk-overlay;editor-integration;tools;testsuite-tools;dev;license;sourcekit-xpc-service;sourcekit-inproc") # Set the SWIFT_INSTALL_COMPONENTS variable to the default value if it is not passed in via -D set(SWIFT_INSTALL_COMPONENTS "${_SWIFT_KNOWN_INSTALL_COMPONENTS}" CACHE STRING @@ -153,6 +149,9 @@ option(SWIFT_RUNTIME_CRASH_REPORTER_CLIENT "Whether to enable CrashReporter integration" FALSE) +set(SWIFT_DARWIN_XCRUN_TOOLCHAIN "XcodeDefault" CACHE STRING + "The name of the toolchain to pass to 'xcrun'") + set(SWIFT_DARWIN_ICU_INCLUDE_PATH "" CACHE STRING "Path to the directory where the ICU headers are located") @@ -208,11 +207,7 @@ set(SWIFT_EXPERIMENTAL_EXTRA_REGEXP_FLAGS "" CACHE STRING "A list of [module_regexp1;flags1;module_regexp2;flags2,...] which can be used to apply specific flags to modules that match a cmake regexp. It always applies the first regexp that matches.") set(SWIFT_EXPERIMENTAL_EXTRA_NEGATIVE_REGEXP_FLAGS "" CACHE STRING - "A list of [module_regexp1;flags1;module_regexp2;flags2,...] which can be used to apply specific flags to modules that do not match a cmake regexp. It always applies the first regexp that does not matche. The reason this is necessary is that cmake does not provide negative matches in the regex. Instead you have to use NOT in the if statement requiring a separate variable.") - -option(SWIFT_RUNTIME_ENABLE_DTRACE - "Should the runtime be built with dtrace instrumentation enabled" - FALSE) + "A list of [module_regexp1;flags1;module_regexp2;flags2,...] which can be used to apply specific flags to modules that do not match a cmake regexp. It always applies the first regexp that does not match. The reason this is necessary is that cmake does not provide negative matches in the regex. Instead you have to use NOT in the if statement requiring a separate variable.") option(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER "Should the runtime be built with support for non-thread-safe leak detecting entrypoints" @@ -250,9 +245,6 @@ endif() option(SWIFT_BUILD_SOURCEKIT "Build SourceKit" ${SWIFT_BUILD_SOURCEKIT_default}) -# Force updating the cache, remove the following after a couple of weeks or so. -set(SWIFT_BUILD_SOURCEKIT ${SWIFT_BUILD_SOURCEKIT_default} - CACHE BOOL "Build SourceKit" FORCE) # # Include CMake modules @@ -313,7 +305,7 @@ if(NOT EXISTS "${CLANG_MAIN_INCLUDE_DIR}/clang/AST/Decl.h") endif() # This could be computed using ${CMAKE_CFG_INTDIR} if we want to link Swift -# against a mathing LLVM build configuration. However, we usually want to be +# against a matching LLVM build configuration. However, we usually want to be # flexible and allow linking a debug Swift against optimized LLVM. set(LLVM_RUNTIME_OUTPUT_INTDIR "${LLVM_BINARY_DIR}") set(LLVM_LIBRARY_OUTPUT_INTDIR "${LLVM_LIBRARY_DIR}") @@ -419,27 +411,63 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") "Deployment OS for Swift host tools (the compiler) [linux].") set(SWIFT_HOST_VARIANT_SDK "LINUX") - set(SWIFT_HOST_VARIANT_ARCH "x86_64") - set(swift_can_crosscompile_stdlib TRUE) + set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX") - is_sdk_requested(LINUX swift_build_linux) - if(swift_build_linux) - configure_sdk_unix(LINUX "Linux" "linux" "linux" "x86_64" "x86_64-unknown-linux-gnu") - set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX") - set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") - endif() + # FIXME: This will not work while trying to cross-compile. + if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") + set(SWIFT_HOST_VARIANT_ARCH "x86_64") + set(swift_can_crosscompile_stdlib TRUE) - is_sdk_requested(ANDROID swift_build_android) - if(swift_build_android AND ${swift_can_crosscompile_stdlib}) - if("${SWIFT_ANDROID_NDK_PATH}" STREQUAL "") - message(FATAL_ERROR "environmental variable ANDROID_NDK_HOME not set") + is_sdk_requested(LINUX swift_build_linux) + if(swift_build_linux) + configure_sdk_unix(LINUX "Linux" "linux" "linux" "x86_64" "x86_64-unknown-linux-gnu") + set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX") + set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") endif() - configure_sdk_unix(ANDROID "Android" "android" "android" "armv7" "armv7-none-linux-androideabi") - set(SWIFT_SDK_ANDROID_PATH "${SWIFT_ANDROID_NDK_PATH}/platforms/android-16/arch-arm") - set(SWIFT_PRIMARY_VARIANT_SDK_default "ANDROID") + is_sdk_requested(ANDROID swift_build_android) + if(swift_build_android AND ${swift_can_crosscompile_stdlib}) + if("${SWIFT_ANDROID_NDK_PATH}" STREQUAL "") + message(FATAL_ERROR "environmental variable ANDROID_NDK_HOME not set") + endif() + configure_sdk_unix(ANDROID "Android" "android" "android" "armv7" "armv7-none-linux-androideabi") + set(SWIFT_SDK_ANDROID_PATH "${SWIFT_ANDROID_NDK_PATH}/platforms/android-16/arch-arm") + + set(SWIFT_PRIMARY_VARIANT_SDK_default "ANDROID") + set(SWIFT_PRIMARY_VARIANT_ARCH_default "armv7") + endif() + # FIXME: This only matches ARMv7l (by far the most common variant). + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l") + configure_sdk_unix(LINUX "Linux" "linux" "linux" "armv7" "armv7-unknown-linux-gnueabihf") + set(SWIFT_HOST_VARIANT_ARCH "armv7") set(SWIFT_PRIMARY_VARIANT_ARCH_default "armv7") + elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64") + configure_sdk_unix(LINUX "Linux" "linux" "linux" "aarch64" "aarch64-unknown-linux-gnu") + set(SWIFT_HOST_VARIANT_ARCH "aarch64") + set(SWIFT_PRIMARY_VARIANT_ARCH_default "aarch64") + else() + message(FATAL_ERROR "Unknown or unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}") endif() + +elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") + # FIXME: Using the host OS version won't produce correct results for + # cross-compilation. + string(REPLACE "[-].*" "" FREEBSD_SYSTEM_VERSION ${CMAKE_SYSTEM_VERSION}) + message(STATUS "FreeBSD Version: ${FREEBSD_SYSTEM_VERSION}") + configure_sdk_unix(FREEBSD "FreeBSD" "freebsd" "freebsd" "x86_64" + "x86_64-unknown-freebsd${FREEBSD_SYSTEM_VERSION}") + + set(CMAKE_EXECUTABLE_FORMAT "ELF") + + set(SWIFT_HOST_VARIANT "freebsd" CACHE STRING + "Deployment OS for Swift host tools (the compiler) [freebsd].") + + set(SWIFT_HOST_VARIANT_SDK "FREEBSD") + set(SWIFT_HOST_VARIANT_ARCH "x86_64") + set(swift_can_crosscompile_stdlib TRUE) + + set(SWIFT_PRIMARY_VARIANT_SDK_default "FREEBSD") + set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") # Set defaults. @@ -472,7 +500,7 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") endif() if(XCODE) - # FIXME: Can not cross-compile stdlib using Xcode. Xcode insists on + # FIXME: Cannot cross-compile stdlib using Xcode. Xcode insists on # passing -mmacosx-version-min to the compiler, and we want to pass # -mios-version-min. Clang sees both options and complains. set(swift_can_crosscompile_stdlib FALSE) @@ -644,7 +672,7 @@ if(SWIFT_BUILD_TOOLS) endif() add_subdirectory(utils) add_subdirectory(stdlib) -if(SWIFT_INCLUDE_BENCHMARKS) +if(SWIFT_BUILD_PERF_TESTSUITE) add_subdirectory(benchmark) endif() if(SWIFT_INCLUDE_TESTS) @@ -655,6 +683,10 @@ if(SWIFT_INCLUDE_DOCS) add_subdirectory(docs) endif() +swift_install_in_component(license + FILES "LICENSE.txt" + DESTINATION "share/swift") + # Add a documentation target so that documentation shows up in the # Xcode project. if(XCODE) diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT index 44dec800ed348..1079da5537579 100644 --- a/CODE_OWNERS.TXT +++ b/CODE_OWNERS.TXT @@ -46,7 +46,7 @@ D: ClangImporter, Serialization, (Objective-)C printer, Driver N: Nadav Rotem E: nrotem@apple.com -D: SILAnalysis, SILPasses +D: SILOptimizer N: Anna Zaks E: ganna@apple.com diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000..e36bf969f0cb9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,10 @@ +By submitting a pull request, you represent that you have the right to license +your contribution to Apple and the community, and agree by submitting the patch +that your contributions are licensed under the [Swift +license](https://swift.org/LICENSE.txt). + +--- + +Before submitting the pull request, please make sure you have tested your +changes and that they follow the Swift project [guidelines for contributing +code](https://swift.org/contributing/#contributing-code). diff --git a/README.md b/README.md index 92453e38082f0..070dd10827e2d 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,33 @@ +Swift logo # Swift Programming Language **Welcome to Swift!** Swift is a high-performance system programming language. It has a clean -and modern syntax, and offers seamless access to existing C and Objective-C code +and modern syntax, offers seamless access to existing C and Objective-C code and frameworks, and is memory safe (by default). Although inspired by Objective-C and many other languages, Swift is not itself a C-derived language. As a complete and independent language, Swift packages core features like flow control, data structures, and functions, with high-level -constructs like objects, protocols, closures, and generics. Swift embraces +constructs like objects, protocols, closures, and generics. Swift embraces modules, eliminating the need for headers and the code duplication they entail. ## Documentation -To read the documentation, start by installing the Sphinx documentation -generator tool (http://sphinx-doc.org, just run `easy_install -U Sphinx` from -the command line and you're good to go). Once you have that, you can build the -Swift documentation by going into `docs` and typing `make`. This compiles -the `.rst` files in the `docs` directory into HTML in the `docs/_build/html` -directory. - -Once built, the best place to start is with the Swift white paper, which gives a -tour of the language (in `docs/_build/html/whitepaper/index.html`). -Another potentially useful document is `docs/LangRef`, which gives a low level -tour of how the language works from the implementation perspective. +To read the documentation, start by installing the +[Sphinx](http://sphinx-doc.org) documentation generator tool (just run +`easy_install -U Sphinx` from the command line and you're good to go). Once you + have that, you can build the Swift documentation by going into `docs` and +typing `make`. This compiles the `.rst` files in the `docs` directory into +HTML in the `docs/_build/html` directory. Many of the docs are out of date, but you can see some historical design documents in the `docs` directory. Another source of documentation is the standard library itself, located in -`stdlib`. Much of the language is actually implemented in the library +`stdlib`. Much of the language is actually implemented in the library (including `Int`), and the standard library gives some examples of what can be expressed today. @@ -39,7 +35,7 @@ expressed today. ## Getting Started These instructions give the most direct path to a working Swift -development environment. Options for doing things differently are +development environment. Options for doing things differently are discussed below. @@ -52,7 +48,7 @@ For OS X, you need [the latest Xcode](https://developer.apple.com/xcode/download For Ubuntu, you'll need the following development dependencies: - sudo apt-get install git cmake ninja-build clang uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config + sudo apt-get install git cmake ninja-build clang python uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config Note: LLDB currently requires at least swig-1.3.40 but will successfully build with version 2 shipped with Ubuntu. @@ -60,37 +56,25 @@ with version 2 shipped with Ubuntu. If you are building on Ubuntu 14.04 LTS, you'll need to upgrade your clang compiler for C++14 support and create a symlink: - sudo apt-get install clang-3.6 - sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100 - sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100 + sudo apt-get install clang-3.6 + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100 + sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100 ### Getting Sources for Swift and Related Projects - For those checking out sources as read-only: - - git clone https://github.com/apple/swift.git swift - git clone https://github.com/apple/swift-llvm.git llvm - git clone https://github.com/apple/swift-clang.git clang - git clone https://github.com/apple/swift-lldb.git lldb - git clone https://github.com/apple/swift-cmark.git cmark - git clone https://github.com/apple/swift-llbuild.git llbuild - git clone https://github.com/apple/swift-package-manager.git swiftpm - git clone https://github.com/apple/swift-corelibs-xctest.git - git clone https://github.com/apple/swift-corelibs-foundation.git - - For those who plan on regular making direct commits, cloning over - SSH may provide a better experience (which requires uploading - SSH keys to GitHub): - - git clone git@github.com:apple/swift.git swift - git clone git@github.com:apple/swift-llvm.git llvm - git clone git@github.com:apple/swift-clang.git clang - git clone git@github.com:apple/swift-lldb.git lldb - git clone git@github.com:apple/swift-cmark.git cmark - git clone git@github.com:apple/swift-llbuild.git llbuild - git clone git@github.com:apple/swift-package-manager.git swiftpm - git clone git@github.com:apple/swift-corelibs-xctest.git - git clone git@github.com:apple/swift-corelibs-foundation.git +**Via HTTPS** For those checking out sources as read-only, HTTPS works best: + + git clone https://github.com/apple/swift.git + cd swift + ./utils/update-checkout --clone + +**Via SSH** For those who plan on regularly making direct commits, +cloning over SSH may provide a better experience (which requires +uploading SSH keys to GitHub): + + git clone git@github.com:apple/swift.git + cd swift + ./utils/update-checkout --clone-with-ssh [CMake](http://cmake.org) is the core infrastructure used to configure builds of Swift and its companion projects; at least version 2.8.12.2 is required. Your @@ -106,7 +90,11 @@ for building Swift and is the default configuration generated by CMake. If you're on OS X or don't install it as part of your Linux distribution, clone it next to the other projects and it will be bootstrapped automatically: - git clone git@github.com:martine/ninja.git + git clone https://github.com/ninja-build/ninja.git + +or + + git clone git@github.com:ninja-build/ninja.git You can also install CMake and Ninja on OS X using a third-party packaging tool like [Homebrew](http://brew.sh)… diff --git a/apinotes/README.md b/apinotes/README.md index f5d8858d4dedf..f954eeb7c551d 100644 --- a/apinotes/README.md +++ b/apinotes/README.md @@ -25,7 +25,7 @@ Swift signatures of imported Objective-C APIs. Compiled API notes files reside in the Swift module directory, i.e., the same directory where the `.swiftmodule` file would reside for the Swift overlay of that module. For system modules, the path depends on the platform -and architecture +and architecture. Platform | Path :------------- | :------------- diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 1f274ff04b08d..7ef0477f168db 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,16 +1,10 @@ -option(SWIFT_INCLUDE_PERF_TESTSUITE "Create targets for swift performance benchmarks." NO) if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") # Performance test harness only builds on Darwin. - if (SWIFT_INCLUDE_PERF_TESTSUITE) - set(PERF_TESTSUITE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/PerfTestSuite" CACHE STRING "Path to swift performance testsuite repo.") - if(EXISTS ${PERF_TESTSUITE_DIR}/CMakeLists.txt) - add_subdirectory(${PERF_TESTSUITE_DIR}) - else() - message(FATAL_ERROR "Can't find the Swift performance suite at ${PERF_TESTSUITE_DIR}/.") - endif() - add_custom_target(benchmark-swift - DEPENDS benchmark-swift PerfTests_Onone PerfTests_O - PerfTests_Ounchecked) + set(PERF_TESTSUITE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/PerfTestSuite" CACHE STRING "Path to swift performance testsuite repo.") + if(EXISTS ${PERF_TESTSUITE_DIR}/CMakeLists.txt) + add_subdirectory(${PERF_TESTSUITE_DIR}) + else() + message(FATAL_ERROR "Can't find the Swift performance suite at ${PERF_TESTSUITE_DIR}/.") endif() endif() diff --git a/bindings/xml/comment-xml-schema.rng b/bindings/xml/comment-xml-schema.rng index 6ee793715ff33..468efa042537e 100644 --- a/bindings/xml/comment-xml-schema.rng +++ b/bindings/xml/comment-xml-schema.rng @@ -767,6 +767,9 @@ + + + diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake index 14a5b68c6a524..64f6659fbdade 100644 --- a/cmake/modules/AddSwift.cmake +++ b/cmake/modules/AddSwift.cmake @@ -14,6 +14,15 @@ function(_list_add_string_suffix input_list suffix result_var_name) set("${result_var_name}" "${result}" PARENT_SCOPE) endfunction() +function(_list_escape_for_shell input_list result_var_name) + set(result "") + foreach(element ${input_list}) + string(REPLACE " " "\\ " element "${element}") + set(result "${result}${element} ") + endforeach() + set("${result_var_name}" "${result}" PARENT_SCOPE) +endfunction() + function(add_dependencies_multiple_targets) cmake_parse_arguments( ADMT # prefix @@ -163,6 +172,8 @@ function(_add_variant_link_flags if("${sdk}" STREQUAL "LINUX") list(APPEND result "-lpthread" "-ldl" "${BSD_LIBRARIES}") + elseif("${sdk}" STREQUAL "FREEBSD") + # No extra libraries required. elseif("${sdk}" STREQUAL "ANDROID") list(APPEND result "-Wl,-Bsymbolic" @@ -1107,18 +1118,19 @@ function(_add_swift_library_single target name) set(PLIST_INFO_BUILD_VERSION) endif() - # On Linux add the linker script that coalesces protocol conformance - # sections. This wouldn't be necessary if the link was done by the swift - # binary: rdar://problem/19007002 - if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + # On Linux and FreeBSD add the linker script that coalesces protocol + # conformance sections. This wouldn't be necessary if the link was done by + # the swift binary: rdar://problem/19007002 + if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR + "${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD") list(APPEND link_flags "-Xlinker" "-T" "-Xlinker" "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/swift.ld") endif() # Convert variables to space-separated strings. - string(REPLACE ";" " " c_compile_flags "${c_compile_flags}") - string(REPLACE ";" " " link_flags "${link_flags}") + _list_escape_for_shell("${c_compile_flags}" c_compile_flags) + _list_escape_for_shell("${link_flags}" link_flags) # Set compilation and link flags. set_property(TARGET "${target}" APPEND_STRING PROPERTY @@ -1686,8 +1698,8 @@ function(_add_swift_executable_single name) llvm_update_compile_flags("${name}") # Convert variables to space-separated strings. - string(REPLACE ";" " " c_compile_flags "${c_compile_flags}") - string(REPLACE ";" " " link_flags "${link_flags}") + _list_escape_for_shell("${c_compile_flags}" c_compile_flags) + _list_escape_for_shell("${link_flags}" link_flags) set_property(TARGET ${name} APPEND_STRING PROPERTY COMPILE_FLAGS " ${c_compile_flags}") @@ -1854,37 +1866,3 @@ function(add_swift_executable name) ${SWIFTEXE_DONT_STRIP_NON_MAIN_SYMBOLS_FLAG} ${SWIFTEXE_DISABLE_ASLR_FLAG}) endfunction() - -function(add_swift_llvm_loadable_module name) - add_llvm_loadable_module(${name} ${ARGN}) - set(sdk "${SWIFT_HOST_VARIANT_SDK}") - set(arch "${SWIFT_HOST_VARIANT_ARCH}") - - # Determine compiler flags. - set(c_compile_flags) - _add_variant_c_compile_flags( - "${sdk}" - "${arch}" - "${CMAKE_BUILD_TYPE}" - "${LLVM_ENABLE_ASSERTIONS}" - FALSE - c_compile_flags) - - set(link_flags) - _add_variant_link_flags( - "${sdk}" - "${arch}" - "${CMAKE_BUILD_TYPE}" - "${LLVM_ENABLE_ASSERTIONS}" - FALSE - link_flags) - - # Convert variables to space-separated strings. - string(REPLACE ";" " " c_compile_flags "${c_compile_flags}") - string(REPLACE ";" " " link_flags "${link_flags}") - - set_property(TARGET ${name} APPEND_STRING PROPERTY - COMPILE_FLAGS " ${c_compile_flags}") - set_property(TARGET ${name} APPEND_STRING PROPERTY - LINK_FLAGS " ${link_flags}") -endfunction() diff --git a/cmake/modules/SwiftSetIfArchBitness.cmake b/cmake/modules/SwiftSetIfArchBitness.cmake index 22617ff68399e..83d80533f6792 100644 --- a/cmake/modules/SwiftSetIfArchBitness.cmake +++ b/cmake/modules/SwiftSetIfArchBitness.cmake @@ -12,7 +12,8 @@ function(set_if_arch_bitness var_name) "${SIA_ARCH}" STREQUAL "armv7s") set("${var_name}" "${SIA_CASE_32_BIT}" PARENT_SCOPE) elseif("${SIA_ARCH}" STREQUAL "x86_64" OR - "${SIA_ARCH}" STREQUAL "arm64") + "${SIA_ARCH}" STREQUAL "arm64" OR + "${SIA_ARCH}" STREQUAL "aarch64") set("${var_name}" "${SIA_CASE_64_BIT}" PARENT_SCOPE) else() message(FATAL_ERROR "Unknown architecture: ${SIA_ARCH}") diff --git a/docs/ABI.rst b/docs/ABI.rst index 30f570f91dd32..dd34104149dc5 100644 --- a/docs/ABI.rst +++ b/docs/ABI.rst @@ -743,15 +743,17 @@ Globals global ::= 'PA' .* // partial application forwarder global ::= 'PAo' .* // ObjC partial application forwarder global ::= 'w' value-witness-kind type // value witness - global ::= 'WV' type // value witness table - global ::= 'Wo' entity // witness table offset - global ::= 'Wv' directness entity // field offset - global ::= 'WP' protocol-conformance // protocol witness table global ::= 'Wa' protocol-conformance // protocol witness table accessor + global ::= 'WG' protocol-conformance // generic protocol witness table + global ::= 'WI' protocol-conformance // generic protocol witness table instantiation function global ::= 'Wl' type protocol-conformance // lazy protocol witness table accessor global ::= 'WL' protocol-conformance // lazy protocol witness table cache variable - global ::= 'WD' protocol-conformance // dependent proto witness table generator - global ::= 'Wd' protocol-conformance // dependent proto witness table template + global ::= 'Wo' entity // witness table offset + global ::= 'WP' protocol-conformance // protocol witness table + global ::= 'Wt' protocol-conformance identifier // associated type metadata accessor + global ::= 'WT' protocol-conformance identifier nominal-type // associated type witness table accessor + global ::= 'Wv' directness entity // field offset + global ::= 'WV' type // value witness table global ::= entity // some identifiable thing global ::= 'TO' global // ObjC-as-swift thunk global ::= 'To' global // swift-as-ObjC thunk @@ -770,6 +772,7 @@ Globals funcsigspecializationarginfo ::= 'd' // Dead argument funcsigspecializationarginfo ::= 'g' 's'? // Owned => Guaranteed and Exploded if 's' present. funcsigspecializationarginfo ::= 's' // Exploded + funcsigspecializationarginfo ::= 'k' // Exploded funcsigspecializationconstantpropinfo ::= 'fr' mangled-name funcsigspecializationconstantpropinfo ::= 'g' mangled-name funcsigspecializationconstantpropinfo ::= 'i' 64-bit-integer @@ -938,6 +941,7 @@ Types nominal-type-kind ::= 'C' // class nominal-type-kind ::= 'O' // enum nominal-type-kind ::= 'V' // struct + declaration-name ::= context decl-name archetype ::= 'Q' index // archetype with depth=0, idx=N archetype ::= 'Qd' index index // archetype with depth=M+1, idx=N archetype ::= associated-type @@ -1088,6 +1092,7 @@ TODO: document these value-witness-kind ::= 'tT' // initializeArrayWithTakeBackToFront value-witness-kind ::= 'ug' // getEnumTag value-witness-kind ::= 'up' // destructiveProjectEnumData + value-witness-kind ::= 'ui' // destructiveInjectEnumTag ```` differentiates the kinds of value witness functions for a type. @@ -1173,12 +1178,12 @@ for the first time. The first argument type will mangle in long form, ``CC3zim4zang4zung``, and in doing so, ``zim`` will acquire substitution ``S_``, ``zim.zang`` will acquire substitution ``S0_``, and ``zim.zang.zung`` will acquire ``S1_``. The second argument is the same as the first and will mangle -using its substitution, ``CS1_``. The +using its substitution, ``S1_``. The third argument type will mangle using the substitution for ``zim``, ``CS_7zippity``. (It also acquires substitution ``S2_`` which would be used if it mangled again.) The result type will mangle using the substitution for -``zim.zang``, ``CS0_zoo`` (and acquire substitution ``S3_``). The full -function type thus mangles as ``fTCC3zim4zang4zungCS1_CS_7zippity_CS0_zoo``. +``zim.zang``, ``CS0_3zoo`` (and acquire substitution ``S3_``). The full +function type thus mangles as ``fTCC3zim4zang4zungS1_CS_7zippity_CS0_3zoo``. :: diff --git a/docs/ARCOptimization.rst b/docs/ARCOptimization.rst index 5cf08d88d7160..bb88d61ae5a1a 100644 --- a/docs/ARCOptimization.rst +++ b/docs/ARCOptimization.rst @@ -15,7 +15,6 @@ Reference Counting Instructions =============================== - strong_retain -- strong_retain_autoreleased - strong_release - strong_retain_unowned - unowned_retain @@ -151,7 +150,7 @@ referent. Consider the following sequence of rules: is deallocated. (3) A different source-level variable pointing at the same referent - must not be changed/invalidated by such a call + must not be changed/invalidated by such a call. (4) If such a variable exists, the compiler must guarantee the refcount is > 1 going into the call. @@ -229,3 +228,22 @@ These builtins perform an implicit cast to NativeObject before checking uniqueness. There’s no way at SIL level to cast the address of a reference, so we need to encapsulate this operation as part of the builtin. + +Semantic Tags +============= + +ARC takes advantage of certain semantic tags. This section documents these +semantics and their meanings. + +arc.programtermination_point +---------------------------- + +If this semantic tag is applied to a function, then we know that: + +- The function does not touch any reference counted objects. +- After the function is executed, all reference counted objects are leaked + (most likely in preparation for program termination). + +This allows one, when performing ARC code motion, to ignore blocks that contain +an apply to this function as long as the block does not have any other side +effect having instructions. diff --git a/docs/AccessControl.rst b/docs/AccessControl.rst index eb45010656ab8..d0005c54fa737 100644 --- a/docs/AccessControl.rst +++ b/docs/AccessControl.rst @@ -90,7 +90,7 @@ Protocols A protocol may have any access level less than or equal to the access levels of the protocols it refines. That is, a ``private`` ExtendedWidget protocol can -refine an ``public`` Widget protocol, but not the other way around. +refine a ``public`` Widget protocol, but not the other way around. The access level of a requirement is the access level of the enclosing protocol, even when the protocol is ``public``. Currently, requirements may not @@ -154,7 +154,7 @@ elements. A function type's access level is the minimum of the access levels of its input and return types. A typealias may have any access level up to the access level of the type it -aliases. That is, a ``private`` typealias can refer to an ``public`` type, but +aliases. That is, a ``private`` typealias can refer to a ``public`` type, but not the other way around. This includes associated types used to satisfy protocol conformances. diff --git a/docs/AccessControlInStdlib.rst b/docs/AccessControlInStdlib.rst index 20f857bba48d7..9bf32bc54a97e 100644 --- a/docs/AccessControlInStdlib.rst +++ b/docs/AccessControlInStdlib.rst @@ -6,7 +6,7 @@ Scope and introduction This document defines the policy for applying access control modifiers and related naming conventions for the Swift standard library and overlays. -In this document, “stdlib” refers to the core standard library and +In this document, "stdlib" refers to the core standard library and overlays for system frameworks written in Swift. Swift has three levels of access control --- private, internal @@ -49,7 +49,7 @@ To document the reason for marking symbols public, we use comments: * symbols that are SPIs for the module X:: public // SPI(X) - public _foo() { ... } + func _foo() { ... } `internal` ========== @@ -60,7 +60,7 @@ explicitly everywhere in the stdlib to avoid confusion. .. Note:: No declaration should omit an access -To create a “single point of truth” about whether a name is intended +To create a "single point of truth" about whether a name is intended for user consumption, the following names should all use the `leading underscore rule`_: @@ -77,7 +77,7 @@ underscore rule`_: `private` ========= -The `private` modifier can not be used in the stdlib at least until +The `private` modifier cannot be used in the stdlib at least until rdar://17631278 is fixed. Leading Underscore Rule diff --git a/docs/DebuggingTheCompiler.rst b/docs/DebuggingTheCompiler.rst index 5f453f7781c4f..52cc8d405d053 100644 --- a/docs/DebuggingTheCompiler.rst +++ b/docs/DebuggingTheCompiler.rst @@ -37,13 +37,13 @@ Here is how to dump the IR after the main phases of the swift compiler #. **Performance SIL passes**. To print the SIL after the complete SIL optimization pipeline:: - swiftc -emit-sil -O file-swift + swiftc -emit-sil -O file.swift #. **IRGen**. To print the LLVM IR after IR generation:: swiftc -emit-ir -Xfrontend -disable-llvm-optzns -O file.swift -4. **LLVM passes**. To print the LLVM IR afer LLVM passes:: +4. **LLVM passes**. To print the LLVM IR after LLVM passes:: swiftc -emit-ir -O file.swift @@ -136,7 +136,7 @@ and check for the function name in the breakpoint condition:: (lldb) br set -c 'hasName("_TFC3nix1Xd")' -f SILFunction.cpp -l 91 -Sometimes you want to know which optimization does insert, remove or move a +Sometimes you may want to know which optimization inserts, removes or moves a certain instruction. To find out, set a breakpoint in ``ilist_traits::addNodeToList`` or ``ilist_traits::removeNodeFromList``, which are defined in diff --git a/docs/DriverInternals.rst b/docs/DriverInternals.rst index 24c6fd407aa3e..041d3c09d38b2 100644 --- a/docs/DriverInternals.rst +++ b/docs/DriverInternals.rst @@ -114,7 +114,7 @@ Analysis` for more information. The Compilation's TaskQueue controls the low-level aspects of managing subprocesses. Multiple Jobs may execute simultaneously, but communication with the parent process (the driver) is handled on a single thread. The level of -parellelism may be controlled by a compiler flag. +parallelism may be controlled by a compiler flag. If a Job does not finish successfully, the Compilation needs to record which jobs have failed, so that they get rebuilt next time the user tries to build diff --git a/docs/ErrorHandling.rst b/docs/ErrorHandling.rst index 0b2424a25d571..547af4def253a 100644 --- a/docs/ErrorHandling.rst +++ b/docs/ErrorHandling.rst @@ -256,7 +256,7 @@ Throwing an error ----------------- The ``throw`` statement begins the propagation of an error. It always -take an argument, which can be any value that conforms to the +takes an argument, which can be any value that conforms to the ``ErrorType`` protocol (described below). :: @@ -680,7 +680,7 @@ can be overloaded on whether its argument closure throws; the overload that takes a throwing closures would itself throw. There is one minor usability problem here, though. If the closure -contains throwing expressions, those expression must be explicitly +contains throwing expressions, those expressions must be explicitly marked within the closure with ``try``. However, from the compiler's perspective, the call to ``autoreleasepool`` is also a call that can throw, and so it must also be marked with ``try``:: diff --git a/docs/ErrorHandlingRationale.rst b/docs/ErrorHandlingRationale.rst index 8714409f5f33b..c5fa599ac67c5 100644 --- a/docs/ErrorHandlingRationale.rst +++ b/docs/ErrorHandlingRationale.rst @@ -26,7 +26,7 @@ The most important dimensions of variation are: errors or not; such a language has **typed propagation**. * Whether, in a language with typed propagation, the default rule is - that that a function can produce an error or that it can't; this + that a function can produce an error or that it can't; this is the language's **default propagation rule**. * Whether, in a language with typed propagation, the language enforces @@ -173,7 +173,7 @@ be quite amazing for us to assert that code shouldn't be written that way, understanding nothing else about it. As long as programmers do face these issues, the language has some responsibility to help them. -Therefore, in my judgement, promoting the use of universal errors is +Therefore, in my judgment, promoting the use of universal errors is highly problematic. They undermine the easy comprehension of code, and they undermine the language's ability to help the programmer reason about errors. This design will instead focus on explicitly @@ -389,7 +389,7 @@ options as a programmer: function called by your function. - You can carefully arrange your function so that there are no - critical sections where an universal error can leave things in an + critical sections where a universal error can leave things in an unwanted state. There are techniques for making the second more palatable. Chiefly, @@ -430,7 +430,7 @@ Here's another example of an out-parameter: .. code-block:: objc - - (instancetype)initWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error; + - (instancetype)initWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error; Out-parameters have some nice advantages. First, they're a reliable source of marking; even if the actual propagation gets separated from @@ -577,7 +577,7 @@ they produce, and so many errors just end up falling into broad buckets. Different libraries end up with their own library-specific general error classes, and exceptions list end up just restating the library's own dependencies or wrapping the underlying errors in ways -that loses criticial information. +that loses critical information. Tradeoffs of typed propagation @@ -741,8 +741,8 @@ This approach is therefore relatively even-handed about the error vs. the non-error path, although it requires some care in order to minimize code-size penalties for parallel error paths. -``setjmp`` / ``longmp`` -~~~~~~~~~~~~~~~~~~~~~~~ +``setjmp`` / ``longjmp`` +~~~~~~~~~~~~~~~~~~~~~~~~ Another strategy to is to dynamically maintain a thread-local stack of interesting frames. A function with an interesting frame must save @@ -768,7 +768,7 @@ not free: which on our platforms means a function call because we're not willing to commit to anything more specific in the ABI. -* Jumping across arbitary frames invalidates the callee-save +* Jumping across arbitrary frames invalidates the callee-save registers, so the registering frame must save them all eagerly. In calling conventions with many callee-save registers, this can be very expensive. However, this is only necessary when it's possible @@ -812,7 +812,7 @@ in a very unsafe way that does not behave well in the presence of inlining. Overall, this approach requires a lot of work in the non-error path -of functions with interesting frames. Given that we expects functions +of functions with interesting frames. Given that we expect functions with interesting frames to be very common in Swift, this is not an implementation approach we would consider in the abstract. However, it is the implementation approach for C++/ObjC exceptions on iOS/ARM32, @@ -955,7 +955,7 @@ This allows the defer action to be written near the code it "balances", allowing the reader to immediately see that the required clean-up will be done (but this has drawbacks, as discussed above). It's very compact, which is nice as most defer actions are short. It -also allow multiple actions to pile up without adding awkward nesting. +also allows multiple actions to pile up without adding awkward nesting. However, the function-exit semantics exacerbate the problem of searching for intervening clean-up actions, and they introduce semantic and performance problems with capturing the values of local @@ -1396,7 +1396,7 @@ same glance. The keyword appears before the arrow for the simple reason that the arrow is optional (along with the rest of the return type) in function and initializer declarations; having the keyword appear in slightly different places based on the presence of a return -type would be silly and would making adding a non-void return type +type would be silly and would make adding a non-void return type feel awkward. The keyword itself should be descriptive, and it's particularly nice for it to be a form of the verb used by the throwing expression, conjugated as if performed by the function itself. Thus, @@ -1687,7 +1687,7 @@ might want to investigate closer, and you can easily imagine codebases that expect uses of it to always be explained in comments. But more importantly, just like ``!`` it's only *statically* unsafe, and it will reliably fail when the programmer is wrong. Therefore, while you -can easily imagine (and demonstrate) uncautious programmers flailing +can easily imagine (and demonstrate) incautious programmers flailing around with it to appease the type-checker, that's not actually a tenable position for the overall program: eventually the programmer will have to learn how to use the feature, or else their program diff --git a/docs/Failable Initializers.rst b/docs/Failable Initializers.rst index b6fcfb59caae6..b6cbf0679948f 100644 --- a/docs/Failable Initializers.rst +++ b/docs/Failable Initializers.rst @@ -173,7 +173,7 @@ a new hidden stored property to each class that directly defines failing initializers. The bit is set if this slice of the instance has been initialized. -Note that unlike partailDeinit, if a class does not have failing initializers, +Note that unlike partialDeinit, if a class does not have failing initializers, it does not need this bit, even if its initializer delegates to a failing initializer in a superclass. diff --git a/docs/Generics.rst b/docs/Generics.rst index 49854392c0d4b..2fa9c7ca76252 100644 --- a/docs/Generics.rst +++ b/docs/Generics.rst @@ -579,7 +579,7 @@ OrderedCollection>) are just sugar for a where clause. For example, the above find() signature is equivalent to:: func find( - collection : C, value : C.Element)-> Int + collection : C, value : C.Element) -> Int Note that find is shorthand for (and equivalent to) find, since every type conforms to the Any protocol composition. @@ -594,7 +594,7 @@ lets us describe an iteration of values of some given value type:: func next() -> Element } -Now, we want to express the notion of an enumerable collection, which provides a +Now, we want to express the notion of an enumerable collection, which provides iteration, which we do by adding requirements into the protocol:: protocol EnumerableCollection : Collection { @@ -814,7 +814,7 @@ because code like this:: will essentially parse the type as:: - identifier operator Int operator + identifier operator identifier operator and verify that the operators are '<' and '>', respectively. Cases involving <> are more interesting, because the type of:: diff --git a/docs/GitWorkflows.rst b/docs/GitWorkflows.rst index 7cb2ff8174e64..1b803ba0ebc0b 100644 --- a/docs/GitWorkflows.rst +++ b/docs/GitWorkflows.rst @@ -43,7 +43,7 @@ to perform a simple repo setup for the Swift repository:: $ git config --global user.name "" $ git config --global user.email "" - $ mkdir swift-source && cd swift-soure + $ mkdir swift-source && cd swift-source $ git clone $ git clone $ git clone @@ -114,7 +114,7 @@ By default when updating, Git will attempt to merge the remote changes and your local changes. Ignoring what that sentence means, this is not an SVN-esque model. Instead we want any local changes that we have to be applied on top of any new remote changes. The 'branch.autosetuprebase' flag causes this to be done -automatically when ever one updates the local repository. +automatically whenever one updates the local repository. Update ------ @@ -261,7 +261,7 @@ command:: $ git log -To see a oneline summary that includes just the title of the commit and its +To see an oneline summary that includes just the title of the commit and its hash, pass the '--oneline' command:: $ git log --oneline diff --git a/docs/HighLevelSILOptimizations.rst b/docs/HighLevelSILOptimizations.rst index 35ca6e4b53d0e..1e1988cab6144 100644 --- a/docs/HighLevelSILOptimizations.rst +++ b/docs/HighLevelSILOptimizations.rst @@ -13,7 +13,7 @@ Abstract This document describes the high-level abstraction of built-in Swift data structures in SIL that is used by the optimizer. You need to read this document if you wish to understand the early stages of the Swift -optimizer or if you are working on one of the containers in the +optimizer or if you are working on one of the containers in the standard library. @@ -33,22 +33,22 @@ Any Swift developer could identify the redundancy in the code sample above. Storing two values into the same key in the dictionary is inefficient. However, optimizing compilers are unaware of the special semantics that the Swift dictionary has and can't perform this optimization. Traditional -compilers would start optimizing this code by inlining the subscript +compilers would start optimizing this code by inlining the subscript function call and try to analyze the sequence of load/store instructions. This approach is not very effective because the compiler has to be very -conservative when optimizing general code with pointers. +conservative when optimizing general code with pointers. On the other hand, compilers for high-level languages usually have special bytecode instructions that allow them to perform high-level optimizations. However, unlike high-level languages such as JavaScript or Python, Swift containers are implemented in Swift itself. Moreover, it is beneficial to be able to inline code from the container into the user program and optimize -them together, especially for code that uses Generics. +them together, especially for code that uses Generics. In order to perform both high-level optimizations, that are common in high-level languages, and low-level optimizations we annotate parts of the standard library and describe the semantics of a domain-specific high-level -operations on data types in the Swift standard library. +operations on data types in the Swift standard library. Annotation of code in the standard library ------------------------------------------ @@ -78,7 +78,7 @@ operations in the semantic model. One for checking the bounds and another one for accessing the elements. With this abstraction the optimizer can remove the ``checkSubscript`` instruction and keep the getElement instruction:: - + @public subscript(index: Int) -> Element { get { checkSubscript(index) @@ -88,7 +88,7 @@ getElement instruction:: @_semantics("array.check_subscript") func checkSubscript(index: Int) { ... } - + @_semantics("array.get_element") func getElement(index: Int) -> Element { return _buffer[index] } @@ -131,8 +131,8 @@ Array The following semantic tags describe Array operations. The operations are first described in terms of the Array "state". Relations between the -operations are formally defined below. 'Array' referes to the standard library -Array, ContigousArray, and ArraySlice data-structures. +operations are formally defined below. 'Array' refers to the standard library +Array, ContiguousArray, and ArraySlice data-structures. We consider the array state to consist of a set of disjoint elements and a storage descriptor that encapsulates nonelement data such as the @@ -166,9 +166,9 @@ array.uninitialized(count: Builtin.Word) -> (Array, Builtin.RawPointer) array.props.isCocoa/needsElementTypeCheck -> Bool Reads storage descriptors properties (isCocoa, needsElementTypeCheck). This is not control dependent or guarded. The optimizer has - semantic knowledge of the state transfer those properties can not make: - An array that is not ``isCocoa`` can not transfer to ``isCocoa``. - An array that is not ``needsElementTypeCheck`` can not transfer to + semantic knowledge of the state transfer those properties cannot make: + An array that is not ``isCocoa`` cannot transfer to ``isCocoa``. + An array that is not ``needsElementTypeCheck`` cannot transfer to ``needsElementTypeCheck``. array.get_element(index: Int) -> Element @@ -236,7 +236,7 @@ array.mutate_unknown To complete the semantics understood by the optimizer, we define these relations: interferes-with - + Given idempotent ``OpA``, the sequence "``OpA, OpB, OpA``" is semantically equivalent to the sequence "``OpA, OpB``" *iff* ``OpB`` does not interfere with ``OpA``. @@ -262,7 +262,7 @@ check_subscript guards get_element, get_element_address make_mutable interferes-with props.isCocoa/needsElementTypeCheck get_elt_addr interferes-with get_element, get_element_address, props.isCocoa/needsElementTypeCheck -mutate_unknown itereferes-with get_element, check_subscript, get_count, +mutate_unknown interferes-with get_element, check_subscript, get_count, get_capacity, get_element_address, props.isCocoa/needsElementTypeCheck ================ =============== ========================================== @@ -282,18 +282,18 @@ String ~~~~~~ string.concat(lhs: String, rhs: String) -> String - + Performs concatenation of two strings. Operands are not mutated. This operation can be optimized away in case of both operands being string literals. In this case, it can be replaced by a string literal representing a concatenation of both operands. - + string.makeUTF8(start: RawPointer, byteSize: Word, isASCII: Int1) -> String - + Converts a built-in UTF8-encoded string literal into a string. - + string.makeUTF16(start: RawPointer, numberOfCodeUnits: Word) -> String - + Converts a built-in UTF16-encoded string literal into a string. Dictionary @@ -323,7 +323,7 @@ readnone readonly - function has no side effects, but is dependent on the global + function has no side effects, but is dependent on the global state of the program. Calls to readonly functions can be eliminated, but cannot be reordered or folded in a way that would move calls to the readnone function across side effects. @@ -335,13 +335,13 @@ readwrite Optimize semantics attribute ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The optimize attribute adds function-sepcific directives to the optimizer. +The optimize attribute adds function-specific directives to the optimizer. The optimize attribute supports the following tags: sil.never - The sil optimizer should not optimize this funciton. + The sil optimizer should not optimize this function. Example: @_semantics("optimize.sil.never") @@ -358,4 +358,3 @@ The availability attribute supports the following tags: availability.osversion(major: Builtin.Word, minor: Builtin.Word, patch: Builtin.Word) -> Builtin.Int1 Returns true if the OS version matches the parameters. - diff --git a/docs/IndexInvalidation.rst b/docs/IndexInvalidation.rst index 97dd1dc016d9c..aaa2de169a49b 100644 --- a/docs/IndexInvalidation.rst +++ b/docs/IndexInvalidation.rst @@ -97,7 +97,7 @@ user: This rule does not imply that indices should be cheap to convert to actual integers. The offsets for consecutive elements could be non-consecutive (e.g., in a hash table with open addressing), or consist of multiple - offsets so that the conversion to an integer is non-trival (e.g., in a + offsets so that the conversion to an integer is non-trivial (e.g., in a tree). Note that this rule, like all other rules, is an "as if" rule. As long as @@ -128,7 +128,7 @@ Consequences: any indices. Indices are composites of offsets, so replacing the value does not change the shape of the data structure and preserves offsets. -- A value type mutable linked list can not conform to +- A value type mutable linked list cannot conform to ``MutableCollectionType``. An index for a linked list has to be implemented as a pointer to the list node to provide O(1) element access. Mutating an element of a non-uniquely referenced linked list will create a copy of the diff --git a/docs/Literals.rst b/docs/Literals.rst index 57473e765d91f..8c596be873c85 100644 --- a/docs/Literals.rst +++ b/docs/Literals.rst @@ -36,12 +36,16 @@ The StringLiteralConvertible Protocol ------------------------------------- Here is the StringLiteralConvertible protocol as defined in the standard -library's Policy.swift:: +library's CompilerProtocols.swift:: // NOTE: the compiler has builtin knowledge of this protocol - protocol StringLiteralConvertible { + // Conforming types can be initialized with arbitrary string literals. + public protocol StringLiteralConvertible + : ExtendedGraphemeClusterLiteralConvertible { + typealias StringLiteralType : _BuiltinStringLiteralConvertible - class func convertFromStringLiteral(value : StringLiteralType) -> Self + // Create an instance initialized to `value`. + init(stringLiteral value: StringLiteralType) } Curiously, the protocol is not defined in terms of primitive types, but in @@ -58,13 +62,16 @@ points could be constructed...which may be what's desired in some cases.) The _BuiltinStringLiteralConvertible Protocol --------------------------------------------- -Policy.swift contains a second protocol:: +CompilerProtocols.swift contains a second protocol:: // NOTE: the compiler has builtin knowledge of this protocol - protocol _BuiltinStringLiteralConvertible { - class func _convertFromBuiltinStringLiteral(value : Builtin.RawPointer, - byteSize : Builtin.Int64, - isASCII: Builtin.Int1) -> Self + public protocol _BuiltinStringLiteralConvertible + : _BuiltinExtendedGraphemeClusterLiteralConvertible { + + init( + _builtinStringLiteral start: Builtin.RawPointer, + byteSize: Builtin.Word, + isASCII: Builtin.Int1) } The use of builtin types makes it clear that this is *only* for use in the diff --git a/docs/MutationModel.rst b/docs/MutationModel.rst index dae65de7431d2..8a3e802fe9b8c 100644 --- a/docs/MutationModel.rst +++ b/docs/MutationModel.rst @@ -37,7 +37,7 @@ Consider:: } var w = Window() - w.title += " (parenthesized remark)” + w.title += " (parenthesized remark)" What do we do with this? Since ``+=`` has an ``inout`` first argument, we detect this situation statically (hopefully one day we’ll @@ -101,14 +101,14 @@ Otherwise, it is considered **read-only**. The implicit ``self`` parameter of a struct or enum method is semantically an ``inout`` parameter if and only if the method is attributed with -``mutating``. Read-only methods do not “write back” onto their target +``mutating``. Read-only methods do not "write back" onto their target objects. A program that applies the ``mutating`` to a method of a class—or of a protocol attributed with ``@class_protocol``—is ill-formed. [Note: it is logically consistent to think of all methods of classes as read-only, even though they may in fact modify instance -variables, because they never “write back” onto the source reference.] +variables, because they never "write back" onto the source reference.] Mutating Operations ------------------- diff --git a/docs/OptimizationTips.rst b/docs/OptimizationTips.rst index a8c66e01eb8fc..26f9476f3f5d4 100644 --- a/docs/OptimizationTips.rst +++ b/docs/OptimizationTips.rst @@ -176,7 +176,7 @@ Advice: Use value types in Array In Swift, types can be divided into two different categories: value types (structs, enums, tuples) and reference types (classes). A key distinction is -that value types can not be included inside an NSArray. Thus when using value +that value types cannot be included inside an NSArray. Thus when using value types, the optimizer can remove most of the overhead in Array that is necessary to handle the possibility of the array being backed an NSArray. @@ -265,7 +265,7 @@ Swift eliminates integer overflow bugs by checking for overflow when performing normal arithmetic. These checks are not appropriate in high performance code where one knows that no memory safety issues can result. -Advice: Use unchecked integer arithmetic when you can prove that overflow can not occur +Advice: Use unchecked integer arithmetic when you can prove that overflow cannot occur --------------------------------------------------------------------------------------- In performance-critical code you can elide overflow checks if you know it is @@ -446,7 +446,7 @@ argument drops from being O(n), depending on the size of the tree to O(1). :: - struct tree : P { + struct Tree : P { var node : [P?] init() { node = [ thing ] diff --git a/docs/OptimizerDesign.md b/docs/OptimizerDesign.md index 39a5e13d3f31e..79bfb2de16311 100644 --- a/docs/OptimizerDesign.md +++ b/docs/OptimizerDesign.md @@ -9,23 +9,23 @@ knowledge of compiler optimizations is required. ### Optimization pipeline overview -The Swift compiler translates textual swift programs into LLVM-IR and uses +The Swift compiler translates textual Swift programs into LLVM-IR and uses multiple representations in between. The Swift frontend is responsible for -translating textual swift program into well-formed and type-checked programs +translating textual Swift programs into well-formed and type-checked programs that are encoded in the SIL intermediate representation. The frontend emits SIL -in a phase that's called SILGen (stands for SIL-generation). Next, the swift +in a phase that's called SILGen (stands for SIL-generation). Next, the Swift compiler performs a sequence of transformations, such as inlining and constant -propagation that allow the swift compiler to emit diagnostic messages (such as +propagation that allow the Swift compiler to emit diagnostic messages (such as warnings for uninitialized variables or arithmetic overflow). Next, the Swift optimizer transforms the code to make it faster. The optimizer removes redundant reference counting operations, devirtualizes function calls, and specializes generics and closures. This phase of the compiler is the focus of this document. Finally, the SIL intermediate representation is passed on to the IRGen -phase (stands for intermediate representation generationphase) that lowers SIL +phase (stands for intermediate representation generation phase) that lowers SIL into LLVM IR. The LLVM backend optimizes and emits binary code for the compiled program. -Please refer to the document “Swift Intermediate Language (SIL)” for more +Please refer to the document "Swift Intermediate Language (SIL)" for more details about the SIL IR. The compiler optimizer is responsible for optimizing the program using the @@ -40,7 +40,7 @@ opaque calls, and the LLVM-optimizer can't do anything about it. The goal of the Swift optimizer is not to reimplement optimizations that already exist in the LLVM optimizer. The goal is to implement optimizations that can't be implemented in LLVM-IR because the high-level semantic information is -lost. The swift optimizer does have some optimizations that are similar to LLVM +lost. The Swift optimizer does have some optimizations that are similar to LLVM optimizations, like SSA-construction and function inlining. These optimizations are implemented at the SIL-level because they are required for exposing other higher-level optimizations. For example, the ARC optimizer and devirtualizer @@ -50,7 +50,7 @@ prerequisite to the array optimizations. ### The Swift Pass Manager The Swift pass manager is the unit that executes optimization -passes on the functions in the swift module. Unlike the LLVM optimizer, the +passes on the functions in the Swift module. Unlike the LLVM optimizer, the Swift pass manager does not schedule analysis or optimization passes. The pass manager simply runs optimization passes on the functions in the module. The order of the optimizations is statically defined in the file "Passes.cpp". @@ -60,7 +60,7 @@ development. The pass manager scans the module and creates a list of functions that are organized at a bottom-up order. This means that the optimizer first optimizes -callees, and later optimizes the callers. This means that when optimizing a some +callees, and later optimizes the callers. This means that when optimizing some caller function, the optimizer had already optimized all of its callees and the optimizer can inspect the callee for side effects and inline it into the caller. @@ -125,8 +125,8 @@ The mechanism that swift uses to invalidate analysis is broadcast-invalidation. Passes ask the pass manager to invalidate specific traits. For example, a pass like simplify-cfg will ask the pass manager to announce that it modified some branches in the code. The pass manager will send a message to all of the -available analysis that says “please invalidate yourself if you care about -branches for function F“. The dominator tree would then invalidate the dominator +available analysis that says "please invalidate yourself if you care about +branches for function F". The dominator tree would then invalidate the dominator tree for function F because it knows that changes to branches can mean that the dominator tree was modified. @@ -153,7 +153,7 @@ the cache for the function that was modified. } ``` -The invalidation traits that passes can invalidate are are: +The invalidation traits that passes can invalidate are: 1. Instructions - some instructions were added, deleted or moved. 2. Calls - some call sites were added or deleted. 3. Branches - branches in the code were added, deleted or modified. @@ -189,7 +189,47 @@ functions with the @_semantics attribute until after all of the data-structure specific optimizations are done. Unfortunately, this lengthens our optimization pipeline. -Please refer to the document “High-Level SIL Optimizations” for more details. +Please refer to the document "High-Level SIL Optimizations" for more details. + + +### Instruction Invalidation in SIL + +Swift Passes and Analysis often keep instruction pointers in internal data +structures such as Map or Set. A good example of such data structure is a list +of visited instructions, or a map between a SILValue and the memory aliasing +effects of the value. + +Passes and utilities delete instructions in many different places in the +optimizer. When instructions are deleted pointers that are saved inside maps in +the different data structures become invalid. These pointers point to +deallocated memory locations. In some cases malloc allocates new instructions +with the same address as the freed instruction. Instruction reallocation bugs +are often difficult to detect because hash maps return values that are logically +incorrect. + +LLVM handles this problem by keeping ValueHandles, which are a kind of smart +pointers that handle instruction deletion and replaceAllUsesWith events. +ValueHandles are special uses of LLVM values. One problem with this approach is +that value handles require additional memory per-value and require doing extra +work when working with values. + +The Swift optimizer approach is to let the Context (currently a part of the +SILModule) handle the invalidation of instructions. When instructions are +deleted the context notifies a list of listeners. The invalidation mechanism is +relatively efficient and incurs a cost only when instructions are deleted. Every +time an instruction is deleted the context notifies all of the listeners that +requested to be notified. A typical notifications list is very short and is made +of the registered Analysis and the currently executed Pass. + +Passes and Analysis are registered by the PassManager to receive instruction +deletion notifications. Passes and Analysis simply need to implement the +following virtual method: + +``` + virtual void handleNotification(swift::ValueBase *Value) override { + llvm::errs()<<"SILCombine Deleting: " << Value<<"\n"; + } +``` ### Debugging the optimizer @@ -201,4 +241,4 @@ TODO. ### List of passes -The updated list of passes is available in the file “Passes.def”. +The updated list of passes is available in the file "Passes.def". diff --git a/docs/Pattern Matching.rst b/docs/Pattern Matching.rst index b3794de132a20..0875e7ee988c5 100644 --- a/docs/Pattern Matching.rst +++ b/docs/Pattern Matching.rst @@ -26,7 +26,7 @@ Swift has a pretty small set of types right now: * Function types. * Tuples. Heterogeneous fixed-length products. Swift's system provides two basic kinds of element: positional and labelled. -* Arrays. Homogenous fixed-length aggregates. +* Arrays. Homogeneous fixed-length aggregates. * Algebraic data types (ADTs), introduce by enum. Nominal closed disjoint unions of heterogeneous types. * Struct types. Nominal heterogeneous fixed-length products. @@ -354,7 +354,7 @@ imperative language — in contrast to, say, a functional language where you're in an expression and you need to produce a value — there's a colorable argument that non-exhaustive matches should be okay. I dislike this, however, and propose that it should be an error to -make an non-exhaustive switch; people who want non-exhaustive matches +make a non-exhaustive switch; people who want non-exhaustive matches can explicitly put in default cases. Exhaustiveness actually isn't that difficult to check, at least over ADTs. It's also really the behavior that I would expect from the @@ -689,13 +689,13 @@ interpreted according to what is found: value must match the named type (according to the rules below for 'is' patterns). It is okay for this to be trivially true. - In addition, there must be an non-empty arguments clause, and each + In addition, there must be a non-empty arguments clause, and each element in the clause must have an identifier. For each element, the identifier must correspond to a known property of the named type, and the value of that property must satisfy the element pattern. -- If the name resolves to a enum element, then the dynamic type +- If the name resolves to an enum element, then the dynamic type of the matched value must match the enum type as discussed above, and the value must be of the specified element. There must be an arguments clause if and only if the element has a value type. diff --git a/docs/Runtime.md b/docs/Runtime.md new file mode 100644 index 0000000000000..be0026fb1b486 --- /dev/null +++ b/docs/Runtime.md @@ -0,0 +1,408 @@ +# The Swift Runtime + +This document describes the ABI interface to the Swift runtime, which provides +the following core functionality for Swift programs: + +- memory management, including allocation and reference counting; +- the runtime type system, including dynamic casting, generic instantiation, + and protocol conformance registration; + +It is intended to describe only the runtime interface that compiler-generated +code should conform to, not details of how things are implemented. + +The final runtime interface is currently a work-in-progress; it is a goal of +Swift 3 to stabilize it. This document attempts to describe both the current +state of the runtime and the intended endpoint of the stable interface. +Changes that are intended to be made before stabilization are marked with +**ABI TODO**. Entry points that only exist on Darwin platforms with +ObjC interop, and +information that only pertains to ObjC interop, are marked **ObjC-only**. + +## Deprecated entry points + +Entry points in this section are intended to be removed or internalized before +ABI stabilization. + +### Exported C++ symbols + +**ABI TODO**: Any exported C++ symbols are implementation details that are not +intended to be part of the stable runtime interface. + +### swift\_ClassMirror\_count +### swift\_ClassMirror\_quickLookObject +### swift\_ClassMirror\_subscript +### swift\_EnumMirror\_caseName +### swift\_EnumMirror\_count +### swift\_EnumMirror\_subscript +### swift\_MagicMirrorData\_objcValue +### swift\_MagicMirrorData\_objcValueType +### swift\_MagicMirrorData\_summary +### swift\_MagicMirrorData\_value +### swift\_MagicMirrorData\_valueType +### swift\_ObjCMirror\_count +### swift\_ObjCMirror\_subscript +### swift\_StructMirror\_count +### swift\_StructMirror\_subscript +### swift\_TupleMirror\_count +### swift\_TupleMirror\_subscript +### swift\_reflectAny + +**ABI TODO**: These functions are implementation details of the standard +library `reflect` interface. They will be superseded by a low-level +runtime reflection API. + +### swift\_stdlib\_demangleName + +``` +@convention(thin) (string: UnsafePointer, + length: UInt, + @out String) -> () +``` + +Given a pointer to a Swift mangled symbol name as a byte string of `length` +characters, returns the demangled name as a `Swift.String`. + +**ABI TODO**: Decouple from the standard library `Swift.String` implementation. +Rename with a non-`stdlib` naming scheme. + +## Memory allocation + +### TODO + +``` +000000000001cb30 T _swift_allocBox +000000000001c990 T _swift_allocObject +000000000001ca60 T _swift_bufferAllocate +000000000001ca70 T _swift_bufferAllocateOnStack +000000000001ca80 T _swift_bufferDeallocateFromStack +000000000001ca90 T _swift_bufferHeaderSize +000000000001cd30 T _swift_deallocBox +000000000001d490 T _swift_deallocClassInstance +000000000001cd60 T _swift_deallocObject +000000000001d4c0 T _swift_deallocPartialClassInstance +000000000001d400 T _swift_rootObjCDealloc +000000000001c960 T _swift_slowAlloc +000000000001c980 T _swift_slowDealloc +000000000001ce10 T _swift_projectBox +000000000001ca00 T _swift_initStackObject +``` + +## Reference counting + +### TODO + +``` +0000000000027ba0 T _swift_bridgeObjectRelease +0000000000027c50 T _swift_bridgeObjectRelease_n +0000000000027b50 T _swift_bridgeObjectRetain +0000000000027be0 T _swift_bridgeObjectRetain_n +000000000001ce70 T _swift_release +000000000001cee0 T _swift_release_n +000000000001ce30 T _swift_retain +000000000001ce50 T _swift_retain_n +000000000001d140 T _swift_tryPin +000000000001d240 T _swift_tryRetain +0000000000027b10 T _swift_unknownRelease +0000000000027a70 T _swift_unknownRelease_n +0000000000027ad0 T _swift_unknownRetain +0000000000027a10 T _swift_unknownRetain_n +0000000000027d50 T _swift_unknownUnownedAssign +00000000000280a0 T _swift_unknownUnownedCopyAssign +0000000000027fd0 T _swift_unknownUnownedCopyInit +0000000000027ed0 T _swift_unknownUnownedDestroy +0000000000027cb0 T _swift_unknownUnownedInit +0000000000027f20 T _swift_unknownUnownedLoadStrong +00000000000281f0 T _swift_unknownUnownedTakeAssign +0000000000028070 T _swift_unknownUnownedTakeInit +0000000000027f70 T _swift_unknownUnownedTakeStrong +00000000000282b0 T _swift_unknownWeakAssign +0000000000028560 T _swift_unknownWeakCopyAssign +00000000000284e0 T _swift_unknownWeakCopyInit +00000000000283e0 T _swift_unknownWeakDestroy +0000000000028270 T _swift_unknownWeakInit +0000000000028420 T _swift_unknownWeakLoadStrong +0000000000028610 T _swift_unknownWeakTakeAssign +0000000000028520 T _swift_unknownWeakTakeInit +0000000000028470 T _swift_unknownWeakTakeStrong +000000000001d3c0 T _swift_unownedCheck +000000000001cfb0 T _swift_unownedRelease +000000000001d0a0 T _swift_unownedRelease_n +000000000001cf70 T _swift_unownedRetain +000000000001cf60 T _swift_unownedRetainCount +000000000001d2b0 T _swift_unownedRetainStrong +000000000001d310 T _swift_unownedRetainStrongAndRelease +000000000001d060 T _swift_unownedRetain_n +000000000001d1b0 T _swift_unpin +000000000001ca20 T _swift_verifyEndOfLifetime +000000000001d680 T _swift_weakAssign +000000000001d830 T _swift_weakCopyAssign +000000000001d790 T _swift_weakCopyInit +000000000001d770 T _swift_weakDestroy +000000000001d640 T _swift_weakInit +000000000001d6d0 T _swift_weakLoadStrong +000000000001d8b0 T _swift_weakTakeAssign +000000000001d800 T _swift_weakTakeInit +000000000001d710 T _swift_weakTakeStrong +000000000002afe0 T _swift_isUniquelyReferencedNonObjC +000000000002af50 T _swift_isUniquelyReferencedNonObjC_nonNull +000000000002b060 T _swift_isUniquelyReferencedNonObjC_nonNull_bridgeObject +000000000002b200 T _swift_isUniquelyReferencedOrPinnedNonObjC_nonNull +000000000002b130 T _swift_isUniquelyReferencedOrPinnedNonObjC_nonNull_bridgeObject +000000000002b2f0 T _swift_isUniquelyReferencedOrPinned_native +000000000002b290 T _swift_isUniquelyReferencedOrPinned_nonNull_native +000000000002af00 T _swift_isUniquelyReferenced_native +000000000002aea0 T _swift_isUniquelyReferenced_nonNull_native +000000000001d280 T _swift_isDeallocating +``` + +**ABI TODO**: `_unsynchronized` r/r entry points + +## Error objects + +The `ErrorType` existential type uses a special single-word, reference- +counted representation. + +**ObjC-only**: The representation is internal to the runtime in order +to provide efficient bridging with the platform `NSError` and `CFError` +implementations. On non-ObjC platforms this bridging is unnecessary, and +the error object interface could be made more fragile. + +To preserve the encapsulation of the ErrorType representation, and +allow for future representation optimizations, the runtime provides +special entry points for allocating, projecting, and reference +counting error values. + + +``` +00000000000268e0 T _swift_allocError +0000000000026d50 T _swift_bridgeErrorTypeToNSError +0000000000026900 T _swift_deallocError +0000000000027120 T _swift_errorRelease +0000000000027100 T _swift_errorRetain +0000000000026b80 T _swift_getErrorValue +``` + +**ABI TODO**: `_unsynchronized` r/r entry points + +**ABI TODO**: `_n` r/r entry points + +## Initialization + +### swift_once + +``` +@convention(thin) (Builtin.RawPointer, @convention(thin) () -> ()) -> () +``` + +Used to lazily initialize global variables. The first parameter must +point to a word-sized memory location that was initialized to zero at +process start. It is undefined behavior to reference memory that has +been initialized to something other than zero or written to by anything other +than `swift_once` in the current process's lifetime. The function referenced by +the second parameter will have been run exactly once in the time between +process start and the function returns. + +## Dynamic casting + +``` +0000000000001470 T _swift_dynamicCast +0000000000000a60 T _swift_dynamicCastClass +0000000000000ae0 T _swift_dynamicCastClassUnconditional +0000000000028750 T _swift_dynamicCastForeignClass +000000000002ae20 T _swift_dynamicCastForeignClassMetatype +000000000002ae30 T _swift_dynamicCastForeignClassMetatypeUnconditional +0000000000028760 T _swift_dynamicCastForeignClassUnconditional +00000000000011c0 T _swift_dynamicCastMetatype +0000000000000cf0 T _swift_dynamicCastMetatypeToObjectConditional +0000000000000d20 T _swift_dynamicCastMetatypeToObjectUnconditional +00000000000012e0 T _swift_dynamicCastMetatypeUnconditional +00000000000286c0 T _swift_dynamicCastObjCClass +0000000000028bd0 T _swift_dynamicCastObjCClassMetatype +0000000000028c00 T _swift_dynamicCastObjCClassMetatypeUnconditional +0000000000028700 T _swift_dynamicCastObjCClassUnconditional +0000000000028af0 T _swift_dynamicCastObjCProtocolConditional +0000000000028a50 T _swift_dynamicCastObjCProtocolUnconditional +0000000000028960 T _swift_dynamicCastTypeToObjCProtocolConditional +00000000000287d0 T _swift_dynamicCastTypeToObjCProtocolUnconditional +0000000000000de0 T _swift_dynamicCastUnknownClass +0000000000000fd0 T _swift_dynamicCastUnknownClassUnconditional +``` + +## Debugging + +``` +0000000000027140 T _swift_willThrow +``` + +## Objective-C Bridging + +**ObjC-only**. + +**ABI TODO**: Decouple from the runtime as much as possible. Much of this +should be implementable in the standard library now. + +``` +0000000000003b60 T _swift_bridgeNonVerbatimFromObjectiveC +0000000000003c80 T _swift_bridgeNonVerbatimFromObjectiveCConditional +00000000000037e0 T _swift_bridgeNonVerbatimToObjectiveC +00000000000039c0 T _swift_getBridgedNonVerbatimObjectiveCType +0000000000003d90 T _swift_isBridgedNonVerbatimToObjectiveC +``` + +## Code generation + +Certain common code paths are implemented in the runtime as a code size +optimization. + +``` +0000000000023a40 T _swift_assignExistentialWithCopy +000000000001dbf0 T _swift_copyPOD +000000000001c560 T _swift_getEnumCaseMultiPayload +000000000001be60 T _swift_getEnumCaseSinglePayload +000000000001c400 T _swift_storeEnumTagMultiPayload +000000000001bf90 T _swift_storeEnumTagSinglePayload +``` + +## Type metadata lookup + +These functions look up metadata for types that potentially require runtime +instantiation or initialization, including structural types, generics, classes, +and metadata for imported C and Objective-C types. + +**ABI TODO**: Instantiation APIs under flux as part of resilience work. For +nominal types, `getGenericMetadata` is likely to become an implementation +detail used to implement resilient per-type metadata accessor functions. + +``` +0000000000023230 T _swift_getExistentialMetatypeMetadata +0000000000023630 T _swift_getExistentialTypeMetadata +0000000000023b90 T _swift_getForeignTypeMetadata +000000000001ef30 T _swift_getFunctionTypeMetadata +000000000001eed0 T _swift_getFunctionTypeMetadata1 +000000000001f1f0 T _swift_getFunctionTypeMetadata2 +000000000001f250 T _swift_getFunctionTypeMetadata3 +000000000001e940 T _swift_getGenericMetadata +000000000001e9c0 T _swift_getGenericMetadata1 +000000000001ea60 T _swift_getGenericMetadata2 +000000000001eb00 T _swift_getGenericMetadata3 +000000000001eba0 T _swift_getGenericMetadata4 +0000000000022fd0 T _swift_getMetatypeMetadata +000000000001ec50 T _swift_getObjCClassMetadata +000000000001e6b0 T _swift_getResilientMetadata +0000000000022260 T _swift_getTupleTypeMetadata +00000000000225a0 T _swift_getTupleTypeMetadata2 +00000000000225d0 T _swift_getTupleTypeMetadata3 +0000000000028bc0 T _swift_getInitializedObjCClass +``` + +**ABI TODO**: Fast entry points for `getExistential*TypeMetadata1-3`. Static +metadata for `Any` and `AnyObject` is probably worth considering too. + +## Type metadata initialization + +Calls to these entry points are emitted when instantiating type metadata at +runtime. + +**ABI TODO**: Initialization APIs under flux as part of resilience work. + +``` +000000000001e3e0 T _swift_allocateGenericClassMetadata +000000000001e620 T _swift_allocateGenericValueMetadata +0000000000022be0 T _swift_initClassMetadata_UniversalStrategy +000000000001c100 T _swift_initEnumMetadataMultiPayload +000000000001bd60 T _swift_initEnumValueWitnessTableSinglePayload +0000000000022a20 T _swift_initStructMetadata_UniversalStrategy +0000000000024230 T _swift_initializeSuperclass +0000000000028b60 T _swift_instantiateObjCClass +``` + +## Metatypes + +``` +0000000000000b60 T _swift_getDynamicType +0000000000022fb0 T _swift_getObjectType +00000000000006f0 T _swift_getTypeName +00000000000040c0 T _swift_isClassType +0000000000003f50 T _swift_isClassOrObjCExistentialType +0000000000004130 T _swift_isOptionalType +00000000000279f0 T _swift_objc_class_usesNativeSwiftReferenceCounting +000000000002b340 T _swift_objc_class_unknownGetInstanceExtents +000000000002b350 T _swift_class_getInstanceExtents +0000000000004080 T _swift_class_getSuperclass +``` + +**ABI TODO**: getTypeByName entry point. + +**ABI TODO**: Should have a `getTypeKind` entry point with well-defined enum +constants to supersede `swift_is*Type`. + +**ABI TODO**: Rename class metadata queries with a consistent naming scheme. + +## Protocol conformance lookup + +``` +0000000000002ef0 T _swift_registerProtocolConformances +0000000000003060 T _swift_conformsToProtocol +``` + +## Error reporting + +``` +000000000001c7d0 T _swift_reportError +000000000001c940 T _swift_deletedMethodError +``` + +## Standard metadata + +The Swift runtime exports standard metadata objects for `Builtin` types +as well as standard value witness tables that can be freely adopted by +types with common layout attributes. Note that, unlike public-facing types, +the runtime does not guarantee a 1:1 mapping of Builtin types to metadata +objects, and will reuse metadata objects to represent builtins with the same +layout characteristics. + +``` +000000000004faa8 S __TMBB +000000000004fab8 S __TMBO +000000000004f9f8 S __TMBb +000000000004f9c8 S __TMBi128_ +000000000004f998 S __TMBi16_ +000000000004f9d8 S __TMBi256_ +000000000004f9a8 S __TMBi32_ +000000000004f9b8 S __TMBi64_ +000000000004f988 S __TMBi8_ +000000000004f9e8 S __TMBo +000000000004fac8 S __TMT_ +000000000004f568 S __TWVBO +000000000004f4b0 S __TWVBb +000000000004f0a8 S __TWVBi128_ +000000000004eec8 S __TWVBi16_ +000000000004f148 S __TWVBi256_ +000000000004ef68 S __TWVBi32_ +000000000004f008 S __TWVBi64_ +000000000004ee28 S __TWVBi8_ +000000000004f1e8 S __TWVBo +000000000004f778 S __TWVFT_T_ +000000000004f3f8 S __TWVMBo +000000000004f8e8 S __TWVT_ +000000000004f830 S __TWVXfT_T_ +000000000004f620 S __TWVXoBO +000000000004f2a0 S __TWVXoBo +000000000004f6d8 S __TWVXwGSqBO_ +000000000004f358 S __TWVXwGSqBo_ +``` + +## Tasks + +- Moving to per-type instantiation functions instead of using + `getGenericMetadata` directly + +- `swift_objc_` naming convention for ObjC + +- Alternative ABIs for retain/release + +- Unsynchronized retain/release + +- Nonnull retain/release + +- Decouple dynamic casting, bridging, and reflection from the standard library diff --git a/docs/SIL.rst b/docs/SIL.rst index 208c7146bb4c7..4d6116e873ae8 100644 --- a/docs/SIL.rst +++ b/docs/SIL.rst @@ -253,7 +253,7 @@ Consider a generic function like this: :: - func generateArray(n : Int, generator : () -> T) -> T[] + func generateArray(n : Int, generator : () -> T) -> [T] The function ``generator`` will be expected to store its result indirectly into an address passed in an implicit parameter. There's @@ -312,7 +312,7 @@ lowered using the pattern ``() -> T``, which eventually causes ``(Int,Int) lowering it with the pattern ``U -> V``; the result is that ``g.fn`` has the following lowered type:: - @callee_owned () -> @owned @callee_owned (@out Float, @in (Int,Int)) -> ()``. + @callee_owned () -> @owned @callee_owned (@out Float, @in (Int,Int)) -> (). As another example, suppose that ``h`` has type ``Generator<(Int, @inout Int) -> Float>``. Neither ``(Int, @inout Int)`` @@ -341,8 +341,6 @@ The type of a value in SIL shall be: - the address of a legal SIL type, ``$*T``, or -- the address of local storage of a legal SIL type, ``$*@local_storage T``. - A type ``T`` is a *legal SIL type* if: - it is a function type which satisfies the constraints (below) on @@ -386,22 +384,6 @@ type. Values of address type thus cannot be allocated, loaded, or stored Addresses can be passed as arguments to functions if the corresponding parameter is indirect. They cannot be returned. -Local Storage Types -``````````````````` - -The *address of local storage for T* ``$*@local_storage T`` is a -handle to a stack allocation of a variable of type ``$T``. - -For many types, the handle for a stack allocation is simply the -allocated address itself. However, if a type is runtime-sized, the -compiler must emit code to potentially dynamically allocate memory. -SIL abstracts over such differences by using values of local-storage -type as the first result of ``alloc_stack`` and the operand of -``dealloc_stack``. - -Local-storage address types are not *first-class* in the same sense -that address types are not first-class. - Box Types ````````` @@ -424,7 +406,7 @@ number of ways: - A SIL function type declares its conventional treatment of its context value: - - If it is ``@thin``, the function requires no context value. + - If it is ``@convention(thin)``, the function requires no context value. - If it is ``@callee_owned``, the context value is treated as an owned direct parameter. @@ -449,8 +431,24 @@ number of ways: the value held there. - An ``@inout`` parameter is indirect. The address must be of an - initialized object, and the function must leave an initialized - object there upon exit. + initialized object. The memory must remain initialized for the duration + of the call until the function returns. The function may mutate the + pointee, and furthermore may weakly assume that there are no aliasing + reads from or writes to the argument, though must preserve a valid + value at the argument so that well-ordered aliasing violations do not + compromise memory safety. This allows for optimizations such as local + load and store propagation, introduction or elimination of temporary + copies, and promotion of the ``@inout`` parameter to an ``@owned`` direct + parameter and result pair, but does not admit "take" optimization out + of the parameter or other optimization that would leave memory in an + uninitialized state. + + - An ``@inout_aliasable`` parameter is indirect. The address must be of an + initialized object. The memory must remain initialized for the duration + of the call until the function returns. The function may mutate the + pointee, and must assume that other aliases may mutate it as well. These + aliases however can be assumed to be well-typed and well-ordered; ill-typed + accesses and data races to the parameter are still undefined. - An ``@out`` parameter is indirect. The address must be of an uninitialized object; the function is responsible for initializing @@ -495,9 +493,19 @@ throughout the execution of the call. This means that any argument can be eliminated. An autoreleased direct result must have a type with a retainable -pointer representation. It may have been autoreleased, and the caller -should take action to reclaim that autorelease with -``strong_retain_autoreleased``. +pointer representation. Autoreleased results are nominally transferred +at +0, but the runtime takes steps to ensure that a +1 can be safely +transferred, and those steps require precise code-layout control. +Accordingly, the SIL pattern for an autoreleased convention looks exactly +like the SIL pattern for an owned convention, and the extra runtime +instrumentation is inserted on both sides when the SIL is lowered into +LLVM IR. An autoreleased ``apply`` of a function that is defined with +an autoreleased result has the effect of a +1 transfer of the result. +An autoreleased ``apply`` of a function that is not defined with +an autoreleased result has the effect of performing a strong retain in +the caller. A non-autoreleased ``apply`` of a function that is defined +with an autoreleased result has the effect of performing an +autorelease in the callee. - The @noescape declaration attribute on Swift parameters (which is valid only on parameters of function type, and is implied by the @autoclosure attribute) @@ -568,7 +576,7 @@ generic constraints: * Non-class protocol types * @weak types - Values of address-only type (“address-only values”) must reside in + Values of address-only type ("address-only values") must reside in memory and can only be referenced in SIL by address. Addresses of address-only values cannot be loaded from or stored to. SIL provides special instructions for indirectly manipulating address-only @@ -578,7 +586,7 @@ Some additional meaningful categories of type: - A *heap object reference* type is a type whose representation consists of a single strong-reference-counted pointer. This includes all class types, - the ``Builtin.ObjectPointer`` and ``Builtin.ObjCPointer`` types, and + the ``Builtin.NativeObject`` and ``Builtin.UnknownObject`` types, and archetypes that conform to one or more class protocols. - A *reference type* is more general in that its low-level representation may include additional global pointers alongside a strong-reference-counted @@ -773,7 +781,7 @@ are bound by the function's caller:: sil @foo : $(Int) -> Int { bb0(%x : $Int): - %1 = return %x : $Int + return %x : $Int } sil @bar : $(Int, Int) -> () { @@ -782,7 +790,7 @@ are bound by the function's caller:: %1 = apply %foo(%x) : $(Int) -> Int %2 = apply %foo(%y) : $(Int) -> Int %3 = tuple () - %4 = return %3 : $() + return %3 : $() } Declaration References @@ -838,16 +846,17 @@ partial application level. For a curried function declaration:: The declaration references and types for the different uncurry levels are as follows:: - #example.foo!0 : $@thin (x:A) -> (y:B) -> (z:C) -> D - #example.foo!1 : $@thin ((y:B), (x:A)) -> (z:C) -> D - #example.foo!2 : $@thin ((z:C), (y:B), (x:A)) -> D + #example.foo!0 : $@convention(thin) (x:A) -> (y:B) -> (z:C) -> D + #example.foo!1 : $@convention(thin) ((y:B), (x:A)) -> (z:C) -> D + #example.foo!2 : $@convention(thin) ((z:C), (y:B), (x:A)) -> D The deepest uncurry level is referred to as the **natural uncurry level**. In this specific example, the reference at the natural uncurry level is ``#example.foo!2``. Note that the uncurried argument clauses are composed right-to-left, as specified in the `calling convention`_. For uncurry levels -less than the uncurry level, the entry point itself is ``@thin`` but returns a -thick function value carrying the partially applied arguments for its context. +less than the uncurry level, the entry point itself is ``@convention(thin)`` but +returns a thick function value carrying the partially applied arguments for its +context. `Dynamic dispatch`_ instructions such as ``class method`` require their method declaration reference to be uncurried to at least uncurry level 1 (which applies @@ -981,9 +990,9 @@ implements the method for that class:: func bas() } - sil @A_foo : $@thin (@owned A) -> () - sil @A_bar : $@thin (@owned A) -> () - sil @A_bas : $@thin (@owned A) -> () + sil @A_foo : $@convention(thin) (@owned A) -> () + sil @A_bar : $@convention(thin) (@owned A) -> () + sil @A_bas : $@convention(thin) (@owned A) -> () sil_vtable A { #A.foo!1: @A_foo @@ -995,7 +1004,7 @@ implements the method for that class:: func bar() } - sil @B_bar : $@thin (@owned B) -> () + sil @B_bar : $@convention(thin) (@owned B) -> () sil_vtable B { #A.foo!1: @A_foo @@ -1007,7 +1016,7 @@ implements the method for that class:: func bas() } - sil @C_bas : $@thin (@owned C) -> () + sil @C_bas : $@convention(thin) (@owned C) -> () sil_vtable C { #A.foo!1: @A_foo @@ -1166,8 +1175,8 @@ Calling Convention This section describes how Swift functions are emitted in SIL. -Swift Calling Convention @cc(swift) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Swift Calling Convention @convention(swift) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The Swift calling convention is the one used by default for native Swift functions. @@ -1362,13 +1371,13 @@ gets lowered to SIL as:: sil @inout : $(@inout Int) -> () { entry(%x : $*Int): - %1 = integer_literal 1 : $Int + %1 = integer_literal $Int, 1 store %1 to %x return } -Swift Method Calling Convention @cc(method) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Swift Method Calling Convention @convention(method) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The method calling convention is currently identical to the freestanding function convention. Methods are considered to be curried functions, taking @@ -1382,8 +1391,8 @@ passed last:: sil @Foo_method_1 : $((x : Int), @inout Foo) -> Int { ... } -Witness Method Calling Convention @cc(witness_method) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Witness Method Calling Convention @convention(witness_method) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The witness method calling convention is used by protocol witness methods in `witness tables`_. It is identical to the ``method`` calling convention @@ -1394,8 +1403,8 @@ witnesses must be polymorphically dispatchable on their ``Self`` type, the ``Self``-related metadata for a witness must be passed in a maximally abstracted manner. -C Calling Convention @cc(cdecl) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +C Calling Convention @convention(c) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In Swift's C module importer, C types are always mapped to Swift types considered trivial by SIL. SIL does not concern itself with platform @@ -1405,8 +1414,8 @@ platform calling convention. SIL (and therefore Swift) cannot currently invoke variadic C functions. -Objective-C Calling Convention @cc(objc_method) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Objective-C Calling Convention @convention(objc_method) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Reference Counts ```````````````` @@ -1497,7 +1506,7 @@ return a class reference:: bb0(%0 : $MyClass): %1 = class_method %0 : $MyClass, #MyClass.foo!1 - %2 = apply %1(%0) : $@cc(method) @thin (@guaranteed MyClass) -> @owned MyOtherClass + %2 = apply %1(%0) : $@convention(method) (@guaranteed MyClass) -> @owned MyOtherClass // use of %2 goes here; no use of %1 strong_release %2 : $MyOtherClass strong_release %1 : $MyClass @@ -1532,8 +1541,8 @@ A value ``%1`` is said to be *value-dependent* on a value ``%0`` if: - ``%1`` is the result of ``mark_dependence`` and ``%0`` is either of the operands. -- ``%1`` is the value address of an allocation instruction of which - ``%0`` is the local storage token or box reference. +- ``%1`` is the value address of a box allocation instruction of which + ``%0`` is the box reference. - ``%1`` is the result of a ``struct``, ``tuple``, or ``enum`` instruction and ``%0`` is an operand. @@ -1604,16 +1613,18 @@ alloc_stack ``````````` :: - sil-instruction ::= 'alloc_stack' sil-type + sil-instruction ::= 'alloc_stack' sil-type (',' debug-var-attr)* %1 = alloc_stack $T - // %1#0 has type $*@local_storage T - // %1#1 has type $*T + // %1 has type $*T Allocates uninitialized memory that is sufficiently aligned on the stack -to contain a value of type ``T``. The first result of the instruction -is a local-storage handle suitable for passing to ``dealloc_stack``. -The second result of the instruction is the address of the allocated memory. +to contain a value of type ``T``. The result of the instruction is the address +of the allocated memory. + +If a type is runtime-sized, the compiler must emit code to potentially +dynamically allocate memory. So there is no guarantee that the allocated +memory is really located on the stack. ``alloc_stack`` marks the start of the lifetime of the value; the allocation must be balanced with a ``dealloc_stack`` instruction to @@ -1671,7 +1682,7 @@ alloc_box ````````` :: - sil-instruction ::= 'alloc_box' sil-type + sil-instruction ::= 'alloc_box' sil-type (',' debug-var-attr)* %1 = alloc_box $T // %1 has two values: @@ -1714,16 +1725,16 @@ dealloc_stack sil-instruction ::= 'dealloc_stack' sil-operand - dealloc_stack %0 : $*@local_storage T - // %0 must be of a local-storage $*@local_storage T type + dealloc_stack %0 : $*T + // %0 must be of $*T type Deallocates memory previously allocated by ``alloc_stack``. The allocated value in memory must be uninitialized or destroyed prior to being deallocated. This instruction marks the end of the lifetime for the value created by the corresponding ``alloc_stack`` instruction. The operand -must be the ``@local_storage`` of the shallowest live ``alloc_stack`` -allocation preceding the deallocation. In other words, deallocations must be -in last-in, first-out stack order. +must be the shallowest live ``alloc_stack`` allocation preceding the +deallocation. In other words, deallocations must be in last-in, first-out +stack order. dealloc_box ``````````` @@ -1860,7 +1871,7 @@ debug_value :: - sil-instruction ::= debug_value sil-operand + sil-instruction ::= debug_value sil-operand (',' debug-var-attr)* debug_value %1 : $Int @@ -1870,12 +1881,24 @@ the SILLocation attached to the debug_value instruction. The operand must have loadable type. +:: + + debug-var-attr ::= 'var' + debug-var-attr ::= 'let' + debug-var-attr ::= 'name' string-literal + debug-var-attr ::= 'argno' integer-literal + +There are a number of attributes that provide details about the source +variable that is being described, including the name of the +variable. For function and closure arguments ``argno`` is the number +of the function argument starting with 1. + debug_value_addr ```````````````` :: - sil-instruction ::= debug_value_addr sil-operand + sil-instruction ::= debug_value_addr sil-operand (',' debug-var-attr)* debug_value_addr %7 : $*SomeProtocol @@ -2168,23 +2191,6 @@ strong_retain Increases the strong retain count of the heap object referenced by ``%0``. -strong_retain_autoreleased -`````````````````````````` -:: - - sil-instruction ::= 'strong_retain_autoreleased' sil-operand - - strong_retain_autoreleased %0 : $T - // $T must have a retainable pointer representation - -Retains the heap object referenced by ``%0`` using the Objective-C ARC -"autoreleased return value" optimization. The operand must be the result of an -``apply`` instruction with an Objective-C method callee, and the -``strong_retain_autoreleased`` instruction must be first use of the value after -the defining ``apply`` instruction. - -TODO: Specify all the other strong_retain_autoreleased constraints here. - strong_release `````````````` :: @@ -2371,8 +2377,8 @@ function_ref sil-instruction ::= 'function_ref' sil-function-name ':' sil-type - %1 = function_ref @function : $@thin T -> U - // $@thin T -> U must be a thin function type + %1 = function_ref @function : $@convention(thin) T -> U + // $@convention(thin) T -> U must be a thin function type // %1 has type $T -> U Creates a reference to a SIL function. @@ -2462,7 +2468,7 @@ class_method sil-instruction ::= 'class_method' sil-method-attributes? sil-operand ',' sil-decl-ref ':' sil-type - %1 = class_method %0 : $T, #T.method!1 : $@thin U -> V + %1 = class_method %0 : $T, #T.method!1 : $@convention(thin) U -> V // %0 must be of a class type or class metatype $T // #T.method!1 must be a reference to a dynamically-dispatched method of T or // of one of its superclasses, at uncurry level >= 1 @@ -2491,11 +2497,11 @@ super_method sil-instruction ::= 'super_method' sil-method-attributes? sil-operand ',' sil-decl-ref ':' sil-type - %1 = super_method %0 : $T, #Super.method!1.foreign : $@thin U -> V + %1 = super_method %0 : $T, #Super.method!1.foreign : $@convention(thin) U -> V // %0 must be of a non-root class type or class metatype $T // #Super.method!1.foreign must be a reference to an ObjC method of T's // superclass or of one of its ancestor classes, at uncurry level >= 1 - // %1 will be of type $@thin U -> V + // %1 will be of type $@convention(thin) U -> V Looks up a method in the superclass of a class or class metatype instance. Note that for native Swift methods, ``super.method`` calls are statically @@ -2511,13 +2517,13 @@ witness_method sil-type ',' sil-decl-ref ':' sil-type %1 = witness_method $T, #Proto.method!1 \ - : $@thin @cc(witness_method) U -> V + : $@convention(witness_method) U -> V // $T must be an archetype // #Proto.method!1 must be a reference to a method of one of the protocol // constraints on T // U -> V must be the type of the referenced method, // generic on Self - // %1 will be of type $@thin U -> V + // %1 will be of type $@convention(thin) U -> V Looks up the implementation of a protocol method for a generic type variable constrained by that protocol. The result will be generic on the ``Self`` @@ -2532,20 +2538,20 @@ dynamic_method sil-instruction ::= 'dynamic_method' sil-method-attributes? sil-operand ',' sil-decl-ref ':' sil-type - %1 = dynamic_method %0 : $P, #X.method!1 : $@thin U -> V + %1 = dynamic_method %0 : $P, #X.method!1 : $@convention(thin) U -> V // %0 must be of a protocol or protocol composition type $P, // where $P contains the Swift.DynamicLookup protocol // #X.method!1 must be a reference to an @objc method of any class // or protocol type // - // The "self" argument of the method type $@thin U -> V must be - // Builtin.ObjCPointer + // The "self" argument of the method type $@convention(thin) U -> V must be + // Builtin.UnknownObject Looks up the implementation of an Objective-C method with the same selector as the named method for the dynamic type of the value inside an existential container. The "self" operand of the result function value is represented using an opaque type, the value for which must -be projected out as a value of type ``Builtin.ObjCPointer``. +be projected out as a value of type ``Builtin.UnknownObject``. It is undefined behavior if the dynamic type of the operand does not have an implementation for the Objective-C method with the selector to @@ -2584,7 +2590,7 @@ apply // %1, %2, etc. must be of the argument types $A, $B, etc. // %r will be of the return type $R - %r = apply %0(%1, %2, ...) : $(T, U, ...) -> R + %r = apply %0(%1, %2, ...) : $(T, U, ...) -> R // %0 must be of a polymorphic function type $(T, U, ...) -> R // %1, %2, etc. must be of the argument types after substitution $A, $B, etc. // %r will be of the substituted return type $R' @@ -2628,7 +2634,7 @@ partial_apply // of the tail part of the argument tuple of %0 // %c will be of the partially-applied thick function type (Z...) -> R - %c = partial_apply %0(%1, %2, ...) : $(Z..., T, U, ...) -> R + %c = partial_apply %0(%1, %2, ...) : $(Z..., T, U, ...) -> R // %0 must be of a polymorphic function type $(T, U, ...) -> R // %1, %2, etc. must be of the argument types after substitution $A, $B, etc. // of the tail part of the argument tuple of %0 @@ -2664,28 +2670,30 @@ curried function in Swift:: emits curry thunks in SIL as follows (retains and releases omitted for clarity):: - func @foo : $@thin A -> B -> C -> D -> E { + func @foo : $@convention(thin) A -> B -> C -> D -> E { entry(%a : $A): - %foo_1 = function_ref @foo_1 : $@thin (B, A) -> C -> D -> E - %thunk = partial_apply %foo_1(%a) : $@thin (B, A) -> C -> D -> E + %foo_1 = function_ref @foo_1 : $@convention(thin) (B, A) -> C -> D -> E + %thunk = partial_apply %foo_1(%a) : $@convention(thin) (B, A) -> C -> D -> E return %thunk : $B -> C -> D -> E } - func @foo_1 : $@thin (B, A) -> C -> D -> E { + func @foo_1 : $@convention(thin) (B, A) -> C -> D -> E { entry(%b : $B, %a : $A): - %foo_2 = function_ref @foo_2 : $@thin (C, B, A) -> D -> E - %thunk = partial_apply %foo_2(%b, %a) : $@thin (C, B, A) -> D -> E + %foo_2 = function_ref @foo_2 : $@convention(thin) (C, B, A) -> D -> E + %thunk = partial_apply %foo_2(%b, %a) \ + : $@convention(thin) (C, B, A) -> D -> E return %thunk : $(B, A) -> C -> D -> E } - func @foo_2 : $@thin (C, B, A) -> D -> E { + func @foo_2 : $@convention(thin) (C, B, A) -> D -> E { entry(%c : $C, %b : $B, %a : $A): - %foo_3 = function_ref @foo_3 : $@thin (D, C, B, A) -> E - %thunk = partial_apply %foo_3(%c, %b, %a) : $@thin (D, C, B, A) -> E + %foo_3 = function_ref @foo_3 : $@convention(thin) (D, C, B, A) -> E + %thunk = partial_apply %foo_3(%c, %b, %a) \ + : $@convention(thin) (D, C, B, A) -> E return %thunk : $(C, B, A) -> D -> E } - func @foo_3 : $@thin (D, C, B, A) -> E { + func @foo_3 : $@convention(thin) (D, C, B, A) -> E { entry(%d : $D, %c : $C, %b : $B, %a : $A): // ... body of foo ... } @@ -2702,12 +2710,12 @@ following example:: lowers to an uncurried entry point and is curried in the enclosing function:: - func @bar : $@thin (Int, @box Int, *Int) -> Int { + func @bar : $@convention(thin) (Int, @box Int, *Int) -> Int { entry(%y : $Int, %x_box : $@box Int, %x_address : $*Int): // ... body of bar ... } - func @foo : $@thin Int -> Int { + func @foo : $@convention(thin) Int -> Int { entry(%x : $Int): // Create a box for the 'x' variable %x_box = alloc_box $Int @@ -2716,7 +2724,7 @@ lowers to an uncurried entry point and is curried in the enclosing function:: // Create the bar closure %bar_uncurried = function_ref @bar : $(Int, Int) -> Int %bar = partial_apply %bar_uncurried(%x_box#0, %x_box#1) \ - : $(Int, Builtin.ObjectPointer, *Int) -> Int + : $(Int, Builtin.NativeObject, *Int) -> Int // Apply it %1 = integer_literal $Int, 1 @@ -2754,8 +2762,8 @@ metatype sil-instruction ::= 'metatype' sil-type - %1 = metatype $T.metatype - // %1 has type $T.metatype + %1 = metatype $T.Type + // %1 has type $T.Type Creates a reference to the metatype object for type ``T``. @@ -2765,9 +2773,9 @@ value_metatype sil-instruction ::= 'value_metatype' sil-type ',' sil-operand - %1 = value_metatype $T.metatype, %0 : $T + %1 = value_metatype $T.Type, %0 : $T // %0 must be a value or address of type $T - // %1 will be of type $T.metatype + // %1 will be of type $T.Type Obtains a reference to the dynamic metatype of the value ``%0``. @@ -2777,10 +2785,10 @@ existential_metatype sil-instruction ::= 'existential_metatype' sil-type ',' sil-operand - %1 = existential_metatype $P.metatype, %0 : $P + %1 = existential_metatype $P.Type, %0 : $P // %0 must be a value of class protocol or protocol composition // type $P, or an address of address-only protocol type $*P - // %1 will be a $P.metatype value referencing the metatype of the + // %1 will be a $P.Type value referencing the metatype of the // concrete value inside %0 Obtains the metatype of the concrete value @@ -2980,16 +2988,16 @@ the enum is injected with an `inject_enum_addr`_ instruction:: sil @init_with_data : $(AddressOnlyType) -> AddressOnlyEnum { entry(%0 : $*AddressOnlyEnum, %1 : $*AddressOnlyType): // Store the data argument for the case. - %2 = init_enum_data_addr %0 : $*AddressOnlyEnum, #AddressOnlyEnum.HasData + %2 = init_enum_data_addr %0 : $*AddressOnlyEnum, #AddressOnlyEnum.HasData!enumelt.1 copy_addr [take] %2 to [initialization] %1 : $*AddressOnlyType // Inject the tag. - inject_enum_addr %0 : $*AddressOnlyEnum, #AddressOnlyEnum.HasData + inject_enum_addr %0 : $*AddressOnlyEnum, #AddressOnlyEnum.HasData!enumelt.1 return } sil @init_without_data : $() -> AddressOnlyEnum { // No data. We only need to inject the tag. - inject_enum_addr %0 : $*AddressOnlyEnum, #AddressOnlyEnum.NoData + inject_enum_addr %0 : $*AddressOnlyEnum, #AddressOnlyEnum.NoData!enumelt return } @@ -3000,7 +3008,7 @@ discriminator and is done with the `switch_enum`_ terminator:: sil @switch_foo : $(Foo) -> () { entry(%foo : $Foo): - switch_enum %foo : $Foo, case #Foo.A: a_dest, case #Foo.B: b_dest + switch_enum %foo : $Foo, case #Foo.A!enumelt.1: a_dest, case #Foo.B!enumelt.1: b_dest a_dest(%a : $Int): /* use %a */ @@ -3017,14 +3025,15 @@ projecting the enum value with `unchecked_take_enum_data_addr`_:: sil @switch_foo : $ (Foo) -> () { entry(%foo : $*Foo): - switch_enum_addr %foo : $*Foo, case #Foo.A: a_dest, case #Foo.B: b_dest + switch_enum_addr %foo : $*Foo, case #Foo.A!enumelt.1: a_dest, \ + case #Foo.B!enumelt.1: b_dest a_dest: - %a = unchecked_take_enum_data_addr %foo : $*Foo, #Foo.A + %a = unchecked_take_enum_data_addr %foo : $*Foo, #Foo.A!enumelt.1 /* use %a */ b_dest: - %b = unchecked_take_enum_data_addr %foo : $*Foo, #Foo.B + %b = unchecked_take_enum_data_addr %foo : $*Foo, #Foo.B!enumelt.1 /* use %b */ } @@ -3034,8 +3043,8 @@ enum sil-instruction ::= 'enum' sil-type ',' sil-decl-ref (',' sil-operand)? - %1 = enum $U, #U.EmptyCase - %1 = enum $U, #U.DataCase, %0 : $T + %1 = enum $U, #U.EmptyCase!enumelt + %1 = enum $U, #U.DataCase!enumelt.1, %0 : $T // $U must be an enum type // #U.DataCase or #U.EmptyCase must be a case of enum $U // If #U.Case has a data type $T, %0 must be a value of type $T @@ -3051,7 +3060,7 @@ unchecked_enum_data sil-instruction ::= 'unchecked_enum_data' sil-operand ',' sil-decl-ref - %1 = unchecked_enum_data %0 : $U, #U.DataCase + %1 = unchecked_enum_data %0 : $U, #U.DataCase!enumelt.1 // $U must be an enum type // #U.DataCase must be a case of enum $U with data // %1 will be of object type $T for the data type of case U.DataCase @@ -3066,7 +3075,7 @@ init_enum_data_addr sil-instruction ::= 'init_enum_data_addr' sil-operand ',' sil-decl-ref - %1 = init_enum_data_addr %0 : $*U, #U.DataCase + %1 = init_enum_data_addr %0 : $*U, #U.DataCase!enumelt.1 // $U must be an enum type // #U.DataCase must be a case of enum $U with data // %1 will be of address type $*T for the data type of case U.DataCase @@ -3088,7 +3097,7 @@ inject_enum_addr sil-instruction ::= 'inject_enum_addr' sil-operand ',' sil-decl-ref - inject_enum_addr %0 : $*U, #U.Case + inject_enum_addr %0 : $*U, #U.Case!enumelt // $U must be an enum type // #U.Case must be a case of enum $U // %0 will be overlaid with the tag for #U.Case @@ -3108,7 +3117,7 @@ unchecked_take_enum_data_addr sil-instruction ::= 'unchecked_take_enum_data_addr' sil-operand ',' sil-decl-ref - %1 = unchecked_take_enum_data_addr %0 : $*U, #U.DataCase + %1 = unchecked_take_enum_data_addr %0 : $*U, #U.DataCase!enumelt.1 // $U must be an enum type // #U.DataCase must be a case of enum $U with data // %1 will be of address type $*T for the data type of case U.DataCase @@ -3135,8 +3144,8 @@ select_enum ':' sil-type %n = select_enum %0 : $U, \ - case #U.Case1: %1, \ - case #U.Case2: %2, /* ... */ \ + case #U.Case1!enumelt: %1, \ + case #U.Case2!enumelt: %2, /* ... */ \ default %3 : $T // $U must be an enum type @@ -3149,8 +3158,8 @@ enum value. This is equivalent to a trivial `switch_enum`_ branch sequence:: entry: switch_enum %0 : $U, \ - case #U.Case1: bb1, \ - case #U.Case2: bb2, /* ... */ \ + case #U.Case1!enumelt: bb1, \ + case #U.Case2!enumelt: bb2, /* ... */ \ default bb_default bb1: br cont(%1 : $T) // value for #U.Case1 @@ -3174,8 +3183,8 @@ select_enum_addr ':' sil-type %n = select_enum_addr %0 : $*U, \ - case #U.Case1: %1, \ - case #U.Case2: %2, /* ... */ \ + case #U.Case1!enumelt: %1, \ + case #U.Case2!enumelt: %2, /* ... */ \ default %3 : $T // %0 must be the address of an enum type $*U @@ -3605,7 +3614,7 @@ ref_to_raw_pointer sil-instruction ::= 'ref_to_raw_pointer' sil-operand 'to' sil-type %1 = ref_to_raw_pointer %0 : $C to $Builtin.RawPointer - // $C must be a class type, or Builtin.ObjectPointer, or Builtin.ObjCPointer + // $C must be a class type, or Builtin.NativeObject, or Builtin.UnknownObject // %1 will be of type $Builtin.RawPointer Converts a heap object reference to a ``Builtin.RawPointer``. The ``RawPointer`` @@ -3620,7 +3629,7 @@ raw_pointer_to_ref sil-instruction ::= 'raw_pointer_to_ref' sil-operand 'to' sil-type %1 = raw_pointer_to_ref %0 : $Builtin.RawPointer to $C - // $C must be a class type, or Builtin.ObjectPointer, or Builtin.ObjCPointer + // $C must be a class type, or Builtin.NativeObject, or Builtin.UnknownObject // %1 will be of type $C Converts a ``Builtin.RawPointer`` back to a heap object reference. Casting @@ -3787,10 +3796,10 @@ thick_to_objc_metatype sil-instruction ::= 'thick_to_objc_metatype' sil-operand 'to' sil-type - %1 = thick_to_objc_metatype %0 : $@thick T.metatype to $@objc_metatype T.metatype - // %0 must be of a thick metatype type $@thick T.metatype + %1 = thick_to_objc_metatype %0 : $@thick T.Type to $@objc_metatype T.Type + // %0 must be of a thick metatype type $@thick T.Type // The destination type must be the corresponding Objective-C metatype type - // %1 will be of type $@objc_metatype T.metatype + // %1 will be of type $@objc_metatype T.Type Converts a thick metatype to an Objective-C class metatype. ``T`` must be of class, class protocol, or class protocol composition type. @@ -3801,10 +3810,10 @@ objc_to_thick_metatype sil-instruction ::= 'objc_to_thick_metatype' sil-operand 'to' sil-type - %1 = objc_to_thick_metatype %0 : $@objc_metatype T.metatype to $@thick T.metatype - // %0 must be of an Objective-C metatype type $@objc_metatype T.metatype + %1 = objc_to_thick_metatype %0 : $@objc_metatype T.Type to $@thick T.Type + // %0 must be of an Objective-C metatype type $@objc_metatype T.Type // The destination type must be the corresponding thick metatype type - // %1 will be of type $@thick T.metatype + // %1 will be of type $@thick T.Type Converts an Objective-C class metatype to a thick metatype. ``T`` must be of class, class protocol, or class protocol composition type. @@ -3936,23 +3945,6 @@ will be the operand of this ``return`` instruction. A function must not contain more than one ``return`` instruction. -autorelease_return -`````````````````` -:: - - sil-terminator ::= 'autorelease_return' sil-operand - - autorelease_return %0 : $T - // $T must be the return type of the current function, which must be of - // class type - -Exits the current function and returns control to the calling function. The -result of the ``apply`` instruction that invoked the current function will be -the operand of this ``return`` instruction. The return value is autoreleased -into the active Objective-C autorelease pool using the "autoreleased return -value" optimization. The current function must use the ``@cc(objc_method)`` -calling convention. - throw ````` :: @@ -4041,7 +4033,7 @@ select_value sil-instruction ::= 'select_value' sil-operand sil-select-value-case* (',' 'default' sil-value)? ':' sil-type - sil-selct-value-case ::= 'case' sil-value ':' sil-value + sil-select-value-case ::= 'case' sil-value ':' sil-value %n = select_value %0 : $U, \ @@ -4054,7 +4046,7 @@ select_value // %r1, %r2, %r3, etc. must have type $T // %n has type $T -Selects one of the "case" or "default" operands based on the case of an +Selects one of the "case" or "default" operands based on the case of a value. This is equivalent to a trivial `switch_value`_ branch sequence:: entry: @@ -4082,8 +4074,8 @@ switch_enum (',' sil-switch-default)? sil-switch-enum-case ::= 'case' sil-decl-ref ':' sil-identifier - switch_enum %0 : $U, case #U.Foo: label1, \ - case #U.Bar: label2, \ + switch_enum %0 : $U, case #U.Foo!enumelt: label1, \ + case #U.Bar!enumelt: label2, \ ..., \ default labelN @@ -4117,12 +4109,12 @@ original enum value. For example:: sil @sum_of_foo : $Foo -> Int { entry(%x : $Foo): switch_enum %x : $Foo, \ - case #Foo.Nothing: nothing, \ - case #Foo.OneInt: one_int, \ - case #Foo.TwoInts: two_ints + case #Foo.Nothing!enumelt: nothing, \ + case #Foo.OneInt!enumelt.1: one_int, \ + case #Foo.TwoInts!enumelt.1: two_ints nothing: - %zero = integer_literal 0 : $Int + %zero = integer_literal $Int, 0 return %zero : $Int one_int(%y : $Int): @@ -4158,8 +4150,8 @@ switch_enum_addr (',' sil-switch-enum-case)* (',' sil-switch-default)? - switch_enum_addr %0 : $*U, case #U.Foo: label1, \ - case #U.Bar: label2, \ + switch_enum_addr %0 : $*U, case #U.Foo!enumelt: label1, \ + case #U.Bar!enumelt: label2, \ ..., \ default labelN @@ -4316,7 +4308,7 @@ constant replacement but leave the function application to be serialized to sil). The compiler flag that influences the value of the ``assert_configuration`` -funtion application is the optimization flag: at ``-Onone` the application will +function application is the optimization flag: at ``-Onone` the application will be replaced by ``Debug`` at higher optimization levels the instruction will be replaced by ``Release``. Optionally, the value to use for replacement can be specified with the ``-AssertConf`` flag which overwrites the value selected by diff --git a/docs/SequencesAndCollections.rst b/docs/SequencesAndCollections.rst index f6272314b22e1..3478e89d62dee 100644 --- a/docs/SequencesAndCollections.rst +++ b/docs/SequencesAndCollections.rst @@ -60,8 +60,8 @@ As you can see, sequence does nothing more than deliver a generator. To understand the need for generators, it's important to distinguish the two kinds of sequences. -* **Volatile** sequences like “stream of network packets,” carry - their own traversal state, and are expected to be “consumed” as they +* **Volatile** sequences like "stream of network packets," carry + their own traversal state, and are expected to be "consumed" as they are traversed. * **Stable** sequences, like arrays, should *not* be mutated by `for`\ @@ -215,7 +215,7 @@ that stability in generic code, we'll need another protocol. Collections =========== -A **collection** is a stable sequence with addressable “positions,” +A **collection** is a stable sequence with addressable "positions," represented by an associated `Index` type:: protocol CollectionType : SequenceType { diff --git a/docs/StdlibAPIGuidelines.rst b/docs/StdlibAPIGuidelines.rst index 26004130fac61..230bac5ae3967 100644 --- a/docs/StdlibAPIGuidelines.rst +++ b/docs/StdlibAPIGuidelines.rst @@ -102,7 +102,7 @@ Subsequent Parameters Other Differences ----------------- -* We don't use namespace prefixes such as “`NS`”, relying instead on +* We don't use namespace prefixes such as "`NS`", relying instead on the language's own facilities. * Names of types, protocols and enum cases are `UpperCamelCase`. @@ -156,7 +156,7 @@ library, but are compatible with the Cocoa guidelines. } * Even unlabelled parameter names should be meaningful as they'll be - referred to in comments and visible in “generated headers” + referred to in comments and visible in "generated headers" (cmd-click in Xcode): .. parsed-literal:: @@ -200,12 +200,12 @@ Acceptable Short or Non-Descriptive Names func map(transformation: T->U) -> [U] // not this one - func forEach(body: (S.Generator.Element)->()) + func forEach(body: (S.Generator.Element) -> ()) Prefixes and Suffixes --------------------- -* `Any` is used as a prefix to denote “type erasure,” +* `Any` is used as a prefix to denote "type erasure," e.g. `AnySequence` wraps any sequence with element type `T`, conforms to `SequenceType` itself, and forwards all operations to the wrapped sequence. When handling the wrapper, the specific type of diff --git a/docs/StdlibRationales.rst b/docs/StdlibRationales.rst index 8669653885f91..6b90b80d14935 100644 --- a/docs/StdlibRationales.rst +++ b/docs/StdlibRationales.rst @@ -64,7 +64,7 @@ generally *should* use a keyword. For example, ``String(33, radix: they're converting. Secondly, avoiding method or property syntax provides a distinct context for code completion. Rather than appearing in completions offered after ``.``, for example, the - available conversions could show up whenever the user hit the “tab” + available conversions could show up whenever the user hit the "tab" key after an expression. Protocols with restricted conformance rules @@ -159,7 +159,7 @@ functions don't return lazy collection wrappers that refer to users' closures. The consequence is that all users' closures are ``@noescape``, except in an explicitly lazy context. -Based on this rule, we conclude that ``enumeraate()``, ``zip()`` and +Based on this rule, we conclude that ``enumerate(), ``zip()`` and ``reverse()`` return lazy wrappers, but ``filter()`` and ``map()`` don't. For the first three functions being lazy is the right default, since usually the result is immediately consumed by for-in, so we don't want to allocate memory diff --git a/docs/StringDesign.rst b/docs/StringDesign.rst index 52fcfca9d8b6b..5e56ace9a7390 100644 --- a/docs/StringDesign.rst +++ b/docs/StringDesign.rst @@ -116,9 +116,9 @@ Goals ``String`` should: * honor industry standards such as Unicode -* when handling non-ASCII text, deliver “reasonably correct” +* when handling non-ASCII text, deliver "reasonably correct" results to users thinking only in terms of ASCII -* when handling ASCII text, provide “expected behavior” to users +* when handling ASCII text, provide "expected behavior" to users thinking only in terms of ASCII * be hard to use incorrectly * be easy to use correctly @@ -165,7 +165,7 @@ optimizations, including: - In-place modification of uniquely-owned buffers As a result, copying_ and slicing__ strings, in particular, can be -viewed by most programmers as being “almost free.” +viewed by most programmers as being "almost free." __ sliceable_ @@ -197,7 +197,7 @@ Strings are **Value Types** Distinct string variables have independent values: when you pass someone a string they get a copy of the value, and when someone passes you a string *you own it*. Nobody can change a string value -“behind your back.” +"behind your back." .. parsed-literal:: |swift| class Cave { @@ -231,18 +231,18 @@ Strings are **Unicode-Aware** specifies requires careful justification. So far, we have found two possible points of deviation for Swift ``String``: - 1. The `Unicode Text Segmentation Specification`_ says, “`do not - break between CR and LF`__.” However, breaking extended + 1. The `Unicode Text Segmentation Specification`_ says, "`do not + break between CR and LF`__." However, breaking extended grapheme clusters between CR and LF may necessary if we wish - ``String`` to “behave normally” for users of pure ASCII. This + ``String`` to "behave normally" for users of pure ASCII. This point is still open for discussion. __ http://www.unicode.org/reports/tr29/#GB2 2. The `Unicode Text Segmentation Specification`_ says, - “`do not break between regional indicator symbols`__.” However, it also - says “(Sequences of more than two RI characters should be separated - by other characters, such as U+200B ZWSP).” Although the + "`do not break between regional indicator symbols`__." However, it also + says "(Sequences of more than two RI characters should be separated + by other characters, such as U+200B ZWSP)." Although the parenthesized note probably has less official weight than the other admonition, breaking pairs of RI characters seems like the right thing for us to do given that Cocoa already forms strings with @@ -278,7 +278,7 @@ Strings are **Locale-Agnostic** Strings neither carry their own locale information, nor provide behaviors that depend on a global locale setting. Thus, for any pair -of strings ``s1`` and ``s2``, “``s1 == s2``” yields the same result +of strings ``s1`` and ``s2``, "``s1 == s2``" yields the same result regardless of system state. Strings *do* provide a suitable foundation on which to build locale-aware interfaces.\ [#locales]_ @@ -316,8 +316,8 @@ Strings are Composed of ``Character``\ s cluster**, as specified by a default or tailored Unicode segmentation algorithm. This term is `precisely defined`__ by the Unicode specification, but it roughly means `what the user thinks of when she -hears “character”`__. For example, the pair of code points “LATIN -SMALL LETTER N, COMBINING TILDE” forms a single grapheme cluster, “ñ”. +hears "character"`__. For example, the pair of code points "LATIN +SMALL LETTER N, COMBINING TILDE" forms a single grapheme cluster, "ñ". __ http://www.unicode.org/glossary/#grapheme_cluster __ http://useless-factor.blogspot.com/2007/08/unicode-implementers-guide-part-4.html @@ -342,8 +342,8 @@ __ http://www.unicode.org/glossary/#extended_grapheme_cluster __ http://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table This segmentation offers naïve users of English, Chinese, French, and -probably a few other languages what we think of as the “expected -results.” However, not every script_ can be segmented uniformly for +probably a few other languages what we think of as the "expected +results." However, not every script_ can be segmented uniformly for all purposes. For example, searching and collation require different segmentations in order to handle Indic scripts correctly. To that end, strings support properties for more-specific segmentations: @@ -386,9 +386,9 @@ Strings are **Sliceable** .. parsed-literal:: |swift| s[r.start...r.end] `// r2 : String = "awe"` - |swift| s[\ :look1:`r.start...`\ ]\ :aside:`postfix slice operator means “through the end”` + |swift| s[\ :look1:`r.start...`\ ]\ :aside:`postfix slice operator means "through the end"` `// r3 : String = "awesome"` - |swift| s[\ :look1:`...r.start`\ ]\ :aside:`prefix slice operator means “from the beginning”` + |swift| s[\ :look1:`...r.start`\ ]\ :aside:`prefix slice operator means "from the beginning"` `// r4 : String = "Strings are "` |swift| :look1:`s[r]`\ :aside:`indexing with a range is the same as slicing` `// r5 : String = "awe"` @@ -579,7 +579,7 @@ How Would You Design It? 5. CodePoint substring search is just byte string search 6. Most programs that handle 8-bit files safely can handle UTF-8 safely 7. UTF-8 sequences sort in code point order. - 8. UTF-8 has no “byte order.” + 8. UTF-8 has no "byte order." __ http://research.swtch.com/2010/03/utf-8-bits-bytes-and-benefits.html @@ -682,7 +682,7 @@ withRange:subrange]`` becomes ``str[subrange].doFoo(arg)``. * Deprecated Cocoa APIs are not considered - * A status of “*Remove*” below indicates a feature whose removal is + * A status of "*Remove*" below indicates a feature whose removal is anticipated. Rationale is provided for these cases. Indexing @@ -806,18 +806,18 @@ Comparison func **<=** (lhs: String, rhs: String) -> Bool func **>=** (lhs: String, rhs: String) -> Bool -``NSString`` comparison is “literal” by default. As the documentation +``NSString`` comparison is "literal" by default. As the documentation says of ``isEqualToString``, - “Ö” represented as the composed character sequence “O” and umlaut - would not compare equal to “Ö” represented as one Unicode character. + "Ö" represented as the composed character sequence "O" and umlaut + would not compare equal to "Ö" represented as one Unicode character. By contrast, Swift string's primary comparison interface uses Unicode's default collation_ algorithm, and is thus always -“Unicode-correct.” Unlike comparisons that depend on locale, it is +"Unicode-correct." Unlike comparisons that depend on locale, it is also stable across changes in system state. However, *just like* ``NSString``\ 's ``isEqualToString`` and ``compare`` methods, it -should not be expected to yield ideal (or even “proper”) results in +should not be expected to yield ideal (or even "proper") results in all contexts. --------- @@ -940,7 +940,7 @@ Searching :Swift: .. parsed-literal:: - func **find**\ (match: (Character)->Bool) -> Range + func **find**\ (match: (Character) -> Bool) -> Range .. Admonition:: Usage Example @@ -1084,10 +1084,10 @@ Capitalization .. Note:: ``NSString`` capitalizes the first letter of each substring separated by spaces, tabs, or line terminators, which is in - no sense “Unicode-correct.” In most other languages that + no sense "Unicode-correct." In most other languages that support a ``capitalize`` method, it operates only on the first character of the string, and capitalization-by-word is - named something like “``title``.” If Swift ``String`` + named something like "``title``." If Swift ``String`` supports capitalization by word, it should be Unicode-correct, but how we sort this particular area out is still **TBD**. @@ -1100,7 +1100,7 @@ Capitalization :Swift: .. parsed-literal:: - trim **trim**\ (match: (Character)->Bool) -> String + trim **trim**\ (match: (Character) -> Bool) -> String .. Admonition:: Usage Example @@ -1712,7 +1712,7 @@ Why YAGNI * Derivation * ... -.. [#agnostic] Unicode specifies default (“un-tailored”) +.. [#agnostic] Unicode specifies default ("un-tailored") locale-independent collation_ and segmentation_ algorithms that make reasonable sense in most contexts. Using these algorithms allows strings to be naturally compared and combined, generating @@ -1748,6 +1748,6 @@ Why YAGNI been normalized, thus speeding up comparison operations. .. [#elements] Since ``String`` is locale-agnostic_, its elements are - determined using Unicode's default, “un-tailored” segmentation_ + determined using Unicode's default, "un-tailored" segmentation_ algorithm. diff --git a/docs/Testing.rst b/docs/Testing.rst index be91cbd822dc2..8e5c39f8de1ed 100644 --- a/docs/Testing.rst +++ b/docs/Testing.rst @@ -200,7 +200,7 @@ code for the target that is not the build machine: * ``%target-jit-run``: run a Swift program on the target machine using a JIT compiler. -* ``%target-swiftc_driver``: FIXME +* ``%target-swiftc_driver``: run ``swiftc`` for the target. * ``%target-sil-opt``: run ``sil-opt`` for the target. @@ -212,15 +212,13 @@ code for the target that is not the build machine: arguments*: like ``%target-swift-ide-test``, but allows to specify command line parameters to use a mock SDK. -* ``%target-swiftc_driver``: FIXME. - * ``%target-swift-autolink-extract``: run ``swift-autolink-extract`` for the target to extract its autolink flags on platforms that support them (when the autolink-extract feature flag is set) * ``%target-clang``: run the system's ``clang++`` for the target. - If you want to run the ``clang`` executable that was built alongside + If you want to run the ``clang`` executable that was built alongside Swift, use ``%clang`` instead. * ``%target-ld``: run ``ld`` configured with flags pointing to the standard @@ -229,6 +227,30 @@ code for the target that is not the build machine: * ``%target-cc-options``: the clang flags to setup the target with the right architecture and platform version. +* ``%target-triple``: a triple composed of the ``%target-cpu``, the vendor, + the ``%target-os``, and the operating system version number. Possible values + include ``i386-apple-ios7.0`` or ``armv7k-apple-watchos2.0``. + +* ``%target-cpu``: the target CPU instruction set (``i386``, ``x86_64``, + ``armv7``, ``armv7k``, ``arm64``). + +* ``%target-os``: the target operating system (``macosx``, ``darwin``, + ``linux``, ``freebsd``). + +* ``%target-object-format``: the platform's object format (``elf``, ``macho``, + ``coff``). + +* ``%target-runtime``: the platform's Swift runtime (objc, native). + +* ``%target-ptrsize``: the pointer size of the target (32, 64). + +* ``%target-swiftmodule-name`` and ``%target-swiftdoc-name``: the basename of + swiftmodule and swiftdoc files for a framework compiled for the target (for + example, ``arm64.swiftmodule`` and ``arm64.swiftdoc``). + +* ``%target-sdk-name``: only for Apple platforms: ``xcrun``-style SDK name + (``macosx``, ``iphoneos``, ``iphonesimulator``). + Always use ``%target-*`` substitutions unless you have a good reason. For example, an exception would be a test that checks how the compiler handles mixing module files for incompatible platforms (that test would need to compile @@ -236,33 +258,53 @@ Swift code for two different platforms that are known to be incompatible). When you can't use ``%target-*`` substitutions, you can use: -* ``%swift_driver_plain``: FIXME. -* ``%swiftc_driver_plain``: FIXME. -* ``%swift_driver``: FIXME. -* ``%swiftc_driver``: FIXME. -* ``%sil-opt``: FIXME. -* ``%sil-extract``: FIXME. -* ``%lldb-moduleimport-test``: FIXME. -* ``%swift-ide-test_plain``: FIXME. -* ``%swift-ide-test``: FIXME. -* ``%llvm-opt``: FIXME. -* ``%swift``: FIXME. -* ``%clang-include-dir``: FIXME. -* ``%clang-importer-sdk``: FIXME. +* ``%swift_driver_plain``: run ``swift`` for the build machine. + +* ``%swift_driver``: like ``%swift_driver_plain`` with ``-module-cache-path`` + set to a temporary directory used by the test suite, and using the + ``SWIFT_TEST_OPTIONS`` environment variable if available. + +* ``%swiftc_driver``: like ``%target-swiftc_driver`` for the build machine. + +* ``%swiftc_driver_plain``: like ``%swiftc_driver``, but does not set the + ``-module-cache-path`` to a temporary directory used by the test suite, + and does not respect the ``SWIFT_TEST_OPTIONS`` environment variable. + +* ``%sil-opt``: like ``%target-sil-opt`` for the build machine. + +* ``%sil-extract``: run ``%target-sil-extract`` for the build machine. + +* ``%lldb-moduleimport-test``: run ``lldb-moduleimport-test`` for the build + machine in order simulate importing LLDB importing modules from the + ``__apple_ast`` section in Mach-O files. See + ``tools/lldb-moduleimport-test/`` for details. + +* ``%swift-ide-test``: like ``%target-swift-ide-test`` for the build machine. + +* ``%swift-ide-test_plain``: like ``%swift-ide-test``, but does not set the + ``-module-cache-path`` or ``-completion-cache-path`` to temporary directories + used by the test suite. + +* ``%swift``: like ``%target-swift-frontend`` for the build machine. + +* ``%clang``: run the locally-built ``clang``. To run ``clang++`` for the + target, use ``%target-clang``. Other substitutions: -* ``%leaks-runner``: FIXME. -* ``%clang_apinotes``: FIXME. -* ``%clang``: FIXME. -* ``%target-triple``: FIXME, possible values. -* ``%target-cpu``: FIXME, possible values. -* ``%target-os``: FIXME, possible values. -* ``%target-object-format``: the platform's object format (elf, macho, coff). -* ``%target-runtime``: the platform's Swift runtime (objc, native). -* ``%target-ptrsize``: the pointer size of the target (32, 64). -* ``%sdk``: FIXME. -* ``%gyb``: FIXME. +* ``%clang-include-dir``: absolute path of the directory where the Clang + include headers are stored on Linux build machines. + +* ``%clang-importer-sdk``: FIXME. + +* ``%clang_apinotes``: run ``clang -cc1apinotes`` using the locally-built + clang. + +* ``%sdk``: only for Apple platforms: the ``SWIFT_HOST_VARIANT_SDK`` specified + by tools/build-script. Possible values include ``IOS`` or ``TVOS_SIMULATOR``. + +* ``%gyb``: run ``gyb``, a boilerplate generation script. For details see + ``utils/gyb``. * ``%platform-module-dir``: absolute path of the directory where the standard library module file for the target platform is stored. For example, @@ -271,12 +313,8 @@ Other substitutions: * ``%platform-sdk-overlay-dir``: absolute path of the directory where the SDK overlay module files for the target platform are stored. -* ``%target-swiftmodule-name`` and ``%target-swiftdoc-name``: the basename of - swiftmodule and swiftdoc files for a framework compiled for the target (for - example, ``arm64.swiftmodule`` and ``arm64.swiftdoc``). - -* ``%target-sdk-name``: only for Apple platforms: ``xcrun``-style SDK name - (``macosx``, ``iphoneos``, ``iphonesimulator``). +* ``%{python}``: run the same Python interpreter that's being used to run the + current ``lit`` test. When writing a test where output (or IR, SIL) depends on the bitness of the target CPU, use this pattern:: @@ -319,7 +357,7 @@ CPU=i386_or_x86_64`` to ``REQUIRES: CPU=x86_64``. ``swift_test_mode_optimize[_unchecked|none]_`` to specify a test mode plus cpu configuration. -``optimized_stdlib_``` to specify a optimized stdlib plus cpu +``optimized_stdlib_``` to specify an optimized stdlib plus cpu configuration. Feature ``REQUIRES: executable_test`` diff --git a/docs/TextFormatting.rst b/docs/TextFormatting.rst index c57f721746286..30e47ef83eb5a 100644 --- a/docs/TextFormatting.rst +++ b/docs/TextFormatting.rst @@ -21,9 +21,9 @@ Scope Goals ..... -* The REPL and LLDB (“debuggers”) share formatting logic -* All types are “debug-printable” automatically -* Making a type “printable for humans” is super-easy +* The REPL and LLDB ("debuggers") share formatting logic +* All types are "debug-printable" automatically +* Making a type "printable for humans" is super-easy * ``toString()``-ability is a consequence of printability. * Customizing a type's printed representations is super-easy * Format variations such as numeric radix are explicit and readable @@ -43,11 +43,11 @@ Non-Goals that feature. Therefore, localization and dynamic format strings should be designed together, and *under this proposal* the only format strings are string literals containing interpolations - (“``\(...)``”). Cocoa programmers can still use Cocoa localization + ("``\(...)``"). Cocoa programmers can still use Cocoa localization APIs for localization jobs. In Swift, only the most common cases need to be very terse. - Anything “fancy” can afford to be a bit more verbose. If and when + Anything "fancy" can afford to be a bit more verbose. If and when we address localization and design a full-featured dynamic string formatter, it may make sense to incorporate features of ``printf`` into the design. @@ -68,7 +68,7 @@ printed with ``print(x)``, and can be converted to ``String`` with The simple extension story for beginners is as follows: - “To make your type ``CustomStringConvertible``, simply declare conformance to + "To make your type ``CustomStringConvertible``, simply declare conformance to ``CustomStringConvertible``:: extension Person : CustomStringConvertible {} @@ -129,8 +129,7 @@ Debug Printing Via compiler magic, *everything* conforms to the ``CustomDebugStringConvertible`` protocol. To change the debug representation for a type, you don't -need to declare conformance: simply give the type a ``debugFormat()`` -:: +need to declare conformance: simply give the type a ``debugFormat()``:: /// \brief A thing that can be printed in the REPL and the Debugger protocol CustomDebugStringConvertible { @@ -153,9 +152,9 @@ directly to the ``OutputStream`` for efficiency reasons, Producing a representation that can be consumed by the REPL and LLDB to produce an equivalent object is strongly encouraged where possible! For example, ``String.debugFormat()`` produces - a representation starting and ending with “``"``”, where special + a representation starting and ending with "``"``", where special characters are escaped, etc. A ``struct Point { var x, y: Int }`` - might be represented as “``Point(x: 3, y: 5)``”. + might be represented as "``Point(x: 3, y: 5)``". (Non-Debug) Printing .................... @@ -199,7 +198,7 @@ Because it's not always efficient to construct a ``String`` representation before writing an object to a stream, we provide a ``Streamable`` protocol, for types that can write themselves into an ``OutputStream``. Every ``Streamable`` is also a ``CustomStringConvertible``, -naturally :: +naturally:: protocol Streamable : CustomStringConvertible { func writeTo(target: [inout] T) @@ -349,7 +348,7 @@ an underlying stream:: However, upcasing is a trivial example: many such transformations—such as ``trim()`` or regex replacement—are stateful, which implies some -way of indicating “end of input” so that buffered state can be +way of indicating "end of input" so that buffered state can be processed and written to the underlying stream: .. parsed-literal:: @@ -423,10 +422,10 @@ If we were willing to say that only ``class``\ es can conform to ``OutputStream``\ s are passed around. Then, we'd simply need a ``class StringStream`` for creating ``String`` representations. It would also make ``OutputStream`` adapters a *bit* simpler to use -because you'd never need to “write back” explicitly onto the target +because you'd never need to "write back" explicitly onto the target stream. However, stateful ``OutputStream`` adapters would still need a ``close()`` method, which makes a perfect place to return a copy of -the underlying stream, which can then be “written back.” : +the underlying stream, which can then be "written back": .. parsed-literal:: diff --git a/docs/TypeChecker.rst b/docs/TypeChecker.rst index 73c54c4c39354..fb1856eb30645 100644 --- a/docs/TypeChecker.rst +++ b/docs/TypeChecker.rst @@ -126,12 +126,12 @@ the Swift type system: to the second, which includes subtyping and equality. Additionally, it allows a user-defined conversion function to be called. Conversion constraints are written ``X { @@ -376,10 +376,10 @@ has a regular structure. For example, consider the ``Optional`` type:: case Some(T) } -The type of ``Optional.Vone`` is ``Optional``, while the type of +The type of ``Optional.None`` is ``Optional``, while the type of ``Optional.Some`` is ``(T) -> Optional``. In fact, the -type of a enum element can have one of two forms: it can be ``T0``, -for a enum element that has no extra data, or it can be ``T2 -> T0``, +type of an enum element can have one of two forms: it can be ``T0``, +for an enum element that has no extra data, or it can be ``T2 -> T0``, where ``T2`` is the data associated with the enum element. For the latter case, the actual arguments are parsed as part of the unresolved member reference, so that a function application constraint describes @@ -403,8 +403,8 @@ concrete type, so long as that type conforms to the protocol ``Comparable``. The type of ``min`` is (internally) written as `` (x: T, y: T) -> T``, which can be read as "for all ``T``, where ``T`` conforms to ``Comparable``, the type of the function is -``(x: T, y: T) -> T``. Different uses of the ``min`` function may -have different bindings for the generic parameter``T``. +``(x: T, y: T) -> T``." Different uses of the ``min`` function may +have different bindings for the generic parameter ``T``. When the constraint generator encounters a reference to a generic function, it immediately replaces each of the generic parameters within @@ -433,8 +433,8 @@ solver. For example, consider the following generic dictionary type:: // ... } -When the constraint solver encounters the expression `` -Dictionary()``, it opens up the type ``Dictionary``---which has not +When the constraint solver encounters the expression ``Dictionary()``, +it opens up the type ``Dictionary``---which has not been provided with any specific generic arguments---to the type ``Dictionary``, for fresh type variables ``T0`` and ``T1``, and introduces the constraint ``T0 conforms to Hashable``. This allows @@ -530,7 +530,7 @@ constraint ``A.member == B`` can be simplified when the type of ``A`` is determined to be a nominal or tuple type, in which case name lookup can resolve the member name to an actual declaration. That declaration has some type ``C``, so the member constraint is simplified to the -exact equality constraint``B := C``. +exact equality constraint ``B := C``. The member name may refer to a set of overloaded declarations. In this case, the type ``C`` is a fresh type variable (call it ``T0``). A @@ -736,12 +736,12 @@ checking problem:: f(10.5, x) This constraint system generates the constraints "``T(f)`` ==Fn ``T0 --> T1``" (for fresh variables ``T0`` and ``T1``), "``(T2, X)`` T1``" (for fresh variables ``T0`` and ``T1``), "``(T2, X) T1``" constraint has a locator that is anchored at the function application and a path with the "apply function" derivation step, meaning that this is the function being -applied. Similarly, the "``(T2, X)`` Infix Attributes

FIXME: Implement these restrictions.

-

Resilience Attribute

+

Resilience Attribute

     attribute-resilience ::= 'resilient'
@@ -786,7 +786,7 @@ 

inout Attribute

inout indicates that the argument will be passed as an "in-out" - parameter. The caller must pass an lvalue decorated with the & + parameter. The caller must pass an lvalue decorated with the & prefix operator as the argument. Semantically, the value of the argument is passed "in" to the callee to a local value, and that local value is stored back "out" to the lvalue when the callee exits. This is normally @@ -837,7 +837,7 @@

inout Attribute

FIXME: we probably need a const-like variant, which permits r-values (and avoids writeback when the l-value is not physical). @@ -1195,7 +1195,7 @@

Array Types

Array types include a base type and an optional size. Array types indicate - a linear sequence of elements stored consequtively memory. Array elements may + a linear sequence of elements stored consecutively memory. Array elements may be efficiently indexed in constant time. All array indexes are bounds checked and out of bound accesses are diagnosed with either a compile time or runtime failure (TODO: runtime failure mode not specified).

@@ -1295,10 +1295,13 @@

Optional Types

T?. To support these intrinsic use cases, the library is required to - provide four functions with these exact signatures: + provide functions with these exact signatures:
    -
  • func _preconditionOptionalHasValue(inout v : T?) +
  • func _doesOptionalHaveValueAsBool(v : T?) -> Bool
  • +
  • func _diagnoseUnexpectedNilOptional()
  • func _getOptionalValue(v : T?) -> T
  • +
  • func _injectValueIntoOptional(v : T) -> T?
  • +
  • func _injectNothingIntoOptional() -> T?

@@ -1317,7 +1320,7 @@

Optional Types

var b : Int? = .None // Declare an array of optionals: - var c : Int?[] = new Int?[4] + var c : [Int?] = [10, nil, 42] @@ -1898,7 +1901,7 @@

Closure Expression

// both have type 'Int'. magic(42, { $0 < $1 }) - // Compare the other way way. + // Compare the other way. magic(42, { $1 < $0 }) // Provide parameter names, but infer the types. @@ -2388,7 +2391,7 @@

'while' Statement

'while' statements provide simple loop construct which (on each iteration - of the loop) evalutes the condition, gets the 'boolValue' property of + of the loop) evaluates the condition, gets the 'boolValue' property of the result if the result not a 'Bool', then determines whether to keep looping. (Internally, the standard library type 'Bool' has a boolValue property that yields a 'Builtin.Int1'.) It is an error if the type of @@ -2449,7 +2452,7 @@

C-Style 'for' Statement

C-Style 'for' statements provide simple loop construct which evaluates the - first part (the initializer) before entering the loop, then evalutes the + first part (the initializer) before entering the loop, then evaluates the second condition as a logic value to determines whether to keep looping. The third condition is executed at the end of the loop. All three are evaluated in a new scope that surrounds the for statement. diff --git a/docs/archive/LangRefNew.rst b/docs/archive/LangRefNew.rst index 21fb5523d82c6..e1bccc4973106 100644 --- a/docs/archive/LangRefNew.rst +++ b/docs/archive/LangRefNew.rst @@ -40,7 +40,7 @@ Basic Goals In no particular order, and not explained well: * Support building great frameworks and applications, with a specific focus on - permiting rich and powerful APIs. + permitting rich and powerful APIs. * Get the defaults right: this reduces the barrier to entry and increases the odds that the right thing happens. * Through our support for building great APIs, we aim to provide an expressive @@ -54,7 +54,7 @@ In no particular order, and not explained well: ideas already out there. * Memory safe by default: array overrun errors, uninitialized values, and other problems endemic to C should not occur in Swift, even if it means some amount - of runtime overhead. Eventually these checks will be disablable for people + of runtime overhead. Eventually these checks will be disableable for people who want ultimate performance in production builds. * Efficiently implementable with a static compiler: runtime compilation is great technology and Swift may eventually get a runtime optimizer, but it is @@ -752,7 +752,7 @@ protocols. } We disambiguate towards ``get-set`` or ``willset-didset`` production if the - first token after ``{`` is the corresponding keyword, possibly preceeded by + first token after ``{`` is the corresponding keyword, possibly preceded by attributes. Thus, the following code is rejected because we are expecting ``{`` after ``set``: @@ -782,7 +782,7 @@ protocols. } We disambiguate towards ``willget-didset`` production if the first token - after ``{`` is the keyword ``willSet`` or ``didSet``, possibly preceeded by + after ``{`` is the keyword ``willSet`` or ``didSet``, possibly preceded by attributes. .. admonition:: Rationale @@ -1424,7 +1424,7 @@ into every file. Its declarations can only be found by dot syntax. It provides access to a small number of primitive representation types and operations defined over them that map directly to LLVM IR. -The existance of and details of this module are a private implementation detail +The existence of and details of this module are a private implementation detail used by our implementation of the standard library. Swift code outside the standard library should not be aware of this library, and an independent implementation of the swift standard library should be allowed to be @@ -1537,8 +1537,8 @@ Short Circuiting Logical Operators :: - func && (lhs: Bool, rhs: ()->Bool) -> Bool - func || (lhs: Bool, rhs: ()->Bool) -> Bool + func && (lhs: Bool, rhs: () -> Bool) -> Bool + func || (lhs: Bool, rhs: () -> Bool) -> Bool Swift has a simplified precedence levels when compared with C. From highest to lowest: @@ -1551,5 +1551,3 @@ lowest: "comparative:" ==, !=, <, <=, >=, > "conjunctive:" && "disjunctive:" || - - diff --git a/docs/archive/Namespace Level Vars and Top Level Code.rst b/docs/archive/Namespace Level Vars and Top Level Code.rst index ba140a8286acd..2ac134fdd0eae 100644 --- a/docs/archive/Namespace Level Vars and Top Level Code.rst +++ b/docs/archive/Namespace Level Vars and Top Level Code.rst @@ -68,10 +68,10 @@ does top level code and multiple actors. As such, the logical semantics are: lazily. 3. Source files that have TLC are each initialized in a deterministic order: The dependence graph of domains is respected (lower level domains are initialized - before dependent ones), and the source files withing a domain are initialized + before dependent ones), and the source files within a domain are initialized in some deterministic order (perhaps according to their filename or something, TBD). -4. Within a source file with TLC, the TLC is run top down in determinstic order +4. Within a source file with TLC, the TLC is run top down in deterministic order whenever the file's initializer is run. This initializer executes in the context of the "first" actor, which is created on behalf of the program by the runtime library. diff --git a/docs/archive/Objective-C Interoperability.rst b/docs/archive/Objective-C Interoperability.rst index c8921e0107a43..70efb8bbbfc83 100644 --- a/docs/archive/Objective-C Interoperability.rst +++ b/docs/archive/Objective-C Interoperability.rst @@ -216,7 +216,7 @@ Non-NSObjects are messageable but not ``id``-compatible: - Cannot assign Swift objects to ``id`` variables. - Cannot put arbitrary Swift objects in NSArrays. - Potentially confusing: "I can message it but I can't put it in an ``id``??" -- Clang must be taught how to message Swift objects and manage their retain +- Clang must be taught how to message Swift objects and manage their retain counts. - On the plus side, then non-NSObjects can use Swift calling conventions. - Requires framework authors to make an arbitrary decision that may not be @@ -315,18 +315,18 @@ Method Overriding Model *Requirement: Swift classes can override any Objective-C methods.* -Methods marked as "overrideable API" only have Objective-C entry points: +Methods marked as "overridable API" only have Objective-C entry points: - Less to think about, maximum compatibility. - Penalizes future Swift clients (and potentially Objective-C clients?). -Methods marked as "overrideable API" have both Objective-C and Swift entry +Methods marked as "overridable API" have both Objective-C and Swift entry points: - Requires teaching Clang to emit Swift vtables. - Increases binary size and link time. -Methods marked as "overrideable API" have only Swift entry points: +Methods marked as "overridable API" have only Swift entry points: - Requires teaching Clang to emit Swift vtables. - Later exposing this method to Objective-C in a subclass may be awkward? diff --git a/docs/conf.py b/docs/conf.py index 968e48416374a..142245c748835 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -10,7 +10,7 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -250,7 +250,7 @@ #texinfo_show_urls = 'footnote' -# FIXME: Define intersphinx configration. +# FIXME: Define intersphinx configuration. intersphinx_mapping = {} diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in index 5468e2386843e..6b56723b5d5f1 100644 --- a/docs/doxygen.cfg.in +++ b/docs/doxygen.cfg.in @@ -1,9 +1,9 @@ # Doxyfile 1.4.4 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: @@ -385,7 +385,7 @@ SHOW_DIRECTORIES = YES # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the progam writes to standard output +# provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. #FILE_VERSION_FILTER = @@ -418,7 +418,7 @@ WARN_IF_UNDOCUMENTED = NO WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for +# This WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of @@ -1063,7 +1063,7 @@ PERL_PATH = #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# generate an inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more @@ -1239,7 +1239,7 @@ SEARCHENGINE = @enable_searchengine@ # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows -# full text search. The disadvances is that it is more difficult to setup +# full text search. The disadvantage is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = @enable_server_based_search@ diff --git a/docs/doxygen.css b/docs/doxygen.css index 83951f673db8d..d5691ed7e62d1 100644 --- a/docs/doxygen.css +++ b/docs/doxygen.css @@ -313,8 +313,8 @@ HR { height: 1px; /* * LLVM Modifications. - * Note: Everything above here is generated with "doxygen -w htlm" command. See - * "doxygen --help" for details. What follows are CSS overrides for LLVM + * Note: Everything above here is generated with "doxygen -w html" command. See + * "doxygen --help" for details. What follows are CSS overrides for LLVM * specific formatting. We want to keep the above so it can be replaced with * subsequent doxygen upgrades. */ diff --git a/docs/proposals/Accessors.rst b/docs/proposals/Accessors.rst index 2af6d07517a36..da5da10f0426b 100644 --- a/docs/proposals/Accessors.rst +++ b/docs/proposals/Accessors.rst @@ -87,7 +87,7 @@ objects:: point = point1 point0.x = x point = point0 - + Note that ``point.y`` is left unchanged. Local analysis @@ -157,7 +157,7 @@ through unexpected aliases:: Note that, in either solution, you've introduced extra full-value loads. This may be quite expensive, and it's not guaranteed to be semantically equivalent. - + Performance ~~~~~~~~~~~ @@ -453,7 +453,7 @@ Nor can this be fixed with a purely local analysis; consider:: class C { var array: [Int] } let global_C = C() - + func assign(inout value: Int) { C.array = [] value = 0 @@ -606,7 +606,7 @@ General solutions ~~~~~~~~~~~~~~~~~ A language generally has six tools for dealing with code it considers -undesireable. Some of this terminology is taken from existing +undesirable. Some of this terminology is taken from existing standards, others not. * The language may nonetheless take steps to ensure that the code @@ -704,7 +704,7 @@ that was technically copied beforehand. For example:: var oldArray : [Int] = [] // This function copies array before modifying it, but because that - // copy is of an value undergoing modification, the copy will use + // copy is of a value undergoing modification, the copy will use // the same buffer and therefore observe updates to the element. func foo(inout element: Int) { oldArray = array @@ -856,7 +856,7 @@ depend on how the l-value is used: that ``left`` contains a value:: // begin FA for ? operand left (DSN={}) - // instataneous FA reading right (DSN={}) + // instantaneous FA reading right (DSN={}) // begin FA for inout argument left?.member (DSN={lhs}) // evaluation of += // end FA for inout argument left?.member @@ -916,7 +916,7 @@ I'm almost ready to state the core rule about formal accesses, but first I need to build up a few more definitions. An *abstract storage location* (ASL) is: - + * a global variable declaration; * an ``inout`` parameter declaration, along with a reference @@ -1027,7 +1027,7 @@ summary of the rule being proposed. If storage is passed to an ``inout`` argument, then any other simultaneous attempt to read or write to that storage, including to -the storage containing it, will have have unspecified behavior. Reads +the storage containing it, will have unspecified behavior. Reads from it may see partially-updated values, or even values which will change as modifications are made to the original storage; and writes may be clobbered or simply disappear. @@ -1106,7 +1106,7 @@ the other FA's DSN set and (2) not from a non-overlapping subobject. Are these conditions true? Recall that an addressor is invoked for an l-value of the form:: - + base.memory or:: @@ -1296,7 +1296,7 @@ Code generation patterns The signatures and access patterns for addressors will need to change in order to ensure memory-safety. -``mutableAddress`` currentlys returns an ``UnsafeMutablePointer``; it +``mutableAddress`` currently returns an ``UnsafeMutablePointer``; it will need to return ``(Builtin.NativeObject?, UnsafeMutablePointer)``. The owner pointer must be a native object; we cannot efficiently support either uniqueness checking or the NSM bit on non-Swift diff --git a/docs/proposals/ArrayBridge.rst b/docs/proposals/ArrayBridge.rst index 163fb487874f7..8cd5bb1087bdd 100644 --- a/docs/proposals/ArrayBridge.rst +++ b/docs/proposals/ArrayBridge.rst @@ -4,7 +4,7 @@ .. .. This source file is part of the Swift.org open source project .. -.. Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +.. Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors .. Licensed under Apache License v2.0 with Runtime Library Exception .. .. See http://swift.org/LICENSE.txt for license information @@ -71,7 +71,7 @@ significant. For example, the design above would pose significant performance problems for arrays of integers, because every subscript operation would have to check to see if the representation is an NSArray, realize it is not, then do the constant time index into the native representation. Beyond requiring an extra -check, this check would disable optimizations that can provide a signficant +check, this check would disable optimizations that can provide a significant performance win (like auto-vectorization). However, the inherent limitations of ``NSArray`` mean that we can diff --git a/docs/proposals/AttrC.rst b/docs/proposals/AttrC.rst index 2c4d2cf193b88..aaaa6069be50e 100644 --- a/docs/proposals/AttrC.rst +++ b/docs/proposals/AttrC.rst @@ -4,7 +4,7 @@ Eventually, we would like to write Swift modules which define pure-C entry points for top-level functions, and be able to export more data types to C code. -This will be imporant for the Linux port, but also perhaps for system +This will be important for the Linux port, but also perhaps for system frameworks that want to transition to Swift. The radars tracking this work are: @@ -59,14 +59,14 @@ and "non-POD". POD types include: On Linux, we can't have reference counted pointers here at all, and NSArray, etc do not exist, so only POD types are bridgeable. We must -ensure that we produce ther right diagnostic and not crash when the +ensure that we produce the right diagnostic and not crash when the user references NSArray, etc on Linux. On Darwin, we can allow passing reference counted pointers directly as function parameters. They are still not allowed as fields in ``@c`` structs, though. -The convention for arguments and results an be the same as CoreFoundation +The convention for arguments and results can be the same as CoreFoundation functions imported from C. The code in ``CFunctionConventions`` in SILFunctionType.cpp looks relevant. diff --git a/docs/proposals/CompressedMangledNames.md b/docs/proposals/CompressedMangledNames.md new file mode 100644 index 0000000000000..bc581474f99f2 --- /dev/null +++ b/docs/proposals/CompressedMangledNames.md @@ -0,0 +1,238 @@ + +Motivation +---------- + +We care deeply about the size of binaries that are generated by the Swift +compiler and make an effort to optimize and shrink the generated binaries. One +of the problems that we have today is that swift symbols are mangled into +extremely long strings. This is especially a problem for libraries, and almost +half of the size of libswiftCore.dylib (the swift runtime library on x86_64 OSX) +is string tables. On MacOSX you can use the command ’size -m file.dylib’ to read +the size of the string table. C++ also suffers from the problem of long names, +but since we control the Swift ABI we can do better than C++. + +Here are two names from the Swift libraries: + + __TIF14StdlibUnittest13checkSequenceu0_Rxs14CollectionType_s12SequenceTypeWx9Generator7Element_zW_9GeneratorS3__rFTxq_KT_SS9showFrameSb10stackTraceVS_14SourceLocStack4fileSS4lineSu16resiliencyChecksVS_32CollectionMisuseResiliencyChecks9sameValueFTWxS2_S3__WxS2_S3___Sb_T_A6_ + + __TTSg5VSS13CharacterViewS_s14CollectionTypes_GVs17IndexingGeneratorS__GS1_S__s13GeneratorTypes_VS_5IndexS3_s16ForwardIndexTypes_SiSis18_SignedIntegerTypes_SiSis33_BuiltinIntegerLiteralConvertibles_Vs20_DisabledRangeIndex__S_S_s9IndexablesS_s12SequenceTypes_GS1_S__GS1_S__S2_s_Vs9Character_S3_S3_S4_s_SiSiS5_s_SiSiS6_s_S7__S__S10__S10____TFFSS12replaceRangeuRxs14CollectionTypeWx9Generator7Element_zVs9CharacterrFTGVs5RangeVVSS13CharacterView5Index_4withx_T_U_FRS4_T_ + +Swift is a systems programming language, and we need to prepare to a future +where the whole operating system is developed in Swift. This means that one day +our phones will have hundreds of shared libraries (written in swift) loaded at +the same time. Thousands of shared libraries will be saved on disk, and updated +every time you upgrade the OS and apps. The string table (linkedit section in +Mach-O) is loaded into memory (as shared copy-on-write). In a world where every +single process uses multiple swift libraries reducing the size of this section +is very beneficial for memory usage, load time, disk usage, etc.. + +On-disk and over-the-air compression can improve things, but these techniques +are insufficient because generic compression is not as effective as domain +specific compression, and they do not address the problem of in-memory tables. + + +Character Set +------------- +The decision on a character set to be used by the compression scheme is +independent of the algorithms that are used for compression. The more characters +that we can use the more efficient the encoding would be. The Base64 encoding +scheme uses 64 characters and has a 75% efficiency compared to unrestricted +8-bit ascii. Base64 uses 6 bits to encode 8 bits of ascii. + +The current implementation uses the character set A-Z, a-z, 0-9 and "_", which +are the legal identifier characters in C. We need to use only printable +characters if we want tools such as nm to be able to work well. It is possible +to extend the character set to more printable characters but this will make SIL +(that uses these names freely) less usable. For example, names should probable +not contain the character , but is probably okay. + +Symbol Compression +------------------ + +This section describes the Swift symbol compression. In Swift we compress each +symbol individually as part of the mangling phase. The compression phase has two +steps: + +1. Dictionary based compression (similar to Lempel-Ziv) +2. Variable length compression (Huffman Coding) + +The swift Mangler and Demangler are responsible for compressing and +decompressing the symbols, and this process is transparent to the debugger. The +nm command line tool prints the compressed name, and swift-demangle is +responsible for decompressing and demangling the name properly. + +Together, the Dictionary based compression and the Variable length compression +are able to compress the size of the string section down to 50% (half of the +original size). + +Dictionary-based compression +---------------------------- + +This section describes the dictionary based compression. This compression phase +reduces the string table section by about 40%. Unlike Lempel-Ziv, the +dictionary-based compression algorithm that we use here can't make use of string +repetitions to compress the string because the input strings are too short. The +obvious alternative is to use "prior knowledge". We know what are the common +sub-strings that are used in Swift names. Some of the most common substrings in +Swift mangled names are: + + "S_S_S_S", "ollectio", "Type", "Index", "erator", "7Element", and "able". + +We can use this prior knowledge to compress our mangling! + +In our compression scheme we compress this string: + +__TTSg5VSS13CharacterView + +Into a string that contains references to some global table that is available to the compressor and decompressor. + +__TTSg513View + +Commonly used strings are encoded as references to global tables. The reference +needs to be encoded as part of the name. We need to have some escape character +and use that character to encode the reference. In our encoding scheme we have two +escape characters. + +The first escape character records an index using a single character. This allows us to encode +the top 63 frequent substrings in our dictionary using two characters (escape + index). + +The second escape character encodes a two-character reference that can access 63 x 63 entries in the table. +Less common substrings can be encoded using this three character sequence (escape + index0 + index1). + +One interesting bit of information is that the character ‘Y’ is only used 4 +times in the entire standard library! The letter J, and a few other letters are +also not used very frequently. We use Y and J as escape characters. + +The dictionary-based encoding uses the following rules: + +1. We use two escape characters that are not frequently used in names (Y and Z). +These characters are escape character and cannot be used as part of the text +without escaping. ‘Y’ is encoded as ‘YY’, and ‘Z’ would be encoded as ‘YZ’. + +2. The most commonly used sub-strings (calculated as length of substring times +number of occurrences) is encoded with a single escape character and a +single index character. The table of highly repetitive substrings can only +contain 61 entries (a-zA-Z0-9_, minus two escape characters). + +A reference to the very frequent substrings is encoded as "Yx", where x is the +character that is translated into a numeric index. This is two chars per +substring. + +3. The less frequently used substrings are encoded as three-character sequence. +"Zxx", where xx is the numeric index in the large table (that can hold 61*61 +substrings). + +It is obvious how to reverse this compression using the same string table used +to compress the names. + +With this encoding scheme the name +"__TwxxV14StdlibUnittest24MinimalForwardCollection" becomes +"__TwxxJ1QYrt24J6wJ5KY9on" and the name "__TMPVs15ContiguousArray" becomes +"__TMPJOSJ6lJ8G". + +Notice that the "_T" prefix is kept and should not be compressed because it +differentiates between swift symbols and non-swift symbols. + +These are two related works on dictionary-based compression: + +"Text compression using a 4 bit coding scheme" by J Pike. +"A universal algorithm for sequential data compression (1977)" by Jacob Ziv , Abraham Lempel + +Variable Length encoding +------------------------ + +The variable length encoding that we use is pretty standard. We use Huffman +encoding to encode frequently used characters with few bits. One interesting +aspect of the problem is that we use a character set that is not a power of two. +To encode a bit stream in a character set that is now a power of two we need to +represent the whole name as a big number and perform the operation of div-modulo +for each character we encode, where the div-modulo value is the number of +characters we use to encode the string. + +Strings are encoded into numbers in reverse (end to start) to make the +decompression faster by allowing strings to be appended and not prepended. + +Implementation +-------------- + +This section describes the implementation of the symbol compression. Both the +dictionary-based compression and the variable length compression are implemented +in a similar way. An external program is used to scan lots of data that +represents the kind of strings that are likely to be common, and generate header +files that contain information that is used by the compression routines. + +The dictionary-based compression generates an H file that contains information +about the escape characters used, the list of words in the codebook (this is the +list of substrings), a list of lengths for each substrings (to accelerate length +calculations). + +Our codebook contains about 3000 entries. In order to compress a word we need to +search the whole codebook, for every character in the string. This is slow +inefficient. Instead, the external program is generating a C program that +implements a search in a Trie-like data structure. The auto-generate search +routine exposes an API that returns the index of the matched word given a string +(the original uncompressed symbol) and length until the end of the string. + +The Huffman coding uses a similar technique. An external program auto-generates +routines that encode a sequence of strings into a number, or extract a number from +a sequence of strings. + +The external programs CBCGen.py and HuffGen.py generate the header files +HuffTables.h and CBC.h. + +Generating the compiler header files +------------------------------------ + +This section describes how to generate the compression tables using a training +set and create the header files (that are currently checked in as part of the +compiler). We generate the compression codebook and the Huffman tables using +data that we think represent the kind of symbol names people use in Swift. It is +important to select training data that is representitive or else the compression +will be less effective. + +Step1: Generate a list of mangled names from swift dylibs. This is done using +the "nm" command: "nm libSwiftCode.dylib > names.txt". Next, remove the prefix +that nm is adding (stuff like "U", "T" and "t" and addresses of symbols in the +dylib) and keep one name per line. + +Once we enable compression in our manglers you will need to decompress these +names using the utility swift-compress: +"cat compressed_names.txt | swift-compress -decompress > names.txt" + +Step2: Run "CBCGen.py file1.txt file2.txt file3.txt > CBC.h" +This will create the CBC header file. + +Step3: Recompile swift-compress and use it to compress names without applying +huffman encoding: "cat names.txt | swift-compress -cbc-only > names.txt.cbc" +This will create a file with names that are only compressed with the CBC +encoder, which is the input of our huffman encoder. + +Step4: Run HuffGen on the cbc-compressed file to generate the huffman encoding +tables: "./HuffGen.py names.txt.cbc > HuffTables.h" + +Error handling +-------------- + +The compression routines only handle characters that are in the list of valid +characters. It is possible to compress every string that uses the valid +character set. However, now all incoming strings are legal. For example the +string "Y" is illegal because 'Y' is an escape character and the decoded expects +another character to follow the escape character. + +There are a few users that will use the compression routines: The +mangler/demangler/remangler (in the compiler and debugger), the migration tool, +the unittests, etc. The current error handling strategy is to have asserts in +the compiler (in release builds). In addition to asserts the compiler handles +the decoding of malformed strings by returning an empty string. This is not +ideal and the compression routines should return a boolean flag that says if the +decompression succeeded. + +Migration plan +-------------- + +Once we finalize the encoding scheme we need to update many places in the compiler. This includes testcases +and places in the compiler where we've hard coded names of functions. +The swift-compress utility can be used to compress and decompress mangled names that appear in text.. +Just like swift-demangle this utility can replace strings and preserve the text around the mangled name. +This tool can help us in upgrading test files. + diff --git a/docs/proposals/Concurrency.rst b/docs/proposals/Concurrency.rst index f74ca909f2664..0030d23a66d15 100644 --- a/docs/proposals/Concurrency.rst +++ b/docs/proposals/Concurrency.rst @@ -202,7 +202,7 @@ variables and unsafe code. Objective-C methods are automatically marked as that do not explicitly mark the APIs as reentrant or non-reentrant. In the example program below the method `fly` may access the global variable -because it is marked with the attribute `unsafe`. The compile won't allow this +because it is marked with the attribute `unsafe`. The compiler won't allow this method to be executed from a worker-thread. .. code-block:: swift @@ -629,7 +629,7 @@ use actors can scale to support millions of concurrent actors because actors are not backed by a live thread or by a stack. In Swift actors could be implemented using classes that inherit from the generic -``Actor`` class. The generic parameter determins the type of messages that the +``Actor`` class. The generic parameter determines the type of messages that the actor can accept. The message type needs to be of ``CopyableType`` to ensure the safety of the model. The actor class exposes two methods: ``send`` and ``accept``. Messages are sent to actors using the ``send`` method and they never diff --git a/docs/proposals/DeclarationTypeChecker.rst b/docs/proposals/DeclarationTypeChecker.rst index bf49ac51d1c74..1872da6f5fd25 100644 --- a/docs/proposals/DeclarationTypeChecker.rst +++ b/docs/proposals/DeclarationTypeChecker.rst @@ -68,7 +68,7 @@ There are a few aspects of the language that make it challenging to implement th extension C { } extension B { struct Inner { } } -Here, the name lookup used for the first extension needs to resolve the typealias, which depends on the second extension having already been bound. There is a similar dependency on resolving superclasses beforing binding extensions:: +Here, the name lookup used for the first extension needs to resolve the typealias, which depends on the second extension having already been bound. There is a similar dependency on resolving superclasses before binding extensions:: class X { struct Inner { } } class Y : X { } @@ -154,7 +154,7 @@ The proposed architecture is significantly different from the current type check **Make name lookup phase-aware**: Name lookup is currently one of the worst offenders when violating phase ordering. Parameterize name lookup based on the phase at which it's operating. For example, asking for name lookup at the "extension binding" phase might not resolve type aliases, look into superclasses, or look into protocols. -**Make type resolution phase-aware**: Type resolution effectively brings a given ``TypeRepr`` up to the "declaration type validation`` phase in one shot. Parameterize type resolution based on the target phase, and start minimizing the among of work that the type checking does. Use extension binding as a testbed for these more-minimal dependencies. +**Make type resolution phase-aware**: Type resolution effectively brings a given ``TypeRepr`` up to the "declaration type validation`` phase in one shot. Parameterize type resolution based on the target phase, and start minimizing the amount of work that the type checking does. Use extension binding as a testbed for these more-minimal dependencies. **Dependency graph and priority queue**: Extend the current-phase trait with an operation that enumerates the dependencies that need to be satisfied to bring a given AST node up to a particular phase. Start with ``TypeRepr`` nodes, and use the dependency graph and priority queue to satisfy all dependencies ahead of time, eliminating direct recursion from the type-resolution code path. Build circular-dependency detection within this test-bed. @@ -165,7 +165,7 @@ The proposed architecture is significantly different from the current type check How do we test it? ~~~~~~~~~~~~~~~~~~ -**Existing code continues to work**: As we move various parts of the type checker over to the dependency graph, existing Swift code should continue to work, since we'll have fallbacks to the existing logic and the new type checker should be strictly more lazy than the existing type checker. +**Existing code continues to work**: As we move various parts of the type checker over to the dependency graph, existing Swift code should continue to work, since we'll have fallbacks to the existing logic and the new type checker should be strictly lazier than the existing type checker. **Order-independence testing**: One of the intended improvements from this type checker architecture is that we should get more predictable order-independent behavior. To check this, we can randomly scramble the order in which we type-check declarations in the primary source file of a well-formed module and verify that we get the same results. @@ -176,8 +176,8 @@ How do we measure progress? The proposed change is a major architectural shift, and it's only complete when we have eliminated all ad hoc recursion from the front end. There are a few ways in which we can measure progress along the way: -**AST nodes that implement the phase-aware trait**: Eventually, all of our AST nodes will implement the phase-aware trait. The number of AST nodes that do properly implement that trait (reporting current phase, enumerating dependencies for a phase transition) and become part of the dependency graph and priorty queue gives an indication of how far we've gotten. +**AST nodes that implement the phase-aware trait**: Eventually, all of our AST nodes will implement the phase-aware trait. The number of AST nodes that do properly implement that trait (reporting current phase, enumerating dependencies for a phase transition) and become part of the dependency graph and priority queue gives an indication of how far we've gotten. **Accessors that check the current phase**: When we're finished, each of the AST's accessors should assert that the AST node is in the appropriate phase. The number of such assertions that have been enabled is an indication of how well the type checker is respecting the dependencies. -**Phases of AST nodes in non-primary files**: With the current type checker, every AST node in a non-primary file that gets touched when type-checking the primary file will end up being fully validated (currently, the "attribute checking" phase). As the type checker gets more lazy, the AST nodes in non-primary files will trend toward earlier phases. Tracking the number of nodes in non-primary files at each phase over time will help us establish how lazy the type checker is becoming. +**Phases of AST nodes in non-primary files**: With the current type checker, every AST node in a non-primary file that gets touched when type-checking the primary file will end up being fully validated (currently, the "attribute checking" phase). As the type checker gets lazier, the AST nodes in non-primary files will trend toward earlier phases. Tracking the number of nodes in non-primary files at each phase over time will help us establish how lazy the type checker is becoming. diff --git a/docs/proposals/Enums.rst b/docs/proposals/Enums.rst index 46402160b1a1f..607596bd4d9b6 100644 --- a/docs/proposals/Enums.rst +++ b/docs/proposals/Enums.rst @@ -281,7 +281,7 @@ circumstances: StringLiteralConvertible. - None of the cases of the enum may have non-void payloads. -If an enum declares an raw type, then its cases may declare raw +If an enum declares a raw type, then its cases may declare raw values. raw values must be integer, float, character, or string literals, and must be unique within the enum. If the raw type is IntegerLiteralConvertible, then the raw values default to diff --git a/docs/proposals/Error Handling.rst b/docs/proposals/Error Handling.rst deleted file mode 100644 index 697b9d3b406aa..0000000000000 --- a/docs/proposals/Error Handling.rst +++ /dev/null @@ -1,171 +0,0 @@ -:orphan: - -.. @raise litre.TestsAreMissing -.. ErrorHandlingModel: - -Swift Error Handling Model -========================== - -The goal of this writeup is to capture ideas around error handling in APIs and -the tradeoffs involved that influenced this design. - -Error Handling In Contemporary Languages ----------------------------------------- - -C and POSIX proffer a mix of "errno" based APIs and APIs that return an error -code explicitly as a result. While this approach _works_, it has a number of -problems: 1) it is too easy to accidentally ignore an error, 2) using a thread -local integer variable for error handling is non-extensible, and 3) using the -return value as an error code in C forces the logical result of the function to -be returned by reference through an argument pointer. - -In contrast, the "obvious" approach to error handling is exception handling as -known from C++, Java, C#, and many other languages. Exception handling allows -decoupling the logic that produces an error, the (implicitly generated) -logic that propagates the error, and the logic that ultimately handles the error -code. The implementation model allows a choice of either "zero cost" exceptions -which have a slow error case, or an implicitly generated propagation which slows -down the normal case a bit to make error propagation faster. That said, there -are a lot of ways to do exception handling wrong. - -Exception Specifications -```````````````````````` - -Exception specifications are difficult to get right. Adding an concrete -exception specification (i.e., "I only throw T") to a function is a very strong -guarantee that is often difficult to maintain as APIs evolve. For this reason, -Java has two sorts of exceptions: normal ones that obey exception specifications -and "runtime" exceptions that are exempt from them. In practice, this loop-hole -makes exception specifications in Java completely useless for reasoning about -the exception behavior of a program, which is one of the reasons that C# -eliminated them completely. - -C++'98 has other unfortunate issues with its exception specifications, including -that all functions are assumed to implicitly throw if they have no exception -spec. Also, its design for empty exception specification (e.g. -"void foo() throw()") is also problematic, and was improved by adding "noexcept" -in C++'11. - -Objective-C is interesting because its exception specifications (i.e. the -presence of an NSError** argument) is binary: a function can return an -error or not, but it isn't encouraged to document *how* APIs can fail in -detailed ways. - -Runtime Failures -```````````````` - -Both Objective-C and Java recognize a difference between general application -errors and "runtime" errors (such as out-of-bound NSArray accesses, or a null -pointer dereference in Java). As mentioned above, Java allows runtime errors -to avoid exception specifications, but otherwise treats them the same as other -exceptions. - -Objective-C handles runtime errors by throwing an Objective-C exception, which -is a somewhat hard failure because very little Objective-C code is exception -safe. This leads to memory leaks or have other adverse effects, which is not -regarded as recoverable behavior. - -A unfortunate aspect of allowing runtime exceptions to be "caught" is that it -means that removing "guard rails" in the language (e.g. turning off array bounds -checks or null pointer dereference checks) can turn a working application (one -that detects, catches, and handles the error) into a broken application (one -that scribbles on garbage memory). - - -Other Problems with Exception Handling -`````````````````````````````````````` - -C++'s exception handling model causes many systems applications (e.g., LLVM, -Webkit, and many others) to disable exception handling with -fno-exception. One -issue is that C++ exception handling violates its own "pay for what you use" -model of C++ by bloating your code with exception tables and RTTI data, -even if you don't actually throw any exceptions. The fact that C++ has a poor -model to reason about what calls actually throw also leads to pessimization in -the optimizer as it has to assume the worst case about exception edges, leading -to lower performance (even with "zero cost" exceptions) and code bloat compared -to building with -fno-exceptions. - -C++ also requires a very specific design style (emphasizing RAII) to make an -application exception safe because it lacks automatic memory management. - -Another common reason that C++ code disables exceptions is that they want a more -"disciplined" or "strict" mode for writing their code. Many people -(particularly at the lower levels of "systems programming" stack) want to know -about and reason about the error handling and propagation behavior of every -error state that can happen, and do not want the implicit propagation aspect of -exceptions. - -Finally, because a lot of disables exceptions, many libraries actively avoid -designing them into their APIs. The STL in particular has very few APIs that -throw exceptions on error cases, and those APIs have non-throwing counterparts. - -Error Handling Goals --------------------- - -The design of an error handling system has conflicting goals based on the -audience: some programmers don't want to think about error handling logic at -all - yielding a more "scripting language" sort of experience, while some people -want to control every error case and be forced to think about error handling in -depth - yielding a more "disciplined" experience. Neither of these is "wrong" -or better than the other, they serve different needs and Swift should support -both use cases. - -While level of strictness is negotiable and Swift should support multiple -approaches, the error handling behavior of stable *API* is something that must -be considered as strongly as the arguments and return value of the function. We -consider it a breaking change (and therefore, unacceptable) for API that was -previously guaranteed to never return an error to start returning error codes. - -It's worth noting that Objective-C achieves these goals -with NSError. NSError "results" are explicitly part of the signature of a -method, and one cannot be added or removed without changing the selector (a -breaking change). Clients who don't care about error handling can (and often -do) completely ignore the NSError result of a method call. - - -Swift Error Handling Model --------------------------- - -Swift categorizes error conditions into two classifications: exceptions and -unrecoverable runtime errors. Either condition can be raised by arbitrary code, -but the two are implemented in different ways and have different ramifications -for propagation and handling of the condition. - -Swift Runtime Errors -```````````````````` - -Runtime errors are conditions like deferencing a null pointer, accessing an -array out of bounds, and explicitly declared exceptions (e.g. out of memory -conditions, at least in some cases). Because they can occur anywhere, they are -not explicitly declared as part of API - any function is assumed to be capable -of raising a runtime error. - -are considered to be "uncatchable" failures that terminate the -current thread/actor, and are - - -Runtime errors can occur anywhere in the application - -array out of bounds -assertion failure, pre/post conditions failures, typestate violation. -cast(V) - - - - - - - - -Swift Exceptions -```````````````` - - -TODO - - -strict mode, vs sloppy mode. - -API means something is strict. - - diff --git a/docs/proposals/InitializerInheritance.rst b/docs/proposals/InitializerInheritance.rst index 6fbb8118deb13..4ae92827cf327 100644 --- a/docs/proposals/InitializerInheritance.rst +++ b/docs/proposals/InitializerInheritance.rst @@ -283,7 +283,7 @@ attribute, are guaranteed to be available in every subclass of } func f(meta: D.Type) { - meta() // okay: every sublass of D guaranteed to have an init() + meta() // okay: every subclass of D guaranteed to have an init() } Note that ``@virtual`` places a requirement on all subclasses to @@ -378,7 +378,7 @@ a trivial ``NSDocument``:: In Swift, there would be no way to create an object of type ``MyDocument``. However, the frameworks will allocate an instance of -``MyDocument`` and then send an message such as +``MyDocument`` and then send a message such as ``initWithContentsOfURL:ofType:error:`` to the object. This will find ``-[NSDocument initWithContentsOfURL:ofType:error:]``, which delegates to ``-[NSDocument init]``, leaving ``MyDocument``'s stored properties diff --git a/docs/proposals/InoutCOWOptimization.rst b/docs/proposals/InoutCOWOptimization.rst index 4f0543fcbf2ed..c784fda253786 100644 --- a/docs/proposals/InoutCOWOptimization.rst +++ b/docs/proposals/InoutCOWOptimization.rst @@ -7,7 +7,7 @@ :Authors: Dave Abrahams, Joe Groff :Summary: Our writeback model interacts with Copy-On-Write (COW) to - cause some surprising ineffiencies, such as O(N) performance + cause some surprising inefficiencies, such as O(N) performance for ``x[0][0] = 1``. We propose a modified COW optimization that recovers O(1) performance for these cases and supports the efficient use of slices in algorithm implementation. @@ -25,8 +25,8 @@ The problem is caused as follows: x[0].mutate() - we “``subscript get``” ``x[0]`` into a temporary, mutate the - temporary, and “``subscript set``” it back into ``x[0]``. + we "``subscript get``" ``x[0]`` into a temporary, mutate the + temporary, and "``subscript set``" it back into ``x[0]``. * When the element itself is a COW type, that temporary implies a retain count of at least 2 on the element's buffer. @@ -51,7 +51,7 @@ could be written as follows: protocol Sliceable { ... @mutating - func quickSort(compare: (StreamType.Element, StreamType.Element)->Bool) { + func quickSort(compare: (StreamType.Element, StreamType.Element) -> Bool) { let (start,end) = (startIndex, endIndex) if start != end && start.succ() != end { let pivot = self[start] diff --git a/docs/proposals/Inplace.rst b/docs/proposals/Inplace.rst index 95d31e1623fc4..47cc17089b1ab 100644 --- a/docs/proposals/Inplace.rst +++ b/docs/proposals/Inplace.rst @@ -310,7 +310,7 @@ as though it were written: .. parsed-literal:: { - (var y: X)->X in + (var y: X) -> X in y\ **.=**\ *f*\ (a₀, p₁: a₁, p₂: a₂, …p\ *n*: a\ *n*) return y }(x) @@ -344,7 +344,7 @@ as though it were written: .. parsed-literal:: { - (var y: X)->X in + (var y: X) -> X in y *op*\ **=**\ *expression* return y }(x) @@ -424,7 +424,7 @@ fine:: foo.=advanced(10) The alternative would be to say that explicitly-written assignment methods -cannot work properly for immutable classes and “work” with reference +cannot work properly for immutable classes and "work" with reference semantics on other classes. We consider this approach indefensible, especially when one considers that operators encourage writing algorithms that can only work properly with value semantics and will diff --git a/docs/proposals/ObjC Interoperation.rst b/docs/proposals/ObjC Interoperation.rst index 90c142680b924..2eb2586c4b591 100644 --- a/docs/proposals/ObjC Interoperation.rst +++ b/docs/proposals/ObjC Interoperation.rst @@ -330,7 +330,7 @@ difference between a stored property and its underlying storage, For another example, code class might access -In bot hcaess, t makes sense to organize the code that way, +In both cases, t makes sense to organize the code that way, but Objective C punishes the performance of that code in order to reserve the language's diff --git a/docs/proposals/OptimizerEffects.rst b/docs/proposals/OptimizerEffects.rst index ae4ec5ded155f..d5c11835af489 100644 --- a/docs/proposals/OptimizerEffects.rst +++ b/docs/proposals/OptimizerEffects.rst @@ -2,8 +2,8 @@ .. OptimizerEffects: -Optimizer Effects: Summarizing and specifing function side effects -================================================================== +Optimizer Effects: Summarizing and specifying function side effects +=================================================================== .. contents:: @@ -20,10 +20,10 @@ Introduction This document formalizes the effects that functions have on program state for the purpose of facilitating compiler optimization. By modeling more precise function effects, the optimizer can make more -assumptions leading to more agressive transformation of the program. +assumptions leading to more aggressive transformation of the program. Function effects may be deduced by the compiler during program -analyis. However, in certain situations it is helpful to directly +analysis. However, in certain situations it is helpful to directly communicate function effects to the compiler via function attributes or types. These source level annotations may or may not be statically enforceable. @@ -207,7 +207,7 @@ state. ``@get_subobject`` - A method marked ``@get_subobject`` must fullfill all of ``@preserve_unique``'s + A method marked ``@get_subobject`` must fulfill all of ``@preserve_unique``'s guarantees. Furthermore, it must return a 'subobject' that is stored by the set of storage objects or a value stored in the CoW struct itself. It must be guaranteed that the 'subobject' returned is kept alive as long the current @@ -245,7 +245,7 @@ state. ``@get_subobject_non_bridged`` - A method marked ``@get_subobject`` must fullfill all of ``@preserve_unique``'s + A method marked ``@get_subobject`` must fulfill all of ``@preserve_unique``'s guarantees. Furthermore, it must return a 'subobject' that is stored by the set of storage objects or a value stored in the CoW struct itself. It must be guaranteed that the 'subobject' returned is kept alive as long the current @@ -280,7 +280,7 @@ state. ``@get_subobject_addr`` - A method marked ``@get_subobject_addr`` must fullfill all of + A method marked ``@get_subobject_addr`` must fulfill all of ``@preserve_unique``'s guarantees. Furthermore, it must return the address of a 'subobject' that is stored by the set of storage objects. It is guaranteed that the 'subobject' at the address returned is kept alive as long the current @@ -304,7 +304,7 @@ state. ``@initialize_subobject`` - A method marked ``@initialize_subobject`` must fullfill all of + A method marked ``@initialize_subobject`` must fulfill all of ``@preserve_unique``'s guarantees. The method must only store its arguments into *uninitialized* storage. The only effect to non-self state is the capture of the method's arguments.:: @@ -332,7 +332,7 @@ state. ``@set_subobject`` - A method marked ``@set_subobject`` must fullfill all of + A method marked ``@set_subobject`` must fulfill all of ``@preserve_unique``'s guarantees. The method must only store its arguments into *initialized* storage. The only effect to non-self state is the capture of the method's arguments and the release of objects of the method arguments' @@ -427,7 +427,7 @@ the object named by 'A' and therefore cannot modify it. Why do we need ``@get_subobject``, ``@initialize_subobject``, and ``@set_subobject``? -We want to be able to hoist ``makeunique`` calls when the array is not identfied +We want to be able to hoist ``makeunique`` calls when the array is not identified by a unique name.:: class AClass { @@ -452,7 +452,7 @@ Further we would like to reason that::: a.array.append -cannot change the uniqueness state of the instance of array 'a.array' accross +cannot change the uniqueness state of the instance of array 'a.array' across iterations. We can conclude so because ``appendAssumingUnique``'s side-effects guarantee that no destructor can run - it's only side-effect is that ``tmp`` is captured and initializes storage in the array - these are the only @@ -535,7 +535,7 @@ User-Specified Effects, Syntax and Defaults Mostly TBD. The optimizer can only take advantage of user-specified effects before -they have been inlined. Consequently, the optimizer initialy preserves +they have been inlined. Consequently, the optimizer initially preserves calls to annotated @effects() functions. After optimizing for effects these functions can be inlined, dropping the effects information. @@ -562,7 +562,7 @@ generic arguments:: func setElt(elt: T) { t = elt } } -With no knowledge of T.deinit() we must assume worst case. SIL effects +With no knowledge of T.deinit() we must assume the worst case. SIL effects analysis following specialization can easily handle such a trivial example. But there are two situations to be concerned about: @@ -617,7 +617,7 @@ optimizing the surrounding code. For example:: func bar(t: T) {...} - + func foo(t: T, N: Int) { for _ in 1...N { bar(t) @@ -644,12 +644,12 @@ defined types composed from Arrays, Sets, and Strings. Conceptually, a pure value does not share state with another value. Any trivial struct is automatically pure. Other structs can be declared pure by the author. It then becomes the author's -resonsibility to guarantee value semantics. For instance, any stored +responsibility to guarantee value semantics. For instance, any stored reference into the heap must either be to immutable data or protected by CoW. Since a pure value type can in practice share implementation state, we -need an enforcable definition of such types. More formally: +need an enforceable definition of such types. More formally: - Copying or destroying a pure value cannot affect other program state. @@ -738,7 +738,7 @@ effects. This is the crux of the difficulty in defining the CoW effects. Consequently, communicating purity to the compiler will require some function annotations and/or type constraints. -A CoW type consits of a top-level value type, most likely a struct, and a +A CoW type consists of a top-level value type, most likely a struct, and a referenced storage, which may be shared between multiple instances of the CoW type. @@ -795,7 +795,7 @@ Store (1) and load (2) do not alias and (3) is defined as ``readnone``. So (1) could be moved over (3). Currently inlining is prevented in high-level SIL for all functions which -have an semantics or effect attribute. Therefore we could say that the +have a semantics or effect attribute. Therefore we could say that the implementor of a pure value type has to define effects on all member functions which eventually can access or modify the storage. @@ -842,7 +842,7 @@ Inferring Function Purity The optimizer can infer function purity by knowing that (1) the function does not access unspecified state, (2) all arguments are pure -values, and (3) no calls are made into nonpure code. +values, and (3) no calls are made into non-pure code. (1) The effects system described above already tells the optimizer via analysis or annotation that the function does not access @@ -853,7 +853,7 @@ values, and (3) no calls are made into nonpure code. type definition, or it may rely on a type constraint. (3) Naturally, any calls within the function body must be transitively - pure. There is no need to check a calls to the storage + pure. There is no need to check calls to the storage deinitializer, which should already be guaranteed pure by virtue of (2). @@ -919,5 +919,5 @@ Generally, a default-safe policy provides a much better user model from some effects. For example, we could decide that functions cannot affect unspecified state by default. If the user accesses globals, they then need to annotate their function. However, default safety -dictates that any neccessary annotations should be introduced before +dictates that any necessary annotations should be introduced before declaring API stability. diff --git a/docs/proposals/ValueSemantics.rst b/docs/proposals/ValueSemantics.rst index 3541d407e0a09..5d03c19518d0b 100644 --- a/docs/proposals/ValueSemantics.rst +++ b/docs/proposals/ValueSemantics.rst @@ -25,7 +25,7 @@ Value Semantics --------------- For a type with value semantics, variable initialization, assignment, -and argument-passing (hereafter, “the big three operations”) each +and argument-passing (hereafter, "the big three operations") each create an *independently modifiable copy* of the source value that is *interchangeable with the source*. [#interchange]_ @@ -151,13 +151,13 @@ The Problem With Generics The classic Liskov principle says the semantics of operations on ``Duck``\ 's subtypes need to be consistent with those on ``Duck`` itself, -so that functions operating on ``Duck``\ s still “work” when passed a +so that functions operating on ``Duck``\ s still "work" when passed a ``Mallard``. More generally, for a function to make meaningful guarantees, the semantics of its sub-operations need to be consistent regardless of the actual argument types passed. The type of an argument passed by-value to an ordinary function is -fully constrained, so the “big three” have knowable semantics. The +fully constrained, so the "big three" have knowable semantics. The type of an ordinary argument passed by-reference is constrained by subtype polymorphism, where a (usually implicit) contract between base- and sub-types can dictate consistency. @@ -179,7 +179,7 @@ Here’s a version of cycle_length that works when state is a mutable value type:: func cycle_length( - s : State, mutate : ( [inout] State )->() + s : State, mutate : ( [inout] State ) -> () ) -> Int requires State : EqualityComparable { @@ -196,7 +196,7 @@ value type:: The reason the above breaks when the state is in a class instance is that the intended copy in line 1 instead creates a new reference to the same state, and the comparison in line 2 (regardless of whether we -decide ``!=`` does “identity” or “value” comparison) always succeeds. +decide ``!=`` does "identity" or "value" comparison) always succeeds. You can write a different implementation that only works on clonable classes: @@ -211,7 +211,7 @@ classes: } func cycle_length( - s : State, mutate : ( [inout] State )->() + s : State, mutate : ( [inout] State ) -> () ) -> Int requires State : EqualityComparable, **Clonable** { @@ -233,8 +233,8 @@ clonable classes: func cycle_length( s : State, - **next : (x : State)->State,** - **equal : ([inout] x : State, [inout] y : State)->Bool** + **next : (x : State) -> State,** + **equal : ([inout] x : State, [inout] y : State) -> Bool** ) -> Int requires State : EqualityComparable { diff --git a/docs/proposals/WholeModuleOptimization.rst b/docs/proposals/WholeModuleOptimization.rst index f391272a216c6..9f67bbf9ee89e 100644 --- a/docs/proposals/WholeModuleOptimization.rst +++ b/docs/proposals/WholeModuleOptimization.rst @@ -23,7 +23,7 @@ compilation that results from having the entire module available makes it possible for the inliner to inline functions that it would otherwise not be able to inline in normal separate compilation. Other optimizations similarly benefit, for example generic specialization -(since it has more opportunities for specializae) and function +(since it has more opportunities for specialize) and function signature optimization (since it has more call sites to rewrite). diff --git a/docs/proposals/archive/Memory and Concurrency Model.rst b/docs/proposals/archive/Memory and Concurrency Model.rst index 82dc4bd50d986..62568f908af22 100644 --- a/docs/proposals/archive/Memory and Concurrency Model.rst +++ b/docs/proposals/archive/Memory and Concurrency Model.rst @@ -48,7 +48,7 @@ Swift. Given a static type, it is obvious what kind it is from its definition. These kinds are: 1. **Immutable Data** - Immutable data (which can have a constructor, but whose - value cannot be changed after it completes) is sharable across actors, and it + value cannot be changed after it completes) is shareable across actors, and it would make sense to unique them where possible. Immutable data can (transitively) point to other immutable data, but it isn't valid (and the compiler rejects) immutable data that is pointing to mutable data. For diff --git a/docs/proposals/archive/ProgramStructureAndCompilationModel.rst b/docs/proposals/archive/ProgramStructureAndCompilationModel.rst index 1f67481707cc1..cea89ce740524 100644 --- a/docs/proposals/archive/ProgramStructureAndCompilationModel.rst +++ b/docs/proposals/archive/ProgramStructureAndCompilationModel.rst @@ -35,7 +35,7 @@ to the business and management reality of the world: **Ownership Domain / Top Level Component**: corresponds to a product that is shipped as a unit (Mac OS/X, iWork, Xcode), is a collection of frameworks/dylibs -and resources. Only acyclic dependences between different domains is +and resources. Only acyclic dependencies between different domains is allowed. There is some correlation in concept here to "umbrella headers" or "dyld shared cache" though it isn't exact. @@ -47,7 +47,7 @@ dylib + optional resources. All contributing source files and resources live in one directory (with optional subdirs), and have a single "project file". Can contribute to multiple namespaces. The division of a domain into components is an implementation detail, not something externally visible as API. Can have -cyclic dependences between other components. Components roughly correspond to +cyclic dependencies between other components. Components roughly correspond to "xcode project" or "B&I project" granularity at Apple. Can rebuild a "debug version" of a subcomponent and drop it into an app without rebuilding the entire world. @@ -104,7 +104,7 @@ Components are explicitly declared, and these declarations can include: * the version of the component (which are used for "availability macros" etc) -* an explicit list of dependences on other top-level components (whose +* an explicit list of dependencies on other top-level components (whose dependence graph is required to be acyclic) optionally with specific versions: "I depend on swift standard libs 1.4 or later" @@ -283,7 +283,7 @@ Now the compiler parses each swift file into an AST. We'll keep the swift grammar carefully factored to keep types and values distinct, so it is possible to parse (but not fully typecheck) the files without first reading "all the headers they depend on". This is important because we want to allow arbitrary -type and value cyclic dependences between files in a component. As each file is +type and value cyclic dependencies between files in a component. As each file is parsed, the compiler resolves as many intra-file references as it can, and ends up with a list of (namespace qualified) types and values that are imported by the file that are not satisfied by other components. This is the list of things @@ -311,7 +311,7 @@ carefully layered to be memory efficient (e.g. only processing an SCC at a time instead of an entire component) as well as highly parallel for multicore machines. For incremental builds, we will have a huge win because the fine-grained dependence information between .o files is tracked and we know -exactly what dependences to rebuild if anything changes. The build cache will +exactly what dependencies to rebuild if anything changes. The build cache will accelerate most of this, which will eventually be a hybrid on-disk/in-memory data structure. @@ -330,7 +330,7 @@ client builds against the component to type check the client and ensure that its references are resolved. Because we have the version number as well as the full interface to the -component available in a consumable format is that we can build a SDK generation +component available in a consumable format is that we can build an SDK generation tool. This tool would take manifest files for a set of releases (e.g. iOS 4.0, 4.0.1, 4.0.2, 4.1, 4.1.1, 4.2) and build a single SDK manifest which would have a mapping from symbol+type -> version list that indicates what the versions a diff --git a/docs/proposals/archive/UnifiedFunctionSyntax.rst b/docs/proposals/archive/UnifiedFunctionSyntax.rst index 5fa8e9a869bc0..5c15dbe1f4243 100644 --- a/docs/proposals/archive/UnifiedFunctionSyntax.rst +++ b/docs/proposals/archive/UnifiedFunctionSyntax.rst @@ -406,7 +406,7 @@ circumstances that affect inclusion or exclusion from the list. +----------------+---------+---------+----------------------------+ | **From** | Yes | No | | +----------------+---------+---------+----------------------------+ -| **Given** | Yes* | No | Never splits a slector | +| **Given** | Yes* | No | Never splits a selector | +----------------+---------+---------+----------------------------+ | **In** | Yes | No | | +----------------+---------+---------+----------------------------+ diff --git a/docs/proposals/containers_value_type.html b/docs/proposals/containers_value_type.html index 6599a83cc84c0..c64d60c53cf5f 100644 --- a/docs/proposals/containers_value_type.html +++ b/docs/proposals/containers_value_type.html @@ -231,7 +231,7 @@

those used in Cocoa. Now there is absolutely nothing wrong with high quality, strictly followed naming conventions. But they aren't checked by the compiler. Having the compiler be able to confirm: yes, this -argument can be modified / no, that argument can not be modified; is a +argument can be modified / no, that argument cannot be modified; is a tremendous productivity booster.

@@ -347,7 +347,7 @@

archives is an in-out argument. And just as importantly, that archivePath is not to be modified within _checkPathForArchiveAndAddToArray. However if -archivePath is a mutable object with reference semantics, we loose +archivePath is a mutable object with reference semantics, we lose that ability to locally reason about this code, even in Swift.

@@ -482,7 +482,7 @@

Summary

more easily spot the few cases where this is desired.

    -
  • Swift can not provide such protection for types with reference semantics.
  • +
  • Swift cannot provide such protection for types with reference semantics.
diff --git a/docs/proposals/rejected/Bridging Container Protocols to Class Clusters.rst b/docs/proposals/rejected/Bridging Container Protocols to Class Clusters.rst index cbef36e587f2d..f80400d1b6fc4 100644 --- a/docs/proposals/rejected/Bridging Container Protocols to Class Clusters.rst +++ b/docs/proposals/rejected/Bridging Container Protocols to Class Clusters.rst @@ -24,7 +24,7 @@ Here's what I propose instead: Although I'll be talking about arrays in this proposal, I think the same approach would work for ``NSDictionary`` and ``NSSet`` as well, mapping them -to generic containers for associative map and and unordered container protocols +to generic containers for associative map and unordered container protocols respectively. NSArray vs Array diff --git a/docs/proposals/rejected/ClassConstruction.rst b/docs/proposals/rejected/ClassConstruction.rst index 9db9f65ead8a8..5b1ea48747c5d 100644 --- a/docs/proposals/rejected/ClassConstruction.rst +++ b/docs/proposals/rejected/ClassConstruction.rst @@ -7,7 +7,7 @@ .. warning:: This proposal was rejected, though it helped in the design of the final Swift 1 initialization model. -Objective-C's “designated inititalizers” pattern seems at first to +Objective-C's "designated initializers pattern seems at first to create a great deal of complication. However, designated initializers are simply the only sane response to Objective-C's initialization rules, which are the root cause of the complication. @@ -116,9 +116,9 @@ Proposal ======== I suggest we define Swift initialization to be as simple and -easily-understood as possible, and avoid “interesting” interactions +easily-understood as possible, and avoid "interesting" interactions with the more complicated Objective-C initialization process. If we -do this, we can treat Objective-C base classes as “sealed and safe” +do this, we can treat Objective-C base classes as "sealed and safe" for the purpose of initialization, and help programmers reason effectively about initialization and their class invariants. @@ -133,7 +133,7 @@ Here are the proposed rules: Objective-C. * ``self.init(…)`` calls in Swift never dispatch virtually. We have a - safe model for “virtual initialization:” ``init`` methods can call + safe model for "virtual initialization:" ``init`` methods can call overridable methods after all instance variables and superclasses are initialized. Allowing *virtual* constructor delegation would undermine that safety. diff --git a/docs/proposals/rejected/Clonable.rst b/docs/proposals/rejected/Clonable.rst index 949ecf93cb883..39bf2c5d08a41 100644 --- a/docs/proposals/rejected/Clonable.rst +++ b/docs/proposals/rejected/Clonable.rst @@ -15,7 +15,7 @@ language-level copying mechanism for classes. **Abstract:** to better support the creation of value types, we -propose a “magic” ``Clonable`` protocol and an annotation for describing +propose a "magic" ``Clonable`` protocol and an annotation for describing which instance variables should be cloned when a type is copied. This proposal **augments revision 1** of the Clonable proposal with our rationale for dropping our support for ``val`` and ``ref``, a @@ -65,7 +65,7 @@ automatic, if we add that feature) forwarding. By dropping ``val`` we also lose some terseness aggregating ``class`` contents into ``struct``\ s. However, since ``ref`` is being dropped -there's less call for a symmetric ``val``. The extra “cruft” that +there's less call for a symmetric ``val``. The extra "cruft" that ``[clone]`` adds actually seems appropriate when viewed as a special bridge for ``class`` types, and less like a penalty against value types. @@ -125,7 +125,7 @@ variables marked ``[clone]``:: var somethingIJustReferTo : Bar } -When a ``Baz`` is copied by any of the “big three” operations (variable +When a ``Baz`` is copied by any of the "big three" operations (variable initialization, assignment, or function argument passing), even as part of a larger ``struct``, its ``[clone]`` member is ``clone()``\ d. Because ``Foo`` itself has a ``[clone]`` member, that is ``clone()``\ d diff --git a/docs/proposals/rejected/Constructors.rst b/docs/proposals/rejected/Constructors.rst index 69fcb9660217f..c88b9b7802571 100644 --- a/docs/proposals/rejected/Constructors.rst +++ b/docs/proposals/rejected/Constructors.rst @@ -461,11 +461,11 @@ zero-argument selector with no trailing colon, e.g.,:: maps to the selector ``initToMemory``. -This mapping is reversible: given a selector in the “init” family, -i.e., where the first word is “init”, we split the selector into its +This mapping is reversible: given a selector in the "init" family, +i.e., where the first word is "init", we split the selector into its various pieces at the colons: -* For the first piece, we remove the “init” and then lowercase the +* For the first piece, we remove the "init" and then lowercase the next character *unless* the second character is also uppercase. This becomes the name of the first parameter to the constructor. If this string is non-empty and the selector is a zero-argument selector @@ -494,7 +494,7 @@ designated initializers in Objective-C. Clang can then be extended to perform similar checking to what we're describing for Swift: designated initializers delegate or chain to the superclass constructor, secondary constructors always delegate, and subclassing -rrequires one to override the designated initializers. The impact can +requires one to override the designated initializers. The impact can be softened somewhat using warnings or other heuristics, to be (separately) determined. @@ -508,7 +508,7 @@ is being substituted for another object. In both cases, we are left with a partially-constructed object that then needs to be destroyed, even though its instance variables may not -yet havee been initialized. This is also a problem for Objective-C, +yet have been initialized. This is also a problem for Objective-C, which makes returning anything other than the original ''self'' brittle. @@ -533,7 +533,7 @@ Alternatives ------------ This proposal is complicated, in part because it's trying to balance -the safety goals of Swift against the convience of Objective-C's +the safety goals of Swift against the convenience of Objective-C's two-phase initialization. Separate Swift Constructors from Objective-C Initializers diff --git a/docs/proposals/valref.rst b/docs/proposals/valref.rst index 6266129ffd804..04f9dfe18fb34 100644 --- a/docs/proposals/valref.rst +++ b/docs/proposals/valref.rst @@ -29,15 +29,15 @@ Introduction Until recently, Swift's support for value semantics outside trivial types like scalars and immutable strings has been weak. While the -recent ``Clonable`` proposal makes new things possible in the “safe” +recent ``Clonable`` proposal makes new things possible in the "safe" zone, it leaves the language syntactically and semantically lumpy, keeping interactions between value and reference types firmly outside -the “easy” zone and failing to address the issue of generic +the "easy" zone and failing to address the issue of generic programming. This proposal builds on the ``Clonable`` proposal to create a more uniform, flexible, and interoperable type system while solving the -generic programming problem and expanding the “easy” zone. +generic programming problem and expanding the "easy" zone. General Description =================== @@ -68,8 +68,8 @@ When applied to ``class`` types, "copy" means to call the ``clone()`` method, which is generated by the compiler when the user has explicitly declared conformance to the ``Clonable`` protocol. -When we refer to variables being “declared ``val``” or “declared -``ref``”, we mean to include the case of equivalent declarations using +When we refer to variables being "declared ``val``" or "declared +``ref``", we mean to include the case of equivalent declarations using ``var`` that request the default semantics for the type. Unless otherwise specified, we discuss implementation details such as @@ -150,7 +150,7 @@ Instance variables can be explicitly declared ``val`` or ``ref``:: When a value is copied, all of its instance variables declared ``val`` (implicitly or explicitly) are copied. Instance variables declared ``ref`` merely have their reference counts incremented (i.e. the -refrence is copied). Therefore, when the defaults are in play, the +reference is copied). Therefore, when the defaults are in play, the semantic rules already defined for Swift are preserved. The new rules are as follows: @@ -178,8 +178,8 @@ Array elements can be explicitly declared ``val`` or ``ref``:: When a reference to an array appears without a variable name, it can be written using the `usual syntax`__:: - var f : ()->ref Int[42] // a closure returning a reference to an array - var b : ref Int[42] // equivalent to to "ref b : Int[42]" + var f : () -> ref Int[42] // a closure returning a reference to an array + var b : ref Int[42] // equivalent to "ref b : Int[42]" __ `standalone types`_ @@ -191,8 +191,8 @@ brackets, that most users will never touch, e.g.:: var z : Array // an array of 42 integers-on-the-heap var z : Array, 2> // an array of 2 references to arrays ref a : Array // a reference to an array of 42 integers - var f : ()->ref Array // a closure returning a reference to an array - var b : ref Array // equivalent to to "ref b : Int[42]" + var f : () -> ref Array // a closure returning a reference to an array + var b : ref Array // equivalent to "ref b : Int[42]" Rules for copying array elements follow those of instance variables. @@ -365,7 +365,7 @@ Objective-C Interoperability Clonable Objective-C classes ----------------------------- -In Cocoa, a notion similar to clonability is captured in the ``NSCopying`` and +In Cocoa, a notion similar to cloneability is captured in the ``NSCopying`` and ``NSMutableCopying`` protocols, and a notion similar to ``val`` instance variables is captured by the behavior of ``(copy)`` properties. However, there are some behavioral and semantic differences that need to be taken into account. @@ -425,7 +425,7 @@ How This Design Improves Swift matters. 4. We move the cases where values and references interact much closer - to, and arguably into, the “easy” zone. + to, and arguably into, the "easy" zone. How This Design Beats Rust/C++/C#/etc. ====================================== @@ -437,7 +437,7 @@ How This Design Beats Rust/C++/C#/etc. rooting`__, etc. By contrast, there's a path to learning swift that postpones the ``val``\ /``ref`` distinction, and that's pretty much *all* one must learn to have a complete understanding of the object - model in the “easy” and “safe” zones. + model in the "easy" and "safe" zones. __ http://static.rust-lang.org/doc/tutorial.html#boxes-and-pointers __ http://static.rust-lang.org/doc/tutorial-borrowed-ptr.html#named-lifetimes @@ -560,7 +560,7 @@ example: There's always the dreaded ``auto``. * Should we drop ``let``\ /``var``\ /``auto`` for ivars, because it - “just feels wrong” there? + "just feels wrong" there? * ``ref`` is spelled like ``[inout]``, but they mean very different things @@ -569,7 +569,7 @@ example: ``[inout]``. * Should we spell ``[inout]`` differently? I think at a high level - it means something like “``[rebind]`` the name to a new value.” + it means something like "``[rebind]`` the name to a new value." * Do we want to consider replacing ``struct`` and/or ``class`` with new names such as ``valtype`` and ``reftype``? We don't love those diff --git a/docs/scripts/ns-html2rst b/docs/scripts/ns-html2rst index 004cf6f6d6a29..bc5ec847ea1d9 100755 --- a/docs/scripts/ns-html2rst +++ b/docs/scripts/ns-html2rst @@ -1,13 +1,15 @@ #!/usr/bin/env python +from __future__ import print_function + import sys, re, subprocess def run(): if len(sys.argv) > 1: - print """ + print(""" ns-html2rst - Convert Cocoa HTML documentation into ReST usage: nshtml2rst < NSString.html > NSString.rst - """ + """) exit(0) html = sys.stdin.read() diff --git a/docs/weak.rst b/docs/weak.rst index 55079a9cc06d2..8ca03a0b7a36c 100644 --- a/docs/weak.rst +++ b/docs/weak.rst @@ -355,29 +355,29 @@ Finalization models built around calling a method on the finalized object (such as Objective-C's :code:`-dealloc`) suffer from a number of limitations and problems: - - Since the method receives a pointer to the object being - deallocated, the implementation must guard against - attempts to resurrect the object. This may complicate - and/or slow down the system's basic reference-management - logic, which tends to be quite important for performance. - - - Since the method receives a pointer to the object being - deallocated, the implementation must leave the object at - least a minimally valid state until the user code is - complete. For example, the instance variables of a - subclass cannot be destroyed until a later phase of - destruction, because a superclass finalizer might invoke - subclass behavior. (This assumes that the dynamic type - of the object does not change during destruction, which - is an alternative that brings its own problems.) - - - Finalization code must be inherent to the object; other - objects cannot request that code be run when the object - is deallocated. For example, an object that registers - itself to observe a certain event source must explicitly - deregister itself in a finalizer; the event source cannot - simply automatically drop the object when it is - deallocated. +- Since the method receives a pointer to the object being + deallocated, the implementation must guard against + attempts to resurrect the object. This may complicate + and/or slow down the system's basic reference-management + logic, which tends to be quite important for performance. + +- Since the method receives a pointer to the object being + deallocated, the implementation must leave the object at + least a minimally valid state until the user code is + complete. For example, the instance variables of a + subclass cannot be destroyed until a later phase of + destruction, because a superclass finalizer might invoke + subclass behavior. (This assumes that the dynamic type + of the object does not change during destruction, which + is an alternative that brings its own problems.) + +- Finalization code must be inherent to the object; other + objects cannot request that code be run when the object + is deallocated. For example, an object that registers + itself to observe a certain event source must explicitly + deregister itself in a finalizer; the event source cannot + simply automatically drop the object when it is + deallocated. Optimization ------------ @@ -402,15 +402,15 @@ Proposal Overview Looking at these use-cases, there are two main thrusts: - - There is a general need to set up back references to objects. - These references must be designed for convenient use by non-expert - users. +- There is a general need to set up back references to objects. + These references must be designed for convenient use by non-expert + users. - - There are a number of more sophisticated use cases which require - notification or interruption of deallocation; these can be used in - the implementation of higher-level abstractions like weak caches. - Here it is reasonable to expect more user expertise, such that - power and flexibility should take priority over ease of use. +- There are a number of more sophisticated use cases which require + notification or interruption of deallocation; these can be used in + the implementation of higher-level abstractions like weak caches. + Here it is reasonable to expect more user expertise, such that + power and flexibility should take priority over ease of use. The second set of use cases should addressed by library types working on top of basic runtime support. @@ -439,11 +439,11 @@ variable-like declaration of reference type :code:`T`. For type-system purposes, the variables behaves like a normal variable of type :code:`Optional`, except: - - it does not maintain a +1 reference count invariant and +- it does not maintain a +1 reference count invariant and - - loading from the variable after the current referent (if present) - has started destruction will result in a :code:`Nothing` value, - indistinguishable from the normal case. +- loading from the variable after the current referent (if present) + has started destruction will result in a :code:`Nothing` value, + indistinguishable from the normal case. The semantics are quite similar to weak references in other environments (particularly Objective-C) except that the change in @@ -485,10 +485,10 @@ designed without first having a solid error-handling design. type-system purposes, the variable behaves exactly like a normal variable of type :code:`T`, except: - - it does not maintain a +1 reference count invariant and +- it does not maintain a +1 reference count invariant and - - loading from the variable after the referent has started - destruction causes an assertion failure. +- loading from the variable after the referent has started + destruction causes an assertion failure. This is a refinement of :code:`weak` focused more narrowly on the case of a back reference with relatively tight validity invariants. This @@ -498,32 +498,32 @@ references; see below. This name isn't really optimal. We've considered several different candidates: - - :code:`weak` is a poor choice because our semantics are very - different from weak references in other environments where it's - valid to access a cleared reference. Plus, we need to expose - those semantics, so the name is claimed. - - - :code:`backref` is strongly evocative of the major use case in the - static reference graph; this would encourage users to use it for - back references and to consider alternatives for other cases, both - of which I like. The latter also makes the husk-leaking - implementation (see below) more palatable. It also contrasts very - well with :code:`weak`. However, its evocativeness makes it - unwieldy to use for local reference-counting optimizations. - - - :code:`dangling` is more general than :code:`backref`, but it has - such strong negative associations that it wouldn't be unreasonable - for users to assume that it's unsafe (with all the pursuant - debugging difficulties) based on the name alone. I don't think - we want to discourage a feature that can help users build tighter - invariants on their classes. - - - :code:`unowned` is somewhat cleaner-looking, and it isn't as tied - to a specific use case, but it does not contrast with :code:`weak` - *at all*; only someone with considerable exposure to weak - references would understand why we named each one the way we did, - and even they are likely to roll their eyes at us. But it's okay - for a working proposal. +- :code:`weak` is a poor choice because our semantics are very + different from weak references in other environments where it's + valid to access a cleared reference. Plus, we need to expose + those semantics, so the name is claimed. + +- :code:`backref` is strongly evocative of the major use case in the + static reference graph; this would encourage users to use it for + back references and to consider alternatives for other cases, both + of which I like. The latter also makes the husk-leaking + implementation (see below) more palatable. It also contrasts very + well with :code:`weak`. However, its evocativeness makes it + unwieldy to use for local reference-counting optimizations. + +- :code:`dangling` is more general than :code:`backref`, but it has + such strong negative associations that it wouldn't be unreasonable + for users to assume that it's unsafe (with all the pursuant + debugging difficulties) based on the name alone. I don't think + we want to discourage a feature that can help users build tighter + invariants on their classes. + +- :code:`unowned` is somewhat cleaner-looking, and it isn't as tied + to a specific use case, but it does not contrast with :code:`weak` + *at all*; only someone with considerable exposure to weak + references would understand why we named each one the way we did, + and even they are likely to roll their eyes at us. But it's okay + for a working proposal. Asserting and Uncheckable ......................... @@ -716,7 +716,7 @@ One complication with extending :code:`weak` to value types is that generally the implementing type will need to be different from the underlying value type. Probably the best solution would be to hide the use of the implementing type from the type system outside of the -well-formedness checks for the variable; SIL-gen would lower the field +wellformedness checks for the variable; SIL-gen would lower the field to its implementing type using the appropriate protocol conformances. As long as we have convenient optional back-references, though, we @@ -857,19 +857,19 @@ become laborious and redundant, and a different mechanism is called for. In the following discussion, a *var-or-member expression* is an expression which is semantically constrained to be one of: - - A reference to a local variable-like declaration from an - enclosing context. +- A reference to a local variable-like declaration from an + enclosing context. - - A member access thereof, possibly recursively. +- A member access thereof, possibly recursively. Such expressions have two useful traits: - - They always end in an identifier which on some level meaningfully - identifies the object. +- They always end in an identifier which on some level meaningfully + identifies the object. - - Evaluating them is relatively likely (but not guaranteed) to not - have interesting side effects, and so we feel less bad about - apparently shifting their evaluation around. +- Evaluating them is relatively likely (but not guaranteed) to not + have interesting side effects, and so we feel less bad about + apparently shifting their evaluation around. Decorated Capture References ---------------------------- @@ -1141,7 +1141,7 @@ The library should definitely provide the following types: will preserve the weakness of the reference. In keeping with our design for :code:`unowned`, I think this type - should should actually be an alias to either + should actually be an alias to either :code:`SafeUnownedReference` or :code:`UnsafeUnownedReference` depending on the current component's build settings. The choice would be exported in binary modules, but for cleanliness we would diff --git a/include/swift/ABI/Class.h b/include/swift/ABI/Class.h index df17094aaf7dd..9b1c7ad858a56 100644 --- a/include/swift/ABI/Class.h +++ b/include/swift/ABI/Class.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,7 +22,7 @@ namespace swift { -/// Objetive-C class flags, stored in the ro-data. +/// Objective-C class flags, stored in the ro-data. enum class ObjCClassFlags : uint32_t { /// This class is a metaclass. Meta = 0x00001, diff --git a/include/swift/ABI/Compression.h b/include/swift/ABI/Compression.h new file mode 100644 index 0000000000000..83152a3667b96 --- /dev/null +++ b/include/swift/ABI/Compression.h @@ -0,0 +1,53 @@ +//===--- Compression.h - Defines the compression interface ------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +#ifndef SWIFT_ABI_COMPRESSION_H +#define SWIFT_ABI_COMPRESSION_H + +#include "llvm/ADT/APInt.h" +#include + +namespace swift { +namespace Compress { + +/// Compress a string using the swift codebook compression. +/// Returns a new compressed string from \p In. +std::string DecodeCBCString(llvm::StringRef In); + +/// Decompress a string using the swift codebook compression. +/// Returns a new decompressed string from \p In. +std::string EncodeCBCString(llvm::StringRef In); + +/// Character encoding kind: +/// Variable - huffman encoding using variable length characters. +/// Fixed - simple fixed length characters. +enum class EncodingKind { Variable, Fixed }; + +/// Convert the string \p In into a number using a fixed length or variable +/// length encoding. +llvm::APInt EncodeStringAsNumber(llvm::StringRef In, EncodingKind Kind); + +/// Convert the number \p In into a string using a fixed length or variable +/// length encoding. +std::string DecodeStringFromNumber(const llvm::APInt &In, EncodingKind Kind); + +/// Compress the string \p In with CBC and variable length encoding. +/// On error return an empty string. +std::string CompressName(llvm::StringRef In); + +/// Decompress the string \p, which is compressed using the swift name +/// compression. On error return an empty string. +std::string DecompressName(llvm::StringRef In); + +} // namespace Compress +} // namespace swift +#endif /* SWIFT_ABI_COMPRESSION_H */ + diff --git a/include/swift/ABI/MetadataKind.def b/include/swift/ABI/MetadataKind.def index 1e8d454288756..7747bd9def2e9 100644 --- a/include/swift/ABI/MetadataKind.def +++ b/include/swift/ABI/MetadataKind.def @@ -1,8 +1,8 @@ -//===--- MetadataKind.def --------------------------------------*- C++ -*--===// +//===--- MetadataKind.def ---------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -47,6 +47,9 @@ NOMINALTYPEMETADATAKIND(Struct, 1) /// If we add reference enums, that needs to go here. NOMINALTYPEMETADATAKIND(Enum, 2) +/// An optional type. +NOMINALTYPEMETADATAKIND(Optional, 3) + /// A type whose value is not exposed in the metadata system. METADATAKIND(Opaque, 8) diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h index 73ec6843095eb..6a91131ac1291 100644 --- a/include/swift/ABI/MetadataValues.h +++ b/include/swift/ABI/MetadataValues.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/ABI/System.h b/include/swift/ABI/System.h index f0214fd427b85..dceb3e85bc5b2 100644 --- a/include/swift/ABI/System.h +++ b/include/swift/ABI/System.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/AST.h b/include/swift/AST/AST.h index b0b68744720da..283ceb1e7d7d4 100644 --- a/include/swift/AST/AST.h +++ b/include/swift/AST/AST.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,6 +25,7 @@ #include "swift/AST/ExprHandle.h" #include "swift/AST/Initializer.h" #include "swift/AST/Module.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/Pattern.h" #include "swift/AST/Stmt.h" #include "swift/AST/Types.h" diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 7349cef227efb..d21c1d790b8fc 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -34,7 +34,6 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/TinyPtrVector.h" -#include "llvm/ADT/StringMap.h" #include "llvm/Support/Allocator.h" #include #include @@ -281,7 +280,7 @@ class ASTContext { template typename std::remove_reference::type *AllocateObjectCopy(T &&t, AllocationArena arena = AllocationArena::Permanent) const { - // This function can not be named AllocateCopy because it would always win + // This function cannot be named AllocateCopy because it would always win // overload resolution over the AllocateCopy(ArrayRef). using TNoRef = typename std::remove_reference::type; TNoRef *res = (TNoRef *) Allocate(sizeof(TNoRef), alignof(TNoRef), arena); @@ -481,6 +480,9 @@ class ASTContext { /// Retrieve the declaration of Swift._unimplemented_initializer. FuncDecl *getUnimplementedInitializerDecl(LazyResolver *resolver) const; + /// Retrieve the declaration of Swift._undefined. + FuncDecl *getUndefinedDecl(LazyResolver *resolver) const; + // Retrieve the declaration of Swift._stdlib_isOSVersionAtLeast. FuncDecl *getIsOSVersionAtLeastDecl(LazyResolver *resolver) const; @@ -587,7 +589,7 @@ class ASTContext { /// one. void loadExtensions(NominalTypeDecl *nominal, unsigned previousGeneration); - /// \brief Load the methods within the given class that that produce + /// \brief Load the methods within the given class that produce /// Objective-C class or instance methods with the given selector. /// /// \param classDecl The class in which we are searching for @objc methods. @@ -601,7 +603,7 @@ class ASTContext { /// /// \param previousGeneration The previous generation with which this /// callback was invoked. The list of methods will already contain all of - /// the results from generations up and and including \c previousGeneration. + /// the results from generations up and including \c previousGeneration. /// /// \param methods The list of @objc methods in this class that have this /// selector and are instance/class methods as requested. This list will be @@ -788,7 +790,7 @@ class ASTContext { /// Collect visible clang modules from the ClangModuleLoader. These modules are /// not necessarily loaded. - void getVisibleTopLevelClangeModules(SmallVectorImpl &Modules) const; + void getVisibleTopLevelClangModules(SmallVectorImpl &Modules) const; /// Retrieve or create the stored archetype builder for the given /// canonical generic signature and module. diff --git a/include/swift/AST/ASTNode.h b/include/swift/AST/ASTNode.h index 2570d04a8a148..da20251935ddb 100644 --- a/include/swift/AST/ASTNode.h +++ b/include/swift/AST/ASTNode.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,7 +18,6 @@ #define SWIFT_AST_AST_NODE_H #include "llvm/ADT/PointerUnion.h" -#include "swift/AST/ASTWalker.h" #include "swift/AST/TypeAlignments.h" namespace swift { @@ -27,6 +26,7 @@ namespace swift { class Decl; class SourceLoc; class SourceRange; + class ASTWalker; struct ASTNode : public llvm::PointerUnion3 { // Inherit the constructors from PointerUnion. diff --git a/include/swift/AST/ASTPrinter.h b/include/swift/AST/ASTPrinter.h index e56eac35ae955..65b0a54ca6e60 100644 --- a/include/swift/AST/ASTPrinter.h +++ b/include/swift/AST/ASTPrinter.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,10 +30,13 @@ namespace swift { /// Describes the context in which a name is being printed, which /// affects the keywords that need to be escaped. enum class PrintNameContext { - // Normal context + /// Normal context Normal, - // Generic parameter context, where 'Self' is not escaped. + /// Generic parameter context, where 'Self' is not escaped. GenericParameter, + /// Function parameter context, where keywords other than let/var/inout are + /// not escaped. + FunctionParameter, }; /// An abstract class used to print an AST. @@ -102,7 +105,7 @@ class ASTPrinter { PendingDeclLocCallback = D; } - /// To sanitize a malformatted utf8 string to a well-formatted one. + /// To sanitize a malformed utf8 string to a well-formed one. static std::string sanitizeUtf8(StringRef Text); static bool printTypeInterface(Type Ty, DeclContext *DC, std::string &Result); static bool printTypeInterface(Type Ty, DeclContext *DC, llvm::raw_ostream &Out); diff --git a/include/swift/AST/ASTVisitor.h b/include/swift/AST/ASTVisitor.h index e48987a12494f..acdcae3192adc 100644 --- a/include/swift/AST/ASTVisitor.h +++ b/include/swift/AST/ASTVisitor.h @@ -1,8 +1,8 @@ -//===-- ASTVisitor.h - Decl, Expr and Stmt Visitor --------------*- C++ -*-===// +//===--- ASTVisitor.h - Decl, Expr and Stmt Visitor -------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -27,6 +27,7 @@ #include "llvm/Support/ErrorHandling.h" namespace swift { + class ParameterList; /// ASTVisitor - This is a simple visitor class for Swift expressions. template(AA)...); \ } #include "swift/AST/Attr.def" + + bool visit(ParameterList *PL) { + return static_cast(this)->visitParameterList(PL); + } + + bool visitParameterList(ParameterList *PL) { return false; } }; diff --git a/include/swift/AST/ASTWalker.h b/include/swift/AST/ASTWalker.h index b5115f0a26b21..43fb12cb6abfe 100644 --- a/include/swift/AST/ASTWalker.h +++ b/include/swift/AST/ASTWalker.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,6 +25,7 @@ class Stmt; class Pattern; class TypeRepr; struct TypeLoc; +class ParameterList; /// \brief An abstract class used to traverse an AST. class ASTWalker { @@ -182,6 +183,18 @@ class ASTWalker { /// params in an AbstractFunctionDecl. virtual bool shouldWalkIntoFunctionGenericParams() { return false; } + /// walkToParameterListPre - This method is called when first visiting a + /// ParameterList, before walking into its parameters. If it returns false, + /// the subtree is skipped. + /// + virtual bool walkToParameterListPre(ParameterList *PL) { return true; } + + /// walkToParameterListPost - This method is called after visiting the + /// children of a parameter list. If it returns false, the remaining + /// traversal is terminated and returns failure. + virtual bool walkToParameterListPost(ParameterList *PL) { return true; } + + protected: ASTWalker() = default; ASTWalker(const ASTWalker &) = default; diff --git a/include/swift/AST/AnyFunctionRef.h b/include/swift/AST/AnyFunctionRef.h index d72c8548aabc2..01455fb313272 100644 --- a/include/swift/AST/AnyFunctionRef.h +++ b/include/swift/AST/AnyFunctionRef.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -61,10 +61,10 @@ class AnyFunctionRef { getCaptureInfo().getLocalCaptures(Result); } - ArrayRef getBodyParamPatterns() const { + ArrayRef getParameterLists() const { if (auto *AFD = TheFunction.dyn_cast()) - return AFD->getBodyParamPatterns(); - return TheFunction.get()->getParamPatterns(); + return AFD->getParameterLists(); + return TheFunction.get()->getParameterLists(); } bool hasType() const { diff --git a/include/swift/AST/ArchetypeBuilder.h b/include/swift/AST/ArchetypeBuilder.h index 2922cae789c9b..cb95ff800d0f2 100644 --- a/include/swift/AST/ArchetypeBuilder.h +++ b/include/swift/AST/ArchetypeBuilder.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -176,7 +176,7 @@ class ArchetypeBuilder { void visitPotentialArchetypes(F f); public: - /// Construct a new archtype builder. + /// Construct a new archetype builder. /// /// \param mod The module in which the builder will create archetypes. /// @@ -218,6 +218,12 @@ class ArchetypeBuilder { /// \returns true if an error occurred, false otherwise. bool addGenericParameter(GenericTypeParamDecl *GenericParam); + /// Add the requirements placed on the given abstract type parameter + /// to the given potential archetype. + /// + /// \returns true if an error occurred, false otherwise. + bool addGenericParameterRequirements(GenericTypeParamDecl *GenericParam); + /// \brief Add a new generic parameter for which there may be requirements. /// /// \returns true if an error occurred, false otherwise. @@ -245,6 +251,14 @@ class ArchetypeBuilder { bool addGenericSignature(GenericSignature *sig, bool adoptArchetypes, bool treatRequirementsAsExplicit = false); + /// \brief Get a generic signature based on the provided complete list + /// of generic parameter types. + /// + /// \returns a generic signature build based on the provided list of + /// generic parameter types. + GenericSignature * + getGenericSignature(ArrayRef genericParamsTypes); + /// Infer requirements from the given type, recursively. /// /// This routine infers requirements from a type that occurs within the @@ -275,12 +289,12 @@ class ArchetypeBuilder { /// because the type \c Dictionary cannot be formed without it. /// /// \returns true if an error occurred, false otherwise. - bool inferRequirements(Pattern *pattern, GenericParamList *genericParams); + bool inferRequirements(ParameterList *params,GenericParamList *genericParams); /// Finalize the set of requirements, performing any remaining checking /// required before generating archetypes. /// - /// \returns true if an error occurs, false otherwse. + /// \returns true if an error occurs, false otherwise. bool finalize(SourceLoc loc); /// \brief Resolve the given type to the potential archetype it names. diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def index 9f74e9e5fa195..264b72f05ac74 100644 --- a/include/swift/AST/Attr.def +++ b/include/swift/AST/Attr.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -37,7 +37,6 @@ TYPE_ATTR(noreturn) // SIL-specific attributes TYPE_ATTR(block_storage) TYPE_ATTR(box) -TYPE_ATTR(local_storage) TYPE_ATTR(sil_unowned) TYPE_ATTR(sil_unmanaged) TYPE_ATTR(sil_weak) @@ -45,6 +44,7 @@ TYPE_ATTR(error) TYPE_ATTR(out) TYPE_ATTR(in) TYPE_ATTR(inout) +TYPE_ATTR(inout_aliasable) TYPE_ATTR(in_guaranteed) TYPE_ATTR(noescape) // Only valid in sil mode. TYPE_ATTR(owned) @@ -91,7 +91,7 @@ SIMPLE_DECL_ATTR(final, Final, DECL_ATTR(objc, ObjC, OnFunc | OnClass | OnProtocol | OnVar | OnSubscript | - OnConstructor | OnDestructor | OnEnum, 3) + OnConstructor | OnDestructor | OnEnum | OnEnumElement, 3) SIMPLE_DECL_ATTR(required, Required, OnConstructor|DeclModifier, 4) @@ -139,7 +139,7 @@ DECL_ATTR(inline, Inline, OnFunc | OnConstructor, 20) DECL_ATTR(_semantics, Semantics, OnFunc | OnConstructor | OnDestructor | OnSubscript | - UserInaccessible, 21) + AllowMultipleAttributes | UserInaccessible, 21) SIMPLE_DECL_ATTR(dynamic, Dynamic, OnFunc | OnVar | OnSubscript | OnConstructor | DeclModifier, 22) @@ -239,6 +239,8 @@ SIMPLE_DECL_ATTR(indirect, Indirect, SIMPLE_DECL_ATTR(warn_unqualified_access, WarnUnqualifiedAccess, OnFunc /*| OnVar*/ | LongAttribute, 61) +DECL_ATTR(_migration_id, MigrationId, OnAnyDecl, 62) + #undef TYPE_ATTR #undef DECL_ATTR_ALIAS #undef SIMPLE_DECL_ATTR diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h index 9fcaa865b8266..36e094df4c51a 100644 --- a/include/swift/AST/Attr.h +++ b/include/swift/AST/Attr.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,6 +19,8 @@ #include "swift/Basic/SourceLoc.h" #include "swift/Basic/UUID.h" +#include "swift/Basic/STLExtras.h" +#include "swift/Basic/Range.h" #include "swift/AST/Identifier.h" #include "swift/AST/KnownProtocols.h" #include "swift/AST/Ownership.h" @@ -462,7 +464,7 @@ class DeclAttribute : public AttributeBase { static bool canAttributeAppearOnDecl(DeclAttrKind DK, const Decl *D); /// Returns true if multiple instances of an attribute kind - /// can appear on a delcaration. + /// can appear on a declaration. static bool allowMultipleAttributes(DeclAttrKind DK) { return getOptions(DK) & AllowMultipleAttributes; } @@ -642,7 +644,7 @@ enum class MinVersionComparison { Unavailable, /// The entity might be unavailable, because it was introduced after - /// the minimimum version. + /// the minimum version. PotentiallyUnavailable, /// The entity has been obsoleted. @@ -1148,6 +1150,31 @@ class WarnUnusedResultAttr : public DeclAttribute { } }; +/// The internal @_migration_id attribute, which is used to keep track of stdlib +/// changes for migration purposes. +class MigrationIdAttr : public DeclAttribute { + StringRef Ident; + StringRef PatternId; + +public: + MigrationIdAttr(SourceLoc atLoc, SourceLoc attrLoc, SourceLoc lParenLoc, + StringRef ident, StringRef patternId, + SourceLoc rParenLoc, bool implicit) + : DeclAttribute(DAK_MigrationId, attrLoc, + SourceRange(atLoc, rParenLoc), implicit), + Ident(ident), PatternId(patternId) {} + + /// Retrieve the migration identifier associated with the symbol. + StringRef getIdent() const { return Ident; } + + /// Retrieve pattern identifier associated with the symbol. + StringRef getPatternId() const { return PatternId; } + + static bool classof(const DeclAttribute *DA) { + return DA->getKind() == DAK_MigrationId; + } +}; + /// \brief Attributes that may be applied to declarations. class DeclAttributes { /// Linked list of declaration attributes. @@ -1258,6 +1285,34 @@ class DeclAttributes { return nullptr; } +private: + /// Predicate used to filter MatchingAttributeRange. + template struct ToAttributeKind { + ToAttributeKind() {} + + Optional + operator()(const DeclAttribute *Attr) const { + if (isa(Attr) && (Attr->isValid() || AllowInvalid)) + return Attr; + return None; + } + }; + +public: + template + using AttributeKindRange = + OptionalTransformRange, + ToAttributeKind, + const_iterator>; + + /// Return a range with all attributes in DeclAttributes with AttrKind + /// ATTR. + template + AttributeKindRange getAttributes() const { + return AttributeKindRange( + make_range(begin(), end()), ToAttributeKind()); + } + // Remove the given attribute from the list of attributes. Used when // the attribute was semantically invalid. void removeAttribute(const DeclAttribute *attr) { diff --git a/include/swift/AST/Availability.h b/include/swift/AST/Availability.h index 731edec4f4f34..cd38482080e99 100644 --- a/include/swift/AST/Availability.h +++ b/include/swift/AST/Availability.h @@ -1,8 +1,8 @@ -//===--- Availability.h - Swift Availability Structures -----*- C++ -*-===// +//===--- Availability.h - Swift Availability Structures ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -35,7 +35,7 @@ class VersionRange { // The concretization of lattice elements is: // Empty: empty // All: all versions - // x.y.x: all versions greater than or equal to to x.y.z + // x.y.x: all versions greater than or equal to x.y.z enum class ExtremalRange { Empty, All }; @@ -117,7 +117,7 @@ class VersionRange { } /// Mutates this range to be the union of itself and Other. This is the - /// join operator (least upper bound) in the veresion range lattice. + /// join operator (least upper bound) in the version range lattice. void unionWith(const VersionRange &Other) { // With the existing lattice this operation is precise. If the lattice // is ever extended it is important that this operation be an @@ -242,9 +242,9 @@ class AvailabilityInference { /// We assume a declaration without an annotation is always available. static VersionRange availableRange(const Decl *D, ASTContext &C); - /// \brief Returns the version range on which the declaration for which - /// declaration is annotated as available, or None if the declaration - /// has not availability annotation. + /// \brief Returns the version range for which the declaration + /// is annotated as available, or None if the declaration + /// has no availability annotation. static Optional annotatedAvailableRange(const Decl *D, ASTContext &C); diff --git a/include/swift/AST/AvailabilitySpec.h b/include/swift/AST/AvailabilitySpec.h index 23c28e409ee31..7bc9b9876bb5a 100644 --- a/include/swift/AST/AvailabilitySpec.h +++ b/include/swift/AST/AvailabilitySpec.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -97,7 +97,7 @@ class VersionConstraintAvailabilitySpec : public AvailabilitySpec { /// to new platforms. Because new platforms typically branch from /// existing platforms, the wildcard allows an #available() check to do the /// "right" thing (executing the guarded branch) on the new platform without -/// requiring a modification to every availablity guard in the program. Note +/// requiring a modification to every availability guard in the program. Note /// that we still do compile-time availability checking with '*', so the /// compiler will still catch references to potentially unavailable symbols. class OtherPlatformAvailabilitySpec : public AvailabilitySpec { diff --git a/include/swift/AST/Builtins.def b/include/swift/AST/Builtins.def index a6592e5eb4f5f..9437d8f7f683b 100644 --- a/include/swift/AST/Builtins.def +++ b/include/swift/AST/Builtins.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -353,6 +353,11 @@ BUILTIN_RUNTIME_CALL(UnexpectedError, "unexpectedError", "") /// errorInMain: ErrorType -> () BUILTIN_RUNTIME_CALL(ErrorInMain, "errorInMain", "") +/// IsOptionalType : T.Type -> Bool +/// This builtin takes a metatype and returns true if the metatype's +/// nominal type is Optional. +BUILTIN_RUNTIME_CALL(IsOptionalType, "isOptional", "") + #undef BUILTIN_RUNTIME_CALL // BUILTIN_MISC_OPERATION - Miscellaneous operations without a unifying class. diff --git a/include/swift/AST/Builtins.h b/include/swift/AST/Builtins.h index 66b74381686b8..07933bd22f0d9 100644 --- a/include/swift/AST/Builtins.h +++ b/include/swift/AST/Builtins.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -91,7 +91,7 @@ getLLVMIntrinsicIDForBuiltinWithOverflow(BuiltinValueKind ID); /// Returns null if the name does not identifier a known builtin value. ValueDecl *getBuiltinValueDecl(ASTContext &Context, Identifier Name); -/// \brief Returns the name of a builtin declaration given an builtin ID. +/// \brief Returns the name of a builtin declaration given a builtin ID. StringRef getBuiltinName(BuiltinValueKind ID); /// \brief The information identifying the builtin - its kind and types. diff --git a/include/swift/AST/CanTypeVisitor.h b/include/swift/AST/CanTypeVisitor.h index 345706d33e94b..0904ee40d2232 100644 --- a/include/swift/AST/CanTypeVisitor.h +++ b/include/swift/AST/CanTypeVisitor.h @@ -1,8 +1,8 @@ -//===-- CanTypeVisitor.h - TypeVisitor specialization -----------*- C++ -*-===// +//===--- CanTypeVisitor.h - TypeVisitor specialization ----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/CaptureInfo.h b/include/swift/AST/CaptureInfo.h index d60af9c679861..8ca4faab21d7f 100644 --- a/include/swift/AST/CaptureInfo.h +++ b/include/swift/AST/CaptureInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/ClangModuleLoader.h b/include/swift/AST/ClangModuleLoader.h index cbc9266e2ae1e..f9062a26d0512 100644 --- a/include/swift/AST/ClangModuleLoader.h +++ b/include/swift/AST/ClangModuleLoader.h @@ -1,8 +1,8 @@ -//===--- ClangModuleLoader.h - Clang Module Loader Interface --*- C++ -*- -===// +//===--- ClangModuleLoader.h - Clang Module Loader Interface ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/Comment.h b/include/swift/AST/Comment.h index 50e8793a97343..3018ff77bafc3 100644 --- a/include/swift/AST/Comment.h +++ b/include/swift/AST/Comment.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/ConcreteDeclRef.h b/include/swift/AST/ConcreteDeclRef.h index 8afa6b9670ad3..abddc14eaccce 100644 --- a/include/swift/AST/ConcreteDeclRef.h +++ b/include/swift/AST/ConcreteDeclRef.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DebuggerClient.h b/include/swift/AST/DebuggerClient.h index 6f6d9c523220b..70dcc573736bc 100644 --- a/include/swift/AST/DebuggerClient.h +++ b/include/swift/AST/DebuggerClient.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index be729431cf27e..8f94f8e7b25c1 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,29 +17,14 @@ #ifndef SWIFT_DECL_H #define SWIFT_DECL_H -#include "swift/AST/Attr.h" #include "swift/AST/CaptureInfo.h" -#include "swift/AST/DeclContext.h" #include "swift/AST/DefaultArgumentKind.h" #include "swift/AST/GenericSignature.h" -#include "swift/AST/KnownProtocols.h" -#include "swift/AST/Identifier.h" #include "swift/AST/LazyResolver.h" -#include "swift/AST/Requirement.h" -#include "swift/AST/Substitution.h" -#include "swift/AST/Type.h" -#include "swift/AST/TypeLoc.h" #include "swift/Basic/OptionalEnum.h" #include "swift/Basic/Range.h" -#include "swift/Basic/SourceLoc.h" -#include "swift/Basic/STLExtras.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/Hashing.h" -#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallPtrSet.h" -#include namespace clang { class Decl; @@ -76,6 +61,7 @@ namespace swift { class NameAliasType; class EnumCaseDecl; class EnumElementDecl; + class ParameterList; class Pattern; struct PrintOptions; class ProtocolDecl; @@ -209,7 +195,7 @@ enum class CircularityCheck { Checked }; -/// Keeps track of whrther a given class inherits initializers from its +/// Keeps track of whether a given class inherits initializers from its /// superclass. enum class StoredInheritsSuperclassInits { /// We have not yet checked. @@ -386,8 +372,8 @@ class alignas(1 << DeclAlignInBits) Decl { /// \see AbstractFunctionDecl::BodyKind unsigned BodyKind : 3; - /// Number of curried parameter patterns (tuples). - unsigned NumParamPatterns : 6; + /// Number of curried parameter lists. + unsigned NumParameterLists : 6; /// Whether we are overridden later. unsigned Overridden : 1; @@ -573,8 +559,11 @@ class alignas(1 << DeclAlignInBits) Decl { unsigned : NumTypeDeclBits; unsigned Recursive : 1; + + /// Whether or not this declaration is currently being type-checked. + unsigned BeingTypeChecked : 1; }; - enum { NumAssociatedTypeDeclBits = NumTypeDeclBits + 1 }; + enum { NumAssociatedTypeDeclBits = NumTypeDeclBits + 2 }; static_assert(NumAssociatedTypeDeclBits <= 32, "fits in an unsigned"); class ImportDeclBitfields { @@ -868,7 +857,7 @@ class alignas(1 << DeclAlignInBits) Decl { // Only allow allocation of Decls using the allocator in ASTContext // or by doing a placement new. - void *operator new(size_t Bytes, ASTContext &C, + void *operator new(size_t Bytes, const ASTContext &C, unsigned Alignment = alignof(Decl)); void *operator new(size_t Bytes, void *Mem) { assert(Mem); @@ -1556,7 +1545,7 @@ class ImportDecl : public Decl { /// Returns the most appropriate import kind for the given list of decls. /// - /// If the list is non-homogenous, or if there is more than one decl that + /// If the list is non-homogeneous, or if there is more than one decl that /// cannot be overloaded, returns None. static Optional findBestImportKind(ArrayRef Decls); @@ -2174,6 +2163,7 @@ class ValueDecl : public Decl { /// Retrieve the full name of the declaration. /// TODO: Rename to getName? DeclName getFullName() const { return Name; } + void setName(DeclName name) { Name = name; } /// Retrieve the base name of the declaration, ignoring any argument /// names. @@ -2239,16 +2229,6 @@ class ValueDecl : public Decl { /// If \p DC is null, returns true only if this declaration is public. bool isAccessibleFrom(const DeclContext *DC) const; - /// Get the innermost declaration context that can provide generic - /// parameters used within this declaration. - DeclContext *getPotentialGenericDeclContext(); - - /// Get the innermost declaration context that can provide generic - /// parameters used within this declaration. - const DeclContext *getPotentialGenericDeclContext() const { - return const_cast(this)->getPotentialGenericDeclContext(); - } - /// Retrieve the "interface" type of this value, which is the type used when /// the declaration is viewed from the outside. For a generic function, /// this will have generic function type using generic parameters rather than @@ -2402,7 +2382,7 @@ class TypeAliasDecl : public TypeDecl { /// The type that represents this (sugared) name alias. mutable NameAliasType *AliasTy; - SourceLoc TypeAliasLoc; // The location of the 'typalias' keyword + SourceLoc TypeAliasLoc; // The location of the 'typealias' keyword TypeLoc UnderlyingTy; public: @@ -2605,6 +2585,14 @@ class AssociatedTypeDecl : public AbstractTypeParamDecl { void setIsRecursive() { AssociatedTypeDeclBits.Recursive = true; } bool isRecursive() { return AssociatedTypeDeclBits.Recursive; } + /// Whether the declaration is currently being validated. + bool isBeingTypeChecked() { return AssociatedTypeDeclBits.BeingTypeChecked; } + + /// Toggle whether or not the declaration is being validated. + void setIsBeingTypeChecked(bool ibt = true) { + AssociatedTypeDeclBits.BeingTypeChecked = ibt; + } + static bool classof(const Decl *D) { return D->getKind() == DeclKind::AssociatedType; } @@ -2797,7 +2785,7 @@ class NominalTypeDecl : public TypeDecl, public DeclContext, return ValidatingGenericSignature; } - /// \brief Returns true if this this decl contains delayed value or protocol + /// \brief Returns true if this decl contains delayed value or protocol /// declarations. bool hasDelayedMembers() const { return NominalTypeDeclBits.HasDelayedMembers; @@ -2860,9 +2848,6 @@ class NominalTypeDecl : public TypeDecl, public DeclContext, return GenericSig; } - /// Mark generic type signature as invalid. - void markInvalidGenericSignature(); - /// getDeclaredType - Retrieve the type declared by this entity. Type getDeclaredType() const { return DeclaredTy; } @@ -3263,17 +3248,19 @@ class ClassDecl : public NominalTypeDecl { return ClassDeclBits.Foreign; } void setForeign(bool isForeign = true) { - ClassDeclBits.Foreign = true; + ClassDeclBits.Foreign = isForeign; } /// Find a method of a class that overrides a given method. /// Return nullptr, if no such method exists. - FuncDecl *findOverridingDecl(const FuncDecl *method) const; + AbstractFunctionDecl *findOverridingDecl( + const AbstractFunctionDecl *method) const; /// Find a method implementation which will be used when a given method /// is invoked on an instance of this class. This implementation may stem /// either from a class itself or its direct or indirect superclasses. - FuncDecl *findImplementingMethod(const FuncDecl *method) const; + AbstractFunctionDecl *findImplementingMethod( + const AbstractFunctionDecl *method) const; /// True if the class has a destructor. /// @@ -3947,7 +3934,7 @@ class AbstractStorageDecl : public ValueDecl { return getAddressorInfo().MutableAddress; } - /// \brief Return the approproiate addressor for the given access kind. + /// \brief Return the appropriate addressor for the given access kind. FuncDecl *getAddressorForAccess(AccessKind accessKind) const { if (accessKind == AccessKind::Read) return getAddressor(); @@ -4022,7 +4009,7 @@ class AbstractStorageDecl : public ValueDecl { /// VarDecl - 'var' and 'let' declarations. class VarDecl : public AbstractStorageDecl { protected: - llvm::PointerUnion3 ParentPattern; + llvm::PointerUnion ParentPattern; VarDecl(DeclKind Kind, bool IsStatic, bool IsLet, SourceLoc NameLoc, Identifier Name, Type Ty, DeclContext *DC) @@ -4075,9 +4062,9 @@ class VarDecl : public AbstractStorageDecl { ParentPattern = PBD; } - /// Return the Pattern involved in initializing this VarDecl. Recall that the - /// Pattern may be involved in initializing more than just this one vardecl - /// though. For example, if this is a VarDecl for "x", the pattern may be + /// Return the Pattern involved in initializing this VarDecl. However, recall + /// that the Pattern may be involved in initializing more than just this one + /// vardecl. For example, if this is a VarDecl for "x", the pattern may be /// "(x, y)" and the initializer on the PatternBindingDecl may be "(1,2)" or /// "foo()". /// @@ -4095,7 +4082,7 @@ class VarDecl : public AbstractStorageDecl { ParentPattern = S; } - /// Return the initializer involved in this VarDecl. However, Recall that the + /// Return the initializer involved in this VarDecl. Recall that the /// initializer may be involved in initializing more than just this one /// vardecl though. For example, if this is a VarDecl for "x", the pattern /// may be "(x, y)" and the initializer on the PatternBindingDecl may be @@ -4163,7 +4150,7 @@ class VarDecl : public AbstractStorageDecl { void emitLetToVarNoteIfSimple(DeclContext *UseDC) const; /// Returns true if the name is the self identifier and is implicit. - bool isImplicitSelf() const; + bool isSelfParameter() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { @@ -4176,14 +4163,32 @@ class ParamDecl : public VarDecl { Identifier ArgumentName; SourceLoc ArgumentNameLoc; + /// This is the type specified, including location information. + TypeLoc typeLoc; + + /// The default value, if any, along with whether this is varargs. + llvm::PointerIntPair DefaultValueAndIsVariadic; + + /// True if the type is implicitly specified in the source, but this has an + /// apparently valid typeRepr. This is used in accessors, which look like: + /// set (value) { + /// but need to get the typeRepr from the property as a whole so Sema can + /// resolve the type. + bool IsTypeLocImplicit = false; + + /// Information about a symbolic default argument, like __FILE__. + DefaultArgumentKind defaultArgumentKind = DefaultArgumentKind::None; + public: ParamDecl(bool isLet, SourceLoc argumentNameLoc, Identifier argumentName, SourceLoc parameterNameLoc, - Identifier parameterName, Type ty, DeclContext *dc) - : VarDecl(DeclKind::Param, /*IsState=*/false, isLet, parameterNameLoc, - parameterName, ty, dc), - ArgumentName(argumentName), ArgumentNameLoc(argumentNameLoc) { } + Identifier parameterName, Type ty, DeclContext *dc); + /// Clone constructor, allocates a new ParamDecl identical to the first. + /// Intentionally not defined as a typical copy constructor to avoid + /// accidental copies. + ParamDecl(ParamDecl *PD); + /// Retrieve the argument (API) name for this function parameter. Identifier getArgumentName() const { return ArgumentName; } @@ -4192,21 +4197,56 @@ class ParamDecl : public VarDecl { /// The resulting source location will be valid if the argument name /// was specified separately from the parameter name. SourceLoc getArgumentNameLoc() const { return ArgumentNameLoc; } + + TypeLoc &getTypeLoc() { return typeLoc; } + TypeLoc getTypeLoc() const { return typeLoc; } - SourceRange getSourceRange() const { - if (ArgumentNameLoc.isValid() && getNameLoc().isInvalid()) - return ArgumentNameLoc; - if (ArgumentNameLoc.isInvalid() && getNameLoc().isValid()) - return getNameLoc(); - return SourceRange(ArgumentNameLoc, getNameLoc()); + bool isTypeLocImplicit() const { return IsTypeLocImplicit; } + void setIsTypeLocImplicit(bool val) { IsTypeLocImplicit = val; } + + bool isDefaultArgument() const { + return defaultArgumentKind != DefaultArgumentKind::None; } - - Pattern *getParamParentPattern() const { - return ParentPattern.dyn_cast(); + DefaultArgumentKind getDefaultArgumentKind() const { + return defaultArgumentKind; } - void setParamParentPattern(Pattern *Pat) { - ParentPattern = Pat; + void setDefaultArgumentKind(DefaultArgumentKind K) { + defaultArgumentKind = K; } + + void setDefaultValue(ExprHandle *H) { + DefaultValueAndIsVariadic.setPointer(H); + } + ExprHandle *getDefaultValue() const { + return DefaultValueAndIsVariadic.getPointer(); + } + /// Whether or not this parameter is varargs. + bool isVariadic() const { return DefaultValueAndIsVariadic.getInt(); } + void setVariadic(bool value = true) {DefaultValueAndIsVariadic.setInt(value);} + + /// Remove the type of this varargs element designator, without the array + /// type wrapping it. A parameter like "Int..." will have formal parameter + /// type of "[Int]" and this returns "Int". + static Type getVarargBaseTy(Type VarArgT); + + /// Remove the type of this varargs element designator, without the array + /// type wrapping it. + Type getVarargBaseTy() const { + assert(isVariadic()); + return getVarargBaseTy(getType()); + } + + SourceRange getSourceRange() const; + + /// Create an implicit 'self' decl for a method in the specified decl context. + /// If 'static' is true, then this is self for a static method in the type. + /// + /// Note that this decl is created, but it is returned with an incorrect + /// DeclContext that needs to be set correctly. This is automatically handled + /// when a function is created with this as part of its argument list. + /// + static ParamDecl *createSelf(SourceLoc loc, DeclContext *DC, + bool isStatic = false, bool isInOut = false); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { @@ -4254,15 +4294,16 @@ enum class ObjCSubscriptKind { /// A given type can have multiple subscript declarations, so long as the /// signatures (indices and element type) are distinct. /// -class SubscriptDecl : public AbstractStorageDecl { +class SubscriptDecl : public AbstractStorageDecl, public DeclContext { SourceLoc ArrowLoc; - Pattern *Indices; + ParameterList *Indices; TypeLoc ElementTy; public: - SubscriptDecl(DeclName Name, SourceLoc SubscriptLoc, Pattern *Indices, + SubscriptDecl(DeclName Name, SourceLoc SubscriptLoc, ParameterList *Indices, SourceLoc ArrowLoc, TypeLoc ElementTy, DeclContext *Parent) : AbstractStorageDecl(DeclKind::Subscript, Parent, Name, SubscriptLoc), + DeclContext(DeclContextKind::SubscriptDecl, Parent), ArrowLoc(ArrowLoc), Indices(nullptr), ElementTy(ElementTy) { setIndices(Indices); } @@ -4272,9 +4313,9 @@ class SubscriptDecl : public AbstractStorageDecl { SourceRange getSourceRange() const; /// \brief Retrieve the indices for this subscript operation. - Pattern *getIndices() { return Indices; } - const Pattern *getIndices() const { return Indices; } - void setIndices(Pattern *p); + ParameterList *getIndices() { return Indices; } + const ParameterList *getIndices() const { return Indices; } + void setIndices(ParameterList *p); /// Retrieve the type of the indices. Type getIndicesType() const; @@ -4303,6 +4344,13 @@ class SubscriptDecl : public AbstractStorageDecl { static bool classof(const Decl *D) { return D->getKind() == DeclKind::Subscript; } + + static bool classof(const DeclContext *DC) { + return DC->getContextKind() == DeclContextKind::SubscriptDecl; + } + + using DeclContext::operator new; + using Decl::getASTContext; }; /// \brief Base class for function-like declarations. @@ -4358,31 +4406,41 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext { }; GenericParamList *GenericParams; + GenericSignature *GenericSig; CaptureInfo Captures; AbstractFunctionDecl(DeclKind Kind, DeclContext *Parent, DeclName Name, - SourceLoc NameLoc, unsigned NumParamPatterns, + SourceLoc NameLoc, unsigned NumParameterLists, GenericParamList *GenericParams) : ValueDecl(Kind, Parent, Name, NameLoc), DeclContext(DeclContextKind::AbstractFunctionDecl, Parent), - Body(nullptr), GenericParams(nullptr) { + Body(nullptr), GenericParams(nullptr), GenericSig(nullptr) { setBodyKind(BodyKind::None); setGenericParams(GenericParams); - AbstractFunctionDeclBits.NumParamPatterns = NumParamPatterns; + AbstractFunctionDeclBits.NumParameterLists = NumParameterLists; AbstractFunctionDeclBits.Overridden = false; // Verify no bitfield truncation. - assert(AbstractFunctionDeclBits.NumParamPatterns == NumParamPatterns); + assert(AbstractFunctionDeclBits.NumParameterLists == NumParameterLists); } - MutableArrayRef getBodyParamBuffer(); - void setBodyKind(BodyKind K) { AbstractFunctionDeclBits.BodyKind = unsigned(K); } void setGenericParams(GenericParamList *GenericParams); + +public: + void setGenericSignature(GenericSignature *GenericSig) { + assert(!this->GenericSig && "already have signature?"); + this->GenericSig = GenericSig; + } + + GenericSignature *getGenericSignature() const { + return GenericSig; + } + public: // FIXME: Hack that provides names with keyword arguments for accessors. DeclName getEffectiveFullName() const; @@ -4418,14 +4476,14 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext { } void setBody(BraceStmt *S, BodyKind NewBodyKind = BodyKind::Parsed) { assert(getBodyKind() != BodyKind::Skipped && - "can not set a body if it was skipped"); + "cannot set a body if it was skipped"); Body = S; setBodyKind(NewBodyKind); } /// \brief Note that the body was skipped for this function. Function body - /// can not be attached after this call. + /// cannot be attached after this call. void setBodySkipped(SourceRange bodyRange) { assert(getBodyKind() == BodyKind::None); BodyRange = bodyRange; @@ -4499,8 +4557,8 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext { /// Determine whether the name of the ith argument is an API name by default. bool argumentNameIsAPIByDefault(unsigned i) const; - unsigned getNumParamPatterns() const { - return AbstractFunctionDeclBits.NumParamPatterns; + unsigned getNumParameterLists() const { + return AbstractFunctionDeclBits.NumParameterLists; } /// \brief Returns the "natural" number of argument clauses taken by this @@ -4525,7 +4583,7 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext { /// func const(x : Int) -> () -> Int { return { x } } // NAC==1 /// \endcode unsigned getNaturalArgumentCount() const { - return getNumParamPatterns(); + return getNumParameterLists(); } /// \brief Returns the parameter pattern(s) for the function definition that @@ -4533,24 +4591,24 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext { /// /// The number of "top-level" elements in this pattern will match the number /// of argument names in the compound name of the function or constructor. - MutableArrayRef getBodyParamPatterns() { - return getBodyParamBuffer(); + MutableArrayRef getParameterLists(); + ArrayRef getParameterLists() const { + auto paramLists = + const_cast(this)->getParameterLists(); + return ArrayRef(paramLists.data(),paramLists.size()); + } + ParameterList *getParameterList(unsigned i) { + return getParameterLists()[i]; } - ArrayRef getBodyParamPatterns() const { - auto Patterns = - const_cast(this)->getBodyParamBuffer(); - return ArrayRef(Patterns.data(), Patterns.size()); + const ParameterList *getParameterList(unsigned i) const { + return getParameterLists()[i]; } /// \brief If this is a method in a type or extension thereof, compute /// and return the type to be used for the 'self' argument of the type, or an /// empty Type() if no 'self' argument should exist. This can /// only be used after name binding has resolved types. - /// - /// \param outerGenericParams If non-NULL, and this function is an instance - /// of a generic type, will be set to the generic parameter list of that - /// generic type. - Type computeSelfType(GenericParamList **outerGenericParams = nullptr); + Type computeSelfType(); /// \brief If this is a method in a type or extension thereof, compute /// and return the type to be used for the 'self' argument of the interface @@ -4566,7 +4624,10 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext { /// /// Note that some functions don't have an implicit 'self' decl, for example, /// free functions. In this case nullptr is returned. - VarDecl *getImplicitSelfDecl() const; + const ParamDecl *getImplicitSelfDecl() const { + return const_cast(this)->getImplicitSelfDecl(); + } + ParamDecl *getImplicitSelfDecl(); /// \brief Retrieve the set of parameters to a generic function, or null if /// this function is not generic. @@ -4579,6 +4640,10 @@ class AbstractFunctionDecl : public ValueDecl, public DeclContext { /// Retrieve the declaration that this method overrides, if any. AbstractFunctionDecl *getOverriddenDecl() const; + /// Returns true if a function declaration overrides a given + /// method from its direct or indirect superclass. + bool isOverridingDecl(const AbstractFunctionDecl *method) const; + /// Whether the declaration is later overridden in the module /// /// Overriddes are resolved during type checking; only query this field after @@ -4627,7 +4692,7 @@ class FuncDecl : public AbstractFunctionDecl { SourceLoc StaticLoc; // Location of the 'static' token or invalid. SourceLoc FuncLoc; // Location of the 'func' token. SourceLoc ThrowsLoc; // Location of the 'throws' token. - SourceLoc AccessorKeywordLoc; // Location of the accessor keyword token, e,g. 'set'. + SourceLoc AccessorKeywordLoc; // Location of the accessor keyword, e.g. 'set'. TypeLoc FnRetType; @@ -4646,23 +4711,24 @@ class FuncDecl : public AbstractFunctionDecl { /// which property and what kind of accessor. llvm::PointerIntPair AccessorDecl; llvm::PointerUnion OverriddenOrDerivedForDecl; - llvm::PointerIntPair OperatorAndAddressorKind; + llvm::PointerIntPair OperatorAndAddressorKind; FuncDecl(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, SourceLoc FuncLoc, DeclName Name, SourceLoc NameLoc, SourceLoc ThrowsLoc, SourceLoc AccessorKeywordLoc, - unsigned NumParamPatterns, + unsigned NumParameterLists, GenericParamList *GenericParams, Type Ty, DeclContext *Parent) : AbstractFunctionDecl(DeclKind::Func, Parent, Name, NameLoc, - NumParamPatterns, GenericParams), + NumParameterLists, GenericParams), StaticLoc(StaticLoc), FuncLoc(FuncLoc), ThrowsLoc(ThrowsLoc), AccessorKeywordLoc(AccessorKeywordLoc), OverriddenOrDerivedForDecl(), OperatorAndAddressorKind(nullptr, AddressorKind::NotAddressor) { FuncDeclBits.IsStatic = StaticLoc.isValid() || getName().isOperator(); FuncDeclBits.StaticSpelling = static_cast(StaticSpelling); - assert(NumParamPatterns > 0 && "Must have at least an empty tuple arg"); + assert(NumParameterLists > 0 && "Must have at least an empty tuple arg"); setType(Ty); FuncDeclBits.Mutating = false; FuncDeclBits.HasDynamicSelf = false; @@ -4678,7 +4744,7 @@ class FuncDecl : public AbstractFunctionDecl { SourceLoc NameLoc, SourceLoc ThrowsLoc, SourceLoc AccessorKeywordLoc, GenericParamList *GenericParams, Type Ty, - unsigned NumParamPatterns, + unsigned NumParameterLists, DeclContext *Parent, ClangNode ClangN); @@ -4690,7 +4756,7 @@ class FuncDecl : public AbstractFunctionDecl { SourceLoc NameLoc, SourceLoc ThrowsLoc, SourceLoc AccessorKeywordLoc, GenericParamList *GenericParams, Type Ty, - unsigned NumParamPatterns, + unsigned NumParameterLists, DeclContext *Parent); static FuncDecl *create(ASTContext &Context, SourceLoc StaticLoc, @@ -4698,7 +4764,7 @@ class FuncDecl : public AbstractFunctionDecl { SourceLoc FuncLoc, DeclName Name, SourceLoc NameLoc, SourceLoc ThrowsLoc, SourceLoc AccessorKeywordLoc, GenericParamList *GenericParams, - Type Ty, ArrayRef BodyParams, + Type Ty, ArrayRef ParameterLists, TypeLoc FnRetType, DeclContext *Parent, ClangNode ClangN = ClangNode()); @@ -4721,6 +4787,25 @@ class FuncDecl : public AbstractFunctionDecl { FuncDeclBits.Mutating = Mutating; } + /// \brief Returns the parameter lists(s) for the function definition. + /// + /// The number of "top-level" elements will match the number of argument names + /// in the compound name of the function or constructor. + MutableArrayRef getParameterLists() { + auto Ptr = reinterpret_cast(cast(this) + 1); + return { Ptr, getNumParameterLists() }; + } + ArrayRef getParameterLists() const { + return AbstractFunctionDecl::getParameterLists(); + } + ParameterList *getParameterList(unsigned i) { + return getParameterLists()[i]; + } + const ParameterList *getParameterList(unsigned i) const { + return getParameterLists()[i]; + } + + bool getHaveSearchedForCommonOverloadReturnType() { return HaveSearchedForCommonOverloadReturnType; } @@ -4738,7 +4823,7 @@ class FuncDecl : public AbstractFunctionDecl { /// attribute. For example a "mutating set" accessor. bool isExplicitNonMutating() const; - void setDeserializedSignature(ArrayRef BodyParams, + void setDeserializedSignature(ArrayRef ParameterLists, TypeLoc FnRetType); SourceLoc getStaticLoc() const { return StaticLoc; } @@ -4784,22 +4869,24 @@ class FuncDecl : public AbstractFunctionDecl { } /// isUnaryOperator - Determine whether this is a unary operator - /// implementation, in other words, the name of the function is an operator, - /// and the argument list consists syntactically of a single-element tuple - /// pattern. This check is syntactic rather than type-based in order to allow + /// implementation. This check is a syntactic rather than type-based check, + /// which looks at the number of parameters specified, in order to allow /// for the definition of unary operators on tuples, as in: - /// func [prefix] + (_:(a:Int, b:Int)) + /// + /// prefix func + (param : (a:Int, b:Int)) + /// /// This also allows the unary-operator-ness of a func decl to be determined /// prior to type checking. bool isUnaryOperator() const; /// isBinaryOperator - Determine whether this is a binary operator - /// implementation, in other words, the name of the function is an operator, - /// and the argument list consists syntactically of a two-element tuple - /// pattern. This check is syntactic rather than type-based in order to - /// distinguish a binary operator from a unary operator on tuples, as in: - /// func [prefix] + (_:(a:Int, b:Int)) // unary operator +(1,2) - /// func [infix] + (a:Int, b:Int) // binary operator 1 + 2 + /// implementation. This check is a syntactic rather than type-based check, + /// which looks at the number of parameters specified, in order to allow + /// distinguishing a binary operator from a unary operator on tuples, as in: + /// + /// prefix func + (_:(a:Int, b:Int)) // unary operator +(1,2) + /// infix func + (a:Int, b:Int) // binary operator 1 + 2 + /// /// This also allows the binary-operator-ness of a func decl to be determined /// prior to type checking. bool isBinaryOperator() const; @@ -4918,10 +5005,6 @@ class FuncDecl : public AbstractFunctionDecl { FuncDeclBits.ForcedStaticDispatch = flag; } - /// Returns true if a function declaration overrides a given - /// method from its direct or indirect superclass. - bool isOverridingDecl(const FuncDecl *method) const; - static bool classof(const Decl *D) { return D->getKind() == DeclKind::Func; } static bool classof(const AbstractFunctionDecl *D) { return classof(static_cast(D)); @@ -5134,8 +5217,6 @@ enum class CtorInitializerKind { /// } /// \endcode class ConstructorDecl : public AbstractFunctionDecl { - friend class AbstractFunctionDecl; - /// The failability of this initializer, which is an OptionalTypeKind. unsigned Failability : 2; @@ -5145,7 +5226,7 @@ class ConstructorDecl : public AbstractFunctionDecl { // Location of the 'throws' token. SourceLoc ThrowsLoc; - Pattern *BodyParams[2]; + ParameterList *ParameterLists[2]; /// The type of the initializing constructor. Type InitializerType; @@ -5164,11 +5245,11 @@ class ConstructorDecl : public AbstractFunctionDecl { public: ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc, OptionalTypeKind Failability, SourceLoc FailabilityLoc, - Pattern *SelfBodyParam, Pattern *BodyParams, + ParamDecl *selfParam, ParameterList *BodyParams, GenericParamList *GenericParams, SourceLoc throwsLoc, DeclContext *Parent); - void setBodyParams(Pattern *selfPattern, Pattern *bodyParams); + void setParameterLists(ParamDecl *selfParam, ParameterList *bodyParams); SourceLoc getConstructorLoc() const { return getNameLoc(); } SourceLoc getStartLoc() const { return getConstructorLoc(); } @@ -5193,6 +5274,26 @@ class ConstructorDecl : public AbstractFunctionDecl { Expr *getSuperInitCall() { return CallToSuperInit; } void setSuperInitCall(Expr *CallExpr) { CallToSuperInit = CallExpr; } + MutableArrayRef getParameterLists() { + return { ParameterLists, 2 }; + } + ArrayRef getParameterLists() const { + return AbstractFunctionDecl::getParameterLists(); + } + ParameterList *getParameterList(unsigned i) { + return getParameterLists()[i]; + } + const ParameterList *getParameterList(unsigned i) const { + return getParameterLists()[i]; + } + + /// Returns the normal parameters to the initializer, not including self. + ParameterList *getParameters() { return ParameterLists[1]; } + + /// Returns the normal parameters to the initializer, not including self. + const ParameterList *getParameters() const { return ParameterLists[1]; } + + /// Specifies the kind of initialization call performed within the body /// of the constructor, e.g., self.init or super.init. enum class BodyInitKind { @@ -5341,14 +5442,22 @@ class ConstructorDecl : public AbstractFunctionDecl { /// } /// \endcode class DestructorDecl : public AbstractFunctionDecl { - friend class AbstractFunctionDecl; - Pattern *SelfPattern; + ParameterList *SelfParameter; public: DestructorDecl(Identifier NameHack, SourceLoc DestructorLoc, - Pattern *SelfPattern, DeclContext *Parent); + ParamDecl *selfDecl, DeclContext *Parent); - void setSelfPattern(Pattern *selfPattern); + void setSelfDecl(ParamDecl *selfDecl); + + MutableArrayRef getParameterLists() { + return { &SelfParameter, 1 }; + } + ArrayRef getParameterLists() const { + return { &SelfParameter, 1 }; + } + + SourceLoc getDestructorLoc() const { return getNameLoc(); } SourceLoc getStartLoc() const { return getDestructorLoc(); } SourceRange getSourceRange() const; @@ -5607,25 +5716,17 @@ inline bool AbstractStorageDecl::isStatic() const { return false; } -inline MutableArrayRef AbstractFunctionDecl::getBodyParamBuffer() { - unsigned NumPatterns = AbstractFunctionDeclBits.NumParamPatterns; - Pattern **Ptr; +inline MutableArrayRef +AbstractFunctionDecl::getParameterLists() { switch (getKind()) { default: llvm_unreachable("Unknown AbstractFunctionDecl!"); case DeclKind::Constructor: - Ptr = cast(this)->BodyParams; - break; - + return cast(this)->getParameterLists(); case DeclKind::Destructor: - Ptr = &cast(this)->SelfPattern; - break; - + return cast(this)->getParameterLists(); case DeclKind::Func: - // Body patterns are tail allocated. - Ptr = reinterpret_cast(cast(this) + 1); - break; + return cast(this)->getParameterLists(); } - return MutableArrayRef(Ptr, NumPatterns); } inline DeclIterator &DeclIterator::operator++() { diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h index c396a90cccf6b..a131ad4cf2219 100644 --- a/include/swift/AST/DeclContext.h +++ b/include/swift/AST/DeclContext.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -66,6 +66,7 @@ enum class DeclContextKind : uint8_t { AbstractClosureExpr, Initializer, TopLevelCodeDecl, + SubscriptDecl, AbstractFunctionDecl, SerializedLocal, Last_LocalDeclContextKind = SerializedLocal, @@ -245,7 +246,7 @@ class alignas(1 << DeclContextAlignInBits) DeclContext { /// ClassDecl, otherwise return null. ClassDecl *isClassOrClassExtensionContext() const; - /// If this DeclContext is a enum, or an extension on a enum, return the + /// If this DeclContext is an enum, or an extension on an enum, return the /// EnumDecl, otherwise return null. EnumDecl *isEnumOrEnumExtensionContext() const; @@ -359,6 +360,15 @@ class alignas(1 << DeclContextAlignInBits) DeclContext { /// Determine whether the innermost context is generic. bool isInnermostContextGeneric() const; + + /// Determine whether the innermost context is either a generic type context, + /// or a concrete type nested inside a generic type context. + bool isGenericTypeContext() const; + + /// Determine the maximum depth of the current generic type context's generic + /// parameters. If the current context is not a generic type context, returns + /// the maximum depth of any generic parameter in this context. + unsigned getGenericTypeContextDepth() const; /// Returns true if lookups within this context could affect downstream files. /// diff --git a/include/swift/AST/DeclNodes.def b/include/swift/AST/DeclNodes.def index 9f349abd502ac..d1cbbf47ccb73 100644 --- a/include/swift/AST/DeclNodes.def +++ b/include/swift/AST/DeclNodes.def @@ -1,8 +1,8 @@ -//===-- DeclNodes.def - Swift Declaration AST Metaprogramming -*- C++ -*-===// +//===--- DeclNodes.def - Swift Declaration AST Metaprogramming --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DefaultArgumentKind.h b/include/swift/AST/DefaultArgumentKind.h index a53a88d3e346f..14ef3124b60f5 100644 --- a/include/swift/AST/DefaultArgumentKind.h +++ b/include/swift/AST/DefaultArgumentKind.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,10 +17,16 @@ #ifndef SWIFT_DEFAULTARGUMENTKIND_H #define SWIFT_DEFAULTARGUMENTKIND_H +namespace llvm { +class StringRef; +} + namespace swift { +class Expr; + /// Describes the kind of default argument a tuple pattern element has. -enum class DefaultArgumentKind { +enum class DefaultArgumentKind : unsigned { /// No default argument. None, /// A normal default argument. @@ -38,8 +44,22 @@ enum class DefaultArgumentKind { Function, /// The __DSO_HANDLE__ default argument, which is expanded at the call site. DSOHandle, + /// The "nil" literal. + Nil, + /// An empty array literal. + EmptyArray, + /// An empty dictionary literal. + EmptyDictionary, }; +/// Retrieve the spelling of this default argument in source code, or +/// an empty string if it has none. +llvm::StringRef getDefaultArgumentSpelling(DefaultArgumentKind kind); + +/// Infer a default argument kind from an expression, if the +/// expression is the canonical way to spell that default argument. +DefaultArgumentKind inferDefaultArgumentKind(Expr *expr); + } // end namespace swift #endif // LLVM_SWIFT_DEFAULTARGUMENTKIND_H diff --git a/include/swift/AST/DiagnosticEngine.h b/include/swift/AST/DiagnosticEngine.h index 1331f8bdb1d98..0331c50cf4c0d 100644 --- a/include/swift/AST/DiagnosticEngine.h +++ b/include/swift/AST/DiagnosticEngine.h @@ -1,8 +1,8 @@ -//===- DiagnosticEngine.h - Diagnostic Display Engine -----------*- C++ -*-===// +//===--- DiagnosticEngine.h - Diagnostic Display Engine ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,18 +18,8 @@ #ifndef SWIFT_BASIC_DIAGNOSTICENGINE_H #define SWIFT_BASIC_DIAGNOSTICENGINE_H -#include "swift/Basic/LLVM.h" -#include "swift/AST/Identifier.h" -#include "swift/AST/Type.h" #include "swift/AST/TypeLoc.h" #include "swift/Basic/DiagnosticConsumer.h" -#include "swift/Basic/SourceLoc.h" -#include "clang/Basic/VersionTuple.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringRef.h" -#include -#include namespace swift { class Decl; diff --git a/include/swift/AST/DiagnosticsAll.def b/include/swift/AST/DiagnosticsAll.def index d808b5ea6b84c..000f0839cc924 100644 --- a/include/swift/AST/DiagnosticsAll.def +++ b/include/swift/AST/DiagnosticsAll.def @@ -1,8 +1,8 @@ -//===- DiagnosticsAll.def - Diagnostics Text Index --------------*- C++ -*-===// +//===--- DiagnosticsAll.def - Diagnostics Text Index ------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsClangImporter.def b/include/swift/AST/DiagnosticsClangImporter.def index 9371fc5ed01b1..3c88a837c5319 100644 --- a/include/swift/AST/DiagnosticsClangImporter.def +++ b/include/swift/AST/DiagnosticsClangImporter.def @@ -1,8 +1,8 @@ -//===- DiagnosticsClangImporter.def - Diagnostics Text ----------*- C++ -*-===// +//===--- DiagnosticsClangImporter.def - Diagnostics Text --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsClangImporter.h b/include/swift/AST/DiagnosticsClangImporter.h index 754beefa0ba55..82d10334edcf4 100644 --- a/include/swift/AST/DiagnosticsClangImporter.h +++ b/include/swift/AST/DiagnosticsClangImporter.h @@ -1,8 +1,8 @@ -//===- DiagnosticsClangImporter.h - Diagnostic Definitions ------*- C++ -*-===// +//===--- DiagnosticsClangImporter.h - Diagnostic Definitions ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsCommon.def b/include/swift/AST/DiagnosticsCommon.def index 7004c58209a8a..11ca741a8a38a 100644 --- a/include/swift/AST/DiagnosticsCommon.def +++ b/include/swift/AST/DiagnosticsCommon.def @@ -1,8 +1,8 @@ -//===- DiagnosticsCommon.def - Diagnostics Text -----------------*- C++ -*-===// +//===--- DiagnosticsCommon.def - Diagnostics Text ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -73,12 +73,6 @@ ERROR(class_var_not_in_class,common,none, // FIXME: Used by both the parser and the type-checker. ERROR(func_decl_without_brace,decl_parsing,PointsToFirstBadToken, "expected '{' in body of function declaration", ()) -ERROR(unsupported_fixed_length_array,type_parsing,none, - "fixed-length arrays are not yet supported", ()) - -ERROR(new_array_syntax,type_parsing,none, - "array types are now written with the brackets around the element type", - ()) NOTE(convert_let_to_var,sema,none, "change 'let' to 'var' to make it mutable", ()) diff --git a/include/swift/AST/DiagnosticsCommon.h b/include/swift/AST/DiagnosticsCommon.h index cec28f3c3d76b..86f5b85a99d66 100644 --- a/include/swift/AST/DiagnosticsCommon.h +++ b/include/swift/AST/DiagnosticsCommon.h @@ -1,8 +1,8 @@ -//===- DiagnosticsCommon.h - Shared Diagnostic Definitions ------*- C++ -*-===// +//===--- DiagnosticsCommon.h - Shared Diagnostic Definitions ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsDriver.def b/include/swift/AST/DiagnosticsDriver.def index 15cc058c5c683..a99d3de1c5bfd 100644 --- a/include/swift/AST/DiagnosticsDriver.def +++ b/include/swift/AST/DiagnosticsDriver.def @@ -1,8 +1,8 @@ -//===- DiagnosticsDriver.def - Diagnostics Text -----------------*- C++ -*-===// +//===--- DiagnosticsDriver.def - Diagnostics Text ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -77,7 +77,7 @@ ERROR(error_unknown_target,driver,none, "unknown target '%0'", (StringRef)) ERROR(error_framework_bridging_header,driver,none, - "using bridging headers with framework targets is unsupported", ()) + "using bridging headers with framework targets is unsupported", ()) ERROR(error_i_mode,driver,none, "the flag '-i' is no longer required and has been removed; " diff --git a/include/swift/AST/DiagnosticsDriver.h b/include/swift/AST/DiagnosticsDriver.h index 133eb7c337435..1c9c76dbdb627 100644 --- a/include/swift/AST/DiagnosticsDriver.h +++ b/include/swift/AST/DiagnosticsDriver.h @@ -1,8 +1,8 @@ -//===- DiagnosticsDriver.h - Diagnostic Definitions -------------*- C++ -*-===// +//===--- DiagnosticsDriver.h - Diagnostic Definitions -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index 683c66bdb4b60..aa8ad25c5ea9b 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -1,8 +1,8 @@ -//===- DiagnosticsFrontend.def - Diagnostics Text ---------------*- C++ -*-===// +//===--- DiagnosticsFrontend.def - Diagnostics Text -------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -58,8 +58,6 @@ ERROR(cannot_open_serialized_file,frontend,none, "cannot open file '%0' for diagnostics emission (%1)", (StringRef, StringRef)) ERROR(error_open_input_file,frontend,none, "error opening input file '%0' (%1)", (StringRef, StringRef)) -ERROR(error_clang_importer_not_linked_in,frontend,none, - "clang importer not available", ()) ERROR(error_clang_importer_create_fail,frontend,none, "clang importer creation failed", ()) ERROR(error_missing_arg_value,frontend,none, diff --git a/include/swift/AST/DiagnosticsFrontend.h b/include/swift/AST/DiagnosticsFrontend.h index 9fc1b3d98fdef..07cce746a8d1f 100644 --- a/include/swift/AST/DiagnosticsFrontend.h +++ b/include/swift/AST/DiagnosticsFrontend.h @@ -1,8 +1,8 @@ -//===- DiagnosticsFrontend.h - Diagnostic Definitions -----------*- C++ -*-===// +//===--- DiagnosticsFrontend.h - Diagnostic Definitions ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsIRGen.def b/include/swift/AST/DiagnosticsIRGen.def index 8eb159a901d92..ef300c38a6bb7 100644 --- a/include/swift/AST/DiagnosticsIRGen.def +++ b/include/swift/AST/DiagnosticsIRGen.def @@ -1,8 +1,8 @@ -//===- DiagnosticsIRGen.def - Diagnostics Text ------------------*- C++ -*-===// +//===--- DiagnosticsIRGen.def - Diagnostics Text ----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsIRGen.h b/include/swift/AST/DiagnosticsIRGen.h index 13a46d7be2343..e97170973f5b2 100644 --- a/include/swift/AST/DiagnosticsIRGen.h +++ b/include/swift/AST/DiagnosticsIRGen.h @@ -1,8 +1,8 @@ -//===- DiagnosticsIRGen.h - Diagnostic Definitions --------------*- C++ -*-===// +//===--- DiagnosticsIRGen.h - Diagnostic Definitions ------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index 86eab14e3d55d..f2429e715838d 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -1,8 +1,8 @@ -//===- DiagnosticsParse.def - Diagnostics Text ------------------*- C++ -*-===// +//===--- DiagnosticsParse.def - Diagnostics Text ----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -71,6 +71,10 @@ ERROR(extra_tokens_line_directive,parsing,none, ERROR(line_directive_line_zero,parsing,none, "the line number needs to be greater than zero", ()) +WARNING(escaped_parameter_name,parsing,none, + "keyword '%0' does not need to be escaped in argument list", + (StringRef)) + //------------------------------------------------------------------------------ // Lexer diagnostics //------------------------------------------------------------------------------ @@ -126,12 +130,14 @@ ERROR(lex_expected_binary_exponent_in_hex_float_literal,lexing,none, "hexadecimal floating point literal must end with an exponent", ()) ERROR(lex_unexpected_block_comment_end,lexing,none, "unexpected end of block comment", ()) -ERROR(lex_unary_equal_is_reserved,lexing,none, - "%select{prefix|postfix}0 '=' is reserved", (unsigned)) +ERROR(lex_unary_equal,lexing,none, + "'=' must have consistent whitespace on both sides", ()) ERROR(lex_unary_postfix_dot_is_reserved,lexing,none, "postfix '.' is reserved", ()) ERROR(lex_editor_placeholder,lexing,none, "editor placeholder in source file", ()) +WARNING(lex_editor_placeholder_in_playground,lexing,none, + "editor placeholder in source file", ()) //------------------------------------------------------------------------------ // Declaration parsing diagnostics @@ -173,25 +179,12 @@ ERROR(decl_inner_scope,decl_parsing,none, ERROR(decl_not_static,decl_parsing,none, "declaration cannot be marked %0", (StaticSpellingKind)) -ERROR(ownership_not_attribute,decl_parsing,none, - "'@%0' is not an attribute, use the '%0' keyword instead", - (StringRef)) - ERROR(cskeyword_not_attribute,decl_parsing,none, "'%0' is a declaration modifier, not an attribute", (StringRef)) -ERROR(convenience_invalid,sema_tcd,none, - "'convenience' is not valid on this declaration", ()) - ERROR(decl_already_static,decl_parsing,none, "%0 specified twice", (StaticSpellingKind)) -ERROR(autoclosure_is_decl_attribute,attribute_parsing,none, - "@autoclosure is now an attribute of the parameter " - "declaration, not its type", ()) -ERROR(autoclosure_not_on_enums,attribute_parsing,none, - "@autoclosure is only allowed on parameters, not on enum cases", ()) - ERROR(enum_case_dot_prefix,decl_parsing,none, "extraneous '.' in enum 'case' declaration", ()) @@ -286,11 +279,6 @@ ERROR(static_func_decl_global_scope,decl_parsing,none, (StaticSpellingKind)) ERROR(func_decl_expected_arrow,decl_parsing,none, "expected '->' after function parameter tuple", ()) -ERROR(func_static_not_allowed,decl_parsing,none, - "static functions are not allowed in this context, " - "use 'class' to declare a class method", ()) -ERROR(func_conversion,decl_parsing,none, - "'__conversion' functions are no longer allowed", ()) // Enum ERROR(expected_lbrace_enum,decl_parsing,PointsToFirstBadToken, @@ -335,7 +323,11 @@ ERROR(expected_arrow_subscript,decl_parsing,PointsToFirstBadToken, ERROR(expected_type_subscript,type_parsing,PointsToFirstBadToken, "expected subscripting element type", ()) ERROR(expected_lbrace_subscript,decl_parsing,PointsToFirstBadToken, - "expected '{' for subscripting", ()) + "expected '{' in subscript to specify getter and setter implementation", + ()) +ERROR(expected_lbrace_subscript_protocol,decl_parsing,PointsToFirstBadToken, + "subscript in protocol must have explicit { get } or " + "{ get set } specifier", ()) ERROR(subscript_without_get,decl_parsing,none, "subscript declarations must have a getter", ()) ERROR(subscript_static,decl_parsing,none, @@ -362,6 +354,9 @@ ERROR(operator_decl_inner_scope,decl_parsing,none, "'operator' may only be declared at file scope", ()) ERROR(expected_operator_name_after_operator,decl_parsing,PointsToFirstBadToken, "expected operator name in operator declaration", ()) +ERROR(identifier_when_expecting_operator,decl_parsing,PointsToFirstBadToken, + "%0 is considered to be an identifier, not an operator", (Identifier)) + ERROR(operator_decl_no_fixity,decl_parsing,none, "operator must be declared as 'prefix', 'postfix', or 'infix'", ()) ERROR(expected_lbrace_after_operator,decl_parsing,PointsToFirstBadToken, @@ -410,8 +405,6 @@ ERROR(expected_sil_constant, decl_parsing,none, "expected constant in SIL code", ()) ERROR(referenced_value_no_accessor, decl_parsing,none, "referenced declaration has no %select{getter|setter}0", (unsigned)) -ERROR(sil_local_storage_non_address, decl_parsing,none, - "can only work with the address of local storage", ()) // SIL Values ERROR(sil_value_redefinition, decl_parsing,none, @@ -453,6 +446,9 @@ ERROR(sil_invalid_instr_operands,decl_parsing,none, "invalid instruction operands", ()) ERROR(sil_operand_not_address,decl_parsing,none, "%0 operand of '%1' must have address type", (StringRef, StringRef)) +ERROR(sil_operand_not_unowned_address,decl_parsing,none, + "%0 operand of '%1' must have address of [unowned] type", + (StringRef, StringRef)) ERROR(sil_operand_not_weak_address,decl_parsing,none, "%0 operand of '%1' must have address of [weak] type", (StringRef, StringRef)) @@ -460,8 +456,6 @@ ERROR(sil_integer_literal_not_integer_type,decl_parsing,none, "integer_literal instruction requires a 'Builtin.Int' type", ()) ERROR(sil_float_literal_not_float_type,decl_parsing,none, "float_literal instruction requires a 'Builtin.FP' type", ()) -ERROR(sil_apply_archetype_not_found,decl_parsing,none, - "archetype name not found in polymorphic function type of apply instruction", ()) ERROR(sil_substitutions_on_non_polymorphic_type,decl_parsing,none, "apply of non-polymorphic function cannot have substitutions", ()) ERROR(sil_witness_method_not_protocol,decl_parsing,none, @@ -480,6 +474,8 @@ ERROR(sil_missing_substitutions,decl_parsing,none, "missing substitutions", ()) ERROR(sil_too_many_substitutions,decl_parsing,none, "too many substitutions", ()) +ERROR(sil_dbg_unknown_key,decl_parsing,none, + "unknown key '%0' in debug variable declaration", (StringRef)) // SIL Basic Blocks ERROR(expected_sil_block_name, decl_parsing,none, @@ -494,8 +490,6 @@ ERROR(sil_basicblock_arg_rparen, decl_parsing,none, "expected ')' in basic block argument list", ()) // SIL Functions -ERROR(expected_sil_linkage_or_function, decl_parsing,none, - "expected SIL linkage type or function name", ()) ERROR(expected_sil_function_name, decl_parsing,none, "expected SIL function name", ()) ERROR(expected_sil_rbrace, decl_parsing,none, @@ -580,8 +574,6 @@ ERROR(expected_type_function_result,type_parsing,PointsToFirstBadToken, "expected type for function result", ()) ERROR(generic_non_function,type_parsing,PointsToFirstBadToken, "only syntactic function types can be generic", ()) -ERROR(throwing_non_function,type_parsing,PointsToFirstBadToken, - "only function types may throw", ()) ERROR(rethrowing_function_type,type_parsing,PointsToFirstBadToken, "only function declarations may be marked 'rethrows'", ()) ERROR(throws_after_function_result,type_parsing,none, @@ -598,8 +590,9 @@ ERROR(nonliteral_enum_case_raw_value,type_parsing,PointsToFirstBadToken, "raw value for enum case must be a literal", ()) // Collection Types -ERROR(expected_expr_array_type,expr_parsing,PointsToFirstBadToken, - "expected expression for size of array type", ()) +ERROR(new_array_syntax,type_parsing,none, + "array types are now written with the brackets around the element type", + ()) ERROR(expected_rbracket_array_type,type_parsing,PointsToFirstBadToken, "expected ']' in array type", ()) ERROR(expected_element_type,type_parsing,PointsToFirstBadToken, @@ -641,10 +634,8 @@ ERROR(untyped_pattern_ellipsis,pattern_parsing,none, "'...' cannot be applied to a subpattern which is not explicitly typed", ()) ERROR(non_func_decl_pattern_init,pattern_parsing,none, "default argument is only permitted for a non-curried function parameter",()) -ERROR(var_not_allowed_in_pattern,pattern_parsing, none, - "Use of 'var' binding here is not allowed", ()) -WARNING(let_on_param_is_redundant,pattern_parsing, none, - "'let' keyword is unnecessary; function parameters are immutable by default", (unsigned)) +WARNING(var_not_allowed_in_pattern,pattern_parsing, none, + "Use of '%select{var|let}0' binding here is deprecated and will be removed in a future version of Swift", (unsigned)) ERROR(var_pattern_in_var,pattern_parsing,none, "'%select{var|let}0' cannot appear nested inside another 'var' or " "'let' pattern", (unsigned)) @@ -662,26 +653,13 @@ ERROR(multiple_parameter_ellipsis,decl_parsing,none, "only a single variadic parameter '...' is permitted", ()) ERROR(parameter_vararg_default,decl_parsing,none, "variadic parameter cannot have a default value", ()) -ERROR(parameter_backtick_missing_name,decl_parsing,PointsToFirstBadToken, - "expected parameter name after '#'", ()) -ERROR(parameter_backtick_empty_name,decl_parsing,none, - "expected non-empty parameter name after '#'", ()) ERROR(parameter_inout_var_let,decl_parsing,none, "parameter may not have multiple 'inout', 'var', or 'let' specifiers", ()) -WARNING(parameter_backtick_two_names,decl_parsing,none, - "extraneous '#' in parameter; keyword argument and parameter name " - "already specified separately", ()) WARNING(parameter_extraneous_double_up,decl_parsing,none, "extraneous duplicate parameter name; %0 already has an argument " "label", (Identifier)) -ERROR(parameter_extraneous_pound,decl_parsing,none, - "'#' has been removed from Swift; %0 already has an argument label", - (Identifier)) -ERROR(parameter_pound_double_up,decl_parsing,none, - "'#' has been removed from Swift; double up '%0 %0' to make the " - "argument label the same as the parameter name", (StringRef)) WARNING(parameter_extraneous_empty_name,decl_parsing,none, "extraneous '_' in parameter: %0 has no keyword argument name", (Identifier)) @@ -754,8 +732,6 @@ ERROR(expected_expr_conditional_letbinding,stmt_parsing,none, ERROR(expected_expr_conditional_letbinding_bool_conditions,stmt_parsing,none, "expected 'let' or 'var' in conditional; " "use '&&' to join boolean conditions", ()) -ERROR(expected_simple_identifier_pattern,stmt_parsing,none, - "expected simple identifier pattern in optional binding condition", ()) ERROR(expected_expr_conditional_var,stmt_parsing,PointsToFirstBadToken, "expected expression after '=' in conditional binding", ()) ERROR(expected_expr_conditional_where,stmt_parsing,PointsToFirstBadToken, @@ -809,8 +785,6 @@ ERROR(expected_while_after_repeat_body,stmt_parsing,PointsToFirstBadToken, "expected 'while' after body of 'repeat' statement", ()) ERROR(expected_expr_repeat_while,stmt_parsing,PointsToFirstBadToken, "expected expression in 'repeat-while' condition", ()) -ERROR(missing_condition_after_repeat_while,stmt_parsing,none, - "missing condition in a 'repeat-while' statement", ()) ERROR(do_while_now_repeat_while,stmt_parsing,none, "'do-while' statement is not allowed; use 'repeat-while' instead", ()) @@ -968,8 +942,6 @@ ERROR(availability_query_outside_if_stmt_guard, expr_parsing, none, ERROR(expected_identifier_after_dot_expr,expr_parsing,none, "expected identifier after '.' expression", ()) -ERROR(expected_field_spec_name_tuple_expr,expr_parsing,none, - "expected field specifier name in tuple expression", ()) ERROR(expected_identifier_after_super_dot_expr,expr_parsing, PointsToFirstBadToken, @@ -1105,14 +1077,6 @@ ERROR(attr_availability_renamed, attribute_parsing, none, ERROR(attr_autoclosure_expected_r_paren,attribute_parsing,PointsToFirstBadToken, "expected ')' in @autoclosure", ()) -// cc -ERROR(cc_attribute_expected_lparen,attribute_parsing,none, - "expected '(' after 'cc' attribute", ()) -ERROR(cc_attribute_expected_name,attribute_parsing,none, - "expected calling convention name identifier in 'cc' attribute", ()) -ERROR(cc_attribute_expected_rparen,attribute_parsing,none, - "expected ')' after calling convention name for 'cc' attribute", ()) - // convention ERROR(convention_attribute_expected_lparen,attribute_parsing,none, "expected '(' after 'convention' attribute", ()) @@ -1169,6 +1133,20 @@ WARNING(attr_warn_unused_result_unknown_parameter,attribute_parsing,none, ERROR(attr_warn_unused_result_expected_rparen,attribute_parsing,none, "expected ')' after 'warn_unused_result' attribute", ()) +// _migration_id +WARNING(attr_migration_id_expected_name,attribute_parsing,none, + "expected parameter 'pattern'", ()) +WARNING(attr_migration_id_unknown_parameter,attribute_parsing,none, + "unknown parameter '%0' in '_migration_id' attribute", (StringRef)) +ERROR(attr_migration_id_expected_eq,attribute_parsing,none, + "expected '=' following '%0' parameter", (StringRef)) +ERROR(attr_migration_id_expected_string,attribute_parsing,none, + "expected a string following '=' for '%0' parameter", (StringRef)) +WARNING(attr_migration_id_duplicate_parameter,attribute_parsing,none, + "duplicate '%0' parameter; previous value will be ignored", (StringRef)) +ERROR(attr_migration_id_expected_rparen,attribute_parsing,none, + "expected ')' after '_migration_id' attribute", ()) + //------------------------------------------------------------------------------ // Generics parsing diagnostics //------------------------------------------------------------------------------ @@ -1233,9 +1211,6 @@ WARNING(unknown_build_config,parsing,none, //------------------------------------------------------------------------------ // Availability query parsing diagnostics //------------------------------------------------------------------------------ -ERROR(avail_query_not_enabled,parsing,Fatal, - "experimental availability checking not enabled", ()) - ERROR(avail_query_expected_condition,parsing,PointsToFirstBadToken, "expected availability condition", ()) ERROR(avail_query_expected_platform_name,parsing,PointsToFirstBadToken, diff --git a/include/swift/AST/DiagnosticsParse.h b/include/swift/AST/DiagnosticsParse.h index e50840cfb8fd1..509b2ebd4c15e 100644 --- a/include/swift/AST/DiagnosticsParse.h +++ b/include/swift/AST/DiagnosticsParse.h @@ -1,8 +1,8 @@ -//===- DiagnosticsParse.h - Diagnostic Definitions --------------*- C++ -*-===// +//===--- DiagnosticsParse.h - Diagnostic Definitions ------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsSIL.def b/include/swift/AST/DiagnosticsSIL.def index c795e28c20691..13aa70809c263 100644 --- a/include/swift/AST/DiagnosticsSIL.def +++ b/include/swift/AST/DiagnosticsSIL.def @@ -1,8 +1,8 @@ -//===- DiagnosticsSILAnalysis.def - Diagnostics Text ------------*- C++ -*-===// +//===--- DiagnosticsSIL.def - Diagnostics Text ------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -97,7 +97,7 @@ ERROR(variable_used_before_initialized,sil_analysis,none, ERROR(variable_inout_before_initialized,sil_analysis,none, "%select{variable|constant}1 '%0' passed by reference before being" " initialized", (StringRef, bool)) -ERROR(variable_escape_before_initialized,sil_analysis,none, +ERROR(variable_closure_use_uninit,sil_analysis,none, "%select{variable|constant}1 '%0' captured by a closure before being" " initialized", (StringRef, bool)) @@ -145,7 +145,7 @@ ERROR(return_from_init_without_initing_stored_properties,sil_analysis,none, "return from initializer without initializing all" " stored properties", ()) -ERROR(global_variable_function_use_uninit,sil_analysis,none, +ERROR(variable_function_use_uninit,sil_analysis,none, "%select{variable|constant}1 '%0' used by function definition before" " being initialized", (StringRef, bool)) diff --git a/include/swift/AST/DiagnosticsSIL.h b/include/swift/AST/DiagnosticsSIL.h index 7c9e24d2c11a7..5bf0c81926f96 100644 --- a/include/swift/AST/DiagnosticsSIL.h +++ b/include/swift/AST/DiagnosticsSIL.h @@ -1,8 +1,8 @@ -//===- DiagnosticsSIL.h - Diagnostic Definitions ----------------*- C++ -*-===// +//===--- DiagnosticsSIL.h - Diagnostic Definitions --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 9c32d337738db..2dbb3c183cf71 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -1,8 +1,8 @@ -//===- DiagnosticsSema.def - Diagnostics Text -------------------*- C++ -*-===// +//===--- DiagnosticsSema.def - Diagnostics Text -----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -397,9 +397,6 @@ ERROR(serialization_target_too_new_repl,sema,none, "module file's minimum deployment target is %0 v%1.%2%select{|.%3}3: %4", (StringRef, unsigned, unsigned, unsigned, StringRef)) -ERROR(unknown_name_in_type,sema_nb,none, - "use of unknown scope %0 in type reference", (Identifier)) - ERROR(invalid_redecl,sema_nb,none,"invalid redeclaration of %0", (DeclName)) NOTE(invalid_redecl_prev,sema_nb,none, "%0 previously declared here", (DeclName)) @@ -420,16 +417,30 @@ ERROR(ambiguous_module_type,sema_nb,none, ERROR(use_nonmatching_operator,sema_nb,none, "%0 is not a %select{binary|prefix unary|postfix unary}1 operator", (Identifier, unsigned)) + +ERROR(unspaced_binary_operator_fixit,sema_nb,none, + "missing whitespace between %0 and %1 operators", + (Identifier, Identifier, bool)) +ERROR(unspaced_binary_operator,sema_nb,none, + "ambiguous missing whitespace between unary and binary operators", ()) +NOTE(unspaced_binary_operators_candidate,sema_nb,none, + "could be %select{binary|postfix}2 %0 and %select{prefix|binary}2 %1", + (Identifier, Identifier, bool)) +ERROR(unspaced_unary_operator,sema_nb,none, + "unary operators may not be juxtaposed; parenthesize inner expression", + ()) + + ERROR(use_unresolved_identifier,sema_nb,none, - "use of unresolved identifier %0", (Identifier)) + "use of unresolved %select{identifier|operator}1 %0", (Identifier, bool)) ERROR(use_undeclared_type,sema_nb,none, "use of undeclared type %0", (Identifier)) ERROR(use_undeclared_type_did_you_mean,sema_nb,none, -"use of undeclared type %0; did you mean to use '%1'?", (Identifier, StringRef)) + "use of undeclared type %0; did you mean to use '%1'?", (Identifier, StringRef)) NOTE(note_remapped_type,sema_nb,none, - "did you mean to use '%0'?", (StringRef)) + "did you mean to use '%0'?", (StringRef)) ERROR(identifier_init_failure,sema_nb,none, - "could not infer type for %0", (Identifier)) + "could not infer type for %0", (Identifier)) ERROR(pattern_used_in_type,sema_nb,none, "%0 used within its own type", (Identifier)) NOTE(note_module_as_type,sema_nb,none, @@ -437,6 +448,11 @@ NOTE(note_module_as_type,sema_nb,none, ERROR(use_unknown_object_literal,sema_nb,none, "use of unknown object literal name %0", (Identifier)) +ERROR(object_literal_default_type_missing,sema_nb,none, + "could not infer type of %0 literal", (StringRef)) +NOTE(object_literal_resolve_import,sema_nb,none, + "import %0 to use '%1' as the default %2 literal type", + (StringRef, StringRef, StringRef)) ERROR(use_non_type_value,sema_nb,none, "%0 is not a type", (Identifier)) @@ -545,9 +561,6 @@ ERROR(downcast_same_type,sema_tcc,none, (Type, Type, StringRef)) WARNING(downcast_to_unrelated,sema_tcc,none, "cast from %0 to unrelated type %1 always fails", (Type, Type)) -ERROR(downcast_from_existential_to_unrelated,sema_tcc,none, - "cannot cast from protocol type %0 to non-conforming type %1", - (Type, Type)) ERROR(downcast_to_more_optional,sema_tcc,none, "cannot downcast from %0 to a more optional type %1", (Type, Type)) @@ -618,6 +631,10 @@ ERROR(argument_out_of_order,sema_tcc,none, ERROR(argument_out_of_order_named_unnamed,sema_tcc,none, "argument %0 must precede unnamed parameter #%1", (Identifier, unsigned)) +ERROR(instance_member_use_on_type,sema_tcc,none, + "use of instance member %1 on type %0; " + "did you mean to use a value of type %0 instead?", (Type, Identifier)) + ERROR(missing_argument_named,sema_tcc,none, "missing argument for parameter %0 in call", (Identifier)) ERROR(missing_argument_positional,sema_tcc,none, @@ -638,6 +655,12 @@ ERROR(unbound_generic_parameter,sema_tcc,none, ERROR(cannot_bind_generic_parameter_to_type,sema_tcc,none, "cannot bind generic parameter to type %0", (Type)) +ERROR(string_index_not_integer,sema_tcc,none, + "String may not be indexed with %0, it has variable size elements", + (Type)) +NOTE(string_index_not_integer_note,sema_tcc,none, + "consider using an existing high level algorithm, " + "str.startIndex.advancedBy(n), or a projection like str.utf8", ()) ERROR(invalid_c_function_pointer_conversion_expr,sema_tcc,none, "a C function pointer can only be formed from a reference to a 'func' or " @@ -828,6 +851,8 @@ NOTE(note_no_in_class_init_3plus,sema_tcd,none, (Identifier, Identifier, Identifier, bool)) ERROR(missing_unimplemented_init_runtime,sema_tcd,none, "standard library error: missing _unimplemented_initializer", ()) +ERROR(missing_undefined_runtime,sema_tcd,none, + "standard library error: missing _undefined", ()) WARNING(unsupported_synthesize_init_variadic,sema_tcd,none, "synthesizing a variadic inherited initializer for subclass %0 is " "unsupported", @@ -1052,7 +1077,7 @@ NOTE(ambiguous_witnesses_wrong_name,sema_tcd,none, "subscript operators}0 with type %2", (RequirementKind, DeclName, Type)) NOTE(no_witnesses_type,sema_tcd,none, "protocol requires nested type %0", (Identifier)) -NOTE(default_assocated_type_req_fail,sema_tcd,none, +NOTE(default_associated_type_req_fail,sema_tcd,none, "default type %0 for associated type %1 (from protocol %2) " "does not conform to %3", (Type, DeclName, Type, Type)) @@ -1210,9 +1235,6 @@ ERROR(override_multiple_decls_base,sema_tcd,none, ERROR(override_multiple_decls_arg_mismatch,sema_tcd,none, "declaration %0 has different argument names from any potential " "overrides", (DeclName)) -ERROR(override_multiple_decls_derived,sema_tcd,none, - "declaration cannot be overridden by more than one subclass " - "declaration", ()) NOTE(overridden_near_match_here,sema_tcd,none, "potential overridden %select{method|initializer}0 %1 here", (bool, DeclName)) @@ -1324,10 +1346,6 @@ ERROR(override_mutable_covariant_subscript,sema_tcd,none, (Type, Type)) ERROR(decl_already_final,sema_tcd,none, "static declarations are already final", ()) -ERROR(decl_no_default_init,sema_tcd,none, - "cannot default-initialize variable of type %0", (Type)) -ERROR(decl_no_default_init_ivar_hole,sema_tcd,none, - "cannot use initial value when one of the variables is '_'", ()) NOTE(decl_init_here,sema_tcd,none, "initial value is here", ()) @@ -1473,8 +1491,6 @@ ERROR(override_rethrows_with_non_rethrows,sema_tcd,none, ERROR(rethrows_without_throwing_parameter,sema_tcd,none, "'rethrows' function must take a throwing function argument", ()) -ERROR(inconsistent_attribute_override,sema_tcd,none, - "@%0 must be consistent between a method and its override", (StringRef)) ERROR(autoclosure_function_type,attribute_parsing,none, "@autoclosure may only be applied to values of function type", ()) @@ -1494,7 +1510,7 @@ ERROR(noescape_conflicts_escaping_autoclosure,attribute_parsing,none, ERROR(attr_NSManaged_not_instance_member,sema_tcd,none, "@NSManaged only allowed on an instance property or method", ()) ERROR(attr_NSManaged_not_stored,sema_tcd,none, - "@NSManaged not allowed on %select{computed|observing|adressed}0 " + "@NSManaged not allowed on %select{computed|observing|addressed}0 " "properties", (unsigned)) ERROR(attr_NSManaged_let_property,sema_tcd,none, "@NSManaged not allowed on a 'let' property", ()) @@ -1694,18 +1710,13 @@ ERROR(try_assign_rhs_noncovering,sema_tce,none, "everything to its right", (unsigned)) ERROR(reference_non_inout,sema_tce,none, - "reference to %0 not used to initialize a inout parameter", (Type)) + "reference to %0 not used to initialize an inout parameter", (Type)) NOTE(subscript_decl_here,sema_tca,none, "subscript operator declared here", ()) ERROR(condition_broken_proto,sema_tce,none, "protocol 'BooleanType' is broken", ()) -ERROR(option_type_broken,sema_tce,none, - "type 'Optional' is broken", ()) ERROR(broken_bool,sema_tce,none, "type 'Bool' is broken", ()) -ERROR(binding_explicit_downcast,sema_tce,none, - "operand of postfix '?' is a forced downcast to type %0; use 'as?' to " - "perform a conditional downcast", (Type)) WARNING(inject_forced_downcast,sema_tce,none, "treating a forced downcast to %0 as optional will never produce 'nil'", @@ -1736,11 +1747,6 @@ ERROR(migrate_from_allZeros,sema_tce,none, ERROR(migrate_to_raw_to_raw_value,sema_tce,none, "method 'fromRaw' has been replaced with a property 'rawValue'", ()) -ERROR(new_array_bound_zero,sema_tce,none, - "array type cannot have zero length", ()) -ERROR(non_constant_array,type_parsing,none, - "array has non-constant size", ()) - ERROR(interpolation_missing_proto,sema_tce,none, "string interpolation requires the protocol 'StringInterpolationConvertible' to be defined", ()) @@ -1809,6 +1815,8 @@ ERROR(type_is_not_array,sema_tce,none, "contextual type %0 cannot be used with array literal", (Type)) NOTE(meant_dictionary_lit, sema_tce,none, "did you mean to use a dictionary literal instead?", ()) +ERROR(should_use_empty_dictionary_literal,sema_tce,none, + "use [:] to get an empty dictionary literal", ()) // Dictionary literals ERROR(dictionary_protocol_broken,sema_tce,none, @@ -1845,7 +1853,6 @@ ERROR(partial_application_of_function_invalid,tce_sema,none, "partial application of %select{" "function with 'inout' parameters|" "'mutating' method|" - "method in @objc protocol|" "'super.init' initializer chain|" "'self.init' initializer delegation" "}0 is not allowed", @@ -1872,11 +1879,6 @@ ERROR(transitive_capture_before_declaration,tce_sema,none, NOTE(transitive_capture_through_here,tce_sema,none, "%0, declared here, captures %1", (Identifier, Identifier)) -ERROR(unsupported_local_function_reference,tce_sema,none, - "cannot reference a local function with captures from another local " - "function", ()) -ERROR(unsupported_recursive_local_function,tce_sema,none, - "local functions cannot reference themselves", ()) WARNING(recursive_accessor_reference,tce_sema,none, "attempting to %select{access|modify}1 %0 within its own " @@ -1990,6 +1992,12 @@ NOTE(change_to_mutating,sema_tcs,none, "mark %select{method|accessor}0 'mutating' to make 'self' mutable", (bool)) +// For Stmt +WARNING(deprecated_c_style_for_stmt,sema_tcs,none, +"C-style for statement is deprecated and will be removed in a future version of Swift", ()) +NOTE(cant_fix_c_style_for_stmt,sema_tcs,none, +"C-style for statement can't be automatically fixed to for-in, because the loop variable is modified inside the loop", ()) + // ForEach Stmt ERROR(sequence_protocol_broken,sema_tcs,none, "SequenceType protocol definition is broken", ()) @@ -2046,12 +2054,6 @@ ERROR(type_pattern_missing_is,sema_tcp,none, ERROR(pattern_type_mismatch_context,sema_tcp,none, "type annotation does not match contextual type %0", (Type)) -ERROR(label_single_entry_tuple,sema_tcp,none, - "label is not allowed on single element tuple pattern", ()) -NOTE(remove_parens_for_type_annotation,sema_tcp,none, - "remove the parentheses to make this a type annotation", ()) -NOTE(remove_label_for_tuple_pattern,sema_tcp,none, - "remove the label to make this a tuple pattern", ()) ERROR(tuple_pattern_in_non_tuple_context,sema_tcp,none, "tuple pattern cannot match values of the non-tuple type %0", (Type)) @@ -2068,8 +2070,6 @@ ERROR(tuple_pattern_label_mismatch,sema_tcp,none, "tuple pattern element label %0 must be %1", (Identifier, Identifier)) ERROR(enum_element_pattern_member_not_found,sema_tcp,none, "enum case '%0' not found in type %1", (StringRef, Type)) -ERROR(enum_element_pattern_not_enum,sema_tcp,none, - "enum case pattern cannot match values of the non-enum type %0", (Type)) ERROR(optional_element_pattern_not_valid_type,sema_tcp,none, "'?' pattern cannot match values of type %0", (Type)) ERROR(condition_optional_element_pattern_not_valid_type,sema_tcp,none, @@ -2247,8 +2247,6 @@ NOTE(overridden_required_initializer_here,sema_tcd,none, // Functions ERROR(attribute_requires_function_type,attribute_parsing,none, "attribute only applies to syntactic function types", ()) -ERROR(first_class_generic_function,type_parsing,PointsToFirstBadToken, - "generic types cannot be used as first-class types", ()) ERROR(objc_block_cannot_be_thin,attribute_parsing,none, "@objc_block function type cannot be @thin", ()) ERROR(attribute_not_supported,attribute_parsing,none, @@ -2265,8 +2263,6 @@ WARNING(deprecated_convention_attribute,type_parsing,none, "instead", (StringRef, StringRef)) // SIL -ERROR(sil_local_storage_nested, decl_parsing,none, - "local storage types cannot be in nested positions", ()) ERROR(opened_non_protocol, decl_parsing,none, "@opened cannot be applied to non-protocol type %0", (Type)) ERROR(sil_function_ellipsis,type_parsing,PointsToFirstBadToken, @@ -2280,8 +2276,6 @@ ERROR(sil_function_multiple_results,type_parsing,PointsToFirstBadToken, "SIL function types cannot have multiple results", ()) ERROR(sil_function_multiple_error_results,type_parsing,PointsToFirstBadToken, "SIL function types cannot have multiple @error results", ()) -ERROR(unsupported_cc_representation_combo,type_parsing,none, - "cc unsupported with this sil representation", ()) ERROR(unsupported_sil_convention,type_parsing,none, "convention '%0' not supported in SIL", (StringRef)) ERROR(sil_deprecated_convention_attribute,type_parsing,none, @@ -2333,9 +2327,7 @@ ERROR(objc_setter_for_nonobjc_subscript,sema_tcd,none, ERROR(objc_enum_generic,sema_tcd,none, "'@objc' enum cannot be generic", ()) ERROR(objc_name_req_nullary,sema_objc,none, - "'@objc' %select{class|protocol|property}0 must have a simple name", (int)) -ERROR(objc_name_enum,sema_objc,none, - "'@objc' enum cannot have a name", ()) + "'@objc' %select{class|protocol|enum|enum case|property}0 must have a simple name", (int)) ERROR(objc_name_subscript,sema_objc,none, "'@objc' subscript cannot have a name; did you mean to put " "the name on the getter or setter?", ()) @@ -2345,6 +2337,13 @@ ERROR(objc_name_func_mismatch,sema_objc,none, "%select{initializer|method}0 has %select{one parameter|%3 parameters}4" "%select{| (%select{|including }4the error parameter)}5", (bool, unsigned, bool, unsigned, bool, bool)) +ERROR(objc_enum_case_req_name,sema_objc,none, + "attribute has no effect; cases within an '@objc' enum are already " + "exposed to Objective-C", ()) +ERROR(objc_enum_case_req_objc_enum,sema_objc,none, + "'@objc' enum case is not allowed outside of an '@objc' enum", ()) +ERROR(objc_enum_case_multi,sema_objc,none, + "'@objc' enum case declaration defines multiple enum cases with the same Objective-C name", ()) // If you change this, also change enum ObjCReason #define OBJC_ATTR_SELECT "select{marked dynamic|marked @objc|marked @IBOutlet|marked @NSManaged|a member of an @objc protocol|implicitly @objc|an @objc override}" diff --git a/include/swift/AST/DiagnosticsSema.h b/include/swift/AST/DiagnosticsSema.h index 1177807691734..494756037cbe4 100644 --- a/include/swift/AST/DiagnosticsSema.h +++ b/include/swift/AST/DiagnosticsSema.h @@ -1,8 +1,8 @@ -//===- DiagnosticsSema.h - Diagnostic Definitions ---------------*- C++ -*-===// +//===--- DiagnosticsSema.h - Diagnostic Definitions -------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,7 +23,7 @@ namespace swift { namespace diag { - /// Describes the kind of requirement in a protocl. + /// Describes the kind of requirement in a protocol. enum class RequirementKind : uint8_t { Constructor, Func, diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index f6cae448e427c..bd5afde9d7f05 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,15 +19,8 @@ #include "swift/AST/CaptureInfo.h" #include "swift/AST/ConcreteDeclRef.h" -#include "swift/AST/DeclContext.h" -#include "swift/AST/Identifier.h" -#include "swift/AST/Substitution.h" #include "swift/AST/TypeLoc.h" #include "swift/AST/Availability.h" -#include "swift/Basic/SourceLoc.h" -#include "swift/Config.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" namespace llvm { struct fltSemantics; @@ -54,6 +47,7 @@ namespace swift { class ConstructorDecl; class TypeDecl; class PatternBindingDecl; + class ParameterList; enum class ExprKind : uint8_t { #define EXPR(Id, Parent) Id, @@ -931,9 +925,6 @@ class DeclRefExpr : public Expr { return DOrSpecialized.get(); } - /// Set the declaration. - void setDeclRef(ConcreteDeclRef ref); - void setSpecialized(); /// \brief Determine whether this declaration reference was immediately @@ -2778,14 +2769,14 @@ class AbstractClosureExpr : public Expr, public DeclContext { CaptureInfo Captures; /// \brief The set of parameters. - Pattern *ParamPattern; + ParameterList *parameterList; public: AbstractClosureExpr(ExprKind Kind, Type FnType, bool Implicit, unsigned Discriminator, DeclContext *Parent) : Expr(Kind, Implicit, FnType), DeclContext(DeclContextKind::AbstractClosureExpr, Parent), - ParamPattern(nullptr) { + parameterList(nullptr) { AbstractClosureExprBits.Discriminator = Discriminator; } @@ -2793,9 +2784,9 @@ class AbstractClosureExpr : public Expr, public DeclContext { const CaptureInfo &getCaptureInfo() const { return Captures; } /// \brief Retrieve the parameters of this closure. - Pattern *getParams() { return ParamPattern; } - const Pattern *getParams() const { return ParamPattern; } - void setParams(Pattern *P); + ParameterList *getParameters() { return parameterList; } + const ParameterList *getParameters() const { return parameterList; } + void setParameterList(ParameterList *P); // Expose this to users. using DeclContext::setParent; @@ -2828,11 +2819,12 @@ class AbstractClosureExpr : public Expr, public DeclContext { decltype(AbstractClosureExprBits)::InvalidDiscriminator }; - ArrayRef getParamPatterns() { - return ParamPattern ? ParamPattern : ArrayRef (); + ArrayRef getParameterLists() { + return parameterList ? parameterList : ArrayRef(); } - ArrayRef getParamPatterns() const { - return ParamPattern ? ParamPattern : ArrayRef (); + + ArrayRef getParameterLists() const { + return parameterList ? parameterList : ArrayRef(); } unsigned getNaturalArgumentCount() const { return 1; } @@ -2924,7 +2916,7 @@ class ClosureExpr : public AbstractClosureExpr { llvm::PointerIntPair Body; public: - ClosureExpr(Pattern *params, SourceLoc throwsLoc, SourceLoc arrowLoc, + ClosureExpr(ParameterList *params, SourceLoc throwsLoc, SourceLoc arrowLoc, SourceLoc inLoc, TypeLoc explicitResultType, unsigned discriminator, DeclContext *parent) : AbstractClosureExpr(ExprKind::Closure, Type(), /*Implicit=*/false, @@ -2932,7 +2924,7 @@ class ClosureExpr : public AbstractClosureExpr { ThrowsLoc(throwsLoc), ArrowLoc(arrowLoc), InLoc(inLoc), ExplicitResultType(explicitResultType), Body(nullptr) { - setParams(params); + setParameterList(params); ClosureExprBits.HasAnonymousClosureVars = false; ClosureExprBits.IsVoidConversionClosure = false; } @@ -3051,7 +3043,7 @@ class ClosureExpr : public AbstractClosureExpr { /// \brief This is a closure of the contained subexpression that is formed -/// when an scalar expression is converted to @autoclosure function type. +/// when a scalar expression is converted to @autoclosure function type. /// For example: /// \code /// @autoclosure var x : () -> Int = 4 @@ -3097,7 +3089,7 @@ class AutoClosureExpr : public AbstractClosureExpr { /// DynamicTypeExpr - "base.dynamicType" - Produces a metatype value. /// -/// The metatype value can comes from a evaluating an expression and then +/// The metatype value can comes from evaluating an expression and then /// getting its metatype. class DynamicTypeExpr : public Expr { Expr *Base; @@ -3745,6 +3737,7 @@ class EditorPlaceholderExpr : public Expr { SourceLoc Loc; TypeLoc PlaceholderTy; TypeRepr *ExpansionTyR; + Expr *SemanticExpr; public: EditorPlaceholderExpr(Identifier Placeholder, SourceLoc Loc, @@ -3753,7 +3746,8 @@ class EditorPlaceholderExpr : public Expr { : Expr(ExprKind::EditorPlaceholder, /*Implicit=*/false), Placeholder(Placeholder), Loc(Loc), PlaceholderTy(PlaceholderTy), - ExpansionTyR(ExpansionTyR) { + ExpansionTyR(ExpansionTyR), + SemanticExpr(nullptr) { } Identifier getPlaceholder() const { return Placeholder; } @@ -3767,6 +3761,9 @@ class EditorPlaceholderExpr : public Expr { static bool classof(const Expr *E) { return E->getKind() == ExprKind::EditorPlaceholder; } + + Expr *getSemanticExpr() const { return SemanticExpr; } + void setSemanticExpr(Expr *SE) { SemanticExpr = SE; } }; #undef SWIFT_FORWARD_SOURCE_LOCS_TO diff --git a/include/swift/AST/ExprHandle.h b/include/swift/AST/ExprHandle.h index 3b3a1d7aa3aad..6c4b8930d25a6 100644 --- a/include/swift/AST/ExprHandle.h +++ b/include/swift/AST/ExprHandle.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -26,7 +26,7 @@ namespace swift { /// ExprHandle - Provides an indirection for expressions, so both a type and a /// pattern can point at the same expression during type-checking. -class ExprHandle { +class alignas(8) ExprHandle { /// \brief The expression along with a bit saying whether this expression /// was already type-checked (or not). llvm::PointerIntPair EAndChecked; diff --git a/include/swift/AST/ExprNodes.def b/include/swift/AST/ExprNodes.def index 07d7c110b47f1..149183bb2159f 100644 --- a/include/swift/AST/ExprNodes.def +++ b/include/swift/AST/ExprNodes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -156,7 +156,7 @@ EXPR(Assign, Expr) EXPR(DefaultValue, Expr) EXPR(CodeCompletion, Expr) UNCHECKED_EXPR(UnresolvedPattern, Expr) -UNCHECKED_EXPR(EditorPlaceholder, Expr) +EXPR(EditorPlaceholder, Expr) #undef EXPR_RANGE #undef UNCHECKED_EXPR diff --git a/include/swift/AST/ForeignErrorConvention.h b/include/swift/AST/ForeignErrorConvention.h index f50ad66b78015..c9023bc4f0137 100644 --- a/include/swift/AST/ForeignErrorConvention.h +++ b/include/swift/AST/ForeignErrorConvention.h @@ -1,8 +1,8 @@ -//===--- ForeignErrorConvention.h - Error conventions ----------*- C++ -*-===// +//===--- ForeignErrorConvention.h - Error conventions -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/GenericSignature.h b/include/swift/AST/GenericSignature.h index f5ddc2e7629ac..6505f9c70de26 100644 --- a/include/swift/AST/GenericSignature.h +++ b/include/swift/AST/GenericSignature.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -101,7 +101,7 @@ class GenericSignature : public llvm::FoldingSetNode { NumGenericParams }; } - /// Retrieve a mutable verison of the requirements. + /// Retrieve a mutable version of the requirements. MutableArrayRef getRequirementsBuffer() { void *genericParams = getGenericParamsBuffer().end(); return { reinterpret_cast(genericParams), @@ -202,9 +202,10 @@ class GenericSignature : public llvm::FoldingSetNode { /// Determine the superclass bound on the given dependent type. Type getSuperclassBound(Type type, ModuleDecl &mod); + using ConformsToArray = SmallVector; /// Determine the set of protocols to which the given dependent type /// must conform. - SmallVector getConformsTo(Type type, ModuleDecl &mod); + ConformsToArray getConformsTo(Type type, ModuleDecl &mod); /// Determine whether the given dependent type is equal to a concrete type. bool isConcreteType(Type type, ModuleDecl &mod); diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 61cac6050adb1..4424c90d72bf4 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -135,7 +135,8 @@ class IRGenOptions { DisableLLVMARCOpts(false), DisableLLVMSLPVectorizer(false), DisableFPElim(true), Playground(false), EmitStackPromotionChecks(false), GenerateProfile(false), - EmbedMode(IRGenEmbedMode::None) {} + EmbedMode(IRGenEmbedMode::None) + {} /// Gets the name of the specified output filename. /// If multiple files are specified, the last one is returned. diff --git a/include/swift/AST/Identifier.h b/include/swift/AST/Identifier.h index 7cdc01d263ed1..7a38b65dd06a1 100644 --- a/include/swift/AST/Identifier.h +++ b/include/swift/AST/Identifier.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,12 +18,8 @@ #define SWIFT_AST_IDENTIFIER_H #include "swift/Basic/LLVM.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/StringRef.h" -#include namespace llvm { class raw_ostream; @@ -31,6 +27,7 @@ namespace llvm { namespace swift { class ASTContext; + class ParameterList; /// DeclRefKind - The kind of reference to an identifier. enum class DeclRefKind { @@ -109,9 +106,6 @@ class Identifier { /// isOperatorContinuationCodePoint - Return true if the specified code point /// is a valid operator code point. static bool isOperatorContinuationCodePoint(uint32_t C) { - // '.' is a special case. It can only appear in '..'. - if (C == '.') - return false; if (isOperatorStartCodePoint(C)) return true; @@ -246,6 +240,9 @@ class DeclName { : SimpleOrCompound(decltype(SimpleOrCompound)::getFromOpaqueValue(Opaque)) {} + void initialize(ASTContext &C, Identifier baseName, + ArrayRef argumentNames); + public: /// Build a null name. DeclName() : SimpleOrCompound(IdentifierAndCompound()) {} @@ -256,9 +253,15 @@ class DeclName { /// Build a compound value name given a base name and a set of argument names. DeclName(ASTContext &C, Identifier baseName, - ArrayRef argumentNames); + ArrayRef argumentNames) { + initialize(C, baseName, argumentNames); + } + + /// Build a compound value name given a base name and a set of argument names + /// extracted from a parameter list. + DeclName(ASTContext &C, Identifier baseName, ParameterList *paramList); - /// Retrive the 'base' name, i.e., the name that follows the introducer, + /// Retrieve the 'base' name, i.e., the name that follows the introducer, /// such as the 'foo' in 'func foo(x:Int, y:Int)' or the 'bar' in /// 'var bar: Int'. Identifier getBaseName() const { diff --git a/include/swift/AST/Initializer.h b/include/swift/AST/Initializer.h index 29039412b36b6..f757c9525743f 100644 --- a/include/swift/AST/Initializer.h +++ b/include/swift/AST/Initializer.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/KnownDecls.def b/include/swift/AST/KnownDecls.def index a8483d202d7ce..524d0f1478ba4 100644 --- a/include/swift/AST/KnownDecls.def +++ b/include/swift/AST/KnownDecls.def @@ -1,8 +1,8 @@ -//===-- KnownDecl.def - Compiler declaration metaprogramming ----*- C++ -*-===// +//===--- KnownDecls.def - Compiler declaration metaprogramming --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/KnownIdentifiers.def b/include/swift/AST/KnownIdentifiers.def index 924b01f56596a..a24de752e972d 100644 --- a/include/swift/AST/KnownIdentifiers.def +++ b/include/swift/AST/KnownIdentifiers.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// // // This file defines macros used for macro-metaprogramming with compiler-known -// identifers. +// identifiers. // //===----------------------------------------------------------------------===// diff --git a/include/swift/AST/KnownProtocols.def b/include/swift/AST/KnownProtocols.def index 1669808d3bd86..615f9d6bd4c65 100644 --- a/include/swift/AST/KnownProtocols.def +++ b/include/swift/AST/KnownProtocols.def @@ -1,8 +1,8 @@ -//===-- KnownProtocols.def - Compiler protocol metaprogramming --*- C++ -*-===// +//===--- KnownProtocols.def - Compiler protocol metaprogramming -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/KnownProtocols.h b/include/swift/AST/KnownProtocols.h index a2554fcebf1df..18cd1cb85b0a7 100644 --- a/include/swift/AST/KnownProtocols.h +++ b/include/swift/AST/KnownProtocols.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/LazyResolver.h b/include/swift/AST/LazyResolver.h index 3320491f108fa..42ac0d8cc8821 100644 --- a/include/swift/AST/LazyResolver.h +++ b/include/swift/AST/LazyResolver.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -129,12 +129,8 @@ class alignas(void*) LazyMemberLoader { /// Populates the given vector with all member decls for \p D. /// /// The implementation should add the members to D. - /// - /// \param[out] hasMissingRequiredMembers If present, set to true if any - /// members failed to import and were non-optional protocol requirements. virtual void - loadAllMembers(Decl *D, uint64_t contextData, - bool *hasMissingRequiredMembers = nullptr) { + loadAllMembers(Decl *D, uint64_t contextData) { llvm_unreachable("unimplemented"); } diff --git a/include/swift/AST/LinkLibrary.h b/include/swift/AST/LinkLibrary.h index df359296a9441..62724a8dd3f1c 100644 --- a/include/swift/AST/LinkLibrary.h +++ b/include/swift/AST/LinkLibrary.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/Mangle.h b/include/swift/AST/Mangle.h index 35e01c711bb72..eb974ad42079f 100644 --- a/include/swift/AST/Mangle.h +++ b/include/swift/AST/Mangle.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -34,17 +34,19 @@ enum class OperatorFixity { Postfix }; -/// Defined in include/swift/SIL/Mangle.h -class SpecializationManglerBase; -/// A class for mangling declarations. +/// A class for mangling declarations. The Mangler accumulates name fragments +/// with the mangleXXX methods, and the final string is constructed with the +/// `finalize` method, after which the Mangler should not be used. class Mangler { struct ArchetypeInfo { unsigned Depth; unsigned Index; }; - raw_ostream &Buffer; + llvm::SmallVector Storage; + llvm::raw_svector_ostream Buffer; + llvm::DenseMap Substitutions; llvm::DenseMap Archetypes; CanGenericSignature CurGenericSignature; @@ -56,8 +58,6 @@ class Mangler { /// If enabled, non-ASCII names are encoded in modified Punycode. bool UsePunycode; - friend class SpecializationManglerBase; - public: enum BindGenerics : unsigned { /// We don't intend to mangle any sort of type within this context @@ -88,14 +88,21 @@ class Mangler { ~ContextStack() { M.ArchetypesDepth = OldDepth; } }; + /// Finish the mangling of the symbol and return the mangled name. + std::string finalize(); + + /// Finish the mangling of the symbol and write the mangled name into + /// \p stream. + void finalize(llvm::raw_ostream &stream); + void setModuleContext(ModuleDecl *M) { Mod = M; } /// \param DWARFMangling - use the 'Qq' mangling format for /// archetypes and the 'a' mangling for alias types. /// \param usePunycode - emit modified Punycode instead of UTF-8. - Mangler(raw_ostream &buffer, bool DWARFMangling = false, + Mangler(bool DWARFMangling = false, bool usePunycode = true) - : Buffer(buffer), DWARFMangling(DWARFMangling), UsePunycode(usePunycode) {} + : Buffer(Storage), DWARFMangling(DWARFMangling), UsePunycode(usePunycode) {} void mangleContextOf(const ValueDecl *decl, BindGenerics shouldBind); void mangleContext(const DeclContext *ctx, BindGenerics shouldBind); void mangleModule(const ModuleDecl *module); @@ -147,7 +154,24 @@ class Mangler { void mangleTypeMetadataFull(CanType ty, bool isPattern); void mangleTypeFullMetadataFull(CanType ty); void mangleGlobalVariableFull(const VarDecl *decl); - + + /// Adds the string \p S into the mangled name. + void append(StringRef S); + + /// Adds the char \p C into the mangled name. + void append(char C); + + /// Add the already mangled symbol \p Name as an identifier. (using the + /// length prefix). + void mangleIdentifierSymbol(StringRef Name); + + /// Add the already mangled symbol \p Name. This gives the mangler the + /// opportunity to decode \p Name before adding it to the mangled name. + void appendSymbol(StringRef Name); + + /// Mangle the integer \p Nat into the name. + void mangleNatural(const APInt &Nat); + /// Mangles globalinit_token and globalinit_func, which are used to /// initialize global variables. /// \param decl The global variable or one of the global variables of a diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index 5069e1e4cb08a..ec8b5cca8f074 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -572,7 +572,7 @@ class ModuleDecl : public TypeDecl, public DeclContext { public: // Only allow allocation of Modules using the allocator in ASTContext // or by doing a placement new. - void *operator new(size_t Bytes, ASTContext &C, + void *operator new(size_t Bytes, const ASTContext &C, unsigned Alignment = alignof(ModuleDecl)); }; diff --git a/include/swift/AST/ModuleLoader.h b/include/swift/AST/ModuleLoader.h index ae3e62490c95f..05bf1b247fa66 100644 --- a/include/swift/AST/ModuleLoader.h +++ b/include/swift/AST/ModuleLoader.h @@ -1,8 +1,8 @@ -//===--- ModuleLoader.h - Module Loader Interface ----------- -*- C++ -*- -===// +//===--- ModuleLoader.h - Module Loader Interface ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -95,7 +95,7 @@ class ModuleLoader { virtual void loadExtensions(NominalTypeDecl *nominal, unsigned previousGeneration) { } - /// \brief Load the methods within the given class that that produce + /// \brief Load the methods within the given class that produce /// Objective-C class or instance methods with the given selector. /// /// \param classDecl The class in which we are searching for @objc methods. @@ -109,7 +109,7 @@ class ModuleLoader { /// /// \param previousGeneration The previous generation with which this /// callback was invoked. The list of methods will already contain all of - /// the results from generations up and and including \c previousGeneration. + /// the results from generations up and including \c previousGeneration. /// /// \param methods The list of @objc methods in this class that have this /// selector and are instance/class methods as requested. This list will be diff --git a/include/swift/AST/NameLookup.h b/include/swift/AST/NameLookup.h index b1fdf59244411..97b94ab03d4c2 100644 --- a/include/swift/AST/NameLookup.h +++ b/include/swift/AST/NameLookup.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -140,7 +140,7 @@ enum class DeclVisibilityKind { MemberOfOutsideNominal, /// Declaration is visible at the top level because it is declared in this - /// module or in a imported module. + /// module or in an imported module. VisibleAtTopLevel, /// Declaration was found via \c AnyObject or \c AnyObject.Type. diff --git a/include/swift/AST/Ownership.h b/include/swift/AST/Ownership.h index b329a324201d4..eeea534f3d59a 100644 --- a/include/swift/AST/Ownership.h +++ b/include/swift/AST/Ownership.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/ParameterList.h b/include/swift/AST/ParameterList.h new file mode 100644 index 0000000000000..d228151b05a9e --- /dev/null +++ b/include/swift/AST/ParameterList.h @@ -0,0 +1,153 @@ +//===--- ParameterList.h - Functions & closures parameter lists -*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines the ParameterList class and support logic. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_AST_PARAMETERLIST_H +#define SWIFT_AST_PARAMETERLIST_H + +#include "swift/AST/Decl.h" +#include "swift/Basic/OptionSet.h" + +namespace swift { + +/// This describes a list of parameters. Each parameter descriptor is tail +/// allocated onto this list. +class alignas(alignof(ParamDecl*)) ParameterList { + void *operator new(size_t Bytes) throw() = delete; + void operator delete(void *Data) throw() = delete; + void *operator new(size_t Bytes, void *Mem) throw() = delete; + void *operator new(size_t Bytes, ASTContext &C, + unsigned Alignment = 8); + + SourceLoc LParenLoc, RParenLoc; + size_t numParameters; + + ParameterList(SourceLoc LParenLoc, size_t numParameters, SourceLoc RParenLoc) + : LParenLoc(LParenLoc), RParenLoc(RParenLoc), numParameters(numParameters){} + void operator=(const ParameterList&) = delete; +public: + /// Create a parameter list with the specified parameters. + static ParameterList *create(const ASTContext &C, SourceLoc LParenLoc, + ArrayRef params, + SourceLoc RParenLoc); + + /// Create a parameter list with the specified parameters, with no location + /// info for the parens. + static ParameterList *create(const ASTContext &C, + ArrayRef params) { + return create(C, SourceLoc(), params, SourceLoc()); + } + + /// Create an empty parameter list. + static ParameterList *createEmpty(const ASTContext &C, + SourceLoc LParenLoc = SourceLoc(), + SourceLoc RParenLoc = SourceLoc()) { + return create(C, LParenLoc, {}, RParenLoc); + } + + /// Create a parameter list for a single parameter lacking location info. + static ParameterList *createWithoutLoc(ParamDecl *decl) { + return create(decl->getASTContext(), decl); + } + + /// Create an implicit 'self' decl for a method in the specified decl context. + /// If 'static' is true, then this is self for a static method in the type. + /// + /// Note that this decl is created, but it is returned with an incorrect + /// DeclContext that needs to be set correctly. This is automatically handled + /// when a function is created with this as part of its argument list. + /// + static ParameterList *createSelf(SourceLoc loc, DeclContext *DC, + bool isStaticMethod = false, + bool isInOut = false); + + SourceLoc getLParenLoc() const { return LParenLoc; } + SourceLoc getRParenLoc() const { return RParenLoc; } + + typedef MutableArrayRef::iterator iterator; + typedef ArrayRef::iterator const_iterator; + iterator begin() { return getArray().begin(); } + iterator end() { return getArray().end(); } + const_iterator begin() const { return getArray().begin(); } + const_iterator end() const { return getArray().end(); } + + MutableArrayRef getArray() { + auto Ptr = reinterpret_cast(this + 1); + return { Ptr, numParameters }; + } + ArrayRef getArray() const { + auto Ptr = reinterpret_cast(this + 1); + return { Ptr, numParameters }; + } + + size_t size() const { + return numParameters; + } + + const ParamDecl *get(unsigned i) const { + return getArray()[i]; + } + + ParamDecl *&get(unsigned i) { + return getArray()[i]; + } + + const ParamDecl *operator[](unsigned i) const { return get(i); } + ParamDecl *&operator[](unsigned i) { return get(i); } + + /// Change the DeclContext of any contained parameters to the specified + /// DeclContext. + void setDeclContextOfParamDecls(DeclContext *DC); + + + /// Flags used to indicate how ParameterList cloning should operate. + enum CloneFlags { + /// The cloned ParamDecls should be marked implicit. + Implicit = 0x01, + /// The cloned pattern is for an inherited constructor; mark default + /// arguments as inherited, and mark unnamed arguments as named. + Inherited = 0x02 + }; + + /// Make a duplicate copy of this parameter list. This allocates copies of + /// the ParamDecls, so they can be reparented into a new DeclContext. + ParameterList *clone(const ASTContext &C, + OptionSet options = None) const; + + /// Return a TupleType or ParenType for this parameter list. This returns a + /// null type if one of the ParamDecls does not have a type set for it yet. + Type getType(const ASTContext &C) const; + + /// Return the full function type for a set of curried parameter lists that + /// returns the specified result type. This returns a null type if one of the + /// ParamDecls does not have a type set for it yet. + /// + static Type getFullType(Type resultType, ArrayRef PL); + + + /// Return the full source range of this parameter. + SourceRange getSourceRange() const; + SourceLoc getStartLoc() const { return getSourceRange().Start; } + SourceLoc getEndLoc() const { return getSourceRange().End; } + + void dump() const; + void dump(raw_ostream &OS, unsigned Indent = 0) const; + + // void print(raw_ostream &OS) const; +}; + +} // end namespace swift. + +#endif diff --git a/include/swift/AST/Pattern.h b/include/swift/AST/Pattern.h index 694e0d54b64e0..e30f875d20be5 100644 --- a/include/swift/AST/Pattern.h +++ b/include/swift/AST/Pattern.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,7 +20,6 @@ #include "swift/Basic/SourceLoc.h" #include "swift/Basic/type_traits.h" #include "swift/AST/Decl.h" -#include "swift/AST/DefaultArgumentKind.h" #include "swift/AST/Expr.h" #include "swift/Basic/LLVM.h" #include "swift/AST/Type.h" @@ -30,7 +29,6 @@ namespace swift { class ASTContext; - class ExprHandle; /// PatternKind - The classification of different kinds of /// value-matching pattern. @@ -120,11 +118,6 @@ class alignas(8) Pattern { /// identifier if the pattern does not bind a name directly. Identifier getBoundName() const; - /// Returns the name directly bound by this pattern within the body of - /// a function, or the null identifier if the pattern does not bind a name - /// directly. - Identifier getBodyName() const; - /// If this pattern binds a single variable without any /// destructuring or conditionalizing, return that variable. VarDecl *getSingleVar() const; @@ -169,54 +162,12 @@ class alignas(8) Pattern { VD->setParentPatternStmt(S); }); } - - /// Return the number of "top-level" variables in the given pattern, - /// which looks into one level of tuple pattern to determine the # - /// of variables. If the pattern is not a tuple, the result is one. - unsigned numTopLevelVariables() const; - - /// \brief Build an implicit 'self' parameter for the specified DeclContext. - static Pattern *buildImplicitSelfParameter(SourceLoc Loc, - TypeLoc TyLoc, - DeclContext *CurDeclContext); - - /// \brief Build an implicit let parameter pattern for the specified - /// DeclContext. - static Pattern *buildImplicitLetParameter(SourceLoc loc, StringRef name, - TypeLoc TyLoc, - DeclContext *CurDeclContext); - - /// Flags used to indicate how pattern cloning should operate. - enum CloneFlags { - /// The cloned pattern should be implicit. - Implicit = 0x01, - /// The cloned pattern is for an inherited constructor; mark default - /// arguments as inherited, and mark unnamed arguments as named. - Inherited = 0x02, - /// Whether the named patterns produced from a cloned 'any' pattern is - /// are 'var'. - IsVar = 0x04 - }; - - Pattern *clone(ASTContext &context, - OptionSet options = None) const; - - /// Given that this is a function-parameter pattern, clone it in a - /// way that permits makeForwardingReference to be called on the - /// result. - Pattern *cloneForwardable(ASTContext &context, DeclContext *DC, - OptionSet options = None) const; - /// Form an un-typechecked reference to the variables bound by this - /// pattern in a manner which perfectly forwards the values. Not - /// all patterns can be forwarded. - Expr *buildForwardingRefExpr(ASTContext &context) const; - static bool classof(const Pattern *P) { return true; } //*** Allocation Routines ************************************************/ - void *operator new(size_t bytes, ASTContext &C); + void *operator new(size_t bytes, const ASTContext &C); // Make placement new and vanilla new/delete illegal for Patterns. void *operator new(size_t bytes) = delete; @@ -271,23 +222,14 @@ class ParenPattern : public Pattern { class TuplePatternElt { Identifier Label; SourceLoc LabelLoc; - llvm::PointerIntPair ThePatternAndEllipsis; - SourceLoc EllipsisLoc; - ExprHandle *Init; - DefaultArgumentKind DefArgKind; + Pattern *ThePattern; public: TuplePatternElt() = default; - explicit TuplePatternElt(Pattern *P) - : ThePatternAndEllipsis(P, false), Init(nullptr), DefArgKind(DefaultArgumentKind::None) {} + explicit TuplePatternElt(Pattern *P) : ThePattern(P) {} - TuplePatternElt(Identifier Label, SourceLoc LabelLoc, - Pattern *p, bool hasEllipsis, - SourceLoc ellipsisLoc = SourceLoc(), - ExprHandle *init = nullptr, - DefaultArgumentKind defArgKind = DefaultArgumentKind::None) - : Label(Label), LabelLoc(LabelLoc), ThePatternAndEllipsis(p, hasEllipsis), - EllipsisLoc(ellipsisLoc), Init(init), DefArgKind(defArgKind) {} + TuplePatternElt(Identifier Label, SourceLoc LabelLoc, Pattern *p) + : Label(Label), LabelLoc(LabelLoc), ThePattern(p) {} Identifier getLabel() const { return Label; } SourceLoc getLabelLoc() const { return LabelLoc; } @@ -296,20 +238,12 @@ class TuplePatternElt { LabelLoc = Loc; } - Pattern *getPattern() { return ThePatternAndEllipsis.getPointer(); } + Pattern *getPattern() { return ThePattern; } const Pattern *getPattern() const { - return ThePatternAndEllipsis.getPointer(); + return ThePattern; } - void setPattern(Pattern *p) { ThePatternAndEllipsis.setPointer(p); } - - bool hasEllipsis() const { return ThePatternAndEllipsis.getInt(); } - SourceLoc getEllipsisLoc() const { return EllipsisLoc; } - - ExprHandle *getInit() const { return Init; } - - DefaultArgumentKind getDefaultArgKind() const { return DefArgKind; } - void setDefaultArgKind(DefaultArgumentKind DAK) { DefArgKind = DAK; } + void setPattern(Pattern *p) { ThePattern = p; } }; /// A pattern consisting of a tuple of patterns. @@ -366,9 +300,6 @@ class TuplePattern : public Pattern { SourceLoc getRParenLoc() const { return RPLoc; } SourceRange getSourceRange() const; - bool hasAnyEllipsis() const; - SourceLoc getAnyEllipsisLoc() const; - static bool classof(const Pattern *P) { return P->getKind() == PatternKind::Tuple; } @@ -387,7 +318,6 @@ class NamedPattern : public Pattern { VarDecl *getDecl() const { return Var; } Identifier getBoundName() const; - Identifier getBodyName() const; StringRef getNameStr() const { return Var->getNameStr(); } SourceLoc getLoc() const { return Var->getLoc(); } @@ -674,6 +604,7 @@ class EnumElementPattern : public Pattern { } SourceRange getSourceRange() const { return {getStartLoc(), getEndLoc()}; } + TypeLoc &getParentType() { return ParentType; } TypeLoc getParentType() const { return ParentType; } static bool classof(const Pattern *P) { diff --git a/include/swift/AST/PatternNodes.def b/include/swift/AST/PatternNodes.def index a35385bdd17d6..40dc5926a8f59 100644 --- a/include/swift/AST/PatternNodes.def +++ b/include/swift/AST/PatternNodes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/PlatformKind.h b/include/swift/AST/PlatformKind.h index 4ac2580ac3aca..3da2fe800b45b 100644 --- a/include/swift/AST/PlatformKind.h +++ b/include/swift/AST/PlatformKind.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -32,7 +32,7 @@ enum class PlatformKind { #include "swift/AST/PlatformKinds.def" }; -/// Returns the short string representating the platform, suitable for +/// Returns the short string representing the platform, suitable for /// use in availability specifications (e.g., "OSX"). StringRef platformString(PlatformKind platform); @@ -40,7 +40,7 @@ StringRef platformString(PlatformKind platform); /// or None if such a platform kind does not exist. Optional platformFromString(StringRef Name); -/// Returns a human-readiable version of the platform name as a string, suitable +/// Returns a human-readable version of the platform name as a string, suitable /// for emission in diagnostics (e.g., "OS X"). StringRef prettyPlatformString(PlatformKind platform); diff --git a/include/swift/AST/PlatformKinds.def b/include/swift/AST/PlatformKinds.def index 0a97d241d8907..3325258e5fd16 100644 --- a/include/swift/AST/PlatformKinds.def +++ b/include/swift/AST/PlatformKinds.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/PrettyStackTrace.h b/include/swift/AST/PrettyStackTrace.h index 5a0e4ba48d5a9..1456a773965c2 100644 --- a/include/swift/AST/PrettyStackTrace.h +++ b/include/swift/AST/PrettyStackTrace.h @@ -1,8 +1,8 @@ -//===- PrettyStackTrace.h - Crash trace information -------------*- C++ -*-===// +//===--- PrettyStackTrace.h - Crash trace information -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines RAII classes that give better dagnostic output +// This file defines RAII classes that give better diagnostic output // about when, exactly, a crash is occurring. // //===----------------------------------------------------------------------===// diff --git a/include/swift/AST/PrintOptions.h b/include/swift/AST/PrintOptions.h index 22fe00cb924d8..a025e067f42be 100644 --- a/include/swift/AST/PrintOptions.h +++ b/include/swift/AST/PrintOptions.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -247,7 +247,7 @@ struct PrintOptions { static PrintOptions printTypeInterface(Type T, DeclContext *DC); - /// Retrive the print options that are suitable to print the testable interface. + /// Retrieve the print options that are suitable to print the testable interface. static PrintOptions printTestableInterface() { PrintOptions result = printInterface(); result.AccessibilityFilter = Accessibility::Internal; diff --git a/include/swift/AST/ProtocolConformance.h b/include/swift/AST/ProtocolConformance.h index c60c6d74e93a6..aaa68d4d787c6 100644 --- a/include/swift/AST/ProtocolConformance.h +++ b/include/swift/AST/ProtocolConformance.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -187,7 +187,9 @@ class ProtocolConformance { /// protocol conformance. /// /// The function object should accept a \c ValueDecl* for the requirement - /// followed by the \c ConcreteDeclRef for the witness. + /// followed by the \c ConcreteDeclRef for the witness. Note that a generic + /// witness will only be specialized if the conformance came from the current + /// file. template void forEachValueWitness(LazyResolver *resolver, F f) const { const ProtocolDecl *protocol = getProtocol(); @@ -252,7 +254,7 @@ class ProtocolConformance { return mem; } - /// Print a parsable and human-readable description of the identifying + /// Print a parseable and human-readable description of the identifying /// information of the protocol conformance. void printName(raw_ostream &os, const PrintOptions &PO = PrintOptions()) const; @@ -376,6 +378,9 @@ class NormalProtocolConformance : public ProtocolConformance, TypeDecl *typeDecl) const; /// Retrieve the value witness corresponding to the given requirement. + /// + /// Note that a generic witness will only be specialized if the conformance + /// came from the current file. ConcreteDeclRef getWitness(ValueDecl *requirement, LazyResolver *resolver) const; diff --git a/include/swift/AST/RawComment.h b/include/swift/AST/RawComment.h index 3b83baef652cd..ad51be01ccd54 100644 --- a/include/swift/AST/RawComment.h +++ b/include/swift/AST/RawComment.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/ReferencedNameTracker.h b/include/swift/AST/ReferencedNameTracker.h index a1738c6b58871..7864ae1f86486 100644 --- a/include/swift/AST/ReferencedNameTracker.h +++ b/include/swift/AST/ReferencedNameTracker.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/Requirement.h b/include/swift/AST/Requirement.h index 41d8a057fda71..9b54fb4642f83 100644 --- a/include/swift/AST/Requirement.h +++ b/include/swift/AST/Requirement.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/ResilienceExpansion.h b/include/swift/AST/ResilienceExpansion.h index f861539a8fd38..a8059e86b0827 100644 --- a/include/swift/AST/ResilienceExpansion.h +++ b/include/swift/AST/ResilienceExpansion.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/SILOptions.h b/include/swift/AST/SILOptions.h index 9366df5726900..67ff129762d15 100644 --- a/include/swift/AST/SILOptions.h +++ b/include/swift/AST/SILOptions.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -97,6 +97,13 @@ class SILOptions { /// Should we use a pass pipeline passed in via a json file? Null by default. StringRef ExternalPassPipelineFilename; + + /// Use super_method for native super method calls instead of function_ref. + bool UseNativeSuperMethod = false; + + /// Emit captures and function contexts using +0 caller-guaranteed ARC + /// conventions. + bool EnableGuaranteedClosureContexts = false; }; } // end namespace swift diff --git a/include/swift/AST/SearchPathOptions.h b/include/swift/AST/SearchPathOptions.h index 8f558dfbfdf48..e767946540c08 100644 --- a/include/swift/AST/SearchPathOptions.h +++ b/include/swift/AST/SearchPathOptions.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/Stmt.h b/include/swift/AST/Stmt.h index f6c50aef97a65..206b184ee7e79 100644 --- a/include/swift/AST/Stmt.h +++ b/include/swift/AST/Stmt.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -217,7 +217,7 @@ class DeferStmt : public Stmt { Expr *getCallExpr() const { return callExpr; } void setCallExpr(Expr *E) { callExpr = E; } - /// Dig the original users's body of the defer out for AST fidelity. + /// Dig the original user's body of the defer out for AST fidelity. BraceStmt *getBodyAsWritten() const; static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Defer; } @@ -800,6 +800,9 @@ class ForStmt : public LabeledStmt { SourceLoc getStartLoc() const { return getLabelLocOrKeywordLoc(ForLoc); } SourceLoc getEndLoc() const { return Body->getEndLoc(); } + + SourceLoc getFirstSemicolonLoc() const { return Semi1Loc; } + SourceLoc getSecondSemicolonLoc() const { return Semi2Loc; } NullablePtr getInitializer() const { return Initializer; } void setInitializer(Expr *V) { Initializer = V; } diff --git a/include/swift/AST/StmtNodes.def b/include/swift/AST/StmtNodes.def index 87b8f9a2b0aa1..38676dcbd5903 100644 --- a/include/swift/AST/StmtNodes.def +++ b/include/swift/AST/StmtNodes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/SubstTypeVisitor.h b/include/swift/AST/SubstTypeVisitor.h index 2abe6583a1d74..012dead8867c2 100644 --- a/include/swift/AST/SubstTypeVisitor.h +++ b/include/swift/AST/SubstTypeVisitor.h @@ -1,8 +1,8 @@ -//===-- SubstTypeVisitor.h - Visitor for substituted types ------*- C++ -*-===// +//===--- SubstTypeVisitor.h - Visitor for substituted types -----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/Substitution.h b/include/swift/AST/Substitution.h index f6754e520f759..d08de06f4632a 100644 --- a/include/swift/AST/Substitution.h +++ b/include/swift/AST/Substitution.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/Type.h b/include/swift/AST/Type.h index 8548667d4bfb8..372eecbdf0eb8 100644 --- a/include/swift/AST/Type.h +++ b/include/swift/AST/Type.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeAlignments.h b/include/swift/AST/TypeAlignments.h index b5844c9cd8c91..a40085de9f179 100644 --- a/include/swift/AST/TypeAlignments.h +++ b/include/swift/AST/TypeAlignments.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeCheckerDebugConsumer.h b/include/swift/AST/TypeCheckerDebugConsumer.h index b6133e4378af5..00a5d9ec2663b 100644 --- a/include/swift/AST/TypeCheckerDebugConsumer.h +++ b/include/swift/AST/TypeCheckerDebugConsumer.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeLoc.h b/include/swift/AST/TypeLoc.h index 8f2f7ef40f49e..a76585e453633 100644 --- a/include/swift/AST/TypeLoc.h +++ b/include/swift/AST/TypeLoc.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeMatcher.h b/include/swift/AST/TypeMatcher.h index 70461e6dbf6db..1cf6c940f176d 100644 --- a/include/swift/AST/TypeMatcher.h +++ b/include/swift/AST/TypeMatcher.h @@ -1,8 +1,8 @@ -//===-- TypeMatcher.h - Recursive Type Matcher------- -----------*- C++ -*-===// +//===--- TypeMatcher.h - Recursive Type Matcher -----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeMemberVisitor.h b/include/swift/AST/TypeMemberVisitor.h index d6afd46a89bd3..6af30cfc3d8d9 100644 --- a/include/swift/AST/TypeMemberVisitor.h +++ b/include/swift/AST/TypeMemberVisitor.h @@ -1,8 +1,8 @@ -//===-- TypeMemberVisitor.h - ASTVisitor specialization ---------*- C++ -*-===// +//===--- TypeMemberVisitor.h - ASTVisitor specialization --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeNodes.def b/include/swift/AST/TypeNodes.def index ebfffbf3baaa6..f9093ca449938 100644 --- a/include/swift/AST/TypeNodes.def +++ b/include/swift/AST/TypeNodes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeRefinementContext.h b/include/swift/AST/TypeRefinementContext.h index 14186ca77dd07..63844e750f10e 100644 --- a/include/swift/AST/TypeRefinementContext.h +++ b/include/swift/AST/TypeRefinementContext.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h index c9fce95d9e67a..1478ba255199e 100644 --- a/include/swift/AST/TypeRepr.h +++ b/include/swift/AST/TypeRepr.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -85,7 +85,7 @@ class alignas(8) TypeRepr { //*** Allocation Routines ************************************************/ - void *operator new(size_t bytes, ASTContext &C, + void *operator new(size_t bytes, const ASTContext &C, unsigned Alignment = alignof(TypeRepr)); // Make placement new and vanilla new/delete illegal for TypeReprs. @@ -98,7 +98,7 @@ class alignas(8) TypeRepr { void dump() const; /// Clone the given type representation. - TypeRepr *clone(ASTContext &ctx) const; + TypeRepr *clone(const ASTContext &ctx) const; /// Visit the top-level types in the given type representation, /// which includes the types referenced by \c IdentTypeReprs either @@ -392,44 +392,24 @@ class FunctionTypeRepr : public TypeRepr { /// [Foo] /// \endcode class ArrayTypeRepr : public TypeRepr { - // FIXME: Tail allocation. Use bits to determine whether Base/Size are - // availble. TypeRepr *Base; - llvm::PointerIntPair SizeAndOldSyntax; SourceRange Brackets; public: - ArrayTypeRepr(TypeRepr *Base, ExprHandle *Size, SourceRange Brackets, - bool OldSyntax) - : TypeRepr(TypeReprKind::Array), Base(Base), - SizeAndOldSyntax(Size, OldSyntax), Brackets(Brackets) { } + ArrayTypeRepr(TypeRepr *Base, SourceRange Brackets) + : TypeRepr(TypeReprKind::Array), Base(Base), Brackets(Brackets) { } TypeRepr *getBase() const { return Base; } - ExprHandle *getSize() const { return SizeAndOldSyntax.getPointer(); } SourceRange getBrackets() const { return Brackets; } - bool usesOldSyntax() const { return SizeAndOldSyntax.getInt(); } - static bool classof(const TypeRepr *T) { return T->getKind() == TypeReprKind::Array; } static bool classof(const ArrayTypeRepr *T) { return true; } private: - SourceLoc getStartLocImpl() const { - if (usesOldSyntax()) - return Base->getStartLoc(); - - return Brackets.Start; - } - SourceLoc getEndLocImpl() const { - // This test is necessary because the type Int[4][2] is represented as - // ArrayTypeRepr(ArrayTypeRepr(Int, 2), 4), so the range needs to cover both - // sets of brackets. - if (usesOldSyntax() && isa(Base)) - return Base->getEndLoc(); - return Brackets.End; - } + SourceLoc getStartLocImpl() const { return Brackets.Start; } + SourceLoc getEndLocImpl() const { return Brackets.End; } void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const; friend class TypeRepr; }; @@ -781,10 +761,8 @@ inline bool TypeRepr::isSimple() const { case TypeReprKind::ProtocolComposition: case TypeReprKind::Tuple: case TypeReprKind::Fixed: - return true; - case TypeReprKind::Array: - return !cast(this)->usesOldSyntax(); + return true; } llvm_unreachable("bad TypeRepr kind"); } diff --git a/include/swift/AST/TypeReprNodes.def b/include/swift/AST/TypeReprNodes.def index 1ec3f7879fe30..50404fd9d9d94 100644 --- a/include/swift/AST/TypeReprNodes.def +++ b/include/swift/AST/TypeReprNodes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeVisitor.h b/include/swift/AST/TypeVisitor.h index 15be7dc39b574..81f89c3b90639 100644 --- a/include/swift/AST/TypeVisitor.h +++ b/include/swift/AST/TypeVisitor.h @@ -1,8 +1,8 @@ -//===-- TypeVisitor.h - Type Visitor ----------------------------*- C++ -*-===// +//===--- TypeVisitor.h - Type Visitor ---------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/AST/TypeWalker.h b/include/swift/AST/TypeWalker.h index 1a3d4042babff..7b079c01e604f 100644 --- a/include/swift/AST/TypeWalker.h +++ b/include/swift/AST/TypeWalker.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -26,11 +26,11 @@ class TypeWalker { Stop }; - /// This method is called when first visiting an type before walking into its + /// This method is called when first visiting a type before walking into its /// children. virtual Action walkToTypePre(Type ty) { return Action::Continue; } - /// This method is called after visiting an type's children. + /// This method is called after visiting a type's children. virtual Action walkToTypePost(Type ty) { return Action::Continue; } /// Controls whether the original type of a SubstitutedType is visited. diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 4fc48aeff04ef..3f4e9b948870d 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -47,6 +47,7 @@ namespace swift { class GenericParamList; class GenericSignature; class Identifier; + enum class ResilienceExpansion : unsigned; class SILModule; class SILType; class TypeAliasDecl; @@ -424,7 +425,7 @@ class alignas(1 << TypeAlignInBits) TypeBase { return getRecursiveProperties().hasOpenedExistential(); } - /// Determine whether the type involves the given opend existential + /// Determine whether the type involves the given opened existential /// archetype. bool hasOpenedExistential(ArchetypeType *opened); @@ -632,7 +633,11 @@ class alignas(1 << TypeAlignInBits) TypeBase { /// unknown-released. bool hasRetainablePointerRepresentation(); - /// Determines whether this type has a bridgable object + /// \brief Given that this type is a reference type, is it known to use + /// Swift-native reference counting? + bool usesNativeReferenceCounting(ResilienceExpansion resilience); + + /// Determines whether this type has a bridgeable object /// representation, i.e., whether it is always represented as a single /// (non-nil) pointer that can be unknown-retained and /// unknown-released. @@ -667,10 +672,6 @@ class alignas(1 << TypeAlignInBits) TypeBase { /// the result would be the (parenthesized) type ((int, int)). Type getUnlabeledType(ASTContext &Context); - /// Relabel the elements of the given type with the given new - /// (top-level) labels. - Type getRelabeledType(ASTContext &Context, ArrayRef labels); - /// \brief Retrieve the type without any default arguments. Type getWithoutDefaultArgs(const ASTContext &Context); @@ -732,7 +733,7 @@ class alignas(1 << TypeAlignInBits) TypeBase { /// \code /// struct X { } /// extension X { - /// typealias SomeArray = [T]; + /// typealias SomeArray = [T] /// } /// \endcode /// @@ -834,17 +835,6 @@ class alignas(1 << TypeAlignInBits) TypeBase { /// Retrieve the type declaration directly referenced by this type, if any. TypeDecl *getDirectlyReferencedTypeDecl() const; - /// Retrieve the default argument string that would be inferred for this type, - /// assuming that we know it is inferred. - /// - /// This routine pre-supposes that we know that the given type is the type of - /// a parameter that has a default, and all we need to figure out is which - /// default argument should be print. - /// - /// FIXME: This should go away when/if inferred default arguments become - /// "real". - StringRef getInferredDefaultArgString(); - private: // Make vanilla new/delete illegal for Types. void *operator new(size_t Bytes) throw() = delete; @@ -1252,9 +1242,11 @@ class TupleTypeElt { /// is variadic. llvm::PointerIntPair NameAndVariadic; - /// \brief This is the type of the field, which is mandatory, along with the - /// kind of default argument. - llvm::PointerIntPair TyAndDefaultArg; + /// \brief This is the type of the field. + Type ElementType; + + /// The default argument, + DefaultArgumentKind DefaultArg; friend class TupleType; @@ -1268,12 +1260,12 @@ class TupleTypeElt { /*implicit*/ TupleTypeElt(TypeBase *Ty) : NameAndVariadic(Identifier(), false), - TyAndDefaultArg(Ty, DefaultArgumentKind::None) { } + ElementType(Ty), DefaultArg(DefaultArgumentKind::None) { } bool hasName() const { return !NameAndVariadic.getPointer().empty(); } Identifier getName() const { return NameAndVariadic.getPointer(); } - Type getType() const { return TyAndDefaultArg.getPointer(); } + Type getType() const { return ElementType.getPointer(); } /// Determine whether this field is variadic. bool isVararg() const { @@ -1281,9 +1273,7 @@ class TupleTypeElt { } /// Retrieve the kind of default argument available on this field. - DefaultArgumentKind getDefaultArgKind() const { - return TyAndDefaultArg.getInt(); - } + DefaultArgumentKind getDefaultArgKind() const { return DefaultArg; } /// Whether we have a default argument. bool hasDefaultArg() const { @@ -1303,11 +1293,6 @@ class TupleTypeElt { TupleTypeElt getWithType(Type T) const { return TupleTypeElt(T, getName(), getDefaultArgKind(), isVararg()); } - - /// Determine whether this tuple element has an initializer. - bool hasInit() const { - return getDefaultArgKind() != DefaultArgumentKind::None; - } }; inline Type getTupleEltType(const TupleTypeElt &elt) { @@ -1353,7 +1338,7 @@ class TupleType : public TypeBase, public llvm::FoldingSetNode { return TupleEltTypeArrayRef(getElements()); } - /// getNamedElementId - If this tuple has a element with the specified name, + /// getNamedElementId - If this tuple has an element with the specified name, /// return the element index, otherwise return -1. int getNamedElementId(Identifier I) const; @@ -2498,10 +2483,18 @@ enum class ParameterConvention { Indirect_In_Guaranteed, /// This argument is passed indirectly, i.e. by directly passing the address - /// of an object in memory. The object is instantaneously valid on entry, and - /// it must be instantaneously valid on exit. The callee may assume that the - /// address does not alias any valid object. + /// of an object in memory. The object is always valid, but the callee may + /// assume that the address does not alias any valid object and reorder loads + /// stores to the parameter as long as the whole object remains valid. Invalid + /// single-threaded aliasing may produce inconsistent results, but should + /// remain memory safe. Indirect_Inout, + + /// This argument is passed indirectly, i.e. by directly passing the address + /// of an object in memory. The object is allowed to be aliased by other + /// well-typed references, but is not allowed to be escaped. This is the + /// convention used by mutable captures in @noescape closures. + Indirect_InoutAliasable, /// This argument is passed indirectly, i.e. by directly passing the address /// of an uninitialized object in memory. The callee is responsible for @@ -2531,6 +2524,7 @@ inline bool isIndirectParameter(ParameterConvention conv) { switch (conv) { case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: case ParameterConvention::Indirect_In_Guaranteed: return true; @@ -2550,6 +2544,7 @@ inline bool isConsumedParameter(ParameterConvention conv) { return true; case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: case ParameterConvention::Direct_Unowned: case ParameterConvention::Direct_Guaranteed: @@ -2560,6 +2555,42 @@ inline bool isConsumedParameter(ParameterConvention conv) { llvm_unreachable("bad convention kind"); } +enum class InoutAliasingAssumption { + /// Assume that an inout indirect parameter may alias other objects. + /// This is the safe assumption an optimizations should make if it may break + /// memory safety in case the inout aliasing rule is violation. + Aliasing, + + /// Assume that an inout indirect parameter cannot alias other objects. + /// Optimizations should only use this if they can guarantee that they will + /// not break memory safety even if the inout aliasing rule is violated. + NotAliasing +}; + +/// Returns true if \p conv is a not-aliasing indirect parameter. +/// The \p isInoutAliasing specifies what to assume about the inout convention. +/// See InoutAliasingAssumption. +inline bool isNotAliasedIndirectParameter(ParameterConvention conv, + InoutAliasingAssumption isInoutAliasing) { + switch (conv) { + case ParameterConvention::Indirect_In: + case ParameterConvention::Indirect_Out: + case ParameterConvention::Indirect_In_Guaranteed: + return true; + + case ParameterConvention::Indirect_Inout: + return isInoutAliasing == InoutAliasingAssumption::NotAliasing; + + case ParameterConvention::Indirect_InoutAliasable: + case ParameterConvention::Direct_Unowned: + case ParameterConvention::Direct_Guaranteed: + case ParameterConvention::Direct_Owned: + case ParameterConvention::Direct_Deallocating: + return false; + } + llvm_unreachable("covered switch isn't covered?!"); +} + /// Returns true if conv is a guaranteed parameter. This may look unnecessary /// but this will allow code to generalize to handle Indirect_Guaranteed /// parameters when they are added. @@ -2570,6 +2601,7 @@ inline bool isGuaranteedParameter(ParameterConvention conv) { return true; case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: case ParameterConvention::Indirect_In: case ParameterConvention::Direct_Unowned: @@ -2587,6 +2619,7 @@ inline bool isDeallocatingParameter(ParameterConvention conv) { case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: case ParameterConvention::Indirect_In_Guaranteed: case ParameterConvention::Direct_Unowned: @@ -2599,19 +2632,20 @@ inline bool isDeallocatingParameter(ParameterConvention conv) { /// A parameter type and the rules for passing it. class SILParameterInfo { - llvm::PointerIntPair TypeAndConvention; + CanType Ty; + ParameterConvention Convention; public: - SILParameterInfo() = default; + SILParameterInfo() : Ty(), Convention((ParameterConvention)0) {} SILParameterInfo(CanType type, ParameterConvention conv) - : TypeAndConvention(type, conv) { + : Ty(type), Convention(conv) { assert(type->isLegalSILType() && "SILParameterInfo has illegal SIL type"); } CanType getType() const { - return TypeAndConvention.getPointer(); + return Ty; } ParameterConvention getConvention() const { - return TypeAndConvention.getInt(); + return Convention; } bool isIndirect() const { return isIndirectParameter(getConvention()); @@ -2624,6 +2658,10 @@ class SILParameterInfo { bool isIndirectInOut() const { return getConvention() == ParameterConvention::Indirect_Inout; } + bool isIndirectMutating() const { + return getConvention() == ParameterConvention::Indirect_Inout + || getConvention() == ParameterConvention::Indirect_InoutAliasable; + } bool isIndirectResult() const { return getConvention() == ParameterConvention::Indirect_Out; } @@ -2675,7 +2713,8 @@ class SILParameterInfo { } void profile(llvm::FoldingSetNodeID &id) { - id.AddPointer(TypeAndConvention.getOpaqueValue()); + id.AddPointer(Ty.getPointer()); + id.AddInteger((unsigned)Convention); } void dump() const; @@ -2689,7 +2728,7 @@ class SILParameterInfo { } bool operator==(SILParameterInfo rhs) const { - return TypeAndConvention == rhs.TypeAndConvention; + return Ty == rhs.Ty && Convention == rhs.Convention; } bool operator!=(SILParameterInfo rhs) const { return !(*this == rhs); @@ -3246,7 +3285,7 @@ class DictionaryType : public TypeBase { Key(key), Value(value), ImplOrContext(&ctx) {} public: - /// Return a uniqued dicitonary type with the specified key and value types. + /// Return a uniqued dictionary type with the specified key and value types. static DictionaryType *get(Type keyTy, Type valueTy); Type getKeyType() const { return Key; } @@ -3985,7 +4024,7 @@ BEGIN_CAN_TYPE_WRAPPER(ReferenceStorageType, Type) PROXY_CAN_TYPE_SIMPLE_GETTER(getReferentType) END_CAN_TYPE_WRAPPER(ReferenceStorageType, Type) -/// \brief The storage type of a variable with [unowned] ownership semantics. +/// \brief The storage type of a variable with @unowned ownership semantics. class UnownedStorageType : public ReferenceStorageType { friend class ReferenceStorageType; UnownedStorageType(Type referent, const ASTContext *C, @@ -3998,6 +4037,10 @@ class UnownedStorageType : public ReferenceStorageType { ReferenceStorageType::get(referent, Ownership::Unowned, C)); } + /// Is this unowned storage type known to be loadable within the given + /// resilience scope? + bool isLoadable(ResilienceExpansion resilience) const; + // Implement isa/cast/dyncast/etc. static bool classof(const TypeBase *T) { return T->getKind() == TypeKind::UnownedStorage; @@ -4312,7 +4355,7 @@ inline TupleTypeElt::TupleTypeElt(Type ty, DefaultArgumentKind defArg, bool isVariadic) : NameAndVariadic(name, isVariadic), - TyAndDefaultArg(ty.getPointer(), defArg) + ElementType(ty), DefaultArg(defArg) { assert(!isVariadic || isa(ty.getPointer()) || diff --git a/include/swift/AST/USRGeneration.h b/include/swift/AST/USRGeneration.h index 5eed154d0477b..2e0255ea32cbb 100644 --- a/include/swift/AST/USRGeneration.h +++ b/include/swift/AST/USRGeneration.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/ASTSectionImporter/ASTSectionImporter.h b/include/swift/ASTSectionImporter/ASTSectionImporter.h index 5cf16e56e2016..2820bb86494d7 100644 --- a/include/swift/ASTSectionImporter/ASTSectionImporter.h +++ b/include/swift/ASTSectionImporter/ASTSectionImporter.h @@ -1,8 +1,8 @@ -//===--- ASTSectionImporter.cpp - Import AST Section Modules ---*- C++ -*--===// +//===--- ASTSectionImporter.h - Import AST Section Modules ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,7 +23,7 @@ namespace swift { class SerializedModuleLoader; - /// \brief Povided a memory buffer with an entire Mach-O __apple_ast + /// \brief Provided a memory buffer with an entire Mach-O __apple_ast /// section, this function makes memory buffer copies of all swift /// modules found in it and registers them using /// registerMemoryBuffer() so they can be found by loadModule(). The diff --git a/include/swift/Basic/Algorithm.h b/include/swift/Basic/Algorithm.h index a1134e802d7fa..c2cef45aff32a 100644 --- a/include/swift/Basic/Algorithm.h +++ b/include/swift/Basic/Algorithm.h @@ -1,8 +1,8 @@ -//===--- Algorithm.h - -------------------------------------------*- C++ -*-==// +//===--- Algorithm.h - ------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/ArrayRefView.h b/include/swift/Basic/ArrayRefView.h index 6cddda4f9296e..f9181db6dc334 100644 --- a/include/swift/Basic/ArrayRefView.h +++ b/include/swift/Basic/ArrayRefView.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/AssertImplements.h b/include/swift/Basic/AssertImplements.h index 81894acb6ae5e..d4aa08b42ded1 100644 --- a/include/swift/Basic/AssertImplements.h +++ b/include/swift/Basic/AssertImplements.h @@ -1,8 +1,8 @@ -//===- AssertImplements.h - Assert that a class overrides a function ------===// +//===--- AssertImplements.h - Assert that a class overrides a function ----===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/BlotMapVector.h b/include/swift/Basic/BlotMapVector.h index 645c2ee1da441..a80be3093cfd6 100644 --- a/include/swift/Basic/BlotMapVector.h +++ b/include/swift/Basic/BlotMapVector.h @@ -1,8 +1,8 @@ -//===- BlotMapVector.h - Map vector with "blot" operation -----*- C++ -*--===// +//===--- BlotMapVector.h - Map vector with "blot" operation ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/BlotSetVector.h b/include/swift/Basic/BlotSetVector.h index 92ca3dfd4ad53..d4066d501566d 100644 --- a/include/swift/Basic/BlotSetVector.h +++ b/include/swift/Basic/BlotSetVector.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -99,7 +99,7 @@ class BlotSetVector { /// V1. void replace(const ValueT &V1, const ValueT &V2) { auto Iter1 = Map.find(V1); - assert(Iter1 != Map.end() && "Can not replace value that is not in set"); + assert(Iter1 != Map.end() && "Cannot replace value that is not in set"); unsigned V1Index = Iter1->second; Map.erase(V1); diff --git a/include/swift/Basic/Cache.h b/include/swift/Basic/Cache.h index e3dfc995723d0..bcfd357e1eb2d 100644 --- a/include/swift/Basic/Cache.h +++ b/include/swift/Basic/Cache.h @@ -1,8 +1,8 @@ -//===--- Cache.h - Caching mechanism interface -------------------*- C++ -*-==// +//===--- Cache.h - Caching mechanism interface ------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/ClusteredBitVector.h b/include/swift/Basic/ClusteredBitVector.h index dcc5cfa31868a..99114d9c3e172 100644 --- a/include/swift/Basic/ClusteredBitVector.h +++ b/include/swift/Basic/ClusteredBitVector.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/Defer.h b/include/swift/Basic/Defer.h index d412db123b503..95e46e7cb2064 100644 --- a/include/swift/Basic/Defer.h +++ b/include/swift/Basic/Defer.h @@ -1,8 +1,8 @@ -//===- Defer.h - 'defer' helper macro ---------------------------*- C++ -*-===// +//===--- Defer.h - 'defer' helper macro -------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // -// This filed defines a 'defer' macro for performing a cleanup on any exit out +// This file defines a 'defer' macro for performing a cleanup on any exit out // of a scope. // //===----------------------------------------------------------------------===// @@ -18,11 +18,12 @@ #ifndef __SWIFT_DEFER_H #define __SWIFT_DEFER_H +#include + namespace swift { template class DoAtScopeExit { F &Fn; - DoAtScopeExit(DoAtScopeExit&) = delete; void operator=(DoAtScopeExit&) = delete; public: DoAtScopeExit(F &Fn) : Fn(Fn){} @@ -30,8 +31,17 @@ namespace swift { Fn(); } }; + + namespace detail { + struct DeferTask {}; + template + DoAtScopeExit::type> operator+(DeferTask, F&& fn) { + return DoAtScopeExit::type>(fn); + } + } } + #define DEFER_CONCAT_IMPL(x, y) x##y #define DEFER_MACRO_CONCAT(x, y) DEFER_CONCAT_IMPL(x, y) @@ -39,16 +49,13 @@ namespace swift { /// This macro is used to register a function / lambda to be run on exit from a /// scope. Its typical use looks like: /// -/// defer([&]{ +/// defer { /// stuff -/// }) +/// }; /// -#define defer(x) \ - auto DEFER_MACRO_CONCAT(defer_func, __LINE__) = (x); \ - swift::DoAtScopeExit \ - DEFER_MACRO_CONCAT(defer_local, __LINE__)\ - (DEFER_MACRO_CONCAT(defer_func, __LINE__)); +#define defer \ + auto DEFER_MACRO_CONCAT(defer_func, __COUNTER__) = \ + ::swift::detail::DeferTask() + [&]() #endif - diff --git a/include/swift/Basic/Demangle.h b/include/swift/Basic/Demangle.h index dba1292b81309..c9d1807a98de2 100644 --- a/include/swift/Basic/Demangle.h +++ b/include/swift/Basic/Demangle.h @@ -1,8 +1,8 @@ -//===--- Demangle.h - Interface to Swift symbol demangling -------*- C++ -*-==// +//===--- Demangle.h - Interface to Swift symbol demangling ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -78,7 +78,8 @@ enum class FunctionSigSpecializationParamKind : unsigned { ConstantPropFloat = 3, ConstantPropString = 4, ClosureProp = 5, - InOutToValue = 6, + BoxToValue = 6, + BoxToStack = 7, // Option Set Flags use bits 6-31. This gives us 26 bits to use for option // flags. @@ -89,7 +90,7 @@ enum class FunctionSigSpecializationParamKind : unsigned { /// The pass that caused the specialization to occur. We use this to make sure /// that two passes that generate similar changes do not yield the same -/// mangling. This currently can not happen, so this is just a safety measure +/// mangling. This currently cannot happen, so this is just a safety measure /// that creates separate name spaces. enum class SpecializationPass : uint8_t { AllocBoxToStack, @@ -101,7 +102,7 @@ enum class SpecializationPass : uint8_t { }; static inline char encodeSpecializationPass(SpecializationPass Pass) { - return char(uint8_t(Pass)) + 48; + return char(uint8_t(Pass)) + '0'; } enum class ValueWitnessKind { diff --git a/include/swift/Basic/DemangleNodes.def b/include/swift/Basic/DemangleNodes.def index 58e5c5752d4d0..0c05714bfda3b 100644 --- a/include/swift/Basic/DemangleNodes.def +++ b/include/swift/Basic/DemangleNodes.def @@ -1,8 +1,8 @@ -//===-- DemangleNodes.def - Demangling Tree Metaprogramming -----*- C++ -*-===// +//===--- DemangleNodes.def - Demangling Tree Metaprogramming ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,6 +30,8 @@ NODE(ArchetypeRef) NODE(ArgumentTuple) NODE(AssociatedType) NODE(AssociatedTypeRef) +NODE(AssociatedTypeMetadataAccessor) +NODE(AssociatedTypeWitnessTableAccessor) NODE(AutoClosureType) NODE(BoundGenericClass) NODE(BoundGenericEnum) @@ -49,8 +51,6 @@ NODE(DependentGenericSameTypeRequirement) NODE(DependentGenericType) NODE(DependentMemberType) NODE(DependentGenericParamType) -NODE(DependentProtocolWitnessTableGenerator) -NODE(DependentProtocolWitnessTableTemplate) CONTEXT_NODE(Destructor) CONTEXT_NODE(DidSet) NODE(Directness) @@ -71,6 +71,8 @@ NODE(FunctionSignatureSpecializationParamKind) NODE(FunctionSignatureSpecializationParamPayload) NODE(FunctionType) NODE(Generics) +NODE(GenericProtocolWitnessTable) +NODE(GenericProtocolWitnessTableInstantiationFunction) NODE(GenericSpecialization) NODE(GenericSpecializationParam) NODE(GenericType) @@ -128,6 +130,7 @@ NODE(QualifiedArchetype) NODE(ReabstractionThunk) NODE(ReabstractionThunkHelper) NODE(ReturnType) +NODE(SILBoxType) NODE(SelfTypeRef) CONTEXT_NODE(Setter) NODE(SpecializationPassID) diff --git a/include/swift/Basic/DemangleWrappers.h b/include/swift/Basic/DemangleWrappers.h index 080320d2c2467..07d121994f6bd 100644 --- a/include/swift/Basic/DemangleWrappers.h +++ b/include/swift/Basic/DemangleWrappers.h @@ -1,8 +1,8 @@ -//===--- DemangleWrappers.h --------------------------------------*- C++ -*-==// +//===--- DemangleWrappers.h -------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/DiagnosticConsumer.h b/include/swift/Basic/DiagnosticConsumer.h index 7a1860ea136b1..80ce1d27ab01e 100644 --- a/include/swift/Basic/DiagnosticConsumer.h +++ b/include/swift/Basic/DiagnosticConsumer.h @@ -1,8 +1,8 @@ -//===- DiagnosticConsumer.h - Diagnostic Consumer Interface -----*- C++ -*-===// +//===--- DiagnosticConsumer.h - Diagnostic Consumer Interface ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,12 +19,8 @@ #ifndef SWIFT_BASIC_DIAGNOSTIC_CONSUMER_H #define SWIFT_BASIC_DIAGNOSTIC_CONSUMER_H -#include "swift/Basic/LLVM.h" #include "swift/Basic/SourceLoc.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/SourceMgr.h" -#include namespace swift { class SourceManager; diff --git a/include/swift/Basic/DiagnosticOptions.h b/include/swift/Basic/DiagnosticOptions.h index 20b232faf913e..91fb9e4df34d3 100644 --- a/include/swift/Basic/DiagnosticOptions.h +++ b/include/swift/Basic/DiagnosticOptions.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/DiverseList.h b/include/swift/Basic/DiverseList.h index 771327bc7bf00..8a2169e35001c 100644 --- a/include/swift/Basic/DiverseList.h +++ b/include/swift/Basic/DiverseList.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -29,7 +29,7 @@ namespace swift { template class DiverseListImpl; -/// DiverseList - A list of heterogenously-typed objects. +/// DiverseList - A list of heterogeneously-typed objects. /// /// \tparam T - A common base class of the objects in the list; must /// provide an allocated_size() const method. diff --git a/include/swift/Basic/DiverseStack.h b/include/swift/Basic/DiverseStack.h index a63dd826a76fb..01351273cee65 100644 --- a/include/swift/Basic/DiverseStack.h +++ b/include/swift/Basic/DiverseStack.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -29,7 +29,7 @@ namespace swift { template class DiverseStackImpl; -/// DiverseStack - A stack of heterogenously-typed objects. +/// DiverseStack - A stack of heterogeneously-typed objects. /// /// \tparam T - A common base class of the objects on the stack; must /// provide an allocated_size() const method. diff --git a/include/swift/Basic/Dwarf.h b/include/swift/Basic/Dwarf.h index cceb2088e9391..c568990d3e8a0 100644 --- a/include/swift/Basic/Dwarf.h +++ b/include/swift/Basic/Dwarf.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/EditorPlaceholder.h b/include/swift/Basic/EditorPlaceholder.h index ea28420b5706c..50df069c15bc0 100644 --- a/include/swift/Basic/EditorPlaceholder.h +++ b/include/swift/Basic/EditorPlaceholder.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/EncodedSequence.h b/include/swift/Basic/EncodedSequence.h index b4c0a8d099211..c0a8bfc342e14 100644 --- a/include/swift/Basic/EncodedSequence.h +++ b/include/swift/Basic/EncodedSequence.h @@ -1,8 +1,8 @@ -//===--- EncodedSequence.h - A byte-encoded sequence -----------*- C++ -*-===// +//===--- EncodedSequence.h - A byte-encoded sequence ------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/Fallthrough.h b/include/swift/Basic/Fallthrough.h index 0e28731c6c0a6..c697722545fc9 100644 --- a/include/swift/Basic/Fallthrough.h +++ b/include/swift/Basic/Fallthrough.h @@ -1,8 +1,8 @@ -//===- Fallthrough.h - switch fallthrough annotation macro ------*- C++ -*-===// +//===--- Fallthrough.h - switch fallthrough annotation macro ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // -// This filed defines a SWIFT_FALLTHROUGH macro to annotate intentional +// This file defines a SWIFT_FALLTHROUGH macro to annotate intentional // fallthrough between switch cases. For compilers that support the // "clang::fallthrough" attribute, it expands to an empty statement with the // attribute applied; otherwise, it expands to just an empty statement. diff --git a/include/swift/Basic/FileSystem.h b/include/swift/Basic/FileSystem.h index 59d99df55c928..749818329f166 100644 --- a/include/swift/Basic/FileSystem.h +++ b/include/swift/Basic/FileSystem.h @@ -1,8 +1,8 @@ -//===--- FileSystem.cpp - Extra helpers for manipulating files --*- C++ -*-===// +//===--- FileSystem.h - Extra helpers for manipulating files ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/FlaggedPointer.h b/include/swift/Basic/FlaggedPointer.h index b70fb8c93d4be..c6d2c349a0b35 100644 --- a/include/swift/Basic/FlaggedPointer.h +++ b/include/swift/Basic/FlaggedPointer.h @@ -1,8 +1,8 @@ -//===- FlaggedPointer.h - Explicit pointer tagging container ----*- C++ -*-===// +//===--- FlaggedPointer.h - Explicit pointer tagging container --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/JSONSerialization.h b/include/swift/Basic/JSONSerialization.h index 9fd98b9d9bfaf..0663aa5461eb3 100644 --- a/include/swift/Basic/JSONSerialization.h +++ b/include/swift/Basic/JSONSerialization.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -284,7 +284,7 @@ struct missingTraits : public std::integral_constant::value && !has_ScalarTraits::value && !has_ObjectTraits::value - && !has_ArrayTraits::value> {}; + && !has_ArrayTraits::value> {}; template struct validatedObjectTraits : public std::integral_constantpostflightKey(SaveInfo); - } - else { + } else { if ( UseDefault ) Val = DefaultValue; } @@ -614,7 +613,7 @@ operator<<(Output &yout, T &map) { return yout; } -// Define non-member operator<< so that Output can stream out a array. +// Define non-member operator<< so that Output can stream out an array. template inline typename diff --git a/include/swift/Basic/LLVM.h b/include/swift/Basic/LLVM.h index 6537f52ad0037..2bfb5b33755b0 100644 --- a/include/swift/Basic/LLVM.h +++ b/include/swift/Basic/LLVM.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/LLVMInitialize.h b/include/swift/Basic/LLVMInitialize.h index 53365f86f5e60..599e78406ae99 100644 --- a/include/swift/Basic/LLVMInitialize.h +++ b/include/swift/Basic/LLVMInitialize.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 66dae000800ad..badd9f00afcab 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -130,7 +130,7 @@ namespace swift { /// This is for testing purposes. std::string DebugForbidTypecheckPrefix; - /// Number of paralellel processes performing AST verification. + /// Number of parallel processes performing AST verification. unsigned ASTVerifierProcessCount = 1U; /// ID of the current process for the purposes of AST verification. @@ -173,7 +173,9 @@ namespace swift { Target.getiOSVersion(major, minor, revision); } else if (Target.isWatchOS()) { Target.getOSVersion(major, minor, revision); - } else if (Target.isOSLinux() || Target.getTriple().empty()) { + } else if (Target.isOSLinux() || Target.isOSFreeBSD() || + Target.getTriple().empty()) + { major = minor = revision = 0; } else { llvm_unreachable("Unsupported target OS"); diff --git a/include/swift/Basic/Lazy.h b/include/swift/Basic/Lazy.h index e10afc49b019f..e720a87a1f906 100644 --- a/include/swift/Basic/Lazy.h +++ b/include/swift/Basic/Lazy.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -74,10 +74,10 @@ template inline T &Lazy::get(void (*initCallback)(void*)) { } // namespace swift #define SWIFT_LAZY_CONSTANT(INITIAL_VALUE) \ - ({ \ + ([]{ \ using T = ::std::remove_reference::type; \ static ::swift::Lazy TheLazy; \ - TheLazy.get([](void *ValueAddr){ ::new(ValueAddr) T{INITIAL_VALUE}; });\ - }) + return TheLazy.get([](void *ValueAddr){ ::new(ValueAddr) T{INITIAL_VALUE}; });\ + }()) #endif // SWIFT_BASIC_LAZY_H diff --git a/include/swift/Basic/Malloc.h b/include/swift/Basic/Malloc.h index 2ac42e6ef5a79..1f11c133251a0 100644 --- a/include/swift/Basic/Malloc.h +++ b/include/swift/Basic/Malloc.h @@ -1,8 +1,8 @@ -//===- Malloc.h - Aligned malloc interface ----------------------*- C++ -*-===// +//===--- Malloc.h - Aligned malloc interface --------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/NullablePtr.h b/include/swift/Basic/NullablePtr.h index c39071dc35ac6..8f827a4625f72 100644 --- a/include/swift/Basic/NullablePtr.h +++ b/include/swift/Basic/NullablePtr.h @@ -1,8 +1,8 @@ -//===- NullablePtr.h - A pointer that allows null ---------------*- C++ -*-===// +//===--- NullablePtr.h - A pointer that allows null -------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/OptionSet.h b/include/swift/Basic/OptionSet.h index 977527e9b19c6..c2763fdf7b600 100644 --- a/include/swift/Basic/OptionSet.h +++ b/include/swift/Basic/OptionSet.h @@ -1,8 +1,8 @@ -//===-- OptionSet.h - Sets of boolean options -------------------*- C++ -*-===// +//===--- OptionSet.h - Sets of boolean options ------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/OptionalEnum.h b/include/swift/Basic/OptionalEnum.h index cfcd34e9b4e90..3d594ab4d998e 100644 --- a/include/swift/Basic/OptionalEnum.h +++ b/include/swift/Basic/OptionalEnum.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/Platform.h b/include/swift/Basic/Platform.h index c60444a42ebfe..4b151a7dbc4a4 100644 --- a/include/swift/Basic/Platform.h +++ b/include/swift/Basic/Platform.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/PointerIntEnum.h b/include/swift/Basic/PointerIntEnum.h new file mode 100644 index 0000000000000..8e18c2a3a7d7e --- /dev/null +++ b/include/swift/Basic/PointerIntEnum.h @@ -0,0 +1,247 @@ +//===--- PointerIntEnum.h -------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "swift/Basic/LLVM.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include +#include +#include +#include +#include +#include + +namespace swift { + +/// A tiny meta function to compute the log2 of a compile time constant. +/// +/// *NOTE* This will be in an updated version of LLVM so this should be removed +/// at that point in time. +template +struct ConstantLog2 + : std::integral_constant::value + 1> {}; +template <> struct ConstantLog2<1> : std::integral_constant {}; + +/// A meta function for computing at compile time cleanly the value for an index +/// kind's value without using cpp macros. +template +struct PointerIntEnumIndexKindValue + : std::integral_constant::value)) | + unsigned(EnumTy::FirstIndexKind)> {}; + +/// A pointer sized ADT that is able to compactly represent a Swift like enum +/// that can contain both Integer and Pointer payloads. It attempts to optimize +/// for the case of being able to represent as many pointer cases as possible +/// while allowing for indices to be stored as well. Without any loss of +/// generality assume that T* is our stored pointer. Then this is done as +/// follows: +/// +/// 1. A PointerIntEnum for which bits [0, (num_tagged_bits(T*)-1)] are not all +/// set to 1 represent an enum with a pointer case. This means that one can have +/// at most ((1 << num_tagged_bits(T*)) - 2) enum cases associated with +/// pointers. +/// +/// 2. A PointerIntEnum for which bits [0, (num_tagged_bits(T*)-1)] are all set +/// is either an invalid PointerIntEnum or an index. +/// +/// 3. A PointerIntEnum with all bits set is an invalid PointerIntEnum. +/// +/// 4. A PointerIntEnum for which bits [0, (num_tagged_bits(T*)-1)] are all set +/// but for which the upper bits are not all set is an index enum. The case bits +/// for the index PointerIntEnum are stored in bits [num_tagged_bits(T*), +/// num_tagged_bits(T*) + num_index_case_bits]. Then the actual index is stored +/// in the remaining top bits. For the case in which this is used in swift +/// currently, we use 3 index bits meaning that on a 32 bit system we have 26 +/// bits for representing indices meaning we can represent indices up to +/// 67_108_862. Any index larger than that will result in an invalid +/// PointerIntEnum. On 64 bit we have many more bits than that. +/// +/// By using this representation, we can make PointerIntEnum a true value type +/// that is trivially constructible and destructible without needing to malloc +/// memory. +/// +/// In order for all of this to work, the user of this needs to construct an +/// enum with the appropriate case structure that allows the data structure to +/// determine what cases are pointer and which are indices. For instance the one +/// used by Projection in swift is: +/// +/// enum class NewProjectionKind : unsigned { +/// // PointerProjectionKinds +/// Upcast = 0, +/// RefCast = 1, +/// BitwiseCast = 2, +/// FirstPointerKind = Upcast, +/// LastPointerKind = BitwiseCast, +/// +/// +/// // This needs to be set to ((1 << num_tagged_bits(T*)) - 1). It +/// // represents the first NonPointerKind. +/// FirstIndexKind = 7, +/// +/// // Index Projection Kinds +/// Struct = PointerIntEnumIndexKindValue<0, EnumTy>::value, +/// Tuple = PointerIntEnumIndexKindValue<1, EnumTy>::value, +/// Index = PointerIntEnumIndexKindValue<2, EnumTy>::value, +/// Class = PointerIntEnumIndexKindValue<3, EnumTy>::value, +/// Enum = PointerIntEnumIndexKindValue<4, EnumTy>::value, +/// LastIndexKind = Enum, +/// }; +/// +template > +class PointerIntEnum { + + // Make sure that the enum fits our requirements. + static_assert(unsigned(EnumTy::FirstIndexKind) == + ((1U << NumPointerKindBits) - 1U), + "Invalid Enum"); + static_assert(unsigned(EnumTy::FirstIndexKind) <= + unsigned(EnumTy::LastIndexKind), + "Invalid Enum"); + static_assert(unsigned(EnumTy::FirstPointerKind) <= + unsigned(EnumTy::LastPointerKind), + "Invalid Enum"); + static_assert(unsigned(EnumTy::LastPointerKind) < + unsigned(EnumTy::FirstIndexKind), + "Invalid Enum"); + + /// The offset in bits where an index would be stored. + static constexpr unsigned IndexShiftOffset = + NumIndexKindBits + NumPointerKindBits; + + /// The number of bits in a PointerIntEnum that can be used to store indices. + static constexpr unsigned NumIndexBits = + sizeof(uintptr_t) * CHAR_BIT - IndexShiftOffset; + + /// The maximum index that can be stored for an index PointerIntEnum case. + static constexpr uintptr_t MaxIndex = (uintptr_t(1) << NumIndexBits) - 2; + + /// The bit representation of an Invalid PointerIntEnum's storage. + static constexpr uintptr_t InvalidStorage = uintptr_t(0) - 1; + + /// The pointer sized type used for the actual storage. + /// + /// Never access this directly. Instead use the following methods: + /// + /// * getKind(): Same as RawKind except if the kind is LargeIndex, will + /// discover the real underlying kind in the malloced memory. + /// * getIndex(): Asserts if getKind() is a pointer storing kind. + /// * getPointer(): Returns the underlying pointer cast into + /// PointerTy. Asserts if getKind() is an index storing kind. + uintptr_t Storage; + +public: + PointerIntEnum() : Storage(InvalidStorage) {} + + PointerIntEnum(EnumTy Kind, uintptr_t NewIndex) { + initWithIndex(Kind, NewIndex); + } + + PointerIntEnum(EnumTy Kind, PointerTy Ptr) { initWithPointer(Kind, Ptr); } + + PointerIntEnum(PointerIntEnum &&P) = default; + PointerIntEnum(const PointerIntEnum &P) = default; + ~PointerIntEnum() = default; + PointerIntEnum &operator=(const PointerIntEnum &P) = default; + PointerIntEnum &operator=(PointerIntEnum &&P) = default; + + bool isValid() const { return Storage != InvalidStorage; } + + bool operator==(const PointerIntEnum &Other) const { + // If this value is not valid, it can only equal another invalid + // PointerIntEnum. + if (!isValid()) + return !Other.isValid(); + + // Otherwise just compare the raw storage. + return Other.Storage == Storage; + } + + bool operator!=(const PointerIntEnum &Other) const { + return !(*this == Other); + } + + /// Convenience method for getting the kind of this enum. Returns None if this + /// enum is invalid. + Optional getKind() const { + if (!isValid()) + return None; + + // Check if the bottom pointer bits are all not set. If that is true then we + // know that we have a pointer kind. + unsigned PointerBits = Storage & uintptr_t(EnumTy::FirstIndexKind); + if (PointerBits != unsigned(EnumTy::FirstIndexKind)) { + return EnumTy(PointerBits); + } + + // Otherwise, we have an index kind. Just mask off the actual index bits and + // return the kind. + unsigned Mask = (1 << IndexShiftOffset) - 1; + unsigned MaskedStorage = Storage & Mask; + return EnumTy(MaskedStorage); + } + + /// Convenience method for getting the underlying index. Assumes that this + /// projection is valid. Otherwise it asserts. + uintptr_t getIndex() const { + assert(isValid()); + assert(unsigned(*getKind()) >= unsigned(EnumTy::FirstIndexKind)); + return Storage >> IndexShiftOffset; + } + + PointerTy getPointer() const { + uintptr_t Value = Storage & ~(uintptr_t(EnumTy::FirstIndexKind)); + return reinterpret_cast(Value); + } + + /// Return the raw storage of the type. Used for testing purposes. + uintptr_t getStorage() const { return Storage; } + +private: + void initInvalid() { Storage = InvalidStorage; } + + /// Initialize this PointerIntEnum with the kind \p Kind and the Pointer \p + /// Ptr. + /// + /// This is an internal helper routine that should not be used directly since + /// it does not properly handle freeing memory. + void initWithIndex(EnumTy Kind, uintptr_t NewIndex) { + // If we can not represent this index, make the PointerIntEnum invalid. + if (NewIndex > MaxIndex) { + Storage = InvalidStorage; + return; + } + + Storage = uintptr_t(Kind) | (uintptr_t(NewIndex) << IndexShiftOffset); + } + + /// Initialize this PointerIntEnum with the kind \p Kind and the Pointer \p + /// Ptr. + /// + /// This is an internal helper routine that should not be used directly since + /// it does not properly handle freeing memory. + void initWithPointer(EnumTy Kind, PointerTy Ptr) { + // Make sure the pointer is at least aligned to NumPointerKindBits. + assert((uintptr_t(Ptr) & ((1 << NumPointerKindBits) - 1)) == 0); + // Make sure that Kind is a PointerKind. + assert(unsigned(Kind) >= unsigned(EnumTy::FirstPointerKind)); + assert(unsigned(Kind) <= unsigned(EnumTy::LastPointerKind)); + + Storage = uintptr_t(Ptr); + Storage |= uintptr_t(Kind); + } +}; + +} // end swift namespace diff --git a/include/swift/Basic/PrefixMap.h b/include/swift/Basic/PrefixMap.h index 47e1a55100f73..7841f7267e0f0 100644 --- a/include/swift/Basic/PrefixMap.h +++ b/include/swift/Basic/PrefixMap.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/PrettyStackTrace.h b/include/swift/Basic/PrettyStackTrace.h index 536dc3abae0de..7d94fde0f5306 100644 --- a/include/swift/Basic/PrettyStackTrace.h +++ b/include/swift/Basic/PrettyStackTrace.h @@ -1,8 +1,8 @@ -//===--- PrettyStackTrace.h - Generic stack-trace prettifiers ----*- C++ -*-==// +//===--- PrettyStackTrace.h - Generic stack-trace prettifiers ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/PrimitiveParsing.h b/include/swift/Basic/PrimitiveParsing.h index 90ea9719b5465..780173238e1ec 100644 --- a/include/swift/Basic/PrimitiveParsing.h +++ b/include/swift/Basic/PrimitiveParsing.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/Program.h b/include/swift/Basic/Program.h index 3d98377e32289..061639afc602c 100644 --- a/include/swift/Basic/Program.h +++ b/include/swift/Basic/Program.h @@ -1,8 +1,8 @@ -//===- swift/Basic/Program.h ------------------------------------*- C++ -*-===// +//===--- Program.h ----------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/Punycode.h b/include/swift/Basic/Punycode.h index 3fbfcb09475ca..de7974160aadf 100644 --- a/include/swift/Basic/Punycode.h +++ b/include/swift/Basic/Punycode.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/QuotedString.h b/include/swift/Basic/QuotedString.h index 5fffc896da3c2..cee2a416b6d60 100644 --- a/include/swift/Basic/QuotedString.h +++ b/include/swift/Basic/QuotedString.h @@ -1,8 +1,8 @@ -//===- QuotedString.h - Print a string in double-quotes ---------*- C++ -*-===// +//===--- QuotedString.h - Print a string in double-quotes -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/Range.h b/include/swift/Basic/Range.h index efdb6d273a4ea..f27fc738e0428 100644 --- a/include/swift/Basic/Range.h +++ b/include/swift/Basic/Range.h @@ -1,8 +1,8 @@ -//===- Range.h - Classes for conveniently working with ranges ---*- C++ -*-===// +//===--- Range.h - Classes for conveniently working with ranges -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -61,12 +61,13 @@ namespace swift { } /// A range of integers. This type behaves roughly like an ArrayRef. -template class IntRange { +template class IntRange { static_assert(std::is_integral::value, "T must be an integer type"); T Begin; T End; public: IntRange() : Begin(0), End(0) {} + IntRange(T end) : Begin(0), End(end) {} IntRange(T begin, T end) : Begin(begin), End(end) { assert(begin <= end); } @@ -165,6 +166,17 @@ indices(const T &collection) { return IntRange().size())>(0, collection.size()); } +/// Returns an Int range [start, end). +static inline IntRange range(unsigned start, unsigned end) { + assert(start <= end && "Invalid integral range"); + return IntRange(start, end); +} + +/// Returns an Int range [0, end). +static inline IntRange range(unsigned end) { + return range(0, end); +} + /// A random access range that provides iterators that can be used to iterate /// over the (element, index) pairs of a collection. template class EnumeratorRange { @@ -280,6 +292,11 @@ none_of(Range R, Predicate P) { return std::none_of(R.begin(), R.end(), P); } +template +inline unsigned count_if(Range R, Predicate P) { + return std::count_if(R.begin(), R.end(), P); +} + } // namespace swift #endif diff --git a/include/swift/Basic/RelativePointer.h b/include/swift/Basic/RelativePointer.h index 188ddf26d9505..c5c084185a55a 100644 --- a/include/swift/Basic/RelativePointer.h +++ b/include/swift/Basic/RelativePointer.h @@ -1,8 +1,8 @@ -//===-- RelativePointer.h - Relative Pointer Support ------------*- C++ -*-===// +//===--- RelativePointer.h - Relative Pointer Support -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -102,6 +102,10 @@ class RelativeDirectPointerImpl { return reinterpret_cast(absolute); } + /// A zero relative offset encodes a null reference. + bool isNull() const & { + return RelativeOffset == 0; + } }; /// A direct relative reference to an object. @@ -122,6 +126,8 @@ class RelativeDirectPointer : const typename super::ValueTy *operator->() const & { return this->get(); } + + using super::isNull; }; /// A specialization of RelativeDirectPointer for function pointers, @@ -139,6 +145,8 @@ class RelativeDirectPointer : RetTy operator()(ArgTy...arg) { return this->get()(std::forward(arg)...); } + + using super::isNull; }; } diff --git a/include/swift/Basic/STLExtras.h b/include/swift/Basic/STLExtras.h index f0182b6df52ed..b50af049727cc 100644 --- a/include/swift/Basic/STLExtras.h +++ b/include/swift/Basic/STLExtras.h @@ -1,8 +1,8 @@ -//===- STLExtras.h - additions to the STL -----------------------*- C++ -*-===// +//===--- STLExtras.h - additions to the STL ---------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -352,7 +352,7 @@ makeTransformRange(Range range, Operation op) { } /// An iterator that filters and transforms the results of an -/// underlying forward iterator based on an transformation from the underlying +/// underlying forward iterator based on a transformation from the underlying /// value type to an optional result type. /// /// \tparam Iterator the underlying iterator. @@ -451,9 +451,9 @@ makeOptionalTransformIterator(Iterator current, Iterator end, } /// A range filtered and transformed by the optional transform. -template +template class OptionalTransformRange { - typedef typename Range::iterator Iterator; Iterator First, Last; OptionalTransform Op; @@ -558,6 +558,21 @@ void sortUnique( C.erase(std::unique(C.begin(), C.end()), C.end()); } +/// Sorts and then uniques a container with random access iterators and an erase +/// method that removes a range specified by random access iterators. +template +void sortUnique( + Container &C, + Comparator Cmp, + typename std::enable_if< + std::is_same::iterator_category, + std::random_access_iterator_tag>::value, + void>::type * = nullptr) { + std::sort(C.begin(), C.end(), Cmp); + C.erase(std::unique(C.begin(), C.end()), C.end()); +} + } // end namespace swift #endif diff --git a/include/swift/Basic/SourceLoc.h b/include/swift/Basic/SourceLoc.h index 050033a0c64fc..debb69396b544 100644 --- a/include/swift/Basic/SourceLoc.h +++ b/include/swift/Basic/SourceLoc.h @@ -1,8 +1,8 @@ -//===- SourceLoc.h - Source Locations and Ranges ----------------*- C++ -*-===// +//===--- SourceLoc.h - Source Locations and Ranges --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/SourceManager.h b/include/swift/Basic/SourceManager.h index 5ffbe7ab861a5..61ef42d40eb09 100644 --- a/include/swift/Basic/SourceManager.h +++ b/include/swift/Basic/SourceManager.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/StringExtras.h b/include/swift/Basic/StringExtras.h index 7d297ce92a0f0..7f3e81db5ddf9 100644 --- a/include/swift/Basic/StringExtras.h +++ b/include/swift/Basic/StringExtras.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,6 +28,11 @@ #include namespace swift { + /// Determine whether the given string can be an argument label. + /// + /// \seealso Token::canBeArgumentLabel() + bool canBeArgumentLabel(StringRef identifier); + /// Describes the kind of preposition a word is. enum PrepositionKind { PK_None = 0, @@ -44,7 +49,6 @@ namespace swift { Unknown, Preposition, Verb, - AuxiliaryVerb, Gerund, }; diff --git a/include/swift/Basic/SuccessorMap.h b/include/swift/Basic/SuccessorMap.h index 7cace7ae8e73f..bc186756de561 100644 --- a/include/swift/Basic/SuccessorMap.h +++ b/include/swift/Basic/SuccessorMap.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -233,7 +233,7 @@ class SuccessorMap { return foundUpperBound; }; - // A heler to finish the operation, given that 'cur' is an upper bound. + // A helper to finish the operation, given that 'cur' is an upper bound. auto finishWithUpperBound = [&] { assert(cur->Left == nullptr); return reassemble(true); diff --git a/include/swift/Basic/TaskQueue.h b/include/swift/Basic/TaskQueue.h index 2f0a8d2adde2f..27e9e6e2c597e 100644 --- a/include/swift/Basic/TaskQueue.h +++ b/include/swift/Basic/TaskQueue.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/ThreadSafeRefCounted.h b/include/swift/Basic/ThreadSafeRefCounted.h index 8bdc3d964e644..f519f7eb60883 100644 --- a/include/swift/Basic/ThreadSafeRefCounted.h +++ b/include/swift/Basic/ThreadSafeRefCounted.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/Timer.h b/include/swift/Basic/Timer.h new file mode 100644 index 0000000000000..b3efe2f7c4cad --- /dev/null +++ b/include/swift/Basic/Timer.h @@ -0,0 +1,50 @@ +//===--- Timer.h - Shared timers for compilation phases ---------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_BASIC_TIMER_H +#define SWIFT_BASIC_TIMER_H + +#include "swift/Basic/LLVM.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Timer.h" + +namespace swift { + /// A convenience class for declaring a timer that's part of the Swift + /// compilation timers group. + class SharedTimer { + enum class State { + Initial, + Skipped, + Enabled + }; + static State CompilationTimersEnabled; + + Optional Timer; + + public: + explicit SharedTimer(StringRef name) { + if (CompilationTimersEnabled == State::Enabled) + Timer.emplace(name, StringRef("Swift compilation")); + else + CompilationTimersEnabled = State::Skipped; + } + + /// Must be called before any SharedTimers have been created. + static void enableCompilationTimers() { + assert(CompilationTimersEnabled != State::Skipped && + "a timer has already been created"); + CompilationTimersEnabled = State::Enabled; + } + }; +} + +#endif // SWIFT_BASIC_TIMER_H diff --git a/include/swift/Basic/TreeScopedHashTable.h b/include/swift/Basic/TreeScopedHashTable.h index 7faa9a6a818d7..2d03b20aba501 100644 --- a/include/swift/Basic/TreeScopedHashTable.h +++ b/include/swift/Basic/TreeScopedHashTable.h @@ -1,8 +1,8 @@ -//===- TreeScopedHashTable.h - A scoped hash table with multiple active scopes -===// +//===--- TreeScopedHashTable.h - Hash table with multiple active scopes ---===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/UUID.h b/include/swift/Basic/UUID.h index efd7948f5a035..d88fd000dc8c4 100644 --- a/include/swift/Basic/UUID.h +++ b/include/swift/Basic/UUID.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/Unicode.h b/include/swift/Basic/Unicode.h index 7a4219284df20..988a4c0da8f32 100644 --- a/include/swift/Basic/Unicode.h +++ b/include/swift/Basic/Unicode.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/ValueEnumerator.h b/include/swift/Basic/ValueEnumerator.h new file mode 100644 index 0000000000000..2203304a9dcc8 --- /dev/null +++ b/include/swift/Basic/ValueEnumerator.h @@ -0,0 +1,58 @@ +//===--- ValueEnumerator.h --- Enumerates values ----------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_BASIC_VALUEENUMERATOR_H +#define SWIFT_BASIC_VALUEENUMERATOR_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/raw_ostream.h" + +namespace swift { + +/// / This class maps values to unique indices. +template +class ValueEnumerator { + /// A running counter to enumerate values. + IndexTy counter; + + /// Maps values to unique integers. + llvm::DenseMap ValueToIndex; + +public: + /// Return the index of value \p v. + IndexTy getIndex(const ValueTy &v) { + // Return the index of this Key, if we've assigned one already. + auto It = ValueToIndex.find(v); + if (It != ValueToIndex.end()) { + return It->second; + } + + // Generate a new counter for the key. + ValueToIndex[v] = ++counter; + return counter; + } + + ValueEnumerator() = default; + + /// Forget about key \p v. + void invalidateValue(const ValueTy &v) { ValueToIndex.erase(v); } + + /// Clear the enumeration state of the + void clear() { + ValueToIndex.clear(); + counter = 0; + } +}; + +} // end namespace swift + +#endif diff --git a/include/swift/Basic/Version.h b/include/swift/Basic/Version.h index b4ffcb6e84e4a..e6fc2313baf98 100644 --- a/include/swift/Basic/Version.h +++ b/include/swift/Basic/Version.h @@ -1,8 +1,8 @@ -//===- Version.h - Swift Version Number -------------------------*- C++ -*-===// +//===--- Version.h - Swift Version Number -----------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Basic/type_traits.h b/include/swift/Basic/type_traits.h index 1270bb5402c71..8aee295aa6de8 100644 --- a/include/swift/Basic/type_traits.h +++ b/include/swift/Basic/type_traits.h @@ -1,8 +1,8 @@ -//===--- type_traits.h - Type traits -----------------------------*- C++ -*-==// +//===--- type_traits.h - Type traits ----------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,7 +22,7 @@ namespace swift { -/// Same as \c std::is_trivially_copyable, which we can not use directly +/// Same as \c std::is_trivially_copyable, which we cannot use directly /// because it is not implemented yet in all C++11 standard libraries. /// /// Unlike \c llvm::isPodLike, this trait should produce a precise result and diff --git a/include/swift/ClangImporter/BuiltinMappedTypes.def b/include/swift/ClangImporter/BuiltinMappedTypes.def index 9fd1b2e0a420b..00825c8d8187b 100644 --- a/include/swift/ClangImporter/BuiltinMappedTypes.def +++ b/include/swift/ClangImporter/BuiltinMappedTypes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 8720ea5716573..cb4a65a0d1519 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -1,8 +1,8 @@ -//===--- ClangImporter.cpp - Import Clang Modules --------------*- C++ -*--===// +//===--- ClangImporter.h - Import Clang Modules -----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -114,14 +114,7 @@ class ClangImporter final : public ClangModuleLoader { /// \brief Look for declarations associated with the given name. /// /// \param name The name we're searching for. - void lookupValue(Identifier name, VisibleDeclConsumer &consumer); - - /// \brief Look for visible declarations in the Clang translation unit and - /// import them as Swift decls. - /// - /// \param Consumer The VisibleDeclConsumer that will be fed decls as they - /// are found and imported. - void lookupVisibleDecls(VisibleDeclConsumer &Consumer) const; + void lookupValue(DeclName name, VisibleDeclConsumer &consumer); /// Look for textually included declarations from the bridging header. /// diff --git a/include/swift/ClangImporter/ClangImporterOptions.h b/include/swift/ClangImporter/ClangImporterOptions.h index b15d8ab6a0ead..506dfc0a00a64 100644 --- a/include/swift/ClangImporter/ClangImporterOptions.h +++ b/include/swift/ClangImporter/ClangImporterOptions.h @@ -1,8 +1,8 @@ -//===-- ClangImporterOptions.h ---------------------------------*- C++ -*--===// +//===--- ClangImporterOptions.h ---------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -53,10 +53,6 @@ class ClangImporterOptions { /// generation. bool DetailedPreprocessingRecord = false; - /// If true, matched getter-like and setter-like methods will be imported as - /// properties. - bool InferImplicitProperties = false; - /// If true, Clang diagnostics will be dumped to stderr using Clang's /// diagnostic printer as well as being passed to Swift's diagnostic engine. bool DumpClangDiagnostics = false; diff --git a/include/swift/ClangImporter/ClangModule.h b/include/swift/ClangImporter/ClangModule.h index e797db9ac64f9..8fcc9f53654a4 100644 --- a/include/swift/ClangImporter/ClangModule.h +++ b/include/swift/ClangImporter/ClangModule.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/ClangImporter/SIMDMappedTypes.def b/include/swift/ClangImporter/SIMDMappedTypes.def index 814f555d9beb5..d020788ae169f 100644 --- a/include/swift/ClangImporter/SIMDMappedTypes.def +++ b/include/swift/ClangImporter/SIMDMappedTypes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Config.h.in b/include/swift/Config.h.in index a60eeb78487a2..263e3086c5724 100644 --- a/include/swift/Config.h.in +++ b/include/swift/Config.h.in @@ -1,5 +1,5 @@ // This file is processed by CMake. -// See http://www.cmake.org/cmake/help/v3.0/command/configure_file.html. +// See https://cmake.org/cmake/help/v3.0/command/configure_file.html. #ifndef SWIFT_CONFIG_H #define SWIFT_CONFIG_H diff --git a/include/swift/Driver/Action.h b/include/swift/Driver/Action.h index 0104c4138916a..937de8acb7549 100644 --- a/include/swift/Driver/Action.h +++ b/include/swift/Driver/Action.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -38,6 +38,7 @@ class Action { enum ActionClass { Input = 0, CompileJob, + InterpretJob, BackendJob, MergeModuleJob, ModuleWrapJob, @@ -164,6 +165,19 @@ class CompileJobAction : public JobAction { } }; +class InterpretJobAction : public JobAction { +private: + virtual void anchor(); + +public: + explicit InterpretJobAction() + : JobAction(Action::InterpretJob, llvm::None, types::TY_Nothing) {} + + static bool classof(const Action *A) { + return A->getKind() == Action::InterpretJob; + } +}; + class BackendJobAction : public JobAction { private: virtual void anchor(); diff --git a/include/swift/Driver/Compilation.h b/include/swift/Driver/Compilation.h index 1c97b80ba9eab..fbd662ba2b067 100644 --- a/include/swift/Driver/Compilation.h +++ b/include/swift/Driver/Compilation.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Driver/DependencyGraph.h b/include/swift/Driver/DependencyGraph.h index b6c786b16cb1a..6348f7009424e 100644 --- a/include/swift/Driver/DependencyGraph.h +++ b/include/swift/Driver/DependencyGraph.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -94,7 +94,7 @@ class DependencyGraphImpl { static_assert(std::is_move_constructible::value, ""); /// The "outgoing" edge map. This lists all outgoing (kind, string) edges - /// representing satisified dependencies from a particular node. + /// representing satisfied dependencies from a particular node. /// /// For multiple outgoing edges with the same string, the kinds are combined /// into one field. diff --git a/include/swift/Driver/Driver.h b/include/swift/Driver/Driver.h index 3057df7e30665..44973ade3a0b1 100644 --- a/include/swift/Driver/Driver.h +++ b/include/swift/Driver/Driver.h @@ -1,8 +1,8 @@ -//===-- Driver.h - Swift compiler driver -----------------------*- C++ -*--===// +//===--- Driver.h - Swift compiler driver -----------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Driver/FrontendUtil.h b/include/swift/Driver/FrontendUtil.h index 5e9791840936b..cb18368c8f379 100644 --- a/include/swift/Driver/FrontendUtil.h +++ b/include/swift/Driver/FrontendUtil.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Driver/Job.h b/include/swift/Driver/Job.h index 69a88d8790c80..c3f4c069c008d 100644 --- a/include/swift/Driver/Job.h +++ b/include/swift/Driver/Job.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -87,6 +87,8 @@ class Job { NewlyAdded }; + using EnvironmentVector = std::vector>; + private: /// The action which caused the creation of this Job, and the conditions /// under which it must be run. @@ -103,8 +105,15 @@ class Job { /// The list of program arguments (not including the implicit first argument, /// which will be the Executable). + /// + /// These argument strings must be kept alive as long as the Job is alive. llvm::opt::ArgStringList Arguments; + /// Additional variables to set in the process environment when running. + /// + /// These strings must be kept alive as long as the Job is alive. + EnvironmentVector ExtraEnvironment; + /// The modification time of the main input file, if any. llvm::sys::TimeValue InputModTime = llvm::sys::TimeValue::MaxTime(); @@ -113,10 +122,12 @@ class Job { SmallVectorImpl &&Inputs, std::unique_ptr Output, const char *Executable, - llvm::opt::ArgStringList Arguments) + llvm::opt::ArgStringList Arguments, + EnvironmentVector ExtraEnvironment = {}) : SourceAndCondition(&Source, Condition::Always), Inputs(std::move(Inputs)), Output(std::move(Output)), - Executable(Executable), Arguments(std::move(Arguments)) {} + Executable(Executable), Arguments(std::move(Arguments)), + ExtraEnvironment(std::move(ExtraEnvironment)) {} const Action &getSource() const { return *SourceAndCondition.getPointer(); } @@ -141,10 +152,21 @@ class Job { return InputModTime; } + ArrayRef> getExtraEnvironment() const { + return ExtraEnvironment; + } + /// Print the command line for this Job to the given \p stream, /// terminating output with the given \p terminator. void printCommandLine(raw_ostream &Stream, StringRef Terminator = "\n") const; + /// Print the command line for this Job to the given \p stream, + /// and include any extra environment variables that will be set. + /// + /// \sa printCommandLine + void printCommandLineAndEnvironment(raw_ostream &Stream, + StringRef Terminator = "\n") const; + void dump() const LLVM_ATTRIBUTE_USED; static void printArguments(raw_ostream &Stream, diff --git a/include/swift/Driver/OutputFileMap.h b/include/swift/Driver/OutputFileMap.h index 4afe6d8eb835f..fe6ff7cbaa76e 100644 --- a/include/swift/Driver/OutputFileMap.h +++ b/include/swift/Driver/OutputFileMap.h @@ -1,8 +1,8 @@ -//===-- OutputFileMap.h - Driver output file map ---------------*- C++ -*--===// +//===--- OutputFileMap.h - Driver output file map ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Driver/ParseableOutput.h b/include/swift/Driver/ParseableOutput.h index 6064a97e29221..d878614a0be2c 100644 --- a/include/swift/Driver/ParseableOutput.h +++ b/include/swift/Driver/ParseableOutput.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Driver/ToolChain.h b/include/swift/Driver/ToolChain.h index 65321c261934e..975bda6f352bc 100644 --- a/include/swift/Driver/ToolChain.h +++ b/include/swift/Driver/ToolChain.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -58,30 +58,44 @@ class ToolChain { const OutputInfo &OI; }; - virtual std::pair + /// Packs together information chosen by toolchains to create jobs. + struct InvocationInfo { + const char *ExecutableName; + llvm::opt::ArgStringList Arguments; + std::vector> ExtraEnvironment; + + InvocationInfo(const char *name, llvm::opt::ArgStringList args, + decltype(ExtraEnvironment) extraEnv = {}) + : ExecutableName(name), Arguments(args), ExtraEnvironment(extraEnv) {} + }; + + virtual InvocationInfo constructInvocation(const CompileJobAction &job, const JobContext &context) const; - virtual std::pair + virtual InvocationInfo + constructInvocation(const InterpretJobAction &job, + const JobContext &context) const; + virtual InvocationInfo constructInvocation(const BackendJobAction &job, const JobContext &context) const; - virtual std::pair + virtual InvocationInfo constructInvocation(const MergeModuleJobAction &job, const JobContext &context) const; - virtual std::pair + virtual InvocationInfo constructInvocation(const ModuleWrapJobAction &job, const JobContext &context) const; - virtual std::pair + virtual InvocationInfo constructInvocation(const REPLJobAction &job, const JobContext &context) const; - virtual std::pair + virtual InvocationInfo constructInvocation(const GenerateDSYMJobAction &job, const JobContext &context) const; - virtual std::pair + virtual InvocationInfo constructInvocation(const AutolinkExtractJobAction &job, const JobContext &context) const; - virtual std::pair + virtual InvocationInfo constructInvocation(const LinkJobAction &job, const JobContext &context) const; @@ -117,7 +131,7 @@ class ToolChain { const llvm::opt::ArgList &args, const OutputInfo &OI) const; - /// Return the default langauge type to use for the given extension. + /// Return the default language type to use for the given extension. virtual types::ID lookupTypeForExtension(StringRef Ext) const; }; } // end namespace driver diff --git a/include/swift/Driver/Types.def b/include/swift/Driver/Types.def index 0a6027c70b780..5b01b5f3ba252 100644 --- a/include/swift/Driver/Types.def +++ b/include/swift/Driver/Types.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Driver/Types.h b/include/swift/Driver/Types.h index 77e788c299332..c219510af3e1f 100644 --- a/include/swift/Driver/Types.h +++ b/include/swift/Driver/Types.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -75,7 +75,7 @@ namespace llvm { } template -void swift::driver::types::forAllTypes(const Fn &fn) { +void swift::driver::types::forAllTypes(const Fn &fn) { static_assert(std::is_constructible,Fn>::value, "must have the signature 'void(types::ID)'"); for (uint8_t i = 0; i < static_cast(TY_INVALID); ++i) diff --git a/include/swift/Driver/Util.h b/include/swift/Driver/Util.h index ef5b7e7ea32ec..6af4b8d353b72 100644 --- a/include/swift/Driver/Util.h +++ b/include/swift/Driver/Util.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Frontend/DiagnosticVerifier.h b/include/swift/Frontend/DiagnosticVerifier.h index 18b9f25d4283d..0ec8ea152c1c3 100644 --- a/include/swift/Frontend/DiagnosticVerifier.h +++ b/include/swift/Frontend/DiagnosticVerifier.h @@ -1,8 +1,8 @@ -//===- DiagnosticVerifier.h - Diagnostic Verifier (-verify) -----*- C++ -*-===// +//===--- DiagnosticVerifier.h - Diagnostic Verifier (-verify) ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index 8c25b9336ddf6..4e08cad86a3bd 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -1,8 +1,8 @@ -//===-- Frontend.h - frontend utility methods ------------------*- C++ -*--===// +//===--- Frontend.h - frontend utility methods ------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 4e36b180035c3..baed3cf849b51 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -166,6 +166,12 @@ class FrontendOptions { /// If set, dumps wall time taken to check each function body to llvm::errs(). bool DebugTimeFunctionBodies = false; + /// If set, prints the time taken in each major compilation phase to + /// llvm::errs(). + /// + /// \sa swift::SharedTimer + bool DebugTimeCompilation = false; + /// Indicates whether function body parsing should be delayed /// until the end of all files. bool DelayedFunctionBodyParsing = false; diff --git a/include/swift/Frontend/PrintingDiagnosticConsumer.h b/include/swift/Frontend/PrintingDiagnosticConsumer.h index 14f2ce7f3609a..e714f9d76ce0b 100644 --- a/include/swift/Frontend/PrintingDiagnosticConsumer.h +++ b/include/swift/Frontend/PrintingDiagnosticConsumer.h @@ -1,8 +1,8 @@ -//===- PrintingDiagnosticConsumer.h - Print Text Diagnostics ----*- C++ -*-===// +//===--- PrintingDiagnosticConsumer.h - Print Text Diagnostics --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Frontend/SerializedDiagnosticConsumer.h b/include/swift/Frontend/SerializedDiagnosticConsumer.h index ad866121f0e56..296b0547c2cc7 100644 --- a/include/swift/Frontend/SerializedDiagnosticConsumer.h +++ b/include/swift/Frontend/SerializedDiagnosticConsumer.h @@ -1,8 +1,8 @@ -//===- SerializedDiagnosticConsumer.h - Serialize Diagnostics --*- C++ -*--===// +//===--- SerializedDiagnosticConsumer.h - Serialize Diagnostics -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/IDE/CodeCompletion.h b/include/swift/IDE/CodeCompletion.h index f55b6913fd136..716a78414d402 100644 --- a/include/swift/IDE/CodeCompletion.h +++ b/include/swift/IDE/CodeCompletion.h @@ -1,8 +1,8 @@ -//===- CodeCompletion.h - Routines for code completion --------------------===// +//===--- CodeCompletion.h - Routines for code completion ------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -266,13 +266,13 @@ class CodeCompletionString { } static Chunk createWithText(ChunkKind Kind, unsigned NestingLevel, - StringRef Text, bool isAnnoation = false) { - return Chunk(Kind, NestingLevel, Text, isAnnoation); + StringRef Text, bool isAnnotation = false) { + return Chunk(Kind, NestingLevel, Text, isAnnotation); } static Chunk createSimple(ChunkKind Kind, unsigned NestingLevel, - bool isAnnoation = false) { - return Chunk(Kind, NestingLevel, isAnnoation); + bool isAnnotation = false) { + return Chunk(Kind, NestingLevel, isAnnotation); } }; @@ -701,7 +701,7 @@ class CodeCompletionContext { /// \brief Return current code completion results. MutableArrayRef takeResults(); - /// \brief Sort code completion results in an implementetion-defined order + /// \brief Sort code completion results in an implementation-defined order /// in place. static void sortCompletionResults( MutableArrayRef Results); @@ -732,7 +732,7 @@ struct SimpleCachingCodeCompletionConsumer : public CodeCompletionConsumer { ArrayRef requestedModules, DeclContext *DCForModules) override; - /// Clients should overrride this method to receive \p Results. + /// Clients should override this method to receive \p Results. virtual void handleResults( MutableArrayRef Results) = 0; }; diff --git a/include/swift/IDE/CodeCompletionCache.h b/include/swift/IDE/CodeCompletionCache.h index c7fa9c441e592..14e0b7c79fc61 100644 --- a/include/swift/IDE/CodeCompletionCache.h +++ b/include/swift/IDE/CodeCompletionCache.h @@ -1,8 +1,8 @@ -//===- CodeCompletionCache.h - Routines for code completion caching -------===// +//===--- CodeCompletionCache.h - Routines for code completion caching -----===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/IDE/CommentConversion.h b/include/swift/IDE/CommentConversion.h index 99594c76a2ee2..af87e4aa8844a 100644 --- a/include/swift/IDE/CommentConversion.h +++ b/include/swift/IDE/CommentConversion.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/IDE/ModuleInterfacePrinting.h b/include/swift/IDE/ModuleInterfacePrinting.h index 937a64a15d4d1..26d80e9740757 100644 --- a/include/swift/IDE/ModuleInterfacePrinting.h +++ b/include/swift/IDE/ModuleInterfacePrinting.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/IDE/REPLCodeCompletion.h b/include/swift/IDE/REPLCodeCompletion.h index f58cb29fd6ac7..834a3d77fd417 100644 --- a/include/swift/IDE/REPLCodeCompletion.h +++ b/include/swift/IDE/REPLCodeCompletion.h @@ -1,8 +1,8 @@ -//===--- REPLCodeCompletion.h - Code completion for REPL ----------* C++ *-===// +//===--- REPLCodeCompletion.h - Code completion for REPL --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/IDE/SourceEntityWalker.h b/include/swift/IDE/SourceEntityWalker.h index 4f74a48e10a9f..b604e60a488dc 100644 --- a/include/swift/IDE/SourceEntityWalker.h +++ b/include/swift/IDE/SourceEntityWalker.h @@ -1,8 +1,8 @@ -//===- SourceEntityWalker.h - Routines for semantic source info -----------===// +//===--- SourceEntityWalker.h - Routines for semantic source info ---------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/IDE/SyntaxModel.h b/include/swift/IDE/SyntaxModel.h index ccdcd6f67b487..df5eafedccc75 100644 --- a/include/swift/IDE/SyntaxModel.h +++ b/include/swift/IDE/SyntaxModel.h @@ -1,8 +1,8 @@ -//===- SyntaxModel.h - Routines for IDE syntax model ---------------------===// +//===--- SyntaxModel.h - Routines for IDE syntax model -------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/IDE/Utils.h b/include/swift/IDE/Utils.h index e4552dfec4c30..f906b35259c7a 100644 --- a/include/swift/IDE/Utils.h +++ b/include/swift/IDE/Utils.h @@ -1,8 +1,8 @@ -//===- Utils.h - Misc utilities -------------------------------------------===// +//===--- Utils.h - Misc utilities -----------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -54,7 +54,7 @@ struct SourceCompleteResult { // The text to use as the indent string when auto indenting the next line. // This will contain the exactly what the client typed (any whitespaces and // tabs) and can be used to indent subsequent lines. It does not include - // the current indent level, IDE clients should insert the currect indentation + // the current indent level, IDE clients should insert the correct indentation // with spaces or tabs to account for the current indent level. The indent // prefix will contain the leading space characters of the line that // contained the '{', '(' or '[' character that was unbalanced. diff --git a/include/swift/Immediate/Immediate.h b/include/swift/Immediate/Immediate.h index 6027ea076319d..101aeb416f338 100644 --- a/include/swift/Immediate/Immediate.h +++ b/include/swift/Immediate/Immediate.h @@ -1,8 +1,8 @@ -//===-- Immediate.h - Entry point for swift immediate mode -----*- C++ -*--===// +//===--- Immediate.h - Entry point for swift immediate mode -----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/LLVMPasses/Passes.h b/include/swift/LLVMPasses/Passes.h index d53d69b17f910..0d2f06ea1791e 100644 --- a/include/swift/LLVMPasses/Passes.h +++ b/include/swift/LLVMPasses/Passes.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/LLVMPasses/PassesFwd.h b/include/swift/LLVMPasses/PassesFwd.h index f1dcdb6eabb07..3b9500dc151bf 100644 --- a/include/swift/LLVMPasses/PassesFwd.h +++ b/include/swift/LLVMPasses/PassesFwd.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Markup/AST.h b/include/swift/Markup/AST.h index 0238e16fe5abd..11357a32c26da 100644 --- a/include/swift/Markup/AST.h +++ b/include/swift/Markup/AST.h @@ -1,8 +1,8 @@ -//===--- AST.h - Markup AST nodes ---------------------------------------===// +//===--- AST.h - Markup AST nodes -----------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -199,15 +199,19 @@ class Item final : public MarkupASTNode { class CodeBlock final : public MarkupASTNode { StringRef LiteralContent; + StringRef Language; - CodeBlock(StringRef LiteralContent) + CodeBlock(StringRef LiteralContent, StringRef Language) : MarkupASTNode(ASTNodeKind::CodeBlock), - LiteralContent(LiteralContent) {} + LiteralContent(LiteralContent), + Language(Language) {} public: - static CodeBlock *create(MarkupContext &MC, StringRef LiteralContent); + static CodeBlock *create(MarkupContext &MC, StringRef LiteralContent, + StringRef Language); StringRef getLiteralContent() const { return LiteralContent; }; + StringRef getLanguage() const { return Language; }; ArrayRef getChildren() const { return {}; diff --git a/include/swift/Markup/ASTNodes.def b/include/swift/Markup/ASTNodes.def index df95413c3f475..b1330bb66ceaa 100644 --- a/include/swift/Markup/ASTNodes.def +++ b/include/swift/Markup/ASTNodes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Markup/LineList.h b/include/swift/Markup/LineList.h index 539df74a07587..518264bbe8f8b 100644 --- a/include/swift/Markup/LineList.h +++ b/include/swift/Markup/LineList.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Markup/Markup.h b/include/swift/Markup/Markup.h index ace38deee7b63..86640c04f3c21 100644 --- a/include/swift/Markup/Markup.h +++ b/include/swift/Markup/Markup.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Markup/SimpleFields.def b/include/swift/Markup/SimpleFields.def index 18a03036b80c9..6ccd4b526869a 100644 --- a/include/swift/Markup/SimpleFields.def +++ b/include/swift/Markup/SimpleFields.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -14,7 +14,7 @@ // These definitions automatically generate the classes and XML printing // facilities. // -// There must be a correspnding definition of these nodes +// There must be a corresponding definition of these nodes // in include/swift/Markup/ASTNodes.def. // //===----------------------------------------------------------------------===// diff --git a/include/swift/Markup/SourceLoc.h b/include/swift/Markup/SourceLoc.h index 57db0d91f6813..4b383b30917d4 100644 --- a/include/swift/Markup/SourceLoc.h +++ b/include/swift/Markup/SourceLoc.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Markup/XMLUtils.h b/include/swift/Markup/XMLUtils.h index 1d3977b705b76..86540acb9bb18 100644 --- a/include/swift/Markup/XMLUtils.h +++ b/include/swift/Markup/XMLUtils.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index cfa1cdc98cefe..b9c600aa647af 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -124,6 +124,8 @@ def debug_forbid_typecheck_prefix : Separate<["-"], "debug-forbid-typecheck-pref HelpText<"Triggers llvm fatal_error if typechecker tries to typecheck a decl " "with the provided prefix name">; +def debug_time_compilation : Flag<["-"], "debug-time-compilation">, + HelpText<"Prints the time taken by each compilation phase">; def debug_time_function_bodies : Flag<["-"], "debug-time-function-bodies">, HelpText<"Dumps the time it takes to type-check each function body">; @@ -142,6 +144,9 @@ def debugger_support : Flag<["-"], "debugger-support">, def disable_arc_opts : Flag<["-"], "disable-arc-opts">, HelpText<"Don't run SIL ARC optimization passes.">; +def enable_guaranteed_closure_contexts : Flag<["-"], "enable-guaranteed-closure-contexts">, + HelpText<"Use @guaranteed convention for closure context">; + def remove_runtime_asserts : Flag<["-"], "remove-runtime-asserts">, HelpText<"Remove runtime asserts.">; @@ -187,6 +192,9 @@ def dump_clang_diagnostics : Flag<["-"], "dump-clang-diagnostics">, def emit_verbose_sil : Flag<["-"], "emit-verbose-sil">, HelpText<"Emit locations during SIL emission">; +def use_native_super_method : Flag<["-"], "use-native-super-method">, + HelpText<"Use super_method for super calls in native classes">; + def disable_self_type_mangling : Flag<["-"], "disable-self-type-mangling">, HelpText<"Disable including Self type in method type manglings">; @@ -197,10 +205,6 @@ def disable_availability_checking : Flag<["-"], "disable-availability-checking">, HelpText<"Disable checking for potentially unavailable APIs">; -def enable_objc_implicit_properties : - Flag<["-"], "enable-objc-implicit-properties">, - HelpText<"Import Objective-C \"implicit properties\" as properties">; - def enable_omit_needless_words : Flag<["-"], "enable-omit-needless-words">, HelpText<"Omit needless words when importing Objective-C names">; @@ -209,6 +213,10 @@ def enable_infer_default_arguments : Flag<["-"], "enable-infer-default-arguments">, HelpText<"Infer default arguments for imported parameters">; +def enable_swift_name_lookup_tables : + Flag<["-"], "enable-swift-name-lookup-tables">, + HelpText<"Enable Swift name lookup tables in the Clang importer">; + def warn_omit_needless_words : Flag<["-"], "Womit-needless-words">, HelpText<"Warn about needless words in names">; diff --git a/include/swift/Option/Options.h b/include/swift/Option/Options.h index a46922eacfcb0..5a29259e1dc95 100644 --- a/include/swift/Option/Options.h +++ b/include/swift/Option/Options.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 1ade695a92ab1..117e573c1c63a 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Parse/CodeCompletionCallbacks.h b/include/swift/Parse/CodeCompletionCallbacks.h index 58dc1c8ad1d55..3b36640c92f0b 100644 --- a/include/swift/Parse/CodeCompletionCallbacks.h +++ b/include/swift/Parse/CodeCompletionCallbacks.h @@ -1,8 +1,8 @@ -//===- CodeCompletionCallbacks.h - Parser's interface to code completion --===// +//===--- CodeCompletionCallbacks.h - Parser's interface to code completion ===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Parse/DelayedParsingCallbacks.h b/include/swift/Parse/DelayedParsingCallbacks.h index 05e5987806569..a1ea0031baa8d 100644 --- a/include/swift/Parse/DelayedParsingCallbacks.h +++ b/include/swift/Parse/DelayedParsingCallbacks.h @@ -1,8 +1,8 @@ -//===- DelayedParsingCallbacks.h - Callbacks for Parser's delayed parsing -===// +//===--- DelayedParsingCallbacks.h - Delayed parsing callbacks ------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h index b1b01802b9092..bc78a6bf70ef4 100644 --- a/include/swift/Parse/Lexer.h +++ b/include/swift/Parse/Lexer.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -240,8 +240,17 @@ class Lexer { restoreState(S); } + /// \brief Retrieve the Token referred to by \c Loc. + /// + /// \param SM The source manager in which the given source location + /// resides. + /// + /// \param Loc The source location of the beginning of a token. + static Token getTokenAtLocation(const SourceManager &SM, SourceLoc Loc); + + /// \brief Retrieve the source location that points just past the - /// end of the token refered to by \c Loc. + /// end of the token referred to by \c Loc. /// /// \param SM The source manager in which the given source location /// resides. @@ -255,8 +264,9 @@ class Lexer { /// resides. /// /// \param SR The source range - static CharSourceRange getCharSourceRangeFromSourceRange(const SourceManager &SM, - const SourceRange &SR) { + static CharSourceRange + getCharSourceRangeFromSourceRange(const SourceManager &SM, + const SourceRange &SR) { return CharSourceRange(SM, SR.Start, getLocForEndOfToken(SM, SR.End)); } @@ -299,6 +309,10 @@ class Lexer { /// reserved word. static tok kindOfIdentifier(StringRef Str, bool InSILMode); + /// \brief Determines if the given string is a valid operator identifier, + /// without escaping characters. + static bool isOperator(StringRef string); + SourceLoc getLocForStartOfBuffer() const { return SourceLoc(llvm::SMLoc::getFromPointer(BufferStart)); } diff --git a/include/swift/Parse/LocalContext.h b/include/swift/Parse/LocalContext.h index 8bdc36e4759ee..9615b0fc094e7 100644 --- a/include/swift/Parse/LocalContext.h +++ b/include/swift/Parse/LocalContext.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index 3b3468ef4831d..0c22729abf5d6 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -83,7 +83,7 @@ class Parser { DeclContext *CurDeclContext; ASTContext &Context; CodeCompletionCallbacks *CodeCompletion = nullptr; - std::vector>> AnonClosureVars; + std::vector>> AnonClosureVars; bool IsParsingInterfaceTokens = false; @@ -760,18 +760,18 @@ class Parser { void record(Parser &P, AbstractStorageDecl *storage, bool invalid, ParseDeclOptions flags, SourceLoc staticLoc, const DeclAttributes &attrs, - TypeLoc elementTy, Pattern *indices, + TypeLoc elementTy, ParameterList *indices, SmallVectorImpl &decls); }; bool parseGetSetImpl(ParseDeclOptions Flags, - Pattern *Indices, TypeLoc ElementTy, + ParameterList *Indices, TypeLoc ElementTy, ParsedAccessors &accessors, SourceLoc &LastValidLoc, SourceLoc StaticLoc, SourceLoc VarLBLoc, SmallVectorImpl &Decls); bool parseGetSet(ParseDeclOptions Flags, - Pattern *Indices, TypeLoc ElementTy, + ParameterList *Indices, TypeLoc ElementTy, ParsedAccessors &accessors, SourceLoc StaticLoc, SmallVectorImpl &Decls); void recordAccessors(AbstractStorageDecl *storage, ParseDeclOptions flags, @@ -803,6 +803,7 @@ class Parser { parseDeclDeinit(ParseDeclOptions Flags, DeclAttributes &Attributes); void addPatternVariablesToScope(ArrayRef Patterns); + void addParametersToScope(ParameterList *PL); ParserResult parseDeclOperator(ParseDeclOptions Flags, DeclAttributes &Attributes); @@ -859,7 +860,7 @@ class Parser { ParserResult parseTypeComposition(); ParserResult parseTypeTupleBody(); - ParserResult parseTypeArray(TypeRepr *Base); + ParserResult parseTypeArray(TypeRepr *Base); /// Parse a collection type. /// type-simple: @@ -900,8 +901,8 @@ class Parser { /// function. void setFunctionContext(DeclContext *DC); - DefaultArgumentInfo() { - NextIndex = 0; + DefaultArgumentInfo(bool inTypeContext) { + NextIndex = inTypeContext ? 1 : 0; HasDefaultArgument = false; } }; @@ -922,10 +923,6 @@ class Parser { }; SpecifierKindTy SpecifierKind = Let; // Defaults to let. - - /// The location of the back-tick preceding the first name, if any. - SourceLoc PoundLoc; - /// The location of the first name. /// /// \c FirstName is the name. @@ -997,23 +994,23 @@ class Parser { DefaultArgumentInfo *defaultArgs, ParameterContextKind paramContext); - ParserResult parseSingleParameterClause( + ParserResult parseSingleParameterClause( ParameterContextKind paramContext, SmallVectorImpl *namePieces = nullptr); ParserStatus parseFunctionArguments(SmallVectorImpl &NamePieces, - SmallVectorImpl &BodyPatterns, + SmallVectorImpl &BodyParams, ParameterContextKind paramContext, DefaultArgumentInfo &defaultArgs); ParserStatus parseFunctionSignature(Identifier functionName, DeclName &fullName, - SmallVectorImpl &bodyPatterns, + SmallVectorImpl &bodyParams, DefaultArgumentInfo &defaultArgs, SourceLoc &throws, bool &rethrows, TypeRepr *&retType); ParserStatus parseConstructorArguments(DeclName &FullName, - Pattern *&BodyPattern, + ParameterList *&BodyParams, DefaultArgumentInfo &defaultArgs); //===--------------------------------------------------------------------===// @@ -1137,7 +1134,7 @@ class Parser { /// \returns true if an error occurred, false otherwise. bool parseClosureSignatureIfPresent( SmallVectorImpl &captureList, - Pattern *¶ms, + ParameterList *¶ms, SourceLoc &throwsLoc, SourceLoc &arrowLoc, TypeRepr *&explicitResultType, diff --git a/include/swift/Parse/ParserResult.h b/include/swift/Parse/ParserResult.h index ef42b3cd82ff1..42ce7f0d53b1d 100644 --- a/include/swift/Parse/ParserResult.h +++ b/include/swift/Parse/ParserResult.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -49,7 +49,7 @@ template class ParserResult { /// Construct a successful parser result. explicit ParserResult(T *Result) : PtrAndBits(Result) { - assert(Result && "a successful parser result can not be null"); + assert(Result && "a successful parser result cannot be null"); } /// Convert from a different but compatible parser result. @@ -125,8 +125,8 @@ static inline ParserResult makeParserCodeCompletionResult(T *Result = /// \brief Same as \c ParserResult, but just the status bits without the AST /// node. /// -/// Useful when the AST node is returned by some other means (for example, a in -/// vector out parameter). +/// Useful when the AST node is returned by some other means (for example, in +/// a vector out parameter). /// /// If you want to use 'bool' as a result type in the Parser, consider using /// ParserStatus instead. diff --git a/include/swift/Parse/PersistentParserState.h b/include/swift/Parse/PersistentParserState.h index 4c20d0ab0557c..8971ee1ab25f7 100644 --- a/include/swift/Parse/PersistentParserState.h +++ b/include/swift/Parse/PersistentParserState.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Parse/Scope.h b/include/swift/Parse/Scope.h index d375e4a59ba3e..cafd90bef6c91 100644 --- a/include/swift/Parse/Scope.h +++ b/include/swift/Parse/Scope.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Parse/Token.h b/include/swift/Parse/Token.h index 5cc1f18ee14e9..8c7a6630b840a 100644 --- a/include/swift/Parse/Token.h +++ b/include/swift/Parse/Token.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -190,6 +190,22 @@ class Token { return isAnyOperator() && Text == ContextPunc; } + /// Determine whether the token can be an argument label. + /// + /// This covers all identifiers and keywords except those keywords + /// used + bool canBeArgumentLabel() const { + // Identifiers, escaped identifiers, and '_' can be argument labels. + if (is(tok::identifier) || isEscapedIdentifier() || is(tok::kw__)) + return true; + + // 'let', 'var', and 'inout' cannot be argument labels. + if (isAny(tok::kw_let, tok::kw_var, tok::kw_inout)) return false; + + // All other keywords can be argument labels. + return isKeyword(); + } + /// True if the token is an identifier or '_'. bool isIdentifierOrUnderscore() const { return isAny(tok::identifier, tok::kw__); diff --git a/include/swift/Parse/Tokens.def b/include/swift/Parse/Tokens.def index 834e0a53e0784..c66fb9d63d62e 100644 --- a/include/swift/Parse/Tokens.def +++ b/include/swift/Parse/Tokens.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/PrintAsObjC/PrintAsObjC.h b/include/swift/PrintAsObjC/PrintAsObjC.h index 676600c18968f..38788455ce8fa 100644 --- a/include/swift/PrintAsObjC/PrintAsObjC.h +++ b/include/swift/PrintAsObjC/PrintAsObjC.h @@ -1,8 +1,8 @@ -//===-- PrintAsObjC.h - Emit a header file for a Swift AST --------------===// +//===--- PrintAsObjC.h - Emit a header file for a Swift AST ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Runtime/Concurrent.h b/include/swift/Runtime/Concurrent.h index 9f9e26125c199..adf8fd31e6e20 100644 --- a/include/swift/Runtime/Concurrent.h +++ b/include/swift/Runtime/Concurrent.h @@ -1,8 +1,8 @@ -//===--- Concurrent.h - Concurrent Data Structures ------------*- C++ -*--===// +//===--- Concurrent.h - Concurrent Data Structures -------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -145,7 +145,7 @@ template struct ConcurrentMapNode { /// The method findOrAllocateNode searches the binary tree in search of the /// exact Key value. If it finds an edge that points to NULL that should /// contain the value then it tries to compare and swap the new node into -/// place. If it looses the race to a different thread it de-allocates +/// place. If it loses the race to a different thread it de-allocates /// the node and starts the search again since the new node should /// be placed (or found) on the new link. See findOrAllocateNode for more /// details. @@ -164,7 +164,7 @@ template class ConcurrentMap { /// accelerating the search of the same value again and again. std::atomic LastSearch; - /// Search a for a node with key value \p. If the node does not exist then + /// Search for a node with key value \p. If the node does not exist then /// allocate a new bucket and add it to the tree. ConcurrentList &findOrAllocateNode(KeyTy Key) { // Try looking at the last node we searched. diff --git a/include/swift/Runtime/Config.h b/include/swift/Runtime/Config.h index 91a4b62f8f2da..7307a435392f0 100644 --- a/include/swift/Runtime/Config.h +++ b/include/swift/Runtime/Config.h @@ -1,8 +1,8 @@ -//===--- Config.h - Swift Language Platform Configuration ------*- C++ -*--===// +//===--- Config.h - Swift Language Platform Configuration -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Runtime/Debug.h b/include/swift/Runtime/Debug.h index 7e9c09a8222ac..86d65960f4b80 100644 --- a/include/swift/Runtime/Debug.h +++ b/include/swift/Runtime/Debug.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -101,7 +101,10 @@ swift_dynamicCastFailure(const void *sourceType, const char *sourceName, const void *targetType, const char *targetName, const char *message = nullptr); +extern "C" +void swift_reportError(const char *message); + // namespace swift -}; +} #endif // _SWIFT_RUNTIME_DEBUG_HELPERS_ diff --git a/include/swift/Runtime/Enum.h b/include/swift/Runtime/Enum.h index 887ecad99cd3c..95ad9c8e0f6c4 100644 --- a/include/swift/Runtime/Enum.h +++ b/include/swift/Runtime/Enum.h @@ -1,8 +1,8 @@ -//===--- Enum.h - Runtime declarations for enums ---------------*- C++ -*--===// +//===--- Enum.h - Runtime declarations for enums ----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Runtime/Heap.h b/include/swift/Runtime/Heap.h index fc6f30e25ad4b..749eb7f9337e8 100644 --- a/include/swift/Runtime/Heap.h +++ b/include/swift/Runtime/Heap.h @@ -1,8 +1,8 @@ -//===--- Heap.h - Swift Language Heap ABI ----------------------*- C++ -*--===// +//===--- Heap.h - Swift Language Heap ABI -----------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Runtime/HeapObject.h b/include/swift/Runtime/HeapObject.h index 7e28ccb22ba4d..4ec557716b52b 100644 --- a/include/swift/Runtime/HeapObject.h +++ b/include/swift/Runtime/HeapObject.h @@ -1,8 +1,8 @@ -//===--- Alloc.h - Swift Language Allocation ABI ---------------*- C++ -*--===// +//===--- HeapObject.h - Swift Language Allocation ABI -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -123,26 +123,6 @@ inline TwoWordPair::TwoWordPair(A first, B second) using BoxPair = TwoWordPair; -/// Allocates a heap object with POD value semantics. The returned memory is -/// uninitialized outside of the heap object header. The object has an -/// initial retain count of 1, and its metadata is set to a predefined -/// POD heap metadata for which destruction is a no-op. -/// -/// \param dataSize The size of the data area for the allocation. -/// Excludes the heap metadata header. -/// \param dataAlignmentMask The alignment of the data area. -/// -/// \returns a BoxPair in which the heapObject field points to the newly-created -/// HeapObject and the value field points to the data area inside the -/// allocation. The value pointer will have the alignment specified -/// by the dataAlignmentMask and point to dataSize bytes of memory. -extern "C" BoxPair::Return -swift_allocPOD(size_t dataSize, size_t dataAlignmentMask); - -/// Deallocates a heap object known to have been allocated by swift_allocPOD and -/// to have no remaining owners. -extern "C" void swift_deallocPOD(HeapObject *obj); - /// Allocates a heap object that can contain a value of the given type. /// Returns a Box structure containing a HeapObject* pointer to the /// allocated object, and a pointer to the value inside the heap object. @@ -226,10 +206,6 @@ extern "C" void swift_release(HeapObject *object); /// count reaches zero, the object is destroyed extern "C" void swift_release_n(HeapObject *object, uint32_t n); -/// ObjC compatibility. Never call this. -extern "C" size_t swift_retainCount(HeapObject *object); -extern "C" size_t swift_weakRetainCount(HeapObject *object); - /// Is this pointer a non-null unique reference to an object /// that uses Swift reference counting? extern "C" bool swift_isUniquelyReferencedNonObjC(const void *); @@ -381,24 +357,103 @@ class SwiftRAII { HeapObject *operator *() const { return object; } }; -/// Increment the weak retain count. -extern "C" void swift_weakRetain(HeapObject *value); +/*****************************************************************************/ +/**************************** UNOWNED REFERENCES *****************************/ +/*****************************************************************************/ + +/// An unowned reference in memory. This is ABI. +struct UnownedReference { + HeapObject *Value; +}; -/// Decrement the weak retain count. -extern "C" void swift_weakRelease(HeapObject *value); +/// Increment the weak/unowned retain count. +extern "C" void swift_unownedRetain(HeapObject *value); -/// Increment the weak retain count by n. -extern "C" void swift_weakRetain_n(HeapObject *value, int n); +/// Decrement the weak/unowned retain count. +extern "C" void swift_unownedRelease(HeapObject *value); -/// Decrement the weak retain count by n. -extern "C" void swift_weakRelease_n(HeapObject *value, int n); +/// Increment the weak/unowned retain count by n. +extern "C" void swift_unownedRetain_n(HeapObject *value, int n); + +/// Decrement the weak/unowned retain count by n. +extern "C" void swift_unownedRelease_n(HeapObject *value, int n); + +/// Increment the strong retain count of an object, aborting if it has +/// been deallocated. +extern "C" void swift_unownedRetainStrong(HeapObject *value); /// Increment the strong retain count of an object which may have been -/// deallocated. -extern "C" void swift_retainUnowned(HeapObject *value); +/// deallocated, aborting if it has been deallocated, and decrement its +/// weak/unowned reference count. +extern "C" void swift_unownedRetainStrongAndRelease(HeapObject *value); /// Aborts if the object has been deallocated. -extern "C" void swift_checkUnowned(HeapObject *value); +extern "C" void swift_unownedCheck(HeapObject *value); + +static inline void swift_unownedInit(UnownedReference *ref, HeapObject *value) { + ref->Value = value; + swift_unownedRetain(value); +} + +static inline void swift_unownedAssign(UnownedReference *ref, + HeapObject *value) { + auto oldValue = ref->Value; + if (value != oldValue) { + swift_unownedRetain(value); + ref->Value = value; + swift_unownedRelease(oldValue); + } +} + +static inline HeapObject *swift_unownedLoadStrong(UnownedReference *ref) { + auto value = ref->Value; + swift_unownedRetainStrong(value); + return value; +} + +static inline void *swift_unownedTakeStrong(UnownedReference *ref) { + auto value = ref->Value; + swift_unownedRetainStrongAndRelease(value); + return value; +} + +static inline void swift_unownedDestroy(UnownedReference *ref) { + swift_unownedRelease(ref->Value); +} + +static inline void swift_unownedCopyInit(UnownedReference *dest, + UnownedReference *src) { + dest->Value = src->Value; + swift_unownedRetain(dest->Value); +} + +static inline void swift_unownedTakeInit(UnownedReference *dest, + UnownedReference *src) { + dest->Value = src->Value; +} + +static inline void swift_unownedCopyAssign(UnownedReference *dest, + UnownedReference *src) { + auto newValue = src->Value; + auto oldValue = dest->Value; + if (newValue != oldValue) { + dest->Value = newValue; + swift_unownedRetain(newValue); + swift_unownedRelease(oldValue); + } +} + +static inline void swift_unownedTakeAssign(UnownedReference *dest, + UnownedReference *src) { + auto newValue = src->Value; + auto oldValue = dest->Value; + dest->Value = newValue; + swift_unownedRelease(oldValue); +} + +/*****************************************************************************/ +/****************************** WEAK REFERENCES ******************************/ +/*****************************************************************************/ /// A weak reference value object. This is ABI. struct WeakReference { @@ -461,10 +516,18 @@ extern "C" void swift_weakCopyAssign(WeakReference *dest, WeakReference *src); /// \param src - never null, but can refer to a null object extern "C" void swift_weakTakeAssign(WeakReference *dest, WeakReference *src); +/*****************************************************************************/ +/************************* OTHER REFERENCE-COUNTING **************************/ +/*****************************************************************************/ + extern "C" void *swift_bridgeObjectRetain(void *value); /// Increment the strong retain count of a bridged object by n. extern "C" void *swift_bridgeObjectRetain_n(void *value, int n); +/*****************************************************************************/ +/************************ UNKNOWN REFERENCE-COUNTING *************************/ +/*****************************************************************************/ + #if SWIFT_OBJC_INTEROP /// Increment the strong retain count of an object which might not be a native @@ -511,47 +574,9 @@ static inline void swift_unknownRelease_n(void *value, int n) { #endif /* SWIFT_OBJC_INTEROP */ -#if SWIFT_OBJC_INTEROP - -/// Increment the strong retain count of an object which may have been -/// deallocated and which might not be a native Swift object. -extern "C" void swift_unknownRetainUnowned(void *value); - -#else - -static inline void swift_unknownRetainUnowned(void *value) { - swift_retainUnowned(static_cast(value)); -} - -#endif /* SWIFT_OBJC_INTEROP */ - -#if SWIFT_OBJC_INTEROP - -/// Increment the weak-reference count of an object that might not be -/// a native Swift object. -extern "C" void swift_unknownWeakRetain(void *value); - -#else - -static inline void swift_unknownWeakRetain(void *value) { - swift_weakRetain(static_cast(value)); -} - -#endif /* SWIFT_OBJC_INTEROP */ - -#if SWIFT_OBJC_INTEROP - -/// Decrement the weak-reference count of an object that might not be -/// a native Swift object. -extern "C" void swift_unknownWeakRelease(void *value); - -#else - -static inline void swift_unknownWeakRelease(void *value) { - swift_weakRelease(static_cast(value)); -} - -#endif /* SWIFT_OBJC_INTEROP */ +/*****************************************************************************/ +/************************** UNKNOWN WEAK REFERENCES **************************/ +/*****************************************************************************/ #if SWIFT_OBJC_INTEROP @@ -690,6 +715,146 @@ static inline void swift_unknownWeakTakeAssign(WeakReference *dest, WeakReferenc #endif /* SWIFT_OBJC_INTEROP */ +/*****************************************************************************/ +/************************ UNKNOWN UNOWNED REFERENCES *************************/ +/*****************************************************************************/ + +#if SWIFT_OBJC_INTEROP + +/// Initialize an unowned reference to an object with unknown reference +/// counting. +extern "C" void swift_unknownUnownedInit(UnownedReference *ref, void *value); + +#else + +static inline void swift_unknownUnownedInit(UnownedReference *ref, + void *value) { + swift_unownedInit(ref, static_cast(value)); +} + +#endif /* SWIFT_OBJC_INTEROP */ + +#if SWIFT_OBJC_INTEROP + +/// Assign to an unowned reference holding an object with unknown reference +/// counting. +extern "C" void swift_unknownUnownedAssign(UnownedReference *ref, void *value); + +#else + +static inline void swift_unknownUnownedAssign(UnownedReference *ref, + void *value) { + swift_unownedAssign(ref, static_cast(value)); +} + +#endif /* SWIFT_OBJC_INTEROP */ + +#if SWIFT_OBJC_INTEROP + +/// Load from an unowned reference to an object with unknown reference +/// counting. +extern "C" void *swift_unknownUnownedLoadStrong(UnownedReference *ref); + +#else + +static inline void *swift_unknownUnownedLoadStrong(UnownedReference *ref) { + return swift_unownedLoadStrong(ref); +} + +#endif /* SWIFT_OBJC_INTEROP */ + +#if SWIFT_OBJC_INTEROP + +/// Take from an unowned reference to an object with unknown reference +/// counting. +extern "C" void *swift_unknownUnownedTakeStrong(UnownedReference *ref); + +#else + +static inline void *swift_unknownUnownedTakeStrong(UnownedReference *ref) { + return swift_unownedTakeStrong(ref); +} + +#endif /* SWIFT_OBJC_INTEROP */ + +#if SWIFT_OBJC_INTEROP + +/// Destroy an unowned reference to an object with unknown reference counting. +extern "C" void swift_unknownUnownedDestroy(UnownedReference *ref); + +#else + +static inline void swift_unknownUnownedDestroy(UnownedReference *ref) { + swift_unownedDestroy(ref); +} + +#endif /* SWIFT_OBJC_INTEROP */ + +#if SWIFT_OBJC_INTEROP + +/// Copy-initialize an unowned reference variable from one that might not +/// refer to a native Swift object. +extern "C" void swift_unknownUnownedCopyInit(UnownedReference *dest, + UnownedReference *src); + +#else + +static inline void swift_unknownUnownedCopyInit(UnownedReference *dest, + UnownedReference *src) { + swift_unownedCopyInit(dest, src); +} + +#endif /* SWIFT_OBJC_INTEROP */ + +#if SWIFT_OBJC_INTEROP + +/// Take-initialize an unowned reference variable from one that might not +/// refer to a native Swift object. +extern "C" void swift_unknownUnownedTakeInit(UnownedReference *dest, + UnownedReference *src); + +#else + +static inline void swift_unknownUnownedTakeInit(UnownedReference *dest, + UnownedReference *src) { + swift_unownedTakeInit(dest, src); +} + +#endif /* SWIFT_OBJC_INTEROP */ + +#if SWIFT_OBJC_INTEROP + +/// Copy-assign an unowned reference variable from another when either +/// or both variables might not refer to a native Swift object. +extern "C" void swift_unknownUnownedCopyAssign(UnownedReference *dest, + UnownedReference *src); + +#else + +static inline void swift_unknownUnownedCopyAssign(UnownedReference *dest, + UnownedReference *src) { + swift_unownedCopyAssign(dest, src); +} + +#endif /* SWIFT_OBJC_INTEROP */ + +#if SWIFT_OBJC_INTEROP + +/// Take-assign an unowned reference variable from another when either +/// or both variables might not refer to a native Swift object. +extern "C" void swift_unknownUnownedTakeAssign(UnownedReference *dest, + UnownedReference *src); + +#else + +static inline void swift_unknownUnownedTakeAssign(UnownedReference *dest, + UnownedReference *src) { + swift_unownedTakeAssign(dest, src); +} + +#endif /* SWIFT_OBJC_INTEROP */ + + } // end namespace swift #endif /* SWIFT_RUNTIME_ALLOC_H */ diff --git a/include/swift/Runtime/InstrumentsSupport.h b/include/swift/Runtime/InstrumentsSupport.h index 78218ce206223..3b5dbc9901930 100644 --- a/include/swift/Runtime/InstrumentsSupport.h +++ b/include/swift/Runtime/InstrumentsSupport.h @@ -1,8 +1,8 @@ -//===--- InstrumentsSupport.h - Support for Instruments.app ------ C++ -*--===// +//===--- InstrumentsSupport.h - Support for Instruments.app -----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h index 41a31d11c648a..71dfeac68b2fe 100644 --- a/include/swift/Runtime/Metadata.h +++ b/include/swift/Runtime/Metadata.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -93,7 +93,7 @@ struct OpaqueValue; /// A buffer can be in one of three states: /// - An unallocated buffer has a completely unspecified state. /// - An allocated buffer has been initialized so that it -/// owns unintialized value storage for the stored type. +/// owns uninitialized value storage for the stored type. /// - An initialized buffer is an allocated buffer whose value /// storage has been initialized. struct ValueBuffer { @@ -192,7 +192,7 @@ class ValueWitnessFlags { /// available in this type's value witness table. bool hasExtraInhabitants() const { return Data & HasExtraInhabitants; } /// True if this type's binary representation is that of an enum, and the - /// enum value witness table entries are avaialble in this type's value + /// enum value witness table entries are available in this type's value /// witness table. bool hasEnumWitnesses() const { return Data & HasEnumWitnesses; } constexpr ValueWitnessFlags @@ -247,9 +247,9 @@ typedef void destroyBuffer(ValueBuffer *buffer, const Metadata *self); /// Given an unallocated buffer, initialize it as a copy of the /// object in the source buffer. This can be decomposed as: /// -/// self->initalizeBufferWithCopy(dest, self->projectBuffer(src), self) +/// self->initializeBufferWithCopy(dest, self->projectBuffer(src), self) /// -/// This operation does not need to be safe aginst 'dest' and 'src' aliasing. +/// This operation does not need to be safe against 'dest' and 'src' aliasing. /// /// Preconditions: /// 'dest' is an unallocated buffer @@ -305,7 +305,7 @@ typedef OpaqueValue *initializeBufferWithCopy(ValueBuffer *dest, /// Given an uninitialized object and an initialized object, copy /// the value. /// -/// This operation does not need to be safe aginst 'dest' and 'src' aliasing. +/// This operation does not need to be safe against 'dest' and 'src' aliasing. /// /// Returns the dest object. /// @@ -322,7 +322,7 @@ typedef OpaqueValue *initializeWithCopy(OpaqueValue *dest, /// Given two initialized objects, copy the value from one to the /// other. /// -/// This operation must be safe aginst 'dest' and 'src' aliasing. +/// This operation must be safe against 'dest' and 'src' aliasing. /// /// Returns the dest object. /// @@ -337,7 +337,7 @@ typedef OpaqueValue *assignWithCopy(OpaqueValue *dest, /// the value from the object to the buffer, leaving the source object /// uninitialized. /// -/// This operation does not need to be safe aginst 'dest' and 'src' aliasing. +/// This operation does not need to be safe against 'dest' and 'src' aliasing. /// /// Returns the dest object. /// @@ -355,11 +355,11 @@ typedef OpaqueValue *initializeBufferWithTake(ValueBuffer *dest, /// the value from one to the other, leaving the source object /// uninitialized. /// -/// There is no need for a initializeBufferWithTakeOfBuffer, because that +/// There is no need for an initializeBufferWithTakeOfBuffer, because that /// can simply be a pointer-aligned memcpy of sizeof(ValueBuffer) /// bytes. /// -/// This operation does not need to be safe aginst 'dest' and 'src' aliasing. +/// This operation does not need to be safe against 'dest' and 'src' aliasing. /// /// Returns the dest object. /// @@ -377,7 +377,7 @@ typedef OpaqueValue *initializeWithTake(OpaqueValue *dest, /// the value from one to the other, leaving the source object /// uninitialized. /// -/// This operation does not need to be safe aginst 'dest' and 'src' aliasing. +/// This operation does not need to be safe against 'dest' and 'src' aliasing. /// Therefore this can be decomposed as: /// /// self->destroy(dest, self); @@ -411,10 +411,10 @@ typedef OpaqueValue *allocateBuffer(ValueBuffer *buffer, /// value from one buffer to the other, leaving the source buffer /// unallocated. /// -/// This operation does not need to be safe aginst 'dest' and 'src' aliasing. +/// This operation does not need to be safe against 'dest' and 'src' aliasing. /// Therefore this can be decomposed as: /// -/// self->initalizeBufferWithTake(dest, self->projectBuffer(src), self) +/// self->initializeBufferWithTake(dest, self->projectBuffer(src), self) /// self->deallocateBuffer(src, self) /// /// However, it may be more efficient because values stored out-of-line @@ -447,7 +447,7 @@ typedef void destroyArray(OpaqueValue *array, size_t n, /// Given an uninitialized array and an initialized array, copy /// the value. /// -/// This operation does not need to be safe aginst 'dest' and 'src' aliasing. +/// This operation does not need to be safe against 'dest' and 'src' aliasing. /// /// Returns the dest object. /// @@ -545,6 +545,13 @@ typedef unsigned getEnumTag(const OpaqueValue *src, typedef void destructiveProjectEnumData(OpaqueValue *src, const Metadata *self); +/// Given a valid object of an enum case payload's type, destructively add +/// the tag bits for the given case, leaving behind a fully-formed value of +/// the enum type. If the enum case does not have a payload, the initial +/// state of the value can be undefined. +typedef void destructiveInjectEnumTag(OpaqueValue *src, + unsigned tag, + const Metadata *self); } // end namespace value_witness_types @@ -702,18 +709,22 @@ struct ExtraInhabitantsValueWitnessTable : ValueWitnessTable { struct EnumValueWitnessTable : ExtraInhabitantsValueWitnessTable { value_witness_types::getEnumTag *getEnumTag; value_witness_types::destructiveProjectEnumData *destructiveProjectEnumData; + value_witness_types::destructiveInjectEnumTag *destructiveInjectEnumTag; constexpr EnumValueWitnessTable() : ExtraInhabitantsValueWitnessTable(), getEnumTag(nullptr), - destructiveProjectEnumData(nullptr) {} + destructiveProjectEnumData(nullptr), + destructiveInjectEnumTag(nullptr) {} constexpr EnumValueWitnessTable( const ExtraInhabitantsValueWitnessTable &base, value_witness_types::getEnumTag *getEnumTag, - value_witness_types::destructiveProjectEnumData *destructiveProjectEnumData) + value_witness_types::destructiveProjectEnumData *destructiveProjectEnumData, + value_witness_types::destructiveInjectEnumTag *destructiveInjectEnumTag) : ExtraInhabitantsValueWitnessTable(base), getEnumTag(getEnumTag), - destructiveProjectEnumData(destructiveProjectEnumData) {} + destructiveProjectEnumData(destructiveProjectEnumData), + destructiveInjectEnumTag(destructiveInjectEnumTag) {} static bool classof(const ValueWitnessTable *table) { return table->flags.hasEnumWitnesses(); @@ -992,6 +1003,7 @@ struct Metadata { case MetadataKind::Function: case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Tuple: case MetadataKind::Existential: @@ -1018,6 +1030,7 @@ struct Metadata { case MetadataKind::ForeignClass: case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Tuple: case MetadataKind::Function: @@ -1070,6 +1083,9 @@ struct Metadata { void vw_destructiveProjectEnumData(OpaqueValue *value) const { getValueWitnesses()->_asEVWT()->destructiveProjectEnumData(value, this); } + void vw_destructiveInjectEnumTag(OpaqueValue *value, unsigned tag) const { + getValueWitnesses()->_asEVWT()->destructiveInjectEnumTag(value, tag, this); + } /// Get the nominal type descriptor if this metadata describes a nominal type, /// or return null if it does not. @@ -1732,7 +1748,8 @@ struct EnumMetadata : public Metadata { } static bool classof(const Metadata *metadata) { - return metadata->getKind() == MetadataKind::Enum; + return metadata->getKind() == MetadataKind::Enum + || metadata->getKind() == MetadataKind::Optional; } }; @@ -2089,6 +2106,25 @@ struct GenericMetadata { } }; +/// \brief The control structure of a generic protocol conformance. +struct GenericWitnessTable { + /// The size of the witness table in words. + uint16_t WitnessTableSizeInWords; + + /// The amount to copy from the pattern in words. The rest is zeroed. + uint16_t WitnessTableSizeInWordsToCopy; + + /// The pattern. + RelativeDirectPointer Pattern; + + /// The instantiation function, which is called after the template is copied. + RelativeDirectPointer Instantiator; + + void *PrivateData[swift::NumGenericMetadataPrivateDataWords]; +}; + /// The structure of a protocol conformance record. /// /// This contains enough static information to recover the witness table for a @@ -2316,6 +2352,20 @@ swift_allocateGenericClassMetadata(GenericMetadata *pattern, extern "C" Metadata * swift_allocateGenericValueMetadata(GenericMetadata *pattern, const void *arguments); + +/// Instantiate a generic protocol witness table. +/// +/// +/// \param instantiationArgs - An opaque pointer that's forwarded to +/// the instantiation function, used for conditional conformances. +/// This API implicitly embeds an assumption that these arguments +/// never form part of the uniquing key for the conformance, which +/// is ultimately a statement about the user model of overlapping +/// conformances. +extern "C" const WitnessTable * +swift_getGenericWitnessTable(GenericWitnessTable *genericTable, + const Metadata *type, + void * const *instantiationArgs); /// \brief Fetch a uniqued metadata for a function type. extern "C" const FunctionTypeMetadata * @@ -2474,7 +2524,6 @@ struct ClassFieldLayout { /// Initialize the field offset vector for a dependent-layout class, using the /// "Universal" layout strategy. extern "C" void swift_initClassMetadata_UniversalStrategy(ClassMetadata *self, - const ClassMetadata *super, size_t numFields, const ClassFieldLayout *fieldLayouts, size_t *fieldOffsets); @@ -2769,17 +2818,6 @@ extern "C" void swift_registerProtocolConformances(const ProtocolConformanceRecord *begin, const ProtocolConformanceRecord *end); -/// FIXME: This doesn't belong in the runtime. -extern "C" void swift_printAny(OpaqueValue *value, const Metadata *type); - -/// \brief Demangle a mangled class name into module+class. -/// Returns true if the name was successfully decoded. -/// On success, *outModule and *outClass must be freed with free(). -extern "C" bool -swift_demangleSimpleClass(const char *mangledName, - char **outModule, char **outClass); - - /// Return the type name for a given type metadata. std::string nameForMetadata(const Metadata *type, bool qualified = true); diff --git a/include/swift/Runtime/ObjCBridge.h b/include/swift/Runtime/ObjCBridge.h index 01949cabdaba5..44f2ad4b7a3b3 100644 --- a/include/swift/Runtime/ObjCBridge.h +++ b/include/swift/Runtime/ObjCBridge.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -54,7 +54,7 @@ typedef struct objc_image_info { } objc_image_info; // Class and metaclass construction from a compiler-generated memory image. -// cls and cls->isa must each be OBJC_MAX_CLASS_SIZE bytes.· +// cls and cls->isa must each be OBJC_MAX_CLASS_SIZE bytes. // Extra bytes not used the metadata must be zero. // info is the same objc_image_info that would be emitted by a static compiler. // Returns nil if a class with the same name already exists. diff --git a/include/swift/Runtime/Once.h b/include/swift/Runtime/Once.h index c31f0623a96e3..ee546272a46a4 100644 --- a/include/swift/Runtime/Once.h +++ b/include/swift/Runtime/Once.h @@ -1,8 +1,8 @@ -//===--- Once.h - Runtime support for lazy initialization ------*- C++ -*--===// +//===--- Once.h - Runtime support for lazy initialization -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Runtime/Reflection.h b/include/swift/Runtime/Reflection.h index 7a948faf57792..e29ad6242fb76 100644 --- a/include/swift/Runtime/Reflection.h +++ b/include/swift/Runtime/Reflection.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/AbstractionPattern.h b/include/swift/SIL/AbstractionPattern.h index 8849874e8fc3b..dcd3f81e3811e 100644 --- a/include/swift/SIL/AbstractionPattern.h +++ b/include/swift/SIL/AbstractionPattern.h @@ -1,8 +1,8 @@ -//===--- AbstractionPattern.h - SIL type abstraction pattersn ---*- C++ -*-===// +//===--- AbstractionPattern.h - SIL type abstraction patterns ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -267,13 +267,6 @@ class AbstractionPattern { Kind getKind() const { return Kind(TheKind); } - CanGenericSignature getGenericSignature() const { - assert(getKind() == Kind::Type || - hasStoredClangType() || - hasStoredObjCMethod()); - return CanGenericSignature(GenericSig); - } - CanGenericSignature getGenericSignatureForFunctionComponent() const { if (auto genericFn = dyn_cast(getType())) { return genericFn.getGenericSignature(); @@ -362,6 +355,13 @@ class AbstractionPattern { return AbstractionPattern(Kind::Invalid); } + CanGenericSignature getGenericSignature() const { + assert(getKind() == Kind::Type || + hasStoredClangType() || + hasStoredObjCMethod()); + return CanGenericSignature(GenericSig); + } + /// Return an open-coded abstraction pattern for a tuple. The /// caller is responsible for ensuring that the storage for the /// tuple elements is valid for as long as the abstraction pattern is. diff --git a/include/swift/SIL/BridgedTypes.def b/include/swift/SIL/BridgedTypes.def index 0b725397e1ac7..9e95c144233cd 100644 --- a/include/swift/SIL/BridgedTypes.def +++ b/include/swift/SIL/BridgedTypes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/CFG.h b/include/swift/SIL/CFG.h index b253fcb5858e9..281ccb4d5ff84 100644 --- a/include/swift/SIL/CFG.h +++ b/include/swift/SIL/CFG.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/Consumption.h b/include/swift/SIL/Consumption.h index 7a6b34ff8ac50..31ac3541b4c29 100644 --- a/include/swift/SIL/Consumption.h +++ b/include/swift/SIL/Consumption.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/DebugUtils.h b/include/swift/SIL/DebugUtils.h index 492a9b51ebab0..16a2601b2339c 100644 --- a/include/swift/SIL/DebugUtils.h +++ b/include/swift/SIL/DebugUtils.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -158,6 +158,17 @@ inline bool hasOneNonDebugUse(const V &value) { return ++I == E; } +// Returns the use if the value has only one non debug user. +template +inline SILInstruction *getSingleNonDebugUser(const V &value) { + auto Range = getNonDebugUses(value); + auto I = Range.begin(), E = Range.end(); + if (I == E) return nullptr; + if (std::next(I) != E) + return nullptr; + return I->getUser(); +} + /// Erases the instruction \p I from it's parent block and deletes it, including /// all debug instructions which use \p I. /// Precondition: The instruction may only have debug instructions as uses. diff --git a/include/swift/SIL/Dominance.h b/include/swift/SIL/Dominance.h index 03a1b307e1136..62da9a5f15912 100644 --- a/include/swift/SIL/Dominance.h +++ b/include/swift/SIL/Dominance.h @@ -1,8 +1,8 @@ -//===--- Dominance.h - SIL dominance analysis ------------------*- C++ -*-===// +//===--- Dominance.h - SIL dominance analysis -------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -41,7 +41,7 @@ class DominanceInfo : public llvm::DominatorTreeBase { /// Return true if the other dominator tree does not match this dominator /// tree. - inline bool errorOccuredOnComparison(const DominanceInfo &Other) const { + inline bool errorOccurredOnComparison(const DominanceInfo &Other) const { const auto *R = getRootNode(); const auto *OtherR = Other.getRootNode(); @@ -131,13 +131,23 @@ class PostDominanceInfo : public llvm::DominatorTreeBase { /// Return true if the other dominator tree does not match this dominator /// tree. - inline bool errorOccuredOnComparison(const PostDominanceInfo &Other) const { + inline bool errorOccurredOnComparison(const PostDominanceInfo &Other) const { const auto *R = getRootNode(); const auto *OtherR = Other.getRootNode(); if (!R || !OtherR || R->getBlock() != OtherR->getBlock()) return true; + if (!R->getBlock()) { + // The post dom-tree has multiple roots. The compare() function can not + // cope with multiple roots if at least one of the roots is caused by + // an infinite loop in the CFG (it crashes because no nodes are allocated + // for the blocks in the infinite loop). + // So we return a conservative false in this case. + // TODO: eventually fix the DominatorTreeBase::compare() function. + return false; + } + // Returns *false* if they match. if (compare(Other)) return true; diff --git a/include/swift/SIL/DynamicCasts.h b/include/swift/SIL/DynamicCasts.h index bed027ce33933..5364b3ba93b89 100644 --- a/include/swift/SIL/DynamicCasts.h +++ b/include/swift/SIL/DynamicCasts.h @@ -1,8 +1,8 @@ -//===--- DynamicsCasts.h - SIL dynamic-cast utilities -----------*- C++ -*-===// +//===--- DynamicCasts.h - SIL dynamic-cast utilities ------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/FormalLinkage.h b/include/swift/SIL/FormalLinkage.h index 5bc39f676c1ac..f6fa16de6c6a3 100644 --- a/include/swift/SIL/FormalLinkage.h +++ b/include/swift/SIL/FormalLinkage.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/LoopInfo.h b/include/swift/SIL/LoopInfo.h index 50dc542b49e4b..7a761a9d95e59 100644 --- a/include/swift/SIL/LoopInfo.h +++ b/include/swift/SIL/LoopInfo.h @@ -1,8 +1,8 @@ -//===-------------- LoopInfo.h - SIL Loop Analysis -----*- C++ -*----------===// +//===--- LoopInfo.h - SIL Loop Analysis -------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -46,6 +46,10 @@ class SILLoop : public llvm::LoopBase { return make_range(begin(), end()); } + /// Check whether it is safe to duplicate this instruction when duplicating + /// this loop by unrolling or versioning. + bool canDuplicate(SILInstruction *Inst) const; + private: friend class llvm::LoopInfoBase; diff --git a/include/swift/SIL/Mangle.h b/include/swift/SIL/Mangle.h index bf7e54af6b323..1425aead3dcad 100644 --- a/include/swift/SIL/Mangle.h +++ b/include/swift/SIL/Mangle.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -26,8 +26,6 @@ namespace swift { class AbstractClosureExpr; -namespace Mangle { - enum class SpecializationKind : uint8_t { Generic, FunctionSignature, @@ -40,7 +38,7 @@ class SpecializationManglerBase { protected: SpecializationKind Kind; SpecializationPass Pass; - Mangler &M; + Mangle::Mangler &M; SILFunction *Function; public: @@ -57,34 +55,34 @@ class SpecializationManglerBase { protected: SpecializationManglerBase(SpecializationKind K, SpecializationPass P, - Mangler &M, SILFunction *F) + Mangle::Mangler &M, SILFunction *F) : Kind(K), Pass(P), M(M), Function(F) {} - llvm::raw_ostream &getBuffer() { return M.Buffer; } SILFunction *getFunction() const { return Function; } - Mangler &getMangler() const { return M; } + Mangle::Mangler &getMangler() const { return M; } void mangleKind() { switch (Kind) { case SpecializationKind::Generic: - M.Buffer << "g"; + M.append("g"); break; case SpecializationKind::FunctionSignature: - M.Buffer << "f"; + M.append("f"); break; } } void manglePass() { - M.Buffer << encodeSpecializationPass(Pass); + M.append(encodeSpecializationPass(Pass)); } void mangleSpecializationPrefix() { - M.Buffer << "_TTS"; + M.append("_TTS"); } void mangleFunctionName() { - M.Buffer << "_" << Function->getName(); + M.append("_"); + M.appendSymbol(Function->getName()); } }; @@ -112,8 +110,8 @@ class SpecializationMangler : public SpecializationManglerBase { } protected: - SpecializationMangler(SpecializationKind K, SpecializationPass P, Mangler &M, - SILFunction *F) + SpecializationMangler(SpecializationKind K, SpecializationPass P, + Mangle::Mangler &M, SILFunction *F) : SpecializationManglerBase(K, P, M, F) {} }; @@ -125,7 +123,7 @@ class GenericSpecializationMangler : ArrayRef Subs; public: - GenericSpecializationMangler(Mangler &M, SILFunction *F, + GenericSpecializationMangler(Mangle::Mangler &M, SILFunction *F, ArrayRef Subs) : SpecializationMangler(SpecializationKind::Generic, SpecializationPass::GenericSpecializer, @@ -148,7 +146,8 @@ class FunctionSignatureSpecializationMangler Unmodified=0, ConstantProp=1, ClosureProp=2, - InOutToValue=3, + BoxToValue=3, + BoxToStack=4, First_Option=0, Last_Option=31, // Option Set Space. 12 bits (i.e. 12 option). @@ -164,14 +163,15 @@ class FunctionSignatureSpecializationMangler public: FunctionSignatureSpecializationMangler(SpecializationPass Pass, - Mangler &M, SILFunction *F); + Mangle::Mangler &M, SILFunction *F); void setArgumentConstantProp(unsigned ArgNo, LiteralInst *LI); void setArgumentClosureProp(unsigned ArgNo, PartialApplyInst *PAI); void setArgumentClosureProp(unsigned ArgNo, ThinToThickFunctionInst *TTTFI); void setArgumentDead(unsigned ArgNo); void setArgumentOwnedToGuaranteed(unsigned ArgNo); void setArgumentSROA(unsigned ArgNo); - void setArgumentInOutToValue(unsigned ArgNo); + void setArgumentBoxToValue(unsigned ArgNo); + void setArgumentBoxToStack(unsigned ArgNo); private: void mangleSpecialization(); @@ -182,7 +182,6 @@ class FunctionSignatureSpecializationMangler NullablePtr Inst); }; -} // end namespace Mangle } // end namespace swift #endif diff --git a/include/swift/SIL/MemLocation.h b/include/swift/SIL/MemLocation.h deleted file mode 100644 index e89b86c6d040a..0000000000000 --- a/include/swift/SIL/MemLocation.h +++ /dev/null @@ -1,509 +0,0 @@ -//===------------------------ MemLocation.h ----------------------------- -===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// -// This file defines the class Location. A MemLocation is an abstraction of an -// object field in program. It consists of a base that is the tracked SILValue -// and a projection path to the represented field. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SIL_MEMLOCATION_H -#define SWIFT_SIL_MEMLOCATION_H - -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SIL/Projection.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/Hashing.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Debug.h" - -namespace swift { - -/// forward declarations. -class SILValueProjection; -class MemLocation; -class LoadStoreValue; - -//===----------------------------------------------------------------------===// -// SILValue Projection -//===----------------------------------------------------------------------===// - -/// This class contains a SILValue base and a ProjectionPath. It is used as -/// the base class for MemLocation and LoadStoreValue. -/// -/// In the case of MemLocation, the base represents the base of the allocated -/// objects and the ProjectionPath tells which field in the object the -/// MemLocation represents. -/// -/// In the case of LoadStoreValue, the base represents the root of loaded or -/// stored value it represents. And the ProjectionPath represents the field in -/// the loaded/store value the LoadStoreValue represents. -/// -class SILValueProjection { -public: - enum KeyKind : uint8_t { EmptyKey = 0, TombstoneKey, NormalKey }; - -protected: - /// The base of the object. - SILValue Base; - /// Empty key, tombstone key or normal key. - KeyKind Kind; - /// The path to reach the accessed field of the object. - Optional Path; - -public: - /// Constructors. - SILValueProjection() : Base(), Kind(NormalKey) {} - SILValueProjection(KeyKind Kind) : Base(), Kind(Kind) {} - SILValueProjection(SILValue B) : Base(B), Kind(NormalKey) {} - SILValueProjection(SILValue B, ProjectionPath &P, KeyKind Kind = NormalKey) - : Base(B), Kind(Kind), Path(std::move(P)) {} - - /// Destructors. - virtual ~SILValueProjection() {} - - /// Copy constructor. - SILValueProjection(const SILValueProjection &RHS) { - Base = RHS.Base; - Path.reset(); - Kind = RHS.Kind; - if (!RHS.Path.hasValue()) - return; - ProjectionPath X; - X.append(RHS.Path.getValue()); - Path = std::move(X); - } - - SILValueProjection &operator=(const SILValueProjection &RHS) { - Base = RHS.Base; - Path.reset(); - Kind = RHS.Kind; - if (!RHS.Path.hasValue()) - return *this; - ProjectionPath X; - X.append(RHS.Path.getValue()); - Path = std::move(X); - return *this; - } - - /// Getters and setters for SILValueProjection. - KeyKind getKind() const { return Kind; } - void setKind(KeyKind K) { Kind = K; } - SILValue getBase() const { return Base; } - Optional &getPath() { return Path; } - - /// Reset the SILValueProjection, i.e. clear base and path. - void reset() { - Base = SILValue(); - Path.reset(); - Kind = NormalKey; - } - - /// Returns whether the SILValueProjection has been initialized properly. - virtual bool isValid() const { return Base && Path.hasValue(); } - - /// Returns true if the LoadStoreValue has a non-empty projection path. - bool hasEmptyProjectionPath() const { return !Path.getValue().size(); } - - /// Return false if one projection path is a prefix of another. false - /// otherwise. - bool hasNonEmptySymmetricPathDifference(const SILValueProjection &RHS) const { - const ProjectionPath &P = RHS.Path.getValue(); - return Path.getValue().hasNonEmptySymmetricDifference(P); - } - - /// Substract the given path from the ProjectionPath. - void subtractPaths(Optional &P) { - if (!P.hasValue()) - return; - ProjectionPath::subtractPaths(Path.getValue(), P.getValue()); - } - - /// Return true if the RHS have identical projection paths. - /// If both SILValueProjection have empty paths, they are treated as having - /// identical projection path. - bool hasIdenticalProjectionPath(const SILValueProjection &RHS) const { - // If both Paths have no value, then the 2 SILValueProjections are different. - if (!Path.hasValue() && !RHS.Path.hasValue()) - return false; - // If 1 Path has value while the other does not, then the 2 - // SILValueProjections are different. - if (Path.hasValue() != RHS.Path.hasValue()) - return false; - // If both Paths are empty, then the 2 SILValueProjections are the same. - if (Path.getValue().empty() && RHS.Path.getValue().empty()) - return true; - // If both Paths have different values, then the 2 SILValueProjections are - // different. - if (Path.getValue() != RHS.Path.getValue()) - return false; - return true; - } - - /// Comparisons. - bool operator!=(const SILValueProjection &RHS) const { - return !(*this == RHS); - } - bool operator==(const SILValueProjection &RHS) const { - // If type is not the same, then SILValueProjections different. - if (Kind != RHS.Kind) - return false; - // Return true if this is a TombstoneKey or EmptyKey. - if (Kind == EmptyKey || Kind == TombstoneKey) - return true; - // If Base is different, then SILValueProjections different. - if (Base != RHS.Base) - return false; - // If the projection paths are different, then SILValueProjections are - // different. - if (!hasIdenticalProjectionPath(RHS)) - return false; - // These SILValueProjections represent the same memory location. - return true; - } - - /// Returns the hashcode for the location. - llvm::hash_code getHashCode() const { - llvm::hash_code HC = llvm::hash_combine( - Base.getDef(), Base.getResultNumber(), Base.getType()); - if (!Path.hasValue()) - return HC; - HC = llvm::hash_combine(HC, hash_value(Path.getValue())); - return HC; - } - - virtual void print() const; -}; - -//===----------------------------------------------------------------------===// -// Load Store Value -//===----------------------------------------------------------------------===// - -using LoadStoreValueList = llvm::SmallVector; -using MemLocationValueMap = llvm::DenseMap; -using ValueTableMap = llvm::SmallMapVector; - -/// This class represents either a single SILValue or a covering of values that -/// we can forward from via the introdution of a SILArgument. This enables us -/// to treat the case of having one value or multiple values and load and store -/// cases all at once abstractly and cleanly. -/// -/// A LoadStoreValue is an abstraction of an object field value in program. It -/// consists of a base that is the tracked SILValue, and a projection path to -/// the represented field. -/// -/// In this example below, 2 LoadStoreValues will be created for the 2 stores, -/// they will have %6 and %7 as their Bases and empty projection paths. -/// -/// struct A { -/// var a: Int -/// var b: Int -/// } -/// -/// sil hidden @test_1 : $@convention(thin) () -> () { -/// %0 = alloc_stack $A // var x // users: %4, %7 -/// %5 = integer_literal $Builtin.Int64, 19 // user: %6 -/// %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 -/// %7 = struct_element_addr %0#1 : $*A, #A.a // user: %8 -/// store %6 to %7 : $*Int // id: %8 -/// %9 = integer_literal $Builtin.Int64, 20 // user: %10 -/// %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 -/// %11 = struct_element_addr %0#1 : $*A, #A.b // user: %12 -/// store %10 to %11 : $*Int // id: %12 -/// } -/// -/// In this example below, 2 LoadStoreValues will be created with %3 as their -/// bases and #a and #b as their projection paths respectively. -/// -/// sil hidden @test_1 : $@convention(thin) () -> () { -/// %0 = alloc_stack $A // var x // users: %4, %6 -/// // function_ref a.A.init (a.A.Type)() -> a.A -/// %1 = function_ref @a.A.init : $@convention(thin) (@thin A.Type) -> A -/// %2 = metatype $@thin A.Type // user: %3 -/// %3 = apply %1(%2) : $@convention(thin) (@thin A.Type) -> A // user: %4 -/// store %3 to %0#1 : $*A // id: %4 -/// } -/// -/// NOTE: LoadStoreValue can take 2 forms. -/// -/// 1. It can take a concrete value, i.e. with a valid Base and ProjectionPath. -/// using the extract function, it can be materialized in IR. -/// -/// 2. It can represent a covering set of LoadStoreValues from all predecessor -/// blocks. and to get the forwardable SILValue, we need to go to its -/// predecessors to materialize each one of them and create the forwarding -/// SILValue through a SILArgument. -/// -/// Given a set of MemLocations and their available LoadStoreValues, -/// reduceWithValues will create the forwarding SILValue by merging them while -/// creating as few value extraction and aggregation as possible. -/// -/// NOTE: ProjectionPath in LoadStoreValue could be replaced by the -/// ProjectionPath in the MemLocation, but that would require we break the -/// ProjectionPath into 2 parts, 1 for the Base to the accessed (aggregate) node -/// and another 1 for the accessed (aggregate) node to the leaf node the -/// MemLocation represents. -/// -/// This makes implementing the MemLocationVault more difficult, as there are -/// multiple ways to represent the same MemLocations (even they have the same -/// base). -/// -class LoadStoreValue : public SILValueProjection { - /// If this is a covering value, we need to go to each predecessor to - /// materialize the value. - bool IsCoveringValue; - - /// Create a path of ValueProjection with the given VA and Path. - SILValue createExtract(SILValue VA, Optional &Path, - SILInstruction *Inst); - -public: - /// Constructors. - LoadStoreValue() : SILValueProjection(), IsCoveringValue(false) {} - LoadStoreValue(SILValue B) : SILValueProjection(B), IsCoveringValue(false) {} - LoadStoreValue(SILValue B, ProjectionPath &P) - : SILValueProjection(B, P), IsCoveringValue(false) {} - - /// Copy constructor. - LoadStoreValue(const LoadStoreValue &RHS) : SILValueProjection(RHS) { - IsCoveringValue = RHS.IsCoveringValue; - } - - /// Assignment operator. - LoadStoreValue &operator=(const LoadStoreValue &RHS) { - SILValueProjection::operator=(RHS); - IsCoveringValue = RHS.IsCoveringValue; - return *this; - } - - /// Returns whether the LoadStoreValue has been initialized properly. - bool isValid() const { - if (IsCoveringValue) - return true; - return Base && Path.hasValue(); - } - - /// Take the last level projection off. Return the modified LoadStoreValue. - LoadStoreValue &stripLastLevelProjection(){ - Path.getValue().remove_front(); - return *this; - } - - /// Returns true if this LoadStoreValue is a covering value. - bool isCoveringValue() const { return IsCoveringValue; } - /// Mark this LoadStoreValue as a covering value. - void setCoveringValue() { - Base = SILValue(); - Path.reset(); - IsCoveringValue = true; - } - - /// Materialize the SILValue that this LoadStoreValue represents. - /// - /// In the case where we have a single value this can be materialized by - /// applying Path to the Base. - /// - /// In the case where we are handling a covering set, this is initially null - /// and when we insert the PHI node, this is set to the SILArgument which - /// represents the PHI node. - SILValue materialize(SILInstruction *Inst) { - // - // TODO: handle covering value. - // - if (IsCoveringValue) - return SILValue(); - return createExtract(Base, Path, Inst); - } - - void print() const { - if (IsCoveringValue) { - llvm::outs() << "Covering Value"; - return; - } - SILValueProjection::print(); - } -}; - -//===----------------------------------------------------------------------===// -// Memory Location -//===----------------------------------------------------------------------===// -/// Type declarations. -using MemLocationSet = llvm::DenseSet; -using MemLocationList = llvm::SmallVector; -using MemLocationIndexMap = llvm::DenseMap; -using TypeExpansionMap = llvm::DenseMap; - -/// This class represents a field in an allocated object. It consists of a -/// base that is the tracked SILValue, and a projection path to the -/// represented field. -/// -/// The base here will point to the actual object this inst is accessing, -/// not this particular field. We call this MemLocation canonicalization. -/// -/// e.g. %1 = alloc_stack $S -/// %2 = struct_element_addr %1, #a -/// store %3 to %2 : $*Int -/// -/// Base will point to %1, but not %2. Projection path will indicate which -/// field is accessed. -/// -/// Canonicalizing MemLocation reduces the # of the MemLocations we keep in -/// the MemLocationVault, and this in turn reduces the # of bits each basic -/// block keeps. -/// -/// Moreover, without canonicalization, its more difficult to implement the -/// intersection operator in DSE/RLE? -/// -/// We basically need to compare every pair of MemLocation and find the ones -/// that must alias O(n^2). Or we need to go through every MemLocation in the -/// vault and turn on/off the bits for the MustAlias ones whenever we want to -/// turn a MemLocation bit on/off. Both are expensive. -/// -/// Canonicalizing suffers from the same problem, but to a lesser extend. i.e. -/// 2 MemLocations with different bases but happen to be the same object and -/// field. By doing canonicalization, the intersection is simply a bitwise AND -/// (No AA involved). -/// -class MemLocation : public SILValueProjection { -public: - /// Constructors. - MemLocation() {} - MemLocation(SILValue B) : SILValueProjection(B) { initialize(B); } - MemLocation(SILValue B, ProjectionPath &P, KeyKind Kind = NormalKey) - : SILValueProjection(B, P, Kind) {} - MemLocation(KeyKind Kind) : SILValueProjection(Kind) {} - - /// Copy constructor. - MemLocation(const MemLocation &RHS) : SILValueProjection(RHS) {} - - /// Assignment operator. - MemLocation &operator=(const MemLocation &RHS) { - SILValueProjection::operator=(RHS); - return *this; - } - - /// Returns the type of the object the MemLocation represents. - SILType getType() const { - // Base might be a address type, e.g. from alloc_stack of struct, - // enum or tuples. - if (Path.getValue().empty()) - return Base.getType().getObjectType(); - return Path.getValue().front().getType().getObjectType(); - } - - /// Trace the given SILValue till the base of the accessed object. Also - /// construct the projection path to the field accessed. - void initialize(SILValue val); - - /// Get the first level locations based on this location's first level - /// projection. - void getFirstLevelMemLocations(MemLocationList &Locs, SILModule *Mod); - - /// Returns true if the MemLocation is local to this function, i.e. - /// does not escape. - /// - /// TODO: we should look at the projection path as well. i.e. one field - /// might escape but the object itself does not. - /// - bool isNonEscapingLocalMemLocation() { - assert(isValid() && "Invalid memory location"); - // TODO: this does not have to be limited to allocstack. - return isa(Base) && isNonEscapingLocalObject(Base); - } - - /// Check whether the 2 MemLocations may alias each other or not. - bool isMayAliasMemLocation(const MemLocation &RHS, AliasAnalysis *AA); - - /// Check whether the 2 MemLocations must alias each other or not. - bool isMustAliasMemLocation(const MemLocation &RHS, AliasAnalysis *AA); - - //============================// - // static functions. // - //============================// - - /// Given Base and 2 ProjectionPaths, create a MemLocation out of them. - static MemLocation createMemLocation(SILValue Base, ProjectionPath &P1, - ProjectionPath &P2); - - /// Expand this location to all individual fields it contains. - /// - /// In SIL, we can have a store to an aggregate and loads from its individual - /// fields. Therefore, we expand all the operations on aggregates onto - /// individual fields and process them separately. - static void expand(MemLocation &Base, SILModule *Mod, MemLocationList &Locs, - TypeExpansionMap &TypeExpansionVault); - - /// Given a set of locations derived from the same base, try to merge/reduce - /// them into smallest number of MemLocations possible. - static void reduce(MemLocation &Base, SILModule *Mod, MemLocationSet &Locs); - - /// Given a memory location and a SILValue, expand the location into its - /// individual fields and the values that is in each individual field. - static void expandWithValues(MemLocation &Base, SILValue &Val, SILModule *Mod, - MemLocationList &Locs, LoadStoreValueList &Vals); - - /// Given a memory location and a map between the expansions of the location - /// and their corresponding values, try to come up with a single SILValue this - /// location holds. This may involve extracting and aggregating available - /// values. - /// - /// NOTE: reduceValues assumes that every component of the location has an - /// concrete (i.e. not coverings set) available value in LocAndVal. - static SILValue reduceWithValues(MemLocation &Base, SILModule *Mod, - MemLocationValueMap &LocAndVal, - SILInstruction *InsertPt); - - /// Enumerate the given Mem MemLocation. - static void enumerateMemLocation(SILModule *M, SILValue Mem, - std::vector &MemLocationVault, - MemLocationIndexMap &LocToBit, - TypeExpansionMap &TypeExpansionVault); - - /// Enumerate all the locations in the function. - static void enumerateMemLocations(SILFunction &F, - std::vector &MemLocationVault, - MemLocationIndexMap &LocToBit, - TypeExpansionMap &TypeExpansionVault); -}; - -static inline llvm::hash_code hash_value(const MemLocation &L) { - return llvm::hash_combine(L.getBase().getDef(), L.getBase().getResultNumber(), - L.getBase().getType()); -} - -} // end swift namespace - -/// MemLocation is used in DenseMap, define functions required by DenseMap. -namespace llvm { - -using swift::MemLocation; -template <> struct DenseMapInfo { - static inline MemLocation getEmptyKey() { - return MemLocation(MemLocation::EmptyKey); - } - static inline MemLocation getTombstoneKey() { - return MemLocation(MemLocation::TombstoneKey); - } - static unsigned getHashValue(const MemLocation &Loc) { - return hash_value(Loc); - } - static bool isEqual(const MemLocation &LHS, const MemLocation &RHS) { - return LHS == RHS; - } -}; - -} // namespace llvm - -#endif // SWIFT_SIL_MEMLOCATION_H diff --git a/include/swift/SIL/Notifications.h b/include/swift/SIL/Notifications.h new file mode 100644 index 0000000000000..244f749bb517a --- /dev/null +++ b/include/swift/SIL/Notifications.h @@ -0,0 +1,44 @@ +//===--- Notifications.h - SIL Undef Value Representation -------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SIL_NOTIFICATIONS_H +#define SWIFT_SIL_NOTIFICATIONS_H + +namespace swift { + +class ValueBase; + +/// A protocol (or interface) for handling value deletion notifications. +/// +/// This class is used as a base class for any class that need to accept +/// instruction deletion notification messages. This is used by passes and +/// analysis that need to invalidate data structures that contain pointers. +/// This is similar to LLVM's ValueHandle. +struct DeleteNotificationHandler { + + DeleteNotificationHandler() { } + virtual ~DeleteNotificationHandler() {} + + /// Handle the invalidation message for the value \p Value. + virtual void handleDeleteNotification(swift::ValueBase *Value) { } + + /// Returns True if the pass, analysis or other entity wants to receive + /// notifications. This callback is called once when the class is being + /// registered, and not once per notification. Entities that implement + /// this callback should always return a constant answer (true/false). + virtual bool needsNotifications() { return false; } +}; + +} // end swift namespace + +#endif + diff --git a/include/swift/SIL/PatternMatch.h b/include/swift/SIL/PatternMatch.h index 6e488d8afda10..6f1f55c468a4a 100644 --- a/include/swift/SIL/PatternMatch.h +++ b/include/swift/SIL/PatternMatch.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -370,7 +370,6 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(DeinitExistentialAddrInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(ProjectBlockStorageInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(StrongRetainInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(StrongReleaseInst) -UNARY_OP_MATCH_WITH_ARG_MATCHER(StrongRetainAutoreleasedInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(StrongRetainUnownedInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(UnownedRetainInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(UnownedReleaseInst) @@ -383,7 +382,6 @@ UNARY_OP_MATCH_WITH_ARG_MATCHER(DeallocBoxInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(DestroyAddrInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(CondFailInst) UNARY_OP_MATCH_WITH_ARG_MATCHER(ReturnInst) -UNARY_OP_MATCH_WITH_ARG_MATCHER(AutoreleaseReturnInst) #undef UNARY_OP_MATCH_WITH_ARG_MATCHER //===----------------------------------------------------------------------===// @@ -693,7 +691,7 @@ using BuiltinApplyTy = typename Apply_match::Ty; /// Matcher for any of the builtin checked conversions. template inline typename OneOf_match, BuiltinApplyTy>::Ty -m_CheckedConversion(const T0 &Op0) { +m_CheckedConversion(const T0 &Op0) { return m_USCheckedConversion(Op0) || m_SUCheckedConversion(Op0); } diff --git a/include/swift/SIL/PrettyStackTrace.h b/include/swift/SIL/PrettyStackTrace.h index 8baaf11021723..0459d186e3476 100644 --- a/include/swift/SIL/PrettyStackTrace.h +++ b/include/swift/SIL/PrettyStackTrace.h @@ -1,8 +1,8 @@ -//===- PrettyStackTrace.h - Crash trace information -------------*- C++ -*-===// +//===--- PrettyStackTrace.h - Crash trace information -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/Projection.h b/include/swift/SIL/Projection.h index 87114bab58551..1c67170f80a9e 100644 --- a/include/swift/SIL/Projection.h +++ b/include/swift/SIL/Projection.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,6 +20,8 @@ #define SWIFT_SIL_PROJECTION_H #include "swift/Basic/NullablePtr.h" +#include "swift/Basic/PointerIntEnum.h" +#include "swift/AST/TypeAlignments.h" #include "swift/SIL/SILValue.h" #include "swift/SIL/SILInstruction.h" #include "llvm/ADT/Hashing.h" @@ -27,14 +29,35 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SetVector.h" #include "llvm/Support/Allocator.h" -#include namespace swift { class SILBuilder; class ProjectionPath; +class NewProjectionPath; using ProjectionPathList = llvm::SmallVector, 8>; +enum class SubSeqRelation_t : uint8_t { + Unknown, + LHSStrictSubSeqOfRHS, + RHSStrictSubSeqOfLHS, + Equal, +}; + +/// Returns true if Seq is either LHSStrictSubSeqOfRHS or +/// RHSStrictSubSeqOfLHS. Returns false if Seq is one of either Equal or +/// Unrelated. +inline bool isStrictSubSeqRelation(SubSeqRelation_t Seq) { + switch (Seq) { + case SubSeqRelation_t::Unknown: + case SubSeqRelation_t::Equal: + return false; + case SubSeqRelation_t::LHSStrictSubSeqOfRHS: + case SubSeqRelation_t::RHSStrictSubSeqOfLHS: + return true; + } +} + /// Extract an integer index from a SILValue. /// /// Return true if IndexVal is a constant index representable as unsigned @@ -42,7 +65,7 @@ using ProjectionPathList = llvm::SmallVector, 8>; bool getIntegerIndex(SILValue IndexVal, unsigned &IndexConst); /// Given a SIL value, capture its element index and the value of the aggregate -/// that immeditely contains it. +/// that immediately contains it. /// /// This lightweight utility maps a SIL address projection to an index. struct ProjectionIndex { @@ -95,7 +118,521 @@ struct ProjectionIndex { }; /// The kind of projection that we are representing. -enum class ProjectionKind : uint8_t { +/// +/// We represent types that need to have a type pointer (i.e. casts) using only +/// up to 3 bits. This is because types are only aligned up to 8 bits. See +/// TypeAlignments.h. +/// +/// Projection Kinds which can be represented via indices can use as many bits +/// as they want to represent the kind. When the index value is uses at most 11 +/// bits, we represent it inline in the data structure. This is taking advantage +/// of the fact that on most modern OSes (including Darwin), the zero page is +/// not allocated. In the case where we have more than 11 bits of value +/// (i.e. the index is >= 2048), we malloc memory to represent the index. In +/// most cases this will not happen. For simplicity, we limit such kinds to use +/// no more than 4 bits. +/// +/// The NewProjection class contains the logic to use NewProjectionKind in this +/// manner. +enum class NewProjectionKind : unsigned { + // PointerProjectionKinds + Upcast = 0, + RefCast = 1, + BitwiseCast = 2, + FirstPointerKind = Upcast, + LastPointerKind = BitwiseCast, + + // Index Projection Kinds + FirstIndexKind = 7, + Struct = PointerIntEnumIndexKindValue<0, NewProjectionKind>::value, + Tuple = PointerIntEnumIndexKindValue<1, NewProjectionKind>::value, + Index = PointerIntEnumIndexKindValue<2, NewProjectionKind>::value, + Class = PointerIntEnumIndexKindValue<3, NewProjectionKind>::value, + Enum = PointerIntEnumIndexKindValue<4, NewProjectionKind>::value, + LastIndexKind = Enum, +}; + +constexpr unsigned MaxPointerProjectionKind = ((1 << TypeAlignInBits) - 1); +/// Make sure that our tagged pointer assumptions are true. See comment above +/// the declaration of NewProjectionKind. +static_assert(unsigned(NewProjectionKind::LastPointerKind) <= + unsigned(MaxPointerProjectionKind), + "Too many projection kinds to fit in Projection"); + +static inline bool isCastNewProjectionKind(NewProjectionKind Kind) { + switch (Kind) { + case NewProjectionKind::Upcast: + case NewProjectionKind::RefCast: + case NewProjectionKind::BitwiseCast: + return true; + case NewProjectionKind::Struct: + case NewProjectionKind::Tuple: + case NewProjectionKind::Index: + case NewProjectionKind::Class: + case NewProjectionKind::Enum: + return false; + } +} + +/// An abstract representation of the index of a subtype of an aggregate +/// type. This is a value type. +/// +/// The intention is it to be paired with a base SILValue in order to provide a +/// lightweight manner of working at a high level with object and address +/// projections. +/// +/// It is intended to be pointer sized and trivially copyable so that memcpy can +/// be used to copy a NewProjection. +class NewProjection { + + friend NewProjectionPath; + + static constexpr unsigned NumPointerKindBits = TypeAlignInBits; + + /// This is the number of bits that we currently use to represent indices at + /// the top of our word. + static constexpr unsigned NumIndexKindBits = 4; + + using ValueTy = PointerIntEnum; + /// A pointer sized type that is used to store the kind of projection that is + /// being represented and also all of the necessary information to convert a + /// base SILType to a derived field SILType. + ValueTy Value; + +public: + NewProjection() = delete; + + explicit NewProjection(SILValue V) + : NewProjection(dyn_cast(V)) {} + explicit NewProjection(SILInstruction *I); + + NewProjection(NewProjection &&P) = default; + NewProjection(const NewProjection &P) = default; + ~NewProjection() = default; + + NewProjection &operator=(const NewProjection &P) = default; + + NewProjection &operator=(NewProjection &&P) = default; + + bool isValid() const { return Value.isValid(); } + + /// Determine if I is a value projection instruction whose corresponding + /// projection equals this projection. + bool matchesObjectProjection(SILInstruction *I) const { + NewProjection P(I); + return P.isValid() && P == *this; + } + + /// If Base's type matches this Projections type ignoring Address vs Object + /// type differences and this Projection is representable as a value + /// projection, create the relevant value projection and return it. Otherwise, + /// return nullptr. + NullablePtr + createObjectProjection(SILBuilder &B, SILLocation Loc, SILValue Base) const; + + /// If Base's type matches this Projections type ignoring Address vs Object + /// type differences and this projection is representable as an address + /// projection, create the relevant address projection and return + /// it. Otherwise, return nullptr. + NullablePtr + createAddressProjection(SILBuilder &B, SILLocation Loc, SILValue Base) const; + + /// Apply this projection to \p BaseType and return the relevant subfield's + /// SILType if BaseField has less subtypes than projection's offset. + SILType getType(SILType BaseType, SILModule &M) const { + assert(isValid()); + switch (getKind()) { + case NewProjectionKind::Struct: + case NewProjectionKind::Class: + return BaseType.getFieldType(getVarDecl(BaseType), M); + case NewProjectionKind::Enum: + return BaseType.getEnumElementType(getEnumElementDecl(BaseType), M); + case NewProjectionKind::Tuple: + return BaseType.getTupleElementType(getIndex()); + case NewProjectionKind::Upcast: + case NewProjectionKind::RefCast: + case NewProjectionKind::BitwiseCast: + return getCastType(BaseType); + case NewProjectionKind::Index: + // Index types do not change the underlying type. + return BaseType; + } + } + + VarDecl *getVarDecl(SILType BaseType) const { + assert(isValid()); + assert((getKind() == NewProjectionKind::Struct || + getKind() == NewProjectionKind::Class)); + assert(BaseType.getNominalOrBoundGenericNominal() && + "This should only be called with a nominal type"); + auto *NDecl = BaseType.getNominalOrBoundGenericNominal(); + auto Iter = NDecl->getStoredProperties().begin(); + std::advance(Iter, getIndex()); + return *Iter; + } + + EnumElementDecl *getEnumElementDecl(SILType BaseType) const { + assert(isValid()); + assert(getKind() == NewProjectionKind::Enum); + assert(BaseType.getEnumOrBoundGenericEnum() && "Expected enum type"); + auto Iter = BaseType.getEnumOrBoundGenericEnum()->getAllElements().begin(); + std::advance(Iter, getIndex()); + return *Iter; + } + + ValueDecl *getValueDecl(SILType BaseType) const { + assert(isValid()); + switch (getKind()) { + case NewProjectionKind::Enum: + return getEnumElementDecl(BaseType); + case NewProjectionKind::Struct: + case NewProjectionKind::Class: + return getVarDecl(BaseType); + case NewProjectionKind::Upcast: + case NewProjectionKind::RefCast: + case NewProjectionKind::BitwiseCast: + case NewProjectionKind::Index: + case NewProjectionKind::Tuple: + llvm_unreachable("NewProjectionKind that does not have a value decl?"); + } + } + + SILType getCastType(SILType BaseType) const { + assert(isValid()); + assert(getKind() == NewProjectionKind::Upcast || + getKind() == NewProjectionKind::RefCast || + getKind() == NewProjectionKind::BitwiseCast); + auto *Ty = getPointer(); + assert(Ty->isCanonical()); + return SILType::getPrimitiveType(Ty->getCanonicalType(), + BaseType.getCategory()); + } + + bool operator==(const NewProjection &Other) const { + return Value == Other.Value; + } + + bool operator!=(const NewProjection &Other) const { + return !(*this == Other); + } + + /// Convenience method for getting the raw underlying kind. + NewProjectionKind getKind() const { return *Value.getKind(); } + + static bool isAddressProjection(SILValue V) { + auto *I = dyn_cast(V); + if (!I) + return false; + return isAddressProjection(I); + } + + /// Returns true if this instruction projects from an address type to an + /// address subtype. + static bool isAddressProjection(SILInstruction *I) { + switch (I->getKind()) { + default: + return false; + case ValueKind::StructElementAddrInst: + case ValueKind::TupleElementAddrInst: + case ValueKind::UncheckedTakeEnumDataAddrInst: + return true; + } + } + + static bool isObjectProjection(SILValue V) { + auto *I = dyn_cast(V); + if (!I) + return false; + return isObjectProjection(I); + } + + /// Returns true if this instruction projects from an object type to an object + /// subtype. + static bool isObjectProjection(SILInstruction *I) { + switch (I->getKind()) { + default: + return false; + case ValueKind::StructExtractInst: + case ValueKind::TupleExtractInst: + return true; + } + } + + static bool isObjectToAddressProjection(SILValue V) { + auto *I = dyn_cast(V); + if (!I) + return false; + return isObjectToAddressProjection(I); + } + + /// Returns true if this instruction projects from an object type into an + /// address subtype. + static bool isObjectToAddressProjection(SILInstruction *I) { + return isa(I); + } + + /// Is this cast which only allows for equality? + /// + /// If we enforce strict type based aliasing when computing access paths this + /// will not be necessary. For now we are conservative since I don't have time + /// to track down potential miscompiles. If we introduce such a thing, we will + /// need a new instruction that a frontend can use to introduce aliasing + /// relationships when TBAA would say that aliasing can not occur. + bool isAliasingCast() const { + switch (getKind()) { + case NewProjectionKind::RefCast: + case NewProjectionKind::BitwiseCast: + return true; + case NewProjectionKind::Upcast: + case NewProjectionKind::Struct: + case NewProjectionKind::Tuple: + case NewProjectionKind::Index: + case NewProjectionKind::Class: + case NewProjectionKind::Enum: + return false; + } + } + + /// Given a specific SILType, return all first level projections if + /// it is an aggregate. + static void + getFirstLevelProjections(SILType V, SILModule &Mod, + llvm::SmallVectorImpl &Out); + + bool isNominalKind() const { + switch (getKind()) { + case NewProjectionKind::Class: + case NewProjectionKind::Enum: + case NewProjectionKind::Struct: + return true; + case NewProjectionKind::BitwiseCast: + case NewProjectionKind::Index: + case NewProjectionKind::RefCast: + case NewProjectionKind::Tuple: + case NewProjectionKind::Upcast: + return false; + } + } + +private: + /// Convenience method for getting the underlying index. Assumes that this + /// projection is valid. Otherwise it asserts. + unsigned getIndex() const { + return Value.getIndex(); + } + + /// Convenience method for getting the raw underlying index as a pointer. + TypeBase *getPointer() const { + return Value.getPointer(); + } + + NewProjection(NewProjectionKind Kind, unsigned NewIndex) + : Value(Kind, NewIndex) {} + + NewProjection(NewProjectionKind Kind, TypeBase *Ptr) + : Value(Kind, Ptr) {} +}; + +/// This is to make sure that new projection is never bigger than a +/// pointer. This is just for performance. +static_assert(sizeof(NewProjection) == sizeof(uintptr_t), + "IndexType should be pointer sized"); + +/// A "path" of projections abstracting either value or aggregate projections +/// upon a value. +/// +/// The main purpose of this class is to enable one to reason about iterated +/// chains of projections. Some example usages are: +/// +/// 1. Converting value projections to aggregate projections or vis-a-versa. +/// 2. Performing tuple operations on two paths (using the mathematical +/// definition of tuples as ordered sets). +class NewProjectionPath { +public: + using PathTy = llvm::SmallVector; + +private: + SILType BaseType; + PathTy Path; + +public: + /// Create an empty path which serves as a stack. Use push_back() to populate + /// the stack with members. + NewProjectionPath(SILType Base) : BaseType(Base), Path() {} + ~NewProjectionPath() = default; + + /// Do not allow copy construction. The only way to get one of these is from + /// getProjectionPath. + NewProjectionPath(const NewProjectionPath &Other) = default; + + /// We only allow for moves of NewProjectionPath since we only want them to be + /// able to be constructed by calling our factory method. + NewProjectionPath(NewProjectionPath &&O) { + BaseType = O.BaseType; + Path = O.Path; + O.BaseType = SILType(); + O.Path.clear(); + } + + NewProjectionPath &operator=(NewProjectionPath &&O) { + BaseType = O.BaseType; + Path = O.Path; + O.BaseType = SILType(); + O.Path.clear(); + return *this; + } + + /// Create a new projection path from the SILValue Start to End. Returns + /// Nothing::None if there is no such path. + /// + /// *NOTE* This method allows for transitions from object types to address + /// types via ref_element_addr. If Start is an address type though, End will + /// always also be an address type. + static Optional getProjectionPath(SILValue Start, + SILValue End); + + /// Treating a projection path as an ordered set, if RHS is a prefix of LHS, + /// return the projection path with that prefix removed. + /// + /// An example of this transformation would be: + /// + /// LHS = [A, B, C, D, E], RHS = [A, B, C] => Result = [D, E] + static Optional + removePrefix(const NewProjectionPath &Path, const NewProjectionPath &Prefix); + + /// Given the SILType Base, expand every leaf nodes in the type tree. + /// Include the intermediate nodes if OnlyLeafNode is false. + static void + expandTypeIntoLeafProjectionPaths(SILType BaseType, SILModule *Mod, + llvm::SmallVectorImpl &P, + bool OnlyLeafNode); + + /// Returns true if the two paths have a non-empty symmetric + /// difference. + /// + /// This means that the two objects have the same base but access different + /// fields of the base object. + bool hasNonEmptySymmetricDifference(const NewProjectionPath &RHS) const; + + /// Compute the subsequence relation in between LHS and RHS which tells the + /// user whether or not the two sequences are unrelated, equal, or if one is a + /// subsequence of the other. + SubSeqRelation_t computeSubSeqRelation(const NewProjectionPath &RHS) const; + + /// Returns true if this is a projection path that takes an address base type + /// to an address derived type. + bool isAddressProjectionPath() const; + + /// Returns true if this is a projection path that takes an object base type + /// to an object derived type. + bool isObjectProjectionPath() const; + + /// Find all object projection paths from I that matches this projection + /// path. Return the tails of each extract path in T. + bool + findMatchingObjectProjectionPaths(SILInstruction *I, + SmallVectorImpl &T) const; + + /// If this is an address projection path and \p Base is a SILValue with the + /// object version of said type, use \p B and \p Loc to recreate the stored + /// address projection path as an object projection path from \p Base. Return + /// the SILValue at the end of the path. + SILValue createObjectProjections(SILBuilder &B, SILLocation Loc, + SILValue Base); + + /// Pushes an element to the path. + void push_back(const NewProjection &Proj) { Path.push_back(Proj); } + + /// Removes the last element from the path. + void pop_back() { Path.pop_back(); } + + /// Returns the last element of the path. + const NewProjection &back() const { return Path.back(); } + + /// Returns true if LHS and RHS have all the same projections in the same + /// order. + bool operator==(const NewProjectionPath &RHS) const { + return computeSubSeqRelation(RHS) == SubSeqRelation_t::Equal; + } + + bool operator!=(const NewProjectionPath &RHS) const { + return !(*this == RHS); + } + + /// Returns the base type of the ProjectionPath. + SILType getBaseType() const { return BaseType; } + + /// Returns the most derived type of the projection path. + SILType getMostDerivedType(SILModule &M) const { + if (Path.empty()) + return getBaseType(); + return getDerivedType(Path.size(), M); + } + + /// Returns the ith derived type of the path. This is zero indexed with 0 + /// being the base type and n consisting of applying the up to n projections + /// to the base type. + SILType getDerivedType(unsigned i, SILModule &M) const { + assert(i <= Path.size()); + SILType IterTy = getBaseType(); + if (i == 0) + return IterTy; + for (unsigned j : range(i)) { + auto &Proj = Path[j]; + IterTy = Proj.getType(IterTy, M); + } + return IterTy; + } + + /// Append the projection \p P onto this. + NewProjectionPath &append(const NewProjection &P) { + push_back(P); + return *this; + } + + /// Append the projections in \p Other onto this. + NewProjectionPath &append(const NewProjectionPath &Other) { + for (auto &X : Other.Path) { + push_back(X); + } + return *this; + } + + /// Returns true if the contained projection path is empty. + bool empty() const { return Path.empty(); } + + /// Returns the number of path elements in the given projection path. + unsigned size() const { return Path.size(); } + + using iterator = PathTy::iterator; + using const_iterator = PathTy::const_iterator; + using reverse_iterator = PathTy::reverse_iterator; + using const_reverse_iterator = PathTy::const_reverse_iterator; + + iterator begin() { return Path.begin(); } + iterator end() { return Path.end(); } + const_iterator begin() const { return Path.begin(); } + const_iterator end() const { return Path.end(); } + + reverse_iterator rbegin() { return Path.rbegin(); } + reverse_iterator rend() { return Path.rend(); } + const_reverse_iterator rbegin() const { return Path.rbegin(); } + const_reverse_iterator rend() const { return Path.rend(); } + + void verify(SILModule &M); + + raw_ostream &print(raw_ostream &OS, SILModule &M); + raw_ostream &printProjections(raw_ostream &OS, SILModule &M); + void dump(SILModule &M); + void dumpProjections(SILModule &M); +}; + +//===----------------------------------------------------------------------===// +// Projection +//===----------------------------------------------------------------------===// + +enum class ProjectionKind : unsigned { Struct, Tuple, Index, @@ -195,6 +732,22 @@ class Projection { } } + /// Helper method that returns isAddrProjection(I->getKind()); + static bool isIndexProjection(SILValue V) { + switch (V->getKind()) { + case ValueKind::IndexAddrInst: { + unsigned Scalar; + return getIntegerIndex(cast(V)->getIndex(), Scalar); + } + case ValueKind::StructElementAddrInst: + case ValueKind::TupleElementAddrInst: + case ValueKind::RefElementAddrInst: + case ValueKind::UncheckedTakeEnumDataAddrInst: + default: + return false; + } + } + /// Helper method that returns isValueProjection(I->getKind()); static bool isValueProjection(SILValue V) { return isValueProjection(V->getKind()); @@ -343,27 +896,6 @@ class Projection { explicit Projection(UncheckedEnumDataInst *UEDAI); }; -enum class SubSeqRelation_t : uint8_t { - Unrelated = 0, - LHSStrictSubSeqOfRHS = 1, - RHSStrictSubSeqOfLHS = 2, - Equal = 3 -}; - -/// Returns true if Seq is either LHSStrictSubSeqOfRHS or -/// RHSStrictSubSeqOfLHS. Returns false if Seq is one of either Equal or -/// Unrelated. -inline bool isStrictSubSeqRelation(SubSeqRelation_t Seq) { - switch (Seq) { - case SubSeqRelation_t::Unrelated: - case SubSeqRelation_t::Equal: - return false; - case SubSeqRelation_t::LHSStrictSubSeqOfRHS: - case SubSeqRelation_t::RHSStrictSubSeqOfLHS: - return true; - } -} - /// A "path" of projections abstracting either value or aggregate projections /// upon a value. /// @@ -394,7 +926,7 @@ class ProjectionPath { /// We only allow for moves of ProjectionPath since we only want them to be /// able to be constructed by calling our factory method or by going through /// the append function. - ProjectionPath(ProjectionPath &&Other) : Path(Other.Path) {} + ProjectionPath(ProjectionPath &&Other) : Path(std::move(Other.Path)) {} /// Append the projection P onto this. ProjectionPath &append(const Projection &P) { @@ -411,8 +943,7 @@ class ProjectionPath { } ProjectionPath &operator=(ProjectionPath &&O) { - *this = std::move(O); - O.Path.clear(); + std::swap(Path, O.Path); return *this; } @@ -429,11 +960,21 @@ class ProjectionPath { subtractPaths(const ProjectionPath &LHS, const ProjectionPath &RHS); /// Given the SILType Base, expand every leaf nodes in the type tree. - /// Include the intermediate nodes if OnlyLeafNode is false. + /// + /// NOTE: this function returns a single empty projection path if the BaseType + /// is a leaf node in the type tree. static void expandTypeIntoLeafProjectionPaths(SILType BaseType, SILModule *Mod, - ProjectionPathList &P, - bool OnlyLeafNode); + ProjectionPathList &P); + + /// Given the SILType Base, expand every intermediate and leaf nodes in the + /// type tree. + /// + /// NOTE: this function returns a single empty projection path if the BaseType + /// is a leaf node in the type tree. + static void expandTypeIntoNodeProjectionPaths(SILType BaseType, + SILModule *Mod, + ProjectionPathList &P); /// Returns true if the two paths have a non-empty symmetric difference. /// @@ -513,7 +1054,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Projection &P) { // Print the projection type first. OS << "Address Projection Type: "; - OS << P.getType() << "\n"; + OS << P.getType().getAddressType() << "\n"; if (P.isNominalKind()) { OS << "Field Type: "; P.getDecl()->print(OS); @@ -615,11 +1156,11 @@ class ProjectionTreeNode { } bool isRoot() const { - // Root does not have a parent. So if we have a parent, we can not be root. + // Root does not have a parent. So if we have a parent, we cannot be root. if (Parent.hasValue()) { assert(Proj.hasValue() && "If parent is not none, then P should be not " "none"); - assert(Index != RootIndex && "If parent is not none, we can not be root"); + assert(Index != RootIndex && "If parent is not none, we cannot be root"); return false; } else { assert(!Proj.hasValue() && "If parent is none, then P should be none"); @@ -789,7 +1330,7 @@ class ProjectionTree { "Should only create root when ProjectionTreeNodes is empty"); auto *Node = new (Allocator) ProjectionTreeNode(BaseTy); ProjectionTreeNodes.push_back(Node); - } + } ProjectionTreeNode *createChild(ProjectionTreeNode *Parent, SILType BaseTy, diff --git a/include/swift/SIL/SILAllocated.h b/include/swift/SIL/SILAllocated.h index ca22106a371ba..6f69e7c8ef3ad 100644 --- a/include/swift/SIL/SILAllocated.h +++ b/include/swift/SIL/SILAllocated.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILArgument.h b/include/swift/SIL/SILArgument.h index 76eb832465fad..4952c41e0016d 100644 --- a/include/swift/SIL/SILArgument.h +++ b/include/swift/SIL/SILArgument.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILBasicBlock.h b/include/swift/SIL/SILBasicBlock.h index 9e51b4fbe3dd8..7640b134b822a 100644 --- a/include/swift/SIL/SILBasicBlock.h +++ b/include/swift/SIL/SILBasicBlock.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,6 +17,7 @@ #ifndef SWIFT_SIL_BASICBLOCK_H #define SWIFT_SIL_BASICBLOCK_H +#include "swift/Basic/Range.h" #include "swift/SIL/SILInstruction.h" namespace llvm { @@ -30,6 +31,7 @@ class SILArgument; class SILBasicBlock : public llvm::ilist_node, public SILAllocated { friend class SILSuccessor; + friend class SILFunction; public: using InstListType = llvm::iplist; private: @@ -167,7 +169,7 @@ public llvm::ilist_node, public SILAllocated { SILArgument *replaceBBArg(unsigned i, SILType Ty, const ValueDecl *D=nullptr); /// Erase a specific argument from the arg list. - void eraseBBArg(int Index) { BBArgList.erase(BBArgList.begin() + Index); } + void eraseBBArg(int Index); /// Allocate a new argument of type \p Ty and append it to the argument /// list. Optionally you can pass in a value decl parameter. @@ -233,10 +235,31 @@ public llvm::ilist_node, public SILAllocated { /// \brief Returns true if \p BB is a successor of this block. bool isSuccessor(SILBasicBlock *BB) const { - for (auto &Succ : getSuccessors()) - if (Succ.getBB() == BB) - return true; - return false; + auto Range = getSuccessorBlocks(); + return any_of(Range, [&BB](const SILBasicBlock *SuccBB) -> bool { + return BB == SuccBB; + }); + } + + using SuccessorBlockListTy = + TransformRange>; + using ConstSuccessorBlockListTy = + TransformRange>; + + /// Return the range of SILBasicBlocks that are successors of this block. + SuccessorBlockListTy getSuccessorBlocks() { + using FuncTy = std::function; + FuncTy F(&SILSuccessor::getBB); + return makeTransformRange(getSuccessors(), F); + } + + /// Return the range of SILBasicBlocks that are successors of this block. + ConstSuccessorBlockListTy getSuccessorBlocks() const { + using FuncTy = std::function; + FuncTy F(&SILSuccessor::getBB); + return makeTransformRange(getSuccessors(), F); } using pred_iterator = SILSuccessorIterator; @@ -249,6 +272,12 @@ public llvm::ilist_node, public SILAllocated { return {pred_begin(), pred_end() }; } + bool isPredecessor(SILBasicBlock *BB) const { + return any_of(getPreds(), [&BB](const SILBasicBlock *PredBB) -> bool { + return BB == PredBB; + }); + } + SILBasicBlock *getSinglePredecessor() { if (pred_empty() || std::next(pred_begin()) != pred_end()) return nullptr; diff --git a/include/swift/SIL/SILBuilder.h b/include/swift/SIL/SILBuilder.h index 67f1cd0079f7f..4898bb6f9ed51 100644 --- a/include/swift/SIL/SILBuilder.h +++ b/include/swift/SIL/SILBuilder.h @@ -1,8 +1,8 @@ -//===--- SILBuilder.h - Class for creating SIL Constructs --------*- C++ -*-==// +//===--- SILBuilder.h - Class for creating SIL Constructs -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -221,10 +221,10 @@ class SILBuilder { //===--------------------------------------------------------------------===// AllocStackInst *createAllocStack(SILLocation Loc, SILType elementType, - unsigned ArgNo = 0) { + SILDebugVariable Var = SILDebugVariable()) { Loc.markAsPrologue(); - return insert(new (F.getModule()) AllocStackInst( - createSILDebugLocation(Loc), elementType, F, ArgNo)); + return insert(AllocStackInst::create(createSILDebugLocation(Loc), + elementType, F, Var)); } AllocRefInst *createAllocRef(SILLocation Loc, SILType elementType, bool objc, @@ -252,10 +252,10 @@ class SILBuilder { } AllocBoxInst *createAllocBox(SILLocation Loc, SILType ElementType, - unsigned ArgNo = 0) { + SILDebugVariable Var = SILDebugVariable()) { Loc.markAsPrologue(); - return insert(new (F.getModule()) AllocBoxInst(createSILDebugLocation(Loc), - ElementType, F, ArgNo)); + return insert( + AllocBoxInst::create(createSILDebugLocation(Loc), ElementType, F, Var)); } AllocExistentialBoxInst * @@ -436,14 +436,15 @@ class SILBuilder { } DebugValueInst *createDebugValue(SILLocation Loc, SILValue src, - unsigned ArgNo = 0) { - return insert(new (F.getModule()) - DebugValueInst(createSILDebugLocation(Loc), src, ArgNo)); + SILDebugVariable Var = SILDebugVariable()) { + return insert(DebugValueInst::create(createSILDebugLocation(Loc), src, + F.getModule(), Var)); } - DebugValueAddrInst *createDebugValueAddr(SILLocation Loc, SILValue src, - unsigned ArgNo = 0) { - return insert(new (F.getModule()) DebugValueAddrInst( - createSILDebugLocation(Loc), src, ArgNo)); + DebugValueAddrInst * + createDebugValueAddr(SILLocation Loc, SILValue src, + SILDebugVariable Var = SILDebugVariable()) { + return insert(DebugValueAddrInst::create(createSILDebugLocation(Loc), src, + F.getModule(), Var)); } LoadWeakInst *createLoadWeak(SILLocation Loc, SILValue src, IsTake_t isTake) { @@ -457,6 +458,20 @@ class SILBuilder { value, dest, isInit)); } + LoadUnownedInst *createLoadUnowned(SILLocation loc, SILValue src, + IsTake_t isTake) { + return insert(new (F.getModule()) + LoadUnownedInst(createSILDebugLocation(loc), src, isTake)); + } + + StoreUnownedInst *createStoreUnowned(SILLocation loc, SILValue value, + SILValue dest, + IsInitialization_t isInit) { + return insert(new (F.getModule()) + StoreUnownedInst(createSILDebugLocation(loc), + value, dest, isInit)); + } + CopyAddrInst *createCopyAddr(SILLocation Loc, SILValue srcAddr, SILValue destAddr, IsTake_t isTake, IsInitialization_t isInitialize) { @@ -996,11 +1011,6 @@ class SILBuilder { return insert(new (F.getModule()) StrongReleaseInst(createSILDebugLocation(Loc), Operand)); } - StrongRetainAutoreleasedInst * - createStrongRetainAutoreleased(SILLocation Loc, SILValue Operand) { - return insert(new (F.getModule()) StrongRetainAutoreleasedInst( - createSILDebugLocation(Loc), Operand)); - } StrongPinInst *createStrongPin(SILLocation Loc, SILValue Operand) { return insert(new (F.getModule()) StrongPinInst(createSILDebugLocation(Loc), Operand)); @@ -1170,12 +1180,6 @@ class SILBuilder { createSILDebugLocation(Loc), ReturnValue)); } - AutoreleaseReturnInst *createAutoreleaseReturn(SILLocation Loc, - SILValue ReturnValue) { - return insertTerminator(new (F.getModule()) AutoreleaseReturnInst( - createSILDebugLocation(Loc), ReturnValue)); - } - ThrowInst *createThrow(SILLocation Loc, SILValue errorValue) { return insertTerminator( new (F.getModule()) ThrowInst(createSILDebugLocation(Loc), errorValue)); diff --git a/include/swift/SIL/SILCloner.h b/include/swift/SIL/SILCloner.h index a7534abba8a1e..001a3d2f82459 100644 --- a/include/swift/SIL/SILCloner.h +++ b/include/swift/SIL/SILCloner.h @@ -1,8 +1,8 @@ -//===--- SILCloner.h - Defines the SILCloner class ---------------*- C++ -*-==// +//===--- SILCloner.h - Defines the SILCloner class --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -29,7 +29,7 @@ namespace swift { /// operations requiring cloning (while possibly modifying, at the same time) /// instruction sequences. /// -/// By default, this visitor will not do anything useful when when called on a +/// By default, this visitor will not do anything useful when called on a /// basic block, or function; subclasses that want to handle those should /// implement the appropriate visit functions and/or provide other entry points. template @@ -348,7 +348,7 @@ void SILCloner::postProcess(SILInstruction *Orig, SILInstruction *Cloned) { assert((Orig->getDebugScope() ? Cloned->getDebugScope()!=nullptr : true) && - "cloned function droped debug scope"); + "cloned function dropped debug scope"); InstructionMap.insert(std::make_pair(Orig, Cloned)); } @@ -366,7 +366,7 @@ SILCloner::visitSILBasicBlock(SILBasicBlock* BB) { // Iterate over successors to do the depth-first search. for (auto &Succ : BB->getSuccessors()) { auto BBI = BBMap.find(Succ); - // Only visit a successor that has not already been visisted. + // Only visit a successor that has not already been visited. if (BBI == BBMap.end()) { // Map the successor to a new BB. auto MappedBB = new (F.getModule()) SILBasicBlock(&F); @@ -400,7 +400,7 @@ SILCloner::cleanUp(SILFunction *F) { // NOTE: It is unfortunate that it essentially duplicates // the code from sil-combine, but doing so allows for // avoiding any cross-layer invocations between SIL and - // SILPasses layers. + // SILOptimizer layers. for (auto *BB : BlocksWithUnreachables) { for (auto &I : *BB) { @@ -670,7 +670,7 @@ SILCloner::visitDebugValueInst(DebugValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDebugValue( Inst->getLoc(), getOpValue(Inst->getOperand()), - Inst->getVarInfo().getArgNo())); + Inst->getVarInfo())); } template void @@ -684,12 +684,32 @@ SILCloner::visitDebugValueAddrInst(DebugValueAddrInst *Inst) { // Do not remap the location for a debug Instruction. SILValue OpValue = getOpValue(Inst->getOperand()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); - doPostProcess( - Inst, getBuilder().createDebugValueAddr(Inst->getLoc(), OpValue, - Inst->getVarInfo().getArgNo())); + doPostProcess(Inst, getBuilder().createDebugValueAddr( + Inst->getLoc(), OpValue, Inst->getVarInfo())); } +template +void +SILCloner::visitLoadUnownedInst(LoadUnownedInst *Inst) { + getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); + doPostProcess(Inst, + getBuilder().createLoadUnowned(getOpLocation(Inst->getLoc()), + getOpValue(Inst->getOperand()), + Inst->isTake())); +} + +template +void +SILCloner::visitStoreUnownedInst(StoreUnownedInst *Inst) { + getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); + doPostProcess(Inst, + getBuilder().createStoreUnowned(getOpLocation(Inst->getLoc()), + getOpValue(Inst->getSrc()), + getOpValue(Inst->getDest()), + Inst->isInitializationOfDest())); +} + template void SILCloner::visitLoadWeakInst(LoadWeakInst *Inst) { @@ -1411,17 +1431,6 @@ SILCloner::visitStrongRetainInst(StrongRetainInst *Inst) { getOpValue(Inst->getOperand()))); } -template -void -SILCloner:: -visitStrongRetainAutoreleasedInst(StrongRetainAutoreleasedInst *Inst) { - SILValue OpValue = getOpValue(Inst->getOperand()); - getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); - doPostProcess(Inst, - getBuilder().createStrongRetainAutoreleased(getOpLocation(Inst->getLoc()), - OpValue)); -} - template void SILCloner::visitFixLifetimeInst(FixLifetimeInst *Inst) { @@ -1646,15 +1655,6 @@ SILCloner::visitReturnInst(ReturnInst *Inst) { getOpValue(Inst->getOperand()))); } -template -void -SILCloner::visitAutoreleaseReturnInst(AutoreleaseReturnInst *Inst) { - getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); - doPostProcess(Inst, - getBuilder().createAutoreleaseReturn(getOpLocation(Inst->getLoc()), - getOpValue(Inst->getOperand()))); -} - template void SILCloner::visitThrowInst(ThrowInst *Inst) { diff --git a/include/swift/SIL/SILCoverageMap.h b/include/swift/SIL/SILCoverageMap.h index d635d83e7bb13..44dec8a870976 100644 --- a/include/swift/SIL/SILCoverageMap.h +++ b/include/swift/SIL/SILCoverageMap.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILDebugScope.h b/include/swift/SIL/SILDebugScope.h index ad7635d96f17d..24f9299d4d9f0 100644 --- a/include/swift/SIL/SILDebugScope.h +++ b/include/swift/SIL/SILDebugScope.h @@ -1,8 +1,8 @@ -//===--- SILDebugScope.h - DebugScopes for SIL code -----------*- C++ -*-===// +//===--- SILDebugScope.h - DebugScopes for SIL code -------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILDebuggerClient.h b/include/swift/SIL/SILDebuggerClient.h index d7ac89158d2d7..e691be768cc82 100644 --- a/include/swift/SIL/SILDebuggerClient.h +++ b/include/swift/SIL/SILDebuggerClient.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILDeclRef.h b/include/swift/SIL/SILDeclRef.h index f34e2166748de..5f352d3342406 100644 --- a/include/swift/SIL/SILDeclRef.h +++ b/include/swift/SIL/SILDeclRef.h @@ -1,8 +1,8 @@ -//===--- SILDeclRef.h - Defines the SILDeclRef struct ---------*- C++ -*---===// +//===--- SILDeclRef.h - Defines the SILDeclRef struct -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -45,6 +45,23 @@ namespace swift { class SILLocation; class AnyFunctionRef; +/// How a method is dispatched. +enum class MethodDispatch { + // The method implementation can be referenced statically. + Static, + // The method implementation uses class_method dispatch. + Class, +}; + +/// Get the method dispatch mechanism for a method. +MethodDispatch getMethodDispatch(AbstractFunctionDecl *method); + +/// True if calling the given method or property should use ObjC dispatch. +bool requiresObjCDispatch(ValueDecl *vd); + +/// True if the entry point is natively foreign. +bool requiresForeignToNativeThunk(ValueDecl *vd); + enum ForDefinition_t : bool { NotForDefinition = false, ForDefinition = true @@ -217,8 +234,7 @@ struct SILDeclRef { /// /// If 'prefix' is non-empty, it will be used in place of the standard '_T' /// prefix. - llvm::StringRef mangle(llvm::SmallVectorImpl &buffer, - StringRef prefix = {}) const; + std::string mangle(StringRef prefix = {}) const; /// True if the SILDeclRef references a function. bool isFunc() const { @@ -253,7 +269,7 @@ struct SILDeclRef { /// \brief True if the function has __always inline attribute. bool isAlwaysInline() const; - /// \return True if the function has a effects attribute. + /// \return True if the function has an effects attribute. bool hasEffectsAttribute() const; /// \return the effects kind of the function. @@ -341,7 +357,11 @@ struct SILDeclRef { /// Return a SILDeclRef to the declaration whose vtable entry this declaration /// overrides. This may be different from "getOverridden" because some /// declarations do not always have vtable entries. - SILDeclRef getOverriddenVTableEntry() const; + SILDeclRef getNextOverriddenVTableEntry() const; + + /// Return a SILDeclRef referring to the ultimate base class's declaration, + /// which must be used with getConstantOverrideInfo. + SILDeclRef getBaseOverriddenVTableEntry() const; /// True if the referenced entity is some kind of thunk. bool isThunk() const; diff --git a/include/swift/SIL/SILExternalSource.h b/include/swift/SIL/SILExternalSource.h deleted file mode 100644 index f8780e4c6a1ce..0000000000000 --- a/include/swift/SIL/SILExternalSource.h +++ /dev/null @@ -1,42 +0,0 @@ -//===--- SILExternalSource.h - On-demand generation of SIL ------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// -// This file defines the abstract SILExternalSource class. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SILEXTERNALSOURCE_H -#define SWIFT_SILEXTERNALSOURCE_H - -namespace swift { - -class SILFunction; - -class SILExternalSource { -public: - SILExternalSource() { } - virtual ~SILExternalSource() = default; - - /// SILExternalSource gets called for each external function - /// that the SIL linker would try to load SIL for. In particular - /// this means transparent functions. - /// - /// \param callee is the (usually empty) called function. - virtual SILFunction *lookupSILFunction(SILFunction *callee) = 0; - -private: - virtual void anchor(); -}; - -} // namespace swift - -#endif diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h index 6dbc4493709ae..1fa36869dabf2 100644 --- a/include/swift/SIL/SILFunction.h +++ b/include/swift/SIL/SILFunction.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -102,13 +102,13 @@ class SILFunction /// functions in the stdlib. unsigned Fragile : 1; - /// Specifies if this function is a thunk or an reabstraction thunk. + /// Specifies if this function is a thunk or a reabstraction thunk. /// /// The inliner uses this information to avoid inlining (non-trivial) /// functions into the thunk. unsigned Thunk : 2; - /// The visiblity of the parent class, if this is a method which is contained + /// The visibility of the parent class, if this is a method which is contained /// in the vtable of that class. unsigned ClassVisibility : 2; @@ -133,12 +133,14 @@ class SILFunction /// It does not include references from debug scopes. unsigned RefCount = 0; - /// The function's semantics attribute. - std::string SemanticsAttr; + /// The function's set of semantics attributes. + /// + /// TODO: Why is this using a std::string? Why don't we use StringRef. + llvm::SmallVector SemanticsAttrSet; /// The function's effects attribute. - EffectsKind EK; - + EffectsKind EffectsKindAttr; + /// True if this function is inlined at least once. This means that the /// debug info keeps a pointer to this function. bool Inlined = false; @@ -165,7 +167,6 @@ class SILFunction const SILDebugScope *debugScope, DeclContext *DC); -public: static SILFunction *create(SILModule &M, SILLinkage linkage, StringRef name, CanSILFunctionType loweredType, GenericParamList *contextGenericParams, @@ -176,10 +177,13 @@ class SILFunction IsThunk_t isThunk = IsNotThunk, ClassVisibility_t classVisibility = NotRelevant, Inline_t inlineStrategy = InlineDefault, - EffectsKind EK = EffectsKind::Unspecified, + EffectsKind EffectsKindAttr = + EffectsKind::Unspecified, SILFunction *InsertBefore = nullptr, const SILDebugScope *DebugScope = nullptr, DeclContext *DC = nullptr); + +public: ~SILFunction(); SILModule &getModule() const { return Module; } @@ -280,7 +284,7 @@ class SILFunction /// Return the mangled name of this SILFunction. StringRef getName() const { return Name; } - /// A convencience function which checks if the function has a specific + /// A convenience function which checks if the function has a specific /// \p name. It is equivalent to getName() == Name, but as it is not /// inlined it can be called from the debugger. bool hasName(const char *Name) const; @@ -299,7 +303,7 @@ class SILFunction /// Get's the effective linkage which is used to derive the llvm linkage. /// Usually this is the same as getLinkage(), except in one case: if this - /// function is a method in a class which has higher visiblity than the + /// function is a method in a class which has higher visibility than the /// method itself, the function can be referenced from vtables of derived /// classes in other compilation units. SILLinkage getEffectiveSymbolLinkage() const { @@ -343,20 +347,40 @@ class SILFunction /// \returns True if the function is marked with the @_semantics attribute /// and has special semantics that the optimizer can use to optimize the /// function. - bool hasDefinedSemantics() const { - return SemanticsAttr.length() > 0; + bool hasSemanticsAttrs() const { return SemanticsAttrSet.size() > 0; } + + /// \returns True if the function has a semantic attribute that starts with a + /// specific string. + /// + /// TODO: This needs a better name. + bool hasSemanticsAttrsThatStartsWith(StringRef S) { + return count_if(getSemanticsAttrs(), [&S](const std::string &Attr) -> bool { + return StringRef(Attr).startswith(S); + }); } /// \returns the semantics tag that describes this function. - StringRef getSemanticsString() const { - assert(hasDefinedSemantics() && - "Accessing a function with no semantics tag"); - return SemanticsAttr; - } + ArrayRef getSemanticsAttrs() const { return SemanticsAttrSet; } /// \returns True if the function has the semantics flag \p Value; - bool hasSemanticsString(StringRef Value) const { - return SemanticsAttr == Value; + bool hasSemanticsAttr(StringRef Value) const { + return std::count(SemanticsAttrSet.begin(), SemanticsAttrSet.end(), Value); + } + + /// Add the given semantics attribute to the attr list set. + void addSemanticsAttr(StringRef Ref) { + if (hasSemanticsAttr(Ref)) + return; + SemanticsAttrSet.push_back(Ref); + std::sort(SemanticsAttrSet.begin(), SemanticsAttrSet.end()); + } + + /// Remove the semantics + void removeSemanticsAttr(StringRef Ref) { + auto Iter = + std::remove(SemanticsAttrSet.begin(), SemanticsAttrSet.end(), Ref); + SemanticsAttrSet.erase(Iter); + std::sort(SemanticsAttrSet.begin(), SemanticsAttrSet.end()); } /// \returns True if the function is optimizable (i.e. not marked as no-opt), @@ -411,13 +435,17 @@ class SILFunction void setInlineStrategy(Inline_t inStr) { InlineStrategy = inStr; } /// \return the function side effects information. - EffectsKind getEffectsKind() const { return EK; } + EffectsKind getEffectsKind() const { return EffectsKindAttr; } /// \return True if the function is annotated with the @effects attribute. - bool hasEffectsKind() const { return EK != EffectsKind::Unspecified; } + bool hasEffectsKind() const { + return EffectsKindAttr != EffectsKind::Unspecified; + } /// \brief Set the function side effect information. - void setEffectsKind(EffectsKind E) { EK = E; } + void setEffectsKind(EffectsKind E) { + EffectsKindAttr = E; + } /// Get this function's global_init attribute. /// @@ -434,9 +462,6 @@ class SILFunction bool isGlobalInit() const { return GlobalInitFlag; } void setGlobalInit(bool isGI) { GlobalInitFlag = isGI; } - StringRef getSemanticsAttr() const { return SemanticsAttr; } - void setSemanticsAttr(StringRef attr) { SemanticsAttr = attr; } - bool isKeepAsPublic() const { return KeepAsPublic; } void setKeepAsPublic(bool keep) { KeepAsPublic = keep; } @@ -516,7 +541,6 @@ class SILFunction return std::find_if(begin(), end(), [](const SILBasicBlock &BB) -> bool { const TermInst *TI = BB.getTerminator(); - // TODO: We autorelease_return should also be handled here. return isa(TI); }); } @@ -546,17 +570,17 @@ class SILFunction //===--------------------------------------------------------------------===// SILArgument *getArgument(unsigned i) { - assert(!empty() && "Can not get argument of a function without a body"); + assert(!empty() && "Cannot get argument of a function without a body"); return begin()->getBBArg(i); } const SILArgument *getArgument(unsigned i) const { - assert(!empty() && "Can not get argument of a function without a body"); + assert(!empty() && "Cannot get argument of a function without a body"); return begin()->getBBArg(i); } ArrayRef getArguments() const { - assert(!empty() && "Can not get arguments of a function without a body"); + assert(!empty() && "Cannot get arguments of a function without a body"); return begin()->getBBArgs(); } diff --git a/include/swift/SIL/SILGlobalVariable.h b/include/swift/SIL/SILGlobalVariable.h index 4a0f7f42d24e3..044b06937b6a7 100644 --- a/include/swift/SIL/SILGlobalVariable.h +++ b/include/swift/SIL/SILGlobalVariable.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h index b739e7b8d042b..bd2da8fbd64c9 100644 --- a/include/swift/SIL/SILInstruction.h +++ b/include/swift/SIL/SILInstruction.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -88,6 +88,13 @@ class SILInstruction : public ValueBase,public llvm::ilist_node{ : ValueBase(Kind, TypeList), ParentBB(0), Location(*DebugLoc) {} public: + /// Instructions should be allocated using a dedicated instruction allocation + /// function from the ContextTy. + template + void *operator new(size_t Bytes, const ContextTy &C, + size_t Alignment = alignof(ValueBase)) { + return C.allocateInst(Bytes, Alignment); + } enum class MemoryBehavior { None, @@ -168,8 +175,14 @@ class SILInstruction : public ValueBase,public llvm::ilist_node{ MemoryBehavior getMemoryBehavior() const; ReleasingBehavior getReleasingBehavior() const; + + /// Returns true if the instruction may release any object. bool mayRelease() const; + /// Returns true if the instruction may release or may read the reference + /// count of any object. + bool mayReleaseOrReadRefCount() const; + /// Can this instruction abort the program in some manner? bool mayTrap() const; @@ -269,6 +282,21 @@ class SILInstruction : public ValueBase,public llvm::ilist_node{ bool isTriviallyDuplicatable() const; }; +/// Returns the combined behavior of \p B1 and \p B2. +inline SILInstruction::MemoryBehavior +combineMemoryBehavior(SILInstruction::MemoryBehavior B1, + SILInstruction::MemoryBehavior B2) { + // Basically the combined behavior is the maximum of both operands. + auto Result = std::max(B1, B2); + + // With one exception: MayRead, MayWrite -> MayReadWrite. + if (Result == SILInstruction::MemoryBehavior::MayWrite && + (B1 == SILInstruction::MemoryBehavior::MayRead || + B2 == SILInstruction::MemoryBehavior::MayRead)) + return SILInstruction::MemoryBehavior::MayReadWrite; + return Result; +} + #ifndef NDEBUG /// Pretty-print the MemoryBehavior. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, @@ -328,13 +356,45 @@ class UnaryInstructionBase : public BASE { /// Holds common debug information about local variables and function /// arguments that are needed by DebugValueInst, DebugValueAddrInst, /// AllocStackInst, and AllocBoxInst. -class DebugVariable { +struct SILDebugVariable { + SILDebugVariable() : Constant(true), ArgNo(0) {} + SILDebugVariable(bool Constant, unsigned ArgNo) + : Constant(Constant), ArgNo(ArgNo) {} + SILDebugVariable(StringRef Name, bool Constant, unsigned ArgNo) + : Name(Name), Constant(Constant), ArgNo(ArgNo) {} + StringRef Name; + bool Constant; + unsigned ArgNo; +}; + +/// A DebugVariable where storage for the strings has been +/// tail-allocated following the parent SILInstruction. +class TailAllocatedDebugVariable { /// The source function argument position from left to right /// starting with 1 or 0 if this is a local variable. - unsigned char ArgNo; + unsigned ArgNo : 16; + /// When this is nonzero there is a tail-allocated string storing + /// variable name present. This typically only happens for + /// instructions that were created from parsing SIL assembler. + unsigned NameLength : 15; + bool Constant : 1; public: - DebugVariable(unsigned ArgNo) : ArgNo(ArgNo) {}; + TailAllocatedDebugVariable(SILDebugVariable DbgVar, char *buf); + unsigned getArgNo() const { return ArgNo; } + void setArgNo(unsigned N) { ArgNo = N; } + /// Returns the name of the source variable, if it is stored in the + /// instruction. + StringRef getName(const char *buf) const; + bool isLet() const { return Constant; } + + SILDebugVariable get(VarDecl *VD, const char *buf) const { + if (VD) + return {VD->getName().empty() ? "" : VD->getName().str(), VD->isLet(), + getArgNo()}; + else + return {getName(buf), isLet(), getArgNo()}; + } }; //===----------------------------------------------------------------------===// @@ -381,29 +441,34 @@ class StackPromotable { /// reference count) stack memory. The memory is provided uninitialized. class AllocStackInst : public AllocationInst { friend class SILBuilder; - DebugVariable VarInfo; + TailAllocatedDebugVariable VarInfo; AllocStackInst(SILDebugLocation *Loc, SILType elementType, SILFunction &F, - unsigned ArgNo); + SILDebugVariable Var); + static AllocStackInst *create(SILDebugLocation *Loc, SILType elementType, + SILFunction &F, SILDebugVariable Var); public: - /// getDecl - Return the underlying variable declaration associated with this + /// Return the underlying variable declaration associated with this /// allocation, or null if this is a temporary allocation. VarDecl *getDecl() const; - DebugVariable getVarInfo() const { return VarInfo; }; - void setArgNo(unsigned N) { VarInfo = DebugVariable(N); } + /// Return the debug variable information attached to this instruction. + SILDebugVariable getVarInfo() const { + return VarInfo.get(getDecl(), reinterpret_cast(this + 1)); + }; + void setArgNo(unsigned N) { VarInfo.setArgNo(N); } + /// getType() is ok since this is known to only have one type. + SILType getType(unsigned i = 0) const { return ValueBase::getType(i); } + /// getElementType - Get the type of the allocated memory (as opposed to the - /// (second) type of the instruction itself, which will be an address type). + /// type of the instruction itself, which will be an address type). SILType getElementType() const { - return getType(1).getObjectType(); + return getType().getObjectType(); } - SILValue getContainerResult() const { return SILValue(this, 0); } - SILValue getAddressResult() const { return SILValue(this, 1); } - ArrayRef getAllOperands() const { return {}; } MutableArrayRef getAllOperands() { return {}; } @@ -481,10 +546,12 @@ class AllocValueBufferInst : class AllocBoxInst : public AllocationInst { friend class SILBuilder; - DebugVariable VarInfo; + TailAllocatedDebugVariable VarInfo; AllocBoxInst(SILDebugLocation *DebugLoc, SILType ElementType, SILFunction &F, - unsigned ArgNo); + SILDebugVariable Var); + static AllocBoxInst *create(SILDebugLocation *Loc, SILType elementType, + SILFunction &F, SILDebugVariable Var); public: @@ -495,11 +562,14 @@ class AllocBoxInst : public AllocationInst { SILValue getContainerResult() const { return SILValue(this, 0); } SILValue getAddressResult() const { return SILValue(this, 1); } - /// getDecl - Return the underlying variable declaration associated with this + /// Return the underlying variable declaration associated with this /// allocation, or null if this is a temporary allocation. VarDecl *getDecl() const; - DebugVariable getVarInfo() const { return VarInfo; }; + /// Return the debug variable information attached to this instruction. + SILDebugVariable getVarInfo() const { + return VarInfo.get(getDecl(), reinterpret_cast(this + 1)); + }; ArrayRef getAllOperands() const { return {}; } MutableArrayRef getAllOperands() { return {}; } @@ -626,24 +696,24 @@ class ApplyInstBase : public Base { bool isNonThrowingApply() const { return NonThrowing; } public: - // The operand number of the first argument. + /// The operand number of the first argument. static unsigned getArgumentOperandNumber() { return 1; } SILValue getCallee() const { return Operands[Callee].get(); } - // Gets the referenced function if the callee is a function_ref instruction. + /// Gets the referenced function if the callee is a function_ref instruction. SILFunction *getCalleeFunction() const { if (auto *FRI = dyn_cast(getCallee())) return FRI->getReferencedFunction(); return nullptr; } - // Get the type of the callee without the applied substitutions. + /// Get the type of the callee without the applied substitutions. CanSILFunctionType getOrigCalleeType() const { return getCallee().getType().template castTo(); } - // Get the type of the callee with the applied substitutions. + /// Get the type of the callee with the applied substitutions. CanSILFunctionType getSubstCalleeType() const { return SubstCalleeType.castTo(); } @@ -709,7 +779,7 @@ class ApplyInstBase : public Base { /// Return the ith argument passed to this instruction. SILValue getArgument(unsigned i) const { return getArguments()[i]; } - // Set the ith argument of this instruction. + /// Set the ith argument of this instruction. void setArgument(unsigned i, SILValue V) { return getArgumentOperands()[i].set(V); } @@ -723,9 +793,9 @@ class ApplyInstBase : public Base { /// does it have the given semantics? bool doesApplyCalleeHaveSemantics(SILValue callee, StringRef semantics); -// The partial specialization of ApplyInstBase for full applications. -// Adds some methods relating to 'self' and to result types that don't -// make sense for partial applications. +/// The partial specialization of ApplyInstBase for full applications. +/// Adds some methods relating to 'self' and to result types that don't +/// make sense for partial applications. template class ApplyInstBase : public ApplyInstBase { @@ -752,7 +822,7 @@ class ApplyInstBase /// The hope is that this will prevent any future bugs from coming up related /// to this. /// - /// Self is always the last parameter, but self subtitutions are always + /// Self is always the last parameter, but self substitutions are always /// first. The reason to add this method is to wrap that dichotomy to reduce /// errors. /// @@ -858,7 +928,7 @@ class ApplyInst : public ApplyInstBase { return V->getKind() == ValueKind::ApplyInst; } - /// Returns true if the called function has an error result but is not actully + /// Returns true if the called function has an error result but is not actually /// throwing an error. bool isNonThrowing() const { return isNonThrowingApply(); @@ -1278,7 +1348,7 @@ class MarkUninitializedInst friend class SILBuilder; public: - // This enum captures what the mark_uninitialized instruction is designating. + /// This enum captures what the mark_uninitialized instruction is designating. enum Kind { /// Var designates the start of a normal variable live range. Var, @@ -1364,16 +1434,21 @@ class MarkFunctionEscapeInst : public SILInstruction { /// types). class DebugValueInst : public UnaryInstructionBase { friend class SILBuilder; - DebugVariable VarInfo; + TailAllocatedDebugVariable VarInfo; - DebugValueInst(SILDebugLocation *DebugLoc, SILValue Operand, unsigned ArgNo) - : UnaryInstructionBase(DebugLoc, Operand), VarInfo(ArgNo) {} + DebugValueInst(SILDebugLocation *DebugLoc, SILValue Operand, + SILDebugVariable Var); + static DebugValueInst *create(SILDebugLocation *DebugLoc, SILValue Operand, + SILModule &M, SILDebugVariable Var); public: - /// getDecl - Return the underlying variable declaration that this denotes, + /// Return the underlying variable declaration that this denotes, /// or null if we don't have one. VarDecl *getDecl() const; - DebugVariable getVarInfo() const { return VarInfo; } + /// Return the debug variable information attached to this instruction. + SILDebugVariable getVarInfo() const { + return VarInfo.get(getDecl(), reinterpret_cast(this + 1)); + } }; /// Define the start or update to a symbolic variable value (for address-only @@ -1381,27 +1456,28 @@ class DebugValueInst : public UnaryInstructionBase { class DebugValueAddrInst : public UnaryInstructionBase { friend class SILBuilder; - DebugVariable VarInfo; + TailAllocatedDebugVariable VarInfo; DebugValueAddrInst(SILDebugLocation *DebugLoc, SILValue Operand, - unsigned ArgNo) - : UnaryInstructionBase(DebugLoc, Operand), VarInfo(ArgNo) {} + SILDebugVariable Var); + static DebugValueAddrInst *create(SILDebugLocation *DebugLoc, + SILValue Operand, SILModule &M, + SILDebugVariable Var); public: - /// getDecl - Return the underlying variable declaration that this denotes, + /// Return the underlying variable declaration that this denotes, /// or null if we don't have one. VarDecl *getDecl() const; - DebugVariable getVarInfo() const { return VarInfo; } + /// Return the debug variable information attached to this instruction. + SILDebugVariable getVarInfo() const { + return VarInfo.get(getDecl(), reinterpret_cast(this + 1)); + }; }; - -/// Represents a load from a @weak memory location. -class LoadWeakInst - : public UnaryInstructionBase -{ - friend class SILBuilder; - +/// An abstract class representing a load from some kind of reference storage. +template +class LoadReferenceInstBase : public UnaryInstructionBase { static SILType getResultType(SILType operandTy) { assert(operandTy.isAddress() && "loading from non-address operand?"); auto refType = cast(operandTy.getSwiftRValueType()); @@ -1410,26 +1486,28 @@ class LoadWeakInst unsigned IsTake : 1; // FIXME: pack this somewhere - /// \param DebugLoc The location of the expression that caused the load. - /// \param lvalue The SILValue representing the address to - /// use for the load. - LoadWeakInst(SILDebugLocation *DebugLoc, SILValue lvalue, IsTake_t isTake) - : UnaryInstructionBase(DebugLoc, lvalue, getResultType(lvalue.getType())), - IsTake(unsigned(isTake)) {} +protected: + LoadReferenceInstBase(SILDebugLocation *loc, SILValue lvalue, IsTake_t isTake) + : UnaryInstructionBase(loc, lvalue, getResultType(lvalue.getType())), + IsTake(unsigned(isTake)) { + } public: IsTake_t isTake() const { return IsTake_t(IsTake); } }; -/// Represents a store to a @weak memory location. -class StoreWeakInst : public SILInstruction { - friend class SILBuilder; - +/// An abstract class representing a store to some kind of reference storage. +template +class StoreReferenceInstBase : public SILInstruction { enum { Src, Dest }; FixedOperandList<2> Operands; unsigned IsInitializationOfDest : 1; // FIXME: pack this somewhere - StoreWeakInst(SILDebugLocation *DebugLoc, SILValue src, SILValue dest, - IsInitialization_t isInit); +protected: + StoreReferenceInstBase(SILDebugLocation *loc, SILValue src, SILValue dest, + IsInitialization_t isInit) + : SILInstruction(K, loc), Operands(this, src, dest), + IsInitializationOfDest(unsigned(isInit)) { + } public: SILValue getSrc() const { return Operands[Src].get(); } @@ -1446,10 +1524,64 @@ class StoreWeakInst : public SILInstruction { MutableArrayRef getAllOperands() { return Operands.asArray(); } static bool classof(const ValueBase *V) { - return V->getKind() == ValueKind::StoreWeakInst; + return V->getKind() == K; } }; +/// Represents a load from a @weak memory location. +class LoadWeakInst + : public LoadReferenceInstBase +{ + friend class SILBuilder; + + /// \param loc The location of the expression that caused the load. + /// \param lvalue The SILValue representing the address to + /// use for the load. + LoadWeakInst(SILDebugLocation *loc, SILValue lvalue, IsTake_t isTake) + : LoadReferenceInstBase(loc, lvalue, isTake) {} +}; + +/// Represents a store to a @weak memory location. +class StoreWeakInst + : public StoreReferenceInstBase +{ + friend class SILBuilder; + + StoreWeakInst(SILDebugLocation *loc, SILValue src, SILValue dest, + IsInitialization_t isInit) + : StoreReferenceInstBase(loc, src, dest, isInit) {} +}; + +/// Represents a load from an @unowned memory location. +/// +/// This is only required for address-only unowned references; for loadable +/// unowned references, it's better to use a load and a strong_retain_unowned. +class LoadUnownedInst + : public LoadReferenceInstBase +{ + friend class SILBuilder; + + /// \param loc The location of the expression that caused the load. + /// \param lvalue The SILValue representing the address to + /// use for the load. + LoadUnownedInst(SILDebugLocation *loc, SILValue lvalue, IsTake_t isTake) + : LoadReferenceInstBase(loc, lvalue, isTake) {} +}; + +/// Represents a store to an @unowned memory location. +/// +/// This is only required for address-only unowned references; for loadable +/// unowned references, it's better to use a ref_to_unowned and a store. +class StoreUnownedInst + : public StoreReferenceInstBase +{ + friend class SILBuilder; + + StoreUnownedInst(SILDebugLocation *loc, SILValue src, SILValue dest, + IsInitialization_t isInit) + : StoreReferenceInstBase(loc, src, dest, isInit) {} +}; + /// CopyAddrInst - Represents a copy from one memory location to another. This /// is similar to: /// %1 = load %src @@ -2169,7 +2301,7 @@ class TupleInst : public SILInstruction { return Operands.getDynamicValuesAsArray(); } - // Return the i'th value referenced by this TupleInst. + /// Return the i'th value referenced by this TupleInst. SILValue getElement(unsigned i) const { return getElements()[i]; } @@ -2373,8 +2505,8 @@ class SelectInstBase : public SILInstruction { unsigned NumCases : 31; unsigned HasDefault : 1; - // The first operand is the operand of select_xxx instruction; - // the rest are the case values and results of a select instruction. + /// The first operand is the operand of select_xxx instruction. The rest of + /// the operands are the case values and results of a select instruction. TailAllocatedOperandList<1> Operands; public: @@ -2462,12 +2594,12 @@ class SelectEnumInstBase return Operands[NumCases + 1].get(); } - // If there is a single case that returns a literal "true" value (an - // "integer_literal $Builtin.Int1, 1" value), return it. - // - // FIXME: This is used to interoperate with passes that reasoned about the - // old enum_is_tag insn. Ideally those passes would become general enough - // not to need this. + /// If there is a single case that returns a literal "true" value (an + /// "integer_literal $Builtin.Int1, 1" value), return it. + /// + /// FIXME: This is used to interoperate with passes that reasoned about the + /// old enum_is_tag insn. Ideally those passes would become general enough + /// not to need this. NullablePtr getSingleTrueElement() const; }; @@ -3127,18 +3259,6 @@ class StrongRetainInst : UnaryInstructionBase(DebugLoc, Operand) {} }; -/// StrongRetainAutoreleasedInst - Take ownership of the autoreleased return -/// value of an ObjC method. -class StrongRetainAutoreleasedInst - : public UnaryInstructionBase -{ - friend class SILBuilder; - - StrongRetainAutoreleasedInst(SILDebugLocation *DebugLoc, SILValue Operand) - : UnaryInstructionBase(DebugLoc, Operand) {} -}; - /// StrongReleaseInst - Decrease the strong reference count of an object. /// /// An object can be destroyed when its strong reference count is @@ -3344,7 +3464,7 @@ class DeallocPartialRefInst : public DeallocationInst { } }; -/// Deallocate memory allocated for a unsafe value buffer. +/// Deallocate memory allocated for an unsafe value buffer. class DeallocValueBufferInst : public UnaryInstructionBase { @@ -3536,6 +3656,32 @@ class IndexRawPointerInst : public IndexingInst { // Instructions representing terminators //===----------------------------------------------------------------------===// +enum class TermKind { + Invalid = 0, +#define TERMINATOR(Id, Parent, MemBehavior, MayRelease) Id, +#include "SILNodes.def" +}; + +struct ValueKindAsTermKind { + TermKind K; + + ValueKindAsTermKind(ValueKind V) { + switch (V) { +#define TERMINATOR(Id, Parent, MemBehavior, MayRelease) \ + case ValueKind::Id: \ + K = TermKind::Id; \ + break; +#define VALUE(Id, Parent) \ + case ValueKind::Id: \ + K = TermKind::Invalid; \ + break; +#include "SILNodes.def" + } + } + + operator TermKind() const { return K; } +}; + /// This class defines a "terminating instruction" for a SILBasicBlock. class TermInst : public SILInstruction { protected: @@ -3559,6 +3705,8 @@ class TermInst : public SILInstruction { } bool isBranch() const { return !getSuccessors().empty(); } + + TermKind getTermKind() const { return ValueKindAsTermKind(getKind()); } }; /// UnreachableInst - Position in the code which would be undefined to reach. @@ -3607,31 +3755,6 @@ class ReturnInst } }; -/// AutoreleaseReturnInst - Transfer ownership of a value to an ObjC -/// autorelease pool, and then return the value. -class AutoreleaseReturnInst - : public UnaryInstructionBase -{ - friend class SILBuilder; - - /// Constructs an AutoreleaseReturnInst representing an autorelease-return - /// sequence. - /// - /// \param DebugLoc The backing AST location. - /// - /// \param ReturnValue The value to be returned. - /// - AutoreleaseReturnInst(SILDebugLocation *DebugLoc, SILValue ReturnValue) - : UnaryInstructionBase(DebugLoc, ReturnValue) {} - -public: - SuccessorListTy getSuccessors() { - // No Successors. - return SuccessorListTy(); - } -}; - /// ThrowInst - Throw a typed error (which, in our system, is /// essentially just a funny kind of return). class ThrowInst @@ -3708,18 +3831,18 @@ class CondBranchInst : public TermInst { ConditionIdx }; enum { - // Map branch targets to block sucessor indices. + // Map branch targets to block successor indices. TrueIdx, FalseIdx }; private: SILSuccessor DestBBs[2]; - // The number of arguments for the True branch. + /// The number of arguments for the True branch. unsigned NumTrueArgs; - // The number of arguments for the False branch. + /// The number of arguments for the False branch. unsigned NumFalseArgs; - // The first argument is the condition; the rest are BB arguments. + /// The first argument is the condition; the rest are BB arguments. TailAllocatedOperandList<1> Operands; CondBranchInst(SILDebugLocation *DebugLoc, SILValue Condition, SILBasicBlock *TrueBB, SILBasicBlock *FalseBB, @@ -4005,7 +4128,7 @@ class DynamicMethodBranchInst : public TermInst { SILSuccessor DestBBs[2]; - // The operand. + /// The operand. FixedOperandList<1> Operands; DynamicMethodBranchInst(SILDebugLocation *DebugLoc, SILValue Operand, @@ -4144,7 +4267,7 @@ class CheckedCastAddrBranchInst : public TermInst { class TryApplyInstBase : public TermInst { public: enum { - // Map branch targets to block sucessor indices. + // Map branch targets to block successor indices. NormalIdx, ErrorIdx }; @@ -4251,7 +4374,8 @@ class ApplySite { FOREACH_IMPL_RETURN(getCallee()); } - // Return the referenced function if the callee is a function_ref instruction. + /// Return the referenced function if the callee is a function_ref + /// instruction. SILFunction *getCalleeFunction() const { FOREACH_IMPL_RETURN(getCalleeFunction()); } @@ -4341,10 +4465,47 @@ class ApplySite { /// Return the ith argument passed to this instruction. SILValue getArgument(unsigned i) const { return getArguments()[i]; } - // Set the ith argument of this instruction. + /// Set the ith argument of this instruction. void setArgument(unsigned i, SILValue V) const { getArgumentOperands()[i].set(V); } + + /// Return the self argument passed to this instruction. + bool hasSelfArgument() const { + switch (Inst->getKind()) { + case ValueKind::ApplyInst: + return cast(Inst)->hasSelfArgument(); + case ValueKind::TryApplyInst: + return cast(Inst)->hasSelfArgument(); + default: + llvm_unreachable("not implemented for this instruction!"); + } + } + + /// Return the self argument passed to this instruction. + SILValue getSelfArgument() const { + switch (Inst->getKind()) { + case ValueKind::ApplyInst: + return cast(Inst)->getSelfArgument(); + case ValueKind::TryApplyInst: + return cast(Inst)->getSelfArgument(); + default: + llvm_unreachable("not implemented for this instruction!"); + } + } + + /// Return the self operand passed to this instruction. + Operand &getSelfArgumentOperand() { + switch (Inst->getKind()) { + case ValueKind::ApplyInst: + return cast(Inst)->getSelfArgumentOperand(); + case ValueKind::TryApplyInst: + return cast(Inst)->getSelfArgumentOperand(); + default: + llvm_unreachable("not implemented for this instruction!"); + } + } + #undef FOREACH_IMPL_RETURN static ApplySite getFromOpaqueValue(void *p) { diff --git a/include/swift/SIL/SILLinkage.h b/include/swift/SIL/SILLinkage.h index 3ebbd69af7c85..26d80117852a9 100644 --- a/include/swift/SIL/SILLinkage.h +++ b/include/swift/SIL/SILLinkage.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILLocation.h b/include/swift/SIL/SILLocation.h index 6519609b50845..7dc60478f9009 100644 --- a/include/swift/SIL/SILLocation.h +++ b/include/swift/SIL/SILLocation.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -202,7 +202,7 @@ class SILLocation { /// Marks the location as coming from auto-generated body. void markAutoGenerated() { KindData |= (1 << AutoGeneratedBit); } - /// Returns true if the location represents an artifically generated + /// Returns true if the location represents an artificially generated /// body, such as thunks or default destructors. /// /// These locations should not be included in the debug line table. @@ -399,7 +399,7 @@ class RegularLocation : public SILLocation { /// Used to represent a return instruction in user code. /// -/// Allowed on an BranchInst, ReturnInst, AutoreleaseReturnInst. +/// Allowed on an BranchInst, ReturnInst. class ReturnLocation : public SILLocation { public: ReturnLocation(ReturnStmt *RS) : SILLocation(RS, ReturnKind) {} @@ -423,7 +423,7 @@ class ReturnLocation : public SILLocation { /// Used on the instruction that was generated to represent an implicit /// return from a function. /// -/// Allowed on an BranchInst, ReturnInst, AutoreleaseReturnInst. +/// Allowed on an BranchInst, ReturnInst. class ImplicitReturnLocation : public SILLocation { public: @@ -467,7 +467,7 @@ class ImplicitReturnLocation : public SILLocation { /// /// This location wraps the call site ASTNode. /// -/// Allowed on any instruction except for ReturnInst, AutoreleaseReturnInst. +/// Allowed on any instruction except for ReturnInst. class InlinedLocation : public SILLocation { public: InlinedLocation(Expr *CallSite) : SILLocation(CallSite, InlinedKind) {} @@ -514,7 +514,7 @@ class InlinedLocation : public SILLocation { /// /// This location wraps the call site ASTNode. /// -/// Allowed on any instruction except for ReturnInst, AutoreleaseReturnInst. +/// Allowed on any instruction except for ReturnInst. class MandatoryInlinedLocation : public SILLocation { public: MandatoryInlinedLocation(Expr *CallSite) : @@ -572,7 +572,7 @@ class MandatoryInlinedLocation : public SILLocation { /// scope's end location points to the SourceLoc that shows when the operation /// is performed at runtime. /// -/// Allowed on any instruction except for ReturnInst, AutoreleaseReturnInst. +/// Allowed on any instruction except for ReturnInst. /// Locations of an inlined destructor should also be represented by this. class CleanupLocation : public SILLocation { public: @@ -604,7 +604,7 @@ class CleanupLocation : public SILLocation { }; /// Used to represent an unreachable location that was -/// auto-generated and has no correspondance to user code. It should +/// auto-generated and has no correspondence to user code. It should /// not be used in diagnostics or for debugging. /// /// Differentiates an unreachable instruction, which is generated by diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h index 7f12cddb01efd..e56fba003b630 100644 --- a/include/swift/SIL/SILModule.h +++ b/include/swift/SIL/SILModule.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -27,6 +27,7 @@ #include "swift/SIL/SILDeclRef.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILGlobalVariable.h" +#include "swift/SIL/Notifications.h" #include "swift/SIL/SILType.h" #include "swift/SIL/SILVTable.h" #include "swift/SIL/SILWitnessTable.h" @@ -44,7 +45,6 @@ namespace swift { class AnyFunctionType; class ASTContext; class FuncDecl; - class SILExternalSource; class SILTypeList; class SILUndef; class SourceFile; @@ -165,19 +165,20 @@ class SILModule { /// This is lazily initialized the first time we attempt to /// deserialize. Previously this was created when the SILModule was /// constructed. In certain cases this was before all Modules had been loaded - /// causeing us to not + /// causing us to not std::unique_ptr SILLoader; /// True if this SILModule really contains the whole module, i.e. /// optimizations can assume that they see the whole module. bool wholeModule; - /// The external SIL source to use when linking this module. - SILExternalSource *ExternalSource = nullptr; - /// The options passed into this SILModule. SILOptions &Options; + /// A list of clients that need to be notified when an instruction + /// invalidation message is sent. + llvm::SetVector NotificationHandlers; + // Intentionally marked private so that we need to use 'constructSIL()' // to construct a SILModule. SILModule(ModuleDecl *M, SILOptions &Options, const DeclContext *associatedDC, @@ -193,6 +194,16 @@ class SILModule { public: ~SILModule(); + /// Add a delete notification handler \p Handler to the module context. + void registerDeleteNotificationHandler(DeleteNotificationHandler* Handler); + + /// Remove the delete notification handler \p Handler from the module context. + void removeDeleteNotificationHandler(DeleteNotificationHandler* Handler); + + /// Send the invalidation message that \p V is being deleted to all + /// registered handlers. The order of handlers is deterministic but arbitrary. + void notifyDeleteHandlers(ValueBase *V); + /// \brief Get a uniqued pointer to a SIL type list. SILTypeList *getSILTypeList(ArrayRef Types) const; @@ -374,24 +385,21 @@ class SILModule { /// /// \return false if the linking failed. bool linkFunction(SILFunction *Fun, - LinkingMode LinkAll=LinkingMode::LinkNormal, - std::function Callback =nullptr); + LinkingMode LinkAll = LinkingMode::LinkNormal); /// Attempt to link a function by declaration. Returns true if linking /// succeeded, false otherwise. /// /// \return false if the linking failed. bool linkFunction(SILDeclRef Decl, - LinkingMode LinkAll=LinkingMode::LinkNormal, - std::function Callback =nullptr); + LinkingMode LinkAll = LinkingMode::LinkNormal); /// Attempt to link a function by mangled name. Returns true if linking /// succeeded, false otherwise. /// /// \return false if the linking failed. bool linkFunction(StringRef Name, - LinkingMode LinkAll=LinkingMode::LinkNormal, - std::function Callback =nullptr); + LinkingMode LinkAll = LinkingMode::LinkNormal); /// Link in all Witness Tables in the module. void linkAllWitnessTables(); @@ -428,13 +436,30 @@ class SILModule { SILDeclRef constant, ForDefinition_t forDefinition); + /// \brief Return the declaration of a function, or create it if it does not + /// exist. + /// + /// This signature is a direct copy of the signature of SILFunction::create() + /// in order to simplify refactoring all SILFunction creation use-sites to use + /// SILModule. Eventually the uses should probably be refactored. + SILFunction *getOrCreateFunction( + SILLinkage linkage, StringRef name, CanSILFunctionType loweredType, + GenericParamList *contextGenericParams, Optional loc, + IsBare_t isBareSILFunction, IsTransparent_t isTrans, + IsFragile_t isFragile, IsThunk_t isThunk = IsNotThunk, + SILFunction::ClassVisibility_t classVisibility = SILFunction::NotRelevant, + Inline_t inlineStrategy = InlineDefault, + EffectsKind EK = EffectsKind::Unspecified, + SILFunction *InsertBefore = nullptr, + const SILDebugScope *DebugScope = nullptr, DeclContext *DC = nullptr); + /// Look up the SILWitnessTable representing the lowering of a protocol /// conformance, and collect the substitutions to apply to the referenced /// witnesses, if any. /// /// \arg C The protocol conformance mapped key to use to lookup the witness /// table. - /// \arg deserializeLazily If we can not find the witness table should we + /// \arg deserializeLazily If we cannot find the witness table should we /// attempt to lazily deserialize it. std::pair> lookUpWitnessTable(const ProtocolConformance *C, bool deserializeLazily=true); @@ -444,8 +469,7 @@ class SILModule { lookUpFunctionInWitnessTable(const ProtocolConformance *C, SILDeclRef Member); /// Look up the VTable mapped to the given ClassDecl. Returns null on failure. - SILVTable *lookUpVTable(const ClassDecl *C, - std::function Callback = nullptr); + SILVTable *lookUpVTable(const ClassDecl *C); /// Attempt to lookup the function corresponding to \p Member in the class /// hierarchy of \p Class. @@ -465,12 +489,6 @@ class SILModule { Stage = s; } - SILExternalSource *getExternalSource() const { return ExternalSource; } - void setExternalSource(SILExternalSource *S) { - assert(!ExternalSource && "External source already set"); - ExternalSource = S; - } - /// \brief Run the SIL verifier to make sure that all Functions follow /// invariants. void verify() const; @@ -499,12 +517,13 @@ class SILModule { bool PrintASTDecls = true) const; /// Allocate memory using the module's internal allocator. - void *allocate(unsigned Size, unsigned Align) const { - if (getASTContext().LangOpts.UseMalloc) - return AlignedAlloc(Size, Align); + void *allocate(unsigned Size, unsigned Align) const; - return BPA.Allocate(Size, Align); - } + /// Allocate memory for an instruction using the module's internal allocator. + void *allocateInst(unsigned Size, unsigned Align) const; + + /// Deallocate memory of an instruction. + void deallocateInst(SILInstruction *I); /// \brief Looks up the llvm intrinsic ID and type for the builtin function. /// diff --git a/include/swift/SIL/SILNodes.def b/include/swift/SIL/SILNodes.def index 2eada1ba57a4b..dbf04dd3a1982 100644 --- a/include/swift/SIL/SILNodes.def +++ b/include/swift/SIL/SILNodes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -91,6 +91,7 @@ ABSTRACT_VALUE(SILInstruction, ValueBase) // Accessing memory INST(LoadInst, SILInstruction, MayRead, DoesNotRelease) + INST(LoadUnownedInst, SILInstruction, MayRead, DoesNotRelease) INST(LoadWeakInst, SILInstruction, MayRead, DoesNotRelease) INST(StoreInst, SILInstruction, MayWrite, DoesNotRelease) INST(AssignInst, SILInstruction, MayWrite, DoesNotRelease) @@ -98,6 +99,7 @@ ABSTRACT_VALUE(SILInstruction, ValueBase) INST(MarkFunctionEscapeInst, SILInstruction, None, DoesNotRelease) INST(DebugValueInst, SILInstruction, None, DoesNotRelease) INST(DebugValueAddrInst, SILInstruction, None, DoesNotRelease) + INST(StoreUnownedInst, SILInstruction, MayWrite, DoesNotRelease) INST(StoreWeakInst, SILInstruction, MayWrite, DoesNotRelease) INST(CopyAddrInst, SILInstruction, MayHaveSideEffects, MayRelease) INST(DestroyAddrInst, SILInstruction, MayHaveSideEffects, MayRelease) @@ -111,8 +113,6 @@ ABSTRACT_VALUE(SILInstruction, ValueBase) // Reference Counting ABSTRACT_VALUE(RefCountingInst, SILInstruction) INST(StrongRetainInst, RefCountingInst, MayHaveSideEffects, DoesNotRelease) - INST(StrongRetainAutoreleasedInst, RefCountingInst, MayHaveSideEffects, - DoesNotRelease) INST(StrongReleaseInst, RefCountingInst, MayHaveSideEffects, MayRelease) INST(StrongRetainUnownedInst, RefCountingInst, MayHaveSideEffects, DoesNotRelease) @@ -243,7 +243,6 @@ ABSTRACT_VALUE(SILInstruction, ValueBase) ABSTRACT_VALUE(TermInst, SILInstruction) TERMINATOR(UnreachableInst, TermInst, None, DoesNotRelease) TERMINATOR(ReturnInst, TermInst, None, DoesNotRelease) - TERMINATOR(AutoreleaseReturnInst, TermInst, None, DoesNotRelease) TERMINATOR(ThrowInst, TermInst, None, DoesNotRelease) TERMINATOR(TryApplyInst, TermInst, MayHaveSideEffects, MayRelease) TERMINATOR(BranchInst, TermInst, None, DoesNotRelease) diff --git a/include/swift/SIL/SILSuccessor.h b/include/swift/SIL/SILSuccessor.h index 4f566b815c1fa..4d002f7660e9f 100644 --- a/include/swift/SIL/SILSuccessor.h +++ b/include/swift/SIL/SILSuccessor.h @@ -1,8 +1,8 @@ -//===--- SILSuccessor.h - Terminator Instruction Successor -------*- C++ -*-==// +//===--- SILSuccessor.h - Terminator Instruction Successor ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILType.h b/include/swift/SIL/SILType.h index cdec383bacb1d..3e808b30a1d29 100644 --- a/include/swift/SIL/SILType.h +++ b/include/swift/SIL/SILType.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -74,13 +74,6 @@ enum class SILValueCategory { /// An address is a pointer to an allocated variable of the type /// (possibly uninitialized). Address, - - /// Local storage is the container for a local allocation. For - /// statically-sized types, this is just the allocation itself. - /// However, for dynamically-sized types (like archetypes or - /// resilient structs), it may be some sort of fixed-size buffer, - /// stack depth, or the like. - LocalStorage }; /// SILType - A Swift type that has been lowered to a SIL representation type. @@ -133,13 +126,6 @@ class SILType { return SILType(T, SILValueCategory::Address); } - /// Form the type for the backing storage of a locally-allocated - /// object, given a Swift type that either does not require any - /// special handling or has already been appropriately lowered. - static SILType getPrimitiveLocalStorageType(CanType T) { - return SILType(T, SILValueCategory::LocalStorage); - } - /// Apply a substitution to the type to produce another lowered SIL type. static SILType substType(SILModule &silModule, ModuleDecl *astModule, TypeSubstitutionMap &subs, SILType SrcTy); @@ -157,7 +143,17 @@ class SILType { SILValueCategory getCategory() const { return SILValueCategory(value.getInt()); } - + + /// Returns the \p Category variant of this type. + SILType getCategoryType(SILValueCategory Category) const { + return SILType(getSwiftRValueType(), Category); + } + + /// Returns the variant of this type that matches \p Ty.getCategory() + SILType copyCategory(SILType Ty) const { + return getCategoryType(Ty.getCategory()); + } + /// Returns the address variant of this type. Instructions which /// manipulate memory will generally work with object addresses. SILType getAddressType() const { @@ -170,13 +166,6 @@ class SILType { return SILType(getSwiftRValueType(), SILValueCategory::Object); } - /// Returns the local storage variant of this type. Local - /// allocations of dynamically-sized types generally require some - /// sort of buffer. - SILType getLocalStorageType() const { - return SILType(getSwiftRValueType(), SILValueCategory::LocalStorage); - } - /// Returns the Swift type referenced by this SIL type. CanType getSwiftRValueType() const { return CanType(value.getPointer()); @@ -258,11 +247,6 @@ class SILType { /// True if the type is an object type. bool isObject() const { return getCategory() == SILValueCategory::Object; } - /// True if the type is a local-storage type. - bool isLocalStorage() const { - return getCategory() == SILValueCategory::LocalStorage; - } - /// isAddressOnly - True if the type, or the referenced type of an address /// type, is address-only. For example, it could be a resilient struct or /// something of unknown size. diff --git a/include/swift/SIL/SILUndef.h b/include/swift/SIL/SILUndef.h index 50722089a868a..9e32f370a3abd 100644 --- a/include/swift/SIL/SILUndef.h +++ b/include/swift/SIL/SILUndef.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILVTable.h b/include/swift/SIL/SILVTable.h index 99ec5b2b04d48..ac590dbec3d7c 100644 --- a/include/swift/SIL/SILVTable.h +++ b/include/swift/SIL/SILVTable.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -55,7 +55,7 @@ class SILVTable : public llvm::ilist_node, /// The number of SILVTables entries. unsigned NumEntries; - /// Tail-allocated SILVTable entires. + /// Tail-allocated SILVTable entries. Pair Entries[1]; /// Private constructor. Create SILVTables by calling SILVTable::create. diff --git a/include/swift/SIL/SILValue.h b/include/swift/SIL/SILValue.h index b809b3b1517a9..50985696dd1a4 100644 --- a/include/swift/SIL/SILValue.h +++ b/include/swift/SIL/SILValue.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -172,7 +172,7 @@ enum { ValueResultNumberBits = 2 }; -/// SILValue - A SILValue is a use of a specific result of an ValueBase. As +/// SILValue - A SILValue is a use of a specific result of a ValueBase. As /// such, it is a pair of the ValueBase and the result number being referenced. class SILValue { llvm::PointerIntPair ValueAndResultNumber; @@ -377,7 +377,7 @@ class Operand { /// Hoist the address projection rooted in this operand to \p InsertBefore. /// Requires the projected value to dominate the insertion point. /// - /// Will look through single basic block predeccessor arguments. + /// Will look through single basic block predecessor arguments. void hoistAddressProjections(SILInstruction *InsertBefore, DominanceInfo *DomTree); diff --git a/include/swift/SIL/SILValueProjection.h b/include/swift/SIL/SILValueProjection.h new file mode 100644 index 0000000000000..eb81d524fa6ee --- /dev/null +++ b/include/swift/SIL/SILValueProjection.h @@ -0,0 +1,554 @@ +//===--- SILValueProjection.h ---------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +/// +/// This file defines SILValueProjection, a class containing a SILValue base +/// and a ProjectionPath. It is used as the base class for LSLocation and +/// LSValue. +/// +/// In the case of LSLocation, the base represents the base of the allocated +/// objects and the ProjectionPath tells which field in the object the +/// LSLocation represents. +/// +/// In the case of LSValue, the base represents the root of loaded or +/// stored value it represents. And the ProjectionPath represents the field in +/// the loaded/store value the LSValue represents. +/// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SIL_VALUEPROJECTION_H +#define SWIFT_SIL_VALUEPROJECTION_H + +#include "swift/SIL/Projection.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/EscapeAnalysis.h" +#include "swift/SILOptimizer/Analysis/TypeExpansionAnalysis.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Debug.h" + +namespace swift { + +/// forward declarations. +class SILValueProjection; +class LSLocation; +class LSValue; + +//===----------------------------------------------------------------------===// +// SILValue Projection +//===----------------------------------------------------------------------===// + +class SILValueProjection { +public: + enum KeyKind : uint8_t { EmptyKey = 0, TombstoneKey, NormalKey }; + +protected: + /// The base of the object. + SILValue Base; + /// Empty key, tombstone key or normal key. + KeyKind Kind; + /// The path to reach the accessed field of the object. + Optional Path; + +public: + /// Constructors. + SILValueProjection() : Base(), Kind(NormalKey) {} + SILValueProjection(KeyKind Kind) : Base(), Kind(Kind) {} + SILValueProjection(SILValue B) : Base(B), Kind(NormalKey) {} + SILValueProjection(SILValue B, const ProjectionPath &P, + KeyKind Kind = NormalKey) + : Base(B), Kind(Kind) { + ProjectionPath T; + T.append(P); + Path = std::move(T); + } + + /// Destructors. + virtual ~SILValueProjection() {} + + /// Copy constructor. + SILValueProjection(const SILValueProjection &RHS) { + Base = RHS.Base; + Path.reset(); + Kind = RHS.Kind; + if (!RHS.Path.hasValue()) + return; + ProjectionPath X; + X.append(RHS.Path.getValue()); + Path = std::move(X); + } + + SILValueProjection &operator=(const SILValueProjection &RHS) { + Base = RHS.Base; + Path.reset(); + Kind = RHS.Kind; + if (!RHS.Path.hasValue()) + return *this; + ProjectionPath X; + X.append(RHS.Path.getValue()); + Path = std::move(X); + return *this; + } + + /// Getters and setters for SILValueProjection. + KeyKind getKind() const { return Kind; } + void setKind(KeyKind K) { Kind = K; } + SILValue getBase() const { return Base; } + Optional &getPath() { return Path; } + + /// Reset the SILValueProjection, i.e. clear base and path. + void reset() { + Base = SILValue(); + Path.reset(); + Kind = NormalKey; + } + + /// Returns whether the SILValueProjection has been initialized properly. + virtual bool isValid() const { return Base && Path.hasValue(); } + + /// Returns true if the LSValue has a non-empty projection path. + bool hasEmptyProjectionPath() const { return !Path.getValue().size(); } + + /// Return false if one projection path is a prefix of another. false + /// otherwise. + bool hasNonEmptySymmetricPathDifference(const SILValueProjection &RHS) const { + const ProjectionPath &P = RHS.Path.getValue(); + return Path.getValue().hasNonEmptySymmetricDifference(P); + } + + /// Subtract the given path from the ProjectionPath. + void subtractPaths(Optional &P) { + if (!P.hasValue()) + return; + ProjectionPath::subtractPaths(Path.getValue(), P.getValue()); + } + + /// Return true if the RHS have identical projection paths. + /// If both SILValueProjection have empty paths, they are treated as having + /// identical projection path. + bool hasIdenticalProjectionPath(const SILValueProjection &RHS) const { + // If both Paths have no value, then the 2 SILValueProjections are + // different. + if (!Path.hasValue() && !RHS.Path.hasValue()) + return false; + // If 1 Path has value while the other does not, then the 2 + // SILValueProjections are different. + if (Path.hasValue() != RHS.Path.hasValue()) + return false; + // If both Paths are empty, then the 2 SILValueProjections are the same. + if (Path.getValue().empty() && RHS.Path.getValue().empty()) + return true; + // If both Paths have different values, then the 2 SILValueProjections are + // different. + if (Path.getValue() != RHS.Path.getValue()) + return false; + return true; + } + + /// Comparisons. + bool operator!=(const SILValueProjection &RHS) const { + return !(*this == RHS); + } + bool operator==(const SILValueProjection &RHS) const { + // If type is not the same, then SILValueProjections different. + if (Kind != RHS.Kind) + return false; + // Return true if this is a TombstoneKey or EmptyKey. + if (Kind == EmptyKey || Kind == TombstoneKey) + return true; + // If Base is different, then SILValueProjections different. + if (Base != RHS.Base) + return false; + // If the projection paths are different, then SILValueProjections are + // different. + if (!hasIdenticalProjectionPath(RHS)) + return false; + // These SILValueProjections represent the same memory location. + return true; + } + + /// Returns the hashcode for the location. + llvm::hash_code getHashCode() const { + llvm::hash_code HC = llvm::hash_combine( + Base.getDef(), Base.getResultNumber(), Base.getType()); + if (!Path.hasValue()) + return HC; + HC = llvm::hash_combine(HC, hash_value(Path.getValue())); + return HC; + } + + virtual void print() const; + + /// Create a path of ValueProjection with the given VA and Path. + static SILValue createExtract(SILValue VA, Optional &Path, + SILInstruction *Inst, bool IsValExt); +}; + +//===----------------------------------------------------------------------===// +// Load Store Value +//===----------------------------------------------------------------------===// + +using LSLocationValueMap = llvm::DenseMap; +using LSValueList = llvm::SmallVector; +using LSValueIndexMap = llvm::DenseMap; +using ValueTableMap = llvm::SmallMapVector; + +/// This class represents either a single SILValue or a covering of values that +/// we can forward from via the introduction of a SILArgument. This enables us +/// to treat the case of having one value or multiple values and load and store +/// cases all at once abstractly and cleanly. +/// +/// A LSValue is an abstraction of an object field value in program. It +/// consists of a base that is the tracked SILValue, and a projection path to +/// the represented field. +/// +/// In this example below, 2 LSValues will be created for the 2 stores, +/// they will have %6 and %7 as their Bases and empty projection paths. +/// +/// struct A { +/// var a: Int +/// var b: Int +/// } +/// +/// sil hidden @test_1 : $@convention(thin) () -> () { +/// %0 = alloc_stack $A // var x // users: %4, %7 +/// %5 = integer_literal $Builtin.Int64, 19 // user: %6 +/// %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 +/// %7 = struct_element_addr %0 : $*A, #A.a // user: %8 +/// store %6 to %7 : $*Int // id: %8 +/// %9 = integer_literal $Builtin.Int64, 20 // user: %10 +/// %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 +/// %11 = struct_element_addr %0 : $*A, #A.b // user: %12 +/// store %10 to %11 : $*Int // id: %12 +/// } +/// +/// In this example below, 2 LSValues will be created with %3 as their +/// bases and #a and #b as their projection paths respectively. +/// +/// sil hidden @test_1 : $@convention(thin) () -> () { +/// %0 = alloc_stack $A // var x // users: %4, %6 +/// // function_ref a.A.init (a.A.Type)() -> a.A +/// %1 = function_ref @a.A.init : $@convention(thin) (@thin A.Type) -> A +/// %2 = metatype $@thin A.Type // user: %3 +/// %3 = apply %1(%2) : $@convention(thin) (@thin A.Type) -> A // user: %4 +/// store %3 to %0 : $*A // id: %4 +/// } +/// +/// NOTE: LSValue can take 2 forms. +/// +/// 1. It can take a concrete value, i.e. with a valid Base and ProjectionPath. +/// using the extract function, it can be materialized in IR. +/// +/// 2. It can represent a covering set of LSValues from all predecessor +/// blocks. and to get the forwardable SILValue, we need to go to its +/// predecessors to materialize each one of them and create the forwarding +/// SILValue through a SILArgument. +/// +/// Given a set of LSLocations and their available LSValues, +/// reduce will create the forwarding SILValue by merging them while +/// creating as few value extraction and aggregation as possible. +/// +/// NOTE: ProjectionPath in LSValue could be replaced by the +/// ProjectionPath in the LSLocation, but that would require we break the +/// ProjectionPath into 2 parts, 1 for the Base to the accessed (aggregate) node +/// and another 1 for the accessed (aggregate) node to the leaf node the +/// LSLocation represents. +/// +/// This makes implementing the LSLocationVault more difficult, as there are +/// multiple ways to represent the same LSLocations (even they have the same +/// base). +/// +class LSValue : public SILValueProjection { + /// If this is a covering value, we need to go to each predecessor to + /// materialize the value. + bool IsCoveringValue; + +public: + /// Constructors. + LSValue() : SILValueProjection(), IsCoveringValue(false) {} + LSValue(SILValue B) : SILValueProjection(B), IsCoveringValue(false) {} + LSValue(SILValue B, const ProjectionPath &P) + : SILValueProjection(B, P), IsCoveringValue(false) {} + LSValue(KeyKind Kind) : SILValueProjection(Kind), IsCoveringValue(false) {} + LSValue(bool CSVal) : SILValueProjection(NormalKey), IsCoveringValue(CSVal) {} + + /// Copy constructor. + LSValue(const LSValue &RHS) : SILValueProjection(RHS) { + IsCoveringValue = RHS.IsCoveringValue; + } + + /// Assignment operator. + LSValue &operator=(const LSValue &RHS) { + SILValueProjection::operator=(RHS); + IsCoveringValue = RHS.IsCoveringValue; + return *this; + } + + /// Comparisons. + bool operator!=(const LSValue &RHS) const { return !(*this == RHS); } + bool operator==(const LSValue &RHS) const { + if (IsCoveringValue && RHS.isCoveringValue()) + return true; + if (IsCoveringValue != RHS.isCoveringValue()) + return false; + + return SILValueProjection::operator==(RHS); + } + + /// Returns whether the LSValue has been initialized properly. + bool isValid() const { + if (IsCoveringValue) + return true; + return Base && Path.hasValue(); + } + + /// Take the last level projection off. Return the modified LSValue. + LSValue &stripLastLevelProjection() { + Path.getValue().remove_front(); + return *this; + } + + /// Returns true if this LSValue is a covering value. + bool isCoveringValue() const { return IsCoveringValue; } + /// Mark this LSValue as a covering value. + void setCoveringValue() { + Base = SILValue(); + Path.reset(); + IsCoveringValue = true; + } + + /// Materialize the SILValue that this LSValue represents. + /// + /// In the case where we have a single value this can be materialized by + /// applying Path to the Base. + /// + /// In the case where we are handling a covering set, this is initially null + /// and when we insert the PHI node, this is set to the SILArgument which + /// represents the PHI node. + SILValue materialize(SILInstruction *Inst) { + if (IsCoveringValue) + return SILValue(); + return SILValueProjection::createExtract(Base, Path, Inst, true); + } + + void print() const { + if (IsCoveringValue) { + llvm::outs() << "Covering Value"; + return; + } + SILValueProjection::print(); + } + + //============================// + // static functions. // + //============================// + + /// Expand this SILValue to all individual fields it contains. + static void expand(SILValue Base, SILModule *Mod, LSValueList &Vals, + TypeExpansionAnalysis *TE); + + /// Given a memory location and a map between the expansions of the location + /// and their corresponding values, try to come up with a single SILValue this + /// location holds. This may involve extracting and aggregating available + /// values. + /// + /// NOTE: reduce assumes that every component of the location has a concrete + /// (i.e. not coverings set) available value in LocAndVal. + /// + /// TODO: we do not really need the llvm::DenseMap here + /// we only need a map between the projection tree of a SILType and the value + /// each leaf node takes. This will be implemented once ProjectionPath memory + /// cost is reduced and made copyable (its copy constructor is deleted at the + /// moment). + static SILValue reduce(LSLocation &Base, SILModule *Mod, + LSLocationValueMap &LocAndVal, + SILInstruction *InsertPt, + TypeExpansionAnalysis *TE); +}; + +static inline llvm::hash_code hash_value(const LSValue &V) { + if (V.isCoveringValue()) + return llvm::hash_combine(V.isCoveringValue()); + return llvm::hash_combine(V.getBase().getDef(), V.getBase().getResultNumber(), + V.getBase().getType()); +} + +//===----------------------------------------------------------------------===// +// Memory Location +//===----------------------------------------------------------------------===// +/// Type declarations. +using LSLocationSet = llvm::DenseSet; +using LSLocationList = llvm::SmallVector; +using LSLocationIndexMap = llvm::DenseMap; + +/// This class represents a field in an allocated object. It consists of a +/// base that is the tracked SILValue, and a projection path to the +/// represented field. +/// +/// The base here will point to the actual object this inst is accessing, +/// not this particular field. We call this LSLocation canonicalization. +/// +/// e.g. %1 = alloc_stack $S +/// %2 = struct_element_addr %1, #a +/// store %3 to %2 : $*Int +/// +/// Base will point to %1, but not %2. Projection path will indicate which +/// field is accessed. +/// +/// Canonicalizing LSLocation reduces the # of the LSLocations we keep in +/// the LSLocationVault, and this in turn reduces the # of bits each basic +/// block keeps. +/// +/// Moreover, without canonicalization, it's more difficult to implement the +/// intersection operator in DSE/RLE? +/// +/// We basically need to compare every pair of LSLocation and find the ones +/// that must alias O(n^2). Or we need to go through every LSLocation in the +/// vault and turn on/off the bits for the MustAlias ones whenever we want to +/// turn a LSLocation bit on/off. Both are expensive. +/// +/// Canonicalizing suffers from the same problem, but to a lesser extend. i.e. +/// 2 LSLocations with different bases but happen to be the same object and +/// field. By doing canonicalization, the intersection is simply a bitwise AND +/// (No AA involved). +/// +class LSLocation : public SILValueProjection { +public: + /// Constructors. + LSLocation() {} + LSLocation(SILValue B) : SILValueProjection(B) { initialize(B); } + LSLocation(SILValue B, ProjectionPath &P, KeyKind Kind = NormalKey) + : SILValueProjection(B, P, Kind) {} + LSLocation(KeyKind Kind) : SILValueProjection(Kind) {} + /// Use the concatenation of the 2 ProjectionPaths as the Path. + LSLocation(SILValue B, const ProjectionPath &P1, const ProjectionPath &P2) + : SILValueProjection(B) { + ProjectionPath T; + T.append(P1); + T.append(P2); + Path = std::move(T); + } + + /// Copy constructor. + LSLocation(const LSLocation &RHS) : SILValueProjection(RHS) {} + + /// Assignment operator. + LSLocation &operator=(const LSLocation &RHS) { + SILValueProjection::operator=(RHS); + return *this; + } + + /// Returns the type of the object the LSLocation represents. + SILType getType() const { + // Base might be an address type, e.g. from alloc_stack of struct, + // enum or tuples. + if (Path.getValue().empty()) + return Base.getType().getObjectType(); + return Path.getValue().front().getType().getObjectType(); + } + + /// Trace the given SILValue till the base of the accessed object. Also + /// construct the projection path to the field accessed. + void initialize(SILValue val); + + /// Get the first level locations based on this location's first level + /// projection. + void getFirstLevelLSLocations(LSLocationList &Locs, SILModule *Mod); + + /// Check whether the 2 LSLocations may alias each other or not. + bool isMayAliasLSLocation(const LSLocation &RHS, AliasAnalysis *AA); + + /// Check whether the 2 LSLocations must alias each other or not. + bool isMustAliasLSLocation(const LSLocation &RHS, AliasAnalysis *AA); + + /// Check whether the LSLocation can escape the current function. + bool isNonEscapingLocalLSLocation(SILFunction *Fn, EscapeAnalysis *EA); + + //============================// + // static functions. // + //============================// + + /// Expand this location to all individual fields it contains. + /// + /// In SIL, we can have a store to an aggregate and loads from its individual + /// fields. Therefore, we expand all the operations on aggregates onto + /// individual fields and process them separately. + static void expand(LSLocation &Base, SILModule *Mod, LSLocationList &Locs, + TypeExpansionAnalysis *TE); + + /// Given a set of locations derived from the same base, try to merge/reduce + /// them into smallest number of LSLocations possible. + static void reduce(LSLocation &Base, SILModule *Mod, LSLocationSet &Locs, + TypeExpansionAnalysis *TE); + + /// Enumerate the given Mem LSLocation. + static void enumerateLSLocation(SILModule *M, SILValue Mem, + std::vector &LSLocationVault, + LSLocationIndexMap &LocToBit, + TypeExpansionAnalysis *TE); + + /// Enumerate all the locations in the function. + static void enumerateLSLocations(SILFunction &F, + std::vector &LSLocationVault, + LSLocationIndexMap &LocToBit, + TypeExpansionAnalysis *TE); +}; + +static inline llvm::hash_code hash_value(const LSLocation &L) { + return llvm::hash_combine(L.getBase().getDef(), L.getBase().getResultNumber(), + L.getBase().getType()); +} + +} // end swift namespace + +/// LSLocation is used in DenseMap, define functions required by DenseMap. +namespace llvm { +using swift::SILValueProjection; +using swift::LSLocation; +using swift::LSValue; + +template <> struct DenseMapInfo { + static inline LSLocation getEmptyKey() { + return LSLocation(SILValueProjection::EmptyKey); + } + static inline LSLocation getTombstoneKey() { + return LSLocation(SILValueProjection::TombstoneKey); + } + static inline unsigned getHashValue(const LSLocation &Loc) { + return hash_value(Loc); + } + static bool isEqual(const LSLocation &LHS, const LSLocation &RHS) { + return LHS == RHS; + } +}; + +template <> struct DenseMapInfo { + static inline LSValue getEmptyKey() { + return LSValue(SILValueProjection::EmptyKey); + } + static inline LSValue getTombstoneKey() { + return LSValue(SILValueProjection::TombstoneKey); + } + static inline unsigned getHashValue(const LSValue &Val) { + return hash_value(Val); + } + static bool isEqual(const LSValue &LHS, const LSValue &RHS) { + return LHS == RHS; + } +}; + +} // namespace llvm + +#endif // SWIFT_SIL_MEMLOCATION_H diff --git a/include/swift/SIL/SILVisitor.h b/include/swift/SIL/SILVisitor.h index a8c19e646bb3f..52f00e29d285f 100644 --- a/include/swift/SIL/SILVisitor.h +++ b/include/swift/SIL/SILVisitor.h @@ -1,8 +1,8 @@ -//===--- SILVisitor.h - Defines the SILVisitor class -------------*- C++ -*-==// +//===--- SILVisitor.h - Defines the SILVisitor class ------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/SILWitnessTable.h b/include/swift/SIL/SILWitnessTable.h index c638f15b320a8..411b1223bd450 100644 --- a/include/swift/SIL/SILWitnessTable.h +++ b/include/swift/SIL/SILWitnessTable.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -181,7 +181,7 @@ class SILWitnessTable : public llvm::ilist_node, NormalProtocolConformance *Conformance; /// The various witnesses containing in this witness table. Is empty if the - /// table has no witness entires or if it is a declaration. + /// table has no witness entries or if it is a declaration. MutableArrayRef Entries; /// Whether or not this witness table is a declaration. This is separate from diff --git a/include/swift/SIL/SILWitnessVisitor.h b/include/swift/SIL/SILWitnessVisitor.h index 88026463b0d9e..9ec75c00de85a 100644 --- a/include/swift/SIL/SILWitnessVisitor.h +++ b/include/swift/SIL/SILWitnessVisitor.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h index ebfd9a5b014d5..07b1f51b0d18f 100644 --- a/include/swift/SIL/TypeLowering.h +++ b/include/swift/SIL/TypeLowering.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -193,7 +193,7 @@ class TypeLowering { /// Return the lowering for the semantic type. inline const TypeLowering &getSemanticTypeLowering(TypeConverter &TC) const; - /// Produce a exact copy of the value in the given address as a + /// Produce an exact copy of the value in the given address as a /// scalar. The caller is responsible for destroying this value, /// e.g. by releasing it. /// @@ -232,7 +232,7 @@ class TypeLowering { virtual void emitDestroyAddress(SILBuilder &B, SILLocation loc, SILValue value) const = 0; - /// Given a +1 r-value which are are claiming ownership of, destroy it. + /// Given a +1 r-value which we are claiming ownership of, destroy it. /// /// Note that an r-value might be an address. virtual void emitDestroyRValue(SILBuilder &B, SILLocation loc, @@ -420,7 +420,7 @@ enum class CaptureKind { /// A local value captured as a single pointer to storage (formed with /// @noescape closures). StorageAddress, - // A local value captures as a constant. + /// A local value captured as a constant. Constant, }; @@ -511,7 +511,7 @@ class TypeConverter { friend struct llvm::DenseMapInfo; - /// Find an cached TypeLowering by TypeKey, or return null if one doesn't + /// Find a cached TypeLowering by TypeKey, or return null if one doesn't /// exist. const TypeLowering *find(TypeKey k); /// Insert a mapping into the cache. @@ -695,7 +695,7 @@ class TypeConverter { /// not override. CanSILFunctionType getConstantOverrideType(SILDeclRef constant) { // Fast path if the constant isn't overridden. - if (constant.getOverriddenVTableEntry().isNull()) + if (constant.getNextOverriddenVTableEntry().isNull()) return getConstantFunctionType(constant); SILDeclRef base = constant; while (SILDeclRef overridden = base.getOverridden()) @@ -770,9 +770,6 @@ class TypeConverter { SILType getSubstitutedStorageType(AbstractStorageDecl *value, Type lvalueType); - /// Retrieve the set of archetypes open in the given context. - GenericParamList *getEffectiveGenericParamsForContext(DeclContext *dc); - /// Retrieve the set of archetypes closed over by the given function. GenericParamList *getEffectiveGenericParams(AnyFunctionRef fn, CaptureInfo captureInfo); diff --git a/include/swift/SIL/TypeSubstCloner.h b/include/swift/SIL/TypeSubstCloner.h index cbf75c0548bae..418930f4bda32 100644 --- a/include/swift/SIL/TypeSubstCloner.h +++ b/include/swift/SIL/TypeSubstCloner.h @@ -1,8 +1,8 @@ -//===--- TypeSubstCloner.h - Clones code and substitutes types ---*- C++ -*-==// +//===--- TypeSubstCloner.h - Clones code and substitutes types --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,7 +21,7 @@ #include "swift/AST/Type.h" #include "swift/SIL/SILCloner.h" #include "swift/SIL/DynamicCasts.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/Support/Debug.h" namespace swift { @@ -278,7 +278,7 @@ class TypeSubstCloner : public SILClonerWithScopes { TypeSubstitutionMap &SubsMap; /// The original function to specialize. SILFunction &Original; - /// The substiutions used at the call site. + /// The substitutions used at the call site. ArrayRef ApplySubs; /// True, if used for inlining. bool Inlining; diff --git a/include/swift/SILAnalysis/AliasAnalysis.h b/include/swift/SILAnalysis/AliasAnalysis.h deleted file mode 100644 index 54962c92bbf7d..0000000000000 --- a/include/swift/SILAnalysis/AliasAnalysis.h +++ /dev/null @@ -1,191 +0,0 @@ -//===-------------- AliasAnalysis.h - SIL Alias Analysis -*- C++ -*--------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SILANALYSIS_ALIASANALYSIS_H -#define SWIFT_SILANALYSIS_ALIASANALYSIS_H - -#include "swift/SIL/SILInstruction.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/SideEffectAnalysis.h" -#include "llvm/ADT/DenseMap.h" - -namespace swift { - -class SILValue; -class SILInstruction; -class SideEffectAnalysis; - -/// This class is a simple wrapper around an alias analysis cache. This is -/// needed since we do not have an "analysis" infrastructure. -class AliasAnalysis : public SILAnalysis { -public: - - /// This enum describes the different kinds of aliasing relations between - /// pointers. - /// - /// NoAlias: There is never dependence between memory referenced by the two - /// pointers. Example: Two pointers pointing to non-overlapping - /// memory ranges. - /// - /// MayAlias: Two pointers might refer to the same memory location. - /// - /// - /// PartialAlias: The two memory locations are known to be overlapping - /// but do not start at the same address. - /// - /// - /// MustAlias: The two memory locations always start at exactly the same - /// location. The pointers are equal. - /// - enum class AliasResult : unsigned { - NoAlias=0, ///< The two values have no dependencies on each - /// other. - MayAlias, ///< The two values can not be proven to alias or - /// not alias. Anything could happen. - PartialAlias, ///< The two values overlap in a partial manner. - MustAlias, ///< The two values are equal. - }; - -private: - SILModule *Mod; - SideEffectAnalysis *SEA; - - using TBAACacheKey = std::pair; - - /// A cache for the computation of TBAA. True means that the types may - /// alias. False means that the types must not alias. - /// - /// We don't need to invalidate this cache because type aliasing relations - /// never change. - llvm::DenseMap TypesMayAliasCache; - - using MemoryBehavior = SILInstruction::MemoryBehavior; - - AliasResult aliasAddressProjection(SILValue V1, SILValue V2, - SILValue O1, SILValue O2); - - /// Perform an alias query to see if V1, V2 refer to the same values. - AliasResult aliasInner(SILValue V1, SILValue V2, - SILType TBAAType1 = SILType(), - SILType TBAAType2 = SILType()); - - /// Returns True if memory of type \p T1 and \p T2 may alias. - bool typesMayAlias(SILType T1, SILType T2); - -public: - AliasAnalysis(SILModule *M) : - SILAnalysis(AnalysisKind::Alias), Mod(M), SEA(nullptr) {} - - static bool classof(const SILAnalysis *S) { - return S->getKind() == AnalysisKind::Alias; - } - - virtual void initialize(SILPassManager *PM); - - /// Perform an alias query to see if V1, V2 refer to the same values. - AliasResult alias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), - SILType TBAAType2 = SILType()); - - /// Convenience method that returns true if V1 and V2 must alias. - bool isMustAlias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), - SILType TBAAType2 = SILType()) { - return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::MustAlias; - } - - /// Convenience method that returns true if V1 and V2 partially alias. - bool isPartialAlias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), - SILType TBAAType2 = SILType()) { - return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::PartialAlias; - } - - /// Convenience method that returns true if V1, V2 can not alias. - bool isNoAlias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), - SILType TBAAType2 = SILType()) { - return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::NoAlias; - } - - /// Convenience method that returns true if V1, V2 may alias. - bool isMayAlias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), - SILType TBAAType2 = SILType()) { - return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::MayAlias; - } - - /// Use the alias analysis to determine the memory behavior of Inst with - /// respect to V. - /// - /// TODO: When ref count behavior is separated from generic memory behavior, - /// the InspectionMode flag will be unnecessary. - MemoryBehavior computeMemoryBehavior(SILInstruction *Inst, SILValue V, - RetainObserveKind); - - /// Returns true if \p Inst may read from memory in a manner that - /// affects V. - bool mayReadFromMemory(SILInstruction *Inst, SILValue V) { - auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::IgnoreRetains); - return B == MemoryBehavior::MayRead || - B == MemoryBehavior::MayReadWrite || - B == MemoryBehavior::MayHaveSideEffects; - } - - /// Returns true if \p Inst may write to memory in a manner that - /// affects V. - bool mayWriteToMemory(SILInstruction *Inst, SILValue V) { - auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::IgnoreRetains); - return B == MemoryBehavior::MayWrite || - B == MemoryBehavior::MayReadWrite || - B == MemoryBehavior::MayHaveSideEffects; - } - - /// Returns true if \p Inst may read or write to memory in a manner that - /// affects V. - bool mayReadOrWriteMemory(SILInstruction *Inst, SILValue V) { - auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::IgnoreRetains); - return MemoryBehavior::None != B; - } - - /// Returns true if Inst may have side effects in a manner that affects V. - bool mayHaveSideEffects(SILInstruction *Inst, SILValue V) { - auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::ObserveRetains); - return B == MemoryBehavior::MayWrite || - B == MemoryBehavior::MayReadWrite || - B == MemoryBehavior::MayHaveSideEffects; - } - - /// Returns true if Inst may have side effects in a manner that affects - /// V. This is independent of whether or not Inst may write to V and is meant - /// to encode notions such as ref count modifications. - bool mayHavePureSideEffects(SILInstruction *Inst, SILValue V) { - auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::ObserveRetains); - return MemoryBehavior::MayHaveSideEffects == B; - } - - virtual void invalidate(SILAnalysis::InvalidationKind K) { } - - virtual void invalidate(SILFunction *, SILAnalysis::InvalidationKind K) { - invalidate(K); - } -}; - -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, - AliasAnalysis::AliasResult R); - -/// If this value is an address that obeys strict TBAA, return the address type. -/// Otherwise, return an empty type. -SILType computeTBAAType(SILValue V); - -/// Check if \p V points to a let-member. -/// Nobody can write into let members. -bool isLetPointer(SILValue V); - -} // end namespace swift - -#endif diff --git a/include/swift/SILAnalysis/CFG.h b/include/swift/SILAnalysis/CFG.h deleted file mode 100644 index bd5e5235f1074..0000000000000 --- a/include/swift/SILAnalysis/CFG.h +++ /dev/null @@ -1,49 +0,0 @@ -//===--- CFG.h - Routines which analyze the CFG of a function ---*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SILANALYSIS_CFG_H -#define SWIFT_SILANALYSIS_CFG_H - -namespace llvm { - -template class TinyPtrVector; - -} // end namespace llvm - -namespace swift { - -class SILFunction; -class SILBasicBlock; - -/// Return true if we conservativly find all BB's that are non-failure exit -/// basic blocks and place them in \p BBs. If we find something we don't -/// understand, bail. -/// -/// A non-failure exit BB is defined as a BB that: -/// -/// 1. Has a return terminator. -/// 2. unreachable + noreturn terminator sequence. -/// -/// If we just have an unreachable without a noreturn call before it, we must -/// have a failure BB. -/// -/// We use a TinyPtrVector since in most cases this will only return one -/// SILBasicBlock since non-failure noreturn functions should not occur often -/// implying in most cases this will be one element. -/// -/// TODO: -bool findAllNonFailureExitBBs(SILFunction *F, - llvm::TinyPtrVector &BBs); - -} // end namespace swift - -#endif diff --git a/include/swift/SILAnalysis/CallGraph.h b/include/swift/SILAnalysis/CallGraph.h deleted file mode 100644 index 920e50f8e0a18..0000000000000 --- a/include/swift/SILAnalysis/CallGraph.h +++ /dev/null @@ -1,615 +0,0 @@ -//===------ CallGraph.h - The Call Graph Data Structure -------*- C++ -*--===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SIL_CALLGRAPH_H -#define SWIFT_SIL_CALLGRAPH_H - -#include "swift/Basic/ArrayRefView.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILInstruction.h" -#include "swift/SIL/SILWitnessTable.h" -#include "llvm/Support/Allocator.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/TinyPtrVector.h" -#include "llvm/Support/raw_ostream.h" -#include -#include - -namespace swift { - -static inline bool canHaveIndirectUses(SILFunction *F) { - if (F->isPossiblyUsedExternally()) - return true; - - // ObjC functions are called through the runtime and are therefore alive - // even if not referenced inside SIL. - if (canBeCalledIndirectly(F->getLoweredFunctionType()->getRepresentation())) - return true; - - return false; -} - -class CallGraphNode; - -class CallGraphEdge { - // FIXME: this should be private -public: - // TODO: Consider increasing SmallSize when we handle method calls. - typedef llvm::SmallSetVector CallGraphNodeSet; - typedef llvm::PointerIntPair CalleeSet; - -public: - // Representation of the callees that this call site can call into. - class Callees { - friend class CallGraphEdge; - - static SILFunction *getFunctionFromNode(CallGraphNode *const &Node); - - typedef llvm::PointerUnion CalleeStorage; - typedef ArrayRefView CalleeFunctionView; - - CalleeStorage TheCallees; - - explicit Callees(CallGraphNode *Node) : TheCallees(Node) {} - explicit Callees(CalleeSet TheCallees) : TheCallees(TheCallees) {} - - public: - CalleeFunctionView::iterator begin() const { - return getFunctionView().begin(); - } - - CalleeFunctionView::iterator end() const { - return getFunctionView().end(); - } - - bool canCallUnknownFunction() const { - if (TheCallees.is()) - return TheCallees.get().getInt(); - - if (TheCallees.get()) - return false; - - // We use nullptr to represent the case where we have no - // information about the callees. - return true; - } - - private: - CalleeFunctionView getFunctionView() const { - // Make a view over the entire callee set. - if (TheCallees.is()) { - auto *Set = TheCallees.get().getPointer(); - return llvm::makeArrayRef(Set->begin(), - Set->end()); - } - - auto *Node = TheCallees.get(); - // Create a singleton view. - if (Node) - return llvm::makeArrayRef(TheCallees.getAddrOfPtr1(), 1); - - // Create an empty view. - return llvm::makeArrayRef((CallGraphNode **) nullptr, 0); - } - }; - - - // The instruction that can result in a function call, which this - // edge represents. - SILInstruction *Inst; - - // The set of things we know this instruction can call into. - Callees CallsiteCallees; - - // A unique identifier for this edge based on the order in which it - // was created relative to other edges. - unsigned Ordinal; - -public: - /// Create a call graph edge for a call site with a single known - /// callee. - CallGraphEdge(SILInstruction *Inst, CallGraphNode *Node, unsigned Ordinal) - : Inst(Inst), CallsiteCallees(Node), Ordinal(Ordinal) { - assert(Node != nullptr && "Expected non-null callee node!"); - } - - /// Create a call graph edge for a call site for which we are not - /// currently able to determine the callees. - CallGraphEdge(SILInstruction *Inst, unsigned Ordinal) - : Inst(Inst), - CallsiteCallees((CallGraphNode *) nullptr), - Ordinal(Ordinal) { - } - - /// Create a call graph edge for a call site where we will fill in - /// the set of potentially called functions later. - CallGraphEdge(SILInstruction *Inst, CalleeSet KnownCallees, - unsigned Ordinal) - : Inst(Inst), - CallsiteCallees(KnownCallees), - Ordinal(Ordinal) { - } - - ~CallGraphEdge() { - } - - SILInstruction *getInstruction() const { return Inst; } - - /// Return the callee set. - CallGraphNodeSet getCalleeSet() const { - auto TheCallees = CallsiteCallees.TheCallees; - if (TheCallees.is()) - return *TheCallees.get().getPointer(); - - CallGraphNodeSet Result; - if (auto *Node = TheCallees.get()) { - assert(Node && - "Cannot get callee set for callsite with no known callees!"); - Result.insert(Node); - } - - return Result; - } - - Callees getCallees() const { - return CallsiteCallees; - } - - /// Return true if this edge represents a call that could reach an - /// unknown function with a matching signature. - bool canCallUnknownFunction() const { - return getCallees().canCallUnknownFunction(); - } - - /// The apply has a complete callee set, and it's of size one. In - /// other words we can replace its callee with a function_ref - /// regardless of what kind of instruction the callee is now. - bool hasSingleCallee() const { - return getSingleCalleeOrNull() != nullptr; - } - - /// Gets the single callee if the apply has one. - CallGraphNode *getSingleCalleeOrNull() const { - if (canCallUnknownFunction()) - return nullptr; - - if (CallsiteCallees.TheCallees.is()) - return CallsiteCallees.TheCallees.get(); - - auto CS = CallsiteCallees.TheCallees.get(); - if (CS.getPointer()->size() != 1) - return nullptr; - - return *CS.getPointer()->begin(); - } - - unsigned getOrdinal() const { - return Ordinal; - } - - void print(llvm::raw_ostream &OS, int Indent) const; - void dump(int Indent) const; - void dump() const; -}; - -class CallGraphNode { - /// The function represented by this call graph node. - SILFunction *Function; - - /// The call graph node ordinal within the SILModule. - const unsigned Ordinal; - - /// Edges representing the known call sites that could call into - /// this function. - /// - /// This is owned by the callgraph itself, not the callgraph node. - llvm::SmallPtrSet CallerEdges; - - /// Edges representing the call sites within this function. - /// - /// This is owned by the callgraph itself, not the callgraph node. - llvm::SmallPtrSet CalleeEdges; - - /// Do we know all the potential callers of this function? - bool CallerEdgesComplete; - -public: - friend class CallGraph; - - CallGraphNode(SILFunction *Function, unsigned Ordinal) - : Function(Function), Ordinal(Ordinal), - CallerEdgesComplete(!canHaveIndirectUses(Function)) { - assert(Function && - "Cannot build a call graph node with a null function pointer!"); - } - - ~CallGraphNode() = default; - - SILFunction *getFunction() const { - return Function; - } - - /// Get the known set of call graph edges that represent possible - /// calls into this function. - const llvm::SmallPtrSetImpl &getCallerEdges() const { - return CallerEdges; - } - - /// Get the set of call sites in this function. - const llvm::SmallPtrSetImpl &getCalleeEdges() const { - return CalleeEdges; - } - - /// Do we know that the set of call sites is complete - i.e. that - /// there is no other place that we can call from that can reach - /// this function? - bool isCallerEdgesComplete() const { - return CallerEdgesComplete; - } - - /// Is this call graph node for a function that we can trivially - /// know is dead? - bool isTriviallyDead() const { - return isCallerEdgesComplete() && getCallerEdges().empty(); - } - - unsigned getOrdinal() const { - return Ordinal; - } - - void print(llvm::raw_ostream &OS) const; - void dump() const; - -private: - /// Mark a set of callers as known to not be complete. - void markCallerEdgesIncomplete() { - CallerEdgesComplete = false; - } - - /// Add an edge representing a call site within this function. - void addCalleeEdge(CallGraphEdge *Edge) { - CalleeEdges.insert(Edge); - } - - /// Remove an edge representing a call site within this function. - void removeCalleeEdge(CallGraphEdge *Edge) { - assert(CalleeEdges.count(Edge) && "Expected edge to be in set!"); - CalleeEdges.erase(Edge); - } - - /// Add an edge representing a call site that calls into this function. - void addCallerEdge(CallGraphEdge *Edge) { - CallerEdges.insert(Edge); - } - - /// Remove an edge representing a call site that calls into this function. - void removeCallerEdge(CallGraphEdge *Edge) { - assert(CallerEdges.count(Edge) && "Expected edge to be in set!"); - CallerEdges.erase(Edge); - } -}; - -struct CallGraphSCC { - llvm::TinyPtrVector SCCNodes; -}; - -class CallGraph { - /// The module that this call graph belongs to. - SILModule &M; - - /// A map from a function to the function's node in the call graph. - llvm::DenseMap FunctionToNodeMap; - - /// A map from an instruction to its call edge in the call graph. - llvm::DenseMap InstToEdgeMap; - - /// A vector of SCCs in bottom up SCC order. - llvm::SmallVector BottomUpSCCOrder; - - /// A vector of functions in bottom up function order. - llvm::SmallVector BottomUpFunctionOrder; - - typedef llvm::DenseMap CalleeSetMap; - - /// Map from function decls for methods to sets of CallGraphNodes - /// representing functions that can be reached via that decl. - CalleeSetMap CalleeSetCache; - - /// An allocator used by the callgraph. - llvm::BumpPtrAllocator Allocator; - - /// Ordinal incremented for each node we add. - unsigned NodeOrdinal; - - /// Ordinal incremented for each edge we add. - unsigned EdgeOrdinal; - -public: -#ifndef NDEBUG - friend struct OrderedCallGraph; -#endif - - friend class CallGraphEditor; - - CallGraph(SILModule *M, bool completeModule); - ~CallGraph(); - - // Functions for getting bottom-up lists of SCCs or functions in the - // call graph. - ArrayRef getBottomUpSCCOrder() { - if (BottomUpSCCOrder.empty()) - computeBottomUpSCCOrder(); - - return BottomUpSCCOrder; - } - - /// Forces recomputation of the bottom-up function list. - void invalidateBottomUpFunctionOrder() { BottomUpFunctionOrder.clear(); } - - ArrayRef getBottomUpFunctionOrder() { - if (BottomUpFunctionOrder.empty()) - computeBottomUpFunctionOrder(); - - return BottomUpFunctionOrder; - } - - // Call graph queries on functions. - - /// Get the known set of call graph edges that represent possible - /// calls into a function. - const llvm::SmallPtrSetImpl & - getCallerEdges(SILFunction *F) const { - return getCallGraphNode(F)->getCallerEdges(); - } - - /// Do we know all the callers of this function? - bool allCallersKnown(SILFunction *F) const { - return getCallGraphNode(F)->isCallerEdgesComplete(); - } - - // Call graph queries on call sites. - - bool canCallUnknownFunction(SILInstruction *I) const { - auto *Edge = tryGetCallGraphEdge(I); - - // Passes that do not maintain the call graph may have applies - // without edges. In this case, return a conservative result. - if (!Edge) return true; - - return Edge->canCallUnknownFunction(); - } - - /// Return the callee set for the given call site. - CallGraphEdge::CallGraphNodeSet - getCalleeSet(SILInstruction *I) const { - return getCallGraphEdge(I)->getCalleeSet(); - } - - /// Return the callees for the given call site. - CallGraphEdge::Callees getCallees(SILInstruction *I) const { - return getCallGraphEdge(I)->getCallees(); - } - - /// Is this call site known to call exactly one single function? - bool hasSingleCallee(SILInstruction *I) const { - return getCallGraphEdge(I)->hasSingleCallee(); - } - - // Printing/dumping functionality. - - void print(llvm::raw_ostream &OS); - void printStats(llvm::raw_ostream &OS); - void dump(); - void dumpStats(); - - /// This function is meant for use from the debugger. You can just say 'call - /// CG->viewCG()' and a dot graph viewer window should pop up from the - /// program, displaying the call graph. This depends on there being a dot - /// graph viewer program, like 'graphviz', in your path. - void viewCG(); - - void verify() const; - - void verify(SILFunction *F) const; -private: - // Functions for editing an existing call graph. - - void addEdgesForInstruction(SILInstruction *I) { - addEdgesForInstruction(I, getCallGraphNode(I->getFunction())); - } - - /// Removes a node from the graph. The node must not have any - /// caller or callee edges. - void removeNode(CallGraphNode *Node); - - void removeEdgeFromFunction(CallGraphEdge *Edge, SILFunction *F); - void removeEdgesForInstruction(SILInstruction *I); - - // Query funtions for getting nodes and edges from the call graph. - - const CallGraphNode *getCallGraphNode(SILFunction *F) const { - return const_cast(this)->getCallGraphNode(F); - } - - CallGraphNode *getCallGraphNode(SILFunction *F) { - auto *CGN = tryGetCallGraphNode(F); - assert(CGN && "Expected call graph node for function!"); - return CGN; - } - - CallGraphEdge *getCallGraphEdge(SILInstruction *I) const { - return const_cast(this)->getCallGraphEdge(I); - } - - CallGraphEdge *getCallGraphEdge(SILInstruction *I) { - auto *Edge = tryGetCallGraphEdge(I); - assert(Edge && "Expected call graph edge for instruction!"); - - return Edge; - } - - CallGraphEdge *tryGetCallGraphEdge(SILInstruction *I) const { - return const_cast(this)->tryGetCallGraphEdge(I); - } - - CallGraphEdge *tryGetCallGraphEdge(SILInstruction *I) { - auto Found = InstToEdgeMap.find(I); - if (Found == InstToEdgeMap.end()) - return nullptr; - - assert(Found->second && "Unexpected null call graph edge in map!"); - return Found->second; - } - - CallGraphEdge::CalleeSet &getOrCreateCalleeSetForMethod(SILDeclRef Decl); - - CallGraphNode *tryGetCallGraphNode(SILFunction *F) const { - return const_cast(this)->tryGetCallGraphNode(F); - } - - CallGraphNode *tryGetCallGraphNode(SILFunction *F) { - auto Found = FunctionToNodeMap.find(F); - if (Found == FunctionToNodeMap.end()) - return nullptr; - - assert(Found->second && "Unexpected null call graph node in map!"); - return Found->second; - } - - CallGraphNode *getOrAddCallGraphNode(SILFunction *F) { - if (auto *CGN = tryGetCallGraphNode(F)) - return CGN; - return addCallGraphNode(F); - } - - void removeFunctionFromCalleeSets(SILFunction *F); - void computeMethodCallees(); - void computeClassMethodCalleesForClass(ClassDecl *CD); - void computeWitnessMethodCalleesForWitnessTable(SILWitnessTable &WTable); - - CallGraphNode *addCallGraphNode(SILFunction *F); - void addEdges(SILFunction *F); - CallGraphEdge *makeCallGraphEdgeForCallee(FullApplySite FAS, - SILValue Callee); - void addEdgesForInstruction(SILInstruction *I, CallGraphNode *CallerNode); - void clearBottomUpSCCOrder(); - void computeBottomUpSCCOrder(); - void computeBottomUpFunctionOrder(); -}; - -class CallGraphEditor { - CallGraph *CG; -public: - CallGraphEditor(CallGraph *CG) : CG(CG) {} - - void replaceApplyWithNew(FullApplySite Old, FullApplySite New); - void replaceApplyWithCallSites(FullApplySite Old, - llvm::SmallVectorImpl &NewCallSites); - - /// Detaches the call graph node from function \p Old and attaches it to - /// function \a New. - void moveNodeToNewFunction(SILFunction *Old, SILFunction *New); - - /// Removes all callee edges from function. - void removeAllCalleeEdgesFrom(SILFunction *F); - - /// Removes all caller edges from function. - void removeAllCallerEdgesFrom(SILFunction *F); - - /// Creates a new node for function \p F and adds callee edges for all - /// call sites in the function. - void addNewFunction(SILFunction *F) { - if (CG && !CG->tryGetCallGraphNode(F)) { - CG->addCallGraphNode(F); - CG->addEdges(F); - } - } - - /// Removes the call graph node of function \p F. The node may have any - /// adjacent caller or callee edges. - void removeCallGraphNode(SILFunction *F) { - if (CG) - CG->removeNode(CG->getCallGraphNode(F)); - } - - /// Removes edges for the instruction \p I. - void removeEdgesForInstruction(SILInstruction *I) { - if (CG) - CG->removeEdgesForInstruction(I); - } - - /// Checks which function(s) are called by instruction \p I and adds - /// edges to the call graph for it. - void addEdgesForInstruction(SILInstruction *I) { - if (CG) - CG->addEdgesForInstruction(I); - } - - /// Update uses of a changed apply site which is not a full apply - /// site. If a use is a full apply site, its call graph edge is - /// updated. - void updatePartialApplyUses(ApplySite AI); - - void addEdgesForFunction(SILFunction *F) { - if (CG) - CG->addEdges(F); - } - - void removeEdgeIfPresent(SILInstruction *I) { - if (CG) - if (auto *Edge = CG->tryGetCallGraphEdge(I)) - CG->removeEdgeFromFunction(Edge, I->getFunction()); - } - - /// Drops all references in function and removes the references to - /// instructions in the function from the call graph. - void dropAllReferences(SILFunction *F) { - F->dropAllReferences(); - - if (CG) { - removeAllCalleeEdgesFrom(F); - removeAllCallerEdgesFrom(F); - CG->removeFunctionFromCalleeSets(F); - } - } - - /// Erase the function from the module and any references to it from - /// the call graph. - void eraseFunction(SILFunction *F); -}; - -class CallGraphLinkerEditor { - CallGraph *CG; - - void callback(SILFunction *F) { - CallGraphEditor(CG).addEdgesForFunction(F); - } - -public: - CallGraphLinkerEditor(CallGraph *CG) : CG(CG) {} - - std::function getCallback() { - return std::bind(&CallGraphLinkerEditor::callback, this, - std::placeholders::_1); - } -}; - -} // end namespace swift - -#endif diff --git a/include/swift/SILAnalysis/CallGraphAnalysis.h b/include/swift/SILAnalysis/CallGraphAnalysis.h deleted file mode 100644 index 3dfebc1011248..0000000000000 --- a/include/swift/SILAnalysis/CallGraphAnalysis.h +++ /dev/null @@ -1,87 +0,0 @@ -//===--- CallGraphAnalysis.h - Analysis of the Call Graph ------*- C++ -*--===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SILANALYSIS_CALLGRAPHANALYSIS_H -#define SWIFT_SILANALYSIS_CALLGRAPHANALYSIS_H - -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/CallGraph.h" - -namespace swift { - -class SILFunction; -class SILModule; - -/// The Call Graph Analysis provides information about the call graph. -class CallGraphAnalysis : public SILAnalysis { - SILModule *M; - CallGraph *CG; - -public: - virtual ~CallGraphAnalysis() { - delete CG; - } - CallGraphAnalysis(SILModule *MM) : SILAnalysis(AnalysisKind::CallGraph), - M(MM), CG(nullptr) {} - - static bool classof(const SILAnalysis *S) { - return S->getKind() == AnalysisKind::CallGraph; - } - - bool haveCallGraph() { return CG; } - CallGraph *getCallGraphOrNull() { return CG; } - CallGraph &getCallGraph() { - assert(haveCallGraph() && "Expected constructed call graph!"); - return *CG; - } - - CallGraph &getOrBuildCallGraph() { - if (!CG) - CG = new CallGraph(M, false); - return *CG; - } - - virtual void invalidate(SILAnalysis::InvalidationKind K) { - bool invalidateCalls = K & InvalidationKind::Calls; - bool invalidateFuncs = K & InvalidationKind::Functions; - if (invalidateCalls || invalidateFuncs) { - delete CG; - CG = nullptr; - } - } - - virtual void invalidate(SILFunction *, SILAnalysis::InvalidationKind K) { - invalidate(K); - } - - virtual void verify() const { -#ifndef NDEBUG - // If we don't have a callgraph, return. - if (!CG) - return; - CG->verify(); -#endif - } - - virtual void verify(SILFunction *F) const { -#ifndef NDEBUG - // If we don't have a callgraph, return. - if (!CG) - return; - CG->verify(F); -#endif - } -}; - -} // end namespace swift - -#endif diff --git a/include/swift/SILAnalysis/SideEffectAnalysis.h b/include/swift/SILAnalysis/SideEffectAnalysis.h deleted file mode 100644 index 58ac0f9988f93..0000000000000 --- a/include/swift/SILAnalysis/SideEffectAnalysis.h +++ /dev/null @@ -1,359 +0,0 @@ -//===------ SideEffectAnalysis.h - SIL Side Effect Analysis -*- C++ -*-----===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SILANALYSIS_SIDEEFFECTANALYSIS_H_ -#define SWIFT_SILANALYSIS_SIDEEFFECTANALYSIS_H_ - -#include "swift/SIL/SILInstruction.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SILAnalysis/Analysis.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallVector.h" - -namespace swift { - -class BasicCalleeAnalysis; -class CallGraphAnalysis; -class CallGraph; - - -/// An enum to represent the kind of scan we perform when we calculate -/// side effects. -enum class RetainObserveKind {ObserveRetains, IgnoreRetains}; - -/// The SideEffectAnalysis provides information about side-effects of SIL -/// functions. Side-effect information is provided per function and includes: -/// Does the function read or write memory? Does the function retain or release -/// objects? etc. -/// For details see SideEffectAnalysis::FunctionEffects and -/// SideEffectAnalysis::Effects. -/// -/// The update and invalidation policy of this analysis is a little bit -/// different than for other analysis. When an optimization pass changes the -/// SIL, there should not be more side-effects on a function than before the -/// transformation. Therefore optimization passes do not _invalidate_ the -/// side-effect information, they may only make it more conservative. -/// For this reason, the invalidate function are no-ops. Instead the -/// UpdateSideEffects pass does recompute the analysis no certain points in the -/// optimization pipeline. This avoids updating the analysis too often. -class SideEffectAnalysis : public SILAnalysis { -public: - - using MemoryBehavior = SILInstruction::MemoryBehavior; - /// Set \p dest if \p src is set and return true if \p dest was not set - /// before. - static bool updateFlag(bool &dest, bool src) { - if (src && !dest) { - dest = src; - return true; - } - return false; - } - - /// Side-effect information for the function (global effects) or a specific - /// parameter of the function. See FunctionEffects. - class Effects { - bool Reads = false; - bool Writes = false; - bool Retains = false; - bool Releases = false; - - /// Sets the most conservative effects. - void setWorstEffects() { - Reads = true; - Writes = true; - Retains = true; - Releases = true; - } - - friend class SideEffectAnalysis; - - public: - - /// Does the function read from memory (excluding reads from locally - /// allocated memory)? - bool mayRead() const { return Reads; } - - /// Does the function write to memory (excluding writes to locally - /// allocated memory)? - bool mayWrite() const { return Writes; } - - /// Does the function retain objects (excluding retains of locally - /// allocated objects)? - bool mayRetain() const { return Retains; } - - /// Does the function release objects (excluding releases of locally - /// allocated objects)? - bool mayRelease() const { return Releases; } - - /// Gets the memory behavior considering the global effects and - /// all parameter effects. If \p ScanKind equals ignoreRetains then retain - /// instructions are considered as side effects. - MemoryBehavior getMemBehavior(RetainObserveKind ScanKind) const { - if (mayRelease()) - return MemoryBehavior::MayHaveSideEffects; - - if (ScanKind == RetainObserveKind::ObserveRetains && mayRetain()) - return MemoryBehavior::MayHaveSideEffects; - - if (mayWrite()) - return mayRead() ? MemoryBehavior::MayReadWrite : - MemoryBehavior::MayWrite; - - if (mayRead()) - return MemoryBehavior::MayRead; - - return MemoryBehavior::None; - } - - /// Merge effects from \p RHS. - bool mergeFrom(const Effects &RHS) { - bool Changed = false; - Changed |= updateFlag(Reads, RHS.Reads); - Changed |= updateFlag(Writes, RHS.Writes); - Changed |= updateFlag(Retains, RHS.Retains); - Changed |= updateFlag(Releases, RHS.Releases); - return Changed; - } - }; - - friend raw_ostream &operator<<(raw_ostream &os, - const SideEffectAnalysis::Effects &Effects) { - if (Effects.mayRead()) - os << 'r'; - if (Effects.mayWrite()) - os << 'w'; - if (Effects.mayRetain()) - os << '+'; - if (Effects.mayRelease()) - os << '-'; - return os; - } - - /// Summarizes the side-effects of a function. The side-effect information - /// is divided into global effects and effects for specific function - /// parameters. - /// If a side-effect can be associated to a specific function parameter, it is - /// not added to the global effects of the function. E.g. if a memory write is - /// only done through an @inout parameter, the mayWrite side-effect is only - /// accounted for this parameter. - /// Effects for a parameter make only sense if the parameter is implemented as - /// a pointer or contains a pointer: - /// *) The parameter is an address parameter, e.g. @out, @inout, etc. - /// *) The parameter is a reference - /// *) The parameter is a value type (e.g. struct) and contains a reference. - /// In this case the effects refer to all references in the value type. - /// E.g. if a struct contains 2 references, a mayWrite effect means that - /// memory is written to one of the referenced objects (or to both). - class FunctionEffects { - - /// Side-effects which can be associated to a parameter. - llvm::SmallVector ParamEffects; - - /// All other side-effects which cannot be associated to a parameter. - Effects GlobalEffects; - - /// Side-effects on locally allocated storage. Such side-effects are not - /// relevant to optimizations. The LocalEffects are only used to return - /// "something" for local storage in getEffectsOn(). - Effects LocalEffects; - - /// Does the function allocate objects, boxes, etc., i.e. everything which - /// has a reference count. - bool AllocsObjects = false; - - /// Can this function trap or exit the program in any way? - bool Traps = false; - - /// Does this function read a refernce count other than with retain or - /// release instructions, e.g. isUnique? - bool ReadsRC = false; - - /// Returns the effecs for an address or reference. This might be a - /// paramter, the LocalEffects or, if the value can not be associated to one - /// of them, the GlobalEffects. - Effects *getEffectsOn(SILValue Addr); - - FunctionEffects(unsigned numParams) : ParamEffects(numParams) { } - - /// Sets the most conservative effects, if we don't know anything about the - /// function. - void setWorstEffects() { - GlobalEffects.setWorstEffects(); - AllocsObjects = true; - Traps = true; - ReadsRC = true; - } - - /// Merge the flags from \p RHS. - bool mergeFlags(const FunctionEffects &RHS) { - bool Changed = false; - Changed |= updateFlag(Traps, RHS.Traps); - Changed |= updateFlag(AllocsObjects, RHS.AllocsObjects); - Changed |= updateFlag(ReadsRC, RHS.ReadsRC); - return Changed; - } - - friend class SideEffectAnalysis; - - public: - - /// Constructs "empty" function effects. - FunctionEffects() { } - - /// Does the function allocate objects, boxes, etc., i.e. everything which - /// has a reference count. - bool mayAllocObjects() const { return AllocsObjects; } - - /// Can this function trap or exit the program in any way? - bool mayTrap() const { return Traps; } - - /// Does this function read a refernce count other than with retain or - /// release instructions, e.g. isUnique? - bool mayReadRC() const { return ReadsRC; } - - /// Gets the memory behavior considering the global effects and - /// all parameter effects. If \p ScanKind equals ignoreRetains then retain - /// instructions are considered as side effects. - MemoryBehavior getMemBehavior(RetainObserveKind ScanKind) const; - - /// Get the global effects for the function. These are effects which cannot - /// be associated to a specific parameter, e.g. writes to global variables - /// or writes to unknown pointers. - const Effects &getGlobalEffects() const { return GlobalEffects; } - - /// Get the array of parameter effects. If a side-effect can be associated - /// to a specific parameter, it is contained here instead of the global - /// effects. - ArrayRef getParameterEffects() const { return ParamEffects; } - - /// Merge effects from \p RHS. - bool mergeFrom(const FunctionEffects &RHS); - - /// Merge effects from an apply site within the function. - bool mergeFromApply(const FunctionEffects &CalleeEffects, - FullApplySite FAS); - - /// Print the function effects. - void dump(); - }; - - friend raw_ostream &operator<<(raw_ostream &os, - const SideEffectAnalysis::FunctionEffects &Effects) { - os << "func=" << Effects.getGlobalEffects(); - int ParamIdx = 0; - for (auto &E : Effects.getParameterEffects()) { - os << ",param" << ParamIdx++ << "=" << E; - } - if (Effects.mayAllocObjects()) - os << ";alloc"; - if (Effects.mayTrap()) - os << ";trap"; - if (Effects.mayReadRC()) - os << ";readrc"; - return os; - } - -private: - /// The module being processed. - SILModule &M; - - /// All the side-effect information for the whole module. - llvm::DenseMap Function2Effects; - - /// The allocator for the map values in Function2Effects. - llvm::SpecificBumpPtrAllocator Allocator; - - /// Callee analysis, used for determining the callees at call sites. - BasicCalleeAnalysis *BCA; - - /// This analysis depends on the call graph. - CallGraphAnalysis *CGA; - - /// If false, nothing has changed between two recompute() calls. - bool shouldRecompute; - - typedef llvm::SetVector WorkListType; - - /// Get the side-effects of a function, which has an @effects attribute. - /// Returns true if \a F has an @effects attribute which could be handled. - static bool getDefinedEffects(FunctionEffects &Effects, SILFunction *F); - - /// Get the side-effects of a semantic call. - /// Return true if \a FAS is a semantic call which could be handled. - bool getSemanticEffects(FunctionEffects &Effects, FullApplySite FAS); - - /// Analyise the side-effects of a function. - /// If the side-effects changed, the callers are pushed onto the \a WorkList. - void analyzeFunction(SILFunction *F, WorkListType &WorkList, CallGraph &CG); - - /// Analyise the side-effects of a single SIL instruction. - void analyzeInstruction(FunctionEffects &Effects, SILInstruction *I); - - /// Get the side-effects of a call site. - void getEffectsOfApply(FunctionEffects &FE, FullApplySite FAS, - bool isRecomputing); - - /// Gets or creates FunctionEffects for \p F. If \a isRecomputing is true, - /// the effects are initialized with empty effects, otherwise with most - /// conservative effects. - FunctionEffects *getFunctionEffects(SILFunction *F, bool isRecomputing) { - auto *FE = Function2Effects[F]; - if (!FE) { - unsigned argSize = F->empty() ? 0 : F->getArguments().size(); - FE = new (Allocator.Allocate()) FunctionEffects(argSize); - Function2Effects[F] = FE; - if (!isRecomputing) - FE->setWorstEffects(); - } - return FE; - } - -public: - SideEffectAnalysis(SILModule *M) - : SILAnalysis(AnalysisKind::SideEffect), M(*M), CGA(nullptr), - shouldRecompute(true) {} - - static bool classof(const SILAnalysis *S) { - return S->getKind() == AnalysisKind::SideEffect; - } - - virtual void initialize(SILPassManager *PM); - - /// Recomputes the side-effect information for all functions the module. - void recompute(); - - /// Get the side-effects of a function. - const FunctionEffects &getEffects(SILFunction *F) { - auto *FE = getFunctionEffects(F, false); - return *FE; - } - - /// Get the side-effects of a call site. - void getEffects(FunctionEffects &FE, FullApplySite FAS); - - /// No invalidation is needed. See comment for SideEffectAnalysis. - virtual void invalidate(InvalidationKind K) { - shouldRecompute = true; - } - - /// No invalidation is needed. See comment for SideEffectAnalysis. - virtual void invalidate(SILFunction *F, InvalidationKind K) { - invalidate(K); - } -}; - -} // end namespace swift - -#endif - diff --git a/include/swift/SILAnalysis/ValueTracking.h b/include/swift/SILAnalysis/ValueTracking.h deleted file mode 100644 index f8d2d60a69990..0000000000000 --- a/include/swift/SILAnalysis/ValueTracking.h +++ /dev/null @@ -1,58 +0,0 @@ -//===-- ValueTracking.h - SIL Value Tracking Analysis ----------*- C++ -*--===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// -// This file contains routines which analyze chains of computations. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SILANALYSIS_VALUETRACKING_H -#define SWIFT_SILANALYSIS_VALUETRACKING_H - -#include "swift/SIL/SILInstruction.h" - -namespace swift { - -class SILValue; - -/// Strip off casts/indexing insts/address projections from V until there is -/// nothing left to strip. -SILValue getUnderlyingObject(SILValue V); - -/// Return true if the pointer is to a function-local object that never escapes -/// from the function. -bool isNonEscapingLocalObject(SILValue V); - -enum class IsZeroKind { - Zero, - NotZero, - Unknown -}; - -/// Check if the value \p Value is known to be zero, non-zero or unknown. -IsZeroKind isZeroValue(SILValue Value); - -/// Checks if a sign bit of a value is known to be set, not set or unknown. -/// Essentially, it is a simple form of a range analysis. -/// This approach is inspired by the corresponding implementation of -/// ComputeSignBit in LLVM's value tracking implementation. -/// It is planned to extend this approach to track all bits of a value. -/// Therefore it can be considered to be the beginning of a range analysis -/// infrastructure for the Swift compiler. -Optional computeSignBit(SILValue Value); - -/// Check if execution of a given builtin instruction can result in overflows. -/// Returns true of an overflow can happen. Otherwise returns false. -bool canOverflow(BuiltinInst *BI); - -} // end namespace swift - -#endif // SWIFT_SILANALYSIS_VALUETRACKING_H diff --git a/include/swift/SILAnalysis/ARCAnalysis.h b/include/swift/SILOptimizer/Analysis/ARCAnalysis.h similarity index 88% rename from include/swift/SILAnalysis/ARCAnalysis.h rename to include/swift/SILOptimizer/Analysis/ARCAnalysis.h index 2e484a4415bb0..4cc2cfe6aff69 100644 --- a/include/swift/SILAnalysis/ARCAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/ARCAnalysis.h @@ -1,8 +1,8 @@ -//===--------------- ARCAnalysis.h - SIL ARC Analysis ----*- C++ -*--------===// +//===--- ARCAnalysis.h - SIL ARC Analysis -----------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,9 +10,10 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_ARCANALYSIS_H -#define SWIFT_SILANALYSIS_ARCANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ARCANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_ARCANALYSIS_H +#include "swift/SIL/SILArgument.h" #include "swift/SIL/SILValue.h" #include "swift/SIL/SILBasicBlock.h" #include "llvm/ADT/SmallPtrSet.h" @@ -102,27 +103,32 @@ valueHasARCDecrementOrCheckInInstructionRange(SILValue Op, SILBasicBlock::iterator End, AliasAnalysis *AA); -/// Match a call to a trap BB with no ARC relevant side effects. -bool isARCInertTrapBB(SILBasicBlock *BB); - /// A class that attempts to match owned arguments and corresponding epilogue /// releases for a specific function. /// /// TODO: This really needs a better name. class ConsumedArgToEpilogueReleaseMatcher { +public: + enum class ExitKind { Return, Throw }; + +private: + SILFunction *F; + RCIdentityFunctionInfo *RCFI; + ExitKind Kind; llvm::SmallMapVector ArgInstMap; + bool HasBlock = false; public: - /// Default constructor: does not find matching releases, so - /// findMatchingReleases should be called explicitly. - ConsumedArgToEpilogueReleaseMatcher() { } /// Finds matching releases in the return block of the function \p F. - ConsumedArgToEpilogueReleaseMatcher(RCIdentityFunctionInfo *RCIA, - SILFunction *F); + ConsumedArgToEpilogueReleaseMatcher(RCIdentityFunctionInfo *RCFI, + SILFunction *F, + ExitKind Kind = ExitKind::Return); /// Finds matching releases in the provided block \p BB. - void findMatchingReleases(RCIdentityFunctionInfo *RCIA, SILBasicBlock *BB); + void findMatchingReleases(SILBasicBlock *BB); + + bool hasBlock() const { return HasBlock; } bool argumentHasRelease(SILArgument *Arg) const { return ArgInstMap.find(Arg) != ArgInstMap.end(); @@ -142,6 +148,16 @@ class ConsumedArgToEpilogueReleaseMatcher { return I->second; } + SILInstruction *releaseForArgument(SILValue V) const { + auto *Arg = dyn_cast(V); + if (!Arg) + return nullptr; + return releaseForArgument(Arg); + } + + /// Recompute the mapping from argument to consumed arg. + void recompute(); + bool isReleaseMatchedToArgument(SILInstruction *Inst) const { auto Pred = [&Inst](const std::pair &P) -> bool { @@ -201,6 +217,9 @@ class ReleaseTracker { /// FinalRelease. bool getFinalReleasesForValue(SILValue Value, ReleaseTracker &Tracker); +/// Match a call to a trap BB with no ARC relevant side effects. +bool isARCInertTrapBB(const SILBasicBlock *BB); + } // end namespace swift #endif diff --git a/include/swift/SILOptimizer/Analysis/AliasAnalysis.h b/include/swift/SILOptimizer/Analysis/AliasAnalysis.h new file mode 100644 index 0000000000000..769252ecc3de7 --- /dev/null +++ b/include/swift/SILOptimizer/Analysis/AliasAnalysis.h @@ -0,0 +1,342 @@ +//===--- AliasAnalysis.h - SIL Alias Analysis -------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ALIASANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_ALIASANALYSIS_H + +#include "swift/Basic/ValueEnumerator.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" +#include "llvm/ADT/DenseMap.h" + +using swift::RetainObserveKind; + +namespace { + /// A cache for AliasAnalysis. + /// This struct represents the argument list to the method 'alias'. + /// The two SILValue pointers are mapped to size_t indices because we need + /// an efficient way to invalidate them (the mechanism is described below). + /// The Type arguments are translated to void* because their + /// underlying storage is opaque pointers that never goes away. + struct AliasKeyTy { + // The SILValue pair: + size_t V1, V2; + unsigned ResultNo1, ResultNo2; + // The TBAAType pair: + void *T1, *T2; + }; + + /// A cache for MemoryBehavior Analysis. + /// The two SILValue pointers are mapped to size_t indices because we need + /// an efficient way to invalidate them (the mechanism is described below). + /// The RetainObserveKind represents the inspection mode for the memory + /// behavior analysis. + struct MemBehaviorKeyTy { + // The SILValue pair: + size_t V1, V2; + // V1 is a SILInstruction and therefore ResultNo is always 0. + unsigned ResultNo2; + RetainObserveKind InspectionMode; + }; +} + +namespace swift { + +class SILValue; +class SILInstruction; +class ValueBase; +class SideEffectAnalysis; +class EscapeAnalysis; + +/// This class is a simple wrapper around an alias analysis cache. This is +/// needed since we do not have an "analysis" infrastructure. +class AliasAnalysis : public SILAnalysis { +public: + + /// This enum describes the different kinds of aliasing relations between + /// pointers. + /// + /// NoAlias: There is never dependence between memory referenced by the two + /// pointers. Example: Two pointers pointing to non-overlapping + /// memory ranges. + /// + /// MayAlias: Two pointers might refer to the same memory location. + /// + /// + /// PartialAlias: The two memory locations are known to be overlapping + /// but do not start at the same address. + /// + /// + /// MustAlias: The two memory locations always start at exactly the same + /// location. The pointers are equal. + /// + enum class AliasResult : unsigned { + NoAlias=0, ///< The two values have no dependencies on each + /// other. + MayAlias, ///< The two values cannot be proven to alias or + /// not alias. Anything could happen. + PartialAlias, ///< The two values overlap in a partial manner. + MustAlias, ///< The two values are equal. + }; + +private: + SILModule *Mod; + SideEffectAnalysis *SEA; + EscapeAnalysis *EA; + + using TBAACacheKey = std::pair; + + /// A cache for the computation of TBAA. True means that the types may + /// alias. False means that the types must not alias. + /// + /// We don't need to invalidate this cache because type aliasing relations + /// never change. + llvm::DenseMap TypesMayAliasCache; + + /// AliasAnalysis value cache. + /// The alias() method uses this map to cache queries. + llvm::DenseMap AliasCache; + + using MemoryBehavior = SILInstruction::MemoryBehavior; + /// MemoryBehavior value cache. + /// The computeMemoryBehavior() method uses this map to cache queries. + llvm::DenseMap MemoryBehaviorCache; + + /// The AliasAnalysis cache can't directly map a pair of ValueBase pointers + /// to alias results because we'd like to be able to remove deleted pointers + /// without having to scan the whole map. So, instead of storing pointers we + /// map pointers to indices and store the indices. + ValueEnumerator AliasValueBaseToIndex; + + /// Same as AliasValueBaseToIndex, map a pointer to the indices for + /// MemoryBehaviorCache. + /// + /// NOTE: we do not use the same ValueEnumerator for the alias cache, + /// as when either cache is cleared, we can not clear the ValueEnumerator + /// because doing so could give rise to collisions in the other cache. + ValueEnumerator MemoryBehaviorValueBaseToIndex; + + AliasResult aliasAddressProjection(SILValue V1, SILValue V2, + SILValue O1, SILValue O2); + + /// Perform an alias query to see if V1, V2 refer to the same values. + AliasResult aliasInner(SILValue V1, SILValue V2, + SILType TBAAType1 = SILType(), + SILType TBAAType2 = SILType()); + + /// Returns True if memory of type \p T1 and \p T2 may alias. + bool typesMayAlias(SILType T1, SILType T2); + + virtual void handleDeleteNotification(ValueBase *I) override { + // The pointer I is going away. We can't scan the whole cache and remove + // all of the occurrences of the pointer. Instead we remove the pointer + // from the cache the translates pointers to indices. + AliasValueBaseToIndex.invalidateValue(I); + MemoryBehaviorValueBaseToIndex.invalidateValue(I); + } + + virtual bool needsNotifications() override { return true; } + + +public: + AliasAnalysis(SILModule *M) : + SILAnalysis(AnalysisKind::Alias), Mod(M), SEA(nullptr), EA(nullptr) {} + + static bool classof(const SILAnalysis *S) { + return S->getKind() == AnalysisKind::Alias; + } + + virtual void initialize(SILPassManager *PM) override; + + /// Perform an alias query to see if V1, V2 refer to the same values. + AliasResult alias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), + SILType TBAAType2 = SILType()); + + /// Convenience method that returns true if V1 and V2 must alias. + bool isMustAlias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), + SILType TBAAType2 = SILType()) { + return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::MustAlias; + } + + /// Convenience method that returns true if V1 and V2 partially alias. + bool isPartialAlias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), + SILType TBAAType2 = SILType()) { + return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::PartialAlias; + } + + /// Convenience method that returns true if V1, V2 cannot alias. + bool isNoAlias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), + SILType TBAAType2 = SILType()) { + return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::NoAlias; + } + + /// Convenience method that returns true if V1, V2 may alias. + bool isMayAlias(SILValue V1, SILValue V2, SILType TBAAType1 = SILType(), + SILType TBAAType2 = SILType()) { + return alias(V1, V2, TBAAType1, TBAAType2) == AliasResult::MayAlias; + } + + /// Use the alias analysis to determine the memory behavior of Inst with + /// respect to V. + /// + /// TODO: When ref count behavior is separated from generic memory behavior, + /// the InspectionMode flag will be unnecessary. + MemoryBehavior computeMemoryBehavior(SILInstruction *Inst, SILValue V, + RetainObserveKind); + + /// Use the alias analysis to determine the memory behavior of Inst with + /// respect to V. + /// + /// TODO: When ref count behavior is separated from generic memory behavior, + /// the InspectionMode flag will be unnecessary. + MemoryBehavior computeMemoryBehaviorInner(SILInstruction *Inst, SILValue V, + RetainObserveKind); + + /// Returns true if \p Inst may read from memory in a manner that + /// affects V. + bool mayReadFromMemory(SILInstruction *Inst, SILValue V) { + auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::IgnoreRetains); + return B == MemoryBehavior::MayRead || + B == MemoryBehavior::MayReadWrite || + B == MemoryBehavior::MayHaveSideEffects; + } + + /// Returns true if \p Inst may write to memory in a manner that + /// affects V. + bool mayWriteToMemory(SILInstruction *Inst, SILValue V) { + auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::IgnoreRetains); + return B == MemoryBehavior::MayWrite || + B == MemoryBehavior::MayReadWrite || + B == MemoryBehavior::MayHaveSideEffects; + } + + /// Returns true if \p Inst may read or write to memory in a manner that + /// affects V. + bool mayReadOrWriteMemory(SILInstruction *Inst, SILValue V) { + auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::IgnoreRetains); + return MemoryBehavior::None != B; + } + + /// Returns true if Inst may have side effects in a manner that affects V. + bool mayHaveSideEffects(SILInstruction *Inst, SILValue V) { + auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::ObserveRetains); + return B == MemoryBehavior::MayWrite || + B == MemoryBehavior::MayReadWrite || + B == MemoryBehavior::MayHaveSideEffects; + } + + /// Returns true if Inst may have side effects in a manner that affects + /// V. This is independent of whether or not Inst may write to V and is meant + /// to encode notions such as ref count modifications. + bool mayHavePureSideEffects(SILInstruction *Inst, SILValue V) { + auto B = computeMemoryBehavior(Inst, V, RetainObserveKind::ObserveRetains); + return MemoryBehavior::MayHaveSideEffects == B; + } + + /// Returns true if \p Ptr may be released in the function call \p FAS. + bool canApplyDecrementRefCount(FullApplySite FAS, SILValue Ptr); + + /// Returns true if \p Ptr may be released by the builtin \p BI. + bool canBuiltinDecrementRefCount(BuiltinInst *BI, SILValue Ptr); + + /// Encodes the alias query as a AliasKeyTy. + /// The parameters to this function are identical to the parameters of alias() + /// and this method serializes them into a key for the alias analysis cache. + AliasKeyTy toAliasKey(SILValue V1, SILValue V2, SILType Type1, SILType Type2); + + /// Encodes the memory behavior query as a MemBehaviorKeyTy. + MemBehaviorKeyTy toMemoryBehaviorKey(SILValue V1, SILValue V2, RetainObserveKind K); + + virtual void invalidate(SILAnalysis::InvalidationKind K) override { + AliasCache.clear(); + MemoryBehaviorCache.clear(); + } + + virtual void invalidate(SILFunction *, + SILAnalysis::InvalidationKind K) override { + invalidate(K); + } +}; + + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + AliasAnalysis::AliasResult R); + +/// If this value is an address that obeys strict TBAA, return the address type. +/// Otherwise, return an empty type. +SILType computeTBAAType(SILValue V); + +/// Check if \p V points to a let-member. +/// Nobody can write into let members. +bool isLetPointer(SILValue V); + +} // end namespace swift + +namespace llvm { + template <> struct llvm::DenseMapInfo { + static inline AliasKeyTy getEmptyKey() { + auto Allone = std::numeric_limits::max(); + return {Allone, Allone, 0xffff, 0xffff, nullptr, nullptr}; + } + static inline AliasKeyTy getTombstoneKey() { + auto Allone = std::numeric_limits::max(); + return {Allone, Allone, 0xff, 0xff, nullptr, nullptr}; + } + static unsigned getHashValue(const AliasKeyTy Val) { + unsigned H = 0; + H ^= DenseMapInfo::getHashValue(Val.V1); + H ^= DenseMapInfo::getHashValue(Val.V2); + H ^= DenseMapInfo::getHashValue(Val.ResultNo1); + H ^= DenseMapInfo::getHashValue(Val.ResultNo2); + H ^= DenseMapInfo::getHashValue(Val.T1); + H ^= DenseMapInfo::getHashValue(Val.T2); + return H; + } + static bool isEqual(const AliasKeyTy LHS, const AliasKeyTy RHS) { + return LHS.V1 == RHS.V1 && + LHS.V2 == RHS.V2 && + LHS.ResultNo1 == RHS.ResultNo1 && + LHS.ResultNo2 == RHS.ResultNo2 && + LHS.T1 == RHS.T1 && + LHS.T2 == RHS.T2; + } + }; + + template <> struct llvm::DenseMapInfo { + static inline MemBehaviorKeyTy getEmptyKey() { + auto Allone = std::numeric_limits::max(); + return {Allone, Allone, 0xffff, RetainObserveKind::RetainObserveKindEnd}; + } + static inline MemBehaviorKeyTy getTombstoneKey() { + auto Allone = std::numeric_limits::max(); + return {Allone, Allone, 0xff, RetainObserveKind::RetainObserveKindEnd}; + } + static unsigned getHashValue(const MemBehaviorKeyTy V) { + unsigned H = 0; + H ^= DenseMapInfo::getHashValue(V.V1); + H ^= DenseMapInfo::getHashValue(V.V2); + H ^= DenseMapInfo::getHashValue(V.ResultNo2); + H ^= DenseMapInfo::getHashValue(static_cast(V.InspectionMode)); + return H; + } + static bool isEqual(const MemBehaviorKeyTy LHS, + const MemBehaviorKeyTy RHS) { + return LHS.V1 == RHS.V1 && + LHS.V2 == RHS.V2 && + LHS.ResultNo2 == RHS.ResultNo2 && + LHS.InspectionMode == RHS.InspectionMode; + } + }; +} + +#endif diff --git a/include/swift/SILAnalysis/Analysis.def b/include/swift/SILOptimizer/Analysis/Analysis.def similarity index 87% rename from include/swift/SILAnalysis/Analysis.def rename to include/swift/SILOptimizer/Analysis/Analysis.def index dc3c06ca0cad9..5961180cb5bde 100644 --- a/include/swift/SILAnalysis/Analysis.def +++ b/include/swift/SILOptimizer/Analysis/Analysis.def @@ -1,8 +1,8 @@ -//===--- Analysis.def ----------------------------------------*- C++ -*----===// +//===--- Analysis.def -------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,7 +25,6 @@ ANALYSIS(Alias) ANALYSIS(BasicCallee) -ANALYSIS(CallGraph) ANALYSIS(ClassHierarchy) ANALYSIS(Destructor) ANALYSIS(Dominance) @@ -37,5 +36,6 @@ ANALYSIS(PostDominance) ANALYSIS(PostOrder) ANALYSIS(RCIdentity) ANALYSIS(SideEffect) +ANALYSIS(TypeExpansion) #undef ANALYSIS diff --git a/include/swift/SILAnalysis/Analysis.h b/include/swift/SILOptimizer/Analysis/Analysis.h similarity index 95% rename from include/swift/SILAnalysis/Analysis.h rename to include/swift/SILOptimizer/Analysis/Analysis.h index 8b7f74ba50d37..63d2975e4de74 100644 --- a/include/swift/SILAnalysis/Analysis.h +++ b/include/swift/SILOptimizer/Analysis/Analysis.h @@ -1,8 +1,8 @@ -//===-- Analysis.h - Swift Analysis ----------------------------*- C++ -*-===// +//===--- Analysis.h - Swift Analysis ---------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,10 +15,11 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "swift/SIL/Notifications.h" #include -#ifndef SWIFT_SILANALYSIS_ANALYSIS_H -#define SWIFT_SILANALYSIS_ANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_ANALYSIS_H namespace swift { class SILModule; @@ -26,7 +27,7 @@ namespace swift { class SILPassManager; /// The base class for all SIL-level analysis. - class SILAnalysis { + class SILAnalysis : public DeleteNotificationHandler { public: /// This is a list of values that allow passes to communicate to analysis /// which traits of the code were invalidated. Based on this information @@ -34,7 +35,7 @@ namespace swift { /// may refer to a specific function or to the whole module depending on /// the context in which it is used. enum InvalidationKind : unsigned { - /// The pass does not change anithing. + /// The pass does not change anything. Nothing = 0x0, /// The pass created, deleted or rearranged some instructions in a @@ -131,7 +132,7 @@ namespace swift { static void verifyFunction(SILFunction *F); }; - /// An abstract base class that implements the boiler plate of cacheing and + /// An abstract base class that implements the boiler plate of caching and /// invalidating analysis for specific functions. template class FunctionAnalysisBase : public SILAnalysis { diff --git a/include/swift/SILAnalysis/ArraySemantic.h b/include/swift/SILOptimizer/Analysis/ArraySemantic.h similarity index 80% rename from include/swift/SILAnalysis/ArraySemantic.h rename to include/swift/SILOptimizer/Analysis/ArraySemantic.h index 545b43009981a..31a7f6935a9f9 100644 --- a/include/swift/SILAnalysis/ArraySemantic.h +++ b/include/swift/SILOptimizer/Analysis/ArraySemantic.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_ARRAYSEMANTIC_H -#define SWIFT_SILANALYSIS_ARRAYSEMANTIC_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ARRAYSEMANTIC_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_ARRAYSEMANTIC_H #include "swift/SIL/SILInstruction.h" @@ -23,7 +23,6 @@ class DominanceInfo; /// of the called function. enum class ArrayCallKind { kNone = 0, - kArrayPropsIsNative, kArrayPropsIsNativeTypeChecked, kCheckSubscript, kCheckIndex, @@ -82,11 +81,11 @@ class ArraySemanticsCall { /// Get the index for operations that have one. SILValue getIndex() const; - /// Get the array.props.isNative argument. - SILValue getArrayPropertyIsNative() const; + /// Get the index as a constant if possible. + Optional getConstantIndex() const; - /// Get the array.props.needsElementTypeCheck argument. - SILValue getArrayPropertyNeedsTypeCheck() const; + /// Get the array.props.isNativeTypeChecked argument. + SILValue getArrayPropertyIsNativeTypeChecked() const; /// Get the count used for this array initialization. /// @@ -99,10 +98,26 @@ class ArraySemanticsCall { /// Returns SILValue() if this is not an array initialization call. SILValue getArrayValue() const; + /// Get the array element storage pointer returned by an array initialization + /// call. + /// + /// Returns SILValue() if this is not an array initialization call or the call + /// can't be parsed. + SILValue getArrayElementStoragePointer() const; + /// Remove the semantics call replacing it by a release of any @owned /// parameter. void removeCall(); + /// Replace a call to get_element by a value. + /// + /// Preconditions: + /// The value \p V must dominate this get_element call. + /// This must be a get_element call. + /// + /// Returns true on success, false otherwise. + bool replaceByValue(SILValue V); + /// Hoist the call to the insert point. void hoist(SILInstruction *InsertBefore, DominanceInfo *DT) { hoistOrCopy(InsertBefore, DT, false); @@ -116,7 +131,7 @@ class ArraySemanticsCall { /// Get the semantics call as an ApplyInst. operator ApplyInst *() const { return SemanticsCall; } - /// Is this an semantics call. + /// Is this a semantics call. operator bool() const { return SemanticsCall != nullptr; } /// Could this array be backed by an NSArray. diff --git a/include/swift/SILAnalysis/BasicCalleeAnalysis.h b/include/swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h similarity index 93% rename from include/swift/SILAnalysis/BasicCalleeAnalysis.h rename to include/swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h index 8a38dc0c196d8..51cd5d8417f88 100644 --- a/include/swift/SILAnalysis/BasicCalleeAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h @@ -1,8 +1,8 @@ -//===- BasicCalleeAnalysis.h - Determine callees per call site -*- C++ -*--===// +//===- BasicCalleeAnalysis.h - Determine callees per call site --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_BASICCALLEEANALYSIS_H -#define SWIFT_SILANALYSIS_BASICCALLEEANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_BASICCALLEEANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_BASICCALLEEANALYSIS_H -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" @@ -62,6 +62,9 @@ class CalleeList { } bool isIncomplete() const { return IsIncomplete; } + + /// Returns true if all callees are known and not external. + bool allCalleesVisible(); }; /// CalleeCache is a helper class that builds lists of potential diff --git a/include/swift/SILOptimizer/Analysis/BottomUpIPAnalysis.h b/include/swift/SILOptimizer/Analysis/BottomUpIPAnalysis.h new file mode 100644 index 0000000000000..dac6473ab2e01 --- /dev/null +++ b/include/swift/SILOptimizer/Analysis/BottomUpIPAnalysis.h @@ -0,0 +1,313 @@ +//===- BottomUpIPAnalysis.h - Bottom-up IP analysis base-class --*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file contains a base class for bottom-up interprocedural analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_BOTTOMUPIPANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_BOTTOMUPIPANALYSIS_H + +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SIL/SILInstruction.h" +#include "llvm/ADT/SmallVector.h" + +namespace swift { + +/// An abstract base class for interprocedural analysis which are computed in +/// bottom-up order of the call-graph. +/// It provides utilities for automatic invalidation and updating the analysis. +class BottomUpIPAnalysis : public SILAnalysis { + + /// Each update cycle gets a unique ID. + /// It is incremented for each recomputation of the analysis. + /// It is mainly used to check for invalid CallerEntries in + /// FunctionInfoBase::Callers (for details see there). + int CurrentUpdateID = 0; + +protected: + + template class FunctionInfoWorkList; + + /// An abstract base class for a \p FunctionInfo class, which stores the + /// analysis information for a function. + /// This base class stores the administrative information needed for + /// invalidation and updating the analysis. + /// In the following "this function" refers to the associated function. + template class FunctionInfoBase { + public: + + /// An entry in the caller list. + struct CallerEntry { + /// The caller function. + FunctionInfo *Caller; + + /// The apply-site. + FullApplySite FAS; + + /// Returns false, if the caller was invalidated since this entry had been + /// created. + bool isValid() const { return Caller->UpdateID == UpdateID; } + + private: + /// Used to check if the caller and its apply-site is still valid. + int UpdateID; + + CallerEntry(FunctionInfo *Caller, FullApplySite FAS, int UpdateID) : + Caller(Caller), FAS(FAS), UpdateID(UpdateID) { } + + friend class FunctionInfoBase; + }; + + private: + + /// The list of callers which must be invalidated if this function gets + /// invalidated. Note that the list may contain invalid entries for already + /// invalidated callers. Those entries are removed lazily in + /// removeInvalidCallers(). + /// The lazy removal of invalid entries avoids that we additionally need to + /// store a callee-set. Also it reduces the number of times we need to + /// iterate through the Callers (in case multiple caller functions are + /// invalidated at the same time). + /// Note that Callers can't be a pure hashed set-like container because the + /// iteration order must be deterministic. + llvm::SmallVector Callers; + + /// In which update-cycle the analysis was computed for this function. + /// A 0-value means that the analysis for this function was not computed + /// yet or got invalidated. + int UpdateID = 0; + + /// Special states for StateAndPosition. + enum { + NotVisited = -2, + Visited = -1, + FirstPosition = 0 + }; + + /// The position in the function schedule, or if not scheduled yet, any of + /// the special states. + /// This field is only used during recomputation. + int StateAndPosition = NotVisited; + + /// How many callees are not in the function schedule yet. + /// This field is only used during recomputation. + int numUnscheduledCallees = 0; + + + /// Removes invalid caller entries. + void removeInvalidCallers() { + Callers.erase(std::remove_if(Callers.begin(), Callers.end(), + [](const CallerEntry &E) { + return !E.isValid(); + }), Callers.end()); + } + + friend class FunctionInfoWorkList; + friend class BottomUpIPAnalysis; + + public: + + /// Returns true if the analysis data for this function is computed and + /// up-to-date. + bool isValid() const { return UpdateID != 0; } + + /// Returns true if this function was already visited during recomputation. + bool isVisited() const { return StateAndPosition >= Visited; } + + /// Returns true if this function is already scheduled in the bottom-up + /// order during recomputation. + bool isScheduled() const { return StateAndPosition >= FirstPosition; } + + /// Returns true if this function is scheduled after \p RHS in the bottom-up + /// order, i.e. is considered as a "caller" of \p RHS. + bool isScheduledAfter(const FunctionInfo *RHS) const { + assert(isScheduled() && RHS->isScheduled() && + "operating with unscheduled functions?"); + return StateAndPosition > RHS->StateAndPosition; + } + + /// Returns the list of caller-entries. + ArrayRef getCallers() const { return Callers; } + + /// Adds a caller for this function. + void addCaller(FunctionInfo *CallerInfo, FullApplySite FAS) { + Callers.push_back(CallerEntry(CallerInfo, FAS, CallerInfo->UpdateID)); + if (!isScheduled()) + ++CallerInfo->numUnscheduledCallees; + } + }; + + /// Computes and stores a bottom-up function order. + template class BottomUpFunctionOrder { + + typedef llvm::SmallVector FunctionInfoList; + + /// The final bottom-up function order. + FunctionInfoList Scheduled; + + /// Functions which are not initially scheduled in the bottom-up order. + FunctionInfoList InitiallyUnscheduled; + + /// The number of visited functions. + unsigned numVisited = 0; + + /// The BottomUpIPAnalysis::CurrentUpdateID. + int CurrentUpdateID; + + public: + + /// The constructor. The \p CurrentUpdateID is the + /// BottomUpIPAnalysis::CurrentUpdateID. + BottomUpFunctionOrder(int CurrentUpdateID) : + CurrentUpdateID(CurrentUpdateID) { + assert(CurrentUpdateID > 0 && "did not allocate an UpdateID"); + } + + ~BottomUpFunctionOrder() { + assert(InitiallyUnscheduled.size() == 0 && + "not finished scheduling"); + assert(Scheduled.size() == numVisited && + "missed some functions to schedule"); + for (FunctionInfo *FInfo : Scheduled) { + assert(FInfo->isScheduled() && + "function not scheduled at the end of recomputation"); + assert(FInfo->numUnscheduledCallees == 0 && + "something basic is broken in scheduling"); + assert(FInfo->isValid() && + "function not recomputed at the end of recomputation"); + FInfo->StateAndPosition = FunctionInfoBase::NotVisited; + } + } + + /// Returns the begin of the bottom-up function order. + typename FunctionInfoList::const_iterator begin() const { + return Scheduled.begin(); + } + + /// Returns the end of the bottom-up function order. + typename FunctionInfoList::const_iterator end() const { + return Scheduled.end(); + } + + /// Returns true if the analysis for \p FInfo was recomputed during the + /// current update-cycle. + bool wasRecomputedWithCurrentUpdateID(FunctionInfo *FInfo) { + return FInfo->UpdateID == CurrentUpdateID; + } + + /// Should be called when first visiting \p FInfo during recomputation. + /// Returns true if the analysis is still valid for \p FInfo and doesn't + /// need to be recomputed. + bool prepareForVisiting(FunctionInfo *FInfo) { + assert(!FInfo->isVisited() && + "function visited multiple times"); + assert(FInfo->numUnscheduledCallees == 0 && + "already added callees at the begin of visiting a function"); + numVisited++; + FInfo->StateAndPosition = FunctionInfoBase::Visited; + if (FInfo->isValid()) { + // Now it's good time to remove invalid caller entries. + // Note: we don't have to do this for function which are recomputed. + FInfo->removeInvalidCallers(); + return true; + } + InitiallyUnscheduled.push_back(FInfo); + // Set to valid. + FInfo->UpdateID = CurrentUpdateID; + return false; + } + + /// Tries to schedule \p FInfo onto the bottom-up function order. + /// This succeeds if \p FInfo does not have any unscheduled callees. + /// Should be called after visiting \p FInfo during recomputation. + void tryToSchedule(FunctionInfo *FInfo) { + assert(FInfo->isVisited() && + "tried to schedule function which was not visited"); + assert(!FInfo->isScheduled() && + "function scheduled multiple times"); + if (FInfo->numUnscheduledCallees == 0) { + FInfo->StateAndPosition = (int)Scheduled.size(); + Scheduled.push_back(FInfo); + return; + } + assert(wasRecomputedWithCurrentUpdateID(FInfo) && + "not recomputed function cannot have unscheduled callees"); + } + + /// Finishes the bottom-up function schedule. + void finishScheduling() { + unsigned Idx = 0; + bool NeedAnotherIteration = false; + do { + /// Schedule all functions we can. + while (Idx < Scheduled.size()) { + FunctionInfo *FInfo = Scheduled[Idx++]; + for (const auto &E : FInfo->Callers) { + if (E.Caller->isVisited() && !E.Caller->isScheduled()) { + E.Caller->numUnscheduledCallees--; + tryToSchedule(E.Caller); + } + } + } + NeedAnotherIteration = false; + // Check if there are still unscheduled functions, which means that + // there is a cycle in the call graph. + while (!InitiallyUnscheduled.empty()) { + FunctionInfo *FInfo = InitiallyUnscheduled.pop_back_val(); + if (!FInfo->isScheduled()) { + // Break the cycle by scheduling the first unscheduled node we + // found. + FInfo->numUnscheduledCallees = 0; + tryToSchedule(FInfo); + assert(FInfo->isScheduled() && + "really, we should be able to schedule this function"); + NeedAnotherIteration = true; + break; + } + } + } while (NeedAnotherIteration); + } + }; + + BottomUpIPAnalysis(AnalysisKind K) : SILAnalysis(K) { } + + /// Increments the CurrentUpdateID. + /// Should be called at the beginning of a recomputation. + void allocNewUpdateID() { ++CurrentUpdateID; } + + /// Returns the ID of the current update-cycle. + int getCurrentUpdateID() const { return CurrentUpdateID; } + + /// Invalidates \p FInfo, including all analysis data which depend on it, i.e. + /// the callers. + template + void invalidateIncludingAllCallers(FunctionInfo *FInfo) { + llvm::SmallVector WorkList; + WorkList.push_back(FInfo); + + while (!WorkList.empty()) { + FunctionInfo *FInfo = WorkList.pop_back_val(); + for (const auto &E : FInfo->Callers) { + if (E.isValid() && E.Caller->isValid()) + WorkList.push_back(E.Caller); + } + FInfo->clear(); + FInfo->Callers.clear(); + FInfo->UpdateID = 0; + } + } +}; + +} // end namespace swift + +#endif // SWIFT_SILOPTIMIZER_ANALYSIS_BOTTOMUPIPANALYSIS_H diff --git a/include/swift/SILOptimizer/Analysis/CFG.h b/include/swift/SILOptimizer/Analysis/CFG.h new file mode 100644 index 0000000000000..6e3c3cc38e772 --- /dev/null +++ b/include/swift/SILOptimizer/Analysis/CFG.h @@ -0,0 +1,49 @@ +//===--- CFG.h - Routines which analyze the CFG of a function ---*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_CFG_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_CFG_H + +namespace llvm { + +template class TinyPtrVector; + +} // end namespace llvm + +namespace swift { + +class SILFunction; +class SILBasicBlock; + +/// Return true if we conservatively find all BB's that are non-failure exit +/// basic blocks and place them in \p BBs. If we find something we don't +/// understand, bail. +/// +/// A non-failure exit BB is defined as a BB that: +/// +/// 1. Has a return terminator. +/// 2. unreachable + noreturn terminator sequence. +/// +/// If we just have an unreachable without a noreturn call before it, we must +/// have a failure BB. +/// +/// We use a TinyPtrVector since in most cases this will only return one +/// SILBasicBlock since non-failure noreturn functions should not occur often +/// implying in most cases this will be one element. +/// +/// TODO: +bool findAllNonFailureExitBBs(SILFunction *F, + llvm::TinyPtrVector &BBs); + +} // end namespace swift + +#endif diff --git a/include/swift/SILAnalysis/ClassHierarchyAnalysis.h b/include/swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h similarity index 86% rename from include/swift/SILAnalysis/ClassHierarchyAnalysis.h rename to include/swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h index 846f66be8c5ed..602ad92687c81 100644 --- a/include/swift/SILAnalysis/ClassHierarchyAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h @@ -1,8 +1,8 @@ -//===-- ClassHierarchyAnalysis.h - Analysis of Class Hierarchy --*- C++ -*-===// +//===--- ClassHierarchyAnalysis.h - Analysis of Class Hierarchy -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_CLASSHIERARCHY_H -#define SWIFT_SILANALYSIS_CLASSHIERARCHY_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_CLASSHIERARCHY_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_CLASSHIERARCHY_H -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILValue.h" #include "llvm/ADT/SmallVector.h" @@ -21,8 +21,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Debug.h" -using namespace llvm; - namespace swift { class SILModule; @@ -32,7 +30,8 @@ class ClassHierarchyAnalysis : public SILAnalysis { typedef SmallVector ClassList; typedef SmallPtrSet ClassSet; typedef SmallVector NominalTypeList; - typedef DenseMap ProtocolImplementations; + typedef llvm::DenseMap + ProtocolImplementations; ClassHierarchyAnalysis(SILModule *Mod) : SILAnalysis(AnalysisKind::ClassHierarchy), M(Mod) { @@ -101,10 +100,10 @@ class ClassHierarchyAnalysis : public SILAnalysis { SILModule *M; /// A cache that maps a class to all of its known direct subclasses. - DenseMap DirectSubclassesCache; + llvm::DenseMap DirectSubclassesCache; /// A cache that maps a class to all of its known indirect subclasses. - DenseMap IndirectSubclassesCache; + llvm::DenseMap IndirectSubclassesCache; /// A cache that maps a protocol to all of its known implementations. ProtocolImplementations ProtocolImplementationsCache; diff --git a/include/swift/SILAnalysis/ColdBlockInfo.h b/include/swift/SILOptimizer/Analysis/ColdBlockInfo.h similarity index 83% rename from include/swift/SILAnalysis/ColdBlockInfo.h rename to include/swift/SILOptimizer/Analysis/ColdBlockInfo.h index a468c63853055..e75f53f8f1cb2 100644 --- a/include/swift/SILAnalysis/ColdBlockInfo.h +++ b/include/swift/SILOptimizer/Analysis/ColdBlockInfo.h @@ -1,8 +1,8 @@ -//===-- ColdBlocks.h - Fast/slow path analysis for the SIL CFG -*- C++ -*--===// +//===--- ColdBlockInfo.h - Fast/slow path analysis for SIL CFG --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_COLDBLOCKS_H -#define SWIFT_SILANALYSIS_COLDBLOCKS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_COLDBLOCKS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_COLDBLOCKS_H #include "llvm/ADT/DenseMap.h" diff --git a/include/swift/SILAnalysis/DestructorAnalysis.h b/include/swift/SILOptimizer/Analysis/DestructorAnalysis.h similarity index 79% rename from include/swift/SILAnalysis/DestructorAnalysis.h rename to include/swift/SILOptimizer/Analysis/DestructorAnalysis.h index 64be474b69265..fa9f8a2444c2f 100644 --- a/include/swift/SILAnalysis/DestructorAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/DestructorAnalysis.h @@ -1,19 +1,19 @@ -//===--- DestructorAnalysis.h ------------------------------*- C++ -*------===// +//===--- DestructorAnalysis.h -----------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_DESTRUCTORANALYSIS_H -#define SWIFT_SILANALYSIS_DESTRUCTORANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_DESTRUCTORANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_DESTRUCTORANALYSIS_H #include "swift/SIL/SILValue.h" -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "llvm/ADT/DenseMap.h" namespace swift { diff --git a/include/swift/SILAnalysis/DominanceAnalysis.h b/include/swift/SILOptimizer/Analysis/DominanceAnalysis.h similarity index 87% rename from include/swift/SILAnalysis/DominanceAnalysis.h rename to include/swift/SILOptimizer/Analysis/DominanceAnalysis.h index 6048e4073d494..f4a85cccf6b69 100644 --- a/include/swift/SILAnalysis/DominanceAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/DominanceAnalysis.h @@ -1,8 +1,8 @@ -//===--- DominanceAnalysis.h - SIL Dominance Analysis -*- C++ -*-----------===// +//===--- DominanceAnalysis.h - SIL Dominance Analysis -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,12 +10,12 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_DOMINANCEANALYSIS_H -#define SWIFT_SILANALYSIS_DOMINANCEANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_DOMINANCEANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_DOMINANCEANALYSIS_H #include "swift/SIL/SILInstruction.h" #include "swift/SIL/Dominance.h" -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "llvm/ADT/DenseMap.h" namespace swift { diff --git a/include/swift/SILAnalysis/EscapeAnalysis.h b/include/swift/SILOptimizer/Analysis/EscapeAnalysis.h similarity index 76% rename from include/swift/SILAnalysis/EscapeAnalysis.h rename to include/swift/SILOptimizer/Analysis/EscapeAnalysis.h index 25936b48a1675..1e06023e79b23 100644 --- a/include/swift/SILAnalysis/EscapeAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/EscapeAnalysis.h @@ -1,8 +1,8 @@ -//===----------- EscapeAnalysis.h - SIL Escape Analysis -*- C++ -*---------===// +//===--- EscapeAnalysis.h - SIL Escape Analysis -----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,12 +10,12 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_ESCAPEANALYSIS_H_ -#define SWIFT_SILANALYSIS_ESCAPEANALYSIS_H_ +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ESCAPEANALYSIS_H_ +#define SWIFT_SILOPTIMIZER_ANALYSIS_ESCAPEANALYSIS_H_ #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILFunction.h" -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/BottomUpIPAnalysis.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" @@ -26,15 +26,9 @@ struct CGForDotView; namespace swift { class BasicCalleeAnalysis; -class CallGraphAnalysis; -class CallGraph; /// The EscapeAnalysis provides information if the lifetime of an object exceeds /// the scope of a function. -/// The analysis is done intra- and interprocedural. The intraprocedural -/// analysis is updated on the fly based on the usual invalidation mechanism. -/// The interprocedural analysis is explicitly updated at some points in the -/// pass pipeline by the UpdateSideEffects pass. /// /// We compute the escape analysis by building a connection graph for each /// function. For the interprocedural analysis the connection graphs are merged @@ -42,7 +36,7 @@ class CallGraph; /// The idea is based on "Escape analysis for Java." by J.-D. Choi, M. Gupta, M. /// Serrano, V. C. Sreedhar, and S. Midkiff /// http://dx.doi.org/10.1145/320384.320386 -class EscapeAnalysis : public SILAnalysis { +class EscapeAnalysis : public BottomUpIPAnalysis { /// The types of edges in the connection graph. /// Escape information is propagated along edges in the connection graph: @@ -72,7 +66,7 @@ class EscapeAnalysis : public SILAnalysis { /// Represents the "memory content" to which a pointer points to. /// The "content" represents all stored properties of the referenced object. - /// We also treat the elements of a referece-counted object as a "content" + /// We also treat the elements of a reference-counted object as a "content" /// of that object. Although ref_element_addr is just a pointer addition, we /// treat it as a "pointer" pointing to the elements. Having this additional /// indirection in the graph, we avoid letting a reference escape just @@ -124,7 +118,7 @@ class EscapeAnalysis : public SILAnalysis { /// pointer points to (see NodeType). class CGNode { - /// The associated value in the functino. It is only used for debug printing. + /// The associated value in the function. It is only used for debug printing. /// There may be multiple nodes associated to the same value, e.g. a Content /// node has the same V as its points-to predecessor. ValueBase *V; @@ -164,7 +158,7 @@ class EscapeAnalysis : public SILAnalysis { bool isInWorkList = false; /// True if the merge is finished (see mergeTo). In this state this node - /// is completly unlinked from the graph, + /// is completely unlinked from the graph, bool isMerged = false; /// The type of the node (mainly distinguishes between content and value @@ -198,7 +192,7 @@ class EscapeAnalysis : public SILAnalysis { } /// Finds a successor node in the outgoing defer edges. - llvm::SmallVectorImpl::iterator findDefered(CGNode *Def) { + llvm::SmallVectorImpl::iterator findDeferred(CGNode *Def) { return std::find(defersTo.begin(), defersTo.end(), Def); } @@ -215,7 +209,7 @@ class EscapeAnalysis : public SILAnalysis { } /// Adds a defer-edge to another node \p To. Not done if \p To is this node. - bool addDefered(CGNode *To) { + bool addDeferred(CGNode *To) { assert(!To->isMerged); if (To == this) return false; @@ -283,11 +277,29 @@ class EscapeAnalysis : public SILAnalysis { /// Returns the escape state. EscapeState getEscapeState() const { return State; } - /// Returns true if the node's value escapes from its function. + /// Returns true if the node's value escapes within the function or via + /// the return instruction. bool escapes() const { return getEscapeState() != EscapeState::None; } + + /// Returns true if the node's value escapes within the function. This + /// means that any unidentified pointer in the function may alias to + /// the node's value. + /// Note that in the false-case the node's value can still escape via + /// the return instruction. + bool escapesInsideFunction(bool isNotAliasingArgument) const { + switch (getEscapeState()) { + case EscapeState::None: + case EscapeState::Return: + return false; + case EscapeState::Arguments: + return !isNotAliasingArgument; + case EscapeState::Global: + return true; + } + } }; - /// Mapping from nodes in a calleee-graph to nodes in a caller-graph. + /// Mapping from nodes in a callee-graph to nodes in a caller-graph. class CGNodeMap { /// The map itself. llvm::DenseMap Map; @@ -329,7 +341,7 @@ class EscapeAnalysis : public SILAnalysis { /// 2) A node can only have a single outgoing points-to edge (is enforced by /// CGNode::pointsTo being a single pointer and not a vector). /// 3) The target of a points-to edge must be a Content node. - /// 4) For any node N, all pathes starting at N which consist of only + /// 4) For any node N, all paths starting at N which consist of only /// defer-edges and a single trailing points-to edge must lead to the same /// Content node. class ConnectionGraph { @@ -356,9 +368,6 @@ class EscapeAnalysis : public SILAnalysis { /// Mapping of use points to bit indices in CGNode::UsePoints. llvm::DenseMap UsePoints; - /// True if the CGNode::UsePoints are computed. - bool UsePointsComputed = false; - /// The allocator for nodes. llvm::SpecificBumpPtrAllocator NodeAllocator; @@ -366,6 +375,11 @@ class EscapeAnalysis : public SILAnalysis { ConnectionGraph(SILFunction *F) : F(F) { } + /// Returns true if the connection graph is empty. + bool isEmpty() { + return Values2Nodes.empty() && Nodes.empty() && UsePoints.empty(); + } + /// Removes all nodes from the graph. void clear(); @@ -417,7 +431,12 @@ class EscapeAnalysis : public SILAnalysis { /// taken. This means the node is always created for the "outermost" value /// where V is contained. /// Returns null, if V is not a "pointer". - CGNode *getOrCreateNode(ValueBase *V); + CGNode *getNode(ValueBase *V, EscapeAnalysis *EA, bool createIfNeeded = true); + + /// Gets or creates a node for a SILValue (same as above). + CGNode *getNode(SILValue V, EscapeAnalysis *EA) { + return getNode(V.getDef(), EA, true); + } /// Gets or creates a content node to which \a AddrNode points to. CGNode *getContentNode(CGNode *AddrNode); @@ -438,7 +457,7 @@ class EscapeAnalysis : public SILAnalysis { /// Returns the node of the "exact" value \p V (no projections are skipped) /// if one exists. - CGNode *getNodeOrNull(ValueBase *V) { + CGNode *lookupNode(ValueBase *V) { CGNode *Node = Values2Nodes.lookup(V); if (Node) return Node->getMergeTarget(); @@ -481,7 +500,6 @@ class EscapeAnalysis : public SILAnalysis { bool defer(CGNode *From, CGNode *To) { bool EdgeAdded = addDeferEdge(From, To); mergeAllScheduledNodes(); - verify(); return EdgeAdded; } @@ -492,6 +510,14 @@ class EscapeAnalysis : public SILAnalysis { /// Propagates the escape states through the graph. void propagateEscapeStates(); + /// Removes a value from the graph. + /// It does not delete its node but makes sure that the value cannot be + /// lookup-up with getNode() anymore. + void removeFromGraph(ValueBase *V) { Values2Nodes.erase(V); } + + /// Returns true if there is a path from \p From to \p To. + bool isReachable(CGNode *From, CGNode *To); + public: /// Gets or creates a node for a value \p V. @@ -499,18 +525,19 @@ class EscapeAnalysis : public SILAnalysis { /// taken. This means the node is always created for the "outermost" value /// where V is contained. /// Returns null, if V is not a "pointer". - CGNode *getNode(ValueBase *V, EscapeAnalysis *EA); + CGNode *getNodeOrNull(ValueBase *V, EscapeAnalysis *EA) { + return getNode(V, EA, false); + } /// Gets or creates a node for a SILValue (same as above). - CGNode *getNode(SILValue V, EscapeAnalysis *EA) { - return getNode(V.getDef(), EA); + CGNode *getNodeOrNull(SILValue V, EscapeAnalysis *EA) { + return getNode(V.getDef(), EA, false); } /// Returns the number of use-points of a node. int getNumUsePoints(CGNode *Node) { assert(!Node->escapes() && "Use points are only valid for non-escaping nodes"); - computeUsePoints(); return Node->UsePoints.count(); } @@ -552,13 +579,8 @@ class EscapeAnalysis : public SILAnalysis { private: - enum { - /// A limit for the interprocedural algorithm. - MaxGraphMerges = 4 - }; - /// All the information we keep for a function. - struct FunctionInfo { + struct FunctionInfo : public FunctionInfoBase { FunctionInfo(SILFunction *F) : Graph(F), SummaryGraph(F) { } /// The connection graph for the function. This is what clients of the @@ -572,15 +594,29 @@ class EscapeAnalysis : public SILAnalysis { /// when explicitly calling recompute(). ConnectionGraph SummaryGraph; - /// The callsites from which we have to merge the callee graphs. - llvm::SmallVector KnownCallees; - /// If true, at least one of the callee graphs has changed. We have to merge /// them again. - bool NeedMergeCallees = false; + bool NeedUpdateSummaryGraph = true; + + /// Clears the analysis data on invalidation. + void clear() { + Graph.clear(); + SummaryGraph.clear(); + } + }; + + typedef BottomUpFunctionOrder FunctionOrder; - /// True if the Graph is valid. - bool Valid = false; + enum { + /// The maximum call-graph recursion depth for recomputing the analysis. + /// This is a relatively small number to reduce compile time in case of + /// large cycles in the call-graph. + /// In case of no cycles, we should not hit this limit at all because the + /// pass manager processes functions in bottom-up order. + MaxRecursionDepth = 3, + + /// A limit for the number of call-graph iterations in recompute(). + MaxGraphMerges = 4 }; /// The connection graphs for all functions (does not include external @@ -601,33 +637,41 @@ class EscapeAnalysis : public SILAnalysis { /// Callee analysis, used for determining the callees at call sites. BasicCalleeAnalysis *BCA; - /// This analysis depends on the call graph. - CallGraphAnalysis *CGA; - - /// If false, nothing has changed between two recompute() calls. - bool shouldRecompute; - /// Returns true if \p V is a "pointer" value. /// See EscapeAnalysis::NodeType::Value. bool isPointer(ValueBase *V); /// If V is a pointer, set it to global escaping. - void setEscapesGlobal(ConnectionGraph *ConGraph, SILValue V) { + void setEscapesGlobal(ConnectionGraph *ConGraph, ValueBase *V) { if (CGNode *Node = ConGraph->getNode(V, this)) ConGraph->setEscapesGlobal(Node); } - /// Builds the connection graph and the summary graph for a function, but - /// does not handle applys of known callees. This is done afterwards in - /// mergeAllCallees. - void buildConnectionGraphs(FunctionInfo *FInfo); + /// Gets or creates FunctionEffects for \p F. + FunctionInfo *getFunctionInfo(SILFunction *F) { + FunctionInfo *&FInfo = Function2Info[F]; + if (!FInfo) + FInfo = new (Allocator.Allocate()) FunctionInfo(F); + return FInfo; + } - /// Returns true if all called functions from an apply site are known and not - /// external. - bool allCalleeFunctionsVisible(FullApplySite FAS); + /// Builds the connection graph for a function, including called functions. + /// Visited callees are added to \p BottomUpOrder until \p RecursionDepth + /// reaches MaxRecursionDepth. + void buildConnectionGraph(FunctionInfo *FInfo, FunctionOrder &BottomUpOrder, + int RecursionDepth); /// Updates the graph by analysing instruction \p I. - void analyzeInstruction(SILInstruction *I, FunctionInfo *FInfo); + /// Visited callees are added to \p BottomUpOrder until \p RecursionDepth + /// reaches MaxRecursionDepth. + void analyzeInstruction(SILInstruction *I, FunctionInfo *FInfo, + FunctionOrder &BottomUpOrder, + int RecursionDepth); + + /// Updates the graph by analysing instruction \p SI, which may be a + /// select_enum, select_enum_addr or select_value. + template + void analyzeSelectInst(SelectInst *SI, ConnectionGraph *ConGraph); /// Returns true if \p V is an Array or the storage reference of an array. bool isArrayOrArrayStorage(SILValue V); @@ -635,8 +679,9 @@ class EscapeAnalysis : public SILAnalysis { /// Sets all operands and results of \p I as global escaping. void setAllEscaping(SILInstruction *I, ConnectionGraph *ConGraph); - /// Merge the graphs of all known callees into this graph. - bool mergeAllCallees(FunctionInfo *FInfo, CallGraph &CG); + /// Recomputes the connection graph for the function \p Initial and + /// all called functions, up to a recursion depth of MaxRecursionDepth. + void recompute(FunctionInfo *Initial); /// Merges the graph of a callee function into the graph of /// a caller function, whereas \p FAS is the call-site. @@ -648,8 +693,10 @@ class EscapeAnalysis : public SILAnalysis { bool mergeSummaryGraph(ConnectionGraph *SummaryGraph, ConnectionGraph *Graph); - /// Set all arguments and return values of all callees to global escaping. - void finalizeGraphsConservatively(FunctionInfo *FInfo); + /// Returns true if the value \p V can escape to the \p UsePoint, where + /// \p UsePoint is either a release-instruction or a function call. + bool canEscapeToUsePoint(SILValue V, ValueBase *UsePoint, + ConnectionGraph *ConGraph); friend struct ::CGForDotView; @@ -660,39 +707,55 @@ class EscapeAnalysis : public SILAnalysis { return S->getKind() == AnalysisKind::Escape; } - virtual void initialize(SILPassManager *PM); + virtual void initialize(SILPassManager *PM) override; - /// Gets or creates a connection graph for \a F. + /// Gets the connection graph for \a F. ConnectionGraph *getConnectionGraph(SILFunction *F) { - FunctionInfo *&FInfo = Function2Info[F]; - if (!FInfo) - FInfo = new (Allocator.Allocate()) FunctionInfo(F); - - if (!FInfo->Valid) - buildConnectionGraphs(FInfo); - + FunctionInfo *FInfo = getFunctionInfo(F); + if (!FInfo->isValid()) + recompute(FInfo); return &FInfo->Graph; } - - /// Recomputes the connection graphs for all functions the module. - void recompute(); - virtual void invalidate(InvalidationKind K) { - Function2Info.clear(); - Allocator.DestroyAll(); - shouldRecompute = true; - } - - virtual void invalidate(SILFunction *F, InvalidationKind K) { - if (FunctionInfo *FInfo = Function2Info.lookup(F)) { - FInfo->Graph.clear(); - FInfo->KnownCallees.clear(); - FInfo->Valid = false; - shouldRecompute = true; - } - } + /// Returns true if the value \p V can escape to the function call \p FAS. + /// This means that the called function may access the value \p V. + /// If \p V has reference semantics, this function returns false if only the + /// address of a contained property escapes, but not the object itself. + bool canEscapeTo(SILValue V, FullApplySite FAS); + + /// Returns true if the value \p V or its content can escape to the + /// function call \p FAS. + /// This is the same as above, except that it returns true if an address of + /// a contained property escapes. + bool canObjectOrContentEscapeTo(SILValue V, FullApplySite FAS); + + /// Returns true if the value \p V can escape to the release-instruction \p + /// RI. This means that \p RI may release \p V or any called destructor may + /// access (or release) \p V. + /// Note that if \p RI is a retain-instruction always false is returned. + bool canEscapeTo(SILValue V, RefCountingInst *RI); + + /// Returns true if the value \p V can escape to any other pointer \p To. + /// This means that either \p To is the same as \p V or contains a reference + /// to \p V. + bool canEscapeToValue(SILValue V, SILValue To); + + /// Returns true if the pointers \p V1 and \p V2 can possibly point to the + /// same memory. + /// If at least one of the pointers refers to a local object and the + /// connection-graph-nodes of both pointers do not point to the same content + /// node, the pointers do not alias. + bool canPointToSameMemory(SILValue V1, SILValue V2); + + virtual void invalidate(InvalidationKind K) override; + + virtual void invalidate(SILFunction *F, InvalidationKind K) override; + + virtual void handleDeleteNotification(ValueBase *I) override; + + virtual bool needsNotifications() override { return true; } - virtual void verify() const { + virtual void verify() const override { #ifndef NDEBUG for (auto Iter : Function2Info) { FunctionInfo *FInfo = Iter.second; @@ -702,7 +765,7 @@ class EscapeAnalysis : public SILAnalysis { #endif } - virtual void verify(SILFunction *F) const { + virtual void verify(SILFunction *F) const override { #ifndef NDEBUG if (FunctionInfo *FInfo = Function2Info.lookup(F)) { FInfo->Graph.verify(); diff --git a/include/swift/SILAnalysis/FunctionOrder.h b/include/swift/SILOptimizer/Analysis/FunctionOrder.h similarity index 88% rename from include/swift/SILAnalysis/FunctionOrder.h rename to include/swift/SILOptimizer/Analysis/FunctionOrder.h index 03c7f55762b2d..ab86c5e3a23fc 100644 --- a/include/swift/SILAnalysis/FunctionOrder.h +++ b/include/swift/SILOptimizer/Analysis/FunctionOrder.h @@ -1,8 +1,8 @@ -//===--- FunctionOrder.h - Utilities for function ordering ----*- C++ -*--===// +//===--- FunctionOrder.h - Utilities for function ordering -----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_FUNCTIONORDER_H -#define SWIFT_SILANALYSIS_FUNCTIONORDER_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_FUNCTIONORDER_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_FUNCTIONORDER_H -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" diff --git a/include/swift/SILAnalysis/IVAnalysis.h b/include/swift/SILOptimizer/Analysis/IVAnalysis.h similarity index 86% rename from include/swift/SILAnalysis/IVAnalysis.h rename to include/swift/SILOptimizer/Analysis/IVAnalysis.h index d50eac4aeb0d4..3cbb8cb415937 100644 --- a/include/swift/SILAnalysis/IVAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/IVAnalysis.h @@ -1,8 +1,8 @@ -//===------------------- IVAnalysis.h - SIL IV Analysis -------*- C++ -*---===// +//===--- IVAnalysis.h - SIL IV Analysis -------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,13 +10,13 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_IVANALYSIS_H -#define SWIFT_SILANALYSIS_IVANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_IVANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_IVANALYSIS_H -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILValue.h" -#include "swift/SILPasses/Utils/SCCVisitor.h" +#include "swift/SILOptimizer/Utils/SCCVisitor.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Debug.h" @@ -30,7 +30,7 @@ class IVInfo : public SCCVisitor { public: - /// A descriptor for an induction variable comprised of an header argument + /// A descriptor for an induction variable comprised of a header argument /// (phi node) and an increment by an integer literal. class IVDesc { public: diff --git a/include/swift/SILAnalysis/LoopAnalysis.h b/include/swift/SILOptimizer/Analysis/LoopAnalysis.h similarity index 81% rename from include/swift/SILAnalysis/LoopAnalysis.h rename to include/swift/SILOptimizer/Analysis/LoopAnalysis.h index 63985d3d6e03d..3b4adbbbc2db1 100644 --- a/include/swift/SILAnalysis/LoopAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/LoopAnalysis.h @@ -1,8 +1,8 @@ -//===-------------- LoopAnalysis.h - SIL Loop Analysis -*- C++ -*----------===// +//===--- LoopAnalysis.h - SIL Loop Analysis ---------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,13 +10,13 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_LOOPINFOANALYSIS_H -#define SWIFT_SILANALYSIS_LOOPINFOANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_LOOPINFOANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_LOOPINFOANALYSIS_H #include "swift/SIL/CFG.h" #include "swift/SIL/LoopInfo.h" #include "swift/SIL/SILBasicBlock.h" -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "llvm/ADT/DenseMap.h" namespace swift { diff --git a/include/swift/SILAnalysis/LoopRegionAnalysis.h b/include/swift/SILOptimizer/Analysis/LoopRegionAnalysis.h similarity index 95% rename from include/swift/SILAnalysis/LoopRegionAnalysis.h rename to include/swift/SILOptimizer/Analysis/LoopRegionAnalysis.h index 12207027fc995..80ac2e4c4335a 100644 --- a/include/swift/SILAnalysis/LoopRegionAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/LoopRegionAnalysis.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -61,7 +61,7 @@ /// /// Then we perform a postorder DFS of the loop nest. The postorder provides the /// inductive rule that all loops will be visited after all of their subloops -/// hae been visited. If a Loop has no subloops (i.e. all subregions are +/// have been visited. If a Loop has no subloops (i.e. all subregions are /// blocks), we do nothing. Otherwise, if the loop does have subloops, we visit /// each subloop and do the following: /// @@ -113,16 +113,16 @@ /// //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_LOOPNESTANALYSIS_H -#define SWIFT_SILANALYSIS_LOOPNESTANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_LOOPNESTANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_LOOPNESTANALYSIS_H -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "swift/Basic/BlotSetVector.h" #include "swift/Basic/Range.h" #include "swift/Basic/STLExtras.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILPasses/PassManager.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" #include "swift/SIL/LoopInfo.h" #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILFunction.h" @@ -245,7 +245,7 @@ class LoopRegion { /// a basic block. The iterator can only be compared against another invalid /// iterator. Any other use causes an unreachable being hit. /// - /// The reason this is needed is because basic blocks can not have + /// The reason this is needed is because basic blocks cannot have /// subregions, yet many graph algorithms want to be able to iterate over /// the subregions of a region regardless of whether it is a basic block, /// loop, or function. By allowing for invalid iterators for basic blocks, @@ -346,7 +346,7 @@ class LoopRegion { /// this BB, we can represent each jump as individual non-local edges in /// between loops. /// - /// *NOTE* This list is not sorted, but can not have any duplicate + /// *NOTE* This list is not sorted, but cannot have any duplicate /// elements. We have a check in LoopRegionFunctionInfo::verify to make sure /// that this stays true. The reason why this is necessary is that subregions /// of a loop, may have a non-local successor edge pointed at this region's @@ -390,15 +390,19 @@ class LoopRegion { /// /// This contains IDs that represent both basic blocks and loops that are /// subregions of this region. What is key to notice is that a loop is - /// represented by the RPO number of its header. We use an auxillary map to + /// represented by the RPO number of its header. We use an auxiliary map to /// map the preheader's RPO number to the loop's ID. llvm::SmallVector Subregions; /// A map from RPO number of a subregion loop's preheader to a subloop - /// regions id. This is neccessary since we represent a loop in the + /// regions id. This is necessary since we represent a loop in the /// Subregions array by the RPO number of its header. llvm::SmallVector, 2> Subloops; + /// A list of subregions with non-local successors. This is the actual ID + /// of the subregion since we do not care about any ordering. + llvm::SmallVector ExitingSubregions; + subregion_iterator begin() const { return subregion_iterator(Subregions.begin(), &Subloops); } @@ -498,6 +502,14 @@ class LoopRegion { return std::find(subregion_begin(), End, R->getID()) != End; } + /// Returns an ArrayRef containing IDs of the exiting subregions of this + /// region. The exit regions associated with the exiting subregions are the + /// end points of the non-local edges. This asserts if this is a region + /// representing a block. + ArrayRef getExitingSubregions() const { + return getSubregionData().ExitingSubregions; + } + using pred_const_iterator = decltype(Preds)::const_iterator; pred_const_iterator pred_begin() const { return Preds.begin(); } pred_const_iterator pred_end() const { return Preds.end(); } @@ -588,20 +600,20 @@ class LoopRegion { IsUnknownControlFlowEdgeTail(false) {} void setParent(LoopRegion *PR) { - assert(!isFunction() && "Functions can not be subregions"); - assert(!PR->isBlock() && "BB regions can not be parents of a region"); + assert(!isFunction() && "Functions cannot be subregions"); + assert(!PR->isBlock() && "BB regions cannot be parents of a region"); ParentID = PR->getID(); } void addPred(LoopRegion *LNR) { - assert(!isFunction() && "Functions can not have predecessors"); + assert(!isFunction() && "Functions cannot have predecessors"); if (std::count(pred_begin(), pred_end(), LNR->getID())) return; Preds.push_back(LNR->ID); } unsigned addSucc(LoopRegion *Successor) { - assert(!isFunction() && "Functions can not have successors"); + assert(!isFunction() && "Functions cannot have successors"); return Succs.insert(SuccessorID(Successor->getID(), false)); } @@ -632,14 +644,14 @@ class LoopRegion { void removeLocalSucc(unsigned ID) { Succs.erase(SuccessorID(ID, false)); } void addBlockSubregion(LoopRegion *R) { - assert(!isBlock() && "Blocks can not have subregions"); + assert(!isBlock() && "Blocks cannot have subregions"); assert(R->isBlock() && "Assumed R was a basic block"); R->setParent(this); getSubregionData().addBlockSubregion(R); } void addLoopSubregion(LoopRegion *L, LoopRegion *Header) { - assert(!isBlock() && "Blocks can not have subregions"); + assert(!isBlock() && "Blocks cannot have subregions"); assert(L->isLoop() && "Assumed L was a loop"); assert(Header->isBlock() && "Assumed Header was a loop"); L->setParent(this); @@ -717,7 +729,7 @@ class LoopRegionFunctionInfo { /// A map from an unsigned integer ID to a region. /// - /// *WARNING* Before modifying the initializiation of this field of the data + /// *WARNING* Before modifying the initialization of this field of the data /// structure please read the comment below: /// /// We assign IDs to BBs, Loops, and the top level Function, so that we can diff --git a/include/swift/SILAnalysis/PostOrderAnalysis.h b/include/swift/SILOptimizer/Analysis/PostOrderAnalysis.h similarity index 93% rename from include/swift/SILAnalysis/PostOrderAnalysis.h rename to include/swift/SILOptimizer/Analysis/PostOrderAnalysis.h index 6c87fad113407..bbb89ea5442db 100644 --- a/include/swift/SILAnalysis/PostOrderAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/PostOrderAnalysis.h @@ -1,8 +1,8 @@ -//===--- PostOrderAnalysis.h - SIL POT and RPOT Analysis -------*- C++ -*--===// +//===--- PostOrderAnalysis.h - SIL POT and RPOT Analysis --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_POSTORDERANALYSIS_H -#define SWIFT_SILANALYSIS_POSTORDERANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_POSTORDERANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_POSTORDERANALYSIS_H -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "swift/Basic/Range.h" #include "swift/SIL/CFG.h" #include "swift/SIL/SILBasicBlock.h" diff --git a/include/swift/SILAnalysis/RCIdentityAnalysis.h b/include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h similarity index 85% rename from include/swift/SILAnalysis/RCIdentityAnalysis.h rename to include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h index 2bf5318b1e9d9..9d3b30f52dbe6 100644 --- a/include/swift/SILAnalysis/RCIdentityAnalysis.h +++ b/include/swift/SILOptimizer/Analysis/RCIdentityAnalysis.h @@ -1,8 +1,8 @@ -//===--- RCIdentityAnalysis.h ------------------------------*- C++ -*------===// +//===--- RCIdentityAnalysis.h -----------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,18 +12,18 @@ // // This is an analysis that determines the ref count identity (i.e. gc root) of // a pointer. Any values with the same ref count identity are able to be -// retained and released interchangably. +// retained and released interchangeably. // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILANALYSIS_RCIDENTITYANALYSIS_H -#define SWIFT_SILANALYSIS_RCIDENTITYANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_RCIDENTITYANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_RCIDENTITYANALYSIS_H #include "swift/SIL/SILValue.h" #include "swift/SIL/SILArgument.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILPasses/PassManager.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" namespace swift { diff --git a/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h b/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h new file mode 100644 index 0000000000000..e2a8adacf48be --- /dev/null +++ b/include/swift/SILOptimizer/Analysis/SideEffectAnalysis.h @@ -0,0 +1,388 @@ +//===--- SideEffectAnalysis.h - SIL Side Effect Analysis --------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_SIDEEFFECTANALYSIS_H_ +#define SWIFT_SILOPTIMIZER_ANALYSIS_SIDEEFFECTANALYSIS_H_ + +#include "swift/SIL/SILInstruction.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SILOptimizer/Analysis/BottomUpIPAnalysis.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallVector.h" + +namespace swift { + +class BasicCalleeAnalysis; + + +/// An enum to represent the kind of scan we perform when we calculate +/// side effects. +enum class RetainObserveKind { + ObserveRetains, + IgnoreRetains, + RetainObserveKindEnd +}; + +/// The SideEffectAnalysis provides information about side-effects of SIL +/// functions. Side-effect information is provided per function and includes: +/// Does the function read or write memory? Does the function retain or release +/// objects? etc. +/// For details see SideEffectAnalysis::FunctionEffects and +/// SideEffectAnalysis::Effects. +class SideEffectAnalysis : public BottomUpIPAnalysis { +public: + + using MemoryBehavior = SILInstruction::MemoryBehavior; + /// Set \p dest if \p src is set and return true if \p dest was not set + /// before. + static bool updateFlag(bool &dest, bool src) { + if (src && !dest) { + dest = src; + return true; + } + return false; + } + + /// Side-effect information for the function (global effects) or a specific + /// parameter of the function. See FunctionEffects. + class Effects { + bool Reads = false; + bool Writes = false; + bool Retains = false; + bool Releases = false; + + /// Sets the most conservative effects. + void setWorstEffects() { + Reads = true; + Writes = true; + Retains = true; + Releases = true; + } + + /// Clears all effects. + void clear() { + Reads = false; + Writes = false; + Retains = false; + Releases = false; + } + + friend class SideEffectAnalysis; + + public: + + /// Does the function read from memory (excluding reads from locally + /// allocated memory)? + bool mayRead() const { return Reads; } + + /// Does the function write to memory (excluding writes to locally + /// allocated memory)? + bool mayWrite() const { return Writes; } + + /// Does the function retain objects (excluding retains of locally + /// allocated objects)? + bool mayRetain() const { return Retains; } + + /// Does the function release objects (excluding releases of locally + /// allocated objects)? + bool mayRelease() const { return Releases; } + + /// Gets the memory behavior considering the global effects and + /// all parameter effects. If \p ScanKind equals ignoreRetains then retain + /// instructions are considered as side effects. + MemoryBehavior getMemBehavior(RetainObserveKind ScanKind) const { + if (mayRelease()) + return MemoryBehavior::MayHaveSideEffects; + + if (ScanKind == RetainObserveKind::ObserveRetains && mayRetain()) + return MemoryBehavior::MayHaveSideEffects; + + if (mayWrite()) + return mayRead() ? MemoryBehavior::MayReadWrite : + MemoryBehavior::MayWrite; + + if (mayRead()) + return MemoryBehavior::MayRead; + + return MemoryBehavior::None; + } + + /// Merge effects from \p RHS. + bool mergeFrom(const Effects &RHS) { + bool Changed = false; + Changed |= updateFlag(Reads, RHS.Reads); + Changed |= updateFlag(Writes, RHS.Writes); + Changed |= updateFlag(Retains, RHS.Retains); + Changed |= updateFlag(Releases, RHS.Releases); + return Changed; + } + }; + + friend raw_ostream &operator<<(raw_ostream &os, + const SideEffectAnalysis::Effects &Effects) { + if (Effects.mayRead()) + os << 'r'; + if (Effects.mayWrite()) + os << 'w'; + if (Effects.mayRetain()) + os << '+'; + if (Effects.mayRelease()) + os << '-'; + return os; + } + + /// Summarizes the side-effects of a function. The side-effect information + /// is divided into global effects and effects for specific function + /// parameters. + /// If a side-effect can be associated to a specific function parameter, it is + /// not added to the global effects of the function. E.g. if a memory write is + /// only done through an @inout parameter, the mayWrite side-effect is only + /// accounted for this parameter. + /// Effects for a parameter make only sense if the parameter is implemented as + /// a pointer or contains a pointer: + /// *) The parameter is an address parameter, e.g. @out, @inout, etc. + /// *) The parameter is a reference + /// *) The parameter is a value type (e.g. struct) and contains a reference. + /// In this case the effects refer to all references in the value type. + /// E.g. if a struct contains 2 references, a mayWrite effect means that + /// memory is written to one of the referenced objects (or to both). + class FunctionEffects { + + /// Side-effects which can be associated to a parameter. + llvm::SmallVector ParamEffects; + + /// All other side-effects which cannot be associated to a parameter. + Effects GlobalEffects; + + /// Side-effects on locally allocated storage. Such side-effects are not + /// relevant to optimizations. The LocalEffects are only used to return + /// "something" for local storage in getEffectsOn(). + Effects LocalEffects; + + /// Does the function allocate objects, boxes, etc., i.e. everything which + /// has a reference count. + bool AllocsObjects = false; + + /// Can this function trap or exit the program in any way? + bool Traps = false; + + /// Does this function read a reference count other than with retain or + /// release instructions, e.g. isUnique? + bool ReadsRC = false; + + /// Returns the effects for an address or reference. This might be a + /// parameter, the LocalEffects or, if the value cannot be associated to one + /// of them, the GlobalEffects. + Effects *getEffectsOn(SILValue Addr); + + FunctionEffects(unsigned numParams) : ParamEffects(numParams) { } + + /// Sets the most conservative effects, if we don't know anything about the + /// function. + void setWorstEffects() { + GlobalEffects.setWorstEffects(); + AllocsObjects = true; + Traps = true; + ReadsRC = true; + } + + /// Clears all effects. + void clear() { + GlobalEffects.clear(); + for (Effects &PE : ParamEffects) + PE.clear(); + AllocsObjects = false; + Traps = false; + ReadsRC = false; + } + + /// Merge the flags from \p RHS. + bool mergeFlags(const FunctionEffects &RHS) { + bool Changed = false; + Changed |= updateFlag(Traps, RHS.Traps); + Changed |= updateFlag(AllocsObjects, RHS.AllocsObjects); + Changed |= updateFlag(ReadsRC, RHS.ReadsRC); + return Changed; + } + + friend class SideEffectAnalysis; + + public: + + /// Constructs "empty" function effects. + FunctionEffects() { } + + /// Does the function allocate objects, boxes, etc., i.e. everything which + /// has a reference count. + bool mayAllocObjects() const { return AllocsObjects; } + + /// Can this function trap or exit the program in any way? + bool mayTrap() const { return Traps; } + + /// Does this function read a reference count other than with retain or + /// release instructions, e.g. isUnique? + bool mayReadRC() const { return ReadsRC; } + + /// Gets the memory behavior considering the global effects and + /// all parameter effects. If \p ScanKind equals ignoreRetains then retain + /// instructions are considered as side effects. + MemoryBehavior getMemBehavior(RetainObserveKind ScanKind) const; + + /// Get the global effects for the function. These are effects which cannot + /// be associated to a specific parameter, e.g. writes to global variables + /// or writes to unknown pointers. + const Effects &getGlobalEffects() const { return GlobalEffects; } + + /// Get the array of parameter effects. If a side-effect can be associated + /// to a specific parameter, it is contained here instead of the global + /// effects. + ArrayRef getParameterEffects() const { return ParamEffects; } + + /// Merge effects from \p RHS. + bool mergeFrom(const FunctionEffects &RHS); + + /// Merge effects from an apply site within the function. + bool mergeFromApply(const FunctionEffects &CalleeEffects, + FullApplySite FAS); + + /// Print the function effects. + void dump() const; + }; + + friend raw_ostream &operator<<(raw_ostream &os, + const SideEffectAnalysis::FunctionEffects &Effects) { + os << "func=" << Effects.getGlobalEffects(); + int ParamIdx = 0; + for (auto &E : Effects.getParameterEffects()) { + os << ",param" << ParamIdx++ << "=" << E; + } + if (Effects.mayAllocObjects()) + os << ";alloc"; + if (Effects.mayTrap()) + os << ";trap"; + if (Effects.mayReadRC()) + os << ";readrc"; + return os; + } + +private: + + /// Stores the analysis data, i.e. the side-effects, for a function. + struct FunctionInfo : public FunctionInfoBase { + + /// The side-effects of the function. + FunctionEffects FE; + + /// Back-link to the function. + SILFunction *F; + + /// Used during recomputation to indicate if the side-effects of a caller + /// must be updated. + bool NeedUpdateCallers = false; + + FunctionInfo(SILFunction *F) : + FE(F->empty() ? 0 : F->getArguments().size()), F(F) { } + + /// Clears the analysis data on invalidation. + void clear() { FE.clear(); } + }; + + typedef BottomUpFunctionOrder FunctionOrder; + + enum { + /// The maximum call-graph recursion depth for recomputing the analysis. + /// This is a relatively small number to reduce compile time in case of + /// large cycles in the call-graph. + /// In case of no cycles, we should not hit this limit at all because the + /// pass manager processes functions in bottom-up order. + MaxRecursionDepth = 5 + }; + + /// All the side-effect information for the whole module. + llvm::DenseMap Function2Info; + + /// The allocator for the map values in Function2Info. + llvm::SpecificBumpPtrAllocator Allocator; + + /// Callee analysis, used for determining the callees at call sites. + BasicCalleeAnalysis *BCA; + + /// Get the side-effects of a function, which has an @effects attribute. + /// Returns true if \a F has an @effects attribute which could be handled. + static bool getDefinedEffects(FunctionEffects &Effects, SILFunction *F); + + /// Get the side-effects of a semantic call. + /// Return true if \p ASC could be handled. + bool getSemanticEffects(FunctionEffects &Effects, ArraySemanticsCall ASC); + + /// Analyze the side-effects of a function, including called functions. + /// Visited callees are added to \p BottomUpOrder until \p RecursionDepth + /// reaches MaxRecursionDepth. + void analyzeFunction(FunctionInfo *FInfo, + FunctionOrder &BottomUpOrder, + int RecursionDepth); + + /// Analyze the side-effects of a single SIL instruction \p I. + /// Visited callees are added to \p BottomUpOrder until \p RecursionDepth + /// reaches MaxRecursionDepth. + void analyzeInstruction(FunctionInfo *FInfo, + SILInstruction *I, + FunctionOrder &BottomUpOrder, + int RecursionDepth); + + /// Gets or creates FunctionEffects for \p F. + FunctionInfo *getFunctionInfo(SILFunction *F) { + FunctionInfo *&FInfo = Function2Info[F]; + if (!FInfo) { + FInfo = new (Allocator.Allocate()) FunctionInfo(F); + } + return FInfo; + } + + /// Recomputes the side-effect information for the function \p Initial and + /// all called functions, up to a recursion depth of MaxRecursionDepth. + void recompute(FunctionInfo *Initial); + +public: + SideEffectAnalysis() + : BottomUpIPAnalysis(AnalysisKind::SideEffect) {} + + static bool classof(const SILAnalysis *S) { + return S->getKind() == AnalysisKind::SideEffect; + } + + virtual void initialize(SILPassManager *PM) override; + + /// Get the side-effects of a function. + const FunctionEffects &getEffects(SILFunction *F) { + FunctionInfo *FInfo = getFunctionInfo(F); + if (!FInfo->isValid()) + recompute(FInfo); + return FInfo->FE; + } + + /// Get the side-effects of a call site. + void getEffects(FunctionEffects &ApplyEffects, FullApplySite FAS); + + /// No invalidation is needed. See comment for SideEffectAnalysis. + virtual void invalidate(InvalidationKind K) override; + + /// No invalidation is needed. See comment for SideEffectAnalysis. + virtual void invalidate(SILFunction *F, InvalidationKind K) override; +}; + +} // end namespace swift + +#endif + diff --git a/include/swift/SILAnalysis/SimplifyInstruction.h b/include/swift/SILOptimizer/Analysis/SimplifyInstruction.h similarity index 95% rename from include/swift/SILAnalysis/SimplifyInstruction.h rename to include/swift/SILOptimizer/Analysis/SimplifyInstruction.h index f07dc1e3d59b7..b0f81db2cb3a1 100644 --- a/include/swift/SILAnalysis/SimplifyInstruction.h +++ b/include/swift/SILOptimizer/Analysis/SimplifyInstruction.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,7 +12,7 @@ // // An analysis that provides utilities for folding instructions. Since it is an // analysis it does not modify the IR in anyway. This is left to actual -// SILPasses. +// SIL Transforms. // //===----------------------------------------------------------------------===// diff --git a/include/swift/SILOptimizer/Analysis/TypeExpansionAnalysis.h b/include/swift/SILOptimizer/Analysis/TypeExpansionAnalysis.h new file mode 100644 index 0000000000000..30a86ca120e6e --- /dev/null +++ b/include/swift/SILOptimizer/Analysis/TypeExpansionAnalysis.h @@ -0,0 +1,53 @@ +//===--- TypeExpansionAnalysis.h --------------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_TYPEEXPANSIONANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_TYPEEXPANSIONANALYSIS_H + +#include "swift/SIL/Projection.h" +#include "swift/SIL/SILType.h" +#include "swift/SIL/SILValue.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "llvm/ADT/DenseMap.h" + +namespace swift { + +/// Type expansion kind. +enum class TEKind { + TELeaf, // Leaf nodes expansion. + TENode // Intermediate and leaf nodes expansion. +}; + +using TypeExpansionMap = llvm::DenseMap; + +/// This analysis determines memory effects during destruction. +class TypeExpansionAnalysis : public SILAnalysis { + /// Caches the type to leaf node expansion. + TypeExpansionMap TELeafCache; + /// Caches the type to each node expansion, including intermediate nodes as + /// well as leaf nodes in the type tree. + TypeExpansionMap TENodeCache; + +public: + TypeExpansionAnalysis(SILModule *M) + : SILAnalysis(AnalysisKind::TypeExpansion) {} + + static bool classof(const SILAnalysis *S) { + return S->getKind() == AnalysisKind::TypeExpansion; + } + + /// Return ProjectionPath to every leaf or intermediate node of the given type. + const ProjectionPathList &getTypeExpansionProjectionPaths(SILType B, + SILModule *Mod, + TEKind K); +}; +} +#endif diff --git a/include/swift/SILOptimizer/Analysis/ValueTracking.h b/include/swift/SILOptimizer/Analysis/ValueTracking.h new file mode 100644 index 0000000000000..d3dbddd9721c9 --- /dev/null +++ b/include/swift/SILOptimizer/Analysis/ValueTracking.h @@ -0,0 +1,69 @@ +//===--- ValueTracking.h - SIL Value Tracking Analysis ----------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file contains routines which analyze chains of computations. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_VALUETRACKING_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_VALUETRACKING_H + +#include "swift/SIL/SILInstruction.h" + +namespace swift { + +class SILValue; + +/// Strip off casts/indexing insts/address projections from V until there is +/// nothing left to strip. +SILValue getUnderlyingObject(SILValue V); + +/// Returns true if \p V is a function argument which may not alias to +/// any other pointer in the function. +/// The \p assumeInoutIsNotAliasing specifies in no-aliasing is assumed for +/// the @inout convention. See swift::isNotAliasedIndirectParameter(). +bool isNotAliasingArgument(SILValue V, InoutAliasingAssumption isInoutAliasing = + InoutAliasingAssumption::Aliasing); + +/// Returns true if \p V is local inside its function. This means its underlying +/// object either is a non-aliasing function argument or a locally allocated +/// object. +/// The \p assumeInoutIsNotAliasing specifies in no-aliasing is assumed for +/// the @inout convention. See swift::isNotAliasedIndirectParameter(). + bool pointsToLocalObject(SILValue V, InoutAliasingAssumption isInoutAliasing = + InoutAliasingAssumption::Aliasing); + +enum class IsZeroKind { + Zero, + NotZero, + Unknown +}; + +/// Check if the value \p Value is known to be zero, non-zero or unknown. +IsZeroKind isZeroValue(SILValue Value); + +/// Checks if a sign bit of a value is known to be set, not set or unknown. +/// Essentially, it is a simple form of a range analysis. +/// This approach is inspired by the corresponding implementation of +/// ComputeSignBit in LLVM's value tracking implementation. +/// It is planned to extend this approach to track all bits of a value. +/// Therefore it can be considered to be the beginning of a range analysis +/// infrastructure for the Swift compiler. +Optional computeSignBit(SILValue Value); + +/// Check if execution of a given builtin instruction can result in overflows. +/// Returns true of an overflow can happen. Otherwise returns false. +bool canOverflow(BuiltinInst *BI); + +} // end namespace swift + +#endif // SWIFT_SILOPTIMIZER_ANALYSIS_VALUETRACKING_H diff --git a/include/swift/SILPasses/PassManager.h b/include/swift/SILOptimizer/PassManager/PassManager.h similarity index 76% rename from include/swift/SILPasses/PassManager.h rename to include/swift/SILOptimizer/PassManager/PassManager.h index 6bbb04dc762f3..5a65b90f3625c 100644 --- a/include/swift/SILPasses/PassManager.h +++ b/include/swift/SILOptimizer/PassManager/PassManager.h @@ -1,8 +1,8 @@ -//===-- PassManager.h - Swift Pass Manager ---------------------*- C++ -*-===// +//===--- PassManager.h - Swift Pass Manager --------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,22 +10,24 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "llvm/Support/Casting.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" +#include -#ifndef SWIFT_SILPASSES_PASSMANAGER_H -#define SWIFT_SILPASSES_PASSMANAGER_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_PASSMANAGER_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_PASSMANAGER_H namespace swift { class SILFunction; class SILFunctionTransform; class SILModule; +class SILModuleTransform; class SILOptions; class SILTransform; @@ -40,6 +42,9 @@ class SILPassManager { /// A list of registered analysis. llvm::SmallVector Analysis; + /// The worklist of functions to be processed by function passes. + std::vector FunctionWorklist; + // Name of the current optimization stage for diagnostics. std::string StageName; @@ -87,6 +92,13 @@ class SILPassManager { /// \brief Run one iteration of the optimization pipeline. void runOneIteration(); + /// \brief Add a function to the function pass worklist. + void addFunctionToWorklist(SILFunction *F) { + assert(F && F->isDefinition() && F->shouldOptimize() && + "Expected optimizable function definition!"); + FunctionWorklist.push_back(F); + } + /// \brief Broadcast the invalidation of the module to all analysis. void invalidateAnalysis(SILAnalysis::InvalidationKind K) { assert(K != SILAnalysis::InvalidationKind::Nothing && @@ -116,7 +128,7 @@ class SILPassManager { } /// \brief Reset the state of the pass manager and remove all transformation - /// owned by the pass manager. Anaysis passes will be kept. + /// owned by the pass manager. Analysis passes will be kept. void resetAndRemoveTransformations(); // Sets the name of the current optimization stage used for debugging. @@ -156,10 +168,26 @@ class SILPassManager { typedef llvm::ArrayRef PassList; private: + /// Run the SIL module transform \p SMT over all the functions in + /// the module. + void runModulePass(SILModuleTransform *SMT); + + /// Run the passes in \p FuncTransforms on the function \p F. + void runPassesOnFunction(PassList FuncTransforms, SILFunction *F); + /// Run the passes in \p FuncTransforms. Return true /// if the pass manager requested to stop the execution /// of the optimization cycle (this is a debug feature). - bool runFunctionPasses(PassList FuncTransforms); + void runFunctionPasses(PassList FuncTransforms); + + /// A helper function that returns (based on SIL stage and debug + /// options) whether we should continue running passes. + bool continueTransforming(); + + /// Displays the call graph in an external dot-viewer. + /// This function is meant for use from the debugger. + /// When asserts are disabled, this is a NoOp. + void viewCallGraph(); }; } // end namespace swift diff --git a/include/swift/SILPasses/Passes.def b/include/swift/SILOptimizer/PassManager/Passes.def similarity index 86% rename from include/swift/SILPasses/Passes.def rename to include/swift/SILOptimizer/PassManager/Passes.def index d5f1db2e27714..1809285e8367b 100644 --- a/include/swift/SILPasses/Passes.def +++ b/include/swift/SILOptimizer/PassManager/Passes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -38,6 +38,8 @@ PASS(AllocBoxToStack, "allocbox-to-stack", "Promote heap allocations to stack allocations") PASS(ArrayCountPropagation, "array-count-propagation", "Propagate the count of arrays") +PASS(ArrayElementPropagation, "array-element-propagation", + "Propagate the value of array elements") PASS(BasicCalleePrinter, "basic-callee-printer", "Construct basic callee analysis and use it to print callees " "for testing purposes") @@ -47,8 +49,6 @@ PASS(COWArrayOpts, "cowarray-opt", "COW Array optimizations") PASS(CSE, "cse", "Common subexpression elimination") -PASS(CallGraphPrinter, "call-graph-printer", - "Construct and print the call graph for use in testing") PASS(CapturePromotion, "capture-promotion", "Promote captures from by-reference to by-value") PASS(CapturePropagation, "capture-prop", @@ -57,6 +57,12 @@ PASS(ClosureSpecializer, "closure-specialize", "Specialize functions passed a closure to call the closure directly") PASS(CodeSinking, "code-sinking", "Sinks code closer to users") +PASS(ComputeDominanceInfo, "compute-dominance-info", + "Utility pass that computes (post-)dominance info for all functions in " + "order to help test dominanceinfo updating") +PASS(ComputeLoopInfo, "compute-loop-info", + "Utility pass that computes loop info for all functions in order to help " + "test loop info updating") PASS(CopyForwarding, "copy-forwarding", "Eliminate redundant copies") PASS(RedundantOverflowCheckRemoval, "remove-redundant-overflow-checks", @@ -69,6 +75,7 @@ PASS(DeadObjectElimination, "deadobject-elim", "Eliminate unused objects that do not have destructors with side effects") PASS(DefiniteInitialization, "definite-init", "Definite Initialization") +PASS(Devirtualizer, "devirtualizer", "Devirtualize indirect calls") PASS(DiagnoseUnreachable, "diagnose-unreachable", "Diagnose Unreachable Code") PASS(DiagnosticConstantPropagation, "diagnostic-constant-propagation", @@ -79,6 +86,8 @@ PASS(EarlyInliner, "early-inline", "Inline functions that are not marked as having special semantics") PASS(EmitDFDiagnostics, "dataflow-diagnostics", "Emit SIL Diagnostics") +PASS(EscapeAnalysisDumper, "escapes-dump", + "Dumps the results of escape analysis for all functions") PASS(ExternalDefsToDecls, "external-defs-to-decls", "Convert external definitions to decls") PASS(ExternalFunctionDefinitionsElimination, "external-func-definition-elim", @@ -89,11 +98,15 @@ PASS(FunctionSignatureOpts, "function-signature-opts", "Optimize Function Signatures") PASS(ARCSequenceOpts, "arc-sequence-opts", "Optimize sequences of retain/release opts by removing redundant inner " - "retain/release sequenes") + "retain/release sequences") +PASS(ARCLoopOpts, "arc-loop-opts", + "Run all arc loop passes") PASS(RedundantLoadElimination, "redundant-load-elim", "Multiple basic block redundant load elimination") PASS(DeadStoreElimination, "dead-store-elim", "Multiple basic block dead store elimination") +PASS(GenericSpecializer, "generic-specializer", + "Specialization of generic functions by static types") PASS(GlobalOpt, "global-opt", "Global variable optimizations") PASS(GlobalPropertyOpt, "global-property-opt", @@ -128,6 +141,8 @@ PASS(LoopRegionViewCFG, "loop-region-view-cfg", "Construct the loop region data structure and dump its contents as a pdf cfg") PASS(LoopRotate, "loop-rotate", "Rotate loops") +PASS(LoopUnroll, "loop-unroll", + "Unroll loops") PASS(LowerAggregateInstrs, "lower-aggregate-instrs", "Lower aggregate instructions to scalar instructions") PASS(MandatoryInlining, "mandatory-inlining", @@ -136,12 +151,14 @@ PASS(Mem2Reg, "mem2reg", "Promote stack allocations to SSA values") PASS(MemBehaviorDumper, "mem-behavior-dump", "Dump MemBehavior results from alias analysis for all instruction pairs") -PASS(MemLocationPrinter, "memlocation-dump", - "Dump MemLocation results from analyzing all accessed locations") +PASS(LSLocationPrinter, "lslocation-dump", + "Dump LSLocation results from analyzing all accessed locations") PASS(MergeCondFails, "merge-cond_fails", "Remove redundant overflow checks") PASS(NoReturnFolding, "noreturn-folding", "Add 'unreachable' after noreturn calls") +PASS(RCIdentityDumper, "rc-id-dumper", + "Dump the RCIdentity of all values in a function") // TODO: It makes no sense to have early inliner, late inliner, and // perf inliner in terms of names. PASS(PerfInliner, "inline", @@ -154,6 +171,8 @@ PASS(ReleaseDevirtualizer, "release-devirtualizer", "Devirtualize release-instructions") PASS(RemovePins, "remove-pins", "Remove pin/unpin pairs") +PASS(SideEffectsDumper, "side-effects-dump", + "Dumps the results of side-effect analysis for all functions") PASS(SILCleanup, "cleanup", "Cleanup SIL in preparation for IRGen") PASS(SILCombine, "sil-combine", @@ -181,10 +200,6 @@ PASS(StripDebugInfo, "strip-debug-info", "Strip debug info") PASS(SwiftArrayOpts, "array-specialize", "Specialize arrays") -PASS(UpdateEscapeAnalysis, "update-escapes", - "Update the escape analysis for all functions") -PASS(UpdateSideEffects, "side-effects", - "Update the side effect analysis for all functions") PASS(UsePrespecialized, "use-prespecialized", "Use pre-specialized functions") PASS_RANGE(AllPasses, AADumper, UsePrespecialized) diff --git a/include/swift/SILPasses/Passes.h b/include/swift/SILOptimizer/PassManager/Passes.h similarity index 90% rename from include/swift/SILPasses/Passes.h rename to include/swift/SILOptimizer/PassManager/Passes.h index e74ba2409c12d..4dc2f5fa1c399 100644 --- a/include/swift/SILPasses/Passes.h +++ b/include/swift/SILOptimizer/PassManager/Passes.h @@ -1,8 +1,8 @@ -//===-------- Passes.h - Swift Compiler SIL Pass Entrypoints ----*- C++ -*-===// +//===--- Passes.h - Swift Compiler SIL Pass Entrypoints ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -14,8 +14,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_PASSES_H -#define SWIFT_SILPASSES_PASSES_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_PASSES_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_PASSES_H #include "swift/SIL/SILModule.h" diff --git a/include/swift/SILPasses/PrettyStackTrace.h b/include/swift/SILOptimizer/PassManager/PrettyStackTrace.h similarity index 79% rename from include/swift/SILPasses/PrettyStackTrace.h rename to include/swift/SILOptimizer/PassManager/PrettyStackTrace.h index 1ae4c836c075a..f2449c927344e 100644 --- a/include/swift/SILPasses/PrettyStackTrace.h +++ b/include/swift/SILOptimizer/PassManager/PrettyStackTrace.h @@ -1,8 +1,8 @@ -//===--- PrettyStackTrace.h - PrettyStackTrace for Transforms -*- C++ -*---===// +//===--- PrettyStackTrace.h - PrettyStackTrace for Transforms ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_PRETTYSTACKTRACE_H -#define SWIFT_SILPASSES_PRETTYSTACKTRACE_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_PRETTYSTACKTRACE_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_PRETTYSTACKTRACE_H #include "llvm/Support/PrettyStackTrace.h" diff --git a/include/swift/SILPasses/Transforms.h b/include/swift/SILOptimizer/PassManager/Transforms.h similarity index 86% rename from include/swift/SILPasses/Transforms.h rename to include/swift/SILOptimizer/PassManager/Transforms.h index c9de30ddb5ba4..455b3ecb433b0 100644 --- a/include/swift/SILPasses/Transforms.h +++ b/include/swift/SILOptimizer/PassManager/Transforms.h @@ -1,18 +1,20 @@ -//===-- Transforms.h - Swift Transformations -------------------*- C++ -*-===// +//===--- Transforms.h - Swift Transformations ------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_TRANSFORMS_H -#define SWIFT_SILPASSES_TRANSFORMS_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_TRANSFORMS_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_TRANSFORMS_H + +#include "swift/SIL/Notifications.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" -#include "swift/SILPasses/PassManager.h" namespace swift { class SILModule; @@ -20,7 +22,7 @@ namespace swift { class PrettyStackTraceSILFunctionTransform; /// The base class for all SIL-level transformations. - class SILTransform { + class SILTransform : public DeleteNotificationHandler { public: /// The kind of transformation passes we use. enum class TransformKind { @@ -94,6 +96,12 @@ namespace swift { void injectFunction(SILFunction *Func) { F = Func; } + /// \brief Notify the pass manager of a function that needs to be + /// processed by the function passes. + void notifyPassManagerOfFunction(SILFunction *F) { + PM->addFunctionToWorklist(F); + } + protected: SILFunction *getFunction() { return F; } @@ -137,4 +145,3 @@ namespace swift { } // end namespace swift #endif - diff --git a/include/swift/SILOptimizer/Utils/CFG.h b/include/swift/SILOptimizer/Utils/CFG.h new file mode 100644 index 0000000000000..7e86832e00b43 --- /dev/null +++ b/include/swift/SILOptimizer/Utils/CFG.h @@ -0,0 +1,132 @@ +//===--- CFG.h - Utilities for SIL CFG transformations ----------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SILOPTIMIZER_UTILS_CFG_H +#define SWIFT_SILOPTIMIZER_UTILS_CFG_H + +#include "swift/SIL/SILInstruction.h" +#include "swift/SIL/SILBuilder.h" + +namespace swift { + +class DominanceInfo; +class SILLoop; +class SILLoopInfo; + +/// \brief Adds a new argument to an edge between a branch and a destination +/// block. +/// +/// \param Branch The terminator to add the argument to. +/// \param Dest The destination block of the edge. +/// \param Val The value to the arguments of the branch. +/// \return The created branch. The old branch is deleted. +/// The argument is appended at the end of the argument tuple. +TermInst *addNewEdgeValueToBranch(TermInst *Branch, SILBasicBlock *Dest, + SILValue Val); + +/// \brief Changes the edge value between a branch and destination basic block +/// at the specified index. Changes all edges from \p Branch to \p Dest to carry +/// the value. +/// +/// \param Branch The branch to modify. +/// \param Dest The destination of the edge. +/// \param Idx The index of the argument to modify. +/// \param Val The new value to use. +/// \return The new branch. Deletes the old one. +TermInst *changeEdgeValue(TermInst *Branch, SILBasicBlock *Dest, size_t Idx, + SILValue Val); + +/// \brief Replace a branch target. +/// +/// \param T The terminating instruction to modify. +/// \param EdgeIdx The successor edges index that will be replaced. +/// \param NewDest The new target block. +/// \param PreserveArgs If set, preserve arguments on the replaced edge. +void changeBranchTarget(TermInst *T, unsigned EdgeIdx, SILBasicBlock *NewDest, + bool PreserveArgs); + +/// \brief Replace a branch target. +/// +/// \param T The terminating instruction to modify. +/// \param OldDest The successor block that will be replaced. +/// \param NewDest The new target block. +/// \param PreserveArgs If set, preserve arguments on the replaced edge. +void replaceBranchTarget(TermInst *T, SILBasicBlock *OldDest, SILBasicBlock *NewDest, + bool PreserveArgs); + +/// \brief Check if the edge from the terminator is critical. +bool isCriticalEdge(TermInst *T, unsigned EdgeIdx); + +/// \brief Splits the edge from terminator if it is critical. +/// +/// Updates dominance information and loop information if not null. +/// Returns the newly created basic block on success or nullptr otherwise (if +/// the edge was not critical). +SILBasicBlock *splitCriticalEdge(TermInst *T, unsigned EdgeIdx, + DominanceInfo *DT = nullptr, + SILLoopInfo *LI = nullptr); + +/// Splits the critical edges between from and to. This code assumes there is +/// exactly one edge between the two basic blocks. It will return the wrong +/// result if there are multiple edges and will assert if there are no edges in +/// between the two blocks. +/// +/// Updates dominance information and loop information if not null. +SILBasicBlock *splitIfCriticalEdge(SILBasicBlock *From, SILBasicBlock *To, + DominanceInfo *DT = nullptr, + SILLoopInfo *LI = nullptr); + +/// \brief Splits the edge from terminator. +/// +/// Updates dominance information and loop information if not null. +/// Returns the newly created basic block. +SILBasicBlock *splitEdge(TermInst *T, unsigned EdgeIdx, + DominanceInfo *DT = nullptr, + SILLoopInfo *LI = nullptr); + +/// \brief Splits the edges between two basic blocks. +/// +/// Updates dominance information and loop information if not null. +void splitEdgesFromTo(SILBasicBlock *From, SILBasicBlock *To, + DominanceInfo *DT = nullptr, SILLoopInfo *LI = nullptr); + +/// \brief Rotate a loop's header as long as it is exiting and not equal to the +/// passed basic block. +/// If \p RotateSingleBlockLoops is true a single basic block loop will be +/// rotated once. ShouldVerify specifies whether to perform verification after +/// the transformation. +/// Returns true if the loop could be rotated. +bool rotateLoop(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI, + bool RotateSingleBlockLoops, SILBasicBlock *UpTo, + bool ShouldVerify); + +/// \brief Splits the basic block before the instruction with an unconditional +/// branch and updates the dominator tree and loop info. +SILBasicBlock *splitBasicBlockAndBranch(SILBuilder &B, + SILInstruction *SplitBeforeInst, + DominanceInfo *DT, SILLoopInfo *LI); + +/// \brief Split all critical edges in the function updating the dominator tree +/// and loop information (if they are not set to null). If \p OnlyNonCondBr is +/// true this will not split cond_br edges (Only edges which can't carry +/// arguments will be split). +bool splitAllCriticalEdges(SILFunction &F, bool OnlyNonCondBr, + DominanceInfo *DT, SILLoopInfo *LI); + +/// \brief Merge a basic block ending in a branch with its successor +/// if possible. If dominance information or loop info is non null update it. +/// Return true if block was merged. +bool mergeBasicBlockWithSuccessor(SILBasicBlock *BB, DominanceInfo *DT, + SILLoopInfo *LI); + +} // End namespace swift. +#endif diff --git a/include/swift/SILPasses/Utils/ConstantFolding.h b/include/swift/SILOptimizer/Utils/ConstantFolding.h similarity index 93% rename from include/swift/SILPasses/Utils/ConstantFolding.h rename to include/swift/SILOptimizer/Utils/ConstantFolding.h index a5ad216cc1369..4e90407b7073b 100644 --- a/include/swift/SILPasses/Utils/ConstantFolding.h +++ b/include/swift/SILOptimizer/Utils/ConstantFolding.h @@ -1,8 +1,8 @@ -//===-- ConstantFolding.h - Utilities for SIL constant folding --*- C++ -*-===// +//===--- ConstantFolding.h - Utilities for SIL constant folding -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SILPasses/Utils/Devirtualize.h b/include/swift/SILOptimizer/Utils/Devirtualize.h similarity index 82% rename from include/swift/SILPasses/Utils/Devirtualize.h rename to include/swift/SILOptimizer/Utils/Devirtualize.h index a9aa941ca03e2..ede616148a8c7 100644 --- a/include/swift/SILPasses/Utils/Devirtualize.h +++ b/include/swift/SILOptimizer/Utils/Devirtualize.h @@ -1,8 +1,8 @@ -//===-- Devirtualize.h - Helper for devirtualizing apply --------*- C++ -*-===// +//===--- Devirtualize.h - Helper for devirtualizing apply -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -26,7 +26,8 @@ #include "swift/SIL/SILModule.h" #include "swift/SIL/SILType.h" #include "swift/SIL/SILValue.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/ArrayRef.h" namespace swift { @@ -43,7 +44,9 @@ namespace swift { typedef std::pair DevirtualizationResult; DevirtualizationResult tryDevirtualizeApply(FullApplySite AI); -bool isClassWithUnboundGenericParameters(SILType C, SILModule &M); +DevirtualizationResult tryDevirtualizeApply(FullApplySite AI, + ClassHierarchyAnalysis *CHA); +bool isNominalTypeWithUnboundGenericParameters(SILType Ty, SILModule &M); bool canDevirtualizeClassMethod(FullApplySite AI, SILType ClassInstanceType); DevirtualizationResult devirtualizeClassMethod(FullApplySite AI, SILValue ClassInstance); diff --git a/include/swift/SILPasses/Utils/GenericCloner.h b/include/swift/SILOptimizer/Utils/GenericCloner.h similarity index 92% rename from include/swift/SILPasses/Utils/GenericCloner.h rename to include/swift/SILOptimizer/Utils/GenericCloner.h index 8812c3153c6da..19950dec2e244 100644 --- a/include/swift/SILPasses/Utils/GenericCloner.h +++ b/include/swift/SILOptimizer/Utils/GenericCloner.h @@ -1,8 +1,8 @@ -//===-- GenericCloner.h - Specializes generic functions --------*- C++ -*-===// +//===--- GenericCloner.h - Specializes generic functions -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // -// This containts the definition of a cloner class for creating specialized +// This contains the definition of a cloner class for creating specialized // versions of generic functions by substituting concrete types. // //===----------------------------------------------------------------------===// @@ -22,7 +22,7 @@ #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/TypeSubstCloner.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include diff --git a/include/swift/SILPasses/Utils/Generics.h b/include/swift/SILOptimizer/Utils/Generics.h similarity index 86% rename from include/swift/SILPasses/Utils/Generics.h rename to include/swift/SILOptimizer/Utils/Generics.h index 1461d4d0edc02..9accb8cc504d6 100644 --- a/include/swift/SILPasses/Utils/Generics.h +++ b/include/swift/SILOptimizer/Utils/Generics.h @@ -1,8 +1,8 @@ -//===-- Generics.h - Utilities for transforming generics --------*- C++ -*-===// +//===--- Generics.h - Utilities for transforming generics -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // -// This containts utilities for transforming generics. +// This contains utilities for transforming generics. // //===----------------------------------------------------------------------===// @@ -21,7 +21,7 @@ #include "swift/SIL/Mangle.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" diff --git a/include/swift/SILPasses/Utils/Local.h b/include/swift/SILOptimizer/Utils/Local.h similarity index 98% rename from include/swift/SILPasses/Utils/Local.h rename to include/swift/SILOptimizer/Utils/Local.h index c19a90319ec03..dcaf88a127162 100644 --- a/include/swift/SILPasses/Utils/Local.h +++ b/include/swift/SILOptimizer/Utils/Local.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,11 +10,11 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_UTILS_LOCAL_H -#define SWIFT_SILPASSES_UTILS_LOCAL_H +#ifndef SWIFT_SILOPTIMIZER_UTILS_LOCAL_H +#define SWIFT_SILOPTIMIZER_UTILS_LOCAL_H #include "swift/Basic/ArrayRefView.h" -#include "swift/SILAnalysis/SimplifyInstruction.h" +#include "swift/SILOptimizer/Analysis/SimplifyInstruction.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILCloner.h" @@ -485,7 +485,7 @@ class CastOptimizer { SILInstruction * optimizeUnconditionalCheckedCastAddrInst(UnconditionalCheckedCastAddrInst *Inst); - /// Check if is is a bridged cast and optimize it. + /// Check if it is a bridged cast and optimize it. /// May change the control flow. SILInstruction * optimizeBridgedCasts(SILInstruction *Inst, @@ -571,7 +571,7 @@ class IgnoreExpectUseIterator Operand *operator*() const { return *CurrentIter; } Operand *operator->() const { return *CurrentIter; } - SILInstruction *getUser() const { return this->getUser(); } + SILInstruction *getUser() const { return CurrentIter->getUser(); } IgnoreExpectUseIterator &operator++() { assert(**this && "increment past end()!"); diff --git a/include/swift/SILOptimizer/Utils/LoopUtils.h b/include/swift/SILOptimizer/Utils/LoopUtils.h new file mode 100644 index 0000000000000..999d7831ecb2c --- /dev/null +++ b/include/swift/SILOptimizer/Utils/LoopUtils.h @@ -0,0 +1,90 @@ +//===--- LoopUtils.h ------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +/// +/// This header file declares utility functions for simplifying and +/// canonicalizing loops. +/// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SILOPTIMIZER_UTILS_LOOPUTILS_H +#define SWIFT_SILOPTIMIZER_UTILS_LOOPUTILS_H + +#include "llvm/ADT/SmallVector.h" + +namespace swift { + +class SILFunction; +class SILBasicBlock; +class SILLoop; +class DominanceInfo; +class SILLoopInfo; + +/// Canonicalize the loop for rotation and downstream passes. +/// +/// Create a single preheader and single latch block. +bool canonicalizeLoop(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI); + +/// Canonicalize all loops in the function F for which \p LI contains loop +/// information. We update loop info and dominance info while we do this. +bool canonicalizeAllLoops(DominanceInfo *DT, SILLoopInfo *LI); + +/// A visitor that visits loops in a function in a bottom up order. It only +/// performs the visit. +class SILLoopVisitor { + SILFunction *F; + SILLoopInfo *LI; + +public: + SILLoopVisitor(SILFunction *Func, SILLoopInfo *LInfo) : F(Func), LI(LInfo) {} + virtual ~SILLoopVisitor() {} + + void run(); + + SILFunction *getFunction() const { return F; } + + virtual void runOnLoop(SILLoop *L) = 0; + virtual void runOnFunction(SILFunction *F) = 0; +}; + +/// A group of sil loop visitors, run in sequence on a function. +class SILLoopVisitorGroup : public SILLoopVisitor { + /// The list of visitors to run. + /// + /// This is set to 3, since currently the only place this is used will have at + /// most 3 such visitors. + llvm::SmallVector Visitors; + +public: + SILLoopVisitorGroup(SILFunction *Func, SILLoopInfo *LInfo) + : SILLoopVisitor(Func, LInfo) {} + virtual ~SILLoopVisitorGroup() {} + + void addVisitor(SILLoopVisitor *V) { + Visitors.push_back(V); + } + + void runOnLoop(SILLoop *L) override { + for (auto *V : Visitors) { + V->runOnLoop(L); + } + } + + void runOnFunction(SILFunction *F) override { + for (auto *V : Visitors) { + V->runOnFunction(F); + } + } +}; + +} // end swift namespace + +#endif diff --git a/include/swift/SILPasses/Utils/SCCVisitor.h b/include/swift/SILOptimizer/Utils/SCCVisitor.h similarity index 88% rename from include/swift/SILPasses/Utils/SCCVisitor.h rename to include/swift/SILOptimizer/Utils/SCCVisitor.h index 71e88429c34bc..301e1876a4bca 100644 --- a/include/swift/SILPasses/Utils/SCCVisitor.h +++ b/include/swift/SILOptimizer/Utils/SCCVisitor.h @@ -1,8 +1,8 @@ -//===------------------- SCCVisitor.h - SIL SCC Visitor -------*- C++ -*---===// +//===--- SCCVisitor.h - SIL SCC Visitor -------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -13,7 +13,7 @@ #ifndef SWIFT_SIL_SCCVISITOR_H #define SWIFT_SIL_SCCVISITOR_H -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "swift/SIL/CFG.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBasicBlock.h" @@ -107,11 +107,11 @@ class SCCVisitor { void getArgsForTerminator(TermInst *Term, SILBasicBlock *SuccBB, int Index, llvm::SmallVectorImpl &Operands) { - switch (Term->getKind()) { - case ValueKind::BranchInst: + switch (Term->getTermKind()) { + case TermKind::BranchInst: return Operands.push_back(cast(Term)->getArg(Index).getDef()); - case ValueKind::CondBranchInst: { + case TermKind::CondBranchInst: { auto *CBI = cast(Term); if (SuccBB == CBI->getTrueBB()) return Operands.push_back(CBI->getTrueArgs()[Index].getDef()); @@ -121,27 +121,26 @@ class SCCVisitor { return; } - case ValueKind::SwitchEnumInst: - case ValueKind::SwitchEnumAddrInst: - case ValueKind::CheckedCastBranchInst: - case ValueKind::CheckedCastAddrBranchInst: - case ValueKind::DynamicMethodBranchInst: + case TermKind::SwitchEnumInst: + case TermKind::SwitchEnumAddrInst: + case TermKind::CheckedCastBranchInst: + case TermKind::CheckedCastAddrBranchInst: + case TermKind::DynamicMethodBranchInst: assert(Index == 0 && "Expected argument index to always be zero!"); return Operands.push_back(Term->getOperand(0).getDef()); - case ValueKind::UnreachableInst: - case ValueKind::ReturnInst: - case ValueKind::AutoreleaseReturnInst: - case ValueKind::SwitchValueInst: - case ValueKind::ThrowInst: + case TermKind::UnreachableInst: + case TermKind::ReturnInst: + case TermKind::SwitchValueInst: + case TermKind::ThrowInst: llvm_unreachable("Did not expect terminator that does not have args!"); - case ValueKind::TryApplyInst: + case TermKind::TryApplyInst: for (auto &O : cast(Term)->getAllOperands()) Operands.push_back(O.get().getDef()); return; - default: + case TermKind::Invalid: llvm_unreachable("Unhandled terminator kind!"); } } diff --git a/include/swift/SILPasses/Utils/SILInliner.h b/include/swift/SILOptimizer/Utils/SILInliner.h similarity index 98% rename from include/swift/SILPasses/Utils/SILInliner.h rename to include/swift/SILOptimizer/Utils/SILInliner.h index 1ae2ab1146598..ac0495470057b 100644 --- a/include/swift/SILPasses/Utils/SILInliner.h +++ b/include/swift/SILOptimizer/Utils/SILInliner.h @@ -1,8 +1,8 @@ -//===--- SILInliner.h - Inlines SIL functions --------------------*- C++ -*-==// +//===--- SILInliner.h - Inlines SIL functions -------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SILPasses/Utils/SILSSAUpdater.h b/include/swift/SILOptimizer/Utils/SILSSAUpdater.h similarity index 97% rename from include/swift/SILPasses/Utils/SILSSAUpdater.h rename to include/swift/SILOptimizer/Utils/SILSSAUpdater.h index 15491c1ce59d2..a16217ea28f89 100644 --- a/include/swift/SILPasses/Utils/SILSSAUpdater.h +++ b/include/swift/SILOptimizer/Utils/SILSSAUpdater.h @@ -1,8 +1,8 @@ -//===------ SILSSAUpdater.h - Unstructured SSA Update Tool ------*- C++ -*-===// +//===--- SILSSAUpdater.h - Unstructured SSA Update Tool ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SILPasses/Utils/CFG.h b/include/swift/SILPasses/Utils/CFG.h deleted file mode 100644 index 71c25da78591c..0000000000000 --- a/include/swift/SILPasses/Utils/CFG.h +++ /dev/null @@ -1,132 +0,0 @@ -//===--- CFG.h - Utilities for SIL CFG transformations ----------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SILPASSES_UTILS_CFG_H -#define SWIFT_SILPASSES_UTILS_CFG_H - -#include "swift/SIL/SILInstruction.h" -#include "swift/SIL/SILBuilder.h" - -namespace swift { - -class DominanceInfo; -class SILLoop; -class SILLoopInfo; - -/// \brief Adds a new argument to an edge between a branch and a destination -/// block. -/// -/// \param Branch The terminator to add the argument to. -/// \param Dest The destination block of the edge. -/// \param Val The value to the arguments of the branch. -/// \return The created branch. The old branch is deleted. -/// The argument is appended at the end of the argument tuple. -TermInst *addNewEdgeValueToBranch(TermInst *Branch, SILBasicBlock *Dest, - SILValue Val); - -/// \brief Changes the edge value between a branch and destination basic block -/// at the specified index. Changes all edges from \p Branch to \p Dest to carry -/// the value. -/// -/// \param Branch The branch to modify. -/// \param Dest The destination of the edge. -/// \param Idx The index of the argument to modify. -/// \param Val The new value to use. -/// \return The new branch. Deletes the old one. -TermInst *changeEdgeValue(TermInst *Branch, SILBasicBlock *Dest, size_t Idx, - SILValue Val); - -/// \brief Replace a branch target. -/// -/// \param T The terminating instruction to modify. -/// \param EdgeIdx The successor edges index that will be replaced. -/// \param NewDest The new target block. -/// \param PreserveArgs If set, preserve arguments on the replaced edge. -void changeBranchTarget(TermInst *T, unsigned EdgeIdx, SILBasicBlock *NewDest, - bool PreserveArgs); - -/// \brief Replace a branch target. -/// -/// \param T The terminating instruction to modify. -/// \param OldDest The successor block that will be replaced. -/// \param NewDest The new target block. -/// \param PreserveArgs If set, preserve arguments on the replaced edge. -void replaceBranchTarget(TermInst *T, SILBasicBlock *OldDest, SILBasicBlock *NewDest, - bool PreserveArgs); - -/// \brief Check if the edge from the terminator is critical. -bool isCriticalEdge(TermInst *T, unsigned EdgeIdx); - -/// \brief Splits the edge from terminator if it is critical. -/// -/// Updates dominance information and loop information if not null. -/// Returns the newly created basic block on success or nullptr otherwise (if -/// the edge was not critical). -SILBasicBlock *splitCriticalEdge(TermInst *T, unsigned EdgeIdx, - DominanceInfo *DT = nullptr, - SILLoopInfo *LI = nullptr); - -/// Splits the critical edges between from and to. This code assumes there is -/// exactly one edge between the two basic blocks. It will return the wrong -/// result if there are multiple edges and will assert if there are no edges in -/// between the two blocks. -/// -/// Updates dominance information and loop information if not null. -SILBasicBlock *splitIfCriticalEdge(SILBasicBlock *From, SILBasicBlock *To, - DominanceInfo *DT = nullptr, - SILLoopInfo *LI = nullptr); - -/// \brief Splits the edge from terminator. -/// -/// Updates dominance information and loop information if not null. -/// Returns the newly created basic block. -SILBasicBlock *splitEdge(TermInst *T, unsigned EdgeIdx, - DominanceInfo *DT = nullptr, - SILLoopInfo *LI = nullptr); - -/// \brief Splits the edges between two basic blocks. -/// -/// Updates dominance information and loop information if not null. -void splitEdgesFromTo(SILBasicBlock *From, SILBasicBlock *To, - DominanceInfo *DT = nullptr, SILLoopInfo *LI = nullptr); - -/// \brief Rotate a loop's header as long as it is exiting and not equal to the -/// passed basic block. -/// If \p RotateSingleBlockLoops is true a single basic block loop will be -/// rotated once. ShouldVerify specifies whether to perform verification after -/// the transformation. -/// Returns true if the loop could be rotated. -bool rotateLoop(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI, - bool RotateSingleBlockLoops, SILBasicBlock *UpTo, - bool ShouldVerify); - -/// \brief Splits the basic block before the instruction with an unconditional -/// branch and updates the dominator tree and loop info. -SILBasicBlock *splitBasicBlockAndBranch(SILBuilder &B, - SILInstruction *SplitBeforeInst, - DominanceInfo *DT, SILLoopInfo *LI); - -/// \brief Split all critical edges in the function updating the dominator tree -/// and loop information (if they are not set to null). If \p OnlyNonCondBr is -/// true this will not split cond_br edges (Only edges which can't carry -/// arguments will be split). -bool splitAllCriticalEdges(SILFunction &F, bool OnlyNonCondBr, - DominanceInfo *DT, SILLoopInfo *LI); - -/// \brief Merge a basic block ending in a branch with its successor -/// if possible. If dominance information or loop info is non null update it. -/// Return true if block was merged. -bool mergeBasicBlockWithSuccessor(SILBasicBlock *BB, DominanceInfo *DT, - SILLoopInfo *LI); - -} // End namespace swift. -#endif diff --git a/include/swift/SILPasses/Utils/LoopUtils.h b/include/swift/SILPasses/Utils/LoopUtils.h deleted file mode 100644 index c3710cdbbea50..0000000000000 --- a/include/swift/SILPasses/Utils/LoopUtils.h +++ /dev/null @@ -1,58 +0,0 @@ -//===--- LoopUtils.h ------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -/// -/// This header file declares utility functions for simplifying and -/// canonicalizing loops. -/// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_SILPASSES_UTILS_LOOPUTILS_H -#define SWIFT_SILPASSES_UTILS_LOOPUTILS_H - -namespace swift { - -class SILFunction; -class SILBasicBlock; -class SILLoop; -class DominanceInfo; -class SILLoopInfo; - -/// Canonicalize the loop for rotation and downstream passes. -/// -/// Create a single preheader and single latch block. -bool canonicalizeLoop(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI); - -/// Canonicalize all loops in the function F for which \p LI contains loop -/// information. We update loop info and dominance info while we do this. -bool canonicalizeAllLoops(DominanceInfo *DT, SILLoopInfo *LI); - -/// A visitor that visits loops in a function in a bottom up order. It only -/// performs the visit. -class SILLoopVisitor { - SILFunction *F; - SILLoopInfo *LI; - -public: - SILLoopVisitor(SILFunction *Func, SILLoopInfo *LInfo) : F(Func), LI(LInfo) {} - virtual ~SILLoopVisitor() {} - - void run(); - - SILFunction *getFunction() const { return F; } - - virtual void runOnLoop(SILLoop *L) = 0; - virtual void runOnFunction(SILFunction *F) = 0; -}; - -} // end swift namespace - -#endif diff --git a/include/swift/Sema/CodeCompletionTypeChecking.h b/include/swift/Sema/CodeCompletionTypeChecking.h index c0c512df439e3..272b576c7d2d4 100644 --- a/include/swift/Sema/CodeCompletionTypeChecking.h +++ b/include/swift/Sema/CodeCompletionTypeChecking.h @@ -1,8 +1,8 @@ -//===--- CodeCompletionTypeChecking.h - Type-check entry points -*- c++ -*-===// +//===--- CodeCompletionTypeChecking.h - Type-check entry points -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Sema/IterativeTypeChecker.h b/include/swift/Sema/IterativeTypeChecker.h index fbaafa2ea670c..64e53a6ebd214 100644 --- a/include/swift/Sema/IterativeTypeChecker.h +++ b/include/swift/Sema/IterativeTypeChecker.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -33,7 +33,7 @@ class TypeChecker; /// An iterative type checker that processes type check requests to /// ensure that the AST has the information needed by the client. class IterativeTypeChecker { - /// The underyling (non-iterative) type checker on which this iterative + /// The underlying (non-iterative) type checker on which this iterative /// type checker depends. /// /// Each dependency on the non-iterative type checker potentially diff --git a/include/swift/Sema/SourceLoader.h b/include/swift/Sema/SourceLoader.h index c0b63c6432b4b..8d55825cb2a67 100644 --- a/include/swift/Sema/SourceLoader.h +++ b/include/swift/Sema/SourceLoader.h @@ -1,8 +1,8 @@ -//===--- SourceLoader.h - Import .swift files as modules --------*- c++ -*-===// +//===--- SourceLoader.h - Import .swift files as modules --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Sema/TypeCheckRequest.h b/include/swift/Sema/TypeCheckRequest.h index b5767e54cf93b..a4f6957b8ed91 100644 --- a/include/swift/Sema/TypeCheckRequest.h +++ b/include/swift/Sema/TypeCheckRequest.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -114,7 +114,42 @@ class TypeCheckRequest { } #include "swift/Sema/TypeCheckRequestPayloads.def" - + + TypeCheckRequest(const TypeCheckRequest &T) { *this = T; } + + TypeCheckRequest& operator=(const TypeCheckRequest &T) { + TheKind = T.getKind(); + switch (getPayloadKind(TheKind)) { + case PayloadKind::Class: + Payload.Class = T.Payload.Class; + break; + case PayloadKind::Enum: + Payload.Enum = T.Payload.Enum; + break; + case PayloadKind::InheritedClauseEntry: + new (&Payload.InheritedClauseEntry) + std::pair, unsigned>(); + Payload.InheritedClauseEntry = T.Payload.InheritedClauseEntry; + break; + case PayloadKind::Protocol: + Payload.Protocol = T.Payload.Protocol; + break; + case PayloadKind::DeclContextLookup: + new (&Payload.DeclContextLookup) DeclContextLookupInfo(); + Payload.DeclContextLookup = T.Payload.DeclContextLookup; + break; + case PayloadKind::TypeResolution: + new (&Payload.InheritedClauseEntry) + std::tuple(); + Payload.TypeResolution = T.Payload.TypeResolution; + break; + case PayloadKind::TypeDeclResolution: + Payload.TypeDeclResolution = T.Payload.TypeDeclResolution; + break; + } + return *this; + } + /// Determine the kind of type check request. Kind getKind() const { return TheKind; } diff --git a/include/swift/Sema/TypeCheckRequestKinds.def b/include/swift/Sema/TypeCheckRequestKinds.def index e90e6db7fc5b5..e64b81b3bf353 100644 --- a/include/swift/Sema/TypeCheckRequestKinds.def +++ b/include/swift/Sema/TypeCheckRequestKinds.def @@ -1,8 +1,8 @@ -//===-- TypeCheckRequestKinds.def - Type Checking Request Kinds -*- C++ -*-===// +//===--- TypeCheckRequestKinds.def - Type Check Request Kinds ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Sema/TypeCheckRequestPayloads.def b/include/swift/Sema/TypeCheckRequestPayloads.def index ab5444e1375ba..53a7eedf5fe0d 100644 --- a/include/swift/Sema/TypeCheckRequestPayloads.def +++ b/include/swift/Sema/TypeCheckRequestPayloads.def @@ -1,8 +1,8 @@ -//===-- TypeCheckRequestPayloads.def - Type Checking Payloads ---*- C++ -*-===// +//===--- TypeCheckRequestPayloads.def - Type Checking Payloads --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Serialization/BCReadingExtras.h b/include/swift/Serialization/BCReadingExtras.h index b4dca346de4be..3607ddd7b86db 100644 --- a/include/swift/Serialization/BCReadingExtras.h +++ b/include/swift/Serialization/BCReadingExtras.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Serialization/DeclTypeRecordNodes.def b/include/swift/Serialization/DeclTypeRecordNodes.def index bfcec568401d1..b2e4e55a3b291 100644 --- a/include/swift/Serialization/DeclTypeRecordNodes.def +++ b/include/swift/Serialization/DeclTypeRecordNodes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -149,6 +149,8 @@ PATTERN(NOMINAL_TYPE) TRAILING_INFO(NOMINAL_TYPE_PATTERN_ELT) PATTERN(VAR) +OTHER(PARAMETERLIST, 226) +OTHER(PARAMETERLIST_ELT, 227) OTHER(FOREIGN_ERROR_CONVENTION, 228) OTHER(DECL_CONTEXT, 229) OTHER(XREF_TYPE_PATH_PIECE, 230) diff --git a/include/swift/Serialization/ModuleFile.h b/include/swift/Serialization/ModuleFile.h index 601b4c6063db0..c8a743bb51cc3 100644 --- a/include/swift/Serialization/ModuleFile.h +++ b/include/swift/Serialization/ModuleFile.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -341,7 +341,7 @@ class ModuleFile : public LazyMemberLoader { template T *createDecl(Args &&... args); - /// Constructs an new module and validates it. + /// Constructs a new module and validates it. ModuleFile(std::unique_ptr moduleInputBuffer, std::unique_ptr moduleDocInputBuffer, bool isFramework, serialization::ExtendedValidationInfo *extInfo); @@ -408,6 +408,8 @@ class ModuleFile : public LazyMemberLoader { /// If the record at the cursor is not a pattern, returns null. Pattern *maybeReadPattern(); + ParameterList *readParameterList(); + GenericParamList *maybeGetOrReadGenericParams(serialization::DeclID contextID, DeclContext *DC, llvm::BitstreamCursor &Cursor); @@ -519,7 +521,7 @@ class ModuleFile : public LazyMemberLoader { /// Note that this may cause other decls to load as well. void loadExtensions(NominalTypeDecl *nominal); - /// \brief Load the methods within the given class that that produce + /// \brief Load the methods within the given class that produce /// Objective-C class or instance methods with the given selector. /// /// \param classDecl The class in which we are searching for @objc methods. @@ -589,8 +591,7 @@ class ModuleFile : public LazyMemberLoader { void verify() const; virtual void loadAllMembers(Decl *D, - uint64_t contextData, - bool *ignored) override; + uint64_t contextData) override; virtual void loadAllConformances(const Decl *D, uint64_t contextData, diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h index 1a5abb62bd3a9..a6986a587df15 100644 --- a/include/swift/Serialization/ModuleFormat.h +++ b/include/swift/Serialization/ModuleFormat.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -50,8 +50,9 @@ const uint16_t VERSION_MAJOR = 0; /// When the format changes IN ANY WAY, this number should be incremented. /// To ensure that two separate changes don't silently get merged into one /// in source control, you should also update the comment to briefly -/// describe what change you made. -const uint16_t VERSION_MINOR = 222; // Last change: @_fixed_layout +/// describe what change you made. The content of this comment isn't important; +/// it just ensures a conflict if two people change the module format. +const uint16_t VERSION_MINOR = 229; // alloc_stack returns a single value using DeclID = Fixnum<31>; using DeclIDField = BCFixed<31>; @@ -179,13 +180,14 @@ enum class ParameterConvention : uint8_t { Indirect_In, Indirect_Out, Indirect_Inout, + Indirect_InoutAliasable, Direct_Owned, Direct_Unowned, Direct_Guaranteed, Indirect_In_Guaranteed, Direct_Deallocating, }; -using ParameterConventionField = BCFixed<3>; +using ParameterConventionField = BCFixed<4>; // These IDs must \em not be renumbered or reordered without incrementing // VERSION_MAJOR. @@ -265,8 +267,11 @@ enum class DefaultArgumentKind : uint8_t { Function, Inherited, DSOHandle, + Nil, + EmptyArray, + EmptyDictionary, }; -using DefaultArgumentField = BCFixed<3>; +using DefaultArgumentField = BCFixed<4>; // These IDs must \em not be renumbered or reordered without incrementing // VERSION_MAJOR. @@ -989,6 +994,17 @@ namespace decls_block { // Trailed by a pattern for self. >; + using ParameterListLayout = BCRecordLayout< + PARAMETERLIST, + BCVBR<5> // numparams + >; + + using ParameterListEltLayout = BCRecordLayout< + PARAMETERLIST_ELT, + DeclIDField, // ParamDecl + BCFixed<1>, // isVariadic? + DefaultArgumentField // default argument + >; using ParenPatternLayout = BCRecordLayout< PAREN_PATTERN, @@ -1006,9 +1022,7 @@ namespace decls_block { using TuplePatternEltLayout = BCRecordLayout< TUPLE_PATTERN_ELT, - IdentifierIDField, // label - BCFixed<1>, // has ellipsis? - DefaultArgumentField // default argument + IdentifierIDField // label // The element pattern trails the record. >; @@ -1116,10 +1130,10 @@ namespace decls_block { BCVBR<5>, // inherited conformances count BCVBR<5>, // defaulted definitions count BCArray - // The array contains value-value-substitutionCount triplets, + // The array contains archetype-value pairs, // then type declarations, then defaulted definitions. // Inherited conformances follow, then the substitution records for the - // values and then types. + // associated types. >; using SpecializedProtocolConformanceLayout = BCRecordLayout< @@ -1338,6 +1352,13 @@ namespace decls_block { // strings, separated by the prior index >; + using MigrationIdDeclAttrLayout = BCRecordLayout< + MigrationId_DECL_ATTR, + BCVBR<6>, // index at the end of the ident, + BCBlob // blob contains the ident and pattern + // strings, separated by the prior index + >; + #define SIMPLE_DECL_ATTR(X, CLASS, ...) \ using CLASS##DeclAttrLayout = BCRecordLayout< \ CLASS##_DECL_ATTR, \ diff --git a/include/swift/Serialization/SerializationOptions.h b/include/swift/Serialization/SerializationOptions.h index 8321f273aaa98..c96c280ea429c 100644 --- a/include/swift/Serialization/SerializationOptions.h +++ b/include/swift/Serialization/SerializationOptions.h @@ -1,8 +1,8 @@ -//===--- SerializationOptions.h - Control swiftmodule emission --*- c++ -*-===// +//===--- SerializationOptions.h - Control swiftmodule emission --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Serialization/SerializedModuleLoader.h b/include/swift/Serialization/SerializedModuleLoader.h index a97a130bdecae..ac190249e77ad 100644 --- a/include/swift/Serialization/SerializedModuleLoader.h +++ b/include/swift/Serialization/SerializedModuleLoader.h @@ -1,8 +1,8 @@ -//===--- SerializedModuleLoader.h - Import Swift modules --------*- c++ -*-===// +//===--- SerializedModuleLoader.h - Import Swift modules --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Serialization/SerializedSILLoader.h b/include/swift/Serialization/SerializedSILLoader.h index 190b48825d3b6..77781da5da405 100644 --- a/include/swift/Serialization/SerializedSILLoader.h +++ b/include/swift/Serialization/SerializedSILLoader.h @@ -1,8 +1,8 @@ -//===--- SerializedSILLoader.h - Handle SIL section in modules --*- c++ -*-===// +//===--- SerializedSILLoader.h - Handle SIL section in modules --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -43,7 +43,7 @@ class SerializedSILLoader { /// Observe that we successfully deserialized a function body. virtual void didDeserializeFunctionBody(ModuleDecl *M, SILFunction *fn) {} - /// Oberve that we successfully deserialized a witness table's entries. + /// Observe that we successfully deserialized a witness table's entries. virtual void didDeserializeWitnessTableEntries(ModuleDecl *M, SILWitnessTable *wt) {} diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h index 3869ab2492e33..3048dd4669b07 100644 --- a/include/swift/Serialization/Validation.h +++ b/include/swift/Serialization/Validation.h @@ -1,8 +1,8 @@ -//===--- Validation.h - Validation / errors for serialization ---*- c++ -*-===// +//===--- Validation.h - Validation / errors for serialization ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Strings.h b/include/swift/Strings.h index b377513b3b73e..6beae5727b808 100644 --- a/include/swift/Strings.h +++ b/include/swift/Strings.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h index 9b5b4cd8e6736..b02301877c217 100644 --- a/include/swift/Subsystems.h +++ b/include/swift/Subsystems.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SwiftDemangle/MangleHack.h b/include/swift/SwiftDemangle/MangleHack.h index a0d447546ed21..79c6eb00120aa 100644 --- a/include/swift/SwiftDemangle/MangleHack.h +++ b/include/swift/SwiftDemangle/MangleHack.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/include/swift/SwiftDemangle/SwiftDemangle.h b/include/swift/SwiftDemangle/SwiftDemangle.h index c3c0d71d1e0c2..166ce942221b3 100644 --- a/include/swift/SwiftDemangle/SwiftDemangle.h +++ b/include/swift/SwiftDemangle/SwiftDemangle.h @@ -1,8 +1,8 @@ -//===--- SwiftDemangle.h - Public demangling interface -----------*- C -*--===// +//===--- SwiftDemangle.h - Public demangling interface ----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/ABI/CBCTables.h b/lib/ABI/CBCTables.h new file mode 100644 index 0000000000000..aa9fb4b4978d7 --- /dev/null +++ b/lib/ABI/CBCTables.h @@ -0,0 +1,12958 @@ +#ifndef SWIFT_MANGLER_CBC_TABLE_H +#define SWIFT_MANGLER_CBC_TABLE_H +// This file is autogenerated. Do not modify this file. +// Processing text files: UIApp.txt coredylib.txt coregraphics.txt foundation.txt simd.txt unittests.txt +namespace CBC { +// The charset that the fragment indices can use: +const unsigned CharsetLength = 62; +const char *Charset = "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXZ$"; +const int IndexOfChar[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,61,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,-1,37,38,39,40,41,42,43,44,45,-1,46,47,48,49,50,51,52,53,54,55,56,57,58,59,-1,60,-1,-1,-1,-1,10,-1,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }; +const char EscapeChar0 = 'Y'; +const char EscapeChar1 = 'J'; +// The Fragments: +const unsigned NumFragments = 3567 ; +const char* CodeBook[] = { "S_S_S_S_","_S_S_S_S","_S_S_S_","S_S_S_S","S_S_S_","_S_S_S","_S_S_","S_S_S","ollectio","Collecti","llection","llectio","ollecti","Collect","_S_S","S_S_","ection","lection","ction","lectio","tion","llecti","ollect","Collec","ectio","Generato","Type","_S_","ibUnitte","tdlibUni","bUnittes","libUnitt","Unittest","dlibUnit","4StdlibU","14Stdlib","StdlibUn","S_S","enerator","ctio","enerato","Generat","lecti","llect","ollec","Colle","ecti","tio","dlibUni","nittest","bUnitte","libUnit","ibUnitt","tdlibUn","Unittes","StdlibU","14Stdli","4Stdlib","able","Index","nerator","enerat","ion","nerato","Genera","Sequenc","Typ","ype","ect","Sequence","ble","nittes","bUnitt","ittest","dlibUn","libUni","Unitte","ibUnit","tdlibU","Stdlib","4Stdli","14Stdl","lect","Inde","cti","erator","olle","llec","Coll","enera","nerat","ndex","equenc","Sequen","erato","Gener","equence","abl","9Generat","lectionT","rator","tdlib","ittes","Stdli","ttest","bUnit","Unitt","libUn","ibUni","dlibU","nitte","14Std","4Stdl","ctionTyp","table","V14Stdli","tionType","7Element","___","Element","eCollect","erat","nde","ectionTy","equen","quenc","quence","Seque","9Genera","ectionT","Equatabl","quatable","lec","Ind","ener","rato","nera","lle","oll","Col","Gene","_GS","tionTyp","ctionTy","7Elemen","V14Stdl","ionType","Elemen","lement","eCollec","dex","Buffer","ator","era","tdli","dlib","Unit","ctionT","est","test","14St","itte","ttes","ibUn","bUni","libU","Stdl","nitt","4Std","Equatab","quatabl","uatable","nerator7","ator7Ele","r7Elemen","rator7El","erator7E","or7Eleme","tor7Elem","ArrayBuf","rrayBuff","rayBuffe","9Gener","tabl","ayBuffer","uence","Types","S0_","eque","uenc","quen","Element_","enc","ement","Sequ","ionTyp","tionTy","tor","7Eleme","onType","V14Std","lemen","rat","eColle","Buffe","Eleme","Value","uffer","ner","14S","Uni","erator7","ator7El","r7Eleme","rator7E","or7Elem","tor7Ele","rayBuff","rrayBuf","ayBuffe","ArrayBu","Array","yBuffer","Equata","quatab","uatabl","atable","tionT","ato","que","ene","bleColle","leCollec","ableColl","nit","9Gene","S1_","Gen","equenceT","lement_","tte","ence","2Sequenc","quenceTy","uenceTyp","enceType","14Collec","4Collect","s14Colle","12Sequen","s12Seque","_Si","tes","dli","lib","tdl","ypes","onTyp","nType","4St","ionTy","7Elem","Std","V14St","itt","bUn","ibU","emen","alue","Vs1","eColl","ment","yBuffe","rator7","ator7E","tor7El","or7Ele","r7Elem","ArrayB","ayBuff","rrayBu","rayBuf","bleColl","leColle","ableCol","tab","leme","nittest1","rray","equ","uffe","Valu","Buff","nce","Equat","uatab","quata","atabl","Elem","quenceT","ffer","ubSequen","bSequenc","SubSeque","11SubSeq","1SubSequ","uen","ement_","Arra","2Sequen","uenceTy","enceTyp","nceType","Seq","4Collec","s14Coll","14Colle","ionT","s12Sequ","12Seque","Int","GVs","IndexTyp","ndexType","Si_","x9Genera","9Gen","Types_","SiS","Range","ctiona","__T","_SiSi","ittest1","_9Genera","ent","WxS","ableCo","bleCol","leColl","yBuff","ator7","r7Ele","or7El","tor7E","rrayB","nTyp","Forward","ayBuf","rayBu","___T","Equa","onTy","ubSeque","bSequen","11SubSe","SubSequ","1SubSeq","7Ele","V14S","uenceT","Wx9Gener","alu","eCol","Ran","___TF","S3_S4__","2Seque","nceTyp","enceTy","ceType","14Coll","4Colle","s14Col","ntiguous","ontiguou","Mutable","Contiguo","ndexTyp","IndexTy","12Sequ","s12Seq","tiona","dexType","eme","ment_","men","pes","x9Gener","S4_","S3_S4_","quat","uata","atab","uff","uousArra","tiguousA","iguousAr","guousArr","lue","rType","s12","S2_","ousArray","SiSi","s_SiSi","_s1","__TF","domAcces","ndomAcce","omAccess","RandomAc","andomAcc","_9Gener","Minimal","fer","eType","idirecti","directio","ectional","irection","rectiona","Bidirect","rra","lem","ttest1","__S","ray","ypes_","Val","eReplace","5Index","ffe","Buf","_s12Sequ","ange","s_Si","_S4_","RangeRep","ngeRepla","angeRepl","Replacea","laceable","placeabl","geReplac","eplaceab","Ele","ableC","orward","Forwar","Wx9Gene","siliency","iencyChe","esilienc","liencyCh","ncyCheck","encyChec","iliencyC","bleCo","bSeque","ubSequ","11SubS","1SubSe","SubSeq","leCol","_ArrayBu","cyChecks","__GS","S0__","Rang","Arr","s_S","enceT","tiguous","ontiguo","ntiguou","x11SubSe","wx11SubS","Contigu","onT","VS_","_SiS","TypesFS","3_S4__","heck","nittest2","utable","IndexT","S3_","uatableF","Mutabl","ndexTy","dexTyp","5Inde","exType","ousArra","uousArr","guousAr","iguousA","yBuf","tor7","or7E","r7El","rayB","2Sequ","ceTyp","nceTy","x9Gene","usArray","ayBu","s12Se","9Ge","s14Co","4Coll","14Col","domAcce","mAccess","omAcces","RandomA","andomAc","ndomAcc","12Seq","Bidirec","ectiona","directi","rection","idirect","ctional","irectio","eCo","Replace","_Contigu","_9Gene","Minima","inimal","3_S4_","S3_S4","qua","wx5Index","eReplac","TSg5","_s12Seq","ValueF","ngeRepl","RangeRe","laceabl","eplacea","angeRep","placeab","geRepla","aceable","s_SiS","iona","ent_","nTy","Equ","_S0_","_ArrayB","tional","ncyChec","esilien","silienc","cyCheck","iencyCh","wx5Inde","liencyC","encyChe","iliency","7El","yChecks","GVs1","V14","rTyp","test1","_S0__","_S4__","Wx9Gen","x11SubS","wx11Sub","ceableCo","aceableC","eableCol","ittest2","5In","eTyp","ontigu","iguous","tiguou","ntiguo","orwar","Forwa","rward","Contig","atableF","x5Index","ata","iSi","bSequ","ubSeq","11Sub","SubSe","1SubS","TypesF","ypesFS","eplace","uat","nceT","pes_","hecks","_Si_","__G","usArra","guousA","ousArr","uousAr","bleC","_SiSiS","xType","sArray","Integer","_TF","ndexT","utabl","ter","Check","_S0","leCo","Mutab","exTyp","dexTy","_Contig","eValue","ndomAc","andomA","_Array","omAcce","Random","domAcc","mAcces","Access","x5Inde","Types_S","s12S","direct","Bidire","irecti","Replac","idirec","rectio","ForwardI","orwardIn","x9Gen","0__","S4__","s14C","ableF","ceable","Rxs","sArrayBu","usArrayB","ubscript","eRepla","ang","GV14Stdl","lectionx","S3_S","_s12Se","nge","s14","_S4","ngeRep","RangeR","placea","laceab","aceabl","angeRe","geRepl","5Ind","___TFVs","2_Contig","s22_Cont","22_Conti","Comparab","omparabl","_9Gen","9Equatab","s9Equata","Minim","inima","nimal","mparable","yCheck","wardInde","rwardInd","2Seq","ceTy","_S3_","liency","cyChec","ilienc","encyCh","ncyChe","wx5Ind","iencyC","esilie","silien","12Se","utableCo","MutableC","14Co","4Col","Checks","tableCol","es_","Mirro","eableCo","ceableC","eable","alueF","ati","C14Stdli","wx11Su","x11Sub","ectionx_","ional","actValue","tractVal","extractV","rapValue","wrapValu","ctValueF","xtractVa","ractValu","nceTypes","Vs22_Con","eck","hec","3_S4","ttest2","___TFV","ccess","Wx9Ge","tableF","rTypes","GSa","_S1_","yBu","Con","ardIndex","or7","nteger","r7E","ayB","_S3_S4_","orType","ace","rGV14Std","ontig","iguou","tiguo","ntigu","guous","Conti","s_SiSiS","eplac","oun","FVs","_s14Coll","ypesF","pesFS","place","S6_","Intege","est1","2_ArrayB","12_Array","s12_Arra","esFS","Mirror","script","rwardIn","orwardI","_s_S","_s_SiSiS","ing","_Conti","rGV","eValu","SiSiS","Types_Si","sArra","Type_","ypes_S","_S1","sArrayB","ubscrip","bscript","rac","usArr","ousAr","uousA","ceT","GV14Std","neratorS","ectionx","Sg5","TSg","ward","Forw","orwa","rwar","ona","Vs12_Arr","Compar","nt_","ubSe","bSeq","11Su","1Sub","SubS","s22_Con","22_Cont","2_Conti","andom","ndomA","omAcc","mAcce","Acces","Rando","domAc","_Arra","omparab","mparabl","Compara","s9Equat","9Equata","parable","ardInde","wardInd","x5Ind","ecks","nte","utableC","tableCo","Vs22_Co","ound","irect","Rxs1","direc","dIndex","recti","Repla","Bidir","idire","__TFVs","rror","rTy","TWurGV","xTyp","cess","akeColle","keCollec","makeColl","ceabl","rTypes_","_S3_S4__","WxS3_S4_","xS3_S4__","_s_Si","eRepl","xS2_","dexT","C14Stdl","utab","ctionx_","Chec","inim","Vs5","Muta","ctValue","extract","ractVal","tValueF","actValu","rapValu","apValue","wrapVal","xtractV","tractVa","pes_SiSi","ypes_SiS","eableC","_s12S","Cont","exTy","ceTypes","ngeRe","angeR","aceab","geRep","lacea","s22","4__","eTy","yChec","ctionx_s","lace","x9Ge","silie","wx5In","lienc","ncyCh","cyChe","encyC","iency","ilien","esili","es_SiSis","TWurG","bleF","Foundati","10Founda","0Foundat","oundatio","TWu","rdIndex","Literal","rGV14St","ypesFS0_","TypesFS0","x11Su","wx11S","_SiSis","leC","S7_","_s14Col","_s_","imal","_9Ge","s12_Arr","2_Array","12_Arra","nima","Mini","Vs12","S6_S7__","__TFV","test2","Sub","_S3_S4","3_S","eabl","_s_SiSi","Slice","irro","x_s","Mirr","eratorS","12S","x_s1","rro","lueF","ypes_Si","onvertib","Converti","nvertibl","ract","s22_Co","ictionar","undation","erType","onal","teger","ntege","orTyp","ces","Vs6UInt","es_SiSi","ini","wardIn","rwardI","WxS2_","Defaulte","efaulted","14C","eRe","Vs12_Ar","F14Stdli","W_9Gener","lement_s","Vs12_","ubscri","bscrip","GV14St","Dictiona","cces","ctionx","sIndex","x_s12Seq","ctionary","Integ","FC14Stdl","2Se","irror","Wx9G","dInde","S5_","scrip","cript","vertible","sFS","2_Cont","Vs22_C","22_Con","ionTypes","ompar","es_Si","_Cont","es_S","akeColl","keColle","makeCol","mparab","parabl","ompara","s16","s9Equa","9Equat","S6_S","esFS0_","arable","rdInde","ardInd","xS3_S4_","WxS3_S4","pes_S","_S3","Vs2","tableC","Tes","xs14Coll","Rxs14Col","4Co","Compa","onti","iguo","tigu","guou","uous","ntig","pes_SiS","FS1_","rdIndexT","dIndexTy","ation","epla","plac","pesF","rGVs","eS_FS1_","tValue","tionx_","urGV14St","6Forward","16Forwar","s16Forwa","C14Std","mAccessI","ccessInd","cessInde","AccessIn","tionx_s","ctValu","extrac","xtract","rapVal","pValue","wrapVa","apValu","actVal","tractV","ractVa","s_SiSis","TSg5V","eTypes","Default","eVal","S4lineSu","SS4lineS","_s9Equat","iSiS","10Found","Foundat","0Founda","oundati","undatio","_TFVs","sArr","WurGV","ype_","ileSS4li","fileSS4l","eSS4line","leSS4lin","4fileSS4","____","usAr","ousA","Test","rTypes_S","ratorTyp","eratorTy","For","cyCh","xs1","SourceLo","und","ypesFS0","pesFS0_","Litera","atorType","Stri","s12_","neratorT","_S3_S","ando","mAcc","Rand","omAc","domA","Acce","ndom","_Arr","iteral","x5In","_s12","ratorS","ourceLoc","rect","rGV14S","3Generat","13Genera","s13Gener","ess","irec","S__","Repl","dire","s6UInt","4simd","uRxs","Bidi","idir","TypeS_FS","ypeS_FS1","peS_FS1_","_s14Co","Inte","Convert","_WxS","nvertib","onverti","vertibl","ectionMi","lectionM","esF","S_1","ceab","TypeS","sInde","Types_G","st1","s12_Ar","2_Arra","12_Arr","S6_S7_","11S","ictiona","ctionar","6_S7__","ndation","_zWxS","subscrip","eRep","onalInde","ionalInd","ctionalI","urceLocS","tionalIn","SiSis","4lineSu","ceLocSta","rceLocSt","efaulte","eLocStac","14Source","faulted","4SourceL","_s_SiS","rLiteral","Vs5Int","_zWxS2_","atio","Slic","ement_s","W_9Gene","F14Stdl","pes_Si","Indexabl","orw","ngeR","geRe","acea","s22_","isuseRes","eResilie","useResil","32Collec","MisuseRe","ionMisus","onMisuse","2Collect","ctionMis","Resilien","suseResi","nMisuseR","seResili","tionMisu","ndexable","UInt","FS0_","Diction","tack","ard","x_s12Se","tionary","ionType_","mal","FC14Std","dIn","LocStack","Vs6UIn","es_SiS","war","yChe","ima","Vs22_","rwa","s22_C","bscriptF","leF","Vs12_A","0_S","lien","esil","wx5I","sili","ency","ienc","ilie","ncyC","ubS","ertible","bSe","9subscri","S_14Sour","_14Sourc","ableValu","1Su","VS_14Sou","nittest3","onTypes","urGV","WurG","TWur","ackTrace","tackTrac","kTraceVS","aceVS_14","ceVS_14S","raceVS_1","eVS_14So","10stackT","stackTra","TraceVS_","ckTraceV","0stackTr","12_","ocStack4","owFrameS","SS9showF","tack4fil","KT_SS9sh","ameSb10s","rameSb10","b10stack","k4fileSS","cStack4f","9showFra","ck4fileS","eSb10sta","wFrameSb","Stack4fi","T_SS9sho","showFram","FrameSb1","howFrame","S9showFr","meSb10st","Sb10stac","_SS9show","ack4file","erTyp","nt_s9Equ","ment_s9E","t_s9Equa","ement_s9","ent_s9Eq","__s1","uta","TWurGV14","WurGV14S","_S2_","WxS3_S","cks","VS_32Col","_32Colle","lectionO","S_32Coll","6resilie","16resili","sVS_32Co","ChecksVS","hecksVS_","cksVS_32","yChecksV","ksVS_32C","ecksVS_3","resilien","22_Co","Rxs14Co","xs14Col","wx11","essIndex","bleValue","wardI","ardIn","x11S","ror","d__","tionx","xTy","dIndexT","makeCo","keColl","u0_Rxs","akeCol","___TFVs1","_11","erLitera","ont","ara","xS3_S4","nim","xS2","Typer","bscri","ubscr","urGV14S","est2","_TFV","6Forwar","s16Forw","16Forwa","exT","essInde","AccessI","GV14S","ccessIn","cessInd","Che","tive","Mut","lice","sFS0_","S1_S","SS4line","S4lineS","_s9Equa","bles","0_Rxs","Object","2_Con","_wx11Sub","S_FS1_","eS_FS1","leSS4li","fileSS4","4fileSS","eSS4lin","ileSS4l","arabl","parab","mpara","eBuffer","FVs12_Ar","efault","rable","s9Equ","9Equa","String","esFS0","nti","rdInd","ionx_s","lac","nteg","tege","eger","orTy","eratorT","ratorTy","atorTyp","WxS2","ourceLo","SourceL","x9G","_Co","ectionOf","nalIndex","tract","1_S","torType","Native","Defaul","Pointer","VS_1","0Found","10Foun","Founda","oundat","ndatio","undati","W_S","Type_S","gerLiter","ntegerLi","tegerLit","egerLite","OffsetSi","outOfBou","tOfBound","utOfBoun","OfBounds","tionx_s1","Str","TypeS_F","tValu","Min","urceLoc","ative","ionx_","erTypes","ompa","_GS1","s13Gene","3Genera","13Gener","TSg5Vs","C14St","dInd","pesFS0","onvert","FGSaW","S0___","ript","crip","scri","ctVal","ypeS_FS","extra","xtrac","apVal","actVa","ractV","pValu","rapVa","wrapV","peS_FS1","onType_S","mpar","_Con","nittest9","ectionM","ctionMi","_9G","Rep","Storag","alIndex","Comp","__s","atorS","onalInd","rceLocS","tionalI","subscri","ionalIn","nalInde","eab","eTypesFS","ceTypesF","14Sourc","ceLocSt","4Source","ueF","LocStac","eLocSta","rLitera","____TF","rGVs1","irr","Mir","Conver","FVs1","Sb10sta","_Rxs","Liter","itera","_SiSis1","act","ertibl","nverti","erTypes_","vertib","Indexab","ndexabl","_GVs","IntegerL","ypes_G","nal","eResili","useResi","isuseRe","ionMisu","2Collec","nMisuse","32Colle","onMisus","MisuseR","Resilie","seResil","suseRes","tionMis","dation","dexable","S4_S5__","tionar","iction","11Opaque","aqueValu","paqueVal","OpaqueVa","1OpaqueV","onType_","4lineS","zWxS2_","tri","dexTypes","ocStack","lineSu","teral","W_S3_S4_","faulte","aulted","uRxs1","urG","_zWxS2","scriptF","_S7__","__TFVs12","F14Std","ment_s","W_9Gen","rGV14","9subscr","_14Sour","ableVal","VS_14So","S_14Sou","bleValu","_TFVs12_","Sg5V","ittest3","bject","6_S","tackTra","s6UIn","ckTrace","6UInt","ackTrac","TFVs12_A","LiteralC","ite","TraceVS","eVS_14S","10stack","stackTr","kTraceV","aceVS_1","ceVS_14","0stackT","raceVS_","teralCon","lConvert","alConver","iteralCo","eralConv","ralConve","cStack4","ameSb10","9showFr","_SS9sho","rameSb1","S9showF","eSb10st","b10stac","meSb10s","k4fileS","ck4file","tack4fi","T_SS9sh","howFram","SS9show","KT_SS9s","TFVs","showFra","ack4fil","Stack4f","owFrame","wFrameS","FrameSb","_s14C","nt_s9Eq","t_s9Equ","Storage","ent_s9E","ment_s9","cce","Dictio","s5Int","sta","x_s12S","ionary","WurGV14","TWurGV1","FC14St","rFT","12_Ar","2_Arr","s12_A","ectionO","VS_32Co","_32Coll","S_32Col","S6_S7","6_S7_","ChecksV","hecksVS","cksVS_3","ecksVS_","6resili","16resil","ksVS_32","sVS_32C","resilie","Wx9","_Wx","Characte","queValue","ssIndex","Si_G","leValue","rtible","s9Indexa","para","9Indexab","nTypes","pla","Vs5In","tring","Pointe","zWxS","__TFVs1","Vs22","erLiter","igu","4fileS","rap","alInde","Rxs14C","xs14Co","zWx","ous","haracter","_T_","TypeS_","Vs6UI","tig","uou","guo","FS1","epl","simd","4sim","Vs5Range","T_S","leS","_S6_S7__","_S0___","_wx11Su","ypeS","sInd","alCo","eBuffe","urGV14","_zWx","WxS3_","FVs12_A","6Forwa","16Forw","s16For","cessIn","ssInde","Indexs","essInd","ccessI","GSq","10sta","alueInto","ValueInt","TestSuit","iSis","xS3_S","bleFVS_2","apValueI","bleFGSaW","tValueFr","alueFrom","ableFGSa","leValueW","ableFVS_","pValueIn","ValueFro","9TestSui","ctionOf","estSuite","t9TestSu","ttest9Te","st9TestS","test9Tes","ittest9T","est9Test","eVa","S4line","SS4lin","_s9Equ","ffsetSi","yCh","sAr","pe_","OffsetS","makeC","keCol","u0_Rx","akeCo","____T","eSS4li","fileSS","ileSS4","leSS4l","ntegerL","egerLit","gerLite","tegerLi","and","tOfBoun","fBounds","OfBound","utOfBou","usA","outOfBo","GSaW","S4_S5_","check","eValueSi","ionx_s1","ire","Strin","Point","GVs5Rang","torTyp","atorTy","ratorT","ack","cyC","rec","ourceL","urceLo","Source","22_","ndo","uRx","2_Co","22_C","_S2__","dom","rrorType","torag","omA","S7__","ointer","torage","nType_S","_zW","per","ittest9","mAc","Acc","_Ar","_S7_","erTy","Objec","ValueSi_","eS_FS","5Indexs2","_FS1_","ypeS_F","x5I","_S5_","GS_","s5Range","S_FS1","ueValueS","rceLoc","TWuRxs","13Gene","3Gener","s13Gen","fault","efaul","eTypesF","onx_s","S1_S2_","FVs22_Co","dir","idi","Bid","rdIn","ardI","peS_FS","_GVs1","Found","ionx","_S1__","tionMi","ctionM","Nativ","Defau","cea","datio","u0_R","ounda","GS1","ndati","10Fou","0Foun","undat","FGSa","S2__","par","lIndex","paqueVa","aqueVal","OpaqueV","1Opaque","queValu","11Opaqu","Si_GS","ype_S","bscr","yper","ubsc","exTypes","ceLocS","x11","onalIn","nalInd","subscr","lic","Indexa","ionalI","alIndexT","lIndexTy","4Sourc","14Sour","ocStac","LocSta","eLocSt","W_S3_S4","GV14","rLiter","nittest4","SiSis1","_TFVs12","UIn","onver","sFS0","Sli","s_Si_","TyperGV","b10sta","Sb10st","KT_S","tac","Sg5Vs","nvert","TFVs12_","1Minimal","ndexab","dexabl","make","iteralC","geR","ertibles","eralCon","alConve","lConver","ralConv","S1_S2__","teralCo","S1__","nMisus","32Coll","suseRe","useRes","ionMis","isuseR","seResi","Misuse","2Colle","onMisu","2_S","Resili","eResil","0_Rx","FV14Stdl","u0_Rxs1","exable","4_S5__","nType_","FS0","0_Rxs1","IntegerT","FVs12_","tegerTyp","ntegerTy","x_s12","fT_","rabl","_KT_S","arab","cStack","9Equ","s9Eq","haracte","orTypes","wx5","esi","5Indexs","Stora","ueValue","Charact","Vs5Rang","VS_14S","egerType","criptF","ili","ien","lie","0___","trac","sil","ncy","_14Sou","ableVa","S_14So","s_Si_G","bleVal","9subsc","leValu","9Indexa","s9Index","ttest3","Wur","wx1","ounds","kTrace","ackTra","ckTrac","tackTr","yBufferg","aceVS_","TraceV","ceVS_1","eVS_14","stackT","0stack","raceVS","10stac","Conve","Stack4","_S6_","FrameS","meSb10","wFrame","_SS9sh","9showF","ack4fi","k4file","howFra","showFr","tack4f","ck4fil","eSb10s","KT_SS9","owFram","rameSb","S9show","T_SS9s","SS9sho","ameSb1","xtra","nt_s9E","t_s9Eq","ent_s9","verti","rtibl","ertib","lineS","_S2","WurGV1","pes_G","VS_32C","ctionO","_32Col","S_32Co","ewx5Inde","hecksV","ValueS","6resil","16resi","sVS_32","ksVS_3","ecksVS","resili","cksVS_","ionar","ictio","tVal","4line","ativ","tableVal","equence_","onx_","zWxS2","aracter","ineSu","C14S","ulted","aulte","_GV","_KT_SS9s","wrap","gGenerat","ingGener","ngGenera","les","ctVa","ger","_S6_S7_","nedInteg","dInteger","extr","edIntege","ignedInt","gnedInte","4file","actV","pVal","rapV","apVa","_TFVs1","F14St","W_9Ge","ent_s","torS","erLite","___TFVs2","_W_9Gene","V4simd","ice","_s14","ive","___GS","eValueS","Indexs2","Opaque","etS","tiv","tible","TFV","st2","fEquatab","OfEquata","estSuit","Dicti","_GS_","loat","teg","onary","alueInt","TestSui","lueInto","ValueIn","FC14S","4lineSu_","0_R","_s9Index","s30Range","30RangeR","0RangeRe","pValueI","lueFrom","eValueW","bleFVS_","leFGSaW","leFVS_2","ableFGS","ValueFr","ableFVS","alueFro","bleFGSa","ver","9TestSu","stSuite","5Int","t9TestS","test9Te","est9Tes","st9Test","ttest9T","__TFVs22","_GS1_","Typew","ted","tera","Lite","iter","S3_S4___","___S","_TFVs22_","TFVs22_C","ables","ValueSi","Bounds","_wx11S","ointe","_11SubSe","ffsetS","rrorTyp","ege","fileS","orT","GVs5Ran","ject","eral","_s9","alInd","Rxs14","lInde","xs14C","tionOf","TyperG","rorType","res","trin","rGV1","omp","ypeS_","Offset","bjec","fsetSi","s5Rang","_Builtin","s6UI","6UIn","ex_","gerLit","egerLi","tegerL","ewx","OfBoun","fBound","utOfBo","tOfBou","outOfB","onx_s1","ablewxS","SignedIn","s5In","alueSi_","Si__","2_Ar","12_A","2__","GVs5","6_S7","urGV1","eBuff","mpa","FVs22_C","s16Fo","16For","6Forw","Indexing","tinInteg","nInteger","xingGene","dexingGe","ndexingG","7Indexin","exingGen","17Indexi","inIntege","s17Index","uiltinIn","iltinInt","ltinInte","ndexs","cessI","rip","essIn","ssInd","PA__T","ring","scr","cri","ipt","_s13Gene","double","Vs5I","SS_","istance","ttest9","dForward","S4lin","SS4li","Types_GS","ileSS","_s9Eq","xS3_","S2_S3_","s10Compa","0Compara","10Compar","Index_","Com","Bufferg","5Range","eIn","leSS4","eSS4l","eFGSaW","inter","4_S5_","S_3","S4_S5","lIndexT","eIndex","View","FVs12","qd__","ittest4","_Rx","imalEqua","alEquata","lEquatab","MinimalE","atableVa","uatableV","eWx9Gene","malEquat","21Minima","inimalEq","nimalEqu","ource","Vs6U","atorT","torTy","xTypes","Sourc","rceLo","urceL","quence_W","ionTypew","GVs22_Co","uence_Wx","tionO","ence_WxS","1Minima","eMutable","rtibles","orage","FV14Std","s_SiSis1","paqueV","11Opaq","queVal","ueValu","1Opaqu","aqueVa","8Distanc","egerTyp","orS","tegerTy","ntegerT","nter","KT_SS","_Si_G","S2_S","3_Builti","WxS3","33_Built","erGV","s33_Buil","22Bidire","2Bidirec","W_S3_S","s22Bidir","s9E","Indexwx","16_Array","s16_Arra","0sta","10st","peS_F","istanc","gerType","s18_Sign","BuiltinI","8_Signed","_SignedI","18_Signe","TFVs12","ceLoc","TWuRx","WuRxs","yperGV","s13Ge","3Gene","13Gen","int","g5V","s21","WxS2_S3_","Vs17Inde","1_S2_","S1_S2","teralC","_Rxs1","eralCo","ralCon","lConve","alConv","1_S2__","Sis","Set","_S5__","ssIndexT","sIndexTy","TWurGVs","oint","akeC","tionM","keCo","ionMi","s10","Sta","Poin","Vs6","CS_3BoxG","GCS_3Box","chec","haract","aracte","ewx5Ind","TypesFS1","ypesFS1_","Charac","Vs5Ran","quence_","tableVa","subsc","ndexa","onalI","eLocS","nalIn","i_G","4Sour","s9Inde","LocSt","cStac","14Sou","ocSta","9Index","_KT_SS9","Vs17","Stack","rLite","ngGener","gGenera","ingGene","Vs3SetSS","_WxS3_S4","peWx9Gen","GVs3SetS","_21Minim","ypeWx9Ge","StringCo","S_21Mini","VS_21Min","TypeWx9G","iSis1","VS_14","orag","tora","eS_F","VS_11Opa","S_11Opaq","s3SetSS_","s21Rando","BoxGVs3S","3BoxGVs3","FGVS_11O","FVS_21Mi","21Random","oxGVs3Se","_11Opaqu","GVS_11Op","xGVs3Set","1RandomA","nedInte","u0_","dIntege","gnedInt","ignedIn","edInteg","S_FS","erti","eS_","erGVs","tSS__16r","IntoEqua","tValueFW","hecksAdd","atableFG","ueFGVS_1","dedGCS_3","eValueW_","FromEqua","sAddedGC","eFGSaW_S","leFVS_21","ableFW_S","3SetSS__","alueSi_W","alueFWxS","oEquatab","atableFW","tableFGS","lueSi_Wx","mEquatab","lueFGVS_","1checksA","checksAd","ksAddedG","__16resi","__12extr","ValueW_S","dGCS_3Bo","eIntoEqu","toEquata","AddedGCS","2extract","SetSS__1","atableFV","ValueFWx","ntoEquat","lueFromE","_x9wrapV","lueIntoE","ddedGCS_","tableFVS","edGCS_3B","__q_22wr","ecksAdde","tableFW_","romEquat","_16resil","S__16res","22wrapVa","5extract","__x9wrap","_25extra","ueSi_WxS","SS__16re","ueIntoEq","_q_22wra","11checks","alueFGVS","eFVS_21M","apValueF","eFromEqu","___x9wra","leFGSaW_","___q_22w","x9wrapVa","25extrac","ueFromEq","__25extr","cksAdded","_22wrapV","omEquata","eFGVS_11","9wrapVal","etSS__16","q_22wrap","2wrapVal","_11check","pValueFG","_12extra","_3BoxGVs","S_3BoxGV","ValueFGV","Type_S1_","12extrac","16_","Sb10s","b10st","__TFVs2","_W_9Gen","S2_S3__","GS1_","dexab","exabl","dexables","TWuRxs1","sIn","_FS1","seRes","FGS","onMis","32Col","Misus","useRe","Resil","isuse","suseR","nMisu","2Coll","eResi","WxS1_","Obje","xable","fEquata","OfEquat","4si","_S3__","_GS7_","racter","dRan","erT","lineSu_T","30Range","lineSu_","_s9Inde","s30Rang","0RangeR","efau","faul","ault","lCo","gerTypes","2_C","nx_s","equenceS","erG","S_14S","sim","imd","riptF","eVS_1","9subs","_S6_S7","_SS","_TFVs22","alC","Foun","_14So","ableV","leVal","bleVa","test3","alueS","TFVs22_","3_S4___","Nati","Defa","dati","ackTr","Trace","kTrac","ckTra","tackT","peS","ndexs2","ValueW","aceVS","stack","0stac","ceVS_","raceV","unda","tack4","0Fou","10Fo","ndat","GVs17Ind","_11SubS","sVS_3","howFr","owFra","ck4fi","wFram","SS9sh","_SS9s","Frame","ameSb","showF","eSb10","9show","rameS","ack4f","meSb1","S9sho","k4fil","T_SS9","i_GS","nt_s9","t_s9E","estSui","__zWxS","stSuit","pe_S","nver","GS7_","lueInt","GVs3Set","alueIn","ValueI","ueInto","TestSu","Logging","paque","_32Co","VS_32","S_32C","_FS","WxS1_S2_","yBufferT","resil","16res","ableFW","cksVS","6resi","leFGSa","bleFVS","ecksV","ableFV","eFVS_2","lueFro","ableFG","ksVS_","alueFr","leFVS_","bleFGS","ueFrom","9TestS","inte","tSuite","rtibles_","ufferTyp","BufferTy","6_ArrayB","st9Tes","onve","test9T","est9Te","t9Test","fferType","ittest11","g9subscr","g5Vs","Builtin","vert","Int32","torTypes","___G","alueSi","_Builti","ext","___TFSa","S5__","TFVs1","SaW","yStorag","___TFS","erLit","V4sim","SignedI","rorTyp","rrorTy","Signed","_KT_","Stor","GVs5Ra","Opaqu","GS7_S0__","exTypes_","_GS6_","ltinInt","ndexing","nIntege","inInteg","7Indexi","exingGe","17Index","dexingG","xingGen","tinInte","s17Inde","Indexin","iltinIn","uiltinI","xS0_","tibl","7__","s17","S4_S","FVs22_","_s13Gen","1__","TyperGVs","_S4___","apacity","unds","lte","Bound","ablewx","line","Conv","dForwar","18_","_S7","ypes_GS","ineS","rin","0Compar","10Compa","s10Comp","lueSi_","ionTypeS","TWV","blewxS","rtib","ubs","es_G","yStorage","_S5","ffset","_wx11","_GS7_S","stance","S0__S","Hashable","AnyObjec","onTypes_","xTypes_S","nyObject","xs14","icti","orTypes_","onar","S3__","fsetS","tra","GVs17","4lin","s16F","eSi_","GS7_S","edInte","11_","eWx9Gen","malEqua","GVs22_C","imalEqu","21Minim","inimalE","atableV","alEquat","nimalEq","lEquata","neSu","SS1","rdI","ulte","lted","uence_W","onTypew","ence_Wx","9AnyObje","s9AnyObj","ionOf","GVs12","onx","nce_WxS","eMutabl","dexTyper","4fil","file","ate","yperG","nt_s","W_9G","ceLo","F14S","setSi","Offse","StringC","s_Si_GS","WxS2_S","GSaWxS","5Rang","s5Ran","ufferg","8Distan","Distanc","_rFT","ert","ake","bsc","egerL","gerLi","eFG","3_Built","nary","33_Buil","s33_Bui","ible","utOfB","fBoun","tOfBo","outOf","OfBou","nx_s1","s22Bidi","GV1","22Bidir","2Bidire","Dict","eInde","6_Array","s16_Arr","16_Arra","_GS6_S","ttest4","uiltin","FC14","18_Sign","8_Signe","s18_Sig","_Signed","essI","KT_","_KT_SS","ableS","ouble","1Minim","Vs17Ind","WxS2_S3","xS2_S3_","mak","ypew","s18_","tibles","_WxS3_S","float","FV14St","eFrom","doubl","sIndexT","GVs2","egerTy","Vs3Set","tegerT","gerTyp","test9","ileS","rab","2_S3_","IndexOf","S_3BoxG","CS_3Box","GCS_3Bo","9Eq","S2_S3","ypesFS1","ndex_","pesFS1_","Indexw","ndexwx","eFGSa","dRange","FVS_","alIn","lInd","s13","ance","WxS1_S","ValueFG","tringCo","S_21Min","TypeWx9","VS_21Mi","s3SetSS","_21Mini","Vs3SetS","peWx9Ge","ypeWx9G","peS_","3SetSS_","s21Rand","1Random","3BoxGVs","FVS_21M","xGVs3Se","S_11Opa","_wx","_11Opaq","FGVS_11","BoxGVs3","oxGVs3S","GVS_11O","VS_11Op","21Rando","_S6","mEquata","__16res","FromEqu","1checks","IntoEqu","_16resi","__25ext","2wrapVa","SetSS__","bleFW_S","tSS__16","etSS__1","alueW_S","AddedGC","romEqua","lueSi_W","___q_22","eFVS_21","eFGSaW_","toEquat","12extra","_x9wrap","9wrapVa","FGSaW_S","_q_22wr","_3BoxGV","q_22wra","ype_S1_","cksAdde","_22wrap","ueIntoE","eFromEq","SS__16r","dGCS_3B","edGCS_3","ValueW_","dedGCS_","lueFWxS","x9wrapV","lueFGVS","alueFGV","25extra","eSi_WxS","ableFW_","_12extr","ntoEqua","oEquata","11check","22wrapV","S__16re","ueSi_Wx","omEquat","tableFV","__x9wra","_25extr","5extrac","ddedGCS","ueFromE","checksA","alueFWx","ksAdded","Type_S1","tableFG","__12ext","hecksAd","ueFGVS_","pValueF","eIntoEq","_11chec","ValueFW","tableFW","sAddedG","eFGVS_1","FGSaWxS","___x9wr","2extrac","__q_22w","ecksAdd","esFS1_","xtr","WurGVs","exables","__TTSg5","stanc","ewx5In","ueVal","From","tVa","queVa","TestS","11Opa","1Opaq","aqueV","Int16","ult","nx_","GS6_","tableV","uence_","eBuf","ineSu_T","loa","16Fo","6For","C14","ssIn","dexs","W_S3_","A__T","PA__","wra","ingGen","gGener","alEqua","ngGene","quenceS","istan","ctV","ignedI","eFW","nedInt","dInteg","gnedIn","GVs12_","Vie","S0_S","urGVs","apV","pVa","perGV","_TFVs2","_W_9Ge","2_S3__","WuRxs1","__SiSi","tOf","eralC","SS4l","S4li","_s9E","leSS","lConv","alCon","_Si__","ralCo","ount","GVs22_","GVs17In","eSS4","OfEqua","fEquat","bleS","BufferT","oat","SS__","s30Ran","4_S5","30Rang","0Range","ineSu_","_s9Ind","harac","aract","FVS_2","racte","__TT","xS1_S2_","WxS1_S2","s_G","igned","Typewx","Chara","Vs5Ra","ourc","urce","ufferTy","fferTyp","tibles_","torT","Lit","TFVs22","ionO","rceL","Sour","ferType","ttest11","g9subsc","GS6_S","S_11","Sis1","9Inde","s9Ind","_Si_GS","abler","10s","rage","_11Sub","xs2","qd_","Vs5Slic","__rFT","GVs3Se","T_SS","TSg5S","jec","utOf","Int3","TWuR","ceVS","Loggin","ral","tionS","ogging","S7_S0__","xTypes_","GS7_S0_","oin","eLoc","__1","F4simd","eVS_","2Co","6res","acter","WuRx","Trac","subs","ArrayS","Obj","_S6_S","13Ge","3Gen","s13G","Builti","bje","yperGVs","1_S2","_Built","Stac","_rFTSS1","s6U","TSg5GVs","6UI","eFVS_","Hashabl","__TFSa","IndexS","yStora","TypeW","Vs15","s5I","onTypeS","onMi","ionM","_s_Si_","PA__TFF","i__","dexs2","alueW","2_A","nyObjec","yObject","AnyObje","nTypes_","ashable","__zWx","16re","_s_Si_G","ict","dexing","ndexin","rti","_GS1_S","exingG","ltinIn","s17Ind","Indexi","iltinI","xingGe","17Inde","inInte","tinInt","7Index","nInteg","stSui","tSuit","estSu","xS1_","LocS","nalI","dexa","lueIn","eInto","alueI","ueInt","_s13Ge","S_14","GCS_","4___","14So","cSta","VS_3","ocSt","4Sou","leFVS","bleFW","bleFV","leFGS","ueFro","lueFr","bleFG","rLit","apacit","pacity","dat","9AnyObj","s9AnyOb","9Test","FVs2","Sb10","Suite","exTyper","s5Slice","ora","est9T","t9Tes","st9Te","dForwa","pes_GS","b10s","xS3","race","s10Com","10Comp","0Compa","nce_","exab","xabl","S4___","lueSi","seRe","eRes","ameS","Res","2Col","suse","useR","nMis","Resi","WxS1","Misu","isus","32Co","FVs22","Unsafe","__TFS","Int64","iew","FVS","rorTy","Signe","rrorT","_GS7","ablew","21Mini","nimalE","malEqu","imalEq","eWx9Ge","lEquat","GVs5R","nce_Wx","ence_W","nTypew","_14S","iptF","eMutab","ce_WxS","9sub","leVa","bleV","ame","WxS0_","lueS","est3","S_32","tringC","eSb1","fil","kTra","ackT","ckTr","8Dista","Distan","stac","aceV","__GS1","GSaWx","blewx","edGCS_","ack4","S1_wx","33_Bui","howF","_SS9","ck4f","wFra","owFr","Fram","s33_Bu","k4fi","sVS_","3_Buil","show","9sho","S9sh","meSb","SS9s","rame","0st","ceV","t_s9","s22Bid","2Bidir","22Bidi","lewxS","ueSi_","che","6_Arra","16_Arr","s16_Ar","VS_2","s18_Si","tance","_Signe","8_Sign","18_Sig","erGVs1","paqu","_32C","aque","ksVS","resi","S_F","cksV","Vs17In","xS2_S3","ndexOf","dInte","edInt","s3Set","_WxS3_","s18","TypeWx","4_S","nt32","SetS","IndexO","tIndex","_3BoxG","keC","tionF","GS_S","VSS","Poi","CS_3Bo","_T_U","erLi","S_3Box","GCS_3B","V4si","pesFS1","SaWxS","FGSaWx","xS2_S","0__S","fferg","Int8","S7_S","Opaq","Vs3Se","1check","_GS6","tSi","rag","BoxGVs","alueFG","ile","iltin","test4","s3SetS","ypeWx9","peWx9G","_21Min","VS_21M","S_21Mi","ringCo","Boun","3SetSS","uilti","10F","oxGVs3","xGVs3S","GVS_11","21Rand","_TTSg5","s21Ran","SetSS_","FVS_21","VS_11O","1Rando","S_11Op","3BoxGV","FGVS_1","_11Opa","S_2","Def","SS__16","hecksA","eFromE","11chec","etSS__","__12ex","AddedG","22wrap","Testsu","_11che","checks","_16res","lueFGV","12extr","ueSi_W","tSS__1","ddedGC","FGSaW_","2extra","eSi_Wx","lueW_S","dGCS_3","omEqua","_25ext","Si_WxS","x9wrap","IntoEq","oEquat","ype_S1","leFW_S","mEquat","lueFWx","bleFW_","__25ex","alueW_","dedGCS","ecksAd","2wrapV","cksAdd","ueFGVS","toEqua","9wrapV","S__16r","FromEq","ntoEqu","sAdded","_22wra","GSaW_S","romEqu","_12ext","__16re","_q_22w","ksAdde","alueFW","___q_2","pe_S1_","eFGVS_","_x9wra","___x9w","eIntoE","q_22wr","__x9wr","5extra","ueFWxS","__q_22","25extr","1Mini","Error","xables","sFS1_","ibles","_S0__S","__TTSg" }; +const unsigned CodeBookLen[] = { 8,8,7,7,6,6,5,5,8,8,8,7,7,7,4,4,6,7,5,6,4,6,6,6,5,8,4,3,8,8,8,8,8,8,8,8,8,3,8,4,7,7,5,5,5,5,4,3,7,7,7,7,7,7,7,7,7,7,4,5,7,6,3,6,6,7,3,3,3,8,3,6,6,6,6,6,6,6,6,6,6,6,4,4,3,6,4,4,4,5,5,4,6,6,5,5,7,3,8,8,5,5,5,5,5,5,5,5,5,5,5,5,5,8,5,8,8,8,3,7,8,4,3,8,5,5,6,5,7,7,8,8,3,3,4,4,4,3,3,3,4,3,7,7,7,7,7,6,6,7,3,6,4,3,4,4,4,6,3,4,4,4,4,4,4,4,4,4,4,7,7,7,8,8,8,8,8,8,8,8,8,8,6,4,8,5,5,3,4,4,4,8,3,5,4,6,6,3,6,6,6,5,3,6,5,5,5,5,3,3,3,7,7,7,7,7,7,7,7,7,7,5,7,6,6,6,6,5,3,3,3,8,8,8,3,5,3,3,8,7,3,4,8,8,8,8,8,8,8,8,8,3,3,3,3,3,4,5,5,3,5,5,3,5,3,3,3,4,4,3,5,4,6,6,6,6,6,6,6,6,6,6,7,7,7,3,4,8,4,3,4,4,4,3,5,5,5,5,4,7,4,8,8,8,8,8,3,6,4,7,7,7,7,3,7,7,7,4,7,7,3,3,8,8,3,8,4,6,3,5,6,3,5,7,8,3,3,6,6,6,5,5,5,5,5,5,4,7,5,5,4,4,4,7,7,7,7,7,4,4,6,8,3,4,3,5,7,6,6,6,6,6,6,6,8,8,7,8,7,7,6,6,5,7,3,5,3,3,7,3,6,4,4,4,3,8,8,8,8,3,5,3,3,8,4,6,3,4,8,8,8,8,8,7,7,3,5,8,8,8,8,8,8,3,3,6,3,3,5,3,8,6,3,3,8,4,4,4,8,8,8,8,8,8,8,8,3,5,6,6,7,8,8,8,8,8,8,8,5,6,6,6,6,6,5,8,8,4,4,4,3,3,5,7,7,7,8,8,7,3,3,4,7,6,4,8,6,6,3,8,6,6,6,5,6,7,7,7,7,4,4,4,4,4,5,5,5,6,7,4,5,3,5,5,5,7,7,7,7,7,7,5,7,7,7,7,7,7,7,3,7,8,6,6,6,5,5,3,8,7,4,7,6,7,7,7,7,7,7,7,7,5,4,4,3,3,4,7,6,7,7,7,7,7,7,7,7,7,3,7,4,3,4,5,5,5,6,7,7,8,8,8,7,3,4,6,6,6,6,5,5,5,6,7,7,3,3,5,5,5,5,5,6,6,6,3,4,4,5,4,3,6,6,6,6,4,6,5,6,7,3,5,5,3,5,3,4,5,5,5,7,6,6,6,6,6,6,6,6,6,6,7,4,6,6,6,6,6,6,8,8,5,3,4,4,5,6,3,8,8,8,6,3,8,8,4,6,3,3,3,6,6,6,6,6,6,6,4,7,8,8,8,8,8,5,8,8,5,5,5,8,6,8,8,4,4,4,6,6,6,6,6,6,6,6,6,4,8,8,4,4,6,8,3,5,7,7,5,5,3,8,6,6,8,5,8,8,8,8,8,8,8,8,8,8,3,3,4,6,6,5,5,6,6,3,4,3,3,8,3,6,3,3,7,6,3,8,5,5,5,5,5,5,7,5,3,3,8,5,5,5,3,6,4,8,8,8,4,6,6,7,7,4,8,3,6,3,5,5,8,5,5,6,3,7,7,7,3,5,5,5,3,7,8,7,3,3,4,4,4,4,3,8,6,3,4,4,4,4,4,7,7,7,5,5,5,5,5,5,5,5,7,7,7,7,7,7,7,7,5,4,3,7,7,7,4,5,4,5,6,5,5,5,5,6,4,3,6,4,4,8,8,8,5,7,8,8,8,5,5,4,4,7,4,7,4,4,3,4,7,7,7,7,7,7,7,7,7,7,8,8,6,5,4,4,7,5,5,5,5,5,3,3,3,5,8,4,4,5,5,5,5,5,5,5,5,5,8,5,4,8,8,8,8,3,7,7,7,8,8,5,5,6,3,3,7,3,4,4,7,7,7,4,4,4,7,5,5,3,6,3,4,7,5,4,3,4,7,3,4,3,4,7,8,8,8,4,6,8,8,6,4,5,5,5,3,7,7,3,6,6,5,8,8,3,3,7,8,8,8,5,6,6,6,8,4,6,6,8,8,5,8,3,5,4,5,3,5,5,8,3,6,6,6,8,5,5,5,4,7,7,7,6,6,6,3,6,6,4,6,6,6,6,7,7,5,3,3,6,3,8,8,3,5,4,4,4,4,4,4,7,4,8,8,5,4,4,4,4,7,6,6,8,8,8,8,6,8,8,8,8,7,6,6,6,6,6,6,6,6,6,6,7,5,6,7,4,8,8,8,4,7,7,7,7,7,5,4,5,4,8,8,8,8,8,4,4,4,4,8,8,8,3,4,3,8,3,7,7,6,8,4,4,8,5,4,4,4,4,4,4,4,4,6,4,4,6,8,4,6,8,8,8,3,4,3,4,4,6,5,4,4,4,8,8,8,6,4,7,4,7,7,7,8,8,3,3,4,5,5,7,3,6,6,6,6,3,7,7,6,7,5,8,4,8,8,8,8,8,5,7,8,8,7,8,8,7,8,6,8,6,7,4,4,7,7,7,6,8,3,4,4,4,4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,4,4,7,4,3,7,7,8,3,7,3,8,6,6,3,4,3,5,3,5,8,3,6,3,4,4,4,4,4,4,4,4,3,7,3,8,8,8,8,3,8,8,7,4,4,4,8,8,8,8,8,8,8,8,8,8,8,8,3,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,5,8,8,8,8,8,4,3,8,8,4,6,3,8,8,8,8,8,8,8,8,8,8,8,8,8,8,5,7,7,4,8,8,5,5,4,3,3,5,3,7,6,6,6,6,8,3,8,3,3,6,3,3,5,5,5,7,4,4,7,7,7,3,7,7,5,7,7,3,4,3,4,5,4,7,7,7,4,5,6,5,8,6,6,7,7,7,7,7,5,5,5,7,8,6,5,5,5,6,5,3,5,6,3,4,4,4,4,7,7,7,4,7,7,3,3,8,8,5,3,7,6,6,7,4,6,6,6,6,6,6,3,6,8,8,8,8,8,8,8,8,8,8,3,7,5,3,7,5,5,7,4,4,7,7,7,6,5,4,6,6,5,5,4,4,4,5,7,5,5,5,5,5,5,5,5,7,8,4,4,8,7,7,3,3,6,7,4,3,5,7,7,7,7,7,7,3,8,8,7,7,7,3,7,7,7,6,5,3,3,6,4,7,4,5,5,7,3,6,6,8,6,7,7,4,8,6,3,7,7,7,7,7,7,7,7,7,7,7,7,7,6,7,7,6,6,8,8,8,8,8,7,6,6,3,8,7,6,5,8,6,6,5,3,6,7,5,8,6,6,6,5,7,7,7,7,7,7,8,4,7,5,3,7,5,7,5,7,8,8,3,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,4,7,7,7,7,7,7,5,7,7,7,7,7,3,6,5,3,6,6,7,7,6,3,5,5,5,7,7,7,7,5,5,7,7,7,7,7,7,7,7,7,3,3,8,8,7,4,7,6,8,4,8,6,3,5,5,6,4,7,4,7,3,6,3,6,6,6,3,3,8,3,6,5,3,3,3,3,3,4,4,8,3,3,8,6,7,4,4,4,6,6,4,5,7,6,6,6,6,6,6,6,6,3,5,8,8,8,4,5,8,8,8,8,8,8,8,8,8,8,8,7,8,8,8,8,8,8,8,3,6,6,6,7,3,3,3,7,5,5,5,5,5,6,6,6,6,7,7,7,7,3,7,7,7,7,3,7,4,6,5,8,7,3,5,5,8,6,6,6,3,3,3,6,6,6,3,3,3,4,4,5,3,8,5,3,4,6,6,7,3,3,7,3,3,3,4,4,5,8,5,8,5,6,3,4,3,7,5,8,6,6,6,6,6,5,5,7,5,6,8,3,3,3,4,4,6,5,5,4,5,6,6,5,5,3,5,4,5,3,5,5,5,5,4,4,3,6,7,7,7,7,7,7,5,5,4,4,4,7,6,3,6,6,6,3,6,6,8,8,6,6,6,6,6,7,4,6,8,6,7,3,5,4,3,5,7,6,6,4,3,5,5,7,8,6,6,4,7,3,8,7,7,7,7,7,7,4,6,6,6,6,6,6,6,6,6,6,3,6,6,4,8,7,6,6,6,3,6,8,6,8,8,5,3,4,5,4,6,4,4,7,7,3,3,7,5,7,7,7,6,8,6,3,3,3,4,4,3,3,6,6,6,6,6,6,6,7,7,6,3,3,5,6,6,6,6,8,6,6,6,6,6,6,6,6,5,6,4,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,4,6,6,6,5,5,5,5,3,6,5,6,6,6,6,8,6,6,6,6,6,6,6,6,6,5,5,4,5,4,8,8,4,5,7,5,4,5,5,3,8,4,8,8,8,3,4,3,7,8,8,4,8,8,8,5,4,4,4,4,6,5,5,5,4,6,8,8,6,3,4,3,5,7,7,6,3,3,5,3,3,8,8,7,5,4,4,3,5,7,7,7,7,5,8,3,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,3,7,7,4,7,7,7,7,7,8,5,5,3,4,4,4,8,4,8,8,5,7,6,6,5,8,6,7,3,5,3,7,4,4,3,5,5,5,5,6,6,7,3,4,4,3,5,6,4,6,6,8,4,4,3,6,6,6,3,6,6,6,6,6,6,7,8,4,7,4,4,4,3,4,4,5,5,3,7,5,5,5,8,8,8,8,8,8,8,8,8,8,8,8,8,8,5,5,3,5,5,5,4,3,3,3,8,6,4,3,7,6,8,5,5,8,5,5,4,6,8,8,8,6,3,7,6,3,5,5,6,5,5,3,5,7,6,4,5,4,7,3,8,8,8,8,8,8,8,8,8,8,8,5,4,5,5,6,5,5,5,8,8,8,8,5,8,7,8,7,5,7,8,6,6,6,6,6,6,8,7,3,7,7,4,5,5,4,8,4,8,4,8,8,8,6,8,3,7,8,8,4,4,5,6,7,8,8,8,8,8,6,5,5,5,6,5,5,5,3,3,3,8,8,5,5,6,5,6,6,6,6,6,3,3,5,8,8,7,4,4,5,4,5,3,3,4,3,8,8,4,6,6,7,8,8,6,6,7,7,5,5,5,5,5,3,5,6,5,5,5,5,6,7,4,5,5,7,7,7,8,8,8,8,8,8,8,8,8,8,5,5,4,4,4,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7,3,7,7,7,7,4,4,3,5,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,3,5,5,7,7,7,4,5,5,8,7,3,4,5,3,5,5,5,5,5,5,5,5,5,5,5,4,5,7,7,3,5,5,6,4,3,8,7,7,7,7,7,4,4,4,3,8,3,4,8,3,5,3,3,5,5,5,6,3,7,3,4,5,5,5,5,5,5,7,7,4,4,4,5,5,5,5,5,3,6,6,5,5,5,5,5,4,5,4,4,4,8,7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,5,5,6,6,6,4,4,4,6,7,6,6,6,6,7,5,5,5,5,3,8,8,5,5,6,5,5,6,6,5,6,6,6,6,5,6,6,6,6,6,4,6,8,8,8,8,6,4,6,6,6,8,8,8,4,7,4,5,8,4,6,7,3,7,4,5,3,7,6,5,5,7,6,6,6,4,4,6,5,8,8,5,7,7,7,7,7,7,7,7,7,7,7,7,7,7,4,4,3,3,4,6,7,3,8,6,7,4,3,5,6,4,4,7,3,3,7,4,3,7,7,7,6,8,3,6,4,3,4,8,3,5,5,6,6,5,8,8,8,8,8,4,4,8,4,4,5,3,5,4,4,4,5,6,3,7,7,7,7,7,7,7,7,7,7,4,3,3,4,4,7,7,7,8,8,5,5,3,7,7,8,4,4,3,5,4,4,4,4,5,5,7,7,6,6,5,5,6,7,7,4,3,3,3,5,5,3,7,4,7,7,4,5,5,5,5,5,5,7,3,7,7,4,5,7,7,7,6,6,6,4,7,7,7,7,4,3,6,5,5,6,7,7,7,3,4,4,6,7,5,6,5,5,7,4,6,6,6,6,5,4,3,5,7,7,7,7,3,5,7,5,7,6,6,5,6,4,4,4,3,4,6,7,7,7,7,7,7,7,7,7,7,4,7,7,7,7,7,7,7,3,7,7,7,7,7,7,7,3,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,3,6,7,7,5,6,5,4,3,5,5,5,5,5,5,3,3,4,6,6,4,7,3,4,4,3,4,4,5,4,4,3,6,6,6,6,7,5,3,6,3,6,6,6,6,3,4,5,3,3,5,6,6,6,6,6,3,5,4,4,4,4,5,5,5,5,4,6,7,4,6,6,4,7,3,4,6,4,6,6,6,6,5,5,5,5,4,7,7,3,5,6,5,5,4,4,7,7,7,4,3,6,4,4,4,7,7,7,5,4,4,5,5,6,5,3,4,6,3,3,7,5,6,4,5,3,4,4,4,4,6,3,5,6,7,7,7,3,4,3,6,4,3,4,5,4,4,4,6,3,5,4,4,4,6,3,7,4,6,4,7,3,7,3,5,7,6,6,6,5,4,3,7,4,4,6,7,3,5,5,3,7,7,7,7,7,5,4,7,3,6,6,3,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,4,4,4,4,5,5,5,5,6,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,4,6,6,3,7,7,5,4,4,5,7,7,3,5,5,5,6,6,4,3,4,6,6,6,4,4,4,5,5,4,4,4,3,4,4,4,4,4,4,4,4,4,5,6,5,5,3,3,5,5,5,4,5,6,6,6,6,6,6,5,6,6,6,4,4,6,6,4,4,4,3,5,4,4,4,6,4,3,4,4,4,6,6,4,4,5,5,5,6,4,5,6,4,4,4,4,4,4,6,4,4,6,4,4,4,4,4,4,3,3,4,6,6,6,5,5,3,6,6,6,4,6,5,6,6,6,6,4,4,4,4,4,3,4,6,6,6,5,5,5,6,3,6,3,4,4,6,6,6,3,5,4,3,3,6,4,4,6,6,4,6,5,6,5,4,5,4,4,4,5,6,4,3,3,6,6,3,5,5,6,6,6,6,6,6,6,4,6,5,3,6,6,6,6,6,6,6,6,6,6,6,6,6,6,3,3,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,6,5,5,6,6 }; +// Returns the index of the longest substring in \p str that's shorter than \p n. +int matchStringSuffix(const char* str, int n) { +if ((0 < n) && (str[0] == '1')) { + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'h')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'k')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'A')) { + return 2493; + } + return 2980; + } + return 3458; + } + } + } + } + } + if ((1 < n) && (str[1] == 'M')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'm')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'l')) { + return 1927; + } + return 2319; + } + return 2908; + } + return 3560; + } + } + } + } + if ((1 < n) && (str[1] == '3')) { + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 1141; + } + return 1467; + } + return 1845; + } + return 2370; + } + return 3207; + } + } + } + if ((1 < n) && (str[1] == 'O')) { + if ((2 < n) && (str[2] == 'p')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'q')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'V')) { + return 1562; + } + return 1884; + } + return 2329; + } + return 3068; + } + } + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '_')) { + return 2822; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'q')) { + return 304; + } + return 355; + } + return 461; + } + return 599; + } + return 817; + } + return 1176; + } + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'h')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'k')) { + if ((7 < n) && (str[7] == 's')) { + return 2528; + } + return 3024; + } + return 3497; + } + } + } + } + if ((2 < n) && (str[2] == 'O')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'q')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'e')) { + return 1558; + } + return 1886; + } + return 2326; + } + return 3067; + } + } + } + } + if ((1 < n) && (str[1] == '0')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'k')) { + if ((7 < n) && (str[7] == 'T')) { + return 1282; + } + return 1605; + } + return 2018; + } + return 1737; + } + return 2354; + } + return 3171; + } + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'm')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'r')) { + return 2274; + } + return 2788; + } + return 3310; + } + } + } + } + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'a')) { + return 921; + } + return 1091; + } + return 1438; + } + return 1874; + } + return 2645; + } + return 3477; + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'q')) { + if ((7 < n) && (str[7] == 'u')) { + return 305; + } + return 357; + } + return 462; + } + return 601; + } + return 818; + } + return 1268; + } + } + if ((1 < n) && (str[1] == '2')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'q')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'n')) { + return 249; + } + return 319; + } + return 380; + } + return 521; + } + return 706; + } + return 958; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'c')) { + return 2555; + } + return 2997; + } + return 3507; + } + } + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'A')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'y')) { + return 775; + } + return 941; + } + return 1174; + } + return 1657; + } + return 2223; + } + return 1287; + } + } + if ((1 < n) && (str[1] == '4')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'b')) { + return 35; + } + return 56; + } + return 81; + } + return 111; + } + return 160; + } + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'e')) { + return 1195; + } + return 1511; + } + return 1904; + } + return 2422; + } + return 3276; + } + return 209; + } + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'c')) { + return 246; + } + return 316; + } + return 371; + } + return 514; + } + return 709; + } + return 984; + } + } + if ((1 < n) && (str[1] == '7')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'i')) { + return 2242; + } + return 2756; + } + return 3256; + } + } + } + } + } + if ((1 < n) && (str[1] == '6')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'i')) { + return 1330; + } + return 1671; + } + return 2060; + } + return 2691; + } + return 3243; + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'A')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'y')) { + return 2351; + } + return 2894; + } + return 3406; + } + } + } + return 2556; + } + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'w')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'r')) { + return 1064; + } + return 1373; + } + return 1729; + } + return 2232; + } + return 3079; + } + } + } + if ((1 < n) && (str[1] == '8')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'e')) { + return 2362; + } + return 2899; + } + return 3413; + } + } + } + return 2782; + } + } + if ((1 < n) && (str[1] == 'R')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'm')) { + if ((7 < n) && (str[7] == 'A')) { + return 2460; + } + return 2963; + } + return 3487; + } + } + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '_')) { + return 2384; + } + return 2376; + } + return 3213; + } + return 1431; + } + if ((2 < n) && (str[2] == '_')) { + return 2771; + } + } +} +if ((0 < n) && (str[0] == '0')) { + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'k')) { + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'r')) { + return 1286; + } + return 1610; + } + return 2016; + } + return 2639; + } + return 2353; + } + return 3396; + } + } + if ((1 < n) && (str[1] == 'R')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'R')) { + if ((7 < n) && (str[7] == 'e')) { + return 2140; + } + return 2597; + } + return 3135; + } + } + } + } + } + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'm')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 2273; + } + return 2787; + } + return 3311; + } + } + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'S')) { + return 1252; + } + if ((2 < n) && (str[2] == 'R')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '1')) { + return 1961; + } + return 1390; + } + return 1954; + } + return 2136; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + return 3452; + } + if ((3 < n) && (str[3] == '_')) { + return 1989; + } + return 652; + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 't')) { + return 922; + } + return 1093; + } + return 1437; + } + return 1875; + } + return 2644; + } + } + } +} +if ((0 < n) && (str[0] == '3')) { + if ((1 < n) && (str[1] == 'B')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '3')) { + return 2452; + } + return 2964; + } + return 3489; + } + } + } + } + } + if ((1 < n) && (str[1] == 'G')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 't')) { + return 1140; + } + return 1466; + } + return 1846; + } + return 2369; + } + return 3208; + } + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '_')) { + return 2484; + } + return 2961; + } + return 3475; + } + } + } + } + } + if ((1 < n) && (str[1] == '0')) { + if ((2 < n) && (str[2] == 'R')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'R')) { + return 2139; + } + return 2593; + } + return 3134; + } + } + } + } + } + if ((1 < n) && (str[1] == '3')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'B')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 't')) { + return 2342; + } + return 2877; + } + return 3379; + } + } + } + } + } + if ((1 < n) && (str[1] == '2')) { + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'c')) { + return 1217; + } + return 1546; + } + return 1942; + } + return 2572; + } + return 3329; + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '_')) { + return 2625; + } + return 483; + } + return 535; + } + return 737; + } + return 950; + } + if ((2 < n) && (str[2] == 'B')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'i')) { + return 2340; + } + return 2875; + } + return 3389; + } + } + } + } + } +} +if ((0 < n) && (str[0] == '2')) { + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 't')) { + return 1221; + } + return 1544; + } + return 1949; + } + return 2579; + } + return 3321; + } + return 3198; + } + } + if ((1 < n) && (str[1] == 'B')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'c')) { + return 2346; + } + return 2889; + } + return 3400; + } + } + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 't')) { + return 2503; + } + return 3052; + } + return 3512; + } + } + } + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == 'R')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'm')) { + return 2455; + } + return 2975; + } + return 3481; + } + } + } + } + if ((2 < n) && (str[2] == 'M')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'm')) { + if ((7 < n) && (str[7] == 'a')) { + return 2302; + } + return 2827; + } + return 3341; + } + } + } + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'c')) { + return 242; + } + return 309; + } + return 367; + } + return 504; + } + return 694; + } + return 1002; + } + } + if ((1 < n) && (str[1] == '2')) { + if ((2 < n) && (str[2] == 'B')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'e')) { + return 2345; + } + return 2888; + } + return 3401; + } + } + } + } + if ((2 < n) && (str[2] == 'w')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'a')) { + return 2520; + } + return 3025; + } + return 3501; + } + } + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'i')) { + return 681; + } + return 821; + } + return 1013; + } + return 1339; + } + return 1813; + } + return 1809; + } + } + if ((1 < n) && (str[1] == '5')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'c')) { + return 2537; + } + return 3018; + } + return 3559; + } + } + } + } + } + if ((1 < n) && (str[1] == 'w')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'l')) { + return 2547; + } + return 2984; + } + return 3531; + } + } + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'A')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'B')) { + return 774; + } + return 940; + } + return 1173; + } + return 1658; + } + return 2222; + } + return 3236; + } + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'g')) { + return 679; + } + return 822; + } + return 1011; + } + return 1392; + } + return 1812; + } + return 2603; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '3')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '_')) { + return 3109; + } + return 2930; + } + } + return 1951; + } + if ((2 < n) && (str[2] == '_')) { + return 2224; + } + } +} +if ((0 < n) && (str[0] == '5')) { + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '2')) { + return 1834; + } + return 1978; + } + return 431; + } + return 493; + } + return 677; + } + if ((3 < n) && (str[3] == 't')) { + return 2155; + } + return 583; + } + } + if ((1 < n) && (str[1] == 'R')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'e')) { + return 2278; + } + return 2863; + } + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 't')) { + return 2521; + } + return 3032; + } + return 3556; + } + } + } + } + } +} +if ((0 < n) && (str[0] == '4')) { + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 't')) { + return 247; + } + return 314; + } + return 372; + } + return 513; + } + return 710; + } + return 1042; + } + } + if ((1 < n) && (str[1] == 'f')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '4')) { + return 1104; + } + return 1398; + } + return 1696; + } + return 2096; + } + return 2849; + } + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == 'U')) { + return 34; + } + return 57; + } + return 80; + } + return 112; + } + return 168; + } + return 259; + } + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'L')) { + return 1197; + } + return 1513; + } + return 1903; + } + return 2418; + } + return 3280; + } + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == '_')) { + return 2135; + } + return 1190; + } + return 1564; + } + return 2069; + } + return 2817; + } + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'm')) { + if ((4 < n) && (str[4] == 'd')) { + return 1149; + } + return 1713; + } + return 2586; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '5')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '_')) { + return 1958; + } + return 2284; + } + return 3133; + } + return 3431; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '_')) { + return 3275; + } + return 902; + } + } +} +if ((0 < n) && (str[0] == '7')) { + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'n')) { + return 2240; + } + return 2754; + } + return 3259; + } + } + } + } + } + if ((1 < n) && (str[1] == 'E')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'm')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 't')) { + return 117; + } + return 144; + } + return 198; + } + return 261; + } + return 358; + } + return 568; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == '_')) { + return 2766; + } + } +} +if ((0 < n) && (str[0] == '6')) { + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'e')) { + return 1329; + } + return 1670; + } + return 2059; + } + return 2694; + } + return 3199; + } + } + } + if ((1 < n) && (str[1] == 'U')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 't')) { + return 1598; + } + return 2205; + } + return 3219; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'A')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'B')) { + return 2713; + } + return 2892; + } + return 3405; + } + } + } + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '7')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '_')) { + return 1179; + } + return 1665; + } + return 2226; + } + return 1594; + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'w')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'd')) { + return 1063; + } + return 1371; + } + return 1728; + } + return 2233; + } + return 3080; + } + } + } +} +if ((0 < n) && (str[0] == '9')) { + if ((1 < n) && (str[1] == 'A')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'y')) { + if ((4 < n) && (str[4] == 'O')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'j')) { + if ((7 < n) && (str[7] == 'e')) { + return 2841; + } + return 3292; + } + } + } + } + } + } + if ((1 < n) && (str[1] == 'E')) { + if ((2 < n) && (str[2] == 'q')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'b')) { + return 685; + } + return 835; + } + return 1027; + } + return 1409; + } + return 1972; + } + return 2935; + } + } + if ((1 < n) && (str[1] == 'G')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 't')) { + return 98; + } + return 128; + } + return 182; + } + return 235; + } + return 326; + } + return 511; + } + } + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'b')) { + return 1685; + } + return 2000; + } + return 2424; + } + return 3167; + } + } + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'h')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'w')) { + if ((5 < n) && (str[5] == 'F')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 1298; + } + return 1620; + } + return 2026; + } + return 2660; + } + return 3391; + } + } + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'i')) { + return 1264; + } + return 1584; + } + return 1998; + } + return 2612; + } + return 3355; + } + } + } + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'i')) { + return 1753; + } + return 2153; + } + return 2707; + } + return 3294; + } + } + } + } + if ((1 < n) && (str[1] == 'w')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'l')) { + return 2544; + } + return 2999; + } + return 3535; + } + } + } + } + } +} +if ((0 < n) && (str[0] == '8')) { + if ((1 < n) && (str[1] == 'D')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'c')) { + return 2331; + } + return 2866; + } + return 3369; + } + } + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'd')) { + return 2360; + } + return 2900; + } + return 3412; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'A')) { + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'I')) { + if ((7 < n) && (str[7] == 'n')) { + return 1070; + } + return 1376; + } + return 639; + } + return 827; + } + return 1130; + } + return 1827; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'S')) { + return 3204; + } + if ((5 < n) && (str[5] == 'B')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'f')) { + return 179; + } + return 220; + } + return 278; + } + return 221; + } + return 308; + } + return 470; + } + } + if ((1 < n) && (str[1] == 'd')) { + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'S')) { + return 2502; + } + return 2990; + } + return 3500; + } + } + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'T')) { + return 3085; + } + } + } + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'y')) { + if ((3 < n) && (str[3] == 'O')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'j')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'c')) { + return 2805; + } + return 3239; + } + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'C')) { + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '4')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'i')) { + return 720; + } + return 872; + } + return 1066; + } + return 1469; + } + return 2077; + } + return 3081; + } + } + if ((1 < n) && (str[1] == 'h')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'e')) { + return 1677; + } + return 1981; + } + return 2408; + } + return 3148; + } + } + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'k')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'S')) { + return 1332; + } + return 1666; + } + return 711; + } + return 624; + } + return 875; + } + return 1380; + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '3')) { + if ((4 < n) && (str[4] == 'B')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'G')) { + return 2400; + } + return 2933; + } + return 3442; + } + } + } + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'm')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'b')) { + return 682; + } + return 833; + } + return 813; + } + return 1043; + } + return 1499; + } + return 2276; + } + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'i')) { + return 9; + } + return 13; + } + return 23; + } + return 45; + } + return 88; + } + return 139; + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'o')) { + return 377; + } + return 478; + } + return 592; + } + return 762; + } + return 893; + } + if ((3 < n) && (str[3] == 'v')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'i')) { + return 964; + } + return 1158; + } + return 1522; + } + return 2019; + } + return 2780; + } + return 747; + } + } +} +if ((0 < n) && (str[0] == 'B')) { + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 't')) { + return 422; + } + return 522; + } + return 644; + } + return 852; + } + return 1151; + } + return 1856; + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'I')) { + return 2359; + } + return 2723; + } + return 3210; + } + } + } + } + if ((2 < n) && (str[2] == 'f')) { + if ((3 < n) && (str[3] == 'f')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'y')) { + return 2712; + } + return 3129; + } + if ((6 < n) && (str[6] == 'g')) { + return 2277; + } + return 151; + } + return 204; + } + return 292; + } + return 433; + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '3')) { + if ((7 < n) && (str[7] == 'S')) { + return 2451; + } + return 2971; + } + return 3462; + } + } + } + } + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 's')) { + return 2174; + } + return 2777; + } + return 3474; + } + } + } +} +if ((0 < n) && (str[0] == 'E')) { + if ((1 < n) && (str[1] == 'q')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == 'l')) { + return 130; + } + return 169; + } + return 223; + } + return 294; + } + return 351; + } + return 555; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'r')) { + return 3561; + } + } + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'm')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == '_')) { + return 191; + } + return 119; + } + return 147; + } + return 205; + } + return 298; + } + return 446; + } + } +} +if ((0 < n) && (str[0] == 'D')) { + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'a')) { + return 994; + } + return 1231; + } + return 1648; + } + return 2125; + } + return 2890; + } + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'c')) { + return 2867; + } + return 3370; + } + } + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'f')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'e')) { + return 982; + } + return 1085; + } + return 1434; + } + return 1867; + } + return 2627; + } + return 3493; + } + } +} +if ((0 < n) && (str[0] == 'G')) { + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'W')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 'S')) { + return 2862; + } + return 3374; + } + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + return 3541; + } + } + return 1791; + } + return 744; + } + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '_')) { + return 2562; + } + return 1872; + } + if ((2 < n) && (str[2] == 'q')) { + return 1736; + } + if ((2 < n) && (str[2] == '7')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '0')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '_')) { + return 2747; + } + return 3192; + } + } + return 2820; + } + return 2675; + } + } + if ((2 < n) && (str[2] == '6')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + return 3164; + } + return 3073; + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + return 3439; + } + return 1839; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'o')) { + return 25; + } + return 41; + } + return 64; + } + return 95; + } + return 140; + } + return 237; + } + } + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '3')) { + if ((5 < n) && (str[5] == 'B')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'x')) { + return 2401; + } + return 2934; + } + return 3446; + } + } + return 3274; + } + } + } + if ((1 < n) && (str[1] == 'V')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'l')) { + return 663; + } + return 802; + } + return 993; + } + return 1377; + } + return 1909; + } + return 2887; + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '_')) { + return 3100; + } + return 2844; + } + if ((4 < n) && (str[4] == '7')) { + if ((5 < n) && (str[5] == 'I')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'd')) { + return 2647; + } + return 3124; + } + } + return 2816; + } + return 570; + } + if ((3 < n) && (str[3] == '3')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'S')) { + return 2435; + } + return 2677; + } + return 3178; + } + } + } + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'o')) { + return 2315; + } + return 2825; + } + return 3123; + } + } + return 2922; + } + if ((3 < n) && (str[3] == '5')) { + if ((4 < n) && (str[4] == 'R')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'g')) { + return 1799; + } + return 2183; + } + return 2745; + } + return 3347; + } + return 2225; + } + return 321; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == 'O')) { + if ((7 < n) && (str[7] == 'p')) { + return 2458; + } + return 2973; + } + return 3480; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'F')) { + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'l')) { + return 1001; + } + return 1238; + } + return 1655; + } + return 2134; + } + return 2898; + } + } + } + if ((1 < n) && (str[1] == 'G')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'W')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'S')) { + return 3050; + } + return 3450; + } + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'S')) { + return 3000; + } + return 3511; + } + return 1473; + } + return 1877; + } + return 2570; + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == 'O')) { + return 2453; + } + return 2970; + } + return 3490; + } + } + } + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'w')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'I')) { + return 649; + } + return 347; + } + return 449; + } + return 590; + } + return 808; + } + return 1112; + } + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'i')) { + return 920; + } + return 1092; + } + return 1439; + } + return 1861; + } + return 2617; + } + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '4')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'i')) { + return 987; + } + return 1206; + } + return 1580; + } + return 2102; + } + return 2856; + } + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '_')) { + return 1051; + } + return 1710; + } + if ((2 < n) && (str[2] == '0')) { + if ((3 < n) && (str[3] == '_')) { + return 1230; + } + return 1960; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'm')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == '1')) { + return 1305; + } + return 1640; + } + return 2022; + } + return 2656; + } + return 3385; + } + } + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'm')) { + if ((4 < n) && (str[4] == 'E')) { + if ((5 < n) && (str[5] == 'q')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'a')) { + return 2479; + } + return 2979; + } + return 3537; + } + } + return 3063; + } + } + } + if ((1 < n) && (str[1] == '4')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'm')) { + if ((5 < n) && (str[5] == 'd')) { + return 3196; + } + } + } + } + } + if ((1 < n) && (str[1] == 'V')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'l')) { + return 1955; + } + return 2323; + } + return 2918; + } + } + } + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'A')) { + if ((7 < n) && (str[7] == 'r')) { + return 1405; + } + return 1727; + } + return 1963; + } + return 2290; + } + return 1523; + } + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'o')) { + return 1853; + } + return 2230; + } + return 2769; + } + return 3330; + } + return 3295; + } + return 766; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == 'M')) { + if ((7 < n) && (str[7] == 'i')) { + return 2454; + } + return 2965; + } + return 3485; + } + return 3140; + } + return 2944; + } + return 3335; + } + } +} +if ((0 < n) && (str[0] == 'I')) { + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == 'l')) { + return 1208; + } + return 1534; + } + return 1899; + } + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'g')) { + return 2234; + } + return 2761; + } + return 3253; + } + if ((5 < n) && (str[5] == 'S')) { + return 3223; + } + if ((5 < n) && (str[5] == 'O')) { + if ((6 < n) && (str[6] == 'f')) { + return 2931; + } + return 3434; + } + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '2')) { + return 2115; + } + return 1733; + } + if ((5 < n) && (str[5] == 'T')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'p')) { + return 322; + } + return 379; + } + return 487; + } + if ((5 < n) && (str[5] == 'w')) { + if ((6 < n) && (str[6] == 'x')) { + return 2350; + } + return 2940; + } + if ((5 < n) && (str[5] == '_')) { + return 2275; + } + return 59; + } + return 83; + } + return 133; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'L')) { + return 1537; + } + if ((7 < n) && (str[7] == 'T')) { + return 1962; + } + return 619; + } + return 772; + } + return 1000; + } + return 1157; + } + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'E')) { + if ((5 < n) && (str[5] == 'q')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'a')) { + return 2472; + } + return 2981; + } + return 3520; + } + } + } + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '6')) { + return 3070; + } + } + if ((3 < n) && (str[3] == '3')) { + if ((4 < n) && (str[4] == '2')) { + return 2725; + } + return 3183; + } + if ((3 < n) && (str[3] == '6')) { + if ((4 < n) && (str[4] == '4')) { + return 3333; + } + } + if ((3 < n) && (str[3] == '8')) { + return 3454; + } + return 320; + } + } +} +if ((0 < n) && (str[0] == 'H')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'h')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 2804; + } + return 3221; + } + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'K')) { + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '9')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'h')) { + return 1292; + } + return 1633; + } + return 2034; + } + return 2337; + } + return 1922; + } + return 2904; + } + } +} +if ((0 < n) && (str[0] == 'M')) { + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'R')) { + if ((7 < n) && (str[7] == 'e')) { + return 1218; + } + return 1548; + } + return 1948; + } + return 2573; + } + return 3327; + } + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'r')) { + return 778; + } + return 714; + } + return 956; + } + return 1521; + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'm')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'E')) { + return 2297; + } + return 414; + } + return 533; + } + return 687; + } + return 943; + } + return 1458; + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'C')) { + return 708; + } + return 376; + } + return 490; + } + return 627; + } + return 878; + } + return 1382; + } + } +} +if ((0 < n) && (str[0] == 'L')) { + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'C')) { + return 1601; + } + return 926; + } + return 1119; + } + return 1526; + } + return 2166; + } + return 3156; + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'k')) { + return 1240; + } + return 1515; + } + return 1906; + } + return 2420; + } + return 3265; + } + } + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == 'g')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'g')) { + return 2682; + } + return 3186; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'O')) { + if ((1 < n) && (str[1] == 'p')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'a')) { + return 1561; + } + return 1883; + } + return 2116; + } + return 2746; + } + return 3456; + } + } + } + if ((1 < n) && (str[1] == 'b')) { + if ((2 < n) && (str[2] == 'j')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 't')) { + return 1391; + } + return 1831; + } + return 2582; + } + return 3205; + } + } + if ((1 < n) && (str[1] == 'f')) { + if ((2 < n) && (str[2] == 'B')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 's')) { + return 1453; + } + return 1787; + } + return 2211; + } + return 2884; + } + } + } + if ((2 < n) && (str[2] == 'E')) { + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'a')) { + return 2123; + } + return 2585; + } + return 3126; + } + } + } + } + if ((2 < n) && (str[2] == 'f')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'i')) { + return 1449; + } + return 1770; + } + return 2199; + } + return 2858; + } + } + } + } +} +if ((0 < n) && (str[0] == 'N')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'v')) { + if ((5 < n) && (str[5] == 'e')) { + return 1433; + } + return 1866; + } + return 2626; + } + } + } +} +if ((0 < n) && (str[0] == 'P')) { + if ((1 < n) && (str[1] == 'A')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'F')) { + if ((6 < n) && (str[6] == 'F')) { + return 3232; + } + } + return 2253; + } + return 3086; + } + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + return 1435; + } + return 1690; + } + return 1798; + } + return 2398; + } + return 3441; + } + } +} +if ((0 < n) && (str[0] == 'S')) { + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == '9')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'h')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'w')) { + if ((7 < n) && (str[7] == 'F')) { + return 1290; + } + return 1632; + } + return 2039; + } + return 2654; + } + return 3394; + } + } + if ((2 < n) && (str[2] == '1')) { + return 2834; + } + if ((2 < n) && (str[2] == '4')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'S')) { + return 1088; + } + return 1386; + } + return 1764; + } + return 2266; + } + return 3114; + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '6')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'e')) { + return 2525; + } + return 3009; + } + return 3494; + } + } + return 3131; + } + return 2261; + } + } + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'W')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 'S')) { + return 3449; + } + } + return 2734; + } + } + if ((1 < n) && (str[1] == 'b')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '0')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'c')) { + return 1309; + } + return 1524; + } + return 1921; + } + return 2557; + } + return 3296; + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'q')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'e')) { + return 69; + } + return 65; + } + return 93; + } + return 127; + } + return 194; + } + return 313; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '1')) { + return 2504; + } + return 2985; + } + return 3484; + } + } + return 3433; + } + return 2386; + } + } + if ((1 < n) && (str[1] == 'g')) { + if ((2 < n) && (str[2] == '5')) { + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 's')) { + return 1924; + } + return 1591; + } + return 805; + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == '1')) { + return 3166; + } + return 2385; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'S')) { + return 788; + } + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '1')) { + return 1912; + } + return 1189; + } + return 404; + } + return 328; + } + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'I')) { + if ((7 < n) && (str[7] == 'n')) { + return 2218; + } + return 2739; + } + return 2742; + } + return 3337; + } + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'W')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 'S')) { + return 3518; + } + } + } + if ((3 < n) && (str[3] == '_')) { + return 2221; + } + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'S')) { + return 1887; + } + return 1680; + } + return 324; + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'e')) { + return 953; + } + return 1203; + } + return 1917; + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'L')) { + if ((7 < n) && (str[7] == 'o')) { + return 1115; + } + return 1425; + } + return 1808; + } + return 2310; + } + return 3160; + } + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '_')) { + return 1938; + } + return 1852; + } + return 2377; + } + return 1385; + } + if ((3 < n) && (str[3] == 'w')) { + if ((4 < n) && (str[4] == 'x')) { + return 3378; + } + } + if ((3 < n) && (str[3] == '_')) { + return 1940; + } + return 236; + } + } + if ((1 < n) && (str[1] == '0')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + return 3102; + } + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + return 2803; + } + if ((4 < n) && (str[4] == '_')) { + return 1474; + } + return 468; + } + return 187; + } + } + if ((1 < n) && (str[1] == '3')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '4')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '_')) { + return 2168; + } + return 366; + } + return 390; + } + return 536; + } + return 665; + } + if ((3 < n) && (str[3] == '_')) { + return 2813; + } + return 488; + } + } + if ((1 < n) && (str[1] == '2')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '3')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '_')) { + return 2561; + } + return 2271; + } + return 2936; + } + return 2339; + } + if ((3 < n) && (str[3] == '_')) { + return 1878; + } + return 402; + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'e')) { + return 3297; + } + } + } + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'q')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'e')) { + return 303; + } + return 356; + } + return 463; + } + return 600; + } + return 819; + } + return 948; + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'k')) { + if ((5 < n) && (str[5] == '4')) { + if ((6 < n) && (str[6] == 'f')) { + if ((7 < n) && (str[7] == 'i')) { + return 1302; + } + return 1637; + } + return 2020; + } + return 2427; + } + return 3215; + } + return 2397; + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'o')) { + return 2438; + } + return 2859; + } + return 1410; + } + return 1797; + } + return 1121; + } + return 1455; + } + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'U')) { + if ((7 < n) && (str[7] == 'n')) { + return 36; + } + return 55; + } + return 79; + } + return 103; + } + return 166; + } + return 262; + } + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'e')) { + return 1644; + } + return 1497; + } + return 1979; + } + return 2744; + } + } + } + if ((1 < n) && (str[1] == '7')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '0')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '_')) { + return 3190; + } + } + } + return 3455; + } + if ((3 < n) && (str[3] == '_')) { + return 1819; + } + return 934; + } + } + if ((1 < n) && (str[1] == '6')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '7')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '_')) { + return 945; + } + return 1175; + } + return 1664; + } + return 1028; + } + return 771; + } + } + if ((1 < n) && (str[1] == '9')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'h')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'w')) { + if ((6 < n) && (str[6] == 'F')) { + if ((7 < n) && (str[7] == 'r')) { + return 1307; + } + return 1623; + } + return 2037; + } + return 2664; + } + return 3392; + } + } + } + if ((1 < n) && (str[1] == '5')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '_')) { + return 2732; + } + return 1006; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '_')) { + return 1394; + } + return 1841; + } + return 2467; + } + return 3420; + } + if ((2 < n) && (str[2] == '3')) { + if ((3 < n) && (str[3] == 'B')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'G')) { + if ((7 < n) && (str[7] == 'V')) { + return 2552; + } + return 2932; + } + return 3445; + } + } + } + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'l')) { + return 1328; + } + return 1663; + } + return 2055; + } + return 2686; + } + return 3362; + } + return 2285; + } + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == 'O')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'q')) { + return 2448; + } + return 2967; + } + return 3488; + } + } + return 3165; + } + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'r')) { + return 1265; + } + return 1588; + } + return 1995; + } + return 2607; + } + return 3273; + } + return 1166; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '_')) { + } + return 3; + } + return 4; + } + return 7; + } + return 15; + } + return 37; + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == 'M')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'i')) { + return 2439; + } + return 2952; + } + return 3472; + } + } + } + return 3492; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '6')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 2519; + } + return 3026; + } + return 3536; + } + } + } + return 1145; + } + } + if ((1 < n) && (str[1] == '4')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'u')) { + return 1087; + } + return 1387; + } + return 1763; + } + return 2265; + } + return 3115; + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '5')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '_')) { + return 1555; + } + return 1792; + } + return 2286; + } + return 2768; + } + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + return 3315; + } + return 653; + } + return 389; + } + } +} +if ((0 < n) && (str[0] == 'R')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'm')) { + if ((6 < n) && (str[6] == 'A')) { + if ((7 < n) && (str[7] == 'c')) { + return 411; + } + return 518; + } + return 636; + } + return 828; + } + return 1127; + } + if ((3 < n) && (str[3] == 'g')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'R')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'p')) { + return 438; + } + return 544; + } + return 671; + } + return 329; + } + return 469; + } + return 364; + } + } + if ((1 < n) && (str[1] == 'x')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '4')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'l')) { + return 1041; + } + return 1340; + } + return 1699; + } + return 2188; + } + return 847; + } + return 657; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'p')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'a')) { + return 441; + } + return 530; + } + return 646; + } + return 851; + } + return 1146; + } + return 1496; + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'n')) { + return 1223; + } + return 1549; + } + return 1952; + } + return 2575; + } + return 3325; + } + return 3320; + } + } +} +if ((0 < n) && (str[0] == 'U')) { + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 't')) { + return 1229; + } + return 1914; + } + } + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 't')) { + return 32; + } + return 54; + } + return 76; + } + return 106; + } + return 156; + } + return 210; + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'f')) { + if ((5 < n) && (str[5] == 'e')) { + return 3331; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'T')) { + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 't')) { + return 1740; + } + return 2131; + } + return 2681; + } + return 3066; + } + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'u')) { + return 3502; + } + } + return 1108; + } + return 1039; + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'A')) { + return 1600; + } + return 1926; + } + return 2363; + } + return 2733; + } + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'C')) { + return 2171; + } + return 2624; + } + return 3157; + } + } + return 1634; + } + return 2120; + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == '5')) { + if ((4 < n) && (str[4] == 'S')) { + return 3180; + } + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 's')) { + return 3218; + } + } + } + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 's')) { + return 1468; + } + return 1083; + } + return 540; + } + return 806; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '_')) { + return 1284; + } + return 1603; + } + return 2012; + } + return 2630; + } + return 3202; + } + } + } + if ((1 < n) && (str[1] == 'W')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'R')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '1')) { + return 2566; + } + return 1844; + } + return 2365; + } + return 3184; + } + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '4')) { + return 1320; + } + return 1654; + } + if ((6 < n) && (str[6] == 's')) { + return 2390; + } + return 857; + } + return 918; + } + return 1274; + } + return 924; + } + if ((2 < n) && (str[2] == 'V')) { + return 2792; + } + } + if ((1 < n) && (str[1] == 'y')) { + if ((2 < n) && (str[2] == 'p')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'w')) { + if ((5 < n) && (str[5] == 'x')) { + return 3147; + } + return 2163; + } + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'F')) { + if ((7 < n) && (str[7] == 'S')) { + return 1153; + } + return 1456; + } + return 1705; + } + return 1168; + } + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'i')) { + return 789; + } + return 641; + } + if ((6 < n) && (str[6] == 'G')) { + if ((7 < n) && (str[7] == 'S')) { + return 2267; + } + return 1170; + } + return 327; + } + if ((5 < n) && (str[5] == 'F')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '1')) { + return 2406; + } + if ((7 < n) && (str[7] == '0')) { + return 929; + } + return 482; + } + return 602; + } + return 186; + } + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 's')) { + return 2772; + } + return 1919; + } + return 2192; + } + return 1365; + } + if ((4 < n) && (str[4] == 'W')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == '9')) { + if ((7 < n) && (str[7] == 'G')) { + return 2441; + } + return 2953; + } + return 3430; + } + return 3225; + } + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '_')) { + return 2554; + } + return 3038; + } + return 1444; + } + return 791; + } + return 26; + } + return 66; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '9')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'h')) { + if ((7 < n) && (str[7] == 'o')) { + return 1303; + } + return 1630; + } + return 2038; + } + return 2666; + } + return 3179; + } + return 1715; + } + } +} +if ((0 < n) && (str[0] == 'W')) { + if ((1 < n) && (str[1] == 'x')) { + if ((2 < n) && (str[2] == '9')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 361; + } + return 450; + } + return 576; + } + return 741; + } + return 1004; + } + return 1675; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '2')) { + if ((7 < n) && (str[7] == '_')) { + return 2688; + } + return 3144; + } + return 2949; + } + return 2581; + } + return 3326; + } + if ((3 < n) && (str[3] == '0')) { + if ((4 < n) && (str[4] == '_')) { + return 3359; + } + } + if ((3 < n) && (str[3] == '3')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '4')) { + if ((7 < n) && (str[7] == '_')) { + return 866; + } + return 1034; + } + return 1323; + } + return 1726; + } + return 2341; + } + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '3')) { + if ((7 < n) && (str[7] == '_')) { + return 2374; + } + return 2910; + } + return 2861; + } + return 981; + } + return 1423; + } + return 336; + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 'R')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '1')) { + return 3110; + } + return 2366; + } + return 3201; + } + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '4')) { + if ((7 < n) && (str[7] == 'S')) { + return 1321; + } + return 1653; + } + return 2050; + } + if ((5 < n) && (str[5] == 's')) { + return 3057; + } + return 1098; + } + return 1273; + } + return 2003; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == '9')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 988; + } + return 1205; + } + return 1582; + } + return 2103; + } + return 2854; + } + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '3')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '4')) { + if ((7 < n) && (str[7] == '_')) { + return 1571; + } + return 1908; + } + return 2347; + } + return 3084; + } + } + return 1443; + } + } +} +if ((0 < n) && (str[0] == 'V')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'I')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 't')) { + return 1739; + } + return 2133; + } + return 2679; + } + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == '_')) { + return 1832; + } + return 2173; + } + return 2058; + } + if ((5 < n) && (str[5] == 'W')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'S')) { + return 2498; + } + return 3012; + } + return 2636; + } + if ((5 < n) && (str[5] == 'F')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'o')) { + return 1752; + } + return 2148; + } + if ((6 < n) && (str[6] == 'G')) { + if ((7 < n) && (str[7] == 'V')) { + return 2553; + } + return 2950; + } + if ((6 < n) && (str[6] == 'W')) { + if ((7 < n) && (str[7] == 'x')) { + return 2506; + } + return 3046; + } + return 542; + } + return 206; + } + return 291; + } + return 429; + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'w')) { + return 2289; + } + return 3101; + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'S')) { + return 3440; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == 'O')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'a')) { + return 2447; + } + return 2974; + } + return 3486; + } + } + if ((4 < n) && (str[4] == '4')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'u')) { + return 1269; + } + return 1587; + } + return 1983; + } + return 2443; + } + return 1436; + } + if ((3 < n) && (str[3] == '3')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'l')) { + return 1325; + } + return 1661; + } + return 2052; + } + return 2685; + } + return 3278; + } + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == 'M')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'n')) { + return 2440; + } + return 2954; + } + return 3471; + } + } + return 3408; + } + return 480; + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '4')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'i')) { + return 115; + } + return 145; + } + return 200; + } + return 263; + } + return 359; + } + return 571; + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'A')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'r')) { + return 812; + } + return 986; + } + return 1251; + } + return 990; + } + return 944; + } + if ((3 < n) && (str[3] == '5')) { + return 3226; + } + if ((3 < n) && (str[3] == '7')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'e')) { + return 2375; + } + return 2909; + } + return 3422; + } + } + return 2426; + } + return 269; + } + if ((2 < n) && (str[2] == '3')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'S')) { + return 2432; + } + return 2957; + } + return 2924; + } + return 3457; + } + } + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'n')) { + return 734; + } + return 844; + } + return 1012; + } + return 1246; + } + return 1693; + } + return 1037; + } + if ((2 < n) && (str[2] == '5')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 't')) { + return 1200; + } + return 1688; + } + return 2260; + } + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'c')) { + return 3176; + } + } + } + } + if ((3 < n) && (str[3] == 'R')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'g')) { + if ((7 < n) && (str[7] == 'e')) { + return 1714; + } + return 1982; + } + return 2409; + } + return 3149; + } + } + return 877; + } + if ((2 < n) && (str[2] == '6')) { + if ((3 < n) && (str[3] == 'U')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 't')) { + return 976; + } + return 1241; + } + return 1706; + } + return 2306; + } + return 2399; + } + } + if ((1 < n) && (str[1] == '4')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'm')) { + if ((5 < n) && (str[5] == 'd')) { + return 2109; + } + return 2738; + } + return 3447; + } + } + } +} +if ((0 < n) && (str[0] == '_')) { + if ((1 < n) && (str[1] == 'A')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'B')) { + if ((7 < n) && (str[7] == 'u')) { + return 465; + } + return 557; + } + return 634; + } + return 830; + } + return 1132; + } + return 1828; + } + } + if ((1 < n) && (str[1] == 'q')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == 'w')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 2527; + } + return 3001; + } + return 3545; + } + } + } + } + } + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'g')) { + if ((7 < n) && (str[7] == 'u')) { + return 531; + } + return 630; + } + return 785; + } + return 1017; + } + return 1491; + } + return 1427; + } + } + if ((1 < n) && (str[1] == 'B')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'n')) { + return 2203; + } + return 2729; + } + return 3214; + } + } + } + } + } + if ((1 < n) && (str[1] == 'w')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'b')) { + return 1393; + } + return 1719; + } + return 2175; + } + return 2800; + } + } + return 2968; + } + } + if ((1 < n) && (str[1] == 'G')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + return 3249; + } + return 2162; + } + return 1464; + } + if ((3 < n) && (str[3] == '7')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + return 2801; + } + return 2588; + } + return 3339; + } + if ((3 < n) && (str[3] == '_')) { + return 2126; + } + if ((3 < n) && (str[3] == '6')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + return 2895; + } + return 2749; + } + return 3459; + } + return 141; + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '1')) { + return 1860; + } + return 1536; + } + return 2080; + } + } + if ((1 < n) && (str[1] == '3')) { + if ((2 < n) && (str[2] == 'B')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 's')) { + return 2551; + } + return 3002; + } + return 3436; + } + } + } + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 1326; + } + return 1662; + } + return 2054; + } + return 2684; + } + return 3416; + } + } + } + if ((1 < n) && (str[1] == 'K')) { + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '9')) { + if ((7 < n) && (str[7] == 's')) { + return 2081; + } + return 2425; + } + return 2905; + } + return 1969; + } + return 2743; + } + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '_')) { + return 1835; + } + return 2568; + } + return 2687; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '1')) { + return 3216; + } + } + } + return 2868; + } + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'S')) { + return 616; + } + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '1')) { + return 1528; + } + return 932; + } + return 332; + } + return 481; + } + if ((3 < n) && (str[3] == 'g')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'I')) { + return 2361; + } + return 2902; + } + return 3411; + } + } + } + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + return 3120; + } + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'S')) { + return 3169; + } + return 2338; + } + return 609; + } + return 251; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '9')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'h')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'w')) { + return 1310; + } + return 1621; + } + return 2025; + } + return 2655; + } + return 3381; + } + return 2614; + } + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + return 1863; + } + return 745; + } + return 793; + } + if ((2 < n) && (str[2] == '0')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + return 3565; + } + if ((5 < n) && (str[5] == '_')) { + return 1718; + } + return 574; + } + return 556; + } + return 625; + } + if ((2 < n) && (str[2] == '3')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '4')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '_')) { + return 865; + } + return 753; + } + return 949; + } + return 1124; + } + if ((4 < n) && (str[4] == '_')) { + return 2587; + } + return 696; + } + return 1036; + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + return 1814; + } + return 1322; + } + return 2049; + } + if ((2 < n) && (str[2] == '5')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + return 2387; + } + return 1838; + } + return 2798; + } + if ((2 < n) && (str[2] == '4')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '_')) { + return 2773; + } + return 575; + } + return 437; + } + return 669; + } + if ((2 < n) && (str[2] == '7')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + return 1578; + } + return 1829; + } + return 2783; + } + if ((2 < n) && (str[2] == '6')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '7')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '_')) { + return 1717; + } + return 2089; + } + return 2613; + } + return 3206; + } + return 2021; + } + return 2976; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'S')) { + return 1; + } + return 2; + } + return 5; + } + return 6; + } + return 14; + } + return 27; + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'e')) { + return 2177; + } + return 2648; + } + return 3173; + } + } + } + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'h')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'k')) { + return 2548; + } + return 3045; + } + return 3503; + } + } + } + if ((3 < n) && (str[3] == 'O')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'q')) { + if ((7 < n) && (str[7] == 'u')) { + return 2457; + } + return 2969; + } + return 3491; + } + } + } + return 1358; + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 2550; + } + return 3021; + } + return 3543; + } + } + } + } + if ((2 < n) && (str[2] == '4')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'c')) { + return 1266; + } + return 1585; + } + return 1993; + } + return 2618; + } + return 3351; + } + } + if ((2 < n) && (str[2] == '6')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'l')) { + return 2518; + } + return 2982; + } + return 3505; + } + } + } + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '3')) { + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'e')) { + return 2258; + } + return 2770; + } + return 3272; + } + } + } + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'q')) { + if ((7 < n) && (str[7] == 'u')) { + return 434; + } + return 541; + } + return 666; + } + return 892; + } + return 1135; + } + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'l')) { + return 767; + } + return 935; + } + return 1156; + } + return 1641; + } + return 2111; + } + return 406; + } + if ((2 < n) && (str[2] == '9')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'x')) { + return 2137; + } + return 2595; + } + return 3137; + } + } + } + if ((3 < n) && (str[3] == 'E')) { + if ((4 < n) && (str[4] == 'q')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 't')) { + return 1089; + } + return 1388; + } + return 1765; + } + return 2269; + } + return 3116; + } + return 2186; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'S')) { + return 783; + } + return 952; + } + return 1198; + } + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'G')) { + return 3244; + } + return 3231; + } + return 868; + } + return 782; + } + return 936; + } + } + if ((1 < n) && (str[1] == 'R')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '1')) { + return 2379; + } + return 1525; + } + return 2293; + } + } + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == '5')) { + return 3482; + } + } + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'U')) { + return 3443; + } + return 1704; + } + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '2')) { + if ((7 < n) && (str[7] == '_')) { + return 1590; + } + return 1913; + } + return 2101; + } + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == '2')) { + if ((7 < n) && (str[7] == '_')) { + return 2170; + } + return 2615; + } + return 3107; + } + return 1096; + } + return 1370; + } + return 620; + } + } + if ((1 < n) && (str[1] == 'W')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '3')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '4')) { + return 2433; + } + return 2916; + } + return 3428; + } + } + return 1159; + } + return 1676; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '9')) { + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'e')) { + return 2108; + } + return 2560; + } + return 3108; + } + } + } + } + } + if ((1 < n) && (str[1] == 'x')) { + if ((2 < n) && (str[2] == '9')) { + if ((3 < n) && (str[3] == 'w')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'V')) { + return 2509; + } + return 2998; + } + return 3551; + } + } + } + } + } + if ((1 < n) && (str[1] == '9')) { + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 334; + } + return 413; + } + return 532; + } + return 684; + } + return 938; + } + return 1495; + } + } + if ((1 < n) && (str[1] == '2')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == 'M')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'm')) { + return 2436; + } + return 2956; + } + return 3470; + } + } + } + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == 'w')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'V')) { + return 2541; + } + return 3006; + } + return 3540; + } + } + } + } + if ((2 < n) && (str[2] == '5')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 2523; + } + return 3031; + } + return 3517; + } + } + } + } + } + if ((1 < n) && (str[1] == 'z')) { + if ((2 < n) && (str[2] == 'W')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == '_')) { + return 1201; + } + return 1576; + } + return 1181; + } + return 1725; + } + return 1823; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'q')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == 'w')) { + if ((7 < n) && (str[7] == 'r')) { + return 2514; + } + return 3053; + } + return 3558; + } + } + } + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'F')) { + if ((4 < n) && (str[4] == 'T')) { + return 3177; + } + } + } + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '1')) { + return 3373; + } + return 467; + } + return 610; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'i')) { + return 3111; + } + } + } + return 426; + } + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'r')) { + return 2497; + } + return 3040; + } + return 3499; + } + } + } + if ((3 < n) && (str[3] == '6')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'i')) { + return 2496; + } + return 2978; + } + return 3544; + } + } + } + return 3195; + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == '1')) { + return 1318; + } + return 1500; + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == '5')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'r')) { + return 2539; + } + return 2983; + } + return 3527; + } + } + } + } + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == '5')) { + return 3059; + } + return 3566; + } + } + return 3142; + } + if ((3 < n) && (str[3] == 'F')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'a')) { + return 3222; + } + return 3332; + } + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '2')) { + return 1579; + } + return 1692; + } + if ((6 < n) && (str[6] == '2')) { + if ((7 < n) && (str[7] == '2')) { + return 2161; + } + return 2559; + } + return 854; + } + return 946; + } + return 407; + } + return 331; + } + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == '9')) { + if ((4 < n) && (str[4] == 'w')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'p')) { + return 2522; + } + return 3030; + } + return 3555; + } + } + } + } + if ((2 < n) && (str[2] == 'z')) { + if ((3 < n) && (str[3] == 'W')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 'S')) { + return 2671; + } + return 3242; + } + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'S')) { + return 2113; + } + return 2727; + } + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == '2')) { + if ((7 < n) && (str[7] == 'w')) { + return 2535; + } + return 2993; + } + return 3548; + } + } + } + if ((3 < n) && (str[3] == 'S')) { + return 2169; + } + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'F')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'a')) { + return 2731; + } + return 2736; + } + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '1')) { + return 1357; + } + if ((7 < n) && (str[7] == '2')) { + return 2107; + } + return 678; + } + return 739; + } + return 365; + } + return 350; + } + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == '9')) { + if ((5 < n) && (str[5] == 'w')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 2533; + } + return 3051; + } + return 3552; + } + } + } + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'F')) { + return 1518; + } + return 1775; + } + return 1105; + } + return 118; + } + } +} +if ((0 < n) && (str[0] == 'a')) { + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'k')) { + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'e')) { + return 1275; + } + return 1599; + } + return 2007; + } + return 2629; + } + return 3367; + } + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == 'f')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 1311; + } + return 1636; + } + return 2027; + } + return 2662; + } + return 3377; + } + return 1803; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'C')) { + return 580; + } + return 550; + } + return 674; + } + return 898; + } + return 1212; + } + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '4')) { + return 1278; + } + return 1608; + } + return 2011; + } + return 2637; + } + return 3372; + } + return 755; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'r')) { + return 3200; + } + } + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'e')) { + return 725; + } + return 883; + } + return 1079; + } + return 1483; + } + return 2097; + } + return 1529; + } + } + if ((1 < n) && (str[1] == 'b')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'l')) { + return 233; + } + return 284; + } + return 337; + } + return 447; + } + if ((4 < n) && (str[4] == 'F')) { + if ((5 < n) && (str[5] == 'W')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'S')) { + return 2483; + } + return 3020; + } + return 2692; + } + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'a')) { + return 1748; + } + return 2147; + } + return 2701; + } + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '_')) { + return 1750; + } + return 2149; + } + return 2698; + } + return 655; + } + if ((4 < n) && (str[4] == 's')) { + return 2172; + } + if ((4 < n) && (str[4] == 'S')) { + return 2906; + } + if ((4 < n) && (str[4] == 'r')) { + return 3170; + } + if ((4 < n) && (str[4] == 'w')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'S')) { + return 2217; + } + return 2778; + } + return 3340; + } + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'u')) { + return 1267; + } + return 1586; + } + return 1994; + } + return 2619; + } + return 58; + } + return 97; + } + } + if ((1 < n) && (str[1] == 'k')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 860; + } + return 1019; + } + return 1356; + } + return 1774; + } + return 2392; + } + return 2870; + } + } + if ((1 < n) && (str[1] == 'm')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '0')) { + if ((7 < n) && (str[7] == 's')) { + return 1293; + } + return 1619; + } + return 2040; + } + return 2657; + } + return 3319; + } + return 3358; + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'T')) { + return 1901; + } + return 1498; + } + return 1698; + } + return 2187; + } + return 2945; + } + } + if ((2 < n) && (str[2] == 'E')) { + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'a')) { + return 2295; + } + return 2830; + } + return 3090; + } + } + } + } + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'v')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 1614; + } + return 1935; + } + return 2383; + } + return 3119; + } + return 1722; + } + return 2616; + } + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'o')) { + return 1738; + } + return 2130; + } + return 2678; + } + return 3270; + } + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'W')) { + return 2485; + } + return 2220; + } + return 2728; + } + return 2623; + } + if ((4 < n) && (str[4] == 'W')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'S')) { + return 2989; + } + return 3528; + } + return 3235; + } + if ((4 < n) && (str[4] == 'F')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'm')) { + return 1747; + } + return 2150; + } + return 2703; + } + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'S')) { + return 2529; + } + return 3017; + } + return 3463; + } + if ((5 < n) && (str[5] == 'W')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'S')) { + return 2486; + } + return 3036; + } + return 3547; + } + return 718; + } + return 268; + } + return 362; + } + } + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'e')) { + return 2948; + } + } + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'm')) { + if ((5 < n) && (str[5] == 'A')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'c')) { + return 412; + } + return 519; + } + return 633; + } + return 823; + } + return 1125; + } + return 1784; + } + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'R')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'l')) { + return 440; + } + return 547; + } + return 675; + } + return 897; + } + return 435; + } + return 662; + } + } + if ((1 < n) && (str[1] == 'q')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'u')) { + return 1559; + } + return 1882; + } + return 2330; + } + return 3069; + } + return 3417; + } + } + } + if ((1 < n) && (str[1] == 'p')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'y')) { + return 2774; + } + return 3289; + } + } + } + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'I')) { + return 1744; + } + if ((7 < n) && (str[7] == 'F')) { + return 2531; + } + return 885; + } + return 1078; + } + return 1482; + } + return 2100; + } + return 3104; + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'h')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + return 3241; + } + } + } + } + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + return 2075; + } + return 2404; + } + return 3139; + } + } + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + return 1030; + } + return 1401; + } + return 1970; + } + return 1361; + } + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'x')) { + return 748; + } + return 837; + } + return 1032; + } + return 1346; + } + return 1858; + } + return 1233; + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'd')) { + return 1573; + } + return 2079; + } + return 2600; + } + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'a')) { + return 2298; + } + return 2829; + } + if ((6 < n) && (str[6] == 'F')) { + if ((7 < n) && (str[7] == 'W')) { + return 2488; + } + if ((7 < n) && (str[7] == 'G')) { + return 2475; + } + if ((7 < n) && (str[7] == 'V')) { + return 2505; + } + return 593; + } + return 226; + } + return 297; + } + return 393; + } + return 595; + } + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'n')) { + return 1054; + } + return 1202; + } + if ((3 < n) && (str[3] == 'v')) { + if ((4 < n) && (str[4] == 'e')) { + return 1460; + } + return 2070; + } + return 719; + } + if ((2 < n) && (str[2] == 'e')) { + return 2851; + } + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'S')) { + return 1501; + } + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'e')) { + return 1120; + } + return 1422; + } + return 1801; + } + return 2307; + } + if ((4 < n) && (str[4] == '7')) { + if ((5 < n) && (str[5] == 'E')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 173; + } + return 212; + } + return 274; + } + return 341; + } + return 152; + } + return 228; + } + } + if ((1 < n) && (str[1] == 'y')) { + if ((2 < n) && (str[2] == 'B')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'f')) { + if ((5 < n) && (str[5] == 'f')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 184; + } + return 219; + } + return 279; + } + return 348; + } + return 509; + } + return 752; + } + } +} +if ((0 < n) && (str[0] == 'c')) { + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'I')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'd')) { + return 1068; + } + return 1378; + } + return 1735; + } + return 740; + } + return 995; + } + return 1647; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'o')) { + return 579; + } + return 716; + } + return 656; + } + return 863; + } + return 1167; + } + return 1868; + } + if ((2 < n) && (str[2] == 'L')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'a')) { + return 1191; + } + return 1512; + } + return 1893; + } + return 2364; + } + return 2855; + } + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'e')) { + return 1069; + } + return 1379; + } + return 1731; + } + return 2249; + } + return 859; + } + return 975; + } + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'y')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'F')) { + return 1510; + } + return 895; + } + return 370; + } + return 505; + } + return 695; + } + return 801; + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '4')) { + if ((7 < n) && (str[7] == 'S')) { + return 1279; + } + return 1609; + } + return 2013; + } + return 2640; + } + return 3185; + } + return 3397; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'W')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 'S')) { + return 3354; + } + } + } + } + } + if ((1 < n) && (str[1] == 'h')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'k')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'A')) { + if ((7 < n) && (str[7] == 'd')) { + return 2494; + } + return 3035; + } + return 3504; + } + return 1793; + } + return 2402; + } + return 3404; + } + } + if ((1 < n) && (str[1] == 'k')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'A')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'd')) { + return 2540; + } + return 3005; + } + return 3532; + } + } + } + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '3')) { + if ((7 < n) && (str[7] == '2')) { + return 1334; + } + return 1668; + } + return 2065; + } + return 2693; + } + return 3421; + } + return 1324; + } + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'V')) { + return 1285; + } + return 1597; + } + return 2008; + } + return 2632; + } + return 3368; + } + } + if ((2 < n) && (str[2] == '4')) { + if ((3 < n) && (str[3] == 'f')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'S')) { + return 1299; + } + return 1628; + } + return 2032; + } + return 2652; + } + return 3382; + } + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'k')) { + if ((6 < n) && (str[6] == '4')) { + if ((7 < n) && (str[7] == 'f')) { + return 1297; + } + return 1618; + } + return 1971; + } + return 2421; + } + return 3277; + } + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'F')) { + return 1985; + } + return 1008; + } + return 1476; + } + return 2256; + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'y')) { + return 999; + } + return 1178; + } + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'I')) { + return 1186; + } + return 527; + } + return 330; + } + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 's')) { + return 905; + } + return 874; + } + return 996; + } + if ((5 < n) && (str[5] == 'M')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 's')) { + return 1222; + } + return 1494; + } + return 1865; + } + if ((5 < n) && (str[5] == 'T')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'p')) { + return 113; + } + return 143; + } + return 157; + } + if ((5 < n) && (str[5] == 'O')) { + if ((6 < n) && (str[6] == 'f')) { + return 1754; + } + return 2053; + } + return 18; + } + return 39; + } + return 84; + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'F')) { + return 730; + } + return 879; + } + return 1072; + } + return 1478; + } + return 2087; + } + return 3094; + } + } + if ((1 < n) && (str[1] == 'y')) { + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'h')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'k')) { + if ((7 < n) && (str[7] == 's')) { + return 466; + } + return 562; + } + return 698; + } + return 912; + } + return 1113; + } + return 1804; + } + } +} +if ((0 < n) && (str[0] == 'b')) { + if ((1 < n) && (str[1] == 'j')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 't')) { + return 1593; + } + return 2200; + } + return 3211; + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'c')) { + return 302; + } + return 354; + } + return 459; + } + return 597; + } + return 816; + } + return 1263; + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 231; + } + return 282; + } + return 338; + } + return 458; + } + return 615; + } + if ((3 < n) && (str[3] == 'F')) { + if ((4 < n) && (str[4] == 'W')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'S')) { + return 2986; + } + return 3526; + } + return 3282; + } + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'W')) { + return 1745; + } + return 2151; + } + return 2705; + } + return 3287; + } + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '2')) { + return 1743; + } + return 2144; + } + return 2696; + } + return 3283; + } + return 919; + } + if ((3 < n) && (str[3] == 's')) { + return 1389; + } + if ((3 < n) && (str[3] == 'S')) { + return 3128; + } + if ((3 < n) && (str[3] == 'w')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 'S')) { + return 2793; + } + return 3375; + } + } + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'e')) { + return 1344; + } + return 1589; + } + return 1997; + } + return 2621; + } + return 3357; + } + return 70; + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '0')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'k')) { + return 1295; + } + return 1625; + } + return 1920; + } + return 2558; + } + return 3306; + } + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'F')) { + return 1249; + } + return 796; + } + return 992; + } + return 1366; + } + return 1889; + } + return 2871; + } + } + if ((1 < n) && (str[1] == 'U')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 30; + } + return 50; + } + return 72; + } + return 105; + } + return 164; + } + return 265; + } + } +} +if ((0 < n) && (str[0] == 'e')) { + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 't')) { + return 120; + } + return 149; + } + return 203; + } + return 270; + } + return 363; + } + return 529; + } + } + if ((1 < n) && (str[1] == 'B')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'f')) { + if ((4 < n) && (str[4] == 'f')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + return 1404; + } + return 1723; + } + return 2228; + } + return 3076; + } + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'm')) { + if ((5 < n) && (str[5] == 'E')) { + if ((6 < n) && (str[6] == 'q')) { + if ((7 < n) && (str[7] == 'u')) { + return 2532; + } + return 3008; + } + return 3496; + } + return 2919; + } + } + } + if ((2 < n) && (str[2] == 'W')) { + return 3096; + } + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'W')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'S')) { + return 2481; + } + return 2995; + } + return 2282; + } + return 2942; + } + } + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '1')) { + return 2543; + } + return 3049; + } + return 3550; + } + } + } + return 2874; + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == 'M')) { + return 2530; + } + return 2994; + } + return 2699; + } + return 3220; + } + } + } + } + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + return 2288; + } + return 2891; + } + } + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'E')) { + if ((6 < n) && (str[6] == 'q')) { + if ((7 < n) && (str[7] == 'u')) { + return 2500; + } + return 3044; + } + return 3553; + } + return 3269; + } + } + return 2279; + } + } + if ((1 < n) && (str[1] == 'M')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 2320; + } + return 2847; + } + return 3353; + } + } + } + } + } + if ((1 < n) && (str[1] == 'L')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'c')) { + return 1194; + } + return 1516; + } + return 1907; + } + return 2415; + } + return 3194; + } + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'W')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'S')) { + return 3019; + } + return 3513; + } + } + return 2819; + } + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'e')) { + return 1102; + } + return 1399; + } + return 1776; + } + return 2281; + } + return 3125; + } + } + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '0')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'a')) { + return 1300; + } + return 1624; + } + return 2033; + } + return 2659; + } + return 3364; + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'F')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '_')) { + return 1059; + } + return 1395; + } + return 1833; + } + return 2446; + } + return 2469; + } + } + if ((1 < n) && (str[1] == 'R')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'e')) { + return 430; + } + return 539; + } + return 661; + } + return 869; + } + return 1183; + } + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'e')) { + return 1215; + } + return 1540; + } + return 1953; + } + return 2580; + } + return 3318; + } + return 985; + } + } + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == 'y')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'F')) { + if ((7 < n) && (str[7] == 'S')) { + return 1509; + } + return 1850; + } + return 1084; + } + return 416; + } + return 584; + } + return 903; + } + } + if ((1 < n) && (str[1] == 'W')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == '9')) { + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'e')) { + return 2300; + } + return 2823; + } + return 3345; + } + } + } + } + } + if ((1 < n) && (str[1] == 'V')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'i')) { + return 1794; + } + return 2114; + } + if ((6 < n) && (str[6] == 'W')) { + if ((7 < n) && (str[7] == '_')) { + return 2478; + } + return 2143; + } + return 631; + } + return 787; + } + return 1086; + } + return 1762; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '4')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'o')) { + return 1281; + } + return 1604; + } + return 2014; + } + return 2611; + } + return 3197; + } + } + } + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'l')) { + return 581; + } + return 715; + } + return 891; + } + return 717; + } + return 951; + } + return 1508; + } + } + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'k')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'A')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'e')) { + return 2515; + } + return 3054; + } + return 3530; + } + } + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '3')) { + return 1337; + } + return 1669; + } + return 2063; + } + return 2697; + } + return 840; + } + return 735; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'l')) { + return 419; + } + return 523; + } + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == '_')) { + return 723; + } + return 804; + } + if ((6 < n) && (str[6] == 'M')) { + if ((7 < n) && (str[7] == 'i')) { + return 1163; + } + return 1493; + } + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'y')) { + return 123; + } + return 129; + } + if ((6 < n) && (str[6] == 'O')) { + if ((7 < n) && (str[7] == 'f')) { + return 1428; + } + return 1660; + } + return 16; + } + return 24; + } + return 46; + } + return 68; + } + } + if ((1 < n) && (str[1] == 'd')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'g')) { + if ((7 < n) && (str[7] == 'e')) { + return 2093; + } + return 2466; + } + return 2821; + } + return 3426; + } + } + } + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '3')) { + if ((7 < n) && (str[7] == 'B')) { + return 2513; + } + return 3011; + } + return 3376; + } + } + } + } + } + if ((1 < n) && (str[1] == 'g')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'L')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'e')) { + return 1448; + } + return 1781; + } + return 2208; + } + return 2872; + } + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'e')) { + return 1984; + } + return 2332; + } + return 2923; + } + } + return 1418; + } + return 2180; + } + } + if ((1 < n) && (str[1] == 'f')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'd')) { + return 983; + } + return 1193; + } + return 1406; + } + return 1849; + } + return 2598; + } + } + } + if ((1 < n) && (str[1] == 'm')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '9')) { + return 1316; + } + return 1204; + } + return 307; + } + return 193; + } + return 267; + } + return 384; + } + } + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'y')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'h')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'c')) { + return 456; + } + return 566; + } + return 700; + } + return 913; + } + return 1257; + } + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'e')) { + return 245; + } + return 311; + } + return 369; + } + return 472; + } + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'W')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'S')) { + return 2318; + } + return 2840; + } + return 3349; + } + } + return 241; + } + return 192; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'r')) { + return 38; + } + return 40; + } + return 61; + } + return 89; + } + return 134; + } + return 230; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '9')) { + if ((6 < n) && (str[6] == 'E')) { + if ((7 < n) && (str[7] == 'q')) { + return 1317; + } + return 1645; + } + return 2044; + } + return 2104; + } + return 553; + } + return 335; + } + } + if ((1 < n) && (str[1] == 'q')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'S')) { + return 2605; + } + if ((7 < n) && (str[7] == 'T')) { + return 238; + } + if ((7 < n) && (str[7] == '_')) { + return 2072; + } + return 96; + } + return 92; + } + return 124; + } + return 188; + } + return 289; + } + } + if ((1 < n) && (str[1] == 'p')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'b')) { + return 445; + } + return 546; + } + return 604; + } + return 764; + } + return 1055; + } + return 1711; + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'c')) { + return 453; + } + return 560; + } + return 704; + } + return 916; + } + return 1254; + } + return 1977; + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'x')) { + return 1343; + } + return 1375; + } + return 1734; + } + return 2251; + } + return 2903; + } + return 1143; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == '1')) { + return 773; + } + if ((3 < n) && (str[3] == '9')) { + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 't')) { + return 1761; + } + return 2158; + } + return 2717; + } + return 3301; + } + } + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'e')) { + return 1755; + } + return 2124; + } + return 2670; + } + return 3263; + } + } + if ((3 < n) && (str[3] == '2')) { + return 1369; + } + if ((3 < n) && (str[3] == '3')) { + return 3361; + } + return 158; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 's')) { + return 917; + } + return 977; + } + return 1242; + } + return 1016; + } + return 1018; + } + if ((3 < n) && (str[3] == 'G')) { + return 2796; + } + return 713; + } + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '_')) { + return 3055; + } + } + if ((4 < n) && (str[4] == '0')) { + if ((5 < n) && (str[5] == '_')) { + return 1029; + } + return 1411; + } + return 777; + } + return 1165; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'S')) { + return 957; + } + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'y')) { + return 1111; + } + return 1420; + } + if ((6 < n) && (str[6] == '7')) { + if ((7 < n) && (str[7] == 'E')) { + return 176; + } + return 211; + } + return 85; + } + return 94; + } + return 121; + } + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'v')) { + return 1616; + } + return 1934; + } + return 2380; + } + return 3113; + } + return 2185; + } + return 153; + } + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '1')) { + return 3414; + } + return 2470; + } + return 2343; + } + return 2606; + } + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'y')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '_')) { + return 1532; + } + return 1462; + } + return 970; + } + return 1312; + } + return 1830; + } + return 2591; + } + if ((2 < n) && (str[2] == 'L')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 1359; + } + return 1694; + } + return 2106; + } + return 2737; + } + return 3444; + } + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 1933; + } + return 1262; + } + return 1530; + } + return 2047; + } + return 2468; + } + return 2869; + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '6')) { + return 2545; + } + return 2988; + } + return 3498; + } + } + } + return 2117; + } + } + if ((1 < n) && (str[1] == 'w')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == '5')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'e')) { + return 2056; + } + return 2405; + } + return 3061; + } + } + } + return 2210; + } + } + if ((1 < n) && (str[1] == 'x')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + return 3058; + } + return 1957; + } + return 2564; + } + return 3313; + } + } + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'n')) { + return 2241; + } + return 2755; + } + return 3250; + } + } + } + } + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'y')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '_')) { + return 2748; + } + return 1892; + } + if ((6 < n) && (str[6] == 'r')) { + return 3298; + } + return 494; + } + return 628; + } + return 894; + } + return 1374; + } + if ((2 < n) && (str[2] == '_')) { + return 2206; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'V')) { + return 727; + } + return 880; + } + return 1073; + } + return 1480; + } + return 2092; + } + return 2730; + } + } +} +if ((0 < n) && (str[0] == 'd')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'n')) { + return 1553; + } + return 1869; + } + return 2628; + } + return 3291; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 2565; + } + return 1554; + } + return 1929; + } + return 2563; + } + return 3267; + } + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'G')) { + if ((7 < n) && (str[7] == 'e')) { + return 2238; + } + return 2757; + } + return 3246; + } + } + } + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '2')) { + return 3234; + } + return 3083; + } + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 1567; + } + if ((7 < n) && (str[7] == 'r')) { + return 2848; + } + return 383; + } + return 492; + } + return 629; + } + return 871; + } + return 150; + } + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '3')) { + return 2477; + } + return 3013; + } + return 3529; + } + } + } + } + } + if ((1 < n) && (str[1] == 'd')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '_')) { + return 2511; + } + return 3033; + } + return 3510; + } + } + } + } + } + if ((1 < n) && (str[1] == 'G')) { + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '3')) { + if ((6 < n) && (str[6] == 'B')) { + if ((7 < n) && (str[7] == 'o')) { + return 2499; + } + return 3010; + } + return 3515; + } + } + } + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'w')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'd')) { + return 2264; + } + return 2781; + } + return 3304; + } + } + } + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'o')) { + return 418; + } + return 524; + } + return 643; + } + return 848; + } + return 1147; + } + return 1854; + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'U')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 't')) { + return 33; + } + return 48; + } + return 74; + } + return 109; + } + return 155; + } + return 253; + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + return 2259; + } + return 2920; + } + } + } + if ((2 < n) && (str[2] == 'm')) { + if ((3 < n) && (str[3] == 'A')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 408; + } + return 515; + } + return 637; + } + return 829; + } + return 1129; + } + return 1815; + } + } + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'y')) { + return 1053; + } + return 1352; + } + return 849; + } + return 1005; + } + return 1470; + } + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 2091; + } + return 2463; + } + return 3098; + } + return 3425; + } + } + return 1239; + } + } + if ((1 < n) && (str[1] == 'R')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'e')) { + return 2943; + } + } + return 2590; + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == '_')) { + return 1349; + } + } +} +if ((0 < n) && (str[0] == 'g')) { + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'L')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 1445; + } + return 1782; + } + return 2207; + } + return 2873; + } + } + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 2602; + } + return 2357; + } + return 2926; + } + } + } + return 2088; + } + if ((2 < n) && (str[2] == 'R')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'c')) { + return 444; + } + return 549; + } + return 676; + } + return 899; + } + return 1211; + } + return 1932; + } + } + if ((1 < n) && (str[1] == 'G')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 't')) { + return 2083; + } + return 2430; + } + return 3089; + } + } + } + } + } + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'e')) { + return 2095; + } + return 2464; + } + return 3099; + } + } + } + } + } + if ((1 < n) && (str[1] == '5')) { + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 's')) { + return 2722; + } + return 2372; + } + } + if ((1 < n) && (str[1] == '9')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'r')) { + return 2721; + } + return 3163; + } + } + } + } + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'A')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'r')) { + return 398; + } + return 497; + } + return 612; + } + return 761; + } + return 1047; + } + return 1709; + } + } +} +if ((0 < n) && (str[0] == 'f')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'd')) { + return 1196; + } + return 1572; + } + return 1848; + } + return 2599; + } + } + } + if ((1 < n) && (str[1] == 'B')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 's')) { + return 1786; + } + return 2212; + } + return 2881; + } + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'e')) { + return 3161; + } + } + } + } + return 415; + } + } + if ((1 < n) && (str[1] == 'f')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'i')) { + return 1766; + } + return 2178; + } + return 2799; + } + } + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'e')) { + return 2719; + } + return 3153; + } + } + } + if ((4 < n) && (str[4] == 'g')) { + return 3453; + } + return 300; + } + return 432; + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '4')) { + if ((7 < n) && (str[7] == 'l')) { + return 1101; + } + return 1397; + } + return 1777; + } + return 2181; + } + return 2850; + } + return 3365; + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 't')) { + return 2917; + } + } + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'i')) { + return 2201; + } + return 2814; + } + } + } + } + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == '_')) { + return 1967; + } + } + if ((1 < n) && (str[1] == 'E')) { + if ((2 < n) && (str[2] == 'q')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'b')) { + return 2122; + } + return 2584; + } + return 3127; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'i')) { + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'e')) { + return 2110; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'r')) { + return 968; + } + return 1177; + } + return 1557; + } + return 2067; + } + return 2810; + } + return 3245; + } + } + if ((1 < n) && (str[1] == 'b')) { + if ((2 < n) && (str[2] == 'U')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'e')) { + return 28; + } + return 52; + } + return 77; + } + return 108; + } + return 163; + } + return 266; + } + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 's')) { + return 3564; + } + return 2879; + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'w')) { + return 3334; + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'h')) { + if ((7 < n) && (str[7] == 'e')) { + return 452; + } + return 563; + } + return 703; + } + return 914; + } + return 1258; + } + return 1987; + } + } + if ((1 < n) && (str[1] == 'd')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'i')) { + return 417; + } + return 526; + } + return 647; + } + return 853; + } + return 1152; + } + return 1855; + } + } + if ((1 < n) && (str[1] == 'g')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'A')) { + if ((7 < n) && (str[7] == 'r')) { + return 397; + } + return 498; + } + return 586; + } + return 758; + } + return 1045; + } + return 1695; + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'I')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 't')) { + return 2094; + } + return 2465; + } + return 3095; + } + return 3146; + } + } + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'R')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 1214; + } + return 1542; + } + return 1946; + } + return 2576; + } + return 3328; + } + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'e')) { + return 2262; + } + return 2356; + } + return 3093; + } + } + } + } + if ((1 < n) && (str[1] == 'm')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'E')) { + if ((5 < n) && (str[5] == 'q')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'a')) { + return 2294; + } + return 2826; + } + return 3344; + } + } + return 937; + } + return 1245; + } + if ((2 < n) && (str[2] == 'd')) { + return 2609; + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'C')) { + return 457; + } + return 567; + } + return 699; + } + return 915; + } + return 1259; + } + return 1986; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '4')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'i')) { + return 1100; + } + return 1400; + } + return 1778; + } + return 2268; + } + return 2928; + } + return 3464; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'I')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 't')) { + return 2246; + } + return 2762; + } + return 3254; + } + return 3465; + } + } + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'y')) { + return 1652; + } + return 2066; + } + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'I')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'd')) { + return 1185; + } + return 1506; + } + return 1900; + } + return 724; + } + return 552; + } + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '1')) { + return 1795; + } + return 1414; + } + return 1461; + } + return 1862; + } + if ((3 < n) && (str[3] == 'M')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 's')) { + return 1219; + } + return 1543; + } + return 1945; + } + return 2395; + } + return 3230; + } + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'S')) { + return 2791; + } + if ((7 < n) && (str[7] == 's')) { + return 1014; + } + if ((7 < n) && (str[7] == 'w')) { + return 2314; + } + if ((7 < n) && (str[7] == '_')) { + return 1236; + } + return 146; + } + return 195; + } + return 260; + } + return 317; + } + if ((3 < n) && (str[3] == 'O')) { + if ((4 < n) && (str[4] == 'f')) { + return 2843; + } + return 3158; + } + return 62; + } + } + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'm')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'E')) { + if ((7 < n) && (str[7] == 'q')) { + return 2303; + } + return 2828; + } + return 534; + } + return 688; + } + return 876; + } + return 978; + } + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'g')) { + if ((7 < n) && (str[7] == 'e')) { + return 2243; + } + return 2753; + } + return 3257; + } + } + } + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'T')) { + return 3077; + } + return 3136; + } + return 2076; + } + return 2785; + } + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'r')) { + return 2283; + } + return 2708; + } + return 2371; + } + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 2084; + } + return 2431; + } + return 3088; + } + } + } + return 784; + } + } + if ((1 < n) && (str[1] == 'p')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'F')) { + return 3352; + } + return 2257; + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'S')) { + return 1090; + } + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '1')) { + return 2442; + } + return 1741; + } + return 596; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'r')) { + return 1003; + } + return 954; + } + return 1520; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'n')) { + return 420; + } + return 528; + } + return 645; + } + return 846; + } + return 1144; + } + return 1796; + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'o')) { + return 1615; + } + return 1931; + } + return 1133; + } + return 1527; + } + return 2167; + } + return 1602; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '1')) { + return 2720; + } + return 333; + } + if ((6 < n) && (str[6] == '9')) { + if ((7 < n) && (str[7] == 'T')) { + return 1760; + } + return 1825; + } + if ((6 < n) && (str[6] == '3')) { + return 1592; + } + if ((6 < n) && (str[6] == '2')) { + return 582; + } + if ((6 < n) && (str[6] == '4')) { + return 2292; + } + return 73; + } + return 102; + } + return 161; + } + return 264; + } + } + if ((1 < n) && (str[1] == 'v')) { + if ((2 < n) && (str[2] == 'e')) { + return 2112; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == '_')) { + return 3233; + } + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'S')) { + return 2667; + } + return 2417; + } + } +} +if ((0 < n) && (str[0] == 'h')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 1703; + } + return 1974; + } + return 2403; + } + return 3138; + } + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'k')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'A')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'd')) { + return 2474; + } + return 3041; + } + return 3495; + } + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '_')) { + return 1333; + } + return 1667; + } + return 2057; + } + return 608; + } + return 484; + } + return 736; + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'w')) { + if ((3 < n) && (str[3] == 'F')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'm')) { + if ((7 < n) && (str[7] == 'e')) { + return 1306; + } + return 1631; + } + return 2029; + } + return 2650; + } + return 3380; + } + } + } +} +if ((0 < n) && (str[0] == 'k')) { + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'A')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'G')) { + return 2495; + } + return 3037; + } + return 3546; + } + } + } + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '3')) { + if ((6 < n) && (str[6] == '2')) { + if ((7 < n) && (str[7] == 'C')) { + return 1336; + } + return 1672; + } + return 2062; + } + return 2702; + } + return 3418; + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'c')) { + return 861; + } + return 1020; + } + return 1354; + } + return 1772; + } + return 2394; + } + return 3437; + } + } + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'S')) { + return 1277; + } + return 1607; + } + return 2006; + } + return 2631; + } + return 3366; + } + } + } + if ((1 < n) && (str[1] == '4')) { + if ((2 < n) && (str[2] == 'f')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'S')) { + return 1296; + } + return 1627; + } + return 2028; + } + return 2665; + } + return 3387; + } + } + } +} +if ((0 < n) && (str[0] == 'j')) { + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 't')) { + return 2184; + } + return 3181; + } + } +} +if ((0 < n) && (str[0] == 'm')) { + if ((1 < n) && (str[1] == 'A')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'I')) { + return 1067; + } + return 516; + } + return 638; + } + return 826; + } + return 1126; + } + return 1826; + } + } + if ((1 < n) && (str[1] == 'p')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 690; + } + return 832; + } + return 1022; + } + return 1403; + } + return 1490; + } + return 2229; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '0')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 't')) { + return 1308; + } + return 1626; + } + return 2023; + } + return 2663; + } + return 3393; + } + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '9')) { + if ((7 < n) && (str[7] == 'E')) { + return 1314; + } + return 1646; + } + return 1581; + } + return 385; + } + return 271; + } + return 386; + } + } + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'k')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'l')) { + return 862; + } + return 1021; + } + return 1353; + } + return 1771; + } + return 1930; + } + return 2912; + } + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'E')) { + if ((4 < n) && (str[4] == 'q')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 't')) { + return 2301; + } + return 2824; + } + return 3343; + } + } + } + return 1237; + } + } + if ((1 < n) && (str[1] == 'E')) { + if ((2 < n) && (str[2] == 'q')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'b')) { + return 2491; + } + return 2977; + } + return 3524; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'l')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 442; + } + return 545; + } + return 673; + } + return 900; + } + return 906; + } + return 1415; + } + } + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'v')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 't')) { + return 1613; + } + return 1936; + } + return 2382; + } + return 3118; + } + } + return 2601; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'x')) { + return 664; + } + if ((7 < n) && (str[7] == 'M')) { + return 1164; + } + if ((7 < n) && (str[7] == 'T')) { + return 99; + } + if ((7 < n) && (str[7] == 'O')) { + return 1327; + } + return 17; + } + return 19; + } + return 42; + } + return 82; + } + return 132; + } + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'W')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + return 3523; + } + } + } + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'W')) { + if ((7 < n) && (str[7] == '_')) { + return 2534; + } + return 2145; + } + return 2695; + } + return 3284; + } + } + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == '2')) { + if ((7 < n) && (str[7] == '1')) { + return 2482; + } + return 2146; + } + return 2704; + } + return 3281; + } + } + return 1250; + } + if ((2 < n) && (str[2] == 's')) { + return 2086; + } + if ((2 < n) && (str[2] == 'm')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 's')) { + return 989; + } + return 239; + } + return 148; + } + return 201; + } + return 286; + } + return 424; + } + if ((2 < n) && (str[2] == 'C')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'c')) { + return 232; + } + return 283; + } + return 339; + } + return 464; + } + return 626; + } + return 933; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '4')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'n')) { + return 1103; + } + return 1396; + } + return 1779; + } + return 2280; + } + return 3117; + } + return 1716; + } + if ((2 < n) && (str[2] == 'w')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 'S')) { + return 3402; + } + } + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'W')) { + return 1749; + } + return 1681; + } + return 1999; + } + return 2620; + } + return 3356; + } + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'e')) { + return 1383; + } + return 1898; + } + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'U')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 't')) { + return 31; + } + return 51; + } + return 75; + } + return 107; + } + return 165; + } + return 254; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'h')) { + return 454; + } + return 565; + } + return 697; + } + return 910; + } + return 1253; + } + return 1988; + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'T')) { + return 2592; + } + return 2594; + } + return 1569; + } + return 2048; + } + return 2779; + } + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'n')) { + return 10; + } + return 11; + } + return 21; + } + return 43; + } + return 87; + } + return 137; + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 't')) { + return 2127; + } + return 3078; + } + } + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'y')) { + return 1902; + } + return 2287; + } + return 1880; + } + return 2189; + } + return 2946; + } + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'E')) { + return 2510; + } + return 2132; + } + return 2676; + } + return 3268; + } + } + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'W')) { + if ((7 < n) && (str[7] == 'x')) { + return 2490; + } + return 2992; + } + return 2790; + } + return 3316; + } + return 3360; + } + if ((3 < n) && (str[3] == 'W')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + return 3514; + } + } + } + if ((3 < n) && (str[3] == 'F')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'm')) { + if ((7 < n) && (str[7] == 'E')) { + return 2508; + } + return 2142; + } + return 2700; + } + return 3286; + } + if ((4 < n) && (str[4] == 'W')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'S')) { + return 3014; + } + return 3525; + } + } + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '_')) { + return 2492; + } + return 3016; + } + return 3506; + } + } + return 961; + } + return 399; + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'e')) { + return 2247; + } + return 2750; + } + return 3251; + } + } + } + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'd')) { + return 2837; + } + return 2776; + } + } + if ((1 < n) && (str[1] == 'E')) { + if ((2 < n) && (str[2] == 'q')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'b')) { + return 2296; + } + return 2832; + } + return 3346; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'o')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 't')) { + return 3130; + } + } + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'k')) { + if ((7 < n) && (str[7] == '4')) { + return 1288; + } + return 1568; + } + return 1905; + } + return 2423; + } + return 3279; + } + } + } + if ((1 < n) && (str[1] == 'E')) { + if ((2 < n) && (str[2] == 'q')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'b')) { + return 2487; + } + return 3023; + } + return 3521; + } + } + } + } + } + if ((1 < n) && (str[1] == 'g')) { + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'g')) { + return 3189; + } + } + } + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + return 1820; + } + return 2176; + } + return 2391; + } + return 3193; + } + } + if ((1 < n) && (str[1] == 'm')) { + if ((2 < n) && (str[2] == 'A')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 's')) { + return 410; + } + return 517; + } + return 635; + } + return 825; + } + return 1128; + } + return 1818; + } + if ((2 < n) && (str[2] == 'p')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == 'l')) { + return 683; + } + return 831; + } + return 1024; + } + return 1015; + } + return 1463; + } + return 2197; + } + if ((2 < n) && (str[2] == 'E')) { + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'a')) { + return 2542; + } + return 3028; + } + return 3516; + } + } + } + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'o')) { + return 8; + } + return 12; + } + return 22; + } + return 44; + } + return 86; + } + return 138; + } + } + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'y')) { + return 2129; + } + return 2812; + } + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'e')) { + return 1184; + } + return 1502; + } + return 1895; + } + return 2414; + } + return 971; + } + return 811; + } + if ((2 < n) && (str[2] == 'M')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'e')) { + return 1220; + } + return 1547; + } + return 1950; + } + return 2571; + } + return 3229; + } + } + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'y')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'S')) { + return 3228; + } + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '_')) { + return 2806; + } + return 1271; + } + if ((6 < n) && (str[6] == 'w')) { + return 2839; + } + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'S')) { + return 1489; + } + return 1563; + } + return 199; + } + return 257; + } + return 352; + } + return 479; + } + if ((2 < n) && (str[2] == 'v')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'b')) { + return 963; + } + return 1161; + } + return 1472; + } + return 1915; + } + return 2715; + } + } + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '1')) { + return 2216; + } + return 1851; + } + return 2073; + } + return 2845; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'u')) { + return 375; + } + return 474; + } + return 585; + } + return 757; + } + return 1044; + } + return 1360; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'g')) { + if ((4 < n) && (str[4] == 'e')) { + return 2322; + } + return 2444; + } + return 3300; + } + if ((2 < n) && (str[2] == 'S')) { + return 2333; + } + if ((2 < n) && (str[2] == 'w')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'I')) { + if ((7 < n) && (str[7] == 'n')) { + return 650; + } + return 781; + } + return 448; + } + return 589; + } + return 809; + } + return 1209; + } + if ((2 < n) && (str[2] == '7')) { + if ((3 < n) && (str[3] == 'E')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'm')) { + if ((7 < n) && (str[7] == 'e')) { + return 177; + } + return 215; + } + return 276; + } + return 343; + } + return 501; + } + return 749; + } + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'y')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '_')) { + return 2811; + } + return 1975; + } + return 754; + } + return 974; + } + return 1419; + } + return 2182; + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'A')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'y')) { + return 403; + } + return 495; + } + return 613; + } + return 799; + } + return 1107; + } + return 1702; + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'L')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'c')) { + return 1137; + } + return 1424; + } + return 1806; + } + return 2305; + } + return 3150; + } + } + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + return 2907; + } + } + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'O')) { + if ((4 < n) && (str[4] == 'f')) { + if ((5 < n) && (str[5] == 'B')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'u')) { + return 1450; + } + return 1790; + } + return 2215; + } + return 2883; + } + } + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'o')) { + return 923; + } + return 1094; + } + return 1440; + } + return 1871; + } + if ((4 < n) && (str[4] == 's')) { + return 2005; + } + return 845; + } + if ((3 < n) && (str[3] == 't')) { + return 3122; + } + return 765; + } + } + if ((1 < n) && (str[1] == 'w')) { + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'm')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'S')) { + return 1289; + } + return 1638; + } + return 2035; + } + return 2651; + } + return 3384; + } + } + } + if ((1 < n) && (str[1] == 'x')) { + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '3')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'e')) { + return 2456; + } + return 2972; + } + return 3478; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'n')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'y')) { + return 2876; + } + } + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'x')) { + return 1429; + } + return 1507; + } + return 1896; + } + return 2416; + } + return 3266; + } + return 1539; + } + } + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'y')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'h')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'k')) { + return 455; + } + return 559; + } + return 701; + } + return 911; + } + return 1260; + } + return 1992; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 733; + } + return 312; + } + return 368; + } + return 506; + } + return 606; + } + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'W')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'S')) { + return 2846; + } + return 3348; + } + } + return 3312; + } + return 293; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'u')) { + return 2833; + } + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'S')) { + return 803; + } + if ((7 < n) && (str[7] == 'T')) { + return 1123; + } + if ((7 < n) && (str[7] == '7')) { + return 172; + } + return 60; + } + return 63; + } + return 90; + } + return 136; + } + return 208; + } + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'g')) { + return 2090; + } + return 2461; + } + return 3097; + } + } + } + } + } + if ((1 < n) && (str[1] == 'd')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'n')) { + return 1180; + } + return 1441; + } + return 1873; + } + return 2646; + } + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 1228; + } + return 1535; + } + return 1928; + } + return 2413; + } + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'g')) { + if ((7 < n) && (str[7] == 'G')) { + return 2239; + } + return 2751; + } + return 3247; + } + } + if ((4 < n) && (str[4] == 'O')) { + if ((5 < n) && (str[5] == 'f')) { + return 3424; + } + } + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == '2')) { + return 2635; + } + return 2248; + } + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'e')) { + return 323; + } + return 378; + } + return 491; + } + return 621; + } + if ((4 < n) && (str[4] == 'w')) { + if ((5 < n) && (str[5] == 'x')) { + return 2941; + } + } + if ((4 < n) && (str[4] == '_')) { + return 2938; + } + return 91; + } + return 122; + } + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'm')) { + if ((4 < n) && (str[4] == 'A')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'e')) { + return 409; + } + return 520; + } + return 632; + } + return 824; + } + return 1131; + } + return 1810; + } + } + if ((1 < n) && (str[1] == 'g')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'R')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'a')) { + return 439; + } + return 543; + } + return 670; + } + return 896; + } + return 1210; + } + return 667; + } + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 2085; + } + return 2429; + } + return 3091; + } + } + } + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'm')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'E')) { + if ((6 < n) && (str[6] == 'q')) { + if ((7 < n) && (str[7] == 'u')) { + return 2304; + } + return 2831; + } + return 3342; + } + return 689; + } + return 942; + } + return 1363; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == '1')) { + return 287; + } + if ((7 < n) && (str[7] == '9')) { + return 1492; + } + if ((7 < n) && (str[7] == '3')) { + return 1270; + } + if ((7 < n) && (str[7] == '2')) { + return 485; + } + if ((7 < n) && (str[7] == '4')) { + return 1911; + } + return 49; + } + return 71; + } + return 110; + } + return 167; + } + return 234; + } + } + if ((1 < n) && (str[1] == 'M')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'R')) { + return 1225; + } + return 1545; + } + return 1941; + } + return 2578; + } + return 3324; + } + } + } + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 2236; + } + return 2752; + } + return 3260; + } + } + } + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'g')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 's')) { + return 374; + } + return 475; + } + return 588; + } + return 760; + } + return 1049; + } + return 1412; + } + if ((2 < n) && (str[2] == '3')) { + if ((3 < n) && (str[3] == '2')) { + return 3432; + } + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'r')) { + return 2336; + } + if ((3 < n) && (str[3] == 'g')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'L')) { + if ((7 < n) && (str[7] == 'i')) { + return 1446; + } + return 1780; + } + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'y')) { + return 1965; + } + return 2335; + } + return 750; + } + return 973; + } + return 1416; + } + return 841; + } + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'E')) { + if ((4 < n) && (str[4] == 'q')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 't')) { + return 2507; + } + return 3022; + } + return 3538; + } + } + } + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '9')) { + if ((5 < n) && (str[5] == 'E')) { + if ((6 < n) && (str[6] == 'q')) { + if ((7 < n) && (str[7] == 'u')) { + return 1313; + } + return 1642; + } + return 2042; + } + return 2668; + } + return 2853; + } + return 814; + } + } + if ((1 < n) && (str[1] == 'v')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == 'l')) { + return 965; + } + return 1160; + } + return 1531; + } + return 1925; + } + return 2674; + } + } + } + if ((1 < n) && (str[1] == 'y')) { + if ((2 < n) && (str[2] == 'O')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'j')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 't')) { + return 2808; + } + return 3237; + } + } + } + } + } + } + if ((1 < n) && (str[1] == 'x')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '1')) { + return 2885; + } + return 2604; + } + return 3072; + } + } + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == 'y')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '_')) { + return 3240; + } + return 1686; + } + if ((5 < n) && (str[5] == 'w')) { + return 3350; + } + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'S')) { + return 1822; + } + return 1959; + } + return 258; + } + return 346; + } + return 554; + } + } +} +if ((0 < n) && (str[0] == 'q')) { + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 131; + } + return 170; + } + return 224; + } + return 296; + } + return 391; + } + return 537; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'e')) { + return 1678; + } + return 1885; + } + return 2327; + } + return 3065; + } + } + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'S')) { + return 3092; + } + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'y')) { + return 243; + } + return 299; + } + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'W')) { + return 2313; + } + return 2410; + } + return 126; + } + return 125; + } + return 190; + } + return 229; + } + } + if ((1 < n) && (str[1] == 'd')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == '_')) { + return 2291; + } + return 3175; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == '2')) { + if ((4 < n) && (str[4] == 'w')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'p')) { + return 2546; + } + return 3003; + } + return 3554; + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'p')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'q')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'l')) { + return 1560; + } + return 1881; + } + return 2325; + } + return 2683; + } + return 3415; + } + } + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'y')) { + return 3290; + } + } + } + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + return 836; + } + return 1023; + } + return 1402; + } + return 1684; + } + return 1879; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'W')) { + if ((3 < n) && (str[3] == 'x')) { + if ((4 < n) && (str[4] == '9')) { + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'n')) { + return 2434; + } + return 2958; + } + return 3469; + } + } + } + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'i')) { + return 889; + } + return 1050; + } + return 1207; + } + return 1035; + } + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'S')) { + return 3305; + } + return 2051; + } + return 607; + } + if ((3 < n) && (str[3] == 'F')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '_')) { + return 2939; + } + return 3448; + } + if ((5 < n) && (str[5] == '0')) { + if ((6 < n) && (str[6] == '_')) { + return 1118; + } + return 1471; + } + return 769; + } + return 1057; + } + return 387; + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'V')) { + return 3106; + } + } + return 1824; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'F')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '_')) { + return 1155; + } + return 1488; + } + return 1859; + } + return 2355; + } + return 2960; + } + return 2634; + } + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '_')) { + return 3549; + } + } + return 2673; + } + return 1769; + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == 'l')) { + return 443; + } + return 548; + } + return 672; + } + return 770; + } + return 1056; + } + return 1687; + } + } + if ((1 < n) && (str[1] == 'V')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'I')) { + if ((7 < n) && (str[7] == 'n')) { + return 1751; + } + return 2141; + } + if ((6 < n) && (str[6] == 'F')) { + if ((7 < n) && (str[7] == 'G')) { + return 2549; + } + return 3043; + } + return 1076; + } + return 1485; + } + return 2098; + } + return 3105; + } + } +} +if ((0 < n) && (str[0] == 's')) { + if ((1 < n) && (str[1] == 'A')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'B')) { + if ((7 < n) && (str[7] == 'u')) { + return 658; + } + return 794; + } + return 618; + } + return 790; + } + return 1097; + } + return 1768; + } + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'G')) { + if ((7 < n) && (str[7] == 'C')) { + return 2480; + } + return 3048; + } + return 3539; + } + } + } + } + } + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'p')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'F')) { + return 1577; + } + return 779; + } + return 1007; + } + return 1477; + } + return 2255; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'R')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'i')) { + return 1226; + } + return 1550; + } + return 1947; + } + return 2569; + } + return 3317; + } + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'i')) { + return 2857; + } + } + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '_')) { + return 3563; + } + } + if ((3 < n) && (str[3] == '0')) { + if ((4 < n) && (str[4] == '_')) { + return 1384; + } + return 1916; + } + return 1010; + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'm')) { + if ((3 < n) && (str[3] == 'd')) { + return 1712; + } + return 2608; + } + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'y')) { + return 451; + } + return 561; + } + return 705; + } + return 908; + } + return 1256; + } + return 1991; + } + } + if ((1 < n) && (str[1] == 'h')) { + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'w')) { + if ((4 < n) && (str[4] == 'F')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'm')) { + return 1304; + } + return 1635; + } + return 2030; + } + return 2658; + } + return 3390; + } + } + } + if ((1 < n) && (str[1] == 'V')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '3')) { + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'o')) { + return 1331; + } + return 1673; + } + return 2061; + } + return 2649; + } + return 3388; + } + } + } + if ((1 < n) && (str[1] == '3')) { + if ((2 < n) && (str[2] == '0')) { + if ((3 < n) && (str[3] == 'R')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'g')) { + if ((7 < n) && (str[7] == 'e')) { + return 2138; + } + return 2596; + } + return 3132; + } + } + } + } + if ((2 < n) && (str[2] == '3')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'B')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'l')) { + return 2344; + } + return 2878; + } + return 3386; + } + } + } + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '_')) { + return 2449; + } + return 2955; + } + return 3467; + } + return 3427; + } + } + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '0')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'm')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'a')) { + return 2272; + } + return 2789; + } + return 3309; + } + } + } + return 2396; + } + if ((2 < n) && (str[2] == '3')) { + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'r')) { + return 1142; + } + return 1465; + } + return 1847; + } + return 2368; + } + return 3209; + } + return 2947; + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'q')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'e')) { + return 250; + } + return 318; + } + return 381; + } + return 510; + } + return 642; + } + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'A')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 776; + } + return 939; + } + return 1172; + } + return 1659; + } + return 1122; + } + return 401; + } + if ((2 < n) && (str[2] == '4')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 248; + } + return 315; + } + return 373; + } + return 512; + } + return 654; + } + return 668; + } + if ((2 < n) && (str[2] == '7')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'x')) { + return 2244; + } + return 2760; + } + return 3252; + } + } + } + return 2767; + } + if ((2 < n) && (str[2] == '6')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'A')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 2352; + } + return 2893; + } + return 3407; + } + } + } + if ((3 < n) && (str[3] == 'F')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'w')) { + if ((7 < n) && (str[7] == 'a')) { + return 1065; + } + return 1372; + } + return 1730; + } + return 2231; + } + return 2818; + } + return 1025; + } + if ((2 < n) && (str[2] == '8')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'g')) { + if ((7 < n) && (str[7] == 'n')) { + return 2358; + } + return 2901; + } + return 3409; + } + } + return 2914; + } + return 3429; + } + } + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'y')) { + return 2389; + } + return 2921; + } + return 997; + } + return 1169; + } + return 1721; + } + return 2567; + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'T')) { + return 2388; + } + return 1679; + } + return 1732; + } + return 2252; + } + return 3082; + } + } + } + if ((1 < n) && (str[1] == '2')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == 'R')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'o')) { + return 2450; + } + return 2962; + } + return 3483; + } + } + } + return 2373; + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == 'B')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'r')) { + return 2348; + } + return 2886; + } + return 3399; + } + } + } + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 't')) { + return 680; + } + return 820; + } + return 967; + } + return 1248; + } + return 1213; + } + return 901; + } + } + if ((1 < n) && (str[1] == 'u')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'R')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'i')) { + return 1224; + } + return 1551; + } + return 1943; + } + return 2577; + } + return 3322; + } + } + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'p')) { + return 1182; + } + return 1505; + } + return 1897; + } + return 2412; + } + return 3203; + } + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == '1')) { + return 1171; + } + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'k')) { + if ((5 < n) && (str[5] == 'T')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 1283; + } + return 1606; + } + return 2015; + } + return 2638; + } + return 3371; + } + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'e')) { + return 2802; + } + return 3060; + } + } + return 1650; + } + if ((2 < n) && (str[2] == '2')) { + return 2121; + } + if ((2 < n) && (str[2] == '9')) { + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'S')) { + return 1758; + } + return 2159; + } + return 2714; + } + return 3303; + } + } + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'e')) { + return 2154; + } + return 2672; + } + return 3261; + } + } + } + } + if ((1 < n) && (str[1] == '6')) { + if ((2 < n) && (str[2] == 'U')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 't')) { + return 1148; + } + return 1596; + } + return 2204; + } + return 3217; + } + } + if ((1 < n) && (str[1] == '9')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'a')) { + return 1683; + } + return 2001; + } + return 2419; + } + return 3168; + } + } + } + if ((2 < n) && (str[2] == 'A')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'O')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == 'j')) { + return 2842; + } + return 3293; + } + } + } + } + } + if ((2 < n) && (str[2] == 'E')) { + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'a')) { + return 686; + } + return 834; + } + return 1026; + } + return 1408; + } + return 1973; + } + return 2349; + } + } + if ((1 < n) && (str[1] == '5')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 't')) { + return 1649; + } + return 2219; + } + return 3227; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'e')) { + return 3299; + } + } + } + } + } + if ((2 < n) && (str[2] == 'R')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'g')) { + if ((6 < n) && (str[6] == 'e')) { + return 1840; + } + return 2202; + } + return 2864; + } + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'S')) { + return 763; + } + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '1')) { + return 2324; + } + return 1082; + } + return 405; + } + return 551; + } + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'S')) { + return 2860; + } + return 1996; + } + return 1918; + } + return 436; + } + return 471; + } + if ((2 < n) && (str[2] == 'G')) { + return 3145; + } + } +} +if ((0 < n) && (str[0] == 'r')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '1')) { + return 1280; + } + return 1611; + } + return 2017; + } + return 2641; + } + return 3308; + } + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + return 2589; + } + return 3141; + } + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'u')) { + return 732; + } + return 881; + } + return 1081; + } + return 1484; + } + return 966; + } + return 797; + } + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + return 1407; + } + return 1968; + } + return 2929; + } + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == 'e')) { + return 3172; + } + return 3461; + } + if ((2 < n) && (str[2] == 'm')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '0')) { + return 1294; + } + return 1622; + } + return 2036; + } + return 2661; + } + return 3395; + } + } + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'C')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'v')) { + if ((7 < n) && (str[7] == 'e')) { + return 1617; + } + return 1937; + } + return 2381; + } + return 3121; + } + } + return 3187; + } + if ((2 < n) && (str[2] == 'p')) { + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'e')) { + return 728; + } + return 884; + } + return 1075; + } + return 1486; + } + return 2099; + } + return 1697; + } + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'S')) { + return 1136; + } + if ((5 < n) && (str[5] == 'T')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'p')) { + return 1110; + } + return 1421; + } + return 1802; + } + if ((5 < n) && (str[5] == '7')) { + if ((6 < n) && (str[6] == 'E')) { + if ((7 < n) && (str[7] == 'l')) { + return 175; + } + return 214; + } + return 273; + } + return 100; + } + return 135; + } + return 202; + } + if ((2 < n) && (str[2] == 'y')) { + if ((3 < n) && (str[3] == 'B')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'f')) { + if ((6 < n) && (str[6] == 'f')) { + if ((7 < n) && (str[7] == 'e')) { + return 181; + } + return 217; + } + return 281; + } + return 349; + } + return 503; + } + return 427; + } + } + if ((1 < n) && (str[1] == 'c')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'L')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 't')) { + return 1192; + } + return 1503; + } + return 1843; + } + return 2311; + } + return 3159; + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'a')) { + return 421; + } + return 525; + } + return 648; + } + return 850; + } + return 1138; + } + return 1805; + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'n')) { + return 1338; + } + return 1674; + } + return 2064; + } + return 2690; + } + return 3419; + } + return 2194; + } + } + if ((1 < n) && (str[1] == '7')) { + if ((2 < n) && (str[2] == 'E')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'm')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'n')) { + return 174; + } + return 213; + } + return 277; + } + return 342; + } + return 502; + } + return 751; + } + } + if ((1 < n) && (str[1] == 'G')) { + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '4')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'd')) { + return 756; + } + return 927; + } + return 1139; + } + return 1583; + } + return 2196; + } + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '1')) { + return 1519; + } + return 1058; + } + return 786; + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'T')) { + return 1656; + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'p')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'F')) { + return 2610; + } + return 1475; + } + return 2250; + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'g')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'o')) { + return 3473; + } + } + return 2254; + } + return 2786; + } + } + if ((1 < n) && (str[1] == 'L')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'l')) { + return 1199; + } + return 1517; + } + return 1910; + } + return 2428; + } + return 3288; + } + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'e')) { + return 2193; + } + return 2740; + } + return 3336; + } + } + return 1348; + } + if ((2 < n) && (str[2] == 'm')) { + if ((3 < n) && (str[3] == 'E')) { + if ((4 < n) && (str[4] == 'q')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 't')) { + return 2517; + } + return 2991; + } + return 3542; + } + } + } + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '_')) { + return 2710; + } + return 2321; + } + return 1682; + } + return 2046; + } + return 2794; + } + return 3248; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'y')) { + if ((4 < n) && (str[4] == 'B')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'f')) { + if ((7 < n) && (str[7] == 'f')) { + return 180; + } + return 218; + } + return 280; + } + return 345; + } + return 288; + } + return 423; + } + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'e')) { + return 1816; + } + return 2179; + } + return 2741; + } + return 3338; + } + return 855; + } + return 960; + } + } + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == 'y')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'S')) { + return 1109; + } + return 864; + } + return 743; + } + return 400; + } + return 572; + } + return 856; + } + } + if ((1 < n) && (str[1] == 'w')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'I')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'd')) { + return 693; + } + return 780; + } + return 980; + } + return 591; + } + return 810; + } + return 1247; + } + } + if ((1 < n) && (str[1] == 'd')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'T')) { + return 1052; + } + return 925; + } + return 1031; + } + return 1413; + } + return 1857; + } + return 2835; + } + } +} +if ((0 < n) && (str[0] == 'u')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'V')) { + return 2299; + } + if ((7 < n) && (str[7] == 'F')) { + return 489; + } + return 171; + } + return 225; + } + return 295; + } + return 392; + } + return 605; + } + } + if ((1 < n) && (str[1] == 'b')) { + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'q')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'n')) { + return 301; + } + return 353; + } + return 460; + } + return 598; + } + return 815; + } + return 1261; + } + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 't')) { + return 660; + } + return 795; + } + return 991; + } + return 1367; + } + return 1891; + } + return 2795; + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'E')) { + if ((7 < n) && (str[7] == 'q')) { + return 2526; + } + return 3007; + } + return 2680; + } + return 3271; + } + } + } + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'S')) { + return 1842; + } + return 1980; + } + return 2328; + } + return 3062; + } + } + } + if ((2 < n) && (str[2] == 'F')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'm')) { + if ((6 < n) && (str[6] == 'E')) { + if ((7 < n) && (str[7] == 'q')) { + return 2538; + } + return 3034; + } + return 2706; + } + return 3285; + } + } + if ((3 < n) && (str[3] == 'W')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 'S')) { + return 3557; + } + } + } + if ((3 < n) && (str[3] == 'G')) { + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '1')) { + return 2476; + } + return 3042; + } + return 3533; + } + } + } + return 1514; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'W')) { + if ((6 < n) && (str[6] == 'x')) { + if ((7 < n) && (str[7] == 'S')) { + return 2524; + } + return 3027; + } + return 3508; + } + return 3403; + } + } + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'T')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'p')) { + return 244; + } + return 310; + } + return 360; + } + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 'W')) { + if ((7 < n) && (str[7] == 'x')) { + return 2316; + } + return 2838; + } + return 3075; + } + return 185; + } + return 189; + } + return 306; + } + } + if ((1 < n) && (str[1] == 'f')) { + if ((2 < n) && (str[2] == 'f')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'T')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'p')) { + return 2711; + } + return 3152; + } + } + if ((5 < n) && (str[5] == 'g')) { + return 2865; + } + return 207; + } + return 290; + } + return 394; + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'I')) { + if ((7 < n) && (str[7] == 'n')) { + return 2245; + } + return 2763; + } + return 2897; + } + return 3476; + } + } + } + } + if ((1 < n) && (str[1] == 'l')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'd')) { + return 2078; + } + return 2836; + } + return 3071; + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 'A')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 395; + } + return 496; + } + return 614; + } + return 800; + } + return 1048; + } + return 1708; + } + } + if ((1 < n) && (str[1] == 'n')) { + if ((2 < n) && (str[2] == 'd')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'n')) { + return 969; + } + return 1095; + } + return 1442; + } + return 1876; + } + return 2642; + } + if ((3 < n) && (str[3] == 's')) { + return 2775; + } + return 1116; + } + } + if ((1 < n) && (str[1] == '0')) { + if ((2 < n) && (str[2] == '_')) { + if ((3 < n) && (str[3] == 'R')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '1')) { + return 1956; + } + return 1355; + } + return 1773; + } + return 1870; + } + return 2462; + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == 'A')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'B')) { + return 659; + } + return 508; + } + return 611; + } + return 798; + } + return 1106; + } + return 1789; + } + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'R')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'l')) { + return 1216; + } + return 1541; + } + return 1944; + } + return 2574; + } + return 3323; + } + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'L')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'c')) { + if ((7 < n) && (str[7] == 'S')) { + return 1187; + } + return 1459; + } + return 1807; + } + return 2312; + } + return 3151; + } + } + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'V')) { + if ((4 < n) && (str[4] == '1')) { + if ((5 < n) && (str[5] == '4')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 't')) { + return 1062; + } + return 1368; + } + return 1724; + } + return 2227; + } + if ((4 < n) && (str[4] == 's')) { + return 3103; + } + return 1272; + } + return 1575; + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'b')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'C')) { + if ((7 < n) && (str[7] == 'o')) { + return 707; + } + return 842; + } + return 486; + } + return 622; + } + return 873; + } + return 1319; + } + if ((2 < n) && (str[2] == 'O')) { + if ((3 < n) && (str[3] == 'f')) { + if ((4 < n) && (str[4] == 'B')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'n')) { + return 1452; + } + return 1788; + } + return 2213; + } + return 2880; + } + return 3182; + } + } + } + if ((1 < n) && (str[1] == 'R')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '1')) { + return 1574; + } + return 1150; + } + return 1811; + } + } +} +if ((0 < n) && (str[0] == 't')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'c')) { + if ((3 < n) && (str[3] == 'k')) { + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'c')) { + return 1276; + } + return 1595; + } + return 2009; + } + return 2633; + } + if ((4 < n) && (str[4] == '4')) { + if ((5 < n) && (str[5] == 'f')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'l')) { + return 1291; + } + return 1629; + } + return 2031; + } + return 2643; + } + return 1232; + } + return 1923; + } + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'l')) { + return 712; + } + return 843; + } + return 1038; + } + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'l')) { + return 2071; + } + return 2411; + } + return 3074; + } + if ((5 < n) && (str[5] == 'F')) { + if ((6 < n) && (str[6] == 'W')) { + if ((7 < n) && (str[7] == '_')) { + return 2516; + } + return 3047; + } + if ((6 < n) && (str[6] == 'G')) { + if ((7 < n) && (str[7] == 'S')) { + return 2489; + } + return 3039; + } + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'S')) { + return 2512; + } + return 3029; + } + return 742; + } + return 114; + } + return 183; + } + return 285; + } + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 'e')) { + return 3410; + } + } + } + } + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == '1')) { + return 573; + } + if ((4 < n) && (str[4] == '9')) { + if ((5 < n) && (str[5] == 'T')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 1759; + } + return 2157; + } + return 2716; + } + return 2927; + } + if ((4 < n) && (str[4] == '3')) { + return 2622; + } + if ((4 < n) && (str[4] == '2')) { + return 947; + } + if ((4 < n) && (str[4] == '4')) { + return 3466; + } + return 159; + } + return 252; + } + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'l')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'o')) { + if ((7 < n) && (str[7] == 'n')) { + return 1612; + } + return 1939; + } + return 2378; + } + return 1570; + } + return 2165; + } + return 623; + } + if ((2 < n) && (str[2] == 'd')) { + return 2164; + } + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'L')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 't')) { + return 1447; + } + return 1783; + } + return 2209; + } + if ((5 < n) && (str[5] == 'T')) { + if ((6 < n) && (str[6] == 'y')) { + if ((7 < n) && (str[7] == 'p')) { + return 1964; + } + return 2334; + } + return 2925; + } + return 972; + } + return 1417; + } + return 2128; + } + } + if ((1 < n) && (str[1] == 'd')) { + if ((2 < n) && (str[2] == 'l')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 'b')) { + if ((5 < n) && (str[5] == 'U')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'i')) { + return 29; + } + return 53; + } + return 78; + } + return 101; + } + return 154; + } + return 255; + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'g')) { + return 2235; + } + return 2759; + } + return 3258; + } + } + } + } + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '_')) { + return 3154; + } + return 2915; + } + return 2119; + } + return 2765; + } + } + if ((2 < n) && (str[2] == 'g')) { + if ((3 < n) && (str[3] == 'u')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'A')) { + return 396; + } + return 473; + } + return 587; + } + return 759; + } + return 1046; + } + return 1707; + } + if ((2 < n) && (str[2] == 'o')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'r')) { + if ((6 < n) && (str[6] == 'y')) { + return 1235; + } + return 1556; + } + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'I')) { + if ((7 < n) && (str[7] == 'n')) { + return 1188; + } + return 1504; + } + return 558; + } + return 382; + } + if ((4 < n) && (str[4] == 'F')) { + return 3438; + } + if ((4 < n) && (str[4] == 'M')) { + if ((5 < n) && (str[5] == 'i')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'u')) { + return 1227; + } + return 1552; + } + return 1864; + } + return 2393; + } + if ((4 < n) && (str[4] == 'O')) { + if ((5 < n) && (str[5] == 'f')) { + return 2191; + } + return 2317; + } + if ((4 < n) && (str[4] == 'S')) { + return 3188; + } + if ((4 < n) && (str[4] == 'T')) { + if ((5 < n) && (str[5] == 'y')) { + if ((6 < n) && (str[6] == 'p')) { + if ((7 < n) && (str[7] == 'e')) { + return 116; + } + return 142; + } + return 196; + } + return 227; + } + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == '_')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == '1')) { + return 1454; + } + return 1071; + } + return 1061; + } + return 1350; + } + return 20; + } + return 47; + } + if ((2 < n) && (str[2] == 'v')) { + if ((3 < n) && (str[3] == 'e')) { + return 1381; + } + return 2118; + } + } + if ((1 < n) && (str[1] == 'o')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'e')) { + return 1821; + } + return 1817; + } + return 2445; + } + if ((3 < n) && (str[3] == 'S')) { + return 2105; + } + if ((3 < n) && (str[3] == 'T')) { + if ((4 < n) && (str[4] == 'y')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 's')) { + return 2726; + } + return 1432; + } + return 1800; + } + return 2308; + } + return 3155; + } + if ((3 < n) && (str[3] == '7')) { + if ((4 < n) && (str[4] == 'E')) { + if ((5 < n) && (str[5] == 'l')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'm')) { + return 178; + } + return 216; + } + return 275; + } + return 344; + } + return 500; + } + return 197; + } + if ((2 < n) && (str[2] == 'E')) { + if ((3 < n) && (str[3] == 'q')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 't')) { + if ((7 < n) && (str[7] == 'a')) { + return 2501; + } + return 2996; + } + return 3534; + } + } + } + } + } + if ((1 < n) && (str[1] == 'I')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'x')) { + return 3435; + } + } + } + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 'i')) { + return 3460; + } + if ((2 < n) && (str[2] == 'S')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '6')) { + if ((7 < n) && (str[7] == 'r')) { + return 2471; + } + return 2987; + } + return 3509; + } + } + } + } + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'i')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'e')) { + return 2709; + } + return 3262; + } + } + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'c')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 'a')) { + if ((7 < n) && (str[7] == 'l')) { + return 726; + } + return 888; + } + return 1080; + } + return 1430; + } + return 1990; + } + return 2815; + } + if ((2 < n) && (str[2] == 'i')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'g')) { + if ((5 < n) && (str[5] == 'C')) { + if ((6 < n) && (str[6] == 'o')) { + return 2951; + } + return 3363; + } + return 1689; + } + return 2195; + } + return 1566; + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == 't')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '1')) { + return 3162; + } + return 425; + } + if ((5 < n) && (str[5] == '9')) { + if ((6 < n) && (str[6] == 'T')) { + if ((7 < n) && (str[7] == 'e')) { + return 1757; + } + return 2160; + } + return 2263; + } + if ((5 < n) && (str[5] == '3')) { + return 2002; + } + if ((5 < n) && (str[5] == '2')) { + return 738; + } + if ((5 < n) && (str[5] == '4')) { + return 2896; + } + return 104; + } + return 162; + } + return 240; + } + } + if ((1 < n) && (str[1] == 'O')) { + if ((2 < n) && (str[2] == 'f')) { + if ((3 < n) && (str[3] == 'B')) { + if ((4 < n) && (str[4] == 'o')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'd')) { + return 1451; + } + return 1785; + } + return 2214; + } + return 2882; + } + } + return 3112; + } + } + if ((1 < n) && (str[1] == 'V')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'F')) { + if ((7 < n) && (str[7] == 'r')) { + return 1746; + } + if ((7 < n) && (str[7] == 'W')) { + return 2473; + } + return 882; + } + return 1060; + } + return 1457; + } + return 2068; + } + return 3064; + } + } + if ((1 < n) && (str[1] == '9')) { + if ((2 < n) && (str[2] == 'T')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 's')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'u')) { + return 1756; + } + return 2156; + } + return 2718; + } + return 3302; + } + } + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == '9')) { + if ((4 < n) && (str[4] == 'E')) { + if ((5 < n) && (str[5] == 'q')) { + if ((6 < n) && (str[6] == 'u')) { + if ((7 < n) && (str[7] == 'a')) { + return 1315; + } + return 1643; + } + return 2043; + } + return 2669; + } + return 3398; + } + } + } +} +if ((0 < n) && (str[0] == 'w')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'd')) { + if ((4 < n) && (str[4] == 'I')) { + if ((5 < n) && (str[5] == 'n')) { + if ((6 < n) && (str[6] == 'd')) { + if ((7 < n) && (str[7] == 'e')) { + return 692; + } + return 838; + } + return 979; + } + return 1345; + } + return 807; + } + return 1243; + } + } + if ((1 < n) && (str[1] == 'x')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == 'u')) { + if ((6 < n) && (str[6] == 'b')) { + if ((7 < n) && (str[7] == 'S')) { + return 477; + } + return 578; + } + return 721; + } + return 931; + } + return 1342; + } + return 2004; + } + if ((2 < n) && (str[2] == '5')) { + if ((3 < n) && (str[3] == 'I')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'd')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'x')) { + return 538; + } + return 564; + } + return 702; + } + return 909; + } + return 1255; + } + return 1976; + } + } + if ((1 < n) && (str[1] == 'r')) { + if ((2 < n) && (str[2] == 'a')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 'V')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'u')) { + return 729; + } + return 886; + } + return 1077; + } + return 1487; + } + return 2082; + } + return 3087; + } + } + if ((1 < n) && (str[1] == 'F')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'm')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'b')) { + return 1301; + } + return 1639; + } + return 2024; + } + return 2653; + } + return 3383; + } + } + } +} +if ((0 < n) && (str[0] == 'v')) { + if ((1 < n) && (str[1] == 'e')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 't')) { + if ((4 < n) && (str[4] == 'i')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'e')) { + return 1009; + } + return 1162; + } + return 1533; + } + return 2045; + } + return 2724; + } + return 2152; + } + } +} +if ((0 < n) && (str[0] == 'y')) { + if ((1 < n) && (str[1] == 'p')) { + if ((2 < n) && (str[2] == 'e')) { + if ((3 < n) && (str[3] == 'w')) { + return 2913; + } + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'F')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == '1')) { + return 1154; + } + return 1479; + } + return 1836; + } + return 2198; + } + return 1720; + } + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '_')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'i')) { + if ((7 < n) && (str[7] == 'S')) { + return 890; + } + return 962; + } + return 792; + } + if ((5 < n) && (str[5] == 'G')) { + if ((6 < n) && (str[6] == 'S')) { + return 2784; + } + return 1538; + } + return 428; + } + if ((4 < n) && (str[4] == 'F')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == '1')) { + if ((7 < n) && (str[7] == '_')) { + return 2407; + } + return 2937; + } + if ((6 < n) && (str[6] == '0')) { + if ((7 < n) && (str[7] == '_')) { + return 928; + } + return 1117; + } + return 603; + } + return 768; + } + return 256; + } + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'V')) { + if ((6 < n) && (str[6] == 's')) { + return 3212; + } + return 2367; + } + return 2852; + } + return 1890; + } + if ((3 < n) && (str[3] == 'W')) { + if ((4 < n) && (str[4] == 'x')) { + if ((5 < n) && (str[5] == '9')) { + if ((6 < n) && (str[6] == 'G')) { + if ((7 < n) && (str[7] == 'e')) { + return 2437; + } + return 2959; + } + return 3468; + } + } + } + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '1')) { + if ((6 < n) && (str[6] == '_')) { + return 3004; + } + return 3522; + } + return 1888; + } + return 1099; + } + return 67; + } + } + if ((1 < n) && (str[1] == 'C')) { + if ((2 < n) && (str[2] == 'h')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 'k')) { + if ((6 < n) && (str[6] == 's')) { + if ((7 < n) && (str[7] == 'V')) { + return 1335; + } + return 569; + } + return 691; + } + return 904; + } + return 1244; + } + return 1767; + } + } + if ((1 < n) && (str[1] == 'B')) { + if ((2 < n) && (str[2] == 'u')) { + if ((3 < n) && (str[3] == 'f')) { + if ((4 < n) && (str[4] == 'f')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'T')) { + return 2689; + } + if ((7 < n) && (str[7] == 'g')) { + return 2010; + } + return 222; + } + return 272; + } + return 340; + } + return 499; + } + return 746; + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == 't')) { + if ((3 < n) && (str[3] == 'o')) { + if ((4 < n) && (str[4] == 'r')) { + if ((5 < n) && (str[5] == 'a')) { + if ((6 < n) && (str[6] == 'g')) { + if ((7 < n) && (str[7] == 'e')) { + return 2797; + } + return 2735; + } + return 3224; + } + } + } + } + } + if ((1 < n) && (str[1] == 'O')) { + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'j')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 'c')) { + if ((6 < n) && (str[6] == 't')) { + return 3238; + } + } + } + } + } + } +} +if ((0 < n) && (str[0] == 'x')) { + if ((1 < n) && (str[1] == 'a')) { + if ((2 < n) && (str[2] == 'b')) { + if ((3 < n) && (str[3] == 'l')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + return 3562; + } + return 2583; + } + return 3314; + } + } + } + if ((1 < n) && (str[1] == 'G')) { + if ((2 < n) && (str[2] == 'V')) { + if ((3 < n) && (str[3] == 's')) { + if ((4 < n) && (str[4] == '3')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 't')) { + return 2459; + } + return 2966; + } + return 3479; + } + } + } + } + } + if ((1 < n) && (str[1] == 'i')) { + if ((2 < n) && (str[2] == 'n')) { + if ((3 < n) && (str[3] == 'g')) { + if ((4 < n) && (str[4] == 'G')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'n')) { + if ((7 < n) && (str[7] == 'e')) { + return 2237; + } + return 2758; + } + return 3255; + } + } + } + } + } + if ((1 < n) && (str[1] == 's')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '4')) { + if ((4 < n) && (str[4] == 'C')) { + if ((5 < n) && (str[5] == 'o')) { + if ((6 < n) && (str[6] == 'l')) { + if ((7 < n) && (str[7] == 'l')) { + return 1040; + } + return 1341; + } + return 1700; + } + return 2190; + } + return 2809; + } + return 1114; + } + if ((2 < n) && (str[2] == '2')) { + return 3174; + } + } + if ((1 < n) && (str[1] == '1')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == 'u')) { + if ((5 < n) && (str[5] == 'b')) { + if ((6 < n) && (str[6] == 'S')) { + if ((7 < n) && (str[7] == 'e')) { + return 476; + } + return 577; + } + return 722; + } + return 930; + } + return 1347; + } + return 1894; + } + } + if ((1 < n) && (str[1] == 'S')) { + if ((2 < n) && (str[2] == '1')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '2')) { + if ((6 < n) && (str[6] == '_')) { + return 3143; + } + } + } + return 3264; + } + } + if ((2 < n) && (str[2] == '0')) { + if ((3 < n) && (str[3] == '_')) { + return 2764; + } + } + if ((2 < n) && (str[2] == '3')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '4')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == '_')) { + return 867; + } + return 1033; + } + return 1362; + } + return 1742; + } + return 2270; + } + return 3307; + } + if ((2 < n) && (str[2] == '2')) { + if ((3 < n) && (str[3] == '_')) { + if ((4 < n) && (str[4] == 'S')) { + if ((5 < n) && (str[5] == '3')) { + if ((6 < n) && (str[6] == '_')) { + return 2911; + } + return 3423; + } + return 3451; + } + return 870; + } + return 1364; + } + } + if ((1 < n) && (str[1] == '5')) { + if ((2 < n) && (str[2] == 'I')) { + if ((3 < n) && (str[3] == 'n')) { + if ((4 < n) && (str[4] == 'd')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'x')) { + return 594; + } + return 640; + } + return 839; + } + return 1134; + } + return 1837; + } + } + if ((1 < n) && (str[1] == 'T')) { + if ((2 < n) && (str[2] == 'y')) { + if ((3 < n) && (str[3] == 'p')) { + if ((4 < n) && (str[4] == 'e')) { + if ((5 < n) && (str[5] == 's')) { + if ((6 < n) && (str[6] == '_')) { + if ((7 < n) && (str[7] == 'S')) { + return 2807; + } + return 3191; + } + return 2309; + } + return 617; + } + return 858; + } + return 1351; + } + } + if ((1 < n) && (str[1] == '9')) { + if ((2 < n) && (str[2] == 'w')) { + if ((3 < n) && (str[3] == 'r')) { + if ((4 < n) && (str[4] == 'a')) { + if ((5 < n) && (str[5] == 'p')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'a')) { + return 2536; + } + return 3015; + } + return 3519; + } + } + } + } + if ((2 < n) && (str[2] == 'G')) { + if ((3 < n) && (str[3] == 'e')) { + if ((4 < n) && (str[4] == 'n')) { + if ((5 < n) && (str[5] == 'e')) { + if ((6 < n) && (str[6] == 'r')) { + if ((7 < n) && (str[7] == 'a')) { + return 325; + } + return 388; + } + return 507; + } + return 651; + } + return 907; + } + return 1426; + } + } + if ((1 < n) && (str[1] == '_')) { + if ((2 < n) && (str[2] == 's')) { + if ((3 < n) && (str[3] == '1')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == 'S')) { + if ((6 < n) && (str[6] == 'e')) { + if ((7 < n) && (str[7] == 'q')) { + return 998; + } + return 1234; + } + return 1651; + } + return 1966; + } + return 959; + } + return 955; + } + } + if ((1 < n) && (str[1] == 't')) { + if ((2 < n) && (str[2] == 'r')) { + if ((3 < n) && (str[3] == 'a')) { + if ((4 < n) && (str[4] == 'c')) { + if ((5 < n) && (str[5] == 't')) { + if ((6 < n) && (str[6] == 'V')) { + if ((7 < n) && (str[7] == 'a')) { + return 731; + } + return 887; + } + return 1074; + } + return 1481; + } + return 2041; + } + return 3056; + } + } +} +if ((0 < n) && (str[0] == 'z')) { + if ((1 < n) && (str[1] == 'W')) { + if ((2 < n) && (str[2] == 'x')) { + if ((3 < n) && (str[3] == 'S')) { + if ((4 < n) && (str[4] == '2')) { + if ((5 < n) && (str[5] == '_')) { + return 1565; + } + return 2074; + } + return 1691; + } + return 1701; + } + } +} + +return -1; +} +} // namespace +#endif /* SWIFT_MANGLER_CBC_TABLE_H */ diff --git a/lib/ABI/CMakeLists.txt b/lib/ABI/CMakeLists.txt new file mode 100644 index 0000000000000..1deada274bc59 --- /dev/null +++ b/lib/ABI/CMakeLists.txt @@ -0,0 +1,3 @@ +add_swift_library(swiftABI + Compression.cpp) + diff --git a/lib/ABI/Compression.cpp b/lib/ABI/Compression.cpp new file mode 100644 index 0000000000000..fdc5f1909762a --- /dev/null +++ b/lib/ABI/Compression.cpp @@ -0,0 +1,314 @@ +//===--- Compression.cpp - Compression of symbols -------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "swift/ABI/Compression.h" +#include "CBCTables.h" +#include "HuffTables.h" +#include + +using namespace llvm; +using namespace swift; + +using EncodingKind = swift::Compress::EncodingKind; + +static unsigned CBCindexOfChar(char c) { + int idx = CBC::IndexOfChar[int(c)]; + assert(idx >= 0 && "Invalid char"); + return (unsigned) idx; +} + +std::string swift::Compress::DecodeCBCString(StringRef In) { + unsigned EndIndex = In.size(); + + // The String Builder. + std::string SB; + SB.reserve(In.size()); + + // Processed Index - The index of the first non-processed char. + unsigned PI = 0; + + while (true) { + if (PI >= EndIndex) break; + const char c = In[PI]; + if (c == CBC::EscapeChar0) { + if ((PI+1) >= EndIndex) { + assert(false && "Invalid Encoding"); + return ""; + } + const char N = In[PI+1]; + + if (N == CBC::EscapeChar0 || N == CBC::EscapeChar1) { + SB += N; + PI += 2; + continue; + } + + unsigned Idx = CBCindexOfChar(N); + if (Idx > CBC::CharsetLength || CBC::Charset[Idx] != N) { + assert(false && "bad indexOfChar"); + return ""; + } + SB += CBC::CodeBook[Idx]; + PI += 2; + continue; + } + + if (c == CBC::EscapeChar1) { + if ((PI+2) >= EndIndex) { + assert(false && "Invalid Encoding"); + return ""; + } + + const char N0 = In[PI+1]; + const char N1 = In[PI+2]; + unsigned JointIndex = (CBC::CharsetLength * CBCindexOfChar(N0)) + + CBCindexOfChar(N1); + if (JointIndex > CBC::NumFragments) { + assert(false && "Read bad index"); + return ""; + } + SB += CBC::CodeBook[JointIndex]; + PI += 3; + continue; + } + // We did not find a match. Just decode the character. + SB += c; + PI++; + } + + return SB; +} + +std::string swift::Compress::EncodeCBCString(StringRef In) { + unsigned EndIndex = In.size(); + + // The String Builder. + std::string SB; + SB.reserve(In.size()); + + // Processed Index - The index of the first non-processed char. + unsigned PI = 0; + + while (true) { +StartMatch: + if (PI >= EndIndex) break; + + const char c = In[PI]; + if (c == CBC::EscapeChar0 || c == CBC::EscapeChar1) { + SB += CBC::EscapeChar0; + SB += c; + PI++; + goto StartMatch; + } + + // The number of unprocessed chars. + unsigned DistanceToEnd = EndIndex - PI; + int FragIdx = CBC::matchStringSuffix(In.data() + PI, DistanceToEnd); + + if (FragIdx >= 0){ + unsigned FragmentLength = CBC::CodeBookLen[FragIdx]; + // Try encoding using a single escape character. + if (FragIdx < int(CBC::CharsetLength)) { + SB += CBC::EscapeChar0; + SB += CBC::Charset[FragIdx]; + PI += FragmentLength; + goto StartMatch; + } + + // Try encoding using two escape character. Make sure that the encoding + // is profitable. + if (FragmentLength > 3) { + SB += CBC::EscapeChar1; + SB += CBC::Charset[FragIdx / CBC::CharsetLength]; + SB += CBC::Charset[FragIdx % CBC::CharsetLength]; + PI += FragmentLength; + goto StartMatch; + } + } + + // We did not find a match. Just save the character. :( + SB += c; + PI++; + } + + return SB; +} + +/// Extract all of the characters from the number \p Num one by one and +/// insert them into the string builder \p SB. +static void DecodeFixedWidth(APInt &Num, std::string &SB) { + uint64_t CL = Huffman::CharsetLength; + + // NL is the number of characters that we can hold in a 64bit number. + // Each letter takes Log2(CL) bits. Doing this computation in floating- + // point arithmetic could give a slightly better (more optimistic) result, + // but the computation may not be constant at compile time. + uint64_t NumLetters = 64 / Log2_64_Ceil(CL); + + assert(Num.getBitWidth() > 8 && + "Not enough bits for arithmetic on this alphabet"); + + // Try to decode eight numbers at once. It is much faster to work with + // local 64bit numbers than working with APInt. In this loop we try to + // extract NL characters at once and process them using a local 64-bit + // number. + + // Calculate CharsetLength**NumLetters (CL to the power of NL), which is the + // highest numeric value that can hold NumLetters characters in a 64bit + // number. Notice: this loop is optimized away and CLX is computed to a + // constant integer at compile time. + uint64_t CLX = 1; + for (unsigned i = 0; i < NumLetters; i++) { CLX *= CL; } + + while (Num.ugt(CLX)) { + unsigned BW = Num.getBitWidth(); + APInt C = APInt(BW, CLX); + APInt Quotient(1, 0), Remainder(1, 0); + APInt::udivrem(Num, C, Quotient, Remainder); + + // Try to reduce the bitwidth of the API after the division. This can + // accelerate the division operation in future iterations because the + // number becomes smaller (fewer bits) with each iteration. However, + // We can't reduce the number to something too small because we still + // need to be able to perform the "mod charset_length" operation. + Num = Quotient.zextOrTrunc(std::max(Quotient.getActiveBits(), 64u)); + uint64_t Tail = Remainder.getZExtValue(); + for (unsigned i = 0; i < NumLetters; i++) { + SB += Huffman::Charset[Tail % CL]; + Tail = Tail / CL; + } + } + + // Pop characters out of the APInt one by one. + while (Num.getBoolValue()) { + unsigned BW = Num.getBitWidth(); + + APInt C = APInt(BW, CL); + APInt Quotient(1, 0), Remainder(1, 0); + APInt::udivrem(Num, C, Quotient, Remainder); + Num = Quotient; + SB += Huffman::Charset[Remainder.getZExtValue()]; + } +} + +static void EncodeFixedWidth(APInt &num, char ch) { + APInt C = APInt(num.getBitWidth(), Huffman::CharsetLength); + // TODO: autogenerate a table for the reverse lookup. + for (unsigned i = 0; i < Huffman::CharsetLength; i++) { + if (Huffman::Charset[i] == ch) { + num *= C; + num += APInt(num.getBitWidth(), i); + return; + } + } + assert(false); +} + +APInt +swift::Compress::EncodeStringAsNumber(StringRef In, EncodingKind Kind) { + // Allocate enough space for the first character plus one bit which is the + // stop bit for variable length encoding. + unsigned BW = (1 + Huffman::LongestEncodingLength); + APInt num = APInt(BW, 0); + + // We set the high bit to zero in order to support encoding + // of chars that start with zero (for variable length encoding). + if (Kind == EncodingKind::Variable) { + num = ++num; + } + + // Encode variable-length strings. + if (Kind == EncodingKind::Variable) { + size_t num_bits = 0; + size_t bits = 0; + + // Append the characters in the string in reverse. This will allow + // us to decode by appending to a string and not prepending. + for (int i = In.size() - 1; i >= 0; i--) { + char ch = In[i]; + + // The local variables 'bits' and 'num_bits' are used as a small + // bitstream. Keep accumulating bits into them until they overflow. + // At that point move them into the APInt. + uint64_t local_bits; + uint64_t local_num_bits; + // Find the huffman encoding of the character. + Huffman::variable_encode(local_bits, local_num_bits, ch); + // Add the encoded character into our bitstream. + num_bits += local_num_bits; + bits = (bits << local_num_bits) + local_bits; + + // Check if there is enough room for another word. If not, flush + // the local bitstream into the APInt. + if (num_bits >= (64 - Huffman::LongestEncodingLength)) { + // Make room for the new bits and add the bits. + num = num.zext(num.getBitWidth() + num_bits); + num = num.shl(num_bits); num = num + bits; + num_bits = 0; bits = 0; + } + } + + // Flush the local bitstream into the APInt number. + if (num_bits) { + num = num.zext(num.getBitWidth() + num_bits); + num = num.shl(num_bits); num = num + bits; + num_bits = 0; bits = 0; + } + + // Make sure that we have a minimal word size to be able to perform + // calculations on our alphabet. + return num.zextOrSelf(std::max(64u, num.getBitWidth())); + } + + // Encode fixed width strings. + for (int i = In.size() - 1; i >= 0; i--) { + char ch = In[i]; + // Extend the number and create room for encoding another character. + unsigned MinBits = num.getActiveBits() + Huffman::LongestEncodingLength; + num = num.zextOrTrunc(std::max(64u, MinBits)); + EncodeFixedWidth(num, ch); + } + + return num; +} + +std::string swift::Compress::DecodeStringFromNumber(const APInt &In, + EncodingKind Kind) { + APInt num = In; + std::string sb; + + if (Kind == EncodingKind::Variable) { + // Keep decoding until we reach our sentinel value. + // See the encoder implementation for more details. + while (num.ugt(1)) { + sb += Huffman::variable_decode(num); + } + } else { + // Decode this number as a regular fixed-width sequence of characters. + DecodeFixedWidth(num, sb); + } + + return sb; +} + +std::string swift::Compress::CompressName(StringRef In) { + std::string cbc = EncodeCBCString(In); + APInt num = EncodeStringAsNumber(cbc, EncodingKind::Variable); + return DecodeStringFromNumber(num, EncodingKind::Fixed); +} + +std::string swift::Compress::DecompressName(StringRef In) { + APInt num = EncodeStringAsNumber(In, EncodingKind::Fixed); + std::string str = DecodeStringFromNumber(num, EncodingKind::Variable); + return DecodeCBCString(str); +} + diff --git a/lib/ABI/HuffTables.h b/lib/ABI/HuffTables.h new file mode 100644 index 0000000000000..d4489345a1639 --- /dev/null +++ b/lib/ABI/HuffTables.h @@ -0,0 +1,591 @@ +#ifndef SWIFT_MANGLER_HUFFMAN_H +#define SWIFT_MANGLER_HUFFMAN_H +#include +#include "llvm/ADT/APInt.h" +using APInt = llvm::APInt; +// This file is autogenerated. Do not modify this file. +// Processing text files: CBC_Compressed.txt.cbc +namespace Huffman { +// The charset that the fragment indices can use: +const unsigned CharsetLength = 64; +const unsigned LongestEncodingLength = 8; +const char *Charset = "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$"; +char variable_decode(APInt &num) { + uint64_t tailbits = *num.getRawData(); +if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'U'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'B'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return '8'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'P'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'v'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(8); + return '$'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(8); + return 'H'; + } + } + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'b'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return 'p'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(5); + return 'a'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'c'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return '4'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(5); + return 's'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'D'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'L'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return '7'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'u'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return 'm'; + } + } + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return '3'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return '5'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(5); + return 't'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'W'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'I'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'R'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'O'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(5); + return 'i'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'd'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'k'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'N'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'l'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'h'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'y'; + } + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'Y'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return '6'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(5); + return '1'; + } + } + } + } +} +if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(5); + return 'S'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'A'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(8); + return 'K'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(8); + return 'X'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return 'f'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(5); + return 'T'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(5); + return 'e'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(3); + return 'J'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'F'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return 'n'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(8); + return 'Z'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(8); + return 'Q'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'E'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(6); + return 'x'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(4); + return '_'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'o'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'q'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'V'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(8); + return 'M'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(8); + return 'j'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return '9'; + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'g'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'z'; + } + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return '2'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'C'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return 'w'; + } + } + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(6); + return 'r'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + if ((tailbits & 1) == 0) { + tailbits/=2; + num = num.lshr(7); + return 'G'; + } + if ((tailbits & 1) == 1) { + tailbits/=2; + num = num.lshr(7); + return '0'; + } + } + } + } + } + } +} + assert(false); return 0; +} +void variable_encode(uint64_t &bits, uint64_t &num_bits, char ch) { +if (ch == 'U') {/*0000000*/ bits = 0; num_bits = 7; return; } +if (ch == 'B') {/*1000000*/ bits = 64; num_bits = 7; return; } +if (ch == '8') {/*100000*/ bits = 32; num_bits = 6; return; } +if (ch == 'P') {/*010000*/ bits = 16; num_bits = 6; return; } +if (ch == 'v') {/*0110000*/ bits = 48; num_bits = 7; return; } +if (ch == '$') {/*01110000*/ bits = 112; num_bits = 8; return; } +if (ch == 'H') {/*11110000*/ bits = 240; num_bits = 8; return; } +if (ch == 'b') {/*001000*/ bits = 8; num_bits = 6; return; } +if (ch == 'p') {/*101000*/ bits = 40; num_bits = 6; return; } +if (ch == 'a') {/*11000*/ bits = 24; num_bits = 5; return; } +if (ch == 'c') {/*000100*/ bits = 4; num_bits = 6; return; } +if (ch == '4') {/*100100*/ bits = 36; num_bits = 6; return; } +if (ch == 's') {/*10100*/ bits = 20; num_bits = 5; return; } +if (ch == 'D') {/*0001100*/ bits = 12; num_bits = 7; return; } +if (ch == 'L') {/*1001100*/ bits = 76; num_bits = 7; return; } +if (ch == '7') {/*101100*/ bits = 44; num_bits = 6; return; } +if (ch == 'u') {/*011100*/ bits = 28; num_bits = 6; return; } +if (ch == 'm') {/*111100*/ bits = 60; num_bits = 6; return; } +if (ch == '3') {/*000010*/ bits = 2; num_bits = 6; return; } +if (ch == '5') {/*100010*/ bits = 34; num_bits = 6; return; } +if (ch == 't') {/*10010*/ bits = 18; num_bits = 5; return; } +if (ch == 'W') {/*0001010*/ bits = 10; num_bits = 7; return; } +if (ch == 'I') {/*1001010*/ bits = 74; num_bits = 7; return; } +if (ch == 'R') {/*0101010*/ bits = 42; num_bits = 7; return; } +if (ch == 'O') {/*1101010*/ bits = 106; num_bits = 7; return; } +if (ch == 'i') {/*11010*/ bits = 26; num_bits = 5; return; } +if (ch == 'd') {/*000110*/ bits = 6; num_bits = 6; return; } +if (ch == 'k') {/*0100110*/ bits = 38; num_bits = 7; return; } +if (ch == 'N') {/*1100110*/ bits = 102; num_bits = 7; return; } +if (ch == 'l') {/*010110*/ bits = 22; num_bits = 6; return; } +if (ch == 'h') {/*0110110*/ bits = 54; num_bits = 7; return; } +if (ch == 'y') {/*1110110*/ bits = 118; num_bits = 7; return; } +if (ch == 'Y') {/*001110*/ bits = 14; num_bits = 6; return; } +if (ch == '6') {/*101110*/ bits = 46; num_bits = 6; return; } +if (ch == '1') {/*11110*/ bits = 30; num_bits = 5; return; } +if (ch == 'S') {/*00001*/ bits = 1; num_bits = 5; return; } +if (ch == 'A') {/*0010001*/ bits = 17; num_bits = 7; return; } +if (ch == 'K') {/*01010001*/ bits = 81; num_bits = 8; return; } +if (ch == 'X') {/*11010001*/ bits = 209; num_bits = 8; return; } +if (ch == 'f') {/*110001*/ bits = 49; num_bits = 6; return; } +if (ch == 'T') {/*01001*/ bits = 9; num_bits = 5; return; } +if (ch == 'e') {/*11001*/ bits = 25; num_bits = 5; return; } +if (ch == 'J') {/*101*/ bits = 5; num_bits = 3; return; } +if (ch == 'F') {/*000011*/ bits = 3; num_bits = 6; return; } +if (ch == 'n') {/*100011*/ bits = 35; num_bits = 6; return; } +if (ch == 'Z') {/*00010011*/ bits = 19; num_bits = 8; return; } +if (ch == 'Q') {/*10010011*/ bits = 147; num_bits = 8; return; } +if (ch == 'E') {/*1010011*/ bits = 83; num_bits = 7; return; } +if (ch == 'x') {/*110011*/ bits = 51; num_bits = 6; return; } +if (ch == '_') {/*1011*/ bits = 11; num_bits = 4; return; } +if (ch == 'o') {/*000111*/ bits = 7; num_bits = 6; return; } +if (ch == 'q') {/*0100111*/ bits = 39; num_bits = 7; return; } +if (ch == 'V') {/*1100111*/ bits = 103; num_bits = 7; return; } +if (ch == 'M') {/*00010111*/ bits = 23; num_bits = 8; return; } +if (ch == 'j') {/*10010111*/ bits = 151; num_bits = 8; return; } +if (ch == '9') {/*1010111*/ bits = 87; num_bits = 7; return; } +if (ch == 'g') {/*0110111*/ bits = 55; num_bits = 7; return; } +if (ch == 'z') {/*1110111*/ bits = 119; num_bits = 7; return; } +if (ch == '2') {/*001111*/ bits = 15; num_bits = 6; return; } +if (ch == 'C') {/*0101111*/ bits = 47; num_bits = 7; return; } +if (ch == 'w') {/*1101111*/ bits = 111; num_bits = 7; return; } +if (ch == 'r') {/*011111*/ bits = 31; num_bits = 6; return; } +if (ch == 'G') {/*0111111*/ bits = 63; num_bits = 7; return; } +if (ch == '0') {/*1111111*/ bits = 127; num_bits = 7; return; } +assert(false); +} +} // namespace +#endif /* SWIFT_MANGLER_HUFFMAN_H */ diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f399971ff66d5..41a7fc6c1e251 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -177,6 +177,9 @@ struct ASTContext::Implementation { /// func _unimplemented_initializer(className: StaticString). FuncDecl *UnimplementedInitializerDecl = nullptr; + /// func _undefined(msg: StaticString, file: StaticString, line: UInt) -> T + FuncDecl *UndefinedDecl = nullptr; + /// func _stdlib_isOSVersionAtLeast(Builtin.Word,Builtin.Word, Builtin.word) // -> Builtin.Int1 FuncDecl *IsOSVersionAtLeastDecl = nullptr; @@ -985,6 +988,21 @@ ASTContext::getUnimplementedInitializerDecl(LazyResolver *resolver) const { return decl; } +FuncDecl * +ASTContext::getUndefinedDecl(LazyResolver *resolver) const { + if (Impl.UndefinedDecl) + return Impl.UndefinedDecl; + + // Look for the function. + CanType input, output; + auto decl = findLibraryIntrinsic(*this, "_undefined", resolver); + if (!decl) + return nullptr; + + Impl.UndefinedDecl = decl; + return decl; +} + FuncDecl *ASTContext::getIsOSVersionAtLeastDecl(LazyResolver *resolver) const { if (Impl.IsOSVersionAtLeastDecl) return Impl.IsOSVersionAtLeastDecl; @@ -1335,7 +1353,7 @@ Module *ASTContext::getLoadedModule(Identifier ModuleName) const { return LoadedModules.lookup(ModuleName); } -void ASTContext::getVisibleTopLevelClangeModules( +void ASTContext::getVisibleTopLevelClangModules( SmallVectorImpl &Modules) const { getClangModuleLoader()->getClangPreprocessor().getHeaderSearchInfo(). collectAllModules(Modules); @@ -2325,7 +2343,8 @@ void TupleType::Profile(llvm::FoldingSetNodeID &ID, ID.AddInteger(Fields.size()); for (const TupleTypeElt &Elt : Fields) { ID.AddPointer(Elt.NameAndVariadic.getOpaqueValue()); - ID.AddPointer(Elt.TyAndDefaultArg.getOpaqueValue()); + ID.AddPointer(Elt.getType().getPointer()); + ID.AddInteger(static_cast(Elt.getDefaultArgKind())); } } @@ -3145,9 +3164,9 @@ ProtocolType::ProtocolType(ProtocolDecl *TheDecl, const ASTContext &Ctx) LValueType *LValueType::get(Type objectTy) { assert(!objectTy->is() && - "can not have ErrorType wrapped inside LValueType"); + "cannot have ErrorType wrapped inside LValueType"); assert(!objectTy->is() && !objectTy->is() && - "can not have 'inout' or @lvalue wrapped inside an @lvalue"); + "cannot have 'inout' or @lvalue wrapped inside an @lvalue"); auto properties = objectTy->getRecursiveProperties() | RecursiveTypeProperties::IsLValue; @@ -3165,9 +3184,9 @@ LValueType *LValueType::get(Type objectTy) { InOutType *InOutType::get(Type objectTy) { assert(!objectTy->is() && - "can not have ErrorType wrapped inside InOutType"); + "cannot have ErrorType wrapped inside InOutType"); assert(!objectTy->is() && !objectTy->is() && - "can not have 'inout' or @lvalue wrapped inside an 'inout'"); + "cannot have 'inout' or @lvalue wrapped inside an 'inout'"); auto properties = objectTy->getRecursiveProperties() | RecursiveTypeProperties::HasInOut; @@ -3392,8 +3411,8 @@ void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id, id.AddPointer(arg.get()); } -DeclName::DeclName(ASTContext &C, Identifier baseName, - ArrayRef argumentNames) { +void DeclName::initialize(ASTContext &C, Identifier baseName, + ArrayRef argumentNames) { if (argumentNames.size() == 0) { SimpleOrCompound = IdentifierAndCompound(baseName, true); return; @@ -3419,6 +3438,17 @@ DeclName::DeclName(ASTContext &C, Identifier baseName, C.Impl.CompoundNames.InsertNode(compoundName, insert); } +/// Build a compound value name given a base name and a set of argument names +/// extracted from a parameter list. +DeclName::DeclName(ASTContext &C, Identifier baseName, + ParameterList *paramList) { + SmallVector names; + + for (auto P : *paramList) + names.push_back(P->getArgumentName()); + initialize(C, baseName, names); +} + Optional ASTContext::getBridgedToObjC(const DeclContext *dc, Type type, LazyResolver *resolver) const { diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index be2925e0a1738..81db157207160 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -1,8 +1,8 @@ -//===--- ASTDumper.cpp - Swift Language AST Dumper-------------------------===// +//===--- ASTDumper.cpp - Swift Language AST Dumper ------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,6 +19,7 @@ #include "swift/AST/ASTPrinter.h" #include "swift/AST/ASTVisitor.h" #include "swift/AST/ForeignErrorConvention.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/TypeVisitor.h" #include "swift/Basic/STLExtras.h" #include "llvm/ADT/APFloat.h" @@ -43,6 +44,42 @@ DEF_COLOR(TypeField, CYAN) #undef DEF_COLOR +namespace { + /// RAII object that prints with the given color, if color is supported on the + /// given stream. + class PrintWithColorRAII { + raw_ostream &OS; + bool ShowColors; + + public: + PrintWithColorRAII(raw_ostream &os, llvm::raw_ostream::Colors color) + : OS(os), ShowColors(false) + { + if (&os == &llvm::errs() || &os == &llvm::outs()) + ShowColors = llvm::errs().has_colors() && llvm::outs().has_colors(); + + if (ShowColors) { + if (auto str = llvm::sys::Process::OutputColor(color, false, false)) { + OS << str; + } + } + } + + ~PrintWithColorRAII() { + if (ShowColors) { + OS << llvm::sys::Process::ResetColor(); + } + } + + template + friend raw_ostream &operator<<(PrintWithColorRAII &&printer, + const T &value){ + printer.OS << value; + return printer.OS; + } + }; +} // end anonymous namespace + //===----------------------------------------------------------------------===// // Generic param list printing. //===----------------------------------------------------------------------===// @@ -235,12 +272,6 @@ namespace { for (auto &elt : P->getElements()) { OS << '\n'; printRec(elt.getPattern()); - if (elt.hasEllipsis()) - OS << " ellipsis"; - if (elt.getInit()) { - OS << '\n'; - printRec(elt.getInit()->getExpr()); - } } OS << ')'; } @@ -339,6 +370,15 @@ namespace { void printRec(Pattern *P) { PrintPattern(OS, Indent+2).visit(P); } void printRec(TypeRepr *T); + // Print a field with a value. + template + raw_ostream &printField(StringRef name, const T &value) { + OS << " "; + PrintWithColorRAII(OS, TypeFieldColor) << name; + OS << "=" << value; + return OS; + } + void printCommon(Decl *D, const char *Name, llvm::Optional Color = llvm::Optional()) { @@ -433,7 +473,7 @@ namespace { OS << ")"; } - void printDeclName(ValueDecl *D) { + void printDeclName(const ValueDecl *D) { if (D->getFullName()) OS << '\"' << D->getFullName() << '\"'; else @@ -542,10 +582,12 @@ namespace { llvm::Optional()) { printCommon((ValueDecl *)NTD, Name, Color); - if (NTD->hasFixedLayout()) - OS << " @_fixed_layout"; - else - OS << " @_resilient_layout"; + if (NTD->hasType()) { + if (NTD->hasFixedLayout()) + OS << " @_fixed_layout"; + else + OS << " @_resilient_layout"; + } } void visitSourceFile(const SourceFile &SF) { @@ -611,15 +653,8 @@ namespace { } } - void visitParamDecl(ParamDecl *VD) { - printCommon(VD, "param_decl"); - if (!VD->isLet()) - OS << " var"; - if (VD->getName() != VD->getArgumentName()) { - OS << " argument_name="; - printName(OS, VD->getArgumentName()); - } - OS << ')'; + void visitParamDecl(ParamDecl *PD) { + printParameter(PD); } void visitEnumCaseDecl(EnumCaseDecl *ECD) { @@ -730,27 +765,88 @@ namespace { OS << ",resulttype=" << fec->getResultType().getString(); } } + + void printParameter(const ParamDecl *P) { + OS.indent(Indent) << "(parameter "; + printDeclName(P); + if (!P->getArgumentName().empty()) + OS << " apiName=" << P->getArgumentName(); + + OS << " type="; + if (P->hasType()) { + OS << '\''; + P->getType().print(OS); + OS << '\''; + } else + OS << ""; + + if (!P->isLet()) + OS << " mutable"; + + if (P->isVariadic()) + OS << " variadic"; - void printPatterns(StringRef Text, ArrayRef Pats) { - if (Pats.empty()) - return; - if (!Text.empty()) { - OS << '\n'; - Indent += 2; - OS.indent(Indent) << '(' << Text; + switch (P->getDefaultArgumentKind()) { + case DefaultArgumentKind::None: break; + case DefaultArgumentKind::Column: + printField("default_arg", "__COLUMN__"); + break; + case DefaultArgumentKind::DSOHandle: + printField("default_arg", "__DSO_HANDLE__"); + break; + case DefaultArgumentKind::File: + printField("default_arg", "__FILE__"); + break; + case DefaultArgumentKind::Function: + printField("default_arg", "__FUNCTION__"); + break; + case DefaultArgumentKind::Inherited: + printField("default_arg", "inherited"); + break; + case DefaultArgumentKind::Line: + printField("default_arg", "__LINE__"); + break; + case DefaultArgumentKind::Nil: + printField("default_arg", "nil"); + break; + case DefaultArgumentKind::EmptyArray: + printField("default_arg", "[]"); + break; + case DefaultArgumentKind::EmptyDictionary: + printField("default_arg", "[:]"); + break; + case DefaultArgumentKind::Normal: + printField("default_arg", "normal"); + break; } - for (auto P : Pats) { - OS << '\n'; - printRec(P); + + if (auto init = P->getDefaultValue()) { + OS << " expression=\n"; + printRec(init->getExpr()); } - if (!Text.empty()) { - OS << ')'; - Indent -= 2; + + OS << ')'; + } + + + void printParameterList(const ParameterList *params) { + OS.indent(Indent) << "(parameter_list"; + Indent += 2; + for (auto P : *params) { + OS << '\n'; + printParameter(P); } + OS << ')'; + Indent -= 2; } void printAbstractFunctionDecl(AbstractFunctionDecl *D) { - printPatterns("body_params", D->getBodyParamPatterns()); + for (auto pl : D->getParameterLists()) { + OS << '\n'; + Indent += 2; + printParameterList(pl); + Indent -= 2; + } if (auto FD = dyn_cast(D)) { if (FD->getBodyResultTypeLoc().getTypeRepr()) { OS << '\n'; @@ -902,6 +998,26 @@ namespace { }; } // end anonymous namespace. +void ParameterList::dump() const { + dump(llvm::errs(), 0); +} + +void ParameterList::dump(raw_ostream &OS, unsigned Indent) const { + llvm::Optional> X; + + // Make sure to print type variables if we can get to ASTContext. + if (size() != 0 && get(0)) { + auto &ctx = get(0)->getASTContext(); + X.emplace(llvm::SaveAndRestore(ctx.LangOpts.DebugConstraintSolver, + true)); + } + + PrintDecl(OS, Indent).printParameterList(this); + llvm::errs() << '\n'; +} + + + void Decl::dump() const { dump(llvm::errs(), 0); } @@ -984,6 +1100,9 @@ static void printContext(raw_ostream &os, DeclContext *dc) { os << "deinit"; break; } + case DeclContextKind::SubscriptDecl: + os << "subscript decl"; + break; } } @@ -1487,7 +1606,7 @@ class PrintExpr : public ExprVisitor { void visitObjectLiteralExpr(ObjectLiteralExpr *E) { printCommon(E, "object_literal") - << " name=" << E->getName().str(); + << " name=" << E->getName(); OS << '\n'; printRec(E->getArg()); } @@ -1536,7 +1655,7 @@ class PrintExpr : public ExprVisitor { } void visitOverloadedDeclRefExpr(OverloadedDeclRefExpr *E) { printCommon(E, "overloaded_decl_ref_expr") - << " name=" << E->getDecls()[0]->getName().str() + << " name=" << E->getDecls()[0]->getName() << " #decls=" << E->getDecls().size() << " specialized=" << (E->isSpecialized()? "yes" : "no"); @@ -1549,7 +1668,7 @@ class PrintExpr : public ExprVisitor { } void visitOverloadedMemberRefExpr(OverloadedMemberRefExpr *E) { printCommon(E, "overloaded_member_ref_expr") - << " name=" << E->getDecls()[0]->getName().str() + << " name=" << E->getDecls()[0]->getName() << " #decls=" << E->getDecls().size() << "\n"; printRec(E->getBase()); for (ValueDecl *D : E->getDecls()) { @@ -1683,7 +1802,7 @@ class PrintExpr : public ExprVisitor { } void visitUnresolvedDotExpr(UnresolvedDotExpr *E) { printCommon(E, "unresolved_dot_expr") - << " field '" << E->getName().str() << "'"; + << " field '" << E->getName() << "'"; if (E->getBase()) { OS << '\n'; printRec(E->getBase()); @@ -1885,24 +2004,37 @@ class PrintExpr : public ExprVisitor { OS << " "; E->getCaptureInfo().print(OS); } + return OS; } - void visitClosureExpr(ClosureExpr *expr) { - printClosure(expr, "closure_expr"); - if (expr->hasSingleExpressionBody()) + void visitClosureExpr(ClosureExpr *E) { + printClosure(E, "closure_expr"); + if (E->hasSingleExpressionBody()) OS << " single-expression"; + + if (E->getParameters()) { + OS << '\n'; + PrintDecl(OS, Indent+2).printParameterList(E->getParameters()); + } + OS << '\n'; - - if (expr->hasSingleExpressionBody()) { - printRec(expr->getSingleExpressionBody()); + if (E->hasSingleExpressionBody()) { + printRec(E->getSingleExpressionBody()); } else { - printRec(expr->getBody()); + printRec(E->getBody()); } OS << ')'; } void visitAutoClosureExpr(AutoClosureExpr *E) { printClosure(E, "autoclosure_expr") << '\n'; + + if (E->getParameters()) { + OS << '\n'; + PrintDecl(OS, Indent+2).printParameterList(E->getParameters()); + } + + OS << '\n'; printRec(E->getSingleExpressionBody()); OS << ')'; } @@ -2166,10 +2298,6 @@ class PrintTypeRepr : public TypeReprVisitor { void visitArrayTypeRepr(ArrayTypeRepr *T) { printCommon(T, "type_array") << '\n'; printRec(T->getBase()); - if (T->getSize()) { - OS << '\n'; - printRec(T->getSize()->getExpr()); - } OS << ')'; } @@ -2282,40 +2410,6 @@ void ProtocolConformance::dump() const { //===----------------------------------------------------------------------===// namespace { - /// RAII object that prints with the given color, if color is supported on the - /// given stream. - class PrintWithColorRAII { - raw_ostream &OS; - bool ShowColors; - - public: - PrintWithColorRAII(raw_ostream &os, llvm::raw_ostream::Colors color) - : OS(os), ShowColors(false) - { - if (&os == &llvm::errs() || &os == &llvm::outs()) - ShowColors = llvm::errs().has_colors() && llvm::outs().has_colors(); - - if (ShowColors) { - if (auto str = llvm::sys::Process::OutputColor(color, false, false)) { - OS << str; - } - } - } - - ~PrintWithColorRAII() { - if (ShowColors) { - OS << llvm::sys::Process::ResetColor(); - } - } - - template - friend raw_ostream &operator<<(PrintWithColorRAII &&printer, - const T &value){ - printer.OS << value; - return printer.OS; - } - }; - class PrintType : public TypeVisitor { raw_ostream &OS; unsigned Indent; @@ -2439,31 +2533,43 @@ namespace { break; case DefaultArgumentKind::Column: - printFlag("default_arg", "__COLUMN__"); + printField("default_arg", "__COLUMN__"); break; case DefaultArgumentKind::DSOHandle: - printFlag("default_arg", "__DSO_HANDLE__"); + printField("default_arg", "__DSO_HANDLE__"); break; case DefaultArgumentKind::File: - printFlag("default_arg", "__FILE__"); + printField("default_arg", "__FILE__"); break; case DefaultArgumentKind::Function: - printFlag("default_arg", "__FUNCTION__"); + printField("default_arg", "__FUNCTION__"); break; case DefaultArgumentKind::Inherited: - printFlag("default_arg", "inherited"); + printField("default_arg", "inherited"); break; case DefaultArgumentKind::Line: - printFlag("default_arg", "__LINE__"); + printField("default_arg", "__LINE__"); + break; + + case DefaultArgumentKind::Nil: + printField("default_arg", "nil"); + break; + + case DefaultArgumentKind::EmptyArray: + printField("default_arg", "[]"); + break; + + case DefaultArgumentKind::EmptyDictionary: + printField("default_arg", "[:]"); break; case DefaultArgumentKind::Normal: - printFlag("default_arg", "normal"); + printField("default_arg", "normal"); break; } diff --git a/lib/AST/ASTNode.cpp b/lib/AST/ASTNode.cpp index 55ee0acabe697..f5e3304e3642c 100644 --- a/lib/AST/ASTNode.cpp +++ b/lib/AST/ASTNode.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 5a9dd3abc451d..d78914af8b343 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -1,8 +1,8 @@ -//===--- ASTPrinter.cpp - Swift Language AST Printer---------------------===// +//===--- ASTPrinter.cpp - Swift Language AST Printer ----------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,6 +23,7 @@ #include "swift/AST/Expr.h" #include "swift/AST/Module.h" #include "swift/AST/NameLookup.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/PrintOptions.h" #include "swift/AST/Stmt.h" #include "swift/AST/TypeVisitor.h" @@ -31,6 +32,7 @@ #include "swift/Basic/Fallthrough.h" #include "swift/Basic/PrimitiveParsing.h" #include "swift/Basic/STLExtras.h" +#include "swift/Basic/StringExtras.h" #include "swift/Parse/Lexer.h" #include "swift/Config.h" #include "swift/Sema/CodeCompletionTypeChecking.h" @@ -120,7 +122,7 @@ std::string ASTPrinter::sanitizeUtf8(StringRef Text) { Builder.append(Data, Data + Step); } else { - // If malformatted, add replacement characters. + // If malformed, add replacement characters. Builder.append(Replacement); } Data += Step; @@ -224,6 +226,9 @@ static bool escapeKeywordInContext(StringRef keyword, PrintNameContext context){ case PrintNameContext::GenericParameter: return keyword != "Self"; + + case PrintNameContext::FunctionParameter: + return !canBeArgumentLabel(keyword); } } @@ -424,15 +429,15 @@ class PrintAST : public ASTVisitor { // is null. if ((Options.PreferTypeRepr && TL.hasLocation()) || TL.getType().isNull()) { - TL.getTypeRepr()->print(Printer, Options); + if (auto repr = TL.getTypeRepr()) + repr->print(Printer, Options); return; } TL.getType().print(Printer, Options); } void printAttributes(const Decl *D); - void printTypedPattern(const TypedPattern *TP, - bool StripOuterSliceType = false); + void printTypedPattern(const TypedPattern *TP); public: void printPattern(const Pattern *pattern); @@ -466,10 +471,11 @@ class PrintAST : public ASTVisitor { /// \returns true if anything was printed. bool printASTNodes(const ArrayRef &Elements, bool NeedIndent = true); - void printOneParameter(const Pattern *BodyPattern, - bool ArgNameIsAPIByDefault, - bool StripOuterSliceType, - bool Curried); + void printOneParameter(const ParamDecl *param, bool Curried, + bool ArgNameIsAPIByDefault); + + void printParameterList(ParameterList *PL, bool isCurried, + std::function isAPINameByDefault); /// \brief Print the function parameters in curried or selector style, /// to match the original function declaration. @@ -507,8 +513,7 @@ void PrintAST::printAttributes(const Decl *D) { D->getAttrs().print(Printer, Options); } -void PrintAST::printTypedPattern(const TypedPattern *TP, - bool StripOuterSliceType) { +void PrintAST::printTypedPattern(const TypedPattern *TP) { auto TheTypeLoc = TP->getTypeLoc(); if (TheTypeLoc.hasLocation()) { // If the outer typeloc is an InOutTypeRepr, print the inout before the @@ -528,13 +533,6 @@ void PrintAST::printTypedPattern(const TypedPattern *TP, printPattern(TP->getSubPattern()); Printer << ": "; - if (StripOuterSliceType) { - Type T = TP->getType(); - if (auto *BGT = T->getAs()) { - BGT->getGenericArgs()[0].print(Printer, Options); - return; - } - } printTypeLoc(TheTypeLoc); return; } @@ -547,12 +545,6 @@ void PrintAST::printTypedPattern(const TypedPattern *TP, printPattern(TP->getSubPattern()); Printer << ": "; - if (StripOuterSliceType) { - if (auto *BGT = T->getAs()) { - BGT->getGenericArgs()[0].print(Printer, Options); - return; - } - } T.print(Printer, Options); } @@ -564,9 +556,8 @@ void PrintAST::printPattern(const Pattern *pattern) { case PatternKind::Named: { auto named = cast(pattern); - recordDeclLoc(named->getDecl(), - [&]{ - Printer.printName(named->getBodyName()); + recordDeclLoc(named->getDecl(), [&]{ + Printer.printName(named->getBoundName()); }); break; } @@ -585,21 +576,8 @@ void PrintAST::printPattern(const Pattern *pattern) { const auto &Elt = Fields[i]; if (i != 0) Printer << ", "; - - if (Elt.hasEllipsis()) { - printTypedPattern(cast(Elt.getPattern()), - /*StripOuterSliceType=*/true); - Printer << "..."; - } else { - printPattern(Elt.getPattern()); - } - if (Elt.getDefaultArgKind() != DefaultArgumentKind::None) { - if (Options.PrintDefaultParameterPlaceholder) - Printer << " = default"; - else if (Options.VarInitializers) { - // FIXME: Print initializer here. - } - } + + printPattern(Elt.getPattern()); } Printer << ")"; break; @@ -900,7 +878,7 @@ void PrintAST::printAccessors(AbstractStorageDecl *ASD) { bool inProtocol = isa(ASD->getDeclContext()); if (inProtocol || (Options.AbstractAccessors && !Options.FunctionDefinitions)) { - bool mutatingGetter = ASD->isGetterMutating(); + bool mutatingGetter = ASD->getGetter() && ASD->isGetterMutating(); bool settable = ASD->isSettable(nullptr); bool nonmutatingSetter = false; if (settable && ASD->isSetterNonMutating() && ASD->isInstanceMember() && @@ -1562,50 +1540,40 @@ void PrintAST::visitParamDecl(ParamDecl *decl) { return visitVarDecl(decl); } -void PrintAST::printOneParameter(const Pattern *BodyPattern, - bool ArgNameIsAPIByDefault, - bool StripOuterSliceType, - bool Curried) { +void PrintAST::printOneParameter(const ParamDecl *param, bool Curried, + bool ArgNameIsAPIByDefault) { auto printArgName = [&]() { // Print argument name. - auto ArgName = BodyPattern->getBoundName(); - auto BodyName = BodyPattern->getBodyName(); + auto ArgName = param->getArgumentName(); + auto BodyName = param->getName(); switch (Options.ArgAndParamPrinting) { case PrintOptions::ArgAndParamPrintingMode::ArgumentOnly: - Printer.printName(ArgName); + Printer.printName(ArgName, PrintNameContext::FunctionParameter); if (!ArgNameIsAPIByDefault && !ArgName.empty()) Printer << " _"; break; case PrintOptions::ArgAndParamPrintingMode::MatchSource: if (ArgName == BodyName && ArgNameIsAPIByDefault) { - Printer.printName(ArgName); + Printer.printName(ArgName, PrintNameContext::FunctionParameter); break; } if (ArgName.empty() && !ArgNameIsAPIByDefault) { - Printer.printName(BodyName); + Printer.printName(BodyName, PrintNameContext::FunctionParameter); break; } SWIFT_FALLTHROUGH; case PrintOptions::ArgAndParamPrintingMode::BothAlways: - Printer.printName(ArgName); + Printer.printName(ArgName, PrintNameContext::FunctionParameter); Printer << " "; - Printer.printName(BodyName); + Printer.printName(BodyName, PrintNameContext::FunctionParameter); break; } Printer << ": "; }; - if (auto *VP = dyn_cast(BodyPattern)) - BodyPattern = VP->getSubPattern(); - auto *TypedBodyPattern = dyn_cast(BodyPattern); - if (!TypedBodyPattern) { - // It was a syntax error. - printArgName(); - return; - } - auto TheTypeLoc = TypedBodyPattern->getTypeLoc(); - if (TheTypeLoc.hasLocation()) { + auto TheTypeLoc = param->getTypeLoc(); + if (TheTypeLoc.getTypeRepr()) { // If the outer typeloc is an InOutTypeRepr, print the 'inout' before the // subpattern. if (auto *IOTR = dyn_cast(TheTypeLoc.getTypeRepr())) { @@ -1619,6 +1587,9 @@ void PrintAST::printOneParameter(const Pattern *BodyPattern, Printer << "inout "; } } else { + if (param->hasType()) + TheTypeLoc = TypeLoc::withoutLoc(param->getType()); + if (Type T = TheTypeLoc.getType()) { if (auto *IOT = T->getAs()) { Printer << "inout "; @@ -1628,9 +1599,9 @@ void PrintAST::printOneParameter(const Pattern *BodyPattern, } // If the parameter is autoclosure, or noescape, print it. This is stored - // on the type of the pattern, not on the typerepr. - if (BodyPattern->hasType()) { - auto bodyCanType = BodyPattern->getType()->getCanonicalType(); + // on the type of the decl, not on the typerepr. + if (param->hasType()) { + auto bodyCanType = param->getType()->getCanonicalType(); if (auto patternType = dyn_cast(bodyCanType)) { switch (patternType->isAutoClosure()*2 + patternType->isNoEscape()) { case 0: break; // neither. @@ -1643,12 +1614,6 @@ void PrintAST::printOneParameter(const Pattern *BodyPattern, printArgName(); - if (StripOuterSliceType && !TheTypeLoc.hasLocation()) { - if (auto *BGT = TypedBodyPattern->getType()->getAs()) { - BGT->getGenericArgs()[0].print(Printer, Options); - return; - } - } auto ContainsFunc = [&] (DeclAttrKind Kind) { return Options.ExcludeAttrList.end() != std::find(Options.ExcludeAttrList. begin(), Options.ExcludeAttrList.end(), Kind); @@ -1667,66 +1632,64 @@ void PrintAST::printOneParameter(const Pattern *BodyPattern, Options.ExcludeAttrList.push_back(DAK_NoEscape); if (!hasAutoClosure) Options.ExcludeAttrList.push_back(DAK_AutoClosure); + + + // If the parameter is variadic, we will print the "..." after it, but we have + // to strip off the added array type. + if (param->isVariadic() && TheTypeLoc.getType()) { + if (auto *BGT = TheTypeLoc.getType()->getAs()) + TheTypeLoc.setType(BGT->getGenericArgs()[0]); + } + printTypeLoc(TheTypeLoc); + + if (param->isVariadic()) + Printer << "..."; // After printing the type, we need to restore what the option used to be. if (!hasNoEscape) RemoveFunc(DAK_NoEscape); if (!hasAutoClosure) RemoveFunc(DAK_AutoClosure); + + + if (Options.PrintDefaultParameterPlaceholder && + param->isDefaultArgument()) { + Printer << " = "; + auto defaultArgStr + = getDefaultArgumentSpelling(param->getDefaultArgumentKind()); + if (defaultArgStr.empty()) + Printer << "default"; + else + Printer << defaultArgStr; + } +} + +void PrintAST::printParameterList(ParameterList *PL, bool isCurried, + std::function isAPINameByDefault) { + Printer << "("; + for (unsigned i = 0, e = PL->size(); i != e; ++i) { + if (i > 0) + Printer << ", "; + + printOneParameter(PL->get(i), isCurried, isAPINameByDefault(i)); + } + Printer << ")"; } void PrintAST::printFunctionParameters(AbstractFunctionDecl *AFD) { - ArrayRef BodyPatterns = AFD->getBodyParamPatterns(); + auto BodyParams = AFD->getParameterLists(); // Skip over the implicit 'self'. - if (AFD->getImplicitSelfDecl()) { - BodyPatterns = BodyPatterns.slice(1); - } + if (AFD->getImplicitSelfDecl()) + BodyParams = BodyParams.slice(1); - for (unsigned CurrPattern = 0, NumPatterns = BodyPatterns.size(); + for (unsigned CurrPattern = 0, NumPatterns = BodyParams.size(); CurrPattern != NumPatterns; ++CurrPattern) { - if (auto *BodyTuple = dyn_cast(BodyPatterns[CurrPattern])) { - Printer << "("; - for (unsigned i = 0, e = BodyTuple->getNumElements(); i != e; ++i) { - if (i > 0) - Printer << ", "; - - // Determine whether the argument name is API by default. - bool ArgNameIsAPIByDefault - = CurrPattern > 0 || AFD->argumentNameIsAPIByDefault(i); - - printOneParameter(BodyTuple->getElement(i).getPattern(), - ArgNameIsAPIByDefault, - BodyTuple->getElement(i).hasEllipsis(), - /*Curried=*/CurrPattern > 0); - auto &CurrElt = BodyTuple->getElement(i); - if (CurrElt.hasEllipsis()) - Printer << "..."; - if (Options.PrintDefaultParameterPlaceholder && - CurrElt.getDefaultArgKind() != DefaultArgumentKind::None) { - if (AFD->getClangDecl() && CurrElt.getPattern()->hasType()) { - // For Clang declarations, figure out the default we're using. - auto CurrType = CurrElt.getPattern()->getType(); - Printer << " = " << CurrType->getInferredDefaultArgString(); - } else { - // Use placeholder anywhere else. - Printer << " = default"; - } - } - } - Printer << ")"; - continue; - } - bool ArgNameIsAPIByDefault - = CurrPattern > 0 || AFD->argumentNameIsAPIByDefault(0); - auto *BodyParen = cast(BodyPatterns[CurrPattern]); - Printer << "("; - printOneParameter(BodyParen->getSubPattern(), - ArgNameIsAPIByDefault, - /*StripOuterSliceType=*/false, - /*Curried=*/CurrPattern > 0); - Printer << ")"; + printParameterList(BodyParams[CurrPattern], /*Curried=*/CurrPattern > 0, + [&](unsigned argNo)->bool { + return CurrPattern > 0 || AFD->argumentNameIsAPIByDefault(argNo); + }); } if (AFD->isBodyThrowing()) { @@ -1797,18 +1760,13 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) { Printer << "nonmutating "; Printer << (decl->isSetter() ? "set" : "willSet"); - auto BodyParams = decl->getBodyParamPatterns(); - auto ValueParam = BodyParams.back()->getSemanticsProvidingPattern(); - if (auto *TP = dyn_cast(ValueParam)) { - if (!TP->isImplicit() && TP->getNumElements() != 0) { - auto *P = TP->getElement(0).getPattern()-> - getSemanticsProvidingPattern(); - Identifier Name = P->getBodyName(); - if (!Name.empty() && !P->isImplicit()) { - Printer << "("; - Printer.printName(Name); - Printer << ")"; - } + auto params = decl->getParameterLists().back(); + if (params->size() != 0 && !params->get(0)->isImplicit()) { + auto Name = params->get(0)->getName(); + if (!Name.empty()) { + Printer << "("; + Printer.printName(Name); + Printer << ")"; } } }); @@ -1926,33 +1884,11 @@ void PrintAST::visitSubscriptDecl(SubscriptDecl *decl) { printDocumentationComment(decl); printAttributes(decl); printAccessibility(decl); - recordDeclLoc(decl, - [&]{ - Printer << "subscript "; - auto *IndicePat = decl->getIndices(); - if (auto *BodyTuple = dyn_cast(IndicePat)) { - Printer << "("; - for (unsigned i = 0, e = BodyTuple->getNumElements(); i != e; ++i) { - if (i > 0) - Printer << ", "; - - printOneParameter(BodyTuple->getElement(i).getPattern(), - /*ArgNameIsAPIByDefault=*/false, - BodyTuple->getElement(i).hasEllipsis(), - /*Curried=*/false); - if (BodyTuple->getElement(i).hasEllipsis()) - Printer << "..."; - } - } else { - auto *BodyParen = cast(IndicePat); - Printer << "("; - printOneParameter(BodyParen->getSubPattern(), - /*ArgNameIsAPIByDefault=*/false, - /*StripOuterSliceType=*/false, - /*Curried=*/false); - } - Printer << ")"; - }); + recordDeclLoc(decl, [&]{ + Printer << "subscript "; + printParameterList(decl->getIndices(), /*Curried=*/false, + /*isAPINameByDefault*/[](unsigned)->bool{return false;}); + }); Printer << " -> "; decl->getElementType().print(Printer, Options); @@ -2384,6 +2320,10 @@ class TypePrinter : public TypeVisitor { case DeclContextKind::AbstractFunctionDecl: visit(cast(DC)->getType()); return; + + case DeclContextKind::SubscriptDecl: + visit(cast(DC)->getType()); + return; } } @@ -2481,7 +2421,7 @@ class TypePrinter : public TypeVisitor { else D = T->getAnyNominal(); - // If we can not find the declaration, be extra careful and print + // If we cannot find the declaration, be extra careful and print // the type qualified. if (!D) return true; @@ -2627,7 +2567,7 @@ class TypePrinter : public TypeVisitor { } if (TD.hasName()) { - Printer.printName(TD.getName()); + Printer.printName(TD.getName(), PrintNameContext::FunctionParameter); Printer << ": "; } @@ -3021,6 +2961,7 @@ class TypePrinter : public TypeVisitor { case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_Out: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_In_Guaranteed: llvm_unreachable("callee convention cannot be indirect"); } @@ -3271,6 +3212,7 @@ static StringRef getStringForParameterConvention(ParameterConvention conv) { case ParameterConvention::Indirect_Out: return "@out "; case ParameterConvention::Indirect_In_Guaranteed: return "@in_guaranteed "; case ParameterConvention::Indirect_Inout: return "@inout "; + case ParameterConvention::Indirect_InoutAliasable: return "@inout_aliasable "; case ParameterConvention::Direct_Owned: return "@owned "; case ParameterConvention::Direct_Unowned: return ""; case ParameterConvention::Direct_Guaranteed: return "@guaranteed "; diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp index 7b0ef70f727f7..4fb1d4fdf03ce 100644 --- a/lib/AST/ASTWalker.cpp +++ b/lib/AST/ASTWalker.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -56,6 +56,7 @@ #include "swift/AST/ASTWalker.h" #include "swift/AST/ASTVisitor.h" #include "swift/AST/ExprHandle.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/PrettyStackTrace.h" using namespace swift; @@ -117,10 +118,14 @@ class Traversal : public ASTVisitorgetIndices())) - SD->setIndices(NewPattern); - else - return true; + visit(SD->getIndices()); return doIt(SD->getElementTypeLoc()); } @@ -261,11 +263,8 @@ class Traversal : public ASTVisitorgetBodyParamPatterns()) { - if (Pattern *NewPattern = doIt(P)) - P = NewPattern; - else - return true; + for (auto PL : AFD->getParameterLists()) { + visit(PL); } if (auto *FD = dyn_cast(AFD)) @@ -312,9 +311,9 @@ class Traversal : public ASTVisitorgetParams())) - expr->setParams(Pat); - else - return nullptr; + visit(expr->getParameters()); if (expr->hasExplicitResultType()) if (doIt(expr->getExplicitResultTypeLoc())) @@ -824,12 +820,13 @@ class Traversal : public ASTVisitorisImplicit() && !P->isTypeLocImplicit() && + doIt(P->getTypeLoc())) + return true; + + if (auto *E = P->getDefaultValue()) { + auto res = doIt(E->getExpr()); + if (!res) return true; + E->setExpr(res, E->alreadyChecked()); + } + } + + return Walker.walkToParameterListPost(PL); + } + public: Traversal(ASTWalker &walker) : Walker(walker) {} @@ -1306,14 +1328,6 @@ Pattern *Traversal::visitTuplePattern(TuplePattern *P) { element.setPattern(newField); else return nullptr; - - if (auto handle = element.getInit()) { - if (auto init = doIt(handle->getExpr())) { - handle->setExpr(init, handle->alreadyChecked()); - } else { - return nullptr; - } - } } return P; } diff --git a/lib/AST/ArchetypeBuilder.cpp b/lib/AST/ArchetypeBuilder.cpp index f32f6896a43ab..4bf9cac47674f 100644 --- a/lib/AST/ArchetypeBuilder.cpp +++ b/lib/AST/ArchetypeBuilder.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,7 +21,7 @@ #include "swift/AST/DiagnosticsSema.h" #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/Module.h" -#include "swift/AST/Pattern.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/ProtocolConformance.h" #include "swift/AST/TypeRepr.h" #include "swift/AST/TypeWalker.h" @@ -736,9 +736,13 @@ bool ArchetypeBuilder::addGenericParameter(GenericTypeParamDecl *GenericParam) { GenericParam->getDeclaredType()->castTo(), RootProtocol, GenericParam->getName()); - - if (!PA) - return true; + + return (!PA); +} + +bool ArchetypeBuilder::addGenericParameterRequirements(GenericTypeParamDecl *GenericParam) { + GenericTypeParamKey Key{GenericParam->getDepth(), GenericParam->getIndex()}; + auto PA = Impl->PotentialArchetypes[Key]; // Add the requirements from the declaration. llvm::SmallPtrSet visited; @@ -854,7 +858,7 @@ bool ArchetypeBuilder::addSameTypeRequirementBetweenArchetypes( T1 = T1->getRepresentative(); T2 = T2->getRepresentative(); - // If the representives are already the same, we're done. + // If the representatives are already the same, we're done. if (T1 == T2) return false; @@ -1384,17 +1388,15 @@ bool ArchetypeBuilder::inferRequirements(TypeLoc type, return walker.hadError(); } -bool ArchetypeBuilder::inferRequirements(Pattern *pattern, +bool ArchetypeBuilder::inferRequirements(ParameterList *params, GenericParamList *genericParams) { - if (!pattern->hasType()) - return true; if (genericParams == nullptr) return false; - // FIXME: Crummy source-location information. - InferRequirementsWalker walker(*this, pattern->getSourceRange().Start, - genericParams->getDepth()); - pattern->getType().walk(walker); - return walker.hadError(); + + bool hadError = false; + for (auto P : *params) + hadError |= inferRequirements(P->getTypeLoc(), genericParams); + return hadError; } /// Perform typo correction on the given nested type, producing the @@ -1771,7 +1773,7 @@ Type ArchetypeBuilder::mapTypeIntoContext(Module *M, assert(genericParamsDepth >= depth); unsigned skipLevels = genericParamsDepth - depth; while (skipLevels > 0) { - myGenericParams = genericParams->getOuterParameters(); + myGenericParams = myGenericParams->getOuterParameters(); assert(myGenericParams && "Wrong number of levels?"); --skipLevels; } @@ -1841,3 +1843,169 @@ bool ArchetypeBuilder::addGenericSignature(GenericSignature *sig, Type ArchetypeBuilder::substDependentType(Type type) { return substConcreteTypesForDependentTypes(*this, type); } + +/// Add the requirements for the given potential archetype and its nested +/// potential archetypes to the set of requirements. +static void +addRequirements( + Module &mod, Type type, + ArchetypeBuilder::PotentialArchetype *pa, + llvm::SmallPtrSet &knownPAs, + SmallVectorImpl &requirements) { + // If the potential archetype has been bound away to a concrete type, + // it needs no requirements. + if (pa->isConcreteType()) + return; + + // Add a value witness marker. + requirements.push_back(Requirement(RequirementKind::WitnessMarker, + type, Type())); + + // Add superclass requirement, if needed. + if (auto superclass = pa->getSuperclass()) { + // FIXME: Distinguish superclass from conformance? + // FIXME: What if the superclass type involves a type parameter? + requirements.push_back(Requirement(RequirementKind::Conformance, + type, superclass)); + } + + // Add conformance requirements. + SmallVector protocols; + for (const auto &conforms : pa->getConformsTo()) { + protocols.push_back(conforms.first); + } + + ProtocolType::canonicalizeProtocols(protocols); + for (auto proto : protocols) { + requirements.push_back(Requirement(RequirementKind::Conformance, + type, proto->getDeclaredType())); + } +} + +static void +addNestedRequirements( + Module &mod, Type type, + ArchetypeBuilder::PotentialArchetype *pa, + llvm::SmallPtrSet &knownPAs, + SmallVectorImpl &requirements) { + using PotentialArchetype = ArchetypeBuilder::PotentialArchetype; + + // Collect the nested types, sorted by name. + // FIXME: Could collect these from the conformance requirements, above. + SmallVector, 16> nestedTypes; + for (const auto &nested : pa->getNestedTypes()) { + // FIXME: Dropping requirements among different associated types of the + // same name. + nestedTypes.push_back(std::make_pair(nested.first, nested.second.front())); + } + std::sort(nestedTypes.begin(), nestedTypes.end(), + OrderPotentialArchetypeByName()); + + // Add requirements for associated types. + for (const auto &nested : nestedTypes) { + auto rep = nested.second->getRepresentative(); + if (knownPAs.insert(rep).second) { + // Form the dependent type that refers to this archetype. + auto assocType = nested.second->getResolvedAssociatedType(); + if (!assocType) + continue; // FIXME: If we do this late enough, there will be no failure. + + // Skip nested types bound to concrete types. + if (rep->isConcreteType()) + continue; + + auto nestedType = DependentMemberType::get(type, assocType, + mod.getASTContext()); + + addRequirements(mod, nestedType, rep, knownPAs, requirements); + addNestedRequirements(mod, nestedType, rep, knownPAs, requirements); + } + } +} + + +/// Collect the set of requirements placed on the given generic parameters and +/// their associated types. +static void collectRequirements(ArchetypeBuilder &builder, + ArrayRef params, + SmallVectorImpl &requirements) { + typedef ArchetypeBuilder::PotentialArchetype PotentialArchetype; + + // Find the "primary" potential archetypes, from which we'll collect all + // of the requirements. + llvm::SmallPtrSet knownPAs; + llvm::SmallVector primary; + for (auto param : params) { + auto pa = builder.resolveArchetype(param); + assert(pa && "Missing potential archetype for generic parameter"); + + // We only care about the representative. + pa = pa->getRepresentative(); + + if (knownPAs.insert(pa).second) + primary.push_back(param); + } + + // Add all of the conformance and superclass requirements placed on the given + // generic parameters and their associated types. + unsigned primaryIdx = 0, numPrimary = primary.size(); + while (primaryIdx < numPrimary) { + unsigned depth = primary[primaryIdx]->getDepth(); + + // For each of the primary potential archetypes, add the requirements. + // Stop when we hit a parameter at a different depth. + // FIXME: This algorithm falls out from the way the "all archetypes" lists + // are structured. Once those lists no longer exist or are no longer + // "the truth", we can simplify this algorithm considerably. + unsigned lastPrimaryIdx = primaryIdx; + for (unsigned idx = primaryIdx; + idx < numPrimary && primary[idx]->getDepth() == depth; + ++idx, ++lastPrimaryIdx) { + auto param = primary[idx]; + auto pa = builder.resolveArchetype(param)->getRepresentative(); + + // Add other requirements. + addRequirements(builder.getModule(), param, pa, knownPAs, + requirements); + } + + // For each of the primary potential archetypes, add the nested requirements. + for (unsigned idx = primaryIdx; idx < lastPrimaryIdx; ++idx) { + auto param = primary[idx]; + auto pa = builder.resolveArchetype(param)->getRepresentative(); + addNestedRequirements(builder.getModule(), param, pa, knownPAs, + requirements); + } + + primaryIdx = lastPrimaryIdx; + } + + + // Add all of the same-type requirements. + for (auto req : builder.getSameTypeRequirements()) { + auto firstType = req.first->getDependentType(builder, false); + Type secondType; + if (auto concrete = req.second.dyn_cast()) + secondType = concrete; + else if (auto secondPA = req.second.dyn_cast()) + secondType = secondPA->getDependentType(builder, false); + + if (firstType->is() || secondType->is() || + firstType->isEqual(secondType)) + continue; + + requirements.push_back(Requirement(RequirementKind::SameType, + firstType, secondType)); + } +} + +GenericSignature *ArchetypeBuilder::getGenericSignature( + ArrayRef genericParamTypes) { + // Collect the requirements placed on the generic parameter types. + SmallVector requirements; + collectRequirements(*this, genericParamTypes, requirements); + + auto sig = GenericSignature::get(genericParamTypes, requirements); + return sig; +} + diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp index ad6a0be0fc831..4a75337d806aa 100644 --- a/lib/AST/Attr.cpp +++ b/lib/AST/Attr.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -383,6 +383,10 @@ void DeclAttribute::print(ASTPrinter &Printer, break; } + case DAK_MigrationId: + // Not printed. + return; + case DAK_Count: llvm_unreachable("exceed declaration attribute kinds"); } @@ -477,6 +481,8 @@ StringRef DeclAttribute::getAttrName() const { return "<>"; case DAK_WarnUnusedResult: return "warn_unused_result"; + case DAK_MigrationId: + return "_migration_id"; } llvm_unreachable("bad DeclAttrKind"); } diff --git a/lib/AST/Availability.cpp b/lib/AST/Availability.cpp index 34c864a012025..21035e9b0e71d 100644 --- a/lib/AST/Availability.cpp +++ b/lib/AST/Availability.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -127,7 +127,7 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) { for (auto Attr : D->getAttrs()) { auto *AvailAttr = dyn_cast(Attr); - if (AvailAttr == NULL || !AvailAttr->Introduced.hasValue() || + if (AvailAttr == nullptr || !AvailAttr->Introduced.hasValue() || !AvailAttr->isActivePlatform(Ctx)) { continue; } diff --git a/lib/AST/AvailabilitySpec.cpp b/lib/AST/AvailabilitySpec.cpp index a985d5c0c8127..5060a32931d15 100644 --- a/lib/AST/AvailabilitySpec.cpp +++ b/lib/AST/AvailabilitySpec.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index b85f398a1f4e5..2af6000098e57 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,7 +22,6 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/LLVMContext.h" -#include #include using namespace swift; @@ -132,43 +131,38 @@ StringRef swift::getBuiltinBaseName(ASTContext &C, StringRef Name, /// Build a builtin function declaration. static FuncDecl * -getBuiltinFunction(Identifier Id, - ArrayRef ArgTypes, - Type ResType, +getBuiltinFunction(Identifier Id, ArrayRef argTypes, Type ResType, FunctionType::ExtInfo Info = FunctionType::ExtInfo()) { auto &Context = ResType->getASTContext(); - Type ArgType = TupleType::get(ArgTypes, Context); + + SmallVector tupleElts; + for (Type argType : argTypes) + tupleElts.push_back(argType); + + Type ArgType = TupleType::get(tupleElts, Context); Type FnType; FnType = FunctionType::get(ArgType, ResType, Info); Module *M = Context.TheBuiltinModule; DeclContext *DC = &M->getMainFile(FileUnitKind::Builtin); - SmallVector ParamPatternElts; - for (auto &ArgTupleElt : ArgTypes) { + SmallVector params; + for (Type argType : argTypes) { auto PD = new (Context) ParamDecl(/*IsLet*/true, SourceLoc(), Identifier(), SourceLoc(), - Identifier(), ArgTupleElt.getType(), + Identifier(), argType, DC); PD->setImplicit(); - Pattern *Pat = new (Context) NamedPattern(PD, /*implicit=*/true); - Pat = new (Context) TypedPattern(Pat, - TypeLoc::withoutLoc(ArgTupleElt.getType()), /*implicit=*/true); - PD->setParamParentPattern(Pat); - - ParamPatternElts.push_back(TuplePatternElt(Pat)); + params.push_back(PD); } - Pattern *ParamPattern = TuplePattern::createSimple( - Context, SourceLoc(), ParamPatternElts, SourceLoc()); - - llvm::SmallVector ArgNames(ParamPattern->numTopLevelVariables(), - Identifier()); - DeclName Name(Context, Id, ArgNames); + auto *paramList = ParameterList::create(Context, params); + + DeclName Name(Context, Id, paramList); auto FD = FuncDecl::create(Context, SourceLoc(), StaticSpellingKind::None, SourceLoc(), Name, SourceLoc(), SourceLoc(), SourceLoc(), /*GenericParams=*/nullptr, FnType, - ParamPattern, TypeLoc::withoutLoc(ResType), DC); + paramList, TypeLoc::withoutLoc(ResType), DC); FD->setImplicit(); FD->setAccessibility(Accessibility::Public); return FD; @@ -178,20 +172,15 @@ getBuiltinFunction(Identifier Id, static FuncDecl * getBuiltinGenericFunction(Identifier Id, ArrayRef ArgParamTypes, - ArrayRef ArgBodyTypes, + ArrayRef ArgBodyTypes, Type ResType, Type ResBodyType, GenericParamList *GenericParams, - FunctionType::ExtInfo Info = FunctionType::ExtInfo()) { + FunctionType::ExtInfo Info = FunctionType::ExtInfo()){ assert(GenericParams && "Missing generic parameters"); auto &Context = ResType->getASTContext(); Type ArgParamType = TupleType::get(ArgParamTypes, Context); - Type ArgBodyType = TupleType::get(ArgBodyTypes, Context); - - // Compute the function type. - Type FnType = PolymorphicFunctionType::get(ArgBodyType, ResBodyType, - GenericParams, Info); // Compute the interface type. SmallVector GenericParamTypes; @@ -215,31 +204,27 @@ getBuiltinGenericFunction(Identifier Id, Module *M = Context.TheBuiltinModule; DeclContext *DC = &M->getMainFile(FileUnitKind::Builtin); - SmallVector ParamPatternElts; - for (auto &ArgTupleElt : ArgBodyTypes) { + SmallVector params; + for (auto paramType : ArgBodyTypes) { auto PD = new (Context) ParamDecl(/*IsLet*/true, SourceLoc(), Identifier(), SourceLoc(), - Identifier(), ArgTupleElt.getType(), - DC); + Identifier(), paramType, DC); PD->setImplicit(); - Pattern *Pat = new (Context) NamedPattern(PD, /*implicit=*/true); - Pat = new (Context) TypedPattern(Pat, - TypeLoc::withoutLoc(ArgTupleElt.getType()), /*implicit=*/true); - PD->setParamParentPattern(Pat); - - ParamPatternElts.push_back(TuplePatternElt(Pat)); + params.push_back(PD); } - Pattern *ParamPattern = TuplePattern::createSimple( - Context, SourceLoc(), ParamPatternElts, SourceLoc()); - llvm::SmallVector ArgNames( - ParamPattern->numTopLevelVariables(), - Identifier()); - DeclName Name(Context, Id, ArgNames); + + auto *paramList = ParameterList::create(Context, params); + + // Compute the function type. + Type FnType = PolymorphicFunctionType::get(paramList->getType(Context), + ResBodyType, GenericParams, Info); + + DeclName Name(Context, Id, paramList); auto func = FuncDecl::create(Context, SourceLoc(), StaticSpellingKind::None, SourceLoc(), Name, SourceLoc(), SourceLoc(), SourceLoc(), - GenericParams, FnType, ParamPattern, + GenericParams, FnType, paramList, TypeLoc::withoutLoc(ResBodyType), DC); func->setInterfaceType(InterfaceType); @@ -254,16 +239,14 @@ static ValueDecl *getGepOperation(Identifier Id, Type ArgType) { auto &Context = ArgType->getASTContext(); // This is always "(i8*, IntTy) -> i8*" - TupleTypeElt ArgElts[] = { Context.TheRawPointerType, ArgType }; + Type ArgElts[] = { Context.TheRawPointerType, ArgType }; Type ResultTy = Context.TheRawPointerType; return getBuiltinFunction(Id, ArgElts, ResultTy); } /// Build a binary operation declaration. static ValueDecl *getBinaryOperation(Identifier Id, Type ArgType) { - TupleTypeElt ArgElts[] = { ArgType, ArgType }; - Type ResultTy = ArgType; - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { ArgType, ArgType }, ArgType); } /// Build a declaration for a binary operation with overflow. @@ -271,7 +254,7 @@ static ValueDecl *getBinaryOperationWithOverflow(Identifier Id, Type ArgType) { auto &Context = ArgType->getASTContext(); Type ShouldCheckForOverflowTy = BuiltinIntegerType::get(1, Context); - TupleTypeElt ArgElts[] = { ArgType, ArgType, ShouldCheckForOverflowTy }; + Type ArgElts[] = { ArgType, ArgType, ShouldCheckForOverflowTy }; Type OverflowBitTy = BuiltinIntegerType::get(1, Context); TupleTypeElt ResultElts[] = { ArgType, OverflowBitTy }; Type ResultTy = TupleType::get(ResultElts, Context); @@ -279,16 +262,14 @@ static ValueDecl *getBinaryOperationWithOverflow(Identifier Id, } static ValueDecl *getUnaryOperation(Identifier Id, Type ArgType) { - TupleTypeElt ArgElts[] = { ArgType }; - Type ResultTy = ArgType; - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { ArgType }, ArgType); } /// Build a binary predicate declaration. static ValueDecl *getBinaryPredicate(Identifier Id, Type ArgType) { auto &Context = ArgType->getASTContext(); - TupleTypeElt ArgElts[] = { ArgType, ArgType }; + Type ArgElts[] = { ArgType, ArgType }; Type ResultTy = BuiltinIntegerType::get(1, Context); if (auto VecTy = ArgType->getAs()) { ResultTy = BuiltinVectorType::get(Context, ResultTy, @@ -425,8 +406,7 @@ static ValueDecl *getCastOperation(ASTContext &Context, Identifier Id, return nullptr; } - TupleTypeElt ArgElts[] = { Input }; - return getBuiltinFunction(Id, ArgElts, Output); + return getBuiltinFunction(Id, { Input }, Output); } static const char * const GenericParamNames[] = { @@ -481,7 +461,7 @@ namespace { SmallVector Archetypes; SmallVector InterfaceParams; - SmallVector BodyParams; + SmallVector BodyParams; Type InterfaceResult; Type BodyResult; @@ -683,16 +663,22 @@ static ValueDecl *getIsPODOperation(ASTContext &Context, Identifier Id) { return builder.build(Id); } +static ValueDecl *getIsOptionalOperation(ASTContext &Context, Identifier Id) { + GenericSignatureBuilder builder(Context); + builder.addParameter(makeMetatype(makeGenericParam())); + builder.setResult(makeConcrete(BuiltinIntegerType::get(1,Context))); + return builder.build(Id); +} + static ValueDecl *getAllocOperation(ASTContext &Context, Identifier Id) { Type PtrSizeTy = BuiltinIntegerType::getWordType(Context); - TupleTypeElt ArgElts[] = { PtrSizeTy, PtrSizeTy }; Type ResultTy = Context.TheRawPointerType; - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { PtrSizeTy, PtrSizeTy }, ResultTy); } static ValueDecl *getDeallocOperation(ASTContext &Context, Identifier Id) { auto PtrSizeTy = BuiltinIntegerType::getWordType(Context); - TupleTypeElt ArgElts[] = { Context.TheRawPointerType, PtrSizeTy, PtrSizeTy }; + Type ArgElts[] = { Context.TheRawPointerType, PtrSizeTy, PtrSizeTy }; Type ResultTy = TupleType::getEmpty(Context); return getBuiltinFunction(Id, ArgElts, ResultTy); } @@ -715,32 +701,26 @@ static ValueDecl *getUnexpectedErrorOperation(ASTContext &Context, static ValueDecl *getCmpXChgOperation(ASTContext &Context, Identifier Id, Type T) { - TupleTypeElt ArgElts[] = { Context.TheRawPointerType, T, T }; + Type ArgElts[] = { Context.TheRawPointerType, T, T }; Type BoolTy = BuiltinIntegerType::get(1, Context); - TupleTypeElt ResultElts[] = { T, BoolTy }; - Type ResultTy = TupleType::get(ResultElts, Context); + Type ResultTy = TupleType::get({ T, BoolTy }, Context); return getBuiltinFunction(Id, ArgElts, ResultTy); } static ValueDecl *getAtomicRMWOperation(ASTContext &Context, Identifier Id, Type T) { - TupleTypeElt ArgElts[] = { Context.TheRawPointerType, T }; - Type ResultTy = T; - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { Context.TheRawPointerType, T }, T); } static ValueDecl *getAtomicLoadOperation(ASTContext &Context, Identifier Id, Type T) { - TupleTypeElt ArgElts[] = { Context.TheRawPointerType }; - Type ResultTy = T; - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { Type(Context.TheRawPointerType) }, T); } static ValueDecl *getAtomicStoreOperation(ASTContext &Context, Identifier Id, Type T) { - TupleTypeElt ArgElts[] = { Context.TheRawPointerType, T }; - Type ResultTy = Context.TheEmptyTupleType; - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { Context.TheRawPointerType, T }, + Context.TheEmptyTupleType); } static ValueDecl *getNativeObjectCast(ASTContext &Context, Identifier Id, @@ -783,8 +763,6 @@ static ValueDecl *getCastFromBridgeObjectOperation(ASTContext &C, Identifier Id, BuiltinValueKind BV) { Type BridgeTy = C.TheBridgeObjectType; - TupleTypeElt ArgElts[] = { BridgeTy }; - switch (BV) { case BuiltinValueKind::CastReferenceFromBridgeObject: { GenericSignatureBuilder builder(C); @@ -795,7 +773,7 @@ static ValueDecl *getCastFromBridgeObjectOperation(ASTContext &C, case BuiltinValueKind::CastBitPatternFromBridgeObject: { Type WordTy = BuiltinIntegerType::get(BuiltinIntegerWidth::pointer(), C); - return getBuiltinFunction(Id, ArgElts, WordTy); + return getBuiltinFunction(Id, { BridgeTy }, WordTy); } default: @@ -861,16 +839,13 @@ static ValueDecl *getCondFailOperation(ASTContext &C, Identifier Id) { // Int1 -> () auto CondTy = BuiltinIntegerType::get(1, C); auto VoidTy = TupleType::getEmpty(C); - TupleTypeElt CondElt(CondTy); - return getBuiltinFunction(Id, CondElt, VoidTy); + return getBuiltinFunction(Id, {CondTy}, VoidTy); } static ValueDecl *getAssertConfOperation(ASTContext &C, Identifier Id) { // () -> Int32 auto Int32Ty = BuiltinIntegerType::get(32, C); - auto VoidTy = TupleType::getEmpty(C); - TupleTypeElt EmptyElt(VoidTy); - return getBuiltinFunction(Id, EmptyElt, Int32Ty); + return getBuiltinFunction(Id, {}, Int32Ty); } static ValueDecl *getFixLifetimeOperation(ASTContext &C, Identifier Id) { @@ -892,9 +867,8 @@ static ValueDecl *getExtractElementOperation(ASTContext &Context, Identifier Id, if (!IndexTy || !IndexTy->isFixedWidth() || IndexTy->getFixedWidth() != 32) return nullptr; - TupleTypeElt ArgElts[] = { VecTy, IndexTy }; Type ResultTy = VecTy->getElementType(); - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { VecTy, IndexTy }, ResultTy); } static ValueDecl *getInsertElementOperation(ASTContext &Context, Identifier Id, @@ -913,16 +887,15 @@ static ValueDecl *getInsertElementOperation(ASTContext &Context, Identifier Id, if (!IndexTy || !IndexTy->isFixedWidth() || IndexTy->getFixedWidth() != 32) return nullptr; - TupleTypeElt ArgElts[] = { VecTy, ElementTy, IndexTy }; - Type ResultTy = VecTy; - return getBuiltinFunction(Id, ArgElts, ResultTy); + Type ArgElts[] = { VecTy, ElementTy, IndexTy }; + return getBuiltinFunction(Id, ArgElts, VecTy); } static ValueDecl *getStaticReportOperation(ASTContext &Context, Identifier Id) { auto BoolTy = BuiltinIntegerType::get(1, Context); auto MessageTy = Context.TheRawPointerType; - TupleTypeElt ArgElts[] = { BoolTy, BoolTy, MessageTy }; + Type ArgElts[] = { BoolTy, BoolTy, MessageTy }; Type ResultTy = TupleType::getEmpty(Context); return getBuiltinFunction(Id, ArgElts, ResultTy); @@ -939,12 +912,10 @@ static ValueDecl *getCheckedTruncOperation(ASTContext &Context, if (InTy->getLeastWidth() < OutTy->getGreatestWidth()) return nullptr; - TupleTypeElt ArgElts[] = { InTy }; Type OverflowBitTy = BuiltinIntegerType::get(1, Context); TupleTypeElt ResultElts[] = { OutTy, OverflowBitTy }; Type ResultTy = TupleType::get(ResultElts, Context); - - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { InTy }, ResultTy); } static ValueDecl *getCheckedConversionOperation(ASTContext &Context, @@ -954,12 +925,10 @@ static ValueDecl *getCheckedConversionOperation(ASTContext &Context, if (!BuiltinTy) return nullptr; - TupleTypeElt ArgElts[] = { BuiltinTy }; Type SignErrorBitTy = BuiltinIntegerType::get(1, Context); TupleTypeElt ResultElts[] = { BuiltinTy, SignErrorBitTy }; Type ResultTy = TupleType::get(ResultElts, Context); - - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { BuiltinTy }, ResultTy); } static ValueDecl *getIntToFPWithOverflowOperation(ASTContext &Context, @@ -970,10 +939,7 @@ static ValueDecl *getIntToFPWithOverflowOperation(ASTContext &Context, if (!InTy || !OutTy) return nullptr; - TupleTypeElt ArgElts[] = { InTy }; - Type ResultTy = OutTy; - - return getBuiltinFunction(Id, ArgElts, ResultTy); + return getBuiltinFunction(Id, { InTy }, OutTy); } static ValueDecl *getUnreachableOperation(ASTContext &Context, @@ -994,11 +960,7 @@ static ValueDecl *getOnceOperation(ASTContext &Context, /*noreturn*/ false, /*throws*/ false); auto BlockTy = FunctionType::get(VoidTy, VoidTy, Thin); - - TupleTypeElt InFields[] = {HandleTy, BlockTy}; - auto OutTy = VoidTy; - - return getBuiltinFunction(Id, InFields, OutTy); + return getBuiltinFunction(Id, {HandleTy, BlockTy}, VoidTy); } static ValueDecl *getTryPinOperation(ASTContext &ctx, Identifier name) { @@ -1225,7 +1187,7 @@ static Type DecodeIntrinsicType(ArrayRef &Table, static bool getSwiftFunctionTypeForIntrinsic(unsigned iid, ArrayRef TypeArgs, ASTContext &Context, - SmallVectorImpl &ArgElts, + SmallVectorImpl &ArgElts, Type &ResultTy, FunctionType::ExtInfo &Info) { llvm::Intrinsic::ID ID = (llvm::Intrinsic::ID)iid; @@ -1320,7 +1282,7 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) { // If this is the name of an LLVM intrinsic, cons up a swift function with a // type that matches the IR types. if (unsigned ID = getLLVMIntrinsicID(OperationName, !Types.empty())) { - SmallVector ArgElts; + SmallVector ArgElts; Type ResultTy; FunctionType::ExtInfo Info; if (getSwiftFunctionTypeForIntrinsic(ID, Types, Context, ArgElts, ResultTy, @@ -1582,6 +1544,9 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) { case BuiltinValueKind::IsPOD: return getIsPODOperation(Context, Id); + case BuiltinValueKind::IsOptionalType: + return getIsOptionalOperation(Context, Id); + case BuiltinValueKind::AllocRaw: return getAllocOperation(Context, Id); diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index f4f888a1e72d2..8f659fbdb2e8c 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -14,6 +14,7 @@ add_swift_library(swiftAST ConformanceLookupTable.cpp Decl.cpp DeclContext.cpp + DefaultArgumentKind.cpp DiagnosticList.cpp DiagnosticEngine.cpp DocComment.cpp @@ -25,6 +26,7 @@ add_swift_library(swiftAST Module.cpp ModuleNameLookup.cpp NameLookup.cpp + Parameter.cpp Pattern.cpp PlatformKind.cpp PrettyStackTrace.cpp diff --git a/lib/AST/CaptureInfo.cpp b/lib/AST/CaptureInfo.cpp index 21b51e4871497..6de67d3a0ce5d 100644 --- a/lib/AST/CaptureInfo.cpp +++ b/lib/AST/CaptureInfo.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/ConcreteDeclRef.cpp b/lib/AST/ConcreteDeclRef.cpp index 55813deac9ba8..bf9499c1424f5 100644 --- a/lib/AST/ConcreteDeclRef.cpp +++ b/lib/AST/ConcreteDeclRef.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/ConformanceLookupTable.cpp b/lib/AST/ConformanceLookupTable.cpp index e109506048cf4..2cd09301a7b1b 100644 --- a/lib/AST/ConformanceLookupTable.cpp +++ b/lib/AST/ConformanceLookupTable.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -149,7 +149,7 @@ void ConformanceLookupTable::forEachInStage(ConformanceStage stage, lastProcessed.setInt(true); // If we have conformances we can load, do so. - // FIXME: This could be more lazy. + // FIXME: This could be lazier. auto loader = nominal->takeConformanceLoader(); if (loader.first) { SmallVector conformances; @@ -179,7 +179,7 @@ void ConformanceLookupTable::forEachInStage(ConformanceStage stage, lastProcessed.setPointer(next); // If we have conformances we can load, do so. - // FIXME: This could be more lazy. + // FIXME: This could be lazier. auto loader = next->takeConformanceLoader(); if (loader.first) { SmallVector conformances; @@ -487,10 +487,14 @@ void ConformanceLookupTable::addProtocols(NominalTypeDecl *nominal, void ConformanceLookupTable::expandImpliedConformances(NominalTypeDecl *nominal, DeclContext *dc, LazyResolver *resolver) { - // Note: recursive type-checking implies that that AllConformances + // Note: recursive type-checking implies that AllConformances // may be reallocated during this traversal, so pay the lookup cost // during each iteration. for (unsigned i = 0; i != AllConformances[dc].size(); ++i) { + /// FIXME: Avoid the possibility of an infinite loop by fixing the root + /// cause instead (incomplete circularity detection). + assert(i <= 16384 && + "Infinite loop due to circular protocol inheritance?"); ConformanceEntry *conformanceEntry = AllConformances[dc][i]; ProtocolDecl *conformingProtocol = conformanceEntry->getProtocol(); @@ -543,7 +547,7 @@ ConformanceLookupTable::Ordering ConformanceLookupTable::compareConformances( bool &diagnoseSuperseded) { // If one entry is fixed and the other is not, we have our answer. if (lhs->isFixed() != rhs->isFixed()) { - // If the non-fixed conformance is not replacable, we have a failure to + // If the non-fixed conformance is not replaceable, we have a failure to // diagnose. diagnoseSuperseded = (lhs->isFixed() && !isReplaceable(rhs->getRankingKind())) || diff --git a/lib/AST/ConformanceLookupTable.h b/lib/AST/ConformanceLookupTable.h index 63493b9323278..dbe5569b66504 100644 --- a/lib/AST/ConformanceLookupTable.h +++ b/lib/AST/ConformanceLookupTable.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 151c6841e4f36..9267d5e4800f8 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,6 +25,7 @@ #include "swift/AST/ForeignErrorConvention.h" #include "swift/AST/LazyResolver.h" #include "swift/AST/Mangle.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/TypeLoc.h" #include "clang/Lex/MacroInfo.h" #include "llvm/ADT/SmallString.h" @@ -72,13 +73,13 @@ const clang::Module *ClangNode::getClangModule() const { } // Only allow allocation of Decls using the allocator in ASTContext. -void *Decl::operator new(size_t Bytes, ASTContext &C, +void *Decl::operator new(size_t Bytes, const ASTContext &C, unsigned Alignment) { return C.Allocate(Bytes, Alignment); } // Only allow allocation of Modules using the allocator in ASTContext. -void *Module::operator new(size_t Bytes, ASTContext &C, +void *Module::operator new(size_t Bytes, const ASTContext &C, unsigned Alignment) { return C.Allocate(Bytes, Alignment); } @@ -398,16 +399,12 @@ bool Decl::isPrivateStdlibDecl(bool whitelistProtocols) const { FU->getKind() != FileUnitKind::SerializedAST) return false; - auto hasInternalParameter = [](ArrayRef Pats) -> bool { - bool hasInternalParam = false; - for (auto Pat : Pats) { - Pat->forEachVariable([&](VarDecl *Param) { - if (Param->hasName() && Param->getNameStr().startswith("_")) { - hasInternalParam = true; - } - }); + auto hasInternalParameter = [](const ParameterList *params) -> bool { + for (auto param : *params) { + if (param->hasName() && param->getNameStr().startswith("_")) + return true; } - return hasInternalParam; + return false; }; if (auto AFD = dyn_cast(D)) { @@ -418,8 +415,9 @@ bool Decl::isPrivateStdlibDecl(bool whitelistProtocols) const { // If it's a function with a parameter with leading underscore, it's a // private function. - if (hasInternalParameter(AFD->getBodyParamPatterns())) - return true; + for (auto *PL : AFD->getParameterLists()) + if (hasInternalParameter(PL)) + return true; } if (auto SubscriptD = dyn_cast(D)) { @@ -1183,7 +1181,7 @@ ValueDecl::getAccessSemanticsFromContext(const DeclContext *UseDC) const { // "StoredWithTrivialAccessors" are generally always accessed indirectly, // but if we know that the trivial accessor will always produce the same - // thing as the getter/setter (i.e., it can't be overriden), then just do a + // thing as the getter/setter (i.e., it can't be overridden), then just do a // direct access. // // This is true in structs and for final properties. @@ -1550,7 +1548,7 @@ static Type mapSignatureFunctionType(ASTContext &ctx, Type type, for (const auto &elt : tupleTy->getElements()) { Type eltTy = mapSignatureParamType(ctx, elt.getType()); if (anyChanged || eltTy.getPointer() != elt.getType().getPointer() || - elt.hasInit()) { + elt.getDefaultArgKind() != DefaultArgumentKind::None) { if (!anyChanged) { elements.reserve(tupleTy->getNumElements()); for (unsigned i = 0; i != idx; ++i) { @@ -1619,7 +1617,7 @@ OverloadSignature ValueDecl::getOverloadSignature() const { /*topLevelFunction=*/true, /*isMethod=*/afd->getImplicitSelfDecl() != nullptr, /*isInitializer=*/isa(afd), - afd->getNumParamPatterns())->getCanonicalType(); + afd->getNumParameterLists())->getCanonicalType(); signature.IsInstanceMember = isInstanceMember(); // Unary operators also include prefix/postfix. @@ -1737,19 +1735,6 @@ void ValueDecl::overwriteType(Type T) { setInvalid(); } -DeclContext *ValueDecl::getPotentialGenericDeclContext() { - if (auto func = dyn_cast(this)) - return func; - if (auto NTD = dyn_cast(this)) - return NTD; - - auto parentDC = getDeclContext(); - if (parentDC->isTypeContext()) - return parentDC; - - return nullptr; -} - Type ValueDecl::getInterfaceType() const { if (InterfaceTy) return InterfaceTy; @@ -1922,13 +1907,6 @@ void NominalTypeDecl::setGenericSignature(GenericSignature *sig) { GenericSig = sig; } -void NominalTypeDecl::markInvalidGenericSignature() { - ASTContext &ctx = getASTContext(); - overwriteType(ErrorType::get(ctx)); - if (!getDeclaredType()) - setDeclaredType(ErrorType::get(ctx)); -} - void NominalTypeDecl::computeType() { assert(!hasType() && "Nominal type declaration already has a type"); @@ -2292,7 +2270,7 @@ bool ClassDecl::inheritsSuperclassInitializers(LazyResolver *resolver) { } // All of the direct superclass's designated initializers have been overridden - // by the sublcass. Initializers can be inherited. + // by the subclass. Initializers can be inherited. ClassDeclBits.InheritsSuperclassInits = static_cast(StoredInheritsSuperclassInits::Inherited); return true; @@ -2336,15 +2314,13 @@ ObjCClassKind ClassDecl::checkObjCAncestry() const { static StringRef mangleObjCRuntimeName(const NominalTypeDecl *nominal, llvm::SmallVectorImpl &buffer) { { - buffer.clear(); - llvm::raw_svector_ostream os(buffer); + // Mangle the type. + Mangle::Mangler mangler(false/*dwarf*/, false/*punycode*/); // We add the "_Tt" prefix to make this a reserved name that will // not conflict with any valid Objective-C class or protocol name. - os << "_Tt"; + mangler.append("_Tt"); - // Mangle the type. - Mangle::Mangler mangler(os, false/*dwarf*/, false/*punycode*/); NominalTypeDecl *NTD = const_cast(nominal); if (isa(nominal)) { mangler.mangleNominalType(NTD, @@ -2353,8 +2329,13 @@ static StringRef mangleObjCRuntimeName(const NominalTypeDecl *nominal, } else { mangler.mangleProtocolDecl(cast(NTD)); } + + buffer.clear(); + llvm::raw_svector_ostream os(buffer); + mangler.finalize(os); } + assert(buffer.size() && "Invalid buffer size"); return StringRef(buffer.data(), buffer.size()); } @@ -2378,10 +2359,11 @@ ArtificialMainKind ClassDecl::getArtificialMainKind() const { llvm_unreachable("class has no @ApplicationMain attr?!"); } -FuncDecl *ClassDecl::findOverridingDecl(const FuncDecl *Method) const { +AbstractFunctionDecl * +ClassDecl::findOverridingDecl(const AbstractFunctionDecl *Method) const { auto Members = getMembers(); for (auto M : Members) { - FuncDecl *CurMethod = dyn_cast(M); + AbstractFunctionDecl *CurMethod = dyn_cast(M); if (!CurMethod) continue; if (CurMethod->isOverridingDecl(Method)) { @@ -2391,12 +2373,24 @@ FuncDecl *ClassDecl::findOverridingDecl(const FuncDecl *Method) const { return nullptr; } -FuncDecl * ClassDecl::findImplementingMethod(const FuncDecl *Method) const { +bool AbstractFunctionDecl::isOverridingDecl( + const AbstractFunctionDecl *Method) const { + const AbstractFunctionDecl *CurMethod = this; + while (CurMethod) { + if (CurMethod == Method) + return true; + CurMethod = CurMethod->getOverriddenDecl(); + } + return false; +} + +AbstractFunctionDecl * +ClassDecl::findImplementingMethod(const AbstractFunctionDecl *Method) const { const ClassDecl *C = this; while (C) { auto Members = C->getMembers(); for (auto M : Members) { - FuncDecl *CurMethod = dyn_cast(M); + AbstractFunctionDecl *CurMethod = dyn_cast(M); if (!CurMethod) continue; if (Method == CurMethod) @@ -2479,7 +2473,7 @@ bool ProtocolDecl::inheritsFrom(const ProtocolDecl *super) const { bool ProtocolDecl::requiresClassSlow() { ProtocolDeclBits.RequiresClass = false; - // Ensure that the result can not change in future. + // Ensure that the result cannot change in future. assert(isInheritedProtocolsValid() || isBeingTypeChecked()); if (getAttrs().hasAttribute() || isObjC()) { @@ -3158,12 +3152,13 @@ SourceRange VarDecl::getSourceRange() const { } SourceRange VarDecl::getTypeSourceRangeForDiagnostics() const { - Pattern *Pat = nullptr; - if (ParentPattern.is()) - Pat = ParentPattern.dyn_cast(); - else - Pat = getParentPattern(); + // For a parameter, map back to its parameter to get the TypeLoc. + if (auto *PD = dyn_cast(this)) { + if (auto typeRepr = PD->getTypeLoc().getTypeRepr()) + return typeRepr->getSourceRange(); + } + Pattern *Pat = getParentPattern(); if (!Pat || Pat->isImplicit()) return getSourceRange(); @@ -3225,8 +3220,11 @@ Pattern *VarDecl::getParentPattern() const { return nullptr; } -bool VarDecl::isImplicitSelf() const { - return isImplicit() && getName() == getASTContext().Id_self; +bool VarDecl::isSelfParameter() const { + // Note: we need to check the isImplicit() bit here to make sure that we + // don't classify explicit parameters declared with `self` as the self param. + return isa(this) && getName() == getASTContext().Id_self && + isImplicit(); } /// Return true if this stored property needs to be accessed with getters and @@ -3306,12 +3304,9 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const { // If it isn't a 'let', don't touch it. if (!isLet()) return; - // Don't suggest mutability for explicit function parameters - if (isa(this) && !isImplicitSelf()) return; - // If this is the 'self' argument of a non-mutating method in a value type, // suggest adding 'mutating' to the method. - if (isImplicitSelf() && UseDC) { + if (isSelfParameter() && UseDC) { // If the problematic decl is 'self', then we might be trying to mutate // a property in a non-mutating method. auto FD = dyn_cast(UseDC->getInnermostMethodContext()); @@ -3325,6 +3320,9 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const { } } + // Besides self, don't suggest mutability for explicit function parameters. + if (isa(this)) return; + // If this is a normal variable definition, then we can change 'let' to 'var'. // We even are willing to suggest this for multi-variable binding, like // "let (a,b) = " @@ -3341,6 +3339,120 @@ void VarDecl::emitLetToVarNoteIfSimple(DeclContext *UseDC) const { } } +ParamDecl::ParamDecl(bool isLet, SourceLoc argumentNameLoc, + Identifier argumentName, SourceLoc parameterNameLoc, + Identifier parameterName, Type ty, DeclContext *dc) + : VarDecl(DeclKind::Param, /*IsStatic=*/false, isLet, parameterNameLoc, + parameterName, ty, dc), + ArgumentName(argumentName), ArgumentNameLoc(argumentNameLoc) { +} + +/// Clone constructor, allocates a new ParamDecl identical to the first. +/// Intentionally not defined as a copy constructor to avoid accidental copies. +ParamDecl::ParamDecl(ParamDecl *PD) + : VarDecl(DeclKind::Param, /*IsStatic=*/false, PD->isLet(), PD->getNameLoc(), + PD->getName(), PD->hasType() ? PD->getType() : Type(), + PD->getDeclContext()), + ArgumentName(PD->getArgumentName()), + ArgumentNameLoc(PD->getArgumentNameLoc()), + typeLoc(PD->getTypeLoc()), + DefaultValueAndIsVariadic(PD->DefaultValueAndIsVariadic), + IsTypeLocImplicit(PD->IsTypeLocImplicit), + defaultArgumentKind(PD->defaultArgumentKind) { +} + + +/// \brief Retrieve the type of 'self' for the given context. +static Type getSelfTypeForContext(DeclContext *dc) { + // For a protocol or extension thereof, the type is 'Self'. + // FIXME: Weird that we're producing an archetype for protocol Self, + // but the declared type of the context in non-protocol cases. + if (dc->isProtocolOrProtocolExtensionContext()) { + // In the parser, generic parameters won't be wired up yet, just give up on + // producing a type. + if (dc->getGenericParamsOfContext() == nullptr) + return Type(); + return dc->getProtocolSelf()->getArchetype(); + } + return dc->getDeclaredTypeOfContext(); +} + + +/// Create an implicit 'self' decl for a method in the specified decl context. +/// If 'static' is true, then this is self for a static method in the type. +/// +/// Note that this decl is created, but it is returned with an incorrect +/// DeclContext that needs to be set correctly. This is automatically handled +/// when a function is created with this as part of its argument list. +/// +ParamDecl *ParamDecl::createSelf(SourceLoc loc, DeclContext *DC, + bool isStaticMethod, bool isInOut) { + ASTContext &C = DC->getASTContext(); + auto selfType = getSelfTypeForContext(DC); + + // If we have a selfType (i.e. we're not in the parser before we know such + // things, configure it. + if (selfType) { + if (isStaticMethod) + selfType = MetatypeType::get(selfType); + + if (isInOut) + selfType = InOutType::get(selfType); + } + + auto *selfDecl = new (C) ParamDecl(/*IsLet*/!isInOut, SourceLoc(), + Identifier(), loc, C.Id_self, selfType,DC); + selfDecl->setImplicit(); + return selfDecl; +} + +/// Return the full source range of this parameter. +SourceRange ParamDecl::getSourceRange() const { + SourceRange range; + + SourceLoc APINameLoc = getArgumentNameLoc(); + SourceLoc nameLoc = getNameLoc(); + + if (APINameLoc.isValid() && nameLoc.isInvalid()) + range = APINameLoc; + else if (APINameLoc.isInvalid() && nameLoc.isValid()) + range = nameLoc; + else + range = SourceRange(APINameLoc, nameLoc); + + if (range.isInvalid()) return range; + + // It would be nice to extend the front of the range to show where inout is, + // but we don't have that location info. Extend the back of the range to the + // location of the default argument, or the typeloc if they are valid. + if (auto expr = getDefaultValue()) { + auto endLoc = expr->getExpr()->getEndLoc(); + if (endLoc.isValid()) + return SourceRange(range.Start, endLoc); + } + + // If the typeloc has a valid location, use it to end the range. + if (auto typeRepr = getTypeLoc().getTypeRepr()) { + auto endLoc = typeRepr->getEndLoc(); + if (endLoc.isValid()) + return SourceRange(range.Start, endLoc); + } + + // Otherwise, just return the info we have about the parameter. + return range; +} + +Type ParamDecl::getVarargBaseTy(Type VarArgT) { + TypeBase *T = VarArgT.getPointer(); + if (ArraySliceType *AT = dyn_cast(T)) + return AT->getBaseType(); + if (BoundGenericType *BGT = dyn_cast(T)) { + // It's the stdlib Array. + return BGT->getGenericArgs()[0]; + } + assert(isa(T)); + return T; +} /// Determine whether the given Swift type is an integral type, i.e., /// a type that wraps a builtin integer. @@ -3371,14 +3483,18 @@ static bool isIntegralType(Type type) { return false; } -void SubscriptDecl::setIndices(Pattern *p) { +void SubscriptDecl::setIndices(ParameterList *p) { Indices = p; - // FIXME: What context should the indices patterns be in? + if (Indices) + Indices->setDeclContextOfParamDecls(this); } Type SubscriptDecl::getIndicesType() const { - return getType()->castTo()->getInput(); + const auto type = getType(); + if (type->is()) + return type; + return type->castTo()->getInput(); } Type SubscriptDecl::getIndicesInterfaceType() const { @@ -3423,8 +3539,7 @@ SourceRange SubscriptDecl::getSourceRange() const { static Type getSelfTypeForContainer(AbstractFunctionDecl *theMethod, bool isInitializingCtor, - bool wantInterfaceType, - GenericParamList **outerGenericParams) { + bool wantInterfaceType) { auto *dc = theMethod->getDeclContext(); // Determine the type of the container. @@ -3475,10 +3590,6 @@ static Type getSelfTypeForContainer(AbstractFunctionDecl *theMethod, } } - // Capture the generic parameters, if requested. - if (outerGenericParams) - *outerGenericParams = dc->getGenericParamsOfContext(); - // If the self type couldn't be computed, or is the result of an // upstream error, return an error type. if (!selfTy || selfTy->is()) @@ -3518,7 +3629,8 @@ DeclName AbstractFunctionDecl::getEffectiveFullName() const { case AccessorKind::IsMutableAddressor: case AccessorKind::IsGetter: return subscript ? subscript->getFullName() - : DeclName(ctx, afd->getName(), { }); + : DeclName(ctx, afd->getName(), + ArrayRef()); case AccessorKind::IsSetter: case AccessorKind::IsMaterializeForSet: @@ -3554,32 +3666,26 @@ void AbstractFunctionDecl::setGenericParams(GenericParamList *GP) { } -Type AbstractFunctionDecl:: -computeSelfType(GenericParamList **outerGenericParams) { - return getSelfTypeForContainer(this, true, false, outerGenericParams); +Type AbstractFunctionDecl::computeSelfType() { + return getSelfTypeForContainer(this, true, false); } Type AbstractFunctionDecl::computeInterfaceSelfType(bool isInitializingCtor) { - return getSelfTypeForContainer(this, isInitializingCtor, true, nullptr); + return getSelfTypeForContainer(this, isInitializingCtor, true); } /// \brief This method returns the implicit 'self' decl. /// /// Note that some functions don't have an implicit 'self' decl, for example, /// free functions. In this case nullptr is returned. -VarDecl *AbstractFunctionDecl::getImplicitSelfDecl() const { - ArrayRef ParamPatterns = getBodyParamPatterns(); - if (ParamPatterns.empty()) +ParamDecl *AbstractFunctionDecl::getImplicitSelfDecl() { + auto paramLists = getParameterLists(); + if (paramLists.empty()) return nullptr; - // "self" is represented as (typed_pattern (named_pattern (var_decl 'self')). - const Pattern *P = ParamPatterns[0]->getSemanticsProvidingPattern(); - - // The decl should be named 'self' and be implicit. - auto NP = dyn_cast(P); - if (NP && NP->isImplicit() && - NP->getDecl()->getName() == getASTContext().Id_self) - return NP->getDecl(); + // "self" is always the first parameter list. + if (paramLists[0]->size() == 1 && paramLists[0]->get(0)->isSelfParameter()) + return paramLists[0]->get(0); return nullptr; } @@ -3589,43 +3695,21 @@ Type AbstractFunctionDecl::getExtensionType() const { std::pair AbstractFunctionDecl::getDefaultArg(unsigned Index) const { - ArrayRef Patterns = getBodyParamPatterns(); - - if (getImplicitSelfDecl()) { - // Skip the 'self' parameter; it is not counted. - Patterns = Patterns.slice(1); - } - - // Find the (sub-)pattern for this index. - // FIXME: This is O(n), which is lame. We should fix the FuncDecl - // representation. - const TuplePatternElt *Found = nullptr; - for (auto OrigPattern : Patterns) { - auto Params = - dyn_cast(OrigPattern->getSemanticsProvidingPattern()); - if (!Params) { - if (Index == 0) { - return { DefaultArgumentKind::None, Type() }; - } + auto paramLists = getParameterLists(); - --Index; - continue; - } + if (getImplicitSelfDecl()) // Skip the 'self' parameter; it is not counted. + paramLists = paramLists.slice(1); - for (auto &Elt : Params->getElements()) { - if (Index == 0) { - Found = &Elt; - break; - } - --Index; + for (auto paramList : paramLists) { + if (Index < paramList->size()) { + auto param = paramList->get(Index); + return { param->getDefaultArgumentKind(), param->getType() }; } - - if (Found) - break; + + Index -= paramList->size(); } - assert(Found && "No argument with this index"); - return { Found->getDefaultArgKind(), Found->getPattern()->getType() }; + llvm_unreachable("Invalid parameter index"); } bool AbstractFunctionDecl::argumentNameIsAPIByDefault(unsigned i) const { @@ -3671,15 +3755,14 @@ SourceRange AbstractFunctionDecl::getSignatureSourceRange() const { if (isImplicit()) return SourceRange(); - auto Pats = getBodyParamPatterns(); - if (Pats.empty()) + auto paramLists = getParameterLists(); + if (paramLists.empty()) return getNameLoc(); - for (int I = Pats.size() - 1; I >= 0; I--) { - auto endLoc = Pats[I]->getEndLoc(); - if (endLoc.isValid()) { + for (auto *paramList : reversed(paramLists)) { + auto endLoc = paramList->getSourceRange().End; + if (endLoc.isValid()) return SourceRange(getNameLoc(), endLoc); - } } return getNameLoc(); } @@ -3823,15 +3906,6 @@ AbstractFunctionDecl *AbstractFunctionDecl::getOverriddenDecl() const { return nullptr; } -/// Set the DeclContext of any VarDecls in P to the specified DeclContext. -static void setDeclContextOfPatternVars(Pattern *P, DeclContext *DC) { - if (!P) return; - P->forEachVariable([&](VarDecl *VD) { - assert(isa(VD) && "Pattern variable is not a parameter?"); - VD->setDeclContext(DC); - }); -} - FuncDecl *FuncDecl::createImpl(ASTContext &Context, SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, @@ -3876,7 +3950,7 @@ FuncDecl *FuncDecl::create(ASTContext &Context, SourceLoc StaticLoc, SourceLoc NameLoc, SourceLoc ThrowsLoc, SourceLoc AccessorKeywordLoc, GenericParamList *GenericParams, - Type Ty, ArrayRef BodyParams, + Type Ty, ArrayRef BodyParams, TypeLoc FnRetType, DeclContext *Parent, ClangNode ClangN) { const unsigned NumParamPatterns = BodyParams.size(); @@ -3902,15 +3976,13 @@ bool FuncDecl::isExplicitNonMutating() const { !getDeclContext()->getDeclaredTypeInContext()->hasReferenceSemantics(); } -void FuncDecl::setDeserializedSignature(ArrayRef BodyParams, +void FuncDecl::setDeserializedSignature(ArrayRef BodyParams, TypeLoc FnRetType) { - MutableArrayRef BodyParamsRef = getBodyParamPatterns(); + MutableArrayRef BodyParamsRef = getParameterLists(); unsigned NumParamPatterns = BodyParamsRef.size(); #ifndef NDEBUG - unsigned NumParams = getDeclContext()->isTypeContext() - ? BodyParams[1]->numTopLevelVariables() - : BodyParams[0]->numTopLevelVariables(); + unsigned NumParams = BodyParams[getDeclContext()->isTypeContext()]->size(); auto Name = getFullName(); assert((!Name || !Name.isSimpleName()) && "Must have a simple name"); assert(!Name || (Name.getArgumentNames().size() == NumParams)); @@ -3921,7 +3993,8 @@ void FuncDecl::setDeserializedSignature(ArrayRef BodyParams, // Set the decl context of any vardecls to this FuncDecl. for (auto P : BodyParams) - setDeclContextOfPatternVars(P, this); + if (P) + P->setDeclContextOfParamDecls(this); this->FnRetType = FnRetType; } @@ -3965,12 +4038,8 @@ bool FuncDecl::isUnaryOperator() const { unsigned opArgIndex = getDeclContext()->isProtocolOrProtocolExtensionContext() ? 1 : 0; - auto *argTuple = dyn_cast(getBodyParamPatterns()[opArgIndex]); - if (!argTuple) - return true; - - return argTuple->getNumElements() == 1 && - !argTuple->getElement(0).hasEllipsis(); + auto *params = getParameterList(opArgIndex); + return params->size() == 1 && !params->get(0)->isVariadic(); } bool FuncDecl::isBinaryOperator() const { @@ -3980,29 +4049,15 @@ bool FuncDecl::isBinaryOperator() const { unsigned opArgIndex = getDeclContext()->isProtocolOrProtocolExtensionContext() ? 1 : 0; - auto *argTuple = dyn_cast(getBodyParamPatterns()[opArgIndex]); - if (!argTuple) - return false; - - return argTuple->getNumElements() == 2 - || (argTuple->getNumElements() == 1 && - argTuple->getElement(0).hasEllipsis()); -} - -bool FuncDecl::isOverridingDecl(const FuncDecl *Method) const { - const FuncDecl *CurMethod = this; - while (CurMethod) { - if (CurMethod == Method) - return true; - CurMethod = CurMethod->getOverriddenDecl(); - } - return false; + auto *params = getParameterList(opArgIndex); + return params->size() == 2 && !params->get(1)->isVariadic(); } ConstructorDecl::ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc, OptionalTypeKind Failability, SourceLoc FailabilityLoc, - Pattern *SelfBodyParam, Pattern *BodyParams, + ParamDecl *selfDecl, + ParameterList *BodyParams, GenericParamList *GenericParams, SourceLoc throwsLoc, DeclContext *Parent) @@ -4010,7 +4065,7 @@ ConstructorDecl::ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc, ConstructorLoc, 2, GenericParams), FailabilityLoc(FailabilityLoc), ThrowsLoc(throwsLoc) { - setBodyParams(SelfBodyParam, BodyParams); + setParameterLists(selfDecl, BodyParams); ConstructorDeclBits.ComputedBodyInitKind = 0; ConstructorDeclBits.InitKind @@ -4019,16 +4074,22 @@ ConstructorDecl::ConstructorDecl(DeclName Name, SourceLoc ConstructorLoc, this->Failability = static_cast(Failability); } -void ConstructorDecl::setBodyParams(Pattern *selfPattern, Pattern *bodyParams) { - BodyParams[0] = selfPattern; - BodyParams[1] = bodyParams; - setDeclContextOfPatternVars(selfPattern, this); - setDeclContextOfPatternVars(bodyParams, this); +void ConstructorDecl::setParameterLists(ParamDecl *selfDecl, + ParameterList *bodyParams) { + if (selfDecl) { + ParameterLists[0] = ParameterList::createWithoutLoc(selfDecl); + ParameterLists[0]->setDeclContextOfParamDecls(this); + } else { + ParameterLists[0] = nullptr; + } + + ParameterLists[1] = bodyParams; + if (bodyParams) + bodyParams->setDeclContextOfParamDecls(this); assert(!getFullName().isSimpleName() && "Constructor name must be compound"); assert(!bodyParams || - (getFullName().getArgumentNames().size() - == bodyParams->numTopLevelVariables())); + (getFullName().getArgumentNames().size() == bodyParams->size())); } bool ConstructorDecl::isObjCZeroParameterWithLongSelector() const { @@ -4037,31 +4098,27 @@ bool ConstructorDecl::isObjCZeroParameterWithLongSelector() const { getFullName().getArgumentNames()[0].empty()) return false; - const Pattern *paramPattern = getBodyParamPatterns()[1]; - Type paramType; - if (auto tuplePattern = dyn_cast(paramPattern)) { - if (tuplePattern->getNumElements() != 1 || - tuplePattern->getElement(0).hasEllipsis()) - return false; - - paramType = tuplePattern->getElement(0).getPattern()->getType(); - } else { - paramType = paramPattern->getType(); - } + auto *params = getParameterList(1); + if (params->size() != 1) + return false; - return paramType->isVoid(); + return params->get(0)->getType()->isVoid(); } DestructorDecl::DestructorDecl(Identifier NameHack, SourceLoc DestructorLoc, - Pattern *SelfPattern, DeclContext *Parent) + ParamDecl *selfDecl, DeclContext *Parent) : AbstractFunctionDecl(DeclKind::Destructor, Parent, NameHack, DestructorLoc, 1, nullptr) { - setSelfPattern(SelfPattern); + setSelfDecl(selfDecl); } -void DestructorDecl::setSelfPattern(Pattern *selfPattern) { - SelfPattern = selfPattern; - setDeclContextOfPatternVars(SelfPattern, this); +void DestructorDecl::setSelfDecl(ParamDecl *selfDecl) { + if (selfDecl) { + SelfParameter = ParameterList::createWithoutLoc(selfDecl); + SelfParameter->setDeclContextOfParamDecls(this); + } else { + SelfParameter = nullptr; + } } @@ -4118,9 +4175,9 @@ SourceRange FuncDecl::getSourceRange() const { getBodyResultTypeLoc().getSourceRange().End.isValid() && !this->isAccessor()) return { StartLoc, getBodyResultTypeLoc().getSourceRange().End }; - const Pattern *LastPat = getBodyParamPatterns().back(); - if (!LastPat->isImplicit()) - return { StartLoc, LastPat->getEndLoc() }; + auto LastParamListEndLoc = getParameterLists().back()->getSourceRange().End; + if (LastParamListEndLoc.isValid()) + return { StartLoc, LastParamListEndLoc }; return StartLoc; } @@ -4142,8 +4199,9 @@ void EnumElementDecl::computeType() { if (getArgumentType()) resultTy = FunctionType::get(getArgumentType(), resultTy); - if (auto gp = ED->getGenericParamsOfContext()) - resultTy = PolymorphicFunctionType::get(argTy, resultTy, gp); + if (ED->isGenericTypeContext()) + resultTy = PolymorphicFunctionType::get(argTy, resultTy, + ED->getGenericParamsOfContext()); else resultTy = FunctionType::get(argTy, resultTy); diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp index aa4b3afb56a1a..dc847fd76e61a 100644 --- a/lib/AST/DeclContext.cpp +++ b/lib/AST/DeclContext.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -46,6 +46,7 @@ DeclContext::isNominalTypeOrNominalTypeExtensionContext() const { case DeclContextKind::AbstractClosureExpr: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: case DeclContextKind::Initializer: case DeclContextKind::SerializedLocal: return nullptr; @@ -107,6 +108,7 @@ Type DeclContext::getDeclaredTypeOfContext() const { case DeclContextKind::AbstractClosureExpr: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: case DeclContextKind::Initializer: case DeclContextKind::SerializedLocal: return Type(); @@ -144,6 +146,7 @@ Type DeclContext::getDeclaredTypeInContext() const { case DeclContextKind::AbstractClosureExpr: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: case DeclContextKind::Initializer: case DeclContextKind::SerializedLocal: return Type(); @@ -178,6 +181,7 @@ Type DeclContext::getDeclaredInterfaceType() const { case DeclContextKind::AbstractClosureExpr: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: case DeclContextKind::Initializer: case DeclContextKind::SerializedLocal: return Type(); @@ -195,89 +199,85 @@ Type DeclContext::getDeclaredInterfaceType() const { } GenericParamList *DeclContext::getGenericParamsOfContext() const { - switch (getContextKind()) { - case DeclContextKind::Module: - case DeclContextKind::FileUnit: - case DeclContextKind::TopLevelCodeDecl: - return nullptr; - - case DeclContextKind::SerializedLocal: - case DeclContextKind::Initializer: - case DeclContextKind::AbstractClosureExpr: - // Closures and initializers can't themselves be generic, but they - // can occur in generic contexts. - return getParent()->getGenericParamsOfContext(); - - case DeclContextKind::AbstractFunctionDecl: { - auto *AFD = cast(this); - if (auto GP = AFD->getGenericParams()) - return GP; - - // If we're within a type context, pick up the generic signature - // of that context. - if (AFD->getDeclContext()->isTypeContext()) - return AFD->getDeclContext()->getGenericParamsOfContext(); - - return nullptr; - } + for (const DeclContext *dc = this; ; dc = dc->getParent()) { + switch (dc->getContextKind()) { + case DeclContextKind::Module: + case DeclContextKind::FileUnit: + case DeclContextKind::TopLevelCodeDecl: + return nullptr; - case DeclContextKind::NominalTypeDecl: { - auto nominal = cast(this); - if (auto gp = nominal->getGenericParams()) - return gp; + case DeclContextKind::SerializedLocal: + case DeclContextKind::Initializer: + case DeclContextKind::AbstractClosureExpr: + case DeclContextKind::SubscriptDecl: + // Closures and initializers can't themselves be generic, but they + // can occur in generic contexts. + continue; - if (nominal->getDeclContext()->isTypeContext()) - return nominal->getDeclContext()->getGenericParamsOfContext(); + case DeclContextKind::AbstractFunctionDecl: { + auto *AFD = cast(dc); + if (auto GP = AFD->getGenericParams()) + return GP; + continue; + } - return nullptr; - } + case DeclContextKind::NominalTypeDecl: { + auto NTD = cast(dc); + if (auto GP = NTD->getGenericParams()) + return GP; + continue; + } - case DeclContextKind::ExtensionDecl: - return cast(this)->getGenericParams(); + case DeclContextKind::ExtensionDecl: { + auto ED = cast(dc); + if (auto GP = ED->getGenericParams()) + return GP; + continue; + } + } + llvm_unreachable("bad DeclContextKind"); } - llvm_unreachable("bad DeclContextKind"); } GenericSignature *DeclContext::getGenericSignatureOfContext() const { - switch (getContextKind()) { - case DeclContextKind::Module: - case DeclContextKind::FileUnit: - case DeclContextKind::TopLevelCodeDecl: - case DeclContextKind::AbstractClosureExpr: - case DeclContextKind::Initializer: - case DeclContextKind::SerializedLocal: - return nullptr; + for (const DeclContext *dc = this; ; dc = dc->getParent()) { + switch (dc->getContextKind()) { + case DeclContextKind::Module: + case DeclContextKind::FileUnit: + case DeclContextKind::TopLevelCodeDecl: + return nullptr; - case DeclContextKind::AbstractFunctionDecl: { - auto *AFD = cast(this); - if (auto GFT = AFD->getInterfaceType()->getAs()) - return GFT->getGenericSignature(); - - // If we're within a type context, pick up the generic signature - // of that context. - if (AFD->getDeclContext()->isTypeContext()) - return AFD->getDeclContext()->getGenericSignatureOfContext(); - - return nullptr; - } + case DeclContextKind::Initializer: + case DeclContextKind::SerializedLocal: + case DeclContextKind::AbstractClosureExpr: + case DeclContextKind::SubscriptDecl: + // Closures and initializers can't themselves be generic, but they + // can occur in generic contexts. + continue; - case DeclContextKind::NominalTypeDecl: { - auto nominal = cast(this); - if (auto genericSig = nominal->getGenericSignature()) - return genericSig; - - // If we're within a type context, pick up the generic signature - // of that context. - if (nominal->getDeclContext()->isTypeContext()) - return nominal->getDeclContext()->getGenericSignatureOfContext(); - - return nullptr; - } + case DeclContextKind::AbstractFunctionDecl: { + auto *AFD = cast(dc); + if (auto genericSig = AFD->getGenericSignature()) + return genericSig; + continue; + } - case DeclContextKind::ExtensionDecl: - return cast(this)->getGenericSignature(); + case DeclContextKind::NominalTypeDecl: { + auto NTD = cast(dc); + if (auto genericSig = NTD->getGenericSignature()) + return genericSig; + continue; + } + + case DeclContextKind::ExtensionDecl: { + auto ED = cast(dc); + if (auto genericSig = ED->getGenericSignature()) + return genericSig; + continue; + } + } + llvm_unreachable("bad DeclContextKind"); } - llvm_unreachable("bad DeclContextKind"); } DeclContext *DeclContext::getLocalContext() { @@ -315,6 +315,7 @@ AbstractFunctionDecl *DeclContext::getInnermostMethodContext() { case DeclContextKind::Module: case DeclContextKind::NominalTypeDecl: case DeclContextKind::TopLevelCodeDecl: + case DeclContextKind::SubscriptDecl: // Not in a method context. return nullptr; } @@ -329,6 +330,7 @@ DeclContext *DeclContext::getInnermostTypeContext() { case DeclContextKind::Initializer: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: case DeclContextKind::SerializedLocal: Result = Result->getParent(); continue; @@ -361,6 +363,9 @@ Decl *DeclContext::getInnermostDeclarationDeclContext() { case DeclContextKind::AbstractFunctionDecl: return cast(DC); + case DeclContextKind::SubscriptDecl: + return cast(DC); + case DeclContextKind::NominalTypeDecl: return cast(DC); @@ -404,15 +409,17 @@ DeclContext *DeclContext::getModuleScopeContext() const { /// Determine whether the given context is generic at any level. bool DeclContext::isGenericContext() const { - for (const DeclContext *dc = this; ; dc = dc->getParent() ) { + for (const DeclContext *dc = this; ; dc = dc->getParent()) { switch (dc->getContextKind()) { case DeclContextKind::Module: case DeclContextKind::FileUnit: + case DeclContextKind::TopLevelCodeDecl: return false; case DeclContextKind::Initializer: case DeclContextKind::AbstractClosureExpr: case DeclContextKind::SerializedLocal: + case DeclContextKind::SubscriptDecl: // Check parent context. continue; @@ -421,10 +428,6 @@ bool DeclContext::isGenericContext() const { return true; continue; - case DeclContextKind::TopLevelCodeDecl: - // Check parent context. - continue; - case DeclContextKind::NominalTypeDecl: if (cast(dc)->getGenericParams()) return true; @@ -440,6 +443,36 @@ bool DeclContext::isGenericContext() const { llvm_unreachable("illegal declcontext hierarchy"); } +/// Determine whether the given context nested inside a generic type context +/// with no local contexts in between. +bool DeclContext::isGenericTypeContext() const { + for (const auto *dc = this; dc->isTypeContext(); dc = dc->getParent()) { + if (dc->isInnermostContextGeneric()) + return true; + } + + return false; +} + +/// Determine the maximum depth of the current generic type context's generic +/// parameters. If the current context is not a generic type context, returns +/// the maximum depth of any generic parameter in this context. +unsigned DeclContext::getGenericTypeContextDepth() const { + unsigned depth = 0; + bool inTypeContext = true; + for (const auto *dc = this; dc; dc = dc->getParent()) { + // Starting from the innermost context that is not a type context, count + // all parent contexts that have generic parameters. + if (!dc->isTypeContext()) + inTypeContext = false; + + if (!inTypeContext && dc->isInnermostContextGeneric()) + depth++; + } + + return depth; +} + /// Determine whether the innermost context is generic. bool DeclContext::isInnermostContextGeneric() const { switch (getContextKind()) { @@ -485,6 +518,13 @@ DeclContext::isCascadingContextForLookup(bool functionsAreNonCascading) const { break; } + case DeclContextKind::SubscriptDecl: { + auto *SD = cast(this); + if (SD->hasAccessibility()) + return SD->getFormalAccess() > Accessibility::Private; + break; + } + case DeclContextKind::Module: case DeclContextKind::FileUnit: return true; @@ -532,6 +572,8 @@ bool DeclContext::walkContext(ASTWalker &Walker) { return cast(this)->walk(Walker); case DeclContextKind::AbstractFunctionDecl: return cast(this)->walk(Walker); + case DeclContextKind::SubscriptDecl: + return cast(this)->walk(Walker); case DeclContextKind::SerializedLocal: llvm_unreachable("walk is unimplemented for deserialized contexts"); case DeclContextKind::Initializer: @@ -605,6 +647,7 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const { case DeclContextKind::AbstractFunctionDecl: Kind = "AbstractFunctionDecl"; break; + case DeclContextKind::SubscriptDecl: Kind = "SubscriptDecl"; break; } OS.indent(Depth*2 + indent) << "0x" << (void*)this << " " << Kind; @@ -652,6 +695,15 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const { OS << " : (no type set)"; break; } + case DeclContextKind::SubscriptDecl: { + auto *SD = cast(this); + OS << " name=" << SD->getName(); + if (SD->hasType()) + OS << " : " << SD->getType(); + else + OS << " : (no type set)"; + break; + } case DeclContextKind::Initializer: switch (cast(this)->getInitializerKind()) { case InitializerKind::PatternBinding: { @@ -782,13 +834,7 @@ void IterableDeclContext::loadAllMembers() const { break; } - bool hasMissingRequiredMembers = false; - resolver->loadAllMembers(const_cast< Decl *>(container), contextData, - &hasMissingRequiredMembers); - - if (hasMissingRequiredMembers) - if (auto proto = dyn_cast(this)) - const_cast(proto)->setHasMissingRequirements(true); + resolver->loadAllMembers(const_cast< Decl *>(container), contextData); --NumUnloadedLazyIterableDeclContexts; } diff --git a/lib/AST/DefaultArgumentKind.cpp b/lib/AST/DefaultArgumentKind.cpp new file mode 100644 index 0000000000000..bbc70a70f16f5 --- /dev/null +++ b/lib/AST/DefaultArgumentKind.cpp @@ -0,0 +1,106 @@ +//===--- DefaultArgumentKind.cpp - Default Argument Implementation --------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file implements utilities associated with default arguments. +// +//===----------------------------------------------------------------------===// +#include "swift/AST/DefaultArgumentKind.h" +#include "swift/AST/ASTContext.h" +#include "swift/AST/Decl.h" +#include "swift/AST/Expr.h" +using namespace swift; + +StringRef swift::getDefaultArgumentSpelling(DefaultArgumentKind kind) { + switch (kind) { + case DefaultArgumentKind::None: + case DefaultArgumentKind::Normal: + case DefaultArgumentKind::Inherited: + return StringRef(); + + case DefaultArgumentKind::File: + return "__FILE__"; + + case DefaultArgumentKind::Line: + return "__LINE__"; + + case DefaultArgumentKind::Column: + return "__COLUMN__"; + + case DefaultArgumentKind::Function: + return "__FUNCTION__"; + + case DefaultArgumentKind::DSOHandle: + return "__DSO_HANDLE__"; + + case DefaultArgumentKind::Nil: + return "nil"; + + case DefaultArgumentKind::EmptyArray: + return "[]"; + + case DefaultArgumentKind::EmptyDictionary: + return "[:]"; + } +} + +DefaultArgumentKind swift::inferDefaultArgumentKind(Expr *expr) { + if (auto call = dyn_cast(expr)) { + if (auto ctorRefCall = dyn_cast(call->getFn())) { + if (auto ctorRef = dyn_cast(ctorRefCall->getFn())) { + if (auto ctor = dyn_cast(ctorRef->getDecl())) { + auto ctorArg = call->getArg()->getSemanticsProvidingExpr(); + + // __FILE__, __LINE__, __COLUMN__, __FUNCTION__, __DSO_HANDLE__. + if (auto magic = dyn_cast(ctorArg)) { + switch (magic->getKind()) { + case MagicIdentifierLiteralExpr::File: + return DefaultArgumentKind::File; + case MagicIdentifierLiteralExpr::Line: + return DefaultArgumentKind::Line; + case MagicIdentifierLiteralExpr::Column: + return DefaultArgumentKind::Column; + case MagicIdentifierLiteralExpr::Function: + return DefaultArgumentKind::Function; + case MagicIdentifierLiteralExpr::DSOHandle: + return DefaultArgumentKind::DSOHandle; + } + } + + // nil. + if (ctor->getFullName().getArgumentNames().size() == 1 && + ctor->getFullName().getArgumentNames()[0] + == ctor->getASTContext().Id_nilLiteral) + return DefaultArgumentKind::Nil; + } + } + } + } + + // Empty array literals, []. + if (auto arrayExpr = dyn_cast(expr)) { + if (arrayExpr->getElements().empty()) + return DefaultArgumentKind::EmptyArray; + + return DefaultArgumentKind::None; + } + + // Empty dictionary literals, [:]. + if (auto dictionaryExpr = dyn_cast(expr)) { + if (dictionaryExpr->getElements().empty()) + return DefaultArgumentKind::EmptyDictionary; + + return DefaultArgumentKind::None; + } + + return DefaultArgumentKind::None; +} + diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp index 7053457995264..52482ad67d692 100644 --- a/lib/AST/DiagnosticEngine.cpp +++ b/lib/AST/DiagnosticEngine.cpp @@ -1,8 +1,8 @@ -//===- DiagnosticEngine.h - Diagnostic Display Engine -----------*- C++ -*-===// +//===--- DiagnosticEngine.cpp - Diagnostic Display Engine -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -502,12 +502,6 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) { // If a declaration was provided instead of a location, and that declaration // has a location we can point to, use that location. loc = decl->getLoc(); - // With an implicit parameter try to point to its type. - if (loc.isInvalid() && isa(decl)) { - if (auto Pat = - cast(decl)->getParamParentPattern()) - loc = Pat->getLoc(); - } if (loc.isInvalid()) { // There is no location we can point to. Pretty-print the declaration @@ -564,6 +558,7 @@ void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) { case DeclContextKind::Initializer: case DeclContextKind::AbstractClosureExpr: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: break; } diff --git a/lib/AST/DiagnosticList.cpp b/lib/AST/DiagnosticList.cpp index 95c4f7c62e79c..062a4d5dad1b7 100644 --- a/lib/AST/DiagnosticList.cpp +++ b/lib/AST/DiagnosticList.cpp @@ -1,8 +1,8 @@ -//===- DiagnosticList.cpp - Diagnostic Definitions ------------------------===// +//===--- DiagnosticList.cpp - Diagnostic Definitions ----------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/DocComment.cpp b/lib/AST/DocComment.cpp index 4e3900cd5915e..44787fd9298ee 100644 --- a/lib/AST/DocComment.cpp +++ b/lib/AST/DocComment.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 96146d364e1be..fd4bb805db7d6 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -286,6 +286,7 @@ void Expr::propagateLValueAccessKind(AccessKind accessKind, LEAF_LVALUE_EXPR(DiscardAssignment) LEAF_LVALUE_EXPR(DynamicLookup) LEAF_LVALUE_EXPR(OpaqueValue) + LEAF_LVALUE_EXPR(EditorPlaceholder) COMPLETE_PHYSICAL_LVALUE_EXPR(AnyTry, getSubExpr()) PARTIAL_PHYSICAL_LVALUE_EXPR(BindOptional, getSubExpr()) @@ -841,13 +842,6 @@ StringLiteralExpr::StringLiteralExpr(StringRef Val, SourceRange Range, unicode::isSingleExtendedGraphemeCluster(Val); } -void DeclRefExpr::setDeclRef(ConcreteDeclRef ref) { - if (auto spec = getSpecInfo()) - spec->D = ref; - else - DOrSpecialized = ref; -} - void DeclRefExpr::setSpecialized() { if (isSpecialized()) return; @@ -899,6 +893,7 @@ bool OverloadSetRefExpr::hasBaseObject() const { } SequenceExpr *SequenceExpr::create(ASTContext &ctx, ArrayRef elements) { + assert(elements.size() & 1 && "even number of elements in sequence"); void *Buffer = ctx.Allocate(sizeof(SequenceExpr) + elements.size() * sizeof(Expr*), alignof(SequenceExpr)); @@ -1064,14 +1059,11 @@ RebindSelfInConstructorExpr::getCalledConstructor(bool &isChainToSuper) const { return otherCtorRef; } -void AbstractClosureExpr::setParams(Pattern *P) { - ParamPattern = P; +void AbstractClosureExpr::setParameterList(ParameterList *P) { + parameterList = P; // Change the DeclContext of any parameters to be this closure. - if (P) { - P->forEachVariable([&](VarDecl *VD) { - VD->setDeclContext(this); - }); - } + if (P) + P->setDeclContextOfParamDecls(this); } diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp index 15fc379f0a8cd..c51b708258ecd 100644 --- a/lib/AST/GenericSignature.cpp +++ b/lib/AST/GenericSignature.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/Identifier.cpp b/lib/AST/Identifier.cpp index 34a69141e76ba..15b46dadc88eb 100644 --- a/lib/AST/Identifier.cpp +++ b/lib/AST/Identifier.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/LookupVisibleDecls.cpp b/lib/AST/LookupVisibleDecls.cpp index a85177bf080af..bd46f9f75c0b7 100644 --- a/lib/AST/LookupVisibleDecls.cpp +++ b/lib/AST/LookupVisibleDecls.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -122,7 +122,7 @@ static bool isDeclVisibleInLookupMode(ValueDecl *Member, LookupState LS, } if (auto *FD = dyn_cast(Member)) { - // Can not call static functions on non-metatypes. + // Cannot call static functions on non-metatypes. if (!LS.isOnMetatype() && FD->isStatic()) return false; @@ -130,27 +130,27 @@ static bool isDeclVisibleInLookupMode(ValueDecl *Member, LookupState LS, return true; } if (auto *VD = dyn_cast(Member)) { - // Can not use static properties on non-metatypes. + // Cannot use static properties on non-metatypes. if (!(LS.isQualified() && LS.isOnMetatype()) && VD->isStatic()) return false; - // Can not use instance properties on metatypes. + // Cannot use instance properties on metatypes. if (LS.isOnMetatype() && !VD->isStatic()) return false; return true; } if (isa(Member)) { - // Can not reference enum elements on non-metatypes. + // Cannot reference enum elements on non-metatypes. if (!(LS.isQualified() && LS.isOnMetatype())) return false; } if (auto CD = dyn_cast(Member)) { - // Constructors with stub implementations can not be called in Swift. + // Constructors with stub implementations cannot be called in Swift. if (CD->hasStubImplementation()) return false; if (LS.isQualified() && LS.isOnSuperclass()) { - // Can not call initializers from a superclass, except for inherited + // Cannot call initializers from a superclass, except for inherited // convenience initializers. return LS.isInheritsSuperclassInitializers() && CD->isInheritable(); } @@ -277,7 +277,7 @@ static void doDynamicLookup(VisibleDeclConsumer &Consumer, if (D->getOverriddenDecl()) return; - // Initializers can not be found by dynamic lookup. + // Initializers cannot be found by dynamic lookup. if (isa(D)) return; @@ -500,6 +500,8 @@ static void lookupVisibleMemberDeclsImpl( ClassDecl *CurClass = dyn_cast(CurNominal); if (CurClass && CurClass->hasSuperclass()) { + assert(BaseTy.getPointer() != CurClass->getSuperclass().getPointer() && + "type is its own superclass"); BaseTy = CurClass->getSuperclass(); Reason = getReasonForSuper(Reason); @@ -588,7 +590,7 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer { } auto &PossiblyConflicting = FoundDecls[VD->getName()]; - // Check all overriden decls. + // Check all overridden decls. { auto *CurrentVD = VD->getOverriddenDecl(); while (CurrentVD) { @@ -712,13 +714,12 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer, namelookup::FindLocalVal(SM, Loc, Consumer).visit(AFD->getBody()); } - for (auto *P : AFD->getBodyParamPatterns()) - namelookup::FindLocalVal(SM, Loc, Consumer) - .checkPattern(P, DeclVisibilityKind::FunctionParameter); + for (auto *P : AFD->getParameterLists()) + namelookup::FindLocalVal(SM, Loc, Consumer).checkParameterList(P); // Constructors and destructors don't have 'self' in parameter patterns. if (isa(AFD) || isa(AFD)) - Consumer.foundDecl(AFD->getImplicitSelfDecl(), + Consumer.foundDecl(const_cast(AFD->getImplicitSelfDecl()), DeclVisibilityKind::FunctionParameter); if (AFD->getExtensionType()) { @@ -740,9 +741,8 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer, if (Loc.isValid()) { auto CE = cast(ACE); namelookup::FindLocalVal(SM, Loc, Consumer).visit(CE->getBody()); - if (auto P = CE->getParams()) { - namelookup::FindLocalVal(SM, Loc, Consumer) - .checkPattern(P, DeclVisibilityKind::FunctionParameter); + if (auto P = CE->getParameters()) { + namelookup::FindLocalVal(SM, Loc, Consumer).checkParameterList(P); } } } else if (auto ED = dyn_cast(DC)) { @@ -759,13 +759,10 @@ void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer, TypeResolver); } - // Check the generic parameters for something with the given name. - if (GenericParams) { - namelookup::FindLocalVal(SM, Loc, Consumer) - .checkGenericParams(GenericParams, - DeclVisibilityKind::GenericParameter); - } - + // Check any generic parameters for something with the given name. + namelookup::FindLocalVal(SM, Loc, Consumer) + .checkGenericParams(GenericParams); + DC = DC->getParent(); Reason = DeclVisibilityKind::MemberOfOutsideNominal; } diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp index 4db65d6b25f88..1b93fc5fc72a9 100644 --- a/lib/AST/Mangle.cpp +++ b/lib/AST/Mangle.cpp @@ -1,8 +1,8 @@ -//===--- Mangle.cpp - Swift Name Mangling --------------------------------===// +//===--- Mangle.cpp - Swift Name Mangling ---------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -58,20 +58,38 @@ namespace { } }; } - + +// Translates operator fixity to demangler operators. +static Demangle::OperatorKind TranslateOperator(OperatorFixity fixity) { + switch (fixity) { + case OperatorFixity::NotOperator:return Demangle::OperatorKind::NotOperator; + case OperatorFixity::Prefix: return Demangle::OperatorKind::Prefix; + case OperatorFixity::Postfix: return Demangle::OperatorKind::Postfix; + case OperatorFixity::Infix: return Demangle::OperatorKind::Infix; + } + llvm_unreachable("invalid operator fixity"); +} + +/// Finish the mangling of the symbol and return the mangled name. +std::string Mangler::finalize() { + assert(Storage.size() && "Mangling an empty name"); + std::string result = std::string(Storage.data(), Storage.size()); + Storage.clear(); + return result; +} + +/// Finish the mangling of the symbol and write the mangled name into +/// \p stream. +void Mangler::finalize(llvm::raw_ostream &stream) { + std::string result = finalize(); + stream.write(result.data(), result.size()); +} + /// Mangle a StringRef as an identifier into a buffer. void Mangler::mangleIdentifier(StringRef str, OperatorFixity fixity, bool isOperator) { - auto operatorKind = [=]() -> Demangle::OperatorKind { - if (!isOperator) return Demangle::OperatorKind::NotOperator; - switch (fixity) { - case OperatorFixity::NotOperator:return Demangle::OperatorKind::NotOperator; - case OperatorFixity::Prefix: return Demangle::OperatorKind::Prefix; - case OperatorFixity::Postfix: return Demangle::OperatorKind::Postfix; - case OperatorFixity::Infix: return Demangle::OperatorKind::Infix; - } - llvm_unreachable("invalid operator fixity"); - }(); + auto operatorKind = isOperator ? TranslateOperator(fixity) : + Demangle::OperatorKind::NotOperator; std::string buf; Demangle::mangleIdentifier(str.data(), str.size(), operatorKind, buf, @@ -296,6 +314,11 @@ void Mangler::mangleContext(const DeclContext *ctx, BindGenerics shouldBind) { return mangleEntity(fn, ResilienceExpansion::Minimal, /*uncurry*/ 0); } + case DeclContextKind::SubscriptDecl: + // FIXME: We may need to do something here if subscripts contain any symbols + // exposed with linkage names. + return mangleContext(ctx->getParent(), shouldBind); + case DeclContextKind::Initializer: switch (cast(ctx)->getInitializerKind()) { case InitializerKind::DefaultArgument: { @@ -446,7 +469,7 @@ static void bindAllGenericParameters(Mangler &mangler, } void Mangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) { - assert(DWARFMangling && "DWARFMangling expected whn mangling for debugger"); + assert(DWARFMangling && "DWARFMangling expected when mangling for debugger"); // Polymorphic function types carry their own generic parameters and // manglePolymorphicType will bind them. @@ -881,6 +904,7 @@ void Mangler::mangleAssociatedTypeName(DependentMemberType *dmt, /// ::= Xo # unowned reference type /// ::= Xw # weak reference type /// ::= XF # SIL function type +/// ::= Xb # SIL @box type /// /// ::= _ # 0 /// ::= _ # N+1 @@ -1108,6 +1132,7 @@ void Mangler::mangleType(Type type, ResilienceExpansion explosion, // ::= 'e' // direct, deallocating // ::= 'i' // indirect, ownership transfer // ::= 'l' // indirect, inout + // ::= 'L' // indirect, inout, aliasable // ::= 'g' // direct, guaranteed // ::= 'G' // indirect, guaranteed // ::= 'z' // error result @@ -1129,6 +1154,7 @@ void Mangler::mangleType(Type type, ResilienceExpansion explosion, case ParameterConvention::Indirect_In: return 'i'; case ParameterConvention::Indirect_Out: return 'i'; case ParameterConvention::Indirect_Inout: return 'l'; + case ParameterConvention::Indirect_InoutAliasable: return 'L'; case ParameterConvention::Indirect_In_Guaranteed: return 'G'; case ParameterConvention::Direct_Owned: return 'o'; case ParameterConvention::Direct_Unowned: return 'd'; @@ -1276,19 +1302,24 @@ void Mangler::mangleType(Type type, ResilienceExpansion explosion, if (DWARFMangling) { Buffer << 'q' << Index(info.Index); - // The DWARF output created by Swift is intentionally flat, - // therefore archetypes are emitted with their DeclContext if - // they appear at the top level of a type (_Tt). - // Clone a new, non-DWARF Mangler for the DeclContext. - Mangler ContextMangler(Buffer, /*DWARFMangling=*/false); - SmallVector SortedSubsts(Substitutions.size()); - for (auto S : Substitutions) SortedSubsts[S.second] = S.first; - for (auto S : SortedSubsts) ContextMangler.addSubstitution(S); - for (; relativeDepth > 0; --relativeDepth) - DC = DC->getParent(); - assert(DC && "no decl context for archetype found"); - if (!DC) return; - ContextMangler.mangleContext(DC, BindGenerics::None); + + { + // The DWARF output created by Swift is intentionally flat, + // therefore archetypes are emitted with their DeclContext if + // they appear at the top level of a type (_Tt). + // Clone a new, non-DWARF Mangler for the DeclContext. + Mangler ContextMangler(/*DWARFMangling=*/false); + SmallVector SortedSubsts(Substitutions.size()); + for (auto S : Substitutions) SortedSubsts[S.second] = S.first; + for (auto S : SortedSubsts) ContextMangler.addSubstitution(S); + for (; relativeDepth > 0; --relativeDepth) + DC = DC->getParent(); + assert(DC && "no decl context for archetype found"); + if (!DC) return; + ContextMangler.mangleContext(DC, BindGenerics::None); + ContextMangler.finalize(Buffer); + } + } else { if (relativeDepth != 0) { Buffer << 'd' << Index(relativeDepth - 1); @@ -1392,6 +1423,11 @@ void Mangler::mangleType(Type type, ResilienceExpansion explosion, } case TypeKind::SILBox: + Buffer << 'X' << 'b'; + mangleType(cast(tybase)->getBoxedType(), explosion, + uncurryLevel); + return; + case TypeKind::SILBlockStorage: llvm_unreachable("should never be mangled"); } @@ -1822,6 +1858,30 @@ void Mangler::mangleTypeMetadataFull(CanType ty, bool isPattern) { mangleType(ty, ResilienceExpansion::Minimal, 0); } +void Mangler::append(StringRef S) { + Buffer << S; +} + +void Mangler::append(char C) { + Buffer << C; +} + +void Mangler::mangleNatural(const APInt &Nat) { + Buffer << Nat; +} + +void Mangler::mangleIdentifierSymbol(StringRef Name) { + // Mangle normal identifiers as: + // count identifier-char+ + // where the count is the number of characters in the identifier, + // and where individual identifier characters represent themselves. + Buffer << Name.size() << Name; +} + +void Mangler::appendSymbol(StringRef Name) { + Buffer << Name; +} + void Mangler::mangleGlobalVariableFull(const VarDecl *decl) { // As a special case, Clang functions and globals don't get mangled at all. // FIXME: When we can import C++, use Clang's mangler. diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index 6b3ea61d8a771..6a81502cb35e0 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -119,7 +119,7 @@ class SourceFile::LookupCache { Members.shrink_and_clear(); } - decltype(Members)::const_iterator begin() const { return Members.begin(); } + decltype(Members)::const_iterator begin() const { return Members.begin(); } decltype(Members)::const_iterator end() const { return Members.end(); } decltype(Members)::const_iterator find(DeclName Name) const { return Members.find(Name); @@ -458,6 +458,7 @@ void Module::lookupMember(SmallVectorImpl &results, case DeclContextKind::Initializer: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: llvm_unreachable("This context does not support lookup."); case DeclContextKind::FileUnit: @@ -1530,7 +1531,7 @@ bool SourceFile::walk(ASTWalker &walker) { return false; } -StringRef SourceFile::getFilename() const { +StringRef SourceFile::getFilename() const { if (BufferID == -1) return ""; SourceManager &SM = getASTContext().SourceMgr; diff --git a/lib/AST/ModuleNameLookup.cpp b/lib/AST/ModuleNameLookup.cpp index 1edfaa1024078..b098f8f3413e6 100644 --- a/lib/AST/ModuleNameLookup.cpp +++ b/lib/AST/ModuleNameLookup.cpp @@ -1,8 +1,8 @@ -//===--- ModuleNameLookup.cpp - Name lookup within a module ----*- c++ -*--===// +//===--- ModuleNameLookup.cpp - Name lookup within a module -----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index 3fde23dd87a26..cb4fdf6afe48b 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -71,6 +71,9 @@ bool swift::removeOverriddenDecls(SmallVectorImpl &decls) { // A.init are in the chain. Make sure we still remove A.init from the // set in this case. if (decl->getFullName().getBaseName() == ctx.Id_init) { + /// FIXME: Avoid the possibility of an infinite loop by fixing the root + /// cause instead (incomplete circularity detection). + assert(decl != overrides && "Circular class inheritance?"); decl = overrides; continue; } @@ -421,8 +424,8 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC, localVal.visit(AFD->getBody()); if (!Results.empty()) return; - for (Pattern *P : AFD->getBodyParamPatterns()) - localVal.checkPattern(P, DeclVisibilityKind::FunctionParameter); + for (auto *PL : AFD->getParameterLists()) + localVal.checkParameterList(PL); if (!Results.empty()) return; } @@ -468,8 +471,7 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC, localVal.visit(CE->getBody()); if (!Results.empty()) return; - localVal.checkPattern(CE->getParams(), - DeclVisibilityKind::FunctionParameter); + localVal.checkParameterList(CE->getParameters()); if (!Results.empty()) return; } @@ -508,8 +510,7 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC, // Check the generic parameters for something with the given name. if (GenericParams) { namelookup::FindLocalVal localVal(SM, Loc, Consumer); - localVal.checkGenericParams(GenericParams, - DeclVisibilityKind::GenericParameter); + localVal.checkGenericParams(GenericParams); if (!Results.empty()) return; @@ -579,8 +580,7 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC, if (dcGenericParams) { namelookup::FindLocalVal localVal(SM, Loc, Consumer); - localVal.checkGenericParams(dcGenericParams, - DeclVisibilityKind::GenericParameter); + localVal.checkGenericParams(dcGenericParams); if (!Results.empty()) return; @@ -698,7 +698,7 @@ class swift::MemberLookupTable { /// Update a lookup table with members from newly-added extensions. void updateLookupTable(NominalTypeDecl *nominal); - /// \brief Add the given member to the lookup tabke. + /// \brief Add the given member to the lookup table. void addMember(Decl *members); /// \brief Add the given members to the lookup table. diff --git a/lib/AST/NameLookupImpl.h b/lib/AST/NameLookupImpl.h index 055735cc1e159..a1264b29e3987 100644 --- a/lib/AST/NameLookupImpl.h +++ b/lib/AST/NameLookupImpl.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,6 +15,7 @@ #include "swift/AST/NameLookup.h" #include "swift/AST/ASTVisitor.h" +#include "swift/AST/ParameterList.h" namespace swift { namespace namelookup { @@ -89,14 +90,19 @@ class FindLocalVal : public StmtVisitor { return; } } + + void checkParameterList(const ParameterList *params) { + for (auto param : *params) { + checkValueDecl(param, DeclVisibilityKind::FunctionParameter); + } + } - void checkGenericParams(GenericParamList *Params, - DeclVisibilityKind Reason) { + void checkGenericParams(GenericParamList *Params) { if (!Params) return; for (auto P : *Params) - checkValueDecl(P, Reason); + checkValueDecl(P, DeclVisibilityKind::GenericParameter); } void checkSourceFile(const SourceFile &SF) { diff --git a/lib/AST/Parameter.cpp b/lib/AST/Parameter.cpp new file mode 100644 index 0000000000000..fe765b987b4f4 --- /dev/null +++ b/lib/AST/Parameter.cpp @@ -0,0 +1,152 @@ +//===--- Parameter.cpp - Functions & closures parameters ------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines the Parameter class, the ParameterList class and support +// logic. +// +//===----------------------------------------------------------------------===// + +#include "swift/AST/ParameterList.h" +#include "swift/AST/ASTContext.h" +#include "swift/AST/Expr.h" +#include "swift/AST/ExprHandle.h" +using namespace swift; + +/// TODO: unique and reuse the () parameter list in ASTContext, it is common to +/// many methods. Other parameter lists cannot be uniqued because the decls +/// within them are always different anyway (they have different DeclContext's). +ParameterList * +ParameterList::create(const ASTContext &C, SourceLoc LParenLoc, + ArrayRef params, SourceLoc RParenLoc) { + assert(LParenLoc.isValid() == RParenLoc.isValid() && + "Either both paren locs are valid or neither are"); + + auto byteSize = sizeof(ParameterList)+params.size()*sizeof(ParamDecl*); + auto rawMem = C.Allocate(byteSize, alignof(ParameterList)); + + // Placement initialize the ParameterList and the Parameter's. + auto PL = ::new (rawMem) ParameterList(LParenLoc, params.size(), RParenLoc); + + for (size_t i = 0, e = params.size(); i != e; ++i) + ::new (&PL->get(i)) ParamDecl*(params[i]); + + return PL; +} + +/// Create an implicit 'self' decl for a method in the specified decl context. +/// If 'static' is true, then this is self for a static method in the type. +/// +/// Note that this decl is created, but it is returned with an incorrect +/// DeclContext that needs to be set correctly. This is automatically handled +/// when a function is created with this as part of its argument list. +/// +ParameterList *ParameterList::createSelf(SourceLoc loc, DeclContext *DC, + bool isStaticMethod, bool isInOut) { + auto *PD = ParamDecl::createSelf(loc, DC, isStaticMethod, isInOut); + return create(DC->getASTContext(), PD); +} + +/// Change the DeclContext of any contained parameters to the specified +/// DeclContext. +void ParameterList::setDeclContextOfParamDecls(DeclContext *DC) { + for (auto P : *this) + P->setDeclContext(DC); +} + + + +/// Make a duplicate copy of this parameter list. This allocates copies of +/// the ParamDecls, so they can be reparented into a new DeclContext. +ParameterList *ParameterList::clone(const ASTContext &C, + OptionSet options) const { + // If this list is empty, don't actually bother with a copy. + if (size() == 0) + return const_cast(this); + + SmallVector params(begin(), end()); + + // Remap the ParamDecls inside of the ParameterList. + for (auto &decl : params) { + decl = new (C) ParamDecl(decl); + if (options & Implicit) + decl->setImplicit(); + + // If the argument isn't named, and we're cloning for an inherited + // constructor, give the parameter a name so that silgen will produce a + // value for it. + if (decl->getName().empty() && (options & Inherited)) + decl->setName(C.getIdentifier("argument")); + + // If we're inheriting a default argument, mark it as such. + if (decl->isDefaultArgument() && (options & Inherited)) { + decl->setDefaultArgumentKind(DefaultArgumentKind::Inherited); + decl->setDefaultValue(nullptr); + } + } + + return create(C, params); +} + +/// Return a TupleType or ParenType for this parameter list. This returns a +/// null type if one of the ParamDecls does not have a type set for it yet. +Type ParameterList::getType(const ASTContext &C) const { + if (size() == 0) + return TupleType::getEmpty(C); + + SmallVector argumentInfo; + + for (auto P : *this) { + if (!P->hasType()) return Type(); + + argumentInfo.push_back({ + P->getType(), P->getArgumentName(), + P->getDefaultArgumentKind(), P->isVariadic() + }); + } + + return TupleType::get(argumentInfo, C); +} + + +/// Return the full function type for a set of curried parameter lists that +/// returns the specified result type. This returns a null type if one of the +/// ParamDecls does not have a type set for it yet. +/// +Type ParameterList::getFullType(Type resultType, ArrayRef PLL) { + auto result = resultType; + auto &C = result->getASTContext(); + + for (auto PL : reversed(PLL)) { + auto paramType = PL->getType(C); + if (!paramType) return Type(); + result = FunctionType::get(paramType, result); + } + return result; +} + +/// Return the full source range of this parameter list. +SourceRange ParameterList::getSourceRange() const { + // If we have locations for the parens, then they define our range. + if (LParenLoc.isValid()) + return { LParenLoc, RParenLoc }; + + // Otherwise, try the first and last parameter. + if (size() != 0) { + auto Start = get(0)->getStartLoc(); + auto End = getArray().back()->getEndLoc(); + if (Start.isValid() && End.isValid()) + return { Start, End }; + } + + return SourceRange(); +} + diff --git a/lib/AST/Pattern.cpp b/lib/AST/Pattern.cpp index d467a23c2503d..a3b6a4716bacf 100644 --- a/lib/AST/Pattern.cpp +++ b/lib/AST/Pattern.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,6 +16,7 @@ #include "swift/AST/Pattern.h" #include "swift/AST/AST.h" +#include "swift/AST/ASTWalker.h" #include "swift/AST/TypeLoc.h" #include "llvm/ADT/APFloat.h" #include "llvm/Support/raw_ostream.h" @@ -25,7 +26,7 @@ using namespace swift; llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &OS, PatternKind kind) { switch (kind) { case PatternKind::Paren: - return OS << "parethesized pattern"; + return OS << "parenthesized pattern"; case PatternKind::Tuple: return OS << "tuple pattern"; case PatternKind::Named: @@ -289,367 +290,8 @@ case PatternKind::ID: foundRefutablePattern = true; break; return foundRefutablePattern; } - - -unsigned Pattern::numTopLevelVariables() const { - auto pattern = getSemanticsProvidingPattern(); - if (auto tuple = dyn_cast(pattern)) - return tuple->getNumElements(); - return 1; -} - -static Pattern *buildImplicitLetParameter(ASTContext &ctx, Identifier name, - SourceLoc loc, TypeLoc tyLoc, - DeclContext *DC) { - auto *paramDecl = new (ctx) ParamDecl(/*IsLet*/ true, SourceLoc(), - Identifier(), loc, name, - tyLoc.getType(), DC); - - paramDecl->setImplicit(); - Pattern *P = new (ctx) NamedPattern(paramDecl, /*Implicit=*/true); - P->setType(tyLoc.getType()); - P = new (ctx) TypedPattern(P, tyLoc, /*Implicit=*/true); - P->setType(tyLoc.getType()); - paramDecl->setParamParentPattern(P); - return P; -} - -Pattern *Pattern::buildImplicitSelfParameter(SourceLoc loc, TypeLoc tyLoc, - DeclContext *DC) { - ASTContext &ctx = DC->getASTContext(); - return ::buildImplicitLetParameter(ctx, ctx.Id_self, loc, tyLoc, DC); -} - -Pattern *Pattern::buildImplicitLetParameter(SourceLoc loc, StringRef name, - TypeLoc tyLoc, DeclContext *DC) { - ASTContext &ctx = DC->getASTContext(); - Identifier ident = (name.empty() ? Identifier() : ctx.getIdentifier(name)); - return ::buildImplicitLetParameter(ctx, ident, loc, tyLoc, DC); -} - -Pattern *Pattern::clone(ASTContext &context, - OptionSet options) const { - Pattern *result; - switch (getKind()) { - case PatternKind::Any: { - result = new (context) AnyPattern(cast(this)->getLoc()); - break; - } - - case PatternKind::Named: { - auto named = cast(this); - VarDecl *var; - if (auto param = dyn_cast(named->getDecl())) { - - auto name = param->getName(); - // If the argument isn't named, and we're cloning for an inherited - // constructor, give the parameter a name so that silgen will produce a - // value for it. - if (name.empty() && (options & Inherited)) - name = context.getIdentifier("argument"); - - var = new (context) ParamDecl(param->isLet(), - param->getArgumentNameLoc(), - param->getArgumentName(), - param->getLoc(), name, - param->hasType() - ? param->getType() - : Type(), - param->getDeclContext()); - } else { - var = new (context) VarDecl(!named->getDecl()->isInstanceMember(), - named->getDecl()->isLet(), - named->getLoc(), - named->getBoundName(), - named->getDecl()->hasType() - ? named->getDecl()->getType() - : Type(), - named->getDecl()->getDeclContext()); - } - - if ((options & Implicit) || var->isImplicit()) - var->setImplicit(); - result = new (context) NamedPattern(var); - break; - } - - case PatternKind::Paren: { - auto paren = cast(this); - result = new (context) ParenPattern(paren->getLParenLoc(), - paren->getSubPattern()->clone(context, - options), - paren->getRParenLoc()); - break; - } - - case PatternKind::Tuple: { - auto tuple = cast(this); - SmallVector elts; - elts.reserve(tuple->getNumElements()); - for (const auto &elt : tuple->getElements()) { - auto eltPattern = elt.getPattern()->clone(context, options); - - // If we're inheriting a default argument, mark it as such. - if (elt.getDefaultArgKind() != DefaultArgumentKind::None && - (options & Inherited)) { - elts.push_back(TuplePatternElt(elt.getLabel(), elt.getLabelLoc(), - eltPattern, elt.hasEllipsis(), - elt.getEllipsisLoc(), nullptr, - DefaultArgumentKind::Inherited)); - } else { - elts.push_back(TuplePatternElt(elt.getLabel(), elt.getLabelLoc(), - eltPattern, elt.hasEllipsis(), - elt.getEllipsisLoc(), elt.getInit(), - elt.getDefaultArgKind())); - } - } - - result = TuplePattern::create(context, tuple->getLParenLoc(), elts, - tuple->getRParenLoc()); - break; - } - - case PatternKind::Typed: { - auto typed = cast(this); - result = new(context) TypedPattern(typed->getSubPattern()->clone(context, - options), - typed->getTypeLoc().clone(context)); - break; - } - - case PatternKind::Is: { - auto isa = cast(this); - result = new(context) IsPattern(isa->getLoc(), - isa->getCastTypeLoc().clone(context), - isa->getSubPattern()->clone(context, - options), - isa->getCastKind()); - break; - } - - case PatternKind::NominalType: { - auto nom = cast(this); - SmallVector elts; - for (const auto &elt : nom->getElements()) { - elts.push_back(NominalTypePattern::Element(elt.getPropertyLoc(), - elt.getPropertyName(), - elt.getProperty(), - elt.getColonLoc(), - elt.getSubPattern()->clone(context, - options))); - } - - result = NominalTypePattern::create(nom->getCastTypeLoc().clone(context), - nom->getLParenLoc(), - elts, - nom->getRParenLoc(), context); - break; - } - - case PatternKind::EnumElement: { - auto oof = cast(this); - Pattern *sub = nullptr; - if (oof->hasSubPattern()) - sub = oof->getSubPattern()->clone(context, options); - result = new (context) EnumElementPattern(oof->getParentType() - .clone(context), - oof->getLoc(), - oof->getNameLoc(), - oof->getName(), - oof->getElementDecl(), - sub); - break; - } - - case PatternKind::OptionalSome: { - auto osp = cast(this); - auto *sub = osp->getSubPattern()->clone(context, options); - auto *r = new (context) OptionalSomePattern(sub, osp->getQuestionLoc()); - r->setElementDecl(osp->getElementDecl()); - result = r; - break; - } - - case PatternKind::Bool: { - auto bp = cast(this); - result = new (context) BoolPattern(bp->getNameLoc(), bp->getValue()); - break; - } - - case PatternKind::Expr: { - auto expr = cast(this); - result = new(context) ExprPattern(expr->getSubExpr(), - expr->isResolved(), - expr->getMatchExpr(), - expr->getMatchVar()); - break; - } - - case PatternKind::Var: { - auto var = cast(this); - result = new(context) VarPattern(var->getLoc(), var->isLet(), - var->getSubPattern()->clone( - context, - options|IsVar)); - } - } - - if (hasType()) - result->setType(getType()); - if ((options & Implicit) || isImplicit()) - result->setImplicit(); - - return result; -} - -Pattern *Pattern::cloneForwardable(ASTContext &context, DeclContext *DC, - OptionSet options) const { - Pattern *result; - switch (getKind()) { - case PatternKind::Any: - case PatternKind::Is: - case PatternKind::NominalType: - case PatternKind::EnumElement: - case PatternKind::OptionalSome: - case PatternKind::Bool: - case PatternKind::Expr: - llvm_unreachable("cannot forward this kind of pattern"); - - case PatternKind::Named: - return clone(context, options); - - case PatternKind::Paren: { - auto paren = cast(this); - auto sub = paren->getSubPattern()->cloneForwardable(context, DC, options); - result = new (context) ParenPattern(paren->getLParenLoc(), - sub, - paren->getRParenLoc()); - break; - } - - case PatternKind::Var: { - auto var = cast(this); - result = new(context) VarPattern(var->getLoc(), var->isLet(), - var->getSubPattern()->cloneForwardable( - context, DC, options|IsVar)); - break; - } - - case PatternKind::Tuple: { - auto tuple = cast(this); - SmallVector elts; - elts.reserve(tuple->getNumElements()); - for (const auto &elt : tuple->getElements()) { - auto eltPattern = elt.getPattern()->cloneForwardable(context, DC, options); - - // If we're inheriting a default argument, mark it as such. - if (elt.getDefaultArgKind() != DefaultArgumentKind::None && - (options & Inherited)) { - elts.push_back(TuplePatternElt(elt.getLabel(), elt.getLabelLoc(), - eltPattern, elt.hasEllipsis(), - elt.getEllipsisLoc(), nullptr, - DefaultArgumentKind::Inherited)); - } else { - elts.push_back(TuplePatternElt(elt.getLabel(), elt.getLabelLoc(), - eltPattern, elt.hasEllipsis(), - elt.getEllipsisLoc(), elt.getInit(), - elt.getDefaultArgKind())); - } - } - - result = TuplePattern::create(context, tuple->getLParenLoc(), elts, - tuple->getRParenLoc()); - break; - } - - case PatternKind::Typed: { - auto typed = cast(this); - TypeLoc tyLoc = typed->getTypeLoc().clone(context); - const Pattern *origSub = typed->getSubPattern(); - - // If the original sub-pattern is a single named variable, go - // ahead and clone it. - if (origSub->getSingleVar()) { - Pattern *cloneSub = origSub->cloneForwardable(context, DC, options); - result = new (context) TypedPattern(cloneSub, tyLoc); - - // Otherwise, create a new bound variable. - } else { - result = buildImplicitLetParameter(origSub->getLoc(), "", tyLoc, DC); - } - break; - } - } - - if (hasType()) - result->setType(getType()); - if ((options & Implicit) || isImplicit()) - result->setImplicit(); - - return result; -} - -Expr *Pattern::buildForwardingRefExpr(ASTContext &context) const { - switch (getKind()) { - case PatternKind::Any: - case PatternKind::Is: - case PatternKind::NominalType: - case PatternKind::EnumElement: - case PatternKind::OptionalSome: - case PatternKind::Bool: - case PatternKind::Expr: - llvm_unreachable("cannot forward this kind of pattern"); - - case PatternKind::Named: { - auto np = cast(this); - Expr *ref = new (context) DeclRefExpr(np->getDecl(), SourceLoc(), - /*implicit*/ true); - if (np->getDecl()->getType()->is()) - ref = new (context) InOutExpr(SourceLoc(), ref, Type(), - /*implicit=*/true); - return ref; - } - - case PatternKind::Paren: { - auto paren = cast(this); - return paren->getSubPattern()->buildForwardingRefExpr(context); - } - - case PatternKind::Var: { - auto var = cast(this); - return var->getSubPattern()->buildForwardingRefExpr(context); - } - - case PatternKind::Typed: { - auto typed = cast(this); - return typed->getSubPattern()->buildForwardingRefExpr(context); - } - - case PatternKind::Tuple: { - auto tuple = cast(this); - SmallVector elts; - SmallVector labels; - SmallVector labelLocs; - elts.reserve(tuple->getNumElements()); - labels.reserve(tuple->getNumElements()); - labelLocs.reserve(tuple->getNumElements()); - for (const auto &elt : tuple->getElements()) { - elts.push_back(elt.getPattern()->buildForwardingRefExpr(context)); - labels.push_back(Identifier()); // FIXME? - labelLocs.push_back(SourceLoc()); - } - - return TupleExpr::create(context, SourceLoc(), elts, labels, labelLocs, - SourceLoc(), /*trailing closure*/ false, - /*implicit*/ true); - } - - } - llvm_unreachable("bad pattern kind"); -} - /// Standard allocator for Patterns. -void *Pattern::operator new(size_t numBytes, ASTContext &C) { +void *Pattern::operator new(size_t numBytes, const ASTContext &C) { return C.Allocate(numBytes, alignof(Pattern)); } @@ -662,20 +304,7 @@ Identifier Pattern::getBoundName() const { return Identifier(); } -Identifier Pattern::getBodyName() const { - if (auto *NP = dyn_cast(getSemanticsProvidingPattern())) - return NP->getBodyName(); - return Identifier(); -} - Identifier NamedPattern::getBoundName() const { - if (auto param = dyn_cast(Var)) - return param->getArgumentName(); - - return Var->getName(); -} - -Identifier NamedPattern::getBodyName() const { return Var->getName(); } @@ -703,10 +332,7 @@ Pattern *TuplePattern::createSimple(ASTContext &C, SourceLoc lp, assert(lp.isValid() == rp.isValid()); if (elements.size() == 1 && - !elements[0].hasEllipsis() && - elements[0].getInit() == nullptr && - elements[0].getPattern()->getBoundName().empty() && - elements[0].getPattern()->getBodyName().empty()) { + elements[0].getPattern()->getBoundName().empty()) { auto &first = const_cast(elements.front()); return new (C) ParenPattern(lp, first.getPattern(), rp, implicit); } @@ -724,27 +350,9 @@ SourceRange TuplePattern::getSourceRange() const { Fields.back().getPattern()->getEndLoc() }; } -bool TuplePattern::hasAnyEllipsis() const { - for (const auto elt : getElements()) { - if (elt.hasEllipsis()) - return true; - } - - return false; -} - -SourceLoc TuplePattern::getAnyEllipsisLoc() const { - for (const auto elt : getElements()) { - if (elt.hasEllipsis()) - return elt.getEllipsisLoc(); - } - - return SourceLoc(); -} - SourceRange TypedPattern::getSourceRange() const { if (isImplicit()) { - // If a TypedPattern is implicit, then its type is definitely implicit, se + // If a TypedPattern is implicit, then its type is definitely implicit, so // we should ignore its location. On the other hand, the sub-pattern can // be explicit or implicit. return SubPattern->getSourceRange(); diff --git a/lib/AST/PlatformKind.cpp b/lib/AST/PlatformKind.cpp index dc1f5a51ffb05..49c3729661a5e 100644 --- a/lib/AST/PlatformKind.cpp +++ b/lib/AST/PlatformKind.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/PrettyStackTrace.cpp b/lib/AST/PrettyStackTrace.cpp index d0be7c12568de..5b3dbaff856de 100644 --- a/lib/AST/PrettyStackTrace.cpp +++ b/lib/AST/PrettyStackTrace.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp index c67845f958653..f8722e7d7004e 100644 --- a/lib/AST/ProtocolConformance.cpp +++ b/lib/AST/ProtocolConformance.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -145,7 +145,7 @@ GenericParamList *ProtocolConformance::getGenericParams() const { case ProtocolConformanceKind::Specialized: // If we have a specialized protocol conformance, since we do not support - // currently partial specialization, we know that it can not have any open + // currently partial specialization, we know that it cannot have any open // type variables. return nullptr; } @@ -174,7 +174,7 @@ GenericSignature *ProtocolConformance::getGenericSignature() const { case ProtocolConformanceKind::Specialized: // If we have a specialized protocol conformance, since we do not support - // currently partial specialization, we know that it can not have any open + // currently partial specialization, we know that it cannot have any open // type variables. return nullptr; } @@ -642,7 +642,7 @@ DeclContext::getLocalProtocols( nullptr, diagnostics); - // Sort if requred. + // Sort if required. if (sorted) { llvm::array_pod_sort(result.begin(), result.end(), &ProtocolType::compareProtocols); diff --git a/lib/AST/RawComment.cpp b/lib/AST/RawComment.cpp index cbc32320f8edb..72aee1c5f7b34 100644 --- a/lib/AST/RawComment.cpp +++ b/lib/AST/RawComment.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 14f31f7638ff8..92227e5d7525c 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -165,7 +165,7 @@ SourceLoc DeferStmt::getEndLoc() const { return tempDecl->getBody()->getEndLoc(); } -/// Dig the original users's body of the defer out for AST fidelity. +/// Dig the original user's body of the defer out for AST fidelity. BraceStmt *DeferStmt::getBodyAsWritten() const { return tempDecl->getBody(); } @@ -248,7 +248,7 @@ bool DoCatchStmt::isSyntacticallyExhaustive() const { } void LabeledConditionalStmt::setCond(StmtCondition e) { - // When set set a condition into a Conditional Statement, inform each of the + // When set a condition into a Conditional Statement, inform each of the // variables bound in any patterns that this is the owning statement for the // pattern. for (auto &elt : e) diff --git a/lib/AST/Substitution.cpp b/lib/AST/Substitution.cpp index 2e2df054abbbd..887ef24efb55d 100644 --- a/lib/AST/Substitution.cpp +++ b/lib/AST/Substitution.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index cc36a0da527c0..62cf31a09b85c 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -721,7 +721,7 @@ static Type getStrippedType(const ASTContext &context, Type type, Type eltTy = getStrippedType(context, elt.getType(), stripLabels, stripDefaultArgs); if (anyChanged || eltTy.getPointer() != elt.getType().getPointer() || - (elt.hasInit() && stripDefaultArgs) || + (elt.hasDefaultArg() && stripDefaultArgs) || (elt.hasName() && stripLabels)) { if (!anyChanged) { elements.reserve(tuple->getNumElements()); @@ -765,38 +765,6 @@ Type TypeBase::getUnlabeledType(ASTContext &Context) { /*defaultArgs=*/true); } -Type TypeBase::getRelabeledType(ASTContext &ctx, - ArrayRef labels) { - if (auto tupleTy = dyn_cast(this)) { - assert(labels.size() == tupleTy->getNumElements() && - "Wrong number of labels"); - SmallVector elements; - unsigned i = 0; - bool anyChanged = false; - for (const auto &elt : tupleTy->getElements()) { - if (elt.getName() != labels[i]) - anyChanged = true; - - elements.push_back(TupleTypeElt(elt.getType(), labels[i], - elt.getDefaultArgKind(), elt.isVararg())); - ++i; - } - - if (!anyChanged) - return this; - - return TupleType::get(elements, ctx); - } - - // If there is no label, the type is unchanged. - if (labels[0].empty()) - return this; - - // Create a one-element tuple to capture the label. - TupleTypeElt elt(this, labels[0]); - return TupleType::get(elt, ctx); -} - Type TypeBase::getWithoutDefaultArgs(const ASTContext &Context) { return getStrippedType(Context, Type(this), /*labels=*/false, /*defaultArgs=*/true); @@ -956,22 +924,6 @@ TypeDecl *TypeBase::getDirectlyReferencedTypeDecl() const { return nullptr; } -StringRef TypeBase::getInferredDefaultArgString() { - if (auto structDecl = getStructOrBoundGenericStruct()) { - if (structDecl->getClangDecl()) { - for (auto attr : structDecl->getAttrs()) { - if (auto synthesizedProto = dyn_cast(attr)) { - if (synthesizedProto->getProtocolKind() - == KnownProtocolKind::OptionSetType) - return "[]"; - } - } - } - } - - return "nil"; -} - /// \brief Collect the protocols in the existential type T into the given /// vector. static void addProtocols(Type T, SmallVectorImpl &Protocols) { @@ -1501,7 +1453,7 @@ bool TypeBase::isSpelledLike(Type other) { return false; for (size_t i = 0, sz = tMe->getNumElements(); i < sz; ++i) { auto &myField = tMe->getElement(i), &theirField = tThem->getElement(i); - if (myField.hasInit() != theirField.hasInit()) + if (myField.hasDefaultArg() != theirField.hasDefaultArg()) return false; if (myField.getName() != theirField.getName()) @@ -1602,7 +1554,10 @@ bool TypeBase::isSpelledLike(Type other) { } Type TypeBase::getSuperclass(LazyResolver *resolver) { + // If this type is either a bound generic type, or a nested type inside a + // bound generic type, we will need to fish out the generic parameters. Type specializedTy; + ClassDecl *classDecl; if (auto classTy = getAs()) { classDecl = classTy->getDecl(); @@ -1622,19 +1577,31 @@ Type TypeBase::getSuperclass(LazyResolver *resolver) { return nullptr; } + // Get the superclass type. If the class is generic, the superclass type may + // contain generic type parameters from the signature of the class. Type superclassTy; if (classDecl) superclassTy = classDecl->getSuperclass(); - if (!specializedTy || !superclassTy) + // If there's no superclass, return a null type. If the class is not in a + // generic context, return the original superclass type. + if (!superclassTy || !classDecl->isGenericContext()) return superclassTy; + // The class is defined in a generic context, so its superclass type may refer + // to generic parameters of the class or some parent type of the class. Map + // it to a contextual type. + // FIXME: Lame to rely on archetypes in the substitution below. superclassTy = ArchetypeBuilder::mapTypeIntoContext(classDecl, superclassTy); - // If the type is specialized, we need to gather all of the substitutions. - // We've already dealt with the top level, but continue gathering - // specializations from the parent types. + // If the type does not bind any generic parameters, return the superclass + // type as-is. + if (!specializedTy) + return superclassTy; + + // If the type is specialized, we need to gather all of the substitutions + // for the type and any parent types. TypeSubstitutionMap substitutions; while (specializedTy) { if (auto nominalTy = specializedTy->getAs()) { @@ -1653,7 +1620,8 @@ Type TypeBase::getSuperclass(LazyResolver *resolver) { specializedTy = boundTy->getParent(); } - // Perform substitutions into the base type. + // Perform substitutions into the superclass type to yield the + // substituted superclass type. Module *module = classDecl->getModuleContext(); return superclassTy.subst(module, substitutions, None); } @@ -1851,7 +1819,7 @@ bool TypeBase::canOverride(Type other, bool allowUnsafeParameterOverride, /// value. bool TupleType::hasAnyDefaultValues() const { for (const TupleTypeElt &Elt : Elements) - if (Elt.hasInit()) + if (Elt.hasDefaultArg()) return true; return false; } @@ -1877,7 +1845,7 @@ int TupleType::getElementForScalarInit() const { int FieldWithoutDefault = -1; for (unsigned i = 0, e = Elements.size(); i != e; ++i) { // Ignore fields with a default value. - if (Elements[i].hasInit()) continue; + if (Elements[i].hasDefaultArg()) continue; // If we already saw a non-vararg field missing a default value, then we // cannot assign a scalar to this tuple. @@ -2125,7 +2093,7 @@ Type ProtocolCompositionType::get(const ASTContext &C, return Protocols.front()->getDeclaredType(); // Form the set of canonical protocol types from the protocol - // declarations, and use that to buid the canonical composition type. + // declarations, and use that to build the canonical composition type. SmallVector CanProtocolTypes; std::transform(Protocols.begin(), Protocols.end(), std::back_inserter(CanProtocolTypes), @@ -2297,9 +2265,12 @@ static Type getMemberForBaseType(Module *module, // If the parent is an archetype, extract the child archetype with the // given name. if (auto archetypeParent = substBase->getAs()) { - if (!archetypeParent->hasNestedType(name) && - archetypeParent->getParent()->isSelfDerived()) { - return archetypeParent->getParent()->getNestedTypeValue(name); + if (!archetypeParent->hasNestedType(name)) { + const auto parent = archetypeParent->getParent(); + if (!parent) + return ErrorType::get(module->getASTContext()); + if (parent->isSelfDerived()) + return parent->getNestedTypeValue(name); } return archetypeParent->getNestedTypeValue(name); @@ -2517,7 +2488,13 @@ TypeSubstitutionMap TypeBase::getMemberSubstitutions(DeclContext *dc) { } // Continue looking into the parent. - baseTy = baseTy->castTo()->getParent(); + if (auto nominalTy = baseTy->getAs()) { + baseTy = nominalTy->getParent(); + continue; + } + + // We're done. + break; } return substitutions; @@ -3137,3 +3114,99 @@ bool Type::isPrivateStdlibType(bool whitelistProtocols) const { return false; } + +bool UnownedStorageType::isLoadable(ResilienceExpansion resilience) const { + return getReferentType()->usesNativeReferenceCounting(resilience); +} + +static bool doesOpaqueClassUseNativeReferenceCounting(const ASTContext &ctx) { + return !ctx.LangOpts.EnableObjCInterop; +} + +static bool usesNativeReferenceCounting(ClassDecl *theClass, + ResilienceExpansion resilience) { + // NOTE: if you change this, change irgen::getReferenceCountingForClass. + // TODO: Resilience? there might be some legal avenue of changing this. + while (Type supertype = theClass->getSuperclass()) { + theClass = supertype->getClassOrBoundGenericClass(); + assert(theClass); + } + return !theClass->hasClangNode(); +} + +bool TypeBase::usesNativeReferenceCounting(ResilienceExpansion resilience) { + assert(allowsOwnership()); + + CanType type = getCanonicalType(); + switch (type->getKind()) { +#define SUGARED_TYPE(id, parent) case TypeKind::id: +#define TYPE(id, parent) +#include "swift/AST/TypeNodes.def" + llvm_unreachable("sugared canonical type?"); + + case TypeKind::BuiltinNativeObject: + case TypeKind::SILBox: + return true; + + case TypeKind::BuiltinUnknownObject: + case TypeKind::BuiltinBridgeObject: + return ::doesOpaqueClassUseNativeReferenceCounting(type->getASTContext()); + + case TypeKind::Class: + return ::usesNativeReferenceCounting(cast(type)->getDecl(), + resilience); + case TypeKind::BoundGenericClass: + return ::usesNativeReferenceCounting( + cast(type)->getDecl(), + resilience); + + case TypeKind::DynamicSelf: + return cast(type).getSelfType() + ->usesNativeReferenceCounting(resilience); + + case TypeKind::Archetype: { + auto archetype = cast(type); + assert(archetype->requiresClass()); + if (auto supertype = archetype->getSuperclass()) + return supertype->usesNativeReferenceCounting(resilience); + return ::doesOpaqueClassUseNativeReferenceCounting(type->getASTContext()); + } + + case TypeKind::Protocol: + case TypeKind::ProtocolComposition: + return ::doesOpaqueClassUseNativeReferenceCounting(type->getASTContext()); + + case TypeKind::UnboundGeneric: + case TypeKind::Function: + case TypeKind::PolymorphicFunction: + case TypeKind::GenericFunction: + case TypeKind::SILFunction: + case TypeKind::SILBlockStorage: + case TypeKind::Error: + case TypeKind::Unresolved: + case TypeKind::BuiltinInteger: + case TypeKind::BuiltinFloat: + case TypeKind::BuiltinRawPointer: + case TypeKind::BuiltinUnsafeValueBuffer: + case TypeKind::BuiltinVector: + case TypeKind::Tuple: + case TypeKind::Enum: + case TypeKind::Struct: + case TypeKind::Metatype: + case TypeKind::ExistentialMetatype: + case TypeKind::Module: + case TypeKind::LValue: + case TypeKind::InOut: + case TypeKind::TypeVariable: + case TypeKind::BoundGenericEnum: + case TypeKind::BoundGenericStruct: + case TypeKind::UnownedStorage: + case TypeKind::UnmanagedStorage: + case TypeKind::WeakStorage: + case TypeKind::GenericTypeParam: + case TypeKind::DependentMember: + llvm_unreachable("type is not a class reference"); + } + + llvm_unreachable("Unhandled type kind!"); +} diff --git a/lib/AST/TypeRefinementContext.cpp b/lib/AST/TypeRefinementContext.cpp index 112b4567b6da1..fc1b676c8cd28 100644 --- a/lib/AST/TypeRefinementContext.cpp +++ b/lib/AST/TypeRefinementContext.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/TypeRepr.cpp b/lib/AST/TypeRepr.cpp index f851be94f0ea3..4a5ddbc486de1 100644 --- a/lib/AST/TypeRepr.cpp +++ b/lib/AST/TypeRepr.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -68,7 +68,8 @@ SourceRange TypeRepr::getSourceRange() const { } /// Standard allocator for TypeReprs. -void *TypeRepr::operator new(size_t Bytes, ASTContext &C, unsigned Alignment) { +void *TypeRepr::operator new(size_t Bytes, const ASTContext &C, + unsigned Alignment) { return C.Allocate(Bytes, Alignment); } @@ -106,10 +107,10 @@ void TypeRepr::print(ASTPrinter &Printer, const PrintOptions &Opts) const { namespace { class CloneVisitor : public TypeReprVisitor { - ASTContext &Ctx; + const ASTContext &Ctx; public: - explicit CloneVisitor(ASTContext &ctx) : Ctx(ctx) { } + explicit CloneVisitor(const ASTContext &ctx) : Ctx(ctx) { } #define TYPEREPR(CLASS, PARENT) \ TypeRepr *visit##CLASS##TypeRepr(CLASS##TypeRepr* type); @@ -157,8 +158,7 @@ TypeRepr *CloneVisitor::visitFunctionTypeRepr(FunctionTypeRepr *T) { } TypeRepr *CloneVisitor::visitArrayTypeRepr(ArrayTypeRepr *T) { - return new (Ctx) ArrayTypeRepr(visit(T->getBase()), T->getSize(), - T->getBrackets(), T->usesOldSyntax()); + return new (Ctx) ArrayTypeRepr(visit(T->getBase()), T->getBrackets()); } TypeRepr *CloneVisitor::visitDictionaryTypeRepr(DictionaryTypeRepr *T) { @@ -221,7 +221,7 @@ TypeRepr *CloneVisitor::visitFixedTypeRepr(FixedTypeRepr *T) { return new (Ctx) FixedTypeRepr(T->getType(), T->getLoc()); } -TypeRepr *TypeRepr::clone(ASTContext &ctx) const { +TypeRepr *TypeRepr::clone(const ASTContext &ctx) const { CloneVisitor visitor(ctx); return visitor.visit(const_cast(this)); } @@ -337,17 +337,9 @@ void FunctionTypeRepr::printImpl(ASTPrinter &Printer, void ArrayTypeRepr::printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const { - if (usesOldSyntax()) { - printTypeRepr(Base, Printer, Opts); - Printer << "["; - if (auto size = getSize()) - size->getExpr()->print(Printer, Opts); - Printer << "]"; - } else { - Printer << "["; - printTypeRepr(Base, Printer, Opts); - Printer << "]"; - } + Printer << "["; + printTypeRepr(getBase(), Printer, Opts); + Printer << "]"; } void DictionaryTypeRepr::printImpl(ASTPrinter &Printer, diff --git a/lib/AST/TypeWalker.cpp b/lib/AST/TypeWalker.cpp index 5813f4165b3c2..75b1885538cd0 100644 --- a/lib/AST/TypeWalker.cpp +++ b/lib/AST/TypeWalker.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/AST/USRGeneration.cpp b/lib/AST/USRGeneration.cpp index 533c0d23cb1a2..e4cd4c4380795 100644 --- a/lib/AST/USRGeneration.cpp +++ b/lib/AST/USRGeneration.cpp @@ -1,8 +1,8 @@ -//===--- USRGeneration.h - Routines for USR generation --------------------===// +//===--- USRGeneration.cpp - Routines for USR generation ------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -71,7 +71,7 @@ bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) { return true; OS << getUSRSpacePrefix(); - Mangler Mangler(OS); + Mangler Mangler; if (auto Ctor = dyn_cast(VD)) { Mangler.mangleConstructorEntity(Ctor, /*isAllocating=*/false, ResilienceExpansion::Minimal, /*uncurryingLevel=*/0); @@ -87,6 +87,8 @@ bool ide::printDeclUSR(const ValueDecl *D, raw_ostream &OS) { Mangler.mangleEntity(VD, ResilienceExpansion::Minimal, /*uncurryingLevel=*/0); } + + Mangler.finalize(OS); return false; } @@ -108,9 +110,10 @@ bool ide::printAccessorUSR(const AbstractStorageDecl *D, AccessorKind AccKind, AbstractStorageDecl *SD = const_cast(D); OS << getUSRSpacePrefix(); - Mangler Mangler(OS); + Mangler Mangler; Mangler.mangleAccessorEntity(AccKind, AddressorKind::NotAddressor, SD, ResilienceExpansion::Minimal); + Mangler.finalize(OS); return false; } diff --git a/lib/AST/Verifier.cpp b/lib/AST/Verifier.cpp index 937ecc1ac440d..820a987180de9 100644 --- a/lib/AST/Verifier.cpp +++ b/lib/AST/Verifier.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -246,7 +246,7 @@ struct ASTNodeBase {}; #undef DISPATCH } - llvm_unreachable("Unhandled declaratiom kind"); + llvm_unreachable("Unhandled declaration kind"); } private: @@ -436,7 +436,7 @@ struct ASTNodeBase {}; return false; // We should know about archetypes corresponding to opened - // existerntial archetypes. + // existential archetypes. if (archetype->getOpenedExistentialType()) { if (OpenedExistentialArchetypes.count(archetype) == 0) { Out << "Found opened existential archetype " @@ -462,8 +462,8 @@ struct ASTNodeBase {}; } while (!activeScope->isModuleScopeContext()); } - Out << "AST verification error: archetype " << archetype - << " not allowed in this context\n"; + Out << "AST verification error: archetype " + << archetype->getString() << " not allowed in this context\n"; auto knownDC = Ctx.ArchetypeContexts.find(archetype); if (knownDC != Ctx.ArchetypeContexts.end()) { @@ -516,6 +516,7 @@ struct ASTNodeBase {}; case DeclContextKind::Initializer: case DeclContextKind::AbstractClosureExpr: case DeclContextKind::SerializedLocal: + case DeclContextKind::SubscriptDecl: return nullptr; case DeclContextKind::AbstractFunctionDecl: @@ -674,8 +675,8 @@ struct ASTNodeBase {}; if (auto Overridden = D->getOverriddenDecl()) { if (D->getDeclContext() == Overridden->getDeclContext()) { - PrettyStackTraceDecl debugStack("verifying overriden", D); - Out << "can not override a decl in the same DeclContext"; + PrettyStackTraceDecl debugStack("verifying overridden", D); + Out << "cannot override a decl in the same DeclContext"; D->dump(Out); Overridden->dump(Out); abort(); @@ -814,6 +815,13 @@ struct ASTNodeBase {}; } void verifyChecked(DeclRefExpr *E) { + if (E->getType()->is()) { + PrettyStackTraceExpr debugStack(Ctx, "verifying decl reference", E); + Out << "reference with inout type " + << E->getType().getString() << "\n"; + E->dump(Out); + abort(); + } if (E->getType()->is()) { PrettyStackTraceExpr debugStack(Ctx, "verifying decl reference", E); Out << "unspecialized reference with polymorphic type " @@ -1594,6 +1602,7 @@ struct ASTNodeBase {}; case DeclContextKind::Initializer: case DeclContextKind::NominalTypeDecl: case DeclContextKind::ExtensionDecl: + case DeclContextKind::SubscriptDecl: return hasEnclosingFunctionContext(dc->getParent()); } } @@ -1609,7 +1618,6 @@ struct ASTNodeBase {}; // Make sure that there are no archetypes in the interface type. if (VD->getDeclContext()->isTypeContext() && !hasEnclosingFunctionContext(VD->getDeclContext()) && - !isa(VD) && /* because of subscripts */ VD->getInterfaceType().findIf([](Type type) { return type->is(); })) { @@ -1834,11 +1842,6 @@ struct ASTNodeBase {}; void verifyParsed(ConstructorDecl *CD) { PrettyStackTraceDecl debugStack("verifying ConstructorDecl", CD); - if (CD->getBodyParamPatterns().size() != 2) { - Out << "ConstructorDecl should have exactly two parameter patterns"; - abort(); - } - auto *DC = CD->getDeclContext(); if (!isa(DC) && !isa(DC) && !CD->isInvalid()) { @@ -1907,11 +1910,7 @@ struct ASTNodeBase {}; PrettyStackTraceDecl debugStack("verifying DestructorDecl", DD); if (DD->isGeneric()) { - Out << "DestructorDecl can not be generic"; - abort(); - } - if (DD->getBodyParamPatterns().size() != 1) { - Out << "DestructorDecl should have 'self' parameter pattern only"; + Out << "DestructorDecl cannot be generic"; abort(); } @@ -2118,83 +2117,32 @@ struct ASTNodeBase {}; PrettyStackTraceDecl debugStack("verifying AbstractFunctionDecl", AFD); // All of the parameter names should match. - if (!isa(AFD)) { + if (!isa(AFD)) { // Destructor has no non-self params. auto paramNames = AFD->getFullName().getArgumentNames(); bool checkParamNames = (bool)AFD->getFullName(); bool hasSelf = AFD->getDeclContext()->isTypeContext(); - const Pattern *firstParams = - AFD->getBodyParamPatterns()[hasSelf ? 1 : 0]; - - if (auto *paramTuple = dyn_cast(firstParams)) { - if (checkParamNames && - paramNames.size() != paramTuple->getNumElements()) { - Out << "Function name does not match its argument pattern (" - << paramNames.size() << " elements instead of " - << paramTuple->getNumElements() << ")\n"; - AFD->dump(Out); - abort(); - } - - // This doesn't use for_each because paramNames shouldn't be checked - // when the function is anonymous. - for (size_t i = 0, e = paramTuple->getNumElements(); i < e; ++i) { - TuplePatternElt elt = paramTuple->getElement(i); - Pattern *param = elt.getPattern()->getSemanticsProvidingPattern(); - if (auto *namedParam = dyn_cast(param)) { - if (namedParam->getBoundName() != elt.getLabel()) { - Out << "Function body param tuple label " - "doesn't match variable's public name\n"; - AFD->dump(Out); - abort(); - } + auto *firstParams = AFD->getParameterList(hasSelf ? 1 : 0); + + if (checkParamNames && + paramNames.size() != firstParams->size()) { + Out << "Function name does not match its argument pattern (" + << paramNames.size() << " elements instead of " + << firstParams->size() << ")\n"; + AFD->dump(Out); + abort(); + } - if (checkParamNames && - namedParam->getBoundName() != paramNames[i]) { - Out << "Function full name doesn't match variable name\n"; - AFD->dump(Out); - abort(); - } - } else { - assert(isa(param)); - if (!elt.getLabel().empty()) { - Out << "Function body param tuple has a label, " - "but there's no variable\n"; - AFD->dump(Out); - abort(); - } + // This doesn't use for_each because paramNames shouldn't be checked + // when the function is anonymous. + for (size_t i = 0, e = firstParams->size(); i < e; ++i) { + auto ¶m = firstParams->get(i); - if (checkParamNames && !paramNames[i].empty()) { - Out << "Function full name doesn't match variable name\n"; - AFD->dump(Out); - abort(); - } - } - } - } else { - if (checkParamNames && paramNames.size() != 1) { - Out << "Function name does not match its non-tuple argument pattern (" - << paramNames.size() << " elements instead of 1)\n"; + if (checkParamNames && + param->getArgumentName() != paramNames[i]) { + Out << "Function full name doesn't match variable name\n"; AFD->dump(Out); abort(); } - - firstParams = firstParams->getSemanticsProvidingPattern(); - if (auto *namedParam = dyn_cast(firstParams)) { - if (checkParamNames && - namedParam->getBoundName() != paramNames.front()) { - Out << "Function full name doesn't match variable name\n"; - AFD->dump(Out); - abort(); - } - } else { - assert(isa(firstParams)); - if (checkParamNames && !paramNames.front().empty()) { - Out << "Function full name has an argument name, " - "but there's no variable\n"; - AFD->dump(Out); - abort(); - } - } } } @@ -2327,7 +2275,7 @@ struct ASTNodeBase {}; PrettyStackTraceDecl debugStack("verifying FuncDecl", FD); unsigned MinParamPatterns = FD->getImplicitSelfDecl() ? 2 : 1; - if (FD->getBodyParamPatterns().size() < MinParamPatterns) { + if (FD->getParameterLists().size() < MinParamPatterns) { Out << "should have at least " << MinParamPatterns << " parameter patterns"; abort(); @@ -2337,7 +2285,7 @@ struct ASTNodeBase {}; unsigned NumExpectedParamPatterns = 1; if (FD->getImplicitSelfDecl()) NumExpectedParamPatterns++; - if (FD->getBodyParamPatterns().size() != NumExpectedParamPatterns) { + if (FD->getParameterLists().size() != NumExpectedParamPatterns) { Out << "accessors should not be curried"; abort(); } @@ -2393,36 +2341,11 @@ struct ASTNodeBase {}; void verifyParsed(TuplePattern *TP) { PrettyStackTracePattern debugStack(Ctx, "verifying TuplePattern", TP); - - for (const auto &elt : TP->getElements()) { - if (elt.hasEllipsis()) { - if (!isa(elt.getPattern())) { - Out << "a vararg subpattern of a TuplePattern should be " - "a TypedPattern\n"; - abort(); - } - } - } - verifyParsedBase(TP); } void verifyChecked(TuplePattern *TP) { PrettyStackTracePattern debugStack(Ctx, "verifying TuplePattern", TP); - - for (const auto &elt : TP->getElements()) { - if (elt.hasEllipsis()) { - Type T = cast(elt.getPattern())->getType() - ->getCanonicalType(); - if (auto *BGT = T->getAs()) { - if (BGT->getDecl() == Ctx.getArrayDecl()) - continue; - } - Out << "a vararg subpattern of a TuplePattern has wrong type"; - abort(); - } - } - verifyCheckedBase(TP); } @@ -2596,11 +2519,9 @@ struct ASTNodeBase {}; } void checkMangling(ValueDecl *D) { - llvm::SmallString<32> Buf; - llvm::raw_svector_ostream OS(Buf); - Mangle::Mangler Mangler(OS); + Mangle::Mangler Mangler; Mangler.mangleDeclName(D); - if (OS.str().empty()) { + if (Mangler.finalize().empty()) { Out << "Mangler gave empty string for a ValueDecl"; abort(); } diff --git a/lib/ASTSectionImporter/ASTSectionImporter.cpp b/lib/ASTSectionImporter/ASTSectionImporter.cpp index 607534e467c09..2a237eb26d01d 100644 --- a/lib/ASTSectionImporter/ASTSectionImporter.cpp +++ b/lib/ASTSectionImporter/ASTSectionImporter.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt index 68b95ffb2aa0b..d8f14e719413f 100644 --- a/lib/Basic/CMakeLists.txt +++ b/lib/Basic/CMakeLists.txt @@ -82,6 +82,7 @@ add_swift_library(swiftBasic StringExtras.cpp TaskQueue.cpp ThreadSafeRefCounted.cpp + Timer.cpp Unicode.cpp UUID.cpp Version.cpp diff --git a/lib/Basic/Cache.cpp b/lib/Basic/Cache.cpp index d8464920d9287..928b3b09fa296 100644 --- a/lib/Basic/Cache.cpp +++ b/lib/Basic/Cache.cpp @@ -1,14 +1,14 @@ -//===--- Cache.h - Caching mechanism implementation -----------------------===// +//===--- Cache.cpp - Caching mechanism implementation ---------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #if defined(__APPLE__) #include "Darwin/Cache-Mac.cpp" diff --git a/lib/Basic/ClusteredBitVector.cpp b/lib/Basic/ClusteredBitVector.cpp index 002195de0bb4c..65e38016822f0 100644 --- a/lib/Basic/ClusteredBitVector.cpp +++ b/lib/Basic/ClusteredBitVector.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/Darwin/Cache-Mac.cpp b/lib/Basic/Darwin/Cache-Mac.cpp index 557ba5f36c72e..c617ac251dc46 100644 --- a/lib/Basic/Darwin/Cache-Mac.cpp +++ b/lib/Basic/Darwin/Cache-Mac.cpp @@ -1,18 +1,18 @@ -//===--- Cache.h - Caching mechanism implementation -----------------------===// +//===--- Cache-Mac.cpp - Caching mechanism implementation -----------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // // This file implements the caching mechanism using darwin's libcache. // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #include "swift/Basic/Cache.h" #include "llvm/ADT/SmallString.h" diff --git a/lib/Basic/Default/TaskQueue.inc b/lib/Basic/Default/TaskQueue.inc index 21097bbcb6453..118df97464391 100644 --- a/lib/Basic/Default/TaskQueue.inc +++ b/lib/Basic/Default/TaskQueue.inc @@ -1,8 +1,8 @@ -//===--- Default/TaskQueue.inc - Default serial TaskQueue -------*- C++ -*-===// +//===--- TaskQueue.inc - Default serial TaskQueue ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/Demangle.cpp b/lib/Basic/Demangle.cpp index d12074982cd11..8357a270ff085 100644 --- a/lib/Basic/Demangle.cpp +++ b/lib/Basic/Demangle.cpp @@ -2,17 +2,17 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // // This file implements declaration name demangling in Swift. // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #include "swift/Basic/Demangle.h" #include "swift/Basic/Fallthrough.h" @@ -577,6 +577,18 @@ class Demangler { DEMANGLE_CHILD_OR_RETURN(witnessTable, ProtocolConformance); return witnessTable; } + if (Mangled.nextIf('G')) { + auto witnessTable = + NodeFactory::create(Node::Kind::GenericProtocolWitnessTable); + DEMANGLE_CHILD_OR_RETURN(witnessTable, ProtocolConformance); + return witnessTable; + } + if (Mangled.nextIf('I')) { + auto witnessTable = NodeFactory::create( + Node::Kind::GenericProtocolWitnessTableInstantiationFunction); + DEMANGLE_CHILD_OR_RETURN(witnessTable, ProtocolConformance); + return witnessTable; + } if (Mangled.nextIf('l')) { auto accessor = NodeFactory::create(Node::Kind::LazyProtocolWitnessTableAccessor); @@ -597,17 +609,20 @@ class Demangler { DEMANGLE_CHILD_OR_RETURN(tableTemplate, ProtocolConformance); return tableTemplate; } - if (Mangled.nextIf('D')) { - auto tableGenerator = NodeFactory::create( - Node::Kind::DependentProtocolWitnessTableGenerator); - DEMANGLE_CHILD_OR_RETURN(tableGenerator, ProtocolConformance); - return tableGenerator; + if (Mangled.nextIf('t')) { + auto accessor = NodeFactory::create( + Node::Kind::AssociatedTypeMetadataAccessor); + DEMANGLE_CHILD_OR_RETURN(accessor, ProtocolConformance); + DEMANGLE_CHILD_OR_RETURN(accessor, DeclName); + return accessor; } - if (Mangled.nextIf('d')) { - auto tableTemplate = NodeFactory::create( - Node::Kind::DependentProtocolWitnessTableTemplate); - DEMANGLE_CHILD_OR_RETURN(tableTemplate, ProtocolConformance); - return tableTemplate; + if (Mangled.nextIf('T')) { + auto accessor = NodeFactory::create( + Node::Kind::AssociatedTypeWitnessTableAccessor); + DEMANGLE_CHILD_OR_RETURN(accessor, ProtocolConformance); + DEMANGLE_CHILD_OR_RETURN(accessor, DeclName); + DEMANGLE_CHILD_OR_RETURN(accessor, ProtocolName); + return accessor; } return nullptr; } @@ -784,7 +799,12 @@ class Demangler { if (!demangleFuncSigSpecializationClosureProp(param)) return nullptr; } else if (Mangled.nextIf("i_")) { - auto result = FUNCSIGSPEC_CREATE_PARAM_KIND(InOutToValue); + auto result = FUNCSIGSPEC_CREATE_PARAM_KIND(BoxToValue); + if (!result) + return nullptr; + param->addChild(result); + } else if (Mangled.nextIf("k_")) { + auto result = FUNCSIGSPEC_CREATE_PARAM_KIND(BoxToStack); if (!result) return nullptr; param->addChild(result); @@ -1878,6 +1898,16 @@ class Demangler { type_application->addChild(type_list); return type_application; } + if (c == 'X') { + if (Mangled.nextIf('b')) { + NodePointer type = demangleType(); + if (!type) + return nullptr; + NodePointer boxType = NodeFactory::create(Node::Kind::SILBoxType); + boxType->addChild(type); + return boxType; + } + } if (c == 'K') { return demangleFunctionType(Node::Kind::AutoClosureType); } @@ -2326,6 +2356,7 @@ class NodePrinter { case Node::Kind::QualifiedArchetype: case Node::Kind::ReturnType: case Node::Kind::SelfTypeRef: + case Node::Kind::SILBoxType: case Node::Kind::Structure: case Node::Kind::TupleElementName: case Node::Kind::Type: @@ -2336,6 +2367,8 @@ class NodePrinter { case Node::Kind::Allocator: case Node::Kind::ArgumentTuple: + case Node::Kind::AssociatedTypeMetadataAccessor: + case Node::Kind::AssociatedTypeWitnessTableAccessor: case Node::Kind::AutoClosureType: case Node::Kind::CFunctionPointer: case Node::Kind::Constructor: @@ -2347,8 +2380,6 @@ class NodePrinter { case Node::Kind::DependentGenericParamCount: case Node::Kind::DependentGenericConformanceRequirement: case Node::Kind::DependentGenericSameTypeRequirement: - case Node::Kind::DependentProtocolWitnessTableGenerator: - case Node::Kind::DependentProtocolWitnessTableTemplate: case Node::Kind::Destructor: case Node::Kind::DidSet: case Node::Kind::DirectMethodReferenceAttribute: @@ -2365,6 +2396,8 @@ class NodePrinter { case Node::Kind::FunctionSignatureSpecializationParamPayload: case Node::Kind::FunctionType: case Node::Kind::Generics: + case Node::Kind::GenericProtocolWitnessTable: + case Node::Kind::GenericProtocolWitnessTableInstantiationFunction: case Node::Kind::GenericSpecialization: case Node::Kind::GenericSpecializationParam: case Node::Kind::GenericType: @@ -2634,7 +2667,8 @@ unsigned NodePrinter::printFunctionSigSpecializationParam(NodePointer pointer, unsigned V = firstChild->getIndex(); auto K = FunctionSigSpecializationParamKind(V); switch (K) { - case FunctionSigSpecializationParamKind::InOutToValue: + case FunctionSigSpecializationParamKind::BoxToValue: + case FunctionSigSpecializationParamKind::BoxToStack: print(pointer->getChild(Idx++)); return Idx; case FunctionSigSpecializationParamKind::ConstantPropFunction: @@ -3099,8 +3133,11 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType) return; switch (FunctionSigSpecializationParamKind(raw)) { - case FunctionSigSpecializationParamKind::InOutToValue: - Printer << "Value Promoted from InOut"; + case FunctionSigSpecializationParamKind::BoxToValue: + Printer << "Value Promoted from Box"; + break; + case FunctionSigSpecializationParamKind::BoxToStack: + Printer << "Stack Promoted from Box"; break; case FunctionSigSpecializationParamKind::ConstantPropFunction: Printer << "Constant Propagated Function"; @@ -3145,14 +3182,6 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType) case Node::Kind::PostfixOperator: Printer << pointer->getText() << " postfix"; return; - case Node::Kind::DependentProtocolWitnessTableGenerator: - Printer << "dependent protocol witness table generator for "; - print(pointer->getFirstChild()); - return; - case Node::Kind::DependentProtocolWitnessTableTemplate: - Printer << "dependent protocol witness table template for "; - print(pointer->getFirstChild()); - return; case Node::Kind::LazyProtocolWitnessTableAccessor: Printer << "lazy protocol witness table accessor for type "; print(pointer->getChild(0)); @@ -3173,6 +3202,14 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType) Printer << "protocol witness table for "; print(pointer->getFirstChild()); return; + case Node::Kind::GenericProtocolWitnessTable: + Printer << "generic protocol witness table for "; + print(pointer->getFirstChild()); + return; + case Node::Kind::GenericProtocolWitnessTableInstantiationFunction: + Printer << "instantiation function for generic protocol witness table for "; + print(pointer->getFirstChild()); + return; case Node::Kind::ProtocolWitness: { Printer << "protocol witness for "; print(pointer->getChild(1)); @@ -3259,6 +3296,20 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType) Printer << "lazy cache variable for type metadata for "; print(pointer->getChild(0)); return; + case Node::Kind::AssociatedTypeMetadataAccessor: + Printer << "associated type metadata accessor for "; + print(pointer->getChild(1)); + Printer << " in "; + print(pointer->getChild(0)); + return; + case Node::Kind::AssociatedTypeWitnessTableAccessor: + Printer << "associated type witness table accessor for "; + print(pointer->getChild(1)); + Printer << " : "; + print(pointer->getChild(2)); + Printer << " in "; + print(pointer->getChild(0)); + return; case Node::Kind::NominalTypeDescriptor: Printer << "nominal type descriptor for "; print(pointer->getChild(0)); @@ -3295,6 +3346,12 @@ void NodePrinter::print(NodePointer pointer, bool asContext, bool suppressType) printFunctionType(pointer); return; } + case Node::Kind::SILBoxType: { + Printer << "@box "; + NodePointer type = pointer->getChild(0); + print(type); + return; + } case Node::Kind::Metatype: { unsigned Idx = 0; if (pointer->getNumChildren() == 2) { diff --git a/lib/Basic/DemangleWrappers.cpp b/lib/Basic/DemangleWrappers.cpp index 816c741819f23..adc5b58d69b67 100644 --- a/lib/Basic/DemangleWrappers.cpp +++ b/lib/Basic/DemangleWrappers.cpp @@ -1,14 +1,14 @@ -//===--- DemangleWrappers.cpp - Swift Name Demangling --------------------===// +//===--- DemangleWrappers.cpp - Swift Name Demangling ---------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #include "swift/Basic/DemangleWrappers.h" #include "swift/Basic/PrettyStackTrace.h" diff --git a/lib/Basic/DiagnosticConsumer.cpp b/lib/Basic/DiagnosticConsumer.cpp index fc94798b8c815..06162e79c7c1c 100644 --- a/lib/Basic/DiagnosticConsumer.cpp +++ b/lib/Basic/DiagnosticConsumer.cpp @@ -1,8 +1,8 @@ -//===- DiagnosticConsumer.cpp - Diagnostic Consumer Impl --------*- C++ -*-===// +//===--- DiagnosticConsumer.cpp - Diagnostic Consumer Impl ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/DiverseStack.cpp b/lib/Basic/DiverseStack.cpp index 8cb9ab932c751..4f738b28a4b24 100644 --- a/lib/Basic/DiverseStack.cpp +++ b/lib/Basic/DiverseStack.cpp @@ -1,8 +1,8 @@ -//===--- DiverseStack.cpp - Out-of-line code for the heterogenous stack ---===// +//===--- DiverseStack.cpp - Out-of-line code for the heterogeneous stack --===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements the small amount of code for the heterogenous +// This file implements the small amount of code for the heterogeneous // stack and list classes. // //===----------------------------------------------------------------------===// diff --git a/lib/Basic/EditorPlaceholder.cpp b/lib/Basic/EditorPlaceholder.cpp index fa6983dd73ac7..76b5257b176f3 100644 --- a/lib/Basic/EditorPlaceholder.cpp +++ b/lib/Basic/EditorPlaceholder.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/FileSystem.cpp b/lib/Basic/FileSystem.cpp index fd842fe0cefbc..035f0d3f51043 100644 --- a/lib/Basic/FileSystem.cpp +++ b/lib/Basic/FileSystem.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/JSONSerialization.cpp b/lib/Basic/JSONSerialization.cpp index 76da55de80438..ed17af9d6507c 100644 --- a/lib/Basic/JSONSerialization.cpp +++ b/lib/Basic/JSONSerialization.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -207,8 +207,7 @@ void Output::scalarString(StringRef &S, bool MustQuote) { // Convert the current character into hexadecimal digits. Stream << llvm::hexdigit((c >> 4) & 0xF); Stream << llvm::hexdigit((c >> 0) & 0xF); - } - else { + } else { // This isn't a control character, so we don't need to escape it. // As a result, emit it directly; if it's part of a multi-byte UTF8 // representation, all bytes will be emitted in this fashion. diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp index d4714b15fab24..63d39f686b1c2 100644 --- a/lib/Basic/LangOptions.cpp +++ b/lib/Basic/LangOptions.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -29,6 +29,7 @@ const std::vector LangOptions::SupportedOSBuildConfigArguments = { "watchOS", "iOS", "Linux", + "FreeBSD", "Android" }; @@ -101,6 +102,8 @@ std::pair LangOptions::setTarget(llvm::Triple triple) { addTargetConfigOption("os", "Android"); else if (triple.isOSLinux()) addTargetConfigOption("os", "Linux"); + else if (triple.isOSFreeBSD()) + addTargetConfigOption("os", "FreeBSD"); else { UnsupportedOS = true; } diff --git a/lib/Basic/PartsOfSpeech.def b/lib/Basic/PartsOfSpeech.def index 9af825f84671c..dec4af5d728e4 100644 --- a/lib/Basic/PartsOfSpeech.def +++ b/lib/Basic/PartsOfSpeech.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // This file lists words that map to various parts of speech. -// ===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #if !defined(PREPOSITION) && !defined(VERB) # error define one or more of PREPOSITION, VERB @@ -28,10 +28,6 @@ # define VERB(Word) #endif -#ifndef AUXILIARY_VERB -# define AUXILIARY_VERB(Word) -#endif - DIRECTIONAL_PREPOSITION(above) DIRECTIONAL_PREPOSITION(after) DIRECTIONAL_PREPOSITION(along) @@ -842,33 +838,6 @@ VERB(yell) VERB(zip) VERB(zoom) -AUXILIARY_VERB(am) -AUXILIARY_VERB(are) -AUXILIARY_VERB(been) -AUXILIARY_VERB(being) -AUXILIARY_VERB(can) -AUXILIARY_VERB(could) -AUXILIARY_VERB(did) -AUXILIARY_VERB(does) -AUXILIARY_VERB(had) -AUXILIARY_VERB(has) -AUXILIARY_VERB(have) -AUXILIARY_VERB(having) -AUXILIARY_VERB(is) -AUXILIARY_VERB(may) -AUXILIARY_VERB(might) -AUXILIARY_VERB(must) -AUXILIARY_VERB(need) -AUXILIARY_VERB(needs) -AUXILIARY_VERB(ought) -AUXILIARY_VERB(shall) -AUXILIARY_VERB(should) -AUXILIARY_VERB(was) -AUXILIARY_VERB(were) -AUXILIARY_VERB(will) -AUXILIARY_VERB(would) - -#undef AUXILIARY_VERB #undef VERB #undef DIRECTIONAL_PREPOSITION #undef PREPOSITION diff --git a/lib/Basic/Platform.cpp b/lib/Basic/Platform.cpp index a0c9188cb025a..cc50c5ab52fc8 100644 --- a/lib/Basic/Platform.cpp +++ b/lib/Basic/Platform.cpp @@ -1,8 +1,8 @@ -//===-- Platform.cpp - Implement platform-related helpers -------*- C++ -*-===// +//===--- Platform.cpp - Implement platform-related helpers ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -68,5 +68,8 @@ StringRef swift::getPlatformNameForTriple(const llvm::Triple &triple) { if (triple.isOSLinux()) return "linux"; + if (triple.isOSFreeBSD()) + return "freebsd"; + return ""; } diff --git a/lib/Basic/PrefixMap.cpp b/lib/Basic/PrefixMap.cpp index 585ead7862568..09327feb73e96 100644 --- a/lib/Basic/PrefixMap.cpp +++ b/lib/Basic/PrefixMap.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/PrettyStackTrace.cpp b/lib/Basic/PrettyStackTrace.cpp index c5dbf1e3efaf9..324d737c8c045 100644 --- a/lib/Basic/PrettyStackTrace.cpp +++ b/lib/Basic/PrettyStackTrace.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/PrimitiveParsing.cpp b/lib/Basic/PrimitiveParsing.cpp index cc5455d2716fe..92e09284e0a99 100644 --- a/lib/Basic/PrimitiveParsing.cpp +++ b/lib/Basic/PrimitiveParsing.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/Program.cpp b/lib/Basic/Program.cpp index a82b50a68b42f..ca4342e446030 100644 --- a/lib/Basic/Program.cpp +++ b/lib/Basic/Program.cpp @@ -1,8 +1,8 @@ -//===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===// +//===--- Program.cpp - Implement OS Program Concept -------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/Punycode.cpp b/lib/Basic/Punycode.cpp index cfa64acc73b44..b5dcb3faf89ac 100644 --- a/lib/Basic/Punycode.cpp +++ b/lib/Basic/Punycode.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/PunycodeUTF8.cpp b/lib/Basic/PunycodeUTF8.cpp index 0c4fa405a9208..ce927f05e06c4 100644 --- a/lib/Basic/PunycodeUTF8.cpp +++ b/lib/Basic/PunycodeUTF8.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/QuotedString.cpp b/lib/Basic/QuotedString.cpp index 62e7a08c51c3c..41a0bc629b0a5 100644 --- a/lib/Basic/QuotedString.cpp +++ b/lib/Basic/QuotedString.cpp @@ -1,8 +1,8 @@ -//===--- QuotedString.cpp - Printing a string as a quoted string ---------===// +//===--- QuotedString.cpp - Printing a string as a quoted string ----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/Remangle.cpp b/lib/Basic/Remangle.cpp index ed4ccf9a847e6..2b91a00e7c2db 100644 --- a/lib/Basic/Remangle.cpp +++ b/lib/Basic/Remangle.cpp @@ -1,20 +1,20 @@ -//===--- Remangle.cpp - Swift re-mangling from a demangling tree ---------===// +//===--- Remangle.cpp - Swift re-mangling from a demangling tree ----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // // This file implements the remangler, which turns a demangling parse // tree back into a mangled string. This is useful for tools which // want to extract subtrees from mangled strings. // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #include "swift/Basic/Demangle.h" #include "swift/Basic/LLVM.h" @@ -70,6 +70,16 @@ static bool isNonAscii(StringRef str) { return false; } +static char mangleOperatorKind(OperatorKind operatorKind) { + switch (operatorKind) { + case OperatorKind::NotOperator: unreachable("invalid"); + case OperatorKind::Infix: return 'i'; + case OperatorKind::Prefix: return 'p'; + case OperatorKind::Postfix: return 'P'; + } + unreachable("invalid"); +} + static void mangleIdentifier(StringRef ident, OperatorKind operatorKind, bool usePunycode, DemanglerPrinter &out) { std::string punycodeBuf; @@ -99,15 +109,7 @@ static void mangleIdentifier(StringRef ident, OperatorKind operatorKind, // operator-fixity ::= 'i' // infix // where the count is the number of characters in the operator, // and where the individual operator characters are translated. - out << 'o' << [=] { - switch (operatorKind) { - case OperatorKind::NotOperator: unreachable("invalid"); - case OperatorKind::Infix: return 'i'; - case OperatorKind::Prefix: return 'p'; - case OperatorKind::Postfix: return 'P'; - } - unreachable("invalid"); - }(); + out << 'o' << mangleOperatorKind(operatorKind); // Mangle ASCII operators directly. out << ident.size(); @@ -522,9 +524,12 @@ void Remangler::mangleFunctionSignatureSpecializationParam(Node *node) { } Out << '_'; return; - case FunctionSigSpecializationParamKind::InOutToValue: + case FunctionSigSpecializationParamKind::BoxToValue: Out << "i_"; return; + case FunctionSigSpecializationParamKind::BoxToStack: + Out << "k_"; + return; default: if (kindValue & unsigned(FunctionSigSpecializationParamKind::Dead)) @@ -695,6 +700,17 @@ void Remangler::mangleProtocolWitnessTable(Node *node) { mangleSingleChildNode(node); // protocol conformance } +void Remangler::mangleGenericProtocolWitnessTable(Node *node) { + Out << "WG"; + mangleSingleChildNode(node); // protocol conformance +} + +void Remangler::mangleGenericProtocolWitnessTableInstantiationFunction( + Node *node) { + Out << "WI"; + mangleSingleChildNode(node); // protocol conformance +} + void Remangler::mangleProtocolWitnessTableAccessor(Node *node) { Out << "Wa"; mangleSingleChildNode(node); // protocol conformance @@ -710,14 +726,17 @@ void Remangler::mangleLazyProtocolWitnessTableCacheVariable(Node *node) { mangleChildNodes(node); // type, protocol conformance } -void Remangler::mangleDependentProtocolWitnessTableGenerator(Node *node) { - Out << "WD"; - mangleSingleChildNode(node); // protocol conformance +void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) { + Out << "Wt"; + mangleChildNodes(node); // protocol conformance, identifier } -void Remangler::mangleDependentProtocolWitnessTableTemplate(Node *node) { - Out << "Wd"; - mangleSingleChildNode(node); // protocol conformance +void Remangler::mangleAssociatedTypeWitnessTableAccessor(Node *node) { + Out << "WT"; + assert(node->getNumChildren() == 3); + mangleChildNode(node, 0); // protocol conformance + mangleChildNode(node, 1); // identifier + mangleProtocolWithoutPrefix(node->begin()[2].get()); // type } void Remangler::mangleReabstractionThunkHelper(Node *node) { @@ -1157,6 +1176,11 @@ void Remangler::mangleErrorType(Node *node) { Out << "ERR"; } +void Remangler::mangleSILBoxType(Node *node) { + Out << 'X' << 'b'; + mangleSingleChildNode(node); +} + void Remangler::mangleMetatype(Node *node) { if (node->getNumChildren() == 1) { Out << 'M'; diff --git a/lib/Basic/SourceLoc.cpp b/lib/Basic/SourceLoc.cpp index 43940d566c8ce..9bc484c5eb7a7 100644 --- a/lib/Basic/SourceLoc.cpp +++ b/lib/Basic/SourceLoc.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/StringExtras.cpp b/lib/Basic/StringExtras.cpp index 0716959bf4c2c..3ffb9f4a961bb 100644 --- a/lib/Basic/StringExtras.cpp +++ b/lib/Basic/StringExtras.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -27,6 +27,13 @@ using namespace swift; using namespace camel_case; +bool swift::canBeArgumentLabel(StringRef identifier) { + if (identifier == "var" || identifier == "let" || identifier == "inout") + return false; + + return true; +} + PrepositionKind swift::getPrepositionKind(StringRef word) { #define DIRECTIONAL_PREPOSITION(Word) \ if (word.equals_lower(#Word)) \ @@ -47,9 +54,6 @@ PartOfSpeech swift::getPartOfSpeech(StringRef word) { #define VERB(Word) \ if (word.equals_lower(#Word)) \ return PartOfSpeech::Verb; -#define AUXILIARY_VERB(Word) \ - if (word.equals_lower(#Word)) \ - return PartOfSpeech::AuxiliaryVerb; #include "PartsOfSpeech.def" // Identify gerunds, which always end in "ing". @@ -664,7 +668,6 @@ static StringRef omitNeedlessWords(StringRef name, break; case PartOfSpeech::Unknown: - case PartOfSpeech::AuxiliaryVerb: // Assume it's a noun or adjective; don't strip anything. break; } @@ -696,23 +699,6 @@ static StringRef omitNeedlessWords(StringRef name, return name; } -/// Determine whether the given word indicates a boolean result. -static bool nameIndicatesBooleanResult(StringRef name) { - for (auto word: camel_case::getWords(name)) { - // Auxiliary verbs indicate Boolean results. - if (getPartOfSpeech(word) == PartOfSpeech::AuxiliaryVerb) - return true; - - // Words that end in "s" indicate either Boolean results---it - // could be a verb in the present continuous tense---or some kind - // of plural, for which "is" would be inappropriate anyway. - if (word.back() == 's') - return true; - } - - return false; -} - /// A form of toLowercaseWord that also lowercases acronyms. static StringRef toLowercaseWordAndAcronym(StringRef string, StringScratchSpace &scratch) { @@ -723,12 +709,19 @@ static StringRef toLowercaseWordAndAcronym(StringRef string, if (!clang::isUppercase(string[0])) return string; - // Lowercase until we hit the end there is an uppercase letter - // followed by a non-uppercase letter. + // Lowercase until we hit the an uppercase letter followed by a + // non-uppercase letter. llvm::SmallString<32> scratchStr; for (unsigned i = 0, n = string.size(); i != n; ++i) { // If the next character is not uppercase, stop. if (i < n - 1 && !clang::isUppercase(string[i+1])) { + // If the next non-uppercase character was alphanumeric, we should + // still lowercase the character we're on. + if (!clang::isLetter(string[i+1])) { + scratchStr.push_back(clang::toLowercase(string[i])); + ++i; + } + scratchStr.append(string.substr(i)); break; } @@ -798,16 +791,6 @@ bool swift::omitNeedlessWords(StringRef &baseName, } } - // Boolean properties should start with "is", unless their - // first word already implies a Boolean result. - if (resultType.isBoolean() && isProperty && - !nameIndicatesBooleanResult(baseName)) { - SmallString<32> newName("is"); - camel_case::appendSentenceCase(newName, baseName); - baseName = scratch.copyString(newName); - anyChanges = true; - } - return lowercaseAcronymsForReturn(); } @@ -857,7 +840,6 @@ bool swift::omitNeedlessWords(StringRef &baseName, break; case PartOfSpeech::Unknown: - case PartOfSpeech::AuxiliaryVerb: ++nameWordRevIter; break; } diff --git a/lib/Basic/TaskQueue.cpp b/lib/Basic/TaskQueue.cpp index 4335a8dba8a84..cedd7ec98d971 100644 --- a/lib/Basic/TaskQueue.cpp +++ b/lib/Basic/TaskQueue.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/ThreadSafeRefCounted.cpp b/lib/Basic/ThreadSafeRefCounted.cpp index 87898fc33a3f7..09f728fc7224d 100644 --- a/lib/Basic/ThreadSafeRefCounted.cpp +++ b/lib/Basic/ThreadSafeRefCounted.cpp @@ -1,8 +1,8 @@ -//===--- ThreadSafeRefCounted.h - Thread-safe Refcounting Base ------------===// +//===--- ThreadSafeRefCounted.cpp - Thread-safe Refcounting Base ----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/Timer.cpp b/lib/Basic/Timer.cpp new file mode 100644 index 0000000000000..98d64a45d2e9d --- /dev/null +++ b/lib/Basic/Timer.cpp @@ -0,0 +1,17 @@ +//===--- Timer.cpp - Shared timers for compilation phases -----------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "swift/Basic/Timer.h" + +using namespace swift; + +SharedTimer::State SharedTimer::CompilationTimersEnabled = State::Initial; diff --git a/lib/Basic/UUID.cpp b/lib/Basic/UUID.cpp index 9ab4b70ccecc0..7391866fd161e 100644 --- a/lib/Basic/UUID.cpp +++ b/lib/Basic/UUID.cpp @@ -1,8 +1,8 @@ -//===--- UUID.h - UUID generation -----------------------------------------===// +//===--- UUID.cpp - UUID generation ---------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -41,7 +41,7 @@ Optional UUID::fromString(const char *s) { void UUID::toString(llvm::SmallVectorImpl &out) const { out.resize(UUID::StringBufferSize); - uuid_unparse(Value, out.data()); + uuid_unparse_upper(Value, out.data()); // Pop off the null terminator. assert(out.back() == '\0' && "did not null-terminate?!"); out.pop_back(); diff --git a/lib/Basic/Unicode.cpp b/lib/Basic/Unicode.cpp index 6f2d40d92d44f..658b90f111d4d 100644 --- a/lib/Basic/Unicode.cpp +++ b/lib/Basic/Unicode.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/UnicodeExtendedGraphemeClusters.cpp.gyb b/lib/Basic/UnicodeExtendedGraphemeClusters.cpp.gyb index 2a5ac3d48e4ee..b1470aced6870 100644 --- a/lib/Basic/UnicodeExtendedGraphemeClusters.cpp.gyb +++ b/lib/Basic/UnicodeExtendedGraphemeClusters.cpp.gyb @@ -7,7 +7,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/Unix/TaskQueue.inc b/lib/Basic/Unix/TaskQueue.inc index 876103b1598f0..3183aa2b17f8e 100644 --- a/lib/Basic/Unix/TaskQueue.inc +++ b/lib/Basic/Unix/TaskQueue.inc @@ -1,8 +1,8 @@ -//===--- Unix/TaskQueue.inc - Unix-specific TaskQueue -----------*- C++ -*-===// +//===--- TaskQueue.inc - Unix-specific TaskQueue ----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp index 178812869a37f..d27888f045612 100644 --- a/lib/Basic/Version.cpp +++ b/lib/Basic/Version.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -59,7 +59,7 @@ namespace version { /// Print a string of the form "LLVM xxxxx, Clang yyyyy, Swift zzzzz", /// where each placeholder is the revision for the associated repository. static void printFullRevisionString(raw_ostream &out) { - // Abitrarily truncate to 10 characters. This should be enough to unique + // Arbitrarily truncate to 10 characters. This should be enough to unique // Git hashes for the time being, and certainly enough for SVN revisions, // while keeping the version string from being ridiculously long. #if defined(LLVM_REVISION) @@ -189,7 +189,7 @@ Version Version::parseVersionString(StringRef VersionString, SmallString<16> digits; llvm::raw_svector_ostream OS(digits); SmallVector, 5> SplitComponents; - // Skip over quote character in string literal + // Skip over quote character in string literal. splitVersionComponents(SplitComponents, VersionString, Loc, Diags); diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 4ffe7da974443..dd1250f23dcaf 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(ABI) add_subdirectory(AST) add_subdirectory(ASTSectionImporter) add_subdirectory(Basic) @@ -18,7 +19,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_subdirectory(SwiftDemangle) endif() add_subdirectory(SIL) -add_subdirectory(SILAnalysis) add_subdirectory(SILGen) -add_subdirectory(SILPasses) +add_subdirectory(SILOptimizer) diff --git a/lib/ClangImporter/CFDatabase.def b/lib/ClangImporter/CFDatabase.def index 1d82be4f17b03..a18a3a368d508 100644 --- a/lib/ClangImporter/CFDatabase.def +++ b/lib/ClangImporter/CFDatabase.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/ClangImporter/ClangDiagnosticConsumer.cpp b/lib/ClangImporter/ClangDiagnosticConsumer.cpp index e1f1e8e034fca..3fc53e205fb52 100644 --- a/lib/ClangImporter/ClangDiagnosticConsumer.cpp +++ b/lib/ClangImporter/ClangDiagnosticConsumer.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/ClangImporter/ClangDiagnosticConsumer.h b/lib/ClangImporter/ClangDiagnosticConsumer.h index e9d2d3e504c41..d286b2fd197fc 100644 --- a/lib/ClangImporter/ClangDiagnosticConsumer.h +++ b/lib/ClangImporter/ClangDiagnosticConsumer.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 815c7f69e0454..aa11c2c82d899 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -45,6 +45,7 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/Frontend/Utils.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/ASTWriter.h" #include "clang/Lex/Preprocessor.h" #include "clang/Parse/Parser.h" #include "clang/Rewrite/Frontend/FrontendActions.h" @@ -237,10 +238,11 @@ ClangImporter::ClangImporter(ASTContext &ctx, : ClangModuleLoader(tracker), Impl(*new Implementation(ctx, clangImporterOpts)) { + Impl.Retain(); } ClangImporter::~ClangImporter() { - delete &Impl; + Impl.Release(); } void ClangImporter::setTypeResolver(LazyResolver &resolver) { @@ -544,6 +546,9 @@ ClangImporter::create(ASTContext &ctx, ppOpts.addRemappedFile(Implementation::moduleImportBufferName, sourceBuffer.release()); + // Install a Clang module file extension to build Swift name lookup tables. + invocation->getFrontendOpts().ModuleFileExtensions.push_back(&importer->Impl); + // Create a compiler instance. auto PCHContainerOperations = std::make_shared(); @@ -622,6 +627,13 @@ ClangImporter::create(ASTContext &ctx, while (!importer->Impl.Parser->ParseTopLevelDecl(parsed)) { for (auto *D : parsed.get()) { importer->Impl.addBridgeHeaderTopLevelDecls(D); + + if (auto named = dyn_cast(D)) { + importer->Impl.addEntryToLookupTable( + instance.getSema(), + importer->Impl.BridgingHeaderLookupTable, + named); + } } } @@ -679,42 +691,30 @@ bool ClangImporter::addSearchPath(StringRef newSearchPath, bool isFramework) { } void ClangImporter::Implementation::addEntryToLookupTable( - SwiftLookupTable &table, clang::NamedDecl *named) + clang::Sema &clangSema, + SwiftLookupTable &table, + clang::NamedDecl *named) { // Determine whether this declaration is suppressed in Swift. - bool suppressDecl = false; - if (auto objcMethod = dyn_cast(named)) { - // If this member is a method that is a getter or setter for a - // property, don't add it into the table. property names and - // getter names (by choosing to only have a property). - // - // Note that this is suppressed for certain accessibility declarations, - // which are imported as getter/setter pairs and not properties. - if (objcMethod->isPropertyAccessor() && !isAccessibilityDecl(objcMethod)) { - suppressDecl = true; - } - } else if (auto objcProperty = dyn_cast(named)) { - // Suppress certain accessibility properties; they're imported as - // getter/setter pairs instead. - if (isAccessibilityDecl(objcProperty)) - suppressDecl = true; - } + if (shouldSuppressDeclImport(named)) return; - if (!suppressDecl) { - // If we have a name to import as, add this entry to the table. - clang::DeclContext *effectiveContext; - if (auto importedName = importFullName(named, None, &effectiveContext)) { - table.addEntry(importedName.Imported, named, effectiveContext); + // If we have a name to import as, add this entry to the table. + clang::DeclContext *effectiveContext; + if (auto importedName = importFullName(named, None, &effectiveContext, + &clangSema)) { + table.addEntry(importedName.Imported, named, effectiveContext); - // Also add the alias, if needed. - if (importedName.Alias) - table.addEntry(importedName.Alias, named, effectiveContext); + // Also add the alias, if needed. + if (importedName.Alias) + table.addEntry(importedName.Alias, named, effectiveContext); - // Also add the subscript entry, if needed. - if (importedName.IsSubscriptAccessor) - table.addEntry(DeclName(SwiftContext, SwiftContext.Id_subscript, { }), - named, effectiveContext); - } + // Also add the subscript entry, if needed. + if (importedName.IsSubscriptAccessor) + table.addEntry(DeclName(SwiftContext, SwiftContext.Id_subscript, + ArrayRef()), + named, effectiveContext); + } else if (auto category = dyn_cast(named)) { + table.addCategory(category); } // Walk the members of any context that can have nested members. @@ -725,7 +725,47 @@ void ClangImporter::Implementation::addEntryToLookupTable( clang::DeclContext *dc = cast(named); for (auto member : dc->decls()) { if (auto namedMember = dyn_cast(member)) - addEntryToLookupTable(table, namedMember); + addEntryToLookupTable(clangSema, table, namedMember); + } + } +} + +void ClangImporter::Implementation::addMacrosToLookupTable( + clang::ASTContext &clangCtx, + clang::Preprocessor &pp, + SwiftLookupTable &table) { + for (const auto ¯o : pp.macros(false)) { + // Find the local history of this macro directive. + clang::MacroDirective *MD = pp.getLocalMacroDirectiveHistory(macro.first); + if (!MD) continue; + + // Import the name. + auto name = importIdentifier(macro.first); + if (name.empty()) continue; + + // Walk the history. + for (; MD; MD = MD->getPrevious()) { + // Check whether we have a macro defined in this module. + auto info = pp.getMacroInfo(macro.first); + if (!info || info->isFromASTFile() || info->isBuiltinMacro()) continue; + + // Only interested in macro definitions. + auto *defMD = dyn_cast(MD); + if (!defMD) continue; + + // If we hit a builtin macro, we're done. + if (auto info = defMD->getInfo()) { + if (info->isBuiltinMacro()) break; + } + + // If we hit a macro with invalid or predefined location, we're done. + auto loc = defMD->getLocation(); + if (loc.isInvalid()) break; + if (pp.getSourceManager().getFileID(loc) == pp.getPredefinesFileID()) + break; + + // Add this entry. + table.addEntry(name, info, clangCtx.getTranslationUnitDecl()); } } } @@ -764,22 +804,25 @@ bool ClangImporter::Implementation::importHeader( clang::Parser::DeclGroupPtrTy parsed; while (!Parser->ParseTopLevelDecl(parsed)) { - if (parsed && (trackParsedSymbols || UseSwiftLookupTables)) { - for (auto *D : parsed.get()) { - if (trackParsedSymbols) - addBridgeHeaderTopLevelDecls(D); - - if (UseSwiftLookupTables) { - if (auto named = dyn_cast(D)) { - addEntryToLookupTable(BridgingHeaderLookupTable, named); - } - } + if (!parsed) continue; + + for (auto *D : parsed.get()) { + if (trackParsedSymbols) + addBridgeHeaderTopLevelDecls(D); + + if (auto named = dyn_cast(D)) { + addEntryToLookupTable(getClangSema(), BridgingHeaderLookupTable, + named); } } } pp.EndSourceFile(); bumpGeneration(); + // Add any defined macros to the bridging header lookup table. + addMacrosToLookupTable(getClangASTContext(), getClangPreprocessor(), + BridgingHeaderLookupTable); + // Wrap all Clang imports under a Swift import decl. for (auto &Import : BridgeHeaderTopLevelImports) { if (auto *ClangImport = Import.dyn_cast()) { @@ -1053,11 +1096,11 @@ Module *ClangImporter::getImportedHeaderModule() const { ClangImporter::Implementation::Implementation(ASTContext &ctx, const ClangImporterOptions &opts) : SwiftContext(ctx), - InferImplicitProperties(opts.InferImplicitProperties), ImportForwardDeclarations(opts.ImportForwardDeclarations), OmitNeedlessWords(opts.OmitNeedlessWords), InferDefaultArguments(opts.InferDefaultArguments), - UseSwiftLookupTables(opts.UseSwiftLookupTables) + UseSwiftLookupTables(opts.UseSwiftLookupTables), + BridgingHeaderLookupTable(nullptr) { // Add filters to determine if a Clang availability attribute // applies in Swift, and if so, what is the cutoff for deprecated @@ -1067,8 +1110,7 @@ ClangImporter::Implementation::Implementation(ASTContext &ctx, if (!ctx.LangOpts.EnableAppExtensionRestrictions) { PlatformAvailabilityFilter = [](StringRef Platform) { return Platform == "ios"; }; - } - else { + } else { PlatformAvailabilityFilter = [](StringRef Platform) { return Platform == "ios" || @@ -1079,13 +1121,11 @@ ClangImporter::Implementation::Implementation(ASTContext &ctx, [](unsigned major, llvm::Optional minor) { return major <= 7; }; DeprecatedAsUnavailableMessage = "APIs deprecated as of iOS 7 and earlier are unavailable in Swift"; - } - else if (ctx.LangOpts.Target.isTvOS()) { + } else if (ctx.LangOpts.Target.isTvOS()) { if (!ctx.LangOpts.EnableAppExtensionRestrictions) { PlatformAvailabilityFilter = [](StringRef Platform) { return Platform == "tvos"; }; - } - else { + } else { PlatformAvailabilityFilter = [](StringRef Platform) { return Platform == "tvos" || @@ -1096,13 +1136,11 @@ ClangImporter::Implementation::Implementation(ASTContext &ctx, [](unsigned major, llvm::Optional minor) { return major <= 7; }; DeprecatedAsUnavailableMessage = "APIs deprecated as of iOS 7 and earlier are unavailable in Swift"; - } - else if (ctx.LangOpts.Target.isWatchOS()) { + } else if (ctx.LangOpts.Target.isWatchOS()) { if (!ctx.LangOpts.EnableAppExtensionRestrictions) { PlatformAvailabilityFilter = [](StringRef Platform) { return Platform == "watchos"; }; - } - else { + } else { PlatformAvailabilityFilter = [](StringRef Platform) { return Platform == "watchos" || @@ -1117,8 +1155,7 @@ ClangImporter::Implementation::Implementation(ASTContext &ctx, if (!ctx.LangOpts.EnableAppExtensionRestrictions) { PlatformAvailabilityFilter = [](StringRef Platform) { return Platform == "macosx"; }; - } - else { + } else { PlatformAvailabilityFilter = [](StringRef Platform) { return Platform == "macosx" || @@ -1454,8 +1491,9 @@ static StringRef getCommonPluralPrefix(StringRef singular, StringRef plural) { } StringRef ClangImporter::Implementation::getEnumConstantNamePrefix( + clang::Sema &sema, const clang::EnumDecl *decl) { - switch (classifyEnum(decl)) { + switch (classifyEnum(sema.getPreprocessor(), decl)) { case EnumKind::Enum: case EnumKind::Options: // Enums are mapped to Swift enums, Options to Swift option sets, both @@ -1473,8 +1511,13 @@ StringRef ClangImporter::Implementation::getEnumConstantNamePrefix( if (ec == ecEnd) return StringRef(); + // Determine whether we can cache the result. + // FIXME: Pass in a cache? + bool useCache = &sema == &getClangSema(); + // If we've already computed the prefix, return it. - auto known = EnumConstantNamePrefixes.find(decl); + auto known = useCache ? EnumConstantNamePrefixes.find(decl) + : EnumConstantNamePrefixes.end(); if (known != EnumConstantNamePrefixes.end()) return known->second; @@ -1519,12 +1562,13 @@ StringRef ClangImporter::Implementation::getEnumConstantNamePrefix( while (ec != ecEnd && (*ec)->hasAttr()) ++ec; if (ec == ecEnd) { - EnumConstantNamePrefixes.insert({decl, StringRef()}); + if (useCache) + EnumConstantNamePrefixes.insert({decl, StringRef()}); return StringRef(); } } - // Compute th e common prefix. + // Compute the common prefix. StringRef commonPrefix = (*ec)->getName(); bool followedByNonIdentifier = false; for (++ec; ec != ecEnd; ++ec) { @@ -1559,14 +1603,9 @@ StringRef ClangImporter::Implementation::getEnumConstantNamePrefix( checkPrefix = checkPrefix.drop_front(); } - // Account for the enum being imported using - // __attribute__((swift_private)). This is a little ad hoc, but it's a - // rare case anyway. - Identifier enumName = importFullName(decl).Imported.getBaseName(); - StringRef enumNameStr = enumName.str(); - if (enumNameStr.startswith("__") && !checkPrefix.startswith("__")) - enumNameStr = enumNameStr.drop_front(2); - + // Don't use importFullName() here, we want to ignore the swift_name + // and swift_private attributes. + StringRef enumNameStr = decl->getName(); StringRef commonWithEnum = getCommonPluralPrefix(checkPrefix, enumNameStr); size_t delta = commonPrefix.size() - checkPrefix.size(); @@ -1581,7 +1620,8 @@ StringRef ClangImporter::Implementation::getEnumConstantNamePrefix( commonPrefix = commonPrefix.slice(0, commonWithEnum.size() + delta); } - EnumConstantNamePrefixes.insert({decl, commonPrefix}); + if (useCache) + EnumConstantNamePrefixes.insert({decl, commonPrefix}); return commonPrefix; } @@ -1665,9 +1705,7 @@ static bool isErrorOutParameter(const clang::ParmVarDecl *param, return false; } -static bool isBoolType(ClangImporter::Implementation &importer, - clang::QualType type) { - auto &ctx = importer.getClangASTContext(); +static bool isBoolType(clang::ASTContext &ctx, clang::QualType type) { do { // Check whether we have a typedef for "BOOL" or "Boolean". if (auto typedefType = dyn_cast(type.getTypePtr())) { @@ -1693,7 +1731,7 @@ static bool isBoolType(ClangImporter::Implementation &importer, static bool isIntegerType(clang::QualType clangType) { if (auto builtinTy = clangType->getAs()) { - return (builtinTy->getKind() >= clang::BuiltinType::Char_U && + return (builtinTy->getKind() >= clang::BuiltinType::Bool && builtinTy->getKind() <= clang::BuiltinType::UInt128) || (builtinTy->getKind() >= clang::BuiltinType::SChar && builtinTy->getKind() <= clang::BuiltinType::Int128); @@ -1735,10 +1773,10 @@ static bool canImportAsOptional(clang::ASTContext &ctx, clang::QualType type) { } static Optional -classifyMethodErrorHandling(ClangImporter::Implementation &importer, - const clang::ObjCMethodDecl *clangDecl, +classifyMethodErrorHandling(const clang::ObjCMethodDecl *clangDecl, OptionalTypeKind resultOptionality) { // TODO: opt out any non-standard methods here? + clang::ASTContext &clangCtx = clangDecl->getASTContext(); // Check for an explicit attribute. if (auto attr = clangDecl->getAttr()) { @@ -1753,15 +1791,14 @@ classifyMethodErrorHandling(ClangImporter::Implementation &importer, // non-optional type. case clang::SwiftErrorAttr::NullResult: if (resultOptionality != OTK_None && - canImportAsOptional(importer.getClangASTContext(), - clangDecl->getReturnType())) + canImportAsOptional(clangCtx, clangDecl->getReturnType())) return ForeignErrorConvention::NilResult; return None; // Preserve the original result type on a zero_result unless we // imported it as Bool. case clang::SwiftErrorAttr::ZeroResult: - if (isBoolType(importer, clangDecl->getReturnType())) { + if (isBoolType(clangCtx, clangDecl->getReturnType())) { return ForeignErrorConvention::ZeroResult; } else if (isIntegerType(clangDecl->getReturnType())) { return ForeignErrorConvention::ZeroPreservedResult; @@ -1781,14 +1818,13 @@ classifyMethodErrorHandling(ClangImporter::Implementation &importer, // Otherwise, apply the default rules. // For bool results, a zero value is an error. - if (isBoolType(importer, clangDecl->getReturnType())) { + if (isBoolType(clangCtx, clangDecl->getReturnType())) { return ForeignErrorConvention::ZeroResult; } // For optional reference results, a nil value is normally an error. if (resultOptionality != OTK_None && - canImportAsOptional(importer.getClangASTContext(), - clangDecl->getReturnType())) { + canImportAsOptional(clangCtx, clangDecl->getReturnType())) { return ForeignErrorConvention::NilResult; } @@ -1931,7 +1967,7 @@ considerErrorImport(ClangImporter::Implementation &importer, } auto errorKind = - classifyMethodErrorHandling(importer, clangDecl, + classifyMethodErrorHandling(clangDecl, getResultOptionality(clangDecl, knownResultNullability)); if (!errorKind) return None; @@ -2011,7 +2047,10 @@ considerErrorImport(ClangImporter::Implementation &importer, auto ClangImporter::Implementation::importFullName( const clang::NamedDecl *D, ImportNameOptions options, - clang::DeclContext **effectiveContext) -> ImportedName { + clang::DeclContext **effectiveContext, + clang::Sema *clangSemaOverride) -> ImportedName { + clang::Sema &clangSema = clangSemaOverride ? *clangSemaOverride + : getClangSema(); ImportedName result; // Objective-C categories and extensions don't have names, despite @@ -2027,7 +2066,7 @@ auto ClangImporter::Implementation::importFullName( // scope, depending how their enclosing enumeration is imported. if (isa(D)) { auto enumDecl = cast(dc); - switch (classifyEnum(enumDecl)) { + switch (classifyEnum(clangSema.getPreprocessor(), enumDecl)) { case EnumKind::Enum: case EnumKind::Options: // Enums are mapped to Swift enums, Options to Swift option sets. @@ -2170,6 +2209,16 @@ auto ClangImporter::Implementation::importFullName( case clang::DeclarationName::Identifier: // Map the identifier. baseName = D->getDeclName().getAsIdentifierInfo()->getName(); + + if (OmitNeedlessWords) { + // For Objective-C BOOL properties, use the name of the getter + // which, conventionally, has an "is" prefix. + if (auto property = dyn_cast(D)) { + if (isBoolType(clangSema.Context, property->getType())) + baseName = property->getGetterName().getNameForSlot(0); + } + } + break; case clang::DeclarationName::ObjCMultiArgSelector: @@ -2268,10 +2317,14 @@ auto ClangImporter::Implementation::importFullName( // Is this one of the accessors for subscripts? if (objcMethod->getMethodFamily() == clang::OMF_None && objcMethod->isInstanceMethod() && - (objcMethod->getSelector() == objectAtIndexedSubscript || - objcMethod->getSelector() == setObjectAtIndexedSubscript || - objcMethod->getSelector() == objectForKeyedSubscript || - objcMethod->getSelector() == setObjectForKeyedSubscript)) + (isNonNullarySelector(objcMethod->getSelector(), + { "objectAtIndexedSubscript" }) || + isNonNullarySelector(objcMethod->getSelector(), + { "setObject", "atIndexedSubscript" }) || + isNonNullarySelector(objcMethod->getSelector(), + { "objectForKeyedSubscript" }) || + isNonNullarySelector(objcMethod->getSelector(), + { "setObject", "forKeyedSubscript" }))) result.IsSubscriptAccessor = true; break; @@ -2283,7 +2336,7 @@ auto ClangImporter::Implementation::importFullName( // Enumeration constants may have common prefixes stripped. if (isa(D)) { auto enumDecl = cast(D->getDeclContext()); - StringRef removePrefix = getEnumConstantNamePrefix(enumDecl); + StringRef removePrefix = getEnumConstantNamePrefix(clangSema, enumDecl); if (baseName.startswith(removePrefix)) baseName = baseName.substr(removePrefix.size()); } @@ -2323,19 +2376,19 @@ auto ClangImporter::Implementation::importFullName( // hidden declarations from different modules because we do a // module check before deciding that there's a conflict. bool hasConflict = false; - clang::LookupResult lookupResult(getClangSema(), D->getDeclName(), + clang::LookupResult lookupResult(clangSema, D->getDeclName(), clang::SourceLocation(), clang::Sema::LookupOrdinaryName); lookupResult.setAllowHidden(true); lookupResult.suppressDiagnostics(); - if (getClangSema().LookupName(lookupResult, /*scope=*/nullptr)) { + if (clangSema.LookupName(lookupResult, /*scope=*/nullptr)) { hasConflict = std::any_of(lookupResult.begin(), lookupResult.end(), isInSameModule); } if (!hasConflict) { lookupResult.clear(clang::Sema::LookupTagName); - if (getClangSema().LookupName(lookupResult, /*scope=*/nullptr)) { + if (clangSema.LookupName(lookupResult, /*scope=*/nullptr)) { hasConflict = std::any_of(lookupResult.begin(), lookupResult.end(), isInSameModule); } @@ -2364,7 +2417,8 @@ auto ClangImporter::Implementation::importFullName( // Local function to determine whether the given declaration is subject to // a swift_private attribute. - auto hasSwiftPrivate = [this](const clang::NamedDecl *D) { + auto clangSemaPtr = &clangSema; + auto hasSwiftPrivate = [clangSemaPtr](const clang::NamedDecl *D) { if (D->hasAttr()) return true; @@ -2372,7 +2426,7 @@ auto ClangImporter::Implementation::importFullName( // private if the parent enum is marked private. if (auto *ECD = dyn_cast(D)) { auto *ED = cast(ECD->getDeclContext()); - switch (classifyEnum(ED)) { + switch (classifyEnum(clangSemaPtr->getPreprocessor(), ED)) { case EnumKind::Constants: case EnumKind::Unknown: if (ED->hasAttr()) @@ -2392,15 +2446,17 @@ auto ClangImporter::Implementation::importFullName( }; // Omit needless words. + clang::ASTContext &clangCtx = clangSema.Context; StringScratchSpace omitNeedlessWordsScratch; if (OmitNeedlessWords) { // Objective-C properties. if (auto objcProperty = dyn_cast(D)) { auto contextType = getClangDeclContextType(D->getDeclContext()); if (!contextType.isNull()) { - auto contextTypeName = getClangTypeNameForOmission(contextType); + auto contextTypeName = getClangTypeNameForOmission(clangCtx, + contextType); auto propertyTypeName = getClangTypeNameForOmission( - objcProperty->getType()); + clangCtx, objcProperty->getType()); // Find the property names. const InheritedNameSet *allPropertyNames = nullptr; if (!contextType.isNull()) { @@ -2421,6 +2477,7 @@ auto ClangImporter::Implementation::importFullName( // Objective-C methods. if (auto method = dyn_cast(D)) { (void)omitNeedlessWordsInFunctionName( + clangSema, baseName, argumentNames, params, @@ -2932,6 +2989,84 @@ isAccessibilityConformingContext(const clang::DeclContext *ctx) { } +/// Determine whether the given method potentially conflicts with the +/// setter for a property in the given protocol. +static bool +isPotentiallyConflictingSetter(const clang::ObjCProtocolDecl *proto, + const clang::ObjCMethodDecl *method) { + auto sel = method->getSelector(); + if (sel.getNumArgs() != 1) + return false; + + clang::IdentifierInfo *setterID = sel.getIdentifierInfoForSlot(0); + if (!setterID || !setterID->getName().startswith("set")) + return false; + + for (auto *prop : proto->properties()) { + if (prop->getSetterName() == sel) + return true; + } + + return false; +} + +bool ClangImporter::Implementation::shouldSuppressDeclImport( + const clang::Decl *decl) { + if (auto objcMethod = dyn_cast(decl)) { + // If this member is a method that is a getter or setter for a + // property, don't add it into the table. property names and + // getter names (by choosing to only have a property). + // + // Note that this is suppressed for certain accessibility declarations, + // which are imported as getter/setter pairs and not properties. + if (objcMethod->isPropertyAccessor()) { + // Suppress the import of this method when the corresponding + // property is not suppressed. + return !shouldSuppressDeclImport( + objcMethod->findPropertyDecl(/*checkOverrides=*/false)); + } + + // If the method was declared within a protocol, check that it + // does not conflict with the setter of a property. + if (auto proto = dyn_cast(decl->getDeclContext())) + return isPotentiallyConflictingSetter(proto, objcMethod); + + return false; + } + + if (auto objcProperty = dyn_cast(decl)) { + // Suppress certain accessibility properties; they're imported as + // getter/setter pairs instead. + if (isAccessibilityDecl(objcProperty)) + return true; + + // Check whether there is a superclass method for the getter that + // is *not* suppressed, in which case we will need to suppress + // this property. + auto dc = objcProperty->getDeclContext(); + auto objcClass = dyn_cast(dc); + if (!objcClass) { + if (auto objcCategory = dyn_cast(dc)) + objcClass = objcCategory->getClassInterface(); + } + + if (objcClass) { + if (auto objcSuperclass = objcClass->getSuperClass()) { + if (auto getterMethod + = objcSuperclass->lookupInstanceMethod( + objcProperty->getGetterName())) { + if (!shouldSuppressDeclImport(getterMethod)) + return true; + } + } + } + + return false; + } + + return false; +} + bool ClangImporter::Implementation::isAccessibilityDecl(const clang::Decl *decl) { @@ -3046,159 +3181,6 @@ bool ClangImporter::Implementation::shouldImportAsInitializer( } #pragma mark Name lookup -void ClangImporter::lookupValue(Identifier name, VisibleDeclConsumer &consumer){ - auto &pp = Impl.Instance->getPreprocessor(); - auto &sema = Impl.Instance->getSema(); - - // Map the name. If we can't represent the Swift name in Clang, bail out now. - auto clangName = Impl.exportName(name); - if (!clangName) - return; - - // See if there's a preprocessor macro we can import by this name. - clang::IdentifierInfo *clangID = clangName.getAsIdentifierInfo(); - if (clangID && clangID->hasMacroDefinition()) { - if (auto clangMacro = pp.getMacroInfo(clangID)) { - if (auto valueDecl = Impl.importMacro(name, clangMacro)) { - consumer.foundDecl(valueDecl, DeclVisibilityKind::VisibleAtTopLevel); - } - } - } - - bool FoundType = false; - bool FoundAny = false; - auto processResults = [&](clang::LookupResult &result) { - SmallVector sortedResults{result.begin(), - result.end()}; - const clang::SourceManager &srcMgr = pp.getSourceManager(); - std::sort(sortedResults.begin(), sortedResults.end(), - [&](const clang::NamedDecl *lhs, - const clang::NamedDecl *rhs) -> bool { - clang::SourceLocation lhsLoc = lhs->getLocStart(); - clang::SourceLocation lhsExpLoc = srcMgr.getExpansionLoc(lhsLoc); - clang::SourceLocation rhsLoc = rhs->getLocStart(); - clang::SourceLocation rhsExpLoc = srcMgr.getExpansionLoc(rhsLoc); - if (lhsExpLoc == rhsExpLoc) - return srcMgr.isBeforeInTranslationUnit(srcMgr.getSpellingLoc(lhsLoc), - srcMgr.getSpellingLoc(rhsLoc)); - return srcMgr.isBeforeInTranslationUnit(lhsExpLoc, rhsExpLoc); - }); - - // FIXME: Filter based on access path? C++ access control? - for (auto decl : result) { - if (auto swiftDecl = Impl.importDeclReal(decl->getUnderlyingDecl())) { - if (auto valueDecl = dyn_cast(swiftDecl)) { - // If the importer gave us a declaration from the stdlib, make sure - // it does not show up in the lookup results for the imported module. - if (valueDecl->getDeclContext()->isModuleScopeContext() && - valueDecl->getModuleContext() == Impl.getStdlibModule()) - continue; - // Check that we didn't pick up something with a remapped name. - if (valueDecl->getName() != name) - continue; - - consumer.foundDecl(valueDecl, DeclVisibilityKind::VisibleAtTopLevel); - FoundType = FoundType || isa(valueDecl); - FoundAny = true; - } - } - } - }; - - - // Perform name lookup into the global scope. - // FIXME: Map source locations over. - clang::LookupResult lookupResult(sema, /*name=*/{}, clang::SourceLocation(), - clang::Sema::LookupOrdinaryName); - - auto lookupNameForSwift = [&](clang::DeclarationName clangNameToLookup) { - lookupResult.setLookupName(clangNameToLookup); - - lookupResult.clear(clang::Sema::LookupOrdinaryName); - if (sema.LookupName(lookupResult, /*Scope=*/nullptr)) - processResults(lookupResult); - - if (!FoundType) { - // Look up a tag name if we did not find a type with this name already. - // We don't want to introduce multiple types with same name. - lookupResult.clear(clang::Sema::LookupTagName); - if (sema.LookupName(lookupResult, /*Scope=*/nullptr)) - processResults(lookupResult); - } - - const auto *clangIDToLookup = clangNameToLookup.getAsIdentifierInfo(); - - // Look up protocol names as well. - lookupResult.clear(clang::Sema::LookupObjCProtocolName); - if (sema.LookupName(lookupResult, /*Scope=*/nullptr)) { - processResults(lookupResult); - - } else if (!FoundAny && - clangIDToLookup->getName().endswith(SWIFT_PROTOCOL_SUFFIX)) { - StringRef noProtoNameStr = clangIDToLookup->getName(); - noProtoNameStr = noProtoNameStr.drop_back(strlen(SWIFT_PROTOCOL_SUFFIX)); - auto protoIdent = &Impl.getClangASTContext().Idents.get(noProtoNameStr); - lookupResult.clear(clang::Sema::LookupObjCProtocolName); - lookupResult.setLookupName(protoIdent); - - if (sema.LookupName(lookupResult, /*Scope=*/nullptr)) - processResults(lookupResult); - } - - // If we *still* haven't found anything, try looking for 'Ref'. - // Eventually, this should be optimized by recognizing this case when - // generating the Clang module. - if (!FoundAny && clangIDToLookup) { - llvm::SmallString<128> buffer; - buffer += clangIDToLookup->getName(); - buffer += SWIFT_CFTYPE_SUFFIX; - auto refIdent = &Impl.Instance->getASTContext().Idents.get(buffer.str()); - - lookupResult.clear(clang::Sema::LookupOrdinaryName); - lookupResult.setLookupName(refIdent); - if (sema.LookupName(lookupResult, /*Scope=*/0)) { - // FIXME: Filter based on access path? C++ access control? - // FIXME: Sort this list, even though there's probably only one result. - for (auto decl : lookupResult) { - auto swiftDecl = Impl.importDeclReal(decl->getUnderlyingDecl()); - auto alias = dyn_cast_or_null(swiftDecl); - if (!alias) - continue; - - Type underlyingTy = alias->getUnderlyingType(); - TypeDecl *underlying = nullptr; - if (auto anotherAlias = - dyn_cast(underlyingTy.getPointer())) { - underlying = anotherAlias->getDecl(); - } else if (auto aliasedClass = underlyingTy->getAs()) { - underlying = aliasedClass->getDecl(); - } - - if (!underlying) - continue; - if (underlying->getName() == name) { - consumer.foundDecl(underlying, - DeclVisibilityKind::VisibleAtTopLevel); - } - } - } - } - }; - - // Actually do the lookup. - lookupNameForSwift(clangName); - - // If we haven't found anything and the name starts with "__", maybe it's a - // decl marked with the swift_private attribute. Try chopping off the prefix. - if (!FoundAny && clangID && clangID->getName().startswith("__") && - clangID->getName().size() > 2) { - StringRef unprefixedName = clangID->getName().drop_front(2); - auto unprefixedID = - &Impl.Instance->getASTContext().Idents.get(unprefixedName); - lookupNameForSwift(unprefixedID); - } -} - const clang::TypedefNameDecl * ClangImporter::Implementation::lookupTypedef(clang::DeclarationName name) { clang::Sema &sema = Instance->getSema(); @@ -3340,29 +3322,17 @@ class FilteringVisibleDeclConsumer : public swift::VisibleDeclConsumer { class FilteringDeclaredDeclConsumer : public swift::VisibleDeclConsumer { swift::VisibleDeclConsumer &NextConsumer; - SmallVectorImpl &ExtensionResults; const ClangModuleUnit *ModuleFilter = nullptr; public: FilteringDeclaredDeclConsumer(swift::VisibleDeclConsumer &consumer, - SmallVectorImpl &ExtensionResults, const ClangModuleUnit *CMU) : NextConsumer(consumer), - ExtensionResults(ExtensionResults), ModuleFilter(CMU) {} void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override { if (isDeclaredInModule(ModuleFilter, VD)) NextConsumer.foundDecl(VD, Reason); - - // Also report the extensions declared in this module (whether the extended - // type is from this module or not). - if (auto NTD = dyn_cast(VD)) { - for (auto Ext : NTD->getExtensions()) { - if (isDeclaredInModule(ModuleFilter, Ext)) - ExtensionResults.push_back(Ext); - } - } } }; @@ -3552,60 +3522,21 @@ bool ClangImporter::lookupDeclsFromHeader(StringRef Filename, return true; // no info found about that header. } -void ClangImporter::lookupVisibleDecls(VisibleDeclConsumer &Consumer) const { - if (Impl.CurrentCacheState != Implementation::CacheState::Valid) { - do { - Impl.CurrentCacheState = Implementation::CacheState::InProgress; - Impl.CachedVisibleDecls.clear(); - - ClangVectorDeclConsumer clangConsumer; - auto &sema = Impl.getClangSema(); - sema.LookupVisibleDecls(sema.getASTContext().getTranslationUnitDecl(), - clang::Sema::LookupNameKind::LookupAnyName, - clangConsumer); - - // Sort all the Clang decls we find, so that we process them - // deterministically. This *shouldn't* be necessary, but the importer - // definitely still has ordering dependencies. - auto results = clangConsumer.getResults(); - llvm::array_pod_sort(results.begin(), results.end(), - [](clang::NamedDecl * const *lhs, - clang::NamedDecl * const *rhs) -> int { - return clang::DeclarationName::compare((*lhs)->getDeclName(), - (*rhs)->getDeclName()); - }); - - for (const clang::NamedDecl *clangDecl : results) { - if (Impl.CurrentCacheState != Implementation::CacheState::InProgress) - break; - if (Decl *imported = Impl.importDeclReal(clangDecl)) - Impl.CachedVisibleDecls.push_back(cast(imported)); - } - - // If we changed things /while/ we were caching, we need to start over - // and try again. Fortunately we record a map of decls we've already - // imported, so most of the work is just the lookup and then going - // through the list. - } while (Impl.CurrentCacheState != Implementation::CacheState::InProgress); - - auto &ClangPP = Impl.getClangPreprocessor(); - for (auto I = ClangPP.macro_begin(), E = ClangPP.macro_end(); I != E; ++I) { - if (!I->first->hasMacroDefinition()) - continue; - auto Name = Impl.importIdentifier(I->first); - if (Name.empty()) - continue; - if (auto *Imported = Impl.importMacro( - Name, ClangPP.getMacroDefinition(I->first).getMacroInfo())) { - Impl.CachedVisibleDecls.push_back(Imported); - } - } +void ClangImporter::lookupValue(DeclName name, VisibleDeclConsumer &consumer){ + // Look for values in the bridging header's lookup table. + Impl.lookupValue(Impl.BridgingHeaderLookupTable, name, consumer); - Impl.CurrentCacheState = Implementation::CacheState::Valid; + // Collect and sort the set of module names. + SmallVector moduleNames; + for (const auto &entry : Impl.LookupTables) { + moduleNames.push_back(entry.first()); } + llvm::array_pod_sort(moduleNames.begin(), moduleNames.end()); - for (auto VD : Impl.CachedVisibleDecls) - Consumer.foundDecl(VD, DeclVisibilityKind::VisibleAtTopLevel); + // Look for values in the module lookup tables. + for (auto moduleName : moduleNames) { + Impl.lookupValue(*Impl.LookupTables[moduleName].get(), name, consumer); + } } void ClangModuleUnit::lookupVisibleDecls(Module::AccessPathTy accessPath, @@ -3627,7 +3558,11 @@ void ClangModuleUnit::lookupVisibleDecls(Module::AccessPathTy accessPath, actualConsumer = &darwinBlacklistConsumer; } - owner.lookupVisibleDecls(*actualConsumer); + // Find the corresponding lookup table. + if (auto lookupTable = owner.Impl.findLookupTable(clangModule)) { + // Search it. + owner.Impl.lookupVisibleDecls(*lookupTable, *actualConsumer); + } } namespace { @@ -3645,19 +3580,28 @@ class VectorDeclPtrConsumer : public swift::VisibleDeclConsumer { void ClangModuleUnit::getTopLevelDecls(SmallVectorImpl &results) const { VectorDeclPtrConsumer consumer(results); - SmallVector extensions; - FilteringDeclaredDeclConsumer filterConsumer(consumer, extensions, this); + FilteringDeclaredDeclConsumer filterConsumer(consumer, this); DarwinBlacklistDeclConsumer blacklistConsumer(filterConsumer, getClangASTContext()); const clang::Module *topLevelModule = clangModule->getTopLevelModule(); - if (DarwinBlacklistDeclConsumer::needsBlacklist(topLevelModule)) { - owner.lookupVisibleDecls(blacklistConsumer); - } else { - owner.lookupVisibleDecls(filterConsumer); - } - results.append(extensions.begin(), extensions.end()); + swift::VisibleDeclConsumer *actualConsumer = &filterConsumer; + if (DarwinBlacklistDeclConsumer::needsBlacklist(topLevelModule)) + actualConsumer = &blacklistConsumer; + + // Find the corresponding lookup table. + if (auto lookupTable = owner.Impl.findLookupTable(topLevelModule)) { + // Search it. + owner.Impl.lookupVisibleDecls(*lookupTable, *actualConsumer); + + // Add the extensions produced by importing categories. + for (auto category : lookupTable->categories()) { + if (auto extension = cast_or_null( + owner.Impl.importDecl(category))) + results.push_back(extension); + } + } } ImportDecl *swift::createImportDecl(ASTContext &Ctx, @@ -3716,10 +3660,6 @@ void ClangModuleUnit::lookupValue(Module::AccessPathTy accessPath, if (!Module::matchesAccessPath(accessPath, name)) return; - // There should be no multi-part top-level decls in a Clang module. - if (!name.isSimpleName()) - return; - // FIXME: Ignore submodules, which are empty for now. if (clangModule && clangModule->isSubModule()) return; @@ -3736,7 +3676,11 @@ void ClangModuleUnit::lookupValue(Module::AccessPathTy accessPath, consumer = &darwinBlacklistConsumer; } - owner.lookupValue(name.getBaseName(), *consumer); + // Find the corresponding lookup table. + if (auto lookupTable = owner.Impl.findLookupTable(clangModule)) { + // Search it. + owner.Impl.lookupValue(*lookupTable, name, *consumer); + } } void ClangImporter::loadExtensions(NominalTypeDecl *nominal, @@ -3836,132 +3780,6 @@ void ClangImporter::loadObjCMethods( } } -// FIXME: This should just be the implementation of -// llvm::array_pod_sort_comparator. The only difference is that it uses -// std::less instead of operator<. -// FIXME: Copied from IRGenModule.cpp. -template -static int pointerPODSortComparator(T * const *lhs, T * const *rhs) { - std::less lt; - if (lt(*lhs, *rhs)) - return -1; - if (lt(*rhs, *lhs)) - return -1; - return 0; -} - - -static void lookupClassMembersImpl(ClangImporter::Implementation &Impl, - VisibleDeclConsumer &consumer, - DeclName name) { - // When looking for a subscript, we actually look for the getters - // and setters. - bool isSubscript = name.isSimpleName(Impl.SwiftContext.Id_subscript); - - // FIXME: Does not include methods from protocols. - auto importMethodsImpl = [&](const clang::ObjCMethodList &start) { - for (auto *list = &start; list != nullptr; list = list->getNext()) { - if (list->getMethod()->isUnavailable()) - continue; - - // If the method is a property accessor, we want the property. - const clang::NamedDecl *searchForDecl = list->getMethod(); - if (list->getMethod()->isPropertyAccessor() && - !Impl.isAccessibilityDecl(list->getMethod())) { - if (auto property = list->getMethod()->findPropertyDecl()) { - // ... unless we are enumerating all decls. In this case, if we see - // a getter, return a property. If we see a setter, we know that - // there is a getter, and we will visit it and return a property at - // that time. - if (!name && list->getMethod()->param_size() != 0) - continue; - searchForDecl = property; - } - } - - auto VD = cast_or_null(Impl.importDeclReal(searchForDecl)); - if (!VD) - continue; - - if (auto func = dyn_cast(VD)) { - if (auto storage = func->getAccessorStorageDecl()) { - consumer.foundDecl(storage, DeclVisibilityKind::DynamicLookup); - continue; - } else if (isSubscript || !name) { - auto known = Impl.Subscripts.find({func, nullptr}); - if (known != Impl.Subscripts.end()) { - consumer.foundDecl(known->second, - DeclVisibilityKind::DynamicLookup); - } - - // If we were looking only for subscripts, don't report the getter. - if (isSubscript) - continue; - } - } - - consumer.foundDecl(VD, DeclVisibilityKind::DynamicLookup); - } - }; - - auto importMethods = [=](const clang::Sema::GlobalMethods &methodListPair) { - if (methodListPair.first.getMethod()) - importMethodsImpl(methodListPair.first); - if (methodListPair.second.getMethod()) - importMethodsImpl(methodListPair.second); - }; - - clang::Sema &S = Impl.getClangSema(); - - if (isSubscript) { - clang::Selector sels[] = { - Impl.objectAtIndexedSubscript, - Impl.setObjectAtIndexedSubscript, - Impl.objectForKeyedSubscript, - Impl.setObjectForKeyedSubscript - }; - for (auto sel : sels) { - S.ReadMethodPool(sel); - importMethods(S.MethodPool[sel]); - } - - } else if (name) { - auto sel = Impl.exportSelector(name); - if (!sel.isNull()) { - S.ReadMethodPool(sel); - importMethods(S.MethodPool[sel]); - - // If this is a simple name, we only checked nullary selectors. Check - // unary ones as well. - // Note: If this is ever used to look up init methods, we'd need to do - // the reverse as well. - if (name.isSimpleName()) { - auto *II = Impl.exportName(name.getBaseName()).getAsIdentifierInfo(); - sel = Impl.getClangASTContext().Selectors.getUnarySelector(II); - assert(!sel.isNull()); - - S.ReadMethodPool(sel); - importMethods(S.MethodPool[sel]); - } - } - - } else { - // Force load all external methods. - // FIXME: Copied from Clang's SemaCodeComplete. - clang::ExternalASTSource *source = S.getExternalSource(); - for (uint32_t i = 0, n = source->GetNumExternalSelectors(); i != n; ++i) { - clang::Selector sel = source->GetExternalSelector(i); - if (sel.isNull() || S.MethodPool.count(sel)) - continue; - - S.ReadMethodPool(sel); - } - - for (auto entry : S.MethodPool) - importMethods(entry.second); - } -} - void ClangModuleUnit::lookupClassMember(Module::AccessPathTy accessPath, DeclName name, @@ -3970,9 +3788,13 @@ ClangModuleUnit::lookupClassMember(Module::AccessPathTy accessPath, if (clangModule && clangModule->isSubModule()) return; - // FIXME: Not limited by module. VectorDeclConsumer consumer(results); - lookupClassMembersImpl(owner.Impl, consumer, name); + + // Find the corresponding lookup table. + if (auto lookupTable = owner.Impl.findLookupTable(clangModule)) { + // Search it. + owner.Impl.lookupObjCMembers(*lookupTable, name, consumer); + } } void ClangModuleUnit::lookupClassMembers(Module::AccessPathTy accessPath, @@ -3981,8 +3803,11 @@ void ClangModuleUnit::lookupClassMembers(Module::AccessPathTy accessPath, if (clangModule && clangModule->isSubModule()) return; - // FIXME: Not limited by module. - lookupClassMembersImpl(owner.Impl, consumer, {}); + // Find the corresponding lookup table. + if (auto lookupTable = owner.Impl.findLookupTable(clangModule)) { + // Search it. + owner.Impl.lookupAllObjCMembers(*lookupTable, consumer); + } } void ClangModuleUnit::collectLinkLibraries( @@ -4289,10 +4114,250 @@ void ClangImporter::getMangledName(raw_ostream &os, Impl.Mangler->mangleName(clangDecl, os); } +// --------------------------------------------------------------------------- +// Swift lookup tables +// --------------------------------------------------------------------------- + +clang::ModuleFileExtensionMetadata +ClangImporter::Implementation::getExtensionMetadata() const { + clang::ModuleFileExtensionMetadata metadata; + metadata.BlockName = "swift.lookup"; + metadata.MajorVersion = SWIFT_LOOKUP_TABLE_VERSION_MAJOR; + metadata.MinorVersion = SWIFT_LOOKUP_TABLE_VERSION_MINOR; + metadata.UserInfo = version::getSwiftFullVersion(); + return metadata; +} + +llvm::hash_code ClangImporter::Implementation::hashExtension( + llvm::hash_code code) const { + return llvm::hash_combine(code, StringRef("swift.lookup"), + SWIFT_LOOKUP_TABLE_VERSION_MAJOR, + SWIFT_LOOKUP_TABLE_VERSION_MINOR, + OmitNeedlessWords, + InferDefaultArguments); +} + +std::unique_ptr +ClangImporter::Implementation::createExtensionWriter(clang::ASTWriter &writer) { + // Local function to populate the lookup table. + auto populateTable = [this](clang::Sema &sema, SwiftLookupTable &table) { + for (auto decl + : sema.Context.getTranslationUnitDecl()->noload_decls()) { + // Skip anything from an AST file. + if (decl->isFromASTFile()) continue; + + // Skip non-named declarations. + auto named = dyn_cast(decl); + if (!named) continue; + + // Add this entry to the lookup table. + addEntryToLookupTable(sema, table, named); + } + + // Add macros to the lookup table. + addMacrosToLookupTable(sema.Context, sema.getPreprocessor(), table); + }; + + return std::unique_ptr( + new SwiftLookupTableWriter(this, populateTable, writer)); +} + +std::unique_ptr +ClangImporter::Implementation::createExtensionReader( + const clang::ModuleFileExtensionMetadata &metadata, + clang::ASTReader &reader, + clang::serialization::ModuleFile &mod, + const llvm::BitstreamCursor &stream) +{ + // Make sure we have a compatible block. Since these values are part + // of the hash, it should never be wrong. + assert(metadata.BlockName == "swift.lookup"); + assert(metadata.MajorVersion == SWIFT_LOOKUP_TABLE_VERSION_MAJOR); + assert(metadata.MinorVersion == SWIFT_LOOKUP_TABLE_VERSION_MINOR); + + // Check whether we already have an entry in the set of lookup tables. + auto &entry = LookupTables[mod.ModuleName]; + if (entry) return nullptr; + + // Local function used to remove this entry when the reader goes away. + std::string moduleName = mod.ModuleName; + auto onRemove = [this, moduleName]() { + LookupTables.erase(moduleName); + }; + + // Create the reader. + auto tableReader = SwiftLookupTableReader::create(this, reader, mod, onRemove, + stream); + if (!tableReader) return nullptr; + + // Create the lookup table. + entry.reset(new SwiftLookupTable(tableReader.get())); + + // Return the new reader. + return std::move(tableReader); +} + +SwiftLookupTable *ClangImporter::Implementation::findLookupTable( + const clang::Module *clangModule) { + // If the Clang module is null, use the bridging header lookup table. + if (!clangModule) + return &BridgingHeaderLookupTable; + + // Submodules share lookup tables with their parents. + if (clangModule->isSubModule()) + return findLookupTable(clangModule->getTopLevelModule()); + + // Look for a Clang module with this name. + auto known = LookupTables.find(clangModule->Name); + if (known == LookupTables.end()) return nullptr; + + return known->second.get(); +} + +/// Determine whether the given Clang entry is visible. +/// +/// FIXME: this is an elaborate hack to badly reflect Clang's +/// submodule visibility into Swift. +static bool isVisibleClangEntry(clang::Preprocessor &pp, + StringRef name, + SwiftLookupTable::SingleEntry entry) { + if (auto clangDecl = entry.dyn_cast()) { + // For a declaration, check whether the declaration is hidden. + if (!clangDecl->isHidden()) return true; + + // Is any redeclaration visible? + for (auto redecl : clangDecl->redecls()) { + if (!cast(redecl)->isHidden()) return true; + } + + return false; + } + + // Check whether the macro is defined. + // FIXME: We could get the wrong macro definition here. + return pp.isMacroDefined(name); +} + +void ClangImporter::Implementation::lookupValue( + SwiftLookupTable &table, DeclName name, + VisibleDeclConsumer &consumer) { + auto clangTU = getClangASTContext().getTranslationUnitDecl(); + auto &clangPP = getClangPreprocessor(); + auto baseName = name.getBaseName().str(); + + for (auto entry : table.lookup(name.getBaseName().str(), clangTU)) { + // If the entry is not visible, skip it. + if (!isVisibleClangEntry(clangPP, baseName, entry)) continue; + + ValueDecl *decl; + + // If it's a Clang declaration, try to import it. + if (auto clangDecl = entry.dyn_cast()) { + decl = cast_or_null( + importDeclReal(clangDecl->getMostRecentDecl())); + if (!decl) continue; + } else { + // Try to import a macro. + auto clangMacro = entry.get(); + decl = importMacro(name.getBaseName(), clangMacro); + if (!decl) continue; + } + + // If we found a declaration from the standard library, make sure + // it does not show up in the lookup results for the imported + // module. + if (decl->getDeclContext()->isModuleScopeContext() && + decl->getModuleContext() == getStdlibModule()) + continue; + + // If the name matched, report this result. + if (decl->getFullName().matchesRef(name)) + consumer.foundDecl(decl, DeclVisibilityKind::VisibleAtTopLevel); + + // If there is an alternate declaration and the name matches, + // report this result. + if (auto alternate = getAlternateDecl(decl)) { + if (alternate->getFullName().matchesRef(name)) + consumer.foundDecl(alternate, DeclVisibilityKind::VisibleAtTopLevel); + } + } +} + +void ClangImporter::Implementation::lookupVisibleDecls( + SwiftLookupTable &table, + VisibleDeclConsumer &consumer) { + // Retrieve and sort all of the base names in this particular table. + auto baseNames = table.allBaseNames(); + llvm::array_pod_sort(baseNames.begin(), baseNames.end()); + + // Look for namespace-scope entities with each base name. + for (auto baseName : baseNames) { + lookupValue(table, SwiftContext.getIdentifier(baseName), consumer); + } +} + +void ClangImporter::Implementation::lookupObjCMembers( + SwiftLookupTable &table, + DeclName name, + VisibleDeclConsumer &consumer) { + auto &clangPP = getClangPreprocessor(); + auto baseName = name.getBaseName().str(); + + for (auto clangDecl : table.lookupObjCMembers(baseName)) { + // If the entry is not visible, skip it. + if (!isVisibleClangEntry(clangPP, baseName, clangDecl)) continue; + + // Import the declaration. + auto decl = cast_or_null(importDeclReal(clangDecl)); + if (!decl) + continue; + + // If the name we found matches, report the declaration. + if (decl->getFullName().matchesRef(name)) + consumer.foundDecl(decl, DeclVisibilityKind::DynamicLookup); + + // Check for an alternate declaration; if it's name matches, + // report it. + if (auto alternate = getAlternateDecl(decl)) { + if (alternate->getFullName().matchesRef(name)) + consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup); + } + } +} + +void ClangImporter::Implementation::lookupAllObjCMembers( + SwiftLookupTable &table, + VisibleDeclConsumer &consumer) { + // Retrieve and sort all of the base names in this particular table. + auto baseNames = table.allBaseNames(); + llvm::array_pod_sort(baseNames.begin(), baseNames.end()); + + // Look for Objective-C members with each base name. + for (auto baseName : baseNames) { + lookupObjCMembers(table, SwiftContext.getIdentifier(baseName), consumer); + } +} + void ClangImporter::dumpSwiftLookupTables() { Impl.dumpSwiftLookupTables(); } void ClangImporter::Implementation::dumpSwiftLookupTables() { + // Sort the module names so we can print in a deterministic order. + SmallVector moduleNames; + for (const auto &lookupTable : LookupTables) { + moduleNames.push_back(lookupTable.first()); + } + array_pod_sort(moduleNames.begin(), moduleNames.end()); + + // Print out the lookup tables for the various modules. + for (auto moduleName : moduleNames) { + llvm::errs() << "<<" << moduleName << " lookup table>>\n"; + LookupTables[moduleName]->deserializeAll(); + LookupTables[moduleName]->dump(); + } + + + llvm::errs() << "<>\n"; BridgingHeaderLookupTable.dump(); } diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index c8acbb3ffbb2f..7891701434098 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,6 +23,7 @@ #include "swift/AST/Expr.h" #include "swift/AST/Module.h" #include "swift/AST/NameLookup.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/Pattern.h" #include "swift/AST/Stmt.h" #include "swift/AST/Types.h" @@ -61,15 +62,6 @@ namespace inferred_attributes { } } -/// \brief Retrieve the type of 'self' for the given context. -static Type getSelfTypeForContext(DeclContext *dc) { - // For a protocol or extension thereof, the type is 'Self'. - // FIXME: Weird that we're producing an archetype for protocol Self, - // but the declared type of the context in non-protocol cases. - if (dc->isProtocolOrProtocolExtensionContext()) - return dc->getProtocolSelf()->getArchetype(); - return dc->getDeclaredTypeOfContext(); -} static bool isInSystemModule(DeclContext *D) { if (cast(D->getModuleScopeContext())->isSystemModule()) @@ -77,34 +69,6 @@ static bool isInSystemModule(DeclContext *D) { return false; } -/// Create an implicit 'self' decl for a method in the specified type. If -/// 'static' is true, then this is self for a static method in the type. -/// -/// Note that this decl is created, but it is returned with an incorrect -/// DeclContext that needs to be reset once the method exists. -/// -static VarDecl *createSelfDecl(DeclContext *DC, bool isStaticMethod, - bool isInOut = false) { - auto selfType = getSelfTypeForContext(DC); - - ASTContext &C = DC->getASTContext(); - - if (isStaticMethod) - selfType = MetatypeType::get(selfType); - - bool isLet = true; - if (auto *ND = selfType->getAnyNominal()) - isLet = !isInOut && !isa(ND) && !isa(ND); - - if (isInOut) - selfType = InOutType::get(selfType); - - VarDecl *selfDecl = new (C) ParamDecl(/*IsLet*/isLet, SourceLoc(), - Identifier(), SourceLoc(), C.Id_self, - selfType, DC); - selfDecl->setImplicit(); - return selfDecl; -} /// Create a typedpattern(namedpattern(decl)) static Pattern *createTypedNamedPattern(VarDecl *decl) { @@ -121,9 +85,9 @@ static Pattern *createTypedNamedPattern(VarDecl *decl) { } template -static bool verifyNameMapping(MappedTypeNameKind NameMappping, +static bool verifyNameMapping(MappedTypeNameKind NameMapping, const char (&left)[A], const char (&right)[B]) { - return NameMappping == MappedTypeNameKind::DoNothing || + return NameMapping == MappedTypeNameKind::DoNothing || strcmp(left, right) != 0; } @@ -333,26 +297,23 @@ static FuncDecl *makeRawValueTrivialGetter(ClangImporter::Implementation &Impl, StructDecl *optionSetDecl, ValueDecl *rawDecl) { ASTContext &C = Impl.SwiftContext; - auto optionSetType = optionSetDecl->getDeclaredTypeInContext(); auto rawType = rawDecl->getType(); - VarDecl *selfDecl = createSelfDecl(optionSetDecl, false); - Pattern *selfParam = createTypedNamedPattern(selfDecl); + auto *selfDecl = ParamDecl::createSelf(SourceLoc(), optionSetDecl); - Pattern *methodParam = TuplePattern::create(C, SourceLoc(),{},SourceLoc()); - methodParam->setType(TupleType::getEmpty(C)); - Pattern *params[] = {selfParam, methodParam}; + ParameterList *params[] = { + ParameterList::createWithoutLoc(selfDecl), + ParameterList::createEmpty(C) + }; + Type toRawType = ParameterList::getFullType(rawType, params); FuncDecl *getterDecl = FuncDecl::create( C, SourceLoc(), StaticSpellingKind::None, SourceLoc(), - DeclName(), SourceLoc(), SourceLoc(), SourceLoc(), nullptr, Type(), params, + DeclName(), SourceLoc(), SourceLoc(), SourceLoc(), nullptr, toRawType, + params, TypeLoc::withoutLoc(rawType), optionSetDecl); getterDecl->setImplicit(); - auto toRawArgType = TupleType::getEmpty(C); - Type toRawType = FunctionType::get(toRawArgType, rawType); - toRawType = FunctionType::get(optionSetType, toRawType); - getterDecl->setType(toRawType); getterDecl->setBodyResultType(rawType); getterDecl->setAccessibility(Accessibility::Public); @@ -389,27 +350,21 @@ static FuncDecl *makeRawValueTrivialSetter(ClangImporter::Implementation &Impl, ValueDecl *rawDecl) { // FIXME: Largely duplicated from the type checker. ASTContext &C = Impl.SwiftContext; - auto selfType = importedDecl->getDeclaredTypeInContext(); auto rawType = rawDecl->getType(); - VarDecl *selfDecl = new (C) ParamDecl(/*IsLet*/false, SourceLoc(), - Identifier(), SourceLoc(), - C.Id_self, selfType, - importedDecl); - selfDecl->setImplicit(); - Pattern *selfParam = createTypedNamedPattern(selfDecl); - - VarDecl *newValueDecl = new (C) ParamDecl(/*IsLet*/true, SourceLoc(), - Identifier(), SourceLoc(), - C.Id_value, rawType, importedDecl); + auto *selfDecl = ParamDecl::createSelf(SourceLoc(), importedDecl, + /*static*/false, /*inout*/true); + auto *newValueDecl = new (C) ParamDecl(/*IsLet*/true, SourceLoc(), + Identifier(), SourceLoc(), + C.Id_value, rawType, importedDecl); newValueDecl->setImplicit(); - Pattern *newValueParam = createTypedNamedPattern(newValueDecl); - newValueParam = new (C) ParenPattern(SourceLoc(), newValueParam, SourceLoc()); - newValueParam->setType(ParenType::get(C, rawType)); - - Pattern *params[] = {selfParam, newValueParam}; + + ParameterList *params[] = { + ParameterList::createWithoutLoc(selfDecl), + ParameterList::createWithoutLoc(newValueDecl) + }; + Type voidTy = TupleType::getEmpty(C); - FuncDecl *setterDecl = FuncDecl::create( C, SourceLoc(), StaticSpellingKind::None, SourceLoc(), DeclName(), SourceLoc(), SourceLoc(), SourceLoc(), nullptr, Type(), params, @@ -417,9 +372,7 @@ static FuncDecl *makeRawValueTrivialSetter(ClangImporter::Implementation &Impl, setterDecl->setImplicit(); setterDecl->setMutating(); - Type fnTy = FunctionType::get(newValueParam->getType(), voidTy); - fnTy = FunctionType::get(selfType, fnTy); - setterDecl->setType(fnTy); + setterDecl->setType(ParameterList::getFullType(voidTy, params)); setterDecl->setBodyResultType(voidTy); setterDecl->setAccessibility(Accessibility::Public); @@ -462,41 +415,27 @@ makeEnumRawValueConstructor(ClangImporter::Implementation &Impl, auto enumTy = enumDecl->getDeclaredTypeInContext(); auto metaTy = MetatypeType::get(enumTy); - VarDecl *selfDecl = createSelfDecl(enumDecl, false); - Pattern *selfPattern = createTypedNamedPattern(selfDecl); + auto selfDecl = ParamDecl::createSelf(SourceLoc(), enumDecl, + /*static*/false, /*inout*/true); auto param = new (C) ParamDecl(/*let*/ true, SourceLoc(), C.Id_rawValue, SourceLoc(), C.Id_rawValue, enumDecl->getRawType(), enumDecl); - Pattern *paramPattern = new (C) NamedPattern(param); - paramPattern->setType(enumDecl->getRawType()); - paramPattern->setImplicit(); - paramPattern = new (C) - TypedPattern(paramPattern, TypeLoc::withoutLoc(enumDecl->getRawType())); - paramPattern->setType(enumDecl->getRawType()); - paramPattern->setImplicit(); + auto paramPL = ParameterList::createWithoutLoc(param); - auto patternElt = TuplePatternElt(paramPattern); - patternElt.setLabel(C.Id_rawValue, SourceLoc()); - paramPattern = TuplePattern::create(C, SourceLoc(), patternElt, SourceLoc()); - paramPattern->setImplicit(); - auto typeElt = TupleTypeElt(enumDecl->getRawType(), C.Id_rawValue); - auto paramTy = TupleType::get(typeElt, C); - paramPattern->setType(paramTy); - - DeclName name(C, C.Id_init, C.Id_rawValue); + DeclName name(C, C.Id_init, paramPL); auto *ctorDecl = new (C) ConstructorDecl(name, enumDecl->getLoc(), OTK_Optional, SourceLoc(), - selfPattern, paramPattern, + selfDecl, paramPL, nullptr, SourceLoc(), enumDecl); ctorDecl->setImplicit(); ctorDecl->setAccessibility(Accessibility::Public); auto optEnumTy = OptionalType::get(enumTy); - auto fnTy = FunctionType::get(paramTy, optEnumTy); + auto fnTy = FunctionType::get(paramPL->getType(C), optEnumTy); auto allocFnTy = FunctionType::get(metaTy, fnTy); auto initFnTy = FunctionType::get(enumTy, fnTy); ctorDecl->setType(allocFnTy); @@ -510,7 +449,7 @@ makeEnumRawValueConstructor(ClangImporter::Implementation &Impl, auto paramRef = new (C) DeclRefExpr(param, SourceLoc(), /*implicit*/ true); auto reinterpretCast - = cast(getBuiltinValueDecl(C, C.getIdentifier("reinterpretCast"))); + = cast(getBuiltinValueDecl(C,C.getIdentifier("reinterpretCast"))); auto reinterpretCastRef = new (C) DeclRefExpr(reinterpretCast, SourceLoc(), /*implicit*/ true); auto reinterpreted = new (C) CallExpr(reinterpretCastRef, paramRef, @@ -540,17 +479,12 @@ static FuncDecl *makeEnumRawValueGetter(ClangImporter::Implementation &Impl, VarDecl *rawValueDecl) { ASTContext &C = Impl.SwiftContext; - VarDecl *selfDecl = createSelfDecl(enumDecl, false); - Pattern *selfPattern = createTypedNamedPattern(selfDecl); + auto selfDecl = ParamDecl::createSelf(SourceLoc(), enumDecl); - Pattern *methodParam = TuplePattern::create(C, SourceLoc(),{},SourceLoc()); - auto unitTy = TupleType::getEmpty(C); - methodParam->setType(unitTy); - - Pattern *params[] = {selfPattern, methodParam}; - - auto fnTy = FunctionType::get(unitTy, enumDecl->getRawType()); - fnTy = FunctionType::get(selfDecl->getType(), fnTy); + ParameterList *params[] = { + ParameterList::createWithoutLoc(selfDecl), + ParameterList::createEmpty(C) + }; auto getterDecl = FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, SourceLoc(), @@ -558,7 +492,8 @@ static FuncDecl *makeEnumRawValueGetter(ClangImporter::Implementation &Impl, Type(), params, TypeLoc::withoutLoc(enumDecl->getRawType()), enumDecl); getterDecl->setImplicit(); - getterDecl->setType(fnTy); + getterDecl->setType(ParameterList::getFullType(enumDecl->getRawType(), + params)); getterDecl->setBodyResultType(enumDecl->getRawType()); getterDecl->setAccessibility(Accessibility::Public); @@ -590,32 +525,23 @@ static FuncDecl *makeFieldGetterDecl(ClangImporter::Implementation &Impl, VarDecl *importedFieldDecl, ClangNode clangNode = ClangNode()) { auto &C = Impl.SwiftContext; - auto selfDecl = createSelfDecl(importedDecl, /*is static*/ false); - auto selfPattern = createTypedNamedPattern(selfDecl); - - auto getterFnRetTypeLoc = TypeLoc::withoutLoc(importedFieldDecl->getType()); - auto getterMethodParam = TuplePattern::create(C, SourceLoc(), {}, SourceLoc()); - Pattern *getterParams[] = { selfPattern, getterMethodParam }; + auto selfDecl = ParamDecl::createSelf(SourceLoc(), importedDecl); + ParameterList *params[] = { + ParameterList::createWithoutLoc(selfDecl), + ParameterList::createEmpty(C) + }; + + auto getterType = importedFieldDecl->getType(); auto getterDecl = FuncDecl::create(C, importedFieldDecl->getLoc(), StaticSpellingKind::None, SourceLoc(), DeclName(), SourceLoc(), SourceLoc(), SourceLoc(), nullptr, Type(), - getterParams, getterFnRetTypeLoc, + params, TypeLoc::withoutLoc(getterType), importedDecl, clangNode); getterDecl->setAccessibility(Accessibility::Public); - - auto voidTy = TupleType::getEmpty(C); - - // Create the field getter - auto getterFnTy = FunctionType::get(voidTy, importedFieldDecl->getType()); - - // Getter methods need to take self as the first argument. Wrap the - // function type to take the self type. - getterFnTy = FunctionType::get(selfDecl->getType(), getterFnTy); - - getterDecl->setType(getterFnTy); - getterDecl->setBodyResultType(importedFieldDecl->getType()); + getterDecl->setType(ParameterList::getFullType(getterType, params)); + getterDecl->setBodyResultType(getterType); return getterDecl; } @@ -625,43 +551,27 @@ static FuncDecl *makeFieldSetterDecl(ClangImporter::Implementation &Impl, VarDecl *importedFieldDecl, ClangNode clangNode = ClangNode()) { auto &C = Impl.SwiftContext; - auto inoutSelfDecl = createSelfDecl(importedDecl, - /*isStaticMethod*/ false, - /*isInOut*/ true); - auto inoutSelfPattern = createTypedNamedPattern(inoutSelfDecl); - - auto voidTy = TupleType::getEmpty(C); - - auto setterFnRetTypeLoc = TypeLoc::withoutLoc(voidTy); - + auto selfDecl = ParamDecl::createSelf(SourceLoc(), importedDecl, + /*isStatic*/false, /*isInOut*/true); auto newValueDecl = new (C) ParamDecl(/*isLet */ true, SourceLoc(), Identifier(), SourceLoc(), C.Id_value, importedFieldDecl->getType(), importedDecl); - Pattern *setterNewValueParam = createTypedNamedPattern(newValueDecl); - // FIXME: Remove ParenPattern? - setterNewValueParam = new (C) ParenPattern(SourceLoc(), setterNewValueParam, - SourceLoc()); - setterNewValueParam->setType(ParenType::get(C, importedFieldDecl->getType())); + ParameterList *params[] = { + ParameterList::createWithoutLoc(selfDecl), + ParameterList::createWithoutLoc(newValueDecl), + }; - Pattern *setterParams[] = { inoutSelfPattern, setterNewValueParam }; + auto voidTy = TupleType::getEmpty(C); auto setterDecl = FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, SourceLoc(), DeclName(), SourceLoc(), SourceLoc(), SourceLoc(), nullptr, Type(), - setterParams, setterFnRetTypeLoc, + params, TypeLoc::withoutLoc(voidTy), importedDecl, clangNode); - - // Create the field setter - auto setterFnTy = FunctionType::get(importedFieldDecl->getType(), voidTy); - - // Setter methods need to take self as the first argument. Wrap the - // function type to take the self type. - setterFnTy = FunctionType::get(inoutSelfDecl->getType(), - setterFnTy); - setterDecl->setType(setterFnTy); + setterDecl->setType(ParameterList::getFullType(voidTy, params)); setterDecl->setBodyResultType(voidTy); setterDecl->setAccessibility(Accessibility::Public); setterDecl->setMutating(); @@ -733,7 +643,7 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl, auto inoutSelf = new (C) InOutExpr(SourceLoc(), inoutSelfRef, InOutType::get(importedUnionDecl->getType()), /*implicit*/ true); - auto newValueDecl = setterDecl->getBodyParamPatterns()[1]->getSingleVar(); + auto newValueDecl = setterDecl->getParameterList(1)->get(0); auto newValueRef = new (C) DeclRefExpr(newValueDecl, SourceLoc(), /*implicit*/ true); @@ -747,10 +657,10 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl, C, C.getIdentifier("initialize"))); auto initializeFnRef = new (C) DeclRefExpr(initializeFn, SourceLoc(), /*implicit*/ true); - auto initalizeArgs = TupleExpr::createImplicit(C, + auto initializeArgs = TupleExpr::createImplicit(C, { newValueRef, selfPointer }, {}); - auto initialize = new (C) CallExpr(initializeFnRef, initalizeArgs, + auto initialize = new (C) CallExpr(initializeFnRef, initializeArgs, /*implicit*/ true); auto body = BraceStmt::create(C, SourceLoc(), { initialize }, SourceLoc(), /*implicit*/ true); @@ -1382,10 +1292,10 @@ namespace { return Type(); } - Type importCFClassType(const clang::TypedefNameDecl *decl, - Identifier className, CFPointeeInfo info) { + ClassDecl *importCFClassType(const clang::TypedefNameDecl *decl, + Identifier className, CFPointeeInfo info) { auto dc = Impl.importDeclContextOf(decl); - if (!dc) return Type(); + if (!dc) return nullptr; Type superclass = findCFSuperclass(decl, info); @@ -1437,7 +1347,7 @@ namespace { } } - return theClass->getDeclaredType(); + return theClass; } Decl *VisitTypedefNameDecl(const clang::TypedefNameDecl *Decl) { @@ -1446,6 +1356,7 @@ namespace { if (Name.empty()) return nullptr; + ValueDecl *alternateDecl = nullptr; Type SwiftType; if (Decl->getDeclContext()->getRedeclContext()->isTranslationUnit()) { bool IsError; @@ -1464,8 +1375,10 @@ namespace { if (auto pointee = CFPointeeInfo::classifyTypedef(Decl)) { // If the pointee is a record, consider creating a class type. if (pointee.isRecord()) { - SwiftType = importCFClassType(Decl, Name, pointee); - if (!SwiftType) return nullptr; + auto SwiftClass = importCFClassType(Decl, Name, pointee); + if (!SwiftClass) return nullptr; + + SwiftType = SwiftClass->getDeclaredInterfaceType(); NameMapping = MappedTypeNameKind::DefineOnly; // If there is an alias (i.e., that doesn't have "Ref"), @@ -1473,6 +1386,9 @@ namespace { if (importedName.Alias) Name = importedName.Alias.getBaseName(); + // Record the class as the alternate decl. + alternateDecl = SwiftClass; + // If the pointee is another CF typedef, create an extra typealias // for the name without "Ref", but not a separate type. } else if (pointee.isTypedef()) { @@ -1508,6 +1424,9 @@ namespace { aliasWithoutRef->computeType(); SwiftType = aliasWithoutRef->getDeclaredType(); NameMapping = MappedTypeNameKind::DefineOnly; + + // Store this alternative declaration. + alternateDecl = aliasWithoutRef; } else { NameMapping = MappedTypeNameKind::DefineAndUse; } @@ -1577,6 +1496,9 @@ namespace { TypeLoc::withoutLoc(SwiftType), DC); Result->computeType(); + + if (alternateDecl) + Impl.AlternateDecls[Result] = alternateDecl; return Result; } @@ -1592,30 +1514,29 @@ namespace { auto &context = Impl.SwiftContext; // Create the 'self' declaration. - auto selfType = structDecl->getDeclaredTypeInContext(); - auto selfMetatype = MetatypeType::get(selfType); - auto selfDecl = createSelfDecl(structDecl, false); - Pattern *selfPattern = createTypedNamedPattern(selfDecl); - - // The default initializer takes no arguments. - auto paramPattern = TuplePattern::create(context, SourceLoc(), {}, - SourceLoc()); - auto emptyTy = TupleType::getEmpty(context); + auto selfDecl = ParamDecl::createSelf(SourceLoc(), structDecl, + /*static*/false, /*inout*/true); + + // self & param. + auto emptyPL = ParameterList::createEmpty(context); // Create the constructor. - DeclName name(context, context.Id_init, {}); + DeclName name(context, context.Id_init, emptyPL); auto constructor = new (context) ConstructorDecl(name, structDecl->getLoc(), - OTK_None, SourceLoc(), - selfPattern, paramPattern, + OTK_None, SourceLoc(), selfDecl, emptyPL, nullptr, SourceLoc(), structDecl); // Set the constructor's type. + auto selfType = structDecl->getDeclaredTypeInContext(); + auto selfMetatype = MetatypeType::get(selfType); + auto emptyTy = TupleType::getEmpty(context); auto fnTy = FunctionType::get(emptyTy, selfType); auto allocFnTy = FunctionType::get(selfMetatype, fnTy); auto initFnTy = FunctionType::get(selfType, fnTy); constructor->setType(allocFnTy); constructor->setInitializerType(initFnTy); + constructor->setAccessibility(Accessibility::Public); // Mark the constructor transparent so that we inline it away completely. @@ -1668,18 +1589,11 @@ namespace { auto &context = Impl.SwiftContext; // Create the 'self' declaration. - auto selfType = structDecl->getDeclaredTypeInContext(); - auto selfMetatype = MetatypeType::get(selfType); - auto selfDecl = createSelfDecl(structDecl, false); - - Pattern *selfPattern = createTypedNamedPattern(selfDecl); + auto selfDecl = ParamDecl::createSelf(SourceLoc(), structDecl, + /*static*/false, /*inout*/true); // Construct the set of parameters from the list of members. - SmallVector paramPatterns; - SmallVector patternElts; - SmallVector tupleElts; - SmallVector params; - SmallVector argNames; + SmallVector valueParameters; for (auto var : members) { Identifier argName = wantCtorParamNames ? var->getName() : Identifier(); @@ -1687,34 +1601,33 @@ namespace { SourceLoc(), argName, SourceLoc(), var->getName(), var->getType(), structDecl); - argNames.push_back(argName); - params.push_back(param); - Pattern *pattern = createTypedNamedPattern(param); - paramPatterns.push_back(pattern); - patternElts.push_back(TuplePatternElt(pattern)); - patternElts.back().setLabel(argName, SourceLoc()); - tupleElts.push_back(TupleTypeElt(var->getType(), var->getName())); + valueParameters.push_back(param); } - auto paramPattern = TuplePattern::create(context, SourceLoc(), patternElts, - SourceLoc()); - auto paramTy = TupleType::get(tupleElts, context); - paramPattern->setType(paramTy); - paramTy = paramTy->getRelabeledType(context, argNames); + // self & param. + ParameterList *paramLists[] = { + ParameterList::createWithoutLoc(selfDecl), + ParameterList::create(context, valueParameters) + }; + // Create the constructor - DeclName name(context, context.Id_init, argNames); + DeclName name(context, context.Id_init, paramLists[1]); auto constructor = new (context) ConstructorDecl(name, structDecl->getLoc(), OTK_None, SourceLoc(), - selfPattern, paramPattern, + selfDecl, paramLists[1], nullptr, SourceLoc(), structDecl); // Set the constructor's type. + auto paramTy = paramLists[1]->getType(context); + auto selfType = structDecl->getDeclaredTypeInContext(); + auto selfMetatype = MetatypeType::get(selfType); auto fnTy = FunctionType::get(paramTy, selfType); auto allocFnTy = FunctionType::get(selfMetatype, fnTy); auto initFnTy = FunctionType::get(selfType, fnTy); constructor->setType(allocFnTy); constructor->setInitializerType(initFnTy); + constructor->setAccessibility(Accessibility::Public); // Make the constructor transparent so we inline it away completely. @@ -1739,7 +1652,8 @@ namespace { /*Implicit=*/true); // Construct right-hand side. - auto rhs = new (context) DeclRefExpr(params[i], SourceLoc(), + auto rhs = new (context) DeclRefExpr(valueParameters[i], + SourceLoc(), /*Implicit=*/true); // Add assignment. @@ -1962,7 +1876,7 @@ namespace { // Create the enum declaration and record it. NominalTypeDecl *result; - auto enumKind = Impl.classifyEnum(decl); + auto enumKind = Impl.classifyEnum(Impl.getClangPreprocessor(), decl); switch (enumKind) { case EnumKind::Constants: { // There is no declaration. Rather, the type is mapped to the @@ -2324,7 +2238,7 @@ namespace { std::tie(getter, setter) = makeUnionFieldAccessors(Impl, result, VD); members.push_back(VD); - // Create labeled inititializers for unions that take one of the + // Create labeled initializers for unions that take one of the // fields, which only initializes the data for that field. auto valueCtor = createValueConstructor(result, VD, @@ -2403,7 +2317,7 @@ namespace { if (name.empty()) return nullptr; - switch (Impl.classifyEnum(clangEnum)) { + switch (Impl.classifyEnum(Impl.getClangPreprocessor(), clangEnum)) { case EnumKind::Constants: { // The enumeration was simply mapped to an integral type. Create a // constant with that integral type. @@ -2437,7 +2351,7 @@ namespace { } case EnumKind::Unknown: { - // The enumeration was mapped to a struct containining the integral + // The enumeration was mapped to a struct containing the integral // type. Create a constant with that struct type. auto dc = Impl.importDeclContextOf(clangEnum); @@ -2518,8 +2432,6 @@ namespace { } Decl *VisitFunctionDecl(const clang::FunctionDecl *decl) { - decl = decl->getMostRecentDecl(); - auto dc = Impl.importDeclContextOf(decl); if (!dc) return nullptr; @@ -2534,7 +2446,7 @@ namespace { // Import the function type. If we have parameters, make sure their names // get into the resulting function type. - SmallVector bodyPatterns; + ParameterList *bodyParams = nullptr; Type type = Impl.importFunctionType(decl, decl->getReturnType(), { decl->param_begin(), @@ -2542,9 +2454,7 @@ namespace { decl->isVariadic(), decl->isNoReturn(), isInSystemModule(dc), - hasCustomName, - bodyPatterns, - name); + hasCustomName, bodyParams, name); if (!type) return nullptr; @@ -2553,8 +2463,8 @@ namespace { // If we had no argument labels to start with, add empty labels now. if (name.isSimpleName()) { - llvm::SmallVector - argNames(bodyPatterns[0]->numTopLevelVariables(), Identifier()); + llvm::SmallVector argNames(bodyParams->size(), + Identifier()); name = DeclName(Impl.SwiftContext, name.getBaseName(), argNames); } @@ -2563,7 +2473,7 @@ namespace { auto result = FuncDecl::create( Impl.SwiftContext, SourceLoc(), StaticSpellingKind::None, loc, name, nameLoc, SourceLoc(), SourceLoc(), - /*GenericParams=*/nullptr, type, bodyPatterns, + /*GenericParams=*/nullptr, type, bodyParams, TypeLoc::withoutLoc(resultTy), dc, decl); result->setBodyResultType(resultTy); @@ -2824,8 +2734,6 @@ namespace { importedName, {decl->param_begin(), decl->param_size()}, decl->isVariadic(), redundant); - if (result) - Impl.importAttributes(decl, result); if ((result || redundant) && member) { ++NumFactoryMethodsAsInitializers; @@ -2847,12 +2755,53 @@ namespace { Impl.SwiftContext.AllocateCopy(os.str()))); } + /// Record the initializer as an alternative declaration for the + /// member. + if (result) + Impl.AlternateDecls[member] = result; + return result; } + /// Determine if the given Objective-C instance method should also + /// be imported as a class method. + /// + /// Objective-C root class instance methods are also reflected as + /// class methods. + bool shouldAlsoImportAsClassMethod(FuncDecl *method) { + // Only instance methods. + if (!method->isInstanceMember()) return false; + + // Must be a method within a class or extension thereof. + auto classDecl = + method->getDeclContext()->isClassOrClassExtensionContext(); + if (!classDecl) return false; + + // The class must not have a superclass. + if (classDecl->getSuperclass()) return false; + + // There must not already be a class method with the same + // selector. + auto objcClass = + cast_or_null(classDecl->getClangDecl()); + if (!objcClass) return false; + + auto objcMethod = + cast_or_null(method->getClangDecl()); + if (!objcMethod) return false; + return !objcClass->getClassMethod(objcMethod->getSelector(), + /*AllowHidden=*/true); + } + + Decl *VisitObjCMethodDecl(const clang::ObjCMethodDecl *decl, + DeclContext *dc) { + return VisitObjCMethodDecl(decl, dc, false); + } + + private: Decl *VisitObjCMethodDecl(const clang::ObjCMethodDecl *decl, DeclContext *dc, - bool forceClassMethod = false) { + bool forceClassMethod) { // If we have an init method, import it as an initializer. if (Impl.isInitMethod(decl)) { // Cannot force initializers into class methods. @@ -2897,11 +2846,12 @@ namespace { return nullptr; // Add the implicit 'self' parameter patterns. - SmallVector bodyPatterns; + SmallVector bodyParams; auto selfVar = - createSelfDecl(dc, decl->isClassMethod() || forceClassMethod); - Pattern *selfPat = createTypedNamedPattern(selfVar); - bodyPatterns.push_back(selfPat); + ParamDecl::createSelf(SourceLoc(), dc, + /*isStatic*/ + decl->isClassMethod() || forceClassMethod); + bodyParams.push_back(ParameterList::createWithoutLoc(selfVar)); SpecialMethodKind kind = SpecialMethodKind::Regular; // FIXME: This doesn't handle implicit properties. @@ -2913,6 +2863,7 @@ namespace { // Import the type that this method will have. DeclName name = importedName.Imported; Optional errorConvention; + bodyParams.push_back(nullptr); auto type = Impl.importMethodType(decl, decl->getReturnType(), { decl->param_begin(), @@ -2920,7 +2871,7 @@ namespace { decl->isVariadic(), decl->hasAttr(), isInSystemModule(dc), - bodyPatterns, + &bodyParams.back(), importedName, name, errorConvention, @@ -2941,7 +2892,7 @@ namespace { Impl.SwiftContext, SourceLoc(), StaticSpellingKind::None, SourceLoc(), name, SourceLoc(), SourceLoc(), SourceLoc(), /*GenericParams=*/nullptr, Type(), - bodyPatterns, TypeLoc(), dc, decl); + bodyParams, TypeLoc(), dc, decl); result->setAccessibility(Accessibility::Public); @@ -3030,54 +2981,30 @@ namespace { !Impl.ImportedDecls[decl->getCanonicalDecl()]) Impl.ImportedDecls[decl->getCanonicalDecl()] = result; - importSpecialMethod(result, dc); + if (importedName.IsSubscriptAccessor) { + // If this was a subscript accessor, try to create a + // corresponding subscript declaration. + (void)importSubscript(result, decl); + } else if (shouldAlsoImportAsClassMethod(result)) { + // If we should import this instance method also as a class + // method, do so and mark the result as an alternate + // declaration. + if (auto imported = VisitObjCMethodDecl(decl, dc, + /*forceClassMethod=*/true)) + Impl.AlternateDecls[result] = cast(imported); + } else if (auto factory = importFactoryMethodAsConstructor( + result, decl, selector, dc)) { + // We imported the factory method as an initializer, so + // record it as an alternate declaration. + if (*factory) + Impl.AlternateDecls[result] = *factory; + } + } return result; } public: - /// \brief Given an imported method, try to import it as some kind of - /// special declaration, e.g., a constructor or subscript. - Decl *importSpecialMethod(Decl *decl, DeclContext *dc) { - // Check whether there's a method associated with this declaration. - auto objcMethod - = dyn_cast_or_null(decl->getClangDecl()); - if (!objcMethod) - return nullptr; - - // Only consider Objective-C methods... - switch (objcMethod->getMethodFamily()) { - case clang::OMF_None: - // Check for one of the subscripting selectors. - if (objcMethod->isInstanceMethod() && - (objcMethod->getSelector() == Impl.objectAtIndexedSubscript || - objcMethod->getSelector() == Impl.setObjectAtIndexedSubscript || - objcMethod->getSelector() == Impl.objectForKeyedSubscript || - objcMethod->getSelector() == Impl.setObjectForKeyedSubscript)) - return importSubscript(decl, objcMethod, dc); - - return nullptr; - - case clang::OMF_init: - case clang::OMF_initialize: - case clang::OMF_new: - case clang::OMF_alloc: - case clang::OMF_autorelease: - case clang::OMF_copy: - case clang::OMF_dealloc: - case clang::OMF_finalize: - case clang::OMF_mutableCopy: - case clang::OMF_performSelector: - case clang::OMF_release: - case clang::OMF_retain: - case clang::OMF_retainCount: - case clang::OMF_self: - // None of these methods have special consideration. - return nullptr; - } - } - - private: /// Record the function or initializer overridden by the given Swift method. void recordObjCOverride(AbstractFunctionDecl *decl) { // Figure out the class in which this method occurs. @@ -3103,15 +3030,25 @@ namespace { continue; // Set function override. - // FIXME: Proper type checking here! if (auto func = dyn_cast(decl)) { - func->setOverriddenDecl(cast(member)); + auto foundFunc = cast(member); + + // Require a selector match. + if (func->getObjCSelector() != foundFunc->getObjCSelector()) + continue; + + func->setOverriddenDecl(foundFunc); return; } // Set constructor override. auto ctor = cast(decl); auto memberCtor = cast(member); + + // Require a selector match. + if (ctor->getObjCSelector() != memberCtor->getObjCSelector()) + continue; + ctor->setOverriddenDecl(memberCtor); // Propagate 'required' to subclass initializers. @@ -3122,7 +3059,7 @@ namespace { } } } - + /// \brief Given an imported method, try to import it as a constructor. /// /// Objective-C methods in the 'init' family are imported as @@ -3162,6 +3099,8 @@ namespace { // If we dropped the variadic, handle it now. if (importedName.DroppedVariadic) { + selector = ObjCSelector(Impl.SwiftContext, selector.getNumArgs()-1, + selector.getSelectorPieces().drop_back()); params = params.drop_back(1); variadic = false; } @@ -3310,22 +3249,22 @@ namespace { } // Add the implicit 'self' parameter patterns. - SmallVector bodyPatterns; - auto selfTy = getSelfTypeForContext(dc); - auto selfMetaVar = createSelfDecl(dc, true); - Pattern *selfPat = createTypedNamedPattern(selfMetaVar); - bodyPatterns.push_back(selfPat); + SmallVector bodyParams; + auto selfMetaVar = ParamDecl::createSelf(SourceLoc(), dc, /*static*/true); + auto selfTy = selfMetaVar->getType()->castTo()->getInstanceType(); + bodyParams.push_back(ParameterList::createWithoutLoc(selfMetaVar)); // Import the type that this method will have. Optional errorConvention; DeclName name = importedName.Imported; + bodyParams.push_back(nullptr); auto type = Impl.importMethodType(objcMethod, objcMethod->getReturnType(), args, variadic, objcMethod->hasAttr(), isInSystemModule(dc), - bodyPatterns, + &bodyParams.back(), importedName, name, errorConvention, @@ -3426,13 +3365,12 @@ namespace { if (known != Impl.Constructors.end()) return known->second; - VarDecl *selfVar = createSelfDecl(dc, false); - selfPat = createTypedNamedPattern(selfVar); + auto *selfVar = ParamDecl::createSelf(SourceLoc(), dc); // Create the actual constructor. auto result = Impl.createDeclWithClangNode(objcMethod, - name, SourceLoc(), failability, SourceLoc(), selfPat, - bodyPatterns.back(), /*GenericParams=*/nullptr, + name, SourceLoc(), failability, SourceLoc(), selfVar, + bodyParams.back(), /*GenericParams=*/nullptr, SourceLoc(), dc); // Make the constructor declaration immediately visible in its @@ -3576,33 +3514,18 @@ namespace { /// Build a declaration for an Objective-C subscript getter. FuncDecl *buildSubscriptGetterDecl(const FuncDecl *getter, Type elementTy, - DeclContext *dc, Pattern *indices) { + DeclContext *dc, ParamDecl *index) { auto &context = Impl.SwiftContext; auto loc = getter->getLoc(); - // Form the argument patterns. - SmallVector getterArgs; - - // 'self' - getterArgs.push_back(createTypedNamedPattern(createSelfDecl(dc, false))); - - // index, for subscript operations. - assert(indices); - indices = indices->clone(context); - auto pat = TuplePattern::create(context, loc, TuplePatternElt(indices), - loc); - pat->setType(TupleType::get(TupleTypeElt(indices->getType()), - context)); - getterArgs.push_back(pat); + // self & index. + ParameterList *getterArgs[] = { + ParameterList::createSelf(SourceLoc(), dc), + ParameterList::create(context, index) + }; // Form the type of the getter. - auto getterType = elementTy; - for (auto it = getterArgs.rbegin(), itEnd = getterArgs.rend(); - it != itEnd; ++it) { - getterType = FunctionType::get( - (*it)->getType()->getUnlabeledType(context), - getterType); - } + auto getterType = ParameterList::getFullType(elementTy, getterArgs); // If we're in a protocol, the getter thunk will be polymorphic. Type interfaceType; @@ -3631,10 +3554,9 @@ namespace { /// Build a declaration for an Objective-C subscript setter. FuncDecl *buildSubscriptSetterDecl(const FuncDecl *setter, Type elementTy, - DeclContext *dc, Pattern *indices) { + DeclContext *dc, ParamDecl *index) { auto &context = Impl.SwiftContext; auto loc = setter->getLoc(); - auto tuple = cast(setter->getBodyParamPatterns()[1]); // Objective-C subscript setters are imported with a function type // such as: @@ -3643,43 +3565,31 @@ namespace { // // Build a setter thunk with the latter signature that maps to the // former. - - // Form the argument patterns. - SmallVector setterArgs; + auto valueIndex = setter->getParameterList(1); // 'self' - setterArgs.push_back(createTypedNamedPattern(createSelfDecl(dc, false))); + auto selfDecl = ParamDecl::createSelf(SourceLoc(), dc); + auto paramVarDecl = new (context) ParamDecl(/*isLet=*/false, SourceLoc(), + Identifier(), loc, + valueIndex->get(0)->getName(), + elementTy, dc); - SmallVector ValueElts; - SmallVector ValueEltTys; - - auto paramVarDecl = new (context) ParamDecl( - /*isLet=*/false, SourceLoc(), Identifier(), loc, - tuple->getElement(0).getPattern()->getSingleVar()->getName(), - elementTy, dc); - auto valuePattern = createTypedNamedPattern(paramVarDecl); - ValueElts.push_back(TuplePatternElt(valuePattern)); - ValueEltTys.push_back(TupleTypeElt(valuePattern->getType())); - // Clone the indices for the thunk. - assert(indices); - indices = indices->clone(context); - ValueElts.push_back(TuplePatternElt(indices)); - ValueEltTys.push_back(TupleTypeElt(indices->getType())); - - // value - setterArgs.push_back(TuplePattern::create(context, loc, ValueElts, loc)); - setterArgs.back()->setType(TupleType::get(ValueEltTys, context)); - + auto valueIndicesPL = ParameterList::create(context, { + paramVarDecl, + index + }); + + // Form the argument lists. + ParameterList *setterArgs[] = { + ParameterList::createWithoutLoc(selfDecl), + valueIndicesPL + }; + // Form the type of the setter. - Type setterType = TupleType::getEmpty(context); - for (auto it = setterArgs.rbegin(), itEnd = setterArgs.rend(); - it != itEnd; ++it) { - setterType = FunctionType::get( - (*it)->getType()->getUnlabeledType(context), - setterType); - } + Type setterType = ParameterList::getFullType(TupleType::getEmpty(context), + setterArgs); // If we're in a protocol or extension thereof, the setter thunk // will be polymorphic. @@ -3692,7 +3602,8 @@ namespace { // Create the setter thunk. FuncDecl *thunk = FuncDecl::create( context, SourceLoc(), StaticSpellingKind::None, setter->getLoc(), - Identifier(), SourceLoc(), SourceLoc(), SourceLoc(), nullptr, setterType, + Identifier(), SourceLoc(), SourceLoc(), SourceLoc(), nullptr, + setterType, setterArgs, TypeLoc::withoutLoc(TupleType::getEmpty(context)), dc, setter->getClangNode()); thunk->setBodyResultType(TupleType::getEmpty(context)); @@ -3706,45 +3617,117 @@ namespace { return thunk; } - /// Hack: Handle the case where a subscript is read-only in the - /// main class interface (either explicitly or because of an adopted - /// protocol) and then the setter is added in a category/extension. - /// - /// \see importSubscript - // FIXME: This is basically the same as handlePropertyRedeclaration below. - void handleSubscriptRedeclaration(SubscriptDecl *original, - const SubscriptDecl *redecl) { - // If the subscript isn't from Clang, we can't safely update it. - if (!original->hasClangNode()) - return; + /// Retrieve the element type and of a subscript setter. + std::pair + decomposeSubscriptSetter(FuncDecl *setter) { + auto *PL = setter->getParameterList(1); + if (PL->size() != 2) + return { nullptr, nullptr }; - // If the original declaration was implicit, we may want to change that. - if (original->isImplicit() && !redecl->isImplicit() && - !redecl->getDeclContext()->isProtocolOrProtocolExtensionContext()) - original->setImplicit(false); + return { PL->get(0)->getType(), PL->get(1) }; + } - // The only other transformation we know how to do safely is add a - // setter. If the subscript is already settable, we're done. - if (original->isSettable()) + /// Rectify the (possibly different) types determined by the + /// getter and setter for a subscript. + /// + /// \param canUpdateType whether the type of subscript can be + /// changed from the getter type to something compatible with both + /// the getter and the setter. + /// + /// \returns the type to be used for the subscript, or a null type + /// if the types cannot be rectified. + Type rectifySubscriptTypes(Type getterType, Type setterType, + bool canUpdateType) { + // If the caller couldn't provide a setter type, there is + // nothing to rectify. + if (!setterType) return nullptr; + + // Trivial case: same type in both cases. + if (getterType->isEqual(setterType)) return getterType; + + // The getter/setter types are different. If we cannot update + // the type, we have to fail. + if (!canUpdateType) return nullptr; + + // Unwrap one level of optionality from each. + if (Type getterObjectType = getterType->getAnyOptionalObjectType()) + getterType = getterObjectType; + if (Type setterObjectType = setterType->getAnyOptionalObjectType()) + setterType = setterObjectType; + + // If they are still different, fail. + // FIXME: We could produce the greatest common supertype of the + // two types. + if (!getterType->isEqual(setterType)) return nullptr; + + // Create an implicitly-unwrapped optional of the object type, + // which subsumes both behaviors. + return ImplicitlyUnwrappedOptionalType::get(setterType); + } + + void recordObjCOverride(SubscriptDecl *subscript) { + // Figure out the class in which this subscript occurs. + auto classTy = + subscript->getDeclContext()->isClassOrClassExtensionContext(); + if (!classTy) return; - auto setter = redecl->getSetter(); - if (!setter) + auto superTy = classTy->getSuperclass(); + if (!superTy) return; - original->setComputedSetter(setter); + // Determine whether this subscript operation overrides another subscript + // operation. + SmallVector lookup; + subscript->getModuleContext() + ->lookupQualified(superTy, subscript->getFullName(), + NL_QualifiedDefault | NL_KnownNoDependency, + Impl.getTypeResolver(), lookup); + Type unlabeledIndices; + for (auto result : lookup) { + auto parentSub = dyn_cast(result); + if (!parentSub) + continue; + + // Compute the type of indices for our own subscript operation, lazily. + if (!unlabeledIndices) { + unlabeledIndices = subscript->getIndices()->getType(Impl.SwiftContext) + ->getUnlabeledType(Impl.SwiftContext); + } + + // Compute the type of indices for the subscript we found. + auto parentUnlabeledIndices = + parentSub->getIndices()->getType(Impl.SwiftContext) + ->getUnlabeledType(Impl.SwiftContext); + if (!unlabeledIndices->isEqual(parentUnlabeledIndices)) + continue; + + // The index types match. This is an override, so mark it as such. + subscript->setOverriddenDecl(parentSub); + auto getterThunk = subscript->getGetter(); + getterThunk->setOverriddenDecl(parentSub->getGetter()); + if (auto parentSetter = parentSub->getSetter()) { + if (auto setterThunk = subscript->getSetter()) + setterThunk->setOverriddenDecl(parentSetter); + } + + // FIXME: Eventually, deal with multiple overrides. + break; + } } /// \brief Given either the getter or setter for a subscript operation, /// create the Swift subscript declaration. SubscriptDecl *importSubscript(Decl *decl, - const clang::ObjCMethodDecl *objcMethod, - DeclContext *dc) { + const clang::ObjCMethodDecl *objcMethod) { assert(objcMethod->isInstanceMethod() && "Caller must filter"); + // If the method we're attempting to import has the + // swift_private attribute, don't import as a subscript. if (objcMethod->hasAttr()) return nullptr; + // Figure out where to look for the counterpart. const clang::ObjCInterfaceDecl *interface = nullptr; const clang::ObjCProtocolDecl *protocol = dyn_cast(objcMethod->getDeclContext()); @@ -3754,13 +3737,32 @@ namespace { const clang::ObjCMethodDecl * { if (interface) return interface->lookupInstanceMethod(Sel); - else - return protocol->lookupInstanceMethod(Sel); + + return protocol->lookupInstanceMethod(Sel); }; + auto findCounterpart = [&](clang::Selector sel) -> FuncDecl * { + // If the declaration we're starting from is in a class, first + // look for a class member with the appropriate selector. + if (auto classDecl + = decl->getDeclContext()->isClassOrClassExtensionContext()) { + auto swiftSel = Impl.importSelector(sel); + for (auto found : classDecl->lookupDirect(swiftSel, true)) { + if (auto foundFunc = dyn_cast(found)) + return foundFunc; + } + } + + // Find based on selector within the current type. + auto counterpart = lookupInstanceMethod(sel); + if (!counterpart) return nullptr; + + return cast_or_null(Impl.importDecl(counterpart)); + }; + + // Determine the selector of the counterpart. FuncDecl *getter = nullptr, *setter = nullptr; clang::Selector counterpartSelector; - if (objcMethod->getSelector() == Impl.objectAtIndexedSubscript) { getter = cast(decl); counterpartSelector = Impl.setObjectAtIndexedSubscript; @@ -3777,27 +3779,30 @@ namespace { llvm_unreachable("Unknown getter/setter selector"); } + // Find the counterpart. bool optionalMethods = (objcMethod->getImplementationControl() == clang::ObjCMethodDecl::Optional); - auto *counterpart = lookupInstanceMethod(counterpartSelector); - if (counterpart) { - auto *importedCounterpart = - cast_or_null(Impl.importDecl(counterpart)); + if (auto *counterpart = findCounterpart(counterpartSelector)) { + // If the counterpart to the method we're attempting to import has the + // swift_private attribute, don't import as a subscript. + if (auto importedFrom = counterpart->getClangDecl()) { + if (importedFrom->hasAttr()) + return nullptr; - assert(!importedCounterpart || !importedCounterpart->isStatic()); + auto counterpartMethod + = dyn_cast(importedFrom); + if (optionalMethods) + optionalMethods = (counterpartMethod->getImplementationControl() == + clang::ObjCMethodDecl::Optional); + } + + assert(!counterpart || !counterpart->isStatic()); if (getter) - setter = importedCounterpart; + setter = counterpart; else - getter = importedCounterpart; - - if (optionalMethods) - optionalMethods = (counterpart->getImplementationControl() == - clang::ObjCMethodDecl::Optional); - - if (counterpart->hasAttr()) - return nullptr; + getter = counterpart; } // Swift doesn't have write-only subscripting. @@ -3806,169 +3811,154 @@ namespace { // Check whether we've already created a subscript operation for // this getter/setter pair. - if (auto subscript = Impl.Subscripts[{getter, setter}]) - return subscript->getDeclContext() == dc? subscript : nullptr; - - // Compute the element type, looking through the implicit 'self' - // parameter and the normal function parameters. - auto elementTy - = getter->getType()->castTo()->getResult() - ->castTo()->getResult(); - - // Check the form of the getter. - FuncDecl *getterThunk = nullptr; - Pattern *getterIndices = nullptr; - auto &context = Impl.SwiftContext; + if (auto subscript = Impl.Subscripts[{getter, setter}]) { + return subscript->getDeclContext() == decl->getDeclContext() + ? subscript + : nullptr; + } // Find the getter indices and make sure they match. + ParamDecl *getterIndex; { - auto tuple = dyn_cast(getter->getBodyParamPatterns()[1]); - if (tuple && tuple->getNumElements() != 1) + auto params = getter->getParameterList(1); + if (params->size() != 1) return nullptr; - - getterIndices = tuple->getElement(0).getPattern(); + getterIndex = params->get(0); } - // Check the form of the setter. - FuncDecl *setterThunk = nullptr; - Pattern *setterIndices = nullptr; - if (setter) { - auto tuple = dyn_cast(setter->getBodyParamPatterns()[1]); - if (!tuple) - return nullptr; - - if (tuple->getNumElements() != 2) - return nullptr; + // Compute the element type based on the getter, looking through + // the implicit 'self' parameter and the normal function + // parameters. + auto elementTy + = getter->getType()->castTo()->getResult() + ->castTo()->getResult(); - // The setter must accept elements of the same type as the getter - // returns. - // FIXME: Adjust C++ references? - auto setterElementTy = tuple->getElement(0).getPattern()->getType(); - if (!elementTy->isEqual(setterElementTy)) { - auto nonOptionalElementTy = elementTy->getAnyOptionalObjectType(); - if (nonOptionalElementTy.isNull()) - nonOptionalElementTy = elementTy; - - auto nonOptionalSetterElementTy = - setterElementTy->getAnyOptionalObjectType(); - if (nonOptionalSetterElementTy.isNull()) - nonOptionalSetterElementTy = setterElementTy; - - if (!nonOptionalElementTy->isEqual(nonOptionalSetterElementTy)) - return nullptr; + // Local function to mark the setter unavailable. + auto makeSetterUnavailable = [&] { + if (setter && !setter->getAttrs().isUnavailable(Impl.SwiftContext)) + Impl.markUnavailable(setter, "use subscripting"); + }; - elementTy = - ImplicitlyUnwrappedOptionalType::get(nonOptionalElementTy); + // If we have a setter, rectify it with the getter. + ParamDecl *setterIndex; + bool getterAndSetterInSameType = false; + if (setter) { + // Whether there is an existing read-only subscript for which + // we have now found a setter. + SubscriptDecl *existingSubscript = Impl.Subscripts[{getter, nullptr}]; + + // Are the getter and the setter in the same type. + getterAndSetterInSameType = + (getter->getDeclContext() + ->isNominalTypeOrNominalTypeExtensionContext() + == setter->getDeclContext() + ->isNominalTypeOrNominalTypeExtensionContext()); + + // Whether we can update the types involved in the subscript + // operation. + bool canUpdateSubscriptType + = !existingSubscript && getterAndSetterInSameType; + + // Determine the setter's element type and indices. + Type setterElementTy; + std::tie(setterElementTy, setterIndex) = + decomposeSubscriptSetter(setter); + + // Rectify the setter element type with the getter's element type. + Type newElementTy = rectifySubscriptTypes(elementTy, setterElementTy, + canUpdateSubscriptType); + if (!newElementTy) + return decl == getter ? existingSubscript : nullptr; + + // Update the element type. + elementTy = newElementTy; + + // Make sure that the index types are equivalent. + // FIXME: Rectify these the same way we do for element types. + if (!setterIndex->getType()->isEqual(getterIndex->getType())) { + // If there is an existing subscript operation, we're done. + if (existingSubscript) + return decl == getter ? existingSubscript : nullptr; + + // Otherwise, just forget we had a setter. + // FIXME: This feels very, very wrong. + setter = nullptr; + setterIndex = nullptr; } - setterIndices = tuple->getElement(1).getPattern(); - - // The setter must use the same indices as the getter. - // FIXME: Adjust C++ references? - if (!setterIndices->getType()->isEqual(getterIndices->getType())) { - setter = nullptr; - setterIndices = nullptr; + // If there is an existing subscript within this context, we + // cannot create a new subscript. Update it if possible. + if (setter && existingSubscript && getterAndSetterInSameType) { + // Can we update the subscript by adding the setter? + if (existingSubscript->hasClangNode() && + !existingSubscript->isSettable()) { + // Create the setter thunk. + auto setterThunk = buildSubscriptSetterDecl( + setter, elementTy, setter->getDeclContext(), + setterIndex); + + // Set the computed setter. + existingSubscript->setComputedSetter(setterThunk); + + // Mark the setter as unavailable; one should use + // subscripting when it is present. + makeSetterUnavailable(); + } - // Check whether we've already created a subscript operation for - // this getter. - if (auto subscript = Impl.Subscripts[{getter, nullptr}]) - return subscript->getDeclContext() == dc? subscript : nullptr; + return decl == getter ? existingSubscript : nullptr; } } - getterThunk = buildSubscriptGetterDecl(getter, elementTy, dc, - getterIndices); + // The context into which the subscript should go. + bool associateWithSetter = setter && !getterAndSetterInSameType; + DeclContext *dc = associateWithSetter ? setter->getDeclContext() + : getter->getDeclContext(); + + // Build the thunks. + FuncDecl *getterThunk = buildSubscriptGetterDecl(getter, elementTy, dc, + getterIndex); + + FuncDecl *setterThunk = nullptr; if (setter) setterThunk = buildSubscriptSetterDecl(setter, elementTy, dc, - setterIndices); + setterIndex); // Build the subscript declaration. - auto bodyPatterns = - getterThunk->getBodyParamPatterns()[1]->clone(context); + auto &context = Impl.SwiftContext; + auto bodyParams = getterThunk->getParameterList(1)->clone(context); DeclName name(context, context.Id_subscript, { Identifier() }); auto subscript = Impl.createDeclWithClangNode(getter->getClangNode(), - name, decl->getLoc(), bodyPatterns, + name, decl->getLoc(), bodyParams, decl->getLoc(), TypeLoc::withoutLoc(elementTy), dc); + + /// Record the subscript as an alternative declaration. + Impl.AlternateDecls[associateWithSetter ? setter : getter] = subscript; + subscript->makeComputed(SourceLoc(), getterThunk, setterThunk, nullptr, SourceLoc()); - auto indicesType = bodyPatterns->getType(); - indicesType = indicesType->getRelabeledType(context, - name.getArgumentNames()); - - subscript->setType(FunctionType::get(indicesType, - subscript->getElementType())); + auto indicesType = bodyParams->getType(context); + + subscript->setType(FunctionType::get(indicesType, elementTy)); addObjCAttribute(subscript, None); // Optional subscripts in protocols. if (optionalMethods && isa(dc)) - subscript->getAttrs().add(new (Impl.SwiftContext) - OptionalAttr(true)); + subscript->getAttrs().add(new (Impl.SwiftContext) OptionalAttr(true)); // Note that we've created this subscript. Impl.Subscripts[{getter, setter}] = subscript; - Impl.Subscripts[{getterThunk, nullptr}] = subscript; + if (setter && !Impl.Subscripts[{getter, nullptr}]) + Impl.Subscripts[{getter, nullptr}] = subscript; // Make the getter/setter methods unavailable. if (!getter->getAttrs().isUnavailable(Impl.SwiftContext)) Impl.markUnavailable(getter, "use subscripting"); - if (setter && !setter->getAttrs().isUnavailable(Impl.SwiftContext)) - Impl.markUnavailable(setter, "use subscripting"); - - // Determine whether this subscript operation overrides another subscript - // operation. - // FIXME: This ends up looking in the superclass for entirely bogus - // reasons. Fix it. - auto containerTy = dc->getDeclaredTypeInContext(); - SmallVector lookup; - dc->lookupQualified(containerTy, name, - NL_QualifiedDefault | NL_KnownNoDependency, - Impl.getTypeResolver(), lookup); - Type unlabeledIndices; - for (auto result : lookup) { - auto parentSub = dyn_cast(result); - if (!parentSub) - continue; - - // Compute the type of indices for our own subscript operation, lazily. - if (!unlabeledIndices) { - unlabeledIndices = subscript->getIndices()->getType() - ->getUnlabeledType(Impl.SwiftContext); - } - - // Compute the type of indices for the subscript we found. - auto parentUnlabeledIndices = parentSub->getIndices()->getType() - ->getUnlabeledType(Impl.SwiftContext); - if (!unlabeledIndices->isEqual(parentUnlabeledIndices)) - continue; - - if (parentSub == subscript) - continue; - - const DeclContext *overrideContext = parentSub->getDeclContext(); - assert(dc != overrideContext && "subscript already exists"); - - if (overrideContext->getDeclaredTypeInContext()->isEqual(containerTy)) { - // We've encountered a redeclaration of the subscript. - // HACK: Just update the original declaration instead of importing a - // second subscript. - handleSubscriptRedeclaration(parentSub, subscript); - Impl.Subscripts[{getter, setter}] = parentSub; - return nullptr; - } + makeSetterUnavailable(); - // The index types match. This is an override, so mark it as such. - subscript->setOverriddenDecl(parentSub); - getterThunk->setOverriddenDecl(parentSub->getGetter()); - if (auto parentSetter = parentSub->getSetter()) { - if (setterThunk) - setterThunk->setOverriddenDecl(parentSetter); - } - - // FIXME: Eventually, deal with multiple overrides. - break; - } + // Wire up overrides. + recordObjCOverride(subscript); return subscript; } @@ -4072,157 +4062,11 @@ namespace { } } - /// Finds the counterpart accessor method for \p MD, if one exists, in the - /// same lexical context. - const clang::ObjCMethodDecl * - findImplicitPropertyAccessor(const clang::ObjCMethodDecl *MD) { - // FIXME: Do we want to infer class properties? - if (!MD->isInstanceMethod()) - return nullptr; - - // First, collect information about the method we have. - clang::Selector sel = MD->getSelector(); - llvm::SmallString<64> counterpartName; - auto numArgs = sel.getNumArgs(); - clang::QualType propTy; - - if (numArgs > 1) - return nullptr; - - if (numArgs == 0) { - clang::IdentifierInfo *getterID = sel.getIdentifierInfoForSlot(0); - if (!getterID) - return nullptr; - counterpartName = - clang::SelectorTable::constructSetterName(getterID->getName()); - propTy = MD->getReturnType(); - - } else { - if (!MD->getReturnType()->isVoidType()) - return nullptr; - - clang::IdentifierInfo *setterID = sel.getIdentifierInfoForSlot(0); - if (!setterID || !setterID->getName().startswith("set")) - return nullptr; - counterpartName = setterID->getName().substr(3); - counterpartName[0] = tolower(counterpartName[0]); - propTy = MD->parameters().front()->getType(); - } - - // Next, look for its counterpart. - const clang::ASTContext &clangCtx = Impl.getClangASTContext(); - auto container = cast(MD->getDeclContext()); - for (auto method : make_range(container->instmeth_begin(), - container->instmeth_end())) { - // Condition 1: it must be a getter if we have a setter, and vice versa. - clang::Selector nextSel = method->getSelector(); - if (nextSel.getNumArgs() != (1 - numArgs)) - continue; - - // Condition 2: it must have the name we expect. - clang::IdentifierInfo *nextID = nextSel.getIdentifierInfoForSlot(0); - if (!nextID) - continue; - if (nextID->getName() != counterpartName) - continue; - - // Condition 3: it must have the right type signature. - if (numArgs == 0) { - if (!method->getReturnType()->isVoidType()) - continue; - clang::QualType paramTy = method->parameters().front()->getType(); - if (!clangCtx.hasSameUnqualifiedType(propTy, paramTy)) - continue; - } else { - clang::QualType returnTy = method->getReturnType(); - if (!clangCtx.hasSameUnqualifiedType(propTy, returnTy)) - continue; - } - - return method; - } - - return nullptr; - } - - /// Creates a computed property VarDecl from the given getter and - /// optional setter. - Decl *makeImplicitPropertyDecl(Decl *opaqueGetter, - Decl *opaqueSetter, - DeclContext *dc) { - auto getter = cast(opaqueGetter); - auto setter = cast_or_null(opaqueSetter); - assert(!setter || setter->getResultType()->isVoid()); - - auto name = getter->getName(); - - // Check whether there is a function with the same name as this - // property. If so, suppress the property; the user will have to use - // the methods directly, to avoid ambiguities. - auto containerTy = dc->getDeclaredTypeInContext(); - VarDecl *overridden = nullptr; - SmallVector lookup; - dc->lookupQualified(containerTy, name, - NL_QualifiedDefault | NL_KnownNoDependency, - nullptr, lookup); - for (auto result : lookup) { - if (isa(result)) - return nullptr; - - if (auto var = dyn_cast(result)) - overridden = var; - } - - // Re-import the type as a property type. - auto clangGetter = cast(getter->getClangDecl()); - auto type = Impl.importType(clangGetter->getReturnType(), - ImportTypeKind::Property, - isInSystemModule(dc), - /*isFullyBridgeable*/true); - if (!type) - return nullptr; - - auto result = Impl.createDeclWithClangNode(clangGetter, - /*static*/ false, /*IsLet*/ false, - Impl.importSourceLoc(clangGetter->getLocation()), - name, type, dc); - - // Turn this into a computed property. - // FIXME: Fake locations for '{' and '}'? - result->makeComputed(SourceLoc(), getter, setter, nullptr, SourceLoc()); - addObjCAttribute(result, None); - - if (overridden) - result->setOverriddenDecl(overridden); - - return result; - } - - static bool - isPotentiallyConflictingSetter(const clang::ObjCProtocolDecl *proto, - const clang::ObjCMethodDecl *method) { - auto sel = method->getSelector(); - if (sel.getNumArgs() != 1) - return false; - - clang::IdentifierInfo *setterID = sel.getIdentifierInfoForSlot(0); - if (!setterID || !setterID->getName().startswith("set")) - return false; - - for (auto *prop : proto->properties()) { - if (prop->getSetterName() == sel) - return true; - } - - return false; - } - /// Import members of the given Objective-C container and add them to the /// list of corresponding Swift members. void importObjCMembers(const clang::ObjCContainerDecl *decl, DeclContext *swiftContext, - SmallVectorImpl &members, - bool &hasMissingRequiredMember) { + SmallVectorImpl &members) { llvm::SmallPtrSet knownMembers; for (auto m = decl->decls_begin(), mEnd = decl->decls_end(); m != mEnd; ++m) { @@ -4231,114 +4075,23 @@ namespace { continue; auto member = Impl.importDecl(nd); - if (!member) { - if (auto method = dyn_cast(nd)) { - if (method->getImplementationControl() == - clang::ObjCMethodDecl::Required) - hasMissingRequiredMember = true; - } else if (auto prop = dyn_cast(nd)) { - if (prop->getPropertyImplementation() == - clang::ObjCPropertyDecl::Required) - hasMissingRequiredMember = true; - } - continue; - } + if (!member) continue; if (auto objcMethod = dyn_cast(nd)) { - // If there is a special declaration associated with this member, - // add it now. - if (auto special = importSpecialMethod(member, swiftContext)) { - if (knownMembers.insert(special).second) - members.push_back(special); + // If there is an alternate declaration for this member, add it. + if (auto alternate = Impl.getAlternateDecl(member)) { + if (alternate->getDeclContext() == member->getDeclContext() && + knownMembers.insert(alternate).second) + members.push_back(alternate); } - // If this is a factory method, try to import it as a constructor. - if (auto factory = importFactoryMethodAsConstructor( - member, - objcMethod, - Impl.importSelector(objcMethod->getSelector()), - swiftContext)) { - if (*factory) - members.push_back(*factory); - } - - // Objective-C root class instance methods are reflected on the - // metatype as well. - if (objcMethod->isInstanceMethod()) { - Type swiftTy = swiftContext->getDeclaredTypeInContext(); - auto swiftClass = swiftTy->getClassOrBoundGenericClass(); - if (swiftClass && !swiftClass->getSuperclass() && - !decl->getClassMethod(objcMethod->getSelector(), - /*AllowHidden=*/true)) { - auto classMember = VisitObjCMethodDecl(objcMethod, swiftContext, - true); - if (classMember) - members.push_back(classMember); - } - } - - // Import explicit properties as instance properties, not as separate - // getter and setter methods. - if (!Impl.isAccessibilityDecl(objcMethod)) { - // If this member is a method that is a getter or setter for a - // propertythat was imported, don't add it to the list of members - // so it won't be found by name lookup. This eliminates the - // ambiguity between property names and getter names (by choosing - // to only have a variable). - if (objcMethod->isPropertyAccessor()) { - auto prop = objcMethod->findPropertyDecl(/*checkOverrides=*/false); - assert(prop); - (void)Impl.importDecl(const_cast(prop)); - // We may have attached this member to an existing property even - // if we've failed to import a new property. - if (cast(member)->isAccessor()) - continue; - } else if (Impl.InferImplicitProperties) { - // Try to infer properties for matched getter/setter pairs. - // Be careful to only do this once per matched pair. - if (auto counterpart = findImplicitPropertyAccessor(objcMethod)) { - if (auto counterpartImported = Impl.importDecl(counterpart)) { - if (objcMethod->getReturnType()->isVoidType()) { - if (auto prop = makeImplicitPropertyDecl(counterpartImported, - member, - swiftContext)) { - members.push_back(prop); - } else { - // If we fail to import the implicit property, fall back to - // adding the accessors as members. We have to add BOTH - // accessors here because we already skipped over the other - // one. - members.push_back(member); - members.push_back(counterpartImported); - } - } - continue; - } - } - } else if (auto *proto = dyn_cast(decl)) { - if (isPotentiallyConflictingSetter(proto, objcMethod)) - continue; - } - } + // If this declaration shouldn't be visible, don't add it to + // the list. + if (Impl.shouldSuppressDeclImport(objcMethod)) continue; } members.push_back(member); } - - // Hack to deal with unannotated Objective-C protocols. If the protocol - // comes from clang and is not annotated and the protocol requirement - // itself is not annotated, then infer availability of the requirement - // based on its types. This makes it possible for a type to conform to an - // Objective-C protocol that is missing annotations but whose requirements - // use types that are less available than the conforming type. - auto *proto = dyn_cast(swiftContext); - if (!proto || proto->getAttrs().hasAttribute()) - return; - - for (Decl *member : members) { - inferProtocolMemberAvailability(Impl, swiftContext, member); - } - } static bool @@ -4366,10 +4119,7 @@ namespace { ArrayRef protocols, SmallVectorImpl &members, ASTContext &Ctx) { - Type swiftTy = dc->getDeclaredTypeInContext(); - auto swiftClass = swiftTy->getClassOrBoundGenericClass(); - bool isRoot = swiftClass && !swiftClass->getSuperclass(); - + assert(dc); const clang::ObjCInterfaceDecl *interfaceDecl = nullptr; const ClangModuleUnit *declModule; const ClangModuleUnit *interfaceModule; @@ -4470,13 +4220,10 @@ namespace { // Import the method. if (auto imported = Impl.importMirroredDecl(objcMethod, dc, proto)) { members.push_back(imported); - } - // Import instance methods of a root class also as class methods. - if (isRoot && objcMethod->isInstanceMethod()) { - if (auto classImport = Impl.importMirroredDecl(objcMethod, - dc, proto, true)) - members.push_back(classImport); + if (auto alternate = Impl.getAlternateDecl(imported)) + if (imported->getDeclContext() == alternate->getDeclContext()) + members.push_back(alternate); } } } @@ -4578,7 +4325,7 @@ namespace { auto superclass = cast(classDecl->getSuperclass()->getAnyNominal()); - // If we we have a superclass, import from it. + // If we have a superclass, import from it. if (auto superclassClangDecl = superclass->getClangDecl()) { if (isa(superclassClangDecl)) { inheritConstructors(superclass->getMembers(), kind); @@ -5026,6 +4773,8 @@ namespace { Decl *VisitObjCPropertyDecl(const clang::ObjCPropertyDecl *decl, DeclContext *dc) { + assert(dc); + auto name = Impl.importFullName(decl).Imported.getBaseName(); if (name.empty()) return nullptr; @@ -5047,8 +4796,13 @@ namespace { result->getFullName().getArgumentNames().empty()) return nullptr; - if (auto var = dyn_cast(result)) - overridden = var; + if (auto var = dyn_cast(result)) { + // If the selectors of the getter match in Objective-C, we have an + // override. + if (var->getObjCGetterSelector() == + Impl.importSelector(decl->getGetterName())) + overridden = var; + } } if (overridden) { @@ -5182,7 +4936,7 @@ namespace { /// \brief Classify the given Clang enumeration to describe how to import it. EnumKind ClangImporter::Implementation:: -classifyEnum(const clang::EnumDecl *decl) { +classifyEnum(clang::Preprocessor &pp, const clang::EnumDecl *decl) { // Anonymous enumerations simply get mapped to constants of the // underlying type of the enum, because there is no way to conjure up a // name for the Swift type. @@ -5193,9 +4947,10 @@ classifyEnum(const clang::EnumDecl *decl) { // FIXME: Use Clang attributes instead of grovelling the macro expansion loc. auto loc = decl->getLocStart(); if (loc.isMacroID()) { - StringRef MacroName = getClangPreprocessor().getImmediateMacroName(loc); - if (MacroName == "CF_ENUM" || MacroName == "OBJC_ENUM" || - MacroName == "SWIFT_ENUM" || MacroName == "__CF_NAMED_ENUM") + StringRef MacroName = pp.getImmediateMacroName(loc); + if (MacroName == "CF_ENUM" || MacroName == "__CF_NAMED_ENUM" || + MacroName == "OBJC_ENUM" || + MacroName == "SWIFT_ENUM" || MacroName == "SWIFT_ENUM_NAMED") return EnumKind::Enum; if (MacroName == "CF_OPTIONS" || MacroName == "OBJC_OPTIONS" || MacroName == "SWIFT_OPTIONS") @@ -5478,8 +5233,8 @@ void ClangImporter::Implementation::importAttributes( if (auto MD = dyn_cast(MappedDecl)) { if (MD->getName().str() == "print" && MD->getDeclContext()->isTypeContext()) { - auto *formalParams = MD->getBodyParamPatterns()[1]; - if (formalParams->numTopLevelVariables() <= 1) { + auto *formalParams = MD->getParameterList(1); + if (formalParams->size() <= 1) { // Use a non-implicit attribute so it shows up in the generated // interface. MD->getAttrs().add( @@ -5523,11 +5278,57 @@ ClangImporter::Implementation::importDeclImpl(const clang::NamedDecl *ClangDecl, Result = converter.Visit(ClangDecl); HadForwardDeclaration = converter.hadForwardDeclaration(); } - if (!Result) + if (!Result) { + // If we couldn't import this Objective-C entity, determine + // whether it was a required member of a protocol. + bool hasMissingRequiredMember = false; + if (auto clangProto + = dyn_cast(ClangDecl->getDeclContext())) { + if (auto method = dyn_cast(ClangDecl)) { + if (method->getImplementationControl() + == clang::ObjCMethodDecl::Required) + hasMissingRequiredMember = true; + } else if (auto prop = dyn_cast(ClangDecl)) { + if (prop->getPropertyImplementation() + == clang::ObjCPropertyDecl::Required) + hasMissingRequiredMember = true; + } + + if (hasMissingRequiredMember) { + // Mark the protocol as having missing requirements. + if (auto proto = cast_or_null(importDecl(clangProto))) { + proto->setHasMissingRequirements(true); + } + } + } + return nullptr; + } - if (Result) - importAttributes(ClangDecl, Result); + // Finalize the imported declaration. + auto finalizeDecl = [&](Decl *result) { + importAttributes(ClangDecl, result); + + // Hack to deal with unannotated Objective-C protocols. If the protocol + // comes from clang and is not annotated and the protocol requirement + // itself is not annotated, then infer availability of the requirement + // based on its types. This makes it possible for a type to conform to an + // Objective-C protocol that is missing annotations but whose requirements + // use types that are less available than the conforming type. + auto dc = result->getDeclContext(); + auto *proto = dyn_cast(dc); + if (!proto || proto->getAttrs().hasAttribute()) + return; + + inferProtocolMemberAvailability(*this, dc, result); + }; + + if (Result) { + finalizeDecl(Result); + + if (auto alternate = getAlternateDecl(Result)) + finalizeDecl(alternate); + } #ifndef NDEBUG auto Canon = cast(ClangDecl->getCanonicalDecl()); @@ -5693,8 +5494,8 @@ Decl *ClangImporter::Implementation::importDeclAndCacheImpl( Decl * ClangImporter::Implementation::importMirroredDecl(const clang::NamedDecl *decl, DeclContext *dc, - ProtocolDecl *proto, - bool forceClassMethod) { + ProtocolDecl *proto) { + assert(dc); if (!decl) return nullptr; @@ -5703,47 +5504,50 @@ ClangImporter::Implementation::importMirroredDecl(const clang::NamedDecl *decl, "importing (mirrored)"); auto canon = decl->getCanonicalDecl(); - auto known = ImportedProtocolDecls.find({{canon, forceClassMethod}, dc }); + auto known = ImportedProtocolDecls.find({canon, dc }); if (known != ImportedProtocolDecls.end()) return known->second; SwiftDeclConverter converter(*this); Decl *result; if (auto method = dyn_cast(decl)) { - result = converter.VisitObjCMethodDecl(method, dc, forceClassMethod); + result = converter.VisitObjCMethodDecl(method, dc); } else if (auto prop = dyn_cast(decl)) { - assert(!forceClassMethod && "can't mirror properties yet"); result = converter.VisitObjCPropertyDecl(prop, dc); } else { llvm_unreachable("unexpected mirrored decl"); } if (result) { - if (!forceClassMethod) { - if (auto special = converter.importSpecialMethod(result, dc)) - result = special; - } - assert(result->getClangDecl() && result->getClangDecl() == canon); - result->setImplicit(); - // Map the Clang attributes onto Swift attributes. - importAttributes(decl, result); + auto updateMirroredDecl = [&](Decl *result) { + result->setImplicit(); + + // Map the Clang attributes onto Swift attributes. + importAttributes(decl, result); - if (proto->getAttrs().hasAttribute()) { - if (!result->getAttrs().hasAttribute()) { - VersionRange protoRange = + if (proto->getAttrs().hasAttribute()) { + if (!result->getAttrs().hasAttribute()) { + VersionRange protoRange = AvailabilityInference::availableRange(proto, SwiftContext); - applyAvailableAttribute(result, protoRange, SwiftContext); + applyAvailableAttribute(result, protoRange, SwiftContext); + } + } else { + // Infer the same availability for the mirrored declaration as + // we would for the protocol member it is mirroring. + inferProtocolMemberAvailability(*this, dc, result); } - } else { - // Infer the same availability for the mirrored declaration as we would for - // the protocol member it is mirroring. - inferProtocolMemberAvailability(*this, dc, result); - } + }; + + updateMirroredDecl(result); + + // Update the alternate declaration as well. + if (auto alternate = getAlternateDecl(result)) + updateMirroredDecl(alternate); } if (result || !converter.hadForwardDeclaration()) - ImportedProtocolDecls[{{canon, forceClassMethod}, dc}] = result; + ImportedProtocolDecls[{canon, dc}] = result; return result; } @@ -5873,32 +5677,19 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc, SourceLoc(), name, type, dc); // Form the argument patterns. - SmallVector getterArgs; - + SmallVector getterArgs; + // 'self' if (dc->isTypeContext()) { - auto selfTy = dc->getDeclaredTypeInContext(); - if (isStatic) - selfTy = MetatypeType::get(selfTy); - - getterArgs.push_back( - Pattern::buildImplicitSelfParameter(SourceLoc(), - TypeLoc::withoutLoc(selfTy), - dc)); + auto *selfDecl = ParamDecl::createSelf(SourceLoc(), dc, isStatic); + getterArgs.push_back(ParameterList::createWithoutLoc(selfDecl)); } // empty tuple - getterArgs.push_back(TuplePattern::create(context, SourceLoc(), { }, - SourceLoc())); - getterArgs.back()->setType(TupleType::getEmpty(context)); + getterArgs.push_back(ParameterList::createEmpty(context)); // Form the type of the getter. - auto getterType = type; - for (auto it = getterArgs.rbegin(), itEnd = getterArgs.rend(); - it != itEnd; ++it) { - getterType = FunctionType::get((*it)->getType()->getUnlabeledType(context), - getterType); - } + auto getterType = ParameterList::getFullType(type, getterArgs); // Create the getter function declaration. auto func = FuncDecl::create(context, SourceLoc(), StaticSpellingKind::None, @@ -5995,8 +5786,8 @@ createUnavailableDecl(Identifier name, DeclContext *dc, Type type, void -ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t unused, - bool *hasMissingRequiredMembers) { +ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t unused) { + assert(D); assert(D->hasClangNode()); auto clangDecl = cast(D->getClangDecl()); @@ -6023,12 +5814,7 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t unused, ImportingEntityRAII Importing(*this); SmallVector members; - bool scratch; - if (!hasMissingRequiredMembers) - hasMissingRequiredMembers = &scratch; - *hasMissingRequiredMembers = false; - converter.importObjCMembers(clangDecl, DC, - members, *hasMissingRequiredMembers); + converter.importObjCMembers(clangDecl, DC, members); protos = takeImportedProtocols(D); if (auto clangClass = dyn_cast(clangDecl)) { diff --git a/lib/ClangImporter/ImportMacro.cpp b/lib/ClangImporter/ImportMacro.cpp index 0bb1555c9f559..6367eb695b857 100644 --- a/lib/ClangImporter/ImportMacro.cpp +++ b/lib/ClangImporter/ImportMacro.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -393,10 +393,25 @@ ValueDecl *ClangImporter::Implementation::importMacro(Identifier name, if (!macro) return nullptr; - // Look for the value for an already-imported macro. - auto known = ImportedMacros.find(macro); + // Look for macros imported with the same name. + auto known = ImportedMacros.find(name); if (known != ImportedMacros.end()) { - return known->second; + // Check whether this macro has already been imported. + for (const auto &entry : known->second) { + if (entry.first == macro) return entry.second; + } + + // Otherwise, check whether this macro is identical to a macro that has + // already been imported. + auto &clangPP = getClangPreprocessor(); + for (const auto &entry : known->second) { + // If the macro is equal to an existing macro, map down to the same + // declaration. + if (macro->isIdenticalTo(*entry.first, clangPP, true)) { + known->second.push_back({macro, entry.second}); + return entry.second; + } + } } ImportingEntityRAII ImportingEntity(*this); @@ -408,6 +423,6 @@ ValueDecl *ClangImporter::Implementation::importMacro(Identifier name, return nullptr; auto valueDecl = ::importMacro(*this, DC, name, macro, macro); - ImportedMacros[macro] = valueDecl; + ImportedMacros[name].push_back({macro, valueDecl}); return valueDecl; } diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 57e44703c7ccb..c53af25853dee 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,13 +23,14 @@ #include "swift/AST/DiagnosticsClangImporter.h" #include "swift/AST/Module.h" #include "swift/AST/NameLookup.h" -#include "swift/AST/Pattern.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/Types.h" #include "swift/ClangImporter/ClangModule.h" #include "swift/Parse/Token.h" #include "swift/Basic/Fallthrough.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" +#include "clang/Lex/Preprocessor.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" @@ -653,7 +654,7 @@ namespace { ImportResult VisitEnumType(const clang::EnumType *type) { auto clangDecl = type->getDecl(); - switch (Impl.classifyEnum(clangDecl)) { + switch (Impl.classifyEnum(Impl.getClangPreprocessor(), clangDecl)) { case ClangImporter::Implementation::EnumKind::Constants: { auto clangDef = clangDecl->getDefinition(); // Map anonymous enums with no fixed underlying type to Int /if/ @@ -1326,15 +1327,13 @@ static OptionalTypeKind getParamOptionality( return OTK_ImplicitlyUnwrappedOptional; } -Type ClangImporter::Implementation::importFunctionType( - const clang::FunctionDecl *clangDecl, - clang::QualType resultType, - ArrayRef params, - bool isVariadic, bool isNoReturn, - bool isFromSystemModule, - bool hasCustomName, - SmallVectorImpl &bodyPatterns, - DeclName &name) { +Type ClangImporter::Implementation:: +importFunctionType(const clang::FunctionDecl *clangDecl, + clang::QualType resultType, + ArrayRef params, + bool isVariadic, bool isNoReturn, + bool isFromSystemModule, bool hasCustomName, + ParameterList *¶meterList, DeclName &name) { bool allowNSUIntegerAsInt = isFromSystemModule; if (allowNSUIntegerAsInt) { @@ -1378,10 +1377,7 @@ Type ClangImporter::Implementation::importFunctionType( return Type(); // Import the parameters. - SmallVector swiftArgParams; - SmallVector swiftBodyParams; - SmallVector argPatternElts; - SmallVector bodyPatternElts; + SmallVector parameters; unsigned index = 0; llvm::SmallBitVector nonNullArgs = getNonNullArgs(clangDecl, params); ArrayRef argNames = name.getArgumentNames(); @@ -1432,8 +1428,6 @@ Type ClangImporter::Implementation::importFunctionType( if (index < argNames.size()) name = argNames[index]; - // Compute the pattern to put into the body. - Pattern *bodyPattern; // It doesn't actually matter which DeclContext we use, so just use the // imported header unit. auto bodyVar @@ -1444,60 +1438,36 @@ Type ClangImporter::Implementation::importFunctionType( bodyName, swiftParamTy, ImportedHeaderUnit); - if (addNoEscapeAttr) { + if (addNoEscapeAttr) bodyVar->getAttrs().add( new (SwiftContext) NoEscapeAttr(/*IsImplicit=*/false)); - } - bodyPattern = new (SwiftContext) NamedPattern(bodyVar); - bodyPattern->setType(swiftParamTy); - bodyPattern - = new (SwiftContext) TypedPattern(bodyPattern, - TypeLoc::withoutLoc(swiftParamTy)); - bodyPattern->setType(swiftParamTy); - bodyPatternElts.push_back(TuplePatternElt(bodyPattern)); - bodyPatternElts.back().setLabel(name, SourceLoc()); - - // Add the tuple elements for the function types. - swiftArgParams.push_back(TupleTypeElt(swiftParamTy, name)); - swiftBodyParams.push_back(TupleTypeElt(swiftParamTy, bodyName)); + parameters.push_back(bodyVar); ++index; } // Append an additional argument to represent varargs. if (isVariadic) { - auto paramTy = BoundGenericType::get(SwiftContext.getArrayDecl(), Type(), - {SwiftContext.getAnyDecl()->getDeclaredType()}); - auto name = SwiftContext.getIdentifier("varargs"); - auto bodyVar = new (SwiftContext) ParamDecl(true, SourceLoc(), Identifier(), - SourceLoc(), name, paramTy, - ImportedHeaderUnit); - Pattern *bodyPattern = new (SwiftContext) NamedPattern(bodyVar); - bodyPattern->setType(paramTy); - bodyPattern = new (SwiftContext) TypedPattern(bodyPattern, - TypeLoc::withoutLoc(paramTy)); - bodyPattern->setType(paramTy); - bodyPatternElts.push_back(TuplePatternElt(Identifier(), SourceLoc(), - bodyPattern, true)); - swiftArgParams.push_back(TupleTypeElt(paramTy, Identifier(), - DefaultArgumentKind::None, true)); - swiftBodyParams.push_back(TupleTypeElt(paramTy, name, - DefaultArgumentKind::None, true)); + auto paramTy = BoundGenericType::get(SwiftContext.getArrayDecl(), Type(), + {SwiftContext.getAnyDecl()->getDeclaredType()}); + auto name = SwiftContext.getIdentifier("varargs"); + auto param = new (SwiftContext) ParamDecl(true, SourceLoc(), + Identifier(), + SourceLoc(), name, paramTy, + ImportedHeaderUnit); + + param->setVariadic(); + parameters.push_back(param); } - // Form the parameter tuples. - auto bodyParamsTy = TupleType::get(swiftBodyParams, SwiftContext); - - // Form the body patterns. - bodyPatterns.push_back(TuplePattern::create(SwiftContext, SourceLoc(), - bodyPatternElts, SourceLoc())); - bodyPatterns.back()->setType(bodyParamsTy); + // Form the parameter list. + parameterList = ParameterList::create(SwiftContext, parameters); FunctionType::ExtInfo extInfo; extInfo = extInfo.withIsNoReturn(isNoReturn); // Form the function type. - auto argTy = TupleType::get(swiftArgParams, SwiftContext); + auto argTy = parameterList->getType(SwiftContext); return FunctionType::get(argTy, swiftResultTy, extInfo); } @@ -1553,12 +1523,10 @@ static bool isObjCCollectionName(StringRef typeName) { /// Retrieve the name of the given Clang type for use when omitting /// needless words. OmissionTypeName ClangImporter::Implementation::getClangTypeNameForOmission( - clang::QualType type) { + clang::ASTContext &ctx, clang::QualType type) { if (type.isNull()) return OmissionTypeName(); - auto &ctx = getClangASTContext(); - // Dig through the type, looking for a typedef-name and stripping // references along the way. StringRef lastTypedefName; @@ -1653,7 +1621,8 @@ OmissionTypeName ClangImporter::Implementation::getClangTypeNameForOmission( return OmissionTypeName(className, None, "Object"); return OmissionTypeName(className, None, - getClangTypeNameForOmission(typeArgs[0]).Name); + getClangTypeNameForOmission(ctx, + typeArgs[0]).Name); } // Objective-C "id" type. @@ -1669,18 +1638,113 @@ OmissionTypeName ClangImporter::Implementation::getClangTypeNameForOmission( // Handle builtin types by importing them and getting the Swift name. if (auto builtinTy = type->getAs()) { - if (Type type = importType(clang::QualType(builtinTy, 0), - ImportTypeKind::Abstract, - /*allowNSUIntegerAsInt=*/true, - /*canFullyBridgeTypes=*/true, - OTK_None)) { - if (auto nominal = type->getAnyNominal()) { - OmissionTypeOptions options; - if (nominal->getName().str() == "Bool") - options |= OmissionTypeFlags::Boolean; - - return OmissionTypeName(nominal->getName().str(), options); + // Names of integer types. + static const char *intTypeNames[] = { + "UInt8", + "UInt16", + "UInt32", + "UInt64", + "UInt128" + }; + + /// Retrieve the name for an integer type based on its size. + auto getIntTypeName = [&](bool isSigned) -> StringRef { + switch (ctx.getTypeSize(builtinTy)) { + case 8: return StringRef(intTypeNames[0]).substr(isSigned ? 1 : 0); + case 16: return StringRef(intTypeNames[1]).substr(isSigned ? 1 : 0); + case 32: return StringRef(intTypeNames[2]).substr(isSigned ? 1 : 0); + case 64: return StringRef(intTypeNames[3]).substr(isSigned ? 1 : 0); + case 128: return StringRef(intTypeNames[4]).substr(isSigned ? 1 : 0); + default: llvm_unreachable("bad integer type size"); } + }; + + switch (builtinTy->getKind()) { + case clang::BuiltinType::Void: + return "Void"; + + case clang::BuiltinType::Bool: + return OmissionTypeName("Bool", OmissionTypeFlags::Boolean); + + case clang::BuiltinType::Float: + return "Float"; + + case clang::BuiltinType::Double: + return "Double"; + + case clang::BuiltinType::Char16: + return "UInt16"; + + case clang::BuiltinType::Char32: + return "UnicodeScalar"; + + case clang::BuiltinType::Char_U: + case clang::BuiltinType::UChar: + case clang::BuiltinType::UShort: + case clang::BuiltinType::UInt: + case clang::BuiltinType::ULong: + case clang::BuiltinType::ULongLong: + case clang::BuiltinType::UInt128: + case clang::BuiltinType::WChar_U: + return getIntTypeName(false); + + case clang::BuiltinType::Char_S: + case clang::BuiltinType::SChar: + case clang::BuiltinType::Short: + case clang::BuiltinType::Int: + case clang::BuiltinType::Long: + case clang::BuiltinType::LongLong: + case clang::BuiltinType::Int128: + case clang::BuiltinType::WChar_S: + return getIntTypeName(true); + + // Types that cannot be mapped into Swift, and probably won't ever be. + case clang::BuiltinType::Dependent: + case clang::BuiltinType::ARCUnbridgedCast: + case clang::BuiltinType::BoundMember: + case clang::BuiltinType::BuiltinFn: + case clang::BuiltinType::Overload: + case clang::BuiltinType::PseudoObject: + case clang::BuiltinType::UnknownAny: + return OmissionTypeName(); + + // FIXME: Types that can be mapped, but aren't yet. + case clang::BuiltinType::Half: + case clang::BuiltinType::LongDouble: + case clang::BuiltinType::NullPtr: + return OmissionTypeName(); + + // Objective-C types that aren't mapped directly; rather, pointers to + // these types will be mapped. + case clang::BuiltinType::ObjCClass: + case clang::BuiltinType::ObjCId: + case clang::BuiltinType::ObjCSel: + return OmissionTypeName(); + + // OpenCL types that don't have Swift equivalents. + case clang::BuiltinType::OCLImage1d: + case clang::BuiltinType::OCLImage1dArray: + case clang::BuiltinType::OCLImage1dBuffer: + case clang::BuiltinType::OCLImage2d: + case clang::BuiltinType::OCLImage2dArray: + case clang::BuiltinType::OCLImage2dDepth: + case clang::BuiltinType::OCLImage2dArrayDepth: + case clang::BuiltinType::OCLImage2dMSAA: + case clang::BuiltinType::OCLImage2dArrayMSAA: + case clang::BuiltinType::OCLImage2dMSAADepth: + case clang::BuiltinType::OCLImage2dArrayMSAADepth: + case clang::BuiltinType::OCLImage3d: + case clang::BuiltinType::OCLSampler: + case clang::BuiltinType::OCLEvent: + case clang::BuiltinType::OCLClkEvent: + case clang::BuiltinType::OCLQueue: + case clang::BuiltinType::OCLNDRange: + case clang::BuiltinType::OCLReserveID: + return OmissionTypeName(); + + // OpenMP types that don't have Swift equivalents. + case clang::BuiltinType::OMPArraySection: + return OmissionTypeName(); } } @@ -1705,6 +1769,7 @@ OmissionTypeName ClangImporter::Implementation::getClangTypeNameForOmission( /// Attempt to omit needless words from the given function name. bool ClangImporter::Implementation::omitNeedlessWordsInFunctionName( + clang::Sema &clangSema, StringRef &baseName, SmallVectorImpl &argumentNames, ArrayRef params, @@ -1716,6 +1781,8 @@ bool ClangImporter::Implementation::omitNeedlessWordsInFunctionName( bool returnsSelf, bool isInstanceMethod, StringScratchSpace &scratch) { + clang::ASTContext &clangCtx = clangSema.Context; + // Collect the parameter type names. StringRef firstParamName; SmallVector paramTypes; @@ -1737,8 +1804,12 @@ bool ClangImporter::Implementation::omitNeedlessWordsInFunctionName( // Figure out whether there will be a default argument for this // parameter. + StringRef argumentName; + if (i < argumentNames.size()) + argumentName = argumentNames[i]; bool hasDefaultArg - = canInferDefaultArgument( + = inferDefaultArgument( + clangSema.PP, param->getType(), getParamOptionality(param, !nonNullArgs.empty() && nonNullArgs[i], @@ -1747,9 +1818,9 @@ bool ClangImporter::Implementation::omitNeedlessWordsInFunctionName( knownMethod->getParamTypeInfo(i)) : None), SwiftContext.getIdentifier(baseName), numParams, - isLastParameter); + argumentName, isLastParameter) != DefaultArgumentKind::None; - paramTypes.push_back(getClangTypeNameForOmission(param->getType()) + paramTypes.push_back(getClangTypeNameForOmission(clangCtx, param->getType()) .withDefaultArgument(hasDefaultArg)); } @@ -1765,8 +1836,8 @@ bool ClangImporter::Implementation::omitNeedlessWordsInFunctionName( // Omit needless words. return omitNeedlessWords(baseName, argumentNames, firstParamName, - getClangTypeNameForOmission(resultType), - getClangTypeNameForOmission(contextType), + getClangTypeNameForOmission(clangCtx, resultType), + getClangTypeNameForOmission(clangCtx, contextType), paramTypes, returnsSelf, /*isProperty=*/false, allPropertyNames, scratch); } @@ -1791,20 +1862,22 @@ clang::QualType ClangImporter::Implementation::getClangDeclContextType( return clang::QualType(); } -bool ClangImporter::Implementation::canInferDefaultArgument( - clang::QualType type, OptionalTypeKind clangOptionality, - Identifier baseName, unsigned numParams, bool isLastParameter) { +DefaultArgumentKind ClangImporter::Implementation::inferDefaultArgument( + clang::Preprocessor &pp, clang::QualType type, + OptionalTypeKind clangOptionality, Identifier baseName, + unsigned numParams, StringRef argumentLabel, + bool isLastParameter) { // Don't introduce a default argument for setters with only a single // parameter. if (numParams == 1 && camel_case::getFirstWord(baseName.str()) == "set") - return false; + return DefaultArgumentKind::None; // Some nullable parameters default to 'nil'. if (clangOptionality == OTK_Optional) { // Nullable trailing closure parameters default to 'nil'. if (isLastParameter && (type->isFunctionPointerType() || type->isBlockPointerType())) - return true; + return DefaultArgumentKind::Nil; // NSZone parameters default to 'nil'. if (auto ptrType = type->getAs()) { @@ -1812,22 +1885,57 @@ bool ClangImporter::Implementation::canInferDefaultArgument( = ptrType->getPointeeType()->getAs()) { if (recType->isStructureOrClassType() && recType->getDecl()->getName() == "_NSZone") - return true; + return DefaultArgumentKind::Nil; } } } // Option sets default to "[]" if they have "Options" in their name. if (const clang::EnumType *enumTy = type->getAs()) - if (classifyEnum(enumTy->getDecl()) == EnumKind::Options) { + if (classifyEnum(pp, enumTy->getDecl()) == EnumKind::Options) { auto enumName = enumTy->getDecl()->getName(); for (auto word : reversed(camel_case::getWords(enumName))) { if (camel_case::sameWordIgnoreFirstCase(word, "options")) - return true; + return DefaultArgumentKind::EmptyArray; } } - return false; + // NSDictionary arguments default to [:] if "options", "attributes", + // or "userInfo" occur in the argument label or (if there is no + // argument label) at the end of the base name. + if (auto objcPtrTy = type->getAs()) { + if (auto objcClass = objcPtrTy->getInterfaceDecl()) { + if (objcClass->getName() == "NSDictionary") { + StringRef searchStr = argumentLabel; + if (searchStr.empty() && !baseName.empty()) + searchStr = baseName.str(); + + bool sawInfo = false; + for (auto word : reversed(camel_case::getWords(searchStr))) { + if (camel_case::sameWordIgnoreFirstCase(word, "options")) + return DefaultArgumentKind::EmptyDictionary; + + if (camel_case::sameWordIgnoreFirstCase(word, "attributes")) + return DefaultArgumentKind::EmptyDictionary; + + if (camel_case::sameWordIgnoreFirstCase(word, "info")) { + sawInfo = true; + continue; + } + + if (sawInfo && camel_case::sameWordIgnoreFirstCase(word, "user")) + return DefaultArgumentKind::EmptyDictionary; + + if (argumentLabel.empty()) + break; + + sawInfo = false; + } + } + } + } + + return DefaultArgumentKind::None; } /// Adjust the result type of a throwing function based on the @@ -1890,7 +1998,7 @@ Type ClangImporter::Implementation::importMethodType( ArrayRef params, bool isVariadic, bool isNoReturn, bool isFromSystemModule, - SmallVectorImpl &bodyPatterns, + ParameterList **bodyParams, ImportedName importedName, DeclName &methodName, Optional &foreignErrorInfo, @@ -1998,9 +2106,7 @@ Type ClangImporter::Implementation::importMethodType( llvm::SmallBitVector nonNullArgs = getNonNullArgs(clangDecl, params); // Import the parameters. - SmallVector swiftArgParams; - SmallVector swiftBodyParams; - SmallVector bodyPatternElts; + SmallVector swiftParams; auto addEmptyTupleParameter = [&](Identifier argName) { // It doesn't actually matter which DeclContext we use, so just @@ -2010,16 +2116,7 @@ Type ClangImporter::Implementation::importMethodType( SourceLoc(), argName, SourceLoc(), argName, type, ImportedHeaderUnit); - Pattern *pattern = new (SwiftContext) NamedPattern(var); - pattern->setType(type); - pattern = new (SwiftContext) TypedPattern(pattern, - TypeLoc::withoutLoc(type)); - pattern->setType(type); - - bodyPatternElts.push_back(TuplePatternElt(pattern)); - bodyPatternElts.back().setLabel(argName, SourceLoc()); - swiftArgParams.push_back(TupleTypeElt(type, argName)); - swiftBodyParams.push_back(TupleTypeElt(type, argName)); + swiftParams.push_back(var); }; // Determine the number of parameters. @@ -2124,24 +2221,6 @@ Type ClangImporter::Implementation::importMethodType( } ++nameIndex; - // Determine whether we have a default argument. - DefaultArgumentKind defaultArg = DefaultArgumentKind::None; - bool isLastParameter - = (paramIndex == params.size() - 1) || - (paramIndex == params.size() - 2 && - errorInfo && errorInfo->ParamIndex == params.size() - 1); - - if (InferDefaultArguments && - (kind == SpecialMethodKind::Regular || - kind == SpecialMethodKind::Constructor) && - canInferDefaultArgument(param->getType(), optionalityOfParam, - methodName.getBaseName(), numEffectiveParams, - isLastParameter)) { - defaultArg = DefaultArgumentKind::Normal; - } - - // Compute the pattern to put into the body. - Pattern *bodyPattern; // It doesn't actually matter which DeclContext we use, so just use the // imported header unit. auto bodyVar @@ -2156,21 +2235,29 @@ Type ClangImporter::Implementation::importMethodType( new (SwiftContext) NoEscapeAttr(/*IsImplicit=*/false)); } - // Set up the body pattern. - bodyPattern = new (SwiftContext) NamedPattern(bodyVar); - bodyPattern->setType(swiftParamTy); - bodyPattern - = new (SwiftContext) TypedPattern(bodyPattern, - TypeLoc::withoutLoc(swiftParamTy)); - bodyPattern->setType(swiftParamTy); - TuplePatternElt patternElt(bodyPattern); - patternElt.setDefaultArgKind(defaultArg); - patternElt.setLabel(name, SourceLoc()); - bodyPatternElts.push_back(patternElt); - - // Add the tuple elements for the function types. - swiftArgParams.push_back(TupleTypeElt(swiftParamTy, name, defaultArg)); - swiftBodyParams.push_back(TupleTypeElt(swiftParamTy, bodyName, defaultArg)); + // Set up the parameter info. + auto paramInfo = bodyVar; + + // Determine whether we have a default argument. + if (InferDefaultArguments && + (kind == SpecialMethodKind::Regular || + kind == SpecialMethodKind::Constructor)) { + bool isLastParameter = (paramIndex == params.size() - 1) || + (paramIndex == params.size() - 2 && + errorInfo && errorInfo->ParamIndex == params.size() - 1); + + auto defaultArg = inferDefaultArgument(getClangPreprocessor(), + param->getType(), + optionalityOfParam, + methodName.getBaseName(), + numEffectiveParams, + name.empty() ? StringRef() + : name.str(), + isLastParameter); + if (defaultArg != DefaultArgumentKind::None) + paramInfo->setDefaultArgumentKind(defaultArg); + } + swiftParams.push_back(paramInfo); } // If we have a constructor with no parameters and a name with an @@ -2180,7 +2267,7 @@ Type ClangImporter::Implementation::importMethodType( addEmptyTupleParameter(argNames[0]); } - if (importedName.HasCustomName && argNames.size() != swiftBodyParams.size()) { + if (importedName.HasCustomName && argNames.size() != swiftParams.size()) { // Note carefully: we're emitting a warning in the /Clang/ buffer. auto &srcMgr = getClangASTContext().getSourceManager(); auto &rawDiagClient = Instance->getDiagnosticClient(); @@ -2189,19 +2276,15 @@ Type ClangImporter::Implementation::importMethodType( diagClient.resolveSourceLocation(srcMgr, clangDecl->getLocation()); if (methodLoc.isValid()) { SwiftContext.Diags.diagnose(methodLoc, diag::invalid_swift_name_method, - swiftBodyParams.size() < argNames.size(), - swiftBodyParams.size(), argNames.size()); + swiftParams.size() < argNames.size(), + swiftParams.size(), argNames.size()); } return Type(); } - // Form the parameter tuple. - auto bodyParamsTy = TupleType::get(swiftBodyParams, SwiftContext); - // Form the body patterns. - bodyPatterns.push_back(TuplePattern::create(SwiftContext, SourceLoc(), - bodyPatternElts, SourceLoc())); - bodyPatterns.back()->setType(bodyParamsTy); + // Form the parameter list. + *bodyParams = ParameterList::create(SwiftContext, swiftParams); FunctionType::ExtInfo extInfo; extInfo = extInfo.withIsNoReturn(isNoReturn); @@ -2215,8 +2298,8 @@ Type ClangImporter::Implementation::importMethodType( } // Form the function type. - auto argTy = TupleType::get(swiftArgParams, SwiftContext); - return FunctionType::get(argTy, swiftResultTy, extInfo); + return FunctionType::get((*bodyParams)->getType(SwiftContext), + swiftResultTy, extInfo); } Module *ClangImporter::Implementation::getStdlibModule() { diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index fad7faf0771e1..3b80638cf1d99 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -1,8 +1,8 @@ -//===--- ImporterImpl.h - Import Clang Modules - Implementation------------===// +//===--- ImporterImpl.h - Import Clang Modules: Implementation ------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,6 +28,7 @@ #include "clang/APINotes/APINotesReader.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Frontend/CompilerInstance.h" +#include "clang/Serialization/ModuleFileExtension.h" #include "clang/AST/Attr.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/DenseMap.h" @@ -219,7 +220,7 @@ using api_notes::FactoryAsInitKind; /// \brief Implementation of the Clang importer. class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation - : public LazyMemberLoader + : public LazyMemberLoader, public clang::ModuleFileExtension { friend class ClangImporter; @@ -249,7 +250,6 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// \brief Swift AST context. ASTContext &SwiftContext; - const bool InferImplicitProperties; const bool ImportForwardDeclarations; const bool OmitNeedlessWords; const bool InferDefaultArguments; @@ -295,6 +295,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// The Swift lookup table for the bridging header. SwiftLookupTable BridgingHeaderLookupTable; + /// The Swift lookup tables, per module. + llvm::StringMap> LookupTables; + public: /// \brief Mapping of already-imported declarations. llvm::DenseMap ImportedDecls; @@ -392,37 +395,35 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// \sa SuperfluousTypedefs llvm::DenseSet DeclsWithSuperfluousTypedefs; - using ClangDeclAndFlag = llvm::PointerIntPair; - /// \brief Mapping of already-imported declarations from protocols, which /// can (and do) get replicated into classes. - llvm::DenseMap, Decl *> + llvm::DenseMap, Decl *> ImportedProtocolDecls; - /// \brief Mapping of already-imported macros. - llvm::DenseMap ImportedMacros; + /// Mapping from identifiers to the set of macros that have that name along + /// with their corresponding Swift declaration. + /// + /// Multiple macro definitions can map to the same declaration if the + /// macros are identically defined. + llvm::DenseMap, 2>> + ImportedMacros; - /// Keeps track of active selector-basde lookups, so that we don't infinitely + /// Keeps track of active selector-based lookups, so that we don't infinitely /// recurse when checking whether a method with a given selector has already /// been imported. llvm::DenseMap, unsigned> ActiveSelectors; - // FIXME: An extra level of caching of visible decls, since lookup needs to - // be filtered by module after the fact. - SmallVector CachedVisibleDecls; - enum class CacheState { - Invalid, - InProgress, - Valid - } CurrentCacheState = CacheState::Invalid; + /// Whether we should suppress the import of the given Clang declaration. + static bool shouldSuppressDeclImport(const clang::Decl *decl); /// \brief Check if the declaration is one of the specially handled /// accessibility APIs. /// - /// These appaer as both properties and methods in ObjC and should be + /// These appear as both properties and methods in ObjC and should be /// imported as methods into Swift. - bool isAccessibilityDecl(const clang::Decl *objCMethodOrProp); + static bool isAccessibilityDecl(const clang::Decl *objCMethodOrProp); /// Determine whether this method is an Objective-C "init" method /// that will be imported as a Swift initializer. @@ -484,8 +485,6 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation void bumpGeneration() { ++Generation; SwiftContext.bumpGeneration(); - CachedVisibleDecls.clear(); - CurrentCacheState = CacheState::Invalid; } /// \brief Cache of the class extensions. @@ -521,7 +520,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// Retrieve the prefix to be stripped from the names of the enum constants /// within the given enum. - StringRef getEnumConstantNamePrefix(const clang::EnumDecl *enumDecl); + StringRef getEnumConstantNamePrefix(clang::Sema &sema, + const clang::EnumDecl *enumDecl); public: /// \brief Keep track of enum constant values that have been imported. @@ -536,6 +536,19 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation ConstructorDecl *> Constructors; + /// A mapping from imported declarations to their "alternate" declarations, + /// for cases where a single Clang declaration is imported to two + /// different Swift declarations. + llvm::DenseMap AlternateDecls; + + /// Retrieve the alternative declaration for the given imported + /// Swift declaration. + ValueDecl *getAlternateDecl(Decl *decl) { + auto known = AlternateDecls.find(decl); + if (known == AlternateDecls.end()) return nullptr; + return known->second; + } + private: /// \brief NSObject, imported into Swift. Type NSObjectTy; @@ -647,7 +660,13 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// Add the given named declaration as an entry to the given Swift name /// lookup table, including any of its child entries. - void addEntryToLookupTable(SwiftLookupTable &table, clang::NamedDecl *named); + void addEntryToLookupTable(clang::Sema &clangSema, SwiftLookupTable &table, + clang::NamedDecl *named); + + /// Add the macros from the given Clang preprocessor to the given + /// Swift name lookup table. + void addMacrosToLookupTable(clang::ASTContext &clangCtx, + clang::Preprocessor &pp, SwiftLookupTable &table); public: void registerExternalDecl(Decl *D) { @@ -716,7 +735,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation ClangModuleUnit *getClangModuleForMacro(const clang::MacroInfo *MI); /// Retrieve the type of an instance of the given Clang declaration context, - /// or a null type if the DeclContext does not have a correspinding type. + /// or a null type if the DeclContext does not have a corresponding type. clang::QualType getClangDeclContextType(const clang::DeclContext *dc); /// Determine whether this typedef is a CF type. @@ -724,15 +743,17 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// Determine the imported CF type for the given typedef-name, or the empty /// string if this is not an imported CF type name. - StringRef getCFTypeName(const clang::TypedefNameDecl *decl, - StringRef *secondaryName = nullptr); + static StringRef getCFTypeName(const clang::TypedefNameDecl *decl, + StringRef *secondaryName = nullptr); /// Retrieve the type name of a Clang type for the purposes of /// omitting unneeded words. - OmissionTypeName getClangTypeNameForOmission(clang::QualType type); + static OmissionTypeName getClangTypeNameForOmission(clang::ASTContext &ctx, + clang::QualType type); /// Omit needless words in a function name. bool omitNeedlessWordsInFunctionName( + clang::Sema &clangSema, StringRef &baseName, SmallVectorImpl &argumentNames, ArrayRef params, @@ -819,7 +840,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// introduces nesting, e.g., for enumerators within an NS_ENUM. ImportedName importFullName(const clang::NamedDecl *D, ImportNameOptions options = None, - clang::DeclContext **effectiveContext = nullptr); + clang::DeclContext **effectiveContext = nullptr, + clang::Sema *clangSemaOverride = nullptr); /// \brief Import the given Clang identifier into Swift. /// @@ -860,7 +882,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// \brief Classify the given Clang enumeration type to describe how it /// should be imported - EnumKind classifyEnum(const clang::EnumDecl *decl); + static EnumKind classifyEnum(clang::Preprocessor &pp, + const clang::EnumDecl *decl); /// Import attributes from the given Clang declaration to its Swift /// equivalent. @@ -912,7 +935,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// \returns The imported declaration, or null if this declaration could not /// be represented in Swift. Decl *importMirroredDecl(const clang::NamedDecl *decl, DeclContext *dc, - ProtocolDecl *proto, bool forceClassMethod = false); + ProtocolDecl *proto); /// \brief Import the given Clang declaration context into Swift. /// @@ -1095,7 +1118,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// \param params The parameter types to the function. /// \param isVariadic Whether the function is variadic. /// \param isNoReturn Whether the function is noreturn. - /// \param bodyPatterns The patterns visible inside the function body. + /// \param parameterList The parameters visible inside the function body. /// /// \returns the imported function type, or null if the type cannot be /// imported. @@ -1105,19 +1128,21 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation bool isVariadic, bool isNoReturn, bool isFromSystemModule, bool hasCustomName, - SmallVectorImpl &bodyPatterns, + ParameterList *¶meterList, DeclName &name); Type importPropertyType(const clang::ObjCPropertyDecl *clangDecl, bool isFromSystemModule); - /// Determine whether we can infer a default argument for a parameter with - /// the given \c type and (Clang) optionality. - bool canInferDefaultArgument(clang::QualType type, - OptionalTypeKind clangOptionality, - Identifier baseName, - unsigned numParams, - bool isLastParameter); + /// Attempt to infer a default argument for a parameter with the + /// given Clang \c type, \c baseName, and optionality. + DefaultArgumentKind inferDefaultArgument(clang::Preprocessor &pp, + clang::QualType type, + OptionalTypeKind clangOptionality, + Identifier baseName, + unsigned numParams, + StringRef argumentLabel, + bool isLastParameter); /// Retrieve a bit vector containing the non-null argument /// annotations for the given declaration. @@ -1140,7 +1165,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// \param isNoReturn Whether the function is noreturn. /// \param isFromSystemModule Whether to apply special rules that only apply /// to system APIs. - /// \param bodyPatterns The patterns visible inside the function body. + /// \param bodyParams The patterns visible inside the function body. /// whether the created arg/body patterns are different (selector-style). /// \param importedName The name of the imported method. /// \param errorConvention Information about the method's error conventions. @@ -1154,7 +1179,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation ArrayRef params, bool isVariadic, bool isNoReturn, bool isFromSystemModule, - SmallVectorImpl &bodyPatterns, + ParameterList **bodyParams, ImportedName importedName, DeclName &name, Optional &errorConvention, @@ -1201,7 +1226,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation SmallVector result = std::move(conformances->second); DelayedConformances.erase(conformances); - return std::move(result); + return result; } /// Record the set of imported protocols for the given declaration, @@ -1232,8 +1257,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation } virtual void - loadAllMembers(Decl *D, uint64_t unused, - bool *hasMissingRequiredMembers) override; + loadAllMembers(Decl *D, uint64_t unused) override; void loadAllConformances( @@ -1255,6 +1279,44 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation return D; } + // Module file extension overrides + + clang::ModuleFileExtensionMetadata getExtensionMetadata() const override; + llvm::hash_code hashExtension(llvm::hash_code code) const override; + + std::unique_ptr + createExtensionWriter(clang::ASTWriter &writer) override; + + std::unique_ptr + createExtensionReader(const clang::ModuleFileExtensionMetadata &metadata, + clang::ASTReader &reader, + clang::serialization::ModuleFile &mod, + const llvm::BitstreamCursor &stream) override; + + /// Find the lookup table that corresponds to the given Clang module. + /// + /// \param clangModule The module, or null to indicate that we're talking + /// about the directly-parsed headers. + SwiftLookupTable *findLookupTable(const clang::Module *clangModule); + + /// Look for namespace-scope values with the given name in the given + /// Swift lookup table. + void lookupValue(SwiftLookupTable &table, DeclName name, + VisibleDeclConsumer &consumer); + + /// Look for namespace-scope values in the given Swift lookup table. + void lookupVisibleDecls(SwiftLookupTable &table, + VisibleDeclConsumer &consumer); + + /// Look for Objective-C members with the given name in the given + /// Swift lookup table. + void lookupObjCMembers(SwiftLookupTable &table, DeclName name, + VisibleDeclConsumer &consumer); + + /// Look for all Objective-C members in the given Swift lookup table. + void lookupAllObjCMembers(SwiftLookupTable &table, + VisibleDeclConsumer &consumer); + /// Dump the Swift-specific name lookup tables we generate. void dumpSwiftLookupTables(); }; diff --git a/lib/ClangImporter/InferredAttributes.def b/lib/ClangImporter/InferredAttributes.def index b7eda9f2f9dcb..54a14a3805546 100644 --- a/lib/ClangImporter/InferredAttributes.def +++ b/lib/ClangImporter/InferredAttributes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,7 +22,7 @@ // ClassName is the name of the class, i.e., NSManagedObject // AttributeSet is an OR of attribute names, i.e., requires_stored_property_inits // -// ===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #ifndef INFERRED_ATTRIBUTES # define INFERRED_ATTRIBUTES(ModuleName, ClassName, AttributeSet) diff --git a/lib/ClangImporter/MacroTable.def b/lib/ClangImporter/MacroTable.def index 64a31eca04c77..11fc68104b16e 100644 --- a/lib/ClangImporter/MacroTable.def +++ b/lib/ClangImporter/MacroTable.def @@ -1,8 +1,8 @@ -//===--- SuppressedMacros.def - Macros suppressed during import -*- C++ -*-===// +//===--- MacroTable.def - Macros suppressed during import -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// // -// This file defines the database of macros that should be suppresed during +// This file defines the database of macros that should be suppressed during // API import. // -// ===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #ifndef SUPPRESS_MACRO /// Describes a macro that should be suppressed. diff --git a/lib/ClangImporter/MappedTypes.def b/lib/ClangImporter/MappedTypes.def index 6f6e822b59a7d..501ac7a68e89b 100644 --- a/lib/ClangImporter/MappedTypes.def +++ b/lib/ClangImporter/MappedTypes.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/ClangImporter/SortedCFDatabase.def.gyb b/lib/ClangImporter/SortedCFDatabase.def.gyb index 0cfa84e9c9f05..04d327ee021f3 100644 --- a/lib/ClangImporter/SortedCFDatabase.def.gyb +++ b/lib/ClangImporter/SortedCFDatabase.def.gyb @@ -6,7 +6,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,6 +17,8 @@ %{ import re +import sys +import codecs prologueLines = "" epilogueLines = "" @@ -26,7 +28,7 @@ epilogueLines = "" lineForName = {} # Load the data file. -with open(CFDatabaseFile, 'rb') as f: +with codecs.open(CFDatabaseFile, encoding='utf-8', errors='strict') as f: for line in f: # Pass through preprocessor directives literally. # Assume that they all fall into either a strict prologue or epilogue. diff --git a/lib/ClangImporter/SwiftLookupTable.cpp b/lib/ClangImporter/SwiftLookupTable.cpp index c234ee2cf3d13..46c6922f53e26 100644 --- a/lib/ClangImporter/SwiftLookupTable.cpp +++ b/lib/ClangImporter/SwiftLookupTable.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,79 +16,239 @@ //===----------------------------------------------------------------------===// #include "SwiftLookupTable.h" #include "swift/Basic/STLExtras.h" +#include "swift/Basic/Version.h" #include "clang/AST/DeclObjC.h" -using namespace swift; +#include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/ASTWriter.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitcode/RecordLayout.h" +#include "llvm/Support/OnDiskHashTable.h" -bool SwiftLookupTable::matchesContext(clang::DeclContext *foundContext, - clang::DeclContext *requestedContext) { - /// If the requested context was null, we match. - if (!requestedContext) - return true; +using namespace swift; +using namespace llvm::support; - // If the contexts match, we match. - if (foundContext == requestedContext) +/// Determine whether the new declarations matches an existing declaration. +static bool matchesExistingDecl(clang::Decl *decl, clang::Decl *existingDecl) { + // If the canonical declarations are equivalent, we have a match. + if (decl->getCanonicalDecl() == existingDecl->getCanonicalDecl()) { return true; - - // If we found something in an Objective-C protocol to which a class - // conforms, we match. - if (auto objcProto = dyn_cast(foundContext)) { - if (auto objcClass = dyn_cast(requestedContext)) { - return objcClass->ClassImplementsProtocol(objcProto, - /*lookupCategory=*/true); - } } return false; } -/// Determine whether the new declarations matches an existing declaration. -static bool matchesExistingDecl(clang::Decl *decl, clang::Decl *existingDecl) { - // If the canonical declarations are equivalent, we have a match. - if (decl->getCanonicalDecl() == existingDecl->getCanonicalDecl()) { +bool SwiftLookupTable::contextRequiresName(ContextKind kind) { + switch (kind) { + case ContextKind::ObjCClass: + case ContextKind::ObjCProtocol: + case ContextKind::Tag: return true; + + case ContextKind::TranslationUnit: + return false; } +} - return false; +Optional> +SwiftLookupTable::translateContext(clang::DeclContext *context) { + // Translation unit context. + if (context->isTranslationUnit()) + return std::make_pair(ContextKind::TranslationUnit, StringRef()); + + // Tag declaration context. + if (auto tag = dyn_cast(context)) { + if (tag->getIdentifier()) + return std::make_pair(ContextKind::Tag, tag->getName()); + if (auto typedefDecl = tag->getTypedefNameForAnonDecl()) + return std::make_pair(ContextKind::Tag, typedefDecl->getName()); + return None; + } + + // Objective-C class context. + if (auto objcClass = dyn_cast(context)) + return std::make_pair(ContextKind::ObjCClass, objcClass->getName()); + + // Objective-C protocol context. + if (auto objcProtocol = dyn_cast(context)) + return std::make_pair(ContextKind::ObjCProtocol, objcProtocol->getName()); + + return None; +} + +void SwiftLookupTable::addCategory(clang::ObjCCategoryDecl *category) { + assert(!Reader && "Cannot modify a lookup table stored on disk"); + + // Add the category. + Categories.push_back(category); } -void SwiftLookupTable::addEntry(DeclName name, clang::NamedDecl *decl, +void SwiftLookupTable::addEntry(DeclName name, SingleEntry newEntry, clang::DeclContext *effectiveContext) { - clang::DeclContext *context = effectiveContext->getPrimaryContext(); - - // First, check whether there is already a full name entry. - auto knownFull = FullNameTable.find(name); - if (knownFull == FullNameTable.end()) { - // We didn't have a full name entry, so record that in the base - // name table. - BaseNameTable[name.getBaseName()].push_back(name); - - // Insert the entry into the full name table. We're done. - FullTableEntry newEntry; - newEntry.Context = context; - newEntry.Decls.push_back(decl); - (void)FullNameTable.insert({name, { newEntry }}); - return; - } + assert(!Reader && "Cannot modify a lookup table stored on disk"); + + // Translate the context. + auto contextOpt = translateContext(effectiveContext); + if (!contextOpt) return; + auto context = *contextOpt; + + // Find the list of entries for this base name. + auto &entries = LookupTable[name.getBaseName().str()]; + auto decl = newEntry.dyn_cast(); + auto macro = newEntry.dyn_cast(); + for (auto &entry : entries) { + if (entry.Context == context) { + // We have entries for this context. - // Check whether there is already an entry with the same context. - auto &fullEntries = knownFull->second; - for (auto &fullEntry : fullEntries) { - if (fullEntry.Context == context) { // Check whether this entry matches any existing entry. - for (auto existingDecl : fullEntry.Decls) { - if (matchesExistingDecl(decl, existingDecl)) return; + for (auto &existingEntry : entry.DeclsOrMacros) { + // If it matches an existing declaration, there's nothing to do. + if (decl && isDeclEntry(existingEntry) && + matchesExistingDecl(decl, mapStoredDecl(existingEntry))) + return; + + // If it matches an existing macro, overwrite the existing entry. + if (macro && isMacroEntry(existingEntry)) { + existingEntry = encodeEntry(macro); + return; + } } - fullEntry.Decls.push_back(decl); + // Add an entry to this context. + if (decl) + entry.DeclsOrMacros.push_back(encodeEntry(decl)); + else + entry.DeclsOrMacros.push_back(encodeEntry(macro)); return; } } // This is a new context for this name. Add it. - FullTableEntry newEntry; - newEntry.Context = context; - newEntry.Decls.push_back(decl); - fullEntries.push_back(newEntry); + FullTableEntry entry; + entry.Context = context; + if (decl) + entry.DeclsOrMacros.push_back(encodeEntry(decl)); + else + entry.DeclsOrMacros.push_back(encodeEntry(macro)); + entries.push_back(entry); +} + + +auto SwiftLookupTable::findOrCreate(StringRef baseName) + -> llvm::DenseMap>::iterator { + // If there is no base name, there is nothing to find. + if (baseName.empty()) return LookupTable.end(); + + // Find entries for this base name. + auto known = LookupTable.find(baseName); + + // If we found something, we're done. + if (known != LookupTable.end()) return known; + + // If there's no reader, we've found all there is to find. + if (!Reader) return known; + + // Add an entry to the table so we don't look again. + known = LookupTable.insert({ baseName, { } }).first; + + // Lookup this base name in the module file. + (void)Reader->lookup(baseName, known->second); + + return known; +} + +SmallVector +SwiftLookupTable::lookup(StringRef baseName, + clang::DeclContext *searchContext) { + SmallVector result; + + // Find the lookup table entry for this base name. + auto known = findOrCreate(baseName); + if (known == LookupTable.end()) return result; + + // Translate context. + Optional> context; + if (searchContext) { + context = translateContext(searchContext); + if (!context) return result; + } + + // Walk each of the entries. + for (auto &entry : known->second) { + // If we're looking in a particular context and it doesn't match the + // entry context, we're done. + if (context && *context != entry.Context) continue; + + // Map each of the declarations. + for (auto &stored : entry.DeclsOrMacros) + result.push_back(mapStored(stored)); + } + + return result; +} + +SmallVector SwiftLookupTable::allBaseNames() { + // If we have a reader, enumerate its base names. + if (Reader) return Reader->getBaseNames(); + + // Otherwise, walk the lookup table. + SmallVector result; + for (const auto &entry : LookupTable) { + result.push_back(entry.first); + } + return result; +} + +SmallVector +SwiftLookupTable::lookupObjCMembers(StringRef baseName) { + SmallVector result; + + // Find the lookup table entry for this base name. + auto known = findOrCreate(baseName); + if (known == LookupTable.end()) return result; + + // Walk each of the entries. + for (auto &entry : known->second) { + // If we're looking in a particular context and it doesn't match the + // entry context, we're done. + switch (entry.Context.first) { + case ContextKind::TranslationUnit: + case ContextKind::Tag: + continue; + + case ContextKind::ObjCClass: + case ContextKind::ObjCProtocol: + break; + } + + // Map each of the declarations. + for (auto &stored : entry.DeclsOrMacros) { + assert(isDeclEntry(stored) && "Not a declaration?"); + result.push_back(mapStoredDecl(stored)); + } + } + + return result; +} + +ArrayRef SwiftLookupTable::categories() { + if (!Categories.empty() || !Reader) return Categories; + + // Map categories known to the reader. + for (auto declID : Reader->categories()) { + auto category = + cast_or_null( + Reader->getASTReader().GetLocalDecl(Reader->getModuleFile(), declID)); + if (category) + Categories.push_back(category); + + } + + return Categories; } static void printName(clang::NamedDecl *named, llvm::raw_ostream &out) { @@ -142,61 +302,53 @@ static void printName(clang::NamedDecl *named, llvm::raw_ostream &out) { } } +void SwiftLookupTable::deserializeAll() { + if (!Reader) return; + + for (auto baseName : Reader->getBaseNames()) { + (void)lookup(baseName, nullptr); + } + + (void)categories(); +} + void SwiftLookupTable::dump() const { - // Dump the base name -> full name mappings. - SmallVector baseNames; - for (const auto &entry : BaseNameTable) { + // Dump the base name -> full table entry mappings. + SmallVector baseNames; + for (const auto &entry : LookupTable) { baseNames.push_back(entry.first); } - std::sort(baseNames.begin(), baseNames.end(), - [&](Identifier x, Identifier y) { - return x.compare(y) < 0; - }); - llvm::errs() << "Base -> full name mappings:\n"; + llvm::array_pod_sort(baseNames.begin(), baseNames.end()); + llvm::errs() << "Base name -> entry mappings:\n"; for (auto baseName : baseNames) { - llvm::errs() << " " << baseName.str() << " --> "; - const auto &fullNames = BaseNameTable.find(baseName)->second; - interleave(fullNames.begin(), fullNames.end(), - [](DeclName fullName) { - llvm::errs() << fullName; - }, - [] { - llvm::errs() << ", "; - }); - llvm::errs() << "\n"; - } - llvm::errs() << "\n"; - - // Dump the full name -> full table entry mappings. - SmallVector fullNames; - for (const auto &entry : FullNameTable) { - fullNames.push_back(entry.first); - } - std::sort(fullNames.begin(), fullNames.end(), - [](DeclName x, DeclName y) { - return x.compare(y) < 0; - }); - llvm::errs() << "Full name -> entry mappings:\n"; - for (auto fullName : fullNames) { - llvm::errs() << " " << fullName << ":\n"; - const auto &fullEntries = FullNameTable.find(fullName)->second; - for (const auto &fullEntry : fullEntries) { + llvm::errs() << " " << baseName << ":\n"; + const auto &entries = LookupTable.find(baseName)->second; + for (const auto &entry : entries) { llvm::errs() << " "; - if (fullEntry.Context->isTranslationUnit()) { + switch (entry.Context.first) { + case ContextKind::TranslationUnit: llvm::errs() << "TU"; - } else if (auto named = dyn_cast(fullEntry.Context)) { - printName(named, llvm::errs()); - } else { - llvm::errs() << ""; + break; + + case ContextKind::Tag: + case ContextKind::ObjCClass: + case ContextKind::ObjCProtocol: + llvm::errs() << entry.Context.second; } llvm::errs() << ": "; - interleave(fullEntry.Decls.begin(), fullEntry.Decls.end(), - [](clang::NamedDecl *decl) { - if (auto named = dyn_cast(decl)) - printName(named, llvm::errs()); - else - decl->printName(llvm::errs()); + interleave(entry.DeclsOrMacros.begin(), entry.DeclsOrMacros.end(), + [this](uintptr_t entry) { + if (isSerializationIDEntry(entry)) { + llvm::errs() << (isMacroEntry(entry) ? "macro" : "decl") + << " ID #" << getSerializationID(entry); + } else if (isMacroEntry(entry)) { + llvm::errs() << "Macro"; + } else { + auto decl = const_cast(this) + ->mapStoredDecl(entry); + printName(decl, llvm::errs()); + } }, [] { llvm::errs() << ", "; @@ -204,4 +356,438 @@ void SwiftLookupTable::dump() const { llvm::errs() << "\n"; } } + + if (!Categories.empty()) { + llvm::errs() << "Categories: "; + interleave(Categories.begin(), Categories.end(), + [](clang::ObjCCategoryDecl *category) { + llvm::errs() << category->getClassInterface()->getName() + << "(" << category->getName() << ")"; + }, + [] { + llvm::errs() << ", "; + }); + llvm::errs() << "\n"; + } else if (Reader && !Reader->categories().empty()) { + llvm::errs() << "Categories: "; + interleave(Reader->categories().begin(), Reader->categories().end(), + [](clang::serialization::DeclID declID) { + llvm::errs() << "decl ID #" << declID; + }, + [] { + llvm::errs() << ", "; + }); + llvm::errs() << "\n"; + } +} + +// --------------------------------------------------------------------------- +// Serialization +// --------------------------------------------------------------------------- +using llvm::Fixnum; +using llvm::BCArray; +using llvm::BCBlob; +using llvm::BCFixed; +using llvm::BCGenericRecordLayout; +using llvm::BCRecordLayout; +using llvm::BCVBR; + +namespace { + enum RecordTypes { + /// Record that contains the mapping from base names to entities with that + /// name. + BASE_NAME_TO_ENTITIES_RECORD_ID + = clang::serialization::FIRST_EXTENSION_RECORD_ID, + + /// Record that contains the list of Objective-C category/extension IDs. + CATEGORIES_RECORD_ID + }; + + using BaseNameToEntitiesTableRecordLayout + = BCRecordLayout, BCBlob>; + + using CategoriesRecordLayout + = llvm::BCRecordLayout; + + /// Trait used to write the on-disk hash table for the base name -> entities + /// mapping. + class BaseNameToEntitiesTableWriterInfo { + SwiftLookupTable &Table; + clang::ASTWriter &Writer; + + public: + using key_type = StringRef; + using key_type_ref = key_type; + using data_type = SmallVector; + using data_type_ref = data_type &; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + BaseNameToEntitiesTableWriterInfo(SwiftLookupTable &table, + clang::ASTWriter &writer) + : Table(table), Writer(writer) + { + } + + hash_value_type ComputeHash(key_type_ref key) { + return llvm::HashString(key); + } + + std::pair EmitKeyDataLength(raw_ostream &out, + key_type_ref key, + data_type_ref data) { + // The length of the key. + uint32_t keyLength = key.size(); + + // # of entries + uint32_t dataLength = sizeof(uint16_t); + + // Storage per entry. + for (const auto &entry : data) { + // Context info. + dataLength += 1; + if (SwiftLookupTable::contextRequiresName(entry.Context.first)) { + dataLength += sizeof(uint16_t) + entry.Context.second.size(); + } + + // # of entries. + dataLength += sizeof(uint16_t); + + // Actual entries. + dataLength += (sizeof(clang::serialization::DeclID) * + entry.DeclsOrMacros.size()); + } + + endian::Writer writer(out); + writer.write(keyLength); + writer.write(dataLength); + return { keyLength, dataLength }; + } + + void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) { + out << key; + } + + void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data, + unsigned len) { + endian::Writer writer(out); + + // # of entries + writer.write(data.size()); + + for (auto &fullEntry : data) { + // Context. + writer.write(static_cast(fullEntry.Context.first)); + if (SwiftLookupTable::contextRequiresName(fullEntry.Context.first)) { + writer.write(fullEntry.Context.second.size()); + out << fullEntry.Context.second; + } + + // # of entries. + writer.write(fullEntry.DeclsOrMacros.size()); + + // Write the declarations and macros. + for (auto &entry : fullEntry.DeclsOrMacros) { + uint32_t id; + if (SwiftLookupTable::isDeclEntry(entry)) { + auto decl = Table.mapStoredDecl(entry); + id = (Writer.getDeclID(decl) << 2) | 0x02; + } else { + auto macro = Table.mapStoredMacro(entry); + id = (Writer.getMacroID(macro) << 2) | 0x02 | 0x01; + } + writer.write(id); + } + } + } + }; +} + +void SwiftLookupTableWriter::writeExtensionContents( + clang::Sema &sema, + llvm::BitstreamWriter &stream) { + // Populate the lookup table. + SwiftLookupTable table(nullptr); + PopulateTable(sema, table); + + SmallVector ScratchRecord; + + // First, gather the sorted list of base names. + SmallVector baseNames; + for (const auto &entry : table.LookupTable) + baseNames.push_back(entry.first); + llvm::array_pod_sort(baseNames.begin(), baseNames.end()); + + // Form the mapping from base names to entities with their context. + { + llvm::SmallString<4096> hashTableBlob; + uint32_t tableOffset; + { + llvm::OnDiskChainedHashTableGenerator + generator; + BaseNameToEntitiesTableWriterInfo info(table, Writer); + for (auto baseName : baseNames) + generator.insert(baseName, table.LookupTable[baseName], info); + + llvm::raw_svector_ostream blobStream(hashTableBlob); + // Make sure that no bucket is at offset 0 + endian::Writer(blobStream).write(0); + tableOffset = generator.Emit(blobStream, info); + } + + BaseNameToEntitiesTableRecordLayout layout(stream); + layout.emit(ScratchRecord, tableOffset, hashTableBlob); + } + + // Write the categories, if there are any. + if (!table.Categories.empty()) { + SmallVector categoryIDs; + for (auto category : table.Categories) { + categoryIDs.push_back(Writer.getDeclID(category)); + } + + StringRef blob(reinterpret_cast(categoryIDs.data()), + categoryIDs.size() * sizeof(clang::serialization::DeclID)); + CategoriesRecordLayout layout(stream); + layout.emit(ScratchRecord, blob); + } } + +namespace { + /// Used to deserialize the on-disk base name -> entities table. + class BaseNameToEntitiesTableReaderInfo { + public: + using internal_key_type = StringRef; + using external_key_type = internal_key_type; + using data_type = SmallVector; + using hash_value_type = uint32_t; + using offset_type = unsigned; + + internal_key_type GetInternalKey(external_key_type key) { + return key; + } + + external_key_type GetExternalKey(internal_key_type key) { + return key; + } + + hash_value_type ComputeHash(internal_key_type key) { + return llvm::HashString(key); + } + + static bool EqualKey(internal_key_type lhs, internal_key_type rhs) { + return lhs == rhs; + } + + static std::pair + ReadKeyDataLength(const uint8_t *&data) { + unsigned keyLength = endian::readNext(data); + unsigned dataLength = endian::readNext(data); + return { keyLength, dataLength }; + } + + static internal_key_type ReadKey(const uint8_t *data, unsigned length) { + return StringRef((const char *)data, length); + } + + static data_type ReadData(internal_key_type key, const uint8_t *data, + unsigned length) { + data_type result; + + // # of entries. + unsigned numEntries = endian::readNext(data); + result.reserve(numEntries); + + // Read all of the entries. + while (numEntries--) { + SwiftLookupTable::FullTableEntry entry; + + // Read the context. + entry.Context.first = + static_cast( + endian::readNext(data)); + if (SwiftLookupTable::contextRequiresName(entry.Context.first)) { + uint16_t length = endian::readNext(data); + entry.Context.second = StringRef((const char *)data, length); + data += length; + } + + // Read the declarations and macros. + unsigned numDeclsOrMacros = + endian::readNext(data); + while (numDeclsOrMacros--) { + auto id = endian::readNext(data); + entry.DeclsOrMacros.push_back(id); + } + + result.push_back(entry); + } + + return result; + } + }; + +} + +namespace swift { + using SerializedBaseNameToEntitiesTable = + llvm::OnDiskIterableChainedHashTable; +} + +clang::NamedDecl *SwiftLookupTable::mapStoredDecl(uintptr_t &entry) { + assert(isDeclEntry(entry) && "Not a declaration entry"); + + // If we have an AST node here, just cast it. + if (isASTNodeEntry(entry)) { + return static_cast(getPointerFromEntry(entry)); + } + + // Otherwise, resolve the declaration. + assert(Reader && "Cannot resolve the declaration without a reader"); + clang::serialization::DeclID declID = getSerializationID(entry); + auto decl = cast_or_null( + Reader->getASTReader().GetLocalDecl(Reader->getModuleFile(), + declID)); + + // Update the entry now that we've resolved the declaration. + entry = encodeEntry(decl); + return decl; +} + +clang::MacroInfo *SwiftLookupTable::mapStoredMacro(uintptr_t &entry) { + assert(isMacroEntry(entry) && "Not a macro entry"); + + // If we have an AST node here, just cast it. + if (isASTNodeEntry(entry)) { + return static_cast(getPointerFromEntry(entry)); + } + + // Otherwise, resolve the macro. + assert(Reader && "Cannot resolve the macro without a reader"); + clang::serialization::MacroID macroID = getSerializationID(entry); + auto macro = cast_or_null( + Reader->getASTReader().getMacro( + Reader->getASTReader().getGlobalMacroID( + Reader->getModuleFile(), + macroID))); + + // Update the entry now that we've resolved the macro. + entry = encodeEntry(macro); + return macro; +} + +SwiftLookupTable::SingleEntry SwiftLookupTable::mapStored(uintptr_t &entry) { + if (isDeclEntry(entry)) + return mapStoredDecl(entry); + + return mapStoredMacro(entry); +} + +SwiftLookupTableReader::~SwiftLookupTableReader() { + OnRemove(); + delete static_cast(SerializedTable); +} + +std::unique_ptr +SwiftLookupTableReader::create(clang::ModuleFileExtension *extension, + clang::ASTReader &reader, + clang::serialization::ModuleFile &moduleFile, + std::function onRemove, + const llvm::BitstreamCursor &stream) +{ + // Look for the base name -> entities table record. + SmallVector scratch; + auto cursor = stream; + auto next = cursor.advance(); + std::unique_ptr serializedTable; + ArrayRef categories; + while (next.Kind != llvm::BitstreamEntry::EndBlock) { + if (next.Kind == llvm::BitstreamEntry::Error) + return nullptr; + + if (next.Kind == llvm::BitstreamEntry::SubBlock) { + // Unknown sub-block, possibly for use by a future version of the + // API notes format. + if (cursor.SkipBlock()) + return nullptr; + + next = cursor.advance(); + continue; + } + + scratch.clear(); + StringRef blobData; + unsigned kind = cursor.readRecord(next.ID, scratch, &blobData); + switch (kind) { + case BASE_NAME_TO_ENTITIES_RECORD_ID: { + // Already saw base name -> entities table. + if (serializedTable) + return nullptr; + + uint32_t tableOffset; + BaseNameToEntitiesTableRecordLayout::readRecord(scratch, tableOffset); + auto base = reinterpret_cast(blobData.data()); + + serializedTable.reset( + SerializedBaseNameToEntitiesTable::Create(base + tableOffset, + base + sizeof(uint32_t), + base)); + break; + } + + case CATEGORIES_RECORD_ID: { + // Already saw categories; input is malformed. + if (!categories.empty()) return nullptr; + + auto start = + reinterpret_cast(blobData.data()); + unsigned numElements + = blobData.size() / sizeof(clang::serialization::DeclID); + categories = llvm::makeArrayRef(start, numElements); + break; + } + + default: + // Unknown record, possibly for use by a future version of the + // module format. + break; + } + + next = cursor.advance(); + } + + if (!serializedTable) return nullptr; + + // Create the reader. + return std::unique_ptr( + new SwiftLookupTableReader(extension, reader, moduleFile, onRemove, + serializedTable.release(), categories)); + +} + +SmallVector SwiftLookupTableReader::getBaseNames() { + auto table = static_cast(SerializedTable); + SmallVector results; + for (auto key : table->keys()) { + results.push_back(key); + } + return results; +} + +/// Retrieve the set of entries associated with the given base name. +/// +/// \returns true if we found anything, false otherwise. +bool SwiftLookupTableReader::lookup( + StringRef baseName, + SmallVectorImpl &entries) { + auto table = static_cast(SerializedTable); + + // Look for an entry with this base name. + auto known = table->find(baseName); + if (known == table->end()) return false; + + // Grab the results. + entries = std::move(*known); + return true; +} + diff --git a/lib/ClangImporter/SwiftLookupTable.h b/lib/ClangImporter/SwiftLookupTable.h index 59ec0a120bcb4..bfe1bc0fb927b 100644 --- a/lib/ClangImporter/SwiftLookupTable.h +++ b/lib/ClangImporter/SwiftLookupTable.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,17 +19,40 @@ #include "swift/Basic/LLVM.h" #include "swift/AST/Identifier.h" +#include "clang/Serialization/ASTBitCodes.h" +#include "clang/Serialization/ModuleFileExtension.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TinyPtrVector.h" +#include +#include + +namespace llvm { +class BitstreamWriter; +} namespace clang { class NamedDecl; class DeclContext; +class MacroInfo; +class ObjCCategoryDecl; } namespace swift { +class SwiftLookupTableReader; +class SwiftLookupTableWriter; + +/// Lookup table major version number. +/// +const uint16_t SWIFT_LOOKUP_TABLE_VERSION_MAJOR = 1; + +/// Lookup table minor version number. +/// +/// When the format changes IN ANY WAY, this number should be incremented. +const uint16_t SWIFT_LOOKUP_TABLE_VERSION_MINOR = 2; + /// A lookup table that maps Swift names to the set of Clang /// declarations with that particular name. /// @@ -40,71 +63,242 @@ namespace swift { /// entities based on their Swift names, and is used by the Clang /// importer to satisfy the Swift compiler's queries. class SwiftLookupTable { +public: + /// The kind of context in which a name occurs. + enum class ContextKind : uint8_t { + /// A translation unit. + TranslationUnit = 0, + /// A tag declaration (struct, enum, union, C++ class). + Tag, + /// An Objective-C class. + ObjCClass, + /// An Objective-C protocol. + ObjCProtocol, + }; + + /// Determine whether the given context requires a name to disambiguate. + static bool contextRequiresName(ContextKind kind); + + /// A single entry referencing either a named declaration or a macro. + typedef llvm::PointerUnion SingleEntry; + /// An entry in the table of C entities indexed by full Swift name. struct FullTableEntry { /// The context in which the entities with the given name occur, e.g., /// a class, struct, translation unit, etc. - /// - /// Many Clang DeclContexts can have redeclarations, so this entry /// is always the canonical DeclContext for the entity. - clang::DeclContext *Context; + std::pair Context; - /// The set of Clang declarations with this name and in this - /// context. - llvm::TinyPtrVector Decls; + /// The set of Clang declarations and macros with this name and in + /// this context. + /// + /// The low bit indicates whether we have a declaration or macro + /// (declaration = unset, macro = set) and the second lowest bit + /// indicates whether we have a serialization ID (set = DeclID or + /// MacroID, as appropriate) vs. a pointer (unset, + /// clang::NamedDecl * or clang::MacroInfo *). In the ID case, the + /// upper N-2 bits are the ID value; in the pointer case, the + /// lower two bits will always be clear due to the alignment of + /// the Clang pointers. + llvm::SmallVector DeclsOrMacros; }; - /// A table mapping from the full name of Swift entities to all of + /// Whether the given entry is a macro entry. + static bool isMacroEntry(uintptr_t entry) { return entry & 0x01; } + + /// Whether the given entry is a declaration entry. + static bool isDeclEntry(uintptr_t entry) { return !isMacroEntry(entry); } + + /// Whether the given entry is a serialization ID. + static bool isSerializationIDEntry(uintptr_t entry) { return (entry & 0x02); } + + /// Whether the given entry is an AST node. + static bool isASTNodeEntry(uintptr_t entry) { + return !isSerializationIDEntry(entry); + } + + /// Retrieve the serialization ID for an entry. + static uint32_t getSerializationID(uintptr_t entry) { + assert(isSerializationIDEntry(entry) && "Not a serialization entry"); + return entry >> 2; + } + + /// Retrieve the pointer for an entry. + static void *getPointerFromEntry(uintptr_t entry) { + assert(isASTNodeEntry(entry) && "Not an AST node entry"); + const uintptr_t mask = ~static_cast(0x03); + return reinterpret_cast(entry & mask); + } + + /// Encode a Clang named declaration as an entry in the table. + static uintptr_t encodeEntry(clang::NamedDecl *decl) { + auto bits = reinterpret_cast(decl); + assert((bits & 0x03) == 0 && "low bits set?"); + return bits; + } + + // Encode a Clang macro as an entry in the table. + static uintptr_t encodeEntry(clang::MacroInfo *macro) { + auto bits = reinterpret_cast(macro); + assert((bits & 0x03) == 0 && "low bits set?"); + return bits | 0x01; + } + + /// Encode a declaration ID as an entry in the table. + static uintptr_t encodeDeclID(clang::serialization::DeclID id) { + auto upper = static_cast(id) << 2; + assert(upper >> 2 == id); + return upper | 0x02; + } + + /// Encode a macro ID as an entry in the table. + static uintptr_t encodeMacroID(clang::serialization::MacroID id) { + auto upper = static_cast(id) << 2; + assert(upper >> 2 == id); + return upper | 0x02 | 0x01; + } + +private: + /// A table mapping from the base name of Swift entities to all of /// the C entities that have that name, in all contexts. - llvm::DenseMap> FullNameTable; + llvm::DenseMap> LookupTable; + + /// The list of Objective-C categories and extensions. + llvm::SmallVector Categories; + + /// The reader responsible for lazily loading the contents of this table. + SwiftLookupTableReader *Reader; - /// A table mapping from the base name of a Swift name to all of the - /// full Swift names based on that identifier. - llvm::DenseMap> BaseNameTable; + friend class SwiftLookupTableReader; + friend class SwiftLookupTableWriter; + + /// Find or create the table entry for the given base name. + llvm::DenseMap>::iterator + findOrCreate(StringRef baseName); - /// Determine whether the given context we found matches the - /// requested context. - bool matchesContext(clang::DeclContext *foundContext, - clang::DeclContext *requestedContext); public: + explicit SwiftLookupTable(SwiftLookupTableReader *reader) : Reader(reader) { } + + /// Maps a stored declaration entry to an actual Clang declaration. + clang::NamedDecl *mapStoredDecl(uintptr_t &entry); + + /// Maps a stored macro entry to an actual Clang macro. + clang::MacroInfo *mapStoredMacro(uintptr_t &entry); + + /// Maps a stored entry to an actual Clang AST node. + SingleEntry mapStored(uintptr_t &entry); + + /// Translate a Clang DeclContext into a context kind and name. + llvm::Optional> + translateContext(clang::DeclContext *context); + /// Add an entry to the lookup table. /// /// \param name The Swift name of the entry. - /// \param decl The Clang declaration to add. + /// \param newEntry The Clang declaration or macro. /// \param effectiveContext The effective context in which name lookup occurs. - void addEntry(DeclName name, clang::NamedDecl *decl, + void addEntry(DeclName name, SingleEntry newEntry, clang::DeclContext *effectiveContext); - /// Lookup the set of declarations with the given base name. + /// Add an Objective-C category or extension to the table. + void addCategory(clang::ObjCCategoryDecl *category); + + /// Lookup the set of entities with the given base name. /// /// \param baseName The base name to search for. All results will /// have this base name. /// - /// \param context The context in which the resulting set of - /// declarations should reside. This may be null to indicate that + /// \param searchContext The context in which the resulting set of + /// entities should reside. This may be null to indicate that /// all results from all contexts should be produced. - ArrayRef - lookup(Identifier baseName, - clang::DeclContext *context, - SmallVectorImpl &scratch); + SmallVector + lookup(StringRef baseName, clang::DeclContext *searchContext); - /// Lookup the set of declarations with the given full name. - /// - /// \param name The full name to search for. All results will have - /// this full name. - /// - /// \param context The context in which the resulting set of - /// declarations should reside. This may be null to indicate that - /// all results from all contexts should be produced. - ArrayRef - lookup(DeclName name, - clang::DeclContext *context, - SmallVectorImpl &scratch); + /// Retrieve the set of base names that are stored in the lookup table. + SmallVector allBaseNames(); + + /// Lookup Objective-C members with the given base name, regardless + /// of context. + SmallVector lookupObjCMembers(StringRef baseName); + + /// Retrieve the set of Objective-C categories and extensions. + ArrayRef categories(); + + /// Deserialize all entries. + void deserializeAll(); /// Dump the internal representation of this lookup table. void dump() const; }; +/// Module file extension writer for the Swift lookup tables. +class SwiftLookupTableWriter : public clang::ModuleFileExtensionWriter { + clang::ASTWriter &Writer; + std::function PopulateTable; + +public: + SwiftLookupTableWriter( + clang::ModuleFileExtension *extension, + std::function populateTable, + clang::ASTWriter &writer) + : ModuleFileExtensionWriter(extension), Writer(writer), + PopulateTable(std::move(populateTable)) { } + + void writeExtensionContents(clang::Sema &sema, + llvm::BitstreamWriter &stream) override; +}; + +/// Module file extension reader for the Swift lookup tables. +class SwiftLookupTableReader : public clang::ModuleFileExtensionReader { + clang::ASTReader &Reader; + clang::serialization::ModuleFile &ModuleFile; + std::function OnRemove; + + void *SerializedTable; + ArrayRef Categories; + + SwiftLookupTableReader(clang::ModuleFileExtension *extension, + clang::ASTReader &reader, + clang::serialization::ModuleFile &moduleFile, + std::function onRemove, + void *serializedTable, + ArrayRef categories) + : ModuleFileExtensionReader(extension), Reader(reader), + ModuleFile(moduleFile), OnRemove(onRemove), + SerializedTable(serializedTable), Categories(categories) { } + +public: + /// Create a new lookup table reader for the given AST reader and stream + /// position. + static std::unique_ptr + create(clang::ModuleFileExtension *extension, clang::ASTReader &reader, + clang::serialization::ModuleFile &moduleFile, + std::function onRemove, + const llvm::BitstreamCursor &stream); + + ~SwiftLookupTableReader(); + + /// Retrieve the AST reader associated with this lookup table reader. + clang::ASTReader &getASTReader() const { return Reader; } + + /// Retrieve the module file associated with this lookup table reader. + clang::serialization::ModuleFile &getModuleFile() { return ModuleFile; } + + /// Retrieve the set of base names that are stored in the on-disk hash table. + SmallVector getBaseNames(); + + /// Retrieve the set of entries associated with the given base name. + /// + /// \returns true if we found anything, false otherwise. + bool lookup(StringRef baseName, + SmallVectorImpl &entries); + + /// Retrieve the declaration IDs of the categories. + ArrayRef categories() const { + return Categories; + } +}; + } #endif // SWIFT_CLANGIMPORTER_SWIFTLOOKUPTABLE_H diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp index e1ce69df6b717..fcccdb0f1578c 100644 --- a/lib/Driver/Action.cpp +++ b/lib/Driver/Action.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,6 +28,7 @@ const char *Action::getClassName(ActionClass AC) { switch (AC) { case Input: return "input"; case CompileJob: return "compile"; + case InterpretJob: return "interpret"; case BackendJob: return "backend"; case MergeModuleJob: return "merge-module"; case ModuleWrapJob: return "modulewrap"; @@ -46,6 +47,8 @@ void JobAction::anchor() {} void CompileJobAction::anchor() {} +void InterpretJobAction::anchor() {} + void BackendJobAction::anchor() {} void MergeModuleJobAction::anchor() {} diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index a8718746a0e86..2bc7e9b785986 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -12,14 +12,10 @@ set(swiftDriver_sources Types.cpp ) +set(swiftDriver_targetDefines) + add_swift_library(swiftDriver ${swiftDriver_sources} DEPENDS SwiftOptions LINK_LIBRARIES swiftAST swiftBasic swiftFrontend swiftOption) -if(${SWIFT_ENABLE_TARGET_LINUX}) - foreach(f ${swiftDriver_sources}) - set_property(SOURCE ${f} APPEND_STRING PROPERTY COMPILE_FLAGS - " -DSWIFT_ENABLE_TARGET_LINUX=\"1\"") - endforeach() -endif() diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index 4235d25e790a6..69be0a9d56cd8 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -262,6 +262,8 @@ int Compilation::performJobsImpl() { return; } + assert(Cmd->getExtraEnvironment().empty() && + "not implemented for compilations with multiple jobs"); State.ScheduledCommands.insert(Cmd); TQ->addTask(Cmd->getExecutable(), Cmd->getArguments(), llvm::None, (void *)Cmd); @@ -497,7 +499,7 @@ int Compilation::performJobsImpl() { Diags.diagnose(SourceLoc(), diag::error_command_signalled, SignalledCmd->getSource().getClassName()); - // Since the task signalled, so unconditionally set result to -2. + // Since the task signalled, unconditionally set result to -2. Result = -2; return TaskFinishedResponse::StopExecution; @@ -584,6 +586,9 @@ int Compilation::performSingleCommand(const Job *Cmd) { const char *ExecPath = Cmd->getExecutable(); const char **argv = Argv.data(); + for (auto &envPair : Cmd->getExtraEnvironment()) + setenv(envPair.first, envPair.second, /*replacing=*/true); + return ExecuteInPlace(ExecPath, argv); } diff --git a/lib/Driver/DependencyGraph.cpp b/lib/Driver/DependencyGraph.cpp index 59e157dd45965..ab58826a5e0dc 100644 --- a/lib/Driver/DependencyGraph.cpp +++ b/lib/Driver/DependencyGraph.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -73,6 +73,19 @@ parseDependencyFile(llvm::MemoryBuffer &buffer, LoadResult result = LoadResult::UpToDate; SmallString<64> scratch; + // After an entry, we know more about the node as a whole. + // Update the "result" variable above. + // This is a macro rather than a lambda because it contains a return. +#define UPDATE_RESULT(update) switch (update) {\ + case LoadResult::HadError: \ + return LoadResult::HadError; \ + case LoadResult::UpToDate: \ + break; \ + case LoadResult::AffectsDownstream: \ + result = LoadResult::AffectsDownstream; \ + break; \ + } \ + // FIXME: LLVM's YAML support does incremental parsing in such a way that // for-range loops break. for (auto i = topLevelMap->begin(), e = topLevelMap->end(); i != e; ++i) { @@ -83,7 +96,6 @@ parseDependencyFile(llvm::MemoryBuffer &buffer, if (!key) return LoadResult::HadError; StringRef keyString = key->getValue(scratch); - LoadResult resultUpdate; if (keyString == "interface-hash") { auto *value = dyn_cast(i->getValue()); @@ -91,7 +103,7 @@ parseDependencyFile(llvm::MemoryBuffer &buffer, return LoadResult::HadError; StringRef valueString = value->getValue(scratch); - resultUpdate = interfaceHashCallback(valueString); + UPDATE_RESULT(interfaceHashCallback(valueString)); } else { enum class DependencyDirection : bool { @@ -172,8 +184,8 @@ parseDependencyFile(llvm::MemoryBuffer &buffer, appended.push_back('\0'); appended += member->getValue(scratch); - resultUpdate = callback(appended.str(), dirAndKind.first, - isCascading); + UPDATE_RESULT(callback(appended.str(), dirAndKind.first, + isCascading)); } } else { for (const yaml::Node &rawEntry : *entries) { @@ -184,22 +196,11 @@ parseDependencyFile(llvm::MemoryBuffer &buffer, bool isDepends = dirAndKind.second == DependencyDirection::Depends; auto &callback = isDepends ? dependsCallback : providesCallback; - resultUpdate = callback(entry->getValue(scratch), dirAndKind.first, - entry->getRawTag() != "!private"); + UPDATE_RESULT(callback(entry->getValue(scratch), dirAndKind.first, + entry->getRawTag() != "!private")); } } } - - // After processing this entry, we now know more about the node as a whole. - switch (resultUpdate) { - case LoadResult::HadError: - return LoadResult::HadError; - case LoadResult::UpToDate: - break; - case LoadResult::AffectsDownstream: - result = LoadResult::AffectsDownstream; - break; - } } return result; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index ea4af3546ac9f..cd1a96dcf0f46 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1,8 +1,8 @@ -//===-- Driver.cpp - Swift compiler driver --------------------------------===// +//===--- Driver.cpp - Swift compiler driver -------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -1244,14 +1244,8 @@ void Driver::buildActions(const ToolChain &TC, break; } } - SWIFT_FALLTHROUGH; - } - case OutputInfo::Mode::Immediate: { - if (Inputs.empty()) - return; // Create a single CompileJobAction for all of the driver's inputs. - // Don't create a CompileJobAction if there are no inputs, though. std::unique_ptr CA(new CompileJobAction(OI.CompilerOutputType)); for (const InputPair &Input : Inputs) { types::ID InputType = Input.first; @@ -1263,6 +1257,21 @@ void Driver::buildActions(const ToolChain &TC, AllLinkerInputs.push_back(CA.release()); break; } + case OutputInfo::Mode::Immediate: { + if (Inputs.empty()) + return; + + assert(OI.CompilerOutputType == types::TY_Nothing); + std::unique_ptr CA(new InterpretJobAction()); + for (const InputPair &Input : Inputs) { + types::ID InputType = Input.first; + const Arg *InputArg = Input.second; + + CA->addInput(new InputAction(*InputArg, InputType)); + } + Actions.push_back(CA.release()); + return; + } case OutputInfo::Mode::REPL: { if (!Inputs.empty()) { // REPL mode requires no inputs. @@ -1378,7 +1387,7 @@ Driver::buildOutputFileMap(const llvm::opt::DerivedArgList &Args) const { // TODO: emit diagnostic with error string Diags.diagnose(SourceLoc(), diag::error_unable_to_load_output_file_map); } - return std::move(OFM); + return OFM; } void Driver::buildJobs(const ActionList &Actions, const OutputInfo &OI, @@ -1990,7 +1999,7 @@ void Driver::printActions(const ActionList &Actions) const { void Driver::printJobs(const Compilation &C) const { for (const Job *J : C.getJobs()) - J->printCommandLine(llvm::outs()); + J->printCommandLineAndEnvironment(llvm::outs()); } void Driver::printVersion(const ToolChain &TC, raw_ostream &OS) const { @@ -2036,11 +2045,10 @@ const ToolChain *Driver::getToolChain(const ArgList &Args) const { case llvm::Triple::WatchOS: TC = new toolchains::Darwin(*this, Target); break; -#if defined(SWIFT_ENABLE_TARGET_LINUX) case llvm::Triple::Linux: - TC = new toolchains::Linux(*this, Target); + case llvm::Triple::FreeBSD: + TC = new toolchains::GenericUnix(*this, Target); break; -#endif // SWIFT_ENABLE_TARGET_LINUX default: TC = nullptr; } diff --git a/lib/Driver/FrontendUtil.cpp b/lib/Driver/FrontendUtil.cpp index 2964034f44539..d18e2c0266320 100644 --- a/lib/Driver/FrontendUtil.cpp +++ b/lib/Driver/FrontendUtil.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp index 99e69b83c6728..9e6a8c242be3a 100644 --- a/lib/Driver/Job.cpp +++ b/lib/Driver/Job.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -85,7 +85,19 @@ void Job::printArguments(raw_ostream &os, } void Job::dump() const { - printCommandLine(llvm::errs()); + printCommandLineAndEnvironment(llvm::errs()); +} + +void Job::printCommandLineAndEnvironment(raw_ostream &Stream, + StringRef Terminator) const { + printCommandLine(Stream, /*Terminator=*/""); + if (!ExtraEnvironment.empty()) { + Stream << " #"; + for (auto &pair : ExtraEnvironment) { + Stream << " " << pair.first << "=" << pair.second; + } + } + Stream << "\n"; } void Job::printCommandLine(raw_ostream &os, StringRef Terminator) const { diff --git a/lib/Driver/OutputFileMap.cpp b/lib/Driver/OutputFileMap.cpp index 104be1d29c541..0725e7336e8c2 100644 --- a/lib/Driver/OutputFileMap.cpp +++ b/lib/Driver/OutputFileMap.cpp @@ -1,8 +1,8 @@ -//===-- OutputFileMap.cpp - Driver output file map -------------*- C++ -*--===// +//===--- OutputFileMap.cpp - Driver output file map -------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Driver/ParseableOutput.cpp b/lib/Driver/ParseableOutput.cpp index a27ef83503d94..e4279b98e38bc 100644 --- a/lib/Driver/ParseableOutput.cpp +++ b/lib/Driver/ParseableOutput.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 868cd16d101bb..3e596c8563e76 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -42,47 +42,50 @@ ToolChain::constructJob(const JobAction &JA, const OutputInfo &OI) const { JobContext context{inputs, *output, inputActions, args, OI}; - const char *executableName; - llvm::opt::ArgStringList arguments; - switch (JA.getKind()) { -#define CASE(K) case Action::K: \ - std::tie(executableName, arguments) = \ - constructInvocation(cast(JA), context); \ - break; - CASE(CompileJob) - CASE(BackendJob) - CASE(MergeModuleJob) - CASE(ModuleWrapJob) - CASE(LinkJob) - CASE(GenerateDSYMJob) - CASE(AutolinkExtractJob) - CASE(REPLJob) + auto invocationInfo = [&]() -> InvocationInfo { + switch (JA.getKind()) { + #define CASE(K) case Action::K: \ + return constructInvocation(cast(JA), context); + CASE(CompileJob) + CASE(InterpretJob) + CASE(BackendJob) + CASE(MergeModuleJob) + CASE(ModuleWrapJob) + CASE(LinkJob) + CASE(GenerateDSYMJob) + CASE(AutolinkExtractJob) + CASE(REPLJob) #undef CASE - case Action::Input: - llvm_unreachable("not a JobAction"); - } + case Action::Input: + llvm_unreachable("not a JobAction"); + } + }(); // Special-case the Swift frontend. const char *executablePath = nullptr; - if (StringRef(SWIFT_EXECUTABLE_NAME) == executableName) { + if (StringRef(SWIFT_EXECUTABLE_NAME) == invocationInfo.ExecutableName) { executablePath = getDriver().getSwiftProgramPath().c_str(); } else { - std::string relativePath = findProgramRelativeToSwift(executableName); + std::string relativePath = + findProgramRelativeToSwift(invocationInfo.ExecutableName); if (!relativePath.empty()) { executablePath = args.MakeArgString(relativePath); } else { - auto systemPath = llvm::sys::findProgramByName(executableName); + auto systemPath = + llvm::sys::findProgramByName(invocationInfo.ExecutableName); if (systemPath) { executablePath = args.MakeArgString(systemPath.get()); } else { // For debugging purposes. - executablePath = executableName; + executablePath = invocationInfo.ExecutableName; } } } return llvm::make_unique(JA, std::move(inputs), std::move(output), - executablePath, std::move(arguments)); + executablePath, + std::move(invocationInfo.Arguments), + std::move(invocationInfo.ExtraEnvironment)); } std::string diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 58ea181d96537..707fece012151 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1,8 +1,8 @@ -//===--- ToolChains.cpp - Job invocations (general and per-plaftorm) ------===// +//===--- ToolChains.cpp - Job invocations (general and per-platform) ------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -148,7 +148,8 @@ static void addCommonFrontendArgs(const ToolChain &TC, arguments.push_back("-color-diagnostics"); } -std::pair + +ToolChain::InvocationInfo ToolChain::constructInvocation(const CompileJobAction &job, const JobContext &context) const { ArgStringList Arguments; @@ -216,10 +217,8 @@ ToolChain::constructInvocation(const CompileJobAction &job, break; } case OutputInfo::Mode::Immediate: - FrontendModeOption = "-interpret"; - break; case OutputInfo::Mode::REPL: - llvm_unreachable("REPL mode handled elsewhere"); + llvm_unreachable("REPL and immediate modes handled elsewhere"); case OutputInfo::Mode::UpdateCode: // Make sure that adding '-update-code' will permit accepting all arguments // '-c' accepts. @@ -257,16 +256,16 @@ ToolChain::constructInvocation(const CompileJobAction &job, } break; } - case OutputInfo::Mode::SingleCompile: - case OutputInfo::Mode::Immediate: { + case OutputInfo::Mode::SingleCompile: { for (const Action *A : context.InputActions) { cast(A)->getInputArg().render(context.Args, Arguments); } break; } - case OutputInfo::Mode::REPL: { - llvm_unreachable("REPL mode handled elsewhere"); - } + + case OutputInfo::Mode::Immediate: + case OutputInfo::Mode::REPL: + llvm_unreachable("REPL and immediate modes handled elsewhere"); } if (context.Args.hasArg(options::OPT_parse_stdlib)) @@ -287,19 +286,6 @@ ToolChain::constructInvocation(const CompileJobAction &job, Arguments.push_back("-module-name"); Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName)); - // Mode-specific arguments. - switch (context.OI.CompilerMode) { - case OutputInfo::Mode::StandardCompile: - case OutputInfo::Mode::SingleCompile: - case OutputInfo::Mode::UpdateCode: - break; - case OutputInfo::Mode::Immediate: - case OutputInfo::Mode::REPL: - context.Args.AddAllArgs(Arguments, options::OPT_l, options::OPT_framework, - options::OPT_L); - break; - } - const std::string &ModuleOutputPath = context.Output.getAdditionalOutputForType(types::ID::TY_SwiftModuleFile); if (!ModuleOutputPath.empty()) { @@ -363,18 +349,52 @@ ToolChain::constructInvocation(const CompileJobAction &job, if (context.Args.hasArg(options::OPT_embed_bitcode_marker)) Arguments.push_back("-embed-bitcode-marker"); - // The immediate arguments must be last. - if (context.OI.CompilerMode == OutputInfo::Mode::Immediate) - context.Args.AddLastArg(Arguments, options::OPT__DASH_DASH); - auto program = SWIFT_EXECUTABLE_NAME; if (context.OI.CompilerMode == OutputInfo::Mode::UpdateCode) program = SWIFT_UPDATE_NAME; - return std::make_pair(program, Arguments); + return {program, Arguments}; } -std::pair +ToolChain::InvocationInfo +ToolChain::constructInvocation(const InterpretJobAction &job, + const JobContext &context) const { + assert(context.OI.CompilerMode == OutputInfo::Mode::Immediate); + ArgStringList Arguments; + + Arguments.push_back("-frontend"); + Arguments.push_back("-interpret"); + + assert(context.Inputs.empty() && + "The Swift frontend does not expect to be fed any input Jobs!"); + + for (const Action *A : context.InputActions) { + cast(A)->getInputArg().render(context.Args, Arguments); + } + + if (context.Args.hasArg(options::OPT_parse_stdlib)) + Arguments.push_back("-disable-objc-attr-requires-foundation-module"); + + addCommonFrontendArgs(*this, context.OI, context.Output, context.Args, + Arguments); + + // Pass the optimization level down to the frontend. + context.Args.AddLastArg(Arguments, options::OPT_O_Group); + + context.Args.AddLastArg(Arguments, options::OPT_parse_sil); + + Arguments.push_back("-module-name"); + Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName)); + + context.Args.AddAllArgs(Arguments, options::OPT_l, options::OPT_framework); + + // The immediate arguments must be last. + context.Args.AddLastArg(Arguments, options::OPT__DASH_DASH); + + return {SWIFT_EXECUTABLE_NAME, Arguments}; +} + +ToolChain::InvocationInfo ToolChain::constructInvocation(const BackendJobAction &job, const JobContext &context) const { assert(context.Args.hasArg(options::OPT_embed_bitcode)); @@ -504,10 +524,10 @@ ToolChain::constructInvocation(const BackendJobAction &job, // Disable all llvm IR level optimizations. Arguments.push_back("-disable-llvm-optzns"); - return std::make_pair(SWIFT_EXECUTABLE_NAME, Arguments); + return {SWIFT_EXECUTABLE_NAME, Arguments}; } -std::pair +ToolChain::InvocationInfo ToolChain::constructInvocation(const MergeModuleJobAction &job, const JobContext &context) const { ArgStringList Arguments; @@ -557,10 +577,10 @@ ToolChain::constructInvocation(const MergeModuleJobAction &job, if (context.OI.CompilerMode == OutputInfo::Mode::UpdateCode) program = SWIFT_UPDATE_NAME; - return std::make_pair(program, Arguments); + return {program, Arguments}; } -std::pair +ToolChain::InvocationInfo ToolChain::constructInvocation(const ModuleWrapJobAction &job, const JobContext &context) const { ArgStringList Arguments; @@ -579,10 +599,10 @@ ToolChain::constructInvocation(const ModuleWrapJobAction &job, Arguments.push_back( context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); - return std::make_pair(SWIFT_EXECUTABLE_NAME, Arguments); + return {SWIFT_EXECUTABLE_NAME, Arguments}; } -std::pair +ToolChain::InvocationInfo ToolChain::constructInvocation(const REPLJobAction &job, const JobContext &context) const { assert(context.Inputs.empty()); @@ -612,7 +632,7 @@ ToolChain::constructInvocation(const REPLJobAction &job, FrontendArgs.insert(FrontendArgs.begin(), {"-frontend", "-repl"}); FrontendArgs.push_back("-module-name"); FrontendArgs.push_back(context.Args.MakeArgString(context.OI.ModuleName)); - return std::make_pair(SWIFT_EXECUTABLE_NAME, FrontendArgs); + return {SWIFT_EXECUTABLE_NAME, FrontendArgs}; } // Squash important frontend options into a single argument for LLDB. @@ -625,11 +645,11 @@ ToolChain::constructInvocation(const REPLJobAction &job, ArgStringList Arguments; Arguments.push_back(context.Args.MakeArgString(std::move(SingleArg))); - return std::make_pair("lldb", Arguments); + return {"lldb", Arguments}; } -std::pair +ToolChain::InvocationInfo ToolChain::constructInvocation(const GenerateDSYMJobAction &job, const JobContext &context) const { assert(context.Inputs.size() == 1); @@ -646,16 +666,16 @@ ToolChain::constructInvocation(const GenerateDSYMJobAction &job, Arguments.push_back( context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); - return std::make_pair("dsymutil", Arguments); + return {"dsymutil", Arguments}; } -std::pair +ToolChain::InvocationInfo ToolChain::constructInvocation(const AutolinkExtractJobAction &job, const JobContext &context) const { llvm_unreachable("autolink extraction not implemented for this toolchain"); } -std::pair +ToolChain::InvocationInfo ToolChain::constructInvocation(const LinkJobAction &job, const JobContext &context) const { llvm_unreachable("linking not implemented for this toolchain"); @@ -726,7 +746,71 @@ static bool findXcodeClangPath(llvm::SmallVectorImpl &path) { return !path.empty(); } -std::pair +static void addPathEnvironmentVariableIfNeeded(Job::EnvironmentVector &env, + const char *name, + const char *separator, + options::ID optionID, + const ArgList &args, + StringRef extraEntry = "") { + auto linkPathOptions = args.filtered(optionID); + if (linkPathOptions.begin() == linkPathOptions.end() && extraEntry.empty()) + return; + + std::string newPaths; + interleave(linkPathOptions, + [&](const Arg *arg) { newPaths.append(arg->getValue()); }, + [&] { newPaths.append(separator); }); + if (!extraEntry.empty()) { + if (!newPaths.empty()) + newPaths.append(separator); + newPaths.append(extraEntry.data(), extraEntry.size()); + } + if (auto currentPaths = llvm::sys::Process::GetEnv(name)) { + newPaths.append(separator); + newPaths.append(currentPaths.getValue()); + } + env.emplace_back(name, args.MakeArgString(newPaths)); +} + +/// Get the runtime library link path, which is platform-specific and found +/// relative to the compiler. +static void getRuntimeLibraryPath(SmallVectorImpl &runtimeLibPath, + const llvm::opt::ArgList &args, + const ToolChain &TC) { + // FIXME: Duplicated from CompilerInvocation, but in theory the runtime + // library link path and the standard library module import path don't + // need to be the same. + if (const Arg *A = args.getLastArg(options::OPT_resource_dir)) { + StringRef value = A->getValue(); + runtimeLibPath.append(value.begin(), value.end()); + } else { + auto programPath = TC.getDriver().getSwiftProgramPath(); + runtimeLibPath.append(programPath.begin(), programPath.end()); + llvm::sys::path::remove_filename(runtimeLibPath); // remove /swift + llvm::sys::path::remove_filename(runtimeLibPath); // remove /bin + llvm::sys::path::append(runtimeLibPath, "lib", "swift"); + } + llvm::sys::path::append(runtimeLibPath, + getPlatformNameForTriple(TC.getTriple())); +} + +ToolChain::InvocationInfo +toolchains::Darwin::constructInvocation(const InterpretJobAction &job, + const JobContext &context) const { + InvocationInfo II = ToolChain::constructInvocation(job, context); + + SmallString<128> runtimeLibraryPath; + getRuntimeLibraryPath(runtimeLibraryPath, context.Args, *this); + + addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_LIBRARY_PATH", + ":", options::OPT_L, context.Args, + runtimeLibraryPath); + addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_FRAMEWORK_PATH", + ":", options::OPT_F, context.Args); + return II; +} + +ToolChain::InvocationInfo toolchains::Darwin::constructInvocation(const LinkJobAction &job, const JobContext &context) const { assert(context.Output.getPrimaryOutputType() == types::TY_Image && @@ -841,21 +925,8 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job, // Add the runtime library link path, which is platform-specific and found // relative to the compiler. - // FIXME: Duplicated from CompilerInvocation, but in theory the runtime - // library link path and the standard library module import path don't - // need to be the same. - llvm::SmallString<128> RuntimeLibPath; - - if (const Arg *A = context.Args.getLastArg(options::OPT_resource_dir)) { - RuntimeLibPath = A->getValue(); - } else { - RuntimeLibPath = D.getSwiftProgramPath(); - llvm::sys::path::remove_filename(RuntimeLibPath); // remove /swift - llvm::sys::path::remove_filename(RuntimeLibPath); // remove /bin - llvm::sys::path::append(RuntimeLibPath, "lib", "swift"); - } - llvm::sys::path::append(RuntimeLibPath, - getPlatformNameForTriple(getTriple())); + SmallString<128> RuntimeLibPath; + getRuntimeLibraryPath(RuntimeLibPath, context.Args, *this); Arguments.push_back("-L"); Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); @@ -924,14 +995,27 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job, Arguments.push_back("-o"); Arguments.push_back(context.Output.getPrimaryOutputFilename().c_str()); - return std::make_pair("ld", Arguments); + return {"ld", Arguments}; +} + +ToolChain::InvocationInfo +toolchains::GenericUnix::constructInvocation(const InterpretJobAction &job, + const JobContext &context) const { + InvocationInfo II = ToolChain::constructInvocation(job, context); + + SmallString<128> runtimeLibraryPath; + getRuntimeLibraryPath(runtimeLibraryPath, context.Args, *this); + + addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "LD_LIBRARY_PATH", + ":", options::OPT_L, context.Args, + runtimeLibraryPath); + return II; } -#if defined(SWIFT_ENABLE_TARGET_LINUX) -std::pair -toolchains::Linux::constructInvocation(const AutolinkExtractJobAction &job, - const JobContext &context) const { +ToolChain::InvocationInfo +toolchains::GenericUnix::constructInvocation(const AutolinkExtractJobAction &job, + const JobContext &context) const { assert(context.Output.getPrimaryOutputType() == types::TY_AutolinkFile); ArgStringList Arguments; @@ -942,12 +1026,12 @@ toolchains::Linux::constructInvocation(const AutolinkExtractJobAction &job, Arguments.push_back( context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); - return std::make_pair("swift-autolink-extract", Arguments); + return {"swift-autolink-extract", Arguments}; } -std::pair -toolchains::Linux::constructInvocation(const LinkJobAction &job, - const JobContext &context) const { +ToolChain::InvocationInfo +toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, + const JobContext &context) const { const Driver &D = getDriver(); assert(context.Output.getPrimaryOutputType() == types::TY_Image && @@ -1058,16 +1142,15 @@ toolchains::Linux::constructInvocation(const LinkJobAction &job, // Add the linker script that coalesces protocol conformance sections. Arguments.push_back("-Xlinker"); Arguments.push_back("-T"); - Arguments.push_back( - context.Args.MakeArgString(Twine(RuntimeLibPath) + "/" + - getTriple().getArchName() + "/swift.ld")); + + // FIXME: This should also query the abi type (i.e. gnueabihf) + Arguments.push_back(context.Args.MakeArgString( + Twine(RuntimeLibPath) + "/" + getTriple().getArchName() + "/swift.ld")); // This should be the last option, for convenience in checking output. Arguments.push_back("-o"); Arguments.push_back(context.Output.getPrimaryOutputFilename().c_str()); - return std::make_pair("clang++", Arguments); + return {"clang++", Arguments}; } -#endif // SWIFT_ENABLE_TARGET_LINUX - diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 629ef3369c6d1..af186282c1e83 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,9 +23,10 @@ namespace toolchains { class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { protected: - std::pair - constructInvocation(const LinkJobAction &job, - const JobContext &context) const override; + InvocationInfo constructInvocation(const InterpretJobAction &job, + const JobContext &context) const override; + InvocationInfo constructInvocation(const LinkJobAction &job, + const JobContext &context) const override; std::string findProgramRelativeToSwiftImpl(StringRef name) const override; @@ -35,26 +36,23 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain { }; -#if defined(SWIFT_ENABLE_TARGET_LINUX) - -class LLVM_LIBRARY_VISIBILITY Linux : public ToolChain { +class LLVM_LIBRARY_VISIBILITY GenericUnix : public ToolChain { protected: - std::pair - constructInvocation(const AutolinkExtractJobAction &job, - const JobContext &context) const override; - std::pair - constructInvocation(const LinkJobAction &job, - const JobContext &context) const override; + InvocationInfo constructInvocation(const InterpretJobAction &job, + const JobContext &context) const override; + InvocationInfo constructInvocation(const AutolinkExtractJobAction &job, + const JobContext &context) const override; + InvocationInfo constructInvocation(const LinkJobAction &job, + const JobContext &context) const override; public: - Linux(const Driver &D, const llvm::Triple &Triple) : ToolChain(D, Triple) {} - ~Linux() = default; + GenericUnix(const Driver &D, const llvm::Triple &Triple) : ToolChain(D, Triple) {} + ~GenericUnix() = default; }; -#endif // SWIFT_ENABLE_TARGET_LINUX - } // end namespace toolchains } // end namespace driver } // end namespace swift #endif + diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp index 03e737cc903e9..84d8a1b14a68c 100644 --- a/lib/Driver/Types.cpp +++ b/lib/Driver/Types.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index e38a09b2eeda3..49dd5d6e4916b 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1,8 +1,8 @@ -//===-- CompilerInvocation.cpp - CompilerInvocation methods ---------------===// +//===--- CompilerInvocation.cpp - CompilerInvocation methods --------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -124,6 +124,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.PrintStats |= Args.hasArg(OPT_print_stats); Opts.PrintClangStats |= Args.hasArg(OPT_print_clang_stats); Opts.DebugTimeFunctionBodies |= Args.hasArg(OPT_debug_time_function_bodies); + Opts.DebugTimeCompilation |= Args.hasArg(OPT_debug_time_compilation); Opts.PlaygroundTransform |= Args.hasArg(OPT_playground); if (Args.hasArg(OPT_disable_playground_transform)) @@ -808,12 +809,9 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts, }); } - Opts.InferImplicitProperties |= - Args.hasArg(OPT_enable_objc_implicit_properties); - Opts.OmitNeedlessWords |= Args.hasArg(OPT_enable_omit_needless_words); Opts.InferDefaultArguments |= Args.hasArg(OPT_enable_infer_default_arguments); - + Opts.UseSwiftLookupTables |= Args.hasArg(OPT_enable_swift_name_lookup_tables); Opts.DumpClangDiagnostics |= Args.hasArg(OPT_dump_clang_diagnostics); if (Args.hasArg(OPT_embed_bitcode)) @@ -1002,6 +1000,10 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args, Opts.GenerateProfile |= Args.hasArg(OPT_profile_generate); Opts.EmitProfileCoverageMapping |= Args.hasArg(OPT_profile_coverage_mapping); + Opts.UseNativeSuperMethod |= + Args.hasArg(OPT_use_native_super_method); + Opts.EnableGuaranteedClosureContexts |= + Args.hasArg(OPT_enable_guaranteed_closure_contexts); return false; } diff --git a/lib/Frontend/DiagnosticVerifier.cpp b/lib/Frontend/DiagnosticVerifier.cpp index 806530ff4b818..4c7155fe5f024 100644 --- a/lib/Frontend/DiagnosticVerifier.cpp +++ b/lib/Frontend/DiagnosticVerifier.cpp @@ -1,8 +1,8 @@ -//===- DiagnosticVerifier.cpp - Diagnostic Verifier (-verify) -------------===// +//===--- DiagnosticVerifier.cpp - Diagnostic Verifier (-verify) -----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -39,6 +39,10 @@ namespace { // This is true if a '*' constraint is present to say that the diagnostic // may appear (or not) an uncounted number of times. bool mayAppear = false; + + // This is true if a '{{none}}' is present to mark that there should be no + // fixits at all. + bool noFixitsMayAppear = false; // This is the raw input buffer for the message text, the part in the // {{...}} @@ -358,6 +362,12 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID, // Prepare for the next round of checks. ExtraChecks = ExtraChecks.substr(EndLoc+2).ltrim(); + // Special case for specifying no fixits should appear. + if (FixItStr == "none") { + Expected.noFixitsMayAppear = true; + continue; + } + // Parse the pieces of the fix-it. size_t MinusLoc = FixItStr.find('-'); if (MinusLoc == StringRef::npos) { @@ -467,20 +477,17 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID, llvm::SMFixIt fix(llvm::SMRange(replStartLoc, replEndLoc), actual); addError(IncorrectFixit, "expected fix-it not seen; actual fix-its: " + actual, fix); -#if 0 // TODO: There are still some bugs with this, and we don't have a - // policy of requiring a fixit specification on tests. - } else if (expected.Fixits.empty() && + } else if (expected.noFixitsMayAppear && !FoundDiagnostic.getFixIts().empty() && - !expected.mayAppear && - false) { + !expected.mayAppear) { // If there was no fixit specification, but some were produced, add a // fixit to add them in. auto actual = renderFixits(FoundDiagnostic.getFixIts(), InputFile); - - llvm::SMFixIt fix(SMLoc::getFromPointer(expected.ExpectedEnd), - " " + actual); - addError(expected.ExpectedEnd, "expected fix-it not specified", fix); -#endif + auto replStartLoc = SMLoc::getFromPointer(expected.ExpectedEnd - 8); // {{none}} length + auto replEndLoc = SMLoc::getFromPointer(expected.ExpectedEnd - 1); + + llvm::SMFixIt fix(llvm::SMRange(replStartLoc, replEndLoc), actual); + addError(replStartLoc.getPointer(), "expected no fix-its; actual fix-it seen: " + actual, fix); } // Actually remove the diagnostic from the list, so we don't match it @@ -617,7 +624,7 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID, /// file and drop it back in place. void DiagnosticVerifier::autoApplyFixes(unsigned BufferID, ArrayRef diags) { - // Walk the list of diagnostics, pulling out any fixits into a array of just + // Walk the list of diagnostics, pulling out any fixits into an array of just // them. SmallVector FixIts; for (auto &diag : diags) diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 66a7a0e3bb966..875c4f06fba25 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -1,8 +1,8 @@ -//===-- Frontend.cpp - frontend utility methods ---------------------------===// +//===--- Frontend.cpp - frontend utility methods --------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp index 73e80ab4f55d2..c6bf4586a5f94 100644 --- a/lib/Frontend/FrontendOptions.cpp +++ b/lib/Frontend/FrontendOptions.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Frontend/PrintingDiagnosticConsumer.cpp b/lib/Frontend/PrintingDiagnosticConsumer.cpp index 9e9e71f2e80d3..f60e964b46417 100644 --- a/lib/Frontend/PrintingDiagnosticConsumer.cpp +++ b/lib/Frontend/PrintingDiagnosticConsumer.cpp @@ -1,8 +1,8 @@ -//===- PrintingDiagnosticConsumer.cpp - Print Text Diagnostics ------------===// +//===--- PrintingDiagnosticConsumer.cpp - Print Text Diagnostics ----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Frontend/SerializedDiagnosticConsumer.cpp b/lib/Frontend/SerializedDiagnosticConsumer.cpp index c7348fb874f3a..7ca9d3549f472 100644 --- a/lib/Frontend/SerializedDiagnosticConsumer.cpp +++ b/lib/Frontend/SerializedDiagnosticConsumer.cpp @@ -1,8 +1,8 @@ -//===- SerializedDiagnosticConsumer.cpp - Serialize Diagnostics --*- C++ -*-===// +//===- SerializedDiagnosticConsumer.cpp - Serialize Diagnostics -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -39,7 +39,7 @@ using namespace swift; enum BlockIDs { /// \brief A top-level block which represents any meta data associated - /// with the diagostics, including versioning of the format. + /// with the diagnostics, including versioning of the format. BLOCK_META = llvm::bitc::FIRST_APPLICATION_BLOCKID, /// \brief The this block acts as a container for all the information @@ -382,7 +382,7 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Diagnostc text. Abbrevs.set(RECORD_DIAG, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev)); - // Emit abbrevation for RECORD_CATEGORY. + // Emit abbreviation for RECORD_CATEGORY. Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(RECORD_CATEGORY)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Category ID. @@ -390,7 +390,7 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Category text. Abbrevs.set(RECORD_CATEGORY, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev)); - // Emit abbrevation for RECORD_SOURCE_RANGE. + // Emit abbreviation for RECORD_SOURCE_RANGE. Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(RECORD_SOURCE_RANGE)); addRangeLocationAbbrev(Abbrev); @@ -411,7 +411,7 @@ void SerializedDiagnosticConsumer::emitBlockInfoBlock() { Abbrev->Add(BitCodeAbbrevOp(RECORD_FILENAME)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped file ID. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Size. - Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Modifcation time. + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Modification time. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size. Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name text. Abbrevs.set(RECORD_FILENAME, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index f0ec00051b39e..f3193815c19b1 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -1,8 +1,8 @@ -//===- CodeCompletion.cpp - Code completion implementation ----------------===// +//===--- CodeCompletion.cpp - Code completion implementation --------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -65,7 +65,7 @@ CodeCompletionCommandKind getCommandKind(StringRef Command) { return CodeCompletionCommandKind::none; } -StringRef getCommnadName(CodeCompletionCommandKind Kind) { +StringRef getCommandName(CodeCompletionCommandKind Kind) { #define CHECK_CASE(KIND) \ if (CodeCompletionCommandKind::KIND == Kind) { \ static std::string Name(#KIND); \ @@ -75,7 +75,7 @@ StringRef getCommnadName(CodeCompletionCommandKind Kind) { CHECK_CASE(recommended) CHECK_CASE(recommendedover) #undef CHECK_CASE - llvm_unreachable("Can not handle this Kind."); + llvm_unreachable("Cannot handle this Kind."); } bool containsInterestedWords(StringRef Content, StringRef Splitter, @@ -179,7 +179,7 @@ class ClangCommentExtractor : public ConstCommentVisitor auto Text = TC->getText(); std::vector Subs; splitTextByComma(Text, Subs); - auto Kind = getCommnadName(CommandKind); + auto Kind = getCommandName(CommandKind); for (auto S : Subs) Words.push_back(std::make_pair(Kind, S)); } else @@ -223,7 +223,7 @@ class SwiftDocWordExtractor : public MarkupASTWalker { void visitText(const Text *Text) override { if (Kind == CodeCompletionCommandKind::none) return; - StringRef CommandName = getCommnadName(Kind); + StringRef CommandName = getCommandName(Kind); std::vector Subs; splitTextByComma(Text->str(), Subs); for (auto S : Subs) @@ -326,7 +326,7 @@ static Stmt *findNearestStmt(const AbstractFunctionDecl *AFD, SourceLoc Loc, auto &SM = AFD->getASTContext().SourceMgr; assert(SM.rangeContainsTokenLoc(AFD->getSourceRange(), Loc)); StmtFinder Finder(SM, Loc, Kind); - // FIXME(thread-safety): the walker is is mutating the AST. + // FIXME(thread-safety): the walker is mutating the AST. const_cast(AFD)->walk(Finder); return Finder.getFoundStmt(); } @@ -1326,6 +1326,7 @@ static bool isTopLevelContext(const DeclContext *DC) { case DeclContextKind::TopLevelCodeDecl: return true; case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: return false; default: continue; @@ -1584,7 +1585,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { void addImportModuleNames() { // FIXME: Add user-defined swift modules SmallVector Modules; - Ctx.getVisibleTopLevelClangeModules(Modules); + Ctx.getVisibleTopLevelClangModules(Modules); std::sort(Modules.begin(), Modules.end(), [](clang::Module* LHS , clang::Module* RHS) { return LHS->getTopLevelModuleName().compare_lower( @@ -1769,7 +1770,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { assert(VD->isStatic() || !(InsideStaticMethod && VD->getDeclContext() == CurrentMethod->getDeclContext()) && - "name lookup bug -- can not see an instance variable " + "name lookup bug -- cannot see an instance variable " "in a static function"); CommandWordsPairs Pairs; @@ -1796,31 +1797,21 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { addTypeAnnotation(Builder, VarType); } - void addPatternParameters(CodeCompletionResultBuilder &Builder, - const Pattern *P) { - if (auto *TP = dyn_cast(P)) { - bool NeedComma = false; - for (unsigned i = 0, end = TP->getNumElements(); i < end; ++i) { - TuplePatternElt TupleElt = TP->getElement(i); - if (NeedComma) - Builder.addComma(); - NeedComma = true; + void addParameters(CodeCompletionResultBuilder &Builder, + const ParameterList *params) { + bool NeedComma = false; + for (auto ¶m : *params) { + if (NeedComma) + Builder.addComma(); + NeedComma = true; - bool HasEllipsis = TupleElt.hasEllipsis(); - Type EltT = TupleElt.getPattern()->getType(); - if (HasEllipsis) - EltT = TupleTypeElt::getVarargBaseTy(EltT); + Type type = param->getType(); + if (param->isVariadic()) + type = ParamDecl::getVarargBaseTy(type); - Builder.addCallParameter(TupleElt.getPattern()->getBoundName(), - EltT, HasEllipsis); - } - return; + Builder.addCallParameter(param->getArgumentName(), type, + param->isVariadic()); } - - Type PType = P->getType(); - if (auto Parens = dyn_cast(PType.getPointer())) - PType = Parens->getUnderlyingType(); - Builder.addCallParameter(P->getBoundName(), PType, /*IsVarArg*/false); } void addPatternFromTypeImpl(CodeCompletionResultBuilder &Builder, Type T, @@ -1894,17 +1885,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { const AbstractFunctionDecl *AFD, bool includeDefaultArgs = true) { - const TuplePattern *BodyTuple = nullptr; - if (AFD) { - auto BodyPatterns = AFD->getBodyParamPatterns(); - // Skip over the implicit 'self'. - if (AFD->getImplicitSelfDecl()) { - BodyPatterns = BodyPatterns.slice(1); - } - - if (!BodyPatterns.empty()) - BodyTuple = dyn_cast(BodyPatterns.front()); - } + const ParameterList *BodyParams = nullptr; + if (AFD) + BodyParams = AFD->getParameterList(AFD->getImplicitSelfDecl() ? 1 : 0); bool modifiedBuilder = false; @@ -1921,6 +1904,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { case DefaultArgumentKind::Normal: case DefaultArgumentKind::Inherited: + case DefaultArgumentKind::Nil: + case DefaultArgumentKind::EmptyArray: + case DefaultArgumentKind::EmptyDictionary: if (includeDefaultArgs) break; continue; @@ -1941,11 +1927,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { if (NeedComma) Builder.addComma(); - if (BodyTuple) { + if (BodyParams) { // If we have a local name for the parameter, pass in that as well. - auto ParamPat = BodyTuple->getElement(i).getPattern(); - Builder.addCallParameter(Name, ParamPat->getBodyName(), ParamType, - TupleElt.isVararg()); + auto name = BodyParams->get(i)->getName(); + Builder.addCallParameter(Name, name, ParamType, TupleElt.isVararg()); } else { Builder.addCallParameter(Name, ParamType, TupleElt.isVararg()); } @@ -1961,9 +1946,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } modifiedBuilder = true; - if (BodyTuple) { - auto ParamPat = BodyTuple->getElement(0).getPattern(); - Builder.addCallParameter(Identifier(), ParamPat->getBodyName(), T, + if (BodyParams) { + auto name = BodyParams->get(0)->getName(); + Builder.addCallParameter(Identifier(), name, T, /*IsVarArg*/false); } else Builder.addCallParameter(Identifier(), T, /*IsVarArg*/false); @@ -2057,7 +2042,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { case LookupKind::EnumElement: case LookupKind::Type: case LookupKind::TypeInDeclContext: - llvm_unreachable("can not have a method call while doing a " + llvm_unreachable("cannot have a method call while doing a " "type completion"); case LookupKind::ImportFromModule: IsImplicitlyCurriedInstanceMethod = false; @@ -2122,7 +2107,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { // Build type annotation. { llvm::raw_svector_ostream OS(TypeStr); - for (unsigned i = FirstIndex + 1, e = FD->getBodyParamPatterns().size(); + for (unsigned i = FirstIndex + 1, e = FD->getParameterLists().size(); i != e; ++i) { ResultType->castTo()->getInput()->print(OS); ResultType = ResultType->castTo()->getResult(); @@ -2245,7 +2230,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } void addSubscriptCall(const SubscriptDecl *SD, DeclVisibilityKind Reason) { - assert(!HaveDot && "can not add a subscript after a dot"); + assert(!HaveDot && "cannot add a subscript after a dot"); CommandWordsPairs Pairs; CodeCompletionResultBuilder Builder( Sink, @@ -2254,7 +2239,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { Builder.setAssociatedDecl(SD); setClangDeclKeywords(SD, Pairs, Builder); Builder.addLeftBracket(); - addPatternParameters(Builder, SD->getIndices()); + addParameters(Builder, SD->getIndices()); Builder.addRightBracket(); // Add a type annotation. @@ -2436,7 +2421,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { if (HaveDot) return; - // If instance type is type alias, showing users that the contructed + // If instance type is type alias, showing users that the constructed // type is the typealias instead of the underlying type of the alias. Optional Result = None; if (auto AT = MT->getInstanceType()) { @@ -2463,11 +2448,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } if (auto *FD = dyn_cast(D)) { - // We can not call operators with a postfix parenthesis syntax. + // We cannot call operators with a postfix parenthesis syntax. if (FD->isBinaryOperator() || FD->isUnaryOperator()) return; - // We can not call accessors. We use VarDecls and SubscriptDecls to + // We cannot call accessors. We use VarDecls and SubscriptDecls to // produce completions that refer to getters and setters. if (FD->isAccessor()) return; @@ -2525,11 +2510,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } if (auto *FD = dyn_cast(D)) { - // We can not call operators with a postfix parenthesis syntax. + // We cannot call operators with a postfix parenthesis syntax. if (FD->isBinaryOperator() || FD->isUnaryOperator()) return; - // We can not call accessors. We use VarDecls and SubscriptDecls to + // We cannot call accessors. We use VarDecls and SubscriptDecls to // produce completions that refer to getters and setters. if (FD->isAccessor()) return; @@ -2798,7 +2783,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { CodeCompletionResultBuilder builder( Sink, CodeCompletionResult::ResultKind::Pattern, SemanticContextKind::None, {}); - // FIXME: we can't use the exclaimation mark chunk kind, or it isn't + // FIXME: we can't use the exclamation mark chunk kind, or it isn't // included in the completion name. builder.addTextChunk("!"); assert(resultType); @@ -3265,10 +3250,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } } - static void collectArgumentExpection(unsigned Position, bool HasName, - ArrayRef Types, SourceLoc Loc, - std::vector &ExpectedTypes, - std::vector &ExpectedNames) { + static void collectArgumentExpectation(unsigned Position, bool HasName, + ArrayRef Types, SourceLoc Loc, + std::vector &ExpectedTypes, + std::vector &ExpectedNames) { SmallPtrSet seenTypes; SmallPtrSet seenNames; @@ -3298,8 +3283,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { ArrayRef Types, SourceLoc Loc) { std::vector ExpectedTypes; std::vector ExpectedNames; - collectArgumentExpection(Position, HasName, Types, Loc, ExpectedTypes, - ExpectedNames); + collectArgumentExpectation(Position, HasName, Types, Loc, ExpectedTypes, + ExpectedNames); addArgNameCompletionResults(ExpectedNames); if (!ExpectedTypes.empty()) { setExpectedTypes(ExpectedTypes); @@ -3311,7 +3296,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { static bool isPotentialSignatureMatch(ArrayRef TupleEles, ArrayRef ExprTypes, DeclContext *DC) { - // Not likely to be a mactch if users provide more arguments than expected. + // Not likely to be a match if users provide more arguments than expected. if (ExprTypes.size() >= TupleEles.size()) return false; for (unsigned I = 0; I < ExprTypes.size(); ++ I) { @@ -3376,16 +3361,16 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } static bool - collectArgumentExpectatation(DeclContext &DC, CallExpr *CallE, Expr *CCExpr, - std::vector &ExpectedTypes, - std::vector &ExpectedNames) { + collectArgumentExpectation(DeclContext &DC, CallExpr *CallE, Expr *CCExpr, + std::vector &ExpectedTypes, + std::vector &ExpectedNames) { SmallVector PossibleTypes; unsigned Position; bool HasName; if (collectPossibleArgTypes(DC, CallE, CCExpr, PossibleTypes, Position, HasName, true)) { - collectArgumentExpection(Position, HasName, PossibleTypes, - CCExpr->getStartLoc(), ExpectedTypes, ExpectedNames); + collectArgumentExpectation(Position, HasName, PossibleTypes, + CCExpr->getStartLoc(), ExpectedTypes, ExpectedNames); return !ExpectedTypes.empty() || !ExpectedNames.empty(); } return false; @@ -3458,7 +3443,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } std::string Description = TargetName.str() + " Attribute"; #define DECL_ATTR(KEYWORD, NAME, ...) \ - if (!DeclAttribute::isUserInaccessible(DAK_##NAME) && \ + if (!StringRef(#KEYWORD).startswith("_") && \ + !DeclAttribute::isUserInaccessible(DAK_##NAME) && \ !DeclAttribute::isDeclModifier(DAK_##NAME) && \ !DeclAttribute::shouldBeRejectedByParser(DAK_##NAME) && \ (!DeclAttribute::isSilOnly(DAK_##NAME) || IsInSil)) { \ @@ -3669,7 +3655,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer { if (FD->isBinaryOperator() || FD->isUnaryOperator()) return; - // We can not override individual accessors. + // We cannot override individual accessors. if (FD->isAccessor()) return; @@ -4186,6 +4172,7 @@ class CodeCompletionTypeContextAnalyzer { switch (S->getKind()) { case StmtKind::Return: case StmtKind::ForEach: + case StmtKind::RepeatWhile: return true; default: return false; @@ -4207,7 +4194,7 @@ class CodeCompletionTypeContextAnalyzer { case ExprKind::Call: { std::vector PotentialTypes; std::vector ExpectedNames; - CompletionLookup::collectArgumentExpectatation( + CompletionLookup::collectArgumentExpectation( *DC, cast(Parent), ParsedExpr, PotentialTypes, ExpectedNames); for (Type Ty : PotentialTypes) @@ -4249,6 +4236,15 @@ class CodeCompletionTypeContextAnalyzer { } break; } + case StmtKind::RepeatWhile: { + auto Cond = cast(Parent)->getCond(); + if (Cond && + SM.rangeContains(Cond->getSourceRange(), + ParsedExpr->getSourceRange())) { + Callback(Context.getBoolDecl()->getDeclaredType()); + } + break; + } default: llvm_unreachable("Unhandled statement kinds."); } @@ -4433,7 +4429,7 @@ void CodeCompletionCallbacksImpl::doneParsing() { Lookup.setHaveRParen(HasRParen); Lookup.getValueExprCompletions(*ExprType); } else { - // Add argument labels, then fallthough to get values. + // Add argument labels, then fallthrough to get values. Lookup.addArgNameCompletionResults(PossibleNames); } } diff --git a/lib/IDE/CodeCompletionResultBuilder.h b/lib/IDE/CodeCompletionResultBuilder.h index b69793288a638..9b76dc1bfe3ae 100644 --- a/lib/IDE/CodeCompletionResultBuilder.h +++ b/lib/IDE/CodeCompletionResultBuilder.h @@ -1,8 +1,8 @@ -//===- CodeCompletionResultBuilder.h - Bulid completion results -----------===// +//===--- CodeCompletionResultBuilder.h - Build completion results ---------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -267,7 +267,7 @@ class CodeCompletionResultBuilder { void addSimpleNamedParameter(StringRef name) { CurrentNestingLevel++; addSimpleChunk(CodeCompletionString::Chunk::ChunkKind::CallParameterBegin); - // Use internal, since we don't want the name to be outisde the placeholder. + // Use internal, since we don't want the name to be outside the placeholder. addChunkWithText( CodeCompletionString::Chunk::ChunkKind::CallParameterInternalName, name); @@ -293,7 +293,7 @@ class CodeCompletionResultBuilder { if (!Name.empty()) { StringRef NameStr = Name.str(); - // 'self' is a keyword, we can not allow to insert it into the source + // 'self' is a keyword, we cannot allow to insert it into the source // buffer. bool IsAnnotation = (NameStr == "self"); diff --git a/lib/IDE/CommentConversion.cpp b/lib/IDE/CommentConversion.cpp index bcc7b595e937b..6004662eb9a2f 100644 --- a/lib/IDE/CommentConversion.cpp +++ b/lib/IDE/CommentConversion.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -100,7 +100,9 @@ struct CommentToXMLConverter { } void printCodeBlock(const CodeBlock *CB) { - OS << ""; + OS << "getLanguage()); + OS << "\">"; SmallVector CodeLines; CB->getLiteralContent().split(CodeLines, "\n"); for (auto Line : CodeLines) { diff --git a/lib/IDE/ModuleInterfacePrinting.cpp b/lib/IDE/ModuleInterfacePrinting.cpp index b11ac0fe62c30..ad764c54579cb 100644 --- a/lib/IDE/ModuleInterfacePrinting.cpp +++ b/lib/IDE/ModuleInterfacePrinting.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -472,7 +472,7 @@ void swift::ide::printSwiftSourceInterface(SourceFile &File, ASTPrinter &Printer, const PrintOptions &Options) { - // We print all comments before the fist line of Swift code. + // We print all comments before the first line of Swift code. printUntilFirstDeclStarts(File, Printer); File.print(Printer, Options); } @@ -493,8 +493,12 @@ void swift::ide::printHeaderInterface( }; SmallVector ClangDecls; + llvm::SmallPtrSet SeenDecls; auto headerReceiver = [&](Decl *D) { - ClangDecls.push_back(D); + if (SeenDecls.count(D) == 0) { + SeenDecls.insert(D); + ClangDecls.push_back(D); + } }; Importer.lookupDeclsFromHeader(Filename, headerFilter, headerReceiver); diff --git a/lib/IDE/REPLCodeCompletion.cpp b/lib/IDE/REPLCodeCompletion.cpp index 4419c16a66c6a..73ce0339b8c89 100644 --- a/lib/IDE/REPLCodeCompletion.cpp +++ b/lib/IDE/REPLCodeCompletion.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -178,7 +178,7 @@ REPLCompletions::REPLCompletions() // Create a CodeCompletionConsumer. Consumer.reset(new REPLCodeCompletionConsumer(*this)); - // Cerate a factory for code completion callbacks that will feed the + // Create a factory for code completion callbacks that will feed the // Consumer. CompletionCallbacksFactory.reset( ide::makeCodeCompletionCallbacksFactory(CompletionContext, diff --git a/lib/IDE/SourceEntityWalker.cpp b/lib/IDE/SourceEntityWalker.cpp index 0a1b20d37e6ba..2816958c1a4d2 100644 --- a/lib/IDE/SourceEntityWalker.cpp +++ b/lib/IDE/SourceEntityWalker.cpp @@ -1,8 +1,8 @@ -//===- SourceEntityWalker.cpp - Routines for semantic source info ---------===// +//===--- SourceEntityWalker.cpp - Routines for semantic source info -------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -460,7 +460,7 @@ bool SourceEntityWalker::visitSubscriptReference(ValueDecl *D, CharSourceRange Range, bool IsOpenBracket) { // Most of the clients treat subscript reference the same way as a - // regular reference when called on the open open bracket and + // regular reference when called on the open bracket and // ignore the closing one. return IsOpenBracket ? visitDeclReference(D, Range, nullptr, Type()) : true; } diff --git a/lib/IDE/SyntaxModel.cpp b/lib/IDE/SyntaxModel.cpp index 065ef03d6c759..ad4845b06a269 100644 --- a/lib/IDE/SyntaxModel.cpp +++ b/lib/IDE/SyntaxModel.cpp @@ -1,8 +1,8 @@ -//===- SyntaxModel.cpp - Routines for IDE syntax model --------------------===// +//===--- SyntaxModel.cpp - Routines for IDE syntax model ------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -48,6 +48,7 @@ struct SyntaxModelContext::Implementation { SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile) : Impl(*new Implementation(SrcFile)) { + const bool IsPlayground = Impl.LangOpts.Playground; const SourceManager &SM = Impl.SrcMgr; std::vector Tokens = swift::tokenize(Impl.LangOpts, SM, *Impl.SrcFile.getBufferID(), @@ -111,7 +112,8 @@ SyntaxModelContext::SyntaxModelContext(SourceFile &SrcFile) case tok::floating_literal: Kind = SyntaxNodeKind::Floating; break; case tok::string_literal: Kind = SyntaxNodeKind::String; break; case tok::comment: - if (Tok.getText().startswith("///")) + if (Tok.getText().startswith("///") || + (IsPlayground && Tok.getText().startswith("//:"))) Kind = SyntaxNodeKind::DocCommentLine; else if (Tok.getText().startswith("/**")) Kind = SyntaxNodeKind::DocCommentBlock; @@ -666,7 +668,7 @@ std::pair ModelASTWalker::walkToStmtPre(Stmt *S) { TokLen = 7; // '#elseif' if (!passNonTokenNode({SyntaxNodeKind::BuildConfigKeyword, CharSourceRange(Clause.Loc, TokLen) })) - return { false, nullptr }; + return { false, nullptr }; if (Clause.Cond && !annotateIfConfigConditionIdentifiers(Clause.Cond)) return { false, nullptr }; @@ -1291,10 +1293,7 @@ bool ModelASTWalker::processComment(CharSourceRange Range) { bool ModelASTWalker::findUrlStartingLoc(StringRef Text, unsigned &Start, std::regex &Regex) { -#ifndef SWIFT_HAVE_WORKING_STD_REGEX - return false; -#endif - +#ifdef SWIFT_HAVE_WORKING_STD_REGEX static const auto MailToPosition = std::find(URLProtocols.begin(), URLProtocols.end(), "mailto"); @@ -1318,6 +1317,7 @@ bool ModelASTWalker::findUrlStartingLoc(StringRef Text, return true; } } +#endif return false; } @@ -1354,10 +1354,8 @@ bool ModelASTWalker::searchForURL(CharSourceRange Range) { Optional ModelASTWalker::parseFieldNode(StringRef Text, StringRef OrigText, SourceLoc OrigLoc) { -#ifndef SWIFT_HAVE_WORKING_STD_REGEX - return None; -#endif - + Optional Node; +#ifdef SWIFT_HAVE_WORKING_STD_REGEX std::match_results Matches; for (unsigned i = 0; i != 3; ++i) { auto &Rx = getDocCommentRegex(i); @@ -1372,7 +1370,9 @@ Optional ModelASTWalker::parseFieldNode(StringRef Text, StringRef MatchStr(Match.first, Match.second - Match.first); auto Loc = OrigLoc.getAdvancedLoc(MatchStr.data() - OrigText.data()); CharSourceRange Range(Loc, MatchStr.size()); - return Optional({ SyntaxNodeKind::DocCommentField, Range }); + Node = Optional({ SyntaxNodeKind::DocCommentField, Range }); +#endif + return Node; } bool ModelASTWalker::findFieldsInDocCommentLine(SyntaxNode Node) { diff --git a/lib/IDE/Utils.cpp b/lib/IDE/Utils.cpp index cd1970f35c7ff..ce1e32d2aa596 100644 --- a/lib/IDE/Utils.cpp +++ b/lib/IDE/Utils.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -119,7 +119,7 @@ ide::isSourceInputComplete(std::unique_ptr MemBuf) { const char *SourceStart = Buffer.data(); const char *SourceEnd = Buffer.data() + Buffer.size(); const char *LineStart = SourceStart; - const char *LineSourceStart = NULL; + const char *LineSourceStart = nullptr; uint32_t LineIndent = 0; struct IndentInfo { StringRef Prefix; @@ -134,7 +134,7 @@ ide::isSourceInputComplete(std::unique_ptr MemBuf) { case '\r': case '\n': LineIndent = 0; - LineSourceStart = NULL; + LineSourceStart = nullptr; LineStart = p + 1; break; @@ -146,7 +146,7 @@ ide::isSourceInputComplete(std::unique_ptr MemBuf) { case '(': case '[': ++LineIndent; - if (LineSourceStart == NULL) + if (LineSourceStart == nullptr) IndentInfos.push_back(IndentInfo(LineStart, p - LineStart, LineIndent)); @@ -166,7 +166,7 @@ ide::isSourceInputComplete(std::unique_ptr MemBuf) { break; default: - if (LineSourceStart == NULL && !isspace(*p)) + if (LineSourceStart == nullptr && !isspace(*p)) LineSourceStart = p; break; } @@ -174,7 +174,7 @@ ide::isSourceInputComplete(std::unique_ptr MemBuf) { break; } if (!IndentInfos.empty()) { - SCR.IndentPrefix = std::move(IndentInfos.back().Prefix.str()); + SCR.IndentPrefix = IndentInfos.back().Prefix.str(); // Trim off anything that follows a non-space character const size_t pos = SCR.IndentPrefix.find_first_not_of(" \t"); if (pos != std::string::npos) @@ -189,7 +189,7 @@ SourceCompleteResult ide::isSourceInputComplete(StringRef Text) { } // Adjust the cc1 triple string we got from clang, to make sure it will be -// accepted when it goes throught the swift clang importer. +// accepted when it goes through the swift clang importer. static std::string adjustClangTriple(StringRef TripleStr) { std::string Result; llvm::raw_string_ostream OS(Result); diff --git a/lib/IRGen/Address.h b/lib/IRGen/Address.h index d7596ae2e063f..a8daaf98b4d01 100644 --- a/lib/IRGen/Address.h +++ b/lib/IRGen/Address.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -91,7 +91,7 @@ class ContainedAddress { /// The address of an object of type T. Address Addr; - /// The address of an object of [local_storage] T. + /// The container of the address. Address Container; public: diff --git a/lib/IRGen/CMakeLists.txt b/lib/IRGen/CMakeLists.txt index 5c20f2dcb147e..587d93c8fdfab 100644 --- a/lib/IRGen/CMakeLists.txt +++ b/lib/IRGen/CMakeLists.txt @@ -2,6 +2,7 @@ add_swift_library(swiftIRGen DebugTypeInfo.cpp EnumPayload.cpp ExtraInhabitants.cpp + Fulfillment.cpp GenArchetype.cpp GenCast.cpp GenClangDecl.cpp @@ -29,6 +30,7 @@ add_swift_library(swiftIRGen IRGenModule.cpp IRGenSIL.cpp Linking.cpp + LocalTypeData.cpp SwiftTargetInfo.cpp StructLayout.cpp TypeLayoutVerifier.cpp diff --git a/lib/IRGen/CallEmission.h b/lib/IRGen/CallEmission.h index 19235618d9dc6..b5facbcb9fbe9 100644 --- a/lib/IRGen/CallEmission.h +++ b/lib/IRGen/CallEmission.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/Callee.h b/lib/IRGen/Callee.h index 80ed4fc85e8ba..c5264d9380c4c 100644 --- a/lib/IRGen/Callee.h +++ b/lib/IRGen/Callee.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/CallingConvention.h b/lib/IRGen/CallingConvention.h index 44d3b17c6a2b6..1d67de03bd804 100644 --- a/lib/IRGen/CallingConvention.h +++ b/lib/IRGen/CallingConvention.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// // // This file declares the interfaces for working with abstract and -// phsyical calling conventions. +// physical calling conventions. // //===----------------------------------------------------------------------===// diff --git a/lib/IRGen/ClassMetadataLayout.h b/lib/IRGen/ClassMetadataLayout.h index 073f88ed83eb4..2c97360fab929 100644 --- a/lib/IRGen/ClassMetadataLayout.h +++ b/lib/IRGen/ClassMetadataLayout.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -84,7 +84,13 @@ template class ClassMetadataLayout : public MetadataLayout { // consistent metadata layout between generic superclasses and concrete // subclasses. if (Type superclass = theClass->getSuperclass()) { - addClassMembers(superclass->getClassOrBoundGenericClass()); + ClassDecl *superclassDecl = superclass->getClassOrBoundGenericClass(); + // Skip superclass fields if superclass is resilient. + // FIXME: Needs runtime support to ensure the field offset vector is + // populated correctly. + if (!IGM.isResilient(superclassDecl, ResilienceScope::Component)) { + addClassMembers(superclass->getClassOrBoundGenericClass()); + } } // Add a reference to the parent class, if applicable. @@ -212,7 +218,7 @@ template class ClassMetadataLayout : public MetadataLayout { unsigned uncurryLevel) { SILDeclRef declRef(fn, kind, explosionLevel, uncurryLevel); // If the method overrides something, we don't need a new entry. - if (declRef.getOverriddenVTableEntry()) + if (declRef.getNextOverriddenVTableEntry()) return; // Both static and non-static functions go in the metadata. diff --git a/lib/IRGen/DebugTypeInfo.cpp b/lib/IRGen/DebugTypeInfo.cpp index 0bbbd95cb4c98..427762cec7dd8 100644 --- a/lib/IRGen/DebugTypeInfo.cpp +++ b/lib/IRGen/DebugTypeInfo.cpp @@ -1,8 +1,8 @@ -//===--- DebugTypeInfo.h - Type Info for Debugging --------------*- C++ -*-===// +//===--- DebugTypeInfo.cpp - Type Info for Debugging ------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/DebugTypeInfo.h b/lib/IRGen/DebugTypeInfo.h index 75c12f9509620..5f2da58c69c1f 100644 --- a/lib/IRGen/DebugTypeInfo.h +++ b/lib/IRGen/DebugTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,93 +18,103 @@ #ifndef SWIFT_IRGEN_DEBUGTYPEINFO_H #define SWIFT_IRGEN_DEBUGTYPEINFO_H -#include "swift/AST/Types.h" -#include "swift/AST/Decl.h" #include "IRGen.h" +#include "swift/AST/Decl.h" +#include "swift/AST/Types.h" namespace llvm { - class Type; +class Type; } namespace swift { - class SILDebugScope; - - namespace irgen { - class TypeInfo; - - /// This data structure holds everything needed to emit debug info - /// for a type. - class DebugTypeInfo { - public: - /// The Decl holds the DeclContext, location, but also allows to - /// look up struct members. If there is no Decl, generic types - /// mandate there be at least a DeclContext. - PointerUnion DeclOrContext; - /// The type we need to emit may be different from the type - /// mentioned in the Decl, for example, stripped of qualifiers. - TypeBase *Type; - /// Needed to determine the size of basic types and to determine - /// the storage type for undefined variables. - llvm::Type *StorageType; - Size size; - Alignment align; - - DebugTypeInfo() - : Type(nullptr), StorageType(nullptr), size(0), align(1) {} - DebugTypeInfo(swift::Type Ty, llvm::Type *StorageTy, - uint64_t SizeInBytes, uint32_t AlignInBytes, - DeclContext *DC); - DebugTypeInfo(swift::Type Ty, llvm::Type *StorageTy, - Size size, Alignment align, DeclContext *DC); - DebugTypeInfo(swift::Type Ty, const TypeInfo &Info, DeclContext *DC); - DebugTypeInfo(ValueDecl *Decl, const TypeInfo &Info); - DebugTypeInfo(ValueDecl *Decl, llvm::Type *StorageType, - Size size, Alignment align); - DebugTypeInfo(ValueDecl *Decl, swift::Type Ty, const TypeInfo &Info); - TypeBase* getType() const { return Type; } - - ValueDecl* getDecl() const { - return DeclOrContext.dyn_cast(); - } - - DeclContext *getDeclContext() const { - if (ValueDecl *D = getDecl()) return D->getDeclContext(); - else return DeclOrContext.get(); - } - - void unwrapInOutType() { - Type = Type->castTo()->getObjectType().getPointer(); - } - - bool isNull() const { return Type == nullptr; } - bool operator==(DebugTypeInfo T) const; - bool operator!=(DebugTypeInfo T) const; - - void dump() const; - }; +class SILDebugScope; + +namespace irgen { +class TypeInfo; + +/// This data structure holds everything needed to emit debug info +/// for a type. +class DebugTypeInfo { +public: + /// The Decl holds the DeclContext, location, but also allows to + /// look up struct members. If there is no Decl, generic types + /// mandate there be at least a DeclContext. + PointerUnion DeclOrContext; + /// The type we need to emit may be different from the type + /// mentioned in the Decl, for example, stripped of qualifiers. + TypeBase *Type; + /// Needed to determine the size of basic types and to determine + /// the storage type for undefined variables. + llvm::Type *StorageType; + Size size; + Alignment align; + + DebugTypeInfo() : Type(nullptr), StorageType(nullptr), size(0), align(1) {} + DebugTypeInfo(swift::Type Ty, llvm::Type *StorageTy, uint64_t SizeInBytes, + uint32_t AlignInBytes, DeclContext *DC); + DebugTypeInfo(swift::Type Ty, llvm::Type *StorageTy, Size size, + Alignment align, DeclContext *DC); + DebugTypeInfo(swift::Type Ty, const TypeInfo &Info, DeclContext *DC); + DebugTypeInfo(ValueDecl *Decl, const TypeInfo &Info); + DebugTypeInfo(ValueDecl *Decl, llvm::Type *StorageType, Size size, + Alignment align); + DebugTypeInfo(ValueDecl *Decl, swift::Type Ty, const TypeInfo &Info); + TypeBase *getType() const { return Type; } + + ValueDecl *getDecl() const { return DeclOrContext.dyn_cast(); } + + DeclContext *getDeclContext() const { + if (ValueDecl *D = getDecl()) + return D->getDeclContext(); + else + return DeclOrContext.get(); + } + + void unwrapLValueOrInOutType() { + Type = Type->getLValueOrInOutObjectType().getPointer(); + } + + // Determine whether this type is an Archetype itself. + bool isArchetype() const { + return Type->getLValueOrInOutObjectType()->getKind() == TypeKind::Archetype; + } + + /// LValues, inout args, and Archetypes are implicitly indirect by + /// virtue of their DWARF type. + bool isImplicitlyIndirect() const { + return Type->isLValueType() || isArchetype() || + (Type->getKind() == TypeKind::InOut); } + + bool isNull() const { return Type == nullptr; } + bool operator==(DebugTypeInfo T) const; + bool operator!=(DebugTypeInfo T) const; + + void dump() const; +}; +} } namespace llvm { - // Dense map specialization. - template<> struct DenseMapInfo { - static swift::irgen::DebugTypeInfo getEmptyKey() { - return swift::irgen::DebugTypeInfo(); - } - static swift::irgen::DebugTypeInfo getTombstoneKey() { - return swift::irgen::DebugTypeInfo(llvm::DenseMapInfo - ::getTombstoneKey(), nullptr, 0, 0, 0); - } - static unsigned getHashValue(swift::irgen::DebugTypeInfo Val) { - return DenseMapInfo::getHashValue(Val.getType()); - } - static bool isEqual(swift::irgen::DebugTypeInfo LHS, - swift::irgen::DebugTypeInfo RHS) { - return LHS == RHS; - } - }; - +// Dense map specialization. +template <> struct DenseMapInfo { + static swift::irgen::DebugTypeInfo getEmptyKey() { + return swift::irgen::DebugTypeInfo(); + } + static swift::irgen::DebugTypeInfo getTombstoneKey() { + return swift::irgen::DebugTypeInfo( + llvm::DenseMapInfo::getTombstoneKey(), nullptr, 0, 0, + 0); + } + static unsigned getHashValue(swift::irgen::DebugTypeInfo Val) { + return DenseMapInfo::getHashValue(Val.getType()); + } + static bool isEqual(swift::irgen::DebugTypeInfo LHS, + swift::irgen::DebugTypeInfo RHS) { + return LHS == RHS; + } +}; } #endif diff --git a/lib/IRGen/DominancePoint.h b/lib/IRGen/DominancePoint.h new file mode 100644 index 0000000000000..d2df06f8429ed --- /dev/null +++ b/lib/IRGen/DominancePoint.h @@ -0,0 +1,77 @@ +//===--- DominancePoint.h - Dominance points --------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines types relating to local dominance calculations +// during the emission of a function. +// +// During the emission of a function, the LLVM IR is not well-formed enough +// to do accurate dominance computations. For example, a basic block may +// appear to have a single predecessor, but that may be because a different +// predecessor has not yet been added. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_DOMINANCEPOINT_H +#define SWIFT_IRGEN_DOMINANCEPOINT_H + +#include +#include + +namespace swift { +namespace irgen { + class IRGenFunction; + +/// An opaque class for storing keys for the dominance callback. The +/// key is assumed to be something like a (uniqued) pointer, and a +/// null pointer is assumed to mean a non-dominating point. +class DominancePoint { + uintptr_t Value; + enum : uintptr_t { + Universal = 0, + }; + explicit DominancePoint(uintptr_t value) : Value(value) {} +public: + explicit DominancePoint(void *value) + : Value(reinterpret_cast(value)) { + assert(isOrdinary()); + } + + /// Something about the definition is known to dominate all possible + /// places that will use it. + static DominancePoint universal() { return DominancePoint(Universal); } + + bool isOrdinary() const { + return Value != Universal; + } + bool isUniversal() const { + return Value == Universal; + } + + template T* as() const { + assert(isOrdinary()); + return reinterpret_cast(Value); + } + bool operator==(DominancePoint other) const { return Value == other.Value; } +}; + +/// A dominance resolver is a function that answers the question of +/// whether one dominance point dominates another. +/// +/// It will only be asked this question with ordinary dominance points. +using DominanceResolverFunction = bool(*)(IRGenFunction &IGF, + DominancePoint curPoint, + DominancePoint definingPoint); + +} +} + +#endif diff --git a/lib/IRGen/DominanceScope.h b/lib/IRGen/DominanceScope.h new file mode 100644 index 0000000000000..97ebeebd5b5c1 --- /dev/null +++ b/lib/IRGen/DominanceScope.h @@ -0,0 +1,82 @@ +//===--- DominanceScope.h - Dominance scoping -------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines types relating to local dominance calculations +// during the emission of a function. +// +// During the emission of a function, the LLVM IR is not well-formed enough +// to do accurate dominance computations. For example, a basic block may +// appear to have a single predecessor, but that may be because a different +// predecessor has not yet been added. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_DOMINANCEPOINT_H +#define SWIFT_IRGEN_DOMINANCEPOINT_H + +#include + +namespace swift { +namespace irgen { + class IRGenFunction; + +/// An opaque class for storing keys for the dominance callback. The +/// key is assumed to be something like a (uniqued) pointer, and a +/// null pointer is assumed to mean a non-dominating point. +class DominancePoint { + uintptr_t Value; + enum : uintptr_t { + Universal = 0, + Unknown = 1, + }; + explicit DominancePoint(uintptr_t value) : Value(value) {} +public: + explicit DominancePoint(void *value) + : Value(reinterpret_cast(value)) { + assert(isOrdinary()); + } + + /// Something about the definition is known to dominate all possible + /// places that will use it. + static DominancePoint universal() { return DominanceKey(Universal); } + + /// This definition point has non-obvious dominance rules; don't put + /// anything here and assume it'll dominate other things. This should be + /// used when IRGen adds its own control flow that might interact awkwardly + /// with dominance. + static DominancePoint unknown() { return DominanceKey(Unknown); } + + bool isOrdinary() { + return Value > Uncacheable; + } + bool isUniversal() { + return Value == Universal; + } + bool isUnknown() { + return Value == Unknown; + } + + template T* as() const { + assert(isOrdinary()); + return reinterpret_cast(Value); + } + bool operator==(DominancePoint other) const { return Value == other.Value; } +}; + +using DominanceResolverFunction = bool(*)(IRGenFunction &IGF, + DominancePoint curPoint, + DominancePoint definingPoint); + +} +} + +#endif diff --git a/lib/IRGen/EnumMetadataLayout.h b/lib/IRGen/EnumMetadataLayout.h index 2dbd65307f9b3..adb228a178983 100644 --- a/lib/IRGen/EnumMetadataLayout.h +++ b/lib/IRGen/EnumMetadataLayout.h @@ -1,8 +1,8 @@ -//===--- EnumMetadataLayout.h - CRTP for enum metadata ------*- C++ -*-===// +//===--- EnumMetadataLayout.h - CRTP for enum metadata ----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/EnumPayload.cpp b/lib/IRGen/EnumPayload.cpp index 940bebf405dd6..bdba5c17e8b47 100644 --- a/lib/IRGen/EnumPayload.cpp +++ b/lib/IRGen/EnumPayload.cpp @@ -1,8 +1,8 @@ -//===--- EnumPayload.cpp - Payload management for 'enum' Types -----------===// +//===--- EnumPayload.cpp - Payload management for 'enum' Types ------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -635,6 +635,39 @@ EnumPayload::emitApplyOrMask(IRGenFunction &IGF, APInt mask) { } } +void +EnumPayload::emitApplyOrMask(IRGenFunction &IGF, + EnumPayload mask) { + unsigned count = PayloadValues.size(); + assert(count == mask.PayloadValues.size()); + + auto &DL = IGF.IGM.DataLayout; + for (unsigned i = 0; i < count; i++ ) { + auto payloadTy = getPayloadType(PayloadValues[i]); + unsigned size = DL.getTypeSizeInBits(payloadTy); + + auto payloadIntTy = llvm::IntegerType::get(IGF.IGM.getLLVMContext(), size); + + if (mask.PayloadValues[i].is()) { + // We're ORing with zero, do nothing + } else if (PayloadValues[i].is()) { + PayloadValues[i] = mask.PayloadValues[i]; + } else { + auto v1 = IGF.Builder.CreateBitOrPointerCast( + PayloadValues[i].get(), + payloadIntTy); + + auto v2 = IGF.Builder.CreateBitOrPointerCast( + mask.PayloadValues[i].get(), + payloadIntTy); + + PayloadValues[i] = IGF.Builder.CreateBitOrPointerCast( + IGF.Builder.CreateOr(v1, v2), + payloadTy); + } + } +} + llvm::Value * EnumPayload::emitGatherSpareBits(IRGenFunction &IGF, const SpareBitVector &spareBits, diff --git a/lib/IRGen/EnumPayload.h b/lib/IRGen/EnumPayload.h index d4859eb6e1fa5..3b675f4b65e4c 100644 --- a/lib/IRGen/EnumPayload.h +++ b/lib/IRGen/EnumPayload.h @@ -1,8 +1,8 @@ -//===--- EnumPayload.h - Payload management for 'enum' Types ------* C++ *-===// +//===--- EnumPayload.h - Payload management for 'enum' Types ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -166,6 +166,9 @@ class EnumPayload { /// Apply an OR mask to the payload. void emitApplyOrMask(IRGenFunction &IGF, APInt mask); + /// Apply an OR mask to the payload. + void emitApplyOrMask(IRGenFunction &IGF, EnumPayload mask); + /// Gather bits from an enum payload based on a spare bit mask. llvm::Value *emitGatherSpareBits(IRGenFunction &IGF, const SpareBitVector &spareBits, diff --git a/lib/IRGen/Explosion.h b/lib/IRGen/Explosion.h index c7ff0befd2808..2f6646bb61b14 100644 --- a/lib/IRGen/Explosion.h +++ b/lib/IRGen/Explosion.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/ExtraInhabitants.cpp b/lib/IRGen/ExtraInhabitants.cpp index 5e9ef76443103..5ee01e145af42 100644 --- a/lib/IRGen/ExtraInhabitants.cpp +++ b/lib/IRGen/ExtraInhabitants.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/ExtraInhabitants.h b/lib/IRGen/ExtraInhabitants.h index 5794776a82bed..436e89f802e56 100644 --- a/lib/IRGen/ExtraInhabitants.h +++ b/lib/IRGen/ExtraInhabitants.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/FixedTypeInfo.h b/lib/IRGen/FixedTypeInfo.h index 4d51071540798..97d30f1c9f2f5 100644 --- a/lib/IRGen/FixedTypeInfo.h +++ b/lib/IRGen/FixedTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/Fulfillment.cpp b/lib/IRGen/Fulfillment.cpp new file mode 100644 index 0000000000000..c4355155323a9 --- /dev/null +++ b/lib/IRGen/Fulfillment.cpp @@ -0,0 +1,345 @@ +//===--- Fulfillment.cpp - Static metadata search ------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file implements routines for searching for ways to find metadata +// from other metadata. +// +//===----------------------------------------------------------------------===// + +#include "Fulfillment.h" +#include "IRGen.h" + +#include "swift/AST/Decl.h" +#include "swift/SIL/TypeLowering.h" + +using namespace swift; +using namespace irgen; + +/// Is metadata for the given type kind a "leaf", or does it possibly +/// store any other type metadata that we can statically extract? +/// +/// It's okay to conservatively answer "no". It's more important for this +/// to be quick than for it to be accurate; don't recurse. +static bool isLeafTypeMetadata(CanType type) { + switch (type->getKind()) { +#define SUGARED_TYPE(ID, SUPER) \ + case TypeKind::ID: +#define UNCHECKED_TYPE(ID, SUPER) \ + case TypeKind::ID: +#define TYPE(ID, SUPER) +#include "swift/AST/TypeNodes.def" + llvm_unreachable("kind is invalid for a canonical type"); + +#define ARTIFICIAL_TYPE(ID, SUPER) \ + case TypeKind::ID: +#define TYPE(ID, SUPER) +#include "swift/AST/TypeNodes.def" + case TypeKind::LValue: + case TypeKind::InOut: + case TypeKind::DynamicSelf: + llvm_unreachable("these types do not have metadata"); + + // All the builtin types are leaves. +#define BUILTIN_TYPE(ID, SUPER) \ + case TypeKind::ID: +#define TYPE(ID, SUPER) +#include "swift/AST/TypeNodes.def" + case TypeKind::Module: + return true; + + // Type parameters are statically opaque. + case TypeKind::Archetype: + case TypeKind::GenericTypeParam: + case TypeKind::DependentMember: + return true; + + // Only the empty tuple is a leaf. + case TypeKind::Tuple: + return cast(type)->getNumElements() == 0; + + // Nominal types might have parents. + case TypeKind::Class: + case TypeKind::Enum: + case TypeKind::Protocol: + case TypeKind::Struct: + return !cast(type)->getParent(); + + // Bound generic types have type arguments. + case TypeKind::BoundGenericClass: + case TypeKind::BoundGenericEnum: + case TypeKind::BoundGenericStruct: + return false; + + // Functions have component types. + case TypeKind::Function: + case TypeKind::PolymorphicFunction: + case TypeKind::GenericFunction: // included for future-proofing + return false; + + // Protocol compositions have component types. + case TypeKind::ProtocolComposition: + return false; + + // Metatypes have instance types. + case TypeKind::Metatype: + case TypeKind::ExistentialMetatype: + return false; + } + llvm_unreachable("bad type kind"); +} + +/// Given that we have a source for metadata of the given type, check +/// to see if it fulfills anything. +/// +/// \param isExact - true if the metadata is known to be exactly the +/// metadata for the given type, false if it might be a subtype +bool FulfillmentMap::searchTypeMetadata(ModuleDecl &M, CanType type, + IsExact_t isExact, + unsigned source, MetadataPath &&path, + const InterestingKeysCallback &keys) { + + // If this is an exact source, and it's an interesting type, add this + // as a fulfillment. + if (isExact && keys.isInterestingType(type)) { + // If the type isn't a leaf type, also check it as an inexact match. + bool hadFulfillment = false; + if (!isLeafTypeMetadata(type)) { + hadFulfillment |= searchTypeMetadata(M, type, IsInexact, source, + MetadataPath(path), keys); + } + + // Add the fulfillment. + hadFulfillment |= addFulfillment({type, nullptr}, source, std::move(path)); + return hadFulfillment; + } + + // Inexact metadata will be a problem if we ever try to use this + // to remember that we already have the metadata for something. + if (auto nomTy = dyn_cast(type)) { + return searchNominalTypeMetadata(M, nomTy, source, std::move(path), keys); + } + if (auto boundTy = dyn_cast(type)) { + return searchBoundGenericTypeMetadata(M, boundTy, source, std::move(path), + keys); + } + + // TODO: tuples + // TODO: functions + // TODO: metatypes + + return false; +} + +/// Given that we have a source for a witness table that the given type +/// conforms to the given protocol, check to see if it fulfills anything. +bool FulfillmentMap::searchWitnessTable(ModuleDecl &M, + CanType type, ProtocolDecl *protocol, + unsigned source, MetadataPath &&path, + const InterestingKeysCallback &keys) { + llvm::SmallPtrSet interestingConformancesBuffer; + llvm::SmallPtrSetImpl *interestingConformances = nullptr; + + // If the interesting-keys set is limiting the set of interesting + // conformances, collect that filter. + if (keys.isInterestingType(type) && + keys.hasLimitedInterestingConformances(type)) { + // Bail out immediately if the set is empty. + // This only makes sense because we're not trying to fulfill + // associated types this way. + auto requiredConformances = keys.getInterestingConformances(type); + if (requiredConformances.empty()) return false; + + interestingConformancesBuffer.insert(requiredConformances.begin(), + requiredConformances.end()); + interestingConformances = &interestingConformancesBuffer; + } + + return searchWitnessTable(M, type, protocol, source, std::move(path), keys, + interestingConformances); +} + +bool FulfillmentMap::searchWitnessTable(ModuleDecl &M, + CanType type, ProtocolDecl *protocol, + unsigned source, MetadataPath &&path, + const InterestingKeysCallback &keys, + const llvm::SmallPtrSetImpl * + interestingConformances) { + assert(Lowering::TypeConverter::protocolRequiresWitnessTable(protocol)); + + bool hadFulfillment = false; + + auto nextInheritedIndex = 0; + for (auto inherited : protocol->getInheritedProtocols(nullptr)) { + auto index = nextInheritedIndex++; + + // Ignore protocols that don't have witness tables. + if (!Lowering::TypeConverter::protocolRequiresWitnessTable(inherited)) + continue; + + MetadataPath inheritedPath = path; + inheritedPath.addInheritedProtocolComponent(index); + hadFulfillment |= searchWitnessTable(M, type, inherited, + source, std::move(inheritedPath), + keys, interestingConformances); + } + + // If we're not limited the set of interesting conformances, or if + // this is an interesting conformance, record it. + if (!interestingConformances || interestingConformances->count(protocol)) { + hadFulfillment |= addFulfillment({type, protocol}, source, std::move(path)); + } + + return hadFulfillment; +} + + +bool FulfillmentMap::searchParentTypeMetadata(ModuleDecl &M, CanType parent, + unsigned source, + MetadataPath &&path, + const InterestingKeysCallback &keys) { + // We might not have a parent type. + if (!parent) return false; + + // If we do, it has to be nominal one way or another. + path.addNominalParentComponent(); + return searchTypeMetadata(M, parent, IsExact, source, std::move(path), keys); +} + +bool FulfillmentMap::searchNominalTypeMetadata(ModuleDecl &M, + CanNominalType type, + unsigned source, + MetadataPath &&path, + const InterestingKeysCallback &keys) { + // Nominal types add no generic arguments themselves, but they + // may have the arguments of their parents. + return searchParentTypeMetadata(M, type.getParent(), + source, std::move(path), keys); +} + +bool FulfillmentMap::searchBoundGenericTypeMetadata(ModuleDecl &M, + CanBoundGenericType type, + unsigned source, + MetadataPath &&path, + const InterestingKeysCallback &keys) { + auto params = type->getDecl()->getGenericParams()->getAllArchetypes(); + auto substitutions = type->getSubstitutions(&M, nullptr); + assert(params.size() >= substitutions.size() && + "generic decl archetypes should parallel generic type subs"); + + bool hadFulfillment = false; + + for (unsigned i = 0, e = substitutions.size(); i != e; ++i) { + auto sub = substitutions[i]; + CanType arg = sub.getReplacement()->getCanonicalType(); + + // Skip uninteresting type arguments. + if (!keys.hasInterestingType(arg)) + continue; + + // If the argument is a type parameter, fulfill conformances for it. + if (keys.isInterestingType(arg)) { + hadFulfillment |= + searchTypeArgConformances(M, arg, params[i], source, path, i, keys); + } + + // Refine the path. + MetadataPath argPath = path; + argPath.addNominalTypeArgumentComponent(i); + hadFulfillment |= + searchTypeMetadata(M, arg, IsExact, source, std::move(argPath), keys); + } + + // Also match against the parent. The polymorphic type + // will start with any arguments from the parent. + hadFulfillment |= searchParentTypeMetadata(M, type.getParent(), + source, std::move(path), keys); + return hadFulfillment; +} + +bool FulfillmentMap::searchTypeArgConformances(ModuleDecl &M, CanType arg, + ArchetypeType *param, + unsigned source, + const MetadataPath &path, + unsigned argIndex, + const InterestingKeysCallback &keys) { + // Our sources are the protocol conformances that are recorded in + // the generic metadata. + auto storedConformances = param->getConformsTo(); + if (storedConformances.empty()) return false; + + llvm::SmallPtrSet interestingConformancesBuffer; + llvm::SmallPtrSetImpl *interestingConformances = nullptr; + + // If the interesting-keys set is limiting the set of interesting + // conformances, collect that filter. + if (keys.hasLimitedInterestingConformances(arg)) { + // Bail out immediately if the set is empty. + auto requiredConformances = keys.getInterestingConformances(arg); + if (requiredConformances.empty()) return false; + + interestingConformancesBuffer.insert(requiredConformances.begin(), + requiredConformances.end()); + interestingConformances = &interestingConformancesBuffer; + } + + bool hadFulfillment = false; + + for (size_t confIndex : indices(storedConformances)) { + auto storedProtocol = storedConformances[confIndex]; + if (!Lowering::TypeConverter::protocolRequiresWitnessTable(storedProtocol)) + continue; + + MetadataPath confPath = path; + confPath.addNominalTypeArgumentConformanceComponent(argIndex, confIndex); + hadFulfillment |= + searchWitnessTable(M, arg, storedProtocol, source, std::move(confPath), + keys, interestingConformances); + } + + return hadFulfillment; +} + +/// Testify that there's a fulfillment at the given path. +bool FulfillmentMap::addFulfillment(FulfillmentKey key, + unsigned source, MetadataPath &&path) { + // Only add a fulfillment if we don't have any previous + // fulfillment for that value or if it 's cheaper than the existing + // fulfillment. + auto it = Fulfillments.find(key); + if (it != Fulfillments.end()) { + if (path.cost() >= it->second.Path.cost()) { + return false; + } + + it->second.SourceIndex = source; + it->second.Path = std::move(path); + return true; + } else { + Fulfillments.insert({ key, Fulfillment(source, std::move(path)) }); + return true; + } +} + +bool FulfillmentMap::Everything::isInterestingType(CanType type) const { + return true; +} +bool FulfillmentMap::Everything::hasInterestingType(CanType type) const { + return true; +} +bool FulfillmentMap::Everything + ::hasLimitedInterestingConformances(CanType type) const { + return false; +} +GenericSignature::ConformsToArray +FulfillmentMap::Everything::getInterestingConformances(CanType type) const{ + return {}; +} diff --git a/lib/IRGen/Fulfillment.h b/lib/IRGen/Fulfillment.h new file mode 100644 index 0000000000000..3351894d0d73a --- /dev/null +++ b/lib/IRGen/Fulfillment.h @@ -0,0 +1,168 @@ +//===--- Fulfillment.h - Deriving type/conformance metadata -----*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines interfaces for deriving type metadata and protocol +// witness tables from various sources. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_FULFILLMENT_H +#define SWIFT_IRGEN_FULFILLMENT_H + +#include "llvm/ADT/DenseMap.h" +#include "swift/AST/Types.h" +#include "swift/AST/GenericSignature.h" +#include "MetadataPath.h" + +namespace swift { +namespace irgen { + enum IsExact_t : bool; + +/// The metadata value can be fulfilled by following the given metadata +/// path from the given source. +struct Fulfillment { + Fulfillment() = default; + Fulfillment(unsigned sourceIndex, MetadataPath &&path) + : SourceIndex(sourceIndex), Path(std::move(path)) {} + + /// The source index. + unsigned SourceIndex; + + /// The path from the source metadata. + MetadataPath Path; +}; + +class FulfillmentMap { + using FulfillmentKey = std::pair; + + llvm::DenseMap Fulfillments; + +public: + struct InterestingKeysCallback { + /// Is the given type something that we should add fulfillments for? + virtual bool isInterestingType(CanType type) const = 0; + + /// Is the given type expressed in terms of types that we should add + /// fulfillments for? + /// + /// It's okay to conservatively return true here. + virtual bool hasInterestingType(CanType type) const = 0; + + /// Are we only interested in a subset of the conformances for a + /// given type? + virtual bool hasLimitedInterestingConformances(CanType type) const = 0; + + /// Return the limited interesting conformances for an interesting type. + virtual GenericSignature::ConformsToArray + getInterestingConformances(CanType type) const = 0; + + virtual ~InterestingKeysCallback() = default; + }; + + /// An implementation of InterestingKeysCallback that returns everything + /// fulfillable. + struct Everything : InterestingKeysCallback { + bool isInterestingType(CanType type) const override; + bool hasInterestingType(CanType type) const override; + bool hasLimitedInterestingConformances(CanType type) const override; + GenericSignature::ConformsToArray + getInterestingConformances(CanType type) const override; + }; + + FulfillmentMap() = default; + + using iterator = decltype(Fulfillments)::iterator; + iterator begin() { return Fulfillments.begin(); } + iterator end() { return Fulfillments.end(); } + + /// Is it even theoretically possible that we might find a fulfillment + /// in the given type? + static bool isInterestingTypeForFulfillments(CanType type) { + // Some day, if we ever record fulfillments for concrete types, this + // optimization will probably no longer be useful. + return type->hasTypeParameter(); + } + + /// Search the given type metadata for useful fulfillments. + /// + /// \return true if any fulfillments were added by this search. + bool searchTypeMetadata(ModuleDecl &M, CanType type, IsExact_t isExact, + unsigned sourceIndex, MetadataPath &&path, + const InterestingKeysCallback &interestingKeys); + + /// Search the given witness table for useful fulfillments. + /// + /// \return true if any fulfillments were added by this search. + bool searchWitnessTable(ModuleDecl &M, CanType type, ProtocolDecl *protocol, + unsigned sourceIndex, MetadataPath &&path, + const InterestingKeysCallback &interestingKeys); + + /// Register a fulfillment for the given key. + /// + /// \return true if the fulfillment was added, which won't happen if there's + /// already a fulfillment that was at least as good + bool addFulfillment(FulfillmentKey key, unsigned source, MetadataPath &&path); + + const Fulfillment *getTypeMetadata(CanType type) const { + auto it = Fulfillments.find({type, nullptr}); + if (it != Fulfillments.end()) { + return &it->second; + } else { + return nullptr; + } + } + + const Fulfillment *getWitnessTable(CanType type, ProtocolDecl *proto) const { + auto it = Fulfillments.find({type, proto}); + if (it != Fulfillments.end()) { + return &it->second; + } else { + return nullptr; + } + } + +private: + bool searchParentTypeMetadata(ModuleDecl &M, CanType parent, + unsigned source, MetadataPath &&path, + const InterestingKeysCallback &keys); + + bool searchNominalTypeMetadata(ModuleDecl &M, CanNominalType type, + unsigned source, MetadataPath &&path, + const InterestingKeysCallback &keys); + + bool searchBoundGenericTypeMetadata(ModuleDecl &M, CanBoundGenericType type, + unsigned source, MetadataPath &&path, + const InterestingKeysCallback &keys); + + bool searchTypeArgConformances(ModuleDecl &M, CanType arg, + ArchetypeType *param, + unsigned source, const MetadataPath &path, + unsigned argIndex, + const InterestingKeysCallback &keys); + + /// Search the given witness table for useful fulfillments. + /// + /// \return true if any fulfillments were added by this search. + bool searchWitnessTable(ModuleDecl &M, CanType type, ProtocolDecl *protocol, + unsigned sourceIndex, MetadataPath &&path, + const InterestingKeysCallback &interestingKeys, + const llvm::SmallPtrSetImpl * + interestingConformances); + +}; + +} +} + +#endif + + diff --git a/lib/IRGen/GenArchetype.cpp b/lib/IRGen/GenArchetype.cpp index 3c78795469456..ec23b3936fcca 100644 --- a/lib/IRGen/GenArchetype.cpp +++ b/lib/IRGen/GenArchetype.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -46,12 +46,16 @@ #include "ProtocolInfo.h" #include "ResilientTypeInfo.h" #include "TypeInfo.h" -#include "UnownedTypeInfo.h" #include "WeakTypeInfo.h" using namespace swift; using namespace irgen; +static llvm::Value *emitArchetypeTypeMetadataRef(IRGenFunction &IGF, + CanArchetypeType archetype) { + return IGF.getLocalTypeData(archetype, LocalTypeDataKind::forMetatype()); +} + namespace { /// Common type implementation details for all archetypes. @@ -84,8 +88,9 @@ class ArchetypeTypeInfoBase { CanArchetypeType archetype, unsigned which) const { assert(which < getNumStoredProtocols()); + auto protocol = archetype->getConformsTo()[which]; return IGF.getLocalTypeData(archetype, - LocalTypeData::forArchetypeProtocolWitness(which)); + LocalTypeDataKind::forArchetypeProtocolWitnessTable(protocol)); } }; @@ -180,6 +185,38 @@ llvm::Value *irgen::emitWitnessTableRef(IRGenFunction &IGF, return wtable; } +llvm::Value *irgen::emitAssociatedTypeMetadataRef(IRGenFunction &IGF, + CanArchetypeType origin, + AssociatedTypeDecl *associate) { + // Find the conformance of the origin to the associated type's protocol. + llvm::Value *wtable = emitWitnessTableRef(IGF, origin, + associate->getProtocol()); + + // Find the origin's type metadata. + llvm::Value *originMetadata = emitArchetypeTypeMetadataRef(IGF, origin); + + return emitAssociatedTypeMetadataRef(IGF, originMetadata, wtable, associate); +} + +llvm::Value * +irgen::emitAssociatedTypeWitnessTableRef(IRGenFunction &IGF, + CanArchetypeType origin, + AssociatedTypeDecl *associate, + llvm::Value *associateMetadata, + ProtocolDecl *associateProtocol) { + // Find the conformance of the origin to the associated type's protocol. + llvm::Value *wtable = emitWitnessTableRef(IGF, origin, + associate->getProtocol()); + + // Find the origin's type metadata. + llvm::Value *originMetadata = emitArchetypeTypeMetadataRef(IGF, origin); + + // FIXME: will this ever be an indirect requirement? + return emitAssociatedTypeWitnessTableRef(IGF, originMetadata, wtable, + associate, associateMetadata, + associateProtocol); +} + const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) { assert(isExemplarArchetype(archetype) && "lowering non-exemplary archetype"); @@ -238,7 +275,7 @@ static void setMetadataRef(IRGenFunction &IGF, llvm::Value *metadata) { assert(metadata->getType() == IGF.IGM.TypeMetadataPtrTy); IGF.setUnscopedLocalTypeData(CanType(archetype), - LocalTypeData::forMetatype(), + LocalTypeDataKind::forMetatype(), metadata); // Create a shadow copy of the metadata in an alloca for the debug info. @@ -262,8 +299,10 @@ static void setWitnessTable(IRGenFunction &IGF, llvm::Value *wtable) { assert(wtable->getType() == IGF.IGM.WitnessTablePtrTy); assert(protocolIndex < archetype->getConformsTo().size()); + auto protocol = archetype->getConformsTo()[protocolIndex]; IGF.setUnscopedLocalTypeData(CanType(archetype), - LocalTypeData::forArchetypeProtocolWitness(protocolIndex), wtable); + LocalTypeDataKind::forArchetypeProtocolWitnessTable(protocol), + wtable); } /// Inform IRGenFunction that the given archetype has the given value @@ -300,8 +339,7 @@ llvm::Value *irgen::emitDynamicTypeOfOpaqueArchetype(IRGenFunction &IGF, auto archetype = type.castTo(); // Acquire the archetype's static metadata. - llvm::Value *metadata = IGF.getLocalTypeData(archetype, - LocalTypeData::forMetatype()); + llvm::Value *metadata = emitArchetypeTypeMetadataRef(IGF, archetype); return IGF.Builder.CreateCall(IGF.IGM.getGetDynamicTypeFn(), {addr.getAddress(), metadata}); } diff --git a/lib/IRGen/GenArchetype.h b/lib/IRGen/GenArchetype.h index 76936393d1811..1ca989ab8838c 100644 --- a/lib/IRGen/GenArchetype.h +++ b/lib/IRGen/GenArchetype.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -36,6 +36,19 @@ namespace irgen { CanArchetypeType archetype, ProtocolDecl *protocol); + /// Emit a metadata reference for an associated type of an archetype. + llvm::Value *emitAssociatedTypeMetadataRef(IRGenFunction &IGF, + CanArchetypeType origin, + AssociatedTypeDecl *associate); + + /// Emit a witness table reference for a specific conformance of an + /// associated type of an archetype. + llvm::Value *emitAssociatedTypeWitnessTableRef(IRGenFunction &IGF, + CanArchetypeType origin, + AssociatedTypeDecl *associate, + llvm::Value *associateMetadata, + ProtocolDecl *associateProtocol); + /// Emit a dynamic metatype lookup for the given archetype. llvm::Value *emitDynamicTypeOfOpaqueArchetype(IRGenFunction &IGF, Address archetypeAddr, diff --git a/lib/IRGen/GenCast.cpp b/lib/IRGen/GenCast.cpp index 955540cde5c69..01bc6ab7e1132 100644 --- a/lib/IRGen/GenCast.cpp +++ b/lib/IRGen/GenCast.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -103,7 +103,7 @@ FailableCastResult irgen::emitClassIdenticalCast(IRGenFunction &IGF, // TODO: use ObjC class references llvm::Value *targetMetadata; if (allowConservative && - (targetMetadata = tryEmitConstantHeapMetadataRef(IGF.IGM, + (targetMetadata = tryEmitConstantTypeMetadataRef(IGF.IGM, toType.getSwiftRValueType()))) { // ok } else { @@ -320,7 +320,7 @@ static llvm::Function *emitExistentialScalarCastFn(IRGenModule &IGM, llvm::Twine(name), IGM.getModule()); fn->setAttributes(IGM.constructInitialAttributes()); - auto IGF = IRGenFunction(IGM, fn); + IRGenFunction IGF(IGM, fn); Explosion args = IGF.collectParameters(); auto value = args.claimNext(); @@ -593,6 +593,7 @@ void irgen::emitScalarExistentialDowncast(IRGenFunction &IGF, // If we're doing a conditional cast, and the ObjC protocol checks failed, // then the cast is done. + Optional condition; llvm::BasicBlock *origBB = nullptr, *successBB = nullptr, *contBB = nullptr; if (!objcProtos.empty()) { switch (mode) { @@ -607,6 +608,7 @@ void irgen::emitScalarExistentialDowncast(IRGenFunction &IGF, cast(objcCast->getType()))); IGF.Builder.CreateCondBr(isNull, contBB, successBB); IGF.Builder.emitBlock(successBB); + condition.emplace(IGF); } } } @@ -658,6 +660,7 @@ void irgen::emitScalarExistentialDowncast(IRGenFunction &IGF, // If we had conditional ObjC checks, join the failure paths. if (contBB) { + condition.reset(); IGF.Builder.CreateBr(contBB); IGF.Builder.emitBlock(contBB); diff --git a/lib/IRGen/GenCast.h b/lib/IRGen/GenCast.h index 85912592c7e0f..d97bf8af0f497 100644 --- a/lib/IRGen/GenCast.h +++ b/lib/IRGen/GenCast.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenClangDecl.cpp b/lib/IRGen/GenClangDecl.cpp index ecb6eaf0e16a5..789c23118d558 100644 --- a/lib/IRGen/GenClangDecl.cpp +++ b/lib/IRGen/GenClangDecl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenClangType.cpp b/lib/IRGen/GenClangType.cpp index c7f67847abdb3..c99610a0a4abf 100644 --- a/lib/IRGen/GenClangType.cpp +++ b/lib/IRGen/GenClangType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -547,6 +547,7 @@ clang::CanQualType GenClangType::visitSILFunctionType(CanSILFunctionType type) { llvm_unreachable("block takes owned parameter"); case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: case ParameterConvention::Indirect_In_Guaranteed: llvm_unreachable("block takes indirect parameter"); @@ -720,9 +721,9 @@ clang::CanQualType IRGenModule::getClangType(SILType type) { clang::CanQualType IRGenModule::getClangType(SILParameterInfo params) { auto clangType = getClangType(params.getSILType()); - // @block_storage types must be wrapped in an @inout and have special - // lowering - if (params.isIndirectInOut() && + // @block_storage types must be @inout_aliasable and have + // special lowering + if (params.isIndirectMutating() && !params.getSILType().is()) { return getClangASTContext().getPointerType(clangType); } diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index c8605c574aa7f..795f1b184e7aa 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -1,8 +1,8 @@ -//===--- GenClass.cpp - Swift IR Generation For 'class' Types -----------===// +//===--- GenClass.cpp - Swift IR Generation For 'class' Types -------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -67,6 +67,7 @@ ReferenceCounting irgen::getReferenceCountingForClass(IRGenModule &IGM, if (!IGM.ObjCInterop) return ReferenceCounting::Native; + // NOTE: if you change this, change Type::usesNativeReferenceCounting. // If the root class is implemented in swift, then we have a swift // refcount; otherwise, we have an ObjC refcount. if (hasKnownSwiftImplementation(IGM, getRootClass(theClass))) @@ -90,50 +91,12 @@ IsaEncoding irgen::getIsaEncodingForType(IRGenModule &IGM, return IsaEncoding::Pointer; } -/// Different policies for accessing a physical field. -enum class FieldAccess : uint8_t { - /// Instance variable offsets are constant. - ConstantDirect, - - /// Instance variable offsets must be loaded from "direct offset" - /// global variables. - NonConstantDirect, - - /// Instance variable offsets are kept in fields in metadata, but - /// the offsets of those fields within the metadata are constant. - ConstantIndirect, - - /// Instance variable offsets are kept in fields in metadata, and - /// the offsets of those fields within the metadata must be loaded - /// from "indirect offset" global variables. - NonConstantIndirect -}; - namespace { - class FieldEntry { - llvm::PointerIntPair VarAndAccess; - public: - FieldEntry(VarDecl *var, FieldAccess access) - : VarAndAccess(var, access) {} - - VarDecl *getVar() const { - return VarAndAccess.getPointer(); - } - FieldAccess getAccess() const { - return VarAndAccess.getInt(); - } - }; - /// Layout information for class types. class ClassTypeInfo : public HeapTypeInfo { ClassDecl *TheClass; mutable StructLayout *Layout; - /// Lazily-initialized array of all fragile stored properties in the class - /// (including superclass stored properties). - mutable ArrayRef AllStoredProperties; - /// Lazily-initialized array of all fragile stored properties inherited from - /// superclasses. - mutable ArrayRef InheritedStoredProperties; + mutable ClassLayout FieldLayout; /// Can we use swift reference-counting, or do we have to use /// objc_retain/release? @@ -159,8 +122,7 @@ namespace { ClassDecl *getClass() const { return TheClass; } const StructLayout &getLayout(IRGenModule &IGM) const; - ArrayRef getAllStoredProperties(IRGenModule &IGM) const; - ArrayRef getInheritedStoredProperties(IRGenModule &IGM) const; + const struct ClassLayout &getClassLayout(IRGenModule &IGM) const; Alignment getHeapAlignment(IRGenModule &IGM) const { return getLayout(IGM).getAlignment(); @@ -169,128 +131,6 @@ namespace { return getLayout(IGM).getElements(); } }; - - /// A class for computing properties of the instance-variable layout - /// of a class. TODO: cache the results! - class LayoutClass { - IRGenModule &IGM; - - ClassDecl *Root; - SmallVector Fields; - - bool IsMetadataResilient = false; - bool IsObjectResilient = false; - bool IsObjectGenericallyArranged = false; - - ResilienceScope Resilience; - - public: - LayoutClass(IRGenModule &IGM, ResilienceScope resilience, - ClassDecl *theClass, SILType type) - : IGM(IGM), Resilience(resilience) { - layout(theClass, type); - } - - /// The root class for purposes of metaclass objects. - ClassDecl *getRootClassForMetaclass() const { - // If the formal root class is imported from Objective-C, then - // we should use that. For a class that's really implemented in - // Objective-C, this is obviously right. For a class that's - // really implemented in Swift, but that we're importing via an - // Objective-C interface, this would be wrong --- except such a - // class can never be a formal root class, because a Swift class - // without a formal superclass will actually be parented by - // SwiftObject (or maybe eventually something else like it), - // which will be visible in the Objective-C type system. - if (Root->hasClangNode()) return Root; - - // FIXME: If the root class specifies its own runtime ObjC base class, - // assume that that base class ultimately inherits NSObject. - if (Root->getAttrs().hasAttribute()) - return IGM.getObjCRuntimeBaseClass(IGM.Context.Id_NSObject); - - return IGM.getObjCRuntimeBaseClass(IGM.Context.Id_SwiftObject); - } - - const FieldEntry &getFieldEntry(VarDecl *field) const { - for (auto &entry : Fields) - if (entry.getVar() == field) - return entry; - llvm_unreachable("no entry for field!"); - } - - private: - void layout(ClassDecl *theClass, SILType type) { - // First, collect information about the superclass. - if (theClass->hasSuperclass()) { - SILType superclassType = type.getSuperclass(nullptr); - auto superclass = superclassType.getClassOrBoundGenericClass(); - assert(superclass); - layout(superclass, superclassType); - } else { - Root = theClass; - } - - // If the class is resilient (which includes classes imported - // from Objective-C), then it may have fields we can't see, - // and all subsequent fields are *at least* resilient. - bool isClassResilient = IGM.isResilient(theClass, Resilience); - if (isClassResilient) { - IsMetadataResilient = true; - IsObjectResilient = true; - } - - // Okay, make entries for all the physical fields we know about. - for (auto member : theClass->getMembers()) { - auto var = dyn_cast(member); - if (!var) continue; - - // Skip properties that we have to access logically. - if (!var->hasStorage()) - continue; - - // Adjust based on the type of this field. - // FIXME: this algorithm is assuming that fields are laid out - // in declaration order. - adjustAccessAfterField(var, type); - - Fields.push_back(FieldEntry(var, getCurFieldAccess())); - } - } - - FieldAccess getCurFieldAccess() const { - if (IsObjectGenericallyArranged) { - if (IsMetadataResilient) { - return FieldAccess::NonConstantIndirect; - } else { - return FieldAccess::ConstantIndirect; - } - } else { - if (IsObjectResilient) { - return FieldAccess::NonConstantDirect; - } else { - return FieldAccess::ConstantDirect; - } - } - } - - void adjustAccessAfterField(VarDecl *var, SILType classType) { - if (!var->hasStorage()) return; - - SILType fieldType = classType.getFieldType(var, *IGM.SILMod); - auto &fieldTI = IGM.getTypeInfo(fieldType); - if (fieldTI.isFixedSize()) - return; - - // If the field type is not fixed-size, the size either depends - // on generic parameters, or resilient types. In the former case, - // we store field offsets in type metadata. - if (fieldType.hasArchetype()) - IsObjectGenericallyArranged = true; - - IsObjectResilient = true; - } - }; } // end anonymous namespace. /// Return the lowered type for the class's 'self' type within its context. @@ -304,23 +144,52 @@ static const ClassTypeInfo &getSelfTypeInfo(IRGenModule &IGM, ClassDecl *base) { return IGM.getTypeInfo(getSelfType(base)).as(); } -/// Return the index of the given field within the class. -static unsigned getFieldIndex(IRGenModule &IGM, - ClassDecl *base, VarDecl *target) { - // FIXME: This is algorithmically terrible. - auto &ti = getSelfTypeInfo(IGM, base); - - auto props = ti.getAllStoredProperties(IGM); - auto found = std::find(props.begin(), props.end(), target); - assert(found != props.end() && "didn't find field in type?!"); - return found - props.begin(); -} - namespace { class ClassLayoutBuilder : public StructLayoutBuilder { SmallVector Elements; SmallVector AllStoredProperties; + SmallVector AllFieldAccesses; + + // The manner in which this class embeds the field offset vector of + // the superclass. + // + // - ConstantDirect - size and content of superclass metadata is known + // at compile time. + // - NonConstantDirect - size of superclass metadata is known, however + // some field offsets depend on the sizes of resilient types, or the + // size of an imported Objective-C base class. + // - ConstantIndirect - size of superclass metadata is known, however + // some field offsets depend on generic parameters, sizes of + // resilient types, or the size of an imported Objective-C base class. + // - NonConstantIndirect - size of superclass metadata is unknown, + // so all class metadata entries for members of this class must be + // accessed indirectly. + FieldAccess MetadataAccess = FieldAccess::ConstantDirect; + unsigned NumInherited = 0; + + // Does the class require a metadata template? This will be true if + // the class or any of its ancestors have generic parameters, or if + // any of the below conditions are false. + bool ClassHasMetadataPattern = false; + + // Does the superclass have a fixed number of stored properties? + // If not, and the class has generally-dependent layout, we have to + // access stored properties through an indirect offset into the field + // offset vector. + bool ClassHasFixedFieldCount = true; + + // Does the class have a fixed size up until the current point? + // If not, we have to access stored properties either ivar offset globals, + // or through the field offset vector, based on whether the layout has + // dependent layout. + bool ClassHasFixedSize = true; + + // Does the class have identical layout under all generic substitutions? + // If not, we can have to access stored properties through the field + // offset vector in the instantiated type metadata. + bool ClassHasConcreteLayout = true; + public: ClassLayoutBuilder(IRGenModule &IGM, ClassDecl *theClass) : StructLayoutBuilder(IGM) @@ -339,31 +208,67 @@ namespace { ArrayRef getElements() const { return Elements; } - - /// Return the full list of stored properties. - ArrayRef getAllStoredProperties() const { - return AllStoredProperties; - } - /// Return the inherited stored property count. - unsigned getNumInherited() const { - return NumInherited; + ClassLayout getClassLayout() const { + ClassLayout fieldLayout; + auto allStoredProps = IGM.Context.AllocateCopy(AllStoredProperties); + auto inheritedStoredProps = allStoredProps.slice(0, NumInherited); + fieldLayout.AllStoredProperties = allStoredProps; + fieldLayout.InheritedStoredProperties = inheritedStoredProps; + fieldLayout.AllFieldAccesses = IGM.Context.AllocateCopy(AllFieldAccesses); + fieldLayout.MetadataAccess = MetadataAccess; + fieldLayout.HasMetadataPattern = ClassHasMetadataPattern; + return fieldLayout; } + private: void addFieldsForClass(ClassDecl *theClass, SILType classType) { + if (theClass->isGenericContext()) + ClassHasMetadataPattern = true; + if (theClass->hasSuperclass()) { // TODO: apply substitutions when computing base-class layouts! SILType superclassType = classType.getSuperclass(nullptr); auto superclass = superclassType.getClassOrBoundGenericClass(); assert(superclass); - // Recur. - addFieldsForClass(superclass, superclassType); - // Count the fields we got from the superclass. - NumInherited = Elements.size(); + if (superclass->hasClangNode()) { + // As a special case, assume NSObject has a fixed layout. + if (superclass->getName() != IGM.Context.Id_NSObject) { + // If the superclass was imported from Objective-C, its size is + // not known at compile time. However, since the field offset + // vector only stores offsets of stored properties defined in + // Swift, we don't have to worry about indirect indexing of + // the field offset vector. + ClassHasFixedSize = false; + } + } else if (IGM.isResilient(superclass, ResilienceScope::Component)) { + // If the superclass is resilient, the number of stored properties + // is not known at compile time. + ClassHasMetadataPattern = true; + + ClassHasFixedFieldCount = false; + ClassHasFixedSize = false; + + // If the superclass is in a generic context, conservatively + // assume the layout depends on generic parameters, since we + // can't look at stored properties. + if (superclassType.hasArchetype()) + ClassHasConcreteLayout = false; + } else { + // Otherwise, we have total knowledge of the class and its + // fields, so walk them to compute the layout. + addFieldsForClass(superclass, superclassType); + // Count the fields we got from the superclass. + NumInherited = Elements.size(); + } } + // The final value is field access for the superclass of the class we're + // building. + MetadataAccess = getCurFieldAccess(); + // Collect fields from this class and add them to the layout as a chunk. addDirectFieldsFromClass(theClass, classType); } @@ -373,15 +278,55 @@ namespace { for (VarDecl *var : theClass->getStoredProperties()) { SILType type = classType.getFieldType(var, *IGM.SILMod); auto &eltType = IGM.getTypeInfo(type); + + if (!eltType.isFixedSize()) { + ClassHasMetadataPattern = true; + ClassHasFixedSize = false; + + if (type.hasArchetype()) + ClassHasConcreteLayout = false; + } + Elements.push_back(ElementLayout::getIncomplete(eltType)); AllStoredProperties.push_back(var); + AllFieldAccesses.push_back(getCurFieldAccess()); + } + } + + FieldAccess getCurFieldAccess() const { + if (ClassHasConcreteLayout) { + if (ClassHasFixedSize) { + // No generic parameter dependencies, fixed size. The field offset + // is known at compile time. + return FieldAccess::ConstantDirect; + } else { + // No generic parameter dependencies, but some stored properties + // have unknown size. The field offset is stored in a global constant + // and set up by the Objective-C or Swift runtime, depending on the + // class's heritage. + return FieldAccess::NonConstantDirect; + } + } else { + if (ClassHasFixedFieldCount) { + // Layout depends on generic parameters, but the number of fields + // is known. The field offset is loaded from a fixed offset in the + // field offset vector in type metadata. + return FieldAccess::ConstantIndirect; + } else { + // Layout depends on generic parameters, and the number of fields + // is not known at compile time either. The field index is loaded + // from a global variable set up by the runtime, and then this + // index is used to load the offset from the field offset vector. + return FieldAccess::NonConstantIndirect; + } } } }; } void ClassTypeInfo::generateLayout(IRGenModule &IGM) const { - assert(!Layout && AllStoredProperties.empty() && "already generated layout"); + assert(!Layout && FieldLayout.AllStoredProperties.empty() && + "already generated layout"); // Add the heap header. ClassLayoutBuilder builder(IGM, getClass()); @@ -395,10 +340,7 @@ void ClassTypeInfo::generateLayout(IRGenModule &IGM) const { Layout = new StructLayout(builder, TheClass->getDeclaredTypeInContext()->getCanonicalType(), classTy, builder.getElements()); - AllStoredProperties - = IGM.Context.AllocateCopy(builder.getAllStoredProperties()); - InheritedStoredProperties - = AllStoredProperties.slice(0, builder.getNumInherited()); + FieldLayout = builder.getClassLayout(); } const StructLayout &ClassTypeInfo::getLayout(IRGenModule &IGM) const { @@ -409,24 +351,13 @@ const StructLayout &ClassTypeInfo::getLayout(IRGenModule &IGM) const { return *Layout; } -ArrayRef -ClassTypeInfo::getAllStoredProperties(IRGenModule &IGM) const { - // Return the cached layout if available. - if (Layout) - return AllStoredProperties; - - generateLayout(IGM); - return AllStoredProperties; -} - -ArrayRef -ClassTypeInfo::getInheritedStoredProperties(IRGenModule &IGM) const { +const ClassLayout &ClassTypeInfo::getClassLayout(IRGenModule &IGM) const { // Return the cached layout if available. if (Layout) - return InheritedStoredProperties; + return FieldLayout; generateLayout(IGM); - return InheritedStoredProperties; + return FieldLayout; } /// Cast the base to i8*, apply the given inbounds offset (in bytes, @@ -464,20 +395,6 @@ static OwnedAddress emitAddressAtOffset(IRGenFunction &IGF, return OwnedAddress(addr, base); } -llvm::Constant *irgen::tryEmitClassConstantFragileFieldOffset(IRGenModule &IGM, - ClassDecl *theClass, - VarDecl *field) { - assert(field->hasStorage()); - // FIXME: This field index computation is an ugly hack. - auto &ti = getSelfTypeInfo(IGM, theClass); - - unsigned fieldIndex = getFieldIndex(IGM, theClass, field); - auto &element = ti.getElements(IGM)[fieldIndex]; - if (element.getKind() == ElementLayout::Kind::Fixed) - return IGM.getSize(element.getByteOffset()); - return nullptr; -} - OwnedAddress irgen::projectPhysicalClassMemberAddress(IRGenFunction &IGF, llvm::Value *base, SILType baseType, @@ -491,19 +408,16 @@ OwnedAddress irgen::projectPhysicalClassMemberAddress(IRGenFunction &IGF, auto &baseClassTI = IGF.getTypeInfo(baseType).as(); ClassDecl *baseClass = baseType.getClassOrBoundGenericClass(); - + // TODO: Lay out the class based on the substituted baseType rather than // the generic type. Doing this requires that we also handle // specialized layout in ClassTypeInfo. - LayoutClass layout(IGF.IGM, ResilienceScope::Component, baseClass, - getSelfType(baseClass) /* TODO: should be baseType */); - - auto &entry = layout.getFieldEntry(field); - switch (entry.getAccess()) { - case FieldAccess::ConstantDirect: { - // FIXME: This field index computation is an ugly hack. - unsigned fieldIndex = getFieldIndex(IGF.IGM, baseClass, field); + auto &classLayout = baseClassTI.getClassLayout(IGF.IGM); + unsigned fieldIndex = classLayout.getFieldIndex(field); + + switch (classLayout.AllFieldAccesses[fieldIndex]) { + case FieldAccess::ConstantDirect: { Address baseAddr(base, baseClassTI.getHeapAlignment(IGF.IGM)); auto &element = baseClassTI.getElements(IGF.IGM)[fieldIndex]; Address memberAddr = element.project(IGF, baseAddr, None); @@ -672,7 +586,7 @@ static bool getInstanceSizeByMethod(IRGenFunction &IGF, // Retain 'self' if necessary. if (fnType->getParameters()[0].isConsumed()) { - IGF.emitRetainCall(selfValue); + IGF.emitNativeStrongRetain(selfValue); } // Adjust down to the defining subclass type if necessary. @@ -776,10 +690,11 @@ void IRGenModule::emitClassDecl(ClassDecl *D) { PrettyStackTraceDecl prettyStackTrace("emitting class metadata for", D); auto &classTI = Types.getTypeInfo(D).as(); - auto &layout = classTI.getLayout(*this); // Emit the class metadata. - emitClassMetadata(*this, D, layout); + emitClassMetadata(*this, D, + classTI.getLayout(*this), + classTI.getClassLayout(*this)); emitNestedTypeDecls(D->getMembers()); } @@ -803,8 +718,8 @@ namespace { IRGenModule &IGM; PointerUnion TheEntity; ExtensionDecl *TheExtension; - const LayoutClass *Layout; - const StructLayout *FieldLayout; + const StructLayout *Layout; + const ClassLayout *FieldLayout; ClassDecl *getClass() const { return TheEntity.get(); @@ -823,7 +738,6 @@ namespace { return TheEntity.is(); } - bool Generic = false; bool HasNonTrivialDestructor = false; bool HasNonTrivialConstructor = false; llvm::SmallString<16> CategoryName; @@ -845,15 +759,15 @@ namespace { unsigned NextFieldIndex; public: ClassDataBuilder(IRGenModule &IGM, ClassDecl *theClass, - const LayoutClass &layout, - const StructLayout &fieldLayout, - unsigned firstField) + const StructLayout &layout, + const ClassLayout &fieldLayout) : IGM(IGM), TheEntity(theClass), TheExtension(nullptr), - Layout(&layout), FieldLayout(&fieldLayout), - Generic(theClass->isGenericContext()), - FirstFieldIndex(firstField), - NextFieldIndex(firstField) + Layout(&layout), + FieldLayout(&fieldLayout) { + FirstFieldIndex = fieldLayout.InheritedStoredProperties.size(); + NextFieldIndex = FirstFieldIndex; + visitConformances(theClass); visitMembers(theClass); @@ -866,9 +780,11 @@ namespace { ClassDataBuilder(IRGenModule &IGM, ClassDecl *theClass, ExtensionDecl *theExtension) : IGM(IGM), TheEntity(theClass), TheExtension(theExtension), - Layout(nullptr), FieldLayout(nullptr), - Generic(theClass->isGenericContext()) + Layout(nullptr), FieldLayout(nullptr) { + FirstFieldIndex = -1; + NextFieldIndex = -1; + buildCategoryName(CategoryName); visitConformances(theExtension); @@ -919,7 +835,7 @@ namespace { void buildMetaclassStub() { assert(Layout && "can't build a metaclass from a category"); // The isa is the metaclass pointer for the root class. - auto rootClass = Layout->getRootClassForMetaclass(); + auto rootClass = getRootClassForMetaclass(IGM, TheEntity.get()); auto rootPtr = IGM.getAddrOfMetaclassObject(rootClass, NotForDefinition); // The superclass of the metaclass is the metaclass of the @@ -931,11 +847,7 @@ namespace { llvm::Constant *superPtr; if (getClass()->hasSuperclass()) { auto base = getClass()->getSuperclass()->getClassOrBoundGenericClass(); - // If the base is generic, we'll need to instantiate it at runtime. - if (base->isGenericContext()) - superPtr = llvm::ConstantPointerNull::get(IGM.ObjCClassPtrTy); - else - superPtr = IGM.getAddrOfMetaclassObject(base, NotForDefinition); + superPtr = IGM.getAddrOfMetaclassObject(base, NotForDefinition); } else { superPtr = IGM.getAddrOfMetaclassObject( IGM.getObjCRuntimeBaseForSwiftRootClass(getClass()), @@ -985,7 +897,7 @@ namespace { fields.push_back(IGM.getAddrOfObjCClass(getClass(), NotForDefinition)); else { auto type = getSelfType(getClass()).getSwiftRValueType(); - llvm::Constant *metadata = tryEmitConstantHeapMetadataRef(IGM, type); + llvm::Constant *metadata = tryEmitConstantTypeMetadataRef(IGM, type); assert(metadata && "extended objc class doesn't have constant metadata?"); fields.push_back(metadata); @@ -1049,7 +961,7 @@ namespace { } llvm::Constant *emitRODataFields(ForMetaClass_t forMeta) { - assert(Layout && FieldLayout && "can't emit rodata for a category"); + assert(Layout && "can't emit rodata for a category"); SmallVector fields; // struct _class_ro_t { // uint32_t flags; @@ -1070,14 +982,14 @@ namespace { // historical nonsense instanceStart = instanceSize; } else { - instanceSize = FieldLayout->getSize(); - if (FieldLayout->getElements().empty() - || FieldLayout->getElements().size() == FirstFieldIndex) { + instanceSize = Layout->getSize(); + if (Layout->getElements().empty() + || Layout->getElements().size() == FirstFieldIndex) { instanceStart = instanceSize; - } else if (FieldLayout->getElement(FirstFieldIndex).getKind() + } else if (Layout->getElement(FirstFieldIndex).getKind() == ElementLayout::Kind::Fixed) { // FIXME: assumes layout is always sequential! - instanceStart = FieldLayout->getElement(FirstFieldIndex).getByteOffset(); + instanceStart = Layout->getElement(FirstFieldIndex).getByteOffset(); } else { instanceStart = Size(0); } @@ -1395,7 +1307,7 @@ namespace { /// affect flags. void visitStoredVar(VarDecl *var) { // FIXME: how to handle ivar extensions in categories? - if (!Layout && !FieldLayout) + if (!Layout) return; // For now, we never try to emit specialized versions of the @@ -1418,38 +1330,31 @@ namespace { /// uint32_t size; /// }; llvm::Constant *buildIvar(VarDecl *ivar, SILType loweredType) { - assert(Layout && FieldLayout && "can't build ivar for category"); + assert(Layout && "can't build ivar for category"); // FIXME: this is not always the right thing to do! - auto &elt = FieldLayout->getElement(NextFieldIndex++); + //auto &elt = Layout->getElement(NextFieldIndex++); auto &ivarTI = IGM.getTypeInfo(loweredType); - + llvm::Constant *offsetPtr; - if (elt.getKind() == ElementLayout::Kind::Fixed) { - // Emit a field offset variable for the fixed field statically. + switch (FieldLayout->AllFieldAccesses[NextFieldIndex++]) { + case FieldAccess::ConstantDirect: + case FieldAccess::NonConstantDirect: { + // If the field offset is fixed relative to the start of the superclass, + // reference the global from the ivar metadata so that the Objective-C + // runtime will slide it down. auto offsetAddr = IGM.getAddrOfFieldOffset(ivar, /*indirect*/ false, - ForDefinition); - auto offsetVar = cast(offsetAddr.getAddress()); - offsetVar->setConstant(false); - auto offsetVal = - llvm::ConstantInt::get(IGM.IntPtrTy, elt.getByteOffset().getValue()); - offsetVar->setInitializer(offsetVal); - - offsetPtr = offsetVar; - } else { - // Emit an indirect field offset variable with the field index. - auto offsetAddr = IGM.getAddrOfFieldOffset(ivar, /*indirect*/ true, - ForDefinition); - auto offsetVar = cast(offsetAddr.getAddress()); - offsetVar->setConstant(false); - auto offset = - getClassFieldOffset(IGM, getClass(), ivar).getValue(); - auto offsetVal = - llvm::ConstantInt::get(IGM.IntPtrTy, offset); - offsetVar->setInitializer(offsetVal); - - // We need to set this up when the metadata is instantiated. + NotForDefinition); + offsetPtr = cast(offsetAddr.getAddress()); + break; + } + case FieldAccess::ConstantIndirect: + case FieldAccess::NonConstantIndirect: + // Otherwise, swift_initClassMetadata_UniversalStrategy() will point + // the Objective-C runtime into the field offset vector of the + // instantiated metadata. offsetPtr = llvm::ConstantPointerNull::get(IGM.IntPtrTy->getPointerTo()); + break; } // TODO: clang puts this in __TEXT,__objc_methname,cstring_literals @@ -1776,10 +1681,9 @@ llvm::Constant *irgen::emitClassPrivateData(IRGenModule &IGM, assert(IGM.ObjCInterop && "emitting RO-data outside of interop mode"); SILType selfType = getSelfType(cls); auto &classTI = IGM.getTypeInfo(selfType).as(); - auto &fieldLayout = classTI.getLayout(IGM); - LayoutClass layout(IGM, ResilienceScope::Universal, cls, selfType); - ClassDataBuilder builder(IGM, cls, layout, fieldLayout, - classTI.getInheritedStoredProperties(IGM).size()); + auto &layout = classTI.getLayout(IGM); + auto &fieldLayout = classTI.getClassLayout(IGM); + ClassDataBuilder builder(IGM, cls, layout, fieldLayout); // First, build the metaclass object. builder.buildMetaclassStub(); @@ -1795,10 +1699,9 @@ irgen::emitClassPrivateDataFields(IRGenModule &IGM, ClassDecl *cls) { assert(IGM.ObjCInterop && "emitting RO-data outside of interop mode"); SILType selfType = getSelfType(cls); auto &classTI = IGM.getTypeInfo(selfType).as(); - auto &fieldLayout = classTI.getLayout(IGM); - LayoutClass layout(IGM, ResilienceScope::Universal, cls, selfType); - ClassDataBuilder builder(IGM, cls, layout, fieldLayout, - classTI.getInheritedStoredProperties(IGM).size()); + auto &layout = classTI.getLayout(IGM); + auto &fieldLayout = classTI.getClassLayout(IGM); + ClassDataBuilder builder(IGM, cls, layout, fieldLayout); auto classFields = builder.emitRODataFields(ForClass); auto metaclassFields = builder.emitRODataFields(ForMetaClass); @@ -1888,7 +1791,32 @@ IRGenModule::getObjCRuntimeBaseForSwiftRootClass(ClassDecl *theClass) { } ClassDecl *irgen::getRootClassForMetaclass(IRGenModule &IGM, ClassDecl *C) { - LayoutClass layout(IGM, ResilienceScope::Component, C, getSelfType(C)); + while (auto superclass = C->getSuperclass()) + C = superclass->getClassOrBoundGenericClass(); + + // If the formal root class is imported from Objective-C, then + // we should use that. For a class that's really implemented in + // Objective-C, this is obviously right. For a class that's + // really implemented in Swift, but that we're importing via an + // Objective-C interface, this would be wrong --- except such a + // class can never be a formal root class, because a Swift class + // without a formal superclass will actually be parented by + // SwiftObject (or maybe eventually something else like it), + // which will be visible in the Objective-C type system. + if (C->hasClangNode()) return C; + + // FIXME: If the root class specifies its own runtime ObjC base class, + // assume that that base class ultimately inherits NSObject. + if (C->getAttrs().hasAttribute()) + return IGM.getObjCRuntimeBaseClass(IGM.Context.Id_NSObject); + + return IGM.getObjCRuntimeBaseClass(IGM.Context.Id_SwiftObject); +} - return layout.getRootClassForMetaclass(); +bool irgen::getClassHasMetadataPattern(IRGenModule &IGM, ClassDecl *theClass) { + // Classes imported from Objective-C never have a metadata pattern. + if (theClass->hasClangNode()) + return false; + + return getSelfTypeInfo(IGM, theClass).getClassLayout(IGM).HasMetadataPattern; } diff --git a/lib/IRGen/GenClass.h b/lib/IRGen/GenClass.h index 68b7a3dd8364c..83645ee57618b 100644 --- a/lib/IRGen/GenClass.h +++ b/lib/IRGen/GenClass.h @@ -1,8 +1,8 @@ -//===--- GenStruct.h - Swift IR generation for classes ------------*- C++ -*-===// +//===--- GenClass.h - Swift IR generation for classes -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -58,7 +58,7 @@ namespace irgen { llvm::Constant *emitClassPrivateData(IRGenModule &IGM, ClassDecl *theClass); void emitGenericClassPrivateDataTemplate(IRGenModule &IGM, - ClassDecl *cls, + ClassDecl *theClass, llvm::SmallVectorImpl &fields, Size &metaclassOffset, Size &classRODataOffset, @@ -96,19 +96,12 @@ namespace irgen { /// does not have fixed layout. For resilient classes this does not /// correspond to the runtime alignment of instances of the class. llvm::Constant *tryEmitClassConstantFragileInstanceSize(IRGenModule &IGM, - ClassDecl *Class); + ClassDecl *theClass); /// Emit the constant fragile instance alignment mask of the class, or null if /// the class does not have fixed layout. For resilient classes this does not /// correspond to the runtime alignment of instances of the class. llvm::Constant *tryEmitClassConstantFragileInstanceAlignMask(IRGenModule &IGM, - ClassDecl *Class); - - /// Emit the constant fragile byte offset for the field in the class, or null - /// if the field does not have fixed layout. For resilient classes this does - /// not correspond to the runtime offset of the field. - llvm::Constant *tryEmitClassConstantFragileFieldOffset(IRGenModule &IGM, - ClassDecl *theClass, - VarDecl *field); + ClassDecl *theClass); /// What reference counting mechanism does a class use? ReferenceCounting getReferenceCountingForClass(IRGenModule &IGM, @@ -117,7 +110,9 @@ namespace irgen { /// What isa-encoding mechanism does a type use? IsaEncoding getIsaEncodingForType(IRGenModule &IGM, CanType type); - ClassDecl *getRootClassForMetaclass(IRGenModule &IGM, ClassDecl *C); + ClassDecl *getRootClassForMetaclass(IRGenModule &IGM, ClassDecl *theClass); + + bool getClassHasMetadataPattern(IRGenModule &IGM, ClassDecl *theClass); } // end namespace irgen } // end namespace swift diff --git a/lib/IRGen/GenControl.cpp b/lib/IRGen/GenControl.cpp index 8a88603cf4ce9..e35716a62bae8 100644 --- a/lib/IRGen/GenControl.cpp +++ b/lib/IRGen/GenControl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenCoverage.cpp b/lib/IRGen/GenCoverage.cpp index 29b172a5ea4cd..eb7b57bddcabc 100644 --- a/lib/IRGen/GenCoverage.cpp +++ b/lib/IRGen/GenCoverage.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index e98663f08961f..06164d4ed619c 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -106,7 +106,7 @@ class CategoryInitializerVisitor class_addProtocol = IGM.getClassAddProtocolFn(); CanType origTy = ext->getDeclaredTypeOfContext()->getCanonicalType(); - classMetadata = tryEmitConstantHeapMetadataRef(IGM, origTy); + classMetadata = tryEmitConstantTypeMetadataRef(IGM, origTy); assert(classMetadata && "extended objc class doesn't have constant metadata?!"); classMetadata = llvm::ConstantExpr::getBitCast(classMetadata, @@ -461,10 +461,10 @@ void IRGenModule::emitSourceFile(SourceFile &SF, unsigned StartElem) { /// metadata or runtime purposes. static llvm::GlobalVariable * emitGlobalList(IRGenModule &IGM, ArrayRef handles, - StringRef name, StringRef section, - llvm::GlobalValue::LinkageTypes linkage, - llvm::Type *eltTy, - bool isConstant) { + StringRef name, StringRef section, + llvm::GlobalValue::LinkageTypes linkage, + llvm::Type *eltTy, + bool isConstant) { // Do nothing if the list is empty. if (handles.empty()) return nullptr; @@ -685,11 +685,12 @@ void IRGenModule::emitGlobalLists() { ExistingLLVMUsed->eraseFromParent(); } - assert(std::all_of(LLVMUsed.begin(), LLVMUsed.end(), - [](const llvm::WeakVH &global) { - return !isa(global) || - !cast(global)->isDeclaration(); - }) && "all globals in the 'used' list must be definitions"); + std::for_each(LLVMUsed.begin(), LLVMUsed.end(), + [](const llvm::WeakVH &global) { + assert(!isa(global) || + !cast(global)->isDeclaration() && + "all globals in the 'used' list must be definitions"); + }); emitGlobalList(*this, LLVMUsed, "llvm.used", "llvm.metadata", llvm::GlobalValue::AppendingLinkage, Int8PtrTy, @@ -743,7 +744,7 @@ void IRGenModuleDispatcher::emitGlobalTopLevel() { } void IRGenModule::finishEmitAfterTopLevel() { - // Emit the implicit import of the swift standard libary. + // Emit the implicit import of the swift standard library. if (DebugInfo) { std::pair AccessPath[] = { { Context.StdlibModuleName, swift::SourceLoc() } @@ -832,7 +833,7 @@ void IRGenModule::emitVTableStubs() { continue; if (!stub) { - // Create a single stub function which calls swift_reportMissingMethod(). + // Create a single stub function which calls swift_deletedMethodError(). stub = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false), llvm::GlobalValue::LinkOnceODRLinkage, "_swift_dead_method_stub"); @@ -841,7 +842,7 @@ void IRGenModule::emitVTableStubs() { stub->setVisibility(llvm::GlobalValue::HiddenVisibility); stub->setCallingConv(RuntimeCC); auto *entry = llvm::BasicBlock::Create(getLLVMContext(), "entry", stub); - auto *errorFunc = getDeadMethodErrorFn(); + auto *errorFunc = getDeletedMethodErrorFn(); llvm::CallInst::Create(errorFunc, ArrayRef(), "", entry); new llvm::UnreachableInst(getLLVMContext(), entry); } @@ -997,9 +998,8 @@ SILLinkage LinkEntity::getLinkage(IRGenModule &IGM, case MetadataAccessStrategy::PrivateAccessor: return getSILLinkage(FormalLinkage::Private, forDefinition); case MetadataAccessStrategy::NonUniqueAccessor: - return SILLinkage::Shared; case MetadataAccessStrategy::Direct: - llvm_unreachable("metadata accessor for type with direct access?"); + return SILLinkage::Shared; } llvm_unreachable("bad metadata access kind"); @@ -1016,7 +1016,6 @@ SILLinkage LinkEntity::getLinkage(IRGenModule &IGM, case Kind::DirectProtocolWitnessTable: case Kind::ProtocolWitnessTableAccessFunction: - case Kind::DependentProtocolWitnessTableGenerator: return getConformanceLinkage(IGM, getProtocolConformance()); case Kind::ProtocolWitnessTableLazyAccessFunction: @@ -1029,7 +1028,10 @@ SILLinkage LinkEntity::getLinkage(IRGenModule &IGM, return SILLinkage::Shared; } - case Kind::DependentProtocolWitnessTableTemplate: + case Kind::AssociatedTypeMetadataAccessFunction: + case Kind::AssociatedTypeWitnessTableAccessFunction: + case Kind::GenericProtocolWitnessTableCache: + case Kind::GenericProtocolWitnessTableInstantiationFunction: return SILLinkage::Private; case Kind::SILFunction: @@ -1049,8 +1051,7 @@ bool LinkEntity::isFragile(IRGenModule &IGM) const { case Kind::SILGlobalVariable: return getSILGlobalVariable()->isFragile(); - case Kind::DirectProtocolWitnessTable: - case Kind::DependentProtocolWitnessTableGenerator: { + case Kind::DirectProtocolWitnessTable: { auto wt = IGM.SILMod->lookUpWitnessTable(getProtocolConformance()); if (wt.first) { return wt.first->isFragile(); @@ -1563,7 +1564,7 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity, Alignment alignment, defaultType, debugType); } -/// Get or create a llvm::GlobalVariable. +/// Get or create an llvm::GlobalVariable. /// /// If a definition type is given, the result will always be an /// llvm::GlobalVariable of that type. Otherwise, the result will @@ -1807,33 +1808,51 @@ static llvm::Constant *emitRelativeReference(IRGenModule &IGM, llvm::Constant *base, unsigned arrayIndex, unsigned structIndex) { - auto targetAddr = llvm::ConstantExpr::getPtrToInt(target.first, IGM.SizeTy); + llvm::Constant *relativeAddr = + IGM.emitDirectRelativeReference(target.first, base, + { arrayIndex, structIndex }); + + // If the reference is to a GOT entry, flag it by setting the low bit. + // (All of the base, direct target, and GOT entry need to be pointer-aligned + // for this to be OK.) + if (target.second == IRGenModule::DirectOrGOT::GOT) { + relativeAddr = llvm::ConstantExpr::getAdd(relativeAddr, + llvm::ConstantInt::get(IGM.RelativeAddressTy, 1)); + } - llvm::Constant *indexes[] = { - llvm::ConstantInt::get(IGM.Int32Ty, 0), - llvm::ConstantInt::get(IGM.Int32Ty, arrayIndex), - llvm::ConstantInt::get(IGM.Int32Ty, structIndex), + return relativeAddr; +} + +/// Form an LLVM constant for the relative distance between a reference +/// (appearing at gep (0, indices...) of `base`) and `target`. For now, +/// for this to succeed portably, both need to be globals defined in the +/// current translation unit. +llvm::Constant * +IRGenModule::emitDirectRelativeReference(llvm::Constant *target, + llvm::Constant *base, + ArrayRef baseIndices) { + // Convert the target to an integer. + auto targetAddr = llvm::ConstantExpr::getPtrToInt(target, SizeTy); + + SmallVector indices; + indices.push_back(llvm::ConstantInt::get(Int32Ty, 0)); + for (unsigned baseIndex : baseIndices) { + indices.push_back(llvm::ConstantInt::get(Int32Ty, baseIndex)); }; + // Drill down to the appropriate address in the base, then convert + // that to an integer. auto baseElt = llvm::ConstantExpr::getInBoundsGetElementPtr( - base->getType()->getPointerElementType(), base, indexes); - - auto baseAddr = llvm::ConstantExpr::getPtrToInt(baseElt, IGM.SizeTy); + base->getType()->getPointerElementType(), base, indices); + auto baseAddr = llvm::ConstantExpr::getPtrToInt(baseElt, SizeTy); + // The relative address is the difference between those. auto relativeAddr = llvm::ConstantExpr::getSub(targetAddr, baseAddr); // Relative addresses can be 32-bit even on 64-bit platforms. - if (IGM.SizeTy != IGM.RelativeAddressTy) + if (SizeTy != RelativeAddressTy) relativeAddr = llvm::ConstantExpr::getTrunc(relativeAddr, - IGM.RelativeAddressTy); - - // If the reference is to a GOT entry, flag it by setting the low bit. - // (All of the base, direct target, and GOT entry need to be pointer-aligned - // for this to be OK.) - if (target.second == IRGenModule::DirectOrGOT::GOT) { - relativeAddr = llvm::ConstantExpr::getAdd(relativeAddr, - llvm::ConstantInt::get(IGM.Int32Ty, 1)); - } + RelativeAddressTy); return relativeAddr; } @@ -2588,7 +2607,14 @@ StringRef IRGenModule::mangleType(CanType type, SmallVectorImpl &buffer) { return StringRef(buffer.data(), buffer.size()); } -/// Is the given declaration resilient? +/// Do we have to use resilient access patterns when working with this +/// declaration? +/// +/// IRGen is primarily concerned with resilient handling of the following: +/// - For structs, a struct's size might change +/// - For enums, new cases can be added +/// - For classes, the superclass might change the size or number +/// of stored properties bool IRGenModule::isResilient(Decl *D, ResilienceScope scope) { auto NTD = dyn_cast(D); if (!NTD) @@ -2604,6 +2630,66 @@ bool IRGenModule::isResilient(Decl *D, ResilienceScope scope) { llvm_unreachable("Bad resilience scope"); } +// The most general resilience scope where the given declaration is visible. +ResilienceScope IRGenModule::getResilienceScopeForAccess(NominalTypeDecl *decl) { + if (decl->getModuleContext() == SILMod->getSwiftModule() && + decl->getFormalAccess() != Accessibility::Public) + return ResilienceScope::Component; + return ResilienceScope::Universal; +} + +// The most general resilience scope which has knowledge of the declaration's +// layout. Calling isResilient() with this scope will always return false. +ResilienceScope IRGenModule::getResilienceScopeForLayout(NominalTypeDecl *decl) { + if (isResilient(decl, ResilienceScope::Universal)) + return ResilienceScope::Component; + + return getResilienceScopeForAccess(decl); +} + +llvm::Constant *IRGenModule:: +getAddrOfGenericWitnessTableCache(const NormalProtocolConformance *conf, + ForDefinition_t forDefinition) { + auto entity = LinkEntity::forGenericProtocolWitnessTableCache(conf); + auto expectedTy = getGenericWitnessTableCacheTy(); + auto storageTy = (forDefinition ? expectedTy : nullptr); + return getAddrOfLLVMVariable(entity, getPointerAlignment(), storageTy, + expectedTy, DebugTypeInfo()); +} + +llvm::Function * +IRGenModule::getAddrOfGenericWitnessTableInstantiationFunction( + const NormalProtocolConformance *conf) { + auto forDefinition = ForDefinition; + + LinkEntity entity = + LinkEntity::forGenericProtocolWitnessTableInstantiationFunction(conf); + llvm::Function *&entry = GlobalFuncs[entity]; + if (entry) { + if (forDefinition) updateLinkageForDefinition(*this, entry, entity); + return entry; + } + + auto fnType = llvm::FunctionType::get(VoidTy, + { WitnessTablePtrTy, + TypeMetadataPtrTy, + Int8PtrPtrTy }, + /*varargs*/ false); + LinkInfo link = LinkInfo::get(*this, entity, forDefinition); + entry = link.createFunction(*this, fnType, RuntimeCC, llvm::AttributeSet()); + return entry; +} + +llvm::StructType *IRGenModule::getGenericWitnessTableCacheTy() { + if (auto ty = GenericWitnessTableCacheTy) return ty; + + GenericWitnessTableCacheTy = llvm::StructType::create(getLLVMContext(), + { Int16Ty, Int16Ty, RelativeAddressTy, RelativeAddressTy, + llvm::ArrayType::get(Int8PtrTy, swift::NumGenericMetadataPrivateDataWords) + }, "swift.generic_witness_table_cache"); + return GenericWitnessTableCacheTy; +} + /// Fetch the witness table access function for a protocol conformance. llvm::Function * IRGenModule::getAddrOfWitnessTableAccessFunction( @@ -2680,6 +2766,50 @@ IRGenModule::getAddrOfWitnessTable(const NormalProtocolConformance *conf, WitnessTableTy, DebugTypeInfo()); } +llvm::Function * +IRGenModule::getAddrOfAssociatedTypeMetadataAccessFunction( + const NormalProtocolConformance *conformance, + AssociatedTypeDecl *associate) { + auto forDefinition = ForDefinition; + + LinkEntity entity = + LinkEntity::forAssociatedTypeMetadataAccessFunction(conformance, associate); + llvm::Function *&entry = GlobalFuncs[entity]; + if (entry) { + if (forDefinition) updateLinkageForDefinition(*this, entry, entity); + return entry; + } + + auto fnType = getAssociatedTypeMetadataAccessFunctionTy(); + LinkInfo link = LinkInfo::get(*this, entity, forDefinition); + entry = link.createFunction(*this, fnType, RuntimeCC, llvm::AttributeSet()); + return entry; +} + +llvm::Function * +IRGenModule::getAddrOfAssociatedTypeWitnessTableAccessFunction( + const NormalProtocolConformance *conformance, + AssociatedTypeDecl *associate, + ProtocolDecl *associateProtocol) { + auto forDefinition = ForDefinition; + + assert(conformance->getProtocol() == associate->getProtocol()); + LinkEntity entity = + LinkEntity::forAssociatedTypeWitnessTableAccessFunction(conformance, + associate, + associateProtocol); + llvm::Function *&entry = GlobalFuncs[entity]; + if (entry) { + if (forDefinition) updateLinkageForDefinition(*this, entry, entity); + return entry; + } + + auto fnType = getAssociatedTypeWitnessTableAccessFunctionTy(); + LinkInfo link = LinkInfo::get(*this, entity, forDefinition); + entry = link.createFunction(*this, fnType, RuntimeCC, llvm::AttributeSet()); + return entry; +} + /// Should we be defining the given helper function? static llvm::Function *shouldDefineHelper(IRGenModule &IGM, llvm::Constant *fn) { diff --git a/lib/IRGen/GenEnum.cpp b/lib/IRGen/GenEnum.cpp index 2fe078ed536ef..5e394c9206327 100644 --- a/lib/IRGen/GenEnum.cpp +++ b/lib/IRGen/GenEnum.cpp @@ -1,8 +1,8 @@ -//===--- GenEnum.cpp - Swift IR Generation For 'enum' Types -------------===// +//===--- GenEnum.cpp - Swift IR Generation For 'enum' Types ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -161,6 +161,10 @@ llvm::Constant *EnumImplStrategy::emitCaseNames() const { return IGM.getAddrOfGlobalString(fieldNames); } +unsigned EnumImplStrategy::getPayloadSizeForMetadata() const { + llvm_unreachable("don't need payload size for this enum kind"); +} + llvm::Value *irgen::EnumImplStrategy:: loadRefcountedPtr(IRGenFunction &IGF, SourceLoc loc, Address addr) const { IGF.IGM.error(loc, "Can only load from an address of an optional " @@ -357,6 +361,13 @@ namespace { EnumElementDecl *Case) const override { // No tag, nothing to do. } + + void emitStoreTag(IRGenFunction &IGF, + SILType T, + Address enumAddr, + llvm::Value *tag) const override { + // No tag, nothing to do. + } void getSchema(ExplosionSchema &schema) const override { if (!getSingleton()) return; @@ -550,6 +561,7 @@ namespace { IGF.Builder.CreateCondBr(xiBool, xiBB, noXIBB); IGF.Builder.emitBlock(xiBB); + ConditionalDominanceScope condition(IGF); copyWitnessFromElt(ValueWitness::ExtraInhabitantFlags); IGF.Builder.CreateBr(noXIBB); @@ -769,6 +781,22 @@ namespace { = IGF.Builder.CreateStructGEP(enumAddr, 0, Size(0)); IGF.Builder.CreateStore(discriminator, discriminatorAddr); } + + void emitStoreTag(IRGenFunction &IGF, + SILType T, + Address enumAddr, + llvm::Value *tag) const override { + // FIXME: We need to do a tag-to-discriminator mapping here, but really + // the only case where this is not one-to-one is with C-compatible enums, + // and those cannot be resilient anyway so it doesn't matter for now. + // However, we will need to fix this if we want to use InjectEnumTag + // value witnesses for write reflection. + llvm::Value *discriminator + = IGF.Builder.CreateIntCast(tag, getDiscriminatorType(), /*signed*/false); + Address discriminatorAddr + = IGF.Builder.CreateStructGEP(enumAddr, 0, Size(0)); + IGF.Builder.CreateStore(discriminator, discriminatorAddr); + } void initializeMetadata(IRGenFunction &IGF, llvm::Value *metadata, @@ -1516,13 +1544,20 @@ namespace { std::tie(payloadTag, extraTag) = getNoPayloadCaseValue(Case); auto &ti = getFixedPayloadTypeInfo(); - bool hasExtraInhabitants = ti.getFixedExtraInhabitantCount(IGF.IGM) > 0; - + llvm::Value *payloadResult = nullptr; - if (hasExtraInhabitants) - payloadResult = payload.emitCompare(IGF, + // We can omit the payload check if this is the only case represented with + // the particular extra tag bit pattern set. + // + // TODO: This logic covers the most common case, when there's exactly one + // more no-payload case than extra inhabitants in the payload. This could + // be slightly generalized to cases where there's multiple tag bits and + // exactly one no-payload case in the highest used tag value. + if (!tagBits || + ElementsWithNoPayload.size() != getFixedExtraInhabitantCount(IGF.IGM)+1) + payloadResult = payload.emitCompare(IGF, ti.getFixedExtraInhabitantMask(IGF.IGM), - payloadTag); + payloadTag); // If any tag bits are present, they must match. llvm::Value *tagResult = nullptr; @@ -1998,7 +2033,7 @@ namespace { llvm::Value *ptr) const { switch (CopyDestroyKind) { case NullableRefcounted: - IGF.emitScalarRetainCall(ptr, Refcounting); + IGF.emitStrongRetain(ptr, Refcounting); return; case POD: case Normal: @@ -2022,7 +2057,7 @@ namespace { llvm::Value *ptr) const { switch (CopyDestroyKind) { case NullableRefcounted: - IGF.emitScalarRelease(ptr, Refcounting); + IGF.emitStrongRelease(ptr, Refcounting); return; case POD: case Normal: @@ -2049,6 +2084,7 @@ namespace { llvm::BasicBlock *endBB = testFixedEnumContainsPayload(IGF, payload, extraTag); if (PayloadBitCount > 0) { + ConditionalDominanceScope condition(IGF); Explosion payloadValue; Explosion payloadCopy; auto &loadableTI = getLoadablePayloadTypeInfo(); @@ -2097,6 +2133,7 @@ namespace { // If we did, consume it. if (PayloadBitCount > 0) { + ConditionalDominanceScope condition(IGF); Explosion payloadValue; auto &loadableTI = getLoadablePayloadTypeInfo(); loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0); @@ -2139,6 +2176,7 @@ namespace { // If we did, consume it. if (PayloadBitCount > 0) { + ConditionalDominanceScope condition(IGF); Explosion payloadValue; auto &loadableTI = getLoadablePayloadTypeInfo(); loadableTI.unpackFromEnumPayload(IGF, payload, payloadValue, 0); @@ -2171,6 +2209,8 @@ namespace { // Check that there is a payload at the address. llvm::BasicBlock *endBB = testEnumContainsPayload(IGF, addr, T); + ConditionalDominanceScope condition(IGF); + // If there is, project and destroy it. Address payloadAddr = projectPayloadData(IGF, addr); getPayloadTypeInfo().destroy(IGF, payloadAddr, @@ -2232,7 +2272,7 @@ namespace { ElementsWithNoPayload.size())}); } - /// Emit an reassignment sequence from an enum at one address to another. + /// Emit a reassignment sequence from an enum at one address to another. void emitIndirectAssign(IRGenFunction &IGF, Address dest, Address src, SILType T, IsTake_t isTake) @@ -2254,46 +2294,64 @@ namespace { llvm::BasicBlock *noDestPayloadBB = testEnumContainsPayload(IGF, dest, T); - // Here, the destination has a payload. Now see if the source also has - // one. - llvm::BasicBlock *destNoSrcPayloadBB - = testEnumContainsPayload(IGF, src, T); + { + ConditionalDominanceScope destCondition(IGF); - // Here, both source and destination have payloads. Do the reassignment - // of the payload in-place. - if (isTake) - getPayloadTypeInfo().assignWithTake(IGF, destData, srcData, PayloadT); - else - getPayloadTypeInfo().assignWithCopy(IGF, destData, srcData, PayloadT); - IGF.Builder.CreateBr(endBB); + // Here, the destination has a payload. Now see if the source also + // has one. + llvm::BasicBlock *destNoSrcPayloadBB + = testEnumContainsPayload(IGF, src, T); - // If the destination has a payload but the source doesn't, we can destroy - // the payload and primitive-store the new no-payload value. - IGF.Builder.emitBlock(destNoSrcPayloadBB); - getPayloadTypeInfo().destroy(IGF, destData, PayloadT); - emitPrimitiveCopy(IGF, dest, src, T); - IGF.Builder.CreateBr(endBB); + { + ConditionalDominanceScope destSrcCondition(IGF); + + // Here, both source and destination have payloads. Do the + // reassignment of the payload in-place. + getPayloadTypeInfo().assign(IGF, destData, srcData, + isTake, PayloadT); + IGF.Builder.CreateBr(endBB); + } + + // If the destination has a payload but the source doesn't, we can + // destroy the payload and primitive-store the new no-payload value. + IGF.Builder.emitBlock(destNoSrcPayloadBB); + { + ConditionalDominanceScope destNoSrcCondition(IGF); + getPayloadTypeInfo().destroy(IGF, destData, PayloadT); + emitPrimitiveCopy(IGF, dest, src, T); + IGF.Builder.CreateBr(endBB); + } + } // Now, if the destination has no payload, check if the source has one. IGF.Builder.emitBlock(noDestPayloadBB); - llvm::BasicBlock *noDestNoSrcPayloadBB - = testEnumContainsPayload(IGF, src, T); - - // Here, the source has a payload but the destination doesn't. We can - // copy-initialize the source over the destination, then primitive-store - // the zero extra tag (if any). - if (isTake) - getPayloadTypeInfo().initializeWithTake(IGF, destData, srcData, PayloadT); - else - getPayloadTypeInfo().initializeWithCopy(IGF, destData, srcData, PayloadT); - emitInitializeExtraTagBitsForPayload(IGF, dest, T); - IGF.Builder.CreateBr(endBB); + { + ConditionalDominanceScope noDestCondition(IGF); + llvm::BasicBlock *noDestNoSrcPayloadBB + = testEnumContainsPayload(IGF, src, T); + + { + ConditionalDominanceScope noDestSrcCondition(IGF); + + // Here, the source has a payload but the destination doesn't. + // We can copy-initialize the source over the destination, then + // primitive-store the zero extra tag (if any). + + getPayloadTypeInfo().initialize(IGF, destData, srcData, isTake, + PayloadT); + emitInitializeExtraTagBitsForPayload(IGF, dest, T); + IGF.Builder.CreateBr(endBB); + } - // If neither destination nor source have payloads, we can just primitive- - // store the new empty-case value. - IGF.Builder.emitBlock(noDestNoSrcPayloadBB); - emitPrimitiveCopy(IGF, dest, src, T); - IGF.Builder.CreateBr(endBB); + // If neither destination nor source have payloads, we can just + // primitive- store the new empty-case value. + IGF.Builder.emitBlock(noDestNoSrcPayloadBB); + { + ConditionalDominanceScope noDestNoSrcCondition(IGF); + emitPrimitiveCopy(IGF, dest, src, T); + IGF.Builder.CreateBr(endBB); + } + } IGF.Builder.emitBlock(endBB); return; @@ -2343,22 +2401,25 @@ namespace { llvm::BasicBlock *noSrcPayloadBB = testEnumContainsPayload(IGF, src, T); - // Here, the source value has a payload. Initialize the destination with - // it, and set the extra tag if any to zero. - if (isTake) - getPayloadTypeInfo().initializeWithTake(IGF, destData, srcData, - getPayloadType(IGF.IGM, T)); - else - getPayloadTypeInfo().initializeWithCopy(IGF, destData, srcData, - getPayloadType(IGF.IGM, T)); - emitInitializeExtraTagBitsForPayload(IGF, dest, T); - IGF.Builder.CreateBr(endBB); + { + ConditionalDominanceScope condition(IGF); + + // Here, the source value has a payload. Initialize the destination + // with it, and set the extra tag if any to zero. + getPayloadTypeInfo().initialize(IGF, destData, srcData, isTake, + getPayloadType(IGF.IGM, T)); + emitInitializeExtraTagBitsForPayload(IGF, dest, T); + IGF.Builder.CreateBr(endBB); + } // If the source value has no payload, we can primitive-store the // empty-case value. IGF.Builder.emitBlock(noSrcPayloadBB); - emitPrimitiveCopy(IGF, dest, src, T); - IGF.Builder.CreateBr(endBB); + { + ConditionalDominanceScope condition(IGF); + emitPrimitiveCopy(IGF, dest, src, T); + IGF.Builder.CreateBr(endBB); + } IGF.Builder.emitBlock(endBB); return; @@ -2461,6 +2522,24 @@ namespace { projectExtraTagBits(IGF, enumAddr)); } + void emitStoreTag(IRGenFunction &IGF, + SILType T, + Address enumAddr, + llvm::Value *tag) const override { + llvm::Value *payload = emitPayloadMetadataForLayout(IGF, T); + llvm::Value *caseIndex = IGF.Builder.CreateSub(tag, + llvm::ConstantInt::getSigned(IGF.IGM.Int32Ty, 1)); + llvm::Value *numEmptyCases = llvm::ConstantInt::get(IGF.IGM.Int32Ty, + ElementsWithNoPayload.size()); + + llvm::Value *opaqueAddr + = IGF.Builder.CreateBitCast(enumAddr.getAddress(), + IGF.IGM.OpaquePtrTy); + + IGF.Builder.CreateCall(IGF.IGM.getStoreEnumTagSinglePayloadFn(), + {opaqueAddr, payload, caseIndex, numEmptyCases}); + } + void initializeMetadata(IRGenFunction &IGF, llvm::Value *metadata, llvm::Value *vwtable, @@ -2631,6 +2710,10 @@ namespace { // The number of tag values used for no-payload cases. unsigned NumEmptyElementTags = ~0u; + // The payload size in bytes. This might need to be written to metadata + // if it depends on resilient types. + unsigned PayloadSize; + /// More efficient value semantics implementations for certain enum layouts. enum CopyDestroyStrategy { /// No special behavior. @@ -2651,6 +2734,7 @@ namespace { CopyDestroyStrategy CopyDestroyKind; ReferenceCounting Refcounting; + bool AllowFixedLayoutOptimizations; static EnumPayloadSchema getPayloadSchema(ArrayRef payloads) { // TODO: We might be able to form a nicer schema if the payload elements @@ -2670,6 +2754,7 @@ namespace { MultiPayloadEnumImplStrategy(IRGenModule &IGM, TypeInfoKind tik, IsFixedSize_t alwaysFixedSize, + bool allowFixedLayoutOptimizations, unsigned NumElements, std::vector &&WithPayload, std::vector &&WithNoPayload) @@ -2678,7 +2763,8 @@ namespace { std::move(WithPayload), std::move(WithNoPayload), getPayloadSchema(WithPayload)), - CopyDestroyKind(Normal) + CopyDestroyKind(Normal), + AllowFixedLayoutOptimizations(allowFixedLayoutOptimizations) { assert(ElementsWithPayload.size() > 1); @@ -2733,7 +2819,17 @@ namespace { // the payload area size from all of the cases, so cache it in the // metadata. For fixed-layout cases this isn't necessary (except for // reflection, but it's OK if reflection is a little slow). - return TIK < Fixed; + // + // Note that even if from within our module the enum has a fixed layout, + // we might need the payload size if from another module the enum has + // a dynamic size, which can happen if the enum contains a resilient + // payload. + return !AllowFixedLayoutOptimizations; + } + + unsigned getPayloadSizeForMetadata() const override { + assert(TIK >= Fixed); + return PayloadSize; } TypeInfo *completeEnumTypeLayout(TypeConverter &TC, @@ -2808,7 +2904,7 @@ namespace { llvm::Value *ptr) const { switch (CopyDestroyKind) { case TaggedRefcounted: - IGF.emitScalarRetainCall(ptr, Refcounting); + IGF.emitStrongRetain(ptr, Refcounting); return; case POD: case BitwiseTakable: @@ -2834,7 +2930,7 @@ namespace { llvm::Value *ptr) const { switch (CopyDestroyKind) { case TaggedRefcounted: - IGF.emitScalarRelease(ptr, Refcounting); + IGF.emitStrongRelease(ptr, Refcounting); return; case POD: case BitwiseTakable: @@ -2843,21 +2939,38 @@ namespace { } } + /// Pack tag into spare bits and tagIndex into payload bits. APInt getEmptyCasePayload(IRGenModule &IGM, - unsigned tagIndex, - unsigned idx) const { + unsigned tag, + unsigned tagIndex) const { // The payload may be empty. if (CommonSpareBits.empty()) return APInt(); APInt v = interleaveSpareBits(IGM, PayloadTagBits, PayloadTagBits.size(), - tagIndex, 0); + tag, 0); v |= interleaveSpareBits(IGM, CommonSpareBits, CommonSpareBits.size(), - 0, idx); + 0, tagIndex); return v; } + + /// Pack tag into spare bits and tagIndex into payload bits. + EnumPayload getEmptyCasePayload(IRGenFunction &IGF, + llvm::Value *tag, + llvm::Value *tagIndex) const { + SpareBitVector commonSpareBits = CommonSpareBits; + commonSpareBits.flipAll(); + + EnumPayload result = interleaveSpareBits(IGF, PayloadSchema, + commonSpareBits, tagIndex); + result.emitApplyOrMask(IGF, + interleaveSpareBits(IGF, PayloadSchema, + PayloadTagBits, tag)); + + return result; + } struct DestructuredLoadableEnum { EnumPayload payload; @@ -3359,10 +3472,15 @@ namespace { // Figure out the tag and payload for the empty case. unsigned numCaseBits = getNumCaseBits(); unsigned tag, tagIndex; - if (numCaseBits >= 32) { + if (numCaseBits >= 32 || + getNumCasesPerTag() >= ElementsWithNoPayload.size()) { + // All no-payload cases have the same payload tag, so we can just use + // the payload value to distinguish between no-payload cases. tag = ElementsWithPayload.size(); tagIndex = index; } else { + // The no-payload cases are distributed between multiple payload tags; + // combine the payload tag with the payload value. tag = (index >> numCaseBits) + ElementsWithPayload.size(); tagIndex = index & ((1 << numCaseBits) - 1); } @@ -3371,17 +3489,65 @@ namespace { APInt extraTag; unsigned numSpareBits = CommonSpareBits.count(); if (numSpareBits > 0) { - // If we have spare bits, pack tag bits into them. + // If we have spare bits, pack the tag into the spare bits and + // the tagIndex into the payload. payload = getEmptyCasePayload(IGM, tag, tagIndex); } else if (CommonSpareBits.size() > 0) { // Otherwise the payload is just the index. payload = APInt(CommonSpareBits.size(), tagIndex); } - // If we have extra tag bits, pack the remaining tag bits into them. + // If the tag bits do not fit in the spare bits, the remaining tag bits + // are the extra tag bits. + if (ExtraTagBitCount > 0) + extraTag = APInt(ExtraTagBitCount, tag >> numSpareBits); + + return {payload, extraTag}; + } + + std::pair + getNoPayloadCaseValue(IRGenFunction &IGF, llvm::Value *index) const { + // Split the case index into two pieces, the tag and tag index. + unsigned numCaseBits = getNumCaseBits(); + + llvm::Value *tag; + llvm::Value *tagIndex; + if (numCaseBits >= 32 || + getNumCasesPerTag() >= ElementsWithNoPayload.size()) { + // All no-payload cases have the same payload tag, so we can just use + // the payload value to distinguish between no-payload cases. + tag = llvm::ConstantInt::get(IGM.Int32Ty, ElementsWithPayload.size()); + tagIndex = index; + } else { + // The no-payload cases are distributed between multiple payload tags. + tag = IGF.Builder.CreateAdd( + IGF.Builder.CreateLShr(index, + llvm::ConstantInt::get(IGM.Int32Ty, numCaseBits)), + llvm::ConstantInt::get(IGM.Int32Ty, ElementsWithPayload.size())); + tagIndex = IGF.Builder.CreateAnd(index, + llvm::ConstantInt::get(IGM.Int32Ty, ((1 << numCaseBits) - 1))); + } + + EnumPayload payload; + llvm::Value *extraTag; + unsigned numSpareBits = CommonSpareBits.count(); + if (numSpareBits > 0) { + // If we have spare bits, pack the tag into the spare bits and + // the tagIndex into the payload. + payload = getEmptyCasePayload(IGF, tag, tagIndex); + } else if (CommonSpareBits.size() > 0) { + // Otherwise the payload is just the index. + payload = EnumPayload::zero(IGM, PayloadSchema); + payload.insertValue(IGF, tagIndex, 0); + } + + // If the tag bits do not fit in the spare bits, the remaining tag bits + // are the extra tag bits. if (ExtraTagBitCount > 0) { - tag >>= numSpareBits; - extraTag = APInt(ExtraTagBitCount, tag); + extraTag = tag; + if (numSpareBits > 0) + extraTag = IGF.Builder.CreateLShr(tag, + llvm::ConstantInt::get(IGM.Int32Ty, numSpareBits)); } return {payload, extraTag}; } @@ -3422,6 +3588,8 @@ namespace { auto *caseBB = llvm::BasicBlock::Create(IGF.IGM.getLLVMContext()); swi->addCase(llvm::ConstantInt::get(tagTy, tagIndex), caseBB); + ConditionalDominanceScope condition(IGF); + IGF.Builder.emitBlock(caseBB); f(tagIndex, payloadCasePair); IGF.Builder.CreateBr(endBB); @@ -3626,6 +3794,7 @@ namespace { auto *noAliasBB = llvm::BasicBlock::Create(C); IGF.Builder.CreateCondBr(alias, endBB, noAliasBB); IGF.Builder.emitBlock(noAliasBB); + ConditionalDominanceScope condition(IGF); // Destroy the old value. destroy(IGF, dest, T); @@ -3704,6 +3873,8 @@ namespace { swi->addCase(llvm::ConstantInt::get(tagTy, tagIndex), caseBB); IGF.Builder.emitBlock(caseBB); + ConditionalDominanceScope condition(IGF); + // Do the take/copy of the payload. Address srcData = IGF.Builder.CreateBitCast(src, payloadTI.getStorageType()->getPointerTo()); @@ -3716,7 +3887,12 @@ namespace { payloadTI.initializeWithCopy(IGF, destData, srcData, PayloadT); // Plant spare bit tag bits, if any, into the new value. - storePayloadTag(IGF, dest, tagIndex, T); + llvm::Value *tag = llvm::ConstantInt::get(IGF.IGM.Int32Ty, tagIndex); + if (TIK < Fixed) + storeDynamicTag(IGF, dest, tag, T); + else + storePayloadTag(IGF, dest, tagIndex, T); + IGF.Builder.CreateBr(endBB); ++tagIndex; @@ -3725,6 +3901,7 @@ namespace { // For trivial payloads (including no-payload cases), we can just // primitive-copy to the destination. IGF.Builder.emitBlock(trivialBB); + ConditionalDominanceScope condition(IGF); emitPrimitiveCopy(IGF, dest, src, T); IGF.Builder.CreateBr(endBB); @@ -3794,14 +3971,8 @@ namespace { } private: - void storePayloadTag(IRGenFunction &IGF, - Address enumAddr, unsigned index, - SILType T) const { - // Use the runtime to initialize dynamic cases. - if (TIK < Fixed) { - return storeDynamicTag(IGF, enumAddr, index, T); - } - + void storePayloadTag(IRGenFunction &IGF, Address enumAddr, + unsigned index, SILType T) const { // If the tag has spare bits, we need to mask them into the // payload area. unsigned numSpareBits = PayloadTagBits.count(); @@ -3833,15 +4004,54 @@ namespace { } } - void storeNoPayloadTag(IRGenFunction &IGF, Address enumAddr, - unsigned index, SILType T) const { - // Use the runtime to initialize dynamic cases. - if (TIK < Fixed) { - // Dynamic case indexes start after the payload cases. - return storeDynamicTag(IGF, enumAddr, - index + ElementsWithPayload.size(), T); + void storePayloadTag(IRGenFunction &IGF, Address enumAddr, + llvm::Value *tag, SILType T) const { + unsigned numSpareBits = PayloadTagBits.count(); + if (numSpareBits > 0) { + llvm::Value *spareTagBits; + if (numSpareBits >= 32) + spareTagBits = tag; + else { + spareTagBits = IGF.Builder.CreateAnd(tag, + llvm::ConstantInt::get(IGF.IGM.Int32Ty, + ((1U << numSpareBits) - 1U))); + } + + // Load the payload area. + Address payloadAddr = projectPayload(IGF, enumAddr); + auto payload = EnumPayload::load(IGF, payloadAddr, PayloadSchema); + + // Mask off the spare bits. + auto spareBitMask = ~PayloadTagBits.asAPInt(); + payload.emitApplyAndMask(IGF, spareBitMask); + + // Store the tag into the spare bits. + payload.emitApplyOrMask(IGF, + interleaveSpareBits(IGF, PayloadSchema, + PayloadTagBits, + spareTagBits)); + + // Store the payload back. + payload.store(IGF, payloadAddr); } + // Initialize the extra tag bits, if we have them. + if (ExtraTagBitCount > 0) { + auto *extraTagValue = tag; + if (numSpareBits > 0) { + auto *shiftCount = llvm::ConstantInt::get(IGF.IGM.Int32Ty, + numSpareBits); + extraTagValue = IGF.Builder.CreateLShr(tag, shiftCount); + } + extraTagValue = IGF.Builder.CreateIntCast(extraTagValue, + extraTagTy, false); + IGF.Builder.CreateStore(extraTagValue, + projectExtraTagBits(IGF, enumAddr)); + } + } + + void storeNoPayloadTag(IRGenFunction &IGF, Address enumAddr, + unsigned index, SILType T) const { // We can just primitive-store the representation for the empty case. APInt payloadValue, extraTag; std::tie(payloadValue, extraTag) = getNoPayloadCaseValue(index); @@ -3849,23 +4059,42 @@ namespace { auto payload = EnumPayload::fromBitPattern(IGF.IGM, payloadValue, PayloadSchema); payload.store(IGF, projectPayload(IGF, enumAddr)); + + // Initialize the extra tag bits, if we have them. if (ExtraTagBitCount > 0) { IGF.Builder.CreateStore( llvm::ConstantInt::get(IGF.IGM.getLLVMContext(), extraTag), projectExtraTagBits(IGF, enumAddr)); } } - - void storeDynamicTag(IRGenFunction &IGF, Address enumAddr, unsigned index, - SILType T) const { + + void storeNoPayloadTag(IRGenFunction &IGF, Address enumAddr, + llvm::Value *tag, SILType T) const { + // We can just primitive-store the representation for the empty case. + EnumPayload payloadValue; + llvm::Value *extraTag; + std::tie(payloadValue, extraTag) = getNoPayloadCaseValue(IGF, tag); + payloadValue.store(IGF, projectPayload(IGF, enumAddr)); + + // Initialize the extra tag bits, if we have them. + if (ExtraTagBitCount > 0) { + extraTag = IGF.Builder.CreateIntCast(extraTag, extraTagTy, + /*signed=*/false); + IGF.Builder.CreateStore(extraTag, projectExtraTagBits(IGF, enumAddr)); + } + } + + void storeDynamicTag(IRGenFunction &IGF, Address enumAddr, + llvm::Value *tag, SILType T) const { + assert(TIK < Fixed); + // Invoke the runtime to store the tag. enumAddr = IGF.Builder.CreateBitCast(enumAddr, IGF.IGM.OpaquePtrTy); - auto indexVal = llvm::ConstantInt::get(IGF.IGM.Int32Ty, index); auto metadata = IGF.emitTypeMetadataRef(T.getSwiftRValueType()); auto call = IGF.Builder.CreateCall( IGF.IGM.getStoreEnumTagMultiPayloadFn(), - {enumAddr.getAddress(), metadata, indexVal}); + {enumAddr.getAddress(), metadata, tag}); call->setDoesNotThrow(); } @@ -3875,25 +4104,64 @@ namespace { SILType T, Address enumAddr, EnumElementDecl *Case) const override { - // See whether this is a payload or empty case we're emitting. - auto payloadI = std::find_if(ElementsWithPayload.begin(), - ElementsWithPayload.end(), - [&](const Element &e) { return e.decl == Case; }); - if (payloadI != ElementsWithPayload.end()) { - unsigned index = payloadI - ElementsWithPayload.begin(); + unsigned index = getTagIndex(Case); + // Use the runtime to initialize dynamic cases. + if (TIK < Fixed) { + auto tag = llvm::ConstantInt::get(IGF.IGM.Int32Ty, index); + return storeDynamicTag(IGF, enumAddr, tag, T); + } + + // See whether this is a payload or empty case we're emitting. + unsigned numPayloadCases = ElementsWithPayload.size(); + if (index < numPayloadCases) return storePayloadTag(IGF, enumAddr, index, T); + return storeNoPayloadTag(IGF, enumAddr, index - numPayloadCases, T); + } + + void emitStoreTag(IRGenFunction &IGF, + SILType T, + Address enumAddr, + llvm::Value *tag) const override { + // Use the runtime to initialize dynamic cases. + if (TIK < Fixed) { + // No-payload case indexes start after the payload cases. + return storeDynamicTag(IGF, enumAddr, tag, T); } - auto emptyI = std::find_if(ElementsWithNoPayload.begin(), - ElementsWithNoPayload.end(), - [&](const Element &e) { return e.decl == Case; }); - assert(emptyI != ElementsWithNoPayload.end() && "case not in enum"); - unsigned index = emptyI - ElementsWithNoPayload.begin(); - - // Use the runtime to store a dynamic tag. Empty tag values always follow - // the payloads. - storeNoPayloadTag(IGF, enumAddr, index, T); + // If there are no empty cases, don't need a conditional. + if (ElementsWithNoPayload.empty()) { + storePayloadTag(IGF, enumAddr, tag, T); + return; + } + + auto &C = IGF.IGM.getLLVMContext(); + auto noPayloadBB = llvm::BasicBlock::Create(C); + auto payloadBB = llvm::BasicBlock::Create(C); + auto endBB = llvm::BasicBlock::Create(C); + + llvm::Value *numPayloadCases = + llvm::ConstantInt::get(IGF.IGM.Int32Ty, + ElementsWithPayload.size()); + llvm::Value *cond = IGF.Builder.CreateICmpUGE(tag, numPayloadCases); + IGF.Builder.CreateCondBr(cond, noPayloadBB, payloadBB); + + IGF.Builder.emitBlock(noPayloadBB); + { + ConditionalDominanceScope condition(IGF); + llvm::Value *noPayloadTag = IGF.Builder.CreateSub(tag, numPayloadCases); + storeNoPayloadTag(IGF, enumAddr, noPayloadTag, T); + IGF.Builder.CreateBr(endBB); + } + + IGF.Builder.emitBlock(payloadBB); + { + ConditionalDominanceScope condition(IGF); + storePayloadTag(IGF, enumAddr, tag, T); + IGF.Builder.CreateBr(endBB); + } + + IGF.Builder.emitBlock(endBB); } /// Clear any tag bits stored in the payload area of the given address. @@ -4081,7 +4349,9 @@ namespace { SILType T, Address enumAddr, EnumElementDecl *Case) const override { - llvm_unreachable("resilient enums cannot be constructed directly"); + emitDestructiveInjectEnumTagCall(IGF, T, + getTagIndex(Case), + enumAddr.getAddress()); } llvm::Value * @@ -4184,6 +4454,11 @@ namespace { const override { emitDestroyCall(IGF, T, addr.getAddress()); } + + void getSchema(ExplosionSchema &schema) const override { + schema.add(ExplosionSchema::Element::forAggregate(getStorageType(), + TI->getBestKnownAlignment())); + } // \group Operations for loadable enums @@ -4236,10 +4511,6 @@ namespace { llvm_unreachable("resilient enums are always indirect"); } - void getSchema(ExplosionSchema &schema) const override { - llvm_unreachable("resilient enums are always indirect"); - } - unsigned getExplosionSize() const override { llvm_unreachable("resilient enums are always indirect"); } @@ -4303,6 +4574,13 @@ namespace { const override { llvm_unreachable("resilient enums cannot be defined"); } + + void emitStoreTag(IRGenFunction &IGF, + SILType T, + Address enumAddr, + llvm::Value *tag) const override { + llvm_unreachable("resilient enums cannot be defined"); + } bool needsPayloadSizeInMetadata() const override { llvm_unreachable("resilient enums cannot be defined"); @@ -4359,9 +4637,27 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC, unsigned numElements = 0; TypeInfoKind tik = Loadable; IsFixedSize_t alwaysFixedSize = IsFixedSize; + bool allowFixedLayoutOptimizations = true; std::vector elementsWithPayload; std::vector elementsWithNoPayload; + // Resilient enums are manipulated as opaque values, except we still + // make the following assumptions: + // 1) Physical case indices won't change + // 2) The indirect-ness of cases won't change + // 3) Payload types won't change in a non-resilient way + bool isResilient = TC.IGM.isResilient(theEnum, ResilienceScope::Component); + + // The most general resilience scope where the enum type is visible. + // Case numbering must not depend on any information that is not static + // in this resilience scope. + ResilienceScope accessScope = TC.IGM.getResilienceScopeForAccess(theEnum); + + // The most general resilience scope where the enum's layout is known. + // Fixed-size optimizations can be applied if all payload types are + // fixed-size from this resilience scope. + ResilienceScope layoutScope = TC.IGM.getResilienceScopeForLayout(theEnum); + for (auto elt : theEnum->getAllElements()) { numElements++; @@ -4390,14 +4686,20 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC, = TC.tryGetCompleteTypeInfo(origArgLoweredTy.getSwiftRValueType()); assert(origArgTI && "didn't complete type info?!"); - // If the unsubstituted argument contains a generic parameter type, or if - // the substituted argument is not universally fixed-size, we need to - // constrain our layout optimizations to what the runtime can reproduce. - if (!origArgTI->isFixedSize(ResilienceScope::Universal)) - alwaysFixedSize = IsNotFixedSize; - - auto loadableOrigArgTI = dyn_cast(origArgTI); - if (loadableOrigArgTI && loadableOrigArgTI->isKnownEmpty()) { + // If the unsubstituted argument contains a generic parameter type, or + // is not fixed-size in all resilience domains that have knowledge of + // this enum's layout, we need to constrain our layout optimizations to + // what the runtime can reproduce. + if (!isResilient && + !origArgTI->isFixedSize(layoutScope)) + allowFixedLayoutOptimizations = false; + + // If the payload is empty, turn the case into a no-payload case, but + // only if case numbering remains unchanged from all resilience domains + // that can see the enum. + if (origArgTI->isFixedSize(accessScope) && + isa(origArgTI) && + cast(origArgTI)->isKnownEmpty()) { elementsWithNoPayload.push_back({elt, nullptr, nullptr}); } else { // *Now* apply the substitutions and get the type info for the instance's @@ -4407,16 +4709,22 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC, auto *substArgTI = &TC.IGM.getTypeInfo(fieldTy); elementsWithPayload.push_back({elt, substArgTI, origArgTI}); - if (!substArgTI->isFixedSize()) - tik = Opaque; - else if (!substArgTI->isLoadable() && tik > Fixed) - tik = Fixed; - // If the substituted argument contains a type that is not universally - // fixed-size, we need to constrain our layout optimizations to what - // the runtime can reproduce. - if (!substArgTI->isFixedSize(ResilienceScope::Universal)) - alwaysFixedSize = IsNotFixedSize; + if (!isResilient) { + if (!substArgTI->isFixedSize(ResilienceScope::Component)) + tik = Opaque; + else if (!substArgTI->isLoadable() && tik > Fixed) + tik = Fixed; + + // If the substituted argument contains a type that is not fixed-size + // in all resilience domains that have knowledge of this enum's layout, + // we need to constrain our layout optimizations to what the runtime + // can reproduce. + if (!substArgTI->isFixedSize(layoutScope)) { + alwaysFixedSize = IsNotFixedSize; + allowFixedLayoutOptimizations = false; + } + } } } @@ -4425,12 +4733,7 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC, + elementsWithNoPayload.size() && "not all elements accounted for"); - // Resilient enums are manipulated as opaque values, except we still - // make the following assumptions: - // 1) Physical case indices won't change - // 2) The indirect-ness of cases won't change - // 3) Payload types won't change in a non-resilient way - if (TC.IGM.isResilient(theEnum, ResilienceScope::Component)) { + if (isResilient) { return new ResilientEnumImplStrategy(TC.IGM, numElements, std::move(elementsWithPayload), @@ -4454,6 +4757,7 @@ EnumImplStrategy *EnumImplStrategy::get(TypeConverter &TC, std::move(elementsWithNoPayload)); if (elementsWithPayload.size() > 1) return new MultiPayloadEnumImplStrategy(TC.IGM, tik, alwaysFixedSize, + allowFixedLayoutOptimizations, numElements, std::move(elementsWithPayload), std::move(elementsWithNoPayload)); @@ -4947,6 +5251,7 @@ MultiPayloadEnumImplStrategy::completeFixedLayout(TypeConverter &TC, Alignment worstAlignment(1); IsPOD_t isPOD = IsPOD; IsBitwiseTakable_t isBT = IsBitwiseTakable; + PayloadSize = 0; for (auto &elt : ElementsWithPayload) { auto &fixedPayloadTI = cast(*elt.ti); if (fixedPayloadTI.getFixedAlignment() > worstAlignment) @@ -4956,14 +5261,18 @@ MultiPayloadEnumImplStrategy::completeFixedLayout(TypeConverter &TC, if (!fixedPayloadTI.isBitwiseTakable(ResilienceScope::Component)) isBT = IsNotBitwiseTakable; + unsigned payloadBytes = fixedPayloadTI.getFixedSize().getValue(); unsigned payloadBits = fixedPayloadTI.getFixedSize().getValueInBits(); - + + if (payloadBytes > PayloadSize) + PayloadSize = payloadBytes; + // See what spare bits from the payload we can use for layout optimization. // The runtime currently does not track spare bits, so we can't use them // if the type is layout-dependent. (Even when the runtime does, it will // likely only track a subset of the spare bits.) - if (!AlwaysFixedSize || TIK < Loadable) { + if (!AllowFixedLayoutOptimizations || TIK < Loadable) { if (CommonSpareBits.size() < payloadBits) CommonSpareBits.extendWithClearBits(payloadBits); continue; @@ -5007,8 +5316,8 @@ MultiPayloadEnumImplStrategy::completeFixedLayout(TypeConverter &TC, // Create the type. We need enough bits to store the largest payload plus // extra tag bits we need. setTaggedEnumBody(TC.IGM, enumTy, - CommonSpareBits.size(), - ExtraTagBitCount); + CommonSpareBits.size(), + ExtraTagBitCount); // The enum has the worst alignment of its payloads. The size includes the // added tag bits. @@ -5408,6 +5717,54 @@ irgen::interleaveSpareBits(IRGenModule &IGM, const SpareBitVector &spareBits, return llvm::APInt(bits, valueParts); } +/// A version of the above where the tag value is dynamic. +EnumPayload irgen::interleaveSpareBits(IRGenFunction &IGF, + const EnumPayloadSchema &schema, + const SpareBitVector &spareBitVector, + llvm::Value *value) { + EnumPayload result; + APInt spareBits = spareBitVector.asAPInt(); + + unsigned usedBits = 0; + + auto &DL = IGF.IGM.DataLayout; + schema.forEachType(IGF.IGM, [&](llvm::Type *type) { + unsigned bitSize = DL.getTypeSizeInBits(type); + + // Take some bits off of the bottom of the pattern. + auto spareBitsChunk = SpareBitVector::fromAPInt( + spareBits.zextOrTrunc(bitSize)); + + if (usedBits >= 32 || spareBitsChunk.count() == 0) { + result.PayloadValues.push_back(type); + } else { + llvm::Value *payloadValue = value; + if (usedBits > 0) { + payloadValue = IGF.Builder.CreateLShr(payloadValue, + llvm::ConstantInt::get(IGF.IGM.Int32Ty, usedBits)); + } + payloadValue = emitScatterSpareBits(IGF, spareBitsChunk, + payloadValue, 0); + if (payloadValue->getType() != type) { + if (type->isPointerTy()) + payloadValue = IGF.Builder.CreateIntToPtr(payloadValue, type); + else + payloadValue = IGF.Builder.CreateBitCast(payloadValue, type); + } + + result.PayloadValues.push_back(payloadValue); + } + + // Shift the remaining bits down. + spareBits = spareBits.lshr(bitSize); + + // Consume bits from the input value. + usedBits += spareBitsChunk.count(); + }); + + return result; +} + static void setAlignmentBits(SpareBitVector &v, Alignment align) { auto value = align.getValue() >> 1; for (unsigned i = 0; value; ++i, value >>= 1) { diff --git a/lib/IRGen/GenEnum.h b/lib/IRGen/GenEnum.h index d4af38cffb6dc..e9fbe685c0646 100644 --- a/lib/IRGen/GenEnum.h +++ b/lib/IRGen/GenEnum.h @@ -1,8 +1,8 @@ -//===--- GenEnum.h - Swift IR Generation For 'enum' Types -------* C++ *-===// +//===--- GenEnum.h - Swift IR Generation For 'enum' Types -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,6 +28,7 @@ namespace swift { namespace irgen { class EnumPayload; + class EnumPayloadSchema; class IRGenFunction; class TypeConverter; @@ -84,6 +85,12 @@ APInt interleaveSpareBits(IRGenModule &IGM, const SpareBitVector &spareBits, unsigned bits, unsigned spareValue, unsigned occupiedValue); +/// A version of the above where the tag value is dynamic. +EnumPayload interleaveSpareBits(IRGenFunction &IGF, + const EnumPayloadSchema &schema, + const SpareBitVector &spareBitVector, + llvm::Value *value); + /// Gather spare bits into the low bits of a smaller integer value. llvm::Value *emitGatherSpareBits(IRGenFunction &IGF, const SpareBitVector &spareBitMask, @@ -223,7 +230,7 @@ class EnumImplStrategy { /// \group Indirect enum operations /// Return the enum case tag for the given value. Payload cases come first, - /// followed by non-payload cases. + /// followed by non-payload cases. Used for the getEnumTag value witness. virtual llvm::Value *emitGetEnumTag(IRGenFunction &IGF, SILType T, Address enumAddr) const = 0; @@ -242,11 +249,20 @@ class EnumImplStrategy { Address enumAddr, EnumElementDecl *elt) const = 0; + /// Overlay a dynamic case tag onto a data value in memory. Used when + /// generating the destructiveInjectEnumTag value witness. + virtual void emitStoreTag(IRGenFunction &IGF, + SILType T, + Address enumAddr, + llvm::Value *tag) const = 0; + /// Clears tag bits from within the payload of an enum in memory and /// projects the address of the data for a case. Does not check /// the referenced enum value. /// Performs the block argument binding for a SIL /// 'switch_enum_addr' instruction. + /// Also used when generating the destructiveProjectEnumData value + /// witness. Address destructiveProjectDataForLoad(IRGenFunction &IGF, SILType T, Address enumAddr, @@ -391,6 +407,7 @@ class EnumImplStrategy { unsigned offset) const = 0; virtual bool needsPayloadSizeInMetadata() const = 0; + virtual unsigned getPayloadSizeForMetadata() const; virtual llvm::Value *loadRefcountedPtr(IRGenFunction &IGF, SourceLoc loc, Address addr) const; diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp index 569463cb2a597..d5265fbf7bf17 100644 --- a/lib/IRGen/GenExistential.cpp +++ b/lib/IRGen/GenExistential.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -46,7 +46,6 @@ #include "NonFixedTypeInfo.h" #include "ProtocolInfo.h" #include "TypeInfo.h" -#include "UnownedTypeInfo.h" #include "WeakTypeInfo.h" using namespace swift; @@ -361,27 +360,29 @@ class OpaqueExistentialTypeInfo : } }; -/// A type implementation for 'weak' existential types. -class WeakClassExistentialTypeInfo : - public ExistentialTypeInfoBase> { - using super = - ExistentialTypeInfoBase>; +/// A type implementation for address-only reference storage of +/// class existential types. +template +class AddressOnlyClassExistentialTypeInfoBase : + public ExistentialTypeInfoBase> { + using super = ExistentialTypeInfoBase>; - ReferenceCounting Refcounting; + using super::asDerived; + using super::emitCopyOfTables; + using super::getNumStoredProtocols; -public: - WeakClassExistentialTypeInfo(ArrayRef protocols, - llvm::Type *ty, Size size, Alignment align, - SpareBitVector &&spareBits, - ReferenceCounting refcounting) - : super(protocols, ty, size, align, std::move(spareBits)), +protected: + const ReferenceCounting Refcounting; + + template + AddressOnlyClassExistentialTypeInfoBase(ArrayRef protocols, + ReferenceCounting refcounting, + As &&...args) + : super(protocols, std::forward(args)...), Refcounting(refcounting) { - assert(refcounting == ReferenceCounting::Native || - refcounting == ReferenceCounting::Unknown); } +public: Address projectWitnessTable(IRGenFunction &IGF, Address container, unsigned index) const { assert(index < getNumStoredProtocols()); @@ -398,10 +399,7 @@ class WeakClassExistentialTypeInfo : SILType T) const override { Address destValue = projectValue(IGF, dest); Address srcValue = projectValue(IGF, src); - if (Refcounting == ReferenceCounting::Native) - IGF.emitWeakCopyAssign(destValue, srcValue); - else - IGF.emitUnknownWeakCopyAssign(destValue, srcValue); + asDerived().emitValueAssignWithCopy(IGF, destValue, srcValue); emitCopyOfTables(IGF, dest, src); } @@ -410,10 +408,7 @@ class WeakClassExistentialTypeInfo : SILType T) const override { Address destValue = projectValue(IGF, dest); Address srcValue = projectValue(IGF, src); - if (Refcounting == ReferenceCounting::Native) - IGF.emitWeakCopyInit(destValue, srcValue); - else - IGF.emitUnknownWeakCopyInit(destValue, srcValue); + asDerived().emitValueInitializeWithCopy(IGF, destValue, srcValue); emitCopyOfTables(IGF, dest, src); } @@ -422,10 +417,7 @@ class WeakClassExistentialTypeInfo : SILType T) const override { Address destValue = projectValue(IGF, dest); Address srcValue = projectValue(IGF, src); - if (Refcounting == ReferenceCounting::Native) - IGF.emitWeakTakeAssign(destValue, srcValue); - else - IGF.emitUnknownWeakTakeAssign(destValue, srcValue); + asDerived().emitValueAssignWithTake(IGF, destValue, srcValue); emitCopyOfTables(IGF, dest, src); } @@ -434,20 +426,14 @@ class WeakClassExistentialTypeInfo : SILType T) const override { Address destValue = projectValue(IGF, dest); Address srcValue = projectValue(IGF, src); - if (Refcounting == ReferenceCounting::Native) - IGF.emitWeakTakeInit(destValue, srcValue); - else - IGF.emitUnknownWeakTakeInit(destValue, srcValue); + asDerived().emitValueInitializeWithTake(IGF, destValue, srcValue); emitCopyOfTables(IGF, dest, src); } void destroy(IRGenFunction &IGF, Address existential, SILType T) const override { Address valueAddr = projectValue(IGF, existential); - if (Refcounting == ReferenceCounting::Native) - IGF.emitWeakDestroy(valueAddr); - else - IGF.emitUnknownWeakDestroy(valueAddr); + asDerived().emitValueDestroy(IGF, valueAddr); } /// Given an explosion with multiple pointer elements in them, pack them @@ -466,7 +452,6 @@ class WeakClassExistentialTypeInfo : } } - // Given an exploded enum payload consisting of consecutive word-sized // chunks, cast them to their underlying component types. // FIXME: Assumes the payload is word-chunked. Should use @@ -488,6 +473,45 @@ class WeakClassExistentialTypeInfo : IGF.IGM.WitnessTablePtrTy)); } } +}; + +/// A type implementation for 'weak' existential types. +class WeakClassExistentialTypeInfo : + public AddressOnlyClassExistentialTypeInfoBase { +public: + WeakClassExistentialTypeInfo(ArrayRef protocols, + llvm::Type *ty, Size size, Alignment align, + SpareBitVector &&spareBits, + ReferenceCounting refcounting) + : AddressOnlyClassExistentialTypeInfoBase(protocols, refcounting, + ty, size, align, + std::move(spareBits)) { + } + + void emitValueAssignWithCopy(IRGenFunction &IGF, + Address dest, Address src) const { + IGF.emitWeakCopyAssign(dest, src, Refcounting); + } + + void emitValueInitializeWithCopy(IRGenFunction &IGF, + Address dest, Address src) const { + IGF.emitWeakCopyInit(dest, src, Refcounting); + } + + void emitValueAssignWithTake(IRGenFunction &IGF, + Address dest, Address src) const { + IGF.emitWeakTakeAssign(dest, src, Refcounting); + } + + void emitValueInitializeWithTake(IRGenFunction &IGF, + Address dest, Address src) const { + IGF.emitWeakTakeInit(dest, src, Refcounting); + } + + void emitValueDestroy(IRGenFunction &IGF, Address addr) const { + IGF.emitWeakDestroy(addr, Refcounting); + } // These explosions must follow the same schema as // ClassExistentialTypeInfo, i.e. first the value, then the tables. @@ -496,12 +520,8 @@ class WeakClassExistentialTypeInfo : Explosion &out) const override { Explosion temp; Address valueAddr = projectValue(IGF, existential); - if (Refcounting == ReferenceCounting::Native) - temp.add(IGF.emitWeakLoadStrong(valueAddr, - IGF.IGM.RefCountedPtrTy)); - else - temp.add(IGF.emitUnknownWeakLoadStrong(valueAddr, - IGF.IGM.UnknownRefCountedPtrTy)); + llvm::Type *resultType = IGF.IGM.getReferenceType(Refcounting); + temp.add(IGF.emitWeakLoadStrong(valueAddr, resultType, Refcounting)); emitLoadOfTables(IGF, existential, temp); mergeExplosion(temp, out, IGF); } @@ -510,12 +530,8 @@ class WeakClassExistentialTypeInfo : Explosion &out) const override { Explosion temp; Address valueAddr = projectValue(IGF, existential); - if (Refcounting == ReferenceCounting::Native) - temp.add(IGF.emitWeakTakeStrong(valueAddr, - IGF.IGM.RefCountedPtrTy)); - else - temp.add(IGF.emitUnknownWeakTakeStrong(valueAddr, - IGF.IGM.UnknownRefCountedPtrTy)); + llvm::Type *resultType = IGF.IGM.getReferenceType(Refcounting); + temp.add(IGF.emitWeakTakeStrong(valueAddr, resultType, Refcounting)); emitLoadOfTables(IGF, existential, temp); mergeExplosion(temp, out, IGF); } @@ -526,16 +542,10 @@ class WeakClassExistentialTypeInfo : decomposeExplosion(in, temp, IGF); llvm::Value *value = temp.claimNext(); - if (Refcounting == ReferenceCounting::Native) - assert(value->getType() == IGF.IGM.RefCountedPtrTy); - else - assert(value->getType() == IGF.IGM.UnknownRefCountedPtrTy); + assert(value->getType() == IGF.IGM.getReferenceType(Refcounting)); emitStoreOfTables(IGF, temp, existential); Address valueAddr = projectValue(IGF, existential); - if (Refcounting == ReferenceCounting::Native) - IGF.emitWeakInit(value, valueAddr); - else - IGF.emitUnknownWeakInit(value, valueAddr); + IGF.emitWeakInit(value, valueAddr, Refcounting); } void weakAssign(IRGenFunction &IGF, Explosion &in, @@ -544,16 +554,87 @@ class WeakClassExistentialTypeInfo : decomposeExplosion(in, temp, IGF); llvm::Value *value = temp.claimNext(); - if (Refcounting == ReferenceCounting::Native) - assert(value->getType() == IGF.IGM.RefCountedPtrTy); - else - assert(value->getType() == IGF.IGM.UnknownRefCountedPtrTy); + assert(value->getType() == IGF.IGM.getReferenceType(Refcounting)); emitStoreOfTables(IGF, temp, existential); Address valueAddr = projectValue(IGF, existential); - if (Refcounting == ReferenceCounting::Native) - IGF.emitWeakAssign(value, valueAddr); - else - IGF.emitUnknownWeakAssign(value, valueAddr); + IGF.emitWeakAssign(value, valueAddr, Refcounting); + } +}; + +/// A type implementation for address-only @unowned existential types. +class AddressOnlyUnownedClassExistentialTypeInfo : + public AddressOnlyClassExistentialTypeInfoBase< + AddressOnlyUnownedClassExistentialTypeInfo, + FixedTypeInfo> { +public: + AddressOnlyUnownedClassExistentialTypeInfo(ArrayRef protocols, + llvm::Type *ty, + SpareBitVector &&spareBits, + Size size, Alignment align, + ReferenceCounting refcounting) + : AddressOnlyClassExistentialTypeInfoBase(protocols, refcounting, + ty, size, std::move(spareBits), + align, IsNotPOD, + IsNotBitwiseTakable, + IsFixedSize) { + } + + void emitValueAssignWithCopy(IRGenFunction &IGF, + Address dest, Address src) const { + IGF.emitUnownedCopyAssign(dest, src, Refcounting); + } + + void emitValueInitializeWithCopy(IRGenFunction &IGF, + Address dest, Address src) const { + IGF.emitUnownedCopyInit(dest, src, Refcounting); + } + + void emitValueAssignWithTake(IRGenFunction &IGF, + Address dest, Address src) const { + IGF.emitUnownedTakeAssign(dest, src, Refcounting); + } + + void emitValueInitializeWithTake(IRGenFunction &IGF, + Address dest, Address src) const { + IGF.emitUnownedTakeInit(dest, src, Refcounting); + } + + void emitValueDestroy(IRGenFunction &IGF, Address addr) const { + IGF.emitUnownedDestroy(addr, Refcounting); + } + + bool mayHaveExtraInhabitants(IRGenModule &IGM) const override { + return true; + } + + unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override { + return IGM.getUnownedExtraInhabitantCount(Refcounting); + } + + APInt getFixedExtraInhabitantValue(IRGenModule &IGM, + unsigned bits, + unsigned index) const override { + return IGM.getUnownedExtraInhabitantValue(bits, index, Refcounting); + } + + llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, + SILType T) const override { + Address valueSrc = projectValue(IGF, src); + return IGF.getUnownedExtraInhabitantIndex(valueSrc, Refcounting); + } + + void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, + Address dest, SILType T) const override { + Address valueDest = projectValue(IGF, dest); + return IGF.storeUnownedExtraInhabitant(index, valueDest, Refcounting); + } + + APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override { + APInt bits = IGM.getUnownedExtraInhabitantMask(Refcounting); + + // Zext out to the size of the existential. + bits = bits.zextOrTrunc(getFixedSize().getValueInBits()); + return bits; } }; @@ -561,13 +642,13 @@ class WeakClassExistentialTypeInfo : /// exploded into scalars. /// /// The subclass must provide: -/// void emitPayloadRetain(IRGenFunction &IGF, llvm::Value *payload) const; -/// void emitPayloadRelease(IRGenFunction &IGF, llvm::Value *payload) const; -/// void emitPayloadFixLifetime(IRGenFunction &IGF, -/// llvm::Value *payload) const; +/// void emitValueRetain(IRGenFunction &IGF, llvm::Value *value) const; +/// void emitValueRelease(IRGenFunction &IGF, llvm::Value *value) const; +/// void emitValueFixLifetime(IRGenFunction &IGF, +/// llvm::Value *value) const; /// const LoadableTypeInfo & -/// getPayloadTypeInfoForExtraInhabitants(IRGenModule &IGM) const; -/// The payload type info is only used to manage extra inhabitants, so it's +/// getValueTypeInfoForExtraInhabitants(IRGenModule &IGM) const; +/// The value type info is only used to manage extra inhabitants, so it's /// okay for it to implement different semantics. template class ScalarExistentialTypeInfoBase : @@ -596,13 +677,15 @@ class ScalarExistentialTypeInfoBase : using super::getNumStoredProtocols; - unsigned getExplosionSize() const override { + unsigned getExplosionSize() const final override { return 1 + getNumStoredProtocols(); } void getSchema(ExplosionSchema &schema) const override { + schema.add(ExplosionSchema::Element::forScalar(asDerived().getValueType())); + llvm::StructType *ty = getStorageType(); - for (unsigned i = 0, e = getExplosionSize(); i != e; ++i) + for (unsigned i = 1, e = getExplosionSize(); i != e; ++i) schema.add(ExplosionSchema::Element::forScalar(ty->getElementType(i))); } @@ -615,6 +698,11 @@ class ScalarExistentialTypeInfoBase : IGF.IGM.getPointerSize() * (n+1)); } + /// Return the type of the instance value. + llvm::Type *getValueType() const { + return getStorageType()->getElementType(0); + } + /// Given the address of a class existential container, returns /// the address of its instance pointer. Address projectValue(IRGenFunction &IGF, Address address) const { @@ -622,7 +710,7 @@ class ScalarExistentialTypeInfoBase : } llvm::Value *loadValue(IRGenFunction &IGF, Address addr) const { - return IGF.Builder.CreateLoad(projectValue(IGF, addr)); + return IGF.Builder.CreateLoad(asDerived().projectValue(IGF, addr)); } /// Given a class existential container, returns a witness table @@ -655,9 +743,8 @@ class ScalarExistentialTypeInfoBase : void loadAsCopy(IRGenFunction &IGF, Address address, Explosion &out) const override { // Load the instance pointer, which is unknown-refcounted. - llvm::Value *instance - = IGF.Builder.CreateLoad(projectValue(IGF, address)); - asDerived().emitPayloadRetain(IGF, instance); + llvm::Value *instance = asDerived().loadValue(IGF, address); + asDerived().emitValueRetain(IGF, instance); out.add(instance); // Load the witness table pointers. @@ -667,7 +754,7 @@ class ScalarExistentialTypeInfoBase : void loadAsTake(IRGenFunction &IGF, Address address, Explosion &e) const override { // Load the instance pointer. - e.add(IGF.Builder.CreateLoad(projectValue(IGF, address))); + e.add(asDerived().loadValue(IGF, address)); // Load the witness table pointers. asDerived().emitLoadOfTables(IGF, address, e); @@ -676,10 +763,10 @@ class ScalarExistentialTypeInfoBase : void assign(IRGenFunction &IGF, Explosion &e, Address address) const override { // Assign the value. - Address instanceAddr = projectValue(IGF, address); + Address instanceAddr = asDerived().projectValue(IGF, address); llvm::Value *old = IGF.Builder.CreateLoad(instanceAddr); IGF.Builder.CreateStore(e.claimNext(), instanceAddr); - asDerived().emitPayloadRelease(IGF, old); + asDerived().emitValueRelease(IGF, old); // Store the witness table pointers. asDerived().emitStoreOfTables(IGF, e, address); @@ -689,7 +776,7 @@ class ScalarExistentialTypeInfoBase : Address address) const override { // Store the instance pointer. IGF.Builder.CreateStore(e.claimNext(), - projectValue(IGF, address)); + asDerived().projectValue(IGF, address)); // Store the witness table pointers. asDerived().emitStoreOfTables(IGF, e, address); @@ -700,7 +787,7 @@ class ScalarExistentialTypeInfoBase : // Copy the instance pointer. llvm::Value *value = src.claimNext(); dest.add(value); - asDerived().emitPayloadRetain(IGF, value); + asDerived().emitValueRetain(IGF, value); // Transfer the witness table pointers. src.transferInto(dest, getNumStoredProtocols()); @@ -710,7 +797,7 @@ class ScalarExistentialTypeInfoBase : const override { // Copy the instance pointer. llvm::Value *value = src.claimNext(); - asDerived().emitPayloadRelease(IGF, value); + asDerived().emitValueRelease(IGF, value); // Throw out the witness table pointers. src.claim(getNumStoredProtocols()); @@ -719,15 +806,15 @@ class ScalarExistentialTypeInfoBase : void fixLifetime(IRGenFunction &IGF, Explosion &src) const override { // Copy the instance pointer. llvm::Value *value = src.claimNext(); - asDerived().emitPayloadFixLifetime(IGF, value); + asDerived().emitValueFixLifetime(IGF, value); // Throw out the witness table pointers. src.claim(getNumStoredProtocols()); } void destroy(IRGenFunction &IGF, Address addr, SILType T) const override { - llvm::Value *value = IGF.Builder.CreateLoad(projectValue(IGF, addr)); - asDerived().emitPayloadRelease(IGF, value); + llvm::Value *value = asDerived().loadValue(IGF, addr); + asDerived().emitValueRelease(IGF, value); } void packIntoEnumPayload(IRGenFunction &IGF, @@ -763,13 +850,13 @@ class ScalarExistentialTypeInfoBase : // pointer(s), but it's unlikely we would ever need to. bool mayHaveExtraInhabitants(IRGenModule &IGM) const override { - assert(asDerived().getPayloadTypeInfoForExtraInhabitants(IGM) + assert(asDerived().getValueTypeInfoForExtraInhabitants(IGM) .mayHaveExtraInhabitants(IGM)); return true; } unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override { - return asDerived().getPayloadTypeInfoForExtraInhabitants(IGM) + return asDerived().getValueTypeInfoForExtraInhabitants(IGM) .getFixedExtraInhabitantCount(IGM); } @@ -777,7 +864,7 @@ class ScalarExistentialTypeInfoBase : unsigned bits, unsigned index) const override { // Note that we pass down the original bit-width. - return asDerived().getPayloadTypeInfoForExtraInhabitants(IGM) + return asDerived().getValueTypeInfoForExtraInhabitants(IGM) .getFixedExtraInhabitantValue(IGM, bits, index); } @@ -787,20 +874,20 @@ class ScalarExistentialTypeInfoBase : // NB: We assume that the witness table slots are zero if an extra // inhabitant is stored in the container. src = projectValue(IGF, src); - return asDerived().getPayloadTypeInfoForExtraInhabitants(IGF.IGM) + return asDerived().getValueTypeInfoForExtraInhabitants(IGF.IGM) .getExtraInhabitantIndex(IGF, src, SILType()); } void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, Address dest, SILType T) const override { Address valueDest = projectValue(IGF, dest); - asDerived().getPayloadTypeInfoForExtraInhabitants(IGF.IGM) + asDerived().getValueTypeInfoForExtraInhabitants(IGF.IGM) .storeExtraInhabitant(IGF, index, valueDest, SILType()); } APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override { - // Ask the payload type for its mask. - APInt bits = asDerived().getPayloadTypeInfoForExtraInhabitants(IGM) + // Ask the value type for its mask. + APInt bits = asDerived().getValueTypeInfoForExtraInhabitants(IGM) .getFixedExtraInhabitantMask(IGM); // Zext out to the size of the existential. @@ -809,50 +896,88 @@ class ScalarExistentialTypeInfoBase : } }; -/// A type implementation for [unowned] class existential types. -class UnownedClassExistentialTypeInfo - : public ScalarExistentialTypeInfoBase { +/// A type implementation for loadable [unowned] class existential types. +class LoadableUnownedClassExistentialTypeInfo + : public ScalarExistentialTypeInfoBase< + LoadableUnownedClassExistentialTypeInfo, + LoadableTypeInfo> { ReferenceCounting Refcounting; + llvm::Type *ValueType; public: - UnownedClassExistentialTypeInfo(ArrayRef storedProtocols, + LoadableUnownedClassExistentialTypeInfo( + ArrayRef storedProtocols, + llvm::Type *valueTy, llvm::Type *ty, const SpareBitVector &spareBits, Size size, Alignment align, ReferenceCounting refcounting) : ScalarExistentialTypeInfoBase(storedProtocols, ty, size, - spareBits, align), - Refcounting(refcounting) { + spareBits, align, IsNotPOD, IsFixedSize), + Refcounting(refcounting), ValueType(valueTy) { assert(refcounting == ReferenceCounting::Native || refcounting == ReferenceCounting::Unknown); } - const LoadableTypeInfo & - getPayloadTypeInfoForExtraInhabitants(IRGenModule &IGM) const { - if (Refcounting == ReferenceCounting::Native) - return IGM.getNativeObjectTypeInfo(); - else - return IGM.getUnknownObjectTypeInfo(); + llvm::Type *getValueType() const { + return ValueType; } - void emitPayloadRetain(IRGenFunction &IGF, llvm::Value *value) const { - if (Refcounting == ReferenceCounting::Native) - IGF.emitUnownedRetain(value); - else - IGF.emitUnknownUnownedRetain(value); + Address projectValue(IRGenFunction &IGF, Address addr) const { + Address valueAddr = ScalarExistentialTypeInfoBase::projectValue(IGF, addr); + return IGF.Builder.CreateBitCast(valueAddr, ValueType->getPointerTo()); } - void emitPayloadRelease(IRGenFunction &IGF, llvm::Value *value) const { - if (Refcounting == ReferenceCounting::Native) - IGF.emitUnownedRelease(value); - else - IGF.emitUnknownUnownedRelease(value); + void emitValueRetain(IRGenFunction &IGF, llvm::Value *value) const { + IGF.emitUnownedRetain(value, Refcounting); + } + + void emitValueRelease(IRGenFunction &IGF, llvm::Value *value) const { + IGF.emitUnownedRelease(value, Refcounting); } - void emitPayloadFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { + void emitValueFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { IGF.emitFixLifetime(value); } + + const LoadableTypeInfo & + getValueTypeInfoForExtraInhabitants(IRGenModule &IGM) const { + llvm_unreachable("should have overridden all actual uses of this"); + } + + bool mayHaveExtraInhabitants(IRGenModule &IGM) const override { + return true; + } + + unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override { + return IGM.getUnownedExtraInhabitantCount(Refcounting); + } + + APInt getFixedExtraInhabitantValue(IRGenModule &IGM, + unsigned bits, + unsigned index) const override { + return IGM.getUnownedExtraInhabitantValue(bits, index, Refcounting); + } + + llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, + SILType T) const override { + Address valueSrc = projectValue(IGF, src); + return IGF.getUnownedExtraInhabitantIndex(valueSrc, Refcounting); + } + + void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, + Address dest, SILType T) const override { + Address valueDest = projectValue(IGF, dest); + return IGF.storeUnownedExtraInhabitant(index, valueDest, Refcounting); + } + + APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override { + APInt bits = IGM.getUnownedExtraInhabitantMask(Refcounting); + + // Zext out to the size of the existential. + bits = bits.zextOrTrunc(asDerived().getFixedSize().getValueInBits()); + return bits; + } }; /// A type implementation for @unowned(unsafe) class existential types. @@ -868,22 +993,22 @@ class UnmanagedClassExistentialTypeInfo spareBits, align, IsPOD, IsFixedSize) {} const LoadableTypeInfo & - getPayloadTypeInfoForExtraInhabitants(IRGenModule &IGM) const { + getValueTypeInfoForExtraInhabitants(IRGenModule &IGM) const { if (!IGM.ObjCInterop) return IGM.getNativeObjectTypeInfo(); else return IGM.getUnknownObjectTypeInfo(); } - void emitPayloadRetain(IRGenFunction &IGF, llvm::Value *value) const { + void emitValueRetain(IRGenFunction &IGF, llvm::Value *value) const { // do nothing } - void emitPayloadRelease(IRGenFunction &IGF, llvm::Value *value) const { + void emitValueRelease(IRGenFunction &IGF, llvm::Value *value) const { // do nothing } - void emitPayloadFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { + void emitValueFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { // do nothing } }; @@ -922,93 +1047,126 @@ class ClassExistentialTypeInfo } const LoadableTypeInfo & - getPayloadTypeInfoForExtraInhabitants(IRGenModule &IGM) const { + getValueTypeInfoForExtraInhabitants(IRGenModule &IGM) const { if (Refcounting == ReferenceCounting::Native) return IGM.getNativeObjectTypeInfo(); else return IGM.getUnknownObjectTypeInfo(); } - void retain(IRGenFunction &IGF, Explosion &e) const override { - // The instance is treated as unknown-refcounted. - if (Refcounting == ReferenceCounting::Native) - IGF.emitRetainCall(e.claimNext()); - else - IGF.emitUnknownRetainCall(e.claimNext()); + void strongRetain(IRGenFunction &IGF, Explosion &e) const override { + IGF.emitStrongRetain(e.claimNext(), Refcounting); e.claim(getNumStoredProtocols()); } - void release(IRGenFunction &IGF, Explosion &e) const override { - // The instance is treated as unknown-refcounted. - if (Refcounting == ReferenceCounting::Native) - IGF.emitRelease(e.claimNext()); - else - IGF.emitUnknownRelease(e.claimNext()); + void strongRelease(IRGenFunction &IGF, Explosion &e) const override { + IGF.emitStrongRelease(e.claimNext(), Refcounting); e.claim(getNumStoredProtocols()); } - void retainUnowned(IRGenFunction &IGF, Explosion &e) const override { - // The instance is treated as unknown-refcounted. - if (Refcounting == ReferenceCounting::Native) - IGF.emitRetainUnowned(e.claimNext()); - else - IGF.emitUnknownRetainUnowned(e.claimNext()); + void strongRetainUnowned(IRGenFunction &IGF, Explosion &e) const override { + IGF.emitStrongRetainUnowned(e.claimNext(), Refcounting); + e.claim(getNumStoredProtocols()); + } + + void strongRetainUnownedRelease(IRGenFunction &IGF, + Explosion &e) const override { + IGF.emitStrongRetainAndUnownedRelease(e.claimNext(), Refcounting); e.claim(getNumStoredProtocols()); } void unownedRetain(IRGenFunction &IGF, Explosion &e) const override { - // The instance is treated as unknown-refcounted. - if (Refcounting == ReferenceCounting::Native) - IGF.emitUnownedRetain(e.claimNext()); - else - IGF.emitUnknownUnownedRetain(e.claimNext()); + IGF.emitUnownedRetain(e.claimNext(), Refcounting); e.claim(getNumStoredProtocols()); } void unownedRelease(IRGenFunction &IGF, Explosion &e) const override { - // The instance is treated as unknown-refcounted. - if (Refcounting == ReferenceCounting::Native) - IGF.emitUnownedRelease(e.claimNext()); - else - IGF.emitUnknownUnownedRelease(e.claimNext()); + IGF.emitUnownedRelease(e.claimNext(), Refcounting); e.claim(getNumStoredProtocols()); } - void emitPayloadRetain(IRGenFunction &IGF, llvm::Value *value) const { - if (Refcounting == ReferenceCounting::Native) - IGF.emitRetainCall(value); - else - IGF.emitUnknownRetainCall(value); + void unownedLoadStrong(IRGenFunction &IGF, Address existential, + Explosion &out) const override { + Address valueAddr = projectValue(IGF, existential); + out.add(IGF.emitUnownedLoadStrong(valueAddr, + IGF.IGM.getReferenceType(Refcounting), + Refcounting)); + emitLoadOfTables(IGF, existential, out); } - void emitPayloadRelease(IRGenFunction &IGF, llvm::Value *value) const { - if (Refcounting == ReferenceCounting::Native) - IGF.emitRelease(value); - else - IGF.emitUnknownRelease(value); + void unownedTakeStrong(IRGenFunction &IGF, Address existential, + Explosion &out) const override { + Address valueAddr = projectValue(IGF, existential); + out.add(IGF.emitUnownedTakeStrong(valueAddr, + IGF.IGM.getReferenceType(Refcounting), + Refcounting)); + emitLoadOfTables(IGF, existential, out); + } + + void unownedInit(IRGenFunction &IGF, Explosion &in, + Address existential) const override { + llvm::Value *value = in.claimNext(); + emitStoreOfTables(IGF, in, existential); + Address valueAddr = projectValue(IGF, existential); + IGF.emitUnownedInit(value, valueAddr, Refcounting); + } + + void unownedAssign(IRGenFunction &IGF, Explosion &in, + Address existential) const override { + llvm::Value *value = in.claimNext(); + emitStoreOfTables(IGF, in, existential); + Address valueAddr = projectValue(IGF, existential); + IGF.emitUnownedAssign(value, valueAddr, Refcounting); + } + + void emitValueRetain(IRGenFunction &IGF, llvm::Value *value) const { + IGF.emitStrongRetain(value, Refcounting); + } + + void emitValueRelease(IRGenFunction &IGF, llvm::Value *value) const { + IGF.emitStrongRelease(value, Refcounting); } - void emitPayloadFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { + void emitValueFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { IGF.emitFixLifetime(value); } LoadedRef loadRefcountedPtr(IRGenFunction &IGF, SourceLoc loc, - Address addr) const override { - if (Refcounting == ReferenceCounting::Native) - return LoadedRef(IGF.emitLoadNativeRefcountedPtr(addr), true); - else - return LoadedRef(IGF.emitLoadUnknownRefcountedPtr(addr), true); + Address existential) const override { + Address valueAddr = projectValue(IGF, existential); + return LoadedRef(IGF.emitLoadRefcountedPtr(valueAddr, Refcounting), true); } - const UnownedTypeInfo * + const TypeInfo * createUnownedStorageType(TypeConverter &TC) const override { // We can just re-use the storage type for the @unowned(safe) type. - return UnownedClassExistentialTypeInfo::create(getStoredProtocols(), - getStorageType(), - getSpareBits(), + + SpareBitVector spareBits = + TC.IGM.getUnownedReferenceSpareBits(Refcounting); + for (unsigned i = 0, e = getNumStoredProtocols(); i != e; ++i) + spareBits.append(TC.IGM.getWitnessTablePtrSpareBits()); + + auto storageTy = buildReferenceStorageType(TC.IGM, + TC.IGM.UnownedReferencePtrTy->getElementType()); + + if (TC.IGM.isUnownedReferenceAddressOnly(Refcounting)) { + return AddressOnlyUnownedClassExistentialTypeInfo::create( + getStoredProtocols(), + storageTy, + std::move(spareBits), + getFixedSize(), + getFixedAlignment(), + Refcounting); + } else { + return LoadableUnownedClassExistentialTypeInfo::create( + getStoredProtocols(), + getValueType(), + storageTy, + std::move(spareBits), getFixedSize(), getFixedAlignment(), Refcounting); + } } const TypeInfo * @@ -1031,12 +1189,8 @@ class ClassExistentialTypeInfo "[weak] alignment not pointer alignment; fix existential layout"); (void)align; - // We need to build a new struct for the [weak] type because the weak - // component is not necessarily pointer-sized. - SmallVector fieldTys; - fieldTys.push_back(TC.IGM.WeakReferencePtrTy->getElementType()); - fieldTys.resize(getNumStoredProtocols() + 1, TC.IGM.WitnessTablePtrTy); - auto storageTy = llvm::StructType::get(TC.IGM.getLLVMContext(), fieldTys); + auto storageTy = buildReferenceStorageType(TC.IGM, + TC.IGM.WeakReferencePtrTy->getElementType()); SpareBitVector spareBits = TC.IGM.getWeakReferenceSpareBits(); for (unsigned i = 0, e = getNumStoredProtocols(); i != e; ++i) @@ -1047,6 +1201,15 @@ class ClassExistentialTypeInfo std::move(spareBits), Refcounting); } + + llvm::StructType *buildReferenceStorageType(IRGenModule &IGM, + llvm::Type *refStorageTy) const { + SmallVector fieldTys; + fieldTys.push_back(refStorageTy); + fieldTys.resize(getNumStoredProtocols() + 1, IGM.WitnessTablePtrTy); + auto storageTy = llvm::StructType::get(IGM.getLLVMContext(), fieldTys); + return storageTy; + } }; /// A type implementation for existential metatypes. @@ -1068,19 +1231,19 @@ class ExistentialMetatypeTypeInfo public: const LoadableTypeInfo & - getPayloadTypeInfoForExtraInhabitants(IRGenModule &IGM) const { + getValueTypeInfoForExtraInhabitants(IRGenModule &IGM) const { return MetatypeTI; } - void emitPayloadRetain(IRGenFunction &IGF, llvm::Value *value) const { + void emitValueRetain(IRGenFunction &IGF, llvm::Value *value) const { // do nothing } - void emitPayloadRelease(IRGenFunction &IGF, llvm::Value *value) const { + void emitValueRelease(IRGenFunction &IGF, llvm::Value *value) const { // do nothing } - void emitPayloadFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { + void emitValueFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { // do nothing } }; @@ -1338,6 +1501,8 @@ static llvm::Constant *getAssignExistentialsFunction(IRGenModule &IGM, // Project down to the buffers. IGF.Builder.emitBlock(contBB); + // We don't need a ConditionalDominanceScope here because (1) there's no + // code in the other condition and (2) we immediately return. Address destBuffer = layout.projectExistentialBuffer(IGF, dest); Address srcBuffer = layout.projectExistentialBuffer(IGF, src); @@ -1353,10 +1518,10 @@ static llvm::Constant *getAssignExistentialsFunction(IRGenModule &IGM, IGF.Builder.CreateICmpEQ(destMetadata, srcMetadata, "sameMetadata"); IGF.Builder.CreateCondBr(sameMetadata, matchBB, noMatchBB); - { // (scope to avoid contaminating other branches with these values) - - // If so, do a direct assignment. - IGF.Builder.emitBlock(matchBB); + // If so, do a direct assignment. + IGF.Builder.emitBlock(matchBB); + { + ConditionalDominanceScope matchCondition(IGF); llvm::Value *destObject = emitProjectBufferCall(IGF, destMetadata, destBuffer); @@ -1374,29 +1539,32 @@ static llvm::Constant *getAssignExistentialsFunction(IRGenModule &IGM, // the madnesses that boost::variant has to go through, with the // advantage of address-invariance. IGF.Builder.emitBlock(noMatchBB); + { + ConditionalDominanceScope noMatchCondition(IGF); - // Store the metadata ref. - IGF.Builder.CreateStore(srcMetadata, destMetadataSlot); + // Store the metadata ref. + IGF.Builder.CreateStore(srcMetadata, destMetadataSlot); - // Store the protocol witness tables. - unsigned numTables = layout.getNumTables(); - for (unsigned i = 0, e = numTables; i != e; ++i) { - Address destTableSlot = layout.projectWitnessTable(IGF, dest, i); - llvm::Value *srcTable = layout.loadWitnessTable(IGF, src, i); + // Store the protocol witness tables. + unsigned numTables = layout.getNumTables(); + for (unsigned i = 0, e = numTables; i != e; ++i) { + Address destTableSlot = layout.projectWitnessTable(IGF, dest, i); + llvm::Value *srcTable = layout.loadWitnessTable(IGF, src, i); - // Overwrite the old witness table. - IGF.Builder.CreateStore(srcTable, destTableSlot); - } + // Overwrite the old witness table. + IGF.Builder.CreateStore(srcTable, destTableSlot); + } - // Destroy the old value. - emitDestroyBufferCall(IGF, destMetadata, destBuffer); + // Destroy the old value. + emitDestroyBufferCall(IGF, destMetadata, destBuffer); - // Copy-initialize with the new value. Again, pull a value - // witness table from the source metadata if we can't use a - // protocol witness table. - emitInitializeBufferWithCopyOfBufferCall(IGF, srcMetadata, - destBuffer, srcBuffer); - IGF.Builder.CreateBr(doneBB); + // Copy-initialize with the new value. Again, pull a value + // witness table from the source metadata if we can't use a + // protocol witness table. + emitInitializeBufferWithCopyOfBufferCall(IGF, srcMetadata, + destBuffer, srcBuffer); + IGF.Builder.CreateBr(doneBB); + } // All done. IGF.Builder.emitBlock(doneBB); @@ -1407,10 +1575,10 @@ static llvm::Constant *getAssignExistentialsFunction(IRGenModule &IGM, /// Retrieve the protocol witness table for a conformance. static llvm::Value *getProtocolWitnessTable(IRGenFunction &IGF, CanType srcType, - const TypeInfo &srcTI, + llvm::Value **srcMetadataCache, ProtocolEntry protoEntry, ProtocolConformance *conformance) { - return emitWitnessTableRef(IGF, srcType, srcTI, + return emitWitnessTableRef(IGF, srcType, srcMetadataCache, protoEntry.getProtocol(), protoEntry.getInfo(), conformance); @@ -1419,7 +1587,8 @@ static llvm::Value *getProtocolWitnessTable(IRGenFunction &IGF, /// Emit protocol witness table pointers for the given protocol conformances, /// passing each emitted witness table index into the given function body. static void forEachProtocolWitnessTable(IRGenFunction &IGF, - CanType srcType, CanType destType, + CanType srcType, llvm::Value **srcMetadataCache, + CanType destType, ArrayRef protocols, ArrayRef conformances, std::function body) { @@ -1437,9 +1606,8 @@ static void forEachProtocolWitnessTable(IRGenFunction &IGF, assert(protocols.size() == witnessConformances.size() && "mismatched protocol conformances"); - auto &srcTI = IGF.getTypeInfoForUnlowered(srcType); for (unsigned i = 0, e = protocols.size(); i < e; ++i) { - auto table = getProtocolWitnessTable(IGF, srcType, srcTI, + auto table = getProtocolWitnessTable(IGF, srcType, srcMetadataCache, protocols[i], witnessConformances[i]); body(i, table); } @@ -1513,7 +1681,7 @@ Address irgen::emitBoxedExistentialContainerAllocation(IRGenFunction &IGF, // Should only be one conformance, for the ErrorType protocol. assert(conformances.size() == 1 && destTI.getStoredProtocols().size() == 1); const ProtocolEntry &entry = destTI.getStoredProtocols()[0]; - auto witness = getProtocolWitnessTable(IGF, formalSrcType, srcTI, + auto witness = getProtocolWitnessTable(IGF, formalSrcType, &srcMetadata, entry, conformances[0]); // Call the runtime to allocate the box. @@ -1608,7 +1776,8 @@ void irgen::emitClassExistentialContainer(IRGenFunction &IGF, out.add(opaqueInstance); // Emit the witness table pointers. - forEachProtocolWitnessTable(IGF, instanceFormalType, + llvm::Value *instanceMetadata = nullptr; + forEachProtocolWitnessTable(IGF, instanceFormalType, &instanceMetadata, outType.getSwiftRValueType(), destTI.getStoredProtocols(), conformances, @@ -1638,7 +1807,8 @@ Address irgen::emitOpaqueExistentialContainerInit(IRGenFunction &IGF, // Next, write the protocol witness tables. - forEachProtocolWitnessTable(IGF, formalSrcType, destType.getSwiftRValueType(), + forEachProtocolWitnessTable(IGF, formalSrcType, &metadata, + destType.getSwiftRValueType(), destTI.getStoredProtocols(), conformances, [&](unsigned i, llvm::Value *ptable) { Address ptableSlot = destLayout.projectWitnessTable(IGF, dest, i); @@ -1669,7 +1839,8 @@ void irgen::emitExistentialMetatypeContainer(IRGenFunction &IGF, } // Emit the witness table pointers. - forEachProtocolWitnessTable(IGF, srcType, destType, + llvm::Value *srcMetadata = nullptr; + forEachProtocolWitnessTable(IGF, srcType, &srcMetadata, destType, destTI.getStoredProtocols(), conformances, [&](unsigned i, llvm::Value *ptable) { diff --git a/lib/IRGen/GenExistential.h b/lib/IRGen/GenExistential.h index 3edfb2ad0fa3d..c85fe0be310a6 100644 --- a/lib/IRGen/GenExistential.h +++ b/lib/IRGen/GenExistential.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 0086becc3f11c..c997b5aaef51b 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -176,11 +176,12 @@ static void addIndirectValueParameterAttributes(IRGenModule &IGM, static void addInoutParameterAttributes(IRGenModule &IGM, llvm::AttributeSet &attrs, const TypeInfo &ti, - unsigned argIndex) { + unsigned argIndex, + bool aliasable) { llvm::AttrBuilder b; // Aliasing inouts is unspecified, but we still want aliasing to be memory- // safe, so we can't mark inouts as noalias at the LLVM level. - // They can't be captured without doing unsafe stuff, though. + // They still can't be captured without doing unsafe stuff, though. b.addAttribute(llvm::Attribute::NoCapture); // The inout must reference dereferenceable memory of the type. addDereferenceableAttributeToBuilder(IGM, b, ti); @@ -431,7 +432,7 @@ namespace { createWeakStorageType(TypeConverter &TC) const override { llvm_unreachable("[weak] function type"); } - const UnownedTypeInfo * + const TypeInfo * createUnownedStorageType(TypeConverter &TC) const override { llvm_unreachable("[unowned] function type"); } @@ -471,7 +472,9 @@ namespace { e.add(IGF.Builder.CreateLoad(fnAddr, fnAddr->getName()+".load")); Address dataAddr = projectData(IGF, address); - IGF.emitLoadAndRetain(dataAddr, e); + auto data = IGF.Builder.CreateLoad(dataAddr); + IGF.emitNativeStrongRetain(data); + e.add(data); } void loadAsTake(IRGenFunction &IGF, Address addr, @@ -491,7 +494,7 @@ namespace { IGF.Builder.CreateStore(e.claimNext(), fnAddr); Address dataAddr = projectData(IGF, address); - IGF.emitAssignRetained(e.claimNext(), dataAddr); + IGF.emitNativeStrongAssign(e.claimNext(), dataAddr); } void initialize(IRGenFunction &IGF, Explosion &e, @@ -502,19 +505,20 @@ namespace { // Store the data pointer, if any, transferring the +1. Address dataAddr = projectData(IGF, address); - IGF.emitInitializeRetained(e.claimNext(), dataAddr); + IGF.emitNativeStrongInit(e.claimNext(), dataAddr); } void copy(IRGenFunction &IGF, Explosion &src, Explosion &dest) const override { src.transferInto(dest, 1); - - IGF.emitRetain(src.claimNext(), dest); + auto data = src.claimNext(); + IGF.emitNativeStrongRetain(data); + dest.add(data); } void consume(IRGenFunction &IGF, Explosion &src) const override { src.claimNext(); - IGF.emitRelease(src.claimNext()); + IGF.emitNativeStrongRelease(src.claimNext()); } void fixLifetime(IRGenFunction &IGF, Explosion &src) const override { @@ -522,33 +526,56 @@ namespace { IGF.emitFixLifetime(src.claimNext()); } - void retain(IRGenFunction &IGF, Explosion &e) const override { + void strongRetain(IRGenFunction &IGF, Explosion &e) const override { e.claimNext(); - IGF.emitRetainCall(e.claimNext()); + IGF.emitNativeStrongRetain(e.claimNext()); } - void release(IRGenFunction &IGF, Explosion &e) const override { + void strongRelease(IRGenFunction &IGF, Explosion &e) const override { e.claimNext(); - IGF.emitRelease(e.claimNext()); + IGF.emitNativeStrongRelease(e.claimNext()); } - void retainUnowned(IRGenFunction &IGF, Explosion &e) const override { - e.claimNext(); - IGF.emitRetainUnowned(e.claimNext()); + void strongRetainUnowned(IRGenFunction &IGF, Explosion &e) const override { + llvm_unreachable("unowned references to functions are not supported"); + } + + void strongRetainUnownedRelease(IRGenFunction &IGF, + Explosion &e) const override { + llvm_unreachable("unowned references to functions are not supported"); } void unownedRetain(IRGenFunction &IGF, Explosion &e) const override { - e.claimNext(); - IGF.emitUnownedRetain(e.claimNext()); + llvm_unreachable("unowned references to functions are not supported"); } void unownedRelease(IRGenFunction &IGF, Explosion &e) const override { - e.claimNext(); - IGF.emitUnownedRelease(e.claimNext()); + llvm_unreachable("unowned references to functions are not supported"); + } + + void unownedLoadStrong(IRGenFunction &IGF, Address src, + Explosion &out) const override { + llvm_unreachable("unowned references to functions are not supported"); + } + + void unownedTakeStrong(IRGenFunction &IGF, Address src, + Explosion &out) const override { + llvm_unreachable("unowned references to functions are not supported"); + } + + void unownedInit(IRGenFunction &IGF, Explosion &in, + Address dest) const override { + llvm_unreachable("unowned references to functions are not supported"); + } + + void unownedAssign(IRGenFunction &IGF, Explosion &in, + Address dest) const override { + llvm_unreachable("unowned references to functions are not supported"); } void destroy(IRGenFunction &IGF, Address addr, SILType T) const override { - IGF.emitRelease(IGF.Builder.CreateLoad(projectData(IGF, addr))); + auto data = IGF.Builder.CreateLoad(projectData(IGF, addr)); + IGF.emitNativeStrongRelease(data); } void packIntoEnumPayload(IRGenFunction &IGF, @@ -1316,7 +1343,7 @@ llvm::Type *SignatureExpansion::expandExternalSignatureTypes() { void SignatureExpansion::expand(SILParameterInfo param) { auto &ti = IGM.getTypeInfo(param.getSILType()); - switch (param.getConvention()) { + switch (auto conv = param.getConvention()) { case ParameterConvention::Indirect_Out: assert(ParamIRTypes.empty()); addIndirectReturnAttributes(IGM, Attrs); @@ -1331,24 +1358,16 @@ void SignatureExpansion::expand(SILParameterInfo param) { return; case ParameterConvention::Indirect_Inout: - addInoutParameterAttributes(IGM, Attrs, ti, ParamIRTypes.size()); + case ParameterConvention::Indirect_InoutAliasable: + addInoutParameterAttributes(IGM, Attrs, ti, ParamIRTypes.size(), + conv == ParameterConvention::Indirect_InoutAliasable); addPointerParameter(IGM.getStorageType(param.getSILType())); return; case ParameterConvention::Direct_Owned: case ParameterConvention::Direct_Unowned: case ParameterConvention::Direct_Guaranteed: - // Go ahead and further decompose tuples. - if (auto tuple = dyn_cast(param.getType())) { - for (auto elt : tuple.getElementTypes()) { - // Propagate the same ownedness down to the element. - expand(SILParameterInfo(elt, param.getConvention())); - } - return; - } - SWIFT_FALLTHROUGH; case ParameterConvention::Direct_Deallocating: - switch (FnType->getLanguage()) { case SILFunctionLanguage::C: { llvm_unreachable("Unexpected C/ObjC method in parameter expansion!"); @@ -1801,7 +1820,7 @@ if (Builtin.ID == BuiltinValueKind::id) { \ return; \ } // FIXME: We could generate the code to dynamically report the overflow if the - // thrid argument is true. Now, we just ignore it. + // third argument is true. Now, we just ignore it. #define BUILTIN_BINARY_PREDICATE(id, name, attrs, overload) \ if (Builtin.ID == BuiltinValueKind::id) \ @@ -2178,7 +2197,7 @@ if (Builtin.ID == BuiltinValueKind::id) { \ return out.add(OverflowFlag); } - // We are currently emiting code for '_convertFromBuiltinIntegerLiteral', + // We are currently emitting code for '_convertFromBuiltinIntegerLiteral', // which will call the builtin and pass it a non-compile-time-const parameter. if (Builtin.ID == BuiltinValueKind::IntToFPWithOverflow) { auto ToTy = @@ -2347,10 +2366,18 @@ void CallEmission::emitToUnmappedExplosion(Explosion &out) { llvm::Value *result = call.getInstruction(); if (result->getType()->isVoidTy()) return; + CanSILFunctionType origFunctionType = getCallee().getOrigFunctionType(); + + // If the result was returned autoreleased, implicitly insert the reclaim. + if (origFunctionType->getResult().getConvention() == + ResultConvention::Autoreleased) { + result = emitObjCRetainAutoreleasedReturnValue(IGF, result); + } + // Get the natural IR type in the body of the function that makes // the call. This may be different than the IR type returned by the // call itself due to ABI type coercion. - auto resultType = getCallee().getOrigFunctionType()->getSILResult(); + auto resultType = origFunctionType->getSILResult(); auto &resultTI = IGF.IGM.getTypeInfo(resultType); auto schema = resultTI.getSchema(); auto *bodyType = schema.getScalarResultType(IGF.IGM); @@ -2879,9 +2906,9 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee, case clang::CodeGen::ABIArgInfo::Direct: { auto toTy = AI.getCoerceToType(); - // inout parameters are bridged as Clang pointer types. For now, this + // Mutating parameters are bridged as Clang pointer types. For now, this // only ever comes up with Clang-generated accessors. - if (params[i - firstParam].isIndirectInOut()) { + if (params[i - firstParam].isIndirectMutating()) { assert(paramType.isAddress() && "SIL type is not an address?"); auto addr = in.claimNext(); @@ -3116,21 +3143,27 @@ void IRGenFunction::emitEpilogue() { AllocaIP->eraseFromParent(); } -Address irgen::allocateForCoercion(IRGenFunction &IGF, - llvm::Type *fromTy, - llvm::Type *toTy, - const llvm::Twine &basename) { +std::pair +irgen::allocateForCoercion(IRGenFunction &IGF, + llvm::Type *fromTy, + llvm::Type *toTy, + const llvm::Twine &basename) { auto &DL = IGF.IGM.DataLayout; - auto bufferTy = DL.getTypeSizeInBits(fromTy) >= DL.getTypeSizeInBits(toTy) + auto fromSize = DL.getTypeSizeInBits(fromTy); + auto toSize = DL.getTypeSizeInBits(toTy); + auto bufferTy = fromSize >= toSize ? fromTy : toTy; auto alignment = std::max(DL.getABITypeAlignment(fromTy), DL.getABITypeAlignment(toTy)); - return IGF.createAlloca(bufferTy, Alignment(alignment), - basename + ".coerced"); + auto buffer = IGF.createAlloca(bufferTy, Alignment(alignment), + basename + ".coerced"); + + Size size(std::max(fromSize, toSize)); + return {buffer, size}; } llvm::Value* IRGenFunction::coerceValue(llvm::Value *value, llvm::Type *toTy, @@ -3156,12 +3189,16 @@ llvm::Value* IRGenFunction::coerceValue(llvm::Value *value, llvm::Type *toTy, } // Otherwise we need to store, bitcast, and load. - auto address = allocateForCoercion(*this, fromTy, toTy, - value->getName() + ".coercion"); + Address address; Size size; + std::tie(address, size) = allocateForCoercion(*this, fromTy, toTy, + value->getName() + ".coercion"); + Builder.CreateLifetimeStart(address, size); auto orig = Builder.CreateBitCast(address, fromTy->getPointerTo()); Builder.CreateStore(value, orig); auto coerced = Builder.CreateBitCast(address, toTy->getPointerTo()); - return Builder.CreateLoad(coerced); + auto loaded = Builder.CreateLoad(coerced); + Builder.CreateLifetimeEnd(address, size); + return loaded; } void IRGenFunction::emitScalarReturn(llvm::Type *resultType, @@ -3372,6 +3409,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, case ParameterConvention::Direct_Deallocating: llvm_unreachable("callables do not have destructors"); case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_In_Guaranteed: @@ -3420,7 +3458,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, switch (argConvention) { case ParameterConvention::Indirect_In: case ParameterConvention::Direct_Owned: - if (!consumesContext) subIGF.emitRetainCall(rawData); + if (!consumesContext) subIGF.emitNativeStrongRetain(rawData); break; case ParameterConvention::Indirect_In_Guaranteed: @@ -3428,7 +3466,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, dependsOnContextLifetime = true; if (outType->getCalleeConvention() == ParameterConvention::Direct_Unowned) { - subIGF.emitRetainCall(rawData); + subIGF.emitNativeStrongRetain(rawData); consumesContext = true; } break; @@ -3441,6 +3479,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, case ParameterConvention::Direct_Deallocating: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: llvm_unreachable("should never happen!"); } @@ -3506,7 +3545,8 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, dependsOnContextLifetime = true; break; case ParameterConvention::Indirect_Inout: - // Load the add ress of the inout parameter. + case ParameterConvention::Indirect_InoutAliasable: + // Load the address of the inout parameter. cast(fieldTI).loadAsCopy(subIGF, fieldAddr, param); break; case ParameterConvention::Direct_Guaranteed: @@ -3557,7 +3597,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, // so we can tail call. The safety of this assumes that neither this release // nor any of the loads can throw. if (consumesContext && !dependsOnContextLifetime) - subIGF.emitRelease(rawData); + subIGF.emitNativeStrongRelease(rawData); } // Derive the callee function pointer. If we found a function @@ -3650,7 +3690,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM, // If the parameters depended on the context, consume the context now. if (rawData && consumesContext && dependsOnContextLifetime) - subIGF.emitRelease(rawData); + subIGF.emitNativeStrongRelease(rawData); // FIXME: Reabstract the result value as substituted. @@ -3729,6 +3769,7 @@ void irgen::emitFunctionPartialApplication(IRGenFunction &IGF, // Capture inout parameters by pointer. case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: argLoweringTy = argType.getSwiftType(); break; @@ -3836,7 +3877,9 @@ void irgen::emitFunctionPartialApplication(IRGenFunction &IGF, // still need to build a thunk, but we don't need to allocate anything. if ((hasSingleSwiftRefcountedContext == Yes || hasSingleSwiftRefcountedContext == Thunkable) && - *singleRefcountedConvention != ParameterConvention::Indirect_Inout) { + *singleRefcountedConvention != ParameterConvention::Indirect_Inout && + *singleRefcountedConvention != + ParameterConvention::Indirect_InoutAliasable) { assert(bindings.empty()); assert(args.size() == 1); @@ -3907,6 +3950,7 @@ void irgen::emitFunctionPartialApplication(IRGenFunction &IGF, case ParameterConvention::Direct_Guaranteed: case ParameterConvention::Direct_Deallocating: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: cast(fieldLayout.getType()) .initialize(IGF, args, fieldAddr); break; diff --git a/lib/IRGen/GenFunc.h b/lib/IRGen/GenFunc.h index a07eff5e97f7a..c0105f001407e 100644 --- a/lib/IRGen/GenFunc.h +++ b/lib/IRGen/GenFunc.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -111,10 +111,11 @@ namespace irgen { /// Allocate a stack buffer of the appropriate size to bitwise-coerce a value /// between two LLVM types. - Address allocateForCoercion(IRGenFunction &IGF, - llvm::Type *fromTy, - llvm::Type *toTy, - const llvm::Twine &basename); + std::pair + allocateForCoercion(IRGenFunction &IGF, + llvm::Type *fromTy, + llvm::Type *toTy, + const llvm::Twine &basename); } // end namespace irgen } // end namespace swift diff --git a/lib/IRGen/GenHeap.cpp b/lib/IRGen/GenHeap.cpp index 39a72c8c6a209..8c06bd2782eff 100644 --- a/lib/IRGen/GenHeap.cpp +++ b/lib/IRGen/GenHeap.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -24,6 +24,7 @@ #include "swift/Basic/Fallthrough.h" #include "swift/Basic/SourceLoc.h" #include "swift/ABI/MetadataValues.h" +#include "swift/AST/IRGenOptions.h" #include "Explosion.h" #include "GenProto.h" @@ -33,7 +34,6 @@ #include "IRGenModule.h" #include "HeapTypeInfo.h" #include "IndirectTypeInfo.h" -#include "UnownedTypeInfo.h" #include "WeakTypeInfo.h" #include "GenHeap.h" @@ -383,93 +383,106 @@ TypeConverter::createUnmanagedStorageType(llvm::Type *valueType) { namespace { /// A type implementation for an [unowned] reference to an object /// with a known-Swift reference count. - class SwiftUnownedReferenceTypeInfo - : public SingleScalarTypeInfo { + class NativeUnownedReferenceTypeInfo + : public SingleScalarTypeInfo { + llvm::Type *ValueType; public: - SwiftUnownedReferenceTypeInfo(llvm::Type *type, - const SpareBitVector &spareBits, - Size size, Alignment alignment) - : SingleScalarTypeInfo(type, size, spareBits, alignment) {} + NativeUnownedReferenceTypeInfo(llvm::Type *valueType, + llvm::Type *unownedType, + SpareBitVector &&spareBits, + Size size, Alignment alignment) + : SingleScalarTypeInfo(unownedType, size, std::move(spareBits), + alignment, IsNotPOD, IsFixedSize), + ValueType(valueType) {} enum { IsScalarPOD = false }; + llvm::Type *getScalarType() const { + return ValueType; + } + + Address projectScalar(IRGenFunction &IGF, Address addr) const { + return IGF.Builder.CreateBitCast(addr, ValueType->getPointerTo()); + } + void emitScalarRetain(IRGenFunction &IGF, llvm::Value *value) const { - IGF.emitUnownedRetain(value); + IGF.emitNativeUnownedRetain(value); } void emitScalarRelease(IRGenFunction &IGF, llvm::Value *value) const { - IGF.emitUnownedRelease(value); + IGF.emitNativeUnownedRelease(value); } void emitScalarFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { IGF.emitFixLifetime(value); } - // Unowned types have the same spare bits as strong heap object refs. - - bool mayHaveExtraInhabitants(IRGenModule &IGM) const override { - return true; - } - unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override { - return getHeapObjectExtraInhabitantCount(IGM); + return IGM.getUnownedExtraInhabitantCount(ReferenceCounting::Native); } APInt getFixedExtraInhabitantValue(IRGenModule &IGM, unsigned bits, unsigned index) const override { - return getHeapObjectFixedExtraInhabitantValue(IGM, bits, index, 0); + return IGM.getUnownedExtraInhabitantValue(bits, index, + ReferenceCounting::Native); } llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, - SILType T) - const override { - return getHeapObjectExtraInhabitantIndex(IGF, src); + SILType T) const override { + return IGF.getUnownedExtraInhabitantIndex(src, + ReferenceCounting::Native); } void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, Address dest, SILType T) const override { - return storeHeapObjectExtraInhabitant(IGF, index, dest); + return IGF.storeUnownedExtraInhabitant(index, dest, + ReferenceCounting::Native); + } + + APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override { + return IGM.getUnownedExtraInhabitantMask(ReferenceCounting::Native); + } }; /// A type implementation for a [weak] reference to an object /// with a known-Swift reference count. - class SwiftWeakReferenceTypeInfo - : public IndirectTypeInfo { llvm::Type *ValueType; public: - SwiftWeakReferenceTypeInfo(llvm::Type *valueType, - llvm::Type *weakType, - Size size, Alignment alignment, - SpareBitVector &&spareBits) + NativeWeakReferenceTypeInfo(llvm::Type *valueType, + llvm::Type *weakType, + Size size, Alignment alignment, + SpareBitVector &&spareBits) : IndirectTypeInfo(weakType, size, alignment, std::move(spareBits)), ValueType(valueType) {} void initializeWithCopy(IRGenFunction &IGF, Address destAddr, Address srcAddr, SILType T) const override { - IGF.emitWeakCopyInit(destAddr, srcAddr); + IGF.emitNativeWeakCopyInit(destAddr, srcAddr); } void initializeWithTake(IRGenFunction &IGF, Address destAddr, Address srcAddr, SILType T) const override { - IGF.emitWeakTakeInit(destAddr, srcAddr); + IGF.emitNativeWeakTakeInit(destAddr, srcAddr); } void assignWithCopy(IRGenFunction &IGF, Address destAddr, Address srcAddr, SILType T) const override { - IGF.emitWeakCopyAssign(destAddr, srcAddr); + IGF.emitNativeWeakCopyAssign(destAddr, srcAddr); } void assignWithTake(IRGenFunction &IGF, Address destAddr, Address srcAddr, SILType T) const override { - IGF.emitWeakTakeAssign(destAddr, srcAddr); + IGF.emitNativeWeakTakeAssign(destAddr, srcAddr); } void destroy(IRGenFunction &IGF, Address addr, SILType T) const override { - IGF.emitWeakDestroy(addr); + IGF.emitNativeWeakDestroy(addr); } llvm::Type *getOptionalIntType() const { @@ -479,14 +492,14 @@ namespace { void weakLoadStrong(IRGenFunction &IGF, Address addr, Explosion &out) const override { - auto value = IGF.emitWeakLoadStrong(addr, ValueType); + auto value = IGF.emitNativeWeakLoadStrong(addr, ValueType); // The optional will be lowered to an integer type the size of the word. out.add(IGF.Builder.CreatePtrToInt(value, getOptionalIntType())); } void weakTakeStrong(IRGenFunction &IGF, Address addr, Explosion &out) const override { - auto value = IGF.emitWeakTakeStrong(addr, ValueType); + auto value = IGF.emitNativeWeakTakeStrong(addr, ValueType); // The optional will be lowered to an integer type the size of the word. out.add(IGF.Builder.CreatePtrToInt(value, getOptionalIntType())); } @@ -497,7 +510,7 @@ namespace { // The optional will be lowered to an integer type the size of the word. assert(value->getType() == getOptionalIntType()); value = IGF.Builder.CreateIntToPtr(value, ValueType); - IGF.emitWeakInit(value, dest); + IGF.emitNativeWeakInit(value, dest); } void weakAssign(IRGenFunction &IGF, Explosion &in, @@ -506,28 +519,11 @@ namespace { // The optional will be lowered to an integer type the size of the word. assert(value->getType() == getOptionalIntType()); value = IGF.Builder.CreateIntToPtr(value, ValueType); - IGF.emitWeakAssign(value, dest); + IGF.emitNativeWeakAssign(value, dest); } }; } -const UnownedTypeInfo * -TypeConverter::createSwiftUnownedStorageType(llvm::Type *valueType) { - return new SwiftUnownedReferenceTypeInfo(valueType, - IGM.getHeapObjectSpareBits(), - IGM.getPointerSize(), - IGM.getPointerAlignment()); -} - -const WeakTypeInfo * -TypeConverter::createSwiftWeakStorageType(llvm::Type *valueType) { - return new SwiftWeakReferenceTypeInfo(valueType, - IGM.WeakReferencePtrTy->getElementType(), - IGM.getWeakReferenceSize(), - IGM.getWeakReferenceAlignment(), - IGM.getWeakReferenceSpareBits()); -} - SpareBitVector IRGenModule::getWeakReferenceSpareBits() const { // The runtime needs to be able to freely manipulate live weak // references without worrying about us mucking around with their @@ -536,57 +532,144 @@ SpareBitVector IRGenModule::getWeakReferenceSpareBits() const { false); } +SpareBitVector +IRGenModule::getUnownedReferenceSpareBits(ReferenceCounting style) const { + // If unknown references don't exist, we can just use the same rules as + // regular pointers. + if (!ObjCInterop) { + assert(style == ReferenceCounting::Native); + return getHeapObjectSpareBits(); + } + + // Otherwise, we have to be conservative (even with native + // reference-counting) in order to interoperate with code that might + // be working more generically with the memory/type. + return SpareBitVector::getConstant(getPointerSize().getValueInBits(), false); +} + +unsigned IRGenModule::getUnownedExtraInhabitantCount(ReferenceCounting style) { + if (!ObjCInterop) { + assert(style == ReferenceCounting::Native); + return getHeapObjectExtraInhabitantCount(*this); + } + + return 1; +} + +APInt IRGenModule::getUnownedExtraInhabitantValue(unsigned bits, unsigned index, + ReferenceCounting style) { + if (!ObjCInterop) { + assert(style == ReferenceCounting::Native); + return getHeapObjectFixedExtraInhabitantValue(*this, bits, index, 0); + } + + assert(index == 0); + return APInt(bits, 0); +} + +APInt IRGenModule::getUnownedExtraInhabitantMask(ReferenceCounting style) { + return APInt::getAllOnesValue(getPointerSize().getValueInBits()); +} + +llvm::Value *IRGenFunction::getUnownedExtraInhabitantIndex(Address src, + ReferenceCounting style) { + if (!IGM.ObjCInterop) { + assert(style == ReferenceCounting::Native); + return getHeapObjectExtraInhabitantIndex(*this, src); + } + + assert(src.getAddress()->getType() == IGM.UnownedReferencePtrTy); + src = Builder.CreateStructGEP(src, 0, Size(0)); + llvm::Value *ptr = Builder.CreateLoad(src); + llvm::Value *isNull = Builder.CreateIsNull(ptr); + llvm::Value *result = + Builder.CreateSelect(isNull, Builder.getInt32(0), + llvm::ConstantInt::getSigned(IGM.Int32Ty, -1)); + return result; +} + +void IRGenFunction::storeUnownedExtraInhabitant(llvm::Value *index, + Address dest, + ReferenceCounting style) { + if (!IGM.ObjCInterop) { + assert(style == ReferenceCounting::Native); + return storeHeapObjectExtraInhabitant(*this, index, dest); + } + + // Since there's only one legal extra inhabitant, it has to have + // the null pattern. + assert(dest.getAddress()->getType() == IGM.UnownedReferencePtrTy); + dest = Builder.CreateStructGEP(dest, 0, Size(0)); + llvm::Value *null = llvm::ConstantPointerNull::get(IGM.RefCountedPtrTy); + Builder.CreateStore(null, dest); +} + namespace { /// A type implementation for an [unowned] reference to an object /// that is not necessarily a Swift object. class UnknownUnownedReferenceTypeInfo : - public SingleScalarTypeInfo { + public IndirectTypeInfo { public: - UnknownUnownedReferenceTypeInfo(llvm::Type *type, - const SpareBitVector &spareBits, + UnknownUnownedReferenceTypeInfo(llvm::Type *unownedType, + SpareBitVector &&spareBits, Size size, Alignment alignment) - : SingleScalarTypeInfo(type, size, spareBits, alignment) {} + : IndirectTypeInfo(unownedType, size, std::move(spareBits), alignment, + IsNotPOD, IsNotBitwiseTakable, IsFixedSize) { + } - enum { IsScalarPOD = false }; + void assignWithCopy(IRGenFunction &IGF, Address dest, + Address src, SILType type) const override { + IGF.emitUnknownUnownedCopyAssign(dest, src); + } - void emitScalarRetain(IRGenFunction &IGF, llvm::Value *value) const { - IGF.emitUnknownUnownedRetain(value); + void initializeWithCopy(IRGenFunction &IGF, Address dest, + Address src, SILType type) const override { + IGF.emitUnknownUnownedCopyInit(dest, src); } - void emitScalarRelease(IRGenFunction &IGF, llvm::Value *value) const { - IGF.emitUnknownUnownedRelease(value); + void assignWithTake(IRGenFunction &IGF, Address dest, + Address src, SILType type) const override { + IGF.emitUnknownUnownedTakeAssign(dest, src); } - void emitScalarFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { - IGF.emitFixLifetime(value); + void initializeWithTake(IRGenFunction &IGF, Address dest, + Address src, SILType type) const override { + IGF.emitUnknownUnownedTakeInit(dest, src); } - - // Unowned types have the same spare bits as strong unknown object refs. - - bool mayHaveExtraInhabitants(IRGenModule &IGM) const override { - return true; + + void destroy(IRGenFunction &IGF, Address addr, + SILType type) const override { + IGF.emitUnknownUnownedDestroy(addr); } + // Unowned types have the same extra inhabitants as normal pointers. + // They do not, however, necessarily have any spare bits. + unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override { - return getHeapObjectExtraInhabitantCount(IGM); + return IGM.getUnownedExtraInhabitantCount(ReferenceCounting::Unknown); } APInt getFixedExtraInhabitantValue(IRGenModule &IGM, unsigned bits, unsigned index) const override { - return getHeapObjectFixedExtraInhabitantValue(IGM, bits, index, 0); + return IGM.getUnownedExtraInhabitantValue(bits, index, + ReferenceCounting::Unknown); } llvm::Value *getExtraInhabitantIndex(IRGenFunction &IGF, Address src, - SILType T) - const override { - return getHeapObjectExtraInhabitantIndex(IGF, src); + SILType T) const override { + return IGF.getUnownedExtraInhabitantIndex(src, + ReferenceCounting::Unknown); } void storeExtraInhabitant(IRGenFunction &IGF, llvm::Value *index, Address dest, SILType T) const override { - return storeHeapObjectExtraInhabitant(IGF, index, dest); + return IGF.storeUnownedExtraInhabitant(index, dest, + ReferenceCounting::Unknown); + } + + APInt getFixedExtraInhabitantMask(IRGenModule &IGM) const override { + return IGM.getUnownedExtraInhabitantMask(ReferenceCounting::Unknown); } }; @@ -669,27 +752,59 @@ namespace { }; } -const UnownedTypeInfo * -TypeConverter::createUnknownUnownedStorageType(llvm::Type *valueType) { - return new UnknownUnownedReferenceTypeInfo(valueType, - IGM.getHeapObjectSpareBits(), - IGM.getPointerSize(), - IGM.getPointerAlignment()); +const TypeInfo *TypeConverter::createUnownedStorageType(llvm::Type *valueType, + ReferenceCounting style) { + auto &&spareBits = IGM.getUnownedReferenceSpareBits(style); + switch (style) { + case ReferenceCounting::Native: + return new NativeUnownedReferenceTypeInfo(valueType, + IGM.UnownedReferencePtrTy->getElementType(), + std::move(spareBits), + IGM.getPointerSize(), + IGM.getPointerAlignment()); + case ReferenceCounting::ObjC: + case ReferenceCounting::Block: + case ReferenceCounting::Unknown: + return new UnknownUnownedReferenceTypeInfo( + IGM.UnownedReferencePtrTy->getElementType(), + std::move(spareBits), + IGM.getPointerSize(), + IGM.getPointerAlignment()); + case ReferenceCounting::Bridge: + case ReferenceCounting::Error: + llvm_unreachable("not supported!"); + } + llvm_unreachable("bad reference-counting style"); } -const WeakTypeInfo * -TypeConverter::createUnknownWeakStorageType(llvm::Type *valueType) { - return new UnknownWeakReferenceTypeInfo(valueType, +const WeakTypeInfo *TypeConverter::createWeakStorageType(llvm::Type *valueType, + ReferenceCounting style) { + switch (style) { + case ReferenceCounting::Native: + return new NativeWeakReferenceTypeInfo(valueType, + IGM.WeakReferencePtrTy->getElementType(), + IGM.getWeakReferenceSize(), + IGM.getWeakReferenceAlignment(), + IGM.getWeakReferenceSpareBits()); + case ReferenceCounting::ObjC: + case ReferenceCounting::Block: + case ReferenceCounting::Unknown: + return new UnknownWeakReferenceTypeInfo(valueType, IGM.WeakReferencePtrTy->getElementType(), - IGM.getWeakReferenceSize(), - IGM.getWeakReferenceAlignment(), - IGM.getWeakReferenceSpareBits()); + IGM.getWeakReferenceSize(), + IGM.getWeakReferenceAlignment(), + IGM.getWeakReferenceSpareBits()); + case ReferenceCounting::Bridge: + case ReferenceCounting::Error: + llvm_unreachable("not supported!"); + } + llvm_unreachable("bad reference-counting style"); } /// Does the given value superficially not require reference-counting? static bool doesNotRequireRefCounting(llvm::Value *value) { // Constants never require reference-counting. - return isa(value); + return isa(value); } static llvm::FunctionType *getTypeOfFunction(llvm::Constant *fn) { @@ -748,8 +863,9 @@ static llvm::Value *emitLoadWeakLikeCall(IRGenFunction &IGF, llvm::Constant *fn, llvm::Value *addr, llvm::Type *resultType) { - assert(addr->getType() == IGF.IGM.WeakReferencePtrTy && - "address is not of a weak reference"); + assert((addr->getType() == IGF.IGM.WeakReferencePtrTy || + addr->getType() == IGF.IGM.UnownedReferencePtrTy) && + "address is not of a weak or unowned reference"); // Instead of casting the output, we cast the function type. // This tends to produce less IR, but might be evil. @@ -775,8 +891,9 @@ static void emitStoreWeakLikeCall(IRGenFunction &IGF, llvm::Constant *fn, llvm::Value *addr, llvm::Value *value) { - assert(addr->getType() == IGF.IGM.WeakReferencePtrTy && - "address is not of a weak reference"); + assert((addr->getType() == IGF.IGM.WeakReferencePtrTy || + addr->getType() == IGF.IGM.UnownedReferencePtrTy) && + "address is not of a weak or unowned reference"); // Instead of casting the inputs, we cast the function type. // This tends to produce less IR, but might be evil. @@ -793,42 +910,25 @@ static void emitStoreWeakLikeCall(IRGenFunction &IGF, call->setDoesNotThrow(); } -/// Emit a call to swift_retain. In general, you should not be using -/// this routine; instead you should use emitRetain, which properly -/// balances the retain. -void IRGenFunction::emitRetainCall(llvm::Value *value) { +/// Emit a call to swift_retain. +void IRGenFunction::emitNativeStrongRetain(llvm::Value *value) { + if (doesNotRequireRefCounting(value)) + return; + // Make sure the input pointer is the right type. if (value->getType() != IGM.RefCountedPtrTy) value = Builder.CreateBitCast(value, IGM.RefCountedPtrTy); // Emit the call. - llvm::CallInst *call = Builder.CreateCall(IGM.getRetainFn(), value); + llvm::CallInst *call = + Builder.CreateCall(IGM.getNativeStrongRetainFn(), value); call->setCallingConv(IGM.RuntimeCC); call->setDoesNotThrow(); } -/// Emit a retain of a value. This is usually not required because -/// values in explosions are typically "live", i.e. have a +1 owned by -/// the explosion. -void IRGenFunction::emitRetain(llvm::Value *value, Explosion &out) { - if (doesNotRequireRefCounting(value)) { - out.add(value); - return; - } - - emitRetainCall(value); - out.add(value); -} - -/// Emit a load of a live value from the given retaining variable. -void IRGenFunction::emitLoadAndRetain(Address address, Explosion &out) { - llvm::Value *value = Builder.CreateLoad(address); - emitRetainCall(value); - out.add(value); -} - /// Emit a store of a live value to the given retaining variable. -void IRGenFunction::emitAssignRetained(llvm::Value *newValue, Address address) { +void IRGenFunction::emitNativeStrongAssign(llvm::Value *newValue, + Address address) { // Pull the old value out of the address. llvm::Value *oldValue = Builder.CreateLoad(address); @@ -836,55 +936,55 @@ void IRGenFunction::emitAssignRetained(llvm::Value *newValue, Address address) { Builder.CreateStore(newValue, address); // Release the old value. - emitRelease(oldValue); + emitNativeStrongRelease(oldValue); } /// Emit an initialize of a live value to the given retaining variable. -void IRGenFunction::emitInitializeRetained(llvm::Value *newValue, - Address address) { +void IRGenFunction::emitNativeStrongInit(llvm::Value *newValue, + Address address) { // We assume the new value is already retained. Builder.CreateStore(newValue, address); } /// Emit a release of a live value with the given refcounting implementation. -void IRGenFunction::emitScalarRelease(llvm::Value *value, +void IRGenFunction::emitStrongRelease(llvm::Value *value, ReferenceCounting refcounting) { switch (refcounting) { case ReferenceCounting::Native: - return emitRelease(value); + return emitNativeStrongRelease(value); case ReferenceCounting::ObjC: - return emitObjCRelease(value); + return emitObjCStrongRelease(value); case ReferenceCounting::Block: return emitBlockRelease(value); case ReferenceCounting::Unknown: - return emitUnknownRelease(value); + return emitUnknownStrongRelease(value); case ReferenceCounting::Bridge: - return emitBridgeRelease(value); + return emitBridgeStrongRelease(value); case ReferenceCounting::Error: - return emitErrorRelease(value); + return emitErrorStrongRelease(value); } } -void IRGenFunction::emitScalarRetainCall(llvm::Value *value, - ReferenceCounting refcounting) { +void IRGenFunction::emitStrongRetain(llvm::Value *value, + ReferenceCounting refcounting) { switch (refcounting) { case ReferenceCounting::Native: - emitRetainCall(value); + emitNativeStrongRetain(value); return; case ReferenceCounting::Bridge: - emitBridgeRetainCall(value); + emitBridgeStrongRetain(value); return; case ReferenceCounting::ObjC: - emitObjCRetainCall(value); + emitObjCStrongRetain(value); return; case ReferenceCounting::Block: emitBlockCopyCall(value); return; case ReferenceCounting::Unknown: - emitUnknownRetainCall(value); + emitUnknownStrongRetain(value); return; case ReferenceCounting::Error: - emitErrorRetainCall(value); + emitErrorStrongRetain(value); return; } } @@ -906,52 +1006,235 @@ llvm::Type *IRGenModule::getReferenceType(ReferenceCounting refcounting) { } } +#define DEFINE_BINARY_OPERATION(KIND, RESULT, TYPE1, TYPE2) \ +RESULT IRGenFunction::emit##KIND(TYPE1 val1, TYPE2 val2, \ + ReferenceCounting style) { \ + switch (style) { \ + case ReferenceCounting::Native: \ + return emitNative##KIND(val1, val2); \ + case ReferenceCounting::ObjC: \ + case ReferenceCounting::Unknown: \ + return emitUnknown##KIND(val1, val2); \ + case ReferenceCounting::Bridge: \ + case ReferenceCounting::Block: \ + case ReferenceCounting::Error: \ + llvm_unreachable("this kind of reference does not support weak/unowned"); \ + } \ + llvm_unreachable("bad refcounting style"); \ +} + +#define DEFINE_UNARY_OPERATION(KIND, RESULT, TYPE1) \ +RESULT IRGenFunction::emit##KIND(TYPE1 val1, ReferenceCounting style) { \ + switch (style) { \ + case ReferenceCounting::Native: \ + return emitNative##KIND(val1); \ + case ReferenceCounting::ObjC: \ + case ReferenceCounting::Unknown: \ + return emitUnknown##KIND(val1); \ + case ReferenceCounting::Bridge: \ + case ReferenceCounting::Block: \ + case ReferenceCounting::Error: \ + llvm_unreachable("this kind of reference does not support weak/unowned"); \ + } \ + llvm_unreachable("bad refcounting style"); \ +} + +DEFINE_BINARY_OPERATION(WeakCopyInit, void, Address, Address) +DEFINE_BINARY_OPERATION(WeakTakeInit, void, Address, Address) +DEFINE_BINARY_OPERATION(WeakCopyAssign, void, Address, Address) +DEFINE_BINARY_OPERATION(WeakTakeAssign, void, Address, Address) +DEFINE_BINARY_OPERATION(WeakInit, void, llvm::Value *, Address) +DEFINE_BINARY_OPERATION(WeakAssign, void, llvm::Value *, Address) +DEFINE_BINARY_OPERATION(WeakLoadStrong, llvm::Value *, Address, llvm::Type *) +DEFINE_BINARY_OPERATION(WeakTakeStrong, llvm::Value *, Address, llvm::Type *) +DEFINE_UNARY_OPERATION(WeakDestroy, void, Address) + +DEFINE_BINARY_OPERATION(UnownedCopyInit, void, Address, Address) +DEFINE_BINARY_OPERATION(UnownedTakeInit, void, Address, Address) +DEFINE_BINARY_OPERATION(UnownedCopyAssign, void, Address, Address) +DEFINE_BINARY_OPERATION(UnownedTakeAssign, void, Address, Address) +DEFINE_BINARY_OPERATION(UnownedInit, void, llvm::Value *, Address) +DEFINE_BINARY_OPERATION(UnownedAssign, void, llvm::Value *, Address) +DEFINE_BINARY_OPERATION(UnownedLoadStrong, llvm::Value *, Address, llvm::Type *) +DEFINE_BINARY_OPERATION(UnownedTakeStrong, llvm::Value *, Address, llvm::Type *) +DEFINE_UNARY_OPERATION(UnownedDestroy, void, Address) + +#undef DEFINE_UNARY_OPERATION +#undef DEFINE_BINARY_OPERATION + +void IRGenFunction::emitUnownedRetain(llvm::Value *value, + ReferenceCounting style) { + assert(style == ReferenceCounting::Native && + "only native references support scalar unowned reference-counting"); + emitNativeUnownedRetain(value); +} + +void IRGenFunction::emitUnownedRelease(llvm::Value *value, + ReferenceCounting style) { + assert(style == ReferenceCounting::Native && + "only native references support scalar unowned reference-counting"); + emitNativeUnownedRelease(value); +} + +void IRGenFunction::emitStrongRetainUnowned(llvm::Value *value, + ReferenceCounting style) { + assert(style == ReferenceCounting::Native && + "only native references support scalar unowned reference-counting"); + emitNativeStrongRetainUnowned(value); +} + +void IRGenFunction::emitStrongRetainAndUnownedRelease(llvm::Value *value, + ReferenceCounting style) { + assert(style == ReferenceCounting::Native && + "only native references support scalar unowned reference-counting"); + emitNativeStrongRetainAndUnownedRelease(value); +} + /// Emit a release of a live value. -void IRGenFunction::emitRelease(llvm::Value *value) { +void IRGenFunction::emitNativeStrongRelease(llvm::Value *value) { if (doesNotRequireRefCounting(value)) return; - emitUnaryRefCountCall(*this, IGM.getReleaseFn(), value); + emitUnaryRefCountCall(*this, IGM.getNativeStrongReleaseFn(), value); +} + +void IRGenFunction::emitNativeUnownedInit(llvm::Value *value, + Address dest) { + dest = Builder.CreateStructGEP(dest, 0, Size(0)); + Builder.CreateStore(value, dest); + emitNativeUnownedRetain(value); +} + +void IRGenFunction::emitNativeUnownedAssign(llvm::Value *value, + Address dest) { + dest = Builder.CreateStructGEP(dest, 0, Size(0)); + auto oldValue = Builder.CreateLoad(dest); + Builder.CreateStore(value, dest); + emitNativeUnownedRetain(value); + emitNativeUnownedRelease(oldValue); +} + +llvm::Value *IRGenFunction::emitNativeUnownedLoadStrong(Address src, + llvm::Type *type) { + src = Builder.CreateStructGEP(src, 0, Size(0)); + llvm::Value *value = Builder.CreateLoad(src); + value = Builder.CreateBitCast(value, type); + emitNativeStrongRetainUnowned(value); + return value; +} + +llvm::Value *IRGenFunction::emitNativeUnownedTakeStrong(Address src, + llvm::Type *type) { + src = Builder.CreateStructGEP(src, 0, Size(0)); + llvm::Value *value = Builder.CreateLoad(src); + value = Builder.CreateBitCast(value, type); + emitNativeStrongRetainAndUnownedRelease(value); + return value; +} + +void IRGenFunction::emitNativeUnownedDestroy(Address ref) { + ref = Builder.CreateStructGEP(ref, 0, Size(0)); + llvm::Value *value = Builder.CreateLoad(ref); + emitNativeUnownedRelease(value); +} + +void IRGenFunction::emitNativeUnownedCopyInit(Address dest, Address src) { + src = Builder.CreateStructGEP(src, 0, Size(0)); + dest = Builder.CreateStructGEP(dest, 0, Size(0)); + llvm::Value *newValue = Builder.CreateLoad(src); + Builder.CreateStore(newValue, dest); + emitNativeUnownedRetain(newValue); +} + +void IRGenFunction::emitNativeUnownedTakeInit(Address dest, Address src) { + src = Builder.CreateStructGEP(src, 0, Size(0)); + dest = Builder.CreateStructGEP(dest, 0, Size(0)); + llvm::Value *newValue = Builder.CreateLoad(src); + Builder.CreateStore(newValue, dest); +} + +void IRGenFunction::emitNativeUnownedCopyAssign(Address dest, Address src) { + src = Builder.CreateStructGEP(src, 0, Size(0)); + dest = Builder.CreateStructGEP(dest, 0, Size(0)); + llvm::Value *newValue = Builder.CreateLoad(src); + llvm::Value *oldValue = Builder.CreateLoad(dest); + Builder.CreateStore(newValue, dest); + emitNativeUnownedRetain(newValue); + emitNativeUnownedRelease(oldValue); +} + +void IRGenFunction::emitNativeUnownedTakeAssign(Address dest, Address src) { + src = Builder.CreateStructGEP(src, 0, Size(0)); + dest = Builder.CreateStructGEP(dest, 0, Size(0)); + llvm::Value *newValue = Builder.CreateLoad(src); + llvm::Value *oldValue = Builder.CreateLoad(dest); + Builder.CreateStore(newValue, dest); + emitNativeUnownedRelease(oldValue); +} + +llvm::Constant *IRGenModule::getFixLifetimeFn() { + if (FixLifetimeFn) + return FixLifetimeFn; + + // Generate a private stub function for the LLVM ARC optimizer to recognize. + auto fixLifetimeTy = llvm::FunctionType::get(VoidTy, RefCountedPtrTy, + /*isVarArg*/ false); + auto fixLifetime = llvm::Function::Create(fixLifetimeTy, + llvm::GlobalValue::PrivateLinkage, + "__swift_fixLifetime", + &Module); + assert(fixLifetime->getName().equals("__swift_fixLifetime") + && "fixLifetime symbol name got mangled?!"); + // Don't inline the function, so it stays as a signal to the ARC passes. + // The ARC passes will remove references to the function when they're + // no longer needed. + fixLifetime->addAttribute(llvm::AttributeSet::FunctionIndex, + llvm::Attribute::NoInline); + + // Give the function an empty body. + auto entry = llvm::BasicBlock::Create(LLVMContext, "", fixLifetime); + llvm::ReturnInst::Create(LLVMContext, entry); + + FixLifetimeFn = fixLifetime; + return fixLifetime; } /// Fix the lifetime of a live value. This communicates to the LLVM level ARC /// optimizer not to touch this value. void IRGenFunction::emitFixLifetime(llvm::Value *value) { + // If we aren't running the LLVM ARC optimizer, we don't need to emit this. + if (!IGM.Opts.Optimize || IGM.Opts.DisableLLVMARCOpts) + return; if (doesNotRequireRefCounting(value)) return; emitUnaryRefCountCall(*this, IGM.getFixLifetimeFn(), value); } -llvm::Value *IRGenFunction::emitUnknownRetainCall(llvm::Value *value) { +void IRGenFunction::emitUnknownStrongRetain(llvm::Value *value) { + if (doesNotRequireRefCounting(value)) return; emitUnaryRefCountCall(*this, IGM.getUnknownRetainFn(), value); - return value; } -void IRGenFunction::emitUnknownRelease(llvm::Value *value) { +void IRGenFunction::emitUnknownStrongRelease(llvm::Value *value) { + if (doesNotRequireRefCounting(value)) return; emitUnaryRefCountCall(*this, IGM.getUnknownReleaseFn(), value); } -llvm::Value *IRGenFunction::emitBridgeRetainCall(llvm::Value *value) { - emitUnaryRefCountCall(*this, IGM.getBridgeObjectRetainFn(), value); - return value; -} - -void IRGenFunction::emitBridgeRelease(llvm::Value *value) { - emitUnaryRefCountCall(*this, IGM.getBridgeObjectReleaseFn(), value); +void IRGenFunction::emitBridgeStrongRetain(llvm::Value *value) { + emitUnaryRefCountCall(*this, IGM.getBridgeObjectStrongRetainFn(), value); } -void IRGenFunction::emitErrorRetain(llvm::Value *value) { - emitUnaryRefCountCall(*this, IGM.getErrorRetainFn(), value); +void IRGenFunction::emitBridgeStrongRelease(llvm::Value *value) { + emitUnaryRefCountCall(*this, IGM.getBridgeObjectStrongReleaseFn(), value); } -llvm::Value *IRGenFunction::emitErrorRetainCall(llvm::Value *value) { - emitUnaryRefCountCall(*this, IGM.getErrorRetainFn(), value); - return value; +void IRGenFunction::emitErrorStrongRetain(llvm::Value *value) { + emitUnaryRefCountCall(*this, IGM.getErrorStrongRetainFn(), value); } -void IRGenFunction::emitErrorRelease(llvm::Value *value) { - emitUnaryRefCountCall(*this, IGM.getErrorReleaseFn(), value); +void IRGenFunction::emitErrorStrongRelease(llvm::Value *value) { + emitUnaryRefCountCall(*this, IGM.getErrorStrongReleaseFn(), value); } -llvm::Value *IRGenFunction::emitTryPin(llvm::Value *value) { - llvm::CallInst *call = Builder.CreateCall(IGM.getTryPinFn(), value); +llvm::Value *IRGenFunction::emitNativeTryPin(llvm::Value *value) { + llvm::CallInst *call = Builder.CreateCall(IGM.getNativeTryPinFn(), value); call->setCallingConv(IGM.RuntimeCC); call->setDoesNotThrow(); @@ -960,30 +1243,19 @@ llvm::Value *IRGenFunction::emitTryPin(llvm::Value *value) { return handle; } -void IRGenFunction::emitUnpin(llvm::Value *value) { +void IRGenFunction::emitNativeUnpin(llvm::Value *value) { // Builtin.NativeObject? has representation i32/i64. value = Builder.CreateIntToPtr(value, IGM.RefCountedPtrTy); - llvm::CallInst *call = Builder.CreateCall(IGM.getUnpinFn(), value); + llvm::CallInst *call = Builder.CreateCall(IGM.getNativeUnpinFn(), value); call->setCallingConv(IGM.RuntimeCC); call->setDoesNotThrow(); } -llvm::Value *IRGenFunction::emitLoadNativeRefcountedPtr(Address addr) { - Address src = - Builder.CreateBitCast(addr, IGM.RefCountedPtrTy->getPointerTo()); - return Builder.CreateLoad(src); -} - -llvm::Value *IRGenFunction::emitLoadUnknownRefcountedPtr(Address addr) { - Address src = - Builder.CreateBitCast(addr, IGM.UnknownRefCountedPtrTy->getPointerTo()); - return Builder.CreateLoad(src); -} - -llvm::Value *IRGenFunction::emitLoadBridgeRefcountedPtr(Address addr) { +llvm::Value *IRGenFunction::emitLoadRefcountedPtr(Address addr, + ReferenceCounting style) { Address src = - Builder.CreateBitCast(addr, IGM.BridgeObjectPtrTy->getPointerTo()); + Builder.CreateBitCast(addr, IGM.getReferenceType(style)->getPointerTo()); return Builder.CreateLoad(src); } @@ -1290,21 +1562,28 @@ void IRGenFunction::emit##ID(llvm::Value *value, Address src) { \ src.getAddress(), value); \ } -DEFINE_VALUE_OP(RetainUnowned) -DEFINE_VALUE_OP(UnownedRelease) -DEFINE_VALUE_OP(UnownedRetain) -DEFINE_LOAD_WEAK_OP(WeakLoadStrong) -DEFINE_LOAD_WEAK_OP(WeakTakeStrong) -DEFINE_STORE_WEAK_OP(WeakInit) -DEFINE_STORE_WEAK_OP(WeakAssign) -DEFINE_ADDR_OP(WeakDestroy) -DEFINE_COPY_OP(WeakCopyInit) -DEFINE_COPY_OP(WeakCopyAssign) -DEFINE_COPY_OP(WeakTakeInit) -DEFINE_COPY_OP(WeakTakeAssign) -DEFINE_VALUE_OP(UnknownRetainUnowned) -DEFINE_VALUE_OP(UnknownUnownedRelease) -DEFINE_VALUE_OP(UnknownUnownedRetain) +DEFINE_VALUE_OP(NativeStrongRetainUnowned) +DEFINE_VALUE_OP(NativeStrongRetainAndUnownedRelease) +DEFINE_VALUE_OP(NativeUnownedRelease) +DEFINE_VALUE_OP(NativeUnownedRetain) +DEFINE_LOAD_WEAK_OP(NativeWeakLoadStrong) +DEFINE_LOAD_WEAK_OP(NativeWeakTakeStrong) +DEFINE_STORE_WEAK_OP(NativeWeakInit) +DEFINE_STORE_WEAK_OP(NativeWeakAssign) +DEFINE_ADDR_OP(NativeWeakDestroy) +DEFINE_COPY_OP(NativeWeakCopyInit) +DEFINE_COPY_OP(NativeWeakCopyAssign) +DEFINE_COPY_OP(NativeWeakTakeInit) +DEFINE_COPY_OP(NativeWeakTakeAssign) +DEFINE_LOAD_WEAK_OP(UnknownUnownedLoadStrong) +DEFINE_LOAD_WEAK_OP(UnknownUnownedTakeStrong) +DEFINE_STORE_WEAK_OP(UnknownUnownedInit) +DEFINE_STORE_WEAK_OP(UnknownUnownedAssign) +DEFINE_ADDR_OP(UnknownUnownedDestroy) +DEFINE_COPY_OP(UnknownUnownedCopyInit) +DEFINE_COPY_OP(UnknownUnownedCopyAssign) +DEFINE_COPY_OP(UnknownUnownedTakeInit) +DEFINE_COPY_OP(UnknownUnownedTakeAssign) DEFINE_LOAD_WEAK_OP(UnknownWeakLoadStrong) DEFINE_LOAD_WEAK_OP(UnknownWeakTakeStrong) DEFINE_STORE_WEAK_OP(UnknownWeakInit) diff --git a/lib/IRGen/GenHeap.h b/lib/IRGen/GenHeap.h index c77918be496ce..56750c8f1e911 100644 --- a/lib/IRGen/GenHeap.h +++ b/lib/IRGen/GenHeap.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenInit.cpp b/lib/IRGen/GenInit.cpp index 7a13df7bee74e..c2abf240ab18b 100644 --- a/lib/IRGen/GenInit.cpp +++ b/lib/IRGen/GenInit.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -62,12 +62,14 @@ ContainedAddress FixedTypeInfo::allocateStack(IRGenFunction &IGF, SILType T, Address alloca = IGF.createAlloca(getStorageType(), getFixedAlignment(), name); - // TODO: lifetime intrinsics? - + IGF.Builder.CreateLifetimeStart(alloca, getFixedSize()); + return { alloca, alloca }; } void FixedTypeInfo::deallocateStack(IRGenFunction &IGF, Address addr, SILType T) const { - // TODO: lifetime intrinsics? + if (isKnownEmpty()) + return; + IGF.Builder.CreateLifetimeEnd(addr, getFixedSize()); } diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index b553ee9301fe8..1e6edc0df86a9 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -59,6 +59,12 @@ using namespace irgen; static llvm::Value *emitLoadOfObjCHeapMetadataRef(IRGenFunction &IGF, llvm::Value *object); +static llvm::LoadInst * +emitLoadFromMetadataAtIndex(IRGenFunction &IGF, + llvm::Value *metadata, + int index, + llvm::Type *objectTy, + const llvm::Twine &suffix = ""); /// Produce a constant to place in a metatype's isa field /// corresponding to the given metadata kind. @@ -119,11 +125,12 @@ namespace { SmallVector Types; void collect(IRGenFunction &IGF, BoundGenericType *type) { + auto subs = type->getSubstitutions(/*FIXME:*/nullptr, nullptr); // Add all the argument archetypes. // TODO: only the *primary* archetypes // TODO: not archetypes from outer contexts // TODO: but we are partially determined by the outer context! - for (auto &sub : type->getSubstitutions(/*FIXME:*/nullptr, nullptr)) { + for (auto &sub : subs) { CanType subbed = sub.getReplacement()->getCanonicalType(); Values.push_back(IGF.emitTypeMetadataRef(subbed)); } @@ -132,8 +139,10 @@ namespace { Types.append(Values.size(), IGF.IGM.TypeMetadataPtrTy); // Add protocol witness tables for all those archetypes. - for (auto &sub : type->getSubstitutions(/*FIXME:*/nullptr, nullptr)) - emitWitnessTableRefs(IGF, sub, Values); + for (auto i : indices(subs)) { + llvm::Value *metadata = Values[i]; + emitWitnessTableRefs(IGF, subs[i], &metadata, Values); + } // All of those values are witness table pointers. Types.append(Values.size() - Types.size(), IGF.IGM.WitnessTablePtrTy); @@ -162,20 +171,17 @@ static void emitPolymorphicParametersFromArray(IRGenFunction &IGF, llvm::Value *metadata = claimNext(IGF.IGM.TypeMetadataPtrTy); metadata->setName(archetype->getFullName()); IGF.setUnscopedLocalTypeData(CanType(archetype), - LocalTypeData::forMetatype(), + LocalTypeDataKind::forMetatype(), metadata); } // Bind all the argument witness tables. for (auto archetype : generics.getAllArchetypes()) { - unsigned nextProtocolIndex = 0; for (auto protocol : archetype->getConformsTo()) { - LocalTypeData key - = LocalTypeData::forArchetypeProtocolWitness(nextProtocolIndex); - nextProtocolIndex++; if (!Lowering::TypeConverter::protocolRequiresWitnessTable(protocol)) continue; llvm::Value *wtable = claimNext(IGF.IGM.WitnessTablePtrTy); + auto key = LocalTypeDataKind::forArchetypeProtocolWitnessTable(protocol); IGF.setUnscopedLocalTypeData(CanType(archetype), key, wtable); } } @@ -188,16 +194,19 @@ static bool hasMetadataPattern(IRGenModule &IGM, NominalTypeDecl *theDecl) { // Protocols must be special-cased in a few places. assert(!isa(theDecl)); - // Classes imported from Objective-C never have a metadata pattern. - if (theDecl->hasClangNode()) - return false; + // For classes, we already computed this when we did the layout. + // FIXME: Try not to call this for classes of other modules, by referencing + // the metadata accessor instead. + if (auto *theClass = dyn_cast(theDecl)) + return getClassHasMetadataPattern(IGM, theClass); - // A generic class, struct, or enum is always initialized at runtime. + // Ok, we have a value type. If it is generic, it is always initialized + // at runtime. if (theDecl->isGenericContext()) return true; - // If we have fields of resilient type, the metadata still has to be - // initialized at runtime. + // If the type is not fixed-size, its size depends on resilient types, + // and the metadata is initialized at runtime. if (!IGM.getTypeInfoForUnlowered(theDecl->getDeclaredType()).isFixedSize()) return true; @@ -206,7 +215,7 @@ static bool hasMetadataPattern(IRGenModule &IGM, NominalTypeDecl *theDecl) { /// Attempts to return a constant heap metadata reference for a /// nominal type. -llvm::Constant *irgen::tryEmitConstantHeapMetadataRef(IRGenModule &IGM, +llvm::Constant *irgen::tryEmitConstantTypeMetadataRef(IRGenModule &IGM, CanType type) { auto theDecl = type->getAnyNominal(); assert(theDecl && "emitting constant metadata ref for non-nominal type?"); @@ -283,7 +292,7 @@ static llvm::Value *emitNominalMetadataRef(IRGenFunction &IGF, // reference already. if (isPattern) { if (auto cache = IGF.tryGetLocalTypeData(theType, - LocalTypeData::forMetatype())) + LocalTypeDataKind::forMetatype())) return cache; } @@ -319,7 +328,8 @@ static llvm::Value *emitNominalMetadataRef(IRGenFunction &IGF, result->setDoesNotThrow(); result->addAttribute(llvm::AttributeSet::FunctionIndex, llvm::Attribute::ReadNone); - IGF.setScopedLocalTypeData(theType, LocalTypeData::forMetatype(), result); + IGF.setScopedLocalTypeData(theType, LocalTypeDataKind::forMetatype(), + result); return result; } @@ -350,7 +360,8 @@ static llvm::Value *emitNominalMetadataRef(IRGenFunction &IGF, result->setDoesNotThrow(); result->addAttribute(llvm::AttributeSet::FunctionIndex, llvm::Attribute::ReadNone); - IGF.setScopedLocalTypeData(theType, LocalTypeData::forMetatype(), result); + IGF.setScopedLocalTypeData(theType, LocalTypeDataKind::forMetatype(), + result); return result; } @@ -360,6 +371,8 @@ static llvm::Value *emitNominalMetadataRef(IRGenFunction &IGF, Address argsBuffer = IGF.createAlloca(argsBufferTy, IGF.IGM.getPointerAlignment(), "generic.arguments"); + IGF.Builder.CreateLifetimeStart(argsBuffer, + IGF.IGM.getPointerSize() * genericArgs.Values.size()); for (unsigned i = 0, e = genericArgs.Values.size(); i != e; ++i) { Address elt = IGF.Builder.CreateStructGEP(argsBuffer, i, IGF.IGM.getPointerSize() * i); @@ -377,7 +390,10 @@ static llvm::Value *emitNominalMetadataRef(IRGenFunction &IGF, result->addAttribute(llvm::AttributeSet::FunctionIndex, llvm::Attribute::ReadOnly); - IGF.setScopedLocalTypeData(theType, LocalTypeData::forMetatype(), result); + IGF.Builder.CreateLifetimeEnd(argsBuffer, + IGF.IGM.getPointerSize() * genericArgs.Values.size()); + + IGF.setScopedLocalTypeData(theType, LocalTypeDataKind::forMetatype(), result); return result; } @@ -422,16 +438,38 @@ bool irgen::hasKnownVTableEntry(IRGenModule &IGM, return hasKnownSwiftImplementation(IGM, theClass); } -/// If we have a non-generic struct or enum whose size does not -/// depend on any opaque resilient types, we can access metadata -/// directly. Otherwise, call an accessor. -/// -/// FIXME: Really, we want to use accessors for any nominal type -/// defined in a different module, too. +static bool hasBuiltinTypeMetadata(CanType type) { + // The empty tuple type has a singleton metadata. + if (auto tuple = dyn_cast(type)) + return tuple->getNumElements() == 0; + + // The builtin types generally don't require metadata, but some of them + // have nodes in the runtime anyway. + if (isa(type)) + return true; + + // SIL box types are artificial, but for the purposes of dynamic layout, + // we use the NativeObject metadata. + if (isa(type)) + return true; + + return false; +} + +/// Is it basically trivial to access the given metadata? If so, we don't +/// need a cache variable in its accessor. static bool isTypeMetadataAccessTrivial(IRGenModule &IGM, CanType type) { - if (isa(type) || isa(type)) - if (IGM.getTypeInfoForLowered(type).isFixedSize()) - return true; + // Value type metadata only requires dynamic initialization on first + // access if it contains a resilient type. + if (isa(type) || isa(type)) { + assert(!cast(type)->getDecl()->isGenericContext() && + "shouldn't be called for a generic type"); + return (IGM.getTypeInfoForLowered(type).isFixedSize()); + } + + if (hasBuiltinTypeMetadata(type)) { + return true; + } return false; } @@ -450,12 +488,16 @@ irgen::getTypeMetadataAccessStrategy(IRGenModule &IGM, CanType type, // the metadata for the existential type. auto nominal = dyn_cast(type); if (nominal && !isa(nominal)) { - assert(!nominal->getDecl()->isGenericContext()); + if (nominal->getDecl()->isGenericContext()) + return MetadataAccessStrategy::NonUniqueAccessor; if (preferDirectAccess && isTypeMetadataAccessTrivial(IGM, type)) return MetadataAccessStrategy::Direct; + // If the type doesn't guarantee that it has an access function, + // we might have to use a non-unique accessor. + // Everything else requires accessors. switch (getDeclLinkage(nominal->getDecl())) { case FormalLinkage::PublicUnique: @@ -472,21 +514,12 @@ irgen::getTypeMetadataAccessStrategy(IRGenModule &IGM, CanType type, llvm_unreachable("bad formal linkage"); } - // Builtin types are assumed to be implemented with metadata in the runtime. - if (isa(type)) - return MetadataAccessStrategy::Direct; - // DynamicSelfType is actually local. if (type->hasDynamicSelfType()) return MetadataAccessStrategy::Direct; - // The zero-element tuple has special metadata in the runtime. - if (auto tuple = dyn_cast(type)) - if (tuple->getNumElements() == 0) - return MetadataAccessStrategy::Direct; - - // SIL box types are opaque to the runtime; NativeObject stands in for them. - if (isa(type)) + // Some types have special metadata in the runtime. + if (hasBuiltinTypeMetadata(type)) return MetadataAccessStrategy::Direct; // Everything else requires a shared accessor function. @@ -661,6 +694,8 @@ namespace { elements.size()); Address buffer = IGF.createAlloca(arrayTy,IGF.IGM.getPointerAlignment(), "tuple-elements"); + IGF.Builder.CreateLifetimeStart(buffer, + IGF.IGM.getPointerSize() * elements.size()); for (unsigned i = 0, e = elements.size(); i != e; ++i) { // Find the metadata pointer for this element. llvm::Value *eltMetadata = IGF.emitTypeMetadataRef(elements[i]); @@ -686,6 +721,9 @@ namespace { call->setDoesNotThrow(); call->setCallingConv(IGF.IGM.RuntimeCC); + IGF.Builder.CreateLifetimeEnd(buffer, + IGF.IGM.getPointerSize() * elements.size()); + return setLocal(type, call); } } @@ -810,6 +848,8 @@ namespace { Address buffer = IGF.createAlloca(arrayTy, IGF.IGM.getPointerAlignment(), "function-arguments"); + IGF.Builder.CreateLifetimeStart(buffer, + IGF.IGM.getPointerSize() * arguments.size()); Address pointerToFirstArg = IGF.Builder.CreateStructGEP(buffer, 0, Size(0)); Address flagsPtr = IGF.Builder.CreateBitCast(pointerToFirstArg, @@ -835,6 +875,10 @@ namespace { pointerToFirstArg.getAddress()); call->setDoesNotThrow(); call->setCallingConv(IGF.IGM.RuntimeCC); + + IGF.Builder.CreateLifetimeEnd(buffer, + IGF.IGM.getPointerSize() * arguments.size()); + return setLocal(type, call); } } @@ -882,6 +926,8 @@ namespace { Address descriptorArray = IGF.createAlloca(descriptorArrayTy, IGF.IGM.getPointerAlignment(), "protocols"); + IGF.Builder.CreateLifetimeStart(descriptorArray, + IGF.IGM.getPointerSize() * protocols.size()); descriptorArray = IGF.Builder.CreateBitCast(descriptorArray, IGF.IGM.ProtocolDescriptorPtrTy->getPointerTo()); @@ -899,6 +945,8 @@ namespace { descriptorArray.getAddress()}); call->setDoesNotThrow(); call->setCallingConv(IGF.IGM.RuntimeCC); + IGF.Builder.CreateLifetimeEnd(descriptorArray, + IGF.IGM.getPointerSize() * protocols.size()); return setLocal(type, call); } @@ -920,7 +968,7 @@ namespace { } llvm::Value *visitArchetypeType(CanArchetypeType type) { - return IGF.getLocalTypeData(type, LocalTypeData::forMetatype()); + return IGF.getLocalTypeData(type, LocalTypeDataKind::forMetatype()); } llvm::Value *visitGenericTypeParamType(CanGenericTypeParamType type) { @@ -949,12 +997,12 @@ namespace { /// Try to find the metatype in local data. llvm::Value *tryGetLocal(CanType type) { - return IGF.tryGetLocalTypeData(type, LocalTypeData::forMetatype()); + return IGF.tryGetLocalTypeData(type, LocalTypeDataKind::forMetatype()); } /// Set the metatype in local data. llvm::Value *setLocal(CanType type, llvm::Instruction *metatype) { - IGF.setScopedLocalTypeData(type, LocalTypeData::forMetatype(), + IGF.setScopedLocalTypeData(type, LocalTypeDataKind::forMetatype(), metatype); return metatype; } @@ -978,70 +1026,6 @@ static Address emitAddressOfSuperclassRefInClassMetadata(IRGenFunction &IGF, return IGF.Builder.CreateConstArrayGEP(addr, index, IGF.IGM.getPointerSize()); } -static void emitInitializeSuperclassOfMetaclass(IRGenFunction &IGF, - llvm::Value *metaclass, - llvm::Value *superMetadata) { - assert(IGF.IGM.ObjCInterop && "metaclasses only matter for ObjC interop"); - - // The superclass of the metaclass is the metaclass of the superclass. - - // Read the superclass's metaclass. - llvm::Value *superMetaClass = - emitLoadOfObjCHeapMetadataRef(IGF, superMetadata); - superMetaClass = IGF.Builder.CreateBitCast(superMetaClass, - IGF.IGM.TypeMetadataPtrTy); - - // Write to the new metaclass's superclass field. - Address metaSuperField - = emitAddressOfSuperclassRefInClassMetadata(IGF, metaclass); - - IGF.Builder.CreateStore(superMetaClass, metaSuperField); -} - -static llvm::Value *emitCallToTypeMetadataAccessFunction(IRGenFunction &IGF, - CanType type, - ForDefinition_t shouldDefine); - -/// Emit runtime initialization that must occur before a type metadata access. -/// -/// This initialization must be dependency-ordered-before any loads from -/// the initialized metadata pointer. -static void emitDirectTypeMetadataInitialization(IRGenFunction &IGF, - CanType type) { - // Currently only concrete subclasses of generic bases need this. - auto classDecl = type->getClassOrBoundGenericClass(); - if (!classDecl) - return; - if (classDecl->isGenericContext()) - return; - auto superclass = type->getSuperclass(nullptr); - if (!superclass) - return; - - // If any ancestors are generic, we need to trigger the superclass's - // initialization. - auto ancestor = superclass; - while (ancestor) { - if (ancestor->getClassOrBoundGenericClass()->isGenericContext()) - goto initialize_super; - - ancestor = ancestor->getSuperclass(nullptr); - } - // No generic ancestors. - return; - -initialize_super: - auto classMetadata = IGF.IGM.getAddrOfTypeMetadata(type, /*pattern*/ false); - // Get the superclass metadata. - auto superMetadata = IGF.emitTypeMetadataRef(superclass->getCanonicalType()); - - // Ask the runtime to initialize the superclass of the metaclass. - // This function will ensure the initialization is dependency-ordered-before - // any loads from the base class metadata. - auto initFn = IGF.IGM.getInitializeSuperclassFn(); - IGF.Builder.CreateCall(initFn, {classMetadata, superMetadata}); -} - /// Emit the body of a lazy cache accessor. /// /// If cacheVariable is null, we perform the direct access every time. @@ -1154,7 +1138,6 @@ static llvm::Function *getTypeMetadataAccessFunction(IRGenModule &IGM, emitLazyCacheAccessFunction(IGM, accessor, cacheVariable, [&](IRGenFunction &IGF) -> llvm::Value* { - emitDirectTypeMetadataInitialization(IGF, type); return emitDirectTypeMetadataRef(IGF, type); }); @@ -1165,16 +1148,12 @@ static llvm::Function *getTypeMetadataAccessFunction(IRGenModule &IGM, /// for the given type. static void maybeEmitTypeMetadataAccessFunction(IRGenModule &IGM, NominalTypeDecl *theDecl) { - CanType declaredType = theDecl->getDeclaredType()->getCanonicalType(); + // Currently, we always emit type metadata access functions for + // the non-generic types we define. + if (theDecl->isGenericContext()) return; - // FIXME: Also do this for generic structs. - // FIXME: Internal types with availability from another module can be - // referenced from @_transparent functions. - if (!theDecl->isGenericContext() && - (isa(theDecl) || - theDecl->getFormalAccess() == Accessibility::Public || - !IGM.getTypeInfoForLowered(declaredType).isFixedSize())) - (void) getTypeMetadataAccessFunction(IGM, declaredType, ForDefinition); + CanType declaredType = theDecl->getDeclaredType()->getCanonicalType(); + (void) getTypeMetadataAccessFunction(IGM, declaredType, ForDefinition); } /// Emit a call to the type metadata accessor for the given function. @@ -1182,7 +1161,8 @@ static llvm::Value *emitCallToTypeMetadataAccessFunction(IRGenFunction &IGF, CanType type, ForDefinition_t shouldDefine) { // If we already cached the metadata, use it. - if (auto local = IGF.tryGetLocalTypeData(type, LocalTypeData::forMetatype())) + if (auto local = + IGF.tryGetLocalTypeData(type, LocalTypeDataKind::forMetatype())) return local; llvm::Constant *accessor = @@ -1193,7 +1173,7 @@ static llvm::Value *emitCallToTypeMetadataAccessFunction(IRGenFunction &IGF, call->setDoesNotThrow(); // Save the metadata for future lookups. - IGF.setScopedLocalTypeData(type, LocalTypeData::forMetatype(), call); + IGF.setScopedLocalTypeData(type, LocalTypeDataKind::forMetatype(), call); return call; } @@ -1218,6 +1198,26 @@ llvm::Value *IRGenFunction::emitTypeMetadataRef(CanType type) { return emitDirectTypeMetadataRef(*this, type); } +/// Return the address of a function that will return type metadata +/// for the given non-dependent type. +llvm::Function *irgen::getOrCreateTypeMetadataAccessFunction(IRGenModule &IGM, + CanType type) { + assert(!type->hasArchetype() && + "cannot create global function to return dependent type metadata"); + + switch (getTypeMetadataAccessStrategy(IGM, type, + /*preferDirectAccess=*/false)) { + case MetadataAccessStrategy::PublicUniqueAccessor: + case MetadataAccessStrategy::HiddenUniqueAccessor: + case MetadataAccessStrategy::PrivateAccessor: + return getTypeMetadataAccessFunction(IGM, type, NotForDefinition); + case MetadataAccessStrategy::Direct: + case MetadataAccessStrategy::NonUniqueAccessor: + return getTypeMetadataAccessFunction(IGM, type, ForDefinition); + } + llvm_unreachable("bad type metadata access strategy"); +} + namespace { /// A visitor class for emitting a reference to a metatype object. /// This implements a "raw" access, useful for implementing cache @@ -1307,6 +1307,8 @@ namespace { elements.size()); Address buffer = IGF.createAlloca(arrayTy,IGF.IGM.getPointerAlignment(), "tuple-elements"); + IGF.Builder.CreateLifetimeStart(buffer, + IGF.IGM.getPointerSize() * elements.size()); for (unsigned i = 0, e = elements.size(); i != e; ++i) { // Find the metadata pointer for this element. llvm::Value *eltMetadata = visit(elements[i]); @@ -1333,6 +1335,9 @@ namespace { call->setDoesNotThrow(); call->setCallingConv(IGF.IGM.RuntimeCC); + IGF.Builder.CreateLifetimeEnd(buffer, + IGF.IGM.getPointerSize() * elements.size()); + return setLocal(type, call); } } @@ -1395,13 +1400,13 @@ namespace { llvm::Value *tryGetLocal(CanType type) { return IGF.tryGetLocalTypeDataForLayout( SILType::getPrimitiveObjectType(type), - LocalTypeData::forMetatype()); + LocalTypeDataKind::forMetatype()); } /// Set the metatype in local data. llvm::Value *setLocal(CanType type, llvm::Instruction *metatype) { IGF.setScopedLocalTypeDataForLayout(SILType::getPrimitiveObjectType(type), - LocalTypeData::forMetatype(), + LocalTypeDataKind::forMetatype(), metatype); return metatype; } @@ -1919,7 +1924,7 @@ namespace { void addGenericMetadataPattern() { NominalTypeDecl *ntd = asImpl().getTarget(); - if (!ntd->getGenericParams()) { + if (!hasMetadataPattern(IGM, ntd)) { // If there are no generic parameters, there's no pattern to link. addWord(llvm::ConstantPointerNull::get(IGM.TypeMetadataPatternPtrTy)); return; @@ -2039,8 +2044,9 @@ namespace { #define BEGIN_METADATA_SEARCHER_0(SEARCHER, DECLKIND) \ struct SEARCHER \ : MetadataSearcher> { \ + using super = MetadataSearcher; \ SEARCHER(IRGenModule &IGM, DECLKIND##Decl *target) \ - : MetadataSearcher(IGM, target) {} + : super(IGM, target) {} #define BEGIN_METADATA_SEARCHER_1(SEARCHER, DECLKIND, TYPE_1, NAME_1) \ struct SEARCHER \ : MetadataSearcher> { \ @@ -2720,7 +2726,7 @@ namespace { value = emitWitnessTableRef(IGF, fillOp.Archetype, fillOp.Protocol); } else { value = IGF.getLocalTypeData(fillOp.Archetype, - LocalTypeData::forMetatype()); + LocalTypeDataKind::forMetatype()); } value = IGF.Builder.CreateBitCast(value, IGM.Int8PtrTy); auto dest = createPointerSizedGEP(IGF, metadataWords, @@ -2896,11 +2902,13 @@ namespace { using super::addStruct; using super::getNextOffset; const StructLayout &Layout; + const ClassLayout &FieldLayout; SILVTable *VTable; ClassMetadataBuilderBase(IRGenModule &IGM, ClassDecl *theClass, - const StructLayout &layout) - : super(IGM, theClass), Layout(layout) { + const StructLayout &layout, + const ClassLayout &fieldLayout) + : super(IGM, theClass), Layout(layout), FieldLayout(fieldLayout) { VTable = IGM.SILMod->lookUpVTable(Target); } @@ -2909,8 +2917,8 @@ namespace { ClassObjectExtents = getSizeOfMetadata(IGM, Target); } - bool HasRuntimeBase = false; bool HasRuntimeParent = false; + public: /// The 'metadata flags' field in a class is actually a pointer to /// the metaclass object for the class. @@ -2987,48 +2995,10 @@ namespace { if (!addReferenceToType(parentType->getCanonicalType())) HasRuntimeParent = true; } - - void addSuperClass() { - // If this is a root class, use SwiftObject as our formal parent. - if (!Target->hasSuperclass()) { - // This is only required for ObjC interoperation. - if (!IGM.ObjCInterop) { - addWord(llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy)); - return; - } - - // We have to do getAddrOfObjCClass ourselves here because - // the ObjC runtime base needs to be ObjC-mangled but isn't - // actually imported from a clang module. - addWord(IGM.getAddrOfObjCClass( - IGM.getObjCRuntimeBaseForSwiftRootClass(Target), - NotForDefinition)); - return; - } - - Type superclassTy - = ArchetypeBuilder::mapTypeIntoContext(Target, - Target->getSuperclass()); - // If the class has any generic heritage, wait until runtime to set up - // the superclass reference. - auto ancestorTy = superclassTy; - while (ancestorTy) { - if (ancestorTy->getClassOrBoundGenericClass()->isGenericContext()) { - // Add a nil placeholder and continue. - addWord(llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy)); - HasRuntimeBase = true; - return; - } - ancestorTy = ancestorTy->getSuperclass(nullptr); - } - - if (!addReferenceToType(superclassTy->getCanonicalType())) - HasRuntimeBase = true; - } bool addReferenceToType(CanType type) { if (llvm::Constant *metadata - = tryEmitConstantHeapMetadataRef(IGM, type)) { + = tryEmitConstantTypeMetadataRef(IGM, type)) { addWord(metadata); return true; } else { @@ -3122,12 +3092,67 @@ namespace { } void addFieldOffset(VarDecl *var) { - // Use a fixed offset if we have one. - if (auto offset = tryEmitClassConstantFragileFieldOffset(IGM,Target,var)) - addWord(offset); - // Otherwise, leave a placeholder for the runtime to populate at runtime. - else - addWord(llvm::ConstantInt::get(IGM.IntPtrTy, 0)); + assert(var->hasStorage()); + + unsigned fieldIndex = FieldLayout.getFieldIndex(var); + llvm::Constant *fieldOffsetOrZero; + auto &element = Layout.getElement(fieldIndex); + + if (element.getKind() == ElementLayout::Kind::Fixed) { + // Use a fixed offset if we have one. + fieldOffsetOrZero = IGM.getSize(element.getByteOffset()); + } else { + // Otherwise, leave a placeholder for the runtime to populate at runtime. + fieldOffsetOrZero = llvm::ConstantInt::get(IGM.IntPtrTy, 0); + } + addWord(fieldOffsetOrZero); + + if (var->getDeclContext() == Target) { + auto access = FieldLayout.AllFieldAccesses[fieldIndex]; + switch (access) { + case FieldAccess::ConstantDirect: + case FieldAccess::NonConstantDirect: { + // Emit a global variable storing the constant field offset. + // If the superclass was imported from Objective-C, the offset + // does not include the superclass size; we rely on the + // Objective-C runtime sliding it down. + // + // TODO: Don't emit the symbol if field has a fixed offset and size + // in all resilience domains + auto offsetAddr = IGM.getAddrOfFieldOffset(var, /*indirect*/ false, + ForDefinition); + auto offsetVar = cast(offsetAddr.getAddress()); + offsetVar->setInitializer(fieldOffsetOrZero); + + // If we know the offset won't change, make it a constant. + offsetVar->setConstant(access == FieldAccess::ConstantDirect); + + break; + } + + case FieldAccess::ConstantIndirect: + // No global variable is needed. + break; + + case FieldAccess::NonConstantIndirect: + // Emit a global variable storing an offset into the field offset + // vector within the class metadata. This access pattern is used + // when the field offset depends on generic parameters. As above, + // the Objective-C runtime will slide the field offsets within the + // class metadata to adjust for the superclass size. + // + // TODO: This isn't plumbed through all the way yet. + auto offsetAddr = IGM.getAddrOfFieldOffset(var, /*indirect*/ true, + ForDefinition); + auto offsetVar = cast(offsetAddr.getAddress()); + offsetVar->setConstant(false); + auto offset = getClassFieldOffset(IGM, Target, var).getValue(); + auto offsetVal = llvm::ConstantInt::get(IGM.IntPtrTy, offset); + offsetVar->setInitializer(offsetVal); + + break; + } + } } void addMethod(SILDeclRef fn) { @@ -3149,7 +3174,7 @@ namespace { } else { // The method is removed by dead method elimination. // It should be never called. We add a pointer to an error function. - addWord(llvm::ConstantExpr::getBitCast(IGM.getDeadMethodErrorFn(), + addWord(llvm::ConstantExpr::getBitCast(IGM.getDeletedMethodErrorFn(), IGM.FunctionPtrTy)); } } @@ -3162,23 +3187,56 @@ namespace { ProtocolDecl *protocol, ClassDecl *forClass) { addWord(llvm::Constant::getNullValue(IGM.WitnessTablePtrTy)); } - - bool hasRuntimeBase() const { - return HasRuntimeBase; - } }; class ClassMetadataBuilder : public ClassMetadataBuilderBase { public: ClassMetadataBuilder(IRGenModule &IGM, ClassDecl *theClass, - const StructLayout &layout) - : ClassMetadataBuilderBase(IGM, theClass, layout) {} + const StructLayout &layout, + const ClassLayout &fieldLayout) + : ClassMetadataBuilderBase(IGM, theClass, layout, fieldLayout) { + + assert(layout.isFixedLayout() && + "non-fixed layout classes require a template"); + // FIXME: Distinguish Objective-C sliding from resilient layout + assert((fieldLayout.MetadataAccess == FieldAccess::ConstantDirect || + fieldLayout.MetadataAccess == FieldAccess::NonConstantDirect) && + "resilient superclasses require a template"); + } llvm::Constant *getInit() { return getInitWithSuggestedType(NumHeapMetadataFields, IGM.FullHeapMetadataStructTy); } + + void addSuperClass() { + // If this is a root class, use SwiftObject as our formal parent. + if (!Target->hasSuperclass()) { + // This is only required for ObjC interoperation. + if (!IGM.ObjCInterop) { + addWord(llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy)); + return; + } + + // We have to do getAddrOfObjCClass ourselves here because + // the ObjC runtime base needs to be ObjC-mangled but isn't + // actually imported from a clang module. + addWord(IGM.getAddrOfObjCClass( + IGM.getObjCRuntimeBaseForSwiftRootClass(Target), + NotForDefinition)); + return; + } + + Type superclassTy + = ArchetypeBuilder::mapTypeIntoContext(Target, + Target->getSuperclass()); + + bool constantSuperclass = + addReferenceToType(superclassTy->getCanonicalType()); + assert(constantSuperclass && "need template if superclass is dependent"); + (void) constantSuperclass; + } }; Address emitAddressOfFieldOffsetVectorInClassMetadata(IRGenFunction &IGF, @@ -3207,14 +3265,6 @@ namespace { { typedef GenericMetadataBuilderBase super; - bool HasDependentSuperclass = false; - bool HasDependentFieldOffsetVector = false; - - std::vector> - AncestorFieldOffsetVectors; - - std::vector AncestorFillOps; - Size MetaclassPtrOffset = Size::invalid(); Size ClassRODataPtrOffset = Size::invalid(); Size MetaclassRODataPtrOffset = Size::invalid(); @@ -3223,19 +3273,18 @@ namespace { Size DependentMetaclassRODataPoint = Size::invalid(); public: GenericClassMetadataBuilder(IRGenModule &IGM, ClassDecl *theClass, - const StructLayout &layout) - : super(IGM, theClass, layout) + const StructLayout &layout, + const ClassLayout &fieldLayout) + : super(IGM, theClass, layout, fieldLayout) { // We need special initialization of metadata objects to trick the ObjC // runtime into initializing them. HasDependentMetadata = true; - - // If the superclass is generic, we'll need to initialize the superclass - // reference at runtime. - if (theClass->hasSuperclass() && - theClass->getSuperclass()->is()) { - HasDependentSuperclass = true; - } + } + + void addSuperClass() { + // Filled in by the runtime. + addWord(llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy)); } llvm::Value *emitAllocateMetadata(IRGenFunction &IGF, @@ -3287,16 +3336,7 @@ namespace { auto isa = IGM.getAddrOfMetaclassObject(rootClass, NotForDefinition); addWord(isa); // super, which is dependent if the superclass is generic - llvm::Constant *super; - if (HasDependentSuperclass) - super = llvm::ConstantPointerNull::get(IGM.ObjCClassPtrTy); - else if (Target->hasSuperclass()) - super = IGM.getAddrOfMetaclassObject( - Target->getSuperclass()->getClassOrBoundGenericClass(), - NotForDefinition); - else - super = isa; - addWord(super); + addWord(llvm::ConstantPointerNull::get(IGM.ObjCClassPtrTy)); // cache addWord(IGM.getObjCEmptyCachePtr()); // vtable @@ -3320,35 +3360,12 @@ namespace { void addDependentValueWitnessTablePattern() { llvm_unreachable("classes should never have dependent vwtables"); } - + void noteStartOfFieldOffsets(ClassDecl *whichClass) { HasDependentMetadata = true; - - if (whichClass == Target) { - // If the metadata contains a field offset vector for the class itself, - // then we need to initialize it at runtime. - HasDependentFieldOffsetVector = true; - return; - } - - // If we have a field offset vector for an ancestor class, we will copy - // it from our superclass metadata at instantiation time. - AncestorFieldOffsetVectors.emplace_back(whichClass, - asImpl().getNextOffset(), - Size::invalid()); } - void noteEndOfFieldOffsets(ClassDecl *whichClass) { - if (whichClass == Target) - return; - - // Mark the end of the ancestor field offset vector. - assert(!AncestorFieldOffsetVectors.empty() - && "no start of ancestor field offsets?!"); - assert(std::get<0>(AncestorFieldOffsetVectors.back()) == whichClass - && "mismatched start of ancestor field offsets?!"); - std::get<2>(AncestorFieldOffsetVectors.back()) = asImpl().getNextOffset(); - } + void noteEndOfFieldOffsets(ClassDecl *whichClass) {} // Suppress GenericMetadataBuilderBase's default behavior of introducing // fill ops for generic arguments unless they belong directly to the target @@ -3359,10 +3376,9 @@ namespace { // Introduce the fill op. GenericMetadataBuilderBase::addGenericArgument(type, forClass); } else { - // Lay out the field, but don't provide the fill op, which we'll get - // from the superclass. + // Lay out the field, but don't fill it in, we will copy it from + // the superclass. HasDependentMetadata = true; - AncestorFillOps.push_back(getNextOffset()); ClassMetadataBuilderBase::addGenericArgument(type, forClass); } } @@ -3376,14 +3392,40 @@ namespace { } else { // Lay out the field, but don't provide the fill op, which we'll get // from the superclass. - HasDependentMetadata = true; - AncestorFillOps.push_back(getNextOffset()); ClassMetadataBuilderBase::addGenericWitnessTable(type, protocol, forClass); } } + // The Objective-C runtime will copy field offsets from the field offset + // vector into field offset globals for us, if present. If there's no + // Objective-C runtime, we have to do this ourselves. + void emitInitializeFieldOffsets(IRGenFunction &IGF, + llvm::Value *metadata) { + unsigned index = FieldLayout.InheritedStoredProperties.size(); + + for (auto prop : Target->getStoredProperties()) { + auto access = FieldLayout.AllFieldAccesses[index]; + if (access == FieldAccess::NonConstantDirect) { + Address offsetA = IGF.IGM.getAddrOfFieldOffset(prop, + /*indirect*/ false, + ForDefinition); + + // We can't use emitClassFieldOffset() here because that creates + // an invariant load, which could be hoisted above the point + // where the metadata becomes fully initialized + Size offset = getClassFieldOffset(IGF.IGM, Target, prop); + int index = getOffsetInWords(IGF.IGM, offset); + auto offsetVal = emitLoadFromMetadataAtIndex(IGF, metadata, index, + IGF.IGM.SizeTy); + IGF.Builder.CreateStore(offsetVal, offsetA); + } + + index++; + } + } + void emitInitializeMetadata(IRGenFunction &IGF, llvm::Value *metadata, llvm::Value *vwtable) { @@ -3442,7 +3484,7 @@ namespace { // NOTE: Unlike other bits of the metadata that should later be removed, // this one is important because things check this value's flags to // determine what kind of object it is. That said, if those checks - // are determined to be removeable, we can remove this as well per + // are determined to be removable, we can remove this as well per // rdar://problem/18801263 assert(!ClassRODataPtrOffset.isInvalid()); Address rodataPtrSlot = createPointerSizedGEP(IGF, metadataPtr, @@ -3471,75 +3513,13 @@ namespace { IGF.Builder.CreateStore(rodata, rodataPtrSlot); } - if (IGF.IGM.ObjCInterop) { - // Generate the runtime name for the class and poke it into the rodata. - auto name = IGF.Builder.CreateCall(IGM.getGetGenericClassObjCNameFn(), - metadata); - name->setDoesNotThrow(); - Size nameOffset(IGM.getPointerAlignment().getValue() > 4 ? 24 : 16); - for (Address rodataPtr : {classRODataPtr, metaclassRODataPtr}) { - auto namePtr = createPointerSizedGEP(IGF, rodataPtr, nameOffset); - namePtr = IGF.Builder.CreateBitCast(namePtr, IGM.Int8PtrPtrTy); - IGF.Builder.CreateStore(name, namePtr); - } - } - - // Get the superclass metadata. - llvm::Value *superMetadata; - if (Target->hasSuperclass()) { - Address superField - = emitAddressOfSuperclassRefInClassMetadata(IGF, metadata); - superMetadata = IGF.Builder.CreateLoad(superField); - } else { - assert(!HasDependentSuperclass - && "dependent superclass without superclass?!"); - superMetadata - = llvm::ConstantPointerNull::get(IGF.IGM.TypeMetadataPtrTy); - } - - // If the superclass is generic, we need to populate the - // superclass field of the metaclass. - if (IGF.IGM.ObjCInterop && HasDependentSuperclass) { - emitInitializeSuperclassOfMetaclass(IGF, metaclass, superMetadata); - } - - // If we have any ancestor generic parameters or field offset vectors, - // copy them from the superclass metadata. - if (!AncestorFieldOffsetVectors.empty() || !AncestorFillOps.empty()) { - Address superBase(superMetadata, IGF.IGM.getPointerAlignment()); - Address selfBase(metadata, IGF.IGM.getPointerAlignment()); - superBase = IGF.Builder.CreateBitCast(superBase, - IGF.IGM.SizeTy->getPointerTo()); - selfBase = IGF.Builder.CreateBitCast(selfBase, - IGF.IGM.SizeTy->getPointerTo()); - - for (Size ancestorOp : AncestorFillOps) { - ancestorOp -= AddressPoint; - Address superOp = createPointerSizedGEP(IGF, superBase, ancestorOp); - Address selfOp = createPointerSizedGEP(IGF, selfBase, ancestorOp); - IGF.Builder.CreateStore(IGF.Builder.CreateLoad(superOp), selfOp); - } - - for (auto &ancestorFields : AncestorFieldOffsetVectors) { - ClassDecl *ancestor; - Size startIndex, endIndex; - std::tie(ancestor, startIndex, endIndex) = ancestorFields; - assert(startIndex <= endIndex); - if (startIndex == endIndex) - continue; - Size size = endIndex - startIndex; - startIndex -= AddressPoint; - - Address superVec = createPointerSizedGEP(IGF, superBase, startIndex); - Address selfVec = createPointerSizedGEP(IGF, selfBase, startIndex); - - IGF.Builder.CreateMemCpy(selfVec, superVec, size); - } - } - - // If the field layout is dependent, ask the runtime to populate the - // offset vector. - if (HasDependentFieldOffsetVector) { + // If we have fields that are not fixed-size, ask the runtime to + // populate the offset vector. + // + // FIXME: if only the superclass is resilient, we can get away + // with sliding field offsets instead of doing the entire layout all + // over again. + if (!Layout.isFixedLayout()) { llvm::Value *fieldVector = emitAddressOfFieldOffsetVectorInClassMetadata(IGF, Target, metadata) @@ -3556,6 +3536,9 @@ namespace { llvm::ArrayType::get(IGF.IGM.SizeTy, storedProperties.size() * 2), IGF.IGM.getPointerAlignment(), "classFields"); + IGF.Builder.CreateLifetimeStart(fields, + IGF.IGM.getPointerSize() * storedProperties.size() * 2); + Address firstField; unsigned index = 0; for (auto prop : storedProperties) { @@ -3587,16 +3570,29 @@ namespace { // Ask the runtime to lay out the class. auto numFields = IGF.IGM.getSize(Size(storedProperties.size())); IGF.Builder.CreateCall(IGF.IGM.getInitClassMetadataUniversalFn(), - {metadata, superMetadata, numFields, + {metadata, numFields, firstField.getAddress(), fieldVector}); + IGF.Builder.CreateLifetimeEnd(fields, + IGF.IGM.getPointerSize() * storedProperties.size() * 2); - } else if (IGF.IGM.ObjCInterop) { - // Register the class with the ObjC runtime. - llvm::Value *instantiateObjC = IGF.IGM.getInstantiateObjCClassFn(); - IGF.Builder.CreateCall(instantiateObjC, metadata); + } else { + // If we have any ancestor generic parameters or field offset vectors, + // copy them from the superclass metadata. + auto initFn = IGF.IGM.getInitializeSuperclassFn(); + + bool copyFieldOffsetVectors = false; + if (FieldLayout.MetadataAccess != FieldAccess::ConstantDirect) + copyFieldOffsetVectors = true; + + IGF.Builder.CreateCall(initFn, + {metadata, + llvm::ConstantInt::get(IGF.IGM.Int1Ty, + copyFieldOffsetVectors)}); } + + if (!IGF.IGM.ObjCInterop) + emitInitializeFieldOffsets(IGF, metadata); } - }; } @@ -3621,25 +3617,23 @@ static void emitObjCClassSymbol(IRGenModule &IGM, /// Emit the type metadata or metadata template for a class. void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl, - const StructLayout &layout) { + const StructLayout &layout, + const ClassLayout &fieldLayout) { assert(!classDecl->isForeign()); // TODO: classes nested within generic types llvm::Constant *init; bool isPattern; - bool hasRuntimeBase; - if (classDecl->isGenericContext()) { - GenericClassMetadataBuilder builder(IGM, classDecl, layout); + if (hasMetadataPattern(IGM, classDecl)) { + GenericClassMetadataBuilder builder(IGM, classDecl, layout, fieldLayout); builder.layout(); init = builder.getInit(); isPattern = true; - hasRuntimeBase = builder.hasRuntimeBase(); } else { - ClassMetadataBuilder builder(IGM, classDecl, layout); + ClassMetadataBuilder builder(IGM, classDecl, layout, fieldLayout); builder.layout(); init = builder.getInit(); isPattern = false; - hasRuntimeBase = builder.hasRuntimeBase(); } maybeEmitTypeMetadataAccessFunction(IGM, classDecl); @@ -3661,7 +3655,7 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl, /*isConstant*/ false, init, section); // Add non-generic classes to the ObjC class list. - if (IGM.ObjCInterop && !isPattern && !isIndirect && !hasRuntimeBase) { + if (IGM.ObjCInterop && !isPattern && !isIndirect) { // Emit the ObjC class symbol to make the class visible to ObjC. if (classDecl->isObjC()) { emitObjCClassSymbol(IGM, classDecl, var); @@ -3685,14 +3679,11 @@ void IRGenFunction::setDereferenceableLoad(llvm::LoadInst *load, } /// Emit a load from the given metadata at a constant index. -/// -/// The load is marked invariant. This function should not be called -/// on metadata objects that are in the process of being initialized. -static llvm::LoadInst *emitInvariantLoadFromMetadataAtIndex(IRGenFunction &IGF, - llvm::Value *metadata, - int index, - llvm::PointerType *objectTy, - const llvm::Twine &suffix = ""){ +static llvm::LoadInst *emitLoadFromMetadataAtIndex(IRGenFunction &IGF, + llvm::Value *metadata, + int index, + llvm::Type *objectTy, + const llvm::Twine &suffix) { // Require the metadata to be some type that we recognize as a // metadata pointer. assert(metadata->getType() == IGF.IGM.TypeMetadataPtrTy); @@ -3700,6 +3691,8 @@ static llvm::LoadInst *emitInvariantLoadFromMetadataAtIndex(IRGenFunction &IGF, // We require objectType to be a pointer type so that the GEP will // scale by the right amount. We could load an arbitrary type using // some extra bitcasting. + assert(IGF.IGM.DataLayout.getTypeStoreSize(objectTy) == + IGF.IGM.DataLayout.getTypeStoreSize(IGF.IGM.SizeTy)); // Cast to T*. auto objectPtrTy = objectTy->getPointerTo(); @@ -3712,8 +3705,21 @@ static llvm::LoadInst *emitInvariantLoadFromMetadataAtIndex(IRGenFunction &IGF, IGF.IGM.getPointerAlignment()); // Load. - auto result = IGF.Builder.CreateLoad(slot, - metadata->getName() + suffix); + return IGF.Builder.CreateLoad(slot, metadata->getName() + suffix); +} + +/// Emit a load from the given metadata at a constant index. +/// +/// The load is marked invariant. This function should not be called +/// on metadata objects that are in the process of being initialized. +static llvm::LoadInst * +emitInvariantLoadFromMetadataAtIndex(IRGenFunction &IGF, + llvm::Value *metadata, + int index, + llvm::Type *objectTy, + const llvm::Twine &suffix = "") { + auto result = emitLoadFromMetadataAtIndex(IGF, metadata, index, objectTy, + suffix); IGF.setInvariantLoad(result); return result; } @@ -3723,13 +3729,14 @@ llvm::Value * IRGenFunction::emitValueWitnessTableRef(CanType type) { // See if we have a cached projection we can use. if (auto cached = tryGetLocalTypeData(type, - LocalTypeData::forValueWitnessTable())) { + LocalTypeDataKind::forValueWitnessTable())) { return cached; } auto metadata = emitTypeMetadataRef(type); auto vwtable = emitValueWitnessTableRefForMetadata(metadata); - setScopedLocalTypeData(type, LocalTypeData::forValueWitnessTable(), vwtable); + setScopedLocalTypeData(type, LocalTypeDataKind::forValueWitnessTable(), + vwtable); return vwtable; } @@ -3737,8 +3744,8 @@ IRGenFunction::emitValueWitnessTableRef(CanType type) { llvm::Value * IRGenFunction::emitValueWitnessTableRefForMetadata(llvm::Value *metadata) { auto witness = emitInvariantLoadFromMetadataAtIndex(*this, metadata, -1, - IGM.WitnessTablePtrTy, - ".valueWitnesses"); + IGM.WitnessTablePtrTy, + ".valueWitnesses"); // A value witness table is dereferenceable to the number of value witness // pointers. @@ -3757,14 +3764,14 @@ llvm::Value * IRGenFunction::emitValueWitnessTableRefForLayout(SILType type) { // See if we have a cached projection we can use. if (auto cached = tryGetLocalTypeDataForLayout(type, - LocalTypeData::forValueWitnessTable())) { + LocalTypeDataKind::forValueWitnessTable())) { return cached; } auto metadata = emitTypeMetadataRefForLayout(type); auto vwtable = emitValueWitnessTableRefForMetadata(metadata); setScopedLocalTypeDataForLayout(type, - LocalTypeData::forValueWitnessTable(), + LocalTypeDataKind::forValueWitnessTable(), vwtable); return vwtable; } @@ -3774,7 +3781,7 @@ static llvm::Value *emitLoadOfMetadataRefAtIndex(IRGenFunction &IGF, llvm::Value *metadata, int index) { return emitInvariantLoadFromMetadataAtIndex(IGF, metadata, index, - IGF.IGM.TypeMetadataPtrTy); + IGF.IGM.TypeMetadataPtrTy); } /// Load the protocol witness table reference at the given index. @@ -3782,7 +3789,7 @@ static llvm::Value *emitLoadOfWitnessTableRefAtIndex(IRGenFunction &IGF, llvm::Value *metadata, int index) { return emitInvariantLoadFromMetadataAtIndex(IGF, metadata, index, - IGF.IGM.WitnessTablePtrTy); + IGF.IGM.WitnessTablePtrTy); } namespace { @@ -3790,7 +3797,7 @@ namespace { BEGIN_METADATA_SEARCHER_0(FindClassParentIndex, Class) void addParentMetadataRef(ClassDecl *forClass) { if (forClass == Target) setTargetOffset(); - addParentMetadataRef(forClass); + super::addParentMetadataRef(forClass); } END_METADATA_SEARCHER() } @@ -3976,8 +3983,8 @@ llvm::Value *irgen::emitClassFieldOffset(IRGenFunction &IGF, llvm::Value *metadata) { irgen::Size offset = getClassFieldOffset(IGF.IGM, theClass, field); int index = getOffsetInWords(IGF.IGM, offset); - llvm::Value *val = emitLoadOfWitnessTableRefAtIndex(IGF, metadata, index); - return IGF.Builder.CreatePtrToInt(val, IGF.IGM.SizeTy); + return emitInvariantLoadFromMetadataAtIndex(IGF, metadata, index, + IGF.IGM.SizeTy); } /// Given a reference to class metadata of the given type, @@ -4241,7 +4248,8 @@ llvm::Value *irgen::emitClassHeapMetadataRefForMetatype(IRGenFunction &IGF, // a select here instead, which might be profitable. IGF.Builder.emitBlock(wrapBB); auto classFromWrapper = - emitInvariantLoadFromMetadataAtIndex(IGF, metatype, 1, IGF.IGM.TypeMetadataPtrTy); + emitInvariantLoadFromMetadataAtIndex(IGF, metatype, 1, + IGF.IGM.TypeMetadataPtrTy); IGF.Builder.CreateBr(contBB); // Continuation block. @@ -4278,21 +4286,6 @@ AbstractCallee irgen::getAbstractVirtualCallee(IRGenFunction &IGF, naturalUncurry, naturalUncurry, ExtraData::None); } -/// Find the function which will actually appear in the virtual table. -static SILDeclRef findOverriddenFunction(IRGenModule &IGM, - SILDeclRef method) { - // 'method' is the most final method in the hierarchy which we - // haven't yet found a compatible override for. 'cur' is the method - // we're currently looking at. Compatibility is transitive, - // so we can forget our original method and just keep going up. - - SILDeclRef cur = method; - while ((cur = cur.getOverriddenVTableEntry())) { - method = cur; - } - return method; -} - /// Load the correct virtual function for the given class method. llvm::Value *irgen::emitVirtualMethodValue(IRGenFunction &IGF, llvm::Value *base, @@ -4304,18 +4297,33 @@ llvm::Value *irgen::emitVirtualMethodValue(IRGenFunction &IGF, = cast(method.getDecl()); // Find the function that's actually got an entry in the metadata. - SILDeclRef overridden = - findOverriddenFunction(IGF.IGM, method); + SILDeclRef overridden = method.getBaseOverriddenVTableEntry(); // Find the metadata. llvm::Value *metadata; if (useSuperVTable) { + auto instanceTy = baseType; if (auto metaTy = dyn_cast(baseType.getSwiftRValueType())) - baseType = SILType::getPrimitiveObjectType(metaTy.getInstanceType()); - - auto superType = baseType.getSuperclass(/*resolver=*/nullptr); - metadata = emitClassHeapMetadataRef(IGF, superType.getSwiftRValueType(), - MetadataValueType::TypeMetadata); + instanceTy = SILType::getPrimitiveObjectType(metaTy.getInstanceType()); + + if (IGF.IGM.isResilient(instanceTy.getClassOrBoundGenericClass(), + ResilienceScope::Component)) { + // The derived type that is making the super call is resilient, + // for example we may be in an extension of a class outside of our + // resilience domain. So, we need to load the superclass metadata + // dynamically. + + metadata = emitClassHeapMetadataRef(IGF, instanceTy.getSwiftRValueType(), + MetadataValueType::TypeMetadata); + auto superField = emitAddressOfSuperclassRefInClassMetadata(IGF, metadata); + metadata = IGF.Builder.CreateLoad(superField); + } else { + // Otherwise, we can directly load the statically known superclass's + // metadata. + auto superTy = instanceTy.getSuperclass(/*resolver=*/nullptr); + metadata = emitClassHeapMetadataRef(IGF, superTy.getSwiftRValueType(), + MetadataValueType::TypeMetadata); + } } else { if ((isa(methodDecl) && cast(methodDecl)->isStatic()) || (isa(methodDecl) && @@ -4524,7 +4532,8 @@ class EnumMetadataBuilderBase : super(IGM, theEnum) {} void addMetadataFlags() { - addWord(getMetadataKind(IGM, MetadataKind::Enum)); + addWord(getMetadataKind(IGM, Target->classifyAsOptionalType() + ? MetadataKind::Optional : MetadataKind::Enum)); } void addNominalTypeDescriptor() { @@ -4559,7 +4568,16 @@ class EnumMetadataBuilder } void addPayloadSize() { - llvm_unreachable("nongeneric enums shouldn't need payload size in metadata"); + auto enumTy = Target->getDeclaredTypeInContext()->getCanonicalType(); + auto &enumTI = IGM.getTypeInfoForLowered(enumTy); + (void) enumTI; + assert(enumTI.isFixedSize(ResilienceScope::Component) && + "emitting constant enum metadata for resilient-sized type?"); + assert(!enumTI.isFixedSize(ResilienceScope::Universal) && + "non-generic, non-resilient enums don't need payload size in metadata"); + + auto &strategy = getEnumImplStrategy(IGM, enumTy); + addConstantWord(strategy.getPayloadSizeForMetadata()); } }; @@ -4595,6 +4613,11 @@ class GenericEnumMetadataBuilder void addPayloadSize() { // In all cases where a payload size is demanded in the metadata, it's // runtime-dependent, so fill in a zero here. + auto enumTy = Target->getDeclaredTypeInContext()->getCanonicalType(); + auto &enumTI = IGM.getTypeInfoForLowered(enumTy); + (void) enumTI; + assert(!enumTI.isFixedSize(ResilienceScope::Universal) && + "non-generic, non-resilient enums don't need payload size in metadata"); addConstantWord(0); } @@ -4603,7 +4626,7 @@ class GenericEnumMetadataBuilder llvm::Value *vwtable) { // Nominal types are always preserved through SIL lowering. auto enumTy = Target->getDeclaredTypeInContext()->getCanonicalType(); - IGM.getTypeInfoForLowered(CanType(Target->getDeclaredTypeInContext())) + IGM.getTypeInfoForLowered(enumTy) .initializeMetadata(IGF, metadata, vwtable, SILType::getPrimitiveAddressType(enumTy)); } diff --git a/lib/IRGen/GenMeta.h b/lib/IRGen/GenMeta.h index 8a54726b7798f..a568cdd14b023 100644 --- a/lib/IRGen/GenMeta.h +++ b/lib/IRGen/GenMeta.h @@ -1,8 +1,8 @@ -//===--- GenMeta.h - Swift IR generation for metadata ----------*- C++ -*-===// +//===--- GenMeta.h - Swift IR generation for metadata -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,6 +23,8 @@ namespace llvm { template class ArrayRef; class Constant; + class Function; + class GlobalVariable; class Value; } @@ -44,6 +46,7 @@ namespace irgen { class IRGenModule; class Size; class StructLayout; + struct ClassLayout; /// Is the given class known to have Swift-compatible metadata? bool hasKnownSwiftMetadata(IRGenModule &IGM, ClassDecl *theClass); @@ -76,7 +79,7 @@ namespace irgen { /// Emit a reference to a compile-time constant piece of type metadata, or /// return a null pointer if the type's metadata cannot be represented by a /// constant. - llvm::Constant *tryEmitConstantHeapMetadataRef(IRGenModule &IGM, + llvm::Constant *tryEmitConstantTypeMetadataRef(IRGenModule &IGM, CanType type); enum class MetadataValueType { ObjCClass, TypeMetadata }; @@ -103,7 +106,8 @@ namespace irgen { /// Emit the metadata associated with the given class declaration. void emitClassMetadata(IRGenModule &IGM, ClassDecl *theClass, - const StructLayout &layout); + const StructLayout &layout, + const ClassLayout &fieldLayout); /// Emit the constant initializer of the type metadata candidate for /// the given foreign class declaration. @@ -278,6 +282,11 @@ namespace irgen { CanType type, bool preferDirectAccess); + /// Return the address of a function that will return type metadata + /// for the given non-dependent type. + llvm::Function *getOrCreateTypeMetadataAccessFunction(IRGenModule &IGM, + CanType type); + /// Get the runtime identifier for a special protocol, if any. SpecialProtocol getSpecialProtocolID(ProtocolDecl *P); diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index 6f2b1f283290c..1ff9b27e7450f 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -51,7 +51,7 @@ using namespace swift; using namespace irgen; -void IRGenFunction::emitObjCRelease(llvm::Value *value) { +void IRGenFunction::emitObjCStrongRelease(llvm::Value *value) { // Get an appropriately-cast function pointer. auto fn = IGM.getObjCReleaseFn(); if (value->getType() != IGM.ObjCPtrTy) { @@ -84,8 +84,8 @@ static llvm::Constant *getCastOfRetainFn(IRGenModule &IGM, return llvm::ConstantExpr::getBitCast(fn, fnTy->getPointerTo(0)); } -void IRGenFunction::emitObjCRetain(llvm::Value *v, Explosion &explosion) { - explosion.add(emitObjCRetainCall(v)); +void IRGenFunction::emitObjCStrongRetain(llvm::Value *v) { + emitObjCRetainCall(v); } llvm::Value *IRGenFunction::emitObjCRetainCall(llvm::Value *value) { @@ -570,6 +570,7 @@ static void emitSuperArgument(IRGenFunction &IGF, bool isInstanceMethod, Address super = IGF.createAlloca(IGF.IGM.ObjCSuperStructTy, IGF.IGM.getPointerAlignment(), "objc_super"); + // TODO: Track lifetime markers for function args. llvm::Value *self = IGF.Builder.CreateBitCast(selfValue, IGF.IGM.ObjCPtrTy); @@ -823,6 +824,7 @@ static llvm::Function *emitObjCPartialApplicationForwarder(IRGenModule &IGM, case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_Out: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: llvm_unreachable("self passed indirectly?!"); } @@ -866,7 +868,7 @@ static llvm::Function *emitObjCPartialApplicationForwarder(IRGenModule &IGM, subIGF.emitObjCAutoreleaseCall(self); } // Release the context. - subIGF.emitRelease(context); + subIGF.emitNativeStrongRelease(context); }; // Emit the call and produce the return value. @@ -1097,7 +1099,7 @@ static llvm::Constant *getObjCEncodingForTypes(IRGenModule &IGM, } // Parameter types. - // TODO. Encode type qualifer, 'in', 'inout', etc. for the parameter. + // TODO. Encode type qualifier, 'in', 'inout', etc. for the parameter. std::string paramsString; for (auto param : params) { auto clangType = IGM.getClangType(param.getType()); @@ -1105,7 +1107,7 @@ static llvm::Constant *getObjCEncodingForTypes(IRGenModule &IGM, return llvm::ConstantPointerNull::get(IGM.Int8PtrTy); // TODO. Some stuff related to Array and Function type is missing. - // TODO. Encode type qualifer, 'in', 'inout', etc. for the parameter. + // TODO. Encode type qualifier, 'in', 'inout', etc. for the parameter. HelperGetObjCEncodingForType(clangASTContext, clangType, paramsString, useExtendedEncoding); paramsString += llvm::itostr(parmOffset); diff --git a/lib/IRGen/GenObjC.h b/lib/IRGen/GenObjC.h index fbcbda6f16be3..db048cc52f538 100644 --- a/lib/IRGen/GenObjC.h +++ b/lib/IRGen/GenObjC.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenOpaque.cpp b/lib/IRGen/GenOpaque.cpp index 085fdd6e381df..d39498f68c889 100644 --- a/lib/IRGen/GenOpaque.cpp +++ b/lib/IRGen/GenOpaque.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -183,6 +183,19 @@ static llvm::Type *createWitnessType(IRGenModule &IGM, ValueWitness index) { ->getPointerTo(); } + /// void (*destructiveInjectEnumTag)(T *obj, unsigned tag, M *self); + case ValueWitness::DestructiveInjectEnumTag: { + llvm::Type *voidTy = IGM.VoidTy; + llvm::Type *ptrTy = IGM.OpaquePtrTy; + llvm::Type *indexTy = IGM.Int32Ty; + llvm::Type *metaTy = IGM.TypeMetadataPtrTy; + + llvm::Type *args[] = {ptrTy, indexTy, metaTy}; + + return llvm::FunctionType::get(voidTy, args, /*isVarArg*/ false) + ->getPointerTo(); + } + case ValueWitness::Size: case ValueWitness::Flags: case ValueWitness::Stride: @@ -256,6 +269,8 @@ static StringRef getValueWitnessLabel(ValueWitness index) { return "getEnumTag"; case ValueWitness::DestructiveProjectEnumData: return "destructiveProjectEnumData"; + case ValueWitness::DestructiveInjectEnumTag: + return "destructiveInjectEnumTag"; } llvm_unreachable("bad value witness index"); } @@ -305,25 +320,26 @@ static llvm::Value *emitLoadOfValueWitnessFromMetadata(IRGenFunction &IGF, llvm::Value *IRGenFunction::emitValueWitness(CanType type, ValueWitness index) { if (auto witness = - tryGetLocalTypeData(type, LocalTypeData::forValueWitness(index))) + tryGetLocalTypeData(type, LocalTypeDataKind::forValueWitness(index))) return witness; auto vwtable = emitValueWitnessTableRef(type); auto witness = emitLoadOfValueWitness(*this, vwtable, index); - setScopedLocalTypeData(type, LocalTypeData::forValueWitness(index), witness); + setScopedLocalTypeData(type, LocalTypeDataKind::forValueWitness(index), + witness); return witness; } llvm::Value *IRGenFunction::emitValueWitnessForLayout(SILType type, ValueWitness index) { if (auto witness = tryGetLocalTypeDataForLayout(type, - LocalTypeData::forValueWitness(index))) + LocalTypeDataKind::forValueWitness(index))) return witness; auto vwtable = emitValueWitnessTableRefForLayout(type); auto witness = emitLoadOfValueWitness(*this, vwtable, index); setScopedLocalTypeDataForLayout(type, - LocalTypeData::forValueWitness(index), witness); + LocalTypeDataKind::forValueWitness(index), witness); return witness; } @@ -679,6 +695,23 @@ void irgen::emitDestructiveProjectEnumDataCall(IRGenFunction &IGF, setHelperAttributes(call); } +/// Emit a call to the 'destructiveInjectEnumTag' operation. +/// The type must be dynamically known to have enum witnesses. +void irgen::emitDestructiveInjectEnumTagCall(IRGenFunction &IGF, + SILType T, + unsigned tag, + llvm::Value *srcObject) { + auto metadata = IGF.emitTypeMetadataRefForLayout(T); + llvm::Value *fn = IGF.emitValueWitnessForLayout(T, + ValueWitness::DestructiveInjectEnumTag); + llvm::Value *tagValue = + llvm::ConstantInt::get(IGF.IGM.Int32Ty, tag); + llvm::CallInst *call = + IGF.Builder.CreateCall(fn, {srcObject, tagValue, metadata}); + call->setCallingConv(IGF.IGM.RuntimeCC); + setHelperAttributes(call); +} + /// Load the 'size' value witness from the given table as a size_t. llvm::Value *irgen::emitLoadOfSize(IRGenFunction &IGF, SILType T) { return IGF.emitValueWitnessForLayout(T, ValueWitness::Size); diff --git a/lib/IRGen/GenOpaque.h b/lib/IRGen/GenOpaque.h index 580800fcac654..99d87d043ac1d 100644 --- a/lib/IRGen/GenOpaque.h +++ b/lib/IRGen/GenOpaque.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -177,6 +177,13 @@ namespace irgen { SILType T, llvm::Value *srcObject); + /// Emit a call to the 'destructiveInjectEnumTag' operation. + /// The type must be dynamically known to have enum witnesses. + void emitDestructiveInjectEnumTagCall(IRGenFunction &IGF, + SILType T, + unsigned tag, + llvm::Value *srcObject); + /// Emit a load of the 'size' value witness. llvm::Value *emitLoadOfSize(IRGenFunction &IGF, SILType T); diff --git a/lib/IRGen/GenPoly.cpp b/lib/IRGen/GenPoly.cpp index 00c314d4830c9..52764f3184572 100644 --- a/lib/IRGen/GenPoly.cpp +++ b/lib/IRGen/GenPoly.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenPoly.h b/lib/IRGen/GenPoly.h index b32625f61e4ec..4c28d72ac3d8f 100644 --- a/lib/IRGen/GenPoly.h +++ b/lib/IRGen/GenPoly.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 1c8b52144e0c7..ffb8cc5dfd90a 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -49,6 +49,7 @@ #include "EnumPayload.h" #include "Explosion.h" #include "FixedTypeInfo.h" +#include "Fulfillment.h" #include "GenArchetype.h" #include "GenClass.h" #include "GenEnum.h" @@ -304,7 +305,8 @@ class irgen::ConformanceInfo { public: virtual ~ConformanceInfo() {} virtual llvm::Value *getTable(IRGenFunction &IGF, - CanType conformingType) const = 0; + CanType conformingType, + llvm::Value **conformingMetadataCache) const = 0; /// Try to get this table as a constant pointer. This might just /// not be supportable at all. virtual llvm::Constant *tryGetConstantTable(IRGenModule &IGM, @@ -314,16 +316,20 @@ class irgen::ConformanceInfo { static llvm::Value * emitWitnessTableAccessorCall(IRGenFunction &IGF, const NormalProtocolConformance *conformance, - CanType conformingType) { + CanType conformingType, + llvm::Value **srcMetadataCache) { auto accessor = IGF.IGM.getAddrOfWitnessTableAccessFunction(conformance, NotForDefinition); - // If the conforming type is generic, the accessor takes the metatype + // If the conformance is generic, the accessor takes the metatype // as an argument. llvm::CallInst *call; if (conformance->getDeclContext()->isGenericContext()) { - auto metadata = IGF.emitTypeMetadataRef(conformingType); - call = IGF.Builder.CreateCall(accessor, {metadata}); + // Emit the source metadata if we haven't yet. + if (!*srcMetadataCache) { + *srcMetadataCache = IGF.emitTypeMetadataRef(conformingType); + } + call = IGF.Builder.CreateCall(accessor, {*srcMetadataCache}); } else { call = IGF.Builder.CreateCall(accessor, {}); } @@ -357,7 +363,9 @@ getWitnessTableLazyAccessFunction(IRGenModule &IGM, ForDefinition)); emitLazyCacheAccessFunction(IGM, accessor, cacheVariable, [&](IRGenFunction &IGF) -> llvm::Value* { - return emitWitnessTableAccessorCall(IGF, conformance, conformingType); + llvm::Value *conformingMetadataCache = nullptr; + return emitWitnessTableAccessorCall(IGF, conformance, conformingType, + &conformingMetadataCache); }); return accessor; @@ -374,8 +382,8 @@ class DirectConformanceInfo : public ConformanceInfo { DirectConformanceInfo(const NormalProtocolConformance *C) : RootConformance(C) {} - llvm::Value *getTable(IRGenFunction &IGF, - CanType conformingType) const override { + llvm::Value *getTable(IRGenFunction &IGF, CanType conformingType, + llvm::Value **conformingMetadataCache) const override { return IGF.IGM.getAddrOfWitnessTable(RootConformance); } @@ -394,12 +402,14 @@ class AccessorConformanceInfo : public ConformanceInfo { AccessorConformanceInfo(const NormalProtocolConformance *C) : Conformance(C) {} - llvm::Value *getTable(IRGenFunction &IGF, CanType type) const override { + llvm::Value *getTable(IRGenFunction &IGF, CanType type, + llvm::Value **typeMetadataCache) const override { // If the conformance isn't generic, or we're looking up a dependent // type, we don't want to / can't cache the result. if (!Conformance->getDeclContext()->isGenericContext() || type->hasArchetype()) { - return emitWitnessTableAccessorCall(IGF, Conformance, type); + return emitWitnessTableAccessorCall(IGF, Conformance, type, + typeMetadataCache); } // Otherwise, call a lazy-cache function. @@ -431,7 +441,7 @@ static bool isNeverAllocated(FixedPacking packing) { } namespace { - /// An operation to be peformed for various kinds of packing. + /// An operation to be performed for various kinds of packing. struct DynamicPackingOperation { virtual ~DynamicPackingOperation() = default; @@ -549,14 +559,18 @@ static void emitDynamicPackingOperation(IRGenFunction &IGF, IGF.Builder.CreateCondBr(isInline, directBB, indirectBB); // Emit the indirect path. - IGF.Builder.emitBlock(indirectBB); - operation.emitForPacking(IGF, T, type, FixedPacking::Allocate); - IGF.Builder.CreateBr(contBB); + IGF.Builder.emitBlock(indirectBB); { + ConditionalDominanceScope condition(IGF); + operation.emitForPacking(IGF, T, type, FixedPacking::Allocate); + IGF.Builder.CreateBr(contBB); + } // Emit the direct path. - IGF.Builder.emitBlock(directBB); - operation.emitForPacking(IGF, T, type, FixedPacking::OffsetZero); - IGF.Builder.CreateBr(contBB); + IGF.Builder.emitBlock(directBB); { + ConditionalDominanceScope condition(IGF); + operation.emitForPacking(IGF, T, type, FixedPacking::OffsetZero); + IGF.Builder.CreateBr(contBB); + } // Enter the continuation block and add the PHI if required. IGF.Builder.emitBlock(contBB); @@ -963,6 +977,7 @@ static void buildValueWitnessFunction(IRGenModule &IGM, IGF.Builder.CreateCondBr(done, exit, loop); IGF.Builder.emitBlock(loop); + ConditionalDominanceScope condition(IGF); type.destroy(IGF, element, concreteType); auto nextCounter = IGF.Builder.CreateSub(counter, llvm::ConstantInt::get(IGM.SizeTy, 1)); @@ -1139,6 +1154,23 @@ static void buildValueWitnessFunction(IRGenModule &IGM, return; } + case ValueWitness::DestructiveInjectEnumTag: { + llvm::Value *value = getArg(argv, "value"); + auto enumTy = type.getStorageType()->getPointerTo(); + value = IGF.Builder.CreateBitCast(value, enumTy); + + llvm::Value *tag = getArg(argv, "tag"); + getArgAsLocalSelfTypeMetadata(IGF, argv, abstractType); + + auto &strategy = getEnumImplStrategy(IGM, concreteType); + strategy.emitStoreTag(IGF, concreteType, + Address(value, type.getBestKnownAlignment()), + tag); + + IGF.Builder.CreateRetVoid(); + return; + } + case ValueWitness::Size: case ValueWitness::Flags: case ValueWitness::Stride: @@ -1189,10 +1221,10 @@ static llvm::Constant *getAssignWithCopyStrongFunction(IRGenModule &IGM) { Address src(&*(it++), IGM.getPointerAlignment()); llvm::Value *newValue = IGF.Builder.CreateLoad(src, "new"); - IGF.emitRetainCall(newValue); + IGF.emitNativeStrongRetain(newValue); llvm::Value *oldValue = IGF.Builder.CreateLoad(dest, "old"); IGF.Builder.CreateStore(newValue, dest); - IGF.emitRelease(oldValue); + IGF.emitNativeStrongRelease(oldValue); IGF.Builder.CreateRet(dest.getAddress()); }); @@ -1215,7 +1247,7 @@ static llvm::Constant *getAssignWithTakeStrongFunction(IRGenModule &IGM) { llvm::Value *newValue = IGF.Builder.CreateLoad(src, "new"); llvm::Value *oldValue = IGF.Builder.CreateLoad(dest, "old"); IGF.Builder.CreateStore(newValue, dest); - IGF.emitRelease(oldValue); + IGF.emitNativeStrongRelease(oldValue); IGF.Builder.CreateRet(dest.getAddress()); }); @@ -1235,7 +1267,7 @@ static llvm::Constant *getInitWithCopyStrongFunction(IRGenModule &IGM) { Address src(&*(it++), IGM.getPointerAlignment()); llvm::Value *newValue = IGF.Builder.CreateLoad(src, "new"); - IGF.emitRetainCall(newValue); + IGF.emitNativeStrongRetain(newValue); IGF.Builder.CreateStore(newValue, dest); IGF.Builder.CreateRet(dest.getAddress()); @@ -1250,7 +1282,7 @@ static llvm::Constant *getDestroyStrongFunction(IRGenModule &IGM) { IGM.VoidTy, argTys, [&](IRGenFunction &IGF) { Address arg(IGF.CurFn->arg_begin(), IGM.getPointerAlignment()); - IGF.emitRelease(IGF.Builder.CreateLoad(arg)); + IGF.emitNativeStrongRelease(IGF.Builder.CreateLoad(arg)); IGF.Builder.CreateRetVoid(); }); } @@ -1576,6 +1608,7 @@ static llvm::Constant *getValueWitness(IRGenModule &IGM, case ValueWitness::GetEnumTag: case ValueWitness::DestructiveProjectEnumData: + case ValueWitness::DestructiveInjectEnumTag: assert(concreteType.getEnumOrBoundGenericEnum()); goto standard; } @@ -1596,35 +1629,14 @@ namespace { IRGenModule &IGM; SmallVectorImpl &Table; CanType ConcreteType; - GenericParamList *ConcreteGenerics = nullptr; - const TypeInfo &ConcreteTI; - const ProtocolConformance &Conformance; - ArrayRef Substitutions; + const NormalProtocolConformance &Conformance; ArrayRef SILEntries; -#ifndef NDEBUG const ProtocolInfo &PI; -#endif - - void computeSubstitutionsForType() { - // FIXME: This is a bit of a hack; the AST doesn't directly encode - // substitutions for the conformance of a generic type to a - // protocol, so we have to dig them out. - Type ty = ConcreteType; - while (ty) { - if (auto nomTy = ty->getAs()) - ty = nomTy->getParent(); - else - break; - } - if (ty) { - if (auto boundTy = ty->getAs()) { - ConcreteGenerics = boundTy->getDecl()->getGenericParams(); - Substitutions = boundTy->getSubstitutions(/*FIXME:*/nullptr, nullptr); - } else { - assert(!ty || !ty->isSpecialized()); - } - } - } + Optional Fulfillments; + SmallVector, 4> + SpecializedBaseConformances; + unsigned NextCacheIndex = 0; + bool RequiresSpecialization = false; public: WitnessTableBuilder(IRGenModule &IGM, @@ -1632,17 +1644,22 @@ namespace { SILWitnessTable *SILWT) : IGM(IGM), Table(table), ConcreteType(SILWT->getConformance()->getType()->getCanonicalType()), - ConcreteTI( - IGM.getTypeInfoForUnlowered(SILWT->getConformance()->getType())), Conformance(*SILWT->getConformance()), - SILEntries(SILWT->getEntries()) -#ifndef NDEBUG - , PI(IGM.getProtocolInfo(SILWT->getConformance()->getProtocol())) -#endif + SILEntries(SILWT->getEntries()), + PI(IGM.getProtocolInfo(SILWT->getConformance()->getProtocol())) { - computeSubstitutionsForType(); + // Cache entries start at the end of the table. + NextCacheIndex = PI.getNumWitnesses(); + // TODO: in conditional conformances, allocate space for the assumed + // conformances here. } + /// The top-level entry point. + void build(); + + /// Create the access function. + void buildAccessFunction(llvm::Constant *wtable); + /// A base protocol is witnessed by a pointer to the conformance /// of this type to that protocol. void addOutOfLineBaseProtocol(ProtocolDecl *baseProto) { @@ -1668,9 +1685,17 @@ namespace { const ConformanceInfo &conf = basePI.getConformance(IGM, baseProto, astConf); + // If we can emit the base witness table as a constant, do so. llvm::Constant *baseWitness = conf.tryGetConstantTable(IGM, ConcreteType); - assert(baseWitness && "couldn't get a constant table!"); - Table.push_back(asOpaquePtr(IGM, baseWitness)); + if (baseWitness) { + Table.push_back(baseWitness); + return; + } + + // Otherwise, we'll need to derive it at instantiation time. + RequiresSpecialization = true; + SpecializedBaseConformances.push_back({Table.size(), &conf}); + Table.push_back(llvm::ConstantPointerNull::get(IGM.WitnessTablePtrTy)); } void addMethodFromSILWitnessTable(AbstractFunctionDecl *iface) { @@ -1697,12 +1722,10 @@ namespace { llvm::Constant *witness = nullptr; if (Func) { witness = IGM.getAddrOfSILFunction(Func, NotForDefinition); - witness = llvm::ConstantExpr::getBitCast(witness, IGM.Int8PtrTy); } else { // The method is removed by dead method elimination. // It should be never called. We add a pointer to an error function. - witness = llvm::ConstantExpr::getBitCast(IGM.getDeadMethodErrorFn(), - IGM.Int8PtrTy); + witness = IGM.getDeletedMethodErrorFn(); } Table.push_back(witness); return; @@ -1716,52 +1739,519 @@ namespace { return addMethodFromSILWitnessTable(iface); } - void addAssociatedType(AssociatedTypeDecl *ty, + void addAssociatedType(AssociatedTypeDecl *requirement, ArrayRef protos) { #ifndef NDEBUG auto &entry = SILEntries.front(); assert(entry.getKind() == SILWitnessTable::AssociatedType && "sil witness table does not match protocol"); - assert(entry.getAssociatedTypeWitness().Requirement == ty + assert(entry.getAssociatedTypeWitness().Requirement == requirement && "sil witness table does not match protocol"); - auto piEntry = PI.getWitnessEntry(ty); + auto piEntry = PI.getWitnessEntry(requirement); assert(piEntry.getAssociatedTypeIndex().getValue() == Table.size() && "offset doesn't match ProtocolInfo layout"); #endif SILEntries = SILEntries.slice(1); - // FIXME: Use info from SILWitnessTable instead of falling through. + const Substitution &sub = + Conformance.getTypeWitness(requirement, nullptr); + assert(protos.size() == sub.getConformances().size()); - // Determine whether the associated type has static metadata. If it - // doesn't, then this witness table is a template that requires runtime - // instantiation. + // This type will be expressed in terms of the archetypes + // of the conforming context. + CanType associate = sub.getReplacement()->getCanonicalType(); + assert(!associate->hasTypeParameter()); - // FIXME: Add static type metadata. - Table.push_back(llvm::ConstantPointerNull::get(IGM.Int8PtrTy)); + llvm::Constant *metadataAccessFunction = + getAssociatedTypeMetadataAccessFunction(requirement, associate); + Table.push_back(metadataAccessFunction); // FIXME: Add static witness tables for type conformances. - for (auto protocol : protos) { + for (auto index : indices(protos)) { + ProtocolDecl *protocol = protos[index]; + auto associatedConformance = sub.getConformances()[index]; + if (!Lowering::TypeConverter::protocolRequiresWitnessTable(protocol)) continue; +#ifndef NDEBUG auto &entry = SILEntries.front(); (void)entry; assert(entry.getKind() == SILWitnessTable::AssociatedTypeProtocol && "sil witness table does not match protocol"); - assert(entry.getAssociatedTypeProtocolWitness().Requirement == ty + auto associatedWitness = entry.getAssociatedTypeProtocolWitness(); + assert(associatedWitness.Requirement == requirement && "sil witness table does not match protocol"); - assert(entry.getAssociatedTypeProtocolWitness().Protocol == protocol + assert(associatedWitness.Protocol == protocol && "sil witness table does not match protocol"); +#endif SILEntries = SILEntries.slice(1); - // FIXME: Use info from SILWitnessTable instead of falling through. - // FIXME: Add static witness table reference. - Table.push_back(llvm::ConstantPointerNull::get(IGM.Int8PtrTy)); + llvm::Constant *wtableAccessFunction = + getAssociatedTypeWitnessTableAccessFunction(requirement, associate, + protocol, associatedConformance); + Table.push_back(wtableAccessFunction); } } + + private: + llvm::Constant *buildInstantiationFunction(); + + llvm::Constant * + getAssociatedTypeMetadataAccessFunction(AssociatedTypeDecl *requirement, + CanType associatedType); + + llvm::Constant * + getAssociatedTypeWitnessTableAccessFunction(AssociatedTypeDecl *requirement, + CanType associatedType, + ProtocolDecl *protocol, + ProtocolConformance *conformance); + + void emitReturnOfCheckedLoadFromCache(IRGenFunction &IGF, + Address destTable, + llvm::Value *selfMetadata, + llvm::function_ref body); + + void bindArchetypes(IRGenFunction &IGF, llvm::Value *selfMetadata); + + /// Allocate another word of private data storage in the conformance table. + unsigned getNextCacheIndex() { + RequiresSpecialization = true; + return NextCacheIndex++; + } + + const FulfillmentMap &getFulfillmentMap() { + if (Fulfillments) return *Fulfillments; + + Fulfillments.emplace(); + if (ConcreteType->hasArchetype()) { + struct Callback : FulfillmentMap::InterestingKeysCallback { + bool isInterestingType(CanType type) const override { + return isa(type); + } + bool hasInterestingType(CanType type) const override { + return type->hasArchetype(); + } + bool hasLimitedInterestingConformances(CanType type) const override { + return false; + } + GenericSignature::ConformsToArray + getInterestingConformances(CanType type) const override { + llvm_unreachable("no limits"); + } + } callback; + Fulfillments->searchTypeMetadata(*IGM.SILMod->getSwiftModule(), + ConcreteType, IsExact, + /*sourceIndex*/ 0, MetadataPath(), + callback); + } + return *Fulfillments; + } + }; +} + +/// Build the witness table. +void WitnessTableBuilder::build() { + visitProtocolDecl(Conformance.getProtocol()); + + // Go through and convert all the entries to i8*. + // TODO: the IR would be more legible if we made a struct instead. + for (auto &entry : Table) { + entry = llvm::ConstantExpr::getBitCast(entry, IGM.Int8PtrTy); + } +} + +/// Return the address of a function which will return the type metadata +/// for an associated type. +llvm::Constant *WitnessTableBuilder:: +getAssociatedTypeMetadataAccessFunction(AssociatedTypeDecl *requirement, + CanType associatedType) { + // If the associated type is non-dependent, we can use an ordinary + // metadata access function. We'll just end up passing extra arguments. + if (!associatedType->hasArchetype()) { + return getOrCreateTypeMetadataAccessFunction(IGM, associatedType); + } + + // Otherwise, emit an access function. + llvm::Function *accessor = + IGM.getAddrOfAssociatedTypeMetadataAccessFunction(&Conformance, + requirement); + + IRGenFunction IGF(IGM, accessor); + if (IGM.DebugInfo) + IGM.DebugInfo->emitArtificialFunction(IGF, accessor); + + Explosion parameters = IGF.collectParameters(); + + llvm::Value *self = parameters.claimNext(); + self->setName("Self"); + + Address destTable(parameters.claimNext(), IGM.getPointerAlignment()); + destTable.getAddress()->setName("wtable"); + + // If the associated type is directly fulfillable from the type, + // we don't need a cache entry. + // TODO: maybe we should have a cache entry anyway if the fulfillment + // is expensive. + if (auto fulfillment = + getFulfillmentMap().getTypeMetadata(associatedType)) { + llvm::Value *metadata = + fulfillment->Path.followFromTypeMetadata(IGF, ConcreteType, self, + /*cache*/ nullptr); + IGF.Builder.CreateRet(metadata); + return accessor; + } + + // Otherwise, we need a cache entry. + emitReturnOfCheckedLoadFromCache(IGF, destTable, self, + [&]() -> llvm::Value* { + return IGF.emitTypeMetadataRef(associatedType); + }); + + return accessor; +} + +/// Return a function which will return a particular witness table +/// conformance. The function will be passed the metadata for which +/// the conformance is being requested; it may ignore this (perhaps +/// implicitly by taking no arguments). +static llvm::Constant * +getOrCreateWitnessTableAccessFunction(IRGenModule &IGM, CanType type, + ProtocolConformance *conformance) { + assert(!type->hasArchetype() && "cannot do this for dependent type"); + + // We always emit an access function for conformances, and in principle + // it is always possible to just use that here directly. However, + // if it's dependent, doing so won't allow us to cache the result. + // For the specific use case of an associated type conformance, we could + // use a cache in the witness table; but that wastes space per conformance + // and won't let us re-use the cache with other non-dependent uses in + // the module. Therefore, in this case, we use the address of the lazy-cache + // function. + // + // FIXME: we will need to pass additional parameters if the target + // conformance is conditional. + auto rootConformance = conformance->getRootNormalConformance(); + if (rootConformance->getDeclContext()->isGenericContext()) { + return getWitnessTableLazyAccessFunction(IGM, rootConformance, type); + } else { + return IGM.getAddrOfWitnessTableAccessFunction( + conformance->getRootNormalConformance(), + NotForDefinition); + } +} + +llvm::Constant *WitnessTableBuilder:: +getAssociatedTypeWitnessTableAccessFunction(AssociatedTypeDecl *requirement, + CanType associatedType, + ProtocolDecl *associatedProtocol, + ProtocolConformance *associatedConformance) { + if (!associatedType->hasArchetype()) { + assert(associatedConformance && + "no concrete conformance for non-dependent type"); + return getOrCreateWitnessTableAccessFunction(IGM, associatedType, + associatedConformance); + } + + // Otherwise, emit an access function. + llvm::Function *accessor = + IGM.getAddrOfAssociatedTypeWitnessTableAccessFunction(&Conformance, + requirement, + associatedProtocol); + + IRGenFunction IGF(IGM, accessor); + if (IGM.DebugInfo) + IGM.DebugInfo->emitArtificialFunction(IGF, accessor); + + Explosion parameters = IGF.collectParameters(); + + llvm::Value *associatedTypeMetadata = parameters.claimNext(); + associatedTypeMetadata->setName(Twine("Self.") + requirement->getNameStr()); + + llvm::Value *self = parameters.claimNext(); + self->setName("Self"); + + Address destTable(parameters.claimNext(), IGM.getPointerAlignment()); + destTable.getAddress()->setName("wtable"); + + const ConformanceInfo *conformanceI = nullptr; + if (associatedConformance) { + const ProtocolInfo &protocolI = IGM.getProtocolInfo(associatedProtocol); + conformanceI = + &protocolI.getConformance(IGM, associatedProtocol, associatedConformance); + + // If we can emit a constant table, do so. + // In principle, any time we can do this, we should try to re-use this + // function for other conformances. But that should typically already + // be covered by the !hasArchetype() check above. + if (auto constantTable = + conformanceI->tryGetConstantTable(IGM, associatedType)) { + IGF.Builder.CreateRet(constantTable); + return accessor; + } + } + + // If the witness table is directly fulfillable from the type, + // we don't need a cache entry. + // TODO: maybe we should have a cache entry anyway if the fulfillment + // is expensive. + if (auto fulfillment = + getFulfillmentMap().getWitnessTable(associatedType, + associatedProtocol)) { + llvm::Value *wtable = + fulfillment->Path.followFromTypeMetadata(IGF, ConcreteType, self, + /*cache*/ nullptr); + IGF.Builder.CreateRet(wtable); + return accessor; + } + + assert(conformanceI && "no conformance information, but also couldn't " + "fulfill witness table contextually"); + + // Otherwise, we need a cache entry. + emitReturnOfCheckedLoadFromCache(IGF, destTable, self, + [&]() -> llvm::Value* { + return conformanceI->getTable(IGF, associatedType, &associatedTypeMetadata); + }); + + return accessor; +} + +void WitnessTableBuilder:: +emitReturnOfCheckedLoadFromCache(IRGenFunction &IGF, Address destTable, + llvm::Value *selfMetadata, + llvm::function_ref body) { + // Allocate a new cache slot and drill down to it. + unsigned cacheIndex = getNextCacheIndex(); + Address cache = IGF.Builder.CreateConstArrayGEP(destTable, cacheIndex, + IGM.getPointerSize()); + + llvm::Type *expectedTy = IGF.CurFn->getReturnType(); + cache = IGF.Builder.CreateBitCast(cache, expectedTy->getPointerTo()); + + // Load and check whether it was null. + auto cachedResult = IGF.Builder.CreateLoad(cache); + // FIXME: cachedResult->setOrdering(Consume); + auto cacheIsEmpty = IGF.Builder.CreateIsNull(cachedResult); + llvm::BasicBlock *fetchBB = IGF.createBasicBlock("fetch"); + llvm::BasicBlock *contBB = IGF.createBasicBlock("cont"); + llvm::BasicBlock *entryBB = IGF.Builder.GetInsertBlock(); + IGF.Builder.CreateCondBr(cacheIsEmpty, fetchBB, contBB); + + // Create a phi in the continuation block and use the loaded value if + // we branched directly here. Note that we arrange blocks so that we + // fall through into this. + IGF.Builder.emitBlock(contBB); + auto result = IGF.Builder.CreatePHI(expectedTy, 2); + result->addIncoming(cachedResult, entryBB); + IGF.Builder.CreateRet(result); + + // In the fetch block, bind the archetypes and evaluate the body. + IGF.Builder.emitBlock(fetchBB); + bindArchetypes(IGF, selfMetadata); + + llvm::Value *fetchedResult = body(); + + // Store the fetched result back to the cache. + // We need to transitively ensure that any stores initializing the result + // that are visible to us are visible to callers. + IGF.Builder.CreateStore(fetchedResult, cache)->setOrdering(llvm::Release); + + auto fetchedResultBB = IGF.Builder.GetInsertBlock(); + IGF.Builder.CreateBr(contBB); + result->addIncoming(fetchedResult, fetchedResultBB); +} + +/// Within a metadata or witness-table accessor on this conformance, bind +/// the type metadata and witness tables for all the associated types. +void WitnessTableBuilder::bindArchetypes(IRGenFunction &IGF, + llvm::Value *selfMetadata) { + auto generics = + Conformance.getDeclContext()->getGenericParamsOfContext(); + if (!generics) return; + + MetadataPath::Map cache; + + auto &fulfillments = getFulfillmentMap(); + + for (auto archetype : generics->getAllArchetypes()) { + // FIXME: be lazier. + + // Find the type metadata for the archetype. + // + // All of the primary archetypes will be fulfilled by the concrete + // type; otherwise they'd be free. Everything else we should be able + // to derive from some parent archetype and its known conformances. + llvm::Value *archetypeMetadata; + if (auto fulfillment = + fulfillments.getTypeMetadata(CanType(archetype))) { + archetypeMetadata = + fulfillment->Path.followFromTypeMetadata(IGF, ConcreteType, + selfMetadata, &cache); + } else { + assert(!archetype->isPrimary() && "free type param in conformance?"); + + // getAllArchetypes is in dependency order, so the parent archetype + // should always be mapped. + auto parentArchetype = CanArchetypeType(archetype->getParent()); + archetypeMetadata = + emitAssociatedTypeMetadataRef(IGF, parentArchetype, + archetype->getAssocType()); + } + + // Find the witness tables for the archetype. + // + // Archetype conformances in a type context can be classified into + // three buckets: + // + // - They can be inherent to the extended type, e.g. Dictionary's + // requirement that its keys be Equatable. These should always + // be fulfillable from the concrete type metadata. + // + // - If the archetype is an associated type, they can be inherent + // to that associated type's requirements. These should always + // be available from the associated type's parent conformance. + // + // - Otherwise, the conformance must be a free requirement on the + // extension; that is, this must be a conditional conformance. + // We don't support this yet, but when we do they'll have to + // be stored in the private section of the witness table. + SmallVector archetypeWitnessTables; + for (auto protocol : archetype->getConformsTo()) { + llvm::Value *wtable; + if (auto fulfillment = + fulfillments.getWitnessTable(CanType(archetype), protocol)) { + wtable = + fulfillment->Path.followFromTypeMetadata(IGF, ConcreteType, + selfMetadata, &cache); + } else { + assert(!archetype->isPrimary() && "conditional conformance?"); + auto parentArchetype = CanArchetypeType(archetype->getParent()); + wtable = emitAssociatedTypeWitnessTableRef(IGF, parentArchetype, + archetype->getAssocType(), + archetypeMetadata, + protocol); + } + archetypeWitnessTables.push_back(wtable); + } + + IGF.bindArchetype(archetype, archetypeMetadata, archetypeWitnessTables); + } +} + +/// Emit the access function for this witness table. +void WitnessTableBuilder::buildAccessFunction(llvm::Constant *wtable) { + llvm::Function *fn = + IGM.getAddrOfWitnessTableAccessFunction(&Conformance, ForDefinition); + + IRGenFunction IGF(IGM, fn); + if (IGM.DebugInfo) + IGM.DebugInfo->emitArtificialFunction(IGF, fn); + + wtable = llvm::ConstantExpr::getBitCast(wtable, IGM.WitnessTablePtrTy); + + // If specialization isn't required, just return immediately. + // TODO: allow dynamic specialization? + if (!RequiresSpecialization) { + IGF.Builder.CreateRet(wtable); + return; + } + + // The target metadata is the first argument. + assert(Conformance.getDeclContext()->isGenericContext()); + Explosion params = IGF.collectParameters(); + llvm::Value *metadata = params.claimNext(); + + // Okay, we need a cache. Build the cache structure. + // struct GenericWitnessTable { + // /// The size of the witness table in words. + // uint16_t WitnessTableSizeInWords; + // + // /// The amount to copy from the pattern in words. The rest is zeroed. + // uint16_t WitnessTableSizeInWordsToCopy; + // + // /// The pattern. + // RelativeDirectPointer WitnessTable; + // + // /// The instantiation function, which is called after the template is copied. + // RelativeDirectPointer Instantiator; + // + // void *PrivateData[swift::NumGenericMetadataPrivateDataWords]; + // }; + + // First, create the global. We have to build this in two phases because + // it contains relative pointers. + auto cache = cast( + IGM.getAddrOfGenericWitnessTableCache(&Conformance, ForDefinition)); + + // We need an instantiation function if the base conformance + // is non-dependent. + // TODO: the conformance might be conditional. + llvm::Constant *instantiationFn; + llvm::Value *instantiationArgs = + llvm::ConstantPointerNull::get(IGM.Int8PtrPtrTy); + if (SpecializedBaseConformances.empty()) { + instantiationFn = llvm::ConstantInt::get(IGM.RelativeAddressTy, 0); + } else { + llvm::Constant *fn = buildInstantiationFunction(); + instantiationFn = IGM.emitDirectRelativeReference(fn, cache, { 3 }); + } + + // Fill in the global. + auto cacheTy = cast(cache->getValueType()); + llvm::Constant *cacheData[] = { + llvm::ConstantInt::get(IGM.Int16Ty, NextCacheIndex), + llvm::ConstantInt::get(IGM.Int16Ty, Table.size()), + IGM.emitDirectRelativeReference(wtable, cache, { 2 }), + instantiationFn, + llvm::Constant::getNullValue(cacheTy->getStructElementType(4)) }; + cache->setInitializer(llvm::ConstantStruct::get(cacheTy, cacheData)); + + auto call = IGF.Builder.CreateCall(IGM.getGetGenericWitnessTableFn(), + { cache, metadata, instantiationArgs }); + call->setCallingConv(IGM.RuntimeCC); + call->setDoesNotThrow(); + + IGF.Builder.CreateRet(call); +} + +llvm::Constant *WitnessTableBuilder::buildInstantiationFunction() { + llvm::Function *fn = + IGM.getAddrOfGenericWitnessTableInstantiationFunction(&Conformance); + IRGenFunction IGF(IGM, fn); + if (IGM.DebugInfo) + IGM.DebugInfo->emitArtificialFunction(IGF, fn); + + // Break out the parameters. + Explosion params = IGF.collectParameters(); + Address wtable(params.claimNext(), IGM.getPointerAlignment()); + llvm::Value *metadata = params.claimNext(); + llvm::Value *instantiationArgs = params.claimNext(); + (void) instantiationArgs; // unused for now + + // TODO: store any required conditional-conformance information + // in the private data. + + // Initialize all the specialized base conformances. + for (auto &base : SpecializedBaseConformances) { + // Ask the ConformanceInfo to emit the wtable. + // TODO: we may need to bind extra information in the IGF in order + // to make conditional conformances work. + llvm::Value *baseWTable = + base.second->getTable(IGF, ConcreteType, &metadata); + baseWTable = IGF.Builder.CreateBitCast(baseWTable, IGM.Int8PtrTy); + + // Store that to the appropriate slot in the new witness table. + Address slot = IGF.Builder.CreateConstArrayGEP(wtable, base.first, + IGM.getPointerSize()); + IGF.Builder.CreateStore(baseWTable, slot); + } + + IGF.Builder.CreateRetVoid(); + return fn; } /// Collect the value witnesses for a particular type. @@ -2006,8 +2496,7 @@ ProtocolInfo::getConformance(IRGenModule &IGM, ProtocolDecl *protocol, // If the conformance is dependent in any way, we need to unique it. // TODO: maybe this should apply whenever it's out of the module? // TODO: actually enable this - if ((false) && - isDependentConformance(IGM, normalConformance, + if (isDependentConformance(IGM, normalConformance, ResilienceScope::Component)) { info = new AccessorConformanceInfo(normalConformance); @@ -2024,16 +2513,19 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) { // Don't emit a witness table if it is a declaration. if (wt->isDeclaration()) return; + + bool mustEmitDefinition = !isAvailableExternally(wt->getLinkage()); + // Don't emit a witness table that is available externally if we are emitting // code for the JIT. We do not do any optimization for the JIT and it has // problems with external symbols that get merged with non-external symbols. - if (Opts.UseJIT && isAvailableExternally(wt->getLinkage())) + if (Opts.UseJIT && !mustEmitDefinition) return; // Build the witnesses. SmallVector witnesses; - WitnessTableBuilder(*this, witnesses, wt) - .visitProtocolDecl(wt->getConformance()->getProtocol()); + WitnessTableBuilder wtableBuilder(*this, witnesses, wt); + wtableBuilder.build(); assert(getProtocolInfo(wt->getConformance()->getProtocol()) .getNumWitnesses() == witnesses.size() @@ -2049,8 +2541,13 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) { global->setInitializer(initializer); global->setAlignment(getWitnessTableAlignment().getValue()); + // FIXME: resilience; this should use the conformance's publishing scope. + if (mustEmitDefinition) { + wtableBuilder.buildAccessFunction(global); + } + // Build the conformance record, if it lives in this TU. - if (isAvailableExternally(wt->getLinkage())) + if (!mustEmitDefinition) return; addProtocolConformanceRecord(wt->getConformance()); @@ -2080,18 +2577,6 @@ bool irgen::hasPolymorphicParameters(CanSILFunctionType ty) { } namespace { - struct Fulfillment { - Fulfillment() = default; - Fulfillment(unsigned sourceIndex, MetadataPath &&path) - : SourceIndex(sourceIndex), Path(std::move(path)) {} - - /// The source index. - unsigned SourceIndex; - - /// The path from the source metadata. - MetadataPath Path; - }; - typedef std::pair FulfillmentKey; /// A class for computing how to pass arguments to a polymorphic /// function. The subclasses of this are the places which need to @@ -2160,11 +2645,10 @@ namespace { CanGenericSignature Generics; std::vector Sources; - bool DidUseLastSource = false; - llvm::DenseMap Fulfillments; + FulfillmentMap Fulfillments; - auto getConformsTo(Type t) -> decltype(Generics->getConformsTo(t, M)) { + GenericSignature::ConformsToArray getConformsTo(Type t) { return Generics->getConformsTo(t, M); } @@ -2222,8 +2706,7 @@ namespace { auto paramType = FnType->getParameters()[0].getType(); Sources.emplace_back(SourceKind::Metadata, 0, paramType); - considerBoundGenericType(cast(paramType), - MetadataPath()); + considerType(paramType, IsInexact, 0, MetadataPath()); } ArrayRef getSources() const { return Sources; } @@ -2233,10 +2716,6 @@ namespace { : GenericSignatureWitnessIterator::emptyRange(); } - /// Given that we have metadata for a type, is it exactly of the - /// specified type, or might it be a subtype? - enum IsExact_t : bool { IsInexact = false, IsExact = true }; - private: void initGenerics() { assert(hasPolymorphicParameters(FnType)); @@ -2265,25 +2744,42 @@ namespace { param, result, None, ctx); } - /// Is the given type interesting for fulfillments? - static bool isInterestingTypeForFulfillments(CanType type) { - return type->hasTypeParameter(); - } - void considerNewTypeSource(SourceKind kind, unsigned paramIndex, CanType type, IsExact_t isExact) { - if (!isInterestingTypeForFulfillments(type)) return; + if (!Fulfillments.isInterestingTypeForFulfillments(type)) return; // Prospectively add a source. Sources.emplace_back(kind, paramIndex, type); - DidUseLastSource = false; // Consider the source. - considerType(type, MetadataPath(), isExact); - - // If the last source was not used in any fulfillments, remove it. - if (!DidUseLastSource) + if (!considerType(type, isExact, Sources.size() - 1, MetadataPath())) { + // If it wasn't used in any fulfillments, remove it. Sources.pop_back(); + } + } + + bool considerType(CanType type, IsExact_t isExact, + unsigned sourceIndex, MetadataPath &&path) { + struct Callback : FulfillmentMap::InterestingKeysCallback { + PolymorphicConvention &Self; + Callback(PolymorphicConvention &self) : Self(self) {} + + bool isInterestingType(CanType type) const override { + return type->isTypeParameter(); + } + bool hasInterestingType(CanType type) const override { + return type->hasTypeParameter(); + } + bool hasLimitedInterestingConformances(CanType type) const override { + return true; + } + GenericSignature::ConformsToArray + getInterestingConformances(CanType type) const override { + return Self.getConformsTo(type); + } + } callbacks(*this); + return Fulfillments.searchTypeMetadata(M, type, isExact, sourceIndex, + std::move(path), callbacks); } /// Testify to generic parameters in the Self type. @@ -2293,14 +2789,10 @@ namespace { selfTy = metaTy.getInstanceType(); Sources.back().Type = selfTy; - if (auto nomTy = dyn_cast(selfTy)) - considerNominalType(nomTy, MetadataPath()); - else if (auto bgTy = dyn_cast(selfTy)) - considerBoundGenericType(bgTy, MetadataPath()); - else if (auto paramTy = dyn_cast(selfTy)) + if (auto paramTy = dyn_cast(selfTy)) considerWitnessParamType(paramTy); else - llvm_unreachable("witness for non-nominal type?!"); + considerType(selfTy, IsInexact, Sources.size() - 1, MetadataPath()); } void considerParameter(SILParameterInfo param, unsigned paramIndex, @@ -2317,6 +2809,7 @@ namespace { case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_In_Guaranteed: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: if (!isSelfParameter) return; if (type->getNominalOrBoundGenericNominal()) { considerNewTypeSource(SourceKind::GenericLValueMetadata, @@ -2351,114 +2844,6 @@ namespace { llvm_unreachable("bad parameter convention"); } - /// Given that we have a source for metadata of the given type, check - /// to see if it fulfills anything. - /// - /// \param isExact - true if the metadata is known to be exactly the - /// metadata for the given type, false if it might be a subtype - void considerType(CanType type, MetadataPath &&path, IsExact_t isExact) { - - // Type parameters. Inexact metadata are useless here. - if (isExact && type->isTypeParameter()) { - return considerTypeParameter(type, std::move(path)); - } - - // Inexact metadata will be a problem if we ever try to use this - // to remember that we already have the metadata for something. - if (auto nomTy = dyn_cast(type)) { - return considerNominalType(nomTy, std::move(path)); - } - if (auto boundTy = dyn_cast(type)) { - return considerBoundGenericType(boundTy, std::move(path)); - } - - // TODO: tuples - // TODO: functions - // TODO: metatypes - } - - void considerParentType(CanType parent, MetadataPath &&path) { - // We might not have a parent type. - if (!parent) return; - - // If we do, it has to be nominal one way or another. - path.addNominalParentComponent(); - considerType(parent, std::move(path), IsExact); - } - - void considerNominalType(CanNominalType type, MetadataPath &&path) { - // Nominal types add no generic arguments themselves, but they - // may have the arguments of their parents. - considerParentType(type.getParent(), std::move(path)); - } - - void considerBoundGenericType(CanBoundGenericType type, - MetadataPath &&path) { - auto params = type->getDecl()->getGenericParams()->getAllArchetypes(); - auto substitutions = type->getSubstitutions(&M, nullptr); - assert(params.size() >= substitutions.size() && - "generic decl archetypes should parallel generic type subs"); - - for (unsigned i = 0, e = substitutions.size(); i != e; ++i) { - auto sub = substitutions[i]; - CanType arg = sub.getReplacement()->getCanonicalType(); - - if (!isInterestingTypeForFulfillments(arg)) - continue; - - // If the argument is a type parameter, fulfill conformances for it. - if (arg->isTypeParameter()) { - considerTypeArgConformances(arg, params[i], path, i); - } - - // Refine the path. - MetadataPath argPath = path; - argPath.addNominalTypeArgumentComponent(i); - considerType(arg, std::move(argPath), IsExact); - } - - // Also match against the parent. The polymorphic type - // will start with any arguments from the parent. - considerParentType(CanType(type->getParent()), std::move(path)); - } - - void considerTypeArgConformances(CanType arg, ArchetypeType *param, - const MetadataPath &path, - unsigned argIndex) { - // Our sources are the protocol conformances that are recorded in - // the generic metadata. - auto storedConformances = param->getConformsTo(); - if (storedConformances.empty()) return; - - // Our targets are the conformances required for the type argument. - auto requiredConformances = getConformsTo(arg); - if (requiredConformances.empty()) return; - - for (auto target : requiredConformances) { - // Ignore trivial protocols. - if (!Lowering::TypeConverter::protocolRequiresWitnessTable(target)) - continue; - - // Check each of the stored conformances. - for (size_t confIndex : indices(storedConformances)) { - // TODO: maybe this should consider indirect conformance. - // But that should be part of the metadata path. - if (target == storedConformances[confIndex]) { - MetadataPath confPath = path; - confPath.addNominalTypeArgumentConformanceComponent(argIndex, - confIndex); - addFulfillment(arg, target, std::move(confPath)); - } - } - } - } - - /// We found a reference to the dependent arg type at the given path. - /// Add any fulfillments this gives us. - void considerTypeParameter(CanType arg, MetadataPath &&path) { - addFulfillment(arg, nullptr, std::move(path)); - } - /// We're binding an archetype for a protocol witness. void considerWitnessParamType(CanGenericTypeParamType arg) { assert(arg->getDepth() == 0 && arg->getIndex() == 0); @@ -2500,36 +2885,12 @@ namespace { } void addSelfFulfillment(CanType arg, MetadataPath &&path) { + unsigned source = Sources.size() - 1; for (auto protocol : getConformsTo(arg)) { - addFulfillment(arg, protocol, MetadataPath(path)); - } - addFulfillment(arg, nullptr, std::move(path)); - } - - /// Testify that there's a fulfillment at the given path. - void addFulfillment(CanType arg, ProtocolDecl *proto, - MetadataPath &&path) { - assert(!Sources.empty() && "adding fulfillment without source?"); - auto sourceIndex = Sources.size() - 1; - - // Only add a fulfillment if we don't have any previous - // fulfillment for that value or if it 's cheaper than the existing - // fulfillment. - assert(arg->isTypeParameter() && "fulfilling non-dependent type?!"); - auto key = FulfillmentKey(arg, proto); - - auto it = Fulfillments.find(key); - if (it != Fulfillments.end()) { - if (path.cost() < it->second.Path.cost()) { - it->second.SourceIndex = sourceIndex; - it->second.Path = std::move(path); - DidUseLastSource = true; - } - } else { - Fulfillments.insert(std::make_pair(key, - Fulfillment(sourceIndex, std::move(path)))); - DidUseLastSource = true; + Fulfillments.addFulfillment({arg, protocol}, source, + MetadataPath(path)); } + Fulfillments.addFulfillment({arg, nullptr}, source, std::move(path)); } }; @@ -2596,7 +2957,7 @@ namespace { // Mark this as the cached metatype for the l-value's object type. CanType argTy = getArgTypeInContext(source.getParamIndex()); - IGF.setUnscopedLocalTypeData(argTy, LocalTypeData::forMetatype(), + IGF.setUnscopedLocalTypeData(argTy, LocalTypeDataKind::forMetatype(), metatype); return metatype; } @@ -2609,7 +2970,7 @@ namespace { // Mark this as the cached metatype for Self. CanType argTy = getArgTypeInContext(FnType->getParameters().size() - 1); IGF.setUnscopedLocalTypeData(argTy, - LocalTypeData::forMetatype(), metatype); + LocalTypeDataKind::forMetatype(), metatype); return metatype; } @@ -2671,7 +3032,9 @@ EmitPolymorphicParameters::emitForGenericValueWitness(llvm::Value *selfMeta) { void EmitPolymorphicParameters::emitWithSourcesBound(Explosion &in) { - for (auto depTy : getAllDependentTypes()) { + for (auto ncDepTy : getAllDependentTypes()) { + CanType depTy = ncDepTy->getCanonicalType(); + // Get the corresponding context archetype. auto contextTy = ArchetypeBuilder::mapTypeIntoContext(IGF.IGM.SILMod->getSwiftModule(), @@ -2683,9 +3046,8 @@ EmitPolymorphicParameters::emitWithSourcesBound(Explosion &in) { llvm::Value *metadata; // If the reference is fulfilled by the source, go for it. - auto it = Fulfillments.find(FulfillmentKey(depTy, nullptr)); - if (it != Fulfillments.end()) { - metadata = getMetadataForFulfillment(it->second); + if (auto fulfillment = Fulfillments.getTypeMetadata(depTy)) { + metadata = getMetadataForFulfillment(*fulfillment); // Otherwise, it's just next in line. } else { @@ -2702,9 +3064,8 @@ EmitPolymorphicParameters::emitWithSourcesBound(Explosion &in) { llvm::Value *wtable; // If the protocol witness table is fulfilled by the source, go for it. - auto it = Fulfillments.find(FulfillmentKey(depTy, protocol)); - if (it != Fulfillments.end()) { - wtable = getMetadataForFulfillment(it->second); + if (auto fulfillment = Fulfillments.getWitnessTable(depTy, protocol)) { + wtable = getMetadataForFulfillment(*fulfillment); // Otherwise, it's just next in line. } else { @@ -2838,11 +3199,29 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF, return source; } + case Component::Kind::InheritedProtocol: { + auto protocol = cast(sourceDecl); + auto inheritedProtocol = + protocol->getInheritedProtocols(nullptr)[component.getPrimaryIndex()]; + sourceDecl = inheritedProtocol; + + if (source) { + auto &pi = IGF.IGM.getProtocolInfo(protocol); + auto &entry = pi.getWitnessEntry(inheritedProtocol); + assert(entry.isOutOfLineBase()); + source = emitInvariantLoadOfOpaqueWitness(IGF, source, + entry.getOutOfLineBaseIndex()); + source = IGF.Builder.CreateBitCast(source, IGF.IGM.WitnessTablePtrTy); + } + + return source; + } + case Component::Kind::Impossible: llvm_unreachable("following an impossible path!"); } - llvm_unreachable("bad metata path component"); + llvm_unreachable("bad metadata path component"); } /// Collect any required metadata for a witness method from the end of @@ -2882,7 +3261,7 @@ void irgen::emitPolymorphicParametersForGenericValueWitness(IRGenFunction &IGF, EmitPolymorphicParameters(IGF, ntd).emitForGenericValueWitness(selfMeta); // Register the 'Self' argument as generic metadata for the type. IGF.setUnscopedLocalTypeData(ntd->getDeclaredTypeInContext()->getCanonicalType(), - LocalTypeData::forMetatype(), selfMeta); + LocalTypeDataKind::forMetatype(), selfMeta); } /// Get the next argument and use it as the 'self' type metadata. @@ -3064,14 +3443,13 @@ void NecessaryBindings::save(IRGenFunction &IGF, Address buffer) const { // Find the metatype for the appropriate archetype and store it in // the slot. - llvm::Value *metatype = - IGF.getLocalTypeData(CanType(archetype), LocalTypeData::forMetatype()); + llvm::Value *metatype = IGF.getLocalTypeData(CanType(archetype), + LocalTypeDataKind::forMetatype()); IGF.Builder.CreateStore(metatype, slot); // Find the witness tables for the archetype's protocol constraints and // store them in the slot. - for (unsigned protocolI : indices(archetype->getConformsTo())) { - auto protocol = archetype->getConformsTo()[protocolI]; + for (auto protocol : archetype->getConformsTo()) { if (!Lowering::TypeConverter::protocolRequiresWitnessTable(protocol)) continue; Address witnessSlot = IGF.Builder.CreateConstArrayGEP(buffer, metadataI, @@ -3081,7 +3459,7 @@ void NecessaryBindings::save(IRGenFunction &IGF, Address buffer) const { ++metadataI; llvm::Value *witness = IGF.getLocalTypeData(CanType(archetype), - LocalTypeData::forArchetypeProtocolWitness(protocolI)); + LocalTypeDataKind::forArchetypeProtocolWitnessTable(protocol)); IGF.Builder.CreateStore(witness, witnessSlot); } } @@ -3108,7 +3486,7 @@ llvm::Value *irgen::emitImpliedWitnessTableRef(IRGenFunction &IGF, /// Emit a protocol witness table for a conformance. llvm::Value *irgen::emitWitnessTableRef(IRGenFunction &IGF, CanType srcType, - const TypeInfo &srcTI, + llvm::Value **srcMetadataCache, ProtocolDecl *proto, const ProtocolInfo &protoI, ProtocolConformance *conformance) { @@ -3126,13 +3504,14 @@ llvm::Value *irgen::emitWitnessTableRef(IRGenFunction &IGF, // All other source types should be concrete enough that we have conformance // info for them. auto &conformanceI = protoI.getConformance(IGF.IGM, proto, conformance); - return conformanceI.getTable(IGF, srcType); + return conformanceI.getTable(IGF, srcType, srcMetadataCache); } /// Emit the witness table references required for the given type /// substitution. void irgen::emitWitnessTableRefs(IRGenFunction &IGF, const Substitution &sub, + llvm::Value **metadataCache, SmallVectorImpl &out) { auto conformances = sub.getConformances(); @@ -3144,7 +3523,6 @@ void irgen::emitWitnessTableRefs(IRGenFunction &IGF, // Look at the replacement type. CanType replType = sub.getReplacement()->getCanonicalType(); - auto &replTI = IGF.getTypeInfoForUnlowered(replType); for (unsigned j = 0, je = archetypeProtos.size(); j != je; ++j) { auto proto = archetypeProtos[j]; @@ -3152,8 +3530,8 @@ void irgen::emitWitnessTableRefs(IRGenFunction &IGF, continue; auto conformance = conformances.size() ? conformances[j] : nullptr; - auto wtable = emitWitnessTableRef(IGF, replType, replTI, proto, - IGF.IGM.getProtocolInfo(proto), + auto wtable = emitWitnessTableRef(IGF, replType, metadataCache, + proto, IGF.IGM.getProtocolInfo(proto), conformance); out.push_back(wtable); @@ -3251,7 +3629,9 @@ void EmitPolymorphicArguments::emit(CanType substInputType, // because non-primary archetypes (which correspond to associated types) // will have their witness tables embedded in the witness table corresponding // to their parent. - for (auto depTy : getAllDependentTypes()) { + for (auto ncDepTy : getAllDependentTypes()) { + CanType depTy = ncDepTy->getCanonicalType(); + // The substitutions should be in the same order. const Substitution &sub = subs.front(); subs = subs.slice(1); @@ -3263,9 +3643,12 @@ void EmitPolymorphicArguments::emit(CanType substInputType, if (Generics->isConcreteType(depTy, M)) continue; + llvm::Value *argMetadata = nullptr; + // Add the metadata reference unless it's fulfilled. - if (!Fulfillments.count(FulfillmentKey(depTy, nullptr))) { - out.add(IGF.emitTypeMetadataRef(argType)); + if (!Fulfillments.getTypeMetadata(depTy)) { + argMetadata = IGF.emitTypeMetadataRef(argType); + out.add(argMetadata); } // Nothing else to do if there aren't any protocols to witness. @@ -3275,8 +3658,6 @@ void EmitPolymorphicArguments::emit(CanType substInputType, if (protocols.empty()) continue; - auto &argTI = IGF.getTypeInfoForUnlowered(argType); - // Add witness tables for each of the required protocols. for (unsigned i = 0, e = protocols.size(); i != e; ++i) { auto protocol = protocols[i]; @@ -3286,12 +3667,11 @@ void EmitPolymorphicArguments::emit(CanType substInputType, continue; // Skip this if it's fulfilled by the source. - if (Fulfillments.count(FulfillmentKey(depTy, protocol))) + if (Fulfillments.getWitnessTable(depTy, protocol)) continue; auto conformance = conformances.size() ? conformances[i] : nullptr; - auto wtable = emitWitnessTableRef(IGF, - argType, argTI, + auto wtable = emitWitnessTableRef(IGF, argType, &argMetadata, protocol, IGF.IGM.getProtocolInfo(protocol), conformance); @@ -3341,14 +3721,16 @@ namespace { for (auto &source : getSources()) addEarlySource(source, out); - for (auto depTy : getAllDependentTypes()) { + for (auto ncDepTy : getAllDependentTypes()) { + CanType depTy = ncDepTy->getCanonicalType(); + // Only emit parameters for independent parameters that haven't been // constrained to concrete types. if (Generics->isConcreteType(depTy, M)) continue; // Pass the type argument if not fulfilled. - if (!Fulfillments.count(FulfillmentKey(depTy, nullptr))) { + if (!Fulfillments.getTypeMetadata(depTy)) { out.push_back(IGM.TypeMetadataPtrTy); } @@ -3358,7 +3740,7 @@ namespace { if (!Lowering::TypeConverter::protocolRequiresWitnessTable(protocol)) continue; - if (!Fulfillments.count(FulfillmentKey(depTy, protocol))) { + if (!Fulfillments.getWitnessTable(depTy, protocol)) { out.push_back(IGM.WitnessTablePtrTy); } } @@ -3409,6 +3791,7 @@ void irgen::expandTrailingWitnessSignature(IRGenModule &IGM, void irgen::emitWitnessMethodValue(IRGenFunction &IGF, CanType baseTy, + llvm::Value **baseMetadataCache, SILDeclRef member, ProtocolConformance *conformance, Explosion &out) { @@ -3419,9 +3802,8 @@ irgen::emitWitnessMethodValue(IRGenFunction &IGF, // Find the witness table. // FIXME conformance for concrete type - auto &baseTI = IGF.getTypeInfoForUnlowered(baseTy); auto &fnProtoInfo = IGF.IGM.getProtocolInfo(fnProto); - llvm::Value *wtable = emitWitnessTableRef(IGF, baseTy, baseTI, + llvm::Value *wtable = emitWitnessTableRef(IGF, baseTy, baseMetadataCache, fnProto, fnProtoInfo, conformance); @@ -3436,3 +3818,76 @@ irgen::emitWitnessMethodValue(IRGenFunction &IGF, // Build the value. out.add(witness); } + +llvm::FunctionType *IRGenModule::getAssociatedTypeMetadataAccessFunctionTy() { + if (AssociatedTypeMetadataAccessFunctionTy) + return AssociatedTypeMetadataAccessFunctionTy; + + auto accessorTy = llvm::FunctionType::get(TypeMetadataPtrTy, + { TypeMetadataPtrTy, + WitnessTablePtrTy }, + /*varargs*/ false); + AssociatedTypeMetadataAccessFunctionTy = accessorTy; + return accessorTy; +} + +llvm::Value *irgen::emitAssociatedTypeMetadataRef(IRGenFunction &IGF, + llvm::Value *parentMetadata, + llvm::Value *wtable, + AssociatedTypeDecl *associatedType) { + auto &pi = IGF.IGM.getProtocolInfo(associatedType->getProtocol()); + auto index = pi.getWitnessEntry(associatedType).getAssociatedTypeIndex(); + llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, wtable, index); + + // Cast the witness to the appropriate function type. + auto witnessTy = IGF.IGM.getAssociatedTypeMetadataAccessFunctionTy(); + witness = IGF.Builder.CreateBitCast(witness, witnessTy->getPointerTo()); + + // Call the accessor. + auto call = IGF.Builder.CreateCall(witness, { parentMetadata, wtable }); + call->setDoesNotThrow(); + call->setCallingConv(IGF.IGM.RuntimeCC); + + return call; +} + +llvm::FunctionType * +IRGenModule::getAssociatedTypeWitnessTableAccessFunctionTy() { + if (AssociatedTypeWitnessTableAccessFunctionTy) + return AssociatedTypeWitnessTableAccessFunctionTy; + + // The associated type metadata is passed first so that this function is + // CC-compatible with a conformance's witness table access function. + auto accessorTy = llvm::FunctionType::get(WitnessTablePtrTy, + { TypeMetadataPtrTy, + TypeMetadataPtrTy, + WitnessTablePtrTy }, + /*varargs*/ false); + AssociatedTypeWitnessTableAccessFunctionTy = accessorTy; + return accessorTy; +} + +llvm::Value * +irgen::emitAssociatedTypeWitnessTableRef(IRGenFunction &IGF, + llvm::Value *parentMetadata, + llvm::Value *wtable, + AssociatedTypeDecl *associatedType, + llvm::Value *associatedTypeMetadata, + ProtocolDecl *associatedProtocol) { + auto &pi = IGF.IGM.getProtocolInfo(associatedType->getProtocol()); + auto index = pi.getWitnessEntry(associatedType) + .getAssociatedTypeWitnessTableIndex(associatedProtocol); + llvm::Value *witness = emitInvariantLoadOfOpaqueWitness(IGF, wtable, index); + + // Cast the witness to the appropriate function type. + auto witnessTy = IGF.IGM.getAssociatedTypeWitnessTableAccessFunctionTy(); + witness = IGF.Builder.CreateBitCast(witness, witnessTy->getPointerTo()); + + // Call the accessor. + auto call = IGF.Builder.CreateCall(witness, + { associatedTypeMetadata, parentMetadata, wtable }); + call->setDoesNotThrow(); + call->setCallingConv(IGF.IGM.RuntimeCC); + + return call; +} diff --git a/lib/IRGen/GenProto.h b/lib/IRGen/GenProto.h index 44a7eac3562f6..1f2d5e0e22dc8 100644 --- a/lib/IRGen/GenProto.h +++ b/lib/IRGen/GenProto.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -43,10 +43,40 @@ namespace irgen { /// as a function value. void emitWitnessMethodValue(IRGenFunction &IGF, CanType baseTy, + llvm::Value **baseMetadataCache, SILDeclRef member, ProtocolConformance *conformance, Explosion &out); + /// Given a type T and an associated type X of some protocol P to + /// which T conforms, return the type metadata for T.X. + /// + /// \param parentMetadata - the type metadata for T + /// \param wtable - the witness table witnessing the conformance of T to P + /// \param associatedType - the declaration of X; a member of P + llvm::Value *emitAssociatedTypeMetadataRef(IRGenFunction &IGF, + llvm::Value *parentMetadata, + llvm::Value *wtable, + AssociatedTypeDecl *associatedType); + + /// Given a type T and an associated type X of a protocol PT to which + /// T conforms, where X is required to implement some protocol PX, return + /// the witness table witnessing the conformance of T.X to PX. + /// + /// PX must be a direct requirement of X. + /// + /// \param parentMetadata - the type metadata for T + /// \param wtable - the witness table witnessing the conformance of T to PT + /// \param associatedType - the declaration of X; a member of PT + /// \param associatedTypeMetadata - the type metadata for T.X + /// \param associatedProtocol - the declaration of PX + llvm::Value *emitAssociatedTypeWitnessTableRef(IRGenFunction &IGF, + llvm::Value *parentMetadata, + llvm::Value *wtable, + AssociatedTypeDecl *associatedType, + llvm::Value *associatedTypeMetadata, + ProtocolDecl *associatedProtocol); + /// Add the witness parameters necessary for calling a function with /// the given generics clause. void expandPolymorphicSignature(IRGenModule &IGM, @@ -125,12 +155,13 @@ namespace irgen { /// Emit references to the witness tables for the substituted type /// in the given substitution. void emitWitnessTableRefs(IRGenFunction &IGF, const Substitution &sub, + llvm::Value **metadataCache, SmallVectorImpl &out); /// Emit a witness table reference. llvm::Value *emitWitnessTableRef(IRGenFunction &IGF, CanType srcType, - const TypeInfo &srcTI, + llvm::Value **srcMetadataCache, ProtocolDecl *proto, const ProtocolInfo &protoI, ProtocolConformance *conformance); diff --git a/lib/IRGen/GenRecord.h b/lib/IRGen/GenRecord.h new file mode 100644 index 0000000000000..a2a8908f01d99 --- /dev/null +++ b/lib/IRGen/GenRecord.h @@ -0,0 +1,417 @@ +//===--- GenRecord.h - IR generation for record types -----------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file provides some common code for emitting record types. +// A record type is something like a tuple or a struct. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_GENRECORD_H +#define SWIFT_IRGEN_GENRECORD_H + +#include "IRGenFunction.h" +#include "IRGenModule.h" +#include "Explosion.h" +#include "GenEnum.h" +#include "LoadableTypeInfo.h" +#include "TypeInfo.h" +#include "StructLayout.h" + +namespace swift { +namespace irgen { + +template class RecordTypeBuilder; + +/// A field of a record type. +template class RecordField { + ElementLayout Layout; + + template friend class RecordTypeBuilder; + + /// Begin/End - the range of explosion indexes for this element + unsigned Begin : 16; + unsigned End : 16; + +protected: + explicit RecordField(const TypeInfo &elementTI) + : Layout(ElementLayout::getIncomplete(elementTI)) {} + + explicit RecordField(const ElementLayout &layout, + unsigned begin, unsigned end) + : Layout(layout), Begin(begin), End(end) {} + + const FieldImpl *asImpl() const { + return static_cast(this); + } +public: + const TypeInfo &getTypeInfo() const { return Layout.getType(); } + + void completeFrom(const ElementLayout &layout) { + Layout.completeFrom(layout); + } + + bool isEmpty() const { + return Layout.isEmpty(); + } + + IsPOD_t isPOD() const { + return Layout.isPOD(); + } + + Address projectAddress(IRGenFunction &IGF, Address seq, + NonFixedOffsets offsets) const { + return Layout.project(IGF, seq, offsets, "." + asImpl()->getFieldName()); + } + + ElementLayout::Kind getKind() const { + return Layout.getKind(); + } + + Size getFixedByteOffset() const { + return Layout.getByteOffset(); + } + + std::pair getProjectionRange() const { + return {Begin, End}; + } +}; + +/// A metaprogrammed TypeInfo implementation for record types. +template ::value> +class RecordTypeInfoImpl : public Base { +public: + typedef FieldImpl_ FieldImpl; + +private: + const unsigned NumFields; + + const FieldImpl *getFieldsBuffer() const { + return reinterpret_cast(static_cast(this)+1); + } + FieldImpl *getFieldsBuffer() { + return reinterpret_cast(static_cast(this)+1); + } + +protected: + const Impl &asImpl() const { return *static_cast(this); } + + template + RecordTypeInfoImpl(ArrayRef fields, As&&...args) + : Base(std::forward(args)...), NumFields(fields.size()) { + std::uninitialized_copy(fields.begin(), fields.end(), + getFieldsBuffer()); + } + +public: + /// Allocate and initialize a type info of this type. + template + static Impl *create(ArrayRef fields, As &&...args) { + void *buffer = + ::operator new(sizeof(Impl) + fields.size() * sizeof(FieldImpl)); + return new(buffer) Impl(fields, std::forward(args)...); + } + + ArrayRef getFields() const { + return ArrayRef(getFieldsBuffer(), NumFields); + } + + /// The standard schema is just all the fields jumbled together. + void getSchema(ExplosionSchema &schema) const override { + for (auto &field : getFields()) { + field.getTypeInfo().getSchema(schema); + } + } + + void assignWithCopy(IRGenFunction &IGF, Address dest, + Address src, SILType T) const override { + auto offsets = asImpl().getNonFixedOffsets(IGF, T); + for (auto &field : getFields()) { + if (field.isEmpty()) continue; + + Address destField = field.projectAddress(IGF, dest, offsets); + Address srcField = field.projectAddress(IGF, src, offsets); + field.getTypeInfo().assignWithCopy(IGF, destField, srcField, + field.getType(IGF.IGM, T)); + } + } + + void assignWithTake(IRGenFunction &IGF, Address dest, + Address src, SILType T) const override { + auto offsets = asImpl().getNonFixedOffsets(IGF, T); + for (auto &field : getFields()) { + if (field.isEmpty()) continue; + + Address destField = field.projectAddress(IGF, dest, offsets); + Address srcField = field.projectAddress(IGF, src, offsets); + field.getTypeInfo().assignWithTake(IGF, destField, srcField, + field.getType(IGF.IGM, T)); + } + } + + void initializeWithCopy(IRGenFunction &IGF, + Address dest, Address src, + SILType T) const override { + // If we're POD, use the generic routine. + if (this->isPOD(ResilienceScope::Component) && + isa(this)) { + return cast(this)-> + LoadableTypeInfo::initializeWithCopy(IGF, dest, src, T); + } + + auto offsets = asImpl().getNonFixedOffsets(IGF, T); + for (auto &field : getFields()) { + if (field.isEmpty()) continue; + + Address destField = field.projectAddress(IGF, dest, offsets); + Address srcField = field.projectAddress(IGF, src, offsets); + field.getTypeInfo().initializeWithCopy(IGF, destField, srcField, + field.getType(IGF.IGM, T)); + } + } + + void initializeWithTake(IRGenFunction &IGF, + Address dest, Address src, + SILType T) const override { + // If we're bitwise-takable, use memcpy. + if (this->isBitwiseTakable(ResilienceScope::Component)) { + IGF.Builder.CreateMemCpy(dest.getAddress(), src.getAddress(), + asImpl().Impl::getSize(IGF, T), + std::min(dest.getAlignment(), src.getAlignment()).getValue()); + return; + } + + auto offsets = asImpl().getNonFixedOffsets(IGF, T); + for (auto &field : getFields()) { + if (field.isEmpty()) continue; + + Address destField = field.projectAddress(IGF, dest, offsets); + Address srcField = field.projectAddress(IGF, src, offsets); + field.getTypeInfo().initializeWithTake(IGF, destField, srcField, + field.getType(IGF.IGM, T)); + } + } + + void destroy(IRGenFunction &IGF, Address addr, SILType T) const override { + auto offsets = asImpl().getNonFixedOffsets(IGF, T); + for (auto &field : getFields()) { + if (field.isPOD()) continue; + + field.getTypeInfo().destroy(IGF, field.projectAddress(IGF, addr, offsets), + field.getType(IGF.IGM, T)); + } + } +}; + +template ::value> +class RecordTypeInfo; + +/// An implementation of RecordTypeInfo for non-loadable types. +template +class RecordTypeInfo + : public RecordTypeInfoImpl { + typedef RecordTypeInfoImpl super; +protected: + template + RecordTypeInfo(As&&...args) : super(std::forward(args)...) {} +}; + +/// An implementation of RecordTypeInfo for loadable types. +template +class RecordTypeInfo + : public RecordTypeInfoImpl { + typedef RecordTypeInfoImpl super; + + unsigned ExplosionSize : 16; + +protected: + using super::asImpl; + + template + RecordTypeInfo(ArrayRef fields, unsigned explosionSize, + As &&...args) + : super(fields, std::forward(args)...), + ExplosionSize(explosionSize) {} + +private: + template + void forAllFields(IRGenFunction &IGF, Address addr, Explosion &out) const { + auto offsets = asImpl().getNonFixedOffsets(IGF); + for (auto &field : getFields()) { + if (field.isEmpty()) continue; + + Address fieldAddr = field.projectAddress(IGF, addr, offsets); + (cast(field.getTypeInfo()).*Op)(IGF, fieldAddr, out); + } + } + + template + void forAllFields(IRGenFunction &IGF, Explosion &in, Address addr) const { + auto offsets = asImpl().getNonFixedOffsets(IGF); + for (auto &field : getFields()) { + if (field.isEmpty()) continue; + + Address fieldAddr = field.projectAddress(IGF, addr, offsets); + (cast(field.getTypeInfo()).*Op)(IGF, in, fieldAddr); + } + } + +public: + using super::getFields; + + void loadAsCopy(IRGenFunction &IGF, Address addr, + Explosion &out) const override { + forAllFields<&LoadableTypeInfo::loadAsCopy>(IGF, addr, out); + } + + void loadAsTake(IRGenFunction &IGF, Address addr, + Explosion &out) const override { + forAllFields<&LoadableTypeInfo::loadAsTake>(IGF, addr, out); + } + + void assign(IRGenFunction &IGF, Explosion &e, Address addr) const override { + forAllFields<&LoadableTypeInfo::assign>(IGF, e, addr); + } + + void initialize(IRGenFunction &IGF, Explosion &e, + Address addr) const override { + forAllFields<&LoadableTypeInfo::initialize>(IGF, e, addr); + } + + unsigned getExplosionSize() const override { + return ExplosionSize; + } + + void reexplode(IRGenFunction &IGF, Explosion &src, + Explosion &dest) const override { + for (auto &field : getFields()) + cast(field.getTypeInfo()).reexplode(IGF, src, dest); + } + + void copy(IRGenFunction &IGF, Explosion &src, + Explosion &dest) const override { + for (auto &field : getFields()) + cast(field.getTypeInfo()).copy(IGF, src, dest); + } + + void consume(IRGenFunction &IGF, Explosion &src) const override { + for (auto &field : getFields()) + cast(field.getTypeInfo()).consume(IGF, src); + } + + void fixLifetime(IRGenFunction &IGF, Explosion &src) const override { + for (auto &field : getFields()) + cast(field.getTypeInfo()).fixLifetime(IGF, src); + } + + void packIntoEnumPayload(IRGenFunction &IGF, + EnumPayload &payload, + Explosion &src, + unsigned startOffset) const override { + for (auto &field : getFields()) { + if (field.getKind() != ElementLayout::Kind::Empty) { + unsigned offset = field.getFixedByteOffset().getValueInBits() + + startOffset; + cast(field.getTypeInfo()) + .packIntoEnumPayload(IGF, payload, src, offset); + } + } + } + + void unpackFromEnumPayload(IRGenFunction &IGF, const EnumPayload &payload, + Explosion &dest, unsigned startOffset) + const override { + for (auto &field : getFields()) { + if (field.getKind() != ElementLayout::Kind::Empty) { + unsigned offset = field.getFixedByteOffset().getValueInBits() + + startOffset; + cast(field.getTypeInfo()) + .unpackFromEnumPayload(IGF, payload, dest, offset); + } + } + } +}; + +/// A builder of record types. +/// +/// Required for a full implementation: +/// TypeInfoImpl *construct(void *buffer, ArrayRef fields); +/// FieldImpl getFieldInfo(const ASTField &field, const TypeInfo &fieldTI); +/// Type getType(const ASTField &field); +/// void performLayout(ArrayRef fieldTypes); +/// - should call recordLayout with the layout +template +class RecordTypeBuilder { +protected: + IRGenModule &IGM; + RecordTypeBuilder(IRGenModule &IGM) : IGM(IGM) {} + + BuilderImpl *asImpl() { return static_cast(this); } + +public: + TypeInfo *layout(ArrayRef astFields) { + SmallVector fields; + SmallVector fieldTypesForLayout; + fields.reserve(astFields.size()); + fieldTypesForLayout.reserve(astFields.size()); + + bool loadable = true; + + unsigned explosionSize = 0; + for (unsigned i : indices(astFields)) { + auto &astField = astFields[i]; + // Compute the field's type info. + auto &fieldTI = IGM.getTypeInfo(asImpl()->getType(astField)); + assert(fieldTI.isComplete()); + fieldTypesForLayout.push_back(&fieldTI); + + fields.push_back(FieldImpl(asImpl()->getFieldInfo(i, astField, fieldTI))); + + auto loadableFieldTI = dyn_cast(&fieldTI); + if (!loadableFieldTI) { + loadable = false; + continue; + } + + auto &fieldInfo = fields.back(); + fieldInfo.Begin = explosionSize; + explosionSize += loadableFieldTI->getExplosionSize(); + fieldInfo.End = explosionSize; + } + + // Perform layout and fill in the fields. + StructLayout layout = asImpl()->performLayout(fieldTypesForLayout); + for (unsigned i = 0, e = fields.size(); i != e; ++i) { + fields[i].completeFrom(layout.getElements()[i]); + } + + // Create the type info. + if (loadable) { + assert(layout.isFixedLayout()); + return asImpl()->createLoadable(fields, std::move(layout), explosionSize); + } else if (layout.isFixedLayout()) { + return asImpl()->createFixed(fields, std::move(layout)); + } else { + return asImpl()->createNonFixed(fields, std::move(layout)); + } + } +}; + +} // end namespace irgen +} // end namespace swift + +#endif diff --git a/lib/IRGen/GenSequential.h b/lib/IRGen/GenSequential.h deleted file mode 100644 index 49ae9c7648c8a..0000000000000 --- a/lib/IRGen/GenSequential.h +++ /dev/null @@ -1,417 +0,0 @@ -//===--- GenSequential.h - IR generation for sequential types ---*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// -// This file provides some common code for emitting sequential types. -// A sequential type is something like a tuple or a struct. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_IRGEN_GENSEQUENTIAL_H -#define SWIFT_IRGEN_GENSEQUENTIAL_H - -#include "IRGenFunction.h" -#include "IRGenModule.h" -#include "Explosion.h" -#include "GenEnum.h" -#include "LoadableTypeInfo.h" -#include "TypeInfo.h" -#include "StructLayout.h" - -namespace swift { -namespace irgen { - -template class SequentialTypeBuilder; - -/// A field of a sequential type. -template class SequentialField { - ElementLayout Layout; - - template friend class SequentialTypeBuilder; - - /// Begin/End - the range of explosion indexes for this element - unsigned Begin : 16; - unsigned End : 16; - -protected: - explicit SequentialField(const TypeInfo &elementTI) - : Layout(ElementLayout::getIncomplete(elementTI)) {} - - explicit SequentialField(const ElementLayout &layout, - unsigned begin, unsigned end) - : Layout(layout), Begin(begin), End(end) {} - - const FieldImpl *asImpl() const { - return static_cast(this); - } -public: - const TypeInfo &getTypeInfo() const { return Layout.getType(); } - - void completeFrom(const ElementLayout &layout) { - Layout.completeFrom(layout); - } - - bool isEmpty() const { - return Layout.isEmpty(); - } - - IsPOD_t isPOD() const { - return Layout.isPOD(); - } - - Address projectAddress(IRGenFunction &IGF, Address seq, - NonFixedOffsets offsets) const { - return Layout.project(IGF, seq, offsets, "." + asImpl()->getFieldName()); - } - - ElementLayout::Kind getKind() const { - return Layout.getKind(); - } - - Size getFixedByteOffset() const { - return Layout.getByteOffset(); - } - - std::pair getProjectionRange() const { - return {Begin, End}; - } -}; - -/// A metaprogrammed TypeInfo implementation for sequential types. -template ::value> -class SequentialTypeInfoImpl : public Base { -public: - typedef FieldImpl_ FieldImpl; - -private: - const unsigned NumFields; - - const FieldImpl *getFieldsBuffer() const { - return reinterpret_cast(static_cast(this)+1); - } - FieldImpl *getFieldsBuffer() { - return reinterpret_cast(static_cast(this)+1); - } - -protected: - const Impl &asImpl() const { return *static_cast(this); } - - template - SequentialTypeInfoImpl(ArrayRef fields, As&&...args) - : Base(std::forward(args)...), NumFields(fields.size()) { - std::uninitialized_copy(fields.begin(), fields.end(), - getFieldsBuffer()); - } - -public: - /// Allocate and initialize a type info of this type. - template - static Impl *create(ArrayRef fields, As &&...args) { - void *buffer = - ::operator new(sizeof(Impl) + fields.size() * sizeof(FieldImpl)); - return new(buffer) Impl(fields, std::forward(args)...); - } - - ArrayRef getFields() const { - return ArrayRef(getFieldsBuffer(), NumFields); - } - - /// The standard schema is just all the fields jumbled together. - void getSchema(ExplosionSchema &schema) const override { - for (auto &field : getFields()) { - field.getTypeInfo().getSchema(schema); - } - } - - void assignWithCopy(IRGenFunction &IGF, Address dest, - Address src, SILType T) const override { - auto offsets = asImpl().getNonFixedOffsets(IGF, T); - for (auto &field : getFields()) { - if (field.isEmpty()) continue; - - Address destField = field.projectAddress(IGF, dest, offsets); - Address srcField = field.projectAddress(IGF, src, offsets); - field.getTypeInfo().assignWithCopy(IGF, destField, srcField, - field.getType(IGF.IGM, T)); - } - } - - void assignWithTake(IRGenFunction &IGF, Address dest, - Address src, SILType T) const override { - auto offsets = asImpl().getNonFixedOffsets(IGF, T); - for (auto &field : getFields()) { - if (field.isEmpty()) continue; - - Address destField = field.projectAddress(IGF, dest, offsets); - Address srcField = field.projectAddress(IGF, src, offsets); - field.getTypeInfo().assignWithTake(IGF, destField, srcField, - field.getType(IGF.IGM, T)); - } - } - - void initializeWithCopy(IRGenFunction &IGF, - Address dest, Address src, - SILType T) const override { - // If we're POD, use the generic routine. - if (this->isPOD(ResilienceScope::Component) && - isa(this)) { - return cast(this)-> - LoadableTypeInfo::initializeWithCopy(IGF, dest, src, T); - } - - auto offsets = asImpl().getNonFixedOffsets(IGF, T); - for (auto &field : getFields()) { - if (field.isEmpty()) continue; - - Address destField = field.projectAddress(IGF, dest, offsets); - Address srcField = field.projectAddress(IGF, src, offsets); - field.getTypeInfo().initializeWithCopy(IGF, destField, srcField, - field.getType(IGF.IGM, T)); - } - } - - void initializeWithTake(IRGenFunction &IGF, - Address dest, Address src, - SILType T) const override { - // If we're bitwise-takable, use memcpy. - if (this->isBitwiseTakable(ResilienceScope::Component)) { - IGF.Builder.CreateMemCpy(dest.getAddress(), src.getAddress(), - asImpl().Impl::getSize(IGF, T), - std::min(dest.getAlignment(), src.getAlignment()).getValue()); - return; - } - - auto offsets = asImpl().getNonFixedOffsets(IGF, T); - for (auto &field : getFields()) { - if (field.isEmpty()) continue; - - Address destField = field.projectAddress(IGF, dest, offsets); - Address srcField = field.projectAddress(IGF, src, offsets); - field.getTypeInfo().initializeWithTake(IGF, destField, srcField, - field.getType(IGF.IGM, T)); - } - } - - void destroy(IRGenFunction &IGF, Address addr, SILType T) const override { - auto offsets = asImpl().getNonFixedOffsets(IGF, T); - for (auto &field : getFields()) { - if (field.isPOD()) continue; - - field.getTypeInfo().destroy(IGF, field.projectAddress(IGF, addr, offsets), - field.getType(IGF.IGM, T)); - } - } -}; - -template ::value> -class SequentialTypeInfo; - -/// An implementation of SequentialTypeInfo for non-loadable types. -template -class SequentialTypeInfo - : public SequentialTypeInfoImpl { - typedef SequentialTypeInfoImpl super; -protected: - template - SequentialTypeInfo(As&&...args) : super(std::forward(args)...) {} -}; - -/// An implementation of SequentialTypeInfo for loadable types. -template -class SequentialTypeInfo - : public SequentialTypeInfoImpl { - typedef SequentialTypeInfoImpl super; - - unsigned ExplosionSize : 16; - -protected: - using super::asImpl; - - template - SequentialTypeInfo(ArrayRef fields, unsigned explosionSize, - As &&...args) - : super(fields, std::forward(args)...), - ExplosionSize(explosionSize) {} - -private: - template - void forAllFields(IRGenFunction &IGF, Address addr, Explosion &out) const { - auto offsets = asImpl().getNonFixedOffsets(IGF); - for (auto &field : getFields()) { - if (field.isEmpty()) continue; - - Address fieldAddr = field.projectAddress(IGF, addr, offsets); - (cast(field.getTypeInfo()).*Op)(IGF, fieldAddr, out); - } - } - - template - void forAllFields(IRGenFunction &IGF, Explosion &in, Address addr) const { - auto offsets = asImpl().getNonFixedOffsets(IGF); - for (auto &field : getFields()) { - if (field.isEmpty()) continue; - - Address fieldAddr = field.projectAddress(IGF, addr, offsets); - (cast(field.getTypeInfo()).*Op)(IGF, in, fieldAddr); - } - } - -public: - using super::getFields; - - void loadAsCopy(IRGenFunction &IGF, Address addr, - Explosion &out) const override { - forAllFields<&LoadableTypeInfo::loadAsCopy>(IGF, addr, out); - } - - void loadAsTake(IRGenFunction &IGF, Address addr, - Explosion &out) const override { - forAllFields<&LoadableTypeInfo::loadAsTake>(IGF, addr, out); - } - - void assign(IRGenFunction &IGF, Explosion &e, Address addr) const override { - forAllFields<&LoadableTypeInfo::assign>(IGF, e, addr); - } - - void initialize(IRGenFunction &IGF, Explosion &e, - Address addr) const override { - forAllFields<&LoadableTypeInfo::initialize>(IGF, e, addr); - } - - unsigned getExplosionSize() const override { - return ExplosionSize; - } - - void reexplode(IRGenFunction &IGF, Explosion &src, - Explosion &dest) const override { - for (auto &field : getFields()) - cast(field.getTypeInfo()).reexplode(IGF, src, dest); - } - - void copy(IRGenFunction &IGF, Explosion &src, - Explosion &dest) const override { - for (auto &field : getFields()) - cast(field.getTypeInfo()).copy(IGF, src, dest); - } - - void consume(IRGenFunction &IGF, Explosion &src) const override { - for (auto &field : getFields()) - cast(field.getTypeInfo()).consume(IGF, src); - } - - void fixLifetime(IRGenFunction &IGF, Explosion &src) const override { - for (auto &field : getFields()) - cast(field.getTypeInfo()).fixLifetime(IGF, src); - } - - void packIntoEnumPayload(IRGenFunction &IGF, - EnumPayload &payload, - Explosion &src, - unsigned startOffset) const override { - for (auto &field : getFields()) { - if (field.getKind() != ElementLayout::Kind::Empty) { - unsigned offset = field.getFixedByteOffset().getValueInBits() - + startOffset; - cast(field.getTypeInfo()) - .packIntoEnumPayload(IGF, payload, src, offset); - } - } - } - - void unpackFromEnumPayload(IRGenFunction &IGF, const EnumPayload &payload, - Explosion &dest, unsigned startOffset) - const override { - for (auto &field : getFields()) { - if (field.getKind() != ElementLayout::Kind::Empty) { - unsigned offset = field.getFixedByteOffset().getValueInBits() - + startOffset; - cast(field.getTypeInfo()) - .unpackFromEnumPayload(IGF, payload, dest, offset); - } - } - } -}; - -/// A builder of sequential types. -/// -/// Required for a full implementation: -/// TypeInfoImpl *construct(void *buffer, ArrayRef fields); -/// FieldImpl getFieldInfo(const ASTField &field, const TypeInfo &fieldTI); -/// Type getType(const ASTField &field); -/// void performLayout(ArrayRef fieldTypes); -/// - should call recordLayout with the layout -template -class SequentialTypeBuilder { -protected: - IRGenModule &IGM; - SequentialTypeBuilder(IRGenModule &IGM) : IGM(IGM) {} - - BuilderImpl *asImpl() { return static_cast(this); } - -public: - TypeInfo *layout(ArrayRef astFields) { - SmallVector fields; - SmallVector fieldTypesForLayout; - fields.reserve(astFields.size()); - fieldTypesForLayout.reserve(astFields.size()); - - bool loadable = true; - - unsigned explosionSize = 0; - for (unsigned i : indices(astFields)) { - auto &astField = astFields[i]; - // Compute the field's type info. - auto &fieldTI = IGM.getTypeInfo(asImpl()->getType(astField)); - assert(fieldTI.isComplete()); - fieldTypesForLayout.push_back(&fieldTI); - - fields.push_back(FieldImpl(asImpl()->getFieldInfo(i, astField, fieldTI))); - - auto loadableFieldTI = dyn_cast(&fieldTI); - if (!loadableFieldTI) { - loadable = false; - continue; - } - - auto &fieldInfo = fields.back(); - fieldInfo.Begin = explosionSize; - explosionSize += loadableFieldTI->getExplosionSize(); - fieldInfo.End = explosionSize; - } - - // Perform layout and fill in the fields. - StructLayout layout = asImpl()->performLayout(fieldTypesForLayout); - for (unsigned i = 0, e = fields.size(); i != e; ++i) { - fields[i].completeFrom(layout.getElements()[i]); - } - - // Create the type info. - if (loadable) { - assert(layout.isFixedLayout()); - return asImpl()->createLoadable(fields, std::move(layout), explosionSize); - } else if (layout.isFixedLayout()) { - return asImpl()->createFixed(fields, std::move(layout)); - } else { - return asImpl()->createNonFixed(fields, std::move(layout)); - } - } -}; - -} // end namespace irgen -} // end namespace swift - -#endif diff --git a/lib/IRGen/GenStruct.cpp b/lib/IRGen/GenStruct.cpp index e53a7c35acce9..339f853e8f70a 100644 --- a/lib/IRGen/GenStruct.cpp +++ b/lib/IRGen/GenStruct.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,7 +28,7 @@ #include "clang/AST/RecordLayout.h" #include "GenMeta.h" -#include "GenSequential.h" +#include "GenRecord.h" #include "GenType.h" #include "IRGenFunction.h" #include "IRGenModule.h" @@ -57,10 +57,10 @@ static StructTypeInfoKind getStructTypeInfoKind(const TypeInfo &type) { } namespace { - class StructFieldInfo : public SequentialField { + class StructFieldInfo : public RecordField { public: StructFieldInfo(VarDecl *field, const TypeInfo &type) - : SequentialField(type), Field(field) {} + : RecordField(type), Field(field) {} /// The field. VarDecl * const Field; @@ -75,11 +75,11 @@ namespace { }; /// A field-info implementation for fields of Clang types. - class ClangFieldInfo : public SequentialField { + class ClangFieldInfo : public RecordField { public: ClangFieldInfo(VarDecl *swiftField, const ElementLayout &layout, unsigned explosionBegin, unsigned explosionEnd) - : SequentialField(layout, explosionBegin, explosionEnd), + : RecordField(layout, explosionBegin, explosionEnd), Field(swiftField) {} VarDecl * const Field; @@ -102,8 +102,8 @@ namespace { /// A common base class for structs. template class StructTypeInfoBase : - public SequentialTypeInfo { - typedef SequentialTypeInfo super; + public RecordTypeInfo { + typedef RecordTypeInfo super; protected: template @@ -415,6 +415,8 @@ namespace { llvm::ArrayType::get(IGF.IGM.Int8PtrPtrTy, storedProperties.size()), IGF.IGM.getPointerAlignment(), "structFields"); + IGF.Builder.CreateLifetimeStart(fields, + IGF.IGM.getPointerSize() * storedProperties.size()); fields = IGF.Builder.CreateStructGEP(fields, 0, Size(0)); unsigned index = 0; @@ -433,18 +435,20 @@ namespace { IGF.Builder.CreateCall(IGF.IGM.getInitStructMetadataUniversalFn(), {numFields, fields.getAddress(), fieldVector, vwtable}); + IGF.Builder.CreateLifetimeEnd(fields, + IGF.IGM.getPointerSize() * storedProperties.size()); } }; class StructTypeBuilder : - public SequentialTypeBuilder { + public RecordTypeBuilder { llvm::StructType *StructTy; CanType TheStruct; public: StructTypeBuilder(IRGenModule &IGM, llvm::StructType *structTy, CanType type) : - SequentialTypeBuilder(IGM), StructTy(structTy), TheStruct(type) { + RecordTypeBuilder(IGM), StructTy(structTy), TheStruct(type) { } LoadableStructTypeInfo *createLoadable(ArrayRef fields, diff --git a/lib/IRGen/GenStruct.h b/lib/IRGen/GenStruct.h index 720e64dc8580e..70ea121333c3f 100644 --- a/lib/IRGen/GenStruct.h +++ b/lib/IRGen/GenStruct.h @@ -1,8 +1,8 @@ -//===--- GenStruct.h - Swift IR generation for structs ------------*- C++ -*-===// +//===--- GenStruct.h - Swift IR generation for structs ----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenTuple.cpp b/lib/IRGen/GenTuple.cpp index 90ae84dcaca66..3a4cfd68f758d 100644 --- a/lib/IRGen/GenTuple.cpp +++ b/lib/IRGen/GenTuple.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -27,7 +27,7 @@ #include "llvm/IR/DerivedTypes.h" #include "GenHeap.h" -#include "GenSequential.h" +#include "GenRecord.h" #include "GenType.h" #include "IRGenFunction.h" #include "IRGenModule.h" @@ -43,10 +43,10 @@ using namespace swift; using namespace irgen; namespace { - class TupleFieldInfo : public SequentialField { + class TupleFieldInfo : public RecordField { public: TupleFieldInfo(unsigned index, StringRef name, const TypeInfo &type) - : SequentialField(type), Index(index), Name(name) + : RecordField(type), Index(index), Name(name) {} /// The field index. @@ -71,8 +71,8 @@ namespace { /// Adapter for tuple types. template class TupleTypeInfoBase - : public SequentialTypeInfo { - typedef SequentialTypeInfo super; + : public RecordTypeInfo { + typedef RecordTypeInfo super; protected: template @@ -283,13 +283,13 @@ namespace { }; class TupleTypeBuilder : - public SequentialTypeBuilder { + public RecordTypeBuilder { SILType TheTuple; public: TupleTypeBuilder(IRGenModule &IGM, SILType theTuple) - : SequentialTypeBuilder(IGM), TheTuple(theTuple) {} + : RecordTypeBuilder(IGM), TheTuple(theTuple) {} FixedTupleTypeInfo *createFixed(ArrayRef fields, StructLayout &&layout) { diff --git a/lib/IRGen/GenTuple.h b/lib/IRGen/GenTuple.h index a2a5dad7f655b..9627cb767e236 100644 --- a/lib/IRGen/GenTuple.h +++ b/lib/IRGen/GenTuple.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/GenType.cpp b/lib/IRGen/GenType.cpp index 3067a18fcf9f0..b97086b377013 100644 --- a/lib/IRGen/GenType.cpp +++ b/lib/IRGen/GenType.cpp @@ -1,8 +1,8 @@ -//===--- GenTypes.cpp - Swift IR Generation For Types ---------------------===// +//===--- GenType.cpp - Swift IR Generation For Types ----------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -40,7 +40,6 @@ #include "ProtocolInfo.h" #include "ReferenceTypeInfo.h" #include "ScalarTypeInfo.h" -#include "UnownedTypeInfo.h" #include "WeakTypeInfo.h" using namespace swift; @@ -51,6 +50,24 @@ TypeConverter::Types_t::getCacheFor(TypeBase *t) { return t->hasTypeParameter() ? DependentCache : IndependentCache; } +void TypeInfo:: assign(IRGenFunction &IGF, Address dest, Address src, + IsTake_t isTake, SILType T) const { + if (isTake) { + assignWithTake(IGF, dest, src, T); + } else { + assignWithCopy(IGF, dest, src, T); + } +} + +void TypeInfo::initialize(IRGenFunction &IGF, Address dest, Address src, + IsTake_t isTake, SILType T) const { + if (isTake) { + initializeWithTake(IGF, dest, src, T); + } else { + initializeWithCopy(IGF, dest, src, T); + } +} + Address TypeInfo::initializeBufferWithTake(IRGenFunction &IGF, Address destBuffer, Address srcAddr, @@ -153,12 +170,14 @@ void TypeInfo::destroyArray(IRGenFunction &IGF, Address array, auto elementVal = IGF.Builder.CreatePHI(array.getType(), 2); elementVal->addIncoming(array.getAddress(), entry); Address element(elementVal, array.getAlignment()); - + auto done = IGF.Builder.CreateICmpEQ(counter, llvm::ConstantInt::get(IGF.IGM.SizeTy, 0)); IGF.Builder.CreateCondBr(done, exit, loop); IGF.Builder.emitBlock(loop); + ConditionalDominanceScope condition(IGF); + destroy(IGF, element, T); auto nextCounter = IGF.Builder.CreateSub(counter, llvm::ConstantInt::get(IGF.IGM.SizeTy, 1)); @@ -197,16 +216,14 @@ void irgen::emitInitializeArrayFrontToBack(IRGenFunction &IGF, srcVal->addIncoming(srcArray.getAddress(), entry); Address dest(destVal, destArray.getAlignment()); Address src(srcVal, srcArray.getAlignment()); - + auto done = IGF.Builder.CreateICmpEQ(counter, llvm::ConstantInt::get(IGM.SizeTy, 0)); IGF.Builder.CreateCondBr(done, exit, loop); IGF.Builder.emitBlock(loop); - if (take) - type.initializeWithTake(IGF, dest, src, T); - else - type.initializeWithCopy(IGF, dest, src, T); + ConditionalDominanceScope condition(IGF); + type.initialize(IGF, dest, src, take, T); auto nextCounter = IGF.Builder.CreateSub(counter, llvm::ConstantInt::get(IGM.SizeTy, 1)); @@ -251,21 +268,19 @@ void irgen::emitInitializeArrayBackToFront(IRGenFunction &IGF, srcVal->addIncoming(srcEnd.getAddress(), entry); Address dest(destVal, destArray.getAlignment()); Address src(srcVal, srcArray.getAlignment()); - + auto done = IGF.Builder.CreateICmpEQ(counter, llvm::ConstantInt::get(IGM.SizeTy, 0)); IGF.Builder.CreateCondBr(done, exit, loop); IGF.Builder.emitBlock(loop); + ConditionalDominanceScope condition(IGF); auto prevDest = type.indexArray(IGF, dest, llvm::ConstantInt::getSigned(IGM.SizeTy, -1), T); auto prevSrc = type.indexArray(IGF, src, llvm::ConstantInt::getSigned(IGM.SizeTy, -1), T); - if (take) - type.initializeWithTake(IGF, prevDest, prevSrc, T); - else - type.initializeWithCopy(IGF, prevDest, prevSrc, T); + type.initialize(IGF, prevDest, prevSrc, take, T); auto nextCounter = IGF.Builder.CreateSub(counter, llvm::ConstantInt::get(IGM.SizeTy, 1)); @@ -537,6 +552,7 @@ FixedTypeInfo::getSpareBitExtraInhabitantIndex(IRGenFunction &IGF, IGF.Builder.CreateCondBr(isValid, endBB, spareBB); IGF.Builder.emitBlock(spareBB); + ConditionalDominanceScope condition(IGF); // Gather the occupied bits. auto OccupiedBits = SpareBits; @@ -662,7 +678,7 @@ namespace { }; /// A TypeInfo implementation for opaque storage. Swift will preserve any - /// data stored into this arbitarily sized and aligned field, but doesn't + /// data stored into this arbitrarily sized and aligned field, but doesn't /// know anything about the data. class OpaqueStorageTypeInfo final : public ScalarTypeInfo @@ -2031,8 +2047,9 @@ SILType irgen::getSingletonAggregateFieldType(IRGenModule &IGM, // If there's only one stored property, we have the layout of its field. auto allFields = structDecl->getStoredProperties(); + auto field = allFields.begin(); - if (std::next(field) == allFields.end()) + if (!allFields.empty() && std::next(field) == allFields.end()) return t.getFieldType(*field, *IGM.SILMod); return SILType(); @@ -2040,8 +2057,9 @@ SILType irgen::getSingletonAggregateFieldType(IRGenModule &IGM, if (auto enumDecl = t.getEnumOrBoundGenericEnum()) { auto allCases = enumDecl->getAllElements(); + auto theCase = allCases.begin(); - if (std::next(theCase) == allCases.end() + if (!allCases.empty() && std::next(theCase) == allCases.end() && (*theCase)->hasArgumentType()) return t.getEnumElementType(*theCase, *IGM.SILMod); diff --git a/lib/IRGen/GenType.h b/lib/IRGen/GenType.h index 19288fe2e6813..b71251a893cbb 100644 --- a/lib/IRGen/GenType.h +++ b/lib/IRGen/GenType.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -158,10 +158,10 @@ class TypeConverter { Alignment storageAlign); const LoadableTypeInfo &getMetatypeTypeInfo(MetatypeRepresentation representation); - const WeakTypeInfo *createSwiftWeakStorageType(llvm::Type *valueType); - const UnownedTypeInfo *createSwiftUnownedStorageType(llvm::Type *valueType); - const WeakTypeInfo *createUnknownWeakStorageType(llvm::Type *valueType); - const UnownedTypeInfo *createUnknownUnownedStorageType(llvm::Type *valueType); + const WeakTypeInfo *createWeakStorageType(llvm::Type *valueType, + ReferenceCounting style); + const TypeInfo *createUnownedStorageType(llvm::Type *valueType, + ReferenceCounting style); const LoadableTypeInfo *createUnmanagedStorageType(llvm::Type *valueType); /// Enter a generic context for lowering the parameters of a generic function diff --git a/lib/IRGen/HeapTypeInfo.h b/lib/IRGen/HeapTypeInfo.h index ec9268ce31047..6105b713b5da5 100644 --- a/lib/IRGen/HeapTypeInfo.h +++ b/lib/IRGen/HeapTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -86,8 +86,10 @@ class HeapTypeInfo : public SingleScalarTypeInfo { static const bool IsScalarPOD = false; + // Emit the copy/destroy operations required by SingleScalarTypeInfo + // using strong reference counting. void emitScalarRelease(IRGenFunction &IGF, llvm::Value *value) const { - IGF.emitScalarRelease(value, asDerived().getReferenceCounting()); + IGF.emitStrongRelease(value, asDerived().getReferenceCounting()); } void emitScalarFixLifetime(IRGenFunction &IGF, llvm::Value *value) const { @@ -95,119 +97,85 @@ class HeapTypeInfo : public SingleScalarTypeInfo { } void emitScalarRetain(IRGenFunction &IGF, llvm::Value *value) const { - IGF.emitScalarRetainCall(value, asDerived().getReferenceCounting()); + IGF.emitStrongRetain(value, asDerived().getReferenceCounting()); } - void emitScalarRetainUnowned(IRGenFunction &IGF, llvm::Value *value) const { - switch (asDerived().getReferenceCounting()) { - case ReferenceCounting::Native: - return IGF.emitRetainUnowned(value); - case ReferenceCounting::ObjC: - case ReferenceCounting::Block: - case ReferenceCounting::Unknown: - return IGF.emitUnknownRetainUnowned(value); - case ReferenceCounting::Bridge: - case ReferenceCounting::Error: - llvm_unreachable("not supported!"); - } - } - - void emitScalarUnownedRelease(IRGenFunction &IGF, llvm::Value *value) const { - switch (asDerived().getReferenceCounting()) { - case ReferenceCounting::Native: - return IGF.emitUnownedRelease(value); - case ReferenceCounting::ObjC: - case ReferenceCounting::Block: - case ReferenceCounting::Unknown: - return IGF.emitUnknownUnownedRelease(value); - case ReferenceCounting::Bridge: - case ReferenceCounting::Error: - llvm_unreachable("not supported!"); - } - } - - void emitScalarUnownedRetain(IRGenFunction &IGF, llvm::Value *value) const { - switch (asDerived().getReferenceCounting()) { - case ReferenceCounting::Native: - return IGF.emitUnownedRetain(value); - case ReferenceCounting::ObjC: - case ReferenceCounting::Block: - case ReferenceCounting::Unknown: - return IGF.emitUnknownUnownedRetain(value); - case ReferenceCounting::Bridge: - case ReferenceCounting::Error: - llvm_unreachable("not supported!"); - } - } - - void retain(IRGenFunction &IGF, Explosion &e) const override { + // Implement the primary retain/release operations of ReferenceTypeInfo + // using basic reference counting. + void strongRetain(IRGenFunction &IGF, Explosion &e) const override { llvm::Value *value = e.claimNext(); asDerived().emitScalarRetain(IGF, value); } - void release(IRGenFunction &IGF, Explosion &e) const override { + void strongRelease(IRGenFunction &IGF, Explosion &e) const override { llvm::Value *value = e.claimNext(); asDerived().emitScalarRelease(IGF, value); } - void retainUnowned(IRGenFunction &IGF, Explosion &e) const override { + void strongRetainUnowned(IRGenFunction &IGF, Explosion &e) const override { + llvm::Value *value = e.claimNext(); + IGF.emitStrongRetainUnowned(value, asDerived().getReferenceCounting()); + } + + void strongRetainUnownedRelease(IRGenFunction &IGF, + Explosion &e) const override { llvm::Value *value = e.claimNext(); - asDerived().emitScalarRetainUnowned(IGF, value); + IGF.emitStrongRetainAndUnownedRelease(value, + asDerived().getReferenceCounting()); } void unownedRetain(IRGenFunction &IGF, Explosion &e) const override { llvm::Value *value = e.claimNext(); - asDerived().emitScalarUnownedRetain(IGF, value); + IGF.emitUnownedRetain(value, asDerived().getReferenceCounting()); } void unownedRelease(IRGenFunction &IGF, Explosion &e) const override { llvm::Value *value = e.claimNext(); - asDerived().emitScalarUnownedRelease(IGF, value); + IGF.emitUnownedRelease(value, asDerived().getReferenceCounting()); + } + + void unownedLoadStrong(IRGenFunction &IGF, Address src, + Explosion &out) const override { + llvm::Value *value = IGF.emitUnownedLoadStrong(src, this->getStorageType(), + asDerived().getReferenceCounting()); + out.add(value); + } + + void unownedTakeStrong(IRGenFunction &IGF, Address src, + Explosion &out) const override { + llvm::Value *value = IGF.emitUnownedTakeStrong(src, this->getStorageType(), + asDerived().getReferenceCounting()); + out.add(value); + } + + void unownedInit(IRGenFunction &IGF, Explosion &in, + Address dest) const override { + IGF.emitUnownedInit(in.claimNext(), dest, + asDerived().getReferenceCounting()); + } + + void unownedAssign(IRGenFunction &IGF, Explosion &in, + Address dest) const override { + IGF.emitUnownedAssign(in.claimNext(), dest, + asDerived().getReferenceCounting()); } LoadedRef loadRefcountedPtr(IRGenFunction &IGF, SourceLoc loc, Address addr) const override { - switch (asDerived().getReferenceCounting()) { - case ReferenceCounting::Native: - return LoadedRef(IGF.emitLoadNativeRefcountedPtr(addr), true); - case ReferenceCounting::ObjC: - case ReferenceCounting::Block: - case ReferenceCounting::Unknown: - return LoadedRef(IGF.emitLoadUnknownRefcountedPtr(addr), true); - case ReferenceCounting::Bridge: - return LoadedRef(IGF.emitLoadBridgeRefcountedPtr(addr), true); - case ReferenceCounting::Error: - llvm_unreachable("not supported!"); - } + llvm::Value *ptr = + IGF.emitLoadRefcountedPtr(addr, asDerived().getReferenceCounting()); + return LoadedRef(ptr, true); } const WeakTypeInfo *createWeakStorageType(TypeConverter &TC) const override { - switch (asDerived().getReferenceCounting()) { - case ReferenceCounting::Native: - return TC.createSwiftWeakStorageType(this->getStorageType()); - case ReferenceCounting::ObjC: - case ReferenceCounting::Block: - case ReferenceCounting::Unknown: - return TC.createUnknownWeakStorageType(this->getStorageType()); - case ReferenceCounting::Bridge: - case ReferenceCounting::Error: - llvm_unreachable("not supported!"); - } + return TC.createWeakStorageType(this->getStorageType(), + asDerived().getReferenceCounting()); } - const UnownedTypeInfo * + const TypeInfo * createUnownedStorageType(TypeConverter &TC) const override { - switch (asDerived().getReferenceCounting()) { - case ReferenceCounting::Native: - return TC.createSwiftUnownedStorageType(this->getStorageType()); - case ReferenceCounting::ObjC: - case ReferenceCounting::Block: - case ReferenceCounting::Unknown: - return TC.createUnknownUnownedStorageType(this->getStorageType()); - case ReferenceCounting::Bridge: - case ReferenceCounting::Error: - llvm_unreachable("not supported!"); - } + return TC.createUnownedStorageType(this->getStorageType(), + asDerived().getReferenceCounting()); } const TypeInfo *createUnmanagedStorageType(TypeConverter &TC) const override { diff --git a/lib/IRGen/IRBuilder.h b/lib/IRGen/IRBuilder.h index 46cfd9a3f3abe..d4a353fa1e9d0 100644 --- a/lib/IRGen/IRBuilder.h +++ b/lib/IRGen/IRBuilder.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -211,6 +211,18 @@ class IRBuilder : public IRBuilderBase { std::min(dest.getAlignment(), src.getAlignment()).getValue()); } + + using IRBuilderBase::CreateLifetimeStart; + llvm::CallInst *CreateLifetimeStart(Address buf, Size size) { + return CreateLifetimeStart(buf.getAddress(), + llvm::ConstantInt::get(Context, APInt(64, size.getValue()))); + } + + using IRBuilderBase::CreateLifetimeEnd; + llvm::CallInst *CreateLifetimeEnd(Address buf, Size size) { + return CreateLifetimeEnd(buf.getAddress(), + llvm::ConstantInt::get(Context, APInt(64, size.getValue()))); + } }; } // end namespace irgen diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index 50744f9ea156a..813f9e34d7fb4 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,6 +23,7 @@ #include "swift/SIL/SILModule.h" #include "swift/Basic/Dwarf.h" #include "swift/Basic/Platform.h" +#include "swift/Basic/Timer.h" #include "swift/ClangImporter/ClangImporter.h" #include "swift/LLVMPasses/PassesFwd.h" #include "swift/LLVMPasses/Passes.h" @@ -116,6 +117,8 @@ void setModuleFlags(IRGenModule &IGM) { void swift::performLLVMOptimizations(IRGenOptions &Opts, llvm::Module *Module, llvm::TargetMachine *TargetMachine) { + SharedTimer timer("LLVM optimization"); + // Set up a pipeline. PassManagerBuilder PMBuilder; @@ -124,6 +127,7 @@ void swift::performLLVMOptimizations(IRGenOptions &Opts, llvm::Module *Module, PMBuilder.Inliner = llvm::createFunctionInliningPass(200); PMBuilder.SLPVectorize = true; PMBuilder.LoopVectorize = true; + PMBuilder.MergeFunctions = true; } else { PMBuilder.OptLevel = 0; if (!Opts.DisableLLVMOptzns) @@ -277,7 +281,10 @@ static bool performLLVM(IRGenOptions &Opts, DiagnosticEngine &Diags, } } - EmitPasses.run(*Module); + { + SharedTimer timer("LLVM output"); + EmitPasses.run(*Module); + } return false; } @@ -408,68 +415,71 @@ static std::unique_ptr performIRGeneration(IRGenOptions &Opts, initLLVMModule(IGM); - // Emit the module contents. - dispatcher.emitGlobalTopLevel(); + { + SharedTimer timer("IRGen"); + // Emit the module contents. + dispatcher.emitGlobalTopLevel(); - if (SF) { - IGM.emitSourceFile(*SF, StartElem); - } else { - assert(StartElem == 0 && "no explicit source file provided"); - for (auto *File : M->getFiles()) { - if (auto *nextSF = dyn_cast(File)) { - if (nextSF->ASTStage >= SourceFile::TypeChecked) - IGM.emitSourceFile(*nextSF, 0); - } else { - File->collectLinkLibraries([&IGM](LinkLibrary LinkLib) { - IGM.addLinkLibrary(LinkLib); - }); + if (SF) { + IGM.emitSourceFile(*SF, StartElem); + } else { + assert(StartElem == 0 && "no explicit source file provided"); + for (auto *File : M->getFiles()) { + if (auto *nextSF = dyn_cast(File)) { + if (nextSF->ASTStage >= SourceFile::TypeChecked) + IGM.emitSourceFile(*nextSF, 0); + } else { + File->collectLinkLibraries([&IGM](LinkLibrary LinkLib) { + IGM.addLinkLibrary(LinkLib); + }); + } } } - } - // Register our info with the runtime if needed. - if (Opts.UseJIT) { - IGM.emitRuntimeRegistration(); - } else { - // Emit protocol conformances into a section we can recognize at runtime. - // In JIT mode these are manually registered above. - IGM.emitProtocolConformances(); - } + // Register our info with the runtime if needed. + if (Opts.UseJIT) { + IGM.emitRuntimeRegistration(); + } else { + // Emit protocol conformances into a section we can recognize at runtime. + // In JIT mode these are manually registered above. + IGM.emitProtocolConformances(); + } - // Okay, emit any definitions that we suddenly need. - dispatcher.emitLazyDefinitions(); + // Okay, emit any definitions that we suddenly need. + dispatcher.emitLazyDefinitions(); - // Emit symbols for eliminated dead methods. - IGM.emitVTableStubs(); + // Emit symbols for eliminated dead methods. + IGM.emitVTableStubs(); - // Verify type layout if we were asked to. - if (!Opts.VerifyTypeLayoutNames.empty()) - IGM.emitTypeVerifier(); + // Verify type layout if we were asked to. + if (!Opts.VerifyTypeLayoutNames.empty()) + IGM.emitTypeVerifier(); - std::for_each(Opts.LinkLibraries.begin(), Opts.LinkLibraries.end(), - [&](LinkLibrary linkLib) { - IGM.addLinkLibrary(linkLib); - }); + std::for_each(Opts.LinkLibraries.begin(), Opts.LinkLibraries.end(), + [&](LinkLibrary linkLib) { + IGM.addLinkLibrary(linkLib); + }); - // Hack to handle thunks eagerly synthesized by the Clang importer. - swift::Module *prev = nullptr; - for (auto external : Ctx.ExternalDefinitions) { - swift::Module *next = external->getModuleContext(); - if (next == prev) - continue; - prev = next; + // Hack to handle thunks eagerly synthesized by the Clang importer. + swift::Module *prev = nullptr; + for (auto external : Ctx.ExternalDefinitions) { + swift::Module *next = external->getModuleContext(); + if (next == prev) + continue; + prev = next; - if (next->getName() == M->getName()) - continue; + if (next->getName() == M->getName()) + continue; - next->collectLinkLibraries([&](LinkLibrary linkLib) { - IGM.addLinkLibrary(linkLib); - }); - } + next->collectLinkLibraries([&](LinkLibrary linkLib) { + IGM.addLinkLibrary(linkLib); + }); + } - IGM.finalize(); + IGM.finalize(); - setModuleFlags(IGM); + setModuleFlags(IGM); + } // Bail out if there are any errors. if (Ctx.hadError()) return nullptr; @@ -655,7 +665,7 @@ static void performParallelIRGeneration(IRGenOptions &Opts, std::vector Threads; llvm::sys::Mutex DiagMutex; - // Start all the threads an do the LLVM compilation. + // Start all the threads and do the LLVM compilation. for (int ThreadIdx = 1; ThreadIdx < numThreads; ++ThreadIdx) { Threads.push_back(std::thread(ThreadEntryPoint, &dispatcher, &DiagMutex, ThreadIdx)); diff --git a/lib/IRGen/IRGen.h b/lib/IRGen/IRGen.h index 172fd54159703..14e74b4d66387 100644 --- a/lib/IRGen/IRGen.h +++ b/lib/IRGen/IRGen.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -73,6 +73,49 @@ inline IsBitwiseTakable_t &operator&=(IsBitwiseTakable_t &l, IsBitwiseTakable_t return (l = (l & r)); } +/// The kind of reference counting implementation a heap object uses. +enum class ReferenceCounting : unsigned char { + /// The object uses native Swift reference counting. + Native, + + /// The object uses ObjC reference counting. + /// + /// When ObjC interop is enabled, native Swift class objects are also ObjC + /// reference counting compatible. Swift non-class heap objects are never + /// ObjC reference counting compatible. + /// + /// Blocks are always ObjC reference counting compatible. + ObjC, + + /// The object uses _Block_copy/_Block_release reference counting. + /// + /// This is a strict subset of ObjC; all blocks are also ObjC reference + /// counting compatible. The block is assumed to have already been moved to + /// the heap so that _Block_copy returns the same object back. + Block, + + /// The object has an unknown reference counting implementation. + /// + /// This uses maximally-compatible reference counting entry points in the + /// runtime. + Unknown, + + /// Cases prior to this one are binary-compatible with Unknown reference + /// counting. + LastUnknownCompatible = Unknown, + + /// The object has an unknown reference counting implementation and + /// the reference value may contain extra bits that need to be masked. + /// + /// This uses maximally-compatible reference counting entry points in the + /// runtime, with a masking layer on top. A bit inside the pointer is used + /// to signal native Swift refcounting. + Bridge, + + /// The object uses ErrorType's reference counting entry points. + Error, +}; + /// Whether or not an object should be emitted on the heap. enum OnHeap_t : unsigned char { NotOnHeap, @@ -93,6 +136,13 @@ enum class ExtraData : unsigned char { Last_ExtraData = Block }; +/// Given that we have metadata for a type, is it for exactly the +/// specified type, or might it be a subtype? +enum IsExact_t : bool { + IsInexact = false, + IsExact = true +}; + /// ResilienceScope - The compiler is often able to pursue /// optimizations based on its knowledge of the implementation of some /// language structure. However, optimizations which affect diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 88e19d091acdc..f041be7c0b804 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -1,8 +1,8 @@ -//===--- IRGenDebugInfo.h - Debug Info Support-----------------------------===// +//===--- IRGenDebugInfo.cpp - Debug Info Support --------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -562,6 +562,7 @@ llvm::DIScope *IRGenDebugInfo::getOrCreateContext(DeclContext *DC) { case DeclContextKind::SerializedLocal: case DeclContextKind::Initializer: case DeclContextKind::ExtensionDecl: + case DeclContextKind::SubscriptDecl: return getOrCreateContext(DC->getParent()); case DeclContextKind::TopLevelCodeDecl: @@ -857,32 +858,12 @@ void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, (Alignment)CI.getTargetInfo().getPointerAlign(0)); emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, IGF.getDebugScope(), TName, 0, - // swift.type is a already pointer type, + // swift.type is already a pointer type, // having a shadow copy doesn't add another // layer of indirection. DirectValue, ArtificialValue); } -void IRGenDebugInfo::emitStackVariableDeclaration( - IRBuilder &B, ArrayRef Storage, DebugTypeInfo DbgTy, - const SILDebugScope *DS, StringRef Name, IndirectionKind Indirection) { - emitVariableDeclaration(B, Storage, DbgTy, DS, Name, 0, Indirection, - RealValue); -} - -void IRGenDebugInfo::emitArgVariableDeclaration( - IRBuilder &Builder, ArrayRef Storage, DebugTypeInfo DbgTy, - const SILDebugScope *DS, StringRef Name, unsigned ArgNo, - IndirectionKind Indirection, ArtificialKind IsArtificial) { - assert(ArgNo > 0); - if (Name == IGM.Context.Id_self.str()) - emitVariableDeclaration(Builder, Storage, DbgTy, DS, Name, ArgNo, - DirectValue, ArtificialValue); - else - emitVariableDeclaration(Builder, Storage, DbgTy, DS, Name, ArgNo, - Indirection, IsArtificial); -} - /// Return the DIFile that is the ancestor of Scope. llvm::DIFile *IRGenDebugInfo::getFile(llvm::DIScope *Scope) { while (!isa(Scope)) { @@ -985,6 +966,10 @@ void IRGenDebugInfo::emitVariableDeclaration( IRBuilder &Builder, ArrayRef Storage, DebugTypeInfo DbgTy, const SILDebugScope *DS, StringRef Name, unsigned ArgNo, IndirectionKind Indirection, ArtificialKind Artificial) { + // Self is always an artificial argument. + if (ArgNo > 0 && Name == IGM.Context.Id_self.str()) + Artificial = ArtificialValue; + // FIXME: Make this an assertion. // assert(DS && "variable has no scope"); if (!DS) @@ -1018,14 +1003,7 @@ void IRGenDebugInfo::emitVariableDeclaration( // Create the descriptor for the variable. llvm::DILocalVariable *Var = nullptr; - llvm::DIExpression *Expr = DBuilder.createExpression(); - if (Indirection) { - // Classes are always passed by reference. - int64_t Addr[] = { llvm::dwarf::DW_OP_deref }; - Expr = DBuilder.createExpression(Addr); - // FIXME: assert(Flags == 0 && "Complex variables cannot have flags"); - } /// This could be Opts.Optimize if we would also unique DIVariables here. bool Optimized = false; Var = (ArgNo > 0) @@ -1043,6 +1021,10 @@ void IRGenDebugInfo::emitVariableDeclaration( ElementSizes EltSizes(DITy, DIRefMap, IndirectEnumCases); auto Dim = EltSizes.getNext(); for (llvm::Value *Piece : Storage) { + SmallVector Operands; + if (Indirection) + Operands.push_back(llvm::dwarf::DW_OP_deref); + // There are variables without storage, such as "struct { func foo() {} }". // Emit them as constant 0. if (isa(Piece)) @@ -1057,7 +1039,7 @@ void IRGenDebugInfo::emitVariableDeclaration( if (!Dim.SizeInBits || (StorageSize && Dim.SizeInBits > StorageSize)) Dim.SizeInBits = StorageSize; - // FIXME: Occasionally we miss out that the Storage is acually a + // FIXME: Occasionally we miss out that the Storage is actually a // refcount wrapper. Silently skip these for now. if (OffsetInBits+Dim.SizeInBits > VarSizeInBits) break; @@ -1069,13 +1051,9 @@ void IRGenDebugInfo::emitVariableDeclaration( assert(Dim.SizeInBits < VarSizeInBits && "piece covers entire var"); assert(OffsetInBits+Dim.SizeInBits <= VarSizeInBits && "pars > totum"); - SmallVector Elts; - if (Indirection) - Elts.push_back(llvm::dwarf::DW_OP_deref); - Elts.push_back(llvm::dwarf::DW_OP_bit_piece); - Elts.push_back(OffsetInBits); - Elts.push_back(Dim.SizeInBits); - Expr = DBuilder.createExpression(Elts); + Operands.push_back(llvm::dwarf::DW_OP_bit_piece); + Operands.push_back(OffsetInBits); + Operands.push_back(Dim.SizeInBits); auto Size = Dim.SizeInBits; Dim = EltSizes.getNext(); @@ -1083,13 +1061,15 @@ void IRGenDebugInfo::emitVariableDeclaration( llvm::RoundUpToAlignment(Size, Dim.AlignInBits ? Dim.AlignInBits : SizeOfByte); } - emitDbgIntrinsic(BB, Piece, Var, Expr, Line, Loc.Col, Scope, DS); + emitDbgIntrinsic(BB, Piece, Var, DBuilder.createExpression(Operands), Line, + Loc.Col, Scope, DS); } // Emit locationless intrinsic for variables that were optimized away. if (Storage.size() == 0) { auto *undef = llvm::UndefValue::get(DbgTy.StorageType); - emitDbgIntrinsic(BB, undef, Var, Expr, Line, Loc.Col, Scope, DS); + emitDbgIntrinsic(BB, undef, Var, DBuilder.createExpression(), Line, Loc.Col, + Scope, DS); } } @@ -1112,7 +1092,7 @@ void IRGenDebugInfo::emitDbgIntrinsic(llvm::BasicBlock *BB, // A dbg.declare is only meaningful if there is a single alloca for // the variable that is live throughout the function. With SIL - // optimizations this is not guranteed and a variable can end up in + // optimizations this is not guaranteed and a variable can end up in // two allocas (for example, one function inlined twice). if (!Opts.Optimize && (isa(Storage) || @@ -1154,14 +1134,9 @@ StringRef IRGenDebugInfo::getMangledName(DebugTypeInfo DbgTy) { if (MetadataTypeDecl && DbgTy.getDecl() == MetadataTypeDecl) return BumpAllocatedString(DbgTy.getDecl()->getName().str()); - llvm::SmallString<160> Buffer; - { - llvm::raw_svector_ostream S(Buffer); - Mangle::Mangler M(S, /* DWARF */ true); - M.mangleTypeForDebugger(DbgTy.getType(), DbgTy.getDeclContext()); - } - assert(!Buffer.empty() && "mangled name came back empty"); - return BumpAllocatedString(Buffer); + Mangle::Mangler M(/* DWARF */ true); + M.mangleTypeForDebugger(DbgTy.getType(), DbgTy.getDeclContext()); + return BumpAllocatedString(M.finalize()); } /// Create a member of a struct, class, tuple, or enum. @@ -1826,7 +1801,7 @@ static bool canMangle(TypeBase *Ty) { switch (Ty->getKind()) { case TypeKind::PolymorphicFunction: // Mangler crashes. case TypeKind::GenericFunction: // Not yet supported. - case TypeKind::SILBlockStorage: // Not suported at all. + case TypeKind::SILBlockStorage: // Not supported at all. case TypeKind::SILBox: return false; case TypeKind::InOut: { diff --git a/lib/IRGen/IRGenDebugInfo.h b/lib/IRGen/IRGenDebugInfo.h index 1d88cf94d4997..177b85a6b21e9 100644 --- a/lib/IRGen/IRGenDebugInfo.h +++ b/lib/IRGen/IRGenDebugInfo.h @@ -1,8 +1,8 @@ -//===--- IRGenDebugInfo.h - Debug Info Support-------------------*- C++ -*-===// +//===--- IRGenDebugInfo.h - Debug Info Support ------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -100,7 +100,7 @@ class IRGenDebugInfo { Location LastDebugLoc; /// The last location that was emitted. const SILDebugScope *LastScope; /// The scope of that last location. - bool IsLibrary; /// Whether this is a libary or a top level module. + bool IsLibrary; /// Whether this is a library or a top level module. #ifndef NDEBUG /// The basic block where the location was last changed. llvm::BasicBlock *LastBasicBlock; @@ -192,7 +192,7 @@ class IRGenDebugInfo { void emitArtificialFunction(SILModule &SILMod, IRBuilder &Builder, llvm::Function *Fn, SILType SILTy = SILType()); - /// Emit a dbg.declare instrinsic at the current insertion point and + /// Emit a dbg.declare intrinsic at the current insertion point and /// the Builder's current debug location. void emitVariableDeclaration(IRBuilder &Builder, ArrayRef Storage, @@ -201,22 +201,6 @@ class IRGenDebugInfo { IndirectionKind = DirectValue, ArtificialKind = RealValue); - /// Convenience function for stack-allocated variables. Calls - /// emitVariableDeclaration internally. - void emitStackVariableDeclaration(IRBuilder &Builder, - ArrayRef Storage, - DebugTypeInfo Ty, const SILDebugScope *DS, - StringRef Name, - IndirectionKind Indirection = DirectValue); - - /// Convenience function for variables that are function arguments. - void emitArgVariableDeclaration(IRBuilder &Builder, - ArrayRef Storage, - DebugTypeInfo Ty, const SILDebugScope *DS, - StringRef Name, unsigned ArgNo, - IndirectionKind = DirectValue, - ArtificialKind = RealValue); - /// Emit a dbg.declare or dbg.value intrinsic, depending on Storage. void emitDbgIntrinsic(llvm::BasicBlock *BB, llvm::Value *Storage, llvm::DILocalVariable *Var, llvm::DIExpression *Expr, @@ -326,7 +310,7 @@ class AutoRestoreLocation { /// instructions (e.g., ARC-inserted calls to release()) that have no /// source location associated with them. The DWARF specification /// allows the compiler to use the special line number 0 to indicate -/// code that can not be attributed to any source location. +/// code that cannot be attributed to any source location. class ArtificialLocation : public AutoRestoreLocation { public: /// \brief Set the current location to line 0, but within scope DS. diff --git a/lib/IRGen/IRGenFunction.cpp b/lib/IRGen/IRGenFunction.cpp index e3a2b4dafaae2..d919764e3ef02 100644 --- a/lib/IRGen/IRGenFunction.cpp +++ b/lib/IRGen/IRGenFunction.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -52,8 +52,12 @@ IRGenFunction::IRGenFunction(IRGenModule &IGM, IRGenFunction::~IRGenFunction() { emitEpilogue(); + // Restore the debug location. if (IGM.DebugInfo) IGM.DebugInfo->popLoc(); + + // Tear down any side-table data structures. + if (LocalTypeData) destroyLocalTypeData(); } /// Call the llvm.memcpy intrinsic. The arguments need not already @@ -187,7 +191,7 @@ static void emitDeallocatingCall(IRGenFunction &IGF, llvm::Constant *fn, void IRGenFunction::emitDeallocRawCall(llvm::Value *pointer, llvm::Value *size, llvm::Value *alignMask) { - // For now, all we have is swift_slowDelloc. + // For now, all we have is swift_slowDealloc. return emitDeallocatingCall(*this, IGM.getSlowDeallocFn(), {pointer, size, alignMask}); } @@ -212,40 +216,6 @@ void IRGenFunction::emitFakeExplosion(const TypeInfo &type, } } -llvm::Value *IRGenFunction::lookupTypeDataMap(CanType type, LocalTypeData index, - const TypeDataMap &scopedMap) { - - // First try to lookup in the unscoped cache (= definitions in the entry block - // of the function). - auto key = getLocalTypeDataKey(type, index); - auto it = LocalTypeDataMap.find(key); - if (it != LocalTypeDataMap.end()) - return it->second; - - // Now try to lookup in the scoped cache. - auto it2 = scopedMap.find(key); - if (it2 == scopedMap.end()) - return nullptr; - - if (auto *I = dyn_cast(it2->second)) { - // This is a very very simple dominance check: either the definition is in the - // entry block or in the current block. - // TODO: do a better dominance check. - if (I->getParent() == &CurFn->getEntryBlock() || - I->getParent() == Builder.GetInsertBlock()) { - return I; - } - return nullptr; - } - - if (isa(it2->second)) { - return it2->second; - } - - // TODO: other kinds of value? - return nullptr; -} - void IRGenFunction::unimplemented(SourceLoc Loc, StringRef Message) { return IGM.unimplemented(Loc, Message); } diff --git a/lib/IRGen/IRGenFunction.h b/lib/IRGen/IRGenFunction.h index b40c176a6f36c..e5391ab0916fc 100644 --- a/lib/IRGen/IRGenFunction.h +++ b/lib/IRGen/IRGenFunction.h @@ -1,8 +1,8 @@ -//===--- IRGenFunction.h - IR Generation for Swift Functions ---*- C++ -*-===// +//===--- IRGenFunction.h - IR Generation for Swift Functions ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,7 +25,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/IR/CallingConv.h" #include "IRBuilder.h" - +#include "LocalTypeDataKind.h" +#include "DominancePoint.h" namespace llvm { class AllocaInst; @@ -60,53 +61,12 @@ namespace irgen { class HeapNonFixedOffsets; class IRGenModule; class LinkEntity; + class LocalTypeDataCache; class Scope; class TypeInfo; enum class ValueWitness : unsigned; enum class ReferenceCounting : unsigned char; -/// A nonce value for storing some sort of locally-known information about a type. -class LocalTypeData { - unsigned Value; - - explicit LocalTypeData(unsigned Value) : Value(Value) {} - - /// Magic values for special kinds of index. - enum : unsigned { - Metatype = ~0U, - ValueWitnessTable = ~1U, - - ValueWitnessBase = 0xFFFFFF00U, - }; - -public: - LocalTypeData() = default; - - // The magic values are all in the "negative" range and so do - // not collide with reasonable index values. - - /// A reference to the type metadata. - static LocalTypeData forMetatype() { return LocalTypeData(Metatype); } - /// A reference to the value witness table. - static LocalTypeData forValueWitnessTable() { - return LocalTypeData(ValueWitnessTable); - } - - /// A reference to a specific value witness. - static LocalTypeData forValueWitness(ValueWitness witness) { - return LocalTypeData((unsigned)witness + ValueWitnessBase); - } - - /// A reference to a protocol witness table for an archetype. - static LocalTypeData forArchetypeProtocolWitness(unsigned index) { - return LocalTypeData(index); - } - - unsigned getValue() const { - return Value; - } -}; - /// IRGenFunction - Primary class for emitting LLVM instructions for a /// specific function. class IRGenFunction { @@ -253,53 +213,120 @@ class IRGenFunction { llvm::Value *emitUnmanagedAlloc(const HeapLayout &layout, const llvm::Twine &name, const HeapNonFixedOffsets *offsets = 0); - void emitLoadAndRetain(Address addr, Explosion &explosion); - void emitAssignRetained(llvm::Value *value, Address addr); - void emitInitializeRetained(llvm::Value *value, Address addr); - void emitScalarRetainCall(llvm::Value *value, ReferenceCounting refcounting); - void emitScalarRelease(llvm::Value *value, ReferenceCounting refcounting); - void emitRetain(llvm::Value *value, Explosion &explosion); - void emitRetainCall(llvm::Value *value); - void emitRelease(llvm::Value *value); - void emitRetainUnowned(llvm::Value *value); - llvm::Value *emitTryPin(llvm::Value *object); - void emitUnpin(llvm::Value *handle); - void emitUnownedRetain(llvm::Value *value); - void emitUnownedRelease(llvm::Value *value); + + // Functions that don't care about the reference-counting style. void emitFixLifetime(llvm::Value *value); - void emitWeakInit(llvm::Value *value, Address dest); - void emitWeakAssign(llvm::Value *value, Address dest); - llvm::Value *emitWeakLoadStrong(Address src, llvm::Type *type); - llvm::Value *emitWeakTakeStrong(Address src, llvm::Type *type); - void emitWeakDestroy(Address addr); - void emitWeakCopyInit(Address destAddr, Address srcAddr); - void emitWeakTakeInit(Address destAddr, Address srcAddr); - void emitWeakCopyAssign(Address destAddr, Address srcAddr); - void emitWeakTakeAssign(Address destAddr, Address srcAddr); - void emitObjCRetain(llvm::Value *value, Explosion &explosion); + + // Routines that are generic over the reference-counting style: + // - strong references + void emitStrongRetain(llvm::Value *value, ReferenceCounting refcounting); + void emitStrongRelease(llvm::Value *value, ReferenceCounting refcounting); + llvm::Value *emitLoadRefcountedPtr(Address addr, ReferenceCounting style); + + // - unowned references + void emitUnownedRetain(llvm::Value *value, ReferenceCounting style); + void emitUnownedRelease(llvm::Value *value, ReferenceCounting style); + void emitStrongRetainUnowned(llvm::Value *value, ReferenceCounting style); + void emitStrongRetainAndUnownedRelease(llvm::Value *value, + ReferenceCounting style); + void emitUnownedInit(llvm::Value *val, Address dest, ReferenceCounting style); + void emitUnownedAssign(llvm::Value *value, Address dest, + ReferenceCounting style); + void emitUnownedCopyInit(Address destAddr, Address srcAddr, + ReferenceCounting style); + void emitUnownedTakeInit(Address destAddr, Address srcAddr, + ReferenceCounting style); + void emitUnownedCopyAssign(Address destAddr, Address srcAddr, + ReferenceCounting style); + void emitUnownedTakeAssign(Address destAddr, Address srcAddr, + ReferenceCounting style); + llvm::Value *emitUnownedLoadStrong(Address src, llvm::Type *resultType, + ReferenceCounting style); + llvm::Value *emitUnownedTakeStrong(Address src, llvm::Type *resultType, + ReferenceCounting style); + void emitUnownedDestroy(Address addr, ReferenceCounting style); + llvm::Value *getUnownedExtraInhabitantIndex(Address src, + ReferenceCounting style); + void storeUnownedExtraInhabitant(llvm::Value *index, Address dest, + ReferenceCounting style); + + // - weak references + void emitWeakInit(llvm::Value *ref, Address dest, ReferenceCounting style); + void emitWeakAssign(llvm::Value *ref, Address dest, ReferenceCounting style); + void emitWeakCopyInit(Address destAddr, Address srcAddr, + ReferenceCounting style); + void emitWeakTakeInit(Address destAddr, Address srcAddr, + ReferenceCounting style); + void emitWeakCopyAssign(Address destAddr, Address srcAddr, + ReferenceCounting style); + void emitWeakTakeAssign(Address destAddr, Address srcAddr, + ReferenceCounting style); + llvm::Value *emitWeakLoadStrong(Address src, llvm::Type *resultType, + ReferenceCounting style); + llvm::Value *emitWeakTakeStrong(Address src, llvm::Type *resultType, + ReferenceCounting style); + void emitWeakDestroy(Address addr, ReferenceCounting style); + + // Routines for the Swift native reference-counting style. + // - strong references + void emitNativeStrongAssign(llvm::Value *value, Address addr); + void emitNativeStrongInit(llvm::Value *value, Address addr); + void emitNativeStrongRetain(llvm::Value *value); + void emitNativeStrongRelease(llvm::Value *value); + // - unowned references + void emitNativeUnownedRetain(llvm::Value *value); + void emitNativeUnownedRelease(llvm::Value *value); + void emitNativeStrongRetainUnowned(llvm::Value *value); + void emitNativeStrongRetainAndUnownedRelease(llvm::Value *value); + void emitNativeUnownedInit(llvm::Value *val, Address dest); + void emitNativeUnownedAssign(llvm::Value *value, Address dest); + void emitNativeUnownedCopyInit(Address destAddr, Address srcAddr); + void emitNativeUnownedTakeInit(Address destAddr, Address srcAddr); + void emitNativeUnownedCopyAssign(Address destAddr, Address srcAddr); + void emitNativeUnownedTakeAssign(Address destAddr, Address srcAddr); + llvm::Value *emitNativeUnownedLoadStrong(Address src, llvm::Type *resultType); + llvm::Value *emitNativeUnownedTakeStrong(Address src, llvm::Type *resultType); + void emitNativeUnownedDestroy(Address addr); + + // - weak references + void emitNativeWeakInit(llvm::Value *value, Address dest); + void emitNativeWeakAssign(llvm::Value *value, Address dest); + llvm::Value *emitNativeWeakLoadStrong(Address src, llvm::Type *type); + llvm::Value *emitNativeWeakTakeStrong(Address src, llvm::Type *type); + void emitNativeWeakDestroy(Address addr); + void emitNativeWeakCopyInit(Address destAddr, Address srcAddr); + void emitNativeWeakTakeInit(Address destAddr, Address srcAddr); + void emitNativeWeakCopyAssign(Address destAddr, Address srcAddr); + void emitNativeWeakTakeAssign(Address destAddr, Address srcAddr); + // - other operations + llvm::Value *emitNativeTryPin(llvm::Value *object); + void emitNativeUnpin(llvm::Value *handle); + + // Routines for the ObjC reference-counting style. + void emitObjCStrongRetain(llvm::Value *value); llvm::Value *emitObjCRetainCall(llvm::Value *value); llvm::Value *emitObjCAutoreleaseCall(llvm::Value *value); - void emitObjCRelease(llvm::Value *value); + void emitObjCStrongRelease(llvm::Value *value); + llvm::Value *emitBlockCopyCall(llvm::Value *value); void emitBlockRelease(llvm::Value *value); - /// Emit a retain of a class instance with unknown retain semantics, and - /// return the retained value. - llvm::Value *emitUnknownRetainCall(llvm::Value *value); - /// Emit a release of a class instance with unknown retain semantics. - void emitUnknownRelease(llvm::Value *value); - void emitUnknownUnownedRetain(llvm::Value *value); - void emitUnknownUnownedRelease(llvm::Value *value); - void emitUnknownRetainUnowned(llvm::Value *value); - /// Emit a retain of a class instance with bridge retain semantics, and - /// return the retained value. - llvm::Value *emitBridgeRetainCall(llvm::Value *value); - /// Emit a release of a class instance with bridge retain semantics. - void emitBridgeRelease(llvm::Value *value); - void emitBridgeRetainUnowned(llvm::Value *value); - void emitErrorRetain(llvm::Value *value); - llvm::Value *emitErrorRetainCall(llvm::Value *value); - void emitErrorRelease(llvm::Value *value); + // Routines for an unknown reference-counting style (meaning, + // dynamically something compatible with either the ObjC or Swift styles). + // - strong references + void emitUnknownStrongRetain(llvm::Value *value); + void emitUnknownStrongRelease(llvm::Value *value); + // - unowned references + void emitUnknownUnownedInit(llvm::Value *val, Address dest); + void emitUnknownUnownedAssign(llvm::Value *value, Address dest); + void emitUnknownUnownedCopyInit(Address destAddr, Address srcAddr); + void emitUnknownUnownedTakeInit(Address destAddr, Address srcAddr); + void emitUnknownUnownedCopyAssign(Address destAddr, Address srcAddr); + void emitUnknownUnownedTakeAssign(Address destAddr, Address srcAddr); + llvm::Value *emitUnknownUnownedLoadStrong(Address src, llvm::Type *resultTy); + llvm::Value *emitUnknownUnownedTakeStrong(Address src, llvm::Type *resultTy); + void emitUnknownUnownedDestroy(Address addr); + // - weak references void emitUnknownWeakDestroy(Address addr); void emitUnknownWeakCopyInit(Address destAddr, Address srcAddr); void emitUnknownWeakTakeInit(Address destAddr, Address srcAddr); @@ -309,9 +336,15 @@ class IRGenFunction { void emitUnknownWeakAssign(llvm::Value *value, Address dest); llvm::Value *emitUnknownWeakLoadStrong(Address src, llvm::Type *type); llvm::Value *emitUnknownWeakTakeStrong(Address src, llvm::Type *type); - llvm::Value *emitLoadNativeRefcountedPtr(Address addr); - llvm::Value *emitLoadUnknownRefcountedPtr(Address addr); - llvm::Value *emitLoadBridgeRefcountedPtr(Address addr); + + // Routines for the Builtin.NativeObject reference-counting style. + void emitBridgeStrongRetain(llvm::Value *value); + void emitBridgeStrongRelease(llvm::Value *value); + + // Routines for the ErrorType reference-counting style. + void emitErrorStrongRetain(llvm::Value *value); + void emitErrorStrongRelease(llvm::Value *value); + llvm::Value *emitIsUniqueCall(llvm::Value *value, SourceLoc loc, bool isNonNull, bool checkPinned); @@ -331,54 +364,132 @@ class IRGenFunction { /// Look for a mapping for a local type-metadata reference. /// The lookup is done for the current block which is the Builder's /// insert-block. - llvm::Value *tryGetLocalTypeData(CanType type, LocalTypeData index) { - return lookupTypeDataMap(type, index, ScopedTypeDataMap); - } + llvm::Value *tryGetLocalTypeData(CanType type, LocalTypeDataKind kind); + + /// Retrieve a local type-metadata reference which is known to exist. + llvm::Value *getLocalTypeData(CanType type, LocalTypeDataKind kind); + + /// Add a local type-metadata reference at a point which definitely + /// dominates all of its uses. + void setUnscopedLocalTypeData(CanType type, LocalTypeDataKind kind, + llvm::Value *data); + + /// Add a local type-metadata reference, valid at the current insertion + /// point. + void setScopedLocalTypeData(CanType type, LocalTypeDataKind kind, + llvm::Value *data); /// The same as tryGetLocalTypeData, just for the Layout metadata. - llvm::Value *tryGetLocalTypeDataForLayout(SILType type, LocalTypeData index) { - return lookupTypeDataMap(type.getSwiftRValueType(), index, - ScopedTypeDataMapForLayout); + /// + /// We use a separate function name for this to clarify that you should + /// only ever be looking type metadata for a lowered SILType for the + /// purposes of local layout (e.g. of a tuple). + llvm::Value *tryGetLocalTypeDataForLayout(SILType type, + LocalTypeDataKind kind) { + return tryGetLocalTypeData(type.getSwiftRValueType(), kind); } - /// Retrieve a local type-metadata reference which is known to exist. - llvm::Value *getLocalTypeData(CanType type, LocalTypeData index) { - auto key = getLocalTypeDataKey(type, index); - assert(LocalTypeDataMap.count(key) && "no mapping for local type data"); - return LocalTypeDataMap.find(key)->second; + /// Add a local type-metadata reference, which is valid for the containing + /// block. + void setScopedLocalTypeDataForLayout(SILType type, LocalTypeDataKind kind, + llvm::Value *data) { + setScopedLocalTypeData(type.getSwiftRValueType(), kind, data); } - /// Add a local type-metadata reference at a point which dominates - /// the entire function. - void setUnscopedLocalTypeData(CanType type, LocalTypeData index, - llvm::Value *data) { - assert(data && "setting a null value for type data!"); + /// Given a concrete type metadata node, add all the local type data + /// that we can reach from it. + void addLocalTypeDataForTypeMetadata(CanType type, IsExact_t isExact, + llvm::Value *metadata); - auto key = getLocalTypeDataKey(type, index); - assert(!LocalTypeDataMap.count(key) && - "existing mapping for local type data"); - LocalTypeDataMap.insert({key, data}); + void setDominanceResolver(DominanceResolverFunction resolver) { + assert(DominanceResolver == nullptr); + DominanceResolver = resolver; } - - /// Add a local type-metadata reference, which is valid for the containing - /// block. - void setScopedLocalTypeData(CanType type, LocalTypeData index, - llvm::Value *data) { - assert(_isValidScopedLocalTypeData(data) && - "metadata instruction not inserted into the Builder's insert-block"); - ScopedTypeDataMap[getLocalTypeDataKey(type, index)] = data; + + bool isActiveDominancePointDominatedBy(DominancePoint point) { + // If the point is universal, it dominates. + if (point.isUniversal()) return true; + + assert(!ActiveDominancePoint.isUniversal() && + "active dominance point is universal but there exists a" + "non-universal point?"); + + // If we don't have a resolver, we're emitting a simple helper + // function; just assume dominance. + if (!DominanceResolver) return true; + + // Otherwise, ask the resolver. + return DominanceResolver(*this, ActiveDominancePoint, point); } - /// Add a local type-metadata reference, which is valid for the containing - /// block. - void setScopedLocalTypeDataForLayout(SILType type, LocalTypeData index, - llvm::Value *data) { - assert(_isValidScopedLocalTypeData(data) && - "metadata instruction not inserted into the Builder's insert-block"); - ScopedTypeDataMapForLayout[ - getLocalTypeDataKey(type.getSwiftRValueType(), index)] = data; + /// Is the current dominance point conditional in some way not + /// tracked by the active dominance point? + /// + /// This should only be used by the local type data cache code. + bool isConditionalDominancePoint() const { + return ConditionalDominance != nullptr; + } + + void registerConditionalLocalTypeDataKey(LocalTypeDataKey key) { + assert(ConditionalDominance != nullptr && + "not in a conditional dominance scope"); + ConditionalDominance->registerConditionalLocalTypeDataKey(key); } + /// Return the currently-active dominance point. + DominancePoint getActiveDominancePoint() const { + return ActiveDominancePoint; + } + + /// A RAII object for temporarily changing the dominance of the active + /// definition point. + class DominanceScope { + IRGenFunction &IGF; + DominancePoint OldDominancePoint; + public: + explicit DominanceScope(IRGenFunction &IGF, DominancePoint newPoint) + : IGF(IGF), OldDominancePoint(IGF.ActiveDominancePoint) { + IGF.ActiveDominancePoint = newPoint; + assert(!newPoint.isOrdinary() || IGF.DominanceResolver); + } + + DominanceScope(const DominanceScope &other) = delete; + DominanceScope &operator=(const DominanceScope &other) = delete; + + ~DominanceScope() { + IGF.ActiveDominancePoint = OldDominancePoint; + } + }; + + /// A RAII object for temporarily suppressing type-data caching at the + /// active definition point. Do this if you're adding local control flow + /// that isn't modeled by the dominance system. + class ConditionalDominanceScope { + IRGenFunction &IGF; + ConditionalDominanceScope *OldScope; + SmallVector RegisteredKeys; + public: + explicit ConditionalDominanceScope(IRGenFunction &IGF) + : IGF(IGF), OldScope(IGF.ConditionalDominance) { + IGF.ConditionalDominance = this; + } + + ConditionalDominanceScope(const ConditionalDominanceScope &other) = delete; + ConditionalDominanceScope &operator=(const ConditionalDominanceScope &other) + = delete; + + void registerConditionalLocalTypeDataKey(LocalTypeDataKey key) { + RegisteredKeys.push_back(key); + } + + ~ConditionalDominanceScope() { + IGF.ConditionalDominance = OldScope; + if (!RegisteredKeys.empty()) { + IGF.unregisterConditionalLocalTypeDataKeys(RegisteredKeys); + } + } + }; + /// The kind of value LocalSelf is. enum LocalSelfKind { /// An object reference. @@ -393,35 +504,17 @@ class IRGenFunction { void setLocalSelfMetadata(llvm::Value *value, LocalSelfKind kind); private: -#ifndef NDEBUG - bool _isValidScopedLocalTypeData(llvm::Value *v) { - // Constants are valid anywhere. - if (isa(v)) - return true; - // Instructions are valid only in the current insert block. - if (auto inst = dyn_cast(v)) - return inst->getParent() == Builder.GetInsertBlock(); - // TODO: Other kinds of value? - return false; - } -#endif - - typedef unsigned LocalTypeDataDepth; - typedef std::pair LocalTypeDataPair; - LocalTypeDataPair getLocalTypeDataKey(CanType type, LocalTypeData index) { - return LocalTypeDataPair(type.getPointer(), index.getValue()); - } - - typedef llvm::DenseMap TypeDataMap; + LocalTypeDataCache &getOrCreateLocalTypeData(); + void destroyLocalTypeData(); + void unregisterConditionalLocalTypeDataKeys(ArrayRef keys); - llvm::Value *lookupTypeDataMap(CanType type, LocalTypeData index, - const TypeDataMap &scopedMap); + LocalTypeDataCache *LocalTypeData = nullptr; - TypeDataMap LocalTypeDataMap; - - TypeDataMap ScopedTypeDataMap; - - TypeDataMap ScopedTypeDataMapForLayout; + /// The dominance resolver. This can be set at most once; when it's not + /// set, this emission must never have a non-null active definition point. + DominanceResolverFunction DominanceResolver = nullptr; + DominancePoint ActiveDominancePoint = DominancePoint::universal(); + ConditionalDominanceScope *ConditionalDominance = nullptr; /// The value that satisfies metadata lookups for dynamic Self. llvm::Value *LocalSelf = nullptr; @@ -429,6 +522,8 @@ class IRGenFunction { LocalSelfKind SelfKind; }; +using ConditionalDominanceScope = IRGenFunction::ConditionalDominanceScope; + } // end namespace irgen } // end namespace swift diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 6a9f8ccd1add9..4286167b3db95 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -159,6 +159,10 @@ IRGenModule::IRGenModule(IRGenModuleDispatcher &dispatcher, SourceFile *SF, WeakReferencePtrTy = createStructPointerType(*this, "swift.weak", { RefCountedPtrTy }); + // Native unowned references are just a pointer. + UnownedReferencePtrTy = + createStructPointerType(*this, "swift.unowned", { RefCountedPtrTy }); + // A type metadata record is the structure pointed to by the canonical // address point of a type metadata. This is at least one word, and // potentially more than that, past the start of the actual global @@ -621,19 +625,6 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) { } } -// FIXME: This should just be the implementation of -// llvm::array_pod_sort_comparator. The only difference is that it uses -// std::less instead of operator<. -template -static int pointerPODSortComparator(T * const *lhs, T * const *rhs) { - std::less lt; - if (lt(*lhs, *rhs)) - return -1; - if (lt(*rhs, *lhs)) - return -1; - return 0; -} - static bool replaceModuleFlagsEntry(llvm::LLVMContext &Ctx, llvm::Module &Module, StringRef EntryName, llvm::Module::ModFlagBehavior Behavior, diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index 5e4680a7698a1..e86ef2055617c 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -204,7 +204,7 @@ class IRGenModuleDispatcher { /// Emit the protocol conformance records needed by each IR module. void emitProtocolConformances(); - /// Emit everthing which is reachable from already emitted IR. + /// Emit everything which is reachable from already emitted IR. void emitLazyDefinitions(); void addLazyFunction(SILFunction *f) { @@ -351,6 +351,7 @@ class IRGenModule { llvm::StructType *RefCountedStructTy;/// %swift.refcounted = type { ... } llvm::PointerType *RefCountedPtrTy; /// %swift.refcounted* llvm::PointerType *WeakReferencePtrTy;/// %swift.weak_reference* + llvm::PointerType *UnownedReferencePtrTy;/// %swift.unowned_reference* llvm::Constant *RefCountedNull; /// %swift.refcounted* null llvm::StructType *FunctionPairTy; /// { i8*, %swift.refcounted* } llvm::FunctionType *DeallocatingDtorTy; /// void (%swift.refcounted*) @@ -384,13 +385,17 @@ class IRGenModule { llvm::PointerType *ErrorPtrTy; /// %swift.error* llvm::StructType *OpenedErrorTripleTy; /// { %swift.opaque*, %swift.type*, i8** } llvm::PointerType *OpenedErrorTriplePtrTy; /// { %swift.opaque*, %swift.type*, i8** }* - + unsigned InvariantMetadataID; /// !invariant.load unsigned DereferenceableID; /// !dereferenceable llvm::MDNode *InvariantNode; llvm::CallingConv::ID RuntimeCC; /// lightweight calling convention + llvm::FunctionType *getAssociatedTypeMetadataAccessFunctionTy(); + llvm::FunctionType *getAssociatedTypeWitnessTableAccessFunctionTy(); + llvm::StructType *getGenericWitnessTableCacheTy(); + /// Get the bit width of an integer type for the target platform. unsigned getBuiltinIntegerWidth(BuiltinIntegerType *t); unsigned getBuiltinIntegerWidth(BuiltinIntegerWidth w); @@ -407,22 +412,48 @@ class IRGenModule { return getPointerAlignment(); } - llvm::Type *getReferenceType(ReferenceCounting refcounting); + llvm::Type *getReferenceType(ReferenceCounting style); + + static bool isUnownedReferenceAddressOnly(ReferenceCounting style) { + switch (style) { + case ReferenceCounting::Native: + return false; + + case ReferenceCounting::Unknown: + case ReferenceCounting::ObjC: + case ReferenceCounting::Block: + return true; + + case ReferenceCounting::Bridge: + case ReferenceCounting::Error: + llvm_unreachable("unowned references to this type are not supported"); + } + } /// Return the spare bit mask to use for types that comprise heap object /// pointers. const SpareBitVector &getHeapObjectSpareBits() const; const SpareBitVector &getFunctionPointerSpareBits() const; - SpareBitVector getWeakReferenceSpareBits() const; const SpareBitVector &getWitnessTablePtrSpareBits() const; + SpareBitVector getWeakReferenceSpareBits() const; Size getWeakReferenceSize() const { return PtrSize; } Alignment getWeakReferenceAlignment() const { return getPointerAlignment(); } + SpareBitVector getUnownedReferenceSpareBits(ReferenceCounting style) const; + unsigned getUnownedExtraInhabitantCount(ReferenceCounting style); + APInt getUnownedExtraInhabitantValue(unsigned bits, unsigned index, + ReferenceCounting syle); + APInt getUnownedExtraInhabitantMask(ReferenceCounting style); + llvm::Type *getFixedBufferTy(); llvm::Type *getValueWitnessTy(ValueWitness index); + llvm::Constant *emitDirectRelativeReference(llvm::Constant *target, + llvm::Constant *base, + ArrayRef baseIndices); + void unimplemented(SourceLoc, StringRef Message); LLVM_ATTRIBUTE_NORETURN void fatal_unimplemented(SourceLoc, StringRef Message); @@ -433,6 +464,9 @@ class IRGenModule { llvm::Type *FixedBufferTy; /// [N x i8], where N == 3 * sizeof(void*) llvm::Type *ValueWitnessTys[MaxNumValueWitnesses]; + llvm::FunctionType *AssociatedTypeMetadataAccessFunctionTy = nullptr; + llvm::FunctionType *AssociatedTypeWitnessTableAccessFunctionTy = nullptr; + llvm::StructType *GenericWitnessTableCacheTy = nullptr; llvm::DenseMap SpareBitsForTypes; @@ -481,6 +515,8 @@ class IRGenModule { } bool isResilient(Decl *decl, ResilienceScope scope); + ResilienceScope getResilienceScopeForAccess(NominalTypeDecl *decl); + ResilienceScope getResilienceScopeForLayout(NominalTypeDecl *decl); SpareBitVector getSpareBitsForType(llvm::Type *scalarTy, Size size); @@ -617,11 +653,14 @@ public: \ private: \ llvm::Constant *Id##Fn = nullptr; #include "RuntimeFunctions.def" + + llvm::Constant *FixLifetimeFn = nullptr; mutable Optional HeapPointerSpareBits; //--- Generic --------------------------------------------------------------- public: + llvm::Constant *getFixLifetimeFn(); /// The constructor. /// @@ -725,6 +764,20 @@ private: \ ForDefinition_t forDefinition); llvm::Constant *getAddrOfWitnessTable(const NormalProtocolConformance *C, llvm::Type *definitionTy = nullptr); + llvm::Constant * + getAddrOfGenericWitnessTableCache(const NormalProtocolConformance *C, + ForDefinition_t forDefinition); + llvm::Function * + getAddrOfGenericWitnessTableInstantiationFunction( + const NormalProtocolConformance *C); + llvm::Function *getAddrOfAssociatedTypeMetadataAccessFunction( + const NormalProtocolConformance *C, + AssociatedTypeDecl *associatedType); + llvm::Function *getAddrOfAssociatedTypeWitnessTableAccessFunction( + const NormalProtocolConformance *C, + AssociatedTypeDecl *associatedType, + ProtocolDecl *requiredProtocol); + Address getAddrOfObjCISAMask(); StringRef mangleType(CanType type, SmallVectorImpl &buffer); diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 3a3203a457adf..6d74f3aa2f63e 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -31,7 +31,9 @@ #include "swift/AST/ASTContext.h" #include "swift/AST/IRGenOptions.h" #include "swift/AST/Pattern.h" +#include "swift/AST/ParameterList.h" #include "swift/AST/Types.h" +#include "swift/SIL/Dominance.h" #include "swift/SIL/PrettyStackTrace.h" #include "swift/SIL/SILDebugScope.h" #include "swift/SIL/SILDeclRef.h" @@ -122,12 +124,15 @@ class LoweredValue { public: enum class Kind { /// This LoweredValue corresponds to a SIL address value. + /// The LoweredValue of an alloc_stack keeps an owning container in + /// addition to the address of the allocated buffer. + /// Depending on the allocated type, the container may be equal to the + /// buffer itself (for types with known sizes) or it may be the address + /// of a fixed-size container which points to the heap-allocated buffer. + /// In this case the address-part may be null, which means that the buffer + /// is not allocated yet. Address, - /// This LoweredValue corresponds to a SIL address value owned by an - /// uninitialized fixed-size buffer. - UnallocatedAddressInBuffer, - /// The following kinds correspond to SIL non-address values. Value_First, /// A normal value, represented as an exploded array of llvm Values. @@ -149,7 +154,7 @@ class LoweredValue { using ExplosionVector = SmallVector; union { - Address address; + ContainedAddress address; struct { ExplosionVector values; } explosion; @@ -158,14 +163,24 @@ class LoweredValue { }; public: + + /// Create an address value without a container (the usual case). LoweredValue(const Address &address) - : kind(Kind::Address), address(address) + : kind(Kind::Address), address(Address(), address) {} - enum UnallocatedAddressInBuffer_t { UnallocatedAddressInBuffer }; + enum ContainerForUnallocatedAddress_t { ContainerForUnallocatedAddress }; + + /// Create an address value for an alloc_stack, consisting of a container and + /// a not yet allocated buffer. + LoweredValue(const Address &container, ContainerForUnallocatedAddress_t) + : kind(Kind::Address), address(container, Address()) + {} - LoweredValue(const Address &address, UnallocatedAddressInBuffer_t) - : kind(Kind::UnallocatedAddressInBuffer), address(address) + /// Create an address value for an alloc_stack, consisting of a container and + /// the address of the allocated buffer. + LoweredValue(const ContainedAddress &address) + : kind(Kind::Address), address(address) {} LoweredValue(StaticFunction &&staticFunction) @@ -187,8 +202,7 @@ class LoweredValue { { switch (kind) { case Kind::Address: - case Kind::UnallocatedAddressInBuffer: - ::new (&address) Address(std::move(lv.address)); + ::new (&address) ContainedAddress(std::move(lv.address)); break; case Kind::Explosion: ::new (&explosion.values) ExplosionVector(std::move(lv.explosion.values)); @@ -210,23 +224,24 @@ class LoweredValue { } bool isAddress() const { - return kind == Kind::Address; + return kind == Kind::Address && address.getAddress().isValid(); } bool isUnallocatedAddressInBuffer() const { - return kind == Kind::UnallocatedAddressInBuffer; + return kind == Kind::Address && !address.getAddress().isValid(); } bool isValue() const { return kind >= Kind::Value_First && kind <= Kind::Value_Last; } Address getAddress() const { - assert(kind == Kind::Address && "not an allocated address"); - return address; + assert(isAddress() && "not an allocated address"); + return address.getAddress(); } - Address getAddressOfUnallocatedBuffer() const { - assert(kind == Kind::UnallocatedAddressInBuffer); - return address; + Address getContainerOfAddress() const { + assert(kind == Kind::Address); + assert(address.getContainer().isValid() && "address has no container"); + return address.getContainer(); } void getExplosion(IRGenFunction &IGF, Explosion &ex) const; @@ -252,8 +267,7 @@ class LoweredValue { ~LoweredValue() { switch (kind) { case Kind::Address: - case Kind::UnallocatedAddressInBuffer: - address.~Address(); + address.~ContainedAddress(); break; case Kind::Explosion: explosion.values.~ExplosionVector(); @@ -292,6 +306,11 @@ class IRGenSILFunction : /// All alloc_ref instructions which allocate the object on the stack. llvm::SmallPtrSet StackAllocs; + /// Keeps track of the mapping of source variables to -O0 shadow copy allocas. + llvm::SmallDenseMap, Address, 8> + ShadowStackSlots; + llvm::SmallDenseMap, 8> AnonymousVariables; + unsigned NumAnonVars = 0; /// Accumulative amount of allocated bytes on the stack. Used to limit the /// size for stack promoted objects. @@ -306,6 +325,9 @@ class IRGenSILFunction : SILFunction *CurSILFn; Address IndirectReturn; + + // A cached dominance analysis. + std::unique_ptr Dominance; IRGenSILFunction(IRGenModule &IGM, SILFunction *f); ~IRGenSILFunction(); @@ -330,23 +352,29 @@ class IRGenSILFunction : /// Create a new Address corresponding to the given SIL address value. void setLoweredAddress(SILValue v, const Address &address) { - assert((v.getType().isAddress() || v.getType().isLocalStorage()) && - "address for non-address value?!"); + assert(v.getType().isAddress() && "address for non-address value?!"); setLoweredValue(v, address); } - void setLoweredUnallocatedAddressInBuffer(SILValue v, - const Address &buffer) { - assert((v.getType().isAddress() || v.getType().isLocalStorage()) && - "address for non-address value?!"); + void setLoweredContainedAddress(SILValue v, const ContainedAddress &address) { + assert(v.getType().isAddress() && "address for non-address value?!"); + setLoweredValue(v, address); + } + + void setContainerOfUnallocatedAddress(SILValue v, + const Address &buffer) { + assert(v.getType().isAddress() && "address for non-address value?!"); setLoweredValue(v, - LoweredValue(buffer, LoweredValue::UnallocatedAddressInBuffer)); + LoweredValue(buffer, LoweredValue::ContainerForUnallocatedAddress)); } - void overwriteLoweredAddress(SILValue v, const Address &address) { - assert((v.getType().isAddress() || v.getType().isLocalStorage()) && - "address for non-address value?!"); - overwriteLoweredValue(v, address); + void overwriteAllocatedAddress(SILValue v, const Address &address) { + assert(v.getType().isAddress() && "address for non-address value?!"); + auto it = LoweredValues.find(v); + assert(it != LoweredValues.end() && "no existing entry for overwrite?"); + assert(it->second.isUnallocatedAddressInBuffer() && + "not an unallocated address"); + it->second = ContainedAddress(it->second.getContainerOfAddress(), address); } void setAllocatedAddressForBuffer(SILValue v, const Address &allocedAddress); @@ -413,8 +441,7 @@ class IRGenSILFunction : auto &ti = getTypeInfo(t); switch (t.getCategory()) { - case SILValueCategory::Address: - case SILValueCategory::LocalStorage: { + case SILValueCategory::Address: { Address undefAddr = ti.getAddressForPointer( llvm::UndefValue::get(ti.getStorageType()->getPointerTo())); LoweredUndefs.insert({t, LoweredValue(undefAddr)}); @@ -456,6 +483,9 @@ class IRGenSILFunction : Address getLoweredAddress(SILValue v) { return getLoweredValue(v).getAddress(); } + Address getLoweredContainerOfAddress(SILValue v) { + return getLoweredValue(v).getContainerOfAddress(); + } /// Add the unmanaged LLVM values lowered from a SIL value to an explosion. void getLoweredExplosion(SILValue v, Explosion &e) { getLoweredValue(v).getExplosion(*this, e); @@ -478,11 +508,35 @@ class IRGenSILFunction : return foundBB->second; } + StringRef getOrCreateAnonymousVarName(VarDecl *Decl) { + llvm::SmallString<4> &Name = AnonymousVariables[Decl]; + if (Name.empty()) { + { + llvm::raw_svector_ostream S(Name); + S << '_' << NumAnonVars++; + } + AnonymousVariables.insert({Decl, Name}); + } + return Name; + } + + template + StringRef getVarName(DebugVarCarryingInst *i) { + StringRef Name = i->getVarInfo().Name; + // The $match variables generated by the type checker are not + // guaranteed to be unique within their scope, but they have + // unique VarDecls. + if ((Name.empty() || Name == "$match") && i->getDecl()) + return getOrCreateAnonymousVarName(i->getDecl()); + return Name; + } + /// At -O0, emit a shadow copy of an Address in an alloca, so the /// register allocator doesn't elide the dbg.value intrinsic when /// register pressure is high. There is a trade-off to this: With /// shadow copies, we lose the precise lifetime. llvm::Value *emitShadowCopy(llvm::Value *Storage, + const SILDebugScope *Scope, StringRef Name, Alignment Align = Alignment(0)) { auto Ty = Storage->getType(); @@ -495,16 +549,21 @@ class IRGenSILFunction : if (Align.isZero()) Align = IGM.getPointerAlignment(); - auto Alloca = createAlloca(Ty, Align, Name+".addr"); + auto &Alloca = ShadowStackSlots[{Scope, Name}]; + if (!Alloca.isValid()) + Alloca = createAlloca(Ty, Align, Name+".addr"); Builder.CreateStore(Storage, Alloca.getAddress(), Align); return Alloca.getAddress(); } - llvm::Value *emitShadowCopy(Address storage, StringRef name) { - return emitShadowCopy(storage.getAddress(), name, storage.getAlignment()); + llvm::Value *emitShadowCopy(Address Storage, const SILDebugScope *Scope, + StringRef Name) { + return emitShadowCopy(Storage.getAddress(), Scope, Name, + Storage.getAlignment()); } - void emitShadowCopy(ArrayRef vals, StringRef name, + void emitShadowCopy(ArrayRef vals, const SILDebugScope *scope, + StringRef name, llvm::SmallVectorImpl ©) { // Only do this at -O0. if (IGM.Opts.Optimize) { @@ -515,7 +574,7 @@ class IRGenSILFunction : // Single or empty values. if (vals.size() <= 1) { for (auto val : vals) - copy.push_back(emitShadowCopy(val, name)); + copy.push_back(emitShadowCopy(val, scope, name)); return; } @@ -553,11 +612,11 @@ class IRGenSILFunction : assert(IGM.DebugInfo && "debug info not enabled"); if (ArgNo) { PrologueLocation AutoRestore(IGM.DebugInfo, Builder); - IGM.DebugInfo->emitArgVariableDeclaration(Builder, Storage, Ty, DS, Name, - ArgNo, Indirection); + IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, Ty, DS, Name, + ArgNo, Indirection); } else - IGM.DebugInfo->emitStackVariableDeclaration(Builder, Storage, Ty, DS, - Name, Indirection); + IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, Ty, DS, Name, 0, + Indirection); } void emitFailBB() { @@ -575,11 +634,11 @@ class IRGenSILFunction : //===--------------------------------------------------------------------===// void visitSILBasicBlock(SILBasicBlock *BB); - IndirectionKind getLoweredArgValue(llvm::SmallVectorImpl &Vals, - SILArgument *Arg, StringRef Name); void emitFunctionArgDebugInfo(SILBasicBlock *BB); + void emitDebugInfoForAllocStack(AllocStackInst *i, const TypeInfo &type, + llvm::Value *addr); void visitAllocStackInst(AllocStackInst *i); void visitAllocRefInst(AllocRefInst *i); void visitAllocRefDynamicInst(AllocRefDynamicInst *i); @@ -669,10 +728,11 @@ class IRGenSILFunction : void visitStrongUnpinInst(StrongUnpinInst *i); void visitStrongRetainInst(StrongRetainInst *i); void visitStrongReleaseInst(StrongReleaseInst *i); - void visitStrongRetainAutoreleasedInst(StrongRetainAutoreleasedInst *i); void visitStrongRetainUnownedInst(StrongRetainUnownedInst *i); void visitUnownedRetainInst(UnownedRetainInst *i); void visitUnownedReleaseInst(UnownedReleaseInst *i); + void visitLoadUnownedInst(LoadUnownedInst *i); + void visitStoreUnownedInst(StoreUnownedInst *i); void visitIsUniqueInst(IsUniqueInst *i); void visitIsUniqueOrPinnedInst(IsUniqueOrPinnedInst *i); void visitDeallocStackInst(DeallocStackInst *i); @@ -723,7 +783,6 @@ class IRGenSILFunction : void visitBranchInst(BranchInst *i); void visitCondBranchInst(CondBranchInst *i); void visitReturnInst(ReturnInst *i); - void visitAutoreleaseReturnInst(AutoreleaseReturnInst *i); void visitThrowInst(ThrowInst *i); void visitSwitchValueInst(SwitchValueInst *i); void visitSwitchEnumInst(SwitchEnumInst *i); @@ -742,7 +801,6 @@ llvm::Value *StaticFunction::getExplosionValue(IRGenFunction &IGF) const { void LoweredValue::getExplosion(IRGenFunction &IGF, Explosion &ex) const { switch (kind) { case Kind::Address: - case Kind::UnallocatedAddressInBuffer: llvm_unreachable("not a value"); case Kind::Explosion: @@ -763,7 +821,6 @@ void LoweredValue::getExplosion(IRGenFunction &IGF, Explosion &ex) const { llvm::Value *LoweredValue::getSingletonExplosion(IRGenFunction &IGF) const { switch (kind) { case Kind::Address: - case Kind::UnallocatedAddressInBuffer: llvm_unreachable("not a value"); case Kind::Explosion: @@ -830,9 +887,7 @@ emitPHINodesForBBArgs(IRGenSILFunction &IGF, if (!silBB->empty()) { SILInstruction &I = *silBB->begin(); auto DS = I.getDebugScope(); - // FIXME: This should be an assertion. - if (!DS || (DS->SILFn != IGF.CurSILFn && !DS->InlinedCallSite)) - DS = IGF.CurSILFn->getDebugScope(); + assert(DS && (DS->SILFn == IGF.CurSILFn || DS->InlinedCallSite)); IGF.IGM.DebugInfo->setCurrentLoc(IGF.Builder, DS, I.getLoc()); } } @@ -936,10 +991,12 @@ static void emitDirectExternalParameter(IRGenSILFunction &IGF, // Otherwise, we need to traffic through memory. // Create a temporary. - Address temporary = allocateForCoercion(IGF, + Address temporary; Size tempSize; + std::tie(temporary, tempSize) = allocateForCoercion(IGF, coercionTy, paramTI.getStorageType(), ""); + IGF.Builder.CreateLifetimeStart(temporary, tempSize); // Write the input parameters into the temporary: Address coercedAddr = @@ -965,6 +1022,7 @@ static void emitDirectExternalParameter(IRGenSILFunction &IGF, paramTI.loadAsTake(IGF, temporary, out); // Deallocate the temporary. + // `deallocateStack` emits the lifetime.end marker for us. paramTI.deallocateStack(IGF, temporary, paramType); } @@ -1201,7 +1259,7 @@ static void emitEntryPointArgumentsCOrObjC(IRGenSILFunction &IGF, // all the value parameters. if (hasPolymorphicParameters(funcTy)) { emitPolymorphicParameters(IGF, *IGF.CurSILFn, params, - NULL, + nullptr, [&](unsigned paramIndex) -> llvm::Value* { SILValue parameter = entry->getBBArgs()[paramIndex]; return IGF.getLoweredSingletonExplosion(parameter); @@ -1250,6 +1308,20 @@ void IRGenSILFunction::emitSILFunction() { CurSILFn->print(llvm::dbgs())); assert(!CurSILFn->empty() && "function has no basic blocks?!"); + + // Configure the dominance resolver. + // TODO: consider re-using a dom analysis from the PassManager + // TODO: consider using a cheaper analysis at -O0 + setDominanceResolver([](IRGenFunction &IGF_, + DominancePoint activePoint, + DominancePoint dominatingPoint) -> bool { + IRGenSILFunction &IGF = static_cast(IGF_); + if (!IGF.Dominance) { + IGF.Dominance.reset(new DominanceInfo(IGF.CurSILFn)); + } + return IGF.Dominance->dominates(dominatingPoint.as(), + activePoint.as()); + }); // FIXME: Or if this is a witness. DebugInfo doesn't have an interface to // correctly handle the generic parameters of a witness, which can come from @@ -1288,7 +1360,7 @@ void IRGenSILFunction::emitSILFunction() { break; } emitLocalSelfMetadata(*this); - + assert(params.empty() && "did not map all llvm params to SIL params?!"); // It's really nice to be able to assume that we've already emitted @@ -1339,8 +1411,7 @@ void IRGenSILFunction::emitSILFunction() { // // Therefore the invariant holds of all the successors, and we can // queue them up if we haven't already visited them. - for (auto &succ : bb->getSuccessors()) { - auto succBB = succ.getBB(); + for (auto *succBB : bb->getSuccessorBlocks()) { if (visitedBlocks.insert(succBB).second) workQueue.push_back(succBB); } @@ -1376,38 +1447,17 @@ void IRGenSILFunction::estimateStackSize() { /// Determine the number of source-level Swift of a function or closure. static unsigned countArgs(DeclContext *DC) { unsigned N = 0; - auto count = [&](ArrayRef Patterns) { - for (auto p : Patterns) - p->forEachVariable([&](VarDecl *VD) { ++N; }); - }; - - if (auto *Fn = dyn_cast(DC)) - count(Fn->getBodyParamPatterns()); - else if (auto *Closure = dyn_cast(DC)) - count(Closure->getParamPatterns()); + if (auto *Fn = dyn_cast(DC)) { + for (auto *PL : Fn->getParameterLists()) + N += PL->size(); + + } else if (auto *Closure = dyn_cast(DC)) + N += Closure->getParameters()->size(); else llvm_unreachable("unhandled declcontext type"); return N; } -/// Store the lowered IR representation of Arg in the array -/// Vals. Returns true if Arg is a byref argument. -IndirectionKind IRGenSILFunction:: -getLoweredArgValue(llvm::SmallVectorImpl &Vals, - SILArgument *Arg, StringRef Name) { - const LoweredValue &LoweredArg = getLoweredValue(Arg); - if (LoweredArg.isAddress()) { - Vals.push_back(LoweredArg.getAddress().getAddress()); - return IndirectValue; - } else if (LoweredArg.kind == LoweredValue::Kind::Explosion) { - Explosion e = LoweredArg.getExplosion(*this); - for (auto val : e.claimAll()) - Vals.push_back(val); - } else - llvm_unreachable("unhandled argument kind"); - return DirectValue; -} - void IRGenSILFunction::emitFunctionArgDebugInfo(SILBasicBlock *BB) { // Emit the artificial error result argument. auto FnTy = CurSILFn->getLoweredFunctionType(); @@ -1420,14 +1470,14 @@ void IRGenSILFunction::emitFunctionArgDebugInfo(SILBasicBlock *BB) { IGM.getPointerAlignment(), nullptr); StringRef Name("$error"); - // We just need any number that is guranteed to be larger than every + // We just need any number that is guaranteed to be larger than every // other argument. It is only used for sorting. unsigned ArgNo = countArgs(CurSILFn->getDeclContext()) + 1 + BB->getBBArgs().size(); - IGM.DebugInfo->emitArgVariableDeclaration( - Builder, emitShadowCopy(ErrorResultSlot.getAddress(), Name), DTI, - getDebugScope(), Name, ArgNo, - IndirectValue, ArtificialValue); + IGM.DebugInfo->emitVariableDeclaration( + Builder, + emitShadowCopy(ErrorResultSlot.getAddress(), getDebugScope(), Name), + DTI, getDebugScope(), Name, ArgNo, IndirectValue, ArtificialValue); } } @@ -1440,6 +1490,11 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) { bool InEntryBlock = BB->pred_empty(); bool ArgsEmitted = false; + // Set this block as the dominance point. This implicitly communicates + // with the dominance resolver configured in emitSILFunction. + DominanceScope dominance(*this, InEntryBlock ? DominancePoint::universal() + : DominancePoint(BB)); + // The basic blocks are visited in a random order. Reset the debug location. std::unique_ptr ScopedLoc; if (InEntryBlock) @@ -1496,8 +1551,7 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) { if (!DS) { if (CurSILFn->isBare()) DS = CurSILFn->getDebugScope(); - // FIXME: Enable this assertion. - //assert(maybeScopeless(I) && "instruction has location, but no scope"); + assert(maybeScopeless(I) && "instruction has location, but no scope"); } // Ignore scope-less instructions and have IRBuilder reuse the @@ -1813,7 +1867,6 @@ static CallEmission getCallEmissionForLoweredValue(IRGenSILFunction &IGF, } case LoweredValue::Kind::Address: - case LoweredValue::Kind::UnallocatedAddressInBuffer: llvm_unreachable("sil address isn't a valid callee"); } @@ -1979,7 +2032,6 @@ getPartialApplicationFunction(IRGenSILFunction &IGF, switch (lv.kind) { case LoweredValue::Kind::Address: - case LoweredValue::Kind::UnallocatedAddressInBuffer: llvm_unreachable("can't partially apply an address"); case LoweredValue::Kind::ObjCMethod: llvm_unreachable("objc method partial application shouldn't get here"); @@ -2178,16 +2230,17 @@ static void emitReturnInst(IRGenSILFunction &IGF, void IRGenSILFunction::visitReturnInst(swift::ReturnInst *i) { Explosion result = getLoweredExplosion(i->getOperand()); - emitReturnInst(*this, i->getOperand().getType(), result); -} -void IRGenSILFunction::visitAutoreleaseReturnInst(AutoreleaseReturnInst *i) { - Explosion result = getLoweredExplosion(i->getOperand()); - assert(result.size() == 1 && - "should have one objc pointer value for autorelease_return"); - Explosion temp; - temp.add(emitObjCAutoreleaseReturnValue(*this, result.claimNext())); - emitReturnInst(*this, i->getOperand().getType(), temp); + // Implicitly autorelease the return value if the function's result + // convention is autoreleased. + if (CurSILFn->getLoweredFunctionType()->getResult().getConvention() == + ResultConvention::Autoreleased) { + Explosion temp; + temp.add(emitObjCAutoreleaseReturnValue(*this, result.claimNext())); + result = std::move(temp); + } + + emitReturnInst(*this, i->getOperand().getType(), result); } void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) { @@ -2732,7 +2785,7 @@ void IRGenSILFunction::visitDynamicMethodBranchInst(DynamicMethodBranchInst *i){ LoweredBB &hasMethodBB = getLoweredBB(i->getHasMethodBB()); LoweredBB &noMethodBB = getLoweredBB(i->getNoMethodBB()); - // Emit the swift_objcRespondsToSelector() call. + // Emit the respondsToSelector: call. StringRef selector; llvm::SmallString<64> selectorBuffer; if (auto fnDecl = dyn_cast(i->getMember().getDecl())) @@ -2746,8 +2799,24 @@ void IRGenSILFunction::visitDynamicMethodBranchInst(DynamicMethodBranchInst *i){ if (object->getType() != IGM.ObjCPtrTy) object = Builder.CreateBitCast(object, IGM.ObjCPtrTy); llvm::Value *loadSel = emitObjCSelectorRefLoad(selector); - llvm::CallInst *call = Builder.CreateCall(IGM.getObjCRespondsToSelectorFn(), - {object, loadSel}); + + llvm::Value *respondsToSelector + = emitObjCSelectorRefLoad("respondsToSelector:"); + + llvm::Constant *messenger = IGM.getObjCMsgSendFn(); + llvm::Type *argTys[] = { + IGM.ObjCPtrTy, + IGM.Int8PtrTy, + IGM.Int8PtrTy, + }; + auto respondsToSelectorTy = llvm::FunctionType::get(IGM.Int1Ty, + argTys, + /*isVarArg*/ false) + ->getPointerTo(); + messenger = llvm::ConstantExpr::getBitCast(messenger, + respondsToSelectorTy); + llvm::CallInst *call = Builder.CreateCall(messenger, + {object, respondsToSelector, loadSel}); call->setDoesNotThrow(); // FIXME: Assume (probably safely) that the hasMethodBB has only us as a @@ -2958,38 +3027,31 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) { if (!IGM.DebugInfo) return; - VarDecl *Decl = i->getDecl(); - if (!Decl) - return; - auto SILVal = i->getOperand(); if (isa(SILVal)) return; - StringRef Name = Decl->getNameStr(); - Explosion e = getLoweredExplosion(SILVal); - DebugTypeInfo DbgTy(Decl, Decl->getType(), getTypeInfo(SILVal.getType())); - if (DbgTy.getType()->getKind() == TypeKind::InOut) - // An inout type that is described by a debug *value* is a - // promoted capture. Unwrap the type. - DbgTy.unwrapInOutType(); + StringRef Name = getVarName(i); + DebugTypeInfo DbgTy; + SILType SILTy = SILVal.getType(); + if (VarDecl *Decl = i->getDecl()) + DbgTy = DebugTypeInfo(Decl, Decl->getType(), getTypeInfo(SILTy)); + else if (i->getFunction()->isBare() && + !SILTy.getSwiftType()->hasArchetype() && !Name.empty()) + // Preliminary support for .sil debug information. + DbgTy = DebugTypeInfo(SILTy.getSwiftType(), getTypeInfo(SILTy), nullptr); + else + return; + // An inout/lvalue type that is described by a debug value has been + // promoted by an optimization pass. Unwrap the type. + DbgTy.unwrapLValueOrInOutType(); // Put the value into a stack slot at -Onone. - llvm::SmallVector Copy; - emitShadowCopy(e.claimAll(), Name, Copy); + llvm::SmallVector Copy; + Explosion e = getLoweredExplosion(SILVal); + emitShadowCopy(e.claimAll(), i->getDebugScope(), Name, Copy); emitDebugVariableDeclaration(Copy, DbgTy, i->getDebugScope(), Name, - i->getVarInfo().getArgNo()); -} - -/// InOut- and Archetypes are already implicitly indirect. -static IndirectionKind getIndirectionForDebugValueAddr(swift::TypeBase *Ty) { - switch (Ty->getKind()) { - case TypeKind::InOut: - case TypeKind::Archetype: - return DirectValue; - default: - return IndirectValue; - } + i->getVarInfo().ArgNo); } void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) { @@ -3003,14 +3065,20 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) { if (isa(SILVal)) return; - StringRef Name = Decl->getName().str(); + StringRef Name = getVarName(i); auto Addr = getLoweredAddress(SILVal).getAddress(); - DebugTypeInfo DbgTy(Decl, Decl->getType(), getTypeInfo(SILVal.getType())); - // Put the value into a stack slot at -Onone and emit a debug intrinsic. + DebugTypeInfo DbgTy(Decl, SILVal.getType().getSwiftType(), + getTypeInfo(SILVal.getType())); + // Unwrap implicitly indirect types and types that are passed by + // reference only at the SIL level and below. + if (DbgTy.isArchetype() || i->getVarInfo().Constant) + DbgTy.unwrapLValueOrInOutType(); + // Put the value's address into a stack slot at -Onone and emit a debug + // intrinsic. emitDebugVariableDeclaration( - emitShadowCopy(Addr, Name), DbgTy, i->getDebugScope(), Name, - i->getVarInfo().getArgNo(), - getIndirectionForDebugValueAddr(DbgTy.getType())); + emitShadowCopy(Addr, i->getDebugScope(), Name), DbgTy, i->getDebugScope(), + Name, i->getVarInfo().ArgNo, + DbgTy.isImplicitlyIndirect() ? DirectValue : IndirectValue); } void IRGenSILFunction::visitLoadWeakInst(swift::LoadWeakInst *i) { @@ -3077,7 +3145,7 @@ void IRGenSILFunction::visitCopyBlockInst(CopyBlockInst *i) { void IRGenSILFunction::visitStrongPinInst(swift::StrongPinInst *i) { Explosion lowered = getLoweredExplosion(i->getOperand()); llvm::Value *object = lowered.claimNext(); - llvm::Value *pinHandle = emitTryPin(object); + llvm::Value *pinHandle = emitNativeTryPin(object); Explosion result; result.add(pinHandle); @@ -3087,49 +3155,25 @@ void IRGenSILFunction::visitStrongPinInst(swift::StrongPinInst *i) { void IRGenSILFunction::visitStrongUnpinInst(swift::StrongUnpinInst *i) { Explosion lowered = getLoweredExplosion(i->getOperand()); llvm::Value *pinHandle = lowered.claimNext(); - emitUnpin(pinHandle); + emitNativeUnpin(pinHandle); } void IRGenSILFunction::visitStrongRetainInst(swift::StrongRetainInst *i) { Explosion lowered = getLoweredExplosion(i->getOperand()); auto &ti = cast(getTypeInfo(i->getOperand().getType())); - ti.retain(*this, lowered); + ti.strongRetain(*this, lowered); } void IRGenSILFunction::visitStrongReleaseInst(swift::StrongReleaseInst *i) { Explosion lowered = getLoweredExplosion(i->getOperand()); auto &ti = cast(getTypeInfo(i->getOperand().getType())); - ti.release(*this, lowered); -} - -void IRGenSILFunction:: -visitStrongRetainAutoreleasedInst(swift::StrongRetainAutoreleasedInst *i) { - Explosion lowered = getLoweredExplosion(i->getOperand()); - llvm::Value *value = lowered.claimNext(); - value = emitObjCRetainAutoreleasedReturnValue(*this, value); - - // Overwrite the stored explosion value with the result of - // objc_retainAutoreleasedReturnValue. This is actually - // semantically important: if the call result is live across this - // call, the backend will have to emit instructions that interfere - // with the reclaim optimization. - // - // This is only sound if the retainAutoreleasedReturnValue - // immediately follows the call, but that should be reliably true. - // - // ...the reclaim here should really be implicit in the SIL calling - // convention. - - Explosion out; - out.add(value); - overwriteLoweredExplosion(i->getOperand(), out); + ti.strongRelease(*this, lowered); } /// Given a SILType which is a ReferenceStorageType, return the type /// info for the underlying reference type. static const ReferenceTypeInfo &getReferentTypeInfo(IRGenFunction &IGF, SILType silType) { - assert(silType.isObject()); auto type = silType.castTo().getReferentType(); return cast(IGF.getTypeInfoForLowered(type)); } @@ -3138,7 +3182,7 @@ void IRGenSILFunction:: visitStrongRetainUnownedInst(swift::StrongRetainUnownedInst *i) { Explosion lowered = getLoweredExplosion(i->getOperand()); auto &ti = getReferentTypeInfo(*this, i->getOperand().getType()); - ti.retainUnowned(*this, lowered); + ti.strongRetainUnowned(*this, lowered); } void IRGenSILFunction::visitUnownedRetainInst(swift::UnownedRetainInst *i) { @@ -3147,13 +3191,38 @@ void IRGenSILFunction::visitUnownedRetainInst(swift::UnownedRetainInst *i) { ti.unownedRetain(*this, lowered); } - void IRGenSILFunction::visitUnownedReleaseInst(swift::UnownedReleaseInst *i) { Explosion lowered = getLoweredExplosion(i->getOperand()); auto &ti = getReferentTypeInfo(*this, i->getOperand().getType()); ti.unownedRelease(*this, lowered); } +void IRGenSILFunction::visitLoadUnownedInst(swift::LoadUnownedInst *i) { + Address source = getLoweredAddress(i->getOperand()); + auto &ti = getReferentTypeInfo(*this, i->getOperand().getType()); + + Explosion result; + if (i->isTake()) { + ti.unownedTakeStrong(*this, source, result); + } else { + ti.unownedLoadStrong(*this, source, result); + } + + setLoweredExplosion(SILValue(i, 0), result); +} + +void IRGenSILFunction::visitStoreUnownedInst(swift::StoreUnownedInst *i) { + Explosion source = getLoweredExplosion(i->getSrc()); + Address dest = getLoweredAddress(i->getDest()); + + auto &ti = getReferentTypeInfo(*this, i->getDest().getType()); + if (i->isInitializationOfDest()) { + ti.unownedInit(*this, source, dest); + } else { + ti.unownedAssign(*this, source, dest); + } +} + static void requireRefCountedType(IRGenSILFunction &IGF, SourceLoc loc, SILType silType) { @@ -3202,7 +3271,6 @@ visitIsUniqueOrPinnedInst(swift::IsUniqueOrPinnedInst *i) { static bool tryDeferFixedSizeBufferInitialization(IRGenSILFunction &IGF, const SILInstruction *allocInst, const TypeInfo &ti, - SILValue containerValue, SILValue addressValue, Address fixedSizeBuffer, const llvm::Twine &name) { @@ -3240,37 +3308,35 @@ static bool tryDeferFixedSizeBufferInitialization(IRGenSILFunction &IGF, // We can defer to this initialization. Allocate the fixed-size buffer // now, but don't allocate the value inside it. - if (!fixedSizeBuffer.getAddress()) + if (!fixedSizeBuffer.getAddress()) { fixedSizeBuffer = IGF.createFixedSizeBufferAlloca(name); - if (containerValue) - IGF.setLoweredAddress(containerValue, fixedSizeBuffer); - IGF.setLoweredUnallocatedAddressInBuffer(addressValue, fixedSizeBuffer); + IGF.Builder.CreateLifetimeStart(fixedSizeBuffer, + getFixedBufferSize(IGF.IGM)); + } + IGF.setContainerOfUnallocatedAddress(addressValue, fixedSizeBuffer); return true; } return false; } -static void emitDebugDeclarationForAllocStack(IRGenSILFunction &IGF, - AllocStackInst *i, - const TypeInfo &type, - llvm::Value *addr) { +void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i, + const TypeInfo &type, + llvm::Value *addr) { VarDecl *Decl = i->getDecl(); - if (IGF.IGM.DebugInfo && Decl) { + if (IGM.DebugInfo && Decl) { auto *Pattern = Decl->getParentPattern(); if (!Pattern || !Pattern->isImplicit()) { + auto DbgTy = DebugTypeInfo(Decl, type); // Discard any inout or lvalue qualifiers. Since the object itself // is stored in the alloca, emitting it as a reference type would // be wrong. - auto DbgTy = DebugTypeInfo(Decl, - Decl->getType()->getLValueOrInOutObjectType(), - type); - auto Name = Decl->getName().empty() ? "_" : Decl->getName().str(); - auto DS = i->getDebugScope(); - if (DS) { - assert(DS->SILFn == IGF.CurSILFn || DS->InlinedCallSite); - IGF.emitDebugVariableDeclaration(addr, DbgTy, DS, Name, - i->getVarInfo().getArgNo()); + DbgTy.unwrapLValueOrInOutType(); + StringRef Name = getVarName(i); + if (auto DS = i->getDebugScope()) { + assert(DS->SILFn == CurSILFn || DS->InlinedCallSite); + emitDebugVariableDeclaration(addr, DbgTy, DS, Name, + i->getVarInfo().ArgNo); } } } @@ -3281,20 +3347,18 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) { // Derive name from SIL location. VarDecl *Decl = i->getDecl(); - StringRef dbgname = + StringRef dbgname; # ifndef NDEBUG - // If this is a DEBUG build, use pretty names for the LLVM IR. - Decl ? Decl->getNameStr() : + // If this is a DEBUG build, use pretty names for the LLVM IR. + dbgname = getVarName(i); # endif - ""; (void) Decl; // If a dynamic alloc_stack is immediately initialized by a copy_addr // operation, we can combine the allocation and initialization using an // optimized value witness. if (tryDeferFixedSizeBufferInitialization(*this, i, type, - i->getContainerResult(), - i->getAddressResult(), + SILValue(i, 0), Address(), dbgname)) return; @@ -3302,12 +3366,10 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) { auto addr = type.allocateStack(*this, i->getElementType(), dbgname); + + emitDebugInfoForAllocStack(i, type, addr.getAddress().getAddress()); - emitDebugDeclarationForAllocStack(*this, i, type, - addr.getAddress().getAddress()); - - setLoweredAddress(i->getContainerResult(), addr.getContainer()); - setLoweredAddress(i->getAddressResult(), addr.getAddress()); + setLoweredContainedAddress(i, addr); } void IRGenSILFunction::visitAllocRefInst(swift::AllocRefInst *i) { @@ -3342,8 +3404,8 @@ void IRGenSILFunction::visitAllocRefDynamicInst(swift::AllocRefDynamicInst *i) { void IRGenSILFunction::visitDeallocStackInst(swift::DeallocStackInst *i) { const TypeInfo &type = getTypeInfo(i->getOperand().getType()); - Address addr = getLoweredAddress(i->getOperand()); - type.deallocateStack(*this, addr, + Address container = getLoweredContainerOfAddress(i->getOperand()); + type.deallocateStack(*this, container, i->getOperand().getType()); } @@ -3399,7 +3461,7 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) { // Derive name from SIL location. VarDecl *Decl = i->getDecl(); - StringRef Name = Decl ? Decl->getName().str() : ""; + StringRef Name = getVarName(i); StringRef DbgName = # ifndef NDEBUG // If this is a DEBUG build, use pretty names for the LLVM IR. @@ -3425,17 +3487,12 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) { // arguments. if (Name == IGM.Context.Id_self.str()) return; - auto Indirection = IndirectValue; - // LValues and inout args are implicitly indirect because of their type. - if (Decl->getType()->getKind() == TypeKind::LValue || - Decl->getType()->getKind() == TypeKind::InOut) - Indirection = DirectValue; - IGM.DebugInfo->emitStackVariableDeclaration - (Builder, - emitShadowCopy(addr.getAddress(), Name), - DebugTypeInfo(Decl, i->getElementType().getSwiftType(), type), - i->getDebugScope(), Name, Indirection); + DebugTypeInfo DbgTy(Decl, i->getElementType().getSwiftType(), type); + IGM.DebugInfo->emitVariableDeclaration( + Builder, emitShadowCopy(addr.getAddress(), i->getDebugScope(), Name), + DbgTy, i->getDebugScope(), Name, 0, + DbgTy.isImplicitlyIndirect() ? DirectValue : IndirectValue); } } @@ -3610,12 +3667,17 @@ static void emitUncheckedValueBitCast(IRGenSILFunction &IGF, outTI.getFixedAlignment()), "bitcast"); + auto maxSize = std::max(inTI.getFixedSize(), outTI.getFixedSize()); + IGF.Builder.CreateLifetimeStart(inStorage, maxSize); + // Store the 'in' value. inTI.initialize(IGF, in, inStorage); // Load the 'out' value as the destination type. auto outStorage = IGF.Builder.CreateBitCast(inStorage, outTI.getStorageType()->getPointerTo()); outTI.loadAsTake(IGF, outStorage, out); + + IGF.Builder.CreateLifetimeEnd(inStorage, maxSize); return; } @@ -3683,19 +3745,24 @@ static void trivialRefConversion(IRGenSILFunction &IGF, IGF.setLoweredExplosion(result, temp); return; } - - // Otherwise, do the conversion. - llvm::Value *value = temp.claimNext(); + auto schema = resultTI.getSchema(); - assert(schema.size() == 1 && "not a single scalar type"); - auto resultTy = schema.begin()->getScalarType(); - if (resultTy->isPointerTy()) - value = IGF.Builder.CreateIntToPtr(value, resultTy); - else - value = IGF.Builder.CreatePtrToInt(value, resultTy); - Explosion out; - out.add(value); + + for (auto schemaElt : schema) { + auto resultTy = schemaElt.getScalarType(); + + llvm::Value *value = temp.claimNext(); + if (value->getType() == resultTy) { + // Nothing to do. This happens with the unowned conversions. + } else if (resultTy->isPointerTy()) { + value = IGF.Builder.CreateIntToPtr(value, resultTy); + } else { + value = IGF.Builder.CreatePtrToInt(value, resultTy); + } + out.add(value); + } + IGF.setLoweredExplosion(result, out); } @@ -4149,8 +4216,7 @@ void IRGenSILFunction::visitInitExistentialAddrInst(swift::InitExistentialAddrIn auto &srcTI = getTypeInfo(i->getLoweredConcreteType()); // See if we can defer initialization of the buffer to a copy_addr into it. - if (tryDeferFixedSizeBufferInitialization(*this, i, srcTI, SILValue(), i, - buffer, "")) + if (tryDeferFixedSizeBufferInitialization(*this, i, srcTI, i, buffer, "")) return; // Compute basic layout information about the type. If we have a @@ -4347,23 +4413,24 @@ void IRGenSILFunction::visitWitnessMethodInst(swift::WitnessMethodInst *i) { ProtocolConformance *conformance = i->getConformance(); SILDeclRef member = i->getMember(); + // It would be nice if this weren't discarded. + llvm::Value *baseMetadataCache = nullptr; + Explosion lowered; - emitWitnessMethodValue(*this, baseTy, member, conformance, lowered); + emitWitnessMethodValue(*this, baseTy, &baseMetadataCache, + member, conformance, lowered); setLoweredExplosion(SILValue(i, 0), lowered); } void IRGenSILFunction::setAllocatedAddressForBuffer(SILValue v, const Address &allocedAddress) { - assert(getLoweredValue(v).kind == LoweredValue::Kind::UnallocatedAddressInBuffer - && "not an unallocated address"); - - overwriteLoweredAddress(v, allocedAddress); + overwriteAllocatedAddress(v, allocedAddress); + // Emit the debug info for the variable if any. if (auto allocStack = dyn_cast(v)) { - emitDebugDeclarationForAllocStack(*this, allocStack, - getTypeInfo(v.getType()), - allocedAddress.getAddress()); + emitDebugInfoForAllocStack(allocStack, getTypeInfo(v.getType()), + allocedAddress.getAddress()); } } @@ -4376,7 +4443,7 @@ void IRGenSILFunction::visitCopyAddrInst(swift::CopyAddrInst *i) { auto &loweredDest = getLoweredValue(i->getDest()); if (loweredDest.isUnallocatedAddressInBuffer()) { isFixedBufferInitialization = true; - dest = loweredDest.getAddressOfUnallocatedBuffer(); + dest = loweredDest.getContainerOfAddress(); } else { isFixedBufferInitialization = false; dest = loweredDest.getAddress(); diff --git a/lib/IRGen/IndirectTypeInfo.h b/lib/IRGen/IndirectTypeInfo.h index 55d3d79462a7f..a64b061e3e5be 100644 --- a/lib/IRGen/IndirectTypeInfo.h +++ b/lib/IRGen/IndirectTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp index aa923d337410f..186ff536e1ec7 100644 --- a/lib/IRGen/Linking.cpp +++ b/lib/IRGen/Linking.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -55,6 +55,7 @@ static StringRef mangleValueWitness(ValueWitness witness) { case ValueWitness::GetExtraInhabitantIndex: return "xg"; case ValueWitness::GetEnumTag: return "ug"; case ValueWitness::DestructiveProjectEnumData: return "up"; + case ValueWitness::DestructiveInjectEnumTag: return "ui"; case ValueWitness::Size: case ValueWitness::Flags: @@ -83,39 +84,38 @@ static void mangleClangDecl(raw_ostream &buffer, void LinkEntity::mangle(raw_ostream &buffer) const { // Almost everything below gets the common prefix: // mangled-name ::= '_T' global - Mangler mangler(buffer); + Mangler mangler; switch (getKind()) { // global ::= 'w' value-witness-kind type // value witness case Kind::ValueWitness: - buffer << "_Tw"; - buffer << mangleValueWitness(getValueWitness()); - + mangler.append("_Tw"); + mangler.append(mangleValueWitness(getValueWitness())); mangler.mangleType(getType(), ResilienceExpansion::Minimal, 0); - return; + return mangler.finalize(buffer); // global ::= 'WV' type // value witness case Kind::ValueWitnessTable: - buffer << "_TWV"; + mangler.append("_TWV"); mangler.mangleType(getType(), ResilienceExpansion::Minimal, 0); - return; + return mangler.finalize(buffer); // global ::= 't' type // Abstract type manglings just follow . case Kind::TypeMangling: mangler.mangleType(getType(), ResilienceExpansion::Minimal, 0); - return; + return mangler.finalize(buffer); // global ::= 'Ma' type // type metadata access function case Kind::TypeMetadataAccessFunction: - buffer << "_TMa"; + mangler.append("_TMa"); mangler.mangleType(getType(), ResilienceExpansion::Minimal, 0); - return; + return mangler.finalize(buffer); // global ::= 'ML' type // type metadata lazy cache variable case Kind::TypeMetadataLazyCacheVariable: - buffer << "_TML"; + mangler.append("_TML"); mangler.mangleType(getType(), ResilienceExpansion::Minimal, 0); - return; + return mangler.finalize(buffer); // global ::= 'Mf' type // 'full' type metadata // global ::= 'M' directness type // type metadata @@ -129,38 +129,38 @@ void LinkEntity::mangle(raw_ostream &buffer) const { mangler.mangleTypeMetadataFull(getType(), isMetadataPattern()); break; } - return; + return mangler.finalize(buffer); // global ::= 'M' directness type // type metadata case Kind::ForeignTypeMetadataCandidate: mangler.mangleTypeMetadataFull(getType(), /*isPattern=*/false); - return; + return mangler.finalize(buffer); // global ::= 'Mm' type // class metaclass case Kind::SwiftMetaclassStub: - buffer << "_TMm"; + mangler.append("_TMm"); mangler.mangleNominalType(cast(getDecl()), ResilienceExpansion::Minimal, Mangler::BindGenerics::None); - return; - + return mangler.finalize(buffer); + // global ::= 'Mn' type // nominal type descriptor case Kind::NominalTypeDescriptor: - buffer << "_TMn"; + mangler.append("_TMn"); mangler.mangleNominalType(cast(getDecl()), ResilienceExpansion::Minimal, Mangler::BindGenerics::None); - return; + return mangler.finalize(buffer); // global ::= 'Mp' type // protocol descriptor case Kind::ProtocolDescriptor: - buffer << "_TMp"; + mangler.append("_TMp"); mangler.mangleProtocolName(cast(getDecl())); - return; - + return mangler.finalize(buffer); + // global ::= 'Wo' entity case Kind::WitnessTableOffset: - buffer << "_TWo"; + mangler.append("_TWo"); // Witness table entries for constructors always refer to the allocating // constructor. @@ -169,51 +169,67 @@ void LinkEntity::mangle(raw_ostream &buffer) const { getResilienceExpansion(), getUncurryLevel()); else - mangler.mangleEntity(getDecl(), getResilienceExpansion(), getUncurryLevel()); - return; + mangler.mangleEntity(getDecl(), getResilienceExpansion(), + getUncurryLevel()); + return mangler.finalize(buffer); // global ::= 'Wv' directness entity case Kind::FieldOffset: mangler.mangleFieldOffsetFull(getDecl(), isOffsetIndirect()); - return; - + return mangler.finalize(buffer); + // global ::= 'WP' protocol-conformance case Kind::DirectProtocolWitnessTable: - buffer << "_TWP"; + mangler.append("_TWP"); mangler.mangleProtocolConformance(getProtocolConformance()); - return; + return mangler.finalize(buffer); + + // global ::= 'WG' protocol-conformance + case Kind::GenericProtocolWitnessTableCache: + buffer << "_TWG"; + mangler.mangleProtocolConformance(getProtocolConformance()); + return mangler.finalize(buffer); + + // global ::= 'WI' protocol-conformance + case Kind::GenericProtocolWitnessTableInstantiationFunction: + buffer << "_TWI"; + mangler.mangleProtocolConformance(getProtocolConformance()); + return mangler.finalize(buffer); // global ::= 'Wa' protocol-conformance case Kind::ProtocolWitnessTableAccessFunction: - buffer << "_TWa"; + mangler.append("_TWa"); mangler.mangleProtocolConformance(getProtocolConformance()); - return; + return mangler.finalize(buffer); // global ::= 'Wl' type protocol-conformance case Kind::ProtocolWitnessTableLazyAccessFunction: - buffer << "_TWl"; + mangler.append("_TWl"); mangler.mangleType(getType(), ResilienceExpansion::Minimal, 0); mangler.mangleProtocolConformance(getProtocolConformance()); - return; + return mangler.finalize(buffer); // global ::= 'WL' type protocol-conformance case Kind::ProtocolWitnessTableLazyCacheVariable: - buffer << "_TWL"; + mangler.append("_TWL"); mangler.mangleType(getType(), ResilienceExpansion::Minimal, 0); mangler.mangleProtocolConformance(getProtocolConformance()); - return; + return mangler.finalize(buffer); - // global ::= 'WD' protocol-conformance - case Kind::DependentProtocolWitnessTableGenerator: - buffer << "_TWD"; + // global ::= 'Wt' protocol-conformance identifier + case Kind::AssociatedTypeMetadataAccessFunction: + mangler.append("_TWt"); mangler.mangleProtocolConformance(getProtocolConformance()); - return; - - // global ::= 'Wd' protocol-conformance - case Kind::DependentProtocolWitnessTableTemplate: - buffer << "_TWd"; + mangler.mangleIdentifier(getAssociatedType()->getNameStr()); + return mangler.finalize(buffer); + + // global ::= 'WT' protocol-conformance identifier nominal-type + case Kind::AssociatedTypeWitnessTableAccessFunction: + mangler.append("_TWT"); mangler.mangleProtocolConformance(getProtocolConformance()); - return; + mangler.mangleIdentifier(getAssociatedType()->getNameStr()); + mangler.mangleProtocolDecl(getAssociatedProtocol()); + return mangler.finalize(buffer); // For all the following, this rule was imposed above: // global ::= local-marker? entity // some identifiable thing @@ -222,8 +238,8 @@ void LinkEntity::mangle(raw_ostream &buffer) const { case Kind::Function: // As a special case, functions can have external asm names. if (auto AsmA = getDecl()->getAttrs().getAttribute()) { - buffer << AsmA->Name; - return; + mangler.append(AsmA->Name); + return mangler.finalize(buffer); } // Otherwise, fall through into the 'other decl' case. @@ -234,18 +250,22 @@ void LinkEntity::mangle(raw_ostream &buffer) const { if (auto clangDecl = getDecl()->getClangDecl()) { if (auto namedClangDecl = dyn_cast(clangDecl)) { if (auto asmLabel = namedClangDecl->getAttr()) { - buffer << '\01' << asmLabel->getLabel(); + mangler.append('\01'); + mangler.append(asmLabel->getLabel()); } else if (namedClangDecl->hasAttr()) { // FIXME: When we can import C++, use Clang's mangler all the time. - mangleClangDecl(buffer, namedClangDecl, getDecl()->getASTContext()); + std::string storage; + llvm::raw_string_ostream SS(storage); + mangleClangDecl(SS, namedClangDecl, getDecl()->getASTContext()); + mangler.append(SS.str()); } else { - buffer << namedClangDecl->getName(); + mangler.append(namedClangDecl->getName()); } - return; + return mangler.finalize(buffer); } } - buffer << "_T"; + mangler.append("_T"); if (auto type = dyn_cast(getDecl())) { mangler.mangleNominalType(type, getResilienceExpansion(), Mangler::BindGenerics::None); @@ -258,30 +278,32 @@ void LinkEntity::mangle(raw_ostream &buffer) const { } else { mangler.mangleEntity(getDecl(), getResilienceExpansion(), getUncurryLevel()); } - return; + return mangler.finalize(buffer); // An Objective-C class reference; not a swift mangling. case Kind::ObjCClass: { - llvm::SmallString<64> nameBuffer; - buffer << "OBJC_CLASS_$_" - << cast(getDecl())->getObjCRuntimeName(nameBuffer); - return; + llvm::SmallString<64> TempBuffer; + mangler.append("OBJC_CLASS_$_"); + StringRef Name = cast(getDecl())->getObjCRuntimeName(TempBuffer); + mangler.append(Name); + return mangler.finalize(buffer); } // An Objective-C metaclass reference; not a swift mangling. case Kind::ObjCMetaclass: { - llvm::SmallString<64> nameBuffer; - buffer << "OBJC_METACLASS_$_" - << cast(getDecl())->getObjCRuntimeName(nameBuffer); - return; + llvm::SmallString<64> TempBuffer; + mangler.append("OBJC_METACLASS_$_"); + StringRef Name = cast(getDecl())->getObjCRuntimeName(TempBuffer); + mangler.append(Name); + return mangler.finalize(buffer); } case Kind::SILFunction: - buffer << getSILFunction()->getName(); - return; + mangler.appendSymbol(getSILFunction()->getName()); + return mangler.finalize(buffer); case Kind::SILGlobalVariable: - buffer << getSILGlobalVariable()->getName(); - return; + mangler.appendSymbol(getSILGlobalVariable()->getName()); + return mangler.finalize(buffer); } llvm_unreachable("bad entity kind!"); } diff --git a/lib/IRGen/Linking.h b/lib/IRGen/Linking.h index b74101ac2d20d..16ab7f87fc9de 100644 --- a/lib/IRGen/Linking.h +++ b/lib/IRGen/Linking.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -83,6 +83,9 @@ class LinkEntity { // These fields appear in the TypeMetadata kind. MetadataAddressShift = 8, MetadataAddressMask = 0x0300, IsPatternShift = 10, IsPatternMask = 0x0400, + + // This field appears in associated type access function kinds. + AssociatedTypeIndexShift = 8, AssociatedTypeIndexMask = ~KindMask, }; #define LINKENTITY_SET_FIELD(field, value) (value << field##Shift) #define LINKENTITY_GET_FIELD(value, field) ((value & field##Mask) >> field##Shift) @@ -127,6 +130,8 @@ class LinkEntity { /// A SIL global variable. The pointer is a SILGlobalVariable*. SILGlobalVariable, + // These next few are protocol-conformance kinds. + /// A direct protocol witness table. The secondary pointer is a /// ProtocolConformance*. DirectProtocolWitnessTable, @@ -134,14 +139,25 @@ class LinkEntity { /// A witness accessor function. The secondary pointer is a /// ProtocolConformance*. ProtocolWitnessTableAccessFunction, + + /// A generic protocol witness table cache. The secondary pointer is a + /// ProtocolConformance*. + GenericProtocolWitnessTableCache, + + /// The instantiation function for a generic protocol witness table. + /// The secondary pointer is a ProtocolConformance*. + GenericProtocolWitnessTableInstantiationFunction, - /// A dependent protocol witness table instantiation function. The - /// secondary pointer is a ProtocolConformance*. - DependentProtocolWitnessTableGenerator, - - /// A template for dependent protocol witness table instantiation. The - /// secondary pointer is a ProtocolConformance*. - DependentProtocolWitnessTableTemplate, + /// A function which returns the type metadata for the associated type + /// of a protocol. The secondary pointer is a ProtocolConformance*. + /// The index of the associated type declaration is stored in the data. + AssociatedTypeMetadataAccessFunction, + + /// A function which returns the witness table for a protocol-constrained + /// associated type of a protocol. The secondary pointer is a + /// ProtocolConformance*. The primary pointer is a ProtocolDecl*. + /// The index of the associated type declaration is stored in the data. + AssociatedTypeWitnessTableAccessFunction, // These are both type kinds and protocol-conformance kinds. @@ -238,6 +254,43 @@ class LinkEntity { Data = LINKENTITY_SET_FIELD(Kind, unsigned(kind)); } + void setForProtocolConformanceAndAssociatedType(Kind kind, + const ProtocolConformance *c, + AssociatedTypeDecl *associate, + ProtocolDecl *associatedProtocol = nullptr) { + assert(isProtocolConformanceKind(kind)); + Pointer = associatedProtocol; + SecondaryPointer = const_cast(static_cast(c)); + Data = LINKENTITY_SET_FIELD(Kind, unsigned(kind)) | + LINKENTITY_SET_FIELD(AssociatedTypeIndex, + getAssociatedTypeIndex(c, associate)); + } + + // We store associated types using their index in their parent protocol + // in order to avoid bloating LinkEntity out to three key pointers. + static unsigned getAssociatedTypeIndex(const ProtocolConformance *conformance, + AssociatedTypeDecl *associate) { + assert(conformance->getProtocol() == associate->getProtocol()); + unsigned result = 0; + for (auto requirement : associate->getProtocol()->getMembers()) { + if (requirement == associate) return result; + if (isa(requirement)) result++; + } + llvm_unreachable("didn't find associated type in protocol?"); + } + + static AssociatedTypeDecl * + getAssociatedTypeByIndex(const ProtocolConformance *conformance, + unsigned index) { + for (auto requirement : conformance->getProtocol()->getMembers()) { + if (auto associate = dyn_cast(requirement)) { + if (index == 0) return associate; + index--; + } + } + llvm_unreachable("didn't find associated type in protocol?"); + } + void setForType(Kind kind, CanType type) { assert(isTypeKind(kind)); Pointer = type.getPointer(); @@ -389,6 +442,22 @@ class LinkEntity { return entity; } + static LinkEntity + forGenericProtocolWitnessTableCache(const ProtocolConformance *C) { + LinkEntity entity; + entity.setForProtocolConformance(Kind::GenericProtocolWitnessTableCache, C); + return entity; + } + + static LinkEntity + forGenericProtocolWitnessTableInstantiationFunction( + const ProtocolConformance *C) { + LinkEntity entity; + entity.setForProtocolConformance( + Kind::GenericProtocolWitnessTableInstantiationFunction, C); + return entity; + } + static LinkEntity forProtocolWitnessTableLazyAccessFunction(const ProtocolConformance *C, CanType type) { @@ -407,6 +476,26 @@ class LinkEntity { return entity; } + static LinkEntity + forAssociatedTypeMetadataAccessFunction(const ProtocolConformance *C, + AssociatedTypeDecl *associate) { + LinkEntity entity; + entity.setForProtocolConformanceAndAssociatedType( + Kind::AssociatedTypeMetadataAccessFunction, C, associate); + return entity; + } + + static LinkEntity + forAssociatedTypeWitnessTableAccessFunction(const ProtocolConformance *C, + AssociatedTypeDecl *associate, + ProtocolDecl *associateProtocol) { + LinkEntity entity; + entity.setForProtocolConformanceAndAssociatedType( + Kind::AssociatedTypeWitnessTableAccessFunction, C, associate, + associateProtocol); + return entity; + } + void mangle(llvm::raw_ostream &out) const; void mangle(SmallVectorImpl &buffer) const; @@ -436,6 +525,18 @@ class LinkEntity { assert(isProtocolConformanceKind(getKind())); return reinterpret_cast(SecondaryPointer); } + + AssociatedTypeDecl *getAssociatedType() const { + assert(getKind() == Kind::AssociatedTypeMetadataAccessFunction || + getKind() == Kind::AssociatedTypeWitnessTableAccessFunction); + return getAssociatedTypeByIndex(getProtocolConformance(), + LINKENTITY_GET_FIELD(Data, AssociatedTypeIndex)); + } + + ProtocolDecl *getAssociatedProtocol() const { + assert(getKind() == Kind::AssociatedTypeWitnessTableAccessFunction); + return reinterpret_cast(Pointer); + } ResilienceExpansion getResilienceExpansion() const { assert(isDeclKind(getKind())); diff --git a/lib/IRGen/LoadableTypeInfo.h b/lib/IRGen/LoadableTypeInfo.h index 29e1bbec3ad3e..17d78762a2628 100644 --- a/lib/IRGen/LoadableTypeInfo.h +++ b/lib/IRGen/LoadableTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -113,7 +113,7 @@ class LoadableTypeInfo : public FixedTypeInfo { virtual void consume(IRGenFunction &IGF, Explosion &explosion) const = 0; /// Fix the lifetime of the source explosion by creating opaque calls to - /// swift_keepAlive for all reference types in the explosion. + /// swift_fixLifetime for all reference types in the explosion. virtual void fixLifetime(IRGenFunction &IGF, Explosion &explosion) const = 0; /// Pack the source explosion into an enum payload. @@ -129,7 +129,7 @@ class LoadableTypeInfo : public FixedTypeInfo { Explosion &targetExplosion, unsigned offset) const = 0; - /// Load a a reference counted pointer from an address. + /// Load a reference counted pointer from an address. /// Return the loaded pointer value. virtual LoadedRef loadRefcountedPtr(IRGenFunction &IGF, SourceLoc loc, Address addr) const; diff --git a/lib/IRGen/LocalTypeData.cpp b/lib/IRGen/LocalTypeData.cpp new file mode 100644 index 0000000000000..bc825673d922b --- /dev/null +++ b/lib/IRGen/LocalTypeData.cpp @@ -0,0 +1,346 @@ +//===--- LocalTypeData.cpp - Local type data search -----------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file implements routines for finding and caching local type data +// for a search. +// +//===----------------------------------------------------------------------===// + +#include "LocalTypeData.h" +#include "Fulfillment.h" +#include "GenMeta.h" +#include "IRGenFunction.h" +#include "IRGenModule.h" +#include "swift/SIL/SILModule.h" + +using namespace swift; +using namespace irgen; + +LocalTypeDataCache &IRGenFunction::getOrCreateLocalTypeData() { + // Lazily allocate it. + if (LocalTypeData) return *LocalTypeData; + LocalTypeData = new LocalTypeDataCache(); + return *LocalTypeData; +} + +void IRGenFunction::destroyLocalTypeData() { + delete LocalTypeData; +} + +unsigned LocalTypeDataCache::CacheEntry::cost() const { + switch (getKind()) { + case Kind::Concrete: + return static_cast(this)->cost(); + case Kind::Abstract: + return static_cast(this)->cost(); + } + llvm_unreachable("bad cache entry kind"); +} + +void LocalTypeDataCache::CacheEntry::erase() const { + switch (getKind()) { + case Kind::Concrete: + delete static_cast(this); + return; + case Kind::Abstract: + delete static_cast(this); + return; + } + llvm_unreachable("bad cache entry kind"); +} + +llvm::Value *IRGenFunction::getLocalTypeData(CanType type, + LocalTypeDataKind kind) { + assert(LocalTypeData); + return LocalTypeData->get(*this, LocalTypeDataCache::getKey(type, kind)); +} + +llvm::Value *IRGenFunction::tryGetLocalTypeData(CanType type, + LocalTypeDataKind kind) { + if (!LocalTypeData) return nullptr; + return LocalTypeData->tryGet(*this, LocalTypeDataCache::getKey(type, kind)); +} + +llvm::Value *LocalTypeDataCache::tryGet(IRGenFunction &IGF, Key key) { + auto it = Map.find(key); + if (it == Map.end()) return nullptr; + auto &chain = it->second; + + CacheEntry *best = nullptr, *bestPrev = nullptr; + Optional bestCost; + + CacheEntry *next = chain.Root, *nextPrev = nullptr; + while (next) { + CacheEntry *cur = next, *curPrev = nextPrev; + nextPrev = cur; + next = cur->getNext(); + + // Ignore unacceptable entries. + if (!IGF.isActiveDominancePointDominatedBy(cur->DefinitionPoint)) + continue; + + // If there's a collision, compare by cost, ignoring higher-cost entries. + if (best) { + // Compute the cost of the best entry if we haven't done so already. + // If that's zero, go ahead and short-circuit out. + if (!bestCost) { + bestCost = best->cost(); + if (*bestCost == 0) break; + } + + auto curCost = cur->cost(); + if (curCost >= *bestCost) continue; + + // Replace the best cost and fall through. + bestCost = curCost; + } + best = cur; + bestPrev = curPrev; + } + + // If we didn't find anything, we're done. + if (!best) return nullptr; + + // Okay, we've found the best entry available. + switch (best->getKind()) { + + // For concrete caches, this is easy. + case CacheEntry::Kind::Concrete: + return static_cast(best)->Value; + + // For abstract caches, we need to follow a path. + case CacheEntry::Kind::Abstract: { + auto entry = static_cast(best); + + // Follow the path. + auto &source = AbstractSources[entry->SourceIndex]; + auto result = entry->follow(IGF, source); + + // Make a new concrete entry at the active definition point. + + // Register with the active ConditionalDominanceScope if necessary. + bool isConditional = IGF.isConditionalDominancePoint(); + if (isConditional) { + IGF.registerConditionalLocalTypeDataKey(key); + } + + // Allocate the new entry. + auto newEntry = + new ConcreteCacheEntry(IGF.getActiveDominancePoint(), + isConditional, result); + + // If the active definition point is the same as the old entry's + // definition point, delete the old entry. + if (best->DefinitionPoint == IGF.getActiveDominancePoint() && + !best->isConditional()) { + chain.eraseEntry(bestPrev, best); + } + + // Add the new entry to the front of the chain. + chain.push_front(newEntry); + + return result; + } + + } + llvm_unreachable("bad cache entry kind"); +} + +llvm::Value * +LocalTypeDataCache::AbstractCacheEntry::follow(IRGenFunction &IGF, + AbstractSource &source) const { + switch (source.getKind()) { + case AbstractSource::Kind::TypeMetadata: + return Path.followFromTypeMetadata(IGF, source.getType(), + source.getValue(), &source.getCache()); + + case AbstractSource::Kind::WitnessTable: + return Path.followFromWitnessTable(IGF, source.getProtocol(), + source.getValue(), &source.getCache()); + } + llvm_unreachable("bad source kind"); +} + +void IRGenFunction::setScopedLocalTypeData(CanType type, LocalTypeDataKind kind, + llvm::Value *data) { + auto key = LocalTypeDataCache::getKey(type, kind); + + // Register with the active ConditionalDominanceScope if necessary. + bool isConditional = isConditionalDominancePoint(); + if (isConditional) { + registerConditionalLocalTypeDataKey(key); + } + + getOrCreateLocalTypeData().addConcrete(getActiveDominancePoint(), + isConditional, key, data); +} + +void IRGenFunction::setUnscopedLocalTypeData(CanType type, + LocalTypeDataKind kind, + llvm::Value *data) { + getOrCreateLocalTypeData() + .addConcrete(DominancePoint::universal(), /*conditional*/ false, + LocalTypeDataCache::getKey(type, kind), data); +} + +void IRGenFunction::addLocalTypeDataForTypeMetadata(CanType type, + IsExact_t isExact, + llvm::Value *metadata) { + // Remember that we have this type metadata concretely. + if (isExact) { + setScopedLocalTypeData(type, LocalTypeDataKind::forMetatype(), metadata); + } + + // Don't bother adding abstract fulfillments at a conditional dominance + // point; we're too likely to throw them all away. + if (isConditionalDominancePoint()) + return; + + getOrCreateLocalTypeData() + .addAbstractForTypeMetadata(*this, type, isExact, metadata); +} + +void LocalTypeDataCache::addAbstractForTypeMetadata(IRGenFunction &IGF, + CanType type, + IsExact_t isExact, + llvm::Value *metadata) { + // Look for anything at all that's fulfilled by this. If we don't find + // anything, stop. + FulfillmentMap fulfillments; + if (!fulfillments.searchTypeMetadata(*IGF.IGM.SILMod->getSwiftModule(), + type, isExact, + /*source*/ 0, MetadataPath(), + FulfillmentMap::Everything())) { + return; + } + + addAbstractForFulfillments(IGF, std::move(fulfillments), + [&]() -> AbstractSource { + return AbstractSource(AbstractSource::Kind::TypeMetadata, type, metadata); + }); +} + +void LocalTypeDataCache:: +addAbstractForFulfillments(IRGenFunction &IGF, FulfillmentMap &&fulfillments, + llvm::function_ref createSource) { + // Add the source lazily. + Optional sourceIndex; + auto getSourceIndex = [&]() -> unsigned { + if (!sourceIndex) { + AbstractSources.emplace_back(createSource()); + sourceIndex = AbstractSources.size() - 1; + } + return *sourceIndex; + }; + + for (auto &fulfillment : fulfillments) { + CanType type = CanType(fulfillment.first.first); + LocalTypeDataKind localDataKind; + + // For now, ignore witness-table fulfillments when they're not for + // archetypes. + if (ProtocolDecl *protocol = fulfillment.first.second) { + if (auto archetype = dyn_cast(type)) { + auto conformsTo = archetype->getConformsTo(); + auto it = std::find(conformsTo.begin(), conformsTo.end(), protocol); + if (it == conformsTo.end()) continue; + localDataKind =LocalTypeDataKind::forArchetypeProtocolWitnessTable(*it); + } else { + continue; + } + + } else { + // Ignore type metadata fulfillments for non-dependent types that + // we can produce very cheaply. We don't want to end up emitting + // the type metadata for Int by chasing through N layers of metadata + // just because that path happens to be in the cache. + if (!type->hasArchetype() && + getTypeMetadataAccessStrategy(IGF.IGM, type, /*preferDirect*/ true) + == MetadataAccessStrategy::Direct) { + continue; + } + + localDataKind = LocalTypeDataKind::forMetatype(); + } + + // Find the chain for the key. + auto key = getKey(type, localDataKind); + auto &chain = Map[key]; + + // Check whether there's already an entry that's at least as good as the + // fulfillment. + Optional fulfillmentCost; + auto getFulfillmentCost = [&]() -> unsigned { + if (!fulfillmentCost) + fulfillmentCost = fulfillment.second.Path.cost(); + return *fulfillmentCost; + }; + + bool foundBetter = false; + for (CacheEntry *cur = chain.Root, *last = nullptr; cur; + last = cur, cur = cur->getNext()) { + // Ensure the entry is acceptable. + if (!IGF.isActiveDominancePointDominatedBy(cur->DefinitionPoint)) + continue; + + // Ensure that the entry isn't better than the fulfillment. + auto curCost = cur->cost(); + if (curCost == 0 || curCost <= getFulfillmentCost()) { + foundBetter = true; + break; + } + + // If the entry is defined at the current point, (1) we know there + // won't be a better entry and (2) we should remove it. + if (cur->DefinitionPoint == IGF.getActiveDominancePoint() && + !cur->isConditional()) { + // Splice it out of the chain. + chain.eraseEntry(last, cur); + break; + } + } + if (foundBetter) continue; + + // Okay, make a new entry. + + // Register with the conditional dominance scope if necessary. + bool isConditional = IGF.isConditionalDominancePoint(); + if (isConditional) { + IGF.registerConditionalLocalTypeDataKey(key); + } + + // Allocate the new entry. + auto newEntry = new AbstractCacheEntry(IGF.getActiveDominancePoint(), + isConditional, + getSourceIndex(), + std::move(fulfillment.second.Path)); + + // Add it to the front of the chain. + chain.push_front(newEntry); + } +} + +void IRGenFunction::unregisterConditionalLocalTypeDataKeys( + ArrayRef keys) { + assert(!keys.empty()); + assert(LocalTypeData); + LocalTypeData->eraseConditional(keys); +} + +void LocalTypeDataCache::eraseConditional(ArrayRef keys) { + for (auto &key : keys) { + auto &chain = Map[key]; + assert(chain.Root); + assert(chain.Root->isConditional()); + chain.eraseEntry(nullptr, chain.Root); + } +} diff --git a/lib/IRGen/LocalTypeData.h b/lib/IRGen/LocalTypeData.h new file mode 100644 index 0000000000000..ed70c02e7da6b --- /dev/null +++ b/lib/IRGen/LocalTypeData.h @@ -0,0 +1,265 @@ +//===--- LocalTypeData.h - Dominance-scoped type data -----------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines types relating to the local caching of type data, +// such as type metadata, value witness tables, and protocol witness tables. +// +// Type data may be cached concretely, meaning that it was already fully +// computed, or abstractly, meaning that we remember how to recreate it +// but haven't actually done so yet. +// +// Type data may be cached at different points within a function. +// Some of these points may not dominate all possible use sites. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_LOCALTYPEDATA_H +#define SWIFT_IRGEN_LOCALTYPEDATA_H + +#include "LocalTypeDataKind.h" +#include "DominancePoint.h" +#include "MetadataPath.h" +#include "swift/AST/Type.h" +#include "llvm/ADT/STLExtras.h" +#include + +namespace swift { + class TypeBase; + +namespace irgen { + class FulfillmentMap; + enum IsExact_t : bool; + + +/// A cache of local type data. +/// +/// Basic design considerations: +/// +/// - We want to be able to efficiently look up a key and find something. +/// Generally this will find something from the entry block. We shouldn't +/// have to scan all the dominating points first. +/// +/// - We don't expect to have multiple definitions for a key very often. +/// Therefore, given a collision, it should be okay to scan a list and +/// ask whether each is acceptable. +class LocalTypeDataCache { +public: + using Key = LocalTypeDataKey; + + static Key getKey(CanType type, LocalTypeDataKind index) { + return { type, index }; + } + +private: + struct CacheEntry { + enum class Kind { + Concrete, Abstract + }; + + DominancePoint DefinitionPoint; + + private: + enum { KindMask = 0x1, ConditionalMask = 0x2 }; + llvm::PointerIntPair NextAndFlags; + + public: + Kind getKind() const { + return Kind(NextAndFlags.getInt() & KindMask); + } + CacheEntry *getNext() const { return NextAndFlags.getPointer(); } + void setNext(CacheEntry *next) { NextAndFlags.setPointer(next); } + + /// Return the abstract cost of evaluating this cache entry. + unsigned cost() const; + + /// Destruct and deallocate this cache entry. + void erase() const; + + bool isConditional() const { + return NextAndFlags.getInt() & ConditionalMask; + } + + protected: + CacheEntry(Kind kind, DominancePoint point, bool isConditional) + : DefinitionPoint(point), + NextAndFlags(nullptr, + unsigned(kind) | (isConditional ? ConditionalMask : 0)) { + } + ~CacheEntry() = default; + }; + + /// A concrete entry in the cache, which directly stores the desired value. + struct ConcreteCacheEntry : CacheEntry { + llvm::Value *Value; + + ConcreteCacheEntry(DominancePoint point, bool isConditional, + llvm::Value *value) + : CacheEntry(Kind::Concrete, point, isConditional), Value(value) {} + + unsigned cost() const { return 0; } + }; + + /// A source of concrete data from which abstract cache entries can be + /// derived. + class AbstractSource { + public: + enum class Kind { + /// Type metadata. The payload is a CanType. + TypeMetadata, + + /// A protocol witness table. The payload is a ProtocolDecl*. + WitnessTable, + }; + + private: + uintptr_t Payload; + MetadataPath::Map Cache; + llvm::Value *Value; + + enum : uintptr_t { KindMask = 0x3 }; + + explicit AbstractSource(Kind kind, void *ptr, llvm::Value *value) + : Payload(uintptr_t(ptr) | unsigned(kind)), Value(value) {} + + public: + explicit AbstractSource(Kind kind, CanType type, llvm::Value *metadata) + : AbstractSource(kind, type.getPointer(), metadata) {} + explicit AbstractSource(Kind kind, ProtocolDecl *protocol, + llvm::Value *witnessTable) + : AbstractSource(kind, (void*) protocol, witnessTable) {} + + Kind getKind() const { + return Kind(Payload & KindMask); + } + + CanType getType() const { + assert(getKind() == Kind::TypeMetadata); + return CanType(reinterpret_cast(Payload & ~KindMask)); + } + ProtocolDecl *getProtocol() const { + assert(getKind() == Kind::WitnessTable); + return reinterpret_cast(Payload & ~KindMask); + } + + llvm::Value *getValue() const { + return Value; + } + + MetadataPath::Map &getCache() { + return Cache; + } + }; + + /// An abstract entry in the cache, which requires some amount of + /// non-trivial evaluation to derive the desired value. + struct AbstractCacheEntry : CacheEntry { + unsigned SourceIndex; + MetadataPath Path; + + AbstractCacheEntry(DominancePoint point, bool isConditional, + unsigned sourceIndex, MetadataPath &&path) + : CacheEntry(Kind::Abstract, point, isConditional), + SourceIndex(sourceIndex), Path(std::move(path)) {} + + llvm::Value *follow(IRGenFunction &IGF, AbstractSource &source) const; + + unsigned cost() const { return Path.cost(); } + }; + + /// The linked list of cache entries corresponding to a particular key. + struct CacheEntryChain { + CacheEntry *Root; + + explicit CacheEntryChain(CacheEntry *root = nullptr) : Root(root) {} + + CacheEntryChain(const CacheEntryChain &other) = delete; + CacheEntryChain &operator=(const CacheEntryChain &other) = delete; + + CacheEntryChain(CacheEntryChain &&other) : Root(other.Root) { + other.Root = nullptr; + } + CacheEntryChain &operator=(CacheEntryChain &&other) { + Root = other.Root; + other.Root = nullptr; + return *this; + } + + void push_front(CacheEntry *entry) { + entry->setNext(Root); + Root = entry; + } + + void eraseEntry(CacheEntry *prev, CacheEntry *entry) { + if (prev) { + assert(prev->getNext() == entry); + prev->setNext(entry->getNext()); + } else { + assert(Root == entry); + Root = entry->getNext(); + } + entry->erase(); + } + + /// Delete the linked list. + ~CacheEntryChain() { + auto next = Root; + while (next) { + auto cur = next; + next = cur->getNext(); + cur->erase(); + } + } + }; + + llvm::DenseMap Map; + + std::vector AbstractSources; + + void addAbstractForFulfillments(IRGenFunction &IGF, + FulfillmentMap &&fulfillments, + llvm::function_ref createSource); + + +public: + LocalTypeDataCache() = default; + LocalTypeDataCache(const LocalTypeDataCache &other) = delete; + LocalTypeDataCache &operator=(const LocalTypeDataCache &other) = delete; + + /// Load the value from cache if possible. This may require emitting + /// code if the value is cached abstractly. + llvm::Value *tryGet(IRGenFunction &IGF, Key key); + + /// Load the value from cache, asserting its presence. + llvm::Value *get(IRGenFunction &IGF, Key key) { + auto result = tryGet(IGF, key); + assert(result && "get() on unmapped entry?"); + return result; + } + + /// Add a new concrete entry to the cache at the given definition point. + void addConcrete(DominancePoint point, bool isConditional, + Key key, llvm::Value *value) { + auto newEntry = new ConcreteCacheEntry(point, isConditional, value); + Map[key].push_front(newEntry); + } + + /// Add entries based on what can be fulfilled from the given type metadata. + void addAbstractForTypeMetadata(IRGenFunction &IGF, CanType type, + IsExact_t isExact, llvm::Value *metadata); + + void eraseConditional(ArrayRef keys); +}; + +} +} + +#endif diff --git a/lib/IRGen/LocalTypeDataCache.h b/lib/IRGen/LocalTypeDataCache.h new file mode 100644 index 0000000000000..0f726946bdda4 --- /dev/null +++ b/lib/IRGen/LocalTypeDataCache.h @@ -0,0 +1,141 @@ +//===-- LocalTypeDataCache.h - Dominance-scoped type data cache -*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines the LocalTypeDataCache type, which is used by +// IRGenFunction to cache the information available for types in a local +// context. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_LOCALTYPEDATACACHE_H +#define SWIFT_IRGEN_LOCALTYPEDATACACHE_H + +#include "swift/AST/Type.h" +#include + +namespace swift { +class TypeBase; + +namespace irgen { +enum class ValueWitness : unsigned; + +/// A nonce value for storing some sort of locally-known information +/// about a type. +class LocalTypeData { +public: + using RawType = unsigned; +private: + RawType Value; + + explicit LocalTypeData(unsigned Value) : Value(Value) {} + + /// Magic values for special kinds of index. + enum : RawType { + Metatype = ~0U, + ValueWitnessTable = ~1U, + + ValueWitnessBase = 0xFFFFFF00U, + }; + +public: + LocalTypeData() = default; + + // The magic values are all in the "negative" range and so do + // not collide with reasonable index values. + + /// A reference to the type metadata. + static LocalTypeData forMetatype() { return LocalTypeData(Metatype); } + /// A reference to the value witness table. + static LocalTypeData forValueWitnessTable() { + return LocalTypeData(ValueWitnessTable); + } + + /// A reference to a specific value witness. + static LocalTypeData forValueWitness(ValueWitness witness) { + return LocalTypeData((unsigned)witness + ValueWitnessBase); + } + + /// A reference to a protocol witness table for an archetype. + static LocalTypeData forArchetypeProtocolWitness(unsigned index) { + return LocalTypeData(index); + } + + RawType getRawValue() const { + return Value; + } +}; + +class LocalTypeDataCache { +public: + using Key = std::pair; + + static Key getKey(CanType type, LocalTypeData index) { + return Key(type.getPointer(), index.getRawValue()); + } + + /// An opaque class for storing keys for the dominance callback. The + /// key is assumed to be something like a pointer, and a null pointer is + /// assumed to mean a non-dominating point. + class DominanceKey { + void *Value; + public: + explicit DominanceKey(void *value = nullptr) : Value(value) {} + template T* as() const { return reinterpret_cast(Value); } + explicit operator bool() const { return Value != nullptr; } + }; + + /// A RAII object for managing a dominance scope. + class DominanceScope { + LocalTypeDataCache &Cache; + DominanceKey OldDefinitionPoint; + public: + explicit DominanceScope(LocalTypeDataCache &cache, DominanceKey newPoint) + : Cache(cache), OldDefinitionPoint(cache.ActiveDefinitionPoint) { + cache.ActiveDefinitionPoint = newPoint; + assert(!newPoint || cache.Callback); + } + + DominanceScope(const DominanceScope &other) = delete; + DominanceScope &operator=(const DominanceScope &other) = delete; + + ~DominanceScope() { + Cache.ActiveDefinitionPoint = OldDefinitionPoint; + } + }; + + using DominanceCallback = bool(IRGenFunction &IGF, DominanceKey key); + +private: + /// The dominance callback. This can be set at most once; when it's not + /// set, the cache must never have a non-null active definition point. + DominanceCallback *Callback = nullptr; + DominanceKey ActiveDefinitionPoint; + + struct CacheEntryBase { + DominanceKey DefinitionPoint; + + }; + + struct Source { + llvm::Value *Value; + MetadataPath::Map Path; + }; + + std::vector< + +public: +}; + +} +} + +#endif diff --git a/lib/IRGen/LocalTypeDataKind.h b/lib/IRGen/LocalTypeDataKind.h new file mode 100644 index 0000000000000..03512a17bcba7 --- /dev/null +++ b/lib/IRGen/LocalTypeDataKind.h @@ -0,0 +1,139 @@ +//===-- LocalTypeDataKind.h - Kinds of locally-cached type data -*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file defines the LocalTypeDataKind class, which opaquely +// represents a particular kind of local type data that we might +// want to cache during emission. +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_LOCALTYPEDATAKIND_H +#define SWIFT_IRGEN_LOCALTYPEDATAKIND_H + +#include "swift/AST/Type.h" +#include +#include "llvm/ADT/DenseMapInfo.h" + +namespace swift { + class NormalProtocolConformance; + class ProtocolDecl; + +namespace irgen { + enum class ValueWitness : unsigned; + +/// The kind of local type data we might want to store for a type. +class LocalTypeDataKind { +public: + using RawType = uintptr_t; +private: + RawType Value; + + explicit LocalTypeDataKind(unsigned Value) : Value(Value) {} + + /// Magic values for special kinds of type metadata. These should be + /// small so that they should never conflict with a valid pointer. + /// + /// Since this representation is opaque, we don't worry about being able + /// to distinguish different kinds of pointer; we just assume that e.g. a + /// ProtocolConformance will never have the same address as a Decl. + enum : RawType { + Metatype, + ValueWitnessTable, + // <- add more special cases here + + // The first enumerator for an individual value witness. + ValueWitnessBase, + }; + +public: + LocalTypeDataKind() = default; + + // The magic values are all odd and so do not collide with pointer values. + + /// A reference to the type metadata. + static LocalTypeDataKind forMetatype() { + return LocalTypeDataKind(Metatype); + } + + /// A reference to the value witness table. + static LocalTypeDataKind forValueWitnessTable() { + return LocalTypeDataKind(ValueWitnessTable); + } + + /// A reference to a specific value witness. + static LocalTypeDataKind forValueWitness(ValueWitness witness) { + return LocalTypeDataKind(ValueWitnessBase + (unsigned)witness); + } + + /// A reference to a protocol witness table for an archetype. + /// + /// This only works for non-concrete types because in principle we might + /// have multiple concrete conformances for a concrete type used in the + /// same function. + static LocalTypeDataKind + forArchetypeProtocolWitnessTable(ProtocolDecl *protocol) { + return LocalTypeDataKind(uintptr_t(protocol)); + } + + /// A reference to a protocol witness table for an archetype. + /// + /// We assume that the protocol conformance is a sufficiently unique key. + /// This implicitly assumes that we don't care about having multiple + /// specializations of a conditional conformance for different + /// conformances. + static LocalTypeDataKind + forConcreteProtocolWitnessTable(NormalProtocolConformance *conformance) { + return LocalTypeDataKind(uintptr_t(conformance)); + } + + RawType getRawValue() const { + return Value; + } + + bool operator==(LocalTypeDataKind other) const { + return Value == other.Value; + } +}; + +struct LocalTypeDataKey { + CanType Type; + LocalTypeDataKind Kind; + + bool operator==(const LocalTypeDataKey &other) const { + return Type == other.Type && Kind == other.Kind; + } +}; + +} +} + +template <> struct llvm::DenseMapInfo { + using LocalTypeDataKey = swift::irgen::LocalTypeDataKey; + using CanTypeInfo = DenseMapInfo; + static inline LocalTypeDataKey getEmptyKey() { + return { CanTypeInfo::getEmptyKey(), + swift::irgen::LocalTypeDataKind::forMetatype() }; + } + static inline LocalTypeDataKey getTombstoneKey() { + return { CanTypeInfo::getTombstoneKey(), + swift::irgen::LocalTypeDataKind::forMetatype() }; + } + static unsigned getHashValue(const LocalTypeDataKey &key) { + return combineHashValue(CanTypeInfo::getHashValue(key.Type), + key.Kind.getRawValue()); + } + static bool isEqual(const LocalTypeDataKey &a, const LocalTypeDataKey &b) { + return a == b; + } +}; + +#endif diff --git a/lib/IRGen/MetadataLayout.h b/lib/IRGen/MetadataLayout.h index ed1f6f94603c0..687039ed1ed8d 100644 --- a/lib/IRGen/MetadataLayout.h +++ b/lib/IRGen/MetadataLayout.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/MetadataPath.h b/lib/IRGen/MetadataPath.h index a98a34ee8ee8b..79fc99a5d67cf 100644 --- a/lib/IRGen/MetadataPath.h +++ b/lib/IRGen/MetadataPath.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// // // This file defines the MetadataPath type, which efficiently records the -// path to an metadata object. +// path to a metadata object. // //===----------------------------------------------------------------------===// @@ -25,7 +25,9 @@ namespace llvm { } namespace swift { + class ProtocolDecl; class CanType; + class Decl; namespace irgen { class IRGenFunction; @@ -46,6 +48,9 @@ class MetadataPath { // Everything past this point has at most one index. + /// Base protocol P of a protocol. + InheritedProtocol, + /// Type argument P of a generic nominal type. NominalTypeArgument, LastWithPrimaryIndex = NominalTypeArgument, @@ -168,6 +173,14 @@ class MetadataPath { argIndex, conformanceIndex)); } + /// Add a step to this path which gets the kth inherited protocol from a + /// witness table. + /// + /// k is computed including protocols which do not have witness tables. + void addInheritedProtocolComponent(unsigned index) { + Path.push_back(Component(Component::Kind::InheritedProtocol, index)); + } + /// Return an abstract measurement of the cost of this path. unsigned cost() const { unsigned cost = 0; diff --git a/lib/IRGen/NecessaryBindings.h b/lib/IRGen/NecessaryBindings.h index 1a41cb2b86f6a..2cb22ef180f8e 100644 --- a/lib/IRGen/NecessaryBindings.h +++ b/lib/IRGen/NecessaryBindings.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/NonFixedTypeInfo.h b/lib/IRGen/NonFixedTypeInfo.h index 4e76f0179048c..65c4e9be40445 100644 --- a/lib/IRGen/NonFixedTypeInfo.h +++ b/lib/IRGen/NonFixedTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,7 +15,7 @@ // statically. // // These classes are useful only for creating TypeInfo -// implementations; unlike the similiarly-named FixedTypeInfo, they +// implementations; unlike the similarly-named FixedTypeInfo, they // do not provide a supplemental API. // //===----------------------------------------------------------------------===// @@ -62,6 +62,7 @@ class WitnessSizedTypeInfo : public IndirectTypeInfo { const llvm::Twine &name) const override { // Make a fixed-size buffer. Address buffer = IGF.createFixedSizeBufferAlloca(name); + IGF.Builder.CreateLifetimeStart(buffer, getFixedBufferSize(IGF.IGM)); // Allocate an object of the appropriate type within it. llvm::Value *address = emitAllocateBufferCall(IGF, T, buffer); @@ -71,6 +72,7 @@ class WitnessSizedTypeInfo : public IndirectTypeInfo { void deallocateStack(IRGenFunction &IGF, Address buffer, SILType T) const override { emitDeallocateBufferCall(IGF, T, buffer); + IGF.Builder.CreateLifetimeEnd(buffer, getFixedBufferSize(IGF.IGM)); } llvm::Value *getValueWitnessTable(IRGenFunction &IGF, SILType T) const { diff --git a/lib/IRGen/ProtocolInfo.h b/lib/IRGen/ProtocolInfo.h index 1b98a7838ae52..b827b812cda57 100644 --- a/lib/IRGen/ProtocolInfo.h +++ b/lib/IRGen/ProtocolInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -124,6 +124,20 @@ class WitnessTableEntry { assert(isAssociatedType()); return BeginIndex; } + + WitnessIndex + getAssociatedTypeWitnessTableIndex(ProtocolDecl *target) const { + assert(!BeginIndex.isPrefix()); + auto index = BeginIndex.getValue() + 1; + for (auto protocol : + cast(Member)->getConformingProtocols(nullptr)) { + if (protocol == target) { + return WitnessIndex(index, false); + } + index++; + } + llvm_unreachable("protocol not in direct conformance list?"); + } }; /// An abstract description of a protocol. @@ -164,17 +178,14 @@ class ProtocolInfo { ProtocolDecl *protocol, const ProtocolConformance *conf) const; + /// The number of witness slots in a conformance to this protocol; + /// in other words, the size of the table in words. unsigned getNumWitnesses() const { return NumWitnesses; } - unsigned getNumTableEntries() const { - return NumTableEntries; - } - ArrayRef getWitnessEntries() const { - return ArrayRef(getEntriesBuffer(), - getNumTableEntries()); + return ArrayRef(getEntriesBuffer(), NumTableEntries); } const WitnessTableEntry &getWitnessEntry(Decl *member) const { diff --git a/lib/IRGen/ReferenceTypeInfo.h b/lib/IRGen/ReferenceTypeInfo.h index 3936a24ece2e2..1459ea71d6131 100644 --- a/lib/IRGen/ReferenceTypeInfo.h +++ b/lib/IRGen/ReferenceTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -40,20 +40,45 @@ class ReferenceTypeInfo : public LoadableTypeInfo { public: /// Strongly retains a value. - virtual void retain(IRGenFunction &IGF, Explosion &explosion) const = 0; + virtual void strongRetain(IRGenFunction &IGF, Explosion &in) const = 0; /// Strongly releases a value. - virtual void release(IRGenFunction &IGF, Explosion &explosion) const = 0; + virtual void strongRelease(IRGenFunction &IGF, Explosion &in) const = 0; /// Strongly retains a value that has come from a safe [unowned] reference. - virtual void retainUnowned(IRGenFunction &IGF, Explosion &in) const = 0; + /// This operation is not supported for all reference types. + virtual void strongRetainUnowned(IRGenFunction &IGF, Explosion &in) const = 0; + + /// Strongly retains a value that has come from a safe [unowned] reference. + /// This operation is not supported for all reference types. + virtual void strongRetainUnownedRelease(IRGenFunction &IGF, + Explosion &in) const = 0; /// Weakly retains a value in the manner of a safe [unowned] reference. + /// This operation is not supported for all reference types. virtual void unownedRetain(IRGenFunction &IGF, Explosion &in) const = 0; /// Weakly releases a value in the manner of a safe [unowned] reference. + /// This operation is not supported for all reference types. virtual void unownedRelease(IRGenFunction &IGF, Explosion &in) const = 0; + /// Load a reference from a safe [unowned] reference in memory and + /// destroy the [unowned] location. + virtual void unownedTakeStrong(IRGenFunction &IGF, Address addr, + Explosion &out) const = 0; + + /// Load a reference from a safe [unowned] reference in memory. + virtual void unownedLoadStrong(IRGenFunction &IGF, Address addr, + Explosion &out) const = 0; + + /// Initialize a safe [unowned] reference in memory. + virtual void unownedInit(IRGenFunction &IGF, Explosion &in, + Address dest) const = 0; + + /// Assign to an initialized safe [unowned] reference in memory. + virtual void unownedAssign(IRGenFunction &IGF, Explosion &in, + Address dest) const = 0; + /// Produce the storage information for [weak] storage. virtual const WeakTypeInfo *createWeakStorageType(TypeConverter &TC) const = 0; @@ -62,7 +87,7 @@ class ReferenceTypeInfo : public LoadableTypeInfo { /// The reference-counting operations done by the value operations /// on the [unowned] storage type are assumed to be basically the /// same operations as weakRetain and weakRelease. - virtual const UnownedTypeInfo *createUnownedStorageType(TypeConverter &TC) + virtual const TypeInfo *createUnownedStorageType(TypeConverter &TC) const = 0; /// Produce the storage information for @unowned(unsafe) storage. diff --git a/lib/IRGen/ResilientTypeInfo.h b/lib/IRGen/ResilientTypeInfo.h index 158f19b7d1d62..e7d536e26186a 100644 --- a/lib/IRGen/ResilientTypeInfo.h +++ b/lib/IRGen/ResilientTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/RuntimeFunctions.def b/lib/IRGen/RuntimeFunctions.def index 3752dbc6159f2..cdc8c92db07e0 100644 --- a/lib/IRGen/RuntimeFunctions.def +++ b/lib/IRGen/RuntimeFunctions.def @@ -1,8 +1,8 @@ -//===-- RuntimeFunctions.def - Runtime Functions Database -------*- C++ -*-===// +//===--- RuntimeFunctions.def - Runtime Functions Database ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,7 +17,7 @@ /// FUNCTION(Id, Name, ReturnTys, ArgTys, CC, Attrs) /// Makes available as "Id" the following runtime function: -/// ReturnTy Name(ArgsTys...); +/// ReturnTy Name(ArgTys...); /// ReturnTys is a call to RETURNS, which takes a non-empty list /// of expressions meant to be looked up in IRGenModule. /// ArgTys is either NO_ARGS or a call to ARGS, which takes a non-empty @@ -127,31 +127,25 @@ FUNCTION(CopyPOD, swift_copyPOD, RuntimeCC, ATTRS(NoUnwind)) // void swift_retain(void *ptr); -FUNCTION(Retain, swift_retain, RuntimeCC, +FUNCTION(NativeStrongRetain, swift_retain, RuntimeCC, RETURNS(VoidTy), ARGS(RefCountedPtrTy), ATTRS(NoUnwind)) // void swift_release(void *ptr); -FUNCTION(Release, swift_release, RuntimeCC, +FUNCTION(NativeStrongRelease, swift_release, RuntimeCC, RETURNS(VoidTy), ARGS(RefCountedPtrTy), ATTRS(NoUnwind)) // void *swift_tryPin(void *ptr); -FUNCTION(TryPin, swift_tryPin, RuntimeCC, +FUNCTION(NativeTryPin, swift_tryPin, RuntimeCC, RETURNS(RefCountedPtrTy), ARGS(RefCountedPtrTy), ATTRS(NoUnwind)) // void swift_unpin(void *ptr); -FUNCTION(Unpin, swift_unpin, RuntimeCC, - RETURNS(VoidTy), - ARGS(RefCountedPtrTy), - ATTRS(NoUnwind)) - -// void swift_fixLifetime(void *ptr); -FUNCTION(FixLifetime, swift_fixLifetime, RuntimeCC, +FUNCTION(NativeUnpin, swift_unpin, RuntimeCC, RETURNS(VoidTy), ARGS(RefCountedPtrTy), ATTRS(NoUnwind)) @@ -159,130 +153,118 @@ FUNCTION(FixLifetime, swift_fixLifetime, RuntimeCC, // void swift_unknownRetain(void *ptr); FUNCTION(UnknownRetain, swift_unknownRetain, RuntimeCC, RETURNS(VoidTy), - ARGS(RefCountedPtrTy), + ARGS(UnknownRefCountedPtrTy), ATTRS(NoUnwind)) // void swift_unknownRelease(void *ptr); FUNCTION(UnknownRelease, swift_unknownRelease, RuntimeCC, RETURNS(VoidTy), - ARGS(RefCountedPtrTy), - ATTRS(NoUnwind)) - - -// void swift_retainUnowned(void *ptr); -FUNCTION(RetainUnowned, swift_retainUnowned, RuntimeCC, - RETURNS(VoidTy), - ARGS(RefCountedPtrTy), + ARGS(UnknownRefCountedPtrTy), ATTRS(NoUnwind)) // void *swift_bridgeObjectRetain(void *ptr); -FUNCTION(BridgeObjectRetain, swift_bridgeObjectRetain, RuntimeCC, +FUNCTION(BridgeObjectStrongRetain, swift_bridgeObjectRetain, RuntimeCC, RETURNS(BridgeObjectPtrTy), ARGS(BridgeObjectPtrTy), ATTRS(NoUnwind)) // void swift_bridgeRelease(void *ptr); -FUNCTION(BridgeObjectRelease, swift_bridgeObjectRelease, RuntimeCC, +FUNCTION(BridgeObjectStrongRelease, swift_bridgeObjectRelease, RuntimeCC, RETURNS(VoidTy), ARGS(BridgeObjectPtrTy), ATTRS(NoUnwind)) // error *swift_errorRetain(error *ptr); -FUNCTION(ErrorRetain, swift_errorRetain, RuntimeCC, +FUNCTION(ErrorStrongRetain, swift_errorRetain, RuntimeCC, RETURNS(ErrorPtrTy), ARGS(ErrorPtrTy), ATTRS(NoUnwind)) // void swift_errorRelease(void *ptr); -FUNCTION(ErrorRelease, swift_errorRelease, RuntimeCC, +FUNCTION(ErrorStrongRelease, swift_errorRelease, RuntimeCC, RETURNS(VoidTy), ARGS(ErrorPtrTy), ATTRS(NoUnwind)) -// void swift_weakRetain(void *ptr); -FUNCTION(UnownedRetain, swift_weakRetain, RuntimeCC, +// void swift_unownedRetain(void *ptr); +FUNCTION(NativeUnownedRetain, swift_unownedRetain, RuntimeCC, + RETURNS(VoidTy), + ARGS(RefCountedPtrTy), + ATTRS(NoUnwind)) + +// void swift_unownedRelease(void *ptr); +FUNCTION(NativeUnownedRelease, swift_unownedRelease,RuntimeCC, RETURNS(VoidTy), ARGS(RefCountedPtrTy), ATTRS(NoUnwind)) -// void swift_weakRelease(void *ptr); -FUNCTION(UnownedRelease, swift_weakRelease,RuntimeCC, +// void swift_unownedRetainStrong(void *ptr); +FUNCTION(NativeStrongRetainUnowned, swift_unownedRetainStrong, RuntimeCC, + RETURNS(VoidTy), + ARGS(RefCountedPtrTy), + ATTRS(NoUnwind)) + +// void swift_unownedRetainStrongAndRelease(void *ptr); +FUNCTION(NativeStrongRetainAndUnownedRelease, + swift_unownedRetainStrongAndRelease, RuntimeCC, RETURNS(VoidTy), ARGS(RefCountedPtrTy), ATTRS(NoUnwind)) // void swift_weakDestroy(WeakReference *object); -FUNCTION(WeakDestroy, swift_weakDestroy, RuntimeCC, +FUNCTION(NativeWeakDestroy, swift_weakDestroy, RuntimeCC, RETURNS(VoidTy), ARGS(WeakReferencePtrTy), ATTRS(NoUnwind)) // void swift_weakInit(WeakReference *object, void *value); -FUNCTION(WeakInit, swift_weakInit, RuntimeCC, +FUNCTION(NativeWeakInit, swift_weakInit, RuntimeCC, RETURNS(VoidTy), ARGS(WeakReferencePtrTy, RefCountedPtrTy), ATTRS(NoUnwind)) // void swift_weakAssign(WeakReference *object, void *value); -FUNCTION(WeakAssign, swift_weakAssign, RuntimeCC, +FUNCTION(NativeWeakAssign, swift_weakAssign, RuntimeCC, RETURNS(VoidTy), ARGS(WeakReferencePtrTy, RefCountedPtrTy), ATTRS(NoUnwind)) // void *swift_weakLoadStrong(WeakReference *object); -FUNCTION(WeakLoadStrong, swift_weakLoadStrong,RuntimeCC, +FUNCTION(NativeWeakLoadStrong, swift_weakLoadStrong,RuntimeCC, RETURNS(RefCountedPtrTy), ARGS(WeakReferencePtrTy), ATTRS(NoUnwind)) // void *swift_weakTakeStrong(WeakReference *object); -FUNCTION(WeakTakeStrong, swift_weakTakeStrong,RuntimeCC, +FUNCTION(NativeWeakTakeStrong, swift_weakTakeStrong,RuntimeCC, RETURNS(RefCountedPtrTy), ARGS(WeakReferencePtrTy), ATTRS(NoUnwind)) // void swift_weakCopyInit(WeakReference *dest, WeakReference *src); -FUNCTION(WeakCopyInit, swift_weakCopyInit, RuntimeCC, +FUNCTION(NativeWeakCopyInit, swift_weakCopyInit, RuntimeCC, RETURNS(VoidTy), ARGS(WeakReferencePtrTy, WeakReferencePtrTy), ATTRS(NoUnwind)) // void swift_weakTakeInit(WeakReference *dest, WeakReference *src); -FUNCTION(WeakTakeInit, swift_weakTakeInit, RuntimeCC, +FUNCTION(NativeWeakTakeInit, swift_weakTakeInit, RuntimeCC, RETURNS(VoidTy), ARGS(WeakReferencePtrTy, WeakReferencePtrTy), ATTRS(NoUnwind)) // void swift_weakCopyAssign(WeakReference *dest, WeakReference *src); -FUNCTION(WeakCopyAssign, swift_weakCopyAssign,RuntimeCC, +FUNCTION(NativeWeakCopyAssign, swift_weakCopyAssign,RuntimeCC, RETURNS(VoidTy), ARGS(WeakReferencePtrTy, WeakReferencePtrTy), ATTRS(NoUnwind)) // void swift_weakTakeAssign(WeakReference *dest, WeakReference *src); -FUNCTION(WeakTakeAssign, swift_weakTakeAssign,RuntimeCC, +FUNCTION(NativeWeakTakeAssign, swift_weakTakeAssign,RuntimeCC, RETURNS(VoidTy), ARGS(WeakReferencePtrTy, WeakReferencePtrTy), ATTRS(NoUnwind)) -// void swift_unknownRetainUnowned(void *ptr); -FUNCTION(UnknownRetainUnowned, swift_unknownRetainUnowned, RuntimeCC, - RETURNS(VoidTy), - ARGS(RefCountedPtrTy), - ATTRS(NoUnwind)) - -// void swift_unknownWeakRetain(void *value); -FUNCTION(UnknownUnownedRetain, swift_unknownWeakRetain, RuntimeCC, - RETURNS(VoidTy), - ARGS(RefCountedPtrTy), - ATTRS(NoUnwind)) - -// void swift_unknownWeakRelease(void *value); -FUNCTION(UnknownUnownedRelease, swift_unknownWeakRelease, RuntimeCC, - RETURNS(VoidTy), - ARGS(RefCountedPtrTy), - ATTRS(NoUnwind)) - // void swift_unknownWeakDestroy(WeakReference *object); FUNCTION(UnknownWeakDestroy, swift_unknownWeakDestroy, RuntimeCC, RETURNS(VoidTy), @@ -331,6 +313,66 @@ FUNCTION(UnknownWeakCopyAssign, swift_unknownWeakCopyAssign,RuntimeCC, ARGS(WeakReferencePtrTy, WeakReferencePtrTy), ATTRS(NoUnwind)) +// void swift_unknownWeakTakeAssign(WeakReference *dest, WeakReference *src); +FUNCTION(UnknownWeakTakeAssign, swift_unknownWeakTakeAssign,RuntimeCC, + RETURNS(VoidTy), + ARGS(WeakReferencePtrTy, WeakReferencePtrTy), + ATTRS(NoUnwind)) + +// void swift_unknownUnownedDestroy(UnownedReference *object); +FUNCTION(UnknownUnownedDestroy, swift_unknownUnownedDestroy, RuntimeCC, + RETURNS(VoidTy), + ARGS(UnownedReferencePtrTy), + ATTRS(NoUnwind)) + +// void swift_unknownUnownedInit(UnownedReference *object, void *value); +FUNCTION(UnknownUnownedInit, swift_unknownUnownedInit, RuntimeCC, + RETURNS(VoidTy), + ARGS(UnownedReferencePtrTy, UnknownRefCountedPtrTy), + ATTRS(NoUnwind)) + +// void swift_unknownUnownedAssign(UnownedReference *object, void *value); +FUNCTION(UnknownUnownedAssign, swift_unknownUnownedAssign, RuntimeCC, + RETURNS(VoidTy), + ARGS(UnownedReferencePtrTy, UnknownRefCountedPtrTy), + ATTRS(NoUnwind)) + +// void *swift_unknownUnownedLoad(UnownedReference *object); +FUNCTION(UnknownUnownedLoadStrong, swift_unknownUnownedLoadStrong,RuntimeCC, + RETURNS(UnknownRefCountedPtrTy), + ARGS(UnownedReferencePtrTy), + ATTRS(NoUnwind)) + +// void *swift_unknownUnownedTake(UnownedReference *object); +FUNCTION(UnknownUnownedTakeStrong, swift_unknownUnownedTakeStrong,RuntimeCC, + RETURNS(UnknownRefCountedPtrTy), + ARGS(UnownedReferencePtrTy), + ATTRS(NoUnwind)) + +// void swift_unknownUnownedCopyInit(UnownedReference *dest, UnownedReference *src); +FUNCTION(UnknownUnownedCopyInit, swift_unknownUnownedCopyInit, RuntimeCC, + RETURNS(VoidTy), + ARGS(UnownedReferencePtrTy, UnownedReferencePtrTy), + ATTRS(NoUnwind)) + +// void swift_unknownUnownedTakeInit(UnownedReference *dest, UnownedReference *src); +FUNCTION(UnknownUnownedTakeInit, swift_unknownUnownedTakeInit, RuntimeCC, + RETURNS(VoidTy), + ARGS(UnownedReferencePtrTy, UnownedReferencePtrTy), + ATTRS(NoUnwind)) + +// void swift_unknownUnownedCopyAssign(UnownedReference *dest, UnownedReference *src); +FUNCTION(UnknownUnownedCopyAssign, swift_unknownUnownedCopyAssign,RuntimeCC, + RETURNS(VoidTy), + ARGS(UnownedReferencePtrTy, UnownedReferencePtrTy), + ATTRS(NoUnwind)) + +// void swift_unknownUnownedTakeAssign(UnownedReference *dest, UnownedReference *src); +FUNCTION(UnknownUnownedTakeAssign, swift_unknownUnownedTakeAssign,RuntimeCC, + RETURNS(VoidTy), + ARGS(UnownedReferencePtrTy, UnownedReferencePtrTy), + ATTRS(NoUnwind)) + // bool swift_isUniquelyReferencedNonObjC(const void *); FUNCTION(IsUniquelyReferencedNonObjC, swift_isUniquelyReferencedNonObjC, RuntimeCC, @@ -404,12 +446,6 @@ FUNCTION(IsUniquelyReferencedOrPinned_nonNull_native, ARGS(RefCountedPtrTy), ATTRS(NoUnwind, ZExt)) -// void swift_unknownWeakTakeAssign(WeakReference *dest, WeakReference *src); -FUNCTION(UnknownWeakTakeAssign, swift_unknownWeakTakeAssign,RuntimeCC, - RETURNS(VoidTy), - ARGS(WeakReferencePtrTy, WeakReferencePtrTy), - ATTRS(NoUnwind)) - // Metadata *swift_getFunctionTypeMetadata(const void **args); FUNCTION(GetFunctionMetadata, swift_getFunctionTypeMetadata, RuntimeCC, RETURNS(TypeMetadataPtrTy), @@ -498,6 +534,17 @@ FUNCTION(GetGenericMetadata4, swift_getGenericMetadata4, RuntimeCC, ARGS(TypeMetadataPatternPtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy), ATTRS(NoUnwind, ReadNone)) +// const ProtocolWitnessTable * +// swift_getGenericWitnessTable(GenericProtocolWitnessTable *genericTable, +// const Metadata *type, +// void * const *otherData); +FUNCTION(GetGenericWitnessTable, swift_getGenericWitnessTable, RuntimeCC, + RETURNS(WitnessTablePtrTy), + ARGS(getGenericWitnessTableCacheTy()->getPointerTo(), + TypeMetadataPtrTy, + Int8PtrPtrTy), + ATTRS(NoUnwind, ReadOnly)) + // Metadata *swift_getMetatypeMetadata(Metadata *instanceTy); FUNCTION(GetMetatypeMetadata, swift_getMetatypeMetadata, RuntimeCC, RETURNS(TypeMetadataPtrTy), @@ -517,11 +564,6 @@ FUNCTION(GetObjCClassMetadata, swift_getObjCClassMetadata, RuntimeCC, ARGS(ObjCClassPtrTy), ATTRS(NoUnwind, ReadNone)) -// _Bool swift_objcRespondsToSelector(id, void*); -FUNCTION(ObjCRespondsToSelector, swift_objcRespondsToSelector, C_CC, - RETURNS(Int1Ty), ARGS(ObjCPtrTy, Int8PtrTy), - ATTRS(NoUnwind, ReadOnly)) - // Metadata *swift_getTupleTypeMetadata(size_t numElements, // Metadata * const *elts, // const char *labels, @@ -559,23 +601,15 @@ FUNCTION(GetExistentialMetadata, ProtocolDescriptorPtrTy->getPointerTo()), ATTRS(NoUnwind, ReadOnly)) -// const char *swift_getGenericClassObjCName(Metadata *self); -FUNCTION(GetGenericClassObjCName, - swift_getGenericClassObjCName, RuntimeCC, - RETURNS(Int8PtrTy), - ARGS(TypeMetadataPtrTy), - ATTRS(NoUnwind)) - // struct FieldInfo { size_t Size; size_t AlignMask; }; // void swift_initClassMetadata_UniversalStrategy(Metadata *self, -// Metadata *super, // size_t numFields, // const FieldInfo *fields, // size_t *fieldOffsets); FUNCTION(InitClassMetadataUniversal, swift_initClassMetadata_UniversalStrategy, RuntimeCC, RETURNS(VoidTy), - ARGS(TypeMetadataPtrTy, TypeMetadataPtrTy, SizeTy, + ARGS(TypeMetadataPtrTy, SizeTy, SizeTy->getPointerTo(), SizeTy->getPointerTo()), ATTRS(NoUnwind)) @@ -811,6 +845,13 @@ FUNCTION(IsClassType, ARGS(TypeMetadataPtrTy), ATTRS(NoUnwind, ReadNone)) +// bool swift_isOptionalType(type*); +FUNCTION(IsOptionalType, + swift_isOptionalType, RuntimeCC, + RETURNS(Int1Ty), + ARGS(TypeMetadataPtrTy), + ATTRS(NoUnwind, ReadNone)) + // void swift_once(swift_once_t *predicate, // void (*function_code)(RefCounted*)); FUNCTION(Once, swift_once, RuntimeCC, @@ -828,7 +869,7 @@ FUNCTION(RegisterProtocolConformances, FUNCTION(InitializeSuperclass, swift_initializeSuperclass, RuntimeCC, RETURNS(VoidTy), - ARGS(TypeMetadataPtrTy, TypeMetadataPtrTy), + ARGS(TypeMetadataPtrTy, Int1Ty), ATTRS(NoUnwind)) FUNCTION(InstantiateObjCClass, swift_instantiateObjCClass, RuntimeCC, RETURNS(VoidTy), @@ -917,8 +958,8 @@ FUNCTION(BlockRelease, _Block_release, C_CC, ARGS(ObjCBlockPtrTy), ATTRS(NoUnwind)) -// void swift_reportMissingMethod(); -FUNCTION(DeadMethodError, swift_reportMissingMethod, C_CC, +// void swift_deletedMethodError(); +FUNCTION(DeletedMethodError, swift_deletedMethodError, C_CC, RETURNS(VoidTy), ARGS(), ATTRS(NoUnwind)) diff --git a/lib/IRGen/ScalarTypeInfo.h b/lib/IRGen/ScalarTypeInfo.h index 1378632567335..1f434bb6fbfb1 100644 --- a/lib/IRGen/ScalarTypeInfo.h +++ b/lib/IRGen/ScalarTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/StructLayout.cpp b/lib/IRGen/StructLayout.cpp index 0a1019f09099e..3f1915d07fc17 100644 --- a/lib/IRGen/StructLayout.cpp +++ b/lib/IRGen/StructLayout.cpp @@ -1,8 +1,8 @@ -//===--- StructLayout.cpp - Layout of structures -------------------------===// +//===--- StructLayout.cpp - Layout of structures --------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/StructLayout.h b/lib/IRGen/StructLayout.h index ff347a9e5ad78..12335a0254a2a 100644 --- a/lib/IRGen/StructLayout.h +++ b/lib/IRGen/StructLayout.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -385,6 +385,49 @@ Size getHeapHeaderSize(IRGenModule &IGM); void addHeapHeaderToLayout(IRGenModule &IGM, Size &size, Alignment &align, SmallVectorImpl &fieldTypes); +/// Different policies for accessing a physical field. +enum class FieldAccess : uint8_t { + /// Instance variable offsets are constant. + ConstantDirect, + + /// Instance variable offsets must be loaded from "direct offset" + /// global variables. + NonConstantDirect, + + /// Instance variable offsets are kept in fields in metadata, but + /// the offsets of those fields within the metadata are constant. + ConstantIndirect, + + /// Instance variable offsets are kept in fields in metadata, and + /// the offsets of those fields within the metadata must be loaded + /// from "indirect offset" global variables. + NonConstantIndirect +}; + +struct ClassLayout { + /// Lazily-initialized array of all fragile stored properties in the class + /// (including superclass stored properties). + ArrayRef AllStoredProperties; + /// Lazily-initialized array of all fragile stored properties inherited from + /// superclasses. + ArrayRef InheritedStoredProperties; + /// Lazily-initialized array of all field access methods. + ArrayRef AllFieldAccesses; + /// Lazily-initialized metadata access method. See the comment in + /// ClassLayoutBuilder. + FieldAccess MetadataAccess; + /// Does the class require a metadata pattern. + bool HasMetadataPattern; + + unsigned getFieldIndex(VarDecl *field) const { + // FIXME: This is algorithmically terrible. + auto found = std::find(AllStoredProperties.begin(), + AllStoredProperties.end(), field); + assert(found != AllStoredProperties.end() && "didn't find field in type?!"); + return found - AllStoredProperties.begin(); + } +}; + } // end namespace irgen } // end namespace swift diff --git a/lib/IRGen/StructMetadataLayout.h b/lib/IRGen/StructMetadataLayout.h index fc798adfc6f28..2314696855349 100644 --- a/lib/IRGen/StructMetadataLayout.h +++ b/lib/IRGen/StructMetadataLayout.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/SwiftTargetInfo.cpp b/lib/IRGen/SwiftTargetInfo.cpp index eff27338c22d6..ef4b59d2b33b5 100644 --- a/lib/IRGen/SwiftTargetInfo.cpp +++ b/lib/IRGen/SwiftTargetInfo.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/SwiftTargetInfo.h b/lib/IRGen/SwiftTargetInfo.h index 5563694f45a5a..f71f0c5186978 100644 --- a/lib/IRGen/SwiftTargetInfo.h +++ b/lib/IRGen/SwiftTargetInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/TypeInfo.h b/lib/IRGen/TypeInfo.h index 1b9bd7ee188ed..ba2877980ad82 100644 --- a/lib/IRGen/TypeInfo.h +++ b/lib/IRGen/TypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -34,6 +34,9 @@ namespace llvm { } namespace swift { + enum IsTake_t : bool; + class SILType; + namespace irgen { class Address; class ContainedAddress; @@ -57,52 +60,6 @@ enum class FixedPacking { /// It needs to be checked dynamically. Dynamic }; - -/// The kind of reference counting implementation a heap object uses. -enum class ReferenceCounting : unsigned char { - /// The object uses native Swift reference counting. - Native, - - /// The object uses ObjC reference counting. - /// - /// When ObjC interop is enabled, native Swift class objects are also ObjC - /// reference counting compatible. Swift non-class heap objects are never - /// ObjC reference counting compatible. - /// - /// Blocks are always ObjC reference counting compatible. - ObjC, - - /// The object uses _Block_copy/_Block_release reference counting. - /// - /// This is a strict subset of ObjC; all blocks are also ObjC reference - /// counting compatible. The block is assumed to have already been moved to - /// the heap so that _Block_copy returns the same object back. - Block, - - /// The object has an unknown reference counting implementation. - /// - /// This uses maximally-compatible reference counting entry points in the - /// runtime. - /// - /// FIXME: Those entry points are currently objc_retain/objc_release, which - /// are not compatible with non-class heap objects. - Unknown, - - /// Cases prior to this one are binary-compatible with Unknown reference - /// counting. - LastUnknownCompatible = Unknown, - - /// The object has an unknown reference counting implementation and - /// the reference value may contain extra bits that need to be masked. - /// - /// This uses maximally-compatible reference counting entry points in the - /// runtime, with a masking layer on top. A bit inside the pointer is used - /// to signal native Swift refcounting. - Bridge, - - /// The object uses ErrorType's reference counting entry points. - Error, -}; /// Information about the IR representation and generation of the /// given type. @@ -126,7 +83,6 @@ class TypeInfo { /// Everything after this is loadable. STIK_Loadable, STIK_Reference, - STIK_Unowned, }; TypeInfo(llvm::Type *Type, Alignment A, IsPOD_t pod, @@ -307,6 +263,12 @@ class TypeInfo { virtual void deallocateStack(IRGenFunction &IGF, Address addr, SILType T) const = 0; + /// Copy or take a value out of one address and into another, destroying + /// old value in the destination. Equivalent to either assignWithCopy + /// or assignWithTake depending on the value of isTake. + void assign(IRGenFunction &IGF, Address dest, Address src, IsTake_t isTake, + SILType T) const; + /// Copy a value out of an object and into another, destroying the /// old value in the destination. virtual void assignWithCopy(IRGenFunction &IGF, Address dest, @@ -317,6 +279,13 @@ class TypeInfo { virtual void assignWithTake(IRGenFunction &IGF, Address dest, Address src, SILType T) const = 0; + /// Copy-initialize or take-initialize an uninitialized object + /// with the value from a different object. Equivalent to either + /// initializeWithCopy or initializeWithTake depending on the value + /// of isTake. + void initialize(IRGenFunction &IGF, Address dest, Address src, + IsTake_t isTake, SILType T) const; + /// Perform a "take-initialization" from the given object. A /// take-initialization is like a C++ move-initialization, except that /// the old object is actually no longer permitted to be destroyed. diff --git a/lib/IRGen/TypeLayoutVerifier.cpp b/lib/IRGen/TypeLayoutVerifier.cpp index f3300d273e392..fb8091474041d 100644 --- a/lib/IRGen/TypeLayoutVerifier.cpp +++ b/lib/IRGen/TypeLayoutVerifier.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/TypeVisitor.h b/lib/IRGen/TypeVisitor.h index dbddd7cbe0df0..8e9c9f2447f5d 100644 --- a/lib/IRGen/TypeVisitor.h +++ b/lib/IRGen/TypeVisitor.h @@ -1,8 +1,8 @@ -//===-- TypeVisitor.h - IR-gen TypeVisitor specialization -------*- C++ -*-===// +//===--- TypeVisitor.h - IR-gen TypeVisitor specialization ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/UnimplementedTypeInfo.cpp b/lib/IRGen/UnimplementedTypeInfo.cpp index 27fe76773cb0c..69019dbac5567 100644 --- a/lib/IRGen/UnimplementedTypeInfo.cpp +++ b/lib/IRGen/UnimplementedTypeInfo.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/UnimplementedTypeInfo.h b/lib/IRGen/UnimplementedTypeInfo.h index 4123ba9d79e1e..9b150b2385c3d 100644 --- a/lib/IRGen/UnimplementedTypeInfo.h +++ b/lib/IRGen/UnimplementedTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/IRGen/UnownedTypeInfo.h b/lib/IRGen/UnownedTypeInfo.h deleted file mode 100644 index 1fb230df062e6..0000000000000 --- a/lib/IRGen/UnownedTypeInfo.h +++ /dev/null @@ -1,52 +0,0 @@ -//===--- UnownedTypeInfo.h - Supplemental API for [unowned] -----*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// -// This file defines UnownedTypeInfo, which supplements the FixedTypeInfo -// interface for types that implement [unowned] references. -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_IRGEN_UNOWNEDTYPEINFO_H -#define SWIFT_IRGEN_UNOWNEDTYPEINFO_H - -#include "LoadableTypeInfo.h" - -namespace swift { -namespace irgen { - -/// \brief An abstract class designed for use when implementing a -/// ReferenceStorageType with [unowned] ownership. -class UnownedTypeInfo : public LoadableTypeInfo { -protected: - UnownedTypeInfo(llvm::Type *type, Size size, - const SpareBitVector &spareBits, Alignment align) - : LoadableTypeInfo(type, size, spareBits, align, - IsNotPOD, IsFixedSize, STIK_Unowned) {} - - UnownedTypeInfo(llvm::Type *type, Size size, - SpareBitVector &&spareBits, Alignment align) - : LoadableTypeInfo(type, size, std::move(spareBits), align, - IsNotPOD, IsFixedSize, STIK_Unowned) {} - -public: - // No API yet. - - static bool classof(const UnownedTypeInfo *type) { return true; } - static bool classof(const TypeInfo *type) { - return type->getSpecialTypeInfoKind() == STIK_Unowned; - } -}; - -} -} - -#endif diff --git a/lib/IRGen/ValueWitness.h b/lib/IRGen/ValueWitness.h index 7faf9e20bcc87..a6f5d3cb9bb6d 100644 --- a/lib/IRGen/ValueWitness.h +++ b/lib/IRGen/ValueWitness.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -83,7 +83,7 @@ enum class ValueWitness : unsigned { /// T *(*initializeBufferWithCopyOfBuffer)(B *dest, B *src, M *self); /// Given an invalid buffer, initialize it as a copy of the /// object in the source buffer. This can be decomposed as: - /// initalizeBufferWithCopy(dest, self->projectBuffer(src), self) + /// initializeBufferWithCopy(dest, self->projectBuffer(src), self) InitializeBufferWithCopyOfBuffer, /// T *(*projectBuffer)(B *buffer, M *self); @@ -156,13 +156,13 @@ enum class ValueWitness : unsigned { /// T *(*initializeBufferWithTakeOfBuffer)(B *dest, B *src, M *self); /// Given an invalid buffer, initialize it by taking the value out of /// the source buffer. This can be (inefficiently) decomposed as: - /// initalizeBufferWithTake(dest, self->projectBuffer(src), self) + /// initializeBufferWithTake(dest, self->projectBuffer(src), self) /// deallocateBuffer(src, self) InitializeBufferWithTakeOfBuffer, /// void (*destroyArray)(T *object, size_t n, witness_t *self); /// - /// Given a vaild array of n objects of this type, destroy the object, leaving + /// Given a valid array of n objects of this type, destroy the object, leaving /// the array invalid. This is useful when generically destroying an array of /// objects to avoid calling the scalar 'destroy' witness in a loop. DestroyArray, @@ -290,7 +290,12 @@ enum class ValueWitness : unsigned { /// Given a valid object of this enum type, destructively extracts the /// associated payload. DestructiveProjectEnumData, - Last_EnumValueWitness = DestructiveProjectEnumData, + /// void (*destructiveInjectEnumTag)(T *obj, unsigned tag, M *self); + /// Given an enum case tag and a valid object of case's payload type, + /// destructively inserts the tag into the payload. + DestructiveInjectEnumTag, + + Last_EnumValueWitness = DestructiveInjectEnumTag, Last_ValueWitness = Last_EnumValueWitness, }; diff --git a/lib/IRGen/WeakTypeInfo.h b/lib/IRGen/WeakTypeInfo.h index 2b4802f83b3ce..ceea010fd48b4 100644 --- a/lib/IRGen/WeakTypeInfo.h +++ b/lib/IRGen/WeakTypeInfo.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Immediate/CMakeLists.txt b/lib/Immediate/CMakeLists.txt index ab54e57cf7dc5..41e18e3b112fd 100644 --- a/lib/Immediate/CMakeLists.txt +++ b/lib/Immediate/CMakeLists.txt @@ -5,7 +5,7 @@ add_swift_library(swiftImmediate swiftIDE swiftFrontend swiftSILGen - swiftSILPasses + swiftSILOptimizer swiftIRGen COMPONENT_DEPENDS linker mcjit) diff --git a/lib/Immediate/Immediate.cpp b/lib/Immediate/Immediate.cpp index ceb248ae23165..8d8dcbe845330 100644 --- a/lib/Immediate/Immediate.cpp +++ b/lib/Immediate/Immediate.cpp @@ -1,8 +1,8 @@ -//===-- Immediate.cpp - the swift immediate mode --------------------------===// +//===--- Immediate.cpp - the swift immediate mode -------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,7 +25,7 @@ #include "swift/AST/IRGenOptions.h" #include "swift/AST/Module.h" #include "swift/Frontend/Frontend.h" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/Basic/LLVM.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/config.h" diff --git a/lib/Immediate/ImmediateImpl.h b/lib/Immediate/ImmediateImpl.h index d3a52877c22c2..5bc40f0b8ff02 100644 --- a/lib/Immediate/ImmediateImpl.h +++ b/lib/Immediate/ImmediateImpl.h @@ -1,8 +1,8 @@ -//===-- ImmediateImpl.h - Support functions for immediate mode -*- C++ -*--===// +//===--- ImmediateImpl.h - Support functions for immediate mode -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Immediate/REPL.cpp b/lib/Immediate/REPL.cpp index 740b315f9ea5c..4723a4f073bfd 100644 --- a/lib/Immediate/REPL.cpp +++ b/lib/Immediate/REPL.cpp @@ -1,8 +1,8 @@ -//===-- REPL.cpp - the integrated REPL ------------------------------------===// +//===--- REPL.cpp - the integrated REPL -----------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -24,7 +24,7 @@ #include "swift/IDE/Utils.h" #include "swift/Parse/PersistentParserState.h" #include "swift/SIL/SILModule.h" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/IR/Module.h" #include "llvm/Transforms/Utils/Cloning.h" @@ -33,7 +33,7 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" -#if defined(__APPLE__) +#if defined(__APPLE__) || defined(__FreeBSD__) // FIXME: Support REPL on non-Apple platforms. Ubuntu 14.10's editline does not // include the wide character entry points needed by the REPL yet. #include @@ -130,6 +130,7 @@ class ConvertForWcharSize<4> { using Convert = ConvertForWcharSize; +#if defined(__APPLE__) || defined(__FreeBSD__) static void convertFromUTF8(llvm::StringRef utf8, llvm::SmallVectorImpl &out) { size_t reserve = out.size() + utf8.size(); @@ -157,9 +158,12 @@ static void convertToUTF8(llvm::ArrayRef wide, (void)res; out.set_size(utf8_begin - out.begin()); } +#endif } // end anonymous namespace +#if defined(__APPLE__) || defined(__FreeBSD__) + static bool appendToREPLFile(SourceFile &SF, PersistentParserState &PersistentState, REPLContext &RC, @@ -183,8 +187,6 @@ static bool appendToREPLFile(SourceFile &SF, return FoundAnySideEffects; } -#if defined(__APPLE__) - /// An arbitrary, otherwise-unused char value that editline interprets as /// entering/leaving "literal mode", meaning it passes prompt characters through /// to the terminal without affecting the line state. This prevents color @@ -948,8 +950,7 @@ class REPLEnvironment { } tryLoadLibraries(CI.getLinkLibraries(), Ctx.SearchPathOpts, CI.getDiags()); - llvm::EngineBuilder builder( - std::move(std::unique_ptr(Module))); + llvm::EngineBuilder builder{std::unique_ptr{Module}}; std::string ErrorMsg; llvm::TargetOptions TargetOpt; std::string CPU; @@ -1190,6 +1191,7 @@ void swift::runREPL(CompilerInstance &CI, const ProcessCmdLine &CmdLine, // Disable the REPL on other platforms; our current implementation is tied // to histedit.h. llvm::report_fatal_error("Compiler-internal integrated REPL unimplemented " - "for this platform"); + "for this platform; use the LLDB-enhanced REPL " + "instead."); } #endif diff --git a/lib/LLVMPasses/ARCEntryPointBuilder.h b/lib/LLVMPasses/ARCEntryPointBuilder.h index bd778bc8bb820..f68325eb808b6 100644 --- a/lib/LLVMPasses/ARCEntryPointBuilder.h +++ b/lib/LLVMPasses/ARCEntryPointBuilder.h @@ -1,8 +1,8 @@ -//===--- ARCEntryPointBuilder.h ----------------------------*- C++ -*------===// +//===--- ARCEntryPointBuilder.h ---------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,7 +21,7 @@ namespace swift { /// A class for building ARC entry points. It is a composition wrapper around an -/// IRBuilder and a constant Cache. It can not be moved or copied. It is meant +/// IRBuilder and a constant Cache. It cannot be moved or copied. It is meant /// to be created once and passed around by reference. class ARCEntryPointBuilder { using IRBuilder = llvm::IRBuilder<>; diff --git a/lib/LLVMPasses/LLVMARCContract.cpp b/lib/LLVMPasses/LLVMARCContract.cpp index 9b1b3be407180..f384ca2313f82 100644 --- a/lib/LLVMPasses/LLVMARCContract.cpp +++ b/lib/LLVMPasses/LLVMARCContract.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/LLVMPasses/LLVMARCOpts.cpp b/lib/LLVMPasses/LLVMARCOpts.cpp index 0b8ef4760fe23..9cdfaebc837bc 100644 --- a/lib/LLVMPasses/LLVMARCOpts.cpp +++ b/lib/LLVMPasses/LLVMARCOpts.cpp @@ -1,8 +1,8 @@ -//===--- Passes.cpp - LLVM Reference Counting Optimizations ---------------===// +//===--- LLVMARCOpts.cpp - LLVM Reference Counting Optimizations ----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -553,8 +553,8 @@ static DtorKind analyzeDestructor(Value *P) { // FIXME: Would like to abstract the dtor slot (#0) out from this to somewhere // unified. - enum { DTorSlotOfHeapMeatadata = 0 }; - Function *DtorFn =dyn_cast(CS->getOperand(DTorSlotOfHeapMeatadata)); + enum { DTorSlotOfHeapMetadata = 0 }; + Function *DtorFn =dyn_cast(CS->getOperand(DTorSlotOfHeapMetadata)); if (DtorFn == 0 || DtorFn->mayBeOverridden() || DtorFn->hasExternalLinkage()) return DtorKind::Unknown; @@ -594,7 +594,7 @@ static DtorKind analyzeDestructor(Value *P) { case RT_BridgeRetain: // x = swift_bridgeRetain(y) case RT_Retain: { // swift_retain(obj) - // Ignore retains of the "self" object, no ressurection is possible. + // Ignore retains of the "self" object, no resurrection is possible. Value *ThisRetainedObject = cast(I).getArgOperand(0); if (ThisRetainedObject->stripPointerCasts() == ThisObject->stripPointerCasts()) @@ -856,7 +856,7 @@ static bool performLocalRetainUnownedOpt(CallInst *Retain, BasicBlock &BB, } /// Removes redundant check_unowned calls if they check the same reference and -/// there is no instruction inbetween which could decrement the reference count. +/// there is no instruction in between which could decrement the reference count. static void performRedundantCheckUnownedRemoval(BasicBlock &BB) { DenseSet checkedValues; for (BasicBlock::iterator BBI = BB.begin(), E = BB.end(); BBI != E; ) { diff --git a/lib/LLVMPasses/LLVMARCOpts.h b/lib/LLVMPasses/LLVMARCOpts.h index 4582a0a839e78..fe84bab856390 100644 --- a/lib/LLVMPasses/LLVMARCOpts.h +++ b/lib/LLVMPasses/LLVMARCOpts.h @@ -1,8 +1,8 @@ -//===- LLVMARCOpts.h - LLVM level ARC Opts Utility Declarations -*- C++ -*-===// +//===--- LLVMARCOpts.h - LLVM level ARC Opts Util. Declarations -*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -62,7 +62,7 @@ enum RT_Kind { /// void swift_unknownRelease_n(%swift.refcounted* %P) RT_UnknownReleaseN, - /// void swift_fixLifetime(%swift.refcounted* %P) + /// void __swift_fixLifetime(%swift.refcounted* %P) RT_FixLifetime, /// void swift_bridgeRetain(%swift.refcounted* %P) @@ -112,7 +112,7 @@ inline RT_Kind classifyInstruction(const llvm::Instruction &I) { .Case("swift_unknownRetain_n", RT_UnknownRetainN) .Case("swift_unknownRelease", RT_UnknownRelease) .Case("swift_unknownRelease_n", RT_UnknownReleaseN) - .Case("swift_fixLifetime", RT_FixLifetime) + .Case("__swift_fixLifetime", RT_FixLifetime) .Default(RT_Unknown); } diff --git a/lib/LLVMPasses/LLVMStackPromotion.cpp b/lib/LLVMPasses/LLVMStackPromotion.cpp index 89c458da58529..2cc89c7f90017 100644 --- a/lib/LLVMPasses/LLVMStackPromotion.cpp +++ b/lib/LLVMPasses/LLVMStackPromotion.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/LLVMPasses/LLVMSwiftAA.cpp b/lib/LLVMPasses/LLVMSwiftAA.cpp index af34283b6abdf..d413ff1391fd3 100644 --- a/lib/LLVMPasses/LLVMSwiftAA.cpp +++ b/lib/LLVMPasses/LLVMSwiftAA.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/LLVMPasses/LLVMSwiftRCIdentity.cpp b/lib/LLVMPasses/LLVMSwiftRCIdentity.cpp index 5487d4a57d281..24e4fb4e0d955 100644 --- a/lib/LLVMPasses/LLVMSwiftRCIdentity.cpp +++ b/lib/LLVMPasses/LLVMSwiftRCIdentity.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Markup/AST.cpp b/lib/Markup/AST.cpp index ba30d77444d40..c78fa7228c6dc 100644 --- a/lib/Markup/AST.cpp +++ b/lib/Markup/AST.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -62,9 +62,10 @@ Code *Code::create(MarkupContext &MC, StringRef LiteralContent) { return new (Mem) Code(LiteralContent); } -CodeBlock *CodeBlock::create(MarkupContext &MC, StringRef LiteralContent) { +CodeBlock *CodeBlock::create(MarkupContext &MC, StringRef LiteralContent, + StringRef Language) { void *Mem = MC.allocate(sizeof(CodeBlock), alignof(CodeBlock)); - return new (Mem) CodeBlock(LiteralContent); + return new (Mem) CodeBlock(LiteralContent, Language); } List::List(ArrayRef Children, bool IsOrdered) @@ -357,11 +358,11 @@ void llvm::markup::dump(const MarkupASTNode *Node, llvm::raw_ostream &OS, unsigned indent) { auto dumpChildren = [](const ArrayRef Children, llvm::raw_ostream &OS, unsigned indent) { - OS << "\n"; + OS << '\n'; for (auto Child = Children.begin(); Child != Children.end(); Child++) { llvm::markup::dump(*Child, OS, indent + 1); if (Child != Children.end() - 1) - OS << "\n"; + OS << '\n'; } }; @@ -390,10 +391,10 @@ void llvm::markup::dump(const MarkupASTNode *Node, llvm::raw_ostream &OS, }; for (unsigned i = 0; i < indent; ++i) { - OS << " "; + OS << ' '; } - OS << "("; + OS << '('; switch (Node->getKind()) { case llvm::markup::ASTNodeKind::Document: { OS << "Document: Children=" << Node->getChildren().size(); @@ -460,7 +461,10 @@ void llvm::markup::dump(const MarkupASTNode *Node, llvm::raw_ostream &OS, } case llvm::markup::ASTNodeKind::CodeBlock: { auto CB = cast(Node); - OS << "CodeBlock: Content="; + OS << "CodeBlock: "; + OS << "Language="; + simpleEscapingPrint(CB->getLanguage(), OS); + OS << " Content="; simpleEscapingPrint(CB->getLiteralContent(), OS); break; } @@ -485,7 +489,7 @@ void llvm::markup::dump(const MarkupASTNode *Node, llvm::raw_ostream &OS, auto L = cast(Node); OS << "Link: Destination="; simpleEscapingPrint(L->getDestination(), OS); - OS << " " << "Children=" << L->getChildren().size(); + OS << ' ' << "Children=" << L->getChildren().size(); dumpChildren(Node->getChildren(), OS, indent + 1); break; } @@ -493,7 +497,7 @@ void llvm::markup::dump(const MarkupASTNode *Node, llvm::raw_ostream &OS, auto I = cast(Node); OS << "Image: Destination="; simpleEscapingPrint(I->getDestination(), OS); - OS << " " << "Children=" << I->getChildren().size(); + OS << ' ' << "Children=" << I->getChildren().size(); dumpChildren(Node->getChildren(), OS, indent + 1); break; } @@ -518,5 +522,5 @@ void llvm::markup::dump(const MarkupASTNode *Node, llvm::raw_ostream &OS, default: llvm_unreachable("Can't dump Markup AST Node: unknown node kind"); } - OS << ")"; + OS << ')'; } diff --git a/lib/Markup/LineList.cpp b/lib/Markup/LineList.cpp index b4ccb89f7d692..671855f3d20c4 100644 --- a/lib/Markup/LineList.cpp +++ b/lib/Markup/LineList.cpp @@ -1,8 +1,8 @@ -//===--- LineList.h - Data structures for Markup parsing ------------------===// +//===--- LineList.cpp - Data structures for Markup parsing ----------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Markup/Markup.cpp b/lib/Markup/Markup.cpp index 985e526116191..9e831d5539eca 100644 --- a/lib/Markup/Markup.cpp +++ b/lib/Markup/Markup.cpp @@ -1,8 +1,8 @@ -//===--- Markup.h - Markup ------------------------------------------------===// +//===--- Markup.cpp - Markup ----------------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,7 +16,6 @@ #include "swift/Markup/LineList.h" #include "swift/Markup/Markup.h" #include "cmark.h" -#include "node.h" using namespace llvm; using namespace markup; @@ -60,15 +59,7 @@ StringRef getLiteralContent(MarkupContext &MC, LineList &LL, cmark_node *Node) { // its parent. auto Literal = cmark_node_get_literal(Node); assert(Literal != nullptr); - size_t Length = 0; - switch (cmark_node_get_type(Node)) { - case CMARK_NODE_CODE_BLOCK: - Length = Node->as.code.literal.len; - break; - default: - Length = Node->as.literal.len; - } - return MC.allocateCopy(StringRef(Literal, Length)); + return MC.allocateCopy(StringRef(Literal)); } ParseResult @@ -117,7 +108,16 @@ ParseResult parseCodeBlock(MarkupContext &MC, LineList &LL, ParseState State) { assert(cmark_node_get_type(State.Node) == CMARK_NODE_CODE_BLOCK && State.Event == CMARK_EVENT_ENTER); - return { CodeBlock::create(MC, getLiteralContent(MC, LL, State.Node)), + + StringRef Language("swift"); + + if (auto FenceInfo = cmark_node_get_fence_info(State.Node)) { + StringRef FenceInfoStr(FenceInfo); + if (!FenceInfoStr.empty()) + Language = MC.allocateCopy(FenceInfoStr); + } + return { CodeBlock::create(MC, getLiteralContent(MC, LL, State.Node), + Language), State.next() }; } diff --git a/lib/Option/Options.cpp b/lib/Option/Options.cpp index 19a948fc9f87f..d8a138d9a052d 100644 --- a/lib/Option/Options.cpp +++ b/lib/Option/Options.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp index e495c94a7d47b..fad3e4b714418 100644 --- a/lib/Parse/Lexer.cpp +++ b/lib/Parse/Lexer.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -523,6 +523,18 @@ bool Lexer::isIdentifier(StringRef string) { return p == end; } +/// \brief Determines if the given string is a valid operator identifier, +/// without escaping characters. +bool Lexer::isOperator(StringRef string) { + if (string.empty()) return false; + char const *p = string.data(), *end = string.end(); + if (!advanceIfValidStartOfOperator(p, end)) + return false; + while (p < end && advanceIfValidContinuationOfOperator(p, end)); + return p == end; +} + + tok Lexer::kindOfIdentifier(StringRef Str, bool InSILMode) { tok Kind = llvm::StringSwitch(Str) #define KEYWORD(kw) \ @@ -595,30 +607,23 @@ static bool isRightBound(const char *tokEnd, bool isLeftBound) { /// lexOperatorIdentifier - Match identifiers formed out of punctuation. void Lexer::lexOperatorIdentifier() { const char *TokStart = CurPtr-1; + CurPtr = TokStart; + bool didStart = advanceIfValidStartOfOperator(CurPtr, BufferEnd); + assert(didStart && "unexpected operator start"); + (void) didStart; + + do { + if (CurPtr != BufferEnd && InSILBody && + (*CurPtr == '!' || *CurPtr == '?')) + // When parsing SIL body, '!' and '?' are special token and can't be + // in the middle of an operator. + break; - // We only allow '.' in a series. - if (*TokStart == '.') { - while (*CurPtr == '.') - ++CurPtr; - - // Lex ..< as an identifier. - if (*CurPtr == '<' && CurPtr-TokStart == 2) - ++CurPtr; - - } else { - CurPtr = TokStart; - bool didStart = advanceIfValidStartOfOperator(CurPtr, BufferEnd); - assert(didStart && "unexpected operator start"); - (void) didStart; - - do { - if (CurPtr != BufferEnd && InSILBody && - (*CurPtr == '!' || *CurPtr == '?')) - // When parsing SIL body, '!' and '?' are special token and can't be - // in the middle of an operator. - break; - } while (advanceIfValidContinuationOfOperator(CurPtr, BufferEnd)); - } + // '.' cannot appear in the middle of an operator unless the operator + // started with a '.'. + if (*CurPtr == '.' && *TokStart != '.') + break; + } while (advanceIfValidContinuationOfOperator(CurPtr, BufferEnd)); // Decide between the binary, prefix, and postfix cases. // It's binary if either both sides are bound or both sides are not bound. @@ -631,8 +636,7 @@ void Lexer::lexOperatorIdentifier() { switch (TokStart[0]) { case '=': if (leftBound != rightBound) { - auto d = diagnose(TokStart, diag::lex_unary_equal_is_reserved, - leftBound); + auto d = diagnose(TokStart, diag::lex_unary_equal); if (leftBound) d.fixItInsert(getSourceLoc(TokStart), " "); else @@ -1164,11 +1168,31 @@ void Lexer::lexStringLiteral() { if (*TokStart == '\'') { // Complain about single-quote string and suggest replacement with // double-quoted equivalent. - // FIXME: Fixit should replace ['"'] with ["\""] (radar 22709931) StringRef orig(TokStart, CurPtr - TokStart); llvm::SmallString<32> replacement; replacement += '"'; - replacement += orig.slice(1, orig.size() - 1); + std::string str = orig.slice(1, orig.size() - 1).str(); + std::string quot = "\""; + size_t pos = 0; + while (pos != str.length()) { + if (str.at(pos) == '\\') { + if (str.at(pos + 1) == '\'') { + // Un-escape escaped single quotes. + str.replace(pos, 2, "'"); + ++pos; + } else { + // Skip over escaped characters. + pos += 2; + } + } else if (str.at(pos) == '"') { + str.replace(pos, 1, "\\\""); + // Advance past the newly added ["\""]. + pos += 2; + } else { + ++pos; + } + } + replacement += StringRef(str); replacement += '"'; diagnose(TokStart, diag::lex_single_quote_string) .fixItReplaceChars(getSourceLoc(TokStart), getSourceLoc(CurPtr), @@ -1259,9 +1283,13 @@ void Lexer::tryLexEditorPlaceholder() { if (Ptr[0] == '<' && Ptr[1] == '#') break; if (Ptr[0] == '#' && Ptr[1] == '>') { - // Found it. Flag it as error for the rest of the compiler pipeline and - // lex it as an identifier. - diagnose(TokStart, diag::lex_editor_placeholder); + // Found it. Flag it as error (or warning, if in playground mode) for the + // rest of the compiler pipeline and lex it as an identifier. + if (LangOpts.Playground) { + diagnose(TokStart, diag::lex_editor_placeholder_in_playground); + } else { + diagnose(TokStart, diag::lex_editor_placeholder); + } CurPtr = Ptr+2; formToken(tok::identifier, TokStart); return; @@ -1640,15 +1668,15 @@ void Lexer::lexImpl() { } } -SourceLoc Lexer::getLocForEndOfToken(const SourceManager &SM, SourceLoc Loc) { +Token Lexer::getTokenAtLocation(const SourceManager &SM, SourceLoc Loc) { // Don't try to do anything with an invalid location. if (!Loc.isValid()) - return Loc; + return Token(); // Figure out which buffer contains this location. int BufferID = SM.findBufferContainingLoc(Loc); if (BufferID < 0) - return SourceLoc(); + return Token(); // Use fake language options; language options only affect validity // and the exact token produced. @@ -1661,10 +1689,14 @@ SourceLoc Lexer::getLocForEndOfToken(const SourceManager &SM, SourceLoc Loc) { Lexer L(FakeLangOpts, SM, BufferID, nullptr, /*InSILMode=*/ false, CommentRetentionMode::ReturnAsTokens); L.restoreState(State(Loc)); - unsigned Length = L.peekNextToken().getLength(); - return Loc.getAdvancedLoc(Length); + return L.peekNextToken(); } +SourceLoc Lexer::getLocForEndOfToken(const SourceManager &SM, SourceLoc Loc) { + return Loc.getAdvancedLocOrInvalid(getTokenAtLocation(SM, Loc).getLength()); +} + + static SourceLoc getLocForStartOfTokenInBuf(SourceManager &SM, unsigned BufferID, unsigned Offset, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index d0c969a210bf0..fba8b2747d7a2 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,8 +20,9 @@ #include "swift/Subsystems.h" #include "swift/AST/Attr.h" #include "swift/AST/DebuggerClient.h" -#include "swift/AST/Module.h" #include "swift/AST/DiagnosticsParse.h" +#include "swift/AST/Module.h" +#include "swift/AST/ParameterList.h" #include "swift/Basic/Defer.h" #include "swift/Basic/Fallthrough.h" #include "llvm/Support/MemoryBuffer.h" @@ -34,12 +35,6 @@ using namespace swift; -/// \brief Build an implicit 'self' parameter for the specified DeclContext. -static Pattern *buildImplicitSelfParameter(SourceLoc Loc, - DeclContext *CurDeclContext) { - return Pattern::buildImplicitSelfParameter(Loc, TypeLoc(), CurDeclContext); -} - namespace { /// A RAII object for deciding whether this DeclKind needs special /// treatment when parsing in the "debugger context", and implementing @@ -1159,6 +1154,115 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc, rParenLoc, false)); break; } + + case DAK_MigrationId: { + if (Tok.isNot(tok::l_paren)) { + diagnose(Loc, diag::attr_expected_lparen, AttrName, + DeclAttribute::isDeclModifier(DK)); + return false; + } + + StringRef ident; + StringRef patternId; + SourceLoc lParenLoc = consumeToken(); + + // If we don't have a string, complain. + if (Tok.isNot(tok::string_literal)) { + diagnose(Tok, diag::attr_expected_string_literal, AttrName); + if (Tok.isNot(tok::r_paren)) + skipUntil(tok::r_paren); + consumeIf(tok::r_paren); + return false; + } + + // Dig out the string. + auto string = getStringLiteralIfNotInterpolated(*this, Loc, Tok, + AttrName); + consumeToken(tok::string_literal); + if (!string) + return false; + ident = string.getValue(); + consumeIf(tok::comma); + + bool invalid = false; + do { + // If we see a closing parenthesis, + if (Tok.is(tok::r_paren)) + break; + + if (Tok.isNot(tok::identifier)) { + diagnose(Tok, diag::attr_migration_id_expected_name); + if (Tok.isNot(tok::r_paren)) + skipUntil(tok::r_paren); + consumeIf(tok::r_paren); + invalid = true; + break; + } + + // Consume the identifier. + StringRef name = Tok.getText(); + SourceLoc nameLoc = consumeToken(); + bool known = (name == "pattern"); + + // If we don't have the '=', complain. + SourceLoc equalLoc; + if (!consumeIf(tok::equal, equalLoc)) { + if (known) + diagnose(Tok, diag::attr_migration_id_expected_eq, name); + else + diagnose(Tok, diag::attr_migration_id_unknown_parameter, name); + continue; + } + + + // If we don't have a string, complain. + if (Tok.isNot(tok::string_literal)) { + diagnose(Tok, diag::attr_migration_id_expected_string, name); + if (Tok.isNot(tok::r_paren)) + skipUntil(tok::r_paren); + consumeIf(tok::r_paren); + invalid = true; + break; + } + + // Dig out the string. + auto param_string = getStringLiteralIfNotInterpolated(*this, nameLoc, Tok, + name.str()); + consumeToken(tok::string_literal); + if (!param_string) { + continue; + } + + if (!known) { + diagnose(nameLoc, diag::attr_migration_id_unknown_parameter, + name); + continue; + } + + if (!patternId.empty()) { + diagnose(nameLoc, diag::attr_migration_id_duplicate_parameter, + name); + } + + patternId = param_string.getValue(); + } while (consumeIf(tok::comma)); + + // Parse the closing ')'. + SourceLoc rParenLoc; + if (Tok.isNot(tok::r_paren)) { + parseMatchingToken(tok::r_paren, rParenLoc, + diag::attr_migration_id_expected_rparen, + lParenLoc); + } + if (Tok.is(tok::r_paren)) { + rParenLoc = consumeToken(); + } + + Attributes.add(new (Context) MigrationIdAttr(AtLoc, Loc, lParenLoc, + ident, patternId, + rParenLoc, false)); + break; + } } if (DuplicateAttribute) { @@ -1336,18 +1440,6 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, bool justChecking) { // Otherwise this is a valid decl attribute so they should have put it on // the decl instead of the type. - auto diagID = diag::decl_attribute_applied_to_type; - if (declAttrID == DAK_AutoClosure) { - // Special case handling of @autoclosure attribute on the type, which - // was supported in Swift 1.0 and 1.1, but removed in Swift 1.2. - diagID = diag::autoclosure_is_decl_attribute; - - // Further special case handling of @autoclosure attribute in - // enumerators in EnumDecl's to produce a nice diagnostic. - if (CurDeclContext && isa(CurDeclContext)) - diagID = diag::autoclosure_not_on_enums; - } - // If this is the first attribute, and if we are on a simple decl, emit a // fixit to move the attribute. Otherwise, we don't have the location of // the @ sign, or we don't have confidence that the fixit will be right. @@ -1355,21 +1447,19 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, bool justChecking) { StructureMarkers.back().Kind != StructureMarkerKind::Declaration || StructureMarkers.back().Loc.isInvalid() || peekToken().is(tok::equal)) { - diagnose(Tok, diagID); + diagnose(Tok, diag::decl_attribute_applied_to_type); } else { // Otherwise, this is the first type attribute and we know where the // declaration is. Emit the same diagnostic, but include a fixit to // move the attribute. Unfortunately, we don't have enough info to add // the attribute to DeclAttributes. - diagnose(Tok, diagID) + diagnose(Tok, diag::decl_attribute_applied_to_type) .fixItRemove(SourceRange(Attributes.AtLoc, Tok.getLoc())) .fixItInsert(StructureMarkers.back().Loc, "@" + Tok.getText().str()+" "); } } - - // Recover by eating @foo when foo is not known. consumeToken(); @@ -1405,7 +1495,6 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, bool justChecking) { switch (attr) { default: break; - case TAK_local_storage: case TAK_out: case TAK_in: case TAK_owned: @@ -1427,7 +1516,7 @@ bool Parser::parseTypeAttribute(TypeAttributes &Attributes, bool justChecking) { case TAK_sil_unowned: Attributes.clearAttribute(attr); if (!isInSILMode()) { - diagnose(Loc, diag::only_allowed_in_sil, "local_storage"); + diagnose(Loc, diag::only_allowed_in_sil, Text); return false; } @@ -2086,7 +2175,7 @@ void Parser::parseDeclDelayed() { // Ensure that we restore the parser state at exit. ParserPositionRAII PPR(*this); - // Create a lexer that can not go past the end state. + // Create a lexer that cannot go past the end state. Lexer LocalLex(*L, BeginParserPosition.LS, EndLexerState); // Temporarily swap out the parser's current lexer with our new one. @@ -2177,6 +2266,19 @@ ParserResult Parser::parseDeclImport(ParseDeclOptions Flags, return nullptr; } while (consumeIf(tok::period)); + if (Tok.is(tok::code_complete)) { + // We omit the code completion token if it immediately follows the module + // identifiers. + auto BufferId = SourceMgr.getCodeCompletionBufferID(); + auto IdEndOffset = SourceMgr.getLocOffsetInBuffer(ImportPath.back().second, + BufferId) + ImportPath.back().first.str().size(); + auto CCTokenOffset = SourceMgr.getLocOffsetInBuffer(SourceMgr. + getCodeCompletionLoc(), BufferId); + if (IdEndOffset == CCTokenOffset) { + consumeToken(); + } + } + if (Kind != ImportKind::Module && ImportPath.size() == 1) { diagnose(ImportPath.front().second, diag::decl_expected_module_name); return nullptr; @@ -2398,8 +2500,8 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) { return parseDecl(MemberDecls, Options); }); - // Don't propagate the code completion bit from members: we can not help - // code completion inside a member decl, and our callers can not do + // Don't propagate the code completion bit from members: we cannot help + // code completion inside a member decl, and our callers cannot do // anything about it either. But propagate the error bit. if (BodyStatus.isError()) status.setIsParseError(); @@ -2622,71 +2724,51 @@ ParserResult Parser::parseDeclTypeAlias(bool WantDefinition, /// This function creates an accessor function (with no body) for a computed /// property or subscript. -static FuncDecl *createAccessorFunc(SourceLoc DeclLoc, - TypedPattern *TypedPattern, +static FuncDecl *createAccessorFunc(SourceLoc DeclLoc, ParameterList *param, TypeLoc ElementTy, - Pattern *Indices, SourceLoc StaticLoc, + ParameterList *Indices, SourceLoc StaticLoc, Parser::ParseDeclOptions Flags, AccessorKind Kind, AddressorKind addressorKind, Parser *P, SourceLoc AccessorKeywordLoc) { - // First task, set up the value argument pattern. This is the NamePattern + // First task, set up the value argument list. This is the "newValue" name // (for setters) followed by the index list (for subscripts). For // non-subscript getters, this degenerates down to "()". // - // We put the 'value' argument before the subscript index list as a + // We put the 'newValue' argument before the subscript index list as a // micro-optimization for Objective-C thunk generation. - Pattern *ValueArg; + ParameterList *ValueArg; { - SmallVector ValueArgElements; + SmallVector ValueArgElements; SourceLoc StartLoc, EndLoc; - bool ExplicitArgument = TypedPattern && - (!TypedPattern->isImplicit() || - !TypedPattern->getSubPattern()->isImplicit()); - - if (TypedPattern) { - ValueArgElements.push_back(TuplePatternElt(TypedPattern)); - StartLoc = TypedPattern->getStartLoc(); - EndLoc = TypedPattern->getEndLoc(); + if (param) { + assert(param->size() == 1 && + "Should only have a single parameter in the list"); + ValueArgElements.push_back(param->get(0)); + StartLoc = param->getStartLoc(); + EndLoc = param->getEndLoc(); } if (Indices) { - auto clonePattern = [&](const Pattern *p) -> Pattern* { - return p->clone(P->Context, Pattern::Implicit); - }; - - if (auto *PP = dyn_cast(Indices)) { - ValueArgElements.push_back( - TuplePatternElt(clonePattern(PP->getSubPattern()))); - } else { - auto *TP = cast(Indices); - for (const auto &elt : TP->getElements()) { - ValueArgElements.push_back( - TuplePatternElt(elt.getLabel(), elt.getLabelLoc(), - clonePattern(elt.getPattern()), - elt.hasEllipsis())); - } - } - - if (!ExplicitArgument) { + Indices = Indices->clone(P->Context, ParameterList::Implicit); + ValueArgElements.append(Indices->begin(), Indices->end()); + if (StartLoc.isInvalid()) { StartLoc = Indices->getStartLoc(); EndLoc = Indices->getEndLoc(); } } - ValueArg = TuplePattern::create(P->Context, StartLoc, ValueArgElements, - EndLoc); - if (!ExplicitArgument) - ValueArg->setImplicit(); + ValueArg = ParameterList::create(P->Context, StartLoc, ValueArgElements, + EndLoc); } // Create the parameter list(s) for the getter. - SmallVector Params; + SmallVector Params; // Add the implicit 'self' to Params, if needed. if (Flags & Parser::PD_HasContainerType) - Params.push_back(buildImplicitSelfParameter(DeclLoc, P->CurDeclContext)); + Params.push_back(ParameterList::createSelf(DeclLoc, P->CurDeclContext)); // Add the "(value)" and subscript indices parameter clause. Params.push_back(ValueArg); @@ -2794,18 +2876,17 @@ static FuncDecl *createAccessorFunc(SourceLoc DeclLoc, case AccessorKind::IsMaterializeForSet: case AccessorKind::NotAccessor: - llvm_unreachable("not parsable accessors"); + llvm_unreachable("not parseable accessors"); } } return D; } -static TypedPattern *createSetterAccessorArgument(SourceLoc nameLoc, - Identifier name, - TypeLoc elementTy, - AccessorKind accessorKind, - Parser &P) { +static ParamDecl * +createSetterAccessorArgument(SourceLoc nameLoc, Identifier name, + TypeLoc elementTy, AccessorKind accessorKind, + Parser &P) { // Add the parameter. If no name was specified, the name defaults to // 'value'. bool isNameImplicit = name.empty(); @@ -2815,26 +2896,27 @@ static TypedPattern *createSetterAccessorArgument(SourceLoc nameLoc, name = P.Context.getIdentifier(implName); } - VarDecl *value = new (P.Context) ParamDecl(/*IsLet*/true, - SourceLoc(), Identifier(), - nameLoc, name, - Type(), P.CurDeclContext); + auto result = new (P.Context) ParamDecl(/*IsLet*/true, SourceLoc(), + Identifier(), nameLoc, name, + Type(), P.CurDeclContext); if (isNameImplicit) - value->setImplicit(); + result->setImplicit(); - Pattern *namedPat = new (P.Context) NamedPattern(value, isNameImplicit); - return new (P.Context) TypedPattern(namedPat, elementTy.clone(P.Context), - /*Implicit*/true); + result->getTypeLoc() = elementTy.clone(P.Context); + + // AST Walker shouldn't go into the type recursively. + result->setIsTypeLocImplicit(true); + return result; } /// Parse a "(value)" specifier for "set" or "willSet" if present. Create a -/// pattern to represent the spelled argument or the implicit one if it is -/// missing. -static TypedPattern * +/// parameter list to represent the spelled argument or return null if none is +/// present. +static ParameterList * parseOptionalAccessorArgument(SourceLoc SpecifierLoc, TypeLoc ElementTy, Parser &P, AccessorKind Kind) { // 'set' and 'willSet' have a (value) parameter, 'didSet' takes an (oldValue) - // paramter and 'get' and always takes a () parameter. + // parameter and 'get' and always takes a () parameter. if (Kind != AccessorKind::IsSetter && Kind != AccessorKind::IsWillSet && Kind != AccessorKind::IsDidSet) return nullptr; @@ -2850,7 +2932,9 @@ parseOptionalAccessorArgument(SourceLoc SpecifierLoc, TypeLoc ElementTy, P.diagnose(P.Tok, diag::expected_accessor_name, (unsigned)Kind); P.skipUntil(tok::r_paren, tok::l_brace); if (P.Tok.is(tok::r_paren)) - P.consumeToken(); + EndLoc = P.consumeToken(); + else + EndLoc = StartLoc; } else { // We have a name. Name = P.Context.getIdentifier(P.Tok.getText()); @@ -2867,7 +2951,8 @@ parseOptionalAccessorArgument(SourceLoc SpecifierLoc, TypeLoc ElementTy, } if (Name.empty()) NameLoc = SpecifierLoc; - return createSetterAccessorArgument(NameLoc, Name, ElementTy, Kind, P); + auto param = createSetterAccessorArgument(NameLoc, Name, ElementTy, Kind, P); + return ParameterList::create(P.Context, StartLoc, param, EndLoc); } static unsigned skipUntilMatchingRBrace(Parser &P) { @@ -3009,7 +3094,7 @@ static void diagnoseRedundantAccessors(Parser &P, SourceLoc loc, /// \brief Parse a get-set clause, optionally containing a getter, setter, /// willSet, and/or didSet clauses. 'Indices' is a paren or tuple pattern, /// specifying the index list for a subscript. -bool Parser::parseGetSetImpl(ParseDeclOptions Flags, Pattern *Indices, +bool Parser::parseGetSetImpl(ParseDeclOptions Flags, ParameterList *Indices, TypeLoc ElementTy, ParsedAccessors &accessors, SourceLoc &LastValidLoc, SourceLoc StaticLoc, SourceLoc VarLBLoc, @@ -3079,11 +3164,11 @@ bool Parser::parseGetSetImpl(ParseDeclOptions Flags, Pattern *Indices, if (Tok.is(tok::l_paren)) diagnose(Loc, diag::protocol_setter_name); - auto *ValueNamePattern + auto *ValueNameParams = parseOptionalAccessorArgument(Loc, ElementTy, *this, Kind); // Set up a function declaration. - TheDecl = createAccessorFunc(Loc, ValueNamePattern, ElementTy, Indices, + TheDecl = createAccessorFunc(Loc, ValueNameParams, ElementTy, Indices, StaticLoc, Flags, Kind, addressorKind, this, AccessorKeywordLoc); TheDecl->getAttrs() = Attributes; @@ -3166,7 +3251,7 @@ bool Parser::parseGetSetImpl(ParseDeclOptions Flags, Pattern *Indices, Attributes = DeclAttributes(); } if (!IsFirstAccessor) { - // Can not have an implicit getter after other accessor. + // Cannot have an implicit getter after other accessor. diagnose(Tok, diag::expected_accessor_kw); skipUntil(tok::r_brace); // Don't signal an error since we recovered. @@ -3224,7 +3309,8 @@ bool Parser::parseGetSetImpl(ParseDeclOptions Flags, Pattern *Indices, LastValidLoc = Loc; } else { Scope S(this, ScopeKind::FunctionBody); - addPatternVariablesToScope(TheDecl->getBodyParamPatterns()); + for (auto PL : TheDecl->getParameterLists()) + addParametersToScope(PL); // Establish the new context. ParseFunctionBody CC(*this, TheDecl); @@ -3260,7 +3346,7 @@ bool Parser::parseGetSetImpl(ParseDeclOptions Flags, Pattern *Indices, return false; } -bool Parser::parseGetSet(ParseDeclOptions Flags, Pattern *Indices, +bool Parser::parseGetSet(ParseDeclOptions Flags, ParameterList *Indices, TypeLoc ElementTy, ParsedAccessors &accessors, SourceLoc StaticLoc, SmallVectorImpl &Decls) { @@ -3297,7 +3383,7 @@ void Parser::parseAccessorBodyDelayed(AbstractFunctionDecl *AFD) { // Ensure that we restore the parser state at exit. ParserPositionRAII PPR(*this); - // Create a lexer that can not go past the end state. + // Create a lexer that cannot go past the end state. Lexer LocalLex(*L, BeginParserPosition.LS, EndLexerState); // Temporarily swap out the parser's current lexer with our new one. @@ -3319,7 +3405,8 @@ void Parser::parseAccessorBodyDelayed(AbstractFunctionDecl *AFD) { } /// \brief Parse the brace-enclosed getter and setter for a variable. -VarDecl *Parser::parseDeclVarGetSet(Pattern *pattern, ParseDeclOptions Flags, +VarDecl *Parser::parseDeclVarGetSet(Pattern *pattern, + ParseDeclOptions Flags, SourceLoc StaticLoc, bool hasInitializer, const DeclAttributes &Attributes, SmallVectorImpl &Decls) { @@ -3400,7 +3487,7 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage, bool invalid, ParseDeclOptions flags, SourceLoc staticLoc, const DeclAttributes &attrs, - TypeLoc elementTy, Pattern *indices, + TypeLoc elementTy, ParameterList *indices, SmallVectorImpl &decls) { auto flagInvalidAccessor = [&](FuncDecl *&func) { if (func) { @@ -3424,10 +3511,10 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage, // Create an implicit accessor declaration. auto createImplicitAccessor = [&](AccessorKind kind, AddressorKind addressorKind, - TypedPattern *argPattern) -> FuncDecl* { - auto accessor = createAccessorFunc(SourceLoc(), argPattern, - elementTy, indices, staticLoc, flags, - kind, addressorKind, &P, SourceLoc()); + ParameterList *argList) -> FuncDecl* { + auto accessor = createAccessorFunc(SourceLoc(), argList, elementTy, indices, + staticLoc, flags, kind, addressorKind, + &P, SourceLoc()); accessor->setImplicit(); decls.push_back(accessor); return accessor; @@ -3527,12 +3614,13 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage, AddressorKind::NotAddressor, nullptr); auto argFunc = (WillSet ? WillSet : DidSet); - auto argLoc = argFunc->getBodyParamPatterns().back()->getLoc(); + auto argLoc = argFunc->getParameterLists().back()->getStartLoc(); - auto argPattern = createSetterAccessorArgument(argLoc, Identifier(), - elementTy, AccessorKind::IsSetter, P); + auto argument = createSetterAccessorArgument(argLoc, Identifier(),elementTy, + AccessorKind::IsSetter, P); + auto argList = ParameterList::create(P.Context, argument); Set = createImplicitAccessor(AccessorKind::IsSetter, - AddressorKind::NotAddressor, argPattern); + AddressorKind::NotAddressor, argList); storage->setObservingAccessors(Get, Set, nullptr); return; @@ -3549,11 +3637,12 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage, // setter and record what we've got. if (MutableAddressor) { assert(Get && !Set); - auto argPattern = + auto argument = createSetterAccessorArgument(MutableAddressor->getLoc(), Identifier(), elementTy, AccessorKind::IsSetter, P); + auto argList = ParameterList::create(P.Context, argument); Set = createImplicitAccessor(AccessorKind::IsSetter, - AddressorKind::NotAddressor, argPattern); + AddressorKind::NotAddressor, argList); storage->makeComputedWithMutableAddress(LBLoc, Get, Set, nullptr, MutableAddressor, RBLoc); @@ -3643,7 +3732,7 @@ ParserStatus Parser::parseDeclVar(ParseDeclOptions Flags, // No matter what error path we take, make sure the // PatternBindingDecl/TopLevel code block are added. - defer([&]{ + defer { // If we didn't parse any patterns, don't create the pattern binding decl. if (PBDEntries.empty()) return; @@ -3683,7 +3772,7 @@ ParserStatus Parser::parseDeclVar(ParseDeclOptions Flags, // specific spot to get it in before any accessors, which SILGen seems to // want. Decls.insert(Decls.begin()+NumDeclsInResult, PBD); - }); + }; do { Pattern *pattern; @@ -3977,7 +4066,7 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, GenericParams = maybeParseGenericParams(); } - SmallVector BodyParams; + SmallVector BodyParams; // If we're within a container, add an implicit first pattern to match the // container type as an element named 'self'. @@ -3986,12 +4075,10 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, // "(inout self: FooTy)->(int)->int", and a static function // "(int)->int" on FooTy into "(self: FooTy.Type)->(int)->int". // Note that we can't actually compute the type here until Sema. - if (HasContainerType) { - Pattern *SelfPattern = buildImplicitSelfParameter(NameLoc, CurDeclContext); - BodyParams.push_back(SelfPattern); - } + if (HasContainerType) + BodyParams.push_back(ParameterList::createSelf(NameLoc, CurDeclContext)); - DefaultArgumentInfo DefaultArgs; + DefaultArgumentInfo DefaultArgs(HasContainerType); TypeRepr *FuncRetTy = nullptr; DeclName FullName; SourceLoc throwsLoc; @@ -4038,7 +4125,8 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, StaticSpellingKind StaticSpelling, CodeCompletion->setDelayedParsedDecl(FD); DefaultArgs.setFunctionContext(FD); - addPatternVariablesToScope(FD->getBodyParamPatterns()); + for (auto PL : FD->getParameterLists()) + addParametersToScope(PL); setLocalDiscriminator(FD); // Establish the new context. @@ -4098,7 +4186,7 @@ bool Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) { // Ensure that we restore the parser state at exit. ParserPositionRAII PPR(*this); - // Create a lexer that can not go past the end state. + // Create a lexer that cannot go past the end state. Lexer LocalLex(*L, BeginParserPosition.LS, EndLexerState); // Temporarily swap out the parser's current lexer with our new one. @@ -4236,6 +4324,7 @@ ParserStatus Parser::parseDeclEnumCase(ParseDeclOptions Flags, // Handle the likely case someone typed 'case X, case Y'. if (Tok.is(tok::kw_case) && CommaLoc.isValid()) { diagnose(Tok, diag::expected_identifier_after_case_comma); + Status.setIsParseError(); return Status; } @@ -4681,7 +4770,7 @@ ParserStatus Parser::parseDeclSubscript(ParseDeclOptions Flags, } SmallVector argumentNames; - ParserResult Indices + ParserResult Indices = parseSingleParameterClause(ParameterContextKind::Subscript, &argumentNames); if (Indices.isNull() || Indices.hasCodeCompletion()) @@ -4717,7 +4806,11 @@ ParserStatus Parser::parseDeclSubscript(ParseDeclOptions Flags, if (Tok.isNot(tok::l_brace)) { // Subscript declarations must always have at least a getter, so they need // to be followed by a {. - diagnose(Tok, diag::expected_lbrace_subscript); + if (Flags.contains(PD_InProtocol)) + diagnose(Tok, diag::expected_lbrace_subscript_protocol) + .fixItInsertAfter(ElementTy.get()->getEndLoc(), " { get set }"); + else + diagnose(Tok, diag::expected_lbrace_subscript); Status.setIsParseError(); } else { if (parseGetSet(Flags, Indices.get(), ElementTy.get(), @@ -4776,8 +4869,8 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) { // Parse the parameters. // FIXME: handle code completion in Arguments. - DefaultArgumentInfo DefaultArgs; - Pattern *BodyPattern; + DefaultArgumentInfo DefaultArgs(/*hasSelf*/true); + ParameterList *BodyPattern; DeclName FullName; ParserStatus SignatureStatus = parseConstructorArguments(FullName, BodyPattern, DefaultArgs); @@ -4801,12 +4894,12 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) { Attributes.add(new (Context) RethrowsAttr(throwsLoc)); } - auto *SelfPattern = buildImplicitSelfParameter(ConstructorLoc,CurDeclContext); + auto *SelfDecl = ParamDecl::createSelf(ConstructorLoc, CurDeclContext); Scope S2(this, ScopeKind::ConstructorBody); auto *CD = new (Context) ConstructorDecl(FullName, ConstructorLoc, Failability, FailabilityLoc, - SelfPattern, BodyPattern, + SelfDecl, BodyPattern, GenericParams, throwsLoc, CurDeclContext); @@ -4827,7 +4920,9 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) { // Tell the type checker not to touch this constructor. CD->setInvalid(); } - addPatternVariablesToScope(ArrayRef{SelfPattern, BodyPattern} ); + + addToScope(SelfDecl); + addParametersToScope(BodyPattern); // '{' if (Tok.is(tok::l_brace)) { @@ -4894,11 +4989,11 @@ parseDeclDeinit(ParseDeclOptions Flags, DeclAttributes &Attributes) { } } - auto *SelfPattern = buildImplicitSelfParameter(DestructorLoc, CurDeclContext); + auto *SelfDecl = ParamDecl::createSelf(DestructorLoc, CurDeclContext); Scope S(this, ScopeKind::DestructorBody); auto *DD = new (Context) DestructorDecl(Context.Id_deinit, DestructorLoc, - SelfPattern, CurDeclContext); + SelfDecl, CurDeclContext); // Parse the body. if (Tok.is(tok::l_brace)) { @@ -4937,7 +5032,23 @@ Parser::parseDeclOperator(ParseDeclOptions Flags, DeclAttributes &Attributes) { bool AllowTopLevel = Flags.contains(PD_AllowTopLevel); if (!Tok.isAnyOperator() && !Tok.is(tok::exclaim_postfix)) { - diagnose(Tok, diag::expected_operator_name_after_operator); + // A common error is to try to define an operator with something in the + // unicode plane considered to be an operator, or to try to define an + // operator like "not". Diagnose this specifically. + if (Tok.is(tok::identifier)) + diagnose(Tok, diag::identifier_when_expecting_operator, + Context.getIdentifier(Tok.getText())); + else + diagnose(Tok, diag::expected_operator_name_after_operator); + + // To improve recovery, check to see if we have a { right after this token. + // If so, swallow until the end } to avoid tripping over the body of the + // malformed operator decl. + if (peekToken().is(tok::l_brace)) { + consumeToken(); + skipSingle(); + } + return nullptr; } diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 7b9555687b674..2e4c41277bd32 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,6 +22,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "swift/Basic/Fallthrough.h" +#include "swift/Basic/StringExtras.h" #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" @@ -37,7 +38,7 @@ static Expr *createArgWithTrailingClosure(ASTContext &context, SourceLoc rightParen, Expr *closure) { // If there are no elements, just build a parenthesized expression around - // the cosure. + // the closure. if (elementsIn.empty()) { return new (context) ParenExpr(leftParen, closure, rightParen, /*hasTrailingClosure=*/true); @@ -291,6 +292,10 @@ ParserResult Parser::parseExprSequence(Diag<> Message, CodeCompletion->completeAssignmentRHS(assign); } consumeToken(); + if (SequencedExprs.size() > 0 && (SequencedExprs.size() & 1) == 0) { + // Make sure we have odd number of sequence exprs. + SequencedExprs.pop_back(); + } auto Result = SequencedExprs.size() == 1 ? makeParserResult(SequencedExprs[0]): makeParserResult(SequenceExpr::create(Context, SequencedExprs)); @@ -432,7 +437,7 @@ ParserResult Parser::parseExprUnary(Diag<> Message, bool isExprBasic) { case tok::oper_postfix: // Postfix operators cannot start a subexpression, but can happen - // syntactically because the operator may just follow whatever preceeds this + // syntactically because the operator may just follow whatever precedes this // expression (and that may not always be an expression). diagnose(Tok, diag::invalid_postfix_operator); Tok.setKind(tok::oper_prefix); @@ -462,7 +467,7 @@ ParserResult Parser::parseExprUnary(Diag<> Message, bool isExprBasic) { if (SubExpr.isNull()) return nullptr; - // Check if we have an unary '-' with number literal sub-expression, for + // Check if we have a unary '-' with number literal sub-expression, for // example, "-42" or "-1.25". if (auto *LE = dyn_cast(SubExpr.get())) { if (Operator->hasName() && Operator->getName().str() == "-") { @@ -626,14 +631,14 @@ static StringRef copyAndStripUnderscores(ASTContext &C, StringRef orig) { /// the start of a trailing closure, or start the variable accessor block. /// /// Check to see if the '{' is followed by a 'didSet' or a 'willSet' label, -/// possibly preceeded by attributes. If so, we disambiguate the parse as the +/// possibly preceded by attributes. If so, we disambiguate the parse as the /// start of a get-set block in a variable definition (not as a trailing /// closure). static bool isStartOfGetSetAccessor(Parser &P) { assert(P.Tok.is(tok::l_brace) && "not checking a brace?"); // The only case this can happen is if the accessor label is immediately after - // a brace (possibly preceeded by attributes). "get" is implicit, so it can't + // a brace (possibly preceded by attributes). "get" is implicit, so it can't // be checked for. Conveniently however, get/set properties are not allowed // to have initializers, so we don't have an ambiguity, we just have to check // for observing accessors. @@ -645,7 +650,7 @@ static bool isStartOfGetSetAccessor(Parser &P) { NextToken.isContextualKeyword("willSet")) return true; - // If we don't have attributes, then it can not be an accessor block. + // If we don't have attributes, then it cannot be an accessor block. if (NextToken.isNot(tok::at_sign)) return false; @@ -1516,7 +1521,7 @@ Expr *Parser::parseExprEditorPlaceholder(Token PlaceholderTok, bool Parser:: parseClosureSignatureIfPresent(SmallVectorImpl &captureList, - Pattern *¶ms, SourceLoc &throwsLoc, + ParameterList *¶ms, SourceLoc &throwsLoc, SourceLoc &arrowLoc, TypeRepr *&explicitResultType, SourceLoc &inLoc){ // Clear out result parameters. @@ -1703,33 +1708,26 @@ parseClosureSignatureIfPresent(SmallVectorImpl &captureList, invalid = true; } else { // Parse identifier (',' identifier)* - SmallVector elements; + SmallVector elements; do { - if (Tok.is(tok::identifier) || Tok.is(tok::kw__)) { - Identifier name = Tok.is(tok::identifier) ? - Context.getIdentifier(Tok.getText()) : Identifier(); - auto var = new (Context) ParamDecl(/*IsLet*/ true, - SourceLoc(), Identifier(), - Tok.getLoc(), - name, - Type(), nullptr); - elements.push_back(TuplePatternElt(new (Context) NamedPattern(var))); - consumeToken(); - } else { + if (Tok.isNot(tok::identifier, tok::kw__)) { diagnose(Tok, diag::expected_closure_parameter_name); invalid = true; break; } + Identifier name = Tok.is(tok::identifier) ? + Context.getIdentifier(Tok.getText()) : Identifier(); + auto var = new (Context) ParamDecl(/*IsLet*/ true, SourceLoc(), + Identifier(), Tok.getLoc(), name, + Type(), nullptr); + elements.push_back(var); + consumeToken(); + // Consume a comma to continue. - if (consumeIf(tok::comma)) { - continue; - } - - break; - } while (true); + } while (consumeIf(tok::comma)); - params = TuplePattern::create(Context, SourceLoc(), elements,SourceLoc()); + params = ParameterList::create(Context, elements); } if (Tok.is(tok::kw_throws)) { @@ -1802,7 +1800,7 @@ ParserResult Parser::parseExprClosure() { SourceLoc leftBrace = consumeToken(); // Parse the closure-signature, if present. - Pattern *params = nullptr; + ParameterList *params = nullptr; SourceLoc throwsLoc; SourceLoc arrowLoc; TypeRepr *explicitResultType; @@ -1834,7 +1832,7 @@ ParserResult Parser::parseExprClosure() { // Handle parameters. if (params) { // Add the parameters into scope. - addPatternVariablesToScope(params); + addParametersToScope(params); } else { // There are no parameters; allow anonymous closure variables. // FIXME: We could do this all the time, and then provide Fix-Its @@ -1862,18 +1860,17 @@ ParserResult Parser::parseExprClosure() { if (!params) { // Create a parameter pattern containing the anonymous variables. auto &anonVars = AnonClosureVars.back().second; - SmallVector elements; - for (auto anonVar : anonVars) { - elements.push_back(TuplePatternElt(new (Context) NamedPattern(anonVar))); - } - params = TuplePattern::createSimple(Context, leftBrace, elements, - leftBrace, /*implicit*/true); + SmallVector elements; + for (auto anonVar : anonVars) + elements.push_back(anonVar); + + params = ParameterList::create(Context, leftBrace, elements, leftBrace); // Pop out of the anonymous closure variables scope. AnonClosureVars.pop_back(); // Attach the parameters to the closure. - closure->setParams(params); + closure->setParameterList(params); closure->setHasAnonymousClosureVars(); } @@ -1949,7 +1946,7 @@ Expr *Parser::parseExprAnonClosureArg() { // generate the anonymous variables we need. auto closure = dyn_cast_or_null( dyn_cast(CurDeclContext)); - if (!closure || closure->getParams()) { + if (!closure || closure->getParameters()) { // FIXME: specialize diagnostic when there were closure parameters. // We can be fairly smart here. diagnose(Loc, closure ? diag::anon_closure_arg_in_closure_with_args @@ -1965,9 +1962,9 @@ Expr *Parser::parseExprAnonClosureArg() { StringRef varName = ("$" + Twine(nextIdx)).toStringRef(StrBuf); Identifier ident = Context.getIdentifier(varName); SourceLoc varLoc = leftBraceLoc; - VarDecl *var = new (Context) ParamDecl(/*IsLet*/ true, - SourceLoc(), Identifier(), - varLoc, ident, Type(), closure); + auto *var = new (Context) ParamDecl(/*IsLet*/ true, SourceLoc(), + Identifier(), varLoc, ident, Type(), + closure); decls.push_back(var); } @@ -2005,13 +2002,21 @@ ParserResult Parser::parseExprList(tok LeftTok, tok RightTok) { Identifier FieldName; SourceLoc FieldNameLoc; - // Check to see if there is a field specifier - if (Tok.is(tok::identifier) && peekToken().is(tok::colon)) { - FieldNameLoc = Tok.getLoc(); - if (parseIdentifier(FieldName, - diag::expected_field_spec_name_tuple_expr)) { - return makeParserError(); + // Check to see if there is an argument label. + if (Tok.canBeArgumentLabel() && peekToken().is(tok::colon)) { + // If this was an escaped identifier that need not have been escaped, + // say so. + if (Tok.isEscapedIdentifier() && canBeArgumentLabel(Tok.getText())) { + SourceLoc start = Tok.getLoc(); + SourceLoc end = start.getAdvancedLoc(Tok.getLength()); + diagnose(Tok, diag::escaped_parameter_name, Tok.getText()) + .fixItRemoveChars(start, start.getAdvancedLoc(1)) + .fixItRemoveChars(end.getAdvancedLoc(-1), end); } + + if (!Tok.is(tok::kw__)) + FieldName = Context.getIdentifier(Tok.getText()); + FieldNameLoc = consumeToken(); consumeToken(tok::colon); } @@ -2338,6 +2343,13 @@ void Parser::addPatternVariablesToScope(ArrayRef Patterns) { } } +void Parser::addParametersToScope(ParameterList *PL) { + for (auto param : *PL) + if (param->hasName()) + addToScope(param); +} + + /// Parse availability query specification. /// diff --git a/lib/Parse/ParseGeneric.cpp b/lib/Parse/ParseGeneric.cpp index b92ce1d4acc91..ec4d18858efb8 100644 --- a/lib/Parse/ParseGeneric.cpp +++ b/lib/Parse/ParseGeneric.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index 1c146b900f60c..c1cbf69476195 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -119,11 +119,12 @@ static bool startsParameterName(Parser &parser, bool isClosure) { return true; // To have a parameter name here, we need a name. - if (!parser.Tok.is(tok::identifier)) + if (!parser.Tok.canBeArgumentLabel()) return false; - // If the next token is another identifier, '_', or ':', this is a name. - if (parser.peekToken().isAny(tok::identifier, tok::kw__, tok::colon)) + // If the next token can be an argument label or is ':', this is a name. + const auto &nextTok = parser.peekToken(); + if (nextTok.is(tok::colon) || nextTok.canBeArgumentLabel()) return true; // The identifier could be a name or it could be a type. In a closure, we @@ -179,15 +180,15 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc, param.LetVarInOutLoc = consumeToken(); param.SpecifierKind = ParsedParameter::InOut; } else if (Tok.is(tok::kw_let)) { - diagnose(Tok.getLoc(), diag::let_on_param_is_redundant, + diagnose(Tok.getLoc(), diag::var_not_allowed_in_pattern, Tok.is(tok::kw_let)).fixItRemove(Tok.getLoc()); param.LetVarInOutLoc = consumeToken(); param.SpecifierKind = ParsedParameter::Let; } else if (Tok.is(tok::kw_var)) { - diagnose(Tok.getLoc(), diag::var_not_allowed_in_pattern) - .fixItRemove(Tok.getLoc()); + diagnose(Tok.getLoc(), diag::var_not_allowed_in_pattern, + Tok.is(tok::kw_let)).fixItRemove(Tok.getLoc()); param.LetVarInOutLoc = consumeToken(); - param.SpecifierKind = ParsedParameter::Let; + param.SpecifierKind = ParsedParameter::Var; } // Redundant specifiers are fairly common, recognize, reject, and recover @@ -198,49 +199,25 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc, consumeToken(); } - // '#'? - if (Tok.is(tok::pound)) - param.PoundLoc = consumeToken(tok::pound); - - if (param.PoundLoc.isValid() || startsParameterName(*this, isClosure)) { + if (startsParameterName(*this, isClosure)) { // identifier-or-none for the first name - if (Tok.is(tok::identifier)) { - param.FirstName = Context.getIdentifier(Tok.getText()); - param.FirstNameLoc = consumeToken(); - - // Operators can not have API names. - if (paramContext == ParameterContextKind::Operator && - param.PoundLoc.isValid()) { - diagnose(param.PoundLoc, - diag::parameter_operator_keyword_argument) - .fixItRemove(param.PoundLoc); - param.PoundLoc = SourceLoc(); - } - } else if (Tok.is(tok::kw__)) { - // A back-tick cannot precede an empty name marker. - if (param.PoundLoc.isValid()) { - diagnose(Tok, diag::parameter_backtick_empty_name) - .fixItRemove(param.PoundLoc); - param.PoundLoc = SourceLoc(); - } - + if (Tok.is(tok::kw__)) { param.FirstNameLoc = consumeToken(); } else { - assert(param.PoundLoc.isValid() && "startsParameterName() lied"); - diagnose(Tok, diag::parameter_backtick_missing_name); - param.FirstNameLoc = param.PoundLoc; - param.PoundLoc = SourceLoc(); + assert(Tok.canBeArgumentLabel() && "startsParameterName() lied"); + param.FirstName = Context.getIdentifier(Tok.getText()); + param.FirstNameLoc = consumeToken(); } // identifier-or-none? for the second name - if (Tok.is(tok::identifier)) { - param.SecondName = Context.getIdentifier(Tok.getText()); - param.SecondNameLoc = consumeToken(); - } else if (Tok.is(tok::kw__)) { + if (Tok.canBeArgumentLabel()) { + if (!Tok.is(tok::kw__)) + param.SecondName = Context.getIdentifier(Tok.getText()); + param.SecondNameLoc = consumeToken(); } - // Operators can not have API names. + // Operators cannot have API names. if (paramContext == ParameterContextKind::Operator && !param.FirstName.empty() && param.SecondNameLoc.isValid()) { @@ -253,31 +230,10 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc, param.SecondNameLoc = SourceLoc(); } - // Cannot have a pound and two names. - if (param.PoundLoc.isValid() && param.SecondNameLoc.isValid()) { - diagnose(param.PoundLoc, diag::parameter_backtick_two_names) - .fixItRemove(param.PoundLoc); - param.PoundLoc = SourceLoc(); - } - // (':' type)? if (Tok.is(tok::colon)) { param.ColonLoc = consumeToken(); - // Special case handling of @autoclosure attribute on the type, which - // was supported in Swift 1.0 and 1.1, but removed in Swift 1.2 (moved - // to a decl attribute). - if (Tok.is(tok::at_sign) && - peekToken().isContextualKeyword("autoclosure")) { - SourceLoc AtLoc = consumeToken(tok::at_sign); - SourceLoc ACLoc = consumeToken(tok::identifier); - diagnose(AtLoc, diag::autoclosure_is_decl_attribute) - .fixItRemove(SourceRange(AtLoc, ACLoc)) - .fixItInsert(StartLoc, "@autoclosure "); - param.Attrs.add(new (Context) AutoClosureAttr(AtLoc, ACLoc, - /*escaping=*/false)); - } - auto type = parseType(diag::expected_parameter_type); status |= type; param.Type = type.getPtrOrNull(); @@ -339,10 +295,8 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc, }); } -/// Map parsed parameters to argument and body patterns. -/// -/// \returns the pattern describing the parsed parameters. -static Pattern* +/// Map parsed parameters to a ParameterList. +static ParameterList * mapParsedParameters(Parser &parser, SourceLoc leftParenLoc, MutableArrayRef params, @@ -353,53 +307,39 @@ mapParsedParameters(Parser &parser, auto &ctx = parser.Context; // Local function to create a pattern for a single parameter. - auto createParamPattern = [&](SourceLoc &letVarInOutLoc, + auto createParam = [&](SourceLoc &letVarInOutLoc, Parser::ParsedParameter::SpecifierKindTy &specifierKind, Identifier argName, SourceLoc argNameLoc, Identifier paramName, SourceLoc paramNameLoc, TypeRepr *type, - const DeclAttributes &Attrs) -> Pattern * { - // Create the parameter based on the name. - Pattern *param; - ParamDecl *var = nullptr; - // Create a variable to capture this. - var = new (ctx) ParamDecl(specifierKind == Parser::ParsedParameter::Let, - argNameLoc, argName, - paramNameLoc, paramName, Type(), - parser.CurDeclContext); - var->getAttrs() = Attrs; + const DeclAttributes &Attrs) -> ParamDecl * { + bool isLet = specifierKind == Parser::ParsedParameter::Let; + auto param = new (ctx) ParamDecl(isLet, argNameLoc, argName, + paramNameLoc, paramName, Type(), + parser.CurDeclContext); + param->getAttrs() = Attrs; + if (argNameLoc.isInvalid() && paramNameLoc.isInvalid()) - var->setImplicit(); - param = new (ctx) NamedPattern(var); - + param->setImplicit(); + // If a type was provided, create the typed pattern. if (type) { // If 'inout' was specified, turn the type into an in-out type. if (specifierKind == Parser::ParsedParameter::InOut) type = new (ctx) InOutTypeRepr(type, letVarInOutLoc); - param = new (ctx) TypedPattern(param, type); + param->getTypeLoc() = TypeLoc(type); } else if (specifierKind == Parser::ParsedParameter::InOut) { parser.diagnose(letVarInOutLoc, diag::inout_must_have_type); letVarInOutLoc = SourceLoc(); specifierKind = Parser::ParsedParameter::Let; } - - // If 'var' or 'let' was specified explicitly, create a pattern for it. - if (specifierKind != Parser::ParsedParameter::InOut && - letVarInOutLoc.isValid()) { - bool isLet = specifierKind == Parser::ParsedParameter::Let; - param = new (ctx) VarPattern(letVarInOutLoc, isLet, param); - } - - if (var) - var->setParamParentPattern(param); return param; }; // Collect the elements of the tuple patterns for argument and body // parameters. - SmallVector elements; + SmallVector elements; SourceLoc ellipsisLoc; bool isFirstParameter = true; for (auto ¶m : params) { @@ -427,7 +367,7 @@ mapParsedParameters(Parser &parser, } // Create the pattern. - Pattern *pattern; + ParamDecl *result = nullptr; Identifier argName; Identifier paramName; if (param.SecondNameLoc.isValid()) { @@ -435,10 +375,10 @@ mapParsedParameters(Parser &parser, paramName = param.SecondName; // Both names were provided, so pass them in directly. - pattern = createParamPattern(param.LetVarInOutLoc, param.SpecifierKind, - argName, param.FirstNameLoc, - paramName, param.SecondNameLoc, - param.Type, param.Attrs); + result = createParam(param.LetVarInOutLoc, param.SpecifierKind, + argName, param.FirstNameLoc, + paramName, param.SecondNameLoc, + param.Type, param.Attrs); // If the first name is empty and this parameter would not have been // an API name by default, complain. @@ -461,31 +401,14 @@ mapParsedParameters(Parser &parser, .fixItRemoveChars(param.FirstNameLoc, param.SecondNameLoc); } } else { - // If it's an API name by default, or there was a pound, we have an - // API name. - if (isKeywordArgumentByDefault || param.PoundLoc.isValid()) { + if (isKeywordArgumentByDefault) argName = param.FirstName; - - // THe pound is going away. Complain. - if (param.PoundLoc.isValid()) { - if (isKeywordArgumentByDefault) { - parser.diagnose(param.PoundLoc, diag::parameter_extraneous_pound, - argName) - .fixItRemove(param.PoundLoc); - } else { - parser.diagnose(param.PoundLoc, diag::parameter_pound_double_up, - argName.str()) - .fixItReplace(param.PoundLoc, (argName.str() + " ").str()); - } - } - } - paramName = param.FirstName; - pattern = createParamPattern(param.LetVarInOutLoc, param.SpecifierKind, - argName, SourceLoc(), - param.FirstName, param.FirstNameLoc, - param.Type, param.Attrs); + result = createParam(param.LetVarInOutLoc, param.SpecifierKind, + argName, SourceLoc(), + param.FirstName, param.FirstNameLoc, + param.Type, param.Attrs); } // If this parameter had an ellipsis, check whether it's the last parameter. @@ -496,29 +419,30 @@ mapParsedParameters(Parser &parser, .fixItRemove(param.EllipsisLoc); param.EllipsisLoc = SourceLoc(); - } else if (!isa(pattern)) { + } else if (!result->getTypeLoc().getTypeRepr()) { parser.diagnose(param.EllipsisLoc, diag::untyped_pattern_ellipsis) - .highlight(pattern->getSourceRange()); + .highlight(result->getSourceRange()); param.EllipsisLoc = SourceLoc(); } else { ellipsisLoc = param.EllipsisLoc; + result->setVariadic(); } } - // Default arguments are only permitted on the first parameter clause. - if (param.DefaultArg && !isFirstParameterClause) { - parser.diagnose(param.EqualLoc, diag::non_func_decl_pattern_init) - .fixItRemove(SourceRange(param.EqualLoc, - param.DefaultArg->getExpr()->getEndLoc())); + if (param.DefaultArg) { + if (!isFirstParameterClause) { + // Default arguments are only permitted on the first parameter clause. + parser.diagnose(param.EqualLoc, diag::non_func_decl_pattern_init) + .fixItRemove(SourceRange(param.EqualLoc, + param.DefaultArg->getExpr()->getEndLoc())); + } else { + result->setDefaultArgumentKind(getDefaultArgKind(param.DefaultArg)); + result->setDefaultValue(param.DefaultArg); + } } - // Create the tuple pattern elements. - auto defArgKind = getDefaultArgKind(param.DefaultArg); - elements.push_back(TuplePatternElt(argName, param.FirstNameLoc, pattern, - param.EllipsisLoc.isValid(), - param.EllipsisLoc, param.DefaultArg, - defArgKind)); + elements.push_back(result); if (argNames) argNames->push_back(argName); @@ -526,11 +450,11 @@ mapParsedParameters(Parser &parser, isFirstParameter = false; } - return TuplePattern::createSimple(ctx, leftParenLoc, elements, rightParenLoc); + return ParameterList::create(ctx, leftParenLoc, elements, rightParenLoc); } /// Parse a single parameter-clause. -ParserResult Parser::parseSingleParameterClause( +ParserResult Parser::parseSingleParameterClause( ParameterContextKind paramContext, SmallVectorImpl *namePieces) { ParserStatus status; @@ -542,11 +466,11 @@ ParserResult Parser::parseSingleParameterClause( /*defaultArgs=*/nullptr, paramContext); // Turn the parameter clause into argument and body patterns. - auto pattern = mapParsedParameters(*this, leftParenLoc, params, + auto paramList = mapParsedParameters(*this, leftParenLoc, params, rightParenLoc, true, namePieces, paramContext); - return makeParserResult(status, pattern); + return makeParserResult(status, paramList); } /// Parse function arguments. @@ -561,13 +485,13 @@ ParserResult Parser::parseSingleParameterClause( /// ParserStatus Parser::parseFunctionArguments(SmallVectorImpl &NamePieces, - SmallVectorImpl &BodyPatterns, + SmallVectorImpl &BodyParams, ParameterContextKind paramContext, DefaultArgumentInfo &DefaultArgs) { // Parse parameter-clauses. ParserStatus status; bool isFirstParameterClause = true; - unsigned FirstBodyPatternIndex = BodyPatterns.size(); + unsigned FirstBodyPatternIndex = BodyParams.size(); while (Tok.is(tok::l_paren)) { SmallVector params; SourceLoc leftParenLoc, rightParenLoc; @@ -583,39 +507,34 @@ Parser::parseFunctionArguments(SmallVectorImpl &NamePieces, isFirstParameterClause ? &NamePieces : nullptr, paramContext); - BodyPatterns.push_back(pattern); + BodyParams.push_back(pattern); isFirstParameterClause = false; paramContext = ParameterContextKind::Curried; } // If the decl uses currying syntax, warn that that syntax is going away. - if (BodyPatterns.size() - FirstBodyPatternIndex > 1) { + if (BodyParams.size() - FirstBodyPatternIndex > 1) { SourceRange allPatternsRange( - BodyPatterns[FirstBodyPatternIndex]->getStartLoc(), - BodyPatterns.back()->getEndLoc()); + BodyParams[FirstBodyPatternIndex]->getStartLoc(), + BodyParams.back()->getEndLoc()); auto diag = diagnose(allPatternsRange.Start, diag::parameter_curry_syntax_removed); diag.highlight(allPatternsRange); bool seenArg = false; - auto isEmptyPattern = [](Pattern *pattern) -> bool { - auto *tuplePattern = dyn_cast(pattern); - return tuplePattern && tuplePattern->getNumElements() == 0; - }; - for (unsigned i = FirstBodyPatternIndex; i < BodyPatterns.size() - 1; i++) { + for (unsigned i = FirstBodyPatternIndex; i < BodyParams.size() - 1; i++) { // Replace ")(" with ", ", so "(x: Int)(y: Int)" becomes // "(x: Int, y: Int)". But just delete them if they're not actually // separating any arguments, e.g. in "()(y: Int)". StringRef replacement(", "); - Pattern *leftPattern = BodyPatterns[i]; - Pattern *rightPattern = BodyPatterns[i + 1]; - if (!isEmptyPattern(leftPattern)) { + auto *leftParamList = BodyParams[i]; + auto *rightParamList = BodyParams[i + 1]; + if (leftParamList->size() != 0) seenArg = true; - } - if (!seenArg || isEmptyPattern(rightPattern)) { + if (!seenArg || rightParamList->size() == 0) replacement = ""; - } - diag.fixItReplace(SourceRange(leftPattern->getEndLoc(), - rightPattern->getStartLoc()), + + diag.fixItReplace(SourceRange(leftParamList->getEndLoc(), + rightParamList->getStartLoc()), replacement); } } @@ -633,7 +552,7 @@ Parser::parseFunctionArguments(SmallVectorImpl &NamePieces, ParserStatus Parser::parseFunctionSignature(Identifier SimpleName, DeclName &FullName, - SmallVectorImpl &bodyPatterns, + SmallVectorImpl &bodyParams, DefaultArgumentInfo &defaultArgs, SourceLoc &throwsLoc, bool &rethrows, @@ -651,28 +570,26 @@ Parser::parseFunctionSignature(Identifier SimpleName, else paramContext = ParameterContextKind::Function; - Status = parseFunctionArguments(NamePieces, bodyPatterns, paramContext, + Status = parseFunctionArguments(NamePieces, bodyParams, paramContext, defaultArgs); FullName = DeclName(Context, SimpleName, llvm::makeArrayRef(NamePieces.begin() + 1, NamePieces.end())); - if (bodyPatterns.empty()) { + if (bodyParams.empty()) { // If we didn't get anything, add a () pattern to avoid breaking // invariants. assert(Status.hasCodeCompletion() || Status.isError()); - bodyPatterns.push_back(TuplePattern::create(Context, Tok.getLoc(), - {}, Tok.getLoc())); + bodyParams.push_back(ParameterList::createEmpty(Context)); } } else { diagnose(Tok, diag::func_decl_without_paren); Status = makeParserError(); // Recover by creating a '() -> ?' signature. - auto *EmptyTuplePattern = - TuplePattern::create(Context, PreviousLoc, {}, PreviousLoc); - bodyPatterns.push_back(EmptyTuplePattern); - FullName = DeclName(Context, SimpleName, { }); + bodyParams.push_back(ParameterList::createEmpty(Context, PreviousLoc, + PreviousLoc)); + FullName = DeclName(Context, SimpleName, bodyParams.back()); } // Check for the 'throws' keyword. @@ -739,7 +656,8 @@ Parser::parseFunctionSignature(Identifier SimpleName, } ParserStatus -Parser::parseConstructorArguments(DeclName &FullName, Pattern *&BodyPattern, +Parser::parseConstructorArguments(DeclName &FullName, + ParameterList *&BodyParams, DefaultArgumentInfo &DefaultArgs) { // If we don't have the leading '(', complain. if (!Tok.is(tok::l_paren)) { @@ -750,10 +668,9 @@ Parser::parseConstructorArguments(DeclName &FullName, Pattern *&BodyPattern, diag.fixItInsert(Tok.getLoc(), "() "); } - // Create an empty tuple to recover. - BodyPattern = TuplePattern::createSimple(Context, PreviousLoc, {}, - PreviousLoc, true); - FullName = DeclName(Context, Context.Id_init, { }); + // Create an empty parameter list to recover. + BodyParams = ParameterList::createEmpty(Context, PreviousLoc, PreviousLoc); + FullName = DeclName(Context, Context.Id_init, BodyParams); return makeParserError(); } @@ -768,11 +685,11 @@ Parser::parseConstructorArguments(DeclName &FullName, Pattern *&BodyPattern, // Turn the parameter clause into argument and body patterns. llvm::SmallVector namePieces; - BodyPattern = mapParsedParameters(*this, leftParenLoc, params, - rightParenLoc, - /*isFirstParameterClause=*/true, - &namePieces, - ParameterContextKind::Initializer); + BodyParams = mapParsedParameters(*this, leftParenLoc, params, + rightParenLoc, + /*isFirstParameterClause=*/true, + &namePieces, + ParameterContextKind::Initializer); FullName = DeclName(Context, Context.Id_init, namePieces); return status; @@ -855,8 +772,8 @@ ParserResult Parser::parsePattern() { } else { // In an always immutable context, `var` is not allowed. if (alwaysImmutable) - diagnose(varLoc, diag::var_not_allowed_in_pattern) - .fixItRemove(varLoc); + diagnose(varLoc, diag::var_not_allowed_in_pattern, isLetKeyword) + .fixItRemove(varLoc); } // In our recursive parse, remember that we're in a var/let pattern. @@ -922,14 +839,7 @@ Parser::parsePatternTupleElement() { if (pattern.isNull()) return std::make_pair(makeParserError(), None); - // Consume the '...'. - SourceLoc ellipsisLoc; - if (Tok.isEllipsis()) - ellipsisLoc = consumeToken(); - auto Elt = TuplePatternElt(Label, LabelLoc, pattern.get(), - ellipsisLoc.isValid(), ellipsisLoc, - nullptr, DefaultArgumentKind::None); - + auto Elt = TuplePatternElt(Label, LabelLoc, pattern.get()); return std::make_pair(makeParserSuccess(), Elt); } @@ -1014,7 +924,7 @@ ParserResult Parser::parseMatchingPattern(bool isExprBasic) { // TODO: Since we expect a pattern in this position, we should optimistically // parse pattern nodes for productions shared by pattern and expression // grammar. For short-term ease of initial implementation, we always go - // through the expr parser for ambiguious productions. + // through the expr parser for ambiguous productions. // Parse productions that can only be patterns. if (Tok.isAny(tok::kw_var, tok::kw_let)) { @@ -1067,7 +977,7 @@ ParserResult Parser::parseMatchingPatternAsLetOrVar(bool isLet, diagnose(varLoc, diag::let_pattern_in_immutable_context); if (!isLet && InVarOrLetPattern == IVOLP_AlwaysImmutable) - diagnose(varLoc, diag::var_not_allowed_in_pattern) + diagnose(varLoc, diag::var_not_allowed_in_pattern, isLet) .fixItReplace(varLoc, "let"); // In our recursive parse, remember that we're in a var/let pattern. diff --git a/lib/Parse/ParseSIL.cpp b/lib/Parse/ParseSIL.cpp index 48a4bcacea1aa..8805129c0f1d3 100644 --- a/lib/Parse/ParseSIL.cpp +++ b/lib/Parse/ParseSIL.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -247,6 +247,7 @@ namespace { } bool parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc, StringRef &OpcodeName); + bool parseSILDebugVar(SILDebugVariable &Var); /// \brief Parses the basic block arguments as part of branch instruction. bool parseSILBBArgsAtBranch(SmallVector &Args, SILBuilder &B); @@ -336,7 +337,7 @@ bool SILParser::parseVerbatim(StringRef name) { bool SILParser::diagnoseProblems() { // Check for any uses of basic blocks that were not defined. if (!UndefinedBlocks.empty()) { - // FIXME: These are going to come out in nondeterminstic order. + // FIXME: These are going to come out in nondeterministic order. for (auto Entry : UndefinedBlocks) P.diagnose(Entry.second.first, diag::sil_undefined_basicblock_use, Entry.second.second); @@ -345,7 +346,7 @@ bool SILParser::diagnoseProblems() { } if (!ForwardRefLocalValues.empty()) { - // FIXME: These are going to come out in nondeterminstic order. + // FIXME: These are going to come out in nondeterministic order. for (auto &Entry : ForwardRefLocalValues) P.diagnose(Entry.second, diag::sil_use_of_undefined_value, Entry.first()); @@ -372,8 +373,9 @@ SILFunction *SILParser::getGlobalNameForDefinition(Identifier Name, Fn->getLoweredFunctionType(), Ty); P.diagnose(It->second.second, diag::sil_prior_reference); auto loc = SILFileLocation(Loc); - Fn = SILFunction::create(SILMod, SILLinkage::Private, "", Ty, - nullptr, loc, IsNotBare, IsNotTransparent, IsNotFragile); + Fn = + SILMod.getOrCreateFunction(SILLinkage::Private, "", Ty, nullptr, loc, + IsNotBare, IsNotTransparent, IsNotFragile); Fn->setDebugScope(new (SILMod) SILDebugScope(loc, *Fn)); } @@ -392,17 +394,17 @@ SILFunction *SILParser::getGlobalNameForDefinition(Identifier Name, // defined already. if (SILMod.lookUpFunction(Name.str()) != nullptr) { P.diagnose(Loc, diag::sil_value_redefinition, Name.str()); - auto fn = SILFunction::create(SILMod, SILLinkage::Private, "", Ty, - nullptr, loc, IsNotBare, IsNotTransparent, - IsNotFragile); + auto *fn = + SILMod.getOrCreateFunction(SILLinkage::Private, "", Ty, nullptr, loc, + IsNotBare, IsNotTransparent, IsNotFragile); fn->setDebugScope(new (SILMod) SILDebugScope(loc, *fn)); return fn; } // Otherwise, this definition is the first use of this name. - auto fn = SILFunction::create(SILMod, SILLinkage::Private, Name.str(), - Ty, nullptr, loc, IsNotBare, IsNotTransparent, - IsNotFragile); + auto *fn = SILMod.getOrCreateFunction(SILLinkage::Private, Name.str(), Ty, + nullptr, loc, IsNotBare, + IsNotTransparent, IsNotFragile); fn->setDebugScope(new (SILMod) SILDebugScope(loc, *fn)); return fn; } @@ -422,9 +424,9 @@ SILFunction *SILParser::getGlobalNameForReference(Identifier Name, if (FnRef->getLoweredFunctionType() != Ty) { P.diagnose(Loc, diag::sil_value_use_type_mismatch, Name.str(), FnRef->getLoweredFunctionType(), Ty); - FnRef = SILFunction::create(SILMod, SILLinkage::Private, "", Ty, nullptr, - loc, IsNotBare, IsNotTransparent, - IsNotFragile); + FnRef = + SILMod.getOrCreateFunction(SILLinkage::Private, "", Ty, nullptr, loc, + IsNotBare, IsNotTransparent, IsNotFragile); FnRef->setDebugScope(new (SILMod) SILDebugScope(loc, *FnRef)); } return FnRef; @@ -432,9 +434,9 @@ SILFunction *SILParser::getGlobalNameForReference(Identifier Name, // If we didn't find a function, create a new one - it must be a forward // reference. - auto Fn = SILFunction::create(SILMod, SILLinkage::Private, - Name.str(), Ty, nullptr, loc, IsNotBare, - IsNotTransparent, IsNotFragile); + auto *Fn = SILMod.getOrCreateFunction(SILLinkage::Private, Name.str(), Ty, + nullptr, loc, IsNotBare, + IsNotTransparent, IsNotFragile); Fn->setDebugScope(new (SILMod) SILDebugScope(loc, *Fn)); TUState.ForwardRefFns[Name] = { Fn, Loc }; TUState.Diags = &P.Diags; @@ -709,10 +711,9 @@ static bool parseSILOptional(bool &Result, SILParser &SP, StringRef Expected) { static bool parseDeclSILOptional(bool *isTransparent, bool *isFragile, IsThunk_t *isThunk, bool *isGlobalInit, - Inline_t *inlineStrategy, - bool *isLet, - std::string *Semantics, EffectsKind *MRK, - Parser &P) { + Inline_t *inlineStrategy, bool *isLet, + llvm::SmallVectorImpl *Semantics, + EffectsKind *MRK, Parser &P) { while (P.consumeIf(tok::l_square)) { if (isLet && P.Tok.is(tok::kw_let)) { *isLet = true; @@ -752,7 +753,7 @@ static bool parseDeclSILOptional(bool *isTransparent, bool *isFragile, // Drop the double quotes. StringRef rawString = P.Tok.getText().drop_front().drop_back(); - *Semantics = rawString; + Semantics->push_back(rawString); P.consumeToken(tok::string_literal); P.parseToken(tok::r_square, diag::expected_in_attribute_list); @@ -916,16 +917,6 @@ bool SILParser::parseSILType(SILType &Result, GenericParamList *&GenericParams, attrs.setAttr(TAK_convention, P.PreviousLoc); attrs.convention = "thin"; } - - // Handle @local_storage, which changes the SIL value category. - if (attrs.has(TAK_local_storage)) { - // Require '*' on local_storage values. - if (category != SILValueCategory::Address) - P.diagnose(attrs.getLoc(TAK_local_storage), - diag::sil_local_storage_non_address); - category = SILValueCategory::LocalStorage; - attrs.clearAttribute(TAK_local_storage); - } return parseSILTypeWithoutQualifiers(Result, category, attrs, GenericParams, IsFuncDecl); } @@ -1193,7 +1184,6 @@ bool SILParser::parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc, .Case("witness_method", ValueKind::WitnessMethodInst) .Case("apply", ValueKind::ApplyInst) .Case("assign", ValueKind::AssignInst) - .Case("autorelease_return", ValueKind::AutoreleaseReturnInst) .Case("autorelease_value", ValueKind::AutoreleaseValueInst) .Case("br", ValueKind::BranchInst) .Case("builtin", ValueKind::BuiltinInst) @@ -1237,6 +1227,7 @@ bool SILParser::parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc, .Case("is_unique_or_pinned", ValueKind::IsUniqueOrPinnedInst) .Case("function_ref", ValueKind::FunctionRefInst) .Case("load", ValueKind::LoadInst) + .Case("load_unowned", ValueKind::LoadUnownedInst) .Case("load_weak", ValueKind::LoadWeakInst) .Case("mark_dependence", ValueKind::MarkDependenceInst) .Case("mark_uninitialized", ValueKind::MarkUninitializedInst) @@ -1269,7 +1260,6 @@ bool SILParser::parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc, .Case("strong_pin", ValueKind::StrongPinInst) .Case("strong_release", ValueKind::StrongReleaseInst) .Case("strong_retain", ValueKind::StrongRetainInst) - .Case("strong_retain_autoreleased", ValueKind::StrongRetainAutoreleasedInst) .Case("strong_retain_unowned", ValueKind::StrongRetainUnownedInst) .Case("strong_unpin", ValueKind::StrongUnpinInst) .Case("return", ValueKind::ReturnInst) @@ -1277,6 +1267,7 @@ bool SILParser::parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc, .Case("select_enum_addr", ValueKind::SelectEnumAddrInst) .Case("select_value", ValueKind::SelectValueInst) .Case("store", ValueKind::StoreInst) + .Case("store_unowned", ValueKind::StoreUnownedInst) .Case("store_weak", ValueKind::StoreWeakInst) .Case("string_literal", ValueKind::StringLiteralInst) .Case("struct", ValueKind::StructInst) @@ -1321,6 +1312,40 @@ bool SILParser::parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc, return true; } +bool SILParser::parseSILDebugVar(SILDebugVariable &Var) { + while (P.Tok.is(tok::comma)) { + P.consumeToken(); + StringRef Key = P.Tok.getText(); + if (Key == "name") { + P.consumeToken(); + if (P.Tok.getKind() != tok::string_literal) { + P.diagnose(P.Tok, diag::expected_tok_in_sil_instr, "string"); + return true; + } + // Drop the double quotes. + StringRef Val = P.Tok.getText().drop_front().drop_back(); + Var.Name = Val; + } else if (Key == "argno") { + P.consumeToken(); + if (P.Tok.getKind() != tok::integer_literal) { + P.diagnose(P.Tok, diag::expected_tok_in_sil_instr, "integer"); + return true; + } + if (P.Tok.getText().getAsInteger(0, Var.ArgNo)) + return true; + } else if (Key == "let") { + Var.Constant = true; + } else if (Key == "var") { + Var.Constant = false; + } else { + P.diagnose(P.Tok, diag::sil_dbg_unknown_key, Key); + return true; + } + P.consumeToken(); + } + return false; +} + bool SILParser::parseSILBBArgsAtBranch(SmallVector &Args, SILBuilder &B) { if (P.Tok.is(tok::l_paren)) { @@ -1480,8 +1505,8 @@ bool getApplySubstitutionsFromParsed( return false; } -// FIXME: we work around canoicalization of PolymorphicFunctionType -// by generating GenericSignature and transforming the input, output +// FIXME: We work around the canonicalization of PolymorphicFunctionType +// by generating a GenericSignature and transforming the input, output // types. static GenericSignature *canonicalPolymorphicFunctionType( PolymorphicFunctionType *Ty, @@ -1658,7 +1683,10 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) { case ValueKind::AllocBoxInst: { SILType Ty; if (parseSILType(Ty)) return true; - ResultVal = B.createAllocBox(InstLoc, Ty); + SILDebugVariable VarInfo; + if (parseSILDebugVar(VarInfo)) + return true; + ResultVal = B.createAllocBox(InstLoc, Ty, VarInfo); break; } case ValueKind::ApplyInst: @@ -1931,9 +1959,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) { UNARY_INSTRUCTION(StrongPin) UNARY_INSTRUCTION(StrongRetain) UNARY_INSTRUCTION(StrongRelease) - UNARY_INSTRUCTION(StrongRetainAutoreleased) UNARY_INSTRUCTION(StrongUnpin) - UNARY_INSTRUCTION(AutoreleaseReturn) UNARY_INSTRUCTION(StrongRetainUnowned) UNARY_INSTRUCTION(UnownedRetain) UNARY_INSTRUCTION(UnownedRelease) @@ -1945,18 +1971,47 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) { UNARY_INSTRUCTION(RetainValue) UNARY_INSTRUCTION(Load) UNARY_INSTRUCTION(CondFail) - UNARY_INSTRUCTION(DebugValue) - UNARY_INSTRUCTION(DebugValueAddr) #undef UNARY_INSTRUCTION - case ValueKind::LoadWeakInst: { - bool isTake = false; - if (parseSILOptional(isTake, *this, "take") || - parseTypedValueRef(Val, B)) - return true; - - ResultVal = B.createLoadWeak(InstLoc, Val, IsTake_t(isTake)); - break; + case ValueKind::DebugValueInst: + case ValueKind::DebugValueAddrInst: { + if (parseTypedValueRef(Val, B)) + return true; + + SILDebugVariable VarInfo; + if (parseSILDebugVar(VarInfo)) + return true; + if (Opcode == ValueKind::DebugValueInst) + ResultVal = B.createDebugValue(InstLoc, Val, VarInfo); + else + ResultVal = B.createDebugValueAddr(InstLoc, Val, VarInfo); + break; + } + + case ValueKind::LoadUnownedInst: + case ValueKind::LoadWeakInst: { + bool isTake = false; + SourceLoc addrLoc; + if (parseSILOptional(isTake, *this, "take") || + parseTypedValueRef(Val, addrLoc, B)) + return true; + + if (Opcode == ValueKind::LoadUnownedInst) { + if (!Val.getType().is()) { + P.diagnose(addrLoc, diag::sil_operand_not_unowned_address, "source", + OpcodeName); + } + ResultVal = B.createLoadUnowned(InstLoc, Val, IsTake_t(isTake)); + + } else { + if (!Val.getType().is()) { + P.diagnose(addrLoc, diag::sil_operand_not_weak_address, "source", + OpcodeName); + } + ResultVal = B.createLoadWeak(InstLoc, Val, IsTake_t(isTake)); + } + + break; } case ValueKind::MarkDependenceInst: { @@ -2248,6 +2303,7 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) { case ValueKind::AssignInst: case ValueKind::StoreInst: + case ValueKind::StoreUnownedInst: case ValueKind::StoreWeakInst: { UnresolvedValueName from; @@ -2258,7 +2314,8 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) { if (parseValueName(from) || parseSILIdentifier(toToken, toLoc, diag::expected_tok_in_sil_instr, "to") || - (Opcode == ValueKind::StoreWeakInst && + ((Opcode == ValueKind::StoreWeakInst || + Opcode == ValueKind::StoreUnownedInst) && parseSILOptional(isInit, *this, "initialization")) || parseTypedValueRef(addrVal, addrLoc, B)) return true; @@ -2274,6 +2331,20 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) { return true; } + if (Opcode == ValueKind::StoreUnownedInst) { + auto refType = addrVal.getType().getAs(); + if (!refType) { + P.diagnose(addrLoc, diag::sil_operand_not_unowned_address, + "destination", OpcodeName); + return true; + } + auto valueTy = SILType::getPrimitiveObjectType(refType.getReferentType()); + ResultVal = B.createStoreUnowned(InstLoc, + getLocalValue(from, valueTy, InstLoc, B), + addrVal, IsInitialization_t(isInit)); + break; + } + if (Opcode == ValueKind::StoreWeakInst) { auto refType = addrVal.getType().getAs(); if (!refType) { @@ -2322,10 +2393,13 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) { SILType Ty; if (parseSILType(Ty)) return true; - - if (Opcode == ValueKind::AllocStackInst) - ResultVal = B.createAllocStack(InstLoc, Ty); - else if (Opcode == ValueKind::AllocRefInst) + + if (Opcode == ValueKind::AllocStackInst) { + SILDebugVariable VarInfo; + if (parseSILDebugVar(VarInfo)) + return true; + ResultVal = B.createAllocStack(InstLoc, Ty, VarInfo); + } else if (Opcode == ValueKind::AllocRefInst) ResultVal = B.createAllocRef(InstLoc, Ty, IsObjC, OnStack); else { assert(Opcode == ValueKind::MetatypeInst); @@ -3053,32 +3127,36 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) { if (intTy) { // If it is a switch on an integer type, check that all case values - // are integer literals. - auto *IL = dyn_cast(CaseVal); - if (!IL) { - P.diagnose(P.Tok, diag::sil_integer_literal_not_integer_type); - return true; - } - APInt CaseValue = IL->getValue(); + // are integer literals or undef. + if (!isa(CaseVal)) { + auto *IL = dyn_cast(CaseVal); + if (!IL) { + P.diagnose(P.Tok, diag::sil_integer_literal_not_integer_type); + return true; + } + APInt CaseValue = IL->getValue(); - if (CaseValue.getBitWidth() != intTy->getGreatestWidth()) - CaseVal = B.createIntegerLiteral( - IL->getLoc(), Val.getType(), - CaseValue.zextOrTrunc(intTy->getGreatestWidth())); + if (CaseValue.getBitWidth() != intTy->getGreatestWidth()) + CaseVal = B.createIntegerLiteral( + IL->getLoc(), Val.getType(), + CaseValue.zextOrTrunc(intTy->getGreatestWidth())); + } } if (functionTy) { // If it is a switch on a function type, check that all case values - // are function references. - auto *FR = dyn_cast(CaseVal); - if (!FR) { - if (auto *CF = dyn_cast(CaseVal)) { - FR = dyn_cast(CF->getOperand()); + // are function references or undef. + if (!isa(CaseVal)) { + auto *FR = dyn_cast(CaseVal); + if (!FR) { + if (auto *CF = dyn_cast(CaseVal)) { + FR = dyn_cast(CF->getOperand()); + } + } + if (!FR) { + P.diagnose(P.Tok, diag::sil_integer_literal_not_integer_type); + return true; } - } - if (!FR) { - P.diagnose(P.Tok, diag::sil_integer_literal_not_integer_type); - return true; } } @@ -3574,7 +3652,7 @@ bool Parser::parseDeclSIL() { IsThunk_t isThunk = IsNotThunk; bool isGlobalInit = false; Inline_t inlineStrategy = InlineDefault; - std::string Semantics; + llvm::SmallVector Semantics; EffectsKind MRK = EffectsKind::Unspecified; if (parseSILLinkage(FnLinkage, *this) || parseDeclSILOptional(&isTransparent, &isFragile, &isThunk, &isGlobalInit, @@ -3605,8 +3683,9 @@ bool Parser::parseDeclSIL() { FunctionState.F->setGlobalInit(isGlobalInit); FunctionState.F->setInlineStrategy(inlineStrategy); FunctionState.F->setEffectsKind(MRK); - if (!Semantics.empty()) - FunctionState.F->setSemanticsAttr(Semantics); + for (auto &Attr : Semantics) { + FunctionState.F->addSemanticsAttr(Attr); + } // Now that we have a SILFunction parse the body, if present. @@ -3637,7 +3716,7 @@ bool Parser::parseDeclSIL() { if (FunctionState.diagnoseProblems()) return true; - // If SIL prsing succeeded, verify the generated SIL. + // If SIL parsing succeeded, verify the generated SIL. if (!FunctionState.P.Diags.hadAnyError()) FunctionState.F->verify(); diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 7d963cbc4cc64..78ebae91d7f4f 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -453,7 +453,7 @@ void Parser::parseTopLevelCodeDeclDelayed() { // Ensure that we restore the parser state at exit. ParserPositionRAII PPR(*this); - // Create a lexer that can not go past the end state. + // Create a lexer that cannot go past the end state. Lexer LocalLex(*L, BeginParserPosition.LS, EndLexerState); // Temporarily swap out the parser's current lexer with our new one. @@ -700,7 +700,7 @@ ParserResult Parser::parseStmtReturn(SourceLoc tryLoc) { ParserResult Result = parseExpr(diag::expected_expr_return); if (Result.isNull()) { // Create an ErrorExpr to tell the type checker that this return - // statement had an expression argument in the source. This supresses + // statement had an expression argument in the source. This suppresses // the error about missing return value in a non-void function. Result = makeParserErrorResult(new (Context) ErrorExpr(ExprLoc)); } @@ -780,8 +780,8 @@ ParserResult Parser::parseStmtDefer() { // // As such, the body of the 'defer' is actually type checked within the // closure's DeclContext. - auto params = TuplePattern::create(Context, SourceLoc(), {}, SourceLoc()); - DeclName name(Context, Context.getIdentifier("$defer"), {}); + auto params = ParameterList::createEmpty(Context); + DeclName name(Context, Context.getIdentifier("$defer"), params); auto tempDecl = FuncDecl::create(Context, /*static*/ SourceLoc(), @@ -1822,8 +1822,9 @@ ParserResult Parser::parseStmtRepeat(LabeledStmtInfo labelInfo) { } else { condition = parseExpr(diag::expected_expr_repeat_while); status |= condition; - if (condition.isNull() || condition.hasCodeCompletion()) + if (condition.isNull()) { return makeParserResult(status, nullptr); // FIXME: better recovery + } } return makeParserResult( @@ -2009,9 +2010,7 @@ static BraceStmt *ConvertClosureToBraceStmt(Expr *E, ASTContext &Ctx) { // doesn't "look" like the body of a control flow statement, it looks like a // closure. if (CE->getInLoc().isValid() || CE->hasExplicitResultType() || - !CE->getParams()->isImplicit() || - !isa(CE->getParams()) || - cast(CE->getParams())->getNumElements() != 0) + CE->getParameters()->size() != 0) return nullptr; // Silence downstream errors by giving it type ()->(), to match up with the diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index 1c7f7d22f3854..820e0eaa3dba6 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -315,7 +315,7 @@ ParserResult Parser::parseTypeIdentifier() { if (Tok.is(tok::kw_Self)) { Loc = consumeIdentifier(&Name); } else { - // FIXME: specialize diagnostic for 'Type': type can not start with + // FIXME: specialize diagnostic for 'Type': type cannot start with // 'metatype' // FIXME: offer a fixit: 'self' -> 'Self' if (parseIdentifier(Name, Loc, diag::expected_identifier_in_dotted_type)) @@ -473,7 +473,7 @@ ParserResult Parser::parseTypeTupleBody() { // If the tuple element starts with "ident :", then // the identifier is an element tag, and it is followed by a type // annotation. - if (Tok.isIdentifierOrUnderscore() && peekToken().is(tok::colon)) { + if (Tok.canBeArgumentLabel() && peekToken().is(tok::colon)) { // Consume the name Identifier name; if (!Tok.is(tok::kw__)) @@ -561,93 +561,39 @@ ParserResult Parser::parseTypeTupleBody() { /// type-array '[' ']' /// type-array '[' expr ']' /// -ParserResult Parser::parseTypeArray(TypeRepr *Base) { +ParserResult Parser::parseTypeArray(TypeRepr *Base) { assert(Tok.isFollowingLSquare()); Parser::StructureMarkerRAII ParsingArrayBound(*this, Tok); SourceLoc lsquareLoc = consumeToken(); - ParserResult NestedType = makeParserResult(Base); ArrayTypeRepr *ATR = nullptr; - // Handle the [] production, meaning an array slice. - if (Tok.is(tok::r_square)) { - SourceLoc rsquareLoc = consumeToken(tok::r_square); - - - // If we're starting another square-bracket clause, recur. - if (Tok.isFollowingLSquare()) { - NestedType = parseTypeArray(Base); - if (NestedType.hasCodeCompletion()) - return makeParserCodeCompletionResult(); - if (NestedType.isNull()) { - // We could not parse the rest of the type, but we still have the base - // type. - NestedType = makeParserErrorResult(Base); - } - } - - // Just build a normal array slice type. - ATR = new (Context) ArrayTypeRepr(NestedType.get(), nullptr, - SourceRange(lsquareLoc, rsquareLoc), - /*OldSyntax=*/true); - - if (NestedType.isParseError()) - return makeParserErrorResult(ATR); - else { - diagnose(lsquareLoc, diag::new_array_syntax) - .fixItInsert(Base->getStartLoc(), "[") - .fixItRemove(lsquareLoc); - - return makeParserResult(ATR); - } - } + // Handle a postfix [] production, a common typo for a C-like array. - SourceLoc rsquareLoc; - - // We currently only accept an integer literal as the inner expression. - // FIXME: Should we decide to support integer constant expressions in the - // future, we will need to remove this check to accept any compositional - // expressions - ParserResult sizeEx = parseExprBasic(diag::expected_expr_array_type); - - parseMatchingToken(tok::r_square, rsquareLoc, - diag::expected_rbracket_array_type, lsquareLoc); - - if (!sizeEx.isNull() && isa(sizeEx.get())) { + // If we have something that might be an array size expression, parse it as + // such, for better error recovery. + if (Tok.isNot(tok::r_square)) { + auto sizeEx = parseExprBasic(diag::expected_expr); if (sizeEx.hasCodeCompletion()) return makeParserCodeCompletionStatus(); - - NestedType = makeParserErrorResult(Base); - - // FIXME: We don't supported fixed-length arrays yet. - diagnose(lsquareLoc, diag::unsupported_fixed_length_array) - .highlight(sizeEx.get()->getSourceRange()); - - ATR = new (Context) ArrayTypeRepr(NestedType.get(), - nullptr, - SourceRange(lsquareLoc, - getEndOfPreviousLoc()), - /*OldSyntax=*/true); - return makeParserErrorResult(ATR); - } - - // If the size expression is null, we would have raised the - // expected_expr_array_type error above when the token stream failed to - // parse as an expression - if (!sizeEx.isNull()) { - diagnose(lsquareLoc, diag::expected_expr_array_type) - .highlight(sizeEx.get()->getSourceRange()); - } else { - // Skip until the next decl, statement or block - skipUntilDeclStmtRBrace(tok::l_brace); + if (sizeEx.isNull()) + return makeParserErrorResult(Base); } - - // Create an array slice type for the malformed array type specification - NestedType = makeParserErrorResult(Base); - ATR = new (Context) ArrayTypeRepr(NestedType.get(), nullptr, - SourceRange(lsquareLoc, - PreviousLoc), - /*OldSyntax=*/true); - return makeParserErrorResult(ATR); + + SourceLoc rsquareLoc; + if (parseMatchingToken(tok::r_square, rsquareLoc, + diag::expected_rbracket_array_type, lsquareLoc)) + return makeParserErrorResult(Base); + + // If we parsed something valid, diagnose it with a fixit to rewrite it to + // Swift syntax. + diagnose(lsquareLoc, diag::new_array_syntax) + .fixItInsert(Base->getStartLoc(), "[") + .fixItRemove(lsquareLoc); + + // Build a normal array slice type for recovery. + ATR = new (Context) ArrayTypeRepr(Base, + SourceRange(Base->getStartLoc(), rsquareLoc)); + return makeParserResult(ATR); } ParserResult Parser::parseTypeCollection() { @@ -693,9 +639,7 @@ ParserResult Parser::parseTypeCollection() { // Form the array type. return makeParserResult(firstTy, new (Context) ArrayTypeRepr(firstTy.get(), - nullptr, - brackets, - /*OldSyntax=*/false)); + brackets)); } bool Parser::isOptionalToken(const Token &T) const { @@ -755,9 +699,9 @@ Parser::parseTypeImplicitlyUnwrappedOptional(TypeRepr *base) { base, exclamationLoc)); } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Speculative type list parsing -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// static bool isGenericTypeDisambiguatingToken(Parser &P) { auto &tok = P.Tok; @@ -991,8 +935,8 @@ bool Parser::canParseTypeTupleBody() { // If the tuple element starts with "ident :", then it is followed // by a type annotation. - if (Tok.is(tok::identifier) && peekToken().is(tok::colon)) { - consumeToken(tok::identifier); + if (Tok.canBeArgumentLabel() && peekToken().is(tok::colon)) { + consumeToken(); consumeToken(tok::colon); // Parse attributes then a type. diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 35398ce70bc69..b7997f5038834 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,6 +20,7 @@ #include "swift/AST/DiagnosticsParse.h" #include "swift/AST/PrettyStackTrace.h" #include "swift/Basic/SourceManager.h" +#include "swift/Basic/Timer.h" #include "swift/Parse/Lexer.h" #include "swift/Parse/CodeCompletionCallbacks.h" #include "swift/Parse/DelayedParsingCallbacks.h" @@ -136,6 +137,7 @@ bool swift::parseIntoSourceFile(SourceFile &SF, SILParserState *SIL, PersistentParserState *PersistentState, DelayedParsingCallbacks *DelayedParseCB) { + SharedTimer timer("Parsing"); Parser P(BufferID, SF, SIL, PersistentState); PrettyStackTraceParser StackTrace(P); @@ -153,6 +155,7 @@ bool swift::parseIntoSourceFile(SourceFile &SF, void swift::performDelayedParsing( DeclContext *DC, PersistentParserState &PersistentState, CodeCompletionCallbacksFactory *CodeCompletionFactory) { + SharedTimer timer("Parsing"); ParseDelayedFunctionBodies Walker(PersistentState, CodeCompletionFactory); DC->walkContext(Walker); @@ -332,7 +335,7 @@ SourceLoc Parser::consumeStartingCharacterOfCurrentToken() { return consumeToken(); } - // ... or a multi-charater token with the first caracter being the one that + // ... or a multi-character token with the first character being the one that // we want to consume as a separate token. restoreParserPosition(getParserPositionAfterFirstCharacter(Tok)); return PreviousLoc; @@ -612,7 +615,7 @@ Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc, // If the lexer stopped with an EOF token whose spelling is ")", then this // is actually the tuple that is a string literal interpolation context. // Just accept the ")" and build the tuple as we usually do. - if (Tok.is(tok::eof) && Tok.getText() == ")") { + if (Tok.is(tok::eof) && Tok.getText() == ")" && RightK == tok::r_paren) { RightLoc = Tok.getLoc(); return Status; } @@ -623,11 +626,21 @@ Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc, continue; } if (!OptionalSep) { + // If we're in a comma-separated list and the next token starts a new + // declaration at the beginning of a new line, skip until the end. + if (SeparatorK == tok::comma && Tok.isAtStartOfLine() && + isStartOfDecl() && Tok.getLoc() != StartLoc) { + skipUntilDeclRBrace(RightK, SeparatorK); + break; + } + StringRef Separator = (SeparatorK == tok::comma ? "," : ";"); diagnose(Tok, diag::expected_separator, Separator) .fixItInsertAfter(PreviousLoc, Separator); Status.setIsParseError(); } + + // If we haven't made progress, skip ahead if (Tok.getLoc() == StartLoc) { skipUntilDeclRBrace(RightK, SeparatorK); diff --git a/lib/Parse/PersistentParserState.cpp b/lib/Parse/PersistentParserState.cpp index 96a6e311f910e..6f70a8f1afb16 100644 --- a/lib/Parse/PersistentParserState.cpp +++ b/lib/Parse/PersistentParserState.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Parse/Scope.cpp b/lib/Parse/Scope.cpp index 9fdc7da5c93dd..4cf02f307cdc4 100644 --- a/lib/Parse/Scope.cpp +++ b/lib/Parse/Scope.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/PrintAsObjC/PrintAsObjC.cpp b/lib/PrintAsObjC/PrintAsObjC.cpp index 18fdb739fa656..8e164be4218d2 100644 --- a/lib/PrintAsObjC/PrintAsObjC.cpp +++ b/lib/PrintAsObjC/PrintAsObjC.cpp @@ -1,8 +1,8 @@ -//===-- PrintAsObjC.cpp - Emit a header file for a Swift AST --------------===// +//===--- PrintAsObjC.cpp - Emit a header file for a Swift AST -------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -71,18 +71,18 @@ namespace { }; } -static Identifier getNameForObjC(const NominalTypeDecl *NTD, +static Identifier getNameForObjC(const ValueDecl *VD, CustomNamesOnly_t customNamesOnly = Normal) { - // FIXME: Should we support renaming for enums too? - assert(isa(NTD) || isa(NTD)); - if (auto objc = NTD->getAttrs().getAttribute()) { + assert(isa(VD) || isa(VD) + || isa(VD) || isa(VD)); + if (auto objc = VD->getAttrs().getAttribute()) { if (auto name = objc->getName()) { assert(name->getNumSelectorPieces() == 1); return name->getSelectorPieces().front(); } } - return customNamesOnly ? Identifier() : NTD->getName(); + return customNamesOnly ? Identifier() : VD->getName(); } @@ -235,16 +235,39 @@ class ObjCPrinter : private DeclVisitor, void visitEnumDecl(EnumDecl *ED) { printDocumentationComment(ED); - llvm::SmallString<32> scratch; - os << "typedef SWIFT_ENUM("; + os << "typedef "; + Identifier customName = getNameForObjC(ED, CustomNamesOnly); + if (customName.empty()) { + os << "SWIFT_ENUM("; + } else { + os << "SWIFT_ENUM_NAMED("; + } print(ED->getRawType(), OTK_None); - os << ", " << ED->getName() << ") {\n"; + if (customName.empty()) { + os << ", " << ED->getName(); + } else { + os << ", " << customName + << ", \"" << ED->getName() << "\""; + } + os << ") {\n"; for (auto Elt : ED->getAllElements()) { printDocumentationComment(Elt); // Print the cases as the concatenation of the enum name with the case // name. - os << " " << ED->getName() << Elt->getName(); + os << " "; + Identifier customEltName = getNameForObjC(Elt, CustomNamesOnly); + if (customEltName.empty()) { + if (customName.empty()) { + os << ED->getName(); + } else { + os << customName; + } + os << Elt->getName(); + } else { + os << customEltName + << " SWIFT_COMPILE_NAME(\"" << Elt->getName() << "\")"; + } if (auto ILE = cast_or_null(Elt->getRawValueExpr())) { os << " = "; @@ -258,7 +281,7 @@ class ObjCPrinter : private DeclVisitor, } void printSingleMethodParam(StringRef selectorPiece, - const Pattern *param, + const ParamDecl *param, const clang::ParmVarDecl *clangParam, bool isNSUIntegerSubscript, bool isLastPiece) { @@ -267,14 +290,14 @@ class ObjCPrinter : private DeclVisitor, (clangParam && isNSUInteger(clangParam->getType()))) { os << "NSUInteger"; } else { - this->print(param->getType(), OTK_None); + print(param->getType(), OTK_None); } os << ")"; - if (isa(param)) { + if (!param->hasName()) { os << "_"; } else { - Identifier name = cast(param)->getBodyName(); + Identifier name = param->getName(); os << name; if (isClangKeyword(name)) os << "_"; @@ -378,17 +401,14 @@ class ObjCPrinter : private DeclVisitor, os << ")"; - auto bodyPatterns = AFD->getBodyParamPatterns(); - assert(bodyPatterns.size() == 2 && "not an ObjC-compatible method"); + auto paramLists = AFD->getParameterLists(); + assert(paramLists.size() == 2 && "not an ObjC-compatible method"); llvm::SmallString<128> selectorBuf; ArrayRef selectorPieces = AFD->getObjCSelector().getSelectorPieces(); - const TuplePattern *paramTuple - = dyn_cast(bodyPatterns.back()); - const ParenPattern *paramParen - = dyn_cast(bodyPatterns.back()); - assert((paramTuple || paramParen) && "Bad body parameters?"); + + const auto ¶ms = paramLists[1]->getArray(); unsigned paramIndex = 0; for (unsigned i = 0, n = selectorPieces.size(); i != n; ++i) { if (i > 0) os << ' '; @@ -413,37 +433,21 @@ class ObjCPrinter : private DeclVisitor, continue; } - // Single-parameter methods. - if (paramParen) { - assert(paramIndex == 0); - auto clangParam = clangMethod ? clangMethod->parameters()[0] : nullptr; - printSingleMethodParam(piece, - paramParen->getSemanticsProvidingPattern(), - clangParam, - isNSUIntegerSubscript, - i == n-1); - paramIndex = 1; - continue; - } - // Zero-parameter methods. - if (paramTuple->getNumElements() == 0) { + if (params.size() == 0) { assert(paramIndex == 0); os << piece; paramIndex = 1; continue; } - // Multi-parameter methods. const clang::ParmVarDecl *clangParam = nullptr; if (clangMethod) clangParam = clangMethod->parameters()[paramIndex]; - const TuplePatternElt ¶m = paramTuple->getElements()[paramIndex]; - auto pattern = param.getPattern()->getSemanticsProvidingPattern(); - printSingleMethodParam(piece, pattern, clangParam, - isNSUIntegerSubscript, - i == n-1); + // Single-parameter methods. + printSingleMethodParam(piece, params[paramIndex], clangParam, + isNSUIntegerSubscript, i == n-1); ++paramIndex; } @@ -655,23 +659,35 @@ class ObjCPrinter : private DeclVisitor, if (!kind) return; - if (printKind == NullabilityPrintKind::After) - os << ' '; - - if (printKind != NullabilityPrintKind::ContextSensitive) - os << "__"; - - switch (*kind) { - case OTK_None: - os << "nonnull"; - break; - - case OTK_Optional: - os << "nullable"; + switch (printKind) { + case NullabilityPrintKind::ContextSensitive: + switch (*kind) { + case OTK_None: + os << "nonnull"; + break; + case OTK_Optional: + os << "nullable"; + break; + case OTK_ImplicitlyUnwrappedOptional: + os << "null_unspecified"; + break; + } break; - - case OTK_ImplicitlyUnwrappedOptional: - os << "null_unspecified"; + case NullabilityPrintKind::After: + os << ' '; + [[clang::fallthrough]]; + case NullabilityPrintKind::Before: + switch (*kind) { + case OTK_None: + os << "_Nonnull"; + break; + case OTK_Optional: + os << "_Nullable"; + break; + case OTK_ImplicitlyUnwrappedOptional: + os << "_Null_unspecified"; + break; + } break; } @@ -805,7 +821,7 @@ class ObjCPrinter : private DeclVisitor, auto *clangTypeDecl = cast(alias->getClangDecl()); os << clangTypeDecl->getName(); - // Print proper nullability for CF types, but __null_unspecified for + // Print proper nullability for CF types, but _Null_unspecified for // all other non-object Clang pointer types. if (aliasTy->hasReferenceSemantics() || isClangObjectPointerType(clangTypeDecl)) { @@ -1527,7 +1543,7 @@ class ModuleWriter { return elem->getName().str() == "Domain"; }); if (!hasDomainCase) { - os << "static NSString * __nonnull const " << ED->getName() + os << "static NSString * _Nonnull const " << ED->getName() << "Domain = @\"" << M.getName() << "." << ED->getName() << "\";\n"; } } @@ -1602,7 +1618,7 @@ class ModuleWriter { "#endif\n" "#if !defined(SWIFT_CLASS)\n" "# if defined(__has_attribute) && " - "__has_attribute(objc_subclassing_restricted) \n" + "__has_attribute(objc_subclassing_restricted)\n" "# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) " "__attribute__((objc_subclassing_restricted)) " "SWIFT_CLASS_EXTRA\n" @@ -1644,6 +1660,15 @@ class ModuleWriter { "# define SWIFT_ENUM(_type, _name) " "enum _name : _type _name; " "enum SWIFT_ENUM_EXTRA _name : _type\n" + "# if defined(__has_feature) && " + "__has_feature(generalized_swift_name)\n" + "# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) " + "enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); " + "enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type\n" + "# else\n" + "# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) " + "SWIFT_ENUM(_type, _name)\n" + "# endif\n" "#endif\n" ; static_assert(SWIFT_MAX_IMPORTED_SIMD_ELEMENTS == 4, diff --git a/lib/SIL/AbstractionPattern.cpp b/lib/SIL/AbstractionPattern.cpp index c2914d7dd1361..0f2eaace1baea 100644 --- a/lib/SIL/AbstractionPattern.cpp +++ b/lib/SIL/AbstractionPattern.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -463,10 +463,10 @@ AbstractionPattern AbstractionPattern::getLValueObjectType() const { return *this; case Kind::Type: return AbstractionPattern(getGenericSignature(), - cast(getType()).getObjectType()); + getType().getLValueOrInOutObjectType()); case Kind::ClangType: return AbstractionPattern(getGenericSignature(), - cast(getType()).getObjectType(), + getType().getLValueOrInOutObjectType(), getClangType()); } llvm_unreachable("bad kind"); diff --git a/lib/SIL/Bridging.cpp b/lib/SIL/Bridging.cpp index 9c39041e829b5..a094f4d69becf 100644 --- a/lib/SIL/Bridging.cpp +++ b/lib/SIL/Bridging.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,9 +30,8 @@ using namespace swift::Lowering; SILType TypeConverter::getLoweredTypeOfGlobal(VarDecl *var) { AbstractionPattern origType = getAbstractionPattern(var); - CanType swiftType = (origType.isOpaque() ? var->getType()->getCanonicalType() - : origType.getType()); - return getLoweredType(origType, swiftType).getObjectType(); + assert(!origType.isOpaque()); + return getLoweredType(origType, origType.getType()).getObjectType(); } CanType TypeConverter::getBridgedInputType(SILFunctionTypeRepresentation rep, diff --git a/lib/SIL/CMakeLists.txt b/lib/SIL/CMakeLists.txt index 82ea602ec2749..d31ed5a0de87b 100644 --- a/lib/SIL/CMakeLists.txt +++ b/lib/SIL/CMakeLists.txt @@ -27,7 +27,7 @@ add_swift_library(swiftSIL SILDeclRef.cpp LoopInfo.cpp Projection.cpp - MemLocation.cpp + SILValueProjection.cpp Mangle.cpp Linker.cpp LINK_LIBRARIES diff --git a/lib/SIL/Dominance.cpp b/lib/SIL/Dominance.cpp index 907b928f0dc6d..6dfd31cd9c68b 100644 --- a/lib/SIL/Dominance.cpp +++ b/lib/SIL/Dominance.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,7 +22,7 @@ template class llvm::DominatorTreeBase; template class llvm::DominatorBase; template class llvm::DomTreeNodeBase; -/// Compute the immmediate-dominators map. +/// Compute the immediate-dominators map. DominanceInfo::DominanceInfo(SILFunction *F) : DominatorTreeBase(/*isPostDom*/ false) { assert(!F->isExternalDeclaration() && @@ -55,7 +55,7 @@ void DominanceInfo::verify() const { DominanceInfo OtherDT(F); // And compare. - if (errorOccuredOnComparison(OtherDT)) { + if (errorOccurredOnComparison(OtherDT)) { llvm::errs() << "DominatorTree is not up to date!\nComputed:\n"; print(llvm::errs()); llvm::errs() << "\nActual:\n"; @@ -64,11 +64,11 @@ void DominanceInfo::verify() const { } } -/// Compute the immmediate-post-dominators map. +/// Compute the immediate-post-dominators map. PostDominanceInfo::PostDominanceInfo(SILFunction *F) : DominatorTreeBase(/*isPostDom*/ true) { assert(!F->isExternalDeclaration() && - "Can not construct a post dominator tree for a declaration"); + "Cannot construct a post dominator tree for a declaration"); recalculate(*F); } @@ -102,7 +102,7 @@ void PostDominanceInfo::verify() const { PostDominanceInfo OtherDT(F); // And compare. - if (errorOccuredOnComparison(OtherDT)) { + if (errorOccurredOnComparison(OtherDT)) { llvm::errs() << "PostDominatorTree is not up to date!\nComputed:\n"; print(llvm::errs()); llvm::errs() << "\nActual:\n"; diff --git a/lib/SIL/DynamicCasts.cpp b/lib/SIL/DynamicCasts.cpp index ac65c66071f0b..81b69212dc55c 100644 --- a/lib/SIL/DynamicCasts.cpp +++ b/lib/SIL/DynamicCasts.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -400,7 +400,7 @@ swift::classifyDynamicCast(Module *M, // FIXME: tuple conversions? - // FIXME: Be more careful with briding conversions from + // FIXME: Be more careful with bridging conversions from // NSArray, NSDictionary and NSSet as they may fail? // Check if there might be a bridging conversion. @@ -591,7 +591,7 @@ namespace { // FIXME: Upcasts between existential metatypes are not handled yet. // We should generate for it: // %openedSrcMetatype = open_existential srcMetatype - // init_existental dstMetatype, %openedSrcMetatype + // init_existential dstMetatype, %openedSrcMetatype auto &srcTL = getTypeLowering(source.Value.getType()); SILValue value; if (source.isAddress()) { @@ -658,7 +658,7 @@ namespace { if (!source.shouldTake()) { sourceTemp = B.createAllocStack(Loc, sourceAddr.getType().getObjectType()); - sourceAddr = sourceTemp->getAddressResult(); + sourceAddr = sourceTemp; B.createCopyAddr(Loc, source.Value, sourceAddr, IsNotTake, IsInitialization); } @@ -677,7 +677,7 @@ namespace { // Deallocate the source temporary if we needed one. if (sourceTemp) { - B.createDeallocStack(Loc, sourceTemp->getContainerResult()); + B.createDeallocStack(Loc, sourceTemp); } Source result = emitSome(resultObject, target, state); diff --git a/lib/SIL/Linker.cpp b/lib/SIL/Linker.cpp index ba637b31d2fff..a3b0f93436e56 100644 --- a/lib/SIL/Linker.cpp +++ b/lib/SIL/Linker.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,7 +16,6 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" #include @@ -34,7 +33,7 @@ STATISTIC(NumFuncLinked, "Number of SIL functions linked"); static bool shouldImportFunction(SILFunction *F) { // Skip functions that are marked with the 'no import' tag. These // are functions that we don't want to copy from the module. - if (F->hasSemanticsString("stdlib_binary_only")) { + if (F->hasSemanticsAttr("stdlib_binary_only")) { // If we are importing a function declaration mark it as external since we // are not importing the body. if (F->isExternalDeclaration()) @@ -64,9 +63,6 @@ bool SILLinkerVisitor::processFunction(SILFunction *F) { if (!NewFn || NewFn->isExternalDeclaration()) return false; - if (Callback) - Callback(NewFn); - F = NewFn; } @@ -98,10 +94,6 @@ bool SILLinkerVisitor::processDeclRef(SILDeclRef Decl) { return false; } - // Notify client of new deserialized function. - if (Callback) - Callback(NewFn); - ++NumFuncLinked; // Try to transitively deserialize everything referenced by NewFn. @@ -123,10 +115,6 @@ bool SILLinkerVisitor::processFunction(StringRef Name) { if (!NewFn || NewFn->isExternalDeclaration()) return false; - // Notify client of new deserialized function. - if (Callback) - Callback(NewFn); - ++NumFuncLinked; // Try to transitively deserialize everything referenced by NewFn. @@ -168,7 +156,7 @@ SILVTable *SILLinkerVisitor::processClassDecl(const ClassDecl *C) { bool SILLinkerVisitor::linkInVTable(ClassDecl *D) { // Attempt to lookup the Vtbl from the SILModule. - SILVTable *Vtbl = Mod.lookUpVTable(D, Callback); + SILVTable *Vtbl = Mod.lookUpVTable(D); // If the SILModule does not have the VTable, attempt to deserialize the // VTable. If we fail to do that as well, bail. @@ -363,25 +351,6 @@ bool SILLinkerVisitor::process() { if (!shouldImportFunction(F)) continue; - // The ExternalSource may wish to rewrite non-empty bodies. - if (!F->isExternalDeclaration() && ExternalSource) { - if (auto *NewFn = ExternalSource->lookupSILFunction(F)) { - if (NewFn->isExternalDeclaration()) - continue; - - NewFn->verify(); - Worklist.push_back(NewFn); - - // Notify client of new deserialized function. - if (Callback) - Callback(NewFn); - - ++NumFuncLinked; - Result = true; - continue; - } - } - DEBUG(llvm::dbgs() << "Imported function: " << F->getName() << "\n"); F->setBare(IsBare); @@ -395,10 +364,6 @@ bool SILLinkerVisitor::process() { Worklist.push_back(NewFn); Result = true; - // Notify client of new deserialized function. - if (Callback) - Callback(NewFn); - ++NumFuncLinked; } } diff --git a/lib/SIL/Linker.h b/lib/SIL/Linker.h index e90ec607b22af..2be10b291488f 100644 --- a/lib/SIL/Linker.h +++ b/lib/SIL/Linker.h @@ -1,8 +1,8 @@ -//===--- Linker.h --------------------------------------------*- C++ -*----===// +//===--- Linker.h -----------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -14,7 +14,6 @@ #define SWIFT_SIL_LINKER_H #include "swift/SIL/SILDebugScope.h" -#include "swift/SIL/SILExternalSource.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/SILModule.h" #include "swift/Serialization/SerializedSILLoader.h" @@ -32,9 +31,6 @@ class SILLinkerVisitor : public SILInstructionVisitor { /// The SILLoader that this visitor is using to link. SerializedSILLoader *Loader; - /// The external SIL source to use when linking this module. - SILExternalSource *ExternalSource = nullptr; - /// Worklist of SILFunctions we are processing. llvm::SmallVector Worklist; @@ -45,18 +41,11 @@ class SILLinkerVisitor : public SILInstructionVisitor { /// The current linking mode. LinkingMode Mode; - /// The callback which is called each time a new function body is - /// deserialized. - std::function Callback; - public: SILLinkerVisitor(SILModule &M, SerializedSILLoader *L, - SILModule::LinkingMode LinkingMode, - SILExternalSource *E = nullptr, - std::function Callback =nullptr) - : Mod(M), Loader(L), ExternalSource(E), Worklist(), - FunctionDeserializationWorklist(), Mode(LinkingMode), - Callback(Callback) {} + SILModule::LinkingMode LinkingMode) + : Mod(M), Loader(L), Worklist(), FunctionDeserializationWorklist(), + Mode(LinkingMode) {} /// Process F, recursively deserializing any thing F may reference. bool processFunction(SILFunction *F); diff --git a/lib/SIL/LoopInfo.cpp b/lib/SIL/LoopInfo.cpp index 6e75adda4bc0a..34d17ea8fe511 100644 --- a/lib/SIL/LoopInfo.cpp +++ b/lib/SIL/LoopInfo.cpp @@ -1,8 +1,8 @@ -//===-------------- LoopInfo.cpp - SIL Loop Analysis -----*- C++ -*--------===// +//===--- LoopInfo.cpp - SIL Loop Analysis -----------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -35,6 +35,51 @@ SILLoopInfo::SILLoopInfo(SILFunction *F, DominanceInfo *DT) { LI.analyze(*DT); } +bool SILLoop::canDuplicate(SILInstruction *I) const { + // The dealloc_stack of an alloc_stack must be in the loop, otherwise the + // dealloc_stack will be fed by a phi node of two alloc_stacks. + if (auto *Alloc = dyn_cast(I)) { + for (auto *UI : Alloc->getUses()) { + if (auto *Dealloc = dyn_cast(UI->getUser())) { + if (!contains(Dealloc->getParent())) + return false; + } + } + return true; + } + + // CodeGen can't build ssa for objc methods. + if (auto *Method = dyn_cast(I)) { + if (Method->getMember().isForeign) { + for (auto *UI : Method->getUses()) { + if (!contains(UI->getUser())) + return false; + } + } + return true; + } + + // We can't have a phi of two openexistential instructions of different UUID. + SILInstruction *OEI = dyn_cast(I); + if (OEI || (OEI = dyn_cast(I)) || + (OEI = dyn_cast(I))) { + for (auto *UI : OEI->getUses()) + if (!contains(UI->getUser())) + return false; + return true; + } + + if (auto *Dealloc = dyn_cast(I)) { + // The matching alloc_stack must be in the loop. + if (auto *Alloc = dyn_cast(Dealloc->getOperand())) + return contains(Alloc->getParent()); + return false; + } + + assert(I->isTriviallyDuplicatable() && + "Code here must match isTriviallyDuplicatable in SILInstruction"); + return true; +} void SILLoopInfo::verify() const { llvm::DenseSet Loops; diff --git a/lib/SIL/Mangle.cpp b/lib/SIL/Mangle.cpp index 5f0067f21ab8d..cf38d93251ea4 100644 --- a/lib/SIL/Mangle.cpp +++ b/lib/SIL/Mangle.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -57,11 +57,10 @@ static void mangleSubstitution(Mangler &M, Substitution Sub) { void GenericSpecializationMangler::mangleSpecialization() { Mangler &M = getMangler(); - llvm::raw_ostream &Buf = getBuffer(); for (auto &Sub : Subs) { mangleSubstitution(M, Sub); - Buf << '_'; + M.append('_'); } } @@ -123,17 +122,22 @@ setArgumentSROA(unsigned ArgNo) { void FunctionSignatureSpecializationMangler:: -setArgumentInOutToValue(unsigned ArgNo) { - Args[ArgNo].first = ArgumentModifierIntBase(ArgumentModifier::InOutToValue); +setArgumentBoxToValue(unsigned ArgNo) { + Args[ArgNo].first = ArgumentModifierIntBase(ArgumentModifier::BoxToValue); +} + +void +FunctionSignatureSpecializationMangler:: +setArgumentBoxToStack(unsigned ArgNo) { + Args[ArgNo].first = ArgumentModifierIntBase(ArgumentModifier::BoxToStack); } void FunctionSignatureSpecializationMangler::mangleConstantProp(LiteralInst *LI) { Mangler &M = getMangler(); - llvm::raw_ostream &os = getBuffer(); // Append the prefix for constant propagation 'cp'. - os << "cp"; + M.append("cp"); // Then append the unique identifier of our literal. switch (LI->getKind()) { @@ -141,36 +145,40 @@ FunctionSignatureSpecializationMangler::mangleConstantProp(LiteralInst *LI) { llvm_unreachable("unknown literal"); case ValueKind::FunctionRefInst: { SILFunction *F = cast(LI)->getReferencedFunction(); - os << "fr"; - M.mangleIdentifier(F->getName()); + M.append("fr"); + M.mangleIdentifierSymbol(F->getName()); break; } case ValueKind::GlobalAddrInst: { SILGlobalVariable *G = cast(LI)->getReferencedGlobal(); - os << "g"; - M.mangleIdentifier(G->getName()); + M.append("g"); + M.mangleIdentifierSymbol(G->getName()); break; } case ValueKind::IntegerLiteralInst: { APInt apint = cast(LI)->getValue(); - os << "i" << apint; + M.append("i"); + M.mangleNatural(apint); break; } case ValueKind::FloatLiteralInst: { APInt apint = cast(LI)->getBits(); - os << "fl" << apint; + M.append("fl"); + M.mangleNatural(apint); break; } case ValueKind::StringLiteralInst: { StringLiteralInst *SLI = cast(LI); StringRef V = SLI->getValue(); - assert(V.size() <= 32 && "Can not encode string of length > 32"); + assert(V.size() <= 32 && "Cannot encode string of length > 32"); llvm::SmallString<33> Str; Str += "u"; Str += V; - os << "se" << unsigned(SLI->getEncoding()) << "v"; + M.append("se"); + M.mangleNatural(APInt(32, unsigned(SLI->getEncoding()))); + M.append("v"); M.mangleIdentifier(Str); break; } @@ -181,16 +189,14 @@ void FunctionSignatureSpecializationMangler:: mangleClosureProp(PartialApplyInst *PAI) { Mangler &M = getMangler(); - llvm::raw_ostream &os = getBuffer(); - - os << "cl"; + M.append("cl"); // Add in the partial applies function name if we can find one. Assert // otherwise. The reason why this is ok to do is currently we only perform // closure specialization if we know the function_ref in question. When this // restriction is removed, the assert here will fire. auto *FRI = cast(PAI->getCallee()); - M.mangleIdentifier(FRI->getReferencedFunction()->getName()); + M.mangleIdentifierSymbol(FRI->getReferencedFunction()->getName()); // Then we mangle the types of the arguments that the partial apply is // specializing. @@ -203,16 +209,14 @@ mangleClosureProp(PartialApplyInst *PAI) { void FunctionSignatureSpecializationMangler::mangleClosureProp( ThinToThickFunctionInst *TTTFI) { Mangler &M = getMangler(); - llvm::raw_ostream &os = getBuffer(); - - os << "cl"; + M.append("cl"); // Add in the partial applies function name if we can find one. Assert // otherwise. The reason why this is ok to do is currently we only perform // closure specialization if we know the function_ref in question. When this // restriction is removed, the assert here will fire. auto *FRI = cast(TTTFI->getCallee()); - M.mangleIdentifier(FRI->getReferencedFunction()->getName()); + M.mangleIdentifierSymbol(FRI->getReferencedFunction()->getName()); } void FunctionSignatureSpecializationMangler::mangleArgument( @@ -233,30 +237,33 @@ void FunctionSignatureSpecializationMangler::mangleArgument( return; } - llvm::raw_ostream &os = getBuffer(); - if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::Unmodified)) { - os << "n"; + M.append("n"); + return; + } + + if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::BoxToValue)) { + M.append("i"); return; } - if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::InOutToValue)) { - os << "i"; + if (ArgMod == ArgumentModifierIntBase(ArgumentModifier::BoxToStack)) { + M.append("k"); return; } bool hasSomeMod = false; if (ArgMod & ArgumentModifierIntBase(ArgumentModifier::Dead)) { - os << "d"; + M.append("d"); hasSomeMod = true; } if (ArgMod & ArgumentModifierIntBase(ArgumentModifier::OwnedToGuaranteed)) { - os << "g"; + M.append("g"); hasSomeMod = true; } if (ArgMod & ArgumentModifierIntBase(ArgumentModifier::SROA)) { - os << "s"; + M.append("s"); hasSomeMod = true; } @@ -264,13 +271,12 @@ void FunctionSignatureSpecializationMangler::mangleArgument( } void FunctionSignatureSpecializationMangler::mangleSpecialization() { - llvm::raw_ostream &os = getBuffer(); for (unsigned i : indices(Args)) { ArgumentModifierIntBase ArgMod; NullablePtr Inst; std::tie(ArgMod, Inst) = Args[i]; mangleArgument(ArgMod, Inst); - os << "_"; + M.append("_"); } } diff --git a/lib/SIL/MemLocation.cpp b/lib/SIL/MemLocation.cpp deleted file mode 100644 index 9492df35ddf86..0000000000000 --- a/lib/SIL/MemLocation.cpp +++ /dev/null @@ -1,346 +0,0 @@ -//===------------------------- MemLocation.cpp ----------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-memlocation" -#include "swift/SIL/MemLocation.h" -#include "llvm/Support/Debug.h" - -using namespace swift; - -//===----------------------------------------------------------------------===// -// Utility Functions -//===----------------------------------------------------------------------===// - -static inline void removeMemLocations(MemLocationValueMap &Values, - MemLocationList &FirstLevel) { - for (auto &X : FirstLevel) - Values.erase(X); -} - -//===----------------------------------------------------------------------===// -// SILValue Projection -//===----------------------------------------------------------------------===// - -void SILValueProjection::print() const { - llvm::outs() << Base; - llvm::outs() << Path.getValue(); -} - -//===----------------------------------------------------------------------===// -// Load Store Value -//===----------------------------------------------------------------------===// - -SILValue LoadStoreValue::createExtract(SILValue Base, - Optional &Path, - SILInstruction *Inst) { - // If we found a projection path, but there are no projections, then the two - // loads must be the same, return PrevLI. - if (!Path || Path->empty()) - return Base; - - // Ok, at this point we know that we can construct our aggregate projections - // from our list of address projections. - SILValue LastExtract = Base; - SILBuilder Builder(Inst); - - // Construct the path! - for (auto PI = Path->rbegin(), PE = Path->rend(); PI != PE; ++PI) { - LastExtract = - PI->createValueProjection(Builder, Inst->getLoc(), LastExtract).get(); - continue; - } - // Return the last extract we created. - return LastExtract; -} - -//===----------------------------------------------------------------------===// -// Memory Location -//===----------------------------------------------------------------------===// - -void MemLocation::initialize(SILValue Dest) { - Base = getUnderlyingObject(Dest); - Path = ProjectionPath::getAddrProjectionPath(Base, Dest); -} - -bool MemLocation::isMustAliasMemLocation(const MemLocation &RHS, - AliasAnalysis *AA) { - // If the bases are not must-alias, the locations may not alias. - if (!AA->isMustAlias(Base, RHS.getBase())) - return false; - // If projection paths are different, then the locations can not alias. - if (!hasIdenticalProjectionPath(RHS)) - return false; - return true; -} - -bool MemLocation::isMayAliasMemLocation(const MemLocation &RHS, - AliasAnalysis *AA) { - // If the bases do not alias, then the locations can not alias. - if (AA->isNoAlias(Base, RHS.getBase())) - return false; - // If one projection path is a prefix of another, then the locations - // could alias. - if (hasNonEmptySymmetricPathDifference(RHS)) - return false; - return true; -} - -MemLocation MemLocation::createMemLocation(SILValue Base, ProjectionPath &P1, - ProjectionPath &P2) { - ProjectionPath T; - T.append(P1); - T.append(P2); - return MemLocation(Base, T); -} - -void MemLocation::getFirstLevelMemLocations(MemLocationList &Locs, - SILModule *Mod) { - SILType Ty = getType(); - llvm::SmallVector Out; - Projection::getFirstLevelAddrProjections(Ty, *Mod, Out); - for (auto &X : Out) { - ProjectionPath P; - P.append(X); - P.append(Path.getValue()); - Locs.push_back(MemLocation(Base, P)); - } -} - -void MemLocation::expand(MemLocation &Base, SILModule *Mod, - MemLocationList &Locs, - TypeExpansionMap &TypeExpansionVault) { - // To expand a memory location to its indivisible parts, we first get the - // address projection paths from the accessed type to each indivisible field, - // i.e. leaf nodes, then we append these projection paths to the Base. - // - // NOTE: we get the address projection because the Base memory location is - // initialized with address projection paths. By keeping it consistent makes - // it easier to implement the getType function for MemLocation. - // - SILType BaseType = Base.getType(); - if (TypeExpansionVault.find(BaseType) == TypeExpansionVault.end()) { - // There is no cached expansion for this type, build and cache it now. - ProjectionPathList Paths; - ProjectionPath::expandTypeIntoLeafProjectionPaths(BaseType, Mod, Paths, - true); - for (auto &X : Paths) { - TypeExpansionVault[Base.getType()].push_back(std::move(X.getValue())); - } - } - - // Construct the MemLocation by appending the projection path from the - // accessed node to the leaf nodes. - for (auto &X : TypeExpansionVault[Base.getType()]) { - Locs.push_back(MemLocation::createMemLocation(Base.getBase(), X.getValue(), - Base.getPath().getValue())); - } -} - -void MemLocation::reduce(MemLocation &Base, SILModule *Mod, - MemLocationSet &Locs) { - // First, construct the MemLocation by appending the projection path from the - // accessed node to the leaf nodes. - MemLocationList ALocs; - ProjectionPathList Paths; - ProjectionPath::expandTypeIntoLeafProjectionPaths(Base.getType(), Mod, Paths, - false); - for (auto &X : Paths) { - ALocs.push_back(MemLocation::createMemLocation(Base.getBase(), X.getValue(), - Base.getPath().getValue())); - } - - // Second, go from leaf nodes to their parents. This guarantees that at the - // point the parent is processed, its children have been processed already. - for (auto I = ALocs.rbegin(), E = ALocs.rend(); I != E; ++I) { - MemLocationList FirstLevel; - I->getFirstLevelMemLocations(FirstLevel, Mod); - // Reached the end of the projection tree, this is a leaf node. - if (FirstLevel.empty()) - continue; - - // If this is a class reference type, we have reached end of the type tree. - if (I->getType().getClassOrBoundGenericClass()) - continue; - - // This is NOT a leaf node, check whether all its first level children are - // alive. - bool Alive = true; - for (auto &X : FirstLevel) { - if (Locs.find(X) != Locs.end()) - continue; - Alive = false; - } - - // All first level locations are alive, create the new aggregated location. - if (Alive) { - for (auto &X : FirstLevel) - Locs.erase(X); - Locs.insert(*I); - } - } -} - -void MemLocation::expandWithValues(MemLocation &Base, SILValue &Val, - SILModule *Mod, MemLocationList &Locs, - LoadStoreValueList &Vals) { - // To expand a memory location to its indivisible parts, we first get the - // projection paths from the accessed type to each indivisible field, i.e. - // leaf nodes, then we append these projection paths to the Base. - ProjectionPathList Paths; - ProjectionPath::expandTypeIntoLeafProjectionPaths(Base.getType(), Mod, Paths, - true); - - // Construct the MemLocation and LoadStoreValues by appending the projection - // path - // from the accessed node to the leaf nodes. - for (auto &X : Paths) { - Locs.push_back(MemLocation::createMemLocation(Base.getBase(), X.getValue(), - Base.getPath().getValue())); - Vals.push_back(LoadStoreValue(Val, X.getValue())); - } -} - -SILValue MemLocation::reduceWithValues(MemLocation &Base, SILModule *Mod, - MemLocationValueMap &Values, - SILInstruction *InsertPt) { - // Walk bottom up the projection tree, try to reason about how to construct - // a single SILValue out of all the available values for all the memory - // locations. - // - // First, get a list of all the leaf nodes and intermediate nodes for the - // Base memory location. - MemLocationList ALocs; - ProjectionPathList Paths; - ProjectionPath::expandTypeIntoLeafProjectionPaths(Base.getType(), Mod, Paths, - false); - for (auto &X : Paths) { - ALocs.push_back(MemLocation::createMemLocation(Base.getBase(), X.getValue(), - Base.getPath().getValue())); - } - - // Second, go from leaf nodes to their parents. This guarantees that at the - // point the parent is processed, its children have been processed already. - for (auto I = ALocs.rbegin(), E = ALocs.rend(); I != E; ++I) { - // This is a leaf node, we have a value for it. - // - // Reached the end of the projection tree, this is a leaf node. - MemLocationList FirstLevel; - I->getFirstLevelMemLocations(FirstLevel, Mod); - if (FirstLevel.empty()) - continue; - - // If this is a class reference type, we have reached end of the type tree. - if (I->getType().getClassOrBoundGenericClass()) - continue; - - // This is NOT a leaf node, we need to construct a value for it. - // - // If there are more than 1 children and all the children nodes have - // LoadStoreValues with the same base. we can get away by not extracting - // value - // for every single field. - // - // Simply create a new node with all the aggregated base value, i.e. - // stripping off the last level projection. - // - bool HasIdenticalValueBase = true; - auto Iter = FirstLevel.begin(); - LoadStoreValue &FirstVal = Values[*Iter]; - SILValue FirstBase = FirstVal.getBase(); - Iter = std::next(Iter); - for (auto EndIter = FirstLevel.end(); Iter != EndIter; ++Iter) { - LoadStoreValue &V = Values[*Iter]; - HasIdenticalValueBase &= (FirstBase == V.getBase()); - } - - if (HasIdenticalValueBase && - (FirstLevel.size() > 1 || !FirstVal.hasEmptyProjectionPath())) { - Values[*I] = FirstVal.stripLastLevelProjection(); - // We have a value for the parent, remove all the values for children. - removeMemLocations(Values, FirstLevel); - continue; - } - - // In 2 cases do we need aggregation. - // - // 1. If there is only 1 child and we can not strip off any projections, - // that means we need to create an aggregation. - // - // 2. Children have values from different bases, We need to create - // extractions and aggregation in this case. - // - llvm::SmallVector Vals; - for (auto &X : FirstLevel) { - Vals.push_back(Values[X].materialize(InsertPt)); - } - SILBuilder Builder(InsertPt); - NullablePtr AI = - Projection::createAggFromFirstLevelProjections( - Builder, InsertPt->getLoc(), I->getType(), Vals); - // This is the Value for the current node. - ProjectionPath P; - Values[*I] = LoadStoreValue(SILValue(AI.get()), P); - removeMemLocations(Values, FirstLevel); - - // Keep iterating until we have reach the top-most level of the projection - // tree. - // i.e. the memory location represented by the Base. - } - - assert(Values.size() == 1 && "Should have a single location this point"); - - // Finally materialize and return the forwarding SILValue. - return Values.begin()->second.materialize(InsertPt); -} - -void MemLocation::enumerateMemLocation(SILModule *M, SILValue Mem, - std::vector &LV, - MemLocationIndexMap &BM, - TypeExpansionMap &TV) { - // Construct a Location to represent the memory written by this instruction. - MemLocation L(Mem); - - // If we cant figure out the Base or Projection Path for the memory location, - // simply ignore it for now. - if (!L.isValid()) - return; - - // Expand the given Mem into individual fields and add them to the - // locationvault. - MemLocationList Locs; - MemLocation::expand(L, M, Locs, TV); - for (auto &Loc : Locs) { - BM[Loc] = LV.size(); - LV.push_back(Loc); - } -} - -void MemLocation::enumerateMemLocations(SILFunction &F, - std::vector &LV, - MemLocationIndexMap &BM, - TypeExpansionMap &TV) { - // Enumerate all locations accessed by the loads or stores. - // - // TODO: process more instructions as we process more instructions in - // processInstruction. - // - SILValue Op; - for (auto &B : F) { - for (auto &I : B) { - if (auto *LI = dyn_cast(&I)) { - enumerateMemLocation(&I.getModule(), LI->getOperand(), LV, BM, TV); - } else if (auto *SI = dyn_cast(&I)) { - enumerateMemLocation(&I.getModule(), SI->getDest(), LV, BM, TV); - } - } - } -} diff --git a/lib/SIL/PrettyStackTrace.cpp b/lib/SIL/PrettyStackTrace.cpp index 2cc33c0948fd0..6fd027463afad 100644 --- a/lib/SIL/PrettyStackTrace.cpp +++ b/lib/SIL/PrettyStackTrace.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SIL/Projection.cpp b/lib/SIL/Projection.cpp index 2e4bc63adb699..7fc26ae8d7776 100644 --- a/lib/SIL/Projection.cpp +++ b/lib/SIL/Projection.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -34,22 +34,699 @@ static_assert(sizeof(Projection) == ((sizeof(uintptr_t) * 2) "Projection size changed"); //===----------------------------------------------------------------------===// -// Projection +// Utility //===----------------------------------------------------------------------===// -/// Returns true if we are accessing different fields. -static bool areProjectionsToDifferentFields(const Projection &P1, - const Projection &P2) { - // If operands have the same type and we are accessing different fields, - // returns true. Operand's type is not saved in Projection. Instead we check - // Decl's context. - if (!P1.isNominalKind() || !P2.isNominalKind()) +static unsigned getIndexForValueDecl(ValueDecl *Decl) { + NominalTypeDecl *D = cast(Decl->getDeclContext()); + + unsigned i = 0; + for (auto *V : D->getStoredProperties()) { + if (V == Decl) + return i; + ++i; + } + + llvm_unreachable("Failed to find Decl in its decl context?!"); +} + +//===----------------------------------------------------------------------===// +// New Projection +//===----------------------------------------------------------------------===// + +NewProjection::NewProjection(SILInstruction *I) : Value() { + if (!I) + return; + /// Initialize given the specific instruction type and verify with asserts + /// that we constructed it correctly. + switch (I->getKind()) { + // If we do not support this instruction kind, then just bail. Index will + // be None so the Projection will be invalid. + default: + return; + case ValueKind::StructElementAddrInst: { + auto *SEAI = cast(I); + Value = ValueTy(NewProjectionKind::Struct, SEAI->getFieldNo()); + assert(getKind() == NewProjectionKind::Struct); + assert(getIndex() == SEAI->getFieldNo()); + assert(getType(SEAI->getOperand().getType(), SEAI->getModule()) == + SEAI->getType()); + break; + } + case ValueKind::StructExtractInst: { + auto *SEI = cast(I); + Value = ValueTy(NewProjectionKind::Struct, SEI->getFieldNo()); + assert(getKind() == NewProjectionKind::Struct); + assert(getIndex() == SEI->getFieldNo()); + assert(getType(SEI->getOperand().getType(), SEI->getModule()) == + SEI->getType()); + break; + } + case ValueKind::RefElementAddrInst: { + auto *REAI = cast(I); + Value = ValueTy(NewProjectionKind::Class, REAI->getFieldNo()); + assert(getKind() == NewProjectionKind::Class); + assert(getIndex() == REAI->getFieldNo()); + assert(getType(REAI->getOperand().getType(), REAI->getModule()) == + REAI->getType()); + break; + } + case ValueKind::TupleExtractInst: { + auto *TEI = cast(I); + Value = ValueTy(NewProjectionKind::Tuple, TEI->getFieldNo()); + assert(getKind() == NewProjectionKind::Tuple); + assert(getIndex() == TEI->getFieldNo()); + assert(getType(TEI->getOperand().getType(), TEI->getModule()) == + TEI->getType()); + break; + } + case ValueKind::TupleElementAddrInst: { + auto *TEAI = cast(I); + Value = ValueTy(NewProjectionKind::Tuple, TEAI->getFieldNo()); + assert(getKind() == NewProjectionKind::Tuple); + assert(getIndex() == TEAI->getFieldNo()); + assert(getType(TEAI->getOperand().getType(), TEAI->getModule()) == + TEAI->getType()); + break; + } + case ValueKind::UncheckedEnumDataInst: { + auto *UEDI = cast(I); + Value = ValueTy(NewProjectionKind::Enum, UEDI->getElementNo()); + assert(getKind() == NewProjectionKind::Enum); + assert(getIndex() == UEDI->getElementNo()); + assert(getType(UEDI->getOperand().getType(), UEDI->getModule()) == + UEDI->getType()); + break; + } + case ValueKind::UncheckedTakeEnumDataAddrInst: { + auto *UTEDAI = cast(I); + Value = ValueTy(NewProjectionKind::Enum, UTEDAI->getElementNo()); + assert(getKind() == NewProjectionKind::Enum); + assert(getIndex() == UTEDAI->getElementNo()); + assert(getType(UTEDAI->getOperand().getType(), UTEDAI->getModule()) == + UTEDAI->getType()); + break; + } + case ValueKind::IndexAddrInst: { + // We can represent all integers provided here since getIntegerIndex only + // returns 32 bit values. When that changes, this code will need to be + // updated and a MaxLargeIndex will need to be used here. Currently we + // represent large Indexes using a 64 bit integer, so we don't need to mess + // with anything. + unsigned NewIndex = ~0; + auto *IAI = cast(I); + if (getIntegerIndex(IAI->getIndex(), NewIndex)) { + assert(NewIndex != unsigned(~0) && "NewIndex should have been changed " + "by getIntegerIndex?!"); + Value = ValueTy(NewProjectionKind::Index, NewIndex); + assert(getKind() == NewProjectionKind::Index); + assert(getIndex() == NewIndex); + } + break; + } + case ValueKind::UpcastInst: { + auto *Ty = I->getType(0).getSwiftRValueType().getPointer(); + assert(Ty->isCanonical()); + Value = ValueTy(NewProjectionKind::Upcast, Ty); + assert(getKind() == NewProjectionKind::Upcast); + assert(getType(I->getOperand(0).getType(), I->getModule()) == + I->getType(0)); + break; + } + case ValueKind::UncheckedRefCastInst: { + auto *Ty = I->getType(0).getSwiftRValueType().getPointer(); + assert(Ty->isCanonical()); + Value = ValueTy(NewProjectionKind::RefCast, Ty); + assert(getKind() == NewProjectionKind::RefCast); + assert(getType(I->getOperand(0).getType(), I->getModule()) == + I->getType(0)); + break; + } + case ValueKind::UncheckedBitwiseCastInst: + case ValueKind::UncheckedAddrCastInst: { + auto *Ty = I->getType(0).getSwiftRValueType().getPointer(); + assert(Ty->isCanonical()); + Value = ValueTy(NewProjectionKind::BitwiseCast, Ty); + assert(getKind() == NewProjectionKind::BitwiseCast); + assert(getType(I->getOperand(0).getType(), I->getModule()) == + I->getType(0)); + break; + } + } +} + +NullablePtr +NewProjection::createObjectProjection(SILBuilder &B, SILLocation Loc, + SILValue Base) const { + SILType BaseTy = Base.getType(); + + // We can only create a value projection from an object. + if (!BaseTy.isObject()) + return nullptr; + + // Ok, we now know that the type of Base and the type represented by the base + // of this projection match and that this projection can be represented as + // value. Create the instruction if we can. Otherwise, return nullptr. + switch (getKind()) { + case NewProjectionKind::Struct: + return B.createStructExtract(Loc, Base, getVarDecl(BaseTy)); + case NewProjectionKind::Tuple: + return B.createTupleExtract(Loc, Base, getIndex()); + case NewProjectionKind::Index: + return nullptr; + case NewProjectionKind::Enum: + return B.createUncheckedEnumData(Loc, Base, getEnumElementDecl(BaseTy)); + case NewProjectionKind::Class: + return nullptr; + case NewProjectionKind::Upcast: + return B.createUpcast(Loc, Base, getCastType(BaseTy)); + case NewProjectionKind::RefCast: + return B.createUncheckedRefCast(Loc, Base, getCastType(BaseTy)); + case NewProjectionKind::BitwiseCast: + return B.createUncheckedBitwiseCast(Loc, Base, getCastType(BaseTy)); + } +} + +NullablePtr +NewProjection::createAddressProjection(SILBuilder &B, SILLocation Loc, + SILValue Base) const { + SILType BaseTy = Base.getType(); + + // We can only create an address projection from an object, unless we have a + // class. + if (BaseTy.getClassOrBoundGenericClass() || !BaseTy.isAddress()) + return nullptr; + + // Ok, we now know that the type of Base and the type represented by the base + // of this projection match and that this projection can be represented as + // value. Create the instruction if we can. Otherwise, return nullptr. + switch (getKind()) { + case NewProjectionKind::Struct: + return B.createStructElementAddr(Loc, Base, getVarDecl(BaseTy)); + case NewProjectionKind::Tuple: + return B.createTupleElementAddr(Loc, Base, getIndex()); + case NewProjectionKind::Index: { + auto IntLiteralTy = + SILType::getBuiltinIntegerType(64, B.getModule().getASTContext()); + auto IntLiteralIndex = + B.createIntegerLiteral(Loc, IntLiteralTy, getIndex()); + return B.createIndexAddr(Loc, Base, IntLiteralIndex); + } + case NewProjectionKind::Enum: + return B.createUncheckedTakeEnumDataAddr(Loc, Base, + getEnumElementDecl(BaseTy)); + case NewProjectionKind::Class: + return B.createRefElementAddr(Loc, Base, getVarDecl(BaseTy)); + case NewProjectionKind::Upcast: + return B.createUpcast(Loc, Base, getCastType(BaseTy)); + case NewProjectionKind::RefCast: + case NewProjectionKind::BitwiseCast: + return B.createUncheckedAddrCast(Loc, Base, getCastType(BaseTy)); + } +} + +void NewProjection::getFirstLevelProjections( + SILType Ty, SILModule &Mod, llvm::SmallVectorImpl &Out) { + if (auto *S = Ty.getStructOrBoundGenericStruct()) { + unsigned Count = 0; + for (auto *VDecl : S->getStoredProperties()) { + (void) VDecl; + NewProjection P(NewProjectionKind::Struct, Count++); + DEBUG(NewProjectionPath X(Ty); + assert(X.getMostDerivedType(Mod) == Ty); + X.append(P); + assert(X.getMostDerivedType(Mod) == Ty.getFieldType(VDecl, Mod)); + X.verify(Mod);); + Out.push_back(P); + } + return; + } + + if (auto TT = Ty.getAs()) { + for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) { + NewProjection P(NewProjectionKind::Tuple, i); + DEBUG(NewProjectionPath X(Ty); + assert(X.getMostDerivedType(Mod) == Ty); + X.append(P); + assert(X.getMostDerivedType(Mod) == Ty.getTupleElementType(i)); + X.verify(Mod);); + Out.push_back(P); + } + return; + } + + if (auto *C = Ty.getClassOrBoundGenericClass()) { + unsigned Count = 0; + for (auto *VDecl : C->getStoredProperties()) { + (void) VDecl; + NewProjection P(NewProjectionKind::Class, Count++); + DEBUG(NewProjectionPath X(Ty); + assert(X.getMostDerivedType(Mod) == Ty); + X.append(P); + assert(X.getMostDerivedType(Mod) == Ty.getFieldType(VDecl, Mod)); + X.verify(Mod);); + Out.push_back(P); + } + return; + } +} + +//===----------------------------------------------------------------------===// +// New Projection Path +//===----------------------------------------------------------------------===// + +Optional NewProjectionPath::getProjectionPath(SILValue Start, + SILValue End) { + NewProjectionPath P(Start.getType()); + + // If Start == End, there is a "trivial" projection path in between the + // two. This is represented by returning an empty ProjectionPath. + if (Start == End) + return std::move(P); + + // Do not inspect the body of types with unreferenced types such as bitfields + // and unions. This is currently only associated with structs. + if (Start.getType().aggregateHasUnreferenceableStorage() || + End.getType().aggregateHasUnreferenceableStorage()) + return llvm::NoneType::None; + + auto Iter = End; + bool NextAddrIsIndex = false; + while (Start != Iter) { + NewProjection AP(Iter); + if (!AP.isValid()) + break; + P.Path.push_back(AP); + NextAddrIsIndex = AP.getKind() == NewProjectionKind::Index; + Iter = cast(*Iter).getOperand(0); + } + + // Return None if we have an empty projection list or if Start == Iter. + // If the next project is index_addr, then Start and End actually point to + // disjoint locations (the value at Start has an implicit index_addr #0). + if (P.empty() || Start != Iter || NextAddrIsIndex) + return llvm::NoneType::None; + + // Otherwise, return P. + return std::move(P); +} + +/// Returns true if the two paths have a non-empty symmetric difference. +/// +/// This means that the two objects have the same base but access different +/// fields of the base object. +bool NewProjectionPath::hasNonEmptySymmetricDifference( + const NewProjectionPath &RHS) const { + // First make sure that both of our base types are the same. + if (BaseType != RHS.BaseType) return false; - return P1.getDecl()->getDeclContext() == P2.getDecl()->getDeclContext() && - P1 != P2; + // We assume that the two paths must be non-empty. + // + // I believe that we assume this since in the code that uses this we check for + // full differences before we use this code path. + // + // TODO: Is this necessary. + if (empty() || RHS.empty()) + return false; + + // Otherwise, we have a common base and perhaps some common subpath. + auto LHSReverseIter = Path.rbegin(); + auto RHSReverseIter = RHS.Path.rbegin(); + + bool FoundDifferingProjections = false; + + // For each index i until min path size... + unsigned i = 0; + for (unsigned e = std::min(size(), RHS.size()); i != e; ++i) { + // Grab the current projections. + const NewProjection &LHSProj = *LHSReverseIter; + const NewProjection &RHSProj = *RHSReverseIter; + + // If we are accessing different fields of a common object, the two + // projection paths may have a non-empty symmetric difference. We check if + if (LHSProj != RHSProj) { + DEBUG(llvm::dbgs() << " Path different at index: " << i << '\n'); + FoundDifferingProjections = true; + break; + } + + // Continue if we are accessing the same field. + LHSReverseIter++; + RHSReverseIter++; + } + + // All path elements are the same. The symmetric difference is empty. + if (!FoundDifferingProjections) + return false; + + // We found differing projections, but we need to make sure that there are no + // casts in the symmetric difference. To be conservative, we only wish to + // allow for casts to appear in the common parts of projections. + for (unsigned li = i, e = size(); li != e; ++li) { + if (LHSReverseIter->isAliasingCast()) + return false; + LHSReverseIter++; + } + for (unsigned ri = i, e = RHS.size(); ri != e; ++ri) { + if (RHSReverseIter->isAliasingCast()) + return false; + RHSReverseIter++; + } + + // If we don't have any casts in our symmetric difference (i.e. only typed + // GEPs), then we can say that these actually have a symmetric difference we + // can understand. The fundamental issue here is that since we do not have any + // notion of size, we cannot know the effect of a cast + gep on the final + // location that we are reaching. + return true; } +/// TODO: Integrate has empty non-symmetric difference into here. +SubSeqRelation_t +NewProjectionPath::computeSubSeqRelation(const NewProjectionPath &RHS) const { + // Make sure that both base types are the same. Otherwise, we can not compare + // the projections as sequences. + if (BaseType != RHS.BaseType) + return SubSeqRelation_t::Unknown; + + // If either path is empty, we can not prove anything, return Unknown. + if (empty() || RHS.empty()) + return SubSeqRelation_t::Unknown; + + // We reverse the projection path to scan from the common object. + auto LHSReverseIter = rbegin(); + auto RHSReverseIter = RHS.rbegin(); + + unsigned MinPathSize = std::min(size(), RHS.size()); + + // For each index i until min path size... + for (unsigned i = 0; i != MinPathSize; ++i) { + // Grab the current projections. + const NewProjection &LHSProj = *LHSReverseIter; + const NewProjection &RHSProj = *RHSReverseIter; + + // If the two projections do not equal exactly, return Unrelated. + // + // TODO: If Index equals zero, then we know that the two lists have nothing + // in common and should return unrelated. If Index is greater than zero, + // then we know that the two projection paths have a common base but a + // non-empty symmetric difference. For now we just return Unrelated since I + // can not remember why I had the special check in the + // hasNonEmptySymmetricDifference code. + if (LHSProj != RHSProj) + return SubSeqRelation_t::Unknown; + + // Otherwise increment reverse iterators. + LHSReverseIter++; + RHSReverseIter++; + } + + // Ok, we now know that one of the paths is a subsequence of the other. If + // both size() and RHS.size() equal then we know that the entire sequences + // equal. + if (size() == RHS.size()) + return SubSeqRelation_t::Equal; + + // If MinPathSize == size(), then we know that LHS is a strict subsequence of + // RHS. + if (MinPathSize == size()) + return SubSeqRelation_t::LHSStrictSubSeqOfRHS; + + // Otherwise, we know that MinPathSize must be RHS.size() and RHS must be a + // strict subsequence of LHS. Assert to check this and return. + assert(MinPathSize == RHS.size() && + "Since LHS and RHS don't equal and size() != MinPathSize, RHS.size() " + "must equal MinPathSize"); + return SubSeqRelation_t::RHSStrictSubSeqOfLHS; +} + +bool NewProjectionPath::findMatchingObjectProjectionPaths( + SILInstruction *I, SmallVectorImpl &T) const { + // We only support unary instructions. + if (I->getNumOperands() != 1 || I->getNumTypes() != 1) + return false; + + // Check that the base result type of I is equivalent to this types base path. + if (I->getOperand(0).getType().copyCategory(BaseType) != BaseType) + return false; + + // We maintain the head of our worklist so we can use our worklist as a queue + // and work in breadth first order. This makes sense since we want to process + // in levels so we can maintain one tail list and delete the tail list when we + // move to the next level. + unsigned WorkListHead = 0; + llvm::SmallVector WorkList; + WorkList.push_back(I); + + // Start at the root of the list. + for (auto PI = rbegin(), PE = rend(); PI != PE; ++PI) { + // When we start a new level, clear the tail list. + T.clear(); + + // If we have an empty worklist, return false. We have been unable to + // complete the list. + unsigned WorkListSize = WorkList.size(); + if (WorkListHead == WorkListSize) + return false; + + // Otherwise, process each instruction in the worklist. + for (; WorkListHead != WorkListSize; WorkListHead++) { + SILInstruction *Ext = WorkList[WorkListHead]; + + // If the current projection does not match I, continue and process the + // next instruction. + if (!PI->matchesObjectProjection(Ext)) { + continue; + } + + // Otherwise, we know that Ext matched this projection path and we should + // visit all of its uses and add Ext itself to our tail list. + T.push_back(Ext); + for (auto *Op : Ext->getUses()) { + WorkList.push_back(Op->getUser()); + } + } + + // Reset the worklist size. + WorkListSize = WorkList.size(); + } + + return true; +} + +Optional +NewProjectionPath::removePrefix(const NewProjectionPath &Path, + const NewProjectionPath &Prefix) { + // We can only subtract paths that have the same base. + if (Path.BaseType != Prefix.BaseType) + return llvm::NoneType::None; + + // If Prefix is greater than or equal to Path in size, Prefix can not be a + // prefix of Path. Return None. + unsigned PrefixSize = Prefix.size(); + unsigned PathSize = Path.size(); + + if (PrefixSize >= PathSize) + return llvm::NoneType::None; + + // First make sure that the prefix matches. + Optional P = NewProjectionPath(Path.BaseType); + for (unsigned i = 0; i < PrefixSize; i++) { + if (Path.Path[i] != Prefix.Path[i]) { + P.reset(); + return P; + } + } + + // Add the rest of Path to P and return P. + for (unsigned i = PrefixSize, e = PathSize; i != e; ++i) { + P->Path.push_back(Path.Path[i]); + } + + return P; +} + +SILValue NewProjectionPath::createObjectProjections(SILBuilder &B, + SILLocation Loc, + SILValue Base) { + assert(BaseType.isAddress()); + assert(Base.getType().isObject()); + assert(Base.getType().getAddressType() == BaseType); + SILValue Val = Base; + for (auto iter : Path) { + Val = iter.createObjectProjection(B, Loc, Val).get(); + } + return Val; +} + +raw_ostream &NewProjectionPath::print(raw_ostream &os, SILModule &M) { + // Match how the memlocation print tests expect us to print projection paths. + // + // TODO: It sort of sucks having to print these bottom up computationally. We + // should really change the test so that prints out the path elements top + // down the path, rather than constructing all of these intermediate paths. + for (unsigned i : reversed(indices(Path))) { + SILType IterType = getDerivedType(i, M); + auto &IterProj = Path[i]; + os << "Address Projection Type: "; + if (IterProj.isNominalKind()) { + auto *Decl = IterProj.getVarDecl(IterType); + IterType = IterProj.getType(IterType, M); + os << IterType.getAddressType() << "\n"; + os << "Field Type: "; + Decl->print(os); + os << "\n"; + continue; + } + + if (IterProj.getKind() == NewProjectionKind::Tuple) { + IterType = IterProj.getType(IterType, M); + os << IterType.getAddressType() << "\n"; + os << "Index: "; + os << IterProj.getIndex() << "\n"; + continue; + } + + llvm_unreachable("Can not print this projection kind"); + } + +// Migrate the tests to this format eventually. +#if 0 + os << "(Projection Path ["; + SILType NextType = BaseType; + os << NextType; + for (const NewProjection &P : Path) { + os << ", "; + NextType = P.getType(NextType, M); + os << NextType; + } + os << "]"; +#endif + return os; +} + +raw_ostream &NewProjectionPath::printProjections(raw_ostream &os, SILModule &M) { + // Match how the memlocation print tests expect us to print projection paths. + // + // TODO: It sort of sucks having to print these bottom up computationally. We + // should really change the test so that prints out the path elements top + // down the path, rather than constructing all of these intermediate paths. + for (unsigned i : reversed(indices(Path))) { + auto &IterProj = Path[i]; + if (IterProj.isNominalKind()) { + os << "Field Type: " << IterProj.getIndex() << "\n"; + continue; + } + + if (IterProj.getKind() == NewProjectionKind::Tuple) { + os << "Index: " << IterProj.getIndex() << "\n"; + continue; + } + + llvm_unreachable("Can not print this projection kind"); + } + + return os; +} + +void NewProjectionPath::dump(SILModule &M) { + print(llvm::outs(), M); + llvm::outs() << "\n"; +} + +void NewProjectionPath::dumpProjections(SILModule &M) { + printProjections(llvm::outs(), M); +} + +void NewProjectionPath::verify(SILModule &M) { +#ifndef NDEBUG + SILType IterTy = getBaseType(); + assert(IterTy); + for (auto &Proj : Path) { + IterTy = Proj.getType(IterTy, M); + assert(IterTy); + } +#endif +} + +void NewProjectionPath::expandTypeIntoLeafProjectionPaths( + SILType B, SILModule *Mod, llvm::SmallVectorImpl &Paths, + bool OnlyLeafNode) { + // Perform a BFS to expand the given type into projectionpath each of + // which contains 1 field from the type. + llvm::SmallVector Worklist; + llvm::SmallVector Projections; + + // Push an empty projection path to get started. + NewProjectionPath P(B); + Worklist.push_back(P); + do { + // Get the next level projections based on current projection's type. + NewProjectionPath PP = Worklist.pop_back_val(); + // Get the current type to process. + SILType Ty = PP.getMostDerivedType(*Mod); + + DEBUG(llvm::dbgs() << "Visiting type: " << Ty << "\n"); + + // Get the first level projection of the current type. + Projections.clear(); + NewProjection::getFirstLevelProjections(Ty, *Mod, Projections); + + // Reached the end of the projection tree, this field can not be expanded + // anymore. + if (Projections.empty()) { + DEBUG(llvm::dbgs() << " No projections. Finished projection list\n"); + Paths.push_back(PP); + continue; + } + + // If this is a class type, we also have reached the end of the type + // tree for this type. + // + // We do not push its next level projection into the worklist, + // if we do that, we could run into an infinite loop, e.g. + // + // class SelfLoop { + // var p : SelfLoop + // } + // + // struct XYZ { + // var x : Int + // var y : SelfLoop + // } + // + // The worklist would never be empty in this case !. + // + if (Ty.getClassOrBoundGenericClass()) { + DEBUG(llvm::dbgs() << " Found class. Finished projection list\n"); + Paths.push_back(PP); + continue; + } + + // This is NOT a leaf node, keep the intermediate nodes as well. + if (!OnlyLeafNode) { + DEBUG(llvm::dbgs() << " Found class. Finished projection list\n"); + Paths.push_back(PP); + } + + // Keep expanding the location. + for (auto &P : Projections) { + NewProjectionPath X(B); + X.append(PP); + assert(PP.getMostDerivedType(*Mod) == X.getMostDerivedType(*Mod)); + X.append(P); + Worklist.push_back(X); + } + + // Keep iterating if the worklist is not empty. + } while (!Worklist.empty()); +} + +//===----------------------------------------------------------------------===// +// Projection +//===----------------------------------------------------------------------===// + bool Projection::matchesValueProjection(SILInstruction *I) const { llvm::Optional P = Projection::valueProjectionForInstruction(I); if (!P) @@ -139,19 +816,6 @@ Projection::operator<(Projection Other) const { } } -static unsigned getIndexForValueDecl(ValueDecl *Decl) { - NominalTypeDecl *D = cast(Decl->getDeclContext()); - - unsigned i = 0; - for (auto *V : D->getStoredProperties()) { - if (V == Decl) - return i; - ++i; - } - - llvm_unreachable("Failed to find Decl in its decl context?!"); -} - /// We do not support symbolic projections yet, only 32-bit unsigned integers. bool swift::getIntegerIndex(SILValue IndexVal, unsigned &IndexConst) { if (auto *IndexLiteral = dyn_cast(IndexVal)) { @@ -218,16 +882,6 @@ createValueProjection(SILBuilder &B, SILLocation Loc, SILValue Base) const { if (!BaseTy.isObject()) return nullptr; - // If this projection is associated with an address type, convert its type to - // an object type. - // - // We explicitly do not convert Type to be an object if it is a local storage - // type since we want it to fail. - SILType Ty = Type.isAddress()? Type.getObjectType() : Type; - - if (!Ty.isObject()) - return nullptr; - // Ok, we now know that the type of Base and the type represented by the base // of this projection match and that this projection can be represented as // value. Create the instruction if we can. Otherwise, return nullptr. @@ -256,17 +910,6 @@ createAddrProjection(SILBuilder &B, SILLocation Loc, SILValue Base) const { if (!BaseTy.isAddress()) return nullptr; - // If this projection is associated with an object type, convert its type to - // an address type. - // - // *NOTE* We purposely do not handle local storage types here since we want to - // always fail in such a case. That is handled by checking that Ty is an - // address. - SILType Ty = Type.isObject()? Type.getAddressType() : Type; - - if (!Ty.isAddress()) - return nullptr; - // Ok, we now know that the type of Base and the type represented by the base // of this projection match and that this projection can be represented as // value. Create the instruction if we can. Otherwise, return nullptr. @@ -397,6 +1040,17 @@ createAggFromFirstLevelProjections(SILBuilder &B, SILLocation Loc, // Projection Path //===----------------------------------------------------------------------===// +static bool areProjectionsToDifferentFields(const Projection &P1, + const Projection &P2) { + // If operands have the same type and we are accessing different fields, + // returns true. Operand's type is not saved in Projection. Instead we check + // Decl's context. + if (!P1.isNominalKind() || !P2.isNominalKind()) + return false; + return P1.getDecl()->getDeclContext() == P2.getDecl()->getDeclContext() && + P1 != P2; +} + Optional ProjectionPath::getAddrProjectionPath(SILValue Start, SILValue End, bool IgnoreCasts) { @@ -488,9 +1142,9 @@ hasNonEmptySymmetricDifference(const ProjectionPath &RHS) const { SubSeqRelation_t ProjectionPath:: computeSubSeqRelation(const ProjectionPath &RHS) const { - // If either path is empty, we can not prove anything, return Unrelated. + // If either path is empty, we cannot prove anything, return Unrelated. if (empty() || RHS.empty()) - return SubSeqRelation_t::Unrelated; + return SubSeqRelation_t::Unknown; // We reverse the projection path to scan from the common object. auto LHSReverseIter = rbegin(); @@ -510,10 +1164,10 @@ computeSubSeqRelation(const ProjectionPath &RHS) const { // in common and should return unrelated. If Index is greater than zero, // then we know that the two projection paths have a common base but a // non-empty symmetric difference. For now we just return Unrelated since I - // can not remember why I had the special check in the + // cannot remember why I had the special check in the // hasNonEmptySymmetricDifference code. if (LHSProj != RHSProj) - return SubSeqRelation_t::Unrelated; + return SubSeqRelation_t::Unknown; // Otherwise increment reverse iterators. LHSReverseIter++; @@ -588,7 +1242,7 @@ findMatchingValueProjectionPaths(SILInstruction *I, Optional ProjectionPath::subtractPaths(const ProjectionPath &LHS, const ProjectionPath &RHS) { - // If RHS is greater than or equal to LHS in size, RHS can not be a prefix of + // If RHS is greater than or equal to LHS in size, RHS cannot be a prefix of // LHS. Return None. unsigned RHSSize = RHS.size(); unsigned LHSSize = LHS.size(); @@ -614,8 +1268,8 @@ ProjectionPath::subtractPaths(const ProjectionPath &LHS, const ProjectionPath &R void ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod, - ProjectionPathList &Paths, - bool OnlyLeafNode) { + ProjectionPathList &Paths) { + // Perform a BFS to expand the given type into projectionpath each of // which contains 1 field from the type. ProjectionPathList Worklist; @@ -636,7 +1290,7 @@ ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod, Projections.clear(); Projection::getFirstLevelAddrProjections(Ty, *Mod, Projections); - // Reached the end of the projection tree, this field can not be expanded + // Reached the end of the projection tree, this field cannot be expanded // anymore. if (Projections.empty()) { Paths.push_back(std::move(PP.getValue())); @@ -665,9 +1319,80 @@ ProjectionPath::expandTypeIntoLeafProjectionPaths(SILType B, SILModule *Mod, continue; } - // This is NOT a leaf node, keep the intermediate nodes as well. - if (!OnlyLeafNode) + // Keep expanding the location. + for (auto &P : Projections) { + ProjectionPath X; + X.append(P); + X.append(PP.getValue()); + Worklist.push_back(std::move(X)); + } + // Keep iterating if the worklist is not empty. + } while (!Worklist.empty()); + +} + +void +ProjectionPath::expandTypeIntoNodeProjectionPaths(SILType B, SILModule *Mod, + ProjectionPathList &Paths) { + // Perform a BFS to expand the given type into projectionpath each of + // which contains 1 field from the type. + ProjectionPathList Worklist; + llvm::SmallVector Projections; + + // Push an empty projection path to get started. + SILType Ty; + ProjectionPath P; + Worklist.push_back(std::move(P)); + do { + // Get the next level projections based on current projection's type. + Optional PP = Worklist.pop_back_val(); + // Get the current type to process, the very first projection path will be + // empty. + Ty = PP.getValue().empty() ? B : PP.getValue().front().getType(); + + // Get the first level projection of the current type. + Projections.clear(); + Projection::getFirstLevelAddrProjections(Ty, *Mod, Projections); + + // Reached the end of the projection tree, this field cannot be expanded + // anymore. + if (Projections.empty()) { + Paths.push_back(std::move(PP.getValue())); + continue; + } + + // If this is a class type, we also have reached the end of the type + // tree for this type. + // + // We do not push its next level projection into the worklist, + // if we do that, we could run into an infinite loop, e.g. + // + // class SelfLoop { + // var p : SelfLoop + // } + // + // struct XYZ { + // var x : Int + // var y : SelfLoop + // } + // + // The worklist would never be empty in this case !. + // + if (Ty.getClassOrBoundGenericClass()) { Paths.push_back(std::move(PP.getValue())); + continue; + } + + // Keep the intermediate nodes as well. + // + // std::move clears the passed ProjectionPath. Give it a temporarily + // created ProjectionPath for now. + // + // TODO: this can be simplified once we reduce the size of the projection + // path and make them copyable. + ProjectionPath T; + T.append(PP.getValue()); + Paths.push_back(std::move(T)); // Keep expanding the location. for (auto &P : Projections) { @@ -753,7 +1478,7 @@ processUsersOfValue(ProjectionTree &Tree, assert(User->getNumTypes() == 1 && "Projections should only have one use"); - // Look up the Node for this projection add add {User, ChildNode} to the + // Look up the Node for this projection add {User, ChildNode} to the // worklist. // // *NOTE* This means that we will process ChildNode multiple times @@ -769,7 +1494,7 @@ processUsersOfValue(ProjectionTree &Tree, "Adding to non projection user!\b"); // The only projection which we do not currently handle are enums since we - // may not know the correct case. This can be xtended in the future. + // may not know the correct case. This can be extended in the future. addNonProjectionUser(Op); } } @@ -1070,7 +1795,7 @@ class ProjectionTreeNode::AggregateBuilder { } SILInstruction *createInstruction() const { - assert(isComplete() && "Can not create instruction until the aggregate is " + assert(isComplete() && "Cannot create instruction until the aggregate is " "complete"); assert(!Invalidated && "Must not be invalidated to create an instruction"); const_cast(this)->Invalidated = true; diff --git a/lib/SIL/SIL.cpp b/lib/SIL/SIL.cpp index 0439805386c58..36763aef1fb30 100644 --- a/lib/SIL/SIL.cpp +++ b/lib/SIL/SIL.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SIL/SILArgument.cpp b/lib/SIL/SILArgument.cpp index 4c88c8b81b4e3..f33407fbd21a1 100644 --- a/lib/SIL/SILArgument.cpp +++ b/lib/SIL/SILArgument.cpp @@ -1,8 +1,8 @@ -//===--- SILArgument.cpp - Arguments for high-level SIL code ---------------==// +//===--- SILArgument.cpp - Arguments for high-level SIL code --------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SIL/SILBasicBlock.cpp b/lib/SIL/SILBasicBlock.cpp index e44645ee576eb..d284b1e106bb8 100644 --- a/lib/SIL/SILBasicBlock.cpp +++ b/lib/SIL/SILBasicBlock.cpp @@ -1,8 +1,8 @@ -//===--- SILBasicBlock.cpp - Basic blocks for high-level SIL code ----------==// +//===--- SILBasicBlock.cpp - Basic blocks for high-level SIL code ---------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -37,7 +37,25 @@ SILBasicBlock::SILBasicBlock(SILFunction *parent, SILBasicBlock *afterBB) } } SILBasicBlock::~SILBasicBlock() { + // Invalidate all of the basic block arguments. + for (auto *Arg : BBArgList) { + getModule().notifyDeleteHandlers(Arg); + } + + dropAllReferences(); + + // Notify the delete handlers that the instructions in this block are + // being deleted. + auto &M = getModule(); + for (auto I = begin(), E = end(); I != E;) { + auto Inst = &*I; + ++I; + M.notifyDeleteHandlers(Inst); + erase(Inst); + } + // iplist's destructor is going to destroy the InstList. + InstList.clearAndLeakNodesUnsafely(); } int SILBasicBlock::getDebugID() { @@ -73,7 +91,11 @@ void SILBasicBlock::remove(SILInstruction *I) { } void SILBasicBlock::erase(SILInstruction *I) { + // Notify the delete handlers that this instruction is going away. + getModule().notifyDeleteHandlers(&*I); + auto *F = getParent(); InstList.erase(I); + F->getModule().deallocateInst(I); } /// This method unlinks 'self' from the containing SILFunction and deletes it. @@ -92,10 +114,18 @@ void SILBasicBlock::removeFromParent() { SILArgument *SILBasicBlock::replaceBBArg(unsigned i, SILType Ty, const ValueDecl *D) { SILModule &M = getParent()->getModule(); + + assert(BBArgList[i]->use_empty() && "Expected no uses of the old BB arg!"); + // Notify the delete handlers that this argument is being deleted. + M.notifyDeleteHandlers(BBArgList[i]); + auto *NewArg = new (M) SILArgument(Ty, D); NewArg->setParent(this); + + // TODO: When we switch to malloc/free allocation we'll be leaking memory + // here. BBArgList[i] = NewArg; return NewArg; @@ -110,6 +140,12 @@ SILArgument *SILBasicBlock::insertBBArg(bbarg_iterator Iter, SILType Ty, return new (getModule()) SILArgument(this, Iter, Ty, D); } +void SILBasicBlock::eraseBBArg(int Index) { + // Notify the delete handlers that this BB argument is going away. + getModule().notifyDeleteHandlers(getBBArg(Index)); + BBArgList.erase(BBArgList.begin() + Index); +} + /// \brief Splits a basic block into two at the specified instruction. /// /// Note that all the instructions BEFORE the specified iterator diff --git a/lib/SIL/SILBuilder.cpp b/lib/SIL/SILBuilder.cpp index 5c5fce062af12..fdef610a4d628 100644 --- a/lib/SIL/SILBuilder.cpp +++ b/lib/SIL/SILBuilder.cpp @@ -1,8 +1,8 @@ -//===--- SILBuilder.cpp - Class for creating SIL Constructs ----------------==// +//===--- SILBuilder.cpp - Class for creating SIL Constructs ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SIL/SILCoverageMap.cpp b/lib/SIL/SILCoverageMap.cpp index daac690fa0a6c..edda49cedfcb6 100644 --- a/lib/SIL/SILCoverageMap.cpp +++ b/lib/SIL/SILCoverageMap.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp index f4a760370de65..a9efb8da892dd 100644 --- a/lib/SIL/SILDeclRef.cpp +++ b/lib/SIL/SILDeclRef.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,9 +25,88 @@ #include "clang/AST/DeclObjC.h" using namespace swift; +/// Get the method dispatch mechanism for a method. +MethodDispatch +swift::getMethodDispatch(AbstractFunctionDecl *method) { + // Final methods can be statically referenced. + if (method->isFinal()) + return MethodDispatch::Static; + // Some methods are forced to be statically dispatched. + if (method->hasForcedStaticDispatch()) + return MethodDispatch::Static; + + // If this declaration is in a class but not marked final, then it is + // always dynamically dispatched. + auto dc = method->getDeclContext(); + if (isa(dc)) + return MethodDispatch::Class; + + // Class extension methods are only dynamically dispatched if they're + // dispatched by objc_msgSend, which happens if they're foreign or dynamic. + if (dc->isClassOrClassExtensionContext()) { + if (method->hasClangNode()) + return MethodDispatch::Class; + if (auto fd = dyn_cast(method)) { + if (fd->isAccessor() && fd->getAccessorStorageDecl()->hasClangNode()) + return MethodDispatch::Class; + } + if (method->getAttrs().hasAttribute()) + return MethodDispatch::Class; + } + + // Otherwise, it can be referenced statically. + return MethodDispatch::Static; +} + +bool swift::requiresForeignToNativeThunk(ValueDecl *vd) { + // Functions imported from C, Objective-C methods imported from Objective-C, + // as well as methods in @objc protocols (even protocols defined in Swift) + // require a foreign to native thunk. + auto dc = vd->getDeclContext(); + if (auto proto = dyn_cast(dc)) + if (proto->isObjC()) + return true; + + if (auto fd = dyn_cast(vd)) + return fd->hasClangNode(); + + return false; +} + +/// FIXME: merge requiresObjCDispatch() into getMethodDispatch() and add +/// an ObjectiveC case to the MethodDispatch enum. +bool swift::requiresObjCDispatch(ValueDecl *vd) { + // Final functions never require ObjC dispatch. + if (vd->isFinal()) + return false; + + if (requiresForeignToNativeThunk(vd)) + return true; + + if (auto *fd = dyn_cast(vd)) { + // Property accessors should be generated alongside the property. + if (fd->isGetterOrSetter()) + return requiresObjCDispatch(fd->getAccessorStorageDecl()); + + return fd->getAttrs().hasAttribute(); + } + + if (auto *cd = dyn_cast(vd)) { + if (cd->hasClangNode()) + return true; + + return cd->getAttrs().hasAttribute(); + } + + if (auto *asd = dyn_cast(vd)) + return asd->requiresObjCGetterAndSetter(); + + return vd->getAttrs().hasAttribute(); +} + static unsigned getFuncNaturalUncurryLevel(AnyFunctionRef AFR) { - assert(AFR.getBodyParamPatterns().size() >= 1 && "no arguments for func?!"); - unsigned Level = AFR.getBodyParamPatterns().size() - 1; + assert(AFR.getParameterLists().size() >= 1 && "no arguments for func?!"); + unsigned Level = AFR.getParameterLists().size() - 1; // Functions with captures have an extra uncurry level for the capture // context. if (AFR.getCaptureInfo().hasLocalCaptures()) @@ -130,7 +209,7 @@ SILDeclRef::SILDeclRef(SILDeclRef::Loc baseLoc, } else if (auto *ACE = baseLoc.dyn_cast()) { loc = ACE; kind = Kind::Func; - assert(ACE->getParamPatterns().size() >= 1 && + assert(ACE->getParameterLists().size() >= 1 && "no param patterns for function?!"); naturalUncurryLevel = getFuncNaturalUncurryLevel(ACE); } else { @@ -248,6 +327,11 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const { if (isThunk()) return SILLinkage::Shared; + // Enum constructors are essentially the same as thunks, they are + // emitted by need and have shared linkage. + if (kind == Kind::EnumElement) + return SILLinkage::Shared; + // Declarations imported from Clang modules have shared linkage. // FIXME: They shouldn't. const SILLinkage ClangLinkage = SILLinkage::Shared; @@ -333,8 +417,7 @@ bool SILDeclRef::isForeignToNativeThunk() const { // have a foreign-to-native thunk. if (!hasDecl()) return false; - // Otherwise, match whether we have a clang node with whether we're foreign. - if (isa(getDecl()) && getDecl()->hasClangNode()) + if (requiresForeignToNativeThunk(getDecl())) return !isForeign; // ObjC initializing constructors and factories are foreign. // We emit a special native allocating constructor though. @@ -368,10 +451,9 @@ static void mangleClangDecl(raw_ostream &buffer, importer->getMangledName(buffer, clangDecl); } -static void mangleConstant(SILDeclRef c, llvm::raw_ostream &buffer, - StringRef prefix) { +static std::string mangleConstant(SILDeclRef c, StringRef prefix) { using namespace Mangle; - Mangler mangler(buffer); + Mangler mangler; // Almost everything below gets one of the common prefixes: // mangled-name ::= '_T' global // Native symbol @@ -395,11 +477,11 @@ static void mangleConstant(SILDeclRef c, llvm::raw_ostream &buffer, // entity ::= declaration // other declaration case SILDeclRef::Kind::Func: if (!c.hasDecl()) { - buffer << introducer; + mangler.append(introducer); mangler.mangleClosureEntity(c.getAbstractClosureExpr(), c.getResilienceExpansion(), c.uncurryLevel); - return; + return mangler.finalize(); } // As a special case, functions can have external asm names. @@ -408,8 +490,8 @@ static void mangleConstant(SILDeclRef c, llvm::raw_ostream &buffer, if (auto AsmA = c.getDecl()->getAttrs().getAttribute()) if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk() && !c.isCurried) { - buffer << AsmA->Name; - return; + mangler.append(AsmA->Name); + return mangler.finalize(); } // Otherwise, fall through into the 'other decl' case. @@ -422,97 +504,97 @@ static void mangleConstant(SILDeclRef c, llvm::raw_ostream &buffer, && !c.isCurried) { if (auto namedClangDecl = dyn_cast(clangDecl)) { if (auto asmLabel = namedClangDecl->getAttr()) { - buffer << '\01' << asmLabel->getLabel(); + mangler.append('\01'); + mangler.append(asmLabel->getLabel()); } else if (namedClangDecl->hasAttr()) { + std::string storage; + llvm::raw_string_ostream SS(storage); // FIXME: When we can import C++, use Clang's mangler all the time. - mangleClangDecl(buffer, namedClangDecl, + mangleClangDecl(SS, namedClangDecl, c.getDecl()->getASTContext()); + mangler.append(SS.str()); } else { - buffer << namedClangDecl->getName(); + mangler.append(namedClangDecl->getName()); } - return; + return mangler.finalize(); } } } - buffer << introducer; + mangler.append(introducer); mangler.mangleEntity(c.getDecl(), c.getResilienceExpansion(), c.uncurryLevel); - return; - + return mangler.finalize(); + // entity ::= context 'D' // deallocating destructor case SILDeclRef::Kind::Deallocator: - buffer << introducer; + mangler.append(introducer); mangler.mangleDestructorEntity(cast(c.getDecl()), /*isDeallocating*/ true); - return; + return mangler.finalize(); // entity ::= context 'd' // destroying destructor case SILDeclRef::Kind::Destroyer: - buffer << introducer; + mangler.append(introducer); mangler.mangleDestructorEntity(cast(c.getDecl()), /*isDeallocating*/ false); - return; + return mangler.finalize(); // entity ::= context 'C' type // allocating constructor case SILDeclRef::Kind::Allocator: - buffer << introducer; + mangler.append(introducer); mangler.mangleConstructorEntity(cast(c.getDecl()), /*allocating*/ true, c.getResilienceExpansion(), c.uncurryLevel); - return; + return mangler.finalize(); // entity ::= context 'c' type // initializing constructor case SILDeclRef::Kind::Initializer: - buffer << introducer; + mangler.append(introducer); mangler.mangleConstructorEntity(cast(c.getDecl()), /*allocating*/ false, c.getResilienceExpansion(), c.uncurryLevel); - return; + return mangler.finalize(); // entity ::= declaration 'e' // ivar initializer // entity ::= declaration 'E' // ivar destroyer case SILDeclRef::Kind::IVarInitializer: case SILDeclRef::Kind::IVarDestroyer: - buffer << introducer; + mangler.append(introducer); mangler.mangleIVarInitDestroyEntity( cast(c.getDecl()), c.kind == SILDeclRef::Kind::IVarDestroyer); - return; + return mangler.finalize(); // entity ::= declaration 'a' // addressor case SILDeclRef::Kind::GlobalAccessor: - buffer << introducer; + mangler.append(introducer); mangler.mangleAddressorEntity(c.getDecl()); - return; + return mangler.finalize(); // entity ::= declaration 'G' // getter case SILDeclRef::Kind::GlobalGetter: - buffer << introducer; + mangler.append(introducer); mangler.mangleGlobalGetterEntity(c.getDecl()); - return; + return mangler.finalize(); // entity ::= context 'e' index // default arg generator case SILDeclRef::Kind::DefaultArgGenerator: - buffer << introducer; + mangler.append(introducer); mangler.mangleDefaultArgumentEntity(cast(c.getDecl()), c.defaultArgIndex); - return; + return mangler.finalize(); } llvm_unreachable("bad entity kind!"); } -StringRef SILDeclRef::mangle(SmallVectorImpl &buffer, - StringRef prefix) const { - assert(buffer.empty()); - llvm::raw_svector_ostream stream(buffer); - mangleConstant(*this, stream, prefix); - return stream.str(); -} +std::string SILDeclRef::mangle(StringRef prefix) const { + return mangleConstant(*this, prefix); + } -SILDeclRef SILDeclRef::getOverriddenVTableEntry() const { +SILDeclRef SILDeclRef::getNextOverriddenVTableEntry() const { if (auto overridden = getOverridden()) { // If we overrode a foreign decl, a dynamic method, this is an // accessor for a property that overrides an ObjC decl, or if it is an @@ -544,6 +626,19 @@ SILDeclRef SILDeclRef::getOverriddenVTableEntry() const { return SILDeclRef(); } +SILDeclRef SILDeclRef::getBaseOverriddenVTableEntry() const { + // 'method' is the most final method in the hierarchy which we + // haven't yet found a compatible override for. 'cur' is the method + // we're currently looking at. Compatibility is transitive, + // so we can forget our original method and just keep going up. + SILDeclRef method = *this; + SILDeclRef cur = method; + while ((cur = cur.getNextOverriddenVTableEntry())) { + method = cur; + } + return method; +} + SILLocation SILDeclRef::getAsRegularLocation() const { if (hasDecl()) return RegularLocation(getDecl()); diff --git a/lib/SIL/SILFunction.cpp b/lib/SIL/SILFunction.cpp index 2a5ed7b3fb074..30ad2ac650436 100644 --- a/lib/SIL/SILFunction.cpp +++ b/lib/SIL/SILFunction.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,7 +16,6 @@ #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/CFG.h" -#include "swift/SIL/SILModule.h" // FIXME: For mapTypeInContext #include "swift/AST/ArchetypeBuilder.h" #include "llvm/ADT/Optional.h" @@ -90,7 +89,7 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage, Linkage(unsigned(Linkage)), KeepAsPublic(false), ForeignBody(false), - EK(E) { + EffectsKindAttr(E) { if (InsertBefore) Module.functions.insert(SILModule::iterator(InsertBefore), this); else @@ -102,14 +101,29 @@ SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage, } SILFunction::~SILFunction() { -#ifndef NDEBUG // If the function is recursive, a function_ref inst inside of the function // will give the function a non-zero ref count triggering the assertion. Thus // we drop all instruction references before we erase. + // We also need to drop all references if instructions are allocated using + // an allocator that may recycle freed memory. dropAllReferences(); + + auto &M = getModule(); + for (auto &BB : *this) { + for (auto I = BB.begin(), E = BB.end(); I != E;) { + auto Inst = &*I; + ++I; + SILInstruction::destroy(Inst); + // TODO: It is only safe to directly deallocate an + // instruction if this BB is being removed in scope + // of destructing a SILFunction. + M.deallocateInst(Inst); + } + BB.InstList.clearAndLeakNodesUnsafely(); + } + assert(RefCount == 0 && "Function cannot be deleted while function_ref's still exist"); -#endif } void SILFunction::setDeclContext(Decl *D) { @@ -151,7 +165,7 @@ ASTContext &SILFunction::getASTContext() const { bool SILFunction::shouldOptimize() const { if (Module.getStage() == SILStage::Raw) return true; - return !hasSemanticsString("optimize.sil.never"); + return !hasSemanticsAttr("optimize.sil.never"); } Type SILFunction::mapTypeIntoContext(Type type) const { diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp index 1cdd51a4eea0f..3e3d0f04872b4 100644 --- a/lib/SIL/SILFunctionType.cpp +++ b/lib/SIL/SILFunctionType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -64,7 +64,7 @@ static CanType getKnownType(Optional &cacheSlot, ASTContext &C, } CanType t = *cacheSlot; - // It is possible that we won't find a briding type (e.g. String) when we're + // It is possible that we won't find a bridging type (e.g. String) when we're // parsing the stdlib itself. if (t) { DEBUG(llvm::dbgs() << "Bridging type " << moduleName << '.' << typeName @@ -122,6 +122,7 @@ enum class ConventionsKind : uint8_t { CFunction = 4, SelectorFamily = 5, Deallocator = 6, + Capture = 7, }; class Conventions { @@ -427,7 +428,8 @@ static CanSILFunctionType getSILFunctionType(SILModule &M, CanAnyFunctionType substFnInterfaceType, AnyFunctionType::ExtInfo extInfo, const Conventions &conventions, - const Optional &foreignError) { + const Optional &foreignError, + Optional constant) { SmallVector inputs; // Per above, only fully honor opaqueness in the abstraction pattern @@ -561,7 +563,67 @@ static CanSILFunctionType getSILFunctionType(SILModule &M, substFnInterfaceType.getInput(), extInfo); } - + + // Lower the capture context parameters, if any. + if (constant) + if (auto function = constant->getAnyFunctionRef()) { + auto &Types = M.Types; + auto loweredCaptures = Types.getLoweredLocalCaptures(*function); + + for (auto capture : loweredCaptures.getCaptures()) { + auto *VD = capture.getDecl(); + auto type = VD->getType()->getCanonicalType(); + + type = Types.getInterfaceTypeOutOfContext(type, + function->getAsDeclContext()); + + auto &loweredTL = Types.getTypeLowering( + AbstractionPattern(genericSig, type), type); + auto loweredTy = loweredTL.getLoweredType(); + switch (Types.getDeclCaptureKind(capture)) { + case CaptureKind::None: + break; + case CaptureKind::Constant: { + // Constants are captured by value. + ParameterConvention convention; + if (loweredTL.isAddressOnly()) { + convention = M.getOptions().EnableGuaranteedClosureContexts + ? ParameterConvention::Indirect_In_Guaranteed + : ParameterConvention::Indirect_In; + } else if (loweredTL.isTrivial()) { + convention = ParameterConvention::Direct_Unowned; + } else { + convention = M.getOptions().EnableGuaranteedClosureContexts + ? ParameterConvention::Direct_Guaranteed + : ParameterConvention::Direct_Owned; + } + SILParameterInfo param(loweredTy.getSwiftRValueType(), convention); + inputs.push_back(param); + break; + } + case CaptureKind::Box: { + // Lvalues are captured as a box that owns the captured value. + SILType ty = loweredTy.getAddressType(); + CanType boxTy = SILBoxType::get(ty.getSwiftRValueType()); + auto convention = M.getOptions().EnableGuaranteedClosureContexts + ? ParameterConvention::Direct_Guaranteed + : ParameterConvention::Direct_Owned; + auto param = SILParameterInfo(boxTy, convention); + inputs.push_back(param); + break; + } + case CaptureKind::StorageAddress: { + // Non-escaping lvalues are captured as the address of the value. + SILType ty = loweredTy.getAddressType(); + auto param = SILParameterInfo(ty.getSwiftRValueType(), + ParameterConvention::Indirect_InoutAliasable); + inputs.push_back(param); + break; + } + } + } + } + auto calleeConvention = ParameterConvention::Direct_Unowned; if (extInfo.hasContext()) calleeConvention = conventions.getCallee(); @@ -727,17 +789,19 @@ namespace { } static CanSILFunctionType getNativeSILFunctionType(SILModule &M, - AbstractionPattern origType, - CanAnyFunctionType substType, - CanAnyFunctionType substInterfaceType, - AnyFunctionType::ExtInfo extInfo, - SILDeclRef::Kind kind) { + AbstractionPattern origType, + CanAnyFunctionType substType, + CanAnyFunctionType substInterfaceType, + AnyFunctionType::ExtInfo extInfo, + Optional constant, + SILDeclRef::Kind kind) { switch (extInfo.getSILRepresentation()) { case SILFunctionType::Representation::Block: case SILFunctionType::Representation::CFunctionPointer: + // TODO: Ought to support captures in block funcs. return getSILFunctionType(M, origType, substType, substInterfaceType, extInfo, DefaultBlockConventions(), - None); + None, constant); case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::ObjCMethod: @@ -748,7 +812,7 @@ static CanSILFunctionType getNativeSILFunctionType(SILModule &M, case SILDeclRef::Kind::Initializer: return getSILFunctionType(M, origType, substType, substInterfaceType, extInfo, DefaultInitializerConventions(), - None); + None, constant); case SILDeclRef::Kind::Func: case SILDeclRef::Kind::Allocator: @@ -761,10 +825,11 @@ static CanSILFunctionType getNativeSILFunctionType(SILModule &M, case SILDeclRef::Kind::EnumElement: return getSILFunctionType(M, origType, substType, substInterfaceType, extInfo, DefaultConventions(), - None); + None, constant); case SILDeclRef::Kind::Deallocator: return getSILFunctionType(M, origType, substType, substInterfaceType, - extInfo, DeallocatorConventions(), None); + extInfo, DeallocatorConventions(), None, + constant); } } } @@ -786,7 +851,7 @@ CanSILFunctionType swift::getNativeSILFunctionType(SILModule &M, extInfo = substType->getExtInfo(); } return ::getNativeSILFunctionType(M, origType, substType, substInterfaceType, - extInfo, kind); + extInfo, None, kind); } //===----------------------------------------------------------------------===// @@ -1098,7 +1163,7 @@ getSILFunctionTypeForClangDecl(SILModule &M, const clang::Decl *clangDecl, AbstractionPattern::getObjCMethod(origType, method, foreignError); return getSILFunctionType(M, origPattern, substType, substInterfaceType, extInfo, ObjCMethodConventions(method), - foreignError); + foreignError, None); } if (auto func = dyn_cast(clangDecl)) { @@ -1106,7 +1171,7 @@ getSILFunctionTypeForClangDecl(SILModule &M, const clang::Decl *clangDecl, func->getType().getTypePtr()); return getSILFunctionType(M, origPattern, substType, substInterfaceType, extInfo, CFunctionConventions(func), - foreignError); + foreignError, None); } llvm_unreachable("call to unknown kind of C function"); @@ -1294,7 +1359,7 @@ getSILFunctionTypeForSelectorFamily(SILModule &M, SelectorFamily family, substType, substInterfaceType, extInfo, SelectorFamilyConventions(family), - foreignError); + foreignError, None); } static CanSILFunctionType @@ -1331,10 +1396,11 @@ getUncachedSILFunctionTypeForConstant(SILModule &M, SILDeclRef constant, if (!constant.isForeign) { return getNativeSILFunctionType(M, AbstractionPattern(origLoweredType), - substLoweredType, - substLoweredInterfaceType, - extInfo, - constant.kind); + substLoweredType, + substLoweredInterfaceType, + extInfo, + constant, + constant.kind); } Optional foreignError; @@ -1625,6 +1691,7 @@ namespace { case ParameterConvention::Direct_Deallocating: case ParameterConvention::Direct_Unowned: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_In_Guaranteed: return orig; @@ -1732,7 +1799,7 @@ SILConstantInfo TypeConverter::getConstantOverrideInfo(SILDeclRef derived, if (found != ConstantOverrideTypes.end()) return found->second; - assert(base.getOverriddenVTableEntry().isNull() + assert(base.getNextOverriddenVTableEntry().isNull() && "base must not be an override"); auto baseInfo = getConstantInfo(base); diff --git a/lib/SIL/SILGlobalVariable.cpp b/lib/SIL/SILGlobalVariable.cpp index 9d05362978776..6f445cdba1894 100644 --- a/lib/SIL/SILGlobalVariable.cpp +++ b/lib/SIL/SILGlobalVariable.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SIL/SILInstruction.cpp b/lib/SIL/SILInstruction.cpp index 560b13dd7030b..77d49531c7c72 100644 --- a/lib/SIL/SILInstruction.cpp +++ b/lib/SIL/SILInstruction.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -88,7 +88,7 @@ void llvm::ilist_traits:: transferNodesFromList(llvm::ilist_traits &L2, llvm::ilist_iterator first, llvm::ilist_iterator last) { - // If transfering instructions within the same basic block, no reason to + // If transferring instructions within the same basic block, no reason to // update their parent pointers. SILBasicBlock *ThisParent = getContainingBlock(); if (ThisParent == L2.getContainingBlock()) return; @@ -160,7 +160,7 @@ void SILInstruction::dropAllReferences() { } // If we have a function ref inst, we need to especially drop its function - // argument so that it gets a proper ref decement. + // argument so that it gets a proper ref decrement. auto *FRI = dyn_cast(this); if (!FRI || !FRI->getReferencedFunction()) return; @@ -806,6 +806,16 @@ bool SILInstruction::mayRelease() const { } } +bool SILInstruction::mayReleaseOrReadRefCount() const { + switch (getKind()) { + case ValueKind::IsUniqueInst: + case ValueKind::IsUniqueOrPinnedInst: + return true; + default: + return mayRelease(); + } +} + namespace { class TrivialCloner : public SILCloner { friend class SILCloner; diff --git a/lib/SIL/SILInstructions.cpp b/lib/SIL/SILInstructions.cpp index 6bc4003e20d48..6a75bb74a9180 100644 --- a/lib/SIL/SILInstructions.cpp +++ b/lib/SIL/SILInstructions.cpp @@ -1,8 +1,8 @@ -//===--- SILInstruction.cpp - Instructions for SIL code -------------------===// +//===--- SILInstructions.cpp - Instructions for SIL code ------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -35,20 +35,36 @@ using namespace Lowering; // SILInstruction Subclasses //===----------------------------------------------------------------------===// -// alloc_stack always returns two results: Builtin.RawPointer & LValue[EltTy] -static SILTypeList *getAllocStackType(SILType eltTy, SILFunction &F) { - SILType resTys[] = { - eltTy.getLocalStorageType(), - eltTy.getAddressType() - }; +template +static void *allocateDebugVarCarryingInst(SILModule &M, SILDebugVariable Var) { + return M.allocateInst(sizeof(INST) + Var.Name.size(), alignof(INST)); +} - return F.getModule().getSILTypeList(resTys); +TailAllocatedDebugVariable::TailAllocatedDebugVariable(SILDebugVariable Var, + char *buf) + : ArgNo(Var.ArgNo), NameLength(Var.Name.size()), Constant(Var.Constant) { + assert((Var.ArgNo < (2<<16)) && "too many arguments"); + assert((NameLength < (2<<15)) && "variable name too long"); + memcpy(buf, Var.Name.data(), NameLength); +} + +StringRef TailAllocatedDebugVariable::getName(const char *buf) const { + return NameLength ? StringRef(buf, NameLength) : StringRef(); } AllocStackInst::AllocStackInst(SILDebugLocation *Loc, SILType elementType, - SILFunction &F, unsigned ArgNo) + SILFunction &F, SILDebugVariable Var) : AllocationInst(ValueKind::AllocStackInst, Loc, - getAllocStackType(elementType, F)), VarInfo(ArgNo) {} + elementType.getAddressType()), + VarInfo(Var, reinterpret_cast(this + 1)) {} + +AllocStackInst *AllocStackInst::create(SILDebugLocation *Loc, + SILType elementType, SILFunction &F, + SILDebugVariable Var) { + void *buf = allocateDebugVarCarryingInst(F.getModule(), Var); + return ::new (buf) + AllocStackInst(Loc, elementType, F, Var); +} /// getDecl - Return the underlying variable declaration associated with this /// allocation, or null if this is a temporary allocation. @@ -75,10 +91,16 @@ static SILTypeList *getAllocBoxType(SILType EltTy, SILFunction &F) { } AllocBoxInst::AllocBoxInst(SILDebugLocation *Loc, SILType ElementType, - SILFunction &F, unsigned ArgNo) + SILFunction &F, SILDebugVariable Var) : AllocationInst(ValueKind::AllocBoxInst, Loc, getAllocBoxType(ElementType, F)), - VarInfo(ArgNo) {} + VarInfo(Var, reinterpret_cast(this + 1)) {} + +AllocBoxInst *AllocBoxInst::create(SILDebugLocation *Loc, SILType ElementType, + SILFunction &F, SILDebugVariable Var) { + void *buf = allocateDebugVarCarryingInst(F.getModule(), Var); + return ::new (buf) AllocBoxInst(Loc, ElementType, F, Var); +} /// getDecl - Return the underlying variable declaration associated with this /// allocation, or null if this is a temporary allocation. @@ -86,6 +108,30 @@ VarDecl *AllocBoxInst::getDecl() const { return getLoc().getAsASTNode(); } +DebugValueInst::DebugValueInst(SILDebugLocation *DebugLoc, SILValue Operand, + SILDebugVariable Var) + : UnaryInstructionBase(DebugLoc, Operand), + VarInfo(Var, reinterpret_cast(this + 1)) {} + +DebugValueInst *DebugValueInst::create(SILDebugLocation *DebugLoc, + SILValue Operand, SILModule &M, + SILDebugVariable Var) { + void *buf = allocateDebugVarCarryingInst(M, Var); + return ::new (buf) DebugValueInst(DebugLoc, Operand, Var); +} + +DebugValueAddrInst::DebugValueAddrInst(SILDebugLocation *DebugLoc, + SILValue Operand, SILDebugVariable Var) + : UnaryInstructionBase(DebugLoc, Operand), + VarInfo(Var, reinterpret_cast(this + 1)) {} + +DebugValueAddrInst *DebugValueAddrInst::create(SILDebugLocation *DebugLoc, + SILValue Operand, SILModule &M, + SILDebugVariable Var) { + void *buf = allocateDebugVarCarryingInst(M, Var); + return ::new (buf) DebugValueAddrInst(DebugLoc, Operand, Var); +} + VarDecl *DebugValueInst::getDecl() const { return getLoc().getAsASTNode(); } @@ -127,8 +173,8 @@ AllocExistentialBoxInst *AllocExistentialBoxInst::create( SILType ConcreteLoweredType, ArrayRef Conformances, SILFunction *F) { SILModule &Mod = F->getModule(); - void *Buffer = Mod.allocate(sizeof(AllocExistentialBoxInst), - alignof(AllocExistentialBoxInst)); + void *Buffer = Mod.allocateInst(sizeof(AllocExistentialBoxInst), + alignof(AllocExistentialBoxInst)); for (ProtocolConformance *C : Conformances) declareWitnessTable(Mod, C); return ::new (Buffer) AllocExistentialBoxInst(Loc, @@ -143,7 +189,7 @@ BuiltinInst *BuiltinInst::create(SILDebugLocation *Loc, Identifier Name, ArrayRef Substitutions, ArrayRef Args, SILFunction &F) { - void *Buffer = F.getModule().allocate( + void *Buffer = F.getModule().allocateInst( sizeof(BuiltinInst) + decltype(Operands)::getExtraSize(Args.size()) + sizeof(Substitution) * Substitutions.size(), @@ -185,12 +231,12 @@ ApplyInst *ApplyInst::create(SILDebugLocation *Loc, SILValue Callee, bool swift::doesApplyCalleeHaveSemantics(SILValue callee, StringRef semantics) { if (auto *FRI = dyn_cast(callee)) if (auto *F = FRI->getReferencedFunction()) - return F->hasSemanticsString(semantics); + return F->hasSemanticsAttr(semantics); return false; } void *swift::allocateApplyInst(SILFunction &F, size_t size, size_t alignment) { - return F.getModule().allocate(size, alignment); + return F.getModule().allocateInst(size, alignment); } PartialApplyInst::PartialApplyInst(SILDebugLocation *Loc, SILValue Callee, @@ -276,14 +322,14 @@ static unsigned getWordsForBitWidth(unsigned bits) { template static void *allocateLiteralInstWithTextSize(SILFunction &F, unsigned length) { - return F.getModule().allocate(sizeof(INST) + length, alignof(INST)); + return F.getModule().allocateInst(sizeof(INST) + length, alignof(INST)); } template static void *allocateLiteralInstWithBitSize(SILFunction &F, unsigned bits) { unsigned words = getWordsForBitWidth(bits); - return F.getModule().allocate(sizeof(INST) + sizeof(llvm::integerPart)*words, - alignof(INST)); + return F.getModule().allocateInst( + sizeof(INST) + sizeof(llvm::integerPart)*words, alignof(INST)); } IntegerLiteralInst::IntegerLiteralInst(SILDebugLocation *Loc, SILType Ty, @@ -409,7 +455,7 @@ AssignInst::AssignInst(SILDebugLocation *Loc, SILValue Src, SILValue Dest) MarkFunctionEscapeInst * MarkFunctionEscapeInst::create(SILDebugLocation *Loc, ArrayRef Elements, SILFunction &F) { - void *Buffer = F.getModule().allocate(sizeof(MarkFunctionEscapeInst) + + void *Buffer = F.getModule().allocateInst(sizeof(MarkFunctionEscapeInst) + decltype(Operands)::getExtraSize(Elements.size()), alignof(MarkFunctionEscapeInst)); return ::new(Buffer) MarkFunctionEscapeInst(Loc, Elements); @@ -428,11 +474,6 @@ static SILType getPinResultType(SILType operandType) { StrongPinInst::StrongPinInst(SILDebugLocation *Loc, SILValue operand) : UnaryInstructionBase(Loc, operand, getPinResultType(operand.getType())) {} -StoreWeakInst::StoreWeakInst(SILDebugLocation *Loc, SILValue value, - SILValue dest, IsInitialization_t isInit) - : SILInstruction(ValueKind::StoreWeakInst, Loc), - Operands(this, value, dest), IsInitializationOfDest(isInit) {} - CopyAddrInst::CopyAddrInst(SILDebugLocation *Loc, SILValue SrcLValue, SILValue DestLValue, IsTake_t isTakeOfSrc, IsInitialization_t isInitializationOfDest) @@ -457,7 +498,7 @@ UnconditionalCheckedCastAddrInst::UnconditionalCheckedCastAddrInst( StructInst *StructInst::create(SILDebugLocation *Loc, SILType Ty, ArrayRef Elements, SILFunction &F) { - void *Buffer = F.getModule().allocate(sizeof(StructInst) + + void *Buffer = F.getModule().allocateInst(sizeof(StructInst) + decltype(Operands)::getExtraSize(Elements.size()), alignof(StructInst)); return ::new(Buffer) StructInst(Loc, Ty, Elements); @@ -471,7 +512,7 @@ StructInst::StructInst(SILDebugLocation *Loc, SILType Ty, TupleInst *TupleInst::create(SILDebugLocation *Loc, SILType Ty, ArrayRef Elements, SILFunction &F) { - void *Buffer = F.getModule().allocate(sizeof(TupleInst) + + void *Buffer = F.getModule().allocateInst(sizeof(TupleInst) + decltype(Operands)::getExtraSize(Elements.size()), alignof(TupleInst)); return ::new(Buffer) TupleInst(Loc, Ty, Elements); @@ -491,7 +532,7 @@ bool TupleExtractInst::isTrivialEltOfOneRCIDTuple() const { if (!getType().isTrivial(Mod)) return false; - // If the elt we are extracting is trivial, we can not have any non trivial + // If the elt we are extracting is trivial, we cannot have any non trivial // fields. if (getOperand().getType().isTrivial(Mod)) return false; @@ -534,7 +575,7 @@ bool TupleExtractInst::isTrivialEltOfOneRCIDTuple() const { bool TupleExtractInst::isEltOnlyNonTrivialElt() const { SILModule &Mod = getModule(); - // If the elt we are extracting is trivial, we can not be a non-trivial + // If the elt we are extracting is trivial, we cannot be a non-trivial // field... return false. if (getType().isTrivial(Mod)) return false; @@ -574,7 +615,7 @@ bool StructExtractInst::isTrivialFieldOfOneRCIDStruct() const { SILType StructTy = getOperand().getType(); - // If the elt we are extracting is trivial, we can not have any non trivial + // If the elt we are extracting is trivial, we cannot have any non trivial // fields. if (StructTy.isTrivial(Mod)) return false; @@ -618,7 +659,7 @@ bool StructExtractInst::isTrivialFieldOfOneRCIDStruct() const { bool StructExtractInst::isFieldOnlyNonTrivialField() const { SILModule &Mod = getModule(); - // If the field we are extracting is trivial, we can not be a non-trivial + // If the field we are extracting is trivial, we cannot be a non-trivial // field... return false. if (getType().isTrivial(Mod)) return false; @@ -674,7 +715,7 @@ BranchInst *BranchInst::create(SILDebugLocation *Loc, SILBasicBlock *DestBB, BranchInst *BranchInst::create(SILDebugLocation *Loc, SILBasicBlock *DestBB, ArrayRef Args, SILFunction &F) { - void *Buffer = F.getModule().allocate(sizeof(BranchInst) + + void *Buffer = F.getModule().allocateInst(sizeof(BranchInst) + decltype(Operands)::getExtraSize(Args.size()), alignof(BranchInst)); return ::new (Buffer) BranchInst(Loc, DestBB, Args); @@ -708,7 +749,7 @@ CondBranchInst::create(SILDebugLocation *Loc, SILValue Condition, Args.append(TrueArgs.begin(), TrueArgs.end()); Args.append(FalseArgs.begin(), FalseArgs.end()); - void *Buffer = F.getModule().allocate(sizeof(CondBranchInst) + + void *Buffer = F.getModule().allocateInst(sizeof(CondBranchInst) + decltype(Operands)::getExtraSize(Args.size()), alignof(CondBranchInst)); return ::new (Buffer) CondBranchInst(Loc, Condition, TrueBB, FalseBB, Args, @@ -725,7 +766,7 @@ OperandValueArrayRef CondBranchInst::getFalseArgs() const { SILValue CondBranchInst::getArgForDestBB(SILBasicBlock *DestBB, SILArgument *A) { - // If TrueBB and FalseBB equal, we can not find an arg for this DestBB so + // If TrueBB and FalseBB equal, we cannot find an arg for this DestBB so // return an empty SILValue. if (getTrueBB() == getFalseBB()) { assert(DestBB == getTrueBB() && "DestBB is not a target of this cond_br"); @@ -811,6 +852,12 @@ SwitchValueInst::SwitchValueInst(SILDebugLocation *Loc, SILValue Operand, } for (unsigned i = 0, size = Cases.size(); i < size; ++i) { + // If we have undef, just add the case and continue. + if (isa(Cases[i])) { + ::new (succs + i) SILSuccessor(this, BBs[i]); + continue; + } + if (OperandBitWidth) { auto *IL = dyn_cast(Cases[i]); assert(IL && "switch_value case value should be of an integer type"); @@ -858,7 +905,7 @@ SwitchValueInst *SwitchValueInst::create( size_t bufSize = sizeof(SwitchValueInst) + decltype(Operands)::getExtraSize(Cases.size()) + sizeof(SILSuccessor) * numSuccessors; - void *buf = F.getModule().allocate(bufSize, alignof(SwitchValueInst)); + void *buf = F.getModule().allocateInst(bufSize, alignof(SwitchValueInst)); return ::new (buf) SwitchValueInst(Loc, Operand, DefaultBB, Cases, BBs); } @@ -894,7 +941,7 @@ SelectValueInst::create(SILDebugLocation *Loc, SILValue Operand, SILType Type, SILFunction &F) { // Allocate enough room for the instruction with tail-allocated data for all // the case values and the SILSuccessor arrays. There are `CaseBBs.size()` - // SILValuues and `CaseBBs.size() + (DefaultBB ? 1 : 0)` successors. + // SILValues and `CaseBBs.size() + (DefaultBB ? 1 : 0)` successors. SmallVector CaseValuesAndResults; for (auto pair : CaseValues) { CaseValuesAndResults.push_back(pair.first); @@ -906,7 +953,7 @@ SelectValueInst::create(SILDebugLocation *Loc, SILValue Operand, SILType Type, size_t bufSize = sizeof(SelectValueInst) + decltype(Operands)::getExtraSize( CaseValuesAndResults.size()); - void *buf = F.getModule().allocate(bufSize, alignof(SelectValueInst)); + void *buf = F.getModule().allocateInst(bufSize, alignof(SelectValueInst)); return ::new (buf) SelectValueInst(Loc, Operand, Type, DefaultResult, CaseValuesAndResults); } @@ -947,7 +994,7 @@ SELECT_ENUM_INST *SelectEnumInstBase::createSelectEnum( // and `CaseBBs.size() + (DefaultBB ? 1 : 0)` values. unsigned numCases = CaseValues.size(); - void *buf = F.getModule().allocate( + void *buf = F.getModule().allocateInst( sizeof(SELECT_ENUM_INST) + sizeof(EnumElementDecl*) * numCases + TailAllocatedOperandList<1>::getExtraSize(numCases + (bool)DefaultValue), alignof(SELECT_ENUM_INST)); @@ -1068,7 +1115,7 @@ SWITCH_ENUM_INST *SwitchEnumInstBase::createSwitchEnum( unsigned numCases = CaseBBs.size(); unsigned numSuccessors = numCases + (DefaultBB ? 1 : 0); - void *buf = F.getModule().allocate(sizeof(SWITCH_ENUM_INST) + void *buf = F.getModule().allocateInst(sizeof(SWITCH_ENUM_INST) + sizeof(EnumElementDecl*) * numCases + sizeof(SILSuccessor) * numSuccessors, alignof(SWITCH_ENUM_INST)); @@ -1134,8 +1181,8 @@ DynamicMethodBranchInst * DynamicMethodBranchInst::create(SILDebugLocation *Loc, SILValue Operand, SILDeclRef Member, SILBasicBlock *HasMethodBB, SILBasicBlock *NoMethodBB, SILFunction &F) { - void *Buffer = F.getModule().allocate(sizeof(DynamicMethodBranchInst), - alignof(DynamicMethodBranchInst)); + void *Buffer = F.getModule().allocateInst(sizeof(DynamicMethodBranchInst), + alignof(DynamicMethodBranchInst)); return ::new (Buffer) DynamicMethodBranchInst(Loc, Operand, Member, HasMethodBB, NoMethodBB); } @@ -1177,7 +1224,7 @@ WitnessMethodInst::create(SILDebugLocation *Loc, CanType LookupType, SILValue OpenedExistential, bool Volatile) { SILModule &Mod = F->getModule(); void *Buffer = - Mod.allocate(sizeof(WitnessMethodInst), alignof(WitnessMethodInst)); + Mod.allocateInst(sizeof(WitnessMethodInst), alignof(WitnessMethodInst)); declareWitnessTable(Mod, Conformance); return ::new (Buffer) WitnessMethodInst(Loc, LookupType, Conformance, Member, @@ -1189,8 +1236,8 @@ InitExistentialAddrInst *InitExistentialAddrInst::create( SILType ConcreteLoweredType, ArrayRef Conformances, SILFunction *F) { SILModule &Mod = F->getModule(); - void *Buffer = Mod.allocate(sizeof(InitExistentialAddrInst), - alignof(InitExistentialAddrInst)); + void *Buffer = Mod.allocateInst(sizeof(InitExistentialAddrInst), + alignof(InitExistentialAddrInst)); for (ProtocolConformance *C : Conformances) declareWitnessTable(Mod, C); return ::new (Buffer) InitExistentialAddrInst(Loc, Existential, @@ -1205,8 +1252,8 @@ InitExistentialRefInst::create(SILDebugLocation *Loc, SILType ExistentialType, ArrayRef Conformances, SILFunction *F) { SILModule &Mod = F->getModule(); - void *Buffer = Mod.allocate(sizeof(InitExistentialRefInst), - alignof(InitExistentialRefInst)); + void *Buffer = Mod.allocateInst(sizeof(InitExistentialRefInst), + alignof(InitExistentialRefInst)); for (ProtocolConformance *C : Conformances) { if (!C) continue; @@ -1240,7 +1287,7 @@ InitExistentialMetatypeInst *InitExistentialMetatypeInst::create( unsigned size = sizeof(InitExistentialMetatypeInst); size += conformances.size() * sizeof(ProtocolConformance *); - void *buffer = M.allocate(size, alignof(InitExistentialMetatypeInst)); + void *buffer = M.allocateInst(size, alignof(InitExistentialMetatypeInst)); for (ProtocolConformance *conformance : conformances) if (!M.lookUpWitnessTable(conformance, false).first) declareWitnessTable(M, conformance); diff --git a/lib/SIL/SILLocation.cpp b/lib/SIL/SILLocation.cpp index d0539d9ef9448..043c49d8434e1 100644 --- a/lib/SIL/SILLocation.cpp +++ b/lib/SIL/SILLocation.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp index ab0a535ed18ec..d67d4d1936f5a 100644 --- a/lib/SIL/SILModule.cpp +++ b/lib/SIL/SILModule.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -14,7 +14,6 @@ #include "swift/SIL/SILModule.h" #include "Linker.h" #include "swift/SIL/SILDebugScope.h" -#include "swift/SIL/SILExternalSource.h" #include "swift/SIL/SILVisitor.h" #include "swift/Serialization/SerializedSILLoader.h" #include "swift/SIL/SILValue.h" @@ -44,9 +43,6 @@ namespace swift { }; } // end namespace swift. -void SILExternalSource::anchor() { -} - /// SILTypeListUniquingType - This is the type of the folding set maintained by /// SILModule that these things are uniqued into. typedef llvm::FoldingSet SILTypeListUniquingType; @@ -124,11 +120,26 @@ SILModule::~SILModule() { delete (SILTypeListUniquingType*)TypeListUniquing; } +void *SILModule::allocate(unsigned Size, unsigned Align) const { + if (getASTContext().LangOpts.UseMalloc) + return AlignedAlloc(Size, Align); + + return BPA.Allocate(Size, Align); +} + +void *SILModule::allocateInst(unsigned Size, unsigned Align) const { + return AlignedAlloc(Size, Align); +} + +void SILModule::deallocateInst(SILInstruction *I) { + AlignedFree(I); +} + SILWitnessTable * SILModule::createWitnessTableDeclaration(ProtocolConformance *C, SILLinkage linkage) { // If we are passed in a null conformance (a valid value), just return nullptr - // since we can not map a witness table to it. + // since we cannot map a witness table to it. if (!C) return nullptr; @@ -247,7 +258,7 @@ static SILFunction::ClassVisibility_t getClassVisibility(SILDeclRef constant) { if (!constant.hasDecl()) return SILFunction::NotRelevant; - // If this decleration is a function which goes into a vtable, then it's + // If this declaration is a function which goes into a vtable, then it's // symbol must be as visible as its class. Derived classes even have to put // all less visible methods of the base class into their vtables. @@ -306,15 +317,14 @@ static bool verifySILSelfParameterType(SILDeclRef DeclRef, // Otherwise, if this function type has a guaranteed self parameter type, // make sure that we have a +0 self param. return !FTy->getExtInfo().hasGuaranteedSelfParam() || - PInfo.isGuaranteed() || PInfo.isIndirectInOut(); + PInfo.isGuaranteed() || PInfo.isIndirectMutating(); } SILFunction *SILModule::getOrCreateFunction(SILLocation loc, SILDeclRef constant, ForDefinition_t forDefinition) { - SmallVector buffer; - auto name = constant.mangle(buffer); + auto name = constant.mangle(); auto constantType = Types.getConstantType(constant).castTo(); SILLinkage linkage = constant.getLinkage(forDefinition); @@ -363,15 +373,15 @@ SILFunction *SILModule::getOrCreateFunction(SILLocation loc, if (constant.isForeign && constant.isClangGenerated()) F->setForeignBody(HasForeignBody); - if (auto SemanticsA = - constant.getDecl()->getAttrs().getAttribute()) - F->setSemanticsAttr(SemanticsA->Value); + auto Attrs = constant.getDecl()->getAttrs(); + for (auto A : Attrs.getAttributes()) + F->addSemanticsAttr(cast(A)->Value); } F->setDeclContext(constant.hasDecl() ? constant.getDecl() : nullptr); // If this function has a self parameter, make sure that it has a +0 calling - // convention. This can not be done for general function types, since + // convention. This cannot be done for general function types, since // function_ref's SILFunctionTypes do not have archetypes associated with // it. CanSILFunctionType FTy = F->getLoweredFunctionType(); @@ -398,6 +408,19 @@ SILFunction *SILModule::getOrCreateSharedFunction(SILLocation loc, isThunk, SILFunction::NotRelevant); } +SILFunction *SILModule::getOrCreateFunction( + SILLinkage linkage, StringRef name, CanSILFunctionType loweredType, + GenericParamList *contextGenericParams, Optional loc, + IsBare_t isBareSILFunction, IsTransparent_t isTrans, IsFragile_t isFragile, + IsThunk_t isThunk, SILFunction::ClassVisibility_t classVisibility, + Inline_t inlineStrategy, EffectsKind EK, SILFunction *InsertBefore, + const SILDebugScope *DebugScope, DeclContext *DC) { + return SILFunction::create(*this, linkage, name, loweredType, + contextGenericParams, loc, isBareSILFunction, + isTrans, isFragile, isThunk, classVisibility, + inlineStrategy, EK, InsertBefore, DebugScope, DC); +} + ArrayRef ValueBase::getTypes() const { // No results. if (TypeOrTypeList.isNull()) @@ -493,27 +516,20 @@ const BuiltinInfo &SILModule::getBuiltinInfo(Identifier ID) { } SILFunction *SILModule::lookUpFunction(SILDeclRef fnRef) { - llvm::SmallString<32> name; - fnRef.mangle(name); + auto name = fnRef.mangle(); return lookUpFunction(name); } -bool SILModule::linkFunction(SILFunction *Fun, SILModule::LinkingMode Mode, - std::function Callback) { - return SILLinkerVisitor(*this, getSILLoader(), Mode, - ExternalSource, Callback).processFunction(Fun); +bool SILModule::linkFunction(SILFunction *Fun, SILModule::LinkingMode Mode) { + return SILLinkerVisitor(*this, getSILLoader(), Mode).processFunction(Fun); } -bool SILModule::linkFunction(SILDeclRef Decl, SILModule::LinkingMode Mode, - std::function Callback) { - return SILLinkerVisitor(*this, getSILLoader(), Mode, - ExternalSource, Callback).processDeclRef(Decl); +bool SILModule::linkFunction(SILDeclRef Decl, SILModule::LinkingMode Mode) { + return SILLinkerVisitor(*this, getSILLoader(), Mode).processDeclRef(Decl); } -bool SILModule::linkFunction(StringRef Name, SILModule::LinkingMode Mode, - std::function Callback) { - return SILLinkerVisitor(*this, getSILLoader(), Mode, - ExternalSource, Callback).processFunction(Name); +bool SILModule::linkFunction(StringRef Name, SILModule::LinkingMode Mode) { + return SILLinkerVisitor(*this, getSILLoader(), Mode).processFunction(Name); } void SILModule::linkAllWitnessTables() { @@ -562,8 +578,7 @@ void SILModule::eraseGlobalVariable(SILGlobalVariable *G) { getSILGlobalList().erase(G); } -SILVTable *SILModule::lookUpVTable(const ClassDecl *C, - std::function Callback) { +SILVTable *SILModule::lookUpVTable(const ClassDecl *C) { if (!C) return nullptr; @@ -573,10 +588,9 @@ SILVTable *SILModule::lookUpVTable(const ClassDecl *C, return R->second; // If that fails, try to deserialize it. If that fails, return nullptr. - SILVTable *Vtbl = SILLinkerVisitor(*this, getSILLoader(), - SILModule::LinkingMode::LinkAll, - ExternalSource, - Callback).processClassDecl(C); + SILVTable *Vtbl = + SILLinkerVisitor(*this, getSILLoader(), SILModule::LinkingMode::LinkAll) + .processClassDecl(C); if (!Vtbl) return nullptr; @@ -664,3 +678,24 @@ lookUpFunctionInVTable(ClassDecl *Class, SILDeclRef Member) { return nullptr; } + + +void SILModule:: +registerDeleteNotificationHandler(DeleteNotificationHandler* Handler) { + // Ask the handler (that can be an analysis, a pass, or some other data + // structure) if it wants to receive delete notifications. + if (Handler->needsNotifications()) { + NotificationHandlers.insert(Handler); + } +} + +void SILModule:: +removeDeleteNotificationHandler(DeleteNotificationHandler* Handler) { + NotificationHandlers.remove(Handler); +} + +void SILModule::notifyDeleteHandlers(ValueBase *V) { + for (auto *Handler : NotificationHandlers) { + Handler->handleDeleteNotification(V); + } +} diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp index 1ac94cd1fe9b6..3bd60fafa080f 100644 --- a/lib/SIL/SILPrinter.cpp +++ b/lib/SIL/SILPrinter.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -212,6 +212,10 @@ static void printFullContext(const DeclContext *Context, raw_ostream &Buffer) { // FIXME Buffer << ""; return; + case DeclContextKind::SubscriptDecl: + // FIXME + Buffer << ""; + return; } llvm_unreachable("bad decl context"); } @@ -330,7 +334,6 @@ static void print(raw_ostream &OS, SILValueCategory category) { switch (category) { case SILValueCategory::Object: return; case SILValueCategory::Address: OS << '*'; return; - case SILValueCategory::LocalStorage: OS << "*@local_storage "; return; } llvm_unreachable("bad value category!"); } @@ -519,18 +522,126 @@ class SILPrinter : public SILVisitor { //===--------------------------------------------------------------------===// // SILInstruction Printing Logic + /// Print out the users of the SILValue \p V. Return true if we printed out + /// either an id or a use list. Return false otherwise. + bool printUsersOfSILValue(SILValue V) { + if (!V->hasValue()) { + PrintState.OS.PadToColumn(50); + *this << "// id: " << getID(V); + return true; + } + + if (V->use_empty()) + return false; + + PrintState.OS.PadToColumn(50); + *this << "// user"; + if (std::next(V->use_begin()) != V->use_end()) + *this << 's'; + *this << ": "; + + // Display the user ids sorted to give a stable use order in the printer's + // output. This makes diffing large sections of SIL significantly easier. + llvm::SmallVector UserIDs; + for (auto *Op : V->getUses()) + UserIDs.push_back(getID(Op->getUser())); + std::sort(UserIDs.begin(), UserIDs.end()); + + interleave(UserIDs.begin(), UserIDs.end(), [&](ID id) { *this << id; }, + [&] { *this << ", "; }); + return true; + } + + void printSILLocation(SILLocation L, SILModule &M, const SILDebugScope *DS, + bool printedSlashes) { + if (!L.isNull()) { + if (!printedSlashes) { + PrintState.OS.PadToColumn(50); + *this << "//"; + } + *this << " "; + + // To minimize output, only print the line and column number for + // everything but the first instruction. + L.getSourceLoc().printLineAndColumn(PrintState.OS, + M.getASTContext().SourceMgr); + + // Print the type of location. + switch (L.getKind()) { + case SILLocation::NoneKind: + assert(L.isAutoGenerated() && "This kind shouldn't be printed."); + break; + case SILLocation::RegularKind: + break; + case SILLocation::ReturnKind: + *this << ":return"; + break; + case SILLocation::ImplicitReturnKind: + *this << ":imp_return"; + break; + case SILLocation::InlinedKind: + *this << ":inlined"; + break; + case SILLocation::MandatoryInlinedKind: + *this << ":minlined"; + break; + case SILLocation::CleanupKind: + *this << ":cleanup"; + break; + case SILLocation::ArtificialUnreachableKind: + *this << ":art_unreach"; + break; + case SILLocation::SILFileKind: + *this << ":sil"; + break; + } + if (L.isAutoGenerated()) + *this << ":auto_gen"; + if (L.isInPrologue()) + *this << ":in_prologue"; + } + if (L.isNull()) { + if (!printedSlashes) { + PrintState.OS.PadToColumn(50); + *this << "//"; + } + if (L.isInTopLevel()) + *this << " top_level"; + else if (L.isAutoGenerated()) + *this << " auto_gen"; + else + *this << " no_loc"; + if (L.isInPrologue()) + *this << ":in_prologue"; + } + + // Print inlined-at location, if any. + if (DS) { + while (DS->InlinedCallSite) { + *this << ": perf_inlined_at "; + auto CallSite = DS->InlinedCallSite->Loc; + if (!CallSite.isNull()) + CallSite.getSourceLoc().print( + PrintState.OS, M.getASTContext().SourceMgr, LastBufferID); + else + *this << "?"; + DS = DS->InlinedCallSite; + } + } + } + void print(SILValue V) { if (auto *FRI = dyn_cast(V)) *this << " // function_ref " - << demangleSymbolAsString(FRI->getReferencedFunction()->getName()) - << "\n"; + << demangleSymbolAsString(FRI->getReferencedFunction()->getName()) + << "\n"; *this << " "; // Print result. if (V->hasValue()) { ID Name = getID(V); - Name.ResultNumber = -1; // Don't print subresult number. + Name.ResultNumber = -1; // Don't print subresult number. *this << Name << " = "; } @@ -538,103 +649,13 @@ class SILPrinter : public SILVisitor { visit(V); // Print users, or id for valueless instructions. - bool printedSlashes = false; - - if (!V->hasValue()) { - PrintState.OS.PadToColumn(50); - *this << "// id: " << getID(V); - printedSlashes = true; - } else if (!V->use_empty()) { - PrintState.OS.PadToColumn(50); - *this << "// user"; - if (std::next(V->use_begin()) != V->use_end()) - *this << 's'; - *this << ": "; - - // Display the user ids sorted to give a stable use order in the printer's - // output. This makes diffing large sections of SIL significantly easier. - llvm::SmallVector UserIDs; - for (auto *Op : V->getUses()) - UserIDs.push_back(getID(Op->getUser())); - std::sort(UserIDs.begin(), UserIDs.end()); - - interleave(UserIDs.begin(), UserIDs.end(), - [&] (ID id) { *this << id; }, - [&] { *this << ", "; }); - printedSlashes = true; - } + bool printedSlashes = printUsersOfSILValue(V); // Print SIL location. if (Verbose) { - if (SILInstruction *I = dyn_cast(V)) { - SILLocation L = I->getLoc(); - SILModule &M = I->getModule(); - if (!L.isNull()) { - if (!printedSlashes) { - PrintState.OS.PadToColumn(50); - *this << "//"; - } - *this << " "; - - // To minimize output, only print the line and column number for - // everything but the first instruction. - L.getSourceLoc().printLineAndColumn(PrintState.OS, - M.getASTContext().SourceMgr); - - // Print the type of location. - switch (L.getKind()) { - case SILLocation::NoneKind : - assert(L.isAutoGenerated() && "This kind shouldn't be printed."); - break; - case SILLocation::RegularKind : - break; - case SILLocation::ReturnKind : - *this << ":return"; break; - case SILLocation::ImplicitReturnKind : - *this << ":imp_return"; break; - case SILLocation::InlinedKind : - *this << ":inlined"; break; - case SILLocation::MandatoryInlinedKind : - *this << ":minlined"; break; - case SILLocation::CleanupKind : - *this << ":cleanup"; break; - case SILLocation::ArtificialUnreachableKind : - *this << ":art_unreach"; break; - case SILLocation::SILFileKind : - *this << ":sil"; break; - } - if (L.isAutoGenerated()) - *this << ":auto_gen"; - if (L.isInPrologue()) - *this << ":in_prologue"; - } - if (L.isNull()) { - if (!printedSlashes) { - PrintState.OS.PadToColumn(50); - *this << "//"; - } - if (L.isInTopLevel()) - *this << " top_level"; - else if (L.isAutoGenerated()) - *this << " auto_gen"; - else - *this << " no_loc"; - if (L.isInPrologue()) - *this << ":in_prologue"; - } - - // Print inlined-at location, if any. - if (auto DS = I->getDebugScope()) - while (DS->InlinedCallSite) { - *this << ": perf_inlined_at "; - auto CallSite = DS->InlinedCallSite->Loc; - if (!CallSite.isNull()) - CallSite.getSourceLoc(). - print(PrintState.OS, M.getASTContext().SourceMgr, LastBufferID); - else - *this << "?"; - DS = DS->InlinedCallSite; - } + if (auto *I = dyn_cast(V)) { + printSILLocation(I->getLoc(), I->getModule(), I->getDebugScope(), + printedSlashes); } } @@ -686,18 +707,21 @@ class SILPrinter : public SILVisitor { *this << "undef<" << A->getType() << ">"; } - template - void printVarDeclComment(VarDeclaringInst *VDI) { - if (VarDecl *VD = VDI->getDecl()) { - *this << " // " << (VD->isLet() ? "let " : "var ") << VD->getName(); - if (unsigned N = VDI->getVarInfo().getArgNo()) - *this << ", argno: " << N; - } - } + void printDebugVar(SILDebugVariable Var) { + if (Var.Name.empty()) + return; + if (Var.Constant) + *this << ", let"; + else + *this << ", var"; + *this << ", name \"" << Var.Name << '"'; + if (Var.ArgNo) + *this << ", argno " << Var.ArgNo; + } void visitAllocStackInst(AllocStackInst *AVI) { *this << "alloc_stack " << AVI->getElementType(); - printVarDeclComment(AVI); + printDebugVar(AVI->getVarInfo()); } void visitAllocRefInst(AllocRefInst *ARI) { @@ -724,7 +748,7 @@ class SILPrinter : public SILVisitor { void visitAllocBoxInst(AllocBoxInst *ABI) { *this << "alloc_box " << ABI->getElementType(); - printVarDeclComment(ABI); + printDebugVar(ABI->getVarInfo()); } void printSubstitutions(ArrayRef Subs) { @@ -866,13 +890,26 @@ class SILPrinter : public SILVisitor { void visitDebugValueInst(DebugValueInst *DVI) { *this << "debug_value " << getIDAndType(DVI->getOperand()); - printVarDeclComment(DVI); + printDebugVar(DVI->getVarInfo()); } void visitDebugValueAddrInst(DebugValueAddrInst *DVAI) { *this << "debug_value_addr " << getIDAndType(DVAI->getOperand()); - printVarDeclComment(DVAI); -} + printDebugVar(DVAI->getVarInfo()); + } + + void visitLoadUnownedInst(LoadUnownedInst *LI) { + *this << "load_unowned "; + if (LI->isTake()) + *this << "[take] "; + *this << getIDAndType(LI->getOperand()); + } + void visitStoreUnownedInst(StoreUnownedInst *SI) { + *this << "store_unowned " << getID(SI->getSrc()) << " to "; + if (SI->isInitializationOfDest()) + *this << "[initialization] "; + *this << getIDAndType(SI->getDest()); + } void visitLoadWeakInst(LoadWeakInst *LI) { *this << "load_weak "; @@ -886,6 +923,7 @@ class SILPrinter : public SILVisitor { *this << "[initialization] "; *this << getIDAndType(SI->getDest()); } + void visitCopyAddrInst(CopyAddrInst *CI) { *this << "copy_addr "; if (CI->isTakeOfSrc()) @@ -1052,7 +1090,7 @@ class SILPrinter : public SILVisitor { // elements. bool SimpleType = true; for (auto &Elt : TI->getType().castTo()->getElements()) { - if (Elt.hasName() || Elt.isVararg() || Elt.hasInit()) { + if (Elt.hasName() || Elt.isVararg() || Elt.hasDefaultArg()) { SimpleType = false; break; } @@ -1241,9 +1279,6 @@ class SILPrinter : public SILVisitor { void visitStrongRetainInst(StrongRetainInst *RI) { *this << "strong_retain " << getIDAndType(RI->getOperand()); } - void visitStrongRetainAutoreleasedInst(StrongRetainAutoreleasedInst *RI) { - *this << "strong_retain_autoreleased " << getIDAndType(RI->getOperand()); - } void visitStrongReleaseInst(StrongReleaseInst *RI) { *this << "strong_release " << getIDAndType(RI->getOperand()); } @@ -1323,10 +1358,6 @@ class SILPrinter : public SILVisitor { *this << "return " << getIDAndType(RI->getOperand()); } - void visitAutoreleaseReturnInst(AutoreleaseReturnInst *RI) { - *this << "autorelease_return " << getIDAndType(RI->getOperand()); - } - void visitThrowInst(ThrowInst *TI) { *this << "throw " << getIDAndType(TI->getOperand()); } @@ -1576,8 +1607,8 @@ void SILFunction::print(llvm::raw_ostream &OS, bool Verbose, if (getEffectsKind() == EffectsKind::ReadWrite) OS << "[readwrite] "; - if (!getSemanticsAttr().empty()) - OS << "[_semantics \"" << getSemanticsAttr() << "\"] "; + for (auto &Attr : getSemanticsAttrs()) + OS << "[_semantics \"" << Attr << "\"] "; printName(OS); OS << " : $"; diff --git a/lib/SIL/SILSuccessor.cpp b/lib/SIL/SILSuccessor.cpp index 67bf748fc0764..b52890484926d 100644 --- a/lib/SIL/SILSuccessor.cpp +++ b/lib/SIL/SILSuccessor.cpp @@ -1,8 +1,8 @@ -//===--- SILSuccessor.cpp - Implementation of SILSuccessor.h ---------------==// +//===--- SILSuccessor.cpp - Implementation of SILSuccessor.h --------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -38,7 +38,7 @@ void SILSuccessor::operator=(SILBasicBlock *BB) { SuccessorBlock = BB; } -// Derferencing the SuccIterator returns the predecessors SILBasicBlock. +// Dereferencing the SuccIterator returns the predecessor's SILBasicBlock. SILBasicBlock *SILSuccessorIterator::operator*() { assert(Cur && "Can't deference end (or default constructed) iterator"); return Cur->ContainingInst->getParent(); diff --git a/lib/SIL/SILType.cpp b/lib/SIL/SILType.cpp index 9cba539bf93c9..cd2fe9ea8b2ff 100644 --- a/lib/SIL/SILType.cpp +++ b/lib/SIL/SILType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -416,7 +416,7 @@ bool SILType::aggregateContainsRecord(SILType Record, SILModule &Mod) const { for (VarDecl *Var : S->getStoredProperties()) Worklist.push_back(Ty.getFieldType(Var, Mod)); - // If we have a class address, it is a pointer so it can not contain other + // If we have a class address, it is a pointer so it cannot contain other // types. // If we reached this point, then this type has no subrecords. Since it does diff --git a/lib/SIL/SILVTable.cpp b/lib/SIL/SILVTable.cpp index 5e261d618ddfd..0ebead67b9896 100644 --- a/lib/SIL/SILVTable.cpp +++ b/lib/SIL/SILVTable.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SIL/SILValue.cpp b/lib/SIL/SILValue.cpp index 88e006e63aeba..59b5b60024070 100644 --- a/lib/SIL/SILValue.cpp +++ b/lib/SIL/SILValue.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -210,11 +210,11 @@ void Operand::hoistAddressProjections(SILInstruction *InsertBefore, while (true) { SILValue Incoming = stripSinglePredecessorArgs(V); - // Forward the incoming arg from a single predeccessor. + // Forward the incoming arg from a single predecessor. if (V != Incoming) { if (V == get()) { // If we are the operand itself set the operand to the incoming - // arugment. + // argument. set(Incoming); V = Incoming; } else { diff --git a/lib/SIL/SILValueProjection.cpp b/lib/SIL/SILValueProjection.cpp new file mode 100644 index 0000000000000..258a1632d6b13 --- /dev/null +++ b/lib/SIL/SILValueProjection.cpp @@ -0,0 +1,351 @@ +//===--- SILValueProjection.cpp -------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-value-projection" +#include "swift/SIL/SILValueProjection.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +//===----------------------------------------------------------------------===// +// Utility Functions +//===----------------------------------------------------------------------===// + +static inline void removeLSLocations(LSLocationValueMap &Values, + LSLocationList &FirstLevel) { + for (auto &X : FirstLevel) + Values.erase(X); +} + +//===----------------------------------------------------------------------===// +// SILValue Projection +//===----------------------------------------------------------------------===// + +void SILValueProjection::print() const { + llvm::outs() << Base; + llvm::outs() << Path.getValue(); +} + +SILValue SILValueProjection::createExtract(SILValue Base, + Optional &Path, + SILInstruction *Inst, + bool IsValExt) { + // If we found a projection path, but there are no projections, then the two + // loads must be the same, return PrevLI. + if (!Path || Path->empty()) + return Base; + + // Ok, at this point we know that we can construct our aggregate projections + // from our list of address projections. + SILValue LastExtract = Base; + SILBuilder Builder(Inst); + + // We use an auto-generated SILLocation for now. + // TODO: make the sil location more precise. + SILLocation Loc = RegularLocation::getAutoGeneratedLocation(); + + // Construct the path! + for (auto PI = Path->rbegin(), PE = Path->rend(); PI != PE; ++PI) { + if (IsValExt) { + LastExtract = + PI->createValueProjection(Builder, Loc, LastExtract).get(); + continue; + } + LastExtract = + PI->createAddrProjection(Builder, Loc, LastExtract).get(); + } + + // Return the last extract we created. + return LastExtract; +} + +//===----------------------------------------------------------------------===// +// Load Store Value +//===----------------------------------------------------------------------===// + +void LSValue::expand(SILValue Base, SILModule *M, LSValueList &Vals, + TypeExpansionAnalysis *TE) { + // To expand a LSValue to its indivisible parts, we first get the + // address projection paths from the accessed type to each indivisible field, + // i.e. leaf nodes, then we append these projection paths to the Base. + for (const auto &P : + TE->getTypeExpansionProjectionPaths(Base.getType(), M, TEKind::TELeaf)) { + Vals.push_back(LSValue(Base, P.getValue())); + } +} + +SILValue LSValue::reduce(LSLocation &Base, SILModule *M, + LSLocationValueMap &Values, + SILInstruction *InsertPt, + TypeExpansionAnalysis *TE) { + // Walk bottom up the projection tree, try to reason about how to construct + // a single SILValue out of all the available values for all the memory + // locations. + // + // First, get a list of all the leaf nodes and intermediate nodes for the + // Base memory location. + LSLocationList ALocs; + ProjectionPath &BasePath = Base.getPath().getValue(); + for (const auto &P : + TE->getTypeExpansionProjectionPaths(Base.getType(), M, TEKind::TENode)) { + ALocs.push_back(LSLocation(Base.getBase(), P.getValue(), BasePath)); + } + + // Second, go from leaf nodes to their parents. This guarantees that at the + // point the parent is processed, its children have been processed already. + for (auto I = ALocs.rbegin(), E = ALocs.rend(); I != E; ++I) { + // This is a leaf node, we have a value for it. + // + // Reached the end of the projection tree, this is a leaf node. + LSLocationList FirstLevel; + I->getFirstLevelLSLocations(FirstLevel, M); + if (FirstLevel.empty()) + continue; + + // If this is a class reference type, we have reached end of the type tree. + if (I->getType().getClassOrBoundGenericClass()) + continue; + + // This is NOT a leaf node, we need to construct a value for it. + + // There is only 1 children node and its value's projection path is not + // empty, keep stripping it. + auto Iter = FirstLevel.begin(); + LSValue &FirstVal = Values[*Iter]; + if (FirstLevel.size() == 1 && !FirstVal.hasEmptyProjectionPath()) { + Values[*I] = FirstVal.stripLastLevelProjection(); + // We have a value for the parent, remove all the values for children. + removeLSLocations(Values, FirstLevel); + continue; + } + + // If there are more than 1 children and all the children nodes have + // LSValues with the same base and non-empty projection path. we can get + // away by not extracting value for every single field. + // + // Simply create a new node with all the aggregated base value, i.e. + // stripping off the last level projection. + bool HasIdenticalValueBase = true; + SILValue FirstBase = FirstVal.getBase(); + Iter = std::next(Iter); + for (auto EndIter = FirstLevel.end(); Iter != EndIter; ++Iter) { + LSValue &V = Values[*Iter]; + HasIdenticalValueBase &= (FirstBase == V.getBase()); + } + + if (FirstLevel.size() > 1 && HasIdenticalValueBase && + !FirstVal.hasEmptyProjectionPath()) { + Values[*I] = FirstVal.stripLastLevelProjection(); + // We have a value for the parent, remove all the values for children. + removeLSLocations(Values, FirstLevel); + continue; + } + + // In 3 cases do we need aggregation. + // + // 1. If there is only 1 child and we cannot strip off any projections, + // that means we need to create an aggregation. + // + // 2. There are multiple children and they have the same base, but empty + // projection paths. + // + // 3. Children have values from different bases, We need to create + // extractions and aggregation in this case. + // + llvm::SmallVector Vals; + for (auto &X : FirstLevel) { + Vals.push_back(Values[X].materialize(InsertPt)); + } + SILBuilder Builder(InsertPt); + + // We use an auto-generated SILLocation for now. + // TODO: make the sil location more precise. + NullablePtr AI = + Projection::createAggFromFirstLevelProjections( + Builder, RegularLocation::getAutoGeneratedLocation(), I->getType(), + Vals); + // This is the Value for the current node. + ProjectionPath P; + Values[*I] = LSValue(SILValue(AI.get()), P); + removeLSLocations(Values, FirstLevel); + + // Keep iterating until we have reach the top-most level of the projection + // tree. + // i.e. the memory location represented by the Base. + } + + assert(Values.size() == 1 && "Should have a single location this point"); + + // Finally materialize and return the forwarding SILValue. + return Values.begin()->second.materialize(InsertPt); +} + +//===----------------------------------------------------------------------===// +// Memory Location +//===----------------------------------------------------------------------===// + +void LSLocation::initialize(SILValue Dest) { + Base = getUnderlyingObject(Dest); + Path = ProjectionPath::getAddrProjectionPath(Base, Dest); +} + +bool LSLocation::isMustAliasLSLocation(const LSLocation &RHS, + AliasAnalysis *AA) { + // If the bases are not must-alias, the locations may not alias. + if (!AA->isMustAlias(Base, RHS.getBase())) + return false; + // If projection paths are different, then the locations cannot alias. + if (!hasIdenticalProjectionPath(RHS)) + return false; + return true; +} + +bool LSLocation::isMayAliasLSLocation(const LSLocation &RHS, + AliasAnalysis *AA) { + // If the bases do not alias, then the locations cannot alias. + if (AA->isNoAlias(Base, RHS.getBase())) + return false; + // If one projection path is a prefix of another, then the locations + // could alias. + if (hasNonEmptySymmetricPathDifference(RHS)) + return false; + return true; +} + + +bool LSLocation::isNonEscapingLocalLSLocation(SILFunction *Fn, + EscapeAnalysis *EA) { + // An alloc_stack is definitely dead at the end of the function. + if (isa(Base)) + return true; + // For other allocations we ask escape analysis. + auto *ConGraph = EA->getConnectionGraph(Fn); + if (isa(Base)) { + auto *Node = ConGraph->getNodeOrNull(Base, EA); + if (Node && !Node->escapes()) { + return true; + } + } + return false; +} + +void LSLocation::getFirstLevelLSLocations(LSLocationList &Locs, + SILModule *Mod) { + SILType Ty = getType(); + llvm::SmallVector Out; + Projection::getFirstLevelAddrProjections(Ty, *Mod, Out); + for (auto &X : Out) { + ProjectionPath P; + P.append(X); + P.append(Path.getValue()); + Locs.push_back(LSLocation(Base, P)); + } +} + +void LSLocation::expand(LSLocation &Base, SILModule *M, LSLocationList &Locs, + TypeExpansionAnalysis *TE) { + // To expand a memory location to its indivisible parts, we first get the + // address projection paths from the accessed type to each indivisible field, + // i.e. leaf nodes, then we append these projection paths to the Base. + // + // Construct the LSLocation by appending the projection path from the + // accessed node to the leaf nodes. + ProjectionPath &BasePath = Base.getPath().getValue(); + for (const auto &P : + TE->getTypeExpansionProjectionPaths(Base.getType(), M, TEKind::TELeaf)) { + Locs.push_back(LSLocation(Base.getBase(), P.getValue(), BasePath)); + } +} + +void LSLocation::reduce(LSLocation &Base, SILModule *M, LSLocationSet &Locs, + TypeExpansionAnalysis *TE) { + // First, construct the LSLocation by appending the projection path from the + // accessed node to the leaf nodes. + LSLocationList Nodes; + ProjectionPath &BasePath = Base.getPath().getValue(); + for (const auto &P : + TE->getTypeExpansionProjectionPaths(Base.getType(), M, TEKind::TENode)) { + Nodes.push_back(LSLocation(Base.getBase(), P.getValue(), BasePath)); + } + + // Second, go from leaf nodes to their parents. This guarantees that at the + // point the parent is processed, its children have been processed already. + for (auto I = Nodes.rbegin(), E = Nodes.rend(); I != E; ++I) { + LSLocationList FirstLevel; + I->getFirstLevelLSLocations(FirstLevel, M); + // Reached the end of the projection tree, this is a leaf node. + if (FirstLevel.empty()) + continue; + + // If this is a class reference type, we have reached end of the type tree. + if (I->getType().getClassOrBoundGenericClass()) + continue; + + // This is NOT a leaf node, check whether all its first level children are + // alive. + bool Alive = true; + for (auto &X : FirstLevel) { + Alive &= Locs.find(X) != Locs.end(); + } + + // All first level locations are alive, create the new aggregated location. + if (Alive) { + for (auto &X : FirstLevel) + Locs.erase(X); + Locs.insert(*I); + } + } +} + + +void LSLocation::enumerateLSLocation(SILModule *M, SILValue Mem, + std::vector &LV, + LSLocationIndexMap &BM, + TypeExpansionAnalysis *TE) { + // Construct a Location to represent the memory written by this instruction. + LSLocation L(Mem); + + // If we cant figure out the Base or Projection Path for the memory location, + // simply ignore it for now. + if (!L.isValid()) + return; + + // Expand the given Mem into individual fields and add them to the + // locationvault. + LSLocationList Locs; + LSLocation::expand(L, M, Locs, TE); + for (auto &Loc : Locs) { + BM[Loc] = LV.size(); + LV.push_back(Loc); + } +} + +void LSLocation::enumerateLSLocations(SILFunction &F, + std::vector &LV, + LSLocationIndexMap &BM, + TypeExpansionAnalysis *TE) { + // Enumerate all locations accessed by the loads or stores. + // + // TODO: process more instructions as we process more instructions in + // processInstruction. + // + SILValue Op; + for (auto &B : F) { + for (auto &I : B) { + if (auto *LI = dyn_cast(&I)) { + enumerateLSLocation(&I.getModule(), LI->getOperand(), LV, BM, TE); + } else if (auto *SI = dyn_cast(&I)) { + enumerateLSLocation(&I.getModule(), SI->getDest(), LV, BM, TE); + } + } + } +} diff --git a/lib/SIL/SILWitnessTable.cpp b/lib/SIL/SILWitnessTable.cpp index d4b0b3fafab56..1df243656ff5a 100644 --- a/lib/SIL/SILWitnessTable.cpp +++ b/lib/SIL/SILWitnessTable.cpp @@ -1,8 +1,8 @@ -//===--- SILWitnessTable.h - Defines the SILWitnessTable class ------------===// +//===--- SILWitnessTable.cpp - Defines the SILWitnessTable class ----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -26,30 +26,27 @@ using namespace swift; -static void mangleConstant(NormalProtocolConformance *C, - llvm::raw_ostream &buffer) { +static std::string mangleConstant(NormalProtocolConformance *C) { using namespace Mangle; - Mangler mangler(buffer); + Mangler mangler; // mangled-name ::= '_T' global // global ::= 'WP' protocol-conformance - buffer << "_TWP"; + mangler.append("_TWP"); mangler.mangleProtocolConformance(C); - buffer.flush(); + return mangler.finalize(); + } SILWitnessTable * SILWitnessTable::create(SILModule &M, SILLinkage Linkage, bool IsFragile, NormalProtocolConformance *Conformance, ArrayRef entries) { - assert(Conformance && "Can not create a witness table for a null " + assert(Conformance && "Cannot create a witness table for a null " "conformance."); // Create the mangled name of our witness table... - llvm::SmallString<32> buffer; - llvm::raw_svector_ostream stream(buffer); - mangleConstant(Conformance, stream); - Identifier Name = M.getASTContext().getIdentifier(buffer); + Identifier Name = M.getASTContext().getIdentifier(mangleConstant(Conformance)); // Allocate the witness table and initialize it. void *buf = M.allocate(sizeof(SILWitnessTable), alignof(SILWitnessTable)); @@ -70,14 +67,12 @@ SILWitnessTable::create(SILModule &M, SILLinkage Linkage, bool IsFragile, SILWitnessTable * SILWitnessTable::create(SILModule &M, SILLinkage Linkage, NormalProtocolConformance *Conformance) { - assert(Conformance && "Can not create a witness table for a null " + assert(Conformance && "Cannot create a witness table for a null " "conformance."); // Create the mangled name of our witness table... - llvm::SmallString<32> buffer; - llvm::raw_svector_ostream stream(buffer); - mangleConstant(Conformance, stream); - Identifier Name = M.getASTContext().getIdentifier(buffer); + Identifier Name = M.getASTContext().getIdentifier(mangleConstant(Conformance)); + // Allocate the witness table and initialize it. void *buf = M.allocate(sizeof(SILWitnessTable), alignof(SILWitnessTable)); diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp index e844224ec837d..f0c6b37a99b67 100644 --- a/lib/SIL/TypeLowering.cpp +++ b/lib/SIL/TypeLowering.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -230,9 +230,22 @@ namespace { } RetTy visitUnownedStorageType(CanUnownedStorageType type) { + // FIXME: resilience + if (type->isLoadable(ResilienceExpansion::Maximal)) { + return asImpl().visitLoadableUnownedStorageType(type); + } else { + return asImpl().visitAddressOnlyUnownedStorageType(type); + } + } + + RetTy visitLoadableUnownedStorageType(CanUnownedStorageType type) { return asImpl().handleReference(type); } + RetTy visitAddressOnlyUnownedStorageType(CanUnownedStorageType type) { + return asImpl().handleAddressOnly(type); + } + RetTy visitWeakStorageType(CanWeakStorageType type) { return asImpl().handleAddressOnly(type); } @@ -310,7 +323,7 @@ namespace { RetTy visitTupleType(CanTupleType type) { bool hasReference = false; // TODO: We ought to be able to early-exit as soon as we've established - // that a type is address-only. However, we also currenty rely on + // that a type is address-only. However, we also currently rely on // SIL lowering to catch unsupported recursive value types. bool isAddressOnly = false; for (auto eltType : type.getElementTypes()) { @@ -846,10 +859,10 @@ namespace { } }; - /// A type lowering for @unowned types. - class UnownedTypeLowering final : public LeafLoadableTypeLowering { + /// A type lowering for loadable @unowned types. + class LoadableUnownedTypeLowering final : public LeafLoadableTypeLowering { public: - UnownedTypeLowering(SILType type) + LoadableUnownedTypeLowering(SILType type) : LeafLoadableTypeLowering(type, IsReferenceCounted) {} void emitRetainValue(SILBuilder &B, SILLocation loc, @@ -995,8 +1008,13 @@ namespace { .visit(unownedBaseType); } - return new (TC, Dependent) UnownedTypeLowering( - SILType::getPrimitiveObjectType(OrigType)); + return this->TypeClassifierBase::visitUnownedStorageType(type); + } + + const TypeLowering * + visitLoadableUnownedStorageType(CanUnownedStorageType type) { + return new (TC, Dependent) LoadableUnownedTypeLowering( + SILType::getPrimitiveObjectType(OrigType)); } const TypeLowering *visitUnmanagedStorageType( @@ -1038,7 +1056,7 @@ namespace { typedef LoadableTupleTypeLowering::Child Child; SmallVector childElts; // TODO: We ought to be able to early-exit as soon as we've established - // that a type is address-only. However, we also currenty rely on + // that a type is address-only. However, we also currently rely on // SIL lowering to catch unsupported recursive value types. bool isAddressOnly = false; bool hasOnlyTrivialChildren = true; @@ -1062,7 +1080,7 @@ namespace { const TypeLowering *visitAnyStructType(CanType structType, StructDecl *D) { // TODO: We ought to be able to early-exit as soon as we've established - // that a type is address-only. However, we also currenty rely on + // that a type is address-only. However, we also currently rely on // SIL lowering to catch unsupported recursive value types. bool isAddressOnly = false; @@ -1098,7 +1116,7 @@ namespace { const TypeLowering *visitAnyEnumType(CanType enumType, EnumDecl *D) { // TODO: We ought to be able to early-exit as soon as we've established - // that a type is address-only. However, we also currenty rely on + // that a type is address-only. However, we also currently rely on // SIL lowering to catch unsupported recursive value types. bool isAddressOnly = false; @@ -1436,12 +1454,14 @@ TypeConverter::getTypeLowering(AbstractionPattern origType, AbstractionPattern origLoweredType = [&] { if (origType.isExactType(substType)) { - return AbstractionPattern(substLoweredType); + return AbstractionPattern(origType.getGenericSignature(), + substLoweredType); } else if (origType.isOpaque()) { return origType; } else { auto origFnType = cast(origType.getType()); - return AbstractionPattern(getLoweredASTFunctionType(origFnType, + return AbstractionPattern(origType.getGenericSignature(), + getLoweredASTFunctionType(origFnType, uncurryLevel, None)); } @@ -1464,9 +1484,9 @@ TypeConverter::getTypeLowering(AbstractionPattern origType, // inout types are a special case for lowering, because they get // completely removed and represented as 'address' SILTypes. - if (auto substInOutType = dyn_cast(substType)) { + if (isa(substType)) { // Derive SILType for InOutType from the object type. - CanType substObjectType = substInOutType.getObjectType(); + CanType substObjectType = substType.getLValueOrInOutObjectType(); AbstractionPattern origObjectType = origType.getLValueObjectType(); SILType loweredType = getLoweredType(origObjectType, substObjectType, @@ -1478,22 +1498,6 @@ TypeConverter::getTypeLowering(AbstractionPattern origType, return *theInfo; } - // Lower the object type of boxes. - if (auto substBoxType = dyn_cast(substType)) { - AbstractionPattern origBoxed(origType.getAs()->getBoxedType()); - SILType loweredBoxedType = getLoweredType(origBoxed, - substBoxType->getBoxedType()); - auto loweredBoxType - = SILBoxType::get(loweredBoxedType.getSwiftRValueType()); - auto loweredBoxSILType - = SILType::getPrimitiveObjectType(loweredBoxType); - - auto *theInfo = new (*this, key.isDependent()) - ReferenceTypeLowering(loweredBoxSILType); - insert(key, theInfo); - return *theInfo; - } - // We need to lower function and metatype types within tuples. if (auto substTupleType = dyn_cast(substType)) { auto loweredType = getLoweredTupleType(*this, origType, substTupleType); @@ -1633,12 +1637,7 @@ mapArchetypeToInterfaceType(const PrimaryArchetypeMap &primaryArchetypes, CanType TypeConverter::getInterfaceTypeOutOfContext(CanType contextTy, DeclContext *context) const { - GenericParamList *genericParams; - do { - genericParams = context->getGenericParamsOfContext(); - context = context->getParent(); - } while (!genericParams && context); - + GenericParamList *genericParams = context->getGenericParamsOfContext(); return getInterfaceTypeOutOfContext(contextTy, genericParams); } @@ -1845,22 +1844,6 @@ static CanAnyFunctionType getIVarInitDestroyerInterfaceType(ClassDecl *cd, return CanFunctionType::get(classType, resultType, extInfo); } -GenericParamList * -TypeConverter::getEffectiveGenericParamsForContext(DeclContext *dc) { - - // FIXME: This is a clunky way of uncurrying nested type parameters from - // a function context. - if (auto func = dyn_cast(dc)) { - return getConstantInfo(SILDeclRef(func)).ContextGenericParams; - } - - if (auto closure = dyn_cast(dc)) { - return getConstantInfo(SILDeclRef(closure)).ContextGenericParams; - } - - return dc->getGenericParamsOfContext(); -} - GenericParamList * TypeConverter::getEffectiveGenericParams(AnyFunctionRef fn, CaptureInfo captureInfo) { @@ -1870,8 +1853,8 @@ TypeConverter::getEffectiveGenericParams(AnyFunctionRef fn, !captureInfo.hasGenericParamCaptures()) { return nullptr; } - - return getEffectiveGenericParamsForContext(dc); + + return dc->getGenericParamsOfContext(); } CanGenericSignature @@ -1879,30 +1862,19 @@ TypeConverter::getEffectiveGenericSignature(AnyFunctionRef fn, CaptureInfo captureInfo) { auto dc = fn.getAsDeclContext(); - if (auto sig = dc->getGenericSignatureOfContext()) - return sig->getCanonicalSignature(); - - dc = dc->getParent(); - - if (dc->isLocalContext() && + // If this is a non-generic local function that does not capture any + // generic type parameters from the outer context, don't need a + // signature at all. + if (!dc->isInnermostContextGeneric() && + dc->getParent()->isLocalContext() && !captureInfo.hasGenericParamCaptures()) { return nullptr; } - // Find the innermost context that has a generic parameter list. - // FIXME: This is wrong for generic local functions in generic contexts. - // Their GenericParamList is not semantically a child of the context - // GenericParamList because they "capture" their context's already-bound - // archetypes. - while (!dc->getGenericSignatureOfContext()) { - dc = dc->getParent(); - if (!dc) return nullptr; - } - - auto sig = dc->getGenericSignatureOfContext(); - if (!sig) - return nullptr; - return sig->getCanonicalSignature(); + if (auto sig = dc->getGenericSignatureOfContext()) + return sig->getCanonicalSignature(); + + return nullptr; } CanAnyFunctionType @@ -1935,42 +1907,8 @@ TypeConverter::getFunctionTypeWithCaptures(CanAnyFunctionType funcType, } - SmallVector inputFields; - - for (auto capture : captureInfo.getCaptures()) { - auto VD = capture.getDecl(); - // A capture of a 'var' or 'inout' variable is done with the underlying - // object type. - auto captureType = - VD->getType()->getLValueOrInOutObjectType()->getCanonicalType(); - - switch (getDeclCaptureKind(capture)) { - case CaptureKind::None: - break; - - case CaptureKind::StorageAddress: - // No-escape stored decls are captured by their raw address. - inputFields.push_back(TupleTypeElt(CanInOutType::get(captureType))); - break; - - case CaptureKind::Constant: - // Capture the value directly. - inputFields.push_back(TupleTypeElt(captureType)); - break; - case CaptureKind::Box: { - // Capture the owning NativeObject and the address of the value. - CanType boxTy = SILBoxType::get(captureType); - inputFields.push_back(boxTy); - auto lvType = CanInOutType::get(captureType); - inputFields.push_back(TupleTypeElt(lvType)); - break; - } - } - } - - CanType capturedInputs = - TupleType::get(inputFields, Context)->getCanonicalType(); - + // Build the type with an extra empty tuple clause. We'll lower the captures + // into this position later. auto extInfo = AnyFunctionType::ExtInfo(FunctionType::Representation::Thin, /*noreturn*/ false, funcType->throws()); @@ -1978,10 +1916,10 @@ TypeConverter::getFunctionTypeWithCaptures(CanAnyFunctionType funcType, extInfo = extInfo.withNoEscape(); if (genericParams) - return CanPolymorphicFunctionType::get(capturedInputs, funcType, + return CanPolymorphicFunctionType::get(Context.TheEmptyTupleType, funcType, genericParams, extInfo); - return CanFunctionType::get(capturedInputs, funcType, extInfo); + return CanFunctionType::get(Context.TheEmptyTupleType, funcType, extInfo); } CanAnyFunctionType @@ -2012,58 +1950,18 @@ TypeConverter::getFunctionInterfaceTypeWithCaptures(CanAnyFunctionType funcType, extInfo); } - SmallVector inputFields; - - for (auto capture : captureInfo.getCaptures()) { - // A capture of a 'var' or 'inout' variable is done with the underlying - // object type. - auto vd = capture.getDecl(); - auto captureType = - vd->getType()->getLValueOrInOutObjectType()->getCanonicalType(); - - switch (getDeclCaptureKind(capture)) { - case CaptureKind::None: - break; - - case CaptureKind::StorageAddress: - // No-escape stored decls are captured by their raw address. - inputFields.push_back(TupleTypeElt(CanInOutType::get(captureType))); - break; - - case CaptureKind::Constant: - // Capture the value directly. - inputFields.push_back(TupleTypeElt(captureType)); - break; - case CaptureKind::Box: { - // Capture the owning NativeObject and the address of the value. - CanType boxTy = SILBoxType::get(captureType); - - inputFields.push_back(boxTy); - auto lvType = CanInOutType::get(captureType); - inputFields.push_back(TupleTypeElt(lvType)); - break; - } - } - } - - CanType capturedInputs = - TupleType::get(inputFields, Context)->getCanonicalType(); - - // Map context archetypes out of the captures. - capturedInputs = - getInterfaceTypeOutOfContext(capturedInputs, - theClosure.getAsDeclContext()); - + // Add an extra empty tuple level to represent the captures. We'll append the + // lowered capture types here. auto extInfo = AnyFunctionType::ExtInfo(FunctionType::Representation::Thin, /*noreturn*/ false, funcType->throws()); if (genericSig) return CanGenericFunctionType::get(genericSig, - capturedInputs, funcType, + Context.TheEmptyTupleType, funcType, extInfo); - return CanFunctionType::get(capturedInputs, funcType, extInfo); + return CanFunctionType::get(Context.TheEmptyTupleType, funcType, extInfo); } /// Replace any DynamicSelf types with their underlying Self type. @@ -2090,7 +1988,7 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) { // parameters. auto funcTy = cast(ACE->getType()->getCanonicalType()); funcTy = cast( - getInterfaceTypeOutOfContext(funcTy, ACE->getParent())); + getInterfaceTypeOutOfContext(funcTy, ACE->getParent())); return getFunctionInterfaceTypeWithCaptures(funcTy, ACE); } @@ -2099,7 +1997,7 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) { func->getInterfaceType()->getCanonicalType()); if (func->getParent() && func->getParent()->isLocalContext()) funcTy = cast( - getInterfaceTypeOutOfContext(funcTy, func->getParent())); + getInterfaceTypeOutOfContext(funcTy, func->getParent())); funcTy = cast(replaceDynamicSelfWithSelf(funcTy)); return getFunctionInterfaceTypeWithCaptures(funcTy, func); } @@ -2159,11 +2057,24 @@ TypeConverter::getConstantContextGenericParams(SILDeclRef c) { return {getEffectiveGenericParams(ACE, captureInfo), nullptr}; } FuncDecl *func = cast(vd); - // FIXME: For local generic functions we need to chain the local generic - // context to the outer context. - if (auto GP = func->getGenericParamsOfContext()) - return {GP, func->getGenericParams()}; auto captureInfo = getLoweredLocalCaptures(func); + + // FIXME: This is really weird: + // 1) For generic functions, generic methods and generic + // local functions, we return the function's generic + // parameter list twice. + // 2) For non-generic methods inside generic types, we + // return the generic type's parameters and nullptr. + // 3) For non-generic local functions, we return the + // outer function's parameters and nullptr. + // + // Local generic functions could probably be modeled better + // at the SIL level. + if (func->isInnermostContextGeneric() || + func->getDeclContext()->isGenericTypeContext()) { + if (auto GP = func->getGenericParamsOfContext()) + return {GP, func->getGenericParams()}; + } return {getEffectiveGenericParams(func, captureInfo), func->getGenericParams()}; } diff --git a/lib/SIL/Verifier.cpp b/lib/SIL/Verifier.cpp index ed8df75ced662..0ca6c3581ee06 100644 --- a/lib/SIL/Verifier.cpp +++ b/lib/SIL/Verifier.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -548,17 +548,21 @@ class SILVerifier : public SILVerifierBase { LocKind == SILLocation::SILFileKind) return; +#if 0 + // FIXME: This check was tautological before the removal of + // AutoreleaseReturnInst, and it turns out that we're violating it. + // Fix incoming. if (LocKind == SILLocation::CleanupKind || LocKind == SILLocation::InlinedKind) require(InstKind != ValueKind::ReturnInst || InstKind != ValueKind::AutoreleaseReturnInst, "cleanup and inlined locations are not allowed on return instructions"); +#endif if (LocKind == SILLocation::ReturnKind || LocKind == SILLocation::ImplicitReturnKind) require(InstKind == ValueKind::BranchInst || InstKind == ValueKind::ReturnInst || - InstKind == ValueKind::AutoreleaseReturnInst || InstKind == ValueKind::UnreachableInst, "return locations are only allowed on branch and return instructions"); @@ -614,13 +618,8 @@ class SILVerifier : public SILVerifierBase { } void checkAllocStackInst(AllocStackInst *AI) { - require(AI->getContainerResult().getType().isLocalStorage(), - "first result of alloc_stack must be local storage"); - require(AI->getAddressResult().getType().isAddress(), - "second result of alloc_stack must be an address type"); - require(AI->getContainerResult().getType().getSwiftRValueType() - == AI->getElementType().getSwiftRValueType(), - "container storage must be for allocated type"); + require(AI->getType(0).isAddress(), + "result of alloc_stack must be an address type"); // Scan the parent block of AI and check that the users of AI inside this // block are inside the lifetime of the allocated memory. @@ -775,7 +774,7 @@ class SILVerifier : public SILVerifierBase { } void verifyLLVMIntrinsic(BuiltinInst *BI, llvm::Intrinsic::ID ID) { - // Certain llvm instrinsic require constant values as their operands. + // Certain llvm intrinsic require constant values as their operands. // Consequently, these must not be phi nodes (aka. basic block arguments). switch (ID) { default: @@ -975,6 +974,32 @@ class SILVerifier : public SILVerifierBase { require(Dest.getType().getObjectType() == Src.getType(), "Store operand type and dest type mismatch"); } + + void checkLoadUnownedInst(LoadUnownedInst *LUI) { + require(LUI->getType().isObject(), "Result of load must be an object"); + auto PointerType = LUI->getOperand().getType(); + auto PointerRVType = PointerType.getSwiftRValueType(); + require(PointerType.isAddress() && + PointerRVType->is(), + "load_unowned operand must be an unowned address"); + require(PointerRVType->getReferenceStorageReferent()->getCanonicalType() == + LUI->getType().getSwiftType(), + "Load operand type and result type mismatch"); + } + + void checkStoreUnownedInst(StoreUnownedInst *SUI) { + require(SUI->getSrc().getType().isObject(), + "Can't store from an address source"); + auto PointerType = SUI->getDest().getType(); + auto PointerRVType = PointerType.getSwiftRValueType(); + require(PointerType.isAddress() && + PointerRVType->is(), + "store_unowned address operand must be an unowned address"); + require(PointerRVType->getReferenceStorageReferent()->getCanonicalType() == + SUI->getSrc().getType().getSwiftType(), + "Store operand type and dest type mismatch"); + } + void checkLoadWeakInst(LoadWeakInst *LWI) { require(LWI->getType().isObject(), "Result of load must be an object"); require(LWI->getType().getSwiftType()->getAnyOptionalObjectType(), @@ -983,7 +1008,7 @@ class SILVerifier : public SILVerifierBase { auto PointerRVType = PointerType.getSwiftRValueType(); require(PointerType.isAddress() && PointerRVType->is(), - "load_weak operand must be an weak address"); + "load_weak operand must be a weak address"); require(PointerRVType->getReferenceStorageReferent()->getCanonicalType() == LWI->getType().getSwiftType(), "Load operand type and result type mismatch"); @@ -998,7 +1023,7 @@ class SILVerifier : public SILVerifierBase { auto PointerRVType = PointerType.getSwiftRValueType(); require(PointerType.isAddress() && PointerRVType->is(), - "store_weak address operand must be an weak address"); + "store_weak address operand must be a weak address"); require(PointerRVType->getReferenceStorageReferent()->getCanonicalType() == SWI->getSrc().getType().getSwiftType(), "Store operand type and dest type mismatch"); @@ -1283,34 +1308,30 @@ class SILVerifier : public SILVerifierBase { void checkStrongRetainInst(StrongRetainInst *RI) { requireReferenceValue(RI->getOperand(), "Operand of strong_retain"); } - void checkStrongRetainAutoreleasedInst(StrongRetainAutoreleasedInst *RI) { - require(RI->getOperand().getType().isObject(), - "Operand of strong_retain_autoreleased must be an object"); - require(RI->getOperand().getType().hasRetainablePointerRepresentation(), - "Operand of strong_retain_autoreleased must be a retainable pointer"); - require(isa(RI->getOperand()) || - isa(RI->getOperand()), - "Operand of strong_retain_autoreleased must be the return value of " - "an apply instruction"); - } void checkStrongReleaseInst(StrongReleaseInst *RI) { requireReferenceValue(RI->getOperand(), "Operand of release"); } void checkStrongRetainUnownedInst(StrongRetainUnownedInst *RI) { - requireObjectType(UnownedStorageType, RI->getOperand(), - "Operand of retain_unowned"); + auto unownedType = requireObjectType(UnownedStorageType, RI->getOperand(), + "Operand of strong_retain_unowned"); + require(unownedType->isLoadable(ResilienceExpansion::Maximal), + "strong_retain_unowned requires unowned type to be loadable"); } void checkUnownedRetainInst(UnownedRetainInst *RI) { - requireObjectType(UnownedStorageType, RI->getOperand(), - "Operand of unowned_retain"); + auto unownedType = requireObjectType(UnownedStorageType, RI->getOperand(), + "Operand of unowned_retain"); + require(unownedType->isLoadable(ResilienceExpansion::Maximal), + "unowned_retain requires unowned type to be loadable"); } void checkUnownedReleaseInst(UnownedReleaseInst *RI) { - requireObjectType(UnownedStorageType, RI->getOperand(), - "Operand of unowned_release"); + auto unownedType = requireObjectType(UnownedStorageType, RI->getOperand(), + "Operand of unowned_release"); + require(unownedType->isLoadable(ResilienceExpansion::Maximal), + "unowned_release requires unowned type to be loadable"); } void checkDeallocStackInst(DeallocStackInst *DI) { - require(DI->getOperand().getType().isLocalStorage(), - "Operand of dealloc_stack must be local storage"); + require(isa(DI->getOperand()), + "Operand of dealloc_stack must be an alloc_stack"); } void checkDeallocRefInst(DeallocRefInst *DI) { require(DI->getOperand().getType().isObject(), @@ -1660,8 +1681,9 @@ class SILVerifier : public SILVerifierBase { } void checkSuperMethodInst(SuperMethodInst *CMI) { - require(CMI->getType() == TC.getConstantType(CMI->getMember()), - "result type of super_method must match type of method"); + auto overrideTy = TC.getConstantOverrideType(CMI->getMember()); + requireSameType(CMI->getType(), SILType::getPrimitiveObjectType(overrideTy), + "result type of super_method must match abstracted type of method"); auto methodType = requireObjectType(SILFunctionType, CMI, "result of super_method"); require(!methodType->getExtInfo().hasContext(), @@ -1991,6 +2013,18 @@ class SILVerifier : public SILVerifierBase { "failure dest of checked_cast_br must take no arguments"); } + void checkCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *CCABI) { + require(CCABI->getSrc().getType().isAddress(), + "checked_cast_addr_br src must be an address"); + require(CCABI->getDest().getType().isAddress(), + "checked_cast_addr_br dest must be an address"); + + require(CCABI->getSuccessBB()->bbarg_size() == 0, + "success dest block of checked_cast_addr_br must not take an argument"); + require(CCABI->getFailureBB()->bbarg_size() == 0, + "failure dest block of checked_cast_addr_br must not take an argument"); + } + void checkThinToThickFunctionInst(ThinToThickFunctionInst *TTFI) { auto opFTy = requireObjectType(SILFunctionType, TTFI->getOperand(), "thin_to_thick_function operand"); @@ -2055,6 +2089,8 @@ class SILVerifier : public SILVerifierBase { auto operandType = I->getOperand().getType().getSwiftRValueType(); auto resultType = requireObjectType(UnownedStorageType, I, "Result of ref_to_unowned"); + require(resultType->isLoadable(ResilienceExpansion::Maximal), + "ref_to_unowned requires unowned type to be loadable"); require(resultType.getReferentType() == operandType, "Result of ref_to_unowned does not have the " "operand's type as its referent type"); @@ -2064,6 +2100,8 @@ class SILVerifier : public SILVerifierBase { auto operandType = requireObjectType(UnownedStorageType, I->getOperand(), "Operand of unowned_to_ref"); + require(operandType->isLoadable(ResilienceExpansion::Maximal), + "unowned_to_ref requires unowned type to be loadable"); requireReferenceStorageCapableValue(I, "Result of unowned_to_ref"); auto resultType = I->getType().getSwiftRValueType(); require(operandType.getReferentType() == resultType, @@ -2302,25 +2340,6 @@ class SILVerifier : public SILVerifierBase { "return value type does not match return type of function"); } - void checkAutoreleaseReturnInst(AutoreleaseReturnInst *RI) { - DEBUG(RI->print(llvm::dbgs())); - - CanSILFunctionType ti = F.getLoweredFunctionType(); - SILType functionResultType - = F.mapTypeIntoContext(ti->getResult().getSILType()); - SILType instResultType = RI->getOperand().getType(); - DEBUG(llvm::dbgs() << "function return type: "; - functionResultType.dump(); - llvm::dbgs() << "return inst type: "; - instResultType.dump();); - require(functionResultType == instResultType, - "return value type does not match return type of function"); - require(instResultType.isObject(), - "autoreleased return value cannot be an address"); - require(instResultType.hasRetainablePointerRepresentation(), - "autoreleased return value must be a reference type"); - } - void checkThrowInst(ThrowInst *TI) { DEBUG(TI->print(llvm::dbgs())); @@ -2530,7 +2549,7 @@ class SILVerifier : public SILVerifierBase { void checkSwitchEnumAddrInst(SwitchEnumAddrInst *SOI){ require(SOI->getOperand().getType().isAddress(), - "switch_enum_addr operand must be an object"); + "switch_enum_addr operand must be an address"); SILType uTy = SOI->getOperand().getType(); EnumDecl *uDecl = uTy.getEnumOrBoundGenericEnum(); @@ -2584,6 +2603,12 @@ class SILVerifier : public SILVerifierBase { } void checkCondBranchInst(CondBranchInst *CBI) { + // It is important that cond_br keeps an i1 type. ARC Sequence Opts assumes + // that cond_br does not use reference counted values or decrement reference + // counted values under the assumption that the instruction that computes + // the i1 is the use/decrement that ARC cares about and that after that + // instruction is evaluated, the scalar i1 has a different identity and the + // object can be deallocated. require(CBI->getCondition().getType() == SILType::getBuiltinIntegerType(1, CBI->getCondition().getType().getASTContext()), @@ -2662,8 +2687,10 @@ class SILVerifier : public SILVerifierBase { require(invokeTy->getParameters().size() >= 1, "invoke function must take at least one parameter"); auto storageParam = invokeTy->getParameters()[0]; - require(storageParam.getConvention() == ParameterConvention::Indirect_Inout, - "invoke function must take block storage as @inout parameter"); + require(storageParam.getConvention() == + ParameterConvention::Indirect_InoutAliasable, + "invoke function must take block storage as @inout_aliasable " + "parameter"); require(storageParam.getType() == storageTy, "invoke function must take block storage type as first parameter"); @@ -2769,12 +2796,13 @@ class SILVerifier : public SILVerifierBase { return false; case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: case ParameterConvention::Indirect_In_Guaranteed: return true; } }), - "entry point address argument must have a nonaliasing calling " + "entry point address argument must have an indirect calling " "convention"); } @@ -2802,15 +2830,13 @@ class SILVerifier : public SILVerifierBase { return true; else if (isa(StartBlock->getTerminator())) return false; - else if (isa(StartBlock->getTerminator())) - return false; else if (isa(StartBlock->getTerminator())) return false; // Recursively check all successors. - for (const auto &SuccBB : StartBlock->getSuccessors()) - if (!Visited.insert(SuccBB.getBB()).second) - if (!isUnreachableAlongAllPathsStartingAt(SuccBB.getBB(), Visited)) + for (auto *SuccBB : StartBlock->getSuccessorBlocks()) + if (!Visited.insert(SuccBB).second) + if (!isUnreachableAlongAllPathsStartingAt(SuccBB, Visited)) return false; return true; @@ -2859,8 +2885,7 @@ class SILVerifier : public SILVerifierBase { "stack dealloc does not match most recent stack alloc"); stack.pop_back(); } - if (isa(&i) || isa(&i) || - isa(&i)) { + if (isa(&i) || isa(&i)) { require(stack.empty(), "return with stack allocs that haven't been deallocated"); } @@ -2927,25 +2952,20 @@ class SILVerifier : public SILVerifierBase { void visitSILBasicBlock(SILBasicBlock *BB) { // Make sure that each of the successors/predecessors of this basic block // have this basic block in its predecessor/successor list. - for (const SILSuccessor &S : BB->getSuccessors()) { - SILBasicBlock *SuccBB = S.getBB(); + for (const auto *SuccBB : BB->getSuccessorBlocks()) { bool FoundSelfInSuccessor = false; - for (const SILBasicBlock *PredBB : SuccBB->getPreds()) { - if (PredBB == BB) { - FoundSelfInSuccessor = true; - break; - } + if (SuccBB->isPredecessor(BB)) { + FoundSelfInSuccessor = true; + break; } require(FoundSelfInSuccessor, "Must be a predecessor of each successor."); } for (const SILBasicBlock *PredBB : BB->getPreds()) { bool FoundSelfInPredecessor = false; - for (const SILSuccessor &S : PredBB->getSuccessors()) { - if (S.getBB() == BB) { - FoundSelfInPredecessor = true; - break; - } + if (PredBB->isSuccessor(BB)) { + FoundSelfInPredecessor = true; + break; } require(FoundSelfInPredecessor, "Must be a successor of each predecessor."); } diff --git a/lib/SILAnalysis/ARCAnalysis.cpp b/lib/SILAnalysis/ARCAnalysis.cpp deleted file mode 100644 index 60433ecb4701e..0000000000000 --- a/lib/SILAnalysis/ARCAnalysis.cpp +++ /dev/null @@ -1,855 +0,0 @@ -//===-------------- ARCAnalysis.cpp - SIL ARC Analysis --------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-arc-analysis" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/Basic/Fallthrough.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILInstruction.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Utils/Local.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/Debug.h" - -using namespace swift; - -//===----------------------------------------------------------------------===// -// Decrement Analysis -//===----------------------------------------------------------------------===// - -static bool isKnownToNotDecrementRefCount(FunctionRefInst *FRI) { - return llvm::StringSwitch(FRI->getReferencedFunction()->getName()) - .Case("swift_keepAlive", true) - .Default(false); -} - -static bool canApplyDecrementRefCount(OperandValueArrayRef Ops, SILValue Ptr, - AliasAnalysis *AA) { - // Ok, this apply *MAY* decrement ref counts. Now our strategy is to attempt - // to use properties of the pointer, the function's arguments, and the - // function itself to prove that the pointer cannot have its ref count - // affected by the applied function. - - // TODO: Put in function property check section here when we get access to - // such information. - - // First make sure that the underlying object of ptr is a local object which - // does not escape. This prevents the apply from indirectly via the global - // affecting the reference count of the pointer. - if (!isNonEscapingLocalObject(getUnderlyingObject(Ptr))) - return true; - - // Now that we know that the function can not affect the pointer indirectly, - // make sure that the apply can not affect the pointer directly via the - // applies arguments by proving that the pointer can not alias any of the - // functions arguments. - for (auto Op : Ops) { - for (int i = 0, e = Ptr->getNumTypes(); i < e; i++) { - if (!AA->isNoAlias(Op, SILValue(Ptr.getDef(), i))) - return true; - } - } - - // Success! The apply inst can not affect the reference count of ptr! - return false; -} - -static bool canApplyDecrementRefCount(ApplyInst *AI, SILValue Ptr, - AliasAnalysis *AA) { - // Ignore any thick functions for now due to us not handling the ref-counted - // nature of its context. - if (auto FTy = AI->getCallee().getType().getAs()) - if (FTy->getExtInfo().hasContext()) - return true; - - // Treat applications of @noreturn functions as decrementing ref counts. This - // causes the apply to become a sink barrier for ref count increments. - if (AI->getCallee().getType().getAs()->isNoReturn()) - return true; - - // swift_keepAlive can not retain values. Remove this when we get rid of that. - if (auto *FRI = dyn_cast(AI->getCallee())) - if (isKnownToNotDecrementRefCount(FRI)) - return false; - - return canApplyDecrementRefCount(AI->getArgumentsWithoutIndirectResult(), - Ptr, AA); -} - -static bool canBuiltinNeverDecrementRefCounts(BuiltinInst *BI) { - // If we have a builtin that is side effect free, we can commute the - // builtin and the retain. - if (!BI->mayHaveSideEffects()) - return true; - - // If this is an instruction which might have side effect, but its side - // effects do not cause reference counts to be decremented, return false. - // - // If this is expanded, refactor it into a method with a string switch. - if (auto Kind = BI->getBuiltinKind()) { - switch (Kind.getValue()) { - case BuiltinValueKind::CopyArray: - return true; - default: - break; - } - } - - if (auto ID = BI->getIntrinsicID()) { - switch (ID.getValue()) { - case llvm::Intrinsic::memcpy: - case llvm::Intrinsic::memmove: - case llvm::Intrinsic::memset: - return true; - default: - break; - } - } - - return false; -} - -static bool canApplyDecrementRefCount(BuiltinInst *BI, SILValue Ptr, - AliasAnalysis *AA) { - if (canBuiltinNeverDecrementRefCounts(BI)) - return false; - - return canApplyDecrementRefCount(BI->getArguments(), Ptr, AA); -} - -/// Is the may have side effects user by the definition of its value kind unable -/// to decrement ref counts. -/// -/// Although is_unique will never decrement a refcount, it must appear to do so -/// from the perspective of the optimizer. This forces a separate retain to be -/// preserved for any original source level copy. -static bool canDecrementRefCountsByValueKind(SILInstruction *User) { - assert(User->getMemoryBehavior() - == SILInstruction::MemoryBehavior::MayHaveSideEffects && - "Invalid argument. Function is only applicable to isntructions with " - "side effects."); - switch (User->getKind()) { - case ValueKind::DeallocStackInst: - case ValueKind::StrongRetainInst: - case ValueKind::StrongRetainAutoreleasedInst: - case ValueKind::StrongRetainUnownedInst: - case ValueKind::UnownedRetainInst: - case ValueKind::RetainValueInst: - case ValueKind::PartialApplyInst: - case ValueKind::FixLifetimeInst: - case ValueKind::CopyBlockInst: - case ValueKind::CondFailInst: - case ValueKind::StrongPinInst: - return false; - - case ValueKind::CopyAddrInst: - // We only decrement ref counts if we are not initializing dest. - return !cast(User)->isInitializationOfDest(); - - case ValueKind::CheckedCastAddrBranchInst: { - // If we do not take on success, we do not touch ref counts. - auto *CCABI = cast(User); - return shouldTakeOnSuccess(CCABI->getConsumptionKind()); - } - default: - return true; - } -} - -bool swift::mayDecrementRefCount(SILInstruction *User, - SILValue Ptr, AliasAnalysis *AA) { - // If we have an instruction that does not have *pure* side effects, it can - // not affect ref counts. - // - // This distinguishes in between a "write" side effect and ref count side - // effects. - if (User->getMemoryBehavior() != - SILInstruction::MemoryBehavior::MayHaveSideEffects) - return false; - - // Ok, we know that this instruction's generic behavior is - // "MayHaveSideEffects". That is a criterion (it has effects not represented - // by use-def chains) that is broader than ours (does it effect a particular - // pointers ref counts). Thus begin by attempting to prove that the type of - // instruction that the user is by definition can not decrement ref counts. - if (!canDecrementRefCountsByValueKind(User)) - return false; - - // Ok, this instruction may have ref counts. If it is an apply, attempt to - // prove that the callee is unable to affect Ptr. - if (auto *AI = dyn_cast(User)) - return canApplyDecrementRefCount(AI, Ptr, AA); - if (auto *BI = dyn_cast(User)) - return canApplyDecrementRefCount(BI, Ptr, AA); - - // We can not conservatively prove that this instruction can not decrement the - // ref count of Ptr. So assume that it does. - return true; -} - -bool swift::mayCheckRefCount(SILInstruction *User) { - return isa(User) || isa(User); -} - -// Attempt to prove conservatively that Inst can never decrement reference -// counts -bool swift::canNeverDecrementRefCounts(SILInstruction *Inst) { - if (Inst->getMemoryBehavior() != - SILInstruction::MemoryBehavior::MayHaveSideEffects) - return true; - - if (!canDecrementRefCountsByValueKind(Inst)) - return true; - - if (auto *BI = dyn_cast(Inst)) - return canBuiltinNeverDecrementRefCounts(BI); - - // We can not prove that Inst can never decrement or use ref counts. Be - // conservative. - return false; -} - -//===----------------------------------------------------------------------===// -// Use Analysis -//===----------------------------------------------------------------------===// - -/// Returns true if a builtin apply can not use reference counted values. -/// -/// The main case that this handles here are builtins that via read none imply -/// that they can not read globals and at the same time do not take any -/// non-trivial types via the arguments. The reason why we care about taking -/// non-trivial types as arguments is that we want to be careful in the face of -/// intrinsics that may be equivalent to bitcast and inttoptr operations. -static bool canApplyOfBuiltinUseNonTrivialValues(BuiltinInst *BInst) { - SILModule &Mod = BInst->getModule(); - - auto &II = BInst->getIntrinsicInfo(); - if (II.ID != llvm::Intrinsic::not_intrinsic) { - if (II.hasAttribute(llvm::Attribute::ReadNone)) { - for (auto &Op : BInst->getAllOperands()) { - if (!Op.get().getType().isTrivial(Mod)) { - return false; - } - } - } - - return true; - } - - auto &BI = BInst->getBuiltinInfo(); - if (BI.isReadNone()) { - for (auto &Op : BInst->getAllOperands()) { - if (!Op.get().getType().isTrivial(Mod)) { - return false; - } - } - } - - return true; -} - -/// Returns true if Inst is a function that we know never uses ref count values. -bool swift::canNeverUseValues(SILInstruction *Inst) { - switch (Inst->getKind()) { - // These instructions do not use other values. - case ValueKind::FunctionRefInst: - case ValueKind::IntegerLiteralInst: - case ValueKind::FloatLiteralInst: - case ValueKind::StringLiteralInst: - case ValueKind::AllocStackInst: - case ValueKind::AllocRefInst: - case ValueKind::AllocRefDynamicInst: - case ValueKind::AllocBoxInst: - case ValueKind::MetatypeInst: - case ValueKind::WitnessMethodInst: - return true; - - // DeallocStackInst do not use reference counted values, only local storage - // handles. - case ValueKind::DeallocStackInst: - return true; - - // Debug values do not use referenced counted values in a manner we care - // about. - case ValueKind::DebugValueInst: - case ValueKind::DebugValueAddrInst: - return true; - - // Casts do not use pointers in a manner that we care about since we strip - // them during our analysis. The reason for this is if the cast is not dead - // then there must be some other use after the cast that we will protect if a - // release is not in between the cast and the use. - case ValueKind::UpcastInst: - case ValueKind::AddressToPointerInst: - case ValueKind::PointerToAddressInst: - case ValueKind::UncheckedRefCastInst: - case ValueKind::UncheckedRefCastAddrInst: - case ValueKind::UncheckedAddrCastInst: - case ValueKind::RefToRawPointerInst: - case ValueKind::RawPointerToRefInst: - case ValueKind::UnconditionalCheckedCastInst: - case ValueKind::UncheckedBitwiseCastInst: - return true; - - // If we have a trivial bit cast between trivial types, it is not something - // that can use ref count ops in a way we care about. We do need to be careful - // with uses with ref count inputs. In such a case, we assume conservatively - // that the bit cast could use it. - // - // The reason why this is different from the ref bitcast is b/c the use of a - // ref bit cast is still a ref typed value implying that our ARC dataflow will - // properly handle its users. A conversion of a reference count value to a - // trivial value though could be used as a trivial value in ways that ARC - // dataflow will not understand implying we need to treat it as a use to be - // safe. - case ValueKind::UncheckedTrivialBitCastInst: { - SILValue Op = cast(Inst)->getOperand(); - return Op.getType().isTrivial(Inst->getModule()); - } - - // Typed GEPs do not use pointers. The user of the typed GEP may but we will - // catch that via the dataflow. - case ValueKind::StructExtractInst: - case ValueKind::TupleExtractInst: - case ValueKind::StructElementAddrInst: - case ValueKind::TupleElementAddrInst: - case ValueKind::UncheckedTakeEnumDataAddrInst: - case ValueKind::RefElementAddrInst: - case ValueKind::UncheckedEnumDataInst: - case ValueKind::IndexAddrInst: - case ValueKind::IndexRawPointerInst: - return true; - - // Aggregate formation by themselves do not create new uses since it is their - // users that would create the appropriate uses. - case ValueKind::EnumInst: - case ValueKind::StructInst: - case ValueKind::TupleInst: - return true; - - // Only uses non reference counted values. - case ValueKind::CondFailInst: - return true; - - case ValueKind::BuiltinInst: { - auto *BI = cast(Inst); - - // Certain builtin function refs we know can never use non-trivial values. - return canApplyOfBuiltinUseNonTrivialValues(BI); - } - - default: - return false; - } -} - -static bool doOperandsAlias(ArrayRef Ops, SILValue Ptr, - AliasAnalysis *AA) { - // If any are not no alias, we have a use. - return std::any_of(Ops.begin(), Ops.end(), - [&AA, &Ptr](const Operand &Op) -> bool { - return !AA->isNoAlias(Ptr, Op.get()); - }); -} - -static bool canTerminatorUseValue(TermInst *TI, SILValue Ptr, - AliasAnalysis *AA) { - if (auto *BI = dyn_cast(TI)) { - return doOperandsAlias(BI->getAllOperands(), Ptr, AA); - } - - if (auto *CBI = dyn_cast(TI)) { - bool First = doOperandsAlias(CBI->getTrueOperands(), Ptr, AA); - bool Second = doOperandsAlias(CBI->getFalseOperands(), Ptr, AA); - return First || Second; - } - - if (auto *SWEI = dyn_cast(TI)) { - return doOperandsAlias(SWEI->getAllOperands(), Ptr, AA); - } - - if (auto *SWVI = dyn_cast(TI)) { - return doOperandsAlias(SWVI->getAllOperands(), Ptr, AA); - } - - auto *CCBI = dyn_cast(TI); - // If we don't have this last case, be conservative and assume that we can use - // the value. - if (!CCBI) - return true; - - // Otherwise, look at the operands. - return doOperandsAlias(CCBI->getAllOperands(), Ptr, AA); -} - -bool swift::mayUseValue(SILInstruction *User, SILValue Ptr, - AliasAnalysis *AA) { - // If Inst is an instruction that we know can never use values with reference - // semantics, return true. - if (canNeverUseValues(User)) - return false; - - // If the user is a load or a store and we can prove that it does not access - // the object then return true. - // Notice that we need to check all of the values of the object. - if (isa(User)) { - for (int i = 0, e = Ptr->getNumTypes(); i < e; i++) { - if (AA->mayWriteToMemory(User, SILValue(Ptr.getDef(), i))) - return true; - } - return false; - } - - if (isa(User) ) { - for (int i = 0, e = Ptr->getNumTypes(); i < e; i++) { - if (AA->mayReadFromMemory(User, SILValue(Ptr.getDef(), i))) - return true; - } - return false; - } - - // If we have a terminator instruction, see if it can use ptr. This currently - // means that we first show that TI can not indirectly use Ptr and then use - // alias analysis on the arguments. - if (auto *TI = dyn_cast(User)) - return canTerminatorUseValue(TI, Ptr, AA); - - // TODO: If we add in alias analysis support here for apply inst, we will need - // to check that the pointer does not escape. - - // Otherwise, assume that Inst can use Target. - return true; -} - -//===----------------------------------------------------------------------===// -// Must Use Analysis -//===----------------------------------------------------------------------===// - -/// Returns true if User must use Ptr. -/// -/// In terms of ARC this means that if we do not remove User, all releases post -/// dominated by User are known safe. -bool swift::mustUseValue(SILInstruction *User, SILValue Ptr, - AliasAnalysis *AA) { - // Right now just pattern match applies. - auto *AI = dyn_cast(User); - if (!AI) - return false; - - // If any of AI's arguments must alias Ptr, return true. - for (SILValue Arg : AI->getArguments()) - if (AA->isMustAlias(Arg, Ptr)) - return true; - return false; -} - -/// Returns true if User must use Ptr in a guaranteed way. -/// -/// This means that assuming that everything is conservative, we can ignore the -/// ref count effects of User on Ptr since we will only remove things over -/// guaranteed parameters if we are known safe in both directions. -bool swift::mustGuaranteedUseValue(SILInstruction *User, SILValue Ptr, - AliasAnalysis *AA) { - // Right now just pattern match applies. - auto *AI = dyn_cast(User); - if (!AI) - return false; - - // For now just look for guaranteed self. - // - // TODO: Expand this to handle *any* guaranteed parameter. - if (!AI->hasGuaranteedSelfArgument()) - return false; - - // Return true if Ptr alias's self. - return AA->isMustAlias(AI->getSelfArgument(), Ptr); -} - -//===----------------------------------------------------------------------===// -// Utility Methods for determining use, decrement of values in a contiguous -// instruction range in one BB. -//===----------------------------------------------------------------------===// - -/// If \p Op has arc uses in the instruction range [Start, End), return the -/// first such instruction. Otherwise return None. We assume that -/// Start and End are both in the same basic block. -Optional -swift:: -valueHasARCUsesInInstructionRange(SILValue Op, - SILBasicBlock::iterator Start, - SILBasicBlock::iterator End, - AliasAnalysis *AA) { - assert(Start->getParent() == End->getParent() && - "Start and End should be in the same basic block"); - - // If Start == End, then we have an empty range, return false. - if (Start == End) - return None; - - // Otherwise, until Start != End. - while (Start != End) { - // Check if Start can use Op in an ARC relevant way. If so, return true. - if (mayUseValue(&*Start, Op, AA)) - return Start; - - // Otherwise, increment our iterator. - ++Start; - } - - // If all such instructions can not use Op, return false. - return None; -} - -/// If \p Op has arc uses in the instruction range (Start, End], return the -/// first such instruction. Otherwise return None. We assume that Start and End -/// are both in the same basic block. -Optional -swift::valueHasARCUsesInReverseInstructionRange(SILValue Op, - SILBasicBlock::iterator Start, - SILBasicBlock::iterator End, - AliasAnalysis *AA) { - assert(Start->getParent() == End->getParent() && - "Start and End should be in the same basic block"); - assert(End != End->getParent()->end() && - "End should be mapped to an actual instruction"); - - // If Start == End, then we have an empty range, return false. - if (Start == End) - return None; - - // Otherwise, until End == Start. - while (Start != End) { - // Check if Start can use Op in an ARC relevant way. If so, return true. - if (mayUseValue(&*End, Op, AA)) - return End; - - // Otherwise, decrement our iterator. - --End; - } - - // If all such instructions can not use Op, return false. - return None; -} - -/// If \p Op has instructions in the instruction range (Start, End] which may -/// decrement it, return the first such instruction. Returns None -/// if no such instruction exists. We assume that Start and End are both in the -/// same basic block. -Optional -swift:: -valueHasARCDecrementOrCheckInInstructionRange(SILValue Op, - SILBasicBlock::iterator Start, - SILBasicBlock::iterator End, - AliasAnalysis *AA) { - assert(Start->getParent() == End->getParent() && - "Start and End should be in the same basic block"); - - // If Start == End, then we have an empty range, return nothing. - if (Start == End) - return None; - - // Otherwise, until Start != End. - while (Start != End) { - // Check if Start can decrement or check Op's ref count. If so, return - // Start. Ref count checks do not have side effects, but are barriers for - // retains. - if (mayDecrementRefCount(&*Start, Op, AA) || mayCheckRefCount(&*Start)) - return Start; - // Otherwise, increment our iterator. - ++Start; - } - - // If all such instructions can not decrement Op, return nothing. - return None; -} - -bool -swift:: -mayGuaranteedUseValue(SILInstruction *User, SILValue Ptr, AliasAnalysis *AA) { - // Only full apply sites can require a guaranteed lifetime. If we don't have - // one, bail. - if (!isa(User)) - return false; - - FullApplySite FAS(User); - - // Ok, we have a full apply site. If the apply has no arguments, we don't need - // to worry about any guaranteed parameters. - if (!FAS.getNumArguments()) - return false; - - // Ok, we have an apply site with arguments. Look at the function type and - // iterate through the function parameters. If any of the parameters are - // guaranteed, attempt to prove that the passed in parameter can not alias - // Ptr. If we fail, return true. - CanSILFunctionType FType = FAS.getSubstCalleeType(); - auto Params = FType->getParameters(); - for (unsigned i : indices(Params)) { - if (!Params[i].isGuaranteed()) - continue; - SILValue Op = FAS.getArgument(i); - for (int i = 0, e = Ptr->getNumTypes(); i < e; i++) - if (!AA->isNoAlias(Op, SILValue(Ptr.getDef(), i))) - return true; - } - - // Ok, we were able to prove that all arguments to the apply that were - // guaranteed do not alias Ptr. Return false. - return false; -} - -//===----------------------------------------------------------------------===// -// Utilities for recognizing trap BBs that are ARC inert -//===----------------------------------------------------------------------===// - -static bool ignoreableApplyInstInUnreachableBlock(ApplyInst *AI) { - const char *fatalName = - "_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_"; - auto *Fn = AI->getCalleeFunction(); - - // We use endswith here since if we specialize fatal error we will always - // prepend the specialization records to fatalName. - if (!Fn || !Fn->getName().endswith(fatalName)) - return false; - - return true; -} - -static bool ignoreableBuiltinInstInUnreachableBlock(BuiltinInst *BI) { - const BuiltinInfo &BInfo = BI->getBuiltinInfo(); - if (BInfo.ID == BuiltinValueKind::CondUnreachable) - return true; - - const IntrinsicInfo &IInfo = BI->getIntrinsicInfo(); - if (IInfo.ID == llvm::Intrinsic::trap) - return true; - - return false; -} - -/// Match a call to a trap BB with no ARC relevant side effects. -bool swift::isARCInertTrapBB(SILBasicBlock *BB) { - // Do a quick check at the beginning to make sure that our terminator is - // actually an unreachable. This ensures that in many cases this function will - // exit early and quickly. - auto II = BB->rbegin(); - if (!isa(*II)) - return false; - - auto IE = BB->rend(); - while (II != IE) { - // Ignore any instructions without side effects. - if (!II->mayHaveSideEffects()) { - ++II; - continue; - } - - // Ignore cond fail. - if (isa(*II)) { - ++II; - continue; - } - - // Check for apply insts that we can ignore. - if (auto *AI = dyn_cast(&*II)) { - if (ignoreableApplyInstInUnreachableBlock(AI)) { - ++II; - continue; - } - } - - // Check for builtins that we can ignore. - if (auto *BI = dyn_cast(&*II)) { - if (ignoreableBuiltinInstInUnreachableBlock(BI)) { - ++II; - continue; - } - } - - // If we can't ignore the instruction, return false. - return false; - } - - // Otherwise, we have an unreachable and every instruction is inert from an - // ARC perspective in an unreachable BB. - return true; -} - -//===----------------------------------------------------------------------===// -// Owned Argument Utilities -//===----------------------------------------------------------------------===// - -ConsumedArgToEpilogueReleaseMatcher:: -ConsumedArgToEpilogueReleaseMatcher(RCIdentityFunctionInfo *RCIA, - SILFunction *F) { - // Find the return BB of F. If we fail, then bail. - auto ReturnBB = F->findReturnBB(); - if (ReturnBB != F->end()) - findMatchingReleases(RCIA, &*ReturnBB); -} - -void ConsumedArgToEpilogueReleaseMatcher:: -findMatchingReleases(RCIdentityFunctionInfo *RCIA, SILBasicBlock *BB) { - for (auto II = std::next(BB->rbegin()), IE = BB->rend(); - II != IE; ++II) { - // If we do not have a release_value or strong_release... - if (!isa(*II) && !isa(*II)) { - // And the object can not use values in a manner that will keep the object - // alive, continue. We may be able to find additional releases. - if (canNeverUseValues(&*II)) - continue; - - // Otherwise, we need to stop computing since we do not want to reduce the - // lifetime of objects. - return; - } - - // Ok, we have a release_value or strong_release. Grab Target and find the - // RC identity root of its operand. - SILInstruction *Target = &*II; - SILValue Op = RCIA->getRCIdentityRoot(Target->getOperand(0)); - - // If Op is not a consumed argument, we must break since this is not an Op - // that is a part of a return sequence. We are being conservative here since - // we could make this more general by allowing for intervening non-arg - // releases in the sense that we do not allow for race conditions in between - // destructors. - auto *Arg = dyn_cast(Op); - if (!Arg || !Arg->isFunctionArg() || - !Arg->hasConvention(ParameterConvention::Direct_Owned)) - return; - - // Ok, we have a release on a SILArgument that is direct owned. Attempt to - // put it into our arc opts map. If we already have it, we have exited the - // return value sequence so break. Otherwise, continue looking for more arc - // operations. - if (!ArgInstMap.insert({Arg, Target}).second) - return; - } -} - -//===----------------------------------------------------------------------===// -// Code for Determining Final Releases -//===----------------------------------------------------------------------===// - -// Propagate liveness backwards from an initial set of blocks in our -// LiveIn set. -static void propagateLiveness(llvm::SmallPtrSetImpl &LiveIn, - SILBasicBlock *DefBB) { - // First populate a worklist of predecessors. - llvm::SmallVector Worklist; - for (auto *BB : LiveIn) - for (auto Pred : BB->getPreds()) - Worklist.push_back(Pred); - - // Now propagate liveness backwards until we hit the alloc_box. - while (!Worklist.empty()) { - auto *BB = Worklist.pop_back_val(); - - // If it's already in the set, then we've already queued and/or - // processed the predecessors. - if (BB == DefBB || !LiveIn.insert(BB).second) - continue; - - for (auto Pred : BB->getPreds()) - Worklist.push_back(Pred); - } -} - -// Is any successor of BB in the LiveIn set? -static bool successorHasLiveIn(SILBasicBlock *BB, - llvm::SmallPtrSetImpl &LiveIn) { - for (auto &Succ : BB->getSuccessors()) - if (LiveIn.count(Succ)) - return true; - - return false; -} - -// Walk backwards in BB looking for the last use of a given -// value, and add it to the set of release points. -static bool addLastUse(SILValue V, SILBasicBlock *BB, - ReleaseTracker &Tracker) { - for (auto I = BB->rbegin(); I != BB->rend(); ++I) { - for (auto &Op : I->getAllOperands()) - if (Op.get().getDef() == V.getDef()) { - Tracker.trackLastRelease(&*I); - return true; - } - } - - llvm_unreachable("BB is expected to have a use of a closure"); - return false; -} - -/// TODO: Refactor this code so the decision on whether or not to accept an -/// instruction. -bool swift::getFinalReleasesForValue(SILValue V, ReleaseTracker &Tracker) { - llvm::SmallPtrSet LiveIn; - llvm::SmallPtrSet UseBlocks; - - // First attempt to get the BB where this value resides. - auto *DefBB = V->getParentBB(); - if (!DefBB) - return false; - - bool seenRelease = false; - SILInstruction *OneRelease = nullptr; - - // We'll treat this like a liveness problem where the value is the def. Each - // block that has a use of the value has the value live-in unless it is the - // block with the value. - for (auto *UI : V.getUses()) { - auto *User = UI->getUser(); - auto *BB = User->getParent(); - - if (!Tracker.isUserAcceptable(User)) - return false; - Tracker.trackUser(User); - - if (BB != DefBB) - LiveIn.insert(BB); - - // Also keep track of the blocks with uses. - UseBlocks.insert(BB); - - // Try to speed up the trivial case of single release/dealloc. - if (isa(User) || isa(User)) { - if (!seenRelease) - OneRelease = User; - else - OneRelease = nullptr; - - seenRelease = true; - } - } - - // Only a single release/dealloc? We're done! - if (OneRelease) { - Tracker.trackLastRelease(OneRelease); - return true; - } - - propagateLiveness(LiveIn, DefBB); - - // Now examine each block we saw a use in. If it has no successors - // that are in LiveIn, then the last use in the block is the final - // release/dealloc. - for (auto *BB : UseBlocks) - if (!successorHasLiveIn(BB, LiveIn)) - if (!addLastUse(V, BB, Tracker)) - return false; - - return true; -} diff --git a/lib/SILAnalysis/Analysis.cpp b/lib/SILAnalysis/Analysis.cpp deleted file mode 100644 index 3cefcdf468e92..0000000000000 --- a/lib/SILAnalysis/Analysis.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//===----- Analysis.cpp - Swift Analysis ----------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-analysis" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/IVAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/CallGraphAnalysis.h" -#include "swift/SILAnalysis/ClassHierarchyAnalysis.h" -#include "swift/AST/Module.h" -#include "swift/AST/SILOptions.h" -#include "swift/SIL/SILModule.h" -#include "swift/SIL/SILFunction.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/Debug.h" -#include "swift/SILPasses/Utils/Local.h" - -using namespace swift; - -void SILAnalysis::verifyFunction(SILFunction *F) { - // Only functions with bodies can be analyzed by the analysis. - assert(F->isDefinition() && "Can't analyze external functions"); -} - -SILAnalysis *swift::createCallGraphAnalysis(SILModule *M) { - return new CallGraphAnalysis(M); -} - -SILAnalysis *swift::createDominanceAnalysis(SILModule *) { - return new DominanceAnalysis(); -} - -SILAnalysis *swift::createPostDominanceAnalysis(SILModule *) { - return new PostDominanceAnalysis(); -} - -SILAnalysis *swift::createInductionVariableAnalysis(SILModule *M) { - return new IVAnalysis(M); -} - -SILAnalysis *swift::createPostOrderAnalysis(SILModule *M) { - return new PostOrderAnalysis(); -} - -SILAnalysis *swift::createClassHierarchyAnalysis(SILModule *M) { - return new ClassHierarchyAnalysis(M); -} - -SILAnalysis *swift::createBasicCalleeAnalysis(SILModule *M) { - return new BasicCalleeAnalysis(M); -} diff --git a/lib/SILAnalysis/ArraySemantic.cpp b/lib/SILAnalysis/ArraySemantic.cpp deleted file mode 100644 index 07f4624f17b35..0000000000000 --- a/lib/SILAnalysis/ArraySemantic.cpp +++ /dev/null @@ -1,549 +0,0 @@ -//===- ArraySemantic.cpp - Wrapper around array semantic calls. -*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/StringSwitch.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SIL/DebugUtils.h" -#include "swift/SIL/SILArgument.h" -#include "swift/SIL/SILBuilder.h" -#include "swift/SIL/SILFunction.h" - -using namespace swift; - -static ParameterConvention -getSelfParameterConvention(ApplyInst *SemanticsCall) { - FunctionRefInst *FRI = cast(SemanticsCall->getCallee()); - SILFunction *F = FRI->getReferencedFunction(); - auto FnTy = F->getLoweredFunctionType(); - - return FnTy->getSelfParameter().getConvention(); -} - -/// \brief Make sure that all parameters are passed with a reference count -/// neutral parameter convention except for self. -bool swift::ArraySemanticsCall::isValidSignature() { - assert(SemanticsCall && getKind() != ArrayCallKind::kNone && - "Need an array semantic call"); - FunctionRefInst *FRI = cast(SemanticsCall->getCallee()); - SILFunction *F = FRI->getReferencedFunction(); - auto FnTy = F->getLoweredFunctionType(); - auto &Mod = F->getModule(); - - // Check whether we have a valid signature for semantic calls that we hoist. - switch (getKind()) { - // All other calls can be consider valid. - default: break; - case ArrayCallKind::kArrayPropsIsNative: - case ArrayCallKind::kArrayPropsIsNativeTypeChecked: { - // @guaranteed/@owned Self - if (SemanticsCall->getNumArguments() != 1) - return false; - auto SelfConvention = FnTy->getSelfParameter().getConvention(); - return SelfConvention == ParameterConvention::Direct_Guaranteed || - SelfConvention == ParameterConvention::Direct_Owned; - } - case ArrayCallKind::kCheckIndex: { - // Int, @guaranteed/@owned Self - if (SemanticsCall->getNumArguments() != 2 || - !SemanticsCall->getArgument(0).getType().isTrivial(Mod)) - return false; - auto SelfConvention = FnTy->getSelfParameter().getConvention(); - return SelfConvention == ParameterConvention::Direct_Guaranteed || - SelfConvention == ParameterConvention::Direct_Owned; - } - case ArrayCallKind::kCheckSubscript: { - // Int, Bool, Self - if (SemanticsCall->getNumArguments() != 3 || - !SemanticsCall->getArgument(0).getType().isTrivial(Mod)) - return false; - if (!SemanticsCall->getArgument(1).getType().isTrivial(Mod)) - return false; - auto SelfConvention = FnTy->getSelfParameter().getConvention(); - return SelfConvention == ParameterConvention::Direct_Guaranteed || - SelfConvention == ParameterConvention::Direct_Owned; - } - case ArrayCallKind::kMakeMutable: { - auto SelfConvention = FnTy->getSelfParameter().getConvention(); - return SelfConvention == ParameterConvention::Indirect_Inout; - } - case ArrayCallKind::kArrayUninitialized: { - // Make sure that if we are a _adoptStorage call that our storage is - // uniquely referenced by us. - SILValue Arg0 = SemanticsCall->getArgument(0); - if (Arg0.getType().isExistentialType()) { - auto *AllocBufferAI = dyn_cast(Arg0); - if (!AllocBufferAI) - return false; - - auto *AllocFn = AllocBufferAI->getCalleeFunction(); - if (!AllocFn) - return false; - - StringRef AllocFuncName = AllocFn->getName(); - if (AllocFuncName != "swift_bufferAllocate" && - AllocFuncName != "swift_bufferAllocateOnStack") - return false; - - if (!hasOneNonDebugUse(*AllocBufferAI)) - return false; - } - return true; - } - } - - return true; -} - -/// Match array semantic calls. -swift::ArraySemanticsCall::ArraySemanticsCall(ValueBase *V, - StringRef SemanticStr, - bool MatchPartialName) { - if (auto *AI = dyn_cast(V)) - if (auto *Fn = AI->getCalleeFunction()) - if ((MatchPartialName && - (Fn->hasDefinedSemantics() && - Fn->getSemanticsString().startswith(SemanticStr))) || - (!MatchPartialName && Fn->hasSemanticsString(SemanticStr))) { - SemanticsCall = AI; - // Need a 'self' argument otherwise this is not a semantic call that - // we recognize. - if (getKind() < ArrayCallKind::kArrayInit && !hasSelf()) - SemanticsCall = nullptr; - - // A arguments must be passed reference count neutral except for self. - if (SemanticsCall && !isValidSignature()) - SemanticsCall = nullptr; - return; - } - // Otherwise, this is not the semantic call we are looking for. - SemanticsCall = nullptr; -} - -/// Determine which kind of array semantics call this is. -ArrayCallKind swift::ArraySemanticsCall::getKind() const { - if (!SemanticsCall) - return ArrayCallKind::kNone; - - auto F = cast(SemanticsCall->getCallee()) - ->getReferencedFunction(); - - auto Kind = - llvm::StringSwitch(F->getSemanticsString()) - .Case("array.props.isNative", ArrayCallKind::kArrayPropsIsNative) - .Case("array.props.isNativeTypeChecked", - ArrayCallKind::kArrayPropsIsNativeTypeChecked) - .Case("array.init", ArrayCallKind::kArrayInit) - .Case("array.uninitialized", ArrayCallKind::kArrayUninitialized) - .Case("array.check_subscript", ArrayCallKind::kCheckSubscript) - .Case("array.check_index", ArrayCallKind::kCheckIndex) - .Case("array.get_count", ArrayCallKind::kGetCount) - .Case("array.get_capacity", ArrayCallKind::kGetCapacity) - .Case("array.get_element", ArrayCallKind::kGetElement) - .Case("array.owner", ArrayCallKind::kGetArrayOwner) - .Case("array.make_mutable", ArrayCallKind::kMakeMutable) - .Case("array.get_element_address", ArrayCallKind::kGetElementAddress) - .Case("array.mutate_unknown", ArrayCallKind::kMutateUnknown) - .Default(ArrayCallKind::kNone); - - return Kind; -} - -bool swift::ArraySemanticsCall::hasSelf() const { - assert(SemanticsCall && "Must have a semantics call"); - // Array.init and Array.uninitialized return 'self' @owned. - return SemanticsCall->getOrigCalleeType()->hasSelfParam(); -} - -SILValue swift::ArraySemanticsCall::getSelf() const { - return SemanticsCall->getSelfArgument(); -} - -Operand &swift::ArraySemanticsCall::getSelfOperand() const { - return SemanticsCall->getSelfArgumentOperand(); -} - -bool swift::ArraySemanticsCall::hasGuaranteedSelf() const { - if (!hasSelf()) - return false; - return getSelfParameterConvention(SemanticsCall) == - ParameterConvention::Direct_Guaranteed; -} - -SILValue swift::ArraySemanticsCall::getIndex() const { - assert(SemanticsCall && "Must have a semantics call"); - assert(SemanticsCall->getNumArguments() && "Must have arguments"); - assert(getKind() == ArrayCallKind::kCheckSubscript || - getKind() == ArrayCallKind::kCheckIndex || - getKind() == ArrayCallKind::kGetElement || - getKind() == ArrayCallKind::kGetElementAddress); - - return SemanticsCall->getArgument(0); -} - -static bool canHoistArrayArgument(ApplyInst *SemanticsCall, SILValue Arr, - SILInstruction *InsertBefore, - DominanceInfo *DT) { - - // We only know how to hoist inout, owned or guaranteed parameters. - auto Convention = getSelfParameterConvention(SemanticsCall); - if (Convention != ParameterConvention::Indirect_Inout && - Convention != ParameterConvention::Direct_Owned && - Convention != ParameterConvention::Direct_Guaranteed) - return false; - - auto *SelfVal = Arr.getDef(); - auto *SelfBB = SelfVal->getParentBB(); - if (DT->dominates(SelfBB, InsertBefore->getParent())) - return true; - - if (auto LI = dyn_cast(SelfVal)) { - // Are we loading a value from an address in a struct defined at a point - // dominating the hoist point. - auto Val = LI->getOperand().getDef(); - bool DoesNotDominate; - StructElementAddrInst *SEI; - while ((DoesNotDominate = !DT->dominates(Val->getParentBB(), - InsertBefore->getParent())) && - (SEI = dyn_cast(Val))) - Val = SEI->getOperand().getDef(); - return DoesNotDominate == false; - } - - return false; -} - -bool swift::ArraySemanticsCall::canHoist(SILInstruction *InsertBefore, - DominanceInfo *DT) const { - auto Kind = getKind(); - switch (Kind) { - default: - break; - - case ArrayCallKind::kCheckIndex: - case ArrayCallKind::kArrayPropsIsNative: - case ArrayCallKind::kArrayPropsIsNativeTypeChecked: - case ArrayCallKind::kGetElementAddress: - case ArrayCallKind::kGetCount: - case ArrayCallKind::kGetCapacity: - return canHoistArrayArgument(SemanticsCall, getSelf(), InsertBefore, DT); - - case ArrayCallKind::kCheckSubscript: - case ArrayCallKind::kGetElement: { - auto IsNativeArg = getArrayPropertyIsNative(); - ArraySemanticsCall IsNative(IsNativeArg.getDef(), "array.props.isNative", - true); - if (!IsNative) { - // Do we have a constant parameter? - auto *SI = dyn_cast(IsNativeArg); - if (!SI) - return false; - if (!isa(SI->getOperand(0))) - return false; - } else if (!IsNative.canHoist(InsertBefore, DT)) - // Otherwise, we must be able to hoist the function call. - return false; - - if (Kind == ArrayCallKind::kCheckSubscript) - return canHoistArrayArgument(SemanticsCall, getSelf(), InsertBefore, DT); - - // Can we hoist the needsElementTypeCheck argument. - ArraySemanticsCall TypeCheck(getArrayPropertyNeedsTypeCheck().getDef(), - "array.props.needsElementTypeCheck", true); - if (!TypeCheck || !TypeCheck.canHoist(InsertBefore, DT)) - return false; - - return canHoistArrayArgument(SemanticsCall, getSelf(), InsertBefore, DT); - } - - case ArrayCallKind::kMakeMutable: { - return canHoistArrayArgument(SemanticsCall, getSelf(), InsertBefore, DT); - } - } // End switch. - - return false; -} - -/// Copy the array load to the insert point. -static SILValue copyArrayLoad(SILValue ArrayStructValue, - SILInstruction *InsertBefore, - DominanceInfo *DT) { - if (DT->dominates(ArrayStructValue.getDef()->getParentBB(), - InsertBefore->getParent())) - return ArrayStructValue; - - auto *LI = cast(ArrayStructValue.getDef()); - - // Recursively move struct_element_addr. - auto *Val = LI->getOperand().getDef(); - auto *InsertPt = InsertBefore; - while (!DT->dominates(Val->getParentBB(), InsertBefore->getParent())) { - auto *Inst = cast(Val); - Inst->moveBefore(InsertPt); - Val = Inst->getOperand().getDef(); - InsertPt = Inst; - } - - return SILValue(LI->clone(InsertBefore), 0); -} - -static ApplyInst *hoistOrCopyCall(ApplyInst *AI, SILInstruction *InsertBefore, - bool LeaveOriginal, DominanceInfo *DT) { - if (!LeaveOriginal) { - AI->moveBefore(InsertBefore); - } else { - // Leave the original and 'hoist' a clone. - AI = cast(AI->clone(InsertBefore)); - } - placeFuncRef(AI, DT); - return AI; -} - - -/// \brief Hoist or copy the self argument of the semantics call. -/// Return the hoisted self argument. -static SILValue hoistOrCopySelf(ApplyInst *SemanticsCall, - SILInstruction *InsertBefore, - DominanceInfo *DT, bool LeaveOriginal) { - - auto SelfConvention = getSelfParameterConvention(SemanticsCall); - - assert((SelfConvention == ParameterConvention::Direct_Owned || - SelfConvention == ParameterConvention::Direct_Guaranteed) && - "Expect @owned or @guaranteed self"); - - auto Self = SemanticsCall->getSelfArgument(); - bool IsOwnedSelf = SelfConvention == ParameterConvention::Direct_Owned; - - // Emit matching release for owned self if we are moving the original call. - if (!LeaveOriginal && IsOwnedSelf) - SILBuilderWithScope(SemanticsCall) - .createReleaseValue(SemanticsCall->getLoc(), Self); - - auto NewArrayStructValue = copyArrayLoad(Self, InsertBefore, DT); - - // Retain the array. - if (IsOwnedSelf) - SILBuilderWithScope(InsertBefore, SemanticsCall) - .createRetainValue(SemanticsCall->getLoc(), NewArrayStructValue); - - return NewArrayStructValue; -} - -ApplyInst *swift::ArraySemanticsCall::hoistOrCopy(SILInstruction *InsertBefore, - DominanceInfo *DT, - bool LeaveOriginal) { - assert(canHoist(InsertBefore, DT) && - "Must be able to hoist the semantics call"); - - auto Kind = getKind(); - switch (Kind) { - case ArrayCallKind::kArrayPropsIsNative: - case ArrayCallKind::kArrayPropsIsNativeTypeChecked: - case ArrayCallKind::kGetCount: - case ArrayCallKind::kGetCapacity: { - assert(SemanticsCall->getNumArguments() == 1 && - "Expect 'self' parameter only"); - - auto HoistedSelf = - hoistOrCopySelf(SemanticsCall, InsertBefore, DT, LeaveOriginal); - - auto *Call = - hoistOrCopyCall(SemanticsCall, InsertBefore, LeaveOriginal, DT); - Call->setSelfArgument(HoistedSelf); - return Call; - } - - case ArrayCallKind::kCheckSubscript: - case ArrayCallKind::kCheckIndex: { - auto HoistedSelf = - hoistOrCopySelf(SemanticsCall, InsertBefore, DT, LeaveOriginal); - - SILValue NewArrayProps; - if (Kind == ArrayCallKind::kCheckSubscript) { - // Copy the array.props argument call. - auto IsNativeArg = getArrayPropertyIsNative(); - ArraySemanticsCall IsNative(IsNativeArg.getDef(), "array.props.isNative", - true); - if (!IsNative) { - // Do we have a constant parameter? - auto *SI = dyn_cast(IsNativeArg); - assert(SI && isa(SI->getOperand(0)) && - "Must have a constant parameter or an array.props.isNative call " - "as argument"); - SI->moveBefore( - &*DT->findNearestCommonDominator(InsertBefore->getParent(), - SI->getParent())->begin()); - auto *IL = cast(SI->getOperand(0)); - IL->moveBefore( - &*DT->findNearestCommonDominator(InsertBefore->getParent(), - IL->getParent())->begin()); - } else { - NewArrayProps = IsNative.copyTo(InsertBefore, DT); - } - } - - // Hoist the call. - auto Call = hoistOrCopyCall(SemanticsCall, InsertBefore, LeaveOriginal, DT); - Call->setSelfArgument(HoistedSelf); - - if (NewArrayProps) { - // Set the array.props argument. - Call->setArgument(1, NewArrayProps); - } - - return Call; - } - - case ArrayCallKind::kMakeMutable: { - assert(!LeaveOriginal && "Copying not yet implemented"); - // Hoist the call. - auto Call = hoistOrCopyCall(SemanticsCall, InsertBefore, LeaveOriginal, DT); - return Call; - } - - default: - llvm_unreachable("Don't know how to hoist this instruction"); - break; - } // End switch. -} - -void swift::ArraySemanticsCall::removeCall() { - if (getSelfParameterConvention(SemanticsCall) == - ParameterConvention::Direct_Owned) - SILBuilderWithScope(SemanticsCall) - .createReleaseValue(SemanticsCall->getLoc(), getSelf()); - - SemanticsCall->eraseFromParent(); - SemanticsCall = nullptr; -} - -static bool hasArrayPropertyNeedsTypeCheck(ArrayCallKind Kind, - unsigned &ArgIdx) { - switch (Kind) { - default: break; - case ArrayCallKind::kGetElement: - ArgIdx = 2; - return true; - } - return false; -} -static bool hasArrayPropertyIsNative(ArrayCallKind Kind, unsigned &ArgIdx) { - switch (Kind) { - default: break; - - case ArrayCallKind::kCheckSubscript: - case ArrayCallKind::kGetElement: - ArgIdx = 1; - return true; - } - return false; -} - -SILValue swift::ArraySemanticsCall::getArrayPropertyIsNative() const { - unsigned ArgIdx = 0; - bool HasArg = hasArrayPropertyIsNative(getKind(), ArgIdx); - (void)HasArg; - assert(HasArg && - "Must have an array.props argument"); - - return SemanticsCall->getArgument(ArgIdx); -} - -SILValue swift::ArraySemanticsCall::getArrayPropertyNeedsTypeCheck() const { - unsigned ArgIdx = 0; - bool HasArg = hasArrayPropertyNeedsTypeCheck(getKind(), ArgIdx); - (void)HasArg; - assert(HasArg && - "Must have an array.props argument"); - - return SemanticsCall->getArgument(ArgIdx); -} - -bool swift::ArraySemanticsCall::mayHaveBridgedObjectElementType() const { - assert(hasSelf() && "Need self parameter"); - - auto Ty = getSelf().getType().getSwiftRValueType(); - auto Cannonical = Ty.getCanonicalTypeOrNull(); - if (Cannonical.isNull()) - return true; - - auto *Struct = Cannonical->getStructOrBoundGenericStruct(); - assert(Struct && "Array must be a struct !?"); - if (Struct) { - auto BGT = dyn_cast(Ty); - if (!BGT) - return true; - - // Check the array element type parameter. - bool isClass = true; - for (auto TP : BGT->getGenericArgs()) { - auto EltTy = TP.getCanonicalTypeOrNull(); - if (EltTy.isNull()) - return true; - if (EltTy->isBridgeableObjectType()) - return true; - isClass = false; - } - return isClass; - } - return true; -} - -SILValue swift::ArraySemanticsCall::getInitializationCount() const { - if (getKind() == ArrayCallKind::kArrayUninitialized) { - // Can be either a call to _adoptStorage or _allocateUninitialized. - // A call to _adoptStorage has the buffer as AnyObject as the first - // argument. The count is the second argument. - // A call to _allocateUninitialized has the count as first argument. - SILValue Arg0 = SemanticsCall->getArgument(0); - if (Arg0.getType().isExistentialType()) - return SemanticsCall->getArgument(1); - else return SemanticsCall->getArgument(0); - } - - if (getKind() == ArrayCallKind::kArrayInit && - SemanticsCall->getNumArguments() == 3) - return SemanticsCall->getArgument(0); - - return SILValue(); -} - -SILValue swift::ArraySemanticsCall::getArrayValue() const { - if (getKind() == ArrayCallKind::kArrayUninitialized) { - TupleExtractInst *ArrayDef = nullptr; - for (auto *Op : SemanticsCall->getUses()) { - auto *TupleElt = dyn_cast(Op->getUser()); - if (!TupleElt) - return SILValue(); - switch (TupleElt->getFieldNo()) { - default: - return SILValue(); - case 0: { - // Should only have one tuple extract after CSE. - if (ArrayDef) - return SILValue(); - ArrayDef = TupleElt; - break; - } - case 1: /*Ignore the storage address */ break; - } - } - return SILValue(ArrayDef); - } - - if(getKind() == ArrayCallKind::kArrayInit) - return SILValue(SemanticsCall); - - return SILValue(); -} diff --git a/lib/SILAnalysis/CFG.cpp b/lib/SILAnalysis/CFG.cpp deleted file mode 100644 index df945b4478ad5..0000000000000 --- a/lib/SILAnalysis/CFG.cpp +++ /dev/null @@ -1,96 +0,0 @@ -//===--- CFG.cpp ----------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#include "swift/SILAnalysis/CFG.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILInstruction.h" -#include "swift/SIL/SILValue.h" -#include "llvm/ADT/TinyPtrVector.h" - -using namespace swift; - -static bool isSafeNonExitTerminator(TermInst *TI) { - switch (TI->getKind()) { - case ValueKind::BranchInst: - case ValueKind::CondBranchInst: - case ValueKind::SwitchValueInst: - case ValueKind::SwitchEnumInst: - case ValueKind::SwitchEnumAddrInst: - case ValueKind::DynamicMethodBranchInst: - case ValueKind::CheckedCastBranchInst: - case ValueKind::CheckedCastAddrBranchInst: - return true; - default: - return false; - } -} - -static bool isTrapNoReturnFunction(ApplyInst *AI) { - const char *fatalName = - "_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_"; - auto *Fn = AI->getCalleeFunction(); - - // We use endswith here since if we specialize fatal error we will always - // prepend the specialization records to fatalName. - if (!Fn || !Fn->getName().endswith(fatalName)) - return false; - - return true; -} - -/// TODO: Add support for autorelease_return. This is not implemented now to -/// cause this to always fail in functions with objc calling convention. -bool -swift:: -findAllNonFailureExitBBs(SILFunction *F, - llvm::TinyPtrVector &BBs) { - for (SILBasicBlock &BB : *F) { - TermInst *TI = BB.getTerminator(); - - // If we know that this terminator is not an exit terminator, continue. - if (isSafeNonExitTerminator(TI)) - continue; - - // A return inst is always a non-failure exit bb. - if (isa(TI)) { - BBs.push_back(&BB); - continue; - } - - // If we don't have an unreachable inst at this point, this is a terminator - // we don't understand. Be conservative and return false. - if (!isa(TI)) - return false; - - // Ok, at this point we know we have a terminator. If it is the only - // instruction in our BB, it is a failure BB. continue... - if (TI == &*BB.begin()) - continue; - - // If the unreachable is preceded by a no-return apply inst, then it is a - // non-failure exit BB. Add it to our list and continue. - auto PrevIter = std::prev(SILBasicBlock::iterator(TI)); - if (auto *AI = dyn_cast(&*PrevIter)) { - if (AI->getSubstCalleeType()->isNoReturn() && - !isTrapNoReturnFunction(AI)) { - BBs.push_back(&BB); - continue; - } - } - - // Otherwise, it must be a failure BB where we leak, continue. - continue; - } - - // We understood all terminators, return true. - return true; -} diff --git a/lib/SILAnalysis/CMakeLists.txt b/lib/SILAnalysis/CMakeLists.txt deleted file mode 100644 index ee0c868002eac..0000000000000 --- a/lib/SILAnalysis/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -add_swift_library(swiftSILAnalysis - ARCAnalysis.cpp - AliasAnalysis.cpp - Analysis.cpp - ArraySemantic.cpp - BasicCalleeAnalysis.cpp - CFG.cpp - CallGraph.cpp - ClassHierarchyAnalysis.cpp - ColdBlockInfo.cpp - DestructorAnalysis.cpp - EscapeAnalysis.cpp - FunctionOrder.cpp - IVAnalysis.cpp - LoopAnalysis.cpp - LoopRegionAnalysis.cpp - MemoryBehavior.cpp - RCIdentityAnalysis.cpp - SideEffectAnalysis.cpp - SimplifyInstruction.cpp - ValueTracking.cpp - LINK_LIBRARIES swiftSILPassesUtils) diff --git a/lib/SILAnalysis/CallGraph.cpp b/lib/SILAnalysis/CallGraph.cpp deleted file mode 100644 index 3a0d487627828..0000000000000 --- a/lib/SILAnalysis/CallGraph.cpp +++ /dev/null @@ -1,1175 +0,0 @@ -//===------ CallGraph.cpp - The Call Graph Data Structure ----*- C++ -*----===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#include "swift/SILAnalysis/CallGraph.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/Basic/Fallthrough.h" -#include "swift/Basic/DemangleWrappers.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILInstruction.h" -#include "swift/SIL/SILModule.h" -#include "swift/SIL/SILWitnessTable.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/GraphWriter.h" -#include "llvm/Support/raw_ostream.h" -#include -#include - -using namespace swift; - -#define DEBUG_TYPE "call-graph" - -STATISTIC(NumCallGraphNodes, "# of call graph nodes created"); -STATISTIC(NumAppliesWithEdges, "# of call sites with edges"); -STATISTIC(NumCallGraphsBuilt, "# of times the call graph is built"); - -llvm::cl::opt DumpCallGraph("sil-dump-call-graph", - llvm::cl::init(false), llvm::cl::Hidden); - -llvm::cl::opt DumpCallGraphStats("sil-dump-call-graph-stats", - llvm::cl::init(false), llvm::cl::Hidden); - -CallGraph::CallGraph(SILModule *Mod, bool completeModule) - : M(*Mod), NodeOrdinal(0), EdgeOrdinal(0) { - ++NumCallGraphsBuilt; - - // Create a call graph node for each function in the module and add - // each to a worklist of functions to process. - std::vector Workitems; - for (auto &F : M) { - addCallGraphNode(&F); - - if (F.isDefinition()) - Workitems.push_back(&F); - } - - // Now compute the sets of call graph nodes any given class method - // decl could target. - computeMethodCallees(); - - // Add edges for each function in the worklist. We capture the - // initial functions in the module up-front into this worklist - // because the process of adding edges can deseralize new functions, - // at which point we process those functions (adding edges), and it - // would be an error to process those functions again when we come - // across them in the module. - for (auto I = Workitems.begin(), E = Workitems.end(); I != E; ++I) - addEdges(*I); - - if (DumpCallGraph) - dump(); - - if (DumpCallGraphStats) - dumpStats(); -} - -CallGraph::~CallGraph() { - // Clean up all call graph nodes. - for (auto &P : FunctionToNodeMap) { - P.second->~CallGraphNode(); - } - - // Clean up all call graph edges. - for (auto &P : InstToEdgeMap) { - P.second->~CallGraphEdge(); - } - - // Clean up all SCCs. - for (CallGraphSCC *SCC : BottomUpSCCOrder) { - SCC->~CallGraphSCC(); - } -} - -/// Update the callee set for each method of a given class, along with -/// all the overridden methods from superclasses. -void CallGraph::computeClassMethodCalleesForClass(ClassDecl *CD) { - for (auto *Member : CD->getMembers()) { - auto *AFD = dyn_cast(Member); - if (!AFD) - continue; - - auto Method = SILDeclRef(AFD); - auto *CalledFn = M.lookUpFunctionInVTable(CD, Method); - if (!CalledFn) - continue; - - // FIXME: Link in external declarations, at least for complete call sets. - - auto *Node = getOrAddCallGraphNode(CalledFn); - - bool canCallUnknown = !calleesAreStaticallyKnowable(M, Method); - - // Update the callee sets for this method and all the methods it - // overrides by inserting the call graph node for the function - // that this method invokes. - do { - auto &TheCalleeSet = getOrCreateCalleeSetForMethod(Method); - assert(TheCalleeSet.getPointer() && "Unexpected null callee set!"); - - TheCalleeSet.getPointer()->insert(Node); - if (canCallUnknown) - TheCalleeSet.setInt(true); - - Method = Method.getOverriddenVTableEntry(); - } while (Method); - } -} - -void -CallGraph::computeWitnessMethodCalleesForWitnessTable(SILWitnessTable &WTable) { - for (const SILWitnessTable::Entry &Entry : WTable.getEntries()) { - if (Entry.getKind() != SILWitnessTable::Method) - continue; - - auto &WitnessEntry = Entry.getMethodWitness(); - auto Requirement = WitnessEntry.Requirement; - auto *WitnessFn = WitnessEntry.Witness; - // Dead function elimination nulls out entries for functions it removes. - if (!WitnessFn) - continue; - - auto *Node = getOrAddCallGraphNode(WitnessFn); - - auto &TheCalleeSet = getOrCreateCalleeSetForMethod(Requirement); - assert(TheCalleeSet.getPointer() && "Unexpected null callee set!"); - - TheCalleeSet.getPointer()->insert(Node); - - // FIXME: For now, conservatively assume that unknown functions - // can be called from any witness_method call site. - TheCalleeSet.setInt(true); - } -} - -/// Remove a function from all the callee sets. This should be called -/// on any function that we'll eventually remove. -// FIXME: Consider adding a reverse mapping from call graph node to -// the sets it appears in. -void CallGraph::removeFunctionFromCalleeSets(SILFunction *F) { - auto *Node = getCallGraphNode(F); - - for (auto I = CalleeSetCache.begin(), E = CalleeSetCache.end(); - I != E; ++I) { - auto *Callees = I->second.getPointer(); - - Callees->remove(Node); - } -} - -/// Compute the callees for each method that appears in a VTable or -/// Witness Table. -void CallGraph::computeMethodCallees() { - // Remove contents of old callee sets - in case we are updating the sets. - for (auto Iter : CalleeSetCache) { - auto *TheCalleeSet = Iter.second.getPointer(); - Iter.second.setInt(false); - TheCalleeSet->clear(); - } - - for (auto &VTable : M.getVTableList()) - computeClassMethodCalleesForClass(VTable.getClass()); - - for (auto &WTable : M.getWitnessTableList()) - computeWitnessMethodCalleesForWitnessTable(WTable); -} - -CallGraphNode *CallGraph::addCallGraphNode(SILFunction *F) { - // TODO: Compute this from the call graph itself after stripping - // unreachable nodes from graph. - ++NumCallGraphNodes; - - auto *Node = new (Allocator) CallGraphNode(F, ++NodeOrdinal); - - assert(!FunctionToNodeMap.count(F) && - "Added function already has a call graph node!"); - - FunctionToNodeMap[F] = Node; - - return Node; -} - -CallGraphEdge::CalleeSet & -CallGraph::getOrCreateCalleeSetForMethod(SILDeclRef Decl) { - auto *AFD = cast(Decl.getDecl()); - auto Found = CalleeSetCache.find(AFD); - if (Found != CalleeSetCache.end()) - return Found->second; - - auto *NodeSet = new (Allocator) CallGraphEdge::CallGraphNodeSet; - - bool canCallUnknown = !calleesAreStaticallyKnowable(M, Decl); - - // Allocate a new callee set, and for now just assume it can call - // unknown functions. - CallGraphEdge::CalleeSet TheCalleeSet(NodeSet, canCallUnknown); - - bool Inserted; - CalleeSetMap::iterator It; - std::tie(It, Inserted) = - CalleeSetCache.insert(std::make_pair(AFD, TheCalleeSet)); - assert(Inserted && "Expected new entry to be inserted!"); - - return It->second; -} - -SILFunction * -CallGraphEdge::Callees::getFunctionFromNode(CallGraphNode *const &Node) { - return Node->getFunction(); -} - -CallGraphEdge *CallGraph::makeCallGraphEdgeForCallee(FullApplySite Apply, - SILValue Callee) { - switch (Callee->getKind()) { - case ValueKind::ThinToThickFunctionInst: - Callee = cast(Callee)->getOperand(); - SWIFT_FALLTHROUGH; - case ValueKind::FunctionRefInst: { - auto *CalleeFn = cast(Callee)->getReferencedFunction(); - if (CalleeFn->isExternalDeclaration()) - M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll, - CallGraphLinkerEditor(this).getCallback()); - - auto *CalleeNode = getOrAddCallGraphNode(CalleeFn); - return new (Allocator) CallGraphEdge(Apply.getInstruction(), CalleeNode, - EdgeOrdinal++); - } - - case ValueKind::PartialApplyInst: { - Callee = cast(Callee)->getCallee(); - return makeCallGraphEdgeForCallee(Apply, Callee); - } - - case ValueKind::DynamicMethodInst: - // TODO: Decide how to handle these in graph construction and - // analysis passes. We might just leave them out of the - // graph. - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - - case ValueKind::SILArgument: - // First-pass call-graph construction will not do anything with - // these, but a second pass can potentially statically determine - // the called function in some cases. - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - - case ValueKind::ApplyInst: - case ValueKind::TryApplyInst: - // TODO: Probably not worth iterating invocation- then - // reverse-invocation order to catch this. - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - - case ValueKind::TupleExtractInst: - // TODO: It would be good to tunnel through extracts so that we - // can build a more accurate call graph prior to any - // optimizations. - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - - case ValueKind::StructExtractInst: - // TODO: It would be good to tunnel through extracts so that we - // can build a more accurate call graph prior to any - // optimizations. - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - - case ValueKind::WitnessMethodInst: { - auto *WMI = cast(Callee); - SILFunction *CalleeFn; - ArrayRef Subs; - SILWitnessTable *WT; - - // Attempt to find a specific callee for the given conformance and member. - std::tie(CalleeFn, WT, Subs) = - WMI->getModule().lookUpFunctionInWitnessTable(WMI->getConformance(), - WMI->getMember()); - - if (CalleeFn) { - if (CalleeFn->isExternalDeclaration()) - M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll, - CallGraphLinkerEditor(this).getCallback()); - - auto *CalleeNode = getOrAddCallGraphNode(CalleeFn); - return new (Allocator) CallGraphEdge(Apply.getInstruction(), CalleeNode, - EdgeOrdinal++); - } - - // Lookup the previously computed callee set if we didn't find a - // specific callee. - auto *AFD = cast(WMI->getMember().getDecl()); - - auto Found = CalleeSetCache.find(AFD); - if (Found != CalleeSetCache.end()) - return new (Allocator) CallGraphEdge(Apply.getInstruction(), - Found->second, EdgeOrdinal++); - - // Otherwise default to an edge with unknown callees. - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - } - - case ValueKind::ClassMethodInst: { - auto *CMI = cast(Callee); - auto *AFD = cast(CMI->getMember().getDecl()); - - auto Found = CalleeSetCache.find(AFD); - if (Found != CalleeSetCache.end()) - return new (Allocator) CallGraphEdge(Apply.getInstruction(), - Found->second, EdgeOrdinal++); - - // We don't know the callees in cases where the method isn't - // present in a vtable, so create a call graph edge with no known - // callees, assumed to be able to call unknown functions. - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - } - - case ValueKind::SuperMethodInst: - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - - default: - assert(!isa(Callee) && - "Unhandled method instruction in call graph construction!"); - return new (Allocator) CallGraphEdge(Apply.getInstruction(), EdgeOrdinal++); - } -} - -static void orderEdges(const llvm::SmallPtrSetImpl &Edges, - llvm::SmallVectorImpl &OrderedEdges) { - for (auto *Edge : Edges) - OrderedEdges.push_back(Edge); - - std::sort(OrderedEdges.begin(), OrderedEdges.end(), - [](CallGraphEdge *left, CallGraphEdge *right) { - return left->getOrdinal() < right->getOrdinal(); - }); -} - -void CallGraph::addEdgesForInstruction(SILInstruction *I, - CallGraphNode *CallerNode) { - auto Apply = FullApplySite::isa(I); - - // TODO: Support non-apply instructions. - if (!Apply) - return; - - auto *Edge = makeCallGraphEdgeForCallee(Apply, Apply.getCallee()); - assert(Edge && "Expected to be able to make call graph edge for callee!"); - assert(!InstToEdgeMap.count(Apply.getInstruction()) && - "Added apply that already has an edge node!\n"); - InstToEdgeMap[Apply.getInstruction()] = Edge; - CallerNode->addCalleeEdge(Edge); - - for (auto *CalleeNode : Edge->getCalleeSet()) - CalleeNode->addCallerEdge(Edge); - - // TODO: Compute this from the call graph itself after stripping - // unreachable nodes from graph. - ++NumAppliesWithEdges; -} - -void CallGraph::removeEdgeFromFunction(CallGraphEdge *Edge, SILFunction *F) { - // Remove the edge from all the potential callee call graph nodes. - auto CalleeSet = Edge->getCalleeSet(); - for (auto *CalleeNode : CalleeSet) - CalleeNode->removeCallerEdge(Edge); - - // Remove the edge from the caller's call graph node. - auto *CallerNode = getCallGraphNode(F); - CallerNode->removeCalleeEdge(Edge); - - // Remove the mapping from the apply to this edge. - auto Apply = Edge->getInstruction(); - InstToEdgeMap.erase(Apply); - - // Call the destructor for the edge. The memory will be reclaimed - // when the call graph is deleted by virtue of the bump pointer - // allocator. - Edge->~CallGraphEdge(); -} - -void CallGraph::removeNode(CallGraphNode *Node) { - assert(Node->getCallerEdges().size() == 0 && - "Node to delete must not have any caller edges"); - assert(Node->getCalleeEdges().size() == 0 && - "Node to delete must not have any callee edges"); - - // Avoid keeping a dangling node pointers in the vectors. - // Next time they will be computed from scratch. - BottomUpFunctionOrder.clear(); - clearBottomUpSCCOrder(); - - FunctionToNodeMap.erase(Node->getFunction()); - - // Call the destructor for the node. The memory will be reclaimed - // when the call graph is deleted by virtue of the bump pointer - // allocator. - Node->~CallGraphNode(); -} - -// Remove the call graph edges associated with an apply, where the -// apply is known to the call graph. -void CallGraph::removeEdgesForInstruction(SILInstruction *I) { - assert(InstToEdgeMap.count(I) && "Expected apply to be in edge map!"); - removeEdgeFromFunction(InstToEdgeMap[I], I->getFunction()); -} - -void CallGraph::addEdges(SILFunction *F) { - auto *CallerNode = getOrAddCallGraphNode(F); - - for (auto &BB : *F) { - for (auto &I : BB) { - if (FullApplySite::isa(&I)) - addEdgesForInstruction(&I, CallerNode); - - auto *FRI = dyn_cast(&I); - if (!FRI) - continue; - - auto *CalleeFn = FRI->getReferencedFunction(); - - if (CalleeFn->isExternalDeclaration()) - M.linkFunction(CalleeFn, SILModule::LinkingMode::LinkAll, - CallGraphLinkerEditor(this).getCallback()); - - if (CalleeFn->isPossiblyUsedExternally()) { - auto *CalleeNode = tryGetCallGraphNode(CalleeFn); - assert((!CalleeNode || !CalleeNode->isCallerEdgesComplete()) && - "Expected function to have incomplete set of caller edges!"); - (void) CalleeNode; - continue; - } - - bool hasAllApplyUsers = - std::none_of(FRI->use_begin(), FRI->use_end(), - [](Operand *Op) { - return !FullApplySite::isa(Op->getUser()); - }); - - // If we have a non-apply user of this function, mark its caller set - // as being incomplete. - if (!hasAllApplyUsers) { - auto *CalleeNode = getOrAddCallGraphNode(CalleeFn); - CalleeNode->markCallerEdgesIncomplete(); - } - } - } -} - -// Print check lines prior to call graph output, and also print the -// function bodies. This can be used to minimize the effort in -// creating new call graph test cases. -static llvm::cl::opt -CallGraphFileCheckPrefix("call-graph-file-check-prefix", llvm::cl::init(""), - llvm::cl::desc("Print a FileCheck prefix before each line")); - -static void indent(llvm::raw_ostream &OS, int Indent) { - if (!CallGraphFileCheckPrefix.empty()) return; - - std::string Blanks(Indent, ' '); - OS << Blanks; -} - -static void printFlag(llvm::raw_ostream &OS, - const char *Description, bool Value, int Indent =0) { - indent(OS, Indent); - OS << CallGraphFileCheckPrefix << Description << ": " << - (Value ? "yes\n" : "no\n"); -} - -void CallGraphEdge::print(llvm::raw_ostream &OS, int Indent) const { - indent(OS, Indent); - OS << CallGraphFileCheckPrefix << "Call site #" << Ordinal << ": "; - OS << *getInstruction(); - - printFlag(OS, "Unknown callees", canCallUnknownFunction(), Indent); - - if (getCalleeSet().empty()) - return; - - bool First = true; - indent(OS, Indent); - OS << CallGraphFileCheckPrefix << "Known callees:\n"; - for (auto *Callee : getCalleeSet()) { - if (!First) - OS << "\n"; - First = false; - auto Name = Callee->getFunction()->getName(); - indent(OS, Indent + 2); - OS << CallGraphFileCheckPrefix << "Name: " << Name << "\n"; - indent(OS, Indent + 2); - OS << CallGraphFileCheckPrefix << "Demangled: " << - demangle_wrappers::demangleSymbolAsString(Name) << "\n"; - } -} - -void CallGraphEdge::dump(int Indent) const { -#ifndef NDEBUG - print(llvm::errs(), Indent); -#endif -} - -void CallGraphEdge::dump() const { -#ifndef NDEBUG - dump(0); -#endif -} - - -void CallGraphNode::print(llvm::raw_ostream &OS) const { - OS << CallGraphFileCheckPrefix << "Function #" << Ordinal << ": " << - getFunction()->getName() << "\n"; - OS << CallGraphFileCheckPrefix << "Demangled: " << - demangle_wrappers::demangleSymbolAsString(getFunction()->getName()) << "\n"; - printFlag(OS, "Trivially dead", isTriviallyDead()); - printFlag(OS, "All callers known", isCallerEdgesComplete()); - - auto &CalleeEdges = getCalleeEdges(); - if (!CalleeEdges.empty()) { - OS << CallGraphFileCheckPrefix << "Call sites:\n"; - - llvm::SmallVector OrderedCalleeEdges; - orderEdges(CalleeEdges, OrderedCalleeEdges); - - for (auto *Edge : OrderedCalleeEdges) { - OS << "\n"; - Edge->print(OS, /* Indent= */ 2); - } - OS << "\n"; - } - - auto &CallerEdges = getCallerEdges(); - if (!CallerEdges.empty()) { - OS << CallGraphFileCheckPrefix << - (!isCallerEdgesComplete() ? "Known " : ""); - OS << "Callers:\n"; - - llvm::SmallVector OrderedCallerEdges; - orderEdges(CallerEdges, OrderedCallerEdges); - - llvm::SetVector Callers; - - for (auto *Edge : OrderedCallerEdges) - Callers.insert(Edge->getInstruction()->getFunction()); - - for (auto *Caller : Callers) { - OS << "\n"; - indent(OS, 2); - OS << CallGraphFileCheckPrefix << "Name: " << Caller->getName() << "\n"; - indent(OS, 2); - OS << CallGraphFileCheckPrefix << "Demangled: " << - demangle_wrappers::demangleSymbolAsString(Caller->getName()) << "\n"; - } - OS << "\n"; - } - - if (!CallGraphFileCheckPrefix.empty()) - getFunction()->print(OS); -} - -void CallGraphNode::dump() const { -#ifndef NDEBUG - print(llvm::errs()); -#endif -} - -void CallGraph::print(llvm::raw_ostream &OS) { - OS << CallGraphFileCheckPrefix << "*** Call Graph ***\n"; - - auto const &Funcs = getBottomUpFunctionOrder(); - for (auto *F : Funcs) { - auto *Node = getCallGraphNode(F); - if (Node) - Node->print(OS); - else - OS << "!!! Missing node for " << F->getName() << "!!!"; - OS << "\n"; - } -} - -void CallGraph::dump() { -#ifndef NDEBUG - print(llvm::errs()); -#endif -} - -namespace { - -template -struct Histogram { - unsigned Data[NumBuckets]; - - Histogram() { - for (auto i = 0; i < NumBuckets; ++i) { - Data[i] = 0; - } - } - - void increment(unsigned Bucket) { - Bucket = Bucket < NumBuckets ? Bucket : NumBuckets - 1; - Data[Bucket]++; - } - - void print(llvm::raw_ostream &OS) { - auto Last = NumBuckets - 1; - for (auto i = 0; i < NumBuckets; ++i) { - auto *Separator = Last == i ? "+: " : ": "; - if (Data[i]) - OS << CallGraphFileCheckPrefix << i << Separator << Data[i] << "\n"; - } - OS << "\n"; - } -}; - -} // end anonymous namespace - -void CallGraph::printStats(llvm::raw_ostream &OS) { - Histogram<256> CallSitesPerFunction; - Histogram<256> CallersPerFunction; - Histogram<256> CalleesPerCallSite; - unsigned CountNodes = 0; - unsigned CountCallSites = 0; - - auto const &Funcs = getBottomUpFunctionOrder(); - for (auto *F : Funcs) { - ++CountNodes; - auto *Node = getCallGraphNode(F); - if (Node) { - CallSitesPerFunction.increment(Node->getCalleeEdges().size()); - CallersPerFunction.increment(Node->getCallerEdges().size()); - - CountCallSites += Node->getCalleeEdges().size(); - - for (auto *Edge : Node->getCalleeEdges()) - CalleesPerCallSite.increment(Edge->getCalleeSet().size()); - } else { - OS << "!!! Missing node for " << F->getName() << "!!!"; - } - } - - OS << CallGraphFileCheckPrefix << "*** Call Graph Statistics ***\n"; - - OS << CallGraphFileCheckPrefix << "Number of call graph nodes: " << - CountNodes << "\n"; - OS << CallGraphFileCheckPrefix << "Number of call graph edges: " << - CountCallSites << "\n"; - - OS << CallGraphFileCheckPrefix << - "Histogram of number of call sites per function:\n"; - CallSitesPerFunction.print(OS); - - OS << CallGraphFileCheckPrefix << - "Histogram of number of callees per call site:\n"; - CalleesPerCallSite.print(OS); - - OS << CallGraphFileCheckPrefix << - "Histogram of number of callers per function:\n"; - CallersPerFunction.print(OS); - - OS << CallGraphFileCheckPrefix << "Bump pointer allocated memory (bytes): " << - Allocator.getTotalMemory() << "\n"; - - OS << CallGraphFileCheckPrefix << "Number of callee sets allocated: " << - CalleeSetCache.size() << "\n"; -} - -void CallGraph::dumpStats() { -#ifndef NDEBUG - printStats(llvm::errs()); -#endif -} - -namespace { - -/// Finds SCCs in the call graph. Our call graph has an unconventional -/// form where each edge of the graph is really a multi-edge that can -/// point to multiple call graph nodes in the case where we can call -/// one of several different functions. -class CallGraphSCCFinder { - unsigned NextDFSNum; - llvm::SmallVectorImpl &TheSCCs; - - llvm::DenseMap DFSNum; - llvm::DenseMap MinDFSNum; - llvm::SetVector DFSStack; - - /// The CallGraphSCCFinder does not own this bump ptr allocator, so does not - /// call the destructor of objects allocated from it. - llvm::BumpPtrAllocator &BPA; - -public: - CallGraphSCCFinder(llvm::SmallVectorImpl &TheSCCs, - llvm::BumpPtrAllocator &BPA) - : NextDFSNum(0), TheSCCs(TheSCCs), BPA(BPA) {} - - void DFS(CallGraphNode *Node) { - // Set the DFSNum for this node if we haven't already, and if we - // have, which indicates it's already been visited, return. - if (!DFSNum.insert(std::make_pair(Node, NextDFSNum)).second) - return; - - assert(MinDFSNum.find(Node) == MinDFSNum.end() && - "Node should not already have a minimum DFS number!"); - - MinDFSNum[Node] = NextDFSNum; - ++NextDFSNum; - - DFSStack.insert(Node); - - llvm::SmallVector OrderedEdges; - orderEdges(Node->getCalleeEdges(), OrderedEdges); - - for (auto *ApplyEdge : OrderedEdges) { - for (auto *CalleeNode : ApplyEdge->getCalleeSet()) { - if (DFSNum.find(CalleeNode) == DFSNum.end()) { - DFS(CalleeNode); - MinDFSNum[Node] = std::min(MinDFSNum[Node], MinDFSNum[CalleeNode]); - } else if (DFSStack.count(CalleeNode)) { - MinDFSNum[Node] = std::min(MinDFSNum[Node], DFSNum[CalleeNode]); - } - } - } - - // If this node is the root of an SCC (including SCCs with a - // single node), pop the SCC and push it on our SCC stack. - if (DFSNum[Node] == MinDFSNum[Node]) { - auto *SCC = new (BPA) CallGraphSCC(); - - CallGraphNode *Popped; - do { - Popped = DFSStack.pop_back_val(); - SCC->SCCNodes.push_back(Popped->getFunction()); - } while (Popped != Node); - - TheSCCs.push_back(SCC); - } - } -}; - -} // end anonymous namespace - -void CallGraph::clearBottomUpSCCOrder() { - for (auto *SCC : BottomUpSCCOrder) - SCC->~CallGraphSCC(); - BottomUpSCCOrder.clear(); -} - -void CallGraph::computeBottomUpSCCOrder() { - if (!BottomUpSCCOrder.empty()) { - clearBottomUpSCCOrder(); - } - - CallGraphSCCFinder SCCFinder(BottomUpSCCOrder, Allocator); - for (auto &F : M) { - if (F.isDefinition()) { - auto *Node = getCallGraphNode(&F); - SCCFinder.DFS(Node); - } - } -} - -void CallGraph::computeBottomUpFunctionOrder() { - // We do not need to call any destructors here. - BottomUpFunctionOrder.clear(); - - computeBottomUpSCCOrder(); - - for (auto *SCC : BottomUpSCCOrder) - for (auto *Fn : SCC->SCCNodes) - BottomUpFunctionOrder.push_back(Fn); -} - -//===----------------------------------------------------------------------===// -// CallGraphEditor -//===----------------------------------------------------------------------===// - -void CallGraphEditor::replaceApplyWithNew(FullApplySite Old, - FullApplySite New) { - if (!CG) - return; - - if (auto *Edge = CG->tryGetCallGraphEdge(Old.getInstruction())) - CG->removeEdgeFromFunction(Edge, Old.getInstruction()->getFunction()); - - CG->addEdgesForInstruction(New.getInstruction()); -} - -void CallGraphEditor::replaceApplyWithCallSites(FullApplySite Old, - llvm::SmallVectorImpl &NewCallSites) { - if (!CG) - return; - - if (auto *Edge = CG->tryGetCallGraphEdge(Old.getInstruction())) - CG->removeEdgeFromFunction(Edge, Old.getInstruction()->getFunction()); - - for (auto NewApply : NewCallSites) - CG->addEdgesForInstruction(NewApply); -} - -void CallGraphEditor::moveNodeToNewFunction(SILFunction *Old, - SILFunction *New) { - if (!CG) - return; - - auto Iter = CG->FunctionToNodeMap.find(Old); - assert(Iter != CG->FunctionToNodeMap.end()); - auto *Node = Iter->second; - CG->FunctionToNodeMap.erase(Iter); - CG->FunctionToNodeMap[New] = Node; -} - -void CallGraphEditor::removeAllCalleeEdgesFrom(SILFunction *F) { - if (!CG) - return; - - auto &CalleeEdges = CG->getCallGraphNode(F)->getCalleeEdges(); - while (!CalleeEdges.empty()) { - auto *Edge = *CalleeEdges.begin(); - CG->removeEdgeFromFunction(Edge, F); - } -} - -void CallGraphEditor::removeAllCallerEdgesFrom(SILFunction *F) { - if (!CG) - return; - - auto &CallerEdges = CG->getCallGraphNode(F)->getCallerEdges(); - while (!CallerEdges.empty()) { - auto *Edge = *CallerEdges.begin(); - auto Apply = Edge->getInstruction(); - CG->removeEdgeFromFunction(Edge, Apply->getFunction()); - } -} - -void CallGraphEditor::updatePartialApplyUses(swift::ApplySite AI) { - if (!CG) - return; - - for (auto *Use : AI.getInstruction()->getUses()) { - if (auto FAS = FullApplySite::isa(Use->getUser())) - replaceApplyWithNew(FAS, FAS); - } -} - -void CallGraphEditor::eraseFunction(SILFunction *F) { - auto &M = F->getModule(); - M.eraseFunction(F); - - if (CG) - removeCallGraphNode(F); -} - -//===----------------------------------------------------------------------===// -// CallGraph Verification -//===----------------------------------------------------------------------===// - -void CallGraph::verify() const { -#ifndef NDEBUG - // For every function in the module, add it to our SILFunction set. - llvm::DenseSet Functions; - for (auto &F : M) - Functions.insert(&F); - - // For every pair (SILFunction, CallGraphNode) in the - // function-to-node map, verify: - // - // a. The function is in the current module. - // b. The call graph node is for that same function. - // - // In addition, call the verify method for the function. - unsigned numEdges = 0; - for (auto &P : FunctionToNodeMap) { - SILFunction *F = P.first; - CallGraphNode *Node = P.second; - assert(Functions.count(F) && - "Function in call graph but not in module!?"); - assert(Node->getFunction() == F && - "Func mapped to node, but node has different Function inside?!"); - verify(F); - numEdges += Node->getCalleeEdges().size(); - } - - assert(InstToEdgeMap.size() == numEdges && - "Some edges in InstToEdgeMap are not contained in any node"); - - // Verify the callee sets. - for (auto Iter : CalleeSetCache) { - auto *CalleeSet = Iter.second.getPointer(); - for (CallGraphNode *Node : *CalleeSet) { - SILFunction *F = Node->getFunction(); - assert(tryGetCallGraphNode(F) && - "Callee set contains dangling node poiners"); - } - } -#endif -} - -void CallGraph::verify(SILFunction *F) const { -#ifndef NDEBUG - // Collect all full apply sites of the function. - - auto *Node = getCallGraphNode(F); - unsigned numEdges = 0; - - for (auto &BB : *F) { - for (auto &I : BB) { - auto FAS = FullApplySite::isa(&I); - if (!FAS) - continue; - - auto *Edge = getCallGraphEdge(FAS.getInstruction()); - - numEdges++; - - assert(Edge->getInstruction() == &I && - "Edge is not linked to the correct apply site"); - - assert(InstToEdgeMap.lookup(FAS.getInstruction()) == Edge && - "Edge is not in InstToEdgeMap"); - - if (!Edge->canCallUnknownFunction()) { - // In the trivial case that we call a known function, check if we have - // exactly one callee in the edge. - SILValue Callee = FAS.getCallee(); - if (auto *PAI = dyn_cast(Callee)) - Callee = PAI->getCallee(); - - if (auto *FRI = dyn_cast(Callee)) { - auto *CalleeNode = Edge->getSingleCalleeOrNull(); - assert(CalleeNode && - CalleeNode->getFunction() == FRI->getReferencedFunction() && - "Direct apply is not represented by a single-callee edge"); - } - } - } - } - - // Check if we have an exact 1-to-1 mapping from full apply sites to edges. - auto &CalleeEdges = Node->getCalleeEdges(); - assert(numEdges == CalleeEdges.size() && "More edges than full apply sites"); - - // Make structural graph checks: - // 1.) Check that the callee edges are part of the callee node's caller set. - for (auto *Edge : CalleeEdges) { - assert(Edge->getInstruction()->getFunction() == F && - "Apply in callee set that is not in the callee function?!"); - - for (auto *CalleeNode : Edge->getCalleeSet()) { - auto &CallerEdges = CalleeNode->getCallerEdges(); - assert(std::find(CallerEdges.begin(), CallerEdges.end(), Edge) != - CallerEdges.end() && - "Edge not in caller set of callee"); - } - } - // 2.) Check that the caller edges have this node in their callee sets. - for (auto *Edge : Node->getCallerEdges()) { - auto CalleeSet = Edge->getCalleeSet(); - assert(std::find(CalleeSet.begin(), CalleeSet.end(), Node) != - CalleeSet.end() && - "Node not in callee set of caller edge"); - } -#endif -} - -//===----------------------------------------------------------------------===// -// View CG Implementation -//===----------------------------------------------------------------------===// - -#ifndef NDEBUG - -namespace swift { - -/// Another representation of the call graph using sorted vectors instead of -/// sets. Used for viewing the callgraph as dot file with llvm::ViewGraph. -struct OrderedCallGraph { - - struct Node; - - struct Edge { - Edge(CallGraphEdge *CGEdge, Node *Child) : CGEdge(CGEdge), Child(Child) { } - CallGraphEdge *CGEdge; - Node *Child; - }; - - struct Node { - CallGraphNode *CGNode; - OrderedCallGraph *OCG; - int NumCallSites = 0; - SmallVector Children; - }; - - struct child_iterator : public std::iterator { - SmallVectorImpl::iterator baseIter; - - child_iterator(SmallVectorImpl::iterator baseIter) : - baseIter(baseIter) - { } - - child_iterator &operator++() { baseIter++; return *this; } - child_iterator operator++(int) { auto tmp = *this; baseIter++; return tmp; } - Node *operator*() const { return baseIter->Child; } - bool operator==(const child_iterator &RHS) const { - return baseIter == RHS.baseIter; - } - bool operator!=(const child_iterator &RHS) const { - return baseIter != RHS.baseIter; - } - difference_type operator-(const child_iterator &RHS) const { - return baseIter - RHS.baseIter; - } - }; - - OrderedCallGraph(CallGraph *CG); - - CallGraph *CG; - std::vector Nodes; - - /// The SILValue IDs which are printed as edge source labels. - llvm::DenseMap InstToIDMap; - - typedef std::vector::iterator iterator; -}; - -OrderedCallGraph::OrderedCallGraph(CallGraph *CG) { - auto const &Funcs = CG->getBottomUpFunctionOrder(); - Nodes.resize(Funcs.size()); - llvm::DenseMap NodeMap; - int idx = 0; - for (auto *F : Funcs) { - auto *CGNode = CG->getCallGraphNode(F); - Node &ONode = Nodes[idx++]; - ONode.CGNode = CGNode; - ONode.OCG = this; - NodeMap[CGNode] = &ONode; - - F->numberValues(InstToIDMap); - } - - for (Node &ONode : Nodes) { - llvm::SmallVector OrderedEdges; - orderEdges(ONode.CGNode->getCalleeEdges(), OrderedEdges); - - ONode.NumCallSites = OrderedEdges.size(); - for (auto *CGEdge : OrderedEdges) { - for (auto *CalleeNode : CGEdge->getCalleeSet()) { - auto *OrderedChild = NodeMap[CalleeNode]; - assert(OrderedChild); - ONode.Children.push_back(Edge(CGEdge, OrderedChild)); - } - } - } -} - -} // end swift namespace - -namespace llvm { - - /// Wraps a dot node label string to multiple lines. The \p NumEdgeLabels - /// gives an estimate on the minimum width of the node shape. - static void wrap(std::string &Str, int NumEdgeLabels) { - unsigned ColNum = 0; - unsigned LastSpace = 0; - unsigned MaxColumns = std::max(60, NumEdgeLabels * 8); - for (unsigned i = 0; i != Str.length(); ++i) { - if (ColNum == MaxColumns) { - if (!LastSpace) - LastSpace = i; - Str.insert(LastSpace + 1, "\\l"); - ColNum = i - LastSpace - 1; - LastSpace = 0; - } else - ++ColNum; - if (Str[i] == ' ' || Str[i] == '.') - LastSpace = i; - } - } - - /// CallGraph GraphTraits specialization so the CallGraph can be - /// iterable by generic graph iterators. - template <> struct GraphTraits { - typedef OrderedCallGraph::Node NodeType; - typedef OrderedCallGraph::child_iterator ChildIteratorType; - - static NodeType *getEntryNode(NodeType *N) { return N; } - static inline ChildIteratorType child_begin(NodeType *N) { - return N->Children.begin(); - } - static inline ChildIteratorType child_end(NodeType *N) { - return N->Children.end(); - } - }; - - template <> struct GraphTraits - : public GraphTraits { - typedef OrderedCallGraph *GraphType; - - static NodeType *getEntryNode(GraphType F) { return nullptr; } - - typedef OrderedCallGraph::iterator nodes_iterator; - static nodes_iterator nodes_begin(GraphType OCG) { - return OCG->Nodes.begin(); - } - static nodes_iterator nodes_end(GraphType OCG) { return OCG->Nodes.end(); } - static unsigned size(GraphType CG) { return CG->Nodes.size(); } - }; - - /// This is everything the llvm::GraphWriter needs to write the call graph in - /// a dot file. - template <> - struct DOTGraphTraits : public DefaultDOTGraphTraits { - - DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} - - std::string getNodeLabel(const OrderedCallGraph::Node *Node, - const OrderedCallGraph *Graph) { - SILFunction *F = Node->CGNode->getFunction(); - std::string Label = F->getName(); - wrap(Label, Node->NumCallSites); - return Label; - } - - std::string getNodeDescription(const OrderedCallGraph::Node *Node, - const OrderedCallGraph *Graph) { - SILFunction *F = Node->CGNode->getFunction(); - std::string Label = demangle_wrappers:: - demangleSymbolAsString(F->getName()); - wrap(Label, Node->NumCallSites); - return Label; - } - - static std::string getEdgeSourceLabel(const OrderedCallGraph::Node *Node, - OrderedCallGraph::child_iterator I) { - std::string Label; - raw_string_ostream O(Label); - SILInstruction *Inst = I.baseIter->CGEdge->getInstruction(); - O << '%' << Node->OCG->InstToIDMap[Inst]; - return Label; - } - - static std::string getEdgeAttributes(const OrderedCallGraph::Node *Node, - OrderedCallGraph::child_iterator I, - const OrderedCallGraph *Graph) { - CallGraphEdge *Edge = I.baseIter->CGEdge; - if (Edge->canCallUnknownFunction()) - return "color=\"red\""; - return ""; - } - }; -} // end llvm namespace -#endif - -void CallGraph::viewCG() { - /// When asserts are disabled, this should be a NoOp. -#ifndef NDEBUG - OrderedCallGraph OCG(this); - llvm::ViewGraph(&OCG, "callgraph"); -#endif -} diff --git a/lib/SILAnalysis/EscapeAnalysis.cpp b/lib/SILAnalysis/EscapeAnalysis.cpp deleted file mode 100644 index 8494d13ae325a..0000000000000 --- a/lib/SILAnalysis/EscapeAnalysis.cpp +++ /dev/null @@ -1,1411 +0,0 @@ -//===-------------- EscapeAnalysis.cpp - SIL Escape Analysis --------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-escape" -#include "swift/SILAnalysis/EscapeAnalysis.h" -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" -#include "swift/SILAnalysis/CallGraphAnalysis.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILPasses/PassManager.h" -#include "swift/SIL/SILArgument.h" -#include "llvm/Support/GraphWriter.h" -#include "llvm/Support/raw_ostream.h" - -using namespace swift; - -static bool isProjection(ValueBase *V) { - switch (V->getKind()) { - case ValueKind::IndexAddrInst: - case ValueKind::IndexRawPointerInst: - case ValueKind::StructElementAddrInst: - case ValueKind::TupleElementAddrInst: - case ValueKind::UncheckedTakeEnumDataAddrInst: - case ValueKind::StructExtractInst: - case ValueKind::TupleExtractInst: - case ValueKind::UncheckedEnumDataInst: - case ValueKind::MarkDependenceInst: - case ValueKind::PointerToAddressInst: - return true; - default: - return false; - } -} - -static bool isNonWritableMemoryAddress(ValueBase *V) { - switch (V->getKind()) { - case ValueKind::FunctionRefInst: - case ValueKind::WitnessMethodInst: - case ValueKind::ClassMethodInst: - case ValueKind::SuperMethodInst: - case ValueKind::StringLiteralInst: - // These instructions return pointers to memory which can't be a - // destination of a store. - return true; - default: - return false; - } -} - -static ValueBase *skipProjections(ValueBase *V) { - for (;;) { - if (!isProjection(V)) - return V; - V = cast(V)->getOperand(0).getDef(); - } - llvm_unreachable("there is no escape from an infinite loop"); -} - -void EscapeAnalysis::ConnectionGraph::clear() { - Values2Nodes.clear(); - Nodes.clear(); - ReturnNode = nullptr; - UsePoints.clear(); - UsePointsComputed = false; - NodeAllocator.DestroyAll(); - assert(ToMerge.empty()); -} - -EscapeAnalysis::CGNode *EscapeAnalysis::ConnectionGraph:: -getOrCreateNode(ValueBase *V) { - CGNode * &Node = Values2Nodes[V]; - if (!Node) { - if (SILArgument *Arg = dyn_cast(V)) { - if (Arg->isFunctionArg()) { - Node = allocNode(V, NodeType::Argument); - Node->mergeEscapeState(EscapeState::Arguments); - } else { - Node = allocNode(V, NodeType::Value); - } - } else { - Node = allocNode(V, NodeType::Value); - } - } - return Node->getMergeTarget(); -} - -EscapeAnalysis::CGNode *EscapeAnalysis::ConnectionGraph::getContentNode( - CGNode *AddrNode) { - // Do we already have a content node (which is not necessarliy an immediate - // successor of AddrNode)? - if (AddrNode->pointsTo) - return AddrNode->pointsTo; - - CGNode *Node = allocNode(AddrNode->V, NodeType::Content); - updatePointsTo(AddrNode, Node); - assert(ToMerge.empty() && - "Initially setting pointsTo should not require any node merges"); - return Node; -} - -bool EscapeAnalysis::ConnectionGraph::addDeferEdge(CGNode *From, CGNode *To) { - if (!From->addDefered(To)) - return false; - - CGNode *FromPointsTo = From->pointsTo; - CGNode *ToPointsTo = To->pointsTo; - if (FromPointsTo != ToPointsTo) { - if (!ToPointsTo) { - updatePointsTo(To, FromPointsTo->getMergeTarget()); - assert(ToMerge.empty() && - "Initially setting pointsTo should not require any node merges"); - } else { - // We are adding an edge between two pointers which point to different - // content nodes. This will require to merge the content nodes (and maybe - // other content nodes as well), because of the graph invariance 4). - updatePointsTo(From, ToPointsTo->getMergeTarget()); - } - } - return true; -} - -void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() { - while (!ToMerge.empty()) { - CGNode *From = ToMerge.pop_back_val(); - CGNode *To = From->mergeTo; - assert(To && "Node scheduled to merge but no merge target set"); - assert(!From->isMerged && "Merge source is already merged"); - assert(From->Type == NodeType::Content && "Can only merge content nodes"); - assert(To->Type == NodeType::Content && "Can only merge content nodes"); - - // Unlink the predecessors and redirect the incoming pointsTo edge. - // Note: we don't redirect the defer-edges because we don't want to trigger - // updatePointsTo (which is called by addDeferEdge) right now. - for (Predecessor Pred : From->Preds) { - CGNode *PredNode = Pred.getPointer(); - if (Pred.getInt() == EdgeType::PointsTo) { - assert(PredNode->getPointsToEdge() == From && - "Incoming pointsTo edge not set in predecessor"); - if (PredNode != From) - PredNode->setPointsTo(To); - } else { - assert(PredNode != From); - auto Iter = PredNode->findDefered(From); - assert(Iter != PredNode->defersTo.end() && - "Incoming defer-edge not found in predecessor's defer list"); - PredNode->defersTo.erase(Iter); - } - } - // Unlink and redirect the outgoing pointsTo edge. - if (CGNode *PT = From->getPointsToEdge()) { - if (PT != From) { - PT->removeFromPreds(Predecessor(From, EdgeType::PointsTo)); - } else { - PT = To; - } - if (CGNode *ExistingPT = To->getPointsToEdge()) { - // The To node already has an outgoing pointsTo edge, so the only thing - // we can do is to merge both content nodes. - scheduleToMerge(ExistingPT, PT); - } else { - To->setPointsTo(PT); - } - } - // Unlink the outgoing defer edges. - for (CGNode *Defers : From->defersTo) { - assert(Defers != From && "defer edge may not form a self-cycle"); - Defers->removeFromPreds(Predecessor(From, EdgeType::Defer)); - } - // Redirect the incoming defer edges. This may trigger other node merges. - for (Predecessor Pred : From->Preds) { - CGNode *PredNode = Pred.getPointer(); - if (Pred.getInt() == EdgeType::Defer) { - assert(PredNode != From && "defer edge may not form a self-cycle"); - addDeferEdge(PredNode, To); - } - } - // Redirect the outgoing defer edges, which may also trigger other node - // merges. - for (CGNode *Defers : From->defersTo) { - addDeferEdge(To, Defers); - } - - // Ensure that graph invariance 4) is kept. At this point there may be still - // some violations because of the new adjacent edges of the To node. - for (Predecessor Pred : To->Preds) { - if (Pred.getInt() == EdgeType::PointsTo) { - CGNode *PredNode = Pred.getPointer(); - for (Predecessor PredOfPred : PredNode->Preds) { - if (PredOfPred.getInt() == EdgeType::Defer) - updatePointsTo(PredOfPred.getPointer(), To); - } - } - } - if (CGNode *ToPT = To->getPointsToEdge()) { - for (CGNode *ToDef : To->defersTo) { - updatePointsTo(ToDef, ToPT); - } - for (Predecessor Pred : To->Preds) { - if (Pred.getInt() == EdgeType::Defer) - updatePointsTo(Pred.getPointer(), ToPT); - } - } - To->mergeEscapeState(From->State); - - // Cleanup the merged node. - From->isMerged = true; - From->Preds.clear(); - From->defersTo.clear(); - From->pointsTo = nullptr; - } -} - -void EscapeAnalysis::ConnectionGraph:: -updatePointsTo(CGNode *InitialNode, CGNode *pointsTo) { - // Visit all nodes in the defer web, which don't have the right pointsTo set. - llvm::SmallVector WorkList; - WorkList.push_back(InitialNode); - InitialNode->isInWorkList = true; - for (unsigned Idx = 0; Idx < WorkList.size(); ++Idx) { - auto *Node = WorkList[Idx]; - if (Node->pointsTo == pointsTo) - continue; - - if (Node->pointsTo) { - // Mismatching: we need to merge! - scheduleToMerge(Node->pointsTo, pointsTo); - } - - // If the node already has a pointsTo _edge_ we don't change it (we don't - // want to change the structure of the graph at this point). - if (!Node->pointsToIsEdge) { - if (Node->defersTo.empty()) { - // This node is the end of a defer-edge path with no pointsTo connected. - // We create an edge to pointsTo (agreed, this changes the structure of - // the graph but adding this edge is harmless). - Node->setPointsTo(pointsTo); - } else { - Node->pointsTo = pointsTo; - } - } - - // Add all adjacent nodes to the WorkList. - for (auto *Defered : Node->defersTo) { - if (!Defered->isInWorkList) { - WorkList.push_back(Defered); - Defered->isInWorkList = true; - } - } - for (Predecessor Pred : Node->Preds) { - if (Pred.getInt() == EdgeType::Defer) { - CGNode *PredNode = Pred.getPointer(); - if (!PredNode->isInWorkList) { - WorkList.push_back(PredNode); - PredNode->isInWorkList = true; - } - } - } - } - clearWorkListFlags(WorkList); -} - -void EscapeAnalysis::ConnectionGraph::propagateEscapeStates() { - bool Changed = false; - do { - Changed = false; - - for (CGNode *Node : Nodes) { - // Propagate the state to all successor nodes. - if (Node->pointsTo) { - Changed |= Node->pointsTo->mergeEscapeState(Node->State); - } - for (CGNode *Def : Node->defersTo) { - Changed |= Def->mergeEscapeState(Node->State); - } - } - } while (Changed); -} - -void EscapeAnalysis::ConnectionGraph::computeUsePoints() { - if (UsePointsComputed) - return; - - // First scan the whole function and add relevant instructions as use-points. - for (auto &BB : *F) { - for (SILArgument *BBArg : BB.getBBArgs()) { - /// In addition to releasing instructions (see below) we also add block - /// arguments as use points. In case of loops, block arguments can - /// "extend" the liferange of a reference in upward direction. - if (CGNode *ArgNode = getNodeOrNull(BBArg)) { - addUsePoint(ArgNode, BBArg); - } - } - - for (auto &I : BB) { - switch (I.getKind()) { - case ValueKind::StrongReleaseInst: - case ValueKind::ReleaseValueInst: - case ValueKind::UnownedReleaseInst: - case ValueKind::ApplyInst: - case ValueKind::TryApplyInst: { - /// Actually we only add instructions which may release a reference. - /// We need the use points only for getting the end of a reference's - /// liferange. And that must be a releaseing instruction. - int ValueIdx = -1; - for (const Operand &Op : I.getAllOperands()) { - ValueBase *OpV = Op.get().getDef(); - if (CGNode *OpNd = getNodeOrNull(skipProjections(OpV))) { - if (ValueIdx < 0) { - ValueIdx = addUsePoint(OpNd, &I); - } else { - OpNd->setUsePointBit(ValueIdx); - } - } - } - break; - } - default: - break; - } - } - } - - // Second, we propagate the use-point information through the graph. - bool Changed = false; - do { - Changed = false; - - for (CGNode *Node : Nodes) { - // Propagate the bits to all successor nodes. - if (Node->pointsTo) { - Changed |= Node->pointsTo->mergeUsePoints(Node); - } - for (CGNode *Def : Node->defersTo) { - Changed |= Def->mergeUsePoints(Node); - } - } - } while (Changed); - - UsePointsComputed = true; -} - -bool EscapeAnalysis::ConnectionGraph::mergeFrom(ConnectionGraph *SourceGraph, - CGNodeMap &Mapping) { - // The main point of the merging algorithm is to map each content node in the - // source graph to a content node in this (destination) graph. This may - // require to create new nodes or to merge existing nodes in this graph. - - // First step: replicate the points-to edges and the content nodes of the - // source graph in this graph. - bool Changed = false; - bool NodesMerged; - do { - NodesMerged = false; - for (unsigned Idx = 0; Idx < Mapping.getMappedNodes().size(); ++Idx) { - CGNode *SourceNd = Mapping.getMappedNodes()[Idx]; - CGNode *DestNd = Mapping.get(SourceNd); - assert(DestNd); - - if (SourceNd->getEscapeState() >= EscapeState::Global) { - // We don't need to merge the source subgraph of nodes which have the - // global escaping state set. - // Just set global escaping in the caller node and that's it. - Changed |= DestNd->mergeEscapeState(EscapeState::Global); - continue; - } - - CGNode *SourcePT = SourceNd->pointsTo; - if (!SourcePT) - continue; - - CGNode *MappedDestPT = Mapping.get(SourcePT); - if (!DestNd->pointsTo) { - // The following getContentNode() will create a new content node. - Changed = true; - } - CGNode *DestPT = getContentNode(DestNd); - if (MappedDestPT) { - // We already found the destination node through another path. - if (DestPT != MappedDestPT) { - // There are two content nodes in this graph which map to the same - // content node in the source graph -> we have to merge them. - scheduleToMerge(DestPT, MappedDestPT); - mergeAllScheduledNodes(); - Changed = true; - NodesMerged = true; - } - assert(SourcePT->isInWorkList); - } else { - // It's the first time we see the destination node, so we add it to the - // mapping. - Mapping.add(SourcePT, DestPT); - } - } - } while (NodesMerged); - - clearWorkListFlags(Mapping.getMappedNodes()); - - // Second step: add the source graph's defer edges to this graph. - llvm::SmallVector WorkList; - for (CGNode *SourceNd : Mapping.getMappedNodes()) { - assert(WorkList.empty()); - WorkList.push_back(SourceNd); - SourceNd->isInWorkList = true; - CGNode *DestFrom = Mapping.get(SourceNd); - assert(DestFrom && "node should have been merged to the graph"); - - // Collect all nodes which are reachable from the SourceNd via a path - // which only contains defer-edges. - for (unsigned Idx = 0; Idx < WorkList.size(); ++Idx) { - CGNode *SourceReachable = WorkList[Idx]; - CGNode *DestReachable = Mapping.get(SourceReachable); - // Create the edge in this graph. Note: this may trigger merging of - // content nodes. - if (DestReachable) - Changed |= defer(DestFrom, DestReachable); - - for (auto *Defered : SourceReachable->defersTo) { - if (!Defered->isInWorkList) { - WorkList.push_back(Defered); - Defered->isInWorkList = true; - } - } - } - clearWorkListFlags(WorkList); - WorkList.clear(); - } - return Changed; -} - -EscapeAnalysis::CGNode *EscapeAnalysis::ConnectionGraph:: -getNode(ValueBase *V, EscapeAnalysis *EA) { - if (isa(V)) - return nullptr; - - if (!V->hasValue()) - return nullptr; - - if (!EA->isPointer(V)) - return nullptr; - - V = skipProjections(V); - - return getOrCreateNode(V); -} - -/// Returns true if \p V is a use of \p Node, i.e. V may (indirectly) -/// somehow refer to the Node's value. -/// Use-points are only values which are relevant for lifeness computation, -/// e.g. release or apply instructions. -bool EscapeAnalysis::ConnectionGraph::isUsePoint(ValueBase *V, CGNode *Node) { - assert(Node->getEscapeState() < EscapeState::Global && - "Use points are only valid for non-escaping nodes"); - computeUsePoints(); - auto Iter = UsePoints.find(V); - if (Iter == UsePoints.end()) - return false; - int Idx = Iter->second; - if (Idx >= (int)Node->UsePoints.size()) - return false; - return Node->UsePoints.test(Idx); -} - - -//===----------------------------------------------------------------------===// -// Dumping, Viewing and Verification -//===----------------------------------------------------------------------===// - -#ifndef NDEBUG - -/// For the llvm's GraphWriter we copy the connection graph into CGForDotView. -/// This makes iterating over the edges easier. -struct CGForDotView { - - enum EdgeTypes { - PointsTo, - Defered - }; - - struct Node { - EscapeAnalysis::CGNode *OrigNode; - CGForDotView *Graph; - SmallVector Children; - SmallVector ChildrenTypes; - }; - - CGForDotView(const EscapeAnalysis::ConnectionGraph *CG); - - std::string getNodeLabel(const Node *Node) const; - - std::string getNodeAttributes(const Node *Node) const; - - std::vector Nodes; - - SILFunction *F; - - const EscapeAnalysis::ConnectionGraph *OrigGraph; - - // The same IDs as the SILPrinter uses. - llvm::DenseMap InstToIDMap; - - typedef std::vector::iterator iterator; - typedef SmallVectorImpl::iterator child_iterator; -}; - -CGForDotView::CGForDotView(const EscapeAnalysis::ConnectionGraph *CG) : - F(CG->F), OrigGraph(CG) { - Nodes.resize(CG->Nodes.size()); - llvm::DenseMap Orig2Node; - int idx = 0; - for (auto *OrigNode : CG->Nodes) { - if (OrigNode->isMerged) - continue; - - Orig2Node[OrigNode] = &Nodes[idx++]; - } - Nodes.resize(idx); - CG->F->numberValues(InstToIDMap); - - idx = 0; - for (auto *OrigNode : CG->Nodes) { - if (OrigNode->isMerged) - continue; - - auto &Nd = Nodes[idx++]; - Nd.Graph = this; - Nd.OrigNode = OrigNode; - if (auto *PT = OrigNode->getPointsToEdge()) { - Nd.Children.push_back(Orig2Node[PT]); - Nd.ChildrenTypes.push_back(PointsTo); - } - for (auto *Def : OrigNode->defersTo) { - Nd.Children.push_back(Orig2Node[Def]); - Nd.ChildrenTypes.push_back(Defered); - } - } -} - -std::string CGForDotView::getNodeLabel(const Node *Node) const { - std::string Label; - llvm::raw_string_ostream O(Label); - if (ValueBase *V = Node->OrigNode->V) - O << '%' << InstToIDMap.lookup(V) << '\n'; - - switch (Node->OrigNode->Type) { - case swift::EscapeAnalysis::NodeType::Content: - O << "content"; - break; - case swift::EscapeAnalysis::NodeType::Return: - O << "return"; - break; - default: { - std::string Inst; - llvm::raw_string_ostream OI(Inst); - SILValue(Node->OrigNode->V).print(OI); - size_t start = Inst.find(" = "); - if (start != std::string::npos) { - start += 3; - } else { - start = 2; - } - O << Inst.substr(start, 20); - break; - } - } - if (!Node->OrigNode->matchPointToOfDefers()) { - O << "\nPT mismatch: "; - if (Node->OrigNode->pointsTo) { - if (ValueBase *V = Node->OrigNode->pointsTo->V) - O << '%' << Node->Graph->InstToIDMap[V]; - } else { - O << "null"; - } - } - O.flush(); - return Label; -} - -std::string CGForDotView::getNodeAttributes(const Node *Node) const { - auto *Orig = Node->OrigNode; - std::string attr; - switch (Orig->Type) { - case swift::EscapeAnalysis::NodeType::Content: - attr = "style=\"rounded\""; - break; - case swift::EscapeAnalysis::NodeType::Argument: - case swift::EscapeAnalysis::NodeType::Return: - attr = "style=\"bold\""; - break; - default: - break; - } - if (Orig->getEscapeState() != swift::EscapeAnalysis::EscapeState::None && - !attr.empty()) - attr += ','; - - switch (Orig->getEscapeState()) { - case swift::EscapeAnalysis::EscapeState::None: - break; - case swift::EscapeAnalysis::EscapeState::Return: - attr += "color=\"green\""; - break; - case swift::EscapeAnalysis::EscapeState::Arguments: - attr += "color=\"blue\""; - break; - case swift::EscapeAnalysis::EscapeState::Global: - attr += "color=\"red\""; - break; - } - return attr; -} - -namespace llvm { - - - /// GraphTraits specialization so the CGForDotView can be - /// iterable by generic graph iterators. - template <> struct GraphTraits { - typedef CGForDotView::Node NodeType; - typedef CGForDotView::child_iterator ChildIteratorType; - - static NodeType *getEntryNode(NodeType *N) { return N; } - static inline ChildIteratorType child_begin(NodeType *N) { - return N->Children.begin(); - } - static inline ChildIteratorType child_end(NodeType *N) { - return N->Children.end(); - } - }; - - template <> struct GraphTraits - : public GraphTraits { - typedef CGForDotView *GraphType; - - static NodeType *getEntryNode(GraphType F) { return nullptr; } - - typedef CGForDotView::iterator nodes_iterator; - static nodes_iterator nodes_begin(GraphType OCG) { - return OCG->Nodes.begin(); - } - static nodes_iterator nodes_end(GraphType OCG) { return OCG->Nodes.end(); } - static unsigned size(GraphType CG) { return CG->Nodes.size(); } - }; - - /// This is everything the llvm::GraphWriter needs to write the call graph in - /// a dot file. - template <> - struct DOTGraphTraits : public DefaultDOTGraphTraits { - - DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} - - static std::string getGraphName(const CGForDotView *Graph) { - return "CG for " + Graph->F->getName().str(); - } - - std::string getNodeLabel(const CGForDotView::Node *Node, - const CGForDotView *Graph) { - return Graph->getNodeLabel(Node); - } - - static std::string getNodeAttributes(const CGForDotView::Node *Node, - const CGForDotView *Graph) { - return Graph->getNodeAttributes(Node); - } - - static std::string getEdgeAttributes(const CGForDotView::Node *Node, - CGForDotView::child_iterator I, - const CGForDotView *Graph) { - unsigned ChildIdx = I - Node->Children.begin(); - switch (Node->ChildrenTypes[ChildIdx]) { - case CGForDotView::PointsTo: return ""; - case CGForDotView::Defered: return "color=\"gray\""; - } - } - }; -} // end llvm namespace - -#endif - -void EscapeAnalysis::ConnectionGraph::viewCG() const { - /// When asserts are disabled, this should be a NoOp. -#ifndef NDEBUG - CGForDotView CGDot(this); - llvm::ViewGraph(&CGDot, "connection-graph"); -#endif -} - -void EscapeAnalysis::CGNode::dump() const { - llvm::errs() << getTypeStr(); - if (V) - llvm::errs() << ": " << *V; - else - llvm::errs() << '\n'; - - if (mergeTo) { - llvm::errs() << " -> merged to "; - mergeTo->dump(); - } -} - -const char *EscapeAnalysis::CGNode::getTypeStr() const { - switch (Type) { - case NodeType::Value: return "Val"; - case NodeType::Content: return "Con"; - case NodeType::Argument: return "Arg"; - case NodeType::Return: return "Ret"; - } -} - -void EscapeAnalysis::ConnectionGraph::dump() const { - print(llvm::errs()); -} - -void EscapeAnalysis::ConnectionGraph::print(llvm::raw_ostream &OS) const { -#ifndef NDEBUG - OS << "CG of " << F->getName() << '\n'; - - // Assign the same IDs to SILValues as the SILPrinter does. - llvm::DenseMap InstToIDMap; - InstToIDMap[nullptr] = (unsigned)-1; - F->numberValues(InstToIDMap); - - // Assign consecutive subindices for nodes which map to the same value. - llvm::DenseMap NumSubindicesPerValue; - llvm::DenseMap Node2Subindex; - - // Sort by SILValue ID+Subindex. To make the output somehow consistent with - // the output of the function's SIL. - auto sortNodes = [&](llvm::SmallVectorImpl &Nodes) { - std::sort(Nodes.begin(), Nodes.end(), - [&](CGNode *Nd1, CGNode *Nd2) -> bool { - unsigned VIdx1 = InstToIDMap[Nd1->V]; - unsigned VIdx2 = InstToIDMap[Nd2->V]; - if (VIdx1 != VIdx2) - return VIdx1 < VIdx2; - return Node2Subindex[Nd1] < Node2Subindex[Nd2]; - }); - }; - - auto NodeStr = [&](CGNode *Nd) -> std::string { - std::string Str; - if (Nd->V) { - llvm::raw_string_ostream OS(Str); - OS << '%' << InstToIDMap[Nd->V]; - unsigned Idx = Node2Subindex[Nd]; - if (Idx != 0) - OS << '.' << Idx; - OS.flush(); - } - return Str; - }; - - llvm::SmallVector SortedNodes; - for (CGNode *Nd : Nodes) { - if (!Nd->isMerged) { - unsigned &Idx = NumSubindicesPerValue[Nd->V]; - Node2Subindex[Nd] = Idx++; - SortedNodes.push_back(Nd); - } - } - sortNodes(SortedNodes); - - llvm::DenseMap Idx2UsePoint; - for (auto Iter : UsePoints) { - Idx2UsePoint[Iter.second] = Iter.first; - } - - for (CGNode *Nd : SortedNodes) { - OS << " " << Nd->getTypeStr() << ' ' << NodeStr(Nd) << " Esc: "; - switch (Nd->getEscapeState()) { - case EscapeState::None: { - const char *Separator = ""; - for (unsigned VIdx = Nd->UsePoints.find_first(); VIdx != -1u; - VIdx = Nd->UsePoints.find_next(VIdx)) { - ValueBase *V = Idx2UsePoint[VIdx]; - OS << Separator << '%' << InstToIDMap[V]; - Separator = ","; - } - break; - } - case EscapeState::Return: - OS << 'R'; - break; - case EscapeState::Arguments: - OS << 'A'; - break; - case EscapeState::Global: - OS << 'G'; - break; - } - OS << ", Succ: "; - const char *Separator = ""; - if (CGNode *PT = Nd->getPointsToEdge()) { - OS << '(' << NodeStr(PT) << ')'; - Separator = ", "; - } - llvm::SmallVector SortedDefers = Nd->defersTo; - sortNodes(SortedDefers); - for (CGNode *Def : SortedDefers) { - OS << Separator << NodeStr(Def); - Separator = ", "; - } - OS << '\n'; - } - OS << "End\n"; -#endif -} - -void EscapeAnalysis::ConnectionGraph::verify() const { -#ifndef NDEBUG - verifyStructure(); - - // Check graph invariance 4) - for (CGNode *Nd : Nodes) { - assert(Nd->matchPointToOfDefers()); - } -#endif -} - -void EscapeAnalysis::ConnectionGraph::verifyStructure() const { -#ifndef NDEBUG - for (CGNode *Nd : Nodes) { - if (Nd->isMerged) { - assert(Nd->mergeTo); - assert(!Nd->pointsTo); - assert(Nd->defersTo.empty()); - assert(Nd->Preds.empty()); - assert(Nd->Type == NodeType::Content); - continue; - } - // Check if predecessor and successor edges are linked correctly. - for (Predecessor Pred : Nd->Preds) { - CGNode *PredNode = Pred.getPointer(); - if (Pred.getInt() == EdgeType::Defer) { - assert(PredNode->findDefered(Nd) != PredNode->defersTo.end()); - } else { - assert(Pred.getInt() == EdgeType::PointsTo); - assert(PredNode->getPointsToEdge() == Nd); - } - } - for (CGNode *Def : Nd->defersTo) { - assert(Def->findPred(Predecessor(Nd, EdgeType::Defer)) != Def->Preds.end()); - assert(Def != Nd); - } - if (CGNode *PT = Nd->getPointsToEdge()) { - assert(PT->Type == NodeType::Content); - assert(PT->findPred(Predecessor(Nd, EdgeType::PointsTo)) != PT->Preds.end()); - } - } -#endif -} - -//===----------------------------------------------------------------------===// -// EscapeAnalysis -//===----------------------------------------------------------------------===// - -EscapeAnalysis::EscapeAnalysis(SILModule *M) : - SILAnalysis(AnalysisKind::Escape), M(M), - ArrayType(M->getASTContext().getArrayDecl()), - CGA(nullptr), shouldRecompute(true) { -} - - -void EscapeAnalysis::initialize(SILPassManager *PM) { - BCA = PM->getAnalysis(); - CGA = PM->getAnalysis(); -} - -/// Returns true if we need to add defer edges for the arguments of a block. -static bool linkBBArgs(SILBasicBlock *BB) { - // Don't need to handle function arguments. - if (BB == &BB->getParent()->front()) - return false; - // We don't need to link to the try_apply's normal result argument, because - // we handle it separatly in setAllEscaping() and mergeCalleeGraph(). - if (SILBasicBlock *SinglePred = BB->getSinglePredecessor()) { - auto *TAI = dyn_cast(SinglePred->getTerminator()); - if (TAI && BB == TAI->getNormalBB()) - return false; - } - return true; -} - -/// Returns true if the type \p Ty is a reference or transitively contains -/// a reference, i.e. if it is a "pointer" type. -static bool isOrContainsReference(SILType Ty, SILModule *Mod) { - if (Ty.hasReferenceSemantics()) - return true; - - if (Ty.getSwiftType() == Mod->getASTContext().TheRawPointerType) - return true; - - if (auto *Str = Ty.getStructOrBoundGenericStruct()) { - for (auto *Field : Str->getStoredProperties()) { - if (isOrContainsReference(Ty.getFieldType(Field, *Mod), Mod)) - return true; - } - return false; - } - if (auto TT = Ty.getAs()) { - for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) { - if (isOrContainsReference(Ty.getTupleElementType(i), Mod)) - return true; - } - return false; - } - if (auto En = Ty.getEnumOrBoundGenericEnum()) { - for (auto *ElemDecl : En->getAllElements()) { - if (ElemDecl->hasArgumentType() && - isOrContainsReference(Ty.getEnumElementType(ElemDecl, *Mod), Mod)) - return true; - } - return false; - } - return false; -} - -bool EscapeAnalysis::isPointer(ValueBase *V) { - assert(V->hasValue()); - SILType Ty = V->getType(0); - auto Iter = isPointerCache.find(Ty); - if (Iter != isPointerCache.end()) - return Iter->second; - - bool IP = (Ty.isAddress() || Ty.isLocalStorage() || - isOrContainsReference(Ty, M)); - isPointerCache[Ty] = IP; - return IP; -} - -void EscapeAnalysis::buildConnectionGraphs(FunctionInfo *FInfo) { - ConnectionGraph *ConGraph = &FInfo->Graph; - // We use a worklist for iteration to visit the blocks in dominance order. - llvm::SmallPtrSet VisitedBlocks; - llvm::SmallVector WorkList; - VisitedBlocks.insert(&*ConGraph->F->begin()); - WorkList.push_back(&*ConGraph->F->begin()); - - while (!WorkList.empty()) { - SILBasicBlock *BB = WorkList.pop_back_val(); - - // Create edges for the instructions. - for (auto &I : *BB) { - analyzeInstruction(&I, FInfo); - } - for (auto &Succ : BB->getSuccessors()) { - if (VisitedBlocks.insert(Succ.getBB()).second) - WorkList.push_back(Succ.getBB()); - } - } - - // Second step: create defer-edges for block arguments. - for (SILBasicBlock &BB : *ConGraph->F) { - if (!linkBBArgs(&BB)) - continue; - - // Create defer-edges from the block arguments to it's values in the - // predecessor's terminator instructions. - for (SILArgument *BBArg : BB.getBBArgs()) { - CGNode *ArgNode = ConGraph->getNode(BBArg, this); - if (!ArgNode) - continue; - - llvm::SmallVector Incoming; - if (!BBArg->getIncomingValues(Incoming)) { - // We don't know where the block argument comes from -> treat it - // conservatively. - ConGraph->setEscapesGlobal(ArgNode); - continue; - } - - for (SILValue Src : Incoming) { - CGNode *SrcArg = ConGraph->getNode(Src, this); - if (SrcArg) { - ConGraph->defer(ArgNode, SrcArg); - } else { - ConGraph->setEscapesGlobal(ArgNode); - break; - } - } - } - } - - ConGraph->propagateEscapeStates(); - mergeSummaryGraph(&FInfo->SummaryGraph, ConGraph); - FInfo->Valid = true; -} - -bool EscapeAnalysis::allCalleeFunctionsVisible(FullApplySite FAS) { - auto Callees = BCA->getCalleeList(FAS); - if (Callees.isIncomplete()) - return false; - - for (SILFunction *Callee : Callees) { - if (Callee->isExternalDeclaration()) - return false; - } - return true; -} - -void EscapeAnalysis::analyzeInstruction(SILInstruction *I, - FunctionInfo *FInfo) { - ConnectionGraph *ConGraph = &FInfo->Graph; - FullApplySite FAS = FullApplySite::isa(I); - if (FAS) { - ArraySemanticsCall ASC(FAS.getInstruction()); - switch (ASC.getKind()) { - case ArrayCallKind::kArrayPropsIsNative: - case ArrayCallKind::kArrayPropsIsNativeTypeChecked: - case ArrayCallKind::kCheckSubscript: - case ArrayCallKind::kCheckIndex: - case ArrayCallKind::kGetCount: - case ArrayCallKind::kGetCapacity: - case ArrayCallKind::kMakeMutable: - // These array semantics calls do not capture anything. - return; - case ArrayCallKind::kArrayUninitialized: - // array.uninitialized may have a first argument which is the - // allocated array buffer. The call is like a struct(buffer) - // instruction. - if (CGNode *BufferNode = ConGraph->getNode(FAS.getArgument(0), this)) { - ConGraph->defer(ConGraph->getNode(I, this), BufferNode); - } - return; - case ArrayCallKind::kGetArrayOwner: - if (CGNode *BufferNode = ConGraph->getNode(ASC.getSelf(), this)) { - ConGraph->defer(ConGraph->getNode(I, this), BufferNode); - } - return; - case ArrayCallKind::kGetElement: - // This is like a load from a ref_element_addr. - if (FAS.getArgument(0).getType().isAddress()) { - if (CGNode *AddrNode = ConGraph->getNode(ASC.getSelf(), this)) { - if (CGNode *DestNode = ConGraph->getNode(FAS.getArgument(0), this)) { - // One content node for going from the array buffer pointer to - // the element address (like ref_element_addr). - CGNode *RefElement = ConGraph->getContentNode(AddrNode); - // Another content node to actually load the element. - CGNode *ArrayContent = ConGraph->getContentNode(RefElement); - // The content of the destination address. - CGNode *DestContent = ConGraph->getContentNode(DestNode); - ConGraph->defer(DestContent, ArrayContent); - return; - } - } - } - break; - case ArrayCallKind::kGetElementAddress: - // This is like a ref_element_addr. - if (CGNode *SelfNode = ConGraph->getNode(ASC.getSelf(), this)) { - ConGraph->defer(ConGraph->getNode(I, this), - ConGraph->getContentNode(SelfNode)); - } - return; - default: - break; - } - - if (allCalleeFunctionsVisible(FAS)) { - // We handle this apply site afterwards by merging the callee graph(s) - // into the caller graph. - FInfo->KnownCallees.push_back(FAS); - return; - } - - if (auto *Fn = FAS.getCalleeFunction()) { - if (Fn->getName() == "swift_bufferAllocate") - // The call is a buffer allocation, e.g. for Array. - return; - } - } - if (isProjection(I)) - return; - - // Instructions which return the address of non-writable memory cannot have - // an effect on escaping. - if (isNonWritableMemoryAddress(I)) - return; - - switch (I->getKind()) { - case ValueKind::AllocStackInst: - case ValueKind::AllocRefInst: - case ValueKind::AllocBoxInst: - case ValueKind::DeallocStackInst: - case ValueKind::StrongRetainInst: - case ValueKind::StrongRetainUnownedInst: - case ValueKind::RetainValueInst: - case ValueKind::UnownedRetainInst: - case ValueKind::BranchInst: - case ValueKind::CondBranchInst: - case ValueKind::SwitchEnumInst: - case ValueKind::DebugValueInst: - case ValueKind::DebugValueAddrInst: - // These instructions don't have any effect on escaping. - return; - case ValueKind::StrongReleaseInst: - case ValueKind::ReleaseValueInst: - case ValueKind::UnownedReleaseInst: { - SILValue OpV = I->getOperand(0); - if (CGNode *AddrNode = ConGraph->getNode(OpV, this)) { - // A release instruction may deallocate the pointer operand. This may - // capture any content of the released object, but not the pointer to - // the object itself (because it will be a dangling pointer after - // deallocation). - CGNode *CapturedByDeinit = ConGraph->getContentNode(AddrNode); - CapturedByDeinit = ConGraph->getContentNode(CapturedByDeinit); - if (isArrayOrArrayStorage(OpV)) { - CapturedByDeinit = ConGraph->getContentNode(CapturedByDeinit); - } - ConGraph->setEscapesGlobal(CapturedByDeinit); - } - return; - } - case ValueKind::LoadInst: - case ValueKind::LoadWeakInst: - // We treat ref_element_addr like a load (see NodeType::Content). - case ValueKind::RefElementAddrInst: - if (isPointer(I)) { - CGNode *AddrNode = ConGraph->getNode(I->getOperand(0), this); - if (!AddrNode) { - // A load from an address we don't handle -> be conservative. - CGNode *ValueNode = ConGraph->getNode(I, this); - ConGraph->setEscapesGlobal(ValueNode); - return; - } - CGNode *PointsTo = ConGraph->getContentNode(AddrNode); - // No need for a separate node for the load instruction: - // just reuse the content node. - ConGraph->setNode(I, PointsTo); - } - return; - case ValueKind::StoreInst: - case ValueKind::StoreWeakInst: - if (CGNode *ValueNode = ConGraph->getNode(I->getOperand(StoreInst::Src), this)) { - CGNode *AddrNode = ConGraph->getNode(I->getOperand(StoreInst::Dest), this); - if (AddrNode) { - // Create a defer-edge from the content to the stored value. - CGNode *PointsTo = ConGraph->getContentNode(AddrNode); - ConGraph->defer(PointsTo, ValueNode); - } else { - // A store to an address we don't handle -> be conservative. - ConGraph->setEscapesGlobal(ValueNode); - } - } - return; - case ValueKind::PartialApplyInst: { - // The result of a partial_apply is a thick function which stores the - // boxed partial applied arguments. We create defer-edges from the - // partial_apply values to the arguments. - CGNode *ResultNode = ConGraph->getNode(I, this); - assert(ResultNode && "thick functions must have a CG node"); - for (const Operand &Op : I->getAllOperands()) { - if (CGNode *ArgNode = ConGraph->getNode(Op.get(), this)) { - ConGraph->defer(ResultNode, ArgNode); - } - } - return; - } - case ValueKind::StructInst: - case ValueKind::TupleInst: - case ValueKind::EnumInst: { - // Aggregate composition is like assigning the aggregate fields to the - // resulting aggregate value. - CGNode *ResultNode = nullptr; - for (const Operand &Op : I->getAllOperands()) { - if (CGNode *FieldNode = ConGraph->getNode(Op.get(), this)) { - if (!ResultNode) { - // A small optimization to reduce the graph size: we re-use the - // first field node as result node. - ConGraph->setNode(I, FieldNode); - ResultNode = FieldNode; - assert(isPointer(I)); - } else { - ConGraph->defer(ResultNode, FieldNode); - } - } - } - return; - } - case ValueKind::UncheckedRefCastInst: - // A cast is almost like a projection. - if (CGNode *OpNode = ConGraph->getNode(I->getOperand(0), this)) { - ConGraph->setNode(I, OpNode); - } - break; - case ValueKind::ReturnInst: - if (CGNode *ValueNd = ConGraph->getNode(cast(I)->getOperand(), this)) { - ConGraph->defer(ConGraph->getReturnNode(), - ValueNd); - } - return; - default: - // We handle all other instructions conservatively. - setAllEscaping(I, ConGraph); - return; - } -} - -bool EscapeAnalysis::isArrayOrArrayStorage(SILValue V) { - for (;;) { - if (V.getType().getNominalOrBoundGenericNominal() == ArrayType) - return true; - - if (!isProjection(V.getDef())) - return false; - - V = dyn_cast(V.getDef())->getOperand(0); - } -} - -void EscapeAnalysis::setAllEscaping(SILInstruction *I, - ConnectionGraph *ConGraph) { - if (auto *TAI = dyn_cast(I)) { - setEscapesGlobal(ConGraph, TAI->getNormalBB()->getBBArg(0)); - setEscapesGlobal(ConGraph, TAI->getErrorBB()->getBBArg(0)); - } - // Even if the instruction does not write memory we conservatively set all - // operands to escaping, because they may "escape" to the result value in - // an unspecified way. For example consider bit-casting a pointer to an int. - // In this case we don't even create a node for the resulting int value. - for (const Operand &Op : I->getAllOperands()) { - SILValue OpVal = Op.get(); - if (!isNonWritableMemoryAddress(OpVal.getDef())) - setEscapesGlobal(ConGraph, OpVal); - } - // Even if the instruction does not write memory it could e.g. return the - // address of global memory. Therefore we have to define it as escaping. - setEscapesGlobal(ConGraph, I); -} - -void EscapeAnalysis::recompute() { - - // Did anything change since the last recompuation? (Probably yes) - if (!shouldRecompute) - return; - - DEBUG(llvm::dbgs() << "recompute escape analysis\n"); - - Function2Info.clear(); - Allocator.DestroyAll(); - shouldRecompute = false; - - CallGraph &CG = CGA->getOrBuildCallGraph(); - - // TODO: Remove this workaround when the bottom-up function order is - // updated automatically. - CG.invalidateBottomUpFunctionOrder(); - - auto BottomUpFunctions = CG.getBottomUpFunctionOrder(); - std::vector FInfos; - FInfos.reserve(BottomUpFunctions.size()); - - // First step: create the initial connection graphs for all functions. - for (SILFunction *F : BottomUpFunctions) { - if (F->isExternalDeclaration()) - continue; - - DEBUG(llvm::dbgs() << " build initial graph for " << F->getName() << '\n'); - - auto *FInfo = new (Allocator.Allocate()) FunctionInfo(F); - Function2Info[F] = FInfo; - buildConnectionGraphs(FInfo); - - FInfos.push_back(FInfo); - FInfo->NeedMergeCallees = true; - } - - // Second step: propagate the connection graphs up the call tree until it - // stabalizes. - int Iteration = 0; - bool Changed; - do { - DEBUG(llvm::dbgs() << "iteration " << Iteration << '\n'); - Changed = false; - for (FunctionInfo *FInfo : FInfos) { - if (!FInfo->NeedMergeCallees) - continue; - FInfo->NeedMergeCallees = false; - - // Limit the total number of iterations. First to limit compile time, - // second to make sure that the loop terminates. Theoretically this - // should always be the case, but who knows? - if (Iteration >= MaxGraphMerges) { - DEBUG(llvm::dbgs() << " finalize " << - FInfo->Graph.F->getName() << '\n'); - finalizeGraphsConservatively(FInfo); - continue; - } - - DEBUG(llvm::dbgs() << " merge into " << - FInfo->Graph.F->getName() << '\n'); - - // Merge the callee-graphs into the graph of the current function. - if (!mergeAllCallees(FInfo, CG)) - continue; - - FInfo->Graph.propagateEscapeStates(); - - // Derive the summary graph of the current function. Even if the - // complete graph of the function did change, it does not mean that the - // summary graph will change. - if (!mergeSummaryGraph(&FInfo->SummaryGraph, &FInfo->Graph)) - continue; - - // Trigger another graph merging action in all caller functions. - auto &CallerSet = CG.getCallerEdges(FInfo->Graph.F); - for (CallGraphEdge *CallerEdge : CallerSet) { - if (!CallerEdge->canCallUnknownFunction()) { - SILFunction *Caller = CallerEdge->getInstruction()->getFunction(); - FunctionInfo *CallerInfo = Function2Info.lookup(Caller); - assert(CallerInfo && "We should have an info for all functions"); - CallerInfo->NeedMergeCallees = true; - } - } - Changed = true; - } - Iteration++; - } while (Changed); - - verify(); -} - -bool EscapeAnalysis::mergeAllCallees(FunctionInfo *FInfo, CallGraph &CG) { - bool Changed = false; - for (FullApplySite FAS : FInfo->KnownCallees) { - auto Callees = CG.getCallees(FAS.getInstruction()); - assert(!Callees.canCallUnknownFunction() && - "knownCallees should not contain an unknown function"); - for (SILFunction *Callee : Callees) { - DEBUG(llvm::dbgs() << " callee " << Callee->getName() << '\n'); - FunctionInfo *CalleeInfo = Function2Info.lookup(Callee); - assert(CalleeInfo && "We should have an info for all functions"); - Changed |= mergeCalleeGraph(FAS, &FInfo->Graph, &CalleeInfo->SummaryGraph); - } - } - return Changed; -} - -bool EscapeAnalysis::mergeCalleeGraph(FullApplySite FAS, - ConnectionGraph *CallerGraph, - ConnectionGraph *CalleeGraph) { - CGNodeMap Callee2CallerMapping; - - // First map the callee parameters to the caller arguments. - SILFunction *Callee = CalleeGraph->F; - unsigned numCallerArgs = FAS.getNumArguments(); - unsigned numCalleeArgs = Callee->getArguments().size(); - assert(numCalleeArgs >= numCallerArgs); - for (unsigned Idx = 0; Idx < numCalleeArgs; ++Idx) { - // If there are more callee parameters than arguments it means that the - // callee is the result of a partial_apply - a thick function. A thick - // function also references the boxed partially applied arguments. - // Therefore we map all the extra callee paramters to the callee operand - // of the apply site. - SILValue CallerArg = (Idx < numCallerArgs ? FAS.getArgument(Idx) : - FAS.getCallee()); - if (CGNode *CalleeNd = CalleeGraph->getNode(Callee->getArgument(Idx), this)) { - Callee2CallerMapping.add(CalleeNd, CallerGraph->getNode(CallerArg, this)); - } - } - - // Map the return value. - if (CGNode *RetNd = CalleeGraph->getReturnNodeOrNull()) { - ValueBase *CallerReturnVal = nullptr; - if (auto *TAI = dyn_cast(FAS.getInstruction())) { - CallerReturnVal = TAI->getNormalBB()->getBBArg(0); - } else { - CallerReturnVal = FAS.getInstruction(); - } - CGNode *CallerRetNd = CallerGraph->getNode(CallerReturnVal, this); - Callee2CallerMapping.add(RetNd, CallerRetNd); - } - return CallerGraph->mergeFrom(CalleeGraph, Callee2CallerMapping); -} - -bool EscapeAnalysis::mergeSummaryGraph(ConnectionGraph *SummaryGraph, - ConnectionGraph *Graph) { - - // Make a 1-to-1 mapping of all arguments and the return value. - CGNodeMap Mapping; - for (SILArgument *Arg : Graph->F->getArguments()) { - if (CGNode *ArgNd = Graph->getNode(Arg, this)) { - Mapping.add(ArgNd, SummaryGraph->getNode(Arg, this)); - } - } - if (CGNode *RetNd = Graph->getReturnNodeOrNull()) { - Mapping.add(RetNd, SummaryGraph->getReturnNode()); - } - // Merging actually creates the summary graph. - return SummaryGraph->mergeFrom(Graph, Mapping); -} - - -void EscapeAnalysis::finalizeGraphsConservatively(FunctionInfo *FInfo) { - for (FullApplySite FAS : FInfo->KnownCallees) { - setAllEscaping(FAS.getInstruction(), &FInfo->Graph); - } - FInfo->Graph.propagateEscapeStates(); - mergeSummaryGraph(&FInfo->SummaryGraph, &FInfo->Graph); -} - -SILAnalysis *swift::createEscapeAnalysis(SILModule *M) { - return new EscapeAnalysis(M); -} diff --git a/lib/SILAnalysis/LoopAnalysis.cpp b/lib/SILAnalysis/LoopAnalysis.cpp deleted file mode 100644 index 2ebff435d9ebb..0000000000000 --- a/lib/SILAnalysis/LoopAnalysis.cpp +++ /dev/null @@ -1,34 +0,0 @@ -//===-------------- LoopAnalysis.cpp - SIL Loop Analysis -*- C++ -*--------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#include "swift/SIL/Dominance.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILPasses/PassManager.h" -#include "llvm/Support/Debug.h" - -using namespace swift; - -SILLoopInfo *SILLoopAnalysis::newFunctionAnalysis(SILFunction *F) { - assert(DA != nullptr && "Expect a valid dominance analysis"); - DominanceInfo *DT = DA->get(F); - assert(DT != nullptr && "Expect a valid dominance information"); - return new SILLoopInfo(F, DT); -} - -void SILLoopAnalysis::initialize(SILPassManager *PM) { - DA = PM->getAnalysis(); -} - -SILAnalysis *swift::createLoopAnalysis(SILModule *M) { - return new SILLoopAnalysis(M); -} diff --git a/lib/SILAnalysis/SideEffectAnalysis.cpp b/lib/SILAnalysis/SideEffectAnalysis.cpp deleted file mode 100644 index 7003cc4865013..0000000000000 --- a/lib/SILAnalysis/SideEffectAnalysis.cpp +++ /dev/null @@ -1,433 +0,0 @@ -//===---------- SideEffectAnalysis.cpp - SIL Side Effect Analysis ---------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-sea" -#include "swift/SILAnalysis/SideEffectAnalysis.h" -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" -#include "swift/SILAnalysis/FunctionOrder.h" -#include "swift/SILAnalysis/CallGraphAnalysis.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILPasses/PassManager.h" -#include "swift/SIL/SILArgument.h" - -using namespace swift; - -using FunctionEffects = SideEffectAnalysis::FunctionEffects; -using Effects = SideEffectAnalysis::Effects; -using MemoryBehavior = SILInstruction::MemoryBehavior; - -MemoryBehavior -FunctionEffects::getMemBehavior(RetainObserveKind ScanKind) const { - - bool Observe = (ScanKind == RetainObserveKind::ObserveRetains); - if ((Observe && mayAllocObjects()) || mayReadRC()) - return MemoryBehavior::MayHaveSideEffects; - - // Start with the global effects. - auto Behavior = GlobalEffects.getMemBehavior(ScanKind); - - // Add effects from the parameters. - for (auto &ParamEffect : ParamEffects) { - MemoryBehavior ArgBehavior = ParamEffect.getMemBehavior(ScanKind); - - if (ArgBehavior > Behavior) - Behavior = ArgBehavior; - - // Stop the scan if we've reached the highest level of side effect. - if (Behavior == MemoryBehavior::MayHaveSideEffects) - break; - } - return Behavior; -} - -bool FunctionEffects::mergeFrom(const FunctionEffects &RHS) { - bool Changed = mergeFlags(RHS); - Changed |= GlobalEffects.mergeFrom(RHS.GlobalEffects); - Changed |= LocalEffects.mergeFrom(RHS.LocalEffects); - // In case of an external function, the RHS may have 0 arguments. - unsigned NumArgs = RHS.ParamEffects.size(); - for (unsigned Idx = 0; Idx < NumArgs; Idx++) { - // In case of a partial_apply, the RHS (= callee) may have more arguments - // than the apply instruction. - if (Idx < ParamEffects.size()) { - Changed |= ParamEffects[Idx].mergeFrom(RHS.ParamEffects[Idx]); - } else { - Changed |= GlobalEffects.mergeFrom(RHS.ParamEffects[Idx]); - } - } - return Changed; -} - -bool FunctionEffects::mergeFromApply( - const FunctionEffects &ApplyEffects, FullApplySite FAS) { - bool Changed = mergeFlags(ApplyEffects); - Changed |= GlobalEffects.mergeFrom(ApplyEffects.GlobalEffects); - auto Args = FAS.getArguments(); - unsigned NumCalleeArgs = ApplyEffects.ParamEffects.size(); - assert(NumCalleeArgs == Args.size()); - for (unsigned Idx = 0; Idx < NumCalleeArgs; Idx++) { - // Map the callee argument effects to parameters of this function. - Effects *E = getEffectsOn(Args[Idx]); - Changed |= E->mergeFrom(ApplyEffects.ParamEffects[Idx]); - } - return Changed; -} - -void FunctionEffects::dump() { - llvm::errs() << *this << '\n'; -} - -static SILValue skipAddrProjections(SILValue V) { - for (;;) { - switch (V->getKind()) { - case ValueKind::IndexAddrInst: - case ValueKind::IndexRawPointerInst: - case ValueKind::StructElementAddrInst: - case ValueKind::TupleElementAddrInst: - case ValueKind::RefElementAddrInst: - case ValueKind::UncheckedTakeEnumDataAddrInst: - case ValueKind::PointerToAddressInst: - V = cast(V)->getOperand(0); - break; - default: - return V; - } - } - llvm_unreachable("there is no escape from an infinite loop"); -} - -static SILValue skipValueProjections(SILValue V) { - for (;;) { - switch (V->getKind()) { - case ValueKind::StructExtractInst: - case ValueKind::TupleExtractInst: - case ValueKind::UncheckedEnumDataInst: - case ValueKind::UncheckedTrivialBitCastInst: - V = cast(V)->getOperand(0); - break; - default: - return V; - } - } - llvm_unreachable("there is no escape from an infinite loop"); -} - -Effects *FunctionEffects::getEffectsOn(SILValue Addr) { - SILValue BaseAddr = skipValueProjections(skipAddrProjections(Addr)); - switch (BaseAddr->getKind()) { - case swift::ValueKind::SILArgument: { - // Can we associate the address to a function parameter? - SILArgument *Arg = cast(BaseAddr); - if (Arg->isFunctionArg()) { - return &ParamEffects[Arg->getIndex()]; - } - break; - } - case ValueKind::AllocStackInst: - case ValueKind::AllocRefInst: - case ValueKind::AllocRefDynamicInst: - case ValueKind::AllocBoxInst: - // Effects on locally allocated storage. - return &LocalEffects; - default: - break; - } - // Everything else. - return &GlobalEffects; -} - -bool SideEffectAnalysis::getDefinedEffects(FunctionEffects &Effects, - SILFunction *F) { - if (F->getLoweredFunctionType()->isNoReturn()) { - Effects.Traps = true; - return true; - } - switch (F->getEffectsKind()) { - case EffectsKind::ReadNone: - return true; - case EffectsKind::ReadOnly: - // @effects(readonly) is worthless if we have owned parameters, because - // the release inside the callee may call a deinit, which itself can do - // anything. - if (!F->hasOwnedParameters()) { - Effects.GlobalEffects.Reads = true; - return true; - } - break; - default: - break; - } - - return false; -} - -bool SideEffectAnalysis::getSemanticEffects(FunctionEffects &FE, - FullApplySite FAS) { - ArraySemanticsCall ASC(FAS.getInstruction()); - if (!ASC || !ASC.hasSelf()) - return false; - - auto &SelfEffects = FE.ParamEffects[FAS.getNumArguments() - 1]; - - // Currently we only handle array semantics. - // TODO: also handle other semantic functions. - - switch (ASC.getKind()) { - case ArrayCallKind::kGetCount: - case ArrayCallKind::kGetCapacity: - if (!ASC.mayHaveBridgedObjectElementType()) { - SelfEffects.Reads = true; - SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); - return true; - } - return false; - - case ArrayCallKind::kCheckSubscript: - case ArrayCallKind::kCheckIndex: - if (!ASC.mayHaveBridgedObjectElementType()) { - SelfEffects.Reads = true; - SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); - FE.Traps = true; - return true; - } - return false; - - case ArrayCallKind::kGetElement: - if (!ASC.mayHaveBridgedObjectElementType()) { - SelfEffects.Reads = true; - SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); - if (FAS.getOrigCalleeType()->hasIndirectResult()) - FE.ParamEffects[0].Writes = true; - return true; - } - return false; - - case ArrayCallKind::kArrayPropsIsNative: - case ArrayCallKind::kArrayPropsIsNativeTypeChecked: - SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); - // The isNative checks evaluate to a constant (no read!) if the array - // cannot be bridged. - if (ASC.mayHaveBridgedObjectElementType()) - SelfEffects.Reads = true; - return true; - - case ArrayCallKind::kGetElementAddress: - SelfEffects.Reads = true; - SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); - return true; - - case ArrayCallKind::kMakeMutable: - if (!ASC.mayHaveBridgedObjectElementType()) { - SelfEffects.Writes = true; - FE.GlobalEffects.Releases = true; - FE.AllocsObjects = true; - FE.ReadsRC = true; - return true; - } - return false; - - default: - return false; - } -} - -void SideEffectAnalysis::analyzeFunction(SILFunction *F, - WorkListType &WorkList, - CallGraph &CG) { - DEBUG(llvm::dbgs() << "analyze " << F->getName() << "\n"); - auto *FE = getFunctionEffects(F, true); - - // Handle @effects attributes - if (getDefinedEffects(*FE, F)) - return; - - if (!F->isDefinition()) { - // We can't assume anything about external functions. - FE->setWorstEffects(); - return; - } - - FunctionEffects NewEffects(F->getArguments().size()); -#ifndef NDEBUG - FunctionEffects RefEffects = *FE; -#endif - // Check all instructions of the function - for (auto &BB : *F) { - for (auto &I : BB) { - analyzeInstruction(NewEffects, &I); - DEBUG(if (RefEffects.mergeFrom(NewEffects)) - llvm::dbgs() << " " << NewEffects << "\t changed in " << I); - } - } - if (FE->mergeFrom(NewEffects)) { - // The effects have changed. We also have to recompute the effects of all - // callers. - for (auto *CallerEdge : CG.getCallerEdges(F)) { - SILFunction *Caller = CallerEdge->getInstruction()->getFunction(); - WorkList.insert(Caller); - } - } -} - -void SideEffectAnalysis::analyzeInstruction(FunctionEffects &FE, - SILInstruction *I) { - if (FullApplySite FAS = FullApplySite::isa(I)) { - FunctionEffects ApplyEffects; - getEffectsOfApply(ApplyEffects, FAS, true); - FE.mergeFromApply(ApplyEffects, FAS); - return; - } - // Handle some kind of instructions specially. - switch (I->getKind()) { - case ValueKind::AllocStackInst: - case ValueKind::DeallocStackInst: - return; - case ValueKind::StrongRetainInst: - case ValueKind::StrongRetainUnownedInst: - case ValueKind::RetainValueInst: - case ValueKind::UnownedRetainInst: - FE.getEffectsOn(I->getOperand(0))->Retains = true; - return; - case ValueKind::StrongReleaseInst: - case ValueKind::ReleaseValueInst: - case ValueKind::UnownedReleaseInst: - FE.getEffectsOn(I->getOperand(0))->Releases = true; - - // TODO: Check the call graph to be less conservative about what - // destructors might be called. - FE.setWorstEffects(); - return; - case ValueKind::LoadInst: - FE.getEffectsOn(cast(I)->getOperand())->Reads = true; - return; - case ValueKind::StoreInst: - FE.getEffectsOn(cast(I)->getDest())->Writes = true; - return; - case ValueKind::CondFailInst: - FE.Traps = true; - return; - case ValueKind::PartialApplyInst: - FE.AllocsObjects = true; - return; - case ValueKind::BuiltinInst: { - auto &BI = cast(I)->getBuiltinInfo(); - switch (BI.ID) { - case BuiltinValueKind::IsUnique: - // TODO: derive this information in a more general way, e.g. add it - // to Builtins.def - FE.ReadsRC = true; - break; - default: - break; - } - // Detailed memory effects of builtins are handled below by checking the - // memory behavior of the instruction. - break; - } - default: - break; - } - - if (isa(I)) { - // Excluding AllocStackInst (which is handled above). - FE.AllocsObjects = true; - } - - // Check the general memory behavior for instructions we didn't handle above. - switch (I->getMemoryBehavior()) { - case MemoryBehavior::None: - break; - case MemoryBehavior::MayRead: - FE.GlobalEffects.Reads = true; - break; - case MemoryBehavior::MayWrite: - FE.GlobalEffects.Writes = true; - break; - case MemoryBehavior::MayReadWrite: - FE.GlobalEffects.Reads = true; - FE.GlobalEffects.Writes = true; - break; - case MemoryBehavior::MayHaveSideEffects: - FE.setWorstEffects(); - break; - } - if (I->mayTrap()) - FE.Traps = true; -} - -void SideEffectAnalysis::getEffectsOfApply(FunctionEffects &ApplyEffects, - FullApplySite FAS, - bool isRecomputing) { - - assert(ApplyEffects.ParamEffects.size() == 0 && - "Not using a new ApplyEffects?"); - ApplyEffects.ParamEffects.resize(FAS.getNumArguments()); - - // Is this a call to a semantics function? - if (getSemanticEffects(ApplyEffects, FAS)) - return; - - auto Callees = BCA->getCalleeList(FAS); - if (Callees.isIncomplete()) { - ApplyEffects.setWorstEffects(); - return; - } - - // We can see all the callees. So we just merge the effects from all of - // them. - for (auto *F : Callees) { - auto *E = getFunctionEffects(F, isRecomputing); - ApplyEffects.mergeFrom(*E); - } -} - -void SideEffectAnalysis::initialize(SILPassManager *PM) { - BCA = PM->getAnalysis(); - CGA = PM->getAnalysis(); -} - -void SideEffectAnalysis::recompute() { - - // Did anything change since the last recompuation? (Probably yes) - if (!shouldRecompute) - return; - - Function2Effects.clear(); - Allocator.DestroyAll(); - shouldRecompute = false; - - WorkListType WorkList; - - BottomUpFunctionOrder BottomUpOrder(M, BCA); - auto BottomUpFunctions = BottomUpOrder.getFunctions(); - - // Copy the bottom-up function list into the worklist. - for (auto I = BottomUpFunctions.rbegin(), E = BottomUpFunctions.rend(); - I != E; ++I) - WorkList.insert(*I); - - CallGraph &CG = CGA->getOrBuildCallGraph(); - - // Iterate until the side-effect information stabilizes. - while (!WorkList.empty()) { - auto *F = WorkList.pop_back_val(); - analyzeFunction(F, WorkList, CG); - } -} - -void SideEffectAnalysis::getEffects(FunctionEffects &FE, FullApplySite FAS) { - getEffectsOfApply(FE, FAS, false); -} - -SILAnalysis *swift::createSideEffectAnalysis(SILModule *M) { - return new SideEffectAnalysis(M); -} diff --git a/lib/SILAnalysis/ValueTracking.cpp b/lib/SILAnalysis/ValueTracking.cpp deleted file mode 100644 index 118fea23e991e..0000000000000 --- a/lib/SILAnalysis/ValueTracking.cpp +++ /dev/null @@ -1,668 +0,0 @@ -//===-- ValueTracking.h - SIL Value Tracking Analysis ----------*- C++ -*--===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-value-tracking" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILAnalysis/SimplifyInstruction.h" -#include "swift/SIL/SILArgument.h" -#include "swift/SIL/SILInstruction.h" -#include "swift/SIL/SILValue.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SIL/PatternMatch.h" -#include "llvm/Support/Debug.h" -using namespace swift; -using namespace swift::PatternMatch; - -/// Strip off casts/indexing insts/address projections from V until there is -/// nothing left to strip. -/// FIXME: Maybe put this on SILValue? -/// FIXME: Why don't we strip projections after stripping indexes? -SILValue swift::getUnderlyingObject(SILValue V) { - while (true) { - SILValue V2 = V.stripCasts().stripAddressProjections().stripIndexingInsts(); - if (V2 == V) - return V2; - V = V2; - } -} - -/// Returns true if the ValueBase inside V is an apply whose callee is a no read -/// builtin. -static bool isNoReadBuiltinInst(SILValue V) { - auto *BI = dyn_cast(V); - return BI && !BI->mayReadOrWriteMemory(); -} - -/// Is Inst an instruction which escapes if and only if one of its results -/// escape? -static bool isTransitiveEscapeInst(SILInstruction *Inst) { - switch (Inst->getKind()) { - case ValueKind::AllocBoxInst: - case ValueKind::AllocExistentialBoxInst: - case ValueKind::AllocRefInst: - case ValueKind::AllocRefDynamicInst: - case ValueKind::AllocStackInst: - case ValueKind::AllocValueBufferInst: - case ValueKind::BuiltinInst: - case ValueKind::ApplyInst: - case ValueKind::TryApplyInst: - case ValueKind::WitnessMethodInst: - case ValueKind::CopyAddrInst: - case ValueKind::RetainValueInst: - case ValueKind::DeallocBoxInst: - case ValueKind::DeallocExistentialBoxInst: - case ValueKind::DeallocRefInst: - case ValueKind::DeallocPartialRefInst: - case ValueKind::DeallocStackInst: - case ValueKind::DeallocValueBufferInst: - case ValueKind::DebugValueAddrInst: - case ValueKind::DebugValueInst: - case ValueKind::DestroyAddrInst: - case ValueKind::ReleaseValueInst: - case ValueKind::AutoreleaseValueInst: - case ValueKind::FloatLiteralInst: - case ValueKind::FunctionRefInst: - case ValueKind::IntegerLiteralInst: - case ValueKind::LoadInst: - case ValueKind::LoadWeakInst: - case ValueKind::MetatypeInst: - case ValueKind::ObjCProtocolInst: - case ValueKind::GlobalAddrInst: - case ValueKind::StoreInst: - case ValueKind::StoreWeakInst: - case ValueKind::StringLiteralInst: - case ValueKind::CopyBlockInst: - case ValueKind::StrongReleaseInst: - case ValueKind::StrongPinInst: // Pin handle is independently managed - case ValueKind::StrongRetainAutoreleasedInst: - case ValueKind::StrongRetainInst: - case ValueKind::StrongRetainUnownedInst: - case ValueKind::StrongUnpinInst: - case ValueKind::UnownedReleaseInst: - case ValueKind::UnownedRetainInst: - case ValueKind::IsUniqueInst: - case ValueKind::IsUniqueOrPinnedInst: - case ValueKind::InjectEnumAddrInst: - case ValueKind::DeinitExistentialAddrInst: - case ValueKind::UnreachableInst: - case ValueKind::IsNonnullInst: - case ValueKind::CondFailInst: - case ValueKind::DynamicMethodBranchInst: - case ValueKind::ReturnInst: - case ValueKind::AutoreleaseReturnInst: - case ValueKind::ThrowInst: - case ValueKind::FixLifetimeInst: - return false; - - case ValueKind::AddressToPointerInst: - case ValueKind::ValueMetatypeInst: - case ValueKind::BranchInst: - case ValueKind::CheckedCastBranchInst: - case ValueKind::CheckedCastAddrBranchInst: - case ValueKind::ClassMethodInst: - case ValueKind::CondBranchInst: - case ValueKind::ConvertFunctionInst: - case ValueKind::DynamicMethodInst: - case ValueKind::EnumInst: - case ValueKind::IndexAddrInst: - case ValueKind::IndexRawPointerInst: - case ValueKind::InitBlockStorageHeaderInst: - case ValueKind::InitEnumDataAddrInst: - case ValueKind::InitExistentialAddrInst: - case ValueKind::InitExistentialMetatypeInst: - case ValueKind::InitExistentialRefInst: - case ValueKind::ObjCExistentialMetatypeToObjectInst: - case ValueKind::ObjCMetatypeToObjectInst: - case ValueKind::ObjCToThickMetatypeInst: - case ValueKind::UncheckedRefCastInst: - case ValueKind::UncheckedRefCastAddrInst: - case ValueKind::UncheckedAddrCastInst: - case ValueKind::UncheckedTrivialBitCastInst: - case ValueKind::UncheckedBitwiseCastInst: - case ValueKind::MarkDependenceInst: - case ValueKind::OpenExistentialAddrInst: - case ValueKind::OpenExistentialMetatypeInst: - case ValueKind::OpenExistentialRefInst: - case ValueKind::OpenExistentialBoxInst: - case ValueKind::PartialApplyInst: - case ValueKind::ProjectBoxInst: - case ValueKind::ProjectValueBufferInst: - case ValueKind::PointerToAddressInst: - case ValueKind::PointerToThinFunctionInst: - case ValueKind::ProjectBlockStorageInst: - case ValueKind::ExistentialMetatypeInst: - case ValueKind::RawPointerToRefInst: - case ValueKind::RefElementAddrInst: - case ValueKind::RefToRawPointerInst: - case ValueKind::RefToUnmanagedInst: - case ValueKind::RefToUnownedInst: - case ValueKind::SelectEnumInst: - case ValueKind::SelectEnumAddrInst: - case ValueKind::SelectValueInst: - case ValueKind::StructElementAddrInst: - case ValueKind::StructExtractInst: - case ValueKind::StructInst: - case ValueKind::SuperMethodInst: - case ValueKind::SwitchEnumAddrInst: - case ValueKind::SwitchEnumInst: - case ValueKind::SwitchValueInst: - case ValueKind::UncheckedEnumDataInst: - case ValueKind::UncheckedTakeEnumDataAddrInst: - case ValueKind::ThickToObjCMetatypeInst: - case ValueKind::ThinFunctionToPointerInst: - case ValueKind::ThinToThickFunctionInst: - case ValueKind::TupleElementAddrInst: - case ValueKind::TupleExtractInst: - case ValueKind::TupleInst: - case ValueKind::UnconditionalCheckedCastInst: - case ValueKind::UnconditionalCheckedCastAddrInst: - case ValueKind::UnmanagedToRefInst: - case ValueKind::UnownedToRefInst: - case ValueKind::UpcastInst: - case ValueKind::RefToBridgeObjectInst: - case ValueKind::BridgeObjectToRefInst: - case ValueKind::BridgeObjectToWordInst: - return true; - - case ValueKind::AssignInst: - case ValueKind::MarkFunctionEscapeInst: - case ValueKind::MarkUninitializedInst: - llvm_unreachable("Invalid in canonical SIL."); - - case ValueKind::SILArgument: - case ValueKind::SILUndef: - llvm_unreachable("These do not use other values."); - } -} - -/// Maximum amount of ValueCapture queries. -static unsigned const ValueCaptureSearchThreshold = 32; - -namespace { - -/// Are there any uses that should be ignored as capture uses. -/// -/// TODO: Expand this if we ever do the store of pointer analysis mentioned in -/// Basic AA. -enum CaptureException : unsigned { - None=0, - ReturnsCannotCapture=1, -}; - -} // end anonymous namespace - -/// Returns true if V is a value that is used in a manner such that we know its -/// captured or we don't understand whether or not it was captured. In such a -/// case to be conservative, we must assume it is captured. -/// FIXME: Maybe put this on SILValue? -static bool valueMayBeCaptured(SILValue V, CaptureException Exception) { - llvm::SmallVector Worklist; - llvm::SmallPtrSet Visited; - unsigned Count = 0; - - DEBUG(llvm::dbgs() << " Checking for capture.\n"); - - - // All all uses of V to the worklist. - for (auto *UI : V.getUses()) { - // If we have more uses than the threshold, be conservative and bail so we - // don't use too much compile time. - if (Count++ >= ValueCaptureSearchThreshold) - return true; - Visited.insert(UI); - Worklist.push_back(UI); - } - - // Until the worklist is empty... - while (!Worklist.empty()) { - // Pop off an operand and grab the operand's user... - Operand *Op = Worklist.pop_back_val(); - SILInstruction *Inst = Op->getUser(); - - DEBUG(llvm::dbgs() << " Visiting: " << *Inst); - - // If Inst is an instruction with the transitive escape property, V escapes - // if and only if the results of Inst escape as well. - if (isTransitiveEscapeInst(Inst)) { - DEBUG(llvm::dbgs() << " Found transitive escape " - "instruction!\n"); - for (auto *UI : Inst->getUses()) { - // If we have more uses than the threshold, be conservative and bail - // so we don't use too much compile time. - if (Count++ >= ValueCaptureSearchThreshold) - return true; - - if (Visited.insert(UI).second) { - Worklist.push_back(UI); - } - } - continue; - } - - // An apply of a builtin that does not read memory can not capture a value. - // - // TODO: Use analysis of the other function perhaps to see if it captures - // memory in some manner? - // TODO: Add in knowledge about how parameters work on swift to make this - // more aggressive. - if (isNoReadBuiltinInst(Inst)) - continue; - - // Loading from a pointer does not cause it to be captured. - if (isa(Inst)) - continue; - - // If we have a store and are storing into the pointer, this is not a - // capture. Otherwise it is safe. - if (auto *SI = dyn_cast(Inst)) { - if (SI->getDest() == Op->get()) { - continue; - } else { - return true; - } - } - - // Deallocation instructions don't capture. - if (isa(Inst)) - continue; - - // Debug instructions don't capture. - if (isa(Inst) || isa(Inst)) - continue; - - // RefCountOperations don't capture. - // - // The release case is true since Swift does not allow destructors to - // resurrect objects. This is enforced via a runtime failure. - if (isa(Inst)) - continue; - - // If we have a return instruction and we are assuming that returns don't - // capture, we are safe. - if (Exception == CaptureException::ReturnsCannotCapture && - (isa(Inst) || isa(Inst))) - continue; - - // We could not prove that Inst does not capture V. Be conservative and - // return true. - DEBUG(llvm::dbgs() << " Could not prove that inst does not capture " - "V!\n"); - return true; - } - - // We successfully proved that V is not captured. Return false. - DEBUG(llvm::dbgs() << " V was not captured!\n"); - return false; -} - -static bool isNoAliasArgument(SILValue V) { - auto *Arg = dyn_cast(V); - if (!Arg) - return false; - - return Arg->isFunctionArg() && V.getType().isAddress(); -} - -/// Return true if the pointer is to a function-local object that never escapes -/// from the function. -bool swift::isNonEscapingLocalObject(SILValue V) { - // If this is a local allocation, or the result of a no read apply inst (which - // can not affect memory in the caller), check to see if the allocation - // escapes. - if (isa(*V) || isNoReadBuiltinInst(V)) - return !valueMayBeCaptured(V, CaptureException::ReturnsCannotCapture); - - // If this is a no alias argument then it has not escaped before entering the - // function. Check if it escapes inside the function. - if (isNoAliasArgument(V)) - return !valueMayBeCaptured(V, CaptureException::ReturnsCannotCapture); - - // If this is an enum value. If it or its operand does not escape, it is - // local. - if (auto *EI = dyn_cast(V)) - return !EI->hasOperand() || - !valueMayBeCaptured(EI->getOperand(), - CaptureException::ReturnsCannotCapture); - - // Otherwise we could not prove that V is a non escaping local object. Be - // conservative and return false. - return false; -} - -/// Check if the value \p Value is known to be zero, non-zero or unknown. -IsZeroKind swift::isZeroValue(SILValue Value) { - // Inspect integer literals. - if (auto *L = dyn_cast(Value.getDef())) { - if (!L->getValue()) - return IsZeroKind::Zero; - return IsZeroKind::NotZero; - } - - // Inspect Structs. - switch (Value.getDef()->getKind()) { - // Bitcast of zero is zero. - case ValueKind::UncheckedTrivialBitCastInst: - // Extracting from a zero class returns a zero. - case ValueKind::StructExtractInst: - return isZeroValue(cast(Value.getDef())->getOperand(0)); - default: - break; - } - - // Inspect casts. - if (auto *BI = dyn_cast(Value.getDef())) { - switch (BI->getBuiltinInfo().ID) { - case BuiltinValueKind::IntToPtr: - case BuiltinValueKind::PtrToInt: - case BuiltinValueKind::ZExt: - return isZeroValue(BI->getArguments()[0]); - case BuiltinValueKind::UDiv: - case BuiltinValueKind::SDiv: { - if (IsZeroKind::Zero == isZeroValue(BI->getArguments()[0])) - return IsZeroKind::Zero; - return IsZeroKind::Unknown; - } - case BuiltinValueKind::Mul: - case BuiltinValueKind::SMulOver: - case BuiltinValueKind::UMulOver: { - IsZeroKind LHS = isZeroValue(BI->getArguments()[0]); - IsZeroKind RHS = isZeroValue(BI->getArguments()[1]); - if (LHS == IsZeroKind::Zero || RHS == IsZeroKind::Zero) - return IsZeroKind::Zero; - - return IsZeroKind::Unknown; - } - default: - return IsZeroKind::Unknown; - } - } - - // Handle results of XXX_with_overflow arithmetic. - if (auto *T = dyn_cast(Value.getDef())) { - // Make sure we are extracting the number value and not - // the overflow flag. - if (T->getFieldNo() != 0) - return IsZeroKind::Unknown; - - BuiltinInst *BI = dyn_cast(T->getOperand()); - if (!BI) - return IsZeroKind::Unknown; - - return isZeroValue(BI); - } - - //Inspect allocations and pointer literals. - if (isa(Value.getDef()) || - isa(Value.getDef()) || - isa(Value.getDef())) - return IsZeroKind::NotZero; - - return IsZeroKind::Unknown; -} - -/// Check if the sign bit of the value \p V is known to be: -/// set (true), not set (false) or unknown (None). -Optional swift::computeSignBit(SILValue V) { - SILValue Value = V; - while (true) { - auto *Def = Value.getDef(); - // Inspect integer literals. - if (auto *L = dyn_cast(Def)) { - if (L->getValue().isNonNegative()) - return false; - return true; - } - - switch (Def->getKind()) { - // Bitcast of non-negative is non-negative - case ValueKind::UncheckedTrivialBitCastInst: - Value = cast(Def)->getOperand(0); - continue; - default: - break; - } - - if (auto *BI = dyn_cast(Def)) { - switch (BI->getBuiltinInfo().ID) { - // Sizeof always returns non-negative results. - case BuiltinValueKind::Sizeof: - return false; - // Strideof always returns non-negative results. - case BuiltinValueKind::Strideof: - return false; - // StrideofNonZero always returns positive results. - case BuiltinValueKind::StrideofNonZero: - return false; - // Alignof always returns non-negative results. - case BuiltinValueKind::Alignof: - return false; - // Both operands to AND must have the top bit set for V to. - case BuiltinValueKind::And: { - // Compute the sign bit of the LHS and RHS. - auto Left = computeSignBit(BI->getArguments()[0]); - auto Right = computeSignBit(BI->getArguments()[1]); - - // We don't know either's sign bit so we can't - // say anything about the result. - if (!Left && !Right) { - return None; - } - - // Now we know that we were able to determine the sign bit - // for at least one of Left/Right. Canonicalize the determined - // sign bit on the left. - if (Right) { - std::swap(Left, Right); - } - - // We know we must have at least one result and it must be on - // the Left. If Right is still not None, then get both values - // and AND them together. - if (Right) { - return Left.getValue() && Right.getValue(); - } - - // Now we know that Right is None and Left has a value. If - // Left's value is true, then we return None as the final - // sign bit depends on the unknown Right value. - if (Left.getValue()) { - return None; - } - - // Otherwise, Left must be false and false AND'd with anything - // else yields false. - return false; - } - // At least one operand to OR must have the top bit set. - case BuiltinValueKind::Or: { - // Compute the sign bit of the LHS and RHS. - auto Left = computeSignBit(BI->getArguments()[0]); - auto Right = computeSignBit(BI->getArguments()[1]); - - // We don't know either's sign bit so we can't - // say anything about the result. - if (!Left && !Right) { - return None; - } - - // Now we know that we were able to determine the sign bit - // for at least one of Left/Right. Canonicalize the determined - // sign bit on the left. - if (Right) { - std::swap(Left, Right); - } - - // We know we must have at least one result and it must be on - // the Left. If Right is still not None, then get both values - // and OR them together. - if (Right) { - return Left.getValue() || Right.getValue(); - } - - // Now we know that Right is None and Left has a value. If - // Left's value is false, then we return None as the final - // sign bit depends on the unknown Right value. - if (!Left.getValue()) { - return None; - } - - // Otherwise, Left must be true and true OR'd with anything - // else yields true. - return true; - } - // Only one of the operands to XOR must have the top bit set. - case BuiltinValueKind::Xor: { - // Compute the sign bit of the LHS and RHS. - auto Left = computeSignBit(BI->getArguments()[0]); - auto Right = computeSignBit(BI->getArguments()[1]); - - // If either Left or Right is unknown then we can't say - // anything about the sign of the final result since - // XOR does not short-circuit. - if (!Left || !Right) { - return None; - } - - // Now we know that both Left and Right must have a value. - // For the sign of the final result to be set, only one - // of Left or Right should be true. - return Left.getValue() != Right.getValue(); - } - case BuiltinValueKind::LShr: { - // If count is provably >= 1, then top bit is not set. - auto *ILShiftCount = dyn_cast(BI->getArguments()[1]); - if (ILShiftCount) { - if (ILShiftCount->getValue().isStrictlyPositive()) { - return false; - } - } - // May be top bit is not set in the value being shifted. - Value = BI->getArguments()[0]; - continue; - } - - // Source and target type sizes are the same. - // S->U conversion can only succeed if - // the sign bit of its operand is 0, i.e. it is >= 0. - // The sign bit of a result is 0 only if the sign - // bit of a source operand is 0. - case BuiltinValueKind::SUCheckedConversion: - Value = BI->getArguments()[0]; - continue; - - // Source and target type sizes are the same. - // U->S conversion can only succeed if - // the top bit of its operand is 0, i.e. - // it is representable as a signed integer >=0. - // The sign bit of a result is 0 only if the sign - // bit of a source operand is 0. - case BuiltinValueKind::USCheckedConversion: - Value = BI->getArguments()[0]; - continue; - - // Sign bit of the operand is promoted. - case BuiltinValueKind::SExt: - Value = BI->getArguments()[0]; - continue; - - // Source type is always smaller than the target type. - // Therefore the sign bit of a result is always 0. - case BuiltinValueKind::ZExt: - return false; - - // Sign bit of the operand is promoted. - case BuiltinValueKind::SExtOrBitCast: - Value = BI->getArguments()[0]; - continue; - - // TODO: If source type size is smaller than the target type - // the result will be always false. - case BuiltinValueKind::ZExtOrBitCast: - Value = BI->getArguments()[0]; - continue; - - // Inspect casts. - case BuiltinValueKind::IntToPtr: - case BuiltinValueKind::PtrToInt: - Value = BI->getArguments()[0]; - continue; - default: - return None; - } - } - - return None; - } -} - -/// Check if a checked trunc instruction can overflow. -/// Returns false if it can be proven that no overflow can happen. -/// Otherwise returns true. -static bool checkTruncOverflow(BuiltinInst *BI) { - SILValue Left, Right; - if (match(BI, m_CheckedTrunc(m_And(m_SILValue(Left), - m_SILValue(Right))))) { - // [US]ToSCheckedTrunc(And(x, mask)) cannot overflow - // if mask has the following properties: - // Only the first (N-1) bits are allowed to be set, where N is the width - // of the trunc result type. - // - // [US]ToUCheckedTrunc(And(x, mask)) cannot overflow - // if mask has the following properties: - // Only the first N bits are allowed to be set, where N is the width - // of the trunc result type. - if (auto BITy = BI->getType(). - getTupleElementType(0). - getAs()) { - unsigned Width = BITy->getFixedWidth(); - - switch (BI->getBuiltinInfo().ID) { - case BuiltinValueKind::SToSCheckedTrunc: - case BuiltinValueKind::UToSCheckedTrunc: - // If it is a trunc to a signed value - // then sign bit should not be set to avoid overflows. - --Width; - break; - default: - break; - } - - if (auto *ILLeft = dyn_cast(Left)) { - APInt Value = ILLeft->getValue(); - if (Value.isIntN(Width)) { - return false; - } - } - - if (auto *ILRight = dyn_cast(Right)) { - APInt Value = ILRight->getValue(); - if (Value.isIntN(Width)) { - return false; - } - } - } - } - return true; -} - -/// Check if execution of a given Apply instruction can result in overflows. -/// Returns true if an overflow can happen. Otherwise returns false. -bool swift::canOverflow(BuiltinInst *BI) { - if (simplifyOverflowBuiltinInstruction(BI) != SILValue()) - return false; - - if (!checkTruncOverflow(BI)) - return false; - - // Conservatively assume that an overflow can happen - return true; -} diff --git a/lib/SILGen/ASTVisitor.h b/lib/SILGen/ASTVisitor.h index 1812175f45fe6..48c12e912b86a 100644 --- a/lib/SILGen/ASTVisitor.h +++ b/lib/SILGen/ASTVisitor.h @@ -1,8 +1,8 @@ -//===-- ASTVisitor.h - SILGen ASTVisitor specialization ---------*- C++ -*-===// +//===--- ASTVisitor.h - SILGen ASTVisitor specialization --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/ArgumentSource.cpp b/lib/SILGen/ArgumentSource.cpp index 28f9eb0337c56..20a37454a1989 100644 --- a/lib/SILGen/ArgumentSource.cpp +++ b/lib/SILGen/ArgumentSource.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -78,6 +78,18 @@ ManagedValue ArgumentSource::getAsSingleValue(SILGenFunction &gen, } } + +ManagedValue ArgumentSource::getAsSingleValue(SILGenFunction &gen, + AbstractionPattern origFormalType, + SGFContext C) && { + auto loc = getLocation(); + auto substFormalType = getSubstType(); + ManagedValue outputValue = std::move(*this).getAsSingleValue(gen); + return gen.emitSubstToOrigValue(loc, + outputValue, origFormalType, + substFormalType, C); +} + void ArgumentSource::forwardInto(SILGenFunction &gen, Initialization *dest) && { assert(!isLValue()); if (isRValue()) { @@ -152,12 +164,10 @@ void ArgumentSource::forwardInto(SILGenFunction &SGF, // Otherwise, emit as a single independent value. SILLocation loc = getLocation(); - ManagedValue inputValue = std::move(*this).getAsSingleValue(SGF); - - // Reabstract. ManagedValue outputValue = - SGF.emitSubstToOrigValue(loc, inputValue, origFormalType, - substFormalType, SGFContext(dest)); + std::move(*this).getAsSingleValue(SGF, origFormalType, + SGFContext(dest)); + if (outputValue.isInContext()) return; // Use RValue's forward-into-initialization code. We have to lie to diff --git a/lib/SILGen/ArgumentSource.h b/lib/SILGen/ArgumentSource.h index c3ee44b29926d..548f81d8d859f 100644 --- a/lib/SILGen/ArgumentSource.h +++ b/lib/SILGen/ArgumentSource.h @@ -1,8 +1,8 @@ -//===--- ArgumentSource.h - Abstracted source of an argument 000-*- C++ -*-===// +//===--- ArgumentSource.h - Abstracted source of an argument ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -256,6 +256,9 @@ class ArgumentSource { RValue getAsRValue(SILGenFunction &gen, SGFContext C = SGFContext()) &&; ManagedValue getAsSingleValue(SILGenFunction &gen, SGFContext C = SGFContext()) &&; + ManagedValue getAsSingleValue(SILGenFunction &gen, + AbstractionPattern origFormalType, + SGFContext C = SGFContext()) &&; void forwardInto(SILGenFunction &gen, Initialization *dest) &&; void forwardInto(SILGenFunction &gen, AbstractionPattern origFormalType, diff --git a/lib/SILGen/Cleanup.cpp b/lib/SILGen/Cleanup.cpp index 69eecdd4babcf..9f30ee118753a 100644 --- a/lib/SILGen/Cleanup.cpp +++ b/lib/SILGen/Cleanup.cpp @@ -1,8 +1,8 @@ -//===--- Cleanup.cpp - Implements the Cleanup mechanics --------------------==// +//===--- Cleanup.cpp - Implements the Cleanup mechanics -------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/Cleanup.h b/lib/SILGen/Cleanup.h index 444dd17ccc435..c1b498d9361e2 100644 --- a/lib/SILGen/Cleanup.h +++ b/lib/SILGen/Cleanup.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/Condition.cpp b/lib/SILGen/Condition.cpp index 305167c03266a..8351cc82f91d1 100644 --- a/lib/SILGen/Condition.cpp +++ b/lib/SILGen/Condition.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/Condition.h b/lib/SILGen/Condition.h index 5ccd88b8eb175..99cd03461f063 100644 --- a/lib/SILGen/Condition.h +++ b/lib/SILGen/Condition.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/ExitableFullExpr.h b/lib/SILGen/ExitableFullExpr.h index 2ca4983241cbb..2fbffbf3bfd89 100644 --- a/lib/SILGen/ExitableFullExpr.h +++ b/lib/SILGen/ExitableFullExpr.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/Initialization.h b/lib/SILGen/Initialization.h index ca8978791ede8..8dc59d0b70ee4 100644 --- a/lib/SILGen/Initialization.h +++ b/lib/SILGen/Initialization.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/JumpDest.h b/lib/SILGen/JumpDest.h index ce52061c2d19b..4cd11da99c04c 100644 --- a/lib/SILGen/JumpDest.h +++ b/lib/SILGen/JumpDest.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/LValue.h b/lib/SILGen/LValue.h index 8ef1d9d2ec7cc..67491e978ff06 100644 --- a/lib/SILGen/LValue.h +++ b/lib/SILGen/LValue.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -53,7 +53,7 @@ struct LValueTypeData { /// On physical path components, projection yields an address of /// this type. On logical path components, materialize yields an /// address of this type, set expects a value of this type, and - /// get yields a vlaue of this type. + /// get yields a value of this type. SILType TypeOfRValue; LValueTypeData() = default; diff --git a/lib/SILGen/ManagedValue.cpp b/lib/SILGen/ManagedValue.cpp index 248ac6b719864..589e02514989a 100644 --- a/lib/SILGen/ManagedValue.cpp +++ b/lib/SILGen/ManagedValue.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/ManagedValue.h b/lib/SILGen/ManagedValue.h index d149fa345f832..9e1ba047d01ab 100644 --- a/lib/SILGen/ManagedValue.h +++ b/lib/SILGen/ManagedValue.h @@ -1,8 +1,8 @@ -//===--- RValue.h - Exploded RValue Representation --------------*- C++ -*-===// +//===--- ManagedValue.h - Exploded RValue Representation --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/RValue.cpp b/lib/SILGen/RValue.cpp index e2a6833a9f3aa..6656fd51cb978 100644 --- a/lib/SILGen/RValue.cpp +++ b/lib/SILGen/RValue.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -279,7 +279,7 @@ class EmitBBArguments : public CanTypeVisitorgetBodyParamPatterns(); + auto paramLists = AFD->getParameterLists(); if (AFD->getDeclContext()->isTypeContext()) - patterns = patterns.slice(1); - emitDefaultArgGenerators(AFD, patterns); + paramLists = paramLists.slice(1); + emitDefaultArgGenerators(AFD, paramLists); } // If this is a function at global scope, it may close over a global variable. @@ -552,13 +553,14 @@ void SILGenModule::emitConstructor(ConstructorDecl *decl) { } void SILGenModule::emitEnumConstructor(EnumElementDecl *decl) { + // Enum element constructors are always emitted by need, so don't need + // delayed emission. SILDeclRef constant(decl); - emitOrDelayFunction(*this, constant, [this,constant,decl](SILFunction *f) { - preEmitFunction(constant, decl, f, decl); - PrettyStackTraceSILFunction X("silgen enum constructor", f); - SILGenFunction(*this, *f).emitEnumConstructor(decl); - postEmitFunction(constant, f); - }); + SILFunction *f = getFunction(constant, ForDefinition); + preEmitFunction(constant, decl, f, decl); + PrettyStackTraceSILFunction X("silgen enum constructor", f); + SILGenFunction(*this, *f).emitEnumConstructor(decl); + postEmitFunction(constant, f); } SILFunction *SILGenModule::emitClosure(AbstractClosureExpr *ce) { @@ -723,10 +725,9 @@ SILFunction *SILGenModule::emitLazyGlobalInitializer(StringRef funcName, auto initSILType = getLoweredType(initType).castTo(); auto *f = - SILFunction::create(M, SILLinkage::Private, funcName, - initSILType, nullptr, SILLocation(binding), - IsNotBare, IsNotTransparent, - makeModuleFragile ? IsFragile : IsNotFragile); + M.getOrCreateFunction(SILLinkage::Private, funcName, initSILType, nullptr, + SILLocation(binding), IsNotBare, IsNotTransparent, + makeModuleFragile ? IsFragile : IsNotFragile); f->setDebugScope(new (M) SILDebugScope(RegularLocation(binding->getInit(pbdEntry)), *f)); @@ -768,21 +769,13 @@ void SILGenModule::emitGlobalGetter(VarDecl *global, } void SILGenModule::emitDefaultArgGenerators(SILDeclRef::Loc decl, - ArrayRef patterns) { + ArrayRef paramLists) { unsigned index = 0; - for (auto pattern : patterns) { - pattern = pattern->getSemanticsProvidingPattern(); - auto tuplePattern = dyn_cast(pattern); - if (!tuplePattern) { - ++index; - continue; - } - - for (auto &elt : tuplePattern->getElements()) { - if (auto handle = elt.getInit()) { - emitDefaultArgGenerator(SILDeclRef::getDefaultArgGenerator(decl,index), + for (auto paramList : paramLists) { + for (auto param : *paramList) { + if (auto handle = param->getDefaultValue()) + emitDefaultArgGenerator(SILDeclRef::getDefaultArgGenerator(decl, index), handle->getExpr()); - } ++index; } } @@ -1145,14 +1138,15 @@ void SILGenModule::emitSourceFile(SourceFile *sf, unsigned startElem) { visit(D); } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // SILModule::constructSIL method implementation -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// std::unique_ptr SILModule::constructSIL(Module *mod, SILOptions &options, FileUnit *SF, Optional startElem, bool makeModuleFragile, bool isWholeModule) { + SharedTimer timer("SILGen"); const DeclContext *DC; if (startElem) { assert(SF && "cannot have a start element without a source file"); diff --git a/lib/SILGen/SILGen.h b/lib/SILGen/SILGen.h index fee1db006494b..51585aec67dfe 100644 --- a/lib/SILGen/SILGen.h +++ b/lib/SILGen/SILGen.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -227,7 +227,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor { void emitFunction(FuncDecl *fd); /// \brief Generates code for the given closure expression and adds the - /// SILFunction to the current SILModule under the nane SILDeclRef(ce). + /// SILFunction to the current SILModule under the name SILDeclRef(ce). SILFunction *emitClosure(AbstractClosureExpr *ce); /// Generates code for the given ConstructorDecl and adds /// the SILFunction to the current SILModule under the name SILDeclRef(decl). @@ -247,7 +247,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor { /// Emits the default argument generator for the given function. void emitDefaultArgGenerators(SILDeclRef::Loc decl, - ArrayRef patterns); + ArrayRef paramLists); /// Emits the curry thunk between two uncurry levels of a function. void emitCurryThunk(ValueDecl *fd, @@ -323,13 +323,6 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor { /// True if the given constructor requires an entry point for ObjC method /// dispatch. bool requiresObjCMethodEntryPoint(ConstructorDecl *constructor); - - /// True if calling the given method or property should use ObjC dispatch. - bool requiresObjCDispatch(ValueDecl *vd); - - /// True if super-calling the given method from a subclass should use ObjC - /// dispatch. - bool requiresObjCSuperDispatch(ValueDecl *vd); /// Emit a global initialization. void emitGlobalInitialization(PatternBindingDecl *initializer, unsigned elt); diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index d2324a9c3f01b..329a193645ee1 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -29,78 +29,6 @@ using namespace swift; using namespace Lowering; -/// Get the method dispatch mechanism for a method. -MethodDispatch -SILGenFunction::getMethodDispatch(AbstractFunctionDecl *method) { - // Final methods can be statically referenced. - if (method->isFinal()) - return MethodDispatch::Static; - // Some methods are forced to be statically dispatched. - if (method->hasForcedStaticDispatch()) - return MethodDispatch::Static; - - // If this declaration is in a class but not marked final, then it is - // always dynamically dispatched. - auto dc = method->getDeclContext(); - if (isa(dc)) - return MethodDispatch::Class; - - // Class extension methods are only dynamically dispatched if they're - // dispatched by objc_msgSend, which happens if they're foreign or dynamic. - if (auto declaredType = dc->getDeclaredTypeInContext()) - if (declaredType->getClassOrBoundGenericClass()) { - if (method->hasClangNode()) - return MethodDispatch::Class; - if (auto fd = dyn_cast(method)) { - if (fd->isAccessor() && fd->getAccessorStorageDecl()->hasClangNode()) - return MethodDispatch::Class; - } - if (method->getAttrs().hasAttribute()) - return MethodDispatch::Class; - } - - // Otherwise, it can be referenced statically. - return MethodDispatch::Static; -} - -static SILDeclRef::Loc getLocForFunctionRef(AnyFunctionRef fn) { - if (auto afd = fn.getAbstractFunctionDecl()) { - return afd; - } else { - auto closure = fn.getAbstractClosureExpr(); - assert(closure); - return closure; - } -} - -/// Collect the captures necessary to invoke a local function into an -/// ArgumentSource. -static std::pair -emitCapturesAsArgumentSource(SILGenFunction &gen, - SILLocation loc, - AnyFunctionRef fn) { - SmallVector captures; - gen.emitCaptures(loc, fn, captures); - - // The capture array should match the explosion schema of the closure's - // first formal argument type. - auto info = gen.SGM.Types.getConstantInfo(SILDeclRef(getLocForFunctionRef(fn))); - auto subs = info.getForwardingSubstitutions(gen.getASTContext()); - auto origFormalTy = info.FormalInterfaceType; - CanFunctionType formalTy; - if (!subs.empty()) { - auto genericOrigFormalTy = cast(origFormalTy); - auto substTy = genericOrigFormalTy - ->substGenericArgs(gen.SGM.SwiftModule, subs) - ->getCanonicalType(); - formalTy = cast(substTy); - } else { - formalTy = cast(origFormalTy); - } - RValue rv(captures, formalTy.getInput()); - return {ArgumentSource(loc, std::move(rv)), formalTy}; -} - /// Retrieve the type to use for a method found via dynamic lookup. static CanAnyFunctionType getDynamicMethodFormalType(SILGenModule &SGM, SILValue proto, @@ -182,16 +110,21 @@ static CanSILFunctionType getDynamicMethodLoweredType(SILGenFunction &gen, namespace { -/// Abstractly represents a callee, and knows how to emit the entry point -/// reference for a callee at any valid uncurry level. +/// Abstractly represents a callee, which may be a constant or function value, +/// and knows how to perform dynamic dispatch and reference the appropriate +/// entry point at any valid uncurry level. class Callee { public: enum class Kind { /// An indirect function value. IndirectValue, + /// A direct standalone function call, referenceable by a FunctionRefInst. StandaloneFunction, + /// Enum case constructor call. + EnumElement, + VirtualMethod_First, /// A method call using class method dispatch. ClassMethod = VirtualMethod_First, @@ -215,23 +148,20 @@ class Callee { private: union { ManagedValue IndirectValue; - SILDeclRef StandaloneFunction; - struct { - SILValue SelfValue; - SILDeclRef MethodName; - } Method; + SILDeclRef Constant; }; + SILValue SelfValue; ArrayRef Substitutions; CanType OrigFormalOldType; CanType OrigFormalInterfaceType; CanAnyFunctionType SubstFormalType; Optional SpecializeLoc; bool HasSubstitutions = false; + Optional> Captures; // The pointer back to the AST node that produced the callee. SILLocation Loc; - private: Callee(ManagedValue indirectValue, @@ -263,7 +193,7 @@ class Callee { Callee(SILGenFunction &gen, SILDeclRef standaloneFunction, CanAnyFunctionType substFormalType, SILLocation l) - : kind(Kind::StandaloneFunction), StandaloneFunction(standaloneFunction), + : kind(Kind::StandaloneFunction), Constant(standaloneFunction), OrigFormalOldType(getConstantFormalType(gen, SILValue(), standaloneFunction)), OrigFormalInterfaceType(getConstantFormalInterfaceType(gen, SILValue(), @@ -279,7 +209,7 @@ class Callee { SILDeclRef methodName, CanAnyFunctionType substFormalType, SILLocation l) - : kind(methodKind), Method{selfValue, methodName}, + : kind(methodKind), Constant(methodName), SelfValue(selfValue), OrigFormalOldType(getConstantFormalType(gen, selfValue, methodName)), OrigFormalInterfaceType(getConstantFormalInterfaceType(gen, selfValue, methodName)), @@ -336,27 +266,11 @@ class Callee { } CanSILFunctionType getSubstFunctionType(SILGenModule &SGM, - CanSILFunctionType origFnType, - CanAnyFunctionType origLoweredType, - unsigned uncurryLevel, - Optional constant, - const Optional &foreignError) const { + CanSILFunctionType origFnType) const { if (!HasSubstitutions) return origFnType; - - assert(origLoweredType); - auto substLoweredType = - SGM.Types.getLoweredASTFunctionType(SubstFormalType, uncurryLevel, - origLoweredType->getExtInfo(), - constant); - auto substLoweredInterfaceType = - SGM.Types.getLoweredASTFunctionType(SubstFormalType, uncurryLevel, - origLoweredType->getExtInfo(), - constant); - - return SGM.Types.substFunctionType(origFnType, origLoweredType, - substLoweredType, - substLoweredInterfaceType, - foreignError); + + return origFnType->substGenericArgs(SGM.M, SGM.SwiftModule, + Substitutions); } /// Add the 'self' clause back to the substituted formal type of @@ -396,9 +310,9 @@ class Callee { // Replace it with the dynamic self type. OrigFormalOldType = OrigFormalInterfaceType - = getDynamicMethodFormalType(SGM, Method.SelfValue, - Method.MethodName.getDecl(), - Method.MethodName, methodType); + = getDynamicMethodFormalType(SGM, SelfValue, + Constant.getDecl(), + Constant, methodType); // Add a self clause to the substituted type. auto origFormalType = cast(OrigFormalOldType); @@ -424,6 +338,13 @@ class Callee { SILLocation l) { return Callee(gen, c, substFormalType, l); } + static Callee forEnumElement(SILGenFunction &gen, SILDeclRef c, + CanAnyFunctionType substFormalType, + SILLocation l) { + assert(isa(c.getDecl())); + return Callee(Kind::EnumElement, gen, SILValue(), + c, substFormalType, l); + } static Callee forClassMethod(SILGenFunction &gen, SILValue selfValue, SILDeclRef name, CanAnyFunctionType substFormalType, @@ -477,6 +398,20 @@ class Callee { SpecializeLoc = loc; HasSubstitutions = true; } + + void setCaptures(SmallVectorImpl &&captures) { + Captures = std::move(captures); + } + + ArrayRef getCaptures() const { + if (Captures) + return *Captures; + return {}; + } + + bool hasCaptures() const { + return Captures.hasValue(); + } CanType getOrigFormalType() const { return OrigFormalOldType; @@ -492,16 +427,20 @@ class Callee { return 0; case Kind::StandaloneFunction: - return StandaloneFunction.uncurryLevel; - + case Kind::EnumElement: case Kind::ClassMethod: case Kind::SuperMethod: case Kind::WitnessMethod: case Kind::DynamicMethod: - return Method.MethodName.uncurryLevel; + return Constant.uncurryLevel; } } + EnumElementDecl *getEnumElementDecl() { + assert(kind == Kind::EnumElement); + return cast(Constant.getDecl()); + } + std::tuple, ApplyOptions> getAtUncurryLevel(SILGenFunction &gen, unsigned level) const { @@ -518,15 +457,15 @@ class Callee { break; case Kind::StandaloneFunction: { - assert(level <= StandaloneFunction.uncurryLevel + assert(level <= Constant.uncurryLevel && "uncurrying past natural uncurry level of standalone function"); - constant = StandaloneFunction.atUncurryLevel(level); + constant = Constant.atUncurryLevel(level); // If we're currying a direct reference to a class-dispatched method, // make sure we emit the right set of thunks. - if (constant->isCurried && StandaloneFunction.hasDecl()) - if (auto func = StandaloneFunction.getAbstractFunctionDecl()) - if (gen.getMethodDispatch(func) == MethodDispatch::Class) + if (constant->isCurried && Constant.hasDecl()) + if (auto func = Constant.getAbstractFunctionDecl()) + if (getMethodDispatch(func) == MethodDispatch::Class) constant = constant->asDirectReference(true); constantInfo = gen.getConstantInfo(*constant); @@ -534,14 +473,28 @@ class Callee { mv = ManagedValue::forUnmanaged(ref); break; } + case Kind::EnumElement: { + assert(level <= Constant.uncurryLevel + && "uncurrying past natural uncurry level of enum constructor"); + constant = Constant.atUncurryLevel(level); + constantInfo = gen.getConstantInfo(*constant); + + // We should not end up here if the enum constructor call is fully + // applied. + assert(constant->isCurried); + + SILValue ref = gen.emitGlobalFunctionRef(Loc, *constant, constantInfo); + mv = ManagedValue::forUnmanaged(ref); + break; + } case Kind::ClassMethod: { - assert(level <= Method.MethodName.uncurryLevel + assert(level <= Constant.uncurryLevel && "uncurrying past natural uncurry level of method"); - constant = Method.MethodName.atUncurryLevel(level); + constant = Constant.atUncurryLevel(level); constantInfo = gen.getConstantInfo(*constant); // If the call is curried, emit a direct call to the curry thunk. - if (level < Method.MethodName.uncurryLevel) { + if (level < Constant.uncurryLevel) { SILValue ref = gen.emitGlobalFunctionRef(Loc, *constant, constantInfo); mv = ManagedValue::forUnmanaged(ref); break; @@ -549,7 +502,7 @@ class Callee { // Otherwise, do the dynamic dispatch inline. SILValue methodVal = gen.B.createClassMethod(Loc, - Method.SelfValue, + SelfValue, *constant, /*volatile*/ constant->isForeign); @@ -558,31 +511,34 @@ class Callee { break; } case Kind::SuperMethod: { - assert(level <= Method.MethodName.uncurryLevel + assert(level <= Constant.uncurryLevel && "uncurrying past natural uncurry level of method"); - assert(level >= 1 - && "currying 'self' of super method dispatch not yet supported"); + assert(level == getNaturalUncurryLevel() && + "Currying the self parameter of super method calls should've been emitted"); - constant = Method.MethodName.atUncurryLevel(level); + constant = Constant.atUncurryLevel(level); constantInfo = gen.getConstantInfo(*constant); - SILValue methodVal = gen.B.createSuperMethod(Loc, - Method.SelfValue, - *constant, - constantInfo.getSILType(), - /*volatile*/ - constant->isForeign); + if (SILDeclRef baseConstant = Constant.getBaseOverriddenVTableEntry()) + constantInfo = gen.SGM.Types.getConstantOverrideInfo(Constant, + baseConstant); + auto methodVal = gen.B.createSuperMethod(Loc, + SelfValue, + *constant, + constantInfo.getSILType(), + /*volatile*/ + constant->isForeign); mv = ManagedValue::forUnmanaged(methodVal); break; } case Kind::WitnessMethod: { - assert(level <= Method.MethodName.uncurryLevel + assert(level <= Constant.uncurryLevel && "uncurrying past natural uncurry level of method"); - constant = Method.MethodName.atUncurryLevel(level); + constant = Constant.atUncurryLevel(level); constantInfo = gen.getConstantInfo(*constant); // If the call is curried, emit a direct call to the curry thunk. - if (level < Method.MethodName.uncurryLevel) { + if (level < Constant.uncurryLevel) { SILValue ref = gen.emitGlobalFunctionRef(Loc, *constant, constantInfo); mv = ManagedValue::forUnmanaged(ref); break; @@ -595,7 +551,7 @@ class Callee { // existential type. SILValue OpenedExistential; if (!archetype->getOpenedExistentialType().isNull()) - OpenedExistential = Method.SelfValue; + OpenedExistential = SelfValue; SILValue fn = gen.B.createWitnessMethod(Loc, archetype, @@ -610,20 +566,20 @@ class Callee { case Kind::DynamicMethod: { assert(level >= 1 && "currying 'self' of dynamic method dispatch not yet supported"); - assert(level <= Method.MethodName.uncurryLevel + assert(level <= Constant.uncurryLevel && "uncurrying past natural uncurry level of method"); - auto constant = Method.MethodName.atUncurryLevel(level); + auto constant = Constant.atUncurryLevel(level); constantInfo = gen.getConstantInfo(constant); auto closureType = replaceSelfTypeForDynamicLookup(gen.getASTContext(), constantInfo.SILFnType, - Method.SelfValue.getType().getSwiftRValueType(), - Method.MethodName); + SelfValue.getType().getSwiftRValueType(), + Constant); SILValue fn = gen.B.createDynamicMethod(Loc, - Method.SelfValue, + SelfValue, constant, SILType::getPrimitiveObjectType(closureType), /*volatile*/ constant.isForeign); @@ -639,9 +595,7 @@ class Callee { } CanSILFunctionType substFnType = - getSubstFunctionType(gen.SGM, mv.getType().castTo(), - constantInfo.LoweredType, level, constant, - foreignError); + getSubstFunctionType(gen.SGM, mv.getType().castTo()); return std::make_tuple(mv, substFnType, foreignError, options); } @@ -650,6 +604,10 @@ class Callee { return Substitutions; } + SILDeclRef getMethodName() const { + return Constant; + } + /// Return a specialized emission function if this is a function with a known /// lowering, such as a builtin, or return null if there is no specialized /// emitter. @@ -661,8 +619,9 @@ class Callee { switch (kind) { case Kind::StandaloneFunction: { - return SpecializedEmitter::forDecl(SGM, StandaloneFunction); + return SpecializedEmitter::forDecl(SGM, Constant); } + case Kind::EnumElement: case Kind::IndirectValue: case Kind::ClassMethod: case Kind::SuperMethod: @@ -717,7 +676,7 @@ static Callee prepareArchetypeCallee(SILGenFunction &gen, SILLocation loc, assert(address.getType().is()); auto formalTy = address.getType().getSwiftRValueType(); - if (getSelfParameter().isIndirectInOut()) { + if (getSelfParameter().isIndirectMutating()) { // Be sure not to consume the cleanup for an inout argument. auto selfLV = ManagedValue::forLValue(address.getValue()); selfValue = ArgumentSource(loc, @@ -788,12 +747,28 @@ static Callee prepareArchetypeCallee(SILGenFunction &gen, SILLocation loc, constant, substFnType, loc); } -/// An ASTVisitor for building SIL function calls. +/// An ASTVisitor for decomposing a nesting of ApplyExprs into an initial +/// Callee and a list of CallSites. The CallEmission class below uses these +/// to generate the actual SIL call. +/// +/// Formally, an ApplyExpr in the AST always has a single argument, which may +/// be of tuple type, possibly empty. Also, some callees have a formal type +/// which is curried -- for example, methods have type Self -> Arg -> Result. /// -/// Nested ApplyExprs applied to an underlying curried function or method -/// reference are flattened into a single SIL apply to the most uncurried entry -/// point fitting the call site, avoiding pointless intermediate closure -/// construction. +/// However, SIL functions take zero or more parameters and the natural entry +/// point of a method takes Self as an additional argument, rather than +/// returning a partial application. +/// +/// Therefore, nested ApplyExprs applied to a constant are flattened into a +/// single call of the most uncurried entry point fitting the call site. +/// This avoids intermediate closure construction. +/// +/// For example, a method reference 'self.method' decomposes into curry thunk +/// as the callee, with a single call site '(self)'. +/// +/// On the other hand, a call of a method 'self.method(x)(y)' with a function +/// return type decomposes into the method's natural entry point as the callee, +/// and two call sites, first '(x, self)' then '(y)'. class SILGenApply : public Lowering::ExprVisitor { public: /// The SILGenFunction that we are emitting SIL into. @@ -1051,7 +1026,7 @@ class SILGenApply : public Lowering::ExprVisitor { if (e->getAccessSemantics() != AccessSemantics::Ordinary) { isDynamicallyDispatched = false; } else { - switch (SGF.getMethodDispatch(afd)) { + switch (getMethodDispatch(afd)) { case MethodDispatch::Class: isDynamicallyDispatched = true; break; @@ -1070,7 +1045,7 @@ class SILGenApply : public Lowering::ExprVisitor { if (ctor->isRequired() && thisCallSite->getArg()->getType()->is() && !thisCallSite->getArg()->isStaticallyDerivedMetatype()) { - if (SGF.SGM.requiresObjCDispatch(afd)) { + if (requiresObjCDispatch(afd)) { // When we're performing Objective-C dispatch, we don't have an // allocating constructor to call. So, perform an alloc_ref_dynamic // and pass that along to the initializer. @@ -1120,7 +1095,7 @@ class SILGenApply : public Lowering::ExprVisitor { SILDeclRef constant(afd, kind.getValue(), SILDeclRef::ConstructAtBestResilienceExpansion, SILDeclRef::ConstructAtNaturalUncurryLevel, - SGF.SGM.requiresObjCDispatch(afd)); + requiresObjCDispatch(afd)); setCallee(Callee::forClassMethod(SGF, selfValue, constant, getSubstFnType(), e)); @@ -1152,35 +1127,26 @@ class SILGenApply : public Lowering::ExprVisitor { SILDeclRef constant(e->getDecl(), SILDeclRef::ConstructAtBestResilienceExpansion, SILDeclRef::ConstructAtNaturalUncurryLevel, - SGF.SGM.requiresObjCDispatch(e->getDecl())); + requiresObjCDispatch(e->getDecl())); - // Otherwise, we have a direct call. + // Otherwise, we have a statically-dispatched call. CanFunctionType substFnType = getSubstFnType(); ArrayRef subs; - // If the decl ref requires captures, emit the capture params. - // The capture params behave like a "self" parameter as the first curry - // level of the function implementation. auto afd = dyn_cast(e->getDecl()); if (afd) { - if (afd->getCaptureInfo().hasLocalCaptures()) { - assert(!e->getDeclRef().isSpecialized() - && "generic local fns not implemented"); - - auto captures = emitCapturesAsArgumentSource(SGF, e, afd); - substFnType = captures.second; - setSelfParam(std::move(captures.first), captures.second.getInput()); - } - - // FIXME: We should be checking hasLocalCaptures() on the lowered - // captures in the constant info too, to generate more efficient - // code for mutually recursive local functions which otherwise - // capture no state. auto constantInfo = SGF.getConstantInfo(constant); // Forward local substitutions to a non-generic local function. if (afd->getParent()->isLocalContext() && !afd->getGenericParams()) subs = constantInfo.getForwardingSubstitutions(SGF.getASTContext()); + + // If there are captures, put the placeholder curry level in the formal + // type. + // TODO: Eliminate the need for this. + if (afd->getCaptureInfo().hasLocalCaptures()) + substFnType = CanFunctionType::get( + SGF.getASTContext().TheEmptyTupleType, substFnType); } if (e->getDeclRef().isSpecialized()) { @@ -1188,8 +1154,32 @@ class SILGenApply : public Lowering::ExprVisitor { subs = e->getDeclRef().getSubstitutions(); } - setCallee(Callee::forDirect(SGF, constant, substFnType, e)); - + + // Enum case constructor references are open-coded. + if (isa(e->getDecl())) + setCallee(Callee::forEnumElement(SGF, constant, substFnType, e)); + else + setCallee(Callee::forDirect(SGF, constant, substFnType, e)); + + // If the decl ref requires captures, emit the capture params. + if (afd) { + if (afd->getCaptureInfo().hasLocalCaptures()) { + assert(!e->getDeclRef().isSpecialized() + && "generic local fns not implemented"); + + SmallVector captures; + SGF.emitCaptures(e, afd, CaptureEmission::ImmediateApplication, + captures); + ApplyCallee->setCaptures(std::move(captures)); + } + + // FIXME: We should be checking hasLocalCaptures() on the lowered + // captures in the constant info too, to generate more efficient + // code for mutually recursive local functions which otherwise + // capture no state. + + } + // If there are substitutions, add them, always at depth 0. if (!subs.empty()) ApplyCallee->setSubstitutions(SGF, e, subs, 0); @@ -1203,16 +1193,8 @@ class SILGenApply : public Lowering::ExprVisitor { if (!SGF.SGM.hasFunction(constant)) SGF.SGM.emitClosure(e); - // If the closure requires captures, emit them. - // The capture params behave like a "self" parameter as the first curry - // level of the function implementation. ArrayRef subs; CanFunctionType substFnType = getSubstFnType(); - if (e->getCaptureInfo().hasLocalCaptures()) { - auto captures = emitCapturesAsArgumentSource(SGF, e, e); - substFnType = captures.second; - setSelfParam(std::move(captures.first), captures.second.getInput()); - } // FIXME: We should be checking hasLocalCaptures() on the lowered // captures in the constant info above, to generate more efficient @@ -1221,7 +1203,22 @@ class SILGenApply : public Lowering::ExprVisitor { auto constantInfo = SGF.getConstantInfo(constant); subs = constantInfo.getForwardingSubstitutions(SGF.getASTContext()); + // If there are captures, put the placeholder curry level in the formal + // type. + // TODO: Eliminate the need for this. + if (e->getCaptureInfo().hasLocalCaptures()) + substFnType = CanFunctionType::get( + SGF.getASTContext().TheEmptyTupleType, substFnType); + setCallee(Callee::forDirect(SGF, constant, substFnType, e)); + + // If the closure requires captures, emit them. + if (e->getCaptureInfo().hasLocalCaptures()) { + SmallVector captures; + SGF.emitCaptures(e, e, CaptureEmission::ImmediateApplication, + captures); + ApplyCallee->setCaptures(std::move(captures)); + } // If there are substitutions, add them, always at depth 0. if (!subs.empty()) ApplyCallee->setSubstitutions(SGF, e, subs, 0); @@ -1290,7 +1287,7 @@ class SILGenApply : public Lowering::ExprVisitor { constant = SILDeclRef(ctorRef->getDecl(), SILDeclRef::Kind::Initializer, SILDeclRef::ConstructAtBestResilienceExpansion, SILDeclRef::ConstructAtNaturalUncurryLevel, - SGF.SGM.requiresObjCSuperDispatch(ctorRef->getDecl())); + requiresObjCDispatch(ctorRef->getDecl())); if (ctorRef->getDeclRef().isSpecialized()) substitutions = ctorRef->getDeclRef().getSubstitutions(); @@ -1299,7 +1296,7 @@ class SILGenApply : public Lowering::ExprVisitor { constant = SILDeclRef(declRef->getDecl(), SILDeclRef::ConstructAtBestResilienceExpansion, SILDeclRef::ConstructAtNaturalUncurryLevel, - SGF.SGM.requiresObjCSuperDispatch(declRef->getDecl())); + requiresObjCDispatch(declRef->getDecl())); if (declRef->getDeclRef().isSpecialized()) substitutions = declRef->getDeclRef().getSubstitutions(); @@ -1311,7 +1308,13 @@ class SILGenApply : public Lowering::ExprVisitor { apply); SILValue superMethod; - if (constant.isForeign) { + auto *funcDecl = cast(constant.getDecl()); + + auto Opts = SGF.B.getModule().getOptions(); + if (constant.isForeign || + (Opts.UseNativeSuperMethod && !funcDecl->isFinal())) { + // All Objective-C methods and + // non-final native Swift methods use dynamic dispatch. SILValue Input = super.getValue(); while (auto *UI = dyn_cast(Input)) Input = UI->getOperand(); @@ -1319,7 +1322,7 @@ class SILGenApply : public Lowering::ExprVisitor { setCallee(Callee::forSuperMethod(SGF, Input, constant, getSubstFnType(), fn)); } else { - // Native Swift super calls are direct. + // Native Swift super calls to final methods are direct. setCallee(Callee::forDirect(SGF, constant, getSubstFnType(), fn)); } @@ -1475,12 +1478,12 @@ class SILGenApply : public Lowering::ExprVisitor { : SILDeclRef::Kind::Initializer, SILDeclRef::ConstructAtBestResilienceExpansion, SILDeclRef::ConstructAtNaturalUncurryLevel, - SGF.SGM.requiresObjCDispatch(ctorRef->getDecl())); + requiresObjCDispatch(ctorRef->getDecl())); setCallee(Callee::forArchetype(SGF, SILValue(), self.getType().getSwiftRValueType(), constant, cast(expr->getType()->getCanonicalType()), expr)); - } else if (SGF.getMethodDispatch(ctorRef->getDecl()) + } else if (getMethodDispatch(ctorRef->getDecl()) == MethodDispatch::Class) { // Dynamic dispatch to the initializer. setCallee(Callee::forClassMethod( @@ -1492,7 +1495,7 @@ class SILGenApply : public Lowering::ExprVisitor { : SILDeclRef::Kind::Initializer, SILDeclRef::ConstructAtBestResilienceExpansion, SILDeclRef::ConstructAtNaturalUncurryLevel, - SGF.SGM.requiresObjCDispatch(ctorRef->getDecl())), + requiresObjCDispatch(ctorRef->getDecl())), getSubstFnType(), fn)); } else { // Directly call the peer constructor. @@ -1924,6 +1927,7 @@ ManagedValue SILGenFunction::emitApply( case ParameterConvention::Indirect_In_Guaranteed: case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: // We may need to support this at some point, but currently only imported // objc methods are returns_inner_pointer. @@ -1932,7 +1936,7 @@ ManagedValue SILGenFunction::emitApply( } } - // If there's an foreign error parameter, fill it in. + // If there's a foreign error parameter, fill it in. Optional errorTempWriteback; ManagedValue errorTemp; if (foreignError) { @@ -2013,8 +2017,7 @@ ManagedValue SILGenFunction::emitApply( break; case ResultConvention::Autoreleased: - // Autoreleased. Retain using retain_autoreleased. - B.createStrongRetainAutoreleased(loc, scalarResult); + // Autoreleased. The reclaim is implicit, so the value is effectively +1. break; case ResultConvention::UnownedInnerPointer: @@ -2916,6 +2919,154 @@ void ArgEmitter::emitShuffle(TupleShuffleExpr *E, origParamType); } +namespace { +/// Cleanup to destroy an uninitialized box. +class DeallocateUninitializedBox : public Cleanup { + SILValue box; +public: + DeallocateUninitializedBox(SILValue box) : box(box) {} + + void emit(SILGenFunction &gen, CleanupLocation l) override { + gen.B.createDeallocBox(l, box); + } +}; +} // end anonymous namespace + +static CleanupHandle enterDeallocBoxCleanup(SILGenFunction &gen, SILValue box) { + gen.Cleanups.pushCleanup(box); + return gen.Cleanups.getTopCleanup(); +} + +/// This is an initialization for a box. +class BoxInitialization : public SingleBufferInitialization { + SILValue box; + SILValue addr; + CleanupHandle uninitCleanup; + CleanupHandle initCleanup; + +public: + BoxInitialization(SILValue box, SILValue addr, + CleanupHandle uninitCleanup, + CleanupHandle initCleanup) + : box(box), addr(addr), + uninitCleanup(uninitCleanup), + initCleanup(initCleanup) {} + + void finishInitialization(SILGenFunction &gen) override { + gen.Cleanups.setCleanupState(uninitCleanup, CleanupState::Dead); + if (initCleanup.isValid()) + gen.Cleanups.setCleanupState(initCleanup, CleanupState::Active); + } + + SILValue getAddressOrNull() const override { + return addr; + } + + ManagedValue getManagedBox() const { + return ManagedValue(box, initCleanup); + } +}; + +/// Emits SIL instructions to create an enum value. Attempts to avoid +/// unnecessary copies by emitting the payload directly into the enum +/// payload, or into the box in the case of an indirect payload. +ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc, + ArgumentSource payload, + SILType enumTy, + EnumElementDecl *element, + SGFContext C) { + // Easy case -- no payload + if (!payload) { + if (enumTy.isLoadable(SGM.M)) { + return emitManagedRValueWithCleanup( + B.createEnum(loc, SILValue(), element, + enumTy.getObjectType())); + } + + // Emit the enum directly into the context if possible + SILValue resultSlot = getBufferForExprResult(loc, enumTy, C); + B.createInjectEnumAddr(loc, resultSlot, element); + return manageBufferForExprResult(resultSlot, + getTypeLowering(enumTy), C); + } + + ManagedValue payloadMV; + AbstractionPattern origFormalType(element->getArgumentType()); + auto &payloadTL = getTypeLowering(origFormalType, + payload.getSubstType()); + + SILType loweredPayloadType = payloadTL.getLoweredType(); + + // If the payload is indirect, emit it into a heap allocated box. + // + // To avoid copies, evaluate it directly into the box, being + // careful to stage the cleanups so that if the expression + // throws, we know to deallocate the uninitialized box. + if (element->isIndirect() || + element->getParentEnum()->isIndirect()) { + auto box = B.createAllocBox(loc, payloadTL.getLoweredType()); + + CleanupHandle initCleanup = enterDestroyCleanup(box); + Cleanups.setCleanupState(initCleanup, CleanupState::Dormant); + CleanupHandle uninitCleanup = enterDeallocBoxCleanup(*this, box); + + BoxInitialization dest(box, box->getAddressResult(), + uninitCleanup, initCleanup); + + std::move(payload).forwardInto(*this, origFormalType, + &dest, payloadTL); + + payloadMV = dest.getManagedBox(); + loweredPayloadType = payloadMV.getType(); + } + + // Loadable with payload + if (enumTy.isLoadable(SGM.M)) { + if (!payloadMV) { + // If the payload was indirect, we already evaluated it and + // have a single value. Otherwise, evaluate the payload. + payloadMV = std::move(payload).getAsSingleValue(*this, origFormalType); + } + + SILValue argValue = payloadMV.forward(*this); + + return emitManagedRValueWithCleanup( + B.createEnum(loc, argValue, element, + enumTy.getObjectType())); + } + + // Address-only with payload + SILValue resultSlot = getBufferForExprResult(loc, enumTy, C); + + SILValue resultData = + B.createInitEnumDataAddr(loc, resultSlot, element, + loweredPayloadType.getAddressType()); + + if (payloadMV) { + // If the payload was indirect, we already evaluated it and + // have a single value. Store it into the result. + B.createStore(loc, payloadMV.forward(*this), resultData); + } else if (payloadTL.isLoadable()) { + // The payload of this specific enum case might be loadable + // even if the overall enum is address-only. + payloadMV = std::move(payload).getAsSingleValue(*this, origFormalType); + B.createStore(loc, payloadMV.forward(*this), resultData); + } else { + // The payload is address-only. Evaluate it directly into + // the enum. + + TemporaryInitialization dest(resultData, CleanupHandle::invalid()); + std::move(payload).forwardInto(*this, origFormalType, + &dest, payloadTL); + } + + // The payload is initialized, now apply the tag. + B.createInjectEnumAddr(loc, resultSlot, element); + + return manageBufferForExprResult(resultSlot, + getTypeLowering(enumTy), C); +} + namespace { /// A structure for conveniently claiming sets of uncurried parameters. struct ParamLowering { @@ -2936,12 +3087,32 @@ namespace { Params = Params.slice(0, Params.size() - count); return result; } + + ArrayRef + claimCaptureParams(ArrayRef captures) { + auto firstCapture = Params.size() - captures.size(); +#ifndef NDEBUG + assert(Params.size() >= captures.size() + && "more captures than params?!"); + for (unsigned i = 0; i < captures.size(); ++i) { + assert(Params[i + firstCapture].getSILType() + == captures[i].getType() + && "capture doesn't match param type"); + } +#endif + + auto result = Params.slice(firstCapture, captures.size()); + Params = Params.slice(0, firstCapture); + return result; + } ~ParamLowering() { assert(Params.empty() && "didn't consume all the parameters"); } }; + /// An application of possibly unevaluated arguments in the form of an + /// ArgumentSource to a Callee. class CallSite { public: SILLocation Loc; @@ -2981,6 +3152,7 @@ namespace { bool throws() const { return Throws; } + /// Evaluate arguments and begin any inout formal accesses. void emit(SILGenFunction &gen, AbstractionPattern origParamType, ParamLowering &lowering, SmallVectorImpl &args, SmallVectorImpl &inoutArgs, @@ -2993,6 +3165,7 @@ namespace { emitter.emitTopLevel(std::move(ArgValue), origParamType); } + /// Take the arguments for special processing, in place of the above. ArgumentSource &&forward() && { return std::move(ArgValue); } @@ -3029,10 +3202,22 @@ namespace { // Reassign ArgValue. RValue NewRValue = RValue(gen, ArgLoc, ArgTy.getSwiftRValueType(), ArgManagedValue); - ArgValue = std::move(ArgumentSource(ArgLoc, std::move(NewRValue))); + ArgValue = ArgumentSource(ArgLoc, std::move(NewRValue)); } }; + /// Once the Callee and CallSites have been prepared by SILGenApply, + /// generate SIL for a fully-formed call. + /// + /// The lowered function type of the callee defines an abstraction pattern + /// for evaluating argument values of tuple type directly into explosions of + /// scalars where possible. + /// + /// If there are more call sites than the natural uncurry level, they are + /// have to be applied recursively to each intermediate callee. + /// + /// Also inout formal access and parameter and result conventions are + /// handled here, with some special logic required for calls with +0 self. class CallEmission { SILGenFunction &gen; @@ -3045,6 +3230,7 @@ namespace { bool AssumedPlusZeroSelf; public: + /// Create an emission for a call of the given callee. CallEmission(SILGenFunction &gen, Callee &&callee, WritebackScope &&writebackScope, bool assumedPlusZeroSelf = false) @@ -3054,8 +3240,17 @@ namespace { uncurries(callee.getNaturalUncurryLevel() + 1), applied(false), AssumedPlusZeroSelf(assumedPlusZeroSelf) - {} + { + // Subtract an uncurry level for captures, if any. + // TODO: Encapsulate this better in Callee. + if (this->callee.hasCaptures()) { + assert(uncurries > 0 && "captures w/o uncurry level?"); + --uncurries; + } + } + /// Add a level of function application by passing in its possibly + /// unevaluated arguments and their formal type. void addCallSite(CallSite &&site) { assert(!applied && "already applied!"); @@ -3069,7 +3264,9 @@ namespace { // Otherwise, apply these arguments to the result of the previous call. extraSites.push_back(std::move(site)); } - + + /// Add a level of function application by passing in its possibly + /// unevaluated arguments and their formal type template void addCallSite(T &&...args) { addCallSite(CallSite{std::forward(args)...}); @@ -3088,12 +3285,26 @@ namespace { uncurriedSites[0].convertToPlusOneFromPlusZero(gen); } + /// Is this a fully-applied enum element constructor call? + bool isEnumElementConstructor() { + return (callee.kind == Callee::Kind::EnumElement && uncurries == 0); + } + + /// True if this is a completely unapplied super method call + bool isPartiallyAppliedSuperMethod(unsigned uncurryLevel) { + return (callee.kind == Callee::Kind::SuperMethod && + uncurryLevel == 0); + } + + /// Emit the fully-formed call. ManagedValue apply(SGFContext C = SGFContext()) { assert(!applied && "already applied!"); applied = true; - // Get the callee value at the needed uncurry level. + // Get the callee value at the needed uncurry level, uncurrying as + // much as possible. If the number of calls is less than the natural + // uncurry level, the callee emission might create a curry thunk. unsigned uncurryLevel = callee.getNaturalUncurryLevel() - uncurries; // Get either the specialized emitter for a known function, or the @@ -3111,12 +3322,22 @@ namespace { AbstractionPattern origFormalType(callee.getOrigFormalType()); CanAnyFunctionType formalType = callee.getSubstFormalType(); - if (specializedEmitter) { + if (specializedEmitter || isPartiallyAppliedSuperMethod(uncurryLevel)) { // We want to emit the arguments as fully-substituted values // because that's what the specialized emitters expect. origFormalType = AbstractionPattern(formalType); substFnType = gen.getLoweredType(formalType, uncurryLevel) .castTo(); + } else if (isEnumElementConstructor()) { + // Enum payloads are always stored at the abstraction level + // of the unsubstituted payload type. This means that unlike + // with specialized emitters above, enum constructors use + // the AST-level abstraction pattern, to ensure that function + // types in payloads are re-abstracted correctly. + assert(!AssumedPlusZeroSelf); + substFnType = gen.getLoweredType(origFormalType, formalType, + uncurryLevel) + .castTo(); } else { std::tie(mv, substFnType, foreignError, initialOptions) = callee.getAtUncurryLevel(gen, uncurryLevel); @@ -3164,6 +3385,32 @@ namespace { argument, formalApplyType, uncurriedContext); + } else if (isEnumElementConstructor()) { + // If we have a fully-applied enum element constructor, open-code + // the construction. + EnumElementDecl *element = callee.getEnumElementDecl(); + + SILLocation uncurriedLoc = uncurriedSites[0].Loc; + + // Ignore metatype argument + claimNextParamClause(origFormalType); + claimNextParamClause(formalType); + std::move(uncurriedSites[0]).forward().getAsSingleValue(gen); + + // Get the payload argument. + ArgumentSource payload; + if (element->hasArgumentType()) { + assert(uncurriedSites.size() == 2); + claimNextParamClause(origFormalType); + claimNextParamClause(formalType); + payload = std::move(uncurriedSites[1]).forward(); + } else { + assert(uncurriedSites.size() == 1); + } + + result = gen.emitInjectEnum(uncurriedLoc, std::move(payload), + substFnType->getSemanticResultSILType(), + element, uncurriedContext); // Otherwise, emit the uncurried arguments now and perform // the call. @@ -3185,6 +3432,19 @@ namespace { if (!uncurriedSites.back().throws()) { initialOptions |= ApplyOptions::DoesNotThrow; } + + // Collect the captures, if any. + if (callee.hasCaptures()) { + // The captures are represented as a placeholder curry level in the + // formal type. + // TODO: Remove this hack. + paramLowering.claimCaptureParams(callee.getCaptures()); + claimNextParamClause(origFormalType); + claimNextParamClause(formalType); + args.push_back({}); + args.back().append(callee.getCaptures().begin(), + callee.getCaptures().end()); + } // Collect the arguments to the uncurried call. for (auto &site : uncurriedSites) { @@ -3215,9 +3475,51 @@ namespace { for (auto &argSet : reversed(args)) uncurriedArgs.append(argSet.begin(), argSet.end()); args = {}; - + // Emit the uncurried call. - if (!specializedEmitter) { + + // Special case for superclass method calls. + if (isPartiallyAppliedSuperMethod(uncurryLevel)) { + assert(uncurriedArgs.size() == 1 && + "Can only partially apply the self parameter of a super method call"); + + auto constant = callee.getMethodName(); + auto loc = uncurriedLoc.getValue(); + auto subs = callee.getSubstitutions(); + auto upcastedSelf = uncurriedArgs.back(); + auto self = cast(upcastedSelf.getValue())->getOperand(); + auto constantInfo = gen.getConstantInfo(callee.getMethodName()); + auto functionTy = constantInfo.getSILType(); + SILValue superMethodVal = gen.B.createSuperMethod( + loc, + self, + constant, + functionTy, + /*volatile*/ + constant.isForeign); + + auto closureTy = SILGenBuilder::getPartialApplyResultType( + constantInfo.getSILType(), + 1, + gen.B.getModule(), + subs); + + auto &module = gen.getFunction().getModule(); + + auto partialApplyTy = functionTy; + if (constantInfo.SILFnType->isPolymorphic() && !subs.empty()) + partialApplyTy = partialApplyTy.substGenericArgs(module, subs); + + SILValue partialApply = gen.B.createPartialApply( + loc, + superMethodVal, + partialApplyTy, + subs, + { upcastedSelf.forward(gen) }, + closureTy); + result = ManagedValue::forUnmanaged(partialApply); + // Handle a regular call. + } else if (!specializedEmitter) { result = gen.emitApply(uncurriedLoc.getValue(), mv, callee.getSubstitutions(), uncurriedArgs, @@ -3227,6 +3529,7 @@ namespace { initialOptions, None, foreignError, uncurriedContext); + // Handle a specialized emitter operating on evaluated arguments. } else if (specializedEmitter->isLateEmitter()) { auto emitter = specializedEmitter->getLateEmitter(); result = emitter(gen, @@ -3235,6 +3538,7 @@ namespace { uncurriedArgs, formalApplyType, uncurriedContext); + // Builtins. } else { assert(specializedEmitter->isNamedBuiltin()); auto builtinName = specializedEmitter->getBuiltinName(); @@ -3475,7 +3779,7 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &gen, bool isClassDispatch = false; if (!isDirectUse) { - switch (gen.getMethodDispatch(decl)) { + switch (getMethodDispatch(decl)) { case MethodDispatch::Class: isClassDispatch = true; break; @@ -3485,7 +3789,7 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &gen, } } - // Dispatch in a struct/enum or to an final method is always direct. + // Dispatch in a struct/enum or to a final method is always direct. if (!isClassDispatch || decl->isFinal()) return Callee::forDirect(gen, constant, substAccessorType, loc); @@ -3496,12 +3800,13 @@ static Callee getBaseAccessorFunctionRef(SILGenFunction &gen, return Callee::forClassMethod(gen, self, constant, substAccessorType, loc); - // If this is a "super." dispatch, we either do a direct dispatch in the case - // of swift classes or an objc super call. + // If this is a "super." dispatch, we do a dynamic dispatch for objc methods + // or non-final native Swift methods. while (auto *upcast = dyn_cast(self)) self = upcast->getOperand(); - if (constant.isForeign) + auto Opts = gen.B.getModule().getOptions(); + if (constant.isForeign || (Opts.UseNativeSuperMethod && !decl->isFinal())) return Callee::forSuperMethod(gen, self, constant, substAccessorType,loc); return Callee::forDirect(gen, constant, substAccessorType, loc); @@ -3518,13 +3823,6 @@ emitSpecializedAccessorFunctionRef(SILGenFunction &gen, { SILConstantInfo constantInfo = gen.getConstantInfo(constant); - // Collect captures if the accessor has them. - auto accessorFn = cast(constant.getDecl()); - if (accessorFn->getCaptureInfo().hasLocalCaptures()) { - assert(!selfValue && "local property has self param?!"); - selfValue = emitCapturesAsArgumentSource(gen, loc, accessorFn).first; - } - // Apply substitutions to the callee type. CanAnyFunctionType substAccessorType = constantInfo.FormalType; if (!substitutions.empty()) { @@ -3538,6 +3836,16 @@ emitSpecializedAccessorFunctionRef(SILGenFunction &gen, Callee callee = getBaseAccessorFunctionRef(gen, loc, constant, selfValue, isSuper, isDirectUse, substAccessorType, substitutions); + + // Collect captures if the accessor has them. + auto accessorFn = cast(constant.getDecl()); + if (accessorFn->getCaptureInfo().hasLocalCaptures()) { + assert(!selfValue && "local property has self param?!"); + SmallVector captures; + gen.emitCaptures(loc, accessorFn, CaptureEmission::ImmediateApplication, + captures); + callee.setCaptures(std::move(captures)); + } // If there are substitutions, specialize the generic accessor. // FIXME: Generic subscript operator could add another layer of @@ -3571,6 +3879,7 @@ ArgumentSource SILGenFunction::prepareAccessorBaseArg(SILLocation loc, // If the accessor wants the value 'inout', always pass the // address we were given. This is semantically required. case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: return false; // If the accessor wants the value 'in', we have to copy if the @@ -3648,13 +3957,12 @@ ArgumentSource SILGenFunction::prepareAccessorBaseArg(SILLocation loc, return (p && !p->requiresClass()); }; #endif - assert((!selfParam.isIndirectInOut() || + assert((!selfParam.isIndirectMutating() || (baseFormalType->isAnyClassReferenceType() && isNonClassProtocolMember(accessor.getDecl()))) && "passing unmaterialized r-value as inout argument"); base = emitMaterializeIntoTemporary(*this, loc, base); - if (selfParam.isIndirectInOut()) { // Drop the cleanup if we have one. auto baseLV = ManagedValue::forLValue(base.getValue()); @@ -3690,12 +3998,17 @@ emitGetAccessor(SILLocation loc, SILDeclRef get, Callee getter = emitSpecializedAccessorFunctionRef(*this, loc, get, substitutions, selfValue, isSuper, isDirectUse); + bool hasCaptures = getter.hasCaptures(); + bool hasSelf = (bool)selfValue; CanAnyFunctionType accessType = getter.getSubstFormalType(); CallEmission emission(*this, std::move(getter), std::move(writebackScope)); // Self -> - if (selfValue) { + if (hasSelf) { emission.addCallSite(loc, std::move(selfValue), accessType); + } + // TODO: Have Callee encapsulate the captures better. + if (hasSelf || hasCaptures) { accessType = cast(accessType.getResult()); } // Index or () if none. @@ -3728,12 +4041,17 @@ void SILGenFunction::emitSetAccessor(SILLocation loc, SILDeclRef set, Callee setter = emitSpecializedAccessorFunctionRef(*this, loc, set, substitutions, selfValue, isSuper, isDirectUse); + bool hasCaptures = setter.hasCaptures(); + bool hasSelf = (bool)selfValue; CanAnyFunctionType accessType = setter.getSubstFormalType(); CallEmission emission(*this, std::move(setter), std::move(writebackScope)); // Self -> - if (selfValue) { + if (hasSelf) { emission.addCallSite(loc, std::move(selfValue), accessType); + } + // TODO: Have Callee encapsulate the captures better. + if (hasSelf || hasCaptures) { accessType = cast(accessType.getResult()); } @@ -3783,12 +4101,17 @@ emitMaterializeForSetAccessor(SILLocation loc, SILDeclRef materializeForSet, materializeForSet, substitutions, selfValue, isSuper, isDirectUse); + bool hasCaptures = callee.hasCaptures(); + bool hasSelf = (bool)selfValue; CanAnyFunctionType accessType = callee.getSubstFormalType(); CallEmission emission(*this, std::move(callee), std::move(writebackScope)); // Self -> - if (selfValue) { + if (hasSelf) { emission.addCallSite(loc, std::move(selfValue), accessType); + } + // TODO: Have Callee encapsulate the captures better. + if (hasSelf || hasCaptures) { accessType = cast(accessType.getResult()); } @@ -3852,12 +4175,17 @@ emitAddressorAccessor(SILLocation loc, SILDeclRef addressor, emitSpecializedAccessorFunctionRef(*this, loc, addressor, substitutions, selfValue, isSuper, isDirectUse); + bool hasCaptures = callee.hasCaptures(); + bool hasSelf = (bool)selfValue; CanAnyFunctionType accessType = callee.getSubstFormalType(); CallEmission emission(*this, std::move(callee), std::move(writebackScope)); // Self -> - if (selfValue) { + if (hasSelf) { emission.addCallSite(loc, std::move(selfValue), accessType); + } + // TODO: Have Callee encapsulate the captures better. + if (hasSelf || hasCaptures) { accessType = cast(accessType.getResult()); } // Index or () if none. diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 96d734e0216b7..6e18afe9e3ce8 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,6 +15,7 @@ #include "Scope.h" #include "swift/AST/AST.h" #include "swift/AST/ForeignErrorConvention.h" +#include "swift/AST/ParameterList.h" #include "swift/Basic/Fallthrough.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/TypeLowering.h" @@ -213,6 +214,7 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &gen, case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_In_Guaranteed: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: llvm_unreachable("indirect params to blocks not supported"); } @@ -241,6 +243,7 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &gen, case ParameterConvention::Indirect_In_Guaranteed: case ParameterConvention::Indirect_In: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: llvm_unreachable("indirect arguments to blocks not supported"); } @@ -278,8 +281,6 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &gen, gen.B.createReturn(loc, resultVal); break; case ResultConvention::Autoreleased: - gen.B.createAutoreleaseReturn(loc, resultVal); - break; case ResultConvention::Owned: gen.B.createReturn(loc, resultVal); break; @@ -297,8 +298,8 @@ ManagedValue SILGenFunction::emitFuncToBlock(SILLocation loc, // Build the invoke function type. SmallVector params; - params.push_back( - SILParameterInfo(storageTy, ParameterConvention::Indirect_Inout)); + params.push_back(SILParameterInfo(storageTy, + ParameterConvention::Indirect_InoutAliasable)); std::copy(blockTy->getParameters().begin(), blockTy->getParameters().end(), std::back_inserter(params)); @@ -718,14 +719,12 @@ static void emitObjCReturnValue(SILGenFunction &gen, // Autorelease the bridged result if necessary. switch (resultInfo.getConvention()) { - case ResultConvention::Autoreleased: - gen.B.createAutoreleaseReturn(loc, result); - return; case ResultConvention::UnownedInnerPointer: case ResultConvention::Unowned: assert(gen.getTypeLowering(result.getType()).isTrivial() && "nontrivial result is returned unowned?!"); SWIFT_FALLTHROUGH; + case ResultConvention::Autoreleased: case ResultConvention::Owned: gen.B.createReturn(loc, result); return; @@ -807,7 +806,7 @@ static SILFunctionType *emitObjCThunkArguments(SILGenFunction &gen, // If this parameter is deallocating, emit an unmanaged rvalue and // continue. The object has the deallocating bit set so retain, release is - // irrelevent. + // irrelevant. if (inputs[i].isDeallocating()) { bridgedArgs.push_back(ManagedValue::forUnmanaged(arg)); continue; @@ -970,14 +969,30 @@ getThunkedForeignFunctionRef(SILGenFunction &gen, SILLocation loc, SILDeclRef foreign, ArrayRef args, + ArrayRef subs, const SILConstantInfo &foreignCI) { assert(!foreign.isCurried && "should not thunk calling convention when curried"); - // Produce a class_method when thunking ObjC methods. - auto foreignTy = foreignCI.SILFnType; - if (foreignTy->getRepresentation() + // Produce a witness_method when thunking ObjC protocol methods. + auto dc = foreign.getDecl()->getDeclContext(); + if (isa(dc) && cast(dc)->isObjC()) { + assert(subs.size() == 1); + auto thisType = subs[0].getReplacement()->getCanonicalType(); + assert(isa(thisType) && "no archetype for witness?!"); + SILValue thisArg = args.back().getValue(); + + SILValue OpenedExistential; + if (!cast(thisType)->getOpenedExistentialType().isNull()) + OpenedExistential = thisArg; + return gen.B.createWitnessMethod(loc, thisType, nullptr, foreign, + foreignCI.getSILType(), + OpenedExistential); + + // Produce a class_method when thunking imported ObjC methods. + } else if (foreignCI.SILFnType->getRepresentation() == SILFunctionTypeRepresentation::ObjCMethod) { + assert(subs.empty()); SILValue thisArg = args.back().getValue(); return gen.B.createClassMethod(loc, thisArg, foreign, @@ -1009,19 +1024,19 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) { } // Forward the arguments. - auto forwardedPatterns = fd->getBodyParamPatterns(); + auto forwardedParameters = fd->getParameterLists(); // For allocating constructors, 'self' is a metatype, not the 'self' value // formally present in the constructor body. Type allocatorSelfType; if (thunk.kind == SILDeclRef::Kind::Allocator) { - allocatorSelfType = forwardedPatterns[0]->getType(); - forwardedPatterns = forwardedPatterns.slice(1); + allocatorSelfType = forwardedParameters[0]->getType(getASTContext()); + forwardedParameters = forwardedParameters.slice(1); } SmallVector params; - for (auto *paramPattern : reversed(forwardedPatterns)) - bindParametersForForwarding(paramPattern, params); + for (auto *paramList : reversed(forwardedParameters)) + bindParametersForForwarding(paramList, params); if (allocatorSelfType) { auto selfMetatype = CanMetatypeType::get(allocatorSelfType->getCanonicalType(), @@ -1080,6 +1095,7 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) { param = ManagedValue::forUnmanaged(paramValue); break; case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: param = ManagedValue::forUnmanaged(paramValue); break; case ParameterConvention::Indirect_In: @@ -1102,12 +1118,19 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) { maybeAddForeignErrorArg(); // Call the original. - auto fn = getThunkedForeignFunctionRef(*this, fd, foreignDeclRef, args, + auto subs = getForwardingSubstitutions(); + auto fn = getThunkedForeignFunctionRef(*this, fd, foreignDeclRef, args, subs, foreignCI); - result = emitMonomorphicApply(fd, ManagedValue::forUnmanaged(fn), - args, - nativeFormalResultTy, - ApplyOptions::None, None, foreignError) + + auto fnType = fn.getType().castTo(); + fnType = fnType->substGenericArgs(SGM.M, SGM.SwiftModule, subs); + + result = emitApply(fd, ManagedValue::forUnmanaged(fn), + subs, args, fnType, + AbstractionPattern(nativeFormalResultTy), + nativeFormalResultTy, + ApplyOptions::None, None, foreignError, + SGFContext()) .forward(*this); } B.createReturn(ImplicitReturnLocation::getImplicitReturnLoc(fd), result); diff --git a/lib/SILGen/SILGenBuiltin.cpp b/lib/SILGen/SILGenBuiltin.cpp index 51e847c979421..6ec16ac142e57 100644 --- a/lib/SILGen/SILGenBuiltin.cpp +++ b/lib/SILGen/SILGenBuiltin.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp index 4afca5feac6d4..cfbb162ae0898 100644 --- a/lib/SILGen/SILGenConstructor.cpp +++ b/lib/SILGen/SILGenConstructor.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "SILGenFunction.h" +#include "ArgumentSource.h" #include "Initialization.h" #include "LValue.h" #include "RValue.h" @@ -67,7 +68,7 @@ static void emitImplicitValueConstructor(SILGenFunction &gen, RegularLocation Loc(ctor); Loc.markAutoGenerated(); // FIXME: Handle 'self' along with the other arguments. - auto *TP = cast(ctor->getBodyParamPatterns()[1]); + auto *paramList = ctor->getParameterList(1); auto selfTyCan = ctor->getImplicitSelfDecl()->getType()->getInOutObjectType(); SILType selfTy = gen.getLoweredType(selfTyCan); @@ -85,12 +86,13 @@ static void emitImplicitValueConstructor(SILGenFunction &gen, // Emit the elementwise arguments. SmallVector elements; - for (size_t i = 0, size = TP->getNumElements(); i < size; ++i) { - auto *P = cast(TP->getElement(i).getPattern()); + for (size_t i = 0, size = paramList->size(); i < size; ++i) { + auto ¶m = paramList->get(i); elements.push_back( emitImplicitValueConstructorArg(gen, Loc, - P->getType()->getCanonicalType(), ctor)); + param->getType()->getCanonicalType(), + ctor)); } emitConstructorMetatypeArg(gen, ctor); @@ -164,13 +166,6 @@ static void emitImplicitValueConstructor(SILGenFunction &gen, return; } -static unsigned countSwiftArgs(ArrayRef Patterns) { - unsigned N = 0; - for (auto p : Patterns) - p->forEachVariable([&](VarDecl *) { ++N; }); - return N; -} - void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) { MagicFunctionName = SILGenModule::getMagicFunctionName(ctor); @@ -190,7 +185,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) { && "can't emit a class ctor here"); // Self is a curried argument and thus comes last. - unsigned N = countSwiftArgs(ctor->getBodyParamPatterns()[1]) + 1; + unsigned N = ctor->getParameterList(1)->size() + 1; // Allocate the local variable for 'self'. emitLocalVariableWithCleanup(selfDecl, false, N)->finishInitialization(*this); @@ -206,7 +201,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) { } // Emit the prolog. - emitProlog(ctor->getBodyParamPatterns()[1], ctor->getResultType(), ctor); + emitProlog(ctor->getParameterList(1), ctor->getResultType(), ctor); emitConstructorMetatypeArg(*this, ctor); // Create a basic block to jump to for the implicit 'self' return. @@ -344,108 +339,66 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) { } } -static void boxIndirectEnumPayload(SILGenFunction &gen, - ManagedValue &payload, - SILLocation loc, - EnumElementDecl *element) { - // If the payload is indirect, we'll need to box it. - if (payload && (element->isIndirect() || - element->getParentEnum()->isIndirect())) { - auto box = gen.B.createAllocBox(loc, payload.getType()); - payload.forwardInto(gen, loc, box->getAddressResult()); - payload = gen.emitManagedRValueWithCleanup(box); - } -} +void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) { + CanType enumTy = element->getParentEnum() + ->getDeclaredTypeInContext() + ->getCanonicalType(); + auto &enumTI = getTypeLowering(enumTy); -static void emitAddressOnlyEnumConstructor(SILGenFunction &gen, - SILType enumTy, - EnumElementDecl *element) { RegularLocation Loc(element); CleanupLocation CleanupLoc(element); Loc.markAutoGenerated(); // Emit the indirect return slot. - auto &AC = gen.getASTContext(); - auto VD = new (AC) ParamDecl(/*IsLet*/ false, SourceLoc(), - AC.getIdentifier("$return_value"), - SourceLoc(), - AC.getIdentifier("$return_value"), - enumTy.getSwiftType(), - element->getDeclContext()); - SILValue resultSlot - = new (gen.F.getModule()) SILArgument(gen.F.begin(), enumTy, VD); - - Scope scope(gen.Cleanups, CleanupLoc); - - // Emit the exploded constructor argument. - ManagedValue argValue; - if (element->hasArgumentType()) { - RValue arg = emitImplicitValueConstructorArg - (gen, Loc, element->getArgumentType()->getCanonicalType(), - element->getDeclContext()); - argValue = std::move(arg).getAsSingleValue(gen, Loc); - } - emitConstructorMetatypeArg(gen, element); - - boxIndirectEnumPayload(gen, argValue, Loc, element); - - // Store the data, if any. - if (argValue) { - SILValue resultData = gen.B.createInitEnumDataAddr(element, resultSlot, - element, argValue.getType().getAddressType()); - argValue.forwardInto(gen, element, resultData); + std::unique_ptr dest; + if (enumTI.isAddressOnly()) { + auto &AC = getASTContext(); + auto VD = new (AC) ParamDecl(/*IsLet*/ false, SourceLoc(), + AC.getIdentifier("$return_value"), + SourceLoc(), + AC.getIdentifier("$return_value"), + CanInOutType::get(enumTy), + element->getDeclContext()); + auto resultSlot = new (SGM.M) SILArgument(F.begin(), + enumTI.getLoweredType(), + VD); + dest = std::unique_ptr( + new KnownAddressInitialization(resultSlot)); } - // Apply the tag. - gen.B.createInjectEnumAddr(Loc, resultSlot, element); - scope.pop(); - gen.B.createReturn(ImplicitReturnLocation::getImplicitReturnLoc(Loc), - gen.emitEmptyTuple(element)); -} - -static void emitLoadableEnumConstructor(SILGenFunction &gen, SILType enumTy, - EnumElementDecl *element) { - RegularLocation Loc(element); - CleanupLocation CleanupLoc(element); - Loc.markAutoGenerated(); - - Scope scope(gen.Cleanups, CleanupLoc); + Scope scope(Cleanups, CleanupLoc); // Emit the exploded constructor argument. - ManagedValue payload; + ArgumentSource payload; if (element->hasArgumentType()) { RValue arg = emitImplicitValueConstructorArg - (gen, Loc, - element->getArgumentType()->getCanonicalType(), + (*this, Loc, element->getArgumentType()->getCanonicalType(), element->getDeclContext()); - payload = std::move(arg).getAsSingleValue(gen, Loc); + payload = ArgumentSource(Loc, std::move(arg)); } - emitConstructorMetatypeArg(gen, element); + // Emit the metatype argument. + emitConstructorMetatypeArg(*this, element); - boxIndirectEnumPayload(gen, payload, Loc, element); - - // Create and return the enum value. - SILValue argValue; - if (payload) - argValue = payload.forward(gen); - SILValue result = gen.B.createEnum(Loc, argValue, element, enumTy); - scope.pop(); - gen.B.createReturn(ImplicitReturnLocation::getImplicitReturnLoc(Loc), result); -} + // If possible, emit the enum directly into the indirect return. + SGFContext C = (dest ? SGFContext(dest.get()) : SGFContext()); + ManagedValue mv = emitInjectEnum(Loc, std::move(payload), + enumTI.getLoweredType(), + element, C); -void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) { - Type enumTy = element->getType()->getAs()->getResult(); - if (element->hasArgumentType()) - enumTy = enumTy->getAs()->getResult(); - auto &enumTI = getTypeLowering(enumTy); + // Return the enum. + auto ReturnLoc = ImplicitReturnLocation::getImplicitReturnLoc(Loc); - if (enumTI.isAddressOnly()) { - return emitAddressOnlyEnumConstructor(*this, enumTI.getLoweredType(), - element); + if (mv.isInContext()) { + assert(enumTI.isAddressOnly()); + scope.pop(); + B.createReturn(ReturnLoc, emitEmptyTuple(Loc)); + } else { + assert(enumTI.isLoadable()); + SILValue result = mv.forward(*this); + scope.pop(); + B.createReturn(ReturnLoc, result); } - return emitLoadableEnumConstructor(*this, enumTI.getLoweredType(), - element); } bool Lowering::usesObjCAllocator(ClassDecl *theClass) { @@ -470,7 +423,7 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) { // Forward the constructor arguments. // FIXME: Handle 'self' along with the other body patterns. SmallVector args; - bindParametersForForwarding(ctor->getBodyParamPatterns()[1], args); + bindParametersForForwarding(ctor->getParameterList(1), args); SILValue selfMetaValue = emitConstructorMetatypeArg(*this, ctor); @@ -607,7 +560,7 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) { // Emit the prolog for the non-self arguments. // FIXME: Handle self along with the other body patterns. - emitProlog(ctor->getBodyParamPatterns()[1], + emitProlog(ctor->getParameterList(1), TupleType::getEmpty(F.getASTContext()), ctor); SILType selfTy = getLoweredLoadableType(selfDecl->getType()); diff --git a/lib/SILGen/SILGenConvert.cpp b/lib/SILGen/SILGenConvert.cpp index 25dcca06913c9..6627d11679ba5 100644 --- a/lib/SILGen/SILGenConvert.cpp +++ b/lib/SILGen/SILGenConvert.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,9 +30,8 @@ using namespace swift; using namespace Lowering; -// FIXME: need to sit down and abstract away differences between -// SGF::emitInjectOptionalInto(), SGF::emitInjectOptionalValueInto(), -// SGF::getOptionalSomeValue(), and this function... +// FIXME: With some changes to their callers, all of the below functions +// could be re-worked to use emitInjectEnum(). ManagedValue SILGenFunction::emitInjectOptional(SILLocation loc, ManagedValue v, diff --git a/lib/SILGen/SILGenDecl.cpp b/lib/SILGen/SILGenDecl.cpp index d6d9f789bb872..dc541981cbcb3 100644 --- a/lib/SILGen/SILGenDecl.cpp +++ b/lib/SILGen/SILGenDecl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -250,7 +250,8 @@ class LocalVariableInitialization : public SingleBufferInitialization { // The variable may have its lifetime extended by a closure, heap-allocate // it using a box. - AllocBoxInst *allocBox = SGF.B.createAllocBox(decl, lType, ArgNo); + AllocBoxInst *allocBox = + SGF.B.createAllocBox(decl, lType, {decl->isLet(), ArgNo}); auto box = SILValue(allocBox, 0); auto addr = SILValue(allocBox, 1); @@ -1063,8 +1064,7 @@ SILGenFunction::emitPatternBindingInitialization(Pattern *P, /// Enter a cleanup to deallocate the given location. CleanupHandle SILGenFunction::enterDeallocStackCleanup(SILValue temp) { - assert(temp.getType().isLocalStorage() && - "must deallocate container operand, not address operand!"); + assert(temp.getType().isAddress() && "dealloc must have an address type"); Cleanups.pushCleanup(temp); return Cleanups.getTopCleanup(); } @@ -1155,11 +1155,9 @@ void SILGenModule::emitExternalDefinition(Decl *d) { } case DeclKind::Enum: { auto ed = cast(d); - // Emit the enum cases and derived conformance methods for the type. + // Emit derived conformance methods for the type. for (auto member : ed->getMembers()) { - if (auto elt = dyn_cast(member)) - emitEnumConstructor(elt); - else if (auto func = dyn_cast(member)) + if (auto func = dyn_cast(member)) emitFunction(func); else if (auto ctor = dyn_cast(member)) emitConstructor(ctor); @@ -1719,11 +1717,10 @@ SILGenModule::emitProtocolWitness(ProtocolConformance *conformance, requirement.uncurryLevel); // Mangle the name of the witness thunk. - llvm::SmallString<128> nameBuffer; + std::string nameBuffer; { - llvm::raw_svector_ostream nameStream(nameBuffer); - nameStream << "_TTW"; - Mangler mangler(nameStream); + Mangler mangler; + mangler.append("_TTW"); mangler.mangleProtocolConformance(conformance); if (auto ctor = dyn_cast(requirement.getDecl())) { @@ -1737,6 +1734,8 @@ SILGenModule::emitProtocolWitness(ProtocolConformance *conformance, mangler.mangleEntity(requiredDecl, ResilienceExpansion::Minimal, requirement.uncurryLevel); } + + nameBuffer = mangler.finalize(); } // Collect the context generic parameters for the witness. @@ -1764,16 +1763,11 @@ SILGenModule::emitProtocolWitness(ProtocolConformance *conformance, if (witness.isAlwaysInline()) InlineStrategy = AlwaysInline; - auto *f = SILFunction::create(M, linkage, nameBuffer, - witnessSILType.castTo(), - witnessContextParams, - SILLocation(witness.getDecl()), - IsNotBare, - IsTransparent, - makeModuleFragile ? IsFragile : IsNotFragile, - IsThunk, - SILFunction::NotRelevant, - InlineStrategy); + auto *f = M.getOrCreateFunction( + linkage, nameBuffer, witnessSILType.castTo(), + witnessContextParams, SILLocation(witness.getDecl()), IsNotBare, + IsTransparent, makeModuleFragile ? IsFragile : IsNotFragile, IsThunk, + SILFunction::NotRelevant, InlineStrategy); f->setDebugScope(new (M) SILDebugScope(RegularLocation(witness.getDecl()), *f)); @@ -1794,16 +1788,15 @@ getOrCreateReabstractionThunk(GenericParamList *thunkContextParams, CanSILFunctionType toType, IsFragile_t Fragile) { // Mangle the reabstraction thunk. - llvm::SmallString<256> buffer; + std::string name ; { - llvm::raw_svector_ostream stream(buffer); - Mangler mangler(stream); + Mangler mangler; // This is actually the SIL helper function. For now, IR-gen // makes the actual thunk. - stream << "_TTR"; + mangler.append("_TTR"); if (auto generics = thunkType->getGenericSignature()) { - stream << 'G'; + mangler.append('G'); mangler.setModuleContext(M.getSwiftModule()); mangler.mangleGenericSignature(generics, ResilienceExpansion::Minimal); @@ -1819,12 +1812,11 @@ getOrCreateReabstractionThunk(GenericParamList *thunkContextParams, ResilienceExpansion::Minimal, /*uncurry*/ 0); mangler.mangleType(toInterfaceType, ResilienceExpansion::Minimal, /*uncurry*/ 0); + name = mangler.finalize(); } auto loc = RegularLocation::getAutoGeneratedLocation(); - return M.getOrCreateSharedFunction(loc, - buffer.str(), - thunkType, - IsBare, IsTransparent, - Fragile, IsReabstractionThunk); + return M.getOrCreateSharedFunction(loc, name, thunkType, IsBare, + IsTransparent, Fragile, + IsReabstractionThunk); } diff --git a/lib/SILGen/SILGenDestructor.cpp b/lib/SILGen/SILGenDestructor.cpp index 53118db785453..b1c8c2a547d26 100644 --- a/lib/SILGen/SILGenDestructor.cpp +++ b/lib/SILGen/SILGenDestructor.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/SILGenDynamicCast.cpp b/lib/SILGen/SILGenDynamicCast.cpp index 31593e5d26979..639018ee0b72b 100644 --- a/lib/SILGen/SILGenDynamicCast.cpp +++ b/lib/SILGen/SILGenDynamicCast.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/SILGenDynamicCast.h b/lib/SILGen/SILGenDynamicCast.h index b2495ed09e991..9477e6f6a5c34 100644 --- a/lib/SILGen/SILGenDynamicCast.h +++ b/lib/SILGen/SILGenDynamicCast.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/SILGenEpilog.cpp b/lib/SILGen/SILGenEpilog.cpp index 0b5de20758421..23045371954ac 100644 --- a/lib/SILGen/SILGenEpilog.cpp +++ b/lib/SILGen/SILGenEpilog.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 4ea03a43e0ca7..b389d7070cbf2 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -196,6 +196,7 @@ namespace { RValue visitInterpolatedStringLiteralExpr(InterpolatedStringLiteralExpr *E, SGFContext C); RValue visitObjectLiteralExpr(ObjectLiteralExpr *E, SGFContext C); + RValue visitEditorPlaceholderExpr(EditorPlaceholderExpr *E, SGFContext C); RValue visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E, SGFContext C); RValue visitCollectionExpr(CollectionExpr *E, SGFContext C); @@ -292,7 +293,7 @@ emitRValueForDecl(SILLocation loc, ConcreteDeclRef declRef, Type ncRefType, // Any writebacks for this access are tightly scoped. WritebackScope scope(*this); - // If this is an decl that we have an lvalue for, produce and return it. + // If this is a decl that we have an lvalue for, produce and return it. ValueDecl *decl = declRef.getDecl(); if (!ncRefType) ncRefType = decl->getType(); @@ -841,8 +842,8 @@ SILValue SILGenFunction::emitTemporaryAllocation(SILLocation loc, SILType ty) { ty = ty.getObjectType(); auto alloc = B.createAllocStack(loc, ty); - enterDeallocStackCleanup(alloc->getContainerResult()); - return alloc->getAddressResult(); + enterDeallocStackCleanup(alloc); + return alloc; } // Return an initialization address we can emit directly into. @@ -1956,6 +1957,11 @@ visitObjectLiteralExpr(ObjectLiteralExpr *E, SGFContext C) { return visit(E->getSemanticExpr(), C); } +RValue RValueEmitter:: +visitEditorPlaceholderExpr(EditorPlaceholderExpr *E, SGFContext C) { + return visit(E->getSemanticExpr(), C); +} + static StringRef getMagicFunctionString(SILGenFunction &gen) { assert(gen.MagicFunctionName @@ -2337,20 +2343,16 @@ RValue RValueEmitter::visitInjectIntoOptionalExpr(InjectIntoOptionalExpr *E, ManagedValue bitcastMV = ManagedValue(bitcast, result.getCleanup()); return RValue(SGF, E, bitcastMV); } - - // Create a buffer for the result if this is an address-only optional. - auto &optTL = SGF.getTypeLowering(E->getType()); - if (!optTL.isAddressOnly()) { - auto result = SGF.emitRValueAsSingleValue(E->getSubExpr()); - result = SGF.getOptionalSomeValue(E, result, optTL); - return RValue(SGF, E, result); - } - - SILValue optAddr = SGF.getBufferForExprResult(E, optTL.getLoweredType(), C); - - SGF.emitInjectOptionalValueInto(E, E->getSubExpr(), optAddr, optTL); - - ManagedValue result = SGF.manageBufferForExprResult(optAddr, optTL, C); + + OptionalTypeKind OTK; + E->getType()->getAnyOptionalObjectType(OTK); + assert(OTK != OTK_None); + + auto someDecl = SGF.getASTContext().getOptionalSomeDecl(OTK); + + ManagedValue result = SGF.emitInjectEnum(E, ArgumentSource(E->getSubExpr()), + SGF.getLoweredType(E->getType()), + someDecl, C); if (result.isInContext()) return RValue(); return RValue(SGF, E, result); diff --git a/lib/SILGen/SILGenForeignError.cpp b/lib/SILGen/SILGenForeignError.cpp index 89510c06381a0..54bd0282b66b0 100644 --- a/lib/SILGen/SILGenForeignError.cpp +++ b/lib/SILGen/SILGenForeignError.cpp @@ -1,8 +1,8 @@ -//===--- SILGenError.cpp - Error-handling code emission -------------------===// +//===--- SILGenForeignError.cpp - Error-handling code emission ------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index 908e84a4be26d..79cf053a08a84 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,9 +28,9 @@ using namespace swift; using namespace Lowering; -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // SILGenFunction Class implementation -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// SILGenFunction::SILGenFunction(SILGenModule &SGM, SILFunction &F) : SGM(SGM), F(F), @@ -55,9 +55,9 @@ SILGenFunction::~SILGenFunction() { freeWritebackStack(); } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Function emission -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Get the __FUNCTION__ name for a declaration. DeclName SILGenModule::getMagicFunctionName(DeclContext *dc) { @@ -146,8 +146,10 @@ SILValue SILGenFunction::emitGlobalFunctionRef(SILLocation loc, constant.uncurryLevel + 1); // If the function is fully uncurried and natively foreign, reference its // foreign entry point. - if (!next.isCurried && vd->hasClangNode()) - next = next.asForeign(); + if (!next.isCurried) { + if (requiresForeignToNativeThunk(vd)) + next = next.asForeign(); + } // Preserve whether the curry thunks lead to a direct reference to the // method implementation. @@ -161,6 +163,8 @@ SILValue SILGenFunction::emitGlobalFunctionRef(SILLocation loc, SGM.emitForeignToNativeThunk(constant); } else if (constant.isNativeToForeignThunk()) { SGM.emitNativeToForeignThunk(constant); + } else if (constant.kind == SILDeclRef::Kind::EnumElement) { + SGM.emitEnumConstructor(cast(constant.getDecl())); } } @@ -198,11 +202,6 @@ SILGenFunction::emitSiblingMethodRef(SILLocation loc, methodTy, subs); } -ManagedValue SILGenFunction::emitFunctionRef(SILLocation loc, - SILDeclRef constant) { - return emitFunctionRef(loc, constant, getConstantInfo(constant)); -} - ManagedValue SILGenFunction::emitFunctionRef(SILLocation loc, SILDeclRef constant, SILConstantInfo constantInfo) { @@ -221,8 +220,28 @@ ManagedValue SILGenFunction::emitFunctionRef(SILLocation loc, void SILGenFunction::emitCaptures(SILLocation loc, AnyFunctionRef TheClosure, + CaptureEmission purpose, SmallVectorImpl &capturedArgs) { auto captureInfo = SGM.Types.getLoweredLocalCaptures(TheClosure); + // For boxed captures, we need to mark the contained variables as having + // escaped for DI diagnostics. + SmallVector escapesToMark; + + // Partial applications take ownership of the context parameters, so we'll + // need to pass ownership rather than merely guaranteeing parameters. + bool canGuarantee; + switch (purpose) { + case CaptureEmission::PartialApplication: + canGuarantee = false; + break; + case CaptureEmission::ImmediateApplication: + canGuarantee = true; + break; + } + // TODO: Or we always retain them when guaranteed contexts aren't enabled. + if (!SGM.M.getOptions().EnableGuaranteedClosureContexts) + canGuarantee = false; + for (auto capture : captureInfo.getCaptures()) { auto *vd = capture.getDecl(); @@ -234,11 +253,18 @@ void SILGenFunction::emitCaptures(SILLocation loc, // let declarations. auto Entry = VarLocs[vd]; - // Non-address-only constants are passed at +1. auto &tl = getTypeLowering(vd->getType()->getReferenceStorageReferent()); SILValue Val = Entry.value; if (!Val.getType().isAddress()) { + // Our 'let' binding can guarantee the lifetime for the callee, + // if we don't need to do anything more to it. + if (canGuarantee && !vd->getType()->is()) { + auto guaranteed = ManagedValue::forUnmanaged(Val); + capturedArgs.push_back(guaranteed); + break; + } + // Just retain a by-val let. B.emitRetainValueOperation(loc, Val); } else { @@ -247,20 +273,15 @@ void SILGenFunction::emitCaptures(SILLocation loc, Val = emitLoad(loc, Val, tl, SGFContext(), IsNotTake).forward(*this); } - // Use an RValue to explode Val if it is a tuple. - RValue RV(*this, loc, vd->getType()->getCanonicalType(), - ManagedValue::forUnmanaged(Val)); - // If we're capturing an unowned pointer by value, we will have just // loaded it into a normal retained class pointer, but we capture it as // an unowned pointer. Convert back now. if (vd->getType()->is()) { auto type = getTypeLowering(vd->getType()).getLoweredType(); - auto val = std::move(RV).forwardAsSingleStorageValue(*this, type,loc); - capturedArgs.push_back(emitManagedRValueWithCleanup(val)); - } else { - std::move(RV).getAll(capturedArgs); + Val = emitConversionFromSemanticValue(loc, Val, type); } + + capturedArgs.push_back(emitManagedRValueWithCleanup(Val)); break; } @@ -283,27 +304,42 @@ void SILGenFunction::emitCaptures(SILLocation loc, // If this is a boxed variable, we can use it directly. if (vl.box) { - B.createStrongRetain(loc, vl.box); - capturedArgs.push_back(emitManagedRValueWithCleanup(vl.box)); - capturedArgs.push_back(ManagedValue::forLValue(vl.value)); + // We can guarantee our own box to the callee. + if (canGuarantee) { + capturedArgs.push_back(ManagedValue::forUnmanaged(vl.box)); + } else { + B.createStrongRetain(loc, vl.box); + capturedArgs.push_back(emitManagedRValueWithCleanup(vl.box)); + } + escapesToMark.push_back(vl.value); } else { // Address only 'let' values are passed by box. This isn't great, in // that a variable captured by multiple closures will be boxed for each // one. This could be improved by doing an "isCaptured" analysis when - // emitting address-only let constants, and emit them into a alloc_box + // emitting address-only let constants, and emit them into an alloc_box // like a variable instead of into an alloc_stack. + // + // TODO: This might not be profitable anymore with guaranteed captures, + // since we could conceivably forward the copied value into the + // closure context and pass it down to the partially applied function + // in-place. AllocBoxInst *allocBox = B.createAllocBox(loc, vl.value.getType().getObjectType()); auto boxAddress = SILValue(allocBox, 1); B.createCopyAddr(loc, vl.value, boxAddress, IsNotTake,IsInitialization); capturedArgs.push_back(emitManagedRValueWithCleanup(SILValue(allocBox, 0))); - capturedArgs.push_back(ManagedValue::forLValue(boxAddress)); } break; } } } + + // Mark box addresses as captured for DI purposes. The values must have + // been fully initialized before we close over them. + if (!escapesToMark.empty()) { + B.createMarkFunctionEscape(loc, escapesToMark); + } } ManagedValue @@ -345,10 +381,10 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant, } SmallVector capturedArgs; - emitCaptures(loc, TheClosure, capturedArgs); + emitCaptures(loc, TheClosure, CaptureEmission::PartialApplication, + capturedArgs); - // Currently all capture arguments are captured at +1. - // TODO: Ideally this would be +0. + // The partial application takes ownership of the context parameters. SmallVector forwardedArgs; for (auto capture : capturedArgs) forwardedArgs.push_back(capture.forward(*this)); @@ -371,7 +407,7 @@ void SILGenFunction::emitFunction(FuncDecl *fd) { MagicFunctionName = SILGenModule::getMagicFunctionName(fd); Type resultTy = fd->getResultType(); - emitProlog(fd, fd->getBodyParamPatterns(), resultTy); + emitProlog(fd, fd->getParameterLists(), resultTy); prepareEpilog(resultTy, fd->isBodyThrowing(), CleanupLocation(fd)); emitProfilerIncrement(fd->getBody()); @@ -383,7 +419,7 @@ void SILGenFunction::emitFunction(FuncDecl *fd) { void SILGenFunction::emitClosure(AbstractClosureExpr *ace) { MagicFunctionName = SILGenModule::getMagicFunctionName(ace); - emitProlog(ace, ace->getParams(), ace->getResultType()); + emitProlog(ace, ace->getParameters(), ace->getResultType()); prepareEpilog(ace->getResultType(), ace->isBodyThrowing(), CleanupLocation(ace)); if (auto *ce = dyn_cast(ace)) { @@ -578,8 +614,6 @@ static void forwardCaptureArgs(SILGenFunction &gen, SILType boxTy = SILType::getPrimitiveObjectType( SILBoxType::get(ty.getSwiftRValueType())); addSILArgument(boxTy, vd); - // Forward the captured value address. - addSILArgument(ty, vd); break; } @@ -599,23 +633,16 @@ static SILValue getNextUncurryLevelRef(SILGenFunction &gen, bool direct, ArrayRef curriedArgs, ArrayRef curriedSubs) { - // For a foreign function, reference the native thunk. - if (next.isForeign) + if (next.isForeign || next.isCurried || !next.hasDecl() || direct) return gen.emitGlobalFunctionRef(loc, next.asForeign(false)); - // If the fully-uncurried reference is to a native dynamic class method, emit - // the dynamic dispatch. - auto fullyAppliedMethod = !next.isCurried && !next.isForeign && !direct && - next.hasDecl(); - auto constantInfo = gen.SGM.Types.getConstantInfo(next); SILValue thisArg; if (!curriedArgs.empty()) thisArg = curriedArgs.back(); - if (fullyAppliedMethod && - isa(next.getDecl()) && - gen.getMethodDispatch(cast(next.getDecl())) + if (isa(next.getDecl()) && + getMethodDispatch(cast(next.getDecl())) == MethodDispatch::Class) { SILValue thisArg = curriedArgs.back(); @@ -630,8 +657,7 @@ static SILValue getNextUncurryLevelRef(SILGenFunction &gen, // If the fully-uncurried reference is to a generic method, look up the // witness. - if (fullyAppliedMethod && - constantInfo.SILFnType->getRepresentation() + if (constantInfo.SILFnType->getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod) { auto thisType = curriedSubs[0].getReplacement()->getCanonicalType(); assert(isa(thisType) && "no archetype for witness?!"); @@ -672,7 +698,7 @@ void SILGenFunction::emitCurryThunk(ValueDecl *vd, --paramCount; // Forward the curried formal arguments. - auto forwardedPatterns = fd->getBodyParamPatterns().slice(0, paramCount); + auto forwardedPatterns = fd->getParameterLists().slice(0, paramCount); for (auto *paramPattern : reversed(forwardedPatterns)) bindParametersForForwarding(paramPattern, curriedArgs); @@ -725,7 +751,7 @@ void SILGenFunction::emitGeneratorFunction(SILDeclRef function, Expr *value) { Loc.markAutoGenerated(); // Override location for __FILE__ __LINE__ etc. to an invalid one so that we - // don't put extra strings into the defaut argument generator function that + // don't put extra strings into the default argument generator function that // is not going to be ever used anyway. overrideLocationForMagicIdentifiers = SourceLoc(); diff --git a/lib/SILGen/SILGenFunction.h b/lib/SILGen/SILGenFunction.h index 24335a9445ffe..95df149223ca6 100644 --- a/lib/SILGen/SILGenFunction.h +++ b/lib/SILGen/SILGenFunction.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,6 +20,7 @@ #include "swift/SIL/SILBuilder.h" namespace swift { + class ParameterList; namespace Lowering { class ArgumentSource; @@ -31,21 +32,13 @@ class LValue; class ManagedValue; class RValue; class TemporaryInitialization; - -/// How a method is dispatched. -enum class MethodDispatch { - // The method implementation can be referenced statically. - Static, - // The method implementation uses class_method dispatch. - Class, -}; /// Internal context information for the SILGenFunction visitor. /// /// In general, emission methods which take an SGFContext indicate /// that they've initialized the emit-into buffer (if they have) by /// returning a "isInContext()" ManagedValue of whatever type. Callers who -/// propagate down an SGFContext that might have a emit-into buffer must be +/// propagate down an SGFContext that might have an emit-into buffer must be /// aware of this. /// /// Clients of emission routines that take an SGFContext can also specify that @@ -209,7 +202,7 @@ class SILGenBuilder : public SILBuilder { MetatypeInst *createMetatype(SILLocation Loc, SILType Metatype); - // Generic pply instructions use the conformances necessary to form the call. + // Generic apply instructions use the conformances necessary to form the call. using SILBuilder::createApply; @@ -265,6 +258,16 @@ class SILGenBuilder : public SILBuilder { ArrayRef Conformances); }; +/// Parameter to \c SILGenFunction::emitCaptures that indicates what the +/// capture parameters are being emitted for. +enum class CaptureEmission { + /// Captures are being emitted for immediate application to a local function. + ImmediateApplication, + /// Captures are being emitted for partial application to form a closure + /// value. + PartialApplication, +}; + /// SILGenFunction - an ASTVisitor for producing SIL from function bodies. class LLVM_LIBRARY_VISIBILITY SILGenFunction : public ASTVisitor @@ -677,15 +680,15 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction /// emitProlog - Generates prolog code to allocate and clean up mutable /// storage for closure captures and local arguments. - void emitProlog(AnyFunctionRef TheClosure, ArrayRef paramPatterns, - Type resultType); + void emitProlog(AnyFunctionRef TheClosure, + ArrayRef paramPatterns, Type resultType); /// returns the number of variables in paramPatterns. - unsigned emitProlog(ArrayRef paramPatterns, + unsigned emitProlog(ArrayRef paramPatterns, Type resultType, DeclContext *DeclCtx); /// Create SILArguments in the entry block that bind all the values /// of the given pattern suitably for being forwarded. - void bindParametersForForwarding(Pattern *paramPattern, + void bindParametersForForwarding(const ParameterList *params, SmallVectorImpl ¶meters); /// \brief Create (but do not emit) the epilog branch, and save the @@ -695,7 +698,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction /// argument of this type to receive the return value for /// the function. /// \param isThrowing If true, create an error epilog block. - /// \param L The SILLocation which should be accosocated with + /// \param L The SILLocation which should be associated with /// cleanup instructions. void prepareEpilog(Type returnType, bool isThrowing, CleanupLocation L); void prepareRethrowEpilog(CleanupLocation l); @@ -710,7 +713,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction /// \returns None if the epilog block is unreachable. Otherwise, returns /// the epilog block's return value argument, or a null SILValue if /// the epilog doesn't take a return value. Also returns the location - /// of the return instrcution if the epilog block is supposed to host + /// of the return instruction if the epilog block is supposed to host /// the ReturnLocation (This happens in case the predecessor block is /// merged with the epilog block.) std::pair, SILLocation> @@ -762,6 +765,12 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction // Type conversions for expr emission and thunks //===--------------------------------------------------------------------===// + ManagedValue emitInjectEnum(SILLocation loc, + ArgumentSource payload, + SILType enumTy, + EnumElementDecl *element, + SGFContext C); + ManagedValue emitInjectOptional(SILLocation loc, ManagedValue v, CanType inputFormalType, @@ -804,7 +813,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction /// The result is a Builtin.Int1. SILValue emitDoesOptionalHaveValue(SILLocation loc, SILValue addrOrValue); - /// \brief Emit a call to the library intrinsic _preconditionOptionalHasValue. + /// \brief Emit a switch_enum to call the library intrinsic + /// _diagnoseUnexpectedNilOptional if the optional has no value. void emitPreconditionOptionalHasValue(SILLocation loc, SILValue addr); /// \brief Emit a call to the library intrinsic _getOptionalValue @@ -1002,7 +1012,6 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction /// Returns a reference to a constant in local context. This will return a /// retained closure object reference if the constant refers to a local func /// decl. - ManagedValue emitFunctionRef(SILLocation loc, SILDeclRef constant); ManagedValue emitFunctionRef(SILLocation loc, SILDeclRef constant, SILConstantInfo constantInfo); @@ -1015,7 +1024,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction = AccessSemantics::Ordinary); /// Produce a singular RValue for a reference to the specified declaration, - /// with the given type and in response to the specified epxression. Try to + /// with the given type and in response to the specified expression. Try to /// emit into the specified SGFContext to avoid copies (when provided). ManagedValue emitRValueForDecl(SILLocation loc, ConcreteDeclRef decl, Type ty, AccessSemantics semantics, @@ -1033,6 +1042,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction void emitCaptures(SILLocation loc, AnyFunctionRef TheClosure, + CaptureEmission purpose, SmallVectorImpl &captures); ManagedValue emitClosureValue(SILLocation loc, @@ -1534,9 +1544,6 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction /// intrinsic. Substitution getPointerSubstitution(Type pointerType, ArchetypeType *archetype); - - /// Get the method dispatch mechanism for a method. - MethodDispatch getMethodDispatch(AbstractFunctionDecl *method); }; diff --git a/lib/SILGen/SILGenGlobalVariable.cpp b/lib/SILGen/SILGenGlobalVariable.cpp index 6dd1d1a624d68..8fe099490c90c 100644 --- a/lib/SILGen/SILGenGlobalVariable.cpp +++ b/lib/SILGen/SILGenGlobalVariable.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,10 +25,11 @@ using namespace Lowering; SILGlobalVariable *SILGenModule::getSILGlobalVariable(VarDecl *gDecl, ForDefinition_t forDef) { // First, get a mangled name for the declaration. - llvm::SmallString<32> mangledName; { - llvm::raw_svector_ostream buffer(mangledName); - Mangler mangler(buffer); + std::string mangledName; + { + Mangler mangler; mangler.mangleGlobalVariableFull(gDecl); + mangledName = mangler.finalize(); } // Check if it is already created, and update linkage if necessary. @@ -210,10 +211,11 @@ void SILGenModule::emitGlobalInitialization(PatternBindingDecl *pd, }); assert(varDecl); - llvm::SmallString<20> onceTokenBuffer; { - llvm::raw_svector_ostream onceTokenStream(onceTokenBuffer); - Mangler tokenMangler(onceTokenStream); + std::string onceTokenBuffer; + { + Mangler tokenMangler; tokenMangler.mangleGlobalInit(varDecl, counter, false); + onceTokenBuffer = tokenMangler.finalize(); } auto onceTy = BuiltinIntegerType::getWordType(M.getASTContext()); @@ -228,12 +230,14 @@ void SILGenModule::emitGlobalInitialization(PatternBindingDecl *pd, onceToken->setDeclaration(false); // Emit the initialization code into a function. - llvm::SmallString<20> onceFuncBuffer; - llvm::raw_svector_ostream onceFuncStream(onceFuncBuffer); - Mangler funcMangler(onceFuncStream); - funcMangler.mangleGlobalInit(varDecl, counter, true); + std::string onceFuncBuffer; + { + Mangler funcMangler; + funcMangler.mangleGlobalInit(varDecl, counter, true); + onceFuncBuffer = funcMangler.finalize(); + } - SILFunction *onceFunc = emitLazyGlobalInitializer(onceFuncStream.str(), pd, + SILFunction *onceFunc = emitLazyGlobalInitializer(onceFuncBuffer, pd, pbdEntry); // Generate accessor functions for all of the declared variables, which diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp index c943a15df66ef..8fb73ce07766e 100644 --- a/lib/SILGen/SILGenLValue.cpp +++ b/lib/SILGen/SILGenLValue.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -562,7 +562,7 @@ namespace { static bool isReadNoneFunction(const Expr *e) { // If this is a curried call to an integer literal conversion operations, then // we can "safely" assume it is readnone (btw, yes this is totally gross). - // This is better to be attribute driven, ala rdar://15587352. + // This is better to be attribute driven, a la rdar://15587352. if (auto *dre = dyn_cast(e)) { DeclName name = dre->getDecl()->getFullName(); return (name.getArgumentNames().size() == 1 && @@ -724,7 +724,7 @@ namespace { AccessKind kind) const override { SILDeclRef accessor = getAccessor(gen, kind); auto accessorType = gen.SGM.Types.getConstantFunctionType(accessor); - if (accessorType->getSelfParameter().isIndirectInOut()) { + if (accessorType->getSelfParameter().isIndirectMutating()) { return AccessKind::ReadWrite; } else { return AccessKind::Read; @@ -1415,7 +1415,7 @@ void LValue::addOrigToSubstComponent(SILType loweredSubstType) { assert(getTypeOfRValue() != loweredSubstType && "reabstraction component is unnecessary!"); - // Peephole away complementary reabstractons. + // Peephole away complementary reabstractions. assert(!Path.empty() && "adding translation component to empty l-value"); if (Path.back()->getKind() == PathComponent::SubstToOrigKind) { // But only if the lowered type matches exactly. @@ -1437,7 +1437,7 @@ void LValue::addSubstToOrigComponent(AbstractionPattern origType, assert(getTypeOfRValue() != loweredSubstType && "reabstraction component is unnecessary!"); - // Peephole away complementary reabstractons. + // Peephole away complementary reabstractions. assert(!Path.empty() && "adding translation component to empty l-value"); if (Path.back()->getKind() == PathComponent::OrigToSubstKind) { // But only if the lowered type matches exactly. @@ -1529,8 +1529,7 @@ static ArrayRef getNonMemberVarDeclSubstitutions(SILGenFunction &gen, VarDecl *var) { ArrayRef substitutions; if (auto genericParams - = gen.SGM.Types.getEffectiveGenericParamsForContext( - var->getDeclContext())) + = var->getDeclContext()->getGenericParamsOfContext()) substitutions = genericParams->getForwardingSubstitutions(gen.getASTContext()); return substitutions; @@ -2073,6 +2072,9 @@ SILValue SILGenFunction::emitConversionToSemanticRValue(SILLocation loc, // For @unowned(safe) types, we need to generate a strong retain and // strip the unowned box. if (auto unownedType = src.getType().getAs()) { + assert(unownedType->isLoadable(ResilienceExpansion::Maximal)); + (void) unownedType; + B.createStrongRetainUnowned(loc, src); return B.createUnownedToRef(loc, src, SILType::getPrimitiveObjectType(unownedType.getReferentType())); @@ -2107,6 +2109,10 @@ static SILValue emitLoadOfSemanticRValue(SILGenFunction &gen, // For @unowned(safe) types, we need to strip the unowned box. if (auto unownedType = storageType.getAs()) { + if (!unownedType->isLoadable(ResilienceExpansion::Maximal)) { + return gen.B.createLoadUnowned(loc, src, isTake); + } + auto unownedValue = gen.B.createLoad(loc, src); gen.B.createStrongRetainUnowned(loc, unownedValue); if (isTake) gen.B.createUnownedRelease(loc, unownedValue); @@ -2159,7 +2165,16 @@ static void emitStoreOfSemanticRValue(SILGenFunction &gen, // For @unowned(safe) types, we need to enter the unowned box by // turning the strong retain into an unowned retain. - if (storageType.is()) { + if (auto unownedType = storageType.getAs()) { + // FIXME: resilience + if (!unownedType->isLoadable(ResilienceExpansion::Maximal)) { + gen.B.createStoreUnowned(loc, value, dest, isInit); + + // store_unowned doesn't take ownership of the input, so cancel it out. + gen.B.emitStrongReleaseAndFold(loc, value); + return; + } + auto unownedValue = gen.B.createRefToUnowned(loc, value, storageType.getObjectType()); gen.B.createUnownedRetain(loc, unownedValue); @@ -2258,7 +2273,10 @@ SILValue SILGenFunction::emitConversionFromSemanticValue(SILLocation loc, // @weak types are never loadable, so we don't need to handle them here. // For @unowned types, place into an unowned box. - if (storageType.is()) { + if (auto unownedType = storageType.getAs()) { + assert(unownedType->isLoadable(ResilienceExpansion::Maximal)); + (void) unownedType; + SILValue unowned = B.createRefToUnowned(loc, semanticValue, storageType); B.createUnownedRetain(loc, unowned); B.emitStrongReleaseAndFold(loc, semanticValue); @@ -2855,7 +2873,7 @@ SILFunction *MaterializeForSetEmitter::createCallback(GeneratorFn generator) { // Mangle this as if it were a conformance thunk for a closure // within the witness. - llvm::SmallString<128> name; + std::string name; { ClosureExpr closure(/*patterns*/ nullptr, /*throws*/ SourceLoc(), @@ -2869,11 +2887,11 @@ SILFunction *MaterializeForSetEmitter::createCallback(GeneratorFn generator) { nullptr)); closure.getCaptureInfo().setGenericParamCaptures(true); - llvm::raw_svector_ostream nameStream(name); - nameStream << "_TTW"; - Mangle::Mangler mangler(nameStream); + Mangle::Mangler mangler; + mangler.append("_TTW"); mangler.mangleProtocolConformance(Conformance); mangler.mangleClosureEntity(&closure, ResilienceExpansion::Minimal, 1); + name = mangler.finalize(); } // Create the SILFunctionType for the callback. diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp index a66f110681e15..88eb67b0fe0b5 100644 --- a/lib/SILGen/SILGenPattern.cpp +++ b/lib/SILGen/SILGenPattern.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,6 +20,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FormattedStream.h" +#include "swift/AST/ASTWalker.h" #include "swift/AST/DiagnosticsSIL.h" #include "swift/AST/Pattern.h" #include "swift/AST/SILOptions.h" @@ -50,7 +51,7 @@ static void dumpPattern(const Pattern *p, llvm::raw_ostream &os) { os << ""; return; case PatternKind::Named: - os << "var " << cast(p)->getBodyName(); + os << "var " << cast(p)->getBoundName(); return; case PatternKind::Tuple: { unsigned numFields = cast(p)->getNumElements(); @@ -1124,7 +1125,7 @@ void PatternMatchEmission::bindIrrefutablePatterns(const ClauseRow &row, void PatternMatchEmission::bindIrrefutablePattern(Pattern *pattern, ConsumableManagedValue value, bool forIrrefutableRow) { - // We use null patterns to mean artifical AnyPatterns. + // We use null patterns to mean artificial AnyPatterns. if (!pattern) return; pattern = pattern->getSemanticsProvidingPattern(); @@ -1296,7 +1297,7 @@ void PatternMatchEmission::emitSpecializedDispatch(ClauseMatrix &clauses, ArrayRef rows, const FailureHandler &innerFailure) { // These two operations must follow the same rules for column - // placement because 'arguments' are parallel to the matrix colums. + // placement because 'arguments' are parallel to the matrix columns. // We use the column-specialization algorithm described in // specializeInPlace. ClauseMatrix innerClauses = clauses.specializeRowsInPlace(column, rows); @@ -1466,7 +1467,7 @@ emitNominalTypeDispatch(ArrayRef rows, CanType baseFormalType = aggMV.getType().getSwiftRValueType(); auto val = SGF.emitRValueForPropertyLoad(loc, aggMV, baseFormalType, false, property, - // FIXME: No generic substitions. + // FIXME: No generic substitutions. {}, AccessSemantics::Ordinary, firstMatcher->getType(), // TODO: Avoid copies on @@ -2049,7 +2050,7 @@ void PatternMatchEmission::emitSharedCaseBlocks() { // blocks might fallthrough into this one. if (!hasFallthroughTo && caseBlock->getCaseLabelItems().size() == 1) { SILBasicBlock *predBB = caseBB->getSinglePredecessor(); - assert(predBB && "Should only have 1 predecesor because it isn't shared"); + assert(predBB && "Should only have 1 predecessor because it isn't shared"); assert(isa(predBB->getTerminator()) && "Should have uncond branch to shared block"); predBB->getTerminator()->eraseFromParent(); diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index a25e568ebd47b..e3444f1fa4109 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -49,7 +49,7 @@ // parameter of the base with a concrete type, the derived class can override // methods in the base that involved generic types. In the derived class, a // method override that involves substituted types will have a different -// SIL lowering than the base method. In this case, the overriden vtable entry +// SIL lowering than the base method. In this case, the overridden vtable entry // will point to a thunk which transforms parameters and results and invokes // the derived method. // @@ -640,6 +640,7 @@ static ManagedValue manageParam(SILGenFunction &gen, return gen.emitManagedBufferWithCleanup(copy); } case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: return ManagedValue::forLValue(paramValue); case ParameterConvention::Indirect_In: return gen.emitManagedBufferWithCleanup(paramValue); @@ -1124,6 +1125,10 @@ namespace { Outputs.push_back(temp->getManagedAddress()); return; } + case ParameterConvention::Indirect_InoutAliasable: { + llvm_unreachable("abstraction difference in aliasable argument not " + "allowed"); + } } llvm_unreachable("Covered switch isn't covered?!"); @@ -1237,10 +1242,7 @@ static SILValue getThunkResult(SILGenFunction &gen, if (!fTy->hasIndirectResult()) { switch (fTy->getResult().getConvention()) { case ResultConvention::Owned: - break; case ResultConvention::Autoreleased: - innerResultValue = - gen.B.createStrongRetainAutoreleased(loc, innerResultValue); break; case ResultConvention::UnownedInnerPointer: // FIXME: We can't reasonably lifetime-extend an inner-pointer result @@ -1308,7 +1310,7 @@ static SILValue getThunkResult(SILGenFunction &gen, /// \param inputOrigType Abstraction pattern of function value being thunked /// \param inputSubstType Formal AST type of function value being thunked /// \param outputOrigType Abstraction pattern of the thunk -/// \param outputSubstType Formal AST type of the thuk +/// \param outputSubstType Formal AST type of the thunk static void buildThunkBody(SILGenFunction &gen, SILLocation loc, AbstractionPattern inputOrigType, CanAnyFunctionType inputSubstType, diff --git a/lib/SILGen/SILGenProfiling.cpp b/lib/SILGen/SILGenProfiling.cpp index 5e84602be92d5..8c8bdde7f7d18 100644 --- a/lib/SILGen/SILGenProfiling.cpp +++ b/lib/SILGen/SILGenProfiling.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -604,9 +604,7 @@ static void walkForProfiling(AbstractFunctionDecl *Root, ASTWalker &Walker) { } void SILGenProfiling::assignRegionCounters(AbstractFunctionDecl *Root) { - SmallString<128> NameBuffer; - SILDeclRef(Root).mangle(NameBuffer); - CurrentFuncName = NameBuffer.str(); + CurrentFuncName = SILDeclRef(Root).mangle(); MapRegionCounters Mapper(RegionCounterMap); walkForProfiling(Root, Mapper); diff --git a/lib/SILGen/SILGenProfiling.h b/lib/SILGen/SILGenProfiling.h index 779f0d7538b84..417a6200934d4 100644 --- a/lib/SILGen/SILGenProfiling.h +++ b/lib/SILGen/SILGenProfiling.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp index bb857af1beb6a..9eced888e5a3e 100644 --- a/lib/SILGen/SILGenProlog.cpp +++ b/lib/SILGen/SILGenProlog.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,6 +15,7 @@ #include "ManagedValue.h" #include "Scope.h" #include "swift/SIL/SILArgument.h" +#include "swift/AST/ParameterList.h" #include "swift/Basic/Fallthrough.h" using namespace swift; @@ -28,13 +29,13 @@ SILValue SILGenFunction::emitSelfDecl(VarDecl *selfDecl) { SILLocation PrologueLoc(selfDecl); PrologueLoc.markAsPrologue(); unsigned ArgNo = 1; // Hardcoded for destructors. - B.createDebugValue(PrologueLoc, selfValue, ArgNo); + B.createDebugValue(PrologueLoc, selfValue, {selfDecl->isLet(), ArgNo}); return selfValue; } namespace { -/// Cleanup that writes back to a inout argument on function exit. +/// Cleanup that writes back to an inout argument on function exit. class CleanupWriteBackToInOut : public Cleanup { VarDecl *var; SILValue inoutAddr; @@ -51,7 +52,10 @@ class CleanupWriteBackToInOut : public Cleanup { IsNotTake, IsNotInitialization); } }; +} // end anonymous namespace + +namespace { class StrongReleaseCleanup : public Cleanup { SILValue box; public: @@ -60,7 +64,10 @@ class StrongReleaseCleanup : public Cleanup { gen.B.emitStrongReleaseAndFold(l, box); } }; +} // end anonymous namespace + +namespace { class EmitBBArguments : public CanTypeVisitor { @@ -96,9 +103,10 @@ class EmitBBArguments : public CanTypeVisitor -{ + +namespace { + +/// A helper for creating SILArguments and binding variables to the argument +/// names. +struct ArgumentInitHelper { SILGenFunction &gen; SILFunction &f; SILGenBuilder &initB; @@ -213,7 +223,7 @@ struct ArgumentInitVisitor : ArrayRef parameters; unsigned ArgNo = 0; - ArgumentInitVisitor(SILGenFunction &gen, SILFunction &f) + ArgumentInitHelper(SILGenFunction &gen, SILFunction &f) : gen(gen), f(f), initB(gen.B), parameters(f.getLoweredFunctionType()->getParameters()) { // If we have an out parameter, skip it. @@ -228,7 +238,6 @@ struct ArgumentInitVisitor : // Create an RValue by emitting destructured arguments into a basic block. CanType canTy = ty->getCanonicalType(); - return EmitBBArguments(gen, parent, l, /*functionArgs*/ true, parameters).visit(canTy); } @@ -255,7 +264,7 @@ struct ArgumentInitVisitor : if (isa(objectType)) { // FIXME: mark a debug location? gen.VarLocs[vd] = SILGenFunction::VarLoc::get(address); - gen.B.createDebugValueAddr(loc, address, ArgNo); + gen.B.createDebugValueAddr(loc, address, {vd->isLet(), ArgNo}); return; } @@ -277,9 +286,9 @@ struct ArgumentInitVisitor : // argument if we're responsible for it. gen.VarLocs[vd] = SILGenFunction::VarLoc::get(argrv.getValue()); if (argrv.getType().isAddress()) - gen.B.createDebugValueAddr(loc, argrv.getValue(), ArgNo); + gen.B.createDebugValueAddr(loc, argrv.getValue(), {vd->isLet(), ArgNo}); else - gen.B.createDebugValue(loc, argrv.getValue(), ArgNo); + gen.B.createDebugValue(loc, argrv.getValue(), {vd->isLet(), ArgNo}); } else { // If the variable is mutable, we need to copy or move the argument // value to local mutable memory. @@ -294,142 +303,54 @@ struct ArgumentInitVisitor : argrv.copyInto(gen, initVar->getAddress(), loc); initVar->finishInitialization(gen); - } } - // Paren, Typed, and Var patterns are no-ops. Just look through them. - void visitParenPattern(ParenPattern *P) { - visit(P->getSubPattern()); - } - void visitTypedPattern(TypedPattern *P) { - visit(P->getSubPattern()); - } - void visitVarPattern(VarPattern *P) { - visit(P->getSubPattern()); - } - - void visitTuplePattern(TuplePattern *P) { - // Destructure tuples into their elements. - for (size_t i = 0, size = P->getNumElements(); i < size; ++i) - visit(P->getElement(i).getPattern()); - } - - void visitAnyPattern(AnyPattern *P) { - llvm_unreachable("unnamed parameters should have a ParamDecl"); - } - - void visitNamedPattern(NamedPattern *P) { + void emitParam(ParamDecl *PD) { ++ArgNo; - auto PD = P->getDecl(); - if (!PD->hasName()) { - // A value bound to _ is unused and can be immediately released. - Scope discardScope(gen.Cleanups, CleanupLocation(P)); - makeArgument(P->getType(), &*f.begin(), PD); - // Popping the scope destroys the value. - } else { - makeArgumentIntoBinding(P->getType(), &*f.begin(), PD); - } - } - -#define PATTERN(Id, Parent) -#define REFUTABLE_PATTERN(Id, Parent) \ - void visit##Id##Pattern(Id##Pattern *) { \ - llvm_unreachable("pattern not valid in argument binding"); \ - } -#include "swift/AST/PatternNodes.def" -}; - -// Unlike the ArgumentInitVisitor, this visitor generates arguments but leaves -// them destructured instead of storing them to lvalues so that the -// argument set can be easily forwarded to another function. -class ArgumentForwardVisitor - : public PatternVisitor -{ - SILGenFunction &gen; - SmallVectorImpl &args; -public: - ArgumentForwardVisitor(SILGenFunction &gen, - SmallVectorImpl &args) - : gen(gen), args(args) {} - - void makeArgument(Type ty, VarDecl *varDecl) { - assert(ty && "no type?!"); - // Destructure tuple arguments. - if (TupleType *tupleTy = ty->getAs()) { - for (auto fieldType : tupleTy->getElementTypes()) - makeArgument(fieldType, varDecl); - } else { - SILValue arg = - new (gen.F.getModule()) SILArgument(gen.F.begin(), - gen.getLoweredType(ty), - varDecl); - args.push_back(arg); + if (PD->hasName()) { + makeArgumentIntoBinding(PD->getType(), &*f.begin(), PD); + return; } - } - - void visitParenPattern(ParenPattern *P) { - visit(P->getSubPattern()); - } - void visitVarPattern(VarPattern *P) { - visit(P->getSubPattern()); - } - - void visitTypedPattern(TypedPattern *P) { - // FIXME: work around a bug in visiting the "self" argument of methods - if (auto NP = dyn_cast(P->getSubPattern())) - makeArgument(P->getType(), NP->getDecl()); + + ManagedValue argrv = makeArgument(PD->getType(), &*f.begin(), PD); + // Emit debug information for the argument. + SILLocation loc(PD); + loc.markAsPrologue(); + if (argrv.getType().isAddress()) + gen.B.createDebugValueAddr(loc, argrv.getValue(), {PD->isLet(), ArgNo}); else - visit(P->getSubPattern()); - } - - void visitTuplePattern(TuplePattern *P) { - for (auto &elt : P->getElements()) - visit(elt.getPattern()); - } + gen.B.createDebugValue(loc, argrv.getValue(), {PD->isLet(), ArgNo}); - void visitAnyPattern(AnyPattern *P) { - llvm_unreachable("unnamed parameters should have a ParamDecl"); + // A value bound to _ is unused and can be immediately released. + Scope discardScope(gen.Cleanups, CleanupLocation(PD)); + // Popping the scope destroys the value. } - - void visitNamedPattern(NamedPattern *P) { - makeArgument(P->getType(), P->getDecl()); - } - -#define PATTERN(Id, Parent) -#define REFUTABLE_PATTERN(Id, Parent) \ - void visit##Id##Pattern(Id##Pattern *) { \ - llvm_unreachable("pattern not valid in argument binding"); \ - } -#include "swift/AST/PatternNodes.def" }; - } // end anonymous namespace -void SILGenFunction::bindParametersForForwarding(Pattern *pattern, - SmallVectorImpl ¶meters) { - ArgumentForwardVisitor(*this, parameters).visit(pattern); + +static void makeArgument(Type ty, ParamDecl *decl, + SmallVectorImpl &args, SILGenFunction &gen) { + assert(ty && "no type?!"); + + // Destructure tuple arguments. + if (TupleType *tupleTy = ty->getAs()) { + for (auto fieldType : tupleTy->getElementTypes()) + makeArgument(fieldType, decl, args, gen); + } else { + auto arg = new (gen.F.getModule()) SILArgument(gen.F.begin(), + gen.getLoweredType(ty),decl); + args.push_back(arg); + } } -/// Tuple values captured by a closure are passed as individual arguments to the -/// SILFunction since SILFunctionType canonicalizes away tuple types. -static SILValue -emitReconstitutedConstantCaptureArguments(SILType ty, - ValueDecl *capture, - SILGenFunction &gen) { - auto TT = ty.getAs(); - if (!TT) - return new (gen.SGM.M) SILArgument(gen.F.begin(), ty, capture); - - SmallVector Elts; - for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) { - auto EltTy = ty.getTupleElementType(i); - auto EV = - emitReconstitutedConstantCaptureArguments(EltTy, capture, gen); - Elts.push_back(EV); - } - return gen.B.createTuple(capture, ty, Elts); +void SILGenFunction::bindParametersForForwarding(const ParameterList *params, + SmallVectorImpl ¶meters) { + for (auto param : *params) { + makeArgument(param->getType(), param, parameters, *this); + } } static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture, @@ -444,10 +365,9 @@ static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture, case CaptureKind::Constant: { auto &lowering = gen.getTypeLowering(VD->getType()); - // Constant decls are captured by value. If the captured value is a tuple - // value, we need to reconstitute it before sticking it in VarLocs. + // Constant decls are captured by value. SILType ty = lowering.getLoweredType(); - SILValue val = emitReconstitutedConstantCaptureArguments(ty, VD, gen); + SILValue val = new (gen.SGM.M) SILArgument(gen.F.begin(), ty, VD); // If the original variable was settable, then Sema will have treated the // VarDecl as an lvalue, even in the closure's use. As such, we need to @@ -463,23 +383,27 @@ static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture, if (auto *AllocStack = dyn_cast(val)) AllocStack->setArgNo(ArgNo); else - gen.B.createDebugValue(Loc, val, ArgNo); - if (!lowering.isTrivial()) + gen.B.createDebugValue(Loc, val, {/*Constant*/true, ArgNo}); + + // TODO: Closure contexts should always be guaranteed. + if (!gen.SGM.M.getOptions().EnableGuaranteedClosureContexts + && !lowering.isTrivial()) gen.enterDestroyCleanup(val); break; } case CaptureKind::Box: { - // LValues are captured as two arguments: a retained NativeObject that owns - // the captured value, and the address of the value itself. + // LValues are captured as a retained @box that owns + // the captured value. SILType ty = gen.getLoweredType(type).getAddressType(); SILType boxTy = SILType::getPrimitiveObjectType( SILBoxType::get(ty.getSwiftRValueType())); SILValue box = new (gen.SGM.M) SILArgument(gen.F.begin(), boxTy, VD); - SILValue addr = new (gen.SGM.M) SILArgument(gen.F.begin(), ty, VD); + SILValue addr = gen.B.createProjectBox(VD, box); gen.VarLocs[VD] = SILGenFunction::VarLoc::get(addr, box); - gen.B.createDebugValueAddr(Loc, addr, ArgNo); - gen.Cleanups.pushCleanup(box); + gen.B.createDebugValueAddr(Loc, addr, {/*Constant*/false, ArgNo}); + if (!gen.SGM.M.getOptions().EnableGuaranteedClosureContexts) + gen.Cleanups.pushCleanup(box); break; } case CaptureKind::StorageAddress: { @@ -487,14 +411,14 @@ static void emitCaptureArguments(SILGenFunction &gen, CapturedValue capture, SILType ty = gen.getLoweredType(type).getAddressType(); SILValue addr = new (gen.SGM.M) SILArgument(gen.F.begin(), ty, VD); gen.VarLocs[VD] = SILGenFunction::VarLoc::get(addr); - gen.B.createDebugValueAddr(Loc, addr, ArgNo); + gen.B.createDebugValueAddr(Loc, addr, {/*Constant*/true, ArgNo}); break; } } } void SILGenFunction::emitProlog(AnyFunctionRef TheClosure, - ArrayRef paramPatterns, + ArrayRef paramPatterns, Type resultType) { unsigned ArgNo = emitProlog(paramPatterns, resultType, TheClosure.getAsDeclContext()); @@ -506,7 +430,7 @@ void SILGenFunction::emitProlog(AnyFunctionRef TheClosure, emitCaptureArguments(*this, capture, ++ArgNo); } -unsigned SILGenFunction::emitProlog(ArrayRef paramPatterns, +unsigned SILGenFunction::emitProlog(ArrayRef paramLists, Type resultType, DeclContext *DeclCtx) { // If the return type is address-only, emit the indirect return argument. const TypeLowering &returnTI = getTypeLowering(resultType); @@ -521,12 +445,14 @@ unsigned SILGenFunction::emitProlog(ArrayRef paramPatterns, } // Emit the argument variables in calling convention order. - ArgumentInitVisitor argVisitor(*this, F); - for (Pattern *p : reversed(paramPatterns)) { + ArgumentInitHelper emitter(*this, F); + + for (ParameterList *paramList : reversed(paramLists)) { // Add the SILArguments and use them to initialize the local argument // values. - argVisitor.visit(p); + for (auto ¶m : *paramList) + emitter.emitParam(param); } - return argVisitor.getNumArgs(); + return emitter.getNumArgs(); } diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp index bfbb04575a3a3..37f8150e7497f 100644 --- a/lib/SILGen/SILGenStmt.cpp +++ b/lib/SILGen/SILGenStmt.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -511,7 +511,7 @@ void StmtEmitter::visitDoCatchStmt(DoCatchStmt *S) { SILArgument *exnArg = throwDest.getBlock()->createBBArg(exnTL.getLoweredType()); - // We always need an continuation block because we might fall out of + // We always need a continuation block because we might fall out of // a catch block. But we don't need a loop block unless the 'do' // statement is labeled. JumpDest endDest = createJumpDest(S->getBody()); diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp index 63ee16cf7cb00..ef99752f88765 100644 --- a/lib/SILGen/SILGenType.cpp +++ b/lib/SILGen/SILGenType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -33,8 +33,7 @@ using namespace Lowering; SILFunction *SILGenModule::getDynamicThunk(SILDeclRef constant, SILConstantInfo constantInfo) { // Mangle the constant with a _TTD header. - llvm::SmallString<32> name; - constant.mangle(name, "_TTD"); + auto name = constant.mangle("_TTD"); auto F = M.getOrCreateFunction(constant.getDecl(), name, SILLinkage::Shared, constantInfo.getSILType().castTo(), @@ -63,8 +62,7 @@ SILGenModule::emitVTableMethod(SILDeclRef derived, SILDeclRef base) { // TODO: If we allocated a new vtable slot for the derived method, then // further derived methods would potentially need multiple thunks, and we // would need to mangle the base method into the symbol as well. - llvm::SmallString<32> name; - derived.mangle(name, "_TTV"); + auto name = derived.mangle("_TTV"); // If we already emitted this thunk, reuse it. // TODO: Allocating new vtable slots for derived methods with different ABIs @@ -88,10 +86,10 @@ SILGenModule::emitVTableMethod(SILDeclRef derived, SILDeclRef base) { auto *derivedDecl = cast(derived.getDecl()); SILLocation loc(derivedDecl); - auto thunk = SILFunction::create(M, SILLinkage::Private, name, - overrideInfo.SILFnType, - derivedDecl->getGenericParams(), - loc, IsBare, IsNotTransparent, IsNotFragile); + auto thunk = + M.getOrCreateFunction(SILLinkage::Private, name, overrideInfo.SILFnType, + derivedDecl->getGenericParams(), loc, IsBare, + IsNotTransparent, IsNotFragile); thunk->setDebugScope(new (M) SILDebugScope(loc, *thunk)); SILGenFunction(*this, *thunk) @@ -136,47 +134,6 @@ bool SILGenModule::requiresObjCMethodEntryPoint(ConstructorDecl *constructor) { return constructor->isObjC(); } -bool SILGenModule::requiresObjCDispatch(ValueDecl *vd) { - // Final functions never require ObjC dispatch. - if (vd->isFinal()) - return false; - - // If the decl is an @objc protocol requirement, then the only witness is - // objc. - if (auto *proto = dyn_cast(vd->getDeclContext())) - if (proto->isObjC()) - return true; - - if (auto *fd = dyn_cast(vd)) { - // If a function has an associated Clang node, it's foreign and only has - // an ObjC entry point. - if (vd->hasClangNode()) - return true; - - // Property accessors should be generated alongside the property. - if (fd->isGetterOrSetter()) - return requiresObjCDispatch(fd->getAccessorStorageDecl()); - - return fd->getAttrs().hasAttribute(); - } - if (auto *cd = dyn_cast(vd)) { - // If a function has an associated Clang node, it's foreign and only has - // an ObjC entry point. - if (vd->hasClangNode()) - return true; - - return cd->getAttrs().hasAttribute(); - } - if (auto *asd = dyn_cast(vd)) - return asd->requiresObjCGetterAndSetter(); - - return vd->getAttrs().hasAttribute(); -} - -bool SILGenModule::requiresObjCSuperDispatch(ValueDecl *vd) { - return requiresObjCDispatch(vd); -} - namespace { /// An ASTVisitor for populating SILVTable entries from ClassDecl members. @@ -232,7 +189,7 @@ class SILGenVTable : public Lowering::ASTVisitor { // Try to find an overridden entry. // NB: Mutates vtableEntries in-place // FIXME: O(n^2) - if (auto overridden = member.getOverriddenVTableEntry()) { + if (auto overridden = member.getNextOverriddenVTableEntry()) { for (SILVTable::Pair &entry : vtableEntries) { SILDeclRef ref = overridden; @@ -352,6 +309,11 @@ class SILGenType : public TypeMemberVisitor { /// Emit SIL functions for all the members of the type. void emitType() { + // Force type lowering to lower the type, so that we have a chance to + // check for infinite value types even if there are no other references + // to this type. + SGM.Types.getTypeLowering(theType->getDeclaredTypeInContext()); + // Start building a vtable if this is a class. if (auto theClass = dyn_cast(theType)) genVTable.emplace(SGM, theClass); @@ -413,10 +375,7 @@ class SILGenType : public TypeMemberVisitor { } void visitEnumCaseDecl(EnumCaseDecl *ecd) {} - void visitEnumElementDecl(EnumElementDecl *ued) { - assert(isa(theType)); - SGM.emitEnumConstructor(ued); - } + void visitEnumElementDecl(EnumElementDecl *ued) {} void visitPatternBindingDecl(PatternBindingDecl *pd) { // Emit initializers for static variables. diff --git a/lib/SILGen/Scope.h b/lib/SILGen/Scope.h index 26fd6d5b46053..3b1535ec115d7 100644 --- a/lib/SILGen/Scope.h +++ b/lib/SILGen/Scope.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILGen/SpecializedEmitter.h b/lib/SILGen/SpecializedEmitter.h index 8a6f76f3d87cc..4c1d59439148d 100644 --- a/lib/SILGen/SpecializedEmitter.h +++ b/lib/SILGen/SpecializedEmitter.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -37,7 +37,7 @@ class SILGenModule; /// Some kind of specialized emitter for a builtin function. class SpecializedEmitter { public: - /// A special function for emitting a call after the arguments + /// A special function for emitting a call before the arguments /// have already been emitted. using EarlyEmitter = ManagedValue (SILGenFunction &, SILLocation, diff --git a/lib/SILGen/Varargs.h b/lib/SILGen/Varargs.h index 5ee6b4e37fffd..c498f59745df6 100644 --- a/lib/SILGen/Varargs.h +++ b/lib/SILGen/Varargs.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILPasses/ARC/ARCBBState.cpp b/lib/SILOptimizer/ARC/ARCBBState.cpp similarity index 95% rename from lib/SILPasses/ARC/ARCBBState.cpp rename to lib/SILOptimizer/ARC/ARCBBState.cpp index 9c9e5ea25c056..ffe3814ca3d18 100644 --- a/lib/SILPasses/ARC/ARCBBState.cpp +++ b/lib/SILOptimizer/ARC/ARCBBState.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-global-arc-opts" +#define DEBUG_TYPE "arc-sequence-opts" #include "ARCBBState.h" #include "llvm/Support/Debug.h" @@ -140,8 +140,6 @@ void ARCBBState::initPredTopDown(ARCBBState &PredBBState) { PtrToTopDownState = PredBBState.PtrToTopDownState; } -void ARCBBState::initializeTrapStatus() { IsTrapBB = isARCInertTrapBB(BB); } - //===----------------------------------------------------------------------===// // ARCBBStateInfo //===----------------------------------------------------------------------===// @@ -153,7 +151,8 @@ using ARCBBStateInfoHandle = ARCSequenceDataflowEvaluator::ARCBBStateInfoHandle; } // end anonymous namespace -ARCBBStateInfo::ARCBBStateInfo(SILFunction *F, PostOrderAnalysis *POA) +ARCBBStateInfo::ARCBBStateInfo(SILFunction *F, PostOrderAnalysis *POA, + ProgramTerminationFunctionInfo *PTFI) : BBToBBIDMap(), BBIDToBottomUpBBStateMap(POA->get(F)->size()), BBIDToTopDownBBStateMap(POA->get(F)->size()), BackedgeMap() { @@ -164,8 +163,9 @@ ARCBBStateInfo::ARCBBStateInfo(SILFunction *F, PostOrderAnalysis *POA) unsigned BBID = BBToBBIDMap.size(); BBToBBIDMap[BB] = BBID; - BBIDToBottomUpBBStateMap[BBID].init(BB); - BBIDToTopDownBBStateMap[BBID].init(BB); + bool IsLeakingBB = PTFI->isProgramTerminatingBlock(BB); + BBIDToBottomUpBBStateMap[BBID].init(BB, IsLeakingBB); + BBIDToTopDownBBStateMap[BBID].init(BB, IsLeakingBB); for (auto &Succ : BB->getSuccessors()) if (SILBasicBlock *SuccBB = Succ.getBB()) diff --git a/lib/SILPasses/ARC/ARCBBState.h b/lib/SILOptimizer/ARC/ARCBBState.h similarity index 92% rename from lib/SILPasses/ARC/ARCBBState.h rename to lib/SILOptimizer/ARC/ARCBBState.h index 8a4f382800358..1daecceb653f8 100644 --- a/lib/SILPasses/ARC/ARCBBState.h +++ b/lib/SILOptimizer/ARC/ARCBBState.h @@ -1,8 +1,8 @@ -//===--- ARCBBState.h --------------------------------------*- C++ -*------===// +//===--- ARCBBState.h -------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_ARC_ARCBBSTATE_H -#define SWIFT_SILPASSES_ARC_ARCBBSTATE_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_ARCBBSTATE_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_ARCBBSTATE_H #include "GlobalARCSequenceDataflow.h" @@ -42,11 +42,10 @@ class ARCSequenceDataflowEvaluator::ARCBBState { ARCBBState() : BB() {} ARCBBState(SILBasicBlock *BB) : BB(BB) {} - void init(SILBasicBlock *NewBB) { + void init(SILBasicBlock *NewBB, bool NewIsTrapBB) { assert(NewBB && "Cannot set NewBB to a nullptr."); BB = NewBB; - IsTrapBB = false; - initializeTrapStatus(); + IsTrapBB = NewIsTrapBB; } /// Is this BB a BB that fits the canonical form of a trap? @@ -56,7 +55,7 @@ class ARCSequenceDataflowEvaluator::ARCBBState { /// builtin "int_trap"() : $() /// unreachable /// - /// This can not have any uses of reference counted values since the frontend + /// This cannot have any uses of reference counted values since the frontend /// just leaks at that point. bool isTrapBB() const { return IsTrapBB; } @@ -138,9 +137,6 @@ class ARCSequenceDataflowEvaluator::ARCBBState { /// BB. Used to create an initial state before we merge in other /// predecessors. This is currently a stub. void initPredTopDown(ARCBBState &PredBB); - -private: - void initializeTrapStatus(); }; class ARCSequenceDataflowEvaluator::ARCBBStateInfoHandle { @@ -191,7 +187,8 @@ class ARCSequenceDataflowEvaluator::ARCBBStateInfo { BackedgeMap; public: - ARCBBStateInfo(SILFunction *F, PostOrderAnalysis *POTA); + ARCBBStateInfo(SILFunction *F, PostOrderAnalysis *POTA, + ProgramTerminationFunctionInfo *PTFI); llvm::Optional getBottomUpBBHandle(SILBasicBlock *BB); llvm::Optional getTopDownBBHandle(SILBasicBlock *BB); diff --git a/lib/SILOptimizer/ARC/ARCLoopOpts.cpp b/lib/SILOptimizer/ARC/ARCLoopOpts.cpp new file mode 100644 index 0000000000000..20400886f78a7 --- /dev/null +++ b/lib/SILOptimizer/ARC/ARCLoopOpts.cpp @@ -0,0 +1,93 @@ +//===--- ARCLoopOpts.cpp --------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// This is a pass that runs multiple interrelated loop passes on a function. It +/// also provides caching of certain analysis information that is used by all of +/// the passes. +/// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "arc-sequence-opts" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "GlobalARCPairingAnalysis.h" +#include "ProgramTerminationAnalysis.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" + +using namespace swift; + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +namespace { + +class ARCLoopOpts : public SILFunctionTransform { + + void run() override { + auto *F = getFunction(); + + // If ARC optimizations are disabled, don't optimize anything and bail. + if (!getOptions().EnableARCOptimizations) + return; + + // Skip global init functions. + if (F->getName().startswith("globalinit_")) + return; + + auto *LA = getAnalysis(); + auto *LI = LA->get(F); + auto *DA = getAnalysis(); + auto *DI = DA->get(F); + + // Canonicalize the loops, invalidating if we need to. + if (canonicalizeAllLoops(DI, LI)) { + // We preserve loop info and the dominator tree. + DA->lockInvalidation(); + LA->lockInvalidation(); + PM->invalidateAnalysis(F, SILAnalysis::InvalidationKind::FunctionBody); + DA->unlockInvalidation(); + LA->unlockInvalidation(); + } + + // Get all of the analyses that we need. + auto *AA = getAnalysis(); + auto *RCFI = getAnalysis()->get(F); + auto *LRFI = getAnalysis()->get(F); + ProgramTerminationFunctionInfo PTFI(F); + + // Create all of our visitors, register them with the visitor group, and + // run. + LoopARCPairingContext LoopARCContext(*F, AA, LRFI, LI, RCFI, &PTFI); + SILLoopVisitorGroup VisitorGroup(F, LI); + VisitorGroup.addVisitor(&LoopARCContext); + VisitorGroup.run(); + + if (LoopARCContext.madeChange()) { + invalidateAnalysis(SILAnalysis::InvalidationKind::CallsAndInstructions); + } + } + + StringRef getName() override { return "ARC Loop Opts"; } +}; + +} // end anonymous namespace + +SILTransform *swift::createARCLoopOpts() { + return new ARCLoopOpts(); +} diff --git a/lib/SILPasses/ARC/ARCRegionState.cpp b/lib/SILOptimizer/ARC/ARCRegionState.cpp similarity index 79% rename from lib/SILPasses/ARC/ARCRegionState.cpp rename to lib/SILOptimizer/ARC/ARCRegionState.cpp index 1643b0f63eab5..050d0f33e8112 100644 --- a/lib/SILPasses/ARC/ARCRegionState.cpp +++ b/lib/SILOptimizer/ARC/ARCRegionState.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,13 +10,13 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-global-arc-opts" +#define DEBUG_TYPE "arc-sequence-opts" #include "ARCRegionState.h" #include "RCStateTransitionVisitors.h" #include "swift/Basic/Range.h" -#include "swift/SILAnalysis/LoopRegionAnalysis.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" #include "llvm/Support/Debug.h" using namespace swift; @@ -25,11 +25,9 @@ using namespace swift; // ARCRegionState //===----------------------------------------------------------------------===// -ARCRegionState::ARCRegionState(LoopRegion *R) - : Region(R), PtrToTopDownState(), PtrToBottomUpState(), AllowsLeaks(false) { - if (R->isBlock()) - AllowsLeaks = isARCInertTrapBB(R->getBlock()); -} +ARCRegionState::ARCRegionState(LoopRegion *R, bool AllowsLeaks) + : Region(R), PtrToTopDownState(), PtrToBottomUpState(), + AllowsLeaks(AllowsLeaks) {} //===--- // Bottom Up Merge @@ -160,13 +158,82 @@ void ARCRegionState::mergePredTopDown(ARCRegionState &PredRegionState) { // Bottom Up Dataflow // +static bool isARCSignificantTerminator(TermInst *TI) { + switch (TI->getTermKind()) { + case TermKind::Invalid: + llvm_unreachable("Expected a TermInst"); + case TermKind::UnreachableInst: + // br is a forwarding use for its arguments. It cannot in of itself extend + // the lifetime of an object (just like a phi-node) cannot. + case TermKind::BranchInst: + // A cond_br is a forwarding use for its non-operand arguments in a similar + // way to br. Its operand must be an i1 that has a different lifetime from any + // ref counted object. + case TermKind::CondBranchInst: + return false; + // Be conservative for now. These actually perform some sort of operation + // against the operand or can use the value in some way. + case TermKind::ThrowInst: + case TermKind::ReturnInst: + case TermKind::TryApplyInst: + case TermKind::SwitchValueInst: + case TermKind::SwitchEnumInst: + case TermKind::SwitchEnumAddrInst: + case TermKind::DynamicMethodBranchInst: + case TermKind::CheckedCastBranchInst: + case TermKind::CheckedCastAddrBranchInst: + return true; + } +} + +// Visit each one of our predecessor regions and see if any are blocks that can +// use reference counted values. If any of them do, we advance the sequence for +// the pointer and create an insertion point here. This state will be propagated +// into all of our predecessors, allowing us to be conservatively correct in all +// cases. +// +// The key thing to notice is that in general this cannot happen due to +// critical edge splitting. To trigger this, one would need a terminator that +// uses a reference counted value and only has one successor due to critical +// edge splitting. This is just to be conservative when faced with the unknown +// of future changes. +// +// We do not need to worry about loops here, since a loop exit block can only +// have predecessors in the loop itself implying that loop exit blocks at the +// loop region level always have only one predecessor, the loop itself. +void ARCRegionState::processBlockBottomUpPredTerminators( + const LoopRegion *R, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI) { + auto &BB = *R->getBlock(); + llvm::TinyPtrVector PredTerminators; + for (unsigned PredID : R->getPreds()) { + auto *PredRegion = LRFI->getRegion(PredID); + if (!PredRegion->isBlock()) + continue; + + auto *TermInst = PredRegion->getBlock()->getTerminator(); + if (!isARCSignificantTerminator(TermInst)) + continue; + PredTerminators.push_back(TermInst); + } + + auto *InsertPt = &*BB.begin(); + for (auto &OtherState : getBottomupStates()) { + // If the other state's value is blotted, skip it. + if (!OtherState.hasValue()) + continue; + + OtherState->second.updateForPredTerminators(PredTerminators, InsertPt, AA); + } +} + bool ARCRegionState::processBlockBottomUp( - SILBasicBlock &BB, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA, - bool FreezeOwnedArgEpilogueReleases, + const LoopRegion *R, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA, + LoopRegionFunctionInfo *LRFI, bool FreezeOwnedArgEpilogueReleases, ConsumedArgToEpilogueReleaseMatcher &ConsumedArgToReleaseMap, BlotMapVector &IncToDecStateMap) { DEBUG(llvm::dbgs() << ">>>> Bottom Up!\n"); + SILBasicBlock &BB = *R->getBlock(); bool NestingDetected = false; BottomUpDataflowRCStateVisitor DataflowVisitor( @@ -213,6 +280,13 @@ bool ARCRegionState::processBlockBottomUp( } } + // Now visit each one of our predecessor regions and see if any are blocks + // that can use reference counted values. If any of them do, we advance the + // sequence for the pointer and create an insertion point here. This state + // will be propagated into all of our predecessors, allowing us to be + // conservatively correct in all cases. + processBlockBottomUpPredTerminators(R, AA, LRFI); + return NestingDetected; } @@ -226,7 +300,7 @@ static bool getInsertionPtsForLoopRegionExits( llvm::SmallVectorImpl &InsertPts) { assert(R->isLoop() && "Expected a loop region that is representing a loop"); - // Go through all of our non local successors. If any of them can not be + // Go through all of our non local successors. If any of them cannot be // ignored, we bail for simplicity. This means that for now we do not handle // early exits. if (any_of(R->getNonLocalSuccs(), [&](unsigned SuccID) -> bool { @@ -287,10 +361,8 @@ bool ARCRegionState::processBottomUp( if (!R->isBlock()) return processLoopBottomUp(R, AA, LRFI, RegionStateInfo); - return processBlockBottomUp(*R->getBlock(), AA, RCIA, - FreezeOwnedArgEpilogueReleases, - ConsumedArgToReleaseMap, - IncToDecStateMap); + return processBlockBottomUp(R, AA, RCIA, LRFI, FreezeOwnedArgEpilogueReleases, + ConsumedArgToReleaseMap, IncToDecStateMap); } //===--- @@ -418,7 +490,7 @@ void ARCRegionState::summarizeBlock(SILBasicBlock *BB) { SummarizedInterestingInsts.clear(); for (auto &I : *BB) - if (!canNeverUseValues(&I) || !canNeverDecrementRefCounts(&I)) + if (!canNeverUseValues(&I) || I.mayReleaseOrReadRefCount()) SummarizedInterestingInsts.push_back(&I); } diff --git a/lib/SILPasses/ARC/ARCRegionState.h b/lib/SILOptimizer/ARC/ARCRegionState.h similarity index 91% rename from lib/SILPasses/ARC/ARCRegionState.h rename to lib/SILOptimizer/ARC/ARCRegionState.h index 452b323ba65fd..94de56e110318 100644 --- a/lib/SILPasses/ARC/ARCRegionState.h +++ b/lib/SILOptimizer/ARC/ARCRegionState.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_ARC_ARCREGIONSTATE_H -#define SWIFT_SILPASSES_ARC_ARCREGIONSTATE_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_ARCREGIONSTATE_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_ARCREGIONSTATE_H #include "GlobalLoopARCSequenceDataflow.h" #include "swift/Basic/NullablePtr.h" @@ -34,7 +34,7 @@ class ARCRegionState { /// The region that this ARCRegionState summarizes information for. /// /// The only time that the pointer is null is during initialization. Using - /// NullablePtr is just a convient way to make sure that we assert if we + /// NullablePtr is just a convenient way to make sure that we assert if we /// attempt to use Region during initialization before the pointer is set. NullablePtr Region; @@ -65,7 +65,7 @@ class ARCRegionState { llvm::SmallVector SummarizedInterestingInsts; public: - ARCRegionState(LoopRegion *R); + ARCRegionState(LoopRegion *R, bool AllowsLeaks); /// Is this Region from which we can leak memory safely? bool allowsLeaks() const { return AllowsLeaks; } @@ -192,11 +192,14 @@ class ARCRegionState { llvm::DenseMap &RegionStateInfo); private: + void processBlockBottomUpPredTerminators(const LoopRegion *R, + AliasAnalysis *AA, + LoopRegionFunctionInfo *LRFI); bool processBlockBottomUp( - SILBasicBlock &BB, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA, - bool FreezeOwnedArgEpilogueReleases, - ConsumedArgToEpilogueReleaseMatcher &ConsumedArgToReleaseMap, - BlotMapVector &IncToDecStateMap); + const LoopRegion *R, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA, + LoopRegionFunctionInfo *LRFI, bool FreezeOwnedArgEpilogueReleases, + ConsumedArgToEpilogueReleaseMatcher &ConsumedArgToReleaseMap, + BlotMapVector &IncToDecStateMap); bool processLoopBottomUp( const LoopRegion *R, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI, llvm::DenseMap &RegionStateInfo); diff --git a/lib/SILPasses/ARC/ARCSequenceOpts.cpp b/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp similarity index 85% rename from lib/SILPasses/ARC/ARCSequenceOpts.cpp rename to lib/SILOptimizer/ARC/ARCSequenceOpts.cpp index b56600e8d8122..a81dad84f2ad0 100644 --- a/lib/SILPasses/ARC/ARCSequenceOpts.cpp +++ b/lib/SILOptimizer/ARC/ARCSequenceOpts.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,20 +11,21 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "arc-sequence-opts" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "GlobalARCPairingAnalysis.h" +#include "ProgramTerminationAnalysis.h" #include "swift/Basic/Fallthrough.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/LoopUtils.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" -#include "swift/SILAnalysis/LoopRegionAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/LoopUtils.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/MapVector.h" @@ -141,11 +142,11 @@ void CodeMotionOrDeleteCallback::processMatchingSet(ARCMatchingSet &MatchSet) { // Non Loop Optimizer //===----------------------------------------------------------------------===// -static bool processFunctionWithoutLoopSupport(SILFunction &F, - bool FreezePostDomReleases, - AliasAnalysis *AA, - PostOrderAnalysis *POTA, - RCIdentityFunctionInfo *RCIA) { +static bool +processFunctionWithoutLoopSupport(SILFunction &F, bool FreezePostDomReleases, + AliasAnalysis *AA, PostOrderAnalysis *POTA, + RCIdentityFunctionInfo *RCIA, + ProgramTerminationFunctionInfo *PTFI) { // GlobalARCOpts seems to be taking up a lot of compile time when running on // globalinit_func. Since that is not *that* interesting from an ARC // perspective (i.e. no ref count operations in a loop), disable it on such @@ -156,7 +157,7 @@ static bool processFunctionWithoutLoopSupport(SILFunction &F, DEBUG(llvm::dbgs() << "***** Processing " << F.getName() << " *****\n"); bool Changed = false; - BlockARCPairingContext Context(F, AA, POTA, RCIA); + BlockARCPairingContext Context(F, AA, POTA, RCIA, PTFI); CodeMotionOrDeleteCallback Callback; // Until we do not remove any instructions or have nested increments, // decrements... @@ -190,11 +191,10 @@ static bool processFunctionWithoutLoopSupport(SILFunction &F, // Loop Optimizer //===----------------------------------------------------------------------===// -static bool -processFunctionWithLoopSupport(SILFunction &F, bool FreezePostDomReleases, - AliasAnalysis *AA, PostOrderAnalysis *POTA, - LoopRegionFunctionInfo *LRFI, SILLoopInfo *LI, - RCIdentityFunctionInfo *RCFI) { +static bool processFunctionWithLoopSupport( + SILFunction &F, AliasAnalysis *AA, PostOrderAnalysis *POTA, + LoopRegionFunctionInfo *LRFI, SILLoopInfo *LI, RCIdentityFunctionInfo *RCFI, + ProgramTerminationFunctionInfo *PTFI) { // GlobalARCOpts seems to be taking up a lot of compile time when running on // globalinit_func. Since that is not *that* interesting from an ARC // perspective (i.e. no ref count operations in a loop), disable it on such @@ -204,8 +204,8 @@ processFunctionWithLoopSupport(SILFunction &F, bool FreezePostDomReleases, DEBUG(llvm::dbgs() << "***** Processing " << F.getName() << " *****\n"); - LoopARCPairingContext Context(F, AA, LRFI, LI, RCFI); - return Context.process(FreezePostDomReleases); + LoopARCPairingContext Context(F, AA, LRFI, LI, RCFI, PTFI); + return Context.process(); } //===----------------------------------------------------------------------===// @@ -226,9 +226,10 @@ class ARCSequenceOpts : public SILFunctionTransform { auto *AA = getAnalysis(); auto *POTA = getAnalysis(); auto *RCFI = getAnalysis()->get(F); + ProgramTerminationFunctionInfo PTFI(F); - if (processFunctionWithoutLoopSupport(*F, false, AA, POTA, RCFI)) { - processFunctionWithoutLoopSupport(*F, true, AA, POTA, RCFI); + if (processFunctionWithoutLoopSupport(*F, false, AA, POTA, RCFI, &PTFI)) { + processFunctionWithoutLoopSupport(*F, true, AA, POTA, RCFI, &PTFI); invalidateAnalysis(SILAnalysis::InvalidationKind::CallsAndInstructions); } return; @@ -253,9 +254,9 @@ class ARCSequenceOpts : public SILFunctionTransform { auto *POTA = getAnalysis(); auto *RCFI = getAnalysis()->get(F); auto *LRFI = getAnalysis()->get(F); + ProgramTerminationFunctionInfo PTFI(F); - if (processFunctionWithLoopSupport(*F, false, AA, POTA, LRFI, LI, RCFI)) { - processFunctionWithLoopSupport(*F, true, AA, POTA, LRFI, LI, RCFI); + if (processFunctionWithLoopSupport(*F, AA, POTA, LRFI, LI, RCFI, &PTFI)) { invalidateAnalysis(SILAnalysis::InvalidationKind::CallsAndInstructions); } } diff --git a/lib/SILOptimizer/ARC/CMakeLists.txt b/lib/SILOptimizer/ARC/CMakeLists.txt new file mode 100644 index 0000000000000..12bc12de864eb --- /dev/null +++ b/lib/SILOptimizer/ARC/CMakeLists.txt @@ -0,0 +1,12 @@ +set(ARC_SOURCES + ARC/ARCBBState.cpp + ARC/ARCRegionState.cpp + ARC/ARCLoopOpts.cpp + ARC/ARCSequenceOpts.cpp + ARC/GlobalARCPairingAnalysis.cpp + ARC/GlobalARCSequenceDataflow.cpp + ARC/GlobalLoopARCSequenceDataflow.cpp + ARC/RCStateTransition.cpp + ARC/RCStateTransitionVisitors.cpp + ARC/RefCountState.cpp + PARENT_SCOPE) diff --git a/lib/SILPasses/ARC/GlobalARCPairingAnalysis.cpp b/lib/SILOptimizer/ARC/GlobalARCPairingAnalysis.cpp similarity index 79% rename from lib/SILPasses/ARC/GlobalARCPairingAnalysis.cpp rename to lib/SILOptimizer/ARC/GlobalARCPairingAnalysis.cpp index 50deee0e95032..3e0fe426b0ca2 100644 --- a/lib/SILPasses/ARC/GlobalARCPairingAnalysis.cpp +++ b/lib/SILOptimizer/ARC/GlobalARCPairingAnalysis.cpp @@ -1,8 +1,8 @@ -//===-- GlobalARCPairingAnalysis.cpp - Global ARC Retain Release Pairing --===// +//===--- GlobalARCPairingAnalysis.cpp - Global ARC Retain Release Pairing -===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-global-arc-opts" +#define DEBUG_TYPE "arc-sequence-opts" #include "GlobalARCPairingAnalysis.h" #include "RefCountState.h" #include "GlobalARCSequenceDataflow.h" @@ -19,12 +19,12 @@ #include "swift/Basic/Fallthrough.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/MapVector.h" @@ -140,40 +140,49 @@ ARCMatchingSetBuilder::matchIncrementsToDecrements() { // We need to be known safe over all increments/decrements we are matching up // to ignore insertion points. - Flags.KnownSafe &= (*BURefCountState)->second.isKnownSafe(); + bool BUIsKnownSafe = (*BURefCountState)->second.isKnownSafe(); + DEBUG(llvm::dbgs() << " KNOWNSAFE: " + << (BUIsKnownSafe ? "true" : "false") << "\n"); + Flags.KnownSafe &= BUIsKnownSafe; // We can only move instructions if we know that we are not partial. We can // still delete instructions in such cases though. - Flags.Partial |= (*BURefCountState)->second.isPartial(); + bool BUIsPartial = (*BURefCountState)->second.isPartial(); + DEBUG(llvm::dbgs() << " PARTIAL: " + << (BUIsPartial ? "true" : "false") << "\n"); + Flags.Partial |= BUIsPartial; // Now that we know we have an inst, grab the decrement. for (auto DecIter : (*BURefCountState)->second.getInstructions()) { SILInstruction *Decrement = DecIter; - DEBUG(llvm::dbgs() << " Decrement: " << *Decrement); + DEBUG(llvm::dbgs() << " Decrement: " << *Decrement); // Now grab the increment matched up with the decrement from the bottom up map. // If we can't find it, bail we can't match this increment up with anything. auto TDRefCountState = TDMap.find(Decrement); if (TDRefCountState == TDMap.end()) { - DEBUG(llvm::dbgs() << " FAILURE! Could not find state for " - "decrement.\n"); + DEBUG(llvm::dbgs() << " FAILURE! Could not find state for " + "decrement.\n"); return None; } - DEBUG(llvm::dbgs() << " SUCCESS! Found state for decrement.\n"); + DEBUG(llvm::dbgs() << " SUCCESS! Found state for " + "decrement.\n"); // Make sure the increment we are looking at is also matched to our decrement. // Otherwise bail. if (!(*TDRefCountState)->second.isTrackingRefCountInst() || !(*TDRefCountState)->second.containsInstruction(Increment)) { - DEBUG(llvm::dbgs() << " FAILURE! Not tracking instruction or " - "found increment that did not match.\n"); + DEBUG( + llvm::dbgs() << " FAILURE! Not tracking instruction or " + "found increment that did not match.\n"); return None; } // Add the decrement to the decrement to move set. If we don't insert // anything, just continue. if (!MatchSet.Decrements.insert(Decrement)) { - DEBUG(llvm::dbgs() << " SKIPPING! Already processed this decrement\n"); + DEBUG(llvm::dbgs() + << " SKIPPING! Already processed this decrement\n"); continue; } @@ -218,34 +227,42 @@ ARCMatchingSetBuilder::matchDecrementsToIncrements() { // We need to be known safe over all increments/decrements we are matching up // to ignore insertion points. - Flags.KnownSafe &= (*TDRefCountState)->second.isKnownSafe(); + bool TDIsKnownSafe = (*TDRefCountState)->second.isKnownSafe(); + DEBUG(llvm::dbgs() << " KNOWNSAFE: " + << (TDIsKnownSafe ? "true" : "false") << "\n"); + Flags.KnownSafe &= TDIsKnownSafe; // We can only move instructions if we know that we are not partial. We can // still delete instructions in such cases though. - Flags.Partial |= (*TDRefCountState)->second.isPartial(); + bool TDIsPartial = (*TDRefCountState)->second.isPartial(); + DEBUG(llvm::dbgs() << " PARTIAL: " + << (TDIsPartial ? "true" : "false") << "\n"); + Flags.Partial |= TDIsPartial; // Now that we know we have an inst, grab the decrement. for (auto IncIter : (*TDRefCountState)->second.getInstructions()) { SILInstruction *Increment = IncIter; - DEBUG(llvm::dbgs() << " Increment: " << *Increment); + DEBUG(llvm::dbgs() << " Increment: " << *Increment); // Now grab the increment matched up with the decrement from the bottom up map. // If we can't find it, bail we can't match this increment up with anything. auto BURefCountState = BUMap.find(Increment); if (BURefCountState == BUMap.end()) { - DEBUG(llvm::dbgs() << " FAILURE! Could not find state for " - "increment.\n"); + DEBUG(llvm::dbgs() << " FAILURE! Could not find state for " + "increment.\n"); return None; } - DEBUG(llvm::dbgs() << " SUCCESS! Found state for increment.\n"); + DEBUG( + llvm::dbgs() << " SUCCESS! Found state for increment.\n"); // Make sure the increment we are looking at is also matched to our decrement. // Otherwise bail. if (!(*BURefCountState)->second.isTrackingRefCountInst() || !(*BURefCountState)->second.containsInstruction(Decrement)) { - DEBUG(llvm::dbgs() << " FAILURE! Not tracking instruction or " - "found increment that did not match.\n"); + DEBUG( + llvm::dbgs() << " FAILURE! Not tracking instruction or " + "found increment that did not match.\n"); return None; } @@ -269,7 +286,7 @@ ARCMatchingSetBuilder::matchDecrementsToIncrements() { /// Visit each retain/release that is matched up to our operand over and over /// again until we converge by not adding any more to the set which we can move. -/// If we find a situation that we can not handle, we bail and return false. If +/// If we find a situation that we cannot handle, we bail and return false. If /// we succeed and it is safe to move increment/releases, we return true. bool ARCMatchingSetBuilder::matchUpIncDecSetsForPtr() { bool KnownSafeTD = true; @@ -405,26 +422,45 @@ bool ARCPairingContext::performMatching(CodeMotionOrDeleteCallback &Callback) { //===----------------------------------------------------------------------===// void LoopARCPairingContext::runOnLoop(SILLoop *L) { - processRegion(LRFI->getRegion(L)); + auto *Region = LRFI->getRegion(L); + if (processRegion(Region, false, false)) { + // We do not recompute for now since we only look at the top function level + // for post dominating releases. + processRegion(Region, true, false); + } + + // Now that we have finished processing the loop, summarize the loop. + Evaluator.summarizeLoop(Region); } void LoopARCPairingContext::runOnFunction(SILFunction *F) { - processRegion(LRFI->getTopLevelRegion()); + if (processRegion(LRFI->getTopLevelRegion(), false, false)) { + // We recompute the final post dom release since we may have moved the final + // post dominated releases. + processRegion(LRFI->getTopLevelRegion(), true, true); + } } -void LoopARCPairingContext::processRegion(const LoopRegion *Region) { - bool NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases); +bool LoopARCPairingContext::processRegion(const LoopRegion *Region, + bool FreezePostDomReleases, + bool RecomputePostDomReleases) { + bool MadeChange = false; + bool NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases, + RecomputePostDomReleases); bool MatchedPair = Context.performMatching(Callback); + MadeChange |= MatchedPair; + Evaluator.clearLoopState(Region); Context.DecToIncStateMap.clear(); Context.IncToDecStateMap.clear(); while (NestingDetected && MatchedPair) { - Evaluator.clearLoopState(Region); - NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases); + NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases, false); MatchedPair = Context.performMatching(Callback); + MadeChange |= MatchedPair; + Evaluator.clearLoopState(Region); Context.DecToIncStateMap.clear(); Context.IncToDecStateMap.clear(); } - Evaluator.summarizeLoop(Region); + return MadeChange; } diff --git a/lib/SILPasses/ARC/GlobalARCPairingAnalysis.h b/lib/SILOptimizer/ARC/GlobalARCPairingAnalysis.h similarity index 81% rename from lib/SILPasses/ARC/GlobalARCPairingAnalysis.h rename to lib/SILOptimizer/ARC/GlobalARCPairingAnalysis.h index fe7a63a01b13d..cfb3100f700c6 100644 --- a/lib/SILPasses/ARC/GlobalARCPairingAnalysis.h +++ b/lib/SILOptimizer/ARC/GlobalARCPairingAnalysis.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,13 +10,13 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_GLOBALARCPAIRINGANALYSIS_H -#define SWIFT_SILPASSES_GLOBALARCPAIRINGANALYSIS_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_GLOBALARCPAIRINGANALYSIS_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_GLOBALARCPAIRINGANALYSIS_H #include "GlobalARCSequenceDataflow.h" #include "GlobalLoopARCSequenceDataflow.h" #include "swift/SIL/SILValue.h" -#include "swift/SILPasses/Utils/LoopUtils.h" +#include "swift/SILOptimizer/Utils/LoopUtils.h" #include "llvm/ADT/SetVector.h" namespace swift { @@ -43,7 +43,7 @@ struct ARCMatchingSet { llvm::SetVector Increments; /// An insertion point for an increment means the earliest point in the - /// program after the increment has occured that the increment can be moved to + /// program after the increment has occurred that the increment can be moved to /// without moving the increment over an instruction that may decrement a /// reference count. llvm::SetVector IncrementInsertPts; @@ -56,7 +56,7 @@ struct ARCMatchingSet { /// reference counted value could be used. llvm::SetVector DecrementInsertPts; - // This is a data structure that can not be moved or copied. + // This is a data structure that cannot be moved or copied. ARCMatchingSet() = default; ARCMatchingSet(const ARCMatchingSet &) = delete; ARCMatchingSet(ARCMatchingSet &&) = delete; @@ -95,7 +95,7 @@ class CodeMotionOrDeleteCallback { bool madeChange() const { return Changed; } }; -/// A wrapper around the results of the bottomup/topdown dataflow that knows how +/// A wrapper around the results of the bottom-up/top-down dataflow that knows how /// to pair the retains/releases in those results. struct ARCPairingContext { SILFunction &F; @@ -118,9 +118,11 @@ struct BlockARCPairingContext { ARCSequenceDataflowEvaluator Evaluator; BlockARCPairingContext(SILFunction &F, AliasAnalysis *AA, - PostOrderAnalysis *POTA, RCIdentityFunctionInfo *RCFI) - : Context(F, RCFI), Evaluator(F, AA, POTA, RCFI, Context.DecToIncStateMap, - Context.IncToDecStateMap) {} + PostOrderAnalysis *POTA, RCIdentityFunctionInfo *RCFI, + ProgramTerminationFunctionInfo *PTFI) + : Context(F, RCFI), + Evaluator(F, AA, POTA, RCFI, PTFI, Context.DecToIncStateMap, + Context.IncToDecStateMap) {} bool run(bool FreezePostDomReleases, CodeMotionOrDeleteCallback &Callback) { bool NestingDetected = Evaluator.run(FreezePostDomReleases); @@ -141,26 +143,31 @@ struct LoopARCPairingContext : SILLoopVisitor { LoopRegionFunctionInfo *LRFI; SILLoopInfo *SLI; CodeMotionOrDeleteCallback Callback; - bool FreezePostDomReleases = false; LoopARCPairingContext(SILFunction &F, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI, SILLoopInfo *SLI, - RCIdentityFunctionInfo *RCFI) + RCIdentityFunctionInfo *RCFI, + ProgramTerminationFunctionInfo *PTFI) : SILLoopVisitor(&F, SLI), Context(F, RCFI), - Evaluator(F, AA, LRFI, SLI, RCFI, Context.DecToIncStateMap, + Evaluator(F, AA, LRFI, SLI, RCFI, PTFI, Context.DecToIncStateMap, Context.IncToDecStateMap), LRFI(LRFI), SLI(SLI), Callback() {} - bool process(bool FreezePDReleases) { - FreezePostDomReleases = FreezePDReleases; + bool process() { run(); - return Callback.madeChange(); + if (!Callback.madeChange()) + return false; + run(); + return true; } + bool madeChange() const { return Callback.madeChange(); } + void runOnLoop(SILLoop *L) override; void runOnFunction(SILFunction *F) override; - void processRegion(const LoopRegion *R); + bool processRegion(const LoopRegion *R, bool FreezePostDomReleases, + bool RecomputePostDomReleases); }; } // end swift namespace diff --git a/lib/SILPasses/ARC/GlobalARCSequenceDataflow.cpp b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp similarity index 82% rename from lib/SILPasses/ARC/GlobalARCSequenceDataflow.cpp rename to lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp index 653ff97a1c29b..7d6404a6163ff 100644 --- a/lib/SILPasses/ARC/GlobalARCSequenceDataflow.cpp +++ b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,13 +10,13 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-global-arc-opts" +#define DEBUG_TYPE "arc-sequence-opts" #include "GlobalARCSequenceDataflow.h" #include "ARCBBState.h" #include "RCStateTransitionVisitors.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILSuccessor.h" @@ -149,7 +149,7 @@ void ARCSequenceDataflowEvaluator::mergePredecessors( ARCBBState &PredBBState = PredDataHandle->getState(); // If we found the state but the state is for a trap BB, skip it. Trap BBs - // leak all reference counts and do not reference reference semantic objects + // leak all reference counts and do not reference semantic objects // in any manner. // // TODO: I think this is a copy paste error, since we a trap BB should have @@ -198,6 +198,36 @@ bool ARCSequenceDataflowEvaluator::processTopDown() { // Bottom Up Dataflow //===----------------------------------------------------------------------===// +// This is temporary code duplication. This will be removed when Loop ARC is +// finished and Block ARC is removed. +static bool isARCSignificantTerminator(TermInst *TI) { + switch (TI->getTermKind()) { + case TermKind::Invalid: + llvm_unreachable("Expected a TermInst"); + case TermKind::UnreachableInst: + // br is a forwarding use for its arguments. It cannot in of itself extend + // the lifetime of an object (just like a phi-node) cannot. + case TermKind::BranchInst: + // A cond_br is a forwarding use for its non-operand arguments in a similar + // way to br. Its operand must be an i1 that has a different lifetime from any + // ref counted object. + case TermKind::CondBranchInst: + return false; + // Be conservative for now. These actually perform some sort of operation + // against the operand or can use the value in some way. + case TermKind::ThrowInst: + case TermKind::ReturnInst: + case TermKind::TryApplyInst: + case TermKind::SwitchValueInst: + case TermKind::SwitchEnumInst: + case TermKind::SwitchEnumAddrInst: + case TermKind::DynamicMethodBranchInst: + case TermKind::CheckedCastBranchInst: + case TermKind::CheckedCastAddrBranchInst: + return true; + } +} + /// Analyze a single BB for refcount inc/dec instructions. /// /// If anything was found it will be added to DecToIncStateMap. @@ -209,9 +239,9 @@ bool ARCSequenceDataflowEvaluator::processTopDown() { /// pointer in a function that implies that the pointer is alive up to that /// point. We "freeze" (i.e. do not attempt to remove or move) such releases if /// FreezeOwnedArgEpilogueReleases is set. This is useful since in certain cases -/// due to dataflow issues, we can not properly propagate the last use +/// due to dataflow issues, we cannot properly propagate the last use /// information. Instead we run an extra iteration of the ARC optimizer with -/// this enabled in a side table so the information gets propgated everywhere in +/// this enabled in a side table so the information gets propagated everywhere in /// the CFG. bool ARCSequenceDataflowEvaluator::processBBBottomUp( ARCBBState &BBState, bool FreezeOwnedArgEpilogueReleases) { @@ -266,6 +296,31 @@ bool ARCSequenceDataflowEvaluator::processBBBottomUp( } } + // This is ignoring the possibility that we may have a loop with an + // interesting terminator but for which, we are going to clear all state + // (since it is a loop boundary). We may in such a case, be too conservative + // with our other predecessors. Luckily this cannot happen since cond_br is + // the only terminator that allows for critical edges and all other + // "interesting terminators" always having multiple successors. This means + // that this block could not have multiple predecessors since otherwise, the + // edge would be broken. + llvm::TinyPtrVector PredTerminators; + for (SILBasicBlock *PredBB : BB.getPreds()) { + auto *TermInst = PredBB->getTerminator(); + if (!isARCSignificantTerminator(TermInst)) + continue; + PredTerminators.push_back(TermInst); + } + + auto *InsertPt = &*BB.begin(); + for (auto &OtherState : BBState.getBottomupStates()) { + // If the other state's value is blotted, skip it. + if (!OtherState.hasValue()) + continue; + + OtherState->second.updateForPredTerminators(PredTerminators, InsertPt, AA); + } + return NestingDetected; } @@ -350,14 +405,14 @@ bool ARCSequenceDataflowEvaluator::processBottomUp( ARCSequenceDataflowEvaluator::ARCSequenceDataflowEvaluator( SILFunction &F, AliasAnalysis *AA, PostOrderAnalysis *POA, - RCIdentityFunctionInfo *RCIA, + RCIdentityFunctionInfo *RCIA, ProgramTerminationFunctionInfo *PTFI, BlotMapVector &DecToIncStateMap, BlotMapVector &IncToDecStateMap) : F(F), AA(AA), POA(POA), RCIA(RCIA), DecToIncStateMap(DecToIncStateMap), IncToDecStateMap(IncToDecStateMap), // We use a malloced pointer here so we don't need to expose // ARCBBStateInfo in the header. - BBStateInfo(new ARCBBStateInfo(&F, POA)), + BBStateInfo(new ARCBBStateInfo(&F, POA, PTFI)), ConsumedArgToReleaseMap(RCIA, &F) {} bool ARCSequenceDataflowEvaluator::run(bool FreezeOwnedReleases) { diff --git a/lib/SILPasses/ARC/GlobalARCSequenceDataflow.h b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h similarity index 89% rename from lib/SILPasses/ARC/GlobalARCSequenceDataflow.h rename to lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h index ad57ef9b3a25d..d8a622d2eb1b8 100644 --- a/lib/SILPasses/ARC/GlobalARCSequenceDataflow.h +++ b/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,11 +10,12 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_ARC_GLOBALARCSEQUENCEDATAFLOW_H -#define SWIFT_SILPASSES_ARC_GLOBALARCSEQUENCEDATAFLOW_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_GLOBALARCSEQUENCEDATAFLOW_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_GLOBALARCSEQUENCEDATAFLOW_H #include "RefCountState.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "ProgramTerminationAnalysis.h" #include "swift/Basic/BlotMapVector.h" #include "swift/Basic/NullablePtr.h" #include "llvm/ADT/MapVector.h" @@ -67,7 +68,7 @@ class ARCSequenceDataflowEvaluator { public: ARCSequenceDataflowEvaluator( SILFunction &F, AliasAnalysis *AA, PostOrderAnalysis *POA, - RCIdentityFunctionInfo *RCIA, + RCIdentityFunctionInfo *RCIA, ProgramTerminationFunctionInfo *PTFI, BlotMapVector &DecToIncStateMap, BlotMapVector &IncToDecStateMap); ~ARCSequenceDataflowEvaluator(); diff --git a/lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.cpp b/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.cpp similarity index 91% rename from lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.cpp rename to lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.cpp index d22bd70ff1f59..101e1eb93a9da 100644 --- a/lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.cpp +++ b/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,13 +10,13 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-global-arc-opts" +#define DEBUG_TYPE "arc-sequence-opts" #include "GlobalLoopARCSequenceDataflow.h" #include "ARCRegionState.h" #include "RCStateTransitionVisitors.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILSuccessor.h" @@ -171,7 +171,7 @@ void LoopARCSequenceDataflowEvaluator::mergeSuccessors(const LoopRegion *Region, } // Otherwise, we treat it as unknown control flow. - DEBUG(llvm::dbgs() << " Cleaing state b/c of early exit\n"); + DEBUG(llvm::dbgs() << " Clearing state b/c of early exit\n"); State.clear(); break; } @@ -188,9 +188,9 @@ void LoopARCSequenceDataflowEvaluator::mergeSuccessors(const LoopRegion *Region, /// pointer in a function that implies that the pointer is alive up to that /// point. We "freeze" (i.e. do not attempt to remove or move) such releases if /// FreezeOwnedArgEpilogueReleases is set. This is useful since in certain cases -/// due to dataflow issues, we can not properly propagate the last use +/// due to dataflow issues, we cannot properly propagate the last use /// information. Instead we run an extra iteration of the ARC optimizer with -/// this enabled in a side table so the information gets propgated everywhere in +/// this enabled in a side table so the information gets propagated everywhere in /// the CFG. bool LoopARCSequenceDataflowEvaluator::processLoopBottomUp( const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases) { @@ -250,13 +250,17 @@ bool LoopARCSequenceDataflowEvaluator::processLoopBottomUp( LoopARCSequenceDataflowEvaluator::LoopARCSequenceDataflowEvaluator( SILFunction &F, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI, SILLoopInfo *SLI, RCIdentityFunctionInfo *RCFI, + ProgramTerminationFunctionInfo *PTFI, BlotMapVector &DecToIncStateMap, BlotMapVector &IncToDecStateMap) : F(F), AA(AA), LRFI(LRFI), SLI(SLI), RCFI(RCFI), DecToIncStateMap(DecToIncStateMap), IncToDecStateMap(IncToDecStateMap), ConsumedArgToReleaseMap(RCFI, &F) { for (auto *R : LRFI->getRegions()) { - RegionStateInfo[R] = new (Allocator) ARCRegionState(R); + bool AllowsLeaks = false; + if (R->isBlock()) + AllowsLeaks |= PTFI->isProgramTerminatingBlock(R->getBlock()); + RegionStateInfo[R] = new (Allocator) ARCRegionState(R, AllowsLeaks); } } @@ -267,7 +271,10 @@ LoopARCSequenceDataflowEvaluator::~LoopARCSequenceDataflowEvaluator() { } bool LoopARCSequenceDataflowEvaluator::runOnLoop( - const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases) { + const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases, + bool RecomputePostDomReleases) { + if (RecomputePostDomReleases) + ConsumedArgToReleaseMap.recompute(); bool NestingDetected = processLoopBottomUp(R, FreezeOwnedArgEpilogueReleases); NestingDetected |= processLoopTopDown(R); return NestingDetected; diff --git a/lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.h b/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.h similarity index 90% rename from lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.h rename to lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.h index 23ecf83b5d7e3..a36441099aced 100644 --- a/lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.h +++ b/lib/SILOptimizer/ARC/GlobalLoopARCSequenceDataflow.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,11 +10,12 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_ARC_GLOBALLOOPARCSEQUENCEDATAFLOW_H -#define SWIFT_SILPASSES_ARC_GLOBALLOOPARCSEQUENCEDATAFLOW_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_GLOBALLOOPARCSEQUENCEDATAFLOW_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_GLOBALLOOPARCSEQUENCEDATAFLOW_H #include "RefCountState.h" -#include "swift/SILAnalysis/LoopRegionAnalysis.h" +#include "ProgramTerminationAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h" #include "swift/Basic/BlotMapVector.h" #include "swift/Basic/NullablePtr.h" #include "llvm/ADT/MapVector.h" @@ -74,6 +75,7 @@ class LoopARCSequenceDataflowEvaluator { LoopARCSequenceDataflowEvaluator( SILFunction &F, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI, SILLoopInfo *SLI, RCIdentityFunctionInfo *RCIA, + ProgramTerminationFunctionInfo *PTFI, BlotMapVector &DecToIncStateMap, BlotMapVector &IncToDecStateMap); ~LoopARCSequenceDataflowEvaluator(); @@ -85,7 +87,8 @@ class LoopARCSequenceDataflowEvaluator { /// Perform the sequence dataflow, bottom up and top down on the loop region /// \p R. - bool runOnLoop(const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases); + bool runOnLoop(const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases, + bool RecomputePostDomReleases); /// Summarize the contents of the loop so that loops further up the loop tree /// can reason about the loop. diff --git a/lib/SILOptimizer/ARC/ProgramTerminationAnalysis.h b/lib/SILOptimizer/ARC/ProgramTerminationAnalysis.h new file mode 100644 index 0000000000000..0813834558f0b --- /dev/null +++ b/lib/SILOptimizer/ARC/ProgramTerminationAnalysis.h @@ -0,0 +1,55 @@ +//===--- ProgramTerminationAnalysis.h -------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// This is an analysis which determines if a block is a "program terminating +/// block". Define a program terminating block is defined as follows: +/// +/// 1. A block at whose end point according to the SIL model, the program must +/// end. An example of such a block is one that includes a call to fatalError. +/// 2. Any block that is joint post-dominated by program terminating blocks. +/// +/// For now we only identify instances of 1. But the analysis could be extended +/// appropriately via simple dataflow or through the use of post-dominator +/// trees. +/// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_PROGRAMTERMINATIONANALYSIS_H +#define SWIFT_SILOPTIMIZER_ANALYSIS_PROGRAMTERMINATIONANALYSIS_H + +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "llvm/ADT/SmallPtrSet.h" + +namespace swift { + +class ProgramTerminationFunctionInfo { + llvm::SmallPtrSet ProgramTerminatingBlocks; + +public: + ProgramTerminationFunctionInfo(const SILFunction *F) { + for (const auto &BB : *F) { + if (!isARCInertTrapBB(&BB)) + continue; + ProgramTerminatingBlocks.insert(&BB); + } + } + + bool isProgramTerminatingBlock(const SILBasicBlock *BB) const { + return ProgramTerminatingBlocks.count(BB); + } +}; + +} // end swift namespace + +#endif diff --git a/lib/SILPasses/ARC/RCStateTransition.cpp b/lib/SILOptimizer/ARC/RCStateTransition.cpp similarity index 98% rename from lib/SILPasses/ARC/RCStateTransition.cpp rename to lib/SILOptimizer/ARC/RCStateTransition.cpp index 9a593cec1708f..96ab4ed67cde2 100644 --- a/lib/SILPasses/ARC/RCStateTransition.cpp +++ b/lib/SILOptimizer/ARC/RCStateTransition.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-global-arc-opts" +#define DEBUG_TYPE "arc-sequence-opts" #include "RCStateTransition.h" #include "swift/Basic/Fallthrough.h" diff --git a/lib/SILPasses/ARC/RCStateTransition.def b/lib/SILOptimizer/ARC/RCStateTransition.def similarity index 93% rename from lib/SILPasses/ARC/RCStateTransition.def rename to lib/SILOptimizer/ARC/RCStateTransition.def index 6124c2376dbb4..7e1d01faf10c6 100644 --- a/lib/SILPasses/ARC/RCStateTransition.def +++ b/lib/SILOptimizer/ARC/RCStateTransition.def @@ -1,8 +1,8 @@ -//===--- RCStateTransition.def -------------------------------*- C++ -*----===// +//===--- RCStateTransition.def ----------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SILPasses/ARC/RCStateTransition.h b/lib/SILOptimizer/ARC/RCStateTransition.h similarity index 94% rename from lib/SILPasses/ARC/RCStateTransition.h rename to lib/SILOptimizer/ARC/RCStateTransition.h index ed32e4067e201..eb7f37ef20170 100644 --- a/lib/SILPasses/ARC/RCStateTransition.h +++ b/lib/SILOptimizer/ARC/RCStateTransition.h @@ -1,8 +1,8 @@ -//===--- RCStateTransition.h -------------------------------*- C++ -*------===// +//===--- RCStateTransition.h ------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_ARC_RCSTATETRANSITION_H -#define SWIFT_SILPASSES_ARC_RCSTATETRANSITION_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_RCSTATETRANSITION_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_RCSTATETRANSITION_H #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILInstruction.h" diff --git a/lib/SILPasses/ARC/RCStateTransitionVisitors.cpp b/lib/SILOptimizer/ARC/RCStateTransitionVisitors.cpp similarity index 96% rename from lib/SILPasses/ARC/RCStateTransitionVisitors.cpp rename to lib/SILOptimizer/ARC/RCStateTransitionVisitors.cpp index 4239196bc9951..dabe1b3dc3924 100644 --- a/lib/SILPasses/ARC/RCStateTransitionVisitors.cpp +++ b/lib/SILOptimizer/ARC/RCStateTransitionVisitors.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,11 +10,11 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-global-arc-opts" +#define DEBUG_TYPE "arc-sequence-opts" #include "RCStateTransitionVisitors.h" #include "ARCBBState.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" #include "llvm/Support/Debug.h" using namespace swift; @@ -71,7 +71,11 @@ BottomUpDataflowRCStateVisitor::visitStrongDecrement(ValueBase *V) { // If we are running with 'frozen' owned arg releases, check if we have a // frozen use in the side table. If so, this release must be known safe. if (FreezeOwnedArgEpilogueReleases) { - State.updateKnownSafe(EpilogueReleaseMatcher.argumentHasRelease(Op)); + if (auto *OwnedRelease = EpilogueReleaseMatcher.releaseForArgument(Op)) { + if (I != OwnedRelease) { + State.updateKnownSafe(true); + } + } } DEBUG(llvm::dbgs() << " REF COUNT DECREMENT! Known Safe: " diff --git a/lib/SILPasses/ARC/RCStateTransitionVisitors.h b/lib/SILOptimizer/ARC/RCStateTransitionVisitors.h similarity index 96% rename from lib/SILPasses/ARC/RCStateTransitionVisitors.h rename to lib/SILOptimizer/ARC/RCStateTransitionVisitors.h index 082863d534cf6..d979777ae4b2f 100644 --- a/lib/SILPasses/ARC/RCStateTransitionVisitors.h +++ b/lib/SILOptimizer/ARC/RCStateTransitionVisitors.h @@ -1,8 +1,8 @@ -//===--- RCStateTransitionVisitors.h -------------------------*- C++ -*----===// +//===--- RCStateTransitionVisitors.h ----------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,8 +16,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_ARC_RCSTATETRANSITIONVISITORS_H -#define SWIFT_SILPASSES_ARC_RCSTATETRANSITIONVISITORS_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_RCSTATETRANSITIONVISITORS_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_RCSTATETRANSITIONVISITORS_H #include "ARCBBState.h" #include "ARCRegionState.h" diff --git a/lib/SILPasses/ARC/RefCountState.cpp b/lib/SILOptimizer/ARC/RefCountState.cpp similarity index 93% rename from lib/SILPasses/ARC/RefCountState.cpp rename to lib/SILOptimizer/ARC/RefCountState.cpp index e638034e44e36..f385f64925dff 100644 --- a/lib/SILPasses/ARC/RefCountState.cpp +++ b/lib/SILOptimizer/ARC/RefCountState.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-global-arc-opts" +#define DEBUG_TYPE "arc-sequence-opts" #include "RefCountState.h" #include "RCStateTransition.h" #include "llvm/Support/Debug.h" @@ -96,7 +96,7 @@ bool BottomUpRefCountState::initWithMutatorInst(SILInstruction *I) { // since we will not move non-arc instructions. KnownSafe |= FoundNonARCUser; - // Set our lattice state to be incremented. + // Set our lattice state to be decremented. LatState = LatticeState::Decremented; return NestingDetected; @@ -117,7 +117,7 @@ bool BottomUpRefCountState::mightRemoveMutators() { /// Uninitialize the current state. void BottomUpRefCountState::clear() { - // If we can not conservatively prove that the given RefCountState will not + // If we cannot conservatively prove that the given RefCountState will not // be removed, be conservative and clear the transition state, so we do not // propagate KnownSafety forward. if (mightRemoveMutators()) @@ -154,8 +154,7 @@ bool BottomUpRefCountState::valueCanBeDecrementedGivenLatticeState() const { /// If advance the state's sequence appropriately for a decrement. If we do /// advance return true. Otherwise return false. -bool BottomUpRefCountState:: -handleDecrement(SILInstruction *PotentialDecrement) { +bool BottomUpRefCountState::handleDecrement() { switch (LatState) { case LatticeState::MightBeUsed: LatState = LatticeState::MightBeDecremented; @@ -182,19 +181,11 @@ bool BottomUpRefCountState::valueCanBeUsedGivenLatticeState() const { /// Given the current lattice state, if we have seen a use, advance the /// lattice state. Return true if we do so and false otherwise. -bool BottomUpRefCountState::handleUser(SILInstruction *PotentialUser, - ArrayRef NewInsertPts, +bool BottomUpRefCountState::handleUser(ArrayRef NewInsertPts, SILValue RCIdentity, AliasAnalysis *AA) { assert(valueCanBeUsedGivenLatticeState() && "Must be able to be used at this point of the lattice."); - // Instructions that we do not recognize (and thus will not move) and that - // *must* use RCIdentity, implies we are always known safe as long as meet - // over all path constraints are satisfied. - if (isRCStateTransitionUnknown(PotentialUser)) - if (mustUseValue(PotentialUser, RCIdentity, AA)) - FoundNonARCUser = true; - // Advance the sequence... switch (LatState) { case LatticeState::Decremented: @@ -227,19 +218,11 @@ valueCanBeGuaranteedUsedGivenLatticeState() const { /// Given the current lattice state, if we have seen a use, advance the /// lattice state. Return true if we do so and false otherwise. bool BottomUpRefCountState::handleGuaranteedUser( - SILInstruction *PotentialGuaranteedUser, ArrayRef NewInsertPts, SILValue RCIdentity, AliasAnalysis *AA) { assert(valueCanBeGuaranteedUsedGivenLatticeState() && "Must be able to be used at this point of the lattice."); - // Instructions that we do not recognize (and thus will not move) and that - // *must* use RCIdentity, implies we are always known safe as long as meet - // over all path constraints are satisfied. - if (isRCStateTransitionUnknown(PotentialGuaranteedUser)) - if (mustUseValue(PotentialGuaranteedUser, RCIdentity, AA)) - FoundNonARCUser = true; - // Advance the sequence... switch (LatState) { // If were decremented, insert the insertion point. @@ -368,14 +351,20 @@ bool BottomUpRefCountState::handlePotentialGuaranteedUser( if (!valueCanBeGuaranteedUsedGivenLatticeState()) return false; - // If we can prove that Other can not use the pointer we are tracking, + // If we can prove that Other cannot use the pointer we are tracking, // return... if (!mayGuaranteedUseValue(PotentialGuaranteedUser, getRCRoot(), AA)) return false; + // Instructions that we do not recognize (and thus will not move) and that + // *must* use RCIdentity, implies we are always known safe as long as meet + // over all path constraints are satisfied. + if (isRCStateTransitionUnknown(PotentialGuaranteedUser)) + if (mustUseValue(PotentialGuaranteedUser, getRCRoot(), AA)) + FoundNonARCUser = true; + // Otherwise, update the ref count state given the guaranteed user. - return handleGuaranteedUser(PotentialGuaranteedUser, InsertPt, getRCRoot(), - AA); + return handleGuaranteedUser(InsertPt, getRCRoot(), AA); } /// Check if PotentialDecrement can decrement the reference count associated @@ -395,14 +384,14 @@ bool BottomUpRefCountState::handlePotentialDecrement( if (!valueCanBeDecrementedGivenLatticeState()) return false; - // If we can prove that Other can not use the pointer we are tracking, + // If we can prove that Other cannot use the pointer we are tracking, // return... if (!mayDecrementRefCount(PotentialDecrement, getRCRoot(), AA)) return false; // Otherwise, allow the CRTP substruct to update itself given we have a // potential decrement. - return handleDecrement(PotentialDecrement); + return handleDecrement(); } // Check if PotentialUser could be a use of the reference counted value that @@ -427,7 +416,14 @@ bool BottomUpRefCountState::handlePotentialUser( if (!mayUseValue(PotentialUser, getRCRoot(), AA)) return false; - return handleUser(PotentialUser, InsertPts, getRCRoot(), AA); + // Instructions that we do not recognize (and thus will not move) and that + // *must* use RCIdentity, implies we are always known safe as long as meet + // over all path constraints are satisfied. + if (isRCStateTransitionUnknown(PotentialUser)) + if (mustUseValue(PotentialUser, getRCRoot(), AA)) + FoundNonARCUser = true; + + return handleUser(InsertPts, getRCRoot(), AA); } void BottomUpRefCountState::updateForSameLoopInst(SILInstruction *I, @@ -475,7 +471,7 @@ void BottomUpRefCountState::updateForDifferentLoopInst( mayDecrementRefCount(I, getRCRoot(), AA)) { DEBUG(llvm::dbgs() << " Found potential guaranteed use:\n " << getRCRoot()); - handleGuaranteedUser(I, InsertPts, getRCRoot(), AA); + handleGuaranteedUser(InsertPts, getRCRoot(), AA); return; } } @@ -488,6 +484,40 @@ void BottomUpRefCountState::updateForDifferentLoopInst( DEBUG(llvm::dbgs() << " Found Potential Use:\n " << getRCRoot()); } +void BottomUpRefCountState::updateForPredTerminators( + ArrayRef Terms, SILInstruction *InsertPt, + AliasAnalysis *AA) { + // If this state is not tracking anything, there is nothing to update. + if (!isTrackingRefCount()) + return; + + if (valueCanBeGuaranteedUsedGivenLatticeState() && + std::any_of(Terms.begin(), Terms.end(), + [this, &AA](SILInstruction *I) -> bool { + return mayGuaranteedUseValue(I, getRCRoot(), AA); + })) { + handleGuaranteedUser(InsertPt, getRCRoot(), AA); + return; + } + + if (valueCanBeDecrementedGivenLatticeState() && + std::any_of(Terms.begin(), Terms.end(), + [this, &AA](SILInstruction *I) -> bool { + return mayDecrementRefCount(I, getRCRoot(), AA); + })) { + handleDecrement(); + return; + } + + if (!valueCanBeUsedGivenLatticeState() || + std::none_of(Terms.begin(), Terms.end(), + [this, &AA](SILInstruction *I) + -> bool { return mayUseValue(I, getRCRoot(), AA); })) + return; + + handleUser(InsertPt, getRCRoot(), AA); +} + //===----------------------------------------------------------------------===// // Top Down Ref Count State //===----------------------------------------------------------------------===// @@ -543,7 +573,7 @@ void TopDownRefCountState::clear() { SuperTy::clear(); } -/// Can we gaurantee that the given reference counted value has been modified? +/// Can we guarantee that the given reference counted value has been modified? bool TopDownRefCountState::isRefCountStateModified() const { switch (LatState) { case LatticeState::Incremented: @@ -765,7 +795,7 @@ bool TopDownRefCountState::handlePotentialGuaranteedUser( if (!valueCanBeGuaranteedUsedGivenLatticeState()) return false; - // If we can prove that Other can not use the pointer we are tracking, + // If we can prove that Other cannot use the pointer we are tracking, // return... if (!mayGuaranteedUseValue(PotentialGuaranteedUser, getRCRoot(), AA)) return false; @@ -793,7 +823,7 @@ bool TopDownRefCountState::handlePotentialDecrement( if (!valueCanBeDecrementedGivenLatticeState()) return false; - // If we can prove that Other can not use the pointer we are tracking, + // If we can prove that Other cannot use the pointer we are tracking, // return... if (!mayDecrementRefCount(PotentialDecrement, getRCRoot(), AA)) return false; diff --git a/lib/SILPasses/ARC/RefCountState.h b/lib/SILOptimizer/ARC/RefCountState.h similarity index 94% rename from lib/SILPasses/ARC/RefCountState.h rename to lib/SILOptimizer/ARC/RefCountState.h index c567dae424fb6..438db61b7c8e7 100644 --- a/lib/SILPasses/ARC/RefCountState.h +++ b/lib/SILOptimizer/ARC/RefCountState.h @@ -1,8 +1,8 @@ -//===--- RefCountState.h - Represents a Reference Count -----*- C++ -*-----===// +//===--- RefCountState.h - Represents a Reference Count ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,15 +10,15 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_ARC_REFCOUNTSTATE_H -#define SWIFT_SILPASSES_ARC_REFCOUNTSTATE_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_REFCOUNTSTATE_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_REFCOUNTSTATE_H #include "RCStateTransition.h" #include "swift/Basic/Fallthrough.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBasicBlock.h" -#include "swift/SILAnalysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" #include namespace swift { @@ -57,7 +57,7 @@ class RefCountState { /// semantics. InstructionSet InsertPts; - /// Have we performed any partial merges of insertion points? We can not + /// Have we performed any partial merges of insertion points? We cannot /// perform two partial merges in a row unless we are able to reason about /// control dependency (which avoid for now). bool Partial = false; @@ -176,7 +176,7 @@ class BottomUpRefCountState : public RefCountState { MightBeUsed, ///< The pointer will be used and then at this point /// be decremented MightBeDecremented, ///< The pointer might be decremented again implying - /// that we can not, without being known safe remove + /// that we cannot, without being known safe remove /// this decrement. }; @@ -219,6 +219,11 @@ class BottomUpRefCountState : public RefCountState { ArrayRef InsertPts, AliasAnalysis *AA); + // Determine the conservative effect of the given list of predecessor + // terminators upon this reference count. + void updateForPredTerminators(ArrayRef PredTerms, + SILInstruction *InsertPt, AliasAnalysis *AA); + /// Attempt to merge \p Other into this ref count state. Return true if we /// succeed and false otherwise. bool merge(const BottomUpRefCountState &Other); @@ -237,7 +242,7 @@ class BottomUpRefCountState : public RefCountState { /// perform the dataflow it may change value. bool mightRemoveMutators(); - /// Can we gaurantee that the given reference counted value has been modified? + /// Can we guarantee that the given reference counted value has been modified? bool isRefCountStateModified() const; /// Returns true if given the current lattice state, do we care if the value @@ -246,7 +251,7 @@ class BottomUpRefCountState : public RefCountState { /// If advance the state's sequence appropriately for a decrement. If we do /// advance return true. Otherwise return false. - bool handleDecrement(SILInstruction *PotentialDecrement); + bool handleDecrement(); /// Check if PotentialDecrement can decrement the reference count associated /// with the value we are tracking. If so advance the state's sequence @@ -261,8 +266,7 @@ class BottomUpRefCountState : public RefCountState { /// lattice state. Return true if we do so and false otherwise. \p InsertPt is /// the location where if \p PotentialUser is a user of this ref count, we /// would insert a release. - bool handleUser(SILInstruction *PotentialUser, - ArrayRef InsertPt, SILValue RCIdentity, + bool handleUser(ArrayRef InsertPt, SILValue RCIdentity, AliasAnalysis *AA); /// Check if PotentialUser could be a use of the reference counted value that @@ -280,8 +284,7 @@ class BottomUpRefCountState : public RefCountState { /// lattice state. Return true if we do so and false otherwise. \p InsertPt is /// the location where if \p PotentialUser is a user of this ref count, we /// would insert a release. - bool handleGuaranteedUser(SILInstruction *PotentialGuaranteedUser, - ArrayRef InsertPts, + bool handleGuaranteedUser(ArrayRef InsertPts, SILValue RCIdentity, AliasAnalysis *AA); /// Check if PotentialGuaranteedUser can use the reference count associated @@ -366,7 +369,7 @@ class TopDownRefCountState : public RefCountState { bool merge(const TopDownRefCountState &Other); private: - /// Can we gaurantee that the given reference counted value has been modified? + /// Can we guarantee that the given reference counted value has been modified? bool isRefCountStateModified() const; /// Returns true if given the current lattice state, do we care if the value diff --git a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp new file mode 100644 index 0000000000000..5a4d5ea063a27 --- /dev/null +++ b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp @@ -0,0 +1,710 @@ +//===--- ARCAnalysis.cpp - SIL ARC Analysis -------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-arc-analysis" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/Basic/Fallthrough.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +//===----------------------------------------------------------------------===// +// Decrement Analysis +//===----------------------------------------------------------------------===// + +bool swift::mayDecrementRefCount(SILInstruction *User, + SILValue Ptr, AliasAnalysis *AA) { + // First do a basic check, mainly based on the type of instruction. + // Reading the RC is as "bad" as releasing. + if (!User->mayReleaseOrReadRefCount()) + return false; + + // Ok, this instruction may have ref counts. If it is an apply, attempt to + // prove that the callee is unable to affect Ptr. + if (auto *AI = dyn_cast(User)) + return AA->canApplyDecrementRefCount(AI, Ptr); + if (auto *TAI = dyn_cast(User)) + return AA->canApplyDecrementRefCount(TAI, Ptr); + if (auto *BI = dyn_cast(User)) + return AA->canBuiltinDecrementRefCount(BI, Ptr); + + // We cannot conservatively prove that this instruction cannot decrement the + // ref count of Ptr. So assume that it does. + return true; +} + +bool swift::mayCheckRefCount(SILInstruction *User) { + return isa(User) || isa(User); +} + +//===----------------------------------------------------------------------===// +// Use Analysis +//===----------------------------------------------------------------------===// + +/// Returns true if a builtin apply cannot use reference counted values. +/// +/// The main case that this handles here are builtins that via read none imply +/// that they cannot read globals and at the same time do not take any +/// non-trivial types via the arguments. The reason why we care about taking +/// non-trivial types as arguments is that we want to be careful in the face of +/// intrinsics that may be equivalent to bitcast and inttoptr operations. +static bool canApplyOfBuiltinUseNonTrivialValues(BuiltinInst *BInst) { + SILModule &Mod = BInst->getModule(); + + auto &II = BInst->getIntrinsicInfo(); + if (II.ID != llvm::Intrinsic::not_intrinsic) { + if (II.hasAttribute(llvm::Attribute::ReadNone)) { + for (auto &Op : BInst->getAllOperands()) { + if (!Op.get().getType().isTrivial(Mod)) { + return false; + } + } + } + + return true; + } + + auto &BI = BInst->getBuiltinInfo(); + if (BI.isReadNone()) { + for (auto &Op : BInst->getAllOperands()) { + if (!Op.get().getType().isTrivial(Mod)) { + return false; + } + } + } + + return true; +} + +/// Returns true if Inst is a function that we know never uses ref count values. +bool swift::canNeverUseValues(SILInstruction *Inst) { + switch (Inst->getKind()) { + // These instructions do not use other values. + case ValueKind::FunctionRefInst: + case ValueKind::IntegerLiteralInst: + case ValueKind::FloatLiteralInst: + case ValueKind::StringLiteralInst: + case ValueKind::AllocStackInst: + case ValueKind::AllocRefInst: + case ValueKind::AllocRefDynamicInst: + case ValueKind::AllocBoxInst: + case ValueKind::MetatypeInst: + case ValueKind::WitnessMethodInst: + return true; + + // DeallocStackInst do not use reference counted values. + case ValueKind::DeallocStackInst: + return true; + + // Debug values do not use referenced counted values in a manner we care + // about. + case ValueKind::DebugValueInst: + case ValueKind::DebugValueAddrInst: + return true; + + // Casts do not use pointers in a manner that we care about since we strip + // them during our analysis. The reason for this is if the cast is not dead + // then there must be some other use after the cast that we will protect if a + // release is not in between the cast and the use. + case ValueKind::UpcastInst: + case ValueKind::AddressToPointerInst: + case ValueKind::PointerToAddressInst: + case ValueKind::UncheckedRefCastInst: + case ValueKind::UncheckedRefCastAddrInst: + case ValueKind::UncheckedAddrCastInst: + case ValueKind::RefToRawPointerInst: + case ValueKind::RawPointerToRefInst: + case ValueKind::UnconditionalCheckedCastInst: + case ValueKind::UncheckedBitwiseCastInst: + return true; + + // If we have a trivial bit cast between trivial types, it is not something + // that can use ref count ops in a way we care about. We do need to be careful + // with uses with ref count inputs. In such a case, we assume conservatively + // that the bit cast could use it. + // + // The reason why this is different from the ref bitcast is b/c the use of a + // ref bit cast is still a ref typed value implying that our ARC dataflow will + // properly handle its users. A conversion of a reference count value to a + // trivial value though could be used as a trivial value in ways that ARC + // dataflow will not understand implying we need to treat it as a use to be + // safe. + case ValueKind::UncheckedTrivialBitCastInst: { + SILValue Op = cast(Inst)->getOperand(); + return Op.getType().isTrivial(Inst->getModule()); + } + + // Typed GEPs do not use pointers. The user of the typed GEP may but we will + // catch that via the dataflow. + case ValueKind::StructExtractInst: + case ValueKind::TupleExtractInst: + case ValueKind::StructElementAddrInst: + case ValueKind::TupleElementAddrInst: + case ValueKind::UncheckedTakeEnumDataAddrInst: + case ValueKind::RefElementAddrInst: + case ValueKind::UncheckedEnumDataInst: + case ValueKind::IndexAddrInst: + case ValueKind::IndexRawPointerInst: + return true; + + // Aggregate formation by themselves do not create new uses since it is their + // users that would create the appropriate uses. + case ValueKind::EnumInst: + case ValueKind::StructInst: + case ValueKind::TupleInst: + return true; + + // Only uses non reference counted values. + case ValueKind::CondFailInst: + return true; + + case ValueKind::BuiltinInst: { + auto *BI = cast(Inst); + + // Certain builtin function refs we know can never use non-trivial values. + return canApplyOfBuiltinUseNonTrivialValues(BI); + } + // We do not care about branch inst, since if the branch inst's argument is + // dead, LLVM will clean it up. + case ValueKind::BranchInst: + case ValueKind::CondBranchInst: + return true; + default: + return false; + } +} + +static bool doOperandsAlias(ArrayRef Ops, SILValue Ptr, + AliasAnalysis *AA) { + // If any are not no alias, we have a use. + return std::any_of(Ops.begin(), Ops.end(), + [&AA, &Ptr](const Operand &Op) -> bool { + return !AA->isNoAlias(Ptr, Op.get()); + }); +} + +static bool canTerminatorUseValue(TermInst *TI, SILValue Ptr, + AliasAnalysis *AA) { + if (auto *BI = dyn_cast(TI)) { + return doOperandsAlias(BI->getAllOperands(), Ptr, AA); + } + + if (auto *CBI = dyn_cast(TI)) { + bool First = doOperandsAlias(CBI->getTrueOperands(), Ptr, AA); + bool Second = doOperandsAlias(CBI->getFalseOperands(), Ptr, AA); + return First || Second; + } + + if (auto *SWEI = dyn_cast(TI)) { + return doOperandsAlias(SWEI->getAllOperands(), Ptr, AA); + } + + if (auto *SWVI = dyn_cast(TI)) { + return doOperandsAlias(SWVI->getAllOperands(), Ptr, AA); + } + + auto *CCBI = dyn_cast(TI); + // If we don't have this last case, be conservative and assume that we can use + // the value. + if (!CCBI) + return true; + + // Otherwise, look at the operands. + return doOperandsAlias(CCBI->getAllOperands(), Ptr, AA); +} + +bool swift::mayUseValue(SILInstruction *User, SILValue Ptr, + AliasAnalysis *AA) { + // If Inst is an instruction that we know can never use values with reference + // semantics, return true. + if (canNeverUseValues(User)) + return false; + + // If the user is a load or a store and we can prove that it does not access + // the object then return true. + // Notice that we need to check all of the values of the object. + if (isa(User)) { + for (int i = 0, e = Ptr->getNumTypes(); i < e; i++) { + if (AA->mayWriteToMemory(User, SILValue(Ptr.getDef(), i))) + return true; + } + return false; + } + + if (isa(User) ) { + for (int i = 0, e = Ptr->getNumTypes(); i < e; i++) { + if (AA->mayReadFromMemory(User, SILValue(Ptr.getDef(), i))) + return true; + } + return false; + } + + // If we have a terminator instruction, see if it can use ptr. This currently + // means that we first show that TI cannot indirectly use Ptr and then use + // alias analysis on the arguments. + if (auto *TI = dyn_cast(User)) + return canTerminatorUseValue(TI, Ptr, AA); + + // TODO: If we add in alias analysis support here for apply inst, we will need + // to check that the pointer does not escape. + + // Otherwise, assume that Inst can use Target. + return true; +} + +//===----------------------------------------------------------------------===// +// Must Use Analysis +//===----------------------------------------------------------------------===// + +/// Returns true if User must use Ptr. +/// +/// In terms of ARC this means that if we do not remove User, all releases post +/// dominated by User are known safe. +bool swift::mustUseValue(SILInstruction *User, SILValue Ptr, + AliasAnalysis *AA) { + // Right now just pattern match applies. + auto *AI = dyn_cast(User); + if (!AI) + return false; + + // If any of AI's arguments must alias Ptr, return true. + for (SILValue Arg : AI->getArguments()) + if (AA->isMustAlias(Arg, Ptr)) + return true; + return false; +} + +/// Returns true if User must use Ptr in a guaranteed way. +/// +/// This means that assuming that everything is conservative, we can ignore the +/// ref count effects of User on Ptr since we will only remove things over +/// guaranteed parameters if we are known safe in both directions. +bool swift::mustGuaranteedUseValue(SILInstruction *User, SILValue Ptr, + AliasAnalysis *AA) { + // Right now just pattern match applies. + auto *AI = dyn_cast(User); + if (!AI) + return false; + + // For now just look for guaranteed self. + // + // TODO: Expand this to handle *any* guaranteed parameter. + if (!AI->hasGuaranteedSelfArgument()) + return false; + + // Return true if Ptr alias's self. + return AA->isMustAlias(AI->getSelfArgument(), Ptr); +} + +//===----------------------------------------------------------------------===// +// Utility Methods for determining use, decrement of values in a contiguous +// instruction range in one BB. +//===----------------------------------------------------------------------===// + +/// If \p Op has arc uses in the instruction range [Start, End), return the +/// first such instruction. Otherwise return None. We assume that +/// Start and End are both in the same basic block. +Optional +swift:: +valueHasARCUsesInInstructionRange(SILValue Op, + SILBasicBlock::iterator Start, + SILBasicBlock::iterator End, + AliasAnalysis *AA) { + assert(Start->getParent() == End->getParent() && + "Start and End should be in the same basic block"); + + // If Start == End, then we have an empty range, return false. + if (Start == End) + return None; + + // Otherwise, until Start != End. + while (Start != End) { + // Check if Start can use Op in an ARC relevant way. If so, return true. + if (mayUseValue(&*Start, Op, AA)) + return Start; + + // Otherwise, increment our iterator. + ++Start; + } + + // If all such instructions cannot use Op, return false. + return None; +} + +/// If \p Op has arc uses in the instruction range (Start, End], return the +/// first such instruction. Otherwise return None. We assume that Start and End +/// are both in the same basic block. +Optional +swift::valueHasARCUsesInReverseInstructionRange(SILValue Op, + SILBasicBlock::iterator Start, + SILBasicBlock::iterator End, + AliasAnalysis *AA) { + assert(Start->getParent() == End->getParent() && + "Start and End should be in the same basic block"); + assert(End != End->getParent()->end() && + "End should be mapped to an actual instruction"); + + // If Start == End, then we have an empty range, return false. + if (Start == End) + return None; + + // Otherwise, until End == Start. + while (Start != End) { + // Check if Start can use Op in an ARC relevant way. If so, return true. + if (mayUseValue(&*End, Op, AA)) + return End; + + // Otherwise, decrement our iterator. + --End; + } + + // If all such instructions cannot use Op, return false. + return None; +} + +/// If \p Op has instructions in the instruction range (Start, End] which may +/// decrement it, return the first such instruction. Returns None +/// if no such instruction exists. We assume that Start and End are both in the +/// same basic block. +Optional +swift:: +valueHasARCDecrementOrCheckInInstructionRange(SILValue Op, + SILBasicBlock::iterator Start, + SILBasicBlock::iterator End, + AliasAnalysis *AA) { + assert(Start->getParent() == End->getParent() && + "Start and End should be in the same basic block"); + + // If Start == End, then we have an empty range, return nothing. + if (Start == End) + return None; + + // Otherwise, until Start != End. + while (Start != End) { + // Check if Start can decrement or check Op's ref count. If so, return + // Start. Ref count checks do not have side effects, but are barriers for + // retains. + if (mayDecrementRefCount(&*Start, Op, AA) || mayCheckRefCount(&*Start)) + return Start; + // Otherwise, increment our iterator. + ++Start; + } + + // If all such instructions cannot decrement Op, return nothing. + return None; +} + +bool +swift:: +mayGuaranteedUseValue(SILInstruction *User, SILValue Ptr, AliasAnalysis *AA) { + // Only full apply sites can require a guaranteed lifetime. If we don't have + // one, bail. + if (!isa(User)) + return false; + + FullApplySite FAS(User); + + // Ok, we have a full apply site. If the apply has no arguments, we don't need + // to worry about any guaranteed parameters. + if (!FAS.getNumArguments()) + return false; + + // Ok, we have an apply site with arguments. Look at the function type and + // iterate through the function parameters. If any of the parameters are + // guaranteed, attempt to prove that the passed in parameter cannot alias + // Ptr. If we fail, return true. + CanSILFunctionType FType = FAS.getSubstCalleeType(); + auto Params = FType->getParameters(); + for (unsigned i : indices(Params)) { + if (!Params[i].isGuaranteed()) + continue; + SILValue Op = FAS.getArgument(i); + for (int i = 0, e = Ptr->getNumTypes(); i < e; i++) + if (!AA->isNoAlias(Op, SILValue(Ptr.getDef(), i))) + return true; + } + + // Ok, we were able to prove that all arguments to the apply that were + // guaranteed do not alias Ptr. Return false. + return false; +} + +//===----------------------------------------------------------------------===// +// Utilities for recognizing trap BBs that are ARC inert +//===----------------------------------------------------------------------===// + + +//===----------------------------------------------------------------------===// +// Owned Argument Utilities +//===----------------------------------------------------------------------===// + +ConsumedArgToEpilogueReleaseMatcher::ConsumedArgToEpilogueReleaseMatcher( + RCIdentityFunctionInfo *RCFI, SILFunction *F, ExitKind Kind) + : F(F), RCFI(RCFI), Kind(Kind) { + recompute(); +} + +void ConsumedArgToEpilogueReleaseMatcher::recompute() { + ArgInstMap.clear(); + + // Find the return BB of F. If we fail, then bail. + SILFunction::iterator BB; + switch (Kind) { + case ExitKind::Return: + BB = F->findReturnBB(); + break; + case ExitKind::Throw: + BB = F->findThrowBB(); + break; + } + + if (BB == F->end()) { + HasBlock = false; + return; + } + HasBlock = true; + findMatchingReleases(&*BB); +} + +void ConsumedArgToEpilogueReleaseMatcher::findMatchingReleases( + SILBasicBlock *BB) { + for (auto II = std::next(BB->rbegin()), IE = BB->rend(); + II != IE; ++II) { + // If we do not have a release_value or strong_release... + if (!isa(*II) && !isa(*II)) { + // And the object cannot use values in a manner that will keep the object + // alive, continue. We may be able to find additional releases. + if (canNeverUseValues(&*II)) + continue; + + // Otherwise, we need to stop computing since we do not want to reduce the + // lifetime of objects. + return; + } + + // Ok, we have a release_value or strong_release. Grab Target and find the + // RC identity root of its operand. + SILInstruction *Target = &*II; + SILValue Op = RCFI->getRCIdentityRoot(Target->getOperand(0)); + + // If Op is not a consumed argument, we must break since this is not an Op + // that is a part of a return sequence. We are being conservative here since + // we could make this more general by allowing for intervening non-arg + // releases in the sense that we do not allow for race conditions in between + // destructors. + auto *Arg = dyn_cast(Op); + if (!Arg || !Arg->isFunctionArg() || + !Arg->hasConvention(ParameterConvention::Direct_Owned)) + return; + + // Ok, we have a release on a SILArgument that is direct owned. Attempt to + // put it into our arc opts map. If we already have it, we have exited the + // return value sequence so break. Otherwise, continue looking for more arc + // operations. + if (!ArgInstMap.insert({Arg, Target}).second) + return; + } +} + +//===----------------------------------------------------------------------===// +// Code for Determining Final Releases +//===----------------------------------------------------------------------===// + +// Propagate liveness backwards from an initial set of blocks in our +// LiveIn set. +static void propagateLiveness(llvm::SmallPtrSetImpl &LiveIn, + SILBasicBlock *DefBB) { + // First populate a worklist of predecessors. + llvm::SmallVector Worklist; + for (auto *BB : LiveIn) + for (auto Pred : BB->getPreds()) + Worklist.push_back(Pred); + + // Now propagate liveness backwards until we hit the alloc_box. + while (!Worklist.empty()) { + auto *BB = Worklist.pop_back_val(); + + // If it's already in the set, then we've already queued and/or + // processed the predecessors. + if (BB == DefBB || !LiveIn.insert(BB).second) + continue; + + for (auto Pred : BB->getPreds()) + Worklist.push_back(Pred); + } +} + +// Is any successor of BB in the LiveIn set? +static bool successorHasLiveIn(SILBasicBlock *BB, + llvm::SmallPtrSetImpl &LiveIn) { + for (auto &Succ : BB->getSuccessors()) + if (LiveIn.count(Succ)) + return true; + + return false; +} + +// Walk backwards in BB looking for the last use of a given +// value, and add it to the set of release points. +static bool addLastUse(SILValue V, SILBasicBlock *BB, + ReleaseTracker &Tracker) { + for (auto I = BB->rbegin(); I != BB->rend(); ++I) { + for (auto &Op : I->getAllOperands()) + if (Op.get().getDef() == V.getDef()) { + Tracker.trackLastRelease(&*I); + return true; + } + } + + llvm_unreachable("BB is expected to have a use of a closure"); + return false; +} + +/// TODO: Refactor this code so the decision on whether or not to accept an +/// instruction. +bool swift::getFinalReleasesForValue(SILValue V, ReleaseTracker &Tracker) { + llvm::SmallPtrSet LiveIn; + llvm::SmallPtrSet UseBlocks; + + // First attempt to get the BB where this value resides. + auto *DefBB = V->getParentBB(); + if (!DefBB) + return false; + + bool seenRelease = false; + SILInstruction *OneRelease = nullptr; + + // We'll treat this like a liveness problem where the value is the def. Each + // block that has a use of the value has the value live-in unless it is the + // block with the value. + for (auto *UI : V.getUses()) { + auto *User = UI->getUser(); + auto *BB = User->getParent(); + + if (!Tracker.isUserAcceptable(User)) + return false; + Tracker.trackUser(User); + + if (BB != DefBB) + LiveIn.insert(BB); + + // Also keep track of the blocks with uses. + UseBlocks.insert(BB); + + // Try to speed up the trivial case of single release/dealloc. + if (isa(User) || isa(User)) { + if (!seenRelease) + OneRelease = User; + else + OneRelease = nullptr; + + seenRelease = true; + } + } + + // Only a single release/dealloc? We're done! + if (OneRelease) { + Tracker.trackLastRelease(OneRelease); + return true; + } + + propagateLiveness(LiveIn, DefBB); + + // Now examine each block we saw a use in. If it has no successors + // that are in LiveIn, then the last use in the block is the final + // release/dealloc. + for (auto *BB : UseBlocks) + if (!successorHasLiveIn(BB, LiveIn)) + if (!addLastUse(V, BB, Tracker)) + return false; + + return true; +} + +//===----------------------------------------------------------------------===// +// Leaking BB Analysis +//===----------------------------------------------------------------------===// + +static bool ignorableApplyInstInUnreachableBlock(const ApplyInst *AI) { + const auto *Fn = AI->getCalleeFunction(); + if (!Fn) + return false; + + return Fn->hasSemanticsAttr("arc.programtermination_point"); +} + +static bool ignorableBuiltinInstInUnreachableBlock(const BuiltinInst *BI) { + const BuiltinInfo &BInfo = BI->getBuiltinInfo(); + if (BInfo.ID == BuiltinValueKind::CondUnreachable) + return true; + + const IntrinsicInfo &IInfo = BI->getIntrinsicInfo(); + if (IInfo.ID == llvm::Intrinsic::trap) + return true; + + return false; +} + +/// Match a call to a trap BB with no ARC relevant side effects. +bool swift::isARCInertTrapBB(const SILBasicBlock *BB) { + // Do a quick check at the beginning to make sure that our terminator is + // actually an unreachable. This ensures that in many cases this function will + // exit early and quickly. + auto II = BB->rbegin(); + if (!isa(*II)) + return false; + + auto IE = BB->rend(); + while (II != IE) { + // Ignore any instructions without side effects. + if (!II->mayHaveSideEffects()) { + ++II; + continue; + } + + // Ignore cond fail. + if (isa(*II)) { + ++II; + continue; + } + + // Check for apply insts that we can ignore. + if (auto *AI = dyn_cast(&*II)) { + if (ignorableApplyInstInUnreachableBlock(AI)) { + ++II; + continue; + } + } + + // Check for builtins that we can ignore. + if (auto *BI = dyn_cast(&*II)) { + if (ignorableBuiltinInstInUnreachableBlock(BI)) { + ++II; + continue; + } + } + + // If we can't ignore the instruction, return false. + return false; + } + + // Otherwise, we have an unreachable and every instruction is inert from an + // ARC perspective in an unreachable BB. + return true; +} diff --git a/lib/SILAnalysis/AliasAnalysis.cpp b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp similarity index 82% rename from lib/SILAnalysis/AliasAnalysis.cpp rename to lib/SILOptimizer/Analysis/AliasAnalysis.cpp index 3fa3ce3c84c26..a5c47f945a97c 100644 --- a/lib/SILAnalysis/AliasAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/AliasAnalysis.cpp @@ -1,8 +1,8 @@ -//===-------------- AliasAnalysis.cpp - SIL Alias Analysis ----------------===// +//===--- AliasAnalysis.cpp - SIL Alias Analysis ---------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,11 +11,12 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-aa" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILAnalysis/SideEffectAnalysis.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/PassManager.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" +#include "swift/SILOptimizer/Analysis/EscapeAnalysis.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" #include "swift/SIL/Projection.h" #include "swift/SIL/SILValue.h" #include "swift/SIL/SILInstruction.h" @@ -28,6 +29,13 @@ using namespace swift; + +// The AliasAnalysis Cache must not grow beyond this size. +// We limit the size of the AA cache to 2**14 because we want to limit the +// memory usage of this cache. +static const int AliasAnalysisMaxCacheSize = 16384; + + //===----------------------------------------------------------------------===// // AA Debugging //===----------------------------------------------------------------------===// @@ -104,25 +112,19 @@ static bool isFunctionArgument(SILValue V) { return Arg->isFunctionArg(); } -/// A no alias argument is an argument that is an address type of the entry -/// basic block of a function. -static bool isNoAliasArgument(SILValue V) { - return isFunctionArgument(V) && V.getType().isAddress(); -} - /// Return true if V is an object that at compile time can be uniquely /// identified. static bool isIdentifiableObject(SILValue V) { if (isa(V) || isa(V)) return true; - if (isNoAliasArgument(V)) + if (isNotAliasingArgument(V)) return true; return false; } /// Return true if V1 and V2 are distinct objects that can be uniquely /// identified at compile time. -static bool areDistinctIdentifyableObjects(SILValue V1, SILValue V2) { +static bool areDistinctIdentifiableObjects(SILValue V1, SILValue V2) { // Do both values refer to the same global variable? if (auto *GA1 = dyn_cast(V1)) { if (auto *GA2 = dyn_cast(V2)) { @@ -148,7 +150,7 @@ static bool isSameValueOrGlobal(SILValue V1, SILValue V2) { return false; } -/// Is this a literal which we know can not refer to a global object? +/// Is this a literal which we know cannot refer to a global object? /// /// FIXME: function_ref? static bool isLocalLiteral(SILValue V) { @@ -165,65 +167,25 @@ static bool isLocalLiteral(SILValue V) { /// Is this a value that can be unambiguously identified as being defined at the /// function level. static bool isIdentifiedFunctionLocal(SILValue V) { - return isa(*V) || isNoAliasArgument(V) || isLocalLiteral(V); -} - -/// Returns true if V is a function argument that is not an address implying -/// that we do not have the gaurantee that it will not alias anything inside the -/// function. -static bool isAliasingFunctionArgument(SILValue V) { - return isFunctionArgument(V) && !V.getType().isAddress(); -} - -/// Returns true if V is an apply inst that may read or write to memory. -static bool isReadWriteApplyInst(SILValue V) { - // See if this is a normal function application. - if (auto *AI = dyn_cast(V)) { - return AI->mayReadOrWriteMemory(); - } - - // Next, see if this is a builtin. - if (auto *BI = dyn_cast(V)) { - return BI->mayReadOrWriteMemory(); - } - - // If we fail, bail... - return false; -} - -/// Return true if the pointer is one which would have been considered an escape -/// by isNonEscapingLocalObject. -static bool isEscapeSource(SILValue V) { - if (isReadWriteApplyInst(V)) - return true; - - if (isAliasingFunctionArgument(V)) - return true; - - // The LoadInst case works since valueMayBeCaptured always assumes stores are - // escapes. - if (isa(*V)) - return true; - - // We could not prove anything, be conservative and return false. - return false; + return isa(*V) || isNotAliasingArgument(V) || + isLocalLiteral(V); } /// Returns true if we can prove that the two input SILValues which do not equal -/// can not alias. +/// cannot alias. static bool aliasUnequalObjects(SILValue O1, SILValue O2) { assert(O1 != O2 && "This function should only be called on unequal values."); // If O1 and O2 do not equal and they are both values that can be statically - // and uniquely identified, they can not alias. - if (areDistinctIdentifyableObjects(O1, O2)) { + // and uniquely identified, they cannot alias. + if (areDistinctIdentifiableObjects(O1, O2)) { DEBUG(llvm::dbgs() << " Found two unequal identified " "objects.\n"); return true; } // Function arguments can't alias with things that are known to be - // unambigously identified at the function level. + // unambiguously identified at the function level. // // Note that both function arguments must be identified. For example, an @in // argument may be an interior pointer into a box that is passed separately as @@ -236,16 +198,6 @@ static bool aliasUnequalObjects(SILValue O1, SILValue O2) { return true; } - // If one pointer is the result of an apply or load and the other is a - // non-escaping local object within the same function, then we know the object - // couldn't escape to a point where the call could return it. - if ((isEscapeSource(O1) && isNonEscapingLocalObject(O2)) || - (isEscapeSource(O2) && isNonEscapingLocalObject(O1))) { - DEBUG(llvm::dbgs() << " Found unequal escape source and non " - "escaping local object!\n"); - return true; - } - // We failed to prove that the two objects are different. return false; } @@ -361,8 +313,8 @@ static bool isTypedAccessOracle(SILInstruction *I) { /// address is with pointer_to_address (via UnsafePointer) or /// unchecked_addr_cast (via Builtin.reinterpretCast). Consequently, if the /// given value is directly derived from a memory location, it cannot -/// alias. Call arguments also cannot alias because they must follow @in, @out, -/// @inout, or @in_guaranteed conventions. +/// alias. Call arguments also cannot alias because they must follow \@in, @out, +/// @inout, or \@in_guaranteed conventions. /// /// FIXME: pointer_to_address should contain a flag that indicates whether the /// address is aliasing. Currently, we aggressively assume that @@ -428,17 +380,17 @@ static bool typedAccessTBAABuiltinTypesMayAlias(SILType LTy, SILType RTy, // 2. (Pointer, Pointer): If we have two pointers to pointers, since we know // that the two values do not equal due to previous AA calculations, one must // be a native object and the other is an unknown object type (i.e. an objc - // object) which can not alias. + // object) which cannot alias. // // 3. (Scalar, Scalar): If we have two scalar pointers, since we know that the - // types are already not equal, we know that they can not alias. For those + // types are already not equal, we know that they cannot alias. For those // unfamiliar even though BuiltinIntegerType/BuiltinFloatType are single // classes, the AST represents each integer/float of different bit widths as // different types, so equality of SILTypes allows us to know that they have // different bit widths. // // Thus we can just return false since in none of the aforementioned cases we - // can not alias, so return false. + // cannot alias, so return false. return false; } @@ -458,7 +410,7 @@ static bool typedAccessTBAAMayAlias(SILType LTy, SILType RTy, SILModule &Mod) { // Typed access based TBAA only occurs on pointers. If we reach this point and // do not have a pointer, be conservative and return that the two types may - // alias. *NOTE* This ensures we return may alias for local_storage. + // alias. if(!LTy.isAddress() || !RTy.isAddress()) return true; @@ -513,7 +465,7 @@ static bool typedAccessTBAAMayAlias(SILType LTy, SILType RTy, SILModule &Mod) { // FIXME: All the code following could be made significantly more aggressive // by saying that aggregates of the same type that do not contain each other - // can not alias. + // cannot alias. // Tuples do not alias non-tuples. bool LTyTT = LTy.is(); @@ -570,9 +522,28 @@ bool AliasAnalysis::typesMayAlias(SILType T1, SILType T2) { /// The main AA entry point. Performs various analyses on V1, V2 in an attempt /// to disambiguate the two values. AliasResult AliasAnalysis::alias(SILValue V1, SILValue V2, - SILType TBAAType1, - SILType TBAAType2) { - return aliasInner(V1, V2, TBAAType1, TBAAType2); + SILType TBAAType1, SILType TBAAType2) { + AliasKeyTy Key = toAliasKey(V1, V2, TBAAType1, TBAAType2); + + // Check if we've already computed this result. + auto It = AliasCache.find(Key); + if (It != AliasCache.end()) { + return It->second; + } + + // Flush the cache if the size of the cache is too large. + if (AliasCache.size() > AliasAnalysisMaxCacheSize) { + AliasCache.clear(); + AliasValueBaseToIndex.clear(); + + // Key is no longer valid as we cleared the AliasValueBaseToIndex. + Key = toAliasKey(V1, V2, TBAAType1, TBAAType2); + } + + // Calculate the aliasing result and store it in the cache. + auto Result = aliasInner(V1, V2, TBAAType1, TBAAType2); + AliasCache[Key] = Result; + return Result; } /// The main AA entry point. Performs various analyses on V1, V2 in an attempt @@ -616,14 +587,26 @@ AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2, DEBUG(llvm::dbgs() << " Underlying V1:" << *O1.getDef()); DEBUG(llvm::dbgs() << " Underlying V2:" << *O2.getDef()); - // If O1 and O2 do not equal, see if we can prove that they can not be the + // If O1 and O2 do not equal, see if we can prove that they cannot be the // same object. If we can, return No Alias. if (O1 != O2 && aliasUnequalObjects(O1, O2)) return AliasResult::NoAlias; // Ok, either O1, O2 are the same or we could not prove anything based off of - // their inequality. Now we climb up use-def chains and attempt to do tricks - // based off of GEPs. + // their inequality. + // Next: ask escape analysis. This catches cases where we compare e.g. a + // non-escaping pointer with another (maybe escaping) pointer. Escape analysis + // uses the connection graph to check if the pointers may point to the same + // content. + // Note that escape analysis must work with the original pointers and not the + // underlying objects because it treats projections differently. + if (!EA->canPointToSameMemory(V1, V2)) { + DEBUG(llvm::dbgs() << " Found not-aliased objects based on" + "escape analysis\n"); + return AliasResult::NoAlias; + } + + // Now we climb up use-def chains and attempt to do tricks based off of GEPs. // First if one instruction is a gep and the other is not, canonicalize our // inputs so that V1 always is the instruction containing the GEP. @@ -645,6 +628,47 @@ AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2, return AliasResult::MayAlias; } +bool AliasAnalysis::canApplyDecrementRefCount(FullApplySite FAS, SILValue Ptr) { + // Treat applications of @noreturn functions as decrementing ref counts. This + // causes the apply to become a sink barrier for ref count increments. + if (FAS.getCallee().getType().getAs()->isNoReturn()) + return true; + + /// If the pointer cannot escape to the function we are done. + if (!EA->canEscapeTo(Ptr, FAS)) + return false; + + SideEffectAnalysis::FunctionEffects ApplyEffects; + SEA->getEffects(ApplyEffects, FAS); + + auto &GlobalEffects = ApplyEffects.getGlobalEffects(); + if (ApplyEffects.mayReadRC() || GlobalEffects.mayRelease()) + return true; + + /// The function has no unidentified releases, so let's look at the arguments + // in detail. + for (unsigned Idx = 0, End = FAS.getNumArguments(); Idx < End; ++Idx) { + auto &ArgEffect = ApplyEffects.getParameterEffects()[Idx]; + if (ArgEffect.mayRelease()) { + // The function may release this argument, so check if the pointer can + // escape to it. + if (EA->canEscapeToValue(Ptr, FAS.getArgument(Idx))) + return true; + } + } + return false; +} + +bool AliasAnalysis::canBuiltinDecrementRefCount(BuiltinInst *BI, SILValue Ptr) { + for (SILValue Arg : BI->getArguments()) { + // A builtin can only release an object if it can escape to one of the + // builtin's arguments. + if (EA->canEscapeToValue(Ptr, Arg)) + return true; + } + return false; +} + bool swift::isLetPointer(SILValue V) { // Traverse the "access" path for V and check that it starts with "let" // and everything along this path is a value-type (i.e. struct or tuple). @@ -673,11 +697,22 @@ bool swift::isLetPointer(SILValue V) { return false; } - void AliasAnalysis::initialize(SILPassManager *PM) { SEA = PM->getAnalysis(); + EA = PM->getAnalysis(); } SILAnalysis *swift::createAliasAnalysis(SILModule *M) { return new AliasAnalysis(M); } + +AliasKeyTy AliasAnalysis::toAliasKey(SILValue V1, SILValue V2, + SILType Type1, SILType Type2) { + size_t idx1 = AliasValueBaseToIndex.getIndex(V1.getDef()); + size_t idx2 = AliasValueBaseToIndex.getIndex(V2.getDef()); + unsigned R1 = V1.getResultNumber(); + unsigned R2 = V2.getResultNumber(); + void *t1 = Type1.getOpaqueValue(); + void *t2 = Type2.getOpaqueValue(); + return {idx1, idx2, R1, R2, t1, t2}; +} diff --git a/lib/SILOptimizer/Analysis/Analysis.cpp b/lib/SILOptimizer/Analysis/Analysis.cpp new file mode 100644 index 0000000000000..3358e94627b5b --- /dev/null +++ b/lib/SILOptimizer/Analysis/Analysis.cpp @@ -0,0 +1,57 @@ +//===--- Analysis.cpp - Swift Analysis ------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-analysis" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/IVAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h" +#include "swift/AST/Module.h" +#include "swift/AST/SILOptions.h" +#include "swift/SIL/SILModule.h" +#include "swift/SIL/SILFunction.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Debug.h" +#include "swift/SILOptimizer/Utils/Local.h" + +using namespace swift; + +void SILAnalysis::verifyFunction(SILFunction *F) { + // Only functions with bodies can be analyzed by the analysis. + assert(F->isDefinition() && "Can't analyze external functions"); +} + +SILAnalysis *swift::createDominanceAnalysis(SILModule *) { + return new DominanceAnalysis(); +} + +SILAnalysis *swift::createPostDominanceAnalysis(SILModule *) { + return new PostDominanceAnalysis(); +} + +SILAnalysis *swift::createInductionVariableAnalysis(SILModule *M) { + return new IVAnalysis(M); +} + +SILAnalysis *swift::createPostOrderAnalysis(SILModule *M) { + return new PostOrderAnalysis(); +} + +SILAnalysis *swift::createClassHierarchyAnalysis(SILModule *M) { + return new ClassHierarchyAnalysis(M); +} + +SILAnalysis *swift::createBasicCalleeAnalysis(SILModule *M) { + return new BasicCalleeAnalysis(M); +} diff --git a/lib/SILOptimizer/Analysis/ArraySemantic.cpp b/lib/SILOptimizer/Analysis/ArraySemantic.cpp new file mode 100644 index 0000000000000..2e58d55770d71 --- /dev/null +++ b/lib/SILOptimizer/Analysis/ArraySemantic.cpp @@ -0,0 +1,648 @@ +//===- ArraySemantic.cpp - Wrapper around array semantic calls. -*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/StringSwitch.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SIL/DebugUtils.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILBuilder.h" +#include "swift/SIL/SILFunction.h" + +using namespace swift; + +static ParameterConvention +getSelfParameterConvention(ApplyInst *SemanticsCall) { + FunctionRefInst *FRI = cast(SemanticsCall->getCallee()); + SILFunction *F = FRI->getReferencedFunction(); + auto FnTy = F->getLoweredFunctionType(); + + return FnTy->getSelfParameter().getConvention(); +} + +/// \brief Make sure that all parameters are passed with a reference count +/// neutral parameter convention except for self. +bool swift::ArraySemanticsCall::isValidSignature() { + assert(SemanticsCall && getKind() != ArrayCallKind::kNone && + "Need an array semantic call"); + FunctionRefInst *FRI = cast(SemanticsCall->getCallee()); + SILFunction *F = FRI->getReferencedFunction(); + auto FnTy = F->getLoweredFunctionType(); + auto &Mod = F->getModule(); + + // Check whether we have a valid signature for semantic calls that we hoist. + switch (getKind()) { + // All other calls can be consider valid. + default: break; + case ArrayCallKind::kArrayPropsIsNativeTypeChecked: { + // @guaranteed/@owned Self + if (SemanticsCall->getNumArguments() != 1) + return false; + auto SelfConvention = FnTy->getSelfParameter().getConvention(); + return SelfConvention == ParameterConvention::Direct_Guaranteed || + SelfConvention == ParameterConvention::Direct_Owned; + } + case ArrayCallKind::kCheckIndex: { + // Int, @guaranteed/@owned Self + if (SemanticsCall->getNumArguments() != 2 || + !SemanticsCall->getArgument(0).getType().isTrivial(Mod)) + return false; + auto SelfConvention = FnTy->getSelfParameter().getConvention(); + return SelfConvention == ParameterConvention::Direct_Guaranteed || + SelfConvention == ParameterConvention::Direct_Owned; + } + case ArrayCallKind::kCheckSubscript: { + // Int, Bool, Self + if (SemanticsCall->getNumArguments() != 3 || + !SemanticsCall->getArgument(0).getType().isTrivial(Mod)) + return false; + if (!SemanticsCall->getArgument(1).getType().isTrivial(Mod)) + return false; + auto SelfConvention = FnTy->getSelfParameter().getConvention(); + return SelfConvention == ParameterConvention::Direct_Guaranteed || + SelfConvention == ParameterConvention::Direct_Owned; + } + case ArrayCallKind::kMakeMutable: { + auto SelfConvention = FnTy->getSelfParameter().getConvention(); + return SelfConvention == ParameterConvention::Indirect_Inout; + } + case ArrayCallKind::kArrayUninitialized: { + // Make sure that if we are a _adoptStorage call that our storage is + // uniquely referenced by us. + SILValue Arg0 = SemanticsCall->getArgument(0); + if (Arg0.getType().isExistentialType()) { + auto *AllocBufferAI = dyn_cast(Arg0); + if (!AllocBufferAI) + return false; + + auto *AllocFn = AllocBufferAI->getCalleeFunction(); + if (!AllocFn) + return false; + + StringRef AllocFuncName = AllocFn->getName(); + if (AllocFuncName != "swift_bufferAllocate" && + AllocFuncName != "swift_bufferAllocateOnStack") + return false; + + if (!hasOneNonDebugUse(*AllocBufferAI)) + return false; + } + return true; + } + } + + return true; +} + +/// Match array semantic calls. +swift::ArraySemanticsCall::ArraySemanticsCall(ValueBase *V, + StringRef SemanticStr, + bool MatchPartialName) { + if (auto *AI = dyn_cast(V)) + if (auto *Fn = AI->getCalleeFunction()) + if ((MatchPartialName && + Fn->hasSemanticsAttrsThatStartsWith(SemanticStr)) || + (!MatchPartialName && Fn->hasSemanticsAttr(SemanticStr))) { + SemanticsCall = AI; + // Need a 'self' argument otherwise this is not a semantic call that + // we recognize. + if (getKind() < ArrayCallKind::kArrayInit && !hasSelf()) + SemanticsCall = nullptr; + + // A arguments must be passed reference count neutral except for self. + if (SemanticsCall && !isValidSignature()) + SemanticsCall = nullptr; + return; + } + // Otherwise, this is not the semantic call we are looking for. + SemanticsCall = nullptr; +} + +/// Determine which kind of array semantics call this is. +ArrayCallKind swift::ArraySemanticsCall::getKind() const { + if (!SemanticsCall) + return ArrayCallKind::kNone; + + auto F = cast(SemanticsCall->getCallee()) + ->getReferencedFunction(); + + ArrayCallKind Kind = ArrayCallKind::kNone; + + for (auto &Attrs : F->getSemanticsAttrs()) { + auto Tmp = + llvm::StringSwitch(Attrs) + .Case("array.props.isNativeTypeChecked", + ArrayCallKind::kArrayPropsIsNativeTypeChecked) + .Case("array.init", ArrayCallKind::kArrayInit) + .Case("array.uninitialized", ArrayCallKind::kArrayUninitialized) + .Case("array.check_subscript", ArrayCallKind::kCheckSubscript) + .Case("array.check_index", ArrayCallKind::kCheckIndex) + .Case("array.get_count", ArrayCallKind::kGetCount) + .Case("array.get_capacity", ArrayCallKind::kGetCapacity) + .Case("array.get_element", ArrayCallKind::kGetElement) + .Case("array.owner", ArrayCallKind::kGetArrayOwner) + .Case("array.make_mutable", ArrayCallKind::kMakeMutable) + .Case("array.get_element_address", + ArrayCallKind::kGetElementAddress) + .Case("array.mutate_unknown", ArrayCallKind::kMutateUnknown) + .Default(ArrayCallKind::kNone); + if (Tmp != ArrayCallKind::kNone) { + assert(Kind == ArrayCallKind::kNone && "Multiple array semantic " + "strings?!"); + Kind = Tmp; + } + } + + return Kind; +} + +bool swift::ArraySemanticsCall::hasSelf() const { + assert(SemanticsCall && "Must have a semantics call"); + // Array.init and Array.uninitialized return 'self' @owned. + return SemanticsCall->getOrigCalleeType()->hasSelfParam(); +} + +SILValue swift::ArraySemanticsCall::getSelf() const { + return SemanticsCall->getSelfArgument(); +} + +Operand &swift::ArraySemanticsCall::getSelfOperand() const { + return SemanticsCall->getSelfArgumentOperand(); +} + +bool swift::ArraySemanticsCall::hasGuaranteedSelf() const { + if (!hasSelf()) + return false; + return getSelfParameterConvention(SemanticsCall) == + ParameterConvention::Direct_Guaranteed; +} + +SILValue swift::ArraySemanticsCall::getIndex() const { + assert(SemanticsCall && "Must have a semantics call"); + assert(SemanticsCall->getNumArguments() && "Must have arguments"); + assert(getKind() == ArrayCallKind::kCheckSubscript || + getKind() == ArrayCallKind::kCheckIndex || + getKind() == ArrayCallKind::kGetElement || + getKind() == ArrayCallKind::kGetElementAddress); + + if (getKind() == ArrayCallKind::kGetElement) + return SemanticsCall->getArgument(1); + + return SemanticsCall->getArgument(0); +} + +Optional swift::ArraySemanticsCall::getConstantIndex() const { + auto *IndexStruct = dyn_cast(getIndex()); + if (!IndexStruct) + return None; + auto StructOpds = IndexStruct->getElements(); + if (StructOpds.size() != 1) + return None; + auto *Literal = dyn_cast(StructOpds[0]); + if (!Literal) + return None; + + auto Val = Literal->getValue(); + if (Val.getNumWords()>1) + return None; + + return Val.getSExtValue(); +} + +static bool canHoistArrayArgument(ApplyInst *SemanticsCall, SILValue Arr, + SILInstruction *InsertBefore, + DominanceInfo *DT) { + + // We only know how to hoist inout, owned or guaranteed parameters. + auto Convention = getSelfParameterConvention(SemanticsCall); + if (Convention != ParameterConvention::Indirect_Inout && + Convention != ParameterConvention::Direct_Owned && + Convention != ParameterConvention::Direct_Guaranteed) + return false; + + auto *SelfVal = Arr.getDef(); + auto *SelfBB = SelfVal->getParentBB(); + if (DT->dominates(SelfBB, InsertBefore->getParent())) + return true; + + if (auto LI = dyn_cast(SelfVal)) { + // Are we loading a value from an address in a struct defined at a point + // dominating the hoist point. + auto Val = LI->getOperand().getDef(); + bool DoesNotDominate; + StructElementAddrInst *SEI; + while ((DoesNotDominate = !DT->dominates(Val->getParentBB(), + InsertBefore->getParent())) && + (SEI = dyn_cast(Val))) + Val = SEI->getOperand().getDef(); + return DoesNotDominate == false; + } + + return false; +} + +bool swift::ArraySemanticsCall::canHoist(SILInstruction *InsertBefore, + DominanceInfo *DT) const { + auto Kind = getKind(); + switch (Kind) { + default: + break; + + case ArrayCallKind::kCheckIndex: + case ArrayCallKind::kArrayPropsIsNativeTypeChecked: + case ArrayCallKind::kGetElementAddress: + case ArrayCallKind::kGetCount: + case ArrayCallKind::kGetCapacity: + return canHoistArrayArgument(SemanticsCall, getSelf(), InsertBefore, DT); + + case ArrayCallKind::kGetElement: + // Not implemented yet. + return false; + + case ArrayCallKind::kCheckSubscript: { + auto IsNativeArg = getArrayPropertyIsNativeTypeChecked(); + ArraySemanticsCall IsNative(IsNativeArg.getDef(), + "array.props.isNativeTypeChecked", true); + if (!IsNative) { + // Do we have a constant parameter? + auto *SI = dyn_cast(IsNativeArg); + if (!SI) + return false; + if (!isa(SI->getOperand(0))) + return false; + } else if (!IsNative.canHoist(InsertBefore, DT)) + // Otherwise, we must be able to hoist the function call. + return false; + + return canHoistArrayArgument(SemanticsCall, getSelf(), InsertBefore, DT); + } + + case ArrayCallKind::kMakeMutable: { + return canHoistArrayArgument(SemanticsCall, getSelf(), InsertBefore, DT); + } + } // End switch. + + return false; +} + +/// Copy the array load to the insert point. +static SILValue copyArrayLoad(SILValue ArrayStructValue, + SILInstruction *InsertBefore, + DominanceInfo *DT) { + if (DT->dominates(ArrayStructValue.getDef()->getParentBB(), + InsertBefore->getParent())) + return ArrayStructValue; + + auto *LI = cast(ArrayStructValue.getDef()); + + // Recursively move struct_element_addr. + auto *Val = LI->getOperand().getDef(); + auto *InsertPt = InsertBefore; + while (!DT->dominates(Val->getParentBB(), InsertBefore->getParent())) { + auto *Inst = cast(Val); + Inst->moveBefore(InsertPt); + Val = Inst->getOperand().getDef(); + InsertPt = Inst; + } + + return SILValue(LI->clone(InsertBefore), 0); +} + +static ApplyInst *hoistOrCopyCall(ApplyInst *AI, SILInstruction *InsertBefore, + bool LeaveOriginal, DominanceInfo *DT) { + if (!LeaveOriginal) { + AI->moveBefore(InsertBefore); + } else { + // Leave the original and 'hoist' a clone. + AI = cast(AI->clone(InsertBefore)); + } + placeFuncRef(AI, DT); + return AI; +} + + +/// \brief Hoist or copy the self argument of the semantics call. +/// Return the hoisted self argument. +static SILValue hoistOrCopySelf(ApplyInst *SemanticsCall, + SILInstruction *InsertBefore, + DominanceInfo *DT, bool LeaveOriginal) { + + auto SelfConvention = getSelfParameterConvention(SemanticsCall); + + assert((SelfConvention == ParameterConvention::Direct_Owned || + SelfConvention == ParameterConvention::Direct_Guaranteed) && + "Expect @owned or @guaranteed self"); + + auto Self = SemanticsCall->getSelfArgument(); + bool IsOwnedSelf = SelfConvention == ParameterConvention::Direct_Owned; + + // Emit matching release for owned self if we are moving the original call. + if (!LeaveOriginal && IsOwnedSelf) + SILBuilderWithScope(SemanticsCall) + .createReleaseValue(SemanticsCall->getLoc(), Self); + + auto NewArrayStructValue = copyArrayLoad(Self, InsertBefore, DT); + + // Retain the array. + if (IsOwnedSelf) + SILBuilderWithScope(InsertBefore, SemanticsCall) + .createRetainValue(SemanticsCall->getLoc(), NewArrayStructValue); + + return NewArrayStructValue; +} + +ApplyInst *swift::ArraySemanticsCall::hoistOrCopy(SILInstruction *InsertBefore, + DominanceInfo *DT, + bool LeaveOriginal) { + assert(canHoist(InsertBefore, DT) && + "Must be able to hoist the semantics call"); + + auto Kind = getKind(); + switch (Kind) { + case ArrayCallKind::kArrayPropsIsNativeTypeChecked: + case ArrayCallKind::kGetCount: + case ArrayCallKind::kGetCapacity: { + assert(SemanticsCall->getNumArguments() == 1 && + "Expect 'self' parameter only"); + + auto HoistedSelf = + hoistOrCopySelf(SemanticsCall, InsertBefore, DT, LeaveOriginal); + + auto *Call = + hoistOrCopyCall(SemanticsCall, InsertBefore, LeaveOriginal, DT); + Call->setSelfArgument(HoistedSelf); + return Call; + } + + case ArrayCallKind::kCheckSubscript: + case ArrayCallKind::kCheckIndex: { + auto HoistedSelf = + hoistOrCopySelf(SemanticsCall, InsertBefore, DT, LeaveOriginal); + + SILValue NewArrayProps; + if (Kind == ArrayCallKind::kCheckSubscript) { + // Copy the array.props argument call. + auto IsNativeArg = getArrayPropertyIsNativeTypeChecked(); + ArraySemanticsCall IsNative(IsNativeArg.getDef(), + "array.props.isNativeTypeChecked", true); + if (!IsNative) { + // Do we have a constant parameter? + auto *SI = dyn_cast(IsNativeArg); + assert(SI && isa(SI->getOperand(0)) && + "Must have a constant parameter or an array.props.isNative call " + "as argument"); + SI->moveBefore(&*DT->findNearestCommonDominator( + InsertBefore->getParent(), SI->getParent()) + ->begin()); + auto *IL = cast(SI->getOperand(0)); + IL->moveBefore(&*DT->findNearestCommonDominator( + InsertBefore->getParent(), IL->getParent()) + ->begin()); + } else { + NewArrayProps = IsNative.copyTo(InsertBefore, DT); + } + + // Replace all uses of the check subscript call by a use of the empty + // dependence. The check subscript call is no longer associated with + // another operation. + auto EmptyDep = SILBuilderWithScope(SemanticsCall) + .createStruct(SemanticsCall->getLoc(), + SemanticsCall->getType(), {}); + SemanticsCall->replaceAllUsesWith(EmptyDep); + } + + // Hoist the call. + auto Call = hoistOrCopyCall(SemanticsCall, InsertBefore, LeaveOriginal, DT); + Call->setSelfArgument(HoistedSelf); + + if (NewArrayProps) { + // Set the array.props argument. + Call->setArgument(1, NewArrayProps); + } + + + return Call; + } + + case ArrayCallKind::kMakeMutable: { + assert(!LeaveOriginal && "Copying not yet implemented"); + // Hoist the call. + auto Call = hoistOrCopyCall(SemanticsCall, InsertBefore, LeaveOriginal, DT); + return Call; + } + + default: + llvm_unreachable("Don't know how to hoist this instruction"); + break; + } // End switch. +} + +void swift::ArraySemanticsCall::removeCall() { + if (getSelfParameterConvention(SemanticsCall) == + ParameterConvention::Direct_Owned) + SILBuilderWithScope(SemanticsCall) + .createReleaseValue(SemanticsCall->getLoc(), getSelf()); + + switch (getKind()) { + default: break; + case ArrayCallKind::kCheckSubscript: { + // Remove all uses with the empty tuple (). + auto EmptyDep = SILBuilderWithScope(SemanticsCall) + .createStruct(SemanticsCall->getLoc(), + SemanticsCall->getType(), {}); + SemanticsCall->replaceAllUsesWith(EmptyDep); + } + break; + case ArrayCallKind::kGetElement: { + // Remove the matching isNativeTypeChecked and check_subscript call. + ArraySemanticsCall IsNative(SemanticsCall->getArgument(2).getDef(), + "array.props.isNativeTypeChecked"); + ArraySemanticsCall SubscriptCheck(SemanticsCall->getArgument(3).getDef(), + "array.check_subscript"); + if (SubscriptCheck) + SubscriptCheck.removeCall(); + + // array.isNativeTypeChecked might be shared among several get_element + // calls. The last user should delete it. + if (IsNative && getSingleNonDebugUser(*IsNative) == SemanticsCall) { + deleteAllDebugUses(IsNative); + (*IsNative).replaceAllUsesWithUndef(); + IsNative.removeCall(); + } + } + break; + } + + SemanticsCall->eraseFromParent(); + SemanticsCall = nullptr; +} + +static bool hasArrayPropertyIsNativeTypeChecked(ArrayCallKind Kind, + unsigned &ArgIdx) { + switch (Kind) { + default: break; + + case ArrayCallKind::kCheckSubscript: + case ArrayCallKind::kGetElement: + ArgIdx = 1; + return true; + } + return false; +} + +SILValue +swift::ArraySemanticsCall::getArrayPropertyIsNativeTypeChecked() const { + unsigned ArgIdx = 0; + bool HasArg = hasArrayPropertyIsNativeTypeChecked(getKind(), ArgIdx); + (void)HasArg; + assert(HasArg && + "Must have an array.props argument"); + + return SemanticsCall->getArgument(ArgIdx); +} + +bool swift::ArraySemanticsCall::mayHaveBridgedObjectElementType() const { + assert(hasSelf() && "Need self parameter"); + + auto Ty = getSelf().getType().getSwiftRValueType(); + auto Canonical = Ty.getCanonicalTypeOrNull(); + if (Canonical.isNull()) + return true; + + auto *Struct = Canonical->getStructOrBoundGenericStruct(); + assert(Struct && "Array must be a struct !?"); + if (Struct) { + auto BGT = dyn_cast(Ty); + if (!BGT) + return true; + + // Check the array element type parameter. + bool isClass = true; + for (auto TP : BGT->getGenericArgs()) { + auto EltTy = TP.getCanonicalTypeOrNull(); + if (EltTy.isNull()) + return true; + if (EltTy->isBridgeableObjectType()) + return true; + isClass = false; + } + return isClass; + } + return true; +} + +SILValue swift::ArraySemanticsCall::getInitializationCount() const { + if (getKind() == ArrayCallKind::kArrayUninitialized) { + // Can be either a call to _adoptStorage or _allocateUninitialized. + // A call to _adoptStorage has the buffer as AnyObject as the first + // argument. The count is the second argument. + // A call to _allocateUninitialized has the count as first argument. + SILValue Arg0 = SemanticsCall->getArgument(0); + if (Arg0.getType().isExistentialType()) + return SemanticsCall->getArgument(1); + else return SemanticsCall->getArgument(0); + } + + if (getKind() == ArrayCallKind::kArrayInit && + SemanticsCall->getNumArguments() == 3) + return SemanticsCall->getArgument(0); + + return SILValue(); +} + +SILValue swift::ArraySemanticsCall::getArrayValue() const { + if (getKind() == ArrayCallKind::kArrayUninitialized) { + TupleExtractInst *ArrayDef = nullptr; + for (auto *Op : SemanticsCall->getUses()) { + auto *TupleElt = dyn_cast(Op->getUser()); + if (!TupleElt) + return SILValue(); + switch (TupleElt->getFieldNo()) { + default: + return SILValue(); + case 0: { + // Should only have one tuple extract after CSE. + if (ArrayDef) + return SILValue(); + ArrayDef = TupleElt; + break; + } + case 1: /*Ignore the storage address */ break; + } + } + return SILValue(ArrayDef); + } + + if(getKind() == ArrayCallKind::kArrayInit) + return SILValue(SemanticsCall); + + return SILValue(); +} + +SILValue swift::ArraySemanticsCall::getArrayElementStoragePointer() const { + if (getKind() == ArrayCallKind::kArrayUninitialized) { + TupleExtractInst *ArrayElementStorage = nullptr; + for (auto *Op : SemanticsCall->getUses()) { + auto *TupleElt = dyn_cast(Op->getUser()); + if (!TupleElt) + return SILValue(); + switch (TupleElt->getFieldNo()) { + default: + return SILValue(); + case 0: { + // Ignore the array value. + break; + } + case 1: + // Should only have one tuple extract after CSE. + if (ArrayElementStorage) + return SILValue(); + ArrayElementStorage = TupleElt; + break; + } + } + return SILValue(ArrayElementStorage); + } + + return SILValue(); +} + +bool swift::ArraySemanticsCall::replaceByValue(SILValue V) { + assert(getKind() == ArrayCallKind::kGetElement && + "Must be a get_element call"); + // We only handle loadable types. + if (!V.getType().isLoadable(SemanticsCall->getModule())) + return false; + + auto Dest = SemanticsCall->getArgument(0); + + // Expect an alloc_stack initialization. + auto *ASI = dyn_cast(Dest); + if (!ASI) + return false; + + // Expect a check_subscript call or the empty dependence. + auto SubscriptCheck = SemanticsCall->getArgument(3); + ArraySemanticsCall Check(SubscriptCheck.getDef(), "array.check_subscript"); + auto *EmptyDep = dyn_cast(SubscriptCheck); + if (!Check && (!EmptyDep || !EmptyDep->getElements().empty())) + return false; + + SILBuilderWithScope Builder(SemanticsCall); + auto &ValLowering = Builder.getModule().getTypeLowering(V.getType()); + ValLowering.emitRetainValue(Builder, SemanticsCall->getLoc(), V); + ValLowering.emitStoreOfCopy(Builder, SemanticsCall->getLoc(), V, Dest, + IsInitialization_t::IsInitialization); + removeCall(); + return true; +} diff --git a/lib/SILAnalysis/BasicCalleeAnalysis.cpp b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp similarity index 92% rename from lib/SILAnalysis/BasicCalleeAnalysis.cpp rename to lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp index 98f082df2f186..72beb575fc19d 100644 --- a/lib/SILAnalysis/BasicCalleeAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/BasicCalleeAnalysis.cpp @@ -1,8 +1,8 @@ -//===- BasicCalleeAnalysis.cpp - Determine callees per call site ----------===// +//===--- BasicCalleeAnalysis.cpp - Determine callees per call site --------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,17 +10,28 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" #include "swift/AST/Decl.h" #include "swift/Basic/Fallthrough.h" #include "swift/SIL/SILModule.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Utils/Local.h" #include using namespace swift; +bool CalleeList::allCalleesVisible() { + if (isIncomplete()) + return false; + + for (SILFunction *Callee : *this) { + if (Callee->isExternalDeclaration()) + return false; + } + return true; +} + void CalleeCache::sortAndUniqueCallees() { // Sort the callees for each decl and remove duplicates. for (auto &Pair : TheCache) { @@ -83,7 +94,7 @@ void CalleeCache::computeClassMethodCalleesForClass(ClassDecl *CD) { if (canCallUnknown) TheCallees.setInt(true); - Method = Method.getOverriddenVTableEntry(); + Method = Method.getNextOverriddenVTableEntry(); } while (Method); } } diff --git a/lib/SILOptimizer/Analysis/CFG.cpp b/lib/SILOptimizer/Analysis/CFG.cpp new file mode 100644 index 0000000000000..339d054a4ef3f --- /dev/null +++ b/lib/SILOptimizer/Analysis/CFG.cpp @@ -0,0 +1,99 @@ +//===--- CFG.cpp ----------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "swift/SILOptimizer/Analysis/CFG.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SIL/SILValue.h" +#include "llvm/ADT/TinyPtrVector.h" + +using namespace swift; + +static bool isSafeNonExitTerminator(TermInst *TI) { + switch (TI->getTermKind()) { + case TermKind::BranchInst: + case TermKind::CondBranchInst: + case TermKind::SwitchValueInst: + case TermKind::SwitchEnumInst: + case TermKind::SwitchEnumAddrInst: + case TermKind::DynamicMethodBranchInst: + case TermKind::CheckedCastBranchInst: + case TermKind::CheckedCastAddrBranchInst: + return true; + case TermKind::UnreachableInst: + case TermKind::ReturnInst: + case TermKind::ThrowInst: + case TermKind::TryApplyInst: + return false; + case TermKind::Invalid: + llvm_unreachable("Invalid Term Inst?!"); + } +} + +static bool isTrapNoReturnFunction(ApplyInst *AI) { + const char *fatalName = + "_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_"; + auto *Fn = AI->getCalleeFunction(); + + // We use endswith here since if we specialize fatal error we will always + // prepend the specialization records to fatalName. + if (!Fn || !Fn->getName().endswith(fatalName)) + return false; + + return true; +} + +bool +swift:: +findAllNonFailureExitBBs(SILFunction *F, + llvm::TinyPtrVector &BBs) { + for (SILBasicBlock &BB : *F) { + TermInst *TI = BB.getTerminator(); + + // If we know that this terminator is not an exit terminator, continue. + if (isSafeNonExitTerminator(TI)) + continue; + + // A return inst is always a non-failure exit bb. + if (isa(TI)) { + BBs.push_back(&BB); + continue; + } + + // If we don't have an unreachable inst at this point, this is a terminator + // we don't understand. Be conservative and return false. + if (!isa(TI)) + return false; + + // Ok, at this point we know we have a terminator. If it is the only + // instruction in our BB, it is a failure BB. continue... + if (TI == &*BB.begin()) + continue; + + // If the unreachable is preceded by a no-return apply inst, then it is a + // non-failure exit BB. Add it to our list and continue. + auto PrevIter = std::prev(SILBasicBlock::iterator(TI)); + if (auto *AI = dyn_cast(&*PrevIter)) { + if (AI->getSubstCalleeType()->isNoReturn() && + !isTrapNoReturnFunction(AI)) { + BBs.push_back(&BB); + continue; + } + } + + // Otherwise, it must be a failure BB where we leak, continue. + continue; + } + + // We understood all terminators, return true. + return true; +} diff --git a/lib/SILOptimizer/Analysis/CMakeLists.txt b/lib/SILOptimizer/Analysis/CMakeLists.txt new file mode 100644 index 0000000000000..cd852e43932cb --- /dev/null +++ b/lib/SILOptimizer/Analysis/CMakeLists.txt @@ -0,0 +1,22 @@ +set(ANALYSIS_SOURCES + Analysis/ARCAnalysis.cpp + Analysis/AliasAnalysis.cpp + Analysis/Analysis.cpp + Analysis/ArraySemantic.cpp + Analysis/BasicCalleeAnalysis.cpp + Analysis/CFG.cpp + Analysis/ClassHierarchyAnalysis.cpp + Analysis/ColdBlockInfo.cpp + Analysis/DestructorAnalysis.cpp + Analysis/EscapeAnalysis.cpp + Analysis/FunctionOrder.cpp + Analysis/IVAnalysis.cpp + Analysis/LoopAnalysis.cpp + Analysis/LoopRegionAnalysis.cpp + Analysis/MemoryBehavior.cpp + Analysis/RCIdentityAnalysis.cpp + Analysis/SideEffectAnalysis.cpp + Analysis/SimplifyInstruction.cpp + Analysis/TypeExpansionAnalysis.cpp + Analysis/ValueTracking.cpp + PARENT_SCOPE) diff --git a/lib/SILAnalysis/ClassHierarchyAnalysis.cpp b/lib/SILOptimizer/Analysis/ClassHierarchyAnalysis.cpp similarity index 92% rename from lib/SILAnalysis/ClassHierarchyAnalysis.cpp rename to lib/SILOptimizer/Analysis/ClassHierarchyAnalysis.cpp index ff000849a8a3f..fd90cb3f3e364 100644 --- a/lib/SILAnalysis/ClassHierarchyAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/ClassHierarchyAnalysis.cpp @@ -1,8 +1,8 @@ -//===- ClassHierarchyAnalysis.cpp - Analysis of class hierarchy -*- C++ -*-===// +//===--- ClassHierarchyAnalysis.cpp - Class hierarchy analysis --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,9 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/ClassHierarchyAnalysis.h" +#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h" #include "swift/AST/ASTContext.h" +#include "swift/AST/ASTWalker.h" #include "swift/AST/Module.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILValue.h" @@ -77,7 +78,7 @@ void ClassHierarchyAnalysis::init() { /// \brief Get all subclasses of a given class. /// Does not include any direct subclasses of given base class. /// -/// \p Base base class, whose direct subclasses are to be excluded +/// \p Base class, whose direct subclasses are to be excluded /// \p Current class, whose direct and indirect subclasses are /// to be collected. /// \p IndirectSubs placeholder for collected results diff --git a/lib/SILAnalysis/ColdBlockInfo.cpp b/lib/SILOptimizer/Analysis/ColdBlockInfo.cpp similarity index 89% rename from lib/SILAnalysis/ColdBlockInfo.cpp rename to lib/SILOptimizer/Analysis/ColdBlockInfo.cpp index 4d71d28dd909f..b62e96a2247be 100644 --- a/lib/SILAnalysis/ColdBlockInfo.cpp +++ b/lib/SILOptimizer/Analysis/ColdBlockInfo.cpp @@ -1,8 +1,8 @@ -//===----- ColdBlocks.cpp - Fast/slow path analysis for the SIL CFG -------===// +//===--- ColdBlockInfo.cpp - Fast/slow path analysis for the SIL CFG ------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/ColdBlockInfo.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/ColdBlockInfo.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" using namespace swift; @@ -34,7 +34,7 @@ enum BranchHint : unsigned { }; } // namespace -/// \return a BranHint if this call is a builtin branch hint. +/// \return a BranchHint if this call is a builtin branch hint. static BranchHint getBranchHint(SILValue Cond) { // Handle the fully inlined Builtin. if (auto *BI = dyn_cast(Cond)) { @@ -57,8 +57,8 @@ static BranchHint getBranchHint(SILValue Cond) { return BranchHint::None; if (auto *F = AI->getCalleeFunction()) { - if (F->hasDefinedSemantics()) { - if (F->getSemanticsString() == "branchhint") { + if (F->hasSemanticsAttrs()) { + if (F->hasSemanticsAttr("branchhint")) { // A "branchint" model takes a Bool expected value as the second // argument. if (auto *SI = dyn_cast(AI->getArgument(1))) { @@ -72,9 +72,9 @@ static BranchHint getBranchHint(SILValue Cond) { } // fastpath/slowpath attrs are untested because the inliner luckily // inlines them before the downstream calls. - else if (F->getSemanticsString() == "slowpath") + else if (F->hasSemanticsAttr("slowpath")) return BranchHint::LikelyFalse; - else if (F->getSemanticsString() == "fastpath") + else if (F->hasSemanticsAttr("fastpath")) return BranchHint::LikelyTrue; } } diff --git a/lib/SILAnalysis/DestructorAnalysis.cpp b/lib/SILOptimizer/Analysis/DestructorAnalysis.cpp similarity index 96% rename from lib/SILAnalysis/DestructorAnalysis.cpp rename to lib/SILOptimizer/Analysis/DestructorAnalysis.cpp index ef80eb315f6bf..4896b9cac4cb4 100644 --- a/lib/SILAnalysis/DestructorAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/DestructorAnalysis.cpp @@ -1,4 +1,4 @@ -#include "swift/SILAnalysis/DestructorAnalysis.h" +#include "swift/SILOptimizer/Analysis/DestructorAnalysis.h" #include "swift/SIL/SILInstruction.h" #include "swift/AST/ASTContext.h" #include "swift/AST/Decl.h" @@ -40,7 +40,7 @@ bool DestructorAnalysis::isSafeType(Type Ty) { } // Before we recurse mark the type as safe i.e if we see it in a recursive - // possition it is safe in the absence of another fact that proves otherwise. + // position it is safe in the absence of another fact that proves otherwise. // We will reset this value to the correct value once we return from the // recursion below. cacheResult(Canonical, true); diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp new file mode 100644 index 0000000000000..92cb00d9214ef --- /dev/null +++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp @@ -0,0 +1,1724 @@ +//===--- EscapeAnalysis.cpp - SIL Escape Analysis -------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-escape" +#include "swift/SILOptimizer/Analysis/EscapeAnalysis.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" +#include "swift/SIL/SILArgument.h" +#include "llvm/Support/GraphWriter.h" +#include "llvm/Support/raw_ostream.h" + +using namespace swift; + +static bool isProjection(ValueBase *V) { + switch (V->getKind()) { + case ValueKind::IndexAddrInst: + case ValueKind::IndexRawPointerInst: + case ValueKind::StructElementAddrInst: + case ValueKind::TupleElementAddrInst: + case ValueKind::UncheckedTakeEnumDataAddrInst: + case ValueKind::StructExtractInst: + case ValueKind::TupleExtractInst: + case ValueKind::UncheckedEnumDataInst: + case ValueKind::MarkDependenceInst: + case ValueKind::PointerToAddressInst: + case ValueKind::AddressToPointerInst: + case ValueKind::InitEnumDataAddrInst: + return true; + default: + return false; + } +} + +static bool isNonWritableMemoryAddress(ValueBase *V) { + switch (V->getKind()) { + case ValueKind::FunctionRefInst: + case ValueKind::WitnessMethodInst: + case ValueKind::ClassMethodInst: + case ValueKind::SuperMethodInst: + case ValueKind::DynamicMethodInst: + case ValueKind::StringLiteralInst: + case ValueKind::ThinToThickFunctionInst: + case ValueKind::ThinFunctionToPointerInst: + case ValueKind::PointerToThinFunctionInst: + // These instructions return pointers to memory which can't be a + // destination of a store. + return true; + default: + return false; + } +} + +static ValueBase *skipProjections(ValueBase *V) { + for (;;) { + if (!isProjection(V)) + return V; + V = cast(V)->getOperand(0).getDef(); + } + llvm_unreachable("there is no escape from an infinite loop"); +} + +void EscapeAnalysis::ConnectionGraph::clear() { + Values2Nodes.clear(); + Nodes.clear(); + ReturnNode = nullptr; + UsePoints.clear(); + NodeAllocator.DestroyAll(); + assert(ToMerge.empty()); +} + +EscapeAnalysis::CGNode *EscapeAnalysis::ConnectionGraph:: +getNode(ValueBase *V, EscapeAnalysis *EA, bool createIfNeeded) { + if (isa(V)) + return nullptr; + + if (!V->hasValue()) + return nullptr; + + if (!EA->isPointer(V)) + return nullptr; + + V = skipProjections(V); + + if (!createIfNeeded) + return lookupNode(V); + + CGNode * &Node = Values2Nodes[V]; + if (!Node) { + if (SILArgument *Arg = dyn_cast(V)) { + if (Arg->isFunctionArg()) { + Node = allocNode(V, NodeType::Argument); + Node->mergeEscapeState(EscapeState::Arguments); + } else { + Node = allocNode(V, NodeType::Value); + } + } else { + Node = allocNode(V, NodeType::Value); + } + } + return Node->getMergeTarget(); +} + +EscapeAnalysis::CGNode *EscapeAnalysis::ConnectionGraph::getContentNode( + CGNode *AddrNode) { + // Do we already have a content node (which is not necessarily an immediate + // successor of AddrNode)? + if (AddrNode->pointsTo) + return AddrNode->pointsTo; + + CGNode *Node = allocNode(AddrNode->V, NodeType::Content); + updatePointsTo(AddrNode, Node); + assert(ToMerge.empty() && + "Initially setting pointsTo should not require any node merges"); + return Node; +} + +bool EscapeAnalysis::ConnectionGraph::addDeferEdge(CGNode *From, CGNode *To) { + if (!From->addDeferred(To)) + return false; + + CGNode *FromPointsTo = From->pointsTo; + CGNode *ToPointsTo = To->pointsTo; + if (FromPointsTo != ToPointsTo) { + if (!ToPointsTo) { + updatePointsTo(To, FromPointsTo->getMergeTarget()); + assert(ToMerge.empty() && + "Initially setting pointsTo should not require any node merges"); + } else { + // We are adding an edge between two pointers which point to different + // content nodes. This will require to merge the content nodes (and maybe + // other content nodes as well), because of the graph invariance 4). + updatePointsTo(From, ToPointsTo->getMergeTarget()); + } + } + return true; +} + +void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() { + while (!ToMerge.empty()) { + CGNode *From = ToMerge.pop_back_val(); + CGNode *To = From->getMergeTarget(); + assert(To != From && "Node scheduled to merge but no merge target set"); + assert(!From->isMerged && "Merge source is already merged"); + assert(From->Type == NodeType::Content && "Can only merge content nodes"); + assert(To->Type == NodeType::Content && "Can only merge content nodes"); + + // Unlink the predecessors and redirect the incoming pointsTo edge. + // Note: we don't redirect the defer-edges because we don't want to trigger + // updatePointsTo (which is called by addDeferEdge) right now. + for (Predecessor Pred : From->Preds) { + CGNode *PredNode = Pred.getPointer(); + if (Pred.getInt() == EdgeType::PointsTo) { + assert(PredNode->getPointsToEdge() == From && + "Incoming pointsTo edge not set in predecessor"); + if (PredNode != From) + PredNode->setPointsTo(To); + } else { + assert(PredNode != From); + auto Iter = PredNode->findDeferred(From); + assert(Iter != PredNode->defersTo.end() && + "Incoming defer-edge not found in predecessor's defer list"); + PredNode->defersTo.erase(Iter); + } + } + // Unlink and redirect the outgoing pointsTo edge. + if (CGNode *PT = From->getPointsToEdge()) { + if (PT != From) { + PT->removeFromPreds(Predecessor(From, EdgeType::PointsTo)); + } else { + PT = To; + } + if (CGNode *ExistingPT = To->getPointsToEdge()) { + // The To node already has an outgoing pointsTo edge, so the only thing + // we can do is to merge both content nodes. + scheduleToMerge(ExistingPT, PT); + } else { + To->setPointsTo(PT); + } + } + // Unlink the outgoing defer edges. + for (CGNode *Defers : From->defersTo) { + assert(Defers != From && "defer edge may not form a self-cycle"); + Defers->removeFromPreds(Predecessor(From, EdgeType::Defer)); + } + // Redirect the incoming defer edges. This may trigger other node merges. + // Note that the Pred iterator may be invalidated (because we may add + // edges in the loop). So we don't do: for (Pred : From->Preds) {...} + for (unsigned PredIdx = 0; PredIdx < From->Preds.size(); ++PredIdx) { + CGNode *PredNode = From->Preds[PredIdx].getPointer(); + if (From->Preds[PredIdx].getInt() == EdgeType::Defer) { + assert(PredNode != From && "defer edge may not form a self-cycle"); + addDeferEdge(PredNode, To); + } + } + // Redirect the outgoing defer edges, which may also trigger other node + // merges. + for (CGNode *Defers : From->defersTo) { + addDeferEdge(To, Defers); + } + // There is no point in updating the pointsTo if the To node will be + // merged to another node eventually. + if (!To->mergeTo) { + // Ensure that graph invariance 4) is kept. At this point there may be still + // some violations because of the new adjacent edges of the To node. + for (unsigned PredIdx = 0; PredIdx < To->Preds.size(); ++PredIdx) { + if (To->Preds[PredIdx].getInt() == EdgeType::PointsTo) { + CGNode *PredNode = To->Preds[PredIdx].getPointer(); + for (unsigned PPIdx = 0; PPIdx < PredNode->Preds.size(); ++PPIdx) { + if (PredNode->Preds[PPIdx].getInt() == EdgeType::Defer) + updatePointsTo(PredNode->Preds[PPIdx].getPointer(), To); + } + for (CGNode *Def : PredNode->defersTo) { + updatePointsTo(Def, To); + } + } + } + if (CGNode *ToPT = To->getPointsToEdge()) { + ToPT = ToPT->getMergeTarget(); + for (CGNode *ToDef : To->defersTo) { + updatePointsTo(ToDef, ToPT); + assert(!ToPT->mergeTo); + } + for (unsigned PredIdx = 0; PredIdx < To->Preds.size(); ++PredIdx) { + if (To->Preds[PredIdx].getInt() == EdgeType::Defer) + updatePointsTo(To->Preds[PredIdx].getPointer(), ToPT); + } + } + To->mergeEscapeState(From->State); + } + // Cleanup the merged node. + From->isMerged = true; + From->Preds.clear(); + From->defersTo.clear(); + From->pointsTo = nullptr; + } +} + +void EscapeAnalysis::ConnectionGraph:: +updatePointsTo(CGNode *InitialNode, CGNode *pointsTo) { + // Visit all nodes in the defer web, which don't have the right pointsTo set. + assert(!pointsTo->mergeTo); + llvm::SmallVector WorkList; + WorkList.push_back(InitialNode); + InitialNode->isInWorkList = true; + bool isInitialSet = false; + for (unsigned Idx = 0; Idx < WorkList.size(); ++Idx) { + auto *Node = WorkList[Idx]; + if (Node->pointsTo == pointsTo) + continue; + + if (Node->pointsTo) { + // Mismatching: we need to merge! + scheduleToMerge(Node->pointsTo, pointsTo); + } else { + isInitialSet = true; + } + + // If the node already has a pointsTo _edge_ we don't change it (we don't + // want to change the structure of the graph at this point). + if (!Node->pointsToIsEdge) { + if (Node->defersTo.empty()) { + // This node is the end of a defer-edge path with no pointsTo connected. + // We create an edge to pointsTo (agreed, this changes the structure of + // the graph but adding this edge is harmless). + Node->setPointsTo(pointsTo); + } else { + Node->pointsTo = pointsTo; + } + } + + // Add all adjacent nodes to the WorkList. + for (auto *Deferred : Node->defersTo) { + if (!Deferred->isInWorkList) { + WorkList.push_back(Deferred); + Deferred->isInWorkList = true; + } + } + for (Predecessor Pred : Node->Preds) { + if (Pred.getInt() == EdgeType::Defer) { + CGNode *PredNode = Pred.getPointer(); + if (!PredNode->isInWorkList) { + WorkList.push_back(PredNode); + PredNode->isInWorkList = true; + } + } + } + } + if (isInitialSet) { + // Here we handle a special case: all defer-edge paths must eventually end + // in a points-to edge to pointsTo. We ensure this by setting the edge on + // nodes which have no defer-successors (see above). But this does not cover + // the case where there is a terminating cycle in the defer-edge path, + // e.g. A -> B -> C -> B + // We find all nodes which don't reach a points-to edge and add additional + // points-to edges to fix that. + llvm::SmallVector PotentiallyInCycles; + + // Keep all nodes with a points-to edge in the WorkList and remove all other + // nodes. + unsigned InsertionPoint = 0; + for (CGNode *Node : WorkList) { + if (Node->pointsToIsEdge) { + WorkList[InsertionPoint++] = Node; + } else { + Node->isInWorkList = false; + PotentiallyInCycles.push_back(Node); + } + } + WorkList.set_size(InsertionPoint); + unsigned Idx = 0; + while (!PotentiallyInCycles.empty()) { + + // Propagate the "reaches-a-points-to-edge" backwards in the defer-edge + // sub-graph by adding those nodes to the WorkList. + while (Idx < WorkList.size()) { + auto *Node = WorkList[Idx++]; + for (Predecessor Pred : Node->Preds) { + if (Pred.getInt() == EdgeType::Defer) { + CGNode *PredNode = Pred.getPointer(); + if (!PredNode->isInWorkList) { + WorkList.push_back(PredNode); + PredNode->isInWorkList = true; + } + } + } + } + // Check if we still have some nodes which don't reach a points-to edge, + // i.e. points not yet in the WorkList. + while (!PotentiallyInCycles.empty()) { + auto *Node = PotentiallyInCycles.pop_back_val(); + if (!Node->isInWorkList) { + // We create a points-to edge for the first node which doesn't reach + // a points-to edge yet. + Node->setPointsTo(pointsTo); + WorkList.push_back(Node); + Node->isInWorkList = true; + break; + } + } + } + } + clearWorkListFlags(WorkList); +} + +void EscapeAnalysis::ConnectionGraph::propagateEscapeStates() { + bool Changed = false; + do { + Changed = false; + + for (CGNode *Node : Nodes) { + // Propagate the state to all successor nodes. + if (Node->pointsTo) { + Changed |= Node->pointsTo->mergeEscapeState(Node->State); + } + for (CGNode *Def : Node->defersTo) { + Changed |= Def->mergeEscapeState(Node->State); + } + } + } while (Changed); +} + +void EscapeAnalysis::ConnectionGraph::computeUsePoints() { + // First scan the whole function and add relevant instructions as use-points. + for (auto &BB : *F) { + for (SILArgument *BBArg : BB.getBBArgs()) { + /// In addition to releasing instructions (see below) we also add block + /// arguments as use points. In case of loops, block arguments can + /// "extend" the liferange of a reference in upward direction. + if (CGNode *ArgNode = lookupNode(BBArg)) { + addUsePoint(ArgNode, BBArg); + } + } + + for (auto &I : BB) { + switch (I.getKind()) { + case ValueKind::StrongReleaseInst: + case ValueKind::ReleaseValueInst: + case ValueKind::UnownedReleaseInst: + case ValueKind::ApplyInst: + case ValueKind::TryApplyInst: { + /// Actually we only add instructions which may release a reference. + /// We need the use points only for getting the end of a reference's + /// liferange. And that must be a releasing instruction. + int ValueIdx = -1; + for (const Operand &Op : I.getAllOperands()) { + ValueBase *OpV = Op.get().getDef(); + if (CGNode *OpNd = lookupNode(skipProjections(OpV))) { + if (ValueIdx < 0) { + ValueIdx = addUsePoint(OpNd, &I); + } else { + OpNd->setUsePointBit(ValueIdx); + } + } + } + break; + } + default: + break; + } + } + } + + // Second, we propagate the use-point information through the graph. + bool Changed = false; + do { + Changed = false; + + for (CGNode *Node : Nodes) { + // Propagate the bits to all successor nodes. + if (Node->pointsTo) { + Changed |= Node->pointsTo->mergeUsePoints(Node); + } + for (CGNode *Def : Node->defersTo) { + Changed |= Def->mergeUsePoints(Node); + } + } + } while (Changed); +} + +bool EscapeAnalysis::ConnectionGraph::mergeFrom(ConnectionGraph *SourceGraph, + CGNodeMap &Mapping) { + // The main point of the merging algorithm is to map each content node in the + // source graph to a content node in this (destination) graph. This may + // require to create new nodes or to merge existing nodes in this graph. + + // First step: replicate the points-to edges and the content nodes of the + // source graph in this graph. + bool Changed = false; + bool NodesMerged; + do { + NodesMerged = false; + for (unsigned Idx = 0; Idx < Mapping.getMappedNodes().size(); ++Idx) { + CGNode *SourceNd = Mapping.getMappedNodes()[Idx]; + CGNode *DestNd = Mapping.get(SourceNd); + assert(DestNd); + + if (SourceNd->getEscapeState() >= EscapeState::Global) { + // We don't need to merge the source subgraph of nodes which have the + // global escaping state set. + // Just set global escaping in the caller node and that's it. + Changed |= DestNd->mergeEscapeState(EscapeState::Global); + continue; + } + + CGNode *SourcePT = SourceNd->pointsTo; + if (!SourcePT) + continue; + + CGNode *MappedDestPT = Mapping.get(SourcePT); + if (!DestNd->pointsTo) { + // The following getContentNode() will create a new content node. + Changed = true; + } + CGNode *DestPT = getContentNode(DestNd); + if (MappedDestPT) { + // We already found the destination node through another path. + if (DestPT != MappedDestPT) { + // There are two content nodes in this graph which map to the same + // content node in the source graph -> we have to merge them. + scheduleToMerge(DestPT, MappedDestPT); + mergeAllScheduledNodes(); + Changed = true; + NodesMerged = true; + } + assert(SourcePT->isInWorkList); + } else { + // It's the first time we see the destination node, so we add it to the + // mapping. + Mapping.add(SourcePT, DestPT); + } + } + } while (NodesMerged); + + clearWorkListFlags(Mapping.getMappedNodes()); + + // Second step: add the source graph's defer edges to this graph. + llvm::SmallVector WorkList; + for (CGNode *SourceNd : Mapping.getMappedNodes()) { + assert(WorkList.empty()); + WorkList.push_back(SourceNd); + SourceNd->isInWorkList = true; + CGNode *DestFrom = Mapping.get(SourceNd); + assert(DestFrom && "node should have been merged to the graph"); + + // Collect all nodes which are reachable from the SourceNd via a path + // which only contains defer-edges. + for (unsigned Idx = 0; Idx < WorkList.size(); ++Idx) { + CGNode *SourceReachable = WorkList[Idx]; + CGNode *DestReachable = Mapping.get(SourceReachable); + // Create the edge in this graph. Note: this may trigger merging of + // content nodes. + if (DestReachable) { + Changed |= defer(DestFrom, DestReachable); + // In case DestFrom is merged during adding the defer-edge. + DestFrom = DestFrom->getMergeTarget(); + } + + for (auto *Deferred : SourceReachable->defersTo) { + if (!Deferred->isInWorkList) { + WorkList.push_back(Deferred); + Deferred->isInWorkList = true; + } + } + } + clearWorkListFlags(WorkList); + WorkList.clear(); + } + return Changed; +} + +/// Returns true if \p V is a use of \p Node, i.e. V may (indirectly) +/// somehow refer to the Node's value. +/// Use-points are only values which are relevant for lifeness computation, +/// e.g. release or apply instructions. +bool EscapeAnalysis::ConnectionGraph::isUsePoint(ValueBase *V, CGNode *Node) { + assert(Node->getEscapeState() < EscapeState::Global && + "Use points are only valid for non-escaping nodes"); + auto Iter = UsePoints.find(V); + if (Iter == UsePoints.end()) + return false; + int Idx = Iter->second; + if (Idx >= (int)Node->UsePoints.size()) + return false; + return Node->UsePoints.test(Idx); +} + +bool EscapeAnalysis::ConnectionGraph::isReachable(CGNode *From, CGNode *To) { + // See if we can reach the From-node by transitively visiting the + // predecessor nodes of the To-node. + // Usually nodes have few predecessor nodes and the graph depth is small. + // So this should be fast. + llvm::SmallVector WorkList; + WorkList.push_back(From); + From->isInWorkList = true; + for (unsigned Idx = 0; Idx < WorkList.size(); ++Idx) { + CGNode *Reachable = WorkList[Idx]; + if (Reachable == To) + return true; + for (Predecessor Pred : Reachable->Preds) { + CGNode *PredNode = Pred.getPointer(); + if (!PredNode->isInWorkList) { + PredNode->isInWorkList = true; + WorkList.push_back(PredNode); + } + } + } + clearWorkListFlags(WorkList); + return false; +} + + +//===----------------------------------------------------------------------===// +// Dumping, Viewing and Verification +//===----------------------------------------------------------------------===// + +#ifndef NDEBUG + +/// For the llvm's GraphWriter we copy the connection graph into CGForDotView. +/// This makes iterating over the edges easier. +struct CGForDotView { + + enum EdgeTypes { + PointsTo, + Deferred + }; + + struct Node { + EscapeAnalysis::CGNode *OrigNode; + CGForDotView *Graph; + SmallVector Children; + SmallVector ChildrenTypes; + }; + + CGForDotView(const EscapeAnalysis::ConnectionGraph *CG); + + std::string getNodeLabel(const Node *Node) const; + + std::string getNodeAttributes(const Node *Node) const; + + std::vector Nodes; + + SILFunction *F; + + const EscapeAnalysis::ConnectionGraph *OrigGraph; + + // The same IDs as the SILPrinter uses. + llvm::DenseMap InstToIDMap; + + typedef std::vector::iterator iterator; + typedef SmallVectorImpl::iterator child_iterator; +}; + +CGForDotView::CGForDotView(const EscapeAnalysis::ConnectionGraph *CG) : + F(CG->F), OrigGraph(CG) { + Nodes.resize(CG->Nodes.size()); + llvm::DenseMap Orig2Node; + int idx = 0; + for (auto *OrigNode : CG->Nodes) { + if (OrigNode->isMerged) + continue; + + Orig2Node[OrigNode] = &Nodes[idx++]; + } + Nodes.resize(idx); + CG->F->numberValues(InstToIDMap); + + idx = 0; + for (auto *OrigNode : CG->Nodes) { + if (OrigNode->isMerged) + continue; + + auto &Nd = Nodes[idx++]; + Nd.Graph = this; + Nd.OrigNode = OrigNode; + if (auto *PT = OrigNode->getPointsToEdge()) { + Nd.Children.push_back(Orig2Node[PT]); + Nd.ChildrenTypes.push_back(PointsTo); + } + for (auto *Def : OrigNode->defersTo) { + Nd.Children.push_back(Orig2Node[Def]); + Nd.ChildrenTypes.push_back(Deferred); + } + } +} + +std::string CGForDotView::getNodeLabel(const Node *Node) const { + std::string Label; + llvm::raw_string_ostream O(Label); + if (ValueBase *V = Node->OrigNode->V) + O << '%' << InstToIDMap.lookup(V) << '\n'; + + switch (Node->OrigNode->Type) { + case swift::EscapeAnalysis::NodeType::Content: + O << "content"; + break; + case swift::EscapeAnalysis::NodeType::Return: + O << "return"; + break; + default: { + std::string Inst; + llvm::raw_string_ostream OI(Inst); + SILValue(Node->OrigNode->V).print(OI); + size_t start = Inst.find(" = "); + if (start != std::string::npos) { + start += 3; + } else { + start = 2; + } + O << Inst.substr(start, 20); + break; + } + } + if (!Node->OrigNode->matchPointToOfDefers()) { + O << "\nPT mismatch: "; + if (Node->OrigNode->pointsTo) { + if (ValueBase *V = Node->OrigNode->pointsTo->V) + O << '%' << Node->Graph->InstToIDMap[V]; + } else { + O << "null"; + } + } + O.flush(); + return Label; +} + +std::string CGForDotView::getNodeAttributes(const Node *Node) const { + auto *Orig = Node->OrigNode; + std::string attr; + switch (Orig->Type) { + case swift::EscapeAnalysis::NodeType::Content: + attr = "style=\"rounded\""; + break; + case swift::EscapeAnalysis::NodeType::Argument: + case swift::EscapeAnalysis::NodeType::Return: + attr = "style=\"bold\""; + break; + default: + break; + } + if (Orig->getEscapeState() != swift::EscapeAnalysis::EscapeState::None && + !attr.empty()) + attr += ','; + + switch (Orig->getEscapeState()) { + case swift::EscapeAnalysis::EscapeState::None: + break; + case swift::EscapeAnalysis::EscapeState::Return: + attr += "color=\"green\""; + break; + case swift::EscapeAnalysis::EscapeState::Arguments: + attr += "color=\"blue\""; + break; + case swift::EscapeAnalysis::EscapeState::Global: + attr += "color=\"red\""; + break; + } + return attr; +} + +namespace llvm { + + + /// GraphTraits specialization so the CGForDotView can be + /// iterable by generic graph iterators. + template <> struct GraphTraits { + typedef CGForDotView::Node NodeType; + typedef CGForDotView::child_iterator ChildIteratorType; + + static NodeType *getEntryNode(NodeType *N) { return N; } + static inline ChildIteratorType child_begin(NodeType *N) { + return N->Children.begin(); + } + static inline ChildIteratorType child_end(NodeType *N) { + return N->Children.end(); + } + }; + + template <> struct GraphTraits + : public GraphTraits { + typedef CGForDotView *GraphType; + + static NodeType *getEntryNode(GraphType F) { return nullptr; } + + typedef CGForDotView::iterator nodes_iterator; + static nodes_iterator nodes_begin(GraphType OCG) { + return OCG->Nodes.begin(); + } + static nodes_iterator nodes_end(GraphType OCG) { return OCG->Nodes.end(); } + static unsigned size(GraphType CG) { return CG->Nodes.size(); } + }; + + /// This is everything the llvm::GraphWriter needs to write the call graph in + /// a dot file. + template <> + struct DOTGraphTraits : public DefaultDOTGraphTraits { + + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} + + static std::string getGraphName(const CGForDotView *Graph) { + return "CG for " + Graph->F->getName().str(); + } + + std::string getNodeLabel(const CGForDotView::Node *Node, + const CGForDotView *Graph) { + return Graph->getNodeLabel(Node); + } + + static std::string getNodeAttributes(const CGForDotView::Node *Node, + const CGForDotView *Graph) { + return Graph->getNodeAttributes(Node); + } + + static std::string getEdgeAttributes(const CGForDotView::Node *Node, + CGForDotView::child_iterator I, + const CGForDotView *Graph) { + unsigned ChildIdx = I - Node->Children.begin(); + switch (Node->ChildrenTypes[ChildIdx]) { + case CGForDotView::PointsTo: return ""; + case CGForDotView::Deferred: return "color=\"gray\""; + } + } + }; +} // end llvm namespace + +#endif + +void EscapeAnalysis::ConnectionGraph::viewCG() const { + /// When asserts are disabled, this should be a NoOp. +#ifndef NDEBUG + CGForDotView CGDot(this); + llvm::ViewGraph(&CGDot, "connection-graph"); +#endif +} + +void EscapeAnalysis::CGNode::dump() const { + llvm::errs() << getTypeStr(); + if (V) + llvm::errs() << ": " << *V; + else + llvm::errs() << '\n'; + + if (mergeTo) { + llvm::errs() << " -> merged to "; + mergeTo->dump(); + } +} + +const char *EscapeAnalysis::CGNode::getTypeStr() const { + switch (Type) { + case NodeType::Value: return "Val"; + case NodeType::Content: return "Con"; + case NodeType::Argument: return "Arg"; + case NodeType::Return: return "Ret"; + } +} + +void EscapeAnalysis::ConnectionGraph::dump() const { + print(llvm::errs()); +} + +void EscapeAnalysis::ConnectionGraph::print(llvm::raw_ostream &OS) const { +#ifndef NDEBUG + OS << "CG of " << F->getName() << '\n'; + + // Assign the same IDs to SILValues as the SILPrinter does. + llvm::DenseMap InstToIDMap; + InstToIDMap[nullptr] = (unsigned)-1; + F->numberValues(InstToIDMap); + + // Assign consecutive subindices for nodes which map to the same value. + llvm::DenseMap NumSubindicesPerValue; + llvm::DenseMap Node2Subindex; + + // Sort by SILValue ID+Subindex. To make the output somehow consistent with + // the output of the function's SIL. + auto sortNodes = [&](llvm::SmallVectorImpl &Nodes) { + std::sort(Nodes.begin(), Nodes.end(), + [&](CGNode *Nd1, CGNode *Nd2) -> bool { + unsigned VIdx1 = InstToIDMap[Nd1->V]; + unsigned VIdx2 = InstToIDMap[Nd2->V]; + if (VIdx1 != VIdx2) + return VIdx1 < VIdx2; + return Node2Subindex[Nd1] < Node2Subindex[Nd2]; + }); + }; + + auto NodeStr = [&](CGNode *Nd) -> std::string { + std::string Str; + if (Nd->V) { + llvm::raw_string_ostream OS(Str); + OS << '%' << InstToIDMap[Nd->V]; + unsigned Idx = Node2Subindex[Nd]; + if (Idx != 0) + OS << '.' << Idx; + OS.flush(); + } + return Str; + }; + + llvm::SmallVector SortedNodes; + for (CGNode *Nd : Nodes) { + if (!Nd->isMerged) { + unsigned &Idx = NumSubindicesPerValue[Nd->V]; + Node2Subindex[Nd] = Idx++; + SortedNodes.push_back(Nd); + } + } + sortNodes(SortedNodes); + + llvm::DenseMap Idx2UsePoint; + for (auto Iter : UsePoints) { + Idx2UsePoint[Iter.second] = Iter.first; + } + + for (CGNode *Nd : SortedNodes) { + OS << " " << Nd->getTypeStr() << ' ' << NodeStr(Nd) << " Esc: "; + switch (Nd->getEscapeState()) { + case EscapeState::None: { + const char *Separator = ""; + for (unsigned VIdx = Nd->UsePoints.find_first(); VIdx != -1u; + VIdx = Nd->UsePoints.find_next(VIdx)) { + ValueBase *V = Idx2UsePoint[VIdx]; + OS << Separator << '%' << InstToIDMap[V]; + Separator = ","; + } + break; + } + case EscapeState::Return: + OS << 'R'; + break; + case EscapeState::Arguments: + OS << 'A'; + break; + case EscapeState::Global: + OS << 'G'; + break; + } + OS << ", Succ: "; + const char *Separator = ""; + if (CGNode *PT = Nd->getPointsToEdge()) { + OS << '(' << NodeStr(PT) << ')'; + Separator = ", "; + } + llvm::SmallVector SortedDefers = Nd->defersTo; + sortNodes(SortedDefers); + for (CGNode *Def : SortedDefers) { + OS << Separator << NodeStr(Def); + Separator = ", "; + } + OS << '\n'; + } + OS << "End\n"; +#endif +} + +void EscapeAnalysis::ConnectionGraph::verify() const { +#ifndef NDEBUG + verifyStructure(); + + // Check graph invariance 4) + for (CGNode *Nd : Nodes) { + assert(Nd->matchPointToOfDefers()); + } +#endif +} + +void EscapeAnalysis::ConnectionGraph::verifyStructure() const { +#ifndef NDEBUG + for (CGNode *Nd : Nodes) { + if (Nd->isMerged) { + assert(Nd->mergeTo); + assert(!Nd->pointsTo); + assert(Nd->defersTo.empty()); + assert(Nd->Preds.empty()); + assert(Nd->Type == NodeType::Content); + continue; + } + // Check if predecessor and successor edges are linked correctly. + for (Predecessor Pred : Nd->Preds) { + CGNode *PredNode = Pred.getPointer(); + if (Pred.getInt() == EdgeType::Defer) { + assert(PredNode->findDeferred(Nd) != PredNode->defersTo.end()); + } else { + assert(Pred.getInt() == EdgeType::PointsTo); + assert(PredNode->getPointsToEdge() == Nd); + } + } + for (CGNode *Def : Nd->defersTo) { + assert(Def->findPred(Predecessor(Nd, EdgeType::Defer)) != Def->Preds.end()); + assert(Def != Nd); + } + if (CGNode *PT = Nd->getPointsToEdge()) { + assert(PT->Type == NodeType::Content); + assert(PT->findPred(Predecessor(Nd, EdgeType::PointsTo)) != PT->Preds.end()); + } + } +#endif +} + +//===----------------------------------------------------------------------===// +// EscapeAnalysis +//===----------------------------------------------------------------------===// + +EscapeAnalysis::EscapeAnalysis(SILModule *M) : + BottomUpIPAnalysis(AnalysisKind::Escape), M(M), + ArrayType(M->getASTContext().getArrayDecl()), BCA(nullptr) { +} + + +void EscapeAnalysis::initialize(SILPassManager *PM) { + BCA = PM->getAnalysis(); +} + +/// Returns true if we need to add defer edges for the arguments of a block. +static bool linkBBArgs(SILBasicBlock *BB) { + // Don't need to handle function arguments. + if (BB == &BB->getParent()->front()) + return false; + // We don't need to link to the try_apply's normal result argument, because + // we handle it separately in setAllEscaping() and mergeCalleeGraph(). + if (SILBasicBlock *SinglePred = BB->getSinglePredecessor()) { + auto *TAI = dyn_cast(SinglePred->getTerminator()); + if (TAI && BB == TAI->getNormalBB()) + return false; + } + return true; +} + +/// Returns true if the type \p Ty is a reference or transitively contains +/// a reference, i.e. if it is a "pointer" type. +static bool isOrContainsReference(SILType Ty, SILModule *Mod) { + if (Ty.hasReferenceSemantics()) + return true; + + if (Ty.getSwiftType() == Mod->getASTContext().TheRawPointerType) + return true; + + if (auto *Str = Ty.getStructOrBoundGenericStruct()) { + for (auto *Field : Str->getStoredProperties()) { + if (isOrContainsReference(Ty.getFieldType(Field, *Mod), Mod)) + return true; + } + return false; + } + if (auto TT = Ty.getAs()) { + for (unsigned i = 0, e = TT->getNumElements(); i != e; ++i) { + if (isOrContainsReference(Ty.getTupleElementType(i), Mod)) + return true; + } + return false; + } + if (auto En = Ty.getEnumOrBoundGenericEnum()) { + for (auto *ElemDecl : En->getAllElements()) { + if (ElemDecl->hasArgumentType() && + isOrContainsReference(Ty.getEnumElementType(ElemDecl, *Mod), Mod)) + return true; + } + return false; + } + return false; +} + +bool EscapeAnalysis::isPointer(ValueBase *V) { + assert(V->hasValue()); + SILType Ty = V->getType(0); + auto Iter = isPointerCache.find(Ty); + if (Iter != isPointerCache.end()) + return Iter->second; + + bool IP = (Ty.isAddress() || isOrContainsReference(Ty, M)); + isPointerCache[Ty] = IP; + return IP; +} + +void EscapeAnalysis::buildConnectionGraph(FunctionInfo *FInfo, + FunctionOrder &BottomUpOrder, + int RecursionDepth) { + if (BottomUpOrder.prepareForVisiting(FInfo)) + return; + + DEBUG(llvm::dbgs() << " >> build graph for " << + FInfo->Graph.F->getName() << '\n'); + + FInfo->NeedUpdateSummaryGraph = true; + + ConnectionGraph *ConGraph = &FInfo->Graph; + assert(ConGraph->isEmpty()); + + // We use a worklist for iteration to visit the blocks in dominance order. + llvm::SmallPtrSet VisitedBlocks; + llvm::SmallVector WorkList; + VisitedBlocks.insert(&*ConGraph->F->begin()); + WorkList.push_back(&*ConGraph->F->begin()); + + while (!WorkList.empty()) { + SILBasicBlock *BB = WorkList.pop_back_val(); + + // Create edges for the instructions. + for (auto &I : *BB) { + analyzeInstruction(&I, FInfo, BottomUpOrder, RecursionDepth); + } + for (auto &Succ : BB->getSuccessors()) { + if (VisitedBlocks.insert(Succ.getBB()).second) + WorkList.push_back(Succ.getBB()); + } + } + + // Second step: create defer-edges for block arguments. + for (SILBasicBlock &BB : *ConGraph->F) { + if (!linkBBArgs(&BB)) + continue; + + // Create defer-edges from the block arguments to it's values in the + // predecessor's terminator instructions. + for (SILArgument *BBArg : BB.getBBArgs()) { + CGNode *ArgNode = ConGraph->getNode(BBArg, this); + if (!ArgNode) + continue; + + llvm::SmallVector Incoming; + if (!BBArg->getIncomingValues(Incoming)) { + // We don't know where the block argument comes from -> treat it + // conservatively. + ConGraph->setEscapesGlobal(ArgNode); + continue; + } + + for (SILValue Src : Incoming) { + CGNode *SrcArg = ConGraph->getNode(Src, this); + if (SrcArg) { + ConGraph->defer(ArgNode, SrcArg); + } else { + ConGraph->setEscapesGlobal(ArgNode); + break; + } + } + } + } + DEBUG(llvm::dbgs() << " << finished graph for " << + FInfo->Graph.F->getName() << '\n'); +} + +void EscapeAnalysis::analyzeInstruction(SILInstruction *I, + FunctionInfo *FInfo, + FunctionOrder &BottomUpOrder, + int RecursionDepth) { + ConnectionGraph *ConGraph = &FInfo->Graph; + FullApplySite FAS = FullApplySite::isa(I); + if (FAS) { + ArraySemanticsCall ASC(FAS.getInstruction()); + switch (ASC.getKind()) { + case ArrayCallKind::kArrayPropsIsNativeTypeChecked: + case ArrayCallKind::kCheckSubscript: + case ArrayCallKind::kCheckIndex: + case ArrayCallKind::kGetCount: + case ArrayCallKind::kGetCapacity: + case ArrayCallKind::kMakeMutable: + // These array semantics calls do not capture anything. + return; + case ArrayCallKind::kArrayUninitialized: + // array.uninitialized may have a first argument which is the + // allocated array buffer. The call is like a struct(buffer) + // instruction. + if (CGNode *BufferNode = ConGraph->getNode(FAS.getArgument(0), this)) { + ConGraph->defer(ConGraph->getNode(I, this), BufferNode); + } + return; + case ArrayCallKind::kGetArrayOwner: + if (CGNode *BufferNode = ConGraph->getNode(ASC.getSelf(), this)) { + ConGraph->defer(ConGraph->getNode(I, this), BufferNode); + } + return; + case ArrayCallKind::kGetElement: + // This is like a load from a ref_element_addr. + if (FAS.getArgument(0).getType().isAddress()) { + if (CGNode *AddrNode = ConGraph->getNode(ASC.getSelf(), this)) { + if (CGNode *DestNode = ConGraph->getNode(FAS.getArgument(0), this)) { + // One content node for going from the array buffer pointer to + // the element address (like ref_element_addr). + CGNode *RefElement = ConGraph->getContentNode(AddrNode); + // Another content node to actually load the element. + CGNode *ArrayContent = ConGraph->getContentNode(RefElement); + // The content of the destination address. + CGNode *DestContent = ConGraph->getContentNode(DestNode); + ConGraph->defer(DestContent, ArrayContent); + return; + } + } + } + break; + case ArrayCallKind::kGetElementAddress: + // This is like a ref_element_addr. + if (CGNode *SelfNode = ConGraph->getNode(ASC.getSelf(), this)) { + ConGraph->defer(ConGraph->getNode(I, this), + ConGraph->getContentNode(SelfNode)); + } + return; + default: + break; + } + + if (RecursionDepth < MaxRecursionDepth) { + CalleeList Callees = BCA->getCalleeList(FAS); + if (Callees.allCalleesVisible()) { + // Derive the connection graph of the apply from the known callees. + for (SILFunction *Callee : Callees) { + FunctionInfo *CalleeInfo = getFunctionInfo(Callee); + CalleeInfo->addCaller(FInfo, FAS); + if (!CalleeInfo->isVisited()) { + // Recursively visit the called function. + buildConnectionGraph(CalleeInfo, BottomUpOrder, RecursionDepth + 1); + BottomUpOrder.tryToSchedule(CalleeInfo); + } + } + return; + } + } + + if (auto *Fn = FAS.getCalleeFunction()) { + if (Fn->getName() == "swift_bufferAllocate") + // The call is a buffer allocation, e.g. for Array. + return; + } + } + if (isProjection(I)) + return; + + // Instructions which return the address of non-writable memory cannot have + // an effect on escaping. + if (isNonWritableMemoryAddress(I)) + return; + + switch (I->getKind()) { + case ValueKind::AllocStackInst: + case ValueKind::AllocRefInst: + case ValueKind::AllocBoxInst: + ConGraph->getNode(I, this); + return; + + case ValueKind::DeallocStackInst: + case ValueKind::StrongRetainInst: + case ValueKind::StrongRetainUnownedInst: + case ValueKind::RetainValueInst: + case ValueKind::UnownedRetainInst: + case ValueKind::BranchInst: + case ValueKind::CondBranchInst: + case ValueKind::SwitchEnumInst: + case ValueKind::DebugValueInst: + case ValueKind::DebugValueAddrInst: + case ValueKind::ValueMetatypeInst: + case ValueKind::InitExistentialMetatypeInst: + case ValueKind::OpenExistentialMetatypeInst: + case ValueKind::ExistentialMetatypeInst: + // These instructions don't have any effect on escaping. + return; + case ValueKind::StrongReleaseInst: + case ValueKind::ReleaseValueInst: + case ValueKind::UnownedReleaseInst: { + SILValue OpV = I->getOperand(0); + if (CGNode *AddrNode = ConGraph->getNode(OpV, this)) { + // A release instruction may deallocate the pointer operand. This may + // capture any content of the released object, but not the pointer to + // the object itself (because it will be a dangling pointer after + // deallocation). + CGNode *CapturedByDeinit = ConGraph->getContentNode(AddrNode); + CapturedByDeinit = ConGraph->getContentNode(CapturedByDeinit); + if (isArrayOrArrayStorage(OpV)) { + CapturedByDeinit = ConGraph->getContentNode(CapturedByDeinit); + } + ConGraph->setEscapesGlobal(CapturedByDeinit); + } + return; + } + case ValueKind::LoadInst: + case ValueKind::LoadWeakInst: + // We treat ref_element_addr like a load (see NodeType::Content). + case ValueKind::RefElementAddrInst: + case ValueKind::ProjectBoxInst: + case ValueKind::InitExistentialAddrInst: + case ValueKind::OpenExistentialAddrInst: + if (isPointer(I)) { + CGNode *AddrNode = ConGraph->getNode(I->getOperand(0), this); + if (!AddrNode) { + // A load from an address we don't handle -> be conservative. + CGNode *ValueNode = ConGraph->getNode(I, this); + ConGraph->setEscapesGlobal(ValueNode); + return; + } + CGNode *PointsTo = ConGraph->getContentNode(AddrNode); + // No need for a separate node for the load instruction: + // just reuse the content node. + ConGraph->setNode(I, PointsTo); + } + return; + case ValueKind::StoreInst: + case ValueKind::StoreWeakInst: + if (CGNode *ValueNode = ConGraph->getNode(I->getOperand(StoreInst::Src), + this)) { + CGNode *AddrNode = ConGraph->getNode(I->getOperand(StoreInst::Dest), + this); + if (AddrNode) { + // Create a defer-edge from the content to the stored value. + CGNode *PointsTo = ConGraph->getContentNode(AddrNode); + ConGraph->defer(PointsTo, ValueNode); + } else { + // A store to an address we don't handle -> be conservative. + ConGraph->setEscapesGlobal(ValueNode); + } + } + return; + case ValueKind::PartialApplyInst: { + // The result of a partial_apply is a thick function which stores the + // boxed partial applied arguments. We create defer-edges from the + // partial_apply values to the arguments. + CGNode *ResultNode = ConGraph->getNode(I, this); + assert(ResultNode && "thick functions must have a CG node"); + for (const Operand &Op : I->getAllOperands()) { + if (CGNode *ArgNode = ConGraph->getNode(Op.get(), this)) { + ConGraph->defer(ResultNode, ArgNode); + } + } + return; + } + case ValueKind::SelectEnumInst: + case ValueKind::SelectEnumAddrInst: + analyzeSelectInst(cast(I), ConGraph); + return; + case ValueKind::SelectValueInst: + analyzeSelectInst(cast(I), ConGraph); + return; + case ValueKind::StructInst: + case ValueKind::TupleInst: + case ValueKind::EnumInst: { + // Aggregate composition is like assigning the aggregate fields to the + // resulting aggregate value. + CGNode *ResultNode = nullptr; + for (const Operand &Op : I->getAllOperands()) { + if (CGNode *FieldNode = ConGraph->getNode(Op.get(), this)) { + if (!ResultNode) { + // A small optimization to reduce the graph size: we re-use the + // first field node as result node. + ConGraph->setNode(I, FieldNode); + ResultNode = FieldNode; + assert(isPointer(I)); + } else { + ConGraph->defer(ResultNode, FieldNode); + } + } + } + return; + } + case ValueKind::UncheckedRefCastInst: + case ValueKind::ConvertFunctionInst: + case ValueKind::UpcastInst: + case ValueKind::InitExistentialRefInst: + case ValueKind::OpenExistentialRefInst: + case ValueKind::UnownedToRefInst: + case ValueKind::RefToUnownedInst: + case ValueKind::RawPointerToRefInst: + case ValueKind::RefToRawPointerInst: + case ValueKind::RefToBridgeObjectInst: + case ValueKind::BridgeObjectToRefInst: + case ValueKind::UncheckedAddrCastInst: + case ValueKind::UnconditionalCheckedCastInst: + // A cast is almost like a projection. + if (CGNode *OpNode = ConGraph->getNode(I->getOperand(0), this)) { + ConGraph->setNode(I, OpNode); + } + break; + case ValueKind::UncheckedRefCastAddrInst: { + auto *URCAI = cast(I); + CGNode *SrcNode = ConGraph->getNode(URCAI->getSrc(), this); + CGNode *DestNode = ConGraph->getNode(URCAI->getDest(), this); + assert(SrcNode && DestNode && "must have nodes for address operands"); + ConGraph->defer(DestNode, SrcNode); + return; + } + case ValueKind::ReturnInst: + if (CGNode *ValueNd = ConGraph->getNode(cast(I)->getOperand(), + this)) { + ConGraph->defer(ConGraph->getReturnNode(), + ValueNd); + } + return; + default: + // We handle all other instructions conservatively. + setAllEscaping(I, ConGraph); + return; + } +} + +template void EscapeAnalysis:: +analyzeSelectInst(SelectInst *SI, ConnectionGraph *ConGraph) { + if (auto *ResultNode = ConGraph->getNode(SI, this)) { + // Connect all case values to the result value. + // Note that this does not include the first operand (the condition). + for (unsigned Idx = 0, End = SI->getNumCases(); Idx < End; ++Idx) { + SILValue CaseVal = SI->getCase(Idx).second; + auto *ArgNode = ConGraph->getNode(CaseVal, this); + assert(ArgNode && + "there should be an argument node if there is a result node"); + ConGraph->defer(ResultNode, ArgNode); + } + // ... also including the default value. + auto *DefaultNode = ConGraph->getNode(SI->getDefaultResult(), this); + assert(DefaultNode && + "there should be an argument node if there is a result node"); + ConGraph->defer(ResultNode, DefaultNode); + } +} + +bool EscapeAnalysis::isArrayOrArrayStorage(SILValue V) { + for (;;) { + if (V.getType().getNominalOrBoundGenericNominal() == ArrayType) + return true; + + if (!isProjection(V.getDef())) + return false; + + V = dyn_cast(V.getDef())->getOperand(0); + } +} + +void EscapeAnalysis::setAllEscaping(SILInstruction *I, + ConnectionGraph *ConGraph) { + if (auto *TAI = dyn_cast(I)) { + setEscapesGlobal(ConGraph, TAI->getNormalBB()->getBBArg(0)); + setEscapesGlobal(ConGraph, TAI->getErrorBB()->getBBArg(0)); + } + // Even if the instruction does not write memory we conservatively set all + // operands to escaping, because they may "escape" to the result value in + // an unspecified way. For example consider bit-casting a pointer to an int. + // In this case we don't even create a node for the resulting int value. + for (const Operand &Op : I->getAllOperands()) { + SILValue OpVal = Op.get(); + if (!isNonWritableMemoryAddress(OpVal.getDef())) + setEscapesGlobal(ConGraph, OpVal.getDef()); + } + // Even if the instruction does not write memory it could e.g. return the + // address of global memory. Therefore we have to define it as escaping. + setEscapesGlobal(ConGraph, I); +} + +void EscapeAnalysis::recompute(FunctionInfo *Initial) { + allocNewUpdateID(); + + DEBUG(llvm::dbgs() << "recompute escape analysis with UpdateID " << + getCurrentUpdateID() << '\n'); + + // Collect and analyze all functions to recompute, starting at Initial. + FunctionOrder BottomUpOrder(getCurrentUpdateID()); + buildConnectionGraph(Initial, BottomUpOrder, 0); + + // Build the bottom-up order. + BottomUpOrder.tryToSchedule(Initial); + BottomUpOrder.finishScheduling(); + + // Second step: propagate the connection graphs up the call-graph until it + // stabilizes. + int Iteration = 0; + bool NeedAnotherIteration; + do { + DEBUG(llvm::dbgs() << "iteration " << Iteration << '\n'); + NeedAnotherIteration = false; + + for (FunctionInfo *FInfo : BottomUpOrder) { + bool SummaryGraphChanged = false; + if (FInfo->NeedUpdateSummaryGraph) { + DEBUG(llvm::dbgs() << " create summary graph for " << + FInfo->Graph.F->getName() << '\n'); + + FInfo->Graph.propagateEscapeStates(); + + // Derive the summary graph of the current function. Even if the + // complete graph of the function did change, it does not mean that the + // summary graph will change. + SummaryGraphChanged = mergeSummaryGraph(&FInfo->SummaryGraph, + &FInfo->Graph); + FInfo->NeedUpdateSummaryGraph = false; + } + + if (Iteration < MaxGraphMerges) { + // In the first iteration we have to merge the summary graphs, even if + // they didn't change (in not recomputed leaf functions). + if (Iteration == 0 || SummaryGraphChanged) { + // Merge the summary graph into all callers. + for (const auto &E : FInfo->getCallers()) { + assert(E.isValid()); + + // Only include callers which we are actually recomputing. + if (BottomUpOrder.wasRecomputedWithCurrentUpdateID(E.Caller)) { + DEBUG(llvm::dbgs() << " merge " << FInfo->Graph.F->getName() << + " into " << E.Caller->Graph.F->getName() << '\n'); + + if (mergeCalleeGraph(E.FAS, &E.Caller->Graph, + &FInfo->SummaryGraph)) { + E.Caller->NeedUpdateSummaryGraph = true; + if (!E.Caller->isScheduledAfter(FInfo)) { + // This happens if we have a cycle in the call-graph. + NeedAnotherIteration = true; + } + } + } + } + } + } else if (Iteration == MaxGraphMerges) { + // Limit the total number of iterations. First to limit compile time, + // second to make sure that the loop terminates. Theoretically this + // should always be the case, but who knows? + DEBUG(llvm::dbgs() << " finalize conservatively " << + FInfo->Graph.F->getName() << '\n'); + for (const auto &E : FInfo->getCallers()) { + assert(E.isValid()); + if (BottomUpOrder.wasRecomputedWithCurrentUpdateID(E.Caller)) { + setAllEscaping(E.FAS.getInstruction(), &E.Caller->Graph); + E.Caller->NeedUpdateSummaryGraph = true; + NeedAnotherIteration = true; + } + } + } + } + Iteration++; + } while (NeedAnotherIteration); + + for (FunctionInfo *FInfo : BottomUpOrder) { + if (BottomUpOrder.wasRecomputedWithCurrentUpdateID(FInfo)) { + FInfo->Graph.computeUsePoints(); + FInfo->Graph.verify(); + FInfo->SummaryGraph.verify(); + } + } +} + +bool EscapeAnalysis::mergeCalleeGraph(FullApplySite FAS, + ConnectionGraph *CallerGraph, + ConnectionGraph *CalleeGraph) { + CGNodeMap Callee2CallerMapping; + + // First map the callee parameters to the caller arguments. + SILFunction *Callee = CalleeGraph->F; + unsigned numCallerArgs = FAS.getNumArguments(); + unsigned numCalleeArgs = Callee->getArguments().size(); + assert(numCalleeArgs >= numCallerArgs); + for (unsigned Idx = 0; Idx < numCalleeArgs; ++Idx) { + // If there are more callee parameters than arguments it means that the + // callee is the result of a partial_apply - a thick function. A thick + // function also references the boxed partially applied arguments. + // Therefore we map all the extra callee parameters to the callee operand + // of the apply site. + SILValue CallerArg = (Idx < numCallerArgs ? FAS.getArgument(Idx) : + FAS.getCallee()); + if (CGNode *CalleeNd = CalleeGraph->getNode(Callee->getArgument(Idx), this)) { + Callee2CallerMapping.add(CalleeNd, CallerGraph->getNode(CallerArg, this)); + } + } + + // Map the return value. + if (CGNode *RetNd = CalleeGraph->getReturnNodeOrNull()) { + ValueBase *CallerReturnVal = nullptr; + if (auto *TAI = dyn_cast(FAS.getInstruction())) { + CallerReturnVal = TAI->getNormalBB()->getBBArg(0); + } else { + CallerReturnVal = FAS.getInstruction(); + } + CGNode *CallerRetNd = CallerGraph->getNode(CallerReturnVal, this); + Callee2CallerMapping.add(RetNd, CallerRetNd); + } + return CallerGraph->mergeFrom(CalleeGraph, Callee2CallerMapping); +} + +bool EscapeAnalysis::mergeSummaryGraph(ConnectionGraph *SummaryGraph, + ConnectionGraph *Graph) { + + // Make a 1-to-1 mapping of all arguments and the return value. + CGNodeMap Mapping; + for (SILArgument *Arg : Graph->F->getArguments()) { + if (CGNode *ArgNd = Graph->getNode(Arg, this)) { + Mapping.add(ArgNd, SummaryGraph->getNode(Arg, this)); + } + } + if (CGNode *RetNd = Graph->getReturnNodeOrNull()) { + Mapping.add(RetNd, SummaryGraph->getReturnNode()); + } + // Merging actually creates the summary graph. + return SummaryGraph->mergeFrom(Graph, Mapping); +} + +bool EscapeAnalysis::canEscapeToUsePoint(SILValue V, ValueBase *UsePoint, + ConnectionGraph *ConGraph) { + + assert((FullApplySite::isa(UsePoint) || isa(UsePoint)) && + "use points are only created for calls and refcount instructions"); + + CGNode *Node = ConGraph->getNodeOrNull(V, this); + if (!Node) + return true; + + // First check if there are escape paths which we don't explicitly see + // in the graph. + if (Node->escapesInsideFunction(isNotAliasingArgument(V))) + return true; + + // No hidden escapes: check if the Node is reachable from the UsePoint. + return ConGraph->isUsePoint(UsePoint, Node); +} + +bool EscapeAnalysis::canEscapeTo(SILValue V, FullApplySite FAS) { + // If it's not a local object we don't know anything about the value. + if (!pointsToLocalObject(V)) + return true; + auto *ConGraph = getConnectionGraph(FAS.getFunction()); + return canEscapeToUsePoint(V, FAS.getInstruction(), ConGraph); +} + +static bool hasReferenceSemantics(SILType T) { + // Exclude address types. + return T.isObject() && T.hasReferenceSemantics(); +} + +bool EscapeAnalysis::canObjectOrContentEscapeTo(SILValue V, FullApplySite FAS) { + // If it's not a local object we don't know anything about the value. + if (!pointsToLocalObject(V)) + return true; + + auto *ConGraph = getConnectionGraph(FAS.getFunction()); + CGNode *Node = ConGraph->getNodeOrNull(V, this); + if (!Node) + return true; + + // First check if there are escape paths which we don't explicitly see + // in the graph. + if (Node->escapesInsideFunction(isNotAliasingArgument(V))) + return true; + + // Check if the object itself can escape to the called function. + SILInstruction *UsePoint = FAS.getInstruction(); + if (ConGraph->isUsePoint(UsePoint, Node)) + return true; + + if (hasReferenceSemantics(V.getType())) { + // Check if the object "content", i.e. a pointer to one of its stored + // properties, can escape to the called function. + CGNode *ContentNode = ConGraph->getContentNode(Node); + if (ContentNode->escapesInsideFunction(false)) + return true; + + if (ConGraph->isUsePoint(UsePoint, ContentNode)) + return true; + } + return false; +} + +bool EscapeAnalysis::canEscapeTo(SILValue V, RefCountingInst *RI) { + // If it's not a local object we don't know anything about the value. + if (!pointsToLocalObject(V)) + return true; + auto *ConGraph = getConnectionGraph(RI->getFunction()); + return canEscapeToUsePoint(V, RI, ConGraph); +} + +/// Utility to get the function which contains both values \p V1 and \p V2. +static SILFunction *getCommonFunction(SILValue V1, SILValue V2) { + SILBasicBlock *BB1 = V1->getParentBB(); + SILBasicBlock *BB2 = V2->getParentBB(); + if (!BB1 || !BB2) + return nullptr; + + SILFunction *F = BB1->getParent(); + assert(BB2->getParent() == F && "values not in same function"); + return F; +} + +bool EscapeAnalysis::canEscapeToValue(SILValue V, SILValue To) { + if (!pointsToLocalObject(V)) + return true; + + SILFunction *F = getCommonFunction(V, To); + if (!F) + return true; + auto *ConGraph = getConnectionGraph(F); + + CGNode *Node = ConGraph->getNodeOrNull(V, this); + if (!Node) + return true; + CGNode *ToNode = ConGraph->getNodeOrNull(To, this); + if (!ToNode) + return true; + return ConGraph->isReachable(Node, ToNode); +} + +bool EscapeAnalysis::canPointToSameMemory(SILValue V1, SILValue V2) { + // At least one of the values must be a non-escaping local object. + bool isLocal1 = pointsToLocalObject(V1); + bool isLocal2 = pointsToLocalObject(V2); + if (!isLocal1 && !isLocal2) + return true; + + SILFunction *F = getCommonFunction(V1, V2); + if (!F) + return true; + auto *ConGraph = getConnectionGraph(F); + + CGNode *Node1 = ConGraph->getNodeOrNull(V1, this); + if (!Node1) + return true; + CGNode *Node2 = ConGraph->getNodeOrNull(V2, this); + if (!Node2) + return true; + + // Finish the check for one value being a non-escaping local object. + if (isLocal1 && Node1->escapesInsideFunction(isNotAliasingArgument(V1))) + isLocal1 = false; + + if (isLocal2 && Node2->escapesInsideFunction(isNotAliasingArgument(V2))) + isLocal2 = false; + + if (!isLocal1 && !isLocal2) + return true; + + // Check if both nodes may point to the same content. + CGNode *Content1 = ConGraph->getContentNode(Node1); + CGNode *Content2 = ConGraph->getContentNode(Node2); + + SILType T1 = V1.getType(); + SILType T2 = V2.getType(); + if (T1.isAddress() && T2.isAddress()) { + return Content1 == Content2; + } + if (hasReferenceSemantics(T1) && hasReferenceSemantics(T2)) { + return Content1 == Content2; + } + // As we model the ref_element_addr instruction as a content-relationship, we + // have to go down one content level if just one of the values is a + // ref-counted object. + if (T1.isAddress() && hasReferenceSemantics(T2)) { + Content2 = ConGraph->getContentNode(Content2); + return Content1 == Content2; + } + if (T2.isAddress() && hasReferenceSemantics(T1)) { + Content1 = ConGraph->getContentNode(Content1); + return Content1 == Content2; + } + return true; +} + +void EscapeAnalysis::invalidate(InvalidationKind K) { + Function2Info.clear(); + Allocator.DestroyAll(); + DEBUG(llvm::dbgs() << "invalidate all\n"); +} + +void EscapeAnalysis::invalidate(SILFunction *F, InvalidationKind K) { + if (FunctionInfo *FInfo = Function2Info.lookup(F)) { + DEBUG(llvm::dbgs() << " invalidate " << FInfo->Graph.F->getName() << '\n'); + invalidateIncludingAllCallers(FInfo); + } +} + +void EscapeAnalysis::handleDeleteNotification(ValueBase *I) { + if (SILBasicBlock *Parent = I->getParentBB()) { + SILFunction *F = Parent->getParent(); + if (FunctionInfo *FInfo = Function2Info.lookup(F)) { + if (FInfo->isValid()) { + FInfo->Graph.removeFromGraph(I); + FInfo->SummaryGraph.removeFromGraph(I); + } + } + } +} + +SILAnalysis *swift::createEscapeAnalysis(SILModule *M) { + return new EscapeAnalysis(M); +} diff --git a/lib/SILAnalysis/FunctionOrder.cpp b/lib/SILOptimizer/Analysis/FunctionOrder.cpp similarity index 92% rename from lib/SILAnalysis/FunctionOrder.cpp rename to lib/SILOptimizer/Analysis/FunctionOrder.cpp index ff5d5d65092ed..b069e51bd791d 100644 --- a/lib/SILAnalysis/FunctionOrder.cpp +++ b/lib/SILOptimizer/Analysis/FunctionOrder.cpp @@ -1,8 +1,8 @@ -//===----- FunctionOrder.cpp - Utility for function ordering --------------===// +//===--- FunctionOrder.cpp - Utility for function ordering ----------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/FunctionOrder.h" +#include "swift/SILOptimizer/Analysis/FunctionOrder.h" #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" diff --git a/lib/SILAnalysis/IVAnalysis.cpp b/lib/SILOptimizer/Analysis/IVAnalysis.cpp similarity index 93% rename from lib/SILAnalysis/IVAnalysis.cpp rename to lib/SILOptimizer/Analysis/IVAnalysis.cpp index bdb7c0add8ca2..50268b024895d 100644 --- a/lib/SILAnalysis/IVAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/IVAnalysis.cpp @@ -1,8 +1,8 @@ -//===----------------- IVAnalysis.cpp - SIL IV Analysis -------*- C++ -*---===// +//===--- IVAnalysis.cpp - SIL IV Analysis -----------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/IVAnalysis.h" +#include "swift/SILOptimizer/Analysis/IVAnalysis.h" #include "swift/SIL/PatternMatch.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILValue.h" diff --git a/lib/SILOptimizer/Analysis/LoopAnalysis.cpp b/lib/SILOptimizer/Analysis/LoopAnalysis.cpp new file mode 100644 index 0000000000000..6323fe4de99b4 --- /dev/null +++ b/lib/SILOptimizer/Analysis/LoopAnalysis.cpp @@ -0,0 +1,34 @@ +//===--- LoopAnalysis.cpp - SIL Loop Analysis -------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "swift/SIL/Dominance.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +SILLoopInfo *SILLoopAnalysis::newFunctionAnalysis(SILFunction *F) { + assert(DA != nullptr && "Expect a valid dominance analysis"); + DominanceInfo *DT = DA->get(F); + assert(DT != nullptr && "Expect a valid dominance information"); + return new SILLoopInfo(F, DT); +} + +void SILLoopAnalysis::initialize(SILPassManager *PM) { + DA = PM->getAnalysis(); +} + +SILAnalysis *swift::createLoopAnalysis(SILModule *M) { + return new SILLoopAnalysis(M); +} diff --git a/lib/SILAnalysis/LoopRegionAnalysis.cpp b/lib/SILOptimizer/Analysis/LoopRegionAnalysis.cpp similarity index 89% rename from lib/SILAnalysis/LoopRegionAnalysis.cpp rename to lib/SILOptimizer/Analysis/LoopRegionAnalysis.cpp index f0dbf36feec00..07b505658b2ec 100644 --- a/lib/SILAnalysis/LoopRegionAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/LoopRegionAnalysis.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-loop-region-analysis" -#include "swift/SILAnalysis/LoopRegionAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h" #include "swift/Basic/Range.h" #include "llvm/Support/DOTGraphTraits.h" #include "llvm/Support/CommandLine.h" @@ -177,7 +177,7 @@ void LoopRegionFunctionInfo::verify() { if (!R->ParentID.hasValue()) { auto NLSuccs = R->getNonLocalSuccs(); assert(NLSuccs.begin() == NLSuccs.end() && - "Can not have non local " + "Cannot have non local " "successors without a parent node"); continue; } @@ -285,13 +285,13 @@ LoopRegionFunctionInfo::createRegion(BlockTy *BB, unsigned RPONum) { void LoopRegionFunctionInfo::initializeBlockRegionSuccessors( BlockTy *BB, RegionTy *BBRegion, PostOrderFunctionInfo *PI) { - for (auto &SuccIter : BB->getSuccessors()) { - unsigned SuccRPOIndex = *PI->getRPONumber(SuccIter.getBB()); - auto *SuccRegion = createRegion(SuccIter.getBB(), SuccRPOIndex); + for (auto *SuccBB : BB->getSuccessorBlocks()) { + unsigned SuccRPOIndex = *PI->getRPONumber(SuccBB); + auto *SuccRegion = createRegion(SuccBB, SuccRPOIndex); BBRegion->addSucc(SuccRegion); SuccRegion->addPred(BBRegion); DEBUG(llvm::dbgs() << " Succ: "; - SuccIter.getBB()->printAsOperand(llvm::dbgs()); + SuccBB->printAsOperand(llvm::dbgs()); llvm::dbgs() << " RPONum: " << SuccRPOIndex << "\n"); } } @@ -503,11 +503,9 @@ rewriteLoopHeaderPredecessors(LoopTy *SubLoop, RegionTy *SubLoopRegion) { return SubLoopHeaderRegion; } -static void -getExitingRegions(LoopRegionFunctionInfo *LRFI, - SILLoop *Loop, - LoopRegion *LRegion, - llvm::SmallVectorImpl &ExitingRegions) { +static void getExitingRegions(LoopRegionFunctionInfo *LRFI, SILLoop *Loop, + LoopRegion *LRegion, + llvm::SmallVectorImpl &ExitingRegions) { llvm::SmallVector ExitingBlocks; Loop->getExitingBlocks(ExitingBlocks); @@ -520,12 +518,16 @@ getExitingRegions(LoopRegionFunctionInfo *LRFI, Region = LRFI->getRegion(RegionParentID); RegionParentID = Region->getParentID(); } - ExitingRegions.push_back(Region); + ExitingRegions.push_back(Region->getID()); } // We can have a loop subregion that has multiple exiting edges from the // current loop. We do not want to visit that loop subregion multiple // times. So we unique the exiting region list. + // + // In order to make sure we have a deterministic ordering when we visiting + // exiting subregions, we need to sort our exiting regions by ID, not pointer + // value. sortUnique(ExitingRegions); } @@ -548,45 +550,68 @@ getExitingRegions(LoopRegionFunctionInfo *LRFI, void LoopRegionFunctionInfo:: rewriteLoopExitingBlockSuccessors(LoopTy *Loop, RegionTy *LRegion) { - llvm::SmallVector ExitingRegions; - getExitingRegions(this, Loop, LRegion, ExitingRegions); - + // Begin by using loop info and loop region info to find all of the exiting + // regions. + // + // We do this by looking up the exiting blocks and finding the outermost + // region which the block is a subregion of. Since we initialize our data + // structure by processing the loop nest bottom up, this should always give us + // the correct region for the level of the loop we are processing. + auto &ExitingSubregions = LRegion->getSubregionData().ExitingSubregions; + getExitingRegions(this, Loop, LRegion, ExitingSubregions); + + // Then for each exiting region ER of the Loop L... DEBUG(llvm::dbgs() << " Visiting Exit Blocks...\n"); - for (auto *ExitingRegion : ExitingRegions) { + for (unsigned ExitingSubregionID : ExitingSubregions) { + auto *ExitingSubregion = getRegion(ExitingSubregionID); DEBUG(llvm::dbgs() << " Exiting Region: " - << ExitingRegion->getID() << "\n"); - for (auto SuccID : ExitingRegion->getSuccs()) { + << ExitingSubregion->getID() << "\n"); + + // For each successor region S of ER... + for (auto SuccID : ExitingSubregion->getSuccs()) { DEBUG(llvm::dbgs() << " Succ: " << SuccID.ID << ". IsNonLocal: " << (SuccID.IsNonLocal ? "true" : "false") << "\n"); + // If S is not contained in L, then: + // + // 1. The successor/predecessor edge in between S and ER with a new + // successor/predecessor edge in between S and L. + // 2. ER is given a non-local successor edge that points at the successor + // index in L that points at S. This will enable us to recover the + // original edge if we need to. + // + // Then we continue. auto *SuccRegion = getRegion(SuccID.ID); if (!LRegion->containsSubregion(SuccRegion)) { DEBUG(llvm::dbgs() << " Is not a subregion, replacing.\n"); - SuccRegion->replacePred(ExitingRegion->ID, LRegion->ID); - if (ExitingRegion->IsUnknownControlFlowEdgeTail) + SuccRegion->replacePred(ExitingSubregion->ID, LRegion->ID); + if (ExitingSubregion->IsUnknownControlFlowEdgeTail) LRegion->IsUnknownControlFlowEdgeTail = true; // If the successor region is already in this LRegion this returns that // regions index. Otherwise it returns a new index. unsigned Index = LRegion->addSucc(SuccRegion); - ExitingRegion->replaceSucc(SuccID, - LoopRegion::SuccessorID(Index, true)); - propagateLivenessDownNonLocalSuccessorEdges(ExitingRegion); + ExitingSubregion->replaceSucc(SuccID, + LoopRegion::SuccessorID(Index, true)); + propagateLivenessDownNonLocalSuccessorEdges(ExitingSubregion); continue; } - // If the rpo number of the successor is less than the RPO number of the - // BB, then we know that it is not a backedge. - if (SuccRegion->getRPONumber() > ExitingRegion->getRPONumber()) { + // Otherwise, we know S is in L. If the RPO number of S is less than the + // RPO number of ER, then we know that the edge in between them is not a + // backedge and thus we do not want to clip the edge. + if (SuccRegion->getRPONumber() > ExitingSubregion->getRPONumber()) { DEBUG(llvm::dbgs() << " Is a subregion, but not a " "backedge, not removing.\n"); continue; } + + // If the edge from ER to S is a back edge, we want to clip it. DEBUG(llvm::dbgs() << " Is a subregion and a backedge, " "removing.\n"); auto Iter = - std::remove(SuccRegion->Preds.begin(), SuccRegion->Preds.end(), - ExitingRegion->getID()); + std::remove(SuccRegion->Preds.begin(), SuccRegion->Preds.end(), + ExitingSubregion->getID()); SuccRegion->Preds.erase(Iter); } } @@ -660,9 +685,17 @@ propagateLivenessDownNonLocalSuccessorEdges(LoopRegion *Parent) { while (Worklist.size()) { LoopRegion *R = Worklist.pop_back_val(); + for (unsigned SubregionID : R->getSubregions()) { LoopRegion *Subregion = getRegion(SubregionID); bool ShouldVisit = false; + + // Make sure we can identify when the subregion has at least one dead + // non-local edge and no remaining live edges. In such a case, we need to + // remove the subregion from the exiting subregion array of R after the + // loop. + bool HasDeadNonLocalEdge = false; + bool HasNoLiveLocalEdges = true; for (auto &SuccID : Subregion->Succs) { // If the successor is already dead, skip it. We should have visited all // its children when we marked it as dead. @@ -673,13 +706,16 @@ propagateLivenessDownNonLocalSuccessorEdges(LoopRegion *Parent) { if (!SuccID->IsNonLocal) continue; - // Finally if the non-local successor edge points to a parent successor - // that is not dead continue. - if (R->Succs[SuccID->ID].hasValue()) + // If the non-local successor edge points to a parent successor that is + // not dead continue. + if (R->Succs[SuccID->ID].hasValue()) { + HasNoLiveLocalEdges = false; continue; + } - // Ok, we found a target! Mark is as dead and make sure that we visit - // the subregion's children. + // Ok, we found a target! Mark it as dead and make sure that we visit + // the subregion's children if it is not a block. + HasDeadNonLocalEdge = true; ShouldVisit = true; // This is safe to do since when erasing in a BlotSetVector, we do not @@ -687,6 +723,16 @@ propagateLivenessDownNonLocalSuccessorEdges(LoopRegion *Parent) { Subregion->Succs.erase(*SuccID); } + // Remove Subregion from R's exiting subregion array if Subregion no + // longer has /any/ non-local successors. + if (HasDeadNonLocalEdge && HasNoLiveLocalEdges) { + auto &ExitingSubregions = R->getSubregionData().ExitingSubregions; + auto Iter = + std::remove(ExitingSubregions.begin(), ExitingSubregions.end(), + Subregion->getID()); + ExitingSubregions.erase(Iter); + } + if (ShouldVisit) Worklist.push_back(Subregion); } @@ -788,6 +834,21 @@ void LoopRegionFunctionInfo::print(raw_ostream &os) const { for (unsigned I : SortedSuccs) { os << "\n (parentindex:" << I << ")"; } + os << ")\n"; + + os << " (exiting-subregs"; + if (!R->isBlock()) { + llvm::SmallVector ExitingSubregions; + auto ExitingSubRegs = R->getExitingSubregions(); + std::copy(ExitingSubRegs.begin(), ExitingSubRegs.end(), + std::back_inserter(ExitingSubregions)); + std::sort(ExitingSubregions.begin(), ExitingSubregions.begin()); + for (unsigned SubregionID : ExitingSubregions) { + os << "\n "; + LoopRegion *Subregion = getRegion(SubregionID); + Subregion->print(os, true); + } + } os << "))\n"; } } diff --git a/lib/SILAnalysis/MemoryBehavior.cpp b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp similarity index 78% rename from lib/SILAnalysis/MemoryBehavior.cpp rename to lib/SILOptimizer/Analysis/MemoryBehavior.cpp index b24dce0acc61d..3e2a2c9365e36 100644 --- a/lib/SILAnalysis/MemoryBehavior.cpp +++ b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,14 +12,20 @@ #define DEBUG_TYPE "sil-membehavior" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/SideEffectAnalysis.h" -#include "swift/SILAnalysis/ValueTracking.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/EscapeAnalysis.h" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" #include "swift/SIL/SILVisitor.h" #include "llvm/Support/Debug.h" using namespace swift; +// The MemoryBehavior Cache must not grow beyond this size. +// We limit the size of the MB cache to 2**14 because we want to limit the +// memory usage of this cache. +static const int MemoryBehaviorAnalysisMaxCacheSize = 16384; + //===----------------------------------------------------------------------===// // Memory Behavior Implementation //===----------------------------------------------------------------------===// @@ -38,6 +44,8 @@ class MemoryBehaviorVisitor SideEffectAnalysis *SEA; + EscapeAnalysis *EA; + /// The value we are attempting to discover memory behavior relative to. SILValue V; @@ -49,9 +57,10 @@ class MemoryBehaviorVisitor RetainObserveKind InspectionMode; public: - MemoryBehaviorVisitor(AliasAnalysis *AA, SideEffectAnalysis *SEA, SILValue V, + MemoryBehaviorVisitor(AliasAnalysis *AA, SideEffectAnalysis *SEA, + EscapeAnalysis *EA, SILValue V, RetainObserveKind IgnoreRefCountIncs) - : AA(AA), SEA(SEA), V(V), InspectionMode(IgnoreRefCountIncs) {} + : AA(AA), SEA(SEA), EA(EA), V(V), InspectionMode(IgnoreRefCountIncs) {} SILType getValueTBAAType() { if (!TypedAccessTy) @@ -94,7 +103,7 @@ class MemoryBehaviorVisitor MemBehavior visitReleaseValueInst(ReleaseValueInst *BI); // Instructions which are none if our SILValue does not alias one of its - // arguments. If we can not prove such a thing, return the relevant memory + // arguments. If we cannot prove such a thing, return the relevant memory // behavior. #define OPERANDALIAS_MEMBEHAVIOR_INST(Name) \ MemBehavior visit##Name(Name *I) { \ @@ -139,7 +148,6 @@ class MemoryBehaviorVisitor return I->getMemoryBehavior(); \ } REFCOUNTINC_MEMBEHAVIOR_INST(StrongRetainInst) - REFCOUNTINC_MEMBEHAVIOR_INST(StrongRetainAutoreleasedInst) REFCOUNTINC_MEMBEHAVIOR_INST(StrongRetainUnownedInst) REFCOUNTINC_MEMBEHAVIOR_INST(UnownedRetainInst) REFCOUNTINC_MEMBEHAVIOR_INST(RetainValueInst) @@ -168,7 +176,7 @@ MemBehavior MemoryBehaviorVisitor::visitStoreInst(StoreInst *SI) { return MemBehavior::None; // If the store dest cannot alias the pointer in question, then the - // specified value can not be modified by the store. + // specified value cannot be modified by the store. if (AA->isNoAlias(SI->getDest(), V, computeTBAAType(SI->getDest()), getValueTBAAType())) { DEBUG(llvm::dbgs() << " Store Dst does not alias inst. Returning " @@ -215,11 +223,9 @@ MemBehavior MemoryBehaviorVisitor::visitBuiltinInst(BuiltinInst *BI) { MemBehavior MemoryBehaviorVisitor::visitTryApplyInst(TryApplyInst *AI) { MemBehavior Behavior = MemBehavior::MayHaveSideEffects; - // If it is an allocstack which does not escape, tryapply instruction can not - // read/modify the memory. - if (auto *ASI = dyn_cast(getUnderlyingObject(V))) - if (isNonEscapingLocalObject(ASI->getAddressResult())) - Behavior = MemBehavior::None; + // Ask escape analysis. + if (!EA->canObjectOrContentEscapeTo(V, AI)) + Behavior = MemBehavior::None; // Otherwise be conservative and return that we may have side effects. DEBUG(llvm::dbgs() << " Found tryapply, returning " << Behavior << '\n'); @@ -247,58 +253,46 @@ MemBehavior MemoryBehaviorVisitor::visitApplyInst(ApplyInst *AI) { Idx < End && Behavior < MemBehavior::MayHaveSideEffects; ++Idx) { auto &ArgEffect = ApplyEffects.getParameterEffects()[Idx]; auto ArgBehavior = ArgEffect.getMemBehavior(InspectionMode); - if (ArgBehavior > Behavior) { + auto NewBehavior = combineMemoryBehavior(Behavior, ArgBehavior); + if (NewBehavior != Behavior) { SILValue Arg = AI->getArgument(Idx); // We only consider the argument effects if the argument aliases V. if (!Arg.getType().isAddress() || !AA->isNoAlias(Arg, V, computeTBAAType(Arg), getValueTBAAType())) { - Behavior = ArgBehavior; + Behavior = NewBehavior; } } } } - if (Behavior > MemBehavior::MayRead && isLetPointer(V)) - Behavior = MemBehavior::MayRead; + if (Behavior > MemBehavior::None) { + if (Behavior > MemBehavior::MayRead && isLetPointer(V)) + Behavior = MemBehavior::MayRead; - // If it is an allocstack which does not escape, apply instruction can not - // read/modify the memory. - if (auto *ASI = dyn_cast(getUnderlyingObject(V))) - if (isNonEscapingLocalObject(ASI->getAddressResult())) { + // Ask escape analysis. + if (!EA->canObjectOrContentEscapeTo(V, AI)) Behavior = MemBehavior::None; - } - + } DEBUG(llvm::dbgs() << " Found apply, returning " << Behavior << '\n'); return Behavior; } MemBehavior MemoryBehaviorVisitor::visitStrongReleaseInst(StrongReleaseInst *SI) { - // Need to make sure that the allocated memory does not escape. - // AllocBox to stack does not check for whether the address of promoted - // allocstack can escape. - // - // TODO: come up with a test case which shows isNonEscapingLocalObject is - // necessary. - if (AllocStackInst *ASI = dyn_cast(getUnderlyingObject(V))) - if (isNonEscapingLocalObject(ASI->getAddressResult())) - return MemBehavior::None; + if (!EA->canEscapeTo(V, SI)) + return MemBehavior::None; return MemBehavior::MayHaveSideEffects; } MemBehavior MemoryBehaviorVisitor::visitUnownedReleaseInst(UnownedReleaseInst *SI) { - // Need to make sure that the allocated memory does not escape. - if (AllocStackInst *ASI = dyn_cast(getUnderlyingObject(V))) - if (isNonEscapingLocalObject(ASI->getAddressResult())) - return MemBehavior::None; + if (!EA->canEscapeTo(V, SI)) + return MemBehavior::None; return MemBehavior::MayHaveSideEffects; } MemBehavior MemoryBehaviorVisitor::visitReleaseValueInst(ReleaseValueInst *SI) { - // Need to make sure that the allocated memory does not escape. - if (AllocStackInst *ASI = dyn_cast(getUnderlyingObject(V))) - if (isNonEscapingLocalObject(ASI->getAddressResult())) - return MemBehavior::None; + if (!EA->canEscapeTo(V, SI)) + return MemBehavior::None; return MemBehavior::MayHaveSideEffects; } @@ -308,9 +302,43 @@ MemBehavior MemoryBehaviorVisitor::visitReleaseValueInst(ReleaseValueInst *SI) { MemBehavior AliasAnalysis::computeMemoryBehavior(SILInstruction *Inst, SILValue V, - RetainObserveKind InspectionMode) { + RetainObserveKind InspectionMode) { + MemBehaviorKeyTy Key = toMemoryBehaviorKey(SILValue(Inst), V, + InspectionMode); + // Check if we've already computed this result. + auto It = MemoryBehaviorCache.find(Key); + if (It != MemoryBehaviorCache.end()) { + return It->second; + } + + // Flush the cache if the size of the cache is too large. + if (MemoryBehaviorCache.size() > MemoryBehaviorAnalysisMaxCacheSize) { + MemoryBehaviorCache.clear(); + MemoryBehaviorValueBaseToIndex.clear(); + + // Key is no longer valid as we cleared the MemoryBehaviorValueBaseToIndex. + Key = toMemoryBehaviorKey(SILValue(Inst), V, InspectionMode); + } + + // Calculate the aliasing result and store it in the cache. + auto Result = computeMemoryBehaviorInner(Inst, V, InspectionMode); + MemoryBehaviorCache[Key] = Result; + return Result; +} + +MemBehavior +AliasAnalysis::computeMemoryBehaviorInner(SILInstruction *Inst, SILValue V, + RetainObserveKind InspectionMode) { DEBUG(llvm::dbgs() << "GET MEMORY BEHAVIOR FOR:\n " << *Inst << " " << *V.getDef()); assert(SEA && "SideEffectsAnalysis must be initialized!"); - return MemoryBehaviorVisitor(this, SEA, V, InspectionMode).visit(Inst); + return MemoryBehaviorVisitor(this, SEA, EA, V, InspectionMode).visit(Inst); +} + +MemBehaviorKeyTy AliasAnalysis::toMemoryBehaviorKey(SILValue V1, SILValue V2, + RetainObserveKind M) { + size_t idx1 = MemoryBehaviorValueBaseToIndex.getIndex(V1.getDef()); + size_t idx2 = MemoryBehaviorValueBaseToIndex.getIndex(V2.getDef()); + unsigned R2 = V2.getResultNumber(); + return {idx1, idx2, R2, M}; } diff --git a/lib/SILAnalysis/RCIdentityAnalysis.cpp b/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp similarity index 98% rename from lib/SILAnalysis/RCIdentityAnalysis.cpp rename to lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp index f2753f2d052cd..517d0a86bfd9b 100644 --- a/lib/SILAnalysis/RCIdentityAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/RCIdentityAnalysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" #include "swift/SIL/SILInstruction.h" #include "llvm/Support/CommandLine.h" @@ -113,7 +113,7 @@ static SILValue stripRCIdentityPreservingInsts(SILValue V) { /// V is the incoming value for the SILArgument A on at least one path. Find a /// value that is trivially RC-identical to V and dominates the argument's -/// block. If such a value exists, it is a candidate for RC-indentity with the +/// block. If such a value exists, it is a candidate for RC-identity with the /// argument itself--the caller must verify this after evaluating all paths. SILValue RCIdentityFunctionInfo::stripOneRCIdentityIncomingValue(SILArgument *A, SILValue V) { @@ -162,7 +162,7 @@ static llvm::Optional proveNonPayloadedEnumCase(SILBasicBlock *BB, bool RCIdentityFunctionInfo:: findDominatingNonPayloadedEdge(SILBasicBlock *IncomingEdgeBB, SILValue RCIdentity) { - // First grab the NonPayloadedEnumBB and RCIdentityBB. If we can not find + // First grab the NonPayloadedEnumBB and RCIdentityBB. If we cannot find // either of them, return false. SILBasicBlock *RCIdentityBB = RCIdentity->getParentBB(); if (!RCIdentityBB) @@ -226,7 +226,7 @@ findDominatingNonPayloadedEdge(SILBasicBlock *IncomingEdgeBB, return false; } -/// Return the underlying SILValue after stripping off SILArguments that can not +/// Return the underlying SILValue after stripping off SILArguments that cannot /// affect RC identity. /// /// This code is meant to enable RCIdentity to be ascertained in the following @@ -317,7 +317,7 @@ SILValue RCIdentityFunctionInfo::stripRCIdentityPreservingArgs(SILValue V, continue; } - // Try to strip off the RCIdentityPresrvingArg for IV. If it matches + // Try to strip off the RCIdentityPreservingArg for IV. If it matches // FirstIV, we may be able to succeed here. if (FirstIV == stripOneRCIdentityIncomingValue(A, IV)) continue; diff --git a/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp new file mode 100644 index 0000000000000..7b3b663267424 --- /dev/null +++ b/lib/SILOptimizer/Analysis/SideEffectAnalysis.cpp @@ -0,0 +1,492 @@ +//===--- SideEffectAnalysis.cpp - SIL Side Effect Analysis ----------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-sea" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/FunctionOrder.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" +#include "swift/SIL/SILArgument.h" + +using namespace swift; + +using FunctionEffects = SideEffectAnalysis::FunctionEffects; +using Effects = SideEffectAnalysis::Effects; +using MemoryBehavior = SILInstruction::MemoryBehavior; + +MemoryBehavior +FunctionEffects::getMemBehavior(RetainObserveKind ScanKind) const { + + bool Observe = (ScanKind == RetainObserveKind::ObserveRetains); + if ((Observe && mayAllocObjects()) || mayReadRC()) + return MemoryBehavior::MayHaveSideEffects; + + // Start with the global effects. + auto Behavior = GlobalEffects.getMemBehavior(ScanKind); + + // Add effects from the parameters. + for (auto &ParamEffect : ParamEffects) { + MemoryBehavior ArgBehavior = ParamEffect.getMemBehavior(ScanKind); + + Behavior = combineMemoryBehavior(Behavior, ArgBehavior); + + // Stop the scan if we've reached the highest level of side effect. + if (Behavior == MemoryBehavior::MayHaveSideEffects) + break; + } + return Behavior; +} + +bool FunctionEffects::mergeFrom(const FunctionEffects &RHS) { + bool Changed = mergeFlags(RHS); + Changed |= GlobalEffects.mergeFrom(RHS.GlobalEffects); + Changed |= LocalEffects.mergeFrom(RHS.LocalEffects); + // In case of an external function, the RHS may have 0 arguments. + unsigned NumArgs = RHS.ParamEffects.size(); + for (unsigned Idx = 0; Idx < NumArgs; Idx++) { + // In case of a partial_apply, the RHS (= callee) may have more arguments + // than the apply instruction. + if (Idx < ParamEffects.size()) { + Changed |= ParamEffects[Idx].mergeFrom(RHS.ParamEffects[Idx]); + } else { + Changed |= GlobalEffects.mergeFrom(RHS.ParamEffects[Idx]); + } + } + return Changed; +} + +bool FunctionEffects::mergeFromApply( + const FunctionEffects &ApplyEffects, FullApplySite FAS) { + bool Changed = mergeFlags(ApplyEffects); + Changed |= GlobalEffects.mergeFrom(ApplyEffects.GlobalEffects); + unsigned numCallerArgs = FAS.getNumArguments(); + unsigned numCalleeArgs = ApplyEffects.ParamEffects.size(); + assert(numCalleeArgs >= numCallerArgs); + for (unsigned Idx = 0; Idx < numCalleeArgs; Idx++) { + // Map the callee argument effects to parameters of this function. + // If there are more callee parameters than arguments it means that the + // callee is the result of a partial_apply. + Effects *E = (Idx < numCallerArgs ? getEffectsOn(FAS.getArgument(Idx)) : + &GlobalEffects); + Changed |= E->mergeFrom(ApplyEffects.ParamEffects[Idx]); + } + return Changed; +} + +void FunctionEffects::dump() const { + llvm::errs() << *this << '\n'; +} + +static SILValue skipAddrProjections(SILValue V) { + for (;;) { + switch (V->getKind()) { + case ValueKind::IndexAddrInst: + case ValueKind::IndexRawPointerInst: + case ValueKind::StructElementAddrInst: + case ValueKind::TupleElementAddrInst: + case ValueKind::RefElementAddrInst: + case ValueKind::UncheckedTakeEnumDataAddrInst: + case ValueKind::PointerToAddressInst: + V = cast(V)->getOperand(0); + break; + default: + return V; + } + } + llvm_unreachable("there is no escape from an infinite loop"); +} + +static SILValue skipValueProjections(SILValue V) { + for (;;) { + switch (V->getKind()) { + case ValueKind::StructExtractInst: + case ValueKind::TupleExtractInst: + case ValueKind::UncheckedEnumDataInst: + case ValueKind::UncheckedTrivialBitCastInst: + V = cast(V)->getOperand(0); + break; + default: + return V; + } + } + llvm_unreachable("there is no escape from an infinite loop"); +} + +Effects *FunctionEffects::getEffectsOn(SILValue Addr) { + SILValue BaseAddr = skipValueProjections(skipAddrProjections(Addr)); + switch (BaseAddr->getKind()) { + case swift::ValueKind::SILArgument: { + // Can we associate the address to a function parameter? + SILArgument *Arg = cast(BaseAddr); + if (Arg->isFunctionArg()) { + return &ParamEffects[Arg->getIndex()]; + } + break; + } + case ValueKind::AllocStackInst: + case ValueKind::AllocRefInst: + case ValueKind::AllocRefDynamicInst: + case ValueKind::AllocBoxInst: + // Effects on locally allocated storage. + return &LocalEffects; + default: + break; + } + // Everything else. + return &GlobalEffects; +} + +bool SideEffectAnalysis::getDefinedEffects(FunctionEffects &Effects, + SILFunction *F) { + if (F->getLoweredFunctionType()->isNoReturn()) { + Effects.Traps = true; + return true; + } + switch (F->getEffectsKind()) { + case EffectsKind::ReadNone: + return true; + case EffectsKind::ReadOnly: + // @effects(readonly) is worthless if we have owned parameters, because + // the release inside the callee may call a deinit, which itself can do + // anything. + if (!F->hasOwnedParameters()) { + Effects.GlobalEffects.Reads = true; + return true; + } + break; + default: + break; + } + + return false; +} + +bool SideEffectAnalysis::getSemanticEffects(FunctionEffects &FE, + ArraySemanticsCall ASC) { + assert(ASC.hasSelf()); + auto &SelfEffects = FE.ParamEffects[FE.ParamEffects.size() - 1]; + + // Currently we only handle array semantics. + // TODO: also handle other semantic functions. + + switch (ASC.getKind()) { + case ArrayCallKind::kGetCount: + case ArrayCallKind::kGetCapacity: + if (!ASC.mayHaveBridgedObjectElementType()) { + SelfEffects.Reads = true; + SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); + return true; + } + return false; + + case ArrayCallKind::kCheckSubscript: + case ArrayCallKind::kCheckIndex: + if (!ASC.mayHaveBridgedObjectElementType()) { + SelfEffects.Reads = true; + SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); + FE.Traps = true; + return true; + } + return false; + + case ArrayCallKind::kGetElement: + if (!ASC.mayHaveBridgedObjectElementType()) { + SelfEffects.Reads = true; + SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); + if (((ApplyInst *)ASC)->getOrigCalleeType()->hasIndirectResult()) + FE.ParamEffects[0].Writes = true; + return true; + } + return false; + + case ArrayCallKind::kArrayPropsIsNativeTypeChecked: + SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); + // The isNative checks evaluate to a constant (no read!) if the array + // cannot be bridged. + if (ASC.mayHaveBridgedObjectElementType()) + SelfEffects.Reads = true; + return true; + + case ArrayCallKind::kGetElementAddress: + SelfEffects.Reads = true; + SelfEffects.Releases |= !ASC.hasGuaranteedSelf(); + return true; + + case ArrayCallKind::kMakeMutable: + if (!ASC.mayHaveBridgedObjectElementType()) { + SelfEffects.Writes = true; + FE.GlobalEffects.Releases = true; + FE.AllocsObjects = true; + FE.ReadsRC = true; + return true; + } + return false; + + default: + return false; + } +} + +void SideEffectAnalysis::analyzeFunction(FunctionInfo *FInfo, + FunctionOrder &BottomUpOrder, + int RecursionDepth) { + FInfo->NeedUpdateCallers = true; + + if (BottomUpOrder.prepareForVisiting(FInfo)) + return; + + // Handle @effects attributes + if (getDefinedEffects(FInfo->FE, FInfo->F)) { + DEBUG(llvm::dbgs() << " -- has defined effects " << + FInfo->F->getName() << '\n'); + return; + } + + if (!FInfo->F->isDefinition()) { + // We can't assume anything about external functions. + DEBUG(llvm::dbgs() << " -- is external " << FInfo->F->getName() << '\n'); + FInfo->FE.setWorstEffects(); + return; + } + + DEBUG(llvm::dbgs() << " >> analyze " << FInfo->F->getName() << '\n'); + + // Check all instructions of the function + for (auto &BB : *FInfo->F) { + for (auto &I : BB) { + analyzeInstruction(FInfo, &I, BottomUpOrder, RecursionDepth); + } + } + DEBUG(llvm::dbgs() << " << finished " << FInfo->F->getName() << '\n'); +} + +void SideEffectAnalysis::analyzeInstruction(FunctionInfo *FInfo, + SILInstruction *I, + FunctionOrder &BottomUpOrder, + int RecursionDepth) { + if (FullApplySite FAS = FullApplySite::isa(I)) { + // Is this a call to a semantics function? + ArraySemanticsCall ASC(I); + if (ASC && ASC.hasSelf()) { + FunctionEffects ApplyEffects(FAS.getNumArguments()); + if (getSemanticEffects(ApplyEffects, ASC)) { + FInfo->FE.mergeFromApply(ApplyEffects, FAS); + return; + } + } + + if (SILFunction *SingleCallee = FAS.getCalleeFunction()) { + // Does the function have any @effects? + if (getDefinedEffects(FInfo->FE, SingleCallee)) + return; + } + + if (RecursionDepth < MaxRecursionDepth) { + CalleeList Callees = BCA->getCalleeList(FAS); + if (Callees.allCalleesVisible()) { + // Derive the effects of the apply from the known callees. + for (SILFunction *Callee : Callees) { + FunctionInfo *CalleeInfo = getFunctionInfo(Callee); + CalleeInfo->addCaller(FInfo, FAS); + if (!CalleeInfo->isVisited()) { + // Recursively visit the called function. + analyzeFunction(CalleeInfo, BottomUpOrder, RecursionDepth + 1); + BottomUpOrder.tryToSchedule(CalleeInfo); + } + } + return; + } + } + // Be conservative for everything else. + FInfo->FE.setWorstEffects(); + return; + } + // Handle some kind of instructions specially. + switch (I->getKind()) { + case ValueKind::AllocStackInst: + case ValueKind::DeallocStackInst: + return; + case ValueKind::StrongRetainInst: + case ValueKind::StrongRetainUnownedInst: + case ValueKind::RetainValueInst: + case ValueKind::UnownedRetainInst: + FInfo->FE.getEffectsOn(I->getOperand(0))->Retains = true; + return; + case ValueKind::StrongReleaseInst: + case ValueKind::ReleaseValueInst: + case ValueKind::UnownedReleaseInst: + FInfo->FE.getEffectsOn(I->getOperand(0))->Releases = true; + + // TODO: Check the call graph to be less conservative about what + // destructors might be called. + FInfo->FE.setWorstEffects(); + return; + case ValueKind::LoadInst: + FInfo->FE.getEffectsOn(cast(I)->getOperand())->Reads = true; + return; + case ValueKind::StoreInst: + FInfo->FE.getEffectsOn(cast(I)->getDest())->Writes = true; + return; + case ValueKind::CondFailInst: + FInfo->FE.Traps = true; + return; + case ValueKind::PartialApplyInst: + FInfo->FE.AllocsObjects = true; + return; + case ValueKind::BuiltinInst: { + auto &BI = cast(I)->getBuiltinInfo(); + switch (BI.ID) { + case BuiltinValueKind::IsUnique: + // TODO: derive this information in a more general way, e.g. add it + // to Builtins.def + FInfo->FE.ReadsRC = true; + break; + default: + break; + } + // Detailed memory effects of builtins are handled below by checking the + // memory behavior of the instruction. + break; + } + default: + break; + } + + if (isa(I)) { + // Excluding AllocStackInst (which is handled above). + FInfo->FE.AllocsObjects = true; + } + + // Check the general memory behavior for instructions we didn't handle above. + switch (I->getMemoryBehavior()) { + case MemoryBehavior::None: + break; + case MemoryBehavior::MayRead: + FInfo->FE.GlobalEffects.Reads = true; + break; + case MemoryBehavior::MayWrite: + FInfo->FE.GlobalEffects.Writes = true; + break; + case MemoryBehavior::MayReadWrite: + FInfo->FE.GlobalEffects.Reads = true; + FInfo->FE.GlobalEffects.Writes = true; + break; + case MemoryBehavior::MayHaveSideEffects: + FInfo->FE.setWorstEffects(); + break; + } + if (I->mayTrap()) + FInfo->FE.Traps = true; +} + +void SideEffectAnalysis::initialize(SILPassManager *PM) { + BCA = PM->getAnalysis(); +} + +void SideEffectAnalysis::recompute(FunctionInfo *Initial) { + allocNewUpdateID(); + + DEBUG(llvm::dbgs() << "recompute side-effect analysis with UpdateID " << + getCurrentUpdateID() << '\n'); + + // Collect and analyze all functions to recompute, starting at Initial. + FunctionOrder BottomUpOrder(getCurrentUpdateID()); + analyzeFunction(Initial, BottomUpOrder, 0); + + // Build the bottom-up order. + BottomUpOrder.tryToSchedule(Initial); + BottomUpOrder.finishScheduling(); + + // Second step: propagate the side-effect information up the call-graph until + // it stabilizes. + bool NeedAnotherIteration; + do { + DEBUG(llvm::dbgs() << "new iteration\n"); + NeedAnotherIteration = false; + + for (FunctionInfo *FInfo : BottomUpOrder) { + if (FInfo->NeedUpdateCallers) { + DEBUG(llvm::dbgs() << " update callers of " << FInfo->F->getName() << + '\n'); + FInfo->NeedUpdateCallers = false; + + // Propagate the side-effects to all callers. + for (const auto &E : FInfo->getCallers()) { + assert(E.isValid()); + + // Only include callers which we are actually recomputing. + if (BottomUpOrder.wasRecomputedWithCurrentUpdateID(E.Caller)) { + DEBUG(llvm::dbgs() << " merge into caller " << + E.Caller->F->getName() << '\n'); + + if (E.Caller->FE.mergeFromApply(FInfo->FE, E.FAS)) { + E.Caller->NeedUpdateCallers = true; + if (!E.Caller->isScheduledAfter(FInfo)) { + // This happens if we have a cycle in the call-graph. + NeedAnotherIteration = true; + } + } + } + } + } + } + } while (NeedAnotherIteration); +} + +void SideEffectAnalysis::getEffects(FunctionEffects &ApplyEffects, FullApplySite FAS) { + assert(ApplyEffects.ParamEffects.size() == 0 && + "Not using a new ApplyEffects?"); + ApplyEffects.ParamEffects.resize(FAS.getNumArguments()); + + // Is this a call to a semantics function? + ArraySemanticsCall ASC(FAS.getInstruction()); + if (ASC && ASC.hasSelf()) { + if (getSemanticEffects(ApplyEffects, ASC)) + return; + } + + if (SILFunction *SingleCallee = FAS.getCalleeFunction()) { + // Does the function have any @effects? + if (getDefinedEffects(ApplyEffects, SingleCallee)) + return; + } + + auto Callees = BCA->getCalleeList(FAS); + if (!Callees.allCalleesVisible()) { + ApplyEffects.setWorstEffects(); + return; + } + + // We can see all the callees. So we just merge the effects from all of + // them. + for (auto *Callee : Callees) { + const FunctionEffects &CalleeFE = getEffects(Callee); + ApplyEffects.mergeFrom(CalleeFE); + } +} + +void SideEffectAnalysis::invalidate(InvalidationKind K) { + Function2Info.clear(); + Allocator.DestroyAll(); + DEBUG(llvm::dbgs() << "invalidate all\n"); +} + +void SideEffectAnalysis::invalidate(SILFunction *F, InvalidationKind K) { + if (FunctionInfo *FInfo = Function2Info.lookup(F)) { + DEBUG(llvm::dbgs() << " invalidate " << FInfo->F->getName() << '\n'); + invalidateIncludingAllCallers(FInfo); + } +} + +SILAnalysis *swift::createSideEffectAnalysis(SILModule *M) { + return new SideEffectAnalysis(); +} diff --git a/lib/SILAnalysis/SimplifyInstruction.cpp b/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp similarity index 96% rename from lib/SILAnalysis/SimplifyInstruction.cpp rename to lib/SILOptimizer/Analysis/SimplifyInstruction.cpp index c9add68356041..6bd74754c46ea 100644 --- a/lib/SILAnalysis/SimplifyInstruction.cpp +++ b/lib/SILOptimizer/Analysis/SimplifyInstruction.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-simplify" -#include "swift/SILAnalysis/SimplifyInstruction.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/SimplifyInstruction.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "swift/SIL/PatternMatch.h" #include "swift/SIL/SILVisitor.h" @@ -29,6 +29,7 @@ namespace { public: SILValue visitSILInstruction(SILInstruction *I) { return SILValue(); } + SILValue visitProjectBoxInst(ProjectBoxInst *PBI); SILValue visitTupleExtractInst(TupleExtractInst *TEI); SILValue visitStructExtractInst(StructExtractInst *SEI); SILValue visitEnumInst(EnumInst *EI); @@ -129,6 +130,16 @@ SILValue InstSimplifier::visitTupleInst(TupleInst *TI) { return SILValue(); } +SILValue InstSimplifier::visitProjectBoxInst(ProjectBoxInst *PBI) { + // project_box(alloc_box#0) -> alloc_box#1 + if (auto TheBox = dyn_cast(PBI->getOperand())) { + assert(PBI->getOperand().getResultNumber() == 0 + && "should only be able to project box result of alloc_box"); + return TheBox->getAddressResult(); + } + return SILValue(); +} + SILValue InstSimplifier::visitTupleExtractInst(TupleExtractInst *TEI) { // tuple_extract(tuple(x, y), 0) -> x if (TupleInst *TheTuple = dyn_cast(TEI->getOperand())) @@ -180,7 +191,7 @@ static SILValue simplifyEnumFromUncheckedEnumData(EnumInst *EI) { SILValue EnumOp = UEDI->getOperand(); - // Same enum elements don't necesserily imply same enum types. + // Same enum elements don't necessarily imply same enum types. // Enum types may be different if the enum is generic, e.g. // E.Case and E.Case. SILType OriginalEnum = EnumOp.getType(); @@ -196,7 +207,7 @@ SILValue InstSimplifier::visitSelectEnumInst(SelectEnumInst *SEI) { auto *EI = dyn_cast(SEI->getEnumOperand()); if (EI && EI->getType() == SEI->getEnumOperand().getType()) { - // Simplify a select_enum on a enum instruction. + // Simplify a select_enum on an enum instruction. // %27 = enum $Optional, #Optional.Some!enumelt.1, %20 : $Int // %28 = integer_literal $Builtin.Int1, -1 // %29 = integer_literal $Builtin.Int1, 0 diff --git a/lib/SILOptimizer/Analysis/TypeExpansionAnalysis.cpp b/lib/SILOptimizer/Analysis/TypeExpansionAnalysis.cpp new file mode 100644 index 0000000000000..9d4d421f19d24 --- /dev/null +++ b/lib/SILOptimizer/Analysis/TypeExpansionAnalysis.cpp @@ -0,0 +1,57 @@ +//===--- TypeExpansionAnalysis.cpp - Type Expansion Analysis --------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "typeexpansion-analysis" +#include "swift/SILOptimizer/Analysis/TypeExpansionAnalysis.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SIL/SILModule.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +// The TypeExpansion Cache must not grow beyond this size. +// We limit the size of the MB cache to 2**12 because we want to limit the +// memory usage of this cache. +static const int TypeExpansionAnalysisMaxCacheSize = 4096; + +const ProjectionPathList & +TypeExpansionAnalysis::getTypeExpansionProjectionPaths(SILType B, SILModule *Mod, + TEKind Kind) { + // Which cache we should be looking up. + bool IsLeaf = Kind == TEKind::TELeaf; + TypeExpansionMap &Cache = IsLeaf ? TELeafCache : TENodeCache; + + // Check whether we have the type expansion. + auto Iter = Cache.find(B); + if (Iter != Cache.end()) { + return Iter->second; + } + + // Flush the cache if the size of the cache is too large. + if (Cache.size() > TypeExpansionAnalysisMaxCacheSize) { + Cache.clear(); + } + + // Build the type expansion for the leaf nodes. + if (IsLeaf) { + ProjectionPath::expandTypeIntoLeafProjectionPaths(B, Mod, Cache[B]); + return Cache[B]; + } + + // Build the type expansion for the internal and leaf nodes. + ProjectionPath::expandTypeIntoNodeProjectionPaths(B, Mod, Cache[B]); + return Cache[B]; +} + +SILAnalysis *swift::createTypeExpansionAnalysis(SILModule *M) { + return new TypeExpansionAnalysis(M); +} diff --git a/lib/SILOptimizer/Analysis/ValueTracking.cpp b/lib/SILOptimizer/Analysis/ValueTracking.cpp new file mode 100644 index 0000000000000..055ee5e81124b --- /dev/null +++ b/lib/SILOptimizer/Analysis/ValueTracking.cpp @@ -0,0 +1,382 @@ +//===--- ValueTracking.cpp - SIL Value Tracking Analysis --------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-value-tracking" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Analysis/SimplifyInstruction.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SIL/SILValue.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SIL/PatternMatch.h" +#include "llvm/Support/Debug.h" +using namespace swift; +using namespace swift::PatternMatch; + +/// Strip off casts/indexing insts/address projections from V until there is +/// nothing left to strip. +/// FIXME: Maybe put this on SILValue? +/// FIXME: Why don't we strip projections after stripping indexes? +SILValue swift::getUnderlyingObject(SILValue V) { + while (true) { + SILValue V2 = V.stripCasts().stripAddressProjections().stripIndexingInsts(); + if (V2 == V) + return V2; + V = V2; + } +} + +bool swift::isNotAliasingArgument(SILValue V, + InoutAliasingAssumption isInoutAliasing) { + auto *Arg = dyn_cast(V); + if (!Arg || !Arg->isFunctionArg()) + return false; + + return isNotAliasedIndirectParameter(Arg->getParameterInfo().getConvention(), + isInoutAliasing); +} + +bool swift::pointsToLocalObject(SILValue V, + InoutAliasingAssumption isInoutAliasing) { + V = getUnderlyingObject(V); + return isa(V) || + isNotAliasingArgument(V, isInoutAliasing); +} + +/// Check if the value \p Value is known to be zero, non-zero or unknown. +IsZeroKind swift::isZeroValue(SILValue Value) { + // Inspect integer literals. + if (auto *L = dyn_cast(Value.getDef())) { + if (!L->getValue()) + return IsZeroKind::Zero; + return IsZeroKind::NotZero; + } + + // Inspect Structs. + switch (Value.getDef()->getKind()) { + // Bitcast of zero is zero. + case ValueKind::UncheckedTrivialBitCastInst: + // Extracting from a zero class returns a zero. + case ValueKind::StructExtractInst: + return isZeroValue(cast(Value.getDef())->getOperand(0)); + default: + break; + } + + // Inspect casts. + if (auto *BI = dyn_cast(Value.getDef())) { + switch (BI->getBuiltinInfo().ID) { + case BuiltinValueKind::IntToPtr: + case BuiltinValueKind::PtrToInt: + case BuiltinValueKind::ZExt: + return isZeroValue(BI->getArguments()[0]); + case BuiltinValueKind::UDiv: + case BuiltinValueKind::SDiv: { + if (IsZeroKind::Zero == isZeroValue(BI->getArguments()[0])) + return IsZeroKind::Zero; + return IsZeroKind::Unknown; + } + case BuiltinValueKind::Mul: + case BuiltinValueKind::SMulOver: + case BuiltinValueKind::UMulOver: { + IsZeroKind LHS = isZeroValue(BI->getArguments()[0]); + IsZeroKind RHS = isZeroValue(BI->getArguments()[1]); + if (LHS == IsZeroKind::Zero || RHS == IsZeroKind::Zero) + return IsZeroKind::Zero; + + return IsZeroKind::Unknown; + } + default: + return IsZeroKind::Unknown; + } + } + + // Handle results of XXX_with_overflow arithmetic. + if (auto *T = dyn_cast(Value.getDef())) { + // Make sure we are extracting the number value and not + // the overflow flag. + if (T->getFieldNo() != 0) + return IsZeroKind::Unknown; + + BuiltinInst *BI = dyn_cast(T->getOperand()); + if (!BI) + return IsZeroKind::Unknown; + + return isZeroValue(BI); + } + + //Inspect allocations and pointer literals. + if (isa(Value.getDef()) || + isa(Value.getDef()) || + isa(Value.getDef())) + return IsZeroKind::NotZero; + + return IsZeroKind::Unknown; +} + +/// Check if the sign bit of the value \p V is known to be: +/// set (true), not set (false) or unknown (None). +Optional swift::computeSignBit(SILValue V) { + SILValue Value = V; + while (true) { + auto *Def = Value.getDef(); + // Inspect integer literals. + if (auto *L = dyn_cast(Def)) { + if (L->getValue().isNonNegative()) + return false; + return true; + } + + switch (Def->getKind()) { + // Bitcast of non-negative is non-negative + case ValueKind::UncheckedTrivialBitCastInst: + Value = cast(Def)->getOperand(0); + continue; + default: + break; + } + + if (auto *BI = dyn_cast(Def)) { + switch (BI->getBuiltinInfo().ID) { + // Sizeof always returns non-negative results. + case BuiltinValueKind::Sizeof: + return false; + // Strideof always returns non-negative results. + case BuiltinValueKind::Strideof: + return false; + // StrideofNonZero always returns positive results. + case BuiltinValueKind::StrideofNonZero: + return false; + // Alignof always returns non-negative results. + case BuiltinValueKind::Alignof: + return false; + // Both operands to AND must have the top bit set for V to. + case BuiltinValueKind::And: { + // Compute the sign bit of the LHS and RHS. + auto Left = computeSignBit(BI->getArguments()[0]); + auto Right = computeSignBit(BI->getArguments()[1]); + + // We don't know either's sign bit so we can't + // say anything about the result. + if (!Left && !Right) { + return None; + } + + // Now we know that we were able to determine the sign bit + // for at least one of Left/Right. Canonicalize the determined + // sign bit on the left. + if (Right) { + std::swap(Left, Right); + } + + // We know we must have at least one result and it must be on + // the Left. If Right is still not None, then get both values + // and AND them together. + if (Right) { + return Left.getValue() && Right.getValue(); + } + + // Now we know that Right is None and Left has a value. If + // Left's value is true, then we return None as the final + // sign bit depends on the unknown Right value. + if (Left.getValue()) { + return None; + } + + // Otherwise, Left must be false and false AND'd with anything + // else yields false. + return false; + } + // At least one operand to OR must have the top bit set. + case BuiltinValueKind::Or: { + // Compute the sign bit of the LHS and RHS. + auto Left = computeSignBit(BI->getArguments()[0]); + auto Right = computeSignBit(BI->getArguments()[1]); + + // We don't know either's sign bit so we can't + // say anything about the result. + if (!Left && !Right) { + return None; + } + + // Now we know that we were able to determine the sign bit + // for at least one of Left/Right. Canonicalize the determined + // sign bit on the left. + if (Right) { + std::swap(Left, Right); + } + + // We know we must have at least one result and it must be on + // the Left. If Right is still not None, then get both values + // and OR them together. + if (Right) { + return Left.getValue() || Right.getValue(); + } + + // Now we know that Right is None and Left has a value. If + // Left's value is false, then we return None as the final + // sign bit depends on the unknown Right value. + if (!Left.getValue()) { + return None; + } + + // Otherwise, Left must be true and true OR'd with anything + // else yields true. + return true; + } + // Only one of the operands to XOR must have the top bit set. + case BuiltinValueKind::Xor: { + // Compute the sign bit of the LHS and RHS. + auto Left = computeSignBit(BI->getArguments()[0]); + auto Right = computeSignBit(BI->getArguments()[1]); + + // If either Left or Right is unknown then we can't say + // anything about the sign of the final result since + // XOR does not short-circuit. + if (!Left || !Right) { + return None; + } + + // Now we know that both Left and Right must have a value. + // For the sign of the final result to be set, only one + // of Left or Right should be true. + return Left.getValue() != Right.getValue(); + } + case BuiltinValueKind::LShr: { + // If count is provably >= 1, then top bit is not set. + auto *ILShiftCount = dyn_cast(BI->getArguments()[1]); + if (ILShiftCount) { + if (ILShiftCount->getValue().isStrictlyPositive()) { + return false; + } + } + // May be top bit is not set in the value being shifted. + Value = BI->getArguments()[0]; + continue; + } + + // Source and target type sizes are the same. + // S->U conversion can only succeed if + // the sign bit of its operand is 0, i.e. it is >= 0. + // The sign bit of a result is 0 only if the sign + // bit of a source operand is 0. + case BuiltinValueKind::SUCheckedConversion: + Value = BI->getArguments()[0]; + continue; + + // Source and target type sizes are the same. + // U->S conversion can only succeed if + // the top bit of its operand is 0, i.e. + // it is representable as a signed integer >=0. + // The sign bit of a result is 0 only if the sign + // bit of a source operand is 0. + case BuiltinValueKind::USCheckedConversion: + Value = BI->getArguments()[0]; + continue; + + // Sign bit of the operand is promoted. + case BuiltinValueKind::SExt: + Value = BI->getArguments()[0]; + continue; + + // Source type is always smaller than the target type. + // Therefore the sign bit of a result is always 0. + case BuiltinValueKind::ZExt: + return false; + + // Sign bit of the operand is promoted. + case BuiltinValueKind::SExtOrBitCast: + Value = BI->getArguments()[0]; + continue; + + // TODO: If source type size is smaller than the target type + // the result will be always false. + case BuiltinValueKind::ZExtOrBitCast: + Value = BI->getArguments()[0]; + continue; + + // Inspect casts. + case BuiltinValueKind::IntToPtr: + case BuiltinValueKind::PtrToInt: + Value = BI->getArguments()[0]; + continue; + default: + return None; + } + } + + return None; + } +} + +/// Check if a checked trunc instruction can overflow. +/// Returns false if it can be proven that no overflow can happen. +/// Otherwise returns true. +static bool checkTruncOverflow(BuiltinInst *BI) { + SILValue Left, Right; + if (match(BI, m_CheckedTrunc(m_And(m_SILValue(Left), + m_SILValue(Right))))) { + // [US]ToSCheckedTrunc(And(x, mask)) cannot overflow + // if mask has the following properties: + // Only the first (N-1) bits are allowed to be set, where N is the width + // of the trunc result type. + // + // [US]ToUCheckedTrunc(And(x, mask)) cannot overflow + // if mask has the following properties: + // Only the first N bits are allowed to be set, where N is the width + // of the trunc result type. + if (auto BITy = BI->getType(). + getTupleElementType(0). + getAs()) { + unsigned Width = BITy->getFixedWidth(); + + switch (BI->getBuiltinInfo().ID) { + case BuiltinValueKind::SToSCheckedTrunc: + case BuiltinValueKind::UToSCheckedTrunc: + // If it is a trunc to a signed value + // then sign bit should not be set to avoid overflows. + --Width; + break; + default: + break; + } + + if (auto *ILLeft = dyn_cast(Left)) { + APInt Value = ILLeft->getValue(); + if (Value.isIntN(Width)) { + return false; + } + } + + if (auto *ILRight = dyn_cast(Right)) { + APInt Value = ILRight->getValue(); + if (Value.isIntN(Width)) { + return false; + } + } + } + } + return true; +} + +/// Check if execution of a given Apply instruction can result in overflows. +/// Returns true if an overflow can happen. Otherwise returns false. +bool swift::canOverflow(BuiltinInst *BI) { + if (simplifyOverflowBuiltinInstruction(BI) != SILValue()) + return false; + + if (!checkTruncOverflow(BI)) + return false; + + // Conservatively assume that an overflow can happen + return true; +} diff --git a/lib/SILOptimizer/CMakeLists.txt b/lib/SILOptimizer/CMakeLists.txt new file mode 100644 index 0000000000000..0cbd42c3edfc0 --- /dev/null +++ b/lib/SILOptimizer/CMakeLists.txt @@ -0,0 +1,22 @@ +add_subdirectory(ARC) +add_subdirectory(Analysis) +add_subdirectory(IPO) +add_subdirectory(LoopTransforms) +add_subdirectory(Mandatory) +add_subdirectory(PassManager) +add_subdirectory(SILCombiner) +add_subdirectory(Transforms) +add_subdirectory(UtilityPasses) +add_subdirectory(Utils) +add_swift_library(swiftSILOptimizer + ${ARC_SOURCES} + ${ANALYSIS_SOURCES} + ${SILCOMBINER_SOURCES} + ${UTILITYPASSES_SOURCES} + ${UTILS_SOURCES} + ${PASSMANAGER_SOURCES} + ${LOOPTRANSFORMS_SOURCES} + ${MANDATORY_SOURCES} + ${TRANSFORMS_SOURCES} + ${IPO_SOURCES} + LINK_LIBRARIES swiftSIL) diff --git a/lib/SILOptimizer/IPO/CMakeLists.txt b/lib/SILOptimizer/IPO/CMakeLists.txt new file mode 100644 index 0000000000000..2bb9b55c86675 --- /dev/null +++ b/lib/SILOptimizer/IPO/CMakeLists.txt @@ -0,0 +1,13 @@ +set(IPO_SOURCES + IPO/CapturePromotion.cpp + IPO/DeadFunctionElimination.cpp + IPO/GlobalOpt.cpp + IPO/PerformanceInliner.cpp + IPO/CapturePropagation.cpp + IPO/ExternalDefsToDecls.cpp + IPO/GlobalPropertyOpt.cpp + IPO/UsePrespecialized.cpp + IPO/ClosureSpecializer.cpp + IPO/FunctionSignatureOpts.cpp + IPO/LetPropertiesOpts.cpp + PARENT_SCOPE) diff --git a/lib/SILPasses/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp similarity index 82% rename from lib/SILPasses/IPO/CapturePromotion.cpp rename to lib/SILOptimizer/IPO/CapturePromotion.cpp index cdb534283db52..c508766284761 100644 --- a/lib/SILPasses/IPO/CapturePromotion.cpp +++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -41,11 +41,11 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-capture-promotion" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/Mangle.h" #include "swift/SIL/SILCloner.h" #include "swift/SIL/TypeSubstCloner.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" @@ -219,11 +219,12 @@ class ClosureCloner : public TypeSubstCloner { void visitStrongReleaseInst(StrongReleaseInst *Inst); void visitStructElementAddrInst(StructElementAddrInst *Inst); void visitLoadInst(LoadInst *Inst); + void visitProjectBoxInst(ProjectBoxInst *Inst); SILFunction *Orig; IndicesSet &PromotableIndices; llvm::DenseMap BoxArgumentMap; - llvm::DenseMap AddrArgumentMap; + llvm::DenseMap ProjectBoxArgumentMap; }; } // end anonymous namespace. @@ -257,7 +258,7 @@ void ReachabilityInfo::compute() { if (!Changed) { // If we have not detected a change yet, then calculate new // reachabilities into a new bit vector so we can determine if any - // change has occured. + // change has occurred. NewSet = CurSet; for (auto PI = BB.pred_begin(), PE = BB.pred_end(); PI != PE; ++PI) { unsigned PredID = BlockMap[*PI]; @@ -319,23 +320,11 @@ ClosureCloner::ClosureCloner(SILFunction *Orig, StringRef ClonedName, /// Compute the SILParameterInfo list for the new cloned closure. /// -/// SILGen always closes over boxes such that the container address is -/// first. Thus we know that: -/// -/// 1. By assumption, all indices that is a box container value is in -/// PromotableIndices. -/// 2. All box address values must have the box container value previous to -/// it implying that PromotableIndices.count(ParamIndex - 1) will be true. -/// 3. The first parameter can *never* be a box address value since there -/// does not exist any previous box container that is able to be -/// associated with it. -/// /// Our goal as a result of this transformation is to: /// /// 1. Let through all arguments not related to a promotable box. -/// 2. Do not add any container box value arguments to the cloned closure. -/// 3. Add the address box value argument to the cloned closure with the -/// appropriate transformations. +/// 2. Replace container box value arguments for the cloned closure with the +/// transformed address or value argument. static void computeNewArgInterfaceTypes(SILFunction *F, IndicesSet &PromotableIndices, @@ -352,24 +341,17 @@ computeNewArgInterfaceTypes(SILFunction *F, << (PromotableIndices.count(Index)?"yes":"no") << " Param: "; param.dump()); - // With that in mind, first check if we do not have a box address value... - if (Index == 0 || !PromotableIndices.count(Index - 1)) { - - // If we do not have a box address value, if we have a box container - // value, continue so we do not add it to the new closure's function type. - if (PromotableIndices.count(Index)) - continue; - - // Otherwise, we have a function argument not related to a promotable - // box. Just add it to the new signature and continue. + if (!PromotableIndices.count(Index)) { OutTys.push_back(param); continue; } - - // Otherwise, we have an address value of the box. Perform the proper - // conversions and then add it to the new parameter list for the type. - assert(param.getConvention() == ParameterConvention::Indirect_Inout); - auto ¶mTL = F->getModule().Types.getTypeLowering(param.getSILType()); + + // Perform the proper conversions and then add it to the new parameter list + // for the type. + assert(!isIndirectParameter(param.getConvention())); + auto paramBoxedTy = param.getSILType().castTo() + ->getBoxedAddressType(); + auto ¶mTL = F->getModule().Types.getTypeLowering(paramBoxedTy); ParameterConvention convention; if (paramTL.isPassedIndirectly()) { convention = ParameterConvention::Indirect_In; @@ -378,42 +360,33 @@ computeNewArgInterfaceTypes(SILFunction *F, } else { convention = ParameterConvention::Direct_Owned; } - OutTys.push_back(SILParameterInfo(param.getType(), convention)); + OutTys.push_back(SILParameterInfo(paramBoxedTy.getSwiftRValueType(), + convention)); } } -static llvm::SmallString<64> getSpecializedName(SILFunction *F, - IndicesSet &PromotableIndices) { - llvm::SmallString<64> Name; - - { - llvm::raw_svector_ostream buffer(Name); - Mangle::Mangler M(buffer); - auto P = Mangle::SpecializationPass::CapturePromotion; - Mangle::FunctionSignatureSpecializationMangler FSSM(P, M, F); - CanSILFunctionType FTy = F->getLoweredFunctionType(); - - ArrayRef Parameters = FTy->getParameters(); - for (unsigned Index : indices(Parameters)) { - if (Index == 0 || !PromotableIndices.count(Index - 1)) { - if (!PromotableIndices.count(Index)) - continue; - FSSM.setArgumentDead(Index); - continue; - } - - FSSM.setArgumentInOutToValue(Index); - } +static std::string getSpecializedName(SILFunction *F, + IndicesSet &PromotableIndices) { + Mangle::Mangler M; + auto P = SpecializationPass::CapturePromotion; + FunctionSignatureSpecializationMangler FSSM(P, M, F); + CanSILFunctionType FTy = F->getLoweredFunctionType(); - FSSM.mangle(); + ArrayRef Parameters = FTy->getParameters(); + for (unsigned Index : indices(Parameters)) { + if (!PromotableIndices.count(Index)) + continue; + FSSM.setArgumentBoxToValue(Index); } - return Name; + FSSM.mangle(); + + return M.finalize(); } /// \brief Create the function corresponding to the clone of the original /// closure with the signature modified to reflect promotable captures (which -/// are givien by PromotableIndices, such that each entry in the set is the +/// are given by PromotableIndices, such that each entry in the set is the /// index of the box containing the variable in the closure's argument list, and /// the address of the box's contents is the argument immediately following each /// box argument); does not actually clone the body of the function @@ -452,14 +425,13 @@ ClosureCloner::initCloned(SILFunction *Orig, StringRef ClonedName, && "SILFunction missing DebugScope"); assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned"); - auto Fn = - SILFunction::create(M, Orig->getLinkage(), ClonedName, SubstTy, - Orig->getContextGenericParams(), Orig->getLocation(), - Orig->isBare(), IsNotTransparent, Orig->isFragile(), - Orig->isThunk(), - Orig->getClassVisibility(), Orig->getInlineStrategy(), - Orig->getEffectsKind(), Orig, Orig->getDebugScope()); - Fn->setSemanticsAttr(Orig->getSemanticsAttr()); + auto *Fn = M.getOrCreateFunction( + Orig->getLinkage(), ClonedName, SubstTy, Orig->getContextGenericParams(), + Orig->getLocation(), Orig->isBare(), IsNotTransparent, Orig->isFragile(), + Orig->isThunk(), Orig->getClassVisibility(), Orig->getInlineStrategy(), + Orig->getEffectsKind(), Orig, Orig->getDebugScope()); + for (auto &Attr : Orig->getSemanticsAttrs()) + Fn->addSemanticsAttr(Attr); Fn->setDeclCtx(Orig->getDeclContext()); return Fn; } @@ -478,15 +450,19 @@ ClosureCloner::populateCloned() { auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end(); while (I != E) { if (PromotableIndices.count(ArgNo)) { - // Handle the case of a promoted capture argument - SILArgument *ReleaseArgument = *I++; + // Handle the case of a promoted capture argument. + auto BoxedTy = (*I)->getType().castTo()->getBoxedAddressType() + .getObjectType(); SILValue MappedValue = - new (M) SILArgument(ClonedEntryBB, - (*I)->getType().getObjectType(), - (*I)->getDecl()); - BoxArgumentMap.insert(std::make_pair(ReleaseArgument, MappedValue)); - AddrArgumentMap.insert(std::make_pair(*I, MappedValue)); - ++ArgNo; + new (M) SILArgument(ClonedEntryBB, BoxedTy, (*I)->getDecl()); + BoxArgumentMap.insert(std::make_pair(*I, MappedValue)); + + // Track the projections of the box. + for (auto *Use : (*I)->getUses()) { + if (auto Proj = dyn_cast(Use->getUser())) { + ProjectBoxArgumentMap.insert(std::make_pair(Proj, MappedValue)); + } + } } else { // Otherwise, create a new argument which copies the original argument SILValue MappedValue = @@ -515,13 +491,13 @@ ClosureCloner::populateCloned() { /// debug_value, otherwise it is handled normally. void ClosureCloner::visitDebugValueAddrInst(DebugValueAddrInst *Inst) { SILValue Operand = Inst->getOperand(); - if (SILArgument *A = dyn_cast(Operand)) { + if (auto *A = dyn_cast(Operand)) { assert(Operand.getResultNumber() == 0); - auto I = AddrArgumentMap.find(A); - if (I != AddrArgumentMap.end()) { + auto I = ProjectBoxArgumentMap.find(A); + if (I != ProjectBoxArgumentMap.end()) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); getBuilder().createDebugValue(Inst->getLoc(), I->second, - Inst->getVarInfo().getArgNo()); + Inst->getVarInfo()); return; } } @@ -530,7 +506,7 @@ void ClosureCloner::visitDebugValueAddrInst(DebugValueAddrInst *Inst) { } /// \brief Handle a strong_release instruction during cloning of a closure; if -/// it is a strong release of a promoted box argument, then it is replaced wit +/// it is a strong release of a promoted box argument, then it is replaced with /// a ReleaseValue of the new object type argument, otherwise it is handled /// normally. void @@ -559,26 +535,36 @@ ClosureCloner::visitStrongReleaseInst(StrongReleaseInst *Inst) { void ClosureCloner::visitStructElementAddrInst(StructElementAddrInst *Inst) { SILValue Operand = Inst->getOperand(); - if (SILArgument *A = dyn_cast(Operand)) { + if (auto *A = dyn_cast(Operand)) { assert(Operand.getResultNumber() == 0); - auto I = AddrArgumentMap.find(A); - if (I != AddrArgumentMap.end()) + auto I = ProjectBoxArgumentMap.find(A); + if (I != ProjectBoxArgumentMap.end()) return; } SILCloner::visitStructElementAddrInst(Inst); } +/// project_box of captured boxes can be eliminated. +void +ClosureCloner::visitProjectBoxInst(ProjectBoxInst *I) { + if (auto Arg = dyn_cast(I->getOperand())) + if (BoxArgumentMap.count(Arg)) + return; + + SILCloner::visitProjectBoxInst(I); +} + /// \brief Handle a load instruction during cloning of a closure; the two /// relevant cases are a direct load from a promoted address argument or a load /// of a struct_element_addr of a promoted address argument. void ClosureCloner::visitLoadInst(LoadInst *Inst) { SILValue Operand = Inst->getOperand(); - if (auto *A = dyn_cast(Operand)) { + if (auto *A = dyn_cast(Operand)) { assert(Operand.getResultNumber() == 0); - auto I = AddrArgumentMap.find(A); - if (I != AddrArgumentMap.end()) { + auto I = ProjectBoxArgumentMap.find(A); + if (I != ProjectBoxArgumentMap.end()) { // Loads of the address argument get eliminated completely; the uses of // the loads get mapped to uses of the new object type argument. ValueMap.insert(std::make_pair(Inst, I->second)); @@ -586,10 +572,10 @@ ClosureCloner::visitLoadInst(LoadInst *Inst) { } } else if (auto *SEAI = dyn_cast(Operand)) { assert(Operand.getResultNumber() == 0); - if (auto *A = dyn_cast(SEAI->getOperand())) { + if (auto *A = dyn_cast(SEAI->getOperand())) { assert(SEAI->getOperand().getResultNumber() == 0); - auto I = AddrArgumentMap.find(A); - if (I != AddrArgumentMap.end()) { + auto I = ProjectBoxArgumentMap.find(A); + if (I != ProjectBoxArgumentMap.end()) { // Loads of a struct_element_addr of an argument get replaced with // struct_extract of the new object type argument. SILBuilderWithPostProcess B(this, Inst); @@ -605,15 +591,10 @@ ClosureCloner::visitLoadInst(LoadInst *Inst) { SILCloner::visitLoadInst(Inst); } -static std::pair getBoxAndAddrFromIndex( - SILFunction *F, - unsigned Index) { +static SILArgument *getBoxFromIndex(SILFunction *F, unsigned Index) { assert(F->isDefinition() && "Expected definition not external declaration!"); auto &Entry = F->front(); - auto *Box = Entry.getBBArg(Index); - auto *Addr = Entry.getBBArg(Index + 1); - - return std::make_pair(Box, Addr); + return Entry.getBBArg(Index); } /// \brief Given a partial_apply instruction and the argument index into its @@ -621,28 +602,43 @@ static std::pair getBoxAndAddrFromIndex( /// for the address of the box's contents), return true if the closure is known /// not to mutate the captured variable. static bool -isNonmutatingCapture(SILArgument *BoxArg, SILArgument *AddrArg) { +isNonmutatingCapture(SILArgument *BoxArg) { + SmallVector Projections; + // Conservatively do not allow any use of the box argument other than a - // strong_release, since this is the pattern expected from SILGen. - for (auto *O : BoxArg->getUses()) - if (!isa(O->getUser())) - return false; + // strong_release or projection, since this is the pattern expected from + // SILGen. + for (auto *O : BoxArg->getUses()) { + if (isa(O->getUser())) + continue; + + if (auto Projection = dyn_cast(O->getUser())) { + Projections.push_back(Projection); + continue; + } + + return false; + } - // Only allow loads of the address argument, either directly or via + // Only allow loads of projections, either directly or via // struct_element_addr instructions. // // TODO: This seems overly limited. Why not projections of tuples and other // stuff? Also, why not recursive struct elements? This should be a helper // function that mirrors isNonEscapingUse. - for (auto *O : AddrArg->getUses()) { - if (auto *SEAI = dyn_cast(O->getUser())) { - for (auto *UO : SEAI->getUses()) - if (!isa(UO->getUser())) - return false; - continue; + for (auto *Projection : Projections) { + for (auto *O : Projection->getUses()) { + if (auto *SEAI = dyn_cast(O->getUser())) { + for (auto *UO : SEAI->getUses()) + if (!isa(UO->getUser())) + return false; + continue; + } + if (!isa(O->getUser()) + && !isa(O->getUser()) + && !isa(O->getUser())) + return false; } - if (!isa(O->getUser()) && !isa(O->getUser())) - return false; } return true; @@ -655,6 +651,10 @@ isNonmutatingCapture(SILArgument *BoxArg, SILArgument *AddrArg) { static bool isNonescapingUse(Operand *O, SmallVectorImpl &Mutations) { auto *U = O->getUser(); + // Marking the boxed value as escaping is OK. It's just a DI annotation. + if (isa(U)) + return true; + // A store or assign is ok if the alloc_box is the destination. if (isa(U) || isa(U)) { if (O->getOperandNumber() != 1) @@ -725,14 +725,10 @@ examineAllocBoxInst(AllocBoxInst *ABI, ReachabilityInfo &RI, llvm::DenseMap &IM) { SmallVector Mutations; - // If the AllocBox is used by a mark_uninitialized, scan the MUI for - // interesting uses. - SILValue Addr = ABI->getAddressResult(); - if (Addr.hasOneUse()) - if (auto MUI = dyn_cast(Addr.use_begin()->getUser())) - Addr = SILValue(MUI); + // Scan the box for interesting uses. + SILValue Box = ABI->getContainerResult(); - for (Operand *O : Addr.getUses()) { + for (Operand *O : Box.getUses()) { if (auto *PAI = dyn_cast(O->getUser())) { unsigned OpNo = O->getOperandNumber(); assert(OpNo != 0 && "Alloc box used as callee of partial apply?"); @@ -743,11 +739,6 @@ examineAllocBoxInst(AllocBoxInst *ABI, ReachabilityInfo &RI, if (IM.count(PAI)) return false; - // Verify that the previous operand of the partial apply is the refcount - // result of the alloc_box. - if (PAI->getOperand(OpNo - 1) != SILValue(ABI)) - return false; - auto Callee = PAI->getCallee(); auto CalleeTy = Callee.getType().castTo(); @@ -761,27 +752,26 @@ examineAllocBoxInst(AllocBoxInst *ABI, ReachabilityInfo &RI, // Calculate the index into the closure's argument list of the captured // box pointer (the captured address is always the immediately following // index so is not stored separately); - unsigned Index = OpNo - 2 + closureType->getParameters().size(); + unsigned Index = OpNo - 1 + closureType->getParameters().size(); auto *Fn = PAI->getCalleeFunction(); if (!Fn || !Fn->isDefinition()) return false; - SILArgument *BoxArg; - SILArgument *AddrArg; - std::tie(BoxArg, AddrArg) = getBoxAndAddrFromIndex(Fn, Index); + SILArgument *BoxArg = getBoxFromIndex(Fn, Index); // For now, return false is the address argument is an address-only type, - // since we currently assume loadable types only. + // since we currently handle loadable types only. // TODO: handle address-only types SILModule &M = PAI->getModule(); - if (AddrArg->getType().isAddressOnly(M)) + if (BoxArg->getType().castTo()->getBoxedAddressType() + .isAddressOnly(M)) return false; // Verify that this closure is known not to mutate the captured value; if // it does, then conservatively refuse to promote any captures of this // value. - if (!isNonmutatingCapture(BoxArg, AddrArg)) + if (!isNonmutatingCapture(BoxArg)) return false; // Record the index and continue. @@ -789,11 +779,24 @@ examineAllocBoxInst(AllocBoxInst *ABI, ReachabilityInfo &RI, continue; } - // Verify that this this use does not otherwise allow the alloc_box to + // Verify that this use does not otherwise allow the alloc_box to // escape. if (!isNonescapingUse(O, Mutations)) return false; } + + // Check for mutations of the address component. + // If the AllocBox is used by a mark_uninitialized, scan the MUI for + // interesting uses. + SILValue Addr = ABI->getAddressResult(); + if (Addr.hasOneUse()) + if (auto MUI = dyn_cast(Addr.use_begin()->getUser())) + Addr = SILValue(MUI); + + for (Operand *O : Addr.getUses()) { + if (!isNonescapingUse(O, Mutations)) + return false; + } // Helper lambda function to determine if instruction b is strictly after // instruction a, assuming both are in the same basic block. @@ -903,13 +906,8 @@ processPartialApplyInst(PartialApplyInst *PAI, IndicesSet &PromotableIndices, unsigned Index = OpNo - 1 + FirstIndex; if (PromotableIndices.count(Index)) { SILValue BoxValue = PAI->getOperand(OpNo); - SILValue AddrValue = PAI->getOperand(OpNo + 1); - SILValue UnderlyingAddrValue = AddrValue; - if (auto *MUI = dyn_cast(AddrValue)) - UnderlyingAddrValue = MUI->getOperand(); - assert(BoxValue.getDef() == UnderlyingAddrValue.getDef() && - BoxValue.getResultNumber() == 0 && - UnderlyingAddrValue.getResultNumber() == 1); + assert(isa(BoxValue) && + BoxValue.getResultNumber() == 0); SILParameterInfo CPInfo = CalleePInfo[Index]; assert(CPInfo.getSILType() == BoxValue.getType() && @@ -920,10 +918,17 @@ processPartialApplyInst(PartialApplyInst *PAI, IndicesSet &PromotableIndices, // Load and copy from the address value, passing the result as an argument // to the new closure. - auto &typeLowering = M.getTypeLowering(AddrValue.getType()); + SILValue Addr = cast(BoxValue)->getAddressResult(); + // If the address is marked uninitialized, load through the mark, so that + // DI can reason about it. + if (Addr.hasOneUse()) + if (auto MUI = dyn_cast( + Addr.use_begin()->getUser())) + Addr = SILValue(MUI); + + auto &typeLowering = M.getTypeLowering(Addr.getType()); Args.push_back( - typeLowering.emitLoadOfCopy(B, PAI->getLoc(), AddrValue, IsNotTake)); - ++OpNo; + typeLowering.emitLoadOfCopy(B, PAI->getLoc(), Addr, IsNotTake)); ++NumCapturesPromoted; } else { Args.push_back(PAI->getOperand(OpNo)); @@ -947,8 +952,8 @@ processPartialApplyInst(PartialApplyInst *PAI, IndicesSet &PromotableIndices, } static void -constructMapFromPartialApplyToPromoteableIndices(SILFunction *F, - PartialApplyIndicesMap &Map) { +constructMapFromPartialApplyToPromotableIndices(SILFunction *F, + PartialApplyIndicesMap &Map) { ReachabilityInfo RS(F); // This is a map from each partial apply to a single index which is a @@ -962,7 +967,7 @@ constructMapFromPartialApplyToPromoteableIndices(SILFunction *F, IndexMap.clear(); if (examineAllocBoxInst(ABI, RS, IndexMap)) { // If we are able to promote at least one capture of the alloc_box, - // then add the promotable indices to the main map. + // then add the promotable index to the main map. for (auto &IndexPair : IndexMap) Map[IndexPair.first].insert(IndexPair.second); } @@ -976,7 +981,7 @@ processFunction(SILFunction *F, SmallVectorImpl &Worklist) { // This is a map from each partial apply to a set of indices of promotable // box variables. PartialApplyIndicesMap IndicesMap; - constructMapFromPartialApplyToPromoteableIndices(F, IndicesMap); + constructMapFromPartialApplyToPromotableIndices(F, IndicesMap); // Do the actual promotions; all promotions on a single partial_apply are // handled together. diff --git a/lib/SILPasses/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp similarity index 91% rename from lib/SILPasses/IPO/CapturePropagation.cpp rename to lib/SILOptimizer/IPO/CapturePropagation.cpp index 2d57df9f13ffb..8f2f6d4657bd8 100644 --- a/lib/SILPasses/IPO/CapturePropagation.cpp +++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp @@ -1,8 +1,8 @@ -//===---- CapturePropagation.cpp - Propagate closure capture constants ----===// +//===--- CapturePropagation.cpp - Propagate closure capture constants -----===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,15 +11,15 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "capture-prop" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/Basic/Demangle.h" #include "swift/SIL/Mangle.h" #include "swift/SIL/SILCloner.h" #include "swift/SIL/SILInstruction.h" -#include "swift/SILAnalysis/ColdBlockInfo.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/ColdBlockInfo.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" @@ -65,14 +65,11 @@ static bool isConstant(SILValue V) { return V && isOptimizableConstant(V); } -static llvm::SmallString<64> getClonedName(PartialApplyInst *PAI, - SILFunction *F) { - llvm::SmallString<64> ClonedName; +static std::string getClonedName(PartialApplyInst *PAI, SILFunction *F) { - llvm::raw_svector_ostream buffer(ClonedName); - Mangle::Mangler M(buffer); - auto P = Mangle::SpecializationPass::CapturePropagation; - Mangle::FunctionSignatureSpecializationMangler Mangler(P, M, F); + Mangle::Mangler M; + auto P = SpecializationPass::CapturePropagation; + FunctionSignatureSpecializationMangler Mangler(P, M, F); // We know that all arguments are literal insts. auto Args = PAI->getArguments(); @@ -80,7 +77,7 @@ static llvm::SmallString<64> getClonedName(PartialApplyInst *PAI, Mangler.setArgumentConstantProp(i, getConstant(Args[i])); Mangler.mangle(); - return ClonedName; + return M.finalize(); } namespace { @@ -217,12 +214,13 @@ void CapturePropagationCloner::cloneBlocks( /// function body. SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI, SILFunction *OrigF) { - llvm::SmallString<64> Name = getClonedName(PAI, OrigF); + std::string Name = getClonedName(PAI, OrigF); // See if we already have a version of this function in the module. If so, // just return it. - if (auto *NewF = OrigF->getModule().lookUpFunction(Name.str())) { - DEBUG(llvm::dbgs() << " Found an already specialized version of the callee: "; + if (auto *NewF = OrigF->getModule().lookUpFunction(Name)) { + DEBUG(llvm::dbgs() + << " Found an already specialized version of the callee: "; NewF->printName(llvm::dbgs()); llvm::dbgs() << "\n"); return NewF; } @@ -233,12 +231,12 @@ SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI, CanSILFunctionType NewFTy = Lowering::adjustFunctionType(PAI->getType().castTo(), SILFunctionType::Representation::Thin); - SILFunction *NewF = SILFunction::create( - *getModule(), SILLinkage::Shared, Name, NewFTy, + SILFunction *NewF = getModule()->getOrCreateFunction( + SILLinkage::Shared, Name, NewFTy, /*contextGenericParams*/ nullptr, OrigF->getLocation(), OrigF->isBare(), OrigF->isTransparent(), OrigF->isFragile(), OrigF->isThunk(), - OrigF->getClassVisibility(), - OrigF->getInlineStrategy(), OrigF->getEffectsKind(), + OrigF->getClassVisibility(), OrigF->getInlineStrategy(), + OrigF->getEffectsKind(), /*InsertBefore*/ OrigF, OrigF->getDebugScope(), OrigF->getDeclContext()); NewF->setDeclCtx(OrigF->getDeclContext()); DEBUG(llvm::dbgs() << " Specialize callee as "; diff --git a/lib/SILPasses/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp similarity index 95% rename from lib/SILPasses/IPO/ClosureSpecializer.cpp rename to lib/SILOptimizer/IPO/ClosureSpecializer.cpp index b2bc6eb87d36b..6c9d0c8d3b38b 100644 --- a/lib/SILPasses/IPO/ClosureSpecializer.cpp +++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp @@ -1,8 +1,8 @@ -//===---- ClosureSpecializer.cpp ------ Performs Closure Specialization----===// +//===--- ClosureSpecializer.cpp - Performs Closure Specialization ---------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -55,18 +55,18 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "closure-specialization" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/Mangle.h" #include "swift/SIL/SILCloner.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" -#include "swift/SILAnalysis/CFG.h" -#include "swift/SILAnalysis/FunctionOrder.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/SILInliner.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/CFG.h" +#include "swift/SILOptimizer/Analysis/FunctionOrder.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/SILInliner.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/CommandLine.h" @@ -201,7 +201,7 @@ class CallSiteDescriptor { FullApplySite getApplyInst() const { return AI; } - void createName(llvm::SmallString<64> &NewName) const; + std::string createName() const; OperandValueArrayRef getArguments() const { if (auto *PAI = dyn_cast(getClosure())) @@ -311,10 +311,10 @@ static void rewriteApplyInst(const CallSiteDescriptor &CSDesc, // apply %specialized_callee(..., %arg) // // However, if they are not in the same basic block the callee might be - // executed more frequenly than the closure (for example, if the closure is + // executed more frequently than the closure (for example, if the closure is // created in a loop preheader and the callee taking the closure is executed - // in the loop). In such a case we must keep the argument live accross the - // call site of the callee and emit a matching retain for every innvocation + // in the loop). In such a case we must keep the argument live across the + // call site of the callee and emit a matching retain for every invocation // of the callee. // // %closure = partial_apply (%arg) @@ -386,20 +386,21 @@ static void rewriteApplyInst(const CallSiteDescriptor &CSDesc, // AI from parent? } -void CallSiteDescriptor::createName(llvm::SmallString<64> &NewName) const { - llvm::raw_svector_ostream buffer(NewName); - Mangle::Mangler M(buffer); - auto P = Mangle::SpecializationPass::ClosureSpecializer; - Mangle::FunctionSignatureSpecializationMangler FSSM(P, M, getApplyCallee()); +std::string CallSiteDescriptor::createName() const { + Mangle::Mangler M; + auto P = SpecializationPass::ClosureSpecializer; + FunctionSignatureSpecializationMangler FSSM(P, M, getApplyCallee()); + if (auto *PAI = dyn_cast(getClosure())) { FSSM.setArgumentClosureProp(getClosureIndex(), PAI); FSSM.mangle(); - return; + return M.finalize(); } auto *TTTFI = cast(getClosure()); FSSM.setArgumentClosureProp(getClosureIndex(), TTTFI); FSSM.mangle(); + return M.finalize(); } void CallSiteDescriptor::extendArgumentLifetime(SILValue Arg) const { @@ -418,8 +419,7 @@ void CallSiteDescriptor::extendArgumentLifetime(SILValue Arg) const { static void specializeClosure(ClosureInfo &CInfo, CallSiteDescriptor &CallDesc) { - llvm::SmallString<64> NewFName; - CallDesc.createName(NewFName); + auto NewFName = CallDesc.createName(); DEBUG(llvm::dbgs() << " Perform optimizations with new name " << NewFName << '\n'); @@ -546,15 +546,21 @@ ClosureSpecCloner::initCloned(const CallSiteDescriptor &CallSiteDesc, // We make this function bare so we don't have to worry about decls in the // SILArgument. - auto Fn = SILFunction::create( - M, ClosureUser->getLinkage(), ClonedName, ClonedTy, + auto *Fn = M.getOrCreateFunction( + // It's important to use a shared linkage for the specialized function + // and not the original linkage. + // Otherwise the new function could have an external linkage (in case the + // original function was de-serialized) and would not be code-gen'd. + getSpecializedLinkage(ClosureUser, ClosureUser->getLinkage()), + ClonedName, ClonedTy, ClosureUser->getContextGenericParams(), ClosureUser->getLocation(), IsBare, ClosureUser->isTransparent(), ClosureUser->isFragile(), ClosureUser->isThunk(), ClosureUser->getClassVisibility(), ClosureUser->getInlineStrategy(), ClosureUser->getEffectsKind(), ClosureUser, ClosureUser->getDebugScope()); Fn->setDeclCtx(ClosureUser->getDeclContext()); - Fn->setSemanticsAttr(ClosureUser->getSemanticsAttr()); + for (auto &Attr : ClosureUser->getSemanticsAttrs()) + Fn->addSemanticsAttr(Attr); return Fn; } @@ -589,7 +595,7 @@ void ClosureSpecCloner::populateCloned() { // Next we need to add in any arguments that are not captured as arguments to // the cloned function. // - // We do not insert the new mapped arugments into the value map since there by + // We do not insert the new mapped arguments into the value map since there by // definition is nothing in the partial apply user function that references // such arguments. After this pass is done the only thing that will reference // the arguments is the partial apply that we will create. @@ -716,7 +722,7 @@ void ClosureSpecializer::gatherCallSites( // Go through all uses of our closure. for (auto *Use : II.getUses()) { - // If this use use is not an apply inst or an apply inst with + // If this use is not an apply inst or an apply inst with // substitutions, there is nothing interesting for us to do, so // continue... auto AI = FullApplySite::isa(Use->getUser()); diff --git a/lib/SILPasses/IPO/DeadFunctionElimination.cpp b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp similarity index 97% rename from lib/SILPasses/IPO/DeadFunctionElimination.cpp rename to lib/SILOptimizer/IPO/DeadFunctionElimination.cpp index d0888d010af31..59f8274e9b5fa 100644 --- a/lib/SILPasses/IPO/DeadFunctionElimination.cpp +++ b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,13 +11,13 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-dead-function-elimination" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SIL/PatternMatch.h" #include "swift/SIL/Projection.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -87,7 +87,7 @@ class FunctionLivenessComputation { /// Gets or creates the MethodInfo for a vtable or witness table method. /// \p decl The method declaration. In case of a vtable method this is always - /// the most overriden method. + /// the most overridden method. MethodInfo *getMethodInfo(AbstractFunctionDecl *decl) { MethodInfo *&entry = MethodInfos[decl]; if (entry == nullptr) { @@ -148,9 +148,9 @@ class FunctionLivenessComputation { // Check if the method implementation is the same in a super class, i.e. // it is not overridden in the derived class. - FuncDecl *Impl1 = MethodCl->findImplementingMethod(FD); + auto *Impl1 = MethodCl->findImplementingMethod(FD); assert(Impl1); - FuncDecl *Impl2 = ImplCl->findImplementingMethod(FD); + auto *Impl2 = ImplCl->findImplementingMethod(FD); assert(Impl2); return Impl1 == Impl2; @@ -197,7 +197,7 @@ class FunctionLivenessComputation { } } - /// Retrieve the visiblity information from the AST. + /// Retrieve the visibility information from the AST. bool isVisibleExternally(ValueDecl *decl) { Accessibility accessibility = decl->getEffectiveAccess(); SILLinkage linkage; @@ -446,7 +446,7 @@ class ExternalFunctionDefinitionsElimination : FunctionLivenessComputation { bool findAliveFunctions() { /// TODO: Once there is a proper support for IPO, /// bodies of all external functions can be removed. - /// Therefore there is no need for a livesness computation. + /// Therefore there is no need for a liveness computation. /// The next line can be just replaced by: /// return false; return FunctionLivenessComputation::findAliveFunctions(); diff --git a/lib/SILPasses/IPO/ExternalDefsToDecls.cpp b/lib/SILOptimizer/IPO/ExternalDefsToDecls.cpp similarity index 81% rename from lib/SILPasses/IPO/ExternalDefsToDecls.cpp rename to lib/SILOptimizer/IPO/ExternalDefsToDecls.cpp index 2102bde9e9be5..9eeaeab78181d 100644 --- a/lib/SILPasses/IPO/ExternalDefsToDecls.cpp +++ b/lib/SILOptimizer/IPO/ExternalDefsToDecls.cpp @@ -1,8 +1,8 @@ -//===--- ExternalDefinitionsToDeclarations.cpp - external defs to decls ---===// +//===--- ExternalDefsToDecls.cpp - external defs to decls -----------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILModule.h" diff --git a/lib/SILPasses/IPO/FunctionSignatureOpts.cpp b/lib/SILOptimizer/IPO/FunctionSignatureOpts.cpp similarity index 83% rename from lib/SILPasses/IPO/FunctionSignatureOpts.cpp rename to lib/SILOptimizer/IPO/FunctionSignatureOpts.cpp index c16c6f4480341..7f7d8f2f677a3 100644 --- a/lib/SILPasses/IPO/FunctionSignatureOpts.cpp +++ b/lib/SILOptimizer/IPO/FunctionSignatureOpts.cpp @@ -1,8 +1,8 @@ -//===-- FunctionSignatureOpts.cpp - Optimizes function signatures ---------===// +//===--- FunctionSignatureOpts.cpp - Optimizes function signatures --------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,13 +11,13 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-function-signature-opts" -#include "swift/SILPasses/Passes.h" -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" -#include "swift/SILAnalysis/FunctionOrder.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/FunctionOrder.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/BlotMapVector.h" #include "swift/Basic/Range.h" @@ -42,7 +42,7 @@ STATISTIC(NumFunctionSignaturesOptimized, "Total func sig optimized"); STATISTIC(NumDeadArgsEliminated, "Total dead args eliminated"); STATISTIC(NumOwnedConvertedToGuaranteed, "Total owned args -> guaranteed args"); STATISTIC(NumCallSitesOptimized, "Total call sites optimized"); -STATISTIC(NumSROAArguments, "Total SROA argumments optimized"); +STATISTIC(NumSROAArguments, "Total SROA arguments optimized"); //===----------------------------------------------------------------------===// // Utility @@ -157,9 +157,10 @@ struct ArgumentDescriptor { /// have access to the original argument's state if we modify the argument /// when optimizing. ArgumentDescriptor(llvm::BumpPtrAllocator &BPA, SILArgument *A) - : Arg(A), Index(A->getIndex()), ParameterInfo(A->getParameterInfo()), - Decl(A->getDecl()), IsDead(false), CalleeRelease(), - CalleeReleaseInThrowBlock(), ProjTree(A->getModule(), BPA, A->getType()) { + : Arg(A), Index(A->getIndex()), ParameterInfo(A->getParameterInfo()), + Decl(A->getDecl()), IsDead(false), CalleeRelease(), + CalleeReleaseInThrowBlock(), + ProjTree(A->getModule(), BPA, A->getType()) { ProjTree.computeUsesAndLiveness(A); } @@ -193,9 +194,8 @@ struct ArgumentDescriptor { /// /// The return value makes it easy to SROA arguments since we can return the /// amount of SROAed arguments we created. - unsigned - updateOptimizedBBArgs(SILBuilder &Builder, SILBasicBlock *BB, - unsigned ArgOffset); + unsigned updateOptimizedBBArgs(SILBuilder &Builder, SILBasicBlock *BB, + unsigned ArgOffset); bool canOptimizeLiveArg() const { return ParameterInfo.getSILType().isObject(); @@ -220,9 +220,8 @@ struct ArgumentDescriptor { } // end anonymous namespace -void -ArgumentDescriptor:: -computeOptimizedInterfaceParams(SmallVectorImpl &Out) const { +void ArgumentDescriptor::computeOptimizedInterfaceParams( + SmallVectorImpl &Out) const { DEBUG(llvm::dbgs() << " Computing Interface Params\n"); // If we have a dead argument, bail. if (IsDead) { @@ -230,21 +229,22 @@ computeOptimizedInterfaceParams(SmallVectorImpl &Out) const { return; } - // If this argument is live, but we can not optimize it. + // If this argument is live, but we cannot optimize it. if (!canOptimizeLiveArg()) { - DEBUG(llvm::dbgs() << " Can not optimize live arg!\n"); + DEBUG(llvm::dbgs() << " Cannot optimize live arg!\n"); Out.push_back(ParameterInfo); return; } - // If we can not explode this value, handle callee release and return. + // If we cannot explode this value, handle callee release and return. if (!shouldExplode()) { - DEBUG(llvm::dbgs() << " ProjTree can not explode arg.\n"); + DEBUG(llvm::dbgs() << " ProjTree cannot explode arg.\n"); // If we found a release in the callee in the last BB on an @owned // parameter, change the parameter to @guaranteed and continue... if (CalleeRelease) { DEBUG(llvm::dbgs() << " Has callee release.\n"); - assert(ParameterInfo.getConvention() == ParameterConvention::Direct_Owned && + assert(ParameterInfo.getConvention() == + ParameterConvention::Direct_Owned && "Can only transform @owned => @guaranteed in this code path"); SILParameterInfo NewInfo(ParameterInfo.getType(), ParameterConvention::Direct_Guaranteed); @@ -278,7 +278,7 @@ computeOptimizedInterfaceParams(SmallVectorImpl &Out) const { ParameterConvention Conv = ParameterInfo.getConvention(); if (Conv == ParameterConvention::Direct_Guaranteed) { assert(!CalleeRelease && "Guaranteed parameter should not have a callee " - "release."); + "release."); SILParameterInfo NewInfo(Ty.getSwiftRValueType(), ParameterConvention::Direct_Guaranteed); Out.push_back(NewInfo); @@ -287,8 +287,8 @@ computeOptimizedInterfaceParams(SmallVectorImpl &Out) const { // If Ty is not trivial and we found a callee release, pass it as // guaranteed. - assert(ParameterInfo.getConvention() == ParameterConvention::Direct_Owned - && "Can only transform @owned => @guaranteed in this code path"); + assert(ParameterInfo.getConvention() == ParameterConvention::Direct_Owned && + "Can only transform @owned => @guaranteed in this code path"); if (CalleeRelease) { SILParameterInfo NewInfo(Ty.getSwiftRValueType(), ParameterConvention::Direct_Guaranteed); @@ -303,10 +303,9 @@ computeOptimizedInterfaceParams(SmallVectorImpl &Out) const { } } -void -ArgumentDescriptor:: -addCallerArgs(SILBuilder &B, FullApplySite FAS, - llvm::SmallVectorImpl &NewArgs) const { +void ArgumentDescriptor::addCallerArgs( + SILBuilder &B, FullApplySite FAS, + llvm::SmallVectorImpl &NewArgs) const { if (IsDead) return; @@ -319,10 +318,9 @@ addCallerArgs(SILBuilder &B, FullApplySite FAS, ProjTree.createTreeFromValue(B, FAS.getLoc(), Arg, NewArgs); } -void -ArgumentDescriptor:: -addThunkArgs(SILBuilder &Builder, SILBasicBlock *BB, - llvm::SmallVectorImpl &NewArgs) const { +void ArgumentDescriptor::addThunkArgs( + SILBuilder &Builder, SILBasicBlock *BB, + llvm::SmallVectorImpl &NewArgs) const { if (IsDead) return; @@ -335,10 +333,9 @@ addThunkArgs(SILBuilder &Builder, SILBasicBlock *BB, BB->getBBArg(Index), NewArgs); } -unsigned -ArgumentDescriptor:: -updateOptimizedBBArgs(SILBuilder &Builder, SILBasicBlock *BB, - unsigned ArgOffset) { +unsigned ArgumentDescriptor::updateOptimizedBBArgs(SILBuilder &Builder, + SILBasicBlock *BB, + unsigned ArgOffset) { // If this argument is completely dead, delete this argument and return // ArgOffset. if (IsDead) { @@ -349,9 +346,9 @@ updateOptimizedBBArgs(SILBuilder &Builder, SILBasicBlock *BB, // TODO: This should not be necessary. if (CalleeRelease) { SILType CalleeReleaseTy = CalleeRelease->getOperand(0).getType(); - CalleeRelease->setOperand(0, SILUndef::get(CalleeReleaseTy, - Builder.getModule())); - + CalleeRelease->setOperand( + 0, SILUndef::get(CalleeReleaseTy, Builder.getModule())); + // TODO: Currently we cannot mark arguments as dead if they are released // in a throw block. But as soon as we can do this, we have to handle // CalleeReleaseInThrowBlock as well. @@ -386,7 +383,8 @@ updateOptimizedBBArgs(SILBuilder &Builder, SILBasicBlock *BB, llvm::SmallVector LeafTypes; ProjTree.getLeafTypes(LeafTypes); for (auto Ty : LeafTypes) { - LeafValues.push_back(BB->insertBBArg(ArgOffset++, Ty, BB->getBBArg(OldArgOffset)->getDecl())); + LeafValues.push_back(BB->insertBBArg( + ArgOffset++, Ty, BB->getBBArg(OldArgOffset)->getDecl())); } } @@ -400,8 +398,7 @@ updateOptimizedBBArgs(SILBuilder &Builder, SILBasicBlock *BB, // Replace all uses of the original arg with undef so it does not have any // uses. SILValue OrigArg = SILValue(BB->getBBArg(OldArgOffset)); - OrigArg.replaceAllUsesWith(SILUndef::get(OrigArg.getType(), - BB->getModule())); + OrigArg.replaceAllUsesWith(SILUndef::get(OrigArg.getType(), BB->getModule())); // Now erase the old argument since it does not have any uses. We also // decrement ArgOffset since we have one less argument now. @@ -418,7 +415,9 @@ updateOptimizedBBArgs(SILBuilder &Builder, SILBasicBlock *BB, namespace { template -inline T1 getFirstPairElt(const std::pair &P) { return P.first; } +inline T1 getFirstPairElt(const std::pair &P) { + return P.first; +} /// A class that contains all analysis information we gather about our /// function. Also provides utility methods for creating the new empty function. @@ -452,24 +451,23 @@ class FunctionAnalyzer { FunctionAnalyzer(FunctionAnalyzer &&) = delete; FunctionAnalyzer(llvm::BumpPtrAllocator &Allocator, - RCIdentityFunctionInfo *RCIA, - SILFunction *F) - : Allocator(Allocator), RCIA(RCIA), F(F), - MayBindDynamicSelf(computeMayBindDynamicSelf(F)), - ShouldOptimize(false), HaveModifiedSelfArgument(false), ArgDescList() {} + RCIdentityFunctionInfo *RCIA, SILFunction *F) + : Allocator(Allocator), RCIA(RCIA), F(F), + MayBindDynamicSelf(computeMayBindDynamicSelf(F)), ShouldOptimize(false), + HaveModifiedSelfArgument(false), ArgDescList() {} /// Analyze the given function. bool analyze(); - /// Returns the managled name of the function that should be generated from + /// Returns the mangled name of the function that should be generated from /// this function analyzer. - llvm::SmallString<64> getOptimizedName(); + std::string getOptimizedName(); /// Create a new empty function with the optimized signature found by this /// analysis. /// /// *NOTE* This occurs in the same module as F. - SILFunction *createEmptyFunctionWithOptimizedSig(llvm::SmallString<64> &Name); + SILFunction *createEmptyFunctionWithOptimizedSig(const std::string &Name); ArrayRef getArgDescList() const { return ArgDescList; } MutableArrayRef getArgDescList() { return ArgDescList; } @@ -494,8 +492,7 @@ class FunctionAnalyzer { /// This function goes through the arguments of F and sees if we have anything /// to optimize in which case it returns true. If we have nothing to optimize, /// it returns false. -bool -FunctionAnalyzer::analyze() { +bool FunctionAnalyzer::analyze() { // For now ignore functions with indirect results. if (F->getLoweredFunctionType()->hasIndirectResult()) return false; @@ -505,10 +502,8 @@ FunctionAnalyzer::analyze() { // A map from consumed SILArguments to the release associated with an // argument. ConsumedArgToEpilogueReleaseMatcher ArgToReturnReleaseMap(RCIA, F); - ConsumedArgToEpilogueReleaseMatcher ArgToThrowReleaseMap; - auto ThrowBBIter = F->findThrowBB(); - if (ThrowBBIter != F->end()) - ArgToThrowReleaseMap.findMatchingReleases(RCIA, &*ThrowBBIter); + ConsumedArgToEpilogueReleaseMatcher ArgToThrowReleaseMap( + RCIA, F, ConsumedArgToEpilogueReleaseMatcher::ExitKind::Throw); for (unsigned i = 0, e = Args.size(); i != e; ++i) { ArgumentDescriptor A(Allocator, Args[i]); @@ -530,12 +525,12 @@ FunctionAnalyzer::analyze() { if (A.hasConvention(ParameterConvention::Direct_Owned)) { if (auto *Release = ArgToReturnReleaseMap.releaseForArgument(A.Arg)) { SILInstruction *ReleaseInThrow = nullptr; - + // If the function has a throw block we must also find a matching // release in the throw block. - if (ThrowBBIter == F->end() || + if (!ArgToThrowReleaseMap.hasBlock() || (ReleaseInThrow = ArgToThrowReleaseMap.releaseForArgument(A.Arg))) { - + // TODO: accept a second release in the throw block to let the // argument be dead. if (OnlyRelease && OnlyRelease.getValue().getPtrOrNull() == Release) { @@ -573,8 +568,7 @@ FunctionAnalyzer::analyze() { // Creating the New Function //===----------------------------------------------------------------------===// -CanSILFunctionType -FunctionAnalyzer::createOptimizedSILFunctionType() { +CanSILFunctionType FunctionAnalyzer::createOptimizedSILFunctionType() { const ASTContext &Ctx = F->getModule().getASTContext(); CanSILFunctionType FTy = F->getLoweredFunctionType(); @@ -595,26 +589,22 @@ FunctionAnalyzer::createOptimizedSILFunctionType() { if (HaveModifiedSelfArgument) ExtInfo = ExtInfo.withRepresentation(SILFunctionTypeRepresentation::Thin); - return SILFunctionType::get(FTy->getGenericSignature(), - ExtInfo, - FTy->getCalleeConvention(), - InterfaceParams, InterfaceResult, - InterfaceErrorResult, Ctx); + return SILFunctionType::get(FTy->getGenericSignature(), ExtInfo, + FTy->getCalleeConvention(), InterfaceParams, + InterfaceResult, InterfaceErrorResult, Ctx); } -SILFunction * -FunctionAnalyzer:: -createEmptyFunctionWithOptimizedSig(llvm::SmallString<64> &NewFName) { +SILFunction *FunctionAnalyzer::createEmptyFunctionWithOptimizedSig( + const std::string &NewFName) { SILModule &M = F->getModule(); // Create the new optimized function type. CanSILFunctionType NewFTy = createOptimizedSILFunctionType(); // Create the new function. - SILFunction *NewF = SILFunction::create( - M, F->getLinkage(), NewFName, NewFTy, nullptr, F->getLocation(), - F->isBare(), F->isTransparent(), F->isFragile(), F->isThunk(), - F->getClassVisibility(), + auto *NewF = M.getOrCreateFunction( + F->getLinkage(), NewFName, NewFTy, nullptr, F->getLocation(), F->isBare(), + F->isTransparent(), F->isFragile(), F->isThunk(), F->getClassVisibility(), F->getInlineStrategy(), F->getEffectsKind(), 0, F->getDebugScope(), F->getDeclContext()); @@ -622,8 +612,9 @@ createEmptyFunctionWithOptimizedSig(llvm::SmallString<64> &NewFName) { // Array semantic clients rely on the signature being as in the original // version. - if (!F->getSemanticsAttr().startswith("array.")) - NewF->setSemanticsAttr(F->getSemanticsAttr()); + for (auto &Attr : F->getSemanticsAttrs()) + if (!StringRef(Attr).startswith("array.")) + NewF->addSemanticsAttr(Attr); return NewF; } @@ -632,38 +623,33 @@ createEmptyFunctionWithOptimizedSig(llvm::SmallString<64> &NewFName) { // Mangling //===----------------------------------------------------------------------===// -llvm::SmallString<64> FunctionAnalyzer::getOptimizedName() { - llvm::SmallString<64> Name; +std::string FunctionAnalyzer::getOptimizedName() { + Mangle::Mangler M; + auto P = SpecializationPass::FunctionSignatureOpts; + FunctionSignatureSpecializationMangler FSSM(P, M, F); - { - llvm::raw_svector_ostream buffer(Name); - Mangle::Mangler M(buffer); - auto P = Mangle::SpecializationPass::FunctionSignatureOpts; - Mangle::FunctionSignatureSpecializationMangler FSSM(P, M, F); - - for (unsigned i : indices(ArgDescList)) { - const ArgumentDescriptor &Arg = ArgDescList[i]; - if (Arg.IsDead) { - FSSM.setArgumentDead(i); - } - - // If we have an @owned argument and found a callee release for it, - // convert the argument to guaranteed. - if (Arg.CalleeRelease) { - FSSM.setArgumentOwnedToGuaranteed(i); - } + for (unsigned i : indices(ArgDescList)) { + const ArgumentDescriptor &Arg = ArgDescList[i]; + if (Arg.IsDead) { + FSSM.setArgumentDead(i); + } - // If this argument is not dead and we can explode it, add 's' to the - // mangling. - if (Arg.shouldExplode() && !Arg.IsDead) { - FSSM.setArgumentSROA(i); - } + // If we have an @owned argument and found a callee release for it, + // convert the argument to guaranteed. + if (Arg.CalleeRelease) { + FSSM.setArgumentOwnedToGuaranteed(i); } - FSSM.mangle(); + // If this argument is not dead and we can explode it, add 's' to the + // mangling. + if (Arg.shouldExplode() && !Arg.IsDead) { + FSSM.setArgumentSROA(i); + } } - return Name; + FSSM.mangle(); + + return M.finalize(); } //===----------------------------------------------------------------------===// @@ -672,10 +658,9 @@ llvm::SmallString<64> FunctionAnalyzer::getOptimizedName() { /// This function takes in OldF and all callsites of OldF and rewrites the /// callsites to call the new function. -static void -rewriteApplyInstToCallNewFunction(FunctionAnalyzer &Analyzer, - SILFunction *NewF, - const ApplyList &CallSites) { +static void rewriteApplyInstToCallNewFunction(FunctionAnalyzer &Analyzer, + SILFunction *NewF, + const ApplyList &CallSites) { for (auto FAS : CallSites) { auto *AI = FAS.getInstruction(); @@ -700,15 +685,15 @@ rewriteApplyInstToCallNewFunction(FunctionAnalyzer &Analyzer, SILInstruction *NewAI; if (ApplyInst *RealAI = dyn_cast(AI)) { NewAI = Builder.createApply(Loc, FRI, LoweredType, ResultType, - ArrayRef(), NewArgs, - RealAI->isNonThrowing()); + ArrayRef(), NewArgs, + RealAI->isNonThrowing()); // Replace all uses of the old apply with the new apply. AI->replaceAllUsesWith(NewAI); } else { auto *TAI = cast(AI); NewAI = Builder.createTryApply(Loc, FRI, LoweredType, - ArrayRef(), NewArgs, - TAI->getNormalBB(), TAI->getErrorBB()); + ArrayRef(), NewArgs, + TAI->getNormalBB(), TAI->getErrorBB()); Builder.setInsertionPoint(TAI->getErrorBB(), TAI->getErrorBB()->begin()); // If we have any arguments that were consumed but are now guaranteed, @@ -719,7 +704,8 @@ rewriteApplyInstToCallNewFunction(FunctionAnalyzer &Analyzer, Builder.createReleaseValue(Loc, FAS.getArgument(ArgDesc.Index)); } // Also insert release_value in the normal block (done below). - Builder.setInsertionPoint(TAI->getNormalBB(), TAI->getNormalBB()->begin()); + Builder.setInsertionPoint(TAI->getNormalBB(), + TAI->getNormalBB()->begin()); } // If we have any arguments that were consumed but are now guaranteed, @@ -732,7 +718,7 @@ rewriteApplyInstToCallNewFunction(FunctionAnalyzer &Analyzer, // Erase the old apply and its callee. recursivelyDeleteTriviallyDeadInstructions(AI, true, - [](SILInstruction *){}); + [](SILInstruction *) {}); ++NumCallSitesOptimized; } @@ -766,13 +752,12 @@ static void createThunkBody(SILBasicBlock *BB, SILFunction *NewF, SILBasicBlock *NormalBlock = Thunk->createBasicBlock(); ReturnValue = NormalBlock->createBBArg(ResultType, 0); SILBasicBlock *ErrorBlock = Thunk->createBasicBlock(); - SILType ErrorType = SILType::getPrimitiveObjectType( - FunctionTy->getErrorResult().getType()); + SILType ErrorType = + SILType::getPrimitiveObjectType(FunctionTy->getErrorResult().getType()); auto *ErrorArg = ErrorBlock->createBBArg(ErrorType, 0); - Builder.createTryApply(Loc, FRI, LoweredType, - ArrayRef(), ThunkArgs, - NormalBlock, ErrorBlock); - + Builder.createTryApply(Loc, FRI, LoweredType, ArrayRef(), + ThunkArgs, NormalBlock, ErrorBlock); + // If we have any arguments that were consumed but are now guaranteed, // insert a release_value in the error block. Builder.setInsertionPoint(ErrorBlock); @@ -786,9 +771,9 @@ static void createThunkBody(SILBasicBlock *BB, SILFunction *NewF, // Also insert release_value in the normal block (done below). Builder.setInsertionPoint(NormalBlock); } else { - ReturnValue = Builder.createApply(Loc, FRI, LoweredType, ResultType, - ArrayRef(), - ThunkArgs, false); + ReturnValue = + Builder.createApply(Loc, FRI, LoweredType, ResultType, + ArrayRef(), ThunkArgs, false); } // If we have any arguments that were consumed but are now guaranteed, @@ -811,7 +796,7 @@ static void createThunkBody(SILBasicBlock *BB, SILFunction *NewF, static SILFunction * moveFunctionBodyToNewFunctionWithName(SILFunction *F, - llvm::SmallString<64> &NewFName, + const std::string &NewFName, FunctionAnalyzer &Analyzer) { // First we create an empty function (i.e. no BB) whose function signature has // had its arity modified. @@ -836,18 +821,17 @@ moveFunctionBodyToNewFunctionWithName(SILFunction *F, // instruction. Builder.setInsertionPoint(NewFEntryBB->begin()); DEBUG(llvm::dbgs() << "Updating arguments at ArgOffset: " << ArgOffset - << " for: " << *ArgDesc.Arg); + << " for: " << *ArgDesc.Arg); ArgOffset = ArgDesc.updateOptimizedBBArgs(Builder, NewFEntryBB, ArgOffset); } // Otherwise generate the thunk body just in case. SILBasicBlock *ThunkBody = F->createBasicBlock(); for (auto &ArgDesc : ArgDescs) { - ThunkBody->createBBArg(ArgDesc.ParameterInfo.getSILType(), - ArgDesc.Decl); + ThunkBody->createBBArg(ArgDesc.ParameterInfo.getSILType(), ArgDesc.Decl); } createThunkBody(ThunkBody, NewF, Analyzer); - + F->setThunk(IsThunk); assert(F->getDebugScope()->SILFn != NewF->getDebugScope()->SILFn); @@ -860,11 +844,10 @@ moveFunctionBodyToNewFunctionWithName(SILFunction *F, /// reduce code duplication in cases where we missed a callsite to F. The /// function returns true if we were successful in creating the new function and /// returns false otherwise. -static bool -optimizeFunctionSignature(llvm::BumpPtrAllocator &BPA, - RCIdentityFunctionInfo *RCIA, - SILFunction *F, - const ApplyList &CallSites) { +static bool optimizeFunctionSignature(llvm::BumpPtrAllocator &BPA, + RCIdentityFunctionInfo *RCIA, + SILFunction *F, + const ApplyList &CallSites) { DEBUG(llvm::dbgs() << "Optimizing Function Signature of " << F->getName() << "\n"); @@ -887,7 +870,7 @@ optimizeFunctionSignature(llvm::BumpPtrAllocator &BPA, ++NumFunctionSignaturesOptimized; - llvm::SmallString<64> NewFName = Analyzer.getOptimizedName(); + auto NewFName = Analyzer.getOptimizedName(); // If we already have a specialized version of this function, do not // respecialize. For now just bail. @@ -900,8 +883,8 @@ optimizeFunctionSignature(llvm::BumpPtrAllocator &BPA, return false; // Otherwise, move F over to NewF. - SILFunction *NewF = moveFunctionBodyToNewFunctionWithName(F, NewFName, - Analyzer); + SILFunction *NewF = + moveFunctionBodyToNewFunctionWithName(F, NewFName, Analyzer); // And remove all Callee releases that we found and made redundant via owned // to guaranteed conversion. @@ -1003,7 +986,8 @@ class FunctionSignatureOpts : public SILModuleTransform { for (auto &F : *M) { // Don't optimize callers that are marked as 'no.optimize'. - if (!F.shouldOptimize()) continue; + if (!F.shouldOptimize()) + continue; // Scan the whole module and search Apply sites. for (auto &BB : F) { @@ -1018,7 +1002,8 @@ class FunctionSignatureOpts : public SILModuleTransform { // Find the target function. auto *FRI = dyn_cast(Callee); - if (!FRI) continue; + if (!FRI) + continue; SILFunction *F = FRI->getReferencedFunction(); CallerMap[F].push_back(Apply); @@ -1050,8 +1035,8 @@ class FunctionSignatureOpts : public SILModuleTransform { continue; // Otherwise, try to optimize the function signature of F. - Changed |= optimizeFunctionSignature(Allocator, RCIA->get(F), F, - CallSites); + Changed |= + optimizeFunctionSignature(Allocator, RCIA->get(F), F, CallSites); } // If we changed anything, invalidate the call graph. diff --git a/lib/SILPasses/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp similarity index 95% rename from lib/SILPasses/IPO/GlobalOpt.cpp rename to lib/SILOptimizer/IPO/GlobalOpt.cpp index 90ef1c6507b05..7c917bca46e22 100644 --- a/lib/SILPasses/IPO/GlobalOpt.cpp +++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp @@ -1,8 +1,8 @@ -//===---------- SILGlobalOpt.cpp - Optimize global initializers -----------===// +//===--- GlobalOpt.cpp - Optimize global initializers ---------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,11 +15,11 @@ #include "swift/SIL/CFG.h" #include "swift/SIL/DebugUtils.h" #include "swift/SIL/SILInstruction.h" -#include "swift/SILAnalysis/ColdBlockInfo.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/ColdBlockInfo.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SCCIterator.h" #include "llvm/Support/CommandLine.h" @@ -164,7 +164,7 @@ void SILGlobalOpt::collectGlobalLoad(LoadInst *LI, SILGlobalVariable *SILG) { //assert(SILG->isLet()); // This is read from a let variable. - // Figure out if the value of this variable is statitcally known. + // Figure out if the value of this variable is statically known. GlobalLoadMap[SILG].push_back(LI); } @@ -195,13 +195,13 @@ static void removeToken(SILValue Op) { static SILFunction *genGetterFromInit(StoreInst *Store, SILGlobalVariable *SILG) { auto *varDecl = SILG->getDecl(); - llvm::SmallString<20> getterBuffer; - llvm::raw_svector_ostream getterStream(getterBuffer); - Mangle::Mangler getterMangler(getterStream); + + Mangle::Mangler getterMangler; getterMangler.mangleGlobalGetterEntity(varDecl); + auto getterName = getterMangler.finalize(); // Check if a getter was generated already. - if (auto *F = Store->getModule().lookUpFunction(getterStream.str())) + if (auto *F = Store->getModule().lookUpFunction(getterName)) return F; // Find the code that performs the initialization first. @@ -231,7 +231,7 @@ static SILFunction *genGetterFromInit(StoreInst *Store, ParameterConvention::Direct_Owned, { }, ResultInfo, None, Store->getModule().getASTContext()); auto *GetterF = Store->getModule().getOrCreateFunction(Store->getLoc(), - getterStream.str(), SILLinkage::PrivateExternal, LoweredType, + getterName, SILLinkage::PrivateExternal, LoweredType, IsBare_t::IsBare, IsTransparent_t::IsNotTransparent, IsFragile_t::IsFragile); GetterF->setDebugScope(Store->getFunction()->getDebugScope()); @@ -304,7 +304,7 @@ void SILGlobalOpt::collectOnceCall(BuiltinInst *BI) { if (!Callee->getName().startswith("globalinit_")) return; - // We currently disable optimizing the intializer if a globalinit_func + // We currently disable optimizing the initializer if a globalinit_func // is called by "once" from multiple locations. if (!BI->getFunction()->isGlobalInit()) // If a globalinit_func is called by "once" from a function that is not @@ -343,10 +343,10 @@ static bool isAvailabilityCheck(SILBasicBlock *BB) { return false; SILFunction *F = AI->getCalleeFunction(); - if (!F || !F->hasDefinedSemantics()) + if (!F || !F->hasSemanticsAttrs()) return false; - - return F->getSemanticsString().startswith("availability"); + + return F->hasSemanticsAttrsThatStartsWith("availability"); } /// Returns true if there are any availability checks along the dominator tree @@ -429,7 +429,7 @@ void SILGlobalOpt::placeInitializers(SILFunction *InitF, while (Node) { SILBasicBlock *DomParentBB = Node->getBlock(); if (isAvailabilityCheck(DomParentBB)) { - DEBUG(llvm::dbgs() << " don't hoist above availibility check at bb" << + DEBUG(llvm::dbgs() << " don't hoist above availability check at bb" << DomParentBB->getDebugID() << "\n"); break; } @@ -454,16 +454,16 @@ void SILGlobalOpt::placeInitializers(SILFunction *InitF, } } -/// Create a getter function from the intializer function. +/// Create a getter function from the initializer function. static SILFunction *genGetterFromInit(SILFunction *InitF, VarDecl *varDecl) { // Generate a getter from the global init function without side-effects. - llvm::SmallString<20> getterBuffer; - llvm::raw_svector_ostream getterStream(getterBuffer); - Mangle::Mangler getterMangler(getterStream); + + Mangle::Mangler getterMangler; getterMangler.mangleGlobalGetterEntity(varDecl); + auto getterName = getterMangler.finalize(); // Check if a getter was generated already. - if (auto *F = InitF->getModule().lookUpFunction(getterStream.str())) + if (auto *F = InitF->getModule().lookUpFunction(getterName)) return F; auto refType = varDecl->getType().getCanonicalTypeOrNull(); @@ -475,7 +475,7 @@ static SILFunction *genGetterFromInit(SILFunction *InitF, VarDecl *varDecl) { ParameterConvention::Direct_Owned, { }, ResultInfo, None, InitF->getASTContext()); auto *GetterF = InitF->getModule().getOrCreateFunction(InitF->getLocation(), - getterStream.str(), SILLinkage::PrivateExternal, LoweredType, + getterName, SILLinkage::PrivateExternal, LoweredType, IsBare_t::IsBare, IsTransparent_t::IsNotTransparent, IsFragile_t::IsFragile); @@ -549,7 +549,7 @@ static bool isAssignedOnlyOnceInInitializer(SILGlobalVariable *SILG) { return false; } -/// Replace load sequence which may contian +/// Replace load sequence which may contain /// a chain of struct_element_addr followed by a load. /// The sequence is traversed starting from the load /// instruction. diff --git a/lib/SILPasses/IPO/GlobalPropertyOpt.cpp b/lib/SILOptimizer/IPO/GlobalPropertyOpt.cpp similarity index 97% rename from lib/SILPasses/IPO/GlobalPropertyOpt.cpp rename to lib/SILOptimizer/IPO/GlobalPropertyOpt.cpp index eb7009b8cf399..5de9ed177c81d 100644 --- a/lib/SILPasses/IPO/GlobalPropertyOpt.cpp +++ b/lib/SILOptimizer/IPO/GlobalPropertyOpt.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,15 +11,15 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "globalpropertyopt" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILBuilder.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILAnalysis/ArraySemantic.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/Statistic.h" @@ -35,7 +35,7 @@ namespace { /// The GlobalPropertyOpt performs an analysis on the whole module to determine /// the values of high-level properties. /// -/// Currently only one property is handled and thats the isNativeTypeChecked +/// Currently only one property is handled and that's the isNativeTypeChecked /// property for arrays. If the property can be proved to be true, the /// corresponding semantics-call is replaced by a true-literal. class GlobalPropertyOpt { @@ -174,7 +174,7 @@ class GlobalPropertyOpt { if (auto *SEI = dyn_cast(def)) { return getFieldEntry(SEI->getField()); } - if (isa(def) && value.getResultNumber() == 1) { + if (isa(def)) { Entry * &entry = ValueEntries[value]; if (!entry) { entry = new (EntryAllocator.Allocate()) Entry(value, nullptr); @@ -295,7 +295,6 @@ void GlobalPropertyOpt::scanInstruction(swift::SILInstruction *Inst) { // swift array. DEBUG(llvm::dbgs() << " array semantics call: " << *AI); return; - case ArrayCallKind::kArrayPropsIsNative: case ArrayCallKind::kArrayPropsIsNativeTypeChecked: // Remember the property-calls for later. DEBUG(llvm::dbgs() << " property check: " << *AI); @@ -469,8 +468,7 @@ bool GlobalPropertyOpt::replacePropertyCalls() { ArraySemanticsCall semCall(AI); assert( - (semCall.getKind() == ArrayCallKind::kArrayPropsIsNative || - semCall.getKind() == ArrayCallKind::kArrayPropsIsNativeTypeChecked) && + (semCall.getKind() == ArrayCallKind::kArrayPropsIsNativeTypeChecked) && "invalid semantics type"); DEBUG(llvm::dbgs() << " remove property check in function " << diff --git a/lib/SILPasses/IPO/LetPropertiesOpts.cpp b/lib/SILOptimizer/IPO/LetPropertiesOpts.cpp similarity index 98% rename from lib/SILPasses/IPO/LetPropertiesOpts.cpp rename to lib/SILOptimizer/IPO/LetPropertiesOpts.cpp index 395ac90eb97de..bd1525f366633 100644 --- a/lib/SILPasses/IPO/LetPropertiesOpts.cpp +++ b/lib/SILOptimizer/IPO/LetPropertiesOpts.cpp @@ -1,8 +1,8 @@ -//===---------- LetPropertiesOpt.cpp - Optimize let properties ------------===// +//===--- LetPropertiesOpts.cpp - Optimize let properties ------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,9 +17,9 @@ #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/MapVector.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" diff --git a/lib/SILPasses/IPO/PerformanceInliner.cpp b/lib/SILOptimizer/IPO/PerformanceInliner.cpp similarity index 88% rename from lib/SILPasses/IPO/PerformanceInliner.cpp rename to lib/SILOptimizer/IPO/PerformanceInliner.cpp index d66ca1eaaafc8..6fffb126fb693 100644 --- a/lib/SILPasses/IPO/PerformanceInliner.cpp +++ b/lib/SILOptimizer/IPO/PerformanceInliner.cpp @@ -1,8 +1,8 @@ -//===- PerformanceInliner.cpp - Basic cost based inlining for performance -===// +//===--- PerformanceInliner.cpp - Basic cost based performance inlining ---===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,19 +15,18 @@ #include "swift/SIL/Dominance.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/Projection.h" -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" -#include "swift/SILAnalysis/CallGraphAnalysis.h" -#include "swift/SILAnalysis/ColdBlockInfo.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/FunctionOrder.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/ConstantFolding.h" -#include "swift/SILPasses/Utils/Devirtualize.h" -#include "swift/SILPasses/Utils/Generics.h" -#include "swift/SILPasses/Utils/SILInliner.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/ColdBlockInfo.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/FunctionOrder.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/ConstantFolding.h" +#include "swift/SILOptimizer/Utils/Devirtualize.h" +#include "swift/SILOptimizer/Utils/Generics.h" +#include "swift/SILOptimizer/Utils/SILInliner.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -217,7 +216,7 @@ namespace { }; class SILPerformanceInliner { - /// The inline threashold. + /// The inline threshold. const int InlineCostThreshold; /// Specifies which functions not to inline, based on @_semantics and /// global_init attributes. @@ -250,22 +249,22 @@ namespace { /// \p Caller and the inliner needs to reject this inlining request. bool hasInliningCycle(SILFunction *Caller, SILFunction *Callee); - FullApplySite devirtualizeUpdatingCallGraph(FullApplySite Apply, - CallGraph &CG); + FullApplySite devirtualize(FullApplySite Apply, + ClassHierarchyAnalysis *CHA); bool devirtualizeAndSpecializeApplies( - llvm::SmallVectorImpl &Applies, - CallGraphAnalysis *CGA, + llvm::SmallVectorImpl &Applies, SILModuleTransform *MT, + ClassHierarchyAnalysis *CHA, llvm::SmallVectorImpl &WorkList); - ApplySite specializeGenericUpdatingCallGraph(ApplySite Apply, - CallGraph &CG, - llvm::SmallVectorImpl &NewApplies); + ApplySite specializeGeneric(ApplySite Apply, + llvm::SmallVectorImpl &NewApplies); - bool inlineCallsIntoFunction(SILFunction *F, DominanceAnalysis *DA, - SILLoopAnalysis *LA, CallGraph &CG, - llvm::SmallVectorImpl &NewApplies); + bool + inlineCallsIntoFunction(SILFunction *F, DominanceAnalysis *DA, + SILLoopAnalysis *LA, + llvm::SmallVectorImpl &NewApplies); public: SILPerformanceInliner(int threshold, @@ -275,9 +274,9 @@ namespace { void inlineDevirtualizeAndSpecialize(SILFunction *WorkItem, SILModuleTransform *MT, - CallGraphAnalysis *CGA, DominanceAnalysis *DA, - SILLoopAnalysis *LA); + SILLoopAnalysis *LA, + ClassHierarchyAnalysis *CHA); }; } @@ -287,7 +286,7 @@ namespace { void ConstantTracker::trackInst(SILInstruction *inst) { - if (LoadInst *LI = dyn_cast(inst)) { + if (auto *LI = dyn_cast(inst)) { SILValue baseAddr = scanProjections(LI->getOperand()); if (SILInstruction *loadLink = getMemoryContent(baseAddr)) links[LI] = loadLink; @@ -535,14 +534,35 @@ bool SILPerformanceInliner::hasInliningCycle(SILFunction *Caller, StringRef CallerName = Caller->getName(); StringRef CalleeName = Callee->getName(); - bool InlinedBefore = InlinedFunctions.count(std::make_pair(CallerName, CalleeName)); + bool InlinedBefore = + InlinedFunctions.count(std::make_pair(CallerName, CalleeName)); - // If the Callee was inlined into the Caller in previous inlining iterations then + // If the Callee was inlined into the Caller in previous inlining iterations + // then // we need to reject this inlining request to prevent a cycle. return InlinedBefore; } -// Returns the callee of an apply_inst if it is basically inlinable. +// Return true if the callee does few (or no) self-recursive calls. +static bool calleeHasMinimalSelfRecursion(SILFunction *Callee) { + int countSelfRecursiveCalls = 0; + + for (auto &BB : *Callee) { + for (auto &I : BB) { + if (auto Apply = FullApplySite::isa(&I)) { + if (Apply.getCalleeFunction() == Callee) + ++countSelfRecursiveCalls; + + if (countSelfRecursiveCalls > 2) + return true; + } + } + } + + return false; +} + +// Returns the callee of an apply_inst if it is basically inlineable. SILFunction *SILPerformanceInliner::getEligibleFunction(FullApplySite AI) { SILFunction *Callee = AI.getCalleeFunction(); @@ -554,16 +574,16 @@ SILFunction *SILPerformanceInliner::getEligibleFunction(FullApplySite AI) { // Don't inline functions that are marked with the @_semantics or @effects // attribute if the inliner is asked not to inline them. - if (Callee->hasDefinedSemantics() || Callee->hasEffectsKind()) { + if (Callee->hasSemanticsAttrs() || Callee->hasEffectsKind()) { if (WhatToInline == InlineSelection::NoSemanticsAndGlobalInit) { DEBUG(llvm::dbgs() << " FAIL: Function " << Callee->getName() << " has special semantics or effects attribute.\n"); return nullptr; } // The "availability" semantics attribute is treated like global-init. - if (Callee->hasDefinedSemantics() && + if (Callee->hasSemanticsAttrs() && WhatToInline != InlineSelection::Everything && - Callee->getSemanticsString().startswith("availability")) { + Callee->hasSemanticsAttrsThatStartsWith("availability")) { return nullptr; } } else if (Callee->isGlobalInit()) { @@ -624,6 +644,17 @@ SILFunction *SILPerformanceInliner::getEligibleFunction(FullApplySite AI) { Callee->getName() << ".\n"); return nullptr; } + + // Inlining self-recursive functions into other functions can result + // in excessive code duplication since we run the inliner multiple + // times in our pipeline, so we only do it for callees with few + // self-recursive calls. + if (calleeHasMinimalSelfRecursion(Callee)) { + DEBUG(llvm::dbgs() << " FAIL: Callee is self-recursive in " + << Callee->getName() << ".\n"); + return nullptr; + } + DEBUG(llvm::dbgs() << " Eligible callee: " << Callee->getName() << "\n"); @@ -747,7 +778,8 @@ bool SILPerformanceInliner::isProfitableToInline(FullApplySite AI, SILInstruction *def = constTracker.getDefInCaller(AI->getCallee()); if (def && (isa(def) || isa(def))) { - DEBUG(llvm::dbgs() << " Boost: apply const function at" << *AI); + DEBUG(llvm::dbgs() << " Boost: apply const function at" + << *AI); Benefit += ConstCalleeBenefit + loopDepth * LoopBenefitFactor; testThreshold *= 2; } @@ -814,30 +846,39 @@ static bool isProfitableInColdBlock(SILFunction *Callee) { return true; } +/// FIXME: Total hack to work around issues exposed while ripping call +/// graph maintenance from the inliner. +static void tryLinkCallee(FullApplySite Apply) { + auto *F = Apply.getCalleeFunction(); + if (!F || F->isDefinition()) return; + + auto &M = Apply.getFunction()->getModule(); + M.linkFunction(F, SILModule::LinkingMode::LinkAll); +} + +// Attempt to devirtualize. When successful, replaces the old apply +// with the new one and returns the new one. When unsuccessful returns +// an empty apply site. +FullApplySite SILPerformanceInliner::devirtualize(FullApplySite Apply, + ClassHierarchyAnalysis *CHA) { -// Attempt to devirtualize, maintaining the call graph if -// successful. When successful, replaces the old apply with the new -// one and returns the new one. When unsuccessful returns an empty -// apply site. -FullApplySite SILPerformanceInliner::devirtualizeUpdatingCallGraph( - FullApplySite Apply, - CallGraph &CG) { - auto NewInstPair = tryDevirtualizeApply(Apply); + auto NewInstPair = tryDevirtualizeApply(Apply, CHA); if (!NewInstPair.second) return FullApplySite(); - auto NewAI = FullApplySite::isa(NewInstPair.second.getInstruction()); - CallGraphEditor(&CG).replaceApplyWithNew(Apply, NewAI); - replaceDeadApply(Apply, NewInstPair.first); + auto NewApply = FullApplySite(NewInstPair.second.getInstruction()); + + // FIXME: This should not be needed. We should instead be linking + // everything in up front, including everything transitively + // referenced through vtables and witness tables. + tryLinkCallee(NewApply); - return NewAI; + return FullApplySite(NewInstPair.second.getInstruction()); } -ApplySite SILPerformanceInliner::specializeGenericUpdatingCallGraph( - ApplySite Apply, - CallGraph &CG, - llvm::SmallVectorImpl &NewApplies) { +ApplySite SILPerformanceInliner::specializeGeneric( + ApplySite Apply, llvm::SmallVectorImpl &NewApplies) { assert(NewApplies.empty() && "Expected out parameter for new applies!"); if (!Apply.hasSubstitutions()) @@ -862,15 +903,9 @@ ApplySite SILPerformanceInliner::specializeGenericUpdatingCallGraph( if (!Specialized) return ApplySite(); - // Add the specialization to the call graph. - CallGraphEditor Editor(&CG); - if (SpecializedFunction) - Editor.addNewFunction(SpecializedFunction); - // Track the new applies from the specialization. for (auto NewCallSite : Collector.getInstructionPairs()) - if (auto NewApply = ApplySite::isa(NewCallSite.first)) - NewApplies.push_back(NewApply); + NewApplies.push_back(ApplySite(NewCallSite.first)); auto FullApply = FullApplySite::isa(Apply.getInstruction()); @@ -880,19 +915,14 @@ ApplySite SILPerformanceInliner::specializeGenericUpdatingCallGraph( // Replace the old apply with the new and delete the old. replaceDeadApply(Apply, Specialized.getInstruction()); - Editor.updatePartialApplyUses(Specialized); return ApplySite(Specialized); } - // Update call graph edges - auto SpecializedFullApply = FullApplySite(Specialized.getInstruction()); - Editor.replaceApplyWithNew(FullApply, SpecializedFullApply); - // Replace the old apply with the new and delete the old. replaceDeadApply(Apply, Specialized.getInstruction()); - return SpecializedFullApply; + return Specialized; } static void collectAllAppliesInFunction(SILFunction *F, @@ -905,10 +935,10 @@ static void collectAllAppliesInFunction(SILFunction *F, Applies.push_back(Apply); } -// Devirtualize and specialize a group of applies, updating the call -// graph and returning a worklist of newly exposed function references -// that should be considered for inlining before continuing with the -// caller that has the passed-in applies. +// Devirtualize and specialize a group of applies, returning a +// worklist of newly exposed function references that should be +// considered for inlining before continuing with the caller that has +// the passed-in applies. // // The returned worklist is stacked such that the last things we want // to process are earlier on the list. @@ -916,12 +946,11 @@ static void collectAllAppliesInFunction(SILFunction *F, // Returns true if any changes were made. bool SILPerformanceInliner::devirtualizeAndSpecializeApplies( llvm::SmallVectorImpl &Applies, - CallGraphAnalysis *CGA, SILModuleTransform *MT, + ClassHierarchyAnalysis *CHA, llvm::SmallVectorImpl &WorkList) { assert(WorkList.empty() && "Expected empty worklist for return results!"); - auto &CG = CGA->getCallGraph(); bool ChangedAny = false; // The set of all new function references generated by @@ -936,7 +965,7 @@ bool SILPerformanceInliner::devirtualizeAndSpecializeApplies( bool ChangedApply = false; if (auto FullApply = FullApplySite::isa(Apply.getInstruction())) { - if (auto NewApply = devirtualizeUpdatingCallGraph(FullApply, CG)) { + if (auto NewApply = devirtualize(FullApply, CHA)) { ChangedApply = true; Apply = ApplySite(NewApply.getInstruction()); @@ -944,8 +973,7 @@ bool SILPerformanceInliner::devirtualizeAndSpecializeApplies( } llvm::SmallVector NewApplies; - if (auto NewApply = specializeGenericUpdatingCallGraph(Apply, CG, - NewApplies)) { + if (auto NewApply = specializeGeneric(Apply, NewApplies)) { ChangedApply = true; Apply = NewApply; @@ -965,10 +993,8 @@ bool SILPerformanceInliner::devirtualizeAndSpecializeApplies( // TODO: Do we need to invalidate everything at this point? // What about side-effects analysis? What about type analysis? - CGA->lockInvalidation(); MT->invalidateAnalysis(Apply.getFunction(), SILAnalysis::InvalidationKind::Everything); - CGA->unlockInvalidation(); } } @@ -1045,7 +1071,6 @@ void SILPerformanceInliner::collectAppliesToInline( bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller, DominanceAnalysis *DA, SILLoopAnalysis *LA, - CallGraph &CG, llvm::SmallVectorImpl &NewApplies) { // Don't optimize functions that are marked with the opt.never attribute. if (!Caller->shouldOptimize()) @@ -1085,11 +1110,10 @@ bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller, SmallVector Args; for (const auto &Arg : AI.getArguments()) Args.push_back(Arg); - - // As we inline and clone we need to collect instructions that - // require updates to the call graph. + + // As we inline and clone we need to collect new applies. auto Filter = [](SILInstruction *I) -> bool { - return I->mayRelease(); + return bool(FullApplySite::isa(I)); }; CloneCollector Collector(Filter); @@ -1111,17 +1135,8 @@ bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller, // we expect it to have happened. assert(Success && "Expected inliner to inline this function!"); llvm::SmallVector AppliesFromInlinee; - llvm::SmallVector NewCallSites; - for (auto &P : Collector.getInstructionPairs()) { - NewCallSites.push_back(P.first); - - if (auto FullApply = FullApplySite::isa(P.first)) { - AppliesFromInlinee.push_back(FullApply); - } - } - - CallGraphEditor Editor(&CG); - Editor.replaceApplyWithCallSites(AI, NewCallSites); + for (auto &P : Collector.getInstructionPairs()) + AppliesFromInlinee.push_back(FullApplySite(P.first)); recursivelyDeleteTriviallyDeadInstructions(AI.getInstruction(), true); @@ -1144,18 +1159,15 @@ bool SILPerformanceInliner::inlineCallsIntoFunction(SILFunction *Caller, void SILPerformanceInliner::inlineDevirtualizeAndSpecialize( SILFunction *Caller, - SILModuleTransform *MT, - CallGraphAnalysis *CGA, - DominanceAnalysis *DA, - SILLoopAnalysis *LA) { - assert(Caller->isDefinition() && - "Expected only defined functions in the call graph!"); + SILModuleTransform *MT, + DominanceAnalysis *DA, + SILLoopAnalysis *LA, + ClassHierarchyAnalysis *CHA) { + assert(Caller->isDefinition() && "Expected only functions with bodies!"); llvm::SmallVector WorkList; WorkList.push_back(Caller); - auto &CG = CGA->getOrBuildCallGraph(); - while (!WorkList.empty()) { llvm::SmallVector WorkItemApplies; SILFunction *CurrentCaller = WorkList.back(); @@ -1166,7 +1178,7 @@ void SILPerformanceInliner::inlineDevirtualizeAndSpecialize( // and collect new functions we should inline into as we do // so. llvm::SmallVector NewFuncs; - if (devirtualizeAndSpecializeApplies(WorkItemApplies, CGA, MT, NewFuncs)) { + if (devirtualizeAndSpecializeApplies(WorkItemApplies, MT, CHA, NewFuncs)) { WorkList.insert(WorkList.end(), NewFuncs.begin(), NewFuncs.end()); NewFuncs.clear(); } @@ -1199,14 +1211,10 @@ void SILPerformanceInliner::inlineDevirtualizeAndSpecialize( // Inlining in turn might result in new applies that we should // consider for devirtualization and specialization. llvm::SmallVector NewApplies; - bool Inlined = inlineCallsIntoFunction(WorkItem, DA, LA, CG, NewApplies); + bool Inlined = inlineCallsIntoFunction(WorkItem, DA, LA, NewApplies); if (Inlined) { - // Invalidate analyses, but lock the call graph since we - // maintain it. - CGA->lockInvalidation(); MT->invalidateAnalysis(WorkItem, SILAnalysis::InvalidationKind::FunctionBody); - CGA->unlockInvalidation(); // FIXME: Update inlineCallsIntoFunction to collect all // remaining applies after inlining, not just those @@ -1214,8 +1222,9 @@ void SILPerformanceInliner::inlineDevirtualizeAndSpecialize( llvm::SmallVector WorkItemApplies; collectAllAppliesInFunction(WorkItem, WorkItemApplies); - bool Modified = devirtualizeAndSpecializeApplies(WorkItemApplies, CGA, - MT, NewFuncs); + bool Modified = + devirtualizeAndSpecializeApplies(WorkItemApplies, MT, + CHA, NewFuncs); if (Modified) { WorkList.insert(WorkList.end(), NewFuncs.begin(), NewFuncs.end()); NewFuncs.clear(); @@ -1280,7 +1289,7 @@ void SILPerformanceInliner::visitColdBlocks( //===----------------------------------------------------------------------===// -// Performane Inliner Pass +// Performance Inliner Pass //===----------------------------------------------------------------------===// namespace { @@ -1297,9 +1306,9 @@ class SILPerformanceInlinerPass : public SILModuleTransform { void run() override { BasicCalleeAnalysis *BCA = PM->getAnalysis(); - CallGraphAnalysis *CGA = PM->getAnalysis(); DominanceAnalysis *DA = PM->getAnalysis(); SILLoopAnalysis *LA = PM->getAnalysis(); + ClassHierarchyAnalysis *CHA = PM->getAnalysis(); if (getOptions().InlineThreshold == 0) { DEBUG(llvm::dbgs() << "*** The Performance Inliner is disabled ***\n"); @@ -1322,8 +1331,7 @@ class SILPerformanceInlinerPass : public SILModuleTransform { // Inline functions bottom up from the leafs. while (!WorkList.empty()) { - Inliner.inlineDevirtualizeAndSpecialize(WorkList.back(), this, CGA, DA, - LA); + Inliner.inlineDevirtualizeAndSpecialize(WorkList.back(), this, DA, LA, CHA); WorkList.pop_back(); } } diff --git a/lib/SILPasses/IPO/UsePrespecialized.cpp b/lib/SILOptimizer/IPO/UsePrespecialized.cpp similarity index 87% rename from lib/SILPasses/IPO/UsePrespecialized.cpp rename to lib/SILOptimizer/IPO/UsePrespecialized.cpp index ec513d74e498d..021343561ea1b 100644 --- a/lib/SILPasses/IPO/UsePrespecialized.cpp +++ b/lib/SILOptimizer/IPO/UsePrespecialized.cpp @@ -1,8 +1,8 @@ -//===------- UsePrespecialized.cpp - use pre-specialized functions -------===// +//===--- UsePrespecialized.cpp - use pre-specialized functions ------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,16 +12,16 @@ #define DEBUG_TYPE "use-prespecialized" #include "swift/Basic/Demangle.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "swift/SIL/Mangle.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILModule.h" #include "llvm/Support/Debug.h" -#include "swift/SILPasses/Utils/Generics.h" +#include "swift/SILOptimizer/Utils/Generics.h" using namespace swift; @@ -99,12 +99,12 @@ bool UsePrespecialized::replaceByPrespecialized(SILFunction &F) { continue; // Create a name of the specialization. - llvm::SmallString<64> ClonedName; + std::string ClonedName; { - llvm::raw_svector_ostream buffer(ClonedName); - Mangle::Mangler M(buffer); - Mangle::GenericSpecializationMangler Mangler(M, ReferencedF, Subs); + Mangle::Mangler M; + GenericSpecializationMangler Mangler(M, ReferencedF, Subs); Mangler.mangle(); + ClonedName = M.finalize(); } SILFunction *NewF = nullptr; @@ -123,7 +123,7 @@ bool UsePrespecialized::replaceByPrespecialized(SILFunction &F) { if (!NewF) continue; - // An existing specializaiton was found. + // An existing specialization was found. DEBUG( llvm::dbgs() << "Found a specialization of " << ReferencedF->getName() << " : " << NewF->getName() << "\n"); diff --git a/lib/SILPasses/Loop/ArrayBoundsCheckOpts.cpp b/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp similarity index 96% rename from lib/SILPasses/Loop/ArrayBoundsCheckOpts.cpp rename to lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp index 47a9d5e3c4ed0..19be6f5b42b04 100644 --- a/lib/SILPasses/Loop/ArrayBoundsCheckOpts.cpp +++ b/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp @@ -1,8 +1,8 @@ -//===----- ArrayBoundsCheckOpts.cpp - Bounds check elim ---*- C++ -*-------===// +//===--- ArrayBoundsCheckOpts.cpp - Bounds check elim -----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -14,19 +14,19 @@ #include "swift/Basic/STLExtras.h" #include "swift/AST/Builtins.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILAnalysis/DestructorAnalysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/IVAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/Analysis/DestructorAnalysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/IVAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" #include "swift/SIL/Dominance.h" #include "swift/SIL/PatternMatch.h" #include "swift/SIL/SILArgument.h" @@ -192,7 +192,7 @@ mayChangeArraySize(SILInstruction *I, ArrayCallKind &Kind, SILValue &Array, return ArrayBoundsEffect::kMayChangeAny; } -/// Two allocations of a mutable array struct can not reference the same +/// Two allocations of a mutable array struct cannot reference the same /// storage after modification. So we can treat them as not aliasing for the /// purpose of bound checking. The change would only be tracked through one of /// the allocations. @@ -250,7 +250,7 @@ class ABCAnalysis { ABCAnalysis(const ABCAnalysis &) = delete; ABCAnalysis &operator=(const ABCAnalysis &) = delete; - /// Find safe array bounds check in a loop. An bounds_check is safe if no size + /// Find safe array bounds check in a loop. A bounds_check is safe if no size /// modifying instruction to the same array has been seen so far. /// /// The code relies on isIdentifiedUnderlyingArrayObject' to make sure that a @@ -707,7 +707,7 @@ static SILValue getSub(SILLocation Loc, SILValue Val, unsigned SubVal, return B.createTupleExtract(Loc, AI, 0); } -/// A cannonical induction variable incremented by one from Start to End-1. +/// A canonical induction variable incremented by one from Start to End-1. struct InductionInfo { SILArgument *HeaderVal; BuiltinInst *Inc; @@ -753,7 +753,7 @@ struct InductionInfo { IsOverflowCheckInserted = true; // We can now remove the cond fail on the increment the above comparison - // guarantuees that the addition won't overflow. + // guarantees that the addition won't overflow. auto *CondFail = isOverflowChecked(cast(Inc)); if (CondFail) CondFail->eraseFromParent(); @@ -792,7 +792,7 @@ class InductionAnalysis { // Look for induction variables. IVInfo::IVDesc IV; if (!(IV = IVs.getInductionDesc(Arg))) { - DEBUG(llvm::dbgs() << " not a induction variable: " << *Arg); + DEBUG(llvm::dbgs() << " not an induction variable: " << *Arg); continue; } @@ -876,14 +876,14 @@ class InductionAnalysis { } }; -/// A block in the loop is guarantueed to be excuted if it dominates the exiting +/// A block in the loop is guaranteed to be executed if it dominates the exiting /// block. static bool isGuaranteedToBeExecuted(DominanceInfo *DT, SILBasicBlock *Block, SILBasicBlock *ExitingBlk) { return DT->dominates(Block, ExitingBlk); } -/// Describes the access function "a[f(i)]" that is based on a cannonical +/// Describes the access function "a[f(i)]" that is based on a canonical /// induction variable. class AccessFunction { InductionInfo *Ind; @@ -895,7 +895,7 @@ class AccessFunction { static AccessFunction getLinearFunction(SILValue Idx, InductionAnalysis &IndVars) { - // Match the actual induction variable burried in the integer struct. + // Match the actual induction variable buried in the integer struct. // %2 = struct $Int(%1 : $Builtin.Word) // = apply %check_bounds(%array, %2) : $@convention(thin) (Int, ArrayInt) -> () auto ArrayIndexStruct = dyn_cast(Idx); @@ -919,7 +919,7 @@ class AccessFunction { } /// Hoists the necessary check for beginning and end of the induction - /// encapsulated by this acess function to the header. + /// encapsulated by this access function to the header. void hoistCheckToPreheader(ArraySemanticsCall CheckToHoist, SILBasicBlock *Preheader, DominanceInfo *DT) { @@ -935,7 +935,7 @@ class AccessFunction { // Set the new start index to the first value of the induction. Start->setOperand(0, FirstVal); - // Clone and fixup the load, retain sequenence to the header. + // Clone and fixup the load, retain sequence to the header. auto NewCheck = CheckToHoist.copyTo(Preheader->getTerminator(), DT); NewCheck->setOperand(1, Start); @@ -1069,7 +1069,7 @@ static bool hoistBoundsChecks(SILLoop *Loop, DominanceInfo *DT, SILLoopInfo *LI, auto *Preheader = Loop->getLoopPreheader(); if (!Preheader) { - // TODO: create one if neccessary. + // TODO: create one if necessary. return false; } @@ -1112,7 +1112,7 @@ static bool hoistBoundsChecks(SILLoop *Loop, DominanceInfo *DT, SILLoopInfo *LI, DEBUG(Preheader->getParent()->dump()); - // Find cannonical induction variables. + // Find canonical induction variables. InductionAnalysis IndVars(DT, IVs, Preheader, Header, ExitingBlk, ExitBlk); bool IVarsFound = IndVars.analyse(); if (!IVarsFound){ diff --git a/lib/SILOptimizer/LoopTransforms/CMakeLists.txt b/lib/SILOptimizer/LoopTransforms/CMakeLists.txt new file mode 100644 index 0000000000000..928fb8e852652 --- /dev/null +++ b/lib/SILOptimizer/LoopTransforms/CMakeLists.txt @@ -0,0 +1,7 @@ +set(LOOPTRANSFORMS_SOURCES + LoopTransforms/ArrayBoundsCheckOpts.cpp + LoopTransforms/COWArrayOpt.cpp + LoopTransforms/LoopRotate.cpp + LoopTransforms/LoopUnroll.cpp + LoopTransforms/LICM.cpp + PARENT_SCOPE) diff --git a/lib/SILPasses/Loop/COWArrayOpt.cpp b/lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp similarity index 95% rename from lib/SILPasses/Loop/COWArrayOpt.cpp rename to lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp index fb0f92e6de648..6c358a5d6ee45 100644 --- a/lib/SILPasses/Loop/COWArrayOpt.cpp +++ b/lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp @@ -1,8 +1,8 @@ -//===------- COWArrayOpt.cpp - Optimize Copy-On-Write Array Checks --------===// +//===--- COWArrayOpt.cpp - Optimize Copy-On-Write Array Checks ------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,27 +11,26 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "cowarray-opts" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/CFG.h" #include "swift/SIL/Projection.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILCloner.h" -#include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/ColdBlockInfo.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/ColdBlockInfo.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" @@ -215,7 +214,7 @@ class StructUseCollector { continue; } - // An alloc_stack returns its address as the second value. + // An alloc_box returns its address as the second value. assert((PI.Aggregate == V || PI.Aggregate == SILValue(V, 1)) && "Expected unary element addr inst."); @@ -312,7 +311,7 @@ namespace { /// Optimize Copy-On-Write array checks based on high-level semantics. /// /// Performs an analysis on all Array users to ensure they do not interfere -/// with make_mutable hoisting. Ultimately, the only thing that can interefere +/// with make_mutable hoisting. Ultimately, the only thing that can interfere /// with make_mutable is a retain of the array. To ensure no retains occur /// within the loop, it is necessary to check that the array does not escape on /// any path reaching the loop, and that it is not directly retained within the @@ -449,7 +448,7 @@ bool COWArrayOpt::checkUniqueArrayContainer(SILValue ArrayContainer) { return false; } -/// Lazilly compute blocks that may reach the loop. +/// Lazily compute blocks that may reach the loop. SmallPtrSetImpl &COWArrayOpt::getReachingBlocks() { if (ReachingBlocks.empty()) { SmallVector Worklist; @@ -476,7 +475,6 @@ static bool isNonMutatingArraySemanticCall(SILInstruction *Inst) { switch (Call.getKind()) { case ArrayCallKind::kNone: - case ArrayCallKind::kArrayPropsIsNative: case ArrayCallKind::kArrayPropsIsNativeTypeChecked: case ArrayCallKind::kCheckSubscript: case ArrayCallKind::kCheckIndex: @@ -537,7 +535,7 @@ bool COWArrayOpt::isRetainReleasedBeforeMutate(SILInstruction *RetainInst, // release %ptr // array_operation(..., @owned %ptr) // - // This is not the case for an potentially aliased array because a release + // This is not the case for a potentially aliased array because a release // can cause a destructor to run. The destructor in turn can cause // arbitrary side effects. if (isa(II) || isa(II)) @@ -570,6 +568,10 @@ bool COWArrayOpt::isRetainReleasedBeforeMutate(SILInstruction *RetainInst, bool COWArrayOpt::checkSafeArrayAddressUses(UserList &AddressUsers) { for (auto *UseInst : AddressUsers) { + + if (isDebugInst(UseInst)) + continue; + if (auto *AI = dyn_cast(UseInst)) { if (ArraySemanticsCall(AI)) continue; @@ -804,7 +806,6 @@ static bool isArrayEltStore(StoreInst *SI) { /// Array.append for example can capture another array value. static bool mayChangeArrayValueToNonUniqueState(ArraySemanticsCall &Call) { switch (Call.getKind()) { - case ArrayCallKind::kArrayPropsIsNative: case ArrayCallKind::kArrayPropsIsNativeTypeChecked: case ArrayCallKind::kCheckSubscript: case ArrayCallKind::kCheckIndex: @@ -908,7 +909,7 @@ stripValueProjections(SILValue V, return V; } -/// Finds the preceeding check_subscript, make_mutable call or returns nil. +/// Finds the preceding check_subscript, make_mutable call or returns nil. /// /// If we found a make_mutable call this means that check_subscript was removed /// by the array bounds check elimination pass. @@ -934,24 +935,33 @@ findPreceedingCheckSubscriptOrMakeMutable(ApplyInst *GetElementAddr) { /// Matches the self parameter arguments, verifies that \p Self is called and /// stores the instructions in \p DepInsts in order. static bool -matchSelfParameterSetup(ApplyInst *Call, LoadInst *Self, +matchSelfParameterSetup(ArraySemanticsCall Call, LoadInst *Self, SmallVectorImpl &DepInsts) { + bool MayHaveBridgedObjectElementType = Call.mayHaveBridgedObjectElementType(); + // We only need the retain/release for the guaranteed parameter if the call + // could release self. This can only happen if the array is backed by an + // Objective-C array. If this is not the case we can safely hoist the call + // without the retain/releases. auto *RetainArray = dyn_cast_or_null(getInstBefore(Call)); - if (!RetainArray) + if (!RetainArray && MayHaveBridgedObjectElementType) return false; auto *ReleaseArray = dyn_cast_or_null(getInstAfter(Call)); - if (!ReleaseArray) + if (!ReleaseArray && MayHaveBridgedObjectElementType) return false; - if (ReleaseArray->getOperand() != RetainArray->getOperand()) + if (ReleaseArray && ReleaseArray->getOperand() != RetainArray->getOperand()) return false; - DepInsts.push_back(ReleaseArray); + if (ReleaseArray) + DepInsts.push_back(ReleaseArray); DepInsts.push_back(Call); - DepInsts.push_back(RetainArray); + if (RetainArray) + DepInsts.push_back(RetainArray); - auto ArrayLoad = stripValueProjections(RetainArray->getOperand(), DepInsts); - if (ArrayLoad != Self) - return false; + if (RetainArray) { + auto ArrayLoad = stripValueProjections(RetainArray->getOperand(), DepInsts); + if (ArrayLoad != Self) + return false; + } DepInsts.push_back(Self); return true; @@ -961,9 +971,9 @@ matchSelfParameterSetup(ApplyInst *Call, LoadInst *Self, /// /// Precondition: The client must make sure that it is valid to actually hoist /// the call. It must make sure that no write and no increment to the array -/// reference has happend such that hoisting is not valid. +/// reference has happened such that hoisting is not valid. /// -/// This helper only checks that the operands computing the array refererence +/// This helper only checks that the operands computing the array reference /// are also hoistable. struct HoistableMakeMutable { SILLoop *Loop; @@ -1000,8 +1010,10 @@ struct HoistableMakeMutable { /// Hoist this make_mutable call and depend instructions to the preheader. void hoist() { auto *Term = Loop->getLoopPreheader()->getTerminator(); - for (auto *It : swift::reversed(DepInsts)) - It->moveBefore(Term); + for (auto *It : swift::reversed(DepInsts)) { + if (It->getParent() != Term->getParent()) + It->moveBefore(Term); + } MakeMutable->moveBefore(Term); } @@ -1054,7 +1066,9 @@ struct HoistableMakeMutable { if (!UncheckedRefCast) return false; DepInsts.push_back(UncheckedRefCast); - auto *BaseLoad = dyn_cast(UncheckedRefCast->getOperand()); + + SILValue ArrayBuffer = stripValueProjections(UncheckedRefCast->getOperand(), DepInsts); + auto *BaseLoad = dyn_cast(ArrayBuffer); if (!BaseLoad || Loop->contains(BaseLoad->getOperand()->getParentBB())) return false; DepInsts.push_back(BaseLoad); @@ -1102,7 +1116,8 @@ struct HoistableMakeMutable { return true; if (Loop->contains(CheckSubscript.getIndex()->getParentBB()) || - Loop->contains(CheckSubscript.getArrayPropertyIsNative()->getParentBB())) + Loop->contains(CheckSubscript.getArrayPropertyIsNativeTypeChecked() + ->getParentBB())) return false; auto *CheckSubscriptArrayLoad = @@ -1153,7 +1168,7 @@ bool COWArrayOpt::hoistInLoopWithOnlyNonArrayValueMutatingOperations() { /// Make sure that no writes to an array value happens in the loop and that - /// no array values are retained without beeing released before hitting a + /// no array values are retained without being released before hitting a /// make_unique: /// /// * array semantic functions that don't change the uniqueness state to @@ -1327,12 +1342,12 @@ bool COWArrayOpt::hasLoopOnlyDestructorSafeArrayOperations() { if (Kind == ArrayCallKind::kArrayInit || Kind == ArrayCallKind::kArrayUninitialized) continue; - // All array types must be the same. This is a stronger guarantueed than + // All array types must be the same. This is a stronger guaranteed than // we actually need. The requirement is that we can't create another // reference to the array by performing an array operation: for example, - // storing or appending one array into an two-dimensional array. + // storing or appending one array into a two-dimensional array. // Checking - // that all types are the same make guarantees that this can not happen. + // that all types are the same make guarantees that this cannot happen. if (SameTy.isNull()) { SameTy = Sem.getSelf().getType().getSwiftRValueType()->getCanonicalType(); @@ -1379,7 +1394,7 @@ bool COWArrayOpt::hasLoopOnlyDestructorSafeArrayOperations() { if (MatchedReleases.count(&RVI->getOperandRef())) continue; - // Ignore fix_lifetime. It can not increment ref counts. + // Ignore fix_lifetime. It cannot increment ref counts. if (isa(Inst)) continue; @@ -1607,7 +1622,7 @@ static llvm::cl::opt ShouldSpecializeArrayProps("sil-array-props", llvm::cl::init(true)); /// Analysis whether it is safe to specialize this loop nest based on the -/// array.props function calls it constains. It is safe to hoist array.props +/// array.props function calls it contains. It is safe to hoist array.props /// calls if the array does not escape such that the array container could be /// overwritten in the hoisted region. /// This analysis also checks if we can clone the instructions in the loop nest. @@ -1649,7 +1664,7 @@ class ArrayPropertiesAnalysis { // Can't clone alloc_stack instructions whose dealloc_stack is outside // the loop. - if (!canCloneInst(&Inst)) + if (!Loop->canDuplicate(&Inst)) return false; ArraySemanticsCall ArrayPropsInst(&Inst, "array.props", true); @@ -1667,39 +1682,6 @@ class ArrayPropertiesAnalysis { private: - /// Checks whether we can build SSA form after cloning for values of this - /// instruction. - bool canCloneInst(SILInstruction *I) { - // The dealloc_stack of an alloc_stack must be in the loop, otherwise the - // dealloc_stack will be fed by a phi node of two alloc_stacks. - if (auto *Alloc = dyn_cast(I)) { - for (auto *UI : Alloc->getUses()) - if (auto *Dealloc = dyn_cast(UI->getUser())) - if (!Loop->contains(Dealloc->getParent())) - return false; - } - - // CodeGen can't build ssa for objc methods. - if (auto *Method = dyn_cast(I)) - if (Method->getMember().isForeign) - for (auto *UI : Method->getUses()) { - if (!Loop->contains(UI->getUser())) - return false; - } - - // We can't have a phi of two openexistential instructions of different UUID. - SILInstruction *OEI = dyn_cast(I); - if (OEI || - (OEI = dyn_cast(I)) || - (OEI = dyn_cast(I))) { - for (auto *UI : OEI->getUses()) - if (!Loop->contains(UI->getUser())) - return false; - } - - return true; - } - /// Strip the struct load and the address projection to the location /// holding the array struct. SILValue stripArrayStructLoad(SILValue V) { @@ -1742,6 +1724,9 @@ class ArrayPropertiesAnalysis { bool checkSafeArrayAddressUses(UserList &AddressUsers) { for (auto *UseInst : AddressUsers) { + if (isDebugInst(UseInst)) + continue; + if (isa(UseInst)) { // Handle destruction of a local array. continue; @@ -1784,7 +1769,7 @@ class ArrayPropertiesAnalysis { return false; } - // Otherwise, all of our users are sane. The array does not scape. + // Otherwise, all of our users are sane. The array does not escape. return true; } @@ -1800,7 +1785,7 @@ class ArrayPropertiesAnalysis { // We have a safe container if the array container is passed as a function // argument by-value or by inout reference. In either case there can't be an // alias of the container. Alternatively, we can have a local variable. We - // will check in checkSafeArrayAddressUses that all intialization stores to + // will check in checkSafeArrayAddressUses that all initialization stores to // this variable are safe (i.e the store dominates the loop etc). bool isSafeArrayContainer(SILValue V) { if (auto *Arg = dyn_cast(V.getDef())) { @@ -1848,10 +1833,10 @@ class ArrayPropertiesAnalysis { bool isClassElementTypeArray(SILValue Arr) { auto Ty = Arr.getType().getSwiftRValueType(); - auto Cannonical = Ty.getCanonicalTypeOrNull(); - if (Cannonical.isNull()) + auto Canonical = Ty.getCanonicalTypeOrNull(); + if (Canonical.isNull()) return false; - auto *Struct = Cannonical->getStructOrBoundGenericStruct(); + auto *Struct = Canonical->getStructOrBoundGenericStruct(); assert(Struct && "Array must be a struct !?"); if (Struct) { // No point in hoisting generic code. @@ -2166,8 +2151,7 @@ createFastNativeArraysCheck(SmallVectorImpl &ArrayProps, for (auto Call : ArrayProps) { auto Loc = (*Call).getLoc(); auto CallKind = Call.getKind(); - if (CallKind == ArrayCallKind::kArrayPropsIsNative || - CallKind == ArrayCallKind::kArrayPropsIsNativeTypeChecked) { + if (CallKind == ArrayCallKind::kArrayPropsIsNativeTypeChecked) { auto Val = createStructExtract(B, Loc, SILValue(Call, 0), 0); Result = createAnd(B, Loc, Result, Val); } @@ -2201,8 +2185,7 @@ static void collectArrayPropsCalls( /// This is true for array.props.isNative and false for /// array.props.needsElementTypeCheck. static void replaceArrayPropsCall(SILBuilder &B, ArraySemanticsCall C) { - assert(C.getKind() == ArrayCallKind::kArrayPropsIsNative || - C.getKind() == ArrayCallKind::kArrayPropsIsNativeTypeChecked); + assert(C.getKind() == ArrayCallKind::kArrayPropsIsNativeTypeChecked); ApplyInst *AI = C; SILType IntBoolTy = SILType::getBuiltinIntegerType(1, B.getASTContext()); @@ -2228,11 +2211,11 @@ void ArrayPropertiesSpecializer::specializeLoopNest() { auto *CheckBlock = splitBasicBlockAndBranch(B, HoistableLoopPreheader->getTerminator(), DomTree, nullptr); - // Get the exit blocks of the orignal loop. + // Get the exit blocks of the original loop. auto *Header = CheckBlock->getSingleSuccessor(); assert(Header); - // Our loop info is not really completedly valid anymore since the cloner does + // Our loop info is not really completely valid anymore since the cloner does // not update it. However, exit blocks of the original loop are still valid. SmallVector ExitBlocks; Lp->getExitBlocks(ExitBlocks); @@ -2303,7 +2286,7 @@ class SwiftArrayOptPass : public SILFunctionTransform { // Check whether we can hoist 'array.props' calls out of loops, collecting // the preheader we can hoist to. We only hoist out of loops if 'all' - // arrray.props call can be hoisted for a given loop nest. + // array.props call can be hoisted for a given loop nest. // We process the loop tree preorder (top-down) to hoist over the biggest // possible loop-nest. SmallVector HoistableLoopNests; diff --git a/lib/SILPasses/Loop/LICM.cpp b/lib/SILOptimizer/LoopTransforms/LICM.cpp similarity index 94% rename from lib/SILPasses/Loop/LICM.cpp rename to lib/SILOptimizer/LoopTransforms/LICM.cpp index 2c8dd7e745cce..ff62a21dcb770 100644 --- a/lib/SILPasses/Loop/LICM.cpp +++ b/lib/SILOptimizer/LoopTransforms/LICM.cpp @@ -1,8 +1,8 @@ -//===--------- LICM.cpp - Loop invariant code motion ------*- C++ -*-------===// +//===--- LICM.cpp - Loop invariant code motion ------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -13,17 +13,17 @@ #define DEBUG_TYPE "sil-licm" #include "swift/SIL/Dominance.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILAnalysis/SideEffectAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILInstruction.h" @@ -47,7 +47,7 @@ using WriteSet = SmallVector; /// alias with the memory addressed by \a LI. static bool mayWriteTo(AliasAnalysis *AA, WriteSet &MayWrites, LoadInst *LI) { for (auto *W : MayWrites) - if (AA->mayWriteToMemory(W, LI->getOperand().getDef())) { + if (AA->mayWriteToMemory(W, LI->getOperand())) { DEBUG(llvm::dbgs() << " mayWriteTo\n" << *W << " to " << *LI << "\n"); return true; } @@ -309,8 +309,8 @@ static bool hoistInstructions(SILLoop *Loop, DominanceInfo *DT, return Changed; } -static bool sinkFixLiftime(SILLoop *Loop, DominanceInfo *DomTree, - SILLoopInfo *LI) { +static bool sinkFixLifetime(SILLoop *Loop, DominanceInfo *DomTree, + SILLoopInfo *LI) { DEBUG(llvm::errs() << " Sink fix_lifetime attempt\n"); auto Preheader = Loop->getLoopPreheader(); if (!Preheader) @@ -371,7 +371,7 @@ static bool sinkFixLiftime(SILLoop *Loop, DominanceInfo *DomTree, } namespace { -/// \brief Summmary of may writes occuring in the loop tree rooted at \p +/// \brief Summary of may writes occurring in the loop tree rooted at \p /// Loop. This includes all writes of the sub loops and the loop itself. struct LoopNestSummary { SILLoop *Loop; @@ -520,7 +520,7 @@ void LoopTreeOptimization::optimizeLoop(SILLoop *CurrentLoop, Changed |= sinkCondFail(CurrentLoop); Changed |= hoistInstructions(CurrentLoop, DomTree, SafeReads, RunsOnHighLevelSil); - Changed |= sinkFixLiftime(CurrentLoop, DomTree, LoopInfo); + Changed |= sinkFixLifetime(CurrentLoop, DomTree, LoopInfo); } namespace { diff --git a/lib/SILPasses/Loop/LoopRotate.cpp b/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp similarity index 95% rename from lib/SILPasses/Loop/LoopRotate.cpp rename to lib/SILOptimizer/LoopTransforms/LoopRotate.cpp index a7d7038eb1213..521bdc2c5e6eb 100644 --- a/lib/SILPasses/Loop/LoopRotate.cpp +++ b/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp @@ -1,8 +1,8 @@ -//===--------- LoopSimplify.cpp - Loop structure simplify -*- C++ -*-------===// +//===--- LoopRotate.cpp - Loop structure simplify ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -13,14 +13,14 @@ #define DEBUG_TYPE "sil-looprotate" #include "swift/SIL/Dominance.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" -#include "swift/SILPasses/Utils/LoopUtils.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" +#include "swift/SILOptimizer/Utils/LoopUtils.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILInstruction.h" @@ -51,7 +51,7 @@ static bool hasLoopInvariantOperands(SILInstruction *I, SILLoop *L, }); } -/// We can not duplicate blocks with AllocStack instructions (they need to be +/// We cannot duplicate blocks with AllocStack instructions (they need to be /// FIFO). Other instructions can be moved to the preheader. static bool canDuplicateOrMoveToPreheader(SILLoop *L, SILBasicBlock *Preheader, @@ -181,7 +181,7 @@ rewriteNewLoopEntryCheckBlock(SILBasicBlock *Header, SmallVector InsertedPHIs; SILSSAUpdater Updater(&InsertedPHIs); - // Fix PHIs (incomming arguments). + // Fix PHIs (incoming arguments). for (auto *Inst: Header->getBBArgs()) updateSSAForUseOfInst(Updater, InsertedPHIs, ValueMap, Header, EntryCheckBlock, Inst); @@ -277,7 +277,7 @@ bool swift::rotateLoop(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI, if (!Header) return false; - // We need a preheader - this is also a cannonicalization for follow-up + // We need a preheader - this is also a canonicalization for follow-up // passes. auto *Preheader = L->getLoopPreheader(); if (!Preheader) { @@ -298,7 +298,7 @@ bool swift::rotateLoop(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI, // The header needs to exit the loop. if (!L->isLoopExiting(Header)) { - DEBUG(llvm::dbgs() << *L << " not a exiting header\n"); + DEBUG(llvm::dbgs() << *L << " not an exiting header\n"); DEBUG(L->getHeader()->getParent()->dump()); return false; } diff --git a/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp b/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp new file mode 100644 index 0000000000000..9b6dc56e4f759 --- /dev/null +++ b/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp @@ -0,0 +1,467 @@ +//===--- LoopUnroll.cpp - Loop unrolling ------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-loopunroll" + +#include "llvm/ADT/DepthFirstIterator.h" + +#include "swift/SIL/PatternMatch.h" +#include "swift/SIL/SILCloner.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/SILInliner.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" + +using namespace swift; +using namespace swift::PatternMatch; + +using llvm::DenseMap; +using llvm::MapVector; + +static const uint64_t SILLoopUnrollThreshold = 250; + +namespace { + +/// Clone the basic blocks in a loop. +class LoopCloner : public SILCloner { + SILLoop *Loop; + + friend class SILVisitor; + friend class SILCloner; + +public: + LoopCloner(SILLoop *Loop) + : SILCloner(*Loop->getHeader()->getParent()), Loop(Loop) {} + + /// Clone the basic blocks in the loop. + void cloneLoop(); + + /// Get a map from basic blocks or the original loop to the cloned loop. + MapVector &getBBMap() { return BBMap; } + + DenseMap &getValueMap() { return ValueMap; } + DenseMap &getInstMap() { + return InstructionMap; + } + +protected: + SILValue remapValue(SILValue V) { + if (auto *BB = V.getDef()->getParentBB()) { + if (!Loop->contains(BB)) + return V; + } + return SILCloner::remapValue(V); + } + void postProcess(SILInstruction *Orig, SILInstruction *Cloned) { + SILCloner::postProcess(Orig, Cloned); + } +}; + +} // End anonymous namespace. + +void LoopCloner::cloneLoop() { + auto *Header = Loop->getHeader(); + auto *CurFun = Loop->getHeader()->getParent(); + auto &Mod = CurFun->getModule(); + + SmallVector ExitBlocks; + Loop->getExitBlocks(ExitBlocks); + for (auto *ExitBB : ExitBlocks) + BBMap[ExitBB] = ExitBB; + + auto *ClonedHeader = new (Mod) SILBasicBlock(CurFun); + BBMap[Header] = ClonedHeader; + + // Clone the arguments. + for (auto *Arg : Header->getBBArgs()) { + SILValue MappedArg = + new (Mod) SILArgument(ClonedHeader, getOpType(Arg->getType())); + ValueMap.insert(std::make_pair(Arg, MappedArg)); + } + + // Clone the instructions in this basic block and recursively clone + // successor blocks. + getBuilder().setInsertionPoint(ClonedHeader); + visitSILBasicBlock(Header); + // Fix-up terminators. + for (auto BBPair : BBMap) + if (BBPair.first != BBPair.second) { + getBuilder().setInsertionPoint(BBPair.second); + visit(BBPair.first->getTerminator()); + } +} + +/// Determine the number of iterations the loop is at most executed. The loop +/// might contain early exits so this is the maximum if no early exits are +/// taken. +static Optional getMaxLoopTripCount(SILLoop *Loop, + SILBasicBlock *Preheader, + SILBasicBlock *Header, + SILBasicBlock *Latch) { + + // Skip a split backedge. + SILBasicBlock *OrigLatch = Latch; + if (!Loop->isLoopExiting(Latch) && !(Latch = Latch->getSinglePredecessor())) + return None; + if (!Loop->isLoopExiting(Latch)) + return None; + + // Get the loop exit condition. + auto *CondBr = dyn_cast(Latch->getTerminator()); + if (!CondBr) + return None; + + // Match an add 1 recurrence. + SILArgument *RecArg; + IntegerLiteralInst *End; + SILValue RecNext; + + if (!match(CondBr->getCondition(), + m_BuiltinInst(BuiltinValueKind::ICMP_EQ, m_SILValue(RecNext), + m_IntegerLiteralInst(End)))) + return None; + if (!match(RecNext, + m_TupleExtractInst(m_ApplyInst(BuiltinValueKind::SAddOver, + m_SILArgument(RecArg), m_One()), + 0))) + return None; + + if (RecArg->getParent() != Header) + return None; + + auto *Start = dyn_cast_or_null( + RecArg->getIncomingValue(Preheader).getDef()); + if (!Start) + return None; + + if (RecNext != RecArg->getIncomingValue(OrigLatch)) + return None; + + auto StartVal = Start->getValue(); + auto EndVal = End->getValue(); + if (StartVal.sgt(EndVal)) + return None; + + auto Dist = EndVal - StartVal; + if (Dist.getBitWidth() > 64) + return None; + + if (Dist == 0) + return None; + + return Dist.getZExtValue(); +} + +/// Check whether we can duplicate the instructions in the loop and use a +/// heuristic that looks at the trip count and the cost of the instructions in +/// the loop to determine whether we should unroll this loop. +static bool canAndShouldUnrollLoop(SILLoop *Loop, uint64_t TripCount) { + assert(Loop->getSubLoops().empty() && "Expect innermost loops"); + if (TripCount > 32) + return false; + + // We can unroll a loop if we can duplicate the instructions it holds. + uint64_t Cost = 0; + for (auto *BB : Loop->getBlocks()) { + for (auto &Inst : *BB) { + if (!Loop->canDuplicate(&Inst)) + return false; + if (instructionInlineCost(Inst) != InlineCost::Free) + ++Cost; + if (Cost * TripCount > SILLoopUnrollThreshold) + return false; + } + } + return true; +} + +/// Redirect the terminator of the current loop iteration's latch to the next +/// iterations header or if this is the last iteration remove the backedge to +/// the header. +static void redirectTerminator(SILBasicBlock *Latch, unsigned CurLoopIter, + unsigned LastLoopIter, SILBasicBlock *OrigHeader, + SILBasicBlock *NextIterationsHeader) { + + auto *CurrentTerminator = Latch->getTerminator(); + + // We can either have a split backedge as our latch terminator. + // HeaderBlock: + // ... + // cond_br %cond, ExitBlock, BackedgeBlock + // + // BackedgeBlock: + // br HeaderBlock: + // + // Or a conditional branch back to the header. + // HeaderBlock: + // ... + // cond_br %cond, ExitBlock, HeaderBlock + // + // Redirect the HeaderBlock target to the unrolled successor. In the + // unrolled block of the last iteration unconditionally jump to the + // ExitBlock instead. + + // Handle the split backedge case. + if (auto *Br = dyn_cast(CurrentTerminator)) { + // On the last iteration change the conditional exit to an unconditional + // one. + if (CurLoopIter == LastLoopIter) { + auto *CondBr = + cast(Latch->getSinglePredecessor()->getTerminator()); + if (CondBr->getTrueBB() != Latch) + SILBuilder(CondBr).createBranch(CondBr->getLoc(), CondBr->getTrueBB(), + CondBr->getTrueArgs()); + else + SILBuilder(CondBr).createBranch(CondBr->getLoc(), CondBr->getFalseBB(), + CondBr->getFalseArgs()); + CondBr->eraseFromParent(); + return; + } + + // Otherwise, branch to the next iteration's header. + SILBuilder(Br).createBranch(Br->getLoc(), NextIterationsHeader, + Br->getArgs()); + Br->eraseFromParent(); + return; + } + + // Otherwise, we have a conditional branch to the header. + auto *CondBr = cast(CurrentTerminator); + // On the last iteration change the conditional exit to an unconditional + // one. + if (CurLoopIter == LastLoopIter) { + if (CondBr->getTrueBB() != OrigHeader) + SILBuilder(CondBr).createBranch(CondBr->getLoc(), CondBr->getTrueBB(), + CondBr->getTrueArgs()); + else + SILBuilder(CondBr).createBranch(CondBr->getLoc(), CondBr->getFalseBB(), + CondBr->getFalseArgs()); + CondBr->eraseFromParent(); + return; + } + + // Otherwise, branch to the next iteration's header. + if (CondBr->getTrueBB() == OrigHeader) { + SILBuilder(CondBr).createCondBranch( + CondBr->getLoc(), CondBr->getCondition(), NextIterationsHeader, + CondBr->getTrueArgs(), CondBr->getFalseBB(), CondBr->getFalseArgs()); + } else { + SILBuilder(CondBr).createCondBranch( + CondBr->getLoc(), CondBr->getCondition(), CondBr->getTrueBB(), + CondBr->getTrueArgs(), NextIterationsHeader, CondBr->getFalseArgs()); + } + CondBr->eraseFromParent(); +} + +/// Collect all the loop live out values in the map that maps original live out +/// value to live out value in the cloned loop. +static void collectLoopLiveOutValues( + DenseMap> &LoopLiveOutValues, + SILLoop *Loop, DenseMap &ClonedValues, + DenseMap &ClonedInstructions) { + for (auto *Block : Loop->getBlocks()) { + // Look at block arguments. + for (auto *Arg : Block->getBBArgs()) { + for (auto *Op : Arg->getUses()) { + // Is this use outside the loop? + if (!Loop->contains(Op->getUser())) { + auto ArgumentValue = SILValue(Arg); + assert(ClonedValues.count(ArgumentValue) && "Unmapped Argument!"); + + if (!LoopLiveOutValues.count(ArgumentValue)) + LoopLiveOutValues[ArgumentValue].push_back( + ClonedValues[ArgumentValue]); + } + } + } + // And the instructions. + for (auto &Inst : *Block) { + for (auto *Op : Inst.getUses()) { + // Is this use outside the loop. + if (!Loop->contains(Op->getUser())) { + auto UsedValue = Op->get(); + assert(UsedValue.getDef() == &Inst && "Instructions must match"); + assert(ClonedInstructions.count(&Inst) && "Unmapped instruction!"); + + if (!LoopLiveOutValues.count(UsedValue)) + LoopLiveOutValues[UsedValue].push_back(SILValue( + ClonedInstructions[&Inst], UsedValue.getResultNumber())); + } + } + } + } +} + +static void +updateSSA(SILLoop *Loop, + DenseMap> &LoopLiveOutValues) { + SILSSAUpdater SSAUp; + for (auto &MapEntry : LoopLiveOutValues) { + // Collect out of loop uses of this value. + auto OrigValue = MapEntry.first; + SmallVector UseList; + for (auto Use : OrigValue.getUses()) + if (!Loop->contains(Use->getUser()->getParent())) + UseList.push_back(UseWrapper(Use)); + // Update SSA of use with the available values. + SSAUp.Initialize(OrigValue.getType()); + SSAUp.AddAvailableValue(OrigValue->getParentBB(), OrigValue); + for (auto NewValue : MapEntry.second) + SSAUp.AddAvailableValue(NewValue->getParentBB(), NewValue); + for (auto U : UseList) { + Operand *Use = U; + SSAUp.RewriteUse(*Use); + } + } +} + +/// Try to fully unroll the loop if we can determine the trip count and the trip +/// count lis below a threshold. +static bool tryToUnrollLoop(SILLoop *Loop) { + assert(Loop->getSubLoops().empty() && "Expecting innermost loops"); + + auto *Preheader = Loop->getLoopPreheader(); + if (!Preheader) + return false; + + auto *Latch = Loop->getLoopLatch(); + if (!Latch) + return false; + + auto *Header = Loop->getHeader(); + + Optional MaxTripCount = + getMaxLoopTripCount(Loop, Preheader, Header, Latch); + if (!MaxTripCount) + return false; + + if (!canAndShouldUnrollLoop(Loop, MaxTripCount.getValue())) + return false; + + // TODO: We need to split edges from non-condbr exits for the SSA updater. For + // now just don't handle loops containing such exits. + SmallVector ExitingBlocks; + Loop->getExitingBlocks(ExitingBlocks); + for (auto &Exit : ExitingBlocks) + if (!isa(Exit->getTerminator())) + return false; + + DEBUG(llvm::dbgs() << "Unrolling loop in " << Header->getParent()->getName() + << " " << *Loop << "\n"); + + SmallVector Headers; + Headers.push_back(Header); + + SmallVector Latches; + Latches.push_back(Latch); + + DenseMap> LoopLiveOutValues; + + // Copy the body MaxTripCount-1 times. + for (uint64_t Cnt = 1; Cnt < *MaxTripCount; ++Cnt) { + // Clone the blocks in the loop. + LoopCloner Cloner(Loop); + Cloner.cloneLoop(); + Headers.push_back(Cloner.getBBMap()[Header]); + Latches.push_back(Cloner.getBBMap()[Latch]); + + // Collect values defined in the loop but used outside. On the first + // iteration we populate the map from original loop to cloned loop. On + // subsequent iterations we only need to update this map with the values + // from the new iteration's clone. + if (Cnt == 1) + collectLoopLiveOutValues(LoopLiveOutValues, Loop, Cloner.getValueMap(), + Cloner.getInstMap()); + else { + for (auto &MapEntry : LoopLiveOutValues) { + // If this is an argument look up the value in the value map. + SILValue MappedValue; + if (isa(MapEntry.first)) + MappedValue = Cloner.getValueMap()[MapEntry.first]; + // Otherwise, consult the instruction map. + else + MappedValue = SILValue( + Cloner + .getInstMap()[cast(MapEntry.first.getDef())], + MapEntry.first.getResultNumber()); + MapEntry.second.push_back(MappedValue); + assert(MapEntry.second.size() == Cnt); + } + } + } + + // Thread the loop clones by redirecting the loop latches to the successor + // iteration's header. + for (unsigned Iteration = 0, End = Latches.size(); Iteration != End; + ++Iteration) { + auto *CurrentLatch = Latches[Iteration]; + auto LastIteration = End - 1; + auto *OriginalHeader = Headers[0]; + auto *NextIterationsHeader = + Iteration == LastIteration ? nullptr : Headers[Iteration + 1]; + + redirectTerminator(CurrentLatch, Iteration, LastIteration, OriginalHeader, + NextIterationsHeader); + } + + // Fixup SSA form for loop values used outside the loop. + updateSSA(Loop, LoopLiveOutValues); + return true; +} + +// ============================================================================= +// Driver +// ============================================================================= + +namespace { + +class LoopUnrolling : public SILFunctionTransform { + + StringRef getName() override { return "SIL Loop Unrolling"; } + + void run() override { + bool Changed = false; + + auto *Fun = getFunction(); + SILLoopInfo *LoopInfo = PM->getAnalysis()->get(Fun); + + // Collect innermost loops. + SmallVector InnermostLoops; + for (auto *Loop : *LoopInfo) { + SmallVector Worklist; + Worklist.push_back(Loop); + + for (unsigned i = 0; i < Worklist.size(); ++i) { + auto *L = Worklist[i]; + for (auto *SubLoop : *L) + Worklist.push_back(SubLoop); + if (L->getSubLoops().empty()) + InnermostLoops.push_back(L); + } + } + + // Try to unroll innermost loops. + for (auto *Loop : InnermostLoops) + Changed |= tryToUnrollLoop(Loop); + + if (Changed) { + invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody); + } + } +}; + +} // end anonymous namespace. + +SILTransform *swift::createLoopUnroll() { + return new LoopUnrolling(); +} diff --git a/lib/SILOptimizer/Mandatory/CMakeLists.txt b/lib/SILOptimizer/Mandatory/CMakeLists.txt new file mode 100644 index 0000000000000..25f6ba12923af --- /dev/null +++ b/lib/SILOptimizer/Mandatory/CMakeLists.txt @@ -0,0 +1,10 @@ +set(MANDATORY_SOURCES + Mandatory/DefiniteInitialization.cpp + Mandatory/MandatoryInlining.cpp + Mandatory/DIMemoryUseCollector.cpp + Mandatory/DataflowDiagnostics.cpp + Mandatory/DiagnoseUnreachable.cpp + Mandatory/PredictableMemOpt.cpp + Mandatory/ConstantPropagation.cpp + Mandatory/InOutDeshadowing.cpp + PARENT_SCOPE) diff --git a/lib/SILPasses/EarlySIL/ConstantPropagation.cpp b/lib/SILOptimizer/Mandatory/ConstantPropagation.cpp similarity index 97% rename from lib/SILPasses/EarlySIL/ConstantPropagation.cpp rename to lib/SILOptimizer/Mandatory/ConstantPropagation.cpp index 55187a04916ce..a24edb44d59a4 100644 --- a/lib/SILPasses/EarlySIL/ConstantPropagation.cpp +++ b/lib/SILOptimizer/Mandatory/ConstantPropagation.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,13 +11,13 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "constant-propagation" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/AST/DiagnosticsSIL.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILInstruction.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/ConstantFolding.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/ConstantFolding.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Debug.h" @@ -264,7 +264,7 @@ constantFoldAndCheckDivision(BuiltinInst *BI, BuiltinValueKind ID, return nullptr; } - // Add the literal instruction to represnet the result of the division. + // Add the literal instruction to represent the result of the division. SILBuilderWithScope B(BI); return B.createIntegerLiteral(BI->getLoc(), BI->getType(), ResVal); } @@ -366,7 +366,7 @@ static SILInstruction *constantFoldBinary(BuiltinInst *BI, } } -static std::pair getTypeSigndness(const BuiltinInfo &Builtin) { +static std::pair getTypeSignedness(const BuiltinInfo &Builtin) { bool SrcTySigned = (Builtin.ID == BuiltinValueKind::SToSCheckedTrunc || Builtin.ID == BuiltinValueKind::SToUCheckedTrunc || @@ -481,7 +481,7 @@ constantFoldAndCheckIntegerConversions(BuiltinInst *BI, // 2048. Is there a better way to identify conversions from literals? bool Literal = (SrcBitWidth == 2048); - // FIXME: This will prevent hard error in cases the error is comming + // FIXME: This will prevent hard error in cases the error is coming // from ObjC interoperability code. Currently, we treat NSUInteger as // Int. if (Loc.getSourceLoc().isInvalid()) { @@ -503,7 +503,7 @@ constantFoldAndCheckIntegerConversions(BuiltinInst *BI, // Otherwise report the overflow error. if (Literal) { bool SrcTySigned, DstTySigned; - std::tie(SrcTySigned, DstTySigned) = getTypeSigndness(Builtin); + std::tie(SrcTySigned, DstTySigned) = getTypeSignedness(Builtin); SmallString<10> SrcAsString; SrcVal.toString(SrcAsString, /*radix*/10, SrcTySigned); @@ -521,7 +521,7 @@ constantFoldAndCheckIntegerConversions(BuiltinInst *BI, // Otherwise, print the Builtin Types. } else { bool SrcTySigned, DstTySigned; - std::tie(SrcTySigned, DstTySigned) = getTypeSigndness(Builtin); + std::tie(SrcTySigned, DstTySigned) = getTypeSignedness(Builtin); diagnose(M.getASTContext(), Loc.getSourceLoc(), diag::integer_literal_overflow_builtin_types, DstTySigned, DstTy, SrcAsString); @@ -540,10 +540,10 @@ constantFoldAndCheckIntegerConversions(BuiltinInst *BI, // Otherwise, print the Builtin Types. } else { - // Since builtin types are sign-agnostic, print the signdness + // Since builtin types are sign-agnostic, print the signedness // separately. bool SrcTySigned, DstTySigned; - std::tie(SrcTySigned, DstTySigned) = getTypeSigndness(Builtin); + std::tie(SrcTySigned, DstTySigned) = getTypeSignedness(Builtin); diagnose(M.getASTContext(), Loc.getSourceLoc(), diag::integer_conversion_overflow_builtin_types, SrcTySigned, SrcTy, DstTySigned, DstTy); @@ -673,10 +673,10 @@ case BuiltinValueKind::id: return nullptr; APFloat TruncVal = V->getValue(); Type DestTy = Builtin.Types[1]; - bool loosesInfo; + bool losesInfo; APFloat::opStatus ConversionStatus = TruncVal.convert( DestTy->castTo()->getAPFloatSemantics(), - APFloat::rmNearestTiesToEven, &loosesInfo); + APFloat::rmNearestTiesToEven, &losesInfo); SILLocation Loc = BI->getLoc(); // Check if conversion was successful. @@ -746,7 +746,7 @@ static bool isApplyOfBuiltin(SILInstruction &I, BuiltinValueKind kind) { static bool isApplyOfStringConcat(SILInstruction &I) { if (auto *AI = dyn_cast(&I)) if (auto *Fn = AI->getCalleeFunction()) - if (Fn->hasSemanticsString("string.concat")) + if (Fn->hasSemanticsAttr("string.concat")) return true; return false; } @@ -1001,7 +1001,7 @@ processFunction(SILFunction &F, bool EnableDiagnostics, if (ResultsInError.hasValue() && ResultsInError.getValue()) ErrorSet.insert(User); - // We failed to constant propogate... continue... + // We failed to constant propagate... continue... if (!C) continue; diff --git a/lib/SILPasses/EarlySIL/DIMemoryUseCollector.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp similarity index 98% rename from lib/SILPasses/EarlySIL/DIMemoryUseCollector.cpp rename to lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp index 666e81f37dcf7..137f9fc2231e0 100644 --- a/lib/SILPasses/EarlySIL/DIMemoryUseCollector.cpp +++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -647,6 +647,21 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) { continue; } + if (auto SUI = dyn_cast(User)) + if (UI->getOperandNumber() == 1) { + DIUseKind Kind; + if (InStructSubElement) + Kind = DIUseKind::PartialStore; + else if (SUI->isInitializationOfDest()) + Kind = DIUseKind::Initialization; + else if (isDefiniteInitFinished) + Kind = DIUseKind::Assign; + else + Kind = DIUseKind::InitOrAssign; + Uses.push_back(DIMemoryUse(User, Kind, BaseEltNo, 1)); + continue; + } + if (auto *CAI = dyn_cast(User)) { // If this is a copy of a tuple, we should scalarize it so that we don't // have an access that crosses elements. @@ -710,7 +725,8 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) { continue; // If this is an @inout parameter, it is like both a load and store. - case ParameterConvention::Indirect_Inout: { + case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: { // If we're in the initializer for a struct, and this is a call to a // mutating method, we model that as an escape of self. If an // individual sub-member is passed as inout, then we model that as an @@ -749,22 +765,16 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) { continue; } - // init_existential_addr is modeled as an initialization store, where the - // uses are treated as subelement accesses. + // init_existential_addr is modeled as an initialization store. if (isa(User)) { assert(!InStructSubElement && "init_existential_addr should not apply to struct subelements"); Uses.push_back(DIMemoryUse(User, DIUseKind::Initialization, BaseEltNo, 1)); - - // Set the "InEnumSubElement" flag (so we don't consider tuple indexes to - // index across elements) and recursively process the uses. - llvm::SaveAndRestore X(InEnumSubElement, true); - collectUses(SILValue(User, 0), BaseEltNo); continue; } - // inject_enum_addr is treated as a store unconditionally. + // inject_enum_addr is modeled as an initialization store. if (isa(User)) { assert(!InStructSubElement && "inject_enum_addr the subelement of a struct unless in a ctor"); @@ -787,6 +797,10 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) { continue; } + if (isa(User)) { + continue; + } + // Otherwise, the use is something complicated, it escapes. addElementUses(BaseEltNo, PointeeType, User, DIUseKind::Escape); } @@ -1370,6 +1384,9 @@ void ElementUseCollector::collectDelegatingClassInitSelfUses() { // The MUI must be used on an alloc_box or alloc_stack instruction. Chase // down the box value to see if there are any releases. auto *AI = cast(MUI->getOperand()); + if (isa(AI)) + return; + for (auto UI : SILValue(AI, 0).getUses()) { SILInstruction *User = UI->getUser(); @@ -1377,12 +1394,6 @@ void ElementUseCollector::collectDelegatingClassInitSelfUses() { Releases.push_back(User); continue; } - - // Ignore the deallocation of the stack box. Its contents will be - // uninitialized by the point it executes. - if (isa(User)) - continue; - assert(0 && "Unknown use of box"); } } diff --git a/lib/SILPasses/EarlySIL/DIMemoryUseCollector.h b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h similarity index 95% rename from lib/SILPasses/EarlySIL/DIMemoryUseCollector.h rename to lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h index f7c1e346f754e..c74a69555765f 100644 --- a/lib/SILPasses/EarlySIL/DIMemoryUseCollector.h +++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,8 +17,8 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_DI_MEMORY_USE_COLLECTOR_H -#define SWIFT_SILPASSES_DI_MEMORY_USE_COLLECTOR_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_DI_MEMORY_USE_COLLECTOR_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_DI_MEMORY_USE_COLLECTOR_H #include "swift/Basic/LLVM.h" #include "llvm/ADT/APInt.h" @@ -77,13 +77,15 @@ class DIMemoryObjectInfo { } SILValue getAddress() const { - if (isa(MemoryInst)) + if (isa(MemoryInst) || + isa(MemoryInst)) return SILValue(MemoryInst, 0); return SILValue(MemoryInst, 1); } SILValue getContainer() const { - if (isa(MemoryInst)) + if (isa(MemoryInst) || + isa(MemoryInst)) return SILValue(); return SILValue(MemoryInst, 0); } @@ -110,7 +112,7 @@ class DIMemoryObjectInfo { return false; } - /// True if the memory object is the 'self' argument of a enum initializer. + /// True if the memory object is the 'self' argument of an enum initializer. bool isEnumInitSelf() const { if (auto *MUI = dyn_cast(MemoryInst)) if (MUI->isRootSelf()) diff --git a/lib/SILPasses/EarlySIL/DataflowDiagnostics.cpp b/lib/SILOptimizer/Mandatory/DataflowDiagnostics.cpp similarity index 95% rename from lib/SILPasses/EarlySIL/DataflowDiagnostics.cpp rename to lib/SILOptimizer/Mandatory/DataflowDiagnostics.cpp index 2d8227338cf5a..8665cad60357b 100644 --- a/lib/SILPasses/EarlySIL/DataflowDiagnostics.cpp +++ b/lib/SILOptimizer/Mandatory/DataflowDiagnostics.cpp @@ -1,8 +1,8 @@ -//===-- DataflowDiagnostics.cpp - Emits diagnostics based on SIL analysis -===// +//===--- DataflowDiagnostics.cpp - Emits diagnostics based on SIL analysis ===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/AST/ASTContext.h" #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticsSIL.h" diff --git a/lib/SILPasses/EarlySIL/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp similarity index 98% rename from lib/SILPasses/EarlySIL/DefiniteInitialization.cpp rename to lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp index d67143af19118..7f145c37884eb 100644 --- a/lib/SILPasses/EarlySIL/DefiniteInitialization.cpp +++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,15 +11,15 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "definite-init" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "DIMemoryUseCollector.h" #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticsSIL.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/Basic/Fallthrough.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" @@ -60,7 +60,7 @@ static void LowerAssignInstruction(SILBuilder &B, AssignInst *Inst, // Otherwise, we need to replace the assignment with the full // load/store/release dance. Note that the new value is already // considered to be retained (by the semantics of the storage type), - // and we're transfering that ownership count into the destination. + // and we're transferring that ownership count into the destination. // This is basically TypeLowering::emitStoreOfCopy, except that if we have // a known incoming value, we can avoid the load. @@ -629,7 +629,7 @@ bool LifetimeChecker::shouldEmitError(SILInstruction *Inst) { /// initializer. void LifetimeChecker::noteUninitializedMembers(const DIMemoryUse &Use) { assert(TheMemory.isAnyInitSelf() && !TheMemory.isDelegatingInit() && - "Not an designated initializer"); + "Not a designated initializer"); // Root protocol initializers (ones that reassign to self, not delegating to // self.init) have no members to initialize and self itself has already been @@ -1089,10 +1089,16 @@ void LifetimeChecker::handleEscapeUse(const DIMemoryUse &Use) { } Diag DiagMessage; - if (isa(Inst)) - DiagMessage = diag::global_variable_function_use_uninit; - else - DiagMessage = diag::variable_escape_before_initialized; + if (isa(Inst)) { + if (Inst->getLoc().isASTNode()) + DiagMessage = diag::variable_closure_use_uninit; + else + DiagMessage = diag::variable_function_use_uninit; + } else if (isa(Inst)) { + DiagMessage = diag::variable_used_before_initialized; + } else { + DiagMessage = diag::variable_closure_use_uninit; + } diagnoseInitError(Use, DiagMessage); } @@ -1109,7 +1115,7 @@ void LifetimeChecker::handleEscapeUse(const DIMemoryUse &Use) { /// %6 = enum $Optional, #Optional.None!enumelt // user: %7 /// br bb2(%6 : $Optional) // id: %7 /// bb2(%8 : $Optional): // Preds: bb0 bb1 -/// dealloc_stack %1#0 : $*@local_storage Enum // id: %9 +/// dealloc_stack %1 : $*Enum // id: %9 /// return %8 : $Optional // id: %10 /// static bool isFailableInitReturnUseOfEnum(EnumInst *EI) { @@ -1220,7 +1226,7 @@ bool LifetimeChecker::diagnoseMethodCall(const DIMemoryUse &Use, } } - // If this is an apply instruction and we're in an class initializer, we're + // If this is an apply instruction and we're in a class initializer, we're // calling a method on self. if (isa(Inst) && TheMemory.isClassInitSelf()) { // If this is a method application, produce a nice, specific, error. @@ -1417,8 +1423,13 @@ void LifetimeChecker::handleLoadUseFailure(const DIMemoryUse &Use, noteUninitializedMembers(Use); return; } - - diagnoseInitError(Use, diag::variable_used_before_initialized); + + // If this is a load into a promoted closure capture, diagnose properly as + // a capture. + if (isa(Inst) && Inst->getLoc().isASTNode()) + diagnoseInitError(Use, diag::variable_closure_use_uninit); + else + diagnoseInitError(Use, diag::variable_used_before_initialized); } /// handleSuperInitUse - When processing a 'self' argument on a class, this is @@ -1544,6 +1555,14 @@ void LifetimeChecker::updateInstructionForInitState(DIMemoryUse &InstInfo) { SW->setIsInitializationOfDest(InitKind); return; } + + if (auto *SU = dyn_cast(Inst)) { + assert(!SU->isInitializationOfDest() && + "should not modify store_unowned that already knows it is an init"); + + SU->setIsInitializationOfDest(InitKind); + return; + } // If this is an assign, rewrite it based on whether it is an initialization // or not. @@ -1820,13 +1839,13 @@ SILValue LifetimeChecker::handleConditionalInitAssign() { auto *Term = BB.getTerminator(); if (isa(Term) || isa(Term)) { B.setInsertionPoint(Term); - B.createDeallocStack(Loc, ControlVariableBox->getContainerResult()); + B.createDeallocStack(Loc, ControlVariableBox); } } // Before the memory allocation, store zero in the control variable. B.setInsertionPoint(TheMemory.MemoryInst->getNextNode()); - SILValue ControlVariableAddr = SILValue(ControlVariableBox, 1); + SILValue ControlVariableAddr = ControlVariableBox; auto Zero = B.createIntegerLiteral(Loc, IVType, 0); B.createStore(Loc, Zero, ControlVariableAddr); @@ -2142,7 +2161,7 @@ computePredsLiveOut(SILBasicBlock *BB) { DEBUG(llvm::dbgs() << " Get liveness for block " << BB->getDebugID() << "\n"); // Collect blocks for which we have to calculate the out-availability. - // These are the pathes from blocks with known out-availability to the BB. + // These are the paths from blocks with known out-availability to the BB. WorkListType WorkList; for (auto Pred : BB->getPreds()) { putIntoWorkList(Pred, WorkList); @@ -2270,7 +2289,7 @@ getLivenessAtInst(SILInstruction *Inst, unsigned FirstElt, unsigned NumElts) { return Result; } - // Check locally to see if any elements are satified within the block, and + // Check locally to see if any elements are satisfied within the block, and // keep track of which ones are still needed in the NeededElements set. llvm::SmallBitVector NeededElements(TheMemory.NumElements); NeededElements.set(FirstElt, FirstElt+NumElts); diff --git a/lib/SILPasses/EarlySIL/DiagnoseUnreachable.cpp b/lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp similarity index 96% rename from lib/SILPasses/EarlySIL/DiagnoseUnreachable.cpp rename to lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp index 84dd072f3c37c..6f26549718007 100644 --- a/lib/SILPasses/EarlySIL/DiagnoseUnreachable.cpp +++ b/lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,13 +11,13 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "diagnose-unreachable" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/AST/DiagnosticsSIL.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILUndef.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" @@ -60,13 +60,13 @@ struct UnreachableInfo { /// removal stage of the path. /// /// To report unreachable user code, we detect the blocks that contain user -/// code and are not reachable (along any of the preceeding paths). Note that we +/// code and are not reachable (along any of the preceding paths). Note that we /// only want to report the first statement on the unreachable path. Keeping /// the info about which branch folding had produced the unreachable block makes /// it possible. class UnreachableUserCodeReportingState { public: - /// \brief The set of top-level blocks that became immediately unreachbale due + /// \brief The set of top-level blocks that became immediately unreachable due /// to conditional branch folding, etc. /// /// This is a SetVector since several blocks may lead to the same error @@ -78,7 +78,7 @@ class UnreachableUserCodeReportingState { /// /// Note, this set is different from the PossiblyUnreachableBlocks as these /// are the blocks that do contain user code and they might not be immediate - /// sucessors of a folded branch. + /// successors of a folded branch. llvm::SmallPtrSet BlocksWithErrors; /// A map from the PossiblyUnreachableBlocks to the folded conditional @@ -145,8 +145,8 @@ static void propagateBasicBlockArgs(SILBasicBlock &BB) { } // If we've reached this point, the optimization is valid, so optimize. - // We know that the incomming arguments from all predecessors are the same, - // so just use them directly and remove the basic block paramters. + // We know that the incoming arguments from all predecessors are the same, + // so just use them directly and remove the basic block parameters. // Drop the arguments from the branch instructions by creating a new branch // instruction and deleting the old one. @@ -200,7 +200,7 @@ static bool constantFoldTerminator(SILBasicBlock &BB, SILBuilderWithScope B(&BB, CBI); // Determine which of the successors is unreachable and create a new - // terminator that only branches to the reachable sucessor. + // terminator that only branches to the reachable successor. SILBasicBlock *UnreachableBlock = nullptr; bool CondIsTrue = false; if (ConstCond->getValue() == APInt(1, /*value*/ 0, false)) { @@ -219,7 +219,7 @@ static bool constantFoldTerminator(SILBasicBlock &BB, // Produce an unreachable code warning for this basic block if it // contains user code (only if we are not within an inlined function or a // template instantiation). - // FIXME: Do not report if we are within a template instatiation. + // FIXME: Do not report if we are within a template instantiation. if (Loc.is() && State && !State->PossiblyUnreachableBlocks.count(UnreachableBlock)) { // If this is the first time we see this unreachable block, store it @@ -267,8 +267,8 @@ static bool constantFoldTerminator(SILBasicBlock &BB, } } - // Not fully covered switches will be diagnosed later. SILGen represnets - // them with a Default basic block with an unrechable instruction. + // Not fully covered switches will be diagnosed later. SILGen represents + // them with a Default basic block with an unreachable instruction. // We are going to produce an error on all unreachable instructions not // eliminated by DCE. if (!TheSuccessorBlock) @@ -285,7 +285,7 @@ static bool constantFoldTerminator(SILBasicBlock &BB, // Produce diagnostic info if we are not within an inlined function or // template instantiation. - // FIXME: Do not report if we are within a template instatiation. + // FIXME: Do not report if we are within a template instantiation. assert(ReachableBlockIdx >= 0); if (Loc.is() && State) { // Find the first unreachable block in the switch so that we could use @@ -557,7 +557,7 @@ static bool simplifyBlocksWithCallsToNoReturn(SILBasicBlock &BB, /// \brief Issue an "unreachable code" diagnostic if the blocks contains or /// leads to another block that contains user code. /// -/// Note, we rely on SILLocation inforamtion to determine if SILInstructions +/// Note, we rely on SILLocation information to determine if SILInstructions /// correspond to user code. static bool diagnoseUnreachableBlock(const SILBasicBlock &B, SILModule &M, @@ -636,7 +636,7 @@ static bool diagnoseUnreachableBlock(const SILBasicBlock &B, return false; // If we have not found user code in this block, inspect it's successors. - // Check if at least one of the sucessors contains user code. + // Check if at least one of the successors contains user code. for (auto I = B.succ_begin(), E = B.succ_end(); I != E; ++I) { SILBasicBlock *SB = *I; bool HasReachablePred = false; @@ -645,7 +645,7 @@ static bool diagnoseUnreachableBlock(const SILBasicBlock &B, HasReachablePred = true; } - // If all of the predecessors of this sucessor are unreachable, check if + // If all of the predecessors of this successor are unreachable, check if // it contains user code. if (!HasReachablePred && diagnoseUnreachableBlock(*SB, M, Reachable, State, TopLevelB, Visited)) diff --git a/lib/SILPasses/EarlySIL/InOutDeshadowing.cpp b/lib/SILOptimizer/Mandatory/InOutDeshadowing.cpp similarity index 94% rename from lib/SILPasses/EarlySIL/InOutDeshadowing.cpp rename to lib/SILOptimizer/Mandatory/InOutDeshadowing.cpp index 8f34f4cb51066..a39dd32ca6fee 100644 --- a/lib/SILPasses/EarlySIL/InOutDeshadowing.cpp +++ b/lib/SILOptimizer/Mandatory/InOutDeshadowing.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,10 +23,10 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "inout-deshadow" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" @@ -50,9 +50,8 @@ static void promoteShadow(AllocStackInst *Alloc, SILArgument *InOutArg) { auto Use = *Alloc->use_begin(); auto *User = Use->getUser(); - // If this is a use of the 0th result, not the address result, just zap the - // instruction. It is a dealloc_stack or something similar. - if (Use->get().getResultNumber() == 0) { + // If this is the dealloc_stack, just zap the instruction. + if (isa(User)) { User->eraseFromParent(); continue; } @@ -72,8 +71,7 @@ static void promoteShadow(AllocStackInst *Alloc, SILArgument *InOutArg) { } // Make the debug information stored in the AllocBox explicit. SILBuilder B(Alloc); - B.createDebugValueAddr(Alloc->getLoc(), InOutArg, - Alloc->getVarInfo().getArgNo()); + B.createDebugValueAddr(Alloc->getLoc(), InOutArg, Alloc->getVarInfo()); Alloc->eraseFromParent(); } @@ -96,9 +94,7 @@ class StackSlotState { // We need to see a store back to the inout on every exit path. for (auto &bb : *F) { auto term = bb.getTerminator(); - if (isa(term) - || isa(term) - || isa(term)) { + if (isa(term) || isa(term)) { DEBUG(llvm::dbgs() << " need load from stack slot on exit " << &bb << '\n'); ExitBBs.insert(&bb); @@ -228,9 +224,7 @@ static void analyzeUseOfInOut(Operand *UI, StackSlotState &state) { if (isa(term)) return; - if (!isa(term) - && !isa(term) - && !isa(term)) + if (!isa(term) && !isa(term)) // Any copy from the inout outside of an exit block fails the analysis. // We don't need full flow-sensitive analysis for SILGen-ed code. return state.setFailed("inout is stored outside of an exit block"); diff --git a/lib/SILPasses/EarlySIL/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp similarity index 96% rename from lib/SILPasses/EarlySIL/MandatoryInlining.cpp rename to lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index 9af3a5221d389..0927d08b843d5 100644 --- a/lib/SILPasses/EarlySIL/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,13 +11,13 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "mandatory-inlining" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticsSIL.h" -#include "swift/SILPasses/Utils/Devirtualize.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/SILInliner.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Utils/Devirtualize.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/SILInliner.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/ImmutableSet.h" @@ -282,7 +282,8 @@ runOnFunctionRecursively(SILFunction *F, FullApplySite AI, SILModule::LinkingMode Mode, DenseFunctionSet &FullyInlinedSet, ImmutableFunctionSet::Factory &SetFactory, - ImmutableFunctionSet CurrentInliningSet) { + ImmutableFunctionSet CurrentInliningSet, + ClassHierarchyAnalysis *CHA) { // Avoid reprocessing functions needlessly. if (FullyInlinedSet.count(F)) return true; @@ -313,7 +314,7 @@ runOnFunctionRecursively(SILFunction *F, FullApplySite AI, auto *ApplyBlock = InnerAI.getParent(); - auto NewInstPair = tryDevirtualizeApply(InnerAI); + auto NewInstPair = tryDevirtualizeApply(InnerAI, CHA); if (auto *NewInst = NewInstPair.first) { replaceDeadApply(InnerAI, NewInst); if (auto *II = dyn_cast(NewInst)) @@ -342,12 +343,12 @@ runOnFunctionRecursively(SILFunction *F, FullApplySite AI, // Then recursively process it first before trying to inline it. if (!runOnFunctionRecursively(CalleeFunction, InnerAI, Mode, FullyInlinedSet, SetFactory, - CurrentInliningSet)) { + CurrentInliningSet, CHA)) { // If we failed due to circular inlining, then emit some notes to // trace back the failure if we have more information. // FIXME: possibly it could be worth recovering and attempting other // inlines within this same recursive call rather than simply - // propogating the failure. + // propagating the failure. if (AI) { SILLocation L = AI.getLoc(); assert(L && "Must have location for transparent inline apply"); @@ -433,6 +434,7 @@ namespace { class MandatoryInlining : public SILModuleTransform { /// The entry point to the transformation. void run() override { + ClassHierarchyAnalysis *CHA = getAnalysis(); SILModule *M = getModule(); SILModule::LinkingMode Mode = getOptions().LinkMode; bool ShouldCleanup = !getOptions().DebugSerialization; @@ -448,7 +450,7 @@ class MandatoryInlining : public SILModuleTransform { runOnFunctionRecursively(&F, FullApplySite(static_cast(nullptr)), Mode, FullyInlinedSet, - SetFactory, SetFactory.getEmptySet()); + SetFactory, SetFactory.getEmptySet(), CHA); } if (!ShouldCleanup) diff --git a/lib/SILPasses/EarlySIL/PredictableMemOpt.cpp b/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp similarity index 98% rename from lib/SILPasses/EarlySIL/PredictableMemOpt.cpp rename to lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp index ca2bf8cedee6a..322098c07f967 100644 --- a/lib/SILPasses/EarlySIL/PredictableMemOpt.cpp +++ b/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,11 +12,11 @@ #define DEBUG_TYPE "predictable-memopt" #include "swift/Basic/Fallthrough.h" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "DIMemoryUseCollector.h" #include "swift/SIL/SILBuilder.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/Statistic.h" @@ -86,7 +86,7 @@ static SILValue getAccessPathRoot(SILValue Pointer) { /// /// This will return a subelement number of 2. /// -/// If this pointer is to within a existential projection, it returns ~0U. +/// If this pointer is to within an existential projection, it returns ~0U. /// static unsigned computeSubelement(SILValue Pointer, SILInstruction *RootInst) { unsigned SubEltNumber = 0; @@ -350,7 +350,7 @@ updateAvailableValues(SILInstruction *Inst, llvm::SmallBitVector &RequiredElts, if (!AnyRequired) return; - // If the copyaddr is of an non-loadable type, we can't promote it. Just + // If the copyaddr is of a non-loadable type, we can't promote it. Just // consider it to be a clobber. if (CAI->getOperand(0).getType().isLoadable(Module)) { // Otherwise, some part of the copy_addr's value is demanded by a load, so @@ -819,7 +819,7 @@ void AllocOptimize::explodeCopyAddr(CopyAddrInst *CAI) { case ValueKind::LoadInst: // If it is a load from the memory object (as oppose to a load from - // something else), track it as an access. We need to explictly check to + // something else), track it as an access. We need to explicitly check to // see if the load accesses "TheMemory" because it could either be a load // for the copy_addr source, or it could be a load corresponding to the // "assign" operation on the destination of the copyaddr. diff --git a/lib/SILOptimizer/PassManager/CMakeLists.txt b/lib/SILOptimizer/PassManager/CMakeLists.txt new file mode 100644 index 0000000000000..51688ec67b3e1 --- /dev/null +++ b/lib/SILOptimizer/PassManager/CMakeLists.txt @@ -0,0 +1,5 @@ +set(PASSMANAGER_SOURCES + PassManager/PassManager.cpp + PassManager/Passes.cpp + PassManager/PrettyStackTrace.cpp + PARENT_SCOPE) diff --git a/lib/SILOptimizer/PassManager/PassManager.cpp b/lib/SILOptimizer/PassManager/PassManager.cpp new file mode 100644 index 0000000000000..646659315d778 --- /dev/null +++ b/lib/SILOptimizer/PassManager/PassManager.cpp @@ -0,0 +1,679 @@ +//===--- PassManager.cpp - Swift Pass Manager -----------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-passmanager" + +#include "swift/Basic/DemangleWrappers.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILModule.h" +#include "swift/SILOptimizer/PassManager/PrettyStackTrace.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringSwitch.h" +#include "swift/SILOptimizer/Analysis/FunctionOrder.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/TimeValue.h" +#include "llvm/Support/GraphWriter.h" + +using namespace swift; + +STATISTIC(NumOptzIterations, "Number of optimization iterations"); + +llvm::cl::opt SILPrintAll( + "sil-print-all", llvm::cl::init(false), + llvm::cl::desc("Print SIL after each pass")); + +llvm::cl::opt SILPrintPassName( + "sil-print-pass-name", llvm::cl::init(false), + llvm::cl::desc("Print the name of each SIL pass before it runs")); + +llvm::cl::opt SILPrintPassTime( + "sil-print-pass-time", llvm::cl::init(false), + llvm::cl::desc("Print the execution time of each SIL pass")); + +llvm::cl::opt SILNumOptPassesToRun( + "sil-opt-pass-count", llvm::cl::init(UINT_MAX), + llvm::cl::desc("Stop optimizing after optimization passes")); + +llvm::cl::opt + SILPrintOnlyFun("sil-print-only-function", llvm::cl::init(""), + llvm::cl::desc("Only print out the sil for this function")); + +llvm::cl::opt + SILPrintOnlyFuns("sil-print-only-functions", llvm::cl::init(""), + llvm::cl::desc("Only print out the sil for the functions " + "whose name contains this substring")); + +llvm::cl::list + SILPrintBefore("sil-print-before", + llvm::cl::desc("Print out the sil before passes which " + "contain a string from this list.")); + +llvm::cl::list + SILPrintAfter("sil-print-after", + llvm::cl::desc("Print out the sil after passes which contain " + "a string from this list.")); + +llvm::cl::list + SILPrintAround("sil-print-around", + llvm::cl::desc("Print out the sil before and after passes " + "which contain a string from this list")); + +llvm::cl::list + SILDisablePass("sil-disable-pass", + llvm::cl::desc("Disable passes " + "which contain a string from this list")); + +llvm::cl::opt SILVerifyWithoutInvalidation( + "sil-verify-without-invalidation", llvm::cl::init(false), + llvm::cl::desc("Verify after passes even if the pass has not invalidated")); + +static bool doPrintBefore(SILTransform *T, SILFunction *F) { + if (!SILPrintOnlyFun.empty() && F && F->getName() != SILPrintOnlyFun) + return false; + + if (!SILPrintOnlyFuns.empty() && F && + F->getName().find(SILPrintOnlyFuns, 0) == StringRef::npos) + return false; + + auto MatchFun = [&](const std::string &Str) -> bool { + return T->getName().find(Str) != StringRef::npos; + }; + + if (SILPrintBefore.end() != + std::find_if(SILPrintBefore.begin(), SILPrintBefore.end(), MatchFun)) + return true; + + if (SILPrintAround.end() != + std::find_if(SILPrintAround.begin(), SILPrintAround.end(), MatchFun)) + return true; + + return false; +} + +static bool doPrintAfter(SILTransform *T, SILFunction *F, bool Default) { + if (!SILPrintOnlyFun.empty() && F && F->getName() != SILPrintOnlyFun) + return false; + + if (!SILPrintOnlyFuns.empty() && F && + F->getName().find(SILPrintOnlyFuns, 0) == StringRef::npos) + return false; + + auto MatchFun = [&](const std::string &Str) -> bool { + return T->getName().find(Str) != StringRef::npos; + }; + + if (SILPrintAfter.end() != + std::find_if(SILPrintAfter.begin(), SILPrintAfter.end(), MatchFun)) + return true; + + if (SILPrintAround.end() != + std::find_if(SILPrintAround.begin(), SILPrintAround.end(), MatchFun)) + return true; + + return Default; +} + +static bool isDisabled(SILTransform *T) { + for (const std::string &NamePattern : SILDisablePass) { + if (T->getName().find(NamePattern) != StringRef::npos) + return true; + } + return false; +} + +static void printModule(SILModule *Mod, bool EmitVerboseSIL) { + if (SILPrintOnlyFun.empty() && SILPrintOnlyFuns.empty()) { + Mod->dump(); + return; + } + for (auto &F : *Mod) { + if (!SILPrintOnlyFun.empty() && F.getName().str() == SILPrintOnlyFun) + F.dump(EmitVerboseSIL); + + if (!SILPrintOnlyFuns.empty() && + F.getName().find(SILPrintOnlyFuns, 0) != StringRef::npos) + F.dump(EmitVerboseSIL); + } +} + +SILPassManager::SILPassManager(SILModule *M, llvm::StringRef Stage) : + Mod(M), StageName(Stage) { + +#define ANALYSIS(NAME) \ + Analysis.push_back(create##NAME##Analysis(Mod)); +#include "swift/SILOptimizer/Analysis/Analysis.def" + + for (SILAnalysis *A : Analysis) { + A->initialize(this); + M->registerDeleteNotificationHandler(A); + } +} + +bool SILPassManager::continueTransforming() { + return Mod->getStage() == SILStage::Raw || + NumPassesRun < SILNumOptPassesToRun; +} + +void SILPassManager::runPassesOnFunction(PassList FuncTransforms, + SILFunction *F) { + + const SILOptions &Options = getOptions(); + + CompletedPasses &completedPasses = CompletedPassesMap[F]; + + for (auto SFT : FuncTransforms) { + PrettyStackTraceSILFunctionTransform X(SFT); + SFT->injectPassManager(this); + SFT->injectFunction(F); + + // If nothing changed since the last run of this pass, we can skip this + // pass. + if (completedPasses.test((size_t)SFT->getPassKind())) + continue; + + if (isDisabled(SFT)) + continue; + + currentPassHasInvalidated = false; + + if (SILPrintPassName) + llvm::dbgs() << "#" << NumPassesRun << " Stage: " << StageName + << " Pass: " << SFT->getName() + << ", Function: " << F->getName() << "\n"; + + if (doPrintBefore(SFT, F)) { + llvm::dbgs() << "*** SIL function before " << StageName << " " + << SFT->getName() << " (" << NumOptimizationIterations + << ") ***\n"; + F->dump(Options.EmitVerboseSIL); + } + + llvm::sys::TimeValue StartTime = llvm::sys::TimeValue::now(); + Mod->registerDeleteNotificationHandler(SFT); + SFT->run(); + Mod->removeDeleteNotificationHandler(SFT); + + // Did running the transform result in new functions being added + // to the top of our worklist? + bool newFunctionsAdded = (F != FunctionWorklist.back()); + + if (SILPrintPassTime) { + auto Delta = + llvm::sys::TimeValue::now().nanoseconds() - StartTime.nanoseconds(); + llvm::dbgs() << Delta << " (" << SFT->getName() << "," << F->getName() + << ")\n"; + } + + // If this pass invalidated anything, print and verify. + if (doPrintAfter(SFT, F, currentPassHasInvalidated && SILPrintAll)) { + llvm::dbgs() << "*** SIL function after " << StageName << " " + << SFT->getName() << " (" << NumOptimizationIterations + << ") ***\n"; + F->dump(Options.EmitVerboseSIL); + } + + // Remember if this pass didn't change anything. + if (!currentPassHasInvalidated) + completedPasses.set((size_t)SFT->getPassKind()); + + if (Options.VerifyAll && + (currentPassHasInvalidated || SILVerifyWithoutInvalidation)) { + F->verify(); + verifyAnalyses(F); + } + + ++NumPassesRun; + + // If running the transform resulted in new functions on the top + // of the worklist, we'll return so that we can begin processing + // those new functions. + if (newFunctionsAdded || !continueTransforming()) + return; + } +} + +void SILPassManager::runFunctionPasses(PassList FuncTransforms) { + BasicCalleeAnalysis *BCA = getAnalysis(); + BottomUpFunctionOrder BottomUpOrder(*Mod, BCA); + auto BottomUpFunctions = BottomUpOrder.getFunctions(); + + assert(FunctionWorklist.empty() && "Expected empty function worklist!"); + + FunctionWorklist.reserve(BottomUpFunctions.size()); + for (auto I = BottomUpFunctions.rbegin(), E = BottomUpFunctions.rend(); + I != E; ++I) { + auto &F = **I; + + // Only include functions that are definitions, and which have not + // been intentionally excluded from optimization. + if (F.isDefinition() && F.shouldOptimize()) + FunctionWorklist.push_back(*I); + } + + // Used to track how many times a given function has been + // (partially) optimized by the function pass pipeline in this + // invocation. + llvm::DenseMap CountOptimized; + + // Pop functions off the worklist, and run all function transforms + // on each of them. + while (!FunctionWorklist.empty()) { + auto *F = FunctionWorklist.back(); + + runPassesOnFunction(FuncTransforms, F); + + ++CountOptimized[F]; + + // If running the function transforms did not result in new + // functions being added to the top of the worklist, then we're + // done with this function and can pop it off and continue. + // Otherwise, we'll return to this function and reoptimize after + // processing the new functions that were added. + if (F == FunctionWorklist.back()) + FunctionWorklist.pop_back(); + } +} + +void SILPassManager::runModulePass(SILModuleTransform *SMT) { + if (isDisabled(SMT)) + return; + + const SILOptions &Options = getOptions(); + + PrettyStackTraceSILModuleTransform X(SMT); + + SMT->injectPassManager(this); + SMT->injectModule(Mod); + + currentPassHasInvalidated = false; + + if (SILPrintPassName) + llvm::dbgs() << "#" << NumPassesRun << " Stage: " << StageName + << " Pass: " << SMT->getName() << " (module pass)\n"; + + if (doPrintBefore(SMT, nullptr)) { + llvm::dbgs() << "*** SIL module before " << StageName << " " + << SMT->getName() << " (" << NumOptimizationIterations + << ") ***\n"; + printModule(Mod, Options.EmitVerboseSIL); + } + + llvm::sys::TimeValue StartTime = llvm::sys::TimeValue::now(); + Mod->registerDeleteNotificationHandler(SMT); + SMT->run(); + Mod->removeDeleteNotificationHandler(SMT); + + if (SILPrintPassTime) { + auto Delta = llvm::sys::TimeValue::now().nanoseconds() - + StartTime.nanoseconds(); + llvm::dbgs() << Delta << " (" << SMT->getName() << ",Module)\n"; + } + + // If this pass invalidated anything, print and verify. + if (doPrintAfter(SMT, nullptr, + currentPassHasInvalidated && SILPrintAll)) { + llvm::dbgs() << "*** SIL module after " << StageName << " " + << SMT->getName() << " (" << NumOptimizationIterations + << ") ***\n"; + printModule(Mod, Options.EmitVerboseSIL); + } + + if (Options.VerifyAll && + (currentPassHasInvalidated || !SILVerifyWithoutInvalidation)) { + Mod->verify(); + verifyAnalyses(); + } +} + +void SILPassManager::runOneIteration() { + // Verify that all analysis were properly unlocked. + for (auto A : Analysis) { + assert(!A->isLocked() && + "Deleting a locked analysis. Did we forget to unlock ?"); + (void)A; + } + + const SILOptions &Options = getOptions(); + + DEBUG(llvm::dbgs() << "*** Optimizing the module (" << StageName + << ") *** \n"); + if (SILPrintAll && NumOptimizationIterations == 0) { + llvm::dbgs() << "*** SIL module before " << StageName + << " transformation (" << NumOptimizationIterations + << ") ***\n"; + printModule(Mod, Options.EmitVerboseSIL); + } + NumOptzIterations++; + NumOptimizationIterations++; + SmallVector PendingFuncTransforms; + + // Run the transforms by alternating between function transforms and + // module transforms. We'll queue up all the function transforms + // that we see in a row and then run the entire group of transforms + // on each function in turn. Then we move on to running the next set + // of consecutive module transforms. + auto It = Transformations.begin(); + auto End = Transformations.end(); + + while (It != End && continueTransforming()) { + assert((isa(*It) || isa(*It)) && + "Unexpected pass kind!"); + + while (It != End && isa(*It)) + PendingFuncTransforms.push_back(cast(*It++)); + + runFunctionPasses(PendingFuncTransforms); + PendingFuncTransforms.clear(); + + while (It != End && isa(*It) && + continueTransforming()) { + runModulePass(cast(*It)); + + ++It; + ++NumPassesRun; + } + } +} + +void SILPassManager::run() { + const SILOptions &Options = getOptions(); + (void) Options; + + if (SILPrintAll) { + if (SILPrintOnlyFun.empty() && SILPrintOnlyFuns.empty()) { + llvm::dbgs() << "*** SIL module before transformation (" + << NumOptimizationIterations << ") ***\n"; + Mod->dump(Options.EmitVerboseSIL); + } else { + for (auto &F : *Mod) { + if (!SILPrintOnlyFun.empty() && F.getName().str() == SILPrintOnlyFun) { + llvm::dbgs() << "*** SIL function before transformation (" + << NumOptimizationIterations << ") ***\n"; + F.dump(Options.EmitVerboseSIL); + } + if (!SILPrintOnlyFuns.empty() && + F.getName().find(SILPrintOnlyFuns, 0) != StringRef::npos) { + llvm::dbgs() << "*** SIL function before transformation (" + << NumOptimizationIterations << ") ***\n"; + F.dump(Options.EmitVerboseSIL); + } + } + } + } + runOneIteration(); +} + +/// D'tor. +SILPassManager::~SILPassManager() { + // Free all transformations. + for (auto T : Transformations) + delete T; + + // delete the analysis. + for (auto A : Analysis) { + Mod->removeDeleteNotificationHandler(A); + assert(!A->isLocked() && + "Deleting a locked analysis. Did we forget to unlock ?"); + delete A; + } +} + +/// \brief Reset the state of the pass manager and remove all transformation +/// owned by the pass manager. Analysis passes will be kept. +void SILPassManager::resetAndRemoveTransformations() { + for (auto T : Transformations) + delete T; + + Transformations.clear(); + NumOptimizationIterations = 0; +} + +void SILPassManager::setStageName(llvm::StringRef NextStage) { + StageName = NextStage; +} + +const SILOptions &SILPassManager::getOptions() const { + return Mod->getOptions(); +} + +// Define the add-functions for all passes. + +#define PASS(ID, NAME, DESCRIPTION) \ + void SILPassManager::add##ID() { \ + SILTransform *T = swift::create##ID(); \ + T->setPassKind(PassKind::ID); \ + Transformations.push_back(T); \ + } +#include "swift/SILOptimizer/PassManager/Passes.def" + +void SILPassManager::addPass(PassKind Kind) { + assert(unsigned(PassKind::AllPasses_Last) >= unsigned(Kind) && + "Invalid pass kind"); + switch (Kind) { +#define PASS(ID, NAME, DESCRIPTION) \ + case PassKind::ID: \ + add##ID(); \ + break; +#include "swift/SILOptimizer/PassManager/Passes.def" + case PassKind::invalidPassKind: + llvm_unreachable("invalid pass kind"); + } +} + +void SILPassManager::addPassForName(StringRef Name) { + auto P = llvm::StringSwitch(Name) +#define PASS(ID, NAME, DESCRIPTION) .Case(#ID, PassKind::ID) +#include "swift/SILOptimizer/PassManager/Passes.def" + ; + addPass(P); +} + +//===----------------------------------------------------------------------===// +// View Call-Graph Implementation +//===----------------------------------------------------------------------===// + +#ifndef NDEBUG + +namespace { + + /// An explicit graph data structure for the call graph. + /// Used for viewing the callgraph as dot file with llvm::ViewGraph. + struct CallGraph { + + struct Node; + + struct Edge { + FullApplySite FAS; + Node *Child; + bool Incomplete; + }; + + struct Node { + SILFunction *F; + CallGraph *CG; + int NumCallSites = 0; + SmallVector Children; + }; + + struct child_iterator + : public std::iterator { + SmallVectorImpl::iterator baseIter; + + child_iterator(SmallVectorImpl::iterator baseIter) : + baseIter(baseIter) + { } + + child_iterator &operator++() { baseIter++; return *this; } + child_iterator operator++(int) { + auto tmp = *this; + baseIter++; + return tmp; + } + Node *operator*() const { return baseIter->Child; } + bool operator==(const child_iterator &RHS) const { + return baseIter == RHS.baseIter; + } + bool operator!=(const child_iterator &RHS) const { + return baseIter != RHS.baseIter; + } + difference_type operator-(const child_iterator &RHS) const { + return baseIter - RHS.baseIter; + } + }; + + CallGraph(SILModule *M, BasicCalleeAnalysis *BCA); + + std::vector Nodes; + + /// The SILValue IDs which are printed as edge source labels. + llvm::DenseMap InstToIDMap; + + typedef std::vector::iterator iterator; + }; + + CallGraph::CallGraph(SILModule *M, BasicCalleeAnalysis *BCA) { + Nodes.resize(M->getFunctionList().size()); + llvm::DenseMap NodeMap; + int idx = 0; + for (SILFunction &F : *M) { + Node &Nd = Nodes[idx++]; + Nd.F = &F; + Nd.CG = this; + NodeMap[&F] = &Nd; + + F.numberValues(InstToIDMap); + } + + for (Node &Nd : Nodes) { + for (SILBasicBlock &BB : *Nd.F) { + for (SILInstruction &I : BB) { + if (FullApplySite FAS = FullApplySite::isa(&I)) { + auto CList = BCA->getCalleeList(FAS); + for (SILFunction *Callee : CList) { + Node *CalleeNode = NodeMap[Callee]; + Nd.Children.push_back({FAS, CalleeNode,CList.isIncomplete()}); + } + } + } + } + } + } + +} // end swift namespace + +namespace llvm { + + /// Wraps a dot node label string to multiple lines. The \p NumEdgeLabels + /// gives an estimate on the minimum width of the node shape. + static void wrap(std::string &Str, int NumEdgeLabels) { + unsigned ColNum = 0; + unsigned LastSpace = 0; + unsigned MaxColumns = std::max(60, NumEdgeLabels * 8); + for (unsigned i = 0; i != Str.length(); ++i) { + if (ColNum == MaxColumns) { + if (!LastSpace) + LastSpace = i; + Str.insert(LastSpace + 1, "\\l"); + ColNum = i - LastSpace - 1; + LastSpace = 0; + } else + ++ColNum; + if (Str[i] == ' ' || Str[i] == '.') + LastSpace = i; + } + } + + /// CallGraph GraphTraits specialization so the CallGraph can be + /// iterable by generic graph iterators. + template <> struct GraphTraits { + typedef CallGraph::Node NodeType; + typedef CallGraph::child_iterator ChildIteratorType; + + static NodeType *getEntryNode(NodeType *N) { return N; } + static inline ChildIteratorType child_begin(NodeType *N) { + return N->Children.begin(); + } + static inline ChildIteratorType child_end(NodeType *N) { + return N->Children.end(); + } + }; + + template <> struct GraphTraits + : public GraphTraits { + typedef CallGraph *GraphType; + + static NodeType *getEntryNode(GraphType F) { return nullptr; } + + typedef CallGraph::iterator nodes_iterator; + static nodes_iterator nodes_begin(GraphType CG) { + return CG->Nodes.begin(); + } + static nodes_iterator nodes_end(GraphType CG) { return CG->Nodes.end(); } + static unsigned size(GraphType CG) { return CG->Nodes.size(); } + }; + + /// This is everything the llvm::GraphWriter needs to write the call graph in + /// a dot file. + template <> + struct DOTGraphTraits : public DefaultDOTGraphTraits { + + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} + + std::string getNodeLabel(const CallGraph::Node *Node, + const CallGraph *Graph) { + std::string Label = Node->F->getName(); + wrap(Label, Node->NumCallSites); + return Label; + } + + std::string getNodeDescription(const CallGraph::Node *Node, + const CallGraph *Graph) { + std::string Label = demangle_wrappers:: + demangleSymbolAsString(Node->F->getName()); + wrap(Label, Node->NumCallSites); + return Label; + } + + static std::string getEdgeSourceLabel(const CallGraph::Node *Node, + CallGraph::child_iterator I) { + std::string Label; + raw_string_ostream O(Label); + SILInstruction *Inst = I.baseIter->FAS.getInstruction(); + O << '%' << Node->CG->InstToIDMap[Inst]; + return Label; + } + + static std::string getEdgeAttributes(const CallGraph::Node *Node, + CallGraph::child_iterator I, + const CallGraph *Graph) { + CallGraph::Edge *Edge = I.baseIter; + if (Edge->Incomplete) + return "color=\"red\""; + return ""; + } + }; +} // end llvm namespace +#endif + +void SILPassManager::viewCallGraph() { + /// When asserts are disabled, this should be a NoOp. +#ifndef NDEBUG + CallGraph OCG(getModule(), getAnalysis()); + llvm::ViewGraph(&OCG, "callgraph"); +#endif +} diff --git a/lib/SILPasses/PassManager/Passes.cpp b/lib/SILOptimizer/PassManager/Passes.cpp similarity index 91% rename from lib/SILPasses/PassManager/Passes.cpp rename to lib/SILOptimizer/PassManager/Passes.cpp index 463246a3a559d..68da7c6511d1e 100644 --- a/lib/SILPasses/PassManager/Passes.cpp +++ b/lib/SILOptimizer/PassManager/Passes.cpp @@ -1,8 +1,8 @@ -//===-------- Passes.cpp - Swift Compiler SIL Pass Entrypoints ------------===// +//===--- Passes.cpp - Swift Compiler SIL Pass Entrypoints -----------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,11 +21,11 @@ #define DEBUG_TYPE "sil-optimizer" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/PassManager.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILAnalysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" #include "swift/AST/ASTContext.h" #include "swift/AST/Module.h" #include "swift/SIL/SILModule.h" @@ -40,13 +40,13 @@ llvm::cl::opt SILViewCFG("sil-view-cfg", llvm::cl::init(false), llvm::cl::desc("Enable the sil cfg viewer pass")); -llvm::cl::opt - SILViewGuaranteedCFG("sil-view-guaranteed-cfg", llvm::cl::init(false), - llvm::cl::desc("Enable the sil cfg viewer pass after diagnostics")); +llvm::cl::opt SILViewGuaranteedCFG( + "sil-view-guaranteed-cfg", llvm::cl::init(false), + llvm::cl::desc("Enable the sil cfg viewer pass after diagnostics")); -llvm::cl::opt - SILViewSILGenCFG("sil-view-silgen-cfg", llvm::cl::init(false), - llvm::cl::desc("Enable the sil cfg viewer pass before diagnostics")); +llvm::cl::opt SILViewSILGenCFG( + "sil-view-silgen-cfg", llvm::cl::init(false), + llvm::cl::desc("Enable the sil cfg viewer pass before diagnostics")); using namespace swift; @@ -133,7 +133,7 @@ void AddSimplifyCFGSILCombine(SILPassManager &PM) { /// Perform semantic annotation/loop base optimizations. void AddHighLevelLoopOptPasses(SILPassManager &PM) { - // Perform classsic SSA optimizations for cleanup. + // Perform classic SSA optimizations for cleanup. PM.addLowerAggregateInstrs(); PM.addSILCombine(); PM.addSROA(); @@ -151,8 +151,17 @@ void AddHighLevelLoopOptPasses(SILPassManager &PM) { PM.addHighLevelCSE(); PM.addSILCombine(); PM.addSimplifyCFG(); - PM.addArrayCountPropagation(); PM.addHighLevelLICM(); + // Start of loop unrolling passes. + PM.addArrayCountPropagation(); + // To simplify induction variable. + PM.addSILCombine(); + PM.addLoopUnroll(); + PM.addSimplifyCFG(); + PM.addPerformanceConstantPropagation(); + PM.addSimplifyCFG(); + PM.addArrayElementPropagation(); + // End of unrolling passes. PM.addRemovePins(); PM.addABCOpt(); // Cleanup. @@ -172,7 +181,7 @@ void AddSSAPasses(SILPassManager &PM, OptimizationLevelKind OpLevel) { PM.addSROA(); PM.addMem2Reg(); - // Perform classsic SSA optimizations. + // Perform classic SSA optimizations. PM.addGlobalOpt(); PM.addLetPropertiesOpt(); PM.addPerformanceConstantPropagation(); @@ -218,7 +227,6 @@ void AddSSAPasses(SILPassManager &PM, OptimizationLevelKind OpLevel) { PM.addEarlyCodeMotion(); PM.addARCSequenceOpts(); PM.addRemovePins(); - PM.addUpdateSideEffects(); } @@ -243,6 +251,8 @@ void swift::runSILOptimizationPasses(SILModule &Module) { // Run two iterations of the high-level SSA passes. PM.setStageName("HighLevel"); + PM.addDevirtualizer(); + PM.addGenericSpecializer(); AddSSAPasses(PM, OptimizationLevelKind::HighLevel); PM.runOneIteration(); PM.runOneIteration(); @@ -254,7 +264,6 @@ void swift::runSILOptimizationPasses(SILModule &Module) { PM.addDeadFunctionElimination(); PM.addDeadObjectElimination(); PM.addGlobalPropertyOpt(); - PM.addUpdateEscapeAnalysis(); // Do the first stack promotion on high-level SIL. PM.addStackPromotion(); @@ -262,7 +271,6 @@ void swift::runSILOptimizationPasses(SILModule &Module) { PM.runOneIteration(); PM.resetAndRemoveTransformations(); - // Run two iterations of the mid-level SSA passes. PM.setStageName("MidLevel"); AddSSAPasses(PM, OptimizationLevelKind::MidLevel); @@ -291,8 +299,6 @@ void swift::runSILOptimizationPasses(SILModule &Module) { // Specialize closure. PM.addClosureSpecializer(); - PM.addUpdateEscapeAnalysis(); - // Do the second stack promotion on low-level SIL. PM.addStackPromotion(); @@ -337,22 +343,23 @@ void swift::runSILOptimizationPasses(SILModule &Module) { PM.runOneIteration(); PM.resetAndRemoveTransformations(); - PM.addCodeSinking(); PM.setStageName("LateLoopOpt"); - PM.addLICM(); - // Perform the final lowering transformations. + // Delete dead code and drop the bodies of shared functions. PM.addExternalFunctionDefinitionsElimination(); PM.addDeadFunctionElimination(); - // Optimize overflow checks: + // Perform the final lowering transformations. + PM.addCodeSinking(); + PM.addLICM(); + + // Optimize overflow checks. PM.addRedundantOverflowCheckRemoval(); PM.addMergeCondFails(); // Remove dead code. PM.addDCE(); - // Clean-up after DCE. PM.addSimplifyCFG(); PM.runOneIteration(); @@ -445,7 +452,8 @@ descriptorsForFile(StringRef Filename, auto *RootList = cast(N); - for (auto &PMDescriptorIter : make_range(RootList->begin(), RootList->end())) { + for (auto &PMDescriptorIter : + make_range(RootList->begin(), RootList->end())) { PMDescriptor PM(cast(&PMDescriptorIter)); Descriptors.push_back(std::move(PM)); } diff --git a/lib/SILPasses/PassManager/PrettyStackTrace.cpp b/lib/SILOptimizer/PassManager/PrettyStackTrace.cpp similarity index 85% rename from lib/SILPasses/PassManager/PrettyStackTrace.cpp rename to lib/SILOptimizer/PassManager/PrettyStackTrace.cpp index 8e011a3c3f020..5e94a442dad1f 100644 --- a/lib/SILPasses/PassManager/PrettyStackTrace.cpp +++ b/lib/SILOptimizer/PassManager/PrettyStackTrace.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,9 +10,9 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/PrettyStackTrace.h" +#include "swift/SILOptimizer/PassManager/PrettyStackTrace.h" #include "swift/SIL/SILFunction.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/Support/raw_ostream.h" using namespace swift; diff --git a/lib/SILPasses/SILCombiner/CMakeLists.txt b/lib/SILOptimizer/SILCombiner/CMakeLists.txt similarity index 100% rename from lib/SILPasses/SILCombiner/CMakeLists.txt rename to lib/SILOptimizer/SILCombiner/CMakeLists.txt diff --git a/lib/SILPasses/SILCombiner/SILCombine.cpp b/lib/SILOptimizer/SILCombiner/SILCombine.cpp similarity index 88% rename from lib/SILPasses/SILCombiner/SILCombine.cpp rename to lib/SILOptimizer/SILCombiner/SILCombine.cpp index 1a95d181f9fae..27b7a4b8a906b 100644 --- a/lib/SILPasses/SILCombiner/SILCombine.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombine.cpp @@ -1,8 +1,8 @@ -//===-------------------------- SILCombine --------------------------------===// +//===--- SILCombine -------------------------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,15 +19,15 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-combine" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "SILCombiner.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/SimplifyInstruction.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/SimplifyInstruction.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -211,11 +211,11 @@ bool SILCombiner::doOneIteration(SILFunction &F, unsigned Iteration) { // the next iteration. auto &TrackingList = *Builder.getTrackingList(); for (SILInstruction *I : TrackingList) { - if (!DeletedInstSet.count(I)) - Worklist.add(I); + DEBUG(llvm::dbgs() << "SC: add " << *I << + " from tracking list to worklist\n"); + Worklist.add(I); } TrackingList.clear(); - DeletedInstSet.clear(); } Worklist.zap(); @@ -263,7 +263,7 @@ SILInstruction *SILCombiner::insertNewInstBefore(SILInstruction *New, } // This method is to be used when an instruction is found to be dead, -// replacable with another preexisting expression. Here we add all uses of I +// replaceable with another preexisting expression. Here we add all uses of I // to the worklist, replace all uses of I with the new value, then return I, // so that the combiner will know that I was modified. SILInstruction *SILCombiner::replaceInstUsesWith(SILInstruction &I, @@ -284,9 +284,9 @@ SILInstruction * SILCombiner:: replaceInstUsesWith(SILInstruction &I, ValueBase *V, unsigned IIndex, unsigned VIndex) { - assert(IIndex < I.getNumTypes() && "Can not have more results than " + assert(IIndex < I.getNumTypes() && "Cannot have more results than " "types."); - assert(VIndex < V->getNumTypes() && "Can not have more results than " + assert(VIndex < V->getNumTypes() && "Cannot have more results than " "types."); // Add all modified instrs to worklist. @@ -301,7 +301,7 @@ replaceInstUsesWith(SILInstruction &I, ValueBase *V, unsigned IIndex, } // Some instructions can never be "trivially dead" due to side effects or -// producing a void value. In those cases, since we can not rely on +// producing a void value. In those cases, since we cannot rely on // SILCombines trivially dead instruction DCE in order to delete the // instruction, visit methods should use this method to delete the given // instruction and upon completion of their peephole return the value returned @@ -314,17 +314,21 @@ SILInstruction *SILCombiner::eraseInstFromFunction(SILInstruction &I, assert(hasNoUsesExceptDebug(&I) && "Cannot erase instruction that is used!"); // Make sure that we reprocess all operands now that we reduced their // use counts. - if (I.getNumOperands() < 8 && AddOperandsToWorklist) - for (auto &OpI : I.getAllOperands()) - if (SILInstruction *Op = llvm::dyn_cast(&*OpI.get())) + if (I.getNumOperands() < 8 && AddOperandsToWorklist) { + for (auto &OpI : I.getAllOperands()) { + if (SILInstruction *Op = llvm::dyn_cast(&*OpI.get())) { + DEBUG(llvm::dbgs() << "SC: add op " << *Op << + " from erased inst to worklist\n"); Worklist.add(Op); + } + } + } for (Operand *DU : getDebugUses(I)) Worklist.remove(DU->getUser()); Worklist.remove(&I); eraseFromParentWithDebugInsts(&I, InstIter); - DeletedInstSet.insert(&I); MadeChange = true; return nullptr; // Don't do anything with I } @@ -337,23 +341,35 @@ namespace { class SILCombine : public SILFunctionTransform { + llvm::SmallVector TrackingList; + /// The entry point to the transformation. void run() override { auto *AA = PM->getAnalysis(); // Create a SILBuilder with a tracking list for newly added // instructions, which we will periodically move to our worklist. - llvm::SmallVector TrackingList; - SILBuilder B(*getFunction(), &TrackingList); SILCombiner Combiner(B, AA, getOptions().RemoveRuntimeAsserts); bool Changed = Combiner.runOnFunction(*getFunction()); + assert(TrackingList.empty() && + "TrackingList should be fully processed by SILCombiner"); if (Changed) { // Invalidate everything. invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody); } } + + virtual void handleDeleteNotification(ValueBase *I) override { + // Linear searching the tracking list doesn't hurt because usually it only + // contains a few elements. + auto Iter = std::find(TrackingList.begin(), TrackingList.end(), I); + if (Iter != TrackingList.end()) + TrackingList.erase(Iter); + } + + virtual bool needsNotifications() override { return true; } StringRef getName() override { return "SIL Combine"; } }; diff --git a/lib/SILPasses/SILCombiner/SILCombiner.h b/lib/SILOptimizer/SILCombiner/SILCombiner.h similarity index 94% rename from lib/SILPasses/SILCombiner/SILCombiner.h rename to lib/SILOptimizer/SILCombiner/SILCombiner.h index 91b2cabd34d16..22112b0ee67f9 100644 --- a/lib/SILPasses/SILCombiner/SILCombiner.h +++ b/lib/SILOptimizer/SILCombiner/SILCombiner.h @@ -1,8 +1,8 @@ -//===-------------------------- SILCombiner.h -----------------*- C++ -*---===// +//===--- SILCombiner.h ------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,14 +18,14 @@ // //===----------------------------------------------------------------------===// -#ifndef SWIFT_SILPASSES_SILCOMBINER_H -#define SWIFT_SILPASSES_SILCOMBINER_H +#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_SILCOMBINER_H +#define SWIFT_SILOPTIMIZER_PASSMANAGER_SILCOMBINER_H #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILValue.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" @@ -130,17 +130,13 @@ class SILCombiner : /// Builder used to insert instructions. SILBuilder &Builder; - /// A set of instructions which have been deleted during this iteration. It is - /// used to make sure that we do not - llvm::DenseSet DeletedInstSet; - /// Cast optimizer CastOptimizer CastOpt; public: SILCombiner(SILBuilder &B, AliasAnalysis *AA, bool removeCondFails) : AA(AA), Worklist(), MadeChange(false), RemoveCondFails(removeCondFails), - Iteration(0), Builder(B), DeletedInstSet(128), + Iteration(0), Builder(B), CastOpt(/* ReplaceInstUsesAction */ [&](SILInstruction *I, ValueBase * V) { replaceInstUsesWith(*I, V); @@ -161,7 +157,7 @@ class SILCombiner : SILInstruction *insertNewInstBefore(SILInstruction *New, SILInstruction &Old); // This method is to be used when an instruction is found to be dead, - // replacable with another preexisting expression. Here we add all uses of I + // replaceable with another preexisting expression. Here we add all uses of I // to the worklist, replace all uses of I with the new value, then return I, // so that the combiner will know that I was modified. SILInstruction *replaceInstUsesWith(SILInstruction &I, ValueBase *V); @@ -172,7 +168,7 @@ class SILCombiner : unsigned IIndex, unsigned VIndex=0); // Some instructions can never be "trivially dead" due to side effects or - // producing a void value. In those cases, since we can not rely on + // producing a void value. In those cases, since we cannot rely on // SILCombines trivially dead instruction DCE in order to delete the // instruction, visit methods should use this method to delete the given // instruction and upon completion of their peephole return the value returned @@ -298,7 +294,7 @@ class SILCombiner : /// Inserts release/destroy instructions for all owner and in-parameters. void eraseApply(FullApplySite FAS, const UserListTy &Users); - /// Returns true if the results of an try_apply are not used. + /// Returns true if the results of a try_apply are not used. static bool isTryApplyResultNotUsed(UserListTy &AcceptedUses, TryApplyInst *TAI); }; diff --git a/lib/SILPasses/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp similarity index 98% rename from lib/SILPasses/SILCombiner/SILCombinerApplyVisitors.cpp rename to lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp index 8aa3f2d35c19d..bb866641e53a8 100644 --- a/lib/SILPasses/SILCombiner/SILCombinerApplyVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,11 +18,11 @@ #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/CFG.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/CFG.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" @@ -202,7 +202,7 @@ void PartialApplyCombiner::allocateTemporaries() { for (unsigned AI = 0, AE = Args.size(); AI != AE; ++AI) { SILValue Arg = Args[AI]; SILParameterInfo Param = Params[AI + Delta]; - if (Param.isIndirectInOut()) + if (Param.isIndirectMutating()) continue; // Create a temporary and copy the argument into it, if: // - the argument stems from an alloc_stack @@ -212,10 +212,11 @@ void PartialApplyCombiner::allocateTemporaries() { (Param.isConsumed() && Param.isIndirect())) { Builder.setInsertionPoint(PAI->getFunction()->begin()->begin()); // Create a new temporary at the beginning of a function. - auto *Tmp = Builder.createAllocStack(PAI->getLoc(), Arg.getType(), AI); + auto *Tmp = Builder.createAllocStack(PAI->getLoc(), Arg.getType(), + {/*Constant*/ true, AI}); Builder.setInsertionPoint(PAI); // Copy argument into this temporary. - Builder.createCopyAddr(PAI->getLoc(), Arg, SILValue(Tmp, 1), + Builder.createCopyAddr(PAI->getLoc(), Arg, Tmp, IsTake_t::IsNotTake, IsInitialization_t::IsInitialization); @@ -250,7 +251,7 @@ void PartialApplyCombiner::deallocateTemporaries() { } } -/// Emit code to release/destory temporaries. +/// Emit code to release/destroy temporaries. void PartialApplyCombiner::releaseTemporaries() { // Insert releases and destroy_addrs as early as possible, // because we don't want to keep objects alive longer than @@ -261,12 +262,11 @@ void PartialApplyCombiner::releaseTemporaries() { continue; for (auto *EndPoint : Lifetime.LastUsers) { Builder.setInsertionPoint(next(SILBasicBlock::iterator(EndPoint))); - auto TmpAddr = SILValue(Op.getDef(), 1); if (!TmpType.isAddressOnly(PAI->getModule())) { - auto *Load = Builder.createLoad(PAI->getLoc(), TmpAddr); + auto *Load = Builder.createLoad(PAI->getLoc(), Op); Builder.createReleaseValue(PAI->getLoc(), Load); } else { - Builder.createDestroyAddr(PAI->getLoc(), TmpAddr); + Builder.createDestroyAddr(PAI->getLoc(), Op); } } } @@ -299,8 +299,7 @@ void PartialApplyCombiner::processSingleApply(FullApplySite AI) { // If there is new temporary for this argument, use it instead. if (isa(Arg)) { if (ArgToTmp.count(Arg)) { - auto Tmp = ArgToTmp.lookup(Arg); - Op = SILValue(Tmp.getDef(), 1); + Op = ArgToTmp.lookup(Arg); } } Args.push_back(Op); @@ -539,6 +538,7 @@ void SILCombiner::eraseApply(FullApplySite FAS, const UserListTy &Users) { break; case ParameterConvention::Indirect_In_Guaranteed: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_Out: case ParameterConvention::Direct_Unowned: case ParameterConvention::Direct_Deallocating: @@ -1167,7 +1167,7 @@ bool SILCombiner::optimizeIdentityCastComposition(ApplyInst *FInverse, if (!knowHowToEmitReferenceCountInsts(FInverse)) return false; - // We need to know that the cast will succeeed. + // We need to know that the cast will succeed. if (!isCastTypeKnownToSucceed(FInverse->getArgument(0).getType(), FInverse->getModule()) || !isCastTypeKnownToSucceed(FInverse->getType(), FInverse->getModule())) @@ -1266,7 +1266,7 @@ SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) { return I; } } - if (SF->hasSemanticsString("array.uninitialized")) { + if (SF->hasSemanticsAttr("array.uninitialized")) { UserListTy Users; // If the uninitialized array is only written into then it can be removed. if (recursivelyCollectARCUsers(Users, AI)) { @@ -1286,7 +1286,7 @@ SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) { for (auto &Op : AI->getArgumentOperands()) { Arguments.push_back(Op.get()); } - // The type of the substition is the source type of the thin to thick + // The type of the substitution is the source type of the thin to thick // instruction. SILType substTy = TTTFI->getOperand().getType(); auto *NewAI = Builder.createApply(AI->getLoc(), TTTFI->getOperand(), @@ -1391,9 +1391,9 @@ SILInstruction *SILCombiner::visitTryApplyInst(TryApplyInst *AI) { SILBasicBlock *NormalBB = AI->getNormalBB(); SILBasicBlock *ErrorBB = AI->getErrorBB(); SILLocation Loc = AI->getLoc(); - eraseApply(AI, Users); Builder.setInsertionPoint(BB); Builder.setCurrentDebugScope(AI->getDebugScope()); + eraseApply(AI, Users); // Replace the try_apply with a cond_br false, which will be removed by // SimplifyCFG. We don't want to modify the CFG in SILCombine. diff --git a/lib/SILPasses/SILCombiner/SILCombinerBuiltinVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerBuiltinVisitors.cpp similarity index 98% rename from lib/SILPasses/SILCombiner/SILCombinerBuiltinVisitors.cpp rename to lib/SILOptimizer/SILCombiner/SILCombinerBuiltinVisitors.cpp index 12ea28f17a7f7..2c2d1ff49a208 100644 --- a/lib/SILPasses/SILCombiner/SILCombinerBuiltinVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerBuiltinVisitors.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,11 +18,11 @@ #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/CFG.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/CFG.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" @@ -32,7 +32,7 @@ using namespace swift::PatternMatch; SILInstruction *SILCombiner::optimizeBuiltinCompareEq(BuiltinInst *BI, bool NegateResult) { - // Canonicalize boolean comparisions. + // Canonicalize boolean comparisons. if (auto OpTy = BI->getArguments()[0].getType().getAs()) if (OpTy->isFixedWidth(1)) // cmp_eq %X, -1 -> xor (cmp_eq %X, 0), -1 diff --git a/lib/SILPasses/SILCombiner/SILCombinerCastVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp similarity index 97% rename from lib/SILPasses/SILCombiner/SILCombinerCastVisitors.cpp rename to lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp index c43ff489f8df5..d0a12e84ee6c4 100644 --- a/lib/SILPasses/SILCombiner/SILCombinerCastVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,11 +18,11 @@ #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/CFG.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/CFG.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" @@ -86,7 +86,7 @@ visitPointerToAddressInst(PointerToAddressInst *PTAI) { PTAI->getType()); } - // Turn this also into a index_addr. We generate this pattern after switching + // Turn this also into an index_addr. We generate this pattern after switching // the Word type to an explicit Int32 or Int64 in the stdlib. // // %101 = builtin "strideof_nonzero"(%84 : $@thick Int.Type) : @@ -433,7 +433,7 @@ visitUncheckedBitwiseCastInst(UncheckedBitwiseCastInst *UBCI) { return nullptr; } -/// Helper function for simplifying convertions between +/// Helper function for simplifying conversions between /// thick and objc metatypes. static SILInstruction * visitMetatypeConversionInst(SILBuilder &Builder, ConversionInst *MCI, diff --git a/lib/SILPasses/SILCombiner/SILCombinerMiscVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp similarity index 90% rename from lib/SILPasses/SILCombiner/SILCombinerMiscVisitors.cpp rename to lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp index 3a833c9b477cf..c05064177dca4 100644 --- a/lib/SILPasses/SILCombiner/SILCombinerMiscVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp @@ -1,8 +1,8 @@ -//===---- SILCombinerMiscVisitors.cpp -------------------------------------===// +//===--- SILCombinerMiscVisitors.cpp --------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,12 +18,12 @@ #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/CFG.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/Devirtualize.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/CFG.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/Devirtualize.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" @@ -168,20 +168,20 @@ namespace { /// /// We detect this pattern /// %0 = alloc_stack $LogicValue -/// %1 = init_existential_addr %0#1 : $*LogicValue, $*Bool +/// %1 = init_existential_addr %0 : $*LogicValue, $*Bool /// ... /// use of %1 /// ... -/// destroy_addr %0#1 : $*LogicValue -/// dealloc_stack %0#0 : $*@local_storage LogicValue +/// destroy_addr %0 : $*LogicValue +/// dealloc_stack %0 : $*LogicValue /// /// At the same we time also look for dead alloc_stack live ranges that are only /// copied into. /// /// %0 = alloc_stack /// copy_addr %src, %0 -/// destroy_addr %0#1 : $*LogicValue -/// dealloc_stack %0#0 : $*@local_storage LogicValue +/// destroy_addr %0 : $*LogicValue +/// dealloc_stack %0 : $*LogicValue struct AllocStackAnalyzer : SILInstructionVisitor { /// The alloc_stack that we are analyzing. AllocStackInst *ASI; @@ -232,7 +232,7 @@ struct AllocStackAnalyzer : SILInstructionVisitor { void visitDeallocStackInst(DeallocStackInst *I) {} void visitInitExistentialAddrInst(InitExistentialAddrInst *I) { - // If we have already seen an init_existential_addr, we can not + // If we have already seen an init_existential_addr, we cannot // optimize. This is because we only handle the single init_existential_addr // case. if (IEI || HaveSeenCopyInto) { @@ -243,7 +243,7 @@ struct AllocStackAnalyzer : SILInstructionVisitor { } void visitOpenExistentialAddrInst(OpenExistentialAddrInst *I) { - // If we have already seen an open_existential_addr, we can not + // If we have already seen an open_existential_addr, we cannot // optimize. This is because we only handle the single open_existential_addr // case. if (OEI) { @@ -251,7 +251,7 @@ struct AllocStackAnalyzer : SILInstructionVisitor { return; } - // Make sure tht the open_existential does not have any uses except + // Make sure that the open_existential does not have any uses except // destroy_addr. for (auto *Use : getNonDebugUses(*I)) { if (!isa(Use->getUser())) { @@ -297,10 +297,9 @@ SILInstruction *SILCombiner::visitAllocStackInst(AllocStackInst *AS) { // init_existential_addr then we can promote the allocation of the init // existential. if (IEI && !OEI) { - auto *ConcAlloc = - Builder.createAllocStack(AS->getLoc(), IEI->getLoweredConcreteType(), - AS->getVarInfo().getArgNo()); - SILValue(IEI, 0).replaceAllUsesWith(ConcAlloc->getAddressResult()); + auto *ConcAlloc = Builder.createAllocStack( + AS->getLoc(), IEI->getLoweredConcreteType(), AS->getVarInfo()); + SILValue(IEI, 0).replaceAllUsesWith(ConcAlloc); eraseInstFromFunction(*IEI); for (auto UI = AS->use_begin(), UE = AS->use_end(); UI != UE;) { @@ -308,7 +307,7 @@ SILInstruction *SILCombiner::visitAllocStackInst(AllocStackInst *AS) { ++UI; if (auto *DA = dyn_cast(Op->getUser())) { Builder.setInsertionPoint(DA); - Builder.createDestroyAddr(DA->getLoc(), SILValue(ConcAlloc, 1)); + Builder.createDestroyAddr(DA->getLoc(), ConcAlloc); eraseInstFromFunction(*DA); continue; } @@ -493,7 +492,7 @@ SILInstruction *SILCombiner::visitRetainValueInst(RetainValueInst *RVI) { return Builder.createStrongRetain(RVI->getLoc(), Operand); } - // RetainValueInst of a trivial type is a no-op + use propogation. + // RetainValueInst of a trivial type is a no-op + use propagation. if (OperandTy.isTrivial(RVI->getModule())) { return eraseInstFromFunction(*RVI); } @@ -509,7 +508,7 @@ SILInstruction *SILCombiner::visitRetainValueInst(RetainValueInst *RVI) { // // Due to the matching pairs being in different basic blocks, the ARC // Optimizer (which is currently local to one basic block does not handle - // it). But that does not mean that we can not eliminate this pair with a + // it). But that does not mean that we cannot eliminate this pair with a // peephole. // If we are not the first instruction in this basic block... @@ -587,7 +586,7 @@ SILInstruction *SILCombiner::visitStrongRetainInst(StrongRetainInst *SRI) { // // Due to the matching pairs being in different basic blocks, the ARC // Optimizer (which is currently local to one basic block does not handle - // it). But that does not mean that we can not eliminate this pair with a + // it). But that does not mean that we cannot eliminate this pair with a // peephole. // If we are not the first instruction in this basic block... @@ -667,7 +666,7 @@ SILCombiner::visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI) { if (SI->getDest() == IEAI->getOperand()) return nullptr; } - // Allow all instructions inbetween, which don't have any dependency to + // Allow all instructions in between, which don't have any dependency to // the store. if (AA->mayWriteToMemory(&*II, IEAI->getOperand())) return nullptr; @@ -706,7 +705,7 @@ SILCombiner::visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI) { if (SI->getDest() == IEAI->getOperand()) return nullptr; } - // Allow all instructions inbetween, which don't have any dependency to + // Allow all instructions in between, which don't have any dependency to // the store. if (AA->mayWriteToMemory(&*II, IEAI->getOperand())) return nullptr; @@ -761,6 +760,8 @@ SILCombiner::visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI) { SILBasicBlock::iterator II = IEAI->getIterator(); StoreInst *SI = nullptr; InitEnumDataAddrInst *DataAddrInst = nullptr; + ApplyInst *AI = nullptr; + Operand *EnumInitOperand = nullptr; for (;;) { if (II == IEAI->getParent()->begin()) return nullptr; @@ -772,24 +773,74 @@ SILCombiner::visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI) { DataAddrInst = dyn_cast(SI->getDest().getDef()); if (DataAddrInst && DataAddrInst->getOperand() == IEAI->getOperand()) break; + SI = nullptr; + } + // Check whether we have an apply initializing the enum. + // %iedai = init_enum_data_addr %enum_addr + // = apply(%iedai,...) + // inject_enum_addr %enum_addr + // + // We can localize the store to an alloc_stack. + // Allowing us to perform the same optimization as for the store. + // + // %alloca = alloc_stack + // apply(%alloca,...) + // %load = load %alloca + // %1 = enum $EnumType, $EnumType.case, %load + // store %1 to %nopayload_addr + // + if ((AI = dyn_cast(&*II))) { + auto Params = AI->getSubstCalleeType()->getParameters(); + unsigned ArgIdx = 0; + for (auto &Opd : AI->getArgumentOperands()) { + // Found an apply that initializes the enum. We can optimize this by + // localizing the initialization to an alloc_stack and loading from it. + DataAddrInst = dyn_cast(Opd.get().getDef()); + if (DataAddrInst && DataAddrInst->getOperand() == IEAI->getOperand() && + Params[ArgIdx].getConvention() == + ParameterConvention::Indirect_Out) { + EnumInitOperand = &Opd; + break; + } + ++ArgIdx; + } + // We found an enum initialization. + if (EnumInitOperand) + break; + AI = nullptr; } - // Allow all instructions inbetween, which don't have any dependency to - // the store. - if (AA->mayWriteToMemory(&*II, IEAI->getOperand())) - return nullptr; } // Found the store to this enum payload. Check if the store is the only use. if (!DataAddrInst->hasOneUse()) return nullptr; - // In that case, create the payload enum/store. - EnumInst *E = + if (SI) { + // In that case, create the payload enum/store. + EnumInst *E = Builder.createEnum(DataAddrInst->getLoc(), SI->getSrc(), - DataAddrInst->getElement(), - DataAddrInst->getOperand().getType().getObjectType()); + DataAddrInst->getElement(), + DataAddrInst->getOperand().getType().getObjectType()); + Builder.createStore(DataAddrInst->getLoc(), E, DataAddrInst->getOperand()); + // Cleanup. + eraseInstFromFunction(*SI); + eraseInstFromFunction(*DataAddrInst); + return eraseInstFromFunction(*IEAI); + } + + assert(AI && "Must have an apply"); + // Localize the address access. + Builder.setInsertionPoint(AI); + auto *AllocStack = Builder.createAllocStack(DataAddrInst->getLoc(), + EnumInitOperand->get().getType()); + EnumInitOperand->set(AllocStack); + Builder.setInsertionPoint(std::next(SILBasicBlock::iterator(AI))); + SILValue Load(Builder.createLoad(DataAddrInst->getLoc(), AllocStack), + 0); + EnumInst *E = Builder.createEnum( + DataAddrInst->getLoc(), Load, DataAddrInst->getElement(), + DataAddrInst->getOperand().getType().getObjectType()); Builder.createStore(DataAddrInst->getLoc(), E, DataAddrInst->getOperand()); - // Cleanup. - eraseInstFromFunction(*SI); + Builder.createDeallocStack(DataAddrInst->getLoc(), AllocStack); eraseInstFromFunction(*DataAddrInst); return eraseInstFromFunction(*IEAI); } @@ -830,7 +881,7 @@ visitUncheckedTakeEnumDataAddrInst(UncheckedTakeEnumDataAddrInst *TEDAI) { if (TEDAI->use_empty()) return nullptr; - // If our enum type is address only, we can not do anything here. The key + // If our enum type is address only, we cannot do anything here. The key // thing to remember is that an enum is address only if any of its cases are // address only. So we *could* have a loadable payload resulting from the // TEDAI without the TEDAI being loadable itself. @@ -911,7 +962,7 @@ SILInstruction *SILCombiner::visitCondBranchInst(CondBranchInst *CBI) { if (!EnumOperandTy.isLoadable(SEI->getModule())) return nullptr; - // Result of the selec_enum should be a boolean. + // Result of the select_enum should be a boolean. if (SEI->getType() != CBI->getCondition().getType()) return nullptr; @@ -1024,7 +1075,7 @@ SILInstruction *SILCombiner::visitFixLifetimeInst(FixLifetimeInst *FLI) { Builder.setCurrentDebugScope(FLI->getDebugScope()); if (auto *AI = dyn_cast(FLI->getOperand())) { if (FLI->getOperand().getType().isLoadable(FLI->getModule())) { - auto Load = Builder.createLoad(FLI->getLoc(), SILValue(AI, 1)); + auto Load = Builder.createLoad(FLI->getLoc(), AI); return Builder.createFixLifetime(FLI->getLoc(), SILValue(Load, 0)); } } diff --git a/lib/SILPasses/Scalar/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp similarity index 77% rename from lib/SILPasses/Scalar/AllocBoxToStack.cpp rename to lib/SILOptimizer/Transforms/AllocBoxToStack.cpp index d060843d2e925..e24219fdc56bb 100644 --- a/lib/SILPasses/Scalar/AllocBoxToStack.cpp +++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,14 +11,14 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "allocbox-to-stack" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/Dominance.h" #include "swift/SIL/Mangle.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILCloner.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" @@ -36,7 +36,7 @@ STATISTIC(NumStackPromoted, "Number of alloc_box's promoted to the stack"); /// This is a list we use to store a set of indices. We create the set by /// sorting, uniqueing at the appropriate time. The reason why it makes sense to /// just use a sorted vector with std::count is because generally functions do -/// not have that many arguments and even less dead arguments. +/// not have that many arguments and even fewer promoted arguments. using ParamIndexList = llvm::SmallVector; static SILInstruction* findUnexpectedBoxUse(SILValue Box, @@ -278,7 +278,7 @@ static SILArgument *getParameterForOperand(SILFunction *F, Operand *O) { } /// Return a pointer to the SILFunction called by Call if we can -/// determine which funciton that is, and we have a body for that +/// determine which function that is, and we have a body for that /// function. Otherwise return nullptr. static SILFunction *getFunctionBody(SILInstruction *Call) { if (auto *FRI = getDirectCallee(Call)) @@ -305,7 +305,7 @@ static bool partialApplyArgumentEscapes(Operand *O) { /// checkPartialApplyBody - Check the body of a partial apply to see /// if the box pointer argument passed to it has uses that would -/// disqualify it from being protmoted to a stack location. Return +/// disqualify it from being promoted to a stack location. Return /// true if this partial apply will not block our promoting the box. static bool checkPartialApplyBody(Operand *O) { SILFunction *F = getFunctionBody(O->getUser()); @@ -315,11 +315,11 @@ static bool checkPartialApplyBody(Operand *O) { // We don't actually use these because we're not recursively // rewriting the partial applies we find. - llvm::SmallVector ElidedOperands; + llvm::SmallVector PromotedOperands; auto Param = SILValue(getParameterForOperand(F, O)); return !findUnexpectedBoxUse(Param, /* examinePartialApply = */ false, /* inAppliedFunction = */ true, - ElidedOperands); + PromotedOperands); } @@ -331,13 +331,13 @@ static bool checkPartialApplyBody(Operand *O) { static SILInstruction* findUnexpectedBoxUse(SILValue Box, bool examinePartialApply, bool inAppliedFunction, - llvm::SmallVectorImpl &ElidedOperands) { + llvm::SmallVectorImpl &PromotedOperands) { assert((Box.getType().is() || Box.getType() == SILType::getNativeObjectType(Box.getType().getASTContext())) && "Expected an object pointer!"); - llvm::SmallVector LocalElidedOperands; + llvm::SmallVector LocalPromotedOperands; // Scan all of the uses of the retain count value, collecting all // the releases and validating that we don't have an unexpected @@ -347,7 +347,9 @@ static SILInstruction* findUnexpectedBoxUse(SILValue Box, // Retains and releases are fine. Deallocs are fine if we're not // examining a function that the alloc_box was passed into. + // Projections are fine as well. if (isa(User) || isa(User) || + isa(User) || (!inAppliedFunction && isa(User))) continue; @@ -357,26 +359,27 @@ static SILInstruction* findUnexpectedBoxUse(SILValue Box, if (auto *PAI = dyn_cast(User)) if (examinePartialApply && checkPartialApplyBody(UI) && !partialApplyEscapes(PAI, /* examineApply = */ true)) { - LocalElidedOperands.push_back(UI); + LocalPromotedOperands.push_back(UI); continue; } return User; } - ElidedOperands.append(LocalElidedOperands.begin(), LocalElidedOperands.end()); + PromotedOperands.append(LocalPromotedOperands.begin(), + LocalPromotedOperands.end()); return nullptr; } /// canPromoteAllocBox - Can we promote this alloc_box to an alloc_stack? static bool canPromoteAllocBox(AllocBoxInst *ABI, - llvm::SmallVectorImpl &ElidedOperands) { + llvm::SmallVectorImpl &PromotedOperands){ // Scan all of the uses of the address of the box to see if any // disqualifies the box from being promoted to the stack. if (auto *User = findUnexpectedBoxUse(ABI->getContainerResult(), /* examinePartialApply = */ true, /* inAppliedFunction = */ false, - ElidedOperands)) { + PromotedOperands)) { (void)User; // Otherwise, we have an unexpected use. DEBUG(llvm::dbgs() << "*** Failed to promote alloc_box in @" @@ -401,25 +404,25 @@ static bool rewriteAllocBoxAsAllocStack(AllocBoxInst *ABI, return false; // Promote this alloc_box to an alloc_stack. Insert the alloc_stack - // at the beginning of the funtion. + // at the beginning of the function. auto &Entry = ABI->getFunction()->front(); SILBuilder BuildAlloc(&Entry, Entry.begin()); BuildAlloc.setCurrentDebugScope(ABI->getDebugScope()); auto *ASI = BuildAlloc.createAllocStack(ABI->getLoc(), ABI->getElementType(), - ABI->getVarInfo().getArgNo()); + ABI->getVarInfo()); // Replace all uses of the address of the box's contained value with // the address of the stack location. - ABI->getAddressResult().replaceAllUsesWith(ASI->getAddressResult()); + ABI->getAddressResult().replaceAllUsesWith(ASI); // Check to see if the alloc_box was used by a mark_uninitialized instruction. // If so, any uses of the pointer result need to keep using the MUI, not the // alloc_stack directly. If we don't do this, DI will miss the uses. - SILValue PointerResult = ASI->getAddressResult(); - for (auto UI : ASI->getAddressResult().getUses()) + SILValue PointerResult = ASI; + for (auto UI : ASI->getUses()) if (auto *MUI = dyn_cast(UI->getUser())) { - assert(ASI->getAddressResult().hasOneUse() && - "alloc_stack used by mark_uninialized, but not exclusively!"); + assert(ASI->hasOneUse() && + "alloc_stack used by mark_uninitialized, but not exclusively!"); PointerResult = MUI; break; } @@ -441,7 +444,7 @@ static bool rewriteAllocBoxAsAllocStack(AllocBoxInst *ABI, for (auto Return : Returns) { SILBuilderWithScope BuildDealloc(Return); - BuildDealloc.createDeallocStack(Loc, ASI->getContainerResult()); + BuildDealloc.createDeallocStack(Loc, ASI); } // Remove any retain and release instructions. Since all uses of result #1 @@ -461,14 +464,13 @@ static bool rewriteAllocBoxAsAllocStack(AllocBoxInst *ABI, namespace { /// \brief A SILCloner subclass which clones a closure function while -/// removing some of the parameters, which are either completely dead -/// or only used in retains and releases (which will not be cloned). -class DeadParamCloner : public SILClonerWithScopes { +/// promoting some of its box parameters to stack addresses. +class PromotedParamCloner : public SILClonerWithScopes { public: - friend class SILVisitor; - friend class SILCloner; + friend class SILVisitor; + friend class SILCloner; - DeadParamCloner(SILFunction *Orig, ParamIndexList &DeadParamIndices, + PromotedParamCloner(SILFunction *Orig, ParamIndexList &PromotedParamIndices, llvm::StringRef ClonedName); void populateCloned(); @@ -477,48 +479,49 @@ class DeadParamCloner : public SILClonerWithScopes { private: static SILFunction *initCloned(SILFunction *Orig, - ParamIndexList &DeadParamIndices, + ParamIndexList &PromotedParamIndices, llvm::StringRef ClonedName); void visitStrongReleaseInst(StrongReleaseInst *Inst); void visitStrongRetainInst(StrongRetainInst *Inst); + void visitProjectBoxInst(ProjectBoxInst *Inst); SILFunction *Orig; - ParamIndexList &DeadParamIndices; + ParamIndexList &PromotedParamIndices; - // The values in the original function that are either dead or only - // used in retains and releases. - llvm::SmallSet DeadParameters; + // The values in the original function that are promoted to stack + // references. + llvm::SmallSet PromotedParameters; }; } // end anonymous namespace. -DeadParamCloner::DeadParamCloner(SILFunction *Orig, - ParamIndexList &DeadParamIndices, +PromotedParamCloner::PromotedParamCloner(SILFunction *Orig, + ParamIndexList &PromotedParamIndices, llvm::StringRef ClonedName) - : SILClonerWithScopes(*initCloned(Orig, DeadParamIndices, + : SILClonerWithScopes(*initCloned(Orig, + PromotedParamIndices, ClonedName)), - Orig(Orig), DeadParamIndices(DeadParamIndices) { + Orig(Orig), PromotedParamIndices(PromotedParamIndices) { assert(Orig->getDebugScope()->SILFn != getCloned()->getDebugScope()->SILFn); } -static void getClonedName(SILFunction *F, - ParamIndexList &DeadParamIndices, - llvm::SmallString<64> &Name) { - llvm::raw_svector_ostream buffer(Name); - Mangle::Mangler M(buffer); - auto P = Mangle::SpecializationPass::AllocBoxToStack; - Mangle::FunctionSignatureSpecializationMangler FSSM(P, M, F); - for (unsigned i : DeadParamIndices) - FSSM.setArgumentDead(i); +static std::string getClonedName(SILFunction *F, + ParamIndexList &PromotedParamIndices) { + Mangle::Mangler M; + auto P = SpecializationPass::AllocBoxToStack; + FunctionSignatureSpecializationMangler FSSM(P, M, F); + for (unsigned i : PromotedParamIndices) + FSSM.setArgumentBoxToStack(i); FSSM.mangle(); + return M.finalize(); } /// \brief Create the function corresponding to the clone of the -/// original closure with the signature modified to reflect removed -/// parameters (which are specified by DeadParamIndices). +/// original closure with the signature modified to reflect promoted +/// parameters (which are specified by PromotedParamIndices). SILFunction* -DeadParamCloner::initCloned(SILFunction *Orig, - ParamIndexList &DeadParamIndices, +PromotedParamCloner::initCloned(SILFunction *Orig, + ParamIndexList &PromotedParamIndices, llvm::StringRef ClonedName) { SILModule &M = Orig->getModule(); @@ -528,13 +531,21 @@ DeadParamCloner::initCloned(SILFunction *Orig, SILFunctionType *OrigFTI = Orig->getLoweredFunctionType(); unsigned Index = 0; for (auto ¶m : OrigFTI->getParameters()) { - if (!std::count(DeadParamIndices.begin(), DeadParamIndices.end(), Index)) + if (std::count(PromotedParamIndices.begin(), PromotedParamIndices.end(), + Index)) { + auto paramTy = param.getType()->castTo() + ->getBoxedAddressType(); + auto promotedParam = SILParameterInfo(paramTy.getSwiftRValueType(), + ParameterConvention::Indirect_InoutAliasable); + ClonedInterfaceArgTys.push_back(promotedParam); + } else { ClonedInterfaceArgTys.push_back(param); + } ++Index; } // Create the new function type for the cloned function with some of - // the parameters removed. + // the parameters promoted. auto ClonedTy = SILFunctionType::get(OrigFTI->getGenericSignature(), OrigFTI->getExtInfo(), @@ -549,14 +560,14 @@ DeadParamCloner::initCloned(SILFunction *Orig, assert((Orig->isTransparent() || Orig->isBare() || Orig->getDebugScope()) && "SILFunction missing DebugScope"); assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned"); - auto Fn = - SILFunction::create(M, SILLinkage::Shared, ClonedName, ClonedTy, - Orig->getContextGenericParams(), Orig->getLocation(), - Orig->isBare(), IsNotTransparent, Orig->isFragile(), - Orig->isThunk(), - Orig->getClassVisibility(), Orig->getInlineStrategy(), - Orig->getEffectsKind(), Orig, Orig->getDebugScope()); - Fn->setSemanticsAttr(Orig->getSemanticsAttr()); + auto *Fn = M.getOrCreateFunction( + SILLinkage::Shared, ClonedName, ClonedTy, Orig->getContextGenericParams(), + Orig->getLocation(), Orig->isBare(), IsNotTransparent, Orig->isFragile(), + Orig->isThunk(), Orig->getClassVisibility(), Orig->getInlineStrategy(), + Orig->getEffectsKind(), Orig, Orig->getDebugScope()); + for (auto &Attr : Orig->getSemanticsAttrs()) { + Fn->addSemanticsAttr(Attr); + } Fn->setDeclCtx(Orig->getDeclContext()); return Fn; } @@ -564,7 +575,7 @@ DeadParamCloner::initCloned(SILFunction *Orig, /// \brief Populate the body of the cloned closure, modifying instructions as /// necessary to take into consideration the removed parameters. void -DeadParamCloner::populateCloned() { +PromotedParamCloner::populateCloned() { SILFunction *Cloned = getCloned(); SILModule &M = Cloned->getModule(); @@ -574,13 +585,27 @@ DeadParamCloner::populateCloned() { unsigned ArgNo = 0; auto I = OrigEntryBB->bbarg_begin(), E = OrigEntryBB->bbarg_end(); while (I != E) { - if (!std::count(DeadParamIndices.begin(), DeadParamIndices.end(), ArgNo)) { + if (std::count(PromotedParamIndices.begin(), + PromotedParamIndices.end(), ArgNo)) { + // Create a new argument with the promoted type. + auto promotedTy = (*I)->getType().castTo() + ->getBoxedAddressType(); + auto promotedArg = new (M) + SILArgument(ClonedEntryBB, promotedTy, (*I)->getDecl()); + PromotedParameters.insert(*I); + + // Map any projections of the box to the promoted argument. + for (auto use : (*I)->getUses()) { + if (auto project = dyn_cast(use->getUser())) { + ValueMap.insert(std::make_pair(project, promotedArg)); + } + } + + } else { // Create a new argument which copies the original argument. SILValue MappedValue = new (M) SILArgument(ClonedEntryBB, (*I)->getType(), (*I)->getDecl()); ValueMap.insert(std::make_pair(*I, MappedValue)); - } else { - DeadParameters.insert(SILValue(*I)); } ++ArgNo; ++I; @@ -600,25 +625,36 @@ DeadParamCloner::populateCloned() { } /// \brief Handle a strong_release instruction during cloning of a closure; if -/// it is a strong release of a promoted box argument, then it is replaced wit +/// it is a strong release of a promoted box argument, then it is replaced with /// a ReleaseValue of the new object type argument, otherwise it is handled /// normally. void -DeadParamCloner::visitStrongReleaseInst(StrongReleaseInst *Inst) { - // If it's a release of a dead parameter, just drop the instruction. - if (DeadParameters.count(Inst->getOperand())) +PromotedParamCloner::visitStrongReleaseInst(StrongReleaseInst *Inst) { + // If it's a release of a promoted parameter, just drop the instruction. + if (PromotedParameters.count(Inst->getOperand())) return; - SILCloner::visitStrongReleaseInst(Inst); + SILCloner::visitStrongReleaseInst(Inst); } void -DeadParamCloner::visitStrongRetainInst(StrongRetainInst *Inst) { - // If it's a retain of a dead parameter, just drop the instruction. - if (DeadParameters.count(Inst->getOperand())) +PromotedParamCloner::visitStrongRetainInst(StrongRetainInst *Inst) { + // If it's a retain of a promoted parameter, just drop the instruction. + if (PromotedParameters.count(Inst->getOperand())) return; - SILCloner::visitStrongRetainInst(Inst); + SILCloner::visitStrongRetainInst(Inst); +} + +void +PromotedParamCloner::visitProjectBoxInst(ProjectBoxInst *Inst) { + // If it's a projection of a promoted parameter, drop the instruction. + // Its uses will be replaced by the promoted address. + // and replace its uses with + if (PromotedParameters.count(Inst->getOperand())) + return; + + SILCloner::visitProjectBoxInst(Inst); } static void emitStrongReleaseAfter(SILValue V, SILInstruction *I) { @@ -648,8 +684,7 @@ LifetimeTracker::EndpointRange LifetimeTracker::getEndpoints() { if (TheValue->hasOneUse()) { Lifetime = ValueLifetime(); Lifetime->LastUsers.insert(TheValue->use_begin().getUser()); - } - else { + } else { ValueLifetimeAnalysis VLA(TheValue); Lifetime = VLA.computeFromDirectUses(); } @@ -657,19 +692,18 @@ LifetimeTracker::EndpointRange LifetimeTracker::getEndpoints() { return EndpointRange(Lifetime->LastUsers.begin(), Lifetime->LastUsers.end()); } -/// Specialize a partial_apply by removing the parameters indicated by -/// indices. We expect these parameters to be either dead, or used -/// only by retains and releases. +/// Specialize a partial_apply by promoting the parameters indicated by +/// indices. We expect these parameters to be replaced by stack address +/// references. static PartialApplyInst * specializePartialApply(PartialApplyInst *PartialApply, - ParamIndexList &DeadParamIndices) { + ParamIndexList &PromotedParamIndices) { auto *FRI = cast(PartialApply->getCallee()); assert(FRI && "Expected a direct partial_apply!"); auto *F = FRI->getReferencedFunction(); assert(F && "Expected a referenced function!"); - llvm::SmallString<64> ClonedName; - getClonedName(F, DeadParamIndices, ClonedName); + std::string ClonedName = getClonedName(F, PromotedParamIndices); auto &M = PartialApply->getModule(); @@ -678,7 +712,7 @@ specializePartialApply(PartialApplyInst *PartialApply, ClonedFn = PrevFn; } else { // Clone the function the existing partial_apply references. - DeadParamCloner Cloner(F, DeadParamIndices, ClonedName); + PromotedParamCloner Cloner(F, PromotedParamIndices, ClonedName); Cloner.populateCloned(); ClonedFn = Cloner.getCloned(); } @@ -688,10 +722,10 @@ specializePartialApply(PartialApplyInst *PartialApply, LifetimeTracker Lifetime(PartialApply); - // Only use the arguments that are not dead. + // Promote the arguments that need promotion. for (auto &O : PartialApply->getArgumentOperands()) { auto ParamIndex = getParameterIndexForOperand(&O); - if (!std::count(DeadParamIndices.begin(), DeadParamIndices.end(), + if (!std::count(PromotedParamIndices.begin(), PromotedParamIndices.end(), ParamIndex)) { Args.push_back(O.get()); continue; @@ -699,13 +733,27 @@ specializePartialApply(PartialApplyInst *PartialApply, auto Endpoints = Lifetime.getEndpoints(); - // If this argument is marked dead, it is a box that we're - // removing from the partial_apply because we've proven we can - // keep this value on the stack. The partial_apply has ownership + // If this argument is promoted, it is a box that we're + // turning into an address because we've proven we can + // keep this value on the stack. The partial_apply had ownership // of this box so we must now release it explicitly when the // partial_apply is released. - assert(cast(O.get())->getContainerResult() == O.get() && - "Expected dead param to be an alloc_box container!"); + auto box = cast(O.get()); + assert(box->getContainerResult() == O.get() && + "Expected promoted param to be an alloc_box container!"); + + // If the box address has a MUI, route accesses through it so DI still + // works. + auto promoted = box->getAddressResult(); + for (auto use : promoted->getUses()) { + if (auto MUI = dyn_cast(use->getUser())) { + assert(promoted.hasOneUse() && "box value used by mark_uninitialized" + " but not exclusively!"); + promoted = MUI; + break; + } + } + Args.push_back(promoted); // If the partial_apply is dead, insert a release after it. if (Endpoints.begin() == Endpoints.end()) { @@ -739,13 +787,13 @@ specializePartialApply(PartialApplyInst *PartialApply, } static void -rewritePartialApplies(llvm::SmallVectorImpl &ElidedOperands) { +rewritePartialApplies(llvm::SmallVectorImpl &PromotedOperands) { llvm::DenseMap IndexMap; ParamIndexList Indices; // Build a map from partial_apply to the indices of the operands - // that will not be in our rewritten version. - for (auto *O : ElidedOperands) { + // that will be promoted in our rewritten version. + for (auto *O : PromotedOperands) { auto ParamIndexNumber = getParameterIndexForOperand(O); Indices.clear(); @@ -785,11 +833,11 @@ rewritePartialApplies(llvm::SmallVectorImpl &ElidedOperands) { static unsigned rewritePromotedBoxes(llvm::SmallVectorImpl &Promoted, - llvm::SmallVectorImpl &ElidedOperands, + llvm::SmallVectorImpl &PromotedOperands, llvm::SmallVectorImpl &Returns) { // First we'll rewrite any partial applies that we can to remove the // box container pointer from the operands. - rewritePartialApplies(ElidedOperands); + rewritePartialApplies(PromotedOperands); unsigned Count = 0; auto rend = Promoted.rend(); @@ -808,24 +856,22 @@ class AllocBoxToStack : public SILFunctionTransform { /// The entry point to the transformation. void run() override { llvm::SmallVector Promotable; - llvm::SmallVector ElidedOperands; + llvm::SmallVector PromotedOperands; llvm::SmallVector Returns; for (auto &BB : *getFunction()) { auto *Term = BB.getTerminator(); - if (isa(Term) || - isa(Term) || - isa(Term)) + if (isa(Term) || isa(Term)) Returns.push_back(Term); for (auto &I : BB) if (auto *ABI = dyn_cast(&I)) - if (canPromoteAllocBox(ABI, ElidedOperands)) + if (canPromoteAllocBox(ABI, PromotedOperands)) Promotable.push_back(ABI); } if (!Promotable.empty()) { - auto Count = rewritePromotedBoxes(Promotable, ElidedOperands, Returns); + auto Count = rewritePromotedBoxes(Promotable, PromotedOperands, Returns); NumStackPromoted += Count; // TODO: Update the call graph instead of invalidating it. diff --git a/lib/SILPasses/Scalar/ArrayCountPropagation.cpp b/lib/SILOptimizer/Transforms/ArrayCountPropagation.cpp similarity index 94% rename from lib/SILPasses/Scalar/ArrayCountPropagation.cpp rename to lib/SILOptimizer/Transforms/ArrayCountPropagation.cpp index f1826d6087517..31a8df7cbb773 100644 --- a/lib/SILPasses/Scalar/ArrayCountPropagation.cpp +++ b/lib/SILOptimizer/Transforms/ArrayCountPropagation.cpp @@ -1,8 +1,8 @@ -//===------ ArrayCountPropagation.cpp - Propagate the count of arrays -----===// +//===--- ArrayCountPropagation.cpp - Propagate the count of arrays --------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -13,9 +13,9 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILAnalysis/ArraySemantic.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" #include "swift/SIL/DebugUtils.h" using namespace swift; @@ -91,7 +91,7 @@ bool ArrayAllocation::propagate() { return propagateCountToUsers(); } -/// Check that we have a array initialization call with a known count. +/// Check that we have an array initialization call with a known count. /// /// The returned array value is known not to be aliased since it was just /// allocated. @@ -120,7 +120,6 @@ bool ArrayAllocation::analyseArrayValueUses() { static bool doesNotChangeArrayCount(ArraySemanticsCall &C) { switch (C.getKind()) { default: return false; - case ArrayCallKind::kArrayPropsIsNative: case ArrayCallKind::kArrayPropsIsNativeTypeChecked: case ArrayCallKind::kCheckSubscript: case ArrayCallKind::kCheckIndex: diff --git a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp new file mode 100644 index 0000000000000..dccda3b1fc3c5 --- /dev/null +++ b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp @@ -0,0 +1,306 @@ +//===--- ArrayElementValuePropagation.cpp - Propagate values of arrays ----===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +#define DEBUG_TYPE "array-element-propagation" + +#include "llvm/ADT/SetVector.h" +#include "swift/SIL/SILBasicBlock.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SIL/DebugUtils.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "llvm/ADT/SmallVector.h" + +using namespace swift; + +/// Propagate the elements of array values to calls of the array's get_element +/// method. +/// +/// Array literal construction and array initialization of array values +/// associates element values with the array value. These values can be +/// propagated to the get_element method if we can prove that the array value +/// has not changed until reading the array value's element. +/// +/// Propagation of the elements of one array allocation. +/// +/// We propagate the elements associated with calls of +/// +/// * Array.init(count:repeatedValue:) +/// The 'repeatedValue'. +/// TODO: this is not yet implemented. +/// +/// * Array._adoptStorage(storage:count:) +/// The stores on the returned array element buffer pointer. +/// +namespace { +class ArrayAllocation { + /// The array allocation call. + ApplyInst *Alloc; + /// The array value returned by the allocation call. + SILValue ArrayValue; + + /// The pointer to the returned array element buffer pointer. + SILValue ElementBuffer; + + // The calls to Array get_element that use this array allocation. + llvm::SmallSetVector GetElementCalls; + llvm::DenseMap ElementValueMap; + + // Array get_element calls and their matching array element value for later + // replacement. + llvm::SmallVectorImpl> &ReplacementMap; + + ArrayAllocation( + ApplyInst *AI, + llvm::SmallVectorImpl> &Replacements) + : Alloc(AI), ReplacementMap(Replacements) {} + + bool findValueReplacements(); + bool isInitializationWithKnownElements(); + bool mapInitializationStores(); + bool analyseArrayValueUses(); + bool recursivelyCollectUses(ValueBase *Def); + bool collectForwardableValues(); + +public: + + /// Find a set of get_element calls that can be replace by the initialization + /// value of the array allocation call. + /// + /// Returns true if an access can be replaced. The replacements are stored in + /// the \p ReplacementMap. + static bool findValueReplacements( + ApplyInst *Inst, + llvm::SmallVectorImpl> &Replacements) { + return ArrayAllocation(Inst, Replacements).findValueReplacements(); + } +}; +} + + +/// Map the indices of array element initialization stores to their values. +bool ArrayAllocation::mapInitializationStores() { + assert(ElementBuffer && + "Must have identified an array element storage pointer"); + + // Match initialization stores. + // %83 = struct_extract %element_buffer : $UnsafeMutablePointer + // %84 = pointer_to_address %83 : $Builtin.RawPointer to $*Int + // store %85 to %84 : $*Int + // %87 = integer_literal $Builtin.Word, 1 + // %88 = index_addr %84 : $*Int, %87 : $Builtin.Word + // store %some_value to %88 : $*Int + + auto *UnsafeMutablePointerExtract = + dyn_cast_or_null(getSingleNonDebugUser(ElementBuffer)); + if (!UnsafeMutablePointerExtract) + return false; + auto *PointerToAddress = dyn_cast_or_null( + getSingleNonDebugUser(*UnsafeMutablePointerExtract)); + if (!PointerToAddress) + return false; + + // Match the stores. We can have either a store directly to the address or + // to an index_addr projection. + for (auto *Op : PointerToAddress->getUses()) { + auto *Inst = Op->getUser(); + + // Store to the base. + auto *SI = dyn_cast(Inst); + if (SI && SI->getDest() == SILValue(PointerToAddress, 0)) { + // We have already seen an entry for this index bail. + if (ElementValueMap.count(0)) + return false; + ElementValueMap[0] = SI->getSrc(); + continue; + } else if (SI) + return false; + + // Store an index_addr projection. + auto *IndexAddr = dyn_cast(Inst); + if (!IndexAddr) + return false; + SI = dyn_cast_or_null(getSingleNonDebugUser(*IndexAddr)); + if (!SI || SI->getDest().getDef() != IndexAddr) + return false; + auto *Index = dyn_cast(IndexAddr->getIndex()); + if (!Index) + return false; + auto IndexVal = Index->getValue(); + // Let's not blow up our map. + if (IndexVal.getActiveBits() > 16) + return false; + // Already saw an entry. + if (ElementValueMap.count(IndexVal.getZExtValue())) + return false; + + ElementValueMap[IndexVal.getZExtValue()] = SI->getSrc(); + } + return !ElementValueMap.empty(); +} + +/// Check that we have an array initialization call with known elements. +/// +/// The returned array value is known not to be aliased since it was just +/// allocated. +bool ArrayAllocation::isInitializationWithKnownElements() { + ArraySemanticsCall Uninitialized(Alloc, "array.uninitialized"); + if (Uninitialized && + (ArrayValue = Uninitialized.getArrayValue()) && + (ElementBuffer = Uninitialized.getArrayElementStoragePointer())) + return mapInitializationStores(); + + return false; +} + +/// Propagate the elements of an array literal to get_element method calls on +/// the same array. +/// +/// We have to prove that the array value is not changed in between the +/// creation and the method call to get_element. +bool ArrayAllocation::findValueReplacements() { + if (!isInitializationWithKnownElements()) + return false; + + // The array value was stored or has escaped. + if (!analyseArrayValueUses()) + return false; + + // No count users. + if (GetElementCalls.empty()) + return false; + + return collectForwardableValues(); +} + +/// Collect all get_element users and check that there are no escapes or uses +/// that could change the array value. +bool ArrayAllocation::analyseArrayValueUses() { + return recursivelyCollectUses(ArrayValue.getDef()); +} + +static bool doesNotChangeArray(ArraySemanticsCall &C) { + switch (C.getKind()) { + default: return false; + case ArrayCallKind::kArrayPropsIsNativeTypeChecked: + case ArrayCallKind::kCheckSubscript: + case ArrayCallKind::kCheckIndex: + case ArrayCallKind::kGetCount: + case ArrayCallKind::kGetCapacity: + case ArrayCallKind::kGetElement: + return true; + } +} + +/// Recursively look at all uses of this definition. Abort if the array value +/// could escape or be changed. Collect all uses that are calls to array.count. +bool ArrayAllocation::recursivelyCollectUses(ValueBase *Def) { + for (auto *Opd : Def->getUses()) { + auto *User = Opd->getUser(); + // Ignore reference counting and debug instructions. + if (isa(User) || isa(User)) + continue; + + // Array value projection. + if (auto *SEI = dyn_cast(User)) { + if (!recursivelyCollectUses(SEI)) + return false; + continue; + } + + // Check array semantic calls. + ArraySemanticsCall ArrayOp(User); + if (ArrayOp && doesNotChangeArray(ArrayOp)) { + if (ArrayOp.getKind() == ArrayCallKind::kGetElement) + GetElementCalls.insert(ArrayOp); + continue; + } + + // An operation that escapes or modifies the array value. + return false; + } + return true; +} + +/// Look at the get_element calls and match them to values by index. +bool ArrayAllocation::collectForwardableValues() { + bool FoundForwardableValue = false; + for (auto *GetElementCall : GetElementCalls) { + ArraySemanticsCall GetElement(GetElementCall); + assert(GetElement.getKind() == ArrayCallKind::kGetElement); + + auto ConstantIndex = GetElement.getConstantIndex(); + if (ConstantIndex == None) + continue; + + assert(*ConstantIndex >= 0 && "Must have a positive index"); + + auto EltValueIt = ElementValueMap.find(*ConstantIndex); + if (EltValueIt == ElementValueMap.end()) + continue; + + ReplacementMap.push_back( + std::make_pair(GetElementCall, EltValueIt->second)); + FoundForwardableValue = true; + } + return FoundForwardableValue; +} + +// ============================================================================= +// Driver +// ============================================================================= + +namespace { + +class ArrayElementPropagation : public SILFunctionTransform { +public: + ArrayElementPropagation() {} + + StringRef getName() override { + return "Array Element Propagation"; + } + + void run() override { + auto &Fn = *getFunction(); + + bool Changed = false; + + // Propagate the elements an of array value to its users. + SmallVector, 16> ValueReplacements; + for (auto &BB :Fn) { + for (auto &Inst : BB) { + if (auto *Apply = dyn_cast(&Inst)) + Changed |= + ArrayAllocation::findValueReplacements(Apply, ValueReplacements); + } + } + DEBUG(if (Changed) { + llvm::dbgs() << "Array elements replaced in " << Fn.getName() << " (" + << ValueReplacements.size() << ")\n"; + }); + // Perform the actual replacement of the get_element call by its value. + for (auto &Repl : ValueReplacements) { + ArraySemanticsCall GetElement(Repl.first); + GetElement.replaceByValue(Repl.second); + } + + if (Changed) { + PM->invalidateAnalysis( + &Fn, SILAnalysis::InvalidationKind::CallsAndInstructions); + } + } +}; +} // End anonymous namespace. + +SILTransform *swift::createArrayElementPropagation() { + return new ArrayElementPropagation(); +} diff --git a/lib/SILOptimizer/Transforms/CMakeLists.txt b/lib/SILOptimizer/Transforms/CMakeLists.txt new file mode 100644 index 0000000000000..52ca9ca998cf1 --- /dev/null +++ b/lib/SILOptimizer/Transforms/CMakeLists.txt @@ -0,0 +1,26 @@ +set(TRANSFORMS_SOURCES + Transforms/AllocBoxToStack.cpp + Transforms/ArrayCountPropagation.cpp + Transforms/ArrayElementValuePropagation.cpp + Transforms/CSE.cpp + Transforms/CopyForwarding.cpp + Transforms/DeadCodeElimination.cpp + Transforms/DeadObjectElimination.cpp + Transforms/DeadStoreElimination.cpp + Transforms/Devirtualizer.cpp + Transforms/GenericSpecializer.cpp + Transforms/MergeCondFail.cpp + Transforms/RedundantLoadElimination.cpp + Transforms/RedundantOverflowCheckRemoval.cpp + Transforms/ReleaseDevirtualizer.cpp + Transforms/RemovePin.cpp + Transforms/SILCleanup.cpp + Transforms/SILCodeMotion.cpp + Transforms/SILLowerAggregateInstrs.cpp + Transforms/SILMem2Reg.cpp + Transforms/SILSROA.cpp + Transforms/SimplifyCFG.cpp + Transforms/Sink.cpp + Transforms/SpeculativeDevirtualizer.cpp + Transforms/StackPromotion.cpp + PARENT_SCOPE) diff --git a/lib/SILPasses/Scalar/CSE.cpp b/lib/SILOptimizer/Transforms/CSE.cpp similarity index 97% rename from lib/SILPasses/Scalar/CSE.cpp rename to lib/SILOptimizer/Transforms/CSE.cpp index 7b1cadcdd6cf4..529f66e104378 100644 --- a/lib/SILPasses/Scalar/CSE.cpp +++ b/lib/SILOptimizer/Transforms/CSE.cpp @@ -1,8 +1,8 @@ -//===- CSE.cpp - Simple and fast CSE pass ---------------------------------===// +//===--- CSE.cpp - Simple and fast CSE pass -------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,19 +16,19 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-cse" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/Dominance.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILType.h" #include "swift/SIL/SILValue.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/SimplifyInstruction.h" -#include "swift/SILAnalysis/SideEffectAnalysis.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/SimplifyInstruction.h" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/ScopedHashTable.h" #include "llvm/ADT/Statistic.h" @@ -428,7 +428,7 @@ class CSE { // StackNode - contains all the needed information to create a stack for doing // a depth first traversal of the tree. This includes scopes for values and // loads as well as the generation. There is a child iterator so that the - // children do not need to be store spearately. + // children do not need to be store separately. class StackNode { public: StackNode(ScopedHTType *availableValues, DominanceInfoNode *n, diff --git a/lib/SILPasses/Scalar/CopyForwarding.cpp b/lib/SILOptimizer/Transforms/CopyForwarding.cpp similarity index 87% rename from lib/SILPasses/Scalar/CopyForwarding.cpp rename to lib/SILOptimizer/Transforms/CopyForwarding.cpp index 74afd3e2e8631..f5cf14db6cb1f 100644 --- a/lib/SILPasses/Scalar/CopyForwarding.cpp +++ b/lib/SILOptimizer/Transforms/CopyForwarding.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -26,9 +26,9 @@ // Useless copies of address-only types look like this: // // %copy = alloc_stack $T -// copy_addr %arg to [initialization] %copy#1 : $*T -// %ret = apply %callee(%copy#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () -// dealloc_stack %copy#0 : $*@local_storage T +// copy_addr %arg to [initialization] %copy : $*T +// %ret = apply %callee(%copy) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () +// dealloc_stack %copy : $*T // destroy_addr %arg : $*T // // Eliminating the address-only copies eliminates a very expensive call to @@ -61,11 +61,11 @@ #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILVisitor.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" #include "swift/SIL/DebugUtils.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/CommandLine.h" @@ -84,18 +84,17 @@ static llvm::cl::opt EnableCopyForwarding("enable-copyforwarding", static llvm::cl::opt EnableDestroyHoisting("enable-destroyhoisting", llvm::cl::init(true)); -/// \return true of the given object can only be accessed via the given def -/// (this def uniquely identifies the object). +/// \return true if the given copy source value can only be accessed via the +/// given def (this def uniquely identifies the object). /// /// (1) An "in" argument. /// (inouts are also nonaliased, but won't be destroyed in scope) /// /// (2) A local alloc_stack variable. -static bool isIdentifiedObject(SILValue Def, SILFunction *F) { +static bool isIdentifiedSourceValue(SILValue Def) { if (SILArgument *Arg = dyn_cast(Def)) { // Check that the argument is passed as an in type. This means there are - // no aliases accessible within this function scope. We may be able to just - // assert this. + // no aliases accessible within this function scope. ParameterConvention Conv = Arg->getParameterInfo().getConvention(); switch (Conv) { case ParameterConvention::Indirect_In: @@ -112,6 +111,32 @@ static bool isIdentifiedObject(SILValue Def, SILFunction *F) { return false; } +/// \return true if the given copy dest value can only be accessed via the given +/// def (this def uniquely identifies the object). +/// +/// (1) An "out" or inout argument. +/// +/// (2) A local alloc_stack variable. +static bool isIdentifiedDestValue(SILValue Def) { + if (SILArgument *Arg = dyn_cast(Def)) { + // Check that the argument is passed as an out type. This means there are + // no aliases accessible within this function scope. + ParameterConvention Conv = Arg->getParameterInfo().getConvention(); + switch (Conv) { + case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_Out: + return true; + default: + DEBUG(llvm::dbgs() << " Skipping Def: Not an @in argument!\n"); + return false; + } + } + else if (isa(Def)) + return true; + + return false; +} + /// Return the parameter convention used by Apply to pass an argument /// indirectly via Address. /// @@ -183,6 +208,7 @@ class AnalyzeForwardUse return true; case ParameterConvention::Indirect_In_Guaranteed: case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: return false; case ParameterConvention::Indirect_Out: llvm_unreachable("copy_addr not released before reinitialization"); @@ -278,6 +304,7 @@ class AnalyzeBackwardUse case ParameterConvention::Indirect_Out: return true; case ParameterConvention::Indirect_Inout: + case ParameterConvention::Indirect_InoutAliasable: case ParameterConvention::Indirect_In_Guaranteed: return false; case ParameterConvention::Indirect_In: @@ -464,6 +491,8 @@ bool CopyForwarding::collectUsers() { case ValueKind::DebugValueAddrInst: SrcDebugValueInsts.insert(cast(UserInst)); break; + case ValueKind::DeallocStackInst: + break; default: // Most likely one of: // init_enum_data_addr @@ -563,6 +592,8 @@ bool CopyForwarding::areCopyDestUsersDominatedBy( auto *UserInst = Use->getUser(); if (UserInst == Copy) continue; + if (isa(UserInst)) + continue; // Initialize the dominator tree info. if (!DT) @@ -589,6 +620,38 @@ bool CopyForwarding::areCopyDestUsersDominatedBy( return true; } +/// Returns the associated dealloc_stack if \p ASI has a single dealloc_stack. +/// Usually this is the case, but the optimizations may generate something like: +/// %1 = alloc_stack +/// if (...) { +/// dealloc_stack %1 +/// } else { +/// dealloc_stack %1 +/// } +static DeallocStackInst *getSingleDealloc(AllocStackInst *ASI) { + DeallocStackInst *SingleDSI = nullptr; + for (Operand *Use : ASI->getUses()) { + if (auto *DSI = dyn_cast(Use->getUser())) { + if (SingleDSI) + return nullptr; + SingleDSI = DSI; + } + } + return SingleDSI; +} + +/// Replace all uses of \p ASI by \p RHS, except the dealloc_stack. +static void replaceAllUsesExceptDealloc(AllocStackInst *ASI, ValueBase *RHS) { + llvm::SmallVector Uses; + for (Operand *Use : ASI->getUses()) { + if (!isa(Use->getUser())) + Uses.push_back(Use); + } + for (Operand *Use : Uses) { + Use->set(SILValue(RHS, Use->get().getResultNumber())); + } +} + /// Perform forward copy-propagation. Find a set of uses that the given copy can /// forward to and replace them with the copy's source. /// @@ -600,9 +663,9 @@ bool CopyForwarding::areCopyDestUsersDominatedBy( /// %copy = alloc_stack $T /// ... /// CurrentBlock: -/// copy_addr %arg to [initialization] %copy#1 : $*T +/// copy_addr %arg to [initialization] %copy : $*T /// ... -/// %ret = apply %callee(%copy#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () +/// %ret = apply %callee(%copy) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () /// \endcode /// /// If the last use (deinit) is a copy, replace it with a destroy+copy[init]. @@ -614,20 +677,25 @@ bool CopyForwarding::forwardPropagateCopy( CopyAddrInst *CopyInst, SmallPtrSetImpl &DestUserInsts) { + SILValue CopyDest = CopyInst->getDest(); + // Require the copy dest to be a simple alloc_stack. This ensures that all + // instructions that may read from the destination address depend on CopyDest. + if (!isa(CopyDest)) + return false; + // Looking at // // copy_addr %Src, [init] %Dst // - // We can reuse %Src if it is destroyed at %Src and not initialized again. To + // We can reuse %Src if it is dead after the copy and not reinitialized. To // know that we can safely replace all uses of %Dst with source we must know // that it is uniquely named and cannot be accessed outside of the function // (an alloc_stack instruction qualifies for this, an inout parameter does // not). Additionally, we must know that all accesses to %Dst further on must // have had this copy on their path (there might be reinitialization of %Dst - // later, but there must no be a path around this copy that reads from %Dst). + // later, but there must not be a path around this copy that reads from %Dst). SmallVector DestUses; - if (isa(CopyInst->getDest()) && /* Uniquely identified name */ - isSourceDeadAtCopy(CopyInst) && + if (isSourceDeadAtCopy(CopyInst) && areCopyDestUsersDominatedBy(CopyInst, DestUses)) { // Replace all uses of Dest with a use of Src. @@ -646,16 +714,14 @@ bool CopyForwarding::forwardPropagateCopy( return true; } - SILValue CopyDest = CopyInst->getDest(); SILInstruction *DefDealloc = nullptr; - if (isa(CurrentDef)) { - SILValue StackAddr(CurrentDef.getDef(), 0); - if (!StackAddr.hasOneUse()) { + if (auto *ASI = dyn_cast(CurrentDef)) { + DefDealloc = getSingleDealloc(ASI); + if (!DefDealloc) { DEBUG(llvm::dbgs() << " Skipping copy" << *CopyInst << " stack address has multiple uses.\n"); return false; } - DefDealloc = StackAddr.use_begin()->getUser(); } // Scan forward recording all operands that use CopyDest until we see the @@ -682,7 +748,7 @@ bool CopyForwarding::forwardPropagateCopy( AnalyzeForwardUse AnalyzeUse(CopyDest); bool seenDeinit = AnalyzeUse.visit(UserInst); - // If this use cannot be anlayzed, then abort. + // If this use cannot be analyzed, then abort. if (!AnalyzeUse.Oper) return false; // Otherwise record the operand. @@ -697,7 +763,7 @@ bool CopyForwarding::forwardPropagateCopy( // Convert a reinitialization of this address into a destroy, followed by an // initialization. Replacing a copy with a destroy+init is not by itself // profitable. However, it does allow eliminating the earlier copy, and we may - // later be able to elimimate this initialization copy. + // later be able to eliminate this initialization copy. if (auto Copy = dyn_cast(&*SI)) { if (Copy->getDest() == CopyDest) { assert(!Copy->isInitializationOfDest() && "expected a deinit"); @@ -720,6 +786,30 @@ bool CopyForwarding::forwardPropagateCopy( return true; } +/// Given an address defined by 'Def', find the object root and all direct uses, +/// not including: +/// - 'Def' itself +/// - Transitive uses of 'Def' (listed elsewhere in DestUserInsts) +/// +/// If the returned root is not 'Def' itself, then 'Def' must be an address +/// projection that can be trivially rematerialized with the root as its +/// operand. +static ValueBase * +findAddressRootAndUsers(ValueBase *Def, + SmallPtrSetImpl &RootUserInsts) { + if (isa(Def) || isa(Def)) { + SILValue InitRoot = cast(Def)->getOperand(0); + for (auto *Use : InitRoot.getUses()) { + auto *UserInst = Use->getUser(); + if (UserInst == Def) + continue; + RootUserInsts.insert(UserInst); + } + return InitRoot.getDef(); + } + return Def; +} + /// Perform backward copy-propagation. Find the initialization point of the /// copy's source and replace the initializer's address with the copy's dest. bool CopyForwarding::backwardPropagateCopy( @@ -728,20 +818,33 @@ bool CopyForwarding::backwardPropagateCopy( SILValue CopySrc = CopyInst->getSrc(); ValueBase *CopyDestDef = CopyInst->getDest().getDef(); + SmallPtrSet RootUserInsts; + ValueBase *CopyDestRoot = findAddressRootAndUsers(CopyDestDef, RootUserInsts); + + // Require the copy dest value to be identified by this address. This ensures + // that all instructions that may write to destination address depend on + // CopyDestRoot. + if (!isIdentifiedDestValue(CopyDestRoot)) + return false; // Scan backward recording all operands that use CopySrc until we see the // most recent init of CopySrc. bool seenInit = false; + bool seenCopyDestDef = false; + // ValueUses records the uses of CopySrc in reverse order. SmallVector ValueUses; SmallVector DebugValueInstsToDelete; auto SI = CopyInst->getIterator(), SE = CopyInst->getParent()->begin(); while (SI != SE) { --SI; SILInstruction *UserInst = &*SI; + if (UserInst == CopyDestDef) + seenCopyDestDef = true; // If we see another use of Dest, then Dest is live after the Src location // is initialized, so we really need the copy. - if (DestUserInsts.count(UserInst) || UserInst == CopyDestDef) { + if (UserInst == CopyDestRoot || DestUserInsts.count(UserInst) + || RootUserInsts.count(UserInst)) { if (auto *DVAI = dyn_cast(UserInst)) { DebugValueInstsToDelete.push_back(DVAI); continue; @@ -758,10 +861,10 @@ bool CopyForwarding::backwardPropagateCopy( AnalyzeBackwardUse AnalyzeUse(CopySrc); seenInit = AnalyzeUse.visit(UserInst); - // If this use cannot be anlayzed, then abort. + // If this use cannot be analyzed, then abort. if (!AnalyzeUse.Oper) return false; - // Otherwise record the operand. + // Otherwise record the operand with the earliest use last in the list. ValueUses.push_back(AnalyzeUse.Oper); // If this is an init, we're done searching. if (seenInit) @@ -776,13 +879,17 @@ bool CopyForwarding::backwardPropagateCopy( // Convert a reinitialization of this address into a destroy, followed by an // initialization. Replacing a copy with a destroy+init is not by itself // profitable. However, it does allow us to eliminate the later copy, and the - // init copy may be eliminater later. + // init copy may be eliminated later. if (auto Copy = dyn_cast(&*SI)) { if (Copy->getDest() == CopySrc && !Copy->isInitializationOfDest()) { SILBuilderWithScope(Copy).createDestroyAddr(Copy->getLoc(), CopySrc); Copy->setIsInitializationOfDest(IsInitialization); } } + // Rematerialize the projection if needed by simply moving it. + if (seenCopyDestDef) { + cast(CopyDestDef)->moveBefore(&*SI); + } // Now that an init was found, it is safe to substitute all recorded uses // with the copy's dest. for (auto *Oper : ValueUses) { @@ -983,7 +1090,7 @@ void CopyForwarding::forwardCopiesOf(SILValue Def, SILFunction *F) { /// %2 = alloc_stack $T /// ... // arbitrary control flow, but no other uses of %0 /// bbN: -/// copy_addr [take] %2#1 to [initialization] %0 : $*T +/// copy_addr [take] %2 to [initialization] %0 : $*T /// ... // no writes /// return static bool canNRVO(CopyAddrInst *CopyInst) { @@ -995,7 +1102,11 @@ static bool canNRVO(CopyAddrInst *CopyInst) { // optimization will early-initialize the copy dest, so we can't allow aliases // to be accessed between the initialization and the return. auto OutArg = dyn_cast(CopyInst->getDest()); - if (!OutArg || !OutArg->getParameterInfo().isIndirect()) + if (!OutArg) + return false; + + auto ArgConv = OutArg->getParameterInfo().getConvention(); + if (ArgConv != ParameterConvention::Indirect_Out) return false; SILBasicBlock *BB = CopyInst->getParent(); @@ -1018,7 +1129,8 @@ static bool canNRVO(CopyAddrInst *CopyInst) { static void performNRVO(CopyAddrInst *CopyInst) { DEBUG(llvm::dbgs() << "NRVO eliminates copy" << *CopyInst); ++NumCopyNRVO; - CopyInst->getSrc().replaceAllUsesWith(CopyInst->getDest()); + replaceAllUsesExceptDealloc(cast(CopyInst->getSrc()), + CopyInst->getDest().getDef()); assert(CopyInst->getSrc() == CopyInst->getDest() && "bad NRVO"); CopyInst->eraseFromParent(); } @@ -1057,7 +1169,7 @@ class CopyForwardingPass : public SILFunctionTransform continue; } SILValue Def = CopyInst->getSrc(); - if (isIdentifiedObject(Def, getFunction())) + if (isIdentifiedSourceValue(Def)) CopiedDefs.insert(Def); else { DEBUG(llvm::dbgs() << " Skipping Def: " << Def diff --git a/lib/SILPasses/Scalar/DeadCodeElimination.cpp b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp similarity index 93% rename from lib/SILPasses/Scalar/DeadCodeElimination.cpp rename to lib/SILOptimizer/Transforms/DeadCodeElimination.cpp index 690b11a6b75ee..1277daf508951 100644 --- a/lib/SILPasses/Scalar/DeadCodeElimination.cpp +++ b/lib/SILOptimizer/Transforms/DeadCodeElimination.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,10 +17,10 @@ #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILUndef.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -43,8 +43,7 @@ static bool seemsUseful(SILInstruction *I) { if (I->mayHaveSideEffects()) return true; - if (isa(I) || isa(I) || - isa(I) || isa(I)) + if (isa(I) || isa(I) || isa(I)) return true; return false; @@ -92,7 +91,7 @@ class DCE : public SILFunctionTransform { /// Tracks if the pass changed branches. bool BranchesChanged; - /// Trackes if the pass changed ApplyInsts. + /// Tracks if the pass changed ApplyInsts. bool CallsChanged; /// The entry point to the transformation. @@ -106,7 +105,7 @@ class DCE : public SILFunctionTransform { PDT = DA->get(F); // If we have a functions that consists of nothing but a - // structrually infinite loop like: + // structurally infinite loop like: // while true {} // we'll have an empty post dominator tree. if (!PDT->getRootNode()) @@ -198,7 +197,7 @@ void DCE::markValueLive(ValueBase *V) { } /// Gets the producing instruction of a cond_fail condition. Currently these -/// are overflow builtints but may be extended to other instructions in the +/// are overflow builtins but may be extended to other instructions in the /// future. static SILInstruction *getProducer(CondFailInst *CFI) { // Check for the pattern: @@ -223,7 +222,7 @@ void DCE::markLive(SILFunction &F) { for (auto &BB : F) { for (auto &I : BB) { if (auto *CFI = dyn_cast(&I)) { - // A cond_fail is only alive if its (identifyable) producer is alive. + // A cond_fail is only alive if its (identifiable) producer is alive. if (SILInstruction *Prod = getProducer(CFI)) { addReverseDependency(Prod, CFI); } else { @@ -281,18 +280,22 @@ void DCE::markTerminatorArgsLive(SILBasicBlock *Pred, // delivers those arguments. markValueLive(Term); - switch (Term->getKind()) { - default: + switch (Term->getTermKind()) { + case TermKind::ReturnInst: + case TermKind::ThrowInst: + case TermKind::Invalid: llvm_unreachable("Unexpected terminator kind!"); - case ValueKind::UnreachableInst: - case ValueKind::SwitchValueInst: + case TermKind::UnreachableInst: + case TermKind::SwitchValueInst: + case TermKind::SwitchEnumAddrInst: + case TermKind::CheckedCastAddrBranchInst: llvm_unreachable("Unexpected argument for terminator kind!"); break; - case ValueKind::DynamicMethodBranchInst: - case ValueKind::SwitchEnumInst: - case ValueKind::CheckedCastBranchInst: + case TermKind::DynamicMethodBranchInst: + case TermKind::SwitchEnumInst: + case TermKind::CheckedCastBranchInst: assert(ArgIndex == 0 && "Expected a single argument!"); // We do not need to do anything with these. If the resulting @@ -301,11 +304,11 @@ void DCE::markTerminatorArgsLive(SILBasicBlock *Pred, // single operand of these instructions as live. break; - case ValueKind::BranchInst: + case TermKind::BranchInst: markValueLive(cast(Term)->getArg(ArgIndex).getDef()); break; - case ValueKind::CondBranchInst: { + case TermKind::CondBranchInst: { auto *CondBr = cast(Term); if (CondBr->getTrueBB() == Succ) { @@ -320,7 +323,7 @@ void DCE::markTerminatorArgsLive(SILBasicBlock *Pred, break; } - case ValueKind::TryApplyInst: { + case TermKind::TryApplyInst: { assert(ArgIndex == 0 && "Expect a single argument!"); break; } @@ -367,34 +370,31 @@ void DCE::propagateLiveness(SILInstruction *I) { return; } - switch (I->getKind()) { -#define TERMINATOR(ID, PARENT, MEM, RELEASE) -#define VALUE(ID, PARENT) case ValueKind::ID: -#include "swift/SIL/SILNodes.def" + switch (ValueKindAsTermKind(I->getKind())) { + case TermKind::Invalid: llvm_unreachable("Unexpected terminator instruction!"); - case ValueKind::BranchInst: - case ValueKind::UnreachableInst: + case TermKind::BranchInst: + case TermKind::UnreachableInst: return; - case ValueKind::ReturnInst: - case ValueKind::AutoreleaseReturnInst: - case ValueKind::ThrowInst: - case ValueKind::CondBranchInst: - case ValueKind::SwitchEnumInst: - case ValueKind::SwitchEnumAddrInst: - case ValueKind::DynamicMethodBranchInst: - case ValueKind::CheckedCastBranchInst: + case TermKind::ReturnInst: + case TermKind::ThrowInst: + case TermKind::CondBranchInst: + case TermKind::SwitchEnumInst: + case TermKind::SwitchEnumAddrInst: + case TermKind::DynamicMethodBranchInst: + case TermKind::CheckedCastBranchInst: markValueLive(I->getOperand(0).getDef()); return; - case ValueKind::TryApplyInst: - case ValueKind::SwitchValueInst: + case TermKind::TryApplyInst: + case TermKind::SwitchValueInst: for (auto &O : I->getAllOperands()) markValueLive(O.get().getDef()); return; - case ValueKind::CheckedCastAddrBranchInst: + case TermKind::CheckedCastAddrBranchInst: markValueLive(I->getOperand(0).getDef()); markValueLive(I->getOperand(1).getDef()); return; @@ -556,7 +556,7 @@ void DCE::computeLevelNumbers(PostDomTreeNode *Node, unsigned Level) { // Structurally infinite loops like: // bb1: // br bb1 -// are not present in the post-dominator tree. Their prescence +// are not present in the post-dominator tree. Their presence // requires significant modifications to the way the rest of the // algorithm works. They should be rare, so for now we'll do the most // conservative thing and completely bail out, doing no dead code diff --git a/lib/SILPasses/Scalar/DeadObjectElimination.cpp b/lib/SILOptimizer/Transforms/DeadObjectElimination.cpp similarity index 97% rename from lib/SILPasses/Scalar/DeadObjectElimination.cpp rename to lib/SILOptimizer/Transforms/DeadObjectElimination.cpp index c1de83ccc9711..8730745e96345 100644 --- a/lib/SILPasses/Scalar/DeadObjectElimination.cpp +++ b/lib/SILOptimizer/Transforms/DeadObjectElimination.cpp @@ -1,8 +1,8 @@ -//===-- DeadObjectElimination.h - Remove unused objects ------------------===// +//===--- DeadObjectElimination.cpp - Remove unused objects ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -24,7 +24,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "dead-object-elim" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/AST/ResilienceExpansion.h" #include "swift/SIL/Projection.h" #include "swift/SIL/SILArgument.h" @@ -34,10 +34,10 @@ #include "swift/SIL/SILModule.h" #include "swift/SIL/SILUndef.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" @@ -79,7 +79,7 @@ static SILFunction *getDestructor(AllocRefInst *ARI) { DEBUG(llvm::dbgs() << " Found destructor!\n"); - // If the destructor has an objc_method calling convention, we can not + // If the destructor has an objc_method calling convention, we cannot // analyze it since it could be swapped out from under us at runtime. if (Fn->getRepresentation() == SILFunctionTypeRepresentation::ObjCMethod) { DEBUG(llvm::dbgs() << " Found objective-c destructor. Can't " @@ -146,7 +146,7 @@ static bool doesDestructorHaveSideEffects(AllocRefInst *ARI) { } // dealloc_ref on self can be ignored, but dealloc_ref on anything else - // can not be eliminated. + // cannot be eliminated. if (auto *DeallocRef = dyn_cast(&I)) { if (DeallocRef->getOperand().stripCasts().getDef() == Self) { DEBUG(llvm::dbgs() << " SAFE! dealloc_ref on self.\n"); @@ -227,7 +227,7 @@ static bool canZapInstruction(SILInstruction *Inst) { /// Analyze the use graph of AllocRef for any uses that would prevent us from /// zapping it completely. static bool -hasUnremoveableUsers(SILInstruction *AllocRef, UserList &Users) { +hasUnremovableUsers(SILInstruction *AllocRef, UserList &Users) { SmallVector Worklist; Worklist.push_back(AllocRef); @@ -331,7 +331,7 @@ namespace { /// dead arrays. We just need a slightly better destructor analysis to prove /// that it only releases elements. class DeadObjectAnalysis { - // Map a each address projection of this object to a list of stores. + // Map each address projection of this object to a list of stores. // Do not iterate over this map's entries. using AddressToStoreMap = llvm::DenseMap >; @@ -740,8 +740,8 @@ bool DeadObjectElimination::processAllocRef(AllocRefInst *ARI) { // Our destructor has no side effects, so if we can prove that no loads // escape, then we can completely remove the use graph of this alloc_ref. UserList UsersToRemove; - if (hasUnremoveableUsers(ARI, UsersToRemove)) { - DEBUG(llvm::dbgs() << " Found a use that can not be zapped...\n"); + if (hasUnremovableUsers(ARI, UsersToRemove)) { + DEBUG(llvm::dbgs() << " Found a use that cannot be zapped...\n"); return false; } @@ -760,8 +760,8 @@ bool DeadObjectElimination::processAllocStack(AllocStackInst *ASI) { return false; UserList UsersToRemove; - if (hasUnremoveableUsers(ASI, UsersToRemove)) { - DEBUG(llvm::dbgs() << " Found a use that can not be zapped...\n"); + if (hasUnremovableUsers(ASI, UsersToRemove)) { + DEBUG(llvm::dbgs() << " Found a use that cannot be zapped...\n"); return false; } diff --git a/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp b/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp new file mode 100644 index 0000000000000..d020f47cd0b2c --- /dev/null +++ b/lib/SILOptimizer/Transforms/DeadStoreElimination.cpp @@ -0,0 +1,1190 @@ +//===--- DeadStoreElimination.cpp - SIL Dead Store Elimination ------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// This pass eliminates dead stores across basic blocks. +/// +/// A store is dead if after the store has occurred: +/// +/// 1. The store to pointer is not used along any path to program exit. +/// 2. The store to pointer is overwritten by another store before any +/// potential use of the pointer. +/// +/// Dead store elimination (DSE) eliminates such stores by: +/// +/// 1. Introducing a notion of a LSLocation that is used to model objects +/// fields. (See below for more details). +/// +/// 2. Performing a post-order walk over the control flow graph, tracking any +/// LSLocations that are read from or stored into in each basic block. After +/// eliminating any dead stores in single blocks, it computes a genset and +/// killset for each block. The genset keeps a list of upward visible stores +/// and the killset keeps a list of LSLocation this basic block reads (kills). +/// +/// 3. An optimistic iterative dataflow is performed on the genset and killset +/// until convergence. +/// +/// At the core of DSE, there is the LSLocation class. a LSLocation is an +/// abstraction of an object field in program. It consists of a base and a +/// projection path to the field accessed. +/// +/// When a load or store instruction is encountered, the memory is broken down +/// to the indivisible components, i.e aggregates are broken down to their +/// individual fields using the expand function. This gives the flexibility to +/// find exactly which part of the store is alive and which part is dead. +/// +/// After the live parts of the store are determined, they are merged into the +/// minimum number of stores possible using the reduce function. This is done +/// so that we do not bloat SIL IR. +/// +/// Another way to implement the DSE optimization is to keep the instructions +/// that read and/or write memory without breaking the memory read/written +/// using the ProjectionPath. However, this can easily lead to loss of +/// opportunities, e.g. a read that only kills part of a store may need to be +/// treated as killing the entire store. However, using ProjectionPath does +/// lead to more memory uses. +/// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-dead-store-elim" +#include "swift/SIL/Projection.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILBuilder.h" +#include "swift/SIL/SILValueProjection.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/EscapeAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +STATISTIC(NumDeadStores, "Number of dead stores removed"); +STATISTIC(NumPartialDeadStores, "Number of partial dead stores removed"); + +/// ComputeMaxStoreSet - If we ignore all reads, what is the max store set that +/// can reach a particular point in a basic block. This helps in generating +/// the genset and killset. i.e. if there is no upward visible store that can +/// reach the beginning of a basic block, then we know that the genset and +/// killset for the stored location need not be set for the basic block. +/// +/// BuildGenKillSet - Build the genset and killset of the basic block. +/// +/// PerformDSE - Perform the actual dead store elimination. +enum class DSEKind : unsigned { + ComputeMaxStoreSet = 0, + BuildGenKillSet = 1, + PerformDSE = 2, +}; + +//===----------------------------------------------------------------------===// +// Utility Functions +//===----------------------------------------------------------------------===// + +static inline bool isComputeMaxStoreSet(DSEKind Kind) { + return Kind == DSEKind::ComputeMaxStoreSet; +} + +static inline bool isBuildingGenKillSet(DSEKind Kind) { + return Kind == DSEKind::BuildGenKillSet; +} + +static inline bool isPerformingDSE(DSEKind Kind) { + return Kind == DSEKind::PerformDSE; +} + +/// Returns true if this is an instruction that may have side effects in a +/// general sense but are inert from a load store perspective. +static bool isDeadStoreInertInstruction(SILInstruction *Inst) { + switch (Inst->getKind()) { + case ValueKind::StrongRetainInst: + case ValueKind::StrongRetainUnownedInst: + case ValueKind::UnownedRetainInst: + case ValueKind::RetainValueInst: + case ValueKind::DeallocStackInst: + case ValueKind::CondFailInst: + case ValueKind::IsUniqueInst: + case ValueKind::IsUniqueOrPinnedInst: + return true; + default: + return false; + } +} + +//===----------------------------------------------------------------------===// +// Basic Block Location State +//===----------------------------------------------------------------------===// + +namespace { + +/// If this function has too many basic blocks or too many locations, it may +/// take a long time to compute the genset and killset. The number of memory +/// behavior or alias query we need to do in worst case is roughly linear to +/// # of BBs x(times) # of locations. +/// +/// we could run DSE on functions with 256 basic blocks and 256 locations, +/// which is a large function. +constexpr unsigned MaxLSLocationBBMultiplicationNone = 256*256; + +/// we could run optimistic DSE on functions with less than 64 basic blocks +/// and 64 locations which is a sizeable function. +constexpr unsigned MaxLSLocationBBMultiplicationPessimistic = 64*64; + +/// If a large store is broken down to too many smaller stores, bail out. +/// Currently, we only do partial dead store if we can form a single contiguous +/// non-dead store. +constexpr unsigned MaxPartialDeadStoreCountLimit = 1; + +/// forward declaration. +class DSEContext; +/// BlockState summarizes how LSLocations are used in a basic block. +/// +/// Initially the BBWriteSetOut is empty. Before a basic block is processed, it +/// is initialized to the intersection of BBWriteSetIns of all successors of the +/// basic block. +/// +/// BBWriteSetMid is initialized to BBWriteSetOut of the current basic block +/// before instructions in the basic block is processed. +/// +/// Initially BBWriteSetIn is set to true. After the basic block is processed, +/// if its BBWriteSetMid is different from BBWriteSetIn, BBWriteSetIn is +/// assigned the value of BBWriteSetMid and the data flow is rerun on the +/// current basic block's predecessors. +/// +/// Instructions in each basic block are processed in post-order as follows: +/// +/// 1. When a store instruction is encountered, the stored location is tracked. +/// +/// 2. When a load instruction is encountered, remove the loaded location and +/// any location it may alias with from the BBWriteSetMid. +/// +/// 3. When an instruction reads from memory in an unknown way, the +/// BBWriteSetMid bit is cleared if the instruction can read the +/// corresponding LSLocation. +/// +class BlockState { +public: + /// The basic block this BlockState represents. + SILBasicBlock *BB; + + /// Keep the number of LSLocations in the LocationVault. + unsigned LocationNum; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If the bit is set, then the location currently has an + /// upward visible store at the end of the basic block. + llvm::SmallBitVector BBWriteSetOut; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If the bit is set, then the location currently has an + /// upward visible store in middle of the basic block. + llvm::SmallBitVector BBWriteSetMid; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If a bit in the vector is set, then the location has an + /// upward visible store at the beginning of the basic block. + llvm::SmallBitVector BBWriteSetIn; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If the bit is set, then the current basic block + /// generates an upward visible store. + llvm::SmallBitVector BBGenSet; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If the bit is set, then the current basic block + /// kills an upward visible store. + llvm::SmallBitVector BBKillSet; + + /// A bit vector to keep the maximum number of stores that can reach a + /// certain point of the basic block. If a bit is set, that means there is + /// potentially an upward visible store to the location at the particular + /// point of the basic block. + llvm::SmallBitVector BBMaxStoreSet; + + /// The dead stores in the current basic block. + llvm::DenseSet DeadStores; + + /// Keeps track of what stores to generate after the data flow stabilizes. + /// these stores come from partial dead stores. + /// + /// The first SILValue keeps the address of the live store and the second + /// SILValue keeps the value of the store. + llvm::DenseMap LiveStores; + + /// Constructors. + BlockState(SILBasicBlock *B) : BB(B) {} + + /// Return the current basic block. + SILBasicBlock *getBB() const { return BB; } + + /// Initialize the bitvectors for the return basic block. + void initReturnBlock(DSEContext &Ctx); + + /// Initialize the bitvectors for the current basic block. + void init(DSEContext &Ctx, bool PessimisticDF); + + /// Check whether the BBWriteSetIn has changed. If it does, we need to rerun + /// the data flow on this block's predecessors to reach fixed point. + bool updateBBWriteSetIn(llvm::SmallBitVector &X); + + /// Functions to manipulate the write set. + void startTrackingLocation(llvm::SmallBitVector &BV, unsigned bit); + void stopTrackingLocation(llvm::SmallBitVector &BV, unsigned bit); + bool isTrackingLocation(llvm::SmallBitVector &BV, unsigned bit); +}; + +} // end anonymous namespace + +bool BlockState::updateBBWriteSetIn(llvm::SmallBitVector &X) { + if (BBWriteSetIn == X) + return false; + BBWriteSetIn = X; + return true; +} + +void BlockState::startTrackingLocation(llvm::SmallBitVector &BV, unsigned i) { + BV.set(i); +} + +void BlockState::stopTrackingLocation(llvm::SmallBitVector &BV, unsigned i) { + BV.reset(i); +} + +bool BlockState::isTrackingLocation(llvm::SmallBitVector &BV, unsigned i) { + return BV.test(i); +} + +//===----------------------------------------------------------------------===// +// Top Level Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class DSEContext { + enum class ProcessKind { + ProcessOptimistic = 0, + ProcessPessimistic = 1, + ProcessNone = 2, + }; +private: + /// The module we are currently processing. + SILModule *Mod; + + /// The function we are currently processing. + SILFunction *F; + + /// Pass manager, used to get various analysis. + SILPassManager *PM; + + /// Alias Analysis. + AliasAnalysis *AA; + + /// Escape Analysis. + EscapeAnalysis *EA; + + /// Type Expansion Analysis. + TypeExpansionAnalysis *TE; + + /// Allocator. + llvm::BumpPtrAllocator BPA; + + /// Map every basic block to its location state. + llvm::DenseMap BBToLocState; + + /// Keeps the actual BlockStates. + std::vector BlockStates; + + /// Keeps all the locations for the current function. The BitVector in each + /// BlockState is then laid on top of it to keep track of which LSLocation + /// has an upward visible store. + std::vector LocationVault; + + /// Keeps a list of basic blocks that have StoreInsts. If a basic block does + /// not have StoreInst, we do not actually perform the last iteration where + /// DSE is actually performed on the basic block. + /// + /// NOTE: This is never populated for functions which will only require 1 + /// data flow iteration. For function that requires more than 1 iteration of + /// the data flow this is populated when the first time the functions is + /// walked, i.e. when the we generate the genset and killset. + llvm::DenseSet BBWithStores; + + /// Contains a map between location to their index in the LocationVault. + /// used to facilitate fast location to index lookup. + LSLocationIndexMap LocToBitIndex; + + /// Return the BlockState for the basic block this basic block belongs to. + BlockState *getBlockState(SILBasicBlock *B) { return BBToLocState[B]; } + + /// Return the BlockState for the basic block this instruction belongs to. + BlockState *getBlockState(SILInstruction *I) { + return getBlockState(I->getParent()); + } + + /// LSLocation written has been extracted, expanded and mapped to the bit + /// position in the bitvector. update the max store set using the bit + /// position. + void processWriteForMaxStoreSet(BlockState *S, unsigned bit); + + /// There is a read to a location, expand the location into individual fields + /// before processing them. + void processRead(SILInstruction *Inst, BlockState *S, SILValue M, DSEKind K); + void processReadForGenKillSet(BlockState *S, unsigned bit); + void processReadForDSE(BlockState *S, unsigned Bit); + + /// There is a write to a location, expand the location into individual fields + /// before processing them. + void processWrite(SILInstruction *Inst, BlockState *S, SILValue V, SILValue M, + DSEKind K); + void processWriteForGenKillSet(BlockState *S, unsigned bit); + bool processWriteForDSE(BlockState *S, unsigned bit); + + /// Process instructions. Extract locations from SIL LoadInst. + void processLoadInst(SILInstruction *Inst, DSEKind Kind); + + /// Process instructions. Extract locations from SIL StoreInst. + void processStoreInst(SILInstruction *Inst, DSEKind Kind); + + /// Process instructions. Extract locations from SIL DebugValueAddrInst. + /// DebugValueAddrInst maybe promoted to DebugValue, when this is done, + /// DebugValueAddrInst is effectively a read on the location. + void processDebugValueAddrInst(SILInstruction *I, DSEKind Kind); + void processDebugValueAddrInstForGenKillSet(SILInstruction *I); + void processDebugValueAddrInstForDSE(SILInstruction *I); + + /// Process instructions. Extract locations from unknown memory inst. + void processUnknownReadInst(SILInstruction *Inst, DSEKind Kind); + void processUnknownReadInstForGenKillSet(SILInstruction *Inst); + void processUnknownReadInstForDSE(SILInstruction *Inst); + + /// Check whether the instruction invalidate any locations due to change in + /// its location Base. + /// + /// This is to handle a case like this. + /// + /// class Foo { var a : Int = 12 } + /// for _ in 0 ...x { + /// x = Foo(); + /// x.a = 13 + /// } + /// x.a = 12 + /// + /// In this case, DSE cannot remove the x.a = 13 inside the loop. + /// + /// To do this, when the algorithm reaches the beginning of the basic block in + /// the loop it will need to invalidate the location in the BBWriteSetMid. + /// i.e. the base of the location is changed. + /// + /// If not, on the second iteration, the intersection of the successors of + /// the loop basic block will have store to x.a and therefore x.a = 13 can now + /// be considered dead. + void invalidateLSLocationBase(SILInstruction *Inst, DSEKind Kind); + void invalidateLSLocationBaseForGenKillSet(SILInstruction *Inst); + void invalidateLSLocationBaseForDSE(SILInstruction *Inst); + + /// Get the bit representing the location in the LocationVault. + unsigned getLocationBit(const LSLocation &L); + +public: + /// Constructor. + DSEContext(SILFunction *F, SILModule *M, SILPassManager *PM, + AliasAnalysis *AA, EscapeAnalysis *EA, TypeExpansionAnalysis *TE) + : Mod(M), F(F), PM(PM), AA(AA), EA(EA), TE(TE) {} + + /// Entry point for dead store elimination. + bool run(); + + /// Run the iterative DF to converge the BBWriteSetIn. + void runIterativeDSE(); + + /// Returns the escape analysis we use. + EscapeAnalysis *getEA() { return EA; } + + /// Returns the function currently being processing. + SILFunction *getFn() { return F; } + + /// Returns the location vault of the current function. + std::vector &getLocationVault() { return LocationVault; } + + /// Use a set of ad hoc rules to tell whether we should run a pessimistic + /// one iteration data flow on the function. + ProcessKind getProcessFunctionKind(); + + /// Compute the kill set for the basic block. return true if the store set + /// changes. + void processBasicBlockForDSE(SILBasicBlock *BB, bool PessimisticDF); + + /// Compute the genset and killset for the current basic block. + void processBasicBlockForGenKillSet(SILBasicBlock *BB); + + /// Compute the BBWriteSetOut and BBWriteSetIn for the current basic + /// block with the generated gen and kill set. + bool processBasicBlockWithGenKillSet(SILBasicBlock *BB); + + /// Intersect the successors' BBWriteSetIns. + void mergeSuccessorLiveIns(SILBasicBlock *BB); + + /// Update the BlockState based on the given instruction. + void processInstruction(SILInstruction *I, DSEKind Kind); +}; + +} // end anonymous namespace + +void BlockState::initReturnBlock(DSEContext &Ctx) { + auto *EA = Ctx.getEA(); + auto *Fn = Ctx.getFn(); + std::vector &LocationVault = Ctx.getLocationVault(); + + // We set the store bit at the end of the function if the location does + // not escape the function. + for (unsigned i = 0; i < LocationVault.size(); ++i) { + if (!LocationVault[i].isNonEscapingLocalLSLocation(Fn, EA)) + continue; + startTrackingLocation(BBWriteSetOut, i); + } +} + +void BlockState::init(DSEContext &Ctx, bool PessimisticDF) { + std::vector &LV = Ctx.getLocationVault(); + LocationNum = LV.size(); + // For function that requires just 1 iteration of the data flow to converge + // we set the initial state of BBWriteSetIn to 0. + // + // For other functions, the initial state of BBWriteSetIn should be all 1's. + // Otherwise the dataflow solution could be too conservative. + // + // Consider this case, the dead store by var a = 10 before the loop will not + // be eliminated if the BBWriteSetIn is set to 0 initially. + // + // var a = 10 + // for _ in 0...1024 {} + // a = 10 + // + // However, by doing so, we can only eliminate the dead stores after the + // data flow stabilizes. + // + BBWriteSetIn.resize(LocationNum, !PessimisticDF); + BBWriteSetOut.resize(LocationNum, false); + BBWriteSetMid.resize(LocationNum, false); + + // GenSet and KillSet initially empty. + BBGenSet.resize(LocationNum, false); + BBKillSet.resize(LocationNum, false); + + // MaxStoreSet is optimistically set to true initially. + BBMaxStoreSet.resize(LocationNum, true); + + // If basic block has no successor, then all local writes can be considered + // dead for block with no successor. + if (BB->succ_empty()) + initReturnBlock(Ctx); +} + +unsigned DSEContext::getLocationBit(const LSLocation &Loc) { + // Return the bit position of the given Loc in the LocationVault. The bit + // position is then used to set/reset the bitvector kept by each BlockState. + // + // We should have the location populated by the enumerateLSLocation at this + // point. + auto Iter = LocToBitIndex.find(Loc); + assert(Iter != LocToBitIndex.end() && "LSLocation should have been enum'ed"); + return Iter->second; +} + +DSEContext::ProcessKind DSEContext::getProcessFunctionKind() { + bool RunOneIteration = true; + unsigned BBCount = 0; + unsigned LocationCount = LocationVault.size(); + + // If all basic blocks will have their successors processed if + // the basic blocks in the functions are iterated in post order. + // Then this function can be processed in one iteration, i.e. no + // need to generate the genset and killset. + auto *PO = PM->getAnalysis()->get(F); + llvm::DenseSet HandledBBs; + for (SILBasicBlock *B : PO->getPostOrder()) { + ++BBCount; + for (auto &X : B->getSuccessors()) { + if (HandledBBs.find(X) == HandledBBs.end()) { + RunOneIteration = false; + break; + } + } + HandledBBs.insert(B); + } + + // Data flow may take too long to run. + if (BBCount * LocationCount > MaxLSLocationBBMultiplicationNone) + return ProcessKind::ProcessNone; + + // This function's data flow would converge in 1 iteration. + if (RunOneIteration) + return ProcessKind::ProcessPessimistic; + + // We run one pessimistic data flow to do dead store elimination on + // the function. + if (BBCount * LocationCount > MaxLSLocationBBMultiplicationPessimistic) + return ProcessKind::ProcessPessimistic; + + return ProcessKind::ProcessOptimistic; +} + +void DSEContext::processBasicBlockForGenKillSet(SILBasicBlock *BB) { + // Compute the MaxStoreSet at the end of the basic block. + auto *BBState = getBlockState(BB); + if (BB->succ_empty()) { + BBState->BBMaxStoreSet = BBState->BBWriteSetOut; + } else { + auto Iter = BB->succ_begin(); + BBState->BBMaxStoreSet = getBlockState(*Iter)->BBMaxStoreSet; + Iter = std::next(Iter); + for (auto EndIter = BB->succ_end(); Iter != EndIter; ++Iter) { + BBState->BBMaxStoreSet &= getBlockState(*Iter)->BBMaxStoreSet; + } + } + + // Compute the genset and killset. + // + // Also compute the MaxStoreSet at the current position of the basic block. + // + // This helps generating the genset and killset. If there is no way a + // location can have an upward visible store at a particular point in the + // basic block, we do not need to turn on the genset and killset for the + // location. + // + // Turning on the genset and killset can be costly as it involves querying + // the AA interface. + for (auto I = BB->rbegin(), E = BB->rend(); I != E; ++I) { + // Only process store insts. + if (isa(*I)) { + if (BBWithStores.find(BB) == BBWithStores.end()) + BBWithStores.insert(BB); + processStoreInst(&(*I), DSEKind::ComputeMaxStoreSet); + } + + // Compute the genset and killset for this instruction. + processInstruction(&(*I), DSEKind::BuildGenKillSet); + } +} + +bool DSEContext::processBasicBlockWithGenKillSet(SILBasicBlock *BB) { + // Compute the BBWriteSetOut at the end of the basic block. + mergeSuccessorLiveIns(BB); + + // Compute the BBWriteSet at the beginning of the basic block. + BlockState *S = getBlockState(BB); + S->BBWriteSetMid = S->BBWriteSetOut; + S->BBWriteSetMid.reset(S->BBKillSet); + S->BBWriteSetMid |= S->BBGenSet; + + // If BBWriteSetIn changes, then keep iterating until reached a fixed point. + return S->updateBBWriteSetIn(S->BBWriteSetMid); +} + +void DSEContext::processBasicBlockForDSE(SILBasicBlock *BB, + bool PessimisticDF) { + // If we know this is not a one iteration function which means its + // its BBWriteSetIn and BBWriteSetOut have been computed and converged, + // and this basic block does not even have StoreInsts, there is no point + // in processing every instruction in the basic block again as no store + // will be eliminated. + if (!PessimisticDF && BBWithStores.find(BB) == BBWithStores.end()) + return; + + // Intersect in the successor WriteSetIns. A store is dead if it is not read + // from any path to the end of the program. Thus an intersection. + mergeSuccessorLiveIns(BB); + + // Initialize the BBWriteSetMid to BBWriteSetOut to get started. + BlockState *S = getBlockState(BB); + S->BBWriteSetMid = S->BBWriteSetOut; + + // Process instructions in post-order fashion. + for (auto I = BB->rbegin(), E = BB->rend(); I != E; ++I) { + processInstruction(&(*I), DSEKind::PerformDSE); + } + + S->BBWriteSetIn = S->BBWriteSetMid; +} + +void DSEContext::mergeSuccessorLiveIns(SILBasicBlock *BB) { + // If basic block has no successor, then all local writes can be considered + // dead for block with no successor. + if (BB->succ_empty()) + return; + + // Use the first successor as the base condition. + BlockState *C = getBlockState(BB); + auto Iter = BB->succ_begin(); + C->BBWriteSetOut = getBlockState(*Iter)->BBWriteSetIn; + + /// Merge/intersection is very frequently performed, so it is important to make + /// it as cheap as possible. + /// + /// To do so, we canonicalize LSLocations, i.e. traced back to the underlying + /// object. Therefore, no need to do a O(N^2) comparison to figure out what is + /// dead along all successors. + /// + /// NOTE: Canonicalization does not solve the problem entirely. i.e. it is + /// still possible that 2 LSLocations with different bases that happen to be + /// the same object and field. In such case, we would miss a dead store + /// opportunity. But this happens less often with canonicalization. + Iter = std::next(Iter); + for (auto EndIter = BB->succ_end(); Iter != EndIter; ++Iter) { + C->BBWriteSetOut &= getBlockState(*Iter)->BBWriteSetIn; + } +} + +void DSEContext::invalidateLSLocationBaseForGenKillSet(SILInstruction *I) { + BlockState *S = getBlockState(I); + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (LocationVault[i].getBase().getDef() != I) + continue; + S->startTrackingLocation(S->BBKillSet, i); + S->stopTrackingLocation(S->BBGenSet, i); + } +} + +void DSEContext::invalidateLSLocationBaseForDSE(SILInstruction *I) { + BlockState *S = getBlockState(I); + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (!S->BBWriteSetMid.test(i)) + continue; + if (LocationVault[i].getBase().getDef() != I) + continue; + S->stopTrackingLocation(S->BBWriteSetMid, i); + } +} + +void DSEContext::invalidateLSLocationBase(SILInstruction *I, DSEKind Kind) { + // If this instruction defines the base of a location, then we need to + // invalidate any locations with the same base. + // + // Are we building genset and killset. + if (isBuildingGenKillSet(Kind)) { + invalidateLSLocationBaseForGenKillSet(I); + return; + } + + // Are we performing dead store elimination. + if (isPerformingDSE(Kind)) { + invalidateLSLocationBaseForDSE(I); + return; + } + + llvm_unreachable("Unknown DSE compute kind"); +} + +void DSEContext::processReadForDSE(BlockState *S, unsigned bit) { + // Remove any may/must-aliasing stores to the LSLocation, as they cant be + // used to kill any upward visible stores due to the interfering load. + LSLocation &R = LocationVault[bit]; + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (!S->isTrackingLocation(S->BBWriteSetMid, i)) + continue; + LSLocation &L = LocationVault[i]; + if (!L.isMayAliasLSLocation(R, AA)) + continue; + S->stopTrackingLocation(S->BBWriteSetMid, i); + } +} + +void DSEContext::processReadForGenKillSet(BlockState *S, unsigned bit) { + // Start tracking the read to this LSLocation in the killset and update + // the genset accordingly. + // + // Even though, LSLocations are canonicalized, we still need to consult + // alias analysis to determine whether 2 LSLocations are disjointed. + LSLocation &R = LocationVault[bit]; + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (!S->BBMaxStoreSet.test(i)) + continue; + // Do nothing if the read location NoAlias with the current location. + LSLocation &L = LocationVault[i]; + if (!L.isMayAliasLSLocation(R, AA)) + continue; + // Update the genset and kill set. + S->startTrackingLocation(S->BBKillSet, i); + S->stopTrackingLocation(S->BBGenSet, i); + } +} + +void DSEContext::processRead(SILInstruction *I, BlockState *S, SILValue Mem, + DSEKind Kind) { + // Construct a LSLocation to represent the memory read by this instruction. + // NOTE: The base will point to the actual object this inst is accessing, + // not this particular field. + // + // e.g. %1 = alloc_stack $S + // %2 = struct_element_addr %1, #a + // %3 = load %2 : $*Int + // + // Base will point to %1, but not %2. Projection path will indicate which + // field is accessed. + // + // This will make comparison between locations easier. This eases the + // implementation of intersection operator in the data flow. + LSLocation L(Mem); + + // If we cant figure out the Base or Projection Path for the read instruction, + // process it as an unknown memory instruction for now. + if (!L.isValid()) { + processUnknownReadInst(I, Kind); + return; + } + + // Expand the given Mem into individual fields and process them as separate + // reads. + LSLocationList Locs; + LSLocation::expand(L, &I->getModule(), Locs, TE); + + // Are we building the genset and killset. + if (isBuildingGenKillSet(Kind)) { + for (auto &E : Locs) { + // Only building the gen and kill sets for now. + processReadForGenKillSet(S, getLocationBit(E)); + } + return; + } + + // Are we performing the actual DSE. + if (isPerformingDSE(Kind)) { + for (auto &E : Locs) { + // This is the last iteration, compute BBWriteSetOut and perform DSE. + processReadForDSE(S, getLocationBit(E)); + } + return; + } + + llvm_unreachable("Unknown DSE compute kind"); +} + +bool DSEContext::processWriteForDSE(BlockState *S, unsigned bit) { + // If a tracked store must aliases with this store, then this store is dead. + bool StoreDead = false; + LSLocation &R = LocationVault[bit]; + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (!S->isTrackingLocation(S->BBWriteSetMid, i)) + continue; + // If 2 locations may alias, we can still keep both stores. + LSLocation &L = LocationVault[i]; + if (!L.isMustAliasLSLocation(R, AA)) + continue; + // There is a must alias store. No need to check further. + StoreDead = true; + break; + } + + // Track this new store. + S->startTrackingLocation(S->BBWriteSetMid, bit); + return StoreDead; +} + +void DSEContext::processWriteForGenKillSet(BlockState *S, unsigned bit) { + S->startTrackingLocation(S->BBGenSet, bit); +} + +void DSEContext::processWriteForMaxStoreSet(BlockState *S, unsigned bit) { + S->startTrackingLocation(S->BBMaxStoreSet, bit); +} + +void DSEContext::processWrite(SILInstruction *I, BlockState *S, SILValue Val, + SILValue Mem, DSEKind Kind) { + // Construct a LSLocation to represent the memory read by this instruction. + // NOTE: The base will point to the actual object this inst is accessing, + // not this particular field. + // + // e.g. %1 = alloc_stack $S + // %2 = struct_element_addr %1, #a + // store %3 to %2 : $*Int + // + // Base will point to %1, but not %2. Projection path will indicate which + // field is accessed. + // + // This will make comparison between locations easier. This eases the + // implementation of intersection operator in the data flow. + LSLocation L(Mem); + + // If we cant figure out the Base or Projection Path for the store + // instruction, simply ignore it. + if (!L.isValid()) + return; + + // Expand the given Mem into individual fields and process them as separate + // writes. + bool Dead = true; + LSLocationList Locs; + LSLocation::expand(L, Mod, Locs, TE); + llvm::SmallBitVector V(Locs.size()); + + // Are we computing max store set. + if (isComputeMaxStoreSet(Kind)) { + for (auto &E : Locs) { + // Update the max store set for the basic block. + processWriteForMaxStoreSet(S, getLocationBit(E)); + } + return; + } + + // Are we computing genset and killset. + if (isBuildingGenKillSet(Kind)) { + for (auto &E : Locs) { + // Only building the gen and kill sets here. + processWriteForGenKillSet(S, getLocationBit(E)); + } + // Data flow has not stabilized, do not perform the DSE just yet. + return; + } + + // We are doing the actual DSE. + assert(isPerformingDSE(Kind) && "Invalid computation kind"); + unsigned idx = 0; + for (auto &E : Locs) { + // This is the last iteration, compute BBWriteSetOut and perform the dead + // store elimination. + if (processWriteForDSE(S, getLocationBit(E))) + V.set(idx); + Dead &= V.test(idx); + ++idx; + } + + // Fully dead store - stores to all the components are dead, therefore this + // instruction is dead. + if (Dead) { + DEBUG(llvm::dbgs() << "Instruction Dead: " << *I << "\n"); + S->DeadStores.insert(I); + ++NumDeadStores; + return; + } + + // Partial dead store - stores to some locations are dead, but not all. This + // is a partially dead store. Also at this point we know what locations are + // dead. + llvm::DenseSet Alives; + if (V.any()) { + // Take out locations that are dead. + for (unsigned i = 0; i < V.size(); ++i) { + if (V.test(i)) + continue; + // This location is alive. + Alives.insert(Locs[i]); + } + + // Try to create as few aggregated stores as possible out of the locations. + LSLocation::reduce(L, Mod, Alives, TE); + + // Oops, we have too many smaller stores generated, bail out. + if (Alives.size() > MaxPartialDeadStoreCountLimit) + return; + + // At this point, we are performing a partial dead store elimination. + // + // Locations here have a projection path from their Base, but this + // particular instruction may not be accessing the base, so we need to + // *rebase* the locations w.r.t. to the current instruction. + SILValue B = Locs[0].getBase(); + Optional BP = ProjectionPath::getAddrProjectionPath(B, Mem); + // Strip off the projection path from base to the accessed field. + for (auto &X : Alives) { + X.subtractPaths(BP); + } + + // We merely setup the remaining live stores, but do not materialize in IR + // yet, These stores will be materialized before the algorithm exits. + for (auto &X : Alives) { + SILValue Value = + SILValueProjection::createExtract(Val, X.getPath(), I, true); + SILValue Addr = + SILValueProjection::createExtract(Mem, X.getPath(), I, false); + S->LiveStores[Addr] = Value; + } + + // Lastly, mark the old store as dead. + DEBUG(llvm::dbgs() << "Instruction Partially Dead: " << *I << "\n"); + S->DeadStores.insert(I); + ++NumPartialDeadStores; + } +} + +void DSEContext::processLoadInst(SILInstruction *I, DSEKind Kind) { + processRead(I, getBlockState(I), cast(I)->getOperand(), Kind); +} + +void DSEContext::processStoreInst(SILInstruction *I, DSEKind Kind) { + auto *SI = cast(I); + processWrite(I, getBlockState(I), SI->getSrc(), SI->getDest(), Kind); +} + +void DSEContext::processDebugValueAddrInstForGenKillSet(SILInstruction *I) { + BlockState *S = getBlockState(I); + SILValue Mem = cast(I)->getOperand(); + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (!S->BBMaxStoreSet.test(i)) + continue; + if (AA->isNoAlias(Mem, LocationVault[i].getBase())) + continue; + S->stopTrackingLocation(S->BBGenSet, i); + S->startTrackingLocation(S->BBKillSet, i); + } +} + +void DSEContext::processDebugValueAddrInstForDSE(SILInstruction *I) { + BlockState *S = getBlockState(I); + SILValue Mem = cast(I)->getOperand(); + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (!S->isTrackingLocation(S->BBWriteSetMid, i)) + continue; + if (AA->isNoAlias(Mem, LocationVault[i].getBase())) + continue; + S->stopTrackingLocation(S->BBWriteSetMid, i); + } +} + +void DSEContext::processDebugValueAddrInst(SILInstruction *I, DSEKind Kind) { + // Are we building genset and killset. + if (isBuildingGenKillSet(Kind)) { + processDebugValueAddrInstForGenKillSet(I); + return; + } + + // Are we performing dead store elimination. + if (isPerformingDSE(Kind)) { + processDebugValueAddrInstForDSE(I); + return; + } + + llvm_unreachable("Unknown DSE compute kind"); +} + +void DSEContext::processUnknownReadInstForGenKillSet(SILInstruction *I) { + BlockState *S = getBlockState(I); + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (!S->BBMaxStoreSet.test(i)) + continue; + if (!AA->mayReadFromMemory(I, LocationVault[i].getBase())) + continue; + // Update the genset and kill set. + S->startTrackingLocation(S->BBKillSet, i); + S->stopTrackingLocation(S->BBGenSet, i); + } +} + +void DSEContext::processUnknownReadInstForDSE(SILInstruction *I) { + BlockState *S = getBlockState(I); + for (unsigned i = 0; i < S->LocationNum; ++i) { + if (!S->isTrackingLocation(S->BBWriteSetMid, i)) + continue; + if (!AA->mayReadFromMemory(I, LocationVault[i].getBase())) + continue; + S->stopTrackingLocation(S->BBWriteSetMid, i); + } +} + +void DSEContext::processUnknownReadInst(SILInstruction *I, DSEKind Kind) { + // Are we building genset and killset. + if (isBuildingGenKillSet(Kind)) { + processUnknownReadInstForGenKillSet(I); + return; + } + + // Are we performing dead store elimination. + if (isPerformingDSE(Kind)) { + processUnknownReadInstForDSE(I); + return; + } + + llvm_unreachable("Unknown DSE compute kind"); +} + +void DSEContext::processInstruction(SILInstruction *I, DSEKind Kind) { + // If this instruction has side effects, but is inert from a store + // perspective, skip it. + if (isDeadStoreInertInstruction(I)) + return; + + // A set of ad-hoc rules to process instructions. + if (isa(I)) { + processLoadInst(I, Kind); + } else if (isa(I)) { + processStoreInst(I, Kind); + } else if (isa(I)) { + processDebugValueAddrInst(I, Kind); + } else if (I->mayReadFromMemory()) { + processUnknownReadInst(I, Kind); + } + + // Check whether this instruction will invalidate any other locations. + invalidateLSLocationBase(I, Kind); +} + +void DSEContext::runIterativeDSE() { + // Generate the genset and killset for each basic block. We can process the + // basic blocks in any order. + // + // We also Compute the max store set at the beginning of the basic block. + // + auto *PO = PM->getAnalysis()->get(F); + for (SILBasicBlock *B : PO->getPostOrder()) { + processBasicBlockForGenKillSet(B); + } + + // Process each basic block with the gen and kill set. Every time the + // BBWriteSetIn of a basic block changes, the optimization is rerun on its + // predecessors. + llvm::SmallVector WorkList; + llvm::DenseSet HandledBBs; + // Push into reverse post order so that we can pop from the back and get + // post order. + for (SILBasicBlock *B : PO->getReversePostOrder()) { + WorkList.push_back(B); + HandledBBs.insert(B); + } + while (!WorkList.empty()) { + SILBasicBlock *BB = WorkList.pop_back_val(); + HandledBBs.erase(BB); + if (processBasicBlockWithGenKillSet(BB)) { + for (auto X : BB->getPreds()) { + // We do not push basic block into the worklist if its already + // in the worklist. + if (HandledBBs.find(X) != HandledBBs.end()) + continue; + WorkList.push_back(X); + } + } + } +} + +bool DSEContext::run() { + // Is this a one iteration function. + auto *PO = PM->getAnalysis()->get(F); + + // Walk over the function and find all the locations accessed by + // this function. + LSLocation::enumerateLSLocations(*F, LocationVault, LocToBitIndex, TE); + + // Check how to optimize this function. + ProcessKind Kind = getProcessFunctionKind(); + + // We do not optimize this function at all. + if (Kind == ProcessKind::ProcessNone) + return false; + + // Do we run a pessimistic data flow ? + bool PessimisticDF = Kind == ProcessKind::ProcessOptimistic ? false : true; + + // For all basic blocks in the function, initialize a BB state. + // + // DenseMap has a minimum size of 64, while many functions do not have more + // than 64 basic blocks. Therefore, allocate the BlockState in a vector and + // use pointer in BBToLocState to access them. + for (auto &B : *F) { + BlockStates.push_back(BlockState(&B)); + // Since we know all the locations accessed in this function, we can resize + // the bit vector to the appropriate size. + BlockStates.back().init(*this, PessimisticDF); + } + + // Initialize the BBToLocState mapping. + for (auto &S : BlockStates) { + BBToLocState[S.getBB()] = &S; + } + + // We perform dead store elimination in the following phases. + // + // Phase 1. we compute the max store set at the beginning of the basic block. + // + // Phase 2. we compute the genset and killset for every basic block. + // + // Phase 3. we run the data flow with the genset and killset until + // BBWriteSetIns stop changing. + // + // Phase 4. we run the data flow for the last iteration and perform the DSE. + // + // Phase 5. we remove the dead stores. + // + // Phase 1 - 3 are only performed when we know the data flow will not + // converge in a single iteration. Otherwise, we only run phase 4 and 5 + // on the function. + + // We need to run the iterative data flow on the function. + if (!PessimisticDF) { + runIterativeDSE(); + } + + // The data flow has stabilized, run one last iteration over all the basic + // blocks and try to remove dead stores. + for (SILBasicBlock *B : PO->getPostOrder()) { + processBasicBlockForDSE(B, PessimisticDF); + } + + // Finally, delete the dead stores and create the live stores. + bool Changed = false; + for (SILBasicBlock &BB : *F) { + // Create the stores that are alive due to partial dead stores. + for (auto &I : getBlockState(&BB)->LiveStores) { + Changed = true; + SILInstruction *IT = cast(I.first)->getNextNode(); + SILBuilderWithScope Builder(IT); + Builder.createStore(I.first.getLoc().getValue(), I.second, I.first); + } + // Delete the dead stores. + for (auto &I : getBlockState(&BB)->DeadStores) { + Changed = true; + DEBUG(llvm::dbgs() << "*** Removing: " << *I << " ***\n"); + // This way, we get rid of pass dependence on DCE. + recursivelyDeleteTriviallyDeadInstructions(I, true); + } + } + + return Changed; +} + +//===----------------------------------------------------------------------===// +// Top Level Entry Point +//===----------------------------------------------------------------------===// + +namespace { + +class DeadStoreElimination : public SILFunctionTransform { +public: + StringRef getName() override { return "SIL Dead Store Elimination"; } + + /// The entry point to the transformation. + void run() override { + auto *AA = PM->getAnalysis(); + auto *EA = PM->getAnalysis(); + auto *TE = PM->getAnalysis(); + SILFunction *F = getFunction(); + DEBUG(llvm::dbgs() << "*** DSE on function: " << F->getName() << " ***\n"); + + DSEContext DSE(F, &F->getModule(), PM, AA, EA, TE); + if (DSE.run()) { + invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions); + } + } +}; + +} // end anonymous namespace + +SILTransform *swift::createDeadStoreElimination() { + return new DeadStoreElimination(); +} diff --git a/lib/SILOptimizer/Transforms/Devirtualizer.cpp b/lib/SILOptimizer/Transforms/Devirtualizer.cpp new file mode 100644 index 0000000000000..5dd965d0e9e98 --- /dev/null +++ b/lib/SILOptimizer/Transforms/Devirtualizer.cpp @@ -0,0 +1,99 @@ +//===--- Devirtualizer.cpp - Devirtualize indirect calls -----------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Devirtualize indirect calls to functions, turning them into direct function +// references. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-devirtualizer" + +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h" +#include "swift/SILOptimizer/Utils/Devirtualize.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "llvm/ADT/SmallVector.h" + +using namespace swift; + +namespace { + +class Devirtualizer : public SILFunctionTransform { + + bool devirtualizeAppliesInFunction(SILFunction &F, + ClassHierarchyAnalysis *CHA); + + /// The entry point to the transformation. + void run() override { + SILFunction &F = *getFunction(); + ClassHierarchyAnalysis *CHA = PM->getAnalysis(); + DEBUG(llvm::dbgs() << "***** Devirtualizer on function:" << F.getName() + << " *****\n"); + + if (devirtualizeAppliesInFunction(F, CHA)) + invalidateAnalysis(SILAnalysis::InvalidationKind::CallsAndInstructions); + } + + StringRef getName() override { return "Devirtualizer"; } +}; + +} // end anonymous namespace + +bool Devirtualizer::devirtualizeAppliesInFunction(SILFunction &F, + ClassHierarchyAnalysis *CHA) { + bool Changed = false; + llvm::SmallVector DeadApplies; + + for (auto &BB : F) { + for (auto It = BB.begin(), End = BB.end(); It != End;) { + auto &I = *It++; + + // Skip non-apply instructions. + + auto Apply = FullApplySite::isa(&I); + if (!Apply) + continue; + + auto NewInstPair = tryDevirtualizeApply(Apply, CHA); + if (!NewInstPair.second) + continue; + + Changed = true; + + auto *CalleeFn = NewInstPair.second.getCalleeFunction(); + assert(CalleeFn && "Expected devirtualized callee!"); + + // We may not have optimized these functions yet, and it could + // be beneficial to rerun some earlier passes on the current + // function now that we've made these direct references visible. + if (CalleeFn->isDefinition() && CalleeFn->shouldOptimize()) + notifyPassManagerOfFunction(CalleeFn); + + auto *AI = Apply.getInstruction(); + if (!isa(AI)) + AI->replaceAllUsesWith(NewInstPair.first); + + DeadApplies.push_back(AI); + } + } + + // Remove all the now-dead applies. + while (!DeadApplies.empty()) { + auto *AI = DeadApplies.pop_back_val(); + recursivelyDeleteTriviallyDeadInstructions(AI, true); + } + + return Changed; +} + +SILTransform *swift::createDevirtualizer() { return new Devirtualizer(); } diff --git a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp new file mode 100644 index 0000000000000..48f5c2e55cfce --- /dev/null +++ b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp @@ -0,0 +1,116 @@ +//===--- GenericSpecializer.cpp - Specialization of generic functions -----===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Specialize calls to generic functions by substituting static type +// information. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-generic-specializer" + +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SILOptimizer/Utils/Generics.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "llvm/ADT/SmallVector.h" + +using namespace swift; + +namespace { + +class GenericSpecializer : public SILFunctionTransform { + + bool specializeAppliesInFunction(SILFunction &F); + + /// The entry point to the transformation. + void run() override { + SILFunction &F = *getFunction(); + DEBUG(llvm::dbgs() << "***** GenericSpecializer on function:" << F.getName() + << " *****\n"); + + if (specializeAppliesInFunction(F)) + invalidateAnalysis(SILAnalysis::InvalidationKind::Everything); + } + + StringRef getName() override { return "Generic Specializer"; } +}; + +} // end anonymous namespace + +bool GenericSpecializer::specializeAppliesInFunction(SILFunction &F) { + bool Changed = false; + llvm::SmallVector DeadApplies; + + for (auto &BB : F) { + for (auto It = BB.begin(), End = BB.end(); It != End;) { + auto &I = *It++; + + // Skip non-apply instructions, apply instructions with no + // substitutions, apply instructions where we do not statically + // know the called function, and apply instructions where we do + // not have the body of the called function. + + ApplySite Apply = ApplySite::isa(&I); + if (!Apply || !Apply.hasSubstitutions()) + continue; + + auto *Callee = Apply.getCalleeFunction(); + if (!Callee || !Callee->isDefinition()) + continue; + + // We have a call that can potentially be specialized, so + // attempt to do so. + + // The specializer helper function currently expects a collector + // argument, but we aren't going to make use of the results so + // we'll have our filter always return false; + auto Filter = [](SILInstruction *I) -> bool { return false; }; + CloneCollector Collector(Filter); + + SILFunction *SpecializedFunction; + + auto Specialized = + trySpecializeApplyOfGeneric(Apply, SpecializedFunction, Collector); + + if (Specialized) { + Changed = true; + + // If calling the specialization utility resulted in a new + // function (as opposed to returning a previous + // specialization), we need to notify the pass manager so that + // the new function gets optimized. + if (SpecializedFunction) + notifyPassManagerOfFunction(SpecializedFunction); + + auto *AI = Apply.getInstruction(); + + if (!isa(AI)) + AI->replaceAllUsesWith(Specialized.getInstruction()); + + DeadApplies.push_back(AI); + } + } + } + + // Remove all the now-dead applies. + while (!DeadApplies.empty()) { + auto *AI = DeadApplies.pop_back_val(); + recursivelyDeleteTriviallyDeadInstructions(AI, true); + } + + return Changed; +} + +SILTransform *swift::createGenericSpecializer() { + return new GenericSpecializer(); +} diff --git a/lib/SILPasses/Scalar/MergeCondFail.cpp b/lib/SILOptimizer/Transforms/MergeCondFail.cpp similarity index 90% rename from lib/SILPasses/Scalar/MergeCondFail.cpp rename to lib/SILOptimizer/Transforms/MergeCondFail.cpp index 27f3dde437c65..09ceaadd1a5c0 100644 --- a/lib/SILPasses/Scalar/MergeCondFail.cpp +++ b/lib/SILOptimizer/Transforms/MergeCondFail.cpp @@ -1,8 +1,8 @@ -//===-- MergeCondFail.cpp - Merge cond_fail instructions -*- C++ -*-------===// +//===--- MergeCondFail.cpp - Merge cond_fail instructions ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,10 +12,10 @@ #define DEBUG_TYPE "merge-cond_fail" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILInstruction.h" @@ -37,7 +37,7 @@ namespace { /// /// We can merge cond_fail instructions if there is no side-effect or memory /// write in between them. -/// This pass merges cond_fail instructions by building the disconjunction of +/// This pass merges cond_fail instructions by building the disjunction of /// their operands. class MergeCondFailInsts : public SILFunctionTransform { public: diff --git a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp b/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp new file mode 100644 index 0000000000000..0caa641733823 --- /dev/null +++ b/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp @@ -0,0 +1,1398 @@ +//===--- RedundantLoadElimination.cpp - SIL Load Forwarding ---------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// This pass eliminates redundant loads. +/// +/// A load can be eliminated if its value has already been held somewhere, +/// i.e. generated by a previous load, LSLocation stored by a known value. +/// +/// In this case, one can replace the load instruction with the previous +/// results. +/// +/// Redundant Load Elimination (RLE) eliminates such loads by: +/// +/// 1. Introducing a notion of a LSLocation that is used to model object +/// fields. (See below for more details). +/// +/// 2. Introducing a notion of a LSValue that is used to model the value +/// that currently resides in the associated LSLocation on the particular +/// program path. (See below for more details). +/// +/// 3. Performing a RPO walk over the control flow graph, tracking any +/// LSLocations that are read from or stored into in each basic block. The +/// read or stored value, kept in a map between LSLocation and LSValue, +/// becomes the available value for the LSLocation. +/// +/// 4. An optimistic iterative intersection-based dataflow is performed on the +/// gensets until convergence. +/// +/// At the core of RLE, there is the LSLocation class. A LSLocation is an +/// abstraction of an object field in program. It consists of a base and a +/// projection path to the field accessed. +/// +/// In SIL, one can access an aggregate as a whole, i.e. store to a struct with +/// 2 Int fields. A store like this will generate 2 *indivisible* LSLocations, +/// 1 for each field and in addition to keeping a list of LSLocation, RLE also +/// keeps their available LSValues. We call it *indivisible* because it +/// cannot be broken down to more LSLocations. +/// +/// LSValue consists of a base - a SILValue from the load or store inst, +/// as well as a projection path to which the field it represents. So, a +/// store to an 2-field struct as mentioned above will generate 2 LSLocations +/// and 2 LSValues. +/// +/// Every basic block keeps a map between LSLocation and LSValue. By +/// keeping the LSLocation and LSValue in their indivisible form, one +/// can easily find which part of the load is redundant and how to compute its +/// forwarding value. +/// +/// Given the case which the 2 fields of the struct both have available values, +/// RLE can find their LSValues (maybe by struct_extract from a larger +/// value) and then aggregate them. +/// +/// However, this may introduce a lot of extraction and aggregation which may +/// not be necessary. i.e. a store the struct followed by a load from the +/// struct. To solve this problem, when RLE detects that a load instruction +/// can be replaced by forwarded value, it will try to find minimum # of +/// extractions necessary to form the forwarded value. It will group the +/// available value's by the LSValue base, i.e. the LSValues come from the +/// same instruction, and then use extraction to obtain the needed components +/// of the base. +/// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-redundant-load-elim" +#include "swift/SIL/Projection.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILBuilder.h" +#include "swift/SIL/SILValueProjection.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/ValueTracking.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +STATISTIC(NumForwardedLoads, "Number of loads forwarded"); + +/// ComputeAvailSetMax - If we ignore all unknown writes, what is the max +/// available set that can reach the a certain point in a basic block. This +/// helps generating the genset and killset. i.e. if there is no downward visible +/// value that can reach the end of a basic block, then we know that the genset +/// and killset for the location need not be set. +/// +/// ComputeAvailGenKillSet - Build the genset and killset of the basic block. +/// +/// ComputeAvailSet - Compute the available set at the end of the basic block. +/// +/// ComputeAvailValue - Compute the available value at the end of the basic +/// block. +/// +/// PerformRLE - Perform the actual redundant load elimination. +enum class RLEKind : unsigned { + ComputeAvailSetMax = 0, + ComputeAvailGenKillSet = 1, + ComputeAvailSet = 2, + ComputeAvailValue = 3, + PerformRLE = 4, +}; + +//===----------------------------------------------------------------------===// +// Utility Functions +//===----------------------------------------------------------------------===// + +static bool inline isComputeAvailSetMax(RLEKind Kind) { + return Kind == RLEKind::ComputeAvailSetMax; +} + +static bool inline isComputeAvailGenKillSet(RLEKind Kind) { + return Kind == RLEKind::ComputeAvailGenKillSet; +} + +static bool inline isComputeAvailSet(RLEKind Kind) { + return Kind == RLEKind::ComputeAvailSet; +} + +static bool inline isComputeAvailValue(RLEKind Kind) { + return Kind == RLEKind::ComputeAvailValue; +} + +static bool inline isPerformingRLE(RLEKind Kind) { + return Kind == RLEKind::PerformRLE; +} + +/// Return true if all basic blocks have their predecessors processed if +/// they are iterated in reverse post order. +static bool isOneIterationFunction(PostOrderFunctionInfo *PO) { + llvm::DenseSet HandledBBs; + for (SILBasicBlock *B : PO->getReversePostOrder()) { + for (auto X : B->getPreds()) { + if (HandledBBs.find(X) == HandledBBs.end()) + return false; + } + HandledBBs.insert(B); + } + return true; +} + +/// Returns true if this is an instruction that may have side effects in a +/// general sense but are inert from a load store perspective. +static bool isRLEInertInstruction(SILInstruction *Inst) { + switch (Inst->getKind()) { + case ValueKind::StrongRetainInst: + case ValueKind::StrongRetainUnownedInst: + case ValueKind::UnownedRetainInst: + case ValueKind::RetainValueInst: + case ValueKind::DeallocStackInst: + case ValueKind::CondFailInst: + case ValueKind::IsUniqueInst: + case ValueKind::IsUniqueOrPinnedInst: + return true; + default: + return false; + } +} + +/// Returns true if the given basic block is reachable from the entry block. +/// +/// TODO: this is very inefficient, can we make use of the domtree. +static bool isReachable(SILBasicBlock *Block) { + SmallPtrSet Visited; + llvm::SmallVector Worklist; + SILBasicBlock *EntryBB = &*Block->getParent()->begin(); + Worklist.push_back(EntryBB); + Visited.insert(EntryBB); + + while (!Worklist.empty()) { + auto *CurBB = Worklist.back(); + Worklist.pop_back(); + + if (CurBB == Block) + return true; + + for (auto &Succ : CurBB->getSuccessors()) + if (!Visited.insert(Succ).second) + Worklist.push_back(Succ); + } + return false; +} + +//===----------------------------------------------------------------------===// +// Basic Block Location State +//===----------------------------------------------------------------------===// +namespace { + +// If there are too many locations in the function, we bail out. +constexpr unsigned MaxLSLocationLimit = 2048; + +/// forward declaration. +class RLEContext; + +/// State of the load store in one basic block which allows for forwarding from +/// loads, stores -> loads +class BlockState { +public: + enum class ValueState : unsigned { + CoverValues = 0, + ConcreteValues = 1, + CoverAndConcreteValues = 2, + }; + +private: + /// # of locations in the LocationVault. + unsigned LocationNum; + + /// The basic block that we are optimizing. + SILBasicBlock *BB; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If the bit is set, then the location currently has an + /// downward visible value at the beginning of the basic block. + llvm::SmallBitVector ForwardSetIn; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If the bit is set, then the location currently has an + /// downward visible value at the end of the basic block. + llvm::SmallBitVector ForwardSetOut; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If we ignore all unknown write, whats the maximum set + /// of available locations at the current position in the basic block. + llvm::SmallBitVector ForwardSetMax; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If the bit is set, then the basic block generates a + /// value for the location. + llvm::SmallBitVector BBGenSet; + + /// A bit vector for which the ith bit represents the ith LSLocation in + /// LocationVault. If the bit is set, then the basic block kills the + /// value for the location. + llvm::SmallBitVector BBKillSet; + + /// This is map between LSLocations and their available values at the + /// beginning of this basic block. + ValueTableMap ForwardValIn; + + /// This is map between LSLocations and their available values at the end of + /// this basic block. + ValueTableMap ForwardValOut; + + /// Keeps a list of replaceable instructions in the current basic block as + /// well as their SILValue replacement. + llvm::DenseMap RedundantLoads; + + /// LSLocation read or written has been extracted, expanded and mapped to the + /// bit position in the bitvector. Update it in the ForwardSetIn of the + /// current basic block. + void updateForwardSetForRead(RLEContext &Ctx, unsigned bit); + void updateForwardSetForWrite(RLEContext &Ctx, unsigned bit); + + /// LSLocation read or written has been extracted, expanded and mapped to the + /// bit position in the bitvector. Update it in the genset and killset of the + /// current basic block. + void updateGenKillSetForRead(RLEContext &Ctx, unsigned bit); + void updateGenKillSetForWrite(RLEContext &Ctx, unsigned bit); + + /// LSLocation read or written has been extracted, expanded and mapped to the + /// bit position in the bitvector. Update it in the MaxAvailForwardSet of the + /// current basic block. + void updateMaxAvailForwardSetForRead(RLEContext &Ctx, unsigned bit); + void updateMaxAvailForwardSetForWrite(RLEContext &Ctx, unsigned bit); + + /// LSLocation written has been extracted, expanded and mapped to the bit + /// position in the bitvector. process it using the bit position. + void updateForwardSetAndValForRead(RLEContext &Ctx, unsigned lbit, + unsigned vbit); + void updateForwardSetAndValForWrite(RLEContext &Ctx, unsigned lbit, + unsigned vbit); + + /// There is a read to a LSLocation, expand the LSLocation into individual + /// fields before processing them. + void processRead(RLEContext &Ctx, SILInstruction *I, SILValue Mem, + SILValue Val, RLEKind Kind); + + /// There is a write to a LSLocation, expand the LSLocation into individual + /// fields before processing them. + void processWrite(RLEContext &Ctx, SILInstruction *I, SILValue Mem, + SILValue Val, RLEKind Kind); + + /// BitVector manipulation functions. + void startTrackingLocation(llvm::SmallBitVector &BV, unsigned bit); + void stopTrackingLocation(llvm::SmallBitVector &BV, unsigned bit); + bool isTrackingLocation(llvm::SmallBitVector &BV, unsigned bit); + void startTrackingValue(ValueTableMap &VM, unsigned lbit, unsigned vbit); + void stopTrackingValue(ValueTableMap &VM, unsigned bit); + +public: + BlockState() = default; + + void init(SILBasicBlock *NewBB, unsigned bitcnt, bool reachable) { + BB = NewBB; + LocationNum = bitcnt; + // For reachable basic blocks, the initial state of ForwardSetOut should be + // all 1's. Otherwise the dataflow solution could be too conservative. + // + // Consider this case, the forwardable value by var a = 10 before the loop + // will not be forwarded if the ForwardSetOut is set to 0 initially. + // + // var a = 10 + // for _ in 0...1024 {} + // use(a); + // + // However, by doing so, we can only do the data forwarding after the + // data flow stabilizes. + // + // We set the initial state of unreachable block to 0, as we do not have + // a value for the location. + // + // This is a bit conservative as we could be missing forwarding + // opportunities. i.e. a joint block with 1 predecessor being an + // unreachable block. + // + // we rely on other passes to clean up unreachable block. + ForwardSetIn.resize(LocationNum, false); + ForwardSetOut.resize(LocationNum, reachable); + + ForwardSetMax.resize(LocationNum, true); + + BBGenSet.resize(LocationNum, false); + BBKillSet.resize(LocationNum, false); + } + + /// Initialize the AvailSetMax by intersecting this basic block's + /// predecessors' AvailSetMax. + void mergePredecessorsAvailSetMax(RLEContext &Ctx); + + /// Initialize the AvailSet by intersecting this basic block' predecessors' + /// AvailSet. + void mergePredecessorAvailSet(RLEContext &Ctx); + + /// Initialize the AvailSet and AvailVal of the current basic block. + void mergePredecessorAvailSetAndValue(RLEContext &Ctx); + + /// Reached the end of the basic block, update the ForwardValOut with the + /// ForwardValIn. + void updateForwardValOut() { ForwardValOut = ForwardValIn; } + + /// Check whether the ForwardSetOut has changed. If it does, we need to + /// rerun the data flow to reach fixed point. + bool updateForwardSetOut() { + if (ForwardSetIn == ForwardSetOut) + return false; + ForwardSetOut = ForwardSetIn; + return true; + } + + /// Returns the current basic block we are processing. + SILBasicBlock *getBB() const { return BB; } + + /// Returns the ForwardValIn for the current basic block. + ValueTableMap &getForwardValIn() { return ForwardValIn; } + + /// Returns the ForwardValOut for the current basic block. + ValueTableMap &getForwardValOut() { return ForwardValOut; } + + /// Returns the redundant loads and their replacement in the currently basic + /// block. + llvm::DenseMap &getRL() { return RedundantLoads; } + + /// Look into the value for the given LSLocation at end of the basic block, + /// return one of the three ValueState type. + ValueState getValueStateAtEndOfBlock(RLEContext &Ctx, LSLocation &L); + + /// Wrappers to query the value state of the location in this BlockState. + bool isCoverValues(RLEContext &Ctx, LSLocation &L) { + return getValueStateAtEndOfBlock(Ctx, L) == ValueState::CoverValues; + } + bool isConcreteValues(RLEContext &Ctx, LSLocation &L) { + return getValueStateAtEndOfBlock(Ctx, L) == ValueState::ConcreteValues; + } + + /// Iterate over the instructions in the basic block in forward order and + /// process them w.r.t. the given \p Kind. + void processInstructionWithKind(RLEContext &Ctx, SILInstruction *I, + RLEKind Kind); + void processBasicBlockWithKind(RLEContext &Ctx, RLEKind Kind); + + /// Process the current basic block with the genset and killset. Return true + /// if the ForwardSetOut changes. + bool processBasicBlockWithGenKillSet(); + + /// Set up the value for redundant load elimination. + bool setupRLE(RLEContext &Ctx, SILInstruction *I, SILValue Mem); + + /// Process Instruction which writes to memory in an unknown way. + void processUnknownWriteInst(RLEContext &Ctx, SILInstruction *I, + RLEKind Kind); + void processUnknownWriteInstForGenKillSet(RLEContext &Ctx, SILInstruction *I); + void processUnknownWriteInstForRLE(RLEContext &Ctx, SILInstruction *I); + + /// Process LoadInst. Extract LSLocations from LoadInst. + void processLoadInst(RLEContext &Ctx, LoadInst *LI, RLEKind Kind); + + /// Process LoadInst. Extract LSLocations from StoreInst. + void processStoreInst(RLEContext &Ctx, StoreInst *SI, RLEKind Kind); + + /// Returns a *single* forwardable SILValue for the given LSLocation right + /// before the InsertPt instruction. + SILValue reduceValuesAtEndOfBlock(RLEContext &Ctx, LSLocation &L); +}; + +} // end anonymous namespace + +//===----------------------------------------------------------------------===// +// RLEContext Interface +//===----------------------------------------------------------------------===// + +namespace { + +using BBValueMap = llvm::DenseMap; + +/// This class stores global state that we use when computing redundant load and +/// their replacement in each basic block. +class RLEContext { + /// Function currently processing. + SILFunction *Fn; + + /// The alias analysis that we will use during all computations. + AliasAnalysis *AA; + + /// The type expansion analysis we will use during all computations. + TypeExpansionAnalysis *TE; + + /// The SSA updater we use to materialize covering values. + SILSSAUpdater Updater; + + /// The range that we use to iterate over the post order and reverse post + /// order of the given function. + PostOrderFunctionInfo *PO; + + /// Keeps all the locations for the current function. The BitVector in each + /// BlockState is then laid on top of it to keep track of which LSLocation + /// has a downward available value. + std::vector LocationVault; + + /// Contains a map between LSLocation to their index in the LocationVault. + /// Use for fast lookup. + llvm::DenseMap LocToBitIndex; + + /// Keeps all the loadstorevalues for the current function. The BitVector in + /// each g is then laid on top of it to keep track of which LSLocation + /// has a downward available value. + std::vector LSValueVault; + + /// Contains a map between LSLocation to their index in the LocationVault. + /// Use for fast lookup. + llvm::DenseMap ValToBitIndex; + + /// A map from each BasicBlock to its BlockState. + llvm::SmallDenseMap BBToLocState; + + /// A map for each basic block and whether its predecessors have forwardable + /// edges. + llvm::DenseMap ForwardableEdge; + +public: + RLEContext(SILFunction *F, AliasAnalysis *AA, TypeExpansionAnalysis *TE, + PostOrderFunctionInfo *PO); + + RLEContext(const RLEContext &) = delete; + RLEContext(RLEContext &&) = default; + ~RLEContext() = default; + + /// Entry point to redundant load elimination. + bool run(); + + /// Run the iterative data flow until convergence. + void runIterativeRLE(); + + /// Process the basic blocks for the gen and kill set. + void processBasicBlocksForGenKillSet(); + + /// Process the basic blocks with the gen and kill set. + void processBasicBlocksWithGenKillSet(); + + /// Process the basic block for values generated in the current basic + /// block. + void processBasicBlocksForAvailValue(); + + /// Process basic blocks to perform the redundant load elimination. + void processBasicBlocksForRLE(); + + /// Returns the alias analysis we will use during all computations. + AliasAnalysis *getAA() const { return AA; } + + /// Returns the current type expansion analysis we are . + TypeExpansionAnalysis *getTE() const { return TE; } + + /// Return the BlockState for the basic block this basic block belongs to. + BlockState &getBlockState(SILBasicBlock *B) { return BBToLocState[B]; } + + /// Get the bit representing the LSLocation in the LocationVault. + unsigned getLocationBit(const LSLocation &L); + + /// Given the bit, get the LSLocation from the LocationVault. + LSLocation &getLocation(const unsigned index); + + /// Get the bit representing the LSValue in the LSValueVault. + unsigned getValueBit(const LSValue &L); + + /// Given the bit, get the LSValue from the LSValueVault. + LSValue &getValue(const unsigned index); + + /// Transitively collect all the values that make up this location and + /// create a SILArgument out of them. + SILValue computePredecessorLocationValue(SILBasicBlock *BB, LSLocation &L); + + /// Given a LSLocation, try to collect all the LSValues for this LSLocation + /// in the given basic block. If part of the locations have covering values, + /// find the values in its predecessors. + bool collectLocationValues(SILBasicBlock *BB, LSLocation &L, + LSLocationValueMap &Values, ValueTableMap &VM); +}; + +} // end anonymous namespace + +void BlockState::startTrackingValue(ValueTableMap &VM, unsigned l, unsigned v){ + VM[l] = v; +} + +void BlockState::stopTrackingValue(ValueTableMap &VM, unsigned bit) { + VM.erase(bit); +} + +bool BlockState::isTrackingLocation(llvm::SmallBitVector &BV, unsigned bit) { + return BV.test(bit); +} + +void BlockState::startTrackingLocation(llvm::SmallBitVector &BV, unsigned bit) { + BV.set(bit); +} + +void BlockState::stopTrackingLocation(llvm::SmallBitVector &BV, unsigned bit) { + BV.reset(bit); +} + +void BlockState::mergePredecessorsAvailSetMax(RLEContext &Ctx) { + if (BB->pred_empty()) { + ForwardSetMax.reset(); + return; + } + + auto Iter = BB->pred_begin(); + ForwardSetMax = Ctx.getBlockState(*Iter).ForwardSetMax; + Iter = std::next(Iter); + for (auto EndIter = BB->pred_end(); Iter != EndIter; ++Iter) { + ForwardSetMax &= Ctx.getBlockState(*Iter).ForwardSetMax; + } +} + +void BlockState::mergePredecessorAvailSet(RLEContext &Ctx) { + // Clear the state if the basic block has no predecessor. + if (BB->getPreds().begin() == BB->getPreds().end()) { + ForwardSetIn.reset(); + return; + } + + auto Iter = BB->pred_begin(); + ForwardSetIn = Ctx.getBlockState(*Iter).ForwardSetOut; + Iter = std::next(Iter); + for (auto EndIter = BB->pred_end(); Iter != EndIter; ++Iter) { + ForwardSetIn &= Ctx.getBlockState(*Iter).ForwardSetOut; + } +} + +void BlockState::mergePredecessorAvailSetAndValue(RLEContext &Ctx) { + // Clear the state if the basic block has no predecessor. + if (BB->getPreds().begin() == BB->getPreds().end()) { + ForwardSetIn.reset(); + ForwardValIn.clear(); + return; + } + + auto Iter = BB->pred_begin(); + ForwardSetIn = Ctx.getBlockState(*Iter).ForwardSetOut; + ForwardValIn = Ctx.getBlockState(*Iter).ForwardValOut; + Iter = std::next(Iter); + for (auto EndIter = BB->pred_end(); Iter != EndIter; ++Iter) { + BlockState &OtherState = Ctx.getBlockState(*Iter); + ForwardSetIn &= OtherState.ForwardSetOut; + + // Merge in the predecessor state. + for (unsigned i = 0; i < LocationNum; ++i) { + if (OtherState.ForwardSetOut[i]) { + // There are multiple values from multiple predecessors, set this as + // a covering value. We do not need to track the value itself, as we + // can always go to the predecessors BlockState to find it. + ForwardValIn[i] = Ctx.getValueBit(LSValue(true)); + continue; + } + // If this location does have an available value, then clear it. + stopTrackingValue(ForwardValIn, i); + stopTrackingLocation(ForwardSetIn, i); + } + } +} + +void BlockState::processBasicBlockWithKind(RLEContext &Ctx, RLEKind Kind) { + // Iterate over instructions in forward order. + for (auto &II : *BB) { + processInstructionWithKind(Ctx, &II, Kind); + } +} + +bool BlockState::processBasicBlockWithGenKillSet() { + ForwardSetIn.reset(BBKillSet); + ForwardSetIn |= BBGenSet; + return updateForwardSetOut(); +} + +SILValue BlockState::reduceValuesAtEndOfBlock(RLEContext &Ctx, LSLocation &L) { + // First, collect current available locations and their corresponding values + // into a map. + LSLocationValueMap Values; + + LSLocationList Locs; + LSLocation::expand(L, &BB->getModule(), Locs, Ctx.getTE()); + + // Find the values that this basic block defines and the locations which + // we do not have a concrete value in the current basic block. + ValueTableMap &OTM = getForwardValOut(); + for (unsigned i = 0; i < Locs.size(); ++i) { + Values[Locs[i]] = Ctx.getValue(OTM[Ctx.getLocationBit(Locs[i])]); + } + + // Second, reduce the available values into a single SILValue we can use to + // forward. + SILValue TheForwardingValue; + TheForwardingValue = LSValue::reduce(L, &BB->getModule(), Values, + BB->getTerminator(), Ctx.getTE()); + /// Return the forwarding value. + return TheForwardingValue; +} + +bool BlockState::setupRLE(RLEContext &Ctx, SILInstruction *I, SILValue Mem) { + // Try to construct a SILValue for the current LSLocation. + // + // Collect the locations and their corresponding values into a map. + LSLocation L(Mem); + LSLocationValueMap Values; + // Use the ForwardValIn as we are currently processing the basic block. + if (!Ctx.collectLocationValues(I->getParent(), L, Values, getForwardValIn())) + return false; + + // Reduce the available values into a single SILValue we can use to forward. + SILModule *Mod = &I->getModule(); + SILValue TheForwardingValue = LSValue::reduce(L, Mod, Values, I, Ctx.getTE()); + if (!TheForwardingValue) + return false; + + // Now we have the forwarding value, record it for forwarding!. + // + // NOTE: we do not perform the RLE right here because doing so could introduce + // new LSLocations. + // + // e.g. + // %0 = load %x + // %1 = load %x + // %2 = extract_struct %1, #a + // %3 = load %2 + // + // If we perform the RLE and replace %1 with %0, we end up having a memory + // location we do not have before, i.e. Base == %0, and Path == #a. + // + // We may be able to add the LSLocation to the vault, but it gets + // complicated very quickly, e.g. we need to resize the bit vectors size, + // etc. + // + // However, since we already know the instruction to replace and the value to + // replace it with, we can record it for now and forwarded it after all the + // forwardable values are recorded in the function. + // + RedundantLoads[I] = TheForwardingValue; + return true; +} + +void BlockState::updateForwardSetForRead(RLEContext &Ctx, unsigned bit) { + // Track the new location and value. + startTrackingLocation(ForwardSetIn, bit); +} + +void BlockState::updateGenKillSetForRead(RLEContext &Ctx, unsigned bit) { + // Track the new location and value. + startTrackingLocation(BBGenSet, bit); + stopTrackingLocation(BBKillSet, bit); +} + +void BlockState::updateForwardSetAndValForRead(RLEContext &Ctx, unsigned lbit, + unsigned vbit) { + // Track the new location and value. + startTrackingValue(ForwardValIn, lbit, vbit); + startTrackingLocation(ForwardSetIn, lbit); +} + +void BlockState::updateGenKillSetForWrite(RLEContext &Ctx, unsigned bit) { + // This is a store, invalidate any location that this location may alias, as + // their values can no longer be forwarded. + LSLocation &R = Ctx.getLocation(bit); + for (unsigned i = 0; i < LocationNum; ++i) { + if (!isTrackingLocation(ForwardSetMax, i)) + continue; + LSLocation &L = Ctx.getLocation(i); + if (!L.isMayAliasLSLocation(R, Ctx.getAA())) + continue; + // MayAlias, invalidate the location. + stopTrackingLocation(BBGenSet, i); + startTrackingLocation(BBKillSet, i); + } + + // Start tracking this location. + startTrackingLocation(BBGenSet, bit); + stopTrackingLocation(BBKillSet, bit); +} + +void BlockState::updateMaxAvailForwardSetForWrite(RLEContext &Ctx, + unsigned bit) { + // Start tracking this location. + startTrackingLocation(ForwardSetMax, bit); +} + +void BlockState::updateMaxAvailForwardSetForRead(RLEContext &Ctx, + unsigned bit) { + // Start tracking this location. + startTrackingLocation(ForwardSetMax, bit); +} + +void BlockState::updateForwardSetForWrite(RLEContext &Ctx, unsigned bit) { + // This is a store, invalidate any location that this location may alias, as + // their values can no longer be forwarded. + LSLocation &R = Ctx.getLocation(bit); + for (unsigned i = 0; i < LocationNum; ++i) { + if (!isTrackingLocation(ForwardSetIn, i)) + continue; + LSLocation &L = Ctx.getLocation(i); + if (!L.isMayAliasLSLocation(R, Ctx.getAA())) + continue; + // MayAlias, invalidate the location. + stopTrackingLocation(ForwardSetIn, i); + } + + // Start tracking this location. + startTrackingLocation(ForwardSetIn, bit); +} + +void BlockState::updateForwardSetAndValForWrite(RLEContext &Ctx, unsigned lbit, + unsigned vbit) { + // This is a store, invalidate any location that this location may alias, as + // their values can no longer be forwarded. + LSLocation &R = Ctx.getLocation(lbit); + for (unsigned i = 0; i < LocationNum; ++i) { + if (!isTrackingLocation(ForwardSetIn, i)) + continue; + LSLocation &L = Ctx.getLocation(i); + if (!L.isMayAliasLSLocation(R, Ctx.getAA())) + continue; + // MayAlias, invalidate the location and value. + stopTrackingValue(ForwardValIn, i); + stopTrackingLocation(ForwardSetIn, i); + } + + // Start tracking this location and value. + startTrackingLocation(ForwardSetIn, lbit); + startTrackingValue(ForwardValIn, lbit, vbit); +} + +void BlockState::processWrite(RLEContext &Ctx, SILInstruction *I, SILValue Mem, + SILValue Val, RLEKind Kind) { + // Initialize the LSLocation. + LSLocation L(Mem); + + // If we cant figure out the Base or Projection Path for the write, + // process it as an unknown memory instruction. + if (!L.isValid()) { + // we can ignore unknown store instructions if we are computing the + // AvailSetMax. + if (!isComputeAvailSetMax(Kind)) { + processUnknownWriteInst(Ctx, I, Kind); + } + return; + } + + // Expand the given location and val into individual fields and process + // them as separate writes. + LSLocationList Locs; + LSLocation::expand(L, &I->getModule(), Locs, Ctx.getTE()); + + if (isComputeAvailSetMax(Kind)) { + for (unsigned i = 0; i < Locs.size(); ++i) { + updateMaxAvailForwardSetForWrite(Ctx, Ctx.getLocationBit(Locs[i])); + } + return; + } + + // Are we computing the genset and killset ? + if (isComputeAvailGenKillSet(Kind)) { + for (unsigned i = 0; i < Locs.size(); ++i) { + updateGenKillSetForWrite(Ctx, Ctx.getLocationBit(Locs[i])); + } + return; + } + + // Are we computing available set ? + if (isComputeAvailSet(Kind)) { + for (unsigned i = 0; i < Locs.size(); ++i) { + updateForwardSetForWrite(Ctx, Ctx.getLocationBit(Locs[i])); + } + return; + } + + // Are we computing available value or performing RLE? + if (isComputeAvailValue(Kind) || isPerformingRLE(Kind)) { + LSValueList Vals; + LSValue::expand(Val, &I->getModule(), Vals, Ctx.getTE()); + for (unsigned i = 0; i < Locs.size(); ++i) { + updateForwardSetAndValForWrite(Ctx, Ctx.getLocationBit(Locs[i]), + Ctx.getValueBit(Vals[i])); + } + return; + } + + llvm_unreachable("Unknown RLE compute kind"); +} + +void BlockState::processRead(RLEContext &Ctx, SILInstruction *I, SILValue Mem, + SILValue Val, RLEKind Kind) { + // Initialize the LSLocation. + LSLocation L(Mem); + + // If we cant figure out the Base or Projection Path for the read, simply + // ignore it for now. + if (!L.isValid()) + return; + + // Expand the given LSLocation and Val into individual fields and process + // them as separate reads. + LSLocationList Locs; + LSLocation::expand(L, &I->getModule(), Locs, Ctx.getTE()); + + if (isComputeAvailSetMax(Kind)) { + for (unsigned i = 0; i < Locs.size(); ++i) { + updateMaxAvailForwardSetForRead(Ctx, Ctx.getLocationBit(Locs[i])); + } + return; + } + + // Are we computing the genset and killset. + if (isComputeAvailGenKillSet(Kind)) { + for (unsigned i = 0; i < Locs.size(); ++i) { + updateGenKillSetForRead(Ctx, Ctx.getLocationBit(Locs[i])); + } + return; + } + + // Are we computing available set ?. + if (isComputeAvailSet(Kind)) { + for (auto &X : Locs) { + if (isTrackingLocation(ForwardSetIn, Ctx.getLocationBit(X))) + continue; + updateForwardSetForRead(Ctx, Ctx.getLocationBit(X)); + } + return; + } + + // Are we computing available values ?. + bool CanForward = true; + if (isComputeAvailValue(Kind) || isPerformingRLE(Kind)) { + LSValueList Vals; + LSValue::expand(Val, &I->getModule(), Vals, Ctx.getTE()); + for (unsigned i = 0; i < Locs.size(); ++i) { + if (isTrackingLocation(ForwardSetIn, Ctx.getLocationBit(Locs[i]))) + continue; + updateForwardSetAndValForRead(Ctx, Ctx.getLocationBit(Locs[i]), + Ctx.getValueBit(Vals[i])); + // We can not perform the forwarding as we are at least missing + // some pieces of the read location. + CanForward = false; + } + } + + // Simply return if we are not performing RLE or we do not have all the + // values available to perform RLE. + if (!isPerformingRLE(Kind) || !CanForward) + return; + + // Lastly, forward value to the load. + setupRLE(Ctx, I, Mem); +} + +void BlockState::processStoreInst(RLEContext &Ctx, StoreInst *SI, RLEKind Kind) { + processWrite(Ctx, SI, SI->getDest(), SI->getSrc(), Kind); +} + +void BlockState::processLoadInst(RLEContext &Ctx, LoadInst *LI, RLEKind Kind) { + processRead(Ctx, LI, LI->getOperand(), SILValue(LI), Kind); +} + +void BlockState::processUnknownWriteInstForGenKillSet(RLEContext &Ctx, + SILInstruction *I) { + auto *AA = Ctx.getAA(); + for (unsigned i = 0; i < LocationNum; ++i) { + if (!isTrackingLocation(ForwardSetMax, i)) + continue; + // Invalidate any location this instruction may write to. + // + // TODO: checking may alias with Base is overly conservative, + // we should check may alias with base plus projection path. + LSLocation &R = Ctx.getLocation(i); + if (!AA->mayWriteToMemory(I, R.getBase())) + continue; + // MayAlias. + stopTrackingLocation(BBGenSet, i); + startTrackingLocation(BBKillSet, i); + } +} + +void BlockState::processUnknownWriteInstForRLE(RLEContext &Ctx, + SILInstruction *I) { + auto *AA = Ctx.getAA(); + for (unsigned i = 0; i < LocationNum; ++i) { + if (!isTrackingLocation(ForwardSetIn, i)) + continue; + // Invalidate any location this instruction may write to. + // + // TODO: checking may alias with Base is overly conservative, + // we should check may alias with base plus projection path. + LSLocation &R = Ctx.getLocation(i); + if (!AA->mayWriteToMemory(I, R.getBase())) + continue; + // MayAlias. + stopTrackingLocation(ForwardSetIn, i); + stopTrackingValue(ForwardValIn, i); + } +} + +void BlockState::processUnknownWriteInst(RLEContext &Ctx, SILInstruction *I, + RLEKind Kind) { + // Are we computing the genset and killset ? + if (isComputeAvailGenKillSet(Kind)) { + processUnknownWriteInstForGenKillSet(Ctx, I); + return; + } + + // Are we computing the available value or doing RLE ? + if (isComputeAvailValue(Kind) || isPerformingRLE(Kind)) { + processUnknownWriteInstForRLE(Ctx, I); + return; + } + + llvm_unreachable("Unknown RLE compute kind"); +} + + +void BlockState::processInstructionWithKind(RLEContext &Ctx, + SILInstruction *Inst, + RLEKind Kind) { + // This is a StoreInst, try to see whether it clobbers any forwarding value + if (auto *SI = dyn_cast(Inst)) { + processStoreInst(Ctx, SI, Kind); + return; + } + + // This is a LoadInst. Let's see if we can find a previous loaded, stored + // value to use instead of this load. + if (auto *LI = dyn_cast(Inst)) { + processLoadInst(Ctx, LI, Kind); + return; + } + + // If this instruction has side effects, but is inert from a load store + // perspective, skip it. + if (isRLEInertInstruction(Inst)) + return; + + // If this instruction does not read or write memory, we can skip it. + if (!Inst->mayReadOrWriteMemory()) + return; + + // If we have an instruction that may write to memory and we cannot prove + // that it and its operands cannot alias a load we have visited, + // invalidate that load. + if (Inst->mayWriteToMemory()) { + processUnknownWriteInst(Ctx, Inst, Kind); + return; + } +} + + +//===----------------------------------------------------------------------===// +// RLEContext Implementation +//===----------------------------------------------------------------------===// + +RLEContext::RLEContext(SILFunction *F, AliasAnalysis *AA, + TypeExpansionAnalysis *TE, PostOrderFunctionInfo *PO) + : Fn(F), AA(AA), TE(TE), PO(PO) { + // Walk over the function and find all the locations accessed by + // this function. + LSLocation::enumerateLSLocations(*Fn, LocationVault, LocToBitIndex, TE); + + // For all basic blocks in the function, initialize a BB state. Since we + // know all the locations accessed in this function, we can resize the bit + // vector to the appropriate size. + for (auto &B : *F) { + BBToLocState[&B] = BlockState(); + BBToLocState[&B].init(&B, LocationVault.size(), isReachable(&B)); + } +} + +LSLocation &RLEContext::getLocation(const unsigned index) { + return LocationVault[index]; +} + +unsigned RLEContext::getLocationBit(const LSLocation &Loc) { + // Return the bit position of the given Loc in the LocationVault. The bit + // position is then used to set/reset the bitvector kept by each BlockState. + // + // We should have the location populated by the enumerateLSLocation at this + // point. + auto Iter = LocToBitIndex.find(Loc); + assert(Iter != LocToBitIndex.end() && "Location should have been enum'ed"); + return Iter->second; +} + +LSValue &RLEContext::getValue(const unsigned index) { + return LSValueVault[index]; +} + +unsigned RLEContext::getValueBit(const LSValue &Val) { + // Return the bit position of the given Val in the LSValueVault. The bit + // position is then used to set/reset the bitvector kept by each g. + auto Iter = ValToBitIndex.find(Val); + + // We do not walk over the function and find all the possible LSValues + // in this function, as some of the these values will not be used, i.e. + // if the LoadInst that generates this value is actually RLE'ed. + // Instead, we create the LSValues when we need them. + if (Iter == ValToBitIndex.end()) { + ValToBitIndex[Val] = LSValueVault.size(); + LSValueVault.push_back(Val); + return ValToBitIndex[Val]; + } + return Iter->second; +} + +BlockState::ValueState BlockState::getValueStateAtEndOfBlock(RLEContext &Ctx, + LSLocation &L) { + // Find number of covering value and concrete values for the locations + // expanded from the given location. + unsigned CSCount = 0, CTCount = 0; + LSLocationList Locs; + LSLocation::expand(L, &BB->getModule(), Locs, Ctx.getTE()); + + ValueTableMap &OTM = getForwardValOut(); + for (auto &X : Locs) { + LSValue &V = Ctx.getValue(OTM[Ctx.getLocationBit(X)]); + if (V.isCoveringValue()) { + ++CSCount; + continue; + } + ++CTCount; + } + + if (CSCount == Locs.size()) + return ValueState::CoverValues; + if (CTCount == Locs.size()) + return ValueState::ConcreteValues; + return ValueState::CoverAndConcreteValues; +} + +SILValue RLEContext::computePredecessorLocationValue(SILBasicBlock *BB, + LSLocation &L) { + BBValueMap Values; + llvm::DenseSet HandledBBs; + llvm::SmallVector WorkList; + + // Push in all the predecessors to get started. + for (auto Pred : BB->getPreds()) { + WorkList.push_back(Pred); + } + + while (!WorkList.empty()) { + auto *CurBB = WorkList.pop_back_val(); + BlockState &Forwarder = getBlockState(CurBB); + + // Mark this basic block as processed. + HandledBBs.insert(CurBB); + + // There are 3 cases that can happen here. + // + // 1. The current basic block contains concrete values for the entire + // location. + // 2. The current basic block contains covering values for the entire + // location. + // 3. The current basic block contains concrete value for part of the + // location and covering values for the rest. + // + // This BlockState contains concrete values for all the expanded + // locations, collect and reduce them into a single value in the current + // basic block. + if (Forwarder.isConcreteValues(*this, L)) { + Values[CurBB] = Forwarder.reduceValuesAtEndOfBlock(*this, L); + continue; + } + + // This BlockState does not contain concrete value for any of the expanded + // locations, collect in this block's predecessors. + if (Forwarder.isCoverValues(*this, L)) { + for (auto Pred : CurBB->getPreds()) { + if (HandledBBs.find(Pred) != HandledBBs.end()) + continue; + WorkList.push_back(Pred); + } + continue; + } + + // This block contains concrete values for some but not all the expanded + // locations, recursively call collectLocationValues to materialize the + // value that reaches this basic block. + LSLocationValueMap LSValues; + if (!collectLocationValues(CurBB, L, LSValues, Forwarder.getForwardValOut())) + return SILValue(); + + // Reduce the available values into a single SILValue we can use to forward + SILInstruction *IPt = CurBB->getTerminator(); + Values[CurBB] = LSValue::reduce(L, &BB->getModule(), LSValues, IPt, TE); + } + + // Finally, collect all the values for the SILArgument, materialize it using + // the SSAUpdater. + Updater.Initialize(L.getType()); + for (auto V : Values) { + Updater.AddAvailableValue(V.first, V.second); + } + + return Updater.GetValueInMiddleOfBlock(BB); +} + +bool RLEContext::collectLocationValues(SILBasicBlock *BB, LSLocation &L, + LSLocationValueMap &Values, + ValueTableMap &VM) { + LSLocationSet CSLocs; + LSLocationList Locs; + LSLocation::expand(L, &BB->getModule(), Locs, TE); + + auto *Mod = &BB->getModule(); + // Find the locations that this basic block defines and the locations which + // we do not have a concrete value in the current basic block. + for (auto &X : Locs) { + Values[X] = getValue(VM[getLocationBit(X)]); + if (!Values[X].isCoveringValue()) + continue; + CSLocs.insert(X); + } + + // For locations which we do not have concrete values for in this basic + // block, try to reduce it to the minimum # of locations possible, this + // will help us to generate as few SILArguments as possible. + LSLocation::reduce(L, Mod, CSLocs, TE); + + // To handle covering value, we need to go to the predecessors and + // materialize them there. + for (auto &X : CSLocs) { + SILValue V = computePredecessorLocationValue(BB, X); + if (!V) + return false; + + // We've constructed a concrete value for the covering value. Expand and + // collect the newly created forwardable values. + LSLocationList Locs; + LSValueList Vals; + LSLocation::expand(X, Mod, Locs, TE); + LSValue::expand(V, Mod, Vals, TE); + + for (unsigned i = 0; i < Locs.size(); ++i) { + Values[Locs[i]] = Vals[i]; + assert(Values[Locs[i]].isValid() && "Invalid load store value"); + } + } + return true; +} + +void RLEContext::processBasicBlocksForGenKillSet() { + for (SILBasicBlock *BB : PO->getReversePostOrder()) { + BlockState &S = getBlockState(BB); + + // Compute the AvailSetMax at the beginning of the basic block. + S.mergePredecessorsAvailSetMax(*this); + + // Compute the genset and killset. + // + // To optimize this process, we also compute the AvailSetMax at particular + // point in the basic block. + for (auto I = BB->begin(), E = BB->end(); I != E; ++I) { + if (auto *LI = dyn_cast(&*I)) { + S.processLoadInst(*this, LI, RLEKind::ComputeAvailSetMax); + } + if (auto *SI = dyn_cast(&*I)) { + S.processStoreInst(*this, SI, RLEKind::ComputeAvailSetMax); + } + + S.processInstructionWithKind(*this, &*I, RLEKind::ComputeAvailGenKillSet); + } + } +} + +void RLEContext::processBasicBlocksWithGenKillSet() { + // Process each basic block with the gen and kill set. Every time the + // ForwardSetOut of a basic block changes, the optimization is rerun on its + // successors. + llvm::SmallVector WorkList; + llvm::DenseSet HandledBBs; + + // Push into the worklist in post order so that we can pop from the back and + // get reverse post order. + for (SILBasicBlock *BB : PO->getPostOrder()) { + WorkList.push_back(BB); + HandledBBs.insert(BB); + } + while (!WorkList.empty()) { + SILBasicBlock *BB = WorkList.pop_back_val(); + HandledBBs.erase(BB); + + // Intersection. + BlockState &Forwarder = getBlockState(BB); + // Compute the ForwardSetIn at the beginning of the basic block. + Forwarder.mergePredecessorAvailSet(*this); + + if (Forwarder.processBasicBlockWithGenKillSet()) { + for (auto &X : BB->getSuccessors()) { + // We do not push basic block into the worklist if its already + // in the worklist. + if (HandledBBs.find(X) != HandledBBs.end()) + continue; + WorkList.push_back(X); + } + } + } +} + +void RLEContext::processBasicBlocksForAvailValue() { + for (SILBasicBlock *BB : PO->getReversePostOrder()) { + BlockState &Forwarder = getBlockState(BB); + + // Merge the predecessors. After merging, BlockState now contains + // lists of available LSLocations and their values that reach the + // beginning of the basic block along all paths. + Forwarder.mergePredecessorAvailSetAndValue(*this); + + // Merge duplicate loads, and forward stores to + // loads. We also update lists of stores|loads to reflect the end + // of the basic block. + Forwarder.processBasicBlockWithKind(*this, RLEKind::ComputeAvailValue); + + // Update the locations with available values. We do not need to update + // the available BitVector here as they should have been initialized and + // stabilized in the processBasicBlocksWithGenKillSet. + Forwarder.updateForwardValOut(); + } +} + +void RLEContext::processBasicBlocksForRLE() { + for (SILBasicBlock *BB : PO->getReversePostOrder()) { + BlockState &Forwarder = getBlockState(BB); + + // Merge the predecessors. After merging, BlockState now contains + // lists of available LSLocations and their values that reach the + // beginning of the basic block along all paths. + Forwarder.mergePredecessorAvailSetAndValue(*this); + + // Perform the actual redundant load elimination. + Forwarder.processBasicBlockWithKind(*this, RLEKind::PerformRLE); + + // Update the locations with available values and their values. + Forwarder.updateForwardSetOut(); + Forwarder.updateForwardValOut(); + } +} + +void RLEContext::runIterativeRLE() { + // We perform redundant load elimination in the following phases. + // + // Phase 1. Compute the genset and killset for every basic block. + // + // Phase 2. Use an iterative data flow to compute whether there is an + // available value at a given point, we do not yet care about what the value + // is. + // + // Phase 3. we compute the real forwardable value at a given point. + // + // Phase 4. we perform the redundant load elimination. + // + // Generate the genset and killset for every basic block. + processBasicBlocksForGenKillSet(); + + // Process basic blocks in RPO. After the data flow converges, run last + // iteration and perform load forwarding. + processBasicBlocksWithGenKillSet(); + + // We have computed the available value bit, now go through every basic + // block and compute the forwarding value locally. This is necessary as + // when we perform the RLE in the last iteration, we must handle loops, i.e. + // predecessor blocks which have not been processed when a basic block is + // processed. + processBasicBlocksForAvailValue(); +} + +bool RLEContext::run() { + // Data flow may take too long to converge. + if (LocationVault.size() > MaxLSLocationLimit) + return false; + + if (!isOneIterationFunction(PO)) + runIterativeRLE(); + + // We have the available value bit computed and the local forwarding value. + // Set up the load forwarding. + processBasicBlocksForRLE(); + + // Finally, perform the redundant load replacements. + llvm::DenseSet InstsToDelete; + bool SILChanged = false; + for (auto &X : BBToLocState) { + for (auto &F : X.second.getRL()) { + DEBUG(llvm::dbgs() << "Replacing " << SILValue(F.first) << "With " + << F.second); + SILChanged = true; + SILValue(F.first).replaceAllUsesWith(F.second); + InstsToDelete.insert(F.first); + ++NumForwardedLoads; + } + } + + // Erase the instructions recursively, this way, we get rid of pass + // dependence on DCE. + for (auto &X : InstsToDelete) { + // It is possible that the instruction still has uses, because it could be + // used as the replacement Value, i.e. F.second, for some other RLE pairs. + // + // TODO: we should fix this, otherwise we are missing RLE opportunities. + if (!X->use_empty()) + continue; + recursivelyDeleteTriviallyDeadInstructions(X, true); + } + return SILChanged; +} + +//===----------------------------------------------------------------------===// +// Top Level Entry Point +//===----------------------------------------------------------------------===// + +namespace { + +class RedundantLoadElimination : public SILFunctionTransform { + + StringRef getName() override { return "SIL Redundant Load Elimination"; } + + /// The entry point to the transformation. + void run() override { + SILFunction *F = getFunction(); + DEBUG(llvm::dbgs() << "*** RLE on function: " << F->getName() << " ***\n"); + + auto *AA = PM->getAnalysis(); + auto *TE = PM->getAnalysis(); + auto *PO = PM->getAnalysis()->get(F); + + RLEContext RLE(F, AA, TE, PO); + if (RLE.run()) { + invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions); + } + } +}; + +} // end anonymous namespace + +SILTransform *swift::createRedundantLoadElimination() { + return new RedundantLoadElimination(); +} diff --git a/lib/SILPasses/Scalar/RedundantOverflowCheckRemoval.cpp b/lib/SILOptimizer/Transforms/RedundantOverflowCheckRemoval.cpp similarity index 95% rename from lib/SILPasses/Scalar/RedundantOverflowCheckRemoval.cpp rename to lib/SILOptimizer/Transforms/RedundantOverflowCheckRemoval.cpp index 908ad852fdc2c..5fb50f586c195 100644 --- a/lib/SILPasses/Scalar/RedundantOverflowCheckRemoval.cpp +++ b/lib/SILOptimizer/Transforms/RedundantOverflowCheckRemoval.cpp @@ -1,8 +1,8 @@ -//===-- RedundantOverflowCheckRemoval.cpp ----------------------*- C++ -*-===// +//===--- RedundantOverflowCheckRemoval.cpp ----------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,12 +16,12 @@ #define DEBUG_TYPE "remove-redundant-overflow-checks" #include "swift/SIL/Dominance.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "swift/SIL/SILInstruction.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" @@ -130,7 +130,7 @@ class RedundantOverflowCheckRemovalPass : public SILFunctionTransform { // Perform a forward scan and use control flow and previously detected // overflow checks to remove the overflow checks. - // For each block in a Reverse Post Prder scan: + // For each block in a Reverse Post Order scan: for (auto &BB : ReversePostOrder) { // For each instruction: for (auto Inst = BB->begin(), End = BB->end(); Inst != End; Inst++) { @@ -255,6 +255,21 @@ class RedundantOverflowCheckRemovalPass : public SILFunctionTransform { // L and R are the righthand and lefthand sides of the constraint. SILValue L = F.Left; SILValue R = F.Right; + assert(L.getType() == R.getType() && "Invalid constraint type"); + + // Make sure that the types of the constraints match the types of the + // arithmetic operation. + switch (BI->getBuiltinInfo().ID) { + default: return false; + case BuiltinValueKind::SAddOver: + case BuiltinValueKind::UAddOver: + case BuiltinValueKind::SMulOver: + case BuiltinValueKind::UMulOver: + case BuiltinValueKind::USubOver: + case BuiltinValueKind::SSubOver: + if (L.getType() != BI->getOperand(0).getType()) + return false; + } switch (BI->getBuiltinInfo().ID) { default: return false; @@ -339,7 +354,7 @@ class RedundantOverflowCheckRemovalPass : public SILFunctionTransform { isKnownAbsLess(B, R)) return true; - // And commutitively, swapping A and B. + // And commutatively, swapping A and B. if (isKnownAbsLess(B, L) && knownRelation(A, R, ValueRelation::EQ)) return true; diff --git a/lib/SILPasses/Scalar/ReleaseDevirtualizer.cpp b/lib/SILOptimizer/Transforms/ReleaseDevirtualizer.cpp similarity index 92% rename from lib/SILPasses/Scalar/ReleaseDevirtualizer.cpp rename to lib/SILOptimizer/Transforms/ReleaseDevirtualizer.cpp index f05869c44f146..f3850f762191e 100644 --- a/lib/SILPasses/Scalar/ReleaseDevirtualizer.cpp +++ b/lib/SILOptimizer/Transforms/ReleaseDevirtualizer.cpp @@ -1,8 +1,8 @@ -//===---- ReleaseDevirtualizer.cpp - Devirtualizes release-instructions ---===// +//===--- ReleaseDevirtualizer.cpp - Devirtualizes release-instructions ----===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "release-devirtualizer" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" #include "swift/SIL/SILBuilder.h" #include "llvm/ADT/Statistic.h" @@ -87,10 +87,12 @@ void ReleaseDevirtualizer::run() { if (LastRelease) { if (auto *DRI = dyn_cast(&I)) { Changed |= devirtualizeReleaseOfObject(LastRelease, DRI); + LastRelease = nullptr; continue; } if (auto *AI = dyn_cast(&I)) { Changed |= devirtualizeReleaseOfBuffer(LastRelease, AI); + LastRelease = nullptr; continue; } } @@ -98,7 +100,7 @@ void ReleaseDevirtualizer::run() { if (isa(&I) || isa(&I)) { LastRelease = &I; - } else if (I.mayRelease()) { + } else if (I.mayReleaseOrReadRefCount()) { LastRelease = nullptr; } } @@ -112,6 +114,8 @@ bool ReleaseDevirtualizer:: devirtualizeReleaseOfObject(SILInstruction *ReleaseInst, DeallocRefInst *DeallocInst) { + DEBUG(llvm::dbgs() << " try to devirtualize " << *ReleaseInst); + // We only do the optimization for stack promoted object, because for these // we know that they don't have associated objects, which are _not_ released // by the deinit method. @@ -138,6 +142,8 @@ bool ReleaseDevirtualizer:: devirtualizeReleaseOfBuffer(SILInstruction *ReleaseInst, ApplyInst *DeallocCall) { + DEBUG(llvm::dbgs() << " try to devirtualize " << *ReleaseInst); + // Is this a deallocation of a buffer? SILFunction *DeallocFn = DeallocCall->getCalleeFunction(); if (!DeallocFn || DeallocFn->getName() != "swift_bufferDeallocateFromStack") @@ -180,6 +186,8 @@ devirtualizeReleaseOfBuffer(SILInstruction *ReleaseInst, bool ReleaseDevirtualizer::createDeinitCall(SILType AllocType, SILInstruction *ReleaseInst, SILValue object) { + DEBUG(llvm::dbgs() << " create deinit call\n"); + ClassDecl *Cl = AllocType.getClassOrBoundGenericClass(); assert(Cl && "no class type allocated with alloc_ref"); diff --git a/lib/SILPasses/Scalar/RemovePin.cpp b/lib/SILOptimizer/Transforms/RemovePin.cpp similarity index 92% rename from lib/SILPasses/Scalar/RemovePin.cpp rename to lib/SILOptimizer/Transforms/RemovePin.cpp index b6131b5b89174..73b371b7aec11 100644 --- a/lib/SILPasses/Scalar/RemovePin.cpp +++ b/lib/SILOptimizer/Transforms/RemovePin.cpp @@ -1,8 +1,8 @@ -//===------- RemovePin.cpp - StrongPin/Unpin removal -----*- C++ -*-------===// +//===--- RemovePin.cpp - StrongPin/Unpin removal ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,21 +12,21 @@ #define DEBUG_TYPE "sil-remove-pins" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/Dominance.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILInstruction.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/ArraySemantic.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/ArraySemantic.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" @@ -38,7 +38,7 @@ STATISTIC(NumPinPairsRemoved, "Num pin pairs removed"); using namespace swift; /// \brief Can this instruction read the pinned bit of the reference count. -/// Reading the pinned prevents us from moving the pin instructions accross it. +/// Reading the pinned prevents us from moving the pin instructions across it. static bool mayReadPinFlag(SILInstruction *I) { auto Kind = I->getKind(); if (Kind == ValueKind::IsUniqueOrPinnedInst) @@ -119,7 +119,7 @@ class RemovePinInsts : public SILFunctionTransform { ++NumPinPairsRemoved; } else { DEBUG(llvm::dbgs() - << " Pin users are not safe! Can not remove!\n"); + << " Pin users are not safe! Cannot remove!\n"); } continue; @@ -219,7 +219,6 @@ class RemovePinInsts : public SILFunctionTransform { // NSArray may do arbitrary things including releasing the array. return !Call.mayHaveBridgedObjectElementType(); - case ArrayCallKind::kArrayPropsIsNative: case ArrayCallKind::kArrayPropsIsNativeTypeChecked: case ArrayCallKind::kGetElementAddress: case ArrayCallKind::kMakeMutable: diff --git a/lib/SILPasses/Scalar/SILCleanup.cpp b/lib/SILOptimizer/Transforms/SILCleanup.cpp similarity index 88% rename from lib/SILPasses/Scalar/SILCleanup.cpp rename to lib/SILOptimizer/Transforms/SILCleanup.cpp index 5d2fbd75c02c8..3fbea434b94d4 100644 --- a/lib/SILPasses/Scalar/SILCleanup.cpp +++ b/lib/SILOptimizer/Transforms/SILCleanup.cpp @@ -1,8 +1,8 @@ -//===-- SILCleanup.cpp - Removes diagnostics instructions -----------------===// +//===--- SILCleanup.cpp - Removes diagnostics instructions ----------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,12 +15,12 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" using namespace swift; diff --git a/lib/SILPasses/Scalar/SILCodeMotion.cpp b/lib/SILOptimizer/Transforms/SILCodeMotion.cpp similarity index 97% rename from lib/SILPasses/Scalar/SILCodeMotion.cpp rename to lib/SILOptimizer/Transforms/SILCodeMotion.cpp index f11179ee23c6a..24bfb44012206 100644 --- a/lib/SILPasses/Scalar/SILCodeMotion.cpp +++ b/lib/SILOptimizer/Transforms/SILCodeMotion.cpp @@ -1,8 +1,8 @@ -//===- SILCodeMotion.cpp - Code Motion Optimizations ----------------------===// +//===--- SILCodeMotion.cpp - Code Motion Optimizations --------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-codemotion" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/Basic/BlotMapVector.h" #include "swift/SIL/Projection.h" #include "swift/SIL/SILBuilder.h" @@ -20,12 +20,12 @@ #include "swift/SIL/SILValue.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/RCIdentityAnalysis.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" @@ -133,7 +133,7 @@ enum OperandRelation { /// The original operand values are equal. AlwaysEqual, - /// The operand values are euqal after replacing with the successor block + /// The operand values are equal after replacing with the successor block /// arguments. EqualAfterMove }; @@ -141,7 +141,7 @@ enum OperandRelation { /// \brief Find a root value for operand \p In. This function inspects a sil /// value and strips trivial conversions such as values that are passed /// as arguments to basic blocks with a single predecessor or type casts. -/// This is a shallow one-spet search and not a deep recursive search. +/// This is a shallow one-step search and not a deep recursive search. /// /// For example, in the SIL code below, the root of %10 is %3, because it is /// the only possible incoming value. @@ -261,7 +261,7 @@ static llvm::Optional cheaperToPassOperandsAsArguments(SILInstruction *First, SILInstruction *Second) { // This will further enable to sink strong_retain_unowned instructions, - // which provides more opportinities for the unowned-optimization in + // which provides more opportunities for the unowned-optimization in // LLVMARCOpts. UnownedToRefInst *UTORI1 = dyn_cast(First); UnownedToRefInst *UTORI2 = dyn_cast(Second); @@ -485,8 +485,8 @@ static bool sinkArgument(SILBasicBlock *BB, unsigned ArgNum) { /// Try to sink literals that are passed to arguments that are coming from /// multiple predecessors. -/// Notice that unline other sinking methods in this file we do allow sinking -/// of literals from blocks with multiple sucessors. +/// Notice that unlike other sinking methods in this file we do allow sinking +/// of literals from blocks with multiple successors. static bool sinkLiteralsFromPredecessors(SILBasicBlock *BB) { if (BB->pred_empty() || BB->getSinglePredecessor()) return false; @@ -806,14 +806,13 @@ static bool tryToSinkRefCountAcrossSelectEnum(CondBranchInst *CondBr, static bool tryToSinkRefCountInst(SILBasicBlock::iterator T, SILBasicBlock::iterator I, - bool CanSinkToSuccessors, - AliasAnalysis *AA, + bool CanSinkToSuccessors, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA) { // The following methods should only be attempted if we can sink to our // successor. if (CanSinkToSuccessors) { // If we have a switch, try to sink ref counts across it and then return - // that result. We do not keep processing since the code below can not + // that result. We do not keep processing since the code below cannot // properly sink ref counts over switch_enums so we might as well exit // early. if (auto *S = dyn_cast(T)) @@ -839,7 +838,7 @@ static bool tryToSinkRefCountInst(SILBasicBlock::iterator T, } // Ok, we have a ref count instruction that *could* be sunk. If we have a - // terminator that we can not sink through or the cfg will not let us sink + // terminator that we cannot sink through or the cfg will not let us sink // into our predecessors, just move the increment before the terminator. if (!CanSinkToSuccessors || (!isa(T) && !isa(T))) { @@ -850,7 +849,7 @@ static bool tryToSinkRefCountInst(SILBasicBlock::iterator T, // Ok, it is legal for us to sink this increment to our successors. Create a // copy of this instruction in each one of our successors unless they are - // ignoreable trap blocks. + // ignorable trap blocks. DEBUG(llvm::dbgs() << " Sinking " << *I); SILBuilderWithScope Builder(T, &*I); for (auto &Succ : T->getParent()->getSuccessors()) { @@ -899,7 +898,7 @@ static bool isRetainAvailableInSomeButNotAllPredecessors( // Check that there is no decrement or check from the increment to the end // of the basic block. After we have hoisted the first release this release // would prevent further hoisting. Instead we check that no decrement or - // check occurs upto this hoisted release. + // check occurs up to this hoisted release. auto End = CheckUpToInstruction[Pred]; auto EndIt = SILBasicBlock::iterator(End ? *End : Pred->getTerminator()); if (Retain == Pred->rend() || valueHasARCDecrementOrCheckInInstructionRange( @@ -982,7 +981,7 @@ static bool hoistDecrementsToPredecessors(SILBasicBlock *BB, AliasAnalysis *AA, return HoistedDecrement; } -/// Try sink a retain as far as possible. This is either to sucessor BBs, +/// Try sink a retain as far as possible. This is either to successor BBs, /// or as far down the current BB as possible static bool sinkRefCountIncrement(SILBasicBlock *BB, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA) { @@ -1283,7 +1282,7 @@ void BBEnumTagDataflowState:: mergePredecessorStates(BBToDataflowStateMap &BBToStateMap) { - // If we have no precessors, there is nothing to do so return early... + // If we have no predecessors, there is nothing to do so return early... if (getBB()->pred_empty()) { DEBUG(llvm::dbgs() << " No Preds.\n"); return; @@ -1324,7 +1323,7 @@ mergePredecessorStates(BBToDataflowStateMap &BBToStateMap) { llvm::SmallVector CurBBValuesToBlot; // If we do not find state for a specific value in any of our predecessor BBs, - // we can not be the end of a switch region since we can not cover our + // we cannot be the end of a switch region since we cannot cover our // predecessor BBs with enum decls. Blot after the loop. llvm::SmallVector PredBBValuesToBlot; @@ -1358,9 +1357,9 @@ mergePredecessorStates(BBToDataflowStateMap &BBToStateMap) { // the predecessor we are processing. auto PredValue = PredBBState->ValueToCaseMap.find(P->first); - // If we can not find the state associated with this SILValue in this + // If we cannot find the state associated with this SILValue in this // predecessor or the value in the corresponding predecessor was blotted, - // we can not find a covering switch for this BB or forward any enum tag + // we cannot find a covering switch for this BB or forward any enum tag // information for this enum value. if (PredValue == PredBBState->ValueToCaseMap.end() || !(*PredValue)->first) { // Otherwise, we are conservative and do not forward the EnumTag that we @@ -1372,7 +1371,7 @@ mergePredecessorStates(BBToDataflowStateMap &BBToStateMap) { } // Check if out predecessor has any other successors. If that is true we - // clear all the state since we can not hoist safely. + // clear all the state since we cannot hoist safely. if (!PredBB->getSingleSuccessor()) { EnumToEnumBBCaseListMap.clear(); DEBUG(llvm::dbgs() << " Predecessor has other " @@ -1498,9 +1497,9 @@ BBEnumTagDataflowState::hoistDecrementsIntoSwitchRegions(AliasAnalysis *AA) { } // Finally ensure that we have no users of this operand preceding the - // release_value in this BB. If we have users like that we can not hoist the + // release_value in this BB. If we have users like that we cannot hoist the // release past them unless we know that there is an additional set of - // releases that together post-dominate this release. If we can not do this, + // releases that together post-dominate this release. If we cannot do this, // skip this release. // // TODO: We need information from the ARC optimizer to prove that property @@ -1526,7 +1525,7 @@ BBEnumTagDataflowState::hoistDecrementsIntoSwitchRegions(AliasAnalysis *AA) { // Otherwise create the release_value before the terminator of the // predecessor. assert(P.first->getSingleSuccessor() && - "Can not hoist release into BB that has multiple successors"); + "Cannot hoist release into BB that has multiple successors"); SILBuilderWithScope Builder(P.first->getTerminator(), RVI); createRefCountOpForPayload(Builder, RVI, P.second); } @@ -1564,7 +1563,7 @@ findLastSinkableMatchingEnumValueRCIncrementInPred(AliasAnalysis *AA, // Otherwise, see if there are any instructions in between FirstPredInc and // the end of the given basic block that could decrement first pred. If such - // an instruction exists, we can not perform this optimization so continue. + // an instruction exists, we cannot perform this optimization so continue. if (valueHasARCDecrementOrCheckInInstructionRange( EnumValue, (*FirstInc).getIterator(), BB->getTerminator()->getIterator(), AA)) @@ -1669,7 +1668,8 @@ sinkIncrementsOutOfSwitchRegions(AliasAnalysis *AA, static bool processFunction(SILFunction *F, AliasAnalysis *AA, PostOrderFunctionInfo *PO, - RCIdentityFunctionInfo *RCIA, bool HoistReleases) { + RCIdentityFunctionInfo *RCIA, + bool HoistReleases) { bool Changed = false; diff --git a/lib/SILPasses/Scalar/SILLowerAggregateInstrs.cpp b/lib/SILOptimizer/Transforms/SILLowerAggregateInstrs.cpp similarity index 96% rename from lib/SILPasses/Scalar/SILLowerAggregateInstrs.cpp rename to lib/SILOptimizer/Transforms/SILLowerAggregateInstrs.cpp index b7fe9c930ba35..d1780e2e2e610 100644 --- a/lib/SILPasses/Scalar/SILLowerAggregateInstrs.cpp +++ b/lib/SILOptimizer/Transforms/SILLowerAggregateInstrs.cpp @@ -1,8 +1,8 @@ -//===- SILLowerAggregateInstrs.cpp - Aggregate insts to Scalar insts -----===// +//===--- SILLowerAggregateInstrs.cpp - Aggregate insts to Scalar insts ---===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,9 +15,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-lower-aggregate-instrs" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILVisitor.h" #include "swift/SIL/SILBuilder.h" diff --git a/lib/SILPasses/Scalar/SILMem2Reg.cpp b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp similarity index 98% rename from lib/SILPasses/Scalar/SILMem2Reg.cpp rename to lib/SILOptimizer/Transforms/SILMem2Reg.cpp index 39aa04ed51355..5f90ff8148d41 100644 --- a/lib/SILPasses/Scalar/SILMem2Reg.cpp +++ b/lib/SILOptimizer/Transforms/SILMem2Reg.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,7 +20,7 @@ #define DEBUG_TYPE "sil-mem2reg" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/AST/DiagnosticsSIL.h" #include "swift/SIL/Dominance.h" #include "swift/SIL/SILBuilder.h" @@ -29,10 +29,10 @@ #include "swift/SIL/SILModule.h" #include "swift/SIL/Projection.h" #include "swift/SIL/TypeLowering.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Statistic.h" @@ -282,7 +282,7 @@ promoteDebugValueAddr(DebugValueAddrInst *DVAI, SILValue Value, SILBuilder &B) { assert(Value.isValid() && "Expected valid value"); B.setInsertionPoint(DVAI); B.setCurrentDebugScope(DVAI->getDebugScope()); - B.createDebugValue(DVAI->getLoc(), Value, DVAI->getVarInfo().getArgNo()); + B.createDebugValue(DVAI->getLoc(), Value, DVAI->getVarInfo()); DVAI->eraseFromParent(); } @@ -414,7 +414,7 @@ StackAllocationPromoter::promoteAllocationInBlock(SILBasicBlock *BB) { // if we have a valid value to use at this point. Otherwise we'll // promote this when we deal with hooking up phis. if (auto *DVAI = dyn_cast(Inst)) { - if (DVAI->getOperand() == ASI->getAddressResult() && + if (DVAI->getOperand() == ASI && RunningVal.isValid()) promoteDebugValueAddr(DVAI, RunningVal, B); continue; @@ -422,7 +422,7 @@ StackAllocationPromoter::promoteAllocationInBlock(SILBasicBlock *BB) { // Replace destroys with a release of the value. if (auto *DAI = dyn_cast(Inst)) { - if (DAI->getOperand() == ASI->getAddressResult() && + if (DAI->getOperand() == ASI && RunningVal.isValid()) { replaceDestroy(DAI, RunningVal); } @@ -483,7 +483,7 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *ASI) { // Replace debug_value_addr with debug_value of the promoted value. if (auto *DVAI = dyn_cast(Inst)) { - if (DVAI->getOperand() == ASI->getAddressResult()) { + if (DVAI->getOperand() == ASI) { if (RunningVal.isValid()) { promoteDebugValueAddr(DVAI, RunningVal, B); } else { @@ -498,7 +498,7 @@ void MemoryToRegisters::removeSingleBlockAllocation(AllocStackInst *ASI) { // Replace destroys with a release of the value. if (auto *DAI = dyn_cast(Inst)) { - if (DAI->getOperand() == ASI->getAddressResult()) { + if (DAI->getOperand() == ASI) { replaceDestroy(DAI, RunningVal); } continue; diff --git a/lib/SILPasses/Scalar/SILSROA.cpp b/lib/SILOptimizer/Transforms/SILSROA.cpp similarity index 92% rename from lib/SILPasses/Scalar/SILSROA.cpp rename to lib/SILOptimizer/Transforms/SILSROA.cpp index 429d39aa96675..0a208ba9cc135 100644 --- a/lib/SILPasses/Scalar/SILSROA.cpp +++ b/lib/SILOptimizer/Transforms/SILSROA.cpp @@ -1,8 +1,8 @@ -//===-- SILSROA.cpp - Scalar Replacement of Aggregates -------------------===// +//===--- SILSROA.cpp - Scalar Replacement of Aggregates ------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,8 +23,8 @@ #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILUndef.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Debug.h" @@ -125,7 +125,7 @@ unsigned SROAMemoryUseAnalyzer::getEltNoForProjection(SILInstruction *Inst) { bool SROAMemoryUseAnalyzer::analyze() { // We only know how to split structs and tuples... So if we have a scalar or a // different sort of aggregate, bail. - SILType Type = SILValue(AI, 1).getType(); + SILType Type = AI->getType(); TT = Type.getAs(); SD = Type.getStructOrBoundGenericStruct(); @@ -139,11 +139,11 @@ bool SROAMemoryUseAnalyzer::analyze() { } // Go through uses of the memory allocation of AI... - for (auto *Operand : getNonDebugUses(SILValue(AI, 1))) { + for (auto *Operand : getNonDebugUses(SILValue(AI))) { SILInstruction *User = Operand->getUser(); DEBUG(llvm::dbgs() << " Visiting use: " << *User); - // If we store the alloca pointer, we can not analyze its uses so bail... + // If we store the alloca pointer, we cannot analyze its uses so bail... // It is ok if we store into the alloca pointer though. if (auto *SI = dyn_cast(User)) { if (SI->getDest().getDef() == AI) { @@ -182,6 +182,11 @@ bool SROAMemoryUseAnalyzer::analyze() { continue; } + if (isa(User)) { + // We can ignore the dealloc_stack. + continue; + } + // Otherwise we do not understand this instruction, so bail. DEBUG(llvm::dbgs() << " Found unknown user, pointer escapes!\n"); ++NumEscapingAllocas; @@ -197,7 +202,7 @@ void SROAMemoryUseAnalyzer:: createAllocas(llvm::SmallVector &NewAllocations) { SILBuilderWithScope B(AI); - SILType Type = AI->getType(1).getObjectType(); + SILType Type = AI->getType().getObjectType(); if (TT) { for (unsigned EltNo : indices(TT->getElementTypes())) { @@ -230,7 +235,7 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector &Worklist SILBuilderWithScope B(LI); llvm::SmallVector Elements; for (auto *NewAI : NewAllocations) - Elements.push_back(B.createLoad(LI->getLoc(), SILValue(NewAI, 1))); + Elements.push_back(B.createLoad(LI->getLoc(), NewAI)); auto *Agg = createAgg(B, LI->getLoc(), LI->getType().getObjectType(), Elements); SILValue(LI).replaceAllUsesWith(Agg); @@ -243,19 +248,18 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector &Worklist for (unsigned EltNo : indices(NewAllocations)) B.createStore(SI->getLoc(), createAggProjection(B, SI->getLoc(), SI->getSrc(), EltNo), - SILValue(NewAllocations[EltNo], 1)); + NewAllocations[EltNo]); SI->eraseFromParent(); } // Forward any field extracts to the new allocation. for (auto *Ext : ExtractInsts) { - SILValue NewValue = SILValue(NewAllocations[getEltNoForProjection(Ext)], 1); + SILValue NewValue = NewAllocations[getEltNoForProjection(Ext)]; SILValue(Ext).replaceAllUsesWith(NewValue); Ext->eraseFromParent(); } - // Find all dealloc instruction that touch the local storage handle for AI - // and then chop them up. + // Find all dealloc instructions for AI and then chop them up. llvm::SmallVector ToRemove; for (auto *Operand : getNonDebugUses(SILValue(AI, 0))) { SILInstruction *User = Operand->getUser(); diff --git a/lib/SILPasses/Scalar/SimplifyCFG.cpp b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp similarity index 97% rename from lib/SILPasses/Scalar/SimplifyCFG.cpp rename to lib/SILOptimizer/Transforms/SimplifyCFG.cpp index a24c278f723fa..e4b3eabd0c7d3 100644 --- a/lib/SILPasses/Scalar/SimplifyCFG.cpp +++ b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,20 +11,20 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-simplify-cfg" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/Dominance.h" #include "swift/SIL/Projection.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILUndef.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/SimplifyInstruction.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/SILInliner.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/SimplifyInstruction.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/SILInliner.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -44,7 +44,7 @@ STATISTIC(NumSROAArguments, "Number of aggregate argument levels split by " // CFG Simplification //===----------------------------------------------------------------------===// -/// dominatorBasedSimplify iterates between dominator based simplifation of +/// dominatorBasedSimplify iterates between dominator based simplification of /// terminator branch condition values and cfg simplification. This is the /// maximum number of iterations we run. The number is the maximum number of /// iterations encountered when compiling the stdlib on April 2 2015. @@ -420,7 +420,7 @@ static bool isKnownEdgeValue(TermInst *Term, SILBasicBlock *SuccBB, return SuccBB->getSinglePredecessor() != nullptr; } -/// Create a enum element by extracting the operand of a switch_enum. +/// Create an enum element by extracting the operand of a switch_enum. static SILInstruction *createEnumElement(SILBuilder &Builder, SwitchEnumInst *SEI, EnumElementDecl *EnumElement) { @@ -454,7 +454,7 @@ static SILInstruction *createValueForEdge(SILInstruction *UserInst, return createEnumElement(Builder, SEI, Case.get()); } -/// Peform dominator based value simplifications and jump threading on all users +/// Perform dominator based value simplifications and jump threading on all users /// of the operand of 'DominatingBB's terminator. static bool tryDominatorBasedSimplifications( SILBasicBlock *DominatingBB, DominanceInfo *DT, @@ -966,7 +966,7 @@ bool SimplifyCFG::simplifyBranchOperands(OperandValueArrayRef Operands) { for (auto O = Operands.begin(), E = Operands.end(); O != E; ++O) if (auto *I = dyn_cast(*O)) if (SILValue Result = simplifyInstruction(I)) { - SILValue(I, 0).replaceAllUsesWith(Result.getDef()); + SILValue(I, 0).replaceAllUsesWith(Result); if (isInstructionTriviallyDead(I)) { eraseFromParentWithDebugInsts(I); Simplified = true; @@ -1124,7 +1124,7 @@ bool SimplifyCFG::simplifyBranchBlock(BranchInst *BI) { if (SILBasicBlock *TrampolineDest = getTrampolineDest(DestBB)) { SILBuilderWithScope(BI).createBranch(BI->getLoc(), TrampolineDest, BI->getArgs()); - // Eliminating the trampoline can expose opportuntities to improve the + // Eliminating the trampoline can expose opportunities to improve the // new block we branch to. if (LoopHeaders.count(DestBB)) LoopHeaders.insert(BB); @@ -1161,7 +1161,7 @@ static bool wouldIntroduceCriticalEdge(TermInst *T, SILBasicBlock *DestBB) { } /// Returns the original boolean value, looking through possible invert -/// builtins. The paramter \p Inverted is inverted if the returned original +/// builtins. The parameter \p Inverted is inverted if the returned original /// value is the inverted value of the passed \p Cond. /// If \p onlyAcceptSingleUse is true and the operand of an invert builtin has /// more than one use, an invalid SILValue() is returned. @@ -1175,7 +1175,7 @@ static SILValue skipInvert(SILValue Cond, bool &Inverted, OperandValueArrayRef Args = BI->getArguments(); if (BI->getBuiltinInfo().ID == BuiltinValueKind::Xor) { - // Check if it's a boolean invertion of the condition. + // Check if it's a boolean inversion of the condition. if (auto *IL = dyn_cast(Args[1])) { if (IL->getValue().isAllOnesValue()) { Cond = Args[0]; @@ -1197,7 +1197,7 @@ static SILValue skipInvert(SILValue Cond, bool &Inverted, /// \brief Returns the first cond_fail if it is the first side-effect /// instruction in this block. -static CondFailInst *getFistCondFail(SILBasicBlock *BB) { +static CondFailInst *getFirstCondFail(SILBasicBlock *BB) { auto It = BB->begin(); CondFailInst *CondFail = nullptr; // Skip instructions that don't have side-effects. @@ -1210,13 +1210,13 @@ static CondFailInst *getFistCondFail(SILBasicBlock *BB) { } /// If the first side-effect instruction in this block is a cond_fail that -/// is guarantueed to fail, it is returned. +/// is guaranteed to fail, it is returned. /// The \p Cond is the condition from a cond_br in the predecessor block. The /// cond_fail must only fail if \p BB is entered through this predecessor block. /// If \p Inverted is true, \p BB is on the false-edge of the cond_br. static CondFailInst *getUnConditionalFail(SILBasicBlock *BB, SILValue Cond, bool Inverted) { - CondFailInst *CondFail = getFistCondFail(BB); + CondFailInst *CondFail = getFirstCondFail(BB); if (!CondFail) return nullptr; @@ -1302,7 +1302,7 @@ bool SimplifyCFG::simplifyCondBrBlock(CondBranchInst *BI) { if (auto *Xor = dyn_cast(BI->getCondition().stripExpectIntrinsic())) { if (Xor->getBuiltinInfo().ID == BuiltinValueKind::Xor) { - // Check if it's a boolean invertion of the condition. + // Check if it's a boolean inversion of the condition. OperandValueArrayRef Args = Xor->getArguments(); if (auto *IL = dyn_cast(Args[1])) { if (IL->getValue().isAllOnesValue()) { @@ -1557,7 +1557,7 @@ bool SimplifyCFG::simplifySwitchEnumUnreachableBlocks(SwitchEnumInst *SEI) { } /// simplifySwitchEnumBlock - Simplify a basic block that ends with a -/// switch_enum instruction that gets its operand from a an enum +/// switch_enum instruction that gets its operand from an enum /// instruction. bool SimplifyCFG::simplifySwitchEnumBlock(SwitchEnumInst *SEI) { auto *EI = dyn_cast(SEI->getOperand()); @@ -1600,7 +1600,7 @@ bool SimplifyCFG::simplifySwitchEnumBlock(SwitchEnumInst *SEI) { } /// simplifySwitchValueBlock - Simplify a basic block that ends with a -/// switch_value instruction that gets its operand from a an integer +/// switch_value instruction that gets its operand from an integer /// literal instruction. bool SimplifyCFG::simplifySwitchValueBlock(SwitchValueInst *SVI) { auto *ThisBB = SVI->getParent(); @@ -1891,18 +1891,32 @@ bool SimplifyCFG::simplifyTryApplyBlock(TryApplyInst *TAI) { TAI->getModule().getSwiftModule(), TAI->getSubstitutions()); } + auto OrigParamTypes = OrigFnTy->getParameterSILTypes(); + auto TargetParamTypes = TargetFnTy->getParameterSILTypes(); + unsigned numArgs = TAI->getNumArguments(); + + // First check if it is possible to convert all arguments. + // Currently we believe that castValueToABICompatibleType can handle all + // cases, so this check should never fail. We just do it to be absolutely + // sure that we don't crash. + for (unsigned i = 0; i < numArgs; ++i) { + if (!canCastValueToABICompatibleType(TAI->getModule(), + OrigParamTypes[i], + TargetParamTypes[i])) { + return false; + } + } + SmallVector Args; - for (int i = 0, e = TAI->getNumArguments(); i < e; ++i) { + for (unsigned i = 0; i < numArgs; ++i) { auto Arg = TAI->getArgument(i); // Cast argument if required. Arg = castValueToABICompatibleType(&Builder, TAI->getLoc(), Arg, - OrigFnTy->getParameterSILTypes()[i], - TargetFnTy->getParameterSILTypes()[i]). - getValue(); + OrigParamTypes[i], + TargetParamTypes[i]).getValue(); Args.push_back(Arg); } - assert (CalleeFnTy->getParameters().size() == Args.size() && "The number of arguments should match"); @@ -1931,8 +1945,7 @@ bool SimplifyCFG::simplifyTryApplyBlock(TryApplyInst *TAI) { // and the destination blocks may have no arguments. bool SimplifyCFG::simplifyTermWithIdenticalDestBlocks(SILBasicBlock *BB) { SILBasicBlock *commonDest = nullptr; - for (const SILSuccessor &Succ : BB->getSuccessors()) { - SILBasicBlock *SuccBlock = Succ.getBB(); + for (auto *SuccBlock : BB->getSuccessorBlocks()) { if (SuccBlock->getNumBBArg() != 0) return false; SILBasicBlock *DestBlock = getTrampolineDest(SuccBlock); @@ -1988,7 +2001,7 @@ bool RemoveUnreachable::run() { } /// Checks if the block contains a cond_fail as first side-effect instruction -/// and trys to move it to the predecessors (if benefitial). A sequence +/// and tries to move it to the predecessors (if beneficial). A sequence /// /// bb1: /// br bb3(%c) @@ -2011,13 +2024,13 @@ bool RemoveUnreachable::run() { /// static bool tryMoveCondFailToPreds(SILBasicBlock *BB) { - CondFailInst *CFI = getFistCondFail(BB); + CondFailInst *CFI = getFirstCondFail(BB); if (!CFI) return false; // Find the underlying condition value of the cond_fail. - // We only accept sinlge uses. This is not a correctness check, but we only - // want to to the optimization if the condition gets dead after moving the + // We only accept single uses. This is not a correctness check, but we only + // want to the optimization if the condition gets dead after moving the // cond_fail. bool inverted = false; SILValue cond = skipInvert(CFI->getOperand(), inverted, true); @@ -2082,38 +2095,42 @@ bool SimplifyCFG::simplifyBlocks() { // Otherwise, try to simplify the terminator. TermInst *TI = BB->getTerminator(); - switch (TI->getKind()) { - case ValueKind::BranchInst: + switch (TI->getTermKind()) { + case TermKind::BranchInst: Changed |= simplifyBranchBlock(cast(TI)); break; - case ValueKind::CondBranchInst: + case TermKind::CondBranchInst: Changed |= simplifyCondBrBlock(cast(TI)); break; - case ValueKind::SwitchValueInst: + case TermKind::SwitchValueInst: // FIXME: Optimize for known switch values. Changed |= simplifySwitchValueBlock(cast(TI)); break; - case ValueKind::SwitchEnumInst: + case TermKind::SwitchEnumInst: Changed |= simplifySwitchEnumBlock(cast(TI)); Changed |= simplifyTermWithIdenticalDestBlocks(BB); break; - case ValueKind::UnreachableInst: + case TermKind::UnreachableInst: Changed |= simplifyUnreachableBlock(cast(TI)); break; - case ValueKind::CheckedCastBranchInst: + case TermKind::CheckedCastBranchInst: Changed |= simplifyCheckedCastBranchBlock(cast(TI)); break; - case ValueKind::CheckedCastAddrBranchInst: + case TermKind::CheckedCastAddrBranchInst: Changed |= simplifyCheckedCastAddrBranchBlock(cast(TI)); break; - case ValueKind::TryApplyInst: + case TermKind::TryApplyInst: Changed |= simplifyTryApplyBlock(cast(TI)); break; - case ValueKind::SwitchEnumAddrInst: + case TermKind::SwitchEnumAddrInst: Changed |= simplifyTermWithIdenticalDestBlocks(BB); break; - default: + case TermKind::ThrowInst: + case TermKind::DynamicMethodBranchInst: + case TermKind::ReturnInst: break; + case TermKind::Invalid: + llvm_unreachable("Invalid Term Inst?!"); } // If the block has a cond_fail, try to move it to the predecessors. Changed |= tryMoveCondFailToPreds(BB); @@ -2173,7 +2190,7 @@ static SILBasicBlock *isObjCMethodCallBlock(SILBasicBlock &Block) { return nullptr; for (auto &Inst : Block) { - // Look for a objc method call. + // Look for an objc method call. auto *Apply = dyn_cast(&Inst); if (!Apply) continue; @@ -2573,7 +2590,7 @@ static bool splitBBArguments(SILFunction &Fn) { bool Changed = false; std::vector Worklist; - // We know that we have atleast one BB, so this is safe since in such a case + // We know that we have at least one BB, so this is safe since in such a case // std::next(Fn->begin()) == Fn->end(), the exit case of iteration on a range. for (auto &BB : make_range(std::next(Fn.begin()), Fn.end())) { for (auto *Arg : BB.getBBArgs()) { @@ -2636,7 +2653,7 @@ bool SimplifyCFG::run() { PostDominanceAnalysis *PDA = PM->getAnalysis(); if (Changed) { - // Force dominator recomputation since we modifed the cfg. + // Force dominator recomputation since we modified the cfg. DA->invalidate(&Fn, SILAnalysis::InvalidationKind::Everything); PDA->invalidate(&Fn, SILAnalysis::InvalidationKind::Everything); } @@ -2689,7 +2706,7 @@ static SILValue getInsertedValue(SILInstruction *Aggregate, return Tuple->getElement(TEI->getFieldNo()); } -/// Check a diamond-form property of graphs generated by swith_enum +/// Check a diamond-form property of graphs generated by switch_enum /// instructions, who only produce integer values by each of BBs handling its /// case tags. /// In such graphs, switch_enum dominates any blocks processing cases and all @@ -3033,7 +3050,7 @@ struct CaseInfo { /// The result value. SILInstruction *Result = nullptr; - /// The block which conains the cond_br of the input value comparison + /// The block which contains the cond_br of the input value comparison /// or the block which assigns the default value. SILBasicBlock *CmpOrDefault = nullptr; }; @@ -3406,7 +3423,7 @@ class SplitCriticalEdges : public SILFunctionTransform { void run() override { auto &Fn = *getFunction(); - // Split all critical egdes from all or non only cond_br terminators. + // Split all critical edges from all or non only cond_br terminators. bool Changed = splitAllCriticalEdges(Fn, OnlyNonCondBrEdges, nullptr, nullptr); @@ -3467,4 +3484,3 @@ SILTransform *swift::createSROABBArgs() { return new SROABBArgs(); } SILTransform *swift::createSimplifyBBArgs() { return new SimplifyBBArgs(); } - diff --git a/lib/SILPasses/Scalar/Sink.cpp b/lib/SILOptimizer/Transforms/Sink.cpp similarity index 87% rename from lib/SILPasses/Scalar/Sink.cpp rename to lib/SILOptimizer/Transforms/Sink.cpp index e0ee93d6c8945..34a27a1fc1903 100644 --- a/lib/SILPasses/Scalar/Sink.cpp +++ b/lib/SILOptimizer/Transforms/Sink.cpp @@ -1,32 +1,35 @@ -//===-- Sink.cpp ----- Code Sinking -----------------------------*- C++ -*-===// +//===--- Sink.cpp ----- Code Sinking ----------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -// Many SIL instructions that don't have side effects at the SIL level are -// lowered to a sequence of LLVM instructions that does have side effects that -// LLVM can't sink. This pass sinks instructions close to their users. +/// +/// \file +/// Many SIL instructions that don't have side effects at the SIL level are +/// lowered to a sequence of LLVM instructions that does have side effects that +/// LLVM can't sink. This pass sinks instructions close to their users. +/// //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sink-instructions" #include "swift/SIL/Dominance.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILValue.h" #include "swift/SIL/SILDebugScope.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "swift/SIL/SILInstruction.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" diff --git a/lib/SILPasses/Scalar/SpeculativeDevirtualizer.cpp b/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp similarity index 96% rename from lib/SILPasses/Scalar/SpeculativeDevirtualizer.cpp rename to lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp index 7877a1b3db3c2..aaa6c8dbb7b8b 100644 --- a/lib/SILPasses/Scalar/SpeculativeDevirtualizer.cpp +++ b/lib/SILOptimizer/Transforms/SpeculativeDevirtualizer.cpp @@ -1,8 +1,8 @@ -//===-- SpeculativeDevirtualizer.cpp -- Speculatively devirtualize calls --===// +//===--- SpeculativeDevirtualizer.cpp - Speculatively devirtualize calls --===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,7 +15,7 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sil-speculative-devirtualizer-pass" +#define DEBUG_TYPE "sil-speculative-devirtualizer" #include "swift/Basic/DemangleWrappers.h" #include "swift/Basic/Fallthrough.h" #include "swift/SIL/SILArgument.h" @@ -23,13 +23,13 @@ #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" -#include "swift/SILAnalysis/ClassHierarchyAnalysis.h" -#include "swift/SILPasses/Utils/Generics.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/PassManager.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Devirtualize.h" -#include "swift/SILPasses/Utils/SILInliner.h" +#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h" +#include "swift/SILOptimizer/Utils/Generics.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/Devirtualize.h" +#include "swift/SILOptimizer/Utils/SILInliner.h" #include "swift/AST/ASTContext.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/PointerIntPair.h" @@ -312,7 +312,7 @@ static bool tryToSpeculateTarget(FullApplySite AI, // Bail if any generic types parameters of the class instance type are // unbound. // We cannot devirtualize unbound generic calls yet. - if (isClassWithUnboundGenericParameters(SubType, AI.getModule())) + if (isNominalTypeWithUnboundGenericParameters(SubType, AI.getModule())) return false; auto &M = CMI->getModule(); @@ -369,7 +369,7 @@ static bool tryToSpeculateTarget(FullApplySite AI, // bound generic class in a general case. if (isa(SubCanTy)) return false; - // Handle the ususal case here: the class in question + // Handle the usual case here: the class in question // should be a real subclass of a bound generic class. return !ClassType.isSuperclassOf( SILType::getPrimitiveObjectType(SubCanTy)); diff --git a/lib/SILPasses/Scalar/StackPromotion.cpp b/lib/SILOptimizer/Transforms/StackPromotion.cpp similarity index 95% rename from lib/SILPasses/Scalar/StackPromotion.cpp rename to lib/SILOptimizer/Transforms/StackPromotion.cpp index 241ab1fb3eb48..51bb1d3f8ba1b 100644 --- a/lib/SILPasses/Scalar/StackPromotion.cpp +++ b/lib/SILOptimizer/Transforms/StackPromotion.cpp @@ -1,8 +1,8 @@ -//===------- StackPromotion.cpp - Promotes allocations to the stack -------===// +//===--- StackPromotion.cpp - Promotes allocations to the stack -----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,10 +11,10 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "stack-promotion" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILAnalysis/EscapeAnalysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Analysis/EscapeAnalysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "llvm/ADT/Statistic.h" @@ -37,7 +37,7 @@ using namespace swift; /// size and alignment for the final stack promotion decision. The arguments /// to swift_bufferAllocate in SIL are not constant because they depend on /// the not-yet-evaluatable sizeof and alignof builtins. Therefore we need -/// LLVM's contant propagation prior to deciding on stack promotion. +/// LLVM's constant propagation prior to deciding on stack promotion. /// The solution to this problem is that we need native support for tail- /// allocated arrays in SIL so that we can do the array buffer allocations /// with alloc_ref instructions. @@ -180,7 +180,7 @@ StackPromoter::ChangeState StackPromoter::promote() { // Search the whole function for stack promotable allocations. for (SILBasicBlock &BB : *F) { for (auto Iter = BB.begin(); Iter != BB.end();) { - // The allocaiton instruction may be moved, so increment Iter prior to + // The allocation instruction may be moved, so increment Iter prior to // doing the optimization. SILInstruction *I = &*Iter++; if (isPromotableAllocInst(I)) { @@ -251,7 +251,8 @@ SILFunction *StackPromoter::getBufferAllocFunc(SILFunction *OrigFunc, "swift_bufferAllocateOnStack", OrigFunc->getLinkage(), OrigFunc->getLoweredFunctionType(), - OrigFunc->isBare(), IsNotTransparent, IsNotFragile); + OrigFunc->isBare(), IsNotTransparent, + OrigFunc->isFragile()); } return BufferAllocFunc; } @@ -279,7 +280,7 @@ SILFunction *StackPromoter::getBufferDeallocFunc(SILFunction *OrigFunc, "swift_bufferDeallocateFromStack", OrigFunc->getLinkage(), FunTy, - OrigFunc->isBare(), IsNotTransparent, IsNotFragile); + OrigFunc->isBare(), IsNotTransparent, OrigFunc->isFragile()); } return BufferDeallocFunc; } @@ -289,7 +290,7 @@ bool StackPromoter::canPromoteAlloc(SILInstruction *AI, SILInstruction *&DeallocInsertionPoint) { AllocInsertionPoint = nullptr; DeallocInsertionPoint = nullptr; - auto *Node = ConGraph->getNode(AI, EA); + auto *Node = ConGraph->getNodeOrNull(AI, EA); if (!Node) return false; @@ -305,7 +306,7 @@ bool StackPromoter::canPromoteAlloc(SILInstruction *AI, int NumUsePointsToFind = ConGraph->getNumUsePoints(Node); if (NumUsePointsToFind == 0) { // There should always be at least one release for an allocated object. - // But in case all pathes from this block end in unreachable then the + // But in case all paths from this block end in unreachable then the // final release of the object may be optimized away. We bail out in this // case. return false; @@ -408,7 +409,7 @@ bool StackPromoter::canPromoteAlloc(SILInstruction *AI, if (WorkList.empty()) { if (EndBlock == BB) { // We reached the EndBlock but didn't find a place for the deallocation - // so far (because we didn't find all uses yet or we entered a another + // so far (because we didn't find all uses yet or we entered another // stack alloc-dealloc region). Let's extend our lifetime region. // E.g.: // %obj = alloc_ref // the allocation diff --git a/lib/SILOptimizer/UtilityPasses/AADumper.cpp b/lib/SILOptimizer/UtilityPasses/AADumper.cpp new file mode 100644 index 0000000000000..bf468a000d990 --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/AADumper.cpp @@ -0,0 +1,105 @@ +//===--- AADumper.cpp - Compare all values in Function with AA ------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This pass collects all values in a function and applies alias analysis to +/// them. The purpose of this is to enable unit tests for SIL Alias Analysis +/// implementations independent of any other passes. +/// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-aa-evaluator" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILValue.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +//===----------------------------------------------------------------------===// +// Value Gatherer +//===----------------------------------------------------------------------===// + +// Return a list of all instruction values in Fn. Returns true if we have at +// least two values to compare. +static bool gatherValues(SILFunction &Fn, std::vector &Values) { + for (auto &BB : Fn) { + for (auto *Arg : BB.getBBArgs()) + Values.push_back(SILValue(Arg)); + for (auto &II : BB) + for (unsigned i = 0, e = II.getNumTypes(); i != e; ++i) + Values.push_back(SILValue(&II, i)); + } + return Values.size() > 1; +} + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +namespace { + +/// Dumps the alias relations between all instructions of a function. +class SILAADumper : public SILModuleTransform { + + void run() override { + for (auto &Fn: *getModule()) { + llvm::outs() << "@" << Fn.getName() << "\n"; + // Gather up all Values in Fn. + std::vector Values; + if (!gatherValues(Fn, Values)) + continue; + + AliasAnalysis *AA = PM->getAnalysis(); + + // A cache + llvm::DenseMap Results; + + // Emit the N^2 alias evaluation of the values. + unsigned PairCount = 0; + for (unsigned i1 = 0, e1 = Values.size(); i1 != e1; ++i1) { + for (unsigned i2 = 0, e2 = Values.size(); i2 != e2; ++i2) { + auto V1 = Values[i1]; + auto V2 = Values[i2]; + + auto Result = + AA->alias(V1, V2, computeTBAAType(V1), computeTBAAType(V2)); + + // Results should always be the same. But if they are different print + // it out so we find the error. This should make our test results less + // verbose. + uint64_t Key = uint64_t(i1) | (uint64_t(i2) << 32); + uint64_t OpKey = uint64_t(i2) | (uint64_t(i1) << 32); + auto R = Results.find(OpKey); + if (R != Results.end() && R->second == Result) + continue; + + Results[Key] = Result; + llvm::outs() << "PAIR #" << PairCount++ << ".\n" << V1 << V2 << Result + << "\n"; + } + } + llvm::outs() << "\n"; + } + } + + StringRef getName() override { return "AA Dumper"; } +}; + +} // end anonymous namespace + +SILTransform *swift::createAADumper() { return new SILAADumper(); } diff --git a/lib/SILPasses/UtilityPasses/BasicCalleePrinter.cpp b/lib/SILOptimizer/UtilityPasses/BasicCalleePrinter.cpp similarity index 88% rename from lib/SILPasses/UtilityPasses/BasicCalleePrinter.cpp rename to lib/SILOptimizer/UtilityPasses/BasicCalleePrinter.cpp index f2b26557b1147..b13856bb93142 100644 --- a/lib/SILPasses/UtilityPasses/BasicCalleePrinter.cpp +++ b/lib/SILOptimizer/UtilityPasses/BasicCalleePrinter.cpp @@ -1,8 +1,8 @@ -//===-- BasicCalleePrinter.cpp - Callee cache printing pass ---*- C++ -*---===// +//===--- BasicCalleePrinter.cpp - Callee cache printing pass ----*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,11 +16,11 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" diff --git a/lib/SILPasses/UtilityPasses/CFGPrinter.cpp b/lib/SILOptimizer/UtilityPasses/CFGPrinter.cpp similarity index 86% rename from lib/SILPasses/UtilityPasses/CFGPrinter.cpp rename to lib/SILOptimizer/UtilityPasses/CFGPrinter.cpp index 4bdf1663cc0cd..6880115ee8bbf 100644 --- a/lib/SILPasses/UtilityPasses/CFGPrinter.cpp +++ b/lib/SILOptimizer/UtilityPasses/CFGPrinter.cpp @@ -1,8 +1,8 @@ -//===-- CFGPrinter.cpp - CFG printer pass ---------------------------------===// +//===--- CFGPrinter.cpp - CFG printer pass --------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,8 +15,8 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SIL/CFG.h" #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILInstruction.h" diff --git a/lib/SILOptimizer/UtilityPasses/CMakeLists.txt b/lib/SILOptimizer/UtilityPasses/CMakeLists.txt new file mode 100644 index 0000000000000..2641f19f3c43c --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/CMakeLists.txt @@ -0,0 +1,20 @@ +set(UTILITYPASSES_SOURCES + UtilityPasses/AADumper.cpp + UtilityPasses/BasicCalleePrinter.cpp + UtilityPasses/ComputeDominanceInfo.cpp + UtilityPasses/ComputeLoopInfo.cpp + UtilityPasses/CFGPrinter.cpp + UtilityPasses/EscapeAnalysisDumper.cpp + UtilityPasses/FunctionOrderPrinter.cpp + UtilityPasses/IVInfoPrinter.cpp + UtilityPasses/InstCount.cpp + UtilityPasses/Link.cpp + UtilityPasses/LoopInfoPrinter.cpp + UtilityPasses/LoopCanonicalizer.cpp + UtilityPasses/LoopRegionPrinter.cpp + UtilityPasses/LSLocationPrinter.cpp + UtilityPasses/MemBehaviorDumper.cpp + UtilityPasses/RCIdentityDumper.cpp + UtilityPasses/SideEffectsDumper.cpp + UtilityPasses/StripDebugInfo.cpp + PARENT_SCOPE) diff --git a/lib/SILOptimizer/UtilityPasses/ComputeDominanceInfo.cpp b/lib/SILOptimizer/UtilityPasses/ComputeDominanceInfo.cpp new file mode 100644 index 0000000000000..f941eb4cfad72 --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/ComputeDominanceInfo.cpp @@ -0,0 +1,30 @@ +//===--- ComputeDominanceInfo.cpp -----------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-compute-dominance-info" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" + +using namespace swift; + +class ComputeDominanceInfo : public SILFunctionTransform { + + void run() override { + PM->getAnalysis()->get(getFunction()); + PM->getAnalysis()->get(getFunction()); + } + + StringRef getName() override { return "Compute Dominance Info"; } +}; + +SILTransform *swift::createComputeDominanceInfo() { return new ComputeDominanceInfo(); } diff --git a/lib/SILOptimizer/UtilityPasses/ComputeLoopInfo.cpp b/lib/SILOptimizer/UtilityPasses/ComputeLoopInfo.cpp new file mode 100644 index 0000000000000..3f6558421a41f --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/ComputeLoopInfo.cpp @@ -0,0 +1,29 @@ +//===--- ComputeLoopInfo.cpp ----------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-compute-loop-info" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" + +using namespace swift; + +class ComputeLoopInfo : public SILFunctionTransform { + + void run() override { + PM->getAnalysis()->get(getFunction()); + } + + StringRef getName() override { return "Compute Loop Info"; } +}; + +SILTransform *swift::createComputeLoopInfo() { return new ComputeLoopInfo(); } diff --git a/lib/SILOptimizer/UtilityPasses/EscapeAnalysisDumper.cpp b/lib/SILOptimizer/UtilityPasses/EscapeAnalysisDumper.cpp new file mode 100644 index 0000000000000..abe0017299878 --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/EscapeAnalysisDumper.cpp @@ -0,0 +1,50 @@ +//===--- EscapeAnalysisDumper.cpp - Dumps the escape analysis -------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "dump-ea" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/Analysis/EscapeAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" + +using namespace swift; + +namespace { + +/// Dumps the escape information of all functions in the module. +/// Only dumps if the compiler is built with assertions. +/// For details see EscapeAnalysis. +class EscapeAnalysisDumper : public SILModuleTransform { + + void run() override { + DEBUG(llvm::dbgs() << "** EscapeAnalysisDumper **\n"); + +#ifndef NDEBUG + auto *EA = PM->getAnalysis(); + + llvm::outs() << "Escape information of module\n"; + for (auto &F : *getModule()) { + if (!F.isExternalDeclaration()) { + auto *ConnectionGraph = EA->getConnectionGraph(&F); + ConnectionGraph->print(llvm::outs()); + } + } +#endif + } + + StringRef getName() override { return "EscapeAnalysisDumper"; } +}; + +} // end anonymous namespace + +SILTransform *swift::createEscapeAnalysisDumper() { + return new EscapeAnalysisDumper(); +} diff --git a/lib/SILPasses/UtilityPasses/FunctionOrderPrinter.cpp b/lib/SILOptimizer/UtilityPasses/FunctionOrderPrinter.cpp similarity index 85% rename from lib/SILPasses/UtilityPasses/FunctionOrderPrinter.cpp rename to lib/SILOptimizer/UtilityPasses/FunctionOrderPrinter.cpp index 493d6e58ccf32..5ddabe4532ffd 100644 --- a/lib/SILPasses/UtilityPasses/FunctionOrderPrinter.cpp +++ b/lib/SILOptimizer/UtilityPasses/FunctionOrderPrinter.cpp @@ -1,8 +1,8 @@ -//===-- FunctionOrderPrinter.cpp - Function ordering test pass ------------===// +//===--- FunctionOrderPrinter.cpp - Function ordering test pass -----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,12 +15,12 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/FunctionOrder.h" +#include "swift/SILOptimizer/Analysis/FunctionOrder.h" #include "swift/Basic/DemangleWrappers.h" -#include "swift/SILAnalysis/BasicCalleeAnalysis.h" +#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" #include "swift/SIL/SILFunction.h" #include "swift/SIL/SILModule.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "llvm/Support/raw_ostream.h" using namespace swift; diff --git a/lib/SILPasses/UtilityPasses/IVInfoPrinter.cpp b/lib/SILOptimizer/UtilityPasses/IVInfoPrinter.cpp similarity index 86% rename from lib/SILPasses/UtilityPasses/IVInfoPrinter.cpp rename to lib/SILOptimizer/UtilityPasses/IVInfoPrinter.cpp index 70aa47118e221..38a6da491d0de 100644 --- a/lib/SILPasses/UtilityPasses/IVInfoPrinter.cpp +++ b/lib/SILOptimizer/UtilityPasses/IVInfoPrinter.cpp @@ -1,8 +1,8 @@ -//===------------ IVInfoPrinter.cpp - Print SIL IV Info -*- C++ -*-------===// +//===--- IVInfoPrinter.cpp - Print SIL IV Info ------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,9 +10,9 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/IVAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Analysis/IVAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" using namespace swift; diff --git a/lib/SILPasses/UtilityPasses/InstCount.cpp b/lib/SILOptimizer/UtilityPasses/InstCount.cpp similarity index 94% rename from lib/SILPasses/UtilityPasses/InstCount.cpp rename to lib/SILOptimizer/UtilityPasses/InstCount.cpp index eef9b4cb89ccb..c9f2613f85356 100644 --- a/lib/SILPasses/UtilityPasses/InstCount.cpp +++ b/lib/SILOptimizer/UtilityPasses/InstCount.cpp @@ -1,8 +1,8 @@ -//===-- InstCount.cpp - Collects the count of all instructions ------------===// +//===--- InstCount.cpp - Collects the count of all instructions -----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,9 +15,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-instcount" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/PassManager.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILVisitor.h" #include "llvm/ADT/Statistic.h" diff --git a/lib/SILOptimizer/UtilityPasses/LSLocationPrinter.cpp b/lib/SILOptimizer/UtilityPasses/LSLocationPrinter.cpp new file mode 100644 index 0000000000000..b05195f9cf490 --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/LSLocationPrinter.cpp @@ -0,0 +1,261 @@ +//===--- LSLocationPrinter.cpp - Dump all memory locations in program -----===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This pass tests type expansion, memlocation expansion and memlocation +// reduction. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-memlocation-dumper" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SIL/Projection.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILValue.h" +#include "swift/SIL/SILValueProjection.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +namespace { + +enum class MLKind : unsigned { + OnlyExpansion = 0, + OnlyReduction = 1, + OnlyTypeExpansion = 2, + All = 3, +}; + +} // end anonymous namespace + +static llvm::cl::opt LSLocationKinds( + "ml", llvm::cl::desc("LSLocation Kinds:"), llvm::cl::init(MLKind::All), + llvm::cl::values( + clEnumValN(MLKind::OnlyExpansion, "only-expansion", "only-expansion"), + clEnumValN(MLKind::OnlyReduction, "only-reduction", "only-reduction"), + clEnumValN(MLKind::OnlyTypeExpansion, "only-type-expansion", + "only-type-expansion"), + clEnumValN(MLKind::All, "all", "all"), clEnumValEnd)); + +static llvm::cl::opt UseNewProjection("lslocation-dump-use-new-projection", + llvm::cl::init(false)); + +namespace { + +class LSLocationPrinter : public SILModuleTransform { + /// Type expansion analysis. + TypeExpansionAnalysis *TE; + +public: + /// Dumps the expansions of SILType accessed in the function. + /// This tests the expandTypeIntoLeafProjectionPaths function, which is + /// a function used extensively in expand and reduce functions. + /// + /// We test it to catch any suspicious things in the earliest point. + /// + void printTypeExpansion(SILFunction &Fn) { + SILModule *M = &Fn.getModule(); + ProjectionPathList PPList; + unsigned Counter = 0; + for (auto &BB : Fn) { + for (auto &II : BB) { + if (auto *LI = dyn_cast(&II)) { + SILValue V = LI->getOperand(); + // This is an address type, take it object type. + SILType Ty = V.getType().getObjectType(); + ProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList); + } else if (auto *SI = dyn_cast(&II)) { + SILValue V = SI->getDest(); + // This is an address type, take it object type. + SILType Ty = V.getType().getObjectType(); + ProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList); + } else { + // Not interested in these instructions yet. + continue; + } + + llvm::outs() << "#" << Counter++ << II; + for (auto &T : PPList) { + llvm::outs() << T.getValue(); + } + PPList.clear(); + } + } + llvm::outs() << "\n"; + } + + void printTypeExpansionWithNewProjection(SILFunction &Fn) { + SILModule *M = &Fn.getModule(); + llvm::SmallVector PPList; + unsigned Counter = 0; + for (auto &BB : Fn) { + for (auto &II : BB) { + SILValue V; + SILType Ty; + if (auto *LI = dyn_cast(&II)) { + V = LI->getOperand(); + // This is an address type, take it object type. + Ty = V.getType().getObjectType(); + NewProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList, + true); + } else if (auto *SI = dyn_cast(&II)) { + V = SI->getDest(); + // This is an address type, take it object type. + Ty = V.getType().getObjectType(); + NewProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList, + true); + } else { + // Not interested in these instructions yet. + continue; + } + + llvm::outs() << "#" << Counter++ << II; + for (auto &T : PPList) { + T.print(llvm::outs(), *M); + } + PPList.clear(); + } + } + llvm::outs() << "\n"; + } + + /// Dumps the expansions of memory locations accessed in the function. + /// This tests the expand function in LSLocation class. + /// + /// We test it to catch any suspicious things when memory location is + /// expanded, i.e. base is traced back and aggregate is expanded + /// properly. + void printMemExpansion(SILFunction &Fn) { + LSLocation L; + LSLocationList Locs; + unsigned Counter = 0; + for (auto &BB : Fn) { + for (auto &II : BB) { + if (auto *LI = dyn_cast(&II)) { + L.initialize(LI->getOperand()); + if (!L.isValid()) + continue; + LSLocation::expand(L, &Fn.getModule(), Locs, TE); + } else if (auto *SI = dyn_cast(&II)) { + L.initialize(SI->getDest()); + if (!L.isValid()) + continue; + LSLocation::expand(L, &Fn.getModule(), Locs, TE); + } else { + // Not interested in these instructions yet. + continue; + } + + llvm::outs() << "#" << Counter++ << II; + for (auto &Loc : Locs) { + Loc.print(); + } + L.reset(); + Locs.clear(); + } + } + llvm::outs() << "\n"; + } + + /// Dumps the reductions of set of memory locations. + /// + /// This function first calls expand on a memory location. It then calls + /// reduce, in hope to get the original memory location back. + /// + void printMemReduction(SILFunction &Fn) { + LSLocation L; + LSLocationList Locs; + llvm::DenseSet SLocs; + unsigned Counter = 0; + for (auto &BB : Fn) { + for (auto &II : BB) { + + // Expand it first. + // + if (auto *LI = dyn_cast(&II)) { + L.initialize(LI->getOperand()); + if (!L.isValid()) + continue; + LSLocation::expand(L, &Fn.getModule(), Locs, TE); + } else if (auto *SI = dyn_cast(&II)) { + L.initialize(SI->getDest()); + if (!L.isValid()) + continue; + LSLocation::expand(L, &Fn.getModule(), Locs, TE); + } else { + // Not interested in these instructions yet. + continue; + } + + // Try to reduce it. + // + // Add into the set in reverse order, Reduction should not care + // about the order of the memory locations in the set. + for (auto I = Locs.rbegin(); I != Locs.rend(); ++I) { + SLocs.insert(*I); + } + // This should get the original (unexpanded) location back. + LSLocation::reduce(L, &Fn.getModule(), SLocs, TE); + llvm::outs() << "#" << Counter++ << II; + for (auto &Loc : SLocs) { + Loc.print(); + } + L.reset(); + Locs.clear(); + SLocs.clear(); + } + } + llvm::outs() << "\n"; + } + + void run() override { + for (auto &Fn : *getModule()) { + if (Fn.isExternalDeclaration()) continue; + + // Initialize the type expansion analysis. + TE = PM->getAnalysis(); + + llvm::outs() << "@" << Fn.getName() << "\n"; + switch (LSLocationKinds) { + case MLKind::OnlyTypeExpansion: + if (UseNewProjection) { + printTypeExpansionWithNewProjection(Fn); + } else { + printTypeExpansion(Fn); + } + break; + case MLKind::OnlyExpansion: + printMemExpansion(Fn); + break; + case MLKind::OnlyReduction: + printMemReduction(Fn); + break; + default: + break; + } + } + } + + StringRef getName() override { return "Mem Location Dumper"; } +}; + +} // end anonymous namespace + +SILTransform *swift::createLSLocationPrinter() { + return new LSLocationPrinter(); +} diff --git a/lib/SILPasses/UtilityPasses/Link.cpp b/lib/SILOptimizer/UtilityPasses/Link.cpp similarity index 90% rename from lib/SILPasses/UtilityPasses/Link.cpp rename to lib/SILOptimizer/UtilityPasses/Link.cpp index 01b1bc8a0532b..a1458394f8a32 100644 --- a/lib/SILPasses/UtilityPasses/Link.cpp +++ b/lib/SILOptimizer/UtilityPasses/Link.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SIL/SILModule.h" using namespace swift; diff --git a/lib/SILPasses/UtilityPasses/LoopCanonicalizer.cpp b/lib/SILOptimizer/UtilityPasses/LoopCanonicalizer.cpp similarity index 83% rename from lib/SILPasses/UtilityPasses/LoopCanonicalizer.cpp rename to lib/SILOptimizer/UtilityPasses/LoopCanonicalizer.cpp index e8ea7e1a7d656..bb3e57592fccf 100644 --- a/lib/SILPasses/UtilityPasses/LoopCanonicalizer.cpp +++ b/lib/SILOptimizer/UtilityPasses/LoopCanonicalizer.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,12 +17,12 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-loop-canonicalizer" -#include "swift/SILPasses/Passes.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/LoopUtils.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/LoopUtils.h" using namespace swift; diff --git a/lib/SILPasses/UtilityPasses/LoopInfoPrinter.cpp b/lib/SILOptimizer/UtilityPasses/LoopInfoPrinter.cpp similarity index 81% rename from lib/SILPasses/UtilityPasses/LoopInfoPrinter.cpp rename to lib/SILOptimizer/UtilityPasses/LoopInfoPrinter.cpp index 278b6fd083d07..5e0a7288193aa 100644 --- a/lib/SILPasses/UtilityPasses/LoopInfoPrinter.cpp +++ b/lib/SILOptimizer/UtilityPasses/LoopInfoPrinter.cpp @@ -1,8 +1,8 @@ -//===------------ LoopInfoPrinter.h - Print SIL Loop Info -*- C++ -*-------===// +//===--- LoopInfoPrinter.cpp - Print SIL Loop Info --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,9 +10,9 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILAnalysis/LoopAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Analysis/LoopAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILVisitor.h" #include "llvm/ADT/Statistic.h" diff --git a/lib/SILPasses/UtilityPasses/LoopRegionPrinter.cpp b/lib/SILOptimizer/UtilityPasses/LoopRegionPrinter.cpp similarity index 86% rename from lib/SILPasses/UtilityPasses/LoopRegionPrinter.cpp rename to lib/SILOptimizer/UtilityPasses/LoopRegionPrinter.cpp index e2656ecdd1883..64e3f4430e64b 100644 --- a/lib/SILPasses/UtilityPasses/LoopRegionPrinter.cpp +++ b/lib/SILOptimizer/UtilityPasses/LoopRegionPrinter.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,9 +17,9 @@ #define DEBUG_TYPE "sil-loop-region-printer" -#include "swift/SILAnalysis/LoopRegionAnalysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" using namespace swift; @@ -49,6 +49,8 @@ class LoopRegionViewCFG : public SILModuleTransform { auto *M = getModule(); for (auto &Fn : M->getFunctions()) { + if (Fn.isExternalDeclaration()) + continue; LRA->get(&Fn)->viewLoopRegions(); } } diff --git a/lib/SILOptimizer/UtilityPasses/MemBehaviorDumper.cpp b/lib/SILOptimizer/UtilityPasses/MemBehaviorDumper.cpp new file mode 100644 index 0000000000000..49a15f458f418 --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/MemBehaviorDumper.cpp @@ -0,0 +1,102 @@ +//===--- MemBehaviorDumper.cpp --------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-mem-behavior-dumper" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILValue.h" +#include "swift/SILOptimizer/Analysis/AliasAnalysis.h" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +//===----------------------------------------------------------------------===// +// Value Gatherer +//===----------------------------------------------------------------------===// + +// Return a list of all instruction values in Fn. Returns true if we have at +// least two values to compare. +static bool gatherValues(SILFunction &Fn, std::vector &Values) { + for (auto &BB : Fn) { + for (auto *Arg : BB.getBBArgs()) + Values.push_back(SILValue(Arg)); + for (auto &II : BB) + for (unsigned i = 0, e = II.getNumTypes(); i != e; ++i) + Values.push_back(SILValue(&II, i)); + } + return Values.size() > 1; +} + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +namespace { + +/// Dumps the memory behavior of instructions in a function. +class MemBehaviorDumper : public SILModuleTransform { + + // To reduce the amount of output, we only dump the memory behavior of + // selected types of instructions. + static bool shouldTestInstruction(SILInstruction *I) { + // Only consider function calls. + if (FullApplySite::isa(I)) + return true; + + return false; + } + + void run() override { + for (auto &Fn : *getModule()) { + llvm::outs() << "@" << Fn.getName() << "\n"; + // Gather up all Values in Fn. + std::vector Values; + if (!gatherValues(Fn, Values)) + continue; + + AliasAnalysis *AA = PM->getAnalysis(); + + unsigned PairCount = 0; + for (auto &BB : Fn) { + for (auto &I : BB) { + if (shouldTestInstruction(&I)) { + + // Print the memory behavior in relation to all other values in the + // function. + for (auto &V : Values) { + bool Read = AA->mayReadFromMemory(&I, V); + bool Write = AA->mayWriteToMemory(&I, V); + bool SideEffects = AA->mayHaveSideEffects(&I, V); + llvm::outs() << "PAIR #" << PairCount++ << ".\n" + << " " << SILValue(&I) << " " << V + << " r=" << Read << ",w=" << Write + << ",se=" << SideEffects << "\n"; + } + } + } + } + llvm::outs() << "\n"; + } + } + + StringRef getName() override { return "Memory Behavior Dumper"; } +}; + +} // end anonymous namespace + +SILTransform *swift::createMemBehaviorDumper() { + return new MemBehaviorDumper(); +} diff --git a/lib/SILOptimizer/UtilityPasses/RCIdentityDumper.cpp b/lib/SILOptimizer/UtilityPasses/RCIdentityDumper.cpp new file mode 100644 index 0000000000000..1bc9b6bf5e857 --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/RCIdentityDumper.cpp @@ -0,0 +1,81 @@ +//===--- RCIdentityDumper.cpp ---------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// This pass applies the RCIdentityAnalysis to all SILValues in a function in +/// order to apply FileCheck testing to RCIdentityAnalysis without needing to +/// test any other passes. +/// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-rc-identity-dumper" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILValue.h" +#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" +#include "llvm/Support/Debug.h" + +using namespace swift; + +namespace { + +/// Dumps the alias relations between all instructions of a function. +class RCIdentityDumper : public SILFunctionTransform { + + void run() override { + auto *Fn = getFunction(); + auto *RCId = PM->getAnalysis()->get(Fn); + + std::vector> Results; + unsigned ValueCount = 0; + llvm::MapVector ValueToValueIDMap; + + llvm::outs() << "@" << Fn->getName() << "@\n"; + + for (auto &BB : *Fn) { + for (auto *Arg : BB.getBBArgs()) { + ValueToValueIDMap[Arg] = ValueCount++; + Results.push_back({Arg, RCId->getRCIdentityRoot(Arg)}); + } + for (auto &II : BB) { + for (unsigned i = 0, e = II.getNumTypes(); i != e; ++i) { + SILValue V(&II, i); + ValueToValueIDMap[V] = ValueCount++; + Results.push_back({V, RCId->getRCIdentityRoot(V)}); + } + } + } + + llvm::outs() << "ValueMap:\n"; + for (auto P : ValueToValueIDMap) { + llvm::outs() << "\tValueMap[" << P.second << "] = " << P.first; + } + + unsigned ResultCount = 0; + for (auto P : Results) { + llvm::outs() << "RESULT #" << ResultCount++ << ": " + << ValueToValueIDMap[P.first] << " = " + << ValueToValueIDMap[P.second] << "\n"; + } + + llvm::outs() << "\n"; + } + + StringRef getName() override { return "RC Identity Dumper"; } +}; + +} // end anonymous namespace + +SILTransform *swift::createRCIdentityDumper() { return new RCIdentityDumper(); } diff --git a/lib/SILOptimizer/UtilityPasses/SideEffectsDumper.cpp b/lib/SILOptimizer/UtilityPasses/SideEffectsDumper.cpp new file mode 100644 index 0000000000000..f3a3fb7577155 --- /dev/null +++ b/lib/SILOptimizer/UtilityPasses/SideEffectsDumper.cpp @@ -0,0 +1,50 @@ +//===--- SideEffectsDumper.cpp - Dumps the side effect analysis -----------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "dump-sea" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/Analysis/SideEffectAnalysis.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" + +using namespace swift; + +namespace { + +/// Dumps the side-effect information of all functions in the module. +/// Only dumps if the compiler is built with assertions. +/// For details see SideEffectAnalysis. +class SideEffectsDumper : public SILModuleTransform { + + void run() override { + + DEBUG(llvm::dbgs() << "** SideEffectsDumper **\n"); + +#ifndef NDEBUG + auto *SEA = PM->getAnalysis(); + + llvm::outs() << "Side effects of module\n"; + for (auto &F : *getModule()) { + llvm::outs() << " sil @" << F.getName() << '\n'; + const auto &Effects = SEA->getEffects(&F); + llvm::outs() << " <" << Effects << ">\n"; + } +#endif + } + + StringRef getName() override { return "SideEffectsDumper"; } +}; + +} // end anonymous namespace + +SILTransform *swift::createSideEffectsDumper() { + return new SideEffectsDumper(); +} diff --git a/lib/SILPasses/UtilityPasses/StripDebugInfo.cpp b/lib/SILOptimizer/UtilityPasses/StripDebugInfo.cpp similarity index 84% rename from lib/SILPasses/UtilityPasses/StripDebugInfo.cpp rename to lib/SILOptimizer/UtilityPasses/StripDebugInfo.cpp index 36c34bb112745..2dff3ff013339 100644 --- a/lib/SILPasses/UtilityPasses/StripDebugInfo.cpp +++ b/lib/SILOptimizer/UtilityPasses/StripDebugInfo.cpp @@ -1,8 +1,8 @@ -//===-------- StripDebugInfo.cpp - Strip debug info from SIL --------------===// +//===--- StripDebugInfo.cpp - Strip debug info from SIL -------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILFunction.h" diff --git a/lib/SILOptimizer/Utils/CFG.cpp b/lib/SILOptimizer/Utils/CFG.cpp new file mode 100644 index 0000000000000..f3dec11ebdfe0 --- /dev/null +++ b/lib/SILOptimizer/Utils/CFG.cpp @@ -0,0 +1,782 @@ +//===--- CFG.cpp - Utilities for SIL CFG transformations --------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "swift/SIL/Dominance.h" +#include "swift/SIL/LoopInfo.h" +#include "swift/SIL/SILArgument.h" +#include "swift/SIL/SILBuilder.h" +#include "swift/SILOptimizer/Utils/CFG.h" + +using namespace swift; + +/// \brief Adds a new argument to an edge between a branch and a destination +/// block. +/// +/// \param Branch The terminator to add the argument to. +/// \param Dest The destination block of the edge. +/// \param Val The value to the arguments of the branch. +/// \return The created branch. The old branch is deleted. +/// The argument is appended at the end of the argument tuple. +TermInst *swift::addNewEdgeValueToBranch(TermInst *Branch, SILBasicBlock *Dest, + SILValue Val) { + SILBuilderWithScope Builder(Branch); + TermInst *NewBr = nullptr; + + if (CondBranchInst *CBI = dyn_cast(Branch)) { + SmallVector TrueArgs; + SmallVector FalseArgs; + + for (auto A : CBI->getTrueArgs()) + TrueArgs.push_back(A); + + for (auto A : CBI->getFalseArgs()) + FalseArgs.push_back(A); + + if (Dest == CBI->getTrueBB()) { + TrueArgs.push_back(Val); + assert(TrueArgs.size() == Dest->getNumBBArg()); + } + if (Dest == CBI->getFalseBB()) { + FalseArgs.push_back(Val); + assert(FalseArgs.size() == Dest->getNumBBArg()); + } + + NewBr = Builder.createCondBranch(CBI->getLoc(), CBI->getCondition(), + CBI->getTrueBB(), TrueArgs, + CBI->getFalseBB(), FalseArgs); + } else if (BranchInst *BI = dyn_cast(Branch)) { + SmallVector Args; + + for (auto A : BI->getArgs()) + Args.push_back(A); + + Args.push_back(Val); + assert(Args.size() == Dest->getNumBBArg()); + NewBr = Builder.createBranch(BI->getLoc(), BI->getDestBB(), Args); + } else { + NewBr->dump(); + // At the moment we can only add arguments to br and cond_br. + llvm_unreachable("Can't add argument to terminator"); + return NewBr; + } + + Branch->dropAllReferences(); + Branch->eraseFromParent(); + + return NewBr; +} + +/// \brief Changes the edge value between a branch and destination basic block +/// at the specified index. Changes all edges from \p Branch to \p Dest to carry +/// the value. +/// +/// \param Branch The branch to modify. +/// \param Dest The destination of the edge. +/// \param Idx The index of the argument to modify. +/// \param Val The new value to use. +/// \return The new branch. Deletes the old one. +/// Changes the edge value between a branch and destination basic block at the +/// specified index. +TermInst *swift::changeEdgeValue(TermInst *Branch, SILBasicBlock *Dest, + size_t Idx, SILValue Val) { + SILBuilderWithScope Builder(Branch); + + if (CondBranchInst *CBI = dyn_cast(Branch)) { + SmallVector TrueArgs; + SmallVector FalseArgs; + + OperandValueArrayRef OldTrueArgs = CBI->getTrueArgs(); + bool BranchOnTrue = CBI->getTrueBB() == Dest; + assert((!BranchOnTrue || Idx < OldTrueArgs.size()) && "Not enough edges"); + + // Copy the edge values overwriting the edge at Idx. + for (unsigned i = 0, e = OldTrueArgs.size(); i != e; ++i) { + if (BranchOnTrue && Idx == i) + TrueArgs.push_back(Val); + else + TrueArgs.push_back(OldTrueArgs[i]); + } + assert(TrueArgs.size() == CBI->getTrueBB()->getNumBBArg() && + "Destination block's number of arguments must match"); + + OperandValueArrayRef OldFalseArgs = CBI->getFalseArgs(); + bool BranchOnFalse = CBI->getFalseBB() == Dest; + assert((!BranchOnFalse || Idx < OldFalseArgs.size()) && "Not enough edges"); + + // Copy the edge values overwriting the edge at Idx. + for (unsigned i = 0, e = OldFalseArgs.size(); i != e; ++i) { + if (BranchOnFalse && Idx == i) + FalseArgs.push_back(Val); + else + FalseArgs.push_back(OldFalseArgs[i]); + } + assert(FalseArgs.size() == CBI->getFalseBB()->getNumBBArg() && + "Destination block's number of arguments must match"); + + CBI = Builder.createCondBranch(CBI->getLoc(), CBI->getCondition(), + CBI->getTrueBB(), TrueArgs, + CBI->getFalseBB(), FalseArgs); + Branch->dropAllReferences(); + Branch->eraseFromParent(); + return CBI; + } + + if (BranchInst *BI = dyn_cast(Branch)) { + SmallVector Args; + + assert(Idx < BI->getNumArgs() && "Not enough edges"); + OperandValueArrayRef OldArgs = BI->getArgs(); + + // Copy the edge values overwriting the edge at Idx. + for (unsigned i = 0, e = OldArgs.size(); i != e; ++i) { + if (Idx == i) + Args.push_back(Val); + else + Args.push_back(OldArgs[i]); + } + assert(Args.size() == Dest->getNumBBArg()); + + BI = Builder.createBranch(BI->getLoc(), BI->getDestBB(), Args); + Branch->dropAllReferences(); + Branch->eraseFromParent(); + return BI; + } + + llvm_unreachable("Unhandled terminator leading to merge block"); +} + +template +SILBasicBlock *replaceSwitchDest(SwitchEnumTy *S, + SmallVectorImpl &Cases, + unsigned EdgeIdx, SILBasicBlock *NewDest) { + auto *DefaultBB = S->hasDefault() ? S->getDefaultBB() : nullptr; + for (unsigned i = 0, e = S->getNumCases(); i != e; ++i) + if (EdgeIdx != i) + Cases.push_back(S->getCase(i)); + else + Cases.push_back(std::make_pair(S->getCase(i).first, NewDest)); + if (EdgeIdx == S->getNumCases()) + DefaultBB = NewDest; + return DefaultBB; +} + +void swift::changeBranchTarget(TermInst *T, unsigned EdgeIdx, + SILBasicBlock *NewDest, bool PreserveArgs) { + SILBuilderWithScope B(T); + + switch (T->getTermKind()) { + case TermKind::Invalid: + llvm_unreachable("Unexpected terminator instruction!"); + // Only Branch and CondBranch may have arguments. + case TermKind::BranchInst: { + auto Br = dyn_cast(T); + SmallVector Args; + if (PreserveArgs) { + for (auto Arg : Br->getArgs()) + Args.push_back(Arg); + } + B.createBranch(T->getLoc(), NewDest, Args); + Br->dropAllReferences(); + Br->eraseFromParent(); + return; + } + + case TermKind::CondBranchInst: { + auto CondBr = dyn_cast(T); + SmallVector TrueArgs; + if (EdgeIdx == CondBranchInst::FalseIdx || PreserveArgs) { + for (auto Arg : CondBr->getTrueArgs()) + TrueArgs.push_back(Arg); + } + SmallVector FalseArgs; + if (EdgeIdx == CondBranchInst::TrueIdx || PreserveArgs) { + for (auto Arg : CondBr->getFalseArgs()) + FalseArgs.push_back(Arg); + } + SILBasicBlock *TrueDest = CondBr->getTrueBB(); + SILBasicBlock *FalseDest = CondBr->getFalseBB(); + if (EdgeIdx == CondBranchInst::TrueIdx) + TrueDest = NewDest; + else + FalseDest = NewDest; + + B.createCondBranch(CondBr->getLoc(), CondBr->getCondition(), + TrueDest, TrueArgs, FalseDest, FalseArgs); + CondBr->dropAllReferences(); + CondBr->eraseFromParent(); + return; + } + + case TermKind::SwitchValueInst: { + auto SII = dyn_cast(T); + SmallVector, 8> Cases; + auto *DefaultBB = replaceSwitchDest(SII, Cases, EdgeIdx, NewDest); + B.createSwitchValue(SII->getLoc(), SII->getOperand(), DefaultBB, Cases); + SII->eraseFromParent(); + return; + } + + case TermKind::SwitchEnumInst: { + auto SEI = dyn_cast(T); + SmallVector, 8> Cases; + auto *DefaultBB = replaceSwitchDest(SEI, Cases, EdgeIdx, NewDest); + B.createSwitchEnum(SEI->getLoc(), SEI->getOperand(), DefaultBB, Cases); + SEI->eraseFromParent(); + return; + } + + case TermKind::SwitchEnumAddrInst: { + auto SEI = dyn_cast(T); + SmallVector, 8> Cases; + auto *DefaultBB = replaceSwitchDest(SEI, Cases, EdgeIdx, NewDest); + B.createSwitchEnumAddr(SEI->getLoc(), SEI->getOperand(), DefaultBB, Cases); + SEI->eraseFromParent(); + return; + } + + case TermKind::DynamicMethodBranchInst: { + auto DMBI = dyn_cast(T); + assert(EdgeIdx == 0 || EdgeIdx == 1 && "Invalid edge index"); + auto HasMethodBB = !EdgeIdx ? NewDest : DMBI->getHasMethodBB(); + auto NoMethodBB = EdgeIdx ? NewDest : DMBI->getNoMethodBB(); + B.createDynamicMethodBranch(DMBI->getLoc(), DMBI->getOperand(), + DMBI->getMember(), HasMethodBB, NoMethodBB); + DMBI->eraseFromParent(); + return; + } + + case TermKind::CheckedCastBranchInst: { + auto CBI = dyn_cast(T); + assert(EdgeIdx == 0 || EdgeIdx == 1 && "Invalid edge index"); + auto SuccessBB = !EdgeIdx ? NewDest : CBI->getSuccessBB(); + auto FailureBB = EdgeIdx ? NewDest : CBI->getFailureBB(); + B.createCheckedCastBranch(CBI->getLoc(), CBI->isExact(), CBI->getOperand(), + CBI->getCastType(), SuccessBB, FailureBB); + CBI->eraseFromParent(); + return; + } + + case TermKind::CheckedCastAddrBranchInst: { + auto CBI = dyn_cast(T); + assert(EdgeIdx == 0 || EdgeIdx == 1 && "Invalid edge index"); + auto SuccessBB = !EdgeIdx ? NewDest : CBI->getSuccessBB(); + auto FailureBB = EdgeIdx ? NewDest : CBI->getFailureBB(); + B.createCheckedCastAddrBranch(CBI->getLoc(), CBI->getConsumptionKind(), + CBI->getSrc(), CBI->getSourceType(), + CBI->getDest(), CBI->getTargetType(), + SuccessBB, FailureBB); + CBI->eraseFromParent(); + return; + } + + case TermKind::TryApplyInst: { + auto *TAI = dyn_cast(T); + assert((EdgeIdx == 0 || EdgeIdx == 1) && "Invalid edge index"); + auto *NormalBB = !EdgeIdx ? NewDest : TAI->getNormalBB(); + auto *ErrorBB = EdgeIdx ? NewDest : TAI->getErrorBB(); + SmallVector Arguments; + for (auto &Op : TAI->getArgumentOperands()) + Arguments.push_back(Op.get()); + + B.createTryApply(TAI->getLoc(), TAI->getCallee(), + TAI->getSubstCalleeSILType(), TAI->getSubstitutions(), + Arguments, NormalBB, ErrorBB); + + TAI->eraseFromParent(); + return; + } + + case TermKind::ReturnInst: + case TermKind::ThrowInst: + case TermKind::UnreachableInst: + llvm_unreachable("Branch target cannot be changed for this terminator instruction!"); + } + llvm_unreachable("Not yet implemented!"); +} + + +template +SILBasicBlock *replaceSwitchDest(SwitchEnumTy *S, + SmallVectorImpl &Cases, + SILBasicBlock *OldDest, SILBasicBlock *NewDest) { + auto *DefaultBB = S->hasDefault() ? S->getDefaultBB() : nullptr; + for (unsigned i = 0, e = S->getNumCases(); i != e; ++i) + if (S->getCase(i).second != OldDest) + Cases.push_back(S->getCase(i)); + else + Cases.push_back(std::make_pair(S->getCase(i).first, NewDest)); + if (OldDest == DefaultBB) + DefaultBB = NewDest; + return DefaultBB; +} + +/// \brief Replace a branch target. +/// +/// \param T The terminating instruction to modify. +/// \param OldDest The successor block that will be replaced. +/// \param NewDest The new target block. +/// \param PreserveArgs If set, preserve arguments on the replaced edge. +void swift::replaceBranchTarget(TermInst *T, SILBasicBlock *OldDest, + SILBasicBlock *NewDest, bool PreserveArgs) { + SILBuilderWithScope B(T); + + switch (T->getTermKind()) { + case TermKind::Invalid: + llvm_unreachable("Unexpected terminator instruction!"); + // Only Branch and CondBranch may have arguments. + case TermKind::BranchInst: { + auto Br = dyn_cast(T); + SmallVector Args; + if (PreserveArgs) { + for (auto Arg : Br->getArgs()) + Args.push_back(Arg); + } + B.createBranch(T->getLoc(), NewDest, Args); + Br->dropAllReferences(); + Br->eraseFromParent(); + return; + } + + case TermKind::CondBranchInst: { + auto CondBr = dyn_cast(T); + SmallVector TrueArgs; + if (OldDest == CondBr->getFalseBB() || PreserveArgs) { + for (auto Arg : CondBr->getTrueArgs()) + TrueArgs.push_back(Arg); + } + SmallVector FalseArgs; + if (OldDest == CondBr->getTrueBB() || PreserveArgs) { + for (auto Arg : CondBr->getFalseArgs()) + FalseArgs.push_back(Arg); + } + SILBasicBlock *TrueDest = CondBr->getTrueBB(); + SILBasicBlock *FalseDest = CondBr->getFalseBB(); + if (OldDest == CondBr->getTrueBB()) + TrueDest = NewDest; + else + FalseDest = NewDest; + + B.createCondBranch(CondBr->getLoc(), CondBr->getCondition(), + TrueDest, TrueArgs, FalseDest, FalseArgs); + CondBr->dropAllReferences(); + CondBr->eraseFromParent(); + return; + } + + case TermKind::SwitchValueInst: { + auto SII = dyn_cast(T); + SmallVector, 8> Cases; + auto *DefaultBB = replaceSwitchDest(SII, Cases, OldDest, NewDest); + B.createSwitchValue(SII->getLoc(), SII->getOperand(), DefaultBB, Cases); + SII->eraseFromParent(); + return; + } + + case TermKind::SwitchEnumInst: { + auto SEI = dyn_cast(T); + SmallVector, 8> Cases; + auto *DefaultBB = replaceSwitchDest(SEI, Cases, OldDest, NewDest); + B.createSwitchEnum(SEI->getLoc(), SEI->getOperand(), DefaultBB, Cases); + SEI->eraseFromParent(); + return; + } + + case TermKind::SwitchEnumAddrInst: { + auto SEI = dyn_cast(T); + SmallVector, 8> Cases; + auto *DefaultBB = replaceSwitchDest(SEI, Cases, OldDest, NewDest); + B.createSwitchEnumAddr(SEI->getLoc(), SEI->getOperand(), DefaultBB, Cases); + SEI->eraseFromParent(); + return; + } + + case TermKind::DynamicMethodBranchInst: { + auto DMBI = dyn_cast(T); + assert(OldDest == DMBI->getHasMethodBB() || OldDest == DMBI->getNoMethodBB() && "Invalid edge index"); + auto HasMethodBB = OldDest == DMBI->getHasMethodBB() ? NewDest : DMBI->getHasMethodBB(); + auto NoMethodBB = OldDest == DMBI->getNoMethodBB() ? NewDest : DMBI->getNoMethodBB(); + B.createDynamicMethodBranch(DMBI->getLoc(), DMBI->getOperand(), + DMBI->getMember(), HasMethodBB, NoMethodBB); + DMBI->eraseFromParent(); + return; + } + + case TermKind::CheckedCastBranchInst: { + auto CBI = dyn_cast(T); + assert(OldDest == CBI->getSuccessBB() || OldDest == CBI->getFailureBB() && "Invalid edge index"); + auto SuccessBB = OldDest == CBI->getSuccessBB() ? NewDest : CBI->getSuccessBB(); + auto FailureBB = OldDest == CBI->getFailureBB() ? NewDest : CBI->getFailureBB(); + B.createCheckedCastBranch(CBI->getLoc(), CBI->isExact(), CBI->getOperand(), + CBI->getCastType(), SuccessBB, FailureBB); + CBI->eraseFromParent(); + return; + } + + case TermKind::CheckedCastAddrBranchInst: { + auto CBI = dyn_cast(T); + assert(OldDest == CBI->getSuccessBB() || OldDest == CBI->getFailureBB() && "Invalid edge index"); + auto SuccessBB = OldDest == CBI->getSuccessBB() ? NewDest : CBI->getSuccessBB(); + auto FailureBB = OldDest == CBI->getFailureBB() ? NewDest : CBI->getFailureBB(); + B.createCheckedCastAddrBranch(CBI->getLoc(), CBI->getConsumptionKind(), + CBI->getSrc(), CBI->getSourceType(), + CBI->getDest(), CBI->getTargetType(), + SuccessBB, FailureBB); + CBI->eraseFromParent(); + return; + } + + case TermKind::ReturnInst: + case TermKind::ThrowInst: + case TermKind::TryApplyInst: + case TermKind::UnreachableInst: + llvm_unreachable("Branch target cannot be replaced for this terminator instruction!"); + } + llvm_unreachable("Not yet implemented!"); +} + +/// \brief Check if the edge from the terminator is critical. +bool swift::isCriticalEdge(TermInst *T, unsigned EdgeIdx) { + assert(T->getSuccessors().size() > EdgeIdx && "Not enough successors"); + + auto SrcSuccs = T->getSuccessors(); + if (SrcSuccs.size() <= 1) + return false; + + SILBasicBlock *DestBB = SrcSuccs[EdgeIdx]; + assert(!DestBB->pred_empty() && "There should be a predecessor"); + if (DestBB->getSinglePredecessor()) + return false; + + return true; +} + +template +SILBasicBlock *getNthEdgeBlock(SwitchInstTy *S, unsigned EdgeIdx) { + if (S->getNumCases() == EdgeIdx) + return S->getDefaultBB(); + return S->getCase(EdgeIdx).second; +} + +static void getEdgeArgs(TermInst *T, unsigned EdgeIdx, SILBasicBlock *NewEdgeBB, + SmallVectorImpl &Args) { + if (auto Br = dyn_cast(T)) { + for (auto V : Br->getArgs()) + Args.push_back(V); + return; + } + + if (auto CondBr = dyn_cast(T)) { + assert(EdgeIdx < 2); + auto OpdArgs = EdgeIdx ? CondBr->getFalseArgs() : CondBr->getTrueArgs(); + for (auto V: OpdArgs) + Args.push_back(V); + return; + } + + if (auto SEI = dyn_cast(T)) { + auto *SuccBB = getNthEdgeBlock(SEI, EdgeIdx); + assert(SuccBB->getNumBBArg() == 0 && "Can't take an argument"); + (void) SuccBB; + return; + } + + // A switch_enum can implicitly pass the enum payload. We need to look at the + // destination block to figure this out. + if (auto SEI = dyn_cast(T)) { + auto *SuccBB = getNthEdgeBlock(SEI, EdgeIdx); + assert(SuccBB->getNumBBArg() < 2 && "Can take at most one argument"); + if (!SuccBB->getNumBBArg()) + return; + Args.push_back( + SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); + return; + } + + // A dynamic_method_br passes the function to the first basic block. + if (auto DMBI = dyn_cast(T)) { + auto *SuccBB = + (EdgeIdx == 0) ? DMBI->getHasMethodBB() : DMBI->getNoMethodBB(); + if (!SuccBB->getNumBBArg()) + return; + Args.push_back( + SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); + return; + } + + /// A checked_cast_br passes the result of the cast to the first basic block. + if (auto CBI = dyn_cast(T)) { + auto SuccBB = EdgeIdx == 0 ? CBI->getSuccessBB() : CBI->getFailureBB(); + if (!SuccBB->getNumBBArg()) + return; + Args.push_back( + SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); + return; + } + if (auto CBI = dyn_cast(T)) { + auto SuccBB = EdgeIdx == 0 ? CBI->getSuccessBB() : CBI->getFailureBB(); + if (!SuccBB->getNumBBArg()) + return; + Args.push_back( + SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); + return; + } + + if (auto *TAI = dyn_cast(T)) { + auto *SuccBB = EdgeIdx == 0 ? TAI->getNormalBB() : TAI->getErrorBB(); + if (!SuccBB->getNumBBArg()) + return; + Args.push_back( + SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); + return; + } + + // For now this utility is only used to split critical edges involving + // cond_br. + llvm_unreachable("Not yet implemented"); +} + +/// Splits the basic block at the iterator with an unconditional branch and +/// updates the dominator tree and loop info. +SILBasicBlock *swift::splitBasicBlockAndBranch(SILBuilder &B, + SILInstruction *SplitBeforeInst, + DominanceInfo *DT, + SILLoopInfo *LI) { + auto *OrigBB = SplitBeforeInst->getParent(); + auto *NewBB = OrigBB->splitBasicBlock(SplitBeforeInst->getIterator()); + B.setInsertionPoint(OrigBB); + B.createBranch(SplitBeforeInst->getLoc(), NewBB); + + // Update the dominator tree. + if (DT) { + auto OrigBBDTNode = DT->getNode(OrigBB); + if (OrigBBDTNode) { + // Change the immediate dominators of the children of the block we + // splitted to the splitted block. + SmallVector Adoptees(OrigBBDTNode->begin(), + OrigBBDTNode->end()); + + auto NewBBDTNode = DT->addNewBlock(NewBB, OrigBB); + for (auto *Adoptee : Adoptees) + DT->changeImmediateDominator(Adoptee, NewBBDTNode); + } + } + + // Update loop info. + if (LI) + if (auto *OrigBBLoop = LI->getLoopFor(OrigBB)) { + OrigBBLoop->addBasicBlockToLoop(NewBB, LI->getBase()); + } + + return NewBB; +} + +SILBasicBlock *swift::splitEdge(TermInst *T, unsigned EdgeIdx, + DominanceInfo *DT, SILLoopInfo *LI) { + auto *SrcBB = T->getParent(); + auto *Fn = SrcBB->getParent(); + + SILBasicBlock *DestBB = T->getSuccessors()[EdgeIdx]; + + // Create a new basic block in the edge, and insert it after the SrcBB. + auto *EdgeBB = new (Fn->getModule()) SILBasicBlock(Fn, SrcBB); + + SmallVector Args; + getEdgeArgs(T, EdgeIdx, EdgeBB, Args); + + SILBuilder(EdgeBB).createBranch(T->getLoc(), DestBB, Args); + + // Strip the arguments and rewire the branch in the source block. + changeBranchTarget(T, EdgeIdx, EdgeBB, /*PreserveArgs=*/false); + + if (!DT && !LI) + return EdgeBB; + + // Update the dominator tree. + if (DT) { + auto *SrcBBNode = DT->getNode(SrcBB); + + // Unreachable code could result in a null return here. + if (SrcBBNode) { + // The new block is dominated by the SrcBB. + auto *EdgeBBNode = DT->addNewBlock(EdgeBB, SrcBB); + + // Are all predecessors of DestBB dominated by DestBB? + auto *DestBBNode = DT->getNode(DestBB); + bool OldSrcBBDominatesAllPreds = std::all_of( + DestBB->pred_begin(), DestBB->pred_end(), [=](SILBasicBlock *B) { + if (B == EdgeBB) + return true; + auto *PredNode = DT->getNode(B); + if (!PredNode) + return true; + if (DT->dominates(DestBBNode, PredNode)) + return true; + return false; + }); + + // If so, the new bb dominates DestBB now. + if (OldSrcBBDominatesAllPreds) + DT->changeImmediateDominator(DestBBNode, EdgeBBNode); + } + } + + if (!LI) + return EdgeBB; + + // Update loop info. Both blocks must be in a loop otherwise the split block + // is outside the loop. + SILLoop *SrcBBLoop = LI->getLoopFor(SrcBB); + if (!SrcBBLoop) + return EdgeBB; + SILLoop *DstBBLoop = LI->getLoopFor(DestBB); + if (!DstBBLoop) + return EdgeBB; + + // Same loop. + if (DstBBLoop == SrcBBLoop) { + DstBBLoop->addBasicBlockToLoop(EdgeBB, LI->getBase()); + return EdgeBB; + } + + // Edge from inner to outer loop. + if (DstBBLoop->contains(SrcBBLoop)) { + DstBBLoop->addBasicBlockToLoop(EdgeBB, LI->getBase()); + return EdgeBB; + } + + // Edge from outer to inner loop. + if (SrcBBLoop->contains(DstBBLoop)) { + SrcBBLoop->addBasicBlockToLoop(EdgeBB, LI->getBase()); + return EdgeBB; + } + + // Neither loop contains the other. The destination must be the header of its + // loop. Otherwise, we would be creating irreducible control flow. + assert(DstBBLoop->getHeader() == DestBB && + "Creating irreducible control flow?"); + + // Add to outer loop if there is one. + if (auto *Parent = DstBBLoop->getParentLoop()) + Parent->addBasicBlockToLoop(EdgeBB, LI->getBase()); + + return EdgeBB; +} + +/// Split every edge between two basic blocks. +void swift::splitEdgesFromTo(SILBasicBlock *From, SILBasicBlock *To, + DominanceInfo *DT, SILLoopInfo *LI) { + for (unsigned EdgeIndex = 0, E = From->getSuccessors().size(); EdgeIndex != E; + ++EdgeIndex) { + SILBasicBlock *SuccBB = From->getSuccessors()[EdgeIndex]; + if (SuccBB != To) + continue; + splitEdge(From->getTerminator(), EdgeIndex, DT, LI); + } +} + +/// Splits the n-th critical edge from the terminator and updates dominance and +/// loop info if set. +/// Returns the newly created basic block on success or nullptr otherwise (if +/// the edge was not critical. +SILBasicBlock *swift::splitCriticalEdge(TermInst *T, unsigned EdgeIdx, + DominanceInfo *DT, SILLoopInfo *LI) { + if (!isCriticalEdge(T, EdgeIdx)) + return nullptr; + + return splitEdge(T, EdgeIdx, DT, LI); +} + +/// Split all critical edges in the function updating the dominator tree and +/// loop information (if they are not set to null). +bool swift::splitAllCriticalEdges(SILFunction &F, bool OnlyNonCondBr, + DominanceInfo *DT, SILLoopInfo *LI) { + bool Changed = false; + + std::vector Blocks; + Blocks.reserve(F.size()); + + for (auto &It : F) + Blocks.push_back(&It); + + for (auto It : Blocks) { + // Only split critical edges for terminators that don't support block + // arguments. + if (OnlyNonCondBr && isa(It->getTerminator())) + continue; + + if (isa(It->getTerminator())) + continue; + + for (unsigned Idx = 0, e = It->getSuccessors().size(); Idx != e; ++Idx) + Changed |= + (splitCriticalEdge(It->getTerminator(), Idx, DT, LI) != nullptr); + } + return Changed; +} + +/// Merge the basic block with its successor if possible. If dominance +/// information or loop info is non null update it. Return true if block was +/// merged. +bool swift::mergeBasicBlockWithSuccessor(SILBasicBlock *BB, DominanceInfo *DT, + SILLoopInfo *LI) { + auto *Branch = dyn_cast(BB->getTerminator()); + if (!Branch) + return false; + + auto *SuccBB = Branch->getDestBB(); + if (BB == SuccBB || !SuccBB->getSinglePredecessor()) + return false; + + // If there are any BB arguments in the destination, replace them with the + // branch operands, since they must dominate the dest block. + for (unsigned i = 0, e = Branch->getArgs().size(); i != e; ++i) + SILValue(SuccBB->getBBArg(i)).replaceAllUsesWith(Branch->getArg(i)); + + Branch->eraseFromParent(); + + // Move the instruction from the successor block to the current block. + BB->spliceAtEnd(SuccBB); + + if (DT) + if (auto *SuccBBNode = DT->getNode(SuccBB)) { + // Change the immediate dominator for children of the successor to be the + // current block. + auto *BBNode = DT->getNode(BB); + SmallVector Children(SuccBBNode->begin(), + SuccBBNode->end()); + for (auto *ChildNode : *SuccBBNode) + DT->changeImmediateDominator(ChildNode, BBNode); + + DT->eraseNode(SuccBB); + } + + if (LI) + LI->removeBlock(SuccBB); + + SuccBB->eraseFromParent(); + + return true; +} + +/// Splits the critical edges between from and to. This code assumes there is +/// only one edge between the two basic blocks. +SILBasicBlock *swift::splitIfCriticalEdge(SILBasicBlock *From, + SILBasicBlock *To, + DominanceInfo *DT, + SILLoopInfo *LI) { + auto *T = From->getTerminator(); + for (unsigned i = 0, e = T->getSuccessors().size(); i != e; ++i) { + if (T->getSuccessors()[i] == To) + return splitCriticalEdge(T, i, DT, LI); + } + llvm_unreachable("Destination block not found"); +} diff --git a/lib/SILOptimizer/Utils/CMakeLists.txt b/lib/SILOptimizer/Utils/CMakeLists.txt new file mode 100644 index 0000000000000..d927cd4d50a58 --- /dev/null +++ b/lib/SILOptimizer/Utils/CMakeLists.txt @@ -0,0 +1,13 @@ +set(UTILS_SOURCES + Utils/CFG.cpp + Utils/Local.cpp + Utils/SILInliner.cpp + Utils/SILSSAUpdater.cpp + Utils/ConstantFolding.cpp + Utils/GenericCloner.cpp + Utils/Generics.cpp + Utils/Devirtualize.cpp + Utils/CheckedCastBrJumpThreading.cpp + Utils/LoopUtils.cpp + PARENT_SCOPE) + diff --git a/lib/SILPasses/Utils/CheckedCastBrJumpThreading.cpp b/lib/SILOptimizer/Utils/CheckedCastBrJumpThreading.cpp similarity index 98% rename from lib/SILPasses/Utils/CheckedCastBrJumpThreading.cpp rename to lib/SILOptimizer/Utils/CheckedCastBrJumpThreading.cpp index 5f67084bbe452..33a67007317e3 100644 --- a/lib/SILPasses/Utils/CheckedCastBrJumpThreading.cpp +++ b/lib/SILOptimizer/Utils/CheckedCastBrJumpThreading.cpp @@ -2,10 +2,10 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "swift/SIL/SILInstruction.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/SILInliner.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Utils/SILInliner.h" using namespace swift; @@ -147,7 +147,7 @@ static unsigned basicBlockInlineCost(SILBasicBlock *BB, unsigned Cutoff) { return Cost; } -/// We can not duplicate blocks with AllocStack instructions (they need to be +/// We cannot duplicate blocks with AllocStack instructions (they need to be /// FIFO). Other instructions can be duplicated. static bool canDuplicateBlock(SILBasicBlock *BB) { for (auto &I : *BB) { @@ -654,7 +654,7 @@ bool CheckedCastBrJumpThreading::trySimplify(TermInst *Term) { if (!areEquivalentConditionsAlongPaths()) continue; - // Check if any jump-threding is required and possible. + // Check if any jump-threading is required and possible. if (SuccessPreds.empty() && FailurePreds.empty()) return false; @@ -706,8 +706,8 @@ bool CheckedCastBrJumpThreading::trySimplify(TermInst *Term) { addBlockToSimplifyCFGWorklist(B); } - for (auto &B : BB->getSuccessors()) { - addBlockToSimplifyCFGWorklist(B.getBB()); + for (auto *B : BB->getSuccessorBlocks()) { + addBlockToSimplifyCFGWorklist(B); } // Create a copy of the BB as a landing BB diff --git a/lib/SILPasses/Utils/ConstantFolding.cpp b/lib/SILOptimizer/Utils/ConstantFolding.cpp similarity index 95% rename from lib/SILPasses/Utils/ConstantFolding.cpp rename to lib/SILOptimizer/Utils/ConstantFolding.cpp index 12f113a3d7c30..2ed3f9e869e22 100644 --- a/lib/SILPasses/Utils/ConstantFolding.cpp +++ b/lib/SILOptimizer/Utils/ConstantFolding.cpp @@ -1,8 +1,8 @@ -//===- ConstantFolding.cpp - Utilities for SIL constant folding -*- C++ -*-===// +//===--- ConstantFolding.cpp - Utils for SIL constant folding ---*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/Utils/ConstantFolding.h" +#include "swift/SILOptimizer/Utils/ConstantFolding.h" using namespace swift; diff --git a/lib/SILOptimizer/Utils/Devirtualize.cpp b/lib/SILOptimizer/Utils/Devirtualize.cpp new file mode 100644 index 0000000000000..56be828aead74 --- /dev/null +++ b/lib/SILOptimizer/Utils/Devirtualize.cpp @@ -0,0 +1,845 @@ +//===--- Devirtualize.cpp - Helper for devirtualizing apply -----*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "sil-devirtualize-utility" +#include "swift/SILOptimizer/Analysis/ClassHierarchyAnalysis.h" +#include "swift/SILOptimizer/Utils/Devirtualize.h" +#include "swift/AST/Decl.h" +#include "swift/AST/Types.h" +#include "swift/SIL/SILDeclRef.h" +#include "swift/SIL/SILFunction.h" +#include "swift/SIL/SILInstruction.h" +#include "swift/SIL/SILModule.h" +#include "swift/SIL/SILType.h" +#include "swift/SIL/SILValue.h" +#include "swift/SILOptimizer/Utils/Local.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Casting.h" +using namespace swift; + +STATISTIC(NumClassDevirt, "Number of class_method applies devirtualized"); +STATISTIC(NumWitnessDevirt, "Number of witness_method applies devirtualized"); + +//===----------------------------------------------------------------------===// +// Class Method Optimization +//===----------------------------------------------------------------------===// + +/// Compute all subclasses of a given class. +/// +/// \p CHA class hierarchy analysis +/// \p CD class declaration +/// \p ClassType type of the instance +/// \p M SILModule +/// \p Subs a container to be used for storing the set of subclasses +static void getAllSubclasses(ClassHierarchyAnalysis *CHA, + ClassDecl *CD, + SILType ClassType, + SILModule &M, + ClassHierarchyAnalysis::ClassList &Subs) { + // Collect the direct and indirect subclasses for the class. + // Sort these subclasses in the order they should be tested by the + // speculative devirtualization. Different strategies could be used, + // E.g. breadth-first, depth-first, etc. + // Currently, let's use the breadth-first strategy. + // The exact static type of the instance should be tested first. + auto &DirectSubs = CHA->getDirectSubClasses(CD); + auto &IndirectSubs = CHA->getIndirectSubClasses(CD); + + Subs.append(DirectSubs.begin(), DirectSubs.end()); + //SmallVector Subs(DirectSubs); + Subs.append(IndirectSubs.begin(), IndirectSubs.end()); + + if (isa(ClassType.getSwiftRValueType())) { + // Filter out any subclassses that do not inherit from this + // specific bound class. + auto RemovedIt = std::remove_if(Subs.begin(), Subs.end(), + [&ClassType, &M](ClassDecl *Sub){ + auto SubCanTy = Sub->getDeclaredType()->getCanonicalType(); + // Unbound generic type can override a method from + // a bound generic class, but this unbound generic + // class is not considered to be a subclass of a + // bound generic class in a general case. + if (isa(SubCanTy)) + return false; + // Handle the usual case here: the class in question + // should be a real subclass of a bound generic class. + return !ClassType.isSuperclassOf( + SILType::getPrimitiveObjectType(SubCanTy)); + }); + Subs.erase(RemovedIt, Subs.end()); + } +} + +/// \brief Returns true, if a method implementation corresponding to +/// the class_method applied to an instance of the class CD is +/// effectively final, i.e. it is statically known to be not overridden +/// by any subclasses of the class CD. +/// +/// \p AI invocation instruction +/// \p ClassType type of the instance +/// \p CD static class of the instance whose method is being invoked +/// \p CHA class hierarchy analysis +bool isEffectivelyFinalMethod(FullApplySite AI, + SILType ClassType, + ClassDecl *CD, + ClassHierarchyAnalysis *CHA) { + if (CD && CD->isFinal()) + return true; + + const DeclContext *DC = AI.getModule().getAssociatedContext(); + + // Without an associated context we cannot perform any + // access-based optimizations. + if (!DC) + return false; + + auto *CMI = cast(AI.getCallee()); + + if (!calleesAreStaticallyKnowable(AI.getModule(), CMI->getMember())) + return false; + + auto *Method = CMI->getMember().getAbstractFunctionDecl(); + assert(Method && "Expected abstract function decl!"); + assert(!Method->isFinal() && "Unexpected indirect call to final method!"); + + // If this method is not overridden in the module, + // there is no other implementation. + if (!Method->isOverridden()) + return true; + + // Class declaration may be nullptr, e.g. for cases like: + // func foo(c: C) {}, where C is a class, but + // it does not have a class decl. + if (!CD) + return false; + + if (!CHA) + return false; + + // This is a private or a module internal class. + // + // We can analyze the class hierarchy rooted at it and + // eventually devirtualize a method call more efficiently. + + ClassHierarchyAnalysis::ClassList Subs; + getAllSubclasses(CHA, CD, ClassType, AI.getModule(), Subs); + + // This is the implementation of the method to be used + // if the exact class of the instance would be CD. + auto *ImplMethod = CD->findImplementingMethod(Method); + + // First, analyze all direct subclasses. + for (auto S : Subs) { + // Check if the subclass overrides a method and provides + // a different implementation. + auto *ImplFD = S->findImplementingMethod(Method); + if (ImplFD != ImplMethod) + return false; + } + + return true; +} + +/// Check if a given class is final in terms of a current +/// compilation, i.e.: +/// - it is really final +/// - or it is private and has not sub-classes +/// - or it is an internal class without sub-classes and +/// it is a whole-module compilation. +static bool isKnownFinalClass(ClassDecl *CD, SILModule &M, + ClassHierarchyAnalysis *CHA) { + const DeclContext *DC = M.getAssociatedContext(); + + if (CD->isFinal()) + return true; + + // Without an associated context we cannot perform any + // access-based optimizations. + if (!DC) + return false; + + // Only handle classes defined within the SILModule's associated context. + if (!CD->isChildContextOf(DC)) + return false; + + if (!CD->hasAccessibility()) + return false; + + // Only consider 'private' members, unless we are in whole-module compilation. + switch (CD->getEffectiveAccess()) { + case Accessibility::Public: + return false; + case Accessibility::Internal: + if (!M.isWholeModule()) + return false; + break; + case Accessibility::Private: + break; + } + + // Take the ClassHierarchyAnalysis into account. + // If a given class has no subclasses and + // - private + // - or internal and it is a WMO compilation + // then this class can be considered final for the purpose + // of devirtualization. + if (CHA) { + if (!CHA->hasKnownDirectSubclasses(CD)) { + switch (CD->getEffectiveAccess()) { + case Accessibility::Public: + return false; + case Accessibility::Internal: + if (!M.isWholeModule()) + return false; + break; + case Accessibility::Private: + break; + } + + return true; + } + } + + return false; +} + + +// Attempt to get the instance for S, whose static type is the same as +// its exact dynamic type, returning a null SILValue() if we cannot find it. +// The information that a static type is the same as the exact dynamic, +// can be derived e.g.: +// - from a constructor or +// - from a successful outcome of a checked_cast_br [exact] instruction. +static SILValue getInstanceWithExactDynamicType(SILValue S, SILModule &M, + ClassHierarchyAnalysis *CHA) { + + while (S) { + S = S.stripCasts(); + if (isa(S) || isa(S)) + return S; + + auto *Arg = dyn_cast(S); + if (!Arg) + break; + + auto *SinglePred = Arg->getParent()->getSinglePredecessor(); + if (!SinglePred) { + if (!Arg->isFunctionArg()) + break; + auto *CD = Arg->getType().getClassOrBoundGenericClass(); + // Check if this class is effectively final. + if (!CD || !isKnownFinalClass(CD, M, CHA)) + break; + return Arg; + } + + // Traverse the chain of predecessors. + if (isa(SinglePred->getTerminator()) || + isa(SinglePred->getTerminator())) { + S = Arg->getIncomingValue(SinglePred); + continue; + } + + // If it is a BB argument received on a success branch + // of a checked_cast_br, then we know its exact type. + auto *CCBI = dyn_cast(SinglePred->getTerminator()); + if (!CCBI) + break; + if (!CCBI->isExact() || CCBI->getSuccessBB() != Arg->getParent()) + break; + return S; + } + + return SILValue(); +} + +/// Return bound generic type for the unbound type Superclass, +/// which is a superclass of a bound generic type BoundDerived +/// (Base may be also the same as BoundDerived or may be +/// non-generic at all). +static CanType bindSuperclass(CanType Superclass, + SILType BoundDerived) { + assert(BoundDerived && "Expected non-null type!"); + + SILType BoundSuperclass = BoundDerived; + + do { + // Get declaration of the superclass. + auto *Decl = BoundSuperclass.getNominalOrBoundGenericNominal(); + // Obtain the unbound variant of the current superclass + CanType UnboundSuperclass = Decl->getDeclaredType()->getCanonicalType(); + // Check if we found a superclass we are looking for. + if (UnboundSuperclass == Superclass) + return BoundSuperclass.getSwiftRValueType(); + + // Get the superclass of current one + BoundSuperclass = BoundSuperclass.getSuperclass(nullptr); + } while (BoundSuperclass); + + llvm_unreachable("Expected to find a bound generic superclass!"); +} + +// Returns true if any generic types parameters of the class are +// unbound. +bool swift::isNominalTypeWithUnboundGenericParameters(SILType Ty, SILModule &M) { + auto *ND = Ty.getNominalOrBoundGenericNominal(); + if (ND && ND->getGenericSignature()) { + auto InstanceTypeSubsts = + Ty.gatherAllSubstitutions(M); + + if (!InstanceTypeSubsts.empty()) { + if (hasUnboundGenericTypes(InstanceTypeSubsts)) + return true; + } + } + + if (Ty.hasArchetype()) + return true; + + return false; +} + +// Start with the substitutions from the apply. +// Try to propagate them to find out the real substitutions required +// to invoke the method. +static ArrayRef +getSubstitutionsForCallee(SILModule &M, CanSILFunctionType GenCalleeType, + SILType ClassInstanceType, FullApplySite AI) { + // *NOTE*: + // Apply instruction substitutions are for the Member from a protocol or + // class B, where this member was first defined, before it got overridden by + // derived classes. + // + // The implementation F (the implementing method) which was found may have + // a different set of generic parameters, e.g. because it is implemented by a + // class D1 derived from B. + // + // ClassInstanceType may have a type different from both the type B + // the Member belongs to and from the ClassInstanceType, e.g. if + // ClassInstance is of a class D2, which is derived from D1, but does not + // override the Member. + // + // As a result, substitutions provided by AI are for Member, whereas + // substitutions in ClassInstanceType are for D2. And substitutions for D1 + // are not available directly in a general case. Therefore, they have to + // be computed. + // + // What we know for sure: + // B is a superclass of D1 + // D1 is a superclass of D2. + // D1 can be the same as D2. D1 can be the same as B. + // + // So, substitutions from AI are for class B. + // Substitutions for class D1 by means of bindSuperclass(), which starts + // with a bound type ClassInstanceType and checks its superclasses until it + // finds a bound superclass matching D1 and returns its substitutions. + + // Class F belongs to. + CanType FSelfClass = GenCalleeType->getSelfParameter().getType(); + + SILType FSelfSubstType; + auto *Module = M.getSwiftModule(); + + ArrayRef ClassSubs; + + if (GenCalleeType->isPolymorphic()) { + // Declaration of the class F belongs to. + if (auto *FSelfTypeDecl = FSelfClass.getNominalOrBoundGenericNominal()) { + // Get the unbound generic type F belongs to. + CanType FSelfGenericType = + FSelfTypeDecl->getDeclaredType()->getCanonicalType(); + + assert((isa(ClassInstanceType.getSwiftRValueType()) || + isa(ClassInstanceType.getSwiftRValueType())) && + "Self type should be either a bound generic type" + "or a non-generic type"); + + assert((isa(FSelfGenericType) || + isa(FSelfGenericType)) && + "Method implementation self type should be generic"); + + if (isa(ClassInstanceType.getSwiftRValueType())) { + auto BoundBaseType = bindSuperclass(FSelfGenericType, + ClassInstanceType); + if (auto BoundTy = BoundBaseType->getAs()) { + ClassSubs = BoundTy->getSubstitutions(Module, nullptr); + } + } + } + } else { + // If the callee is not polymorphic, no substitutions are required. + return {}; + } + + if (ClassSubs.empty()) + return AI.getSubstitutions(); + + auto AISubs = AI.getSubstitutions(); + + CanSILFunctionType AIGenCalleeType = + AI.getCallee().getType().castTo(); + + CanType AISelfClass = AIGenCalleeType->getSelfParameter().getType(); + + unsigned NextMethodParamIdx = 0; + unsigned NumMethodParams = 0; + if (AIGenCalleeType->isPolymorphic()) { + NextMethodParamIdx = 0; + // Generic parameters of the method start after generic parameters + // of the instance class. + if (auto AISelfClassSig = + AISelfClass.getClassBound()->getGenericSignature()) { + NextMethodParamIdx = AISelfClassSig->getGenericParams().size(); + } + NumMethodParams = AISubs.size() - NextMethodParamIdx; + } + + unsigned NumSubs = ClassSubs.size() + NumMethodParams; + + if (ClassSubs.size() == NumSubs) + return ClassSubs; + + // Mix class subs with method specific subs from the AI substitutions. + + // Assumptions: AI substitutions contain first the substitutions for + // a class of the method being invoked and then the substitutions + // for a method being invoked. + auto Subs = M.getASTContext().Allocate(NumSubs); + + unsigned i = 0; + for (auto &S : ClassSubs) { + Subs[i++] = S; + } + + for (; i < NumSubs; ++i, ++NextMethodParamIdx) { + Subs[i] = AISubs[NextMethodParamIdx]; + } + + return Subs; +} + +static SILFunction *getTargetClassMethod(SILModule &M, + SILType ClassOrMetatypeType, + SILDeclRef Member) { + if (ClassOrMetatypeType.is()) + ClassOrMetatypeType = ClassOrMetatypeType.getMetatypeInstanceType(M); + + auto *CD = ClassOrMetatypeType.getClassOrBoundGenericClass(); + return M.lookUpFunctionInVTable(CD, Member); +} + + +/// \brief Check if it is possible to devirtualize an Apply instruction +/// and a class member obtained using the class_method instruction into +/// a direct call to a specific member of a specific class. +/// +/// \p AI is the apply to devirtualize. +/// \p ClassOrMetatypeType is the class type or metatype type we are +/// devirtualizing for. +/// return true if it is possible to devirtualize, false - otherwise. +bool swift::canDevirtualizeClassMethod(FullApplySite AI, + SILType ClassOrMetatypeType) { + DEBUG(llvm::dbgs() << " Trying to devirtualize : " << *AI.getInstruction()); + + SILModule &Mod = AI.getModule(); + + // First attempt to lookup the origin for our class method. The origin should + // either be a metatype or an alloc_ref. + DEBUG(llvm::dbgs() << " Origin Type: " << ClassOrMetatypeType); + + auto *MI = cast(AI.getCallee()); + + // Find the implementation of the member which should be invoked. + auto *F = getTargetClassMethod(Mod, ClassOrMetatypeType, MI->getMember()); + + // If we do not find any such function, we have no function to devirtualize + // to... so bail. + if (!F) { + DEBUG(llvm::dbgs() << " FAIL: Could not find matching VTable or " + "vtable method for this class.\n"); + return false; + } + + if (AI.getFunction()->isFragile()) { + // function_ref inside fragile function cannot reference a private or + // hidden symbol. + if (!(F->isFragile() || isValidLinkageForFragileRef(F->getLinkage()) || + F->isExternalDeclaration())) + return false; + } + + CanSILFunctionType GenCalleeType = F->getLoweredFunctionType(); + + auto Subs = getSubstitutionsForCallee(Mod, GenCalleeType, + ClassOrMetatypeType, AI); + + // For polymorphic functions, bail if the number of substitutions is + // not the same as the number of expected generic parameters. + if (GenCalleeType->isPolymorphic()) { + auto GenericSig = GenCalleeType->getGenericSignature(); + // Get the number of expected generic parameters, which + // is a sum of the number of explicit generic parameters + // and the number of their recursive member types exposed + // through protocol requirements. + auto DepTypes = GenericSig->getAllDependentTypes(); + unsigned ExpectedGenParamsNum = 0; + + for (auto DT: DepTypes) { + (void)DT; + ExpectedGenParamsNum++; + } + + if (ExpectedGenParamsNum != Subs.size()) + return false; + } + + // Check if the optimizer knows how to cast the return type. + CanSILFunctionType SubstCalleeType = GenCalleeType; + if (GenCalleeType->isPolymorphic()) + SubstCalleeType = + GenCalleeType->substGenericArgs(Mod, Mod.getSwiftModule(), Subs); + + // If we have a direct return type, make sure we use the subst callee return + // type. If we have an indirect return type, AI's return type of the empty + // tuple should be ok. + SILType ReturnType = AI.getType(); + if (!SubstCalleeType->hasIndirectResult()) { + ReturnType = SubstCalleeType->getSILResult(); + } + + if (!canCastValueToABICompatibleType(Mod, ReturnType, AI.getType())) + return false; + + return true; +} + +/// \brief Devirtualize an apply of a class method. +/// +/// \p AI is the apply to devirtualize. +/// \p ClassOrMetatype is a class value or metatype value that is the +/// self argument of the apply we will devirtualize. +/// return the result value of the new ApplyInst if created one or null. +DevirtualizationResult swift::devirtualizeClassMethod(FullApplySite AI, + SILValue ClassOrMetatype) { + DEBUG(llvm::dbgs() << " Trying to devirtualize : " << *AI.getInstruction()); + + SILModule &Mod = AI.getModule(); + auto *MI = cast(AI.getCallee()); + auto ClassOrMetatypeType = ClassOrMetatype.getType(); + auto *F = getTargetClassMethod(Mod, ClassOrMetatypeType, MI->getMember()); + + CanSILFunctionType GenCalleeType = F->getLoweredFunctionType(); + + auto Subs = getSubstitutionsForCallee(Mod, GenCalleeType, + ClassOrMetatypeType, AI); + CanSILFunctionType SubstCalleeType = GenCalleeType; + if (GenCalleeType->isPolymorphic()) + SubstCalleeType = GenCalleeType->substGenericArgs(Mod, Mod.getSwiftModule(), Subs); + + SILBuilderWithScope B(AI.getInstruction()); + FunctionRefInst *FRI = B.createFunctionRef(AI.getLoc(), F); + + // Create the argument list for the new apply, casting when needed + // in order to handle covariant indirect return types and + // contravariant argument types. + llvm::SmallVector NewArgs; + auto Args = AI.getArguments(); + auto ParamTypes = SubstCalleeType->getParameterSILTypes(); + + for (unsigned i = 0, e = Args.size() - 1; i != e; ++i) + NewArgs.push_back(castValueToABICompatibleType(&B, AI.getLoc(), Args[i], + Args[i].getType(), + ParamTypes[i]).getValue()); + + // Add the self argument, upcasting if required because we're + // calling a base class's method. + auto SelfParamTy = SubstCalleeType->getSelfParameter().getSILType(); + NewArgs.push_back(castValueToABICompatibleType(&B, AI.getLoc(), + ClassOrMetatype, + ClassOrMetatypeType, + SelfParamTy).getValue()); + + // If we have a direct return type, make sure we use the subst callee return + // type. If we have an indirect return type, AI's return type of the empty + // tuple should be ok. + SILType ResultTy = AI.getType(); + if (!SubstCalleeType->hasIndirectResult()) { + ResultTy = SubstCalleeType->getSILResult(); + } + + SILType SubstCalleeSILType = + SILType::getPrimitiveObjectType(SubstCalleeType); + FullApplySite NewAI; + + SILBasicBlock *ResultBB = nullptr; + SILBasicBlock *NormalBB = nullptr; + SILValue ResultValue; + bool ResultCastRequired = false; + SmallVector OriginalResultUses; + + if (!isa(AI)) { + NewAI = B.createApply(AI.getLoc(), FRI, SubstCalleeSILType, ResultTy, + Subs, NewArgs, cast(AI)->isNonThrowing()); + ResultValue = SILValue(NewAI.getInstruction(), 0); + } else { + auto *TAI = cast(AI); + // Create new normal and error BBs only if: + // - re-using a BB would create a critical edge + // - or, the result of the new apply would be of different + // type than the argument of the original normal BB. + if (TAI->getNormalBB()->getSinglePredecessor()) + ResultBB = TAI->getNormalBB(); + else { + ResultBB = B.getFunction().createBasicBlock(); + ResultBB->createBBArg(ResultTy); + } + + NormalBB = TAI->getNormalBB(); + + SILBasicBlock *ErrorBB = nullptr; + if (TAI->getErrorBB()->getSinglePredecessor()) + ErrorBB = TAI->getErrorBB(); + else { + ErrorBB = B.getFunction().createBasicBlock(); + ErrorBB->createBBArg(TAI->getErrorBB()->getBBArg(0)->getType()); + } + + NewAI = B.createTryApply(AI.getLoc(), FRI, SubstCalleeSILType, + Subs, NewArgs, + ResultBB, ErrorBB); + if (ErrorBB != TAI->getErrorBB()) { + B.setInsertionPoint(ErrorBB); + B.createBranch(TAI->getLoc(), TAI->getErrorBB(), + {ErrorBB->getBBArg(0)}); + } + + // Does the result value need to be casted? + ResultCastRequired = ResultTy != NormalBB->getBBArg(0)->getType(); + + if (ResultBB != NormalBB) + B.setInsertionPoint(ResultBB); + else if (ResultCastRequired) { + B.setInsertionPoint(NormalBB->begin()); + // Collect all uses, before casting. + for (auto *Use : NormalBB->getBBArg(0)->getUses()) { + OriginalResultUses.push_back(Use); + } + NormalBB->getBBArg(0)->replaceAllUsesWith(SILUndef::get(AI.getType(), Mod)); + NormalBB->replaceBBArg(0, ResultTy, nullptr); + } + + // The result value is passed as a parameter to the normal block. + ResultValue = ResultBB->getBBArg(0); + } + + // Check if any casting is required for the return value. + ResultValue = castValueToABICompatibleType(&B, NewAI.getLoc(), ResultValue, + ResultTy, AI.getType()).getValue(); + + DEBUG(llvm::dbgs() << " SUCCESS: " << F->getName() << "\n"); + NumClassDevirt++; + + if (NormalBB) { + if (NormalBB != ResultBB) { + // If artificial normal BB was introduced, branch + // to the original normal BB. + B.createBranch(NewAI.getLoc(), NormalBB, { ResultValue }); + } else if (ResultCastRequired) { + // Update all original uses by the new value. + for(auto *Use: OriginalResultUses) { + Use->set(ResultValue); + } + } + return std::make_pair(NewAI.getInstruction(), NewAI); + } + + // We need to return a pair of values here: + // - the first one is the actual result of the devirtualized call, possibly + // casted into an appropriate type. This SILValue may be a BB arg, if it + // was a cast between optional types. + // - the second one is the new apply site. + return std::make_pair(ResultValue.getDef(), NewAI); +} + +DevirtualizationResult swift::tryDevirtualizeClassMethod(FullApplySite AI, + SILValue ClassInstance) { + if (!canDevirtualizeClassMethod(AI, ClassInstance.getType())) + return std::make_pair(nullptr, FullApplySite()); + return devirtualizeClassMethod(AI, ClassInstance); +} + + +//===----------------------------------------------------------------------===// +// Witness Method Optimization +//===----------------------------------------------------------------------===// + +/// Generate a new apply of a function_ref to replace an apply of a +/// witness_method when we've determined the actual function we'll end +/// up calling. +static ApplySite devirtualizeWitnessMethod(ApplySite AI, SILFunction *F, + ArrayRef Subs) { + // We know the witness thunk and the corresponding set of substitutions + // required to invoke the protocol method at this point. + auto &Module = AI.getModule(); + + // Collect all the required substitutions. + // + // The complete set of substitutions may be different, e.g. because the found + // witness thunk F may have been created by a specialization pass and have + // additional generic parameters. + SmallVector NewSubstList(Subs.begin(), Subs.end()); + + // Add the non-self-derived substitutions from the original application. + ArrayRef SubstList; + SubstList = AI.getSubstitutionsWithoutSelfSubstitution(); + + for (auto &origSub : SubstList) + if (!origSub.getArchetype()->isSelfDerived()) + NewSubstList.push_back(origSub); + + // Figure out the exact bound type of the function to be called by + // applying all substitutions. + auto CalleeCanType = F->getLoweredFunctionType(); + auto SubstCalleeCanType = CalleeCanType->substGenericArgs( + Module, Module.getSwiftModule(), NewSubstList); + + // Collect arguments from the apply instruction. + auto Arguments = SmallVector(); + + auto ParamTypes = SubstCalleeCanType->getParameterSILTypes(); + + // Iterate over the non self arguments and add them to the + // new argument list, upcasting when required. + SILBuilderWithScope B(AI.getInstruction()); + for (unsigned ArgN = 0, ArgE = AI.getNumArguments(); ArgN != ArgE; ++ArgN) { + SILValue A = AI.getArgument(ArgN); + auto ParamType = ParamTypes[ParamTypes.size() - AI.getNumArguments() + ArgN]; + if (A.getType() != ParamType) + A = B.createUpcast(AI.getLoc(), A, ParamType); + + Arguments.push_back(A); + } + + // Replace old apply instruction by a new apply instruction that invokes + // the witness thunk. + SILBuilderWithScope Builder(AI.getInstruction()); + SILLocation Loc = AI.getLoc(); + FunctionRefInst *FRI = Builder.createFunctionRef(Loc, F); + + auto SubstCalleeSILType = SILType::getPrimitiveObjectType(SubstCalleeCanType); + auto ResultSILType = SubstCalleeCanType->getSILResult(); + ApplySite SAI; + + if (auto *A = dyn_cast(AI)) + SAI = Builder.createApply(Loc, FRI, SubstCalleeSILType, + ResultSILType, NewSubstList, Arguments, + A->isNonThrowing()); + if (auto *TAI = dyn_cast(AI)) + SAI = Builder.createTryApply(Loc, FRI, SubstCalleeSILType, + NewSubstList, Arguments, + TAI->getNormalBB(), TAI->getErrorBB()); + if (auto *PAI = dyn_cast(AI)) + SAI = Builder.createPartialApply(Loc, FRI, SubstCalleeSILType, + NewSubstList, Arguments, PAI->getType()); + + NumWitnessDevirt++; + return SAI; +} + +/// In the cases where we can statically determine the function that +/// we'll call to, replace an apply of a witness_method with an apply +/// of a function_ref, returning the new apply. +DevirtualizationResult swift::tryDevirtualizeWitnessMethod(ApplySite AI) { + SILFunction *F; + ArrayRef Subs; + SILWitnessTable *WT; + + auto *WMI = cast(AI.getCallee()); + + std::tie(F, WT, Subs) = + AI.getModule().lookUpFunctionInWitnessTable(WMI->getConformance(), + WMI->getMember()); + + if (!F) + return std::make_pair(nullptr, FullApplySite()); + + auto Result = devirtualizeWitnessMethod(AI, F, Subs); + return std::make_pair(Result.getInstruction(), Result); +} + +//===----------------------------------------------------------------------===// +// Top Level Driver +//===----------------------------------------------------------------------===// + +/// Attempt to devirtualize the given apply if possible, and return a +/// new instruction in that case, or nullptr otherwise. +DevirtualizationResult +swift::tryDevirtualizeApply(FullApplySite AI, ClassHierarchyAnalysis *CHA) { + DEBUG(llvm::dbgs() << " Trying to devirtualize: " << *AI.getInstruction()); + + // Devirtualize apply instructions that call witness_method instructions: + // + // %8 = witness_method $Optional, #LogicValue.boolValue!getter.1 + // %9 = apply %8(%6#1) : ... + // + if (isa(AI.getCallee())) + return tryDevirtualizeWitnessMethod(AI); + + /// Optimize a class_method and alloc_ref pair into a direct function + /// reference: + /// + /// \code + /// %XX = alloc_ref $Foo + /// %YY = class_method %XX : $Foo, #Foo.get!1 : $@convention(method)... + /// \endcode + /// + /// or + /// + /// %XX = metatype $... + /// %YY = class_method %XX : ... + /// + /// into + /// + /// %YY = function_ref @... + if (auto *CMI = dyn_cast(AI.getCallee())) { + auto &M = AI.getModule(); + auto Instance = CMI->getOperand().stripUpCasts(); + auto ClassType = Instance.getType(); + if (ClassType.is()) + ClassType = ClassType.getMetatypeInstanceType(M); + + auto *CD = ClassType.getClassOrBoundGenericClass(); + + if (isEffectivelyFinalMethod(AI, ClassType, CD, CHA)) + return tryDevirtualizeClassMethod(AI, Instance); + + // Try to check if the exact dynamic type of the instance is statically + // known. + if (auto Instance = getInstanceWithExactDynamicType(CMI->getOperand(), + CMI->getModule(), + CHA)) + return tryDevirtualizeClassMethod(AI, Instance); + } + + if (isa(AI.getCallee())) { + if (AI.hasSelfArgument()) { + return tryDevirtualizeClassMethod(AI, AI.getSelfArgument()); + } + + // It is an invocation of a class method. + // Last operand is the metatype that should be used for dispatching. + return tryDevirtualizeClassMethod(AI, AI.getArguments().back()); + } + + return std::make_pair(nullptr, FullApplySite()); +} diff --git a/lib/SILPasses/Utils/GenericCloner.cpp b/lib/SILOptimizer/Utils/GenericCloner.cpp similarity index 87% rename from lib/SILPasses/Utils/GenericCloner.cpp rename to lib/SILOptimizer/Utils/GenericCloner.cpp index d970f21cf3622..5a42696f5f3a7 100644 --- a/lib/SILPasses/Utils/GenericCloner.cpp +++ b/lib/SILOptimizer/Utils/GenericCloner.cpp @@ -1,8 +1,8 @@ -//===--------- GenericCloner.cpp - Specializes generic functions ---------===// +//===--- GenericCloner.cpp - Specializes generic functions ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -#include "swift/SILPasses/Utils/GenericCloner.h" +#include "swift/SILOptimizer/Utils/GenericCloner.h" #include "swift/AST/Type.h" #include "swift/SIL/SILBasicBlock.h" @@ -18,7 +18,7 @@ #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILValue.h" -#include "swift/SILPasses/Utils/Local.h" +#include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" @@ -43,14 +43,16 @@ SILFunction *GenericCloner::initCloned(SILFunction *Orig, assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned"); // Create a new empty function. - SILFunction *NewF = SILFunction::create( - M, getSpecializedLinkage(Orig, Orig->getLinkage()), NewName, FTy, nullptr, + SILFunction *NewF = M.getOrCreateFunction( + getSpecializedLinkage(Orig, Orig->getLinkage()), NewName, FTy, nullptr, Orig->getLocation(), Orig->isBare(), Orig->isTransparent(), Orig->isFragile(), Orig->isThunk(), Orig->getClassVisibility(), Orig->getInlineStrategy(), Orig->getEffectsKind(), Orig, Orig->getDebugScope(), Orig->getDeclContext()); NewF->setDeclCtx(Orig->getDeclContext()); - NewF->setSemanticsAttr(Orig->getSemanticsAttr()); + for (auto &Attr : Orig->getSemanticsAttrs()) { + NewF->addSemanticsAttr(Attr); + } return NewF; } diff --git a/lib/SILPasses/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp similarity index 92% rename from lib/SILPasses/Utils/Generics.cpp rename to lib/SILOptimizer/Utils/Generics.cpp index fe430d7230f27..0f4dcbd805193 100644 --- a/lib/SILPasses/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -1,8 +1,8 @@ -//===- Generics.cpp ---- Utilities for transforming generics ----*- C++ -*-===// +//===--- Generics.cpp ---- Utilities for transforming generics --*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -13,8 +13,8 @@ #define DEBUG_TYPE "generic-specializer" #include "swift/Strings.h" -#include "swift/SILPasses/Utils/Generics.h" -#include "swift/SILPasses/Utils/GenericCloner.h" +#include "swift/SILOptimizer/Utils/Generics.h" +#include "swift/SILOptimizer/Utils/GenericCloner.h" using namespace swift; @@ -53,7 +53,7 @@ ApplySite swift::replaceWithSpecializedFunction(ApplySite AI, /// Try to convert definition into declaration. -static bool convertExtenralDefinitionIntoDeclaration(SILFunction *F) { +static bool convertExternalDefinitionIntoDeclaration(SILFunction *F) { // Bail if it is a declaration already. if (!F->isDefinition()) return false; @@ -156,12 +156,13 @@ static bool cacheSpecialization(SILModule &M, SILFunction *F) { llvm::dbgs() << "Keep specialization: " << DemangledName << " : " << F->getName() << "\n"); // Make it public, so that others can refer to it. - // NOTE: This function may refer to non-public symbols, which may lead - // to problems, if you ever try to inline this function. Therefore, - // these specializations should only be used to refer to them, - // but should never be inlined! - // The general rule could be: Never inline specializations from stdlib! - + // + // NOTE: This function may refer to non-public symbols, which may lead to + // problems, if you ever try to inline this function. Therefore, these + // specializations should only be used to refer to them, but should never + // be inlined! The general rule could be: Never inline specializations + // from stdlib! + // // NOTE: Making these specializations public at this point breaks // some optimizations. Therefore, just mark the function. // DeadFunctionElimination pass will check if the function is marked @@ -206,9 +207,9 @@ SILFunction *swift::getExistingSpecialization(SILModule &M, Specialization->setLinkage(SILLinkage::PublicExternal); // Ignore body for -Onone and -Odebug. assert((Specialization->isExternalDeclaration() || - convertExtenralDefinitionIntoDeclaration(Specialization)) && + convertExternalDefinitionIntoDeclaration(Specialization)) && "Could not remove body of the found specialization"); - if (!convertExtenralDefinitionIntoDeclaration(Specialization)) { + if (!convertExternalDefinitionIntoDeclaration(Specialization)) { DEBUG( llvm::dbgs() << "Could not remove body of specialization: " << FunctionName << '\n'); @@ -263,7 +264,7 @@ ApplySite swift::trySpecializeApplyOfGeneric(ApplySite Apply, // We do not support partial specialization. if (hasUnboundGenericTypes(InterfaceSubs)) { - DEBUG(llvm::dbgs() << " Can not specialize with interface subs.\n"); + DEBUG(llvm::dbgs() << " Cannot specialize with interface subs.\n"); return ApplySite(); } if (hasDynamicSelfTypes(InterfaceSubs)) { @@ -271,13 +272,13 @@ ApplySite swift::trySpecializeApplyOfGeneric(ApplySite Apply, return ApplySite(); } - llvm::SmallString<64> ClonedName; + std::string ClonedName; { - llvm::raw_svector_ostream buffer(ClonedName); ArrayRef Subs = Apply.getSubstitutions(); - Mangle::Mangler M(buffer); - Mangle::GenericSpecializationMangler Mangler(M, F, Subs); + Mangle::Mangler M; + GenericSpecializationMangler Mangler(M, F, Subs); Mangler.mangle(); + ClonedName = M.finalize(); } DEBUG(llvm::dbgs() << " Specialized function " << ClonedName << '\n'); diff --git a/lib/SILPasses/Utils/Local.cpp b/lib/SILOptimizer/Utils/Local.cpp similarity index 97% rename from lib/SILPasses/Utils/Local.cpp rename to lib/SILOptimizer/Utils/Local.cpp index c818a6cbc77be..cad00bc5a2886 100644 --- a/lib/SILPasses/Utils/Local.cpp +++ b/lib/SILOptimizer/Utils/Local.cpp @@ -1,18 +1,18 @@ -//===--- Local.cpp - Functions that perform local SIL transformations. ---===// +//===--- Local.cpp - Functions that perform local SIL transformations. ----===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // -//===---------------------------------------------------------------------===// -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILAnalysis/ARCAnalysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" +//===----------------------------------------------------------------------===// +#include "swift/SILOptimizer/Utils/Local.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/Analysis/ARCAnalysis.h" +#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h" #include "swift/SIL/DynamicCasts.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" @@ -112,7 +112,7 @@ recursivelyDeleteTriviallyDeadInstructions(ArrayRef IA, } // If we have a function ref inst, we need to especially drop its function - // argument so that it gets a proper ref decement. + // argument so that it gets a proper ref decrement. auto *FRI = dyn_cast(I); if (FRI && FRI->getReferencedFunction()) FRI->dropReferencedFunction(); @@ -270,7 +270,7 @@ bool swift::computeMayBindDynamicSelf(SILFunction *F) { } /// Find a new position for an ApplyInst's FuncRef so that it dominates its -/// use. Not that FuncionRefInsts may be shared by multiple ApplyInsts. +/// use. Not that FunctionRefInsts may be shared by multiple ApplyInsts. void swift::placeFuncRef(ApplyInst *AI, DominanceInfo *DT) { FunctionRefInst *FuncRef = cast(AI->getCallee()); SILBasicBlock *DomBB = @@ -341,8 +341,8 @@ SILLinkage swift::getSpecializedLinkage(SILFunction *F, SILLinkage L) { // Treat stdlib_binary_only specially. We don't serialize the body of // stdlib_binary_only functions so we can't mark them as Shared (making // their visibility in the dylib hidden). - return F->hasSemanticsString("stdlib_binary_only") ? SILLinkage::Public - : SILLinkage::Shared; + return F->hasSemanticsAttr("stdlib_binary_only") ? SILLinkage::Public + : SILLinkage::Shared; case SILLinkage::Private: case SILLinkage::PrivateExternal: @@ -684,8 +684,7 @@ bool StringConcatenationOptimizer::extractStringConcatOperands() { if (!Fn) return false; - if (AI->getNumOperands() != 3 || - !Fn->hasSemanticsString("string.concat")) + if (AI->getNumOperands() != 3 || !Fn->hasSemanticsAttr("string.concat")) return false; // Left and right operands of a string concatenation operation. @@ -708,12 +707,9 @@ bool StringConcatenationOptimizer::extractStringConcatOperands() { FRIRightFun->getEffectsKind() >= EffectsKind::ReadWrite) return false; - if (!FRILeftFun->hasDefinedSemantics() || - !FRIRightFun->hasDefinedSemantics()) + if (!FRILeftFun->hasSemanticsAttrs() || !FRIRightFun->hasSemanticsAttrs()) return false; - auto SemanticsLeft = FRILeftFun->getSemanticsString(); - auto SemanticsRight = FRIRightFun->getSemanticsString(); auto AILeftOperandsNum = AILeft->getNumOperands(); auto AIRightOperandsNum = AIRight->getNumOperands(); @@ -721,10 +717,14 @@ bool StringConcatenationOptimizer::extractStringConcatOperands() { // (start: RawPointer, numberOfCodeUnits: Word) // makeUTF8 should have following parameters: // (start: RawPointer, byteSize: Word, isASCII: Int1) - if (!((SemanticsLeft == "string.makeUTF16" && AILeftOperandsNum == 4) || - (SemanticsLeft == "string.makeUTF8" && AILeftOperandsNum == 5) || - (SemanticsRight == "string.makeUTF16" && AIRightOperandsNum == 4) || - (SemanticsRight == "string.makeUTF8" && AIRightOperandsNum == 5))) + if (!((FRILeftFun->hasSemanticsAttr("string.makeUTF16") && + AILeftOperandsNum == 4) || + (FRILeftFun->hasSemanticsAttr("string.makeUTF8") && + AILeftOperandsNum == 5) || + (FRIRightFun->hasSemanticsAttr("string.makeUTF16") && + AIRightOperandsNum == 4) || + (FRIRightFun->hasSemanticsAttr("string.makeUTF8") && + AIRightOperandsNum == 5))) return false; SLILeft = dyn_cast(AILeft->getOperand(1)); @@ -899,7 +899,7 @@ void swift::releasePartialApplyCapturedArg(SILBuilder &Builder, SILLocation Loc, // not need to destroy it here. This is something that is implicit in the // partial_apply design that will be revisited when partial_apply is // redesigned. - if (PInfo.isIndirectInOut()) + if (PInfo.isIndirectMutating()) return; if (isa(Arg)) { @@ -1154,7 +1154,7 @@ static Type getCastFromObjC(SILModule &M, CanType source, CanType target) { } /// Create a call of _forceBridgeFromObjectiveC_bridgeable or -/// _conditionallyBridgeFromObjectiveC_bridgeable which converts an an ObjC +/// _conditionallyBridgeFromObjectiveC_bridgeable which converts an ObjC /// instance into a corresponding Swift type, conforming to /// _ObjectiveCBridgeable. SILInstruction * @@ -1244,7 +1244,7 @@ optimizeBridgedObjCToSwiftCast(SILInstruction *Inst, // Now emit the a cast from the casted ObjC object into a target type. // This is done by means of calling _forceBridgeFromObjectiveC or - // _conditionallyBridgeFromObjectiveC_birdgeable from the Target type. + // _conditionallyBridgeFromObjectiveC_bridgeable from the Target type. // Lookup the required function in the Target type. // Lookup the _ObjectiveCBridgeable protocol. @@ -1297,7 +1297,7 @@ optimizeBridgedObjCToSwiftCast(SILInstruction *Inst, OptionalTy.getAnyOptionalObjectType(OTK); Tmp = Builder.createAllocStack(Loc, SILType::getPrimitiveObjectType(OptionalTy)); - InOutOptionalParam = SILValue(Tmp, 1); + InOutOptionalParam = Tmp; } else { InOutOptionalParam = Dest; } @@ -1921,10 +1921,10 @@ CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) { // Should be in the same BB. if (ASI->getParent() != EMI->getParent()) return nullptr; - // Check if this alloc_stac is is only initialized once by means of + // Check if this alloc_stack is only initialized once by means of // single init_existential_addr. bool isLegal = true; - // init_existental instruction used to initialize this alloc_stack. + // init_existential instruction used to initialize this alloc_stack. InitExistentialAddrInst *FoundIEI = nullptr; for (auto Use: getNonDebugUses(*ASI)) { auto *User = Use->getUser(); @@ -1982,8 +1982,8 @@ CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) { // Should be in the same BB. if (ASRI->getParent() != EMI->getParent()) return nullptr; - // Check if this alloc_stac is is only initialized once by means of - // a single initt_existential_ref. + // Check if this alloc_stack is only initialized once by means of + // a single init_existential_ref. bool isLegal = true; for (auto Use: getNonDebugUses(*ASRI)) { auto *User = Use->getUser(); @@ -2299,9 +2299,9 @@ swift::analyzeStaticInitializer(SILValue V, return false; } -/// Replace load sequence which may contian +/// Replace load sequence which may contain /// a chain of struct_element_addr followed by a load. -/// The sequence is travered inside out, i.e. +/// The sequence is traversed inside out, i.e. /// starting with the innermost struct_element_addr /// Move into utils. void swift::replaceLoadSequence(SILInstruction *I, @@ -2352,6 +2352,9 @@ bool swift::calleesAreStaticallyKnowable(SILModule &M, SILDeclRef Decl) { if (AFD->isDynamic()) return false; + if (!AFD->hasAccessibility()) + return false; + // Only consider 'private' members, unless we are in whole-module compilation. switch (AFD->getEffectiveAccess()) { case Accessibility::Public: diff --git a/lib/SILPasses/Utils/LoopUtils.cpp b/lib/SILOptimizer/Utils/LoopUtils.cpp similarity index 78% rename from lib/SILPasses/Utils/LoopUtils.cpp rename to lib/SILOptimizer/Utils/LoopUtils.cpp index 87b04c6012049..146c6efc5a38b 100644 --- a/lib/SILPasses/Utils/LoopUtils.cpp +++ b/lib/SILOptimizer/Utils/LoopUtils.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,45 +11,79 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-loop-utils" -#include "swift/SILPasses/Utils/LoopUtils.h" +#include "swift/SILOptimizer/Utils/LoopUtils.h" #include "swift/SIL/Dominance.h" #include "swift/SIL/LoopInfo.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILModule.h" -#include "swift/SILPasses/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/CFG.h" #include "llvm/Support/Debug.h" using namespace swift; -static SILBasicBlock *getSingleOutsideLoopPredecessor(SILLoop *L, - SILBasicBlock *BB) { - SmallVector Preds; - for (auto *Pred : BB->getPreds()) - if (!L->contains(Pred)) - Preds.push_back(Pred); - if (Preds.size() != 1) - return nullptr; - return Preds[0]; +static SILBasicBlock *createInitialPreheader(SILBasicBlock *Header) { + auto *Preheader = new (Header->getModule()) + SILBasicBlock(Header->getParent(), &*std::prev(Header->getIterator())); + + // Clone the arguments from header into the pre-header. + llvm::SmallVector Args; + for (auto *HeaderArg : Header->getBBArgs()) { + Args.push_back(Preheader->createBBArg(HeaderArg->getType(), nullptr)); + } + + // Create the branch to the header. + SILBuilder(Preheader) + .createBranch(SILFileLocation(SourceLoc()), Header, Args); + + return Preheader; } -/// \brief Try to create a unique loop preheader. -/// -/// FIXME: We should handle merging multiple loop predecessors. -static SILBasicBlock* insertPreheader(SILLoop *L, DominanceInfo *DT, +/// \brief Create a unique loop preheader. +static SILBasicBlock *insertPreheader(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI) { assert(!L->getLoopPreheader() && "Expect multiple preheaders"); - SILBasicBlock *Header = L->getHeader(); - SILBasicBlock *Preheader = nullptr; - if (auto LoopPred = getSingleOutsideLoopPredecessor(L, Header)) { - if (isa(LoopPred->getTerminator())) { - Preheader = splitIfCriticalEdge(LoopPred, Header, DT, LI); - DEBUG(llvm::dbgs() << "Created preheader for loop: " << *L); - assert(Preheader && "Must have a preheader now"); + + // Before we create the preheader, gather all of the original preds of header. + llvm::SmallVector Preds; + for (auto *Pred : Header->getPreds()) { + if (!L->contains(Pred)) { + Preds.push_back(Pred); + } + } + + // Then create the pre-header and connect it to header. + SILBasicBlock *Preheader = createInitialPreheader(Header); + + // Then change all of the original predecessors to target Preheader instead of + // header. + for (auto *Pred : Preds) { + replaceBranchTarget(Pred->getTerminator(), Header, Preheader, + true /*PreserveArgs*/); + } + + // Update dominance info. + if (DT) { + // Get the dominance node of the header. + auto *HeaderBBDTNode = DT->getNode(Header); + if (HeaderBBDTNode) { + // Make a DTNode for the preheader and make the header's immediate + // dominator, the immediate dominator of the pre-header. + auto *PreheaderDTNode = + DT->addNewBlock(Preheader, HeaderBBDTNode->getIDom()->getBlock()); + // Then change the immediate dominator of the header to be the pre-header. + HeaderBBDTNode->setIDom(PreheaderDTNode); } } + + // Make the pre-header a part of the parent loop of L if L has a parent loop. + if (LI) { + if (auto *PLoop = L->getParentLoop()) + PLoop->addBasicBlockToLoop(Preheader, LI->getBase()); + } + return Preheader; } @@ -197,9 +231,8 @@ static bool canonicalizeLoopExitBlocks(SILLoop *L, DominanceInfo *DT, bool swift::canonicalizeLoop(SILLoop *L, DominanceInfo *DT, SILLoopInfo *LI) { bool ChangedCFG = false; if (!L->getLoopPreheader()) { - if (!insertPreheader(L, DT, LI)) - // Skip further simplification with no preheader. - return ChangedCFG; + insertPreheader(L, DT, LI); + assert(L->getLoopPreheader() && "L should have a pre-header now"); ChangedCFG = true; } diff --git a/lib/SILPasses/Utils/SILInliner.cpp b/lib/SILOptimizer/Utils/SILInliner.cpp similarity index 97% rename from lib/SILPasses/Utils/SILInliner.cpp rename to lib/SILOptimizer/Utils/SILInliner.cpp index 1e448c506d3fb..4b8919ffa0a73 100644 --- a/lib/SILPasses/Utils/SILInliner.cpp +++ b/lib/SILOptimizer/Utils/SILInliner.cpp @@ -1,8 +1,8 @@ -//===--- SILInliner.cpp - Inlines SIL functions ----------------------------==// +//===--- SILInliner.cpp - Inlines SIL functions ---------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "sil-inliner" -#include "swift/SILPasses/Utils/SILInliner.h" +#include "swift/SILOptimizer/Utils/SILInliner.h" #include "swift/SIL/SILDebugScope.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" @@ -173,9 +173,6 @@ bool SILInliner::inlineFunction(FullApplySite AI, ArrayRef Args) { continue; } - assert(!isa(BI->first->getTerminator()) && - "Unexpected autorelease return while inlining non-Objective-C " - "function?"); // Otherwise use normal visitor, which clones the existing instruction // but remaps basic blocks and values. visit(BI->first->getTerminator()); @@ -316,7 +313,6 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) { case ValueKind::ValueMetatypeInst: case ValueKind::WitnessMethodInst: case ValueKind::AssignInst: - case ValueKind::AutoreleaseReturnInst: case ValueKind::BranchInst: case ValueKind::CheckedCastBranchInst: case ValueKind::CheckedCastAddrBranchInst: @@ -350,6 +346,7 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) { case ValueKind::InjectEnumAddrInst: case ValueKind::IsNonnullInst: case ValueKind::LoadInst: + case ValueKind::LoadUnownedInst: case ValueKind::LoadWeakInst: case ValueKind::OpenExistentialAddrInst: case ValueKind::OpenExistentialBoxInst: @@ -361,10 +358,10 @@ InlineCost swift::instructionInlineCost(SILInstruction &I) { case ValueKind::RefToUnmanagedInst: case ValueKind::RefToUnownedInst: case ValueKind::StoreInst: + case ValueKind::StoreUnownedInst: case ValueKind::StoreWeakInst: case ValueKind::StrongPinInst: case ValueKind::StrongReleaseInst: - case ValueKind::StrongRetainAutoreleasedInst: case ValueKind::StrongRetainInst: case ValueKind::StrongRetainUnownedInst: case ValueKind::StrongUnpinInst: diff --git a/lib/SILPasses/Utils/SILSSAUpdater.cpp b/lib/SILOptimizer/Utils/SILSSAUpdater.cpp similarity index 96% rename from lib/SILPasses/Utils/SILSSAUpdater.cpp rename to lib/SILOptimizer/Utils/SILSSAUpdater.cpp index 687980dd0ad70..01f90d8af849f 100644 --- a/lib/SILPasses/Utils/SILSSAUpdater.cpp +++ b/lib/SILOptimizer/Utils/SILSSAUpdater.cpp @@ -1,8 +1,8 @@ -//===------ SILSSAUpdater.h - Unstructured SSA Update Tool ------*- C++ -*-===// +//===--- SILSSAUpdater.cpp - Unstructured SSA Update Tool -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,8 +20,8 @@ #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILUndef.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" +#include "swift/SILOptimizer/Utils/CFG.h" +#include "swift/SILOptimizer/Utils/SILSSAUpdater.h" using namespace swift; @@ -140,7 +140,7 @@ static OperandValueArrayRef getEdgeValuesForTerminator(TermInst *TI, return IsTrueEdge ? CondBrInst->getTrueArgs() : CondBrInst->getFalseArgs(); } - // We need a predecessor who is capabable of holding outgoing branch + // We need a predecessor who is capable of holding outgoing branch // arguments. llvm_unreachable("Unrecognized terminator leading to phi block"); } @@ -173,7 +173,15 @@ SILValue SILSSAUpdater::GetValueInMiddleOfBlock(SILBasicBlock *BB) { SILValue SingularValue; SmallVector, 4> PredVals; bool FirstPred = true; + + // SSAUpdater can modify TerminatorInst and therefore invalidate the + // predecessor iterator. Find all the predecessors before the SSA update. + SmallVector Preds; for (auto *PredBB: BB->getPreds()) { + Preds.push_back(PredBB); + } + + for (auto *PredBB : Preds) { SILValue PredVal = GetValueAtEndOfBlock(PredBB); PredVals.push_back(std::make_pair(PredBB, PredVal)); if (FirstPred) { @@ -352,7 +360,7 @@ class SSAUpdaterTraits { OperandValueArrayRef Edges = getEdgeValuesForTerminator(PredBB->getTerminator(), PhiBB); - assert(PhiIdx < Edges.size() && "Not enough egdes!"); + assert(PhiIdx < Edges.size() && "Not enough edges!"); SILValue V = Edges[PhiIdx]; // Check for the 'not set' sentinel. diff --git a/lib/SILPasses/ARC/CMakeLists.txt b/lib/SILPasses/ARC/CMakeLists.txt deleted file mode 100644 index 17ddb484bd96d..0000000000000 --- a/lib/SILPasses/ARC/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -set(ARC_SOURCES - ARC/ARCBBState.cpp - ARC/ARCRegionState.cpp - ARC/ARCSequenceOpts.cpp - ARC/GlobalARCPairingAnalysis.cpp - ARC/GlobalARCSequenceDataflow.cpp - ARC/GlobalLoopARCSequenceDataflow.cpp - ARC/RCStateTransition.cpp - ARC/RCStateTransitionVisitors.cpp - ARC/RefCountState.cpp - PARENT_SCOPE) diff --git a/lib/SILPasses/CMakeLists.txt b/lib/SILPasses/CMakeLists.txt deleted file mode 100644 index a031f6e14a63c..0000000000000 --- a/lib/SILPasses/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -add_subdirectory(Utils) -add_subdirectory(SILCombiner) -add_subdirectory(UtilityPasses) -add_subdirectory(ARC) -add_subdirectory(PassManager) -add_subdirectory(Loop) -add_subdirectory(EarlySIL) -add_subdirectory(Scalar) -add_subdirectory(IPO) -add_swift_library(swiftSILPasses - ${SILCOMBINER_SOURCES} - ${UTILITYPASSES_SOURCES} - ${ARC_SOURCES} - ${PM_SOURCES} - ${LOOP_SOURCES} - ${EARLY_SOURCES} - ${SCALAR_SOURCES} - ${IPO_SOURCES} - LINK_LIBRARIES swiftSILPassesUtils swiftSILAnalysis) diff --git a/lib/SILPasses/EarlySIL/CMakeLists.txt b/lib/SILPasses/EarlySIL/CMakeLists.txt deleted file mode 100644 index 6f0fe530404be..0000000000000 --- a/lib/SILPasses/EarlySIL/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -set(EARLY_SOURCES - EarlySIL/DefiniteInitialization.cpp - EarlySIL/MandatoryInlining.cpp - EarlySIL/DIMemoryUseCollector.cpp - EarlySIL/DataflowDiagnostics.cpp - EarlySIL/DiagnoseUnreachable.cpp - EarlySIL/PredictableMemOpt.cpp - EarlySIL/ConstantPropagation.cpp - EarlySIL/InOutDeshadowing.cpp - PARENT_SCOPE) diff --git a/lib/SILPasses/IPO/CMakeLists.txt b/lib/SILPasses/IPO/CMakeLists.txt deleted file mode 100644 index 3e10b1d005381..0000000000000 --- a/lib/SILPasses/IPO/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(IPO_SOURCES - IPO/CapturePromotion.cpp - IPO/DeadFunctionElimination.cpp - IPO/GlobalOpt.cpp - IPO/PerformanceInliner.cpp - IPO/CapturePropagation.cpp - IPO/ExternalDefsToDecls.cpp - IPO/GlobalPropertyOpt.cpp - IPO/UsePrespecialized.cpp - IPO/ClosureSpecializer.cpp - IPO/FunctionSignatureOpts.cpp - IPO/LetPropertiesOpts.cpp - PARENT_SCOPE) diff --git a/lib/SILPasses/Loop/CMakeLists.txt b/lib/SILPasses/Loop/CMakeLists.txt deleted file mode 100644 index 8ef31754e4de8..0000000000000 --- a/lib/SILPasses/Loop/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(LOOP_SOURCES - Loop/ArrayBoundsCheckOpts.cpp - Loop/COWArrayOpt.cpp - Loop/LoopRotate.cpp - Loop/LICM.cpp - PARENT_SCOPE) diff --git a/lib/SILPasses/PassManager/CMakeLists.txt b/lib/SILPasses/PassManager/CMakeLists.txt deleted file mode 100644 index 5722e04095145..0000000000000 --- a/lib/SILPasses/PassManager/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(PM_SOURCES - PassManager/PassManager.cpp - PassManager/Passes.cpp - PassManager/PrettyStackTrace.cpp - PARENT_SCOPE) diff --git a/lib/SILPasses/PassManager/PassManager.cpp b/lib/SILPasses/PassManager/PassManager.cpp deleted file mode 100644 index 912b89a0ff5da..0000000000000 --- a/lib/SILPasses/PassManager/PassManager.cpp +++ /dev/null @@ -1,437 +0,0 @@ -//===----- PassManager.cpp - Swift Pass Manager ---------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-passmanager" - -#include "swift/SILPasses/PassManager.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILModule.h" -#include "swift/SILPasses/PrettyStackTrace.h" -#include "swift/SILPasses/Transforms.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/TimeValue.h" - -using namespace swift; - -STATISTIC(NumOptzIterations, "Number of optimization iterations"); - -llvm::cl::opt SILPrintAll( - "sil-print-all", llvm::cl::init(false), - llvm::cl::desc("Print SIL after each pass")); - -llvm::cl::opt SILPrintPassName( - "sil-print-pass-name", llvm::cl::init(false), - llvm::cl::desc("Print the name of each SIL pass before it runs")); - -llvm::cl::opt SILPrintPassTime( - "sil-print-pass-time", llvm::cl::init(false), - llvm::cl::desc("Print the execution time of each SIL pass")); - -llvm::cl::opt SILNumOptPassesToRun( - "sil-opt-pass-count", llvm::cl::init(UINT_MAX), - llvm::cl::desc("Stop optimizing after optimization passes")); - -llvm::cl::opt - SILPrintOnlyFun("sil-print-only-function", llvm::cl::init(""), - llvm::cl::desc("Only print out the sil for this function")); - -llvm::cl::opt - SILPrintOnlyFuns("sil-print-only-functions", llvm::cl::init(""), - llvm::cl::desc("Only print out the sil for the functions whose name contains this substring")); - -llvm::cl::list - SILPrintBefore("sil-print-before", - llvm::cl::desc("Print out the sil before passes which " - "contain a string from this list.")); - -llvm::cl::list - SILPrintAfter("sil-print-after", - llvm::cl::desc("Print out the sil after passes which contain " - "a string from this list.")); - -llvm::cl::list - SILPrintAround("sil-print-around", - llvm::cl::desc("Print out the sil before and after passes " - "which contain a string from this list")); - -llvm::cl::list - SILDisablePass("sil-disable-pass", - llvm::cl::desc("Disable passes " - "which contain a string from this list")); - -llvm::cl::opt SILVerifyWithoutInvalidation( - "sil-verify-without-invalidation", llvm::cl::init(false), - llvm::cl::desc("Verify after passes even if the pass has not invalidated")); - -static bool doPrintBefore(SILTransform *T, SILFunction *F) { - if (!SILPrintOnlyFun.empty() && F && F->getName() != SILPrintOnlyFun) - return false; - - if (!SILPrintOnlyFuns.empty() && F && - F->getName().find(SILPrintOnlyFuns, 0) == StringRef::npos) - return false; - - auto MatchFun = [&](const std::string &Str) -> bool { - return T->getName().find(Str) != StringRef::npos; - }; - - if (SILPrintBefore.end() != - std::find_if(SILPrintBefore.begin(), SILPrintBefore.end(), MatchFun)) - return true; - - if (SILPrintAround.end() != - std::find_if(SILPrintAround.begin(), SILPrintAround.end(), MatchFun)) - return true; - - return false; -} - -static bool doPrintAfter(SILTransform *T, SILFunction *F, bool Default) { - if (!SILPrintOnlyFun.empty() && F && F->getName() != SILPrintOnlyFun) - return false; - - if (!SILPrintOnlyFuns.empty() && F && - F->getName().find(SILPrintOnlyFuns, 0) == StringRef::npos) - return false; - - auto MatchFun = [&](const std::string &Str) -> bool { - return T->getName().find(Str) != StringRef::npos; - }; - - if (SILPrintAfter.end() != - std::find_if(SILPrintAfter.begin(), SILPrintAfter.end(), MatchFun)) - return true; - - if (SILPrintAround.end() != - std::find_if(SILPrintAround.begin(), SILPrintAround.end(), MatchFun)) - return true; - - return Default; -} - -static bool isDisabled(SILTransform *T) { - for (const std::string &NamePattern : SILDisablePass) { - if (T->getName().find(NamePattern) != StringRef::npos) - return true; - } - return false; -} - -static void printModule(SILModule *Mod, bool EmitVerboseSIL) { - if (SILPrintOnlyFun.empty() && SILPrintOnlyFuns.empty()) { - Mod->dump(); - return; - } - for (auto &F : *Mod) { - if (!SILPrintOnlyFun.empty() && F.getName().str() == SILPrintOnlyFun) - F.dump(EmitVerboseSIL); - - if (!SILPrintOnlyFuns.empty() && - F.getName().find(SILPrintOnlyFuns, 0) != StringRef::npos) - F.dump(EmitVerboseSIL); - } -} - -SILPassManager::SILPassManager(SILModule *M, llvm::StringRef Stage) : - Mod(M), StageName(Stage) { - -#define ANALYSIS(NAME) \ - Analysis.push_back(create##NAME##Analysis(Mod)); -#include "swift/SILAnalysis/Analysis.def" - - for (SILAnalysis *A : Analysis) { - A->initialize(this); - } -} - -bool SILPassManager::runFunctionPasses(PassList FuncTransforms) { - const SILOptions &Options = getOptions(); - - for (auto &F : *Mod) { - if (F.empty()) - continue; - - // Don't optimize functions that are marked with the opt.never attribute. - if (!F.shouldOptimize()) - continue; - - CompletedPasses &completedPasses = CompletedPassesMap[&F]; - - for (auto SFT : FuncTransforms) { - PrettyStackTraceSILFunctionTransform X(SFT); - SFT->injectPassManager(this); - SFT->injectFunction(&F); - - // If nothing changed since the last run of this pass, we can skip this - // pass. - if (completedPasses.test((size_t)SFT->getPassKind())) - continue; - - if (isDisabled(SFT)) - continue; - - currentPassHasInvalidated = false; - - if (SILPrintPassName) - llvm::dbgs() << "#" << NumPassesRun << " Stage: " << StageName - << " Pass: " << SFT->getName() - << ", Function: " << F.getName() << "\n"; - - if (doPrintBefore(SFT, &F)) { - llvm::dbgs() << "*** SIL function before " << StageName << " " - << SFT->getName() << " (" << NumOptimizationIterations - << ") ***\n"; - F.dump(Options.EmitVerboseSIL); - } - - llvm::sys::TimeValue StartTime = llvm::sys::TimeValue::now(); - SFT->run(); - - if (SILPrintPassTime) { - auto Delta = llvm::sys::TimeValue::now().nanoseconds() - - StartTime.nanoseconds(); - llvm::dbgs() << Delta << " (" << SFT->getName() << "," << F.getName() - << ")\n"; - } - - // If this pass invalidated anything, print and verify. - if (doPrintAfter(SFT, &F, - currentPassHasInvalidated && SILPrintAll)) { - llvm::dbgs() << "*** SIL function after " << StageName << " " - << SFT->getName() << " (" << NumOptimizationIterations - << ") ***\n"; - F.dump(Options.EmitVerboseSIL); - } - - // Remember if this pass didn't change anything. - if (!currentPassHasInvalidated) - completedPasses.set((size_t)SFT->getPassKind()); - - if (Options.VerifyAll && - (currentPassHasInvalidated || SILVerifyWithoutInvalidation)) { - F.verify(); - verifyAnalyses(&F); - } - - ++NumPassesRun; - // Request that we stop this optimization phase. - if (Mod->getStage() == SILStage::Canonical - && NumPassesRun >= SILNumOptPassesToRun) - return true; - } - } - - return false; -} - -void SILPassManager::runOneIteration() { - // Verify that all analysis were properly unlocked. - for (auto A : Analysis) { - assert(!A->isLocked() && - "Deleting a locked analysis. Did we forget to unlock ?"); - (void)A; - } - - const SILOptions &Options = getOptions(); - - DEBUG(llvm::dbgs() << "*** Optimizing the module (" << StageName - << ") *** \n"); - if (SILPrintAll && NumOptimizationIterations == 0) { - llvm::dbgs() << "*** SIL module before " << StageName - << " transformation (" << NumOptimizationIterations - << ") ***\n"; - printModule(Mod, Options.EmitVerboseSIL); - } - NumOptzIterations++; - NumOptimizationIterations++; - SmallVector PendingFuncTransforms; - - // For each transformation: - for (SILTransform *ST : Transformations) { - // Bail out if we've hit the optimization pass limit. - if (Mod->getStage() == SILStage::Canonical - && NumPassesRun >= SILNumOptPassesToRun) - return; - - // Run module transformations on the module. - if (SILModuleTransform *SMT = llvm::dyn_cast(ST)) { - // Run all function passes that we've seen since the last module pass. - // Stop stop this optimization phase if one of the passes requested to - // stop. - bool NeedToStop = runFunctionPasses(PendingFuncTransforms); - if (NeedToStop) - return; - - PendingFuncTransforms.clear(); - - if (isDisabled(SMT)) - continue; - - PrettyStackTraceSILModuleTransform X(SMT); - - SMT->injectPassManager(this); - SMT->injectModule(Mod); - - currentPassHasInvalidated = false; - - if (SILPrintPassName) - llvm::dbgs() << "#" << NumPassesRun << " Stage: " << StageName - << " Pass: " << SMT->getName() << " (module pass)\n"; - - if (doPrintBefore(SMT, nullptr)) { - llvm::dbgs() << "*** SIL module before " << StageName << " " - << SMT->getName() << " (" << NumOptimizationIterations - << ") ***\n"; - printModule(Mod, Options.EmitVerboseSIL); - } - - llvm::sys::TimeValue StartTime = llvm::sys::TimeValue::now(); - SMT->run(); - - if (SILPrintPassTime) { - auto Delta = llvm::sys::TimeValue::now().nanoseconds() - - StartTime.nanoseconds(); - llvm::dbgs() << Delta << " (" << SMT->getName() << ",Module)\n"; - } - - // If this pass invalidated anything, print and verify. - if (doPrintAfter(SMT, nullptr, - currentPassHasInvalidated && SILPrintAll)) { - llvm::dbgs() << "*** SIL module after " << StageName << " " - << SMT->getName() << " (" << NumOptimizationIterations - << ") ***\n"; - printModule(Mod, Options.EmitVerboseSIL); - } - - if (Options.VerifyAll && - (currentPassHasInvalidated || !SILVerifyWithoutInvalidation)) { - Mod->verify(); - verifyAnalyses(); - } - - ++NumPassesRun; - if (Mod->getStage() == SILStage::Canonical - && NumPassesRun >= SILNumOptPassesToRun) { - return; - } - - continue; - } - - // Run function transformation on all functions. - if (SILFunctionTransform *SFT = llvm::dyn_cast(ST)) { - PendingFuncTransforms.push_back(SFT); - continue; - } - - llvm_unreachable("Unknown pass kind."); - } - - runFunctionPasses(PendingFuncTransforms); -} - -void SILPassManager::run() { - const SILOptions &Options = getOptions(); - (void) Options; - - if (SILPrintAll) { - if (SILPrintOnlyFun.empty() && SILPrintOnlyFuns.empty()) { - llvm::dbgs() << "*** SIL module before transformation (" - << NumOptimizationIterations << ") ***\n"; - Mod->dump(Options.EmitVerboseSIL); - } else { - for (auto &F : *Mod) { - if (!SILPrintOnlyFun.empty() && F.getName().str() == SILPrintOnlyFun) { - llvm::dbgs() << "*** SIL function before transformation (" - << NumOptimizationIterations << ") ***\n"; - F.dump(Options.EmitVerboseSIL); - } - if (!SILPrintOnlyFuns.empty() && - F.getName().find(SILPrintOnlyFuns, 0) != StringRef::npos) { - llvm::dbgs() << "*** SIL function before transformation (" - << NumOptimizationIterations << ") ***\n"; - F.dump(Options.EmitVerboseSIL); - } - } - } - } - runOneIteration(); -} - -/// D'tor. -SILPassManager::~SILPassManager() { - // Free all transformations. - for (auto T : Transformations) - delete T; - - // delete the analyis. - for (auto A : Analysis) { - assert(!A->isLocked() && - "Deleting a locked analysis. Did we forget to unlock ?"); - delete A; - } -} - -/// \brief Reset the state of the pass manager and remove all transformation -/// owned by the pass manager. Anaysis passes will be kept. -void SILPassManager::resetAndRemoveTransformations() { - for (auto T : Transformations) - delete T; - - Transformations.clear(); - NumOptimizationIterations = 0; -} - -void SILPassManager::setStageName(llvm::StringRef NextStage) { - StageName = NextStage; -} - -const SILOptions &SILPassManager::getOptions() const { - return Mod->getOptions(); -} - -// Define the add-functions for all passes. - -#define PASS(ID, NAME, DESCRIPTION) \ -void SILPassManager::add##ID() { \ - SILTransform *T = swift::create##ID(); \ - T->setPassKind(PassKind::ID); \ - Transformations.push_back(T); \ -} -#include "swift/SILPasses/Passes.def" - -void SILPassManager::addPass(PassKind Kind) { - assert(unsigned(PassKind::AllPasses_Last) >= unsigned(Kind) && - "Invalid pass kind"); - switch (Kind) { -#define PASS(ID, NAME, DESCRIPTION) \ - case PassKind::ID: \ - add##ID(); \ - break; -#include "swift/SILPasses/Passes.def" - case PassKind::invalidPassKind: - llvm_unreachable("invalid pass kind"); - } -} - -void SILPassManager::addPassForName(StringRef Name) { - auto P = llvm::StringSwitch(Name) -#define PASS(ID, NAME, DESCRIPTION) .Case(#ID, PassKind::ID) -#include "swift/SILPasses/Passes.def" - ; - addPass(P); -} - - diff --git a/lib/SILPasses/Scalar/CMakeLists.txt b/lib/SILPasses/Scalar/CMakeLists.txt deleted file mode 100644 index c79e687f4cd0d..0000000000000 --- a/lib/SILPasses/Scalar/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -set(SCALAR_SOURCES - Scalar/AllocBoxToStack.cpp - Scalar/ArrayCountPropagation.cpp - Scalar/MergeCondFail.cpp - Scalar/SILSROA.cpp - Scalar/CSE.cpp - Scalar/RedundantOverflowCheckRemoval.cpp - Scalar/SimplifyCFG.cpp - Scalar/CopyForwarding.cpp - Scalar/RemovePin.cpp - Scalar/Sink.cpp - Scalar/DeadCodeElimination.cpp - Scalar/SILCleanup.cpp - Scalar/SpeculativeDevirtualizer.cpp - Scalar/ReleaseDevirtualizer.cpp - Scalar/DeadObjectElimination.cpp - Scalar/SILCodeMotion.cpp - Scalar/StackPromotion.cpp - Scalar/DeadStoreElimination.cpp - Scalar/SILLowerAggregateInstrs.cpp - Scalar/RedundantLoadElimination.cpp - Scalar/SILMem2Reg.cpp - PARENT_SCOPE) diff --git a/lib/SILPasses/Scalar/DeadStoreElimination.cpp b/lib/SILPasses/Scalar/DeadStoreElimination.cpp deleted file mode 100644 index 28fe4d0c8b650..0000000000000 --- a/lib/SILPasses/Scalar/DeadStoreElimination.cpp +++ /dev/null @@ -1,936 +0,0 @@ -//===---- DeadStoreElimination.cpp - SIL Dead Store Elimination -----===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// -/// This pass eliminates dead stores across basic blocks. -/// -/// A store is dead if after the store has occurred: -/// -/// 1. The store to pointer is not used along any path to program exit. -/// 2. The store to pointer is overwritten by another store before any -/// potential use of the pointer. -/// -/// Dead store elimination (DSE) eliminates such stores by: -/// -/// 1. Introducing a notion of a MemLocation that is used to model objects -/// fields. (See below for more details). -/// -/// 2. Performing a post-order walk over the control flow graph, tracking any -/// MemLocations that are read from or stored into in each basic block. After -/// eliminating any dead stores in single blocks, it computes a kill set for -/// each block. The kill set tracks what MemLocations are stored into by this -/// basic block and its successors. -/// -/// 3. An optimistic iterative dataflow is performed on the gen sets and kill -/// sets until convergence. -/// -/// At the core of DSE, there is the MemLocation class. a MemLocation is an -/// abstraction of an object field in program. It consists of a base and a -/// projection path to the field accessed. -/// -/// When a load or store instruction is encountered, the memory is broken down -/// to the indivisible components, i.e aggregates are broken down to their -/// individual fields using the expand function. This gives the flexbility to -/// find exactly which part of the store is alive and which part is dead. -/// -/// After the live parts of the store are determined, they are merged into the -/// minimum number of stores possible using the reduce function. This is done -/// so that we do not bloat SIL IR. -/// -/// Another way to implement the DSE optimization is to keep the instructions -/// that read and/or write memory without breaking the memory read/written -/// using the ProjectionPath. However, this can easily lead to loss of -/// opportunities, e.g. a read that only kills part of a store may need to be -/// treated as killing the entire store. However, using ProjectionPath does -/// lead to more memory uses. -/// -/// TODO: Handle same value store in DSE, currently handled in RLE. -/// -/// e.g. -/// %0 = load %A -/// ... nothing happens in middle and the %A contains the value of %0. -/// store %0 to %A <---- no need to do this store. -/// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-dead-store-elim" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SIL/MemLocation.h" -#include "swift/SIL/Projection.h" -#include "swift/SIL/SILArgument.h" -#include "swift/SIL/SILBuilder.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" -#include - -using namespace swift; -using swift::MemLocation; - -static llvm::cl::opt EnableLocalStoreDSE("enable-local-store-dse", - llvm::cl::init(false)); - -STATISTIC(NumDeadStores, "Number of dead stores removed"); -STATISTIC(NumPartialDeadStores, "Number of partial dead stores removed"); - -//===----------------------------------------------------------------------===// -// Utility Functions -//===----------------------------------------------------------------------===// - -/// Returns true if this is an instruction that may have side effects in a -/// general sense but are inert from a load store perspective. -static bool isDeadStoreInertInstruction(SILInstruction *Inst) { - switch (Inst->getKind()) { - case ValueKind::StrongRetainInst: - case ValueKind::StrongRetainUnownedInst: - case ValueKind::UnownedRetainInst: - case ValueKind::RetainValueInst: - case ValueKind::DeallocStackInst: - case ValueKind::CondFailInst: - case ValueKind::IsUniqueInst: - case ValueKind::IsUniqueOrPinnedInst: - return true; - default: - return false; - } -} - -//===----------------------------------------------------------------------===// -// Basic Block Location State -//===----------------------------------------------------------------------===// - -namespace { - -/// If a large store is broken down to too many smaller stores, bail out. -/// Currently, we only do partial dead store if we can form a single contiguous -/// non-dead store. -constexpr unsigned MaxPartialDeadStoreCountLimit = 1; - -/// BBState summarizes how MemLocations are used in a basic block. -/// -/// Initially the WriteSetOut is empty. Before a basic block is processed, it is -/// initialized to the intersection of WriteSetIns of all successors of the -/// basic block. -/// -/// Initially WriteSetIn is set to true. After the basic block is processed, if -/// its WriteSetOut is different from WriteSetIn, WriteSetIn is initialized to -/// the value of WriteSetOut and the data flow is rerun. -/// -/// Instructions in each basic block are processed in post-order as follows: -/// -/// 1. When a store instruction is encountered, the stored location is tracked. -/// -/// 2. When a load instruction is encountered, remove the loaded location and -/// any location it may alias with from the WriteSetOut. -/// -/// 3. When an instruction reads from memory in an unknown way, the WriteSetOut -/// bit is cleared if the instruction can read the corresponding MemLocation. -/// -class BBState { -public: - /// The basic block this BBState represents. - SILBasicBlock *BB; - - /// Keep the number of MemLocations in the LocationVault. - unsigned MemLocationNum; - - /// A bit vector for which the ith bit represents the ith MemLocation in - /// MemLocationVault. If the bit is set, then the location currently has an - /// upward visible store. - llvm::BitVector WriteSetOut; - - /// If WriteSetIn changes while processing a basicblock, then all its - /// predecessors needs to be rerun. - llvm::BitVector WriteSetIn; - - /// A bit vector for which the ith bit represents the ith MemLocation in - /// MemLocationVault. If the bit is set, then the current basic block - /// generates an upward visible store. - llvm::BitVector BBGenSet; - - /// A bit vector for which the ith bit represents the ith MemLocation in - /// MemLocationVault. If the bit is set, then the current basic block - /// kills an upward visible store. - llvm::BitVector BBKillSet; - - /// The dead stores in the current basic block. - llvm::DenseSet DeadStores; - - /// Keeps track of what stores to generate after the data flow stabilizes. - /// these stores come from partial dead stores. - llvm::DenseMap LiveStores; - - /// Constructors. - BBState() : BB(nullptr) {} - BBState(SILBasicBlock *B) : BB(B) {} - - /// Return the current basic block. - SILBasicBlock *getBB() const { return BB; } - - void init(unsigned lcnt) { - MemLocationNum = lcnt; - // The initial state of WriteSetIn should be all 1's. Otherwise the - // dataflow solution could be too conservative. - // - // consider this case, the dead store by var a = 10 before the loop will not - // be eliminated if the WriteSetIn is set to 0 initially. - // - // var a = 10 - // for _ in 0...1024 {} - // a = 10 - // - // However, by doing so, we can only eliminate the dead stores after the - // data flow stablizes. - // - WriteSetIn.resize(MemLocationNum, true); - WriteSetOut.resize(MemLocationNum, false); - - // GenSet and KillSet initially empty. - BBGenSet.resize(MemLocationNum, false); - BBKillSet.resize(MemLocationNum, false); - } - - /// Check whether the WriteSetIn has changed. If it does, we need to rerun - /// the data flow to reach fixed point. - bool updateWriteSetIn(); - - /// Functions to manipulate the write set. - void clearMemLocations(); - void startTrackingMemLocation(unsigned bit); - void stopTrackingMemLocation(unsigned bit); - bool isTrackingMemLocation(unsigned bit); - void initialize(const BBState &L); - void intersect(const BBState &L); -}; - -} // end anonymous namespace - -bool BBState::updateWriteSetIn() { - bool Changed = (WriteSetIn != WriteSetOut); - WriteSetIn = WriteSetOut; - return Changed; -} - -void BBState::clearMemLocations() { WriteSetOut.reset(); } - -void BBState::startTrackingMemLocation(unsigned bit) { WriteSetOut.set(bit); } - -void BBState::stopTrackingMemLocation(unsigned bit) { WriteSetOut.reset(bit); } - -bool BBState::isTrackingMemLocation(unsigned bit) { - return WriteSetOut.test(bit); -} - -void BBState::initialize(const BBState &Succ) { WriteSetOut = Succ.WriteSetIn; } - -/// Intersect is very frequently performed, so it is important to make it as -/// cheap as possible. -/// -/// To do so, we canonicalize MemLocations, i.e. traced back to the underlying -/// object. Therefore, no need to do a O(N^2) comparison to figure out what is -/// dead along all successors. -/// -/// NOTE: Canonicalizing does not solve the problem entirely. i.e. it is still -/// possible that 2 MemLocations with different bases that happen to be the -/// same object and field. In such case, we would miss a dead store -/// opportunity. But this happens less often with canonicalization. -void BBState::intersect(const BBState &Succ) { WriteSetOut &= Succ.WriteSetIn; } - -//===----------------------------------------------------------------------===// -// Top Level Implementation -//===----------------------------------------------------------------------===// - -namespace { - -class DSEContext { - /// The module we are currently processing. - SILModule *Mod; - - /// The function we are currently processing. - SILFunction *F; - - /// Pass manager, used to get various analysis. - SILPassManager *PM; - - /// Alias Analysis. - AliasAnalysis *AA; - - /// Allocator. - llvm::BumpPtrAllocator BPA; - - /// Map every basic block to its location state. - llvm::DenseMap BBToLocState; - - /// Keeps the actual BBStates. - std::vector BBStates; - - /// Keeps all the locations for the current function. The BitVector in each - /// BBState is then laid on top of it to keep track of which MemLocation - /// has an upward visible store. - std::vector MemLocationVault; - - /// Caches a list of projection paths to leaf nodes in the given type. - TypeExpansionMap TypeExpansionVault; - - /// Contains a map between location to their index in the MemLocationVault. - MemLocationIndexMap LocToBitIndex; - - /// Return the BBState for the basic block this basic block belongs to. - BBState *getBBLocState(SILBasicBlock *B) { return BBToLocState[B]; } - - /// Return the BBState for the basic block this instruction belongs to. - BBState *getBBLocState(SILInstruction *I) { - return getBBLocState(I->getParent()); - } - - /// MemLocation read has been extracted, expanded and mapped to the bit - /// position in the bitvector. update the gen kill set using the bit - /// position. - void updateGenKillSetForRead(BBState *S, unsigned bit); - - /// MemLocation written has been extracted, expanded and mapped to the bit - /// position in the bitvector. update the gen kill set using the bit - /// position. - void updateGenKillSetForWrite(BBState *S, unsigned bit); - - /// MemLocation read has been extracted, expanded and mapped to the bit - /// position in the bitvector. process it using the bit position. - void updateWriteSetForRead(BBState *S, unsigned Bit); - - /// MemLocation written has been extracted, expanded and mapped to the bit - /// position in the bitvector. process it using the bit position. - bool updateWriteSetForWrite(BBState *S, unsigned Bit); - - /// There is a read to a location, expand the location into individual fields - /// before processing them. - void processRead(SILInstruction *Inst, BBState *State, SILValue Mem, - bool BuildGenKillSet); - - /// There is a write to a location, expand the location into individual fields - /// before processing them. - void processWrite(SILInstruction *Inst, BBState *State, SILValue Val, - SILValue Mem, bool BuildGenKillSet); - - /// Process Instructions. Extract MemLocations from SIL LoadInst. - void processLoadInst(SILInstruction *Inst, bool BuildGenKillSet); - - /// Process Instructions. Extract MemLocations from SIL StoreInst. - void processStoreInst(SILInstruction *Inst, bool BuildGenKillSet); - - /// Process Instructions. Extract MemLocations from SIL DebugValueAddrInst. - /// DebugValueAddrInst operand maybe promoted to DebugValue, when this is - /// done, DebugValueAddrInst is effectively a read on the MemLocation. - void processDebugValueAddrInst(SILInstruction *I); - - /// Process Instructions. Extract MemLocations from SIL Unknown Memory Inst. - void processUnknownReadMemInst(SILInstruction *Inst, bool BuildGenKillSet); - - /// Check whether the instruction invalidate any MemLocations due to change in - /// its MemLocation Base. - /// - /// This is to handle a case like this. - /// - /// class Foo { var a : Int = 12 } - /// for _ in 0 ...x { - /// x = Foo(); - /// x.a = 13 - /// } - /// x.a = 12 - /// - /// In this case, DSE can not remove the x.a = 13 inside the loop. - /// - /// To do this, when the algorithm reaches the beginning of the basic block in - /// the loop it will need to invalidate the MemLocation in the WriteSetOut. - /// i.e. - /// the base of the MemLocation is changed. - /// - /// If not, on the second iteration, the intersection of the successors of - /// the loop basic block will have store to x.a and therefore x.a = 13 can now - /// be considered dead. - /// - void invalidateMemLocationBase(SILInstruction *Inst, bool BuildGenKillSet); - - /// Get the bit representing the location in the MemLocationVault. - /// - /// NOTE: Adds the location to the location vault if necessary. - unsigned getMemLocationBit(const MemLocation &L); - - /// Create the value or address extraction based on the give Base and - /// projection path. - SILValue createExtract(SILValue Base, Optional &Path, - SILInstruction *Inst, bool IsValExtract); - -public: - /// Constructor. - DSEContext(SILFunction *F, SILModule *M, SILPassManager *PM, - AliasAnalysis *AA) - : Mod(M), F(F), PM(PM), AA(AA) {} - - /// Compute the kill set for the basic block. return true if the store set - /// changes. - bool processBasicBlock(SILBasicBlock *BB); - - /// Compute the genset and killset for the current basic block. - void processBasicBlockForGenKillSet(SILBasicBlock *BB); - - /// Compute the WriteSetOut and WriteSetIn for the current basic - /// block with the generated gen and kill set. - bool processBasicBlockWithGenKillSet(SILBasicBlock *BB); - - /// Intersect the successor live-ins. - void mergeSuccessorStates(SILBasicBlock *BB); - - /// Update the BBState based on the given instruction. - void processInstruction(SILInstruction *I, bool BuildGenKillSet); - - /// Entry point for global dead store elimination. - void run(); -}; - -} // end anonymous namespace - -unsigned DSEContext::getMemLocationBit(const MemLocation &Loc) { - // Return the bit position of the given Loc in the MemLocationVault. The bit - // position is then used to set/reset the bitvector kept by each BBState. - // - // We should have the location populated by the enumerateMemLocation at this - // point. - // - auto Iter = LocToBitIndex.find(Loc); - assert(Iter != LocToBitIndex.end() && - "MemLocation should have been enumerated"); - return Iter->second; -} - -void DSEContext::processBasicBlockForGenKillSet(SILBasicBlock *BB) { - for (auto I = BB->rbegin(), E = BB->rend(); I != E; ++I) { - processInstruction(&(*I), true); - } -} - -bool DSEContext::processBasicBlockWithGenKillSet(SILBasicBlock *BB) { - // Compute the WriteSetOut at the end of the basic block. - mergeSuccessorStates(BB); - - // Compute the WriteSetOut at the beginning of the basic block. - BBState *S = getBBLocState(BB); - llvm::BitVector T = S->BBKillSet; - S->WriteSetOut &= T.flip(); - S->WriteSetOut |= S->BBGenSet; - - // If WriteSetIn changes, then keep iterating until reached a fixed - // point. - return S->updateWriteSetIn(); -} - -bool DSEContext::processBasicBlock(SILBasicBlock *BB) { - // Intersect in the successor live-ins. A store is dead if it is not read from - // any path to the end of the program. Thus an intersection. - mergeSuccessorStates(BB); - - // Process instructions in post-order fashion. - for (auto I = BB->rbegin(), E = BB->rend(); I != E; ++I) { - processInstruction(&(*I), false); - } - - // If WriteSetIn changes, then keep iterating until reached a fixed - // point. - return getBBLocState(BB)->updateWriteSetIn(); -} - -void DSEContext::mergeSuccessorStates(SILBasicBlock *BB) { - // First, clear the WriteSetOut for the current basicblock. - BBState *C = getBBLocState(BB); - C->clearMemLocations(); - - // If basic block has no successor, then all local writes can be considered - // dead at this point. - if (BB->succ_empty()) { - // There is currently a outstand radar in the swift type/aa system, will - // take this flag off once thats fixed. - if (!EnableLocalStoreDSE) - return; - for (unsigned i = 0; i < MemLocationVault.size(); ++i) { - if (!MemLocationVault[i].isNonEscapingLocalMemLocation()) - continue; - C->startTrackingMemLocation(i); - } - return; - } - - // Use the first successor as the base condition. - auto Iter = BB->succ_begin(); - C->initialize(*getBBLocState(*Iter)); - Iter = std::next(Iter); - for (auto EndIter = BB->succ_end(); Iter != EndIter; ++Iter) { - C->intersect(*getBBLocState(*Iter)); - } -} - -void DSEContext::invalidateMemLocationBase(SILInstruction *I, - bool BuildGenKillSet) { - // If this instruction defines the base of a location, then we need to - // invalidate any locations with the same base. - BBState *S = getBBLocState(I); - if (BuildGenKillSet) { - for (unsigned i = 0; i < S->MemLocationNum; ++i) { - if (MemLocationVault[i].getBase().getDef() != I) - continue; - S->BBGenSet.reset(i); - S->BBKillSet.set(i); - } - return; - } - - for (unsigned i = 0; i < S->MemLocationNum; ++i) { - if (!S->WriteSetOut.test(i)) - continue; - if (MemLocationVault[i].getBase().getDef() != I) - continue; - S->stopTrackingMemLocation(i); - } -} - -void DSEContext::updateWriteSetForRead(BBState *S, unsigned bit) { - // Remove any may/must-aliasing stores to the MemLocation, as they cant be - // used to kill any upward visible stores due to the intefering load. - MemLocation &R = MemLocationVault[bit]; - for (unsigned i = 0; i < S->MemLocationNum; ++i) { - if (!S->isTrackingMemLocation(i)) - continue; - MemLocation &L = MemLocationVault[i]; - if (!L.isMayAliasMemLocation(R, AA)) - continue; - DEBUG(llvm::dbgs() << "Loc Removal: " << MemLocationVault[i].getBase() - << "\n"); - S->stopTrackingMemLocation(i); - } -} - -void DSEContext::updateGenKillSetForRead(BBState *S, unsigned bit) { - // Start tracking the read to this MemLocation in the killset and update - // the genset accordingly. - // - // Even though, MemLocations are canonicalized, we still need to consult - // alias analysis to determine whether 2 MemLocations are disjointed. - MemLocation &R = MemLocationVault[bit]; - for (unsigned i = 0; i < S->MemLocationNum; ++i) { - MemLocation &L = MemLocationVault[i]; - if (!L.isMayAliasMemLocation(R, AA)) - continue; - S->BBGenSet.reset(i); - // Update the kill set, we need to be conservative about kill set. Kill set - // kills any MemLocation that this currently MemLocation mayalias. - S->BBKillSet.set(i); - } -} - -bool DSEContext::updateWriteSetForWrite(BBState *S, unsigned bit) { - // If a tracked store must aliases with this store, then this store is dead. - bool IsDead = false; - MemLocation &R = MemLocationVault[bit]; - for (unsigned i = 0; i < S->MemLocationNum; ++i) { - if (!S->isTrackingMemLocation(i)) - continue; - // If 2 locations may alias, we can still keep both stores. - MemLocation &L = MemLocationVault[i]; - if (!L.isMustAliasMemLocation(R, AA)) - continue; - IsDead = true; - // No need to check the rest of the upward visible stores as this store - // is dead. - break; - } - - // Track this new store. - DEBUG(llvm::dbgs() << "Loc Insertion: " << MemLocationVault[bit].getBase() - << "\n"); - S->startTrackingMemLocation(bit); - return IsDead; -} - -void DSEContext::updateGenKillSetForWrite(BBState *S, unsigned bit) { - // Start tracking the store to this MemLoation. - S->BBGenSet.set(bit); -} - -void DSEContext::processRead(SILInstruction *I, BBState *S, SILValue Mem, - bool BuildGenKillSet) { - // Construct a MemLocation to represent the memory read by this instruction. - // NOTE: The base will point to the actual object this inst is accessing, - // not this particular field. - // - // e.g. %1 = alloc_stack $S - // %2 = struct_element_addr %1, #a - // %3 = load %2 : $*Int - // - // Base will point to %1, but not %2. Projection path will indicate which - // field is accessed. - // - // This will make comparison between locations easier. This eases the - // implementation of intersection operator in the data flow. - MemLocation L(Mem); - - // If we cant figure out the Base or Projection Path for the read instruction, - // process it as an unknown memory instruction for now. - if (!L.isValid()) { - processUnknownReadMemInst(I, BuildGenKillSet); - return; - } - -#ifndef NDEBUG - // Make sure that the MemLocation getType() returns the same type as the - // loaded type. - if (auto *LI = dyn_cast(I)) { - assert(LI->getOperand().getType().getObjectType() == L.getType() && - "MemLocation returns different type"); - } -#endif - - // Expand the given Mem into individual fields and process them as - // separate reads. - MemLocationList Locs; - MemLocation::expand(L, &I->getModule(), Locs, TypeExpansionVault); - if (BuildGenKillSet) { - for (auto &E : Locs) { - // Only building the gen and kill sets for now. - updateGenKillSetForRead(S, getMemLocationBit(E)); - } - } else { - for (auto &E : Locs) { - // This is the last iteration, compute WriteSetOut and perform the dead - // store elimination. - updateWriteSetForRead(S, getMemLocationBit(E)); - } - } -} - -void DSEContext::processWrite(SILInstruction *I, BBState *S, SILValue Val, - SILValue Mem, bool BuildGenKillSet) { - // Construct a MemLocation to represent the memory read by this instruction. - // NOTE: The base will point to the actual object this inst is accessing, - // not this particular field. - // - // e.g. %1 = alloc_stack $S - // %2 = struct_element_addr %1, #a - // store %3 to %2 : $*Int - // - // Base will point to %1, but not %2. Projection path will indicate which - // field is accessed. - // - // This will make comparison between locations easier. This eases the - // implementation of intersection operator in the data flow. - MemLocation L(Mem); - - // If we cant figure out the Base or Projection Path for the store - // instruction, - // simply ignore it for now. - if (!L.isValid()) - return; - -#ifndef NDEBUG - // Make sure that the MemLocation getType() returns the same type as the - // stored type. - if (auto *SI = dyn_cast(I)) { - assert(SI->getDest().getType().getObjectType() == L.getType() && - "MemLocation returns different type"); - } -#endif - - // Expand the given Mem into individual fields and process them as separate - // writes. - bool Dead = true; - MemLocationList Locs; - MemLocation::expand(L, Mod, Locs, TypeExpansionVault); - llvm::BitVector V(Locs.size()); - if (BuildGenKillSet) { - for (auto &E : Locs) { - // Only building the gen and kill sets here. - updateGenKillSetForWrite(S, getMemLocationBit(E)); - } - } else { - unsigned idx = 0; - for (auto &E : Locs) { - // This is the last iteration, compute WriteSetOut and perform the dead - // store elimination. - if (updateWriteSetForWrite(S, getMemLocationBit(E))) - V.set(idx); - Dead &= V.test(idx); - ++idx; - } - } - - // Data flow has not stablized, do not perform the DSE just yet. - if (BuildGenKillSet) - return; - - // Fully dead store - stores to all the components are dead, therefore this - // instruction is dead. - if (Dead) { - DEBUG(llvm::dbgs() << "Instruction Dead: " << *I << "\n"); - S->DeadStores.insert(I); - ++NumDeadStores; - return; - } - - // Partial dead store - stores to some locations are dead, but not all. This - // is a partially dead store. Also at this point we know what locations are - // dead. - llvm::DenseSet Alives; - if (V.any()) { - // Take out locations that are dead. - for (unsigned i = 0; i < V.size(); ++i) { - if (V.test(i)) - continue; - // This location is alive. - Alives.insert(Locs[i]); - } - - // Try to create as few aggregated stores as possible out of the locations. - MemLocation::reduce(L, Mod, Alives); - - // Oops, we have too many smaller stores generated, bail out. - if (Alives.size() > MaxPartialDeadStoreCountLimit) - return; - - // At this point, we are performing a partial dead store elimination. - // - // Locations here have a projection path from their Base, but this - // particular instruction may not be accessing the base, so we need to - // *rebase* the locations w.r.t. to the current instruction. - SILValue B = Locs[0].getBase(); - Optional BP = ProjectionPath::getAddrProjectionPath(B, Mem); - // Strip off the projection path from base to the accessed field. - for (auto &X : Alives) { - X.subtractPaths(BP); - } - - // We merely setup the remain live stores, but do not materialize in IR yet, - // These stores will be materialized when before the algorithm exits. - for (auto &X : Alives) { - SILValue Value = createExtract(Val, X.getPath(), I, true); - SILValue Addr = createExtract(Mem, X.getPath(), I, false); - S->LiveStores[Addr] = Value; - } - - // Lastly, mark the old store as dead. - DEBUG(llvm::dbgs() << "Instruction Partially Dead: " << *I << "\n"); - S->DeadStores.insert(I); - ++NumPartialDeadStores; - } -} - -void DSEContext::processLoadInst(SILInstruction *I, bool BuildGenKillSet) { - SILValue Mem = cast(I)->getOperand(); - processRead(I, getBBLocState(I), Mem, BuildGenKillSet); -} - -void DSEContext::processStoreInst(SILInstruction *I, bool BuildGenKillSet) { - SILValue Val = cast(I)->getSrc(); - SILValue Mem = cast(I)->getDest(); - processWrite(I, getBBLocState(I), Val, Mem, BuildGenKillSet); -} - -void DSEContext::processDebugValueAddrInst(SILInstruction *I) { - BBState *S = getBBLocState(I); - SILValue Mem = cast(I)->getOperand(); - for (unsigned i = 0; i < S->WriteSetOut.size(); ++i) { - if (!S->isTrackingMemLocation(i)) - continue; - if (AA->isNoAlias(Mem, MemLocationVault[i].getBase())) - continue; - getBBLocState(I)->stopTrackingMemLocation(i); - } -} - -void DSEContext::processUnknownReadMemInst(SILInstruction *I, - bool BuildGenKillSet) { - BBState *S = getBBLocState(I); - // Update the gen kill set. - if (BuildGenKillSet) { - for (unsigned i = 0; i < S->MemLocationNum; ++i) { - if (!AA->mayReadFromMemory(I, MemLocationVault[i].getBase())) - continue; - S->BBKillSet.set(i); - S->BBGenSet.reset(i); - } - return; - } - - // We do not know what this instruction does or the memory that it *may* - // touch. Hand it to alias analysis to see whether we need to invalidate - // any MemLocation. - for (unsigned i = 0; i < S->MemLocationNum; ++i) { - if (!S->isTrackingMemLocation(i)) - continue; - if (!AA->mayReadFromMemory(I, MemLocationVault[i].getBase())) - continue; - getBBLocState(I)->stopTrackingMemLocation(i); - } -} - -void DSEContext::processInstruction(SILInstruction *I, bool BuildGenKillSet) { - // If this instruction has side effects, but is inert from a store - // perspective, skip it. - if (isDeadStoreInertInstruction(I)) - return; - - // A set of ad-hoc rules to process instructions. - // - // TODO: process more instructions. - // - if (isa(I)) { - processLoadInst(I, BuildGenKillSet); - } else if (isa(I)) { - processStoreInst(I, BuildGenKillSet); - } else if (isa(I)) { - processDebugValueAddrInst(I); - } else if (I->mayReadFromMemory()) { - processUnknownReadMemInst(I, BuildGenKillSet); - } - - // Check whether this instruction will invalidate any other MemLocations. - invalidateMemLocationBase(I, BuildGenKillSet); -} - -SILValue DSEContext::createExtract(SILValue Base, - Optional &Path, - SILInstruction *Inst, bool IsValExt) { - // If we found a projection path, but there are no projections, then the two - // loads must be the same, return PrevLI. - if (!Path || Path->empty()) - return Base; - - // Ok, at this point we know that we can construct our aggregate projections - // from our list of address projections. - SILValue LastExtract = Base; - SILBuilder Builder(Inst); - - // Construct the path! - for (auto PI = Path->rbegin(), PE = Path->rend(); PI != PE; ++PI) { - if (IsValExt) { - LastExtract = - PI->createValueProjection(Builder, Inst->getLoc(), LastExtract).get(); - continue; - } - LastExtract = - PI->createAddrProjection(Builder, Inst->getLoc(), LastExtract).get(); - } - - // Return the last extract we created. - return LastExtract; -} - -void DSEContext::run() { - // Walk over the function and find all the locations accessed by - // this function. - MemLocation::enumerateMemLocations(*F, MemLocationVault, LocToBitIndex, - TypeExpansionVault); - - // For all basic blocks in the function, initialize a BB state. Since we - // know all the locations accessed in this function, we can resize the bit - // vector to the approproate size. - // - // DenseMap has a minimum size of 64, while many functions do not have more - // than 64 basic blocks. Therefore, allocate the BBState in a vector and use - // pointer in BBToLocState to access them. - for (auto &B : *F) { - BBStates.push_back(BBState(&B)); - BBStates.back().init(MemLocationVault.size()); - } - - // Initialize the BBToLocState mapping. - for (auto &S : BBStates) { - BBToLocState[S.getBB()] = &S; - } - - // Generate the genset and killset for each basic block. - for (auto &B : *F) { - processBasicBlockForGenKillSet(&B); - } - - // Process each basic block with the gen and kill set. Every time the - // WriteSetIn of a basic block changes, the optimization is rerun on its - // predecessors. - auto *PO = PM->getAnalysis()->get(F); - llvm::SmallVector WorkList; - for (SILBasicBlock *B : PO->getPostOrder()) { - WorkList.push_back(B); - } - - while (!WorkList.empty()) { - SILBasicBlock *BB = WorkList.pop_back_val(); - if (processBasicBlockWithGenKillSet(BB)) { - for (auto X : BB->getPreds()) - WorkList.push_back(X); - } - } - - // The data flow has stablized, run one last iteration over all the basic - // blocks and try to remove dead stores. - for (SILBasicBlock &BB : *F) { - processBasicBlock(&BB); - } - - // Finally, delete the dead stores and create the live stores. - for (SILBasicBlock &BB : *F) { - // Create the stores that are alive due to partial dead stores. - for (auto &I : getBBLocState(&BB)->LiveStores) { - SILInstruction *IT = cast(I.first)->getNextNode(); - SILBuilderWithScope Builder(IT); - Builder.createStore(I.first.getLoc().getValue(), I.second, I.first); - } - // Delete the dead stores. - for (auto &I : getBBLocState(&BB)->DeadStores) { - DEBUG(llvm::dbgs() << "*** Removing: " << *I << " ***\n"); - // This way, we get rid of pass dependence on DCE. - recursivelyDeleteTriviallyDeadInstructions(I, true); - } - } -} - -//===----------------------------------------------------------------------===// -// Top Level Entry Point -//===----------------------------------------------------------------------===// - -namespace { - -class DeadStoreElimination : public SILFunctionTransform { -public: - StringRef getName() override { return "SIL Dead Store Elimination"; } - - /// The entry point to the transformation. - void run() override { - auto *AA = PM->getAnalysis(); - SILFunction *F = getFunction(); - DEBUG(llvm::dbgs() << "*** DSE on function: " << F->getName() << " ***\n"); - - DSEContext DSE(F, &F->getModule(), PM, AA); - DSE.run(); - } -}; - -} // end anonymous namespace - -SILTransform *swift::createDeadStoreElimination() { - return new DeadStoreElimination(); -} diff --git a/lib/SILPasses/Scalar/RedundantLoadElimination.cpp b/lib/SILPasses/Scalar/RedundantLoadElimination.cpp deleted file mode 100644 index 1c05f49144c93..0000000000000 --- a/lib/SILPasses/Scalar/RedundantLoadElimination.cpp +++ /dev/null @@ -1,998 +0,0 @@ -//===-------- RedundantLoadElimination.cpp - SIL Load Forwarding ---------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// -/// This pass eliminates redundant loads. -/// -/// A load can be eliminated if its value has already been held somewhere, -/// i.e. loaded by a previous load, MemLocation stored by a known -/// value. -/// -/// In this case, one can replace the load instruction with the previous -/// results. -/// -/// Redudant Load Elimination (RLE) eliminates such loads by: -/// -/// 1. Introducing a notion of a MemLocation that is used to model object -/// fields. (See below for more details). -/// -/// 2. Introducing a notion of a LoadStoreValue that is used to model the value -/// that currently resides in the associated MemLocation on the particular -/// program path. (See below for more details). -/// -/// 3. Performing a RPO walk over the control flow graph, tracking any -/// MemLocations that are read from or stored into in each basic block. The -/// read or stored value, kept in a map (gen-set) between MemLocation and -/// LoadStoreValue, becomes the avalable value for the MemLocation. -/// -/// 4. An optimistic iterative intersection-based dataflow is performed on the -/// gen sets until convergence. -/// -/// At the core of RLE, there is the MemLocation class. A MemLocation is an -/// abstraction of an object field in program. It consists of a base and a -/// projection path to the field accessed. -/// -/// In SIL, one can access an aggregate as a whole, i.e. store to a struct with -/// 2 Int fields. A store like this will generate 2 *indivisible* MemLocations, -/// 1 for each field and in addition to keeping a list of MemLocation, RLE also -/// keeps their available LoadStoreValues. We call it *indivisible* because it -/// can not be broken down to more MemLocations. -/// -/// LoadStoreValue consists of a base - a SILValue from the load or store inst, -/// as well as a projection path to which the field it represents. So, a -/// store to an 2-field struct as mentioned above will generate 2 MemLocations -/// and 2 LoadStoreValues. -/// -/// Every basic block keeps a map between MemLocation and LoadStoreValue. By -/// keeping the MemLocation and LoadStoreValue in their indivisible form, one -/// can easily find which part of the load is redundant and how to compute its -/// forwarding value. -/// -/// Given the case which the 2 fields of the struct both have available values, -/// RLE can find their LoadStoreValues (maybe by struct_extract from a larger -/// value) and then aggregate them. -/// -/// However, this may introduce a lot of extraction and aggregation which may -/// not be necessary. i.e. a store the struct followed by a load from the -/// struct. To solve this problem, when RLE detects that an load instruction -/// can be replaced by forwarded value, it will try to find minimum # of -/// extraction necessary to form the forwarded value. It will group the -/// available value's by the LoadStoreValue base, i.e. the LoadStoreValues come -/// from the same instruction, and then use extraction to obtain the needed -/// components of the base. -/// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-redundant-load-elim" -#include "swift/SIL/MemLocation.h" -#include "swift/SIL/Projection.h" -#include "swift/SIL/SILArgument.h" -#include "swift/SIL/SILBuilder.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/DominanceAnalysis.h" -#include "swift/SILAnalysis/PostOrderAnalysis.h" -#include "swift/SILAnalysis/ValueTracking.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/Transforms.h" -#include "swift/SILPasses/Utils/CFG.h" -#include "swift/SILPasses/Utils/Local.h" -#include "swift/SILPasses/Utils/SILSSAUpdater.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/MapVector.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/TinyPtrVector.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" - -using namespace swift; - -STATISTIC(NumForwardedLoads, "Number of loads forwarded"); - -//===----------------------------------------------------------------------===// -// Utility Functions -//===----------------------------------------------------------------------===// - -/// Returns true if this is an instruction that may have side effects in a -/// general sense but are inert from a load store perspective. -static bool isRLEInertInstruction(SILInstruction *Inst) { - switch (Inst->getKind()) { - case ValueKind::StrongRetainInst: - case ValueKind::StrongRetainUnownedInst: - case ValueKind::UnownedRetainInst: - case ValueKind::RetainValueInst: - case ValueKind::DeallocStackInst: - case ValueKind::CondFailInst: - case ValueKind::IsUniqueInst: - case ValueKind::IsUniqueOrPinnedInst: - return true; - default: - return false; - } -} - -/// Returns true if the given basic block is reachable from the entry block. -/// -/// TODO: this is very inefficient, can we make use of the domtree. -static bool isReachable(SILBasicBlock *Block) { - SmallPtrSet Visited; - llvm::SmallVector Worklist; - SILBasicBlock *EntryBB = &*Block->getParent()->begin(); - Worklist.push_back(EntryBB); - Visited.insert(EntryBB); - - while (!Worklist.empty()) { - auto *CurBB = Worklist.back(); - Worklist.pop_back(); - - if (CurBB == Block) - return true; - - for (auto &Succ : CurBB->getSuccessors()) - if (!Visited.insert(Succ).second) - Worklist.push_back(Succ); - } - return false; -} - -static bool isForwardableEdge(SILBasicBlock *BB) { - if (auto *TI = BB->getTerminator()) { - if (isa(TI) || isa(TI)) - return true; - } - return false; -} - -//===----------------------------------------------------------------------===// -// Basic Block Location State -//===----------------------------------------------------------------------===// -namespace { - -/// forward declaration. -class RLEContext; -/// State of the load store in one basic block which allows for forwarding from -/// loads, stores -> loads -class BBState { - /// The basic block that we are optimizing. - SILBasicBlock *BB; - - /// A bit vector for which the ith bit represents the ith MemLocation in - /// MemLocationVault. If the bit is set, then the location currently has an - /// downward visible value. - llvm::BitVector ForwardSetIn; - - /// If ForwardSetOut changes while processing a basicblock, then all its - /// successors need to be rerun. - llvm::BitVector ForwardSetOut; - - /// This is map between MemLocations and their available values at the - /// beginning of this basic block. - ValueTableMap ForwardValIn; - - /// This is map between MemLocations and their available values at the end of - /// this basic block. - ValueTableMap ForwardValOut; - - /// Keeps a list of replaceable instructions in the current basic block as - /// well as their SILValue replacement. - llvm::DenseMap RedundantLoads; - - /// Check whether the ForwardSetOut has changed. If it does, we need to - /// rerun the data flow to reach fixed point. - bool updateForwardSetOut() { - bool Changed = (ForwardSetIn != ForwardSetOut); - // Reached the end of this basic block, update the end-of-block - // ForwardSetOut and ForwardValOut; - ForwardSetOut = ForwardSetIn; - ForwardValOut = ForwardValIn; - return Changed; - } - - /// Merge in the state of an individual predecessor. - void mergePredecessorState(BBState &OtherState); - - /// MemLocation read has been extracted, expanded and mapped to the bit - /// position in the bitvector. process it using the bit position. - void updateForwardSetForRead(RLEContext &Ctx, unsigned Bit, - LoadStoreValue Val); - - /// MemLocation written has been extracted, expanded and mapped to the bit - /// position in the bitvector. process it using the bit position. - void updateForwardSetForWrite(RLEContext &Ctx, unsigned Bit, - LoadStoreValue Val); - - /// There is a read to a MemLocation, expand the MemLocation into individual - /// fields before processing them. - void processRead(RLEContext &Ctx, SILInstruction *I, SILValue Mem, - SILValue Val, bool PF); - - /// There is a write to a MemLocation, expand the MemLocation into individual - /// fields before processing them. - void processWrite(RLEContext &Ctx, SILInstruction *I, SILValue Mem, - SILValue Val); - - /// BitVector manipulation fucntions. - void clearMemLocations(); - void startTrackingMemLocation(unsigned bit, LoadStoreValue Val); - void stopTrackingMemLocation(unsigned bit); - void updateTrackedMemLocation(unsigned bit, LoadStoreValue Val); - bool isTrackingMemLocation(unsigned bit); - -public: - BBState() = default; - - void init(SILBasicBlock *NewBB, unsigned bitcnt, bool reachable) { - BB = NewBB; - // The initial state of ForwardSetOut should be all 1's. Otherwise the - // dataflow solution could be too conservative. - // - // Consider this case, the forwardable value by var a = 10 before the loop - // will not be forwarded if the ForwardSetOut is set to 0 initially. - // - // var a = 10 - // for _ in 0...1024 {} - // use(a); - // - // However, by doing so, we can only do the data forwarding after the - // data flow stablizes. - // - ForwardSetIn.resize(bitcnt, false); - ForwardSetOut.resize(bitcnt, reachable); - } - - /// Returns the current basic block we are processing. - SILBasicBlock *getBB() const { return BB; } - - /// Returns the ForwardValIn for the current basic block. - ValueTableMap &getForwardValIn() { return ForwardValIn; } - - /// Returns the ForwardValOut for the current basic block. - ValueTableMap &getForwardValOut() { return ForwardValOut; } - - /// Returns the redundant loads and their replacement in the currently basic - /// block. - llvm::DenseMap &getRL() { return RedundantLoads; } - - bool optimize(RLEContext &Ctx, bool PF); - - /// Set up the value for redundant load elimination. - bool setupRLE(RLEContext &Ctx, SILInstruction *I, SILValue Mem); - - /// Merge in the states of all predecessors. - void mergePredecessorStates(RLEContext &Ctx); - - /// Process Instruction which writes to memory in an unknown way. - void processUnknownWriteInst(RLEContext &Ctx, SILInstruction *I); - - /// Process LoadInst. Extract MemLocations from LoadInst. - void processLoadInst(RLEContext &Ctx, LoadInst *LI, bool PF); - - /// Process LoadInst. Extract MemLocations from StoreInst. - void processStoreInst(RLEContext &Ctx, StoreInst *SI); - - /// Returns a *single* forwardable SILValue for the given MemLocation right - /// before the InsertPt instruction. - SILValue computeForwardingValues(RLEContext &Ctx, MemLocation &L, - SILInstruction *InsertPt, - bool UseForwardValOut); -}; - -} // end anonymous namespace - - -//===----------------------------------------------------------------------===// -// RLEContext Interface -//===----------------------------------------------------------------------===// - -namespace { - -/// This class stores global state that we use when computing redudant load and -/// their replacement in each basic block. -class RLEContext { - /// The alias analysis that we will use during all computations. - AliasAnalysis *AA; - - /// The range that we use to iterate over the reverse post order of the given - /// function. - PostOrderFunctionInfo::reverse_range ReversePostOrder; - - /// Keeps all the locations for the current function. The BitVector in each - /// BBState is then laid on top of it to keep track of which MemLocation - /// has a downward available value. - std::vector MemLocationVault; - - /// Caches a list of projection paths to leaf nodes in the given type. - TypeExpansionMap TypeExpansionCache; - - /// Contains a map between MemLocation to their index in the MemLocationVault. - /// Use for fast lookup. - llvm::DenseMap LocToBitIndex; - - /// A map from each BasicBlock to its BBState. - llvm::SmallDenseMap BBToLocState; - - /// A map for each basic block and whether its predecessors have forwardable - /// edges. - llvm::DenseMap ForwardableEdge; - -public: - RLEContext(SILFunction *F, AliasAnalysis *AA, - PostOrderFunctionInfo::reverse_range RPOT); - - RLEContext(const RLEContext &) = delete; - RLEContext(RLEContext &&) = default; - ~RLEContext() = default; - - bool run(); - - /// Returns the alias analysis we will use during all computations. - AliasAnalysis *getAA() const { return AA; } - - /// Returns the TypeExpansionCache we will use during expanding MemLocations. - TypeExpansionMap &getTypeExpansionCache() { return TypeExpansionCache; } - - /// Return the BBState for the basic block this basic block belongs to. - BBState &getBBLocState(SILBasicBlock *B) { return BBToLocState[B]; } - - /// Get the bit representing the MemLocation in the MemLocationVault. - unsigned getMemLocationBit(const MemLocation &L); - - /// Given the bit, get the MemLocation from the MemLocationVault. - MemLocation &getMemLocation(const unsigned index); - - /// Go to the predecessors of the given basic block, compute the value - /// for the given MemLocation. - SILValue computePredecessorCoveringValue(SILBasicBlock *B, MemLocation &L); - - /// Return true if all the predecessors of the basic block can have - /// BBArgument. - bool withTransistivelyForwardableEdges(SILBasicBlock *BB); - - /// Given a MemLocation, try to collect all the LoadStoreValues for this - /// MemLocation in the given basic block. If a LoadStoreValue is a covering - /// value, collectForwardingValues also create a SILArgument for it. As a - /// a result, collectForwardingValues may invalidate TerminatorInsts for - /// basic blocks. - /// - /// UseForwardValOut tells whether to use the ForwardValOut or not. i.e. - /// when materialize a covering value, we go to each predecessors and - /// collect forwarding values from their ForwardValOuts. - bool gatherValues(SILBasicBlock *B, MemLocation &L, MemLocationValueMap &Vs, - bool UseForwardValOut); -}; - -} // end anonymous namespace - -bool BBState::isTrackingMemLocation(unsigned bit) { - return ForwardSetIn.test(bit); -} - -void BBState::stopTrackingMemLocation(unsigned bit) { - ForwardSetIn.reset(bit); - ForwardValIn.erase(bit); -} - -void BBState::clearMemLocations() { - ForwardSetIn.reset(); - ForwardValIn.clear(); -} - -void BBState::startTrackingMemLocation(unsigned bit, LoadStoreValue Val) { - ForwardSetIn.set(bit); - ForwardValIn[bit] = Val; -} - -void BBState::updateTrackedMemLocation(unsigned bit, LoadStoreValue Val) { - ForwardValIn[bit] = Val; -} - -SILValue BBState::computeForwardingValues(RLEContext &Ctx, MemLocation &L, - SILInstruction *InsertPt, - bool UseForwardValOut) { - SILBasicBlock *ParentBB = InsertPt->getParent(); - bool IsTerminator = (InsertPt == ParentBB->getTerminator()); - // We do not have a SILValue for the current MemLocation, try to construct - // one. - // - // Collect the locations and their corresponding values into a map. - // First, collect current available locations and their corresponding values - // into a map. - MemLocationValueMap Values; - if (!Ctx.gatherValues(ParentBB, L, Values, UseForwardValOut)) - return SILValue(); - - // If the InsertPt is the terminator instruction of the basic block, we - // *refresh* it as terminator instruction could be deleted as a result - // of adding new edge values to the terminator instruction. - if (IsTerminator) - InsertPt = ParentBB->getTerminator(); - - // Second, reduce the available values into a single SILValue we can use to - // forward. - SILValue TheForwardingValue; - TheForwardingValue = MemLocation::reduceWithValues(L, &ParentBB->getModule(), - Values, InsertPt); - /// Return the forwarding value. - return TheForwardingValue; -} - -bool BBState::setupRLE(RLEContext &Ctx, SILInstruction *I, SILValue Mem) { - // Try to construct a SILValue for the current MemLocation. - // - // Collect the locations and their corresponding values into a map. - MemLocation L(Mem); - MemLocationValueMap Values; - if (!Ctx.gatherValues(I->getParent(), L, Values, false)) - return false; - - // Reduce the available values into a single SILValue we can use to forward. - SILModule *Mod = &I->getModule(); - SILValue TheForwardingValue; - TheForwardingValue = MemLocation::reduceWithValues(L, Mod, Values, I); - if (!TheForwardingValue) - return false; - - // Now we have the forwarding value, record it for forwarding!. - // - // NOTE: we do not perform the RLE right here because doing so could introduce - // new MemLocations. - // - // e.g. - // %0 = load %x - // %1 = load %x - // %2 = extract_struct %1, #a - // %3 = load %2 - // - // If we perform the RLE and replace %1 with %0, we end up having a memory - // location we do not have before, i.e. Base == %0, and Path == #a. - // - // We may be able to add the MemLocation to the vault, but it gets - // complicated very quickly, e.g. we need to resize the bit vectors size, - // etc. - // - // However, since we already know the instruction to replace and the value to - // replace it with, we can record it for now and forwarded it after all the - // forwardable values are recorded in the function. - // - RedundantLoads[I] = TheForwardingValue; - return true; -} - -void BBState::updateForwardSetForRead(RLEContext &Ctx, unsigned bit, - LoadStoreValue Val) { - // If there is already an available value for this location, use - // the existing value. - if (isTrackingMemLocation(bit)) - return; - - // Track the new location and value. - startTrackingMemLocation(bit, Val); -} - -void BBState::updateForwardSetForWrite(RLEContext &Ctx, unsigned bit, - LoadStoreValue Val) { - // This is a store. Invalidate any Memlocation that this location may - // alias, as their value can no longer be forwarded. - MemLocation &R = Ctx.getMemLocation(bit); - for (unsigned i = 0; i < ForwardSetIn.size(); ++i) { - if (!isTrackingMemLocation(i)) - continue; - MemLocation &L = Ctx.getMemLocation(i); - if (!L.isMayAliasMemLocation(R, Ctx.getAA())) - continue; - // MayAlias, invaliate the MemLocation. - stopTrackingMemLocation(i); - } - - // Start tracking this MemLocation. - startTrackingMemLocation(bit, Val); -} - -void BBState::processWrite(RLEContext &Ctx, SILInstruction *I, SILValue Mem, - SILValue Val) { - // Initialize the MemLocation. - MemLocation L(Mem); - - // If we cant figure out the Base or Projection Path for the write, - // process it as an unknown memory instruction. - if (!L.isValid()) { - processUnknownWriteInst(Ctx, I); - return; - } - - // Expand the given MemLocation and Val into individual fields and process - // them as separate writes. - MemLocationList Locs; - LoadStoreValueList Vals; - MemLocation::expandWithValues(L, Val, &I->getModule(), Locs, Vals); - for (unsigned i = 0; i < Locs.size(); ++i) { - updateForwardSetForWrite(Ctx, Ctx.getMemLocationBit(Locs[i]), Vals[i]); - } -} - -void BBState::processRead(RLEContext &Ctx, SILInstruction *I, SILValue Mem, - SILValue Val, bool PF) { - // Initialize the MemLocation. - MemLocation L(Mem); - - // If we cant figure out the Base or Projection Path for the read, simply - // ignore it for now. - if (!L.isValid()) - return; - - // Expand the given MemLocation and Val into individual fields and process - // them as separate reads. - MemLocationList Locs; - LoadStoreValueList Vals; - MemLocation::expandWithValues(L, Val, &I->getModule(), Locs, Vals); - - bool CanForward = true; - for (auto &X : Locs) { - CanForward &= isTrackingMemLocation(Ctx.getMemLocationBit(X)); - } - - // We do not have every location available, track the MemLocations and - // their values from this instruction, and return. - if (!CanForward) { - for (unsigned i = 0; i < Locs.size(); ++i) { - updateForwardSetForRead(Ctx, Ctx.getMemLocationBit(Locs[i]), Vals[i]); - } - return; - } - - // At this point, we have all the MemLocations and their values available. - // - // If we are not doing forwarding just yet, simply return. - if (!PF) - return; - - // Lastly, forward value to the load. - setupRLE(Ctx, I, Mem); -} - -void BBState::processStoreInst(RLEContext &Ctx, StoreInst *SI) { - processWrite(Ctx, SI, SI->getDest(), SI->getSrc()); -} - -void BBState::processLoadInst(RLEContext &Ctx, LoadInst *LI, bool PF) { - processRead(Ctx, LI, LI->getOperand(), SILValue(LI), PF); -} - -void BBState::processUnknownWriteInst(RLEContext &Ctx, SILInstruction *I) { - auto *AA = Ctx.getAA(); - for (unsigned i = 0; i < ForwardSetIn.size(); ++i) { - if (!isTrackingMemLocation(i)) - continue; - // Invalidate any location this instruction may write to. - // - // TODO: checking may alias with Base is overly conservative, - // we should check may alias with base plus projection path. - MemLocation &R = Ctx.getMemLocation(i); - if (!AA->mayWriteToMemory(I, R.getBase())) - continue; - // MayAlias. - stopTrackingMemLocation(i); - } -} - -/// Promote stored values to loads and merge duplicated loads. -bool BBState::optimize(RLEContext &Ctx, bool PF) { - for (auto &II : *BB) { - SILInstruction *Inst = &II; - DEBUG(llvm::dbgs() << " Visiting: " << *Inst); - - // This is a StoreInst, try to see whether it clobbers any forwarding - // value. - if (auto *SI = dyn_cast(Inst)) { - processStoreInst(Ctx, SI); - continue; - } - - // This is a LoadInst. Let's see if we can find a previous loaded, stored - // value to use instead of this load. - if (auto *LI = dyn_cast(Inst)) { - processLoadInst(Ctx, LI, PF); - continue; - } - - // If this instruction has side effects, but is inert from a load store - // perspective, skip it. - if (isRLEInertInstruction(Inst)) { - DEBUG(llvm::dbgs() << " Found inert instruction: " << *Inst); - continue; - } - - // If this instruction does not read or write memory, we can skip it. - if (!Inst->mayReadOrWriteMemory()) { - DEBUG(llvm::dbgs() << " Found readnone instruction, does not " - "affect loads and stores.\n"); - continue; - } - - // If we have an instruction that may write to memory and we can not prove - // that it and its operands can not alias a load we have visited, invalidate - // that load. - if (Inst->mayWriteToMemory()) { - processUnknownWriteInst(Ctx, Inst); - continue; - } - } - - // The basic block is finished, see whether there is a change in the - // ForwardSetOut set. - return updateForwardSetOut(); -} - -void BBState::mergePredecessorState(BBState &OtherState) { - // Merge in the predecessor state. - llvm::SmallVector LocDeleteList; - for (unsigned i = 0; i < ForwardSetIn.size(); ++i) { - if (OtherState.ForwardSetOut[i]) { - // There are multiple values from multiple predecessors, set this as - // a covering value. We do not need to track the value itself, as we - // can always go to the predecessors BBState to find it. - ForwardValIn[i].setCoveringValue(); - continue; - } - // If this location does have an available value, then clear it. - stopTrackingMemLocation(i); - } -} - -void BBState::mergePredecessorStates(RLEContext &Ctx) { - // Clear the state if the basic block has no predecessor. - if (BB->getPreds().begin() == BB->getPreds().end()) { - clearMemLocations(); - return; - } - - // We initialize the state with the first predecessor's state and merge - // in states of other predecessors. - bool HasAtLeastOnePred = false; - // For each predecessor of BB... - for (auto Pred : BB->getPreds()) { - BBState &Other = Ctx.getBBLocState(Pred); - - // If we have not had at least one predecessor, initialize BBState - // with the state of the initial predecessor. - // If BB is also a predecessor of itself, we should not initialize. - if (!HasAtLeastOnePred) { - ForwardSetIn = Other.ForwardSetOut; - ForwardValIn = Other.ForwardValOut; - } else { - mergePredecessorState(Other); - } - HasAtLeastOnePred = true; - } - -#ifndef NDEBUG - for (auto &X : ForwardValIn) { - (void)X; - assert(X.second.isValid() && "Invalid load store value"); - } -#endif -} - -//===----------------------------------------------------------------------===// -// RLEContext Implementation -//===----------------------------------------------------------------------===// - -RLEContext::RLEContext(SILFunction *F, AliasAnalysis *AA, - PostOrderFunctionInfo::reverse_range RPOT) - : AA(AA), ReversePostOrder(RPOT) { - // Walk over the function and find all the locations accessed by - // this function. - MemLocation::enumerateMemLocations(*F, MemLocationVault, LocToBitIndex, - TypeExpansionCache); - - // For all basic blocks in the function, initialize a BB state. Since we - // know all the locations accessed in this function, we can resize the bit - // vector to the approproate size. - for (auto &B : *F) { - BBToLocState[&B] = BBState(); - // We set the initial state of unreachable block to 0, as we do not have - // a value for the location. - // - // This is a bit conservative as we could be missing forwarding - // opportunities. i.e. a joint block with 1 predecessor being an - // unreachable block. - // - // we rely on other passes to clean up unreachable block. - BBToLocState[&B].init(&B, MemLocationVault.size(), isReachable(&B)); - } -} - -bool RLEContext::withTransistivelyForwardableEdges(SILBasicBlock *BB) { - // Have we processed this basic block before ? - if (ForwardableEdge.find(BB) != ForwardableEdge.end()) - return ForwardableEdge[BB]; - - // Look at all predecessors whether have forwardable edges. - llvm::DenseSet Visited; - llvm::SmallVector Worklist; - for (auto Pred : BB->getPreds()) { - Worklist.push_back(Pred); - Visited.insert(Pred); - } - - while (!Worklist.empty()) { - auto *CurBB = Worklist.back(); - Worklist.pop_back(); - - if (!isForwardableEdge(CurBB)) { - ForwardableEdge[BB] = false; - return false; - } - - for (auto Pred : CurBB->getPreds()) { - if (Visited.find(Pred) == Visited.end()) { - Visited.insert(Pred); - Worklist.push_back(Pred); - } - } - } - ForwardableEdge[BB] = true; - return true; -} - -SILValue RLEContext::computePredecessorCoveringValue(SILBasicBlock *BB, - MemLocation &L) { - // This is a covering value, need to go to each of the predecessors to - // materialize them and create a SILArgument to merge them. - // - // If any of the predecessors can not forward an edge value, bail out - // for now. - // - // *NOTE* This is a strong argument in favor of representing PHI nodes - // separately from SILArguments. - // - // TODO: we can create a trampoline basic block if the predecessor has - // a non-edgevalue terminator inst. - // - if (!withTransistivelyForwardableEdges(BB)) - return SILValue(); - - // At this point, we know this MemLocation has available value and we also - // know we can forward a SILValue from every predecesor. It is safe to - // insert the basic block argument. - BBState &Forwarder = getBBLocState(BB); - SILValue TheForwardingValue = BB->createBBArg(L.getType()); - - // For the given MemLocation, we just created a concrete value at the - // beginning of this basic block. Update the ForwardValOut for the - // current basic block. - // - // ForwardValOut keeps all the MemLocations and their forwarding values - // at the end of the basic block. If a MemLocation has a covering value - // at the end of the basic block, we can now replace the covering value with - // this concrete SILArgument. - // - // However, if the MemLocation has a concrete value, we know there must - // be an instruction that generated the concrete value between the current - // instruction and the end of the basic block, we do not update the - // ForwardValOut in this case. - // - // NOTE: This is necessary to prevent an infinite loop while materializing - // the covering value. - // - // Imagine an empty selfloop block with 1 predecessor having a load [A], to - // materialize [A]'s covering value, we go to its predecessors. However, - // the backedge will carry a covering value as well in this case. - // - MemLocationList Locs; - MemLocation::expand(L, &BB->getModule(), Locs, getTypeExpansionCache()); - LoadStoreValueList Vals; - MemLocation::expandWithValues(L, TheForwardingValue, &BB->getModule(), Locs, - Vals); - ValueTableMap &VTM = Forwarder.getForwardValOut(); - for (unsigned i = 0; i < Locs.size(); ++i) { - unsigned bit = getMemLocationBit(Locs[i]); - if (!VTM[bit].isCoveringValue()) - continue; - VTM[bit] = Vals[i]; - } - - // Compute the SILArgument for the covering value. - llvm::SmallVector Preds; - for (auto Pred : BB->getPreds()) { - Preds.push_back(Pred); - } - - llvm::DenseMap Args; - for (auto Pred : Preds) { - BBState &Forwarder = getBBLocState(Pred); - // Call computeForwardingValues with using ForwardValOut as we are - // computing the MemLocation value at the end of each predecessor. - Args[Pred] = Forwarder.computeForwardingValues(*this, L, - Pred->getTerminator(), true); - assert(Args[Pred] && "Fail to create a forwarding value"); - } - - // Create the new SILArgument and set ForwardingValue to it. - for (auto Pred : Preds) { - // Update all edges. We do not create new edges in between BBs so this - // information should always be correct. - addNewEdgeValueToBranch(Pred->getTerminator(), BB, Args[Pred]); - } - - return TheForwardingValue; -} - -MemLocation &RLEContext::getMemLocation(const unsigned index) { - return MemLocationVault[index]; -} - -unsigned RLEContext::getMemLocationBit(const MemLocation &Loc) { - // Return the bit position of the given Loc in the MemLocationVault. The bit - // position is then used to set/reset the bitvector kept by each BBState. - // - // We should have the location populated by the enumerateMemLocation at this - // point. - // - auto Iter = LocToBitIndex.find(Loc); - assert(Iter != LocToBitIndex.end() && - "MemLocation should have been enumerated"); - return Iter->second; -} - -bool RLEContext::gatherValues(SILBasicBlock *BB, MemLocation &L, - MemLocationValueMap &Values, - bool UseForwardValOut) { - MemLocationSet CSLocs; - MemLocationList Locs; - MemLocation::expand(L, &BB->getModule(), Locs, getTypeExpansionCache()); - // Are we using the ForwardVal at the end of the basic block or not. - // If we are collecting values at the end of the basic block, we can - // use its ForwardValOut. - // - BBState &Forwarder = getBBLocState(BB); - ValueTableMap &OTM = UseForwardValOut ? Forwarder.getForwardValOut() - : Forwarder.getForwardValIn(); - for (auto &X : Locs) { - Values[X] = OTM[getMemLocationBit(X)]; - if (!Values[X].isCoveringValue()) - continue; - CSLocs.insert(X); - } - - // Try to reduce it to the minimum # of locations possible, this will help - // us to generate as few extractions as possible. - MemLocation::reduce(L, &BB->getModule(), CSLocs); - - // To handle covering value, we need to go to the predecessors and - // materialize them there. - for (auto &X : CSLocs) { - SILValue V = computePredecessorCoveringValue(BB, X); - if (!V) - return false; - // We've constructed a concrete value for the covering value. Expand and - // collect the newly created forwardable values. - MemLocationList Locs; - LoadStoreValueList Vals; - MemLocation::expandWithValues(X, V, &BB->getModule(), Locs, Vals); - for (unsigned i = 0; i < Locs.size(); ++i) { - Values[Locs[i]] = Vals[i]; - assert(Values[Locs[i]].isValid() && "Invalid load store value"); - } - } - -// Sanity check to make sure we have valid load store values for each -// MemLocation. -#ifndef NDEBUG - for (auto &X : Locs) { - (void)X; - assert(Values[X].isValid() && "Invalid load store value"); - } -#endif - return true; -} - -bool RLEContext::run() { - // Process basic blocks in RPO. After the data flow converges, run last - // iteration and perform load forwarding. - bool LastIteration = false; - bool ForwardSetChanged = false; - do { - ForwardSetChanged = false; - for (SILBasicBlock *BB : ReversePostOrder) { - BBState &Forwarder = getBBLocState(BB); - - // Merge the predecessors. After merging, BBState now contains - // lists of available MemLocations and their values that reach the - // beginning of the basic block along all paths. - Forwarder.mergePredecessorStates(*this); - - // Merge duplicate loads, and forward stores to - // loads. We also update lists of stores|loads to reflect the end - // of the basic block. - ForwardSetChanged |= Forwarder.optimize(*this, LastIteration); - } - - // Last iteration completed, we are done here. - if (LastIteration) - break; - - // ForwardSetOut have not changed in any basic block. Run one last - // the data flow has converged, run last iteration and try to perform - // load forwarding. - // - if (!ForwardSetChanged) { - LastIteration = true; - } - - // ForwardSetOut in some basic blocks changed, rerun the data flow. - // - // TODO: We only need to rerun basic blocks with predecessors changed. - // use a worklist in the future. - // - } while (ForwardSetChanged || LastIteration); - - // Finally, perform the redundant load replacements. - llvm::DenseSet InstsToRemove; - bool SILChanged = false; - for (auto &X : BBToLocState) { - for (auto &F : X.second.getRL()) { - DEBUG(llvm::dbgs() << "Replacing " << SILValue(F.first) << "With " - << F.second); - SILChanged = true; - SILValue(F.first).replaceAllUsesWith(F.second); - InstsToRemove.insert(F.first); - ++NumForwardedLoads; - } - } - - // Erase the instructions recursively, this way, we get rid of pass - // dependence on DCE. - for (auto &X : InstsToRemove) { - // It is possible that the instruction still has uses, because it could be - // used as the replacement Value, i.e. F.second, for some other RLE pairs. - // - // TODO: we should fix this, otherwise we are missing RLE opportunities. - if (!X->use_empty()) - continue; - recursivelyDeleteTriviallyDeadInstructions(X, true); - } - return SILChanged; -} - -//===----------------------------------------------------------------------===// -// Top Level Entry Point -//===----------------------------------------------------------------------===// - -namespace { - -class RedundantLoadElimination : public SILFunctionTransform { - - /// The entry point to the transformation. - void run() override { - SILFunction *F = getFunction(); - DEBUG(llvm::dbgs() << "***** Redundant Load Elimination on function: " - << F->getName() << " *****\n"); - - auto *AA = PM->getAnalysis(); - auto *PO = PM->getAnalysis()->get(F); - - RLEContext RLE(F, AA, PO->getReversePostOrder()); - if (RLE.run()) { - invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions); - } - } - - StringRef getName() override { return "SIL Redundant Load Elimination"; } -}; - -} // end anonymous namespace - -SILTransform *swift::createRedundantLoadElimination() { - return new RedundantLoadElimination(); -} diff --git a/lib/SILPasses/UtilityPasses/AADumper.cpp b/lib/SILPasses/UtilityPasses/AADumper.cpp deleted file mode 100644 index 8fd74d2d73d5e..0000000000000 --- a/lib/SILPasses/UtilityPasses/AADumper.cpp +++ /dev/null @@ -1,160 +0,0 @@ -//===-------- AADumper.cpp - Compare all values in Function with AA -------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// -// This pass collects all values in a function and applies alias analysis to -// them. The purpose of this is to enable unit tests for SIL Alias Analysis -// implementations independent of any other passes. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-aa-evaluator" -#include "swift/SILPasses/Passes.h" -#include "swift/SIL/SILArgument.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILValue.h" -#include "swift/SILAnalysis/AliasAnalysis.h" -#include "swift/SILAnalysis/SideEffectAnalysis.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILPasses/Transforms.h" -#include "llvm/Support/Debug.h" - -using namespace swift; - -//===----------------------------------------------------------------------===// -// Value Gatherer -//===----------------------------------------------------------------------===// - -// Return a list of all instruction values in Fn. Returns true if we have at -// least two values to compare. -static bool gatherValues(SILFunction &Fn, std::vector &Values) { - for (auto &BB : Fn) { - for (auto *Arg : BB.getBBArgs()) - Values.push_back(SILValue(Arg)); - for (auto &II : BB) - for (unsigned i = 0, e = II.getNumTypes(); i != e; ++i) - Values.push_back(SILValue(&II, i)); - } - return Values.size() > 1; -} - -//===----------------------------------------------------------------------===// -// Top Level Driver -//===----------------------------------------------------------------------===// - -namespace { - -/// Dumps the alias relations between all instructions of a function. -class SILAADumper : public SILModuleTransform { - - void run() override { - for (auto &Fn: *getModule()) { - llvm::outs() << "@" << Fn.getName() << "\n"; - // Gather up all Values in Fn. - std::vector Values; - if (!gatherValues(Fn, Values)) - continue; - - AliasAnalysis *AA = PM->getAnalysis(); - - // A cache - llvm::DenseMap Results; - - // Emit the N^2 alias evaluation of the values. - unsigned PairCount = 0; - for (unsigned i1 = 0, e1 = Values.size(); i1 != e1; ++i1) { - for (unsigned i2 = 0, e2 = Values.size(); i2 != e2; ++i2) { - auto V1 = Values[i1]; - auto V2 = Values[i2]; - - auto Result = - AA->alias(V1, V2, computeTBAAType(V1), computeTBAAType(V2)); - - // Results should always be the same. But if they are different print - // it out so we find the error. This should make our test results less - // verbose. - uint64_t Key = uint64_t(i1) | (uint64_t(i2) << 32); - uint64_t OpKey = uint64_t(i2) | (uint64_t(i1) << 32); - auto R = Results.find(OpKey); - if (R != Results.end() && R->second == Result) - continue; - - Results[Key] = Result; - llvm::outs() << "PAIR #" << PairCount++ << ".\n" << V1 << V2 << Result - << "\n"; - } - } - llvm::outs() << "\n"; - } - } - - StringRef getName() override { return "AA Dumper"; } -}; - -/// Dumps the memory behavior of instructions in a function. -class MemBehaviorDumper : public SILModuleTransform { - - // To reduce the amount of output, we only dump the memory behavior of - // selected types of instructions. - static bool shouldTestInstruction(SILInstruction *I) { - // Only consider function calls. - if (FullApplySite::isa(I)) - return true; - - return false; - } - - void run() override { - for (auto &Fn: *getModule()) { - llvm::outs() << "@" << Fn.getName() << "\n"; - // Gather up all Values in Fn. - std::vector Values; - if (!gatherValues(Fn, Values)) - continue; - - AliasAnalysis *AA = PM->getAnalysis(); - SideEffectAnalysis *SEA = PM->getAnalysis(); - SEA->recompute(); - - unsigned PairCount = 0; - for (auto &BB : Fn) { - for (auto &I : BB) { - if (shouldTestInstruction(&I)) { - - // Print the memory behavior in relation to all other values in the - // function. - for (auto &V : Values) { - bool Read = AA->mayReadFromMemory(&I, V); - bool Write = AA->mayWriteToMemory(&I, V); - bool SideEffects = AA->mayHaveSideEffects(&I, V); - llvm::outs() << - "PAIR #" << PairCount++ << ".\n" << - " " << SILValue(&I) << - " " << V << - " r=" << Read << ",w=" << Write << ",se=" << SideEffects << "\n"; - } - } - } - } - llvm::outs() << "\n"; - } - } - - StringRef getName() override { return "Memory Behavior Dumper"; } -}; - -} // end anonymous namespace - -SILTransform *swift::createAADumper() { return new SILAADumper(); } - -SILTransform *swift::createMemBehaviorDumper() { - return new MemBehaviorDumper(); -} diff --git a/lib/SILPasses/UtilityPasses/CMakeLists.txt b/lib/SILPasses/UtilityPasses/CMakeLists.txt deleted file mode 100644 index e2ef568bfcc40..0000000000000 --- a/lib/SILPasses/UtilityPasses/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(UTILITYPASSES_SOURCES - UtilityPasses/AADumper.cpp - UtilityPasses/BasicCalleePrinter.cpp - UtilityPasses/CFGPrinter.cpp - UtilityPasses/CallGraphPrinter.cpp - UtilityPasses/FunctionOrderPrinter.cpp - UtilityPasses/IVInfoPrinter.cpp - UtilityPasses/InstCount.cpp - UtilityPasses/Link.cpp - UtilityPasses/LoopInfoPrinter.cpp - UtilityPasses/LoopCanonicalizer.cpp - UtilityPasses/LoopRegionPrinter.cpp - UtilityPasses/MemLocationPrinter.cpp - UtilityPasses/StripDebugInfo.cpp - UtilityPasses/UpdateEscapeAnalysis.cpp - UtilityPasses/UpdateSideEffects.cpp - PARENT_SCOPE) diff --git a/lib/SILPasses/UtilityPasses/CallGraphPrinter.cpp b/lib/SILPasses/UtilityPasses/CallGraphPrinter.cpp deleted file mode 100644 index 59e5e64f5a3a0..0000000000000 --- a/lib/SILPasses/UtilityPasses/CallGraphPrinter.cpp +++ /dev/null @@ -1,41 +0,0 @@ -//===----- CallGraphPrinter.cpp - Call graph printing pass ----*- C++ -*---===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// -// This pass prints the call graph for use in testing. -// -//===----------------------------------------------------------------------===// - -#include "swift/SILAnalysis/CallGraphAnalysis.h" -#include "swift/SILPasses/Transforms.h" - -using namespace swift; - -#define DEBUG_TYPE "call-graph-printer" - -namespace { - -class CallGraphPrinterPass : public SILModuleTransform { - /// The entry point to the transformation. - void run() override { - auto *CGA = getAnalysis(); - CallGraph &CG = CGA->getOrBuildCallGraph(); - CG.print(llvm::outs()); - CG.printStats(llvm::outs()); - } - StringRef getName() override { return "Call Graph Printer"; } -}; - -} // end anonymous namespace - -SILTransform *swift::createCallGraphPrinter() { - return new CallGraphPrinterPass(); -} diff --git a/lib/SILPasses/UtilityPasses/MemLocationPrinter.cpp b/lib/SILPasses/UtilityPasses/MemLocationPrinter.cpp deleted file mode 100644 index be4cb85fbf53b..0000000000000 --- a/lib/SILPasses/UtilityPasses/MemLocationPrinter.cpp +++ /dev/null @@ -1,217 +0,0 @@ -///===--- MemLocationPrinter.cpp - Dump all memory locations in program ---===// -/// -/// This source file is part of the Swift.org open source project -/// -/// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -/// Licensed under Apache License v2.0 with Runtime Library Exception -/// -/// See http://swift.org/LICENSE.txt for license information -/// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -/// -///===---------------------------------------------------------------------===// -/// -/// This pass tests type expansion, memlocation expansion and memlocation -/// reduction. -/// -///===---------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-memlocation-dumper" -#include "swift/SILPasses/Passes.h" -#include "swift/SIL/Projection.h" -#include "swift/SIL/MemLocation.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILValue.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILPasses/Transforms.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" - -using namespace swift; - -//===----------------------------------------------------------------------===// -// Top Level Driver -//===----------------------------------------------------------------------===// - -namespace { - -enum class MLKind : unsigned { - OnlyExpansion = 0, - OnlyReduction = 1, - OnlyTypeExpansion = 2, - All = 3, -}; - -} // end anonymous namespace - -static llvm::cl::opt MemLocationKinds( - "ml", llvm::cl::desc("MemLocation Kinds:"), llvm::cl::init(MLKind::All), - llvm::cl::values( - clEnumValN(MLKind::OnlyExpansion, "only-expansion", "only-expansion"), - clEnumValN(MLKind::OnlyReduction, "only-reduction", "only-reduction"), - clEnumValN(MLKind::OnlyTypeExpansion, "only-type-expansion", - "only-type-expansion"), - clEnumValN(MLKind::All, "all", "all"), clEnumValEnd)); - -namespace { - -class MemLocationPrinter : public SILModuleTransform { - - /// Dumps the expansions of SILType accessed in the function. - /// This tests the expandTypeIntoLeafProjectionPaths function, which is - /// a function used extensively in expand and reduce functions. - /// - /// We test it to catch any suspicious things in the earliest point. - /// - void printTypeExpansion(SILFunction &Fn) { - SILModule *M = &Fn.getModule(); - ProjectionPathList PPList; - unsigned Counter = 0; - for (auto &BB : Fn) { - for (auto &II : BB) { - if (auto *LI = dyn_cast(&II)) { - SILValue V = LI->getOperand(); - // This is an address type, take it object type. - SILType Ty = V.getType().getObjectType(); - ProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList, - true); - } else if (auto *SI = dyn_cast(&II)) { - SILValue V = SI->getDest(); - // This is an address type, take it object type. - SILType Ty = V.getType().getObjectType(); - ProjectionPath::expandTypeIntoLeafProjectionPaths(Ty, M, PPList, - true); - } else { - // Not interested in these instructions yet. - continue; - } - - llvm::outs() << "#" << Counter++ << II; - for (auto &T : PPList) { - llvm::outs() << T.getValue(); - } - PPList.clear(); - } - } - llvm::outs() << "\n"; - } - - /// Dumps the expansions of memory locations accessed in the function. - /// This tests the expand function in MemLocation class. - /// - /// We test it to catch any suspicious things when memory location is - /// expanded, i.e. base is traced back and aggregate is expanded - /// properly. - void printMemExpansion(SILFunction &Fn) { - MemLocation L; - TypeExpansionMap Types; - MemLocationList Locs; - unsigned Counter = 0; - for (auto &BB : Fn) { - for (auto &II : BB) { - if (auto *LI = dyn_cast(&II)) { - L.initialize(LI->getOperand()); - if (!L.isValid()) - continue; - MemLocation::expand(L, &Fn.getModule(), Locs, Types); - } else if (auto *SI = dyn_cast(&II)) { - L.initialize(SI->getDest()); - if (!L.isValid()) - continue; - MemLocation::expand(L, &Fn.getModule(), Locs, Types); - } else { - // Not interested in these instructions yet. - continue; - } - - llvm::outs() << "#" << Counter++ << II; - for (auto &Loc : Locs) { - Loc.print(); - } - L.reset(); - Locs.clear(); - } - } - llvm::outs() << "\n"; - } - - /// Dumps the reductions of set of memory locations. - /// - /// This function first calls expand on a memory location. It then calls - /// reduce, in hope to get the original memory location back. - /// - void printMemReduction(SILFunction &Fn) { - MemLocation L; - MemLocationList Locs; - TypeExpansionMap Types; - llvm::DenseSet SLocs; - unsigned Counter = 0; - for (auto &BB : Fn) { - for (auto &II : BB) { - - // Expand it first. - // - if (auto *LI = dyn_cast(&II)) { - L.initialize(LI->getOperand()); - if (!L.isValid()) - continue; - MemLocation::expand(L, &Fn.getModule(), Locs, Types); - } else if (auto *SI = dyn_cast(&II)) { - L.initialize(SI->getDest()); - if (!L.isValid()) - continue; - MemLocation::expand(L, &Fn.getModule(), Locs, Types); - } else { - // Not interested in these instructions yet. - continue; - } - - // Try to reduce it. - // - // Add into the set in reverse order, Reduction should not care - // about the order of the memory locations in the set. - for (auto I = Locs.rbegin(); I != Locs.rend(); ++I) { - SLocs.insert(*I); - } - // This should get the original (unexpanded) location back. - MemLocation::reduce(L, &Fn.getModule(), SLocs); - llvm::outs() << "#" << Counter++ << II; - for (auto &Loc : SLocs) { - Loc.print(); - } - L.reset(); - Locs.clear(); - SLocs.clear(); - } - } - llvm::outs() << "\n"; - } - - void run() override { - for (auto &Fn : *getModule()) { - if (Fn.isExternalDeclaration()) continue; - - llvm::outs() << "@" << Fn.getName() << "\n"; - switch (MemLocationKinds) { - case MLKind::OnlyTypeExpansion: - printTypeExpansion(Fn); - break; - case MLKind::OnlyExpansion: - printMemExpansion(Fn); - break; - case MLKind::OnlyReduction: - printMemReduction(Fn); - break; - default: - break; - } - } - } - - StringRef getName() override { return "Mem Location Dumper"; } -}; - -} // end anonymous namespace - -SILTransform *swift::createMemLocationPrinter() { - return new MemLocationPrinter(); -} diff --git a/lib/SILPasses/UtilityPasses/UpdateEscapeAnalysis.cpp b/lib/SILPasses/UtilityPasses/UpdateEscapeAnalysis.cpp deleted file mode 100644 index b30982cfcb3cb..0000000000000 --- a/lib/SILPasses/UtilityPasses/UpdateEscapeAnalysis.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//===------- UpdateEscapeAnalysis.cpp - Computes the escape analysis ------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "update-ea" -#include "swift/SILPasses/Passes.h" -#include "swift/SILAnalysis/EscapeAnalysis.h" -#include "swift/SILPasses/Transforms.h" -#include "llvm/Support/CommandLine.h" - -using namespace swift; - -namespace { - -#ifndef NDEBUG -llvm::cl::opt PrintEscapes("sil-print-escapes", - llvm::cl::desc("Print the result of the escape analysis"), - llvm::cl::init(false)); -#endif - -/// Recomputes the escape information for all functions in the module. -/// For details see EscapeAnalysis. -class UpdateEscapeAnalysis : public SILModuleTransform { - - void run() override { - - DEBUG(llvm::dbgs() << "** UpdateEscapeAnalysis **\n"); - - auto *EA = PM->getAnalysis(); - EA->recompute(); - -#ifndef NDEBUG - if (PrintEscapes) { - llvm::outs() << "Escape information of module\n"; - for (auto &F : *getModule()) { - if (!F.isExternalDeclaration()) { - if (auto *ConnectionGraph = EA->getConnectionGraph(&F)) { - ConnectionGraph->computeUsePoints(); - ConnectionGraph->print(llvm::outs()); - } - } - } - } -#endif - } - - StringRef getName() override { return "UpdateEscapeAnalysis"; } -}; - -} // end anonymous namespace - -SILTransform *swift::createUpdateEscapeAnalysis() { - return new UpdateEscapeAnalysis(); -} diff --git a/lib/SILPasses/UtilityPasses/UpdateSideEffects.cpp b/lib/SILPasses/UtilityPasses/UpdateSideEffects.cpp deleted file mode 100644 index 968fa603c5ec9..0000000000000 --- a/lib/SILPasses/UtilityPasses/UpdateSideEffects.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===------ UpdateSideEffects.cpp - Computes the side effect analysis -----===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "update-sea" -#include "swift/SILPasses/Passes.h" -#include "swift/SILAnalysis/SideEffectAnalysis.h" -#include "swift/SILPasses/Transforms.h" -#include "llvm/Support/CommandLine.h" - -using namespace swift; - -namespace { - -#ifndef NDEBUG -llvm::cl::opt PrintSideEffects("sil-print-side-effects", - llvm::cl::desc("Print the result of the side-effect analysis"), - llvm::cl::init(false)); -#endif - -/// Recomputes the side-effect information for all functions in the module. -/// For details see SideEffectAnalysis. -class UpdateSideEffects : public SILModuleTransform { - - void run() override { - - DEBUG(llvm::dbgs() << "** UpdateSideEffects **\n"); - - auto *SEA = PM->getAnalysis(); - SEA->recompute(); - -#ifndef NDEBUG - if (PrintSideEffects) { - llvm::outs() << "Side effects of module\n"; - for (auto &F : *getModule()) { - llvm::outs() << " sil @" << F.getName() << '\n'; - const auto &Effects = SEA->getEffects(&F); - llvm::outs() << " <" << Effects << ">\n"; - } - } -#endif - } - - StringRef getName() override { return "UpdateSideEffects"; } -}; - -} // end anonymous namespace - -SILTransform *swift::createUpdateSideEffects() { - return new UpdateSideEffects(); -} diff --git a/lib/SILPasses/Utils/CFG.cpp b/lib/SILPasses/Utils/CFG.cpp deleted file mode 100644 index 9afc821ac8b09..0000000000000 --- a/lib/SILPasses/Utils/CFG.cpp +++ /dev/null @@ -1,788 +0,0 @@ -//===--- CFG.cpp - Utilities for SIL CFG transformations --------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#include "swift/SIL/Dominance.h" -#include "swift/SIL/LoopInfo.h" -#include "swift/SIL/SILArgument.h" -#include "swift/SIL/SILBuilder.h" -#include "swift/SILPasses/Utils/CFG.h" - -using namespace swift; - -/// \brief Adds a new argument to an edge between a branch and a destination -/// block. -/// -/// \param Branch The terminator to add the argument to. -/// \param Dest The destination block of the edge. -/// \param Val The value to the arguments of the branch. -/// \return The created branch. The old branch is deleted. -/// The argument is appended at the end of the argument tuple. -TermInst *swift::addNewEdgeValueToBranch(TermInst *Branch, SILBasicBlock *Dest, - SILValue Val) { - SILBuilderWithScope Builder(Branch); - TermInst *NewBr = nullptr; - - if (CondBranchInst *CBI = dyn_cast(Branch)) { - SmallVector TrueArgs; - SmallVector FalseArgs; - - for (auto A : CBI->getTrueArgs()) - TrueArgs.push_back(A); - - for (auto A : CBI->getFalseArgs()) - FalseArgs.push_back(A); - - if (Dest == CBI->getTrueBB()) { - TrueArgs.push_back(Val); - assert(TrueArgs.size() == Dest->getNumBBArg()); - } - if (Dest == CBI->getFalseBB()) { - FalseArgs.push_back(Val); - assert(FalseArgs.size() == Dest->getNumBBArg()); - } - - NewBr = Builder.createCondBranch(CBI->getLoc(), CBI->getCondition(), - CBI->getTrueBB(), TrueArgs, - CBI->getFalseBB(), FalseArgs); - } else if (BranchInst *BI = dyn_cast(Branch)) { - SmallVector Args; - - for (auto A : BI->getArgs()) - Args.push_back(A); - - Args.push_back(Val); - assert(Args.size() == Dest->getNumBBArg()); - NewBr = Builder.createBranch(BI->getLoc(), BI->getDestBB(), Args); - } else { - NewBr->dump(); - // At the moment we can only add arguments to br and cond_br. - llvm_unreachable("Can't add argument to terminator"); - return NewBr; - } - - Branch->dropAllReferences(); - Branch->eraseFromParent(); - - return NewBr; -} - -/// \brief Changes the edge value between a branch and destination basic block -/// at the specified index. Changes all edges from \p Branch to \p Dest to carry -/// the value. -/// -/// \param Branch The branch to modify. -/// \param Dest The destination of the edge. -/// \param Idx The index of the argument to modify. -/// \param Val The new value to use. -/// \return The new branch. Deletes the old one. -/// Changes the edge value between a branch and destination basic block at the -/// specified index. -TermInst *swift::changeEdgeValue(TermInst *Branch, SILBasicBlock *Dest, - size_t Idx, SILValue Val) { - SILBuilderWithScope Builder(Branch); - - if (CondBranchInst *CBI = dyn_cast(Branch)) { - SmallVector TrueArgs; - SmallVector FalseArgs; - - OperandValueArrayRef OldTrueArgs = CBI->getTrueArgs(); - bool BranchOnTrue = CBI->getTrueBB() == Dest; - assert((!BranchOnTrue || Idx < OldTrueArgs.size()) && "Not enough edges"); - - // Copy the edge values overwritting the edge at Idx. - for (unsigned i = 0, e = OldTrueArgs.size(); i != e; ++i) { - if (BranchOnTrue && Idx == i) - TrueArgs.push_back(Val); - else - TrueArgs.push_back(OldTrueArgs[i]); - } - assert(TrueArgs.size() == CBI->getTrueBB()->getNumBBArg() && - "Destination block's number of arguments must match"); - - OperandValueArrayRef OldFalseArgs = CBI->getFalseArgs(); - bool BranchOnFalse = CBI->getFalseBB() == Dest; - assert((!BranchOnFalse || Idx < OldFalseArgs.size()) && "Not enough edges"); - - // Copy the edge values overwritting the edge at Idx. - for (unsigned i = 0, e = OldFalseArgs.size(); i != e; ++i) { - if (BranchOnFalse && Idx == i) - FalseArgs.push_back(Val); - else - FalseArgs.push_back(OldFalseArgs[i]); - } - assert(FalseArgs.size() == CBI->getFalseBB()->getNumBBArg() && - "Destination block's number of arguments must match"); - - CBI = Builder.createCondBranch(CBI->getLoc(), CBI->getCondition(), - CBI->getTrueBB(), TrueArgs, - CBI->getFalseBB(), FalseArgs); - Branch->dropAllReferences(); - Branch->eraseFromParent(); - return CBI; - } - - if (BranchInst *BI = dyn_cast(Branch)) { - SmallVector Args; - - assert(Idx < BI->getNumArgs() && "Not enough edges"); - OperandValueArrayRef OldArgs = BI->getArgs(); - - // Copy the edge values overwritting the edge at Idx. - for (unsigned i = 0, e = OldArgs.size(); i != e; ++i) { - if (Idx == i) - Args.push_back(Val); - else - Args.push_back(OldArgs[i]); - } - assert(Args.size() == Dest->getNumBBArg()); - - BI = Builder.createBranch(BI->getLoc(), BI->getDestBB(), Args); - Branch->dropAllReferences(); - Branch->eraseFromParent(); - return BI; - } - - llvm_unreachable("Unhandled terminator leading to merge block"); -} - -template -SILBasicBlock *replaceSwitchDest(SwitchEnumTy *S, - SmallVectorImpl &Cases, - unsigned EdgeIdx, SILBasicBlock *NewDest) { - auto *DefaultBB = S->hasDefault() ? S->getDefaultBB() : nullptr; - for (unsigned i = 0, e = S->getNumCases(); i != e; ++i) - if (EdgeIdx != i) - Cases.push_back(S->getCase(i)); - else - Cases.push_back(std::make_pair(S->getCase(i).first, NewDest)); - if (EdgeIdx == S->getNumCases()) - DefaultBB = NewDest; - return DefaultBB; -} - -void swift::changeBranchTarget(TermInst *T, unsigned EdgeIdx, - SILBasicBlock *NewDest, bool PreserveArgs) { - SILBuilderWithScope B(T); - - switch (T->getKind()) { -#define TERMINATOR(ID, PARENT, MEM, RELEASE) -#define VALUE(ID, PARENT) case ValueKind::ID: -#include "swift/SIL/SILNodes.def" - llvm_unreachable("Unexpected terminator instruction!"); - // Only Branch and CondBranch may have arguments. - case ValueKind::BranchInst: { - auto Br = dyn_cast(T); - SmallVector Args; - if (PreserveArgs) { - for (auto Arg : Br->getArgs()) - Args.push_back(Arg); - } - B.createBranch(T->getLoc(), NewDest, Args); - Br->dropAllReferences(); - Br->eraseFromParent(); - return; - } - - case ValueKind::CondBranchInst: { - auto CondBr = dyn_cast(T); - SmallVector TrueArgs; - if (EdgeIdx == CondBranchInst::FalseIdx || PreserveArgs) { - for (auto Arg : CondBr->getTrueArgs()) - TrueArgs.push_back(Arg); - } - SmallVector FalseArgs; - if (EdgeIdx == CondBranchInst::TrueIdx || PreserveArgs) { - for (auto Arg : CondBr->getFalseArgs()) - FalseArgs.push_back(Arg); - } - SILBasicBlock *TrueDest = CondBr->getTrueBB(); - SILBasicBlock *FalseDest = CondBr->getFalseBB(); - if (EdgeIdx == CondBranchInst::TrueIdx) - TrueDest = NewDest; - else - FalseDest = NewDest; - - B.createCondBranch(CondBr->getLoc(), CondBr->getCondition(), - TrueDest, TrueArgs, FalseDest, FalseArgs); - CondBr->dropAllReferences(); - CondBr->eraseFromParent(); - return; - } - - case ValueKind::SwitchValueInst: { - auto SII = dyn_cast(T); - SmallVector, 8> Cases; - auto *DefaultBB = replaceSwitchDest(SII, Cases, EdgeIdx, NewDest); - B.createSwitchValue(SII->getLoc(), SII->getOperand(), DefaultBB, Cases); - SII->eraseFromParent(); - return; - } - - case ValueKind::SwitchEnumInst: { - auto SEI = dyn_cast(T); - SmallVector, 8> Cases; - auto *DefaultBB = replaceSwitchDest(SEI, Cases, EdgeIdx, NewDest); - B.createSwitchEnum(SEI->getLoc(), SEI->getOperand(), DefaultBB, Cases); - SEI->eraseFromParent(); - return; - } - - case ValueKind::SwitchEnumAddrInst: { - auto SEI = dyn_cast(T); - SmallVector, 8> Cases; - auto *DefaultBB = replaceSwitchDest(SEI, Cases, EdgeIdx, NewDest); - B.createSwitchEnumAddr(SEI->getLoc(), SEI->getOperand(), DefaultBB, Cases); - SEI->eraseFromParent(); - return; - } - - case ValueKind::DynamicMethodBranchInst: { - auto DMBI = dyn_cast(T); - assert(EdgeIdx == 0 || EdgeIdx == 1 && "Invalid edge index"); - auto HasMethodBB = !EdgeIdx ? NewDest : DMBI->getHasMethodBB(); - auto NoMethodBB = EdgeIdx ? NewDest : DMBI->getNoMethodBB(); - B.createDynamicMethodBranch(DMBI->getLoc(), DMBI->getOperand(), - DMBI->getMember(), HasMethodBB, NoMethodBB); - DMBI->eraseFromParent(); - return; - } - - case ValueKind::CheckedCastBranchInst: { - auto CBI = dyn_cast(T); - assert(EdgeIdx == 0 || EdgeIdx == 1 && "Invalid edge index"); - auto SuccessBB = !EdgeIdx ? NewDest : CBI->getSuccessBB(); - auto FailureBB = EdgeIdx ? NewDest : CBI->getFailureBB(); - B.createCheckedCastBranch(CBI->getLoc(), CBI->isExact(), CBI->getOperand(), - CBI->getCastType(), SuccessBB, FailureBB); - CBI->eraseFromParent(); - return; - } - - case ValueKind::CheckedCastAddrBranchInst: { - auto CBI = dyn_cast(T); - assert(EdgeIdx == 0 || EdgeIdx == 1 && "Invalid edge index"); - auto SuccessBB = !EdgeIdx ? NewDest : CBI->getSuccessBB(); - auto FailureBB = EdgeIdx ? NewDest : CBI->getFailureBB(); - B.createCheckedCastAddrBranch(CBI->getLoc(), CBI->getConsumptionKind(), - CBI->getSrc(), CBI->getSourceType(), - CBI->getDest(), CBI->getTargetType(), - SuccessBB, FailureBB); - CBI->eraseFromParent(); - return; - } - - case ValueKind::TryApplyInst: { - auto *TAI = dyn_cast(T); - assert((EdgeIdx == 0 || EdgeIdx == 1) && "Invalid edge index"); - auto *NormalBB = !EdgeIdx ? NewDest : TAI->getNormalBB(); - auto *ErrorBB = EdgeIdx ? NewDest : TAI->getErrorBB(); - SmallVector Arguments; - for (auto &Op : TAI->getArgumentOperands()) - Arguments.push_back(Op.get()); - - B.createTryApply(TAI->getLoc(), TAI->getCallee(), - TAI->getSubstCalleeSILType(), TAI->getSubstitutions(), - Arguments, NormalBB, ErrorBB); - - TAI->eraseFromParent(); - return; - } - - case ValueKind::AutoreleaseReturnInst: - case ValueKind::ReturnInst: - case ValueKind::ThrowInst: - case ValueKind::UnreachableInst: - llvm_unreachable("Branch target cannot be changed for this terminator instruction!"); - } - llvm_unreachable("Not yet implemented!"); -} - - -template -SILBasicBlock *replaceSwitchDest(SwitchEnumTy *S, - SmallVectorImpl &Cases, - SILBasicBlock *OldDest, SILBasicBlock *NewDest) { - auto *DefaultBB = S->hasDefault() ? S->getDefaultBB() : nullptr; - for (unsigned i = 0, e = S->getNumCases(); i != e; ++i) - if (S->getCase(i).second != OldDest) - Cases.push_back(S->getCase(i)); - else - Cases.push_back(std::make_pair(S->getCase(i).first, NewDest)); - if (OldDest == DefaultBB) - DefaultBB = NewDest; - return DefaultBB; -} - -/// \brief Replace a branch target. -/// -/// \param T The terminating instruction to modify. -/// \param OldDest The successor block that will be replaced. -/// \param NewDest The new target block. -/// \param PreserveArgs If set, preserve arguments on the replaced edge. -void swift::replaceBranchTarget(TermInst *T, SILBasicBlock *OldDest, - SILBasicBlock *NewDest, bool PreserveArgs) { - SILBuilderWithScope B(T); - - switch (T->getKind()) { -#define TERMINATOR(ID, PARENT, MEM, RELEASE) -#define VALUE(ID, PARENT) case ValueKind::ID: -#include "swift/SIL/SILNodes.def" - llvm_unreachable("Unexpected terminator instruction!"); - // Only Branch and CondBranch may have arguments. - case ValueKind::BranchInst: { - auto Br = dyn_cast(T); - SmallVector Args; - if (PreserveArgs) { - for (auto Arg : Br->getArgs()) - Args.push_back(Arg); - } - B.createBranch(T->getLoc(), NewDest, Args); - Br->dropAllReferences(); - Br->eraseFromParent(); - return; - } - - case ValueKind::CondBranchInst: { - auto CondBr = dyn_cast(T); - SmallVector TrueArgs; - if (OldDest == CondBr->getFalseBB() || PreserveArgs) { - for (auto Arg : CondBr->getTrueArgs()) - TrueArgs.push_back(Arg); - } - SmallVector FalseArgs; - if (OldDest == CondBr->getTrueBB() || PreserveArgs) { - for (auto Arg : CondBr->getFalseArgs()) - FalseArgs.push_back(Arg); - } - SILBasicBlock *TrueDest = CondBr->getTrueBB(); - SILBasicBlock *FalseDest = CondBr->getFalseBB(); - if (OldDest == CondBr->getTrueBB()) - TrueDest = NewDest; - else - FalseDest = NewDest; - - B.createCondBranch(CondBr->getLoc(), CondBr->getCondition(), - TrueDest, TrueArgs, FalseDest, FalseArgs); - CondBr->dropAllReferences(); - CondBr->eraseFromParent(); - return; - } - - case ValueKind::SwitchValueInst: { - auto SII = dyn_cast(T); - SmallVector, 8> Cases; - auto *DefaultBB = replaceSwitchDest(SII, Cases, OldDest, NewDest); - B.createSwitchValue(SII->getLoc(), SII->getOperand(), DefaultBB, Cases); - SII->eraseFromParent(); - return; - } - - case ValueKind::SwitchEnumInst: { - auto SEI = dyn_cast(T); - SmallVector, 8> Cases; - auto *DefaultBB = replaceSwitchDest(SEI, Cases, OldDest, NewDest); - B.createSwitchEnum(SEI->getLoc(), SEI->getOperand(), DefaultBB, Cases); - SEI->eraseFromParent(); - return; - } - - case ValueKind::SwitchEnumAddrInst: { - auto SEI = dyn_cast(T); - SmallVector, 8> Cases; - auto *DefaultBB = replaceSwitchDest(SEI, Cases, OldDest, NewDest); - B.createSwitchEnumAddr(SEI->getLoc(), SEI->getOperand(), DefaultBB, Cases); - SEI->eraseFromParent(); - return; - } - - case ValueKind::DynamicMethodBranchInst: { - auto DMBI = dyn_cast(T); - assert(OldDest == DMBI->getHasMethodBB() || OldDest == DMBI->getNoMethodBB() && "Invalid edge index"); - auto HasMethodBB = OldDest == DMBI->getHasMethodBB() ? NewDest : DMBI->getHasMethodBB(); - auto NoMethodBB = OldDest == DMBI->getNoMethodBB() ? NewDest : DMBI->getNoMethodBB(); - B.createDynamicMethodBranch(DMBI->getLoc(), DMBI->getOperand(), - DMBI->getMember(), HasMethodBB, NoMethodBB); - DMBI->eraseFromParent(); - return; - } - - case ValueKind::CheckedCastBranchInst: { - auto CBI = dyn_cast(T); - assert(OldDest == CBI->getSuccessBB() || OldDest == CBI->getFailureBB() && "Invalid edge index"); - auto SuccessBB = OldDest == CBI->getSuccessBB() ? NewDest : CBI->getSuccessBB(); - auto FailureBB = OldDest == CBI->getFailureBB() ? NewDest : CBI->getFailureBB(); - B.createCheckedCastBranch(CBI->getLoc(), CBI->isExact(), CBI->getOperand(), - CBI->getCastType(), SuccessBB, FailureBB); - CBI->eraseFromParent(); - return; - } - - case ValueKind::CheckedCastAddrBranchInst: { - auto CBI = dyn_cast(T); - assert(OldDest == CBI->getSuccessBB() || OldDest == CBI->getFailureBB() && "Invalid edge index"); - auto SuccessBB = OldDest == CBI->getSuccessBB() ? NewDest : CBI->getSuccessBB(); - auto FailureBB = OldDest == CBI->getFailureBB() ? NewDest : CBI->getFailureBB(); - B.createCheckedCastAddrBranch(CBI->getLoc(), CBI->getConsumptionKind(), - CBI->getSrc(), CBI->getSourceType(), - CBI->getDest(), CBI->getTargetType(), - SuccessBB, FailureBB); - CBI->eraseFromParent(); - return; - } - - case ValueKind::AutoreleaseReturnInst: - case ValueKind::ReturnInst: - case ValueKind::ThrowInst: - case ValueKind::TryApplyInst: - case ValueKind::UnreachableInst: - llvm_unreachable("Branch target cannot be replaced for this terminator instruction!"); - } - llvm_unreachable("Not yet implemented!"); -} - -/// \brief Check if the edge from the terminator is critical. -bool swift::isCriticalEdge(TermInst *T, unsigned EdgeIdx) { - assert(T->getSuccessors().size() > EdgeIdx && "Not enough successors"); - - auto SrcSuccs = T->getSuccessors(); - if (SrcSuccs.size() <= 1) - return false; - - SILBasicBlock *DestBB = SrcSuccs[EdgeIdx]; - assert(!DestBB->pred_empty() && "There should be a predecessor"); - if (DestBB->getSinglePredecessor()) - return false; - - return true; -} - -template -SILBasicBlock *getNthEdgeBlock(SwitchInstTy *S, unsigned EdgeIdx) { - if (S->getNumCases() == EdgeIdx) - return S->getDefaultBB(); - return S->getCase(EdgeIdx).second; -} - -static void getEdgeArgs(TermInst *T, unsigned EdgeIdx, SILBasicBlock *NewEdgeBB, - SmallVectorImpl &Args) { - if (auto Br = dyn_cast(T)) { - for (auto V : Br->getArgs()) - Args.push_back(V); - return; - } - - if (auto CondBr = dyn_cast(T)) { - assert(EdgeIdx < 2); - auto OpdArgs = EdgeIdx ? CondBr->getFalseArgs() : CondBr->getTrueArgs(); - for (auto V: OpdArgs) - Args.push_back(V); - return; - } - - if (auto SEI = dyn_cast(T)) { - auto *SuccBB = getNthEdgeBlock(SEI, EdgeIdx); - assert(SuccBB->getNumBBArg() == 0 && "Can't take an argument"); - (void) SuccBB; - return; - } - - // A switch_enum can implicitly pass the enum payload. We need to look at the - // destination block to figure this out. - if (auto SEI = dyn_cast(T)) { - auto *SuccBB = getNthEdgeBlock(SEI, EdgeIdx); - assert(SuccBB->getNumBBArg() < 2 && "Can take at most one argument"); - if (!SuccBB->getNumBBArg()) - return; - Args.push_back( - SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); - return; - } - - // A dynamic_method_br passes the function to the first basic block. - if (auto DMBI = dyn_cast(T)) { - auto *SuccBB = - (EdgeIdx == 0) ? DMBI->getHasMethodBB() : DMBI->getNoMethodBB(); - if (!SuccBB->getNumBBArg()) - return; - Args.push_back( - SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); - return; - } - - /// A checked_cast_br passes the result of the cast to the first basic block. - if (auto CBI = dyn_cast(T)) { - auto SuccBB = EdgeIdx == 0 ? CBI->getSuccessBB() : CBI->getFailureBB(); - if (!SuccBB->getNumBBArg()) - return; - Args.push_back( - SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); - return; - } - if (auto CBI = dyn_cast(T)) { - auto SuccBB = EdgeIdx == 0 ? CBI->getSuccessBB() : CBI->getFailureBB(); - if (!SuccBB->getNumBBArg()) - return; - Args.push_back( - SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); - return; - } - - if (auto *TAI = dyn_cast(T)) { - auto *SuccBB = EdgeIdx == 0 ? TAI->getNormalBB() : TAI->getErrorBB(); - if (!SuccBB->getNumBBArg()) - return; - Args.push_back( - SILValue(NewEdgeBB->createBBArg(SuccBB->getBBArg(0)->getType()), 0)); - return; - } - - // For now this utility is only used to split critical edges involving - // cond_br. - llvm_unreachable("Not yet implemented"); -} - -/// Splits the basic block at the iterator with an unconditional branch and -/// updates the dominator tree and loop info. -SILBasicBlock *swift::splitBasicBlockAndBranch(SILBuilder &B, - SILInstruction *SplitBeforeInst, - DominanceInfo *DT, - SILLoopInfo *LI) { - auto *OrigBB = SplitBeforeInst->getParent(); - auto *NewBB = OrigBB->splitBasicBlock(SplitBeforeInst->getIterator()); - B.setInsertionPoint(OrigBB); - B.createBranch(SplitBeforeInst->getLoc(), NewBB); - - // Update the dominator tree. - if (DT) { - auto OrigBBDTNode = DT->getNode(OrigBB); - if (OrigBBDTNode) { - // Change the immediate dominators of the children of the block we - // splitted to the splitted block. - SmallVector Adoptees(OrigBBDTNode->begin(), - OrigBBDTNode->end()); - - auto NewBBDTNode = DT->addNewBlock(NewBB, OrigBB); - for (auto *Adoptee : Adoptees) - DT->changeImmediateDominator(Adoptee, NewBBDTNode); - } - } - - // Update loop info. - if (LI) - if (auto *OrigBBLoop = LI->getLoopFor(OrigBB)) { - OrigBBLoop->addBasicBlockToLoop(NewBB, LI->getBase()); - } - - return NewBB; -} - -SILBasicBlock *swift::splitEdge(TermInst *T, unsigned EdgeIdx, - DominanceInfo *DT, SILLoopInfo *LI) { - auto *SrcBB = T->getParent(); - auto *Fn = SrcBB->getParent(); - - SILBasicBlock *DestBB = T->getSuccessors()[EdgeIdx]; - - // Create a new basic block in the edge, and insert it after the SrcBB. - auto *EdgeBB = new (Fn->getModule()) SILBasicBlock(Fn, SrcBB); - - SmallVector Args; - getEdgeArgs(T, EdgeIdx, EdgeBB, Args); - - SILBuilder(EdgeBB).createBranch(T->getLoc(), DestBB, Args); - - // Strip the arguments and rewire the branch in the source block. - changeBranchTarget(T, EdgeIdx, EdgeBB, /*PreserveArgs=*/false); - - if (!DT && !LI) - return EdgeBB; - - // Update the dominator tree. - if (DT) { - auto *SrcBBNode = DT->getNode(SrcBB); - - // Unreachable code could result in a null return here. - if (SrcBBNode) { - // The new block is dominated by the SrcBB. - auto *EdgeBBNode = DT->addNewBlock(EdgeBB, SrcBB); - - // Are all predecessors of DestBB dominated by DestBB? - auto *DestBBNode = DT->getNode(DestBB); - bool OldSrcBBDominatesAllPreds = std::all_of( - DestBB->pred_begin(), DestBB->pred_end(), [=](SILBasicBlock *B) { - if (B == EdgeBB) - return true; - auto *PredNode = DT->getNode(B); - if (!PredNode) - return true; - if (DT->dominates(DestBBNode, PredNode)) - return true; - return false; - }); - - // If so, the new bb dominates DestBB now. - if (OldSrcBBDominatesAllPreds) - DT->changeImmediateDominator(DestBBNode, EdgeBBNode); - } - } - - if (!LI) - return EdgeBB; - - // Update loop info. Both blocks must be in a loop otherwise the split block - // is outside the loop. - SILLoop *SrcBBLoop = LI->getLoopFor(SrcBB); - if (!SrcBBLoop) - return EdgeBB; - SILLoop *DstBBLoop = LI->getLoopFor(DestBB); - if (!DstBBLoop) - return EdgeBB; - - // Same loop. - if (DstBBLoop == SrcBBLoop) { - DstBBLoop->addBasicBlockToLoop(EdgeBB, LI->getBase()); - return EdgeBB; - } - - // Edge from inner to outer loop. - if (DstBBLoop->contains(SrcBBLoop)) { - DstBBLoop->addBasicBlockToLoop(EdgeBB, LI->getBase()); - return EdgeBB; - } - - // Edge from outer to inner loop. - if (SrcBBLoop->contains(DstBBLoop)) { - SrcBBLoop->addBasicBlockToLoop(EdgeBB, LI->getBase()); - return EdgeBB; - } - - // Neither loop contains the other. The destination must be the header of its - // loop. Otherwise, we would be creating irreducable control flow. - assert(DstBBLoop->getHeader() == DestBB && - "Creating irreducible control flow?"); - - // Add to outer loop if there is one. - if (auto *Parent = DstBBLoop->getParentLoop()) - Parent->addBasicBlockToLoop(EdgeBB, LI->getBase()); - - return EdgeBB; -} - -/// Split every edge between two basic blocks. -void swift::splitEdgesFromTo(SILBasicBlock *From, SILBasicBlock *To, - DominanceInfo *DT, SILLoopInfo *LI) { - for (unsigned EdgeIndex = 0, E = From->getSuccessors().size(); EdgeIndex != E; - ++EdgeIndex) { - SILBasicBlock *SuccBB = From->getSuccessors()[EdgeIndex]; - if (SuccBB != To) - continue; - splitEdge(From->getTerminator(), EdgeIndex, DT, LI); - } -} - -/// Splits the n-th critical edge from the terminator and updates dominance and -/// loop info if set. -/// Returns the newly created basic block on success or nullptr otherwise (if -/// the edge was not critical. -SILBasicBlock *swift::splitCriticalEdge(TermInst *T, unsigned EdgeIdx, - DominanceInfo *DT, SILLoopInfo *LI) { - if (!isCriticalEdge(T, EdgeIdx)) - return nullptr; - - return splitEdge(T, EdgeIdx, DT, LI); -} - -/// Split all critical edges in the function updating the dominator tree and -/// loop information (if they are not set to null). -bool swift::splitAllCriticalEdges(SILFunction &F, bool OnlyNonCondBr, - DominanceInfo *DT, SILLoopInfo *LI) { - bool Changed = false; - - std::vector Blocks; - Blocks.reserve(F.size()); - - for (auto &It : F) - Blocks.push_back(&It); - - for (auto It : Blocks) { - // Only split critical edges for terminators that don't support block - // arguments. - if (OnlyNonCondBr && isa(It->getTerminator())) - continue; - - if (isa(It->getTerminator())) - continue; - - for (unsigned Idx = 0, e = It->getSuccessors().size(); Idx != e; ++Idx) - Changed |= - (splitCriticalEdge(It->getTerminator(), Idx, DT, LI) != nullptr); - } - return Changed; -} - -/// Merge the basic block with its successor if possible. If dominance -/// information or loop info is non null update it. Return true if block was -/// merged. -bool swift::mergeBasicBlockWithSuccessor(SILBasicBlock *BB, DominanceInfo *DT, - SILLoopInfo *LI) { - auto *Branch = dyn_cast(BB->getTerminator()); - if (!Branch) - return false; - - auto *SuccBB = Branch->getDestBB(); - if (BB == SuccBB || !SuccBB->getSinglePredecessor()) - return false; - - // If there are any BB arguments in the destination, replace them with the - // branch operands, since they must dominate the dest block. - for (unsigned i = 0, e = Branch->getArgs().size(); i != e; ++i) - SILValue(SuccBB->getBBArg(i)).replaceAllUsesWith(Branch->getArg(i)); - - Branch->eraseFromParent(); - - // Move the instruction from the successor block to the current block. - BB->spliceAtEnd(SuccBB); - - if (DT) - if (auto *SuccBBNode = DT->getNode(SuccBB)) { - // Change the immediate dominator for children of the successor to be the - // current block. - auto *BBNode = DT->getNode(BB); - SmallVector Children(SuccBBNode->begin(), - SuccBBNode->end()); - for (auto *ChildNode : *SuccBBNode) - DT->changeImmediateDominator(ChildNode, BBNode); - - DT->eraseNode(SuccBB); - } - - if (LI) - LI->removeBlock(SuccBB); - - SuccBB->eraseFromParent(); - - return true; -} - -/// Splits the critical edges between from and to. This code assumes there is -/// only one edge between the two basic blocks. -SILBasicBlock *swift::splitIfCriticalEdge(SILBasicBlock *From, - SILBasicBlock *To, - DominanceInfo *DT, - SILLoopInfo *LI) { - auto *T = From->getTerminator(); - for (unsigned i = 0, e = T->getSuccessors().size(); i != e; ++i) { - if (T->getSuccessors()[i] == To) - return splitCriticalEdge(T, i, DT, LI); - } - llvm_unreachable("Destination block not found"); -} diff --git a/lib/SILPasses/Utils/CMakeLists.txt b/lib/SILPasses/Utils/CMakeLists.txt deleted file mode 100644 index a866ea7dcfc7b..0000000000000 --- a/lib/SILPasses/Utils/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_swift_library(swiftSILPassesUtils - CFG.cpp - Local.cpp - SILInliner.cpp - SILSSAUpdater.cpp - ConstantFolding.cpp - GenericCloner.cpp - Generics.cpp - Devirtualize.cpp - CheckedCastBrJumpThreading.cpp - LoopUtils.cpp - LINK_LIBRARIES swiftSIL swiftSILAnalysis) - diff --git a/lib/SILPasses/Utils/Devirtualize.cpp b/lib/SILPasses/Utils/Devirtualize.cpp deleted file mode 100644 index f688a760ad810..0000000000000 --- a/lib/SILPasses/Utils/Devirtualize.cpp +++ /dev/null @@ -1,658 +0,0 @@ -//===-- Devirtualize.cpp - Helper for devirtualizing apply ------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "sil-devirtualize-utility" -#include "swift/SILPasses/Utils/Devirtualize.h" -#include "swift/AST/Decl.h" -#include "swift/AST/Types.h" -#include "swift/SIL/SILDeclRef.h" -#include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILInstruction.h" -#include "swift/SIL/SILModule.h" -#include "swift/SIL/SILType.h" -#include "swift/SIL/SILValue.h" -#include "swift/SILPasses/Utils/Local.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/Support/Casting.h" -using namespace swift; - -STATISTIC(NumClassDevirt, "Number of class_method applies devirtualized"); -STATISTIC(NumWitnessDevirt, "Number of witness_method applies devirtualized"); - -//===----------------------------------------------------------------------===// -// Class Method Optimization -//===----------------------------------------------------------------------===// - -// Attempt to get the instance for S, whose static type is the same as -// its exact dynamic type, returning a null SILValue() if we cannot find it. -// The information that a static type is the same as the exact dynamic, -// can be derived e.g.: -// - from a constructor or -// - from a successful outcome of a checked_cast_br [exact] instruction. -static SILValue getInstanceWithExactDynamicType(SILValue S) { - - while (S) { - S = S.stripCasts(); - if (isa(S) || isa(S)) - return S; - - auto *Arg = dyn_cast(S); - if (!Arg) - break; - - auto *SinglePred = Arg->getParent()->getSinglePredecessor(); - if (!SinglePred) - break; - - // Traverse the chain of predecessors. - if (isa(SinglePred->getTerminator()) || - isa(SinglePred->getTerminator())) { - S = Arg->getIncomingValue(SinglePred); - continue; - } - - // If it is a BB argument received on a success branch - // of a checked_cast_br, then we know its exact type. - auto *CCBI = dyn_cast(SinglePred->getTerminator()); - if (!CCBI) - break; - if (!CCBI->isExact() || CCBI->getSuccessBB() != Arg->getParent()) - break; - return S; - } - - return SILValue(); -} - -/// Return bound generic type for the unbound type Superclass, -/// which is a superclass of a bound generic type BoundDerived -/// (Base may be also the same as BoundDerived or may be -/// non-generic at all). -static CanType bindSuperclass(CanType Superclass, - SILType BoundDerived) { - assert(BoundDerived && "Expected non-null type!"); - - SILType BoundSuperclass = BoundDerived; - - do { - // Get declaration of the superclass. - auto *Decl = BoundSuperclass.getNominalOrBoundGenericNominal(); - // Obtain the unbound variant of the current superclass - CanType UnboundSuperclass = Decl->getDeclaredType()->getCanonicalType(); - // Check if we found a superclass we are looking for. - if (UnboundSuperclass == Superclass) - return BoundSuperclass.getSwiftRValueType(); - - // Get the superclass of current one - BoundSuperclass = BoundSuperclass.getSuperclass(nullptr); - } while (BoundSuperclass); - - llvm_unreachable("Expected to find a bound generic superclass!"); -} - -// Returns true if any generic types parameters of the class are -// unbound. -bool swift::isClassWithUnboundGenericParameters(SILType C, SILModule &M) { - auto *CD = C.getClassOrBoundGenericClass(); - if (CD && CD->getGenericSignature()) { - auto InstanceTypeSubsts = - C.gatherAllSubstitutions(M); - - if (!InstanceTypeSubsts.empty()) { - if (hasUnboundGenericTypes(InstanceTypeSubsts)) - return true; - } - } - - if (C.hasArchetype()) - return true; - - return false; -} - -// Start with the substitutions from the apply. -// Try to propagate them to find out the real substitutions required -// to invoke the method. -static ArrayRef -getSubstitutionsForCallee(SILModule &M, CanSILFunctionType GenCalleeType, - SILType ClassInstanceType, FullApplySite AI) { - // *NOTE*: - // Apply instruction substitutions are for the Member from a protocol or - // class B, where this member was first defined, before it got overridden by - // derived classes. - // - // The implementation F (the implementing method) which was found may have - // a different set of generic parameters, e.g. because it is implemented by a - // class D1 derived from B. - // - // ClassInstanceType may have a type different from both the type B - // the Member belongs to and from the ClassInstanceType, e.g. if - // ClassInstance is of a class D2, which is derived from D1, but does not - // override the Member. - // - // As a result, substitutions provided by AI are for Member, whereas - // substitutions in ClassInstanceType are for D2. And substitutions for D1 - // are not available directly in a general case. Therefore, they have to - // be computed. - // - // What we know for sure: - // B is a superclass of D1 - // D1 is a superclass of D2. - // D1 can be the same as D2. D1 can be the same as B. - // - // So, substitutions from AI are for class B. - // Substitutions for class D1 by means of bindSuperclass(), which starts - // with a bound type ClassInstanceType and checks its superclasses until it - // finds a bound superclass matching D1 and returns its substitutions. - - // Class F belongs to. - CanType FSelfClass = GenCalleeType->getSelfParameter().getType(); - - SILType FSelfSubstType; - Module *Module = M.getSwiftModule(); - - ArrayRef ClassSubs; - - if (GenCalleeType->isPolymorphic()) { - // Declaration of the class F belongs to. - if (auto *FSelfTypeDecl = FSelfClass.getNominalOrBoundGenericNominal()) { - // Get the unbound generic type F belongs to. - CanType FSelfGenericType = - FSelfTypeDecl->getDeclaredType()->getCanonicalType(); - - assert((isa(ClassInstanceType.getSwiftRValueType()) || - isa(ClassInstanceType.getSwiftRValueType())) && - "Self type should be either a bound generic type" - "or a non-generic type"); - - assert((isa(FSelfGenericType) || - isa(FSelfGenericType)) && - "Method implementation self type should be generic"); - - if (isa(ClassInstanceType.getSwiftRValueType())) { - auto BoundBaseType = bindSuperclass(FSelfGenericType, - ClassInstanceType); - if (auto BoundTy = BoundBaseType->getAs()) { - ClassSubs = BoundTy->getSubstitutions(Module, nullptr); - } - } - } - } else { - // If the callee is not polymorphic, no substitutions are required. - return {}; - } - - if (ClassSubs.empty()) - return AI.getSubstitutions(); - - auto AISubs = AI.getSubstitutions(); - - CanSILFunctionType AIGenCalleeType = - AI.getCallee().getType().castTo(); - - CanType AISelfClass = AIGenCalleeType->getSelfParameter().getType(); - - unsigned NextMethodParamIdx = 0; - unsigned NumMethodParams = 0; - if (AIGenCalleeType->isPolymorphic()) { - NextMethodParamIdx = 0; - // Generic parameters of the method start after generic parameters - // of the instance class. - if (auto AISelfClassSig = - AISelfClass.getClassBound()->getGenericSignature()) { - NextMethodParamIdx = AISelfClassSig->getGenericParams().size(); - } - NumMethodParams = AISubs.size() - NextMethodParamIdx; - } - - unsigned NumSubs = ClassSubs.size() + NumMethodParams; - - if (ClassSubs.size() == NumSubs) - return ClassSubs; - - // Mix class subs with method specific subs from the AI substitutions. - - // Assumptions: AI substitutions contain first the substitutions for - // a class of the method being invoked and then the substitutions - // for a method being invoked. - auto Subs = M.getASTContext().Allocate(NumSubs); - - unsigned i = 0; - for (auto &S : ClassSubs) { - Subs[i++] = S; - } - - for (; i < NumSubs; ++i, ++NextMethodParamIdx) { - Subs[i] = AISubs[NextMethodParamIdx]; - } - - return Subs; -} - -static SILFunction *getTargetClassMethod(SILModule &M, - SILType ClassOrMetatypeType, - SILDeclRef Member) { - if (ClassOrMetatypeType.is()) - ClassOrMetatypeType = ClassOrMetatypeType.getMetatypeInstanceType(M); - - auto *CD = ClassOrMetatypeType.getClassOrBoundGenericClass(); - return M.lookUpFunctionInVTable(CD, Member); -} - - -/// \brief Check if it is possible to devirtualize an Apply instruction -/// and a class member obtained using the class_method instruction into -/// a direct call to a specific member of a specific class. -/// -/// \p AI is the apply to devirtualize. -/// \p ClassOrMetatypeType is the class type or metatype type we are -/// devirtualizing for. -/// return true if it is possible to devirtualize, false - otherwise. -bool swift::canDevirtualizeClassMethod(FullApplySite AI, - SILType ClassOrMetatypeType) { - DEBUG(llvm::dbgs() << " Trying to devirtualize : " << *AI.getInstruction()); - - SILModule &Mod = AI.getModule(); - - // Bail if any generic types parameters of the class instance type are - // unbound. - // We cannot devirtualize unbound generic calls yet. - if (isClassWithUnboundGenericParameters(ClassOrMetatypeType, Mod)) - return false; - - // First attempt to lookup the origin for our class method. The origin should - // either be a metatype or an alloc_ref. - DEBUG(llvm::dbgs() << " Origin Type: " << ClassOrMetatypeType); - - auto *CMI = cast(AI.getCallee()); - - // Find the implementation of the member which should be invoked. - auto *F = getTargetClassMethod(Mod, ClassOrMetatypeType, CMI->getMember()); - - // If we do not find any such function, we have no function to devirtualize - // to... so bail. - if (!F) { - DEBUG(llvm::dbgs() << " FAIL: Could not find matching VTable or " - "vtable method for this class.\n"); - return false; - } - - if (AI.getFunction()->isFragile()) { - // function_ref inside fragile function cannot reference a private or - // hidden symbol. - if (!(F->isFragile() || isValidLinkageForFragileRef(F->getLinkage()) || - F->isExternalDeclaration())) - return false; - } - - CanSILFunctionType GenCalleeType = F->getLoweredFunctionType(); - - auto Subs = getSubstitutionsForCallee(Mod, GenCalleeType, - ClassOrMetatypeType, AI); - - // For polymorphic functions, bail if the number of substitutions is - // not the same as the number of expected generic parameters. - if (GenCalleeType->isPolymorphic()) { - auto GenericSig = GenCalleeType->getGenericSignature(); - // Get the number of expected generic parameters, which - // is a sum of the number of explicit generic parameters - // and the number of their recursive member types exposed - // through protocol requirements. - auto DepTypes = GenericSig->getAllDependentTypes(); - unsigned ExpectedGenParamsNum = 0; - - for (auto DT: DepTypes) { - (void)DT; - ExpectedGenParamsNum++; - } - - if (ExpectedGenParamsNum != Subs.size()) - return false; - } - - // Check if the optimizer knows how to cast the return type. - CanSILFunctionType SubstCalleeType = GenCalleeType; - if (GenCalleeType->isPolymorphic()) - SubstCalleeType = - GenCalleeType->substGenericArgs(Mod, Mod.getSwiftModule(), Subs); - - // If we have a direct return type, make sure we use the subst callee return - // type. If we have an indirect return type, AI's return type of the empty - // tuple should be ok. - SILType ReturnType = AI.getType(); - if (!SubstCalleeType->hasIndirectResult()) { - ReturnType = SubstCalleeType->getSILResult(); - } - - if (!canCastValueToABICompatibleType(Mod, ReturnType, AI.getType())) - return false; - - return true; -} - -/// \brief Devirtualize an apply of a class method. -/// -/// \p AI is the apply to devirtualize. -/// \p ClassOrMetatype is a class value or metatype value that is the -/// self argument of the apply we will devirtualize. -/// return the result value of the new ApplyInst if created one or null. -DevirtualizationResult swift::devirtualizeClassMethod(FullApplySite AI, - SILValue ClassOrMetatype) { - DEBUG(llvm::dbgs() << " Trying to devirtualize : " << *AI.getInstruction()); - - SILModule &Mod = AI.getModule(); - auto *CMI = cast(AI.getCallee()); - auto ClassOrMetatypeType = ClassOrMetatype.getType(); - auto *F = getTargetClassMethod(Mod, ClassOrMetatypeType, CMI->getMember()); - - CanSILFunctionType GenCalleeType = F->getLoweredFunctionType(); - - auto Subs = getSubstitutionsForCallee(Mod, GenCalleeType, - ClassOrMetatypeType, AI); - CanSILFunctionType SubstCalleeType = GenCalleeType; - if (GenCalleeType->isPolymorphic()) - SubstCalleeType = GenCalleeType->substGenericArgs(Mod, Mod.getSwiftModule(), Subs); - - SILBuilderWithScope B(AI.getInstruction()); - FunctionRefInst *FRI = B.createFunctionRef(AI.getLoc(), F); - - // Create the argument list for the new apply, casting when needed - // in order to handle covariant indirect return types and - // contravariant argument types. - llvm::SmallVector NewArgs; - auto Args = AI.getArguments(); - auto ParamTypes = SubstCalleeType->getParameterSILTypes(); - - for (unsigned i = 0, e = Args.size() - 1; i != e; ++i) - NewArgs.push_back(castValueToABICompatibleType(&B, AI.getLoc(), Args[i], - Args[i].getType(), - ParamTypes[i]).getValue()); - - // Add the self argument, upcasting if required because we're - // calling a base class's method. - auto SelfParamTy = SubstCalleeType->getSelfParameter().getSILType(); - NewArgs.push_back(castValueToABICompatibleType(&B, AI.getLoc(), - ClassOrMetatype, - ClassOrMetatypeType, - SelfParamTy).getValue()); - - // If we have a direct return type, make sure we use the subst callee return - // type. If we have an indirect return type, AI's return type of the empty - // tuple should be ok. - SILType ResultTy = AI.getType(); - if (!SubstCalleeType->hasIndirectResult()) { - ResultTy = SubstCalleeType->getSILResult(); - } - - SILType SubstCalleeSILType = - SILType::getPrimitiveObjectType(SubstCalleeType); - FullApplySite NewAI; - - SILBasicBlock *ResultBB = nullptr; - SILBasicBlock *NormalBB = nullptr; - SILValue ResultValue; - bool ResultCastRequired = false; - SmallVector OriginalResultUses; - - if (!isa(AI)) { - NewAI = B.createApply(AI.getLoc(), FRI, SubstCalleeSILType, ResultTy, - Subs, NewArgs, cast(AI)->isNonThrowing()); - ResultValue = SILValue(NewAI.getInstruction(), 0); - } else { - auto *TAI = cast(AI); - // Create new normal and error BBs only if: - // - re-using a BB would create a critical edge - // - or, the result of the new apply would be of different - // type than the argument of the original normal BB. - if (TAI->getNormalBB()->getSinglePredecessor()) - ResultBB = TAI->getNormalBB(); - else { - ResultBB = B.getFunction().createBasicBlock(); - ResultBB->createBBArg(ResultTy); - } - - NormalBB = TAI->getNormalBB(); - - SILBasicBlock *ErrorBB = nullptr; - if (TAI->getErrorBB()->getSinglePredecessor()) - ErrorBB = TAI->getErrorBB(); - else { - ErrorBB = B.getFunction().createBasicBlock(); - ErrorBB->createBBArg(TAI->getErrorBB()->getBBArg(0)->getType()); - } - - NewAI = B.createTryApply(AI.getLoc(), FRI, SubstCalleeSILType, - Subs, NewArgs, - ResultBB, ErrorBB); - if (ErrorBB != TAI->getErrorBB()) { - B.setInsertionPoint(ErrorBB); - B.createBranch(TAI->getLoc(), TAI->getErrorBB(), - {ErrorBB->getBBArg(0)}); - } - - // Does the result value need to be casted? - ResultCastRequired = ResultTy != NormalBB->getBBArg(0)->getType(); - - if (ResultBB != NormalBB) - B.setInsertionPoint(ResultBB); - else if (ResultCastRequired) { - B.setInsertionPoint(NormalBB->begin()); - // Collect all uses, before casting. - for (auto *Use : NormalBB->getBBArg(0)->getUses()) { - OriginalResultUses.push_back(Use); - } - NormalBB->getBBArg(0)->replaceAllUsesWith(SILUndef::get(AI.getType(), Mod)); - NormalBB->replaceBBArg(0, ResultTy, nullptr); - } - - // The result value is passed as a parameter to the normal block. - ResultValue = ResultBB->getBBArg(0); - } - - // Check if any casting is required for the return value. - ResultValue = castValueToABICompatibleType(&B, NewAI.getLoc(), ResultValue, - ResultTy, AI.getType()).getValue(); - - DEBUG(llvm::dbgs() << " SUCCESS: " << F->getName() << "\n"); - NumClassDevirt++; - - if (NormalBB) { - if (NormalBB != ResultBB) { - // If artificial normal BB was introduced, branch - // to the original normal BB. - B.createBranch(NewAI.getLoc(), NormalBB, { ResultValue }); - } else if (ResultCastRequired) { - // Update all original uses by the new value. - for(auto *Use: OriginalResultUses) { - Use->set(ResultValue); - } - } - return std::make_pair(NewAI.getInstruction(), NewAI); - } - - // We need to return a pair of values here: - // - the first one is the actual result of the devirtualized call, possibly - // casted into an appropriate type. This SILValue may be a BB arg, if it - // was a cast between optional types. - // - the second one is the new apply site. - return std::make_pair(ResultValue.getDef(), NewAI); -} - -DevirtualizationResult swift::tryDevirtualizeClassMethod(FullApplySite AI, - SILValue ClassInstance) { - if (!canDevirtualizeClassMethod(AI, ClassInstance.getType())) - return std::make_pair(nullptr, FullApplySite()); - return devirtualizeClassMethod(AI, ClassInstance); -} - - -//===----------------------------------------------------------------------===// -// Witness Method Optimization -//===----------------------------------------------------------------------===// - -/// Generate a new apply of a function_ref to replace an apply of a -/// witness_method when we've determined the actual function we'll end -/// up calling. -static ApplySite devirtualizeWitnessMethod(ApplySite AI, SILFunction *F, - ArrayRef Subs) { - // We know the witness thunk and the corresponding set of substitutions - // required to invoke the protocol method at this point. - auto &Module = AI.getModule(); - - // Collect all the required substitutions. - // - // The complete set of substitutions may be different, e.g. because the found - // witness thunk F may have been created by a specialization pass and have - // additional generic parameters. - SmallVector NewSubstList(Subs.begin(), Subs.end()); - - // Add the non-self-derived substitutions from the original application. - ArrayRef SubstList; - SubstList = AI.getSubstitutionsWithoutSelfSubstitution(); - - for (auto &origSub : SubstList) - if (!origSub.getArchetype()->isSelfDerived()) - NewSubstList.push_back(origSub); - - // Figure out the exact bound type of the function to be called by - // applying all substitutions. - auto CalleeCanType = F->getLoweredFunctionType(); - auto SubstCalleeCanType = CalleeCanType->substGenericArgs( - Module, Module.getSwiftModule(), NewSubstList); - - // Collect arguments from the apply instruction. - auto Arguments = SmallVector(); - - auto ParamTypes = SubstCalleeCanType->getParameterSILTypes(); - - // Iterate over the non self arguments and add them to the - // new argument list, upcasting when required. - SILBuilderWithScope B(AI.getInstruction()); - for (unsigned ArgN = 0, ArgE = AI.getNumArguments(); ArgN != ArgE; ++ArgN) { - SILValue A = AI.getArgument(ArgN); - auto ParamType = ParamTypes[ParamTypes.size() - AI.getNumArguments() + ArgN]; - if (A.getType() != ParamType) - A = B.createUpcast(AI.getLoc(), A, ParamType); - - Arguments.push_back(A); - } - - // Replace old apply instruction by a new apply instruction that invokes - // the witness thunk. - SILBuilderWithScope Builder(AI.getInstruction()); - SILLocation Loc = AI.getLoc(); - FunctionRefInst *FRI = Builder.createFunctionRef(Loc, F); - - auto SubstCalleeSILType = SILType::getPrimitiveObjectType(SubstCalleeCanType); - auto ResultSILType = SubstCalleeCanType->getSILResult(); - ApplySite SAI; - - if (auto *A = dyn_cast(AI)) - SAI = Builder.createApply(Loc, FRI, SubstCalleeSILType, - ResultSILType, NewSubstList, Arguments, - A->isNonThrowing()); - if (auto *TAI = dyn_cast(AI)) - SAI = Builder.createTryApply(Loc, FRI, SubstCalleeSILType, - NewSubstList, Arguments, - TAI->getNormalBB(), TAI->getErrorBB()); - if (auto *PAI = dyn_cast(AI)) - SAI = Builder.createPartialApply(Loc, FRI, SubstCalleeSILType, - NewSubstList, Arguments, PAI->getType()); - - NumWitnessDevirt++; - return SAI; -} - -/// In the cases where we can statically determine the function that -/// we'll call to, replace an apply of a witness_method with an apply -/// of a function_ref, returning the new apply. -DevirtualizationResult swift::tryDevirtualizeWitnessMethod(ApplySite AI) { - SILFunction *F; - ArrayRef Subs; - SILWitnessTable *WT; - - auto *WMI = cast(AI.getCallee()); - - std::tie(F, WT, Subs) = - AI.getModule().lookUpFunctionInWitnessTable(WMI->getConformance(), - WMI->getMember()); - - if (!F) - return std::make_pair(nullptr, FullApplySite()); - - auto Result = devirtualizeWitnessMethod(AI, F, Subs); - return std::make_pair(Result.getInstruction(), Result); -} - -//===----------------------------------------------------------------------===// -// Top Level Driver -//===----------------------------------------------------------------------===// - -/// Return the final class decl based on access control information. -static bool isKnownFinal(SILModule &M, SILDeclRef Member) { - if (!calleesAreStaticallyKnowable(M, Member)) - return false; - - auto *FD = Member.getAbstractFunctionDecl(); - assert(FD && "Expected abstract function decl!"); - - assert(!FD->isFinal() && "Unexpected indirect call to final method!"); - - if (FD->isOverridden()) - return false; - - return true; -} - -/// Attempt to devirtualize the given apply if possible, and return a -/// new instruction in that case, or nullptr otherwise. -DevirtualizationResult swift::tryDevirtualizeApply(FullApplySite AI) { - DEBUG(llvm::dbgs() << " Trying to devirtualize: " << *AI.getInstruction()); - - // Devirtualize apply instructions that call witness_method instructions: - // - // %8 = witness_method $Optional, #LogicValue.boolValue!getter.1 - // %9 = apply %8(%6#1) : ... - // - if (isa(AI.getCallee())) - return tryDevirtualizeWitnessMethod(AI); - - /// Optimize a class_method and alloc_ref pair into a direct function - /// reference: - /// - /// \code - /// %XX = alloc_ref $Foo - /// %YY = class_method %XX : $Foo, #Foo.get!1 : $@convention(method)... - /// \endcode - /// - /// or - /// - /// %XX = metatype $... - /// %YY = class_method %XX : ... - /// - /// into - /// - /// %YY = function_ref @... - if (auto *CMI = dyn_cast(AI.getCallee())) { - // Check if the class member is known to be final. - if (isKnownFinal(CMI->getModule(), CMI->getMember())) - return tryDevirtualizeClassMethod(AI, CMI->getOperand()); - - // Try to check if the exact dynamic type of the instance is statically - // known. - if (auto Instance = getInstanceWithExactDynamicType(CMI->getOperand())) - return tryDevirtualizeClassMethod(AI, Instance); - } - - return std::make_pair(nullptr, FullApplySite()); -} diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 393a2404f4a45..be8682110d7af 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,6 +21,7 @@ #include "swift/AST/ASTVisitor.h" #include "swift/AST/ASTWalker.h" #include "swift/AST/Attr.h" +#include "swift/Basic/StringExtras.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/SmallString.h" @@ -239,7 +240,7 @@ static DeclTy *findNamedWitnessImpl(TypeChecker &tc, DeclContext *dc, Type type, if (!conforms) return nullptr; - // For an type with dependent conformance, just return the requirement from + // For a type with dependent conformance, just return the requirement from // the protocol. There are no protocol conformance tables. if (type->hasDependentProtocolConformances()) { return requirement; @@ -295,6 +296,7 @@ namespace { DeclContext *dc; const Solution &solution; bool SuppressDiagnostics; + bool SkipClosures; private: /// \brief Coerce the given tuple to another tuple type. @@ -392,7 +394,7 @@ namespace { // specialized reference to it. if (auto genericFn = decl->getInterfaceType()->getAs()) { - auto dc = decl->getPotentialGenericDeclContext(); + auto dc = decl->getInnermostDeclContext(); SmallVector substitutions; auto type = solution.computeSubstitutions( @@ -404,6 +406,16 @@ namespace { } auto type = simplifyType(openedType); + + // If we've ended up trying to assign an inout type here, it means we're + // missing an ampersand in front of the ref. + if (auto inoutType = type->getAs()) { + auto &tc = cs.getTypeChecker(); + tc.diagnose(loc, diag::missing_address_of, inoutType->getInOutObjectType()) + .fixItInsert(loc, "&"); + return nullptr; + } + return new (ctx) DeclRefExpr(decl, loc, implicit, semantics, type); } @@ -728,7 +740,7 @@ namespace { // Figure out the declaration context where we'll get the generic // parameters. - auto dc = member->getPotentialGenericDeclContext(); + auto dc = member->getInnermostDeclContext(); // Build a reference to the generic member. SmallVector substitutions; @@ -776,12 +788,11 @@ namespace { (cast(func)->hasDynamicSelf() || (openedExistential && cast(func)->hasArchetypeSelf()))) || isPolymorphicConstructor(func)) { - refTy = refTy->replaceCovariantResultType( - containerTy, - func->getNumParamPatterns()); + refTy = refTy->replaceCovariantResultType(containerTy, + func->getNumParameterLists()); dynamicSelfFnType = refTy->replaceCovariantResultType( baseTy, - func->getNumParamPatterns()); + func->getNumParameterLists()); if (openedExistential) { // Replace the covariant result type in the opened type. We need to @@ -792,7 +803,7 @@ namespace { openedType = optObject; openedType = openedType->replaceCovariantResultType( baseTy, - func->getNumParamPatterns()-1); + func->getNumParameterLists()-1); if (optKind != OptionalTypeKind::OTK_None) openedType = OptionalType::get(optKind, openedType); } @@ -1458,9 +1469,10 @@ namespace { public: ExprRewriter(ConstraintSystem &cs, const Solution &solution, - bool suppressDiagnostics) + bool suppressDiagnostics, bool skipClosures) : cs(cs), dc(cs.DC), solution(solution), - SuppressDiagnostics(suppressDiagnostics) { } + SuppressDiagnostics(suppressDiagnostics), + SkipClosures(skipClosures) { } ConstraintSystem &getConstraintSystem() const { return cs; } @@ -3237,6 +3249,30 @@ namespace { } Expr *visitEditorPlaceholderExpr(EditorPlaceholderExpr *E) { + Type valueType = simplifyType(E->getType()); + E->setType(valueType); + + auto &tc = cs.getTypeChecker(); + auto &ctx = tc.Context; + // Synthesize a call to _undefined() of appropriate type. + FuncDecl *undefinedDecl = ctx.getUndefinedDecl(&tc); + if (!undefinedDecl) { + tc.diagnose(E->getLoc(), diag::missing_undefined_runtime); + return nullptr; + } + DeclRefExpr *fnRef = new (ctx) DeclRefExpr(undefinedDecl, SourceLoc(), + /*Implicit=*/true); + StringRef msg = "attempt to evaluate editor placeholder"; + Expr *argExpr = new (ctx) StringLiteralExpr(msg, E->getLoc(), + /*implicit*/true); + argExpr = new (ctx) ParenExpr(E->getLoc(), argExpr, E->getLoc(), + /*hasTrailingClosure*/false); + Expr *callExpr = new (ctx) CallExpr(fnRef, argExpr, /*implicit*/true); + bool invalid = tc.typeCheckExpression(callExpr, cs.DC, valueType, + CTP_CannotFail); + (void) invalid; + assert(!invalid && "conversion cannot fail"); + E->setSemanticExpr(callExpr); return E; } @@ -3365,11 +3401,11 @@ findDefaultArgsOwner(ConstraintSystem &cs, const Solution &solution, }, [&](ValueDecl *decl, Type openedType) -> ConcreteDeclRef { - if (decl->getPotentialGenericDeclContext()->isGenericContext()) { + if (decl->getInnermostDeclContext()->isGenericContext()) { SmallVector subs; solution.computeSubstitutions( decl->getType(), - decl->getPotentialGenericDeclContext(), + decl->getInnermostDeclContext(), openedType, locator, subs); return ConcreteDeclRef(cs.getASTContext(), decl, subs); } @@ -3390,7 +3426,7 @@ getCallerDefaultArg(TypeChecker &tc, DeclContext *dc, unsigned index) { auto ownerFn = cast(owner.getDecl()); auto defArg = ownerFn->getDefaultArg(index); - MagicIdentifierLiteralExpr::Kind magicKind; + Expr *init = nullptr; switch (defArg.first) { case DefaultArgumentKind::None: llvm_unreachable("No default argument here?"); @@ -3404,30 +3440,51 @@ getCallerDefaultArg(TypeChecker &tc, DeclContext *dc, return getCallerDefaultArg(tc, dc, loc, owner, index); case DefaultArgumentKind::Column: - magicKind = MagicIdentifierLiteralExpr::Column; + init = new (tc.Context) MagicIdentifierLiteralExpr( + MagicIdentifierLiteralExpr::Column, loc, + /*Implicit=*/true); break; case DefaultArgumentKind::File: - magicKind = MagicIdentifierLiteralExpr::File; + init = new (tc.Context) MagicIdentifierLiteralExpr( + MagicIdentifierLiteralExpr::File, loc, + /*Implicit=*/true); break; case DefaultArgumentKind::Line: - magicKind = MagicIdentifierLiteralExpr::Line; + init = new (tc.Context) MagicIdentifierLiteralExpr( + MagicIdentifierLiteralExpr::Line, loc, + /*Implicit=*/true); break; case DefaultArgumentKind::Function: - magicKind = MagicIdentifierLiteralExpr::Function; + init = new (tc.Context) MagicIdentifierLiteralExpr( + MagicIdentifierLiteralExpr::Function, loc, + /*Implicit=*/true); break; case DefaultArgumentKind::DSOHandle: - magicKind = MagicIdentifierLiteralExpr::DSOHandle; + init = new (tc.Context) MagicIdentifierLiteralExpr( + MagicIdentifierLiteralExpr::DSOHandle, loc, + /*Implicit=*/true); + break; + + case DefaultArgumentKind::Nil: + init = new (tc.Context) NilLiteralExpr(loc, /*Implicit=*/true); + break; + + case DefaultArgumentKind::EmptyArray: + init = ArrayExpr::create(tc.Context, loc, {}, {}, loc); + init->setImplicit(); + break; + + case DefaultArgumentKind::EmptyDictionary: + init = DictionaryExpr::create(tc.Context, loc, {}, loc); + init->setImplicit(); break; } - // Create the default argument, which is a converted magic identifier - // literal expression. - Expr *init = new (tc.Context) MagicIdentifierLiteralExpr(magicKind, loc, - /*Implicit=*/true); + // Convert the literal to the appropriate type. bool invalid = tc.typeCheckExpression(init, dc, defArg.second,CTP_CannotFail); assert(!invalid && "conversion cannot fail"); (void)invalid; @@ -3564,7 +3621,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr, TupleType *fromTuple, toElt.getDefaultArgKind(), toElt.isVararg())); fromTupleExprFields[sources[i]] = fromElt; - hasInits |= toElt.hasInit(); + hasInits |= toElt.hasDefaultArg(); continue; } @@ -3596,7 +3653,7 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr, TupleType *fromTuple, fromElt.getName(), fromElt.getDefaultArgKind(), fromElt.isVararg()); - hasInits |= toElt.hasInit(); + hasInits |= toElt.hasDefaultArg(); } // Convert all of the variadic arguments to the destination type. @@ -3725,7 +3782,7 @@ Expr *ExprRewriter::coerceScalarToTuple(Expr *expr, TupleType *toTuple, bool hasInit = false; int i = 0; for (auto &field : toTuple->getElements()) { - if (field.hasInit()) { + if (field.hasDefaultArg()) { hasInit = true; break; } @@ -3777,7 +3834,7 @@ Expr *ExprRewriter::coerceScalarToTuple(Expr *expr, TupleType *toTuple, continue; } - assert(field.hasInit() && "Expected a default argument"); + assert(field.hasDefaultArg() && "Expected a default argument"); ConcreteDeclRef argOwner; // Dig out the owner of the default arguments. @@ -4063,7 +4120,7 @@ Expr *ExprRewriter::coerceCallArguments(Expr *arg, Type paramType, }; // Local function to extract the ith argument label, which papers over some - // of the weirdndess with tuples vs. parentheses. + // of the weirdness with tuples vs. parentheses. auto getArgLabel = [&](unsigned i) -> Identifier { if (argTuple) return argTuple->getElementName(i); @@ -4801,11 +4858,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, auto discriminator = AutoClosureExpr::InvalidDiscriminator; auto closure = new (tc.Context) AutoClosureExpr(expr, toType, discriminator, dc); - Pattern *pattern = TuplePattern::create(tc.Context, expr->getLoc(), - ArrayRef(), - expr->getLoc()); - pattern->setType(TupleType::getEmpty(tc.Context)); - closure->setParams(pattern); + closure->setParameterList(ParameterList::createEmpty(tc.Context)); // Compute the capture list, now that we have analyzed the expression. tc.ClosuresWithUncomputedCaptures.push_back(closure); @@ -5424,9 +5477,7 @@ diagnoseArgumentLabelError(Expr *expr, ArrayRef newNames, continue; } - tok newNameKind = - Lexer::kindOfIdentifier(newName.str(), /*inSILMode=*/false); - bool newNameIsReserved = newNameKind != tok::identifier; + bool newNameIsReserved = !canBeArgumentLabel(newName.str()); llvm::SmallString<16> newStr; if (newNameIsReserved) newStr += "`"; @@ -5513,7 +5564,7 @@ static std::pair getPrecedenceParentAndIndex(Expr *expr, // Return infix data representing the precedence of E. // FIXME: unify this with getInfixData() in lib/Sema/TypeCheckExpr.cpp; the // function there is meant to return infix data for expressions that have not -// yet been folded, so currently the correct behavor for this infixData() and +// yet been folded, so currently the correct behavior for this infixData() and // that one are mutually exclusive. static InfixData getInfixDataForFixIt(DeclContext *DC, Expr *E) { assert(E); @@ -5613,6 +5664,11 @@ namespace { ExprWalker(ExprRewriter &Rewriter) : Rewriter(Rewriter) { } ~ExprWalker() { + // If we're re-typechecking an expression for diagnostics, don't + // visit closures that have non-single expression bodies. + if (Rewriter.SkipClosures) + return; + auto &cs = Rewriter.getConstraintSystem(); auto &tc = cs.getTypeChecker(); for (auto *closure : closuresToTypeCheck) @@ -5632,16 +5688,9 @@ namespace { // Coerce the pattern, in case we resolved something. auto fnType = closure->getType()->castTo(); - Pattern *params = closure->getParams(); - TypeResolutionOptions TROptions; - TROptions |= TR_OverrideType; - TROptions |= TR_FromNonInferredPattern; - TROptions |= TR_InExpression; - TROptions |= TR_ImmediateFunctionInput; - if (tc.coercePatternToType(params, closure, fnType->getInput(), - TROptions)) + auto *params = closure->getParameters(); + if (tc.coerceParameterListToType(params, closure, fnType->getInput())) return { false, nullptr }; - closure->setParams(params); // If this is a single-expression closure, convert the expression // in the body to the result type of the closure. @@ -5649,6 +5698,8 @@ namespace { // Enter the context of the closure when type-checking the body. llvm::SaveAndRestore savedDC(Rewriter.dc, closure); Expr *body = closure->getSingleExpressionBody()->walk(*this); + if (!body) + return { false, nullptr }; if (body != closure->getSingleExpressionBody()) closure->setSingleExpressionBody(body); @@ -5665,7 +5716,7 @@ namespace { closure, ConstraintLocator::ClosureResult)); if (!body) - return { false, nullptr } ; + return { false, nullptr }; closure->setSingleExpressionBody(body); } @@ -6091,7 +6142,8 @@ bool ConstraintSystem::applySolutionFix(Expr *expr, Expr *ConstraintSystem::applySolution(Solution &solution, Expr *expr, Type convertType, bool discardedExpr, - bool suppressDiagnostics) { + bool suppressDiagnostics, + bool skipClosures) { // If any fixes needed to be applied to arrive at this solution, resolve // them to specific expressions. if (!solution.Fixes.empty()) { @@ -6106,7 +6158,7 @@ Expr *ConstraintSystem::applySolution(Solution &solution, Expr *expr, return nullptr; } - ExprRewriter rewriter(*this, solution, suppressDiagnostics); + ExprRewriter rewriter(*this, solution, suppressDiagnostics, skipClosures); ExprWalker walker(rewriter); // Apply the solution to the expression. @@ -6136,7 +6188,8 @@ Expr *ConstraintSystem::applySolution(Solution &solution, Expr *expr, Expr *ConstraintSystem::applySolutionShallow(const Solution &solution, Expr *expr, bool suppressDiagnostics) { - ExprRewriter rewriter(*this, solution, suppressDiagnostics); + ExprRewriter rewriter(*this, solution, suppressDiagnostics, + /*skipClosures=*/false); rewriter.walkToExprPre(expr); Expr *result = rewriter.walkToExprPost(expr); if (result) @@ -6148,7 +6201,9 @@ Expr *Solution::coerceToType(Expr *expr, Type toType, ConstraintLocator *locator, bool ignoreTopLevelInjection) const { auto &cs = getConstraintSystem(); - ExprRewriter rewriter(cs, *this, /*suppressDiagnostics=*/false); + ExprRewriter rewriter(cs, *this, + /*suppressDiagnostics=*/false, + /*skipClosures=*/false); Expr *result = rewriter.coerceToType(expr, toType, locator); if (!result) return nullptr; @@ -6172,10 +6227,9 @@ static bool isVariadicWitness(AbstractFunctionDecl *afd) { if (afd->getExtensionType()) ++index; - auto params = afd->getBodyParamPatterns()[index]; - if (auto *tuple = dyn_cast(params)) { - return tuple->hasAnyEllipsis(); - } + for (auto param : *afd->getParameterList(index)) + if (param->isVariadic()) + return true; return false; } @@ -6274,7 +6328,9 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc, } Solution &solution = solutions.front(); - ExprRewriter rewriter(cs, solution, /*suppressDiagnostics=*/false); + ExprRewriter rewriter(cs, solution, + /*suppressDiagnostics=*/false, + /*skipClosures=*/false); auto memberRef = rewriter.buildMemberRef(base, openedFullType, base->getStartLoc(), diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp index ffa25b0bb118b..57f3981ffd286 100644 --- a/lib/Sema/CSDiag.cpp +++ b/lib/Sema/CSDiag.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,6 +16,7 @@ #include "ConstraintSystem.h" #include "llvm/Support/SaveAndRestore.h" +#include "swift/AST/ASTWalker.h" using namespace swift; using namespace constraints; @@ -46,14 +47,6 @@ void Failure::dump(SourceManager *sm, raw_ostream &out) const { << " and " << getSecondType().getString(); break; - case MissingArgument: - out << "missing argument for parameter " << getValue(); - break; - - case ExtraArgument: - out << "extra argument " << getValue(); - break; - case NoPublicInitializers: out << getFirstType().getString() << " does not have any public initializers"; @@ -343,11 +336,11 @@ static Expr *simplifyLocatorToAnchor(ConstraintSystem &cs, /// Retrieve the argument pattern for the given declaration. /// -static Pattern *getParameterPattern(ValueDecl *decl) { +static ParameterList *getParameterList(ValueDecl *decl) { if (auto func = dyn_cast(decl)) - return func->getBodyParamPatterns()[0]; + return func->getParameterList(0); if (auto constructor = dyn_cast(decl)) - return constructor->getBodyParamPatterns()[1]; + return constructor->getParameterList(1); if (auto subscript = dyn_cast(decl)) return subscript->getIndices(); @@ -449,56 +442,31 @@ ResolvedLocator constraints::resolveLocatorToDecl( // FIXME: This is an egregious hack. We'd be far better off // FIXME: Perform deeper path resolution? auto path = locator->getPath(); - Pattern *parameterPattern = nullptr; + ParameterList *parameterList = nullptr; bool impliesFullPattern = false; while (!path.empty()) { switch (path[0].getKind()) { case ConstraintLocator::ApplyArgument: // If we're calling into something that has parameters, dig into the // actual parameter pattern. - parameterPattern = getParameterPattern(declRef.getDecl()); - if (!parameterPattern) + parameterList = getParameterList(declRef.getDecl()); + if (!parameterList) break; impliesFullPattern = true; path = path.slice(1); continue; - case ConstraintLocator::TupleElement: - case ConstraintLocator::NamedTupleElement: - if (parameterPattern) { - unsigned index = path[0].getValue(); - if (auto tuple = dyn_cast( - parameterPattern->getSemanticsProvidingPattern())) { - if (index < tuple->getNumElements()) { - parameterPattern = tuple->getElement(index).getPattern(); - impliesFullPattern = false; - path = path.slice(1); - continue; - } - } - parameterPattern = nullptr; - } - break; - - case ConstraintLocator::ApplyArgToParam: - if (parameterPattern) { - unsigned index = path[0].getValue2(); - if (auto tuple = dyn_cast( - parameterPattern->getSemanticsProvidingPattern())) { - if (index < tuple->getNumElements()) { - parameterPattern = tuple->getElement(index).getPattern(); - impliesFullPattern = false; - path = path.slice(1); - continue; - } - } - parameterPattern = nullptr; + case ConstraintLocator::ApplyArgToParam: { + if (!parameterList) break; + + unsigned index = path[0].getValue2(); + if (index < parameterList->size()) { + auto param = parameterList->get(index); + return ResolvedLocator(ResolvedLocator::ForVar, param); } break; - - case ConstraintLocator::ScalarToTuple: - continue; + } default: break; @@ -507,23 +475,6 @@ ResolvedLocator constraints::resolveLocatorToDecl( break; } - // If we have a parameter pattern that refers to a parameter, grab it. - if (parameterPattern) { - parameterPattern = parameterPattern->getSemanticsProvidingPattern(); - if (impliesFullPattern) { - if (auto tuple = dyn_cast(parameterPattern)) { - if (tuple->getNumElements() == 1) { - parameterPattern = tuple->getElement(0).getPattern(); - parameterPattern = parameterPattern->getSemanticsProvidingPattern(); - } - } - } - - if (auto named = dyn_cast(parameterPattern)) { - return ResolvedLocator(ResolvedLocator::ForVar, named->getDecl()); - } - } - // Otherwise, do the best we can with the declaration we found. if (isa(declRef.getDecl())) return ResolvedLocator(ResolvedLocator::ForFunction, declRef); @@ -642,46 +593,7 @@ static bool diagnoseFailure(ConstraintSystem &cs, Failure &failure, } // FIXME: diagnose other cases return false; - - case Failure::MissingArgument: { - Identifier name; - unsigned idx = failure.getValue(); - if (auto tupleTy = failure.getFirstType()->getAs()) { - name = tupleTy->getElement(idx).getName(); - } else { - // Scalar. - assert(idx == 0); - } - - if (name.empty()) - tc.diagnose(loc, diag::missing_argument_positional, idx+1); - else - tc.diagnose(loc, diag::missing_argument_named, name); - return true; - } - case Failure::ExtraArgument: { - if (auto tuple = dyn_cast_or_null(anchor)) { - unsigned firstIdx = failure.getValue(); - auto name = tuple->getElementName(firstIdx); - Expr *arg = tuple->getElement(firstIdx); - - if (firstIdx == tuple->getNumElements()-1 && - tuple->hasTrailingClosure()) - tc.diagnose(arg->getLoc(), diag::extra_trailing_closure_in_call) - .highlight(arg->getSourceRange()); - else if (name.empty()) - tc.diagnose(loc, diag::extra_argument_positional) - .highlight(arg->getSourceRange()); - else - tc.diagnose(loc, diag::extra_argument_named, name) - .highlight(arg->getSourceRange()); - return true; - } - - return false; - } - case Failure::NoPublicInitializers: { tc.diagnose(loc, diag::no_accessible_initializers, failure.getFirstType()) .highlight(range); @@ -1118,8 +1030,11 @@ namespace { // If this is an operator func decl in a type context, the 'self' isn't // actually going to be applied. if (auto *fd = dyn_cast(decl)) - if (fd->isOperator() && fd->getDeclContext()->isTypeContext()) + if (fd->isOperator() && fd->getDeclContext()->isTypeContext()) { + if (type->is()) + return nullptr; type = type->castTo()->getResult(); + } for (unsigned i = 0, e = level; i != e; ++i) { auto funcTy = type->getAs(); @@ -1208,7 +1123,7 @@ namespace { collectCalleeCandidates(Fn); } - CalleeCandidateInfo(ArrayRef candidates, + CalleeCandidateInfo(Type baseType, ArrayRef candidates, unsigned UncurryLevel, bool hasTrailingClosure, ConstraintSystem *CS); @@ -1237,6 +1152,11 @@ namespace { /// overloads. void suggestPotentialOverloads(SourceLoc loc, bool isResult = false); + /// If the candidate set has been narrowed down to a specific structural + /// problem, e.g. that there are too few parameters specified or that + /// argument labels don't match up, diagnose that error and return true. + bool diagnoseAnyStructuralArgumentError(Expr *fnExpr, Expr *argExpr); + void dump() const LLVM_ATTRIBUTE_USED; private: @@ -1657,16 +1577,32 @@ void CalleeCandidateInfo::filterContextualMemberList(Expr *argExpr) { return filterList(ArgElts); } -CalleeCandidateInfo::CalleeCandidateInfo(ArrayRef overloads, +CalleeCandidateInfo::CalleeCandidateInfo(Type baseType, + ArrayRef overloads, unsigned uncurryLevel, bool hasTrailingClosure, ConstraintSystem *CS) : CS(CS), hasTrailingClosure(hasTrailingClosure) { + + // If we have a useful base type for the candidate set, we'll want to + // substitute it into each member. If not, ignore it. + if (isUnresolvedOrTypeVarType(baseType)) + baseType = Type(); + for (auto cand : overloads) { - if (cand.isDecl()) - candidates.push_back({ cand.getDecl(), uncurryLevel }); + if (!cand.isDecl()) continue; + + auto decl = cand.getDecl(); + candidates.push_back({ decl, uncurryLevel }); + + if (baseType) { + auto substType = baseType->getTypeOfMember(CS->DC->getParentModule(), + decl, nullptr); + if (substType) + candidates.back().declType = substType; + } } - + if (!candidates.empty()) declName = candidates[0].decl->getNameStr().str(); } @@ -1716,6 +1652,170 @@ suggestPotentialOverloads(SourceLoc loc, bool isResult) { } } + +/// If the candidate set has been narrowed down to a specific structural +/// problem, e.g. that there are too few parameters specified or that argument +/// labels don't match up, diagnose that error and return true. +bool CalleeCandidateInfo::diagnoseAnyStructuralArgumentError(Expr *fnExpr, + Expr *argExpr) { + // TODO: We only handle the situation where there is exactly one candidate + // here. + if (size() != 1) return false; + + + auto args = decomposeArgParamType(argExpr->getType()); + + auto argTy = candidates[0].getArgumentType(); + if (!argTy) return false; + + auto params = decomposeArgParamType(argTy); + + // It is a somewhat common error to try to access an instance method as a + // curried member on the type, instead of using an instance, e.g. the user + // wrote: + // + // Foo.doThing(42, b: 19) + // + // instead of: + // + // myFoo.doThing(42, b: 19) + // + // Check for this situation and handle it gracefully. + if (params.size() == 1 && candidates[0].decl->isInstanceMember() && + candidates[0].level == 0) { + if (auto UDE = dyn_cast(fnExpr)) + if (isa(UDE->getBase())) { + auto baseType = candidates[0].getArgumentType(); + CS->TC.diagnose(UDE->getLoc(), diag::instance_member_use_on_type, + baseType, UDE->getName()) + .highlight(UDE->getBase()->getSourceRange()); + return true; + } + } + + // We only handle structural errors here. + if (closeness != CC_ArgumentLabelMismatch && + closeness != CC_ArgumentCountMismatch) + return false; + + SmallVector correctNames; + unsigned OOOArgIdx = ~0U, OOOPrevArgIdx = ~0U; + unsigned extraArgIdx = ~0U, missingParamIdx = ~0U; + + // If we have a single candidate that failed to match the argument list, + // attempt to use matchCallArguments to diagnose the problem. + struct OurListener : public MatchCallArgumentListener { + SmallVectorImpl &correctNames; + unsigned &OOOArgIdx, &OOOPrevArgIdx; + unsigned &extraArgIdx, &missingParamIdx; + + public: + OurListener(SmallVectorImpl &correctNames, + unsigned &OOOArgIdx, unsigned &OOOPrevArgIdx, + unsigned &extraArgIdx, unsigned &missingParamIdx) + : correctNames(correctNames), + OOOArgIdx(OOOArgIdx), OOOPrevArgIdx(OOOPrevArgIdx), + extraArgIdx(extraArgIdx), missingParamIdx(missingParamIdx) {} + void extraArgument(unsigned argIdx) override { + extraArgIdx = argIdx; + } + void missingArgument(unsigned paramIdx) override { + missingParamIdx = paramIdx; + } + void outOfOrderArgument(unsigned argIdx, unsigned prevArgIdx) override{ + OOOArgIdx = argIdx; + OOOPrevArgIdx = prevArgIdx; + } + bool relabelArguments(ArrayRef newNames) override { + correctNames.append(newNames.begin(), newNames.end()); + return true; + } + } listener(correctNames, OOOArgIdx, OOOPrevArgIdx, + extraArgIdx, missingParamIdx); + + // Use matchCallArguments to determine how close the argument list is (in + // shape) to the specified candidates parameters. This ignores the + // concrete types of the arguments, looking only at the argument labels. + SmallVector paramBindings; + if (!matchCallArguments(args, params, hasTrailingClosure, + /*allowFixes:*/true, listener, paramBindings)) + return false; + + + // If we are missing a parameter, diagnose that. + if (missingParamIdx != ~0U) { + Identifier name = params[missingParamIdx].Label; + auto loc = argExpr->getStartLoc(); + if (name.empty()) + CS->TC.diagnose(loc, diag::missing_argument_positional, + missingParamIdx+1); + else + CS->TC.diagnose(loc, diag::missing_argument_named, name); + return true; + } + + if (extraArgIdx != ~0U) { + auto name = args[extraArgIdx].Label; + Expr *arg = argExpr; + auto tuple = dyn_cast(argExpr); + if (tuple) + arg = tuple->getElement(extraArgIdx); + auto loc = arg->getLoc(); + if (tuple && extraArgIdx == tuple->getNumElements()-1 && + tuple->hasTrailingClosure()) + CS->TC.diagnose(loc, diag::extra_trailing_closure_in_call) + .highlight(arg->getSourceRange()); + else if (params.empty()) + CS->TC.diagnose(loc, diag::extra_argument_to_nullary_call) + .highlight(argExpr->getSourceRange()); + else if (name.empty()) + CS->TC.diagnose(loc, diag::extra_argument_positional) + .highlight(arg->getSourceRange()); + else + CS->TC.diagnose(loc, diag::extra_argument_named, name) + .highlight(arg->getSourceRange()); + return true; + } + + // If this is an argument label mismatch, then diagnose that error now. + if (!correctNames.empty() && + CS->diagnoseArgumentLabelError(argExpr, correctNames, + /*isSubscript=*/false)) + return true; + + // If we have an out-of-order argument, diagnose it as such. + if (OOOArgIdx != ~0U && isa(argExpr)) { + auto tuple = cast(argExpr); + Identifier first = tuple->getElementName(OOOArgIdx); + Identifier second = tuple->getElementName(OOOPrevArgIdx); + + SourceLoc diagLoc; + if (!first.empty()) + diagLoc = tuple->getElementNameLoc(OOOArgIdx); + else + diagLoc = tuple->getElement(OOOArgIdx)->getStartLoc(); + + if (!second.empty()) { + CS->TC.diagnose(diagLoc, diag::argument_out_of_order, first, second) + .highlight(tuple->getElement(OOOArgIdx)->getSourceRange()) + .highlight(SourceRange(tuple->getElementNameLoc(OOOPrevArgIdx), + tuple->getElement(OOOPrevArgIdx)->getEndLoc())); + return true; + } + + CS->TC.diagnose(diagLoc, diag::argument_out_of_order_named_unnamed, first, + OOOPrevArgIdx) + .highlight(tuple->getElement(OOOArgIdx)->getSourceRange()) + .highlight(tuple->getElement(OOOPrevArgIdx)->getSourceRange()); + return true; + } + return false; +} + + + + + /// Flags that can be used to control name lookup. enum TCCFlags { /// Allow the result of the subexpression to be an lvalue. If this is not @@ -1839,6 +1939,7 @@ class FailureDiagnosis :public ASTVisitor{ bool visitUnresolvedMemberExpr(UnresolvedMemberExpr *E); bool visitArrayExpr(ArrayExpr *E); bool visitDictionaryExpr(DictionaryExpr *E); + bool visitObjectLiteralExpr(ObjectLiteralExpr *E); bool visitForceValueExpr(ForceValueExpr *FVE); bool visitBindOptionalExpr(BindOptionalExpr *BOE); @@ -1881,14 +1982,16 @@ static bool isConversionConstraint(const Constraint *C) { /// low that we would only like to issue an error message about it if there is /// nothing else interesting we can scrape out of the constraint system. static bool isLowPriorityConstraint(Constraint *C) { - // If the member constraint is a ".Element" lookup to find the element type of - // a generator in a foreach loop, then it is very low priority: We will get a - // better and more useful diagnostic from the failed conversion to - // SequenceType that will fail as well. + // If the member constraint is a ".Generator" lookup to find the generator + // type in a foreach loop, or a ".Element" lookup to find its element type, + // then it is very low priority: We will get a better and more useful + // diagnostic from the failed conversion to SequenceType that will fail as + // well. if (C->getKind() == ConstraintKind::TypeMember) { if (auto *loc = C->getLocator()) for (auto Elt : loc->getPath()) - if (Elt.getKind() == ConstraintLocator::GeneratorElementType) + if (Elt.getKind() == ConstraintLocator::GeneratorElementType || + Elt.getKind() == ConstraintLocator::SequenceGeneratorType) return true; } @@ -1927,7 +2030,7 @@ bool FailureDiagnosis::diagnoseConstraintFailure() { if (isConversionConstraint(C)) return rankedConstraints.push_back({C, CR_ConversionConstraint}); - // We occassionally end up with disjunction constraints containing an + // We occasionally end up with disjunction constraints containing an // original constraint along with one considered with a fix. If we find // this situation, add the original one to our list for diagnosis. if (C->getKind() == ConstraintKind::Disjunction) { @@ -1978,7 +2081,7 @@ bool FailureDiagnosis::diagnoseConstraintFailure() { classifyConstraint(&C); // Okay, now that we've classified all the constraints, sort them by their - // priority and priviledge the favored constraints. + // priority and privilege the favored constraints. std::stable_sort(rankedConstraints.begin(), rankedConstraints.end(), [&] (RCElt LHS, RCElt RHS) { // Rank things by their kind as the highest priority. @@ -2149,7 +2252,7 @@ bool FailureDiagnosis::diagnoseGeneralMemberFailure(Constraint *constraint) { if (allUnavailable) { auto firstDecl = result.ViableCandidates[0].getDecl(); if (CS->TC.diagnoseExplicitUnavailability(firstDecl, anchor->getLoc(), - CS->DC, nullptr)) + CS->DC)) return true; } @@ -2252,7 +2355,7 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy, return; } -// In the absense of a better conversion constraint failure, point out the +// In the absence of a better conversion constraint failure, point out the // inability to find an appropriate overload. bool FailureDiagnosis::diagnoseGeneralOverloadFailure(Constraint *constraint) { Constraint *bindOverload = constraint; @@ -2324,7 +2427,7 @@ bool FailureDiagnosis::diagnoseGeneralConversionFailure(Constraint *constraint){ Type fromType = CS->simplifyType(constraint->getFirstType()); - if (fromType->is() && resolvedAnchorToExpr) { + if (fromType->hasTypeVariable() && resolvedAnchorToExpr) { TCCOptions options; // If we know we're removing a contextual constraint, then we can force a @@ -2415,12 +2518,16 @@ bool FailureDiagnosis::diagnoseGeneralConversionFailure(Constraint *constraint){ return true; } - // Emit a conformance error through conformsToProtocol. If this succeeds, - // then keep searching. + // Emit a conformance error through conformsToProtocol. If this succeeds + // and yields a valid protocol conformance, then keep searching. + ProtocolConformance *Conformance = nullptr; if (CS->TC.conformsToProtocol(fromType, PT->getDecl(), CS->DC, ConformanceCheckFlags::InExpression, - nullptr, expr->getLoc())) - return false; + &Conformance, expr->getLoc())) { + if (!Conformance || !Conformance->isInvalid()) { + return false; + } + } return true; } @@ -2467,31 +2574,77 @@ bool FailureDiagnosis::diagnoseGeneralConversionFailure(Constraint *constraint){ } namespace { - class ExprTypeSaver { + class ExprTypeSaverAndEraser { llvm::DenseMap ExprTypes; llvm::DenseMap> TypeLocTypes; llvm::DenseMap PatternTypes; + llvm::DenseMap ParamDeclTypes; + ExprTypeSaverAndEraser(const ExprTypeSaverAndEraser&) = delete; + void operator=(const ExprTypeSaverAndEraser&) = delete; public: - void save(Expr *E) { + ExprTypeSaverAndEraser(Expr *E) { struct TypeSaver : public ASTWalker { - ExprTypeSaver *TS; - TypeSaver(ExprTypeSaver *TS) : TS(TS) {} + ExprTypeSaverAndEraser *TS; + TypeSaver(ExprTypeSaverAndEraser *TS) : TS(TS) {} std::pair walkToExprPre(Expr *expr) override { TS->ExprTypes[expr] = expr->getType(); + + // Preserve module expr type data to prevent further lookups. + if (auto *declRef = dyn_cast(expr)) + if (isa(declRef->getDecl())) + return { false, expr }; + + // Don't strip type info off OtherConstructorDeclRefExpr, because CSGen + // doesn't know how to reconstruct it. + if (isa(expr)) + return { false, expr }; + + // TypeExpr's are relabeled by CSGen. + if (isa(expr)) + return { false, expr }; + + // If a literal has a Builtin.Int or Builtin.FP type on it already, + // then sema has already expanded out a call to + // Init.init() + // and we don't want it to make + // Init.init(Init.init()) + // preserve the type info to prevent this from happening. + if (isa(expr) && + !(expr->getType() && expr->getType()->is())) + return { false, expr }; + + // If a ClosureExpr's parameter list has types on the decls, and the + // types and remove them so that they'll get regenerated from the + // associated TypeLocs or resynthesized as fresh typevars. + if (auto *CE = dyn_cast(expr)) + for (auto P : *CE->getParameters()) + if (P->hasType()) { + TS->ParamDeclTypes[P] = P->getType(); + P->overwriteType(Type()); + } + + expr->setType(nullptr); + expr->clearLValueAccessKind(); + return { true, expr }; } + // If we find a TypeLoc (e.g. in an as? expr), save and erase it. bool walkToTypeLocPre(TypeLoc &TL) override { - if (TL.getTypeRepr() && TL.getType()) + if (TL.getTypeRepr() && TL.getType()) { TS->TypeLocTypes[&TL] = { TL.getType(), TL.wasValidated() }; + TL.setType(Type(), /*was validated*/false); + } return true; } std::pair walkToPatternPre(Pattern *P) override { - if (P->hasType()) + if (P->hasType()) { TS->PatternTypes[P] = P->getType(); + P->setType(Type()); + } return { true, P }; } @@ -2505,7 +2658,7 @@ namespace { E->walk(TypeSaver(this)); } - void restore(Expr *E) { + void restore() { for (auto exprElt : ExprTypes) exprElt.first->setType(exprElt.second); @@ -2516,6 +2669,9 @@ namespace { for (auto patternElt : PatternTypes) patternElt.first->setType(patternElt.second); + for (auto paramDeclElt : ParamDeclTypes) + paramDeclElt.first->setType(paramDeclElt.second); + // Done, don't do redundant work on destruction. ExprTypes.clear(); TypeLocTypes.clear(); @@ -2529,7 +2685,7 @@ namespace { // and if expr-specific diagnostics fail to turn up anything useful to say, // we go digging through failed constraints, and expect their locators to // still be meaningful. - ~ExprTypeSaver() { + ~ExprTypeSaverAndEraser() { for (auto exprElt : ExprTypes) if (!exprElt.first->getType()) exprElt.first->setType(exprElt.second); @@ -2542,72 +2698,15 @@ namespace { for (auto patternElt : PatternTypes) if (!patternElt.first->hasType()) patternElt.first->setType(patternElt.second); - } - }; -} - -/// \brief "Nullify" an expression tree's type data, to make it suitable for -/// re-typecheck operations. -static void eraseTypeData(Expr *expr) { - /// Private class to "cleanse" an expression tree of types. This is done in the - /// case of a typecheck failure, where we may want to re-typecheck partially- - /// typechecked subexpressions in a context-free manner. - class TypeNullifier : public ASTWalker { - public: - std::pair walkToExprPre(Expr *expr) override { - // Preserve module expr type data to prevent further lookups. - if (auto *declRef = dyn_cast(expr)) - if (isa(declRef->getDecl())) - return { false, expr }; - - // Don't strip type info off OtherConstructorDeclRefExpr, because CSGen - // doesn't know how to reconstruct it. - if (isa(expr)) - return { false, expr }; - - // TypeExpr's are relabeled by CSGen. - if (isa(expr)) - return { false, expr }; - - // If a literal has a Builtin.Int or Builtin.FP type on it already, - // then sema has already expanded out a call to - // Init.init() - // and we don't want it to make - // Init.init(Init.init()) - // preserve the type info to prevent this from happening. - if (isa(expr) && - !(expr->getType() && expr->getType()->is())) - return { false, expr }; - expr->setType(nullptr); - expr->clearLValueAccessKind(); - return { true, expr }; - } - - // If we find a TypeLoc (e.g. in an as? expr) with a type variable, rewrite - // it. - bool walkToTypeLocPre(TypeLoc &TL) override { - if (TL.getTypeRepr()) - TL.setType(Type(), /*was validated*/false); - return true; - } - - std::pair walkToPatternPre(Pattern *pattern) override { - pattern->setType(nullptr); - return { true, pattern }; - } - - // Don't walk into statements. This handles the BraceStmt in - // non-single-expr closures, so we don't walk into their body. - std::pair walkToStmtPre(Stmt *S) override { - return { false, S }; + for (auto paramDeclElt : ParamDeclTypes) + if (!paramDeclElt.first->hasType()) + paramDeclElt.first->setType(paramDeclElt.second); + } }; - - expr->walk(TypeNullifier()); } - /// Erase an expression tree's open existentials after a re-typecheck operation. /// /// This is done in the case of a typecheck failure, after we re-typecheck @@ -2733,7 +2832,7 @@ typeCheckChildIndependently(Expr *subExpr, Type convertType, // If we have no contextual type information and the subexpr is obviously a // overload set, don't recursively simplify this. The recursive solver will - // sometimes pick one based on arbitrary ranking behavior behavior (e.g. like + // sometimes pick one based on arbitrary ranking behavior (e.g. like // which is the most specialized) even then all the constraints are being // fulfilled by UnresolvedType, which doesn't tell us anything. if (convertTypePurpose == CTP_Unused && @@ -2742,21 +2841,25 @@ typeCheckChildIndependently(Expr *subExpr, Type convertType, return subExpr; } - ExprTypeSaver SavedTypeData; - SavedTypeData.save(subExpr); + // Save any existing type data of the subexpr tree, and reset it to null in + // prep for re-type-checking the tree. If things fail, we can revert the + // types back to their original state. + ExprTypeSaverAndEraser SavedTypeData(subExpr); // Store off the sub-expression, in case a new one is provided via the // type check operation. Expr *preCheckedExpr = subExpr; - - eraseTypeData(subExpr); - + // Disable structural checks, because we know that the overall expression // has type constraint problems, and we don't want to know about any // syntactic issues in a well-typed subexpression (which might be because // the context is missing). TypeCheckExprOptions TCEOptions = TypeCheckExprFlags::DisableStructuralChecks; + // Don't walk into non-single expression closure bodies, because + // ExprTypeSaver and TypeNullifier skip them too. + TCEOptions |= TypeCheckExprFlags::SkipMultiStmtClosures; + // Claim that the result is discarded to preserve the lvalue type of // the expression. if (options.contains(TCC_AllowLValue)) @@ -2789,7 +2892,7 @@ typeCheckChildIndependently(Expr *subExpr, Type convertType, // just pretend as though nothing happened. if (subExpr->getType()->is()) { subExpr = preCheckedExpr; - SavedTypeData.restore(subExpr); + SavedTypeData.restore(); } CS->TC.addExprForDiagnosis(preCheckedExpr, subExpr); @@ -2822,10 +2925,11 @@ typeCheckArbitrarySubExprIndependently(Expr *subExpr, TCCOptions options) { // none of its arguments are type variables. If so, these type variables // would be accessible to name lookup of the subexpression and may thus leak // in. Reset them to UnresolvedTypes for safe measures. - CE->getParams()->forEachVariable([&](VarDecl *VD) { + for (auto param : *CE->getParameters()) { + auto VD = param; if (VD->getType()->hasTypeVariable() || VD->getType()->is()) VD->overwriteType(CS->getASTContext().TheUnresolvedType); - }); + } } // When we're type checking a single-expression closure, we need to reset the @@ -2889,6 +2993,28 @@ bool FailureDiagnosis::diagnoseCalleeResultContextualConversionError() { } } + +/// Return true if the conversion from fromType to toType is an invalid string +/// index operation. +static bool isIntegerToStringIndexConversion(Type fromType, Type toType, + ConstraintSystem *CS) { + auto integerType = + CS->TC.getProtocol(SourceLoc(), + KnownProtocolKind::IntegerLiteralConvertible); + if (!integerType) return false; + + // If the from type is an integer type, and the to type is + // String.CharacterView.Index, then we found one. + if (CS->TC.conformsToProtocol(fromType, integerType, CS->DC, + ConformanceCheckFlags::InExpression)) { + if (toType->getCanonicalType().getString() == "String.CharacterView.Index") + return true; + } + + return false; +} + + bool FailureDiagnosis::diagnoseContextualConversionError() { // If the constraint system has a contextual type, then we can test to see if // this is the problem that prevents us from solving the system. @@ -3044,6 +3170,18 @@ bool FailureDiagnosis::diagnoseContextualConversionError() { return true; } + exprType = exprType->getRValueType(); + + // Special case of some common conversions involving Swift.String + // indexes, catching cases where people attempt to index them with an integer. + if (isIntegerToStringIndexConversion(exprType, contextualType, CS)) { + diagnose(expr->getLoc(), diag::string_index_not_integer, + exprType->getRValueType()) + .highlight(expr->getSourceRange()); + diagnose(expr->getLoc(), diag::string_index_not_integer_note); + return true; + } + // When complaining about conversion to a protocol type, complain about // conformance instead of "conversion". if (contextualType->is() || @@ -3072,7 +3210,7 @@ bool FailureDiagnosis::diagnoseContextualConversionError() { diagID = diag::noescape_functiontype_mismatch; } - diagnose(expr->getLoc(), diagID, exprType->getRValueType(), contextualType) + diagnose(expr->getLoc(), diagID, exprType, contextualType) .highlight(expr->getSourceRange()); return true; } @@ -3127,8 +3265,17 @@ typeCheckArgumentChildIndependently(Expr *argExpr, Type argType, if (candidates.size() == 1 && !argType) argType = candidates[0].getArgumentType(); } + + // If our candidates are instance members at curry level #0, then the argument + // being provided is the receiver type for the instance. We produce better + // diagnostics when we don't force the self type down. + if (argType && !candidates.empty() && + candidates[0].decl->isInstanceMember() && candidates[0].level == 0 && + !isa(candidates[0].decl)) + argType = Type(); + - // FIXME: This should all just be a matter of getting type type of the + // FIXME: This should all just be a matter of getting the type of the // sub-expression, but this doesn't work well when typeCheckChildIndependently // is over-conservative w.r.t. TupleExprs. auto *TE = dyn_cast(argExpr); @@ -3332,7 +3479,7 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) { - CalleeCandidateInfo calleeInfo(result.ViableCandidates, 0, + CalleeCandidateInfo calleeInfo(baseType, result.ViableCandidates, 0, /*FIXME: Subscript trailing closures*/ /*hasTrailingClosure*/false, CS); @@ -3367,7 +3514,7 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) { // Explode out multi-index subscripts to find the best match. auto indexResult = - evaluateCloseness(SD->getIndicesType(), decomposedIndexType, + evaluateCloseness(cand.getArgumentType(), decomposedIndexType, /*FIXME: Subscript trailing closures*/false); if (selfConstraint > indexResult.first) return {selfConstraint, {}}; @@ -3397,8 +3544,7 @@ bool FailureDiagnosis::visitSubscriptExpr(SubscriptExpr *SE) { if (calleeInfo.closeness == CC_Unavailable) { if (CS->TC.diagnoseExplicitUnavailability(calleeInfo[0].decl, - SE->getLoc(), - CS->DC, nullptr)) + SE->getLoc(), CS->DC)) return true; return false; } @@ -3434,7 +3580,7 @@ namespace { // If we have no contextual type, there is nothing to do. if (!contextualType) return false; - // If the expresion is obviously something that produces a metatype, + // If the expression is obviously something that produces a metatype, // then don't put a constraint on it. auto semExpr = expr->getValueProvidingExpr(); if (isa(semExpr) ||isa(semExpr)) @@ -3536,7 +3682,10 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) { // Filter the candidate list based on the argument we may or may not have. calleeInfo.filterContextualMemberList(callExpr->getArg()); - + + if (calleeInfo.diagnoseAnyStructuralArgumentError(callExpr->getFn(), + callExpr->getArg())) + return true; Type argType; // Type of the argument list, if knowable. if (auto FTy = fnType->getAs()) @@ -3560,82 +3709,8 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) { calleeInfo.filterList(argExpr->getType()); - - // If we filtered this down to exactly one candidate, see if we can produce - // an extremely specific error about it. - if (calleeInfo.size() == 1) { - if (calleeInfo.closeness == CC_ArgumentLabelMismatch) { - auto args = decomposeArgParamType(argExpr->getType()); - SmallVector correctNames; - unsigned OOOArgIdx = ~0U, OOOPrevArgIdx = ~0U; - - // If we have a single candidate that failed to match the argument list, - // attempt to use matchCallArguments to diagnose the problem. - struct OurListener : public MatchCallArgumentListener { - SmallVectorImpl &correctNames; - unsigned &OOOArgIdx, &OOOPrevArgIdx; - - public: - OurListener(SmallVectorImpl &correctNames, - unsigned &OOOArgIdx, unsigned &OOOPrevArgIdx) - : correctNames(correctNames), - OOOArgIdx(OOOArgIdx), OOOPrevArgIdx(OOOPrevArgIdx) {} - void extraArgument(unsigned argIdx) override {} - void missingArgument(unsigned paramIdx) override {} - void outOfOrderArgument(unsigned argIdx, unsigned prevArgIdx) override{ - OOOArgIdx = argIdx; - OOOPrevArgIdx = prevArgIdx; - } - bool relabelArguments(ArrayRef newNames) override { - correctNames.append(newNames.begin(), newNames.end()); - return true; - } - } listener(correctNames, OOOArgIdx, OOOPrevArgIdx); - - // Use matchCallArguments to determine how close the argument list is (in - // shape) to the specified candidates parameters. This ignores the - // concrete types of the arguments, looking only at the argument labels. - SmallVector paramBindings; - auto params = decomposeArgParamType(calleeInfo[0].getArgumentType()); - if (matchCallArguments(args, params, hasTrailingClosure, - /*allowFixes:*/true, listener, paramBindings)) { - - // If this is a argument label mismatch, then diagnose that error now. - if (!correctNames.empty() && - CS->diagnoseArgumentLabelError(argExpr, correctNames, - /*isSubscript=*/false)) - return true; - - // If we have an out-of-order argument, diagnose it as such. - if (OOOArgIdx != ~0U && isa(callExpr->getArg())) { - auto tuple = cast(callExpr->getArg()); - Identifier first = tuple->getElementName(OOOArgIdx); - Identifier second = tuple->getElementName(OOOPrevArgIdx); - - SourceLoc diagLoc; - if (!first.empty()) - diagLoc = tuple->getElementNameLoc(OOOArgIdx); - else - diagLoc = tuple->getElement(OOOArgIdx)->getStartLoc(); - - if (!second.empty()) { - diagnose(diagLoc, - diag::argument_out_of_order, first, second) - .highlight(tuple->getElement(OOOArgIdx)->getSourceRange()) - .highlight(SourceRange(tuple->getElementNameLoc(OOOPrevArgIdx), - tuple->getElement(OOOPrevArgIdx)->getEndLoc())); - return true; - } - - diagnose(diagLoc, diag::argument_out_of_order_named_unnamed, first, - OOOPrevArgIdx) - .highlight(tuple->getElement(OOOArgIdx)->getSourceRange()) - .highlight(tuple->getElement(OOOPrevArgIdx)->getSourceRange()); - return true; - } - } - } - } + if (calleeInfo.diagnoseAnyStructuralArgumentError(callExpr->getFn(), argExpr)) + return true; // If we have a failure where the candidate set differs on exactly one // argument, and where we have a consistent mismatch across the candidate set @@ -3676,8 +3751,7 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) { // Handle uses of unavailable symbols. if (calleeInfo.closeness == CC_Unavailable) return CS->TC.diagnoseExplicitUnavailability(calleeInfo[0].decl, - callExpr->getLoc(), - CS->DC, nullptr); + callExpr->getLoc(), CS->DC); // A common error is to apply an operator that only has inout forms (e.g. +=) // to non-lvalues (e.g. a local let). Produce a nice diagnostic for this @@ -3925,7 +3999,7 @@ bool FailureDiagnosis::visitInOutExpr(InOutExpr *IOE) { auto pointerEltType = pointerType->getGenericArgs()[0]; // If the element type is Void, then we allow any input type, since - // everything is convertable to UnsafePointer + // everything is convertible to UnsafePointer if (pointerEltType->isVoid()) contextualType = Type(); else @@ -4090,19 +4164,17 @@ bool FailureDiagnosis::visitClosureExpr(ClosureExpr *CE) { CS->getContextualType()->is()) { auto fnType = CS->getContextualType()->castTo(); - Pattern *params = CE->getParams(); + auto *params = CE->getParameters(); Type inferredArgType = fnType->getInput(); // It is very common for a contextual type to disagree with the argument // list built into the closure expr. This can be because the closure expr - // had an explicitly specified pattern, ala: + // had an explicitly specified pattern, a la: // { a,b in ... } // or could be because the closure has an implicitly generated one: // { $0 + $1 } // in either case, we want to produce nice and clear diagnostics. - unsigned actualArgCount = 1; - if (auto *TP = dyn_cast(params)) - actualArgCount = TP->getNumElements(); + unsigned actualArgCount = params->size(); unsigned inferredArgCount = 1; if (auto *argTupleTy = inferredArgType->getAs()) inferredArgCount = argTupleTy->getNumElements(); @@ -4145,15 +4217,9 @@ bool FailureDiagnosis::visitClosureExpr(ClosureExpr *CE) { fnType, inferredArgCount, actualArgCount); return true; } - - TypeResolutionOptions TROptions; - TROptions |= TR_OverrideType; - TROptions |= TR_FromNonInferredPattern; - TROptions |= TR_InExpression; - TROptions |= TR_ImmediateFunctionInput; - if (CS->TC.coercePatternToType(params, CE, inferredArgType, TROptions)) + + if (CS->TC.coerceParameterListToType(params, CE, inferredArgType)) return true; - CE->setParams(params); expectedResultType = fnType->getResult(); } else { @@ -4164,10 +4230,10 @@ bool FailureDiagnosis::visitClosureExpr(ClosureExpr *CE) { // lookups against the parameter decls. // // Handle this by rewriting the arguments to UnresolvedType(). - CE->getParams()->forEachVariable([&](VarDecl *VD) { + for (auto VD : *CE->getParameters()) { if (VD->getType()->hasTypeVariable() || VD->getType()->is()) VD->overwriteType(CS->getASTContext().TheUnresolvedType); - }); + } } // If this is a complex leaf closure, there is nothing more we can do. @@ -4270,10 +4336,20 @@ bool FailureDiagnosis::visitArrayExpr(ArrayExpr *E) { } if (!foundConformance) { + // If the contextual type conforms to DictionaryLiteralConvertible and + // this is an empty array, then they meant "[:]". + if (E->getNumElements() == 0 && + isDictionaryLiteralCompatible(contextualType, CS, E->getLoc())) { + diagnose(E->getStartLoc(), diag::should_use_empty_dictionary_literal) + .fixItInsert(E->getEndLoc(), ":"); + return true; + } + + diagnose(E->getStartLoc(), diag::type_is_not_array, contextualType) .highlight(E->getSourceRange()); - // If the contextual type conforms to DicitonaryLiteralConvertible, then + // If the contextual type conforms to DictionaryLiteralConvertible, then // they wrote "x = [1,2]" but probably meant "x = [1:2]". if ((E->getElements().size() & 1) == 0 && !E->getElements().empty() && isDictionaryLiteralCompatible(contextualType, CS, E->getLoc())) { @@ -4382,6 +4458,77 @@ bool FailureDiagnosis::visitDictionaryExpr(DictionaryExpr *E) { return false; } +/// When an object literal fails to typecheck because its protocol's +/// corresponding default type has not been set in the global namespace (e.g. +/// _ColorLiteralType), suggest that the user import the appropriate module for +/// the target. +bool FailureDiagnosis::visitObjectLiteralExpr(ObjectLiteralExpr *E) { + auto &TC = CS->getTypeChecker(); + + // Type check the argument first. + auto protocol = TC.getLiteralProtocol(E); + if (!protocol) + return false; + DeclName constrName = TC.getObjectLiteralConstructorName(E); + assert(constrName); + ArrayRef constrs = protocol->lookupDirect(constrName); + if (constrs.size() != 1 || !isa(constrs.front())) + return false; + auto *constr = cast(constrs.front()); + if (!typeCheckChildIndependently( + E->getArg(), constr->getArgumentType(), CTP_CallArgument)) + return true; + + // Conditions for showing this diagnostic: + // * The object literal protocol's default type is unimplemented + if (TC.getDefaultType(protocol, CS->DC)) + return false; + // * The object literal has no contextual type + if (CS->getContextualType()) + return false; + + // Figure out what import to suggest. + auto &Ctx = CS->getASTContext(); + const auto &target = Ctx.LangOpts.Target; + StringRef plainName = E->getName().str(); + StringRef importModule; + StringRef importDefaultTypeName; + if (protocol == Ctx.getProtocol(KnownProtocolKind::ColorLiteralConvertible)) { + plainName = "color"; + if (target.isMacOSX()) { + importModule = "AppKit"; + importDefaultTypeName = "NSColor"; + } else if (target.isiOS() || target.isTvOS()) { + importModule = "UIKit"; + importDefaultTypeName = "UIColor"; + } + } else if (protocol == Ctx.getProtocol( + KnownProtocolKind::ImageLiteralConvertible)) { + plainName = "image"; + if (target.isMacOSX()) { + importModule = "AppKit"; + importDefaultTypeName = "NSImage"; + } else if (target.isiOS() || target.isTvOS()) { + importModule = "UIKit"; + importDefaultTypeName = "UIImage"; + } + } else if (protocol == Ctx.getProtocol( + KnownProtocolKind::FileReferenceLiteralConvertible)) { + plainName = "file reference"; + importModule = "Foundation"; + importDefaultTypeName = "NSURL"; + } + + // Emit the diagnostic. + TC.diagnose(E->getLoc(), diag::object_literal_default_type_missing, + plainName); + if (!importModule.empty()) { + TC.diagnose(E->getLoc(), diag::object_literal_resolve_import, + importModule, importDefaultTypeName, plainName); + } + return true; +} + bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { // If we have no contextual type, there is no way to resolve this. Just // diagnose this as an ambiguity. @@ -4450,7 +4597,7 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { // Dump all of our viable candidates into a CalleeCandidateInfo (with an // uncurry level of 1 to represent the contextual type) and sort it out. - CalleeCandidateInfo candidateInfo(result.ViableCandidates, 1, + CalleeCandidateInfo candidateInfo(baseObjTy, result.ViableCandidates, 1, hasTrailingClosure, CS); // Filter the candidate list based on the argument we may or may not have. @@ -4498,7 +4645,7 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { case CC_Unavailable: if (CS->TC.diagnoseExplicitUnavailability(candidateInfo[0].decl, - E->getLoc(), CS->DC, nullptr)) + E->getLoc(), CS->DC)) return true; return false; diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index e4c1e480d5134..0399ff37794ef 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,6 +19,7 @@ #include "swift/AST/ASTWalker.h" #include "swift/AST/Attr.h" #include "swift/AST/Expr.h" +#include "swift/AST/ParameterList.h" #include "swift/Sema/CodeCompletionTypeChecking.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/APInt.h" @@ -53,7 +54,7 @@ static ValueDecl *findReferencedDecl(Expr *expr, SourceLoc &loc) { } /// \brief Return 'true' if the decl in question refers to an operator that -/// could be added to the global scope via a delayed protcol conformance. +/// could be added to the global scope via a delayed protocol conformance. /// Currently, this is only true for '==', which is added via an Equatable /// conformance. static bool isDelayedOperatorDecl(ValueDecl *vd) { @@ -337,7 +338,7 @@ namespace { /// of the overload set and call arguments. /// /// \param expr The application. - /// \param isFavored Determine wheth the given overload is favored. + /// \param isFavored Determine whether the given overload is favored. /// \param createReplacements If provided, a function that creates a set of /// replacement fallback constraints. /// \param mustConsider If provided, a function to detect the presence of @@ -550,9 +551,7 @@ namespace { /// Return a pair, containing the total parameter count of a function, coupled /// with the number of non-default parameters. std::pair getParamCount(ValueDecl *VD) { - auto fty = VD->getType()->getAs(); - assert(fty && "attempting to count parameters of a non-function type"); auto t = fty->getInput(); @@ -560,13 +559,10 @@ namespace { size_t nNoDefault = 0; if (auto AFD = dyn_cast(VD)) { - for (auto pattern : AFD->getBodyParamPatterns()) { - - if (auto tuplePattern = dyn_cast(pattern)) { - for (auto elt : tuplePattern->getElements()) { - if (elt.getDefaultArgKind() == DefaultArgumentKind::None) - nNoDefault++; - } + for (auto params : AFD->getParameterLists()) { + for (auto param : *params) { + if (!param->isDefaultArgument()) + nNoDefault++; } } } else { @@ -752,7 +748,10 @@ namespace { } Type paramTy = fnTy->getInput(); - auto paramTupleTy = paramTy->castTo(); + auto paramTupleTy = paramTy->getAs(); + if (!paramTupleTy || paramTupleTy->getNumElements() != 2) + return false; + auto firstParamTy = paramTupleTy->getElement(0).getType(); auto secondParamTy = paramTupleTy->getElement(1).getType(); @@ -1514,8 +1513,11 @@ namespace { Type visitSubscriptExpr(SubscriptExpr *expr) { ValueDecl *decl = nullptr; - if (expr->hasDecl()) + if (expr->hasDecl()) { decl = expr->getDecl().getDecl(); + if (decl->isInvalid()) + return Type(); + } return addSubscriptConstraints(expr, expr->getBase(), expr->getIndex(), decl); } @@ -1675,21 +1677,44 @@ namespace { return addMemberRefConstraints(expr, expr->getBase(), name); } + /// Give each parameter in a ClosureExpr a fresh type variable if parameter + /// types were not specified, and return the eventual function type. + Type getTypeForParameterList(ParameterList *params, + ConstraintLocatorBuilder locator) { + for (auto param : *params) { + // If a type was explicitly specified, use its opened type. + if (auto type = param->getTypeLoc().getType()) { + // FIXME: Need a better locator for a pattern as a base. + Type openedType = CS.openType(type, locator); + param->overwriteType(openedType); + continue; + } + + // Otherwise, create a fresh type variable. + Type ty = CS.createTypeVariable(CS.getConstraintLocator(locator), + /*options=*/0); + + param->overwriteType(ty); + } + + return params->getType(CS.getASTContext()); + } + + /// \brief Produces a type for the given pattern, filling in any missing /// type information with fresh type variables. /// /// \param pattern The pattern. - Type getTypeForPattern(Pattern *pattern, bool forFunctionParam, - ConstraintLocatorBuilder locator) { + Type getTypeForPattern(Pattern *pattern, ConstraintLocatorBuilder locator) { switch (pattern->getKind()) { case PatternKind::Paren: // Parentheses don't affect the type. return getTypeForPattern(cast(pattern)->getSubPattern(), - forFunctionParam, locator); + locator); case PatternKind::Var: // Var doesn't affect the type. return getTypeForPattern(cast(pattern)->getSubPattern(), - forFunctionParam, locator); + locator); case PatternKind::Any: // For a pattern of unknown type, create a new type variable. return CS.createTypeVariable(CS.getConstraintLocator(locator), @@ -1720,20 +1745,11 @@ namespace { // For weak variables, use Optional. if (auto *OA = var->getAttrs().getAttribute()) - if (!forFunctionParam && OA->get() == Ownership::Weak) { + if (OA->get() == Ownership::Weak) { ty = CS.getTypeChecker().getOptionalType(var->getLoc(), ty); if (!ty) return Type(); } - // We want to set the variable's type here when type-checking - // a function's parameter clauses because we're going to - // type-check the entire function body within the context of - // the constraint system. In contrast, when type-checking a - // variable binding, we really don't want to set the - // variable's type because it can easily escape the constraint - // system and become a dangling type reference. - if (forFunctionParam) - var->overwriteType(ty); return ty; } @@ -1755,15 +1771,10 @@ namespace { tupleTypeElts.reserve(tuplePat->getNumElements()); for (unsigned i = 0, e = tuplePat->getNumElements(); i != e; ++i) { auto &tupleElt = tuplePat->getElement(i); - bool hasEllipsis = tupleElt.hasEllipsis(); - Type eltTy = getTypeForPattern(tupleElt.getPattern(),forFunctionParam, + Type eltTy = getTypeForPattern(tupleElt.getPattern(), locator.withPathElement( LocatorPathElt::getTupleElement(i))); - - Type varArgBaseTy; - tupleTypeElts.push_back(TupleTypeElt(eltTy, tupleElt.getLabel(), - tupleElt.getDefaultArgKind(), - hasEllipsis)); + tupleTypeElts.push_back(TupleTypeElt(eltTy, tupleElt.getLabel())); } return TupleType::get(tupleTypeElts, CS.getASTContext()); } @@ -2002,7 +2013,8 @@ namespace { // stand in for that parameter or return type, allowing it to be inferred // from context. Type funcTy; - if (expr->hasExplicitResultType()) { + if (expr->hasExplicitResultType() && + expr->getExplicitResultTypeLoc().getType()) { funcTy = expr->getExplicitResultTypeLoc().getType(); } else if (!crt.isNull()) { funcTy = crt; @@ -2023,12 +2035,10 @@ namespace { } } - // Walk through the patterns in the func expression, backwards, - // computing the type of each pattern (which may involve fresh type - // variables where parameter types where no provided) and building the - // eventual function type. - auto paramTy = getTypeForPattern( - expr->getParams(), /*forFunctionParam*/ true, + // Give each parameter in a ClosureExpr a fresh type variable if parameter + // types were not specified, and return the eventual function type. + auto paramTy = getTypeForParameterList( + expr->getParameters(), CS.getConstraintLocator( expr, LocatorPathElt::getTupleElement(0))); @@ -2467,9 +2477,20 @@ namespace { } Type visitEditorPlaceholderExpr(EditorPlaceholderExpr *E) { + if (E->getTypeLoc().isNull()) { + auto locator = CS.getConstraintLocator(E); + auto placeholderTy = CS.createTypeVariable(locator, /*options*/0); + // A placeholder may have any type, but default to Void type if + // otherwise unconstrained. + CS.addConstraint(ConstraintKind::Defaultable, + placeholderTy, TupleType::getEmpty(CS.getASTContext()), + locator); + E->setType(placeholderTy); + } + // NOTE: The type loc may be there but have failed to validate, in which + // case we return the null type. return E->getType(); } - }; /// \brief AST walker that "sanitizes" an expression for the @@ -2617,7 +2638,7 @@ namespace { if (arg != call->getArg()) return; - // Dig out the function, looking through, parenthses, ?, and !. + // Dig out the function, looking through, parentheses, ?, and !. auto fn = call->getFn(); do { fn = fn->getSemanticsProvidingExpr(); @@ -2664,7 +2685,7 @@ Expr *ConstraintSystem::generateConstraints(Expr *expr) { // Remove implicit conversions from the expression. expr = expr->walk(SanitizeExpr(getTypeChecker())); - // Wall the expression to associate labeled argumets. + // Walk the expression to associate labeled arguments. expr->walk(ArgumentLabelWalker(*this, expr)); // Walk the expression, generating constraints. @@ -2698,7 +2719,7 @@ Expr *ConstraintSystem::generateConstraintsShallow(Expr *expr) { Type ConstraintSystem::generateConstraints(Pattern *pattern, ConstraintLocatorBuilder locator) { ConstraintGenerator cg(*this); - return cg.getTypeForPattern(pattern, /*forFunctionParam*/ false, locator); + return cg.getTypeForPattern(pattern, locator); } void ConstraintSystem::optimizeConstraints(Expr *e) { @@ -2740,7 +2761,7 @@ class InferUnresolvedMemberConstraintGenerator : public ConstraintGenerator { return ConstraintGenerator::visitUnresolvedMemberExpr(Expr); } // Otherwise, create a type variable saying we know nothing about this expr. - assert(!VT && "cannot reassign type viriable."); + assert(!VT && "cannot reassign type variable."); return VT = createFreeTypeVariableType(Expr); } @@ -2750,7 +2771,7 @@ class InferUnresolvedMemberConstraintGenerator : public ConstraintGenerator { return ConstraintGenerator::visitParenExpr(Expr); } // Otherwise, create a type variable saying we know nothing about this expr. - assert(!VT && "cannot reassign type viriable."); + assert(!VT && "cannot reassign type variable."); return VT = createFreeTypeVariableType(Expr); } @@ -2760,7 +2781,7 @@ class InferUnresolvedMemberConstraintGenerator : public ConstraintGenerator { return ConstraintGenerator::visitTupleExpr(Expr); } // Otherwise, create a type variable saying we know nothing about this expr. - assert(!VT && "cannot reassign type viriable."); + assert(!VT && "cannot reassign type variable."); return VT = createFreeTypeVariableType(Expr); } diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp index ce1f5f7e90e7a..63b9566d9c784 100644 --- a/lib/Sema/CSRanking.cpp +++ b/lib/Sema/CSRanking.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,9 +21,9 @@ using namespace swift; using namespace constraints; -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Statistics -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #define DEBUG_TYPE "Constraint solver overall" STATISTIC(NumDiscardedSolutions, "# of solutions discarded"); @@ -226,25 +226,6 @@ static Comparison compareWitnessAndRequirement(TypeChecker &tc, DeclContext *dc, return proto1? Comparison::Worse : Comparison::Better; } -namespace { - /// Dependent type opener that maps from a dependent type to its corresponding - /// archetype in the given context. - class ArchetypeOpener : public constraints::DependentTypeOpener { - DeclContext *DC; - - public: - explicit ArchetypeOpener(DeclContext *dc) : DC(dc) { } - - virtual Type mapGenericTypeParamType(GenericTypeParamType *param) { - return ArchetypeBuilder::mapTypeIntoContext(DC, param); - } - - virtual Type mapDependentMemberType(DependentMemberType *memberType) { - return ArchetypeBuilder::mapTypeIntoContext(DC, memberType); - } - }; -} - namespace { /// Describes the relationship between the context types for two declarations. enum class SelfTypeRelationship { @@ -388,27 +369,23 @@ static bool isDeclMoreConstrainedThan(ValueDecl *decl1, ValueDecl *decl2) { return false; } -static TypeBase* getTypeAtIndex(TypeBase* containerType, size_t index) { +static Type getTypeAtIndex(const ParameterList *params, size_t index) { + if (params->size() == 0) + return nullptr; + + if (index < params->size()) { + auto param = params->get(index); + if (param->isVariadic()) + return param->getVarargBaseTy(); - if (auto parenType = dyn_cast(containerType)) { - if (!index) { - return parenType->getDesugaredType(); - } + return param->getType(); } - if (auto tupleType = containerType->getAs()) { - auto elements = tupleType->getElements(); - - if (!elements.empty()) { - if (index < elements.size()) { - if (elements[index].isVararg()) { - return elements[index].getVarargBaseTy().getPointer(); - } - return elements[index].getType().getPointer(); - } else if (elements.back().isVararg()) { - return elements.back().getVarargBaseTy().getPointer(); - } - } + /// FIXME: This looks completely wrong for varargs within a parameter list. + if (params->size() != 0) { + auto lastParam = params->getArray().back(); + if (lastParam->isVariadic()) + return lastParam->getVarargBaseTy(); } return nullptr; @@ -419,36 +396,26 @@ static TypeBase* getTypeAtIndex(TypeBase* containerType, size_t index) { /// against a non-existential parameter at the same position of the first decl. /// This is used to disambiguate function overloads that would otherwise be /// identical after opening their parameter types. -static bool hasEmptyExistenialParameterMismatch(ValueDecl *decl1, - ValueDecl *decl2) { - +static bool hasEmptyExistentialParameterMismatch(ValueDecl *decl1, + ValueDecl *decl2) { auto func1 = dyn_cast(decl1); auto func2 = dyn_cast(decl2); - - if (func1 && func2) { + if (!func1 || !func2) return false; - auto pp1 = func1->getBodyParamPatterns(); - auto pp2 = func2->getBodyParamPatterns(); - - if (pp1.empty() || pp2.empty()) + auto pl1 = func1->getParameterLists(); + auto pl2 = func2->getParameterLists(); + + auto pc = std::min(pl1.size(), pl2.size()); + + for (size_t i = 0; i < pc; i++) { + auto t1 = getTypeAtIndex(pl1[i], i); + auto t2 = getTypeAtIndex(pl2[i], i); + if (!t1 || !t2) return false; - auto pc = std::min(pp1.size(), pp2.size()); - - for (size_t i = 0; i < pc; i++) { - - auto t1 = getTypeAtIndex(pp1[i]->getType().getPointer(), i); - auto t2 = getTypeAtIndex(pp2[i]->getType().getPointer(), i); - - if (!t1 || !t2) - break; - - if (t2->isAnyExistentialType() && !t1->isAnyExistentialType()) { - return t2->isEmptyExistentialComposition(); - } - } + if (t2->isAnyExistentialType() && !t1->isAnyExistentialType()) + return t2->isEmptyExistentialComposition(); } - return false; } @@ -484,7 +451,8 @@ static bool isProtocolExtensionAsSpecializedAs(TypeChecker &tc, ConstraintSystem cs(tc, dc1, None); llvm::DenseMap replacements; cs.openGeneric(dc2, sig2->getGenericParams(), sig2->getRequirements(), - false, nullptr, ConstraintLocatorBuilder(nullptr), + false, dc2->getGenericTypeContextDepth(), + ConstraintLocatorBuilder(nullptr), replacements); // Bind the 'Self' type from the first extension to the type parameter from @@ -503,14 +471,11 @@ static bool isProtocolExtensionAsSpecializedAs(TypeChecker &tc, /// Count the number of default arguments in the primary clause. static unsigned countDefaultArguments(AbstractFunctionDecl *func) { - auto pattern - = func->getBodyParamPatterns()[func->getImplicitSelfDecl() != 0]; - auto tuple = dyn_cast(pattern); - if (!tuple) return 0; + auto paramList = func->getParameterList(func->getImplicitSelfDecl() != 0); unsigned count = 0; - for (const auto &elt : tuple->getElements()) { - if (elt.getDefaultArgKind() != DefaultArgumentKind::None) + for (auto elt : *paramList) { + if (elt->isDefaultArgument()) ++count; } @@ -608,15 +573,20 @@ static bool isDeclAsSpecializedAs(TypeChecker &tc, DeclContext *dc, // FIXME: Locator when anchored on a declaration. // Get the type of a reference to the second declaration. Type openedType2 = cs.openType(type2, locator, - decl2->getPotentialGenericDeclContext()); + decl2->getInnermostDeclContext()); // Get the type of a reference to the first declaration, swapping in // archetypes for the dependent types. - ArchetypeOpener opener(decl1->getPotentialGenericDeclContext()); - Type openedType1 = cs.openType(type1, locator, - decl1->getPotentialGenericDeclContext(), - /*skipProtocolSelfConstraint=*/false, - &opener); + llvm::DenseMap replacements; + auto dc1 = decl1->getInnermostDeclContext(); + Type openedType1 = cs.openType(type1, locator, replacements, dc1); + for (const auto &replacement : replacements) { + if (auto mapped = ArchetypeBuilder::mapTypeIntoContext(dc1, + replacement.first)) { + cs.addConstraint(ConstraintKind::Bind, replacement.second, mapped, + locator); + } + } // Extract the self types from the declarations, if they have them. Type selfTy1; @@ -922,11 +892,11 @@ ConstraintSystem::compareSolutions(ConstraintSystem &cs, // wise comparison between an empty existential collection and a non- // existential type. if (!(foundRefinement1 && foundRefinement2)) { - if (hasEmptyExistenialParameterMismatch(decl1, decl2)) { + if (hasEmptyExistentialParameterMismatch(decl1, decl2)) { foundRefinement1 = true; } - if (hasEmptyExistenialParameterMismatch(decl2, decl1)) { + if (hasEmptyExistentialParameterMismatch(decl2, decl1)) { foundRefinement2 = true; } } @@ -1252,7 +1222,7 @@ ConstraintSystem::findBestSolution(SmallVectorImpl &viable, return None; } -SolutionDiff::SolutionDiff(ArrayRef solutions) { +SolutionDiff::SolutionDiff(ArrayRef solutions) { if (solutions.size() <= 1) return; diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index d21229dc7ddbe..c77266c7ed7d7 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -444,7 +444,7 @@ matchCallArguments(ArrayRef args, if (param.Variadic) continue; - // Parameters with defaults can be unfilfilled. + // Parameters with defaults can be unfulfilled. if (param.HasDefaultArgument) continue; @@ -518,29 +518,7 @@ matchCallArguments(ConstraintSystem &cs, TypeMatchKind kind, ConstraintLocatorBuilder &locator) : CS(cs), ArgType(argType), ParamType(paramType), Locator(locator) { } - virtual void extraArgument(unsigned argIdx) { - if (!CS.shouldRecordFailures()) - return; - - CS.recordFailure(CS.getConstraintLocator(Locator), - Failure::ExtraArgument, - argIdx); - } - - virtual void missingArgument(unsigned paramIdx) { - if (!CS.shouldRecordFailures()) - return; - - CS.recordFailure(CS.getConstraintLocator(Locator), - Failure::MissingArgument, - ParamType, paramIdx); - } - - virtual void outOfOrderArgument(unsigned argIdx, unsigned prevArgIdx) { - return; - } - - virtual bool relabelArguments(ArrayRef newNames) { + bool relabelArguments(ArrayRef newNames) override { if (!CS.shouldAttemptFixes()) { // FIXME: record why this failed. We have renaming. return true; @@ -604,7 +582,7 @@ matchCallArguments(ConstraintSystem &cs, TypeMatchKind kind, case TypeMatchKind::SameType: case TypeMatchKind::ConformsTo: case TypeMatchKind::Subtype: - llvm_unreachable("Not an call argument constraint"); + llvm_unreachable("Not a call argument constraint"); } auto haveOneNonUserConversion = @@ -1167,17 +1145,22 @@ static bool isArrayDictionarySetOrString(const ASTContext &ctx, Type type) { return false; } -/// Return the number of elements of parameter tuple type 'tupleTy' that must -/// be matched to arguments, as opposed to being varargs or having default -/// values. -static unsigned tupleTypeRequiredArgCount(TupleType *tupleTy) { - auto argIsRequired = [&](const TupleTypeElt &elt) { - return !elt.isVararg() && - elt.getDefaultArgKind() == DefaultArgumentKind::None; - }; - return std::count_if( - tupleTy->getElements().begin(), tupleTy->getElements().end(), - argIsRequired); +/// Given that 'tupleTy' is the argument type of a function that's being +/// invoked with a single unlabeled argument, return the type of the parameter +/// that matches that argument, or the null type if such a match is impossible. +static Type getTupleElementTypeForSingleArgument(TupleType *tupleTy) { + Type result; + for (auto ¶m : tupleTy->getElements()) { + bool mustClaimArg = !param.isVararg() && + param.getDefaultArgKind() == DefaultArgumentKind::None; + bool canClaimArg = !param.hasName(); + if (!result && canClaimArg) { + result = param.isVararg() ? param.getVarargBaseTy() : param.getType(); + } else if (mustClaimArg) { + return Type(); + } + } + return result; } ConstraintSystem::SolutionKind @@ -1354,30 +1337,19 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind, case TypeMatchKind::ArgumentTupleConversion: if (typeVar1 && !typeVar1->getImpl().literalConformanceProto && - kind == TypeMatchKind::ArgumentTupleConversion && (flags & TMF_GenerateConstraints) && dyn_cast(type1.getPointer())) { - auto tupleTy = type2->getAs(); - - if (tupleTy && - !tupleTy->getElements().empty() && - (tupleTy->hasAnyDefaultValues() || - tupleTy->getElement(0).isVararg()) && - !tupleTy->getElement(0).hasName() && - tupleTypeRequiredArgCount(tupleTy) <= 1) { - - // Look through vararg types, if necessary. - auto tupleElt = tupleTy->getElement(0); - auto tupleEltTy = tupleElt.isVararg() ? - tupleElt.getVarargBaseTy() : tupleElt.getType(); - - addConstraint(getConstraintKind(kind), - typeVar1, - tupleEltTy, - getConstraintLocator(locator)); - return SolutionKind::Solved; + if (auto tupleTy = type2->getAs()) { + if (auto tupleEltTy = getTupleElementTypeForSingleArgument(tupleTy)) { + addConstraint(getConstraintKind(kind), + typeVar1, + tupleEltTy, + getConstraintLocator(locator)); + return SolutionKind::Solved; + } } + } SWIFT_FALLTHROUGH; @@ -1621,12 +1593,16 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind, // containing a single element if the scalar type is a subtype of // the type of that tuple's element. // - // A scalar type can be converted to a tuple so long as there is at - // most one non-defaulted element. + // A scalar type can be converted to an argument tuple so long as + // there is at most one non-defaulted element. + // For non-argument tuples, we can do the same conversion but not + // to a tuple with varargs. if ((tuple2->getNumElements() == 1 && !tuple2->getElement(0).isVararg()) || (kind >= TypeMatchKind::Conversion && - tuple2->getElementForScalarInit() >= 0)) { + tuple2->getElementForScalarInit() >= 0 && + (isArgumentTupleConversion || + !tuple2->getVarArgsBaseType()))) { conversionsOrFixes.push_back( ConversionRestrictionKind::ScalarToTuple); @@ -2312,12 +2288,30 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint( llvm_unreachable("bad constraint kind"); } - if (!type->getAnyOptionalObjectType().isNull() && - protocol->isSpecificProtocol(KnownProtocolKind::BooleanType)) { - Fixes.push_back({FixKind::OptionalToBoolean, - getConstraintLocator(locator)}); - - return SolutionKind::Solved; + if (!shouldAttemptFixes()) + return SolutionKind::Error; + + // See if there's anything we can do to fix the conformance: + OptionalTypeKind optionalKind; + if (auto optionalObjectType = type->getAnyOptionalObjectType(optionalKind)) { + if (protocol->isSpecificProtocol(KnownProtocolKind::BooleanType)) { + // Optionals don't conform to BooleanType; suggest '!= nil'. + if (recordFix(FixKind::OptionalToBoolean, getConstraintLocator(locator))) + return SolutionKind::Error; + return SolutionKind::Solved; + } else if (optionalKind == OTK_Optional) { + // The underlying type of an optional may conform to the protocol if the + // optional doesn't; suggest forcing if that's the case. + auto result = simplifyConformsToConstraint( + optionalObjectType, protocol, kind, + locator.withPathElement(LocatorPathElt::getGenericArgument(0)), flags); + if (result == SolutionKind::Solved) { + if (recordFix(FixKind::ForceOptional, getConstraintLocator(locator))) { + return SolutionKind::Error; + } + } + return result; + } } // There's nothing more we can do; fail. @@ -2572,7 +2566,7 @@ static bool isUnavailableInExistential(TypeChecker &tc, ValueDecl *decl) { // Allow functions to return Self, but not have Self anywhere in // their argument types. - for (unsigned i = 1, n = afd->getNumParamPatterns(); i != n; ++i) { + for (unsigned i = 1, n = afd->getNumParameterLists(); i != n; ++i) { // Check whether the input type contains Self anywhere. auto fnType = type->castTo(); if (containsProtocolSelf(fnType->getInput())) @@ -3180,12 +3174,9 @@ ConstraintSystem::simplifyMemberConstraint(const Constraint &constraint) { // If the base type was an optional, try to look through it. if (shouldAttemptFixes() && baseObjTy->getOptionalObjectType()) { // Note the fix. - increaseScore(SK_Fix); - if (worseThanBestSolution()) + if (recordFix(FixKind::ForceOptional, constraint.getLocator())) return SolutionKind::Error; - Fixes.push_back({FixKind::ForceOptional, constraint.getLocator()}); - // Look through one level of optional. addConstraint(Constraint::create(*this, ConstraintKind::TypeMember, baseObjTy->getOptionalObjectType(), @@ -3210,19 +3201,16 @@ ConstraintSystem::simplifyMemberConstraint(const Constraint &constraint) { // FIXME: This is temporary. // Record this fix. - increaseScore(SK_Fix); - if (worseThanBestSolution()) + if (recordFix(FixKind::FromRawToInit, constraint.getLocator())) return SolutionKind::Error; - - auto locator = constraint.getLocator(); - Fixes.push_back({FixKind::FromRawToInit,getConstraintLocator(locator)}); - + // Form the type that "fromRaw" would have had and bind the // member type to it. Type fromRawType = FunctionType::get(ParenType::get(TC.Context, rawValueType), OptionalType::get(instanceTy)); - addConstraint(ConstraintKind::Bind, memberTy, fromRawType, locator); + addConstraint(ConstraintKind::Bind, memberTy, fromRawType, + constraint.getLocator()); return SolutionKind::Solved; } @@ -3233,18 +3221,15 @@ ConstraintSystem::simplifyMemberConstraint(const Constraint &constraint) { // FIXME: This is temporary. // Record this fix. - increaseScore(SK_Fix); - if (worseThanBestSolution()) + if (recordFix(FixKind::ToRawToRawValue, constraint.getLocator())) return SolutionKind::Error; - auto locator = constraint.getLocator(); - Fixes.push_back({FixKind::ToRawToRawValue,getConstraintLocator(locator)}); - // Form the type that "toRaw" would have had and bind the member // type to it. Type toRawType = FunctionType::get(TupleType::getEmpty(TC.Context), rawValueType); - addConstraint(ConstraintKind::Bind, memberTy, toRawType, locator); + addConstraint(ConstraintKind::Bind, memberTy, toRawType, + constraint.getLocator()); return SolutionKind::Solved; } @@ -3255,16 +3240,13 @@ ConstraintSystem::simplifyMemberConstraint(const Constraint &constraint) { // FIXME: This is temporary. // Record this fix. - increaseScore(SK_Fix); - if (worseThanBestSolution()) + if (recordFix(FixKind::AllZerosToInit, constraint.getLocator())) return SolutionKind::Error; - auto locator = constraint.getLocator(); - Fixes.push_back({FixKind::AllZerosToInit,getConstraintLocator(locator)}); - // Form the type that "allZeros" would have had and bind the // member type to it. - addConstraint(ConstraintKind::Bind, memberTy, rawValueType, locator); + addConstraint(ConstraintKind::Bind, memberTy, rawValueType, + constraint.getLocator()); return SolutionKind::Solved; } @@ -3272,12 +3254,9 @@ ConstraintSystem::simplifyMemberConstraint(const Constraint &constraint) { // If the base type was an optional, look through it. // Note the fix. - increaseScore(SK_Fix); - if (worseThanBestSolution()) + if (recordFix(FixKind::ForceOptional, constraint.getLocator())) return SolutionKind::Error; - Fixes.push_back({FixKind::ForceOptional, constraint.getLocator()}); - // Look through one level of optional. addValueMemberConstraint(baseObjTy->getOptionalObjectType(), constraint.getMember(), @@ -3518,32 +3497,25 @@ ConstraintSystem::simplifyApplicableFnConstraint(const Constraint &constraint) { getConstraintLocator(outerLocator)); } + if (!shouldAttemptFixes()) + return SolutionKind::Error; + // If we're coming from an optional type, unwrap the optional and try again. if (auto objectType2 = desugar2->getOptionalObjectType()) { - // Increase the score before we attempt a fix. - increaseScore(SK_Fix); - if (worseThanBestSolution()) + if (recordFix(FixKind::ForceOptional, getConstraintLocator(locator))) return SolutionKind::Error; - Fixes.push_back({FixKind::ForceOptional,getConstraintLocator(locator)}); - type2 = objectType2; desugar2 = type2->getDesugaredType(); goto retry; } // If this is a '()' call, drop the call. - if (shouldAttemptFixes() && - func1->getInput()->isEqual(TupleType::getEmpty(getASTContext()))) { - // Increase the score before we attempt a fix. - increaseScore(SK_Fix); - if (worseThanBestSolution()) - return SolutionKind::Error; - + if (func1->getInput()->isEqual(TupleType::getEmpty(getASTContext()))) { // We don't bother with a 'None' case, because at this point we won't get // a better diagnostic from that case. - Fixes.push_back({FixKind::RemoveNullaryCall, - getConstraintLocator(locator)}); + if (recordFix(FixKind::RemoveNullaryCall, getConstraintLocator(locator))) + return SolutionKind::Error; return matchTypes(func1->getResult(), type2, TypeMatchKind::BindType, @@ -3767,7 +3739,7 @@ ConstraintSystem::simplifyRestrictedConstraint(ConversionRestrictionKind restric // We don't want to allow this after user-defined conversions: // - it gets really complex for users to understand why there's // a dereference in their code - // - it would allow nil to be coerceable to a non-optional type + // - it would allow nil to be coercible to a non-optional type // Fortunately, user-defined conversions only allow subtype // conversions on their results. case ConversionRestrictionKind::ForceUnchecked: { @@ -4273,13 +4245,13 @@ bool ConstraintSystem::recordFix(Fix fix, ConstraintLocatorBuilder locator) { // Record the fix. if (fix.getKind() != FixKind::None) { - Fixes.push_back({fix, getConstraintLocator(locator)}); - // Increase the score. If this would make the current solution worse than // the best solution we've seen already, stop now. increaseScore(SK_Fix); if (worseThanBestSolution()) return true; + + Fixes.push_back({fix, getConstraintLocator(locator)}); } return false; } diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp index 1e2ad76bb82ed..bb25c97056dbf 100644 --- a/lib/Sema/CSSolver.cpp +++ b/lib/Sema/CSSolver.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,9 +23,9 @@ using namespace swift; using namespace constraints; -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Constraint solver statistics -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #define DEBUG_TYPE "Constraint solver overall" #define JOIN(X,Y) JOIN2(X,Y) #define JOIN2(X,Y) X##Y @@ -70,7 +70,7 @@ static Optional checkTypeOfBinding(ConstraintSystem &cs, return type; } -/// Reconsistitute type sugar, e.g., for array types, dictionary +/// Reconstitute type sugar, e.g., for array types, dictionary /// types, optionals, etc. static Type reconstituteSugar(Type type) { if (auto boundGeneric = dyn_cast(type.getPointer())) { @@ -191,7 +191,7 @@ Solution ConstraintSystem::finalize( solution.OpenedExistentialTypes.insert(openedExistential); } - return std::move(solution); + return solution; } void ConstraintSystem::applySolution(const Solution &solution) { @@ -336,6 +336,8 @@ bool ConstraintSystem::simplify(bool ContinueAfterFailures) { if (solverState) solverState->retiredConstraints.push_front(constraint); + else + CG.removeConstraint(constraint); break; @@ -1094,7 +1096,7 @@ static bool tryTypeVariableBindings( for (auto binding : bindings) { auto type = binding.BindingType; - // After our first pass, note that that we've explored these + // After our first pass, note that we've explored these // types. if (tryCount == 0) exploredTypes.insert(type->getCanonicalType()); @@ -1370,7 +1372,7 @@ bool ConstraintSystem::solveRec(SmallVectorImpl &solutions, // ready for the next component. TypeVariables = std::move(allTypeVariables); - // For each of the partial solutions, substract off the current score. + // For each of the partial solutions, subtract off the current score. // It doesn't contribute. for (auto &solution : partialSolutions[component]) solution.getFixedScore() -= CurrentScore; diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp index cb8b6f7762038..83dd3b5ae5640 100644 --- a/lib/Sema/CodeSynthesis.cpp +++ b/lib/Sema/CodeSynthesis.cpp @@ -1,8 +1,8 @@ -//===--- TypeCheckDecl.cpp - Type Checking for Declarations ---------------===// +//===--- CodeSynthesis.cpp - Type Checking for Declarations ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,6 +22,7 @@ #include "swift/AST/Attr.h" #include "swift/AST/Availability.h" #include "swift/AST/Expr.h" +#include "swift/AST/ParameterList.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" using namespace swift; @@ -41,69 +42,34 @@ static void addMemberToContextIfNeeded(Decl *D, DeclContext *DC, "Unknown declcontext"); } -static VarDecl *getParamDeclAtIndex(FuncDecl *fn, unsigned index) { - TuplePatternElt singleParam; - Pattern *paramPattern = fn->getBodyParamPatterns().back(); - ArrayRef params; - if (auto paramTuple = dyn_cast(paramPattern)) { - params = paramTuple->getElements(); - } else { - singleParam = TuplePatternElt( - cast(paramPattern)->getSubPattern()); - params = singleParam; - } - - auto firstParamPattern = params[index].getPattern(); - return firstParamPattern->getSingleVar(); +static ParamDecl *getParamDeclAtIndex(FuncDecl *fn, unsigned index) { + return fn->getParameterLists().back()->get(index); } static VarDecl *getFirstParamDecl(FuncDecl *fn) { return getParamDeclAtIndex(fn, 0); }; -/// \brief Build an implicit 'self' parameter for the specified DeclContext. -static Pattern *buildImplicitSelfParameter(SourceLoc Loc, DeclContext *DC) { - ASTContext &Ctx = DC->getASTContext(); - auto *SelfDecl = new (Ctx) ParamDecl(/*IsLet*/ true, Loc, Identifier(), - Loc, Ctx.Id_self, Type(), DC); - SelfDecl->setImplicit(); - Pattern *P = new (Ctx) NamedPattern(SelfDecl, /*Implicit=*/true); - return new (Ctx) TypedPattern(P, TypeLoc()); -} -static TuplePatternElt buildArgumentPattern(SourceLoc loc, DeclContext *DC, - StringRef name, Type type, - bool isLet, - VarDecl **paramDecl, - ASTContext &Context) { - auto *param = new (Context) ParamDecl(isLet, SourceLoc(), Identifier(), - loc, Context.getIdentifier(name), +static ParamDecl *buildArgument(SourceLoc loc, DeclContext *DC, + StringRef name, Type type, bool isLet) { + auto &context = DC->getASTContext(); + auto *param = new (context) ParamDecl(isLet, SourceLoc(), Identifier(), + loc, context.getIdentifier(name), Type(), DC); - if (paramDecl) *paramDecl = param; param->setImplicit(); - - Pattern *valuePattern - = new (Context) TypedPattern(new (Context) NamedPattern(param, true), - TypeLoc::withoutLoc(type)); - valuePattern->setImplicit(); - - return TuplePatternElt(valuePattern); + param->getTypeLoc().setType(type); + return param; } -static TuplePatternElt buildLetArgumentPattern(SourceLoc loc, DeclContext *DC, - StringRef name, Type type, - VarDecl **paramDecl, - ASTContext &ctx) { - return buildArgumentPattern(loc, DC, name, type, - /*isLet*/ true, paramDecl, ctx); +static ParamDecl *buildLetArgument(SourceLoc loc, DeclContext *DC, + StringRef name, Type type) { + return buildArgument(loc, DC, name, type, /*isLet*/ true); } -static TuplePatternElt buildInOutArgumentPattern(SourceLoc loc, DeclContext *DC, - StringRef name, Type type, - VarDecl **paramDecl, - ASTContext &ctx) { - return buildArgumentPattern(loc, DC, name, InOutType::get(type), - /*isLet*/ false, paramDecl, ctx); +static ParamDecl *buildInOutArgument(SourceLoc loc, DeclContext *DC, + StringRef name, Type type) { + return buildArgument(loc, DC, name, InOutType::get(type), /*isLet*/ false); } static Type getTypeOfStorage(AbstractStorageDecl *storage, @@ -118,62 +84,35 @@ static Type getTypeOfStorage(AbstractStorageDecl *storage, } } -static TuplePatternElt -buildSetterValueArgumentPattern(AbstractStorageDecl *storage, - VarDecl **valueDecl, TypeChecker &TC) { - auto storageType = getTypeOfStorage(storage, TC); - return buildLetArgumentPattern(storage->getLoc(), - storage->getDeclContext(), - "value", storageType, valueDecl, TC.Context); -} - -/// Build a pattern which can forward the formal index parameters of a +/// Build a parameter list which can forward the formal index parameters of a /// declaration. /// /// \param prefix optional arguments to be prefixed onto the index -/// forwarding pattern -static Pattern *buildIndexForwardingPattern(AbstractStorageDecl *storage, - MutableArrayRef prefix, - TypeChecker &TC) { +/// forwarding pattern. +static ParameterList * +buildIndexForwardingParamList(AbstractStorageDecl *storage, + ArrayRef prefix) { + auto &context = storage->getASTContext(); auto subscript = dyn_cast(storage); - // Fast path: if this isn't a subscript, and we have a first - // pattern, we can just use that. - if (!subscript) { - auto tuple = TuplePattern::createSimple(TC.Context, SourceLoc(), prefix, - SourceLoc()); - tuple->setImplicit(); - return tuple; - } + // Fast path: if this isn't a subscript, just use whatever we have. + if (!subscript) + return ParameterList::create(context, prefix); - // Otherwise, we need to build up a new TuplePattern. - SmallVector elements; + // Clone the parameter list over for a new decl, so we get new ParamDecls. + auto indices = subscript->getIndices()->clone(context, + ParameterList::Implicit); + if (prefix.empty()) + return indices; + + + // Otherwise, we need to build up a new parameter list. + SmallVector elements; - // Start with the fields from the first pattern, if there are any. + // Start with the fields we were given, if there are any. elements.append(prefix.begin(), prefix.end()); - - // Clone index patterns in a manner that allows them to be - // perfectly forwarded. - DeclContext *DC = storage->getDeclContext(); - auto addVarPatternFor = [&](Pattern *P, Identifier label = Identifier()) { - Pattern *vp = P->cloneForwardable(TC.Context, DC, Pattern::Implicit); - elements.push_back(TuplePatternElt(vp)); - elements.back().setLabel(label, SourceLoc()); - }; - - // This is the same breakdown the parser does. - auto indices = subscript->getIndices(); - if (auto pp = dyn_cast(indices)) { - addVarPatternFor(pp); - } else { - auto tp = cast(indices); - for (auto &element : tp->getElements()) { - addVarPatternFor(element.getPattern(), element.getLabel()); - } - } - - return TuplePattern::createSimple(TC.Context, SourceLoc(), elements, - SourceLoc()); + elements.append(indices->begin(), indices->end()); + return ParameterList::create(context, elements); } static FuncDecl *createGetterPrototype(AbstractStorageDecl *storage, @@ -181,15 +120,16 @@ static FuncDecl *createGetterPrototype(AbstractStorageDecl *storage, SourceLoc loc = storage->getLoc(); // Create the parameter list for the getter. - SmallVector getterParams; + SmallVector getterParams; // The implicit 'self' argument if in a type context. if (storage->getDeclContext()->isTypeContext()) - getterParams.push_back( - buildImplicitSelfParameter(loc, storage->getDeclContext())); + getterParams.push_back(ParameterList::createSelf(loc, + storage->getDeclContext(), + /*isStatic*/false)); // Add an index-forwarding clause. - getterParams.push_back(buildIndexForwardingPattern(storage, {}, TC)); + getterParams.push_back(buildIndexForwardingParamList(storage, {})); SourceLoc staticLoc; if (auto var = dyn_cast(storage)) { @@ -219,23 +159,26 @@ static FuncDecl *createGetterPrototype(AbstractStorageDecl *storage, } static FuncDecl *createSetterPrototype(AbstractStorageDecl *storage, - VarDecl *&valueDecl, + ParamDecl *&valueDecl, TypeChecker &TC) { SourceLoc loc = storage->getLoc(); // Create the parameter list for the setter. - SmallVector params; + SmallVector params; // The implicit 'self' argument if in a type context. if (storage->getDeclContext()->isTypeContext()) { - params.push_back( - buildImplicitSelfParameter(loc, storage->getDeclContext())); + params.push_back(ParameterList::createSelf(loc, + storage->getDeclContext(), + /*isStatic*/false)); } - - // Add a "(value : T, indices...)" pattern. - TuplePatternElt valuePattern = - buildSetterValueArgumentPattern(storage, &valueDecl, TC); - params.push_back(buildIndexForwardingPattern(storage, valuePattern, TC)); + + // Add a "(value : T, indices...)" argument list. + auto storageType = getTypeOfStorage(storage, TC); + valueDecl = buildLetArgument(storage->getLoc(), + storage->getDeclContext(), "value", + storageType); + params.push_back(buildIndexForwardingParamList(storage, valueDecl)); Type setterRetTy = TupleType::getEmpty(TC.Context); FuncDecl *setter = FuncDecl::create( @@ -346,30 +289,26 @@ static Type createMaterializeForSetReturnType(AbstractStorageDecl *storage, } static FuncDecl *createMaterializeForSetPrototype(AbstractStorageDecl *storage, - VarDecl *&bufferParamDecl, TypeChecker &TC) { auto &ctx = storage->getASTContext(); SourceLoc loc = storage->getLoc(); // Create the parameter list: - SmallVector params; + SmallVector params; // - The implicit 'self' argument if in a type context. auto DC = storage->getDeclContext(); if (DC->isTypeContext()) - params.push_back(buildImplicitSelfParameter(loc, DC)); + params.push_back(ParameterList::createSelf(loc, DC, /*isStatic*/false)); // - The buffer parameter, (buffer: Builtin.RawPointer, // inout storage: Builtin.UnsafeValueBuffer, // indices...). - TuplePatternElt bufferElements[] = { - buildLetArgumentPattern(loc, DC, "buffer", ctx.TheRawPointerType, - &bufferParamDecl, TC.Context), - buildInOutArgumentPattern(loc, DC, "callbackStorage", - ctx.TheUnsafeValueBufferType, - nullptr, TC.Context), + ParamDecl *bufferElements[] = { + buildLetArgument(loc, DC, "buffer", ctx.TheRawPointerType), + buildInOutArgument(loc, DC, "callbackStorage", ctx.TheUnsafeValueBufferType) }; - params.push_back(buildIndexForwardingPattern(storage, bufferElements, TC)); + params.push_back(buildIndexForwardingParamList(storage, bufferElements)); // The accessor returns (Builtin.RawPointer, (@convention(thin) (...) -> ())?), // where the first pointer is the materialized address and the @@ -447,46 +386,51 @@ static Expr *buildTupleExpr(ASTContext &ctx, ArrayRef args) { } -static Expr *buildTupleForwardingRefExpr(ASTContext &ctx, - ArrayRef params, - ArrayRef formalIndexTypes) { - assert(params.size() == formalIndexTypes.size()); - +/// Build an expression that evaluates the specified parameter list as a tuple +/// or paren expr, suitable for use in an applyexpr. +/// +/// NOTE: This returns null if a varargs parameter exists in the list, as it +/// cannot be forwarded correctly yet. +/// +static Expr *buildArgumentForwardingExpr(ArrayRef params, + ASTContext &ctx) { SmallVector labels; SmallVector labelLocs; SmallVector args; - - for (unsigned i = 0, e = params.size(); i != e; ++i) { - const Pattern *param = params[i].getPattern(); - args.push_back(param->buildForwardingRefExpr(ctx)); - labels.push_back(formalIndexTypes[i].getName()); + + for (auto param : params) { + // We cannot express how to forward variadic parameters yet. + if (param->isVariadic()) + return nullptr; + + Expr *ref = new (ctx) DeclRefExpr(param, SourceLoc(), /*implicit*/ true); + if (param->getType()->is()) + ref = new (ctx) InOutExpr(SourceLoc(), ref, Type(), /*implicit=*/true); + args.push_back(ref); + + labels.push_back(param->getArgumentName()); labelLocs.push_back(SourceLoc()); } - + // A single unlabelled value is not a tuple. if (args.size() == 1 && labels[0].empty()) return args[0]; - + return TupleExpr::create(ctx, SourceLoc(), args, labels, labelLocs, SourceLoc(), false, IsImplicit); } -/// Build a reference to the subscript index variables for this -/// subscript accessor. + + + + +/// Build a reference to the subscript index variables for this subscript +/// accessor. static Expr *buildSubscriptIndexReference(ASTContext &ctx, FuncDecl *accessor) { // Pull out the body parameters, which we should have cloned // previously to be forwardable. Drop the initial buffer/value // parameter in accessors that have one. - TuplePatternElt singleParam; - Pattern *paramPattern = accessor->getBodyParamPatterns().back(); - ArrayRef params; - if (auto paramTuple = dyn_cast(paramPattern)) { - params = paramTuple->getElements(); - } else { - singleParam = TuplePatternElt( - cast(paramPattern)->getSubPattern()); - params = singleParam; - } + auto params = accessor->getParameterLists().back()->getArray(); auto accessorKind = accessor->getAccessorKind(); // Ignore the value/buffer parameter. @@ -496,15 +440,11 @@ static Expr *buildSubscriptIndexReference(ASTContext &ctx, FuncDecl *accessor) { // Ignore the materializeForSet callback storage parameter. if (accessorKind == AccessorKind::IsMaterializeForSet) params = params.slice(1); - - // Look for formal subscript labels. - auto subscript = cast(accessor->getAccessorStorageDecl()); - auto indexType = subscript->getIndicesType(); - if (auto indexTuple = indexType->getAs()) { - return buildTupleForwardingRefExpr(ctx, params, indexTuple->getElements()); - } else { - return buildTupleForwardingRefExpr(ctx, params, TupleTypeElt(indexType)); - } + + // Okay, everything else should be forwarded, build the expression. + auto result = buildArgumentForwardingExpr(params, ctx); + assert(result && "FIXME: Cannot forward varargs"); + return result; } enum class SelfAccessKind { @@ -764,7 +704,7 @@ static void maybeMarkTransparent(FuncDecl *accessor, } /// Synthesize the body of a trivial getter. For a non-member vardecl or one -/// which is not an override of a base class property, it performs a a direct +/// which is not an override of a base class property, it performs a direct /// storage load. For an override of a base member property, it chains up to /// super. static void synthesizeTrivialGetter(FuncDecl *getter, @@ -894,9 +834,7 @@ static bool doesStorageNeedSetter(AbstractStorageDecl *storage) { /// Add a materializeForSet accessor to the given declaration. static FuncDecl *addMaterializeForSet(AbstractStorageDecl *storage, TypeChecker &TC) { - VarDecl *bufferDecl; - auto materializeForSet = - createMaterializeForSetPrototype(storage, bufferDecl, TC); + auto materializeForSet = createMaterializeForSetPrototype(storage, TC); addMemberToContextIfNeeded(materializeForSet, storage->getDeclContext(), storage->getSetter()); storage->setMaterializeForSetFunc(materializeForSet); @@ -918,7 +856,7 @@ void swift::addTrivialAccessorsToStorage(AbstractStorageDecl *storage, // Create the setter. FuncDecl *setter = nullptr; - VarDecl *setterValueParam = nullptr; + ParamDecl *setterValueParam = nullptr; if (doesStorageNeedSetter(storage)) { setter = createSetterPrototype(storage, setterValueParam, TC); } @@ -1035,31 +973,29 @@ static Expr *buildMaterializeForSetCallback(ASTContext &ctx, // Unexpected subtlety: it actually important to call the inout self // parameter something other than 'self' so that we don't trigger // the "implicit use of self" diagnostic. - VarDecl *bufferDecl; - VarDecl *callbackStorageDecl; - VarDecl *selfDecl; - TuplePatternElt argPatterns[] = { - buildLetArgumentPattern(loc, DC, "buffer", ctx.TheRawPointerType, - &bufferDecl, ctx), - buildInOutArgumentPattern(loc, DC, "callbackStorage", - ctx.TheUnsafeValueBufferType, - &callbackStorageDecl, ctx), - buildInOutArgumentPattern(loc, DC, "selfValue", selfType, &selfDecl, ctx), - buildLetArgumentPattern(loc, DC, "selfType", MetatypeType::get(selfType), - nullptr, ctx), - }; - auto args = TuplePattern::createSimple(ctx, SourceLoc(), argPatterns, - SourceLoc()); - args->setImplicit(); + auto bufferParam = + buildLetArgument(loc, DC, "buffer", ctx.TheRawPointerType); + auto callbackStorageParam = + buildInOutArgument(loc, DC, "callbackStorage",ctx.TheUnsafeValueBufferType); + auto selfValueParam = buildInOutArgument(loc, DC, "selfValue", selfType); + auto selfTypeParam = buildLetArgument(loc, DC, "selfType", + MetatypeType::get(selfType)); + + auto paramList = ParameterList::create(ctx, { + bufferParam, + callbackStorageParam, + selfValueParam, + selfTypeParam + }); // Create the closure expression itself. - auto closure = new (ctx) ClosureExpr(args, SourceLoc(), SourceLoc(), + auto closure = new (ctx) ClosureExpr(paramList, SourceLoc(), SourceLoc(), SourceLoc(), TypeLoc(), /*discriminator*/ 0, materializeForSet); // Generate the body of the closure. SmallVector body; - generator(body, selfDecl, bufferDecl, callbackStorageDecl); + generator(body, selfValueParam, bufferParam, callbackStorageParam); closure->setBody(BraceStmt::create(ctx, SourceLoc(), body, SourceLoc(), IsImplicit), /*isSingleExpression*/ false); @@ -1348,7 +1284,7 @@ static void synthesizeAddressedMaterializeForSet(FuncDecl *materializeForSet, }(); // Initialize the callback storage with the owner value, which is - // the second elemenet of the addressor result. + // the second element of the addressor result. Expr *owner = new (ctx) DeclRefExpr(tempDecl, SourceLoc(), IsImplicit); owner = new (ctx) TupleElementExpr(owner, SourceLoc(), /*field index*/ 1, SourceLoc(), Type()); @@ -1476,11 +1412,7 @@ void swift::synthesizeObservingAccessors(VarDecl *VD, TypeChecker &TC) { // decls for 'self' and 'value'. auto *Set = VD->getSetter(); auto *SelfDecl = Set->getImplicitSelfDecl(); - VarDecl *ValueDecl = nullptr; - Set->getBodyParamPatterns().back()->forEachVariable([&](VarDecl *VD) { - assert(!ValueDecl && "Already found 'value'?"); - ValueDecl = VD; - }); + VarDecl *ValueDecl = Set->getParameterLists().back()->get(0); // The setter loads the oldValue, invokes willSet with the incoming value, // does a direct store, then invokes didSet with the oldValue. @@ -1572,7 +1504,7 @@ static void convertNSManagedStoredVarToComputed(VarDecl *VD, TypeChecker &TC) { auto *Get = createGetterPrototype(VD, TC); // Create the setter. - VarDecl *SetValueDecl = nullptr; + ParamDecl *SetValueDecl = nullptr; auto *Set = createSetterPrototype(VD, SetValueDecl, TC); // Okay, we have both the getter and setter. Set them in VD. @@ -1619,7 +1551,7 @@ namespace { }; } -/// Synthesize the getter for an lazy property with the specified storage +/// Synthesize the getter for a lazy property with the specified storage /// vardecl. static FuncDecl *completeLazyPropertyGetter(VarDecl *VD, VarDecl *Storage, TypeChecker &TC) { @@ -1852,7 +1784,7 @@ void swift::maybeAddAccessorsToVariable(VarDecl *var, TypeChecker &TC) { getter->setMutating(); getter->setAccessibility(var->getFormalAccess()); - VarDecl *newValueParam = nullptr; + ParamDecl *newValueParam = nullptr; auto *setter = createSetterPrototype(var, newValueParam, TC); var->makeComputed(var->getLoc(), getter, setter, nullptr, var->getLoc()); @@ -1918,8 +1850,7 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc, accessLevel = std::min(accessLevel, Accessibility::Internal); // Determine the parameter type of the implicit constructor. - SmallVector patternElts; - SmallVector argNames; + SmallVector params; if (ICK == ImplicitConstructorKind::Memberwise) { assert(isa(decl) && "Only struct have memberwise constructor"); @@ -1929,7 +1860,6 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc, continue; tc.validateDecl(var); - // Initialized 'let' properties have storage, but don't get an argument // to the memberwise initializer since they already have an initial // value that cannot be overridden. @@ -1952,24 +1882,18 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc, auto *arg = new (context) ParamDecl(/*IsLet*/true, Loc, var->getName(), Loc, var->getName(), varType, decl); arg->setImplicit(); - argNames.push_back(var->getName()); - Pattern *pattern = new (context) NamedPattern(arg); - pattern->setImplicit(); - TypeLoc tyLoc = TypeLoc::withoutLoc(varType); - pattern = new (context) TypedPattern(pattern, tyLoc); - patternElts.push_back(TuplePatternElt(var->getName(), SourceLoc(), - pattern, false)); + params.push_back(arg); } } - auto pattern = TuplePattern::create(context, Loc, patternElts, Loc); - pattern->setImplicit(); - + auto paramList = ParameterList::create(context, params); + // Create the constructor. - DeclName name(context, context.Id_init, argNames); - Pattern *selfPat = buildImplicitSelfParameter(Loc, decl); + DeclName name(context, context.Id_init, paramList); + auto *selfParam = ParamDecl::createSelf(Loc, decl, + /*static*/false, /*inout*/true); auto *ctor = new (context) ConstructorDecl(name, Loc, OTK_None, SourceLoc(), - selfPat, pattern, + selfParam, paramList, nullptr, SourceLoc(), decl); // Mark implicit. @@ -1999,105 +1923,6 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc, return ctor; } -/// Create an expression that references the variables in the given -/// pattern for, e.g., forwarding of these variables to another -/// function with the same signature. -static Expr *forwardArguments(TypeChecker &tc, ClassDecl *classDecl, - ConstructorDecl *toDecl, - Pattern *bodyPattern, - ArrayRef argumentNames) { - switch (bodyPattern->getKind()) { -#define PATTERN(Id, Parent) -#define REFUTABLE_PATTERN(Id, Parent) case PatternKind::Id: -#include "swift/AST/PatternNodes.def" - return nullptr; - - case PatternKind::Paren: { - auto subExpr = forwardArguments(tc, classDecl, toDecl, - cast(bodyPattern)->getSubPattern(), - { }); - if (!subExpr) return nullptr; - - // If there is a name for this single-argument thing, then form a tupleexpr. - if (argumentNames.size() != 1 || argumentNames[0].empty()) - return new (tc.Context) ParenExpr(SourceLoc(), subExpr, SourceLoc(), - /*hasTrailingClosure=*/false); - - return TupleExpr::createImplicit(tc.Context, subExpr, argumentNames); - } - - - case PatternKind::Tuple: { - auto bodyTuple = cast(bodyPattern); - SmallVector values; - - // FIXME: Can't forward varargs yet. - if (bodyTuple->hasAnyEllipsis()) { - tc.diagnose(classDecl->getLoc(), - diag::unsupported_synthesize_init_variadic, - classDecl->getDeclaredType()); - tc.diagnose(toDecl, diag::variadic_superclass_init_here); - return nullptr; - } - - for (unsigned i = 0, n = bodyTuple->getNumElements(); i != n; ++i) { - // Forward the value. - auto subExpr = forwardArguments(tc, classDecl, toDecl, - bodyTuple->getElement(i).getPattern(), - { }); - if (!subExpr) - return nullptr; - values.push_back(subExpr); - - // Dig out the name. - auto subPattern = bodyTuple->getElement(i).getPattern(); - do { - if (auto typed = dyn_cast(subPattern)) { - subPattern = typed->getSubPattern(); - continue; - } - - if (auto paren = dyn_cast(subPattern)) { - subPattern = paren->getSubPattern(); - continue; - } - - break; - } while (true); - } - - if (values.size() == 1 && - (argumentNames.empty() || argumentNames[0].empty())) - return new (tc.Context) ParenExpr(SourceLoc(), values[0], SourceLoc(), - /*hasTrailingClosure=*/false); - - return TupleExpr::createImplicit(tc.Context, values, argumentNames); - } - - case PatternKind::Any: - case PatternKind::Named: { - auto decl = cast(bodyPattern)->getDecl(); - Expr *declRef = new (tc.Context) DeclRefExpr(decl, SourceLoc(), - /*Implicit=*/true); - if (decl->getType()->is()) - declRef = new (tc.Context) InOutExpr(SourceLoc(), declRef, - Type(), /*isImplicit=*/true); - return declRef; - } - - case PatternKind::Typed: - return forwardArguments(tc, classDecl, toDecl, - cast(bodyPattern)->getSubPattern(), - argumentNames); - - case PatternKind::Var: - return forwardArguments(tc, classDecl, toDecl, - cast(bodyPattern)->getSubPattern(), - argumentNames); - - } -} - /// Create a stub body that emits a fatal error message. static void createStubBody(TypeChecker &tc, ConstructorDecl *ctor) { auto unimplementedInitDecl = tc.Context.getUnimplementedInitializerDecl(&tc); @@ -2146,87 +1971,18 @@ swift::createDesignatedInitOverride(TypeChecker &tc, auto &ctx = tc.Context; // Create the 'self' declaration and patterns. - auto *selfDecl = new (ctx) ParamDecl(/*IsLet*/ true, - SourceLoc(), Identifier(), - SourceLoc(), ctx.Id_self, - Type(), classDecl); - selfDecl->setImplicit(); - Pattern *selfBodyPattern - = new (ctx) NamedPattern(selfDecl, /*Implicit=*/true); - selfBodyPattern = new (ctx) TypedPattern(selfBodyPattern, TypeLoc()); + auto *selfDecl = ParamDecl::createSelf(SourceLoc(), classDecl); // Create the initializer parameter patterns. - OptionSet options = Pattern::Implicit; - options |= Pattern::Inherited; - Pattern *bodyParamPatterns - = superclassCtor->getBodyParamPatterns()[1]->clone(ctx, options); - - // Fix up the default arguments in the type to refer to inherited default - // arguments. - // FIXME: If we weren't cloning the type along with the pattern, this would be - // a lot more direct. - Type argType = bodyParamPatterns->getType(); - - // Local function that maps default arguments to inherited default arguments. - std::function inheritDefaultArgs = [&](Type type) -> Type { - auto tuple = type->getAs(); - if (!tuple) - return type; - - bool anyChanged = false; - SmallVector elements; - unsigned index = 0; - for (const auto &elt : tuple->getElements()) { - Type eltTy = elt.getType().transform(inheritDefaultArgs); - if (!eltTy) - return Type(); - - // If nothing has changed, just keep going. - if (!anyChanged && eltTy.getPointer() == elt.getType().getPointer() && - (elt.getDefaultArgKind() == DefaultArgumentKind::None || - elt.getDefaultArgKind() == DefaultArgumentKind::Inherited)) { - ++index; - continue; - } - - // If this is the first change we've seen, copy all of the previous - // elements. - if (!anyChanged) { - // Copy all of the previous elements. - for (unsigned i = 0; i != index; ++i) { - const TupleTypeElt &FromElt = tuple->getElement(i); - elements.push_back(TupleTypeElt(FromElt.getType(), FromElt.getName(), - FromElt.getDefaultArgKind(), - FromElt.isVararg())); - } - - anyChanged = true; - } - - // Add the new tuple element, with the new type, no initializer, - auto defaultArgKind = elt.getDefaultArgKind(); - if (defaultArgKind != DefaultArgumentKind::None) - defaultArgKind = DefaultArgumentKind::Inherited; - elements.push_back(TupleTypeElt(eltTy, elt.getName(), defaultArgKind, - elt.isVararg())); - ++index; - } - - if (!anyChanged) - return type; - - return TupleType::get(elements, ctx); - }; - - argType = argType.transform(inheritDefaultArgs); - bodyParamPatterns->setType(argType); - + OptionSet options = ParameterList::Implicit; + options |= ParameterList::Inherited; + auto *bodyParams = superclassCtor->getParameterList(1)->clone(ctx,options); + // Create the initializer declaration. auto ctor = new (ctx) ConstructorDecl(superclassCtor->getFullName(), classDecl->getBraces().Start, superclassCtor->getFailability(), - SourceLoc(), - selfBodyPattern, bodyParamPatterns, + SourceLoc(), selfDecl, bodyParams, nullptr, SourceLoc(), classDecl); ctor->setImplicit(); ctor->setAccessibility(std::min(classDecl->getFormalAccess(), @@ -2238,14 +1994,10 @@ swift::createDesignatedInitOverride(TypeChecker &tc, ctx); // Configure 'self'. - GenericParamList *outerGenericParams = nullptr; - Type selfType = configureImplicitSelf(tc, ctor, outerGenericParams); - selfBodyPattern->setType(selfType); - cast(selfBodyPattern)->getSubPattern()->setType(selfType); + auto selfType = configureImplicitSelf(tc, ctor); // Set the type of the initializer. - configureConstructorType(ctor, outerGenericParams, selfType, - bodyParamPatterns->getType(), + configureConstructorType(ctor, selfType, bodyParams->getType(ctx), superclassCtor->isBodyThrowing()); if (superclassCtor->isObjC()) { auto errorConvention = superclassCtor->getForeignErrorConvention(); @@ -2286,14 +2038,16 @@ swift::createDesignatedInitOverride(TypeChecker &tc, SourceLoc(), /*Implicit=*/true); - Expr *ctorArgs = forwardArguments(tc, classDecl, superclassCtor, - ctor->getBodyParamPatterns()[1], - ctor->getFullName().getArgumentNames()); + auto ctorArgs = buildArgumentForwardingExpr(bodyParams->getArray(), ctx); + + // If buildArgumentForwardingExpr failed, then it was because we tried to + // forward varargs, which cannot be done yet. + // TODO: We should be able to forward varargs! if (!ctorArgs) { - // FIXME: We should be able to assert that this never happens, - // but there are currently holes when dealing with vararg - // initializers and _ parameters. Fail somewhat gracefully by - // generating a stub here. + tc.diagnose(classDecl->getLoc(), + diag::unsupported_synthesize_init_variadic, + classDecl->getDeclaredType()); + tc.diagnose(superclassCtor, diag::variadic_superclass_init_here); createStubBody(tc, ctor); return ctor; } @@ -2315,10 +2069,10 @@ void TypeChecker::addImplicitDestructor(ClassDecl *CD) { if (CD->hasDestructor() || CD->isInvalid()) return; - Pattern *selfPat = buildImplicitSelfParameter(CD->getLoc(), CD); + auto *selfDecl = ParamDecl::createSelf(CD->getLoc(), CD); auto *DD = new (Context) DestructorDecl(Context.Id_deinit, CD->getLoc(), - selfPat, CD); + selfDecl, CD); DD->setImplicit(); diff --git a/lib/Sema/CodeSynthesis.h b/lib/Sema/CodeSynthesis.h index b2b54480e7b93..878fa2f6c73b9 100644 --- a/lib/Sema/CodeSynthesis.h +++ b/lib/Sema/CodeSynthesis.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -47,10 +47,8 @@ void markAsObjC(TypeChecker &TC, ValueDecl *D, Optional isObjC, Optional errorConvention = None); Type configureImplicitSelf(TypeChecker &tc, - AbstractFunctionDecl *func, - GenericParamList *&outerGenericParams); + AbstractFunctionDecl *func); void configureConstructorType(ConstructorDecl *ctor, - GenericParamList *outerGenericParams, Type selfType, Type argType, bool throws); diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp index f7f9e9c48e57d..9db0abce51909 100644 --- a/lib/Sema/Constraint.cpp +++ b/lib/Sema/Constraint.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/Constraint.h b/lib/Sema/Constraint.h index ebbec8f9de2fc..b82cc5e9852d7 100644 --- a/lib/Sema/Constraint.h +++ b/lib/Sema/Constraint.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -138,7 +138,7 @@ enum class ConstraintClassification : char { /// it a reference type. Member, - /// \brief An property of a single type, such as whether it is an archetype. + /// \brief A property of a single type, such as whether it is an archetype. TypeProperty, /// \brief A disjunction constraint. diff --git a/lib/Sema/ConstraintGraph.cpp b/lib/Sema/ConstraintGraph.cpp index e92cd1fe4be61..dea2706197f2d 100644 --- a/lib/Sema/ConstraintGraph.cpp +++ b/lib/Sema/ConstraintGraph.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/ConstraintGraph.h b/lib/Sema/ConstraintGraph.h index 3385275f30bd1..1b38c6f4958f9 100644 --- a/lib/Sema/ConstraintGraph.h +++ b/lib/Sema/ConstraintGraph.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/ConstraintGraphScope.h b/lib/Sema/ConstraintGraphScope.h index d6410dd78a914..213ca89439613 100644 --- a/lib/Sema/ConstraintGraphScope.h +++ b/lib/Sema/ConstraintGraphScope.h @@ -1,8 +1,8 @@ -//===--- ConstraintGraphScope.h - Constraint Graph Scope---------*- C++ -*-===// +//===--- ConstraintGraphScope.h - Constraint Graph Scope --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -53,6 +53,6 @@ class ConstraintGraphScope { }; } // end namespace swift::constraints -} // end namespacae swift +} // end namespace swift #endif // LLVM_SWIFT_SEMA_CONSTRAINT_GRAPH_SCOPE_H diff --git a/lib/Sema/ConstraintLocator.cpp b/lib/Sema/ConstraintLocator.cpp index ab653deced826..6b94519ba2141 100644 --- a/lib/Sema/ConstraintLocator.cpp +++ b/lib/Sema/ConstraintLocator.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/ConstraintLocator.h b/lib/Sema/ConstraintLocator.h index 50023142901fe..9bc1cc70c1510 100644 --- a/lib/Sema/ConstraintLocator.h +++ b/lib/Sema/ConstraintLocator.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -51,7 +51,7 @@ namespace constraints { /// to indicate constraints on its argument or result type. class ConstraintLocator : public llvm::FoldingSetNode { public: - /// \brief Describes the kind of a a particular path element, e.g., + /// \brief Describes the kind of a particular path element, e.g., /// "tuple element", "call result", "base of member lookup", etc. enum PathElementKind : unsigned char { /// \brief The argument of function application. @@ -116,7 +116,7 @@ class ConstraintLocator : public llvm::FoldingSetNode { Load, /// The candidate witness during protocol conformance checking. Witness, - /// This is refering to a type produced by opening a generic type at the + /// This is referring to a type produced by opening a generic type at the /// base of the locator. OpenedGeneric, }; diff --git a/lib/Sema/ConstraintSolverStats.def b/lib/Sema/ConstraintSolverStats.def index cddacbddd54f1..d18433bc71a54 100644 --- a/lib/Sema/ConstraintSolverStats.def +++ b/lib/Sema/ConstraintSolverStats.def @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index f5abecc655335..948d0a953b178 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -159,50 +159,24 @@ void ConstraintSystem::addTypeVariableConstraintsToWorkList( } } -/// Retrieve a uniqued selector ID for the given declaration. -static std::pair -getDynamicResultSignature(ValueDecl *decl, - llvm::StringMap &selectors) { - llvm::SmallString<32> buffer; - - StringRef selector; - Type type; - if (auto func = dyn_cast(decl)) { +/// Retrieve a dynamic result signature for the given declaration. +static std::tuple +getDynamicResultSignature(ValueDecl *decl) { + if (auto func = dyn_cast(decl)) { // Handle functions. - // FIXME: Use ObjCSelector here! - selector = func->getObjCSelector().getString(buffer); - type = decl->getType()->castTo()->getResult(); - - // Append a '+' for static methods, '-' for instance methods. This - // distinguishes methods with a given name from properties that - // might have the same name. - if (func->isStatic()) { - buffer += '+'; - } else { - buffer += '-'; - } - selector = buffer.str(); - } else if (auto asd = dyn_cast(decl)) { - // Handle properties and subscripts. Only the getter matters. - selector = asd->getObjCGetterSelector().getString(buffer); - type = asd->getType(); - } else if (auto ctor = dyn_cast(decl)) { - // Handle constructors. - selector = ctor->getObjCSelector().getString(buffer); - type = decl->getType()->castTo()->getResult(); - } else { - llvm_unreachable("Dynamic lookup found a non-[objc] result"); + auto type = + decl->getInterfaceType()->castTo()->getResult(); + return std::make_tuple(func->isStatic(), func->getObjCSelector(), + type->getCanonicalType()); } - // Look for this selector in the table. If we find it, we're done. - auto known = selectors.find(selector); - if (known != selectors.end()) - return { known->second, type->getCanonicalType() }; + if (auto asd = dyn_cast(decl)) { + // Handle properties and subscripts, anchored by the getter's selector. + return std::make_tuple(asd->isStatic(), asd->getObjCGetterSelector(), + asd->getInterfaceType()->getCanonicalType()); + } - // Add this selector to the table. - unsigned result = selectors.size(); - selectors[selector] = result; - return { result, type->getCanonicalType() }; + llvm_unreachable("Not a valid @objc member"); } LookupResult &ConstraintSystem::lookupMember(Type base, DeclName name) { @@ -235,13 +209,12 @@ LookupResult &ConstraintSystem::lookupMember(Type base, DeclName name) { return *result; // We are performing dynamic lookup. Filter out redundant results early. - llvm::DenseSet> known; - llvm::StringMap selectors; + llvm::DenseSet> known; result->filter([&](ValueDecl *decl) -> bool { if (decl->isInvalid()) return false; - return known.insert(getDynamicResultSignature(decl, selectors)).second; + return known.insert(getDynamicResultSignature(decl)).second; }); return *result; @@ -451,13 +424,11 @@ namespace { ConstraintSystem &CS; ConstraintGraph &CG; ConstraintLocatorBuilder &Locator; - DependentTypeOpener *Opener; public: GetTypeVariable(ConstraintSystem &cs, - ConstraintLocatorBuilder &locator, - DependentTypeOpener *opener) - : CS(cs), CG(CS.getConstraintGraph()), Locator(locator), Opener(opener) {} + ConstraintLocatorBuilder &locator) + : CS(cs), CG(CS.getConstraintGraph()), Locator(locator) {} TypeVariableType *operator()(Type base, AssociatedTypeDecl *member) { // FIXME: Premature associated type -> identifier mapping. We should @@ -503,31 +474,12 @@ namespace { auto memberTypeVar = CS.createTypeVariable(locator, TVO_PrefersSubtypeBinding); - // Determine whether we should bind the new type variable as a - // member of the base type variable, or let it float. - Type replacementType; - bool shouldBindMember = true; - if (Opener) { - shouldBindMember = Opener->shouldBindAssociatedType(base, baseTypeVar, - member, - memberTypeVar, - replacementType); - } - // Bind the member's type variable as a type member of the base, - // if needed. - if (shouldBindMember) { - CS.addConstraint(Constraint::create(CS, ConstraintKind::TypeMember, - baseTypeVar, memberTypeVar, - member->getName(), locator)); - } + // Bind the member's type variable as a type member of the base. + CS.addConstraint(Constraint::create(CS, ConstraintKind::TypeMember, + baseTypeVar, memberTypeVar, + member->getName(), locator)); - // If we have a replacement type, bind the member's type - // variable to it. - if (replacementType) - CS.addConstraint(ConstraintKind::Bind, memberTypeVar, - replacementType, locator); - if (!archetype) { // If the nested type is not an archetype (because it was constrained // to a concrete type by a requirement), return the fresh type @@ -558,7 +510,7 @@ namespace { ConstraintSystem &cs; DeclContext *dc; bool skipProtocolSelfConstraint; - DependentTypeOpener *opener; + unsigned minOpeningDepth; ConstraintLocatorBuilder &locator; llvm::DenseMap &replacements; GetTypeVariable &getTypeVariable; @@ -568,13 +520,13 @@ namespace { ConstraintSystem &cs, DeclContext *dc, bool skipProtocolSelfConstraint, - DependentTypeOpener *opener, + unsigned minOpeningDepth, ConstraintLocatorBuilder &locator, llvm::DenseMap &replacements, GetTypeVariable &getTypeVariable) : cs(cs), dc(dc), skipProtocolSelfConstraint(skipProtocolSelfConstraint), - opener(opener), locator(locator), replacements(replacements), - getTypeVariable(getTypeVariable) { } + minOpeningDepth(minOpeningDepth), locator(locator), + replacements(replacements), getTypeVariable(getTypeVariable) { } Type operator()(Type type) { assert(!type->is() && "Shouldn't get here"); @@ -584,24 +536,8 @@ namespace { return type; } - // Replace archetypes with fresh type variables. - if (auto archetype = type->getAs()) { - auto known = replacements.find(archetype->getCanonicalType()); - if (known != replacements.end()) - return known->second; - - return archetype; - } - // Replace a generic type parameter with its corresponding type variable. if (auto genericParam = type->getAs()) { - if (opener) { - // If we have a mapping for this type parameter, there's nothing else to do. - if (Type replacement = opener->mapGenericTypeParamType(genericParam)){ - return replacement; - } - } - auto known = replacements.find(genericParam->getCanonicalType()); if (known == replacements.end()) @@ -613,14 +549,6 @@ namespace { // Replace a dependent member with a fresh type variable and make it a // member of its base type. if (auto dependentMember = type->getAs()) { - if (opener) { - // If we have a mapping for this type parameter, there's nothing else to do. - if (Type replacement - = opener->mapDependentMemberType(dependentMember)) { - return replacement; - } - } - // Check whether we've already dealt with this dependent member. auto known = replacements.find(dependentMember->getCanonicalType()); if (known != replacements.end()) @@ -643,7 +571,7 @@ namespace { genericFn->getGenericParams(), genericFn->getRequirements(), skipProtocolSelfConstraint, - opener, + minOpeningDepth, locator, replacements); @@ -678,7 +606,7 @@ namespace { unboundDecl->getGenericParamTypes(), unboundDecl->getGenericRequirements(), /*skipProtocolSelfConstraint=*/false, - opener, + minOpeningDepth, locator, replacements); @@ -703,12 +631,12 @@ Type ConstraintSystem::openType( llvm::DenseMap &replacements, DeclContext *dc, bool skipProtocolSelfConstraint, - DependentTypeOpener *opener) { - GetTypeVariable getTypeVariable{*this, locator, opener}; + unsigned minOpeningDepth) { + GetTypeVariable getTypeVariable{*this, locator}; ReplaceDependentTypes replaceDependentTypes(*this, dc, skipProtocolSelfConstraint, - opener, + minOpeningDepth, locator, replacements, getTypeVariable); return startingType.transform(replaceDependentTypes); @@ -748,9 +676,8 @@ bool ConstraintSystem::isSetType(Type type) { } Type ConstraintSystem::openBindingType(Type type, - ConstraintLocatorBuilder locator, - DeclContext *dc) { - Type result = openType(type, locator, dc); + ConstraintLocatorBuilder locator) { + Type result = openType(type, locator); if (isArrayType(type)) { auto boundStruct = cast(type.getPointer()); @@ -849,8 +776,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value, bool isTypeReference, bool isSpecialized, ConstraintLocatorBuilder locator, - const DeclRefExpr *base, - DependentTypeOpener *opener) { + const DeclRefExpr *base) { llvm::DenseMap replacements; if (value->getDeclContext()->isTypeContext() && isa(value)) { @@ -858,8 +784,11 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value, auto func = cast(value); assert(func->isOperator() && "Lookup should only find operators"); - auto openedType = openType(func->getInterfaceType(), locator, - replacements, func, false, opener); + auto openedType = + openType(func->getInterfaceType(), locator, + replacements, func, + false, + value->getDeclContext()->getGenericTypeContextDepth()); auto openedFnType = openedType->castTo(); // If this is a method whose result type is dynamic Self, replace @@ -868,7 +797,7 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value, Type selfTy = openedFnType->getInput()->getRValueInstanceType(); openedType = openedType->replaceCovariantResultType( selfTy, - func->getNumParamPatterns()); + func->getNumParameterLists()); openedFnType = openedType->castTo(); } @@ -897,7 +826,9 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value, // Open the type. type = openType(type, locator, replacements, - value->getInnermostDeclContext(), false, opener); + value->getInnermostDeclContext(), + false, + value->getDeclContext()->getGenericTypeContextDepth()); // If we opened up any type variables, record the replacements. recordOpenedTypes(locator, replacements); @@ -932,9 +863,9 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value, // Adjust the type of the reference. valueType = openType(valueType, locator, replacements, - value->getPotentialGenericDeclContext(), + value->getInnermostDeclContext(), /*skipProtocolSelfConstraint=*/false, - opener); + value->getDeclContext()->getGenericTypeContextDepth()); // If we opened up any type variables, record the replacements. recordOpenedTypes(locator, replacements); @@ -947,18 +878,13 @@ void ConstraintSystem::openGeneric( ArrayRef params, ArrayRef requirements, bool skipProtocolSelfConstraint, - DependentTypeOpener *opener, + unsigned minOpeningDepth, ConstraintLocatorBuilder locator, llvm::DenseMap &replacements) { auto locatorPtr = getConstraintLocator(locator); // Create the type variables for the generic parameters. for (auto gp : params) { - // If we have a mapping for this type parameter, there's nothing else to do. - if (opener && opener->mapGenericTypeParamType(gp)) { - continue; - } - ArchetypeType *archetype = ArchetypeBuilder::mapTypeIntoContext(dc, gp) ->castTo(); auto typeVar = createTypeVariable(getConstraintLocator( @@ -968,22 +894,16 @@ void ConstraintSystem::openGeneric( TVO_MustBeMaterializable); replacements[gp->getCanonicalType()] = typeVar; - // Note that we opened a generic parameter to a type variable. - if (opener) { - Type replacementType; - opener->openedGenericParameter(gp, typeVar, replacementType); - - if (replacementType) - addConstraint(ConstraintKind::Bind, typeVar, replacementType, - locatorPtr); - } + if (gp->getDepth() < minOpeningDepth) + addConstraint(ConstraintKind::Bind, typeVar, archetype, locatorPtr); } - GetTypeVariable getTypeVariable{*this, locator, opener}; + GetTypeVariable getTypeVariable{*this, locator}; ReplaceDependentTypes replaceDependentTypes(*this, dc, skipProtocolSelfConstraint, - opener, locator, replacements, + minOpeningDepth, + locator, replacements, getTypeVariable); // Remember that any new constraints generated by opening this generic are @@ -1080,12 +1000,13 @@ Type ConstraintSystem::replaceSelfTypeInArchetype(ArchetypeType *archetype) { } std::pair -ConstraintSystem::getTypeOfMemberReference(Type baseTy, ValueDecl *value, - bool isTypeReference, - bool isDynamicResult, - ConstraintLocatorBuilder locator, - const DeclRefExpr *base, - DependentTypeOpener *opener) { +ConstraintSystem::getTypeOfMemberReference( + Type baseTy, ValueDecl *value, + bool isTypeReference, + bool isDynamicResult, + ConstraintLocatorBuilder locator, + const DeclRefExpr *base, + llvm::DenseMap *replacementsPtr) { // Figure out the instance type used for the base. TypeVariableType *baseTypeVar = nullptr; Type baseObjTy = getFixedTypeRecursive(baseTy, baseTypeVar, @@ -1099,7 +1020,7 @@ ConstraintSystem::getTypeOfMemberReference(Type baseTy, ValueDecl *value, // If the base is a module type, just use the type of the decl. if (baseObjTy->is()) { return getTypeOfReference(value, isTypeReference, /*isSpecialized=*/false, - locator, base, opener); + locator, base); } // Handle associated type lookup as a special case, horribly. @@ -1149,29 +1070,35 @@ ConstraintSystem::getTypeOfMemberReference(Type baseTy, ValueDecl *value, } // Figure out the declaration context to use when opening this type. - DeclContext *dc = value->getPotentialGenericDeclContext(); + DeclContext *dc = value->getInnermostDeclContext(); + unsigned minOpeningDepth = + value->getDeclContext()->getGenericTypeContextDepth(); // Open the type of the generic function or member of a generic type. Type openedType; auto isClassBoundExistential = false; - llvm::DenseMap replacements; + llvm::DenseMap localReplacements; + auto &replacements = replacementsPtr ? *replacementsPtr : localReplacements; if (auto genericFn = value->getInterfaceType()->getAs()){ openedType = openType(genericFn, locator, replacements, dc, - /*skipProtocolSelfConstraint=*/true, opener); + /*skipProtocolSelfConstraint=*/true, + minOpeningDepth); } else { openedType = TC.getUnopenedTypeOfReference(value, baseTy, DC, base, /*wantInterfaceType=*/true); Type selfTy; if (auto sig = dc->getGenericSignatureOfContext()) { + // Open up the generic parameter list for the container. openGeneric(dc, sig->getGenericParams(), sig->getRequirements(), - /*skipProtocolSelfConstraint=*/true, - opener, locator, replacements); + /*skipProtocolSelfConstraint=*/true, minOpeningDepth, + locator, replacements); // Open up the type of the member. - openedType = openType(openedType, locator, replacements, nullptr, false, - opener); + openedType = openType(openedType, locator, replacements, nullptr, + /*skipProtocolSelfConstraint=*/false, + minOpeningDepth); // Determine the object type of 'self'. auto nominal = value->getDeclContext()->getDeclaredTypeOfContext() @@ -1224,7 +1151,7 @@ ConstraintSystem::getTypeOfMemberReference(Type baseTy, ValueDecl *value, func->hasArchetypeSelf())) { openedType = openedType->replaceCovariantResultType( baseObjTy, - func->getNumParamPatterns()); + func->getNumParameterLists()); } } // If this is an initializer, replace the result type with the base diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index e071b3339d65d..9166780322293 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -219,7 +219,7 @@ class TypeVariableType::Implementation { if (!ParentOrFixed.is()) return true; - // Check whether the representatative is different from our own type + // Check whether the representative is different from our own type // variable. return ParentOrFixed.get() != getTypeVariable(); } @@ -365,10 +365,6 @@ class Failure : public llvm::FoldingSetNode { IsNotBridgedToObjectiveC, /// \brief The type is not allowed to be an l-value. IsForbiddenLValue, - /// Missing argument in a call. - MissingArgument, - /// Extra argument in a call. - ExtraArgument, /// Type has no public initializers. NoPublicInitializers, /// The type is not materializable. @@ -437,12 +433,9 @@ class Failure : public llvm::FoldingSetNode { getSecondType()); case IsNotBridgedToObjectiveC: - case MissingArgument: case NoPublicInitializers: return Profile(id, locator, kind, resolvedOverloadSets, getFirstType(), value); - case ExtraArgument: - return Profile(id, locator, kind, resolvedOverloadSets, value, value2); } } @@ -980,66 +973,6 @@ struct SpecificConstraint { ConstraintKind Kind; }; -/// Abstract class implemented by clients that want to be involved in -/// the process of opening dependent types to type variables. -class DependentTypeOpener { -public: - virtual ~DependentTypeOpener() { } - - /// Directly map a generic type parameter to a type, or return null if - /// the type parameter should be opened. - virtual Type mapGenericTypeParamType(GenericTypeParamType *param) { - return Type(); - } - - /// Directly map a dependent member type to a type, or return null if - /// the dependent member type should be opened. - virtual Type mapDependentMemberType(DependentMemberType *memberType) { - return Type(); - } - - /// Invoked when a generic type parameter is opened to a type variable. - /// - /// \param param The generic type parameter. - /// - /// \param typeVar The type variable to which the generic parameter was - /// opened. - /// - /// \param replacementType If the caller sets this to a non-null type, the - /// type variable will be bound directly to this type. - virtual void openedGenericParameter(GenericTypeParamType *param, - TypeVariableType *typeVar, - Type &replacementType) { } - - /// Invoked when an associated type reference is opened to a type - /// variable to determine how the associated type should be resolved. - /// - /// \param baseType The type of the base of the reference. - /// - /// \param baseTypeVar The type variable to which the base type was - /// opened. - /// - /// \param assocType The associated type being opened. - /// - /// \param memberTypeVar The type variable representing the - /// dependent member type. - /// - /// \param replacementType If the caller sets this to a non-null type, the - /// member type variable will be bound directly to this type. - /// - /// \returns true if the constraint system should introduce a - /// constraint that specifies that the member type is in fact a the - /// named member of the base's type variable. - virtual bool shouldBindAssociatedType(Type baseType, - TypeVariableType *baseTypeVar, - AssociatedTypeDecl *assocType, - TypeVariableType *memberTypeVar, - Type &replacementType) { - return true; - } -}; - - /// An intrusive, doubly-linked list of constraints. typedef llvm::ilist ConstraintList; @@ -1059,7 +992,7 @@ struct MemberLookupResult { Unsolved, /// This result indicates that the member reference is erroneous, but was - /// already dianosed. Don't emit another error. + /// already diagnosed. Don't emit another error. ErrorAlreadyDiagnosed, /// This result indicates that the lookup produced candidate lists, @@ -1145,7 +1078,7 @@ class ConstraintSystem { Constraint *failedConstraint = nullptr; - /// \brief Failures that occured while solving. + /// \brief Failures that occurred while solving. /// /// FIXME: We really need to track overload sets and type variable bindings /// to make any sense of this data. Also, it probably belongs within @@ -1612,7 +1545,7 @@ class ConstraintSystem { /// \brief Whether we should be recording failures. bool shouldRecordFailures() { // FIXME: It still makes sense to record failures when there are fixes - // present, but they shold be less desirable. + // present, but they should be less desirable. if (!Fixes.empty()) return false; @@ -1853,17 +1786,13 @@ class ConstraintSystem { /// /// \param dc The declaration context in which the type occurs. /// - /// \param skipProtocolSelfConstraint Whether to skip the constraint on a - /// protocol's 'Self' type. - /// /// \returns The opened type. Type openType(Type type, ConstraintLocatorBuilder locator, - DeclContext *dc = nullptr, - bool skipProtocolSelfConstraint = false, - DependentTypeOpener *opener = nullptr) { + DeclContext *dc = nullptr) { llvm::DenseMap replacements; - return openType(type, locator, replacements, dc, skipProtocolSelfConstraint, - opener); + return openType(type, locator, replacements, dc, + /*skipProtocolSelfConstraint=*/false, + /*minOpeningDepth=*/0); } /// \brief "Open" the given type by replacing any occurrences of generic @@ -1879,8 +1808,9 @@ class ConstraintSystem { /// \param skipProtocolSelfConstraint Whether to skip the constraint on a /// protocol's 'Self' type. /// - /// \param opener Abstract class that assists in opening dependent - /// types. + /// \param minOpeningDepth Whether to skip generic parameters from generic + /// contexts that we're inheriting context archetypes from. See the comment + /// on openGeneric(). /// /// \returns The opened type, or \c type if there are no archetypes in it. Type openType(Type type, @@ -1888,7 +1818,7 @@ class ConstraintSystem { llvm::DenseMap &replacements, DeclContext *dc = nullptr, bool skipProtocolSelfConstraint = false, - DependentTypeOpener *opener = nullptr); + unsigned minOpeningDepth = 0); /// \brief "Open" the given binding type by replacing any occurrences of /// archetypes (including those implicit in unbound generic types) with @@ -1900,16 +1830,34 @@ class ConstraintSystem { /// /// \param type The type to open. /// \returns The opened type, or \c type if there are no archetypes in it. - Type openBindingType(Type type, ConstraintLocatorBuilder locator, - DeclContext *dc = nullptr); + Type openBindingType(Type type, ConstraintLocatorBuilder locator); /// Open the generic parameter list and its requirements, creating /// type variables for each of the type parameters. + /// + /// Note: when a generic declaration is nested inside a generic function, the + /// generic parameters of the outer function do not appear in the inner type's + /// generic signature. + /// + /// Eg, + /// + /// func foo() { + /// func g() -> T {} // type is () -> T + /// } + /// + /// class Foo { + /// func g() -> T {} // type is Foo -> () -> T + /// } + /// + /// Instead, the outer parameters can appear as free variables in the nested + /// declaration's signature, but they do not have to, so they might not be + /// substituted at all. Since the inner declaration inherits the context + /// archetypes of the outer function we do not need to open them here. void openGeneric(DeclContext *dc, ArrayRef params, ArrayRef requirements, bool skipProtocolSelfConstraint, - DependentTypeOpener *opener, + unsigned minOpeningDepth, ConstraintLocatorBuilder locator, llvm::DenseMap &replacements); @@ -1938,8 +1886,7 @@ class ConstraintSystem { bool isTypeReference, bool isSpecialized, ConstraintLocatorBuilder locator, - const DeclRefExpr *base = nullptr, - DependentTypeOpener *opener = nullptr); + const DeclRefExpr *base = nullptr); /// Replace the 'Self' type in the archetype with the appropriate /// type variable, if needed. @@ -1967,7 +1914,8 @@ class ConstraintSystem { bool isDynamicResult, ConstraintLocatorBuilder locator, const DeclRefExpr *base = nullptr, - DependentTypeOpener *opener = nullptr); + llvm::DenseMap + *replacements = nullptr); /// \brief Add a new overload set to the list of unresolved overload /// sets. @@ -2057,7 +2005,7 @@ class ConstraintSystem { /// Indicates we're matching an operator parameter. TMF_ApplyingOperatorParameter = 0x4, - /// Indicates we're unwrapping an optional type for an value-to-optional + /// Indicates we're unwrapping an optional type for a value-to-optional /// conversion. TMF_UnwrappingOptional = 0x8, @@ -2282,7 +2230,7 @@ class ConstraintSystem { /// \returns true if an error occurred, false otherwise. bool simplify(bool ContinueAfterFailures = false); - /// \brief Simplify the given constaint. + /// \brief Simplify the given constraint. SolutionKind simplifyConstraint(const Constraint &constraint); private: @@ -2375,9 +2323,14 @@ class ConstraintSystem { /// /// \param convertType the contextual type to which the /// expression should be converted, if any. + /// \param discardedExpr if true, the result of the expression + /// is contextually ignored. + /// \param skipClosures if true, don't descend into bodies of + /// non-single expression closures. Expr *applySolution(Solution &solution, Expr *expr, Type convertType, bool discardedExpr, - bool suppressDiagnostics); + bool suppressDiagnostics, + bool skipClosures); /// \brief Apply a given solution to the expression to the top-level /// expression, producing a fully type-checked expression. @@ -2406,7 +2359,7 @@ class ConstraintSystem { } /// \brief Reorder the disjunctive clauses for a given expression to - /// increase the likelyhood that a favored constraint will be be successfully + /// increase the likelihood that a favored constraint will be successfully /// resolved before any others. void optimizeConstraints(Expr *e); @@ -2519,7 +2472,7 @@ class MatchCallArgumentListener { /// \param prevArgIdx The argument that the \c argIdx should have preceded. virtual void outOfOrderArgument(unsigned argIdx, unsigned prevArgIdx); - /// Indicates that the arguments need to be relabed to match the parameters. + /// Indicates that the arguments need to be relabeled to match the parameters. /// /// \returns true to indicate that this should cause a failure, false /// otherwise. diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp index ed433573327ac..e2722aeea7a91 100644 --- a/lib/Sema/DerivedConformanceEquatableHashable.cpp +++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp @@ -1,8 +1,8 @@ -//===--- DerivedConformanceEquatableHashable.cpp - Derived Equatable & co. ===// +//===--- DerivedConformanceEquatableHashable.cpp - Derived Equatable & co -===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -128,15 +128,9 @@ static void deriveBodyEquatable_enum_eq(AbstractFunctionDecl *eqDecl) { auto parentDC = eqDecl->getDeclContext(); ASTContext &C = parentDC->getASTContext(); - auto args = cast(eqDecl->getBodyParamPatterns().back()); - auto aPattern = args->getElement(0).getPattern(); - auto aParamPattern = - cast(aPattern->getSemanticsProvidingPattern()); - auto aParam = aParamPattern->getDecl(); - auto bPattern = args->getElement(1).getPattern(); - auto bParamPattern = - cast(bPattern->getSemanticsProvidingPattern()); - auto bParam = bParamPattern->getDecl(); + auto args = eqDecl->getParameterLists().back(); + auto aParam = args->get(0); + auto bParam = args->get(1); CanType boolTy = C.getBoolDecl()->getDeclaredType().getCanonicalTypeOrNull(); @@ -200,48 +194,22 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) { auto parentDC = cast(parentDecl); auto enumTy = parentDC->getDeclaredTypeInContext(); - auto getParamPattern = [&](StringRef s) -> std::pair { - VarDecl *aDecl = new (C) ParamDecl(/*isLet*/ true, - SourceLoc(), - Identifier(), - SourceLoc(), - C.getIdentifier(s), - enumTy, - parentDC); - aDecl->setImplicit(); - Pattern *aParam = new (C) NamedPattern(aDecl, /*implicit*/ true); - aParam->setType(enumTy); - aParam = new (C) TypedPattern(aParam, TypeLoc::withoutLoc(enumTy)); - aParam->setType(enumTy); - aParam->setImplicit(); - return {aDecl, aParam}; + auto getParamDecl = [&](StringRef s) -> ParamDecl* { + return new (C) ParamDecl(/*isLet*/true, SourceLoc(), Identifier(), + SourceLoc(), C.getIdentifier(s), enumTy, + parentDC); }; - auto aParam = getParamPattern("a"); - auto bParam = getParamPattern("b"); - - TupleTypeElt typeElts[] = { - TupleTypeElt(enumTy), - TupleTypeElt(enumTy) - }; - auto paramsTy = TupleType::get(typeElts, C); - - TuplePatternElt paramElts[] = { - TuplePatternElt(aParam.second), - TuplePatternElt(bParam.second), - }; - auto params = TuplePattern::create(C, SourceLoc(), - paramElts, SourceLoc()); - params->setImplicit(); - params->setType(paramsTy); + auto params = ParameterList::create(C, { + getParamDecl("a"), + getParamDecl("b") + }); auto genericParams = parentDC->getGenericParamsOfContext(); - auto boolTy = C.getBoolDecl()->getDeclaredType(); - auto moduleDC = parentDecl->getModuleContext(); - DeclName name(C, C.Id_EqualsOperator, { Identifier(), Identifier() }); + DeclName name(C, C.Id_EqualsOperator, params); auto eqDecl = FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, SourceLoc(), name, SourceLoc(), SourceLoc(), SourceLoc(), @@ -266,11 +234,18 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) { eqDecl->setDerivedForTypeDecl(enumDecl); eqDecl->setBodySynthesizer(&deriveBodyEquatable_enum_eq); - // Compute the type and interface type. - Type fnTy, interfaceTy; - if (genericParams) { + // Compute the type. + auto paramsTy = params->getType(C); + Type fnTy; + if (genericParams) fnTy = PolymorphicFunctionType::get(paramsTy, boolTy, genericParams); - + else + fnTy = FunctionType::get(paramsTy, boolTy); + eqDecl->setType(fnTy); + + // Compute the interface type. + Type interfaceTy; + if (auto genericSig = parentDC->getGenericSignatureOfContext()) { auto enumIfaceTy = parentDC->getDeclaredInterfaceType(); TupleTypeElt ifaceParamElts[] = { enumIfaceTy, enumIfaceTy, @@ -278,13 +253,11 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) { auto ifaceParamsTy = TupleType::get(ifaceParamElts, C); interfaceTy = GenericFunctionType::get( - parentDC->getGenericSignatureOfContext(), - ifaceParamsTy, boolTy, + genericSig, ifaceParamsTy, boolTy, AnyFunctionType::ExtInfo()); } else { - fnTy = interfaceTy = FunctionType::get(paramsTy, boolTy); + interfaceTy = FunctionType::get(paramsTy, boolTy); } - eqDecl->setType(fnTy); eqDecl->setInterfaceType(interfaceTy); // Since we can't insert the == operator into the same FileUnit as the enum, @@ -325,13 +298,8 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) { ASTContext &C = parentDC->getASTContext(); auto enumDecl = parentDC->isEnumOrEnumExtensionContext(); - SmallVector statements; - - Pattern *curriedArgs = hashValueDecl->getBodyParamPatterns().front(); - auto selfPattern = - cast(curriedArgs->getSemanticsProvidingPattern()); - auto selfDecl = selfPattern->getDecl(); + auto selfDecl = hashValueDecl->getImplicitSelfDecl(); DeclRefExpr *indexRef = convertEnumToIndex(statements, parentDC, enumDecl, selfDecl, hashValueDecl, "index"); @@ -369,8 +337,6 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl, ASTContext &C = tc.Context; auto parentDC = cast(parentDecl); - - Type enumType = parentDC->getDeclaredTypeInContext(); Type intType = C.getIntDecl()->getDeclaredType(); // We can't form a Hashable conformance if Int isn't Hashable or @@ -389,21 +355,12 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl, return nullptr; } - VarDecl *selfDecl = new (C) ParamDecl(/*IsLet*/true, - SourceLoc(), - Identifier(), - SourceLoc(), - C.Id_self, - enumType, - parentDC); - selfDecl->setImplicit(); - Pattern *selfParam = new (C) NamedPattern(selfDecl, /*implicit*/ true); - selfParam->setType(enumType); - selfParam = new (C) TypedPattern(selfParam, TypeLoc::withoutLoc(enumType)); - selfParam->setType(enumType); - Pattern *methodParam = TuplePattern::create(C, SourceLoc(),{},SourceLoc()); - methodParam->setType(TupleType::getEmpty(tc.Context)); - Pattern *params[] = {selfParam, methodParam}; + auto selfDecl = ParamDecl::createSelf(SourceLoc(), parentDC); + + ParameterList *params[] = { + ParameterList::createWithoutLoc(selfDecl), + ParameterList::createEmpty(C) + }; FuncDecl *getterDecl = FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, SourceLoc(), @@ -414,9 +371,11 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl, getterDecl->setBodySynthesizer(deriveBodyHashable_enum_hashValue); // Compute the type of hashValue(). - GenericParamList *genericParams = nullptr; + GenericParamList *genericParams = getterDecl->getGenericParamsOfContext(); Type methodType = FunctionType::get(TupleType::getEmpty(tc.Context), intType); - Type selfType = getterDecl->computeSelfType(&genericParams); + Type selfType = getterDecl->computeSelfType(); + selfDecl->overwriteType(selfType); + Type type; if (genericParams) type = PolymorphicFunctionType::get(selfType, methodType, genericParams); @@ -432,7 +391,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl, interfaceType = GenericFunctionType::get(sig, selfIfaceType, methodType, AnyFunctionType::ExtInfo()); else - interfaceType = type; + interfaceType = FunctionType::get(selfType, methodType); getterDecl->setInterfaceType(interfaceType); getterDecl->setAccessibility(enumDecl->getFormalAccess()); diff --git a/lib/Sema/DerivedConformanceErrorType.cpp b/lib/Sema/DerivedConformanceErrorType.cpp index 741f0819272b3..99c7b32ef3bf8 100644 --- a/lib/Sema/DerivedConformanceErrorType.cpp +++ b/lib/Sema/DerivedConformanceErrorType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -147,11 +147,10 @@ static ValueDecl *deriveErrorType_code(TypeChecker &tc, Decl *parentDecl, ASTContext &C = tc.Context; auto intTy = C.getIntDecl()->getDeclaredType(); - Type nominalType = cast(parentDecl)->getDeclaredTypeInContext(); // Define the getter. auto getterDecl = declareDerivedPropertyGetter(tc, parentDecl, nominal, - nominalType, intTy, intTy); + intTy, intTy); if (isa(nominal)) getterDecl->setBodySynthesizer(&deriveBodyErrorType_enum_code); else @@ -225,11 +224,10 @@ static ValueDecl *deriveBridgedNSError_enum_NSErrorDomain(TypeChecker &tc, ASTContext &C = tc.Context; auto stringTy = C.getStringDecl()->getDeclaredType(); - Type enumType = enumDecl->getDeclaredTypeInContext(); // Define the getter. auto getterDecl = declareDerivedPropertyGetter(tc, parentDecl, enumDecl, - enumType, stringTy, stringTy, + stringTy, stringTy, /*isStatic=*/true); getterDecl->setBodySynthesizer(&deriveBodyBridgedNSError_enum_NSErrorDomain); diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp index e08e2dad45a22..e5a1916b5dfd9 100644 --- a/lib/Sema/DerivedConformanceRawRepresentable.cpp +++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -130,11 +130,8 @@ static VarDecl *deriveRawRepresentable_raw(TypeChecker &tc, auto rawInterfaceType = enumDecl->getRawType(); auto rawType = ArchetypeBuilder::mapTypeIntoContext(parentDC, rawInterfaceType); - Type enumType = parentDC->getDeclaredTypeInContext(); - // Define the getter. auto getterDecl = declareDerivedPropertyGetter(tc, parentDecl, enumDecl, - enumType, rawInterfaceType, rawType); getterDecl->setBodySynthesizer(&deriveBodyRawRepresentable_raw); @@ -234,9 +231,7 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl) { /*HasBoundDecls=*/false, SourceLoc(), dfltBody)); - Pattern *args = initDecl->getBodyParamPatterns().back(); - auto rawArgPattern = cast(args->getSemanticsProvidingPattern()); - auto rawDecl = rawArgPattern->getDecl(); + auto rawDecl = initDecl->getParameterList(1)->get(0); auto rawRef = new (C) DeclRefExpr(rawDecl, SourceLoc(), /*implicit*/true); auto switchStmt = SwitchStmt::create(LabeledStmtInfo(), SourceLoc(), rawRef, SourceLoc(), cases, SourceLoc(), C); @@ -270,55 +265,28 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc, } Type enumType = parentDC->getDeclaredTypeInContext(); - VarDecl *selfDecl = new (C) ParamDecl(/*IsLet*/false, - SourceLoc(), - Identifier(), - SourceLoc(), - C.Id_self, - enumType, - parentDC); - selfDecl->setImplicit(); - Pattern *selfParam = new (C) NamedPattern(selfDecl, /*implicit*/ true); - selfParam->setType(enumType); - selfParam = new (C) TypedPattern(selfParam, - TypeLoc::withoutLoc(enumType)); - selfParam->setType(enumType); - selfParam->setImplicit(); - - VarDecl *rawDecl = new (C) ParamDecl(/*IsVal*/true, - SourceLoc(), - C.Id_rawValue, - SourceLoc(), - C.Id_rawValue, - rawType, - parentDC); + auto *selfDecl = ParamDecl::createSelf(SourceLoc(), parentDC, + /*static*/false, /*inout*/true); + + auto *rawDecl = new (C) ParamDecl(/*IsLet*/true, SourceLoc(), + C.Id_rawValue, SourceLoc(), + C.Id_rawValue, rawType, parentDC); rawDecl->setImplicit(); - Pattern *rawParam = new (C) NamedPattern(rawDecl, /*implicit*/ true); - rawParam->setType(rawType); - rawParam = new (C) TypedPattern(rawParam, TypeLoc::withoutLoc(rawType)); - rawParam->setType(rawType); - rawParam->setImplicit(); - rawParam = new (C) ParenPattern(SourceLoc(), rawParam, SourceLoc()); - rawParam->setType(rawType); - rawParam->setImplicit(); + auto paramList = ParameterList::createWithoutLoc(rawDecl); auto retTy = OptionalType::get(enumType); - DeclName name(C, C.Id_init, { C.Id_rawValue }); + DeclName name(C, C.Id_init, paramList); auto initDecl = new (C) ConstructorDecl(name, SourceLoc(), /*failability*/ OTK_Optional, - SourceLoc(), - selfParam, - rawParam, - nullptr, - SourceLoc(), - parentDC); + SourceLoc(), selfDecl, paramList, + nullptr, SourceLoc(), parentDC); initDecl->setImplicit(); initDecl->setBodySynthesizer(&deriveBodyRawRepresentable_init); // Compute the type of the initializer. - GenericParamList *genericParams = nullptr; + GenericParamList *genericParams = initDecl->getGenericParamsOfContext(); TupleTypeElt element(rawType, C.Id_rawValue); auto argType = TupleType::get(element, C); @@ -326,7 +294,9 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc, auto interfaceArgType = TupleType::get(interfaceElement, C); Type type = FunctionType::get(argType, retTy); - Type selfType = initDecl->computeSelfType(&genericParams); + + Type selfType = initDecl->computeSelfType(); + selfDecl->overwriteType(selfType); Type selfMetatype = MetatypeType::get(selfType->getInOutObjectType()); Type allocType; @@ -359,8 +329,8 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc, interfaceType, FunctionType::ExtInfo()); } else { - allocIfaceType = allocType; - initIfaceType = initType; + allocIfaceType = FunctionType::get(selfMetatype, type); + initIfaceType = FunctionType::get(selfType, type); } initDecl->setInterfaceType(allocIfaceType); initDecl->setInitializerInterfaceType(initIfaceType); diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp index f090985b56c0c..d7985d2297682 100644 --- a/lib/Sema/DerivedConformances.cpp +++ b/lib/Sema/DerivedConformances.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -117,45 +117,24 @@ DeclRefExpr * DerivedConformance::createSelfDeclRef(AbstractFunctionDecl *fn) { ASTContext &C = fn->getASTContext(); - Pattern *curriedArgs = fn->getBodyParamPatterns().front(); - auto selfPattern = - cast(curriedArgs->getSemanticsProvidingPattern()); - auto selfDecl = selfPattern->getDecl(); + auto selfDecl = fn->getImplicitSelfDecl(); return new (C) DeclRefExpr(selfDecl, SourceLoc(), /*implicit*/true); } FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc, Decl *parentDecl, NominalTypeDecl *typeDecl, - Type contextType, Type propertyInterfaceType, Type propertyContextType, bool isStatic) { auto &C = tc.Context; - - Type selfType = contextType; - if (isStatic) - selfType = MetatypeType::get(selfType); - auto parentDC = cast(parentDecl); - - VarDecl *selfDecl = new (C) ParamDecl(/*IsLet*/true, - SourceLoc(), - Identifier(), - SourceLoc(), - C.Id_self, - selfType, - parentDC); - selfDecl->setImplicit(); - Pattern *selfParam = new (C) NamedPattern(selfDecl, /*implicit*/ true); - selfParam->setType(selfType); - selfParam = new (C) TypedPattern(selfParam, - TypeLoc::withoutLoc(selfType)); - selfParam->setType(selfType); - Pattern *methodParam = TuplePattern::create(C, SourceLoc(),{},SourceLoc()); - methodParam->setType(TupleType::getEmpty(C)); - Pattern *params[] = {selfParam, methodParam}; - + auto selfDecl = ParamDecl::createSelf(SourceLoc(), parentDC, isStatic); + ParameterList *params[] = { + ParameterList::createWithoutLoc(selfDecl), + ParameterList::createEmpty(C) + }; + FuncDecl *getterDecl = FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, SourceLoc(), DeclName(), SourceLoc(), SourceLoc(), SourceLoc(), @@ -165,10 +144,12 @@ FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc, getterDecl->setStatic(isStatic); // Compute the type of the getter. - GenericParamList *genericParams = nullptr; + GenericParamList *genericParams = getterDecl->getGenericParamsOfContext(); Type type = FunctionType::get(TupleType::getEmpty(C), propertyContextType); - selfType = getterDecl->computeSelfType(&genericParams); + Type selfType = getterDecl->computeSelfType(); + selfDecl->overwriteType(selfType); + if (genericParams) type = PolymorphicFunctionType::get(selfType, type, genericParams); else @@ -207,8 +188,7 @@ DerivedConformance::declareDerivedReadOnlyProperty(TypeChecker &tc, auto &C = tc.Context; auto parentDC = cast(parentDecl); - VarDecl *propDecl = new (C) VarDecl(isStatic, - /*let*/ false, + VarDecl *propDecl = new (C) VarDecl(isStatic, /*let*/ false, SourceLoc(), name, propertyContextType, parentDC); diff --git a/lib/Sema/DerivedConformances.h b/lib/Sema/DerivedConformances.h index d2d302819405a..2e3d3288bd11b 100644 --- a/lib/Sema/DerivedConformances.h +++ b/lib/Sema/DerivedConformances.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -127,7 +127,6 @@ inline SomeDecl *insertOperatorDecl(ASTContext &C, FuncDecl *declareDerivedPropertyGetter(TypeChecker &tc, Decl *parentDecl, NominalTypeDecl *typeDecl, - Type contextType, Type propertyInterfaceType, Type propertyContextType, bool isStatic = false); diff --git a/lib/Sema/GenericTypeResolver.h b/lib/Sema/GenericTypeResolver.h index a69bfe23b7b3b..3a3bb5822803e 100644 --- a/lib/Sema/GenericTypeResolver.h +++ b/lib/Sema/GenericTypeResolver.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/ITCDecl.cpp b/lib/Sema/ITCDecl.cpp index 086f272691c70..1371b77b31bc0 100644 --- a/lib/Sema/ITCDecl.cpp +++ b/lib/Sema/ITCDecl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,9 +22,9 @@ #include using namespace swift; -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Inheritance clause handling -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// static std::tuple> decomposeInheritedClauseDecl( @@ -116,9 +116,9 @@ bool IterativeTypeChecker::breakCycleForResolveInheritedClauseEntry( return true; } -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Superclass handling -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// bool IterativeTypeChecker::isTypeCheckSuperclassSatisfied(ClassDecl *payload) { return payload->LazySemanticInfo.Superclass.getInt(); } @@ -162,9 +162,9 @@ bool IterativeTypeChecker::breakCycleForTypeCheckSuperclass( return true; } -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Raw type handling -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// bool IterativeTypeChecker::isTypeCheckRawTypeSatisfied(EnumDecl *payload) { return payload->LazySemanticInfo.RawType.getInt(); } @@ -205,9 +205,9 @@ bool IterativeTypeChecker::breakCycleForTypeCheckRawType(EnumDecl *enumDecl) { return true; } -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Inherited protocols -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// bool IterativeTypeChecker::isInheritedProtocolsSatisfied(ProtocolDecl *payload){ return payload->isInheritedProtocolsValid(); } @@ -280,9 +280,9 @@ bool IterativeTypeChecker::breakCycleForInheritedProtocols( return true; } -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Resolve a type declaration -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// bool IterativeTypeChecker::isResolveTypeDeclSatisfied(TypeDecl *typeDecl) { if (auto typeAliasDecl = dyn_cast(typeDecl)) { // If the underlying type was validated, we're done. diff --git a/lib/Sema/ITCNameLookup.cpp b/lib/Sema/ITCNameLookup.cpp index 880d1460b8ea5..87ab7256d3682 100644 --- a/lib/Sema/ITCNameLookup.cpp +++ b/lib/Sema/ITCNameLookup.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,9 +21,9 @@ #include using namespace swift; -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Qualified name lookup handling -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// bool IterativeTypeChecker::isQualifiedLookupInDeclContextSatisfied( TypeCheckRequest::DeclContextLookupPayloadType payload) { auto dc = payload.DC; @@ -35,6 +35,7 @@ bool IterativeTypeChecker::isQualifiedLookupInDeclContextSatisfied( case DeclContextKind::Initializer: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::SerializedLocal: + case DeclContextKind::SubscriptDecl: llvm_unreachable("not a DeclContext that supports name lookup"); case DeclContextKind::Module: @@ -122,15 +123,16 @@ bool IterativeTypeChecker::breakCycleForQualifiedLookupInDeclContext( return false; } -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Qualified name lookup handling -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// bool IterativeTypeChecker::isUnqualifiedLookupInDeclContextSatisfied( TypeCheckRequest::DeclContextLookupPayloadType payload) { auto dc = payload.DC; switch (dc->getContextKind()) { case DeclContextKind::AbstractClosureExpr: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: case DeclContextKind::Initializer: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::SerializedLocal: diff --git a/lib/Sema/ITCType.cpp b/lib/Sema/ITCType.cpp index 1d7ccd3391123..8a8c4bdfc859d 100644 --- a/lib/Sema/ITCType.cpp +++ b/lib/Sema/ITCType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,12 +18,13 @@ #include "TypeChecker.h" #include "swift/Sema/IterativeTypeChecker.h" #include "swift/AST/ASTContext.h" +#include "swift/AST/ASTWalker.h" #include "swift/AST/Decl.h" using namespace swift; -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Type resolution. -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// bool IterativeTypeChecker::isResolveTypeReprSatisfied( std::tuple payload) { auto typeRepr = std::get<0>(payload); diff --git a/lib/Sema/IterativeTypeChecker.cpp b/lib/Sema/IterativeTypeChecker.cpp index d6cf18fcbce90..0cd26e9788ef4 100644 --- a/lib/Sema/IterativeTypeChecker.cpp +++ b/lib/Sema/IterativeTypeChecker.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -84,7 +84,7 @@ void IterativeTypeChecker::satisfy(TypeCheckRequest request) { // Add this request to the stack of active requests. ActiveRequests.push_back(request); - defer([&] { ActiveRequests.pop_back(); }); + defer { ActiveRequests.pop_back(); }; while (true) { // Process this requirement, enumerating dependencies if anything else needs @@ -112,9 +112,9 @@ void IterativeTypeChecker::satisfy(TypeCheckRequest request) { } } -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Diagnostics -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// void IterativeTypeChecker::diagnoseCircularReference( ArrayRef requests) { bool isFirst = true; diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 6a2d31cecd5e5..60d913cb3d724 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,9 +25,9 @@ #include "llvm/ADT/MapVector.h" using namespace swift; -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Diagnose assigning variable to itself. -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// static Decl *findSimpleReferencedDecl(const Expr *E) { if (auto *LE = dyn_cast(E)) @@ -115,7 +115,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E, enum : unsigned { Function, MutatingMethod, - ObjCProtocolMethod, SuperInit, SelfInit, }; @@ -136,32 +135,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E, } } - /// If this is an application of a function that cannot be partially - /// applied, arrange for us to check that it gets fully applied. - void recordUnsupportedPartialApply(DeclRefExpr *expr) { - bool requiresFullApply = false; - unsigned kind; - - auto fn = dyn_cast(expr->getDecl()); - if (!fn) - return; - - // @objc protocol methods cannot be partially applied. - if (auto proto = fn->getDeclContext()->isProtocolOrProtocolExtensionContext()) { - if (proto->isObjC()) { - requiresFullApply = true; - kind = PartialApplication::ObjCProtocolMethod; - } - } - - if (requiresFullApply) { - // We need to apply all argument clauses. - InvalidPartialApplications.insert({ - expr, {fn->getNaturalArgumentCount(), kind} - }); - } - } - /// If this is an application of a function that cannot be partially /// applied, arrange for us to check that it gets fully applied. void recordUnsupportedPartialApply(ApplyExpr *expr, Expr *fnExpr) { @@ -181,8 +154,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E, if (!fnDeclRef) return; - recordUnsupportedPartialApply(fnDeclRef); - auto fn = dyn_cast(fnDeclRef->getDecl()); if (!fn) return; @@ -203,11 +174,6 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E, /// This method is called in post-order over the AST to validate that /// methods are fully applied when they can't support partial application. void checkInvalidPartialApplication(Expr *E) { - if (auto DRE = dyn_cast(E)) { - recordUnsupportedPartialApply(DRE); - return; - } - if (auto AE = dyn_cast(E)) { Expr *fnExpr = AE->getFn()->getSemanticsProvidingExpr(); if (auto forceExpr = dyn_cast(fnExpr)) @@ -711,8 +677,8 @@ static void diagnoseImplicitSelfUseInClosure(TypeChecker &TC, const Expr *E, /// Return true if this is an implicit reference to self. static bool isImplicitSelfUse(Expr *E) { auto *DRE = dyn_cast(E); - return DRE && DRE->isImplicit() && DRE->getDecl()->hasName() && - DRE->getDecl()->getName().str() == "self" && + return DRE && DRE->isImplicit() && isa(DRE->getDecl()) && + cast(DRE->getDecl())->isSelfParameter() && // Metatype self captures don't extend the lifetime of an object. !DRE->getType()->is(); } @@ -805,63 +771,15 @@ static void diagnoseImplicitSelfUseInClosure(TypeChecker &TC, const Expr *E, const_cast(E)->walk(DiagnoseWalker(TC, isAlreadyInClosure)); } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Diagnose availability. -//===--------------------------------------------------------------------===// - -static void tryFixPrintWithAppendNewline(const ValueDecl *D, - const Expr *ParentExpr, - InFlightDiagnostic &Diag) { - if (!D || !ParentExpr) - return; - if (!D->getModuleContext()->isStdlibModule()) - return; - - DeclName Name = D->getFullName(); - if (Name.getBaseName().str() != "print") - return; - auto ArgNames = Name.getArgumentNames(); - if (ArgNames.size() != 2) - return; - if (ArgNames[1].str() != "appendNewline") - return; - - // Go through the expr to determine if second parameter is boolean literal. - auto *CE = dyn_cast_or_null(ParentExpr); - if (!CE) - return; - auto *TE = dyn_cast(CE->getArg()); - if (!TE) - return; - if (TE->getNumElements() != 2) - return; - auto *SCE = dyn_cast(TE->getElement(1)); - if (!SCE || !SCE->isImplicit()) - return; - auto *STE = dyn_cast(SCE->getArg()); - if (!STE || !STE->isImplicit()) - return; - if (STE->getNumElements() != 1) - return; - auto *BE = dyn_cast(STE->getElement(0)); - if (!BE) - return; - - SmallString<20> termStr = StringRef("terminator: \""); - if (BE->getValue()) - termStr += "\\n"; - termStr += "\""; - - SourceRange RangeToFix(TE->getElementNameLoc(1), BE->getEndLoc()); - Diag.fixItReplace(RangeToFix, termStr); -} +//===----------------------------------------------------------------------===// /// Emit a diagnostic for references to declarations that have been /// marked as unavailable, either through "unavailable" or "obsoleted=". bool TypeChecker::diagnoseExplicitUnavailability(const ValueDecl *D, SourceRange R, - const DeclContext *DC, - const Expr *ParentExpr) { + const DeclContext *DC) { auto *Attr = AvailableAttr::isUnavailable(D); if (!Attr) return false; @@ -899,9 +817,9 @@ bool TypeChecker::diagnoseExplicitUnavailability(const ValueDecl *D, diagnose(Loc, diag::availability_decl_unavailable, Name).highlight(R); } else { EncodedDiagnosticMessage EncodedMessage(Attr->Message); - tryFixPrintWithAppendNewline(D, ParentExpr, - diagnose(Loc, diag::availability_decl_unavailable_msg, Name, - EncodedMessage.Message).highlight(R)); + diagnose(Loc, diag::availability_decl_unavailable_msg, Name, + EncodedMessage.Message) + .highlight(R); } break; @@ -939,35 +857,6 @@ bool TypeChecker::diagnoseExplicitUnavailability(const ValueDecl *D, return true; } -/// Diagnose uses of unavailable declarations. Returns true if a diagnostic -/// was emitted. -static bool diagAvailability(TypeChecker &TC, const ValueDecl *D, - SourceRange R, const DeclContext *DC, - const Expr *ParentExpr = nullptr) { - if (!D) - return false; - - if (TC.diagnoseExplicitUnavailability(D, R, DC, ParentExpr)) - return true; - - // Diagnose for deprecation - if (const AvailableAttr *Attr = TypeChecker::getDeprecated(D)) { - TC.diagnoseDeprecated(R, DC, Attr, D->getFullName()); - } - - if (TC.getLangOpts().DisableAvailabilityChecking) { - return false; - } - - // Diagnose for potential unavailability - auto maybeUnavail = TC.checkDeclarationAvailability(D, R.Start, DC); - if (maybeUnavail.hasValue()) { - TC.diagnosePotentialUnavailability(D, R, DC, maybeUnavail.getValue()); - return true; - } - return false; -} - namespace { class AvailabilityWalker : public ASTWalker { /// Describes how the next member reference will be treated as we traverse @@ -988,13 +877,13 @@ class AvailabilityWalker : public ASTWalker { }; TypeChecker &TC; - const DeclContext *DC; + DeclContext *DC; const MemberAccessContext AccessContext; SmallVector ExprStack; public: AvailabilityWalker( - TypeChecker &TC, const DeclContext *DC, + TypeChecker &TC, DeclContext *DC, MemberAccessContext AccessContext = MemberAccessContext::Getter) : TC(TC), DC(DC), AccessContext(AccessContext) {} @@ -1008,21 +897,20 @@ class AvailabilityWalker : public ASTWalker { }; if (auto DR = dyn_cast(E)) - diagAvailability(TC, DR->getDecl(), DR->getSourceRange(), DC, - getParentForDeclRef()); + diagAvailability(DR->getDecl(), DR->getSourceRange()); if (auto MR = dyn_cast(E)) { walkMemberRef(MR); return skipChildren(); } if (auto OCDR = dyn_cast(E)) - diagAvailability(TC, OCDR->getDecl(), OCDR->getConstructorLoc(), DC); + diagAvailability(OCDR->getDecl(), OCDR->getConstructorLoc()); if (auto DMR = dyn_cast(E)) - diagAvailability(TC, DMR->getMember().getDecl(), DMR->getNameLoc(), DC); + diagAvailability(DMR->getMember().getDecl(), DMR->getNameLoc()); if (auto DS = dyn_cast(E)) - diagAvailability(TC, DS->getMember().getDecl(), DS->getSourceRange(), DC); + diagAvailability(DS->getMember().getDecl(), DS->getSourceRange()); if (auto S = dyn_cast(E)) { if (S->hasDecl()) - diagAvailability(TC, S->getDecl().getDecl(), S->getSourceRange(), DC); + diagAvailability(S->getDecl().getDecl(), S->getSourceRange()); } if (auto A = dyn_cast(E)) { walkAssignExpr(A); @@ -1044,6 +932,10 @@ class AvailabilityWalker : public ASTWalker { } private: + bool diagAvailability(const ValueDecl *D, SourceRange R); + bool diagnoseIncDecDeprecation(const ValueDecl *D, SourceRange R, + const AvailableAttr *Attr); + /// Walk an assignment expression, checking for availability. void walkAssignExpr(AssignExpr *E) const { // We take over recursive walking of assignment expressions in order to @@ -1076,13 +968,11 @@ class AvailabilityWalker : public ASTWalker { ValueDecl *D = E->getMember().getDecl(); // Diagnose for the member declaration itself. - if (diagAvailability(TC, D, E->getNameLoc(), DC)) { + if (diagAvailability(D, E->getNameLoc())) return; - } - if (TC.getLangOpts().DisableAvailabilityChecking) { + if (TC.getLangOpts().DisableAvailabilityChecking) return; - } if (auto *ASD = dyn_cast(D)) { // Diagnose for appropriate accessors, given the access context. @@ -1147,54 +1037,128 @@ class AvailabilityWalker : public ASTWalker { ForInout); } } +}; +} - const Expr *getParentForDeclRef() { - assert(isa(ExprStack.back())); - ArrayRef Stack = ExprStack; - Stack = Stack.drop_back(); - if (Stack.empty()) - return nullptr; +/// Diagnose uses of unavailable declarations. Returns true if a diagnostic +/// was emitted. +bool AvailabilityWalker::diagAvailability(const ValueDecl *D, SourceRange R) { + if (!D) + return false; + + if (TC.diagnoseExplicitUnavailability(D, R, DC)) + return true; - if (isa(Stack.back())) - Stack = Stack.drop_back(); - if (Stack.empty()) - return nullptr; - - return Stack.back(); + // Diagnose for deprecation + if (const AvailableAttr *Attr = TypeChecker::getDeprecated(D)) { + if (!diagnoseIncDecDeprecation(D, R, Attr)) + TC.diagnoseDeprecated(R, DC, Attr, D->getFullName()); } -}; + + if (TC.getLangOpts().DisableAvailabilityChecking) + return false; + + // Diagnose for potential unavailability + auto maybeUnavail = TC.checkDeclarationAvailability(D, R.Start, DC); + if (maybeUnavail.hasValue()) { + TC.diagnosePotentialUnavailability(D, R, DC, maybeUnavail.getValue()); + return true; + } + return false; } -/// Diagnose uses of unavailable declarations. -static void diagAvailability(TypeChecker &TC, const Expr *E, - const DeclContext *DC) { - AvailabilityWalker walker(TC, DC); - const_cast(E)->walk(walker); + +/// Return true if the specified type looks like an integer of floating point +/// type. +static bool isIntegerOrFloatingPointType(Type ty, DeclContext *DC, + TypeChecker &TC) { + auto integerType = + TC.getProtocol(SourceLoc(), + KnownProtocolKind::IntegerLiteralConvertible); + auto floatingType = + TC.getProtocol(SourceLoc(), + KnownProtocolKind::FloatLiteralConvertible); + if (!integerType || !floatingType) return false; + + return + TC.conformsToProtocol(ty, integerType, DC, + ConformanceCheckFlags::InExpression) || + TC.conformsToProtocol(ty, floatingType, DC, + ConformanceCheckFlags::InExpression); } -//===--------------------------------------------------------------------===// -// High-level entry points. -//===--------------------------------------------------------------------===// -/// \brief Emit diagnostics for syntactic restrictions on a given expression. -void swift::performSyntacticExprDiagnostics(TypeChecker &TC, const Expr *E, - const DeclContext *DC, - bool isExprStmt) { - diagSelfAssignment(TC, E); - diagSyntacticUseRestrictions(TC, E, DC, isExprStmt); - diagRecursivePropertyAccess(TC, E, DC); - diagnoseImplicitSelfUseInClosure(TC, E, DC); - diagAvailability(TC, E, DC); +/// If this is a call to a deprecated ++ / -- operator, try to diagnose it with +/// a fixit hint and return true. If not, or if we fail, return false. +bool AvailabilityWalker::diagnoseIncDecDeprecation(const ValueDecl *D, + SourceRange R, + const AvailableAttr *Attr) { + // We can only produce a fixit if we're talking about ++ or --. + bool isInc = D->getNameStr() == "++"; + if (!isInc && D->getNameStr() != "--") + return false; + + // We can only handle the simple cases of lvalue++ and ++lvalue. This is + // always modeled as: + // (postfix_unary_expr (declrefexpr ++), (inoutexpr (lvalue))) + // if not, bail out. + if (ExprStack.size() != 2 || + !isa(ExprStack[1]) || + !(isa(ExprStack[0]) || + isa(ExprStack[0]))) + return false; + + auto call = cast(ExprStack[0]); + + // If the expression type is integer or floating point, then we can rewrite it + // to "lvalue += 1". + std::string replacement; + if (isIntegerOrFloatingPointType(call->getType(), DC, TC)) + replacement = isInc ? " += 1" : " -= 1"; + else { + // Otherwise, it must be an index type. Rewrite to: + // "lvalue = lvalue.successor()". + auto &SM = TC.Context.SourceMgr; + auto CSR = Lexer::getCharSourceRangeFromSourceRange(SM, + call->getArg()->getSourceRange()); + replacement = " = " + SM.extractText(CSR).str(); + replacement += isInc ? ".successor()" : ".predecessor()"; + } + + if (!replacement.empty()) { + // If we emit a deprecation diagnostic, produce a fixit hint as well. + TC.diagnoseDeprecated(R, DC, Attr, D->getFullName(), + [&](InFlightDiagnostic &diag) { + if (isa(call)) { + // Prefix: remove the ++ or --. + diag.fixItRemove(call->getFn()->getSourceRange()); + diag.fixItInsertAfter(call->getArg()->getEndLoc(), replacement); + } else { + // Postfix: replace the ++ or --. + diag.fixItReplace(call->getFn()->getSourceRange(), replacement); + } + }); + + return true; + } + + + return false; } -void swift::performStmtDiagnostics(TypeChecker &TC, const Stmt *S) { - TC.checkUnsupportedProtocolType(const_cast(S)); + + +/// Diagnose uses of unavailable declarations. +static void diagAvailability(TypeChecker &TC, const Expr *E, + DeclContext *DC) { + AvailabilityWalker walker(TC, DC); + const_cast(E)->walk(walker); } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Per func/init diagnostics -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// namespace { class VarDeclUsageChecker : public ASTWalker { @@ -1229,13 +1193,22 @@ class VarDeclUsageChecker : public ASTWalker { public: VarDeclUsageChecker(TypeChecker &TC, AbstractFunctionDecl *AFD) : TC(TC) { // Track the parameters of the function. - for (auto P : AFD->getBodyParamPatterns()) - P->forEachVariable([&](VarDecl *VD) { - if (shouldTrackVarDecl(VD)) - VarDecls[VD] = 0; - }); + for (auto PL : AFD->getParameterLists()) + for (auto param : *PL) + if (shouldTrackVarDecl(param)) + VarDecls[param] = 0; + } - + + VarDeclUsageChecker(TypeChecker &TC, VarDecl *VD) : TC(TC) { + // Track a specific VarDecl + VarDecls[VD] = 0; + } + + void suppressDiagnostics() { + sawError = true; // set this flag so that no diagnostics will be emitted on delete. + } + // After we have scanned the entire region, diagnose variables that could be // declared with a narrower usage kind. ~VarDeclUsageChecker(); @@ -1258,6 +1231,10 @@ class VarDeclUsageChecker : public ASTWalker { } return sawMutation; } + + bool isVarDeclEverWritten(VarDecl *VD) { + return (VarDecls[VD] & RK_Written) != 0; + } bool shouldTrackVarDecl(VarDecl *VD) { // If the variable is implicit, ignore it. @@ -1515,17 +1492,7 @@ VarDeclUsageChecker::~VarDeclUsageChecker() { } // If this is a parameter explicitly marked 'var', remove it. - if (auto *param = dyn_cast(var)) - if (auto *pattern = param->getParamParentPattern()) - if (auto *vp = dyn_cast(pattern)) { - TC.diagnose(var->getLoc(), diag::variable_never_mutated, - var->getName(), /*param*/1) - .fixItRemove(vp->getLoc()); - continue; - } - unsigned varKind = isa(var); - // FIXME: fixit when we can find a pattern binding. if (FixItLoc.isInvalid()) TC.diagnose(var->getLoc(), diag::variable_never_mutated, var->getName(), varKind); @@ -1600,7 +1567,7 @@ void VarDeclUsageChecker::markStoredOrInOutExpr(Expr *E, unsigned Flags) { // are mutating the base expression. We also need to visit the index // expressions as loads though. if (auto *SE = dyn_cast(E)) { - // The index of the subscript is evaluted as an rvalue. + // The index of the subscript is evaluated as an rvalue. SE->getIndex()->walk(*this); if (SE->hasDecl()) markBaseOfAbstractStorageDeclStore(SE->getBase(), SE->getDecl()); @@ -1723,12 +1690,166 @@ void swift::performAbstractFuncDeclDiagnostics(TypeChecker &TC, AFD->getBody()->walk(VarDeclUsageChecker(TC, AFD)); } +/// Diagnose C style for loops. + +static Expr *endConditionValueForConvertingCStyleForLoop(const ForStmt *FS, VarDecl *loopVar) { + auto *Cond = FS->getCond().getPtrOrNull(); + if (!Cond) + return nullptr; + auto callExpr = dyn_cast(Cond); + if (!callExpr) + return nullptr; + auto dotSyntaxExpr = dyn_cast(callExpr->getFn()); + if (!dotSyntaxExpr) + return nullptr; + auto binaryExpr = dyn_cast(dotSyntaxExpr->getBase()); + if (!binaryExpr) + return nullptr; + auto binaryFuncExpr = dyn_cast(binaryExpr->getFn()); + if (!binaryFuncExpr) + return nullptr; + + // Verify that the condition is a simple != or < comparison to the loop variable. + auto comparisonOpName = binaryFuncExpr->getDecl()->getNameStr(); + if (comparisonOpName != "!=" && comparisonOpName != "<") + return nullptr; + auto args = binaryExpr->getArg()->getElements(); + auto loadExpr = dyn_cast(args[0]); + if (!loadExpr) + return nullptr; + auto declRefExpr = dyn_cast(loadExpr->getSubExpr()); + if (!declRefExpr) + return nullptr; + if (declRefExpr->getDecl() != loopVar) + return nullptr; + return args[1]; +} + +static bool unaryIncrementForConvertingCStyleForLoop(const ForStmt *FS, VarDecl *loopVar) { + auto *Increment = FS->getIncrement().getPtrOrNull(); + if (!Increment) + return false; + ApplyExpr *unaryExpr = dyn_cast(Increment); + if (!unaryExpr) + unaryExpr = dyn_cast(Increment); + if (!unaryExpr) + return false; + auto inoutExpr = dyn_cast(unaryExpr->getArg()); + if (!inoutExpr) + return false; + auto incrementDeclRefExpr = dyn_cast(inoutExpr->getSubExpr()); + if (!incrementDeclRefExpr) + return false; + auto unaryFuncExpr = dyn_cast(unaryExpr->getFn()); + if (!unaryFuncExpr) + return false; + if (unaryFuncExpr->getDecl()->getNameStr() != "++") + return false; + return incrementDeclRefExpr->getDecl() == loopVar; +} + +static bool plusEqualOneIncrementForConvertingCStyleForLoop(TypeChecker &TC, const ForStmt *FS, VarDecl *loopVar) { + auto *Increment = FS->getIncrement().getPtrOrNull(); + if (!Increment) + return false; + ApplyExpr *binaryExpr = dyn_cast(Increment); + if (!binaryExpr) + return false; + auto binaryFuncExpr = dyn_cast(binaryExpr->getFn()); + if (!binaryFuncExpr) + return false; + if (binaryFuncExpr->getDecl()->getNameStr() != "+=") + return false; + auto argTupleExpr = dyn_cast(binaryExpr->getArg()); + if (!argTupleExpr) + return false; + auto addOneConstExpr = argTupleExpr->getElement(1); + + // Rather than unwrapping expressions all the way down implicit constructors, etc, just check that the + // source text for the += argument is "1". + SourceLoc constEndLoc = Lexer::getLocForEndOfToken(TC.Context.SourceMgr, addOneConstExpr->getEndLoc()); + auto range = CharSourceRange(TC.Context.SourceMgr, addOneConstExpr->getStartLoc(), constEndLoc); + if (range.str() != "1") + return false; + + auto inoutExpr = dyn_cast(argTupleExpr->getElement(0)); + if (!inoutExpr) + return false; + auto declRefExpr = dyn_cast(inoutExpr->getSubExpr()); + if (!declRefExpr) + return false; + return declRefExpr->getDecl() == loopVar; +} + +static void checkCStyleForLoop(TypeChecker &TC, const ForStmt *FS) { + // If we're missing semi-colons we'll already be erroring out, and this may not even have been intended as C-style. + if (FS->getFirstSemicolonLoc().isInvalid() || FS->getSecondSemicolonLoc().isInvalid()) + return; + + InFlightDiagnostic diagnostic = TC.diagnose(FS->getStartLoc(), diag::deprecated_c_style_for_stmt); + + // Try to construct a fix it using for-each: + + // Verify that there is only one loop variable, and it is declared here. + auto initializers = FS->getInitializerVarDecls(); + PatternBindingDecl *loopVarDecl = initializers.size() == 2 ? dyn_cast(initializers[0]) : nullptr; + if (!loopVarDecl || loopVarDecl->getNumPatternEntries() != 1) + return; + + VarDecl *loopVar = dyn_cast(initializers[1]); + Expr *startValue = loopVarDecl->getInit(0); + Expr *endValue = endConditionValueForConvertingCStyleForLoop(FS, loopVar); + bool strideByOne = unaryIncrementForConvertingCStyleForLoop(FS, loopVar) || + plusEqualOneIncrementForConvertingCStyleForLoop(TC, FS, loopVar); + + if (!loopVar || !startValue || !endValue || !strideByOne) + return; + + // Verify that the loop variable is invariant inside the body. + VarDeclUsageChecker checker(TC, loopVar); + checker.suppressDiagnostics(); + FS->getBody()->walk(checker); + + if (checker.isVarDeclEverWritten(loopVar)) { + diagnostic.flush(); + TC.diagnose(FS->getStartLoc(), diag::cant_fix_c_style_for_stmt); + return; + } + + SourceLoc loopPatternEnd = Lexer::getLocForEndOfToken(TC.Context.SourceMgr, loopVarDecl->getPattern(0)->getEndLoc()); + SourceLoc endOfIncrementLoc = Lexer::getLocForEndOfToken(TC.Context.SourceMgr, FS->getIncrement().getPtrOrNull()->getEndLoc()); + + diagnostic + .fixItReplaceChars(loopPatternEnd, startValue->getStartLoc(), " in ") + .fixItReplaceChars(FS->getFirstSemicolonLoc(), endValue->getStartLoc(), " ..< ") + .fixItRemoveChars(FS->getSecondSemicolonLoc(), endOfIncrementLoc); +} + +//===----------------------------------------------------------------------===// +// High-level entry points. +//===----------------------------------------------------------------------===// +/// \brief Emit diagnostics for syntactic restrictions on a given expression. +void swift::performSyntacticExprDiagnostics(TypeChecker &TC, const Expr *E, + const DeclContext *DC, + bool isExprStmt) { + diagSelfAssignment(TC, E); + diagSyntacticUseRestrictions(TC, E, DC, isExprStmt); + diagRecursivePropertyAccess(TC, E, DC); + diagnoseImplicitSelfUseInClosure(TC, E, DC); + diagAvailability(TC, E, const_cast(DC)); +} +void swift::performStmtDiagnostics(TypeChecker &TC, const Stmt *S) { + TC.checkUnsupportedProtocolType(const_cast(S)); + + if (auto forStmt = dyn_cast(S)) + checkCStyleForLoop(TC, forStmt); +} -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Utility functions -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// void swift::fixItAccessibility(InFlightDiagnostic &diag, ValueDecl *VD, Accessibility desiredAccess, bool isForSetter) { @@ -1924,22 +2045,13 @@ static Optional omitNeedlessWords(AbstractFunctionDecl *afd) { // String'ify the parameter types. SmallVector paramTypes; - Type functionType = afd->getInterfaceType(); - Type argumentType; - for (unsigned i = 0, n = afd->getNaturalArgumentCount()-1; i != n; ++i) - functionType = functionType->getAs()->getResult(); - argumentType = functionType->getAs()->getInput(); - if (auto tupleTy = argumentType->getAs()) { - if (tupleTy->getNumElements() == argNameStrs.size()) { - for (const auto &elt : tupleTy->getElements()) - paramTypes.push_back(getTypeNameForOmission(elt.getType()) - .withDefaultArgument(elt.hasDefaultArg())); - } - } - - if (argNameStrs.size() == 1 && paramTypes.empty()) - paramTypes.push_back(getTypeNameForOmission(argumentType)); + // Always look at the parameters in the last parameter list. + for (auto param : *afd->getParameterLists().back()) { + paramTypes.push_back(getTypeNameForOmission(param->getType()) + .withDefaultArgument(param->isDefaultArgument())); + } + // Handle contextual type, result type, and returnsSelf. Type contextType = afd->getDeclContext()->getDeclaredInterfaceType(); Type resultType; @@ -1955,18 +2067,9 @@ static Optional omitNeedlessWords(AbstractFunctionDecl *afd) { // Figure out the first parameter name. StringRef firstParamName; - unsigned skipBodyPatterns = afd->getImplicitSelfDecl() ? 1 : 0; - auto bodyPattern = afd->getBodyParamPatterns()[skipBodyPatterns]; - if (auto tuplePattern = dyn_cast(bodyPattern)) { - if (tuplePattern->getNumElements() > 0) { - auto firstParam = tuplePattern->getElement(0).getPattern(); - if (auto named = dyn_cast( - firstParam->getSemanticsProvidingPattern())) { - if (!named->getBodyName().empty()) - firstParamName = named->getBodyName().str(); - } - } - } + auto params = afd->getParameterList(afd->getImplicitSelfDecl() ? 1 : 0); + if (params->size() != 0 && !params->get(0)->getName().empty()) + firstParamName = params->get(0)->getName().str(); // Find the set of property names. const InheritedNameSet *allPropertyNames = nullptr; @@ -2079,33 +2182,6 @@ void TypeChecker::checkOmitNeedlessWords(VarDecl *var) { .fixItReplace(var->getLoc(), newName->str()); } -/// Determine the "fake" default argument provided by the given expression. -static Optional getDefaultArgForExpr(Expr *expr) { - // Empty array literals, []. - if (auto arrayExpr = dyn_cast(expr)) { - if (arrayExpr->getElements().empty()) - return StringRef("[]"); - - return None; - } - - // nil. - if (auto call = dyn_cast(expr)) { - if (auto ctorRefCall = dyn_cast(call->getFn())) { - if (auto ctorRef = dyn_cast(ctorRefCall->getFn())) { - if (auto ctor = dyn_cast(ctorRef->getDecl())) { - if (ctor->getFullName().getArgumentNames().size() == 1 && - ctor->getFullName().getArgumentNames()[0] - == ctor->getASTContext().Id_nilLiteral) - return StringRef("nil"); - } - } - } - } - - return None; -} - namespace { struct CallEdit { enum { @@ -2124,12 +2200,10 @@ namespace { /// Find the source ranges of extraneous default arguments within a /// call to the given function. -static bool hasExtraneousDefaultArguments( - AbstractFunctionDecl *afd, - Expr *arg, - DeclName name, - SmallVectorImpl &ranges, - SmallVectorImpl &removedArgs) { +static bool hasExtraneousDefaultArguments(AbstractFunctionDecl *afd, + Expr *arg, DeclName name, + SmallVectorImpl &ranges, + SmallVectorImpl &removedArgs) { if (!afd->getClangDecl()) return false; @@ -2141,133 +2215,124 @@ static bool hasExtraneousDefaultArguments( TupleExpr *argTuple = dyn_cast(arg); ParenExpr *argParen = dyn_cast(arg); - - ArrayRef bodyPatterns = afd->getBodyParamPatterns(); - - // Skip over the implicit 'self'. - if (afd->getImplicitSelfDecl()) { - bodyPatterns = bodyPatterns.slice(1); - } - + ASTContext &ctx = afd->getASTContext(); - Pattern *bodyPattern = bodyPatterns[0]; - if (auto *tuple = dyn_cast(bodyPattern)) { - Optional firstRemoved; - Optional lastRemoved; - unsigned numElementsInParens; - if (argTuple) { - numElementsInParens = (argTuple->getNumElements() - - argTuple->hasTrailingClosure()); - } else if (argParen) { - numElementsInParens = 1 - argParen->hasTrailingClosure(); - } else { - numElementsInParens = 0; - } - - for (unsigned i = 0; i != numElementsInParens; ++i) { - auto &elt = tuple->getElements()[i]; - if (elt.getDefaultArgKind() == DefaultArgumentKind::None) - continue; + // Skip over the implicit 'self'. + auto *bodyParams = afd->getParameterList(afd->getImplicitSelfDecl()?1:0); - auto defaultArg - = elt.getPattern()->getType()->getInferredDefaultArgString(); + Optional firstRemoved; + Optional lastRemoved; + unsigned numElementsInParens; + if (argTuple) { + numElementsInParens = (argTuple->getNumElements() - + argTuple->hasTrailingClosure()); + } else if (argParen) { + numElementsInParens = 1 - argParen->hasTrailingClosure(); + } else { + numElementsInParens = 0; + } - // Never consider removing the first argument for a "set" method - // with an unnamed first argument. - if (i == 0 && - !name.getBaseName().empty() && - camel_case::getFirstWord(name.getBaseName().str()) == "set" && - name.getArgumentNames().size() > 0 && - name.getArgumentNames()[0].empty()) - continue; + for (unsigned i = 0; i != numElementsInParens; ++i) { + auto param = bodyParams->get(i); + if (!param->isDefaultArgument()) + continue; - SourceRange removalRange; - if (argTuple && i < argTuple->getNumElements()) { - // Check whether we have a default argument. - auto exprArg = getDefaultArgForExpr(argTuple->getElement(i)); - if (!exprArg || defaultArg != *exprArg) - continue; + auto defaultArg = param->getDefaultArgumentKind(); - // Figure out where to start removing this argument. - if (i == 0) { - // Start removing right after the opening parenthesis. - removalRange.Start = argTuple->getLParenLoc(); - } else { - // Start removing right after the preceding argument, so we - // consume the comma as well. - removalRange.Start = argTuple->getElement(i-1)->getEndLoc(); - } + // Never consider removing the first argument for a "set" method + // with an unnamed first argument. + if (i == 0 && + !name.getBaseName().empty() && + camel_case::getFirstWord(name.getBaseName().str()) == "set" && + name.getArgumentNames().size() > 0 && + name.getArgumentNames()[0].empty()) + continue; - // Adjust to the end of the starting token. - removalRange.Start - = Lexer::getLocForEndOfToken(ctx.SourceMgr, removalRange.Start); - - // Figure out where to finish removing this element. - if (i == 0 && i < numElementsInParens - 1) { - // We're the first of several arguments; consume the - // following comma as well. - removalRange.End = argTuple->getElementNameLoc(i+1); - if (removalRange.End.isInvalid()) - removalRange.End = argTuple->getElement(i+1)->getStartLoc(); - } else if (i < numElementsInParens - 1) { - // We're in the middle; consume through the end of this - // element. - removalRange.End - = Lexer::getLocForEndOfToken(ctx.SourceMgr, - argTuple->getElement(i)->getEndLoc()); - } else { - // We're at the end; consume up to the closing parentheses. - removalRange.End = argTuple->getRParenLoc(); - } - } else if (argParen) { - // Check whether we have a default argument. - auto exprArg = getDefaultArgForExpr(argParen->getSubExpr()); - if (!exprArg || defaultArg != *exprArg) - continue; + SourceRange removalRange; + if (argTuple && i < argTuple->getNumElements()) { + // Check whether the supplied argument is the same as the + // default argument. + if (defaultArg != inferDefaultArgumentKind(argTuple->getElement(i))) + continue; - removalRange = SourceRange(argParen->getSubExpr()->getStartLoc(), - argParen->getRParenLoc()); + // Figure out where to start removing this argument. + if (i == 0) { + // Start removing right after the opening parenthesis. + removalRange.Start = argTuple->getLParenLoc(); } else { - continue; + // Start removing right after the preceding argument, so we + // consume the comma as well. + removalRange.Start = argTuple->getElement(i-1)->getEndLoc(); } - if (removalRange.isInvalid()) + // Adjust to the end of the starting token. + removalRange.Start + = Lexer::getLocForEndOfToken(ctx.SourceMgr, removalRange.Start); + + // Figure out where to finish removing this element. + if (i == 0 && i < numElementsInParens - 1) { + // We're the first of several arguments; consume the + // following comma as well. + removalRange.End = argTuple->getElementNameLoc(i+1); + if (removalRange.End.isInvalid()) + removalRange.End = argTuple->getElement(i+1)->getStartLoc(); + } else if (i < numElementsInParens - 1) { + // We're in the middle; consume through the end of this + // element. + removalRange.End + = Lexer::getLocForEndOfToken(ctx.SourceMgr, + argTuple->getElement(i)->getEndLoc()); + } else { + // We're at the end; consume up to the closing parentheses. + removalRange.End = argTuple->getRParenLoc(); + } + } else if (argParen) { + // Check whether we have a default argument. + if (defaultArg != inferDefaultArgumentKind(argParen->getSubExpr())) continue; - // Note that we're removing this argument. - removedArgs.push_back(i); + removalRange = SourceRange(argParen->getSubExpr()->getStartLoc(), + argParen->getRParenLoc()); + } else { + continue; + } - // If we hadn't removed anything before, this is the first - // removal. - if (!firstRemoved) { - ranges.push_back(removalRange); - firstRemoved = i; - lastRemoved = i; - continue; - } + if (removalRange.isInvalid()) + continue; - // If the previous removal range was the previous argument, - // combine the ranges. - if (*lastRemoved == i - 1) { - ranges.back().End = removalRange.End; - lastRemoved = i; - continue; - } + // Note that we're removing this argument. + removedArgs.push_back(i); - // Otherwise, add this new removal range. + // If we hadn't removed anything before, this is the first + // removal. + if (!firstRemoved) { ranges.push_back(removalRange); + firstRemoved = i; lastRemoved = i; + continue; } - // If there is a single removal range that covers everything but - // the trailing closure at the end, also zap the parentheses. - if (ranges.size() == 1 && - *firstRemoved == 0 && *lastRemoved == tuple->getNumElements() - 2 && - argTuple && argTuple->hasTrailingClosure()) { - ranges.front().Start = argTuple->getLParenLoc(); - ranges.front().End - = Lexer::getLocForEndOfToken(ctx.SourceMgr, argTuple->getRParenLoc()); + // If the previous removal range was the previous argument, + // combine the ranges. + if (*lastRemoved == i - 1) { + ranges.back().End = removalRange.End; + lastRemoved = i; + continue; } + + // Otherwise, add this new removal range. + ranges.push_back(removalRange); + lastRemoved = i; + } + + // If there is a single removal range that covers everything but + // the trailing closure at the end, also zap the parentheses. + if (ranges.size() == 1 && + *firstRemoved == 0 && *lastRemoved == bodyParams->size() - 2 && + argTuple && argTuple->hasTrailingClosure()) { + ranges.front().Start = argTuple->getLParenLoc(); + ranges.front().End + = Lexer::getLocForEndOfToken(ctx.SourceMgr, argTuple->getRParenLoc()); } return !ranges.empty(); diff --git a/lib/Sema/MiscDiagnostics.h b/lib/Sema/MiscDiagnostics.h index de5d97c100235..8fe263316acaa 100644 --- a/lib/Sema/MiscDiagnostics.h +++ b/lib/Sema/MiscDiagnostics.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/NameBinding.cpp b/lib/Sema/NameBinding.cpp index 86d6aba94b504..9d0547c824bab 100644 --- a/lib/Sema/NameBinding.cpp +++ b/lib/Sema/NameBinding.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/OverloadChoice.cpp b/lib/Sema/OverloadChoice.cpp index f647b09fbecd6..ca4efc805098f 100644 --- a/lib/Sema/OverloadChoice.cpp +++ b/lib/Sema/OverloadChoice.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/OverloadChoice.h b/lib/Sema/OverloadChoice.h index 7d0afca091f16..53d19c03be889 100644 --- a/lib/Sema/OverloadChoice.h +++ b/lib/Sema/OverloadChoice.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -208,7 +208,7 @@ class OverloadChoice { } } - /// \brief Retrieve the declaraton that corresponds to this overload choice. + /// \brief Retrieve the declaration that corresponds to this overload choice. ValueDecl *getDecl() const { assert(isDecl() && "Not a declaration"); return reinterpret_cast(DeclOrKind & ~(uintptr_t)0x03); diff --git a/lib/Sema/PlaygroundTransform.cpp b/lib/Sema/PlaygroundTransform.cpp index 319db048f173b..56f387352376a 100644 --- a/lib/Sema/PlaygroundTransform.cpp +++ b/lib/Sema/PlaygroundTransform.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -637,8 +637,7 @@ class Instrumenter { EI += 2; } } - } - else { + } else { if (E->getType()->getCanonicalType() != Context.TheEmptyTupleType) { std::pair PV = @@ -897,8 +896,7 @@ class Instrumenter { dyn_cast(InitExpr->getType().getPointer())) { MaybeLoadInitExpr = new (Context) LoadExpr (InitExpr, LVT->getObjectType()); - } - else { + } else { MaybeLoadInitExpr = InitExpr; } diff --git a/lib/Sema/SourceLoader.cpp b/lib/Sema/SourceLoader.cpp index 1445c53df3cea..d558629008a69 100644 --- a/lib/Sema/SourceLoader.cpp +++ b/lib/Sema/SourceLoader.cpp @@ -1,8 +1,8 @@ -//===--- SourceLoader.cpp - Import .swift files as modules ------*- c++ -*-===// +//===--- SourceLoader.cpp - Import .swift files as modules ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index c7136e0302201..d2c0976e6f0d3 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -76,6 +76,7 @@ class AttributeEarlyChecker : public AttributeVisitor { IGNORED_ATTR(UIApplicationMain) IGNORED_ATTR(UnsafeNoObjCTaggedPointer) IGNORED_ATTR(WarnUnusedResult) + IGNORED_ATTR(MigrationId) #undef IGNORED_ATTR void visitAlignmentAttr(AlignmentAttr *attr) { @@ -95,7 +96,7 @@ class AttributeEarlyChecker : public AttributeVisitor { void visitTransparentAttr(TransparentAttr *attr); void visitMutationAttr(DeclAttribute *attr); void visitMutatingAttr(MutatingAttr *attr) { visitMutationAttr(attr); } - void visitNonMutatingAttr(NonMutatingAttr *attr) { visitMutationAttr(attr); } + void visitNonMutatingAttr(NonMutatingAttr *attr) { visitMutationAttr(attr); } void visitDynamicAttr(DynamicAttr *attr); void visitOwnershipAttr(OwnershipAttr *attr) { @@ -426,7 +427,7 @@ void AttributeEarlyChecker::visitLazyAttr(LazyAttr *attr) { if (!VD->hasStorage()) return diagnoseAndRemoveAttr(attr, diag::lazy_not_on_computed); - // lazy is not allowed on a lazily initiailized global variable or on a + // lazy is not allowed on a lazily initialized global variable or on a // static property (which is already lazily initialized). if (VD->isStatic() || (varDC->isModuleScopeContext() && @@ -645,6 +646,7 @@ class AttributeChecker : public AttributeVisitor { IGNORED_ATTR(SILStored) IGNORED_ATTR(Testable) IGNORED_ATTR(WarnUnqualifiedAccess) + IGNORED_ATTR(MigrationId) #undef IGNORED_ATTR void visitAvailableAttr(AvailableAttr *attr); @@ -683,8 +685,8 @@ class AttributeChecker : public AttributeVisitor { static bool checkObjectOrOptionalObjectType(TypeChecker &TC, Decl *D, - const Pattern *argPattern) { - Type ty = argPattern->getType(); + ParamDecl *param) { + Type ty = param->getType(); if (auto unwrapped = ty->getAnyOptionalObjectType()) ty = unwrapped; @@ -692,8 +694,8 @@ static bool checkObjectOrOptionalObjectType(TypeChecker &TC, Decl *D, // @objc class types are okay. if (!classDecl->isObjC()) { TC.diagnose(D, diag::ibaction_nonobjc_class_argument, - argPattern->getType()) - .highlight(argPattern->getSourceRange()); + param->getType()) + .highlight(param->getSourceRange()); return true; } } else if (ty->isObjCExistentialType()) { @@ -702,8 +704,8 @@ static bool checkObjectOrOptionalObjectType(TypeChecker &TC, Decl *D, } else { // No other types are permitted. TC.diagnose(D, diag::ibaction_nonobject_argument, - argPattern->getSemanticsProvidingPattern()->getType()) - .highlight(argPattern->getSourceRange()); + param->getType()) + .highlight(param->getSourceRange()); return true; } @@ -733,64 +735,50 @@ void AttributeChecker::visitIBActionAttr(IBActionAttr *attr) { return; } - auto Arguments = FD->getBodyParamPatterns()[1]; - auto ArgTuple = dyn_cast(Arguments); - - auto checkSingleArgument = [this](const Pattern *argPattern) -> bool { + auto paramList = FD->getParameterList(1); + bool relaxedIBActionUsedOnOSX = false; + bool Valid = true; + switch (paramList->size()) { + case 0: + // (iOS only) No arguments. + if (!isRelaxedIBAction(TC)) { + relaxedIBActionUsedOnOSX = true; + break; + } + break; + case 1: // One argument. May be a scalar on iOS/watchOS (because of WatchKit). if (isRelaxedIBAction(TC)) { // Do a rough check to allow any ObjC-representable struct or enum type // on iOS. - Type ty = argPattern->getType(); + Type ty = paramList->get(0)->getType(); if (auto nominal = ty->getAnyNominal()) if (isa(nominal) || isa(nominal)) if (nominal->classifyAsOptionalType() == OTK_None) if (TC.isTriviallyRepresentableInObjC(cast(D), ty)) - return false; + break; // Looks ok. } - return checkObjectOrOptionalObjectType(TC, D, argPattern); - }; - - bool relaxedIBActionUsedOnOSX = false; - bool Valid = true; - if (ArgTuple) { - auto fields = ArgTuple->getElements(); - switch (ArgTuple->getNumElements()) { - case 0: - // (iOS only) No arguments. - if (!isRelaxedIBAction(TC)) { - relaxedIBActionUsedOnOSX = true; - break; - } - break; - case 1: - // One argument, see above. - if (checkSingleArgument(fields[0].getPattern())) - Valid = false; - break; - case 2: - // (iOS/watchOS only) Two arguments, the second of which is a UIEvent. - // We don't currently enforce the UIEvent part. - if (!isRelaxedIBAction(TC)) { - relaxedIBActionUsedOnOSX = true; - break; - } - if (checkObjectOrOptionalObjectType(TC, D, fields[0].getPattern())) - Valid = false; - if (checkObjectOrOptionalObjectType(TC, D, fields[1].getPattern())) - Valid = false; - break; - default: - // No platform allows an action signature with more than two arguments. - TC.diagnose(D, diag::invalid_ibaction_argument_count, - isRelaxedIBAction(TC)); + if (checkObjectOrOptionalObjectType(TC, D, paramList->get(0))) Valid = false; + break; + case 2: + // (iOS/watchOS only) Two arguments, the second of which is a UIEvent. + // We don't currently enforce the UIEvent part. + if (!isRelaxedIBAction(TC)) { + relaxedIBActionUsedOnOSX = true; break; } - } else { - // One argument without a name. - if (checkSingleArgument(Arguments)) + if (checkObjectOrOptionalObjectType(TC, D, paramList->get(0))) + Valid = false; + if (checkObjectOrOptionalObjectType(TC, D, paramList->get(1))) Valid = false; + break; + default: + // No platform allows an action signature with more than two arguments. + TC.diagnose(D, diag::invalid_ibaction_argument_count, + isRelaxedIBAction(TC)); + Valid = false; + break; } if (relaxedIBActionUsedOnOSX) { @@ -1229,9 +1217,10 @@ void AttributeChecker::visitRethrowsAttr(RethrowsAttr *attr) { // 'rethrows' only applies to functions that take throwing functions // as parameters. auto fn = cast(D); - for (auto param : fn->getBodyParamPatterns()) { - if (hasThrowingFunctionParameter(param->getType()->getCanonicalType())) - return; + for (auto paramList : fn->getParameterLists()) { + for (auto param : *paramList) + if (hasThrowingFunctionParameter(param->getType()->getCanonicalType())) + return; } TC.diagnose(attr->getLocation(), diag::rethrows_without_throwing_parameter); diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 0175181bf3ddc..a77f619286945 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -46,9 +46,9 @@ using namespace swift; using namespace constraints; -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Type variable implementation. -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #pragma mark Type variable implementation void TypeVariableType::Implementation::print(llvm::raw_ostream &OS) { @@ -185,7 +185,7 @@ bool constraints::computeTupleShuffle(ArrayRef fromTuple, // If there aren't any more inputs, we can use a default argument. if (fromNext == fromLast) { - if (elt2.hasInit()) { + if (elt2.hasDefaultArg()) { sources[i] = TupleShuffleExpr::DefaultInitialize; continue; } @@ -239,9 +239,9 @@ bool constraints::hasTrailingClosure(const ConstraintLocatorBuilder &locator) { return false; } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // High-level entry points. -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// static unsigned getNumArgs(ValueDecl *value) { if (!isa(value)) return ~0U; @@ -281,6 +281,153 @@ static bool matchesDeclRefKind(ValueDecl *value, DeclRefKind refKind) { llvm_unreachable("bad declaration reference kind"); } +static bool containsDeclRefKind(LookupResult &lookupResult, + DeclRefKind refKind) { + for (auto candidate : lookupResult) { + ValueDecl *D = candidate.Decl; + if (!D || !D->hasType()) + continue; + if (matchesDeclRefKind(D, refKind)) + return true; + } + return false; +} + +/// Emit a diagnostic with a fixit hint for an invalid binary operator, showing +/// how to split it according to splitCandidate. +static void diagnoseBinOpSplit(UnresolvedDeclRefExpr *UDRE, + std::pair splitCandidate, + Diag diagID, + TypeChecker &TC) { + + unsigned splitLoc = splitCandidate.first; + bool isBinOpFirst = splitCandidate.second; + StringRef nameStr = UDRE->getName().str(); + auto startStr = nameStr.substr(0, splitLoc); + auto endStr = nameStr.drop_front(splitLoc); + + // One valid split found, it is almost certainly the right answer. + auto diag = TC.diagnose(UDRE->getLoc(), diagID, + TC.Context.getIdentifier(startStr), + TC.Context.getIdentifier(endStr), isBinOpFirst); + // Highlight the whole operator. + diag.highlight(UDRE->getLoc()); + // Insert whitespace on the left if the binop is at the start, or to the + // right if it is end. + if (isBinOpFirst) + diag.fixItInsert(UDRE->getLoc(), " "); + else + diag.fixItInsertAfter(UDRE->getLoc(), " "); + + // Insert a space between the operators. + diag.fixItInsert(UDRE->getLoc().getAdvancedLoc(splitLoc), " "); +} + +/// If we failed lookup of a binary operator, check to see it to see if +/// it is a binary operator juxtaposed with a unary operator (x*-4) that +/// needs whitespace. If so, emit specific diagnostics for it and return true, +/// otherwise return false. +static bool diagnoseOperatorJuxtaposition(UnresolvedDeclRefExpr *UDRE, + DeclContext *DC, + TypeChecker &TC) { + Identifier name = UDRE->getName(); + StringRef nameStr = name.str(); + if (!name.isOperator() || nameStr.size() < 2) + return false; + + bool isBinOp = UDRE->getRefKind() == DeclRefKind::BinaryOperator; + + // If this is a binary operator, relex the token, to decide whether it has + // whitespace around it or not. If it does "x +++ y", then it isn't likely to + // be a case where a space was forgotten. + if (isBinOp) { + auto tok = Lexer::getTokenAtLocation(TC.Context.SourceMgr, UDRE->getLoc()); + if (tok.getKind() != tok::oper_binary_unspaced) + return false; + } + + // Okay, we have a failed lookup of a multicharacter operator. Check to see if + // lookup succeeds if part is split off, and record the matches found. + // + // In the case of a binary operator, the bool indicated is false if the + // first half of the split is the unary operator (x!*4) or true if it is the + // binary operator (x*+4). + std::vector> WorkableSplits; + + // Check all the potential splits. + for (unsigned splitLoc = 1, e = nameStr.size(); splitLoc != e; ++splitLoc) { + // For it to be a valid split, the start and end section must be valid + // operators, splitting a unicode code point isn't kosher. + auto startStr = nameStr.substr(0, splitLoc); + auto endStr = nameStr.drop_front(splitLoc); + if (!Lexer::isOperator(startStr) || !Lexer::isOperator(endStr)) + continue; + + auto startName = TC.Context.getIdentifier(startStr); + auto endName = TC.Context.getIdentifier(endStr); + + // Perform name lookup for the first and second pieces. If either fail to + // be found, then it isn't a valid split. + NameLookupOptions LookupOptions = defaultUnqualifiedLookupOptions; + if (isa(DC)) + LookupOptions |= NameLookupFlags::KnownPrivate; + auto startLookup = TC.lookupUnqualified(DC, startName, UDRE->getLoc(), + LookupOptions); + if (!startLookup) continue; + auto endLookup = TC.lookupUnqualified(DC, endName, UDRE->getLoc(), + LookupOptions); + if (!endLookup) continue; + + // If the overall operator is a binary one, then we're looking at + // juxtaposed binary and unary operators. + if (isBinOp) { + // Look to see if the candidates found could possibly match. + if (containsDeclRefKind(startLookup, DeclRefKind::PostfixOperator) && + containsDeclRefKind(endLookup, DeclRefKind::BinaryOperator)) + WorkableSplits.push_back({ splitLoc, false }); + + if (containsDeclRefKind(startLookup, DeclRefKind::BinaryOperator) && + containsDeclRefKind(endLookup, DeclRefKind::PrefixOperator)) + WorkableSplits.push_back({ splitLoc, true }); + } else { + // Otherwise, it is two of the same kind, e.g. "!!x" or "!~x". + if (containsDeclRefKind(startLookup, UDRE->getRefKind()) && + containsDeclRefKind(endLookup, UDRE->getRefKind())) + WorkableSplits.push_back({ splitLoc, false }); + } + } + + switch (WorkableSplits.size()) { + case 0: + // No splits found, can't produce this diagnostic. + return false; + case 1: + // One candidate: produce an error with a fixit on it. + if (isBinOp) + diagnoseBinOpSplit(UDRE, WorkableSplits[0], + diag::unspaced_binary_operator_fixit, TC); + else + TC.diagnose(UDRE->getLoc().getAdvancedLoc(WorkableSplits[0].first), + diag::unspaced_unary_operator); + return true; + + default: + // Otherwise, we have to produce a series of notes listing the various + // options. + TC.diagnose(UDRE->getLoc(), isBinOp ? diag::unspaced_binary_operator : + diag::unspaced_unary_operator) + .highlight(UDRE->getLoc()); + + if (isBinOp) { + for (auto candidateSplit : WorkableSplits) + diagnoseBinOpSplit(UDRE, candidateSplit, + diag::unspaced_binary_operators_candidate, TC); + } + return true; + } +} + + /// Bind an UnresolvedDeclRefExpr by performing name lookup and /// returning the resultant expression. Context is the DeclContext used /// for the lookup. @@ -297,8 +444,14 @@ resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *DC) { auto Lookup = lookupUnqualified(DC, Name, Loc, LookupOptions); if (!Lookup) { - diagnose(Loc, diag::use_unresolved_identifier, Name) - .highlight(Loc); + // If we failed lookup of an operator, check to see it to see if it is + // because two operators are juxtaposed e.g. (x*-4) that needs whitespace. + // If so, emit specific diagnostics for it. + if (!diagnoseOperatorJuxtaposition(UDRE, DC, *this)) { + diagnose(Loc, diag::use_unresolved_identifier, Name, + UDRE->getName().isOperator()) + .highlight(Loc); + } return new (Context) ErrorExpr(Loc); } @@ -653,10 +806,9 @@ bool PreCheckExpression::walkToClosureExprPre(ClosureExpr *closure) { TypeResolutionOptions options; options |= TR_AllowUnspecifiedTypes; options |= TR_AllowUnboundGenerics; - options |= TR_ImmediateFunctionInput; options |= TR_InExpression; bool hadParameterError = false; - if (TC.typeCheckPattern(closure->getParams(), DC, options)) { + if (TC.typeCheckParameterList(closure->getParameters(), DC, options)) { closure->setType(ErrorType::get(TC.Context)); // If we encounter an error validating the parameter list, don't bail. @@ -693,33 +845,7 @@ bool PreCheckExpression::walkToClosureExprPre(ClosureExpr *closure) { /// as expressions due to the parser not knowing which identifiers are /// type names. TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) { - // Fold T[] into an array, it isn't a subscript on a metatype. - if (auto *SE = dyn_cast(E)) { - auto *TyExpr = dyn_cast(SE->getBase()); - if (!TyExpr) return nullptr; - - // We don't fold subscripts with indexes, just an empty subscript. - TupleExpr *Indexes = dyn_cast(SE->getIndex()); - if (!Indexes || Indexes->getNumElements() != 0) - return nullptr; - - auto *InnerTypeRepr = TyExpr->getTypeRepr(); - assert(!TyExpr->isImplicit() && InnerTypeRepr && - "SubscriptExpr doesn't work on implicit TypeExpr's, " - "the TypeExpr should have been built correctly in the first place"); - - auto *NewTypeRepr = - new (TC.Context) ArrayTypeRepr(InnerTypeRepr, nullptr, - Indexes->getSourceRange(), - /*OldSyntax=*/true); - - TC.diagnose(Indexes->getStartLoc(), diag::new_array_syntax) - .fixItInsert(SE->getStartLoc(), "[") - .fixItRemove(Indexes->getStartLoc()); - return new (TC.Context) TypeExpr(TypeLoc(NewTypeRepr, Type())); - } - // Fold 'T.Type' or 'T.Protocol' into a metatype when T is a TypeExpr. if (auto *MRE = dyn_cast(E)) { auto *TyExpr = dyn_cast(MRE->getBase()); @@ -845,10 +971,9 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) { return nullptr; auto *NewTypeRepr = - new (TC.Context) ArrayTypeRepr(TyExpr->getTypeRepr(), nullptr, + new (TC.Context) ArrayTypeRepr(TyExpr->getTypeRepr(), SourceRange(AE->getLBracketLoc(), - AE->getRBracketLoc()), - /*OldSyntax=*/false); + AE->getRBracketLoc())); return new (TC.Context) TypeExpr(TypeLoc(NewTypeRepr, Type())); } @@ -1188,8 +1313,9 @@ bool TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc, // Apply the solution to the expression. auto &solution = viable[0]; bool isDiscarded = options.contains(TypeCheckExprFlags::IsDiscarded); + bool skipClosures = options.contains(TypeCheckExprFlags::SkipMultiStmtClosures); auto result = cs.applySolution(solution, expr, convertType, isDiscarded, - suppressDiagnostics); + suppressDiagnostics, skipClosures); if (!result) { // Failure already diagnosed, above, as part of applying the solution. return true; @@ -1234,10 +1360,23 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc, // Attempt to solve the constraint system. SmallVector viable; + const Type originalType = expr->getType(); + const bool needClearType = originalType && originalType->is(); + const auto recoverOriginalType = [&] () { + if (needClearType) + expr->setType(originalType); + }; + + // If the previous checking gives the expr error type, clear the result and + // re-check. + if (needClearType) + expr->setType(Type()); if (solveForExpression(expr, dc, /*convertType*/Type(), allowFreeTypeVariables, listener, cs, viable, - TypeCheckExprFlags::SuppressDiagnostics)) + TypeCheckExprFlags::SuppressDiagnostics)) { + recoverOriginalType(); return None; + } // Get the expression's simplified type. auto &solution = viable[0]; @@ -1247,6 +1386,8 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc, assert(!exprType->hasTypeVariable() && "free type variable with FreeTypeVariableBinding::GenericParameters?"); + // Recover the original type if needed. + recoverOriginalType(); return exprType; } @@ -1454,6 +1595,9 @@ bool TypeChecker::typeCheckBinding(Pattern *&pattern, Expr *&initializer, TypeResolutionOptions options; options |= TR_OverrideType; options |= TR_InExpression; + if (isa(expr->getSemanticsProvidingExpr())) { + options |= TR_EditorPlaceholder; + } if (tc.coercePatternToType(pattern, DC, patternType, options)) { return nullptr; } @@ -1566,6 +1710,9 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) { /// The type of the initializer. Type InitType; + /// The type of the sequence. + Type SequenceType; + public: explicit BindingListener(ForEachStmt *stmt) : Stmt(stmt) { } @@ -1581,12 +1728,23 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) { return true; } + SequenceType = + cs.createTypeVariable(Locator, /*options=*/TVO_MustBeMaterializable); cs.addConstraint(ConstraintKind::Conversion, expr->getType(), + SequenceType, Locator); + cs.addConstraint(ConstraintKind::ConformsTo, SequenceType, sequenceProto->getDeclaredType(), Locator); + auto generatorLocator = + cs.getConstraintLocator(Locator, + ConstraintLocator::SequenceGeneratorType); + auto elementLocator = + cs.getConstraintLocator(generatorLocator, + ConstraintLocator::GeneratorElementType); + // Collect constraints from the element pattern. auto pattern = Stmt->getPattern(); - InitType = cs.generateConstraints(pattern, Locator); + InitType = cs.generateConstraints(pattern, elementLocator); if (!InitType) return true; @@ -1619,13 +1777,10 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) { // Determine the generator type of the sequence. generatorType = cs.createTypeVariable(Locator, /*options=*/0); - cs.addConstraint( - Constraint::create(cs, ConstraintKind::TypeMember, - expr->getType(), generatorType, - tc.Context.Id_Generator, - cs.getConstraintLocator( - Locator, - ConstraintLocator::SequenceGeneratorType))); + cs.addConstraint(Constraint::create( + cs, ConstraintKind::TypeMember, + SequenceType, generatorType, + tc.Context.Id_Generator, generatorLocator)); // Determine the element type of the generator. // FIXME: Should look up the type witness. @@ -1633,31 +1788,30 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) { cs.addConstraint(Constraint::create( cs, ConstraintKind::TypeMember, generatorType, elementType, - tc.Context.Id_Element, - cs.getConstraintLocator( - Locator, - ConstraintLocator::GeneratorElementType))); + tc.Context.Id_Element, elementLocator)); } // Add a conversion constraint between the element type of the sequence // and the type of the element pattern. cs.addConstraint(ConstraintKind::Conversion, elementType, InitType, - Locator); + elementLocator); Stmt->setSequence(expr); return false; } virtual Expr *appliedSolution(Solution &solution, Expr *expr) { - // Figure out what type the constraints decided on. + // Figure out what types the constraints decided on. auto &cs = solution.getConstraintSystem(); auto &tc = cs.getTypeChecker(); InitType = solution.simplifyType(tc, InitType); + SequenceType = solution.simplifyType(tc, SequenceType); - // Force the sequence to be materializable. - // FIXME: work this into the constraint system - expr = tc.coerceToMaterializable(expr); + // Perform any necessary conversions of the sequence (e.g. [T]! -> [T]). + if (tc.convertToType(expr, SequenceType, cs.DC)) { + return nullptr; + } // Apply the solution to the iteration pattern as well. Pattern *pattern = Stmt->getPattern(); @@ -1839,10 +1993,7 @@ bool TypeChecker::typeCheckStmtCondition(StmtCondition &cond, DeclContext *dc, // If the pattern didn't get a type, it's because we ran into some // unknown types along the way. We'll need to check the initializer. auto init = elt.getInitializer(); - if (typeCheckBinding(pattern, init, dc)) { - hadError = true; - continue; - } + hadError |= typeCheckBinding(pattern, init, dc); elt.setPattern(pattern); elt.setInitializer(init); hadAnyFalsable |= pattern->isRefutablePattern(); @@ -2109,9 +2260,9 @@ bool TypeChecker::convertToType(Expr *&expr, Type type, DeclContext *dc) { return false; } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Debugging -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #pragma mark Debugging void Solution::dump() const { @@ -2303,7 +2454,7 @@ void ConstraintSystem::print(raw_ostream &out) { case OverloadChoiceKind::DeclViaUnwrappedOptional: if (choice.getBaseType()) out << choice.getBaseType()->getString() << "."; - out << choice.getDecl()->getName().str() << ": " + out << choice.getDecl()->getName() << ": " << resolved->BoundType->getString() << " == " << resolved->ImpliedType->getString() << "\n"; break; @@ -2575,7 +2726,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType, return CheckedCastKind::ValueCast; } -/// If the expression is a an implicit call to _forceBridgeFromObjectiveC or +/// If the expression is an implicit call to _forceBridgeFromObjectiveC or /// _conditionallyBridgeFromObjectiveC, returns the argument of that call. static Expr *lookThroughBridgeFromObjCCall(ASTContext &ctx, Expr *expr) { auto call = dyn_cast(expr); diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index f83bfb31c7b7b..0d01cc0d2ae7f 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -356,7 +356,7 @@ void TypeChecker::checkInheritanceClause(Decl *decl, { bool iBTC = decl->isBeingTypeChecked(); decl->setIsBeingTypeChecked(); - defer([&]{decl->setIsBeingTypeChecked(iBTC); }); + defer {decl->setIsBeingTypeChecked(iBTC); }; // Validate the type. if (validateType(inherited, DC, options, resolver)) { @@ -702,67 +702,6 @@ static void revertDependentTypeLoc(TypeLoc &tl) { tl.setType(Type(), /*validated=*/false); } -static void revertDependentPattern(Pattern *pattern) { - // Clear out the pattern's type. - if (pattern->hasType()) { - // If the type of the pattern was in error, we're done. - if (pattern->getType()->is()) - return; - - pattern->overwriteType(Type()); - } - - switch (pattern->getKind()) { -#define PATTERN(Id, Parent) -#define REFUTABLE_PATTERN(Id, Parent) case PatternKind::Id: -#include "swift/AST/PatternNodes.def" - // Do nothing for refutable patterns. - break; - - case PatternKind::Any: - // Do nothing; - break; - - case PatternKind::Named: { - // Clear out the type of the variable. - auto named = cast(pattern); - if (named->getDecl()->hasType() && - !named->getDecl()->isInvalid()) - named->getDecl()->overwriteType(Type()); - break; - } - - case PatternKind::Paren: - // Recurse into parentheses patterns. - revertDependentPattern(cast(pattern)->getSubPattern()); - break; - - case PatternKind::Var: - // Recurse into var patterns. - revertDependentPattern(cast(pattern)->getSubPattern()); - break; - - case PatternKind::Tuple: { - // Recurse into tuple elements. - auto tuple = cast(pattern); - for (auto &field : tuple->getElements()) { - revertDependentPattern(field.getPattern()); - } - break; - } - - case PatternKind::Typed: { - // Revert the type annotation. - auto typed = cast(pattern); - revertDependentTypeLoc(typed->getTypeLoc()); - - // Revert the subpattern. - revertDependentPattern(typed->getSubPattern()); - break; - } - } -} - /// Revert the dependent types within the given generic parameter list. void TypeChecker::revertGenericParamList(GenericParamList *genericParams) { // Revert the inherited clause of the generic parameter list. @@ -795,22 +734,23 @@ void TypeChecker::revertGenericParamList(GenericParamList *genericParams) { } } -static void markInvalidGenericSignature(AbstractFunctionDecl *AFD, +static void markInvalidGenericSignature(ValueDecl *VD, TypeChecker &TC) { - ArchetypeBuilder builder = TC.createArchetypeBuilder(AFD->getParentModule()); - auto genericParams = AFD->getGenericParams(); - - // If there is a parent context, add the generic parameters and requirements - // from that context. - auto dc = AFD->getDeclContext(); - - if (dc->isTypeContext()) - if (auto sig = dc->getGenericSignatureOfContext()) - builder.addGenericSignature(sig, true); + GenericParamList *genericParams; + if (auto *AFD = dyn_cast(VD)) + genericParams = AFD->getGenericParams(); + else + genericParams = cast(VD)->getGenericParams(); // If there aren't any generic parameters at this level, we're done. - if (!genericParams) + if (genericParams == nullptr) return; + + DeclContext *DC = VD->getDeclContext(); + ArchetypeBuilder builder = TC.createArchetypeBuilder(DC->getParentModule()); + + if (auto sig = DC->getGenericSignatureOfContext()) + builder.addGenericSignature(sig, true); // Visit each of the generic parameters. for (auto param : *genericParams) @@ -937,16 +877,18 @@ bool TypeChecker::handleSILGenericParams( void TypeChecker::revertGenericFuncSignature(AbstractFunctionDecl *func) { // Revert the result type. - if (auto fn = dyn_cast(func)) { - if (!fn->getBodyResultTypeLoc().isNull()) { + if (auto fn = dyn_cast(func)) + if (!fn->getBodyResultTypeLoc().isNull()) revertDependentTypeLoc(fn->getBodyResultTypeLoc()); - } - } - // Revert the body patterns. - ArrayRef bodyPatterns = func->getBodyParamPatterns(); - for (auto bodyPattern : bodyPatterns) { - revertDependentPattern(bodyPattern); + // Revert the body parameter types. + for (auto paramList : func->getParameterLists()) { + for (auto ¶m : *paramList) { + // Clear out the type of the decl. + if (param->hasType() && !param->isInvalid()) + param->overwriteType(Type()); + revertDependentTypeLoc(param->getTypeLoc()); + } } // Revert the generic parameter list. @@ -1219,9 +1161,9 @@ static void validatePatternBindingDecl(TypeChecker &tc, // On any path out of this function, make sure to mark the binding as done // being type checked. - defer([&]{ + defer { binding->setIsBeingTypeChecked(false); - }); + }; // Resolve the pattern. auto *pattern = tc.resolvePattern(binding->getPattern(entryNumber), @@ -1372,14 +1314,10 @@ void swift::makeDynamic(ASTContext &ctx, ValueDecl *D) { /// pattern, etc. /// /// \param func The function whose 'self' is being configured. -/// \param outerGenericParams The generic parameters from the outer scope. /// /// \returns the type of 'self'. Type swift::configureImplicitSelf(TypeChecker &tc, - AbstractFunctionDecl *func, - GenericParamList *&outerGenericParams) { - outerGenericParams = nullptr; - + AbstractFunctionDecl *func) { auto selfDecl = func->getImplicitSelfDecl(); // Validate the context. @@ -1390,28 +1328,23 @@ Type swift::configureImplicitSelf(TypeChecker &tc, } // Compute the type of self. - Type selfTy = func->computeSelfType(&outerGenericParams); + Type selfTy = func->computeSelfType(); assert(selfDecl && selfTy && "Not a method"); - if (selfDecl->hasType()) - return selfDecl->getType(); - // 'self' is 'let' for reference types (i.e., classes) or when 'self' is // neither inout. selfDecl->setLet(!selfTy->is()); - selfDecl->setType(selfTy); - - auto bodyPattern = cast(func->getBodyParamPatterns()[0]); - if (!bodyPattern->getTypeLoc().getTypeRepr()) - bodyPattern->getTypeLoc() = TypeLoc::withoutLoc(selfTy); - + selfDecl->overwriteType(selfTy); + + // Install the self type on the Parameter that contains it. This ensures that + // we don't lose it when generic types get reverted. + selfDecl->getTypeLoc() = TypeLoc::withoutLoc(selfTy); return selfTy; } /// Compute the allocating and initializing constructor types for /// the given constructor. void swift::configureConstructorType(ConstructorDecl *ctor, - GenericParamList *outerGenericParams, Type selfType, Type argType, bool throws) { @@ -1423,12 +1356,11 @@ void swift::configureConstructorType(ConstructorDecl *ctor, resultType = OptionalType::get(ctor->getFailability(), resultType); } - // Use the argument names in the argument type. - argType = argType->getRelabeledType(ctor->getASTContext(), - ctor->getFullName().getArgumentNames()); - auto extInfo = AnyFunctionType::ExtInfo().withThrows(throws); + GenericParamList *outerGenericParams = + ctor->getDeclContext()->getGenericParamsOfContext(); + if (GenericParamList *innerGenericParams = ctor->getGenericParams()) { innerGenericParams->setOuterParameters(outerGenericParams); fnType = PolymorphicFunctionType::get(argType, resultType, @@ -1438,7 +1370,7 @@ void swift::configureConstructorType(ConstructorDecl *ctor, fnType = FunctionType::get(argType, resultType, extInfo); } Type selfMetaType = MetatypeType::get(selfType->getInOutObjectType()); - if (outerGenericParams) { + if (ctor->getDeclContext()->isGenericTypeContext()) { allocFnType = PolymorphicFunctionType::get(selfMetaType, fnType, outerGenericParams); initFnType = PolymorphicFunctionType::get(selfType, fnType, @@ -1600,6 +1532,7 @@ void TypeChecker::computeAccessibility(ValueDecl *D) { case DeclContextKind::Initializer: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: D->setAccessibility(Accessibility::Private); break; case DeclContextKind::Module: @@ -2054,12 +1987,8 @@ static void checkAccessibility(TypeChecker &TC, const Decl *D) { Optional minAccess; const TypeRepr *complainRepr = nullptr; bool problemIsElement = false; - SD->getIndices()->forEachNode([&](const Pattern *P) { - auto *TP = dyn_cast(P); - if (!TP) - return; - - checkTypeAccessibility(TC, TP->getTypeLoc(), SD, + for (auto &P : *SD->getIndices()) { + checkTypeAccessibility(TC, P->getTypeLoc(), SD, [&](Accessibility typeAccess, const TypeRepr *thisComplainRepr) { if (!minAccess || *minAccess > typeAccess) { @@ -2067,7 +1996,7 @@ static void checkAccessibility(TypeChecker &TC, const Decl *D) { complainRepr = thisComplainRepr; } }); - }); + } checkTypeAccessibility(TC, SD->getElementTypeLoc(), SD, [&](Accessibility typeAccess, @@ -2112,16 +2041,9 @@ static void checkAccessibility(TypeChecker &TC, const Decl *D) { Optional minAccess; const TypeRepr *complainRepr = nullptr; - bool problemIsResult = false; - std::for_each(fn->getBodyParamPatterns().begin() + isTypeContext, - fn->getBodyParamPatterns().end(), - [&](const Pattern *paramList) { - paramList->forEachNode([&](const Pattern *P) { - auto *TP = dyn_cast(P); - if (!TP) - return; - - checkTypeAccessibility(TC, TP->getTypeLoc(), fn, + for (auto *PL : fn->getParameterLists().slice(isTypeContext)) { + for (auto &P : *PL) { + checkTypeAccessibility(TC, P->getTypeLoc(), fn, [&](Accessibility typeAccess, const TypeRepr *thisComplainRepr) { if (!minAccess || *minAccess > typeAccess) { @@ -2129,9 +2051,10 @@ static void checkAccessibility(TypeChecker &TC, const Decl *D) { complainRepr = thisComplainRepr; } }); - }); - }); + } + } + bool problemIsResult = false; if (auto FD = dyn_cast(fn)) { checkTypeAccessibility(TC, FD->getBodyResultTypeLoc(), FD, [&](Accessibility typeAccess, @@ -2930,7 +2853,7 @@ class DeclChecker : public DeclVisitor { if (!IsSecondPass) { for (unsigned i = 0, e = PBD->getNumPatternEntries(); i != e; ++i) { - // Type check each VarDecl in that his PatternBinding handles. + // Type check each VarDecl that this PatternBinding handles. visitBoundVars(PBD->getPattern(i)); // If we have a type but no initializer, check whether the type is @@ -3038,8 +2961,8 @@ class DeclChecker : public DeclVisitor { auto dc = SD->getDeclContext(); bool isInvalid = TC.validateType(SD->getElementTypeLoc(), dc); - isInvalid |= TC.typeCheckPattern(SD->getIndices(), dc, - TR_ImmediateFunctionInput); + isInvalid |= TC.typeCheckParameterList(SD->getIndices(), dc, + TypeResolutionOptions()); if (isInvalid) { SD->overwriteType(ErrorType::get(TC.Context)); @@ -3051,7 +2974,7 @@ class DeclChecker : public DeclVisitor { return; // Relabel the indices according to the subscript name. - auto indicesType = SD->getIndices()->getType(); + auto indicesType = SD->getIndices()->getType(TC.Context); SD->setType(FunctionType::get(indicesType, SD->getElementType())); // If we're in a generic context, set the interface type. @@ -3192,6 +3115,18 @@ class DeclChecker : public DeclVisitor { } void visitAssociatedTypeDecl(AssociatedTypeDecl *assocType) { + if (assocType->isBeingTypeChecked()) { + + if (!assocType->isInvalid()) { + assocType->setInvalid(); + assocType->overwriteType(ErrorType::get(TC.Context)); + TC.diagnose(assocType->getLoc(), diag::circular_type_alias, assocType->getName()); + } + return; + } + + assocType->setIsBeingTypeChecked(); + TC.checkDeclAttributesEarly(assocType); if (!assocType->hasAccessibility()) assocType->setAccessibility(assocType->getProtocol()->getFormalAccess()); @@ -3205,6 +3140,8 @@ class DeclChecker : public DeclVisitor { defaultDefinition.setInvalidType(TC.Context); } TC.checkDeclAttributes(assocType); + + assocType->setIsBeingTypeChecked(false); } bool checkUnsupportedNestedGeneric(NominalTypeDecl *NTD) { @@ -3351,7 +3288,7 @@ class DeclChecker : public DeclVisitor { TC.checkDeclAttributes(SD); } - /// Check whether the given propertes can be @NSManaged in this class. + /// Check whether the given properties can be @NSManaged in this class. static bool propertiesCanBeNSManaged(ClassDecl *classDecl, ArrayRef vars) { // Check whether we have an Objective-C-defined class in our @@ -3590,20 +3527,14 @@ class DeclChecker : public DeclVisitor { bool semaFuncParamPatterns(AbstractFunctionDecl *fd, GenericTypeResolver *resolver = nullptr) { - // Type check the body patterns. - bool badType = false; - auto bodyPatterns = fd->getBodyParamPatterns(); - for (unsigned i = 0, e = bodyPatterns.size(); i != e; ++i) { - auto *bodyPat = bodyPatterns[i]; - - if (bodyPat->hasType()) - continue; - - if (TC.typeCheckPattern(bodyPat, fd, TR_ImmediateFunctionInput, resolver)) - badType = true; + bool hadError = false; + for (auto paramList : fd->getParameterLists()) { + hadError |= TC.typeCheckParameterList(paramList, fd, + TypeResolutionOptions(), + resolver); } - return badType; + return hadError; } void semaFuncDecl(FuncDecl *FD, GenericTypeResolver *resolver) { @@ -3616,7 +3547,7 @@ class DeclChecker : public DeclVisitor { bool badType = false; if (!FD->getBodyResultTypeLoc().isNull()) { - TypeResolutionOptions options = TR_FunctionResult; + TypeResolutionOptions options; if (FD->hasDynamicSelf()) options |= TR_DynamicSelfResult; if (TC.validateType(FD->getBodyResultTypeLoc(), FD, options, @@ -3653,19 +3584,18 @@ class DeclChecker : public DeclVisitor { // patterns. GenericParamList *genericParams = FD->getGenericParams(); GenericParamList *outerGenericParams = nullptr; - auto patterns = FD->getBodyParamPatterns(); + auto paramLists = FD->getParameterLists(); bool hasSelf = FD->getDeclContext()->isTypeContext(); - if (hasSelf) + if (FD->getDeclContext()->isGenericTypeContext()) outerGenericParams = FD->getDeclContext()->getGenericParamsOfContext(); - for (unsigned i = 0, e = patterns.size(); i != e; ++i) { - if (!patterns[e - i - 1]->hasType()) { + for (unsigned i = 0, e = paramLists.size(); i != e; ++i) { + Type argTy = paramLists[e - i - 1]->getType(TC.Context); + if (!argTy) { FD->setType(ErrorType::get(TC.Context)); FD->setInvalid(); return; } - - Type argTy = patterns[e - i - 1]->getType(); // Determine the appropriate generic parameters at this level. GenericParamList *params = nullptr; @@ -3981,11 +3911,8 @@ class DeclChecker : public DeclVisitor { Type valueTy = ASD->getType()->getReferenceStorageReferent(); if (FD->isObservingAccessor() || (FD->isSetter() && FD->isImplicit())) { unsigned firstParamIdx = FD->getParent()->isTypeContext(); - auto *firstParamPattern = FD->getBodyParamPatterns()[firstParamIdx]; - auto *tuplePattern = cast(firstParamPattern); - auto *paramPattern = tuplePattern->getElements().front().getPattern(); - auto *paramTypePattern = cast(paramPattern); - paramTypePattern->getTypeLoc().setType(valueTy, true); + auto *firstParamPattern = FD->getParameterList(firstParamIdx); + firstParamPattern->get(0)->getTypeLoc().setType(valueTy, true); } else if (FD->isGetter() && FD->isImplicit()) { FD->getBodyResultTypeLoc().setType(valueTy, true); } @@ -3993,13 +3920,12 @@ class DeclChecker : public DeclVisitor { } // Before anything else, set up the 'self' argument correctly if present. - GenericParamList *outerGenericParams = nullptr; if (FD->getDeclContext()->isTypeContext()) - configureImplicitSelf(TC, FD, outerGenericParams); + configureImplicitSelf(TC, FD); // If we have generic parameters, check the generic signature now. if (auto gp = FD->getGenericParams()) { - gp->setOuterParameters(outerGenericParams); + gp->setOuterParameters(FD->getDeclContext()->getGenericParamsOfContext()); if (TC.validateGenericFuncSignature(FD)) { markInvalidGenericSignature(FD, TC); @@ -4010,7 +3936,7 @@ class DeclChecker : public DeclVisitor { TC.checkGenericParamList(&builder, gp, FD->getDeclContext()); // Infer requirements from parameter patterns. - for (auto pattern : FD->getBodyParamPatterns()) { + for (auto pattern : FD->getParameterLists()) { builder.inferRequirements(pattern, gp); } @@ -4026,7 +3952,7 @@ class DeclChecker : public DeclVisitor { // Assign archetypes. finalizeGenericParamList(builder, gp, FD, TC); } - } else if (outerGenericParams) { + } else if (FD->getDeclContext()->isGenericTypeContext()) { if (TC.validateGenericFuncSignature(FD)) { markInvalidGenericSignature(FD, TC); } else if (!FD->hasType()) { @@ -4139,41 +4065,36 @@ class DeclChecker : public DeclVisitor { // closure parameter; warn about such things, because the closure will not // be treated as a trailing closure. if (!FD->isImplicit()) { - auto paramPattern = FD->getBodyParamPatterns()[ - FD->getDeclContext()->isTypeContext() ? 1 : 0]; - if (auto paramTuple = dyn_cast(paramPattern)) { - ArrayRef fields = paramTuple->getElements(); - unsigned n = fields.size(); - bool anyDefaultArguments = false; - for (unsigned i = n; i > 0; --i) { - // Determine whether the parameter is of (possibly lvalue, possibly - // optional), non-autoclosure function type, which could receive a - // closure. We look at the type sugar directly, so that one can - // suppress this warning by adding parentheses. - auto paramType = fields[i-1].getPattern()->getType(); - - if (auto *funcTy = isUnparenthesizedTrailingClosure(paramType)) { - // If we saw any default arguments before this, complain. - // This doesn't apply to autoclosures. - if (anyDefaultArguments && !funcTy->getExtInfo().isAutoClosure()) { - TC.diagnose(fields[i-1].getPattern()->getStartLoc(), - diag::non_trailing_closure_before_default_args) - .highlight(SourceRange(fields[i].getPattern()->getStartLoc(), - fields[n-1].getPattern()->getEndLoc())); - } - - break; - } - - // If we have a default argument, keep going. - if (fields[i-1].getDefaultArgKind() != DefaultArgumentKind::None) { - anyDefaultArguments = true; - continue; + auto paramList = FD->getParameterList(FD->getImplicitSelfDecl() ? 1 : 0); + bool anyDefaultArguments = false; + for (unsigned i = paramList->size(); i != 0; --i) { + // Determine whether the parameter is of (possibly lvalue, possibly + // optional), non-autoclosure function type, which could receive a + // closure. We look at the type sugar directly, so that one can + // suppress this warning by adding parentheses. + auto ¶m = paramList->get(i-1); + auto paramType = param->getType(); + + if (auto *funcTy = isUnparenthesizedTrailingClosure(paramType)) { + // If we saw any default arguments before this, complain. + // This doesn't apply to autoclosures. + if (anyDefaultArguments && !funcTy->getExtInfo().isAutoClosure()) { + TC.diagnose(param->getStartLoc(), + diag::non_trailing_closure_before_default_args) + .highlight(param->getSourceRange()); } - // We're done. break; } + + // If we have a default argument, keep going. + if (param->isDefaultArgument()) { + anyDefaultArguments = true; + continue; + } + + // We're done. + break; } } } @@ -4230,10 +4151,6 @@ class DeclChecker : public DeclVisitor { return true; } - static const Pattern *getTupleElementPattern(const TuplePatternElt &elt) { - return elt.getPattern(); - } - /// Drop the optionality of the result type of the given function type. static Type dropResultOptionality(Type type, unsigned uncurryLevel) { // We've hit the result type. @@ -4272,28 +4189,22 @@ class DeclChecker : public DeclVisitor { parentTy = parentTy->getResult()->castTo(); // Check the parameter types. - auto checkParam = [&](const Pattern *paramPattern, Type parentParamTy) { - Type paramTy = paramPattern->getType(); + auto checkParam = [&](const ParamDecl *decl, Type parentParamTy) { + Type paramTy = decl->getType(); if (!paramTy || !paramTy->getImplicitlyUnwrappedOptionalObjectType()) return; if (!parentParamTy || parentParamTy->getAnyOptionalObjectType()) return; - if (auto parenPattern = dyn_cast(paramPattern)) - paramPattern = parenPattern->getSubPattern(); - if (auto varPattern = dyn_cast(paramPattern)) - paramPattern = varPattern->getSubPattern(); - auto typedParamPattern = dyn_cast(paramPattern); - if (!typedParamPattern) + TypeLoc TL = decl->getTypeLoc(); + if (!TL.getTypeRepr()) return; - TypeLoc TL = typedParamPattern->getTypeLoc(); - // Allow silencing this warning using parens. if (isa(TL.getType().getPointer())) return; - TC.diagnose(paramPattern->getLoc(), diag::override_unnecessary_IUO, + TC.diagnose(decl->getStartLoc(), diag::override_unnecessary_IUO, method->getDescriptiveKind(), parentParamTy, paramTy) .highlight(TL.getSourceRange()); @@ -4311,33 +4222,17 @@ class DeclChecker : public DeclVisitor { .fixItInsertAfter(TL.getSourceRange().End, ")"); }; - auto rawParamPatterns = method->getBodyParamPatterns()[1]; - auto paramPatterns = dyn_cast(rawParamPatterns); - + auto paramList = method->getParameterList(1); auto parentInput = parentTy->getInput(); - auto parentTupleInput = parentInput->getAs(); - if (parentTupleInput) { - if (paramPatterns) { - // FIXME: If we ever allow argument reordering, this is incorrect. - ArrayRef sharedParams = paramPatterns->getElements(); - sharedParams = sharedParams.slice(0, - parentTupleInput->getNumElements()); - - using PatternView = ArrayRefView; - for_each(PatternView(sharedParams), parentTupleInput->getElementTypes(), - checkParam); - } else if (parentTupleInput->getNumElements() > 0) { - checkParam(rawParamPatterns, parentTupleInput->getElementType(0)); - } + + if (auto parentTupleInput = parentInput->getAs()) { + // FIXME: If we ever allow argument reordering, this is incorrect. + ArrayRef sharedParams = paramList->getArray(); + sharedParams = sharedParams.slice(0, parentTupleInput->getNumElements()); + for_each(sharedParams, parentTupleInput->getElementTypes(), checkParam); } else { // Otherwise, the parent has a single parameter with no label. - if (paramPatterns) { - checkParam(paramPatterns->getElements().front().getPattern(), - parentInput); - } else { - checkParam(rawParamPatterns, parentInput); - } + checkParam(paramList->get(0), parentInput); } auto methodAsFunc = dyn_cast(method); @@ -4830,6 +4725,7 @@ class DeclChecker : public DeclVisitor { UNINTERESTING_ATTR(WarnUnusedResult) UNINTERESTING_ATTR(WarnUnqualifiedAccess) + UNINTERESTING_ATTR(MigrationId) #undef UNINTERESTING_ATTR @@ -5152,7 +5048,7 @@ class DeclChecker : public DeclVisitor { auto resultTy = TC.getInterfaceTypeFromInternalType(enumDecl, funcTy->getResult()); auto interfaceTy - = GenericFunctionType::get(enumDecl->getGenericSignature(), + = GenericFunctionType::get(enumDecl->getGenericSignatureOfContext(), inputTy, resultTy, funcTy->getExtInfo()); // Record the interface type. @@ -5181,7 +5077,7 @@ class DeclChecker : public DeclVisitor { EED->setIsBeingTypeChecked(); // Only attempt to validate the argument type or raw value if the element - // is not currenly being validated. + // is not currently being validated. if (EED->getRecursiveness() == ElementRecursiveness::NotRecursive) { EED->setRecursiveness(ElementRecursiveness::PotentiallyRecursive); @@ -5231,7 +5127,7 @@ class DeclChecker : public DeclVisitor { // case the enclosing enum type was illegally declared inside of a generic // context. (In that case, we'll post a diagnostic while visiting the // parent enum.) - if (ED->getGenericParams()) + if (EED->getDeclContext()->isGenericTypeContext()) computeEnumElementInterfaceType(EED); // Require the carried type to be materializable. @@ -5378,13 +5274,12 @@ class DeclChecker : public DeclVisitor { } } - GenericParamList *outerGenericParams; - Type SelfTy = configureImplicitSelf(TC, CD, outerGenericParams); + Type SelfTy = configureImplicitSelf(TC, CD); Optional builder; if (auto gp = CD->getGenericParams()) { // Write up generic parameters and check the generic parameter list. - gp->setOuterParameters(outerGenericParams); + gp->setOuterParameters(CD->getDeclContext()->getGenericParamsOfContext()); if (TC.validateGenericFuncSignature(CD)) { markInvalidGenericSignature(CD, TC); @@ -5394,7 +5289,7 @@ class DeclChecker : public DeclVisitor { TC.checkGenericParamList(&builder, gp, CD->getDeclContext()); // Infer requirements from the parameters of the constructor. - builder.inferRequirements(CD->getBodyParamPatterns()[1], gp); + builder.inferRequirements(CD->getParameterList(1), gp); // Revert the types within the signature so it can be type-checked with // archetypes below. @@ -5403,7 +5298,7 @@ class DeclChecker : public DeclVisitor { // Assign archetypes. finalizeGenericParamList(builder, gp, CD, TC); } - } else if (outerGenericParams) { + } else if (CD->getDeclContext()->isGenericTypeContext()) { if (TC.validateGenericFuncSignature(CD)) { CD->setInvalid(); } else { @@ -5417,8 +5312,8 @@ class DeclChecker : public DeclVisitor { CD->overwriteType(ErrorType::get(TC.Context)); CD->setInvalid(); } else { - configureConstructorType(CD, outerGenericParams, SelfTy, - CD->getBodyParamPatterns()[1]->getType(), + configureConstructorType(CD, SelfTy, + CD->getParameterList(1)->getType(TC.Context), CD->getThrowsLoc().isValid()); } @@ -5546,10 +5441,9 @@ class DeclChecker : public DeclVisitor { DD->setAccessibility(enclosingClass->getFormalAccess()); } - GenericParamList *outerGenericParams; - Type SelfTy = configureImplicitSelf(TC, DD, outerGenericParams); + Type SelfTy = configureImplicitSelf(TC, DD); - if (outerGenericParams) + if (DD->getDeclContext()->isGenericTypeContext()) TC.validateGenericFuncSignature(DD); if (semaFuncParamPatterns(DD)) { @@ -5558,10 +5452,10 @@ class DeclChecker : public DeclVisitor { } Type FnTy; - if (outerGenericParams) + if (DD->getDeclContext()->isGenericTypeContext()) FnTy = PolymorphicFunctionType::get(SelfTy, TupleType::getEmpty(TC.Context), - outerGenericParams); + DD->getDeclContext()->getGenericParamsOfContext()); else FnTy = FunctionType::get(SelfTy, TupleType::getEmpty(TC.Context)); @@ -5607,7 +5501,7 @@ bool TypeChecker::isAvailabilitySafeForConformance( return true; NominalTypeDecl *conformingDecl = DC->isNominalTypeOrNominalTypeExtensionContext(); - assert(conformingDecl && "Must have conformining declaration"); + assert(conformingDecl && "Must have conforming declaration"); // Make sure that any access of the witness through the protocol // can only occur when the witness is available. That is, make sure that @@ -5758,6 +5652,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { case DeclContextKind::FileUnit: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::Initializer: + case DeclContextKind::SubscriptDecl: llvm_unreachable("cannot have type params"); case DeclContextKind::NominalTypeDecl: { @@ -5810,7 +5705,7 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { // Validate the generic type parameters. if (validateGenericTypeSignature(nominal)) { - nominal->markInvalidGenericSignature(); + markInvalidGenericSignature(nominal, *this); return; } @@ -5875,9 +5770,8 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { // Validate the generic type signature, which is just . validateGenericTypeSignature(proto); - GenericParamList *outerGenericParams = - proto->getDeclContext()->getGenericParamsOfContext(); - gp->setOuterParameters(outerGenericParams); + assert(gp->getOuterParameters() == + proto->getDeclContext()->getGenericParamsOfContext()); revertGenericParamList(gp); @@ -5956,21 +5850,19 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { if (VD->getParentInitializer() && !VD->getParentInitializer()->getType()) { diagnose(parentPattern->getLoc(), diag::identifier_init_failure, - parentPattern->getBodyName()); + parentPattern->getBoundName()); } return; } - } else if (VD->isImplicit() && - (VD->getName() == Context.Id_self)) { + } else if (VD->isSelfParameter()) { // If the variable declaration is for a 'self' parameter, it may be // because the self variable was reverted whilst validating the function // signature. In that case, reset the type. if (isa(VD->getDeclContext()->getParent())) { if (auto funcDeclContext = dyn_cast(VD->getDeclContext())) { - GenericParamList *outerGenericParams = nullptr; - configureImplicitSelf(*this, funcDeclContext, outerGenericParams); + configureImplicitSelf(*this, funcDeclContext); } } else { D->setType(ErrorType::get(Context)); @@ -6239,7 +6131,7 @@ static Type checkExtensionGenericParams( }; ext->setIsBeingTypeChecked(true); - defer([ext] { ext->setIsBeingTypeChecked(false); }); + defer { ext->setIsBeingTypeChecked(false); }; // Validate the generic type signature. bool invalid = false; @@ -6901,40 +6793,34 @@ void TypeChecker::defineDefaultConstructor(NominalTypeDecl *decl) { if (!ctor || ctor->isInvalid()) continue; - auto paramTuple = ctor->getArgumentType()->getAs(); - if (!paramTuple) { - // A designated initializer other than a default initializer - // means we can't call super.init(). - if (ctor->isDesignatedInit()) - return; - - continue; - } - - // Check whether any of the tuple elements are missing an initializer. + // Check to see if this ctor has zero arguments, or if they all have + // default values. + auto params = ctor->getParameters(); + bool missingInit = false; - for (auto &elt : paramTuple->getElements()) { - if (elt.hasInit()) - continue; - - missingInit = true; - break; + for (auto param : *params) { + if (!param->isDefaultArgument()) { + missingInit = true; + break; + } } + + // Check to see if this is an impossible candidate. if (missingInit) { - // A designated initializer other than a default initializer - // means we can't call super.init(). + // If we found an impossible designated initializer, then we cannot + // call super.init(), even if there is a match. if (ctor->isDesignatedInit()) return; + // Otherwise, keep looking. continue; } - // We found a constructor that can be invoked with an empty tuple. - if (foundDefaultConstructor) { - // We found two constructors that can be invoked with an empty tuple. - foundDefaultConstructor = false; - break; - } + // Ok, we found a constructor that can be invoked with an empty tuple. + // If this is our second, then we bail out, because we don't want to + // pick one arbitrarily. + if (foundDefaultConstructor) + return; foundDefaultConstructor = true; } @@ -6995,6 +6881,12 @@ static void validateAttributes(TypeChecker &TC, Decl *D) { } else if (auto ED = dyn_cast(D)) { if (ED->isGenericContext()) error = diag::objc_enum_generic; + } else if (auto EED = dyn_cast(D)) { + auto ED = EED->getParentEnum(); + if (!ED->getAttrs().hasAttribute()) + error = diag::objc_enum_case_req_objc_enum; + else if (objcAttr->hasName() && EED->getParentCase()->getElements().size() > 1) + error = diag::objc_enum_case_multi; } else if (isa(D)) { auto func = cast(D); if (!checkObjCDeclContext(D)) @@ -7024,14 +6916,17 @@ static void validateAttributes(TypeChecker &TC, Decl *D) { // If there is a name, check whether the kind of name is // appropriate. if (auto objcName = objcAttr->getName()) { - if (isa(D) || isa(D) || isa(D)) { + if (isa(D) || isa(D) || isa(D) + || isa(D) || isa(D)) { // Types and properties can only have nullary // names. Complain and recover by chopping off everything // after the first name. if (objcName->getNumArgs() > 0) { - int which = isa(D)? 0 + int which = isa(D)? 0 : isa(D)? 1 - : 2; + : isa(D)? 2 + : isa(D)? 3 + : 4; SourceLoc firstNameLoc = objcAttr->getNameLocs().front(); SourceLoc afterFirstNameLoc = Lexer::getLocForEndOfToken(TC.Context.SourceMgr, firstNameLoc); @@ -7041,10 +6936,6 @@ static void validateAttributes(TypeChecker &TC, Decl *D) { ObjCSelector(TC.Context, 0, objcName->getSelectorPieces()[0]), /*implicit=*/false); } - } else if (isa(D)) { - // Enums don't have runtime names. - TC.diagnose(objcAttr->getLParenLoc(), diag::objc_name_enum); - const_cast(objcAttr)->clearName(); } else if (isa(D)) { // Subscripts can never have names. TC.diagnose(objcAttr->getLParenLoc(), diag::objc_name_subscript); @@ -7053,15 +6944,11 @@ static void validateAttributes(TypeChecker &TC, Decl *D) { // We have a function. Make sure that the number of parameters // matches the "number of colons" in the name. auto func = cast(D); - auto bodyPattern = func->getBodyParamPatterns()[1]; - unsigned numParameters; - if (isa(func) && - cast(func)->isObjCZeroParameterWithLongSelector()) - numParameters = 0; - else if (auto tuple = dyn_cast(bodyPattern)) - numParameters = tuple->getNumElements(); - else - numParameters = 1; + auto params = func->getParameterList(1); + unsigned numParameters = params->size(); + if (auto CD = dyn_cast(func)) + if (CD->isObjCZeroParameterWithLongSelector()) + numParameters = 0; // Something like "init(foo: ())" // A throwing method has an error parameter. if (func->isBodyThrowing()) @@ -7084,6 +6971,11 @@ static void validateAttributes(TypeChecker &TC, Decl *D) { D->getAttrs().removeAttribute(objcAttr); } } + } else if (isa(D)) { + // Enum elements require names. + TC.diagnose(objcAttr->getLocation(), diag::objc_enum_case_req_name) + .fixItRemove(objcAttr->getRangeWithAt()); + objcAttr->setInvalid(); } } @@ -7158,10 +7050,7 @@ void TypeChecker::fixAbstractFunctionNames(InFlightDiagnostic &diag, // Fix the argument names that need fixing. assert(name.getArgumentNames().size() == targetName.getArgumentNames().size()); - auto pattern - = func->getBodyParamPatterns()[func->getDeclContext()->isTypeContext()]; - auto tuplePattern = dyn_cast( - pattern->getSemanticsProvidingPattern()); + auto params = func->getParameterList(func->getDeclContext()->isTypeContext()); for (unsigned i = 0, n = name.getArgumentNames().size(); i != n; ++i) { auto origArg = name.getArgumentNames()[i]; auto targetArg = targetName.getArgumentNames()[i]; @@ -7169,61 +7058,38 @@ void TypeChecker::fixAbstractFunctionNames(InFlightDiagnostic &diag, if (origArg == targetArg) continue; - // Find the location to update or insert. - SourceLoc loc; - if (tuplePattern) { - auto origPattern = tuplePattern->getElement(i).getPattern(); - if (auto param = cast_or_null(origPattern->getSingleVar())) { - // The parameter has an explicitly-specified API name, and it's wrong. - if (param->getArgumentNameLoc() != param->getLoc() && - param->getArgumentNameLoc().isValid()) { - // ... but the internal parameter name was right. Just zap the - // incorrect explicit specialization. - if (param->getName() == targetArg) { - diag.fixItRemoveChars(param->getArgumentNameLoc(), - param->getLoc()); - continue; - } - - // Fix the API name. - StringRef targetArgStr = targetArg.empty()? "_" : targetArg.str(); - diag.fixItReplace(param->getArgumentNameLoc(), targetArgStr); - continue; - } - - // The parameter did not specify a separate API name. Insert one. - if (targetArg.empty()) - diag.fixItInsert(param->getLoc(), "_ "); - else { - llvm::SmallString<8> targetArgStr; - targetArgStr += targetArg.str(); - targetArgStr += ' '; - diag.fixItInsert(param->getLoc(), targetArgStr); - } - - if (param->isImplicit()) { - loc = origPattern->getLoc(); - } else { - continue; - } + auto *param = params->get(i); + + // The parameter has an explicitly-specified API name, and it's wrong. + if (param->getArgumentNameLoc() != param->getLoc() && + param->getArgumentNameLoc().isValid()) { + // ... but the internal parameter name was right. Just zap the + // incorrect explicit specialization. + if (param->getName() == targetArg) { + diag.fixItRemoveChars(param->getArgumentNameLoc(), + param->getLoc()); + continue; } - if (auto any = dyn_cast( - origPattern->getSemanticsProvidingPattern())) { - if (any->isImplicit()) { - loc = origPattern->getLoc(); - } else { - loc = any->getLoc(); - } - } else { - loc = origPattern->getLoc(); - } - } else if (auto paren = dyn_cast(pattern)) { - loc = paren->getSubPattern()->getLoc(); - } else { - loc = pattern->getLoc(); + // Fix the API name. + StringRef targetArgStr = targetArg.empty()? "_" : targetArg.str(); + diag.fixItReplace(param->getArgumentNameLoc(), targetArgStr); + continue; } + // The parameter did not specify a separate API name. Insert one. + if (targetArg.empty()) + diag.fixItInsert(param->getLoc(), "_ "); + else { + llvm::SmallString<8> targetArgStr; + targetArgStr += targetArg.str(); + targetArgStr += ' '; + diag.fixItInsert(param->getLoc(), targetArgStr); + } + + // Find the location to update or insert. + SourceLoc loc = func->getLoc(); + StringRef replacement; if (targetArg.empty()) replacement = "_"; diff --git a/lib/Sema/TypeCheckError.cpp b/lib/Sema/TypeCheckError.cpp index 7e25a32aae7a4..4f91581300595 100644 --- a/lib/Sema/TypeCheckError.cpp +++ b/lib/Sema/TypeCheckError.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -303,7 +303,7 @@ enum class ThrowingKind { Throws, }; -/// A type expressing the result of classifying whether an call or function +/// A type expressing the result of classifying whether a call or function /// throws. class Classification { ThrowingKind Result; diff --git a/lib/Sema/TypeCheckExpr.cpp b/lib/Sema/TypeCheckExpr.cpp index a16aaedb85e35..0a91522cf3024 100644 --- a/lib/Sema/TypeCheckExpr.cpp +++ b/lib/Sema/TypeCheckExpr.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -142,7 +142,9 @@ static InfixData getInfixData(TypeChecker &TC, DeclContext *DC, Expr *E) { Associativity::Right, /*assignment*/ false); - } else if (auto *assign = dyn_cast(E)) { + } + + if (auto *assign = dyn_cast(E)) { // Assignment has fixed precedence. assert(!assign->isFolded() && "already folded assign expr in sequence?!"); (void)assign; @@ -150,7 +152,9 @@ static InfixData getInfixData(TypeChecker &TC, DeclContext *DC, Expr *E) { Associativity::Right, /*assignment*/ true); - } else if (auto *as = dyn_cast(E)) { + } + + if (auto *as = dyn_cast(E)) { // 'as' and 'is' casts have fixed precedence. assert(!as->isFolded() && "already folded 'as' expr in sequence?!"); (void)as; @@ -158,7 +162,9 @@ static InfixData getInfixData(TypeChecker &TC, DeclContext *DC, Expr *E) { Associativity::None, /*assignment*/ false); - } else if (DeclRefExpr *DRE = dyn_cast(E)) { + } + + if (DeclRefExpr *DRE = dyn_cast(E)) { SourceFile *SF = DC->getParentSourceFile(); Identifier name = DRE->getDecl()->getName(); bool isCascading = DC->isCascadingContextForLookup(true); @@ -166,7 +172,9 @@ static InfixData getInfixData(TypeChecker &TC, DeclContext *DC, Expr *E) { E->getLoc())) return op->getInfixData(); - } else if (OverloadedDeclRefExpr *OO = dyn_cast(E)) { + } + + if (OverloadedDeclRefExpr *OO = dyn_cast(E)) { SourceFile *SF = DC->getParentSourceFile(); Identifier name = OO->getDecls()[0]->getName(); bool isCascading = DC->isCascadingContextForLookup(true); @@ -174,8 +182,12 @@ static InfixData getInfixData(TypeChecker &TC, DeclContext *DC, Expr *E) { E->getLoc())) return op->getInfixData(); } - - TC.diagnose(E->getLoc(), diag::unknown_binop); + + // If E is already an ErrorExpr, then we've diagnosed it as invalid already, + // otherwise emit an error. + if (!isa(E)) + TC.diagnose(E->getLoc(), diag::unknown_binop); + // Recover with an infinite-precedence left-associative operator. return InfixData((unsigned char)~0U, Associativity::Left, /*assignment*/ false); @@ -890,7 +902,7 @@ namespace { } // Recursively check the transitive captures. capturePath.push_back(func); - defer([&]{ capturePath.pop_back(); }); + defer { capturePath.pop_back(); }; for (auto capture : func->getCaptureInfo().getCaptures()) if (!validateForwardCapture(capture.getDecl())) return false; @@ -974,8 +986,14 @@ namespace { bool walkToDeclPre(Decl *D) override { if (auto *AFD = dyn_cast(D)) { propagateCaptures(AFD, AFD->getLoc()); - for (auto *paramPattern : AFD->getBodyParamPatterns()) - paramPattern->walk(*this); + + // Can default parameter initializers capture state? That seems like + // a really bad idea. + for (auto *paramList : AFD->getParameterLists()) + for (auto param : *paramList) { + if (auto E = param->getDefaultValue()) + E->getExpr()->walk(*this); + } return false; } @@ -1064,30 +1082,16 @@ void TypeChecker::computeCaptures(AnyFunctionRef AFR) { } } - // We don't distinguish inner from outer generic parameters yet, but also - // nested generics are not really supported by the rest of the compiler. - // There are three cases where getGenericSignatureOfContext() returns a - // non-null value: - // - // 1) Top-level generic functions - // 2) Methods with a generic signature either on the type or the method - // 3) Local generic functions - // - // But *not* - // - // 4) Closure or non-generic local function inside a generic context - // - // In case 1) and 2), usages of generic type parameters are never formally - // "captures". In case 3), the only way a generic type parameter can be - // captured is if the local generic function is itself nested inside a generic - // context. However, SILGen does not currently support this anyway. + // Since nested generic functions are not supported yet, the only case where + // generic parameters can be captured is by closures and non-generic local + // functions. // - // So we only set GenericParamCaptures in case 4), to avoid confusing SILGen. - // Eventually, the computation in checkType() will be more exact and this - // conditional should be removed. - if (!(AFR.getAbstractFunctionDecl() && - AFR.getAbstractFunctionDecl()->hasType() && - AFR.getAbstractFunctionDecl()->getGenericSignatureOfContext())) { + // So we only set GenericParamCaptures if we have a closure, or a + // non-generic function defined inside a local context. + auto *AFD = AFR.getAbstractFunctionDecl(); + if (!AFD || + (!AFD->getGenericParams() && + AFD->getDeclContext()->isLocalContext())) { AFR.getCaptureInfo().setGenericParamCaptures(GenericParamCaptures); } diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index 26569df7d0bfd..7280f8f48c1d7 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,7 +30,10 @@ Type DependentGenericTypeResolver::resolveDependentMemberType( DeclContext *DC, SourceRange baseRange, ComponentIdentTypeRepr *ref) { - return Builder.resolveArchetype(baseTy)->getRepresentative() + auto archetype = Builder.resolveArchetype(baseTy); + assert(archetype && "Bad generic context nesting?"); + + return archetype->getRepresentative() ->getNestedType(ref->getIdentifier(), Builder) ->getDependentType(Builder, true); } @@ -39,7 +42,10 @@ Type DependentGenericTypeResolver::resolveSelfAssociatedType( Type selfTy, DeclContext *DC, AssociatedTypeDecl *assocType) { - return Builder.resolveArchetype(selfTy)->getRepresentative() + auto archetype = Builder.resolveArchetype(selfTy); + assert(archetype && "Bad generic context nesting?"); + + return archetype->getRepresentative() ->getNestedType(assocType->getName(), Builder) ->getDependentType(Builder, true); } @@ -210,20 +216,6 @@ Type CompleteGenericTypeResolver::resolveTypeOfContext(DeclContext *dc) { return ext->getExtendedType()->getAnyNominal()->getDeclaredInterfaceType(); } -/// Add the generic parameters and requirements from the parent context to the -/// archetype builder. -static void addContextParamsAndRequirements(ArchetypeBuilder &builder, - DeclContext *dc, - bool adoptArchetypes) { - if (!dc->isTypeContext()) - return; - - if (auto sig = dc->getGenericSignatureOfContext()) { - // Add generic signature from this context. - builder.addGenericSignature(sig, adoptArchetypes); - } -} - /// Check the generic parameters in the given generic parameter list (and its /// parent generic parameter lists) according to the given resolver. bool TypeChecker::checkGenericParamList(ArchetypeBuilder *builder, @@ -236,7 +228,8 @@ bool TypeChecker::checkGenericParamList(ArchetypeBuilder *builder, // If there is a parent context, add the generic parameters and requirements // from that context. if (builder && parentDC) - addContextParamsAndRequirements(*builder, parentDC, adoptArchetypes); + if (auto sig = parentDC->getGenericSignatureOfContext()) + builder->addGenericSignature(sig, adoptArchetypes); // If there aren't any generic parameters at this level, we're done. if (!genericParams) @@ -253,20 +246,25 @@ bool TypeChecker::checkGenericParamList(ArchetypeBuilder *builder, options = TR_GenericSignature; } - // Visit each of the generic parameters. + // First, set the depth of each generic parameter, and add them to the + // archetype builder. Do this before checking the inheritance clause, + // since it may itself be dependent on one of these parameters. unsigned depth = genericParams->getDepth(); for (auto param : *genericParams) { - // Check the generic type parameter. - // Set the depth of this type parameter. param->setDepth(depth); - // Check the inheritance clause of this type parameter. - checkInheritanceClause(param, resolver); - if (builder) { - // Add the generic parameter to the builder. if (builder->addGenericParameter(param)) invalid = true; + } + } + + // Now, check the inheritance clauses of each parameter. + for (auto param : *genericParams) { + checkInheritanceClause(param, resolver); + + if (builder) { + builder->addGenericParameterRequirements(param); // Infer requirements from the inherited types. for (const auto &inherited : param->getInherited()) { @@ -350,15 +348,12 @@ static void collectGenericParamTypes( GenericParamList *genericParams, DeclContext *parentDC, SmallVectorImpl &allParams) { - // If the parent context is a generic type (or nested type thereof), - // add its generic parameters. - if (parentDC->isTypeContext()) { - if (auto parentSig = parentDC->getGenericSignatureOfContext()) { - allParams.append(parentSig->getGenericParams().begin(), - parentSig->getGenericParams().end()); - } + // If the parent context has a generic signature, add its generic parameters. + if (auto parentSig = parentDC->getGenericSignatureOfContext()) { + allParams.append(parentSig->getGenericParams().begin(), + parentSig->getGenericParams().end()); } - + if (genericParams) { // Add our parameters. for (auto param : *genericParams) { @@ -368,186 +363,6 @@ static void collectGenericParamTypes( } } -namespace { - /// \brief Function object that orders potential archetypes by name. - struct OrderPotentialArchetypeByName { - using PotentialArchetype = ArchetypeBuilder::PotentialArchetype; - - bool operator()(std::pair X, - std::pair Y) const { - return X.first.str() < Y.second->getName().str(); - } - - bool operator()(std::pair X, - Identifier Y) const { - return X.first.str() < Y.str(); - } - - bool operator()(Identifier X, - std::pair Y) const { - return X.str() < Y.first.str(); - } - - bool operator()(Identifier X, Identifier Y) const { - return X.str() < Y.str(); - } - }; -} - -/// Add the requirements for the given potential archetype and its nested -/// potential archetypes to the set of requirements. -static void -addRequirements( - Module &mod, Type type, - ArchetypeBuilder::PotentialArchetype *pa, - llvm::SmallPtrSet &knownPAs, - SmallVectorImpl &requirements) { - // If the potential archetype has been bound away to a concrete type, - // it needs no requirements. - if (pa->isConcreteType()) - return; - - // Add a value witness marker. - requirements.push_back(Requirement(RequirementKind::WitnessMarker, - type, Type())); - - // Add superclass requirement, if needed. - if (auto superclass = pa->getSuperclass()) { - // FIXME: Distinguish superclass from conformance? - // FIXME: What if the superclass type involves a type parameter? - requirements.push_back(Requirement(RequirementKind::Conformance, - type, superclass)); - } - - // Add conformance requirements. - SmallVector protocols; - for (const auto &conforms : pa->getConformsTo()) { - protocols.push_back(conforms.first); - } - - ProtocolType::canonicalizeProtocols(protocols); - for (auto proto : protocols) { - requirements.push_back(Requirement(RequirementKind::Conformance, - type, proto->getDeclaredType())); - } -} - -static void -addNestedRequirements( - Module &mod, Type type, - ArchetypeBuilder::PotentialArchetype *pa, - llvm::SmallPtrSet &knownPAs, - SmallVectorImpl &requirements) { - using PotentialArchetype = ArchetypeBuilder::PotentialArchetype; - - // Collect the nested types, sorted by name. - // FIXME: Could collect these from the conformance requirements, above. - SmallVector, 16> nestedTypes; - for (const auto &nested : pa->getNestedTypes()) { - // FIXME: Dropping requirements among different associated types of the - // same name. - nestedTypes.push_back(std::make_pair(nested.first, nested.second.front())); - } - std::sort(nestedTypes.begin(), nestedTypes.end(), - OrderPotentialArchetypeByName()); - - // Add requirements for associated types. - for (const auto &nested : nestedTypes) { - auto rep = nested.second->getRepresentative(); - if (knownPAs.insert(rep).second) { - // Form the dependent type that refers to this archetype. - auto assocType = nested.second->getResolvedAssociatedType(); - if (!assocType) - continue; // FIXME: If we do this late enough, there will be no failure. - - // Skip nested types bound to concrete types. - if (rep->isConcreteType()) - continue; - - auto nestedType = DependentMemberType::get(type, assocType, - mod.getASTContext()); - - addRequirements(mod, nestedType, rep, knownPAs, requirements); - addNestedRequirements(mod, nestedType, rep, knownPAs, requirements); - } - } -} - -/// Collect the set of requirements placed on the given generic parameters and -/// their associated types. -static void collectRequirements(ArchetypeBuilder &builder, - ArrayRef params, - SmallVectorImpl &requirements) { - typedef ArchetypeBuilder::PotentialArchetype PotentialArchetype; - - // Find the "primary" potential archetypes, from which we'll collect all - // of the requirements. - llvm::SmallPtrSet knownPAs; - llvm::SmallVector primary; - for (auto param : params) { - auto pa = builder.resolveArchetype(param); - assert(pa && "Missing potential archetype for generic parameter"); - - // We only care about the representative. - pa = pa->getRepresentative(); - - if (knownPAs.insert(pa).second) - primary.push_back(param); - } - - // Add all of the conformance and superclass requirements placed on the given - // generic parameters and their associated types. - unsigned primaryIdx = 0, numPrimary = primary.size(); - while (primaryIdx < numPrimary) { - unsigned depth = primary[primaryIdx]->getDepth(); - - // For each of the primary potential archetypes, add the requirements. - // Stop when we hit a parameter at a different depth. - // FIXME: This algorithm falls out from the way the "all archetypes" lists - // are structured. Once those lists no longer exist or are no longer - // "the truth", we can simplify this algorithm considerably. - unsigned lastPrimaryIdx = primaryIdx; - for (unsigned idx = primaryIdx; - idx < numPrimary && primary[idx]->getDepth() == depth; - ++idx, ++lastPrimaryIdx) { - auto param = primary[idx]; - auto pa = builder.resolveArchetype(param)->getRepresentative(); - - // Add other requirements. - addRequirements(builder.getModule(), param, pa, knownPAs, - requirements); - } - - // For each of the primary potential archetypes, add the nested requirements. - for (unsigned idx = primaryIdx; idx < lastPrimaryIdx; ++idx) { - auto param = primary[idx]; - auto pa = builder.resolveArchetype(param)->getRepresentative(); - addNestedRequirements(builder.getModule(), param, pa, knownPAs, - requirements); - } - - primaryIdx = lastPrimaryIdx; - } - - - // Add all of the same-type requirements. - for (auto req : builder.getSameTypeRequirements()) { - auto firstType = req.first->getDependentType(builder, false); - Type secondType; - if (auto concrete = req.second.dyn_cast()) - secondType = concrete; - else if (auto secondPA = req.second.dyn_cast()) - secondType = secondPA->getDependentType(builder, false); - - if (firstType->is() || secondType->is() || - firstType->isEqual(secondType)) - continue; - - requirements.push_back(Requirement(RequirementKind::SameType, - firstType, secondType)); - } -} - /// Check the signature of a generic function. static bool checkGenericFuncSignature(TypeChecker &tc, ArchetypeBuilder *builder, @@ -564,15 +379,15 @@ static bool checkGenericFuncSignature(TypeChecker &tc, false, &resolver); // Check the parameter patterns. - for (auto pattern : func->getBodyParamPatterns()) { + for (auto params : func->getParameterLists()) { // Check the pattern. - if (tc.typeCheckPattern(pattern, func, TR_ImmediateFunctionInput, - &resolver)) + if (tc.typeCheckParameterList(params, func, TypeResolutionOptions(), + &resolver)) badType = true; // Infer requirements from the pattern. if (builder) { - builder->inferRequirements(pattern, genericParams); + builder->inferRequirements(params, genericParams); } } @@ -580,7 +395,7 @@ static bool checkGenericFuncSignature(TypeChecker &tc, if (auto fn = dyn_cast(func)) { if (!fn->getBodyResultTypeLoc().isNull()) { // Check the result type of the function. - TypeResolutionOptions options = TR_FunctionResult; + TypeResolutionOptions options; if (fn->hasDynamicSelf()) options |= TR_DynamicSelfResult; @@ -644,16 +459,16 @@ static Type getResultType(TypeChecker &TC, FuncDecl *fn, Type resultType) { } bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) { + bool invalid = false; + // Create the archetype builder. ArchetypeBuilder builder = createArchetypeBuilder(func->getParentModule()); // Type check the function declaration, treating all generic type // parameters as dependent, unresolved. DependentGenericTypeResolver dependentResolver(builder); - if (checkGenericFuncSignature(*this, &builder, func, dependentResolver)) { - func->overwriteType(ErrorType::get(Context)); - return true; - } + if (checkGenericFuncSignature(*this, &builder, func, dependentResolver)) + invalid = true; // If this triggered a recursive validation, back out: we're done. // FIXME: This is an awful hack. @@ -668,10 +483,8 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) { // function signature and type-check it again, completely. revertGenericFuncSignature(func); CompleteGenericTypeResolver completeResolver(*this, builder); - if (checkGenericFuncSignature(*this, nullptr, func, completeResolver)) { - func->overwriteType(ErrorType::get(Context)); - return true; - } + if (checkGenericFuncSignature(*this, nullptr, func, completeResolver)) + invalid = true; // The generic function signature is complete and well-formed. Determine // the type of the generic function. @@ -682,9 +495,31 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) { func->getDeclContext(), allGenericParams); - // Collect the requirements placed on the generic parameter types. - SmallVector requirements; - collectRequirements(builder, allGenericParams, requirements); + auto sig = builder.getGenericSignature(allGenericParams); + + // Debugging of the archetype builder and generic signature generation. + if (sig && Context.LangOpts.DebugGenericSignatures) { + func->dumpRef(llvm::errs()); + llvm::errs() << "\n"; + builder.dump(llvm::errs()); + llvm::errs() << "Generic signature: "; + sig->print(llvm::errs()); + llvm::errs() << "\n"; + llvm::errs() << "Canonical generic signature: "; + sig->getCanonicalSignature()->print(llvm::errs()); + llvm::errs() << "\n"; + llvm::errs() << "Canonical generic signature for mangling: "; + sig->getCanonicalManglingSignature(*func->getParentModule()) + ->print(llvm::errs()); + llvm::errs() << "\n"; + } + + func->setGenericSignature(sig); + + if (invalid) { + func->overwriteType(ErrorType::get(Context)); + return true; + } // Compute the function type. Type funcTy; @@ -718,42 +553,20 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) { funcTy = TupleType::getEmpty(Context); } - auto patterns = func->getBodyParamPatterns(); - SmallVector storedPatterns; + auto paramLists = func->getParameterLists(); + SmallVector storedParamLists; // FIXME: Destructors don't have the '()' pattern in their signature, so // paste it here. if (isa(func)) { - storedPatterns.append(patterns.begin(), patterns.end()); - - Pattern *pattern = TuplePattern::create(Context, SourceLoc(), { }, - SourceLoc(), /*Implicit=*/true); - pattern->setType(TupleType::getEmpty(Context)); - storedPatterns.push_back(pattern); - patterns = storedPatterns; - } - - auto sig = GenericSignature::get(allGenericParams, requirements); - - // Debugging of the archetype builder and generic signature generation. - if (Context.LangOpts.DebugGenericSignatures) { - func->dumpRef(llvm::errs()); - llvm::errs() << "\n"; - builder.dump(llvm::errs()); - llvm::errs() << "Generic signature: "; - sig->print(llvm::errs()); - llvm::errs() << "\n"; - llvm::errs() << "Canonical generic signature: "; - sig->getCanonicalSignature()->print(llvm::errs()); - llvm::errs() << "\n"; - llvm::errs() << "Canonical generic signature for mangling: "; - sig->getCanonicalManglingSignature(*func->getParentModule()) - ->print(llvm::errs()); - llvm::errs() << "\n"; + assert(paramLists.size() == 1 && "Only the self paramlist"); + storedParamLists.push_back(paramLists[0]); + storedParamLists.push_back(ParameterList::createEmpty(Context)); + paramLists = storedParamLists; } bool hasSelf = func->getDeclContext()->isTypeContext(); - for (unsigned i = 0, e = patterns.size(); i != e; ++i) { + for (unsigned i = 0, e = paramLists.size(); i != e; ++i) { Type argTy; Type initArgTy; @@ -767,7 +580,7 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) { initArgTy = func->computeInterfaceSelfType(/*isInitializingCtor=*/true); } } else { - argTy = patterns[e - i - 1]->getType(); + argTy = paramLists[e - i - 1]->getType(Context); // For an implicit declaration, our argument type will be in terms of // archetypes rather than dependent types. Replace the @@ -910,14 +723,8 @@ GenericSignature *TypeChecker::validateGenericSignature( SmallVector allGenericParams; collectGenericParamTypes(genericParams, dc, allGenericParams); - // Collect the requirements placed on the generic parameter types. - // FIXME: This ends up copying all of the requirements from outer scopes, - // which is mostly harmless (but quite annoying). - SmallVector requirements; - collectRequirements(builder, allGenericParams, requirements); - // Record the generic type parameter types and the requirements. - auto sig = GenericSignature::get(allGenericParams, requirements); + auto sig = builder.getGenericSignature(allGenericParams); // Debugging of the archetype builder and generic signature generation. if (Context.LangOpts.DebugGenericSignatures) { @@ -1010,14 +817,26 @@ bool TypeChecker::checkGenericArguments(DeclContext *dc, SourceLoc loc, ArrayRef genericArgs) { // Form the set of generic substitutions required TypeSubstitutionMap substitutions; + auto genericParams = genericSig->getGenericParams(); - assert(genericParams.size() == genericArgs.size()); - for (unsigned i = 0, n = genericParams.size(); i != n; ++i) { - auto gp - = genericParams[i]->getCanonicalType()->castTo(); - substitutions[gp] = genericArgs[i]; + + unsigned genericTypeDepth = + owner->getAnyNominal()->getGenericTypeContextDepth(); + unsigned count = 0; + + for (auto gp : genericParams) { + // Skip parameters that were introduced by outer generic + // function signatures. + if (gp->getDecl()->getDepth() < genericTypeDepth) + continue; + auto gpTy = gp->getCanonicalType()->castTo(); + substitutions[gpTy] = genericArgs[count++]; } + // The number of generic type arguments being bound must be equal to the + // total number of generic parameters in the current generic type context. + assert(count == genericArgs.size()); + // Check each of the requirements. Module *module = dc->getParentModule(); for (const auto &req : genericSig->getRequirements()) { diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp index 14ed9159ad102..e51fce4e5d2d2 100644 --- a/lib/Sema/TypeCheckNameLookup.cpp +++ b/lib/Sema/TypeCheckNameLookup.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index 518e7cb870e7f..8a4e6f55dad7b 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,6 +19,7 @@ #include "GenericTypeResolver.h" #include "swift/AST/Attr.h" #include "swift/AST/ExprHandle.h" +#include "swift/AST/ASTWalker.h" #include "swift/AST/ASTVisitor.h" #include "swift/AST/NameLookup.h" #include "llvm/Support/SaveAndRestore.h" @@ -58,7 +59,7 @@ extractEnumElement(const VarDecl *constant) { /// Find the first enum element in \p foundElements. /// -/// If there are no enum elements but there are properties, attepmts to map +/// If there are no enum elements but there are properties, attempts to map /// an arbitrary property to an enum element using extractEnumElement. static EnumElementDecl * filterForEnumElement(LookupResult foundElements) { @@ -368,8 +369,7 @@ class ResolvePattern : public ASTVisitorgetElement(i)); patternElts.push_back(TuplePatternElt(E->getElementName(i), E->getElementNameLoc(i), - pattern, - false)); + pattern)); } return TuplePattern::create(TC.Context, E->getLoc(), @@ -692,37 +692,93 @@ static bool validateTypedPattern(TypeChecker &TC, DeclContext *DC, TypedPattern *TP, TypeResolutionOptions options, GenericTypeResolver *resolver) { - if (TP->hasType()) { + if (TP->hasType()) return TP->getType()->is(); - } - bool hadError = false; TypeLoc &TL = TP->getTypeLoc(); - if (TC.validateType(TL, DC, options, resolver)) - hadError = true; - Type Ty = TL.getType(); + bool hadError = TC.validateType(TL, DC, options, resolver); + + if (hadError) + TP->setType(ErrorType::get(TC.Context)); + else + TP->setType(TL.getType()); + return hadError; +} + - if ((options & TR_Variadic) && !hadError) { +static bool validateParameterType(ParamDecl *decl, DeclContext *DC, + TypeResolutionOptions options, + GenericTypeResolver *resolver, + TypeChecker &TC) { + if (auto ty = decl->getTypeLoc().getType()) + return ty->is(); + + bool hadError = TC.validateType(decl->getTypeLoc(), DC, + options|TR_FunctionInput, resolver); + + Type Ty = decl->getTypeLoc().getType(); + if (decl->isVariadic() && !hadError) { // If isn't legal to declare something both inout and variadic. if (Ty->is()) { - TC.diagnose(TP->getLoc(), diag::inout_cant_be_variadic); + TC.diagnose(decl->getStartLoc(), diag::inout_cant_be_variadic); hadError = true; } else { - // FIXME: Use ellipsis loc for diagnostic. - Ty = TC.getArraySliceType(TP->getLoc(), Ty); - if (Ty.isNull()) + Ty = TC.getArraySliceType(decl->getStartLoc(), Ty); + if (Ty.isNull()) { hadError = true; + } } + decl->getTypeLoc().setType(Ty); } - if (hadError) { - TP->setType(ErrorType::get(TC.Context)); - } else { - TP->setType(Ty); + if (hadError) + decl->getTypeLoc().setType(ErrorType::get(TC.Context), /*validated*/true); + + return hadError; +} + +/// Type check a parameter list. +bool TypeChecker::typeCheckParameterList(ParameterList *PL, DeclContext *DC, + TypeResolutionOptions options, + GenericTypeResolver *resolver) { + bool hadError = false; + + for (auto param : *PL) { + if (param->getTypeLoc().getTypeRepr()) + hadError |= validateParameterType(param, DC, options, resolver, *this); + + auto type = param->getTypeLoc().getType(); + if (!type && param->hasType()) { + type = param->getType(); + param->getTypeLoc().setType(type); + } + + // If there was no type specified, and if we're not looking at a + // ClosureExpr, then we have a parse error (no type was specified). The + // parser will have already diagnosed this, but treat this as a type error + // as well to get the ParamDecl marked invalid and to get an ErrorType. + if (!type) { + // Closure argument lists are allowed to be missing types. + if (options & TR_InExpression) + continue; + param->setInvalid(); + } + + if (param->isInvalid()) { + param->overwriteType(ErrorType::get(Context)); + hadError = true; + } else + param->overwriteType(type); + + checkTypeModifyingDeclAttributes(param); + if (param->getType()->is()) + param->setLet(false); } + return hadError; } + bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc, TypeResolutionOptions options, GenericTypeResolver *resolver) { @@ -731,7 +787,6 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc, if (!resolver) resolver = &defaultResolver; - TypeResolutionOptions subOptions = options - TR_Variadic; switch (P->getKind()) { // Type-check paren patterns by checking the sub-pattern and // propagating that type out. @@ -742,7 +797,7 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc, SP = PP->getSubPattern(); else SP = cast(P)->getSubPattern(); - if (typeCheckPattern(SP, dc, subOptions, resolver)) { + if (typeCheckPattern(SP, dc, options, resolver)) { P->setType(ErrorType::get(Context)); return true; } @@ -784,7 +839,8 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc, P->setType(ErrorType::get(Context)); if (auto named = dyn_cast(P)) { if (auto var = named->getDecl()) { - var->setType(ErrorType::get(Context)); + var->setInvalid(); + var->overwriteType(ErrorType::get(Context)); } } return true; @@ -797,19 +853,15 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc, // If this is the top level of a function input list, peel off the // ImmediateFunctionInput marker and install a FunctionInput one instead. - auto elementOptions = withoutContext(subOptions); - if (subOptions & TR_ImmediateFunctionInput) + auto elementOptions = withoutContext(options); + if (options & TR_ImmediateFunctionInput) elementOptions |= TR_FunctionInput; bool missingType = false; for (unsigned i = 0, e = tuplePat->getNumElements(); i != e; ++i) { TuplePatternElt &elt = tuplePat->getElement(i); Pattern *pattern = elt.getPattern(); - bool hasEllipsis = elt.hasEllipsis(); - TypeResolutionOptions eltOptions = elementOptions; - if (hasEllipsis) - eltOptions |= TR_Variadic; - if (typeCheckPattern(pattern, dc, eltOptions, resolver)){ + if (typeCheckPattern(pattern, dc, elementOptions, resolver)){ hadError = true; continue; } @@ -818,10 +870,7 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc, continue; } - typeElts.push_back(TupleTypeElt(pattern->getType(), - elt.getLabel(), - elt.getDefaultArgKind(), - hasEllipsis)); + typeElts.push_back(TupleTypeElt(pattern->getType(), elt.getLabel())); } if (hadError) { @@ -908,8 +957,7 @@ static bool coercePatternViaConditionalDowncast(TypeChecker &tc, bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, TypeResolutionOptions options, GenericTypeResolver *resolver) { - TypeResolutionOptions subOptions - = options - TR_Variadic - TR_EnumPatternPayload; + TypeResolutionOptions subOptions = options - TR_EnumPatternPayload; switch (P->getKind()) { // For parens and vars, just set the type annotation and propagate inwards. case PatternKind::Paren: { @@ -1025,7 +1073,8 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, if (shouldRequireType && !(options & TR_FromNonInferredPattern) && - !(options & TR_EnumerationVariable)) { + !(options & TR_EnumerationVariable) && + !(options & TR_EditorPlaceholder)) { diagnose(NP->getLoc(), diag::type_inferred_to_undesirable_type, NP->getDecl()->getName(), type, NP->getDecl()->isLet()); diagnose(NP->getLoc(), diag::add_explicit_type_annotation_to_silence); @@ -1041,10 +1090,7 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, // TODO: permit implicit conversions? case PatternKind::Tuple: { TuplePattern *TP = cast(P); - bool hadError = false; - - if (type->is()) - hadError = true; + bool hadError = type->is(); // Sometimes a paren is just a paren. If the tuple pattern has a single // element, we can reduce it to a paren pattern. @@ -1077,7 +1123,6 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, } // The number of elements must match exactly. - // TODO: incomplete tuple patterns, with some syntax. if (!hadError && tupleTy->getNumElements() != TP->getNumElements()) { if (canDecayToParen) return decayToParen(); @@ -1092,7 +1137,6 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, for (unsigned i = 0, e = TP->getNumElements(); i != e; ++i) { TuplePatternElt &elt = TP->getElement(i); Pattern *pattern = elt.getPattern(); - bool hasEllipsis = elt.hasEllipsis(); Type CoercionType; if (hadError) @@ -1102,52 +1146,17 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, // If the tuple pattern had a label for the tuple element, it must match // the label for the tuple type being matched. - // TODO: detect and diagnose shuffling - // TODO: permit shuffling if (!hadError && !elt.getLabel().empty() && - i < tupleTy->getNumElements() && elt.getLabel() != tupleTy->getElement(i).getName()) { diagnose(elt.getLabelLoc(), diag::tuple_pattern_label_mismatch, elt.getLabel(), tupleTy->getElement(i).getName()); hadError = true; } - TypeResolutionOptions subOptions = options - TR_Variadic; - if (hasEllipsis) - subOptions |= TR_Variadic; - hadError |= coercePatternToType(pattern, dc, CoercionType, subOptions, - resolver); + hadError |= coercePatternToType(pattern, dc, CoercionType, + options, resolver); if (!hadError) elt.setPattern(pattern); - - // Type-check the initialization expression. - assert(!elt.getInit() && - "Tuples cannot have default values, only parameters"); - } - - // For Swift 2.0, we ban single-element tuple patterns that have labels. - // They are too confusingly similar to parenthesized typed patterns that - // were allowed in Swift 1.x, and it is always safe to just remove the tuple - // label if it was desired. We can relax this limitation later if necessary. - // - // Note that we allow these in enum contexts and in function/closure - // argument lists, since being able to name the first argument of a function - // is still considered to be important. - if (!hadError && TP->getNumElements() == 1 && - !TP->getElement(0).getLabel().empty() && - !(options & TR_EnumPatternPayload) && - !(options & TR_FunctionInput) && - !(options & TR_ImmediateFunctionInput)) { - SourceLoc LabelLoc = TP->getElement(0).getLabelLoc(); - diagnose(LabelLoc, diag::label_single_entry_tuple); - // Emit two notes with fixits offering help to resolve this ambiguity. - diagnose(TP->getLParenLoc(), diag::remove_parens_for_type_annotation) - .fixItRemove(TP->getLParenLoc()).fixItRemove(TP->getRParenLoc()); - unsigned LabelLen = TP->getElement(0).getLabel().getLength(); - diagnose(LabelLoc, diag::remove_label_for_tuple_pattern) - .fixItRemove(SourceRange(LabelLoc, - LabelLoc.getAdvancedLocOrInvalid(LabelLen))); - hadError = true; } return hadError; @@ -1227,7 +1236,7 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, IP->getLoc(), IP->getLoc(),IP->getCastTypeLoc().getSourceRange(), [](Type) { return false; }, - /*suppressDiagnostics=*/ false); + /*suppressDiagnostics=*/ type->is()); switch (castKind) { case CheckedCastKind::Unresolved: return false; @@ -1279,17 +1288,18 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, // type as `.Foo`), resolve it now that we have a type. Optional castKind; + EnumElementDecl *elt = EEP->getElementDecl(); + Type enumTy; - if (!EEP->getElementDecl()) { - EnumElementDecl *element = nullptr; + if (!elt) { if (type->getAnyNominal()) - element = lookupEnumMemberElement(*this, dc, type, EEP->getName()); - if (!element) { - diagnose(EEP->getLoc(), diag::enum_element_pattern_member_not_found, - EEP->getName().str(), type); + elt = lookupEnumMemberElement(*this, dc, type, EEP->getName()); + if (!elt) { + if (!type->is()) + diagnose(EEP->getLoc(), diag::enum_element_pattern_member_not_found, + EEP->getName().str(), type); return true; } - EEP->setElementDecl(element); enumTy = type; } else { // Check if the explicitly-written enum type matches the type we're @@ -1336,8 +1346,6 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, } } - EnumElementDecl *elt = EEP->getElementDecl(); - // If there is a subpattern, push the enum element type down onto it. if (EEP->hasSubPattern()) { Type elementType; @@ -1354,6 +1362,8 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, return true; EEP->setSubPattern(sub); } + + EEP->setElementDecl(elt); EEP->setType(enumTy); // Ensure that the type of our TypeLoc is fully resolved. If an unbound @@ -1531,3 +1541,93 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type, } llvm_unreachable("bad pattern kind!"); } + + +/// Coerce the specified parameter list of a ClosureExpr to the specified +/// contextual type. +/// +/// \returns true if an error occurred, false otherwise. +/// +/// TODO: These diagnostics should be a lot better now that we know this is +/// all specific to closures. +/// +bool TypeChecker::coerceParameterListToType(ParameterList *P, DeclContext *DC, + Type paramListType) { + bool hadError = paramListType->is(); + + // Sometimes a scalar type gets applied to a single-argument parameter list. + auto handleParameter = [&](ParamDecl *param, Type ty) -> bool { + bool hadError = false; + + // Check that the type, if explicitly spelled, is ok. + if (param->getTypeLoc().getTypeRepr()) { + hadError |= validateParameterType(param, DC, TypeResolutionOptions(), + nullptr, *this); + + // Now that we've type checked the explicit argument type, see if it + // agrees with the contextual type. + if (!hadError && !ty->isEqual(param->getTypeLoc().getType()) && + !ty->is()) + param->overwriteType(ty); + } + + if (param->isInvalid()) + param->overwriteType(ErrorType::get(Context)); + else + param->overwriteType(ty); + + checkTypeModifyingDeclAttributes(param); + if (ty->is()) + param->setLet(false); + return hadError; + }; + + + // The context type must be a tuple. + TupleType *tupleTy = paramListType->getAs(); + if (!tupleTy && !hadError) { + if (P->size() == 1) + return handleParameter(P->get(0), paramListType); + diagnose(P->getStartLoc(), diag::tuple_pattern_in_non_tuple_context, + paramListType); + hadError = true; + } + + // The number of elements must match exactly. + // TODO: incomplete tuple patterns, with some syntax. + if (!hadError && tupleTy->getNumElements() != P->size()) { + if (P->size() == 1) + return handleParameter(P->get(0), paramListType); + + diagnose(P->getStartLoc(), diag::tuple_pattern_length_mismatch, + paramListType); + hadError = true; + } + + // Coerce each parameter to the respective type. + for (unsigned i = 0, e = P->size(); i != e; ++i) { + auto ¶m = P->get(i); + + Type CoercionType; + if (hadError) + CoercionType = ErrorType::get(Context); + else + CoercionType = tupleTy->getElement(i).getType(); + + // If the tuple pattern had a label for the tuple element, it must match + // the label for the tuple type being matched. + auto argName = param->getArgumentName(); + if (!hadError && !argName.empty() && + argName != tupleTy->getElement(i).getName()) { + diagnose(param->getArgumentNameLoc(), + diag::tuple_pattern_label_mismatch, + argName, tupleTy->getElement(i).getName()); + hadError = true; + } + + hadError |= handleParameter(param, CoercionType); + assert(!param->isDefaultArgument() && "Closures cannot have default args"); + } + + return hadError; +} diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 8b6f573753921..67c42e17e6e60 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -561,37 +561,20 @@ SourceLoc OptionalAdjustment::getOptionalityLoc(ValueDecl *witness) const { } // For parameter adjustments, dig out the pattern. - Pattern *pattern = nullptr; + ParameterList *params = nullptr; if (auto func = dyn_cast(witness)) { - auto bodyPatterns = func->getBodyParamPatterns(); + auto bodyParamLists = func->getParameterLists(); if (func->getDeclContext()->isTypeContext()) - bodyPatterns = bodyPatterns.slice(1); - pattern = bodyPatterns[0]; + bodyParamLists = bodyParamLists.slice(1); + params = bodyParamLists[0]; } else if (auto subscript = dyn_cast(witness)) { - pattern = subscript->getIndices(); + params = subscript->getIndices(); } else { return SourceLoc(); } - // Handle parentheses. - if (auto paren = dyn_cast(pattern)) { - assert(getParameterIndex() == 0 && "just the one parameter"); - if (auto typed = dyn_cast(paren->getSubPattern())) { - return getOptionalityLoc(typed->getTypeLoc().getTypeRepr()); - } - return SourceLoc(); - } - - // Handle tuples. - auto tuple = dyn_cast(pattern); - if (!tuple) - return SourceLoc(); - - const auto &tupleElt = tuple->getElement(getParameterIndex()); - if (auto typed = dyn_cast(tupleElt.getPattern())) { - return getOptionalityLoc(typed->getTypeLoc().getTypeRepr()); - } - return SourceLoc(); + return getOptionalityLoc(params->get(getParameterIndex())->getTypeLoc() + .getTypeRepr()); } SourceLoc OptionalAdjustment::getOptionalityLoc(TypeRepr *tyR) const { @@ -669,74 +652,26 @@ static SmallVector decomposeIntoTupleElements(Type type) { return result; } -namespace { - /// Dependent type opener that maps the type of a requirement, replacing - /// already-known associated types to their type witnesses and inner generic - /// parameters to their archetypes. - class RequirementTypeOpener : public constraints::DependentTypeOpener { - /// The type variable that represents the 'Self' type. - constraints::ConstraintSystem &CS; - NormalProtocolConformance *Conformance; - DeclContext *DC; - ProtocolDecl *Proto; - - public: - RequirementTypeOpener(constraints::ConstraintSystem &cs, - NormalProtocolConformance *conformance, - DeclContext *dc) - : CS(cs), Conformance(conformance), DC(dc), - Proto(conformance->getProtocol()) - { - } - - virtual void openedGenericParameter(GenericTypeParamType *param, - TypeVariableType *typeVar, - Type &replacementType) { - // If this is the 'Self' type, record it. - if (param->getDepth() == 0 && param->getIndex() == 0) - CS.SelfTypeVar = typeVar; - else - replacementType = ArchetypeBuilder::mapTypeIntoContext(DC, param); - } - - virtual bool shouldBindAssociatedType(Type baseType, - TypeVariableType *baseTypeVar, - AssociatedTypeDecl *assocType, - TypeVariableType *memberTypeVar, - Type &replacementType) { - // If the base is our 'Self' type, we have a witness for this - // associated type already. - if (baseTypeVar == CS.SelfTypeVar && - cast(assocType->getDeclContext()) == Proto) { - replacementType = Conformance->getTypeWitness(assocType, nullptr) - .getReplacement(); - - // Let the member type variable float; we don't want to - // resolve it as a member. - return false; - } - - // If the base is somehow derived from our 'Self' type, we can go ahead - // and bind it. There's nothing more to do. - auto rootBaseType = baseType; - while (auto dependentMember = rootBaseType->getAs()) - rootBaseType = dependentMember->getBase(); - if (auto rootGP = rootBaseType->getAs()) { - if (rootGP->getDepth() == 0 && rootGP->getIndex() == 0) - return true; - } else { - return true; +/// If the given type is a direct reference to an associated type of +/// the given protocol, return the referenced associated type. +static AssociatedTypeDecl * +getReferencedAssocTypeOfProtocol(Type type, ProtocolDecl *proto) { + if (auto dependentMember = type->getAs()) { + if (auto genericParam + = dependentMember->getBase()->getAs()) { + if (genericParam->getDepth() == 0 && genericParam->getIndex() == 0) { + if (auto assocType = dependentMember->getAssocType()) { + if (assocType->getDeclContext() == proto) + return assocType; + } } - - // We have a dependent member type based on a generic parameter; map it - // to an archetype. - auto memberType = DependentMemberType::get(baseType, assocType, - DC->getASTContext()); - replacementType = ArchetypeBuilder::mapTypeIntoContext(DC, memberType); - return true; } - }; + } + return nullptr; +} + +namespace { /// The kind of variance (none, covariance, contravariance) to apply /// when comparing types from a witness to types in the requirement /// we're matching it against. @@ -1241,23 +1176,54 @@ matchWitness(ConformanceChecker &cc, TypeChecker &tc, /*isTypeReference=*/false, /*isDynamicResult=*/false, witnessLocator, - /*base=*/nullptr, - /*opener=*/nullptr); + /*base=*/nullptr); } openWitnessType = openWitnessType->getRValueType(); // Open up the type of the requirement. We only truly open 'Self' and // its associated types (recursively); inner generic type parameters get // mapped to their archetypes directly. - DeclContext *reqDC = req->getPotentialGenericDeclContext(); - RequirementTypeOpener reqTypeOpener(*cs, conformance, reqDC); + DeclContext *reqDC = req->getInnermostDeclContext(); + llvm::DenseMap replacements; std::tie(openedFullReqType, reqType) = cs->getTypeOfMemberReference(model, req, /*isTypeReference=*/false, /*isDynamicResult=*/false, locator, /*base=*/nullptr, - &reqTypeOpener); + &replacements); + + // Bind the associated types. + auto proto = conformance->getProtocol(); + for (const auto &replacement : replacements) { + if (auto gpType = replacement.first->getAs()) { + // Record the type variable for 'Self'. + if (gpType->getDepth() == 0 && gpType->getIndex() == 0) { + cs->SelfTypeVar = replacement.second; + continue; + } + + // Replace any other type variable with the archetype within + // the requirement's context. + cs->addConstraint(ConstraintKind::Bind, + replacement.second, + ArchetypeBuilder::mapTypeIntoContext(reqDC, gpType), + locator); + + continue; + } + + // Associated type of 'self'. + if (auto assocType = getReferencedAssocTypeOfProtocol(replacement.first, + proto)) { + cs->addConstraint(ConstraintKind::Bind, + replacement.second, + conformance->getTypeWitness(assocType, nullptr) + .getReplacement(), + locator); + continue; + } + } reqType = reqType->getRValueType(); return std::make_tuple(None, reqType, openWitnessType); @@ -1292,7 +1258,7 @@ matchWitness(ConformanceChecker &cc, TypeChecker &tc, if (openedFullWitnessType->hasTypeVariable()) { // Figure out the context we're substituting into. - auto witnessDC = witness->getPotentialGenericDeclContext(); + auto witnessDC = witness->getInnermostDeclContext(); // Compute the set of substitutions we'll need for the witness. solution->computeSubstitutions(witness->getInterfaceType(), @@ -1399,7 +1365,7 @@ static Type getRequirementTypeForDisplay(TypeChecker &tc, Module *module, } } - // Replace 'Self' with the conforming type type. + // Replace 'Self' with the conforming type. if (type->isEqual(selfTy)) return conformance->getType(); @@ -1562,25 +1528,6 @@ static Substitution getArchetypeSubstitution(TypeChecker &tc, }; } -/// If the given type is a direct reference to an associated type of -/// the given protocol, return the referenced associated type. -static AssociatedTypeDecl * -getReferencedAssocTypeOfProtocol(Type type, ProtocolDecl *proto) { - if (auto dependentMember = type->getAs()) { - if (auto genericParam - = dependentMember->getBase()->getAs()) { - if (genericParam->getDepth() == 0 && genericParam->getIndex() == 0) { - if (auto assocType = dependentMember->getAssocType()) { - if (assocType->getDeclContext() == proto) - return assocType; - } - } - } - } - - return nullptr; -} - ArrayRef ConformanceChecker::getReferencedAssociatedTypes(ValueDecl *req) { // Check whether we've already cached this information. @@ -2263,7 +2210,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) { }); } - // An non-failable initializer requirement cannot be satisfied + // A non-failable initializer requirement cannot be satisfied // by a failable initializer. if (ctor->getFailability() == OTK_None) { switch (witnessCtor->getFailability()) { @@ -2922,9 +2869,9 @@ void ConformanceChecker::resolveTypeWitnesses() { // Track when we are checking type witnesses. ProtocolConformanceState initialState = Conformance->getState(); Conformance->setState(ProtocolConformanceState::CheckingTypeWitnesses); - defer([&] { + defer { Conformance->setState(initialState); - }); + }; for (auto member : Proto->getMembers()) { auto assocType = dyn_cast(member); @@ -3036,7 +2983,7 @@ void ConformanceChecker::resolveTypeWitnesses() { if (Adoptee->is()) return Type(); - // UnresolvedTypes propagated their unresolveness to any witnesses. + // UnresolvedTypes propagated their unresolvedness to any witnesses. if (Adoptee->is()) return Adoptee; @@ -3251,11 +3198,11 @@ void ConformanceChecker::resolveTypeWitnesses() { valueWitnesses.push_back({inferredReq.first, witnessReq.Witness}); if (witnessReq.Witness->getDeclContext()->isProtocolExtensionContext()) ++numValueWitnessesInProtocolExtensions; - defer([&]{ + defer { if (witnessReq.Witness->getDeclContext()->isProtocolExtensionContext()) --numValueWitnessesInProtocolExtensions; valueWitnesses.pop_back(); - }); + }; // Introduce each of the type witnesses into the hash table. bool failed = false; @@ -3450,7 +3397,7 @@ void ConformanceChecker::resolveTypeWitnesses() { NormalProtocolConformance *conformance) { auto proto = conformance->getProtocol(); tc.diagnose(failedDefaultedAssocType, - diag::default_assocated_type_req_fail, + diag::default_associated_type_req_fail, failedDefaultedWitness, failedDefaultedAssocType->getFullName(), proto->getDeclaredType(), @@ -3635,7 +3582,7 @@ void ConformanceChecker::resolveSingleWitness(ValueDecl *requirement) { // Note that we're resolving this witness. assert(ResolvingWitnesses.count(requirement) == 0 && "Currently resolving"); ResolvingWitnesses.insert(requirement); - defer([&]{ ResolvingWitnesses.erase(requirement); }); + defer { ResolvingWitnesses.erase(requirement); }; // Make sure we've validated the requirement. if (!requirement->hasType()) @@ -3732,7 +3679,7 @@ void ConformanceChecker::checkConformance() { } // Ensure that all of the requirements of the protocol have been satisfied. - // Note: the odd check for one generic parameter parameter copes with + // Note: the odd check for one generic parameter copes with // protocols nested within other generic contexts, which is ill-formed. SourceLoc noteLoc = Proto->getLoc(); if (noteLoc.isInvalid()) @@ -3934,7 +3881,7 @@ checkConformsToProtocol(TypeChecker &TC, // Note that we are checking this conformance now. conformance->setState(ProtocolConformanceState::Checking); - defer([&] { conformance->setState(ProtocolConformanceState::Complete); }); + defer { conformance->setState(ProtocolConformanceState::Complete); }; // If the protocol requires a class, non-classes are a non-starter. if (Proto->requiresClass() && !canT->getClassOrBoundGenericClass()) { @@ -4198,6 +4145,11 @@ bool TypeChecker::isProtocolExtensionUsable(DeclContext *dc, Type type, if (!protocolExtension->isConstrainedExtension()) return true; + // If the type still has parameters, the constrained extension is considered + // unusable. + if (type->hasTypeParameter()) + return false; + // Set up a constraint system where we open the generic parameters of the // protocol extension. ConstraintSystem cs(*this, dc, None); @@ -4205,7 +4157,8 @@ bool TypeChecker::isProtocolExtensionUsable(DeclContext *dc, Type type, auto genericSig = protocolExtension->getGenericSignature(); cs.openGeneric(protocolExtension, genericSig->getGenericParams(), - genericSig->getRequirements(), false, nullptr, + genericSig->getRequirements(), false, + protocolExtension->getGenericTypeContextDepth(), ConstraintLocatorBuilder(nullptr), replacements); // Bind the 'Self' type variable to the provided type. diff --git a/lib/Sema/TypeCheckREPL.cpp b/lib/Sema/TypeCheckREPL.cpp index 60141e307a335..96997a56a1a8a 100644 --- a/lib/Sema/TypeCheckREPL.cpp +++ b/lib/Sema/TypeCheckREPL.cpp @@ -1,8 +1,8 @@ -//===--- TypeCheckREPL.cpp - Type Checking for the REPL -----------------===// +//===--- TypeCheckREPL.cpp - Type Checking for the REPL -------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -166,7 +166,7 @@ struct PatternBindingPrintLHS : public ASTVisitor { ResultString += ")"; } void visitNamedPattern(NamedPattern *P) { - ResultString += P->getBodyName().str(); + ResultString += P->getBoundName().str(); } void visitAnyPattern(AnyPattern *P) { ResultString += "_"; @@ -222,31 +222,23 @@ void REPLChecker::generatePrintOfExpression(StringRef NameStr, Expr *E) { if (requirePrintDecls()) return; + TopLevelCodeDecl *newTopLevel = new (Context) TopLevelCodeDecl(&SF); + // Build function of type T->() which prints the operand. - VarDecl *Arg = new (Context) ParamDecl(/*isLet=*/true, + auto *Arg = new (Context) ParamDecl(/*isLet=*/true, SourceLoc(), Identifier(), Loc, Context.getIdentifier("arg"), - E->getType(), /*DC*/ nullptr); - Pattern *ParamPat = new (Context) NamedPattern(Arg); - ParamPat = new (Context) TypedPattern(ParamPat, - TypeLoc::withoutLoc(Arg->getType())); - TuplePatternElt elt{ParamPat}; - ParamPat = TuplePattern::create(Context, SourceLoc(), elt, SourceLoc()); - TC.typeCheckPattern(ParamPat, Arg->getDeclContext(), - TR_ImmediateFunctionInput); + E->getType(), /*DC*/ newTopLevel); + auto params = ParameterList::createWithoutLoc(Arg); - TopLevelCodeDecl *newTopLevel = new (Context) TopLevelCodeDecl(&SF); unsigned discriminator = TLC.claimNextClosureDiscriminator(); ClosureExpr *CE = - new (Context) ClosureExpr(ParamPat, SourceLoc(), SourceLoc(), SourceLoc(), + new (Context) ClosureExpr(params, SourceLoc(), SourceLoc(), SourceLoc(), TypeLoc(), discriminator, newTopLevel); - Type ParamTy = ParamPat->getType(); - ParamTy = ParamTy->getRelabeledType(TC.Context, { Identifier() }); - Type FuncTy = FunctionType::get(ParamTy, TupleType::getEmpty(Context)); - CE->setType(FuncTy); - + CE->setType(ParameterList::getFullType(TupleType::getEmpty(Context), params)); + // Convert the pattern to a string we can print. llvm::SmallString<16> PrefixString; PrefixString += "// "; diff --git a/lib/Sema/TypeCheckRequest.cpp b/lib/Sema/TypeCheckRequest.cpp index b61246246d1f2..9e0511d4a0daa 100644 --- a/lib/Sema/TypeCheckRequest.cpp +++ b/lib/Sema/TypeCheckRequest.cpp @@ -1,8 +1,8 @@ -//===--- TypeCheckRequest.h - Type Checking Request -----------------------===// +//===--- TypeCheckRequest.cpp - Type Checking Request ---------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp index f1886317b62fc..a47cd06eefe39 100644 --- a/lib/Sema/TypeCheckStmt.cpp +++ b/lib/Sema/TypeCheckStmt.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -331,7 +331,7 @@ class StmtChecker : public StmtVisitor { /// Type-check an entire function body. bool typeCheckBody(BraceStmt *&S) { - if (typeCheckStmt(S)) return true; + typeCheckStmt(S); setAutoClosureDiscriminators(DC, S); return false; } @@ -396,13 +396,12 @@ class StmtChecker : public StmtVisitor { RS->isImplicit()); } - auto failed = TC.typeCheckExpression(E, DC, ResultTy, CTP_ReturnStmt); + auto hadTypeError = TC.typeCheckExpression(E, DC, ResultTy, CTP_ReturnStmt); RS->setResult(E); - if (failed) { + if (hadTypeError) { tryDiagnoseUnnecessaryCastOverOptionSet(TC.Context, E, ResultTy, DC->getParentModule()); - return nullptr; } return RS; @@ -415,10 +414,8 @@ class StmtChecker : public StmtVisitor { Type exnType = TC.getExceptionType(DC, TS->getThrowLoc()); if (!exnType) return TS; - auto failed = TC.typeCheckExpression(E, DC, exnType, CTP_ThrowStmt); + TC.typeCheckExpression(E, DC, exnType, CTP_ThrowStmt); TS->setSubExpr(E); - - if (failed) return nullptr; return TS; } @@ -427,8 +424,7 @@ class StmtChecker : public StmtVisitor { TC.typeCheckDecl(DS->getTempDecl(), /*isFirstPass*/false); Expr *theCall = DS->getCallExpr(); - if (!TC.typeCheckExpression(theCall, DC)) - return nullptr; + TC.typeCheckExpression(theCall, DC); DS->setCallExpr(theCall); return DS; @@ -436,18 +432,17 @@ class StmtChecker : public StmtVisitor { Stmt *visitIfStmt(IfStmt *IS) { StmtCondition C = IS->getCond(); - - if (TC.typeCheckStmtCondition(C, DC, diag::if_always_true)) return 0; + TC.typeCheckStmtCondition(C, DC, diag::if_always_true); IS->setCond(C); AddLabeledStmt ifNest(*this, IS); Stmt *S = IS->getThenStmt(); - if (typeCheckStmt(S)) return 0; + typeCheckStmt(S); IS->setThenStmt(S); if ((S = IS->getElseStmt())) { - if (typeCheckStmt(S)) return 0; + typeCheckStmt(S); IS->setElseStmt(S); } @@ -456,14 +451,13 @@ class StmtChecker : public StmtVisitor { Stmt *visitGuardStmt(GuardStmt *GS) { StmtCondition C = GS->getCond(); - if (TC.typeCheckStmtCondition(C, DC, diag::guard_always_succeeds)) - return 0; + TC.typeCheckStmtCondition(C, DC, diag::guard_always_succeeds); GS->setCond(C); AddLabeledStmt ifNest(*this, GS); Stmt *S = GS->getBody(); - if (typeCheckStmt(S)) return 0; + typeCheckStmt(S); GS->setBody(S); return GS; } @@ -479,19 +473,19 @@ class StmtChecker : public StmtVisitor { Stmt *visitDoStmt(DoStmt *DS) { AddLabeledStmt loopNest(*this, DS); Stmt *S = DS->getBody(); - if (typeCheckStmt(S)) return 0; + typeCheckStmt(S); DS->setBody(S); return DS; } Stmt *visitWhileStmt(WhileStmt *WS) { StmtCondition C = WS->getCond(); - if (TC.typeCheckStmtCondition(C, DC, diag::while_always_true)) return 0; + TC.typeCheckStmtCondition(C, DC, diag::while_always_true); WS->setCond(C); AddLabeledStmt loopNest(*this, WS); Stmt *S = WS->getBody(); - if (typeCheckStmt(S)) return 0; + typeCheckStmt(S); WS->setBody(S); return WS; @@ -500,12 +494,12 @@ class StmtChecker : public StmtVisitor { { AddLabeledStmt loopNest(*this, RWS); Stmt *S = RWS->getBody(); - if (typeCheckStmt(S)) return nullptr; + typeCheckStmt(S); RWS->setBody(S); } Expr *E = RWS->getCond(); - if (TC.typeCheckCondition(E, DC)) return nullptr; + TC.typeCheckCondition(E, DC); RWS->setCond(E); return RWS; } @@ -515,30 +509,27 @@ class StmtChecker : public StmtVisitor { TC.typeCheckDecl(D, /*isFirstPass*/false); if (auto *Initializer = FS->getInitializer().getPtrOrNull()) { - if (TC.typeCheckExpression(Initializer, DC, Type(), CTP_Unused, - TypeCheckExprFlags::IsDiscarded)) - return nullptr; + TC.typeCheckExpression(Initializer, DC, Type(), CTP_Unused, + TypeCheckExprFlags::IsDiscarded); FS->setInitializer(Initializer); TC.checkIgnoredExpr(Initializer); } if (auto *Cond = FS->getCond().getPtrOrNull()) { - if (TC.typeCheckCondition(Cond, DC)) - return nullptr; + TC.typeCheckCondition(Cond, DC); FS->setCond(Cond); } if (auto *Increment = FS->getIncrement().getPtrOrNull()) { - if (TC.typeCheckExpression(Increment, DC, Type(), CTP_Unused, - TypeCheckExprFlags::IsDiscarded)) - return nullptr; + TC.typeCheckExpression(Increment, DC, Type(), CTP_Unused, + TypeCheckExprFlags::IsDiscarded); FS->setIncrement(Increment); TC.checkIgnoredExpr(Increment); } AddLabeledStmt loopNest(*this, FS); Stmt *S = FS->getBody(); - if (typeCheckStmt(S)) return nullptr; + typeCheckStmt(S); FS->setBody(S); return FS; @@ -691,7 +682,7 @@ class StmtChecker : public StmtVisitor { // Type-check the body of the loop. AddLabeledStmt loopNest(*this, S); BraceStmt *Body = S->getBody(); - if (typeCheckStmt(Body)) return nullptr; + typeCheckStmt(Body); S->setBody(Body); return S; @@ -810,14 +801,11 @@ class StmtChecker : public StmtVisitor { Stmt *visitSwitchStmt(SwitchStmt *S) { // Type-check the subject expression. Expr *subjectExpr = S->getSubjectExpr(); - bool hadTypeError = TC.typeCheckExpression(subjectExpr, DC); - subjectExpr = TC.coerceToMaterializable(subjectExpr); - - if (!subjectExpr) - return nullptr; - + TC.typeCheckExpression(subjectExpr, DC); + if (Expr *newSubjectExpr = TC.coerceToMaterializable(subjectExpr)) + subjectExpr = newSubjectExpr; S->setSubjectExpr(subjectExpr); - Type subjectType = subjectExpr->getType(); + Type subjectType = S->getSubjectExpr()->getType(); // Type-check the case blocks. AddSwitchNest switchNest(*this); @@ -835,40 +823,33 @@ class StmtChecker : public StmtVisitor { if (auto *newPattern = TC.resolvePattern(pattern, DC, /*isStmtCondition*/false)) { pattern = newPattern; - } else { - hadTypeError = true; - continue; - } - - // Coerce the pattern to the subject's type. - if (TC.coercePatternToType(pattern, DC, subjectType, TR_InExpression)) { - // If that failed, mark any variables binding pieces of the pattern - // as invalid to silence follow-on errors. - pattern->forEachVariable([&](VarDecl *VD) { - VD->overwriteType(ErrorType::get(TC.Context)); - VD->setInvalid(); - }); - hadTypeError = true; + // Coerce the pattern to the subject's type. + if (TC.coercePatternToType(pattern, DC, subjectType, + TR_InExpression)) { + // If that failed, mark any variables binding pieces of the pattern + // as invalid to silence follow-on errors. + pattern->forEachVariable([&](VarDecl *VD) { + VD->overwriteType(ErrorType::get(TC.Context)); + VD->setInvalid(); + }); + } + labelItem.setPattern(pattern); } - labelItem.setPattern(pattern); // Check the guard expression, if present. if (auto *guard = labelItem.getGuardExpr()) { - if (TC.typeCheckCondition(guard, DC)) - hadTypeError = true; - else - labelItem.setGuardExpr(guard); + TC.typeCheckCondition(guard, DC); + labelItem.setGuardExpr(guard); } } // Type-check the body statements. Stmt *body = caseBlock->getBody(); - if (typeCheckStmt(body)) - hadTypeError = true; + typeCheckStmt(body); caseBlock->setBody(body); } - return hadTypeError ? nullptr : S; + return S; } Stmt *visitCaseStmt(CaseStmt *S) { @@ -881,22 +862,20 @@ class StmtChecker : public StmtVisitor { llvm_unreachable("catch stmt outside of do-catch?!"); } - bool checkCatchStmt(CatchStmt *S) { + void checkCatchStmt(CatchStmt *S) { // Check the catch pattern. - bool hadTypeError = TC.typeCheckCatchPattern(S, DC); + TC.typeCheckCatchPattern(S, DC); // Check the guard expression, if present. if (Expr *guard = S->getGuardExpr()) { - hadTypeError |= TC.typeCheckCondition(guard, DC); + TC.typeCheckCondition(guard, DC); S->setGuardExpr(guard); } // Type-check the clause body. Stmt *body = S->getBody(); - hadTypeError |= typeCheckStmt(body); + typeCheckStmt(body); S->setBody(body); - - return hadTypeError; } Stmt *visitDoCatchStmt(DoCatchStmt *S) { @@ -905,23 +884,18 @@ class StmtChecker : public StmtVisitor { // entire construct. AddLabeledStmt loopNest(*this, S); - bool hadTypeError = false; - // Type-check the 'do' body. Type failures in here will generally // not cause type failures in the 'catch' clauses. Stmt *newBody = S->getBody(); - if (typeCheckStmt(newBody)) { - hadTypeError = true; - } else { - S->setBody(newBody); - } + typeCheckStmt(newBody); + S->setBody(newBody); // Check all the catch clauses independently. for (auto clause : S->getCatches()) { - hadTypeError |= checkCatchStmt(clause); + checkCatchStmt(clause); } - return hadTypeError ? nullptr : S; + return S; } Stmt *visitFailStmt(FailStmt *S) { @@ -934,8 +908,6 @@ class StmtChecker : public StmtVisitor { } // end anonymous namespace bool TypeChecker::typeCheckCatchPattern(CatchStmt *S, DeclContext *DC) { - bool hadTypeError = false; - // Grab the standard exception type. Type exnType = getExceptionType(DC, S->getCatchLoc()); @@ -954,15 +926,11 @@ bool TypeChecker::typeCheckCatchPattern(CatchStmt *S, DeclContext *DC) { var->overwriteType(ErrorType::get(Context)); var->setInvalid(); }); - hadTypeError = true; } S->setErrorPattern(pattern); - } else { - hadTypeError = true; } - - return hadTypeError; + return false; } void TypeChecker::checkIgnoredExpr(Expr *E) { @@ -1082,14 +1050,10 @@ Stmt *StmtChecker::visitBraceStmt(BraceStmt *BS) { if (isDiscarded) options |= TypeCheckExprFlags::IsDiscarded; - if (TC.typeCheckExpression(SubExpr, DC, Type(), CTP_Unused, options)) { - elem = SubExpr; - continue; - } - - if (isDiscarded) + bool hadTypeError = TC.typeCheckExpression(SubExpr, DC, Type(), + CTP_Unused, options); + if (isDiscarded && !hadTypeError) TC.checkIgnoredExpr(SubExpr); - elem = SubExpr; continue; } @@ -1100,8 +1064,8 @@ Stmt *StmtChecker::visitBraceStmt(BraceStmt *BS) { (Loc == EndTypeCheckLoc || SM.isBeforeInBuffer(EndTypeCheckLoc, Loc))) break; - if (!typeCheckStmt(SubStmt)) - elem = SubStmt; + typeCheckStmt(SubStmt); + elem = SubStmt; continue; } @@ -1118,75 +1082,51 @@ Stmt *StmtChecker::visitBraceStmt(BraceStmt *BS) { } /// Check the default arguments that occur within this pattern. -static void checkDefaultArguments(TypeChecker &tc, Pattern *pattern, - unsigned &nextArgIndex, - DeclContext *dc) { +static void checkDefaultArguments(TypeChecker &tc, ParameterList *params, + unsigned &nextArgIndex, DeclContext *dc) { assert(dc->isLocalContext()); - switch (pattern->getKind()) { - case PatternKind::Tuple: - for (auto &field : cast(pattern)->getElements()) { - unsigned curArgIndex = nextArgIndex++; - if (field.getInit() && - field.getPattern()->hasType() && - !field.getPattern()->getType()->is()) { - - Expr *e = field.getInit()->getExpr(); - - // Re-use an existing initializer context if possible. - auto existingContext = e->findExistingInitializerContext(); - DefaultArgumentInitializer *initContext; - if (existingContext) { - initContext = cast(existingContext); - assert(initContext->getIndex() == curArgIndex); - assert(initContext->getParent() == dc); - - // Otherwise, allocate one temporarily. - } else { - initContext = - tc.Context.createDefaultArgumentContext(dc, curArgIndex); - } - - // Type-check the initializer, then flag that we did so. - if (tc.typeCheckExpression(e, initContext,field.getPattern()->getType(), - CTP_DefaultParameter)) - field.getInit()->setExpr(field.getInit()->getExpr(), true); - else - field.getInit()->setExpr(e, true); + for (auto ¶m : *params) { + unsigned curArgIndex = nextArgIndex++; + if (!param->getDefaultValue() || !param->hasType() || + param->getType()->is()) + continue; + + auto defaultValueHandle = param->getDefaultValue(); + Expr *e = defaultValueHandle->getExpr(); + + // Re-use an existing initializer context if possible. + auto existingContext = e->findExistingInitializerContext(); + DefaultArgumentInitializer *initContext; + if (existingContext) { + initContext = cast(existingContext); + assert(initContext->getIndex() == curArgIndex); + assert(initContext->getParent() == dc); + + // Otherwise, allocate one temporarily. + } else { + initContext = + tc.Context.createDefaultArgumentContext(dc, curArgIndex); + } - tc.checkInitializerErrorHandling(initContext, e); + // Type-check the initializer, then flag that we did so. + if (tc.typeCheckExpression(e, initContext, param->getType(), + CTP_DefaultParameter)) + defaultValueHandle->setExpr(defaultValueHandle->getExpr(), true); + else + defaultValueHandle->setExpr(e, true); - // Walk the checked initializer and contextualize any closures - // we saw there. - bool hasClosures = tc.contextualizeInitializer(initContext, e); + tc.checkInitializerErrorHandling(initContext, e); - // If we created a new context and didn't run into any autoclosures - // during the walk, give the context back to the ASTContext. - if (!hasClosures && !existingContext) - tc.Context.destroyDefaultArgumentContext(initContext); - } - } - return; - case PatternKind::Paren: - return checkDefaultArguments(tc, - cast(pattern)->getSubPattern(), - nextArgIndex, - dc); - case PatternKind::Var: - return checkDefaultArguments(tc, cast(pattern)->getSubPattern(), - nextArgIndex, - dc); - case PatternKind::Typed: - case PatternKind::Named: - case PatternKind::Any: - return; + // Walk the checked initializer and contextualize any closures + // we saw there. + bool hasClosures = tc.contextualizeInitializer(initContext, e); -#define PATTERN(Id, Parent) -#define REFUTABLE_PATTERN(Id, Parent) case PatternKind::Id: -#include "swift/AST/PatternNodes.def" - llvm_unreachable("pattern can't appear in argument list!"); + // If we created a new context and didn't run into any autoclosures + // during the walk, give the context back to the ASTContext. + if (!hasClosures && !existingContext) + tc.Context.destroyDefaultArgumentContext(initContext); } - llvm_unreachable("bad pattern kind!"); } bool TypeChecker::typeCheckAbstractFunctionBodyUntil(AbstractFunctionDecl *AFD, @@ -1222,9 +1162,8 @@ bool TypeChecker::typeCheckFunctionBodyUntil(FuncDecl *FD, SourceLoc EndTypeCheckLoc) { // Check the default argument definitions. unsigned nextArgIndex = 0; - for (auto pattern : FD->getBodyParamPatterns()) { - checkDefaultArguments(*this, pattern, nextArgIndex, FD); - } + for (auto paramList : FD->getParameterLists()) + checkDefaultArguments(*this, paramList, nextArgIndex, FD); // Clang imported inline functions do not have a Swift body to // typecheck. @@ -1323,8 +1262,8 @@ bool TypeChecker::typeCheckConstructorBodyUntil(ConstructorDecl *ctor, SourceLoc EndTypeCheckLoc) { // Check the default argument definitions. unsigned nextArgIndex = 0; - for (auto pattern : ctor->getBodyParamPatterns()) - checkDefaultArguments(*this, pattern, nextArgIndex, ctor); + for (auto paramList : ctor->getParameterLists()) + checkDefaultArguments(*this, paramList, nextArgIndex, ctor); BraceStmt *body = ctor->getBody(); if (!body) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 436a98916fe6b..7c3c7d6d0c582 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -165,7 +165,7 @@ TypeChecker::getDynamicBridgedThroughObjCClass(DeclContext *dc, !dynamicType->getClassOrBoundGenericClass()) return Type(); - // If the value type canot be bridged, we're done. + // If the value type cannot be bridged, we're done. if (!valueType->isPotentiallyBridgedValueType()) return Type(); @@ -211,7 +211,7 @@ Type TypeChecker::resolveTypeInContext( // type within the context. if (auto nominal = dyn_cast(typeDecl)) { - this->forceExternalDeclMembers(nominal); + forceExternalDeclMembers(nominal); if (!nominal->getGenericParams() || !isSpecialized) { for (DeclContext *dc = fromDC; dc; dc = dc->getParent()) { @@ -240,6 +240,7 @@ Type TypeChecker::resolveTypeInContext( case DeclContextKind::AbstractClosureExpr: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: continue; case DeclContextKind::SerializedLocal: llvm_unreachable("should not be typechecking deserialized things"); @@ -304,9 +305,11 @@ Type TypeChecker::resolveTypeInContext( continue; // Search the type of this context and its supertypes. + Type superClassOfFromType; + int traversedClassHierarchyDepth = 0; for (auto fromType = resolver->resolveTypeOfContext(parentDC); fromType; - fromType = getSuperClassOf(fromType)) { + fromType = superClassOfFromType) { // If the nominal type declaration of the context type we're looking at // matches the owner's nominal type declaration, this is how we found // the member type declaration. Substitute the type we're coming from as @@ -335,6 +338,14 @@ Type TypeChecker::resolveTypeInContext( conformance) { return conformance->getTypeWitness(assocType, this).getReplacement(); } + superClassOfFromType = getSuperClassOf(fromType); + /// FIXME: Avoid the possibility of an infinite loop by fixing the root + /// cause instead (incomplete circularity detection). + assert(fromType.getPointer() != superClassOfFromType.getPointer() && + "Infinite loop due to circular class inheritance."); + assert(traversedClassHierarchyDepth++ <= 16384 && + "Infinite loop due to circular class inheritance?"); + (void) traversedClassHierarchyDepth; } } @@ -367,8 +378,10 @@ Type TypeChecker::applyGenericArguments(Type type, if (!unbound) { // FIXME: Highlight generic arguments and introduce a Fix-It to remove // them. - diagnose(loc, diag::not_a_generic_type, type); - + if (!type->is()) { + diagnose(loc, diag::not_a_generic_type, type); + } + // Just return the type; this provides better recovery anyway. return type; } @@ -733,7 +746,7 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC, } } - if (!DC->isCascadingContextForLookup(/*excludeFunctions*/true)) + if (!DC->isCascadingContextForLookup(/*excludeFunctions*/false)) options |= TR_KnownNonCascadingDependency; // The remaining lookups will be in the parent context. @@ -1207,7 +1220,7 @@ Type TypeChecker::resolveIdentifierType( // We allow a type to conform to a protocol that is less available than // the type itself. This enables a type to retroactively model or directly - // conform to a protocl only available on newer OSes and yet still be used on + // conform to a protocol only available on newer OSes and yet still be used on // older OSes. // To support this, inside inheritance clauses we allow references to // protocols that are unavailable in the current type refinement context. @@ -1339,7 +1352,13 @@ Type TypeChecker::resolveType(TypeRepr *TyR, DeclContext *DC, resolver = &defaultResolver; TypeResolver typeResolver(*this, DC, resolver, unsatisfiedDependency); - return typeResolver.resolveType(TyR, options); + auto result = typeResolver.resolveType(TyR, options); + + // If we resolved down to an error, make sure to mark the typeRepr as invalid + // so we don't produce a redundant diagnostic. + if (result && result->is()) + TyR->setInvalid(); + return result; } Type TypeResolver::resolveType(TypeRepr *repr, TypeResolutionOptions options) { @@ -1739,13 +1758,6 @@ Type TypeResolver::resolveAttributedType(TypeAttributes &attrs, attrs.clearAttribute(TAK_box); } - // Diagnose @local_storage in nested positions. - if (attrs.has(TAK_local_storage)) { - assert(DC->getParentSourceFile()->Kind == SourceFileKind::SIL); - TC.diagnose(attrs.getLoc(TAK_local_storage),diag::sil_local_storage_nested); - attrs.clearAttribute(TAK_local_storage); - } - for (unsigned i = 0; i != TypeAttrKind::TAK_Count; ++i) if (attrs.has((TypeAttrKind)i)) TC.diagnose(attrs.getLoc((TypeAttrKind)i), @@ -1761,8 +1773,7 @@ Type TypeResolver::resolveASTFunctionType(FunctionTypeRepr *repr, options | TR_ImmediateFunctionInput); if (!inputTy || inputTy->is()) return inputTy; - Type outputTy = resolveType(repr->getResultTypeRepr(), - options | TR_FunctionResult); + Type outputTy = resolveType(repr->getResultTypeRepr(), options); if (!outputTy || outputTy->is()) return outputTy; extInfo = extInfo.withThrows(repr->throws()); @@ -1839,8 +1850,7 @@ Type TypeResolver::resolveSILFunctionType(FunctionTypeRepr *repr, // For now, resolveSILResults only returns a single ordinary result. // FIXME: Deal with unsatisfied dependencies. SmallVector ordinaryResults; - if (resolveSILResults(repr->getResultTypeRepr(), - options | TR_FunctionResult, + if (resolveSILResults(repr->getResultTypeRepr(), options, ordinaryResults, errorResult)) { hasError = true; } else { @@ -1936,6 +1946,8 @@ SILParameterInfo TypeResolver::resolveSILParameter( checkFor(TypeAttrKind::TAK_in, ParameterConvention::Indirect_In); checkFor(TypeAttrKind::TAK_out, ParameterConvention::Indirect_Out); checkFor(TypeAttrKind::TAK_inout, ParameterConvention::Indirect_Inout); + checkFor(TypeAttrKind::TAK_inout_aliasable, + ParameterConvention::Indirect_InoutAliasable); checkFor(TypeAttrKind::TAK_owned, ParameterConvention::Direct_Owned); checkFor(TypeAttrKind::TAK_guaranteed, ParameterConvention::Direct_Guaranteed); @@ -2048,7 +2060,6 @@ bool TypeResolver::resolveSILResults(TypeRepr *repr, TypeResolutionOptions options, SmallVectorImpl &ordinaryResults, Optional &errorResult) { - assert(options & TR_FunctionResult && "Should be marked as a result"); // When we generalize SIL to handle multiple normal results, we // should always split up a tuple (a single level deep only). Until @@ -2076,6 +2087,7 @@ Type TypeResolver::resolveInOutType(InOutTypeRepr *repr, if (!(options & TR_FunctionInput) && !(options & TR_ImmediateFunctionInput)) { TC.diagnose(repr->getInOutLoc(), diag::inout_only_parameter); + repr->setInvalid(); return ErrorType::get(Context); } @@ -2088,14 +2100,6 @@ Type TypeResolver::resolveArrayType(ArrayTypeRepr *repr, // FIXME: diagnose non-materializability of element type! Type baseTy = resolveType(repr->getBase(), withoutContext(options)); if (!baseTy || baseTy->is()) return baseTy; - - if (ExprHandle *sizeEx = repr->getSize()) { - // FIXME: We don't support fixed-length arrays yet. - // FIXME: We need to check Size! (It also has to be convertible to int). - TC.diagnose(repr->getBrackets().Start, diag::unsupported_fixed_length_array) - .highlight(sizeEx->getExpr()->getSourceRange()); - return ErrorType::get(Context); - } auto sliceTy = TC.getArraySliceType(repr->getBrackets().Start, baseTy); if (!sliceTy) @@ -2404,37 +2408,9 @@ static void describeObjCReason(TypeChecker &TC, const ValueDecl *VD, } } -static Type getFunctionParamType(const Pattern *P) { - if (auto *TP = dyn_cast(P)) - return TP->getType(); - return {}; -} - -static SourceRange getFunctionParamTypeSourceRange(const Pattern *P) { - if (auto *TP = dyn_cast(P)) - return TP->getTypeLoc().getTypeRepr()->getSourceRange(); - return {}; -} - -static bool isParamRepresentableInObjC(TypeChecker &TC, - const DeclContext *DC, - const Pattern *P) { - // Look through 'var' pattern. - if (auto VP = dyn_cast(P)) - P = VP->getSubPattern(); - - auto *TP = dyn_cast(P); - if (!TP) - return false; - if (!TC.isRepresentableInObjC(DC, TP->getType())) - return false; - auto *SubPattern = TP->getSubPattern(); - return isa(SubPattern) || isa(SubPattern); -} - static void diagnoseFunctionParamNotRepresentable( TypeChecker &TC, const AbstractFunctionDecl *AFD, unsigned NumParams, - unsigned ParamIndex, const Pattern *P, ObjCReason Reason) { + unsigned ParamIndex, const ParamDecl *P, ObjCReason Reason) { if (Reason == ObjCReason::DoNotDiagnose) return; @@ -2445,77 +2421,68 @@ static void diagnoseFunctionParamNotRepresentable( TC.diagnose(AFD->getLoc(), diag::objc_invalid_on_func_param_type, ParamIndex + 1, getObjCDiagnosticAttrKind(Reason)); } - if (Type ParamTy = getFunctionParamType(P)) { - SourceRange SR = getFunctionParamTypeSourceRange(P); + if (P->hasType()) { + Type ParamTy = P->getType(); + SourceRange SR; + if (auto typeRepr = P->getTypeLoc().getTypeRepr()) + SR = typeRepr->getSourceRange(); TC.diagnoseTypeNotRepresentableInObjC(AFD, ParamTy, SR); } describeObjCReason(TC, AFD, Reason); } -static bool isParamPatternRepresentableInObjC(TypeChecker &TC, - const AbstractFunctionDecl *AFD, - const Pattern *P, - ObjCReason Reason) { +static bool isParamListRepresentableInObjC(TypeChecker &TC, + const AbstractFunctionDecl *AFD, + const ParameterList *PL, + ObjCReason Reason) { // If you change this function, you must add or modify a test in PrintAsObjC. bool Diagnose = (Reason != ObjCReason::DoNotDiagnose); - if (auto *TP = dyn_cast(P)) { - auto Fields = TP->getElements(); - unsigned NumParams = Fields.size(); - // Varargs are not representable in Objective-C. - if (TP->hasAnyEllipsis()) { + bool IsObjC = true; + unsigned NumParams = PL->size(); + for (unsigned ParamIndex = 0; ParamIndex != NumParams; ParamIndex++) { + auto param = PL->get(ParamIndex); + + // Swift Varargs are not representable in Objective-C. + if (param->isVariadic()) { if (Diagnose && Reason != ObjCReason::DoNotDiagnose) { - TC.diagnose(TP->getAnyEllipsisLoc(), - diag::objc_invalid_on_func_variadic, - getObjCDiagnosticAttrKind(Reason)); + TC.diagnose(param->getStartLoc(), diag::objc_invalid_on_func_variadic, + getObjCDiagnosticAttrKind(Reason)) + .highlight(param->getSourceRange()); describeObjCReason(TC, AFD, Reason); } - + return false; } - - if (NumParams == 0) - return true; - - bool IsObjC = true; - for (unsigned ParamIndex = 0; ParamIndex != NumParams; ParamIndex++) { - auto &TupleElt = Fields[ParamIndex]; - if (!isParamRepresentableInObjC(TC, AFD, TupleElt.getPattern())) { - // Permit '()' when this method overrides a method with a - // foreign error convention that replaces NSErrorPointer with () - // and this is the replaced parameter. - AbstractFunctionDecl *overridden; - if (TupleElt.getPattern()->getType()->isVoid() && - AFD->isBodyThrowing() && - (overridden = AFD->getOverriddenDecl())) { - auto foreignError = overridden->getForeignErrorConvention(); - if (foreignError && - foreignError->isErrorParameterReplacedWithVoid() && - foreignError->getErrorParameterIndex() == ParamIndex) { - continue; - } - } - - IsObjC = false; - if (!Diagnose) { - // Save some work and return as soon as possible if we are not - // producing diagnostics. - return IsObjC; - } - diagnoseFunctionParamNotRepresentable(TC, AFD, NumParams, ParamIndex, - TupleElt.getPattern(), Reason); + + if (TC.isRepresentableInObjC(AFD, param->getType())) + continue; + + // Permit '()' when this method overrides a method with a + // foreign error convention that replaces NSErrorPointer with () + // and this is the replaced parameter. + AbstractFunctionDecl *overridden; + if (param->getType()->isVoid() && AFD->isBodyThrowing() && + (overridden = AFD->getOverriddenDecl())) { + auto foreignError = overridden->getForeignErrorConvention(); + if (foreignError && + foreignError->isErrorParameterReplacedWithVoid() && + foreignError->getErrorParameterIndex() == ParamIndex) { + continue; } } - return IsObjC; - } - auto *PP = cast(P); - if (!isParamRepresentableInObjC(TC, AFD, PP->getSubPattern())) { - diagnoseFunctionParamNotRepresentable(TC, AFD, 1, 1, PP->getSubPattern(), - Reason); - return false; + + IsObjC = false; + if (!Diagnose) { + // Save some work and return as soon as possible if we are not + // producing diagnostics. + return IsObjC; + } + diagnoseFunctionParamNotRepresentable(TC, AFD, NumParams, ParamIndex, + param, Reason); } - return true; + return IsObjC; } /// Check whether the given declaration occurs within a constrained @@ -2638,19 +2605,6 @@ static bool isBridgedToObjectiveCClass(DeclContext *dc, Type type) { return classDecl->getName().str() != "NSNumber"; } -/// Determine whether this is a trailing closure type. -static AnyFunctionType *isTrailingClosure(Type type) { - // Only consider the rvalue type. - type = type->getRValueType(); - - // Look through one level of optionality. - if (auto objectType = type->getAnyOptionalObjectType()) - type = objectType; - - // Is it a function type? - return type->getAs(); -} - bool TypeChecker::isRepresentableInObjC( const AbstractFunctionDecl *AFD, ObjCReason Reason, @@ -2693,7 +2647,7 @@ bool TypeChecker::isRepresentableInObjC( unsigned ExpectedParamPatterns = 1; if (FD->getImplicitSelfDecl()) ExpectedParamPatterns++; - if (FD->getBodyParamPatterns().size() != ExpectedParamPatterns) { + if (FD->getParameterLists().size() != ExpectedParamPatterns) { if (Diagnose) { diagnose(AFD->getLoc(), diag::objc_invalid_on_func_curried, getObjCDiagnosticAttrKind(Reason)); @@ -2729,9 +2683,8 @@ bool TypeChecker::isRepresentableInObjC( isSpecialInit = init->isObjCZeroParameterWithLongSelector(); if (!isSpecialInit && - !isParamPatternRepresentableInObjC(*this, AFD, - AFD->getBodyParamPatterns()[1], - Reason)) { + !isParamListRepresentableInObjC(*this, AFD, AFD->getParameterList(1), + Reason)) { if (!Diagnose) { // Return as soon as possible if we are not producing diagnostics. return false; @@ -2866,18 +2819,23 @@ bool TypeChecker::isRepresentableInObjC( // If the selector did not provide an index for the error, find // the last parameter that is not a trailing closure. if (!foundErrorParameterIndex) { - const Pattern *paramPattern = AFD->getBodyParamPatterns()[1]; - if (auto *tuple = dyn_cast(paramPattern)) { - errorParameterIndex = tuple->getNumElements(); - while (errorParameterIndex > 0 && - isTrailingClosure( - tuple->getElement(errorParameterIndex - 1).getPattern() - ->getType())) - --errorParameterIndex; - } else { - auto paren = cast(paramPattern); - errorParameterIndex - = isTrailingClosure(paren->getSubPattern()->getType()) ? 0 : 1; + auto *paramList = AFD->getParameterList(1); + errorParameterIndex = paramList->size(); + while (errorParameterIndex > 0) { + // Skip over trailing closures. + auto type = paramList->get(errorParameterIndex - 1)->getType(); + + // It can't be a trailing closure unless it has a specific form. + // Only consider the rvalue type. + type = type->getRValueType(); + + // Look through one level of optionality. + if (auto objectType = type->getAnyOptionalObjectType()) + type = objectType; + + // Is it a function type? + if (!type->is()) break; + --errorParameterIndex; } } @@ -2985,6 +2943,9 @@ bool TypeChecker::isRepresentableInObjC(const SubscriptDecl *SD, if (TupleTy->getNumElements() == 1 && !TupleTy->getElement(0).isVararg()) IndicesType = TupleTy->getElementType(0); } + + if (IndicesType->is()) + return false; bool IndicesResult = isRepresentableInObjC(SD->getDeclContext(), IndicesType); bool ElementResult = isRepresentableInObjC(SD->getDeclContext(), diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp index df90413e5b874..7c29a2c000c7a 100644 --- a/lib/Sema/TypeChecker.cpp +++ b/lib/Sema/TypeChecker.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -27,6 +27,7 @@ #include "swift/AST/PrettyStackTrace.h" #include "swift/AST/TypeRefinementContext.h" #include "swift/Basic/STLExtras.h" +#include "swift/Basic/Timer.h" #include "swift/ClangImporter/ClangImporter.h" #include "swift/Parse/Lexer.h" #include "swift/Sema/CodeCompletionTypeChecking.h" @@ -511,13 +512,18 @@ void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC, // Make sure that name binding has been completed before doing any type // checking. - performNameBinding(SF, StartElem); + { + SharedTimer timer("Name binding"); + performNameBinding(SF, StartElem); + } auto &Ctx = SF.getASTContext(); { // NOTE: The type checker is scoped to be torn down before AST // verification. TypeChecker TC(Ctx); + SharedTimer timer("Type checking / Semantic analysis"); + auto &DefinedFunctions = TC.definedFunctions; if (Options.contains(TypeCheckingFlags::DebugTimeFunctionBodies)) TC.enableDebugTimeFunctionBodies(); @@ -609,16 +615,19 @@ void swift::performTypeChecking(SourceFile &SF, TopLevelContext &TLC, // Verify that we've checked types correctly. SF.ASTStage = SourceFile::TypeChecked; - // Verify the SourceFile. - verify(SF); + { + SharedTimer timer("AST verification"); + // Verify the SourceFile. + verify(SF); - // Verify imported modules. + // Verify imported modules. #ifndef NDEBUG - if (SF.Kind != SourceFileKind::REPL && - !Ctx.LangOpts.DebuggerSupport) { - Ctx.verifyAllLoadedModules(); - } + if (SF.Kind != SourceFileKind::REPL && + !Ctx.LangOpts.DebuggerSupport) { + Ctx.verifyAllLoadedModules(); + } #endif + } } void swift::performWholeModuleTypeChecking(SourceFile &SF) { @@ -838,7 +847,7 @@ class TypeRefinementContextBuilder : private ASTWalker { /// A mapping from abstract storage declarations with accessors to /// to the type refinement contexts for those declarations. We refer to - /// this map to determine the appopriate parent TRC to use when + /// this map to determine the appropriate parent TRC to use when /// walking the accessor function. llvm::DenseMap StorageContexts; @@ -1386,7 +1395,7 @@ TypeChecker::overApproximateOSVersionsAtLocation(SourceLoc loc, SourceFile *SF = DC->getParentSourceFile(); // If our source location is invalid (this may be synthesized code), climb - // the decl context hierarchy until until we find a location that is valid, + // the decl context hierarchy until we find a location that is valid, // collecting availability ranges on the way up. // We will combine the version ranges from these annotations // with the TRC for the valid location to overapproximate the running @@ -1585,7 +1594,7 @@ class InnermostAncestorFinder : private ASTWalker { } /// Once we have found the target node, look for the innermost ancestor - /// matching our criteria on the way back up the spine of of the tree. + /// matching our criteria on the way back up the spine of the tree. bool walkToNodePost(ASTNode Node) { if (!InnermostMatchingNode.hasValue() && Predicate(Node, Parent)) { assert(Node.getSourceRange().isInvalid() || @@ -1792,9 +1801,9 @@ static const Decl *ancestorTypeLevelDeclForAvailabilityFixit(const Decl *D) { /// /// \param FoundVersionCheckNode Returns a node that can be wrapped in a /// if #available(...) { ... } version check to fix the unavailable reference, -/// or None if such such a node cannot be found. +/// or None if such a node cannot be found. /// -/// \param FoundMemberLevelDecl Returns memember-level declaration (i.e., the +/// \param FoundMemberLevelDecl Returns member-level declaration (i.e., the /// child of a type DeclContext) for which an @available attribute would /// fix the unavailable reference. /// @@ -2205,8 +2214,9 @@ static bool isInsideDeprecatedDeclaration(SourceRange ReferenceRange, void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange, const DeclContext *ReferenceDC, const AvailableAttr *Attr, - DeclName Name) { - // We match the behavior of clang to not report deprecation warnigs + DeclName Name, + std::function extraInfoHandler) { + // We match the behavior of clang to not report deprecation warnings // inside declarations that are themselves deprecated on all deployment // targets. if (isInsideDeprecatedDeclaration(ReferenceRange, ReferenceDC, *this)) { @@ -2230,24 +2240,30 @@ void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange, DeprecatedVersion = Attr->Deprecated.getValue(); if (Attr->Message.empty() && Attr->Rename.empty()) { - diagnose(ReferenceRange.Start, diag::availability_deprecated, Name, - Attr->hasPlatform(), Platform, Attr->Deprecated.hasValue(), - DeprecatedVersion) - .highlight(Attr->getRange()); + auto diagValue = std::move( + diagnose(ReferenceRange.Start, diag::availability_deprecated, Name, + Attr->hasPlatform(), Platform, Attr->Deprecated.hasValue(), + DeprecatedVersion) + .highlight(Attr->getRange())); + extraInfoHandler(diagValue); return; } if (Attr->Message.empty()) { - diagnose(ReferenceRange.Start, diag::availability_deprecated_rename, Name, - Attr->hasPlatform(), Platform, Attr->Deprecated.hasValue(), - DeprecatedVersion, Attr->Rename) - .highlight(Attr->getRange()); + auto diagValue = std::move( + diagnose(ReferenceRange.Start, diag::availability_deprecated_rename, Name, + Attr->hasPlatform(), Platform, Attr->Deprecated.hasValue(), + DeprecatedVersion, Attr->Rename) + .highlight(Attr->getRange())); + extraInfoHandler(diagValue); } else { EncodedDiagnosticMessage EncodedMessage(Attr->Message); - diagnose(ReferenceRange.Start, diag::availability_deprecated_msg, Name, - Attr->hasPlatform(), Platform, Attr->Deprecated.hasValue(), - DeprecatedVersion, EncodedMessage.Message) - .highlight(Attr->getRange()); + auto diagValue = std::move( + diagnose(ReferenceRange.Start, diag::availability_deprecated_msg, Name, + Attr->hasPlatform(), Platform, Attr->Deprecated.hasValue(), + DeprecatedVersion, EncodedMessage.Message) + .highlight(Attr->getRange())); + extraInfoHandler(diagValue); } if (!Attr->Rename.empty()) { diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index f47c431ecb9af..ea44419f67276 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -194,6 +194,10 @@ enum class TypeCheckExprFlags { /// statement. This should only be used for syntactic restrictions, and should /// not affect type checking itself. IsExprStmt = 0x20, + + /// If set, this expression is being re-type checked as part of diagnostics, + /// and so we should not visit bodies of non-single expression closures. + SkipMultiStmtClosures = 0x40, }; typedef OptionSet TypeCheckExprOptions; @@ -297,9 +301,6 @@ enum TypeResolutionFlags : unsigned { /// Whether to allow unspecified types within a pattern. TR_AllowUnspecifiedTypes = 0x01, - /// Whether the pattern is variadic. - TR_Variadic = 0x02, - /// Whether the given type can override the type of a typed pattern. TR_OverrideType = 0x04, @@ -316,9 +317,6 @@ enum TypeResolutionFlags : unsigned { /// Whether this is the immediate input type to a function type, TR_ImmediateFunctionInput = 0x40, - /// Whether we are in the result type of a function type. - TR_FunctionResult = 0x80, - /// Whether we are in the result type of a function body that is /// known to produce dynamic Self. TR_DynamicSelfResult = 0x100, @@ -365,6 +363,9 @@ enum TypeResolutionFlags : unsigned { /// Whether we should resolve only the structure of the resulting /// type rather than its complete semantic properties. TR_ResolveStructure = 0x100000, + + /// Whether this is the type of an editor placeholder. + TR_EditorPlaceholder = 0x200000, }; /// Option set describing how type resolution should work. @@ -380,7 +381,6 @@ static inline TypeResolutionOptions withoutContext(TypeResolutionOptions options) { options -= TR_ImmediateFunctionInput; options -= TR_FunctionInput; - options -= TR_FunctionResult; options -= TR_EnumCase; return options; } @@ -778,9 +778,9 @@ class TypeChecker final : public LazyResolver { /// \brief Determine whether a constraint of the given kind can be satisfied /// by the two types. /// - /// \param t1 The first type of the constrant. + /// \param t1 The first type of the constraint. /// - /// \param t2 The second type of the constrant. + /// \param t2 The second type of the constraint. /// /// \param dc The context of the conversion. /// @@ -1140,7 +1140,7 @@ class TypeChecker final : public LazyResolver { /// of printing diagnostics. /// /// \returns a CheckedCastKind indicating the semantics of the cast. If the - /// cast is invald, Unresolved is returned. If the cast represents an implicit + /// cast is invalid, Unresolved is returned. If the cast represents an implicit /// conversion, Coercion is returned. CheckedCastKind typeCheckCheckedCast(Type fromType, Type toType, @@ -1201,6 +1201,11 @@ class TypeChecker final : public LazyResolver { bool typeCheckCatchPattern(CatchStmt *S, DeclContext *dc); + /// Type check a parameter list. + bool typeCheckParameterList(ParameterList *PL, DeclContext *dc, + TypeResolutionOptions options, + GenericTypeResolver *resolver = nullptr); + /// Coerce a pattern to the given type. /// /// \param P The pattern, which may be modified by this coercion. @@ -1216,6 +1221,13 @@ class TypeChecker final : public LazyResolver { bool typeCheckExprPattern(ExprPattern *EP, DeclContext *DC, Type type); + /// Coerce the specified parameter list of a ClosureExpr to the specified + /// contextual type. + /// + /// \returns true if an error occurred, false otherwise. + bool coerceParameterListToType(ParameterList *P, DeclContext *dc, Type type); + + /// Type-check an initialized variable pattern declaration. bool typeCheckBinding(Pattern *&P, Expr *&Init, DeclContext *DC); bool typeCheckPatternBinding(PatternBindingDecl *PBD, unsigned patternNumber); @@ -1481,8 +1493,7 @@ class TypeChecker final : public LazyResolver { /// marked as unavailable, either through "unavailable" or "obsoleted=". bool diagnoseExplicitUnavailability(const ValueDecl *D, SourceRange R, - const DeclContext *DC, - const Expr *ParentExpr); + const DeclContext *DC); /// @} @@ -1583,7 +1594,7 @@ class TypeChecker final : public LazyResolver { /// @{ /// \brief Returns true if the availability of the overriding declaration - /// makes it a safe override, given the availability of the base declation. + /// makes it a safe override, given the availability of the base declaration. bool isAvailabilitySafeForOverride(ValueDecl *override, ValueDecl *base); /// \brief Returns true if the availability of the witness @@ -1596,7 +1607,7 @@ class TypeChecker final : public LazyResolver { VersionRange &requiredRange); /// Returns an over-approximation of the range of operating system versions - /// that could the passed-in location location could be executing upon for + /// that could the passed-in location could be executing upon for /// the target platform. VersionRange overApproximateOSVersionsAtLocation(SourceLoc loc, const DeclContext *DC); @@ -1682,10 +1693,14 @@ class TypeChecker final : public LazyResolver { static const AvailableAttr *getDeprecated(const Decl *D); /// Emits a diagnostic for a reference to a declaration that is deprecated. + /// Callers can provide a lambda that adds additional information (such as a + /// fixit hint) to the deprecation diagnostic, if it is emitted. void diagnoseDeprecated(SourceRange SourceRange, const DeclContext *ReferenceDC, const AvailableAttr *Attr, - DeclName Name); + DeclName Name, + std::function extraInfoHandler = + [](InFlightDiagnostic&){}); /// @} /// If LangOptions::DebugForbidTypecheckPrefix is set and the given decl diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index 37e80cd204e64..ed52d3c9d5753 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -270,10 +270,55 @@ getActualDefaultArgKind(uint8_t raw) { return swift::DefaultArgumentKind::Function; case serialization::DefaultArgumentKind::DSOHandle: return swift::DefaultArgumentKind::DSOHandle; + case serialization::DefaultArgumentKind::Nil: + return swift::DefaultArgumentKind::Nil; + case serialization::DefaultArgumentKind::EmptyArray: + return swift::DefaultArgumentKind::EmptyArray; + case serialization::DefaultArgumentKind::EmptyDictionary: + return swift::DefaultArgumentKind::EmptyDictionary; } return None; } +ParameterList *ModuleFile::readParameterList() { + using namespace decls_block; + + SmallVector scratch; + auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd); + unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch); + assert(recordID == PARAMETERLIST); + (void) recordID; + unsigned numParams; + decls_block::ParameterListLayout::readRecord(scratch, numParams); + + SmallVector params; + for (unsigned i = 0; i != numParams; ++i) { + scratch.clear(); + auto entry = DeclTypeCursor.advance(AF_DontPopBlockAtEnd); + unsigned recordID = DeclTypeCursor.readRecord(entry.ID, scratch); + assert(recordID == PARAMETERLIST_ELT); + (void) recordID; + + DeclID paramID; + bool isVariadic; + uint8_t rawDefaultArg; + decls_block::ParameterListEltLayout::readRecord(scratch, paramID, + isVariadic, rawDefaultArg); + + + auto decl = cast(getDecl(paramID)); + decl->setVariadic(isVariadic); + + // Decode the default argument kind. + // FIXME: Default argument expression, if available. + if (auto defaultArg = getActualDefaultArgKind(rawDefaultArg)) + decl->setDefaultArgumentKind(*defaultArg); + params.push_back(decl); + } + + return ParameterList::create(getContext(), params); +} + Pattern *ModuleFile::maybeReadPattern() { using namespace decls_block; @@ -319,25 +364,12 @@ Pattern *ModuleFile::maybeReadPattern() { // FIXME: Add something for this record or remove it. IdentifierID labelID; - uint8_t rawDefaultArg; - bool hasEllipsis; - TuplePatternEltLayout::readRecord(scratch, labelID, hasEllipsis, - rawDefaultArg); + TuplePatternEltLayout::readRecord(scratch, labelID); Identifier label = getIdentifier(labelID); Pattern *subPattern = maybeReadPattern(); assert(subPattern); - - // Decode the default argument kind. - // FIXME: Default argument expression, if available. - swift::DefaultArgumentKind defaultArgKind - = swift::DefaultArgumentKind::None; - if (auto defaultArg = getActualDefaultArgKind(rawDefaultArg)) - defaultArgKind = *defaultArg; - - elements.push_back(TuplePatternElt(label, SourceLoc(), subPattern, - hasEllipsis, SourceLoc(), - nullptr, defaultArgKind)); + elements.push_back(TuplePatternElt(label, SourceLoc(), subPattern)); } auto result = TuplePattern::create(getContext(), SourceLoc(), @@ -579,6 +611,11 @@ ModuleFile::maybeReadSubstitution(llvm::BitstreamCursor &cursor) { replacementID, numConformances); + if (&cursor == &SILCursor) { + assert(Types[archetypeID-1].isComplete() && + "SIL substitutions should always reference existing archetypes"); + } + auto archetypeTy = getType(archetypeID)->castTo(); auto replacementTy = getType(replacementID); @@ -1436,6 +1473,8 @@ DeclContext *ModuleFile::getDeclContext(DeclContextID DCID) { declContextOrOffset = ED; } else if (auto AFD = dyn_cast(D)) { declContextOrOffset = AFD; + } else if (auto SD = dyn_cast(D)) { + declContextOrOffset = SD; } else { llvm_unreachable("Unknown Decl : DeclContext kind"); } @@ -1486,7 +1525,7 @@ Module *ModuleFile::getModule(ArrayRef name) { } -/// Translate from the Serialization assocativity enum values to the AST +/// Translate from the Serialization associativity enum values to the AST /// strongly-typed enum. /// /// The former is guaranteed to be stable, but may not reflect this version of @@ -1947,6 +1986,21 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional ForcedContext) { break; } + case decls_block::MigrationId_DECL_ATTR: { + uint64_t endOfIdentIndex; + serialization::decls_block::MigrationIdDeclAttrLayout::readRecord( + scratch, endOfIdentIndex); + + StringRef ident = blobData.substr(0, endOfIdentIndex); + StringRef pattern = blobData.substr(endOfIdentIndex); + Attr = new (ctx) MigrationIdAttr(SourceLoc(), SourceLoc(), + SourceLoc(), + ctx.AllocateCopy(ident), + ctx.AllocateCopy(pattern), + SourceLoc(), /*isImplicit=*/false); + break; + } + #define SIMPLE_DECL_ATTR(NAME, CLASS, ...) \ case decls_block::CLASS##_DECL_ATTR: { \ bool isImplicit; \ @@ -2229,17 +2283,22 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional ForcedContext) { return nullptr; } - Pattern *bodyParams0 = maybeReadPattern(); - Pattern *bodyParams1 = maybeReadPattern(); - assert(bodyParams0&&bodyParams1 && "missing body patterns for constructor"); - ctor->setBodyParams(bodyParams0, bodyParams1); + auto *bodyParams0 = readParameterList(); + bodyParams0->get(0)->setImplicit(); // self is implicit. + + auto *bodyParams1 = readParameterList(); + assert(bodyParams0 && bodyParams1 && "missing parameters for constructor"); + ctor->setParameterLists(bodyParams0->get(0), bodyParams1); // This must be set after recording the constructor in the map. // A polymorphic constructor type needs to refer to the constructor to get // its generic parameters. ctor->setType(getType(signatureID)); - if (auto interfaceType = getType(interfaceID)) + if (auto interfaceType = getType(interfaceID)) { + if (auto genericFnType = interfaceType->getAs()) + ctor->setGenericSignature(genericFnType->getGenericSignature()); ctor->setInterfaceType(interfaceType); + } // Set the initializer type of the constructor. auto allocType = ctor->getType(); @@ -2480,19 +2539,21 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional ForcedContext) { fn->setType(signature); // Set the interface type. - if (auto interfaceType = getType(interfaceTypeID)) + if (auto interfaceType = getType(interfaceTypeID)) { + if (auto genericFnType = interfaceType->getAs()) + fn->setGenericSignature(genericFnType->getGenericSignature()); fn->setInterfaceType(interfaceType); + } - SmallVector patternBuf; - while (Pattern *pattern = maybeReadPattern()) - patternBuf.push_back(pattern); - - assert(!patternBuf.empty()); - assert((patternBuf.size() == numParamPatterns) && - "incorrect number of parameters"); + SmallVector paramLists; + for (unsigned i = 0, e = numParamPatterns; i != e; ++i) + paramLists.push_back(readParameterList()); - ArrayRef patterns(patternBuf); - fn->setDeserializedSignature(patterns, + // If the first parameter list is (self), mark it implicit. + if (numParamPatterns && DC->isTypeContext()) + paramLists[0]->get(0)->setImplicit(); + + fn->setDeserializedSignature(paramLists, TypeLoc::withoutLoc(signature->getResult())); if (auto errorConvention = maybeReadForeignErrorConvention()) @@ -2908,23 +2969,19 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional ForcedContext) { if (declOrOffset.isComplete()) return declOrOffset; - Pattern *indices = maybeReadPattern(); - assert(indices); - - auto elemTy = TypeLoc::withoutLoc(getType(elemTypeID)); - if (declOrOffset.isComplete()) - return declOrOffset; - // Resolve the name ids. SmallVector argNames; for (auto argNameID : argNameIDs) argNames.push_back(getIdentifier(argNameID)); DeclName name(ctx, ctx.Id_subscript, argNames); - auto subscript = createDecl(name, SourceLoc(), indices, - SourceLoc(), elemTy, DC); + auto subscript = createDecl(name, SourceLoc(), nullptr, + SourceLoc(), TypeLoc(), DC); declOrOffset = subscript; + subscript->setIndices(readParameterList()); + subscript->getElementTypeLoc() = TypeLoc::withoutLoc(getType(elemTypeID)); + configureStorage(subscript, rawStorageKind, getterID, setterID, materializeForSetID, addressorID, mutableAddressorID, willSetID, didSetID); @@ -3049,9 +3106,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional ForcedContext) { declOrOffset = dtor; dtor->setAccessibility(cast(DC)->getFormalAccess()); - Pattern *selfParams = maybeReadPattern(); + auto *selfParams = readParameterList(); + selfParams->get(0)->setImplicit(); // self is implicit. + assert(selfParams && "Didn't get self pattern?"); - dtor->setSelfPattern(selfParams); + dtor->setSelfDecl(selfParams->get(0)); dtor->setType(getType(signatureID)); dtor->setInterfaceType(getType(interfaceID)); @@ -3152,6 +3211,7 @@ Optional getActualParameterConvention(uint8_t raw) { CASE(Indirect_In) CASE(Indirect_Out) CASE(Indirect_Inout) + CASE(Indirect_InoutAliasable) CASE(Indirect_In_Guaranteed) CASE(Direct_Owned) CASE(Direct_Unowned) @@ -3892,9 +3952,7 @@ Type ModuleFile::getType(TypeID TID) { return typeOrOffset; } -void ModuleFile::loadAllMembers(Decl *D, - uint64_t contextData, - bool *) { +void ModuleFile::loadAllMembers(Decl *D, uint64_t contextData) { PrettyStackTraceDecl trace("loading members for", D); BCOffsetRAII restoreOffset(DeclTypeCursor); @@ -3955,6 +4013,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance, SmallVector scratch; unsigned kind = DeclTypeCursor.readRecord(entry.ID, scratch); + (void) kind; assert(kind == NORMAL_PROTOCOL_CONFORMANCE && "registered lazy loader incorrectly"); NormalProtocolConformanceLayout::readRecord(scratch, protoID, @@ -3975,23 +4034,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance, auto second = cast_or_null(getDecl(*rawIDIter++)); assert(second || first->getAttrs().hasAttribute() || first->getAttrs().isUnavailable(ctx)); - - unsigned substitutionCount = *rawIDIter++; - - SmallVector substitutions; - while (substitutionCount--) { - auto sub = maybeReadSubstitution(DeclTypeCursor); - assert(sub.hasValue()); - substitutions.push_back(sub.getValue()); - } - - ConcreteDeclRef witness; - if (substitutions.empty()) - witness = ConcreteDeclRef(second); - else - witness = ConcreteDeclRef(ctx, second, substitutions); - - witnesses.insert(std::make_pair(first, witness)); + witnesses.insert(std::make_pair(first, second)); } assert(rawIDIter <= rawIDs.end() && "read too much"); diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index e94c411697285..7f8b379a22e87 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -293,11 +293,10 @@ static SILFunction *createBogusSILFunction(SILModule &M, StringRef name, SILType type) { SourceLoc loc; - return SILFunction::create(M, SILLinkage::Private, name, - type.castTo(), - nullptr, SILFileLocation(loc), IsNotBare, - IsNotTransparent, IsNotFragile, IsNotThunk, - SILFunction::NotRelevant); + return M.getOrCreateFunction( + SILLinkage::Private, name, type.castTo(), nullptr, + SILFileLocation(loc), IsNotBare, IsNotTransparent, IsNotFragile, + IsNotThunk, SILFunction::NotRelevant); } /// Helper function to find a SILFunction, given its name and type. @@ -336,7 +335,7 @@ SILFunction *SILDeserializer::getFuncForReference(StringRef name) { } /// Helper function to find a SILGlobalVariable given its name. It first checks -/// in the module. If we can not find it in the module, we attempt to +/// in the module. If we cannot find it in the module, we attempt to /// deserialize it. SILGlobalVariable *SILDeserializer::getGlobalForReference(StringRef name) { // Check to see if we have a global by this name already. @@ -384,12 +383,11 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID, TypeID funcTyID; unsigned rawLinkage, isTransparent, isFragile, isThunk, isGlobal, inlineStrategy, effect; - IdentifierID SemanticsID; + ArrayRef SemanticsIDs; // TODO: read fragile - SILFunctionLayout::readRecord(scratch, rawLinkage, - isTransparent, isFragile, isThunk, isGlobal, - inlineStrategy, effect, funcTyID, - SemanticsID); + SILFunctionLayout::readRecord(scratch, rawLinkage, isTransparent, isFragile, + isThunk, isGlobal, inlineStrategy, effect, + funcTyID, SemanticsIDs); if (funcTyID == 0) { DEBUG(llvm::dbgs() << "SILFunction typeID is 0.\n"); @@ -435,17 +433,16 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID, // Otherwise, create a new function. } else { - fn = SILFunction::create(SILMod, linkage.getValue(), name, - ty.castTo(), - nullptr, loc, - IsNotBare, IsTransparent_t(isTransparent == 1), - IsFragile_t(isFragile == 1), - IsThunk_t(isThunk), SILFunction::NotRelevant, - (Inline_t)inlineStrategy); + fn = SILMod.getOrCreateFunction( + linkage.getValue(), name, ty.castTo(), nullptr, loc, + IsNotBare, IsTransparent_t(isTransparent == 1), + IsFragile_t(isFragile == 1), IsThunk_t(isThunk), + SILFunction::NotRelevant, (Inline_t)inlineStrategy); fn->setGlobalInit(isGlobal == 1); fn->setEffectsKind((EffectsKind)effect); - if (SemanticsID) - fn->setSemanticsAttr(MF->getIdentifier(SemanticsID).str()); + for (auto ID : SemanticsIDs) { + fn->addSemanticsAttr(MF->getIdentifier(ID).str()); + } if (Callback) Callback->didDeserialize(MF->getAssociatedModule(), fn); } @@ -538,7 +535,7 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID, // If CurrentBB is empty, just return fn. The code in readSILInstruction // assumes that such a situation means that fn is a declaration. Thus it // is using return false to mean two different things, error a failure - // occured and this is a declaration. Work around that for now. + // occurred and this is a declaration. Work around that for now. if (!CurrentBB) return fn; @@ -1195,8 +1192,6 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB, UNARY_INSTRUCTION(StrongUnpin) UNARY_INSTRUCTION(StrongRetain) UNARY_INSTRUCTION(StrongRelease) - UNARY_INSTRUCTION(StrongRetainAutoreleased) - UNARY_INSTRUCTION(AutoreleaseReturn) UNARY_INSTRUCTION(StrongRetainUnowned) UNARY_INSTRUCTION(UnownedRetain) UNARY_INSTRUCTION(UnownedRelease) @@ -1206,6 +1201,15 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB, UNARY_INSTRUCTION(DebugValueAddr) #undef UNARY_INSTRUCTION + case ValueKind::LoadUnownedInst: { + auto Ty = MF->getType(TyID); + bool isTake = (Attr > 0); + ResultVal = Builder.createLoadUnowned(Loc, + getLocalValue(ValID, ValResNum, + getSILType(Ty, (SILValueCategory)TyCategory)), + IsTake_t(isTake)); + break; + } case ValueKind::LoadWeakInst: { auto Ty = MF->getType(TyID); bool isTake = (Attr > 0); @@ -1231,6 +1235,18 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn, SILBasicBlock *BB, getLocalValue(ValID2, ValResNum2, addrType)); break; } + case ValueKind::StoreUnownedInst: { + auto Ty = MF->getType(TyID); + SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory); + auto refType = addrType.getAs(); + auto ValType = SILType::getPrimitiveObjectType(refType.getReferentType()); + bool isInit = (Attr > 0); + ResultVal = Builder.createStoreUnowned(Loc, + getLocalValue(ValID, ValResNum, ValType), + getLocalValue(ValID2, ValResNum2, addrType), + IsInitialization_t(isInit)); + break; + } case ValueKind::StoreWeakInst: { auto Ty = MF->getType(TyID); SILType addrType = getSILType(Ty, (SILValueCategory)TyCategory); @@ -2101,8 +2117,8 @@ void SILDeserializer::getAllWitnessTables() { SILWitnessTable * SILDeserializer::lookupWitnessTable(SILWitnessTable *existingWt) { - assert(existingWt && "Can not deserialize a null witness table declaration."); - assert(existingWt->isDeclaration() && "Can not deserialize a witness table " + assert(existingWt && "Cannot deserialize a null witness table declaration."); + assert(existingWt->isDeclaration() && "Cannot deserialize a witness table " "definition."); // If we don't have a witness table list, we can't look anything up. diff --git a/lib/Serialization/DeserializeSIL.h b/lib/Serialization/DeserializeSIL.h index 3f3bbcd9c55f3..ca9be7ced6948 100644 --- a/lib/Serialization/DeserializeSIL.h +++ b/lib/Serialization/DeserializeSIL.h @@ -1,8 +1,8 @@ -//===--- DeserializeSIL.h - Read SIL ---------------------------*- C++ -*--===// +//===--- DeserializeSIL.h - Read SIL ----------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp index a792a1073871d..f4cf6049c4f18 100644 --- a/lib/Serialization/ModuleFile.cpp +++ b/lib/Serialization/ModuleFile.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -1220,7 +1220,7 @@ void ModuleFile::getImportDecls(SmallVectorImpl &Results) { if (!M) { // The dependency module could not be loaded. Just make a guess - // about the import kind, we can not do better. + // about the import kind, we cannot do better. Kind = ImportKind::Func; } else { SmallVector Decls; @@ -1229,7 +1229,7 @@ void ModuleFile::getImportDecls(SmallVectorImpl &Results) { nullptr, Decls); Optional FoundKind = ImportDecl::findBestImportKind(Decls); assert(FoundKind.hasValue() && - "deserialized imports should not be ambigous"); + "deserialized imports should not be ambiguous"); Kind = *FoundKind; } @@ -1466,7 +1466,7 @@ Optional ModuleFile::getCommentForDecl(const Decl *D) { // Keep these as assertions instead of early exits to ensure that we are not // doing extra work. These cases should be handled by clients of this API. assert(!D->hasClangNode() && - "can not find comments for Clang decls in Swift modules"); + "cannot find comments for Clang decls in Swift modules"); assert(D->getDeclContext()->getModuleScopeContext() == FileContext && "Decl is from a different serialized file"); diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h index 4a7181a692a6a..5e5a16ec15e90 100644 --- a/lib/Serialization/SILFormat.h +++ b/lib/Serialization/SILFormat.h @@ -1,8 +1,8 @@ -//===--- SILFormat.h - The internals of serialized SILs --------*- C++ -*-===// +//===--- SILFormat.h - The internals of serialized SILs ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -216,19 +216,18 @@ namespace sil_block { BCFixed<1> // Is this a let variable. >; - using SILFunctionLayout = BCRecordLayout< - SIL_FUNCTION, - SILLinkageField, - BCFixed<1>, // transparent - BCFixed<1>, // fragile - BCFixed<2>, // thunk/reabstraction_thunk - BCFixed<1>, // global_init - BCFixed<2>, // inlineStrategy - BCFixed<2>, // side effect info. - TypeIDField, - IdentifierIDField // Semantics Attribute - // followed by generic param list, if any - >; + using SILFunctionLayout = + BCRecordLayout, // transparent + BCFixed<1>, // fragile + BCFixed<2>, // thunk/reabstraction_thunk + BCFixed<1>, // global_init + BCFixed<2>, // inlineStrategy + BCFixed<2>, // side effect info. + TypeIDField, + BCArray // Semantics Attribute + // followed by generic param list, if any + >; // Has an optional argument list where each argument is a typed valueref. using SILBasicBlockLayout = BCRecordLayout< diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 09d09dc5ee37c..fba90fdf4b2b7 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,6 +25,7 @@ #include "swift/Basic/FileSystem.h" #include "swift/Basic/STLExtras.h" #include "swift/Basic/SourceManager.h" +#include "swift/Basic/Timer.h" #include "swift/ClangImporter/ClangImporter.h" #include "swift/ClangImporter/ClangModule.h" #include "swift/Serialization/SerializationOptions.h" @@ -163,7 +164,8 @@ static ASTContext &getContext(ModuleOrSourceFile DC) { } static bool shouldSerializeAsLocalContext(const DeclContext *DC) { - return DC->isLocalContext() && !isa(DC); + return DC->isLocalContext() && !isa(DC) && + !isa(DC); } static const Decl *getDeclForContext(const DeclContext *DC) { @@ -187,6 +189,8 @@ static const Decl *getDeclForContext(const DeclContext *DC) { llvm_unreachable("shouldn't serialize the main module"); case DeclContextKind::AbstractFunctionDecl: return cast(DC); + case DeclContextKind::SubscriptDecl: + return cast(DC); } } @@ -748,6 +752,9 @@ static uint8_t getRawStableDefaultArgumentKind(swift::DefaultArgumentKind kind) CASE(Line) CASE(Function) CASE(DSOHandle) + CASE(Nil) + CASE(EmptyArray) + CASE(EmptyDictionary) #undef CASE } } @@ -784,6 +791,27 @@ static uint8_t getRawStableAddressorKind(swift::AddressorKind kind) { llvm_unreachable("bad addressor kind"); } +void Serializer::writeParameterList(const ParameterList *PL) { + using namespace decls_block; + + unsigned abbrCode = DeclTypeAbbrCodes[ParameterListLayout::Code]; + ParameterListLayout::emitRecord(Out, ScratchRecord, abbrCode, + PL->size()); + + abbrCode = DeclTypeAbbrCodes[ParameterListEltLayout::Code]; + for (auto ¶m : *PL) { + // FIXME: Default argument expressions? + + auto defaultArg = + getRawStableDefaultArgumentKind(param->getDefaultArgumentKind()); + ParameterListEltLayout::emitRecord(Out, ScratchRecord, abbrCode, + addDeclRef(param), + param->isVariadic(), + defaultArg); + } +} + + void Serializer::writePattern(const Pattern *pattern) { using namespace decls_block; @@ -809,9 +837,7 @@ void Serializer::writePattern(const Pattern *pattern) { for (auto &elt : tuple->getElements()) { // FIXME: Default argument expressions? TuplePatternEltLayout::emitRecord( - Out, ScratchRecord, abbrCode, addIdentifierRef(elt.getLabel()), - elt.hasEllipsis(), - getRawStableDefaultArgumentKind(elt.getDefaultArgKind())); + Out, ScratchRecord, abbrCode, addIdentifierRef(elt.getLabel())); writePattern(elt.getPattern()); } break; @@ -1013,8 +1039,6 @@ void Serializer::writeNormalConformance( data.push_back(addDeclRef(witness.getDecl())); assert(witness.getDecl() || req->getAttrs().hasAttribute() || req->getAttrs().isUnavailable(req->getASTContext())); - // The substitution records are serialized later. - data.push_back(witness.getSubstitutions().size()); ++numValueWitnesses; }); @@ -1061,11 +1085,6 @@ void Serializer::writeNormalConformance( DeclTypeAbbrCodes); } - conformance->forEachValueWitness(nullptr, - [&](ValueDecl *req, - ConcreteDeclRef witness) { - writeSubstitutions(witness.getSubstitutions(), DeclTypeAbbrCodes); - }); conformance->forEachTypeWitness(/*resolver=*/nullptr, [&](AssociatedTypeDecl *assocType, const Substitution &witness, @@ -1325,6 +1344,21 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) { break; } + case DeclContextKind::SubscriptDecl: { + auto SD = cast(DC); + writeCrossReference(DC->getParent(), pathLen + 1); + + Type ty = SD->getInterfaceType()->getCanonicalType(); + + abbrCode = DeclTypeAbbrCodes[XRefValuePathPieceLayout::Code]; + bool isProtocolExt = SD->getDeclContext()->isProtocolExtensionContext(); + XRefValuePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode, + addTypeRef(ty), + addIdentifierRef(SD->getName()), + isProtocolExt); + break; + } + case DeclContextKind::AbstractFunctionDecl: { if (auto fn = dyn_cast(DC)) { if (auto storage = fn->getAccessorStorageDecl()) { @@ -1691,6 +1725,21 @@ void Serializer::writeDeclAttribute(const DeclAttribute *DA) { blob); return; } + + case DAK_MigrationId: { + auto *theAttr = cast(DA); + + // Compute the blob. + SmallString<128> blob; + blob += theAttr->getIdent(); + uint64_t endOfIdentIndex = blob.size(); + blob += theAttr->getPatternId(); + auto abbrCode = DeclTypeAbbrCodes[MigrationIdDeclAttrLayout::Code]; + MigrationIdDeclAttrLayout::emitRecord(Out, ScratchRecord, abbrCode, + endOfIdentIndex, + blob); + return; + } } } @@ -1724,6 +1773,7 @@ void Serializer::writeDeclContext(const DeclContext *DC) { switch (DC->getContextKind()) { case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: case DeclContextKind::NominalTypeDecl: case DeclContextKind::ExtensionDecl: declOrDeclContextID = addDeclRef(getDeclForContext(DC)); @@ -2359,7 +2409,7 @@ void Serializer::writeDecl(const Decl *D) { fn->isObjC(), fn->isMutating(), fn->hasDynamicSelf(), - fn->getBodyParamPatterns().size(), + fn->getParameterLists().size(), addTypeRef(fn->getType()), addTypeRef(fn->getInterfaceType()), addDeclRef(fn->getOperatorDecl()), @@ -2373,8 +2423,8 @@ void Serializer::writeDecl(const Decl *D) { writeGenericParams(fn->getGenericParams(), DeclTypeAbbrCodes); // Write the body parameters. - for (auto pattern : fn->getBodyParamPatterns()) - writePattern(pattern); + for (auto pattern : fn->getParameterLists()) + writeParameterList(pattern); if (auto errorConvention = fn->getForeignErrorConvention()) writeForeignErrorConvention(*errorConvention); @@ -2452,7 +2502,7 @@ void Serializer::writeDecl(const Decl *D) { rawSetterAccessLevel, nameComponents); - writePattern(subscript->getIndices()); + writeParameterList(subscript->getIndices()); break; } @@ -2487,9 +2537,10 @@ void Serializer::writeDecl(const Decl *D) { nameComponents); writeGenericParams(ctor->getGenericParams(), DeclTypeAbbrCodes); - assert(ctor->getBodyParamPatterns().size() == 2); - for (auto pattern : ctor->getBodyParamPatterns()) - writePattern(pattern); + assert(ctor->getParameterLists().size() == 2); + // Why is this writing out the param list for self? + for (auto paramList : ctor->getParameterLists()) + writeParameterList(paramList); if (auto errorConvention = ctor->getForeignErrorConvention()) writeForeignErrorConvention(*errorConvention); break; @@ -2508,9 +2559,9 @@ void Serializer::writeDecl(const Decl *D) { dtor->isObjC(), addTypeRef(dtor->getType()), addTypeRef(dtor->getInterfaceType())); - assert(dtor->getBodyParamPatterns().size() == 1); - for (auto pattern : dtor->getBodyParamPatterns()) - writePattern(pattern); + assert(dtor->getParameterLists().size() == 1); + // Why is this writing out the param list for self? + writeParameterList(dtor->getParameterLists()[0]); break; } @@ -2572,6 +2623,7 @@ static uint8_t getRawStableParameterConvention(swift::ParameterConvention pc) { SIMPLE_CASE(ParameterConvention, Indirect_In_Guaranteed) SIMPLE_CASE(ParameterConvention, Indirect_Out) SIMPLE_CASE(ParameterConvention, Indirect_Inout) + SIMPLE_CASE(ParameterConvention, Indirect_InoutAliasable) SIMPLE_CASE(ParameterConvention, Direct_Owned) SIMPLE_CASE(ParameterConvention, Direct_Unowned) SIMPLE_CASE(ParameterConvention, Direct_Guaranteed) @@ -3063,7 +3115,7 @@ void Serializer::writeType(Type ty) { auto generic = cast(ty.getPointer()); // We don't want two copies of Archetype being serialized, one by - // serializing genericArgs, the other by serializaing the Decl. The reason + // serializing genericArgs, the other by serializing the Decl. The reason // is that it is likely the Decl's Archetype can be serialized in // a different module, causing two copies being constructed at // deserialization, one in the other module, one in this module as @@ -3083,7 +3135,7 @@ void Serializer::writeType(Type ty) { if (auto arche = dyn_cast(next.getPointer())) { auto genericParams = generic->getDecl()->getGenericParams(); unsigned idx = 0; - // Check if next exisits in the Decl. + // Check if next exists in the Decl. for (auto archetype : genericParams->getAllArchetypes()) { if (archetype == arche) { found = true; @@ -3185,6 +3237,9 @@ void Serializer::writeAllDeclsAndTypes() { registerDeclTypeAbbr(); registerDeclTypeAbbr(); + registerDeclTypeAbbr(); + registerDeclTypeAbbr(); + registerDeclTypeAbbr(); registerDeclTypeAbbr(); registerDeclTypeAbbr(); @@ -3631,11 +3686,10 @@ void Serializer::writeAST(ModuleOrSourceFile DC) { for (auto TD : localTypeDecls) { hasLocalTypes = true; - SmallString<32> MangledName; - llvm::raw_svector_ostream Stream(MangledName); - Mangle::Mangler DebugMangler(Stream, false); + Mangle::Mangler DebugMangler(false); DebugMangler.mangleType(TD->getDeclaredType(), ResilienceExpansion::Minimal, 0); + auto MangledName = DebugMangler.finalize(); assert(!MangledName.empty() && "Mangled type came back empty!"); localTypeGenerator.insert(MangledName, { addDeclRef(TD), TD->getLocalDiscriminator() @@ -3798,6 +3852,7 @@ void swift::serialize(ModuleOrSourceFile DC, bool hadError = withOutputFile(getContext(DC), options.OutputPath, [&](raw_ostream &out) { + SharedTimer timer("Serialization (swiftmodule)"); Serializer::writeToStream(out, DC, M, options); }); if (hadError) @@ -3806,6 +3861,7 @@ void swift::serialize(ModuleOrSourceFile DC, if (options.DocOutputPath && options.DocOutputPath[0] != '\0') { (void)withOutputFile(getContext(DC), options.DocOutputPath, [&](raw_ostream &out) { + SharedTimer timer("Serialization (swiftdoc)"); Serializer::writeDocToStream(out, DC); }); } diff --git a/lib/Serialization/Serialization.h b/lib/Serialization/Serialization.h index a0fd272ad1a52..0fddfe081bda3 100644 --- a/lib/Serialization/Serialization.h +++ b/lib/Serialization/Serialization.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -235,6 +235,8 @@ class Serializer { /// modules and its source files. void writeInputBlock(const SerializationOptions &options); + void writeParameterList(const ParameterList *PL); + /// Writes the given pattern, recursively. void writePattern(const Pattern *pattern); diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 4642f188c5815..072e183630dea 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,6 +20,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -167,7 +168,6 @@ namespace { << " for layout " << Layout::Code << "\n"); } - // TODO: this is not required anymore. Remove it. bool ShouldSerializeAll; /// Helper function to update ListOfValues for MethodInst. Format: @@ -236,9 +236,10 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { << " FnID " << FnID << "\n"); DEBUG(llvm::dbgs() << "Serialized SIL:\n"; F.dump()); - IdentifierID SemanticsID = - F.getSemanticsAttr().empty() ? (IdentifierID)0 : - S.addIdentifierRef(Ctx.getIdentifier(F.getSemanticsAttr())); + llvm::SmallVector SemanticsIDs; + for (auto SemanticAttr : F.getSemanticsAttrs()) { + SemanticsIDs.push_back(S.addIdentifierRef(Ctx.getIdentifier(SemanticAttr))); + } SILLinkage Linkage = F.getLinkage(); @@ -247,7 +248,7 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { // 1. shared_external linkage is just a hack to tell the optimizer that a // shared function was deserialized. // - // 2. We can not just serialize a declaration to a shared_external function + // 2. We cannot just serialize a declaration to a shared_external function // since shared_external functions still have linkonce_odr linkage at the LLVM // level. This means they must be defined not just declared. // @@ -259,7 +260,7 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { bool NoBody = DeclOnly || isAvailableExternally(Linkage) || F.isExternalDeclaration(); - // If we don't emit a function body then make sure to mark the decleration + // If we don't emit a function body then make sure to mark the declaration // as available externally. if (NoBody) { Linkage = addExternalToLinkage(Linkage); @@ -269,8 +270,8 @@ void SILSerializer::writeSILFunction(const SILFunction &F, bool DeclOnly) { Out, ScratchRecord, abbrCode, toStableSILLinkage(Linkage), (unsigned)F.isTransparent(), (unsigned)F.isFragile(), (unsigned)F.isThunk(), (unsigned)F.isGlobalInit(), - (unsigned)F.getInlineStrategy(), (unsigned)F.getEffectsKind(), - FnID, SemanticsID); + (unsigned)F.getInlineStrategy(), (unsigned)F.getEffectsKind(), FnID, + SemanticsIDs); if (NoBody) return; @@ -890,6 +891,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) { case ValueKind::DestroyAddrInst: case ValueKind::IsNonnullInst: case ValueKind::LoadInst: + case ValueKind::LoadUnownedInst: case ValueKind::LoadWeakInst: case ValueKind::MarkUninitializedInst: case ValueKind::FixLifetimeInst: @@ -897,9 +899,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) { case ValueKind::StrongPinInst: case ValueKind::StrongReleaseInst: case ValueKind::StrongRetainInst: - case ValueKind::StrongRetainAutoreleasedInst: case ValueKind::StrongUnpinInst: - case ValueKind::AutoreleaseReturnInst: case ValueKind::StrongRetainUnownedInst: case ValueKind::UnownedRetainInst: case ValueKind::UnownedReleaseInst: @@ -912,6 +912,8 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) { unsigned Attr = 0; if (auto *LWI = dyn_cast(&SI)) Attr = LWI->isTake(); + else if (auto *LUI = dyn_cast(&SI)) + Attr = LUI->isTake(); else if (auto *MUI = dyn_cast(&SI)) Attr = (unsigned)MUI->getKind(); else if (auto *DRI = dyn_cast(&SI)) @@ -1140,6 +1142,7 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) { case ValueKind::AssignInst: case ValueKind::CopyAddrInst: case ValueKind::StoreInst: + case ValueKind::StoreUnownedInst: case ValueKind::StoreWeakInst: { SILValue operand, value; unsigned Attr = 0; @@ -1147,6 +1150,10 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) { Attr = cast(&SI)->isInitializationOfDest(); operand = cast(&SI)->getDest(); value = cast(&SI)->getSrc(); + } else if (SI.getKind() == ValueKind::StoreUnownedInst) { + Attr = cast(&SI)->isInitializationOfDest(); + operand = cast(&SI)->getDest(); + value = cast(&SI)->getSrc(); } else if (SI.getKind() == ValueKind::StoreInst) { operand = cast(&SI)->getDest(); value = cast(&SI)->getSrc(); diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 2510da96b4f14..96a14b6004b5a 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/Serialization/SerializedSILLoader.cpp b/lib/Serialization/SerializedSILLoader.cpp index bec70db01de6f..08a5660388a22 100644 --- a/lib/Serialization/SerializedSILLoader.cpp +++ b/lib/Serialization/SerializedSILLoader.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SwiftDemangle/MangleHack.cpp b/lib/SwiftDemangle/MangleHack.cpp index bae3a5e740956..b22010a0e3303 100644 --- a/lib/SwiftDemangle/MangleHack.cpp +++ b/lib/SwiftDemangle/MangleHack.cpp @@ -1,8 +1,8 @@ -//===-- MangleHack.cpp - Swift Mangle Hack for various clients ------------===// +//===--- MangleHack.cpp - Swift Mangle Hack for various clients -----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/lib/SwiftDemangle/SwiftDemangle.cpp b/lib/SwiftDemangle/SwiftDemangle.cpp index 38e59172be6ce..b2a664b9f000b 100644 --- a/lib/SwiftDemangle/SwiftDemangle.cpp +++ b/lib/SwiftDemangle/SwiftDemangle.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/internal/SwiftExperimental/SwiftExperimental.swift b/stdlib/internal/SwiftExperimental/SwiftExperimental.swift index 7e85e7059244b..1f32b4ec6dbfd 100644 --- a/stdlib/internal/SwiftExperimental/SwiftExperimental.swift +++ b/stdlib/internal/SwiftExperimental/SwiftExperimental.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/README.txt b/stdlib/private/README.txt index eafbdd904ff5c..aa7aa4aa66462 100644 --- a/stdlib/private/README.txt +++ b/stdlib/private/README.txt @@ -1,5 +1,5 @@ The modules in the 'stdlib/private' directory contain APIs that are -considered private to the Swift project. Don't use them outside of the +considered private to the Swift project. Don't use them outside of the repositories related to the Swift project. These APIs are used for building Swift build and test automation tools, diff --git a/stdlib/private/StdlibUnittest/CMakeLists.txt b/stdlib/private/StdlibUnittest/CMakeLists.txt index 936188672b168..0d280f3fd1eb0 100644 --- a/stdlib/private/StdlibUnittest/CMakeLists.txt +++ b/stdlib/private/StdlibUnittest/CMakeLists.txt @@ -40,7 +40,7 @@ add_swift_library(swiftStdlibUnittest SHARED IS_STDLIB LifetimeTracked.swift ${swift_stdlib_unittest_platform_sources} - # Can not serialize StdlibUnittest because of: + # Cannot serialize StdlibUnittest because of: # Compiling StdlibUnittest with -sil-serialize-all # crashes in SIL serializer # diff --git a/stdlib/private/StdlibUnittest/CheckCollectionType.swift b/stdlib/private/StdlibUnittest/CheckCollectionType.swift index f65450eb3b1cf..cf67a3e652f09 100644 --- a/stdlib/private/StdlibUnittest/CheckCollectionType.swift +++ b/stdlib/private/StdlibUnittest/CheckCollectionType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/StdlibUnittest/CheckMutableCollectionType.swift.gyb b/stdlib/private/StdlibUnittest/CheckMutableCollectionType.swift.gyb index 5d1f10c95d6c9..45e0f17c97706 100644 --- a/stdlib/private/StdlibUnittest/CheckMutableCollectionType.swift.gyb +++ b/stdlib/private/StdlibUnittest/CheckMutableCollectionType.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -53,9 +53,9 @@ public func withInvalidOrderings(body: ((Int,Int) -> Bool) -> Void) { body { (_,_) in true } body { (_,_) in false } var i = 0 - body { (_,_) in i++ % 2 == 0 } - body { (_,_) in i++ % 3 == 0 } - body { (_,_) in i++ % 5 == 0 } + body { (_,_) in defer {i += 1}; return i % 2 == 0 } + body { (_,_) in defer {i += 1}; return i % 3 == 0 } + body { (_,_) in defer {i += 1}; return i % 5 == 0 } } internal func _mapInPlace( diff --git a/stdlib/private/StdlibUnittest/CheckRangeReplaceableCollectionType.swift b/stdlib/private/StdlibUnittest/CheckRangeReplaceableCollectionType.swift index a4d58323c43bc..221cc4c3c2d7c 100644 --- a/stdlib/private/StdlibUnittest/CheckRangeReplaceableCollectionType.swift +++ b/stdlib/private/StdlibUnittest/CheckRangeReplaceableCollectionType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/StdlibUnittest/CheckRangeReplaceableSliceType.swift b/stdlib/private/StdlibUnittest/CheckRangeReplaceableSliceType.swift index 4abdd49c5229f..bbe79dbac71ac 100644 --- a/stdlib/private/StdlibUnittest/CheckRangeReplaceableSliceType.swift +++ b/stdlib/private/StdlibUnittest/CheckRangeReplaceableSliceType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/StdlibUnittest/CheckSequenceType.swift b/stdlib/private/StdlibUnittest/CheckSequenceType.swift index 604fc3c3a398b..e233a86adb516 100644 --- a/stdlib/private/StdlibUnittest/CheckSequenceType.swift +++ b/stdlib/private/StdlibUnittest/CheckSequenceType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -1520,7 +1520,8 @@ self.test("\(testNamePrefix).dropFirst/semantics/equivalence") { let s1 = makeWrappedSequence([1010, 2020, 3030, 4040].map(OpaqueValue.init)) let s2 = makeWrappedSequence([1010, 2020, 3030, 4040].map(OpaqueValue.init)) - let result1 = s1.dropFirst(1).dropFirst(1) + let result0 = s1.dropFirst(1) + let result1 = result0.dropFirst(1) let result2 = s2.dropFirst(2) expectEqualSequence( @@ -1611,7 +1612,8 @@ self.test("\(testNamePrefix).prefix/semantics/equivalence") { let s2 = makeWrappedSequence(expected) let prefixedOnce = s1.prefix(3) - let prefixedTwice = s2.prefix(3).prefix(3) + let temp = s2.prefix(3) + let prefixedTwice = temp.prefix(3) expectEqualSequence(prefixedOnce, prefixedTwice) { extractValue($0).value == extractValue($1).value @@ -1649,7 +1651,8 @@ self.test("\(testNamePrefix).suffix/semantics/equivalence") { let s2 = makeWrappedSequence(expected) let prefixedOnce = s1.suffix(3) - let prefixedTwice = s2.suffix(3).prefix(3) + let temp = s2.suffix(3) + let prefixedTwice = temp.prefix(3) expectEqualSequence(prefixedOnce, prefixedTwice) { extractValue($0).value == extractValue($1).value diff --git a/stdlib/private/StdlibUnittest/GetOSVersion.mm b/stdlib/private/StdlibUnittest/GetOSVersion.mm index 8e36cc41bf999..1ba1507ba9465 100644 --- a/stdlib/private/StdlibUnittest/GetOSVersion.mm +++ b/stdlib/private/StdlibUnittest/GetOSVersion.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/StdlibUnittest/InterceptTraps.cpp b/stdlib/private/StdlibUnittest/InterceptTraps.cpp index 19ec7327c9a20..7252287a12d30 100644 --- a/stdlib/private/StdlibUnittest/InterceptTraps.cpp +++ b/stdlib/private/StdlibUnittest/InterceptTraps.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/StdlibUnittest/LifetimeTracked.swift b/stdlib/private/StdlibUnittest/LifetimeTracked.swift index 4f7290bcbf1a6..341b814912485 100644 --- a/stdlib/private/StdlibUnittest/LifetimeTracked.swift +++ b/stdlib/private/StdlibUnittest/LifetimeTracked.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,15 +12,16 @@ public final class LifetimeTracked : ForwardIndexType, CustomStringConvertible { public init(_ value: Int, identity: Int = 0) { - ++LifetimeTracked.instances - serialNumber = ++LifetimeTracked._nextSerialNumber + LifetimeTracked.instances += 1 + LifetimeTracked._nextSerialNumber += 1 + serialNumber = LifetimeTracked._nextSerialNumber self.value = value self.identity = identity } deinit { assert(serialNumber > 0, "double destruction!") - --LifetimeTracked.instances + LifetimeTracked.instances -= 1 serialNumber = -serialNumber } diff --git a/stdlib/private/StdlibUnittest/LoggingWrappers.swift.gyb b/stdlib/private/StdlibUnittest/LoggingWrappers.swift.gyb index 0322e8deed2e3..2d861128a84af 100644 --- a/stdlib/private/StdlibUnittest/LoggingWrappers.swift.gyb +++ b/stdlib/private/StdlibUnittest/LoggingWrappers.swift.gyb @@ -1,8 +1,8 @@ -//===--- LoggingWrappers.swift ---------------------------------------===// +//===--- LoggingWrappers.swift --------------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -49,7 +49,7 @@ public struct LoggingGenerator } public mutating func next() -> Base.Element? { - ++Log.next[selfType] + Log.next[selfType] += 1 return base.next() } @@ -99,14 +99,14 @@ public struct LoggingRangeReplaceableCollection< public init() { self.base = Base() - ++Log.init_[selfType] + Log.init_[selfType] += 1 } public init< S : SequenceType where S.Generator.Element == Generator.Element >(_ elements: S) { self.base = Base(elements) - ++Log.initWithSequence[selfType] + Log.initWithSequence[selfType] += 1 } public init(_ base: Base) { @@ -142,73 +142,73 @@ public struct LoggingRangeReplaceableCollection< >( subRange: Range, with newElements: C ) { - ++Log.replaceRange[selfType] + Log.replaceRange[selfType] += 1 base.replaceRange(subRange, with: newElements) } public mutating func append(newElement: Base.Generator.Element) { - ++Log.append[selfType] + Log.append[selfType] += 1 base.append(newElement) } public mutating func appendContentsOf< S : SequenceType where S.Generator.Element == Base.Generator.Element >(newElements: S) { - ++Log.appendContentsOf[selfType] + Log.appendContentsOf[selfType] += 1 base.appendContentsOf(newElements) } public mutating func insert( newElement: Base.Generator.Element, atIndex i: Base.Index ) { - ++Log.insert[selfType] + Log.insert[selfType] += 1 base.insert(newElement, atIndex: i) } public mutating func removeAtIndex(index: Base.Index) -> Base.Generator.Element { - ++Log.removeAtIndex[selfType] + Log.removeAtIndex[selfType] += 1 return base.removeAtIndex(index) } public mutating func _customRemoveLast() -> Base.Generator.Element? { - ++Log._customRemoveLast[selfType] + Log._customRemoveLast[selfType] += 1 return base._customRemoveLast() } public mutating func _customRemoveLast(n: Int) -> Bool { - ++Log._customRemoveLastN[selfType] + Log._customRemoveLastN[selfType] += 1 return base._customRemoveLast(n) } public mutating func removeFirst() -> Base.Generator.Element { - ++Log.removeFirst[selfType] + Log.removeFirst[selfType] += 1 return base.removeFirst() } public mutating func removeFirst(n: Int) { - ++Log.removeFirstN[selfType] + Log.removeFirstN[selfType] += 1 base.removeFirst(n) } public mutating func removeRange(subRange: Range) { - ++Log.removeRange[selfType] + Log.removeRange[selfType] += 1 base.removeRange(subRange) } public mutating func removeAll(keepCapacity keepCapacity: Bool) { - ++Log.removeAll[selfType] + Log.removeAll[selfType] += 1 base.removeAll(keepCapacity: keepCapacity) } public mutating func reserveCapacity(n: Base.Index.Distance) { - ++Log.reserveCapacity[selfType] + Log.reserveCapacity[selfType] += 1 base.reserveCapacity(n) } public mutating func insertContentsOf< C : CollectionType where C.Generator.Element == Base.Generator.Element >(newElements: C, at i: Base.Index) { - ++Log.insertContentsOf[selfType] + Log.insertContentsOf[selfType] += 1 base.insertContentsOf(newElements, at: i) } @@ -331,30 +331,30 @@ public struct Logging${Kind}< } public func successor() -> Logging${Kind} { - ++Log.successor[selfType] + Log.successor[selfType] += 1 return Logging${Kind}(base.successor()) } % if Kind == 'BidirectionalIndex' or Kind == 'RandomAccessIndex': public func predecessor() -> Logging${Kind} { - ++Log.predecessor[selfType] + Log.predecessor[selfType] += 1 return Logging${Kind}(base.predecessor()) } % end public func distanceTo(end: Logging${Kind}) -> Base.Distance { - ++Log.distanceTo[selfType] + Log.distanceTo[selfType] += 1 return base.distanceTo(end.base) } public func advancedBy(n: Base.Distance) -> Logging${Kind} { - ++Log.advancedBy[selfType] + Log.advancedBy[selfType] += 1 return Logging${Kind}(base.advancedBy(n)) } public func advancedBy(n: Base.Distance, limit: Logging${Kind}) -> Logging${Kind} { - ++Log.advancedByWithLimit[selfType] + Log.advancedByWithLimit[selfType] += 1 return Logging${Kind}(base.advancedBy(n, limit: limit.base)) } } @@ -376,23 +376,23 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { % if Kind == 'Collection' or Kind == 'MutableCollection': public var startIndex: Base.Index { - ++Log.startIndex[selfType] + Log.startIndex[selfType] += 1 return base.startIndex } public var endIndex: Base.Index { - ++Log.endIndex[selfType] + Log.endIndex[selfType] += 1 return base.endIndex } public subscript(position: Base.Index) -> Base.Generator.Element { get { - ++Log.subscriptIndex[selfType] + Log.subscriptIndex[selfType] += 1 return base[position] } % if Kind == 'MutableCollection': set { - ++Log.subscriptIndexSet[selfType] + Log.subscriptIndexSet[selfType] += 1 base[position] = newValue } % end @@ -400,36 +400,36 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { public subscript(bounds: Range) -> Base.SubSequence { get { - ++Log.subscriptRange[selfType] + Log.subscriptRange[selfType] += 1 return base[bounds] } % if Kind == 'MutableCollection': set { - ++Log.subscriptRangeSet[selfType] + Log.subscriptRangeSet[selfType] += 1 base[bounds] = newValue } % end } public var isEmpty: Bool { - ++Log.isEmpty[selfType] + Log.isEmpty[selfType] += 1 return base.isEmpty } public var count: Base.Index.Distance { - ++Log.count[selfType] + Log.count[selfType] += 1 return base.count } public func _customIndexOfEquatableElement( element: Base.Generator.Element ) -> Base.Index?? { - ++Log._customIndexOfEquatableElement[selfType] + Log._customIndexOfEquatableElement[selfType] += 1 return base._customIndexOfEquatableElement(element) } public var first: Base.Generator.Element? { - ++Log.first[selfType] + Log.first[selfType] += 1 return base.first } % end @@ -438,29 +438,29 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { public mutating func _withUnsafeMutableBufferPointerIfSupported( @noescape body: (UnsafeMutablePointer, Int) throws -> R ) rethrows -> R? { - ++Log._withUnsafeMutableBufferPointerIfSupported[selfType] + Log._withUnsafeMutableBufferPointerIfSupported[selfType] += 1 let result = try base._withUnsafeMutableBufferPointerIfSupported(body) if result != nil { - ++Log._withUnsafeMutableBufferPointerIfSupportedNonNilReturns[selfType] + Log._withUnsafeMutableBufferPointerIfSupportedNonNilReturns[selfType] += 1 } return result } % end public func generate() -> LoggingGenerator { - ++Log.generate[selfType] + Log.generate[selfType] += 1 return LoggingGenerator(base.generate()) } public func underestimateCount() -> Int { - ++Log.underestimateCount[selfType] + Log.underestimateCount[selfType] += 1 return base.underestimateCount() } public func forEach( @noescape body: (Base.Generator.Element) throws -> Void ) rethrows { - ++Log.forEach[selfType] + Log.forEach[selfType] += 1 try base.forEach(body) } @@ -468,7 +468,7 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { public func map( @noescape transform: (Base.Generator.Element) throws -> T ) rethrows -> [T] { - ++Log.map[selfType] + Log.map[selfType] += 1 return try base.map(transform) } @@ -476,27 +476,27 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { public func filter( @noescape includeElement: (Base.Generator.Element) throws -> Bool ) rethrows -> [Base.Generator.Element] { - ++Log.filter[selfType] + Log.filter[selfType] += 1 return try base.filter(includeElement) } public func dropFirst(n: Int) -> Base.SubSequence { - ++Log.dropFirst[selfType] + Log.dropFirst[selfType] += 1 return base.dropFirst(n) } public func dropLast(n: Int) -> Base.SubSequence { - ++Log.dropLast[selfType] + Log.dropLast[selfType] += 1 return base.dropLast(n) } public func prefix(maxLength: Int) -> Base.SubSequence { - ++Log.prefix[selfType] + Log.prefix[selfType] += 1 return base.prefix(maxLength) } public func suffix(maxLength: Int) -> Base.SubSequence { - ++Log.suffix[selfType] + Log.suffix[selfType] += 1 return base.suffix(maxLength) } @@ -505,7 +505,7 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { allowEmptySlices: Bool = false, @noescape isSeparator: (Base.Generator.Element) throws -> Bool ) rethrows -> [Base.SubSequence] { - ++Log.split[selfType] + Log.split[selfType] += 1 return try base.split(maxSplit, allowEmptySlices: allowEmptySlices, isSeparator: isSeparator) } @@ -513,17 +513,17 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { % if Kind == 'Collection' or Kind == 'MutableCollection': public func prefixUpTo(end: Index) -> Base.SubSequence { - ++Log.prefixUpTo[selfType] + Log.prefixUpTo[selfType] += 1 return base.prefixUpTo(end) } public func suffixFrom(start: Index) -> Base.SubSequence { - ++Log.suffixFrom[selfType] + Log.suffixFrom[selfType] += 1 return base.suffixFrom(start) } public func prefixThrough(position: Index) -> Base.SubSequence { - ++Log.prefixThrough[selfType] + Log.prefixThrough[selfType] += 1 return base.prefixThrough(position) } @@ -532,7 +532,7 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { public func _customContainsEquatableElement( element: Base.Generator.Element ) -> Bool? { - ++Log._customContainsEquatableElement[selfType] + Log._customContainsEquatableElement[selfType] += 1 return base._customContainsEquatableElement(element) } @@ -540,9 +540,9 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. public func _preprocessingPass( - preprocess: (Logging${Kind})->R + @noescape preprocess: (Logging${Kind}) -> R ) -> R? { - ++Log._preprocessingPass[selfType] + Log._preprocessingPass[selfType] += 1 return base._preprocessingPass { _ in preprocess(self) } } @@ -550,14 +550,14 @@ public struct Logging${Kind} : ${Kind}Type, LoggingType { /// in the same order. public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer { - ++Log._copyToNativeArrayBuffer[selfType] + Log._copyToNativeArrayBuffer[selfType] += 1 return base._copyToNativeArrayBuffer() } /// Copy a Sequence into an array. public func _initializeTo(ptr: UnsafeMutablePointer) -> UnsafeMutablePointer { - ++Log._initializeTo[selfType] + Log._initializeTo[selfType] += 1 return base._initializeTo(ptr) } @@ -572,7 +572,7 @@ public func expectCustomizable< T.Log == T.Base.Log >(_: T, _ counters: TypeIndexed, //===--- TRACE boilerplate ----------------------------------------------===// - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__ @@ -590,7 +590,7 @@ public func expectNotCustomizable< T.Log == T.Base.Log >(_: T, _ counters: TypeIndexed, //===--- TRACE boilerplate ----------------------------------------------===// - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__ diff --git a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp index c30dfddc56bb0..7c8790e6db6a0 100644 --- a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp +++ b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift index 2bc2048b568a4..7bb8727527b49 100644 --- a/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift +++ b/stdlib/private/StdlibUnittest/OpaqueIdentityFunctions.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/StdlibUnittest/RaceTest.swift b/stdlib/private/StdlibUnittest/RaceTest.swift index 9defe825c11f6..b1a9832b1e622 100644 --- a/stdlib/private/StdlibUnittest/RaceTest.swift +++ b/stdlib/private/StdlibUnittest/RaceTest.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -342,7 +342,7 @@ struct _RaceTestAggregatedEvaluations : CustomStringConvertible { mutating func addEvaluation(evaluation: RaceTestObservationEvaluation) { switch evaluation { case .Pass: - ++passCount + passCount += 1 case .PassInteresting(let s): if passInterestingCount[s] == nil { @@ -351,7 +351,7 @@ struct _RaceTestAggregatedEvaluations : CustomStringConvertible { passInterestingCount[s] = passInterestingCount[s]! + 1 case .Failure: - ++failureCount + failureCount += 1 case .FailureInteresting(let s): if failureInterestingCount[s] == nil { @@ -501,8 +501,8 @@ public func runRaceTest( let racingThreadCount = threads ?? max(2, _stdlib_getHardwareConcurrency()) let sharedState = _RaceTestSharedState(racingThreadCount: racingThreadCount) - let masterThreadBody: (_: ())->() = { - (_: ())->() in + let masterThreadBody: () -> Void = { + () -> Void in for _ in 0..( } } - let racingThreadBody: (Int)->() = { - (tid: Int)->() in + let racingThreadBody: (Int) -> Void = { + (tid: Int) -> Void in for _ in 0..String = "", + TRACE = '''@autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__''' @@ -166,7 +166,7 @@ public func expectationFailure( } public func expectEqual( - expected: T, _ actual: T, ${TRACE}, sameValue equal: (T,T)->Bool + expected: T, _ actual: T, ${TRACE}, sameValue equal: (T,T) -> Bool ) { if !equal(expected, actual) { expectationFailure( @@ -186,7 +186,7 @@ public func expectNotEqual(expected: T, _ actual: T, ${TRACE}) { } } -// Can not write a sane set of overloads using generics because of: +// Cannot write a sane set of overloads using generics because of: // Array->NSArray implicit conversion insanity public func expectOptionalEqual( expected: T, _ actual: T?, ${TRACE} @@ -195,7 +195,7 @@ public func expectOptionalEqual( } public func expectOptionalEqual( - expected: T, _ actual: T?, ${TRACE}, sameValue equal: (T,T)->Bool + expected: T, _ actual: T?, ${TRACE}, sameValue equal: (T,T) -> Bool ) { if (actual == nil) || !equal(expected, actual!) { expectationFailure( @@ -477,15 +477,17 @@ struct _ParentProcess { internal var _runTestsInProcess: Bool internal var _filter: String? + internal var _args: [String] - init(runTestsInProcess: Bool, filter: String?) { + init(runTestsInProcess: Bool, args: [String], filter: String?) { self._runTestsInProcess = runTestsInProcess self._filter = filter + self._args = args } mutating func _spawnChild() { - let (pid, childStdinFD, childStdoutFD, childStderrFD) = - spawnChild([ "--stdlib-unittest-run-child" ]) + let params = [ "--stdlib-unittest-run-child" ] + _args + let (pid, childStdinFD, childStdoutFD, childStderrFD) = spawnChild(params) _pid = pid _childStdin = _FDOutputStream(fd: childStdinFD) _childStdout = _FDInputStream(fd: childStdoutFD) @@ -782,11 +784,14 @@ public func runAllTests() { } else { var runTestsInProcess: Bool = false var filter: String? = nil - for var i = 0; i < Process.arguments.count; { + var args = [String]() + var i = 0 + i += 1 // Skip the name of the executable. + while i < Process.arguments.count { let arg = Process.arguments[i] if arg == "--stdlib-unittest-in-process" { runTestsInProcess = true - ++i + i += 1 continue } if arg == "--stdlib-unittest-filter" { @@ -807,12 +812,14 @@ public func runAllTests() { return } - // FIXME: skipping unrecognized parameters. - ++i + // Pass through unparsed arguments to the child process. + args.append(Process.arguments[i]) + + i += 1 } var parent = _ParentProcess( - runTestsInProcess: runTestsInProcess, filter: filter) + runTestsInProcess: runTestsInProcess, args: args, filter: filter) parent.run() } } @@ -1042,21 +1049,19 @@ func _getOSVersion() -> OSVersion { #elseif os(Android) return .Android #else - let productName = _stdlib_getSystemVersionPlistProperty("ProductName")! let productVersion = _stdlib_getSystemVersionPlistProperty("ProductVersion")! let (major, minor, bugFix) = _parseDottedVersionTriple(productVersion) - switch productName { - case "Mac OS X": - return .OSX(major: major, minor: minor, bugFix: bugFix) - case "iPhone OS": - return .iOS(major: major, minor: minor, bugFix: bugFix) - case "Apple TVOS": - return .TVOS(major: major, minor: minor, bugFix: bugFix) - case "Watch OS": - return .watchOS(major: major, minor: minor, bugFix: bugFix) - default: - fatalError("could not determine OS version") - } + #if os(OSX) + return .OSX(major: major, minor: minor, bugFix: bugFix) + #elseif os(iOS) + return .iOS(major: major, minor: minor, bugFix: bugFix) + #elseif os(tvOS) + return .TVOS(major: major, minor: minor, bugFix: bugFix) + #elseif os(watchOS) + return .watchOS(major: major, minor: minor, bugFix: bugFix) + #else + fatalError("could not determine OS version") + #endif #endif } @@ -1494,7 +1499,7 @@ public func checkHashable< Instances: CollectionType where Instances.Generator.Element : Hashable >( instances: Instances, - equalityOracle: (Instances.Index, Instances.Index)->Bool, + equalityOracle: (Instances.Index, Instances.Index) -> Bool, ${TRACE} ) { checkEquatable(instances, oracle: equalityOracle, ${trace}) @@ -1515,9 +1520,9 @@ public func checkHashable( [lhs, rhs], equalityOracle: { expectedEqual || $0 == $1 }, ${trace}) } -% for inc, protocol, op, successor, end in ( -% ('inc', '_Incrementable', '++', 'successor', 'end'), -% ('dec', 'BidirectionalIndexType', '--', 'predecessor', 'start')): +% for inc, protocol, successor, end in ( +% ('inc', '_Incrementable', 'successor', 'end'), +% ('dec', 'BidirectionalIndexType', 'predecessor', 'start')): /// Test that the elements of `instances` satisfy /// ${'some of ' if inc == 'dec' else ''}the semantic @@ -1533,7 +1538,7 @@ public func check${inc.capitalize()}rementable< where Instances.Generator.Element : ${protocol} >( instances: Instances, - equalityOracle: (Instances.Index, Instances.Index)->Bool, + equalityOracle: (Instances.Index, Instances.Index) -> Bool, ${end}Index: Instances.Generator.Element, ${TRACE} ) { checkEquatable(instances, oracle: equalityOracle, ${trace}) @@ -1547,16 +1552,6 @@ public func check${inc.capitalize()}rementable< var j = i j._${successor}InPlace() expectEqual(j, next, ${trace}) - - // Post-${inc}rement works - j = i - expectEqual(j${op}, i, ${trace}) - expectEqual(j, next, ${trace}) - - // Pre-${inc}rement works - j = i - expectEqual(${op}j, next, ${trace}) - expectEqual(j, next, ${trace}) } } } @@ -1752,10 +1747,10 @@ internal func _checkIncrementalAdvance< Instances: CollectionType where Instances.Generator.Element : ForwardIndexType >( instances: Instances, - equalityOracle: (Instances.Index, Instances.Index)->Bool, + equalityOracle: (Instances.Index, Instances.Index) -> Bool, limit: Instances.Generator.Element, sign: Instances.Generator.Element.Distance, // 1 or -1 - next: (Instances.Generator.Element)->Instances.Generator.Element, + next: (Instances.Generator.Element) -> Instances.Generator.Element, ${TRACE} ) { for i in instances { @@ -1786,7 +1781,7 @@ public func checkForwardIndex< Instances: CollectionType where Instances.Generator.Element : ForwardIndexType >( instances: Instances, - equalityOracle: (Instances.Index, Instances.Index)->Bool, + equalityOracle: (Instances.Index, Instances.Index) -> Bool, endIndex: Instances.Generator.Element, ${TRACE} ) { typealias Index = Instances.Generator.Element @@ -1812,7 +1807,7 @@ public func checkBidirectionalIndex< where Instances.Generator.Element : BidirectionalIndexType >( instances: Instances, - equalityOracle: (Instances.Index, Instances.Index)->Bool, + equalityOracle: (Instances.Index, Instances.Index) -> Bool, startIndex: Instances.Generator.Element, endIndex: Instances.Generator.Element, ${TRACE} @@ -1936,15 +1931,16 @@ public func checkSequence< // Check that _initializeTo does the right thing if we can do so // without destroying the sequence. - sequence._preprocessingPass { (sequence)->Void in + sequence._preprocessingPass { (sequence) -> Void in var count = 0 - for _ in sequence { ++count } + for _ in sequence { count += 1 } let buf = UnsafeMutablePointer.alloc(count) let end = sequence._initializeTo(buf) expectTrue(end == buf + count, "_initializeTo returned the wrong value") var j = expected.startIndex for i in 0..<(end - buf) { - expectTrue(sameValue(expected[j++], buf[i])) + expectTrue(sameValue(expected[j], buf[i])) + j = j.successor() } buf.destroy(end - buf) buf.dealloc(count) @@ -2029,12 +2025,12 @@ public func check${traversal}Collection< var i = i if n < 0 { for _ in 0 ..< -(n.toIntMax()) { - --i + i -= 1 } } else { for _ in 0..( - makeCollection: ()->C, - _ makeNewValues: (Int)->N + makeCollection: () -> C, + _ makeNewValues: (Int) -> N ) { typealias A = C @@ -2303,7 +2299,7 @@ public func expectEqualSequence< Actual: SequenceType where Expected.Generator.Element == Actual.Generator.Element >(expected: Expected, _ actual: Actual, ${TRACE}, - sameValue: (Expected.Generator.Element, Expected.Generator.Element)->Bool) { + sameValue: (Expected.Generator.Element, Expected.Generator.Element) -> Bool) { if !expected.elementsEqual(actual, isEquivalent: sameValue) { expectationFailure("expected elements: \"\(expected)\"\n" @@ -2522,10 +2518,11 @@ public struct MinimalGenerator : GeneratorType { if isConsumed { expectUnreachable("next() was called on a consumed generator") } - ++_privateState.returnedNilCounter + _privateState.returnedNilCounter += 1 return nil } - return _sharedState.data[_sharedState.i++] + defer { _sharedState.i += 1 } + return _sharedState.data[_sharedState.i] } public var isConsumed: Bool { @@ -2779,7 +2776,8 @@ public struct _CollectionState : Equatable, Hashable { } internal init(newRootStateForElementCount count: Int) { - self._id = _CollectionState._nextUnusedState++ + self._id = _CollectionState._nextUnusedState + _CollectionState._nextUnusedState += 1 self._elementsLastMutatedStateIds = Array(Repeat(count: count, repeatedValue: self._id)) } @@ -2835,7 +2833,8 @@ internal struct _CollectionStateTransition { previousState: _CollectionState, operation: _CollectionOperation ) { - let nextStateId = _CollectionState._nextUnusedState++ + let nextStateId = _CollectionState._nextUnusedState + _CollectionState._nextUnusedState += 1 let newElementStates = operation._applyTo( previousState._elementsLastMutatedStateIds, nextStateId: nextStateId) let nextState = _CollectionState( @@ -3152,11 +3151,11 @@ public struct ${DefaultedIndex}: ${StrictIndexType} { } public func logSuccessor() { - ${DefaultedIndex}.timesSuccessorCalled.value++ + ${DefaultedIndex}.timesSuccessorCalled.value += 1 } public func logPredecessor() { - ${DefaultedIndex}.timesPredecessorCalled.value++ + ${DefaultedIndex}.timesPredecessorCalled.value += 1 } % if Traversal == 'RandomAccess': @@ -3706,7 +3705,7 @@ public func == ( lhs: MinimalEquatableValue, rhs: MinimalEquatableValue ) -> Bool { - ++MinimalEquatableValue.timesEqualEqualWasCalled + MinimalEquatableValue.timesEqualEqualWasCalled += 1 return lhs.value == rhs.value } @@ -3735,7 +3734,7 @@ public struct ${Self} : Equatable, Hashable { } public var hashValue: Int { - ++${Self}.timesHashValueWasCalled + ${Self}.timesHashValueWasCalled += 1 return value.hashValue } } @@ -3744,7 +3743,7 @@ public func == ( lhs: ${Self}, rhs: ${Self} ) -> Bool { - ++${Self}.timesEqualEqualWasCalled + ${Self}.timesEqualEqualWasCalled += 1 return lhs.value == rhs.value } @@ -3781,7 +3780,7 @@ public func == ( lhs: MinimalComparableValue, rhs: MinimalComparableValue ) -> Bool { - ++MinimalComparableValue.timesEqualEqualWasCalled.value + MinimalComparableValue.timesEqualEqualWasCalled.value += 1 return MinimalComparableValue.equalImpl.value(lhs.value, rhs.value) } @@ -3789,7 +3788,7 @@ public func < ( lhs: MinimalComparableValue, rhs: MinimalComparableValue ) -> Bool { - ++MinimalComparableValue.timesLessWasCalled.value + MinimalComparableValue.timesLessWasCalled.value += 1 return MinimalComparableValue.lessImpl.value(lhs.value, rhs.value) } diff --git a/stdlib/private/StdlibUnittest/TypeIndexed.swift b/stdlib/private/StdlibUnittest/TypeIndexed.swift index a51586c682629..df6c0a130906d 100644 --- a/stdlib/private/StdlibUnittest/TypeIndexed.swift +++ b/stdlib/private/StdlibUnittest/TypeIndexed.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -55,11 +55,11 @@ public class TypeIndexed : Resettable { extension TypeIndexed where Value : ForwardIndexType { public func expectIncrement( t: Any.Type, - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__, - body: ()->R + body: () -> R ) -> R { let expected = self[t].successor() let r = body() @@ -73,11 +73,11 @@ extension TypeIndexed where Value : ForwardIndexType { extension TypeIndexed where Value : Equatable { public func expectUnchanged( t: Any.Type, - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__, - body: ()->R + body: () -> R ) -> R { let expected = self[t] let r = body() @@ -99,7 +99,7 @@ public func <=> ( public func expectEqual( expected: DictionaryLiteral, _ actual: TypeIndexed, - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__ diff --git a/stdlib/private/StdlibUnittestFoundationExtras/CMakeLists.txt b/stdlib/private/StdlibUnittestFoundationExtras/CMakeLists.txt index 99431e8b17c00..63fe9e3415833 100644 --- a/stdlib/private/StdlibUnittestFoundationExtras/CMakeLists.txt +++ b/stdlib/private/StdlibUnittestFoundationExtras/CMakeLists.txt @@ -3,7 +3,7 @@ add_swift_library(swiftStdlibUnittestFoundationExtras SHARED IS_STDLIB # filename. StdlibUnittestFoundationExtras.swift - # Can not serialize StdlibUnittestFoundationExtras because of: + # Cannot serialize StdlibUnittestFoundationExtras because of: # Compiling StdlibUnittest with -sil-serialize-all # crashes in SIL serializer # diff --git a/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift b/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift index b567c02c82d45..5966470f34a18 100644 --- a/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift +++ b/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/SwiftPrivate/IO.swift b/stdlib/private/SwiftPrivate/IO.swift index 59b73711768dd..c89936ceb5714 100644 --- a/stdlib/private/SwiftPrivate/IO.swift +++ b/stdlib/private/SwiftPrivate/IO.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -49,7 +49,7 @@ public struct _FDInputStream { _buffer.reserveCapacity(minFree - bufferFree) while bufferFree < minFree { _buffer.append(0) - ++bufferFree + bufferFree += 1 } } let readResult: __swift_ssize_t = _buffer.withUnsafeMutableBufferPointer { diff --git a/stdlib/private/SwiftPrivate/PRNG.swift b/stdlib/private/SwiftPrivate/PRNG.swift index d05583050f27e..da2ad1db83f5e 100644 --- a/stdlib/private/SwiftPrivate/PRNG.swift +++ b/stdlib/private/SwiftPrivate/PRNG.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift b/stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift index ffc37531b4655..4ccbfdbcced4b 100644 --- a/stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift +++ b/stdlib/private/SwiftPrivate/ShardedAtomicCounter.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -34,7 +34,7 @@ public struct _stdlib_ShardedAtomicCounter { let hardwareConcurrency = _stdlib_getHardwareConcurrency() let count = max(8, hardwareConcurrency * hardwareConcurrency) let shards = UnsafeMutablePointer.alloc(count) - for var i = 0; i != count; i++ { + for i in 0.. Int { var result = 0 - for var i = 0; i != Int._sizeInBits; ++i { + for _ in 0..> 1) ^ (-(_state & 1) & Int(bitPattern: 0xD0000001)) } diff --git a/stdlib/private/SwiftPrivate/SwiftPrivate.swift b/stdlib/private/SwiftPrivate/SwiftPrivate.swift index e0a2ff6462575..19bb8f128ec75 100644 --- a/stdlib/private/SwiftPrivate/SwiftPrivate.swift +++ b/stdlib/private/SwiftPrivate/SwiftPrivate.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -43,7 +43,7 @@ public func scan< public func randomShuffle(a: [T]) -> [T] { var result = a - for var i = a.count - 1; i != 0; --i { + for i in (1.., + _ oflag: CInt, + _ mode: mode_t +) -> CInt + +@warn_unused_result +@_silgen_name("_swift_Glibc_openat") +func _swift_Glibc_openat( + fd: CInt, + _ path: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t +) -> CInt + +@warn_unused_result +public func open( + path: UnsafePointer, + _ oflag: CInt +) -> CInt { + return _swift_Glibc_open(path, oflag, 0) +} + +@warn_unused_result +public func open( + path: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t +) -> CInt { + return _swift_Glibc_open(path, oflag, mode) +} + +@warn_unused_result +public func openat( + fd: CInt, + _ path: UnsafePointer, + _ oflag: CInt +) -> CInt { + return _swift_Glibc_openat(fd, path, oflag, 0) +} + +@warn_unused_result +public func openat( + fd: CInt, + _ path: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t +) -> CInt { + return _swift_Glibc_openat(fd, path, oflag, mode) +} + +@warn_unused_result +@_silgen_name("_swift_Glibc_fcntl") +internal func _swift_Glibc_fcntl( + fd: CInt, + _ cmd: CInt, + _ value: CInt +) -> CInt + +@warn_unused_result +@_silgen_name("_swift_Glibc_fcntlPtr") +internal func _swift_Glibc_fcntlPtr( + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer +) -> CInt + +@warn_unused_result +public func fcntl( + fd: CInt, + _ cmd: CInt +) -> CInt { + return _swift_Glibc_fcntl(fd, cmd, 0) +} + +@warn_unused_result +public func fcntl( + fd: CInt, + _ cmd: CInt, + _ value: CInt +) -> CInt { + return _swift_Glibc_fcntl(fd, cmd, value) +} + +@warn_unused_result +public func fcntl( + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer +) -> CInt { + return _swift_Glibc_fcntlPtr(fd, cmd, ptr) +} + public var S_IFMT: mode_t { return mode_t(0o170000) } public var S_IFIFO: mode_t { return mode_t(0o010000) } public var S_IFCHR: mode_t { return mode_t(0o020000) } @@ -74,3 +176,46 @@ public var SIG_HOLD: __sighandler_t { } #endif +//===----------------------------------------------------------------------===// +// semaphore.h +//===----------------------------------------------------------------------===// + +/// The value returned by `sem_open()` in the case of failure. +public var SEM_FAILED: UnsafeMutablePointer { + // The value is ABI. Value verified to be correct on Glibc. + return UnsafeMutablePointer(bitPattern: 0) +} + +@warn_unused_result +@_silgen_name("_swift_Glibc_sem_open2") +internal func _swift_Glibc_sem_open2( + name: UnsafePointer, + _ oflag: CInt +) -> UnsafeMutablePointer + +@warn_unused_result +@_silgen_name("_swift_Glibc_sem_open4") +internal func _swift_Glibc_sem_open4( + name: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t, + _ value: CUnsignedInt +) -> UnsafeMutablePointer + +@warn_unused_result +public func sem_open( + name: UnsafePointer, + _ oflag: CInt +) -> UnsafeMutablePointer { + return _swift_Glibc_sem_open2(name, oflag) +} + +@warn_unused_result +public func sem_open( + name: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t, + _ value: CUnsignedInt +) -> UnsafeMutablePointer { + return _swift_Glibc_sem_open4(name, oflag, mode, value) +} diff --git a/stdlib/public/Glibc/Misc.c b/stdlib/public/Glibc/Misc.c new file mode 100644 index 0000000000000..6de7bec829d13 --- /dev/null +++ b/stdlib/public/Glibc/Misc.c @@ -0,0 +1,46 @@ +//===--- Misc.c - Glibc overlay helpers -----------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include + +extern int +_swift_Glibc_open(const char *path, int oflag, mode_t mode) { + return open(path, oflag, mode); +} + +extern int +_swift_Glibc_openat(int fd, const char *path, int oflag, mode_t mode) { + return openat(fd, path, oflag, mode); +} + +extern sem_t *_swift_Glibc_sem_open2(const char *name, int oflag) { + return sem_open(name, oflag); +} + +extern sem_t *_swift_Glibc_sem_open4(const char *name, int oflag, + mode_t mode, unsigned int value) { + return sem_open(name, oflag, mode, value); +} + +extern int +_swift_Glibc_fcntl(int fd, int cmd, int value) { + return fcntl(fd, cmd, value); +} + +extern int +_swift_Glibc_fcntlPtr(int fd, int cmd, void* ptr) { + return fcntl(fd, cmd, ptr); +} + diff --git a/stdlib/public/Glibc/module.freebsd.map.in b/stdlib/public/Glibc/module.freebsd.map.in new file mode 100644 index 0000000000000..c60664e8a01b6 --- /dev/null +++ b/stdlib/public/Glibc/module.freebsd.map.in @@ -0,0 +1,364 @@ +//===--- module.freebsd.map.in --------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// This is a semi-complete modulemap that maps glibc's headers in a roughly +/// similar way to the Darwin SDK modulemap. We do not take care to list every +/// single header which may be included by a particular submodule, so there can +/// still be issues if imported into the same context as one in which someone +/// included those headers directly. +/// +/// It's not named just FreeBSD libc so that it doesn't conflict in the event of a +/// future official FreeBSD libc modulemap. +module SwiftGlibc [system] { + link "pthread" + link "dl" + + // C standard library + module C { + module complex { + header "@GLIBC_INCLUDE_PATH@/complex.h" + export * + } + module ctype { + header "@GLIBC_INCLUDE_PATH@/ctype.h" + export * + } + module errno { + header "@GLIBC_INCLUDE_PATH@/errno.h" + export * + } + + module fenv { + header "@GLIBC_INCLUDE_PATH@/fenv.h" + export * + } + + // note: supplied by compiler + // module float { + // header "@GLIBC_INCLUDE_PATH@/float.h" + // export * + // } + + module inttypes { + header "@GLIBC_INCLUDE_PATH@/inttypes.h" + export * + } + + // note: potentially supplied by compiler + // module iso646 { + // header "@GLIBC_INCLUDE_PATH@/iso646.h" + // export * + // } + // module limits { + // header "@GLIBC_INCLUDE_PATH@/limits.h" + // export * + // } + + module locale { + header "@GLIBC_INCLUDE_PATH@/locale.h" + export * + } + module math { + header "@GLIBC_INCLUDE_PATH@/math.h" + export * + } + module setjmp { + header "@GLIBC_INCLUDE_PATH@/setjmp.h" + export * + } + module signal { + header "@GLIBC_INCLUDE_PATH@/signal.h" + export * + } + + // note: supplied by the compiler + // module stdarg { + // header "@GLIBC_INCLUDE_PATH@/stdarg.h" + // export * + // } + // module stdbool { + // header "@GLIBC_INCLUDE_PATH@/stdbool.h" + // export * + // } + // module stddef { + // header "@GLIBC_INCLUDE_PATH@/stddef.h" + // export * + // } + // module stdint { + // header "@GLIBC_INCLUDE_PATH@/stdint.h" + // export * + // } + + module stdio { + header "@GLIBC_INCLUDE_PATH@/stdio.h" + export * + } + module stdlib { + header "@GLIBC_INCLUDE_PATH@/stdlib.h" + export * + export stddef + } + module string { + header "@GLIBC_INCLUDE_PATH@/string.h" + export * + } + + // note: supplied by the compiler + // explicit module tgmath { + // header "@GLIBC_INCLUDE_PATH@/tgmath.h" + // export * + // } + + module time { + header "@GLIBC_INCLUDE_PATH@/time.h" + export * + } + } + + // POSIX + module POSIX { + module aio { + header "@GLIBC_INCLUDE_PATH@/aio.h" + export * + } + module arpa { + module inet { + header "@GLIBC_INCLUDE_PATH@/arpa/inet.h" + export * + } + export * + } + module cpio { + header "@GLIBC_INCLUDE_PATH@/cpio.h" + export * + } + module dirent { + header "@GLIBC_INCLUDE_PATH@/dirent.h" + export * + } + module dlfcn { + header "@GLIBC_INCLUDE_PATH@/dlfcn.h" + export * + } + module fcntl { + header "@GLIBC_INCLUDE_PATH@/fcntl.h" + export * + } + module fmtmsg { + header "@GLIBC_INCLUDE_PATH@/fmtmsg.h" + export * + } + module fnmatch { + header "@GLIBC_INCLUDE_PATH@/fnmatch.h" + export * + } + module ftw { + header "@GLIBC_INCLUDE_PATH@/ftw.h" + export * + } + module glob { + header "@GLIBC_INCLUDE_PATH@/glob.h" + export * + } + module grp { + header "@GLIBC_INCLUDE_PATH@/grp.h" + export * + } + module iconv { + header "@GLIBC_INCLUDE_PATH@/iconv.h" + export * + } + module ioctl { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/ioctl.h" + export * + } + module langinfo { + header "@GLIBC_INCLUDE_PATH@/langinfo.h" + export * + } + module libgen { + header "@GLIBC_INCLUDE_PATH@/libgen.h" + export * + } + module monetary { + header "@GLIBC_INCLUDE_PATH@/monetary.h" + export * + } + module netdb { + header "@GLIBC_INCLUDE_PATH@/netdb.h" + export * + } + module net { + module if { + header "@GLIBC_INCLUDE_PATH@/net/if.h" + export * + } + } + module netinet { + module in { + header "@GLIBC_INCLUDE_PATH@/netinet/in.h" + export * + + exclude header "@GLIBC_INCLUDE_PATH@/netinet6/in6.h" + } + module tcp { + header "@GLIBC_INCLUDE_PATH@/netinet/tcp.h" + export * + } + } + module nl_types { + header "@GLIBC_INCLUDE_PATH@/nl_types.h" + export * + } + module poll { + header "@GLIBC_INCLUDE_PATH@/poll.h" + export * + } + module pthread { + header "@GLIBC_INCLUDE_PATH@/pthread.h" + export * + } + module pwd { + header "@GLIBC_INCLUDE_PATH@/pwd.h" + export * + } + module regex { + header "@GLIBC_INCLUDE_PATH@/regex.h" + export * + } + module sched { + header "@GLIBC_INCLUDE_PATH@/sched.h" + export * + } + module search { + header "@GLIBC_INCLUDE_PATH@/search.h" + export * + } + module semaphore { + header "@GLIBC_INCLUDE_PATH@/semaphore.h" + export * + } + module spawn { + header "@GLIBC_INCLUDE_PATH@/spawn.h" + export * + } + module strings { + header "@GLIBC_INCLUDE_PATH@/strings.h" + export * + } + + module sys { + export * + + module ipc { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/ipc.h" + export * + } + module mman { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/mman.h" + export * + } + module msg { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/msg.h" + export * + } + module resource { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/resource.h" + export * + } + module select { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/select.h" + export * + } + module sem { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/sem.h" + export * + } + module shm { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/shm.h" + export * + } + module socket { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/socket.h" + export * + } + module stat { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/stat.h" + export * + } + module statvfs { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/statvfs.h" + export * + } + module time { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/time.h" + export * + } + module times { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/times.h" + export * + } + module types { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/types.h" + export * + } + module uio { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/uio.h" + export * + } + module un { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/un.h" + export * + } + module utsname { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/utsname.h" + export * + } + module wait { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/wait.h" + export * + } + } + module syslog { + header "@GLIBC_INCLUDE_PATH@/syslog.h" + export * + } + module tar { + header "@GLIBC_INCLUDE_PATH@/tar.h" + export * + } + module termios { + header "@GLIBC_INCLUDE_PATH@/termios.h" + export * + } + module ulimit { + header "@GLIBC_INCLUDE_PATH@/ulimit.h" + export * + } + module unistd { + header "@GLIBC_INCLUDE_PATH@/unistd.h" + export * + } + module utime { + header "@GLIBC_INCLUDE_PATH@/utime.h" + export * + } + module utmpx { + header "@GLIBC_INCLUDE_PATH@/utmpx.h" + export * + } + module wordexp { + header "@GLIBC_INCLUDE_PATH@/wordexp.h" + export * + } + } +} diff --git a/stdlib/public/Glibc/module.map b/stdlib/public/Glibc/module.map deleted file mode 100644 index b08485d2abad9..0000000000000 --- a/stdlib/public/Glibc/module.map +++ /dev/null @@ -1,374 +0,0 @@ -//===--- module.map -------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// This is a semi-complete modulemap that maps glibc's headers in a roughly -/// similar way to the Darwin SDK modulemap. We do not take care to list every -/// single header which may be included by a particular submodule, so there can -/// still be issues if imported into the same context as one in which someone -/// included those headers directly. -/// -/// It's not named just Glibc so that it doesn't conflict in the event of a -/// future official glibc modulemap. -module SwiftGlibc [system] { - link "pthread" - link "dl" - - // C standard library - module C { - module complex { - header "/usr/include/complex.h" - export * - } - module ctype { - header "/usr/include/ctype.h" - export * - } - module errno { - header "/usr/include/errno.h" - export * - } - - // glibc specific - module features { - header "/usr/include/features.h" - export * - } - - module fenv { - header "/usr/include/fenv.h" - export * - } - - // note: supplied by compiler - // module float { - // header "/usr/include/float.h" - // export * - // } - - module inttypes { - header "/usr/include/inttypes.h" - export * - } - - // note: potentially supplied by compiler - // module iso646 { - // header "/usr/include/iso646.h" - // export * - // } - // module limits { - // header "/usr/include/limits.h" - // export * - // } - - module locale { - header "/usr/include/locale.h" - export * - } - module math { - header "/usr/include/math.h" - export * - } - module setjmp { - header "/usr/include/setjmp.h" - export * - } - module signal { - header "/usr/include/signal.h" - export * - } - - // note: supplied by the compiler - // module stdarg { - // header "/usr/include/stdarg.h" - // export * - // } - // module stdbool { - // header "/usr/include/stdbool.h" - // export * - // } - // module stddef { - // header "/usr/include/stddef.h" - // export * - // } - // module stdint { - // header "/usr/include/stdint.h" - // export * - // } - - module stdio { - header "/usr/include/stdio.h" - export * - } - module stdlib { - header "/usr/include/stdlib.h" - export * - export stddef - } - module string { - header "/usr/include/string.h" - export * - } - - // note: supplied by the compiler - // explicit module tgmath { - // header "/usr/include/tgmath.h" - // export * - // } - - module time { - header "/usr/include/time.h" - export * - } - } - - // POSIX - module POSIX { - module aio { - header "/usr/include/aio.h" - export * - } - module arpa { - module inet { - header "/usr/include/arpa/inet.h" - export * - } - export * - } - module cpio { - header "/usr/include/cpio.h" - export * - } - module dirent { - header "/usr/include/dirent.h" - export * - } - module dlfcn { - header "/usr/include/dlfcn.h" - export * - } - module fcntl { - header "/usr/include/fcntl.h" - export * - } - module fmtmsg { - header "/usr/include/fmtmsg.h" - export * - } - module fnmatch { - header "/usr/include/fnmatch.h" - export * - } - module ftw { - header "/usr/include/ftw.h" - export * - } - module glob { - header "/usr/include/glob.h" - export * - } - module grp { - header "/usr/include/grp.h" - export * - } - module iconv { - header "/usr/include/iconv.h" - export * - } - module ioctl { - header "/usr/include/x86_64-linux-gnu/sys/ioctl.h" - export * - } - module langinfo { - header "/usr/include/langinfo.h" - export * - } - module libgen { - header "/usr/include/libgen.h" - export * - } - module monetary { - header "/usr/include/monetary.h" - export * - } - module netdb { - header "/usr/include/netdb.h" - export * - } - module net { - module if { - header "/usr/include/net/if.h" - export * - } - } - module netinet { - module in { - header "/usr/include/netinet/in.h" - export * - - exclude header "/usr/include/netinet6/in6.h" - } - module tcp { - header "/usr/include/netinet/tcp.h" - export * - } - } - module nl_types { - header "/usr/include/nl_types.h" - export * - } - module poll { - header "/usr/include/poll.h" - export * - } - module pthread { - header "/usr/include/pthread.h" - export * - } - module pwd { - header "/usr/include/pwd.h" - export * - } - module regex { - header "/usr/include/regex.h" - export * - } - module sched { - header "/usr/include/sched.h" - export * - } - module search { - header "/usr/include/search.h" - export * - } - module semaphore { - header "/usr/include/semaphore.h" - export * - } - module spawn { - header "/usr/include/spawn.h" - export * - } - module strings { - header "/usr/include/strings.h" - export * - } - - module sys { - export * - - module ipc { - header "/usr/include/x86_64-linux-gnu/sys/ipc.h" - export * - } - module mman { - header "/usr/include/x86_64-linux-gnu/sys/mman.h" - export * - } - module msg { - header "/usr/include/x86_64-linux-gnu/sys/msg.h" - export * - } - module resource { - header "/usr/include/x86_64-linux-gnu/sys/resource.h" - export * - } - module select { - header "/usr/include/x86_64-linux-gnu/sys/select.h" - export * - } - module sem { - header "/usr/include/x86_64-linux-gnu/sys/sem.h" - export * - } - module shm { - header "/usr/include/x86_64-linux-gnu/sys/shm.h" - export * - } - module socket { - header "/usr/include/x86_64-linux-gnu/sys/socket.h" - export * - } - module stat { - header "/usr/include/x86_64-linux-gnu/sys/stat.h" - export * - } - module statvfs { - header "/usr/include/x86_64-linux-gnu/sys/statvfs.h" - export * - } - module time { - header "/usr/include/x86_64-linux-gnu/sys/time.h" - export * - } - module times { - header "/usr/include/x86_64-linux-gnu/sys/times.h" - export * - } - module types { - header "/usr/include/x86_64-linux-gnu/sys/types.h" - export * - } - module uio { - header "/usr/include/x86_64-linux-gnu/sys/uio.h" - export * - } - module un { - header "/usr/include/x86_64-linux-gnu/sys/un.h" - export * - } - module utsname { - header "/usr/include/x86_64-linux-gnu/sys/utsname.h" - export * - } - module wait { - header "/usr/include/x86_64-linux-gnu/sys/wait.h" - export * - } - } - module syslog { - header "/usr/include/syslog.h" - export * - } - module tar { - header "/usr/include/tar.h" - export * - } - module termios { - header "/usr/include/termios.h" - export * - } - module ulimit { - header "/usr/include/ulimit.h" - export * - } - module unistd { - header "/usr/include/unistd.h" - export * - } - module utime { - header "/usr/include/utime.h" - export * - } - module utmpx { - header "/usr/include/utmpx.h" - export * - } - module wait { - header "/usr/include/wait.h" - export * - } - module wordexp { - header "/usr/include/wordexp.h" - export * - } - } -} diff --git a/stdlib/public/Glibc/module.map.in b/stdlib/public/Glibc/module.map.in new file mode 100644 index 0000000000000..668967406d5dd --- /dev/null +++ b/stdlib/public/Glibc/module.map.in @@ -0,0 +1,374 @@ +//===--- module.map -------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// This is a semi-complete modulemap that maps glibc's headers in a roughly +/// similar way to the Darwin SDK modulemap. We do not take care to list every +/// single header which may be included by a particular submodule, so there can +/// still be issues if imported into the same context as one in which someone +/// included those headers directly. +/// +/// It's not named just Glibc so that it doesn't conflict in the event of a +/// future official glibc modulemap. +module SwiftGlibc [system] { + link "pthread" + link "dl" + + // C standard library + module C { + module complex { + header "@GLIBC_INCLUDE_PATH@/complex.h" + export * + } + module ctype { + header "@GLIBC_INCLUDE_PATH@/ctype.h" + export * + } + module errno { + header "@GLIBC_INCLUDE_PATH@/errno.h" + export * + } + + // glibc specific + module features { + header "@GLIBC_INCLUDE_PATH@/features.h" + export * + } + + module fenv { + header "@GLIBC_INCLUDE_PATH@/fenv.h" + export * + } + + // note: supplied by compiler + // module float { + // header "@GLIBC_INCLUDE_PATH@/float.h" + // export * + // } + + module inttypes { + header "@GLIBC_INCLUDE_PATH@/inttypes.h" + export * + } + + // note: potentially supplied by compiler + // module iso646 { + // header "@GLIBC_INCLUDE_PATH@/iso646.h" + // export * + // } + // module limits { + // header "@GLIBC_INCLUDE_PATH@/limits.h" + // export * + // } + + module locale { + header "@GLIBC_INCLUDE_PATH@/locale.h" + export * + } + module math { + header "@GLIBC_INCLUDE_PATH@/math.h" + export * + } + module setjmp { + header "@GLIBC_INCLUDE_PATH@/setjmp.h" + export * + } + module signal { + header "@GLIBC_INCLUDE_PATH@/signal.h" + export * + } + + // note: supplied by the compiler + // module stdarg { + // header "@GLIBC_INCLUDE_PATH@/stdarg.h" + // export * + // } + // module stdbool { + // header "@GLIBC_INCLUDE_PATH@/stdbool.h" + // export * + // } + // module stddef { + // header "@GLIBC_INCLUDE_PATH@/stddef.h" + // export * + // } + // module stdint { + // header "@GLIBC_INCLUDE_PATH@/stdint.h" + // export * + // } + + module stdio { + header "@GLIBC_INCLUDE_PATH@/stdio.h" + export * + } + module stdlib { + header "@GLIBC_INCLUDE_PATH@/stdlib.h" + export * + export stddef + } + module string { + header "@GLIBC_INCLUDE_PATH@/string.h" + export * + } + + // note: supplied by the compiler + // explicit module tgmath { + // header "@GLIBC_INCLUDE_PATH@/tgmath.h" + // export * + // } + + module time { + header "@GLIBC_INCLUDE_PATH@/time.h" + export * + } + } + + // POSIX + module POSIX { + module aio { + header "@GLIBC_INCLUDE_PATH@/aio.h" + export * + } + module arpa { + module inet { + header "@GLIBC_INCLUDE_PATH@/arpa/inet.h" + export * + } + export * + } + module cpio { + header "@GLIBC_INCLUDE_PATH@/cpio.h" + export * + } + module dirent { + header "@GLIBC_INCLUDE_PATH@/dirent.h" + export * + } + module dlfcn { + header "@GLIBC_INCLUDE_PATH@/dlfcn.h" + export * + } + module fcntl { + header "@GLIBC_INCLUDE_PATH@/fcntl.h" + export * + } + module fmtmsg { + header "@GLIBC_INCLUDE_PATH@/fmtmsg.h" + export * + } + module fnmatch { + header "@GLIBC_INCLUDE_PATH@/fnmatch.h" + export * + } + module ftw { + header "@GLIBC_INCLUDE_PATH@/ftw.h" + export * + } + module glob { + header "@GLIBC_INCLUDE_PATH@/glob.h" + export * + } + module grp { + header "@GLIBC_INCLUDE_PATH@/grp.h" + export * + } + module iconv { + header "@GLIBC_INCLUDE_PATH@/iconv.h" + export * + } + module ioctl { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/ioctl.h" + export * + } + module langinfo { + header "@GLIBC_INCLUDE_PATH@/langinfo.h" + export * + } + module libgen { + header "@GLIBC_INCLUDE_PATH@/libgen.h" + export * + } + module monetary { + header "@GLIBC_INCLUDE_PATH@/monetary.h" + export * + } + module netdb { + header "@GLIBC_INCLUDE_PATH@/netdb.h" + export * + } + module net { + module if { + header "@GLIBC_INCLUDE_PATH@/net/if.h" + export * + } + } + module netinet { + module in { + header "@GLIBC_INCLUDE_PATH@/netinet/in.h" + export * + + exclude header "@GLIBC_INCLUDE_PATH@/netinet6/in6.h" + } + module tcp { + header "@GLIBC_INCLUDE_PATH@/netinet/tcp.h" + export * + } + } + module nl_types { + header "@GLIBC_INCLUDE_PATH@/nl_types.h" + export * + } + module poll { + header "@GLIBC_INCLUDE_PATH@/poll.h" + export * + } + module pthread { + header "@GLIBC_INCLUDE_PATH@/pthread.h" + export * + } + module pwd { + header "@GLIBC_INCLUDE_PATH@/pwd.h" + export * + } + module regex { + header "@GLIBC_INCLUDE_PATH@/regex.h" + export * + } + module sched { + header "@GLIBC_INCLUDE_PATH@/sched.h" + export * + } + module search { + header "@GLIBC_INCLUDE_PATH@/search.h" + export * + } + module semaphore { + header "@GLIBC_INCLUDE_PATH@/semaphore.h" + export * + } + module spawn { + header "@GLIBC_INCLUDE_PATH@/spawn.h" + export * + } + module strings { + header "@GLIBC_INCLUDE_PATH@/strings.h" + export * + } + + module sys { + export * + + module ipc { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/ipc.h" + export * + } + module mman { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/mman.h" + export * + } + module msg { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/msg.h" + export * + } + module resource { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/resource.h" + export * + } + module select { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/select.h" + export * + } + module sem { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/sem.h" + export * + } + module shm { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/shm.h" + export * + } + module socket { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/socket.h" + export * + } + module stat { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/stat.h" + export * + } + module statvfs { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/statvfs.h" + export * + } + module time { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/time.h" + export * + } + module times { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/times.h" + export * + } + module types { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/types.h" + export * + } + module uio { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/uio.h" + export * + } + module un { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/un.h" + export * + } + module utsname { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/utsname.h" + export * + } + module wait { + header "@GLIBC_ARCH_INCLUDE_PATH@/sys/wait.h" + export * + } + } + module syslog { + header "@GLIBC_INCLUDE_PATH@/syslog.h" + export * + } + module tar { + header "@GLIBC_INCLUDE_PATH@/tar.h" + export * + } + module termios { + header "@GLIBC_INCLUDE_PATH@/termios.h" + export * + } + module ulimit { + header "@GLIBC_INCLUDE_PATH@/ulimit.h" + export * + } + module unistd { + header "@GLIBC_INCLUDE_PATH@/unistd.h" + export * + } + module utime { + header "@GLIBC_INCLUDE_PATH@/utime.h" + export * + } + module utmpx { + header "@GLIBC_INCLUDE_PATH@/utmpx.h" + export * + } + module wait { + header "@GLIBC_INCLUDE_PATH@/wait.h" + export * + } + module wordexp { + header "@GLIBC_INCLUDE_PATH@/wordexp.h" + export * + } + } +} diff --git a/stdlib/public/SDK/AppKit/AppKit.swift b/stdlib/public/SDK/AppKit/AppKit.swift index cb7de9c84f948..ccc54a0d4713c 100644 --- a/stdlib/public/SDK/AppKit/AppKit.swift +++ b/stdlib/public/SDK/AppKit/AppKit.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,7 +30,7 @@ struct _NSCursorMirror : _MirrorType { _preconditionFailure("_MirrorType access out of bounds") } - var summary: String { return ""} + var summary: String { return "" } var quickLookObject: PlaygroundQuickLook? { return .Some(.Image(_value.image)) @@ -46,57 +46,55 @@ extension NSCursor : _Reflectable { } struct _NSViewMirror : _MirrorType { - static var _views = NSMutableSet() + static var _views = Set() var _v : NSView - init(_ v : NSView) {_v = v} + init(_ v : NSView) { _v = v } - var value: Any { get { return _v } } + var value: Any { return _v } - var valueType: Any.Type { get { return (_v as Any).dynamicType } } + var valueType: Any.Type { return (_v as Any).dynamicType } - var objectIdentifier: ObjectIdentifier? { get { return .None } } + var objectIdentifier: ObjectIdentifier? { return .None } - var count: Int { get { return 0 } } + var count: Int { return 0 } subscript(_: Int) -> (String, _MirrorType) { _preconditionFailure("_MirrorType access out of bounds") } - var summary: String { get { return ""} } + var summary: String { return "" } - var quickLookObject: PlaygroundQuickLook? { get { - // adapted from the Xcode QuickLooks implementation - - var result: PlaygroundQuickLook? = nil + var quickLookObject: PlaygroundQuickLook? { + // adapted from the Xcode QuickLooks implementation + + var result: PlaygroundQuickLook? = nil + + // if you set NSView.needsDisplay, you can get yourself in a recursive scenario where the same view + // could need to draw itself in order to get a QLObject for itself, which in turn if your code was + // instrumented to log on-draw, would cause yourself to get back here and so on and so forth + // until you run out of stack and crash + // This code checks that we aren't trying to log the same view recursively - and if so just returns + // nil, which is probably a safer option than crashing + // FIXME: is there a way to say "cacheDisplayInRect butDoNotRedrawEvenIfISaidSo"? + if !_NSViewMirror._views.contains(_v) { + _NSViewMirror._views.insert(_v) - // if you set NSView.needsDisplay, you can get yourself in a recursive scenario where the same view - // could need to draw itself in order to get a QLObject for itself, which in turn if your code was - // instrumented to log on-draw, would cause yourself to get back here and so on and so forth - // until you run out of stack and crash - // This code checks that we aren't trying to log the same view recursively - and if so just returns - // nil, which is probably a safer option than crashing - // FIXME: is there a way to say "cacheDisplayInRect butDoNotRedrawEvenIfISaidSo"? - switch _NSViewMirror._views.member(_v) { - case nil: - _NSViewMirror._views.addObject(_v) - - let bounds = _v.bounds - if let b = _v.bitmapImageRepForCachingDisplayInRect(bounds) { - _v.cacheDisplayInRect(bounds, toBitmapImageRep: b) - result = .Some(.View(b)) - } - - _NSViewMirror._views.removeObject(_v) - default: () + let bounds = _v.bounds + if let b = _v.bitmapImageRepForCachingDisplayInRect(bounds) { + _v.cacheDisplayInRect(bounds, toBitmapImageRep: b) + result = .Some(.View(b)) } - return result - - } } + _NSViewMirror._views.remove(_v) + } + + return result + + } - var disposition : _MirrorDisposition { get { return .Aggregate } } + var disposition : _MirrorDisposition { return .Aggregate } } extension NSView : _Reflectable { diff --git a/stdlib/public/SDK/AppKit/NSError.swift b/stdlib/public/SDK/AppKit/NSError.swift index 457c86ff56f42..2a0eadd79aa28 100644 --- a/stdlib/public/SDK/AppKit/NSError.swift +++ b/stdlib/public/SDK/AppKit/NSError.swift @@ -28,14 +28,14 @@ public extension NSCocoaError { } public var isServiceError: Bool { - return rawValue >= 66560 && rawValue <= 66817; + return rawValue >= 66560 && rawValue <= 66817 } public var isSharingServiceError: Bool { - return rawValue >= 67072 && rawValue <= 67327; + return rawValue >= 67072 && rawValue <= 67327 } public var isTextReadWriteError: Bool { - return rawValue >= 65792 && rawValue <= 66303; + return rawValue >= 65792 && rawValue <= 66303 } } diff --git a/stdlib/public/SDK/AssetsLibrary/AssetsLibrary.swift b/stdlib/public/SDK/AssetsLibrary/AssetsLibrary.swift index 2b1b01914b6d1..60f30e0ceb636 100644 --- a/stdlib/public/SDK/AssetsLibrary/AssetsLibrary.swift +++ b/stdlib/public/SDK/AssetsLibrary/AssetsLibrary.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/Contacts/Contacts.swift b/stdlib/public/SDK/Contacts/Contacts.swift index 5bda8ff026bb4..f30a1dbb32bc5 100644 --- a/stdlib/public/SDK/Contacts/Contacts.swift +++ b/stdlib/public/SDK/Contacts/Contacts.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/CoreAudio/CoreAudio.swift b/stdlib/public/SDK/CoreAudio/CoreAudio.swift index 5857aa89f0fe6..647da5dc7fd54 100644 --- a/stdlib/public/SDK/CoreAudio/CoreAudio.swift +++ b/stdlib/public/SDK/CoreAudio/CoreAudio.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/CoreGraphics/CGFloat.swift.gyb b/stdlib/public/SDK/CoreGraphics/CGFloat.swift.gyb index 3b654ce53aabd..c2c3024636df2 100644 --- a/stdlib/public/SDK/CoreGraphics/CGFloat.swift.gyb +++ b/stdlib/public/SDK/CoreGraphics/CGFloat.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift index 480c60a5370bf..c7acf4ff78d07 100644 --- a/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift +++ b/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/CoreGraphics/CoreGraphicsMirrors.swift.gyb b/stdlib/public/SDK/CoreGraphics/CoreGraphicsMirrors.swift.gyb index 496cfee5da5cf..173c3ad6b5414 100644 --- a/stdlib/public/SDK/CoreGraphics/CoreGraphicsMirrors.swift.gyb +++ b/stdlib/public/SDK/CoreGraphics/CoreGraphicsMirrors.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/CoreImage/CoreImage.swift b/stdlib/public/SDK/CoreImage/CoreImage.swift index 444796780ff01..92b81eb187f1d 100644 --- a/stdlib/public/SDK/CoreImage/CoreImage.swift +++ b/stdlib/public/SDK/CoreImage/CoreImage.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/CoreMedia/CMTime.swift b/stdlib/public/SDK/CoreMedia/CMTime.swift index 9ae8db2f77fc4..4f9df9b444f33 100644 --- a/stdlib/public/SDK/CoreMedia/CMTime.swift +++ b/stdlib/public/SDK/CoreMedia/CMTime.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -67,7 +67,6 @@ extension CMTime { public func convertScale(newTimescale: Int32, method: CMTimeRoundingMethod) -> CMTime { - return CMTimeConvertScale(self, newTimescale, method) } } diff --git a/stdlib/public/SDK/CoreMedia/CMTimeRange.swift b/stdlib/public/SDK/CoreMedia/CMTimeRange.swift index e10138bf03db3..d6e0e2cf5ea11 100644 --- a/stdlib/public/SDK/CoreMedia/CMTimeRange.swift +++ b/stdlib/public/SDK/CoreMedia/CMTimeRange.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/CoreMedia/CoreMedia.swift b/stdlib/public/SDK/CoreMedia/CoreMedia.swift index bbf1b32ff46a7..ce986fe913e66 100644 --- a/stdlib/public/SDK/CoreMedia/CoreMedia.swift +++ b/stdlib/public/SDK/CoreMedia/CoreMedia.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/Darwin/Darwin.swift b/stdlib/public/SDK/Darwin/Darwin.swift index 47b19024b5ce6..3472f6b87e845 100644 --- a/stdlib/public/SDK/Darwin/Darwin.swift +++ b/stdlib/public/SDK/Darwin/Darwin.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -79,7 +79,8 @@ func _convertDarwinBooleanToBool(x: DarwinBoolean) -> Bool { @_transparent @warn_unused_result public func && ( - lhs: T, @autoclosure rhs: () -> DarwinBoolean + lhs: T, + @autoclosure rhs: () -> DarwinBoolean ) -> Bool { return lhs.boolValue ? rhs().boolValue : false } @@ -87,7 +88,8 @@ public func && ( @_transparent @warn_unused_result public func || ( - lhs: T, @autoclosure rhs: () -> DarwinBoolean + lhs: T, + @autoclosure rhs: () -> DarwinBoolean ) -> Bool { return lhs.boolValue ? true : rhs().boolValue } @@ -145,38 +147,98 @@ public var stderr : UnsafeMutablePointer { @warn_unused_result @_silgen_name("_swift_Darwin_open") -func _swift_Darwin_open(path: UnsafePointer, - _ oflag: CInt, _ mode: mode_t) -> CInt +func _swift_Darwin_open( + path: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t +) -> CInt @warn_unused_result @_silgen_name("_swift_Darwin_openat") func _swift_Darwin_openat(fd: CInt, _ path: UnsafePointer, - _ oflag: CInt, _ mode: mode_t) -> CInt + _ oflag: CInt, + _ mode: mode_t +) -> CInt @warn_unused_result -public func open(path: UnsafePointer, _ oflag: CInt) -> CInt { +public func open( + path: UnsafePointer, + _ oflag: CInt +) -> CInt { return _swift_Darwin_open(path, oflag, 0) } @warn_unused_result -public func open(path: UnsafePointer, _ oflag: CInt, - _ mode: mode_t) -> CInt { +public func open( + path: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t +) -> CInt { return _swift_Darwin_open(path, oflag, mode) } @warn_unused_result -public func openat(fd: CInt, _ path: UnsafePointer, - _ oflag: CInt) -> CInt { +public func openat( + fd: CInt, + _ path: UnsafePointer, + _ oflag: CInt +) -> CInt { return _swift_Darwin_openat(fd, path, oflag, 0) } @warn_unused_result -public func openat(fd: CInt, _ path: UnsafePointer, - _ oflag: CInt, _ mode: mode_t) -> CInt { +public func openat( + fd: CInt, + _ path: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t +) -> CInt { return _swift_Darwin_openat(fd, path, oflag, mode) } +@warn_unused_result +@_silgen_name("_swift_Darwin_fcntl") +internal func _swift_Darwin_fcntl( + fd: CInt, + _ cmd: CInt, + _ value: CInt +) -> CInt + +@warn_unused_result +@_silgen_name("_swift_Darwin_fcntlPtr") +internal func _swift_Darwin_fcntlPtr( + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer +) -> CInt + +@warn_unused_result +public func fcntl( + fd: CInt, + _ cmd: CInt +) -> CInt { + return _swift_Darwin_fcntl(fd, cmd, 0) +} + +@warn_unused_result +public func fcntl( + fd: CInt, + _ cmd: CInt, + _ value: CInt +) -> CInt { + return _swift_Darwin_fcntl(fd, cmd, value) +} + +@warn_unused_result +public func fcntl( + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer +) -> CInt { + return _swift_Darwin_fcntlPtr(fd, cmd, ptr) +} + public var S_IFMT: mode_t { return mode_t(0o170000) } public var S_IFIFO: mode_t { return mode_t(0o010000) } public var S_IFCHR: mode_t { return mode_t(0o020000) } diff --git a/stdlib/public/SDK/Darwin/Misc.mm b/stdlib/public/SDK/Darwin/Misc.mm index 207c7dbbfde1f..75e08b8a3f9c6 100644 --- a/stdlib/public/SDK/Darwin/Misc.mm +++ b/stdlib/public/SDK/Darwin/Misc.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -32,3 +32,13 @@ return sem_open(name, oflag, mode, value); } +extern "C" int +_swift_Darwin_fcntl(int fd, int cmd, int value) { + return fcntl(fd, cmd, value); +} + +extern "C" int +_swift_Darwin_fcntlPtr(int fd, int cmd, void* ptr) { + return fcntl(fd, cmd, ptr); +} + diff --git a/stdlib/public/SDK/Darwin/tgmath.swift.gyb b/stdlib/public/SDK/Darwin/tgmath.swift.gyb index 6dec54eb82fcd..db028e5851d5e 100644 --- a/stdlib/public/SDK/Darwin/tgmath.swift.gyb +++ b/stdlib/public/SDK/Darwin/tgmath.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/Dispatch/Dispatch.mm b/stdlib/public/SDK/Dispatch/Dispatch.mm index 0cc51299795cc..a8cbf16120366 100644 --- a/stdlib/public/SDK/Dispatch/Dispatch.mm +++ b/stdlib/public/SDK/Dispatch/Dispatch.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/Dispatch/Dispatch.swift b/stdlib/public/SDK/Dispatch/Dispatch.swift index 5bb6d3458f950..ddadf38ae5cd4 100644 --- a/stdlib/public/SDK/Dispatch/Dispatch.swift +++ b/stdlib/public/SDK/Dispatch/Dispatch.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -67,10 +67,10 @@ public var DISPATCH_QUEUE_PRIORITY_BACKGROUND: dispatch_queue_priority_t { @warn_unused_result public func dispatch_get_global_queue(identifier: qos_class_t, _ flags: UInt) -> dispatch_queue_t { - return dispatch_get_global_queue(Int(identifier.rawValue), flags); + return dispatch_get_global_queue(Int(identifier.rawValue), flags) } -public var DISPATCH_QUEUE_CONCURRENT : dispatch_queue_attr_t { +public var DISPATCH_QUEUE_CONCURRENT: dispatch_queue_attr_t { return _swift_dispatch_queue_concurrent() } @@ -79,7 +79,7 @@ public var DISPATCH_QUEUE_CONCURRENT : dispatch_queue_attr_t { internal func _swift_dispatch_queue_concurrent() -> dispatch_queue_attr_t // dispatch/data.h -public var dispatch_data_empty : dispatch_data_t { +public var dispatch_data_empty: dispatch_data_t { return _swift_dispatch_data_empty() } diff --git a/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift b/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift index 5996dcfa40b1f..bde1205bfcb6f 100644 --- a/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift +++ b/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/Foundation/Foundation.swift b/stdlib/public/SDK/Foundation/Foundation.swift index d2eaa0d7b0249..3e77580350cb5 100644 --- a/stdlib/public/SDK/Foundation/Foundation.swift +++ b/stdlib/public/SDK/Foundation/Foundation.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -313,8 +313,7 @@ extension Bool: _ObjectiveCBridgeable { } public init(_ number: NSNumber) { - if number.boolValue { self = true } - else { self = false } + self = number.boolValue } public static func _getObjectiveCType() -> Any.Type { @@ -696,7 +695,7 @@ final public class NSFastGenerator : GeneratorType { if count == 0 { return .None } } let next : AnyObject = state[0].itemsPtr[n]! - ++n + n += 1 return next } @@ -1044,15 +1043,25 @@ extension CGRectEdge { public typealias NSErrorPointer = AutoreleasingUnsafeMutablePointer +public // COMPILER_INTRINSIC +let _nilObjCError: ErrorType = _GenericObjCError.NilError + @warn_unused_result @_silgen_name("swift_convertNSErrorToErrorType") public // COMPILER_INTRINSIC -func _convertNSErrorToErrorType(error: NSError?) -> ErrorType +func _convertNSErrorToErrorType(error: NSError?) -> ErrorType { + if let error = error { + return error + } + return _nilObjCError +} @warn_unused_result @_silgen_name("swift_convertErrorTypeToNSError") public // COMPILER_INTRINSIC -func _convertErrorTypeToNSError(error: ErrorType) -> NSError +func _convertErrorTypeToNSError(error: ErrorType) -> NSError { + return unsafeDowncast(_bridgeErrorTypeToNSError(error)) +} //===----------------------------------------------------------------------===// // Variadic initializers and methods @@ -1161,7 +1170,7 @@ extension NSOrderedSet : ArrayLiteralConvertible { //===--- "Copy constructors" ----------------------------------------------===// // These are needed to make Cocoa feel natural since we eliminated -// implicit briding conversions from Objective-C to Swift +// implicit bridging conversions from Objective-C to Swift //===----------------------------------------------------------------------===// extension NSArray { diff --git a/stdlib/public/SDK/Foundation/FoundationMirrors.swift.gyb b/stdlib/public/SDK/Foundation/FoundationMirrors.swift.gyb index 8e0d0f3957d4c..3701a4182d632 100644 --- a/stdlib/public/SDK/Foundation/FoundationMirrors.swift.gyb +++ b/stdlib/public/SDK/Foundation/FoundationMirrors.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/Foundation/NSError.swift b/stdlib/public/SDK/Foundation/NSError.swift index e45a91dd40da3..d31a7d8747b17 100644 --- a/stdlib/public/SDK/Foundation/NSError.swift +++ b/stdlib/public/SDK/Foundation/NSError.swift @@ -26,14 +26,6 @@ public enum _GenericObjCError : ErrorType { case NilError } -/// An intrinsic used by the runtime to create an error when an -/// Objective-C API indicates failure but produces a nil error. -@warn_unused_result -@_silgen_name("swift_allocNilObjCError") -public func _allocNilObjCError() -> ErrorType { - return _GenericObjCError.NilError -} - /// An internal protocol to represent Swift error enums that map to standard /// Cocoa NSError domains. public protocol _ObjectiveCBridgeableErrorType : ErrorType { @@ -61,7 +53,7 @@ public func _stdlib_bridgeNSErrorToErrorType< } } -/// Helper protocol for _BridgedNSError, which used used to provide +/// Helper protocol for _BridgedNSError, which used to provide /// default implementations. public protocol __BridgedNSError : RawRepresentable, ErrorType { static var _NSErrorDomain: String { get } @@ -363,44 +355,44 @@ public extension NSCocoaError { @available(OSX, introduced=10.11) @available(iOS, introduced=9.0) public var isCoderError: Bool { - return rawValue >= 4864 && rawValue <= 4991; + return rawValue >= 4864 && rawValue <= 4991 } @available(OSX, introduced=10.5) @available(iOS, introduced=2.0) public var isExecutableError: Bool { - return rawValue >= 3584 && rawValue <= 3839; + return rawValue >= 3584 && rawValue <= 3839 } public var isFileError: Bool { - return rawValue >= 0 && rawValue <= 1023; + return rawValue >= 0 && rawValue <= 1023 } public var isFormattingError: Bool { - return rawValue >= 2048 && rawValue <= 2559; + return rawValue >= 2048 && rawValue <= 2559 } @available(OSX, introduced=10.6) @available(iOS, introduced=4.0) public var isPropertyListError: Bool { - return rawValue >= 3840 && rawValue <= 4095; + return rawValue >= 3840 && rawValue <= 4095 } @available(OSX, introduced=10.9) @available(iOS, introduced=7.0) public var isUbiquitousFileError: Bool { - return rawValue >= 4352 && rawValue <= 4607; + return rawValue >= 4352 && rawValue <= 4607 } @available(OSX, introduced=10.10) @available(iOS, introduced=8.0) public var isUserActivityError: Bool { - return rawValue >= 4608 && rawValue <= 4863; + return rawValue >= 4608 && rawValue <= 4863 } public var isValidationError: Bool { - return rawValue >= 1024 && rawValue <= 2047; + return rawValue >= 1024 && rawValue <= 2047 } @available(OSX, introduced=10.8) @available(iOS, introduced=6.0) public var isXPCConnectionError: Bool { - return rawValue >= 4096 && rawValue <= 4224; + return rawValue >= 4096 && rawValue <= 4224 } } diff --git a/stdlib/public/SDK/Foundation/NSStringAPI.swift b/stdlib/public/SDK/Foundation/NSStringAPI.swift index b4483a5ce74fd..9b569d4ac8e8a 100644 --- a/stdlib/public/SDK/Foundation/NSStringAPI.swift +++ b/stdlib/public/SDK/Foundation/NSStringAPI.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -54,7 +54,7 @@ func _countFormatSpecifiers(a: String) -> Int { lastChar = notPercentUTF16 } else { - ++count + count += 1 lastChar = c } } else { @@ -103,7 +103,7 @@ extension String { /// memory referred to by `index` func _withOptionalOutParameter( index: UnsafeMutablePointer, - @noescape body: (UnsafeMutablePointer)->Result + @noescape body: (UnsafeMutablePointer) -> Result ) -> Result { var utf16Index: Int = 0 let result = index._withBridgeValue(&utf16Index) { @@ -118,7 +118,7 @@ extension String { /// it into the memory referred to by `range` func _withOptionalOutParameter( range: UnsafeMutablePointer>, - @noescape body: (UnsafeMutablePointer)->Result + @noescape body: (UnsafeMutablePointer) -> Result ) -> Result { var nsRange = NSRange(location: 0, length: 0) let result = range._withBridgeValue(&nsRange) { @@ -141,7 +141,7 @@ extension String { var p = NSString.availableStringEncodings() while p.memory != 0 { result.append(p.memory) - ++p + p += 1 } return result } @@ -277,7 +277,7 @@ extension String { /// Returns a capitalized representation of the `String` /// using the specified locale. @warn_unused_result - public func capitalizedStringWithLocale(locale: NSLocale?) -> String{ + public func capitalizedStringWithLocale(locale: NSLocale?) -> String { return _ns.capitalizedStringWithLocale(locale) as String } @@ -479,7 +479,7 @@ extension String { // enumerateLinesUsingBlock:(void (^)(NSString *line, BOOL *stop))block /// Enumerates all the lines in a string. - public func enumerateLines(body: (line: String, inout stop: Bool)->()) { + public func enumerateLines(body: (line: String, inout stop: Bool) -> ()) { _ns.enumerateLinesUsingBlock { (line: String, stop: UnsafeMutablePointer) in @@ -511,7 +511,7 @@ extension String { options opts: NSLinguisticTaggerOptions, orthography: NSOrthography?, _ body: - (String, Range, Range, inout Bool)->() + (String, Range, Range, inout Bool) -> () ) { _ns.enumerateLinguisticTagsInRange( _toNSRange(range), @@ -546,7 +546,7 @@ extension String { _ body: ( substring: String?, substringRange: Range, enclosingRange: Range, inout Bool - )->() + ) -> () ) { _ns.enumerateSubstringsInRange(_toNSRange(range), options: opts) { var stop_ = false @@ -1181,7 +1181,7 @@ extension String { aSet: NSCharacterSet, options mask:NSStringCompareOptions = [], range aRange: Range? = nil - )-> Range? { + ) -> Range? { return _optionalRange( _ns.rangeOfCharacterFromSet( aSet, options: mask, @@ -1315,7 +1315,7 @@ extension String { allowedCharacters: NSCharacterSet ) -> String? { // FIXME: the documentation states that this method can return nil if the - // transformation is not possible, without going into futher details. The + // transformation is not possible, without going into further details. The // implementation can only return nil if malloc() returns nil, so in // practice this is not possible. Still, to be consistent with // documentation, we declare the method as returning an optional String. @@ -1369,7 +1369,7 @@ extension String { @available(*, unavailable, message="Use URLByAppendingPathExtension on NSURL instead.") public func stringByAppendingPathExtension(ext: String) -> String? { // FIXME: This method can return nil in practice, for example when self is - // an empty string. OTOH, this is not documented, documentatios says that + // an empty string. OTOH, this is not documented, documentation says that // it always returns a string. // // -[NSString stringByAppendingPathExtension] can @@ -1537,7 +1537,7 @@ extension String { // - (NSArray *)stringsByAppendingPaths:(NSArray *)paths /// Returns an array of strings made by separately appending - /// to the `String` each string in in a given array. + /// to the `String` each string in a given array. @available(*, unavailable, message="map over paths with URLByAppendingPathComponent instead.") public func stringsByAppendingPaths(paths: [String]) -> [String] { return _ns.stringsByAppendingPaths(paths) diff --git a/stdlib/public/SDK/Foundation/NSValue.swift b/stdlib/public/SDK/Foundation/NSValue.swift index 8b5cd61e931af..901712d6c76c6 100644 --- a/stdlib/public/SDK/Foundation/NSValue.swift +++ b/stdlib/public/SDK/Foundation/NSValue.swift @@ -1,8 +1,8 @@ -//===--- NSValue.swift - Bridging things in NSValue -------------*-swift-*-===// +//===--- NSValue.swift - Bridging things in NSValue -----------*- swift -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/Foundation/Thunks.mm b/stdlib/public/SDK/Foundation/Thunks.mm index fd1acbbb0d701..db45d8e2bc731 100644 --- a/stdlib/public/SDK/Foundation/Thunks.mm +++ b/stdlib/public/SDK/Foundation/Thunks.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/GLKit/GLKit.swift.gyb b/stdlib/public/SDK/GLKit/GLKit.swift.gyb index a8f76d51c1d76..01d58fb9c4aaa 100644 --- a/stdlib/public/SDK/GLKit/GLKit.swift.gyb +++ b/stdlib/public/SDK/GLKit/GLKit.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/GameplayKit/GameplayKit.mm b/stdlib/public/SDK/GameplayKit/GameplayKit.mm index 611526acf36b4..bcd0b4f4e5724 100644 --- a/stdlib/public/SDK/GameplayKit/GameplayKit.mm +++ b/stdlib/public/SDK/GameplayKit/GameplayKit.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/GameplayKit/GameplayKit.swift b/stdlib/public/SDK/GameplayKit/GameplayKit.swift index dc0bbd8726279..e65365105e70b 100644 --- a/stdlib/public/SDK/GameplayKit/GameplayKit.swift +++ b/stdlib/public/SDK/GameplayKit/GameplayKit.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift index 31cbc10a6fa8a..5d4b29fff19b0 100644 --- a/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift +++ b/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/OpenCL/OpenCL.swift b/stdlib/public/SDK/OpenCL/OpenCL.swift index 7d03dff926446..0a3012a9f5a95 100644 --- a/stdlib/public/SDK/OpenCL/OpenCL.swift +++ b/stdlib/public/SDK/OpenCL/OpenCL.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/SceneKit/SceneKit.swift b/stdlib/public/SDK/SceneKit/SceneKit.swift index 0154676e951b5..d78d1017d4e2b 100644 --- a/stdlib/public/SDK/SceneKit/SceneKit.swift +++ b/stdlib/public/SDK/SceneKit/SceneKit.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -121,7 +121,8 @@ extension SCNMatrix4 { extension float4x4 { public init(_ m: SCNMatrix4) { - self.init([ float4(Float(m.m11), Float(m.m12), Float(m.m13), Float(m.m14)), + self.init([ + float4(Float(m.m11), Float(m.m12), Float(m.m13), Float(m.m14)), float4(Float(m.m21), Float(m.m22), Float(m.m23), Float(m.m24)), float4(Float(m.m31), Float(m.m32), Float(m.m33), Float(m.m34)), float4(Float(m.m41), Float(m.m42), Float(m.m43), Float(m.m44)) @@ -131,7 +132,8 @@ extension float4x4 { extension double4x4 { public init(_ m: SCNMatrix4) { - self.init([ double4(Double(m.m11), Double(m.m12), Double(m.m13), Double(m.m14)), + self.init([ + double4(Double(m.m11), Double(m.m12), Double(m.m13), Double(m.m14)), double4(Double(m.m21), Double(m.m22), Double(m.m23), Double(m.m24)), double4(Double(m.m31), Double(m.m32), Double(m.m33), Double(m.m34)), double4(Double(m.m41), Double(m.m42), Double(m.m43), Double(m.m44)) diff --git a/stdlib/public/SDK/SceneKit/Thunks.mm b/stdlib/public/SDK/SceneKit/Thunks.mm index a92639fe4682a..733fc48d7031f 100644 --- a/stdlib/public/SDK/SceneKit/Thunks.mm +++ b/stdlib/public/SDK/SceneKit/Thunks.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/SpriteKit/SpriteKit.swift b/stdlib/public/SDK/SpriteKit/SpriteKit.swift index 2ad3548dbccb6..d03e5922e3db0 100644 --- a/stdlib/public/SDK/SpriteKit/SpriteKit.swift +++ b/stdlib/public/SDK/SpriteKit/SpriteKit.swift @@ -15,18 +15,3 @@ public typealias SKColor = UIColor override init() { _sanityCheckFailure("don't touch me") } @objc func _copyImageData() -> NSData! { return nil } } - -extension SKNode { - public subscript (name: String) -> [SKNode] { - // Note: Don't stomp on objectForKeyedSubscript: - @objc(_swiftObjectForKeyedSubscript:) get { - var nodes = [SKNode]() - enumerateChildNodesWithName(name) { node, stop in - nodes.append(node) - } - - return nodes - } - } -} - diff --git a/stdlib/public/SDK/SpriteKit/SpriteKitMirrors.swift.gyb b/stdlib/public/SDK/SpriteKit/SpriteKitMirrors.swift.gyb index 4f42d6b19230f..3c40b4314068b 100644 --- a/stdlib/public/SDK/SpriteKit/SpriteKitMirrors.swift.gyb +++ b/stdlib/public/SDK/SpriteKit/SpriteKitMirrors.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/UIKit/DesignatedInitializers.mm b/stdlib/public/SDK/UIKit/DesignatedInitializers.mm index 297f6f2ef5926..efd85a3eb4cd4 100644 --- a/stdlib/public/SDK/UIKit/DesignatedInitializers.mm +++ b/stdlib/public/SDK/UIKit/DesignatedInitializers.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/UIKit/UIKit.swift b/stdlib/public/SDK/UIKit/UIKit.swift index 0fe7bfb3a99b6..0c806e7c64c37 100644 --- a/stdlib/public/SDK/UIKit/UIKit.swift +++ b/stdlib/public/SDK/UIKit/UIKit.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,7 +21,7 @@ import Foundation @_transparent // @fragile @warn_unused_result public func == (lhs: UIEdgeInsets, rhs: UIEdgeInsets) -> Bool { - return lhs.top == rhs.top && + return lhs.top == rhs.top && lhs.left == rhs.left && lhs.bottom == rhs.bottom && lhs.right == rhs.right @@ -32,7 +32,7 @@ extension UIEdgeInsets : Equatable {} @_transparent // @fragile @warn_unused_result public func == (lhs: UIOffset, rhs: UIOffset) -> Bool { - return lhs.horizontal == rhs.horizontal && + return lhs.horizontal == rhs.horizontal && lhs.vertical == rhs.vertical } @@ -46,26 +46,24 @@ extension UIOffset : Equatable {} #if !os(watchOS) && !os(tvOS) public extension UIDeviceOrientation { - var isLandscape: Bool { - get { return self == .LandscapeLeft || self == .LandscapeRight } + var isLandscape: Bool { + return self == .LandscapeLeft || self == .LandscapeRight } - var isPortrait: Bool { - get { return self == .Portrait || self == .PortraitUpsideDown } + var isPortrait: Bool { + return self == .Portrait || self == .PortraitUpsideDown } var isFlat: Bool { - get { return self == .FaceUp || self == .FaceDown } + return self == .FaceUp || self == .FaceDown } var isValidInterfaceOrientation: Bool { - get { - switch (self) { - case .Portrait, .PortraitUpsideDown, .LandscapeLeft, .LandscapeRight: - return true - default: - return false - } + switch (self) { + case .Portrait, .PortraitUpsideDown, .LandscapeLeft, .LandscapeRight: + return true + default: + return false } } } @@ -81,7 +79,7 @@ public func UIDeviceOrientationIsLandscape( public func UIDeviceOrientationIsPortrait( orientation: UIDeviceOrientation ) -> Bool { - return orientation.isPortrait + return orientation.isPortrait } @warn_unused_result @@ -98,12 +96,12 @@ public func UIDeviceOrientationIsValidInterfaceOrientation( #if !os(watchOS) && !os(tvOS) public extension UIInterfaceOrientation { - var isLandscape: Bool { - get { return self == .LandscapeLeft || self == .LandscapeRight } + var isLandscape: Bool { + return self == .LandscapeLeft || self == .LandscapeRight } - var isPortrait: Bool { - get { return self == .Portrait || self == .PortraitUpsideDown } + var isPortrait: Bool { + return self == .Portrait || self == .PortraitUpsideDown } } @@ -169,67 +167,63 @@ public extension UIAlertView { #if !os(watchOS) struct _UIViewMirror : _MirrorType { - static var _views = NSMutableSet() + static var _views = Set() var _v : UIView - init(_ v : UIView) {_v = v} + init(_ v : UIView) { _v = v } - var value: Any { get { return _v } } + var value: Any { return _v } - var valueType: Any.Type { get { return (_v as Any).dynamicType } } + var valueType: Any.Type { return (_v as Any).dynamicType } - var objectIdentifier: ObjectIdentifier? { get { return .None } } + var objectIdentifier: ObjectIdentifier? { return .None } - var count: Int { get { return 0 } } + var count: Int { return 0 } subscript(_: Int) -> (String, _MirrorType) { _preconditionFailure("_MirrorType access out of bounds") } - var summary: String { get { return ""} } + var summary: String { return "" } var quickLookObject: PlaygroundQuickLook? { - // iOS 7 or greater only + // iOS 7 or greater only + + var result: PlaygroundQuickLook? = nil + + if !_UIViewMirror._views.contains(_v) { + _UIViewMirror._views.insert(_v) - var result: PlaygroundQuickLook? = nil + let bounds = _v.bounds + // in case of an empty rectangle abort the logging + if (bounds.size.width == 0) || (bounds.size.height == 0) { + return nil + } - switch _UIViewMirror._views.member(_v) { - case nil: - _UIViewMirror._views.addObject(_v) - - let bounds = _v.bounds - // in case of an empty rectangle abort the logging - if (bounds.size.width == 0) || (bounds.size.height == 0) { - return nil - } + UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0) - UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0) - - // UIKit is about to update this to be optional, so make it work - // with both older and newer SDKs. (In this context it should always - // be present.) - let ctx: CGContext! = UIGraphicsGetCurrentContext() - UIColor(white:1.0, alpha:0.0).set() - CGContextFillRect(ctx, bounds) - _v.layer.renderInContext(ctx) - - let image: UIImage! = UIGraphicsGetImageFromCurrentImageContext() + // UIKit is about to update this to be optional, so make it work + // with both older and newer SDKs. (In this context it should always + // be present.) + let ctx: CGContext! = UIGraphicsGetCurrentContext() + UIColor(white:1.0, alpha:0.0).set() + CGContextFillRect(ctx, bounds) + _v.layer.renderInContext(ctx) - UIGraphicsEndImageContext() + let image: UIImage! = UIGraphicsGetImageFromCurrentImageContext() - result = .Some(.View(image)) - - _UIViewMirror._views.removeObject(_v) - - default: () - } - - - return result + UIGraphicsEndImageContext() + + result = .Some(.View(image)) + + _UIViewMirror._views.remove(_v) + } + + return result } - var disposition : _MirrorDisposition { get { return .Aggregate } } + var disposition : _MirrorDisposition { return .Aggregate } } extension UIView : _Reflectable { diff --git a/stdlib/public/SDK/WatchKit/WatchKit.swift b/stdlib/public/SDK/WatchKit/WatchKit.swift index 0b181e5c5c7a2..0bf1b20e813cb 100644 --- a/stdlib/public/SDK/WatchKit/WatchKit.swift +++ b/stdlib/public/SDK/WatchKit/WatchKit.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SDK/XCTest/XCTest.swift b/stdlib/public/SDK/XCTest/XCTest.swift index 1efa98ad73552..f9784a7a28d42 100644 --- a/stdlib/public/SDK/XCTest/XCTest.swift +++ b/stdlib/public/SDK/XCTest/XCTest.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -153,7 +153,7 @@ public func XCTAssertNotNil(@autoclosure expression: () -> Any?, _ message: Stri public func XCTAssert( @autoclosure expression: () -> BooleanType, _ message: String = "", file: String = __FILE__, line: UInt = __LINE__) -> Void { // XCTAssert is just a cover for XCTAssertTrue. - XCTAssertTrue(expression, message, file: file, line: line); + XCTAssertTrue(expression, message, file: file, line: line) } public func XCTAssertTrue(@autoclosure expression: () -> BooleanType, _ message: String = "", file: String = __FILE__, line: UInt = __LINE__) -> Void { diff --git a/stdlib/public/SDK/XCTest/XCTestCaseAdditions.mm b/stdlib/public/SDK/XCTest/XCTestCaseAdditions.mm index 774ae730d9098..55491bfecf82b 100644 --- a/stdlib/public/SDK/XCTest/XCTestCaseAdditions.mm +++ b/stdlib/public/SDK/XCTest/XCTestCaseAdditions.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -12,6 +12,8 @@ #import #include "swift/Runtime/Metadata.h" +#include "swift/Basic/Demangle.h" +#include "swift/Strings.h" // NOTE: This is a temporary workaround. // XCTestCase needs the unmangled version of a test case name, so let -className @@ -22,6 +24,85 @@ @interface XCTest (WarningAvoidance) @property (readonly, copy) NSString *className; @end +static char *scanIdentifier(const char *&mangled) +{ + const char *original = mangled; + + { + if (*mangled == '0') goto fail; // length may not be zero + + size_t length = 0; + while (swift::Demangle::isDigit(*mangled)) { + size_t oldlength = length; + length *= 10; + length += *mangled++ - '0'; + if (length <= oldlength) goto fail; // integer overflow + } + + if (length == 0) goto fail; + if (length > strlen(mangled)) goto fail; + + char *result = strndup(mangled, length); + assert(result); + mangled += length; + return result; + } + +fail: + mangled = original; // rewind + return nullptr; +} + + +/// \brief Demangle a mangled class name into module+class. +/// Returns true if the name was successfully decoded. +/// On success, *outModule and *outClass must be freed with free(). +/// FIXME: this should be replaced by a real demangler +static bool demangleSimpleClass(const char *mangledName, + char **outModule, char **outClass) { + char *moduleName = nullptr; + char *className = nullptr; + + { + // Prefix for a mangled class + const char *m = mangledName; + if (0 != strncmp(m, "_TtC", 4)) + goto fail; + m += 4; + + // Module name + if (strncmp(m, "Ss", 2) == 0) { + moduleName = strdup(swift::STDLIB_NAME); + assert(moduleName); + m += 2; + } else { + moduleName = scanIdentifier(m); + if (!moduleName) + goto fail; + } + + // Class name + className = scanIdentifier(m); + if (!className) + goto fail; + + // Nothing else + if (strlen(m)) + goto fail; + + *outModule = moduleName; + *outClass = className; + return true; + } + +fail: + if (moduleName) free(moduleName); + if (className) free(className); + *outModule = nullptr; + *outClass = nullptr; + return false; +} + @implementation XCTestCase (SwiftAdditions) - (NSString *)className @@ -30,8 +111,8 @@ - (NSString *)className char *modulePart; char *classPart; - bool ok = swift::swift_demangleSimpleClass([className UTF8String], - &modulePart, &classPart); + bool ok = demangleSimpleClass([className UTF8String], + &modulePart, &classPart); if (ok) { className = [NSString stringWithUTF8String:classPart]; diff --git a/stdlib/public/SDK/simd/simd.swift.gyb b/stdlib/public/SDK/simd/simd.swift.gyb index f3b297667b35d..d94387a2457ec 100644 --- a/stdlib/public/SDK/simd/simd.swift.gyb +++ b/stdlib/public/SDK/simd/simd.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SwiftShims/CMakeLists.txt b/stdlib/public/SwiftShims/CMakeLists.txt index 14d8f2c66afd4..3fae8a13c95de 100644 --- a/stdlib/public/SwiftShims/CMakeLists.txt +++ b/stdlib/public/SwiftShims/CMakeLists.txt @@ -55,7 +55,6 @@ if(SWIFT_BUILT_STANDALONE) set(clang_headers_location) foreach(loc ${clang_headers_locations}) - message(WARNING "go: ${loc}") if(EXISTS "${loc}") set(clang_headers_location "${loc}") break() diff --git a/stdlib/public/SwiftShims/CoreFoundationShims.h b/stdlib/public/SwiftShims/CoreFoundationShims.h index 515eff44d8256..eb586681299f0 100644 --- a/stdlib/public/SwiftShims/CoreFoundationShims.h +++ b/stdlib/public/SwiftShims/CoreFoundationShims.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SwiftShims/FoundationShims.h b/stdlib/public/SwiftShims/FoundationShims.h index 36e2942ac38e7..82d70bdc814cb 100644 --- a/stdlib/public/SwiftShims/FoundationShims.h +++ b/stdlib/public/SwiftShims/FoundationShims.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,7 +21,7 @@ //===--- Layout-compatible clones of Foundation structs -------------------===// // Ideally we would declare the same names as Foundation does, but -// swift's module importer is not yet tolerant of the same struct +// Swift's module importer is not yet tolerant of the same struct // coming in from two different Clang modules // (rdar://problem/16294674). Instead, we copy the definitions here // and then do horrible unsafeBitCast trix to make them usable where required. diff --git a/stdlib/public/SwiftShims/GlobalObjects.h b/stdlib/public/SwiftShims/GlobalObjects.h index 8355f22319b35..9f3fab44982e6 100644 --- a/stdlib/public/SwiftShims/GlobalObjects.h +++ b/stdlib/public/SwiftShims/GlobalObjects.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SwiftShims/HeapObject.h b/stdlib/public/SwiftShims/HeapObject.h index 9c5c89f8f44ed..cc4b0dbf16c45 100644 --- a/stdlib/public/SwiftShims/HeapObject.h +++ b/stdlib/public/SwiftShims/HeapObject.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SwiftShims/LibcShims.h b/stdlib/public/SwiftShims/LibcShims.h index d0d15280c095d..e5e63e3142b6d 100644 --- a/stdlib/public/SwiftShims/LibcShims.h +++ b/stdlib/public/SwiftShims/LibcShims.h @@ -1,8 +1,8 @@ -//===--- LibcShims.h - Access to POSIX for Swift's core stdlib -----------===// +//===--- LibcShims.h - Access to POSIX for Swift's core stdlib ------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,7 +28,11 @@ namespace swift { extern "C" { // This declaration is not universally correct. We verify its correctness for // the current platform in the runtime code. +#if defined(__linux__) && defined (__arm__) +typedef int __swift_ssize_t; +#else typedef long int __swift_ssize_t; +#endif // General utilities // Memory management functions diff --git a/stdlib/public/SwiftShims/RefCount.h b/stdlib/public/SwiftShims/RefCount.h index 648199fcc943f..fcb2a14211963 100644 --- a/stdlib/public/SwiftShims/RefCount.h +++ b/stdlib/public/SwiftShims/RefCount.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -275,8 +275,6 @@ class WeakRefCount { enum : uint32_t { // There isn't really a flag here. - // Making weak RC_ONE == strong RC_ONE saves an - // instruction in allocation on arm64. RC_UNUSED_FLAG = 1, RC_FLAGS_COUNT = 1, diff --git a/stdlib/public/SwiftShims/RuntimeShims.h b/stdlib/public/SwiftShims/RuntimeShims.h index 54e785ecbf6e1..f3e34249187a5 100644 --- a/stdlib/public/SwiftShims/RuntimeShims.h +++ b/stdlib/public/SwiftShims/RuntimeShims.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -27,10 +27,7 @@ namespace swift { extern "C" { #define bool _Bool #endif -bool _swift_usesNativeSwiftReferenceCounting_nonNull(const void *); -bool _swift_usesNativeSwiftReferenceCounting_class(const void *); - -__swift_size_t _swift_class_getInstancePositiveExtentSize(const void *); +bool swift_objc_class_usesNativeSwiftReferenceCounting(const void *); /// Return an NSString to be used as the Mirror summary of the object void *_swift_objCMirrorSummary(const void * nsObject); @@ -39,11 +36,11 @@ void *_swift_objCMirrorSummary(const void * nsObject); /// types so we can operate on Float80. Return NULL on overflow. const char *_swift_stdlib_strtold_clocale(const char *nptr, void *outResult); /// Call strtod_l with the C locale, swapping argument and return -/// types so we can operate constistently on Float80. Return NULL on +/// types so we can operate consistently on Float80. Return NULL on /// overflow. const char *_swift_stdlib_strtod_clocale(const char *nptr, double *outResult); /// Call strtof_l with the C locale, swapping argument and return -/// types so we can operate constistently on Float80. Return NULL on +/// types so we can operate consistently on Float80. Return NULL on /// overflow. const char *_swift_stdlib_strtof_clocale(const char *nptr, float *outResult); @@ -51,7 +48,7 @@ struct Metadata; /// Return the superclass, if any. The result is nullptr for root /// classes and class protocol types. -const struct Metadata *_swift_getSuperclass_nonNull( +const struct Metadata *swift_class_getSuperclass( const struct Metadata *); void _swift_stdlib_flockfile_stdout(void); diff --git a/stdlib/public/SwiftShims/RuntimeStubs.h b/stdlib/public/SwiftShims/RuntimeStubs.h index 286b82900d344..322870b6da4f3 100644 --- a/stdlib/public/SwiftShims/RuntimeStubs.h +++ b/stdlib/public/SwiftShims/RuntimeStubs.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SwiftShims/SwiftStddef.h b/stdlib/public/SwiftShims/SwiftStddef.h index aa9ab9e5a1bd1..cca2204975302 100644 --- a/stdlib/public/SwiftShims/SwiftStddef.h +++ b/stdlib/public/SwiftShims/SwiftStddef.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SwiftShims/SwiftStdint.h b/stdlib/public/SwiftShims/SwiftStdint.h index 20bfdc8b2c805..f9e0fdeb5cbd9 100644 --- a/stdlib/public/SwiftShims/SwiftStdint.h +++ b/stdlib/public/SwiftShims/SwiftStdint.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/SwiftShims/UnicodeShims.h b/stdlib/public/SwiftShims/UnicodeShims.h index 0431d74140c83..a874e8da2921e 100644 --- a/stdlib/public/SwiftShims/UnicodeShims.h +++ b/stdlib/public/SwiftShims/UnicodeShims.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/common/MirrorBoilerplate.gyb b/stdlib/public/common/MirrorBoilerplate.gyb index b61a14cc99631..972c22b1dddbb 100644 --- a/stdlib/public/common/MirrorBoilerplate.gyb +++ b/stdlib/public/common/MirrorBoilerplate.gyb @@ -3,7 +3,7 @@ #// #// This source file is part of the Swift.org open source project #// -#// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +#// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors #// Licensed under Apache License v2.0 with Runtime Library Exception #// #// See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/common/MirrorCommon.py b/stdlib/public/common/MirrorCommon.py index 94f394338b491..8471f944fbc99 100644 --- a/stdlib/public/common/MirrorCommon.py +++ b/stdlib/public/common/MirrorCommon.py @@ -1,36 +1,39 @@ -#//===--- MirrorCommon.py -------------------------------------*- python -*-===// -#// -#// This source file is part of the Swift.org open source project -#// -#// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -#// Licensed under Apache License v2.0 with Runtime Library Exception -#// -#// See http://swift.org/LICENSE.txt for license information -#// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -#// -#//===----------------------------------------------------------------------===// +# MirrorCommon.py -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ----------------------------------------------------------------------------- +# # This file contains utility functions that are used by the gyb template files # that generate Mirrors for the Swift Standard Library. # If you edit this, make sure to also accordingly tweak the actual template files. +# +# ----------------------------------------------------------------------------- def getDisposition(disp=None): - if disp == None: + if disp is None: return '.Aggregate' if len(disp) == 0 or disp[0] != '.': disp = '.' + disp return disp -def _getGenericArgStrings(genericArgs=None,genericConstraints=None): - if genericArgs == None: +def _getGenericArgStrings(genericArgs=None, genericConstraints=None): + if genericArgs is None: return ('','') genericArgString = '' first = True for arg in genericArgs: if not first: - genericArgString = genericArgString + ',' + genericArgString = genericArgString + ',' first = False genericArgString = genericArgString + arg - if genericConstraints == None: + if genericConstraints is None: genericConstraintString = genericArgString else: genericConstraintString = '' @@ -45,11 +48,11 @@ def _getGenericArgStrings(genericArgs=None,genericConstraints=None): genericConstraintString = genericConstraintString + ' : ' + cons genericArgString = '<' + genericArgString + '>' genericConstraintString = '<' + genericConstraintString + '>' - return (genericArgString,genericConstraintString) + return (genericArgString, genericConstraintString) -def getGenericArgString(genericArgs=None,genericConstraints=None): - return _getGenericArgStrings(genericArgs,genericConstraints)[0] +def getGenericArgString(genericArgs=None, genericConstraints=None): + return _getGenericArgStrings(genericArgs, genericConstraints)[0] -def getGenericConstraintString(genericArgs=None,genericConstraints=None): - return _getGenericArgStrings(genericArgs,genericConstraints)[1] +def getGenericConstraintString(genericArgs=None, genericConstraints=None): + return _getGenericArgStrings(genericArgs, genericConstraints)[1] diff --git a/stdlib/public/common/MirrorConformance.gyb b/stdlib/public/common/MirrorConformance.gyb index 00f6922ca1765..e95b7b4e63fbb 100644 --- a/stdlib/public/common/MirrorConformance.gyb +++ b/stdlib/public/common/MirrorConformance.gyb @@ -3,7 +3,7 @@ #// #// This source file is part of the Swift.org open source project #// -#// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +#// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors #// Licensed under Apache License v2.0 with Runtime Library Exception #// #// See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/common/MirrorDecl.gyb b/stdlib/public/common/MirrorDecl.gyb index 67b6d4bfebb50..338be26af1214 100644 --- a/stdlib/public/common/MirrorDecl.gyb +++ b/stdlib/public/common/MirrorDecl.gyb @@ -3,7 +3,7 @@ #// #// This source file is part of the Swift.org open source project #// -#// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +#// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors #// Licensed under Apache License v2.0 with Runtime Library Exception #// #// See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Algorithm.swift b/stdlib/public/core/Algorithm.swift index 770971bec5bb9..f7d09443d01f1 100644 --- a/stdlib/public/core/Algorithm.swift +++ b/stdlib/public/core/Algorithm.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -44,59 +44,50 @@ public func find< } /// Returns the lesser of `x` and `y`. +/// +/// If `x == y`, returns `x`. @warn_unused_result public func min(x: T, _ y: T) -> T { - var r = x - if y < x { - r = y - } - return r + // In case `x == y` we pick `x`. + // This preserves any pre-existing order in case `T` has identity, + // which is important for e.g. the stability of sorting algorithms. + // `(min(x, y), max(x, y))` should return `(x, y)` in case `x == y`. + return y < x ? y : x } /// Returns the least argument passed. +/// +/// If there are multiple equal least arguments, returns the first one. @warn_unused_result public func min(x: T, _ y: T, _ z: T, _ rest: T...) -> T { - var r = x - if y < x { - r = y - } - if z < r { - r = z - } - for t in rest { - if t < r { - r = t - } + var minValue = min(min(x, y), z) + // In case `value == minValue`, we pick `minValue`. See min(_:_:). + for value in rest where value < minValue { + minValue = value } - return r + return minValue } /// Returns the greater of `x` and `y`. +/// +/// If `x == y`, returns `y`. @warn_unused_result public func max(x: T, _ y: T) -> T { - var r = y - if y < x { - r = x - } - return r + // In case `x == y`, we pick `y`. See min(_:_:). + return y >= x ? y : x } /// Returns the greatest argument passed. +/// +/// If there are multiple equal greatest arguments, returns the last one. @warn_unused_result public func max(x: T, _ y: T, _ z: T, _ rest: T...) -> T { - var r = y - if y < x { - r = x - } - if r < z { - r = z - } - for t in rest { - if t >= r { - r = t - } + var maxValue = max(max(x, y), z) + // In case `value == maxValue`, we pick `value`. See min(_:_:). + for value in rest where value >= maxValue { + maxValue = value } - return r + return maxValue } /// Returns the result of slicing `elements` into sub-sequences that @@ -164,12 +155,11 @@ public struct EnumerateGenerator< /// The type of element returned by `next()`. public typealias Element = (index: Int, element: Base.Element) var base: Base - var count: Int + var count: Int = 0 /// Construct from a `Base` generator. public init(_ base: Base) { self.base = base - count = 0 } /// Advance to the next element and return it, or `nil` if no next @@ -177,9 +167,9 @@ public struct EnumerateGenerator< /// /// - Requires: No preceding call to `self.next()` has returned `nil`. public mutating func next() -> Element? { - let b = base.next() - if b == nil { return .None } - return .Some((index: count++, element: b!)) + guard let b = base.next() else { return nil } + defer { count += 1 } + return (index: count, element: b) } } diff --git a/stdlib/public/core/ArrayBody.swift b/stdlib/public/core/ArrayBody.swift index 25d74c4020299..e13d2c8b3a0e6 100644 --- a/stdlib/public/core/ArrayBody.swift +++ b/stdlib/public/core/ArrayBody.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/ArrayBuffer.swift b/stdlib/public/core/ArrayBuffer.swift index 1f7426cf1878e..a4dc1ab3b22c4 100644 --- a/stdlib/public/core/ArrayBuffer.swift +++ b/stdlib/public/core/ArrayBuffer.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -49,7 +49,7 @@ public struct _ArrayBuffer : _ArrayBufferType { var deferredTypeCheckMask : Int { return 1 } /// Returns an `_ArrayBuffer` containing the same elements, - /// deffering checking each element's `U`-ness until it is accessed. + /// deferring checking each element's `U`-ness until it is accessed. /// /// - Requires: `U` is a class or `@objc` existential derived from `Element`. @warn_unused_result @@ -88,10 +88,6 @@ extension _ArrayBuffer { _storage = _ArrayBridgeStorage(native: source._storage) } - var arrayPropertyIsNative : Bool { - return _isNative - } - /// `true`, if the array is native and does not need a deferred type check. var arrayPropertyIsNativeTypeChecked : Bool { return _isNativeTypeChecked @@ -179,7 +175,7 @@ extension _ArrayBuffer { element is Element, "Down-casted Array element failed to match the target type") } - else { + else { let ns = _nonNative _precondition( ns.objectAtIndex(index) is Element, @@ -229,7 +225,7 @@ extension _ArrayBuffer { var result = target for _ in subRange { result.initialize(result.memory) - ++result + result += 1 } return result } diff --git a/stdlib/public/core/ArrayBufferType.swift b/stdlib/public/core/ArrayBufferType.swift index f84fc7d13fe3a..b3090173a5176 100644 --- a/stdlib/public/core/ArrayBufferType.swift +++ b/stdlib/public/core/ArrayBufferType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -35,7 +35,7 @@ public protocol _ArrayBufferType : MutableCollectionType { /// If this buffer is backed by a uniquely-referenced mutable /// `_ContiguousArrayBuffer` that can be grown in-place to allow the `self` /// buffer store `minimumCapacity` elements, returns that buffer. - /// Otherwise, returns nil. + /// Otherwise, returns `nil`. /// /// - Note: The result's firstElementAddress may not match ours, if we are a /// _SliceBuffer. @@ -159,11 +159,13 @@ extension _ArrayBufferType { // Assign over the original subRange var i = newValues.startIndex for j in subRange { - elements[j] = newValues[i++] + elements[j] = newValues[i] + i._successorInPlace() } // Initialize the hole left by sliding the tail forward for j in oldTailIndex..( let bridged: AnyObject? = _bridgeToObjectiveC(value) _precondition( bridged != nil, "array element cannot be bridged to Objective-C") - // FIXME: should be an unsafeDowncast, but for - p++.initialize(unsafeBitCast(bridged!, TargetElement.self)) + // FIXME: should be an unsafeDowncast. + p.initialize(unsafeBitCast(bridged!, TargetElement.self)) + p += 1 } } return Array(_ArrayBuffer(buf, shiftedToStartIndex: 0)) @@ -162,7 +163,8 @@ ElementwiseBridging: if _slowPath(value == nil) { break ElementwiseBridging } - p++.initialize(value!) + p.initialize(value!) + p += 1 } return Array(_ArrayBuffer(buf, shiftedToStartIndex: 0)) } diff --git a/stdlib/public/core/ArrayType.swift b/stdlib/public/core/ArrayType.swift index 2a5ea0fc4c90b..3a15cd15a65b0 100644 --- a/stdlib/public/core/ArrayType.swift +++ b/stdlib/public/core/ArrayType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -45,7 +45,7 @@ protocol _ArrayType /// - Postcondition: `capacity >= minimumCapacity` and the array has /// mutable contiguous storage. /// - /// - Complexity: O(`count`). + /// - Complexity: O(`self.count`). mutating func reserveCapacity(minimumCapacity: Int) /// Operator form of `appendContentsOf`. diff --git a/stdlib/public/core/Arrays.swift.gyb b/stdlib/public/core/Arrays.swift.gyb index 7badea9b687ab..482b571d7d38e 100644 --- a/stdlib/public/core/Arrays.swift.gyb +++ b/stdlib/public/core/Arrays.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,11 +19,14 @@ // contiguous sequence of `Element`s. // // - `Array` is like `ContiguousArray` when `Element` is not -// an reference type or an Objective-C existential. Otherwise, it may use +// a reference type or an Objective-C existential. Otherwise, it may use // an `NSArray` bridged from Cocoa for storage. // //===----------------------------------------------------------------------===// +/// This type is used as a result of the _checkSubscript call to associate the +/// call with the array access call it guards. +public struct _DependenceToken {} %{ arrayTypes = [ @@ -119,7 +122,7 @@ if True: /// property, these array types have a `capacity` that reflects their /// potential to store elements without reallocation, and when you /// know how many elements you'll store, you can call -/// `reserveCapacity` to pre-emptively reallocate and prevent +/// `reserveCapacity` to preemptively reallocate and prevent /// intermediate reallocations. /// /// Objective-C Bridge @@ -140,7 +143,7 @@ if True: /// sequence of mutating operations causes elements to be copied into /// unique, contiguous storage which may cost `O(N)` time and space, /// where `N` is the length of the array (or more, if the underlying -/// `NSArray` is has unusual performance characteristics). +/// `NSArray` has unusual performance characteristics). /// /// Bridging to Objective-C /// ----------------------- @@ -207,7 +210,6 @@ public struct ${Self} /// Access the `index`th element. Reading is O(1). Writing is /// ${O1}. public subscript(index: Int) -> Element { -%if Self == 'Array': get { // This call may be hoisted or eliminated by the optimizer. If // there is an inout violation, this value may be stale so needs to be @@ -216,25 +218,13 @@ public struct ${Self} // Make sure the index is in range and wasNativeTypeChecked is // still valid. - _checkSubscript(index, wasNativeTypeChecked: wasNativeTypeChecked) + let token = _checkSubscript( + index, wasNativeTypeChecked: wasNativeTypeChecked) - return _getElement(index, wasNativeTypeChecked: wasNativeTypeChecked) + return _getElement( + index, wasNativeTypeChecked: wasNativeTypeChecked, + matchingSubscriptCheck: token) } -%elif Self == 'ContiguousArray': - addressWithNativeOwner { - _checkSubscript_native(index) - return ( - UnsafePointer(_buffer.subscriptBaseAddress + index), - Builtin.castToNativeObject(_buffer.owner)) - } -%else: - addressWithOwner { - _checkSubscript_native(index) - return ( - UnsafePointer(_buffer.subscriptBaseAddress + index), - Builtin.castToUnknownObject(_buffer.owner)) - } -%end mutableAddressWithPinnedNativeOwner { _makeMutableAndUniqueOrPinned() // makes the array native, too _checkSubscript_native(index) @@ -245,14 +235,22 @@ public struct ${Self} /// Access the `index`th element. Reading is O(1). Writing is /// ${O1}. public subscript(index: Int) -> Element { - - addressWithNativeOwner { - _checkSubscript_native(index) - return ( - UnsafePointer(_buffer.subscriptBaseAddress + index), - Builtin.castToNativeObject(_buffer.owner)) + get { + // This call may be hoisted or eliminated by the optimizer. If + // there is an inout violation, this value may be stale so needs to be + // checked again below. + let wasNativeTypeChecked = _hoistableIsNativeTypeChecked() + + // Make sure the index is in range and wasNativeTypeChecked is + // still valid. + let token = _checkSubscript( + index, wasNativeTypeChecked: wasNativeTypeChecked) + + return _getElement( + index, wasNativeTypeChecked: wasNativeTypeChecked, + matchingSubscriptCheck: token) } - + mutableAddressWithPinnedNativeOwner { _makeMutableAndUniqueOrPinned() _checkSubscript_native(index) @@ -283,13 +281,6 @@ public struct ${Self} //===--- private --------------------------------------------------------===// - @warn_unused_result - @_semantics("array.props.isNative") - public // @testable - func _getArrayPropertyIsNative() -> Bool { - return _buffer.arrayPropertyIsNative - } - /// Returns true if the array is native and does not need a deferred /// type check. May be hoisted by the optimizer, which means its /// results may be stale by the time they are used if there is an @@ -338,7 +329,7 @@ public struct ${Self} } // Don't inline copyBuffer - this would inline the copy loop into the current - // path preventing retains/releases to be matched accross that region. + // path preventing retains/releases to be matched across that region. @inline(never) static internal func _copyBuffer(inout buffer: _Buffer) { let newBuffer = _ContiguousArrayBuffer( @@ -374,20 +365,25 @@ public struct ${Self} % end } -% if Self == 'Array': /// Check that the given `index` is valid for subscripting, i.e. `0 /// ≤ index < count`. @_semantics("array.check_subscript") public // @testable - func _checkSubscript(index: Int, wasNativeTypeChecked: Bool) { + func _checkSubscript( + index: Int, wasNativeTypeChecked: Bool + ) -> _DependenceToken { #if _runtime(_ObjC) +% if Self == 'Array': _buffer._checkInoutAndNativeTypeCheckedBounds( index, wasNativeTypeChecked: wasNativeTypeChecked) +% else: + _buffer._checkValidSubscript(index) +% end #else _buffer._checkValidSubscript(index) #endif + return _DependenceToken() } -% end /// Check that the given `index` is valid, i.e. `0 ≤ index ≤ count`. @_semantics("array.check_index") @@ -400,7 +396,11 @@ public struct ${Self} @_semantics("array.get_element") @inline(__always) public // @testable - func _getElement(index: Int, wasNativeTypeChecked : Bool) -> Element { + func _getElement( + index: Int, + wasNativeTypeChecked : Bool, + matchingSubscriptCheck: _DependenceToken + ) -> Element { #if ${'_runtime(_ObjC)' if Self == 'Array' else 'false'} return _buffer.getElement(index, wasNativeTypeChecked: wasNativeTypeChecked) #else @@ -465,7 +465,7 @@ public func _allocateUninitializedArray(_count: Builtin.Word) -> (Array, Builtin.RawPointer) { let count = Int(_count) if count > 0 { - // Doing the actual buffer alloction outside of the array.uninitialized + // Doing the actual buffer allocation outside of the array.uninitialized // semantics function enables stack propagation of the buffer. let bufferObject = ManagedBufferPointer<_ArrayBody, Element>( _uncheckedBufferClass: _ContiguousArrayStorage.self, @@ -513,7 +513,8 @@ extension ${Self} : _ArrayType { var p: UnsafeMutablePointer (self, p) = ${Self}._allocateUninitialized(count) for _ in 0.. 0 { // Creating a buffer instead of calling reserveCapacity saves doing an - // unneccessary uniqueness check. We disable inlining here to curb code + // unnecessary uniqueness check. We disable inlining here to curb code // growth. _buffer = ${Self}._allocateBufferUninitialized(count) } @@ -618,7 +619,7 @@ extension ${Self} : _ArrayType { /// - Postcondition: `capacity >= minimumCapacity` and the array has /// mutable contiguous storage. /// - /// - Complexity: O(`count`). + /// - Complexity: O(`self.count`). @_semantics("array.mutate_unknown") public mutating func reserveCapacity(minimumCapacity: Int) { if _buffer.requestUniqueMutableBackingBuffer(minimumCapacity) == nil { @@ -722,7 +723,7 @@ extension ${Self} : _ArrayType { /// /// - Requires: `i <= count`. /// - /// - Complexity: O(`count`). + /// - Complexity: O(`self.count`). public mutating func insert(newElement: Element, atIndex i: Int) { _checkIndex(i) self.replaceRange(i.. Element { let result = self[index] self.replaceRange(index..<(index + 1), with: EmptyCollection()) @@ -908,7 +909,9 @@ internal struct _InitializeMemoryFromCollection< var p = rawMemory var q = newValues.startIndex for _ in 0..( /// Create a unique mutable buffer that has enough capacity to hold /// 'minNewCapacity' elements and set the count of the new buffer to /// 'countForNewBuffer'. The content of the buffer uninitialized. -/// The forumula used to compute the new buffers capacity is: +/// The formula used to compute the new buffers capacity is: /// max(minNewCapacity, source.capacity) if minNewCapacity <= source.capacity /// max(minNewCapacity, _growArrayCapacity(source.capacity)) otherwise @inline(never) @@ -1238,7 +1241,8 @@ internal func _arrayAppendSequence< let base = buffer.firstElementAddress while (nextItem != nil) && count < capacity { - (base + count++).initialize(nextItem!) + (base + count).initialize(nextItem!) + count += 1 nextItem = stream.next() } buffer.count = count diff --git a/stdlib/public/core/Assert.swift b/stdlib/public/core/Assert.swift index 10748db8e34c6..25c33ad8f13aa 100644 --- a/stdlib/public/core/Assert.swift +++ b/stdlib/public/core/Assert.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/AssertCommon.swift b/stdlib/public/core/AssertCommon.swift index c06dc6c3cef1d..6ff9abd9d8115 100644 --- a/stdlib/public/core/AssertCommon.swift +++ b/stdlib/public/core/AssertCommon.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -60,26 +60,26 @@ func _isStdlibInternalChecksEnabled() -> Bool { #endif } -@_silgen_name("swift_reportFatalErrorInFile") +@_silgen_name("_swift_stdlib_reportFatalErrorInFile") func _reportFatalErrorInFile( prefix: UnsafePointer, _ prefixLength: UInt, _ message: UnsafePointer, _ messageLength: UInt, _ file: UnsafePointer, _ fileLength: UInt, _ line: UInt) -@_silgen_name("swift_reportFatalError") +@_silgen_name("_swift_stdlib_reportFatalError") func _reportFatalError( prefix: UnsafePointer, _ prefixLength: UInt, _ message: UnsafePointer, _ messageLength: UInt) -@_silgen_name("swift_reportUnimplementedInitializerInFile") +@_silgen_name("_swift_stdlib_reportUnimplementedInitializerInFile") func _reportUnimplementedInitializerInFile( className: UnsafePointer, _ classNameLength: UInt, _ initName: UnsafePointer, _ initNameLength: UInt, _ file: UnsafePointer, _ fileLength: UInt, _ line: UInt, _ column: UInt) -@_silgen_name("swift_reportUnimplementedInitializer") +@_silgen_name("_swift_stdlib_reportUnimplementedInitializer") func _reportUnimplementedInitializer( className: UnsafePointer, _ classNameLength: UInt, _ initName: UnsafePointer, _ initNameLength: UInt) @@ -148,6 +148,7 @@ func _assertionFailed( /// bloats code. @noreturn @inline(never) @_semantics("stdlib_binary_only") +@_semantics("arc.programtermination_point") func _fatalErrorMessage(prefix: StaticString, _ message: StaticString, _ file: StaticString, _ line: UInt) { #if INTERNAL_CHECKS_ENABLED @@ -179,7 +180,7 @@ func _fatalErrorMessage(prefix: StaticString, _ message: StaticString, Builtin.int_trap() } -/// Prints a fatal error message when a unimplemented initializer gets +/// Prints a fatal error message when an unimplemented initializer gets /// called by the Objective-C runtime. @_transparent @noreturn public // COMPILER_INTRINSIC @@ -221,3 +222,12 @@ func _unimplemented_initializer(className: StaticString, Builtin.int_trap() } + +@noreturn +public // COMPILER_INTRINSIC +func _undefined( + @autoclosure message: () -> String = String(), + file: StaticString = __FILE__, line: UInt = __LINE__ +) -> T { + _assertionFailed("fatal error", message(), file, line) +} diff --git a/stdlib/public/core/Availability.swift b/stdlib/public/core/Availability.swift index f1464a2571dec..88d4c244b14d6 100644 --- a/stdlib/public/core/Availability.swift +++ b/stdlib/public/core/Availability.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,7 +15,7 @@ import SwiftShims /// Returns 1 if the running OS version is greater than or equal to /// major.minor.patchVersion and 0 otherwise. /// -/// This is a magic entrypoint known to the compiler. It is called in +/// This is a magic entry point known to the compiler. It is called in /// generated code for API availability checking. @warn_unused_result @_semantics("availability.osversion") @@ -47,75 +47,43 @@ extension _SwiftNSOperatingSystemVersion : Comparable { } @warn_unused_result public func == ( - left: _SwiftNSOperatingSystemVersion, - right: _SwiftNSOperatingSystemVersion + lhs: _SwiftNSOperatingSystemVersion, + rhs: _SwiftNSOperatingSystemVersion ) -> Bool { - return left.majorVersion == right.majorVersion && - left.minorVersion == right.minorVersion && - left.patchVersion == right.patchVersion + return lhs.majorVersion == rhs.majorVersion && + lhs.minorVersion == rhs.minorVersion && + lhs.patchVersion == rhs.patchVersion } /// Lexicographic comparison of version components. @warn_unused_result public func < ( - _lhs: _SwiftNSOperatingSystemVersion, - _rhs: _SwiftNSOperatingSystemVersion + lhs: _SwiftNSOperatingSystemVersion, + rhs: _SwiftNSOperatingSystemVersion ) -> Bool { - if _lhs.majorVersion > _rhs.majorVersion { - return false + guard lhs.majorVersion == rhs.majorVersion else { + return lhs.majorVersion < rhs.majorVersion } - if _lhs.majorVersion < _rhs.majorVersion { - return true + guard lhs.minorVersion == rhs.minorVersion else { + return lhs.minorVersion < rhs.minorVersion } - if _lhs.minorVersion > _rhs.minorVersion { - return false - } - - if _lhs.minorVersion < _rhs.minorVersion { - return true - } - - if _lhs.patchVersion > _rhs.patchVersion { - return false - } - - if _lhs.patchVersion < _rhs.patchVersion { - return true - } - - return false + return lhs.patchVersion < rhs.patchVersion } @warn_unused_result public func >= ( - _lhs: _SwiftNSOperatingSystemVersion, - _rhs: _SwiftNSOperatingSystemVersion + lhs: _SwiftNSOperatingSystemVersion, + rhs: _SwiftNSOperatingSystemVersion ) -> Bool { - if _lhs.majorVersion < _rhs.majorVersion { - return false - } - - if _lhs.majorVersion > _rhs.majorVersion { - return true - } - - if _lhs.minorVersion < _rhs.minorVersion { - return false - } - - if _lhs.minorVersion > _rhs.minorVersion { - return true - } - - if _lhs.patchVersion < _rhs.patchVersion { - return false + guard lhs.majorVersion == rhs.majorVersion else { + return lhs.majorVersion >= rhs.majorVersion } - if _lhs.patchVersion > _rhs.patchVersion { - return true + guard lhs.minorVersion == rhs.minorVersion else { + return lhs.minorVersion >= rhs.minorVersion } - return true + return lhs.patchVersion >= rhs.patchVersion } diff --git a/stdlib/public/core/Bit.swift b/stdlib/public/core/Bit.swift index 368fd8a914938..1ef13aa02c318 100644 --- a/stdlib/public/core/Bit.swift +++ b/stdlib/public/core/Bit.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -63,7 +63,7 @@ internal struct _BitMirror : _MirrorType { var valueType: Any.Type { return (_value as Any).dynamicType } - var objectIdentifier: ObjectIdentifier? { return .None } + var objectIdentifier: ObjectIdentifier? { return nil } var count: Int { return 0 } @@ -78,7 +78,7 @@ internal struct _BitMirror : _MirrorType { } } - var quickLookObject: PlaygroundQuickLook? { return .None } + var quickLookObject: PlaygroundQuickLook? { return nil } var disposition: _MirrorDisposition { return .Enum } } @@ -94,11 +94,15 @@ public func < (lhs: Bit, rhs: Bit) -> Bool { } extension Bit : IntegerArithmeticType { - static func _withOverflow(v: (Int, overflow: Bool)) -> (Bit, overflow: Bool) { - if let b = Bit(rawValue: v.0) { - return (b, v.overflow) + static func _withOverflow( + intResult: Int, overflow: Bool + ) -> (Bit, overflow: Bool) { + if let bit = Bit(rawValue: intResult) { + return (bit, overflow: overflow) } else { - return (Bit(rawValue: v.0 % 2)!, true) + let bitRaw = intResult % 2 + (intResult < 0 ? 2 : 0) + let bit = Bit(rawValue: bitRaw)! + return (bit, overflow: true) } } diff --git a/stdlib/public/core/Bool.swift b/stdlib/public/core/Bool.swift index e7087ecd001f1..377acec1f47e5 100644 --- a/stdlib/public/core/Bool.swift +++ b/stdlib/public/core/Bool.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -64,7 +64,7 @@ extension Bool : CustomStringConvertible { } } -// This is a magic entrypoint known to the compiler. +// This is a magic entry point known to the compiler. @_transparent public // COMPILER_INTRINSIC func _getBool(v: Builtin.Int1) -> Bool { return Bool(v) } diff --git a/stdlib/public/core/BooleanType.swift b/stdlib/public/core/BooleanType.swift index f229f06a4b97b..0da99532f7ef6 100644 --- a/stdlib/public/core/BooleanType.swift +++ b/stdlib/public/core/BooleanType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/BridgeObjectiveC.swift b/stdlib/public/core/BridgeObjectiveC.swift index d2914639a3d69..309d539143826 100644 --- a/stdlib/public/core/BridgeObjectiveC.swift +++ b/stdlib/public/core/BridgeObjectiveC.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,7 +15,7 @@ /// `_ObjectiveCBridgeable` can be passed to Objective-C as an NSArray or /// NSDictionary, respectively. The elements of the resulting NSArray /// or NSDictionary will be the result of calling `_bridgeToObjectiveC` -/// on each elmeent of the source container. +/// on each element of the source container. public protocol _ObjectiveCBridgeable { typealias _ObjectiveCType : AnyObject @@ -29,7 +29,7 @@ public protocol _ObjectiveCBridgeable { static func _isBridgedToObjectiveC() -> Bool // _getObjectiveCType is a workaround: right now protocol witness - // tables don't include associated types, so we can not find + // tables don't include associated types, so we cannot find // '_ObjectiveCType.self' from them. /// Must return `_ObjectiveCType.self`. @@ -81,7 +81,7 @@ public protocol _ObjectiveCBridgeable { /// /// The language and runtime do not yet support protocol conformances for /// structural types like metatypes. However, we can use a struct that contains -/// a metatype, make it conform to to _ObjectiveCBridgeable, and its witness table +/// a metatype, make it conform to _ObjectiveCBridgeable, and its witness table /// will be ABI-compatible with one that directly provided conformance to the /// metatype type itself. public struct _BridgeableMetatype: _ObjectiveCBridgeable { @@ -131,7 +131,7 @@ public struct _BridgeableMetatype: _ObjectiveCBridgeable { /// Attempt to convert `x` to its Objective-C representation. /// -/// - If `T` is a class type, it is alaways bridged verbatim, the function +/// - If `T` is a class type, it is always bridged verbatim, the function /// returns `x`; /// /// - otherwise, `T` conforms to `_ObjectiveCBridgeable`: @@ -257,7 +257,7 @@ func _bridgeNonVerbatimFromObjectiveC( inout _ result: T? ) -/// Runtime optional to conditionall perform a bridge from an object to a value +/// Runtime optional to conditionally perform a bridge from an object to a value /// type. /// /// - parameter result: Will be set to the resulting value if bridging succeeds, and @@ -300,7 +300,7 @@ public func _isBridgedVerbatimToObjectiveC(_: T.Type) -> Bool { /// Retrieve the Objective-C type to which the given type is bridged. @warn_unused_result -public func _getBridgedObjectiveCType(_: T.Type) -> Any.Type? { +public func _getBridgedObjectiveCType(_: T.Type) -> Any.Type? { if _fastPath(_isClassOrObjCExistential(T.self)) { return T.self } diff --git a/stdlib/public/core/BridgeStorage.swift b/stdlib/public/core/BridgeStorage.swift index 2efefabc55313..11abff2693a44 100644 --- a/stdlib/public/core/BridgeStorage.swift +++ b/stdlib/public/core/BridgeStorage.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift index 10ee4bbbf3618..c68bcfef01366 100644 --- a/stdlib/public/core/Builtin.swift +++ b/stdlib/public/core/Builtin.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -175,8 +175,8 @@ func _conditionallyUnreachable() { } @warn_unused_result -@_silgen_name("swift_isClassOrObjCExistential") -func _swift_isClassOrObjCExistential(x: T.Type) -> Bool +@_silgen_name("swift_isClassOrObjCExistentialType") +func _swift_isClassOrObjCExistentialType(x: T.Type) -> Bool /// Returns `true` iff `T` is a class type or an `@objc` existential such as /// `AnyObject`. @@ -194,7 +194,7 @@ internal func _isClassOrObjCExistential(x: T.Type) -> Bool { } // Maybe a class. - return _swift_isClassOrObjCExistential(x) + return _swift_isClassOrObjCExistentialType(x) } /// Returns an `UnsafePointer` to the storage used for `object`. There's @@ -318,7 +318,7 @@ public func _slowPath(x: C) -> Bool { @warn_unused_result internal func _usesNativeSwiftReferenceCounting(theClass: AnyClass) -> Bool { #if _runtime(_ObjC) - return _swift_usesNativeSwiftReferenceCounting_class( + return swift_objc_class_usesNativeSwiftReferenceCounting( unsafeAddressOf(theClass) ) #else @@ -327,25 +327,26 @@ internal func _usesNativeSwiftReferenceCounting(theClass: AnyClass) -> Bool { } @warn_unused_result -@_silgen_name("_swift_class_getInstancePositiveExtentSize_native") -func _swift_class_getInstancePositiveExtentSize_native(theClass: AnyClass) -> UInt +@_silgen_name("swift_class_getInstanceExtents") +func swift_class_getInstanceExtents(theClass: AnyClass) + -> (negative: UInt, positive: UInt) -/// - Returns: `class_getInstanceSize(theClass)`. +@warn_unused_result +@_silgen_name("swift_objc_class_unknownGetInstanceExtents") +func swift_objc_class_unknownGetInstanceExtents(theClass: AnyClass) + -> (negative: UInt, positive: UInt) + +/// - Returns: @inline(__always) @warn_unused_result internal func _class_getInstancePositiveExtentSize(theClass: AnyClass) -> Int { #if _runtime(_ObjC) - return Int(_swift_class_getInstancePositiveExtentSize( - unsafeAddressOf(theClass))) + return Int(swift_objc_class_unknownGetInstanceExtents(theClass).positive) #else - return Int(_swift_class_getInstancePositiveExtentSize_native(theClass)) + return Int(swift_class_getInstanceExtents(theClass).positive) #endif } -@warn_unused_result -@_silgen_name("_swift_isClass") -public func _swift_isClass(x: Any) -> Bool - //===--- Builtin.BridgeObject ---------------------------------------------===// #if arch(i386) || arch(arm) @@ -474,18 +475,18 @@ internal func _makeBridgeObject( ) } -/// Return the superclass of `t`, if any. The result is nil if `t` is +/// Return the superclass of `t`, if any. The result is `nil` if `t` is /// a root class or class protocol. @inline(__always) @warn_unused_result public // @testable func _getSuperclass(t: AnyClass) -> AnyClass? { return unsafeBitCast( - _swift_getSuperclass_nonNull(unsafeBitCast(t, COpaquePointer.self)), + swift_class_getSuperclass(unsafeBitCast(t, COpaquePointer.self)), AnyClass.self) } -/// Return the superclass of `t`, if any. The result is nil if `t` is +/// Return the superclass of `t`, if any. The result is `nil` if `t` is /// not a class, is a root class, or is a class protocol. @inline(__always) @warn_unused_result @@ -534,7 +535,7 @@ internal func _isUniqueOrPinned(inout object: T) -> Bool { public // @testable func _isUnique_native(inout object: T) -> Bool { // This could be a bridge object, single payload enum, or plain old - // reference. Any any case it's non pointer bits must be zero, so + // reference. Any case it's non pointer bits must be zero, so // force cast it to BridgeObject and check the spare bits. _sanityCheck( (_bitPattern(Builtin.reinterpretCast(object)) & _objectPointerSpareBits) @@ -551,7 +552,7 @@ func _isUnique_native(inout object: T) -> Bool { public // @testable func _isUniqueOrPinned_native(inout object: T) -> Bool { // This could be a bridge object, single payload enum, or plain old - // reference. Any any case it's non pointer bits must be zero. + // reference. Any case it's non pointer bits must be zero. _sanityCheck( (_bitPattern(Builtin.reinterpretCast(object)) & _objectPointerSpareBits) == 0) @@ -568,3 +569,11 @@ public // @testable func _isPOD(type: T.Type) -> Bool { return Bool(Builtin.ispod(type)) } + +/// Return true if type is nominally an Optional type. +@_transparent +@warn_unused_result +public // @testable +func _isOptional(type: T.Type) -> Bool { + return Bool(Builtin.isOptional(type)) +} diff --git a/stdlib/public/core/BuiltinMath.swift.gyb b/stdlib/public/core/BuiltinMath.swift.gyb index 941744a2486ba..21de5882da637 100644 --- a/stdlib/public/core/BuiltinMath.swift.gyb +++ b/stdlib/public/core/BuiltinMath.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index a09ac19a10df0..772067b7ad5f2 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -2,7 +2,7 @@ # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ # #===----------------------------------------------------------------------===# -# The list of sources without which it's impossble to build a core +# The list of sources without which it's impossible to build a core # standard library. Try to add new standard library sources to # SWIFTLIB_SOURCES, below, rather than SWIFTLIB_ESSENTIAL, if # possible, to improve layering. Check that you got it right by @@ -127,6 +127,7 @@ set(SWIFTLIB_SOURCES Mirror.swift Process.swift SliceBuffer.swift + Tuple.swift.gyb VarArgs.swift Zip.swift Prespecialized.swift @@ -154,6 +155,11 @@ else() # -Wl,--whole-archive swiftRuntime -Wl,--no-whole-archive) list(APPEND swift_core_private_link_libraries swiftRuntime swiftStdlibStubs) find_package(ICU REQUIRED COMPONENTS uc i18n) + list(APPEND swift_core_private_link_libraries + ${ICU_UC_LIBRARY} ${ICU_I18N_LIBRARY}) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") find_package(BSD REQUIRED) list(APPEND swift_core_private_link_libraries ${ICU_UC_LIBRARY} ${ICU_I18N_LIBRARY}) diff --git a/stdlib/public/core/CString.swift b/stdlib/public/core/CString.swift index fb400126cf076..c20488ec118bc 100644 --- a/stdlib/public/core/CString.swift +++ b/stdlib/public/core/CString.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,7 +23,7 @@ extension String { @warn_unused_result public static func fromCString(cs: UnsafePointer) -> String? { if cs._isNull { - return .None + return nil } let len = Int(_swift_stdlib_strlen(cs)) return String._fromCodeUnitSequence(UTF8.self, @@ -41,7 +41,7 @@ extension String { cs: UnsafePointer) -> (String?, hadError: Bool) { if cs._isNull { - return (.None, hadError: false) + return (nil, hadError: false) } let len = Int(_swift_stdlib_strlen(cs)) let (result, hadError) = String._fromCodeUnitSequenceWithRepair(UTF8.self, @@ -51,16 +51,16 @@ extension String { } /// From a non-`nil` `UnsafePointer` to a null-terminated string -/// with possibly-transient lifetime, create a nul-terminated array of 'C' char. +/// with possibly-transient lifetime, create a null-terminated array of 'C' char. /// Returns `nil` if passed a null pointer. @warn_unused_result public func _persistCString(s: UnsafePointer) -> [CChar]? { if s == nil { - return .None + return nil } let length = Int(_swift_stdlib_strlen(s)) var result = [CChar](count: length + 1, repeatedValue: 0) - for var i = 0; i < length; ++i { + for var i = 0; i < length; i += 1 { // FIXME: this will not compile on platforms where 'CChar' is unsigned. result[i] = s[i] } diff --git a/stdlib/public/core/CTypes.swift b/stdlib/public/core/CTypes.swift index 9807c49dbd18c..1cd5a4abec76e 100644 --- a/stdlib/public/core/CTypes.swift +++ b/stdlib/public/core/CTypes.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Character.swift b/stdlib/public/core/Character.swift index 28d42b9d65d3e..d72e064d24fb4 100644 --- a/stdlib/public/core/Character.swift +++ b/stdlib/public/core/Character.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -66,8 +66,8 @@ public struct Character : isASCII: Builtin.Int1) { self = Character( String( - _builtinExtendedGraphemeClusterLiteral: start, - byteSize: byteSize, + _builtinExtendedGraphemeClusterLiteral: start, + byteSize: byteSize, isASCII: isASCII)) } @@ -120,7 +120,7 @@ public struct Character : @warn_unused_result static func _smallSize(value: UInt64) -> Int { var mask: UInt64 = 0xFF - for var i = 0; i < 8; ++i { + for var i = 0; i < 8; i += 1 { if (value & mask) == mask { return i } @@ -165,7 +165,7 @@ public struct Character : subscript(position: Int) -> UTF8.CodeUnit { _sanityCheck(position >= 0) _sanityCheck(position < Int(count)) - // Note: using unchecked arthmetic because overflow can not happen if the + // Note: using unchecked arithmetic because overflow cannot happen if the // above sanity checks hold. return UTF8.CodeUnit( truncatingBitPattern: data >> (UInt64(position) &* 8)) @@ -237,7 +237,7 @@ public struct Character : subscript(position: Int) -> UTF16.CodeUnit { _sanityCheck(position >= 0) _sanityCheck(position < Int(count)) - // Note: using unchecked arthmetic because overflow can not happen if the + // Note: using unchecked arithmetic because overflow cannot happen if the // above sanity checks hold. return UTF16.CodeUnit(truncatingBitPattern: data >> ((UInt64(count) &- UInt64(position) &- 1) &* 16)) diff --git a/stdlib/public/core/CocoaArray.swift b/stdlib/public/core/CocoaArray.swift index 2094fb318985b..3991da9e45ed3 100644 --- a/stdlib/public/core/CocoaArray.swift +++ b/stdlib/public/core/CocoaArray.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -39,10 +39,10 @@ internal struct _CocoaArrayWrapper : CollectionType { } /// Returns a pointer to the first element in the given subRange if - /// the subRange is stored contiguously. Otherwise, return nil. + /// the subRange is stored contiguously. Otherwise, return `nil`. /// /// - Note: This method should only be used as an optimization; it - /// is sometimes conservative and may return nil even when + /// is sometimes conservative and may return `nil` even when /// contiguous storage exists, e.g., if array doesn't have a smart /// implementation of countByEnumeratingWithState. func contiguousStorage( diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift index ecee5d30fe368..1d2bf59a91514 100644 --- a/stdlib/public/core/Collection.swift +++ b/stdlib/public/core/Collection.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -101,8 +101,10 @@ public struct IndexingGenerator /// /// - Requires: No preceding call to `self.next()` has returned `nil`. public mutating func next() -> Elements._Element? { - return _position == _elements.endIndex - ? .None : .Some(_elements[_position++]) + if _position == _elements.endIndex { return nil } + let element = _elements[_position] + _position._successorInPlace() + return element } internal let _elements: Elements @@ -260,7 +262,12 @@ extension CollectionType { /// /// - Complexity: O(1) public var first: Generator.Element? { - return isEmpty ? nil : self[startIndex] + // NB: Accessing `startIndex` may not be O(1) for some lazy collections, + // so instead of testing `isEmpty` and then returning the first element, + // we'll just rely on the fact that the generator always yields the + // first element first. + var gen = generate() + return gen.next() } /// Returns a value less than or equal to the number of elements in @@ -320,7 +327,8 @@ extension CollectionType { var i = self.startIndex for _ in 0..(preprocess: (Self)->R) -> R? { + public func _preprocessingPass(@noescape preprocess: (Self) -> R) -> R? { return preprocess(self) } } @@ -724,16 +733,16 @@ internal func _writeBackMutableSlice< newElementIndex != newElementsEndIndex { self_[selfElementIndex] = slice[newElementIndex] - ++selfElementIndex - ++newElementIndex + selfElementIndex._successorInPlace() + newElementIndex._successorInPlace() } _precondition( selfElementIndex == selfElementsEndIndex, - "Can not replace a slice of a MutableCollectionType with a slice of a larger size") + "Cannot replace a slice of a MutableCollectionType with a slice of a larger size") _precondition( newElementIndex == newElementsEndIndex, - "Can not replace a slice of a MutableCollectionType with a slice of a smaller size") + "Cannot replace a slice of a MutableCollectionType with a slice of a smaller size") } /// Returns the range of `x`'s valid index values. @@ -765,8 +774,7 @@ public struct PermutationGenerator< /// /// - Requires: No preceding call to `self.next()` has returned `nil`. public mutating func next() -> Element? { - let result = indices.next() - return result != nil ? seq[result!] : .None + return indices.next().map { seq[$0] } } /// Construct a *generator* over a permutation of `elements` given diff --git a/stdlib/public/core/CollectionAlgorithms.swift.gyb b/stdlib/public/core/CollectionAlgorithms.swift.gyb index 02e261adf1367..8c5e81c725627 100644 --- a/stdlib/public/core/CollectionAlgorithms.swift.gyb +++ b/stdlib/public/core/CollectionAlgorithms.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/CollectionMirrors.swift.gyb b/stdlib/public/core/CollectionMirrors.swift.gyb index c80bc89a8f42f..9b724f1fb7abd 100644 --- a/stdlib/public/core/CollectionMirrors.swift.gyb +++ b/stdlib/public/core/CollectionMirrors.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -47,7 +47,7 @@ ${MirrorDecl} { var summary: String { return "${SummaryString}" } - var quickLookObject: PlaygroundQuickLook? { return .None } + var quickLookObject: PlaygroundQuickLook? { return nil } } ${MirrorConformance} diff --git a/stdlib/public/core/CollectionOfOne.swift b/stdlib/public/core/CollectionOfOne.swift index 1be1b332f8215..6d54afd173cc5 100644 --- a/stdlib/public/core/CollectionOfOne.swift +++ b/stdlib/public/core/CollectionOfOne.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -29,7 +29,7 @@ public struct GeneratorOfOne : GeneratorType, SequenceType { /// has returned `nil`. public mutating func next() -> Element? { let result = elements - elements = .None + elements = nil return result } var elements: Element? diff --git a/stdlib/public/core/CompilerProtocols.swift b/stdlib/public/core/CompilerProtocols.swift index 1ca8d0b407bf6..72b6017d33bfd 100644 --- a/stdlib/public/core/CompilerProtocols.swift +++ b/stdlib/public/core/CompilerProtocols.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/ContiguousArrayBuffer.swift b/stdlib/public/core/ContiguousArrayBuffer.swift index 36d39a4f1a4d4..f74c3cd8aa54b 100644 --- a/stdlib/public/core/ContiguousArrayBuffer.swift +++ b/stdlib/public/core/ContiguousArrayBuffer.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,7 +15,7 @@ import SwiftShims /// Class used whose sole instance is used as storage for empty /// arrays. The instance is defined in the runtime and statically /// initialized. See stdlib/runtime/GlobalObjects.cpp for details. -/// Because it's statically referenced, it requires nonlazy realization +/// Because it's statically referenced, it requires non-lazy realization /// by the Objective-C runtime. @objc_non_lazy_realization internal final class _EmptyArrayStorage @@ -244,17 +244,13 @@ public struct _ContiguousArrayBuffer : _ArrayBufferType { elementTypeIsBridgedVerbatim: verbatim)) } - var arrayPropertyIsNative : Bool { - return true - } - /// True, if the array is native and does not need a deferred type check. var arrayPropertyIsNativeTypeChecked : Bool { return true } /// If the elements are stored contiguously, a pointer to the first - /// element. Otherwise, nil. + /// element. Otherwise, `nil`. public var firstElementAddress: UnsafeMutablePointer { return __bufferPointer._elementPointer } @@ -585,12 +581,12 @@ extension _ContiguousArrayBuffer { } } -/// This is a fast implemention of _copyToNativeArrayBuffer() for collections. +/// This is a fast implementation of _copyToNativeArrayBuffer() for collections. /// /// It avoids the extra retain, release overhead from storing the /// ContiguousArrayBuffer into /// _UnsafePartiallyInitializedContiguousArrayBuffer. Since we do not support -/// ARC loops, the extra retain, release overhead can not be eliminated which +/// ARC loops, the extra retain, release overhead cannot be eliminated which /// makes assigning ranges very slow. Once this has been implemented, this code /// should be changed to use _UnsafePartiallyInitializedContiguousArrayBuffer. @warn_unused_result @@ -612,10 +608,12 @@ internal func _copyCollectionToNativeArrayBuffer< var i = source.startIndex for _ in 0.. { mutating func addWithExistingCapacity(element: Element) { _sanityCheck(remainingCapacity > 0, "_UnsafePartiallyInitializedContiguousArrayBuffer has no more capacity") - remainingCapacity-- + remainingCapacity -= 1 - (p++).initialize(element) + p.initialize(element) + p += 1 } /// Finish initializing the buffer, adjusting its count to the final diff --git a/stdlib/public/core/EmptyCollection.swift b/stdlib/public/core/EmptyCollection.swift index 0d1a653a3c491..69254a68ad698 100644 --- a/stdlib/public/core/EmptyCollection.swift +++ b/stdlib/public/core/EmptyCollection.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/ErrorType.swift b/stdlib/public/core/ErrorType.swift index 973ad2e538165..55f5d49577454 100644 --- a/stdlib/public/core/ErrorType.swift +++ b/stdlib/public/core/ErrorType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Existential.swift b/stdlib/public/core/Existential.swift index 50ddd3d99c10d..17ca1ef950194 100644 --- a/stdlib/public/core/Existential.swift +++ b/stdlib/public/core/Existential.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,7 +20,7 @@ /// Unavailable; use `AnyGenerator` instead. @available(*, unavailable, renamed="AnyGenerator") -public struct GeneratorOf {} +public struct GeneratorOf {} /// Unavailable; use `AnySequence` instead. @available(*, unavailable, renamed="AnySequence") @@ -30,7 +30,7 @@ internal struct _CollectionOf< IndexType_ : ForwardIndexType, T > : CollectionType { init(startIndex: IndexType_, endIndex: IndexType_, - _ subscriptImpl: (IndexType_)->T) { + _ subscriptImpl: (IndexType_) -> T) { self.startIndex = startIndex self.endIndex = endIndex _subscriptImpl = subscriptImpl @@ -44,10 +44,10 @@ internal struct _CollectionOf< return AnyGenerator { () -> T? in if _fastPath(index != self.endIndex) { - ++index + index._successorInPlace() return self._subscriptImpl(index) } - return .None + return nil } } @@ -58,9 +58,9 @@ internal struct _CollectionOf< return _subscriptImpl(i) } - let _subscriptImpl: (IndexType_)->T + let _subscriptImpl: (IndexType_) -> T } -@available(*, unavailable, message="SinkOf has been removed. Use (T)->() closures directly instead.") +@available(*, unavailable, message="SinkOf has been removed. Use (T) -> () closures directly instead.") public struct SinkOf {} diff --git a/stdlib/public/core/ExistentialCollection.swift.gyb b/stdlib/public/core/ExistentialCollection.swift.gyb index 5f1962836cefb..1e78803a157fa 100644 --- a/stdlib/public/core/ExistentialCollection.swift.gyb +++ b/stdlib/public/core/ExistentialCollection.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -81,14 +81,14 @@ public struct AnyGenerator : GeneratorType { /// traversing the sequence consumes the generator. extension AnyGenerator : SequenceType {} -@available(*, unavailable, renamed="AnyGenerator") +@available(*, deprecated, renamed="AnyGenerator") public func anyGenerator(base: G) -> AnyGenerator { - fatalError("unavailable function can't be called") + return AnyGenerator(base) } -@available(*, unavailable, renamed="AnyGenerator") -public func anyGenerator(body: ()->Element?) -> AnyGenerator { - fatalError("unavailable function can't be called") +@available(*, deprecated, renamed="AnyGenerator") +public func anyGenerator(body: () -> Element?) -> AnyGenerator { + return AnyGenerator(body: body) } internal struct _ClosureBasedGenerator : GeneratorType { @@ -139,6 +139,11 @@ internal class _AnySequenceBox { internal func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { _abstract() } + + internal func _dropFirst(n: Int) -> _AnySequenceBox { _abstract() } + internal func _prefix(maxLength: Int) -> _AnySequenceBox { + _abstract() + } } internal class _AnyCollectionBoxBase : _AnySequenceBox { @@ -154,8 +159,15 @@ internal class _AnyCollectionBoxBase : _AnySequenceBox { % for Kind in ['Sequence', 'Collection']: // FIXME: can't make this a protocol due to -internal class _${Kind}Box - : _Any${Kind}Box { +internal final class _${Kind}Box< + S : ${Kind}Type +% if Kind == 'Sequence': + where + S.SubSequence : ${Kind}Type, + S.SubSequence.Generator.Element == S.Generator.Element, + S.SubSequence.SubSequence == S.SubSequence +% end +> : _Any${Kind}Box { typealias Element = S.Generator.Element override func generate() -> AnyGenerator { @@ -171,6 +183,15 @@ internal class _${Kind}Box override func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { return _base._copyToNativeArrayBuffer()._storage } +% if Kind == 'Sequence': + internal override func _dropFirst(n: Int) -> _AnySequenceBox { + return _SequenceBox(_base.dropFirst(n)) + } + internal override func _prefix(maxLength: Int) -> _AnySequenceBox { + return _SequenceBox(_base.prefix(maxLength)) + } +% end + % if Kind == 'Collection': override func _count() -> IntMax { return numericCast(_base.count) @@ -223,8 +244,15 @@ public struct AnySequence : SequenceType { @available(*, unavailable, renamed="Element") public typealias T = Element - /// Wrap and forward operations to to `base`. - public init(_ base: S) { + /// Wrap and forward operations to `base`. + public init< + S: SequenceType + where + S.Generator.Element == Element, + S.SubSequence : SequenceType, + S.SubSequence.Generator.Element == Element, + S.SubSequence.SubSequence == S.SubSequence + >(_ base: S) { _box = _SequenceBox(base) } @@ -236,6 +264,10 @@ public struct AnySequence : SequenceType { self.init(_ClosureBasedSequence(makeUnderlyingGenerator)) } + internal init(_ box: _AnySequenceBox) { + _box = box + } + /// Return a *generator* over the elements of this *sequence*. /// /// - Complexity: O(1). @@ -246,6 +278,18 @@ public struct AnySequence : SequenceType { internal let _box: _AnySequenceBox } +extension AnySequence { + @warn_unused_result + public func dropFirst(n: Int) -> AnySequence { + return AnySequence(_box._dropFirst(n)) + } + + @warn_unused_result + public func prefix(maxLength: Int) -> AnySequence { + return AnySequence(_box._prefix(maxLength)) + } +} + % for Kind in ['Sequence'] + [t + 'Collection' for t in traversals]: extension Any${Kind} { public func underestimateCount() -> Int { @@ -378,7 +422,7 @@ internal class _BidirectionalIndexBox< } } -//===--- RandomAccessIndex -----------------------------------------------===// +//===--- RandomAccessIndex ------------------------------------------------===// //===----------------------------------------------------------------------===// internal protocol _RandomAccessIndexBoxType : _BidirectionalIndexBoxType {} @@ -635,7 +679,7 @@ public struct Any${Traversal}Collection : AnyCollectionType { } /// Uniquely identifies the stored underlying collection. - public // due to language limitations only + public // Due to language limitations only var _underlyingCollectionID: ObjectIdentifier { return ObjectIdentifier(_box) } diff --git a/stdlib/public/core/Filter.swift b/stdlib/public/core/Filter.swift index a6244f633aec1..b957473df1157 100644 --- a/stdlib/public/core/Filter.swift +++ b/stdlib/public/core/Filter.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,20 +25,19 @@ public struct LazyFilterGenerator< /// since the copy was made, and no preceding call to `self.next()` /// has returned `nil`. public mutating func next() -> Base.Element? { - var n: Base.Element? - for/*ever*/;; { - n = _base.next() - if n != nil ? _predicate(n!) : true { + while let n = _base.next() { + if _predicate(n) { return n } } + return nil } /// Creates an instance that produces the elements `x` of `base` /// for which `predicate(x) == true`. public init( _ base: Base, - whereElementsSatisfy predicate: (Base.Element)->Bool + whereElementsSatisfy predicate: (Base.Element) -> Bool ) { self._base = base self._predicate = predicate @@ -51,7 +50,7 @@ public struct LazyFilterGenerator< /// The predicate used to determine which elements produced by /// `base` are also produced by `self`. - internal var _predicate: (Base.Element)->Bool + internal var _predicate: (Base.Element) -> Bool } /// A sequence whose elements consist of the elements of some base @@ -74,7 +73,7 @@ public struct LazyFilterSequence /// which `predicate(x) == true`. public init( _ base: Base, - whereElementsSatisfy predicate: (Base.Generator.Element)->Bool + whereElementsSatisfy predicate: (Base.Generator.Element) -> Bool ) { self.base = base self._include = predicate @@ -85,7 +84,7 @@ public struct LazyFilterSequence /// The predicate used to determine which elements of `base` are /// also elements of `self`. - internal let _include: (Base.Generator.Element)->Bool + internal let _include: (Base.Generator.Element) -> Bool } /// The `Index` used for subscripting a `LazyFilterCollection`. @@ -131,7 +130,7 @@ public struct LazyFilterIndex< /// The predicate used to determine which elements of `base` are /// also elements of `self`. - internal let _include: (BaseElements.Generator.Element)->Bool + internal let _include: (BaseElements.Generator.Element) -> Bool @available(*, unavailable, renamed="BaseElements") public typealias Base = BaseElements @@ -149,12 +148,12 @@ public func == ( /// A lazy `CollectionType` wrapper that includes the elements of an /// underlying collection that satisfy a predicate. /// -/// - Note: The performance of advancing a `LazyFilterIndex` -/// depends on how sparsely the filtering predicate is satisfied, -/// and may not offer the usual performance given by models of -/// `ForwardIndexType`. Be aware, therefore, that general operations -/// on `LazyFilterCollection` instances may not have the -/// documented complexity. +/// - Note: The performance of accessing `startIndex`, `first`, any methods +/// that depend on `startIndex`, or of advancing a `LazyFilterIndex` depends +/// on how sparsely the filtering predicate is satisfied, and may not offer +/// the usual performance given by `CollectionType` or `ForwardIndexType`. Be +/// aware, therefore, that general operations on `LazyFilterCollection` +/// instances may not have the documented complexity. public struct LazyFilterCollection< Base : CollectionType > : LazyCollectionType { @@ -169,7 +168,7 @@ public struct LazyFilterCollection< /// satisfy `predicate`. public init( _ base: Base, - whereElementsSatisfy predicate: (Base.Generator.Element)->Bool + whereElementsSatisfy predicate: (Base.Generator.Element) -> Bool ) { self._base = base self._predicate = predicate @@ -187,7 +186,7 @@ public struct LazyFilterCollection< if _predicate(_base[first]) { break } - ++first + first._successorInPlace() } return LazyFilterIndex( _baseElements: _base, base: first, _include: _predicate) @@ -222,7 +221,7 @@ public struct LazyFilterCollection< } var _base: Base - var _predicate: (Base.Generator.Element)->Bool + var _predicate: (Base.Generator.Element) -> Bool } extension LazySequenceType { @@ -234,7 +233,7 @@ extension LazySequenceType { /// elements. @warn_unused_result public func filter( - predicate: (Elements.Generator.Element)->Bool + predicate: (Elements.Generator.Element) -> Bool ) -> LazyFilterSequence { return LazyFilterSequence( self.elements, whereElementsSatisfy: predicate) @@ -250,7 +249,7 @@ extension LazyCollectionType { /// elements. @warn_unused_result public func filter( - predicate: (Elements.Generator.Element)->Bool + predicate: (Elements.Generator.Element) -> Bool ) -> LazyFilterCollection { return LazyFilterCollection( self.elements, whereElementsSatisfy: predicate) diff --git a/stdlib/public/core/FixedPoint.swift.gyb b/stdlib/public/core/FixedPoint.swift.gyb index 51c8e0604e5e7..ebabc25ba2ad9 100644 --- a/stdlib/public/core/FixedPoint.swift.gyb +++ b/stdlib/public/core/FixedPoint.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -353,7 +353,7 @@ extension ${Self} : CustomStringConvertible { // restrictive than the full range of ${Self}---against which we're // not able to check. Overflows are not useful indicators of // precondition violations in this context. Therefore, we use masked -// arithmetic in this conformance, and we need to be be sure that +// arithmetic in this conformance, and we need to be sure that // generic implementations of the arithmetic operators for // RandomAccessIndexType's are all shadowed by more-specific // implementations that *do* check for overflows. @@ -446,7 +446,7 @@ extension ${Self} { extension ${Self} : SignedNumberType {} % end -// construction from other integer types +// Construction from other integer types @_transparent extension ${Self} { % for src_ty in all_integer_types(word_bits): @@ -586,7 +586,7 @@ public func ${op} (lhs: ${Self}, rhs: ${Self}) -> ${Self} { } % end -// bitwise operations +// Bitwise operations @_transparent extension ${Self} : BitwiseOperationsType { /// The empty bitset of type ${Self}. @@ -606,12 +606,14 @@ public func ${op}=(inout lhs: ${Self}, rhs: ${Self}) { // FIXME: After is fixed, we should be able // to remove these. @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public prefix func ++ (inout x: ${Self}) -> ${Self} { x = x + 1 return x } @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public postfix func ++ (inout x: ${Self}) -> ${Self} { let ret = x x = x + 1 @@ -619,12 +621,14 @@ public postfix func ++ (inout x: ${Self}) -> ${Self} { } @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public prefix func -- (inout x: ${Self}) -> ${Self} { x = x - 1 return x } @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public postfix func -- (inout x: ${Self}) -> ${Self} { let ret = x x = x - 1 diff --git a/stdlib/public/core/FlatMap.swift b/stdlib/public/core/FlatMap.swift index c5f00a1db0d45..e7408d5ec9f81 100644 --- a/stdlib/public/core/FlatMap.swift +++ b/stdlib/public/core/FlatMap.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,7 +19,7 @@ extension LazySequenceType { /// - Complexity: O(1) @warn_unused_result public func flatMap( - transform: (Elements.Generator.Element)->Intermediate + transform: (Elements.Generator.Element) -> Intermediate ) -> LazySequence< FlattenSequence>> { return self.map(transform).flatten() @@ -35,7 +35,7 @@ extension LazyCollectionType { /// - Complexity: O(1) @warn_unused_result public func flatMap( - transform: (Elements.Generator.Element)->Intermediate + transform: (Elements.Generator.Element) -> Intermediate ) -> LazyCollection< FlattenCollection< LazyMapCollection> @@ -57,7 +57,7 @@ extension LazyCollectionType where Elements.Index : BidirectionalIndexType Intermediate: CollectionType where Intermediate.Index : BidirectionalIndexType >( - transform: (Elements.Generator.Element)->Intermediate + transform: (Elements.Generator.Element) -> Intermediate ) -> LazyCollection< FlattenBidirectionalCollection< LazyMapCollection diff --git a/stdlib/public/core/Flatten.swift.gyb b/stdlib/public/core/Flatten.swift.gyb index 913f6aacbd162..92c425b308abc 100644 --- a/stdlib/public/core/Flatten.swift.gyb +++ b/stdlib/public/core/Flatten.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -144,11 +144,18 @@ public struct ${Index}< /// - Requires: The previous value is representable. public func predecessor() -> ${Index} { var prevOuter = _outer - var prevInnerCollection = _innerCollection ?? _base[--prevOuter] + var prevInnerCollection : BaseElements.Generator.Element + if let ic = _innerCollection { + prevInnerCollection = ic + } else { + prevOuter._predecessorInPlace() + prevInnerCollection = _base[prevOuter] + } var prevInner = _inner ?? prevInnerCollection.endIndex while prevInner == prevInnerCollection.startIndex { - prevInnerCollection = _base[--prevOuter] + prevOuter._predecessorInPlace() + prevInnerCollection = _base[prevOuter] prevInner = prevInnerCollection.endIndex } @@ -218,6 +225,14 @@ public func == ( /// * `c.flatten().map(f)` maps eagerly and returns a new array /// * `c.lazy.flatten().map(f)` maps lazily and returns a `LazyMapCollection` /// +/// - Note: The performance of accessing `startIndex`, `first`, any methods +/// that depend on `startIndex`, or of advancing a `${Collection}Index` +/// depends on how many empty subcollections are found in the base +/// collection, and may not offer the usual performance given by +/// `CollectionType` or `${traversal}IndexType`. Be aware, therefore, that +/// general operations on `${Collection}` instances may not have the +/// documented complexity. +/// /// - See also: `FlattenSequence` public struct ${Collection}< Base: CollectionType where ${constraints % {'Base': 'Base.'}} diff --git a/stdlib/public/core/FloatingPoint.swift.gyb b/stdlib/public/core/FloatingPoint.swift.gyb index 98940b570c5bf..08f5fe77b3e29 100644 --- a/stdlib/public/core/FloatingPoint.swift.gyb +++ b/stdlib/public/core/FloatingPoint.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -181,7 +181,7 @@ public struct ${Self} { @_transparent public init() { let zero: Int64 = 0 - self._value = Builtin.uitofp_Int64_FPIEEE${bits}(zero._value) + self._value = Builtin.sitofp_Int64_FPIEEE${bits}(zero._value) } @_transparent @@ -198,7 +198,14 @@ public struct ${Self} { extension ${Self} : CustomStringConvertible { /// A textual representation of `self`. public var description: String { - return _float${bits}ToString(self) + return _float${bits}ToString(self, debug: false) + } +} + +extension ${Self} : CustomDebugStringConvertible { + /// A textual representation of `self`. + public var debugDescription: String { + return _float${bits}ToString(self, debug: true) } } @@ -567,12 +574,16 @@ extension ${Self} { //===----------------------------------------------------------------------===// @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public prefix func ++ (inout rhs: ${Self}) -> ${Self} { rhs += 1.0; return rhs } @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public prefix func -- (inout rhs: ${Self}) -> ${Self} { rhs -= 1.0; return rhs } @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public postfix func ++ (inout lhs: ${Self}) -> ${Self} { let tmp = lhs; lhs += 1.0; return tmp } @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public postfix func -- (inout lhs: ${Self}) -> ${Self} { let tmp = lhs; lhs -= 1.0; return tmp } @@ -655,23 +666,23 @@ extension ${Self} { // Float80.isFinite is missing _precondition( other.isFinite, - "floating point value can not be converted to ${Self} because it is either infinite or NaN") + "floating point value cannot be converted to ${Self} because it is either infinite or NaN") % if signed: // FIXME: Float80 doesn't have a _fromBitPattern // ${That}(roundTowardsZero: ${Self}.min) // > ${getMinFloat(srcBits, incIfSigned(intFormatFix(bits), signed))} _precondition(other >= ${That}._fromBitPattern(${getMinFloat(srcBits, incIfSigned(intFormatFix(bits), signed))}), - "floating point value can not be converted to ${Self} because it is less than ${Self}.min") + "floating point value cannot be converted to ${Self} because it is less than ${Self}.min") % else: _precondition(other >= (0.0 as ${That}), - "floating point value can not be converted to ${Self} because it is less than ${Self}.min") + "floating point value cannot be converted to ${Self} because it is less than ${Self}.min") % end // ${That}(roundTowardsZero: ${Self}.max) // > ${getMaxFloat(srcBits, incIfSigned(intFormatFix(bits), signed))} _precondition(other <= ${That}._fromBitPattern(${getMaxFloat(srcBits, incIfSigned(intFormatFix(bits), signed))}), - "floating point value can not be converted to ${Self} because it is greater than ${Self}.max") + "floating point value cannot be converted to ${Self} because it is greater than ${Self}.max") % end self._value = diff --git a/stdlib/public/core/FloatingPointOperations.swift.gyb b/stdlib/public/core/FloatingPointOperations.swift.gyb index 3b8f516caef39..2af7d423647be 100644 --- a/stdlib/public/core/FloatingPointOperations.swift.gyb +++ b/stdlib/public/core/FloatingPointOperations.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -33,28 +33,6 @@ public enum FloatingPointClassification { case PositiveInfinity } -extension FloatingPointClassification : Equatable {} - -public -func ==(lhs: FloatingPointClassification, rhs: FloatingPointClassification) -> Bool { - switch (lhs, rhs) { - case (.SignalingNaN, .SignalingNaN), - (.QuietNaN, .QuietNaN), - (.NegativeInfinity, .NegativeInfinity), - (.NegativeNormal, .NegativeNormal), - (.NegativeSubnormal, .NegativeSubnormal), - (.NegativeZero, .NegativeZero), - (.PositiveZero, .PositiveZero), - (.PositiveSubnormal, .PositiveSubnormal), - (.PositiveNormal, .PositiveNormal), - (.PositiveInfinity, .PositiveInfinity): - return true - - default: - return false - } -} - /// A set of common requirements for Swift's floating point types. public protocol FloatingPointType : Strideable { typealias _BitsType diff --git a/stdlib/public/core/FloatingPointParsing.swift.gyb b/stdlib/public/core/FloatingPointParsing.swift.gyb index b3d985d7c202f..f662ae5a2b97f 100644 --- a/stdlib/public/core/FloatingPointParsing.swift.gyb +++ b/stdlib/public/core/FloatingPointParsing.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/HashedCollections.swift.gyb b/stdlib/public/core/HashedCollections.swift.gyb index e34b712798a96..f1709f1bc18ee 100644 --- a/stdlib/public/core/HashedCollections.swift.gyb +++ b/stdlib/public/core/HashedCollections.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -53,7 +53,7 @@ import SwiftShims // does not use tombstones. // // In addition to the native storage `Dictionary` can also wrap an -// `NSDictionary` in order to allow brdidging `NSDictionary` to `Dictionary` in +// `NSDictionary` in order to allow bridging `NSDictionary` to `Dictionary` in // `O(1)`. // // Currently native storage uses a data structure like this:: @@ -653,7 +653,7 @@ public struct Set : /// The first element obtained when iterating, or `nil` if `self` is /// empty. Equivalent to `self.generate().next()`. public var first: Element? { - return count > 0 ? self[startIndex] : .None + return count > 0 ? self[startIndex] : nil } } @@ -678,8 +678,10 @@ public func == (lhs: Set, rhs: Set) -> Boo case (.Native(let lhsNativeOwner), .Native(let rhsNativeOwner)): let lhsNative = lhsNativeOwner.nativeStorage let rhsNative = rhsNativeOwner.nativeStorage - // FIXME(performance): early exit if lhs and rhs reference the same - // storage? + + if lhsNativeOwner === rhsNativeOwner { + return true + } if lhsNative.count != rhsNative.count { return false @@ -711,7 +713,7 @@ public func == (lhs: Set, rhs: Set) -> Boo } let endIndex = lhsNative.endIndex - for var i = lhsNative.startIndex; i != endIndex; ++i { + for var i = lhsNative.startIndex; i != endIndex; i = i.successor() { let key = lhsNative.assertingGet(i) let bridgedKey: AnyObject = _bridgeToObjectiveCUnconditional(key) let optRhsValue: AnyObject? = rhsCocoa.maybeGet(bridgedKey) @@ -861,7 +863,7 @@ public func _setDownCast(source: Set) /// Implements a conditional downcast. /// -/// If the cast fails, the function returns `.None`. All checks should be +/// If the cast fails, the function returns `nil`. All checks should be /// performed eagerly. /// /// - Precondition: `DerivedValue` is a subtype of `BaseValue` and both @@ -879,7 +881,7 @@ public func _setDownCastConditional( result.insert(derivedMember) continue } - return .None + return nil } return result } @@ -899,7 +901,7 @@ public func _setBridgeFromObjectiveC( /// Implements a conditional downcast that involves bridging. /// -/// If the cast fails, the function returns `.None`. All checks should be +/// If the cast fails, the function returns `nil`. All checks should be /// performed eagerly. /// /// - Precondition: At least one of `SwiftValue` is a bridged value @@ -1078,7 +1080,7 @@ public struct Dictionary : /// /// Invalidates all indices with respect to `self`. /// - /// - Complexity: O(`count`). + /// - Complexity: O(`self.count`). public mutating func removeAtIndex(index: Index) -> Element { return _variantStorage.removeAtIndex(index) } @@ -1101,7 +1103,7 @@ public struct Dictionary : /// storage capacity that the collection has, otherwise the underlying /// storage is released. The default is `false`. /// - /// Complexity: O(`count`). + /// Complexity: O(`self.count`). public mutating func removeAll(keepCapacity keepCapacity: Bool = false) { // The 'will not decrease' part in the documentation comment is worded very // carefully. The capacity can increase if we replace Cocoa storage with @@ -1184,8 +1186,10 @@ public func == ( case (.Native(let lhsNativeOwner), .Native(let rhsNativeOwner)): let lhsNative = lhsNativeOwner.nativeStorage let rhsNative = rhsNativeOwner.nativeStorage - // FIXME(performance): early exit if lhs and rhs reference the same - // storage? + + if lhsNativeOwner === rhsNativeOwner { + return true + } if lhsNative.count != rhsNative.count { return false @@ -1226,7 +1230,8 @@ public func == ( } let endIndex = lhsNative.endIndex - for var index = lhsNative.startIndex; index != endIndex; ++index { + for var index = lhsNative.startIndex; index != endIndex; + index._successorInPlace() { let (key, value) = lhsNative.assertingGet(index) let optRhsValue: AnyObject? = rhsCocoa.maybeGet(_bridgeToObjectiveCUnconditional(key)) @@ -1308,7 +1313,7 @@ internal func _stdlib_NSDictionary_allKeys(nsd: _NSDictionaryType) } #endif -//===--- Compiler conversion/casting entry points for Dictionary =// +//===--- Compiler conversion/casting entry points for Dictionary ----===// #if _runtime(_ObjC) /// Perform a non-bridged upcast that always succeeds. @@ -1415,7 +1420,7 @@ public func _dictionaryDownCast( switch source._variantStorage { case .Native(let nativeOwner): // FIXME(performance): this introduces an indirection through Objective-C - // runtime, even though we access native storage. But we can not + // runtime, even though we access native storage. But we cannot // unsafeBitCast the owner object, because that would change the generic // arguments. // @@ -1438,7 +1443,7 @@ public func _dictionaryDownCast( /// Implements a conditional downcast. /// -/// If the cast fails, the function returns `.None`. All checks should be +/// If the cast fails, the function returns `nil`. All checks should be /// performed eagerly. /// /// - Precondition: `DerivedKey` is a subtype of `BaseKey`, `DerivedValue` is @@ -1488,7 +1493,7 @@ public func _dictionaryBridgeFromObjectiveC< /// Implements a conditional downcast that involves bridging. /// -/// If the cast fails, the function returns `.None`. All checks should be +/// If the cast fails, the function returns `nil`. All checks should be /// performed eagerly. /// /// - Precondition: At least one of `SwiftKey` or `SwiftValue` is a bridged value @@ -2108,7 +2113,7 @@ struct _Native${Self}Storage<${TypeParametersDecl}> : var description: String { var result = "" #if INTERNAL_CHECKS_ENABLED - for var i = 0; i != capacity; ++i { + for var i = 0; i != capacity; i += 1 { if isInitializedEntry(i) { let key = keyAt(i) result += "bucket \(i), ideal bucket = \(_bucket(key)), key = \(key)\n" @@ -2138,10 +2143,10 @@ struct _Native${Self}Storage<${TypeParametersDecl}> : internal func indexForKey(key: Key) -> Index? { if count == 0 { // Fast path that avoids computing the hash of the key. - return .None + return nil } let (i, found) = _find(key, _bucket(key)) - return found ? i : .None + return found ? i : nil } @warn_unused_result @@ -2173,7 +2178,7 @@ struct _Native${Self}Storage<${TypeParametersDecl}> : internal func maybeGet(key: Key) -> Value? { if count == 0 { // Fast path that avoids computing the hash of the key. - return .None + return nil } let (i, found) = _find(key, _bucket(key)) @@ -2184,7 +2189,7 @@ struct _Native${Self}Storage<${TypeParametersDecl}> : return valueAt(i.offset) %end } - return .None + return nil } internal mutating func updateValue(value: Value, forKey: Key) -> Value? { @@ -2226,7 +2231,7 @@ struct _Native${Self}Storage<${TypeParametersDecl}> : continue } nativeStorage.initializeKey(key, at: i.offset) - ++count + count += 1 } nativeStorage.count = count @@ -2247,7 +2252,7 @@ struct _Native${Self}Storage<${TypeParametersDecl}> : #if _runtime(_ObjC) /// Storage for bridged `${Self}` elements. We could have used -/// `${Self}<${AnyTypeParameters}>`, but `AnyObject` can not be a Key because +/// `${Self}<${AnyTypeParameters}>`, but `AnyObject` cannot be a Key because /// it is not `Hashable`. internal struct _BridgedNative${Self}Storage { internal typealias StorageImpl = @@ -2385,7 +2390,7 @@ final internal class _Native${Self}StorageKeyNSEnumerator< return nil } let bridgedKey: AnyObject = nativeStorageOwner._getBridgedKey(nextIndex) - nextIndex = nextIndex.successor() + nextIndex._successorInPlace() return bridgedKey } @@ -2410,7 +2415,7 @@ final internal class _Native${Self}StorageKeyNSEnumerator< // Return only a single element so that code can start iterating via fast // enumeration, terminate it, and continue via NSEnumerator. let bridgedKey: AnyObject = nativeStorageOwner._getBridgedKey(nextIndex) - nextIndex = nextIndex.successor() + nextIndex._successorInPlace() let unmanagedObjects = _UnmanagedAnyObjectArray(objects) unmanagedObjects[0] = bridgedKey @@ -2596,7 +2601,7 @@ final internal class _Native${Self}StorageOwner<${TypeParametersDecl}> let bridged = _createBridgedNativeStorage(nativeStorage.capacity) // Bridge everything. - for var i = 0; i < nativeStorage.capacity; ++i { + for var i = 0; i < nativeStorage.capacity; i += 1 { if nativeStorage.isInitializedEntry(i) { let key = _bridgeToObjectiveCUnconditional(nativeStorage.keyAt(i)) %if Self == 'Set': @@ -2664,9 +2669,9 @@ final internal class _Native${Self}StorageOwner<${TypeParametersDecl}> _ keys: UnsafeMutablePointer ) { bridgeEverything() - // the user is expected to provide a buffer of the correct size - var i = 0 // position in the input buffer - var position = 0 // position in the dictionary storage + // The user is expected to provide a buffer of the correct size + var i = 0 // Position in the input buffer + var position = 0 // Position in the dictionary storage let count = bridgedNativeStorage.capacity let unmanagedKeys = _UnmanagedAnyObjectArray(keys) let unmanagedObjects = _UnmanagedAnyObjectArray(objects) @@ -2679,9 +2684,9 @@ final internal class _Native${Self}StorageOwner<${TypeParametersDecl}> while position < count { if bridgedNativeStorage.isInitializedEntry(position) { unmanagedObjects[i] = bridgedNativeStorage.valueAt(position) - i++ + i += 1 } - position++ + position += 1 } } } else { @@ -2690,9 +2695,9 @@ final internal class _Native${Self}StorageOwner<${TypeParametersDecl}> while position < count { if bridgedNativeStorage.isInitializedEntry(position) { unmanagedKeys[i] = bridgedNativeStorage.keyAt(position) - i++ + i += 1 } - position++ + position += 1 } } else { // keys nonnull, objects nonnull @@ -2700,9 +2705,9 @@ final internal class _Native${Self}StorageOwner<${TypeParametersDecl}> if bridgedNativeStorage.isInitializedEntry(position) { unmanagedObjects[i] = bridgedNativeStorage.valueAt(position) unmanagedKeys[i] = bridgedNativeStorage.keyAt(position) - i++ + i += 1 } - position++ + position += 1 } } } @@ -2761,8 +2766,8 @@ final internal class _Native${Self}StorageOwner<${TypeParametersDecl}> let bridgedKey: AnyObject = _getBridgedKey(currIndex) unmanagedObjects[i] = bridgedKey - ++stored - currIndex = currIndex.successor() + stored += 1 + currIndex._successorInPlace() } theState.extra.0 = CUnsignedLong(currIndex.offset) state.memory = theState @@ -2796,7 +2801,7 @@ internal struct _Cocoa${Self}Storage : _HashStorageType { // potential savings are significant: we could skip a memory allocation and // a linear search. if maybeGet(key) == nil { - return .None + return nil } %if Self == 'Set': @@ -2855,19 +2860,19 @@ internal struct _Cocoa${Self}Storage : _HashStorageType { } internal mutating func updateValue(value: Value, forKey: Key) -> Value? { - _sanityCheckFailure("can not mutate NS${Self}") + _sanityCheckFailure("cannot mutate NS${Self}") } internal mutating func removeAtIndex(index: Index) -> SequenceElement { - _sanityCheckFailure("can not mutate NS${Self}") + _sanityCheckFailure("cannot mutate NS${Self}") } internal mutating func removeValueForKey(key: Key) -> Value? { - _sanityCheckFailure("can not mutate NS${Self}") + _sanityCheckFailure("cannot mutate NS${Self}") } internal mutating func removeAll(keepCapacity keepCapacity: Bool) { - _sanityCheckFailure("can not mutate NS${Self}") + _sanityCheckFailure("cannot mutate NS${Self}") } internal var count: Int { @@ -3076,16 +3081,16 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType { switch self { case .Native: if let nativeIndex = native.indexForKey(key) { - return .Some(._Native(nativeIndex)) + return ._Native(nativeIndex) } - return .None + return nil case .Cocoa(let cocoaStorage): #if _runtime(_ObjC) let anyObjectKey: AnyObject = _bridgeToObjectiveCUnconditional(key) if let cocoaIndex = cocoaStorage.indexForKey(anyObjectKey) { - return .Some(._Cocoa(cocoaIndex)) + return ._Cocoa(cocoaIndex) } - return .None + return nil #else _sanityCheckFailure("internal error: unexpected cocoa ${Self}") #endif @@ -3142,7 +3147,7 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType { if let anyObjectValue = cocoaStorage.maybeGet(anyObjectKey) { return _forceBridgeFromObjectiveC(anyObjectValue, Value.self) } - return .None + return nil } #endif @@ -3177,20 +3182,20 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType { } %if Self == 'Set': - let oldValue: Value? = found ? native.keyAt(i.offset) : .None + let oldValue: Value? = found ? native.keyAt(i.offset) : nil if found { native.setKey(key, at: i.offset) } else { native.initializeKey(key, at: i.offset) - ++native.count + native.count += 1 } %elif Self == 'Dictionary': - let oldValue: Value? = found ? native.valueAt(i.offset) : .None + let oldValue: Value? = found ? native.valueAt(i.offset) : nil if found { native.setKey(key, value: value, at: i.offset) } else { native.initializeKey(key, value: value, at: i.offset) - ++native.count + native.count += 1 } %end @@ -3229,13 +3234,13 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType { // remove the element nativeStorage.destroyEntryAt(offset) - --nativeStorage.count + nativeStorage.count -= 1 // If we've put a hole in a chain of contiguous elements, some // element after the hole may belong where the new hole is. var hole = offset - // Find the first bucket in the contigous chain + // Find the first bucket in the contiguous chain var start = idealBucket while nativeStorage.isInitializedEntry(nativeStorage._prev(start)) { start = nativeStorage._prev(start) @@ -3264,7 +3269,7 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType { let c0 = idealBucket >= start let c1 = idealBucket <= hole if start <= hole ? (c0 && c1) : (c0 || c1) { - break // found it + break // Found it } } @@ -3286,7 +3291,7 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType { // Fast path: if the key is not present, we will not mutate the set, // so don't force unique storage. if !found { - return .None + return nil } let (reallocated, capacityChanged) = @@ -3379,7 +3384,7 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType { #if _runtime(_ObjC) let anyObjectKey: AnyObject = _bridgeToObjectiveCUnconditional(key) if cocoaStorage.maybeGet(anyObjectKey) == nil { - return .None + return nil } migrateDataToNativeStorage(cocoaStorage) return nativeRemoveObjectForKey(key) @@ -3404,7 +3409,7 @@ internal enum _Variant${Self}Storage<${TypeParametersDecl}> : _HashStorageType { nativeStorage = native } - for var b = 0; b != nativeStorage.capacity; ++b { + for var b = 0; b != nativeStorage.capacity; b += 1 { if nativeStorage.isInitializedEntry(b) { nativeStorage.destroyEntryAt(b) } @@ -3505,7 +3510,7 @@ internal struct _Native${Self}Index<${TypeParametersDecl}> : break } // end workaround - ++i + i += 1 } return NativeIndex(nativeStorage: nativeStorage, offset: i) } @@ -3579,7 +3584,7 @@ internal struct _Cocoa${Self}Index : ForwardIndexType, Comparable { @warn_unused_result internal func successor() -> _Cocoa${Self}Index { _precondition( - currentKeyIndex < allKeys.value, "can not increment endIndex") + currentKeyIndex < allKeys.value, "cannot increment endIndex") return _Cocoa${Self}Index(cocoa${Self}, allKeys, currentKeyIndex + 1) } } @@ -3587,7 +3592,7 @@ internal struct _Cocoa${Self}Index : ForwardIndexType, Comparable { @warn_unused_result internal func ==(lhs: _Cocoa${Self}Index, rhs: _Cocoa${Self}Index) -> Bool { _precondition(lhs.cocoa${Self} === rhs.cocoa${Self}, - "can not compare indexes pointing to different ${Self}s") + "cannot compare indexes pointing to different ${Self}s") _precondition(lhs.allKeys.value == rhs.allKeys.value, "one or both of the indexes have been invalidated") @@ -3597,7 +3602,7 @@ internal func ==(lhs: _Cocoa${Self}Index, rhs: _Cocoa${Self}Index) -> Bool { @warn_unused_result internal func <(lhs: _Cocoa${Self}Index, rhs: _Cocoa${Self}Index) -> Bool { _precondition(lhs.cocoa${Self} === rhs.cocoa${Self}, - "can not compare indexes pointing to different ${Self}s") + "cannot compare indexes pointing to different ${Self}s") _precondition(lhs.allKeys.value == rhs.allKeys.value, "one or both of the indexes have been invalidated") @@ -3643,7 +3648,7 @@ public struct ${Self}Index<${TypeParametersDecl}> : // not, because neither NSEnumerator nor fast enumeration support moving // backwards. Even if they did, there is another issue: NSEnumerator does // not support NSCopying, and fast enumeration does not document that it is - // safe to copy the state. So, we can not implement Index that is a value + // safe to copy the state. So, we cannot implement Index that is a value // type for bridged NS${Self} in terms of Cocoa enumeration facilities. internal typealias _NativeIndex = _Native${Self}Index<${TypeParameters}> @@ -3766,7 +3771,7 @@ public func < <${TypeParametersDecl}> ( final internal class _Cocoa${Self}Generator : GeneratorType { internal typealias Element = ${AnySequenceType} - // Cocoa ${Self} generator has to be a class, otherwise we can not + // Cocoa ${Self} generator has to be a class, otherwise we cannot // guarantee that the fast enumeration struct is pinned to a certain memory // location. @@ -3791,7 +3796,7 @@ final internal class _Cocoa${Self}Generator : GeneratorType { return UnsafeMutablePointer(_fastEnumerationStatePtr + 1) } - // These members have to be word-sized integers, they can not be limited to + // These members have to be word-sized integers, they cannot be limited to // Int8 just because our buffer holds 16 elements: fast enumeration is // allowed to return inner pointers to the container, which can be much // larger. @@ -3804,7 +3809,7 @@ final internal class _Cocoa${Self}Generator : GeneratorType { internal func next() -> Element? { if itemIndex < 0 { - return .None + return nil } let cocoa${Self} = self.cocoa${Self} if itemIndex == itemCount { @@ -3819,7 +3824,7 @@ final internal class _Cocoa${Self}Generator : GeneratorType { count: stackBufLength) if itemCount == 0 { itemIndex = -1 - return .None + return nil } itemIndex = 0 } @@ -3827,7 +3832,7 @@ final internal class _Cocoa${Self}Generator : GeneratorType { UnsafeMutablePointer(_fastEnumerationState.itemsPtr) let itemsPtr = _UnmanagedAnyObjectArray(itemsPtrUP) let key: AnyObject = itemsPtr[itemIndex] - ++itemIndex + itemIndex += 1 %if Self == 'Set': return key %elif Self == 'Dictionary': @@ -3908,7 +3913,7 @@ public struct ${Self}Generator<${TypeParametersDecl}> : GeneratorType { switch _state { case ._Native(let startIndex, let endIndex, let owner): if startIndex == endIndex { - return .None + return nil } let result = startIndex.nativeStorage.assertingGet(startIndex) _state = @@ -3944,7 +3949,7 @@ public struct ${Self}Generator<${TypeParametersDecl}> : GeneratorType { return (nativeKey, nativeValue) } %end - return .None + return nil #else _sanityCheckFailure("internal error: unexpected cocoa ${Self}") #endif @@ -3965,7 +3970,7 @@ internal struct ${Self}MirrorPosition<${TypeParametersDecl}> { internal mutating func successor() { _intPos = _intPos + 1 - ${Self}Pos = ${Self}Pos.successor() + ${Self}Pos._successorInPlace() } } @@ -4089,13 +4094,13 @@ public struct _${Self}Builder<${TypeParametersDecl}> { public mutating func add(key newKey: Key, value: Value) { _nativeStorage.unsafeAddNew(key: newKey, value: value) %end - _actualCount++ + _actualCount += 1 } @warn_unused_result public mutating func take() -> ${Self}<${TypeParameters}> { _precondition(_actualCount >= 0, - "can not take the result twice") + "cannot take the result twice") _precondition(_actualCount == _requestedCount, "the number of members added does not match the promised count") @@ -4153,7 +4158,7 @@ extension ${Self} { return ${Self}<${TypeParameters}>(_nativeStorageOwner: nativeOwner) } // FIXME: what if `s` is native storage, but for different key/value type? - return .None + return nil } } #endif diff --git a/stdlib/public/core/Hashing.swift b/stdlib/public/core/Hashing.swift index d35e28cf322cc..75ea63e7e3095 100644 --- a/stdlib/public/core/Hashing.swift +++ b/stdlib/public/core/Hashing.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -68,7 +68,7 @@ struct _HashingDetail { // // _mix*() functions all have type (T) -> T. These functions don't compress -// their inputs and just exhibit avalance effect. +// their inputs and just exhibit avalanche effect. // @_transparent @@ -166,7 +166,7 @@ func _squeezeHashValue(hashValue: Int, _ resultRange: Range) -> Int { // We perform the unchecked arithmetic on `UInt` (instead of doing // straightforward computations on `Int`) in order to handle the following // tricky case: `startIndex` is negative, and `resultCardinality >= Int.max`. - // We can not convert the latter to `Int`. + // We cannot convert the latter to `Int`. return Int(bitPattern: UInt(bitPattern: resultRange.startIndex) &+ unsignedResult) diff --git a/stdlib/public/core/HeapBuffer.swift b/stdlib/public/core/HeapBuffer.swift index 3a4227fa0d1e9..0ba2662a89074 100644 --- a/stdlib/public/core/HeapBuffer.swift +++ b/stdlib/public/core/HeapBuffer.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -129,7 +129,7 @@ struct _HeapBuffer : Equatable { } init() { - self._storage = .None + self._storage = nil } public // @testable diff --git a/stdlib/public/core/ImplicitlyUnwrappedOptional.swift b/stdlib/public/core/ImplicitlyUnwrappedOptional.swift index f1ab6ea1af68f..9184ba6e4ea6a 100644 --- a/stdlib/public/core/ImplicitlyUnwrappedOptional.swift +++ b/stdlib/public/core/ImplicitlyUnwrappedOptional.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -59,7 +59,7 @@ public enum ImplicitlyUnwrappedOptional } } - /// Returns `nil` if `self` is nil, `f(self!)` otherwise. + /// Returns `nil` if `self` is `nil`, `f(self!)` otherwise. @warn_unused_result public func flatMap( @noescape f: (Wrapped) throws -> ImplicitlyUnwrappedOptional @@ -95,6 +95,17 @@ extension ImplicitlyUnwrappedOptional : CustomStringConvertible { } } +/// Directly conform to CustomDebugStringConvertible to support +/// optional printing. Implementation of that feature relies on +/// _isOptional thus cannot distinguish ImplicitlyUnwrappedOptional +/// from Optional. When conditional conformance is available, this +/// outright conformance can be removed. +extension ImplicitlyUnwrappedOptional : CustomDebugStringConvertible { + public var debugDescription: String { + return description + } +} + @_transparent @warn_unused_result public // COMPILER_INTRINSIC diff --git a/stdlib/public/core/Index.swift b/stdlib/public/core/Index.swift index ad8c259aa199e..77b6fb65bc018 100644 --- a/stdlib/public/core/Index.swift +++ b/stdlib/public/core/Index.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -73,6 +73,7 @@ public struct _DisabledRangeIndex_ { /// Replace `i` with its `successor()` and return the updated value of /// `i`. @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public prefix func ++ (inout i: T) -> T { i._successorInPlace() return i @@ -81,6 +82,7 @@ public prefix func ++ (inout i: T) -> T { /// Replace `i` with its `successor()` and return the original /// value of `i`. @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public postfix func ++ (inout i: T) -> T { let ret = i i._successorInPlace() @@ -214,8 +216,10 @@ extension ForwardIndexType { _precondition(n >= 0, "Only BidirectionalIndexType can be advanced by a negative amount") var p = self - for var i: Distance = 0; i != n; ++i { - ++p + var i : Distance = 0 + while i != n { + p._successorInPlace() + i = i + 1 } return p } @@ -227,8 +231,11 @@ extension ForwardIndexType { _precondition(n >= 0, "Only BidirectionalIndexType can be advanced by a negative amount") var p = self - for var i: Distance = 0; i != n && p != limit; ++i { - ++p + var i : Distance = 0 + while i != n { + if p == limit { break } + p._successorInPlace() + i = i + 1 } return p } @@ -248,8 +255,8 @@ extension ForwardIndexType { var p = self var count: Distance = 0 while p != end { - ++count - ++p + count += 1 + p._successorInPlace() } return count } @@ -288,8 +295,10 @@ extension BidirectionalIndexType { return _advanceForward(n) } var p = self - for var i: Distance = n; i != 0; ++i { - --p + var i: Distance = n + while i != 0 { + p._predecessorInPlace() + i._successorInPlace() } return p } @@ -300,8 +309,10 @@ extension BidirectionalIndexType { return _advanceForward(n, limit) } var p = self - for var i: Distance = n; i != 0 && p != limit; ++i { - --p + var i: Distance = n + while i != 0 && p != limit { + p._predecessorInPlace() + i._successorInPlace() } return p } @@ -310,6 +321,7 @@ extension BidirectionalIndexType { /// Replace `i` with its `predecessor()` and return the updated value /// of `i`. @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public prefix func -- (inout i: T) -> T { i._predecessorInPlace() return i @@ -319,6 +331,7 @@ public prefix func -- (inout i: T) -> T { /// Replace `i` with its `predecessor()` and return the original /// value of `i`. @_transparent +@available(*, deprecated, message="it will be removed in Swift 3") public postfix func -- (inout i: T) -> T { let ret = i i._predecessorInPlace() @@ -337,7 +350,7 @@ public protocol _RandomAccessAmbiguity { extension _RandomAccessAmbiguity { @warn_unused_result public func advancedBy(n: Distance) -> Self { - fatalError("advancedBy(n) not implememented") + fatalError("advancedBy(n) not implemented") } } diff --git a/stdlib/public/core/InputStream.swift b/stdlib/public/core/InputStream.swift index 78add15a21322..c66fca4cd9dcb 100644 --- a/stdlib/public/core/InputStream.swift +++ b/stdlib/public/core/InputStream.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/IntegerArithmetic.swift.gyb b/stdlib/public/core/IntegerArithmetic.swift.gyb index 1f19cc0cf3297..d6c46369efe9a 100644 --- a/stdlib/public/core/IntegerArithmetic.swift.gyb +++ b/stdlib/public/core/IntegerArithmetic.swift.gyb @@ -1,8 +1,8 @@ -//===--- IntegerArithmetic.swift.gyb -------------------------*- swift -*--===// +//===--- IntegerArithmetic.swift.gyb --------------------------*- swift -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/IntegerParsing.swift.gyb b/stdlib/public/core/IntegerParsing.swift.gyb index 23785008ce9f8..37b6a09cef84c 100644 --- a/stdlib/public/core/IntegerParsing.swift.gyb +++ b/stdlib/public/core/IntegerParsing.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -29,7 +29,7 @@ UIntMax = 'UInt%s' % int_max_bits /// return `nil`. /// /// - Note: If `text` begins with `"+"` or `"-"`, even if the rest of -/// the characters are `"0"`, the result is nil. +/// the characters are `"0"`, the result is `nil`. internal func _parseUnsignedAsciiAsUIntMax( u16: String.UTF16View, _ radix: Int, _ maximum: UIntMax ) -> UIntMax? { @@ -67,21 +67,21 @@ internal func _parseUnsignedAsciiAsUIntMax( /// non-negative number <= `maximum`, return that number. Otherwise, /// return `nil`. /// -/// - Note: If `text` begins with `"+"` or `"-"`, even if the rest of -/// the characters are `"0"`, the result is nil. +/// - Note: For text matching the regular expression "-0+", the result +/// is `0`, not `nil`. internal func _parseAsciiAsUIntMax( - u16: String.UTF16View, _ radix: Int, _ maximum: UIntMax + utf16: String.UTF16View, _ radix: Int, _ maximum: UIntMax ) -> UIntMax? { - if u16.isEmpty { return nil } - let c = u16.first - if _fastPath(c != _ascii16("-")) { - let unsignedText - = c == _ascii16("+") ? u16.dropFirst() : u16 - return _parseUnsignedAsciiAsUIntMax(unsignedText, radix, maximum) - } - else { - return _parseAsciiAsIntMax(u16, radix, 0) == 0 ? 0 : nil - } + if utf16.isEmpty { return nil } + // Parse (optional) sign. + let (digitsUTF16, hasMinus) = _parseOptionalAsciiSign(utf16) + // Parse digits. + guard let result = _parseUnsignedAsciiAsUIntMax(digitsUTF16, radix, maximum) + else { return nil } + // Disallow < 0. + if hasMinus && result != 0 { return nil } + + return result } /// If text is an ASCII representation in the given `radix` of a @@ -91,23 +91,30 @@ internal func _parseAsciiAsUIntMax( /// - Note: For text matching the regular expression "-0+", the result /// is `0`, not `nil`. internal func _parseAsciiAsIntMax( - u16: String.UTF16View, _ radix: Int, _ maximum: IntMax + utf16: String.UTF16View, _ radix: Int, _ maximum: IntMax ) -> IntMax? { _sanityCheck(maximum >= 0, "maximum should be non-negative") + if utf16.isEmpty { return nil } + // Parse (optional) sign. + let (digitsUTF16, hasMinus) = _parseOptionalAsciiSign(utf16) + // Parse digits. +1 for negatives because e.g. Int8's range is -128...127. + let absValueMax = UIntMax(bitPattern: maximum) + (hasMinus ? 1 : 0) + guard let absValue = + _parseUnsignedAsciiAsUIntMax(digitsUTF16, radix, absValueMax) + else { return nil } + // Convert to signed. + return IntMax(bitPattern: hasMinus ? 0 &- absValue : absValue) +} - if u16.isEmpty { return nil } - - // Drop any leading "-" - let negative = u16.first == _ascii16("-") - let absResultText = negative ? u16.dropFirst() : u16 - - let absResultMax = UIntMax(bitPattern: maximum) + (negative ? 1 : 0) - - // Parse the result as unsigned - if let absResult = _parseAsciiAsUIntMax(absResultText, radix, absResultMax) { - return IntMax(bitPattern: negative ? 0 &- absResult : absResult) +/// Strip an optional single leading ASCII plus/minus sign from `utf16`. +private func _parseOptionalAsciiSign( + utf16: String.UTF16View +) -> (digitsUTF16: String.UTF16View, isMinus: Bool) { + switch utf16.first { + case _ascii16("-")?: return (utf16.dropFirst(), true) + case _ascii16("+")?: return (utf16.dropFirst(), false) + default: return (utf16, false) } - return nil } //===--- Loop over all integer types --------------------------------------===// @@ -119,7 +126,7 @@ extension ${Self} { /// Construct from an ASCII representation in the given `radix`. /// /// If `text` does not match the regular expression - /// "[+-][0-9a-zA-Z]+", or the value it denotes in the given `radix` + /// "[+-]?[0-9a-zA-Z]+", or the value it denotes in the given `radix` /// is not representable, the result is `nil`. public init?(_ text: String, radix: Int = 10) { if let value = _parseAsciiAs${'' if signed else 'U'}IntMax( diff --git a/stdlib/public/core/Interval.swift.gyb b/stdlib/public/core/Interval.swift.gyb index 1da7a5c8f4fb1..2cbb54babbed4 100644 --- a/stdlib/public/core/Interval.swift.gyb +++ b/stdlib/public/core/Interval.swift.gyb @@ -1,8 +1,8 @@ -//===--- Interval.swift.gyb ----------------------------------*- swift -*--===// +//===--- Interval.swift.gyb -----------------------------------*- swift -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -226,6 +226,6 @@ internal struct _IntervalMirror< internal var summary: String { return _value.description } internal var quickLookObject: PlaygroundQuickLook? { - return .Some(.Text(summary)) + return .Text(summary) } } diff --git a/stdlib/public/core/Join.swift b/stdlib/public/core/Join.swift index 901d6e0cc410b..8a18093826fc0 100644 --- a/stdlib/public/core/Join.swift +++ b/stdlib/public/core/Join.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/LazyCollection.swift b/stdlib/public/core/LazyCollection.swift index d811b87ce4359..4ca882488efb3 100644 --- a/stdlib/public/core/LazyCollection.swift +++ b/stdlib/public/core/LazyCollection.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/LazySequence.swift b/stdlib/public/core/LazySequence.swift index aadcc0045b66a..b6a08124ac248 100644 --- a/stdlib/public/core/LazySequence.swift +++ b/stdlib/public/core/LazySequence.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -47,7 +47,7 @@ /// /// - Complexity: O(N) /// func scan( /// initial: ResultElement, -/// @noescape combine: (ResultElement, Generator.Element)->ResultElement +/// @noescape combine: (ResultElement, Generator.Element) -> ResultElement /// ) -> [ResultElement] { /// var result = [initial] /// for x in self { @@ -70,7 +70,7 @@ /// } /// private var nextElement: ResultElement? // The next result of next(). /// private var base: Base // The underlying generator. -/// private let combine: (ResultElement, Base.Element)->ResultElement +/// private let combine: (ResultElement, Base.Element) -> ResultElement /// } /// /// struct LazyScanSequence @@ -83,7 +83,7 @@ /// private let initial: ResultElement /// private let base: Base /// private let combine: -/// (ResultElement, Base.Generator.Element)->ResultElement +/// (ResultElement, Base.Generator.Element) -> ResultElement /// } /// /// and finally, we can give all lazy sequences a lazy `scan` method: @@ -101,7 +101,7 @@ /// /// - Complexity: O(1) /// func scan( /// initial: ResultElement, -/// combine: (ResultElement, Generator.Element)->ResultElement +/// combine: (ResultElement, Generator.Element) -> ResultElement /// ) -> LazyScanSequence { /// return LazyScanSequence( /// initial: initial, base: self, combine: combine) @@ -141,7 +141,7 @@ public protocol LazySequenceType : SequenceType { /// of `self` can prevent result types from growing an extra /// `LazySequence` layer. For example, /// - /// _prext_ example neeeded + /// _prext_ example needed /// /// Note: this property need not be implemented by conforming types, /// it has a default implementation in a protocol extension that diff --git a/stdlib/public/core/LifetimeManager.swift b/stdlib/public/core/LifetimeManager.swift index 8984029cbed1a..474951729b5e3 100644 --- a/stdlib/public/core/LifetimeManager.swift +++ b/stdlib/public/core/LifetimeManager.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/ManagedBuffer.swift b/stdlib/public/core/ManagedBuffer.swift index da15cf4d2d215..38789e3a021c5 100644 --- a/stdlib/public/core/ManagedBuffer.swift +++ b/stdlib/public/core/ManagedBuffer.swift @@ -1,8 +1,8 @@ -//===--- ManagedBuffer.swift - variable-sized buffer of aligned memory ---===// +//===--- ManagedBuffer.swift - variable-sized buffer of aligned memory ----===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -45,7 +45,7 @@ public class ManagedProtoBuffer : NonObjectiveCBase { /// - Note: This pointer is only valid for the duration of the /// call to `body`. public final func withUnsafeMutablePointerToValue( - body: (UnsafeMutablePointer)->R + body: (UnsafeMutablePointer) -> R ) -> R { return withUnsafeMutablePointers { (v, e) in return body(v) } } @@ -56,7 +56,7 @@ public class ManagedProtoBuffer : NonObjectiveCBase { /// - Note: This pointer is only valid for the duration of the /// call to `body`. public final func withUnsafeMutablePointerToElements( - body: (UnsafeMutablePointer)->R + body: (UnsafeMutablePointer) -> R ) -> R { return withUnsafeMutablePointers { return body($0.1) } } @@ -67,7 +67,7 @@ public class ManagedProtoBuffer : NonObjectiveCBase { /// - Note: These pointers are only valid for the duration of the /// call to `body`. public final func withUnsafeMutablePointers( - body: (_: UnsafeMutablePointer, _: UnsafeMutablePointer)->R + body: (_: UnsafeMutablePointer, _: UnsafeMutablePointer) -> R ) -> R { return ManagedBufferPointer(self).withUnsafeMutablePointers(body) } @@ -99,7 +99,7 @@ public class ManagedBuffer /// generate an initial `Value`. public final class func create( minimumCapacity: Int, - initialValue: (ManagedProtoBuffer)->Value + initialValue: (ManagedProtoBuffer) -> Value ) -> ManagedBuffer { let p = ManagedBufferPointer( @@ -146,7 +146,7 @@ public class ManagedBuffer /// typealias Manager = ManagedBufferPointer<(Int,String), Element> /// deinit { /// Manager(unsafeBufferObject: self).withUnsafeMutablePointers { -/// (pointerToValue, pointerToElements)->Void in +/// (pointerToValue, pointerToElements) -> Void in /// pointerToElements.destroy(self.count) /// pointerToValue.destroy() /// } @@ -181,7 +181,7 @@ public struct ManagedBufferPointer : Equatable { public init( bufferClass: AnyClass, minimumCapacity: Int, - initialValue: (buffer: AnyObject, allocatedCount: (AnyObject)->Int)->Value + initialValue: (buffer: AnyObject, allocatedCount: (AnyObject) -> Int) -> Value ) { self = ManagedBufferPointer(bufferClass: bufferClass, minimumCapacity: minimumCapacity) @@ -253,7 +253,7 @@ public struct ManagedBufferPointer : Equatable { /// - Note: This pointer is only valid /// for the duration of the call to `body`. public func withUnsafeMutablePointerToValue( - body: (UnsafeMutablePointer)->R + body: (UnsafeMutablePointer) -> R ) -> R { return withUnsafeMutablePointers { (v, e) in return body(v) } } @@ -264,7 +264,7 @@ public struct ManagedBufferPointer : Equatable { /// - Note: This pointer is only valid for the duration of the /// call to `body`. public func withUnsafeMutablePointerToElements( - body: (UnsafeMutablePointer)->R + body: (UnsafeMutablePointer) -> R ) -> R { return withUnsafeMutablePointers { return body($0.1) } } @@ -275,7 +275,7 @@ public struct ManagedBufferPointer : Equatable { /// - Note: These pointers are only valid for the duration of the /// call to `body`. public func withUnsafeMutablePointers( - body: (_: UnsafeMutablePointer, _: UnsafeMutablePointer)->R + body: (_: UnsafeMutablePointer, _: UnsafeMutablePointer) -> R ) -> R { let result = body(_valuePointer, _elementPointer) _fixLifetime(_nativeBuffer) diff --git a/stdlib/public/core/Map.swift b/stdlib/public/core/Map.swift index db885411e7f1a..3ec1b318a83b5 100644 --- a/stdlib/public/core/Map.swift +++ b/stdlib/public/core/Map.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -26,17 +26,13 @@ public struct LazyMapGenerator< /// since the copy was made, and no preceding call to `self.next()` /// has returned `nil`. public mutating func next() -> Element? { - let x = _base.next() - if x != nil { - return _transform(x!) - } - return nil + return _base.next().map(_transform) } public var base: Base { return _base } internal var _base: Base - internal var _transform: (Base.Element)->Element + internal var _transform: (Base.Element) -> Element } /// A `SequenceType` whose elements consist of those in a `Base` @@ -65,13 +61,13 @@ public struct LazyMapSequence /// Create an instance with elements `transform(x)` for each element /// `x` of base. - public init(_ base: Base, transform: (Base.Generator.Element)->Element) { + public init(_ base: Base, transform: (Base.Generator.Element) -> Element) { self._base = base self._transform = transform } public var _base: Base - internal var _transform: (Base.Generator.Element)->Element + internal var _transform: (Base.Generator.Element) -> Element @available(*, unavailable, renamed="Element") public typealias T = Element @@ -127,19 +123,19 @@ public struct LazyMapCollection /// Create an instance with elements `transform(x)` for each element /// `x` of base. - public init(_ base: Base, transform: (Base.Generator.Element)->Element) { + public init(_ base: Base, transform: (Base.Generator.Element) -> Element) { self._base = base self._transform = transform } public var _base: Base - var _transform: (Base.Generator.Element)->Element + var _transform: (Base.Generator.Element) -> Element @available(*, unavailable, renamed="Element") public typealias T = Element } -//===--- Support for s.lazy ----------------------------------------------===// +//===--- Support for s.lazy -----------------------------------------------===// extension LazySequenceType { /// Return a `LazyMapSequence` over this `Sequence`. The elements of diff --git a/stdlib/public/core/Mirror.swift b/stdlib/public/core/Mirror.swift index 380c27e6bf48d..13fccfa476dc5 100644 --- a/stdlib/public/core/Mirror.swift +++ b/stdlib/public/core/Mirror.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -83,7 +83,7 @@ public struct Mirror { /// children: ["someProperty": self.someProperty], /// ancestorRepresentation: .Customized(super.customMirror)) // <== /// } - case Customized(()->Mirror) + case Customized(() -> Mirror) /// Suppress the representation of all ancestor classes. The /// resulting `Mirror`'s `superclassMirror()` is `nil`. @@ -169,7 +169,7 @@ public struct Mirror { @warn_unused_result internal static func _superclassGenerator( subject: T, _ ancestorRepresentation: AncestorRepresentation - ) -> ()->Mirror? { + ) -> () -> Mirror? { if let subject = subject as? AnyObject, let subjectClass = T.self as? AnyClass, @@ -338,7 +338,7 @@ public struct Mirror { return _makeSuperclassMirror() } - internal let _makeSuperclassMirror: ()->Mirror? + internal let _makeSuperclassMirror: () -> Mirror? internal let _defaultDescendantRepresentation: DefaultDescendantRepresentation } @@ -490,7 +490,7 @@ extension _MirrorType { internal extension Mirror { /// An adapter that represents a legacy `_MirrorType`'s children as /// a `Collection` with integer `Index`. Note that the performance - /// characterstics of the underlying `_MirrorType` may not be + /// characteristics of the underlying `_MirrorType` may not be /// appropriate for random access! To avoid this pitfall, convert /// mirrors to use the new style, which only present forward /// traversal in general. @@ -552,7 +552,7 @@ internal extension Mirror { internal init( legacy legacyMirror: _MirrorType, subjectType: Any.Type, - makeSuperclassMirror: (()->Mirror?)? = nil + makeSuperclassMirror: (() -> Mirror?)? = nil ) { if let makeSuperclassMirror = makeSuperclassMirror { self._makeSuperclassMirror = makeSuperclassMirror diff --git a/stdlib/public/core/Mirrors.swift.gyb b/stdlib/public/core/Mirrors.swift.gyb index 6e0eb40d1fa90..48549acff82f5 100644 --- a/stdlib/public/core/Mirrors.swift.gyb +++ b/stdlib/public/core/Mirrors.swift.gyb @@ -1,8 +1,8 @@ -//===--- Mirrors.swift.gyb - Common _MirrorType implementations -*- swift -*-==// +//===--- Mirrors.swift.gyb - Common _MirrorType impls. --------*- swift -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -43,7 +43,7 @@ internal func _toString(x: T) -> String { extension ${Type[0]} : _Reflectable { /// Returns a mirror that reflects `self`. public func _getMirror() -> _MirrorType { - return _LeafMirror(self, _toString, { .Some(${Type[1]}(${Type[2]})) }) + return _LeafMirror(self, _toString, { ${Type[1]}(${Type[2]}) }) } } % end diff --git a/stdlib/public/core/Misc.swift b/stdlib/public/core/Misc.swift index 51ad4203b7064..ae6941b0c651f 100644 --- a/stdlib/public/core/Misc.swift +++ b/stdlib/public/core/Misc.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -83,6 +83,30 @@ func _typeName(type: Any.Type, qualified: Bool = true) -> String { input: UnsafeBufferPointer(start: stringPtr, count: count)) } +@warn_unused_result +@_silgen_name("swift_stdlib_demangleName") +func _stdlib_demangleNameImpl( + mangledName: UnsafePointer, + _ mangledNameLength: UInt, + _ demangledName: UnsafeMutablePointer) + +// NB: This function is not used directly in the Swift codebase, but is +// exported for Xcode support. Please coordinate before changing. +@warn_unused_result +public // @testable +func _stdlib_demangleName(mangledName: String) -> String { + let mangledNameUTF8 = Array(mangledName.utf8) + return mangledNameUTF8.withUnsafeBufferPointer { + (mangledNameUTF8) in + let (_, demangledName) = _withUninitializedString { + _stdlib_demangleNameImpl( + mangledNameUTF8.baseAddress, UInt(mangledNameUTF8.endIndex), + $0) + } + return demangledName + } +} + /// Returns `floor(log(x))`. This equals to the position of the most /// significant non-zero bit, or 63 - number-of-zeros before it. /// @@ -100,7 +124,7 @@ func _typeName(type: Any.Type, qualified: Bool = true) -> String { public // @testable func _floorLog2(x: Int64) -> Int { _sanityCheck(x > 0, "_floorLog2 operates only on non-negative integers") - // Note: use unchecked subtraction because we this expression can not + // Note: use unchecked subtraction because we this expression cannot // overflow. return 63 &- Int(_countLeadingZeros(x)) } diff --git a/stdlib/public/core/ObjCMirrors.swift b/stdlib/public/core/ObjCMirrors.swift index 40609b5587af5..ffb1525de07f3 100644 --- a/stdlib/public/core/ObjCMirrors.swift +++ b/stdlib/public/core/ObjCMirrors.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/OptionSet.swift b/stdlib/public/core/OptionSet.swift index 1498921a6ad4a..dbf3c3abe94af 100644 --- a/stdlib/public/core/OptionSet.swift +++ b/stdlib/public/core/OptionSet.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Optional.swift b/stdlib/public/core/Optional.swift index 4f81e50b73fdc..1511fb75e913c 100644 --- a/stdlib/public/core/Optional.swift +++ b/stdlib/public/core/Optional.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -38,7 +38,7 @@ public enum Optional : _Reflectable, NilLiteralConvertible { } } - /// Returns `nil` if `self` is nil, `f(self!)` otherwise. + /// Returns `nil` if `self` is `nil`, `f(self!)` otherwise. @warn_unused_result public func flatMap(@noescape f: (Wrapped) throws -> U?) rethrows -> U? { switch self { @@ -86,14 +86,14 @@ extension Optional : CustomDebugStringConvertible { // /// Haskell's fmap for Optionals. @available(*, unavailable, message="call the 'map()' method on the optional value") -public func map(x: T?, @noescape _ f: (T)->U) -> U? { +public func map(x: T?, @noescape _ f: (T) -> U) -> U? { fatalError("unavailable function can't be called") } -/// Returns `f(self)!` iff `self` and `f(self)` are not nil. +/// Returns `f(self)!` iff `self` and `f(self)` are not `nil`. @available(*, unavailable, message="call the 'flatMap()' method on the optional value") -public func flatMap(x: T?, @noescape _ f: (T)->U?) -> U? { +public func flatMap(x: T?, @noescape _ f: (T) -> U?) -> U? { fatalError("unavailable function can't be called") } @@ -138,7 +138,7 @@ func _injectNothingIntoOptional() -> Wrapped? { // Comparisons @warn_unused_result public func == (lhs: T?, rhs: T?) -> Bool { - switch (lhs,rhs) { + switch (lhs, rhs) { case let (l?, r?): return l == r case (nil, nil): @@ -230,8 +230,8 @@ internal struct _OptionalMirror : _MirrorType { var count: Int { return (_value != nil) ? 1 : 0 } subscript(i: Int) -> (String, _MirrorType) { - switch (_value,i) { - case (.Some(let contents),0) : return ("Some",_reflect(contents)) + switch (_value, i) { + case (.Some(let contents), 0) : return ("Some", _reflect(contents)) default: _preconditionFailure("cannot extract this child index") } } @@ -251,7 +251,7 @@ internal struct _OptionalMirror : _MirrorType { @warn_unused_result public func < (lhs: T?, rhs: T?) -> Bool { - switch (lhs,rhs) { + switch (lhs, rhs) { case let (l?, r?): return l < r case (nil, _?): @@ -263,7 +263,7 @@ public func < (lhs: T?, rhs: T?) -> Bool { @warn_unused_result public func > (lhs: T?, rhs: T?) -> Bool { - switch (lhs,rhs) { + switch (lhs, rhs) { case let (l?, r?): return l > r default: @@ -273,7 +273,7 @@ public func > (lhs: T?, rhs: T?) -> Bool { @warn_unused_result public func <= (lhs: T?, rhs: T?) -> Bool { - switch (lhs,rhs) { + switch (lhs, rhs) { case let (l?, r?): return l <= r default: @@ -283,7 +283,7 @@ public func <= (lhs: T?, rhs: T?) -> Bool { @warn_unused_result public func >= (lhs: T?, rhs: T?) -> Bool { - switch (lhs,rhs) { + switch (lhs, rhs) { case let (l?, r?): return l >= r default: diff --git a/stdlib/public/core/OutputStream.swift b/stdlib/public/core/OutputStream.swift index cf68151642b25..e3d07c8b87f96 100644 --- a/stdlib/public/core/OutputStream.swift +++ b/stdlib/public/core/OutputStream.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -165,6 +165,16 @@ internal func _adHocPrint( internal func _print_unlocked( value: T, inout _ target: TargetStream ) { + // Optional has no representation suitable for display; therefore, + // values of optional type should be printed as a debug + // string. Check for Optional first, before checking protocol + // conformance below, because an Optional value is convertible to a + // protocol if its wrapped type conforms to that protocol. + if _isOptional(value.dynamicType) { + let debugPrintable = value as! CustomDebugStringConvertible + debugPrintable.debugDescription.writeTo(&target) + return + } if case let streamableObject as Streamable = value { streamableObject.writeTo(&target) return @@ -333,7 +343,7 @@ public func toDebugString(x: T) -> String { } /// A hook for playgrounds to print through. -public var _playgroundPrintHook : ((String)->Void)? = {_ in () } +public var _playgroundPrintHook : ((String) -> Void)? = {_ in () } internal struct _TeeStream< L : OutputStreamType, diff --git a/stdlib/public/core/Pointer.swift b/stdlib/public/core/Pointer.swift index ac10075644e27..96eddcc18b254 100644 --- a/stdlib/public/core/Pointer.swift +++ b/stdlib/public/core/Pointer.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Policy.swift b/stdlib/public/core/Policy.swift index 5d072539ab43b..e4cf45b9edff0 100644 --- a/stdlib/public/core/Policy.swift +++ b/stdlib/public/core/Policy.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -85,10 +85,10 @@ public typealias Any = protocol<> /// @objc func getCValue() -> Int { return 42 } /// } /// -/// // If x has a method @objc getValue()->Int, call it and -/// // return the result. Otherwise, return nil. +/// // If x has a method @objc getValue() -> Int, call it and +/// // return the result. Otherwise, return `nil`. /// func getCValue1(x: AnyObject) -> Int? { -/// if let f: ()->Int = x.getCValue { // <=== +/// if let f: () -> Int = x.getCValue { // <=== /// return f() /// } /// return nil @@ -134,7 +134,7 @@ public protocol AnyObject : class {} /// } /// /// // If x has an @objc cValue: Int, return its value. -/// // Otherwise, return nil. +/// // Otherwise, return `nil`. /// func getCValue(x: AnyClass) -> Int? { /// return x.cValue // <=== /// } @@ -142,6 +142,10 @@ public protocol AnyObject : class {} /// - SeeAlso: `AnyObject` public typealias AnyClass = AnyObject.Type +/// Returns true iff `lhs` and `rhs` are references to the same object +/// instance (in other words, are identical pointers). +/// +/// - SeeAlso: `Equatable`, `==` @warn_unused_result public func === (lhs: AnyObject?, rhs: AnyObject?) -> Bool { switch (lhs, rhs) { @@ -327,7 +331,7 @@ public protocol Hashable : Equatable { } public protocol _SinkType {} -@available(*, unavailable, message="SinkType has been removed. Use (T)->() closures directly instead.") +@available(*, unavailable, message="SinkType has been removed. Use (T) -> () closures directly instead.") public typealias SinkType = _SinkType //===----------------------------------------------------------------------===// @@ -447,4 +451,3 @@ infix operator |= { associativity right precedence 90 assignment } // example of how this operator is used, and how its use can be hidden // from users. infix operator ~> { associativity left precedence 255 } - diff --git a/stdlib/public/core/Prespecialized.swift b/stdlib/public/core/Prespecialized.swift index 41772a059707d..f258d07bc9d2d 100644 --- a/stdlib/public/core/Prespecialized.swift +++ b/stdlib/public/core/Prespecialized.swift @@ -2,14 +2,14 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -// Pre-specializaiton of some popular generic classes and functions. +// Pre-specialization of some popular generic classes and functions. //===----------------------------------------------------------------------===// struct _Prespecialize { @@ -29,8 +29,8 @@ struct _Prespecialize { a[0] = a[j] } - for var i1 = 0; i1 < a.count; ++i1 { - for var i2 = 0; i2 < a.count; ++i2 { + for i1 in 0..( @@ -100,7 +100,7 @@ public func print( /// /// - Note: To print without a trailing newline, pass `terminator: ""` /// -/// - SeeAlso: `print`, Streamable`, `CustomStringConvertible`, +/// - SeeAlso: `print`, `Streamable`, `CustomStringConvertible`, /// `CustomDebugStringConvertible` @inline(__always) public func debugPrint( diff --git a/stdlib/public/core/Process.swift b/stdlib/public/core/Process.swift index 1a80e97d23c00..004d3b10c8c05 100644 --- a/stdlib/public/core/Process.swift +++ b/stdlib/public/core/Process.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/REPL.swift b/stdlib/public/core/REPL.swift index 0826df5aad696..e6e94fe4b07af 100644 --- a/stdlib/public/core/REPL.swift +++ b/stdlib/public/core/REPL.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Range.swift b/stdlib/public/core/Range.swift index ea214964e49f6..89160126dd979 100644 --- a/stdlib/public/core/Range.swift +++ b/stdlib/public/core/Range.swift @@ -1,8 +1,8 @@ -//===- Range.swift.gyb ----------------------------------------*- swift -*-===// +//===--- Range.swift ------------------------------------------*- swift -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,10 +28,10 @@ public struct RangeGenerator< /// Advance to the next element and return it, or `nil` if no next /// element exists. public mutating func next() -> Element? { - if startIndex == endIndex { - return .None - } - return startIndex++ + if startIndex == endIndex { return nil } + let element = startIndex + startIndex._successorInPlace() + return element } /// The lower bound of the remaining range. diff --git a/stdlib/public/core/RangeMirrors.swift.gyb b/stdlib/public/core/RangeMirrors.swift.gyb index 69197c94ca608..294f5ce17097c 100644 --- a/stdlib/public/core/RangeMirrors.swift.gyb +++ b/stdlib/public/core/RangeMirrors.swift.gyb @@ -1,8 +1,8 @@ -//===- RangeMirrors.swift.gyb ---------------------------------*- swift -*-===// +//===--- RangeMirrors.swift.gyb -------------------------------*- swift -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/RangeReplaceableCollectionType.swift b/stdlib/public/core/RangeReplaceableCollectionType.swift index 9017e8a895bae..f7f0ca48fe46e 100644 --- a/stdlib/public/core/RangeReplaceableCollectionType.swift +++ b/stdlib/public/core/RangeReplaceableCollectionType.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -459,7 +459,7 @@ public func +< where S.Generator.Element == C.Generator.Element >(lhs: S, rhs: C) -> C { var result = C() - result.reserveCapacity(rhs.count + numericCast(rhs.underestimateCount())) + result.reserveCapacity(rhs.count + numericCast(lhs.underestimateCount())) result.appendContentsOf(lhs) result.appendContentsOf(rhs) return result diff --git a/stdlib/public/core/Reflection.swift b/stdlib/public/core/Reflection.swift index 77cd39d74cda5..e58d4335ca3c8 100644 --- a/stdlib/public/core/Reflection.swift +++ b/stdlib/public/core/Reflection.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -175,7 +175,7 @@ func _dumpWithMirror( inout _ targetStream: TargetStream ) { if maxItemCounter <= 0 { return } - --maxItemCounter + maxItemCounter -= 1 for _ in 0.., - _ bufferLength: UInt, _ value: Float${bits} + _ bufferLength: UInt, _ value: Float${bits}, + _ debug: Bool ) -> UInt @warn_unused_result -func _float${bits}ToString(value: Float${bits}) -> String { +func _float${bits}ToString(value: Float${bits}, debug: Bool) -> String { _sanityCheck(sizeof(_Buffer32.self) == 32) _sanityCheck(sizeof(_Buffer72.self) == 72) @@ -367,7 +368,7 @@ func _float${bits}ToString(value: Float${bits}) -> String { return withUnsafeMutablePointer(&buffer) { (bufferPtr) in let bufferUTF8Ptr = UnsafeMutablePointer(bufferPtr) - let actualLength = _float${bits}ToStringImpl(bufferUTF8Ptr, 32, value) + let actualLength = _float${bits}ToStringImpl(bufferUTF8Ptr, 32, value, debug) return String._fromWellFormedCodeUnitSequence( UTF8.self, input: UnsafeBufferPointer( @@ -502,7 +503,7 @@ class _SwiftNativeNSEnumerator {} // Use 'dynamic' to prevent this call to be duplicated into other modules. @objc dynamic func initializeReturnAutoreleased() { - // On x86_64 it is sufficient to perform one cycle of return-autorelesed + // On x86_64 it is sufficient to perform one cycle of return-autoreleased // call sequence in order to initialize all required PLT entries. self.returnsAutoreleased(self) } diff --git a/stdlib/public/core/Sequence.swift b/stdlib/public/core/Sequence.swift index 70f35449c56b1..0d7df20275016 100644 --- a/stdlib/public/core/Sequence.swift +++ b/stdlib/public/core/Sequence.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -189,7 +189,7 @@ public protocol SequenceType { /// If `self` is multi-pass (i.e., a `CollectionType`), invoke /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. - func _preprocessingPass(preprocess: (Self)->R) -> R? + func _preprocessingPass(@noescape preprocess: (Self) -> R) -> R? /// Create a native array buffer containing the elements of `self`, /// in the same order. @@ -240,10 +240,20 @@ internal class _DropFirstSequence dropped = limit return nil } - ++dropped + dropped += 1 } return generator.next() } + + internal func dropFirst(n: Int) -> AnySequence { + // If this is already a _DropFirstSequence, we need to fold in + // the current drop count and drop limit so no data is lost. + // + // i.e. [1,2,3,4].dropFirst(1).dropFirst(1) should be equivalent to + // [1,2,3,4].dropFirst(2). + return AnySequence( + _DropFirstSequence(generator, limit: limit + n, dropped: dropped)) + } } /// A sequence that only consumes up to `n` elements from an underlying @@ -253,7 +263,8 @@ internal class _DropFirstSequence /// /// This is a class - we require reference semantics to keep track /// of how many elements we've already taken from the underlying sequence. -internal class _PrefixSequence : SequenceType, GeneratorType { +internal class _PrefixSequence + : SequenceType, GeneratorType { internal let maxLength: Int internal var generator: Base internal var taken: Int @@ -270,7 +281,7 @@ internal class _PrefixSequence : SequenceType, GeneratorTy internal func next() -> Base.Element? { if taken >= maxLength { return nil } - ++taken + taken += 1 if let next = generator.next() { return next @@ -279,6 +290,12 @@ internal class _PrefixSequence : SequenceType, GeneratorTy taken = maxLength return nil } + + internal func prefix(maxLength: Int) -> AnySequence { + return AnySequence( + _PrefixSequence(generator, + maxLength: min(maxLength, self.maxLength), taken: taken)) + } } //===----------------------------------------------------------------------===// @@ -331,83 +348,6 @@ extension SequenceType { return Array(result) } - /// Returns a subsequence containing all but the first `n` elements. - /// - /// - Requires: `n >= 0` - /// - Complexity: O(`n`) - @warn_unused_result - public func dropFirst(n: Int) -> AnySequence { - _precondition(n >= 0, "Can't drop a negative number of elements from a sequence") - if n == 0 { return AnySequence(self) } - // If this is already a _DropFirstSequence, we need to fold in - // the current drop count and drop limit so no data is lost. - // - // i.e. [1,2,3,4].dropFirst(1).dropFirst(1) should be equivalent to - // [1,2,3,4].dropFirst(2). - // FIXME: Use method dispatch to fold - // _PrefixSequence and _DropFirstSequence counts - if let any = self as? AnySequence, - let box = any._box as? _SequenceBox<_DropFirstSequence> { - let base = box._base - let folded = _DropFirstSequence(base.generator, limit: base.limit + n, - dropped: base.dropped) - return AnySequence(folded) - } - - return AnySequence(_DropFirstSequence(generate(), limit: n)) - } - - /// Returns a subsequence containing all but the last `n` elements. - /// - /// - Requires: `self` is a finite collection. - /// - Requires: `n >= 0` - /// - Complexity: O(`self.count`) - @warn_unused_result - public func dropLast(n: Int) -> AnySequence { - _precondition(n >= 0, "Can't drop a negative number of elements from a sequence") - if n == 0 { return AnySequence(self) } - // FIXME: Create reusable RingBuffer - // Put incoming elements from this sequence in a holding tank, a ring buffer - // of size <= n. If more elements keep coming in, pull them out of the - // holding tank into the result, an `Array`. This saves - // `n` * sizeof(Generator.Element) of memory, because slices keep the entire - // memory of an `Array` alive. - var result: [Generator.Element] = [] - var ringBuffer: [Generator.Element] = [] - var i = ringBuffer.startIndex - - for element in self { - if ringBuffer.count < n { - ringBuffer.append(element) - } else { - result.append(ringBuffer[i]) - ringBuffer[i] = element - i = i.successor() % n - } - } - return AnySequence(result) - } - - @warn_unused_result - public func prefix(maxLength: Int) -> AnySequence { - _precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence") - if maxLength == 0 { - return AnySequence(EmptyCollection()) - } - // FIXME: Use method dispatch to fold - // _PrefixSequence and _DropFirstSequence counts - if let any = self as? AnySequence, - let box = any._box as? _SequenceBox<_PrefixSequence> { - let base = box._base - let folded = _PrefixSequence( - base.generator, - maxLength: min(base.maxLength, maxLength), - taken: base.taken) - return AnySequence(folded) - } - return AnySequence(_PrefixSequence(generate(), maxLength: maxLength)) - } - @warn_unused_result public func suffix(maxLength: Int) -> AnySequence { _precondition(maxLength >= 0, "Can't take a suffix of negative length from a sequence") @@ -516,7 +456,7 @@ extension SequenceType { return 0 } - public func _preprocessingPass(preprocess: (Self)->R) -> R? { + public func _preprocessingPass(@noescape preprocess: (Self) -> R) -> R? { return nil } @@ -526,9 +466,7 @@ extension SequenceType { ) -> Bool? { return nil } -} -extension SequenceType { /// Call `body` on each element in `self` in the same order as a /// *for-in loop.* /// @@ -585,6 +523,64 @@ extension SequenceType where Generator.Element : Equatable { } } +extension SequenceType where + SubSequence : SequenceType, + SubSequence.Generator.Element == Generator.Element, + SubSequence.SubSequence == SubSequence { + + /// Returns a subsequence containing all but the first `n` elements. + /// + /// - Requires: `n >= 0` + /// - Complexity: O(`n`) + @warn_unused_result + public func dropFirst(n: Int) -> AnySequence { + _precondition(n >= 0, "Can't drop a negative number of elements from a sequence") + if n == 0 { return AnySequence(self) } + return AnySequence(_DropFirstSequence(generate(), limit: n)) + } + + /// Returns a subsequence containing all but the last `n` elements. + /// + /// - Requires: `self` is a finite collection. + /// - Requires: `n >= 0` + /// - Complexity: O(`self.count`) + @warn_unused_result + public func dropLast(n: Int) -> AnySequence { + _precondition(n >= 0, "Can't drop a negative number of elements from a sequence") + if n == 0 { return AnySequence(self) } + + // FIXME: Create reusable RingBuffer + // Put incoming elements from this sequence in a holding tank, a ring buffer + // of size <= n. If more elements keep coming in, pull them out of the + // holding tank into the result, an `Array`. This saves + // `n` * sizeof(Generator.Element) of memory, because slices keep the entire + // memory of an `Array` alive. + var result: [Generator.Element] = [] + var ringBuffer: [Generator.Element] = [] + var i = ringBuffer.startIndex + + for element in self { + if ringBuffer.count < n { + ringBuffer.append(element) + } else { + result.append(ringBuffer[i]) + ringBuffer[i] = element + i = i.successor() % n + } + } + return AnySequence(result) + } + + @warn_unused_result + public func prefix(maxLength: Int) -> AnySequence { + _precondition(maxLength >= 0, "Can't take a prefix of negative length from a sequence") + if maxLength == 0 { + return AnySequence(EmptyCollection()) + } + return AnySequence(_PrefixSequence(generate(), maxLength: maxLength)) + } +} + extension SequenceType { /// Returns a subsequence containing all but the first element. /// @@ -613,7 +609,8 @@ extension SequenceType { -> UnsafeMutablePointer { var p = UnsafeMutablePointer(ptr) for x in GeneratorSequence(self.generate()) { - p++.initialize(x) + p.initialize(x) + p += 1 } return p } diff --git a/stdlib/public/core/SequenceAlgorithms.swift.gyb b/stdlib/public/core/SequenceAlgorithms.swift.gyb index 27fbebb6832b7..eb95e1e48aac6 100644 --- a/stdlib/public/core/SequenceAlgorithms.swift.gyb +++ b/stdlib/public/core/SequenceAlgorithms.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -53,7 +53,7 @@ extension SequenceType { if preds: orderingRequirement = """ /// - Requires: `isOrderedBefore` is a - /// [strict weak ordering](http://en.wikipedia.org/wiki/Strict_weak_order#Strict_weak_orderings). + /// [strict weak ordering](http://en.wikipedia.org/wiki/Strict_weak_order#Strict_weak_orderings) /// over `self`.""" rethrows_ = "rethrows " else: @@ -285,7 +285,7 @@ else: if ${"try isOrderedBefore(e2, e1)" if preds else "e2 < e1"} { return false } - continue // equivalent + continue // Equivalent } return false } diff --git a/stdlib/public/core/SequenceWrapper.swift b/stdlib/public/core/SequenceWrapper.swift index 971d8e8992905..a968b04cf5bc2 100644 --- a/stdlib/public/core/SequenceWrapper.swift +++ b/stdlib/public/core/SequenceWrapper.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -61,7 +61,7 @@ extension SequenceType /// If `self` is multi-pass (i.e., a `CollectionType`), invoke /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. - public func _preprocessingPass(preprocess: (Self)->R) -> R? { + public func _preprocessingPass(@noescape preprocess: (Self) -> R) -> R? { return _base._preprocessingPass { _ in preprocess(self) } } @@ -137,7 +137,7 @@ extension CollectionType /// If `self` is multi-pass (i.e., a `CollectionType`), invoke /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. - public func _preprocessingPass(preprocess: (Self)->R) -> R? { + public func _preprocessingPass(@noescape preprocess: (Self) -> R) -> R? { return _base._preprocessingPass { _ in preprocess(self) } } diff --git a/stdlib/public/core/SetAlgebra.swift b/stdlib/public/core/SetAlgebra.swift index 2119215e3d832..8dab5c0178e78 100644 --- a/stdlib/public/core/SetAlgebra.swift +++ b/stdlib/public/core/SetAlgebra.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -46,7 +46,6 @@ /// - `x.isStrictSupersetOf(y)` iff `x.isSupersetOf(y) && x != y` /// - `x.isStrictSubsetOf(y)` iff `x.isSubsetOf(y) && x != y` public protocol SetAlgebraType : Equatable, ArrayLiteralConvertible { - /// A type for which `Self` provides a containment test. typealias Element @@ -148,7 +147,6 @@ public protocol SetAlgebraType : Equatable, ArrayLiteralConvertible { /// - SeeAlso: `Self.element(_, subsumes:_)` @warn_unused_result static func element(a: Element, isDisjointWith b: Element) -> Bool - } /// `SetAlgebraType` requirements for which default implementations @@ -200,7 +198,7 @@ extension SetAlgebraType { return self.intersect(other).isEmpty } - /// Returns true iff `self.intersect(other).isEmpty`. + /// Returns the set of elements contained in `self` but not in `other`. @warn_unused_result public func subtract(other: Self) -> Self { return self.intersect(self.exclusiveOr(other)) diff --git a/stdlib/public/core/ShadowProtocols.swift b/stdlib/public/core/ShadowProtocols.swift index d881c77e813e8..a6055267af0a3 100644 --- a/stdlib/public/core/ShadowProtocols.swift +++ b/stdlib/public/core/ShadowProtocols.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Shims.swift b/stdlib/public/core/Shims.swift index ca3f90a82b1d7..86aace93ab91b 100644 --- a/stdlib/public/core/Shims.swift +++ b/stdlib/public/core/Shims.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/Slice.swift.gyb b/stdlib/public/core/Slice.swift.gyb index 612883de955b4..2a4cfc591b3dd 100644 --- a/stdlib/public/core/Slice.swift.gyb +++ b/stdlib/public/core/Slice.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,12 +21,12 @@ def get_slice_doc_comment(Self): /// /// A `%s` instance inherits the value or reference semantics of the base /// collection. That is, if a `%s` instance is wrapped around a mutable -/// colection that has value semantics (for example, `Array`), mutating the +/// collection that has value semantics (for example, `Array`), mutating the /// original collection would not affect the copy stored inside of the slice. /// /// An element of a slice is located under the same index in the slice and in /// the base collection, as long as neither the collection or the slice were -/// mutated. Thus, indices of a slice can be used interchangibly with indices +/// mutated. Thus, indices of a slice can be used interchangeably with indices /// of the base collection. /// /// - Warning: Long-term storage of `%s` instances is discouraged. diff --git a/stdlib/public/core/SliceBuffer.swift b/stdlib/public/core/SliceBuffer.swift index bf948dc2da7ad..cdd68ac0caab7 100644 --- a/stdlib/public/core/SliceBuffer.swift +++ b/stdlib/public/core/SliceBuffer.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -194,10 +194,6 @@ struct _SliceBuffer : _ArrayBufferType { return target + c } - var arrayPropertyIsNative : Bool { - return _hasNativeBuffer - } - /// True, if the array is native and does not need a deferred type check. var arrayPropertyIsNativeTypeChecked : Bool { return _hasNativeBuffer diff --git a/stdlib/public/core/Sort.swift.gyb b/stdlib/public/core/Sort.swift.gyb index 1681bcbc171f2..95ca79a3613b7 100644 --- a/stdlib/public/core/Sort.swift.gyb +++ b/stdlib/public/core/Sort.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -45,7 +45,7 @@ func _insertionSort< >( inout elements: C, _ range: Range ${"," if p else ""} - ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) { if !range.isEmpty { let start = range.startIndex @@ -56,7 +56,8 @@ func _insertionSort< // One element is trivially already-sorted, thus pre-increment // Continue until the sorted elements cover the whole sequence - while (++sortedEnd != range.endIndex) { + sortedEnd._successorInPlace() + while sortedEnd != range.endIndex { // get the first unsorted element let x: C.Generator.Element = elements[sortedEnd] @@ -73,13 +74,14 @@ func _insertionSort< // Move y forward elements[i] = predecessor - } - while --i != start + i._predecessorInPlace() + } while i != start if i != sortedEnd { // Plop x into position elements[i] = x } + sortedEnd._successorInPlace() } } } @@ -100,7 +102,7 @@ public func partition< >( inout elements: C, _ range: Range ${"," if p else ""} - ${"_ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"_ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) -> C.Index { fatalError("unavailable function can't be called") } @@ -111,7 +113,7 @@ func _partition< >( inout elements: C, _ range: Range ${"," if p else ""} - ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) -> C.Index { var lo = range.startIndex var hi = range.endIndex @@ -130,15 +132,19 @@ func _partition< Loop: while true { FindLo: repeat { - while ++lo != hi { + lo._successorInPlace() + while lo != hi { if !${cmp("elements[lo]", "pivot", p)} { break FindLo } + lo._successorInPlace() } break Loop } while false FindHi: repeat { - while --hi != lo { + hi._predecessorInPlace() + while hi != lo { if ${cmp("elements[hi]", "pivot", p)} { break FindHi } + hi._predecessorInPlace() } break Loop } while false @@ -146,7 +152,7 @@ Loop: while true { swap(&elements[lo], &elements[hi]) } - --lo + lo._predecessorInPlace() if lo != range.startIndex { // swap the pivot into place swap(&elements[lo], &elements[range.startIndex]) @@ -162,7 +168,7 @@ func _introSort< >( inout elements: C, _ range: Range ${"," if p else ""} - ${"_ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"_ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) { % if p: var comp = isOrderedBefore @@ -183,7 +189,7 @@ func _introSortImpl< >( inout elements: C, _ range: Range ${"," if p else ""} - ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""}, + ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""}, _ depthLimit: Int ) { @@ -215,7 +221,7 @@ func _siftDown< inout elements: C, _ index: C.Index, _ range: Range ${"," if p else ""} - ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) { let countToIndex = (range.startIndex..( inout elements: C, _ range: Range ${"," if p else ""} - ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) { // Here we build a heap starting from the lowest nodes and moving to the root. // On every step we sift down the current node to obey the max-heap property: @@ -259,7 +265,8 @@ func _heapify< // any children. let root = range.startIndex var node = root.advancedBy(C.Index.Distance(range.count.toIntMax()/2)) - while node-- != root { + while node != root { + node._predecessorInPlace() _siftDown(&elements, node, range ${", &isOrderedBefore" if p else ""}) } } @@ -269,14 +276,16 @@ func _heapSort< >( inout elements: C, _ range: Range ${"," if p else ""} - ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"inout _ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) { var hi = range.endIndex let lo = range.startIndex _heapify(&elements, range ${", &isOrderedBefore" if p else ""}) - while --hi != lo { + hi._predecessorInPlace() + while hi != lo { swap(&elements[lo], &elements[hi]) _siftDown(&elements, lo, lo..( inout collection: C ${"," if p else ""} - ${"_ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"_ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) { fatalError("unavailable function can't be called") } @@ -351,7 +360,7 @@ public func sorted< C: SequenceType${"" if p else " where C.Generator.Element : Comparable"} >( source: C ${"," if p else ""} - ${"_ isOrderedBefore: (C.Generator.Element, C.Generator.Element)->Bool" if p else ""} + ${"_ isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool" if p else ""} ) -> [C.Generator.Element] { fatalError("unavailable function can't be called") } @@ -359,6 +368,8 @@ public func sorted< // for p in preds /// Exchange the values of `a` and `b`. +/// +/// - Requires: `a` and `b` do not alias each other. public func swap(inout a : T, inout _ b : T) { // Semantically equivalent to (a, b) = (b, a). // Microoptimized to avoid retain/release traffic. diff --git a/stdlib/public/core/StaticString.swift b/stdlib/public/core/StaticString.swift index cd24966e22a34..fa44e00a332ca 100644 --- a/stdlib/public/core/StaticString.swift +++ b/stdlib/public/core/StaticString.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,7 +17,7 @@ // are involved in its construction. This feature is crucial for // preventing infinite recursion even in non-asserting cases. -/// An simple string designed to represent text that is "knowable at +/// A simple string designed to represent text that is "knowable at /// compile-time". /// /// Logically speaking, each instance looks something like this: @@ -119,7 +119,7 @@ public struct StaticString var i = 0 let sink: (UInt8) -> Void = { buffer = buffer | (UInt64($0) << (UInt64(i) * 8)) - ++i + i += 1 } UTF8.encode(unicodeScalar, output: sink) return body(UnsafeBufferPointer( diff --git a/stdlib/public/core/Stride.swift b/stdlib/public/core/Stride.swift index 10c855c676000..22b8b1236ff28 100644 --- a/stdlib/public/core/Stride.swift +++ b/stdlib/public/core/Stride.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -50,30 +50,30 @@ public func == (x: T, y: T) -> Bool { } @warn_unused_result -public func + (lhs: T, rhs: T.Stride) -> T { +public func + (lhs: T, rhs: T.Stride) -> T { return lhs.advancedBy(rhs) } @warn_unused_result -public func + (lhs: T.Stride, rhs: T) -> T { +public func + (lhs: T.Stride, rhs: T) -> T { return rhs.advancedBy(lhs) } @warn_unused_result -public func - (lhs: T, rhs: T.Stride) -> T { +public func - (lhs: T, rhs: T.Stride) -> T { return lhs.advancedBy(-rhs) } @warn_unused_result -public func - (lhs: T, rhs: T) -> T.Stride { +public func - (lhs: T, rhs: T) -> T.Stride { return rhs.distanceTo(lhs) } -public func += (inout lhs: T, rhs: T.Stride) { +public func += (inout lhs: T, rhs: T.Stride) { lhs = lhs.advancedBy(rhs) } -public func -= (inout lhs: T, rhs: T.Stride) { +public func -= (inout lhs: T, rhs: T.Stride) { lhs = lhs.advancedBy(-rhs) } @@ -82,37 +82,37 @@ public func -= (inout lhs: T, rhs: T.Stride) { // overloads, expressions such as UInt(2) + Int(3) would compile. // //===----------------------------------------------------------------------===// -public func + ( +public func + ( lhs: T, rhs: T._DisallowMixedSignArithmetic ) -> T { _sanityCheckFailure("Should not be callable.") } -public func + ( +public func + ( lhs: T._DisallowMixedSignArithmetic, rhs: T ) -> T { _sanityCheckFailure("Should not be callable.") } -public func - ( +public func - ( lhs: T, rhs: T._DisallowMixedSignArithmetic ) -> T { _sanityCheckFailure("Should not be callable.") } -public func - ( +public func - ( lhs: T, rhs: T ) -> T._DisallowMixedSignArithmetic { _sanityCheckFailure("Should not be callable.") } -public func += ( +public func += ( inout lhs: T, rhs: T._DisallowMixedSignArithmetic ) { _sanityCheckFailure("Should not be callable.") } -public func -= ( +public func -= ( inout lhs: T, rhs: T._DisallowMixedSignArithmetic ) { _sanityCheckFailure("Should not be callable.") @@ -120,7 +120,7 @@ public func -= ( //===----------------------------------------------------------------------===// -/// A GeneratorType for `StrideTo`. +/// A `GeneratorType` for `StrideTo`. public struct StrideToGenerator : GeneratorType { @available(*, unavailable, renamed="Element") public typealias T = Element @@ -135,9 +135,9 @@ public struct StrideToGenerator : GeneratorType { if stride > 0 ? current >= end : current <= end { return nil } - let ret = current + let result = current current += stride - return ret + return result } } @@ -186,7 +186,7 @@ public func stride< fatalError("unavailable function can't be called") } -/// A GeneratorType for `StrideThrough`. +/// A `GeneratorType` for `StrideThrough`. public struct StrideThroughGenerator : GeneratorType { @available(*, unavailable, renamed="Element") public typealias T = Element @@ -209,9 +209,9 @@ public struct StrideThroughGenerator : GeneratorType { } return nil } - let ret = current + let result = current current += stride - return ret + return result } } @@ -243,7 +243,7 @@ public struct StrideThrough : SequenceType { } extension Strideable { - /// Return the sequence of values (`start`, `start + stride`, `start + + /// Return the sequence of values (`self`, `self + stride`, `self + /// stride + stride`, ... *last*) where *last* is the last value in /// the progression less than or equal to `end`. /// diff --git a/stdlib/public/core/StrideMirrors.swift.gyb b/stdlib/public/core/StrideMirrors.swift.gyb index 40e581b0d274f..f93ff916a1862 100644 --- a/stdlib/public/core/StrideMirrors.swift.gyb +++ b/stdlib/public/core/StrideMirrors.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/String.swift b/stdlib/public/core/String.swift index 8169af68829cd..b1cd66211de02 100644 --- a/stdlib/public/core/String.swift +++ b/stdlib/public/core/String.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -102,7 +102,7 @@ import SwiftShims /// any sequence of mutating operations causes elements to be copied /// into unique, contiguous storage which may cost `O(N)` time and /// space, where `N` is the length of the string representation (or -/// more, if the underlying `NSString` is has unusual performance +/// more, if the underlying `NSString` has unusual performance /// characteristics). public struct String { /// An empty `String`. @@ -145,7 +145,7 @@ extension String { if let stringBuffer = stringBufferOptional { return String(_storage: stringBuffer) } else { - return .None + return nil } } @@ -208,7 +208,7 @@ extension String : _BuiltinUTF16StringLiteralConvertible { public init( _builtinUTF16StringLiteral start: Builtin.RawPointer, numberOfCodeUnits: Builtin.Word - ) { + ) { self = String( _StringCore( baseAddress: COpaquePointer(start), @@ -272,7 +272,7 @@ extension String { Encoding: UnicodeCodecType >(encoding: Encoding.Type) -> Int { var codeUnitCount = 0 - let output: (Encoding.CodeUnit) -> Void = { _ in ++codeUnitCount } + let output: (Encoding.CodeUnit) -> Void = { _ in codeUnitCount += 1 } self._encode(encoding, output: output) return codeUnitCount } @@ -310,7 +310,7 @@ extension String { @_silgen_name("swift_stdlib_compareNSStringDeterministicUnicodeCollation") public func _stdlib_compareNSStringDeterministicUnicodeCollation( lhs: AnyObject, _ rhs: AnyObject -)-> Int32 +) -> Int32 #endif extension String : Equatable { @@ -355,7 +355,7 @@ extension String { compare = self._core.count - rhs._core.count } // This efficiently normalizes the result to -1, 0, or 1 to match the - // behaviour of NSString's compare function. + // behavior of NSString's compare function. return (compare > 0 ? 1 : 0) - (compare < 0 ? 1 : 0) } #endif diff --git a/stdlib/public/core/StringBridge.swift b/stdlib/public/core/StringBridge.swift index fdbb5d03dbecd..70fc3196601ee 100644 --- a/stdlib/public/core/StringBridge.swift +++ b/stdlib/public/core/StringBridge.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/StringBuffer.swift b/stdlib/public/core/StringBuffer.swift index 2069229a4d163..b0285a6395c74 100644 --- a/stdlib/public/core/StringBuffer.swift +++ b/stdlib/public/core/StringBuffer.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -94,7 +94,7 @@ public struct _StringBuffer { let inputStream = input.generate() guard let (utf16Count, isAscii) = UTF16.measure(encoding, input: inputStream, repairIllFormedSequences: repairIllFormedSequences) else { - return (.None, true) + return (nil, true) } // Allocate storage @@ -106,18 +106,20 @@ public struct _StringBuffer { if isAscii { var p = UnsafeMutablePointer(result.start) let sink: (UTF32.CodeUnit) -> Void = { - (p++).memory = UTF8.CodeUnit($0) + p.memory = UTF8.CodeUnit($0) + p += 1 } let hadError = transcode( encoding, UTF32.self, input.generate(), sink, stopOnError: true) - _sanityCheck(!hadError, "string can not be ASCII if there were decoding errors") + _sanityCheck(!hadError, "string cannot be ASCII if there were decoding errors") return (result, hadError) } else { var p = result._storage.baseAddress let sink: (UTF16.CodeUnit) -> Void = { - (p++).memory = $0 + p.memory = $0 + p += 1 } let hadError = transcode( encoding, UTF16.self, input.generate(), sink, @@ -184,7 +186,7 @@ public struct _StringBuffer { /// Attempt to claim unused capacity in the buffer. /// /// Operation succeeds if there is sufficient capacity, and either: - /// - the buffer is uniquely-refereced, or + /// - the buffer is uniquely-referenced, or /// - `oldUsedEnd` points to the end of the currently used capacity. /// /// - parameter subRange: Range of the substring that the caller tries @@ -231,7 +233,7 @@ public struct _StringBuffer { } var _anyObject: AnyObject? { - return _storage.storage != nil ? .Some(_storage.storage!) : .None + return _storage.storage != nil ? _storage.storage! : nil } var _storage: _Storage diff --git a/stdlib/public/core/StringCharacterView.swift b/stdlib/public/core/StringCharacterView.swift index 519b14155515f..20373b64a0b61 100644 --- a/stdlib/public/core/StringCharacterView.swift +++ b/stdlib/public/core/StringCharacterView.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -46,7 +46,7 @@ extension String { /// that is the target of this method) during the execution of /// `body`: it may not appear to have its correct value. Instead, /// use only the `String.CharacterView` argument to `body`. - public mutating func withMutableCharacters(body: (inout CharacterView)->R) -> R { + public mutating func withMutableCharacters(body: (inout CharacterView) -> R) -> R { // Naively mutating self.characters forces multiple references to // exist at the point of mutation. Instead, temporarily move the // core of this string into a CharacterView. @@ -88,7 +88,7 @@ extension String.CharacterView : CollectionType { /// /// - Requires: The next value is representable. public func successor() -> Index { - _precondition(_base != _base._viewEndIndex, "can not increment endIndex") + _precondition(_base != _base._viewEndIndex, "cannot increment endIndex") return Index(_base: _endBase) } @@ -97,7 +97,7 @@ extension String.CharacterView : CollectionType { /// - Requires: The previous value is representable. public func predecessor() -> Index { _precondition(_base != _base._viewStartIndex, - "can not decrement startIndex") + "cannot decrement startIndex") let predecessorLengthUTF16 = Index._measureExtendedGraphemeClusterBackward(_base) return Index( @@ -143,9 +143,9 @@ extension String.CharacterView : CollectionType { var gcb0 = graphemeClusterBreakProperty.getPropertyRawValue( unicodeScalars[start].value) - ++start + start._successorInPlace() - for ; start != end; ++start { + for ; start != end; start._successorInPlace() { // FIXME(performance): consider removing this "fast path". A branch // that is hard to predict could be worse for performance than a few // loads from cache to fetch the property 'gcb1'. @@ -182,14 +182,14 @@ extension String.CharacterView : CollectionType { var graphemeClusterStart = end - --graphemeClusterStart + graphemeClusterStart._predecessorInPlace() var gcb0 = graphemeClusterBreakProperty.getPropertyRawValue( unicodeScalars[graphemeClusterStart].value) var graphemeClusterStartUTF16 = graphemeClusterStart._position while graphemeClusterStart != start { - --graphemeClusterStart + graphemeClusterStart._predecessorInPlace() let gcb1 = graphemeClusterBreakProperty.getPropertyRawValue( unicodeScalars[graphemeClusterStart].value) if segmenter.isBoundary(gcb1, gcb0) { @@ -242,7 +242,7 @@ extension String.CharacterView : CollectionType { var valueType: Any.Type { return (_value as Any).dynamicType } - var objectIdentifier: ObjectIdentifier? { return .None } + var objectIdentifier: ObjectIdentifier? { return nil } var disposition: _MirrorDisposition { return .Aggregate } @@ -255,7 +255,7 @@ extension String.CharacterView : CollectionType { var summary: String { return "\(_value._utf16Index)" } var quickLookObject: PlaygroundQuickLook? { - return .Some(.Int(Int64(_value._utf16Index))) + return .Int(Int64(_value._utf16Index)) } } } diff --git a/stdlib/public/core/StringCore.swift b/stdlib/public/core/StringCore.swift index 3e81acb21cee8..a7f473e51a1bc 100644 --- a/stdlib/public/core/StringCore.swift +++ b/stdlib/public/core/StringCore.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -121,7 +121,9 @@ public struct _StringCore { var src = UnsafeMutablePointer(srcStart) let srcEnd = src + count while (src != srcEnd) { - dest++.memory = UTF16.CodeUnit(src++.memory) + dest.memory = UTF16.CodeUnit(src.memory) + dest += 1 + src += 1 } } else { @@ -130,7 +132,9 @@ public struct _StringCore { var src = UnsafeMutablePointer(srcStart) let srcEnd = src + count while (src != srcEnd) { - dest++.memory = UTF8.CodeUnit(src++.memory) + dest.memory = UTF8.CodeUnit(src.memory) + dest += 1 + src += 1 } } } @@ -174,7 +178,7 @@ public struct _StringCore { public init() { self._baseAddress = _emptyStringBase self._countAndFlags = 0 - self._owner = .None + self._owner = nil _invariantCheck() } @@ -237,7 +241,7 @@ public struct _StringCore { return UnsafeMutablePointer(_baseAddress) } - /// the native _StringBuffer, if any, or .None. + /// the native _StringBuffer, if any, or `nil`. public var nativeBuffer: _StringBuffer? { if !hasCocoaBuffer { return _owner.map { @@ -248,7 +252,7 @@ public struct _StringCore { } #if _runtime(_ObjC) - /// the Cocoa String buffer, if any, or .None. + /// the Cocoa String buffer, if any, or `nil`. public var cocoaBuffer: _CocoaStringType? { if hasCocoaBuffer { return _owner.map { @@ -618,13 +622,15 @@ extension _StringCore : RangeReplaceableCollectionType { if _fastPath(elementWidth == 1) { var dst = rangeStart for u in newElements { - dst++.memory = UInt8(u & 0xFF) + dst.memory = UInt8(u & 0xFF) + dst += 1 } } else { var dst = UnsafeMutablePointer(rangeStart) for u in newElements { - dst++.memory = u + dst.memory = u + dst += 1 } } diff --git a/stdlib/public/core/StringInterpolation.swift.gyb b/stdlib/public/core/StringInterpolation.swift.gyb index 720fc2fea67ae..d9011c67f047a 100644 --- a/stdlib/public/core/StringInterpolation.swift.gyb +++ b/stdlib/public/core/StringInterpolation.swift.gyb @@ -1,8 +1,8 @@ -//===--- StringInterpolation.swift.gyb - String Interpolation --*- swift -*-==// +//===--- StringInterpolation.swift.gyb - String Interpolation -*- swift -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/StringLegacy.swift b/stdlib/public/core/StringLegacy.swift index 6d70c600fd497..3fc5b06ea46a2 100644 --- a/stdlib/public/core/StringLegacy.swift +++ b/stdlib/public/core/StringLegacy.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -111,7 +111,7 @@ extension String { } /// Create an instance representing `v` in base 10. - public init(_ v: T) { + public init(_ v: T) { self = _uint64ToString(v.toUIntMax()) } @@ -133,7 +133,7 @@ extension String { /// starting with `a` if `uppercase` is `false` or `A` otherwise. public init( _ v: T, radix: Int, uppercase: Bool = false - ) { + ) { _precondition(radix > 1, "Radix must be greater than 1") self = _uint64ToString( v.toUIntMax(), radix: Int64(radix), uppercase: uppercase) @@ -158,7 +158,7 @@ extension String { let rng = unicodeScalars var startIndex = rng.startIndex for _ in 0.. UTF8.CodeUnit { let result: UTF8.CodeUnit = numericCast(position._buffer & 0xFF) - _precondition(result != 0xFF, "can not subscript using endIndex") + _precondition(result != 0xFF, "cannot subscript using endIndex") return result } diff --git a/stdlib/public/core/StringUTFViewsMirrors.swift.gyb b/stdlib/public/core/StringUTFViewsMirrors.swift.gyb index 91118d6214cfc..b1aaf2ba67bac 100644 --- a/stdlib/public/core/StringUTFViewsMirrors.swift.gyb +++ b/stdlib/public/core/StringUTFViewsMirrors.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -34,6 +34,6 @@ extension String { var summary: String { return _value.description } - var quickLookObject: PlaygroundQuickLook? { return .Some(.Text(summary)) } + var quickLookObject: PlaygroundQuickLook? { return .Text(summary) } } } diff --git a/stdlib/public/core/StringUnicodeScalarView.swift b/stdlib/public/core/StringUnicodeScalarView.swift index 5828c320eba4d..73deb5638225a 100644 --- a/stdlib/public/core/StringUnicodeScalarView.swift +++ b/stdlib/public/core/StringUnicodeScalarView.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -44,9 +44,10 @@ extension String { } mutating func next() -> UTF16.CodeUnit? { if idx == core.endIndex { - return .None + return nil } - return self.core[idx++] + defer { idx += 1 } + return self.core[idx] } } @@ -73,11 +74,11 @@ extension String { /// - Requires: The previous value is representable. @warn_unused_result public func predecessor() -> Index { - var i = _position - let codeUnit = _core[--i] + var i = _position-1 + let codeUnit = _core[i] if _slowPath((codeUnit >> 10) == 0b1101_11) { if i != 0 && (_core[i - 1] >> 10) == 0b1101_10 { - --i + i -= 1 } } return Index(i, _core) @@ -123,7 +124,7 @@ extension String { case .Result(let us): return us case .EmptyInput: - _sanityCheckFailure("can not subscript using an endIndex") + _sanityCheckFailure("cannot subscript using an endIndex") case .Error: return UnicodeScalar(0xfffd) } @@ -175,7 +176,7 @@ extension String { switch self._asciiBase.next() { case let x?: result = .Result(UnicodeScalar(x)) - case .None: + case nil: result = .EmptyInput } } else { @@ -188,7 +189,7 @@ extension String { case .Result(let us): return us case .EmptyInput: - return .None + return nil case .Error: return UnicodeScalar(0xfffd) } diff --git a/stdlib/public/core/SwiftNativeNSArray.swift b/stdlib/public/core/SwiftNativeNSArray.swift index ef57f1ed3072c..c36203e8d37da 100644 --- a/stdlib/public/core/SwiftNativeNSArray.swift +++ b/stdlib/public/core/SwiftNativeNSArray.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -38,7 +38,7 @@ internal func _isValidArraySubscript(index: Int, _ count: Int) -> Bool { /// An `NSArray` with Swift-native reference counting and contiguous /// storage. class _SwiftNativeNSArrayWithContiguousStorage - : _SwiftNativeNSArray { // provides NSArray inheritance and native refcounting + : _SwiftNativeNSArray { // Provides NSArray inheritance and native refcounting // Operate on our contiguous storage internal func withUnsafeBufferOfObjects( @@ -194,7 +194,7 @@ extension _SwiftNativeNSArrayWithContiguousStorage: _NSArrayCoreType { let storage: HeapBufferStorage = unsafeDowncast(objects.storage!) _destroyBridgedStorage(storage) } - continue // try again + continue // Try again } defer { _fixLifetime(self) } diff --git a/stdlib/public/core/Tuple.swift.gyb b/stdlib/public/core/Tuple.swift.gyb new file mode 100644 index 0000000000000..3b9424fe11219 --- /dev/null +++ b/stdlib/public/core/Tuple.swift.gyb @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +// Generate comparison functions for tuples up to some reasonable arity. + +% for arity in range(2,7): +% typeParams = [chr(ord("A")+i) for i in range(arity)] +% tupleT = "({})".format(",".join(typeParams)) + +% equatableTypeParams = ", ".join(["{} : Equatable".format(c) for c in typeParams]) + +/// Returns `true` iff each component of `lhs` is equal to the corresponding +/// component of `rhs`. +@warn_unused_result +public func == <${equatableTypeParams}>(lhs: ${tupleT}, rhs: ${tupleT}) -> Bool { + guard lhs.0 == rhs.0 else { return false } + /*tail*/ return ( + ${", ".join("lhs.{}".format(i) for i in range(1, arity))} + ) == ( + ${", ".join("rhs.{}".format(i) for i in range(1, arity))} + ) +} + +/// Returns `true` iff any component of `lhs` is not equal to the corresponding +/// component of `rhs`. +@warn_unused_result +public func != <${equatableTypeParams}>(lhs: ${tupleT}, rhs: ${tupleT}) -> Bool { + guard lhs.0 == rhs.0 else { return true } + /*tail*/ return ( + ${", ".join("lhs.{}".format(i) for i in range(1, arity))} + ) != ( + ${", ".join("rhs.{}".format(i) for i in range(1, arity))} + ) +} + +% comparableTypeParams = ", ".join(["{} : Comparable".format(c) for c in typeParams]) +% for op in ["<", ">"]: +% for opeq in ["", "="]: +/// A [lexicographical order](https://en.wikipedia.org/wiki/Lexicographical_order) +/// over tuples of `Comparable` elements. +/// +/// Given two tuples `(a1, a2, ..., aN)` and `(b1, b2, ..., bN)`, the +/// first tuple is `${op}${opeq}` the second tuple iff `a1 ${op} b1` or +/// (`a1 == b1` and `(a2, ..., aN) ${op}${opeq} (b2, ..., bN)`). +@warn_unused_result +public func ${op}${opeq} <${comparableTypeParams}>(lhs: ${tupleT}, rhs: ${tupleT}) -> Bool { + if lhs.0 != rhs.0 { return lhs.0 ${op}${opeq} rhs.0 } + /*tail*/ return ( + ${", ".join("lhs.{}".format(i) for i in range(1, arity))} + ) ${op}${opeq} ( + ${", ".join("rhs.{}".format(i) for i in range(1, arity))} + ) +} +% end +% end +% end diff --git a/stdlib/public/core/UnavailableStringAPIs.swift.gyb b/stdlib/public/core/UnavailableStringAPIs.swift.gyb index c9f390fc793d7..20c3761f9a00e 100644 --- a/stdlib/public/core/UnavailableStringAPIs.swift.gyb +++ b/stdlib/public/core/UnavailableStringAPIs.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -18,7 +18,7 @@ stringSubscriptComment = """ /// different interpretations in different libraries and system /// components. The correct interpretation should be selected /// according to the use case and the APIs involved, so `String` - /// can not be subscripted with an integer. + /// cannot be subscripted with an integer. /// /// Swift provides several different ways to access the character /// data stored inside strings. @@ -38,8 +38,8 @@ stringSubscriptComment = """ /// Use this API when you are performing low-level manipulation /// of character data. /// - /// - `String.chracters` is a collection of extended grapheme - /// clusters, which are an approximation of user-precieved + /// - `String.characters` is a collection of extended grapheme + /// clusters, which are an approximation of user-perceived /// characters. /// /// Note that when processing strings that contain human-readable @@ -98,9 +98,9 @@ ${stringSubscriptComment} /// Unicode scalars in the string. Use this API when you are /// performing low-level manipulation of character data. /// - /// - `String.chracters.count` property returns the number of + /// - `String.characters.count` property returns the number of /// extended grapheme clusters. Use this API to count the - /// number of user-precieved characters in the string. + /// number of user-perceived characters in the string. @available( *, unavailable, message="there is no universally good answer, see the documentation comment for discussion") diff --git a/stdlib/public/core/Unicode.swift b/stdlib/public/core/Unicode.swift index 33ff759908ac6..bacff2522ea34 100644 --- a/stdlib/public/core/Unicode.swift +++ b/stdlib/public/core/Unicode.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -79,7 +79,7 @@ public struct UTF8 : UnicodeCodecType { public init() {} /// Returns the number of expected trailing bytes for a given first byte: 0, - /// 1, 2 or 3. If the first byte can not start a valid UTF-8 code unit + /// 1, 2 or 3. If the first byte cannot start a valid UTF-8 code unit /// sequence, returns 4. @warn_unused_result public static func _numTrailingBytes(cu0: CodeUnit) -> UInt8 { @@ -749,7 +749,7 @@ internal func _transcodeSomeUTF16AsUTF8< if _fastPath(u <= 0x7f) { result |= UTF8Chunk(u) << shift - ++utf8Count + utf8Count += 1 } else { var scalarUtf8Length: Int var r: UInt @@ -947,7 +947,7 @@ extension UTF16 { break loop case .Error: if !repairIllFormedSequences { - return .None + return nil } isAscii = false count += width(UnicodeScalar(0xfffd)) diff --git a/stdlib/public/core/UnicodeScalar.swift b/stdlib/public/core/UnicodeScalar.swift index 4057da78e66ad..3a46ec3efd32c 100644 --- a/stdlib/public/core/UnicodeScalar.swift +++ b/stdlib/public/core/UnicodeScalar.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -20,11 +20,7 @@ public struct UnicodeScalar : var _value: UInt32 /// A numeric representation of `self`. - public var value: UInt32 { - get { - return _value - } - } + public var value: UInt32 { return _value } @_transparent public init(_builtinUnicodeScalarLiteral value: Builtin.Int32) { @@ -159,7 +155,7 @@ public struct UnicodeScalar : return (self >= "A" && self <= "Z") || (self >= "a" && self <= "z") } - // FIXME: Is there an similar term of art in Unicode? + // FIXME: Is there a similar term of art in Unicode? @warn_unused_result public func _isASCIIDigit() -> Bool { return self >= "0" && self <= "9" diff --git a/stdlib/public/core/UnicodeTrie.swift.gyb b/stdlib/public/core/UnicodeTrie.swift.gyb index 0645d8152d5a4..1247009eecefd 100644 --- a/stdlib/public/core/UnicodeTrie.swift.gyb +++ b/stdlib/public/core/UnicodeTrie.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // -// A custom trie implementation to quickly retrive Unicode property values. +// A custom trie implementation to quickly retrieve Unicode property values. // //===----------------------------------------------------------------------===// @@ -45,7 +45,7 @@ SuppDataBytesOffset = 12817 import SwiftShims public // @testable -enum _GraphemeClusterBreakPropertyValue : Int, CustomStringConvertible { +enum _GraphemeClusterBreakPropertyValue : Int { case Other = 0 case CR = 1 case LF = 2 @@ -59,39 +59,6 @@ enum _GraphemeClusterBreakPropertyValue : Int, CustomStringConvertible { case T = 10 case LV = 11 case LVT = 12 - - /// A textual representation of `self`. - public // @testable - var description: String { - switch self { - case Other: - return "Other" - case CR: - return "CR" - case LF: - return "LF" - case Control: - return "Control" - case Extend: - return "Extend" - case Regional_Indicator: - return "Regional_Indicator" - case Prepend: - return "Prepend" - case SpacingMark: - return "SpacingMark" - case L: - return "L" - case V: - return "V" - case T: - return "T" - case LV: - return "LV" - case LVT: - return "LVT" - } - } } // It is expensive to convert a raw enum value to an enum, so we use this type diff --git a/stdlib/public/core/Unmanaged.swift b/stdlib/public/core/Unmanaged.swift index d055d558c19dc..086b2b52b735c 100644 --- a/stdlib/public/core/Unmanaged.swift +++ b/stdlib/public/core/Unmanaged.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/core/UnsafeBufferPointer.swift.gyb b/stdlib/public/core/UnsafeBufferPointer.swift.gyb index 3be9f5f76c001..12e3b4f388b7b 100644 --- a/stdlib/public/core/UnsafeBufferPointer.swift.gyb +++ b/stdlib/public/core/UnsafeBufferPointer.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,7 +21,11 @@ public struct UnsafeBufferPointerGenerator /// Advance to the next element and return it, or `nil` if no next /// element exists. public mutating func next() -> Element? { - return position == end ? nil : (position++).memory + if position == end { return nil } + + let result = position.memory + position += 1 + return result } var position, end: UnsafePointer diff --git a/stdlib/public/core/UnsafePointer.swift.gyb b/stdlib/public/core/UnsafePointer.swift.gyb index 3435d3de738da..ee73982481072 100644 --- a/stdlib/public/core/UnsafePointer.swift.gyb +++ b/stdlib/public/core/UnsafePointer.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -164,7 +164,7 @@ ${comment} /// /// - Precondition: The memory is not initialized. /// - /// - Postcondition: The memory is initalized; the value should eventually + /// - Postcondition: The memory is initialized; the value should eventually /// be destroyed or moved from to avoid leaks. public func initialize(newvalue: Memory) { Builtin.initialize(newvalue, _rawValue) @@ -210,8 +210,10 @@ ${comment} _debugPrecondition( source < self || source >= self + count, "${Self}.assignBackwardFrom non-preceding overlapping range; use assignFrom instead") - for var i = count; --i >= 0; { + var i = count-1 + while i >= 0 { self[i] = source[i] + i -= 1 } } @@ -357,7 +359,7 @@ ${comment} #if _runtime(_ObjC) /// Return the result of invoking body. If self was converted from - /// nil, passes nil as the argument. Otherwise, passes the address + /// `nil`, passes `nil` as the argument. Otherwise, passes the address /// of a `Memory` which is written into buffer before this method returns. @_transparent public func _withBridgeObject( @@ -444,7 +446,7 @@ ${MirrorDecl} { return "\(selfType)(0x\(_uint64ToString(ptrValue, radix:16, uppercase:true)))" } - var quickLookObject: PlaygroundQuickLook? { return .Some(.Text(summary)) } + var quickLookObject: PlaygroundQuickLook? { return .Text(summary) } } ${MirrorConformance} diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift index 7ddf1472b7d7f..ce4ee0e916fb3 100644 --- a/stdlib/public/core/VarArgs.swift +++ b/stdlib/public/core/VarArgs.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,11 +10,6 @@ // //===----------------------------------------------------------------------===// -#if _runtime(_ObjC) -// Excluded due to use of dynamic casting and Builtin.autorelease, neither -// of which correctly work without the ObjC Runtime right now. -// See rdar://problem/18801510 - /// Instances of conforming types can be encoded, and appropriately /// passed, as elements of a C `va_list`. /// @@ -82,6 +77,11 @@ public func withVaList(builder: VaListBuilder, return result } +#if _runtime(_ObjC) +// Excluded due to use of dynamic casting and Builtin.autorelease, neither +// of which correctly work without the ObjC Runtime right now. +// See rdar://problem/18801510 + /// Returns a `CVaListPointer` built from `args` that's backed by /// autoreleased storage. /// @@ -100,6 +100,7 @@ public func getVaList(args: [CVarArgType]) -> CVaListPointer { Builtin.autorelease(builder) return builder.va_list() } +#endif @warn_unused_result public func _encodeBitsAsWords(x: T) -> [Int] { @@ -237,6 +238,7 @@ extension UnsafeMutablePointer : CVarArgType { } } +#if _runtime(_ObjC) extension AutoreleasingUnsafeMutablePointer : CVarArgType { /// Transform `self` into a series of machine words that can be /// appropriately interpreted by C varargs. @@ -244,6 +246,7 @@ extension AutoreleasingUnsafeMutablePointer : CVarArgType { return _encodeBitsAsWords(self) } } +#endif extension Float : _CVarArgPassedAsDouble, _CVarArgAlignedType { /// Transform `self` into a series of machine words that can be @@ -330,7 +333,8 @@ final public class VaListBuilder { } for word in words { - storage[count++] = word + storage[count] = word + count += 1 } } @@ -395,12 +399,13 @@ final public class VaListBuilder { + (sseRegistersUsed * _x86_64SSERegisterWords) for w in encoded { storage[startIndex] = w - ++startIndex + startIndex += 1 } - ++sseRegistersUsed + sseRegistersUsed += 1 } else if encoded.count == 1 && gpRegistersUsed < _x86_64CountGPRegisters { - storage[gpRegistersUsed++] = encoded[0] + storage[gpRegistersUsed] = encoded[0] + gpRegistersUsed += 1 } else { for w in encoded { @@ -429,4 +434,3 @@ final public class VaListBuilder { #endif -#endif // _runtime(_ObjC) diff --git a/stdlib/public/core/Zip.swift b/stdlib/public/core/Zip.swift index 1eccb37149d6b..ca0a6961a9144 100644 --- a/stdlib/public/core/Zip.swift +++ b/stdlib/public/core/Zip.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,7 +28,7 @@ public struct Zip2Generator< /// Construct around a pair of underlying generators. public init(_ generator1: Generator1, _ generator2: Generator2) { - _baseStreams = (generator1, generator2) + (_baseStream1, _baseStream2) = (generator1, generator2) } /// Advance to the next element and return it, or `nil` if no next @@ -38,30 +38,26 @@ public struct Zip2Generator< /// since the copy was made, and no preceding call to `self.next()` /// has returned `nil`. public mutating func next() -> Element? { - // The next() function needs to track if it has reached the end. If we - // didn't, and the first sequence is shorter than the second, then, when we + // The next() function needs to track if it has reached the end. If we + // didn't, and the first sequence is longer than the second, then when we // have already exhausted the second sequence, on every subsequent call to // next() we would consume and discard one additional element from the - // first sequence, even though next() return nil. + // first sequence, even though next() had already returned nil. if _reachedEnd { return nil } - guard let e0 = _baseStreams.0.next() else { + guard let element1 = _baseStream1.next(), element2 = _baseStream2.next() else { _reachedEnd = true return nil } - guard let e1 = _baseStreams.1.next() else { - _reachedEnd = true - return nil - } - - return .Some((e0, e1)) + return (element1, element2) } - internal var _baseStreams: (Generator1, Generator2) + internal var _baseStream1: Generator1 + internal var _baseStream2: Generator2 internal var _reachedEnd: Bool = false } @@ -81,7 +77,7 @@ public struct Zip2Sequence /// Construct an instance that makes pairs of elements from `sequence1` and /// `sequence2`. public init(_ sequence1: Sequence1, _ sequence2: Sequence2) { - _sequences = (sequence1, sequence2) + (_sequence1, _sequence2) = (sequence1, sequence2) } /// Return a *generator* over the elements of this *sequence*. @@ -89,11 +85,12 @@ public struct Zip2Sequence /// - Complexity: O(1). public func generate() -> Generator { return Generator( - _sequences.0.generate(), - _sequences.1.generate()) + _sequence1.generate(), + _sequence2.generate()) } - internal let _sequences: (Sequence1, Sequence2) + internal let _sequence1: Sequence1 + internal let _sequence2: Sequence2 } @available(*, unavailable, renamed="Zip2Generator") diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt index 3c9384be43b78..67407b1b12db8 100644 --- a/stdlib/public/runtime/CMakeLists.txt +++ b/stdlib/public/runtime/CMakeLists.txt @@ -17,36 +17,19 @@ if(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER) set(swift_runtime_leaks_sources Leaks.mm) endif() -set(swift_runtime_dtrace_sources) -if (SWIFT_RUNTIME_ENABLE_DTRACE) - set(swift_runtime_dtrace_sources SwiftRuntimeDTraceProbes.d) - list(APPEND swift_runtime_compile_flags - "-DSWIFT_RUNTIME_ENABLE_DTRACE=1") -endif() - # Acknowledge that the following sources are known. set(LLVM_OPTIONAL_SOURCES Remangle.cpp) set(swift_runtime_objc_sources) set(swift_runtime_unicode_normalization_sources) -set(swift_runtime_link_libraries) if(SWIFT_HOST_VARIANT MATCHES "${SWIFT_DARWIN_VARIANTS}") set(swift_runtime_objc_sources ErrorObject.mm SwiftObject.mm Remangle.cpp Reflection.mm) - set(LLVM_OPTIONAL_SOURCES - UnicodeNormalization.cpp) else() - find_package(ICU REQUIRED COMPONENTS uc i18n) - set(swift_runtime_unicode_normalization_sources - UnicodeNormalization.cpp) - set(swift_runtime_link_libraries - ${ICU_UC_LIBRARY} ${ICU_I18N_LIBRARY}) - include_directories( - ${ICU_UC_INCLUDE_DIR} ${ICU_I18N_INCLUDE_DIR}) endif() add_swift_library(swiftRuntime IS_STDLIB IS_STDLIB_CORE @@ -62,17 +45,13 @@ add_swift_library(swiftRuntime IS_STDLIB IS_STDLIB_CORE Once.cpp Reflection.cpp SwiftObject.cpp - UnicodeExtendedGraphemeClusters.cpp.gyb ${swift_runtime_objc_sources} - ${swift_runtime_dtrace_sources} ${swift_runtime_leaks_sources} - ${swift_runtime_unicode_normalization_sources} C_COMPILE_FLAGS ${swift_runtime_compile_flags} - LINK_LIBRARIES ${swift_runtime_link_libraries} INSTALL_IN_COMPONENT stdlib) foreach(sdk ${SWIFT_CONFIGURED_SDKS}) - if("${sdk}" STREQUAL "LINUX" OR "${sdk}" STREQUAL "ANDROID") + if("${sdk}" STREQUAL "LINUX" OR "${sdk}" STREQUAL "FREEBSD" OR "${sdk}" STREQUAL "ANDROID") foreach(arch ${SWIFT_SDK_${sdk}_ARCHITECTURES}) set(arch_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${arch}") diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp index bf64f4ec03825..3244ff13d9993 100644 --- a/stdlib/public/runtime/Casting.cpp +++ b/stdlib/public/runtime/Casting.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -247,6 +247,7 @@ static void _buildNameForMetadata(const Metadata *type, result); } case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Struct: { auto structType = static_cast(type); return _buildNominalTypeName(structType->Description, @@ -574,6 +575,7 @@ static bool _conformsToProtocol(const OpaqueValue *value, case MetadataKind::HeapGenericLocalVariable: case MetadataKind::ErrorObject: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -600,7 +602,7 @@ static bool _conformsToProtocol(const OpaqueValue *value, if (value) { return _unknownClassConformsToObjCProtocol(value, protocol); } else { - return _swift_classConformsToObjCProtocol(type, protocol); + return classConformsToObjCProtocol(type, protocol); } #endif return false; @@ -611,7 +613,7 @@ static bool _conformsToProtocol(const OpaqueValue *value, return _unknownClassConformsToObjCProtocol(value, protocol); } else { auto wrapper = cast(type); - return _swift_classConformsToObjCProtocol(wrapper->Class, protocol); + return classConformsToObjCProtocol(wrapper->Class, protocol); } #endif return false; @@ -634,6 +636,7 @@ static bool _conformsToProtocol(const OpaqueValue *value, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -736,6 +739,7 @@ static void findDynamicValueAndType(OpaqueValue *value, const Metadata *type, case MetadataKind::HeapGenericLocalVariable: case MetadataKind::ErrorObject: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -797,6 +801,7 @@ static void deallocateDynamicValue(OpaqueValue *value, const Metadata *type) { case MetadataKind::HeapGenericLocalVariable: case MetadataKind::ErrorObject: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -822,6 +827,7 @@ swift_dynamicCastMetatypeToObjectConditional(const Metadata *metatype) { // Other kinds of metadata don't cast to AnyObject. case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Tuple: case MetadataKind::Function: @@ -852,6 +858,7 @@ swift_dynamicCastMetatypeToObjectUnconditional(const Metadata *metatype) { // Other kinds of metadata don't cast to AnyObject. case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Tuple: case MetadataKind::Function: @@ -939,6 +946,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest, case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: #if SWIFT_OBJC_INTEROP // If the source type is bridged to Objective-C, try to bridge. if (auto srcBridgeWitness = findBridgeWitness(srcDynamicType)) { @@ -1050,7 +1058,7 @@ _dynamicCastUnknownClassToExistential(const void *object, if (protocol->Flags.getSpecialProtocol() == SpecialProtocol::AnyObject) break; - if (!_swift_objectConformsToObjCProtocol(object, protocol)) + if (!objectConformsToObjCProtocol(object, protocol)) return nullptr; break; #else @@ -1111,6 +1119,7 @@ swift::swift_dynamicCastUnknownClass(const void *object, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1166,6 +1175,7 @@ swift::swift_dynamicCastUnknownClassUnconditional(const void *object, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1225,6 +1235,7 @@ swift::swift_dynamicCastMetatype(const Metadata *sourceType, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1255,6 +1266,7 @@ swift::swift_dynamicCastMetatype(const Metadata *sourceType, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1270,6 +1282,7 @@ swift::swift_dynamicCastMetatype(const Metadata *sourceType, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1332,6 +1345,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1363,6 +1377,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1377,6 +1392,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType, case MetadataKind::ErrorObject: case MetadataKind::Metatype: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1388,6 +1404,7 @@ swift::swift_dynamicCastMetatypeUnconditional(const Metadata *sourceType, } } +#if SWIFT_OBJC_INTEROP /// Do a dynamic cast to the target class. static void *_dynamicCastUnknownClass(void *object, const Metadata *targetType, @@ -1400,6 +1417,7 @@ static void *_dynamicCastUnknownClass(void *object, return const_cast(swift_dynamicCastUnknownClass(object, targetType)); } +#endif static bool _dynamicCastUnknownClassIndirect(OpaqueValue *dest, void *object, @@ -1713,6 +1731,7 @@ static bool _dynamicCastToMetatype(OpaqueValue *dest, case MetadataKind::HeapGenericLocalVariable: case MetadataKind::ErrorObject: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1883,6 +1902,7 @@ static bool _dynamicCastToExistentialMetatype(OpaqueValue *dest, case MetadataKind::HeapGenericLocalVariable: case MetadataKind::ErrorObject: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Struct: case MetadataKind::Tuple: @@ -1945,6 +1965,7 @@ static bool _dynamicCastToFunction(OpaqueValue *dest, case MetadataKind::Class: case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::ObjCClassWrapper: case MetadataKind::ForeignClass: case MetadataKind::ExistentialMetatype: @@ -1969,13 +1990,59 @@ static id dynamicCastValueToNSError(OpaqueValue *src, } #endif +static bool canCastToExistential(OpaqueValue *dest, OpaqueValue *src, + const Metadata *srcType, + const Metadata *targetType) { + if (targetType->getKind() != MetadataKind::Existential) + return false; + + return _dynamicCastToExistential(dest, src, srcType, + cast(targetType), + DynamicCastFlags::Default); +} + /// Perform a dynamic cast to an arbitrary type. bool swift::swift_dynamicCast(OpaqueValue *dest, OpaqueValue *src, const Metadata *srcType, const Metadata *targetType, DynamicCastFlags flags) { + // Check if the cast source is Optional and the target is not an existential + // that Optional conforms to. Unwrap one level of Optional and continue. + if (srcType->getKind() == MetadataKind::Optional + && !canCastToExistential(dest, src, srcType, targetType)) { + const Metadata *payloadType = + cast(srcType)->getGenericArgs()[0]; + int enumCase = + swift_getEnumCaseSinglePayload(src, payloadType, 1 /*emptyCases=*/); + if (enumCase != -1) { + // Allow Optional.None -> Optional.None + if (targetType->getKind() != MetadataKind::Optional) + return _fail(src, srcType, targetType, flags); + // Inject the .None tag + swift_storeEnumTagSinglePayload(dest, payloadType, enumCase, + 1 /*emptyCases=*/); + return _succeed(dest, src, srcType, flags); + } + // .Some + // Single payload enums are guaranteed layout compatible with their + // payload. Only the source's payload needs to be taken or destroyed. + srcType = payloadType; + } + switch (targetType->getKind()) { + // Handle wrapping an Optional target. + case MetadataKind::Optional: { + // Recursively cast into the layout compatible payload area. + const Metadata *payloadType = + cast(targetType)->getGenericArgs()[0]; + if (swift_dynamicCast(dest, src, srcType, payloadType, flags)) { + swift_storeEnumTagSinglePayload(dest, payloadType, -1 /*case*/, + 1 /*emptyCases*/); + return true; + } + return false; + } // Casts to class type. case MetadataKind::Class: @@ -2018,6 +2085,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest, } case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Struct: { #if SWIFT_OBJC_INTEROP // If the source type is bridged to Objective-C, try to bridge. @@ -2090,6 +2158,7 @@ bool swift::swift_dynamicCast(OpaqueValue *dest, } case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Existential: case MetadataKind::ExistentialMetatype: case MetadataKind::Function: @@ -2231,10 +2300,6 @@ const { #define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".swift2_protocol_conformances_start" #endif -// std:once_flag token to install the dyld callback to enqueue images for -// protocol conformance lookup. -static std::once_flag InstallProtocolConformanceAddImageCallbackOnce; - namespace { struct ConformanceSection { const ProtocolConformanceRecord *Begin, *End; @@ -2271,7 +2336,7 @@ namespace { # if __APPLE__ assert((!Success && Data <= 0xFFFFFFFFU) || (Success && Data > 0xFFFFFFFFU)); -# elif __linux__ +# elif __linux__ || __FreeBSD__ assert((!Success && Data <= 0x0FFFU) || (Success && Data > 0x0FFFU)); # else @@ -2306,7 +2371,7 @@ namespace { #if __LP64__ # if __APPLE__ return Data > 0xFFFFFFFFU; -# elif __linux__ +# elif __linux__ || __FreeBSD__ return Data > 0x0FFFU; # else # error "port me" @@ -2332,6 +2397,8 @@ namespace { // Conformance Cache. +static void _initializeCallbacksToInspectDylib(); + struct ConformanceState { ConcurrentMap Cache; std::vector SectionsToScan; @@ -2340,24 +2407,18 @@ struct ConformanceState { ConformanceState() { SectionsToScan.reserve(16); pthread_mutex_init(&SectionsToScanLock, nullptr); + _initializeCallbacksToInspectDylib(); } }; static Lazy Conformances; -// This variable is used to signal when a cache was generated and -// it is correct to avoid a new scan. -static unsigned ConformanceCacheGeneration = 0; - -void -swift::swift_registerProtocolConformances(const ProtocolConformanceRecord *begin, - const ProtocolConformanceRecord *end){ - auto &C = Conformances.get(); - +static void +_registerProtocolConformances(ConformanceState &C, + const ProtocolConformanceRecord *begin, + const ProtocolConformanceRecord *end) { pthread_mutex_lock(&C.SectionsToScanLock); - C.SectionsToScan.push_back(ConformanceSection{begin, end}); - pthread_mutex_unlock(&C.SectionsToScanLock); } @@ -2372,7 +2433,10 @@ static void _addImageProtocolConformancesBlock(const uint8_t *conformances, auto recordsEnd = reinterpret_cast (conformances + conformancesSize); - swift_registerProtocolConformances(recordsBegin, recordsEnd); + + // Conformance cache should always be sufficiently initialized by this point. + _registerProtocolConformances(Conformances.unsafeGetAlreadyInitialized(), + recordsBegin, recordsEnd); } #if defined(__APPLE__) && defined(__MACH__) @@ -2486,29 +2550,35 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info, } #endif -static void installCallbacksToInspectDylib() { - static OnceToken_t token; - auto callback = [](void*) { - #if defined(__APPLE__) && defined(__MACH__) - // Install our dyld callback if we haven't already. - // Dyld will invoke this on our behalf for all images that have already - // been loaded. - _dyld_register_func_for_add_image(_addImageProtocolConformances); - #elif defined(__ANDROID__) - // Android only gained dl_iterate_phdr in API 21, so use /proc/self/maps - android_iterate_libs(_addImageProtocolConformances); - #elif defined(__ELF__) - // Search the loaded dls. Unlike the above, this only searches the already - // loaded ones. - // FIXME: Find a way to have this continue to happen after. - // rdar://problem/19045112 - dl_iterate_phdr(_addImageProtocolConformances, nullptr); - #else - # error No known mechanism to inspect dynamic libraries on this platform. - #endif - }; - - SWIFT_ONCE_F(token, callback, nullptr); +static void _initializeCallbacksToInspectDylib() { +#if defined(__APPLE__) && defined(__MACH__) + // Install our dyld callback. + // Dyld will invoke this on our behalf for all images that have already + // been loaded. + _dyld_register_func_for_add_image(_addImageProtocolConformances); +#elif defined(__ANDROID__) + // Android only gained dl_iterate_phdr in API 21, so use /proc/self/maps + android_iterate_libs(_addImageProtocolConformances); +#elif defined(__ELF__) + // Search the loaded dls. Unlike the above, this only searches the already + // loaded ones. + // FIXME: Find a way to have this continue to happen after. + // rdar://problem/19045112 + dl_iterate_phdr(_addImageProtocolConformances, nullptr); +#else +# error No known mechanism to inspect dynamic libraries on this platform. +#endif +} + +// This variable is used to signal when a cache was generated and +// it is correct to avoid a new scan. +static unsigned ConformanceCacheGeneration = 0; + +void +swift::swift_registerProtocolConformances(const ProtocolConformanceRecord *begin, + const ProtocolConformanceRecord *end){ + auto &C = Conformances.get(); + _registerProtocolConformances(C, begin, end); } static size_t hashTypeProtocolPair(const void *type, @@ -2578,11 +2648,9 @@ searchInConformanceCache(const Metadata *type, // If the type is a class, try its superclass. if (const ClassMetadata *classType = type->getClassObject()) { - if (auto super = classType->SuperClass) { - if (super != getRootSuperclass()) { - type = swift_getObjCClassMetadata(super); - goto recur_inside_cache_lock; - } + if (classHasSuperclass(classType)) { + type = swift_getObjCClassMetadata(classType->SuperClass); + goto recur_inside_cache_lock; } } @@ -2610,13 +2678,11 @@ bool isRelatedType(const Metadata *type, const void *candidate) { // If the type is a class, try its superclass. if (const ClassMetadata *classType = type->getClassObject()) { - if (auto super = classType->SuperClass) { - if (super != getRootSuperclass()) { - type = swift_getObjCClassMetadata(super); - if (type == candidate) - return true; - continue; - } + if (classHasSuperclass(classType)) { + type = swift_getObjCClassMetadata(classType->SuperClass); + if (type == candidate) + return true; + continue; } } @@ -2630,14 +2696,8 @@ const WitnessTable * swift::swift_conformsToProtocol(const Metadata *type, const ProtocolDescriptor *protocol) { auto &C = Conformances.get(); - - // Install callbacks for tracking when a new dylib is loaded so we can - // scan it. - installCallbacksToInspectDylib(); auto origType = type; - unsigned numSections = 0; - ConformanceCacheEntry *foundEntry; recur: @@ -2764,7 +2824,7 @@ _TFs24_injectValueIntoOptionalU__FQ_GSqQ__(OpaqueValue *value, extern "C" OpaqueExistentialContainer _TFs26_injectNothingIntoOptionalU__FT_GSqQ__(const Metadata *T); -static inline bool swift_isClassOrObjCExistentialImpl(const Metadata *T) { +static inline bool swift_isClassOrObjCExistentialTypeImpl(const Metadata *T) { auto kind = T->getKind(); // Classes. if (Metadata::isAnyKindOfClass(kind)) @@ -3032,6 +3092,7 @@ findBridgeWitness(const Metadata *T) { case MetadataKind::Class: case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Tuple: case MetadataKind::Function: @@ -3050,7 +3111,7 @@ findBridgeWitness(const Metadata *T) { extern "C" HeapObject *swift_bridgeNonVerbatimToObjectiveC( OpaqueValue *value, const Metadata *T ) { - assert(!swift_isClassOrObjCExistentialImpl(T)); + assert(!swift_isClassOrObjCExistentialTypeImpl(T)); if (const auto *bridgeWitness = findBridgeWitness(T)) { if (!bridgeWitness->isBridgedToObjectiveC(T, T)) { @@ -3073,7 +3134,7 @@ extern "C" const Metadata *swift_getBridgedNonVerbatimObjectiveCType( const Metadata *value, const Metadata *T ) { // Classes and Objective-C existentials bridge verbatim. - assert(!swift_isClassOrObjCExistentialImpl(T)); + assert(!swift_isClassOrObjCExistentialTypeImpl(T)); // Check if the type conforms to _BridgedToObjectiveC, in which case // we'll extract its associated type. @@ -3174,7 +3235,7 @@ swift_bridgeNonVerbatimFromObjectiveCConditional( extern "C" bool swift_isBridgedNonVerbatimToObjectiveC( const Metadata *value, const Metadata *T ) { - assert(!swift_isClassOrObjCExistentialImpl(T)); + assert(!swift_isClassOrObjCExistentialTypeImpl(T)); auto bridgeWitness = findBridgeWitness(T); return bridgeWitness && bridgeWitness->isBridgedToObjectiveC(value, T); @@ -3182,32 +3243,25 @@ extern "C" bool swift_isBridgedNonVerbatimToObjectiveC( #endif // func isClassOrObjCExistential(x: T.Type) -> Bool -extern "C" bool swift_isClassOrObjCExistential(const Metadata *value, +extern "C" bool swift_isClassOrObjCExistentialType(const Metadata *value, const Metadata *T) { - return swift_isClassOrObjCExistentialImpl(T); + return swift_isClassOrObjCExistentialTypeImpl(T); } -// func _swift_isClass(x: Any) -> Bool -extern "C" bool _swift_isClass(OpaqueExistentialContainer *value) { - bool Result = Metadata::isAnyKindOfClass(value->Type->getKind()); - - // Destroy value->Buffer since the Any is passed in at +1. - value->Type->vw_destroyBuffer(&value->Buffer); - - return Result; -} - -// func _swift_getSuperclass_nonNull(_: AnyClass) -> AnyClass? -extern "C" const Metadata *_swift_getSuperclass_nonNull( +// func swift_class_getSuperclass(_: AnyClass) -> AnyClass? +extern "C" const Metadata *swift_class_getSuperclass( const Metadata *theClass ) { if (const ClassMetadata *classType = theClass->getClassObject()) - if (auto super = classType->SuperClass) - if (super != getRootSuperclass()) - return swift_getObjCClassMetadata(super); + if (classHasSuperclass(classType)) + return swift_getObjCClassMetadata(classType->SuperClass); return nullptr; } extern "C" bool swift_isClassType(const Metadata *type) { return Metadata::isAnyKindOfClass(type->getKind()); } + +extern "C" bool swift_isOptionalType(const Metadata *type) { + return type->getKind() == MetadataKind::Optional; +} diff --git a/stdlib/public/runtime/Demangle.cpp b/stdlib/public/runtime/Demangle.cpp index c3554b87f60ae..1d1c4d4b13ec6 100644 --- a/stdlib/public/runtime/Demangle.cpp +++ b/stdlib/public/runtime/Demangle.cpp @@ -1,2 +1,228 @@ #include "../../../lib/Basic/Demangle.cpp" #include "../../../lib/Basic/Punycode.cpp" +#include "swift/Runtime/Metadata.h" +#include "Private.h" + +#if SWIFT_OBJC_INTEROP + +#include + +// Build a demangled type tree for a nominal type. +static Demangle::NodePointer +_buildDemanglingForNominalType(Demangle::Node::Kind boundGenericKind, + const Metadata *type, + const NominalTypeDescriptor *description) { + using namespace Demangle; + + // Demangle the base name. + auto node = demangleTypeAsNode(description->Name, + strlen(description->Name)); + // If generic, demangle the type parameters. + if (description->GenericParams.NumPrimaryParams > 0) { + auto typeParams = NodeFactory::create(Node::Kind::TypeList); + auto typeBytes = reinterpret_cast(type); + auto genericParam = reinterpret_cast( + typeBytes + sizeof(void*) * description->GenericParams.Offset); + for (unsigned i = 0, e = description->GenericParams.NumPrimaryParams; + i < e; ++i, ++genericParam) { + typeParams->addChild(_swift_buildDemanglingForMetadata(*genericParam)); + } + + auto genericNode = NodeFactory::create(boundGenericKind); + genericNode->addChild(node); + genericNode->addChild(typeParams); + return genericNode; + } + return node; +} + +// Build a demangled type tree for a type. +Demangle::NodePointer swift::_swift_buildDemanglingForMetadata(const Metadata *type) { + using namespace Demangle; + + switch (type->getKind()) { + case MetadataKind::Class: { + auto classType = static_cast(type); + return _buildDemanglingForNominalType(Node::Kind::BoundGenericClass, + type, classType->getDescription()); + } + case MetadataKind::Enum: + case MetadataKind::Optional: { + auto structType = static_cast(type); + return _buildDemanglingForNominalType(Node::Kind::BoundGenericEnum, + type, structType->Description); + } + case MetadataKind::Struct: { + auto structType = static_cast(type); + return _buildDemanglingForNominalType(Node::Kind::BoundGenericStructure, + type, structType->Description); + } + case MetadataKind::ObjCClassWrapper: { +#if SWIFT_OBJC_INTEROP + auto objcWrapper = static_cast(type); + const char *className = class_getName((Class)objcWrapper->Class); + + // ObjC classes mangle as being in the magic "__ObjC" module. + auto module = NodeFactory::create(Node::Kind::Module, "__ObjC"); + + auto node = NodeFactory::create(Node::Kind::Class); + node->addChild(module); + node->addChild(NodeFactory::create(Node::Kind::Identifier, + llvm::StringRef(className))); + + return node; +#else + assert(false && "no ObjC interop"); + return nullptr; +#endif + } + case MetadataKind::ForeignClass: { + auto foreign = static_cast(type); + return Demangle::demangleTypeAsNode(foreign->getName(), + strlen(foreign->getName())); + } + case MetadataKind::Existential: { + auto exis = static_cast(type); + NodePointer proto_list = NodeFactory::create(Node::Kind::ProtocolList); + NodePointer type_list = NodeFactory::create(Node::Kind::TypeList); + + proto_list->addChild(type_list); + + std::vector protocols; + protocols.reserve(exis->Protocols.NumProtocols); + for (unsigned i = 0, e = exis->Protocols.NumProtocols; i < e; ++i) + protocols.push_back(exis->Protocols[i]); + + // Sort the protocols by their mangled names. + // The ordering in the existential type metadata is by metadata pointer, + // which isn't necessarily stable across invocations. + std::sort(protocols.begin(), protocols.end(), + [](const ProtocolDescriptor *a, const ProtocolDescriptor *b) -> bool { + return strcmp(a->Name, b->Name) < 0; + }); + + for (auto *protocol : protocols) { + // The protocol name is mangled as a type symbol, with the _Tt prefix. + auto protocolNode = demangleSymbolAsNode(protocol->Name, + strlen(protocol->Name)); + + // ObjC protocol names aren't mangled. + if (!protocolNode) { + auto module = NodeFactory::create(Node::Kind::Module, + MANGLING_MODULE_OBJC); + auto node = NodeFactory::create(Node::Kind::Protocol); + node->addChild(module); + node->addChild(NodeFactory::create(Node::Kind::Identifier, + llvm::StringRef(protocol->Name))); + auto typeNode = NodeFactory::create(Node::Kind::Type); + typeNode->addChild(node); + type_list->addChild(typeNode); + continue; + } + + // FIXME: We have to dig through a ridiculous number of nodes to get + // to the Protocol node here. + protocolNode = protocolNode->getChild(0); // Global -> TypeMangling + protocolNode = protocolNode->getChild(0); // TypeMangling -> Type + protocolNode = protocolNode->getChild(0); // Type -> ProtocolList + protocolNode = protocolNode->getChild(0); // ProtocolList -> TypeList + protocolNode = protocolNode->getChild(0); // TypeList -> Type + + assert(protocolNode->getKind() == Node::Kind::Type); + assert(protocolNode->getChild(0)->getKind() == Node::Kind::Protocol); + type_list->addChild(protocolNode); + } + + return proto_list; + } + case MetadataKind::ExistentialMetatype: { + auto metatype = static_cast(type); + auto instance = _swift_buildDemanglingForMetadata(metatype->InstanceType); + auto node = NodeFactory::create(Node::Kind::ExistentialMetatype); + node->addChild(instance); + return node; + } + case MetadataKind::Function: { + auto func = static_cast(type); + + Node::Kind kind; + switch (func->getConvention()) { + case FunctionMetadataConvention::Swift: + kind = Node::Kind::FunctionType; + break; + case FunctionMetadataConvention::Block: + kind = Node::Kind::ObjCBlock; + break; + case FunctionMetadataConvention::CFunctionPointer: + kind = Node::Kind::CFunctionPointer; + break; + case FunctionMetadataConvention::Thin: + kind = Node::Kind::ThinFunctionType; + break; + } + + std::vector inputs; + for (unsigned i = 0, e = func->getNumArguments(); i < e; ++i) { + auto arg = func->getArguments()[i]; + auto input = _swift_buildDemanglingForMetadata(arg.getPointer()); + if (arg.getFlag()) { + NodePointer inout = NodeFactory::create(Node::Kind::InOut); + inout->addChild(input); + input = inout; + } + inputs.push_back(input); + } + + NodePointer totalInput; + if (inputs.size() > 1) { + auto tuple = NodeFactory::create(Node::Kind::NonVariadicTuple); + for (auto &input : inputs) + tuple->addChild(input); + totalInput = tuple; + } else { + totalInput = inputs.front(); + } + + NodePointer args = NodeFactory::create(Node::Kind::ArgumentTuple); + args->addChild(totalInput); + + NodePointer resultTy = _swift_buildDemanglingForMetadata(func->ResultType); + NodePointer result = NodeFactory::create(Node::Kind::ReturnType); + result->addChild(resultTy); + + auto funcNode = NodeFactory::create(kind); + if (func->throws()) + funcNode->addChild(NodeFactory::create(Node::Kind::ThrowsAnnotation)); + funcNode->addChild(args); + funcNode->addChild(result); + return funcNode; + } + case MetadataKind::Metatype: { + auto metatype = static_cast(type); + auto instance = _swift_buildDemanglingForMetadata(metatype->InstanceType); + auto node = NodeFactory::create(Node::Kind::Metatype); + node->addChild(instance); + return node; + } + case MetadataKind::Tuple: { + auto tuple = static_cast(type); + auto tupleNode = NodeFactory::create(Node::Kind::NonVariadicTuple); + for (unsigned i = 0, e = tuple->NumElements; i < e; ++i) { + auto elt = _swift_buildDemanglingForMetadata(tuple->getElement(i).Type); + tupleNode->addChild(elt); + } + return tupleNode; + } + case MetadataKind::Opaque: + // FIXME: Some opaque types do have manglings, but we don't have enough info + // to figure them out. + case MetadataKind::HeapLocalVariable: + case MetadataKind::HeapGenericLocalVariable: + case MetadataKind::ErrorObject: + break; + } + // Not a type. + return nullptr; +} + +#endif diff --git a/stdlib/public/runtime/Enum.cpp b/stdlib/public/runtime/Enum.cpp index aa8e79654422e..50216d6347f44 100644 --- a/stdlib/public/runtime/Enum.cpp +++ b/stdlib/public/runtime/Enum.cpp @@ -1,8 +1,8 @@ -//===--- Enum.cpp - Runtime declarations for enums -----------*- C++ -*--===// +//===--- Enum.cpp - Runtime declarations for enums --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/runtime/ErrorObject.cpp b/stdlib/public/runtime/ErrorObject.cpp index a12cbe075412b..20d3747aee84f 100644 --- a/stdlib/public/runtime/ErrorObject.cpp +++ b/stdlib/public/runtime/ErrorObject.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/runtime/ErrorObject.h b/stdlib/public/runtime/ErrorObject.h index 3ec36ed20c9df..62748b84eed51 100644 --- a/stdlib/public/runtime/ErrorObject.h +++ b/stdlib/public/runtime/ErrorObject.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -180,14 +180,6 @@ extern "C" void swift_unexpectedError(SwiftError *object) /// Initialize an ErrorType box to make it usable as an NSError instance. extern "C" id swift_bridgeErrorTypeToNSError(SwiftError *errorObject); -/// Convert an (optional) NSError instance to a (non-optional) -/// ErrorType box. -extern "C" SwiftError *swift_convertNSErrorToErrorType(id errorObject); - -/// Convert a (non-optional) ErrorType box to a (non-optional) -/// NSError instance. -extern "C" id swift_convertErrorTypeToNSError(SwiftError *errorObject); - /// Attempt to dynamically cast an NSError instance to a Swift ErrorType /// implementation using the _ObjectiveCBridgeableErrorType protocol. /// diff --git a/stdlib/public/runtime/ErrorObject.mm b/stdlib/public/runtime/ErrorObject.mm index 8a302f4f282c9..851d194e908b7 100644 --- a/stdlib/public/runtime/ErrorObject.mm +++ b/stdlib/public/runtime/ErrorObject.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -313,23 +313,6 @@ static id _swift_bridgeErrorTypeToNSError_(SwiftError *errorObject) { return _swift_bridgeErrorTypeToNSError(errorObject); } -SwiftError * -swift::swift_convertNSErrorToErrorType(id errorObject) { - // The fast path is that we have a real error object. - if (errorObject) return reinterpret_cast(errorObject); - - // Unlike Objective-C, we can't just propagate nil errors around. - auto allocNilError = - (SwiftError*(*)()) dlsym(RTLD_DEFAULT, "swift_allocNilObjCError"); - assert(allocNilError && "didn't link Foundation overlay?"); - return allocNilError(); -} - -id swift::swift_convertErrorTypeToNSError(SwiftError *errorObject) { - assert(errorObject && "bridging a nil error!"); - return swift_bridgeErrorTypeToNSError(errorObject); -} - bool swift::tryDynamicCastNSErrorToValue(OpaqueValue *dest, OpaqueValue *src, @@ -380,6 +363,7 @@ static id _swift_bridgeErrorTypeToNSError_(SwiftError *errorObject) { } // Not a class. case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Existential: case MetadataKind::ExistentialMetatype: case MetadataKind::Function: diff --git a/stdlib/public/runtime/Errors.cpp b/stdlib/public/runtime/Errors.cpp index 248bbcb2901d2..7b8aeb091929c 100644 --- a/stdlib/public/runtime/Errors.cpp +++ b/stdlib/public/runtime/Errors.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -85,6 +85,12 @@ reportNow(const char *message) #endif } +/// Report a fatal error to system console, stderr, and crash logs. +/// Does not crash by itself. +void swift::swift_reportError(const char *message) { + reportNow(message); + reportOnCrash(message); +} // Report a fatal error to system console, stderr, and crash logs, then abort. LLVM_ATTRIBUTE_NORETURN @@ -97,89 +103,13 @@ swift::fatalError(const char *format, ...) char *log; vasprintf(&log, format, args); - reportNow(log); - reportOnCrash(log); - + swift_reportError(log); abort(); } - -// Report a fatal error to system console, stderr, and crash logs. -// : : file , line \n -// The message may be omitted by passing messageLength=0. -extern "C" void -swift_reportFatalErrorInFile(const char *prefix, intptr_t prefixLength, - const char *message, intptr_t messageLength, - const char *file, intptr_t fileLength, - uintptr_t line) { - char *log; - asprintf(&log, "%.*s: %.*s%sfile %.*s, line %zu\n", (int)prefixLength, prefix, - (int)messageLength, message, (messageLength ? ": " : ""), - (int)fileLength, file, (size_t)line); - - reportNow(log); - reportOnCrash(log); - - free(log); -} - -// Report a fatal error to system console, stderr, and crash logs. -// : : file , line \n -// The message may be omitted by passing messageLength=0. -extern "C" void swift_reportFatalError(const char *prefix, - intptr_t prefixLength, - const char *message, - intptr_t messageLength) { - char *log; - asprintf(&log, "%.*s: %.*s\n", (int)prefixLength, prefix, - (int)messageLength, message); - - reportNow(log); - reportOnCrash(log); - - free(log); -} - -// Report a call to an unimplemented initializer. -// : : : fatal error: use of unimplemented -// initializer '' for class 'className' -extern "C" void swift_reportUnimplementedInitializerInFile( - const char *className, intptr_t classNameLength, const char *initName, - intptr_t initNameLength, const char *file, intptr_t fileLength, - uintptr_t line, uintptr_t column) { - char *log; - asprintf(&log, "%.*s: %zu: %zu: fatal error: use of unimplemented " - "initializer '%.*s' for class '%.*s'\n", - (int)fileLength, file, (size_t)line, (size_t)column, - (int)initNameLength, initName, (int)classNameLength, className); - - reportNow(log); - reportOnCrash(log); - - free(log); -} - -// Report a call to an unimplemented initializer. -// fatal error: use of unimplemented initializer '' for class -// 'className' -extern "C" void swift_reportUnimplementedInitializer(const char *className, - intptr_t classNameLength, - const char *initName, - intptr_t initNameLength) { - char *log; - asprintf(&log, "fatal error: use of unimplemented " - "initializer '%.*s' for class '%.*s'\n", - (int)initNameLength, initName, (int)classNameLength, className); - - reportNow(log); - reportOnCrash(log); - - free(log); -} - -// Report a call to a removed method. +// Crash when a deleted method is called by accident. LLVM_ATTRIBUTE_NORETURN extern "C" void -swift_reportMissingMethod() { - swift::fatalError("fatal error: call of removed method\n"); +swift_deletedMethodError() { + swift::fatalError("fatal error: call of deleted method\n"); } diff --git a/stdlib/public/runtime/ExistentialMetadataImpl.h b/stdlib/public/runtime/ExistentialMetadataImpl.h index afa3c8e842a39..f91810bc834be 100644 --- a/stdlib/public/runtime/ExistentialMetadataImpl.h +++ b/stdlib/public/runtime/ExistentialMetadataImpl.h @@ -1,8 +1,8 @@ -//===--- ExistentialMetadataImpl.h - Existential metadata ------*- C++ -*--===// +//===--- ExistentialMetadataImpl.h - Existential metadata -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -325,7 +325,7 @@ struct LLVM_LIBRARY_VISIBILITY ClassExistentialBox static constexpr size_t isBitwiseTakable = true; }; -/// A non-fixed box implementation class for an class existential +/// A non-fixed box implementation class for a class existential /// type with a dynamic number of witness tables. struct LLVM_LIBRARY_VISIBILITY NonFixedClassExistentialBox : ClassExistentialBoxBase { diff --git a/stdlib/public/runtime/Heap.cpp b/stdlib/public/runtime/Heap.cpp index 5480c02107c36..d82bbffdac8cf 100644 --- a/stdlib/public/runtime/Heap.cpp +++ b/stdlib/public/runtime/Heap.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/runtime/HeapObject.cpp b/stdlib/public/runtime/HeapObject.cpp index 59ea90c41751c..15f122b10d8b9 100644 --- a/stdlib/public/runtime/HeapObject.cpp +++ b/stdlib/public/runtime/HeapObject.cpp @@ -1,8 +1,8 @@ -//===--- Alloc.cpp - Swift Language ABI Allocation Support ----------------===// +//===--- HeapObject.cpp - Swift Language ABI Allocation Support -----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -38,14 +38,6 @@ # include #include "swift/Runtime/ObjCBridge.h" #endif -#if SWIFT_RUNTIME_ENABLE_DTRACE -# include "SwiftRuntimeDTraceProbes.h" -#else -# define SWIFT_ALLOCATEOBJECT() -# define SWIFT_DEALLOCATEOBJECT() -# define SWIFT_RELEASE() -# define SWIFT_RETAIN() -#endif #include "Leaks.h" using namespace swift; @@ -54,7 +46,6 @@ HeapObject * swift::swift_allocObject(HeapMetadata const *metadata, size_t requiredSize, size_t requiredAlignmentMask) { - SWIFT_ALLOCATEOBJECT(); return _swift_allocObject(metadata, requiredSize, requiredAlignmentMask); } static HeapObject * @@ -105,8 +96,8 @@ extern "C" HeapObject* swift_bufferAllocate( } /// \brief Another entrypoint for swift_bufferAllocate. -/// It is generated by the compiler in some corner cases, e.g. if an serialized -/// optimzed module is imported into a non-optimized main module. +/// It is generated by the compiler in some corner cases, e.g. if a serialized +/// optimized module is imported into a non-optimized main module. /// TODO: This is only a workaround. Remove this function as soon as we can /// get rid of the llvm SwiftStackPromotion pass. extern "C" HeapObject* swift_bufferAllocateOnStack( @@ -116,8 +107,8 @@ extern "C" HeapObject* swift_bufferAllocateOnStack( /// \brief Called at the end of the lifetime of an object returned by /// swift_bufferAllocateOnStack. -/// It is generated by the compiler in some corner cases, e.g. if an serialized -/// optimzed module is imported into a non-optimized main module. +/// It is generated by the compiler in some corner cases, e.g. if a serialized +/// optimized module is imported into a non-optimized main module. /// TODO: This is only a workaround. Remove this function as soon as we can /// get rid of the llvm SwiftStackPromotion pass. extern "C" void swift_bufferDeallocateFromStack(HeapObject *) { @@ -125,55 +116,6 @@ extern "C" void swift_bufferDeallocateFromStack(HeapObject *) { extern "C" intptr_t swift_bufferHeaderSize() { return sizeof(HeapObject); } -/// A do-nothing destructor for POD metadata. -static void destroyPOD(HeapObject *o); - -/// Heap metadata for POD allocations. -static const FullMetadata PODHeapMetadata{ - HeapMetadataHeader{{destroyPOD}, {nullptr}}, - HeapMetadata{Metadata{MetadataKind::HeapLocalVariable}} -}; - -namespace { - /// Header for a POD allocation created by swift_allocPOD. - struct PODBox : HeapObject { - /// The size of the complete allocation. - size_t allocatedSize; - - /// The required alignment of the complete allocation. - size_t allocatedAlignMask; - - /// Returns the offset in bytes from the address of the header of a POD - /// allocation with the given size and alignment. - static size_t getValueOffset(size_t size, size_t alignMask) { - // llvm::RoundUpToAlignment(size, mask + 1) generates terrible code - return (sizeof(PODBox) + alignMask) & ~alignMask; - } - }; -} - -static void destroyPOD(HeapObject *o) { - auto box = static_cast(o); - // Deallocate the buffer. - return swift_deallocObject(box, box->allocatedSize, box->allocatedAlignMask); -} - -BoxPair::Return -swift::swift_allocPOD(size_t dataSize, size_t dataAlignmentMask) { - assert(isAlignmentMask(dataAlignmentMask)); - // Allocate the heap object. - size_t valueOffset = PODBox::getValueOffset(dataSize, dataAlignmentMask); - size_t size = valueOffset + dataSize; - size_t alignMask = std::max(dataAlignmentMask, alignof(HeapObject) - 1); - auto *obj = swift_allocObject(&PODHeapMetadata, size, alignMask); - // Initialize the header for the box. - static_cast(obj)->allocatedSize = size; - static_cast(obj)->allocatedAlignMask = alignMask; - // Get the address of the value inside. - auto *data = reinterpret_cast(obj) + valueOffset; - return BoxPair{obj, reinterpret_cast(data)}; -} - namespace { /// Heap metadata for a box, which may have been generated statically by the /// compiler or by the runtime. @@ -317,7 +259,6 @@ void _swift_release_dealloc(HeapObject *object) __attribute__((noinline,used)); void swift::swift_retain(HeapObject *object) { - SWIFT_RETAIN(); _swift_retain(object); } static void _swift_retain_(HeapObject *object) { @@ -326,7 +267,6 @@ static void _swift_retain_(HeapObject *object) { auto swift::_swift_retain = _swift_retain_; void swift::swift_retain_n(HeapObject *object, uint32_t n) { - SWIFT_RETAIN(); _swift_retain_n(object, n); } static void _swift_retain_n_(HeapObject *object, uint32_t n) { @@ -337,7 +277,6 @@ static void _swift_retain_n_(HeapObject *object, uint32_t n) { auto swift::_swift_retain_n = _swift_retain_n_; void swift::swift_release(HeapObject *object) { - SWIFT_RELEASE(); return _swift_release(object); } static void _swift_release_(HeapObject *object) { @@ -348,7 +287,6 @@ static void _swift_release_(HeapObject *object) { auto swift::_swift_release = _swift_release_; void swift::swift_release_n(HeapObject *object, uint32_t n) { - SWIFT_RELEASE(); return _swift_release_n(object, n); } static void _swift_release_n_(HeapObject *object, uint32_t n) { @@ -358,21 +296,13 @@ static void _swift_release_n_(HeapObject *object, uint32_t n) { } auto swift::_swift_release_n = _swift_release_n_; -size_t swift::swift_retainCount(HeapObject *object) { - return object->refCount.getCount(); -} - -size_t swift::swift_weakRetainCount(HeapObject *object) { - return object->weakRefCount.getCount(); -} - -void swift::swift_weakRetain(HeapObject *object) { +void swift::swift_unownedRetain(HeapObject *object) { if (!object) return; object->weakRefCount.increment(); } -void swift::swift_weakRelease(HeapObject *object) { +void swift::swift_unownedRelease(HeapObject *object) { if (!object) return; if (object->weakRefCount.decrementShouldDeallocate()) { @@ -386,13 +316,13 @@ void swift::swift_weakRelease(HeapObject *object) { } } -void swift::swift_weakRetain_n(HeapObject *object, int n) { +void swift::swift_unownedRetain_n(HeapObject *object, int n) { if (!object) return; object->weakRefCount.increment(n); } -void swift::swift_weakRelease_n(HeapObject *object, int n) { +void swift::swift_unownedRelease_n(HeapObject *object, int n) { if (!object) return; if (object->weakRefCount.decrementShouldDeallocateN(n)) { @@ -446,16 +376,30 @@ static bool _swift_isDeallocating_(HeapObject *object) { } auto swift::_swift_isDeallocating = _swift_isDeallocating_; -void swift::swift_retainUnowned(HeapObject *object) { +void swift::swift_unownedRetainStrong(HeapObject *object) { + if (!object) return; + assert(object->weakRefCount.getCount() && + "object is not currently weakly retained"); + + if (! object->refCount.tryIncrement()) + _swift_abortRetainUnowned(object); +} + +void swift::swift_unownedRetainStrongAndRelease(HeapObject *object) { if (!object) return; assert(object->weakRefCount.getCount() && "object is not currently weakly retained"); if (! object->refCount.tryIncrement()) _swift_abortRetainUnowned(object); + + // This should never cause a deallocation. + bool dealloc = object->weakRefCount.decrementShouldDeallocate(); + assert(!dealloc && "retain-strong-and-release caused dealloc?"); + (void) dealloc; } -void swift::swift_checkUnowned(HeapObject *object) { +void swift::swift_unownedCheck(HeapObject *object) { if (!object) return; assert(object->weakRefCount.getCount() && "object is not currently weakly retained"); @@ -532,7 +476,6 @@ static inline void memset_pattern8(void *b, const void *pattern8, size_t len) { void swift::swift_deallocObject(HeapObject *object, size_t allocatedSize, size_t allocatedAlignMask) { - SWIFT_DEALLOCATEOBJECT(); assert(isAlignmentMask(allocatedAlignMask)); assert(object->refCount.isDeallocating()); #ifdef SWIFT_RUNTIME_CLOBBER_FREED_OBJECTS @@ -612,32 +555,27 @@ void swift::swift_deallocObject(HeapObject *object, size_t allocatedSize, if (object->weakRefCount.getCount() == 1) { swift_slowDealloc(object, allocatedSize, allocatedAlignMask); } else { - swift_weakRelease(object); + swift_unownedRelease(object); } } -/// This is a function that is opaque to the optimizer. It is called to ensure -/// that an object is alive at least until that time. -extern "C" void swift_fixLifetime(OpaqueValue *value) { -} - void swift::swift_weakInit(WeakReference *ref, HeapObject *value) { ref->Value = value; - swift_weakRetain(value); + swift_unownedRetain(value); } void swift::swift_weakAssign(WeakReference *ref, HeapObject *newValue) { - swift_weakRetain(newValue); + swift_unownedRetain(newValue); auto oldValue = ref->Value; ref->Value = newValue; - swift_weakRelease(oldValue); + swift_unownedRelease(oldValue); } HeapObject *swift::swift_weakLoadStrong(WeakReference *ref) { auto object = ref->Value; if (object == nullptr) return nullptr; if (object->refCount.isDeallocating()) { - swift_weakRelease(object); + swift_unownedRelease(object); ref->Value = nullptr; return nullptr; } @@ -653,7 +591,7 @@ HeapObject *swift::swift_weakTakeStrong(WeakReference *ref) { void swift::swift_weakDestroy(WeakReference *ref) { auto tmp = ref->Value; ref->Value = nullptr; - swift_weakRelease(tmp); + swift_unownedRelease(tmp); } void swift::swift_weakCopyInit(WeakReference *dest, WeakReference *src) { @@ -663,10 +601,10 @@ void swift::swift_weakCopyInit(WeakReference *dest, WeakReference *src) { } else if (object->refCount.isDeallocating()) { src->Value = nullptr; dest->Value = nullptr; - swift_weakRelease(object); + swift_unownedRelease(object); } else { dest->Value = object; - swift_weakRetain(object); + swift_unownedRetain(object); } } @@ -675,20 +613,20 @@ void swift::swift_weakTakeInit(WeakReference *dest, WeakReference *src) { dest->Value = object; if (object != nullptr && object->refCount.isDeallocating()) { dest->Value = nullptr; - swift_weakRelease(object); + swift_unownedRelease(object); } } void swift::swift_weakCopyAssign(WeakReference *dest, WeakReference *src) { if (auto object = dest->Value) { - swift_weakRelease(object); + swift_unownedRelease(object); } swift_weakCopyInit(dest, src); } void swift::swift_weakTakeAssign(WeakReference *dest, WeakReference *src) { if (auto object = dest->Value) { - swift_weakRelease(object); + swift_unownedRelease(object); } swift_weakTakeInit(dest, src); } diff --git a/stdlib/public/runtime/KnownMetadata.cpp b/stdlib/public/runtime/KnownMetadata.cpp index 55eee7d38991b..c4fc1371a1d58 100644 --- a/stdlib/public/runtime/KnownMetadata.cpp +++ b/stdlib/public/runtime/KnownMetadata.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/runtime/Leaks.h b/stdlib/public/runtime/Leaks.h index a0685c3633558..ce2398cbbc48e 100644 --- a/stdlib/public/runtime/Leaks.h +++ b/stdlib/public/runtime/Leaks.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/runtime/Leaks.mm b/stdlib/public/runtime/Leaks.mm index 6cd80b1a12c04..b79595875e3ec 100644 --- a/stdlib/public/runtime/Leaks.mm +++ b/stdlib/public/runtime/Leaks.mm @@ -1,8 +1,8 @@ -//===--- Leaks.mm ----------------------------------------*- C++ -*--------===// +//===--- Leaks.mm -----------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp index 5c905fb792a17..c06ec087e548b 100644 --- a/stdlib/public/runtime/Metadata.cpp +++ b/stdlib/public/runtime/Metadata.cpp @@ -1,8 +1,8 @@ -//===--- Metadata.cpp - Swift Language ABI Metdata Support ----------------===// +//===--- Metadata.cpp - Swift Language ABI Metadata Support ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -1457,24 +1457,105 @@ static uint32_t getLog2AlignmentFromMask(size_t alignMask) { log2++; return log2; } + +static inline ClassROData *getROData(ClassMetadata *theClass) { + return (ClassROData*) (theClass->Data & ~uintptr_t(1)); +} + +static void _swift_initGenericClassObjCName(ClassMetadata *theClass) { + // Use the remangler to generate a mangled name from the type metadata. + auto demangling = _swift_buildDemanglingForMetadata(theClass); + + // Remangle that into a new type mangling string. + auto typeNode + = Demangle::NodeFactory::create(Demangle::Node::Kind::TypeMangling); + typeNode->addChild(demangling); + auto globalNode + = Demangle::NodeFactory::create(Demangle::Node::Kind::Global); + globalNode->addChild(typeNode); + + auto string = Demangle::mangleNode(globalNode); + + auto fullNameBuf = (char*)swift_slowAlloc(string.size() + 1, 0); + memcpy(fullNameBuf, string.c_str(), string.size() + 1); + + auto theMetaclass = (ClassMetadata *)object_getClass((id)theClass); + + getROData(theClass)->Name = fullNameBuf; + getROData(theMetaclass)->Name = fullNameBuf; +} +#endif + +static void _swift_initializeSuperclass(ClassMetadata *theClass, + bool copyFieldOffsetVectors) { +#if SWIFT_OBJC_INTEROP + // If the class is generic, we need to give it a name for Objective-C. + if (theClass->getDescription()->GenericParams.NumParams > 0) + _swift_initGenericClassObjCName(theClass); #endif + const ClassMetadata *theSuperclass = theClass->SuperClass; + if (theSuperclass == nullptr) + return; + + // If any ancestors had generic parameters or field offset vectors, + // inherit them. + auto ancestor = theSuperclass; + auto *classWords = reinterpret_cast(theClass); + auto *superWords = reinterpret_cast(theSuperclass); + while (ancestor && ancestor->isTypeMetadata()) { + auto description = ancestor->getDescription(); + auto &genericParams = description->GenericParams; + if (genericParams.hasGenericParams()) { + unsigned numParamWords = 0; + for (unsigned i = 0; i < genericParams.NumParams; ++i) { + // 1 word for the type metadata, and 1 for every protocol witness + numParamWords += + 1 + genericParams.Parameters[i].NumWitnessTables; + } + memcpy(classWords + genericParams.Offset, + superWords + genericParams.Offset, + numParamWords * sizeof(uintptr_t)); + } + if (copyFieldOffsetVectors && + description->Class.hasFieldOffsetVector()) { + unsigned fieldOffsetVector = description->Class.FieldOffsetVectorOffset; + memcpy(classWords + fieldOffsetVector, + superWords + fieldOffsetVector, + description->Class.NumFields * sizeof(uintptr_t)); + } + ancestor = ancestor->SuperClass; + } + +#if SWIFT_OBJC_INTEROP + // Set up the superclass of the metaclass, which is the metaclass of the + // superclass. + auto theMetaclass = (ClassMetadata *)object_getClass((id)theClass); + auto theSuperMetaclass + = (const ClassMetadata *)object_getClass((id)theSuperclass); + theMetaclass->SuperClass = theSuperMetaclass; +#endif +} + /// Initialize the field offset vector for a dependent-layout class, using the /// "Universal" layout strategy. void swift::swift_initClassMetadata_UniversalStrategy(ClassMetadata *self, - const ClassMetadata *super, size_t numFields, const ClassFieldLayout *fieldLayouts, size_t *fieldOffsets) { + _swift_initializeSuperclass(self, /*copyFieldOffsetVectors=*/true); + // Start layout by appending to a standard heap object header. size_t size, alignMask; #if SWIFT_OBJC_INTEROP - ClassROData *rodata = (ClassROData*) (self->Data & ~uintptr_t(1)); + ClassROData *rodata = getROData(self); #endif // If we have a superclass, start from its size and alignment instead. - if (super) { + if (classHasSuperclass(self)) { + const ClassMetadata *super = self->SuperClass; + // This is straightforward if the superclass is Swift. #if SWIFT_OBJC_INTEROP if (super->isTypeMetadata()) { @@ -2140,7 +2221,7 @@ ExistentialTypeMetadata::getWitnessTable(const OpaqueValue *container, } // The return type here describes extra structure for the protocol - // witness table for some reason. We should probaby have a nominal + // witness table for some reason. We should probably have a nominal // type for these, just for type safety reasons. return witnessTables[i]; } @@ -2323,6 +2404,7 @@ Metadata::getNominalTypeDescriptor() const { } case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: return static_cast(this)->Description; case MetadataKind::ForeignClass: case MetadataKind::Opaque: @@ -2362,6 +2444,7 @@ Metadata::getClassObject() const { // Other kinds of types don't have class objects. case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::ForeignClass: case MetadataKind::Opaque: case MetadataKind::Tuple: @@ -2376,88 +2459,6 @@ Metadata::getClassObject() const { } } -/// Scan and return a single run-length encoded identifier. -/// Returns a malloc-allocated string, or nullptr on failure. -/// mangled is advanced past the end of the scanned token. -static char *scanIdentifier(const char *&mangled) -{ - const char *original = mangled; - - { - if (*mangled == '0') goto fail; // length may not be zero - - size_t length = 0; - while (Demangle::isDigit(*mangled)) { - size_t oldlength = length; - length *= 10; - length += *mangled++ - '0'; - if (length <= oldlength) goto fail; // integer overflow - } - - if (length == 0) goto fail; - if (length > strlen(mangled)) goto fail; - - char *result = strndup(mangled, length); - assert(result); - mangled += length; - return result; - } - -fail: - mangled = original; // rewind - return nullptr; -} - - -/// \brief Demangle a mangled class name into module+class. -/// Returns true if the name was successfully decoded. -/// On success, *outModule and *outClass must be freed with free(). -/// FIXME: this should be replaced by a real demangler -bool swift::swift_demangleSimpleClass(const char *mangledName, - char **outModule, char **outClass) { - char *moduleName = nullptr; - char *className = nullptr; - - { - // Prefix for a mangled class - const char *m = mangledName; - if (0 != strncmp(m, "_TtC", 4)) - goto fail; - m += 4; - - // Module name - if (strncmp(m, "Ss", 2) == 0) { - moduleName = strdup(swift::STDLIB_NAME); - assert(moduleName); - m += 2; - } else { - moduleName = scanIdentifier(m); - if (!moduleName) - goto fail; - } - - // Class name - className = scanIdentifier(m); - if (!className) - goto fail; - - // Nothing else - if (strlen(m)) - goto fail; - - *outModule = moduleName; - *outClass = className; - return true; - } - -fail: - if (moduleName) free(moduleName); - if (className) free(className); - *outModule = nullptr; - *outClass = nullptr; - return false; -} - #ifndef NDEBUG extern "C" void _swift_debug_verifyTypeLayoutAttribute(Metadata *type, @@ -2493,61 +2494,14 @@ void _swift_debug_verifyTypeLayoutAttribute(Metadata *type, extern "C" void swift_initializeSuperclass(ClassMetadata *theClass, - const ClassMetadata *theSuperclass) { - // We need a lock in order to ensure the class initialization and ObjC - // registration are atomic. - // TODO: A global lock for this is lame. - // TODO: A lock is also totally unnecessary for the non-objc runtime. - // Without ObjC registration, a release store of the superclass - // reference should be enough to dependency-order the other - // initialization steps. - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - - pthread_mutex_lock(&mutex); - - // Bail out if this already happened while we were waiting. - if (theClass->SuperClass) { - pthread_mutex_unlock(&mutex); - return; - } - - // Put the superclass reference in the base class. - theClass->SuperClass = theSuperclass; - - // If any ancestors had generic parameters, inherit them. - auto ancestor = theSuperclass; - auto *classWords = reinterpret_cast(theClass); - auto *superWords = reinterpret_cast(theSuperclass); - while (ancestor && ancestor->isTypeMetadata()) { - auto description = ancestor->getDescription(); - auto &genericParams = description->GenericParams; - if (genericParams.hasGenericParams()) { - unsigned numParamWords = 0; - for (unsigned i = 0; i < genericParams.NumParams; ++i) { - // 1 word for the type metadata, and 1 for every protocol witness - numParamWords += - 1 + genericParams.Parameters[i].NumWitnessTables; - } - memcpy(classWords + genericParams.Offset, - superWords + genericParams.Offset, - numParamWords * sizeof(uintptr_t)); - } - ancestor = ancestor->SuperClass; - } - + bool copyFieldOffsetVectors) { + // Copy generic parameters and field offset vectors from the superclass. + _swift_initializeSuperclass(theClass, copyFieldOffsetVectors); + #if SWIFT_OBJC_INTEROP - // Set up the superclass of the metaclass, which is the metaclass of the - // superclass. - auto theMetaclass = (ClassMetadata *)object_getClass((id)theClass); - auto theSuperMetaclass - = (const ClassMetadata *)object_getClass((id)theSuperclass); - theMetaclass->SuperClass = theSuperMetaclass; - // Register the class pair with the ObjC runtime. swift_instantiateObjCClass(theClass); #endif - - pthread_mutex_unlock(&mutex); } namespace llvm { namespace hashing { namespace detail { @@ -2556,3 +2510,65 @@ namespace llvm { namespace hashing { namespace detail { size_t fixed_seed_override = 0; } } } +/*** Protocol witness tables *************************************************/ + +namespace { + class WitnessTableCacheEntry : public CacheEntry { + public: + static const char *getName() { return "WitnessTableCache"; } + + WitnessTableCacheEntry(size_t numArguments) {} + + static constexpr size_t getNumArguments() { + return 1; + } + }; +} + +using GenericWitnessTableCache = MetadataCache; +using LazyGenericWitnessTableCache = Lazy; + +/// Fetch the cache for a generic witness-table structure. +static GenericWitnessTableCache &getCache(GenericWitnessTable *gen) { + // Keep this assert even if you change the representation above. + static_assert(sizeof(LazyGenericWitnessTableCache) <= + sizeof(GenericWitnessTable::PrivateData), + "metadata cache is larger than the allowed space"); + + auto lazyCache = + reinterpret_cast(gen->PrivateData); + return lazyCache->get(); +} + +extern "C" const WitnessTable * +swift::swift_getGenericWitnessTable(GenericWitnessTable *genericTable, + const Metadata *type, + void * const *instantiationArgs) { + // Search the cache. + constexpr const size_t numGenericArgs = 1; + const void *args[] = { type }; + auto &cache = getCache(genericTable); + auto entry = cache.findOrAdd(args, numGenericArgs, + [&]() -> WitnessTableCacheEntry* { + // Create a new entry for the cache. + auto entry = WitnessTableCacheEntry::allocate(cache.getAllocator(), + args, numGenericArgs, + genericTable->WitnessTableSizeInWords * sizeof(void*)); + + auto *table = entry->getData(); + memcpy((void**) table, (void* const *) &*genericTable->Pattern, + genericTable->WitnessTableSizeInWordsToCopy * sizeof(void*)); + bzero((void**) table + genericTable->WitnessTableSizeInWordsToCopy, + (genericTable->WitnessTableSizeInWords + - genericTable->WitnessTableSizeInWordsToCopy) * sizeof(void*)); + + // Call the instantiation function. + if (!genericTable->Instantiator.isNull()) { + genericTable->Instantiator(table, type, instantiationArgs); + } + + return entry; + }); + + return entry->getData(); +} diff --git a/stdlib/public/runtime/MetadataCache.h b/stdlib/public/runtime/MetadataCache.h index 9d10cd7717e13..b83277ccc9e69 100644 --- a/stdlib/public/runtime/MetadataCache.h +++ b/stdlib/public/runtime/MetadataCache.h @@ -1,8 +1,8 @@ -//===--- MetadataCache.h - Implements the metadata cache -------*- C++ -*--===// +//===--- MetadataCache.h - Implements the metadata cache --------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -201,7 +201,7 @@ template class MetadataCache { // Build the new cache entry. // For some cache types this call may re-entrantly perform additional // cache lookups. - // Notice that the entry is completly constructed before it is inserted + // Notice that the entry is completely constructed before it is inserted // into the map, and that only one entry can be constructed at once // because of the lock above. Entry *entry = entryBuilder(); diff --git a/stdlib/public/runtime/MetadataImpl.h b/stdlib/public/runtime/MetadataImpl.h index 32260bf366fe2..f75f57d36f981 100644 --- a/stdlib/public/runtime/MetadataImpl.h +++ b/stdlib/public/runtime/MetadataImpl.h @@ -1,8 +1,8 @@ -//===--- MetadataImpl.h - Metadata implementation routines -----*- C++ -*--===// +//===--- MetadataImpl.h - Metadata implementation routines ------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -269,13 +269,28 @@ struct SwiftRetainableBox : struct SwiftUnownedRetainableBox : RetainableBoxBase { static HeapObject *retain(HeapObject *obj) { - swift_weakRetain(obj); + swift_unownedRetain(obj); return obj; } static void release(HeapObject *obj) { - swift_weakRelease(obj); + swift_unownedRelease(obj); } + +#if SWIFT_OBJC_INTEROP + // The implementation from RetainableBoxBase is valid when interop is + // disabled. + static constexpr unsigned numExtraInhabitants = 1; + + static void storeExtraInhabitant(HeapObject **dest, int index) { + assert(index == 0); + *dest = nullptr; + } + + static int getExtraInhabitantIndex(const HeapObject * const *src) { + return (*src == nullptr ? 0 : -1); + } +#endif }; /// CRTP base class for weak reference boxes. @@ -377,17 +392,39 @@ struct ObjCRetainableBox : RetainableBoxBase { /// A box implementation class for unowned Objective-C object pointers. struct ObjCUnownedRetainableBox - : RetainableBoxBase { - static constexpr unsigned numExtraInhabitants = - swift_getHeapObjectExtraInhabitantCount(); + : WeakRetainableBoxBase { - static void *retain(void *obj) { - swift_unknownWeakRetain(obj); - return obj; + static constexpr unsigned numExtraInhabitants = 1; + static void storeExtraInhabitant(UnownedReference *dest, int index) { + assert(index == 0); + dest->Value = nullptr; + } + static int getExtraInhabitantIndex(const UnownedReference *src) { + return (src->Value == nullptr ? 0 : -1); } - static void release(void *obj) { - swift_unknownWeakRelease(obj); + static void destroy(UnownedReference *ref) { + swift_unknownUnownedDestroy(ref); + } + static UnownedReference *initializeWithCopy(UnownedReference *dest, + UnownedReference *src) { + swift_unknownUnownedCopyInit(dest, src); + return dest; + } + static UnownedReference *initializeWithTake(UnownedReference *dest, + UnownedReference *src) { + swift_unknownUnownedTakeInit(dest, src); + return dest; + } + static UnownedReference *assignWithCopy(UnownedReference *dest, + UnownedReference *src) { + swift_unknownUnownedCopyAssign(dest, src); + return dest; + } + static UnownedReference *assignWithTake(UnownedReference *dest, + UnownedReference *src) { + swift_unknownUnownedTakeAssign(dest, src); + return dest; } }; diff --git a/stdlib/public/runtime/Once.cpp b/stdlib/public/runtime/Once.cpp index ee8f691156ba2..5fea28dd1ab66 100644 --- a/stdlib/public/runtime/Once.cpp +++ b/stdlib/public/runtime/Once.cpp @@ -1,8 +1,8 @@ -//===--- Once.cpp - Runtime support for lazy initialization ----------------==// +//===--- Once.cpp - Runtime support for lazy initialization ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,7 +22,7 @@ using namespace swift; #ifdef __APPLE__ -// On OS X and and iOS, swift_once is implemented using GCD. +// On OS X and iOS, swift_once is implemented using GCD. #include static_assert(std::is_same::value, diff --git a/stdlib/public/runtime/Private.h b/stdlib/public/runtime/Private.h index 0a66df2e16843..1443a5b72966c 100644 --- a/stdlib/public/runtime/Private.h +++ b/stdlib/public/runtime/Private.h @@ -1,8 +1,8 @@ -//===--- Private.h - Private runtime declarations --------------*- C++ -*--===// +//===--- Private.h - Private runtime declarations ---------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,6 +17,7 @@ #ifndef SWIFT_RUNTIME_PRIVATE_H #define SWIFT_RUNTIME_PRIVATE_H +#include "swift/Basic/Demangle.h" #include "swift/Runtime/Config.h" #include "swift/Runtime/Metadata.h" #include "llvm/Support/Compiler.h" @@ -29,12 +30,10 @@ namespace swift { #endif #if SWIFT_OBJC_INTEROP - extern "C" LLVM_LIBRARY_VISIBILITY - bool _swift_objectConformsToObjCProtocol(const void *theObject, + bool objectConformsToObjCProtocol(const void *theObject, const ProtocolDescriptor *theProtocol); - extern "C" LLVM_LIBRARY_VISIBILITY - bool _swift_classConformsToObjCProtocol(const void *theClass, + bool classConformsToObjCProtocol(const void *theClass, const ProtocolDescriptor *theProtocol); #endif @@ -95,7 +94,13 @@ namespace swift { /// Note that this function may return a nullptr on non-objc platforms, /// where there is no common root class. rdar://problem/18987058 const ClassMetadata *getRootSuperclass(); - + + /// Check if a class has a formal superclass in the AST. + static inline + bool classHasSuperclass(const ClassMetadata *c) { + return (c->SuperClass && c->SuperClass != getRootSuperclass()); + } + /// Replace entries of a freshly-instantiated value witness table with more /// efficient common implementations where applicable. /// @@ -106,6 +111,9 @@ namespace swift { /// Returns true if common value witnesses were used, false otherwise. void installCommonValueWitnesses(ValueWitnessTable *vwtable); +#if SWIFT_OBJC_INTEROP + Demangle::NodePointer _swift_buildDemanglingForMetadata(const Metadata *type); +#endif } // end namespace swift diff --git a/stdlib/public/runtime/Reflection.mm b/stdlib/public/runtime/Reflection.mm index 245a0938cf2f4..bcaf960e2d9a4 100644 --- a/stdlib/public/runtime/Reflection.mm +++ b/stdlib/public/runtime/Reflection.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,7 +22,6 @@ #include #include #include -#include #include #if SWIFT_OBJC_INTEROP @@ -309,6 +308,7 @@ void swift_MagicMirrorData_summary(const Metadata *T, String *result) { new (result) String("(Struct)"); break; case MetadataKind::Enum: + case MetadataKind::Optional: new (result) String("(Enum Value)"); break; case MetadataKind::Opaque: @@ -381,6 +381,7 @@ intptr_t swift_TupleMirror_count(HeapObject *owner, case MetadataKind::Class: case MetadataKind::Opaque: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Function: case MetadataKind::Metatype: break; @@ -596,7 +597,7 @@ static void getEnumMirrorInfo(const OpaqueValue *value, const OpaqueValue *value, const Metadata *type) { if (!isEnumReflectable(type)) - return NULL; + return nullptr; const auto Enum = static_cast(type); const auto &Description = Enum->Description->Enum; @@ -658,18 +659,6 @@ StringMirrorTuple swift_EnumMirror_subscript(intptr_t i, } // -- Class destructuring. -static bool classHasSuperclass(const ClassMetadata *c) { -#if SWIFT_OBJC_INTEROP - // A class does not have a superclass if its ObjC superclass is the - // "SwiftObject" root class. - return c->SuperClass - && (Class)c->SuperClass != NSClassFromString(@"SwiftObject"); -#else - // In non-objc mode, the test is just if it has a non-null superclass. - return c->SuperClass != nullptr; -#endif -} - static Mirror getMirrorForSuperclass(const ClassMetadata *sup, HeapObject *owner, const OpaqueValue *value, @@ -1149,6 +1138,7 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup, T, &StructMirrorMetadata, &StructMirrorWitnessTable); case MetadataKind::Enum: + case MetadataKind::Optional: return std::make_tuple( T, &EnumMirrorMetadata, &EnumMirrorWitnessTable); @@ -1264,3 +1254,17 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup, T->vw_destroy(value); return MirrorReturn(result); } + +// NB: This function is not used directly in the Swift codebase, but is +// exported for Xcode support. Please coordinate before changing. +extern "C" void swift_stdlib_demangleName(const char *mangledName, + size_t mangledNameLength, + String *demangledName) { + auto options = Demangle::DemangleOptions(); + options.DisplayDebuggerGeneratedModule = false; + auto result = + Demangle::demangleSymbolAsString(mangledName, + mangledNameLength, + options); + new (demangledName) String(result.data(), result.size()); +} diff --git a/stdlib/public/runtime/SwiftObject.mm b/stdlib/public/runtime/SwiftObject.mm index ab15117b3cbff..4179d164ec88b 100644 --- a/stdlib/public/runtime/SwiftObject.mm +++ b/stdlib/public/runtime/SwiftObject.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -24,6 +24,7 @@ #endif #include "llvm/ADT/StringRef.h" #include "swift/Basic/Demangle.h" +#include "swift/Basic/LLVM.h" #include "swift/Basic/Lazy.h" #include "swift/Runtime/Heap.h" #include "swift/Runtime/HeapObject.h" @@ -43,12 +44,6 @@ # include # include #endif -#if SWIFT_RUNTIME_ENABLE_DTRACE -# include "SwiftRuntimeDTraceProbes.h" -#else -#define SWIFT_ISUNIQUELYREFERENCED() -#define SWIFT_ISUNIQUELYREFERENCEDORPINNED() -#endif using namespace swift; @@ -237,8 +232,8 @@ - (BOOL)isProxy { } - (struct _NSZone *)zone { - return (struct _NSZone *) - (malloc_zone_from_ptr(self) ?: malloc_default_zone()); + auto zone = malloc_zone_from_ptr(self); + return (struct _NSZone *)(zone ? zone : malloc_default_zone()); } - (void)doesNotRecognizeSelector: (SEL) sel { @@ -261,7 +256,7 @@ - (id)autorelease { return _objc_rootAutorelease(self); } - (NSUInteger)retainCount { - return swift::swift_retainCount(reinterpret_cast(self)); + return reinterpret_cast(self)->refCount.getCount(); } - (BOOL)_isDeallocating { return swift_isDeallocating(reinterpret_cast(self)); @@ -435,79 +430,6 @@ - (BOOL)isNSValue__ { return NO; } @end -/*****************************************************************************/ -/****************************** WEAK REFERENCES ******************************/ -/*****************************************************************************/ - -/// A side-table of shared weak references for use by the unowned entry. -/// -/// FIXME: this needs to be integrated with the ObjC runtime so that -/// entries will actually get collected. Also, that would make this just -/// a simple manipulation of the internal structures there. -/// -/// FIXME: this is not actually safe; if the ObjC runtime deallocates -/// the pointer, the keys in UnownedRefs will become dangling -/// references. rdar://16968733 -namespace { - struct UnownedRefEntry { - id Value; - size_t Count; - }; -} - -// The ObjC runtime will hold a point into the UnownedRefEntry, -// so we require pointers to objects to be stable across rehashes. -// DenseMap doesn't guarantee that, but std::unordered_map does. - -namespace { -struct UnownedTable { - std::unordered_map Refs; - std::mutex Mutex; -}; -} - -static Lazy UnownedRefs; - -static void objc_rootRetainUnowned(id object) { - auto &Unowned = UnownedRefs.get(); - - std::lock_guard lock(Unowned.Mutex); - auto it = Unowned.Refs.find((const void*) object); - assert(it != Unowned.Refs.end()); - assert(it->second.Count > 0); - - // Do an unbalanced retain. - id result = objc_loadWeakRetained(&it->second.Value); - - // If that yielded null, abort. - if (!result) _swift_abortRetainUnowned((const void*) object); -} - -static void objc_rootWeakRetain(id object) { - auto &Unowned = UnownedRefs.get(); - - std::lock_guard lock(Unowned.Mutex); - auto ins = Unowned.Refs.insert({ (const void*) object, UnownedRefEntry() }); - if (!ins.second) { - ins.first->second.Count++; - } else { - objc_initWeak(&ins.first->second.Value, object); - ins.first->second.Count = 1; - } -} - -static void objc_rootWeakRelease(id object) { - auto &Unowned = UnownedRefs.get(); - - std::lock_guard lock(Unowned.Mutex); - auto it = Unowned.Refs.find((const void*) object); - assert(it != Unowned.Refs.end()); - assert(it->second.Count > 0); - if (--it->second.Count == 0) { - objc_destroyWeak(&it->second.Value); - Unowned.Refs.erase(it); - } -} #endif /// Decide dynamically whether the given object uses native Swift @@ -523,7 +445,7 @@ static void objc_rootWeakRelease(id object) { // version for SwiftShims bool -swift::_swift_usesNativeSwiftReferenceCounting_class(const void *theClass) { +swift::swift_objc_class_usesNativeSwiftReferenceCounting(const void *theClass) { #if SWIFT_OBJC_INTEROP return usesNativeSwiftReferenceCounting((const ClassMetadata *)theClass); #else @@ -551,21 +473,6 @@ static bool usesNativeSwiftReferenceCounting_allocated(const void *object) { return usesNativeSwiftReferenceCounting(_swift_getClassOfAllocated(object)); } -static bool usesNativeSwiftReferenceCounting_unowned(const void *object) { - auto &Unowned = UnownedRefs.get(); - - // If an unknown object is unowned-referenced, it may in fact be implemented - // using an ObjC weak reference, which will eagerly deallocate the object - // when strongly released. We have to check first whether the object is in - // the side table before dereferencing the pointer. - if (Unowned.Refs.count(object)) - return false; - // For a natively unowned reference, even after all strong references have - // been released, there's enough of a husk left behind to determine its - // species. - return usesNativeSwiftReferenceCounting_allocated(object); -} - void swift::swift_unknownRetain_n(void *object, int n) { if (isObjCTaggedPointerOrNull(object)) return; if (usesNativeSwiftReferenceCounting_allocated(object)) { @@ -700,26 +607,246 @@ static bool isNonNative_unTagged_bridgeObject(void *object) { #if SWIFT_OBJC_INTEROP -void swift::swift_unknownRetainUnowned(void *object) { - if (isObjCTaggedPointerOrNull(object)) return; - if (usesNativeSwiftReferenceCounting_unowned(object)) - return swift_retainUnowned((HeapObject*) object); - objc_rootRetainUnowned((id) object); + +/*****************************************************************************/ +/**************************** UNOWNED REFERENCES *****************************/ +/*****************************************************************************/ + +// Swift's native unowned references are implemented purely with +// reference-counting: as long as an unowned reference is held to an object, +// it can be destroyed but never deallocated, being that it remains fully safe +// to pass around a pointer and perform further reference-counting operations. +// +// For imported class types (meaning ObjC, for now, but in principle any +// type which supports ObjC-style weak references but not directly Swift-style +// unowned references), we have to implement this on top of the weak-reference +// support, at least for now. But we'd like to be able to statically take +// advantage of Swift's representational advantages when we know that all the +// objects involved are Swift-native. That means that whatever scheme we use +// for unowned references needs to interoperate with code just doing naive +// loads and stores, at least when the ObjC case isn't triggered. +// +// We have to be sensitive about making unreasonable assumptions about the +// implementation of ObjC weak references, and we definitely cannot modify +// memory owned by the ObjC runtime. In the long run, direct support from +// the ObjC runtime can allow an efficient implementation that doesn't violate +// those requirements, both by allowing us to directly check whether a weak +// reference was cleared by deallocation vs. just initialized to nil and by +// guaranteeing a bit pattern that distinguishes Swift references. In the +// meantime, out-of-band allocation is inefficient but not ridiculously so. +// +// Note that unowned references need not provide guaranteed behavior in +// the presence of read/write or write/write races on the reference itself. +// Furthermore, and unlike weak references, they also do not need to be +// safe against races with the deallocation of the object. It is the user's +// responsibility to ensure that the reference remains valid at the time +// that the unowned reference is read. + +namespace { + /// An Objective-C unowned reference. Given an unknown unowned reference + /// in memory, it is an ObjC unowned reference if the IsObjCFlag bit + /// is set; if so, the pointer stored in the reference actually points + /// to out-of-line storage containing an ObjC weak reference. + /// + /// It is an invariant that this out-of-line storage is only ever + /// allocated and constructed for non-null object references, so if the + /// weak load yields null, it can only be because the object was deallocated. + struct ObjCUnownedReference : UnownedReference { + // Pretending that there's a subclass relationship here means that + // accesses to objects formally constructed as UnownedReferences will + // technically be aliasing violations. However, the language runtime + // will generally not see any such objects. + + enum : uintptr_t { IsObjCMask = 0x1, IsObjCFlag = 0x1 }; + + /// The out-of-line storage of an ObjC unowned reference. + struct Storage { + /// A weak reference registered with the ObjC runtime. + mutable id WeakRef; + + Storage(id ref) { + assert(ref && "creating storage for null reference?"); + objc_initWeak(&WeakRef, ref); + } + + Storage(const Storage &other) { + objc_copyWeak(&WeakRef, &other.WeakRef); + } + + Storage &operator=(const Storage &other) = delete; + + Storage &operator=(id ref) { + objc_storeWeak(&WeakRef, ref); + return *this; + } + + ~Storage() { + objc_destroyWeak(&WeakRef); + } + + // Don't use the C++ allocator. + void *operator new(size_t size) { return malloc(size); } + void operator delete(void *ptr) { free(ptr); } + }; + + Storage *storage() { + assert(isa(this)); + return reinterpret_cast( + reinterpret_cast(Value) & ~IsObjCMask); + } + + static void initialize(UnownedReference *dest, id value) { + initializeWithStorage(dest, new Storage(value)); + } + + static void initializeWithCopy(UnownedReference *dest, Storage *src) { + initializeWithStorage(dest, new Storage(*src)); + } + + static void initializeWithStorage(UnownedReference *dest, + Storage *storage) { + dest->Value = (HeapObject*) (uintptr_t(storage) | IsObjCFlag); + } + + static bool classof(const UnownedReference *ref) { + return (uintptr_t(ref->Value) & IsObjCMask) == IsObjCFlag; + } + }; } -void swift::swift_unknownWeakRetain(void *object) { - if (isObjCTaggedPointerOrNull(object)) return; - if (usesNativeSwiftReferenceCounting_unowned(object)) - return swift_weakRetain((HeapObject*) object); - objc_rootWeakRetain((id) object); +static bool isObjCForUnownedReference(void *value) { + return (isObjCTaggedPointer(value) || + !usesNativeSwiftReferenceCounting_allocated(value)); } -void swift::swift_unknownWeakRelease(void *object) { - if (isObjCTaggedPointerOrNull(object)) return; - if (usesNativeSwiftReferenceCounting_unowned(object)) - return swift_weakRelease((HeapObject*) object); - objc_rootWeakRelease((id) object); + +void swift::swift_unknownUnownedInit(UnownedReference *dest, void *value) { + if (!value) { + dest->Value = nullptr; + } else if (isObjCForUnownedReference(value)) { + ObjCUnownedReference::initialize(dest, (id) value); + } else { + swift_unownedInit(dest, (HeapObject*) value); + } } +void swift::swift_unknownUnownedAssign(UnownedReference *dest, void *value) { + if (!value) { + swift_unknownUnownedDestroy(dest); + dest->Value = nullptr; + } else if (isObjCForUnownedReference(value)) { + if (auto objcDest = dyn_cast(dest)) { + objc_storeWeak(&objcDest->storage()->WeakRef, (id) value); + } else { + swift_unownedDestroy(dest); + ObjCUnownedReference::initialize(dest, (id) value); + } + } else { + if (auto objcDest = dyn_cast(dest)) { + delete objcDest->storage(); + swift_unownedInit(dest, (HeapObject*) value); + } else { + swift_unownedAssign(dest, (HeapObject*) value); + } + } +} + +void *swift::swift_unknownUnownedLoadStrong(UnownedReference *ref) { + if (!ref->Value) { + return nullptr; + } else if (auto objcRef = dyn_cast(ref)) { + auto result = (void*) objc_loadWeakRetained(&objcRef->storage()->WeakRef); + if (result == nullptr) { + _swift_abortRetainUnowned(nullptr); + } + return result; + } else { + return swift_unownedLoadStrong(ref); + } +} + +void *swift::swift_unknownUnownedTakeStrong(UnownedReference *ref) { + if (!ref->Value) { + return nullptr; + } else if (auto objcRef = dyn_cast(ref)) { + auto storage = objcRef->storage(); + auto result = (void*) objc_loadWeakRetained(&objcRef->storage()->WeakRef); + if (result == nullptr) { + _swift_abortRetainUnowned(nullptr); + } + delete storage; + return result; + } else { + return swift_unownedTakeStrong(ref); + } +} + +void swift::swift_unknownUnownedDestroy(UnownedReference *ref) { + if (!ref->Value) { + // Nothing to do. + return; + } else if (auto objcRef = dyn_cast(ref)) { + delete objcRef->storage(); + } else { + swift_unownedDestroy(ref); + } +} + +void swift::swift_unknownUnownedCopyInit(UnownedReference *dest, + UnownedReference *src) { + assert(dest != src); + if (!src->Value) { + dest->Value = nullptr; + } else if (auto objcSrc = dyn_cast(src)) { + ObjCUnownedReference::initializeWithCopy(dest, objcSrc->storage()); + } else { + swift_unownedCopyInit(dest, src); + } +} + +void swift::swift_unknownUnownedTakeInit(UnownedReference *dest, + UnownedReference *src) { + assert(dest != src); + dest->Value = src->Value; +} + +void swift::swift_unknownUnownedCopyAssign(UnownedReference *dest, + UnownedReference *src) { + if (dest == src) return; + + if (auto objcSrc = dyn_cast(src)) { + if (auto objcDest = dyn_cast(dest)) { + // ObjC unfortunately doesn't expose a copy-assign operation. + objc_destroyWeak(&objcDest->storage()->WeakRef); + objc_copyWeak(&objcDest->storage()->WeakRef, + &objcSrc->storage()->WeakRef); + return; + } + + swift_unownedDestroy(dest); + ObjCUnownedReference::initializeWithCopy(dest, objcSrc->storage()); + } else { + if (auto objcDest = dyn_cast(dest)) { + delete objcDest->storage(); + swift_unownedCopyInit(dest, src); + } else { + swift_unownedCopyAssign(dest, src); + } + } +} + +void swift::swift_unknownUnownedTakeAssign(UnownedReference *dest, + UnownedReference *src) { + assert(dest != src); + + // There's not really anything more efficient to do here than this. + swift_unknownUnownedDestroy(dest); + dest->Value = src->Value; +} + +/*****************************************************************************/ +/****************************** WEAK REFERENCES ******************************/ +/*****************************************************************************/ + // FIXME: these are not really valid implementations; they assume too // much about the implementation of ObjC weak references, and the // loads from ->Value can race with clears by the runtime. @@ -845,6 +972,7 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { /*****************************************************************************/ /******************************* DYNAMIC CASTS *******************************/ /*****************************************************************************/ + #if SWIFT_OBJC_INTEROP const void * swift::swift_dynamicCastObjCClass(const void *object, @@ -891,18 +1019,14 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { return object; } -extern "C" bool swift_objcRespondsToSelector(id object, SEL selector) { - return [object respondsToSelector:selector]; -} - -extern "C" bool swift::_swift_objectConformsToObjCProtocol(const void *theObject, - const ProtocolDescriptor *protocol) { +bool swift::objectConformsToObjCProtocol(const void *theObject, + const ProtocolDescriptor *protocol) { return [((id) theObject) conformsToProtocol: (Protocol*) protocol]; } -extern "C" bool swift::_swift_classConformsToObjCProtocol(const void *theClass, - const ProtocolDescriptor *protocol) { +bool swift::classConformsToObjCProtocol(const void *theClass, + const ProtocolDescriptor *protocol) { return [((Class) theClass) conformsToProtocol: (Protocol*) protocol]; } @@ -926,6 +1050,7 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { // Other kinds of type can never conform to ObjC protocols. case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Tuple: case MetadataKind::Function: @@ -973,6 +1098,7 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { // Other kinds of type can never conform to ObjC protocols. case MetadataKind::Struct: case MetadataKind::Enum: + case MetadataKind::Optional: case MetadataKind::Opaque: case MetadataKind::Tuple: case MetadataKind::Function: @@ -1062,245 +1188,6 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { swift_dynamicCastFailure(source, dest); } - -static Demangle::NodePointer _buildDemanglingForMetadata(const Metadata *type); - -// Build a demangled type tree for a nominal type. -static Demangle::NodePointer -_buildDemanglingForNominalType(Demangle::Node::Kind boundGenericKind, - const Metadata *type, - const NominalTypeDescriptor *description) { - using namespace Demangle; - - // Demangle the base name. - auto node = demangleTypeAsNode(description->Name, - strlen(description->Name)); - // If generic, demangle the type parameters. - if (description->GenericParams.NumPrimaryParams > 0) { - auto typeParams = NodeFactory::create(Node::Kind::TypeList); - auto typeBytes = reinterpret_cast(type); - auto genericParam = reinterpret_cast( - typeBytes + sizeof(void*) * description->GenericParams.Offset); - for (unsigned i = 0, e = description->GenericParams.NumPrimaryParams; - i < e; ++i, ++genericParam) { - typeParams->addChild(_buildDemanglingForMetadata(*genericParam)); - } - - auto genericNode = NodeFactory::create(boundGenericKind); - genericNode->addChild(node); - genericNode->addChild(typeParams); - return genericNode; - } - return node; -} - -// Build a demangled type tree for a type. -static Demangle::NodePointer _buildDemanglingForMetadata(const Metadata *type) { - using namespace Demangle; - - switch (type->getKind()) { - case MetadataKind::Class: { - auto classType = static_cast(type); - return _buildDemanglingForNominalType(Node::Kind::BoundGenericClass, - type, classType->getDescription()); - } - case MetadataKind::Enum: { - auto structType = static_cast(type); - return _buildDemanglingForNominalType(Node::Kind::BoundGenericEnum, - type, structType->Description); - } - case MetadataKind::Struct: { - auto structType = static_cast(type); - return _buildDemanglingForNominalType(Node::Kind::BoundGenericStructure, - type, structType->Description); - } - case MetadataKind::ObjCClassWrapper: { -#if SWIFT_OBJC_INTEROP - auto objcWrapper = static_cast(type); - const char *className = class_getName((Class)objcWrapper->Class); - - // ObjC classes mangle as being in the magic "__ObjC" module. - auto module = NodeFactory::create(Node::Kind::Module, "__ObjC"); - - auto node = NodeFactory::create(Node::Kind::Class); - node->addChild(module); - node->addChild(NodeFactory::create(Node::Kind::Identifier, - llvm::StringRef(className))); - - return node; -#else - assert(false && "no ObjC interop"); - return nullptr; -#endif - } - case MetadataKind::ForeignClass: { - auto foreign = static_cast(type); - return Demangle::demangleTypeAsNode(foreign->getName(), - strlen(foreign->getName())); - } - case MetadataKind::Existential: { - auto exis = static_cast(type); - NodePointer proto_list = NodeFactory::create(Node::Kind::ProtocolList); - NodePointer type_list = NodeFactory::create(Node::Kind::TypeList); - - proto_list->addChild(type_list); - - std::vector protocols; - protocols.reserve(exis->Protocols.NumProtocols); - for (unsigned i = 0, e = exis->Protocols.NumProtocols; i < e; ++i) - protocols.push_back(exis->Protocols[i]); - - // Sort the protocols by their mangled names. - // The ordering in the existential type metadata is by metadata pointer, - // which isn't necessarily stable across invocations. - std::sort(protocols.begin(), protocols.end(), - [](const ProtocolDescriptor *a, const ProtocolDescriptor *b) -> bool { - return strcmp(a->Name, b->Name) < 0; - }); - - for (auto *protocol : protocols) { - // The protocol name is mangled as a type symbol, with the _Tt prefix. - auto protocolNode = demangleSymbolAsNode(protocol->Name, - strlen(protocol->Name)); - - // ObjC protocol names aren't mangled. - if (!protocolNode) { - auto module = NodeFactory::create(Node::Kind::Module, - MANGLING_MODULE_OBJC); - auto node = NodeFactory::create(Node::Kind::Protocol); - node->addChild(module); - node->addChild(NodeFactory::create(Node::Kind::Identifier, - llvm::StringRef(protocol->Name))); - auto typeNode = NodeFactory::create(Node::Kind::Type); - typeNode->addChild(node); - type_list->addChild(typeNode); - continue; - } - - // FIXME: We have to dig through a ridiculous number of nodes to get - // to the Protocol node here. - protocolNode = protocolNode->getChild(0); // Global -> TypeMangling - protocolNode = protocolNode->getChild(0); // TypeMangling -> Type - protocolNode = protocolNode->getChild(0); // Type -> ProtocolList - protocolNode = protocolNode->getChild(0); // ProtocolList -> TypeList - protocolNode = protocolNode->getChild(0); // TypeList -> Type - - assert(protocolNode->getKind() == Node::Kind::Type); - assert(protocolNode->getChild(0)->getKind() == Node::Kind::Protocol); - type_list->addChild(protocolNode); - } - - return proto_list; - } - case MetadataKind::ExistentialMetatype: { - auto metatype = static_cast(type); - auto instance = _buildDemanglingForMetadata(metatype->InstanceType); - auto node = NodeFactory::create(Node::Kind::ExistentialMetatype); - node->addChild(instance); - return node; - } - case MetadataKind::Function: { - auto func = static_cast(type); - - Node::Kind kind; - switch (func->getConvention()) { - case FunctionMetadataConvention::Swift: - kind = Node::Kind::FunctionType; - break; - case FunctionMetadataConvention::Block: - kind = Node::Kind::ObjCBlock; - break; - case FunctionMetadataConvention::CFunctionPointer: - kind = Node::Kind::CFunctionPointer; - break; - case FunctionMetadataConvention::Thin: - kind = Node::Kind::ThinFunctionType; - break; - } - - std::vector inputs; - for (unsigned i = 0, e = func->getNumArguments(); i < e; ++i) { - auto arg = func->getArguments()[i]; - auto input = _buildDemanglingForMetadata(arg.getPointer()); - if (arg.getFlag()) { - NodePointer inout = NodeFactory::create(Node::Kind::InOut); - inout->addChild(input); - input = inout; - } - inputs.push_back(input); - } - - NodePointer totalInput; - if (inputs.size() > 1) { - auto tuple = NodeFactory::create(Node::Kind::NonVariadicTuple); - for (auto &input : inputs) - tuple->addChild(input); - totalInput = tuple; - } else { - totalInput = inputs.front(); - } - - NodePointer args = NodeFactory::create(Node::Kind::ArgumentTuple); - args->addChild(totalInput); - - NodePointer resultTy = _buildDemanglingForMetadata(func->ResultType); - NodePointer result = NodeFactory::create(Node::Kind::ReturnType); - result->addChild(resultTy); - - auto funcNode = NodeFactory::create(kind); - if (func->throws()) - funcNode->addChild(NodeFactory::create(Node::Kind::ThrowsAnnotation)); - funcNode->addChild(args); - funcNode->addChild(result); - return funcNode; - } - case MetadataKind::Metatype: { - auto metatype = static_cast(type); - auto instance = _buildDemanglingForMetadata(metatype->InstanceType); - auto node = NodeFactory::create(Node::Kind::Metatype); - node->addChild(instance); - return node; - } - case MetadataKind::Tuple: { - auto tuple = static_cast(type); - auto tupleNode = NodeFactory::create(Node::Kind::NonVariadicTuple); - for (unsigned i = 0, e = tuple->NumElements; i < e; ++i) { - auto elt = _buildDemanglingForMetadata(tuple->getElement(i).Type); - tupleNode->addChild(elt); - } - return tupleNode; - } - case MetadataKind::Opaque: - // FIXME: Some opaque types do have manglings, but we don't have enough info - // to figure them out. - case MetadataKind::HeapLocalVariable: - case MetadataKind::HeapGenericLocalVariable: - case MetadataKind::ErrorObject: - break; - } - // Not a type. - return nullptr; -} - -extern "C" const char * -swift_getGenericClassObjCName(const ClassMetadata *clas) { - // Use the remangler to generate a mangled name from the type metadata. - auto demangling = _buildDemanglingForMetadata(clas); - - // Remangle that into a new type mangling string. - auto typeNode - = Demangle::NodeFactory::create(Demangle::Node::Kind::TypeMangling); - typeNode->addChild(demangling); - auto globalNode - = Demangle::NodeFactory::create(Demangle::Node::Kind::Global); - globalNode->addChild(typeNode); - - auto string = Demangle::mangleNode(globalNode); - - auto fullNameBuf = (char*)swift_slowAlloc(string.size() + 1, 0); - memcpy(fullNameBuf, string.c_str(), string.size() + 1); - return fullNameBuf; -} #endif const ClassMetadata * @@ -1321,26 +1208,23 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { return sourceType; } +#if SWIFT_OBJC_INTEROP // Given a non-nil object reference, return true iff the object uses // native swift reference counting. -bool swift::_swift_usesNativeSwiftReferenceCounting_nonNull( +static bool usesNativeSwiftReferenceCounting_nonNull( const void* object ) { - assert(object != nullptr); -#if SWIFT_OBJC_INTEROP - return !isObjCTaggedPointer(object) && - usesNativeSwiftReferenceCounting_allocated(object); -#else - return true; -#endif + assert(object != nullptr); + return !isObjCTaggedPointer(object) && + usesNativeSwiftReferenceCounting_allocated(object); } +#endif bool swift::swift_isUniquelyReferenced_nonNull_native( const HeapObject* object ) { assert(object != nullptr); assert(!object->refCount.isDeallocating()); - SWIFT_ISUNIQUELYREFERENCED(); return object->refCount.isUniquelyReferenced(); } @@ -1353,7 +1237,7 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { assert(object != nullptr); return #if SWIFT_OBJC_INTEROP - _swift_usesNativeSwiftReferenceCounting_nonNull(object) && + usesNativeSwiftReferenceCounting_nonNull(object) && #endif swift_isUniquelyReferenced_nonNull_native((HeapObject*)object); } @@ -1423,7 +1307,7 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { assert(object != nullptr); return #if SWIFT_OBJC_INTEROP - _swift_usesNativeSwiftReferenceCounting_nonNull(object) && + usesNativeSwiftReferenceCounting_nonNull(object) && #endif swift_isUniquelyReferencedOrPinned_nonNull_native( (const HeapObject*)object); @@ -1444,31 +1328,44 @@ static void doWeakDestroy(WeakReference *addr, bool valueIsNative) { /// pinned flag is set. bool swift::swift_isUniquelyReferencedOrPinned_nonNull_native( const HeapObject* object) { - SWIFT_ISUNIQUELYREFERENCEDORPINNED(); assert(object != nullptr); assert(!object->refCount.isDeallocating()); return object->refCount.isUniquelyReferencedOrPinned(); } -#if SWIFT_OBJC_INTEROP -/// Returns class_getInstanceSize(c) -/// -/// That function is otherwise unavailable to the core stdlib. -size_t swift::_swift_class_getInstancePositiveExtentSize(const void* c) { - return class_getInstanceSize((Class)c); -} -#endif +using ClassExtents = TwoWordPair; -extern "C" size_t _swift_class_getInstancePositiveExtentSize_native( - const Metadata *c) { +extern "C" +ClassExtents::Return +swift_class_getInstanceExtents(const Metadata *c) { assert(c && c->isClassObject()); auto metaData = c->getClassObject(); - return metaData->getInstanceSize() - metaData->getInstanceAddressPoint(); + return ClassExtents{ + metaData->getInstanceAddressPoint(), + metaData->getInstanceSize() - metaData->getInstanceAddressPoint() + }; } +#if SWIFT_OBJC_INTEROP +extern "C" +ClassExtents::Return +swift_objc_class_unknownGetInstanceExtents(const ClassMetadata* c) { + // Pure ObjC classes never have negative extents. + if (c->isPureObjC()) + return ClassExtents{0, class_getInstanceSize((Class)c)}; + + return swift_class_getInstanceExtents(c); +} +#endif + const ClassMetadata *swift::getRootSuperclass() { #if SWIFT_OBJC_INTEROP - return (const ClassMetadata *)[SwiftObject class]; + static Lazy SwiftObjectClass; + + return SwiftObjectClass.get([](void *ptr) { + *((const ClassMetadata **) ptr) = + (const ClassMetadata *)[SwiftObject class]; + }); #else return nullptr; #endif diff --git a/stdlib/public/runtime/SwiftRuntimeDTraceProbes.d b/stdlib/public/runtime/SwiftRuntimeDTraceProbes.d deleted file mode 100644 index cfe5236d4963c..0000000000000 --- a/stdlib/public/runtime/SwiftRuntimeDTraceProbes.d +++ /dev/null @@ -1,9 +0,0 @@ - -provider swift { - probe retain(); - probe release(); - probe allocateObject(); - probe deallocateObject(); - probe isUniquelyReferenced(); - probe isUniquelyReferencedOrPinned(); -}; diff --git a/stdlib/public/stubs/Assert.cpp b/stdlib/public/stubs/Assert.cpp new file mode 100644 index 0000000000000..c80ff44b97a8f --- /dev/null +++ b/stdlib/public/stubs/Assert.cpp @@ -0,0 +1,91 @@ +//===--- Assert.cpp - Assertion failure reporting -------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Implementation of +// +//===----------------------------------------------------------------------===// + +#include "swift/Runtime/Debug.h" +#include +#include +#include + +using namespace swift; + +// Report a fatal error to system console, stderr, and crash logs. +// : : file , line \n +// The message may be omitted by passing messageLength=0. +extern "C" void +_swift_stdlib_reportFatalErrorInFile(const char *prefix, intptr_t prefixLength, + const char *message, intptr_t messageLength, + const char *file, intptr_t fileLength, + uintptr_t line) { + char *log; + asprintf(&log, "%.*s: %.*s%sfile %.*s, line %zu\n", (int)prefixLength, prefix, + (int)messageLength, message, (messageLength ? ": " : ""), + (int)fileLength, file, (size_t)line); + + swift_reportError(log); + free(log); +} + +// Report a fatal error to system console, stderr, and crash logs. +// : : file , line \n +// The message may be omitted by passing messageLength=0. +extern "C" void +_swift_stdlib_reportFatalError(const char *prefix, + intptr_t prefixLength, + const char *message, + intptr_t messageLength) { + char *log; + asprintf(&log, "%.*s: %.*s\n", (int)prefixLength, prefix, + (int)messageLength, message); + + swift_reportError(log); + free(log); +} + +// Report a call to an unimplemented initializer. +// : : : fatal error: use of unimplemented +// initializer '' for class 'className' +extern "C" void +_swift_stdlib_reportUnimplementedInitializerInFile( + const char *className, intptr_t classNameLength, const char *initName, + intptr_t initNameLength, const char *file, intptr_t fileLength, + uintptr_t line, uintptr_t column) { + char *log; + asprintf(&log, "%.*s: %zu: %zu: fatal error: use of unimplemented " + "initializer '%.*s' for class '%.*s'\n", + (int)fileLength, file, (size_t)line, (size_t)column, + (int)initNameLength, initName, (int)classNameLength, className); + + swift_reportError(log); + free(log); +} + +// Report a call to an unimplemented initializer. +// fatal error: use of unimplemented initializer '' for class +// 'className' +extern "C" void +_swift_stdlib_reportUnimplementedInitializer(const char *className, + intptr_t classNameLength, + const char *initName, + intptr_t initNameLength) { + char *log; + asprintf(&log, "fatal error: use of unimplemented " + "initializer '%.*s' for class '%.*s'\n", + (int)initNameLength, initName, (int)classNameLength, className); + + swift_reportError(log); + free(log); +} + diff --git a/stdlib/public/stubs/Availability.mm b/stdlib/public/stubs/Availability.mm index d76d0b1a4ac91..3d13741bde8c4 100644 --- a/stdlib/public/stubs/Availability.mm +++ b/stdlib/public/stubs/Availability.mm @@ -1,8 +1,8 @@ -//===--- Availability.mm - Swift Language API Availability Support---------===// +//===--- Availability.mm - Swift Language API Availability Support --------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/stubs/CMakeLists.txt b/stdlib/public/stubs/CMakeLists.txt index e61398e569608..4de51baec354e 100644 --- a/stdlib/public/stubs/CMakeLists.txt +++ b/stdlib/public/stubs/CMakeLists.txt @@ -1,19 +1,35 @@ set(swift_stubs_objc_sources) +set(swift_stubs_unicode_normalization_sources) +set(swift_stubs_link_libraries) if(SWIFT_HOST_VARIANT MATCHES "${SWIFT_DARWIN_VARIANTS}") set(swift_stubs_objc_sources Availability.mm FoundationHelpers.mm SwiftNativeNSXXXBase.mm.gyb) + set(LLVM_OPTIONAL_SOURCES + UnicodeNormalization.cpp) +else() + find_package(ICU REQUIRED COMPONENTS uc i18n) + set(swift_stubs_unicode_normalization_sources + UnicodeNormalization.cpp) + set(swift_stubs_link_libraries + ${ICU_UC_LIBRARY} ${ICU_I18N_LIBRARY}) + include_directories( + ${ICU_UC_INCLUDE_DIR} ${ICU_I18N_INCLUDE_DIR}) endif() add_swift_library(swiftStdlibStubs IS_STDLIB IS_STDLIB_CORE + Assert.cpp GlobalObjects.cpp LibcShims.cpp Stubs.cpp + UnicodeExtendedGraphemeClusters.cpp.gyb android_support/Android_log2.cpp android_support/Android_log2f.cpp ${swift_stubs_objc_sources} + ${swift_stubs_unicode_normalization_sources} C_COMPILE_FLAGS ${SWIFT_CORE_CXX_FLAGS} + LINK_LIBRARIES ${swift_stubs_link_libraries} INSTALL_IN_COMPONENT stdlib) diff --git a/stdlib/public/stubs/FoundationHelpers.mm b/stdlib/public/stubs/FoundationHelpers.mm index 4974b9a308740..be4b18ef102c8 100644 --- a/stdlib/public/stubs/FoundationHelpers.mm +++ b/stdlib/public/stubs/FoundationHelpers.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/stubs/GlobalObjects.cpp b/stdlib/public/stubs/GlobalObjects.cpp index 2ff75573d878c..02e04cd63c51d 100644 --- a/stdlib/public/stubs/GlobalObjects.cpp +++ b/stdlib/public/stubs/GlobalObjects.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/stubs/LibcShims.cpp b/stdlib/public/stubs/LibcShims.cpp index b816f91451194..5f6a40e0a4dc6 100644 --- a/stdlib/public/stubs/LibcShims.cpp +++ b/stdlib/public/stubs/LibcShims.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -66,6 +66,11 @@ size_t _swift_stdlib_malloc_size(const void *ptr) { return malloc_size(ptr); } size_t _swift_stdlib_malloc_size(const void *ptr) { return malloc_usable_size(const_cast(ptr)); } +#elif defined(__FreeBSD__) +#include +size_t _swift_stdlib_malloc_size(const void *ptr) { + return malloc_usable_size(const_cast(ptr)); +} #elif defined(__ANDROID__) // on Android before API 21 malloc_usable_size is exported by this name size_t _swift_stdlib_malloc_size(const void *ptr) { diff --git a/stdlib/public/stubs/Stubs.cpp b/stdlib/public/stubs/Stubs.cpp index 6ceb7c0e3bb97..a73819b47c630 100644 --- a/stdlib/public/stubs/Stubs.cpp +++ b/stdlib/public/stubs/Stubs.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,10 +16,15 @@ // //===----------------------------------------------------------------------===// +#if defined(__FreeBSD__) +#define _WITH_GETLINE +#endif + #include #include #include #include +#include #include #include #include @@ -164,12 +169,16 @@ static int swift_snprintf_l(char *Str, size_t StrSize, locale_t Locale, template static uint64_t swift_floatingPointToString(char *Buffer, size_t BufferLength, - T Value, const char *Format) { + T Value, const char *Format, + bool Debug) { if (BufferLength < 32) swift::crash("swift_floatingPointToString: insufficient buffer size"); - const int Precision = std::numeric_limits::digits10; - + int Precision = std::numeric_limits::digits10; + if (Debug) { + Precision = std::numeric_limits::max_digits10; + } + // Pass a null locale to use the C locale. int i = swift_snprintf_l(Buffer, BufferLength, /*locale=*/nullptr, Format, Precision, Value); @@ -193,28 +202,28 @@ static uint64_t swift_floatingPointToString(char *Buffer, size_t BufferLength, } extern "C" uint64_t swift_float32ToString(char *Buffer, size_t BufferLength, - float Value) { + float Value, bool Debug) { return swift_floatingPointToString(Buffer, BufferLength, Value, - "%0.*g"); + "%0.*g", Debug); } extern "C" uint64_t swift_float64ToString(char *Buffer, size_t BufferLength, - double Value) { + double Value, bool Debug) { return swift_floatingPointToString(Buffer, BufferLength, Value, - "%0.*g"); + "%0.*g", Debug); } extern "C" uint64_t swift_float80ToString(char *Buffer, size_t BufferLength, - long double Value) { + long double Value, bool Debug) { return swift_floatingPointToString(Buffer, BufferLength, Value, - "%0.*Lg"); + "%0.*Lg", Debug); } /// \param[out] LinePtr Replaced with the pointer to the malloc()-allocated /// line. Can be NULL if no characters were read. /// /// \returns Size of character data returned in \c LinePtr, or -1 -/// if an error occured, or EOF was reached. +/// if an error occurred, or EOF was reached. extern "C" ssize_t swift_stdlib_readLine_stdin(char **LinePtr) { size_t Capacity = 0; return getline(LinePtr, &Capacity, stdin); @@ -239,7 +248,10 @@ extern "C" long double _swift_fmodl(long double lhs, long double rhs) { // This implementation is copied here to avoid a new dependency // on compiler-rt on Linux. // FIXME: rdar://14883575 Libcompiler_rt omits muloti4 -#if __arm64__ || (!defined(__APPLE__) && !defined(__ANDROID__)) +#if (defined(__APPLE__) && defined(__arm64__)) || \ + (defined(__ANDROID__) && defined(__arm64__)) || \ + (defined(__linux__) && defined(__x86_64__)) || \ + (defined(__linux__) && defined(__aarch64__)) typedef int ti_int __attribute__ ((mode (TI))); extern "C" @@ -284,6 +296,54 @@ __muloti4(ti_int a, ti_int b, int* overflow) #endif +#if defined(__linux__) && defined(__arm__) && !defined(__ANDROID__) +// Similar to above, but with mulodi4. Perhaps this is +// something that shouldn't be done, and is a bandaid over +// some other lower-level architecture issue that I'm +// missing. Perhaps relevant bug report: +// FIXME: https://llvm.org/bugs/show_bug.cgi?id=14469 +typedef int di_int __attribute__ ((mode (DI))); +extern "C" +di_int +__mulodi4(di_int a, di_int b, int* overflow) +{ + const int N = (int)(sizeof(di_int) * CHAR_BIT); + const di_int MIN = (di_int)1 << (N-1); + const di_int MAX = ~MIN; + *overflow = 0; + di_int result = a * b; + if (a == MIN) + { + if (b != 0 && b != 1) + *overflow = 1; + return result; + } + if (b == MIN) + { + if (a != 0 && a != 1) + *overflow = 1; + return result; + } + di_int sa = a >> (N - 1); + di_int abs_a = (a ^ sa) - sa; + di_int sb = b >> (N - 1); + di_int abs_b = (b ^ sb) - sb; + if (abs_a < 2 || abs_b < 2) + return result; + if (sa == sb) + { + if (abs_a > MAX / abs_b) + *overflow = 1; + } + else + { + if (abs_a > MIN / -abs_b) + *overflow = 1; + } + return result; +} +#endif + // We can't return Float80, but we can receive a pointer to one, so // switch the return type and the out parameter on strtold. template @@ -297,7 +357,7 @@ static const char *_swift_stdlib_strtoX_clocale_impl( *outResult = result; if (result == huge || result == -huge || result == 0.0 || result == -0.0) { if (errno == ERANGE) - EndPtr = NULL; + EndPtr = nullptr; } return EndPtr; } diff --git a/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb b/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb index d4c0ec2ffe7e4..43611e9925517 100644 --- a/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb +++ b/stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -74,6 +74,15 @@ using namespace swift; auto SELF = reinterpret_cast(self); return (bool)swift_tryRetain(SELF); } +- (BOOL)_isDeallocating { + return swift_isDeallocating(reinterpret_cast(self)); +} +- (BOOL)allowsWeakReference { + return !swift_isDeallocating(reinterpret_cast(self)); +} +- (BOOL)retainWeakReference { + return swift_tryRetain(reinterpret_cast(self)) != nullptr; +} #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wobjc-missing-super-calls" diff --git a/stdlib/public/runtime/UnicodeExtendedGraphemeClusters.cpp.gyb b/stdlib/public/stubs/UnicodeExtendedGraphemeClusters.cpp.gyb similarity index 96% rename from stdlib/public/runtime/UnicodeExtendedGraphemeClusters.cpp.gyb rename to stdlib/public/stubs/UnicodeExtendedGraphemeClusters.cpp.gyb index 75f6d5384355e..28e86984c0021 100644 --- a/stdlib/public/runtime/UnicodeExtendedGraphemeClusters.cpp.gyb +++ b/stdlib/public/stubs/UnicodeExtendedGraphemeClusters.cpp.gyb @@ -1,8 +1,8 @@ -//===- UnicodeExtendedGraphemeClusters.cpp.gyb ------------------*- c++ -*-===// +//===--- UnicodeExtendedGraphemeClusters.cpp.gyb ----------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/stdlib/public/runtime/UnicodeNormalization.cpp b/stdlib/public/stubs/UnicodeNormalization.cpp similarity index 97% rename from stdlib/public/runtime/UnicodeNormalization.cpp rename to stdlib/public/stubs/UnicodeNormalization.cpp index f0d62844c2318..74caec310fa3f 100644 --- a/stdlib/public/runtime/UnicodeNormalization.cpp +++ b/stdlib/public/stubs/UnicodeNormalization.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -72,13 +72,13 @@ class ASCIICollation { public: static const ASCIICollation *getTable() { - // We are reallying on C++11's guarantueed of thread safe static variable + // We are reallying on C++11's guaranteed of thread safe static variable // initialization. static ASCIICollation collation; return &collation; } - /// Maps an ASCII character to an collation element priority as would be + /// Maps an ASCII character to a collation element priority as would be /// returned by a call to ucol_next(). int32_t map(unsigned char c) const { return CollationTable[c]; @@ -287,7 +287,7 @@ int32_t _swift_stdlib_unicode_strToUpper(uint16_t *Destination, /// Convert the unicode string to lowercase. This function will return the /// required buffer length as a result. If this length does not match the /// 'DestinationCapacity' this function must be called again with a buffer of -/// the required length to get an lowercase version of the string. +/// the required length to get a lowercase version of the string. extern "C" int32_t _swift_stdlib_unicode_strToLower(uint16_t *Destination, int32_t DestinationCapacity, diff --git a/test/1_stdlib/ArrayBridge.swift b/test/1_stdlib/ArrayBridge.swift index 7a0255a6047ad..402b63c9ba2d3 100644 --- a/test/1_stdlib/ArrayBridge.swift +++ b/test/1_stdlib/ArrayBridge.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -47,14 +47,15 @@ class Tracked : NSObject, Fooable { func foo() { } required init(_ value: Int) { - ++trackedCount - serialNumber = ++nextTrackedSerialNumber + trackedCount += 1 + nextTrackedSerialNumber += 1 + serialNumber = nextTrackedSerialNumber self.value = value } deinit { assert(serialNumber > 0, "double destruction!") - --trackedCount + trackedCount -= 1 serialNumber = -serialNumber } @@ -102,7 +103,7 @@ struct BridgedSwift : CustomStringConvertible, _ObjectiveCBridgeable { } func _bridgeToObjectiveC() -> BridgedObjC { - ++bridgeToOperationCount + bridgeToOperationCount += 1 return BridgedObjC(trak.value) } @@ -115,7 +116,7 @@ struct BridgedSwift : CustomStringConvertible, _ObjectiveCBridgeable { inout result: BridgedSwift? ) { assert(x.value >= 0, "not bridged") - ++bridgeFromOperationCount + bridgeFromOperationCount += 1 result = BridgedSwift(x.value) } @@ -527,7 +528,7 @@ func testRoundTrip() { } } - var test = Test() + let test = Test() let array = [ BridgedSwift(10), BridgedSwift(20), BridgedSwift(30), @@ -555,7 +556,7 @@ print(x.objectAtIndex(0) as Base) */ func testMutableArray() { - var m = NSMutableArray(array: ["fu", "bar", "buzz"]) + let m = NSMutableArray(array: ["fu", "bar", "buzz"]) let a = m as NSArray as! [NSString] print(a) // CHECK-NEXT: [fu, bar, buzz] m.addObject("goop") diff --git a/test/1_stdlib/ArrayCore.swift b/test/1_stdlib/ArrayCore.swift index ae8759cce0cd8..0a15b62f5ccda 100644 --- a/test/1_stdlib/ArrayCore.swift +++ b/test/1_stdlib/ArrayCore.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,14 +23,15 @@ var nextTrackedSerialNumber = 0 final class Tracked : ForwardIndexType, CustomStringConvertible { required init(_ value: Int) { - ++trackedCount - serialNumber = ++nextTrackedSerialNumber + trackedCount += 1 + nextTrackedSerialNumber += 1 + serialNumber = nextTrackedSerialNumber self.value = value } deinit { assert(serialNumber > 0, "double destruction!") - --trackedCount + trackedCount -= 1 serialNumber = -serialNumber } diff --git a/test/1_stdlib/ArrayTraps.swift.gyb b/test/1_stdlib/ArrayTraps.swift.gyb index f21e2ed9fc426..e6f930fc7e85b 100644 --- a/test/1_stdlib/ArrayTraps.swift.gyb +++ b/test/1_stdlib/ArrayTraps.swift.gyb @@ -238,14 +238,14 @@ class ElementClass : BaseClass { } } -class ViolateInoutSafeySwitchToObjcBuffer { +class ViolateInoutSafetySwitchToObjcBuffer { final var anArray: [ElementClass] = [] let nsArray = NSArray( objects: ElementClass("a"), ElementClass("b"), ElementClass("c")) @inline(never) - func accessArrayViaInoutVolation() { + func accessArrayViaInoutViolation() { anArray = _convertNSArrayToArray(nsArray) } @@ -255,9 +255,11 @@ class ViolateInoutSafeySwitchToObjcBuffer { // loop calls a function that violates inout safety and overrides the array. let isNativeTypeChecked = A._hoistableIsNativeTypeChecked() for i in 0.. 0, "double destruction!") - --trackedCount + trackedCount -= 1 serialNumber = -serialNumber } @@ -111,12 +112,12 @@ func testScope() { // We can get a single element out // CHECK-NEXT: nsx[0]: 1 . - var one = nsx.objectAtIndex(0) as! Tracked + let one = nsx.objectAtIndex(0) as! Tracked print("nsx[0]: \(one.value) .") // We can get the element again, but it may not have the same identity // CHECK-NEXT: object identity matches? - var anotherOne = nsx.objectAtIndex(0) as! Tracked + let anotherOne = nsx.objectAtIndex(0) as! Tracked print("object identity matches? \(one === anotherOne)") // Because the elements come back at +0, we really don't want to @@ -125,7 +126,7 @@ func testScope() { objects.withUnsafeMutableBufferPointer { // FIXME: Can't elide signature and use $0 here - (inout buf: UnsafeMutableBufferPointer)->() in + (inout buf: UnsafeMutableBufferPointer) -> () in nsx.getObjects( UnsafeMutablePointer(buf.baseAddress), range: _SwiftNSRange(location: 1, length: 2)) diff --git a/test/1_stdlib/BridgeStorage.swift.gyb b/test/1_stdlib/BridgeStorage.swift.gyb index 26fd3890d86bf..2db4152ffed8e 100644 --- a/test/1_stdlib/BridgeStorage.swift.gyb +++ b/test/1_stdlib/BridgeStorage.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -48,79 +48,6 @@ protocol BridgeStorage { extension _BridgeStorage : BridgeStorage {} -struct BridgeObject - : BridgeStorage { - - typealias Native = NativeType - typealias ObjC = ObjCType - - init(native: Native, bits: Int) { - _sanityCheck( - bits >= 0 && bits < 2, - "BridgeObject can't store bits outside the range 0-1") - - self.object = native - self.bits = UInt8(truncatingBitPattern: bits) - } - - init(native: Native) { - self.object = native - self.bits = 0 - } - - init(objC: ObjC) { - self.object = objC - self.bits = 0 - } - - mutating func isUniquelyReferencedNative() -> Bool { - return _getBool(Builtin.isUnique(&object)) - } - - var isNative: Bool { - return _swift_usesNativeSwiftReferenceCounting_nonNull( - UnsafePointer(rawObject)) - } - - var isObjC: Bool { - return !isNative - } - - var nativeInstance: Native { - precondition(isNative) - return Builtin.bridgeFromRawPointer(rawObject) - } - - var nativeInstance_noSpareBits: Native { - precondition(isNative) - precondition(spareBits == 0) - return Builtin.bridgeFromRawPointer(rawObject) - } - - mutating func isUniquelyReferenced_native_noSpareBits() -> Bool { - precondition(isNative) - precondition(spareBits == 0) - return _isUnique_native(&object) - } - - var objCInstance: ObjC { - precondition(isObjC) - return Builtin.bridgeFromRawPointer(rawObject) - } - - var spareBits: Int { - return Int(bits) - } - - var rawObject: Builtin.RawPointer { - return Builtin.bridgeToRawPointer(object) - } - - // object declared mutable to be passed to isUnique. - var object: AnyObject - let bits: UInt8 -} - //===----------------------------------------------------------------------===// //===--- Testing code -----------------------------------------------------===// //===----------------------------------------------------------------------===// @@ -192,7 +119,7 @@ var unTaggedNSString : NSString { return expectTagged("fûtbōl" as NSString, false) } -% for Self in '_BridgeStorage', 'BridgeObject': +% for Self in ['_BridgeStorage']: allTests.test("${Self}") { typealias B = ${Self} diff --git a/test/1_stdlib/Builtins.swift b/test/1_stdlib/Builtins.swift index d074460077f77..8b22920d89760 100644 --- a/test/1_stdlib/Builtins.swift +++ b/test/1_stdlib/Builtins.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -119,8 +119,8 @@ var NoisyDeathCount = 0 protocol P {} class Noisy : P { - init() { ++NoisyLifeCount } - deinit { ++NoisyDeathCount } + init() { NoisyLifeCount += 1 } + deinit { NoisyDeathCount += 1} } struct Large : P { @@ -277,4 +277,14 @@ tests.test("_isPOD") { expectFalse(_isPOD(P.self)) } +tests.test("_isOptional") { + expectTrue(_isOptional(Optional.self)) + expectTrue(_isOptional(Optional.self)) + expectTrue(_isOptional(Optional

.self)) + expectTrue(_isOptional(ImplicitlyUnwrappedOptional

.self)) + expectFalse(_isOptional(Int.self)) + expectFalse(_isOptional(X.self)) + expectFalse(_isOptional(P.self)) +} + runAllTests() diff --git a/test/1_stdlib/CastTraps.swift.gyb b/test/1_stdlib/CastTraps.swift.gyb index 8c2ef8abe1e0d..1a891aeaa2936 100644 --- a/test/1_stdlib/CastTraps.swift.gyb +++ b/test/1_stdlib/CastTraps.swift.gyb @@ -11,6 +11,15 @@ // XFAIL: linux import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import Foundation diff --git a/test/1_stdlib/Character.swift b/test/1_stdlib/Character.swift index 791d9b12641a7..897ef1c1b2aba 100644 --- a/test/1_stdlib/Character.swift +++ b/test/1_stdlib/Character.swift @@ -7,6 +7,13 @@ import StdlibUnittest import Swift import SwiftPrivate +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +#if _runtime(_ObjC) +import ObjectiveC +#endif + //===--- // Utilities. //===--- diff --git a/test/1_stdlib/Collection.swift b/test/1_stdlib/Collection.swift index ef08005a6a540..1daad9ca9d3de 100644 --- a/test/1_stdlib/Collection.swift +++ b/test/1_stdlib/Collection.swift @@ -1,6 +1,13 @@ -// RUN: %target-run-simple-swift | FileCheck %s +// RUN: %target-run-simple-swift --stdlib-unittest-in-process | tee %t.txt +// RUN: FileCheck %s < %t.txt +// note: remove the --stdlib-unittest-in-process once all the FileCheck tests +// have been converted to StdlibUnittest // REQUIRES: executable_test +import StdlibUnittest + +var CollectionTests = TestSuite("CollectionTests") + struct X : CollectionType { typealias Element = String.CharacterView.Generator.Element typealias Index = String.Index @@ -45,7 +52,7 @@ func isPalindrome0< >(seq: S) -> Bool { typealias Index = S.Index - var a = seq.indices + let a = seq.indices var i = seq.indices var ir = i.lazy.reverse() var b = ir.generate() @@ -111,12 +118,14 @@ func isPalindrome2< var b = seq.startIndex, e = seq.endIndex while (b != e) { - if (b == --e) { + e = e.predecessor() + if (b == e) { break } - if seq[b++] != seq[e] { + if seq[b] != seq[e] { return false } + b = b.successor() } return true } @@ -200,5 +209,38 @@ func testIsEmptyFirstLast() { } testIsEmptyFirstLast() +/// A `CollectionType` that vends just the default implementations for +/// `CollectionType` methods. +struct CollectionOnly : CollectionType { + var base: T + + var startIndex: T.Index { + return base.startIndex + } + + var endIndex: T.Index { + return base.endIndex + } + + func generate() -> T.Generator { + return base.generate() + } + + subscript(position: T.Index) -> T.Generator.Element { + return base[position] + } +} + // CHECK: all done. print("all done.") + +CollectionTests.test("first/performance") { + // accessing `first` should not perform duplicate work on lazy collections + var log: [Int] = [] + let col_ = (0..<10).lazy.filter({ log.append($0); return (2..<8).contains($0) }) + let col = CollectionOnly(base: col_) + expectEqual(2, col.first) + expectEqual([0, 1, 2], log) +} + +runAllTests() diff --git a/test/1_stdlib/CollectionDiagnostics.swift b/test/1_stdlib/CollectionDiagnostics.swift index 1c4d8b7717065..5a0235a081cf8 100644 --- a/test/1_stdlib/CollectionDiagnostics.swift +++ b/test/1_stdlib/CollectionDiagnostics.swift @@ -369,7 +369,7 @@ func renamedRangeReplaceableCollectionTypeMethods(c: DefaultedForwardRangeReplac } func renamedAnyGenerator(g: G) { - _ = anyGenerator(g) // expected-error {{'anyGenerator' has been renamed to 'AnyGenerator'}} - _ = anyGenerator { 1 } // expected-error {{'anyGenerator' has been renamed to 'AnyGenerator'}} + _ = anyGenerator(g) // expected-warning {{'anyGenerator' is deprecated: renamed to 'AnyGenerator'}} expected-note {{use 'AnyGenerator' instead}} + _ = anyGenerator { 1 } // expected-warning {{'anyGenerator' is deprecated: renamed to 'AnyGenerator'}} expected-note {{use 'AnyGenerator' instead}} } diff --git a/test/1_stdlib/CollectionOfOne.swift b/test/1_stdlib/CollectionOfOne.swift index 7786ada0a212d..e003cf5f91554 100644 --- a/test/1_stdlib/CollectionOfOne.swift +++ b/test/1_stdlib/CollectionOfOne.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/DictionaryLiteral.swift b/test/1_stdlib/DictionaryLiteral.swift index ef8705c63a534..3fb60fe1b56ca 100644 --- a/test/1_stdlib/DictionaryLiteral.swift +++ b/test/1_stdlib/DictionaryLiteral.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Dispatch.swift b/test/1_stdlib/Dispatch.swift index 4874d07771f00..e7756fa4729e8 100644 --- a/test/1_stdlib/Dispatch.swift +++ b/test/1_stdlib/Dispatch.swift @@ -32,7 +32,7 @@ DispatchAPI.test("OS_OBJECT support") { DispatchAPI.test("dispatch_block_t conversions") { var counter = 0 let closure = { () -> Void in - counter++ + counter += 1 } let block = closure as dispatch_block_t @@ -59,7 +59,7 @@ if #available(OSX 10.10, iOS 8.0, *) { var counter = 0 let block = dispatch_block_create(dispatch_block_flags_t(0)) { - counter++ + counter += 1 } block() expectEqual(1, counter) diff --git a/test/1_stdlib/ErrorHandling.swift b/test/1_stdlib/ErrorHandling.swift index b8c9113a1e7c2..baf4acea82964 100644 --- a/test/1_stdlib/ErrorHandling.swift +++ b/test/1_stdlib/ErrorHandling.swift @@ -7,11 +7,19 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var NoisyCount = 0 class Noisy { - init() { NoisyCount++ } - deinit { NoisyCount-- } + init() { NoisyCount += 1 } + deinit { NoisyCount -= 1 } } enum SillyError: ErrorType { case JazzHands } @@ -127,7 +135,7 @@ ErrorHandlingTests.test("ErrorHandling/forEach") { var loopCount = 0 do { try [1, 2, 3].forEach { - ++loopCount + loopCount += 1 if $0 == 2 { throw SillyError.JazzHands } @@ -143,7 +151,7 @@ ErrorHandlingTests.test("ErrorHandling/Optional flatMap") { var loopCount = 0 do { let _: [Int] = try [1, 2, 3].flatMap { - ++loopCount + loopCount += 1 if $0 == 2 { throw SillyError.JazzHands } @@ -159,7 +167,7 @@ ErrorHandlingTests.test("ErrorHandling/Array flatMap") { var loopCount = 0 do { let _: [Int] = try [1, 2, 3].flatMap {(x) -> [Int] in - ++loopCount + loopCount += 1 if x == 2 { throw SillyError.JazzHands } @@ -235,7 +243,7 @@ ErrorHandlingTests.test("ErrorHandling/reduce") { let x: Int = try [1, 2, 3, 4, 5].reduce(0, combine: { (x: Int, y: Int) -> Int in - ++loopCount + loopCount += 1 var total = x + y if total > 5 { throw SillyError.JazzHands @@ -287,7 +295,7 @@ ErrorHandlingTests.test("ErrorHandling/Sequence map") { if loopCount == throwAtCount { throw SillyError.JazzHands } - ++loopCount + loopCount += 1 return Noisy() } expectEqual(NoisyCount, initialCount + 3) @@ -308,7 +316,7 @@ ErrorHandlingTests.test("ErrorHandling/Sequence filter") { if loopCount == throwAtCount { throw SillyError.JazzHands } - ++loopCount + loopCount += 1 return condition } expectEqual(NoisyCount, initialCount + sequence.count) @@ -329,7 +337,7 @@ ErrorHandlingTests.test("ErrorHandling/Collection map") { if loopCount == throwAtCount { throw SillyError.JazzHands } - ++loopCount + loopCount += 1 return Noisy() } expectEqual(NoisyCount, initialCount + 3) diff --git a/test/1_stdlib/ErrorType.swift b/test/1_stdlib/ErrorType.swift index f8430af9deb81..155f9ca43c52e 100644 --- a/test/1_stdlib/ErrorType.swift +++ b/test/1_stdlib/ErrorType.swift @@ -3,6 +3,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var ErrorTypeTests = TestSuite("ErrorType") var NoisyErrorLifeCount = 0 @@ -17,8 +25,8 @@ protocol OtherClassProtocol : class { } class NoisyError : ErrorType, OtherProtocol, OtherClassProtocol { - init() { ++NoisyErrorLifeCount } - deinit { ++NoisyErrorDeathCount } + init() { NoisyErrorLifeCount += 1 } + deinit { NoisyErrorDeathCount += 1 } let _domain = "NoisyError" let _code = 123 diff --git a/test/1_stdlib/ErrorTypeBridging.swift b/test/1_stdlib/ErrorTypeBridging.swift index 1355bfe993de0..99df736f1abae 100644 --- a/test/1_stdlib/ErrorTypeBridging.swift +++ b/test/1_stdlib/ErrorTypeBridging.swift @@ -22,8 +22,8 @@ protocol OtherClassProtocol : class { } class NoisyError : ErrorType, OtherProtocol, OtherClassProtocol { - init() { ++NoisyErrorLifeCount } - deinit { ++NoisyErrorDeathCount } + init() { NoisyErrorLifeCount += 1 } + deinit { NoisyErrorDeathCount += 1 } let _domain = "NoisyError" let _code = 123 diff --git a/test/1_stdlib/ExistentialCollection.swift b/test/1_stdlib/ExistentialCollection.swift index 63093347bbc94..ea8fa9a72c352 100644 --- a/test/1_stdlib/ExistentialCollection.swift +++ b/test/1_stdlib/ExistentialCollection.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -14,6 +14,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + // Check that the generic parameter is called 'Element'. protocol TestProtocol1 {} @@ -62,7 +70,11 @@ tests.test("AnyGenerator") { expectEqual(["0", "1", "2", "3", "4"], Array(countStrings())) var x = 7 - let g = AnyGenerator { x < 15 ? x++ : nil } + let g = AnyGenerator { + if x >= 15 { return nil } + x += 1 + return x-1 + } expectEqual([ 7, 8, 9, 10, 11, 12, 13, 14 ], Array(g)) } @@ -88,32 +100,32 @@ struct InstrumentedIndex : RandomAccessIndexType { } func successor() -> InstrumentedIndex { - ++callCounts["successor"]! + callCounts["successor"]! += 1 return InstrumentedIndex(base.successor()) } mutating func _successorInPlace() { - ++callCounts["_successorInPlace"]! + callCounts["_successorInPlace"]! += 1 base._successorInPlace() } func predecessor() -> InstrumentedIndex { - ++callCounts["predecessor"]! + callCounts["predecessor"]! += 1 return InstrumentedIndex(base.predecessor()) } mutating func _predecessorInPlace() { - ++callCounts["_predecessorInPlace"]! + callCounts["_predecessorInPlace"]! += 1 base._predecessorInPlace() } func advancedBy(distance: Distance) -> InstrumentedIndex { - ++callCounts["advancedBy"]! + callCounts["advancedBy"]! += 1 return InstrumentedIndex(base.advancedBy(distance)) } func distanceTo(other: InstrumentedIndex) -> Distance { - ++callCounts["distanceTo"]! + callCounts["distanceTo"]! += 1 return base.distanceTo(other.base) } } @@ -159,10 +171,11 @@ tests.test("ForwardIndex") { i = i.successor() expectEqual(1, callCounts["successor"]) expectEqual(0, callCounts["_successorInPlace"]) - ++i + i._successorInPlace() expectEqual(1, callCounts["successor"]) expectEqual(1, callCounts["_successorInPlace"]) - var x = i++ + var x = i + i = i.successor() expectEqual(2, callCounts["successor"]) expectEqual(1, callCounts["_successorInPlace"]) _blackHole(x) @@ -176,10 +189,11 @@ tests.test("BidirectionalIndex") { i = i.predecessor() expectEqual(1, callCounts["predecessor"]) expectEqual(0, callCounts["_predecessorInPlace"]) - --i + i._predecessorInPlace() expectEqual(1, callCounts["predecessor"]) expectEqual(1, callCounts["_predecessorInPlace"]) - var x = i-- + var x = i + i = i.predecessor() expectEqual(2, callCounts["predecessor"]) expectEqual(1, callCounts["_predecessorInPlace"]) _blackHole(x) diff --git a/test/1_stdlib/Experimental.swift b/test/1_stdlib/Experimental.swift index 494353dbcbb79..9d717fe076172 100644 --- a/test/1_stdlib/Experimental.swift +++ b/test/1_stdlib/Experimental.swift @@ -4,6 +4,14 @@ import SwiftExperimental import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var ExperimentalTestSuite = TestSuite("Experimental") ExperimentalTestSuite.test("ComposeOperator/SmokeTest") { @@ -38,8 +46,8 @@ ExperimentalTestSuite.test("ComposeOperator/CountCalls") { var aCalled = 0 var bCalled = 0 - func a(_: A) -> B { ++aCalled; return B() } - func b(_: B) -> C { ++bCalled; return C() } + func a(_: A) -> B { aCalled += 1; return B() } + func b(_: B) -> C { bCalled += 1; return C() } var result = b ∘ a expectEqual(0, aCalled) @@ -56,8 +64,8 @@ struct C {} var aCalled = 0 var bCalled = 0 -func a(_: A) -> B { ++aCalled; return B() } -func b(_: B) -> C { ++bCalled; return C() } +func a(_: A) -> B { aCalled += 1; return B() } +func b(_: B) -> C { bCalled += 1; return C() } ExperimentalTestSuite.test("ComposeOperator/CountCalls/Workaround") { var result = b ∘ a diff --git a/test/1_stdlib/Filter.swift b/test/1_stdlib/Filter.swift index 95c215f32b4c8..74ee1225e2196 100644 --- a/test/1_stdlib/Filter.swift +++ b/test/1_stdlib/Filter.swift @@ -2,16 +2,28 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -// RUN: %target-run-simple-swift | FileCheck %s +// RUN: %target-run-simple-swift // REQUIRES: executable_test +import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + +let FilterTests = TestSuite("Filter") + // Check that the generic parameter is called 'Base'. protocol TestProtocol1 {} @@ -39,59 +51,20 @@ extension LazyFilterCollection where Base : TestProtocol1 { } } -// CHECK: testing... -print("testing...") - -func printlnByGenerating(s: S) { - print("<", terminator: "") - var prefix = "" - for x in s { - print("\(prefix)\(x)", terminator: "") - prefix = ", " - } - print(">") -} - -func printlnByIndexing(c: C) { - printlnByGenerating( - PermutationGenerator(elements: c, indices: c.indices) - ) -} - -// Test filtering Collections -if true { +FilterTests.test("filtering collections") { let f0 = LazyFilterCollection(0..<30) { $0 % 7 == 0 } - - // CHECK-NEXT: <0, 7, 14, 21, 28> - printlnByGenerating(f0) - // CHECK-NEXT: <0, 7, 14, 21, 28> - printlnByIndexing(f0) + expectEqualSequence([0, 7, 14, 21, 28], f0) - // Also try when the first element of the underlying sequence - // doesn't pass the filter let f1 = LazyFilterCollection(1..<30) { $0 % 7 == 0 } - - // CHECK-NEXT: <7, 14, 21, 28> - printlnByGenerating(f1) - // CHECK-NEXT: <7, 14, 21, 28> - printlnByIndexing(f1) + expectEqualSequence([7, 14, 21, 28], f1) } - -// Test filtering Sequences -if true { +FilterTests.test("filtering sequences") { let f0 = (0..<30).generate().lazy.filter { $0 % 7 == 0 } - - // CHECK-NEXT: <0, 7, 14, 21, 28> - printlnByGenerating(f0) + expectEqualSequence([0, 7, 14, 21, 28], f0) - // Also try when the first element of the underlying sequence - // doesn't pass the filter let f1 = (1..<30).generate().lazy.filter { $0 % 7 == 0 } - - // CHECK-NEXT: <7, 14, 21, 28> - printlnByGenerating(f1) + expectEqualSequence([7, 14, 21, 28], f1) } -// CHECK-NEXT: all done. -print("all done.") +runAllTests() diff --git a/test/1_stdlib/Float.swift b/test/1_stdlib/Float.swift index 8cf37ecceb821..b96a700adc03b 100644 --- a/test/1_stdlib/Float.swift +++ b/test/1_stdlib/Float.swift @@ -37,12 +37,12 @@ func checkNormal(normal: TestFloat) { } func testNormal() { - var positiveNormal: TestFloat = 42.0 + let positiveNormal: TestFloat = 42.0 checkNormal(positiveNormal) _precondition(!positiveNormal.isSignMinus) _precondition(positiveNormal.floatingPointClass == .PositiveNormal) - var negativeNormal: TestFloat = -42.0 + let negativeNormal: TestFloat = -42.0 checkNormal(negativeNormal) _precondition(negativeNormal.isSignMinus) _precondition(negativeNormal.floatingPointClass == .NegativeNormal) @@ -74,12 +74,12 @@ func checkZero(zero: TestFloat) { } func testZero() { - var plusZero = noinlinePlusZero() + let plusZero = noinlinePlusZero() checkZero(plusZero) _precondition(!plusZero.isSignMinus) _precondition(plusZero.floatingPointClass == .PositiveZero) - var minusZero = noinlineMinusZero() + let minusZero = noinlineMinusZero() checkZero(minusZero) _precondition(minusZero.isSignMinus) _precondition(minusZero.floatingPointClass == .NegativeZero) @@ -129,7 +129,7 @@ func testSubnormal() { _preconditionFailure("unhandled float kind") } var positiveSubnormal: TestFloat = 1.0 - for var i = 0; i < iterations; i++ { + for var i = 0; i < iterations; i += 1 { positiveSubnormal /= 2.0 as TestFloat } checkSubnormal(positiveSubnormal) @@ -138,7 +138,7 @@ func testSubnormal() { _precondition(positiveSubnormal != 0.0) var negativeSubnormal: TestFloat = -1.0 - for var i = 0; i < iterations; i++ { + for var i = 0; i < iterations; i += 1{ negativeSubnormal /= 2.0 as TestFloat } checkSubnormal(negativeSubnormal) diff --git a/test/1_stdlib/FloatingPoint.swift.gyb b/test/1_stdlib/FloatingPoint.swift.gyb index bfa918312919e..ac9ce39e56a79 100644 --- a/test/1_stdlib/FloatingPoint.swift.gyb +++ b/test/1_stdlib/FloatingPoint.swift.gyb @@ -8,6 +8,14 @@ import Swift import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + #if arch(i386) || arch(x86_64) struct Float80Bits : Equatable, CustomStringConvertible { @@ -215,7 +223,7 @@ func checkFloatingPointComparison_${FloatSelf}( expected: ExpectedComparisonResult, _ lhs: ${FloatSelf}, _ rhs: ${FloatSelf}, //===--- TRACE boilerplate ----------------------------------------------===// - // @autoclosure _ message: ()->String = "", + // @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__ @@ -316,222 +324,222 @@ FloatingPoint.test("${Self}/Strideable") { // Float80 does not conform to FloatingPointType FloatingPoint.test("Float32/Literals") { - if true { + do { let f: Float32 = 0.0 expectEqual(0x0000_0000, f._toBitPattern()) } - if true { + do { let f: Float32 = -0.0 expectEqual(0x8000_0000, f._toBitPattern()) } - if true { + do { let f: Float32 = 1.0 expectEqual(0x3f80_0000, f._toBitPattern()) } - if true { + do { let f: Float32 = -1.0 expectEqual(0xbf80_0000, f._toBitPattern()) } - if true { + do { let f: Float32 = 0.999999 expectEqual(0x3f7fffef, f._toBitPattern()) } - if true { + do { let f: Float32 = 0.9999999 expectEqual(0x3f7ffffe, f._toBitPattern()) } - if true { + do { let f: Float32 = 0.99999999 expectEqual(0x3f80_0000, f._toBitPattern()) } // Infinity. // FIXME: this should be a compile-time error, not silent overflow. - if true { + do { let f: Float32 = 1.0e999 expectEqual(0x7f80_0000, f._toBitPattern()) } - if true { + do { let f: Float32 = -1.0e999 expectEqual(0xff80_0000, f._toBitPattern()) } // Smallest subnormal. - if true { + do { let f: Float32 = 1.4e-45 expectEqual(0x0000_0001, f._toBitPattern()) } - if true { + do { let f: Float32 = -1.4e-45 expectEqual(0x8000_0001, f._toBitPattern()) } // Rounded to zero. - if true { + do { let f: Float32 = 0.7e-45 expectEqual(0x0000_0000, f._toBitPattern()) } - if true { + do { let f: Float32 = -0.7e-45 expectEqual(0x8000_0000, f._toBitPattern()) } // Second largest normal. - if true { + do { let f: Float32 = 3.4028232e+38 expectEqual(0x7f7f_fffe, f._toBitPattern()) } - if true { + do { let f: Float32 = -3.4028232e+38 expectEqual(0xff7f_fffe, f._toBitPattern()) } // Largest normal. - if true { + do { let f: Float32 = 3.4028234e+38 expectEqual(0x7f7f_ffff, f._toBitPattern()) } - if true { + do { let f: Float32 = 340282340000000000000000000000000000000.0 expectEqual(0x7f7f_ffff, f._toBitPattern()) } - if true { + do { let f: Float32 = 340282340000000000000000000000000000000 expectEqual(0x7f7f_ffff, f._toBitPattern()) } - if true { + do { let f: Float32 = -3.4028234e+38 expectEqual(0xff7f_ffff, f._toBitPattern()) } - if true { + do { let f: Float32 = -340282340000000000000000000000000000000.0 expectEqual(0xff7f_ffff, f._toBitPattern()) } - if true { + do { let f: Float32 = -340282340000000000000000000000000000000 expectEqual(0xff7f_ffff, f._toBitPattern()) } // Smallest decimal that is rounded to infinity. // FIXME: this should be a compile-time error, not silent overflow. - if true { + do { let f: Float32 = 3.4028236e+38 expectEqual(0x7f80_0000, f._toBitPattern()) } - if true { + do { let f: Float32 = -3.4028236e+38 expectEqual(0xff80_0000, f._toBitPattern()) } } FloatingPoint.test("Float64/Literals") { - if true { + do { let f: Float64 = 0.0 expectEqual(0x0000_0000_0000_0000, f._toBitPattern()) } - if true { + do { let f: Float64 = -0.0 expectEqual(0x8000_0000_0000_0000, f._toBitPattern()) } - if true { + do { let f: Float64 = 1.0 expectEqual(0x3ff0_0000_0000_0000, f._toBitPattern()) } - if true { + do { let f: Float64 = -1.0 expectEqual(0xbff0_0000_0000_0000, f._toBitPattern()) } - if true { + do { let f: Float64 = 0.999999999999999 expectEqual(0x3fef_ffff_ffff_fff7, f._toBitPattern()) } - if true { + do { let f: Float64 = 0.9999999999999999 expectEqual(0x3fef_ffff_ffff_ffff, f._toBitPattern()) } - if true { + do { let f: Float64 = 0.99999999999999999 expectEqual(0x3ff0_0000_0000_0000, f._toBitPattern()) } // Infinity. // FIXME: this should be a compile-time error, not silent overflow. - if true { + do { let f: Float64 = 1.0e999 expectEqual(0x7ff0_0000_0000_0000, f._toBitPattern()) } - if true { + do { let f: Float64 = -1.0e999 expectEqual(0xfff0_0000_0000_0000, f._toBitPattern()) } // Smallest subnormal. - if true { + do { let f: Float64 = 4.0e-324 expectEqual(0x0000_0000_0000_0001, f._toBitPattern()) } - if true { + do { let f: Float64 = -4.0e-324 expectEqual(0x8000_0000_0000_0001, f._toBitPattern()) } // Rounded to zero. - if true { + do { let f: Float64 = 2.4e-324 expectEqual(0x0000_0000_0000_0000, f._toBitPattern()) } - if true { + do { let f: Float64 = -2.4e-324 expectEqual(0x8000_0000_0000_0000, f._toBitPattern()) } // Second largest normal. - if true { + do { let f: Float64 = 1.79769313486231551e+308 expectEqual(0x7fef_ffff_ffff_fffe, f._toBitPattern()) } - if true { + do { let f: Float64 = -1.79769313486231551e+308 expectEqual(0xffef_ffff_ffff_fffe, f._toBitPattern()) } // Largest normal. - if true { + do { let f: Float64 = 1.7976931348623157e+308 expectEqual(0x7fef_ffff_ffff_ffff, f._toBitPattern()) } - if true { + do { let f: Float64 = 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 expectEqual(0x7fef_ffff_ffff_ffff, f._toBitPattern()) } - if true { + do { let f: Float64 = 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 expectEqual(0x7fef_ffff_ffff_ffff, f._toBitPattern()) } - if true { + do { let f: Float64 = -1.7976931348623157e+308 expectEqual(0xffef_ffff_ffff_ffff, f._toBitPattern()) } - if true { + do { let f: Float64 = -179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 expectEqual(0xffef_ffff_ffff_ffff, f._toBitPattern()) } - if true { + do { let f: Float64 = -179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 expectEqual(0xffef_ffff_ffff_ffff, f._toBitPattern()) } // Smallest decimal that is rounded to infinity. // FIXME: this should be a compile-time error, not silent overflow. - if true { + do { let f: Float64 = 1.7976931348623159e+308 expectEqual(0x7ff0_0000_0000_0000, f._toBitPattern()) } - if true { + do { let f: Float64 = -1.7976931348623159e+308 expectEqual(0xfff0_0000_0000_0000, f._toBitPattern()) } @@ -540,98 +548,98 @@ FloatingPoint.test("Float64/Literals") { #if arch(i386) || arch(x86_64) FloatingPoint.test("Float80/Literals") { - if true { + do { let f: Float80 = 0.0 expectEqual(Float80Bits(0x0000, 0x0000_0000_0000_0000), f._toBitPattern()) } - if true { + do { let f: Float80 = -0.0 expectEqual(Float80Bits(0x8000, 0x0000_0000_0000_0000), f._toBitPattern()) } - if true { + do { let f: Float80 = 1.0 expectEqual(Float80Bits(0x3fff, 0x8000_0000_0000_0000), f._toBitPattern()) } - if true { + do { let f: Float80 = -1.0 expectEqual(Float80Bits(0xbfff, 0x8000_0000_0000_0000), f._toBitPattern()) } - if true { + do { let f: Float80 = 0.999999999999999999 expectEqual(Float80Bits(0x3ffe, 0xffff_ffff_ffff_ffee), f._toBitPattern()) } - if true { + do { let f: Float80 = 0.9999999999999999999 expectEqual(Float80Bits(0x3ffe, 0xffff_ffff_ffff_fffe), f._toBitPattern()) } - if true { + do { let f: Float80 = 0.99999999999999999995 expectEqual(Float80Bits(0x3ffe, 0xffff_ffff_ffff_ffff), f._toBitPattern()) } - if true { + do { let f: Float80 = 0.99999999999999999999 expectEqual(Float80Bits(0x3fff, 0x8000_0000_0000_0000), f._toBitPattern()) } // Infinity. // FIXME: this should be a compile-time error, not silent overflow. - if true { + do { let f: Float80 = 1.0e19999 expectEqual(Float80Bits(0x7fff, 0x8000_0000_0000_0000), f._toBitPattern()) } - if true { + do { let f: Float80 = -1.0e19999 expectEqual(Float80Bits(0xffff, 0x8000_0000_0000_0000), f._toBitPattern()) } // Smallest subnormal. - if true { + do { // 3.645199531882474602528e-4951 let f: Float80 = 3.6e-4951 expectEqual(Float80Bits(0x0000, 0x0000_0000_0000_0001), f._toBitPattern()) } - if true { + do { let f: Float80 = -3.6e-4951 expectEqual(Float80Bits(0x8000, 0x0000_0000_0000_0001), f._toBitPattern()) } // Rounded to zero. - if true { + do { let f: Float80 = 1.8e-4951 expectEqual(Float80Bits(0x0000, 0x0000_0000_0000_0000), f._toBitPattern()) } - if true { + do { let f: Float80 = -1.8e-4951 expectEqual(Float80Bits(0x8000, 0x0000_0000_0000_0000), f._toBitPattern()) } // Largest normal. - if true { + do { let f: Float80 = 1.189731495357231765e+4932 expectEqual(Float80Bits(0x7ffe, 0xffff_ffff_ffff_ffff), f._toBitPattern()) } - if true { + do { let f: Float80 = 1189731495357231765000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 expectEqual(Float80Bits(0x7ffe, 0xffff_ffff_ffff_ffff), f._toBitPattern()) } - if true { + do { let f: Float80 = -1.189731495357231765e+4932 expectEqual(Float80Bits(0xfffe, 0xffff_ffff_ffff_ffff), f._toBitPattern()) } - if true { + do { let f: Float80 = -1189731495357231765000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 expectEqual(Float80Bits(0xfffe, 0xffff_ffff_ffff_ffff), f._toBitPattern()) } // Smallest decimal that is rounded to infinity. // FIXME: this should be a compile-time error, not silent overflow. - if true { + do { let f: Float80 = 1.18973149535723176515e+4932 expectEqual(Float80Bits(0x7fff, 0x8000_0000_0000_0000), f._toBitPattern()) } - if true { + do { let f: Float80 = -1.18973149535723176515e+4932 expectEqual(Float80Bits(0xffff, 0x8000_0000_0000_0000), f._toBitPattern()) } @@ -639,5 +647,24 @@ FloatingPoint.test("Float80/Literals") { #endif +var FloatingPointClassification = TestSuite("NumericParsing") + +FloatingPointClassification.test("FloatingPointClassification/Equatable") { + let values: [FloatingPointClassification] = [ + .SignalingNaN, + .QuietNaN, + .NegativeInfinity, + .NegativeNormal, + .NegativeSubnormal, + .NegativeZero, + .PositiveZero, + .PositiveSubnormal, + .PositiveNormal, + .PositiveInfinity + ] + // Values should be equal iff indices equal + checkEquatable(values, oracle: { $0 == $1 }) +} + runAllTests() diff --git a/test/1_stdlib/Generator.swift b/test/1_stdlib/Generator.swift index eac389a4121de..4533cdb19c0e7 100644 --- a/test/1_stdlib/Generator.swift +++ b/test/1_stdlib/Generator.swift @@ -2,6 +2,15 @@ // REQUIRES: executable_test import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var tests = TestSuite("Generator") // Check to make sure we are actually getting Optionals out of this @@ -26,7 +35,7 @@ tests.test("GeneratorSequence") { var x = MinimalGenerator(Array(r)) for a in GeneratorSequence(x) { expectEqual(r.startIndex, a) - ++r.startIndex + r.startIndex = r.startIndex.successor() } expectEqual(r.startIndex, r.endIndex) } @@ -34,7 +43,9 @@ tests.test("GeneratorSequence") { struct G : GeneratorType { var i = 0 mutating func next() -> Int? { - return i < 10 ? i++ : nil + if i >= 10 { return nil } + i += 1 + return i-1 } } @@ -42,7 +53,8 @@ extension G : SequenceType {} tests.test("GeneratorsModelSequenceTypeByDeclaration") { var n = 0 for i in G() { - expectEqual(n++, i) + expectEqual(n, i) + n += 1 } } diff --git a/test/1_stdlib/ImplicitlyUnwrappedOptional.swift b/test/1_stdlib/ImplicitlyUnwrappedOptional.swift index b974a53bbafaa..c106ef483bc50 100644 --- a/test/1_stdlib/ImplicitlyUnwrappedOptional.swift +++ b/test/1_stdlib/ImplicitlyUnwrappedOptional.swift @@ -4,8 +4,7 @@ var x : Int! = .None if x != nil { print("x is non-empty!") -} -else { +} else { print("an empty optional is logically false") } // CHECK: an empty optional is logically false @@ -14,8 +13,7 @@ x = .Some(0) if x != nil { print("a non-empty optional is logically true") -} -else { +} else { print("x is empty!") } // CHECK: a non-empty optional is logically true @@ -39,6 +37,15 @@ if c === nil { // CHECK: an empty class optional should equal nil import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import Swift var ImplicitlyUnwrappedOptionalTests = TestSuite("ImplicitlyUnwrappedOptional") diff --git a/test/1_stdlib/Index.swift.gyb b/test/1_stdlib/Index.swift.gyb index 7722380d59e0b..8a323963edb69 100644 --- a/test/1_stdlib/Index.swift.gyb +++ b/test/1_stdlib/Index.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/InputStream.swift.gyb b/test/1_stdlib/InputStream.swift.gyb index d223991b21fb0..fcb9830747e4d 100644 --- a/test/1_stdlib/InputStream.swift.gyb +++ b/test/1_stdlib/InputStream.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -19,6 +19,15 @@ // XFAIL: interpret import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import Swift var ReadLineTestSuite = TestSuite("ReadLine") diff --git a/test/1_stdlib/Inputs/ArrayBridge/ArrayBridge.h b/test/1_stdlib/Inputs/ArrayBridge/ArrayBridge.h index c9f0d83c54524..4ff7a3e737774 100644 --- a/test/1_stdlib/Inputs/ArrayBridge/ArrayBridge.h +++ b/test/1_stdlib/Inputs/ArrayBridge/ArrayBridge.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Inputs/ArrayBridge/ArrayBridge.m b/test/1_stdlib/Inputs/ArrayBridge/ArrayBridge.m index 68104f62e3746..781610757ce6a 100644 --- a/test/1_stdlib/Inputs/ArrayBridge/ArrayBridge.m +++ b/test/1_stdlib/Inputs/ArrayBridge/ArrayBridge.m @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Inputs/ArrayBridge/module.map b/test/1_stdlib/Inputs/ArrayBridge/module.map index 91941205411dc..511987f8227d1 100644 --- a/test/1_stdlib/Inputs/ArrayBridge/module.map +++ b/test/1_stdlib/Inputs/ArrayBridge/module.map @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Inputs/DictionaryKeyValueTypes.swift b/test/1_stdlib/Inputs/DictionaryKeyValueTypes.swift index e371f7d6dad9e..8ce4d2e8b5c61 100644 --- a/test/1_stdlib/Inputs/DictionaryKeyValueTypes.swift +++ b/test/1_stdlib/Inputs/DictionaryKeyValueTypes.swift @@ -428,7 +428,7 @@ struct TestBridgedValueTy : CustomStringConvertible, _ObjectiveCBridgeable { } func _bridgeToObjectiveC() -> TestObjCValueTy { - TestBridgedValueTy.bridgeOperations++ + TestBridgedValueTy.bridgeOperations += 1 return TestObjCValueTy(value) } @@ -436,7 +436,7 @@ struct TestBridgedValueTy : CustomStringConvertible, _ObjectiveCBridgeable { x: TestObjCValueTy, inout result: TestBridgedValueTy? ) { - TestBridgedValueTy.bridgeOperations++ + TestBridgedValueTy.bridgeOperations += 1 result = TestBridgedValueTy(x.value) } @@ -637,7 +637,7 @@ func slurpFastEnumerationFromSwift( for i in 0..= maxItems! { return @@ -681,7 +681,7 @@ func slurpFastEnumerationFromSwift( let value: AnyObject = d.objectForKey(key)! let kv = (key, value) sink(kv) - ++itemsReturned + itemsReturned += 1 } if maxItems != nil && itemsReturned >= maxItems! { return @@ -791,7 +791,7 @@ func _checkArrayFastEnumerationImpl( expected: [Int], _ a: NSArray, _ makeEnumerator: () -> NSFastEnumeration, - _ useEnumerator: (NSArray, NSFastEnumeration, (AnyObject)->()) -> Void, + _ useEnumerator: (NSArray, NSFastEnumeration, (AnyObject) -> ()) -> Void, _ convertValue: (AnyObject) -> Int ) { let expectedContentsWithoutIdentity = @@ -924,7 +924,7 @@ func _checkSetFastEnumerationImpl( expected: [Int], _ s: NSSet, _ makeEnumerator: () -> NSFastEnumeration, - _ useEnumerator: (NSSet, NSFastEnumeration, (AnyObject)->()) -> Void, + _ useEnumerator: (NSSet, NSFastEnumeration, (AnyObject) -> ()) -> Void, _ convertMember: (AnyObject) -> Int ) { let expectedContentsWithoutIdentity = @@ -999,7 +999,7 @@ func slurpFastEnumerationFromSwift( for i in 0..= maxItems! { return @@ -1142,7 +1142,7 @@ func _checkDictionaryFastEnumerationImpl( expected: [(Int, Int)], _ d: NSDictionary, _ makeEnumerator: () -> NSFastEnumeration, - _ useEnumerator: (NSDictionary, NSFastEnumeration, (AnyObjectTuple2)->()) -> Void, + _ useEnumerator: (NSDictionary, NSFastEnumeration, (AnyObjectTuple2) -> ()) -> Void, _ convertKey: (AnyObject) -> Int, _ convertValue: (AnyObject) -> Int ) { diff --git a/test/1_stdlib/Inputs/Mirror/Mirror.h b/test/1_stdlib/Inputs/Mirror/Mirror.h index 5acab1b170d0b..3f50ca90a499b 100644 --- a/test/1_stdlib/Inputs/Mirror/Mirror.h +++ b/test/1_stdlib/Inputs/Mirror/Mirror.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Inputs/Mirror/Mirror.mm b/test/1_stdlib/Inputs/Mirror/Mirror.mm index 2b3be7a0fd021..9d053502d3557 100644 --- a/test/1_stdlib/Inputs/Mirror/Mirror.mm +++ b/test/1_stdlib/Inputs/Mirror/Mirror.mm @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Inputs/Mirror/module.map b/test/1_stdlib/Inputs/Mirror/module.map index ceacc55b29191..5042e7e0bfd1b 100644 --- a/test/1_stdlib/Inputs/Mirror/module.map +++ b/test/1_stdlib/Inputs/Mirror/module.map @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Inputs/PrintTestTypes.swift b/test/1_stdlib/Inputs/PrintTestTypes.swift new file mode 100644 index 0000000000000..d89a0bdbda3a2 --- /dev/null +++ b/test/1_stdlib/Inputs/PrintTestTypes.swift @@ -0,0 +1,157 @@ +public protocol ProtocolUnrelatedToPrinting {} + +public struct StructPrintable : CustomStringConvertible, + ProtocolUnrelatedToPrinting { + + let x: Int + + public init(_ x: Int) { + self.x = x + } + + public var description: String { + return "►\(x)◀︎" + } +} + +public struct LargeStructPrintable : CustomStringConvertible, + ProtocolUnrelatedToPrinting { + + let a: Int + let b: Int + let c: Int + let d: Int + + public init(_ a: Int, _ b: Int, _ c: Int, _ d: Int) { + self.a = a + self.b = b + self.c = c + self.d = d + } + + public var description: String { + return "<\(a) \(b) \(c) \(d)>" + } +} + +public struct StructDebugPrintable : CustomDebugStringConvertible { + let x: Int + + public init(_ x: Int) { + self.x = x + } + + public var debugDescription: String { + return "►\(x)◀︎" + } +} + +public struct StructVeryPrintable : CustomStringConvertible, + CustomDebugStringConvertible, ProtocolUnrelatedToPrinting { + + let x: Int + + public init(_ x: Int) { + self.x = x + } + + public var description: String { + return "" + } + + public var debugDescription: String { + return "" + } +} + +public struct EmptyStructWithoutDescription { + public init() {} +} + +public struct WithoutDescription { + let x: Int + + public init(_ x: Int) { + self.x = x + } +} + +public struct ValuesWithoutDescription { + let t: T + let u: U + let v: V + + public init(_ t: T, _ u: U, _ v: V) { + self.t = t + self.u = u + self.v = v + } +} + + +public class ClassPrintable : CustomStringConvertible, + ProtocolUnrelatedToPrinting { + + let x: Int + + public init(_ x: Int) { + self.x = x + } + + public var description: String { + return "►\(x)◀︎" + } +} + +public class ClassVeryPrintable : CustomStringConvertible, + CustomDebugStringConvertible, ProtocolUnrelatedToPrinting { + + let x: Int + + public init(_ x: Int) { + self.x = x + } + + public var description: String { + return "" + } + + public var debugDescription: String { + return "" + } +} + +public struct MyString : StringLiteralConvertible, + StringInterpolationConvertible { + + public init(str: String) { + value = str + } + + public var value: String + + public init(unicodeScalarLiteral value: String) { + self.init(str: value) + } + + public init(extendedGraphemeClusterLiteral value: String) { + self.init(str: value) + } + + public init(stringLiteral value: String) { + self.init(str: value) + } + + public init(stringInterpolation strings: MyString...) { + var result = "" + for s in strings { + result += s.value + } + self.init(str: result) + } + + public init(stringInterpolationSegment expr: T) { + self.init(str: "") + } +} + diff --git a/test/1_stdlib/Inputs/SwiftObjectNSObject/SwiftObjectNSObject.m b/test/1_stdlib/Inputs/SwiftObjectNSObject/SwiftObjectNSObject.m index 97225317b2401..d8eca5aff0e07 100644 --- a/test/1_stdlib/Inputs/SwiftObjectNSObject/SwiftObjectNSObject.m +++ b/test/1_stdlib/Inputs/SwiftObjectNSObject/SwiftObjectNSObject.m @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Interval.swift b/test/1_stdlib/Interval.swift index c2b4e9447466d..38679fc2be2e3 100644 --- a/test/1_stdlib/Interval.swift +++ b/test/1_stdlib/Interval.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,6 +16,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + // Check that the generic parameter is called 'Bound'. protocol TestProtocol1 {} @@ -169,11 +177,11 @@ IntervalTestSuite.test("CustomStringConvertible/CustomDebugStringConvertible") { expectEqual("0.0...0.1", String(X(0.0)...X(0.1))) expectEqual( - "HalfOpenInterval(X(0.0).. Int { - ++SequenceWithCustomUnderestimateCount.timesUnderestimateCountWasCalled + SequenceWithCustomUnderestimateCount.timesUnderestimateCountWasCalled += 1 return _data.underestimateCount() } @@ -400,7 +400,7 @@ func expectSequencePassthrough< _ = s._copyToNativeArrayBuffer() } - SequenceLog._initializeTo.expectIncrement(baseType) { ()->Void in + SequenceLog._initializeTo.expectIncrement(baseType) { () -> Void in let buf = UnsafeMutablePointer.alloc(count) let end = s._initializeTo(buf) @@ -486,8 +486,8 @@ tests.test("LazyMapSequence") { var calls = 0 var mapped = base.map { - (x: OpaqueValue)->OpaqueValue in - ++calls + (x: OpaqueValue) -> OpaqueValue in + calls += 1 return OpaqueValue(Double(x.value) / 2.0) } @@ -528,8 +528,8 @@ tests.test("LazyMapCollection/${traversal}") { var calls = 0 var mapped = base.map { - (x: OpaqueValue)->OpaqueValue in - ++calls + (x: OpaqueValue) -> OpaqueValue in + calls += 1 return OpaqueValue(Double(x.value) / 2.0) } expectEqual(0, calls) @@ -595,7 +595,7 @@ tests.test("ReverseCollection") { // Check that the reverse collection is still eager do { var calls = 0 - _ = r.reverse().map { _ in ++calls } + _ = r.reverse().map { _ in calls += 1 } expectEqual(r.count, calls) } @@ -606,7 +606,7 @@ tests.test("ReverseCollection") { // Check that the reverse collection is still eager do { var calls = 0 - _ = "foobar".characters.reverse().map { _ in ++calls } + _ = "foobar".characters.reverse().map { _ in calls += 1 } expectEqual("foobar".characters.count, calls) } } @@ -635,7 +635,7 @@ tests.test("ReverseCollection/Lazy") { ExpectType.test(reversed) var calls = 0 - let reversedAndMapped = reversed.map { (x)->Int in ++calls; return x } + let reversedAndMapped = reversed.map { (x) -> Int in calls += 1; return x } expectEqual(0, calls) checkRandomAccessCollection(0...11, reversedAndMapped) expectNotEqual(0, calls) @@ -657,7 +657,7 @@ tests.test("ReverseCollection/Lazy") { ExpectType.test(reversed) var calls = 0 - let reversedAndMapped = reversed.map { (x)->Character in ++calls; return x } + let reversedAndMapped = reversed.map { (x) -> Character in calls += 1; return x } expectEqual(0, calls) checkBidirectionalCollection("raboof".characters, reversedAndMapped) expectNotEqual(0, calls) @@ -695,7 +695,7 @@ tests.test("LazyFilterSequence") { var calls = 0 var filtered = MinimalSequence(elements: base).lazy.filter { - x in ++calls; + x in calls += 1; return x.value % 2 == 0 } expectEqual(calls, 0, "filtering was eager!") @@ -710,7 +710,7 @@ tests.test("LazyFilterSequence") { } expectEqual(100, calls) - // check that it works when the first element doesn't satify the predicate + // Check that it works when the first element doesn't satisfy the predicate let odds = 1.stride(to: 100, by: 2).map(OpaqueValue.init) filtered = MinimalSequence(elements: base).lazy.filter { $0.value % 2 != 0 } @@ -721,7 +721,7 @@ tests.test("LazyFilterSequence") { // Try again using explicit construction filtered = LazyFilterSequence( MinimalSequence(elements: base), - whereElementsSatisfy: { x in ++calls; return x.value % 2 == 0}) + whereElementsSatisfy: { x in calls += 1; return x.value % 2 == 0}) expectEqual(100, calls) @@ -759,7 +759,7 @@ tests.test("LazyFilterCollection") { var calls = 0 let filtered = base.lazy.filter { - x in ++calls; + x in calls += 1; return x.value % 2 == 0 } expectEqual(calls, 0, "filtering was eager!") @@ -821,7 +821,7 @@ do { elements: data.map { MinimalSequence(elements: $0) }) let flattened = base.flatten() var calls = 0 - _ = flattened.map { _ in ++calls } + _ = flattened.map { _ in calls += 1 } expectEqual( expected.count, calls, "unexpected laziness in \(flattened.dynamicType)") @@ -835,7 +835,7 @@ do { let flattened = base.flatten() var calls = 0 - _ = flattened.map { _ in ++calls } + _ = flattened.map { _ in calls += 1 } expectEqual(0, calls, "unexpected eagerness in \(flattened.dynamicType)") } @@ -850,7 +850,7 @@ do { // Checking that flatten doesn't introduce laziness var calls = 0 - _ = flattened.map { _ in ++calls } + _ = flattened.map { _ in calls += 1 } expectLE( expected.count, calls, "unexpected laziness in \(flattened.dynamicType)") @@ -865,7 +865,7 @@ do { let flattened = base.flatten() var calls = 0 - _ = flattened.map { _ in ++calls } + _ = flattened.map { _ in calls += 1 } expectEqual(0, calls, "unexpected eagerness in \(flattened.dynamicType)") } % end diff --git a/test/1_stdlib/ManagedBuffer.swift b/test/1_stdlib/ManagedBuffer.swift index ab2febf4bd688..54e328b13b4db 100644 --- a/test/1_stdlib/ManagedBuffer.swift +++ b/test/1_stdlib/ManagedBuffer.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -95,7 +95,7 @@ final class TestManagedBuffer : ManagedBuffer { let count = self.count withUnsafeMutablePointerToElements { - (x: UnsafeMutablePointer)->() in + (x: UnsafeMutablePointer) -> () in for i in 0.stride(to: count, by: 2) { (x + i).destroy() } @@ -107,7 +107,7 @@ final class TestManagedBuffer : ManagedBuffer { precondition(count + 2 <= capacity) withUnsafeMutablePointerToElements { - (p: UnsafeMutablePointer)->() in + (p: UnsafeMutablePointer) -> () in (p + count).initialize(x) } self.count = count + 2 @@ -118,7 +118,7 @@ class MyBuffer { typealias Manager = ManagedBufferPointer deinit { Manager(unsafeBufferObject: self).withUnsafeMutablePointers { - (pointerToValue, pointerToElements)->Void in + (pointerToValue, pointerToElements) -> Void in pointerToElements.destroy(self.count) pointerToValue.destroy() } diff --git a/test/1_stdlib/Map.swift b/test/1_stdlib/Map.swift index a6be9f05c30de..f09062105c7b0 100644 --- a/test/1_stdlib/Map.swift +++ b/test/1_stdlib/Map.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -52,7 +52,7 @@ for x in s { } print(">") -//===--- Avoid creating gratutitously self-destructive sequences ----------===// +//===--- Avoid creating gratuitously self-destructive sequences -----------===// // In a naive implementation, mapping over a non-self-destructive // SequenceType having a reference-semantics GeneratorType produces a @@ -65,7 +65,9 @@ print(">") // A GeneratorType with reference semantics class Counter : GeneratorType { func next() -> Int? { - return n < end ? n++ : nil + if n >= end { return nil } + n += 1 + return n-1 } init(_ n: Int, _ end: Int) { diff --git a/test/1_stdlib/Mirror.swift b/test/1_stdlib/Mirror.swift index 15257461cb16f..c2e74c68a8b74 100644 --- a/test/1_stdlib/Mirror.swift +++ b/test/1_stdlib/Mirror.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -21,6 +21,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var mirrors = TestSuite("Mirrors") extension Mirror { @@ -55,13 +63,15 @@ func find(substring: String, within domain: String) -> String.Index? { if (domainCount < substringCount) { return nil } var sliceStart = domain.startIndex var sliceEnd = domain.startIndex.advancedBy(substringCount) - for var i = 0;; ++i { + var i = 0 + while true { if domain[sliceStart..String, + _ op: (_: NSLocale?) -> String, _ localeID: String? = nil, - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__ @@ -347,13 +347,13 @@ NSStringAPIs.test("compare(_:options:range:locale:)") { expectEqual(NSComparisonResult.OrderedSame, "абв".compare("абВ", options: .CaseInsensitiveSearch)) - if true { + do { let s = "abcd" let r = s.startIndex.successor().. String { - return s.stringByFoldingWithOptions(options, locale: loc) + ) -> (NSLocale?) -> String { + return { loc in s.stringByFoldingWithOptions(options, locale: loc) } } expectLocalizedEquality("abcd", fwo("abCD", .CaseInsensitiveSearch), "en") @@ -1449,7 +1449,7 @@ NSStringAPIs.test("stringByRemovingPercentEncoding") { } NSStringAPIs.test("stringByReplacingCharactersInRange(_:withString:)") { - if true { + do { let empty = "" expectEqual("", empty.stringByReplacingCharactersInRange( empty.startIndex.. UnsafeMutablePointer { return nil } -func getASCIICString() -> (UnsafeMutablePointer, dealloc: ()->()) { +func getASCIICString() -> (UnsafeMutablePointer, dealloc: () -> ()) { let up = UnsafeMutablePointer.alloc(100) up[0] = 0x61 up[1] = 0x62 @@ -2151,7 +2151,7 @@ func getASCIICString() -> (UnsafeMutablePointer, dealloc: ()->()) { return (up, { up.dealloc(100) }) } -func getNonASCIICString() -> (UnsafeMutablePointer, dealloc: ()->()) { +func getNonASCIICString() -> (UnsafeMutablePointer, dealloc: () -> ()) { let up = UnsafeMutablePointer.alloc(100) up[0] = 0xd0 up[1] = 0xb0 @@ -2162,7 +2162,7 @@ func getNonASCIICString() -> (UnsafeMutablePointer, dealloc: ()->()) { } func getIllFormedUTF8String1( -) -> (UnsafeMutablePointer, dealloc: ()->()) { +) -> (UnsafeMutablePointer, dealloc: () -> ()) { let up = UnsafeMutablePointer.alloc(100) up[0] = 0x41 up[1] = 0xed @@ -2174,7 +2174,7 @@ func getIllFormedUTF8String1( } func getIllFormedUTF8String2( -) -> (UnsafeMutablePointer, dealloc: ()->()) { +) -> (UnsafeMutablePointer, dealloc: () -> ()) { let up = UnsafeMutablePointer.alloc(100) up[0] = 0x41 up[1] = 0xed @@ -2190,21 +2190,21 @@ func asCCharArray(a: [UInt8]) -> [CChar] { } CStringTests.test("String.fromCString") { - if true { + do { let s = getNullCString() expectEmpty(String.fromCString(s)) } - if true { + do { let (s, dealloc) = getASCIICString() expectOptionalEqual("ab", String.fromCString(s)) dealloc() } - if true { + do { let (s, dealloc) = getNonASCIICString() expectOptionalEqual("аб", String.fromCString(s)) dealloc() } - if true { + do { let (s, dealloc) = getIllFormedUTF8String1() expectEmpty(String.fromCString(s)) dealloc() @@ -2212,27 +2212,27 @@ CStringTests.test("String.fromCString") { } CStringTests.test("String.fromCStringRepairingIllFormedUTF8") { - if true { + do { let s = getNullCString() let (result, hadError) = String.fromCStringRepairingIllFormedUTF8(s) expectEmpty(result) expectFalse(hadError) } - if true { + do { let (s, dealloc) = getASCIICString() let (result, hadError) = String.fromCStringRepairingIllFormedUTF8(s) expectOptionalEqual("ab", result) expectFalse(hadError) dealloc() } - if true { + do { let (s, dealloc) = getNonASCIICString() let (result, hadError) = String.fromCStringRepairingIllFormedUTF8(s) expectOptionalEqual("аб", result) expectFalse(hadError) dealloc() } - if true { + do { let (s, dealloc) = getIllFormedUTF8String1() let (result, hadError) = String.fromCStringRepairingIllFormedUTF8(s) expectOptionalEqual("\u{41}\u{fffd}\u{fffd}\u{fffd}\u{41}", result) diff --git a/test/1_stdlib/NSValueBridging.swift b/test/1_stdlib/NSValueBridging.swift index fe7642d473b41..7f1ee547b8ff4 100644 --- a/test/1_stdlib/NSValueBridging.swift +++ b/test/1_stdlib/NSValueBridging.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/NewArray.swift.gyb b/test/1_stdlib/NewArray.swift.gyb index d1bdb7e88ff40..37f6f759280cc 100644 --- a/test/1_stdlib/NewArray.swift.gyb +++ b/test/1_stdlib/NewArray.swift.gyb @@ -1,9 +1,9 @@ %# -*- mode: swift -*- -//===--- Array.swift ------------------------------------------------------===// +//===--- NewArray.swift ---------------------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,14 +30,15 @@ final class X : ForwardIndexType, Comparable, CustomStringConvertible, IntegerLiteralConvertible { required init(_ value: Int) { - ++xCount - serial = ++xSerial + xCount += 1 + xSerial += 1 + serial = xSerial self.value = value } deinit { assert(serial > 0, "double destruction!") - --xCount + xCount -= 1 serial = -serial } @@ -142,7 +143,7 @@ where T.Generator.Element == T._Buffer.Element, checkEqual(x, y, false) func checkReallocations( - a: T, _ growthDescription: String, _ growBy1: (inout _: T)->() + a: T, _ growthDescription: String, _ growBy1: (inout _: T) -> () ) { var a = a var reallocations = 0 @@ -155,7 +156,7 @@ where T.Generator.Element == T._Buffer.Element, let oldId = bufferID(a) growBy1(&a) if oldId != bufferID(a) { - ++reallocations + reallocations += 1 } } @@ -166,8 +167,8 @@ where T.Generator.Element == T._Buffer.Element, } } - checkReallocations(x, "append") { (inout x: T)->() in x.append(42) } - checkReallocations(x, "+=") { (inout x: T)->() in x.append(42) } + checkReallocations(x, "append") { (inout x: T) -> () in x.append(42) } + checkReallocations(x, "+=") { (inout x: T) -> () in x.append(42) } print("done.") } @@ -269,7 +270,7 @@ func testCocoa() { // Prove that we create contiguous storage for an opaque NSArray a.withUnsafeBufferPointer { - (p)->() in + (p) -> () in print(p[0]) // CHECK-NEXT: foo } @@ -347,13 +348,13 @@ let testWidth = 11 %arrayTypes = ['ContiguousArray', 'Array', 'ArraySlice'] %for A in arrayTypes: -func testReplace(make: ()->${A}) { +func testReplace(make: () -> ${A}) { checkRangeReplaceable(make, { X(100)..${A} = { + makeOne: () -> ${A} = { var x = ${A}() // make sure some - but not all - replacements will have to grow the buffer x.reserveCapacity(testWidth * 3 / 2) diff --git a/test/1_stdlib/NewStringAppending.swift b/test/1_stdlib/NewStringAppending.swift index b703c30fd2d7f..d260e720ea85a 100644 --- a/test/1_stdlib/NewStringAppending.swift +++ b/test/1_stdlib/NewStringAppending.swift @@ -6,7 +6,7 @@ // like OpaqueString anyway, so we can just disable the failing // configuration // -// Memory allocator specifics also vary across platorms. +// Memory allocator specifics also vary across platforms. // REQUIRES: CPU=x86_64, OS=macosx import Foundation diff --git a/test/1_stdlib/NoFoundation.swift b/test/1_stdlib/NoFoundation.swift index c2128e551ca23..51daed0ddfcdf 100644 --- a/test/1_stdlib/NoFoundation.swift +++ b/test/1_stdlib/NoFoundation.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/NumericParsing.swift.gyb b/test/1_stdlib/NumericParsing.swift.gyb index 79f6b84186aad..48a3fd22b40b8 100644 --- a/test/1_stdlib/NumericParsing.swift.gyb +++ b/test/1_stdlib/NumericParsing.swift.gyb @@ -1,8 +1,8 @@ -//===--- NumericParsing.swift.gyb ----------------------------------------===// +//===--- NumericParsing.swift.gyb -----------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -47,6 +47,14 @@ number_of_values = 23 import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var tests = TestSuite("NumericParsing") % for type in all_integer_types(word_bits): @@ -84,6 +92,10 @@ tests.test("${Self}/success") { expectEqual(nil, ${Self}("${minValue - 1}")) expectEqual(nil, ${Self}("\u{1D7FF}")) // MATHEMATICAL MONOSPACE DIGIT NINE + // Cases that should fail to parse + expectEqual(nil, ${Self}("--0")) // Zero w/ repeated plus + expectEqual(nil, ${Self}("-+5")) // Non-zero with -+ + // Do more exhaustive testing % for radix in radices_to_test: % for n in required_values + range( diff --git a/test/1_stdlib/OptionSetTest.swift b/test/1_stdlib/OptionSetTest.swift index ac52a84242190..dd1feb66b9cf9 100644 --- a/test/1_stdlib/OptionSetTest.swift +++ b/test/1_stdlib/OptionSetTest.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,6 +30,14 @@ struct PackagingOptions : OptionSetType { import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var tests = TestSuite("OptionSet") tests.test("basics") { diff --git a/test/1_stdlib/Optional.swift b/test/1_stdlib/Optional.swift index 8b042047d284d..e7e07bf8bc653 100644 --- a/test/1_stdlib/Optional.swift +++ b/test/1_stdlib/Optional.swift @@ -1,6 +1,19 @@ -// RUN: %target-run-simple-swift | FileCheck %s +// RUN: %target-run-simple-swift // REQUIRES: executable_test +import StdlibUnittest +import Swift + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + +let OptionalTests = TestSuite("Optional") + protocol TestProtocol1 {} // Check that the generic parameter is called 'Memory'. @@ -16,110 +29,56 @@ extension ImplicitlyUnwrappedOptional where Wrapped : TestProtocol1 { } } -var x : Optional = nil -if x != nil { - print("x is non-empty!") -} -else { - print("an empty optional is logically false") -} -// CHECK: an empty optional is logically false - -switch x { -case .Some(let y): - assert(false, "Something's wrong here!") -case .None: - () -} - -x = .Some(0) +OptionalTests.test("nil comparison") { + var x: Int? = nil + expectFalse(x != nil) -x = .Some(1) + switch x { + case .Some(let y): expectUnreachable() + case .None: break + } -if x != nil { - print("a non-empty optional is logically true") -} else { - assert(false, "x is empty!") -} -// CHECK: a non-empty optional is logically true + x = .Some(1) + expectTrue(x != nil) -if x == nil { - print("logical negation fails 0") -} -else { - print("logical negation works 0") -} -// CHECK: logical negation works 0 + if true { + var y1: Int? = .None + expectTrue(y1 == nil) -if true { - var y1 : Optional = .None - if y1 == nil { - print("y1 is .None") + var y2: Int? = .None + expectTrue(y2 == nil) } - // CHECK: y1 is .None - var y2 : Optional = .None - if y2 == nil { - print("y2 is .None") - } - // CHECK: y2 is .None -} + let x1: Int? = nil + let x2: Int? = .None -func optional_param(x: Optional) { - if x == nil { - print("optional param OK") - } -} -optional_param(.None) -// CHECK: optional param OK + expectTrue(x1 == nil) + expectTrue(x2 == nil) -func optional_return() -> Optional { - return .None -} -if optional_return() == nil { - print("optional return OK") -} -// CHECK: optional return OK + switch x { + case .Some(let y): expectEqual("1", "\(y)") + case .None: assert(false) + } -var empty: Bool = true -switch x { -case .Some(let y): - print("destructuring bind: \(y).") -case .None: - () + expectEqual("forced extraction: 1.", "forced extraction: \(x!).") + expectEqual("forced extraction use: 2.", "forced extraction use: \(x!.successor()).") } -// CHECK: destructuring bind: 1. - - -print("forced extraction: \(x!).") -// CHECK: forced extraction: 1. - -print("forced extraction use: \(x!.successor()).") -// CHECK-NEXT: forced extraction use: 2. -func testRelation(p: (Int?, Int?) -> Bool) { +func testRelation(p: (Int?, Int?) -> Bool) -> [Bool] { typealias optPair = (Int?, Int?) let relationships: [optPair] = [ (1, 1), (1, 2), (2, 1), (1, .None), (.None, 1), (.None, .None) ] - var prefix = "" - for (l,r) in relationships { - print("\(prefix)\(p(l, r))", terminator: "") - prefix=", " - } - print(".") + return relationships.map { p($0, $1) } } -testRelation(==) -// CHECK-NEXT: true, false, false, false, false, true. - -testRelation(!=) -// CHECK-NEXT: false, true, true, true, true, false - -testRelation(<) -// CHECK-NEXT: false, true, false, false, true, false. +OptionalTests.test("Equatable") { + expectEqual([true, false, false, false, false, true], testRelation(==)) + expectEqual([false, true, true, true, true, false], testRelation(!=)) + expectEqual([false, true, false, false, true, false], testRelation(<)) +} struct X {} class C {} @@ -127,103 +86,86 @@ class C {} class E : Equatable {} func == (_: E, _: E) -> Bool { return true } -func nilComparison() { +OptionalTests.test("initializers") { let _: X? = nil let _: X? = X() - /* - // FIXME: Optional() == nil where T: !Equatable - print(x1 == nil) // DISABLED-CHECK-NEXT: false - print(x1 != nil) // DISABLED-CHECK-NEXT: true - print(x0 == nil) // DISABLED-CHECK-NEXT: true - print(x0 != nil) // DISABLED-CHECK-NEXT: false - - print(nil == x1) // DISABLED-CHECK-NEXT: false - print(nil != x1) // DISABLED-CHECK-NEXT: true - print(nil == x0) // DISABLED-CHECK-NEXT: true - print(nil != x0) // DISABLED-CHECK-NEXT: false - */ - + let _: C? = nil + let _: C? = C() +} + +OptionalTests.test("nil comparison") { let v0: Int? = nil let v1: Int? = 1 - - print(v1 == nil) // CHECK-NEXT: false - print(v1 != nil) // CHECK-NEXT: true - print(v0 == nil) // CHECK-NEXT: true - print(v0 != nil) // CHECK-NEXT: false - print(nil == v1) // CHECK-NEXT: false - print(nil != v1) // CHECK-NEXT: true - print(nil == v0) // CHECK-NEXT: true - print(nil != v0) // CHECK-NEXT: false + expectFalse(v1 == nil) + expectTrue(v1 != nil) + expectTrue(v0 == nil) + expectFalse(v0 != nil) + + expectFalse(nil == v1) + expectTrue(nil != v1) + expectTrue(nil == v0) + expectFalse(nil != v0) - let _: C? = nil - let _: C? = C() - - /* - // FIXME: Optional() == nil where T: !Equatable - print(c1 == nil) // DISABLED-CHECK-NEXT: false - print(c1 != nil) // DISABLED-CHECK-NEXT: true - print(c0 == nil) // DISABLED-CHECK-NEXT: true - print(c0 != nil) // DISABLED-CHECK-NEXT: false - - print(nil == c1) // DISABLED-CHECK-NEXT: false - print(nil != c1) // DISABLED-CHECK-NEXT: true - print(nil == c0) // DISABLED-CHECK-NEXT: true - print(nil != c0) // DISABLED-CHECK-NEXT: false - */ - let e0: E? = nil let e1: E? = E() - print(e1 == nil) // CHECK-NEXT: false - print(e1 != nil) // CHECK-NEXT: true - print(e0 == nil) // CHECK-NEXT: true - print(e0 != nil) // CHECK-NEXT: false - - print(nil == e1) // CHECK-NEXT: false - print(nil != e1) // CHECK-NEXT: true - print(nil == e0) // CHECK-NEXT: true - print(nil != e0) // CHECK-NEXT: false -} -nilComparison() - -var counter = 0 -func nextCounter() -> Int { - return counter++ -} - -let a: Int? = 123 -let b: Int? = nil -let c: Int? = nil -let d: Int? = 456 -let e: Int? = nil -let f: Int? = nil - -debugPrint(a ?? nextCounter()) // CHECK-NEXT: 123 -debugPrint(b ?? nextCounter()) // CHECK-NEXT: 0 -debugPrint(c ?? nextCounter()) // CHECK-NEXT: 1 -debugPrint(d ?? nextCounter()) // CHECK-NEXT: 456 -debugPrint(e ?? d ?? nextCounter()) // CHECK-NEXT: 456 -debugPrint(f ?? nextCounter()) // CHECK-NEXT: 2 - -func nextCounter2() -> Int? { - return nextCounter() -} - -debugPrint(c ?? d) // CHECK-NEXT: Optional(456) -debugPrint(c ?? e) // CHECK-NEXT: nil -debugPrint(a ?? nextCounter2()) // CHECK-NEXT: Optional(123) -debugPrint(b ?? nextCounter2()) // CHECK-NEXT: Optional(3) -debugPrint(c ?? nextCounter2()) // CHECK-NEXT: Optional(4) -debugPrint(d ?? nextCounter2()) // CHECK-NEXT: Optional(456) -debugPrint(e ?? d ?? nextCounter2()) // CHECK-NEXT: Optional(456) -debugPrint(f ?? nextCounter2()) // CHECK-NEXT: Optional(5) + expectFalse(e1 == nil) + expectTrue(e1 != nil) + expectTrue(e0 == nil) + expectFalse(e0 != nil) -import StdlibUnittest -import Swift + expectFalse(nil == e1) + expectTrue(nil != e1) + expectTrue(nil == e0) + expectFalse(nil != e0) -var OptionalTests = TestSuite("Optional") + /* + // FIXME: Optional() == nil where T: !Equatable + let _: X? = nil + let _: X? = X() + + expectFalse(x1 == nil) + expectTrue(x1 != nil) + expectTrue(x0 == nil) + expectFalse(x0 != nil) + + expectFalse(nil == x1) + expectTrue(nil != x1) + expectTrue(nil == x0) + expectFalse(nil != x0) + */ +} + +OptionalTests.test("??") { + var counter = 0 + func nextCounter() -> Int { counter += 1; return counter-1 } + func nextCounter2() -> Int? { return nextCounter() } + + let a: Int? = 123 + let b: Int? = nil + let c: Int? = nil + let d: Int? = 456 + let e: Int? = nil + let f: Int? = nil + + expectEqual(123, a ?? nextCounter()) + expectEqual(0, b ?? nextCounter()) + expectEqual(1, c ?? nextCounter()) + expectEqual(456, d ?? nextCounter()) + expectEqual(456, e ?? d ?? nextCounter()) + expectEqual(2, f ?? nextCounter()) + + expectEqual(Optional(456), c ?? d) + expectEqual(nil, c ?? e) + expectEqual(Optional(123), a ?? nextCounter2()) + expectEqual(Optional(3), b ?? nextCounter2()) + expectEqual(Optional(4), c ?? nextCounter2()) + expectEqual(Optional(456), d ?? nextCounter2()) + expectEqual(Optional(456), e ?? d ?? nextCounter2()) + expectEqual(Optional(5), f ?? nextCounter2()) +} OptionalTests.test("flatMap") { let half: Int32 -> Int16? = @@ -237,4 +179,130 @@ OptionalTests.test("flatMap") { expectEmpty((3 as Int32?).flatMap(half)) } +@inline(never) +func anyToAny(a: T, _ : U.Type) -> U { + return a as! U +} +@inline(never) +func anyToAnyOrNil(a: T, _ : U.Type) -> U? { + return a as? U +} +func canGenericCast(a: T, _ ty : U.Type) -> Bool { + return anyToAnyOrNil(a, ty) != nil +} + +OptionalTests.test("Casting Optional") { + let x = C() + let sx: C? = x + let nx: C? = nil + expectTrue(anyToAny(x, Optional.self)! === x) + expectTrue(anyToAny(sx, C.self) === x) + expectTrue(anyToAny(sx, Optional.self)! === x) + + expectTrue(anyToAny(nx, Optional.self) == nil) + expectTrue(anyToAnyOrNil(nx, C.self) == nil) + + let i = Int.max + let si: Int? = Int.max + let ni: Int? = nil + expectEqual(anyToAny(i, Optional.self)!, Int.max) + expectEqual(anyToAny(si, Int.self), Int.max) + expectEqual(anyToAny(si, Optional.self)!, Int.max) + + expectTrue(anyToAny(ni, Optional.self) == nil) + expectTrue(anyToAnyOrNil(ni, Int.self) == nil) + + let ssx: C?? = sx + expectTrue(anyToAny(ssx, Optional.self)! === x) + expectTrue(anyToAny(x, Optional>.self)!! === x) + expectTrue(anyToAnyOrNil(ni, Int.self) == nil) +} + +OptionalTests.test("Casting Optional Traps") { + let nx: C? = nil + expectCrashLater() + anyToAny(nx, Int.self) +} + +class TestNoString {} +class TestString : CustomStringConvertible, CustomDebugStringConvertible { + var description: String { + return "AString" + } + var debugDescription: String { + return "XString" + } +} +class TestStream : Streamable { + func writeTo(inout target: Target) { + target.write("AStream") + } +} + +func debugPrintStr(a: T) -> String { + var s = "" + debugPrint(a, terminator: "", toStream: &s) + return s +} +// Optional should not conform to output stream protocols itself, but is +// convertible to them if its wrapped type is. +// Furthermore, printing an Optional should always print the debug +// description regardless of whether the wrapper type conforms to an +// output stream protocol. +OptionalTests.test("Optional OutputStream") { + let optNoString: TestNoString? = TestNoString() + expectFalse(optNoString is CustomStringConvertible) + expectFalse(canGenericCast(optNoString, CustomStringConvertible.self)) + expectFalse(optNoString is Streamable) + expectFalse(canGenericCast(optNoString, Streamable.self)) + expectTrue(optNoString is CustomDebugStringConvertible) + expectTrue(canGenericCast(optNoString, CustomDebugStringConvertible.self)) + expectEqual(String(optNoString), "Optional(main.TestNoString)") + expectEqual(debugPrintStr(optNoString), "Optional(main.TestNoString)") + + let iouNoString: TestNoString! = TestNoString() + // IUO directly conforms to CustomStringConvertible. + // Disabled pending SR-164 + // expectTrue(iouNoString is CustomStringConvertible) + expectTrue(canGenericCast(iouNoString, CustomStringConvertible.self)) + expectFalse(iouNoString is Streamable) + expectFalse(canGenericCast(iouNoString, Streamable.self)) + // CustomDebugStringConvertible conformance is a temporary hack. + // Disabled pending SR-164 + // expectTrue(iouNoString is CustomDebugStringConvertible) + expectTrue(canGenericCast(iouNoString, CustomDebugStringConvertible.self)) + expectEqual(String(iouNoString), "main.TestNoString") + expectEqual(debugPrintStr(iouNoString), "main.TestNoString") + + let optString: TestString? = TestString() + expectTrue(optString is CustomStringConvertible) + expectTrue(canGenericCast(optString, CustomStringConvertible.self)) + expectTrue(optString is CustomDebugStringConvertible) + expectTrue(canGenericCast(optString, CustomDebugStringConvertible.self)) + expectEqual(String(TestString()), "AString") + expectEqual(String(optString), "Optional(XString)") + expectEqual(debugPrintStr(optString), "Optional(XString)") + + let iouString: TestString! = TestString() + expectTrue(iouString is CustomStringConvertible) + expectTrue(canGenericCast(iouString, CustomStringConvertible.self)) + // CustomDebugStringConvertible conformance is a temporary hack. + expectTrue(iouString is CustomDebugStringConvertible) + expectTrue(canGenericCast(iouString, CustomDebugStringConvertible.self)) + expectEqual(String(iouString), "AString") + // FIXME: Ideally the debug output would be "XString", but a reasonable + // implementation of that behavior requires conditional conformance. + // (directly invoking debugPrint(Any) already works correctly). + expectEqual(debugPrintStr(iouString), "AString") + + let optStream: TestStream? = TestStream() + expectTrue(optStream is Streamable) + expectTrue(canGenericCast(optStream, Streamable.self)) + expectTrue(optStream is CustomDebugStringConvertible) + expectTrue(canGenericCast(optStream, CustomDebugStringConvertible.self)) + expectEqual(String(TestStream()), "AStream") + expectEqual(String(optStream), "Optional(AStream)") + expectEqual(debugPrintStr(optStream), "Optional(AStream)") +} + runAllTests() diff --git a/test/1_stdlib/POSIX.swift b/test/1_stdlib/POSIX.swift index dd19fc5c05cad..f5819650b8970 100644 --- a/test/1_stdlib/POSIX.swift +++ b/test/1_stdlib/POSIX.swift @@ -1,29 +1,40 @@ // RUN: %target-run-simple-swift // REQUIRES: executable_test -// XFAIL: linux -// FIXME: Glibc needs the same overlay. - import StdlibUnittest -import Darwin - -var POSIXSemaphore = TestSuite("POSIXSemaphore") +#if os(Linux) + import Glibc +#else + import Darwin +#endif + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + +var POSIXTests = TestSuite("POSIXTests") let semaphoreName = "TestSem" +let fn = "test.txt" -POSIXSemaphore.setUp { +POSIXTests.setUp { sem_unlink(semaphoreName) + unlink(fn) } // Failed semaphore creation. -POSIXSemaphore.test("sem_open fail") { +POSIXTests.test("sem_open fail") { let sem = sem_open(semaphoreName, 0) expectEqual(SEM_FAILED, sem) expectEqual(ENOENT, errno) } // Successful semaphore creation. -POSIXSemaphore.test("sem_open success") { +POSIXTests.test("sem_open success") { let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1) expectNotEqual(SEM_FAILED, sem) @@ -35,7 +46,7 @@ POSIXSemaphore.test("sem_open success") { } // Successful semaphore creation with O_EXCL. -POSIXSemaphore.test("sem_open O_EXCL success") { +POSIXTests.test("sem_open O_EXCL success") { let sem = sem_open(semaphoreName, O_CREAT | O_EXCL, 0o777, 1) expectNotEqual(SEM_FAILED, sem) @@ -47,7 +58,7 @@ POSIXSemaphore.test("sem_open O_EXCL success") { } // Successful creation and re-obtaining of existing semaphore. -POSIXSemaphore.test("sem_open existing") { +POSIXTests.test("sem_open existing") { let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1) expectNotEqual(SEM_FAILED, sem) @@ -64,7 +75,7 @@ POSIXSemaphore.test("sem_open existing") { } // Fail because the semaphore already exists. -POSIXSemaphore.test("sem_open existing O_EXCL fail") { +POSIXTests.test("sem_open existing O_EXCL fail") { let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1) expectNotEqual(SEM_FAILED, sem) @@ -78,6 +89,111 @@ POSIXSemaphore.test("sem_open existing O_EXCL fail") { let res2 = sem_unlink(semaphoreName) expectEqual(0, res2) } + +// Fail because file doesn't exist. +POSIXTests.test("fcntl(CInt, CInt): fail") { + let fd = open(fn, 0) + expectEqual(-1, fd) + expectEqual(ENOENT, errno) + + let _ = fcntl(fd, F_GETFL) + expectEqual(EBADF, errno) +} + +// Change modes on existing file. +POSIXTests.test("fcntl(CInt, CInt): F_GETFL/F_SETFL success with file") { + // Create and open file. + let fd = open(fn, O_CREAT, 0o666) + expectGT(Int(fd), 0) + + var flags = fcntl(fd, F_GETFL) + expectGE(Int(flags), 0) + + // Change to APPEND mode... + var rc = fcntl(fd, F_SETFL, O_APPEND) + expectEqual(0, rc) + + flags = fcntl(fd, F_GETFL) + expectEqual(flags | O_APPEND, flags) + + // Change back... + rc = fcntl(fd, F_SETFL, 0) + expectEqual(0, rc) + + flags = fcntl(fd, F_GETFL) + expectGE(Int(flags), 0) + + // Clean up... + rc = close(fd) + expectEqual(0, rc) + + rc = unlink(fn) + expectEqual(0, rc) +} + +POSIXTests.test("fcntl(CInt, CInt, CInt): block and unblocking sockets success") { + // Create socket, note: socket created by default in blocking mode... + let sock = socket(PF_INET, 1, 0) + expectGT(Int(sock), 0) + + var flags = fcntl(sock, F_GETFL) + expectGE(Int(flags), 0) + + // Change mode of socket to non-blocking... + var rc = fcntl(sock, F_SETFL, flags | O_NONBLOCK) + expectEqual(0, rc) + + flags = fcntl(sock, F_GETFL) + expectEqual((flags | O_NONBLOCK), flags) + + // Change back to blocking... + rc = fcntl(sock, F_SETFL, flags & ~O_NONBLOCK) + expectEqual(0, rc) + + flags = fcntl(sock, F_GETFL) + expectGE(Int(flags), 0) + + // Clean up... + rc = close(sock) + expectEqual(0, rc) +} + +POSIXTests.test("fcntl(CInt, CInt, UnsafeMutablePointer): locking and unlocking success") { + // Create the file and add data to it... + var fd = open(fn, O_CREAT | O_WRONLY, 0o666) + expectGT(Int(fd), 0) + + let data = "Testing 1 2 3" + let bytesWritten = write(fd, data, data.utf8.count) + expectEqual(data.utf8.count, bytesWritten) + + var rc = close(fd) + expectEqual(0, rc) + + // Re-open the file... + fd = open(fn, 0) + expectGT(Int(fd), 0) + + // Lock for reading... + var flck = flock() + flck.l_type = Int16(F_RDLCK) + flck.l_len = off_t(data.utf8.count) + rc = fcntl(fd, F_SETLK, &flck) + expectEqual(0, rc) + + // Unlock for reading... + flck = flock() + flck.l_type = Int16(F_UNLCK) + rc = fcntl(fd, F_SETLK, &flck) + expectEqual(0, rc) + + // Clean up... + rc = close(fd) + expectEqual(0, rc) + + rc = unlink(fn) + expectEqual(0, rc) +} runAllTests() diff --git a/test/1_stdlib/Print.swift b/test/1_stdlib/Print.swift index ddcb274216391..42ac0ee28392c 100644 --- a/test/1_stdlib/Print.swift +++ b/test/1_stdlib/Print.swift @@ -1,1028 +1,73 @@ -// RUN: mkdir -p %t -// RUN: %target-build-swift %s -parse-stdlib -Xfrontend -disable-access-control -o %t/a.out -Xlinker -dead_strip -// RUN: %target-run %t/a.out env | FileCheck %s -// RUN: %target-run %t/a.out ru_RU.UTF-8 | FileCheck %s +// RUN: rm -rf %t && mkdir %t +// RUN: %target-build-swift -c -force-single-frontend-invocation -parse-as-library -emit-module -emit-module-path %t/PrintTestTypes.swiftmodule -o %t/PrintTestTypes.o %S/Inputs/PrintTestTypes.swift +// RUN: %target-build-swift %s -Xlinker %t/PrintTestTypes.o -I %t -L %t -o %t/main +// RUN: %target-run %t/main // REQUIRES: executable_test -// XFAIL: linux +import StdlibUnittest +import PrintTestTypes -import Swift -import Darwin - -// Interpret the command line arguments. -var arg = Process.arguments[1] - -if arg == "env" { - setlocale(LC_ALL, "") -} else { - setlocale(LC_ALL, arg) -} - -func stdlibTypesHaveDescription() { - func hasDescription(_: CustomStringConvertible) {} - - hasDescription(Int(42)) - hasDescription(UInt(42)) - - hasDescription(Int8(-42)) - hasDescription(Int16(-42)) - hasDescription(Int32(-42)) - hasDescription(Int64(-42)) - hasDescription(UInt8(42)) - hasDescription(UInt16(42)) - hasDescription(UInt32(42)) - hasDescription(UInt64(42)) - - hasDescription(Bool(true)) - - hasDescription(CChar(42)) - hasDescription(CUnsignedChar(42)) - hasDescription(CUnsignedShort(42)) - hasDescription(CUnsignedInt(42)) - hasDescription(CUnsignedLong(42)) - hasDescription(CUnsignedLongLong(42)) - hasDescription(CSignedChar(42)) - hasDescription(CShort(42)) - hasDescription(CInt(42)) - hasDescription(CLong(42)) - hasDescription(CLongLong(42)) - hasDescription(CFloat(1.0)) - hasDescription(CDouble(1.0)) - - hasDescription(CWideChar(42)) - hasDescription(CChar16(42)) - hasDescription(CChar32(42)) - hasDescription(CBool(true)) -} - -var failed = false - -func printedIs( - object: T, _ expected1: String, expected2: String? = nil, - file: StaticString = __FILE__, line: UInt = __LINE__ -) { - let actual = String(object) - var match = expected1 == actual - if !match && expected2 != nil { - match = expected2! == actual - } - if !match { - print( - "check failed at \(file), line \(line)", - "expected: \"\(expected1)\" or \"\(expected2)\"", - "actual: \"\(actual)\"", - "", - separator: "\n") - failed = true - } -} - -func debugPrintedIs( - object: T, _ expected1: String, expected2: String? = nil, - file: StaticString = __FILE__, line: UInt = __LINE__ -) { - var actual = "" - debugPrint(object, terminator: "", toStream: &actual) - if expected1 != actual && (expected2 != nil && expected2! != actual) { - print( - "check failed at \(file), line \(line)", - "expected: \"\(expected1)\" or \"\(expected2)\"", - "actual: \"\(actual)\"", - "", - separator: "\n") - failed = true - } -} - -func assertEquals( - expected: String, _ actual: String, - file: StaticString = __FILE__, line: UInt = __LINE__ -) { - if expected != actual { - print( - "check failed at \(file), line \(line)", - "expected: \"\(expected)\"", - "actual: \"\(actual)\"", - "", - separator: "\n") - failed = true - } -} - -func test_StdlibTypesPrinted() { - printedIs(Float(1.0), "1.0") - printedIs(Float(-1.0), "-1.0") - printedIs(Double(1.0), "1.0") - printedIs(Double(-1.0), "-1.0") - - printedIs(CChar(42), "42") - printedIs(CUnsignedChar(42), "42") - printedIs(CUnsignedShort(42), "42") - printedIs(CUnsignedInt(42), "42") - printedIs(CUnsignedLong(42), "42") - printedIs(CUnsignedLongLong(42), "42") - printedIs(CSignedChar(42), "42") - printedIs(CShort(42), "42") - printedIs(CInt(42), "42") - printedIs(CLong(42), "42") - printedIs(CLongLong(42), "42") - printedIs(CFloat(1.0), "1.0") - printedIs(CFloat(-1.0), "-1.0") - printedIs(CDouble(1.0), "1.0") - printedIs(CDouble(-1.0), "-1.0") - - printedIs(CWideChar(42), "*") - printedIs(CChar16(42), "42") - printedIs(CChar32(42), "*") - printedIs(CBool(true), "true") - printedIs(CBool(false), "false") - - var s: String = "abc" - printedIs(s, "abc") - debugPrintedIs(s, "\"abc\"") - s = "\\ \' \" \0 \n \r \t \u{05}" - debugPrintedIs(s, "\"\\\\ \\\' \\\" \\0 \\n \\r \\t \\u{05}\"") - - let ch: Character = "a" - printedIs(ch, "a") - debugPrintedIs(ch, "\"a\"") - - var us: UnicodeScalar = "a" - printedIs(us, "a") - debugPrintedIs(us, "\"a\"") - us = "\\" - printedIs(us, "\\") - assertEquals("\"\\\\\"", us.description) - debugPrintedIs(us, "\"\\\\\"") - us = "あ" - printedIs(us, "あ") - assertEquals("\"あ\"", us.description) - debugPrintedIs(us, "\"\\u{3042}\"") - - if true { - var implicitlyUnwrappedString: String! = nil - printedIs(implicitlyUnwrappedString, "nil") - implicitlyUnwrappedString = "meow" - printedIs(implicitlyUnwrappedString, "meow") - } - if true { - var optionalString: String? = nil - printedIs(optionalString, "nil") - optionalString = "meow" - printedIs(optionalString, "Optional(\"meow\")") - } - if true { - struct Wrapper : CustomStringConvertible { - var x: CustomStringConvertible? = nil - - var description: String { - return "Wrapper(" + x.debugDescription + ")" - } - } - printedIs(Wrapper(), "Wrapper(nil)") - printedIs(Wrapper(x: Wrapper()), "Wrapper(Optional(Wrapper(nil)))") - printedIs(Wrapper(x: Wrapper(x: Wrapper())), - "Wrapper(Optional(Wrapper(Optional(Wrapper(nil)))))") - } - - print("test_StdlibTypesPrinted done") -} -test_StdlibTypesPrinted() -// CHECK: test_StdlibTypesPrinted done - -func test_IntegerPrinting() { - if (UInt64(Int.max) > 0x1_0000_0000 as UInt64) { - printedIs(Int.min, "-9223372036854775808") - printedIs(Int.max, "9223372036854775807") - } else { - printedIs(Int.min, "-2147483648") - printedIs(Int.max, "2147483647") - } - printedIs(Int(0), "0") - printedIs(Int(42), "42") - printedIs(Int(-42), "-42") - - if (UInt64(UInt.max) > 0x1_0000_0000 as UInt64) { - printedIs(UInt.max, "18446744073709551615") - } else { - printedIs(UInt.max, "4294967295") - } - printedIs(UInt.min, "0") - printedIs(UInt(0), "0") - printedIs(UInt(42), "42") - - printedIs(Int8.min, "-128") - printedIs(Int8.max, "127") - printedIs(Int8(0), "0") - printedIs(Int8(42), "42") - printedIs(Int8(-42), "-42") - - printedIs(UInt8.min, "0") - printedIs(UInt8.max, "255") - printedIs(UInt8(0), "0") - printedIs(UInt8(42), "42") - - printedIs(Int16.min, "-32768") - printedIs(Int16.max, "32767") - printedIs(Int16(0), "0") - printedIs(Int16(42), "42") - printedIs(Int16(-42), "-42") - - printedIs(UInt16.min, "0") - printedIs(UInt16.max, "65535") - printedIs(UInt16(0), "0") - printedIs(UInt16(42), "42") - - printedIs(Int32.min, "-2147483648") - printedIs(Int32.max, "2147483647") - printedIs(Int32(0), "0") - printedIs(Int32(42), "42") - printedIs(Int32(-42), "-42") - - printedIs(UInt32.min, "0") - printedIs(UInt32.max, "4294967295") - printedIs(UInt32(0), "0") - printedIs(UInt32(42), "42") - - printedIs(Int64.min, "-9223372036854775808") - printedIs(Int64.max, "9223372036854775807") - printedIs(Int64(0), "0") - printedIs(Int64(42), "42") - printedIs(Int64(-42), "-42") - - printedIs(UInt64.min, "0") - printedIs(UInt64.max, "18446744073709551615") - printedIs(UInt64(0), "0") - printedIs(UInt64(42), "42") - - printedIs(Int8(-42), "-42") - printedIs(Int16(-42), "-42") - printedIs(Int32(-42), "-42") - printedIs(Int64(-42), "-42") - printedIs(UInt8(42), "42") - printedIs(UInt16(42), "42") - printedIs(UInt32(42), "42") - printedIs(UInt64(42), "42") - - print("test_IntegerPrinting done") -} -test_IntegerPrinting() -// CHECK: test_IntegerPrinting done - -func test_FloatingPointPrinting() { - func asFloat32(f: Float32) -> Float32 { return f } - func asFloat64(f: Float64) -> Float64 { return f } -#if arch(i386) || arch(x86_64) - func asFloat80(f: Swift.Float80) -> Swift.Float80 { return f } -#endif - - printedIs(Float.infinity, "inf") - printedIs(-Float.infinity, "-inf") - printedIs(Float.NaN, "nan") - printedIs(asFloat32(0.0), "0.0") - printedIs(asFloat32(1.0), "1.0") - printedIs(asFloat32(-1.0), "-1.0") - printedIs(asFloat32(100.125), "100.125") - printedIs(asFloat32(-100.125), "-100.125") - - printedIs(Double.infinity, "inf") - printedIs(-Double.infinity, "-inf") - printedIs(Double.NaN, "nan") - printedIs(asFloat64(0.0), "0.0") - printedIs(asFloat64(1.0), "1.0") - printedIs(asFloat64(-1.0), "-1.0") - printedIs(asFloat64(100.125), "100.125") - printedIs(asFloat64(-100.125), "-100.125") - - printedIs(asFloat32(1.00001), "1.00001") - printedIs(asFloat32(125000000000000000.0), "1.25e+17") - printedIs(asFloat32(12500000000000000.0), "1.25e+16") - printedIs(asFloat32(1250000000000000.0), "1.25e+15") - printedIs(asFloat32(125000000000000.0), "1.25e+14") - printedIs(asFloat32(12500000000000.0), "1.25e+13") - printedIs(asFloat32(1250000000000.0), "1.25e+12") - printedIs(asFloat32(125000000000.0), "1.25e+11") - printedIs(asFloat32(12500000000.0), "1.25e+10") - printedIs(asFloat32(1250000000.0), "1.25e+09") - printedIs(asFloat32(125000000.0), "1.25e+08") - printedIs(asFloat32(12500000.0), "1.25e+07") - printedIs(asFloat32(1250000.0), "1.25e+06") - printedIs(asFloat32(125000.0), "125000.0") - printedIs(asFloat32(12500.0), "12500.0") - printedIs(asFloat32(1250.0), "1250.0") - printedIs(asFloat32(125.0), "125.0") - printedIs(asFloat32(12.5), "12.5") - printedIs(asFloat32(1.25), "1.25") - printedIs(asFloat32(0.125), "0.125") - printedIs(asFloat32(0.0125), "0.0125") - printedIs(asFloat32(0.00125), "0.00125") - printedIs(asFloat32(0.000125), "0.000125") - printedIs(asFloat32(0.0000125), "1.25e-05") - printedIs(asFloat32(0.00000125), "1.25e-06") - printedIs(asFloat32(0.000000125), "1.25e-07") - printedIs(asFloat32(0.0000000125), "1.25e-08") - printedIs(asFloat32(0.00000000125), "1.25e-09") - printedIs(asFloat32(0.000000000125), "1.25e-10") - printedIs(asFloat32(0.0000000000125), "1.25e-11") - printedIs(asFloat32(0.00000000000125), "1.25e-12") - printedIs(asFloat32(0.000000000000125), "1.25e-13") - printedIs(asFloat32(0.0000000000000125), "1.25e-14") - printedIs(asFloat32(0.00000000000000125), "1.25e-15") - printedIs(asFloat32(0.000000000000000125), "1.25e-16") - printedIs(asFloat32(0.0000000000000000125), "1.25e-17") - - printedIs(asFloat64(1.00000000000001), "1.00000000000001") - printedIs(asFloat64(125000000000000000.0), "1.25e+17") - printedIs(asFloat64(12500000000000000.0), "1.25e+16") - printedIs(asFloat64(1250000000000000.0), "1.25e+15") - printedIs(asFloat64(125000000000000.0), "125000000000000.0") - printedIs(asFloat64(12500000000000.0), "12500000000000.0") - printedIs(asFloat64(1250000000000.0), "1250000000000.0") - printedIs(asFloat64(125000000000.0), "125000000000.0") - printedIs(asFloat64(12500000000.0), "12500000000.0") - printedIs(asFloat64(1250000000.0), "1250000000.0") - printedIs(asFloat64(125000000.0), "125000000.0") - printedIs(asFloat64(12500000.0), "12500000.0") - printedIs(asFloat64(1250000.0), "1250000.0") - printedIs(asFloat64(125000.0), "125000.0") - printedIs(asFloat64(12500.0), "12500.0") - printedIs(asFloat64(1250.0), "1250.0") - printedIs(asFloat64(125.0), "125.0") - printedIs(asFloat64(12.5), "12.5") - printedIs(asFloat64(1.25), "1.25") - printedIs(asFloat64(0.125), "0.125") - printedIs(asFloat64(0.0125), "0.0125") - printedIs(asFloat64(0.00125), "0.00125") - printedIs(asFloat64(0.000125), "0.000125") - printedIs(asFloat64(0.0000125), "1.25e-05") - printedIs(asFloat64(0.00000125), "1.25e-06") - printedIs(asFloat64(0.000000125), "1.25e-07") - printedIs(asFloat64(0.0000000125), "1.25e-08") - printedIs(asFloat64(0.00000000125), "1.25e-09") - printedIs(asFloat64(0.000000000125), "1.25e-10") - printedIs(asFloat64(0.0000000000125), "1.25e-11") - printedIs(asFloat64(0.00000000000125), "1.25e-12") - printedIs(asFloat64(0.000000000000125), "1.25e-13") - printedIs(asFloat64(0.0000000000000125), "1.25e-14") - printedIs(asFloat64(0.00000000000000125), "1.25e-15") - printedIs(asFloat64(0.000000000000000125), "1.25e-16") - printedIs(asFloat64(0.0000000000000000125), "1.25e-17") - -#if arch(i386) || arch(x86_64) - printedIs(asFloat80(1.00000000000000001), "1.00000000000000001") - printedIs(asFloat80(12500000000000000000.0), "1.25e+19") - printedIs(asFloat80(1250000000000000000.0), "1.25e+18") - printedIs(asFloat80(125000000000000000.0), "125000000000000000.0") - printedIs(asFloat80(12500000000000000.0), "12500000000000000.0") - printedIs(asFloat80(1250000000000000.0), "1250000000000000.0") - printedIs(asFloat80(125000000000000.0), "125000000000000.0") - printedIs(asFloat80(12500000000000.0), "12500000000000.0") - printedIs(asFloat80(1250000000000.0), "1250000000000.0") - printedIs(asFloat80(125000000000.0), "125000000000.0") - printedIs(asFloat80(12500000000.0), "12500000000.0") - printedIs(asFloat80(1250000000.0), "1250000000.0") - printedIs(asFloat80(125000000.0), "125000000.0") - printedIs(asFloat80(12500000.0), "12500000.0") - printedIs(asFloat80(1250000.0), "1250000.0") - printedIs(asFloat80(125000.0), "125000.0") - printedIs(asFloat80(12500.0), "12500.0") - printedIs(asFloat80(1250.0), "1250.0") - printedIs(asFloat80(125.0), "125.0") - printedIs(asFloat80(12.5), "12.5") - printedIs(asFloat80(1.25), "1.25") - printedIs(asFloat80(0.125), "0.125") - printedIs(asFloat80(0.0125), "0.0125") - printedIs(asFloat80(0.00125), "0.00125") - printedIs(asFloat80(0.000125), "0.000125") - printedIs(asFloat80(0.0000125), "1.25e-05") - printedIs(asFloat80(0.00000125), "1.25e-06") - printedIs(asFloat80(0.000000125), "1.25e-07") - printedIs(asFloat80(0.0000000125), "1.25e-08") - printedIs(asFloat80(0.00000000125), "1.25e-09") - printedIs(asFloat80(0.000000000125), "1.25e-10") - printedIs(asFloat80(0.0000000000125), "1.25e-11") - printedIs(asFloat80(0.00000000000125), "1.25e-12") - printedIs(asFloat80(0.000000000000125), "1.25e-13") - printedIs(asFloat80(0.0000000000000125), "1.25e-14") - printedIs(asFloat80(0.00000000000000125), "1.25e-15") - printedIs(asFloat80(0.000000000000000125), "1.25e-16") - printedIs(asFloat80(0.0000000000000000125), "1.25e-17") -#endif - - print("test_FloatingPointPrinting done") -} -test_FloatingPointPrinting() -// CHECK: test_FloatingPointPrinting done - - -func test_BoolPrinting() { - printedIs(Bool(true), "true") - printedIs(Bool(false), "false") - - printedIs(true, "true") - printedIs(false, "false") - - print("test_BoolPrinting done") -} -test_BoolPrinting() -// CHECK: test_BoolPrinting done - -func test_CTypesPrinting() { - printedIs(CChar(42), "42") - printedIs(CUnsignedChar(42), "42") - printedIs(CUnsignedShort(42), "42") - printedIs(CUnsignedInt(42), "42") - printedIs(CUnsignedLong(42), "42") - printedIs(CUnsignedLongLong(42), "42") - printedIs(CSignedChar(42), "42") - printedIs(CShort(42), "42") - printedIs(CInt(42), "42") - printedIs(CLong(42), "42") - printedIs(CLongLong(42), "42") - printedIs(CFloat(1.0), "1.0") - printedIs(CFloat(-1.0), "-1.0") - printedIs(CDouble(1.0), "1.0") - printedIs(CDouble(-1.0), "-1.0") - - printedIs(CWideChar(42), "*") - printedIs(CChar16(42), "42") - printedIs(CChar32(42), "*") - printedIs(CBool(true), "true") - printedIs(CBool(false), "false") - - print("test_CTypesPrinting done") -} -test_CTypesPrinting() -// CHECK: test_CTypesPrinting done - - -func test_PointerPrinting() { - let nullUP = UnsafeMutablePointer() - let fourByteUP = UnsafeMutablePointer(bitPattern: 0xabcd1234 as UInt) - -#if !(arch(i386) || arch(arm)) - let eightByteAddr: UInt = 0xabcddcba12344321 - let eightByteUP = UnsafeMutablePointer(bitPattern: eightByteAddr) -#endif - -#if arch(i386) || arch(arm) - let expectedNull = "0x00000000" - printedIs(fourByteUP, "0xabcd1234") -#else - let expectedNull = "0x0000000000000000" - printedIs(fourByteUP, "0x00000000abcd1234") - printedIs(eightByteUP, "0xabcddcba12344321") -#endif - - printedIs(nullUP, expectedNull) - - printedIs(UnsafeBufferPointer(start: nullUP, count: 0), - "UnsafeBufferPointer(start: \(expectedNull), length: 0)") - printedIs(UnsafeMutableBufferPointer(start: nullUP, count: 0), - "UnsafeMutableBufferPointer(start: \(expectedNull), length: 0)") - - printedIs(COpaquePointer(), expectedNull) - printedIs(CVaListPointer(_fromUnsafeMutablePointer: nullUP), expectedNull) - printedIs(AutoreleasingUnsafeMutablePointer(), expectedNull) - - print("test_PointerPrinting done") -} -test_PointerPrinting() -// CHECK: test_PointerPrinting done - - -protocol ProtocolUnrelatedToPrinting {} - -struct StructPrintable : CustomStringConvertible, ProtocolUnrelatedToPrinting { - let x: Int - - init(_ x: Int) { - self.x = x - } - - var description: String { - return "►\(x)◀︎" - } -} - -struct LargeStructPrintable : CustomStringConvertible, ProtocolUnrelatedToPrinting { - let a: Int - let b: Int - let c: Int - let d: Int - - init(_ a: Int, _ b: Int, _ c: Int, _ d: Int) { - self.a = a - self.b = b - self.c = c - self.d = d - } - - var description: String { - return "<\(a) \(b) \(c) \(d)>" - } +let PrintTests = TestSuite("Print") +PrintTests.test("Metatype") { + expectPrinted("Int", Int.self) + expectDebugPrinted("Swift.Int", Int.self) } -struct StructDebugPrintable : CustomDebugStringConvertible { - let x: Int - - init(_ x: Int) { - self.x = x - } - - var debugDescription: String { - return "►\(x)◀︎" - } -} - -struct StructVeryPrintable : CustomStringConvertible, CustomDebugStringConvertible, ProtocolUnrelatedToPrinting { - let x: Int - - init(_ x: Int) { - self.x = x - } - - var description: String { - return "" - } - - var debugDescription: String { - return "" - } -} - -struct EmptyStructWithoutDescription {} - -struct WithoutDescription { - let x: Int - - init(_ x: Int) { - self.x = x - } -} - -struct ValuesWithoutDescription { - let t: T - let u: U - let v: V - - init(_ t: T, _ u: U, _ v: V) { - self.t = t - self.u = u - self.v = v - } -} - - -class ClassPrintable : CustomStringConvertible, ProtocolUnrelatedToPrinting { - let x: Int - - init(_ x: Int) { - self.x = x - } - - var description: String { - return "►\(x)◀︎" - } -} - -class ClassVeryPrintable : CustomStringConvertible, CustomDebugStringConvertible, ProtocolUnrelatedToPrinting { - let x: Int - - init(_ x: Int) { - self.x = x - } - - var description: String { - return "" - } - - var debugDescription: String { - return "" - } -} - -func test_ObjectPrinting() { - if true { - let s = StructPrintable(1) - printedIs(s, "►1◀︎") - } - if true { - let s: ProtocolUnrelatedToPrinting = StructPrintable(1) - printedIs(s, "►1◀︎") - } - if true { - let s: CustomStringConvertible = StructPrintable(1) - printedIs(s, "►1◀︎") - } - if true { - let s: Any = StructPrintable(1) - printedIs(s, "►1◀︎") - } - - if true { - let s = LargeStructPrintable(10, 20, 30, 40) - printedIs(s, "<10 20 30 40>") - } - if true { - let s: ProtocolUnrelatedToPrinting = LargeStructPrintable(10, 20, 30, 40) - printedIs(s, "<10 20 30 40>") - } - if true { - let s: CustomStringConvertible = LargeStructPrintable(10, 20, 30, 40) - printedIs(s, "<10 20 30 40>") - } - if true { - let s: Any = LargeStructPrintable(10, 20, 30, 40) - printedIs(s, "<10 20 30 40>") - } - - if true { - let s = StructVeryPrintable(1) - printedIs(s, "") - } - if true { - let s: ProtocolUnrelatedToPrinting = StructVeryPrintable(1) - printedIs(s, "") - } - if true { - let s: CustomStringConvertible = StructVeryPrintable(1) - printedIs(s, "") - } - if true { - let s: CustomDebugStringConvertible = StructVeryPrintable(1) - printedIs(s, "") - } - if true { - let s: Any = StructVeryPrintable(1) - printedIs(s, "") - } - - if true { - let c = ClassPrintable(1) - printedIs(c, "►1◀︎") - } - if true { - let c: ProtocolUnrelatedToPrinting = ClassPrintable(1) - printedIs(c, "►1◀︎") - } - if true { - let c: CustomStringConvertible = ClassPrintable(1) - printedIs(c, "►1◀︎") - } - if true { - let c: Any = ClassPrintable(1) - printedIs(c, "►1◀︎") - } - - if true { - let c = ClassVeryPrintable(1) - printedIs(c, "") - } - if true { - let c: ProtocolUnrelatedToPrinting = ClassVeryPrintable(1) - printedIs(c, "") - } - if true { - let c: CustomStringConvertible = ClassVeryPrintable(1) - printedIs(c, "") - } - if true { - let c: CustomDebugStringConvertible = ClassVeryPrintable(1) - printedIs(c, "") - } - if true { - let c: Any = ClassVeryPrintable(1) - printedIs(c, "") - } - - print("test_ObjectPrinting done") -} -test_ObjectPrinting() -// CHECK: test_ObjectPrinting done - -func test_ThickMetatypePrintingImpl( - thickMetatype: T.Type, - _ expectedPrint: String, - _ expectedDebug: String -) { - printedIs(thickMetatype, expectedPrint) - printedIs([ thickMetatype ], "[" + expectedDebug + "]") - debugPrintedIs(thickMetatype, expectedDebug) - debugPrintedIs([ thickMetatype ], "[" + expectedDebug + "]") -} - -func test_gcMetatypePrinting() { - let structMetatype = StructPrintable.self - printedIs(structMetatype, "StructPrintable") - debugPrintedIs(structMetatype, "a.StructPrintable") - printedIs([ structMetatype ], "[a.StructPrintable]") - debugPrintedIs([ structMetatype ], "[a.StructPrintable]") - test_ThickMetatypePrintingImpl(structMetatype, "StructPrintable", - "a.StructPrintable") - - let classMetatype = ClassPrintable.self - printedIs(classMetatype, "ClassPrintable") - debugPrintedIs(classMetatype, "a.ClassPrintable") - printedIs([ classMetatype ], "[a.ClassPrintable]") - debugPrintedIs([ classMetatype ], "[a.ClassPrintable]") - test_ThickMetatypePrintingImpl(classMetatype, "ClassPrintable", - "a.ClassPrintable") - - print("test_gcMetatypePrinting done") -} -test_gcMetatypePrinting() -// CHECK: test_gcMetatypePrinting done - -func test_ArrayPrinting() { - let arrayOfInts: [Int] = [] - printedIs(arrayOfInts, "[]") - - printedIs([ 1 ], "[1]") - printedIs([ 1, 2 ], "[1, 2]") - printedIs([ 1, 2, 3 ], "[1, 2, 3]") - - printedIs([ "foo", "bar", "bas" ], "[\"foo\", \"bar\", \"bas\"]") - debugPrintedIs([ "foo", "bar", "bas" ], "[\"foo\", \"bar\", \"bas\"]") - - printedIs([ StructPrintable(1), StructPrintable(2), - StructPrintable(3) ], - "[►1◀︎, ►2◀︎, ►3◀︎]") - - printedIs([ LargeStructPrintable(10, 20, 30, 40), - LargeStructPrintable(50, 60, 70, 80) ], - "[<10 20 30 40>, <50 60 70 80>]") - - printedIs([ StructDebugPrintable(1) ], "[►1◀︎]") - - printedIs([ ClassPrintable(1), ClassPrintable(2), - ClassPrintable(3) ], - "[►1◀︎, ►2◀︎, ►3◀︎]") - - printedIs([ ClassPrintable(1), ClassPrintable(2), - ClassPrintable(3) ] as Array, - "[►1◀︎, ►2◀︎, ►3◀︎]") - - print("test_ArrayPrinting done") -} -test_ArrayPrinting() -// CHECK: test_ArrayPrinting done - -func test_DictionaryPrinting() { - var dictSI: Dictionary = [:] - printedIs(dictSI, "[:]") - debugPrintedIs(dictSI, "[:]") - - dictSI = [ "aaa": 1 ] - printedIs(dictSI, "[\"aaa\": 1]") - debugPrintedIs(dictSI, "[\"aaa\": 1]") - - dictSI = [ "aaa": 1, "bbb": 2 ] - printedIs(dictSI, "[\"aaa\": 1, \"bbb\": 2]", expected2: "[\"bbb\": 2, \"aaa\": 1]") - debugPrintedIs(dictSI, "[\"aaa\": 1, \"bbb\": 2]", expected2: "[\"bbb\": 2, \"aaa\": 1]") - - let dictSS = [ "aaa": "bbb" ] - printedIs(dictSS, "[\"aaa\": \"bbb\"]") - debugPrintedIs(dictSS, "[\"aaa\": \"bbb\"]") - - print("test_DictionaryPrinting done") -} -test_DictionaryPrinting() -// CHECK: test_DictionaryPrinting done - -func test_SetPrinting() { - var sI = Set() - printedIs(sI, "[]") - debugPrintedIs(sI, "Set([])") - - sI = Set([11, 22]) - printedIs(sI, "[11, 22]", expected2: "[22, 11]") - debugPrintedIs(sI, "Set([11, 22])", expected2: "Set([22, 11])") - - let sS = Set(["Hello", "world"]) - printedIs(sS, "[\"Hello\", \"world\"]", expected2: "[\"world\", \"Hello\"]") - debugPrintedIs(sS, "Set([\"Hello\", \"world\"])", expected2: "Set([\"world\", \"Hello\"])") - - print("test_SetPrinting done") -} -test_SetPrinting() -// CHECK: test_SetPrinting done - -func test_TuplePrinting() { - let tuple1 = (42, ()) - printedIs(tuple1, "(42, ())") - - let tuple2 = ((), 42) - printedIs(tuple2, "((), 42)") - - let tuple3 = (42, StructPrintable(3)) - printedIs(tuple3, "(42, ►3◀︎)") - - let tuple4 = (42, LargeStructPrintable(10, 20, 30, 40)) - printedIs(tuple4, "(42, <10 20 30 40>)") - - let tuple5 = (42, ClassPrintable(3)) - printedIs(tuple5, "(42, ►3◀︎)") - - let tuple6 = ([123: 123], (1, 2, "3")) - printedIs(tuple6, "([123: 123], (1, 2, \"3\"))") - - let arrayOfTuples1 = - [ (1, "two", StructPrintable(3), StructDebugPrintable(4), - WithoutDescription(5)) ] - printedIs(arrayOfTuples1, "[(1, \"two\", ►3◀︎, ►4◀︎, a.WithoutDescription(x: 5))]") - - let arrayOfTuples2 = - [ (1, "two", WithoutDescription(3)), - (11, "twenty-two", WithoutDescription(33)), - (111, "two hundred twenty-two", WithoutDescription(333)) ] - printedIs(arrayOfTuples2, "[(1, \"two\", a.WithoutDescription(x: 3)), (11, \"twenty-two\", a.WithoutDescription(x: 33)), (111, \"two hundred twenty-two\", a.WithoutDescription(x: 333))]") - - print("test_TuplePrinting done") -} -test_TuplePrinting() -// CHECK: test_TuplePrinting done - -func test_ArbitraryStructPrinting() { - let arrayOfArbitraryStructs = - [ WithoutDescription(1), WithoutDescription(2), WithoutDescription(3) ] - printedIs( - arrayOfArbitraryStructs, - "[a.WithoutDescription(x: 1), a.WithoutDescription(x: 2), a.WithoutDescription(x: 3)]") - debugPrintedIs( - arrayOfArbitraryStructs, - "[a.WithoutDescription(x: 1), a.WithoutDescription(x: 2), a.WithoutDescription(x: 3)]") - - printedIs( - EmptyStructWithoutDescription(), - "EmptyStructWithoutDescription()") - debugPrintedIs( - EmptyStructWithoutDescription(), - "a.EmptyStructWithoutDescription()") - - printedIs( - ValuesWithoutDescription(1.25, "abc", [ 1, 2, 3 ]), - "ValuesWithoutDescription>(t: 1.25, u: \"abc\", v: [1, 2, 3])") - debugPrintedIs( - ValuesWithoutDescription(1.25, "abc", [ 1, 2, 3 ]), - "a.ValuesWithoutDescription>(t: 1.25, u: \"abc\", v: [1, 2, 3])") - - print("test_ArbitraryStructPrinting done") -} -test_ArbitraryStructPrinting() -// CHECK: test_ArbitraryStructPrinting done - -func test_MetatypePrinting() { - printedIs(Int.self, "Int") - debugPrintedIs(Int.self, "Swift.Int") - - print("test_MetatypePrinting done") -} -test_MetatypePrinting() -// CHECK: test_MetatypePrinting done - -func test_StringInterpolation() { - assertEquals("1", "\(1)") - assertEquals("2", "\(1 + 1)") - assertEquals("aaa1bbb2ccc", "aaa\(1)bbb\(2)ccc") - - assertEquals("1.0", "\(1.0)") - assertEquals("1.5", "\(1.5)") - assertEquals("1e-12", "\(1.0 / (1000000000000))") - - assertEquals("inf", "\(1 / 0.0)") - assertEquals("-inf", "\(-1 / 0.0)") - assertEquals("nan", "\(0 / 0.0)") - - assertEquals("<[►1◀︎, ►2◀︎, ►3◀︎]>", "<\([ StructPrintable(1), StructPrintable(2), StructPrintable(3) ])>") - assertEquals("WithoutDescription(x: 1)", "\(WithoutDescription(1))") - - print("test_StringInterpolation done") -} -test_StringInterpolation() -// CHECK: test_StringInterpolation done - -struct MyString : StringLiteralConvertible, StringInterpolationConvertible { - init(str: String) { - value = str - } - - var value: String - - init(unicodeScalarLiteral value: String) { - self.init(str: value) - } - - init(extendedGraphemeClusterLiteral value: String) { - self.init(str: value) - } - - init(stringLiteral value: String) { - self.init(str: value) - } - - init(stringInterpolation strings: MyString...) { - var result = "" - for s in strings { - result += s.value - } - self.init(str: result) - } - - init(stringInterpolationSegment expr: T) { - self.init(str: "") - } -} - -func test_CustomStringInterpolation() { - assertEquals("", - ("aaa\(1)bbb" as MyString).value) - - print("test_CustomStringInterpolation done") -} -test_CustomStringInterpolation() -// CHECK: test_CustomStringInterpolation done - -func test_StdoutUTF8Printing() { - print("\u{00B5}") -// CHECK: {{^}}µ{{$}} - - print("test_StdoutUTF8Printing done") +PrintTests.test("StringInterpolation") { + expectEqual("1", "\(1)") + expectEqual("2", "\(1 + 1)") + expectEqual("aaa1bbb2ccc", "aaa\(1)bbb\(2)ccc") + + expectEqual("1.0", "\(1.0)") + expectEqual("1.5", "\(1.5)") + expectEqual("1e-12", "\(1.0 / (1000000000000))") + + expectEqual("inf", "\(1 / 0.0)") + expectEqual("-inf", "\(-1 / 0.0)") + expectEqual("nan", "\(0 / 0.0)") + + expectEqual("<[►1◀︎, ►2◀︎, ►3◀︎]>", "<\([ StructPrintable(1), StructPrintable(2), StructPrintable(3) ])>") + expectEqual("WithoutDescription(x: 1)", "\(WithoutDescription(1))") } -test_StdoutUTF8Printing() -// CHECK: test_StdoutUTF8Printing done - -func test_varargs() { - print("", 1, 2, 3, 4, "", separator: "|") // CHECK: |1|2|3|4| - print(1, 2, 3, separator: "\n", terminator: "===") - print(4, 5, 6, separator: "\n") - // CHECK-NEXT: 1 - // CHECK-NEXT: 2 - // CHECK-NEXT: 3===4 - // CHECK-NEXT: 5 - // CHECK-NEXT: 6 - debugPrint("", 1, 2, 3, 4, "", separator: "|") - // CHECK-NEXT: ""|1|2|3|4|"" - debugPrint(1, 2, 3, separator: "\n", terminator: "===") - debugPrint(4, 5, 6, separator: "\n") - // CHECK-NEXT: 1 - // CHECK-NEXT: 2 - // CHECK-NEXT: 3===4 - // CHECK-NEXT: 5 - // CHECK-NEXT: 6 - - var output = "" - print( - "", 1, 2, 3, 4, "", separator: "|", toStream: &output) - print(output == "|1|2|3|4|\n") // CHECK-NEXT: true - output = "" - debugPrint( - "", 1, 2, 3, 4, "", separator: "|", terminator: "", toStream: &output) - print(output == "\"\"|1|2|3|4|\"\"") // CHECK-NEXT: true - print("test_varargs done") +PrintTests.test("StdoutUTF8") { + expectPrinted("µ", "\u{00B5}") } -test_varargs() -// CHECK: test_varargs done -func test_playgroundPrintHook() { - - var printed: String? = nil - _playgroundPrintHook = { printed = $0 } +PrintTests.test("Varargs") { + var s0 = "" + print("", 1, 2, 3, 4, "", separator: "|", toStream: &s0) + expectEqual("|1|2|3|4|\n", s0) - print("", 1, 2, 3, 4, "", separator: "|") // CHECK: |1|2|3|4| - print("%\(printed!)%") // CHECK-NEXT: %|1|2|3|4| - // CHECK-NEXT: % + var s1 = "" + print(1, 2, 3, separator: "\n", terminator: "===", toStream: &s1) + expectEqual("1\n2\n3===", s1) - printed = nil - debugPrint("", 1, 2, 3, 4, "", separator: "|") - // CHECK-NEXT: ""|1|2|3|4|"" - print("%\(printed!)%") // CHECK-NEXT: %""|1|2|3|4|"" - // CHECK-NEXT: % + var s2 = "" + print(4, 5, 6, separator: "\n", toStream: &s2) + expectEqual("4\n5\n6\n", s2) - var explicitStream = "" - printed = nil - print("", 1, 2, 3, 4, "", separator: "!", toStream: &explicitStream) - print(printed) // CHECK-NEXT: nil - print("%\(explicitStream)%") // CHECK-NEXT: %!1!2!3!4! - // CHECK-NEXT: % - - explicitStream = "" - printed = nil - debugPrint( - "", 1, 2, 3, 4, "", separator: "!", toStream: &explicitStream) - print(printed) // CHECK-NEXT: nil - print("%\(explicitStream)%") // CHECK-NEXT: %""!1!2!3!4!"" - // CHECK-NEXT: % - - _playgroundPrintHook = nil - print("test_playgroundPrintHook done") - // CHECK-NEXT: test_playgroundPrintHook done + var s3 = "" + print("", 1, 2, 3, 4, "", separator: "|", toStream: &s3) + expectEqual("|1|2|3|4|\n", s3) } -test_playgroundPrintHook() -if !failed { - print("OK") +PrintTests.test("PlaygroundPrintHook") { + var printed = "" + _playgroundPrintHook = { printed = $0 } + + var s0 = "" + print("", 1, 2, 3, 4, "", separator: "|", toStream: &s0) + expectEqual("|1|2|3|4|\n", s0) + print("%\(s0)%") + expectEqual("%|1|2|3|4|\n%\n", printed) + + printed = "" + var s1 = "" + print("", 1, 2, 3, 4, "", separator: "!", toStream: &s1) + expectEqual("", printed) + print("%\(s1)%") + expectEqual("%!1!2!3!4!\n%\n", printed) } -// CHECK: OK +runAllTests() diff --git a/test/1_stdlib/PrintArray.swift b/test/1_stdlib/PrintArray.swift new file mode 100644 index 0000000000000..0bc2a3daddd08 --- /dev/null +++ b/test/1_stdlib/PrintArray.swift @@ -0,0 +1,36 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: %target-build-swift -c -force-single-frontend-invocation -parse-as-library -emit-module -emit-module-path %t/PrintTestTypes.swiftmodule -o %t/PrintTestTypes.o %S/Inputs/PrintTestTypes.swift +// RUN: %target-build-swift %s -Xlinker %t/PrintTestTypes.o -I %t -L %t -o %t/main +// RUN: %target-run %t/main +// REQUIRES: executable_test + +import StdlibUnittest +import PrintTestTypes + +let PrintTests = TestSuite("PrintArray") + +PrintTests.test("Printable") { + expectPrinted("[]", [Int]()) + expectPrinted("[1]", [ 1 ]) + expectPrinted("[1, 2]", [ 1, 2 ]) + expectPrinted("[1, 2, 3]", [ 1, 2, 3 ]) + + expectPrinted("[\"foo\", \"bar\", \"bas\"]", [ "foo", "bar", "bas" ]) + expectDebugPrinted("[\"foo\", \"bar\", \"bas\"]", [ "foo", "bar", "bas" ]) + + expectPrinted("[►1◀︎, ►2◀︎, ►3◀︎]", [ StructPrintable(1), + StructPrintable(2), StructPrintable(3) ]) + + expectPrinted("[<10 20 30 40>, <50 60 70 80>]", + [ LargeStructPrintable(10, 20, 30, 40), LargeStructPrintable(50, 60, 70, 80) ]) + + expectPrinted("[►1◀︎]", [ StructDebugPrintable(1) ]) + + expectPrinted("[►1◀︎, ►2◀︎, ►3◀︎]", [ ClassPrintable(1), + ClassPrintable(2), ClassPrintable(3) ]) + + expectPrinted("[►1◀︎, ►2◀︎, ►3◀︎]", [ ClassPrintable(1), + ClassPrintable(2), ClassPrintable(3) ] as Array) +} + +runAllTests() diff --git a/test/1_stdlib/PrintBoolean.swift b/test/1_stdlib/PrintBoolean.swift new file mode 100644 index 0000000000000..eaae61ab991c7 --- /dev/null +++ b/test/1_stdlib/PrintBoolean.swift @@ -0,0 +1,28 @@ +// RUN: %target-run-simple-swift +// REQUIRES: executable_test + +import StdlibUnittest + +let PrintTests = TestSuite("PrintBoolean") + +PrintTests.test("CustomStringConvertible") { + func hasDescription(any: Any) { + expectTrue(any is CustomStringConvertible) + } + + hasDescription(Bool(true)) + hasDescription(CBool(true)) +} + +PrintTests.test("Printable") { + expectPrinted("true", CBool(true)) + expectPrinted("false", CBool(false)) + + expectPrinted("true", Bool(true)) + expectPrinted("false", Bool(false)) + + expectPrinted("true", true) + expectPrinted("false", false) +} + +runAllTests() diff --git a/test/1_stdlib/PrintClass.swift b/test/1_stdlib/PrintClass.swift new file mode 100644 index 0000000000000..489f68ef859f1 --- /dev/null +++ b/test/1_stdlib/PrintClass.swift @@ -0,0 +1,44 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: %target-build-swift -c -force-single-frontend-invocation -parse-as-library -emit-module -emit-module-path %t/PrintTestTypes.swiftmodule -o %t/PrintTestTypes.o %S/Inputs/PrintTestTypes.swift +// RUN: %target-build-swift %s -Xlinker %t/PrintTestTypes.o -I %t -L %t -o %t/main +// RUN: %target-run %t/main +// REQUIRES: executable_test + +import StdlibUnittest +import PrintTestTypes + +let PrintTests = TestSuite("PrintClass") + +PrintTests.test("ClassPrintable") { + let c0 = ClassPrintable(1) + let c1: ProtocolUnrelatedToPrinting = ClassPrintable(1) + let c2: CustomStringConvertible = ClassPrintable(1) + let c3: Any = ClassPrintable(1) + + expectPrinted("►1◀︎", c0) + expectPrinted("►1◀︎", c1) + expectPrinted("►1◀︎", c2) + expectPrinted("►1◀︎", c3) + + let classMetatype = ClassPrintable.self + expectPrinted("ClassPrintable", classMetatype) + expectDebugPrinted("PrintTestTypes.ClassPrintable", classMetatype) + expectPrinted("[PrintTestTypes.ClassPrintable]", [ classMetatype ]) + expectDebugPrinted("[PrintTestTypes.ClassPrintable]", [ classMetatype ]) +} + +PrintTests.test("ClassVeryPrintable") { + let c0 = ClassVeryPrintable(1) + let c1: ProtocolUnrelatedToPrinting = ClassVeryPrintable(1) + let c2: CustomStringConvertible = ClassVeryPrintable(1) + let c3: CustomDebugStringConvertible = ClassVeryPrintable(1) + let c4: Any = ClassVeryPrintable(1) + + expectPrinted("", c0) + expectPrinted("", c1) + expectPrinted("", c2) + expectPrinted("", c3) + expectPrinted("", c4) +} + +runAllTests() diff --git a/test/1_stdlib/PrintDictionary.swift b/test/1_stdlib/PrintDictionary.swift new file mode 100644 index 0000000000000..74f328f6a6a00 --- /dev/null +++ b/test/1_stdlib/PrintDictionary.swift @@ -0,0 +1,26 @@ +// RUN: %target-run-simple-swift +// REQUIRES: executable_test + +import StdlibUnittest + +let PrintTests = TestSuite("PrintDictionary") + +PrintTests.test("Printable") { + expectPrinted("[:]", [String: Int]()) + expectDebugPrinted("[:]", [String: Int]()) + + expectPrinted("[\"aaa\": 1]", [ "aaa": 1 ]) + expectDebugPrinted("[\"aaa\": 1]", [ "aaa": 1 ]) + + let d0 = [ "aaa": 1, "bbb": 2 ] + expectPrinted(expectedOneOf: [ "[\"aaa\": 1, \"bbb\": 2]", + "[\"bbb\": 2, \"aaa\": 1]" ], d0) + expectDebugPrinted(expectedOneOf: [ "[\"aaa\": 1, \"bbb\": 2]", + "[\"bbb\": 2, \"aaa\": 1]" ], d0) + + let d1 = [ "aaa": "bbb" ] + expectPrinted("[\"aaa\": \"bbb\"]", d1) + expectDebugPrinted("[\"aaa\": \"bbb\"]", d1) +} + +runAllTests() diff --git a/test/1_stdlib/PrintFloat.swift b/test/1_stdlib/PrintFloat.swift new file mode 100644 index 0000000000000..52b229ddfc5fe --- /dev/null +++ b/test/1_stdlib/PrintFloat.swift @@ -0,0 +1,202 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: %target-build-swift -c -force-single-frontend-invocation -parse-as-library -emit-module -emit-module-path %t/PrintTestTypes.swiftmodule -o %t/PrintTestTypes.o %S/Inputs/PrintTestTypes.swift +// RUN: %target-build-swift %s -Xlinker %t/PrintTestTypes.o -I %t -L %t -o %t/main.out +// RUN: %target-run %t/main.out +// RUN: %target-run %t/main.out --locale ru_RU.UTF-8 +// REQUIRES: executable_test +// XFAIL: linux + +import StdlibUnittest +import Darwin +import PrintTestTypes + +let PrintTests = TestSuite("PrintFloat") + +PrintTests.setUp { + if let localeArgIndex = Process.arguments.indexOf("--locale") { + let locale = Process.arguments[localeArgIndex + 1] + expectEqual("ru_RU.UTF-8", locale) + setlocale(LC_ALL, locale) + } else { + setlocale(LC_ALL, "") + } +} + +PrintTests.test("CustomStringConvertible") { + func hasDescription(any: Any) { + expectTrue(any is CustomStringConvertible) + } + + hasDescription(CFloat(1.0)) + hasDescription(CDouble(1.0)) +} + +PrintTests.test("Printable") { + func asFloat32(f: Float32) -> Float32 { return f } + func asFloat64(f: Float64) -> Float64 { return f } +#if arch(i386) || arch(x86_64) + func asFloat80(f: Swift.Float80) -> Swift.Float80 { return f } +#endif + + expectPrinted("1.0", Float(1.0)) + expectPrinted("-1.0", Float(-1.0)) + expectPrinted("1.0", Double(1.0)) + expectPrinted("-1.0", Double(-1.0)) + + expectPrinted("1.0", CFloat(1.0)) + expectPrinted("-1.0", CFloat(-1.0)) + expectPrinted("1.0", CDouble(1.0)) + expectPrinted("-1.0", CDouble(-1.0)) + + expectPrinted("inf", Float.infinity) + expectPrinted("-inf", -Float.infinity) + expectPrinted("nan", Float.NaN) + expectPrinted("0.0", asFloat32(0.0)) + expectPrinted("1.0", asFloat32(1.0)) + expectPrinted("-1.0", asFloat32(-1.0)) + expectPrinted("100.125", asFloat32(100.125)) + expectPrinted("-100.125", asFloat32(-100.125)) + + expectPrinted("inf", Double.infinity) + expectPrinted("-inf", -Double.infinity) + expectPrinted("nan", Double.NaN) + expectPrinted("0.0", asFloat64(0.0)) + expectPrinted("1.0", asFloat64(1.0)) + expectPrinted("-1.0", asFloat64(-1.0)) + expectPrinted("100.125", asFloat64(100.125)) + expectPrinted("-100.125", asFloat64(-100.125)) + + expectPrinted("1.00001", asFloat32(1.00001)) + expectPrinted("1.25e+17", asFloat32(125000000000000000.0)) + expectPrinted("1.25e+16", asFloat32(12500000000000000.0)) + expectPrinted("1.25e+15", asFloat32(1250000000000000.0)) + expectPrinted("1.25e+14", asFloat32(125000000000000.0)) + expectPrinted("1.25e+13", asFloat32(12500000000000.0)) + expectPrinted("1.25e+12", asFloat32(1250000000000.0)) + expectPrinted("1.25e+11", asFloat32(125000000000.0)) + expectPrinted("1.25e+10", asFloat32(12500000000.0)) + expectPrinted("1.25e+09", asFloat32(1250000000.0)) + expectPrinted("1.25e+08", asFloat32(125000000.0)) + expectPrinted("1.25e+07", asFloat32(12500000.0)) + expectPrinted("1.25e+06", asFloat32(1250000.0)) + expectPrinted("125000.0", asFloat32(125000.0)) + expectPrinted("12500.0", asFloat32(12500.0)) + expectPrinted("1250.0", asFloat32(1250.0)) + expectPrinted("125.0", asFloat32(125.0)) + expectPrinted("12.5", asFloat32(12.5)) + expectPrinted("1.25", asFloat32(1.25)) + expectPrinted("0.125", asFloat32(0.125)) + expectPrinted("0.0125", asFloat32(0.0125)) + expectPrinted("0.00125", asFloat32(0.00125)) + expectPrinted("0.000125", asFloat32(0.000125)) + expectPrinted("1.25e-05", asFloat32(0.0000125)) + expectPrinted("1.25e-06", asFloat32(0.00000125)) + expectPrinted("1.25e-07", asFloat32(0.000000125)) + expectPrinted("1.25e-08", asFloat32(0.0000000125)) + expectPrinted("1.25e-09", asFloat32(0.00000000125)) + expectPrinted("1.25e-10", asFloat32(0.000000000125)) + expectPrinted("1.25e-11", asFloat32(0.0000000000125)) + expectPrinted("1.25e-12", asFloat32(0.00000000000125)) + expectPrinted("1.25e-13", asFloat32(0.000000000000125)) + expectPrinted("1.25e-14", asFloat32(0.0000000000000125)) + expectPrinted("1.25e-15", asFloat32(0.00000000000000125)) + expectPrinted("1.25e-16", asFloat32(0.000000000000000125)) + expectPrinted("1.25e-17", asFloat32(0.0000000000000000125)) + + expectPrinted("1.00000000000001", asFloat64(1.00000000000001)) + expectPrinted("1.25e+17", asFloat64(125000000000000000.0)) + expectPrinted("1.25e+16", asFloat64(12500000000000000.0)) + expectPrinted("1.25e+15", asFloat64(1250000000000000.0)) + expectPrinted("125000000000000.0", asFloat64(125000000000000.0)) + expectPrinted("12500000000000.0", asFloat64(12500000000000.0)) + expectPrinted("1250000000000.0", asFloat64(1250000000000.0)) + expectPrinted("125000000000.0", asFloat64(125000000000.0)) + expectPrinted("12500000000.0", asFloat64(12500000000.0)) + expectPrinted("1250000000.0", asFloat64(1250000000.0)) + expectPrinted("125000000.0", asFloat64(125000000.0)) + expectPrinted("12500000.0", asFloat64(12500000.0)) + expectPrinted("1250000.0", asFloat64(1250000.0)) + expectPrinted("125000.0", asFloat64(125000.0)) + expectPrinted("12500.0", asFloat64(12500.0)) + expectPrinted("1250.0", asFloat64(1250.0)) + expectPrinted("125.0", asFloat64(125.0)) + expectPrinted("12.5", asFloat64(12.5)) + expectPrinted("1.25", asFloat64(1.25)) + expectPrinted("0.125", asFloat64(0.125)) + expectPrinted("0.0125", asFloat64(0.0125)) + expectPrinted("0.00125", asFloat64(0.00125)) + expectPrinted("0.000125", asFloat64(0.000125)) + expectPrinted("1.25e-05", asFloat64(0.0000125)) + expectPrinted("1.25e-06", asFloat64(0.00000125)) + expectPrinted("1.25e-07", asFloat64(0.000000125)) + expectPrinted("1.25e-08", asFloat64(0.0000000125)) + expectPrinted("1.25e-09", asFloat64(0.00000000125)) + expectPrinted("1.25e-10", asFloat64(0.000000000125)) + expectPrinted("1.25e-11", asFloat64(0.0000000000125)) + expectPrinted("1.25e-12", asFloat64(0.00000000000125)) + expectPrinted("1.25e-13", asFloat64(0.000000000000125)) + expectPrinted("1.25e-14", asFloat64(0.0000000000000125)) + expectPrinted("1.25e-15", asFloat64(0.00000000000000125)) + expectPrinted("1.25e-16", asFloat64(0.000000000000000125)) + expectPrinted("1.25e-17", asFloat64(0.0000000000000000125)) + +#if arch(i386) || arch(x86_64) + expectPrinted("1.00000000000000001", asFloat80(1.00000000000000001)) + expectPrinted("1.25e+19", asFloat80(12500000000000000000.0)) + expectPrinted("1.25e+18", asFloat80(1250000000000000000.0)) + expectPrinted("125000000000000000.0", asFloat80(125000000000000000.0)) + expectPrinted("12500000000000000.0", asFloat80(12500000000000000.0)) + expectPrinted("1250000000000000.0", asFloat80(1250000000000000.0)) + expectPrinted("125000000000000.0", asFloat80(125000000000000.0)) + expectPrinted("12500000000000.0", asFloat80(12500000000000.0)) + expectPrinted("1250000000000.0", asFloat80(1250000000000.0)) + expectPrinted("125000000000.0", asFloat80(125000000000.0)) + expectPrinted("12500000000.0", asFloat80(12500000000.0)) + expectPrinted("1250000000.0", asFloat80(1250000000.0)) + expectPrinted("125000000.0", asFloat80(125000000.0)) + expectPrinted("12500000.0", asFloat80(12500000.0)) + expectPrinted("1250000.0", asFloat80(1250000.0)) + expectPrinted("125000.0", asFloat80(125000.0)) + expectPrinted("12500.0", asFloat80(12500.0)) + expectPrinted("1250.0", asFloat80(1250.0)) + expectPrinted("125.0", asFloat80(125.0)) + expectPrinted("12.5", asFloat80(12.5)) + expectPrinted("1.25", asFloat80(1.25)) + expectPrinted("0.125", asFloat80(0.125)) + expectPrinted("0.0125", asFloat80(0.0125)) + expectPrinted("0.00125", asFloat80(0.00125)) + expectPrinted("0.000125", asFloat80(0.000125)) + expectPrinted("1.25e-05", asFloat80(0.0000125)) + expectPrinted("1.25e-06", asFloat80(0.00000125)) + expectPrinted("1.25e-07", asFloat80(0.000000125)) + expectPrinted("1.25e-08", asFloat80(0.0000000125)) + expectPrinted("1.25e-09", asFloat80(0.00000000125)) + expectPrinted("1.25e-10", asFloat80(0.000000000125)) + expectPrinted("1.25e-11", asFloat80(0.0000000000125)) + expectPrinted("1.25e-12", asFloat80(0.00000000000125)) + expectPrinted("1.25e-13", asFloat80(0.000000000000125)) + expectPrinted("1.25e-14", asFloat80(0.0000000000000125)) + expectPrinted("1.25e-15", asFloat80(0.00000000000000125)) + expectPrinted("1.25e-16", asFloat80(0.000000000000000125)) + expectPrinted("1.25e-17", asFloat80(0.0000000000000000125)) +#endif + + expectDebugPrinted("1.10000002", asFloat32(1.1)) + expectDebugPrinted("1.24999998e+17", asFloat32(125000000000000000.0)) + expectDebugPrinted("1.25", asFloat32(1.25)) + expectDebugPrinted("1.24999997e-05", asFloat32(0.0000125)) + + expectDebugPrinted("1.1000000000000001", asFloat64(1.1)) + expectDebugPrinted("1.25e+17", asFloat64(125000000000000000.0)) + expectDebugPrinted("1.25", asFloat64(1.25)) + expectDebugPrinted("1.2500000000000001e-05", asFloat64(0.0000125)) + +#if arch(i386) || arch(x86_64) + expectDebugPrinted("1.10000000000000000002", asFloat80(1.1)) + expectDebugPrinted("125000000000000000.0", asFloat80(125000000000000000.0)) + expectDebugPrinted("1.25", asFloat80(1.25)) + expectDebugPrinted("1.25000000000000000001e-05", asFloat80(0.0000125)) +#endif +} + +runAllTests() diff --git a/test/1_stdlib/PrintInteger.swift b/test/1_stdlib/PrintInteger.swift new file mode 100644 index 0000000000000..1bf6fa169f1c9 --- /dev/null +++ b/test/1_stdlib/PrintInteger.swift @@ -0,0 +1,148 @@ +// RUN: %target-run-simple-swift +// REQUIRES: executable_test + +import StdlibUnittest + +let PrintTests = TestSuite("PrintInteger") +PrintTests.test("CustomStringConvertible") { + func hasDescription(any: Any) { + expectTrue(any is CustomStringConvertible) + } + + hasDescription(Int(42)) + hasDescription(UInt(42)) + + hasDescription(Int8(-42)) + hasDescription(Int16(-42)) + hasDescription(Int32(-42)) + hasDescription(Int64(-42)) + hasDescription(UInt8(42)) + hasDescription(UInt16(42)) + hasDescription(UInt32(42)) + hasDescription(UInt64(42)) + + hasDescription(CChar(42)) + hasDescription(CUnsignedChar(42)) + hasDescription(CUnsignedShort(42)) + hasDescription(CUnsignedInt(42)) + hasDescription(CUnsignedLong(42)) + hasDescription(CUnsignedLongLong(42)) + hasDescription(CSignedChar(42)) + hasDescription(CShort(42)) + hasDescription(CInt(42)) + hasDescription(CLong(42)) + hasDescription(CLongLong(42)) + hasDescription(CWideChar(42)) + hasDescription(CChar16(42)) + hasDescription(CChar32(42)) +} + +PrintTests.test("Printable") { + expectPrinted("42", CChar(42)) + expectPrinted("42", CUnsignedChar(42)) + expectPrinted("42", CUnsignedShort(42)) + expectPrinted("42", CUnsignedInt(42)) + expectPrinted("42", CUnsignedLong(42)) + expectPrinted("42", CUnsignedLongLong(42)) + expectPrinted("42", CSignedChar(42)) + expectPrinted("42", CShort(42)) + expectPrinted("42", CInt(42)) + expectPrinted("42", CLong(42)) + expectPrinted("42", CLongLong(42)) + expectPrinted("*", CWideChar(42)) + expectPrinted("42", CChar16(42)) + expectPrinted("*", CChar32(42)) + + if (UInt64(Int.max) > 0x1_0000_0000 as UInt64) { + expectPrinted("-9223372036854775808", Int.min) + expectPrinted("9223372036854775807", Int.max) + } else { + expectPrinted("-2147483648", Int.min) + expectPrinted("2147483647", Int.max) + } + + expectPrinted("0", Int(0)) + expectPrinted("42", Int(42)) + expectPrinted("-42", Int(-42)) + + if (UInt64(UInt.max) > 0x1_0000_0000 as UInt64) { + expectPrinted("18446744073709551615", UInt.max) + } else { + expectPrinted("4294967295", UInt.max) + } + + expectPrinted("0", UInt.min) + expectPrinted("0", UInt(0)) + expectPrinted("42", UInt(42)) + + expectPrinted("-128", Int8.min) + expectPrinted("127", Int8.max) + expectPrinted("0", Int8(0)) + expectPrinted("42", Int8(42)) + expectPrinted("-42", Int8(-42)) + + expectPrinted("0", UInt8.min) + expectPrinted("255", UInt8.max) + expectPrinted("0", UInt8(0)) + expectPrinted("42", UInt8(42)) + + expectPrinted("-32768", Int16.min) + expectPrinted("32767", Int16.max) + expectPrinted("0", Int16(0)) + expectPrinted("42", Int16(42)) + expectPrinted("-42", Int16(-42)) + + expectPrinted("0", UInt16.min) + expectPrinted("65535", UInt16.max) + expectPrinted("0", UInt16(0)) + expectPrinted("42", UInt16(42)) + + expectPrinted("-2147483648", Int32.min) + expectPrinted("2147483647", Int32.max) + expectPrinted("0", Int32(0)) + expectPrinted("42", Int32(42)) + expectPrinted("-42", Int32(-42)) + + expectPrinted("0", UInt32.min) + expectPrinted("4294967295", UInt32.max) + expectPrinted("0", UInt32(0)) + expectPrinted("42", UInt32(42)) + + expectPrinted("-9223372036854775808", Int64.min) + expectPrinted("9223372036854775807", Int64.max) + expectPrinted("0", Int64(0)) + expectPrinted("42", Int64(42)) + expectPrinted("-42", Int64(-42)) + + expectPrinted("0", UInt64.min) + expectPrinted("18446744073709551615", UInt64.max) + expectPrinted("0", UInt64(0)) + expectPrinted("42", UInt64(42)) + + expectPrinted("-42", Int8(-42)) + expectPrinted("-42", Int16(-42)) + expectPrinted("-42", Int32(-42)) + expectPrinted("-42", Int64(-42)) + expectPrinted("42", UInt8(42)) + expectPrinted("42", UInt16(42)) + expectPrinted("42", UInt32(42)) + expectPrinted("42", UInt64(42)) + + expectPrinted("42", CChar(42)) + expectPrinted("42", CUnsignedChar(42)) + expectPrinted("42", CUnsignedShort(42)) + expectPrinted("42", CUnsignedInt(42)) + expectPrinted("42", CUnsignedLong(42)) + expectPrinted("42", CUnsignedLongLong(42)) + expectPrinted("42", CSignedChar(42)) + expectPrinted("42", CShort(42)) + expectPrinted("42", CInt(42)) + expectPrinted("42", CLong(42)) + expectPrinted("42", CLongLong(42)) + + expectPrinted("*", CWideChar(42)) + expectPrinted("42", CChar16(42)) + expectPrinted("*", CChar32(42)) +} + +runAllTests() diff --git a/test/1_stdlib/PrintPointer.swift b/test/1_stdlib/PrintPointer.swift new file mode 100644 index 0000000000000..56828347d0c02 --- /dev/null +++ b/test/1_stdlib/PrintPointer.swift @@ -0,0 +1,39 @@ +// RUN: %target-run-simple-swift +// REQUIRES: executable_test + +import StdlibUnittest + +let PrintTests = TestSuite("PrintPointer") +PrintTests.test("Printable") { + let nullUP = UnsafeMutablePointer() + let fourByteUP = UnsafeMutablePointer(bitPattern: 0xabcd1234 as UInt) + +#if !(arch(i386) || arch(arm)) + let eightByteAddr: UInt = 0xabcddcba12344321 + let eightByteUP = UnsafeMutablePointer(bitPattern: eightByteAddr) +#endif + +#if arch(i386) || arch(arm) + let expectedNull = "0x00000000" + expectPrinted("0xabcd1234", fourByteUP) +#else + let expectedNull = "0x0000000000000000" + expectPrinted("0x00000000abcd1234", fourByteUP) + expectPrinted("0xabcddcba12344321", eightByteUP) +#endif + + expectPrinted(expectedNull, nullUP) + + expectPrinted("UnsafeBufferPointer(start: \(expectedNull), length: 0)", + UnsafeBufferPointer(start: nullUP, count: 0)) + expectPrinted("UnsafeMutableBufferPointer(start: \(expectedNull), length: 0)", + UnsafeMutableBufferPointer(start: nullUP, count: 0)) + + expectPrinted(expectedNull, COpaquePointer()) + expectPrinted(expectedNull, CVaListPointer(_fromUnsafeMutablePointer: nullUP)) +#if _runtime(_ObjC) + expectPrinted(expectedNull, AutoreleasingUnsafeMutablePointer()) +#endif +} + +runAllTests() diff --git a/test/1_stdlib/PrintSet.swift b/test/1_stdlib/PrintSet.swift new file mode 100644 index 0000000000000..60bf004462f7c --- /dev/null +++ b/test/1_stdlib/PrintSet.swift @@ -0,0 +1,23 @@ +// RUN: %target-run-simple-swift +// REQUIRES: executable_test + +import StdlibUnittest + +let PrintTests = TestSuite("PrintSet") +PrintTests.test("Printable") { + expectPrinted("[]", Set()) + expectDebugPrinted("Set([])", Set()) + + let s0 = Set([11, 22]) + expectPrinted(expectedOneOf: [ "[11, 22]", "[22, 11]" ], s0) + expectDebugPrinted(expectedOneOf: [ "Set([11, 22])", + "Set([22, 11])" ], s0) + + let s1 = Set(["Hello", "world"]) + expectPrinted(expectedOneOf: [ "[\"Hello\", \"world\"]", + "[\"world\", \"Hello\"]" ], s1) + expectDebugPrinted(expectedOneOf: [ "Set([\"Hello\", \"world\"])", + "Set([\"world\", \"Hello\"])" ], s1) +} + +runAllTests() diff --git a/test/1_stdlib/PrintString.swift b/test/1_stdlib/PrintString.swift new file mode 100644 index 0000000000000..5fc6405c583df --- /dev/null +++ b/test/1_stdlib/PrintString.swift @@ -0,0 +1,50 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: %target-build-swift -c -force-single-frontend-invocation -parse-as-library -emit-module -emit-module-path %t/PrintTestTypes.swiftmodule -o %t/PrintTestTypes.o %S/Inputs/PrintTestTypes.swift +// RUN: %target-build-swift %s -Xlinker %t/PrintTestTypes.o -I %t -L %t -o %t/main +// RUN: %target-run %t/main +// REQUIRES: executable_test + +import StdlibUnittest +import PrintTestTypes + +let PrintTests = TestSuite("PrintString") +PrintTests.test("Printable") { + let s0: String = "abc" + expectPrinted("abc", s0) + expectDebugPrinted("\"abc\"", s0) + + let s1: String = "\\ \' \" \0 \n \r \t \u{05}" + expectDebugPrinted("\"\\\\ \\\' \\\" \\0 \\n \\r \\t \\u{05}\"", s1) + + let ch: Character = "a" + expectPrinted("a", ch) + expectDebugPrinted("\"a\"", ch) + + let us0: UnicodeScalar = "a" + expectPrinted("a", us0) + expectDebugPrinted("\"a\"", us0) + + let us1: UnicodeScalar = "\\" + expectPrinted("\\", us1) + expectEqual("\"\\\\\"", us1.description) + expectDebugPrinted("\"\\\\\"", us1) + + let us2: UnicodeScalar = "あ" + expectPrinted("あ", us2) + expectEqual("\"あ\"", us2.description) + expectDebugPrinted("\"\\u{3042}\"", us2) +} + +PrintTests.test("Printable") { + expectPrinted("nil", String!()) + expectPrinted("meow", String!("meow")) + expectPrinted("nil", String?()) + expectPrinted("Optional(\"meow\")", String?("meow")) +} + +PrintTests.test("CustomStringInterpolation") { + let s = ("aaa\(1)bbb" as MyString).value + expectEqual("", s) +} + +runAllTests() diff --git a/test/1_stdlib/PrintStruct.swift b/test/1_stdlib/PrintStruct.swift new file mode 100644 index 0000000000000..f60a02fbf4c29 --- /dev/null +++ b/test/1_stdlib/PrintStruct.swift @@ -0,0 +1,107 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: %target-build-swift -c -force-single-frontend-invocation -parse-as-library -emit-module -emit-module-path %t/PrintTestTypes.swiftmodule -o %t/PrintTestTypes.o %S/Inputs/PrintTestTypes.swift +// RUN: %target-build-swift %s -Xlinker %t/PrintTestTypes.o -I %t -L %t -o %t/main +// RUN: %target-run %t/main +// REQUIRES: executable_test + +import StdlibUnittest +import PrintTestTypes + +let PrintTests = TestSuite("PrintStruct") + +PrintTests.test("Printable") { + let s0 = [ WithoutDescription(1), WithoutDescription(2), WithoutDescription(3) ] + expectPrinted( + "[PrintTestTypes.WithoutDescription(x: 1), PrintTestTypes.WithoutDescription(x: 2), PrintTestTypes.WithoutDescription(x: 3)]", + s0) + expectDebugPrinted( + "[PrintTestTypes.WithoutDescription(x: 1), PrintTestTypes.WithoutDescription(x: 2), PrintTestTypes.WithoutDescription(x: 3)]", + s0) + + expectPrinted("EmptyStructWithoutDescription()", + EmptyStructWithoutDescription()) + expectDebugPrinted("PrintTestTypes.EmptyStructWithoutDescription()", + EmptyStructWithoutDescription()) + + expectPrinted( + "ValuesWithoutDescription>(t: 1.25, u: \"abc\", v: [1, 2, 3])", + ValuesWithoutDescription(1.25, "abc", [ 1, 2, 3 ])) + expectDebugPrinted( + "PrintTestTypes.ValuesWithoutDescription>(t: 1.25, u: \"abc\", v: [1, 2, 3])", ValuesWithoutDescription(1.25, "abc", [ 1, 2, 3 ])) +} + +PrintTests.test("custom string convertible structs") { + struct Wrapper : CustomStringConvertible { + var x: CustomStringConvertible? = nil + + var description: String { + return "Wrapper(\(x.debugDescription))" + } + } + + expectPrinted("Wrapper(nil)", Wrapper()) + expectPrinted("Wrapper(Optional(Wrapper(nil)))", + Wrapper(x: Wrapper())) + expectPrinted("Wrapper(Optional(Wrapper(Optional(Wrapper(nil)))))", + Wrapper(x: Wrapper(x: Wrapper()))) +} + +func test_ThickMetatypePrintingImpl( + thickMetatype: T.Type, + _ expectedPrint: String, + _ expectedDebug: String + ) { + expectPrinted(expectedPrint, thickMetatype) + expectPrinted("[\(expectedDebug)]", [ thickMetatype ]) + expectDebugPrinted(expectedDebug, thickMetatype) + expectDebugPrinted("[\(expectedDebug)]", [ thickMetatype ]) +} + +PrintTests.test("StructPrintable") { + let s0 = StructPrintable(1) + let s1: ProtocolUnrelatedToPrinting = StructPrintable(1) + let s2: CustomStringConvertible = StructPrintable(1) + let s3: Any = StructPrintable(1) + + expectPrinted("►1◀︎", s0) + expectPrinted("►1◀︎", s1) + expectPrinted("►1◀︎", s2) + expectPrinted("►1◀︎", s3) + + let structMetatype = StructPrintable.self + expectPrinted("StructPrintable", structMetatype) + expectDebugPrinted("PrintTestTypes.StructPrintable", structMetatype) + expectPrinted("[PrintTestTypes.StructPrintable]", [ structMetatype ]) + expectDebugPrinted("[PrintTestTypes.StructPrintable]", [ structMetatype ]) + test_ThickMetatypePrintingImpl(structMetatype, "StructPrintable", + "PrintTestTypes.StructPrintable") +} + +PrintTests.test("LargeStructPrintable") { + let s0 = LargeStructPrintable(10, 20, 30, 40) + let s1: ProtocolUnrelatedToPrinting = LargeStructPrintable(10, 20, 30, 40) + let s2: CustomStringConvertible = LargeStructPrintable(10, 20, 30, 40) + let s3: Any = LargeStructPrintable(10, 20, 30, 40) + + expectPrinted("<10 20 30 40>", s0) + expectPrinted("<10 20 30 40>", s1) + expectPrinted("<10 20 30 40>", s2) + expectPrinted("<10 20 30 40>", s0) + expectPrinted("<10 20 30 40>", s3) +} + +PrintTests.test("StructVeryPrintable") { + let s0 = StructVeryPrintable(1) + let s1: ProtocolUnrelatedToPrinting = StructVeryPrintable(1) + let s2: CustomStringConvertible = StructVeryPrintable(1) + let s3: CustomDebugStringConvertible = StructVeryPrintable(1) + let s4: Any = StructVeryPrintable(1) + + expectPrinted("", s0) + expectPrinted("", s1) + expectPrinted("", s2) + expectPrinted("", s3) + expectPrinted("", s4) +} + +runAllTests() diff --git a/test/1_stdlib/PrintTuple.swift b/test/1_stdlib/PrintTuple.swift new file mode 100644 index 0000000000000..72c57e9d605cf --- /dev/null +++ b/test/1_stdlib/PrintTuple.swift @@ -0,0 +1,32 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: %target-build-swift -c -force-single-frontend-invocation -parse-as-library -emit-module -emit-module-path %t/PrintTestTypes.swiftmodule -o %t/PrintTestTypes.o %S/Inputs/PrintTestTypes.swift +// RUN: %target-build-swift %s -Xlinker %t/PrintTestTypes.o -I %t -L %t -o %t/main +// RUN: %target-run %t/main +// REQUIRES: executable_test + +import StdlibUnittest +import PrintTestTypes + +let PrintTests = TestSuite("PrintTuple") +PrintTests.test("Printable") { + expectPrinted("(42, ())", (42, ())) + expectPrinted("((), 42)", ((), 42)) + expectPrinted("(42, ►3◀︎)", (42, StructPrintable(3))) + expectPrinted("(42, <10 20 30 40>)", + (42, LargeStructPrintable(10, 20, 30, 40))) + expectPrinted("(42, ►3◀︎)", (42, ClassPrintable(3))) + expectPrinted("([123: 123], (1, 2, \"3\"))", + ([123: 123], (1, 2, "3"))) + + let t0 = [ (1, "two", StructPrintable(3), StructDebugPrintable(4), + WithoutDescription(5)) ] + expectPrinted("[(1, \"two\", ►3◀︎, ►4◀︎, PrintTestTypes.WithoutDescription(x: 5))]", + t0) + + let t1 = [ (1, "2", WithoutDescription(3)), + (4, "5", WithoutDescription(6)), + (7, "8", WithoutDescription(9)) ] + expectPrinted("[(1, \"2\", PrintTestTypes.WithoutDescription(x: 3)), (4, \"5\", PrintTestTypes.WithoutDescription(x: 6)), (7, \"8\", PrintTestTypes.WithoutDescription(x: 9))]", t1) +} + +runAllTests() diff --git a/test/1_stdlib/Range.swift b/test/1_stdlib/Range.swift index ab83d6a6a554b..eec2604c9363d 100644 --- a/test/1_stdlib/Range.swift +++ b/test/1_stdlib/Range.swift @@ -5,6 +5,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + // Check that the generic parameter is called 'Element'. protocol TestProtocol1 {} diff --git a/test/1_stdlib/RangeDiagnostics.swift b/test/1_stdlib/RangeDiagnostics.swift index 29cccb658ee30..05a7e6a24f575 100644 --- a/test/1_stdlib/RangeDiagnostics.swift +++ b/test/1_stdlib/RangeDiagnostics.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/RangeTraps.swift b/test/1_stdlib/RangeTraps.swift index cac7717f8354e..b61899b28dc37 100644 --- a/test/1_stdlib/RangeTraps.swift +++ b/test/1_stdlib/RangeTraps.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Reflection.swift b/test/1_stdlib/Reflection.swift index 788a20dca6b3e..e974baf4e9418 100644 --- a/test/1_stdlib/Reflection.swift +++ b/test/1_stdlib/Reflection.swift @@ -173,7 +173,7 @@ print("\(intArrayMirror[0].0): \(intArrayMirror[0].1.summary)") // CHECK-NEXT: [4]: 5 print("\(intArrayMirror[4].0): \(intArrayMirror[4].1.summary)") -var justSomeFunction = { (x:Int)->Int in return x + 1 } +var justSomeFunction = { (x:Int) -> Int in return x + 1 } // CHECK-NEXT: (Function) print(_reflect(justSomeFunction).summary) diff --git a/test/1_stdlib/ReflectionHashing.swift b/test/1_stdlib/ReflectionHashing.swift index ff4ab4153b0cb..6293ea53980d7 100644 --- a/test/1_stdlib/ReflectionHashing.swift +++ b/test/1_stdlib/ReflectionHashing.swift @@ -11,6 +11,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var Reflection = TestSuite("Reflection") Reflection.test("Dictionary/Empty") { @@ -67,7 +75,7 @@ Reflection.test("Dictionary") { expected += " - .0: Four\n" expected += " - .1: 4\n" #else - fatalError("unipmelemented") + fatalError("unimplemented") #endif expectEqual(expected, output) diff --git a/test/1_stdlib/Repeat.swift b/test/1_stdlib/Repeat.swift new file mode 100644 index 0000000000000..f87985d6c5c69 --- /dev/null +++ b/test/1_stdlib/Repeat.swift @@ -0,0 +1,16 @@ +// RUN: %target-run-simple-swift +// REQUIRES: executable_test + +import StdlibUnittest +import Swift + +let RepeatTests = TestSuite("Repeat") +RepeatTests.test("Attributes") { + let r = Repeat(count: 42, repeatedValue: "repeat") + expectEqual(r.count, 42) + expectEqual(r.startIndex, 0) + expectEqual(r.endIndex, 42) + expectEqual(r.repeatedValue, "repeat") +} + +runAllTests() diff --git a/test/1_stdlib/Runtime.swift b/test/1_stdlib/Runtime.swift index 3c4dfd450ce8d..5df6462fcb4a1 100644 --- a/test/1_stdlib/Runtime.swift +++ b/test/1_stdlib/Runtime.swift @@ -17,10 +17,10 @@ import MirrorObjC var nsObjectCanaryCount = 0 @objc class NSObjectCanary : NSObject { override init() { - ++nsObjectCanaryCount + nsObjectCanaryCount += 1 } deinit { - --nsObjectCanaryCount + nsObjectCanaryCount -= 1 } } @@ -31,10 +31,10 @@ struct NSObjectCanaryStruct { var swiftObjectCanaryCount = 0 class SwiftObjectCanary { init() { - ++swiftObjectCanaryCount + swiftObjectCanaryCount += 1 } deinit { - --swiftObjectCanaryCount + swiftObjectCanaryCount -= 1 } } @@ -238,11 +238,11 @@ Runtime.test("_isClassOrObjCExistential") { expectFalse(_isClassOrObjCExistential(SwiftObjectCanaryStruct.self)) expectFalse(_isClassOrObjCExistential_Opaque(SwiftObjectCanaryStruct.self)) - typealias SwiftClosure = ()->() + typealias SwiftClosure = () -> () expectFalse(_isClassOrObjCExistential(SwiftClosure.self)) expectFalse(_isClassOrObjCExistential_Opaque(SwiftClosure.self)) - typealias ObjCClosure = @convention(block) ()->() + typealias ObjCClosure = @convention(block) () -> () expectTrue(_isClassOrObjCExistential(ObjCClosure.self)) expectTrue(_isClassOrObjCExistential_Opaque(ObjCClosure.self)) @@ -272,10 +272,10 @@ Runtime.test("_canBeClass") { expectEqual(1, _canBeClass(SwiftObjectCanary.self)) expectEqual(0, _canBeClass(SwiftObjectCanaryStruct.self)) - typealias SwiftClosure = ()->() + typealias SwiftClosure = () -> () expectEqual(0, _canBeClass(SwiftClosure.self)) - typealias ObjCClosure = @convention(block) ()->() + typealias ObjCClosure = @convention(block) () -> () expectEqual(1, _canBeClass(ObjCClosure.self)) expectEqual(1, _canBeClass(CFArray.self)) @@ -383,7 +383,7 @@ Runtime.test("isBridgedVerbatimToObjectiveC") { expectTrue(_isBridgedVerbatimToObjectiveC(BridgedVerbatimRefType)) } -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // The protocol should be defined in the standard library, otherwise the cast // does not work. @@ -409,7 +409,7 @@ struct Struct2ConformsToP1 : BooleanType, Q1 { var value: T } -// A large struct that can not be stored inline in an opaque buffer. +// A large struct that cannot be stored inline in an opaque buffer. struct Struct3ConformsToP2 : CustomStringConvertible, Q1 { var a: UInt64 = 10 var b: UInt64 = 20 @@ -428,7 +428,7 @@ struct Struct3ConformsToP2 : CustomStringConvertible, Q1 { } } -// A large struct that can not be stored inline in an opaque buffer. +// A large struct that cannot be stored inline in an opaque buffer. struct Struct4ConformsToP2 : CustomStringConvertible, Q1 { var value: T var e: UInt64 = 50 @@ -665,6 +665,16 @@ Runtime.test("typeName") { expectEqual("protocol<>.Protocol", _typeName(a.dynamicType)) } +Runtime.test("demangleName") { + expectEqual("", _stdlib_demangleName("")) + expectEqual("abc", _stdlib_demangleName("abc")) + expectEqual("\0", _stdlib_demangleName("\0")) + expectEqual("Swift.Double", _stdlib_demangleName("_TtSd")) + expectEqual("x.a : x.Foo, x.Foo>, x.Foo, x.Foo>>", + _stdlib_demangleName("_Tv1x1aGCS_3FooGS0_GS0_SiSi_GS0_SiSi__GS0_GS0_SiSi_GS0_SiSi___")) + expectEqual("Foobar", _stdlib_demangleName("_TtC13__lldb_expr_46Foobar")) +} + Runtime.test("_stdlib_atomicCompareExchangeStrongPtr") { typealias IntPtr = UnsafeMutablePointer var origP1 = IntPtr(bitPattern: 0x10101010) @@ -899,14 +909,14 @@ RuntimeFoundationWrappers.test("_stdlib_NSObject_isEqual/NoLeak") { var nsStringCanaryCount = 0 @objc class NSStringCanary : NSString { override init() { - ++nsStringCanaryCount + nsStringCanaryCount += 1 super.init() } required init(coder: NSCoder) { fatalError("don't call this initializer") } deinit { - --nsStringCanaryCount + nsStringCanaryCount -= 1 } @objc override var length: Int { return 0 @@ -2256,7 +2266,7 @@ func computeCountLeadingZeroes(x: Int64) -> Int64 { var r: Int64 = 64 while x != 0 { x >>= 1 - r-- + r -= 1 } return r } diff --git a/test/1_stdlib/SceneKit.swift b/test/1_stdlib/SceneKit.swift index 39431ed3fa6c8..c8a3e7e66d133 100644 --- a/test/1_stdlib/SceneKit.swift +++ b/test/1_stdlib/SceneKit.swift @@ -38,8 +38,8 @@ if #available(iOS 8.0, OSX 10.10, *) { node.position.z = scn_float_from_cg expectTrue(SCNVector3EqualToVector3(node.position, scn_vec3_ref)) - let f1: SCNFloat = scn_vec3_ref.x; - let f2: SCNFloat = scn_vec4_ref.y; + let f1: SCNFloat = scn_vec3_ref.x + let f2: SCNFloat = scn_vec4_ref.y expectEqual(f1, 1.0); expectEqual(f2, 2.0); } diff --git a/test/1_stdlib/SequenceWrapperTest.swift b/test/1_stdlib/SequenceWrapperTest.swift index da18bd8ac1e35..485478899b6b9 100644 --- a/test/1_stdlib/SequenceWrapperTest.swift +++ b/test/1_stdlib/SequenceWrapperTest.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -27,11 +27,11 @@ let indirect = LoggingSequence(direct) let dispatchLog = base.log func expectWrapperDispatch( - @autoclosure directOperation: ()->R1, - @autoclosure _ indirectOperation: ()->R2, + @autoclosure directOperation: () -> R1, + @autoclosure _ indirectOperation: () -> R2, _ counters: TypeIndexed, //===--- TRACE boilerplate ----------------------------------------------===// - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__ diff --git a/test/1_stdlib/SpriteKit.swift b/test/1_stdlib/SpriteKit.swift index 2d2491abcfdf0..eb579f37b0504 100644 --- a/test/1_stdlib/SpriteKit.swift +++ b/test/1_stdlib/SpriteKit.swift @@ -9,6 +9,15 @@ import Foundation import SpriteKit +// Check that the subscript is there. +@available(OSX,introduced=10.10) +@available(iOS,introduced=8.0) +@available(tvOS,introduced=8.0) +@available(watchOS,introduced=2.0) +func testSubscript(node: SKNode) { + var nodes: [SKNode] = node["me"] +} + // SKColor is NSColor on OS X and UIColor on iOS. var r = CGFloat(0) diff --git a/test/1_stdlib/StaticString.swift b/test/1_stdlib/StaticString.swift index fa61ad3cf7ac1..a719a23365167 100644 --- a/test/1_stdlib/StaticString.swift +++ b/test/1_stdlib/StaticString.swift @@ -3,6 +3,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var StaticStringTestSuite = TestSuite("StaticString") StaticStringTestSuite.test("PointerRepresentation/ASCII/Empty") { diff --git a/test/1_stdlib/Strideable.swift b/test/1_stdlib/Strideable.swift index ae4c58ab22876..c8b5badcdc731 100644 --- a/test/1_stdlib/Strideable.swift +++ b/test/1_stdlib/Strideable.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,6 +16,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + // Check that the generic parameter is called 'Element'. protocol TestProtocol1 {} diff --git a/test/1_stdlib/StringReallocation.swift b/test/1_stdlib/StringReallocation.swift index 79bcc54a5da91..acbfaf57d8fa7 100644 --- a/test/1_stdlib/StringReallocation.swift +++ b/test/1_stdlib/StringReallocation.swift @@ -15,7 +15,7 @@ func testReallocation() { story += " " story += s if lastBase != story._core._baseAddress { - ++reallocations + reallocations += 1 // To avoid dumping a vast string here, just write the first // part of the story out each time there's a reallocation. diff --git a/test/1_stdlib/StringTraps.swift b/test/1_stdlib/StringTraps.swift index 304f0cac5f623..3fb0f04cfc974 100644 --- a/test/1_stdlib/StringTraps.swift +++ b/test/1_stdlib/StringTraps.swift @@ -7,10 +7,7 @@ // RUN: %target-run %t/a.out_Release // REQUIRES: executable_test -// XFAIL: linux - import StdlibUnittest -import Foundation // Also import modules which are used by StdlibUnittest internally. This // workaround is needed to link all required libraries in case we compile @@ -29,10 +26,10 @@ StringTraps.test("startIndex/predecessor") .code { var s = "abc" var i = s.startIndex - ++i - --i + i = i.successor() + i = i.predecessor() expectCrashLater() - --i + i = i.predecessor() } StringTraps.test("endIndex/successor") @@ -42,11 +39,11 @@ StringTraps.test("endIndex/successor") .code { var s = "abc" var i = s.startIndex - ++i - ++i - ++i + i = i.successor() + i = i.successor() + i = i.successor() expectCrashLater() - ++i + i = i.successor() } StringTraps.test("subscript(_:)/endIndex") @@ -56,9 +53,9 @@ StringTraps.test("subscript(_:)/endIndex") .code { var s = "abc" var i = s.startIndex - ++i - ++i - ++i + i = i.successor() + i = i.successor() + i = i.successor() expectCrashLater() s[i] } @@ -70,11 +67,11 @@ StringTraps.test("UTF8ViewEndIndexSuccessor") .code { var s = "abc" var i = s.utf8.startIndex - ++i - ++i - ++i + i = i.successor() + i = i.successor() + i = i.successor() expectCrashLater() - ++i + i = i.successor() } StringTraps.test("UTF8ViewSubscript/endIndex") @@ -84,9 +81,9 @@ StringTraps.test("UTF8ViewSubscript/endIndex") .code { var s = "abc" var i = s.utf8.startIndex - ++i - ++i - ++i + i = i.successor() + i = i.successor() + i = i.successor() expectCrashLater() s.utf8[i] } @@ -98,7 +95,7 @@ StringTraps.test("UTF16ViewSubscript/DecrementedStartIndex") .code { var s = "abc" var i = s.utf16.startIndex - --i + i = i.predecessor() expectCrashLater() s.utf16[i] } @@ -110,9 +107,9 @@ StringTraps.test("UTF16ViewSubscript/endIndex") .code { var s = "abc" var i = s.utf16.startIndex - ++i - ++i - ++i + i = i.successor() + i = i.successor() + i = i.successor() expectCrashLater() s.utf16[i] } diff --git a/test/1_stdlib/SwiftObjectNSObject.swift b/test/1_stdlib/SwiftObjectNSObject.swift index 61ecfa232807f..380a691fa59ba 100644 --- a/test/1_stdlib/SwiftObjectNSObject.swift +++ b/test/1_stdlib/SwiftObjectNSObject.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/test/1_stdlib/Tuple.swift.gyb b/test/1_stdlib/Tuple.swift.gyb new file mode 100644 index 0000000000000..e3b3201b4a3e7 --- /dev/null +++ b/test/1_stdlib/Tuple.swift.gyb @@ -0,0 +1,154 @@ +// RUN: rm -f %t.swift %t.out + +// RUN: %S/../../utils/gyb %s -o %t.swift +// RUN: %S/../../utils/line-directive %t.swift -- %target-build-swift %t.swift -o %t.out +// RUN: %S/../../utils/line-directive %t.swift -- %target-run %t.out +// REQUIRES: executable_test + +import StdlibUnittest + +var TupleTestSuite = TestSuite("Tuple") + +// Test tuple comparison operators +// all the tuple types use the same basic implementation for the operators +// so testing any arity tests the logic for them all. +// Include at least one invocation for all arities as a sanity check. + +% maxArity = 6 # the highest arity the operators are defined for + +func testEquality( + lhs: (A,B,C), equal: Bool, to rhs: (A,B,C), + //===--- TRACE boilerplate ----------------------------------------------===// + @autoclosure _ message: ()->String = "", + showFrame: Bool = true, + stackTrace: SourceLocStack = SourceLocStack(), + file: String = __FILE__, line: UInt = __LINE__ +) { + let trace = stackTrace.pushIf(showFrame, file: file, line: line) + expectEqual(equal, lhs == rhs, stackTrace: trace) + expectEqual(equal, rhs == lhs, stackTrace: trace) + expectEqual(!equal, lhs != rhs, stackTrace: trace) + expectEqual(!equal, rhs != lhs, stackTrace: trace) +} + +TupleTestSuite.test("Tuple/equality") { + testEquality((1,2,3), equal: true, to: (1,2,3)) + testEquality((1,2,3), equal: false, to: (1,2,4)) + testEquality((1,2,3), equal: false, to: (1,3,3)) + testEquality((1,2,3), equal: false, to: (2,2,3)) + testEquality((1,"2",3), equal: true, to: (1,"2",3)) + testEquality((1,"2",3), equal: false, to: (1,"3",3)) + testEquality(("one", 2.2, 3..<5), equal: true, to: ("one", 2.2, 3..<5)) + + testEquality((1.0, 2.0, 3.0), equal: false, to: (1.0, 2.0, .NaN)) + testEquality((1.0, 2.0, 3.0), equal: false, to: (1.0, .NaN, 3.0)) + testEquality((1.0, 2.0, 3.0), equal: false, to: (.NaN, 2.0, 3.0)) + testEquality((1.0, 2.0, 3.0), equal: false, to: (.NaN, .NaN, .NaN)) + testEquality((1.0, 2.0, Float.NaN), equal: false, to: (1.0, 2.0, 3.0)) + testEquality((1.0, 2.0, Float.NaN), equal: false, to: (1.0, 2.0, Float.NaN)) + testEquality((Float.NaN, Float.NaN, Float.NaN), equal: false, to: (.NaN, .NaN, .NaN)) + testEquality((Float.NaN, Float.NaN, Float.NaN), equal: false, to: (1.0, 2.0, 3.0)) + + expectTrue((1,2) == (1,2)) + expectTrue((1,2) != (1,3)) + expectTrue((1,2,3,4) == (1,2,3,4)) + expectTrue((1,2,3,4) != (1,2,3,3)) + expectTrue((1,2,3,4,5) == (1,2,3,4,5)) + expectTrue((1,2,3,4,5) != (1,2,3,4,4)) + expectTrue((1,2,3,4,5,6) == (1,2,3,4,5,6)) + expectTrue((1,2,3,4,5,6) != (1,2,3,4,5,5)) +} + +TupleTestSuite.test("Tuple/equality/sanity-check") { + // sanity check all arities +% for arity in range(2,maxArity+1): +% a = str(tuple(range(1, arity+1))) +% b = "({}, 0)".format(", ".join([str(i) for i in range(1,arity)])) +% c = "(0, {})".format(", ".join([str(i) for i in range(2,arity+1)])) + expectTrue(${a} == ${a}) + expectTrue(${a} != ${b}) + expectTrue(${b} != ${a}) + expectTrue(${a} != ${c}) + expectTrue(${c} != ${a}) +% end +} + +enum Ordering : Equatable { + case LessThan + case EqualTo + case GreaterThan + case UnorderedWith // Comparable defines strict total order, but Float disobeys that with NaN + + var isLT: Bool { + return self == .LessThan + } + var isEQ: Bool { + return self == .EqualTo + } + var isGT: Bool { + return self == .GreaterThan + } +} + +func testOrdering( + lhs: (A,B,C), _ ordering: Ordering, _ rhs: (A, B, C), + //===--- TRACE boilerplate ----------------------------------------------===// + @autoclosure _ message: ()->String = "", + showFrame: Bool = true, + stackTrace: SourceLocStack = SourceLocStack(), + file: String = __FILE__, line: UInt = __LINE__ +) { + let trace = stackTrace.pushIf(showFrame, file: file, line: line) + expectEqual(ordering.isLT, lhs < rhs, stackTrace: trace) + expectEqual(ordering.isLT, rhs > lhs, stackTrace: trace) + expectEqual(ordering.isLT || ordering.isEQ, lhs <= rhs, stackTrace: trace) + expectEqual(ordering.isLT || ordering.isEQ, rhs >= lhs, stackTrace: trace) + expectEqual(ordering.isGT, lhs > rhs, stackTrace: trace) + expectEqual(ordering.isGT, rhs < lhs, stackTrace: trace) + expectEqual(ordering.isGT || ordering.isEQ, lhs >= rhs, stackTrace: trace) + expectEqual(ordering.isGT || ordering.isEQ, rhs <= lhs, stackTrace: trace) +} + +TupleTestSuite.test("Tuple/comparison") { + testOrdering((1,2,3), .EqualTo, (1,2,3)) + testOrdering((1,2,3), .LessThan, (1,2,4)) + testOrdering((1,2,3), .GreaterThan, (1,2,2)) + testOrdering((1,3,2), .GreaterThan, (1,2,3)) + testOrdering((0,2,3), .LessThan, (1,2,3)) + testOrdering((3,2,1), .GreaterThan, (1,2,3)) + + testOrdering(("one", 2, 3.3), .EqualTo, ("one", 2, 3.3)) + testOrdering(("one", 2, 3.3), .LessThan, ("one", 2, 3.4)) + testOrdering(("on", 2, 3.3), .LessThan, ("one", 1, 3.2)) + + testOrdering((1, 2, Float.NaN), .UnorderedWith, (1, 2, .NaN)) + testOrdering((1, Float.NaN, 3), .UnorderedWith, (1, 2, 3)) + testOrdering((Double.NaN, 2, 3), .UnorderedWith, (.NaN, 2, 3)) + testOrdering((Float.NaN, Float.NaN, Float.NaN), .UnorderedWith, (1, 2, 3)) + testOrdering((1, 2, 3.0), .UnorderedWith, (1, 2, .NaN)) + testOrdering((1, 2, 3.0), .LessThan, (1, 3, .NaN)) + testOrdering((1, 2, 3.0), .GreaterThan, (1, 1, .NaN)) + testOrdering((1, 2.0, 3), .LessThan, (2, .NaN, 3)) + testOrdering((1, 2.0, 3), .GreaterThan, (0, .NaN, 3)) + testOrdering((1, 2, Float.NaN), .LessThan, (1, 3, 3.0)) + testOrdering((1, Float.NaN, 3), .GreaterThan, (0, 2.0, 3)) + testOrdering(("one", "two", 3.0), .GreaterThan, ("a", "b", .NaN)) + testOrdering(("one", "two", .NaN), .GreaterThan, ("a", "b", 3.0)) + testOrdering((1.0, "two", "three"), .UnorderedWith, (.NaN, "two", "four")) + testOrdering((.NaN, "two", "three"), .UnorderedWith, (1.0, "two", "four")) +} + +TupleTestSuite.test("Tuple/comparison/sanity-check") { + // sanity check all arities +% for arity in range(2,maxArity+1): +% a = str(tuple(range(1, arity+1))) +% b = "({}, 0)".format(", ".join([str(i) for i in range(1,arity)])) +% c = "(0, {})".format(", ".join([str(i) for i in range(2,arity+1)])) + expectTrue(${b} < ${a}) + expectTrue(${b} <= ${a}) + expectTrue(${a} > ${c}) + expectTrue(${a} >= ${c}) +% end +} + +runAllTests() diff --git a/test/1_stdlib/TypeName.swift b/test/1_stdlib/TypeName.swift index 87e4b661ee7c8..65f83eb8ed1a0 100644 --- a/test/1_stdlib/TypeName.swift +++ b/test/1_stdlib/TypeName.swift @@ -1,8 +1,6 @@ // RUN: %target-run-simple-swift | FileCheck %s // REQUIRES: executable_test -// XFAIL: linux - class C {} struct S {} enum E {} @@ -56,13 +54,21 @@ printTypeName(F.self) // CHECK-NEXT: () -> () printTypeName(F2.self) // CHECK-NEXT: () -> () -> () printTypeName(F3.self) // CHECK-NEXT: (() -> ()) -> () +#if _runtime(_ObjC) typealias B = @convention(block) () -> () typealias B2 = () -> @convention(block) () -> () typealias B3 = (@convention(block) () -> ()) -> () - -printTypeName(B.self) // CHECK-NEXT: @convention(block) () -> () -printTypeName(B2.self) // CHECK-NEXT: () -> @convention(block) () -> () -printTypeName(B3.self) // CHECK-NEXT: (@convention(block) () -> ()) -> () +printTypeName(B.self) +printTypeName(B2.self) +printTypeName(B3.self) +#else +print("@convention(block) () -> ()") +print("() -> @convention(block) () -> ()") +print("(@convention(block) () -> ()) -> ()") +#endif +// CHECK-NEXT: @convention(block) () -> () +// CHECK-NEXT: () -> @convention(block) () -> () +// CHECK-NEXT: (@convention(block) () -> ()) -> () printTypeName(F.Type.self) // CHECK-NEXT: (() -> ()).Type printTypeName(C.Type.self) // CHECK-NEXT: [[THIS]].C.Type diff --git a/test/1_stdlib/Unicode.swift b/test/1_stdlib/Unicode.swift index 23ab35ffed72a..b59a33c8389c0 100644 --- a/test/1_stdlib/Unicode.swift +++ b/test/1_stdlib/Unicode.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,11 +22,11 @@ UnicodeInternals.test("copy") { var u16: [UTF16.CodeUnit] = [ 6, 7, 8, 9, 10, 11 ] u16.withUnsafeMutableBufferPointer { - (u16)->() in + (u16) -> () in let p16 = u16.baseAddress u8.withUnsafeMutableBufferPointer { - (u8)->() in + (u8) -> () in let p8 = u8.baseAddress UTF16._copy(p8, destination: p16, count: 3) diff --git a/test/1_stdlib/Unmanaged.swift b/test/1_stdlib/Unmanaged.swift index 039506b14d20e..25a1512a1a55f 100644 --- a/test/1_stdlib/Unmanaged.swift +++ b/test/1_stdlib/Unmanaged.swift @@ -5,6 +5,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + // Check that the generic parameter is called 'Instance'. protocol TestProtocol1 {} diff --git a/test/1_stdlib/UnsafePointer.swift.gyb b/test/1_stdlib/UnsafePointer.swift.gyb index 383f9169a9707..63afc948b52b0 100644 --- a/test/1_stdlib/UnsafePointer.swift.gyb +++ b/test/1_stdlib/UnsafePointer.swift.gyb @@ -5,6 +5,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + protocol TestProtocol1 {} // Check that the generic parameter is called 'Memory'. @@ -124,7 +132,7 @@ class Missile { static var missilesLaunched = 0 let number: Int init(_ number: Int) { self.number = number } - deinit { Missile.missilesLaunched++ } + deinit { Missile.missilesLaunched += 1 } } func checkPointerCorrectness(check: Check, diff --git a/test/1_stdlib/VarArgs.swift b/test/1_stdlib/VarArgs.swift index 240fa871aa9c5..2791711de4113 100644 --- a/test/1_stdlib/VarArgs.swift +++ b/test/1_stdlib/VarArgs.swift @@ -1,17 +1,19 @@ // RUN: %target-run-stdlib-swift -parse-stdlib %s | FileCheck %s // REQUIRES: executable_test -// XFAIL: linux - import Swift -import CoreGraphics -@_silgen_name("vprintf") -func c_vprintf(format: UnsafePointer, _ args: CVaListPointer) +#if _runtime(_ObjC) +import Darwin +import CoreGraphics +#else +import Glibc +typealias CGFloat = Double +#endif func my_printf(format: String, _ arguments: CVarArgType...) { withVaList(arguments) { - c_vprintf(format, $0) + vprintf(format, $0) } } @@ -35,7 +37,7 @@ func test_varArgs1() { // CHECK: dig it: 0 0 -1 1 -2 2 -3 3 -4 4 -5 5 -6 6 -7 7 -8 8 -9 9 -10 10 -11 11 withVaList(args) { - c_vprintf(format + "\n", $0) + vprintf(format + "\n", $0) } } test_varArgs1() @@ -48,12 +50,18 @@ func test_varArgs3() { args.append(COpaquePointer(bitPattern: 0x1234_5671)) args.append(UnsafePointer(bitPattern: 0x1234_5672)) args.append(UnsafeMutablePointer(bitPattern: 0x1234_5673)) + +#if _runtime(_ObjC) args.append(AutoreleasingUnsafeMutablePointer( UnsafeMutablePointer(bitPattern: 0x1234_5674))) +#else + //Linux does not support AutoreleasingUnsafeMutablePointer; put placeholder. + args.append(UnsafeMutablePointer(bitPattern: 0x1234_5674)) +#endif // CHECK: {{pointers: '(0x)?0*12345670' '(0x)?0*12345671' '(0x)?0*12345672' '(0x)?0*12345673' '(0x)?0*12345674'}} withVaList(args) { - c_vprintf(format, $0) + vprintf(format, $0) } } test_varArgs3() diff --git a/test/1_stdlib/Zip.swift b/test/1_stdlib/Zip.swift index e8cee56f835be..f76807c0ae0bc 100644 --- a/test/1_stdlib/Zip.swift +++ b/test/1_stdlib/Zip.swift @@ -10,7 +10,7 @@ var i = 0 var prefix = "" for p in zip(n, s) { print("\(prefix)\(p.0) => \(p.1)", terminator: "") - ++i + i += 1 prefix = ", " } print(" (\(i) items)") @@ -20,7 +20,7 @@ i = 0 prefix = "" for p in zip(s, n) { print("\(prefix)\(p.0) => \(p.1)", terminator: "") - ++i + i += 1 prefix = ", " } print(" (\(i) items)") diff --git a/test/1_stdlib/simd.swift.gyb b/test/1_stdlib/simd.swift.gyb index cc06766a5925c..720fefb716598 100644 --- a/test/1_stdlib/simd.swift.gyb +++ b/test/1_stdlib/simd.swift.gyb @@ -11,6 +11,14 @@ import simd import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + % scalar_types = ['Float', 'Double', 'Int32'] % float_types = ['Float', 'Double'] % ctype = { 'Float':'float', 'Double':'double', 'Int32':'int' } @@ -246,7 +254,7 @@ simdTestSuite.test("matrix init") { % mat = 'm_' + mattype % diagsize = rows if rows < cols else cols - // Check empty intializer. + // Check empty initializer. var ${mat} = ${mattype}() expectEqual(${mat}, ${mattype}(${[[0]*rows]*cols}), sameValue: same) diff --git a/test/ABI/name_migrator.sil b/test/ABI/name_migrator.sil new file mode 100644 index 0000000000000..d9a5a319f7b68 --- /dev/null +++ b/test/ABI/name_migrator.sil @@ -0,0 +1,46 @@ +// RUN: swift-compress < %s | FileCheck %s + +sil_stage canonical + +import Builtin +import Swift +import SwiftShims + +class X +{ + private func ping() -> Int + @objc deinit + init() +} + +class Y : X +{ + @objc deinit + override init() +} + +//CHECK: _TcFDbNLPuN5mHx7uPzDVMqMw$Wfp3V +//CHECK: _TcFDbNLPuN5mHx7uP4Mm4ZK3E2dg +//CHECK: _TcFDbNLPuN5mHx7uPKxK8Xu7h5rx +//CHECK: _TcFDbNLPuN5mHx7Ky3gX5w$WfFvi4 +//CHECK: _TcFDbNLPuN5mHx7KyOGTa2$Swj1C8 +sil @_TFC14devirt_access21X4pingfS0_FT_Si : $@convention(method) (@guaranteed X) -> Int +sil @_TFC14devirt_access21XcfMS0_FT_S0_ : $@convention(method) (@owned X) -> @owned X +sil @_TFC14devirt_access21XCfMS0_FT_S0_ : $@convention(thin) (@thick X.Type) -> @owned X +sil @_TFC14devirt_access21YcfMS0_FT_S0_ : $@convention(method) (@owned Y) -> @owned Y +sil @_TFC14devirt_access21YCfMS0_FT_S0_ : $@convention(thin) (@thick Y.Type) -> @owned Y + +//CHECK: _TcFDbNLPuN5mHx7uPzDVMqMw$Wfp3V +//CHECK: _TcFDbNLPuN5mHx7uP4Mm4ZK3E2dg +sil_vtable X { + #X.ping!1: _TFC14devirt_access21X4pingfS0_FT_Si // devirt_access2.X.ping (devirt_access2.X)() -> Swift.Int + #X.init!initializer.1: _TFC14devirt_access21XcfMS0_FT_S0_ // devirt_access2.X.init (devirt_access2.X.Type)() -> devirt_access2.X +} + +//CHECK: _TcFDbNLPuN5mHx7uPzDVMqMw$Wfp3V +//CHECK: _TcFDbNLPuN5mHx7Ky3gX5w$WfFvi4 +sil_vtable Y { + #X.ping!1: _TFC14devirt_access21X4pingfS0_FT_Si // devirt_access2.X.ping (devirt_access2.X)() -> Swift.Int + #X.init!initializer.1: _TFC14devirt_access21YcfMS0_FT_S0_ // devirt_access2.Y.init (devirt_access2.Y.Type)() -> devirt_access2.Y +} + diff --git a/test/APINotes/blocks.swift b/test/APINotes/blocks.swift index ff1d3a1cda104..6779e81c4600a 100644 --- a/test/APINotes/blocks.swift +++ b/test/APINotes/blocks.swift @@ -7,11 +7,11 @@ import UIKit class MyView: UIView { func foo() { - UIView.animateWithDuration( 1, delay: 1, options: UIViewAnimationOptions.LayoutSubviews, - animations:{print("animating")}, - completion: {(finished:Bool)->Void in print("here we are")}); - UIView.animateWithDuration( 1, delay: 1, options: UIViewAnimationOptions.LayoutSubviews, - animations:{print("animating")}, + UIView.animateWithDuration(1, delay: 1, options: UIViewAnimationOptions.LayoutSubviews, + animations: { print("animating") }, + completion: { (finished: Bool) -> Void in print("here we are") }); + UIView.animateWithDuration(1, delay: 1, options: UIViewAnimationOptions.LayoutSubviews, + animations: { print("animating") }, completion: nil); } } diff --git a/test/BuildConfigurations/basicDeclarations.swift b/test/BuildConfigurations/basicDeclarations.swift index 1ebef409fa0c3..0bbe0c0436944 100644 --- a/test/BuildConfigurations/basicDeclarations.swift +++ b/test/BuildConfigurations/basicDeclarations.swift @@ -3,7 +3,7 @@ class A {} #if FOO -typealias A1 = A; +typealias A1 = A #endif var a: A = A() var a1: A1 = A1() // should not result in an error @@ -16,14 +16,14 @@ var c = C() // should not result in an error class D { #if FOO - var x: Int; + var x: Int #endif init() { #if !BAR x = "BAR"; // should not result in an error #else - x = 1; + x = 1 #endif } } @@ -48,13 +48,13 @@ var i: Int = f1() protocol P1 { #if FOO - func fFOO() -> Int; + func fFOO() -> Int #endif #if !BAR - func fNotBAR() -> Int; + func fNotBAR() -> Int #else - func fBAR() -> Int; + func fBAR() -> Int #endif } diff --git a/test/BuildConfigurations/module_top_level.swift b/test/BuildConfigurations/module_top_level.swift index 6ccdd61a5aa5d..1f206431a06c9 100644 --- a/test/BuildConfigurations/module_top_level.swift +++ b/test/BuildConfigurations/module_top_level.swift @@ -4,6 +4,6 @@ class C {} func > (lhs: C, rhs: C) -> Bool { - return false; + return false } #endif diff --git a/test/BuildConfigurations/pound-if-inside-function-4.swift b/test/BuildConfigurations/pound-if-inside-function-4.swift index fe648ad4b8de7..f2a77d4d853bc 100644 --- a/test/BuildConfigurations/pound-if-inside-function-4.swift +++ b/test/BuildConfigurations/pound-if-inside-function-4.swift @@ -5,7 +5,7 @@ func foo() { // expected-note {{to match this opening '{'}} #if BLAH - _ = 123; + _ = 123 #elseif !BLAH #else #else // expected-error{{further conditions after #else are unreachable}} diff --git a/test/BuildConfigurations/pound-if-top-level-3.swift b/test/BuildConfigurations/pound-if-top-level-3.swift index 9d66539e3d830..86f21c83ae3af 100644 --- a/test/BuildConfigurations/pound-if-top-level-3.swift +++ b/test/BuildConfigurations/pound-if-top-level-3.swift @@ -1,6 +1,5 @@ // RUN: %target-parse-verify-swift -// e xpected-error@+1{{unexpected configuration expression type}} #if arch(x86_64) // expected-error@+2{{expected '{' in protocol type}} // expected-error@+1{{expected #else or #endif at end of configuration block}} diff --git a/test/BuildConfigurations/x64FreeBSDTarget.swift b/test/BuildConfigurations/x64FreeBSDTarget.swift new file mode 100644 index 0000000000000..284060fa6eb49 --- /dev/null +++ b/test/BuildConfigurations/x64FreeBSDTarget.swift @@ -0,0 +1,8 @@ +// RUN: %swift -parse %s -verify -D FOO -D BAR -target x86_64-unknown-freebsd10 -disable-objc-interop -D FOO -parse-stdlib +// RUN: %swift-ide-test -test-input-complete -source-filename=%s -target x86_64-unknown-freebsd10 + +#if arch(x86_64) && os(FreeBSD) && _runtime(_Native) +class C {} +var x = C() +#endif +var y = x diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 183a4db7e4fc9..b213da38d3b93 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -25,7 +25,7 @@ function(swift_configure_lit_site_cfg source_path destination_path installed_nam endfunction() function(normalize_boolean_spelling var_name) - if("${var_name}") + if(${var_name}) set("${var_name}" TRUE PARENT_SCOPE) else() set("${var_name}" FALSE PARENT_SCOPE) @@ -40,7 +40,7 @@ function(get_test_dependencies SDK result_var_name) endif() set(deps_binaries - swift swift-ide-test sil-opt swift-llvm-opt swift-demangle sil-extract + swift swift-ide-test sil-opt swift-llvm-opt swift-demangle sil-extract swift-compress lldb-moduleimport-test) if(NOT SWIFT_BUILT_STANDALONE) list(APPEND deps_binaries llc) @@ -57,6 +57,7 @@ function(get_test_dependencies SDK result_var_name) ("${SDK}" STREQUAL "TVOS_SIMULATOR") OR ("${SDK}" STREQUAL "WATCHOS_SIMULATOR") OR ("${SDK}" STREQUAL "LINUX") OR + ("${SDK}" STREQUAL "FREEBSD") OR ("${SDK}" STREQUAL "ANDROID")) # No extra dependencies. else() diff --git a/test/ClangModules/Inputs/SwiftPrivateAttr.txt b/test/ClangModules/Inputs/SwiftPrivateAttr.txt index 06331fbd4c4c4..53c5cbadebf7b 100644 --- a/test/ClangModules/Inputs/SwiftPrivateAttr.txt +++ b/test/ClangModules/Inputs/SwiftPrivateAttr.txt @@ -95,5 +95,8 @@ struct NSOptions : OptionSetType { static var B: NSOptions { get } } typealias __PrivCFTypeRef = __PrivCFType +class __PrivCFType { +} typealias __PrivCFSubRef = __PrivCFSub +typealias __PrivCFSub = __PrivCFTypeRef typealias __PrivInt = Int32 diff --git a/test/ClangModules/Inputs/custom-modules/MacrosRedefA.h b/test/ClangModules/Inputs/custom-modules/MacrosRedefA.h new file mode 100644 index 0000000000000..f6e75f0410d87 --- /dev/null +++ b/test/ClangModules/Inputs/custom-modules/MacrosRedefA.h @@ -0,0 +1,2 @@ +#define REDEF_1 "hello" +#define REDEF_2 "world" diff --git a/test/ClangModules/Inputs/custom-modules/MacrosRedefB.h b/test/ClangModules/Inputs/custom-modules/MacrosRedefB.h new file mode 100644 index 0000000000000..9b3eaa886687b --- /dev/null +++ b/test/ClangModules/Inputs/custom-modules/MacrosRedefB.h @@ -0,0 +1,2 @@ +#define REDEF_1 "hello" +#define REDEF_2 "Swift" diff --git a/test/ClangModules/Inputs/custom-modules/ObjCImplicitProperties.h b/test/ClangModules/Inputs/custom-modules/ObjCImplicitProperties.h deleted file mode 100644 index ce84275c3d914..0000000000000 --- a/test/ClangModules/Inputs/custom-modules/ObjCImplicitProperties.h +++ /dev/null @@ -1,71 +0,0 @@ -__attribute__((objc_root_class)) -@interface ImplicitProperties -- (id)implicitProperty; -- (void)setImplicitProperty:(id)implicitProperty; - -- (void)setAnotherImplicitProperty:(int)implicitProperty; -- (int)anotherImplicitProperty; -@end - -__attribute__((objc_root_class)) -@interface BadImplicitProperties -- (int)nonVoidReturn; -- (int)setNonVoidReturn:(int)val; - -- (void)setNonMatchingType:(id)val; -- (int)nonMatchingType; - -- (int)wrongGetterArgs:(int)val; -- (void)setWrongGetterArgs:(int)val; - -- (void)setWrongSetterArgs:(int)val extra:(int)another; -- (int)wrongSetterArgs; - -- (int)wrongSetterArgs2; -- (void)setWrongSetterArgs2; - -- (int)getterOnly; - -- (void)setSetterOnly:(int)val; -@end - - -@protocol PropertiesProto -- (id)methodInProto; -@property id propertyInProto; -@end - -__attribute__((objc_root_class)) -@interface Base -- (id)methodInBase; -@property(readonly) id propertyInBase; - -- (id)methodPairInBase; -- (void)setMethodPairInBase:(id)value; - -- (id)getterOnlyInBase; - -- (void)setSetterOnlyInBase:(id)value; - -@property id methodInProto; -- (id)propertyInProto; -- (id)methodInBaseButPropertyInProto; -@property id propertyInBaseButMethodInProto; -@end - -@protocol SubProto -- (id)propertyInBaseButMethodInProto; -@property id methodInBaseButPropertyInProto; -@end - -@interface Sub : Base -@property id methodInBase; -- (id)propertyInBase; - -- (void)setMethodPairInBase:(id)value; - -- (id)getterOnlyInBase; -- (void)setGetterOnlyInBase:(id)value; - -- (id)setterOnlyInBase; -@end diff --git a/test/ClangModules/Inputs/custom-modules/SwiftName.h b/test/ClangModules/Inputs/custom-modules/SwiftName.h index aaa2353381c6e..cf98fe59a59c1 100644 --- a/test/ClangModules/Inputs/custom-modules/SwiftName.h +++ b/test/ClangModules/Inputs/custom-modules/SwiftName.h @@ -8,7 +8,7 @@ enum SWIFT_NAME(ColorKind) ColorType { CT_blue, }; -typedef struct { +typedef struct SWIFT_NAME(Point) { int X SWIFT_NAME(x); int Y SWIFT_NAME(y); } PointType; diff --git a/test/ClangModules/Inputs/custom-modules/module.map b/test/ClangModules/Inputs/custom-modules/module.map index a2bca8571b989..b4fa5ee806ac9 100644 --- a/test/ClangModules/Inputs/custom-modules/module.map +++ b/test/ClangModules/Inputs/custom-modules/module.map @@ -89,11 +89,6 @@ module ObjCParseExtrasSystem [system] { export * } -module ObjCImplicitProperties { - header "ObjCImplicitProperties.h" - export * -} - module ObjCSubscripts { header "ObjCSubscripts.h" export * @@ -133,3 +128,11 @@ module Requires { module SwiftName { header "SwiftName.h" } + +module MacrosRedefA { + header "MacrosRedefA.h" +} + +module MacrosRedefB { + header "MacrosRedefB.h" +} diff --git a/test/ClangModules/Inputs/enum-objc.h b/test/ClangModules/Inputs/enum-objc.h new file mode 100644 index 0000000000000..3b9df46d6207e --- /dev/null +++ b/test/ClangModules/Inputs/enum-objc.h @@ -0,0 +1,10 @@ +@import Foundation; + +#define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +#define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type + +typedef SWIFT_ENUM_NAMED(NSInteger, ObjCEnum, "SwiftEnum") { + ObjCEnumOne = 1, + ObjCEnumTwo, + ObjCEnumThree +}; diff --git a/test/ClangModules/MixedSource/Inputs/resolve-cross-language/Base.swift b/test/ClangModules/MixedSource/Inputs/resolve-cross-language/Base.swift index 3d05a94f0d775..2b4bade79dff9 100644 --- a/test/ClangModules/MixedSource/Inputs/resolve-cross-language/Base.swift +++ b/test/ClangModules/MixedSource/Inputs/resolve-cross-language/Base.swift @@ -21,7 +21,14 @@ extension BaseClass { case Zung } +@objc(RenamedEnum) public enum SwiftEnum: CShort { + case Quux + case Corge + case Grault +} + @objc public class AnotherClass { @objc public func getEnum() -> BaseEnum { return .Zung } + @objc public func getSwiftEnum() -> SwiftEnum { return .Quux } public init() {} } diff --git a/test/ClangModules/MixedSource/Inputs/resolve-cross-language/BaseUser.framework/Headers/BaseUser.h b/test/ClangModules/MixedSource/Inputs/resolve-cross-language/BaseUser.framework/Headers/BaseUser.h index eb1873e10463a..b5b577a91fab3 100644 --- a/test/ClangModules/MixedSource/Inputs/resolve-cross-language/BaseUser.framework/Headers/BaseUser.h +++ b/test/ClangModules/MixedSource/Inputs/resolve-cross-language/BaseUser.framework/Headers/BaseUser.h @@ -13,6 +13,7 @@ void useBaseProtoObjC(id ); @interface BaseClass (ObjCExtensions) - (void)categoryMethod; - (BaseEnum)baseEnumMethod:(BaseEnum)be; +- (RenamedEnum)renamedEnumMethod:(RenamedEnum)se; @end typedef OBJC_ENUM(unsigned char, BaseEnumObjC) { @@ -27,8 +28,29 @@ void useBaseEnum(BaseEnum); BaseEnumObjC getBaseEnumObjC(); void useBaseEnumObjC(BaseEnumObjC); +// temporarily redefine OBJC_ENUM because ClangImporter cares about the macro name +#undef OBJC_ENUM +#define OBJC_ENUM(_type, _name, SWIFT_NAME) enum _name : _type _name __attribute__((swift_name(SWIFT_NAME))); enum __attribute__((swift_name(SWIFT_NAME))) _name : _type + +typedef OBJC_ENUM(unsigned char, RenamedEnumObjC, "SwiftEnumObjC") { + RenamedEnumObjCQuux = RenamedEnumQuux, + RenamedEnumObjCCorge = RenamedEnumCorge, + RenamedEnumObjCGrault = RenamedEnumGrault, +}; + +// put OBJC_ENUM back just in case +#undef OBJC_ENUM +#define OBJC_ENUM(_type, _name) enum _name : _type _name; enum _name : _type + +RenamedEnum getRenamedEnum(); +void useRenamedEnum(RenamedEnum); + +RenamedEnumObjC getRenamedEnumObjC(); +void useRenamedEnumObjC(RenamedEnumObjC); + @protocol EnumProto - (BaseEnum)getEnum; +- (RenamedEnum)getSwiftEnum; @end @interface AnotherClass (EnumProtoConformance) diff --git a/test/ClangModules/MixedSource/resolve-cross-language.swift b/test/ClangModules/MixedSource/resolve-cross-language.swift index b143ddd8af3c8..d07393283f858 100644 --- a/test/ClangModules/MixedSource/resolve-cross-language.swift +++ b/test/ClangModules/MixedSource/resolve-cross-language.swift @@ -20,6 +20,12 @@ be = getBaseClass().baseEnumMethod(be) be = AnotherClass().getEnum() var beo: BaseEnumObjC = getBaseEnumObjC() useBaseEnumObjC(beo) +var se: SwiftEnum = getRenamedEnum() +useRenamedEnum(se) +se = getBaseClass().renamedEnumMethod(se) +se = AnotherClass().getSwiftEnum() +var seo: SwiftEnumObjC = getRenamedEnumObjC() +useRenamedEnumObjC(seo) // Check type resolution. useBaseClass(getBaseClassObjC()) @@ -44,5 +50,17 @@ beo = BaseEnumObjC.Dah var beoRaw: CUnsignedChar = beo.rawValue +se = SwiftEnum.Quux +se = SwiftEnum.Corge +se = SwiftEnum.Grault + +var seRaw: CShort = se.rawValue + +seo = SwiftEnumObjC.Quux +seo = SwiftEnumObjC.Corge +seo = SwiftEnumObjC.Grault + +var seoRaw: CUnsignedChar = seo.rawValue + // Make sure we're actually parsing stuff. useBaseClass() // expected-error{{missing argument for parameter #1}} diff --git a/test/ClangModules/attr-swift_name_renaming.swift b/test/ClangModules/attr-swift_name_renaming.swift index 81ed168467a0d..8e378c01959ea 100644 --- a/test/ClangModules/attr-swift_name_renaming.swift +++ b/test/ClangModules/attr-swift_name_renaming.swift @@ -8,17 +8,17 @@ func test() { drawString("hello", 3, 5) // expected-error{{missing argument labels 'x:y:' in call}} // Enum name remapping. - var color: ColorKind = CT_red // FIXME: expected-error{{use of undeclared type 'ColorKind'}} + var color: ColorKind = CT_red var colo2: ColorType = CT_Red // FIXME: should provide Fix-It expected-error{{use of undeclared type 'ColorType'}} - // Typedef-of-anonymous-type-name renamming - var p = Point() // FIXME: expected-error{{use of unresolved identifier 'Point'}} - var p2 = PointType() // FIXME: should error + // Typedef-of-anonymous-type-name renaming + var p = Point() + var p2 = PointType() // FIXME: should provide Fix-It expected-error{{use of unresolved identifier 'PointType'}} // Field name remapping p.x = 7 // Typedef renaming - var mi: MyInt = 5 // FIXME: expected-error{{use of undeclared type 'MyInt'}} + var mi: MyInt = 5 var mi2: my_int_t = 7 // FIXME: should provide Fix-It expected-error{{use of undeclared type 'my_int_t'}} } diff --git a/test/ClangModules/availability_implicit_macosx.swift b/test/ClangModules/availability_implicit_macosx.swift index ee5600c536ca7..bc0ee59f158ed 100644 --- a/test/ClangModules/availability_implicit_macosx.swift +++ b/test/ClangModules/availability_implicit_macosx.swift @@ -60,7 +60,7 @@ class DeprecatedSuperClass { class NotDeprecatedSubClassOfDeprecatedSuperClass : DeprecatedSuperClass { // expected-warning {{'DeprecatedSuperClass' was deprecated in OS X 10.10}} } -func callImplicitInitalizerOnNotDeprecatedSubClassOfDeprecatedSuperClass() { +func callImplicitInitializerOnNotDeprecatedSubClassOfDeprecatedSuperClass() { // We do not expect a warning here because the synthesized initializer // in NotDeprecatedSubClassOfDeprecatedSuperClass is not itself marked // deprecated. diff --git a/test/ClangModules/cfuncs_parse.swift b/test/ClangModules/cfuncs_parse.swift index eea44702cbc71..a38edabaca392 100644 --- a/test/ClangModules/cfuncs_parse.swift +++ b/test/ClangModules/cfuncs_parse.swift @@ -12,8 +12,8 @@ func test_cfunc1(i: Int) { func test_cfunc2(i: Int) { let f = cfunc2(i, 17) _ = f as Float - // FIXME: Should report this error: {{cannot convert the expression's type '$T3' to type 'CLong'}} - cfunc2(b:17, a:i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'Int32'}} + cfunc2(b:17, a:i) // expected-error{{extraneous argument labels 'b:a:' in call}} + cfunc2(17, i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'Int32'}} } func test_cfunc3_a() { diff --git a/test/ClangModules/enum-objc.swift b/test/ClangModules/enum-objc.swift new file mode 100644 index 0000000000000..5b8f0fe2e246b --- /dev/null +++ b/test/ClangModules/enum-objc.swift @@ -0,0 +1,11 @@ +// RUN: %target-swift-frontend -emit-sil %s -import-objc-header %S/Inputs/enum-objc.h -verify + +// REQUIRES: objc_interop + +func test(value: SwiftEnum) { + switch value { + case .One: break + case .Two: break + case .Three: break + } // no error +} diff --git a/test/ClangModules/foreign_errors.swift b/test/ClangModules/foreign_errors.swift index 48098e7ce473e..53c6f3422e1a4 100644 --- a/test/ClangModules/foreign_errors.swift +++ b/test/ClangModules/foreign_errors.swift @@ -98,7 +98,7 @@ func testSwiftError() throws { } // rdar://21074857 -func needsNonThrowing(fn: () -> ()) {} +func needsNonThrowing(fn: () -> Void) {} func testNSErrorExhaustive() { needsNonThrowing { do { diff --git a/test/ClangModules/macros_redef.swift b/test/ClangModules/macros_redef.swift new file mode 100644 index 0000000000000..6e37fcc3be256 --- /dev/null +++ b/test/ClangModules/macros_redef.swift @@ -0,0 +1,11 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/custom-modules -parse -verify %s + +import MacrosRedefA +import MacrosRedefB + +func testMacroRedef() { + var s: String + s = REDEF_1 + s = REDEF_2 // expected-error{{ambiguous use of 'REDEF_2'}} +} + diff --git a/test/ClangModules/no-sdk.swift b/test/ClangModules/no-sdk.swift index e4fddc726511c..eb1685eebc65c 100644 --- a/test/ClangModules/no-sdk.swift +++ b/test/ClangModules/no-sdk.swift @@ -2,6 +2,6 @@ // RUN: %target-swift-frontend -parse -sdk "" -I %S/Inputs/custom-modules %s // Verify that we can still import modules even without an SDK. -import ExternIntX; +import ExternIntX let y: CInt = ExternIntX.x diff --git a/test/ClangModules/nullability_silgen.swift b/test/ClangModules/nullability_silgen.swift index a56ef8177530a..550757103ab4d 100644 --- a/test/ClangModules/nullability_silgen.swift +++ b/test/ClangModules/nullability_silgen.swift @@ -2,7 +2,7 @@ // REQUIRES: objc_interop -import nullability; +import nullability // null_resettable properties. // CHECK-LABEL: sil hidden @_TF18nullability_silgen18testNullResettable diff --git a/test/ClangModules/objc_dynamic_lookup.swift b/test/ClangModules/objc_dynamic_lookup.swift new file mode 100644 index 0000000000000..54e2f5484d1f9 --- /dev/null +++ b/test/ClangModules/objc_dynamic_lookup.swift @@ -0,0 +1,9 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse %s -verify + +// REQUIRES: objc_interop + +import Foundation + +func useAnyObject(obj: AnyObject) { + _ = obj.makingHoney +} diff --git a/test/ClangModules/objc_factory_method.swift b/test/ClangModules/objc_factory_method.swift index 1298a91d0e47b..29ae9e896c4b6 100644 --- a/test/ClangModules/objc_factory_method.swift +++ b/test/ClangModules/objc_factory_method.swift @@ -36,7 +36,7 @@ func testFactoryWithLaterIntroducedInit() { _ = NSHavingConvenienceFactoryAndEarlierConvenienceInit(flim:5) _ = NSHavingConvenienceFactoryAndEarlierConvenienceInit(flam:5) - // Don't prefer more available convience factory initializer over less + // Don't prefer more available convenience factory initializer over less // available designated initializer _ = NSHavingConvenienceFactoryAndLaterDesignatedInit(flim:5) // expected-error {{'init(flim:)' is only available on OS X 10.11 or newer}} // expected-note @-1 {{add 'if #available' version check}} diff --git a/test/ClangModules/objc_implicit_properties.swift b/test/ClangModules/objc_implicit_properties.swift deleted file mode 100644 index c604954b53fd5..0000000000000 --- a/test/ClangModules/objc_implicit_properties.swift +++ /dev/null @@ -1,80 +0,0 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse -I %S/Inputs/custom-modules -enable-objc-implicit-properties %s -verify - -// REQUIRES: objc_interop - -import ObjectiveC -import ObjCImplicitProperties - -func acceptsInt(_: Int) {} -func acceptsInt(_: UInt) {} - -func implicitProperties(obj: ImplicitProperties, other: AnyObject) { - obj.implicitProperty = other // no-warning - obj.implicitProperty.hash // no-warning - - obj.anotherImplicitProperty = 42 // no-warning - acceptsInt(Int(obj.anotherImplicitProperty)) // no-warning -} - -func badImplicitProperties(obj: BadImplicitProperties) { - acceptsInt(obj.nonVoidReturn) // expected-error {{cannot invoke 'acceptsInt' with an argument list of type '(() -> Int32)'}} - // expected-note @-1 {{overloads for 'acceptsInt' exist with these partially matching parameter lists: (Int), (UInt)}} - - acceptsInt(obj.nonMatchingType) // expected-error {{cannot invoke 'acceptsInt' with an argument list of type '(() -> Int32)'}} - // expected-note @-1 {{overloads for 'acceptsInt' exist with these partially matching parameter lists: (Int), (UInt)}} - - acceptsInt(obj.wrongGetterArgs) // expected-error {{cannot invoke 'acceptsInt' with an argument list of type '((Int32) -> Int32)'}} - // expected-note @-1 {{overloads for 'acceptsInt' exist with these partially matching parameter lists: (Int), (UInt)}} - - acceptsInt(obj.wrongSetterArgs) // expected-error {{cannot invoke 'acceptsInt' with an argument list of type '(() -> Int32)'}} - // expected-note @-1 {{overloads for 'acceptsInt' exist with these partially matching parameter lists: (Int), (UInt)}} - - acceptsInt(obj.wrongSetterArgs2) // expected-error {{cannot invoke 'acceptsInt' with an argument list of type '(() -> Int32)'}} - // expected-note @-1 {{overloads for 'acceptsInt' exist with these partially matching parameter lists: (Int), (UInt)}} - - acceptsInt(obj.getterOnly) // expected-error {{cannot invoke 'acceptsInt' with an argument list of type '(() -> Int32)'}} - // expected-note @-1 {{overloads for 'acceptsInt' exist with these partially matching parameter lists: (Int), (UInt)}} - - acceptsInt(obj.setterOnly) // expected-error {{value of type 'BadImplicitProperties' has no member 'setterOnly'}} - - // But we should still import all of the methods as methods. - let x: CInt = obj.setNonVoidReturn(obj.nonVoidReturn()) - let y: CInt = obj.nonMatchingType() - obj.setNonMatchingType(obj) - obj.setWrongGetterArgs(obj.wrongGetterArgs(42)) - obj.setWrongSetterArgs(obj.wrongSetterArgs(), extra: 42) - let z: CInt = obj.wrongSetterArgs2() - obj.setWrongSetterArgs2() - obj.setSetterOnly(obj.getterOnly()) -} - -func overriding(obj: Sub) { - let a: AnyObject = obj.methodInBase() - let b: AnyObject = obj.propertyInBase - let c: AnyObject = obj.methodPairInBase - let d: AnyObject = obj.getterOnlyInBase // expected-error {{}} {{42-42=()}} - let e: AnyObject = obj.setterOnlyInBase // expected-error {{}} {{42-42=()}} - let f: AnyObject = obj.methodInProto - let g: AnyObject = obj.propertyInProto() - let h: AnyObject = obj.methodInBaseButPropertyInProto() - let i: AnyObject = obj.propertyInBaseButMethodInProto - - obj.setGetterOnlyInBase(obj.getterOnlyInBase()) - obj.setSetterOnlyInBase(obj.setterOnlyInBase()) - - // FIXME: These are incorrectly accepted or incorrectly rejected. - obj.setMethodPairInBase(c) - - obj.setPropertyInProto(g) // expected-error {{value of type 'Sub' has no member 'setPropertyInProto'}} - obj.setMethodInBaseButPropertyInProto(h) // expected-error {{value of type 'Sub' has no member 'setMethodInBaseButPropertyInProto'}} -} - -func doSomethingBase(obj: T) {} -func doSomethingSub(obj: T) {} - -func protocols(obj: Sub) { - _ = obj as PropertiesProto - _ = obj as SubProto - doSomethingBase(obj) - doSomethingSub(obj) -} diff --git a/test/ClangModules/objc_ir.swift b/test/ClangModules/objc_ir.swift index beccd73d22c7d..72c7ca7af69a8 100644 --- a/test/ClangModules/objc_ir.swift +++ b/test/ClangModules/objc_ir.swift @@ -28,11 +28,11 @@ func instanceMethods(b: B) { // CHECK: define hidden void @_TF7objc_ir16extensionMethodsFT1bCSo1B_T_ func extensionMethods(b b: B) { - // CHECK: load i8*, i8** @"\01L_selector(method:separateExtMethod:)", align 8 - // CHECK: [[T0:%.*]] = call i8* bitcast (void ()* @objc_msgSend to i8* - // CHECK: [[T1:%.*]] = ptrtoint i8* [[T0]] to i64 - // CHECK: [[T2:%.*]] = inttoptr i64 [[T1]] to i8* - // CHECK: call i8* @objc_retainAutoreleasedReturnValue(i8* [[T2]]) + // CHECK: load i8*, i8** @"\01L_selector(method:separateExtMethod:)", align 8 + // CHECK: [[T0:%.*]] = call i8* bitcast (void ()* @objc_msgSend to i8* + // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NOT: [[T0]] + // CHECK: [[T1]] b.method(1, separateExtMethod:1.5) } diff --git a/test/ClangModules/objc_parse.swift b/test/ClangModules/objc_parse.swift index b15e0bc918955..966a19efaab58 100644 --- a/test/ClangModules/objc_parse.swift +++ b/test/ClangModules/objc_parse.swift @@ -57,7 +57,7 @@ func instanceMethods(b: B) { var obj = NSObject() var prot = NSObjectProtocol.self b.`protocol`(prot, hasThing:obj) - b.doThing(obj, `protocol`: prot) + b.doThing(obj, protocol: prot) } // Class method invocation diff --git a/test/ClangModules/optional.swift b/test/ClangModules/optional.swift index afa43aef641b9..829c076830498 100644 --- a/test/ClangModules/optional.swift +++ b/test/ClangModules/optional.swift @@ -28,7 +28,7 @@ class A { // CHECK-NEXT: br // Continuation. // CHECK: bb3([[T0:%.*]] : $Optional): -// CHECK-NEXT: autorelease_return [[T0]] +// CHECK-NEXT: return [[T0]] @objc func bar(x x : String?) {} // CHECK-LABEL: sil hidden [thunk] @_TToFC8optional1A3barfT1xGSqSS__T_ : $@convention(objc_method) (Optional, A) -> () diff --git a/test/Constraints/assignment.swift b/test/Constraints/assignment.swift index e06abf7b47d07..e162628626076 100644 --- a/test/Constraints/assignment.swift +++ b/test/Constraints/assignment.swift @@ -49,3 +49,11 @@ func value2(inout x: Int) {} value2(&_) // expected-error{{'_' can only appear in a pattern or on the left side of an assignment}} value(_) // expected-error{{'_' can only appear in a pattern or on the left side of an assignment}} + +// = vs. == in Swift if string character count statement causes segmentation fault +func f23798944() { + let s = "" + if s.characters.count = 0 { // expected-error {{cannot assign to property: 'count' is a get-only property}} + } +} + diff --git a/test/Constraints/bridging.swift b/test/Constraints/bridging.swift index 6796d9dea2696..b1cfc891fca71 100644 --- a/test/Constraints/bridging.swift +++ b/test/Constraints/bridging.swift @@ -273,6 +273,7 @@ func rdar20029786(ns: NSString?) { // QoI: Using as! instead of as in this case produces really bad diagnostic func rdar19813772(nsma: NSMutableArray) { var a1 = nsma as! Array // expected-error{{generic parameter 'Element' could not be inferred}} + // FIXME: The following diagnostic is misleading and should not happen: expected-warning@-1{{cast from 'NSMutableArray' to unrelated type 'Array<_>' always fails}} var a2 = nsma as! Array // expected-warning{{forced cast from 'NSMutableArray' to 'Array' always succeeds; did you mean to use 'as'?}} {{17-20=as}} var a3 = nsma as Array } diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift index 43420c35354ba..5bf2fe14fd873 100644 --- a/test/Constraints/closures.swift +++ b/test/Constraints/closures.swift @@ -19,7 +19,7 @@ mySort(strings, { x, y in x < y }) // Closures with inout arguments. func f0(t: T, _ f: (inout T) -> U) -> U { - var t2 = t; + var t2 = t return f(&t2) } @@ -45,7 +45,7 @@ func foo() { // struct X3 { - init(_: (T)->()) {} + init(_: (T) -> ()) {} } func testX3(x: Int) { @@ -98,46 +98,46 @@ func testMap() { } // "UnresolvedDot" "in wrong phase" assertion from verifier -[].reduce { $0 + $1 } // expected-error {{cannot convert value of type '(_, _) -> _' to expected argument type '(_, combine: @noescape (_, _) throws -> _)'}} +[].reduce { $0 + $1 } // expected-error {{missing argument for parameter #1 in call}} // QoI: improve diagnostic when contextual type of closure disagrees with arguments -var _: ()-> Int = {0} +var _: () -> Int = {0} -// expected-error @+1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{23-23=_ in }} -var _: (Int)-> Int = {0} +// expected-error @+1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{24-24=_ in }} +var _: (Int) -> Int = {0} -// expected-error @+1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{23-23= _ in}} -var _: (Int)-> Int = { 0 } +// expected-error @+1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{24-24= _ in}} +var _: (Int) -> Int = { 0 } -// expected-error @+1 {{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{28-28=_,_ in }} -var _: (Int, Int)-> Int = {0} +// expected-error @+1 {{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{29-29=_,_ in }} +var _: (Int, Int) -> Int = {0} // expected-error @+1 {{contextual closure type '(Int, Int) -> Int' expects 2 arguments, but 3 were used in closure body}} -var _: (Int,Int)-> Int = {$0+$1+$2} +var _: (Int,Int) -> Int = {$0+$1+$2} // expected-error @+1 {{contextual closure type '(Int, Int, Int) -> Int' expects 3 arguments, but 2 were used in closure body}} -var _: (Int, Int, Int)-> Int = {$0+$1} +var _: (Int, Int, Int) -> Int = {$0+$1} -var _: ()-> Int = {a in 0} +var _: () -> Int = {a in 0} // expected-error @+1 {{contextual closure type '(Int) -> Int' expects 1 argument, but 2 were used in closure body}} -var _: (Int)-> Int = {a,b in 0} +var _: (Int) -> Int = {a,b in 0} // expected-error @+1 {{contextual closure type '(Int) -> Int' expects 1 argument, but 3 were used in closure body}} -var _: (Int)-> Int = {a,b,c in 0} +var _: (Int) -> Int = {a,b,c in 0} -var _: (Int, Int)-> Int = {a in 0} +var _: (Int, Int) -> Int = {a in 0} // expected-error @+1 {{contextual closure type '(Int, Int, Int) -> Int' expects 3 arguments, but 2 were used in closure body}} -var _: (Int, Int, Int)-> Int = {a, b in a+b} +var _: (Int, Int, Int) -> Int = {a, b in a+b} // Fail to infer types for closure that takes an inout argument func r15998821() { - func take_closure(x : (inout Int)-> ()) { } + func take_closure(x : (inout Int) -> ()) { } func test1() { take_closure { (inout a : Int) in @@ -159,6 +159,17 @@ func r15998821() { } // better diagnostics for closures w/o "in" clause -var _: (Int,Int)-> Int = {$0+$1+$2} // expected-error {{contextual closure type '(Int, Int) -> Int' expects 2 arguments, but 3 were used in closure body}} +var _: (Int,Int) -> Int = {$0+$1+$2} // expected-error {{contextual closure type '(Int, Int) -> Int' expects 2 arguments, but 3 were used in closure body}} +// Crash when re-typechecking bodies of non-single expression closures + +struct CC {} +func callCC(f: CC -> U) -> () {} + +func typeCheckMultiStmtClosureCrash() { + callCC { // expected-error {{cannot invoke 'callCC' with an argument list of type '((CC) -> _)'}} + _ = $0 // expected-note@-1 {{expected an argument list of type '(CC -> U)'}} + return 1 + } +} diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift index 0292cdc488b6d..47466eeb3d2d5 100644 --- a/test/Constraints/diagnostics.swift +++ b/test/Constraints/diagnostics.swift @@ -42,8 +42,8 @@ f1( ) // Tuple element unused. -f0(i, i, // expected-error{{extra argument in call}} - i) +f0(i, i, + i) // expected-error{{extra argument in call}} // Position mismatch @@ -117,7 +117,7 @@ func rdar20142523() { map(0..<10, { x in // expected-error{{cannot invoke 'map' with an argument list of type '(Range, (_) -> _)'}} // expected-note @-1 {{overloads for 'map' exist with these partially matching parameter lists: (C, (C.Generator.Element) -> T), (T?, @noescape (T) -> U)}} () - return x // expected-error {{type of expression is ambiguous without more context}} + return x }) } @@ -166,7 +166,7 @@ func validateSaveButton(text: String) { // QoI: poor diagnostic when calling a class method via a metatype class r20201968C { func blah() { - r20201968C.blah() // expected-error {{missing argument for parameter #1 in call}} + r20201968C.blah() // expected-error {{use of instance member 'blah' on type 'r20201968C'; did you mean to use a value of type 'r20201968C' instead?}} } } @@ -261,9 +261,9 @@ func rdar21784170() { } // BOGUS: unexpected trailing closure -func expect(_: T)(_: U.Type) {} // expected-note {{found this candidate}} expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} -func expect(_: T, _: Int = 1)(_: U.Type) {} // expected-note {{found this candidate}} expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} -expect(Optional(3))(Optional.self) // expected-error {{ambiguous use of 'expect'}} +func expect(_: T)(_: U.Type) {} // expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} +func expect(_: T, _: Int = 1)(_: U.Type) {} // expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} +expect(Optional(3))(Optional.self) // Swift Enum Scoping Oddity func rdar19804707() { @@ -308,12 +308,15 @@ func f7(a: Int)(b : Int) -> Int { // expected-warning{{curried function declarat f7(1)(b: 1) f7(1.0)(2) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} -f7(1)(1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +f7(1)(1.0) // expected-error {{missing argument label 'b:' in call}} +f7(1)(b: 1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} let f8 = f7(2) f8(b: 1) f8(10) // expected-error {{missing argument label 'b:' in call}} {{4-4=b: }} -f8(1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +f8(1.0) // expected-error {{missing argument label 'b:' in call}} +f8(b: 1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} + class CurriedClass { func method1() {} @@ -336,12 +339,12 @@ c.method2(1.0)(b: 2.0) // expected-error {{cannot convert value of type 'Double' CurriedClass.method1(c)() _ = CurriedClass.method1(c) CurriedClass.method1(c)(1) // expected-error {{argument passed to call that takes no arguments}} -CurriedClass.method1(2.0)(1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'CurriedClass'}} +CurriedClass.method1(2.0)(1) // expected-error {{use of instance member 'method1' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} CurriedClass.method2(c)(32)(b: 1) _ = CurriedClass.method2(c) _ = CurriedClass.method2(c)(32) -_ = CurriedClass.method2(1,2) // expected-error {{extra argument in call}} +_ = CurriedClass.method2(1,2) // expected-error {{use of instance member 'method2' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} CurriedClass.method2(c)(1.0)(b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} CurriedClass.method2(c)(1)(b: 1.0) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} CurriedClass.method2(c)(2)(c: 1.0) // expected-error {{incorrect argument label in call (have 'c:', expected 'b:')}} @@ -350,9 +353,9 @@ CurriedClass.method3(c)(32, b: 1) _ = CurriedClass.method3(c) _ = CurriedClass.method3(c)(1, 2) // expected-error {{missing argument label 'b:' in call}} {{32-32=b: }} _ = CurriedClass.method3(c)(1, b: 2)(32) // expected-error {{cannot call value of non-function type '()'}} -_ = CurriedClass.method3(1, 2) // expected-error {{extra argument in call}} +_ = CurriedClass.method3(1, 2) // expected-error {{use of instance member 'method3' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} CurriedClass.method3(c)(1.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} -CurriedClass.method3(c)(1) // expected-error {{cannot convert value of type 'Int' to expected argument type '(Int, b: Int)'}} +CurriedClass.method3(c)(1) // expected-error {{missing argument for parameter 'b' in call}} CurriedClass.method3(c)(c: 1.0) // expected-error {{missing argument for parameter 'b' in call}} @@ -361,11 +364,27 @@ extension CurriedClass { func f() { method3(1, b: 2) method3() // expected-error {{missing argument for parameter #1 in call}} - method3(42) // expected-error {{cannot convert value of type 'Int' to expected argument type '(Int, b: Int)'}} + method3(42) // expected-error {{missing argument for parameter 'b' in call}} method3(self) // expected-error {{missing argument for parameter 'b' in call}} } } +extension CurriedClass { + func m1(a : Int, b : Int) {} + + func m2(a : Int) {} +} + +// QoI: "Extra argument" error when accidentally currying a method +CurriedClass.m1(2, b: 42) // expected-error {{use of instance member 'm1' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} + + +// QoI: Confusing error message when calling an instance method as a class method +CurriedClass.m2(12) // expected-error {{use of instance member 'm2' on type 'CurriedClass'; did you mean to use a value of type 'CurriedClass' instead?}} + + + + // Incorrect diagnostic for failed member lookups within closures passed as arguments ("(_) -> _") func ident(t: T) -> T {} @@ -406,8 +425,7 @@ func f20371273() { // FIXME: Should complain about not having a return type annotation in the closure. [0].map { _ in let r = (1,2).0; return r } // expected-error @-1 {{cannot invoke 'map' with an argument list of type '(@noescape (Int) throws -> _)'}} -// expected-error @-2 {{cannot convert return expression of type 'Int' to return type 'T'}} -// expected-note @-3 {{expected an argument list of type '(@noescape Int throws -> T)'}} +// expected-note @-2 {{expected an argument list of type '(@noescape Int throws -> T)'}} // Less than useful error message when using map on optional dictionary type func rdar21078316() { @@ -513,7 +531,8 @@ class B { func test(a : B) { B.f1(nil) // expected-error {{nil is not compatible with expected argument type 'AOpts'}} - a.function(42, nil) //expected-error {{nil is not compatible with expected argument type 'AOpts'}} + a.function(42, a: nil) //expected-error {{nil is not compatible with expected argument type 'AOpts'}} + a.function(42, nil) //expected-error {{missing argument label 'a:' in call}} a.f2(nil) // expected-error {{nil is not compatible with expected argument type 'AOpts'}} } @@ -656,4 +675,13 @@ func r23272739(contentType: String) { return actualAcceptableContentTypes.contains(contentType) // expected-error {{unexpected non-void return value in void function}} } +// QoI: Strings in Swift cannot be indexed directly with integer offsets +func r23641896() { + var g = "Hello World" + g.replaceRange(0...2, with: "ce") // expected-error {{String may not be indexed with 'Int', it has variable size elements}} + // expected-note @-1 {{consider using an existing high level algorithm, str.startIndex.advancedBy(n), or a projection like str.utf8}} + + _ = g[12] // expected-error {{'subscript' is unavailable: cannot subscript String with an Int, see the documentation comment for discussion}} + +} diff --git a/test/Constraints/dictionary_literal.swift b/test/Constraints/dictionary_literal.swift index 6c3b6c4c8950b..579f7ffa25196 100644 --- a/test/Constraints/dictionary_literal.swift +++ b/test/Constraints/dictionary_literal.swift @@ -59,3 +59,6 @@ var _: Dictionary? = ["foo", 1.0, 2] // expected-error {{contextua var _: Dictionary? = ["foo" : 1.0] // expected-error {{cannot convert value of type 'Double' to expected dictionary value type 'Int'}} +// QoI: Should handle [] in dictionary contexts better +var _: [Int: Int] = [] // expected-error {{use [:] to get an empty dictionary literal}} {{22-22=:}} + diff --git a/test/Constraints/function.swift b/test/Constraints/function.swift index 1ddc44c40f351..9a2a4c972dd8f 100644 --- a/test/Constraints/function.swift +++ b/test/Constraints/function.swift @@ -12,7 +12,7 @@ f1(f1(f)) f2(f) f2(1.0) -func call_lvalue(@autoclosure rhs: ()->Bool) -> Bool { +func call_lvalue(@autoclosure rhs: () -> Bool) -> Bool { return rhs() } diff --git a/test/Constraints/generic_overload.swift b/test/Constraints/generic_overload.swift index 65cb605ffc411..980382d069104 100644 --- a/test/Constraints/generic_overload.swift +++ b/test/Constraints/generic_overload.swift @@ -44,7 +44,7 @@ var f2_x1_x1b = f2(x1, x1b) i = f2_x1_x1b // Overloading of struct methods -struct StructOverload { +struct StructOverload { func f0(u: U, t: T) -> Int { return 0 } func f0(u: U, t: T) -> Double { return 0 } @@ -65,7 +65,7 @@ var so_f1_x2 = SO.f1(5, t: x2) d = so_f1_x2 // Overloading of class methods -class ClassOverloadA { +class ClassOverloadA { func f0(u: U, t: T) -> Int { return 0 } func f1(u: U, t: T) -> Double { return 0 } } diff --git a/test/Constraints/generics.swift b/test/Constraints/generics.swift index 457867539050c..b3d52333a930f 100644 --- a/test/Constraints/generics.swift +++ b/test/Constraints/generics.swift @@ -142,12 +142,12 @@ func test16078944 (lhs: T, args: T) -> Int { class r22409190ManagedBuffer { final var value: Value { get {} set {}} func withUnsafeMutablePointerToElements( - body: (UnsafeMutablePointer)->R) -> R { + body: (UnsafeMutablePointer) -> R) -> R { } } class MyArrayBuffer: r22409190ManagedBuffer { deinit { - self.withUnsafeMutablePointerToElements { elems->Void in + self.withUnsafeMutablePointerToElements { elems -> Void in elems.destroy(self.value) // expected-error {{cannot convert value of type 'UInt' to expected argument type 'Int'}} } } diff --git a/test/Constraints/invalid_constraint_lookup.swift b/test/Constraints/invalid_constraint_lookup.swift index e2eb8c60bda6c..1a57a061b69bb 100644 --- a/test/Constraints/invalid_constraint_lookup.swift +++ b/test/Constraints/invalid_constraint_lookup.swift @@ -11,7 +11,7 @@ func f(rhs: U) -> X { // expected-error {{use of undeclared type 'X'} } struct Zzz { - subscript (a: Foo) -> Zzz { // expected-error 2 {{use of undeclared type 'Foo'}} + subscript (a: Foo) -> Zzz { // expected-error {{use of undeclared type 'Foo'}} get: // expected-error {{expected '{' to start getter definition}} set: for i in value {} diff --git a/test/Constraints/invalid_logicvalue_coercion.swift b/test/Constraints/invalid_logicvalue_coercion.swift index e5418cb21eb07..426f4586071b7 100644 --- a/test/Constraints/invalid_logicvalue_coercion.swift +++ b/test/Constraints/invalid_logicvalue_coercion.swift @@ -5,5 +5,5 @@ var c = C() if c as C { // expected-error{{type 'C' does not conform to protocol 'BooleanType'}} } -if ({1} as ()->Int) { // expected-error{{type '() -> Int' does not conform to protocol 'BooleanType'}} +if ({1} as () -> Int) { // expected-error{{type '() -> Int' does not conform to protocol 'BooleanType'}} } diff --git a/test/Constraints/keyword_arguments.swift b/test/Constraints/keyword_arguments.swift index 6dbf5a7246823..ea8d6f0e3698f 100644 --- a/test/Constraints/keyword_arguments.swift +++ b/test/Constraints/keyword_arguments.swift @@ -51,7 +51,7 @@ allkeywords1(1, y: 2) // expected-error{{missing argument label 'x:' in call}} { // If keyword is reserved, make sure to quote it. rdar://problem/21392294 func reservedLabel(x: Int, `repeat`: Bool) {} -reservedLabel(1, true) // expected-error{{missing argument label 'repeat:' in call}}{{18-18=`repeat`: }} +reservedLabel(1, true) // expected-error{{missing argument label 'repeat:' in call}}{{18-18=repeat: }} // Insert missing keyword before initial backtick. rdar://problem/21392294 part 2 func reservedExpr(x: Int, y: Int) {} diff --git a/test/Constraints/lvalues.swift b/test/Constraints/lvalues.swift index 985d5ba930c19..b586296b459a8 100644 --- a/test/Constraints/lvalues.swift +++ b/test/Constraints/lvalues.swift @@ -106,7 +106,7 @@ fref().property = 0.0 f2(&fref().property) f1(&fref().property) fref().property += 0.0 -++fref().property +fref().property += 1 // settable property of a non-settable value type is non-settable: z.non_settable_x.property = 1.0 // expected-error{{cannot assign to property: 'non_settable_x' is a get-only property}} @@ -120,7 +120,7 @@ z.non_settable_reftype.property = 1.0 f2(&z.non_settable_reftype.property) f1(&z.non_settable_reftype.property) z.non_settable_reftype.property += 1.0 -++z.non_settable_reftype.property +z.non_settable_reftype.property += 1 // regressions with non-settable subscripts in value contexts _ = z[0] == 0 @@ -203,3 +203,34 @@ func testImmutableUnsafePointer(p: UnsafePointer) { p[0] = 1 // expected-error {{cannot assign through subscript: subscript is get-only}} } +// Inferring closure param type to +// inout crashes compiler +let g = { x in f0(x) } // expected-error{{passing value of type 'Int' to an inout parameter requires explicit '&'}} {{19-19=&}} + +// Crash with optional closure taking inout +func rdar17245353() { + typealias Fn = (inout Int) -> () + func getFn() -> Fn? { return nil } + + let _: (inout UInt, UInt) -> Void = { $0 += $1 } +} + +// Bugs related to closures with inout parameters +func rdar23131768() { + func f(g: (inout Int) -> Void) { var a = 1; g(&a); print(a) } + f { $0 += 1 } // Crashes compiler + + func f2(g: (inout Int) -> Void) { var a = 1; g(&a); print(a) } + f2 { $0 = $0 + 1 } // previously error: Cannot convert value of type '_ -> ()' to expected type '(inout Int) -> Void' + + func f3(g: (inout Int) -> Void) { var a = 1; g(&a); print(a) } + f3 { (inout v: Int) -> Void in v += 1 } +} + +// Swift: Compiler crash related to closures with inout parameter. +func r23331567(fn: (inout x: Int) -> Void) { + var a = 0 + fn(x: &a) +} +r23331567 { $0 += 1 } + diff --git a/test/Constraints/members_objc.swift b/test/Constraints/members_objc.swift index d99ba36587b6d..a3101048c8515 100644 --- a/test/Constraints/members_objc.swift +++ b/test/Constraints/members_objc.swift @@ -5,18 +5,18 @@ import Swift @objc protocol P2 { func bar(x: Int) + static func pub(x: Int) } func existential(p2 : P2) { - _ = p2.bar // expected-error{{partial application of method in @objc protocol is not allowed}} + _ = p2.bar + _ = P2.bar } func archetype(p2 : T) { - _ = p2.bar // expected-error{{partial application of method in @objc protocol is not allowed}} -} - -func archetypeMeta(p2 : T) { - _ = T.bar // expected-error {{partial application of method in @objc protocol is not allowed}} + _ = p2.bar + _ = T.bar + _ = T.pub } // rdar://problem/22012606 - test applications of subscript members of class-constrained protocols @@ -31,4 +31,4 @@ func archetypeMeta(p2 : T) { func test_subject_ClassConstrainedSubscript() { let list: subject_ClassConstrainedSubscript! = test_HasSubscript() list[0] -} \ No newline at end of file +} diff --git a/test/Constraints/nested_generics.swift b/test/Constraints/nested_generics.swift index 4b64acc7925ff..1f611bcf74ddb 100644 --- a/test/Constraints/nested_generics.swift +++ b/test/Constraints/nested_generics.swift @@ -34,7 +34,7 @@ struct AnyStream { func next() -> Element? { let result = (index, elements.next()) if result.1 == nil { return .None } - ++index + index += 1 return (result.0, result.1!) } } diff --git a/test/Constraints/patterns.swift b/test/Constraints/patterns.swift index d12865be34f00..c7a0c3ef6f0ef 100644 --- a/test/Constraints/patterns.swift +++ b/test/Constraints/patterns.swift @@ -167,8 +167,8 @@ default: break // FIXME: rdar://problem/23378003 // These will eventually become errors. -for (var x) in 0...100 {} // expected-error {{Use of 'var' binding here is not allowed}} {{6-9=}} -for var x in 0...100 {} // expected-error {{Use of 'var' binding here is not allowed}} {{5-9=}} +for (var x) in 0...100 {} // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{6-9=}} +for var x in 0...100 {} // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{5-9=}} for (let x) in 0...100 {} // expected-error {{'let' pattern is already in an immutable context}} @@ -176,5 +176,54 @@ var (let y) = 42 // expected-error {{'let' cannot appear nested inside another let (var z) = 42 // expected-error {{'var' cannot appear nested inside another 'var' or 'let' pattern}} +// Crash when re-typechecking EnumElementPattern. +// FIXME: This should actually type-check -- the diagnostics are bogus. But +// at least we don't crash anymore. +protocol PP { + typealias E +} + +struct A : PP { + typealias E = T +} + +extension PP { + func map(f: Self.E -> T) -> T {} +} + +enum EE { + case A + case B +} + +func good(a: A) -> Int { + return a.map { + switch $0 { + case .A: + return 1 + default: + return 2 + } + } +} +func bad(a: A) { + a.map { // expected-error {{cannot invoke 'map' with an argument list of type '((EE) -> _)'}} + // expected-note@-1 {{expected an argument list of type '(EE -> T)'}} + let _: EE = $0 + return 1 + } +} + +func ugly(a: A) { + a.map { // expected-error {{cannot invoke 'map' with an argument list of type '((EE) -> _)'}} + // expected-note@-1 {{expected an argument list of type '(EE -> T)'}} + switch $0 { + case .A: + return 1 + default: + return 2 + } + } +} diff --git a/test/Constraints/protocols.swift b/test/Constraints/protocols.swift index bdc3b3b2ce501..7351b1772708c 100644 --- a/test/Constraints/protocols.swift +++ b/test/Constraints/protocols.swift @@ -32,9 +32,9 @@ var i : Int var f : Float var b : Barable -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Conversion to and among existential types -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// f0(i) f0(f) @@ -44,9 +44,9 @@ f1(i) f1(f) // expected-error{{argument type 'Float' does not conform to expected type 'protocol'}} f1(b) // expected-error{{argument type 'Barable' does not conform to expected type 'protocol'}} -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Subtyping -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// g(f0) // okay (subtype) g(f1) // okay (exact match) @@ -93,9 +93,9 @@ let _: () -> Int = { return "" } -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Dynamic self -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// protocol Clonable { func maybeClone() -> Self? func badMaybeClone() -> Self?? diff --git a/test/Constraints/subscript.swift b/test/Constraints/subscript.swift index 9a08d6a3d38b0..0dd8afcc8af05 100644 --- a/test/Constraints/subscript.swift +++ b/test/Constraints/subscript.swift @@ -74,10 +74,18 @@ let _ = 1["1"] // expected-error {{ambiguous use of 'subscript'}} // rdar://17687826 - QoI: error message when reducing to an untyped dictionary isn't helpful let squares = [ 1, 2, 3 ].reduce([:]) { (dict, n) in // expected-error {{cannot invoke 'reduce' with an argument list of type '([_ : _], @noescape (_, Int) throws -> _)'}} // expected-note @-1 {{expected an argument list of type '(T, combine: @noescape (T, Int) throws -> T)'}} - var dict = dict // expected-error {{type of expression is ambiguous without more context}} + var dict = dict dict[n] = n * n return dict } +// QoI: Misleading error message when assigning a value from [String : AnyObject] +func r23670252(dictionary: [String : AnyObject], someObject: AnyObject) { + let color : String? + color = dictionary["color"] // expected-error {{cannot assign value of type 'AnyObject?' to type 'String?'}} + _ = color +} + + diff --git a/test/Constraints/tuple.swift b/test/Constraints/tuple.swift index e40631c459022..cbe8d05c27064 100644 --- a/test/Constraints/tuple.swift +++ b/test/Constraints/tuple.swift @@ -24,9 +24,9 @@ func f5(x: (Int, Int)) {} func f6(_: (i: Int, j: Int), k: Int = 15) {} -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Conversions and shuffles -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // Variadic functions. f4() diff --git a/test/Constraints/unconstrained_generic.swift b/test/Constraints/unconstrained_generic.swift index 27a00722fc8f3..dce7a7202c6d4 100644 --- a/test/Constraints/unconstrained_generic.swift +++ b/test/Constraints/unconstrained_generic.swift @@ -15,8 +15,9 @@ unconstrained(x) // FIXME: There's an inconsistency here in call argument matching between // rvalues and lvalues. unconstrained((x, y)) -unconstrained(x, y) // expected-error{{cannot invoke 'unconstrained' with an argument list of type '(Int, String)'}} -// expected-note @-1 {{expected an argument list of type '(T)'}} + +unconstrained(x, + y) // expected-error{{extra argument in call}} let a = 0 diff --git a/test/DebugInfo/Destructors.swift b/test/DebugInfo/Destructors.swift index 278822be9e7ea..277aae6fbdc6c 100644 --- a/test/DebugInfo/Destructors.swift +++ b/test/DebugInfo/Destructors.swift @@ -1,15 +1,9 @@ // RUN: %target-swift-frontend %s -emit-ir -g -o - | FileCheck %s -func markUsed(t: T) {} - -class Foo { +public class Foo { // CHECK: !DISubprogram(name: "deinit", linkageName: "_TFC11Destructors3FooD" // CHECK-SAME: line: [[@LINE-2]] // CHECK-SAME: isDefinition: true var x : Int64 init(x: Int64) { self.x = x } - func bar() -> (() -> ()) { return { markUsed(self.x) } } } - -var f = Foo(x: 1) -f.bar()() diff --git a/test/DebugInfo/ImportClangSubmodule.swift b/test/DebugInfo/ImportClangSubmodule.swift new file mode 100644 index 0000000000000..87c44836da25e --- /dev/null +++ b/test/DebugInfo/ImportClangSubmodule.swift @@ -0,0 +1,13 @@ +// RUN: rm -rf %t && mkdir -p %t +// REQUIRES: OS=macosx + +// RUN: %target-swift-frontend -emit-ir %s -g -o - | FileCheck %s + +// CHECK: !DIImportedEntity( +// CHECK: tag: DW_TAG_imported_module{{.*}}entity: ![[C:.*]], line: [[@LINE+1]]) +import Darwin.C + +let irrational = sqrt(2 as Double) + +// CHECK: ![[C]] = !DIModule(scope: ![[Darwin:.*]], name: "C", +// CHECK: ![[Darwin]] = !DIModule(scope: null, name: "Darwin", diff --git a/test/DebugInfo/allocstack.swift b/test/DebugInfo/allocstack.swift index 86d95255f4540..4534f3cd9efdf 100644 --- a/test/DebugInfo/allocstack.swift +++ b/test/DebugInfo/allocstack.swift @@ -6,10 +6,10 @@ import StdlibUnittest // mandatory SIL optimization passes. func main() { - // CHECK-SIL-DAG: debug_value {{.*}}let x + // CHECK-SIL-DAG: debug_value {{.*}}: $Int, let, name "x" // CHECK-DAG: DILocalVariable(name: "x" let x = 10 - // CHECK-SIL-DAG: alloc_stack {{.*}}var y + // CHECK-SIL-DAG: alloc_stack $Int, var, name "y" // CHECK-DAG: DILocalVariable(name: "y" var y = 10 // The expression x+y may become constant folded. diff --git a/test/DebugInfo/anonymous.swift b/test/DebugInfo/anonymous.swift index a0d2ae12a250b..7e94b1a7e5a13 100644 --- a/test/DebugInfo/anonymous.swift +++ b/test/DebugInfo/anonymous.swift @@ -1,22 +1,10 @@ // RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | FileCheck %s -// Don't crash when emitting debug info for anonymous variables. -// CHECK: !DILocalVariable(name: "_" +// CHECK: !DILocalVariable(name: "_0", arg: 1 +// CHECK: !DILocalVariable(name: "_1", arg: 2 +// CHECK: !DILocalVariable(name: "_2", arg: 3 +// CHECK: !DILocalVariable(name: "x4", arg: 4 -func markUsed(t: T) {} - -protocol F_ { - func successor() -> Self -} - -protocol F : F_ { - func ~> (_: Self, _: (_Distance, (Self))) -> Int64 -} - -struct _Distance {} - -func ~> (self_:I, _: (_Distance, (I))) -> Int64 { - self_.successor() - markUsed("F") - return 0 +public func fourth(_: T, _: T, _: T, x4 : T) -> T { + return x4 } diff --git a/test/DebugInfo/arg-debug_value.swift b/test/DebugInfo/arg-debug_value.swift index b93de74330360..989cd6c138669 100644 --- a/test/DebugInfo/arg-debug_value.swift +++ b/test/DebugInfo/arg-debug_value.swift @@ -5,11 +5,11 @@ var g: Int64 = 1 class Foo { - var x: Int64 + var x: Int64 // CHECK: define {{.*}}_TFC4main3FoocfT_S0_ // CHECK: entry: // CHECK-NEXT: %[[SELF:.*]] = alloca // CHECK-NEXT: store %C4main3Foo* %0, %C4main3Foo** %[[SELF]] // CHECK-NEXT: call void @llvm.dbg.declare({{.*}}%[[SELF]] - init () { x = g++ } + init () { x = g; g += 1 } } diff --git a/test/DebugInfo/argument.swift b/test/DebugInfo/argument.swift index d9cb85318472d..67dd399610f2a 100644 --- a/test/DebugInfo/argument.swift +++ b/test/DebugInfo/argument.swift @@ -64,5 +64,5 @@ func uncurry (a: Int64) (b: Int64) -> (Int64, Int64) { // CHECK: !DILocalVariable(name: "x", arg: 1,{{.*}} line: [[@LINE+2]] // CHECK: !DILocalVariable(name: "y", arg: 2,{{.*}} line: [[@LINE+1]] func tuple(x: Int64, y: (Int64, Float, String)) -> Int64 { - return x+y.0; + return x+y.0 } diff --git a/test/DebugInfo/autoclosure.swift b/test/DebugInfo/autoclosure.swift index d9c3d2f7aa59b..4ca64d7bd109d 100644 --- a/test/DebugInfo/autoclosure.swift +++ b/test/DebugInfo/autoclosure.swift @@ -17,7 +17,7 @@ infix operator &&&&& { precedence 120 } -func &&&&&(lhs: BooleanType, @autoclosure rhs: ()->BooleanType) -> Bool { +func &&&&&(lhs: BooleanType, @autoclosure rhs: () -> BooleanType) -> Bool { return lhs.boolValue ? rhs().boolValue : false } diff --git a/test/DebugInfo/byref-capture.swift b/test/DebugInfo/byref-capture.swift index b35f0471dee3f..8d97581b55c4b 100644 --- a/test/DebugInfo/byref-capture.swift +++ b/test/DebugInfo/byref-capture.swift @@ -7,10 +7,11 @@ func makeIncrementor(inc : Int64) -> () -> Int64 func inner() -> Int64 { // CHECK: call void @llvm.dbg.declare(metadata %Vs5Int64** // CHECK-SAME: metadata ![[SUM_CAPTURE:[0-9]+]], - // CHECK-SAME: metadata ![[DEREF:[0-9]+]]) - // CHECK: ![[DEREF]] = !DIExpression(DW_OP_deref) - // CHECK: ![[SUM_CAPTURE]] = !DILocalVariable(name: "sum", - // CHECK-SAME: line: [[@LINE-8]] + // CHECK-SAME: metadata ![[EMPTY:.*]]) + // CHECK: ![[EMPTY]] = !DIExpression() + // CHECK: ![[SUM_CAPTURE]] = !DILocalVariable(name: "sum", arg: 1, + // CHECK-SAME: line: [[@LINE-8]], type: !"_TtRVs5Int64" + // ^ inout type. sum += inc return sum } diff --git a/test/DebugInfo/closure.swift b/test/DebugInfo/closure.swift index e175948b8fb19..73380d0da2574 100644 --- a/test/DebugInfo/closure.swift +++ b/test/DebugInfo/closure.swift @@ -5,7 +5,7 @@ func markUsed(t: T) {} func foldl1(list: [T], _ function: (a: T, b: T) -> T) -> T { assert(list.count > 1) var accumulator = list[0] - for var i = 1; i < list.count; ++i { + for var i = 1; i < list.count; i += 1 { accumulator = function(a: accumulator, b: list[i]) } return accumulator diff --git a/test/DebugInfo/debug_value_addr.swift b/test/DebugInfo/debug_value_addr.swift index 0c373893b33f7..f4f2baa5f111c 100644 --- a/test/DebugInfo/debug_value_addr.swift +++ b/test/DebugInfo/debug_value_addr.swift @@ -5,7 +5,7 @@ // instructions. // CHECK-SIL: sil hidden @_TF16debug_value_addr4testurFxT_ -// CHECK-SIL: debug_value_addr %0 : $*T // let t +// CHECK-SIL: debug_value_addr %0 : $*T, let, name "t" // CHECK: define {{.*}}_TF16debug_value_addr4testurFxT_ // CHECK: entry: diff --git a/test/DebugInfo/enum.swift b/test/DebugInfo/enum.swift index ba9fd93ee58ae..2e709032b4781 100644 --- a/test/DebugInfo/enum.swift +++ b/test/DebugInfo/enum.swift @@ -46,13 +46,15 @@ public func foo(empty : Nothing) { } // CHECK: !DICompositeType({{.*}}name: "Rose", {{.*}}elements: ![[ELTS:[0-9]+]], // CHECK-SAME: {{.*}}identifier: "_TtGO4enum4Rosex_") -public enum Rose { +enum Rose { case MkRose(() -> A, () -> [Rose]) // CHECK: !DICompositeType({{.*}}name: "Rose", {{.*}}elements: ![[ELTS]], // CHECK-SAME: {{.*}}identifier: "_TtGO4enum4RoseQq_S0__") case IORose(() -> Rose) } +func foo(x : Rose) -> Rose { return x } + // CHECK: !DICompositeType({{.*}}name: "Tuple", {{.*}}elements: ![[ELTS:[0-9]+]], // CHECK-SAME: {{.*}}identifier: "_TtGO4enum5Tuplex_") public enum Tuple

{ @@ -61,6 +63,8 @@ public enum Tuple

{ case C(P, () -> Tuple) } +func bar(x : Tuple) -> Tuple { return x } + public enum List { indirect case Tail(List, T) case End diff --git a/test/DebugInfo/for.swift b/test/DebugInfo/for.swift index 69926ebdfcc04..5a2bf3709831b 100644 --- a/test/DebugInfo/for.swift +++ b/test/DebugInfo/for.swift @@ -2,11 +2,11 @@ // Verify that variables bound in the for statements are in distinct scopes. -for var i = 0; i < 3; ++i { +for var i = 0; i < 3; i += 1 { // CHECK: !DILocalVariable(name: "i", scope: ![[SCOPE1:[0-9]+]] // CHECK: ![[SCOPE1]] = distinct !DILexicalBlock(scope: ![[MAIN:[0-9]+]] } -for var i = 0; i < 3; ++i { +for var i = 0; i < 3; i += 1 { // CHECK: !DILocalVariable(name: "i", scope: ![[SCOPE2:[0-9]+]] // CHECK: ![[SCOPE2]] = distinct !DILexicalBlock(scope: ![[MAIN]] } diff --git a/test/DebugInfo/generic_arg3.swift b/test/DebugInfo/generic_arg3.swift new file mode 100644 index 0000000000000..df34a339a3cdd --- /dev/null +++ b/test/DebugInfo/generic_arg3.swift @@ -0,0 +1,16 @@ +// RUN: %target-swift-frontend %s -emit-ir -g -o - | FileCheck %s + +func apply(T : Type, fn: (Type) -> Type) -> Type { return fn(T) } + +public func f(value : Type) +{ + // CHECK: define {{.*}}_TFF12generic_arg31furFxT_U_FQ_Q_ + // CHECK: store %swift.opaque* %1, %swift.opaque** %[[ALLOCA:.*]], align + // CHECK: call void @llvm.dbg.declare(metadata %swift.opaque** %[[ALLOCA]], + // CHECK-SAME: metadata ![[ARG:.*]], metadata ![[EXPR:.*]]) + // No deref here: The argument is an Archetype and this implicitly indirect. + // CHECK: ![[EXPR]] = !DIExpression() + // CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1, + // CHECK-SAME: line: [[@LINE+1]], type: !"_TtQq_F12generic_arg31furFxT_") + apply(value) { arg in return arg } +} diff --git a/test/DebugInfo/generic_arg4.swift b/test/DebugInfo/generic_arg4.swift new file mode 100644 index 0000000000000..32fa448ab0d48 --- /dev/null +++ b/test/DebugInfo/generic_arg4.swift @@ -0,0 +1,16 @@ +// RUN: %target-swift-frontend %s -emit-ir -g -o - | FileCheck %s +// REQUIRES: objc_interop +public struct Q { + let x: T +} + // CHECK: define {{.*}}_TF12generic_arg43foourFGSaGVS_1Qx__T_ + // CHECK: store %[[TY:.*]]* %0, %[[TY]]** %[[ALLOCA:.*]], align + // CHECK: call void @llvm.dbg.declare(metadata %[[TY]]** %[[ALLOCA]], + // CHECK-SAME: metadata ![[ARG:.*]], metadata ![[EXPR:.*]]) + // No deref here: the array argument is passed by value. + // CHECK: ![[EXPR]] = !DIExpression() + // CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1, + // CHECK-SAME: line: [[@LINE+2]], + // CHECK-SAME: type: !"_TtGSaGV12generic_arg41QQq_FS_3foourFGSaGS0_x__T___") +public func foo(arg: [Q]) { +} diff --git a/test/DebugInfo/generic_arg5.swift b/test/DebugInfo/generic_arg5.swift new file mode 100644 index 0000000000000..eb518d64b8890 --- /dev/null +++ b/test/DebugInfo/generic_arg5.swift @@ -0,0 +1,22 @@ +// RUN: %target-swift-frontend %s -emit-ir -g -o - | FileCheck %s +public struct S +{ + let value : Type +} + +public func foo(values : [S]) +{ + // CHECK: define {{.*}}_TFF12generic_arg53foourFGSaGVS_1Sx__T_U_FGS0_Q__GSqGS0_Q___ + // CHECK: store %[[TY:.*]]* %1, %[[TY]]** %[[ALLOCA:.*]], align + // CHECK: call void @llvm.dbg.declare(metadata %[[TY]]** %[[ALLOCA]], + // CHECK-SAME: metadata ![[ARG:.*]], metadata ![[EXPR:.*]]) + // The argument is a by-ref struct and thus needs to be dereferenced. + // CHECK: ![[ARG]] = !DILocalVariable(name: "arg", arg: 1, + // CHECK-SAME: line: [[@LINE+3]], + // CHECK-SAME: type: !"_TtGV12generic_arg51SQq_FS_3foourFGSaGS0_x__T__") + // CHECK: ![[EXPR]] = !DIExpression(DW_OP_deref) + let _ = values.flatMap { arg in + return arg + } + +} diff --git a/test/DebugInfo/generic_args.swift b/test/DebugInfo/generic_args.swift index 1eeeefbc587d1..bd07b059d9fdd 100644 --- a/test/DebugInfo/generic_args.swift +++ b/test/DebugInfo/generic_args.swift @@ -3,7 +3,7 @@ func markUsed(t: T) {} protocol AProtocol { - func f() -> String; + func f() -> String } class AClass : AProtocol { func f() -> String { return "A" } @@ -45,7 +45,7 @@ struct Wrapper { } // CHECK: !DILocalVariable(name: "f", {{.*}}, line: [[@LINE+1]], type: !"_TtFQq_F12generic_args5applyu0_rFTx1fFxq__q_Qq0_F12generic_args5applyu0_rFTx1fFxq__q_") -func apply (x: T, f: (T)->(U)) -> U { +func apply (x: T, f: (T) -> (U)) -> U { return f(x) } diff --git a/test/DebugInfo/inout.swift b/test/DebugInfo/inout.swift index c301d8f0345b7..259f00187c9e8 100644 --- a/test/DebugInfo/inout.swift +++ b/test/DebugInfo/inout.swift @@ -17,7 +17,7 @@ typealias MyFloat = Float // CHECK-SAME: %[[ALLOCB]], metadata ![[B:[0-9]+]], metadata !{{[0-9]+}}) // Closure with promoted capture. -// PROMO-CHECK: define {{.*}}@_TTSf2d_i___TFF5inout13modifyFooHeapFTRVs5Int64Sf_T_U_FT_S0_ +// PROMO-CHECK: define {{.*}}@_TTSf2i___TFF5inout13modifyFooHeapFTRVs5Int64Sf_T_U_FT_S0_ // PROMO-CHECK: call void @llvm.dbg.declare(metadata {{(i32|i64)}}* % // PROMO-CHECK-SAME: metadata ![[A1:[0-9]+]], metadata ![[EMPTY_EXPR:[0-9]+]]) diff --git a/test/DebugInfo/inout2.swift b/test/DebugInfo/inout2.swift index cbf1fbcc4930a..7d8f2d99a0114 100644 --- a/test/DebugInfo/inout2.swift +++ b/test/DebugInfo/inout2.swift @@ -26,13 +26,13 @@ struct Struct { func foo(inout x: Class) { // CHECK: !DILocalVariable(name: "x", arg: 1{{.*}} line: [[@LINE-1]] markUsed(x.ivar) - x.ivar++ // Set breakpoint here + x.ivar += 1 // Set breakpoint here } func foo(inout x: Struct) { // CHECK: !DILocalVariable(name: "x", arg: 1{{.*}} line: [[@LINE-1]] markUsed(x.ivar) - x.ivar++ // Set breakpoint here + x.ivar += 1 // Set breakpoint here } func main() { diff --git a/test/DebugInfo/linetable-cleanups.swift b/test/DebugInfo/linetable-cleanups.swift index 3e6c589b687d7..1c31fc846959d 100644 --- a/test/DebugInfo/linetable-cleanups.swift +++ b/test/DebugInfo/linetable-cleanups.swift @@ -23,6 +23,12 @@ func main() { // The cleanups should share the line number with the ret stmt. // CHECK: call void {{.*}}elease({{.*}}) {{#[0-9]+}}, !dbg ![[CLEANUPS:.*]] // CHECK-NEXT: !dbg ![[CLEANUPS]] +// CHECK-NEXT: bitcast +// CHECK-NEXT: llvm.lifetime.end +// CHECK-NEXT: bitcast +// CHECK-NEXT: llvm.lifetime.end +// CHECK-NEXT: bitcast +// CHECK-NEXT: llvm.lifetime.end // CHECK-NEXT: ret void, !dbg ![[CLEANUPS]] // CHECK: ![[CLEANUPS]] = !DILocation(line: [[@LINE+1]], column: 1, } diff --git a/test/DebugInfo/linetable.swift b/test/DebugInfo/linetable.swift index 846e98881c067..e89548ac50b2b 100644 --- a/test/DebugInfo/linetable.swift +++ b/test/DebugInfo/linetable.swift @@ -2,20 +2,17 @@ // RUN: %target-swift-frontend %s -S -g -o - | FileCheck %s --check-prefix ASM-CHECK // REQUIRES: CPU=i386_or_x86_64 + import Swift func markUsed(t: T) {} class MyClass { var x : Int64 - init(input: Int64) - { - x = 2 * input - } - + init(input: Int64) { x = input } func do_something(input: Int64) -> Int64 { - return x * input; + return x * input } } @@ -29,38 +26,33 @@ func main(x: Int64) -> Void { var my_class = MyClass(input: 10) // Linetable continuity. Don't go into the closure expression. -// ASM-CHECK: .loc [[FILEID:[0-9]]] [[@LINE+1]] 5 +// ASM-CHECK: .loc [[FILEID:[0-9]]] [[@LINE+1]] 5 call_me ( -// ASM-CHECK-NOT: .loc [[FILEID]] [[@LINE+1]] 5 -// CHECK: @_TTSf2d_i_n___TFF9linetable4mainFVs5Int64T_U_FT_T_ +// ASM-CHECK-NOT: .loc [[FILEID]] [[@LINE+1]] 5 +// CHECK: @_TTSf2i_n___TFF9linetable4mainFVs5Int64T_U_FT_T_ { var result = my_class.do_something(x) markUsed(result) // CHECK: call {{.*}} @swift_release {{.*}} // CHECK: call {{.*}} @swift_release {{.*}}, !dbg ![[CLOSURE_END:.*]] +// CHECK-NEXT: bitcast +// CHECK-NEXT: llvm.lifetime.end // CHECK-NEXT: ret void, !dbg ![[CLOSURE_END]] // CHECK: ![[CLOSURE_END]] = !DILocation(line: [[@LINE+1]], } ) -// ASM-CHECK: .loc [[FILEID]] [[@LINE+1]] 5 - call_me ( - { - markUsed(x) - } - ) - // The swift_releases at the end should not jump to the point where // that memory was retained/allocated and also not to line 0. -// ASM-CHECK-NOT: .loc [[FILEID]] 0 0 -// ASM-CHECK: .loc [[FILEID]] [[@LINE+2]] 1 +// ASM-CHECK-NOT: .loc [[FILEID]] 0 0 +// ASM-CHECK: .loc [[FILEID]] [[@LINE+2]] 1 // ASM-CHECK: ret } -// ASM-CHECK:_TTSf2d_i_n___TFF9linetable4mainFVs5Int64T_U_FT_T_: +// ASM-CHECK: {{^_?_TTSf2i_n___TFF9linetable4mainFVs5Int64T_U_FT_T_:}} // ASM-CHECK-NOT: retq // The end-of-prologue should have a valid location (0 is ok, too). -// ASM-CHECK: .loc [[FILEID]] 0 {{[0-9]+}} prologue_end -// ASM-CHECK: .loc [[FILEID]] 37 {{[0-9]+}} +// ASM-CHECK: .loc [[FILEID]] 0 {{[0-9]+}} prologue_end +// ASM-CHECK: .loc [[FILEID]] 34 {{[0-9]+}} main(30) diff --git a/test/DebugInfo/patternmatching.swift b/test/DebugInfo/patternmatching.swift index 920bd8915dcbd..a9dc292f8731d 100644 --- a/test/DebugInfo/patternmatching.swift +++ b/test/DebugInfo/patternmatching.swift @@ -8,7 +8,7 @@ func markUsed(t: T) {} func classifyPoint2(p: (Double, Double)) { func return_same (input : Double) -> Double { var input = input - return input; + return input } switch p { diff --git a/test/DebugInfo/protocol.swift b/test/DebugInfo/protocol.swift index 2633470156f42..2134915a91ef5 100644 --- a/test/DebugInfo/protocol.swift +++ b/test/DebugInfo/protocol.swift @@ -9,8 +9,8 @@ class Point : PointUtils { var x : Float var y : Float init (_x : Float, _y : Float) { - x = _x; - y = _y; + x = _x + y = _y } func distanceFromOrigin() -> Float { diff --git a/test/DebugInfo/protocolarg.swift b/test/DebugInfo/protocolarg.swift index 0da94ab48fcfe..9920a82bf0b28 100644 --- a/test/DebugInfo/protocolarg.swift +++ b/test/DebugInfo/protocolarg.swift @@ -2,27 +2,27 @@ func markUsed(t: T) {} -// FIXME: Should be DW_TAG_interface_type -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "IGiveOutInts" -// CHECK-SAME: identifier: [[PT:"[^"]+"]] -protocol IGiveOutInts { +public protocol IGiveOutInts { func callMe() -> Int64 } -class SomeImplementor : IGiveOutInts { - init() {} - func callMe() -> Int64 { return 1 } -} +// CHECK: define {{.*}}@_TF11protocolarg16printSomeNumbersFPS_12IGiveOutInts_T_ +// CHECK: @llvm.dbg.declare(metadata %P11protocolarg12IGiveOutInts_* % +// CHECK-SAME: metadata ![[VAR:.*]], metadata ![[EMPTY:.*]]) +// CHECK: @llvm.dbg.declare(metadata %P11protocolarg12IGiveOutInts_** % +// CHECK-SAME: metadata ![[ARG:.*]], metadata ![[DEREF:.*]]) + +// FIXME: Should be DW_TAG_interface_type +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "IGiveOutInts" +// CHECK-SAME: identifier: [[PT:"[^"]+"]] -func printSomeNumbers(gen: IGiveOutInts) { +public func printSomeNumbers(gen: IGiveOutInts) { var gen = gen - // CHECK: !DILocalVariable(name: "gen", scope{{.*}} line: [[@LINE-1]] - // CHECK: !DILocalVariable(name: "gen", arg: 1{{.*}} line: [[@LINE-3]] - // CHECK-SAME: type: ![[PT]] + // CHECK: ![[EMPTY]] = !DIExpression() + // CHECK: ![[VAR]] = !DILocalVariable(name: "gen", {{.*}} line: [[@LINE-2]] + // CHECK: ![[ARG]] = !DILocalVariable(name: "gen", arg: 1, + // CHECK-SAME: line: [[@LINE-5]], type: ![[PT]] + // CHECK: ![[DEREF]] = !DIExpression(DW_OP_deref) markUsed(gen.callMe()) } -var i1 : IGiveOutInts = SomeImplementor() - -printSomeNumbers(i1) - diff --git a/test/DebugInfo/return.swift b/test/DebugInfo/return.swift index d59aecbeb6bf7..1554959dd5898 100644 --- a/test/DebugInfo/return.swift +++ b/test/DebugInfo/return.swift @@ -7,15 +7,15 @@ class X { // CHECK: define {{.*}}ifelseexpr public func ifelseexpr() -> Int64 { - var x = X(i:0); + var x = X(i:0) // CHECK: [[META:%.*]] = call %swift.type* @_TMaC6return1X() // CHECK: [[X:%.*]] = call %C6return1X* @_TFC6return1XCfT1iVs5Int64_S0_( // CHECK-SAME: i64 0, %swift.type* [[META]]) // CHECK: @swift_release to void (%C6return1X*)*)(%C6return1X* [[X]]) if true { - x.x++; + x.x += 1 } else { - x.x--; + x.x -= 1 } // CHECK: @swift_release to void (%C6return1X*)*)(%C6return1X* [[X]]) // CHECK: @swift_release to void (%C6return1X*)*)(%C6return1X* [[X]]) @@ -23,6 +23,6 @@ public func ifelseexpr() -> Int64 { // The ret instruction should be in the same scope as the return expression. // CHECK: ret{{.*}}, !dbg ![[RELEASE]] - return x.x; // CHECK: ![[RELEASE]] = !DILocation(line: [[@LINE]], column: 3 + return x.x // CHECK: ![[RELEASE]] = !DILocation(line: [[@LINE]], column: 3 } diff --git a/test/DebugInfo/returnlocation.swift b/test/DebugInfo/returnlocation.swift index 44e856410b72e..b7f62d6f580bb 100644 --- a/test/DebugInfo/returnlocation.swift +++ b/test/DebugInfo/returnlocation.swift @@ -13,7 +13,7 @@ import Foundation public func none(inout a: Int64) { // CHECK_NONE: call void @llvm.dbg{{.*}}, !dbg // CHECK_NONE: !dbg ![[NONE_INIT:.*]] - a -= 2; + a -= 2 // CHECK_NONE: ret {{.*}}, !dbg ![[NONE_RET:.*]] // CHECK_NONE: ![[NONE_INIT]] = !DILocation(line: [[@LINE-2]], column: // CHECK_NONE: ![[NONE_RET]] = !DILocation(line: [[@LINE+1]], column: 1, @@ -28,7 +28,7 @@ public func empty(inout a: Int64) { return } - a -= 2; + a -= 2 // CHECK-DAG_EMPTY: br {{.*}}, !dbg ![[EMPTY_RET2:.*]] // CHECK-DAG_EMPTY_RET2: ![[EMPTY_RET]] = !DILocation(line: [[@LINE+1]], column: 3, return @@ -40,10 +40,10 @@ public func empty(inout a: Int64) { // CHECK_EMPTY_NONE: define {{.*}}empty_none public func empty_none(inout a: Int64) { if a > 24 { - return; + return } - a -= 2; + a -= 2 // CHECK_EMPTY_NONE: ret {{.*}}, !dbg ![[EMPTY_NONE_RET:.*]] // CHECK_EMPTY_NONE: ![[EMPTY_NONE_RET]] = !DILocation(line: [[@LINE+1]], column: 1, } @@ -52,7 +52,7 @@ public func empty_none(inout a: Int64) { // CHECK_SIMPLE_RET: define {{.*}}simple public func simple(a: Int64) -> Int64 { if a > 24 { - return 0; + return 0 } return 1 // CHECK_SIMPLE_RET: ret i{{.*}}, !dbg ![[SIMPLE_RET:.*]] @@ -108,7 +108,7 @@ public func cleanup_none(inout a: NSString) { // CHECK_CLEANUP_EMPTY: define {{.*}}cleanup_empty public func cleanup_empty(inout a: NSString) { if a.length > 24 { - return; + return } a = "empty" @@ -121,7 +121,7 @@ public func cleanup_empty(inout a: NSString) { // CHECK_CLEANUP_EMPTY_NONE: define {{.*}}cleanup_empty_none public func cleanup_empty_none(inout a: NSString) { if a.length > 24 { - return; + return } a = "empty" diff --git a/test/DebugInfo/simple.sil b/test/DebugInfo/simple.sil index 04effb922db91..c5fdc1785af98 100644 --- a/test/DebugInfo/simple.sil +++ b/test/DebugInfo/simple.sil @@ -7,7 +7,7 @@ import Swift sil @square : $@convention(thin) (Int32) -> Int32 { bb0(%0 : $Int32): - debug_value %0 : $Int32 // let x // id: %1 + debug_value %0 : $Int32, let, name "x" // id: %1 %3 = struct_extract %0 : $Int32, #Int32._value // user: %6 %4 = struct_extract %0 : $Int32, #Int32._value // user: %6 %5 = integer_literal $Builtin.Int1, -1 // user: %6 diff --git a/test/DebugInfo/specialization.swift b/test/DebugInfo/specialization.swift new file mode 100644 index 0000000000000..42ae73e19766a --- /dev/null +++ b/test/DebugInfo/specialization.swift @@ -0,0 +1,18 @@ +// RUN: %target-swift-frontend -O %s -disable-llvm-optzns -emit-sil -g -o - | FileCheck %s + +// CHECK: sil shared [noinline] @_TTSg5SiSis21IntegerArithmeticTypes__ +// CHECK-SAME: _TF14specialization3sumuRxs21IntegerArithmeticTyperFTxx_x +// CHECK-SAME: $@convention(thin) (@out Int, @in Int, @in Int) -> () { +// CHECK: bb0(%0 : $*Int, %1 : $*Int, %2 : $*Int): +// CHECK: debug_value_addr %1 : $*Int, let, name "i", argno 1 +// CHECK: debug_value_addr %2 : $*Int, let, name "j", argno 2 + +@inline(never) +public func sum(i : T, _ j : T) -> T { + let result = i + j + return result +} + +public func inc(inout i : Int) { + i = sum(i, 1) +} diff --git a/test/DebugInfo/trap-optimized.swift b/test/DebugInfo/trap-optimized.swift index a05a38d904b6c..22663aaf96e1a 100644 --- a/test/DebugInfo/trap-optimized.swift +++ b/test/DebugInfo/trap-optimized.swift @@ -1,13 +1,14 @@ // RUN: %target-swift-frontend -O -primary-file %s -emit-ir -g -o - | FileCheck %s - +import StdlibUnittest // CHECK-LABEL: define{{.*}}2fn -func fn() { - print("two") -// CHECK-DAG: ![[LOC:.*]] = !DILocation(line: [[@LINE+1]], column: 11, - print(0 - UInt(Process.arguments.count)) -// CHECK-DAG: ![[LOC2:.*]] = !DILocation(line: [[@LINE+1]], column: 11, - print(1 - UInt(Process.arguments.count)) - print("three") +public var i : UInt32 = 1 +public func fn() { + _blackHole(i) +// CHECK-DAG: ![[LOC:.*]] = !DILocation(line: [[@LINE+1]], column: 16, + _blackHole(0 - i) +// CHECK-DAG: ![[LOC2:.*]] = !DILocation(line: [[@LINE+1]], column: 16, + _blackHole(0 - i) + _blackHole(i) } // CHECK-DAG: call void @llvm.trap(), !dbg ![[LOC]] diff --git a/test/DebugInfo/typearg.swift b/test/DebugInfo/typearg.swift index d6a6ea4d1f7e3..e533a250098ee 100644 --- a/test/DebugInfo/typearg.swift +++ b/test/DebugInfo/typearg.swift @@ -1,7 +1,7 @@ // RUN: %target-swift-frontend %s -emit-ir -g -o - | FileCheck %s protocol AProtocol { - func f() -> String; + func f() -> String } class AClass : AProtocol { func f() -> String { return "A" } diff --git a/test/DebugInfo/value-update.sil b/test/DebugInfo/value-update.sil new file mode 100644 index 0000000000000..af6b1cf34475a --- /dev/null +++ b/test/DebugInfo/value-update.sil @@ -0,0 +1,47 @@ +// RUN: %target-swift-frontend %s -emit-ir -module-name test -g -o - | FileCheck %s +// REQUIRES: CPU=x86_64 +sil_stage canonical + +import Builtin +import Swift +import SwiftShims + +// test.foo () -> () +sil @_TF4test3fooFT_T_ : $@convention(thin) () -> () { +bb0: + %1 = integer_literal $Builtin.Int64, 23 + %2 = struct $Int (%1 : $Builtin.Int64) + debug_value %2 : $Int, var, name "v" + // CHECK: store i64 23, i64* %[[ALLOCA:.*]], align 8, !dbg + // CHECK: dbg.declare + // function_ref StdlibUnittest._blackHole (A) -> () + %5 = function_ref @_TF14StdlibUnittest10_blackHoleurFxT_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %8 + %6 = tuple () + %7 = alloc_stack $() // users: %8, %9 + %8 = apply %5<()>(%7) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %7 : $*() // id: %9 + + // CHECK: store i64 42, i64* %[[ALLOCA]], align 8, !dbg + // CHECK-NOT: dbg.declare + %9 = integer_literal $Builtin.Int64, 42 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %11 + debug_value %10 : $Int, var, name "v" + + // function_ref StdlibUnittest._blackHole (A) -> () + %13 = function_ref @_TF14StdlibUnittest10_blackHoleurFxT_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %16 + %14 = tuple () + %15 = alloc_stack $() // users: %16, %17 + %16 = apply %13<()>(%15) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %15 : $*() // id: %17 + + %18 = tuple () // user: %21 + return %18 : $() // id: %21 + // CHECK: {{^}}} +} + +// Swift.Int.init (_builtinIntegerLiteral : Builtin.Int2048) -> Swift.Int +sil [transparent] [fragile] @_TFSiCfT22_builtinIntegerLiteralBi2048__Si : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int + +// StdlibUnittest._blackHole (A) -> () +sil @_TF14StdlibUnittest10_blackHoleurFxT_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + diff --git a/test/DebugInfo/variables.swift b/test/DebugInfo/variables.swift index 760d07fb041bf..873194f45490a 100644 --- a/test/DebugInfo/variables.swift +++ b/test/DebugInfo/variables.swift @@ -11,17 +11,17 @@ // CHECK-DAG: ![[TLC:.*]] = !DIModule({{.*}}, name: "variables" // Global variables. -var glob_i8: Int8 = 8; +var glob_i8: Int8 = 8 // CHECK-DAG: !DIGlobalVariable(name: "glob_i8",{{.*}} scope: ![[TLC]],{{.*}} line: [[@LINE-1]],{{.*}} type: ![[I8:[^,]+]] -var glob_i16: Int16 = 16; +var glob_i16: Int16 = 16 // CHECK-DAG: !DIGlobalVariable(name: "glob_i16",{{.*}} scope: ![[TLC]],{{.*}} line: [[@LINE-1]],{{.*}} type: ![[I16:[^,]+]] -var glob_i32: Int32 = 32; +var glob_i32: Int32 = 32 // CHECK-DAG: !DIGlobalVariable(name: "glob_i32",{{.*}} scope: ![[TLC]],{{.*}} line: [[@LINE-1]],{{.*}} type: ![[I32:[^,]+]] -var glob_i64: Int64 = 64; +var glob_i64: Int64 = 64 // CHECK-DAG: !DIGlobalVariable(name: "glob_i64",{{.*}} scope: ![[TLC]],{{.*}} line: [[@LINE-1]],{{.*}} type: ![[I64:[^,]+]] -var glob_f: Float = 2.89; +var glob_f: Float = 2.89 // CHECK-DAG: !DIGlobalVariable(name: "glob_f",{{.*}} scope: ![[TLC]],{{.*}} line: [[@LINE-1]],{{.*}} type: ![[F:[^,]+]] -var glob_d: Double = 3.14; +var glob_d: Double = 3.14 // CHECK-DAG: !DIGlobalVariable(name: "glob_d",{{.*}} scope: ![[TLC]],{{.*}} line: [[@LINE-1]],{{.*}} type: ![[D:[^,]+]] var glob_b: Bool = true // CHECK-DAG: !DIGlobalVariable(name: "glob_b",{{.*}} scope: ![[TLC]],{{.*}} line: [[@LINE-1]],{{.*}} type: ![[B:[^,]+]] @@ -47,10 +47,10 @@ var unused: Int32 = -1 func foo(dt: Float) -> Float { // CHECK-DAG: call void @llvm.dbg.declare // CHECK-DAG: !DILocalVariable(name: "f" - var f: Float = 9.78; + var f: Float = 9.78 // CHECK-DAG: !DILocalVariable(name: "r" - var r: Float = f*dt; - return r; + var r: Float = f*dt + return r } var g = foo(1.0); diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt index a1ce4a0c8dd51..f6e38b413af4a 100644 --- a/test/Demangle/Inputs/manglings.txt +++ b/test/Demangle/Inputs/manglings.txt @@ -100,8 +100,10 @@ _TWPC3foo3barS_8barrables ---> protocol witness table for foo.bar : foo.barrable _TWaC3foo3barS_8barrableS_ ---> protocol witness table accessor for foo.bar : foo.barrable in foo _TWlC3foo3barS0_S_8barrableS_ ---> lazy protocol witness table accessor for type foo.bar and conformance foo.bar : foo.barrable in foo _TWLC3foo3barS0_S_8barrableS_ ---> lazy protocol witness table cache variable for type foo.bar and conformance foo.bar : foo.barrable in foo -_TWDC3foo3barS_8barrableS_ ---> dependent protocol witness table generator for foo.bar : foo.barrable in foo -_TWdC3foo3barS_8barrableS_ ---> dependent protocol witness table template for foo.bar : foo.barrable in foo +_TWGC3foo3barS_8barrableS_ ---> generic protocol witness table for foo.bar : foo.barrable in foo +_TWIC3foo3barS_8barrableS_ ---> instantiation function for generic protocol witness table for foo.bar : foo.barrable in foo +_TWtC3foo3barS_8barrableS_4fred ---> associated type metadata accessor for fred in foo.bar : foo.barrable in foo +_TWTC3foo3barS_8barrableS_4fredS_6thomas ---> associated type witness table accessor for fred : foo.thomas in foo.bar : foo.barrable in foo _TFSCg5greenVSC5Color ---> __C.green.getter : __C.Color _TIF1t1fFT1iSi1sSS_T_A_ ---> t.(f (i : Swift.Int, s : Swift.String) -> ()).(default argument 0) _TIF1t1fFT1iSi1sSS_T_A0_ ---> t.(f (i : Swift.Int, s : Swift.String) -> ()).(default argument 1) @@ -191,8 +193,8 @@ _TTSf0gs___TFVs11_StringCore15_invariantCheckfT_T_ ---> function signature speci _TTSf2g___TTSf2s_d___TFVs11_StringCoreCfVs13_StringBufferS_ ---> function signature specialization of function signature specialization of Swift._StringCore.init (Swift._StringBuffer) -> Swift._StringCore _TTSf2dg___TTSf2s_d___TFVs11_StringCoreCfVs13_StringBufferS_ ---> function signature specialization of function signature specialization of Swift._StringCore.init (Swift._StringBuffer) -> Swift._StringCore _TTSf2dgs___TTSf2s_d___TFVs11_StringCoreCfVs13_StringBufferS_ ---> function signature specialization of function signature specialization of Swift._StringCore.init (Swift._StringBuffer) -> Swift._StringCore -_TTSf3d_i_d_i_d_i___TFVs11_StringCoreCfVs13_StringBufferS_ ---> function signature specialization of Swift._StringCore.init (Swift._StringBuffer) -> Swift._StringCore -_TTSf3d_i_n_i_d_i___TFVs11_StringCoreCfVs13_StringBufferS_ ---> function signature specialization of Swift._StringCore.init (Swift._StringBuffer) -> Swift._StringCore +_TTSf3d_i_d_i_d_i___TFVs11_StringCoreCfVs13_StringBufferS_ ---> function signature specialization of Swift._StringCore.init (Swift._StringBuffer) -> Swift._StringCore +_TTSf3d_i_n_i_d_i___TFVs11_StringCoreCfVs13_StringBufferS_ ---> function signature specialization of Swift._StringCore.init (Swift._StringBuffer) -> Swift._StringCore _TFIZvV8mangling10HasVarInit5stateSbiu_KT_Sb ---> static mangling.HasVarInit.(state : Swift.Bool).(variable initialization expression).(implicit closure #1) _TFFV23interface_type_mangling18GenericTypeContext23closureInGenericContexturFqd__T_L_3fooFTQd__Q__T_ ---> interface_type_mangling.GenericTypeContext.(closureInGenericContext (A1) -> ()).(foo #1) (A1, A) -> () _TFFV23interface_type_mangling18GenericTypeContextg31closureInGenericPropertyContextxL_3fooFT_Q_ ---> interface_type_mangling.GenericTypeContext.(closureInGenericPropertyContext.getter : A).(foo #1) () -> A diff --git a/test/Demangle/Inputs/simplified-manglings.txt b/test/Demangle/Inputs/simplified-manglings.txt index 19b59ab33881c..5d9aa6e52cd82 100644 --- a/test/Demangle/Inputs/simplified-manglings.txt +++ b/test/Demangle/Inputs/simplified-manglings.txt @@ -93,8 +93,8 @@ _TWPC3foo3barS_8barrables ---> protocol witness table for bar _TWaC3foo3barS_8barrableS_ ---> protocol witness table accessor for bar _TWlC3foo3barS0_S_8barrableS_ ---> lazy protocol witness table accessor for type bar and conformance bar _TWLC3foo3barS0_S_8barrableS_ ---> lazy protocol witness table cache variable for type bar and conformance bar -_TWDC3foo3barS_8barrableS_ ---> dependent protocol witness table generator for bar -_TWdC3foo3barS_8barrableS_ ---> dependent protocol witness table template for bar +_TWGC3foo3barS_8barrableS_ ---> generic protocol witness table for bar +_TWIC3foo3barS_8barrableS_ ---> instantiation function for generic protocol witness table for bar _TFSCg5greenVSC5Color ---> green.getter _TIF1t1fFT1iSi1sSS_T_A_ ---> (f(i : Int, s : String) -> ()).(default argument 0) _TIF1t1fFT1iSi1sSS_T_A0_ ---> (f(i : Int, s : String) -> ()).(default argument 1) diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/main.swift b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/main.swift new file mode 100644 index 0000000000000..41c4459572e7d --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/main.swift @@ -0,0 +1,4 @@ +# Dependencies after compilation: +depends-nominal: [x, a, z] +depends-member: [[x, x], [a, a], [z, z]] +provides-nominal: [b] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/main.swiftdeps b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/main.swiftdeps new file mode 100644 index 0000000000000..daf4f75424422 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/main.swiftdeps @@ -0,0 +1,4 @@ +# Dependencies before compilation: +depends-nominal: [x, a] +depends-member: [[x, x], !private [a, a]] +provides-nominal: [b] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/other.swift b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/other.swift new file mode 100644 index 0000000000000..417f71c53c111 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/other.swift @@ -0,0 +1,2 @@ +# Dependencies after compilation: +provides-member: [[a, a]] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/other.swiftdeps b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/other.swiftdeps new file mode 100644 index 0000000000000..8920d930bbc99 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/other.swiftdeps @@ -0,0 +1,2 @@ +# Dependencies before compilation: +provides-member: [[a, a]] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/output.json b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/output.json new file mode 100644 index 0000000000000..78134f1ab01d1 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/output.json @@ -0,0 +1,17 @@ +{ + "./main.swift": { + "object": "./main.o", + "swift-dependencies": "./main.swiftdeps" + }, + "./other.swift": { + "object": "./other.o", + "swift-dependencies": "./other.swiftdeps" + }, + "./yet-another.swift": { + "object": "./yet-another.o", + "swift-dependencies": "./yet-another.swiftdeps" + }, + "": { + "swift-dependencies": "./main~buildrecord.swiftdeps" + } +} diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/yet-another.swift b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/yet-another.swift new file mode 100644 index 0000000000000..f4d83dcc59888 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/yet-another.swift @@ -0,0 +1,2 @@ +# Dependencies after compilation: +depends-nominal: [b] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/yet-another.swiftdeps b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/yet-another.swiftdeps new file mode 100644 index 0000000000000..813bf188859ef --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple-nominal-members/yet-another.swiftdeps @@ -0,0 +1,2 @@ +# Dependencies before compilation: +depends-nominal: [b] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple/main.swift b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/main.swift new file mode 100644 index 0000000000000..63f1b24bea3d6 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/main.swift @@ -0,0 +1,3 @@ +# Dependencies after compilation: +depends-top-level: [x, a, z] +provides-nominal: [b] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple/main.swiftdeps b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/main.swiftdeps new file mode 100644 index 0000000000000..698632a11e988 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/main.swiftdeps @@ -0,0 +1,3 @@ +# Dependencies before compilation: +depends-top-level: [x, !private a] +provides-nominal: [b] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple/other.swift b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/other.swift new file mode 100644 index 0000000000000..7e7daa298c540 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/other.swift @@ -0,0 +1,2 @@ +# Dependencies after compilation: +provides-top-level: [a] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple/other.swiftdeps b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/other.swiftdeps new file mode 100644 index 0000000000000..37adc17c77e7c --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/other.swiftdeps @@ -0,0 +1,2 @@ +# Dependencies before compilation: +provides-top-level: [a] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple/output.json b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/output.json new file mode 100644 index 0000000000000..78134f1ab01d1 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/output.json @@ -0,0 +1,17 @@ +{ + "./main.swift": { + "object": "./main.o", + "swift-dependencies": "./main.swiftdeps" + }, + "./other.swift": { + "object": "./other.o", + "swift-dependencies": "./other.swiftdeps" + }, + "./yet-another.swift": { + "object": "./yet-another.o", + "swift-dependencies": "./yet-another.swiftdeps" + }, + "": { + "swift-dependencies": "./main~buildrecord.swiftdeps" + } +} diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple/yet-another.swift b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/yet-another.swift new file mode 100644 index 0000000000000..f4d83dcc59888 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/yet-another.swift @@ -0,0 +1,2 @@ +# Dependencies after compilation: +depends-nominal: [b] diff --git a/test/Driver/Dependencies/Inputs/chained-private-after-multiple/yet-another.swiftdeps b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/yet-another.swiftdeps new file mode 100644 index 0000000000000..813bf188859ef --- /dev/null +++ b/test/Driver/Dependencies/Inputs/chained-private-after-multiple/yet-another.swiftdeps @@ -0,0 +1,2 @@ +# Dependencies before compilation: +depends-nominal: [b] diff --git a/test/Driver/Dependencies/Inputs/fail.py b/test/Driver/Dependencies/Inputs/fail.py index 95c72f8c19a10..4384c6de14254 100755 --- a/test/Driver/Dependencies/Inputs/fail.py +++ b/test/Driver/Dependencies/Inputs/fail.py @@ -1,3 +1,12 @@ #!/usr/bin/env python +# fail.py - Just exits with an error code -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors exit(1) diff --git a/test/Driver/Dependencies/Inputs/fake-build-for-bitcode.py b/test/Driver/Dependencies/Inputs/fake-build-for-bitcode.py index 24855b144601b..5e14ed8d148ff 100755 --- a/test/Driver/Dependencies/Inputs/fake-build-for-bitcode.py +++ b/test/Driver/Dependencies/Inputs/fake-build-for-bitcode.py @@ -1,10 +1,24 @@ #!/usr/bin/env python - +# fake-build-for-bitcode.py - Fake build with -embed-bitcode -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# # Emulates the frontend of an -embed-bitcode job. That means we have to handle # -emit-bc and -c actions. +# +# ---------------------------------------------------------------------------- + +from __future__ import print_function import os -import shutil import sys assert sys.argv[1] == '-frontend' @@ -18,8 +32,8 @@ os.utime(outputFile, None) if '-emit-bc' in sys.argv: - print "Handled", os.path.basename(primaryFile) + print("Handled", os.path.basename(primaryFile)) elif '-c' in sys.argv: - print "Produced", os.path.basename(outputFile) + print("Produced", os.path.basename(outputFile)) else: assert False, "unknown action" diff --git a/test/Driver/Dependencies/Inputs/fake-build-whole-module.py b/test/Driver/Dependencies/Inputs/fake-build-whole-module.py index 3b176a2846ee4..d84348f98804a 100755 --- a/test/Driver/Dependencies/Inputs/fake-build-whole-module.py +++ b/test/Driver/Dependencies/Inputs/fake-build-whole-module.py @@ -1,9 +1,23 @@ #!/usr/bin/env python - +# fake-build-for-whole-module.py - Optimized fake build -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# # Emulates the frontend of a -whole-module-optimization compilation. +# +# ---------------------------------------------------------------------------- + +from __future__ import print_function import os -import shutil import sys assert sys.argv[1] == '-frontend' @@ -16,4 +30,4 @@ with open(outputFile, 'a'): os.utime(outputFile, None) -print "Produced", os.path.basename(outputFile) +print("Produced", os.path.basename(outputFile)) diff --git a/test/Driver/Dependencies/Inputs/modify-non-primary-files.py b/test/Driver/Dependencies/Inputs/modify-non-primary-files.py index a131a72067f43..8ff578e971111 100755 --- a/test/Driver/Dependencies/Inputs/modify-non-primary-files.py +++ b/test/Driver/Dependencies/Inputs/modify-non-primary-files.py @@ -1,10 +1,24 @@ #!/usr/bin/env python - +# modify-non-primary-files.py - Fake build while modifying files -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# # modify-non-primary-files.py simulates a build where the user is modifying the # source files during compilation. +# +# ---------------------------------------------------------------------------- + +from __future__ import print_function import os -import shutil import sys assert sys.argv[1] == '-frontend' @@ -32,6 +46,6 @@ os.utime(outputFile, None) if primaryFile: - print "Handled", os.path.basename(primaryFile) + print("Handled", os.path.basename(primaryFile)) else: - print "Produced", os.path.basename(outputFile) + print("Produced", os.path.basename(outputFile)) diff --git a/test/Driver/Dependencies/Inputs/touch.py b/test/Driver/Dependencies/Inputs/touch.py new file mode 100755 index 0000000000000..dfca7957980c9 --- /dev/null +++ b/test/Driver/Dependencies/Inputs/touch.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# touch.py - /bin/touch that writes the LLVM epoch -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# Like /bin/touch, but takes a time using the LLVM epoch. +# +# ---------------------------------------------------------------------------- + +import os +import sys + +assert len(sys.argv) >= 2 +timeVal = int(sys.argv[1]) + +timeVal += 946684800 # offset between Unix and LLVM epochs + +# Update the output file mtime, or create it if necessary. +# From http://stackoverflow.com/a/1160227. +for outputFile in sys.argv[1:]: + with open(outputFile, 'a'): + os.utime(outputFile, (timeVal, timeVal)) diff --git a/test/Driver/Dependencies/Inputs/update-dependencies-bad.py b/test/Driver/Dependencies/Inputs/update-dependencies-bad.py index 1c2c9f8d98f5e..5386eea64b6f0 100755 --- a/test/Driver/Dependencies/Inputs/update-dependencies-bad.py +++ b/test/Driver/Dependencies/Inputs/update-dependencies-bad.py @@ -1,7 +1,22 @@ #!/usr/bin/env python - +# update-dependencies-bad.py - Fails on bad.swift -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# # Fails if the input file is named "bad.swift"; otherwise dispatches to # update-dependencies.py. +# +# ---------------------------------------------------------------------------- + +from __future__ import print_function import os import sys @@ -11,7 +26,7 @@ primaryFile = sys.argv[sys.argv.index('-primary-file') + 1] if os.path.basename(primaryFile) == 'bad.swift': - print "Handled", os.path.basename(primaryFile) + print("Handled", os.path.basename(primaryFile)) exit(1) dir = os.path.dirname(os.path.abspath(__file__)) diff --git a/test/Driver/Dependencies/Inputs/update-dependencies.py b/test/Driver/Dependencies/Inputs/update-dependencies.py index aac77698ff47c..d8768c7fa66fd 100755 --- a/test/Driver/Dependencies/Inputs/update-dependencies.py +++ b/test/Driver/Dependencies/Inputs/update-dependencies.py @@ -1,7 +1,18 @@ #!/usr/bin/env python - -# update-dependencies.py simulates a Swift compilation for the purposes of -# dependency analysis. That means it has two tasks: +# update-dependencies.py - Fake build for dependency analysis -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# Simulates a Swift compilation for the purposes of dependency analysis. +# That means this has two tasks: # # 1. Update the main output of the compilation job. # 2. Update the associated dependencies file, in case anything changed. @@ -13,6 +24,10 @@ # the old dependencies (if present). # # If invoked in non-primary-file mode, it only creates the output file. +# +# ---------------------------------------------------------------------------- + +from __future__ import print_function import os import shutil @@ -37,6 +52,6 @@ os.utime(outputFile, None) if primaryFile: - print "Handled", os.path.basename(primaryFile) + print("Handled", os.path.basename(primaryFile)) else: - print "Produced", os.path.basename(outputFile) + print("Produced", os.path.basename(outputFile)) diff --git a/test/Driver/Dependencies/bindings-build-record.swift b/test/Driver/Dependencies/bindings-build-record.swift index 6b64ce0362943..c4d6ced29fbff 100644 --- a/test/Driver/Dependencies/bindings-build-record.swift +++ b/test/Driver/Dependencies/bindings-build-record.swift @@ -1,8 +1,5 @@ -// rdar://problem/21515673 -// REQUIRES: OS=macosx - // RUN: rm -rf %t && cp -r %S/Inputs/bindings-build-record/ %t -// RUN: touch -t 201401240005 %t/* +// RUN: %S/Inputs/touch.py 443865900 %t/* // RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=MUST-EXEC @@ -32,13 +29,13 @@ // FILE-ADDED: inputs: ["./added.swift"], output: {{[{].*[}]}}, condition: newly-added{{$}} -// RUN: touch -t 201401240006 %t/main.swift +// RUN: %S/Inputs/touch.py 443865960 %t/main.swift // RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=BUILD-RECORD-PLUS-CHANGE // BUILD-RECORD-PLUS-CHANGE: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading // BUILD-RECORD-PLUS-CHANGE: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading{{$}} // BUILD-RECORD-PLUS-CHANGE: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}} -// RUN: touch -t 201401240005 %t/main.swift +// RUN: %S/Inputs/touch.py 443865900 %t/* // RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift -incremental -output-file-map %t/output.json 2>&1 | FileCheck %s -check-prefix=FILE-REMOVED // FILE-REMOVED: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading // FILE-REMOVED: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading diff --git a/test/Driver/Dependencies/chained-private-after-multiple-nominal-members.swift b/test/Driver/Dependencies/chained-private-after-multiple-nominal-members.swift new file mode 100644 index 0000000000000..77a68b5202fdb --- /dev/null +++ b/test/Driver/Dependencies/chained-private-after-multiple-nominal-members.swift @@ -0,0 +1,22 @@ +/// other --> main ==> yet-another +/// other ==>+ main ==> yet-another + +// RUN: rm -rf %t && cp -r %S/Inputs/chained-private-after-multiple-nominal-members/ %t +// RUN: touch -t 201401240005 %t/*.swift + +// Generate the build record... +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift ./yet-another.swift -module-name main -j1 -v + +// ...then reset the .swiftdeps files. +// RUN: cp -r %S/Inputs/chained-private-after-multiple-nominal-members/*.swiftdeps %t +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift ./yet-another.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-FIRST %s + +// CHECK-FIRST-NOT: warning +// CHECK-FIRST-NOT: Handled + +// RUN: touch -t 201401240006 %t/other.swift +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./yet-another.swift ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-SECOND %s + +// CHECK-SECOND: Handled other.swift +// CHECK-SECOND: Handled main.swift +// CHECK-SECOND: Handled yet-another.swift diff --git a/test/Driver/Dependencies/chained-private-after-multiple.swift b/test/Driver/Dependencies/chained-private-after-multiple.swift new file mode 100644 index 0000000000000..cde7c6bfc87b0 --- /dev/null +++ b/test/Driver/Dependencies/chained-private-after-multiple.swift @@ -0,0 +1,22 @@ +/// other --> main ==> yet-another +/// other ==>+ main ==> yet-another + +// RUN: rm -rf %t && cp -r %S/Inputs/chained-private-after-multiple/ %t +// RUN: touch -t 201401240005 %t/*.swift + +// Generate the build record... +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift ./yet-another.swift -module-name main -j1 -v + +// ...then reset the .swiftdeps files. +// RUN: cp -r %S/Inputs/chained-private-after-multiple/*.swiftdeps %t +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift ./yet-another.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-FIRST %s + +// CHECK-FIRST-NOT: warning +// CHECK-FIRST-NOT: Handled + +// RUN: touch -t 201401240006 %t/other.swift +// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path %S/Inputs/update-dependencies.py -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./yet-another.swift ./main.swift ./other.swift -module-name main -j1 -v 2>&1 | FileCheck -check-prefix=CHECK-SECOND %s + +// CHECK-SECOND: Handled other.swift +// CHECK-SECOND: Handled main.swift +// CHECK-SECOND: Handled yet-another.swift diff --git a/test/Driver/Inputs/print-var.sh b/test/Driver/Inputs/print-var.sh new file mode 100755 index 0000000000000..2bdd799b57fa3 --- /dev/null +++ b/test/Driver/Inputs/print-var.sh @@ -0,0 +1,3 @@ +#!/bin/bash +last_arg=${@: -1} +echo ${!last_arg} diff --git a/test/Driver/driver_mode.swift b/test/Driver/driver_mode.swift index 0451b19f4cd3d..2b58e90ab0602 100644 --- a/test/Driver/driver_mode.swift +++ b/test/Driver/driver_mode.swift @@ -11,4 +11,4 @@ // CHECK-SWIFTC-elf: 3: link, {1, 2}, image // CHECK-SWIFT: 0: input, "{{.*}}driver_mode.swift", swift -// CHECK-SWIFT: 1: compile, {0}, none +// CHECK-SWIFT: 1: interpret, {0}, none diff --git a/test/Driver/environment.swift b/test/Driver/environment.swift new file mode 100644 index 0000000000000..f0b3e91dec765 --- /dev/null +++ b/test/Driver/environment.swift @@ -0,0 +1,5 @@ +// UNSUPPORTED: objc_interop +// Apple's "System Integrity Protection" makes this test fail on OS X. + +// RUN: %swift_driver -target x86_64-unknown-gnu-linux -L/foo/ -driver-use-frontend-path %S/Inputs/print-var.sh %s LD_LIBRARY_PATH | FileCheck %s +// CHECK: {{^/foo/:[^:]+/lib/swift/linux$}} diff --git a/test/Driver/linker-autolink-extract.swift b/test/Driver/linker-autolink-extract.swift index c8289dfcb09a8..19f7843e65deb 100644 --- a/test/Driver/linker-autolink-extract.swift +++ b/test/Driver/linker-autolink-extract.swift @@ -1,6 +1,6 @@ // RUN: %swiftc_driver -driver-print-jobs -target x86_64-unknown-linux-gnu -g %s | FileCheck -check-prefix DEBUG_LINUX %s -// REQUIRES: swift-autolink-extract +// REQUIRES: autolink-extract // DEBUG_LINUX: bin/swift // DEBUG_LINUX-NEXT: bin/swift-autolink-extract diff --git a/test/Driver/linker.swift b/test/Driver/linker.swift index d25c4af80fc26..0bae408b09c96 100644 --- a/test/Driver/linker.swift +++ b/test/Driver/linker.swift @@ -12,16 +12,18 @@ // RUN: FileCheck -check-prefix watchOS_SIMPLE %s < %t.simple.txt // RUN: %swiftc_driver -driver-print-jobs -target x86_64-unknown-linux-gnu -Ffoo -framework bar -Lbaz -lboo -Xlinker -undefined %s 2>&1 > %t.linux.txt -// RUN: FileCheck -check-prefix LINUX %s < %t.linux.txt +// RUN: FileCheck -check-prefix LINUX-x86_64 %s < %t.linux.txt + +// RUN: %swiftc_driver -driver-print-jobs -target armv7-unknown-linux-gnueabihf -Ffoo -framework bar -Lbaz -lboo -Xlinker -undefined %s 2>&1 > %t.linux.txt +// RUN: FileCheck -check-prefix LINUX-armv7 %s < %t.linux.txt // RUN: %swiftc_driver -driver-print-jobs -emit-library -target x86_64-apple-macosx10.9.1 %s -sdk %S/../Inputs/clang-importer-sdk -lfoo -framework bar -Lbaz -Fgarply -Xlinker -undefined -Xlinker dynamic_lookup -o sdk.out 2>&1 > %t.complex.txt // RUN: FileCheck %s < %t.complex.txt // RUN: FileCheck -check-prefix COMPLEX %s < %t.complex.txt // RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -g %s | FileCheck -check-prefix DEBUG %s - -// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.10 %s | FileCheck -check-prefix NO_ARCLITE %s -// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-ios8.0 %s | FileCheck -check-prefix NO_ARCLITE %s +// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.10 %s | FileCheck -check-prefix NO_ARCLITE %s +// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-ios8.0 %s | FileCheck -check-prefix NO_ARCLITE %s // RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -emit-library %s -module-name LINKER | FileCheck -check-prefix INFERRED_NAME %s // RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -emit-library %s -o libLINKER.dylib | FileCheck -check-prefix INFERRED_NAME %s @@ -90,21 +92,37 @@ // watchOS_SIMPLE: -o linker -// LINUX: swift -// LINUX: -o [[OBJECTFILE:.*]] - -// LINUX: clang++{{"? }} -// LINUX-DAG: [[OBJECTFILE]] -// LINUX-DAG: -lswiftCore -// LINUX-DAG: -L [[STDLIB_PATH:[^ ]+/lib/swift]] -// LINUX-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH]] -// LINUX-DAG: -Xlinker -T /{{[^ ]+}}/linux/x86_64/swift.ld -// LINUX-DAG: -F foo -// LINUX-DAG: -framework bar -// LINUX-DAG: -L baz -// LINUX-DAG: -lboo -// LINUX-DAG: -Xlinker -undefined -// LINUX: -o linker +// LINUX-x86_64: swift +// LINUX-x86_64: -o [[OBJECTFILE:.*]] + +// LINUX-x86_64: clang++{{"? }} +// LINUX-x86_64-DAG: [[OBJECTFILE]] +// LINUX-x86_64-DAG: -lswiftCore +// LINUX-x86_64-DAG: -L [[STDLIB_PATH:[^ ]+/lib/swift]] +// LINUX-x86_64-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH]] +// LINUX-x86_64-DAG: -Xlinker -T /{{[^ ]+}}/linux/x86_64/swift.ld +// LINUX-x86_64-DAG: -F foo +// LINUX-x86_64-DAG: -framework bar +// LINUX-x86_64-DAG: -L baz +// LINUX-x86_64-DAG: -lboo +// LINUX-x86_64-DAG: -Xlinker -undefined +// LINUX-x86_64: -o linker + +// LINUX-armv7: swift +// LINUX-armv7: -o [[OBJECTFILE:.*]] + +// LINUX-armv7: clang++{{"? }} +// LINUX-armv7-DAG: [[OBJECTFILE]] +// LINUX-armv7-DAG: -lswiftCore +// LINUX-armv7-DAG: -L [[STDLIB_PATH:[^ ]+/lib/swift]] +// LINUX-armv7-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH]] +// LINUX-armv7-DAG: -Xlinker -T /{{[^ ]+}}/linux/armv7/swift.ld +// LINUX-armv7-DAG: -F foo +// LINUX-armv7-DAG: -framework bar +// LINUX-armv7-DAG: -L baz +// LINUX-armv7-DAG: -lboo +// LINUX-armv7-DAG: -Xlinker -undefined +// LINUX-armv7: -o linker // COMPLEX: bin/ld{{"? }} // COMPLEX-DAG: -dylib diff --git a/test/Driver/options-interpreter.swift b/test/Driver/options-interpreter.swift index 3eed8c10971b8..d474073c4f6eb 100644 --- a/test/Driver/options-interpreter.swift +++ b/test/Driver/options-interpreter.swift @@ -12,3 +12,53 @@ // RUN: %swift_driver -### -parse-stdlib %s | FileCheck -check-prefix PARSE_STDLIB %s // RUN: %swift_driver -### -parse-stdlib | FileCheck -check-prefix PARSE_STDLIB %s // PARSE_STDLIB: -parse-stdlib + + +// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -resource-dir /RSRC/ %s | FileCheck -check-prefix=CHECK-RESOURCE-DIR-ONLY %s +// CHECK-RESOURCE-DIR-ONLY: # DYLD_LIBRARY_PATH=/RSRC/macosx{{$}} + +// RUN: %swift_driver -### -target x86_64-unknown-linux-gnu -resource-dir /RSRC/ %s | FileCheck -check-prefix=CHECK-RESOURCE-DIR-ONLY-LINUX %s +// CHECK-RESOURCE-DIR-ONLY-LINUX: # LD_LIBRARY_PATH=/RSRC/linux{{$}} + +// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -L/foo/ %s | FileCheck -check-prefix=CHECK-L %s +// CHECK-L: # DYLD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/macosx$}} + +// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -L/foo/ -L/bar/ %s | FileCheck -check-prefix=CHECK-L2 %s +// CHECK-L2: # DYLD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/macosx$}} + +// RUN: env DYLD_LIBRARY_PATH=/abc/ %swift_driver_plain -### -target x86_64-apple-macosx10.9 -L/foo/ -L/bar/ %s | FileCheck -check-prefix=CHECK-L2-ENV %s +// CHECK-L2-ENV: # DYLD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/macosx:/abc/$}} + +// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 %s | FileCheck -check-prefix=CHECK-NO-FRAMEWORKS %s +// RUN: env DYLD_FRAMEWORK_PATH=/abc/ %swift_driver_plain -### -target x86_64-apple-macosx10.9 %s | FileCheck -check-prefix=CHECK-NO-FRAMEWORKS %s +// CHECK-NO-FRAMEWORKS-NOT: DYLD_FRAMEWORK_PATH + +// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -F/foo/ %s | FileCheck -check-prefix=CHECK-F %s +// CHECK-F: -F /foo/ +// CHECK-F: # +// CHECK-F: DYLD_FRAMEWORK_PATH=/foo/{{$}} + +// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -F/foo/ -F/bar/ %s | FileCheck -check-prefix=CHECK-F2 %s +// CHECK-F2: -F /foo/ +// CHECK-F2: -F /bar/ +// CHECK-F2: # +// CHECK-F2: DYLD_FRAMEWORK_PATH=/foo/:/bar/{{$}} + +// RUN: env DYLD_FRAMEWORK_PATH=/abc/ %swift_driver_plain -### -target x86_64-apple-macosx10.9 -F/foo/ -F/bar/ %s | FileCheck -check-prefix=CHECK-F2-ENV %s +// CHECK-F2-ENV: -F /foo/ +// CHECK-F2-ENV: -F /bar/ +// CHECK-F2-ENV: # +// CHECK-F2-ENV: DYLD_FRAMEWORK_PATH=/foo/:/bar/:/abc/{{$}} + +// RUN: env DYLD_FRAMEWORK_PATH=/abc/ %swift_driver_plain -### -target x86_64-apple-macosx10.9 -F/foo/ -F/bar/ -L/foo2/ -L/bar2/ %s | FileCheck -check-prefix=CHECK-COMPLEX %s +// CHECK-COMPLEX: -F /foo/ +// CHECK-COMPLEX: -F /bar/ +// CHECK-COMPLEX: # +// CHECK-COMPLEX-DAG: DYLD_FRAMEWORK_PATH=/foo/:/bar/:/abc/{{$| }} +// CHECK-COMPLEX-DAG: DYLD_LIBRARY_PATH={{/foo2/:/bar2/:[^:]+/lib/swift/macosx($| )}} + +// RUN: %swift_driver -### -target x86_64-unknown-linux-gnu -L/foo/ %s | FileCheck -check-prefix=CHECK-L-LINUX %s +// CHECK-L-LINUX: # LD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/linux$}} + +// RUN: env LD_LIBRARY_PATH=/abc/ %swift_driver_plain -### -target x86_64-unknown-linux-gnu -L/foo/ -L/bar/ %s | FileCheck -check-prefix=CHECK-LINUX-COMPLEX %s +// CHECK-LINUX-COMPLEX: # LD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/linux:/abc/$}} diff --git a/test/FixCode/fixits-apply.swift b/test/FixCode/fixits-apply.swift index 502684b181e55..4d512bfd1e441 100644 --- a/test/FixCode/fixits-apply.swift +++ b/test/FixCode/fixits-apply.swift @@ -13,7 +13,7 @@ b as! Base var opti : Int? // Don't add bang. var i : Int = opti -// But remove unecessary bang. +// But remove unnecessary bang. var i2 : Int = i! struct MyMask : OptionSetType { @@ -45,10 +45,6 @@ struct Test1 : RawOptionSetType { var rawValue: Int { return 0 } } -print("", appendNewline: false) -Swift.print("", appendNewline: false) -print("", appendNewline: true) -print("", false, appendNewline: false) print("", false) func ftest1() { diff --git a/test/FixCode/fixits-apply.swift.result b/test/FixCode/fixits-apply.swift.result index 8afd86dccf359..0821735797bdf 100644 --- a/test/FixCode/fixits-apply.swift.result +++ b/test/FixCode/fixits-apply.swift.result @@ -13,7 +13,7 @@ b var opti : Int? // Don't add bang. var i : Int = opti -// But remove unecessary bang. +// But remove unnecessary bang. var i2 : Int = i struct MyMask : OptionSetType { @@ -38,17 +38,13 @@ func foo() -> Int { } } -func goo(e : ErrorType) {} +func goo(var e : ErrorType) {} struct Test1 : OptionSetType { init(rawValue: Int) {} var rawValue: Int { return 0 } } -print("", terminator: "") -Swift.print("", terminator: "") -print("", terminator: "\n") -print("", false, appendNewline: false) print("", false) func ftest1() { diff --git a/test/Generics/algorithms.swift b/test/Generics/algorithms.swift index 4322ab6becb22..2a36cdddf4be5 100644 --- a/test/Generics/algorithms.swift +++ b/test/Generics/algorithms.swift @@ -41,7 +41,7 @@ func count var result = 0 for x in GeneratorSequence(range) { if x == value { - ++result + result += 1 } } return result @@ -53,7 +53,7 @@ func countIf< var result = 0 for x in GeneratorSequence(range) { if predicate(x) { - ++result + result += 1 } } return result @@ -80,7 +80,7 @@ func equal (range1 : R1, range2 : R2, - predicate : (R1.Element, R2.Element)-> Bool) -> Bool { + predicate : (R1.Element, R2.Element) -> Bool) -> Bool { var range1 = range1 var range2 = range2 var e1 = range1.next() diff --git a/test/Generics/associated_self_constraints.swift b/test/Generics/associated_self_constraints.swift index a0af58d5653d3..2f5e9a8faebef 100644 --- a/test/Generics/associated_self_constraints.swift +++ b/test/Generics/associated_self_constraints.swift @@ -50,7 +50,7 @@ class Subject: Observer, Observable { observer.onError(error) } - return self; + return self } } @@ -78,5 +78,5 @@ struct IP : P { func onNext(item: A) { _onNext(item) } - var _onNext: (A)->() + var _onNext: (A) -> () } diff --git a/test/Generics/associated_type_typo.swift b/test/Generics/associated_type_typo.swift index ea7b48e4af834..6a35107325c18 100644 --- a/test/Generics/associated_type_typo.swift +++ b/test/Generics/associated_type_typo.swift @@ -49,11 +49,11 @@ func typoAssoc4(_: T) { } // func typoFunc1(x: TypoType) { // expected-error{{use of undeclared type 'TypoType'}} - let _: T.Assoc -> () = { let _ = $0 } + let _: T.Assoc -> () = { let _ = $0 } // expected-error{{'Assoc' is not a member type of 'T'}} } func typoFunc2(x: TypoType, y: T) { // expected-error{{use of undeclared type 'TypoType'}} - let _: T.Assoc -> () = { let _ = $0 } + let _: T.Assoc -> () = { let _ = $0 } // expected-error{{'Assoc' is not a member type of 'T'}} } func typoFunc3(x: TypoType, y: T.Assoc -> ()) { // expected-error{{use of undeclared type 'TypoType'}} diff --git a/test/Generics/function_defs.swift b/test/Generics/function_defs.swift index 19f2c6ad30ac9..be9f38b78f780 100644 --- a/test/Generics/function_defs.swift +++ b/test/Generics/function_defs.swift @@ -14,7 +14,7 @@ protocol EqualComparable { func doCompare(t1: T, t2: T, u: U) -> Bool { var b1 = t1.isEqual(t2) if b1 { - return true; + return true } return t1.isEqual(u) // expected-error {{cannot invoke 'isEqual' with an argument list of type '(U)'}} @@ -195,7 +195,7 @@ func conformanceViaRequires(t1: T, t2: T) -> Bool { let b1 = t1.isEqual(t2) if b1 || t1.isLess(t2) { - return true; + return true } } diff --git a/test/Generics/generic_types.swift b/test/Generics/generic_types.swift index 39720e1d20487..43e96b97fc9a4 100644 --- a/test/Generics/generic_types.swift +++ b/test/Generics/generic_types.swift @@ -195,7 +195,8 @@ func useNested(ii: Int, hni: HasNested, typealias HNI = HasNested var id = hni.f(1, u: 3.14159) id = (2, 3.14159) - hni.f(1.5, 3.14159) // expected-error{{cannot convert value of type 'Double' to expected argument type 'Int'}} + hni.f(1.5, 3.14159) // expected-error{{missing argument label 'u:' in call}} + hni.f(1.5, u: 3.14159) // expected-error{{cannot convert value of type 'Double' to expected argument type 'Int'}} // Generic constructor of a generic struct HNI(1, 2.71828) // expected-warning{{unused}} @@ -322,3 +323,12 @@ class X6 { init(_ value: T2) {} } } + +// Invalid inheritance clause + +struct UnsolvableInheritance1 {} +// expected-error@-1 {{inheritance from non-protocol, non-class type 'T.A'}} + +struct UnsolvableInheritance2 {} +// expected-error@-1 {{inheritance from non-protocol, non-class type 'U.A'}} +// expected-error@-2 {{inheritance from non-protocol, non-class type 'T.A'}} diff --git a/test/Generics/materializable_restrictions.swift b/test/Generics/materializable_restrictions.swift index 6d4173f3973b3..c7dca86ba4cca 100644 --- a/test/Generics/materializable_restrictions.swift +++ b/test/Generics/materializable_restrictions.swift @@ -9,17 +9,16 @@ func test15921520() { func test20807269() { var x: Int = 0 func f(x: T) {} - // expected-note @+1 {{expected an argument list of type '(T)'}} - f(1, &x) // expected-error{{cannot invoke 'f' with an argument list of type '(Int, inout Int)'}} + f(1, &x) // expected-error{{extra argument in call}} } func test15921530() { struct X {} - func makef() -> (T)->() { // expected-note {{in call to function 'makef'}} + func makef() -> (T) -> () { // expected-note {{in call to function 'makef'}} return { x in () } } - var _: (inout X)->() = makef() // expected-error{{generic parameter 'T' could not be inferred}} + var _: (inout X) -> () = makef() // expected-error{{generic parameter 'T' could not be inferred}} } diff --git a/test/Generics/requirement_inference.swift b/test/Generics/requirement_inference.swift index ef08c5156f076..dd42758bd441f 100644 --- a/test/Generics/requirement_inference.swift +++ b/test/Generics/requirement_inference.swift @@ -115,13 +115,13 @@ struct Model_P3_P4_Eq { } // CHECK-LABEL: .inferSameType1@ // CHECK-NEXT: Requirements: // CHECK-NEXT: T witness marker -// CHECK-NEXT: T : P3 [inferred @ {{.*}}:26] +// CHECK-NEXT: T : P3 [inferred @ {{.*}}:30] // CHECK-NEXT: U witness marker -// CHECK-NEXT: U : P4 [inferred @ {{.*}}:26] +// CHECK-NEXT: U : P4 [inferred @ {{.*}}:30] // CHECK-NEXT: T[.P3].P3Assoc witness marker // CHECK-NEXT: T[.P3].P3Assoc : P1 [protocol @ {{.*}}:13] // CHECK-NEXT: T[.P3].P3Assoc : P2 [protocol @ {{.*}}:13] -// CHECK-NEXT: U[.P4].P4Assoc == T[.P3].P3Assoc [inferred @ {{.*}}26] +// CHECK-NEXT: U[.P4].P4Assoc == T[.P3].P3Assoc [inferred @ {{.*}}30] func inferSameType1(x: Model_P3_P4_Eq) { } // CHECK-LABEL: .inferSameType2@ diff --git a/test/Generics/same_type_constraints.swift b/test/Generics/same_type_constraints.swift index 754582b618686..11f9270f7ab54 100644 --- a/test/Generics/same_type_constraints.swift +++ b/test/Generics/same_type_constraints.swift @@ -48,7 +48,7 @@ struct SatisfySameTypeAssocTypeRequirementDependent public struct GeneratorOf : GeneratorType, SequenceType { /// Construct an instance whose `next()` method calls `nextElement`. - public init(_ nextElement: ()->T?) { + public init(_ nextElement: () -> T?) { self._next = nextElement } @@ -74,7 +74,7 @@ public struct GeneratorOf : GeneratorType, SequenceType { public func generate() -> GeneratorOf { return self } - let _next: ()->T? + let _next: () -> T? } // rdar://problem/19009056 @@ -105,7 +105,7 @@ public final class IterateGenerator : GeneratorType { // rdar://problem/18475138 public protocol Observable : class { typealias Output - func addObserver(obj : Output->Void) + func addObserver(obj : Output -> Void) } public protocol Bindable : class { @@ -174,7 +174,7 @@ class Cow : Animal { struct SpecificAnimal : Animal { typealias EdibleFood=F - let _eat:(f:F)->() + let _eat:(f:F) -> () init(_ selfie:A) { _eat = { selfie.eat($0) } diff --git a/test/Generics/slice_test.swift b/test/Generics/slice_test.swift index 2f8a4a0ea4e1d..35f146313f6b3 100644 --- a/test/Generics/slice_test.swift +++ b/test/Generics/slice_test.swift @@ -102,7 +102,7 @@ func find(array: [T], value: T) -> Int { var idx = 0 for elt in array { if (elt == value) { return idx } - ++idx + idx += 1 } return -1 } @@ -111,7 +111,7 @@ func findIf(array: [T], fn: (T) -> Bool) -> Int { var idx = 0 for elt in array { if (fn(elt)) { return idx } - ++idx + idx += 1 } return -1 } diff --git a/test/IDE/Inputs/AnyObject/baz_clang_module.h b/test/IDE/Inputs/AnyObject/baz_clang_module.h index 4c1994016b2e5..e00d85ae99cef 100644 --- a/test/IDE/Inputs/AnyObject/baz_clang_module.h +++ b/test/IDE/Inputs/AnyObject/baz_clang_module.h @@ -12,6 +12,7 @@ - (id)objectAtIndexedSubscript:(int)idx; @property Baz_Class *baz_Class_Property1; +@property (getter=get_baz_Class_Property2) Baz_Class *baz_Class_Property2; @end diff --git a/test/IDE/Inputs/dumped_api.swift b/test/IDE/Inputs/dumped_api.swift deleted file mode 100644 index e908803f65ca8..0000000000000 --- a/test/IDE/Inputs/dumped_api.swift +++ /dev/null @@ -1,588 +0,0 @@ -//===--- dump_api.swift ---------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// RUN: %target-swift-ide-test -dump-api -source-filename %s > %t.swift -// RUN: diff -du %S/Inputs/dumped_api.swift %t.swift - -//===--- Definitions needed only while experimental -----------------------===// -public struct _Distance {} -public struct _InitializeTo {} -extension _InitializeTo { } -extension _ContiguousArrayBuffer { -} - -//===----------------------------------------------------------------------===// - - - -//===--- Generator --------------------------------------------------------===// -//===----------------------------------------------------------------------===// - -public class _AnyGeneratorBase {} - -/// An abstract `GeneratorType` base class over `T` elements. -/// -/// Use this as a `Sequence`'s associated `Generator` type when you -/// don't want to expose details of the concrete generator, a subclass. -/// -/// It is an error to create instances of `AnyGenerator` that are not -/// also instances of an `AnyGenerator` subclass. -/// -/// See also: -/// -/// struct AnySequence -/// func anyGenerator(base: G) -> AnyGenerator -/// func anyGenerator(nextImplementation: ()->T?) -> AnyGenerator -public class AnyGenerator : _AnyGeneratorBase, GeneratorType { - /// Initialize the instance. May only be called from a subclass - /// initializer. - override public init() - - /// Advance to the next element and return it, or `nil` if no next - /// element exists. - /// - /// Note: subclasses must override this method. - public func next() -> T? -} - -/// Every `GeneratorType` can also be a `SequenceType`. Note that -/// traversing the sequence consumes the generator. -extension AnyGenerator : SequenceType { - /// Returns `self`. - public func generate() -> AnyGenerator -} - -/// Return a `GeneratorType` instance that wraps `base` but whose type -/// depends only on the type of `G.Element`. -/// -/// Example: -/// -/// func countStrings() -> AnyGenerator { -/// let lazyStrings = lazy(0..<10).map { String($0) } -/// -/// // This is a really complicated type of no interest to our -/// // clients. -/// let g: MapSequenceGenerator, String> -/// = lazyStrings.generate() -/// return anyGenerator(g) -/// } -public func anyGenerator(base: G) -> AnyGenerator - - -/// Return a `GeneratorType` instance whose `next` method invokes -/// `nextImplementation` and returns the result. -/// -/// Example: -/// -/// var x = 7 -/// let g = anyGenerator { x < 15 ? x++ : nil } -/// let a = Array(g) // [ 7, 8, 9, 10, 11, 12, 13, 14 ] -public func anyGenerator(nextImplementation: ()->T?) -> AnyGenerator - - - -//===--- Sequence ---------------------------------------------------------===// -//===----------------------------------------------------------------------===// - - - -// FIXME: can't make this a protocol due to -// FIXME: can't make this a protocol due to - -/// A type-erased sequence. -/// -/// Forwards operations to an arbitrary underlying sequence having the -/// same `Element` type, hiding the specifics of the underlying -/// `SequenceType`. -/// -/// See also: `AnyGenerator`. -public struct AnySequence : SequenceType { - - /// Wrap and forward operations to to `base` - public init(_ base: S) - - /// Return a *generator* over the elements of this *sequence*. - /// - /// Complexity: O(1) - public func generate() -> AnyGenerator - -} - -public func ~> ( - source: AnySequence, - ptr: (_InitializeTo, UnsafeMutablePointer) -) - -extension AnySequence { - public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer -} - -public func ~> ( - source: AnyForwardCollection, - ptr: (_InitializeTo, UnsafeMutablePointer) -) - -extension AnyForwardCollection { - public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer -} - -public func ~> ( - source: AnyBidirectionalCollection, - ptr: (_InitializeTo, UnsafeMutablePointer) -) - -extension AnyBidirectionalCollection { - public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer -} - -public func ~> ( - source: AnyRandomAccessCollection, - ptr: (_InitializeTo, UnsafeMutablePointer) -) - -extension AnyRandomAccessCollection { - public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer -} - -//===--- ForwardIndex -----------------------------------------------------===// -//===----------------------------------------------------------------------===// - - - -//===--- BidirectionalIndex -----------------------------------------------===// -//===----------------------------------------------------------------------===// - - - -//===--- RandomAccessIndex -----------------------------------------------===// -//===----------------------------------------------------------------------===// - - - -//===--- All Index Protocols ----------------------------------------------===// -//===----------------------------------------------------------------------===// - - -/// A wrapper over an underlying `ForwardIndexType` that hides -/// the specific underlying type. -/// -/// See also: `AnyForwardCollection` -public struct AnyForwardIndex : ForwardIndexType { - public typealias Distance = IntMax - - /// Wrap and forward operations to `base`. - public init(_ base: BaseIndex) - - /// Return the next consecutive value in a discrete sequence of - /// `AnyForwardIndex` values. - /// - /// Requires: `self` has a well-defined successor. - public func successor() -> AnyForwardIndex - - - - //===--- private --------------------------------------------------------===// - - - -} - -public func ~> ( - start: AnyForwardIndex, other : (_Distance, AnyForwardIndex) -) -> AnyForwardIndex.Distance - -public func ~> ( - start: AnyForwardIndex, distance : (_Advance, AnyForwardIndex.Distance) -) -> AnyForwardIndex - -public func ~> ( - start: AnyForwardIndex, - args: (_Advance, (AnyForwardIndex.Distance, AnyForwardIndex)) -) -> AnyForwardIndex - -/// Return true iff `lhs` and `rhs` wrap equal underlying -/// `AnyForwardIndex`s. -/// -/// Requires: the types of indices wrapped by `lhs` and `rhs` are -/// identical. -public func == (lhs: AnyForwardIndex, rhs: AnyForwardIndex) -> Bool - -/// A wrapper over an underlying `BidirectionalIndexType` that hides -/// the specific underlying type. -/// -/// See also: `AnyBidirectionalCollection` -public struct AnyBidirectionalIndex : BidirectionalIndexType { - public typealias Distance = IntMax - - /// Wrap and forward operations to `base`. - public init(_ base: BaseIndex) - - /// Return the next consecutive value in a discrete sequence of - /// `AnyBidirectionalIndex` values. - /// - /// Requires: `self` has a well-defined successor. - public func successor() -> AnyBidirectionalIndex - - /// Return the previous consecutive value in a discrete sequence of - /// `AnyBidirectionalIndex` values. - /// - /// Requires: `self` has a well-defined predecessor. - public func predecessor() -> AnyBidirectionalIndex - - - //===--- private --------------------------------------------------------===// - - - -} - -public func ~> ( - start: AnyBidirectionalIndex, other : (_Distance, AnyBidirectionalIndex) -) -> AnyBidirectionalIndex.Distance - -public func ~> ( - start: AnyBidirectionalIndex, distance : (_Advance, AnyBidirectionalIndex.Distance) -) -> AnyBidirectionalIndex - -public func ~> ( - start: AnyBidirectionalIndex, - args: (_Advance, (AnyBidirectionalIndex.Distance, AnyBidirectionalIndex)) -) -> AnyBidirectionalIndex - -/// Return true iff `lhs` and `rhs` wrap equal underlying -/// `AnyBidirectionalIndex`s. -/// -/// Requires: the types of indices wrapped by `lhs` and `rhs` are -/// identical. -public func == (lhs: AnyBidirectionalIndex, rhs: AnyBidirectionalIndex) -> Bool - -/// A wrapper over an underlying `RandomAccessIndexType` that hides -/// the specific underlying type. -/// -/// See also: `AnyRandomAccessCollection` -public struct AnyRandomAccessIndex : RandomAccessIndexType { - public typealias Distance = IntMax - - /// Wrap and forward operations to `base`. - public init(_ base: BaseIndex) - - /// Return the next consecutive value in a discrete sequence of - /// `AnyRandomAccessIndex` values. - /// - /// Requires: `self` has a well-defined successor. - public func successor() -> AnyRandomAccessIndex - - /// Return the previous consecutive value in a discrete sequence of - /// `AnyRandomAccessIndex` values. - /// - /// Requires: `self` has a well-defined predecessor. - public func predecessor() -> AnyRandomAccessIndex - - /// Return the minimum number of applications of `successor` or - /// `predecessor` required to reach `other` from `self`. - /// - /// Requires: `self` and `other` wrap instances of the same type. - public func distanceTo(other: AnyRandomAccessIndex) -> Distance - - /// Return `self` offset by `n` steps. - /// - /// - Returns: If `n > 0`, the result of applying `successor` to - /// `self` `n` times. If `n < 0`, the result of applying - /// `predecessor` to `self` `n` times. Otherwise, `self`. - public func advancedBy(amount: Distance) -> AnyRandomAccessIndex - - //===--- private --------------------------------------------------------===// - - - -} - -public func ~> ( - start: AnyRandomAccessIndex, other : (_Distance, AnyRandomAccessIndex) -) -> AnyRandomAccessIndex.Distance - -public func ~> ( - start: AnyRandomAccessIndex, distance : (_Advance, AnyRandomAccessIndex.Distance) -) -> AnyRandomAccessIndex - -public func ~> ( - start: AnyRandomAccessIndex, - args: (_Advance, (AnyRandomAccessIndex.Distance, AnyRandomAccessIndex)) -) -> AnyRandomAccessIndex - -/// Return true iff `lhs` and `rhs` wrap equal underlying -/// `AnyRandomAccessIndex`s. -/// -/// Requires: the types of indices wrapped by `lhs` and `rhs` are -/// identical. -public func == (lhs: AnyRandomAccessIndex, rhs: AnyRandomAccessIndex) -> Bool - -//===--- Collections ------------------------------------------------------===// -//===----------------------------------------------------------------------===// - - -/// A protocol for `AnyForwardCollection`, -/// `AnyBidirectionalCollection`, and -/// `AnyRandomAccessCollection`. -/// -/// This protocol can be considered an implementation detail of the -/// `===` and `!==` implementations for these types. -public protocol AnyCollectionType : CollectionType { - /// Identifies the underlying collection stored by `self`. Instances - /// copied from one another have the same `underlyingCollectionID`. - var underlyingCollectionID: ObjectIdentifier {get} -} - -/// Return true iff `lhs` and `rhs` store the same underlying collection. -public func === < - L: AnyCollectionType, R: AnyCollectionType ->(lhs: L, rhs: R) -> Bool - -/// Return false iff `lhs` and `rhs` store the same underlying collection. -public func !== < - L: AnyCollectionType, R: AnyCollectionType ->(lhs: L, rhs: R) -> Bool - -/// A type-erased wrapper over any collection with at least -/// forward indices. -/// -/// Forwards operations to an arbitrary underlying collection having the -/// same `Element` type, hiding the specifics of the underlying -/// `CollectionType`. -/// -/// See also: `AnyBidirectionalType`, `AnyRandomAccessType` -public struct AnyForwardCollection : AnyCollectionType { - - /// Create an `AnyForwardCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: ForwardIndexType, C.Generator.Element == Element - >(_ base: C) - - /// Create an `AnyForwardCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyForwardCollection) - /// Create an `AnyForwardCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: BidirectionalIndexType, C.Generator.Element == Element - >(_ base: C) - - /// Create an `AnyForwardCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyBidirectionalCollection) - /// Create an `AnyForwardCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: RandomAccessIndexType, C.Generator.Element == Element - >(_ base: C) - - /// Create an `AnyForwardCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyRandomAccessCollection) - - - /// Return a *generator* over the elements of this *collection*. - /// - /// Complexity: O(1) - public func generate() -> AnyGenerator - - /// The position of the first element in a non-empty collection. - /// - /// Identical to `endIndex` in an empty collection. - public var startIndex: AnyForwardIndex - - /// The collection's "past the end" position. - /// - /// `endIndex` is not a valid argument to `subscript`, and is always - /// reachable from `startIndex` by zero or more applications of - /// `successor()`. - public var endIndex: AnyForwardIndex - - /// Access the element indicated by `position`. - /// - /// Requires: `position` indicates a valid position in `self` and - /// `position != endIndex`. - public subscript(position: AnyForwardIndex) -> Element - - /// Uniquely identifies the stored underlying collection. - public var underlyingCollectionID: ObjectIdentifier - -} -/// A type-erased wrapper over any collection with at least -/// bidirectional indices. -/// -/// Forwards operations to an arbitrary underlying collection having the -/// same `Element` type, hiding the specifics of the underlying -/// `CollectionType`. -/// -/// See also: `AnyRandomAccessType`, `AnyForwardType` -public struct AnyBidirectionalCollection : AnyCollectionType { - - /// Create an `AnyBidirectionalCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: BidirectionalIndexType, C.Generator.Element == Element - >(_ base: C) - - /// Create an `AnyBidirectionalCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyBidirectionalCollection) - /// Create an `AnyBidirectionalCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: RandomAccessIndexType, C.Generator.Element == Element - >(_ base: C) - - /// Create an `AnyBidirectionalCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyRandomAccessCollection) - - /// If the indices of the underlying collection stored by `other` - /// satisfy `BidirectionalIndexType`, create an - /// `AnyBidirectionalCollection` having the same underlying - /// collection as `other`. Otherwise, the result is `nil`. - /// - /// Complexity: O(1) - public init?(_ other: AnyForwardCollection) - - /// Return a *generator* over the elements of this *collection*. - /// - /// Complexity: O(1) - public func generate() -> AnyGenerator - - /// The position of the first element in a non-empty collection. - /// - /// Identical to `endIndex` in an empty collection. - public var startIndex: AnyBidirectionalIndex - - /// The collection's "past the end" position. - /// - /// `endIndex` is not a valid argument to `subscript`, and is always - /// reachable from `startIndex` by zero or more applications of - /// `successor()`. - public var endIndex: AnyBidirectionalIndex - - /// Access the element indicated by `position`. - /// - /// Requires: `position` indicates a valid position in `self` and - /// `position != endIndex`. - public subscript(position: AnyBidirectionalIndex) -> Element - - /// Uniquely identifies the stored underlying collection. - public var underlyingCollectionID: ObjectIdentifier - -} -/// A type-erased wrapper over any collection with at least -/// randomaccess indices. -/// -/// Forwards operations to an arbitrary underlying collection having the -/// same `Element` type, hiding the specifics of the underlying -/// `CollectionType`. -/// -/// See also: `AnyForwardType`, `AnyBidirectionalType` -public struct AnyRandomAccessCollection : AnyCollectionType { - - /// Create an `AnyRandomAccessCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: RandomAccessIndexType, C.Generator.Element == Element - >(_ base: C) - - /// Create an `AnyRandomAccessCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyRandomAccessCollection) - - /// If the indices of the underlying collection stored by `other` - /// satisfy `RandomAccessIndexType`, create an - /// `AnyRandomAccessCollection` having the same underlying - /// collection as `other`. Otherwise, the result is `nil`. - /// - /// Complexity: O(1) - public init?(_ other: AnyForwardCollection) - /// If the indices of the underlying collection stored by `other` - /// satisfy `RandomAccessIndexType`, create an - /// `AnyRandomAccessCollection` having the same underlying - /// collection as `other`. Otherwise, the result is `nil`. - /// - /// Complexity: O(1) - public init?(_ other: AnyBidirectionalCollection) - - /// Return a *generator* over the elements of this *collection*. - /// - /// Complexity: O(1) - public func generate() -> AnyGenerator - - /// The position of the first element in a non-empty collection. - /// - /// Identical to `endIndex` in an empty collection. - public var startIndex: AnyRandomAccessIndex - - /// The collection's "past the end" position. - /// - /// `endIndex` is not a valid argument to `subscript`, and is always - /// reachable from `startIndex` by zero or more applications of - /// `successor()`. - public var endIndex: AnyRandomAccessIndex - - /// Access the element indicated by `position`. - /// - /// Requires: `position` indicates a valid position in `self` and - /// `position != endIndex`. - public subscript(position: AnyRandomAccessIndex) -> Element - - /// Uniquely identifies the stored underlying collection. - public var underlyingCollectionID: ObjectIdentifier - -} - diff --git a/test/IDE/Inputs/mock-sdk/Foo.annotated.txt b/test/IDE/Inputs/mock-sdk/Foo.annotated.txt index c0b4caa8b10e7..02dc2fdde746d 100644 --- a/test/IDE/Inputs/mock-sdk/Foo.annotated.txt +++ b/test/IDE/Inputs/mock-sdk/Foo.annotated.txt @@ -253,6 +253,8 @@ class FooClassDerived : FooClassBase, init!() convenience init!(float f: Float) } +class FooCFType { +} typealias FooCFTypeRef = FooCFType @available(*, unavailable, message="Core Foundation objects are automatically memory managed") func FooCFTypeRelease(_: FooCFType!) @@ -265,10 +267,10 @@ func FooCFTypeRelease(_: FooCFType!) extension FooRepeatedMembers { var repeatedPropertyInCategory: Int32 func repeatedMethodInCategory() - var repeatedPropertyFromCategory: Int32 - func repeatedMethodFromCategory() } extension FooRepeatedMembers { + var repeatedPropertyFromCategory: Int32 + func repeatedMethodFromCategory() } enum SCNFilterMode : Int { init?(rawValue: Int) diff --git a/test/IDE/Inputs/mock-sdk/Foo.printed.recursive.txt b/test/IDE/Inputs/mock-sdk/Foo.printed.recursive.txt index eddfb32e395bb..d353b924a6583 100644 --- a/test/IDE/Inputs/mock-sdk/Foo.printed.recursive.txt +++ b/test/IDE/Inputs/mock-sdk/Foo.printed.recursive.txt @@ -253,6 +253,8 @@ class FooUnavailableMembers : FooClassBase { init!() convenience init!(float f: Float) } +class FooCFType { +} typealias FooCFTypeRef = FooCFType @available(*, unavailable, message="Core Foundation objects are automatically memory managed") func FooCFTypeRelease(_: FooCFType!) @@ -265,10 +267,10 @@ class FooRepeatedMembers : FooClassBase { extension FooRepeatedMembers { var repeatedPropertyInCategory: Int32 func repeatedMethodInCategory() - var repeatedPropertyFromCategory: Int32 - func repeatedMethodFromCategory() } extension FooRepeatedMembers { + var repeatedPropertyFromCategory: Int32 + func repeatedMethodFromCategory() } enum SCNFilterMode : Int { init?(rawValue: Int) diff --git a/test/IDE/Inputs/mock-sdk/Foo.printed.txt b/test/IDE/Inputs/mock-sdk/Foo.printed.txt index 60f4d4872bc12..b2a28056777ea 100644 --- a/test/IDE/Inputs/mock-sdk/Foo.printed.txt +++ b/test/IDE/Inputs/mock-sdk/Foo.printed.txt @@ -307,6 +307,8 @@ class FooUnavailableMembers : FooClassBase { convenience init!(float f: Float) } +class FooCFType { +} typealias FooCFTypeRef = FooCFType @available(*, unavailable, message="Core Foundation objects are automatically memory managed") func FooCFTypeRelease(_: FooCFType!) @@ -321,12 +323,11 @@ class FooRepeatedMembers : FooClassBase { extension FooRepeatedMembers { var repeatedPropertyInCategory: Int32 func repeatedMethodInCategory() - - var repeatedPropertyFromCategory: Int32 - func repeatedMethodFromCategory() } extension FooRepeatedMembers { + var repeatedPropertyFromCategory: Int32 + func repeatedMethodFromCategory() } enum SCNFilterMode : Int { diff --git a/test/IDE/Inputs/print_clang_header_swift_name.h b/test/IDE/Inputs/print_clang_header_swift_name.h new file mode 100644 index 0000000000000..ec18c17477692 --- /dev/null +++ b/test/IDE/Inputs/print_clang_header_swift_name.h @@ -0,0 +1,31 @@ +@import Foundation; + +#define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) + +#define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type + +typedef SWIFT_ENUM(NSInteger, Normal) { + NormalOne = 0, + NormalTwo, + NormalThree +}; + +// FIXME (#618): Use SWIFT_ENUM_NAMED() when support for that lands +#undef SWIFT_ENUM +#define SWIFT_ENUM(_type, _name) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_ENUM_NAME); enum SWIFT_COMPILE_NAME(SWIFT_ENUM_NAME) SWIFT_ENUM_EXTRA _name : _type + +#define SWIFT_ENUM_NAME "SwiftEnum" +typedef SWIFT_ENUM(NSInteger, ObjCEnum) { + ObjCEnumOne = 0, + ObjCEnumTwo, + ObjCEnumThree +}; + +#undef SWIFT_ENUM_NAME +#define SWIFT_ENUM_NAME "SwiftEnumTwo" +typedef SWIFT_ENUM(NSInteger, ObjCEnumTwo) { + // the following shouldn't have their prefixes stripped + SwiftEnumTwoA, + SwiftEnumTwoB, + SwiftEnumTwoC +}; diff --git a/test/IDE/Inputs/swift_name_objc.h b/test/IDE/Inputs/swift_name_objc.h index 2a43a2a1e4319..a9c42c4004471 100644 --- a/test/IDE/Inputs/swift_name_objc.h +++ b/test/IDE/Inputs/swift_name_objc.h @@ -1,4 +1,4 @@ -@import ObjectiveC; +@import Foundation; #define SWIFT_NAME(X) __attribute__((swift_name(#X))) @@ -38,13 +38,19 @@ SWIFT_NAME(SomeProtocol) @interface SNSomeClass (Category1) - (void)categoryMethodWithX:(float)x y:(float)y; - (void)categoryMethodWithX:(float)x y:(float)y z:(float)z; -- (object)objectAtIndexedSubscript:(NSInteger)index; +- (id)objectAtIndexedSubscript:(NSInteger)index; @end @interface SNCollision @end @protocol SNCollision +@property (readonly,nonnull) id reqSetter; +- (void)setReqSetter:(nonnull id)bar; + +@property (readonly,nonnull) id optSetter; +@optional +- (void)setOptSetter:(nonnull id)bar; @end @protocol NSAccessibility diff --git a/test/IDE/coloring.swift b/test/IDE/coloring.swift index 34d782dccda70..cff1b68bbb7f2 100644 --- a/test/IDE/coloring.swift +++ b/test/IDE/coloring.swift @@ -429,9 +429,13 @@ func emptyDocBlockComment3() {} /**/ -func malformedBlockComment(f : ()throws->()) rethrows {} +func malformedBlockComment(f : () throws -> ()) rethrows {} // CHECK: /**/ -// CHECK: func malformedBlockComment(f : ()throws->()) rethrows {} +// CHECK: func malformedBlockComment(f : () throws -> ()) rethrows {} + +//: playground doc comment line +func playgroundCommentLine(f : () throws -> ()) rethrows {} +// CHECK: //: playground doc comment line "--\"\(x) --" diff --git a/test/IDE/coloring_playground.swift b/test/IDE/coloring_playground.swift new file mode 100644 index 0000000000000..61c666ebd2a92 --- /dev/null +++ b/test/IDE/coloring_playground.swift @@ -0,0 +1,16 @@ +// RUN: %target-swift-ide-test -syntax-coloring -playground -source-filename %s | FileCheck %s +// RUN: %target-swift-ide-test -syntax-coloring -playground -typecheck -source-filename %s | FileCheck %s + +//: playground doc comment line +func playgroundCommentLine(f : () throws -> ()) rethrows {} +// CHECK: //: playground doc comment line + +// Keep this as the last test +/** + Trailing off ... +func unterminatedBlockComment() {} +// CHECK: // Keep this as the last test +// CHECK: /** +// CHECK: Trailing off ... +// CHECK: func unterminatedBlockComment() {} +// CHECK: diff --git a/test/IDE/comment_attach.swift b/test/IDE/comment_attach.swift index 55452655bbf40..e3138dcbe4d94 100644 --- a/test/IDE/comment_attach.swift +++ b/test/IDE/comment_attach.swift @@ -149,7 +149,7 @@ struct decl_struct_1 { /// NestedEnum Aaa. enum NestedEnum {} - // Can not declare a nested protocol. + // Cannot declare a nested protocol. // protocol NestedProtocol {} /// NestedTypealias Aaa. @@ -277,7 +277,7 @@ func unterminatedBlockDocComment() {} // CHECK-NEXT: comment_attach.swift:135:8: Func/decl_struct_1.instanceFunc4 RawComment=[/// instanceFunc4 Aaa.\n] // CHECK-NEXT: comment_attach.swift:138:3: Constructor/decl_struct_1.init RawComment=[/// init(). Aaa.\n] BriefComment=[init(). Aaa.] // CHECK-NEXT: comment_attach.swift:141:3: Subscript/decl_struct_1.subscript RawComment=[/// subscript Aaa.\n] -// CHECK-NEXT: comment_attach.swift:141:13: Param/decl_struct_1.i RawComment=none +// CHECK-NEXT: comment_attach.swift:141:13: Param/i RawComment=none // CHECK-NEXT: comment_attach.swift:141:31: Func/decl_struct_1. RawComment=none // CHECK-NEXT: comment_attach.swift:144:10: Struct/decl_struct_1.NestedStruct RawComment=[/// NestedStruct Aaa.\n] // CHECK-NEXT: comment_attach.swift:147:9: Class/decl_struct_1.NestedClass RawComment=[/// NestedClass Aaa.\n] diff --git a/test/IDE/comment_extensions.swift b/test/IDE/comment_extensions.swift index 57e33f9f7485a..f5091520c1181 100644 --- a/test/IDE/comment_extensions.swift +++ b/test/IDE/comment_extensions.swift @@ -59,4 +59,3 @@ // CHECK: {{.*}}DocCommentAsXML=[urlWithQueryString()s:F14swift_ide_test18urlWithQueryStringFT_T_func urlWithQueryString()Brief.Test a link] // CHECK: {{.*}}DocCommentAsXML=[imageWithAmpersandsInTitleAndAlt()s:F14swift_ide_test32imageWithAmpersandsInTitleAndAltFT_T_func imageWithAmpersandsInTitleAndAlt()Brief.]]>] - diff --git a/test/IDE/complete_after_self.swift b/test/IDE/complete_after_self.swift index 78fc483e268a0..a7f84d095f3ac 100644 --- a/test/IDE/complete_after_self.swift +++ b/test/IDE/complete_after_self.swift @@ -96,7 +96,7 @@ class ThisDerived1 : ThisBase1 { } } - subscript(#s: String) -> Int { + subscript(s s: String) -> Int { get { return 0 } diff --git a/test/IDE/complete_crashes.swift b/test/IDE/complete_crashes.swift index 257d11a144b83..9c744bea9c2e6 100644 --- a/test/IDE/complete_crashes.swift +++ b/test/IDE/complete_crashes.swift @@ -63,7 +63,7 @@ struct CustomGenericCollection : DictionaryLiteralConvertible { // GENERIC_PARAM_AND_ASSOC_TYPE-DAG: Decl[TypeAlias]/CurrNominal: Key[#Key#]; name=Key // GENERIC_PARAM_AND_ASSOC_TYPE-DAG: Decl[TypeAlias]/CurrNominal: Value[#Value#]; name=Value // GENERIC_PARAM_AND_ASSOC_TYPE: End completions - + var count: Int { #^GENERIC_PARAM_AND_ASSOC_TYPE^# } } @@ -159,3 +159,9 @@ func rdar22834017() { } // FIXME: We could provide a useful completion here. rdar://problem/22846558 // INVALID_TYPE_INIT-NOT: Begin completions + +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=RDAR_23173692 | FileCheck %s -check-prefix=RDAR_23173692 +func rdar23173692() { + return IndexingGenerator(#^RDAR_23173692^#) +} +// RDAR_23173692: Begin completions diff --git a/test/IDE/complete_dynamic_lookup.swift b/test/IDE/complete_dynamic_lookup.swift index a8d54fc5c2ea7..8ce42b41ac4f1 100644 --- a/test/IDE/complete_dynamic_lookup.swift +++ b/test/IDE/complete_dynamic_lookup.swift @@ -139,6 +139,7 @@ protocol Bar { func bar() } // DL_INSTANCE_DOT-DAG: Decl[InstanceVar]/OtherModule[swift_ide_test]: base1_Property2[#Base?#]{{; name=.+$}} // DL_INSTANCE_DOT-DAG: Decl[InstanceMethod]/OtherModule[baz_clang_module]: baz_Class_InstanceFunc1!()[#Void#]{{; name=.+$}} // DL_INSTANCE_DOT-DAG: Decl[InstanceVar]/OtherModule[baz_clang_module]: baz_Class_Property1[#Baz_Class!?#]{{; name=.+$}} +// DL_INSTANCE_DOT-DAG: Decl[InstanceVar]/OtherModule[baz_clang_module]: baz_Class_Property2[#Baz_Class!?#]{{; name=.+$}} // DL_INSTANCE_DOT-DAG: Decl[InstanceMethod]/OtherModule[baz_clang_module]: baz_Protocol_InstanceFunc1!()[#Void#]{{; name=.+$}} // DL_INSTANCE_DOT-DAG: Decl[InstanceMethod]/OtherModule[foo_swift_module]: foo_Nested1_ObjcInstanceFunc1!()[#Void#]{{; name=.+$}} // DL_INSTANCE_DOT-DAG: Decl[InstanceVar]/OtherModule[foo_swift_module]: foo_Nested1_Property1[#Int?#]{{; name=.+$}} @@ -455,7 +456,7 @@ func testAnyObject10() { func testAnyObject11(dl: AnyObject) { dl.returnsObjcClass#^DL_FUNC_NAME_1^# } -// FIXME: it wolud be nice if we produced a call pattern here. +// FIXME: it would be nice if we produced a call pattern here. // DL_FUNC_NAME_1: Begin completions // DL_FUNC_NAME_1-DAG: Decl[InstanceMethod]/CurrNominal: .map({#(f): // DL_FUNC_NAME_1-DAG: Decl[InstanceMethod]/CurrNominal: .flatMap({#(f): @@ -470,7 +471,7 @@ func testAnyObject11_(dl: AnyObject) { func testAnyObject12(dl: AnyObject) { dl.returnsObjcClass.#^DL_FUNC_NAME_DOT_1^# } -// FIXME: it wolud be nice if we produced a call pattern here. +// FIXME: it would be nice if we produced a call pattern here. // DL_FUNC_NAME_DOT_1: Begin completions // DL_FUNC_NAME_DOT_1-DAG: Decl[InstanceMethod]/CurrNominal: map({#(f): // DL_FUNC_NAME_DOT_1-DAG: Decl[InstanceMethod]/CurrNominal: flatMap({#(f): diff --git a/test/IDE/complete_expr_tuple.swift b/test/IDE/complete_expr_tuple.swift index 4ddf870c7c7e0..93e309ac9dae4 100644 --- a/test/IDE/complete_expr_tuple.swift +++ b/test/IDE/complete_expr_tuple.swift @@ -27,27 +27,45 @@ func testTupleNoDot1() { var t = (1, 2.0) t#^TUPLE_NO_DOT_1^# } -// TUPLE_NO_DOT_1: Begin completions, 2 items -// TUPLE_NO_DOT_1-NEXT: Pattern/CurrNominal: .0[#Int#]{{; name=.+$}} -// TUPLE_NO_DOT_1-NEXT: Pattern/CurrNominal: .1[#Double#]{{; name=.+$}} +// TUPLE_NO_DOT_1: Begin completions, 8 items +// TUPLE_NO_DOT_1-DAG: Pattern/CurrNominal: .0[#Int#]{{; name=.+$}} +// TUPLE_NO_DOT_1-DAG: Pattern/CurrNominal: .1[#Double#]{{; name=.+$}} +// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: <= {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: >= {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: < {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}} // TUPLE_NO_DOT_1-NEXT: End completions func testTupleNoDot2() { var t = (foo: 1, bar: 2.0) t#^TUPLE_NO_DOT_2^# } -// TUPLE_NO_DOT_2: Begin completions, 2 items -// TUPLE_NO_DOT_2-NEXT: Pattern/CurrNominal: .foo[#Int#]{{; name=.+$}} -// TUPLE_NO_DOT_2-NEXT: Pattern/CurrNominal: .bar[#Double#]{{; name=.+$}} +// TUPLE_NO_DOT_2: Begin completions, 8 items +// TUPLE_NO_DOT_2-DAG: Pattern/CurrNominal: .foo[#Int#]{{; name=.+$}} +// TUPLE_NO_DOT_2-DAG: Pattern/CurrNominal: .bar[#Double#]{{; name=.+$}} +// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: <= {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: >= {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: < {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}} // TUPLE_NO_DOT_2-NEXT: End completions func testTupleNoDot3() { var t = (foo: 1, 2.0) t#^TUPLE_NO_DOT_3^# } -// TUPLE_NO_DOT_3: Begin completions, 2 items -// TUPLE_NO_DOT_3-NEXT: Pattern/CurrNominal: .foo[#Int#]{{; name=.+$}} -// TUPLE_NO_DOT_3-NEXT: Pattern/CurrNominal: .1[#Double#]{{; name=.+$}} +// TUPLE_NO_DOT_3: Begin completions, 8 items +// TUPLE_NO_DOT_3-DAG: Pattern/CurrNominal: .foo[#Int#]{{; name=.+$}} +// TUPLE_NO_DOT_3-DAG: Pattern/CurrNominal: .1[#Double#]{{; name=.+$}} +// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: <= {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: >= {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: < {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}} +// TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}} // TUPLE_NO_DOT_3-NEXT: End completions func testTupleDot1() { diff --git a/test/IDE/complete_import.swift b/test/IDE/complete_import.swift index 2c1d7d6c7d952..8c7d33a38c21a 100644 --- a/test/IDE/complete_import.swift +++ b/test/IDE/complete_import.swift @@ -1,6 +1,10 @@ // RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_IMPORT1 | FileCheck %s -check-prefix=CLANG_IMPORT1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_IMPORT2 | FileCheck %s -check-prefix=CLANG_IMPORT2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_IMPORT3 | FileCheck %s -check-prefix=CLANG_IMPORT3 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_IMPORT4 | FileCheck %s -check-prefix=CLANG_IMPORT4 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_IMPORT5 | FileCheck %s -check-prefix=CLANG_IMPORT5 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_IMPORT6 | FileCheck %s -check-prefix=CLANG_IMPORT6 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -F %S/Inputs/mock-sdk -code-completion-token=CLANG_IMPORT7 | FileCheck %s -check-prefix=CLANG_IMPORT7 // REQUIRES: objc_interop @@ -26,3 +30,15 @@ import Foo.#^CLANG_IMPORT3^# // CLANG_IMPORT3: Begin completions // CLANG_IMPORT3-NEXT: Decl[Module]/OtherModule[FooSub]/NotRecommended: FooSub[#Module#]; name=FooSub + +import Foo#^CLANG_IMPORT4^# +// CLANG_IMPORT4-NOT: Begin completions + +import Foo #^CLANG_IMPORT5^# +// CLANG_IMPORT5: Begin completions + +import Foo.FooSub#^CLANG_IMPORT6^# +// CLANG_IMPORT6-NOT: Begin completions + +import Foo.FooSub #^CLANG_IMPORT7^# +// CLANG_IMPORT7: Begin completions diff --git a/test/IDE/complete_in_closures.swift b/test/IDE/complete_in_closures.swift index 5c1482b23c33e..f615937ee4c54 100644 --- a/test/IDE/complete_in_closures.swift +++ b/test/IDE/complete_in_closures.swift @@ -313,7 +313,7 @@ struct LazyVar3 { } func closureTaker(theFunc:(theValue:Int) -> ()) {} -func closureTaker2(theFunc: (Value1:Int, Value2:Int) ->()) {} +func closureTaker2(theFunc: (Value1:Int, Value2:Int) -> ()) {} func testClosureParam1() { closureTaker { (theValue) -> () in #^CLOSURE_PARAM_1^# diff --git a/test/IDE/complete_literal.swift b/test/IDE/complete_literal.swift index 85b46a5231713..43a1e4e8c02c1 100644 --- a/test/IDE/complete_literal.swift +++ b/test/IDE/complete_literal.swift @@ -2,6 +2,7 @@ // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LITERAL2 | FileCheck %s -check-prefix=LITERAL2 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LITERAL3 | FileCheck %s -check-prefix=LITERAL3 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LITERAL4 | FileCheck %s -check-prefix=LITERAL4 +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=LITERAL5 | FileCheck %s -check-prefix=LITERAL5 { 1.#^LITERAL1^# @@ -48,3 +49,14 @@ // LITERAL4-DAG: Decl[InstanceMethod]/CurrNominal: insertContentsOf({#(newElements): S#}, {#at: Index#})[#Void#]; name=insertContentsOf(newElements: S, at: Index){{$}} // LITERAL4-DAG: Decl[InstanceMethod]/CurrNominal: removeAtIndex({#(i): Index#})[#Character#]; name=removeAtIndex(i: Index){{$}} // LITERAL4-DAG: Decl[InstanceVar]/CurrNominal: lowercaseString[#String#]; name=lowercaseString{{$}} + +func giveMeAString() -> Int { + // rdar://22637799 + return "Here's a string".#^LITERAL5^# // try .characters.count here +} + +// LITERAL5-DAG: Decl[InstanceVar]/CurrNominal: characters[#String.CharacterView#]{{; name=.+$}} +// LITERAL5-DAG: Decl[InstanceVar]/CurrNominal: endIndex[#Index#]{{; name=.+$}} +// LITERAL5-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: reserveCapacity({#(n): Int#})[#Void#]{{; name=.+$}} +// LITERAL5-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: append({#(c): Character#})[#Void#]{{; name=.+$}} +// LITERAL5-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Invalid]: appendContentsOf({#(newElements): S#})[#Void#]{{; name=.+$}} diff --git a/test/IDE/complete_member_decls_from_parent_decl_context.swift b/test/IDE/complete_member_decls_from_parent_decl_context.swift index 804465bb01558..faeb1ef23eb27 100644 --- a/test/IDE/complete_member_decls_from_parent_decl_context.swift +++ b/test/IDE/complete_member_decls_from_parent_decl_context.swift @@ -59,7 +59,7 @@ class CodeCompletionInClassMethods1 { struct NestedStruct {} class NestedClass {} enum NestedEnum {} - // Can not declare a nested protocol. + // Cannot declare a nested protocol. // protocol NestedProtocol {} typealias NestedTypealias = Int @@ -162,7 +162,7 @@ struct CodeCompletionInStructMethods1 { struct NestedStruct {} class NestedClass {} enum NestedEnum {} - // Can not declare a nested protocol. + // Cannot declare a nested protocol. // protocol NestedProtocol {} typealias NestedTypealias = Int diff --git a/test/IDE/complete_stmt_controlling_expr.swift b/test/IDE/complete_stmt_controlling_expr.swift index fda29d6f9da26..c85d2edae03fa 100644 --- a/test/IDE/complete_stmt_controlling_expr.swift +++ b/test/IDE/complete_stmt_controlling_expr.swift @@ -15,7 +15,8 @@ // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=COND_WHILE_3 | FileCheck %s -check-prefix=COND_COMMON // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=COND_WHILE_4 | FileCheck %s -check-prefix=COND_COMMON -// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=COND_DO_WHILE_1 | FileCheck %s -check-prefix=COND_COMMON +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=COND_DO_WHILE_1 | FileCheck %s -check-prefix=COND-WITH-RELATION +// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=COND_DO_WHILE_2 | FileCheck %s -check-prefix=COND-WITH-RELATION1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=C_STYLE_FOR_INIT_1 | FileCheck %s -check-prefix=COND_COMMON // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=C_STYLE_FOR_INIT_2 | FileCheck %s -check-prefix=COND_COMMON @@ -119,6 +120,8 @@ struct FooStruct { var instanceVar : Int init(_: Int = 0) { } + func boolGen() -> Bool { return false } + func intGen() -> Int { return 1 } } func testIf1(fooObject: FooStruct) { @@ -228,6 +231,13 @@ func testRepeatWhile1(fooObject: FooStruct) { } while #^COND_DO_WHILE_1^# } +func testRepeatWhile2(fooObject: FooStruct) { + var localInt = 42 + var localFooObject = FooStruct(localInt) + repeat { + } while localFooObject.#^COND_DO_WHILE_2^# +} + func testCStyleForInit1(fooObject: FooStruct) { var localInt = 42 var localFooObject = FooStruct(localInt) @@ -456,6 +466,24 @@ func testSwitchCaseWhereExprIJ1(fooObject: FooStruct) { // COND_COMMON-DAG: Decl[Struct]/CurrModule: FooStruct[#FooStruct#]{{; name=.+$}} // COND_COMMON: End completions +// COND-WITH-RELATION: Begin completions +// COND-WITH-RELATION-DAG: Literal[Boolean]/None/TypeRelation[Identical]: true[#Bool#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Literal[Boolean]/None/TypeRelation[Identical]: false[#Bool#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Decl[LocalVar]/Local: fooObject[#FooStruct#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Decl[LocalVar]/Local: localInt[#Int#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Decl[LocalVar]/Local: localFooObject[#FooStruct#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Decl[Struct]/CurrModule: FooStruct[#FooStruct#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Decl[FreeFunction]/CurrModule/TypeRelation[Invalid]: testIf2({#(fooObject): FooStruct#})[#Void#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Decl[FreeFunction]/CurrModule/TypeRelation[Invalid]: testWhile3({#(fooObject): FooStruct#})[#Void#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Decl[FreeFunction]/CurrModule/TypeRelation[Invalid]: testIfElseIf5({#(fooObject): FooStruct#})[#Void#]{{; name=.+$}} +// COND-WITH-RELATION-DAG: Decl[FreeFunction]/CurrModule/TypeRelation[Invalid]: testCStyleForIncrIE1({#(fooObject): FooStruct#})[#Void#]{{; name=.+$}} + +// COND-WITH-RELATION1: Begin completions +// COND-WITH-RELATION1-DAG: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}} +// COND-WITH-RELATION1-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Identical]: boolGen()[#Bool#]{{; name=.+$}} +// COND-WITH-RELATION1-DAG: Decl[InstanceMethod]/CurrNominal: intGen()[#Int#]{{; name=.+$}} +// COND-WITH-RELATION1: End completions + // WITH_I_INT_LOCAL: Decl[LocalVar]/Local: i[#Int#]{{; name=.+$}} // WITH_I_INT_EXPR_SPECIFIC: Decl[LocalVar]/ExprSpecific: i[#Int#]{{; name=.+$}} diff --git a/test/IDE/complete_unresolved_members.swift b/test/IDE/complete_unresolved_members.swift index 7c938d0a96114..b8ff38cbfc753 100644 --- a/test/IDE/complete_unresolved_members.swift +++ b/test/IDE/complete_unresolved_members.swift @@ -49,7 +49,7 @@ enum SomeEnum3 { } struct NotOptions1 { - static let NotSet = 1; + static let NotSet = 1 } struct SomeOptions1 : OptionSetType { @@ -178,7 +178,7 @@ OptionSetTaker6(.Option4, .#^UNRESOLVED_17^#,) var a = {() in OptionSetTaker5([.#^UNRESOLVED_18^#], .Option4, .South, .West) } -var Containner = OptionTakerContainer1() +var Container = OptionTakerContainer1() Container.OptionSetTaker1(.#^UNRESOLVED_19^# Container.EnumTaker1(.#^UNRESOLVED_20^# diff --git a/test/IDE/complete_value_expr.swift b/test/IDE/complete_value_expr.swift index 9959f9f133f1c..c42c03868c8b9 100644 --- a/test/IDE/complete_value_expr.swift +++ b/test/IDE/complete_value_expr.swift @@ -188,7 +188,7 @@ struct FooStruct { mutating func instanceFunc6() -> Int! {} mutating - func instanceFunc7(#a: Int) {} + func instanceFunc7(a a: Int) {} mutating func instanceFunc8(a: (Int, Int)) {} mutating @@ -271,7 +271,7 @@ struct FooStruct { struct NestedStruct {} class NestedClass {} enum NestedEnum {} - // Can not declare a nested protocol. + // Cannot declare a nested protocol. // protocol NestedProtocol {} typealias NestedTypealias = Int @@ -769,7 +769,7 @@ func testInsideFunctionCall1() { var a = FooStruct() a.instanceFunc0(#^INSIDE_FUNCTION_CALL_1^# // There should be no other results here because the function call -// unambigously resolves to overload that takes 0 arguments. +// unambiguously resolves to overload that takes 0 arguments. // INSIDE_FUNCTION_CALL_1: Begin completions // INSIDE_FUNCTION_CALL_1-NEXT: Pattern/ExprSpecific: ['('])[#Void#]{{; name=.+$}} // INSIDE_FUNCTION_CALL_1-NEXT: End completions @@ -789,7 +789,7 @@ func testInsideFunctionCall3() { FooStruct().instanceFunc1(42, #^INSIDE_FUNCTION_CALL_3^# // INSIDE_FUNCTION_CALL_3: Begin completions // FIXME: There should be no results here because the function call -// unambigously resolves to overload that takes 1 argument. +// unambiguously resolves to overload that takes 1 argument. // INSIDE_FUNCTION_CALL_3-DAG: Decl[GlobalVar]/CurrModule: fooObject[#FooStruct#]{{; name=.+$}} // INSIDE_FUNCTION_CALL_3: End completions } @@ -1368,11 +1368,11 @@ func testResolveGenericParamsError1() { class BuilderStyle { var count = 0 func addString(s: String) -> BuilderStyle { - count++ + count += 1 return self } func add(t: T) -> BuilderStyle { - count++ + count += 1 return self } func get() -> Int { diff --git a/test/IDE/complete_vararg.swift b/test/IDE/complete_vararg.swift index eeef80632b717..753452b39fdc2 100644 --- a/test/IDE/complete_vararg.swift +++ b/test/IDE/complete_vararg.swift @@ -11,23 +11,23 @@ // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GENERIC_FREE_FUNC_1 | FileCheck %s -check-prefix=GENERIC_FREE_FUNC_1 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INTERESTING_TYPE_1 | FileCheck %s -check-prefix=INTERESTING_TYPE_1 -func freeFunc1(#x: Int...) { } -func freeFunc2(#x: Int, #y: Int...) { } -func freeFunc3(#w: Int...)(#x: Int...) { } +func freeFunc1(x x: Int...) { } +func freeFunc2(x x: Int, y y: Int...) { } +func freeFunc3(w w: Int...)(x x: Int...) { } class C { init(x: Int...) { } - func method1(#x: Int...) { } - func method2(#x: Int, y: Int...) { } - func method3(#w: Int...)(#x: Int...) { } - func method4(#`do` : Int...) {} + func method1(x x: Int...) { } + func method2(x x: Int, y: Int...) { } + func method3(w w: Int...)(x x: Int...) { } + func method4(`do` `do` : Int...) {} func method5(`class` : Int...) {} func method6(`class` `protocol`: Int...) {} subscript(i: Int...) -> Int { return 0 } } -func genericFreeFunc1(#t: T...) { } -func interestingType1(#x: (Int, (Int, String))...) { } +func genericFreeFunc1(t t: T...) { } +func interestingType1(x x: (Int, (Int, String))...) { } func testTopLevel() { #^TOP_LEVEL_1^# diff --git a/test/IDE/dump_api.swift b/test/IDE/dump_api.swift deleted file mode 100644 index f1adbd2c98770..0000000000000 --- a/test/IDE/dump_api.swift +++ /dev/null @@ -1,1005 +0,0 @@ -//===--- dump_api.swift ---------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// -// RUN: %target-swift-ide-test -dump-api -source-filename %s > %t.swift -// RUN: diff -du %S/Inputs/dumped_api.swift %t.swift - -//===--- Definitions needed only while experimental -----------------------===// -internal typealias _ContiguousArrayStorageBase = AnyObject -public struct _Distance {} -public struct _InitializeTo {} -extension _InitializeTo { init() {} } -extension _ContiguousArrayBuffer { - var _storage: _ContiguousArrayStorageBase { return owner } - init(_ owner: _ContiguousArrayStorageBase) { - self = unsafeBitCast(owner, _ContiguousArrayBuffer.self) - } -} - -//===----------------------------------------------------------------------===// - - -@noreturn @inline(never) -internal func _abstract(file: StaticString = __FILE__, line: UWord = __LINE__) { - fatalError("Method must be overridden", file: file, line: line) -} - -//===--- Generator --------------------------------------------------------===// -//===----------------------------------------------------------------------===// - -public class _AnyGeneratorBase {} - -/// An abstract `GeneratorType` base class over `T` elements. -/// -/// Use this as a `Sequence`'s associated `Generator` type when you -/// don't want to expose details of the concrete generator, a subclass. -/// -/// It is an error to create instances of `AnyGenerator` that are not -/// also instances of an `AnyGenerator` subclass. -/// -/// See also: -/// -/// struct AnySequence -/// func anyGenerator(base: G) -> AnyGenerator -/// func anyGenerator(nextImplementation: ()->T?) -> AnyGenerator -public class AnyGenerator : _AnyGeneratorBase, GeneratorType { - /// Initialize the instance. May only be called from a subclass - /// initializer. - override public init() { - super.init() - _debugPrecondition( - _typeID(self) != unsafeBitCast(AnyGenerator.self, ObjectIdentifier.self), - "AnyGenerator instances can not be created; create a subclass instance instead." - ) - } - - /// Advance to the next element and return it, or `nil` if no next - /// element exists. - /// - /// Note: subclasses must override this method. - public func next() -> T? {_abstract()} -} - -/// Every `GeneratorType` can also be a `SequenceType`. Note that -/// traversing the sequence consumes the generator. -extension AnyGenerator : SequenceType { - /// Returns `self`. - public func generate() -> AnyGenerator { return self } -} - -/// Return a `GeneratorType` instance that wraps `base` but whose type -/// depends only on the type of `G.Element`. -/// -/// Example: -/// -/// func countStrings() -> AnyGenerator { -/// let lazyStrings = lazy(0..<10).map { String($0) } -/// -/// // This is a really complicated type of no interest to our -/// // clients. -/// let g: MapSequenceGenerator, String> -/// = lazyStrings.generate() -/// return anyGenerator(g) -/// } -public func anyGenerator(base: G) -> AnyGenerator { - return _GeneratorBox(base) -} - -internal class _FunctionGenerator : AnyGenerator { - init(_ nextImplementation: ()->T?) { - self.nextImplementation = nextImplementation - } - override func next() -> T? { return nextImplementation() } - let nextImplementation: ()->T? -} - -/// Return a `GeneratorType` instance whose `next` method invokes -/// `nextImplementation` and returns the result. -/// -/// Example: -/// -/// var x = 7 -/// let g = anyGenerator { x < 15 ? x++ : nil } -/// let a = Array(g) // [ 7, 8, 9, 10, 11, 12, 13, 14 ] -public func anyGenerator(nextImplementation: ()->T?) -> AnyGenerator { - return _FunctionGenerator(nextImplementation) -} - -internal final class _GeneratorBox< - Base: GeneratorType -> : AnyGenerator { - init(_ base: Base) { self.base = base } - override func next() -> Base.Element? { return base.next() } - var base: Base -} - -internal func _typeID(instance: AnyObject) -> ObjectIdentifier { - return ObjectIdentifier(instance.dynamicType) -} - -//===--- Sequence ---------------------------------------------------------===// -//===----------------------------------------------------------------------===// - -internal class _AnySequenceBox { - // FIXME: can't make _AnySequenceBox generic and return - // _AnyGenerator here due to - func generate() -> _AnyGeneratorBase {_abstract()} - - func _underestimateCount() -> Int {_abstract()} - // FIXME: can't traffic in UnsafeMutablePointer and - // _ContiguousArrayBuffer here due to - func _initializeTo(ptr: UnsafeMutablePointer) {_abstract()} - func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase {_abstract()} -} - -internal class _AnyCollectionBoxBase : _AnySequenceBox { - init(startIndex: _ForwardIndexBoxType, endIndex: _ForwardIndexBoxType) { - self.startIndex = startIndex - self.endIndex = endIndex - } - let startIndex: _ForwardIndexBoxType - let endIndex: _ForwardIndexBoxType -} - -// FIXME: can't make this a protocol due to -internal class _SequenceBox - : _AnySequenceBox { - typealias Element = S.Generator.Element - - override func generate() -> _AnyGeneratorBase { - return _GeneratorBox(_base.generate()) - } - override func _underestimateCount() -> Int { - return Swift.underestimateCount(_base) - } - override func _initializeTo(ptr: UnsafeMutablePointer) { - _base~>(_InitializeTo(), UnsafeMutablePointer(ptr)) - } - override func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { - return _base._copyToNativeArrayBuffer()._storage - } - init(_ base: S) { - self._base = base - } - internal var _base: S -} -// FIXME: can't make this a protocol due to -internal class _CollectionBox - : _AnyCollectionBox { - typealias Element = S.Generator.Element - - override func generate() -> _AnyGeneratorBase { - fatalError("") - } - override func _underestimateCount() -> Int { - return Swift.underestimateCount(_base) - } - override func _initializeTo(ptr: UnsafeMutablePointer) { - _base~>(_InitializeTo(), UnsafeMutablePointer(ptr)) - } - override func _copyToNativeArrayBuffer() -> _ContiguousArrayStorageBase { - return _base._copyToNativeArrayBuffer()._storage - } - override func _count() -> IntMax { - return 0 - } - override subscript(position: _ForwardIndexBoxType) -> Element { - if let i = position._unbox() as S.Index? { - return _base[i] - } - fatalError("Index type mismatch!") - } - init( - _ base: S, - startIndex: _ForwardIndexBoxType, - endIndex: _ForwardIndexBoxType - ) { - self._base = base - super.init(startIndex: startIndex, endIndex: endIndex) - } - internal var _base: S -} - -/// A type-erased sequence. -/// -/// Forwards operations to an arbitrary underlying sequence having the -/// same `Element` type, hiding the specifics of the underlying -/// `SequenceType`. -/// -/// See also: `AnyGenerator`. -public struct AnySequence : SequenceType { - typealias Element = T - - /// Wrap and forward operations to to `base` - public init(_ base: S) { - _box = _SequenceBox(base) - } - - /// Return a *generator* over the elements of this *sequence*. - /// - /// Complexity: O(1) - public func generate() -> AnyGenerator { - return unsafeDowncast(_box.generate()) - } - - internal let _box: _AnySequenceBox -} - -public func ~> ( - source: AnySequence, - ptr: (_InitializeTo, UnsafeMutablePointer) -) { - source._box._initializeTo(UnsafeMutablePointer(ptr.1)) -} - -extension AnySequence { - public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer { - return _ContiguousArrayBuffer(self._box._copyToNativeArrayBuffer()) - } -} - -public func ~> ( - source: AnyForwardCollection, - ptr: (_InitializeTo, UnsafeMutablePointer) -) { - source._box._initializeTo(UnsafeMutablePointer(ptr.1)) -} - -extension AnyForwardCollection { - public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer { - return _ContiguousArrayBuffer(self._box._copyToNativeArrayBuffer()) - } -} - -public func ~> ( - source: AnyBidirectionalCollection, - ptr: (_InitializeTo, UnsafeMutablePointer) -) { - source._box._initializeTo(UnsafeMutablePointer(ptr.1)) -} - -extension AnyBidirectionalCollection { - public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer { - return _ContiguousArrayBuffer(self._box._copyToNativeArrayBuffer()) - } -} - -public func ~> ( - source: AnyRandomAccessCollection, - ptr: (_InitializeTo, UnsafeMutablePointer) -) { - source._box._initializeTo(UnsafeMutablePointer(ptr.1)) -} - -extension AnyRandomAccessCollection { - public func _copyToNativeArrayBuffer() -> _ContiguousArrayBuffer { - return _ContiguousArrayBuffer(self._box._copyToNativeArrayBuffer()) - } -} - -//===--- ForwardIndex -----------------------------------------------------===// -//===----------------------------------------------------------------------===// - -internal protocol _ForwardIndexBoxType : class { - var typeID: ObjectIdentifier {get} - func successor() -> _ForwardIndexBoxType - func equals(other: _ForwardIndexBoxType) -> Bool - func _unbox() -> T? - func _distanceTo(other: _ForwardIndexBoxType) -> AnyForwardIndex.Distance - // FIXME: Can't return Self from _advancedBy pending - func _advancedBy(distance: AnyForwardIndex.Distance) -> _ForwardIndexBoxType - func _advancedBy( - distance: AnyForwardIndex.Distance, - _ limit: _ForwardIndexBoxType - ) -> _ForwardIndexBoxType -} - -internal class _ForwardIndexBox< - BaseIndex: ForwardIndexType -> : _ForwardIndexBoxType { - required init(_ base: BaseIndex) { - self.base = base - } - - func successor() -> _ForwardIndexBoxType { - return self.dynamicType(self.base.successor()) - } - - func unsafeUnbox(other: _ForwardIndexBoxType) -> BaseIndex { - return (unsafeDowncast(other) as _ForwardIndexBox).base - } - - func equals(other: _ForwardIndexBoxType) -> Bool { - return base == unsafeUnbox(other) - } - - func _distanceTo(other: _ForwardIndexBoxType) -> AnyForwardIndex.Distance { - return numericCast(distance(base, unsafeUnbox(other))) - } - - func _advancedBy(n: AnyForwardIndex.Distance) -> _ForwardIndexBoxType { - return self.dynamicType(advance(base, numericCast(n))) - } - - func _advancedBy( - n: AnyForwardIndex.Distance, - _ limit: _ForwardIndexBoxType - ) -> _ForwardIndexBoxType { - return self.dynamicType(advance(base, numericCast(n), unsafeUnbox(limit))) - } - - func _unbox() -> T? { - if T.self is BaseIndex.Type { - _sanityCheck(BaseIndex.self is T.Type) - // This bit cast is really nothing as we have proven they are - // the same type. - return unsafeBitCast(base, T.self) - } - return nil - } - - var typeID: ObjectIdentifier { return _typeID(self) } - - internal // private - let base: BaseIndex -} - -//===--- BidirectionalIndex -----------------------------------------------===// -//===----------------------------------------------------------------------===// - -internal protocol _BidirectionalIndexBoxType : _ForwardIndexBoxType { - func predecessor() -> _BidirectionalIndexBoxType -} - -internal class _BidirectionalIndexBox< - BaseIndex: BidirectionalIndexType -> : _ForwardIndexBox, _BidirectionalIndexBoxType { - required init(_ base: BaseIndex) { - super.init(base) - } - - override func successor() -> _ForwardIndexBoxType { - return self.dynamicType(self.base.successor()) - } - - func predecessor() -> _BidirectionalIndexBoxType { - return self.dynamicType(self.base.predecessor()) - } -} - -//===--- RandomAccessIndex -----------------------------------------------===// -//===----------------------------------------------------------------------===// - -internal protocol _RandomAccessIndexBoxType : _BidirectionalIndexBoxType {} - -internal final class _RandomAccessIndexBox< - BaseIndex: RandomAccessIndexType -> : _BidirectionalIndexBox, _RandomAccessIndexBoxType { - required init(_ base: BaseIndex) { - super.init(base) - } -} - -//===--- All Index Protocols ----------------------------------------------===// -//===----------------------------------------------------------------------===// - - -/// A wrapper over an underlying `ForwardIndexType` that hides -/// the specific underlying type. -/// -/// See also: `AnyForwardCollection` -public struct AnyForwardIndex : ForwardIndexType { - public typealias Distance = IntMax - - /// Wrap and forward operations to `base`. - public init(_ base: BaseIndex) { - _box = _ForwardIndexBox(base) - } - - /// Return the next consecutive value in a discrete sequence of - /// `AnyForwardIndex` values. - /// - /// Requires: `self` has a well-defined successor. - public func successor() -> AnyForwardIndex { - return AnyForwardIndex(_box.successor()) - } - - - - //===--- private --------------------------------------------------------===// - - internal var _typeID: ObjectIdentifier { - return _box.typeID - } - - internal init(_ box: _ForwardIndexBoxType) { - self._box = box - } - - internal let _box: _ForwardIndexBoxType -} - -public func ~> ( - start: AnyForwardIndex, other : (_Distance, AnyForwardIndex) -) -> AnyForwardIndex.Distance { - precondition( - start._typeID == other.1._typeID, - "distance: base index types differ.") - return start._box._distanceTo(other.1._box) -} - -public func ~> ( - start: AnyForwardIndex, distance : (_Advance, AnyForwardIndex.Distance) -) -> AnyForwardIndex { - return AnyForwardIndex(start._box._advancedBy(distance.1)) -} - -public func ~> ( - start: AnyForwardIndex, - args: (_Advance, (AnyForwardIndex.Distance, AnyForwardIndex)) -) -> AnyForwardIndex { - precondition( - start._typeID == args.1.1._typeID, "advance: base index types differ.") - return AnyForwardIndex(start._box._advancedBy(args.1.0, args.1.1._box)) -} - -/// Return true iff `lhs` and `rhs` wrap equal underlying -/// `AnyForwardIndex`s. -/// -/// Requires: the types of indices wrapped by `lhs` and `rhs` are -/// identical. -public func == (lhs: AnyForwardIndex, rhs: AnyForwardIndex) -> Bool { - precondition(lhs._typeID == rhs._typeID, "base index types differ.") - return lhs._box.equals(rhs._box) -} - -/// A wrapper over an underlying `BidirectionalIndexType` that hides -/// the specific underlying type. -/// -/// See also: `AnyBidirectionalCollection` -public struct AnyBidirectionalIndex : BidirectionalIndexType { - public typealias Distance = IntMax - - /// Wrap and forward operations to `base`. - public init(_ base: BaseIndex) { - _box = _BidirectionalIndexBox(base) - } - - /// Return the next consecutive value in a discrete sequence of - /// `AnyBidirectionalIndex` values. - /// - /// Requires: `self` has a well-defined successor. - public func successor() -> AnyBidirectionalIndex { - return AnyBidirectionalIndex(_box.successor()) - } - - /// Return the previous consecutive value in a discrete sequence of - /// `AnyBidirectionalIndex` values. - /// - /// Requires: `self` has a well-defined predecessor. - public func predecessor() -> AnyBidirectionalIndex { - return AnyBidirectionalIndex(_box.predecessor()) - } - - - //===--- private --------------------------------------------------------===// - - internal var _typeID: ObjectIdentifier { - return _box.typeID - } - - internal init(_ box: _ForwardIndexBoxType) { - self._box = box as! _BidirectionalIndexBoxType - } - - internal let _box: _BidirectionalIndexBoxType -} - -public func ~> ( - start: AnyBidirectionalIndex, other : (_Distance, AnyBidirectionalIndex) -) -> AnyBidirectionalIndex.Distance { - precondition( - start._typeID == other.1._typeID, - "distance: base index types differ.") - return start._box._distanceTo(other.1._box) -} - -public func ~> ( - start: AnyBidirectionalIndex, distance : (_Advance, AnyBidirectionalIndex.Distance) -) -> AnyBidirectionalIndex { - return AnyBidirectionalIndex(start._box._advancedBy(distance.1)) -} - -public func ~> ( - start: AnyBidirectionalIndex, - args: (_Advance, (AnyBidirectionalIndex.Distance, AnyBidirectionalIndex)) -) -> AnyBidirectionalIndex { - precondition( - start._typeID == args.1.1._typeID, "advance: base index types differ.") - return AnyBidirectionalIndex(start._box._advancedBy(args.1.0, args.1.1._box)) -} - -/// Return true iff `lhs` and `rhs` wrap equal underlying -/// `AnyBidirectionalIndex`s. -/// -/// Requires: the types of indices wrapped by `lhs` and `rhs` are -/// identical. -public func == (lhs: AnyBidirectionalIndex, rhs: AnyBidirectionalIndex) -> Bool { - precondition(lhs._typeID == rhs._typeID, "base index types differ.") - return lhs._box.equals(rhs._box) -} - -/// A wrapper over an underlying `RandomAccessIndexType` that hides -/// the specific underlying type. -/// -/// See also: `AnyRandomAccessCollection` -public struct AnyRandomAccessIndex : RandomAccessIndexType { - public typealias Distance = IntMax - - /// Wrap and forward operations to `base`. - public init(_ base: BaseIndex) { - _box = _RandomAccessIndexBox(base) - } - - /// Return the next consecutive value in a discrete sequence of - /// `AnyRandomAccessIndex` values. - /// - /// Requires: `self` has a well-defined successor. - public func successor() -> AnyRandomAccessIndex { - return AnyRandomAccessIndex(_box.successor()) - } - - /// Return the previous consecutive value in a discrete sequence of - /// `AnyRandomAccessIndex` values. - /// - /// Requires: `self` has a well-defined predecessor. - public func predecessor() -> AnyRandomAccessIndex { - return AnyRandomAccessIndex(_box.predecessor()) - } - - /// Return the minimum number of applications of `successor` or - /// `predecessor` required to reach `other` from `self`. - /// - /// Requires: `self` and `other` wrap instances of the same type. - public func distanceTo(other: AnyRandomAccessIndex) -> Distance { - return _box._distanceTo(other._box) - } - - /// Return `self` offset by `n` steps. - /// - /// - Returns: If `n > 0`, the result of applying `successor` to - /// `self` `n` times. If `n < 0`, the result of applying - /// `predecessor` to `self` `n` times. Otherwise, `self`. - public func advancedBy(amount: Distance) -> AnyRandomAccessIndex { - return AnyRandomAccessIndex(_box._advancedBy(amount)) - } - - //===--- private --------------------------------------------------------===// - - internal var _typeID: ObjectIdentifier { - return _box.typeID - } - - internal init(_ box: _ForwardIndexBoxType) { - self._box = box as! _RandomAccessIndexBoxType - } - - internal let _box: _RandomAccessIndexBoxType -} - -public func ~> ( - start: AnyRandomAccessIndex, other : (_Distance, AnyRandomAccessIndex) -) -> AnyRandomAccessIndex.Distance { - precondition( - start._typeID == other.1._typeID, - "distance: base index types differ.") - return start._box._distanceTo(other.1._box) -} - -public func ~> ( - start: AnyRandomAccessIndex, distance : (_Advance, AnyRandomAccessIndex.Distance) -) -> AnyRandomAccessIndex { - return AnyRandomAccessIndex(start._box._advancedBy(distance.1)) -} - -public func ~> ( - start: AnyRandomAccessIndex, - args: (_Advance, (AnyRandomAccessIndex.Distance, AnyRandomAccessIndex)) -) -> AnyRandomAccessIndex { - precondition( - start._typeID == args.1.1._typeID, "advance: base index types differ.") - return AnyRandomAccessIndex(start._box._advancedBy(args.1.0, args.1.1._box)) -} - -/// Return true iff `lhs` and `rhs` wrap equal underlying -/// `AnyRandomAccessIndex`s. -/// -/// Requires: the types of indices wrapped by `lhs` and `rhs` are -/// identical. -public func == (lhs: AnyRandomAccessIndex, rhs: AnyRandomAccessIndex) -> Bool { - precondition(lhs._typeID == rhs._typeID, "base index types differ.") - return lhs._box.equals(rhs._box) -} - -//===--- Collections ------------------------------------------------------===// -//===----------------------------------------------------------------------===// - -internal class _AnyCollectionBox : _AnyCollectionBoxBase { - subscript(_ForwardIndexBoxType) -> Element {_abstract()} - func _count() -> IntMax {_abstract()} - - // FIXME: should be inherited, but a known bug prevents it since - // this class is generic. - override init( - startIndex: _ForwardIndexBoxType, - endIndex: _ForwardIndexBoxType - ) { - super.init(startIndex: startIndex, endIndex: endIndex) - } -} - -/// A protocol for `AnyForwardCollection`, -/// `AnyBidirectionalCollection`, and -/// `AnyRandomAccessCollection`. -/// -/// This protocol can be considered an implementation detail of the -/// `===` and `!==` implementations for these types. -public protocol AnyCollectionType : CollectionType { - /// Identifies the underlying collection stored by `self`. Instances - /// copied from one another have the same `underlyingCollectionID`. - var underlyingCollectionID: ObjectIdentifier {get} -} - -/// Return true iff `lhs` and `rhs` store the same underlying collection. -public func === < - L: AnyCollectionType, R: AnyCollectionType ->(lhs: L, rhs: R) -> Bool { - return lhs.underlyingCollectionID == rhs.underlyingCollectionID -} - -/// Return false iff `lhs` and `rhs` store the same underlying collection. -public func !== < - L: AnyCollectionType, R: AnyCollectionType ->(lhs: L, rhs: R) -> Bool { - return lhs.underlyingCollectionID != rhs.underlyingCollectionID -} - -/// A type-erased wrapper over any collection with at least -/// forward indices. -/// -/// Forwards operations to an arbitrary underlying collection having the -/// same `Element` type, hiding the specifics of the underlying -/// `CollectionType`. -/// -/// See also: `AnyBidirectionalType`, `AnyRandomAccessType` -public struct AnyForwardCollection : AnyCollectionType { - typealias Box = _AnyCollectionBox - - /// Create an `AnyForwardCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: ForwardIndexType, C.Generator.Element == Element - >(_ base: C) { - self._box = _CollectionBox( - base, - startIndex: _ForwardIndexBox(base.startIndex), - endIndex: _ForwardIndexBox(base.endIndex)) - } - - /// Create an `AnyForwardCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyForwardCollection) { - self._box = other._box - } - /// Create an `AnyForwardCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: BidirectionalIndexType, C.Generator.Element == Element - >(_ base: C) { - self._box = _CollectionBox( - base, - startIndex: _BidirectionalIndexBox(base.startIndex), - endIndex: _BidirectionalIndexBox(base.endIndex)) - } - - /// Create an `AnyForwardCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyBidirectionalCollection) { - self._box = other._box - } - /// Create an `AnyForwardCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: RandomAccessIndexType, C.Generator.Element == Element - >(_ base: C) { - self._box = _CollectionBox( - base, - startIndex: _RandomAccessIndexBox(base.startIndex), - endIndex: _RandomAccessIndexBox(base.endIndex)) - } - - /// Create an `AnyForwardCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyRandomAccessCollection) { - self._box = other._box - } - - - /// Return a *generator* over the elements of this *collection*. - /// - /// Complexity: O(1) - public func generate() -> AnyGenerator { - return unsafeDowncast(_box.generate()) - } - - /// The position of the first element in a non-empty collection. - /// - /// Identical to `endIndex` in an empty collection. - public var startIndex: AnyForwardIndex { - return AnyForwardIndex(_box.startIndex) - } - - /// The collection's "past the end" position. - /// - /// `endIndex` is not a valid argument to `subscript`, and is always - /// reachable from `startIndex` by zero or more applications of - /// `successor()`. - public var endIndex: AnyForwardIndex { - return AnyForwardIndex(_box.endIndex) - } - - /// Access the element indicated by `position`. - /// - /// Requires: `position` indicates a valid position in `self` and - /// `position != endIndex`. - public subscript(position: AnyForwardIndex) -> Element { - return _box[position._box] - } - - /// Uniquely identifies the stored underlying collection. - public var underlyingCollectionID: ObjectIdentifier { - return ObjectIdentifier(_box) - } - - internal let _box: Box -} -/// A type-erased wrapper over any collection with at least -/// bidirectional indices. -/// -/// Forwards operations to an arbitrary underlying collection having the -/// same `Element` type, hiding the specifics of the underlying -/// `CollectionType`. -/// -/// See also: `AnyRandomAccessType`, `AnyForwardType` -public struct AnyBidirectionalCollection : AnyCollectionType { - typealias Box = _AnyCollectionBox - - /// Create an `AnyBidirectionalCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: BidirectionalIndexType, C.Generator.Element == Element - >(_ base: C) { - self._box = _CollectionBox( - base, - startIndex: _BidirectionalIndexBox(base.startIndex), - endIndex: _BidirectionalIndexBox(base.endIndex)) - } - - /// Create an `AnyBidirectionalCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyBidirectionalCollection) { - self._box = other._box - } - /// Create an `AnyBidirectionalCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: RandomAccessIndexType, C.Generator.Element == Element - >(_ base: C) { - self._box = _CollectionBox( - base, - startIndex: _RandomAccessIndexBox(base.startIndex), - endIndex: _RandomAccessIndexBox(base.endIndex)) - } - - /// Create an `AnyBidirectionalCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyRandomAccessCollection) { - self._box = other._box - } - - /// If the indices of the underlying collection stored by `other` - /// satisfy `BidirectionalIndexType`, create an - /// `AnyBidirectionalCollection` having the same underlying - /// collection as `other`. Otherwise, the result is `nil`. - /// - /// Complexity: O(1) - public init?(_ other: AnyForwardCollection) { - if !(other._box.startIndex is _BidirectionalIndexBoxType) { - return nil - } - _sanityCheck(other._box.endIndex is _BidirectionalIndexBoxType) - self._box = other._box - } - - /// Return a *generator* over the elements of this *collection*. - /// - /// Complexity: O(1) - public func generate() -> AnyGenerator { - return unsafeDowncast(_box.generate()) - } - - /// The position of the first element in a non-empty collection. - /// - /// Identical to `endIndex` in an empty collection. - public var startIndex: AnyBidirectionalIndex { - return AnyBidirectionalIndex(_box.startIndex) - } - - /// The collection's "past the end" position. - /// - /// `endIndex` is not a valid argument to `subscript`, and is always - /// reachable from `startIndex` by zero or more applications of - /// `successor()`. - public var endIndex: AnyBidirectionalIndex { - return AnyBidirectionalIndex(_box.endIndex) - } - - /// Access the element indicated by `position`. - /// - /// Requires: `position` indicates a valid position in `self` and - /// `position != endIndex`. - public subscript(position: AnyBidirectionalIndex) -> Element { - return _box[position._box] - } - - /// Uniquely identifies the stored underlying collection. - public var underlyingCollectionID: ObjectIdentifier { - return ObjectIdentifier(_box) - } - - internal let _box: Box -} -/// A type-erased wrapper over any collection with at least -/// randomaccess indices. -/// -/// Forwards operations to an arbitrary underlying collection having the -/// same `Element` type, hiding the specifics of the underlying -/// `CollectionType`. -/// -/// See also: `AnyForwardType`, `AnyBidirectionalType` -public struct AnyRandomAccessCollection : AnyCollectionType { - typealias Box = _AnyCollectionBox - - /// Create an `AnyRandomAccessCollection` that stores `base` as its - /// underlying collection. - /// - /// Complexity: O(1) - public init< - C: CollectionType - where C.Index: RandomAccessIndexType, C.Generator.Element == Element - >(_ base: C) { - self._box = _CollectionBox( - base, - startIndex: _RandomAccessIndexBox(base.startIndex), - endIndex: _RandomAccessIndexBox(base.endIndex)) - } - - /// Create an `AnyRandomAccessCollection` having the same underlying - /// collection as `other`. - /// - /// Postcondition: the result is `===` to `other`. - /// - /// Complexity: O(1) - public init(_ other: AnyRandomAccessCollection) { - self._box = other._box - } - - /// If the indices of the underlying collection stored by `other` - /// satisfy `RandomAccessIndexType`, create an - /// `AnyRandomAccessCollection` having the same underlying - /// collection as `other`. Otherwise, the result is `nil`. - /// - /// Complexity: O(1) - public init?(_ other: AnyForwardCollection) { - if !(other._box.startIndex is _RandomAccessIndexBoxType) { - return nil - } - _sanityCheck(other._box.endIndex is _RandomAccessIndexBoxType) - self._box = other._box - } - /// If the indices of the underlying collection stored by `other` - /// satisfy `RandomAccessIndexType`, create an - /// `AnyRandomAccessCollection` having the same underlying - /// collection as `other`. Otherwise, the result is `nil`. - /// - /// Complexity: O(1) - public init?(_ other: AnyBidirectionalCollection) { - if !(other._box.startIndex is _RandomAccessIndexBoxType) { - return nil - } - _sanityCheck(other._box.endIndex is _RandomAccessIndexBoxType) - self._box = other._box - } - - /// Return a *generator* over the elements of this *collection*. - /// - /// Complexity: O(1) - public func generate() -> AnyGenerator { - return unsafeDowncast(_box.generate()) - } - - /// The position of the first element in a non-empty collection. - /// - /// Identical to `endIndex` in an empty collection. - public var startIndex: AnyRandomAccessIndex { - return AnyRandomAccessIndex(_box.startIndex) - } - - /// The collection's "past the end" position. - /// - /// `endIndex` is not a valid argument to `subscript`, and is always - /// reachable from `startIndex` by zero or more applications of - /// `successor()`. - public var endIndex: AnyRandomAccessIndex { - return AnyRandomAccessIndex(_box.endIndex) - } - - /// Access the element indicated by `position`. - /// - /// Requires: `position` indicates a valid position in `self` and - /// `position != endIndex`. - public subscript(position: AnyRandomAccessIndex) -> Element { - return _box[position._box] - } - - /// Uniquely identifies the stored underlying collection. - public var underlyingCollectionID: ObjectIdentifier { - return ObjectIdentifier(_box) - } - - internal let _box: Box -} - diff --git a/test/IDE/dump_swift_lookup_tables.swift b/test/IDE/dump_swift_lookup_tables.swift index e8f9352d5f40b..ee4403964fe2c 100644 --- a/test/IDE/dump_swift_lookup_tables.swift +++ b/test/IDE/dump_swift_lookup_tables.swift @@ -3,22 +3,8 @@ // REQUIRES: objc_interop -// CHECK: Base -> full name mappings: -// CHECK-NEXT: Bar --> Bar -// CHECK-NEXT: Blue --> Blue -// CHECK-NEXT: Green --> Green -// CHECK-NEXT: MyInt --> MyInt -// CHECK-NEXT: Point --> Point -// CHECK-NEXT: Rouge --> Rouge -// CHECK-NEXT: SNColorChoice --> SNColorChoice -// CHECK-NEXT: SomeStruct --> SomeStruct -// CHECK-NEXT: __SNTransposeInPlace --> __SNTransposeInPlace -// CHECK-NEXT: makeSomeStruct --> makeSomeStruct(x:y:), makeSomeStruct(x:) -// CHECK-NEXT: x --> x -// CHECK-NEXT: y --> y -// CHECK-NEXT: z --> z - -// CHECK: Full name -> entry mappings: +// CHECK-LABEL: <> +// CHECK-NEXT: Base name -> entry mappings: // CHECK-NEXT: Bar: // CHECK-NEXT: TU: SNFoo // CHECK-NEXT: Blue: @@ -33,14 +19,18 @@ // CHECK-NEXT: SNColorChoice: SNColorRed // CHECK-NEXT: SNColorChoice: // CHECK-NEXT: TU: SNColorChoice, SNColorChoice +// CHECK-NEXT: SWIFT_ENUM: +// CHECK-NEXT: TU: Macro +// CHECK-NEXT: SWIFT_NAME: +// CHECK-NEXT: TU: Macro // CHECK-NEXT: SomeStruct: // CHECK-NEXT: TU: SNSomeStruct // CHECK-NEXT: __SNTransposeInPlace: // CHECK-NEXT: TU: SNTransposeInPlace -// CHECK-NEXT: makeSomeStruct(x:): -// CHECK-NEXT: TU: SNMakeSomeStructForX -// CHECK-NEXT: makeSomeStruct(x:y:): -// CHECK-NEXT: TU: SNMakeSomeStruct +// CHECK-NEXT: __swift: +// CHECK-NEXT: TU: __swift +// CHECK-NEXT: makeSomeStruct: +// CHECK-NEXT: TU: SNMakeSomeStruct, SNMakeSomeStructForX // CHECK-NEXT: x: // CHECK-NEXT: SNSomeStruct: X // CHECK-NEXT: SNPoint: x diff --git a/test/IDE/dump_swift_lookup_tables_objc.swift b/test/IDE/dump_swift_lookup_tables_objc.swift index bc703fa4a28a8..fd5faa4893915 100644 --- a/test/IDE/dump_swift_lookup_tables_objc.swift +++ b/test/IDE/dump_swift_lookup_tables_objc.swift @@ -6,34 +6,19 @@ // REQUIRES: objc_interop -// CHECK: Base -> full name mappings: -// CHECK-NEXT: CCItem --> CCItem -// CHECK-NEXT: CCItemRef --> CCItemRef -// CHECK-NEXT: CFTypeRef --> CFTypeRef -// CHECK-NEXT: NSAccessibility --> NSAccessibility -// CHECK-NEXT: NSError --> NSError -// CHECK-NEXT: NSErrorImports --> NSErrorImports -// CHECK-NEXT: SNCollision --> SNCollision -// CHECK-NEXT: SNCollisionProtocol --> SNCollisionProtocol -// CHECK-NEXT: SomeClass --> SomeClass -// CHECK-NEXT: SomeProtocol --> SomeProtocol -// CHECK-NEXT: UIActionSheet --> UIActionSheet -// CHECK-NEXT: __CCItem --> __CCItem -// CHECK-NEXT: accessibilityFloat --> accessibilityFloat() -// CHECK-NEXT: categoryMethodWithX --> categoryMethodWithX(_:y:), categoryMethodWithX(_:y:z:) -// CHECK-NEXT: doubleProperty --> doubleProperty{{$}} -// CHECK-NEXT: extensionMethodWithX --> extensionMethodWithX(_:y:) -// CHECK-NEXT: floatProperty --> floatProperty{{$}} -// CHECK-NEXT: init --> init(float:), init(withDefault:), init(double:), init(withTry:), init(uint8:), init(title:delegate:cancelButtonTitle:destructiveButtonTitle:) -// CHECK-NEXT: instanceMethodWithX --> instanceMethodWithX(_:y:z:) -// CHECK-NEXT: method --> method() -// CHECK-NEXT: methodWithFloat --> methodWithFloat(_:) -// CHECK-NEXT: objectAtIndexedSubscript --> objectAtIndexedSubscript(_:) -// CHECK-NEXT: protoInstanceMethodWithX --> protoInstanceMethodWithX(_:y:) -// CHECK-NEXT: setAccessibilityFloat --> setAccessibilityFloat(_:) -// CHECK-NEXT: subscript --> subscript() +// CHECK-LABEL: <> +// CHECK: Categories:{{.*}}NSValue(NSValueCreation){{.*}} -// CHECK: Full name -> entry mappings: +// CHECK-LABEL: <> +// CHECK-NEXT: Base name -> entry mappings: +// CHECK-NOT: lookup table +// CHECK: NSObject: +// CHECK-NEXT: TU: NSObject +// CHECK-NEXT: NSObjectProtocol: +// CHECK-NEXT: TU: NSObject + +// CHECK-LABEL: <> +// CHECK-NEXT: Base name -> entry mappings: // CHECK-NEXT: CCItem: // CHECK-NEXT: TU: CCItemRef // CHECK-NEXT: CCItemRef: @@ -50,6 +35,10 @@ // CHECK-NEXT: TU: SNCollision{{$}} // CHECK-NEXT: SNCollisionProtocol: // CHECK-NEXT: TU: SNCollision{{$}} +// CHECK-NEXT: SWIFT_ENUM: +// CHECK-NEXT: TU: Macro +// CHECK-NEXT: SWIFT_NAME: +// CHECK-NEXT: TU: Macro // CHECK-NEXT: SomeClass: // CHECK-NEXT: TU: SNSomeClass // CHECK-NEXT: SomeProtocol: @@ -58,52 +47,48 @@ // CHECK-NEXT: TU: UIActionSheet // CHECK-NEXT: __CCItem: // CHECK-NEXT: TU: __CCItem -// CHECK-NEXT: accessibilityFloat(): +// CHECK-NEXT: __swift: +// CHECK-NEXT: TU: __swift +// CHECK-NEXT: accessibilityFloat: // CHECK-NEXT: NSAccessibility: -[NSAccessibility accessibilityFloat] -// CHECK-NEXT: categoryMethodWithX(_:y:): -// CHECK-NEXT: SNSomeClass: -[SNSomeClass categoryMethodWithX:y:] -// CHECK-NEXT: categoryMethodWithX(_:y:z:): -// CHECK-NEXT: SNSomeClass: -[SNSomeClass categoryMethodWithX:y:z:] +// CHECK-NEXT: categoryMethodWithX: +// CHECK-NEXT: SNSomeClass: -[SNSomeClass categoryMethodWithX:y:], -[SNSomeClass categoryMethodWithX:y:z:] // CHECK-NEXT: doubleProperty: // CHECK-NEXT: SNSomeClass: SNSomeClass.doubleProperty -// CHECK-NEXT: extensionMethodWithX(_:y:): +// CHECK-NEXT: extensionMethodWithX: // CHECK-NEXT: SNSomeClass: -[SNSomeClass extensionMethodWithX:y:] // CHECK-NEXT: floatProperty: // CHECK-NEXT: SNSomeClass: SNSomeClass.floatProperty -// CHECK-NEXT: init(andReturnError:): -// CHECK-NEXT: NSErrorImports: -[NSErrorImports initAndReturnError:] -// CHECK-NEXT: init(double:): -// CHECK-NEXT: SNSomeClass: +[SNSomeClass someClassWithDouble:] -// CHECK-NEXT: init(float:): -// CHECK-NEXT: SNSomeClass: -[SNSomeClass initWithFloat:] -// CHECK-NEXT: NSErrorImports: -[NSErrorImports initWithFloat:error:] -// CHECK-NEXT: init(title:delegate:cancelButtonTitle:destructiveButtonTitle:): +// CHECK-NEXT: init: +// CHECK-NEXT: SNSomeClass: -[SNSomeClass initWithFloat:], -[SNSomeClass initWithDefault], +[SNSomeClass someClassWithDouble:], +[SNSomeClass someClassWithTry:], +[SNSomeClass buildWithUnsignedChar:] // CHECK-NEXT: UIActionSheet: -[UIActionSheet initWithTitle:delegate:cancelButtonTitle:destructiveButtonTitle:otherButtonTitles:] -// CHECK-NEXT: init(uint8:): -// CHECK-NEXT: SNSomeClass: +[SNSomeClass buildWithUnsignedChar:] -// CHECK-NEXT: init(withDefault:): -// CHECK-NEXT: SNSomeClass: -[SNSomeClass initWithDefault] -// CHECK-NEXT: init(withTry:): -// CHECK-NEXT: SNSomeClass: +[SNSomeClass someClassWithTry:] -// CHECK-NEXT: instanceMethodWithX(_:y:z:): +// CHECK-NEXT: NSErrorImports: -[NSErrorImports initAndReturnError:], -[NSErrorImports initWithFloat:error:] +// CHECK-NEXT: instanceMethodWithX: // CHECK-NEXT: SNSomeClass: -[SNSomeClass instanceMethodWithX:Y:Z:] -// CHECK-NEXT: method(): +// CHECK-NEXT: method: // CHECK-NEXT: NSErrorImports: -[NSErrorImports methodAndReturnError:] -// CHECK-NEXT: methodWithFloat(_:): +// CHECK-NEXT: methodWithFloat: // CHECK-NEXT: NSErrorImports: -[NSErrorImports methodWithFloat:error:] -// CHECK-NEXT: objectAtIndexedSubscript(_:): +// CHECK-NEXT: objectAtIndexedSubscript: // CHECK-NEXT: SNSomeClass: -[SNSomeClass objectAtIndexedSubscript:] -// CHECK-NEXT: protoInstanceMethodWithX(_:y:): +// CHECK-NEXT: optSetter: +// CHECK-NEXT: SNCollision: SNCollision.optSetter +// CHECK-NEXT: protoInstanceMethodWithX: // CHECK-NEXT: SNSomeProtocol: -[SNSomeProtocol protoInstanceMethodWithX:y:] -// CHECK-NEXT: setAccessibilityFloat(_:): +// CHECK-NEXT: reqSetter: +// CHECK-NEXT: SNCollision: SNCollision.reqSetter +// CHECK-NEXT: setAccessibilityFloat: // CHECK-NEXT: NSAccessibility: -[NSAccessibility setAccessibilityFloat:] -// CHECK-NEXT: subscript(): +// CHECK-NEXT: subscript: // CHECK-NEXT: SNSomeClass: -[SNSomeClass objectAtIndexedSubscript:] -// CHECK-OMIT-NEEDLESS-WORDS: Base -> full name mappings: -// CHECK-OMIT-NEEDLESS-WORDS: instanceMethodWithX --> instanceMethodWithX(_:y:z:) -// CHECK-OMIT-NEEDLESS-WORDS: methodWith --> methodWith(_:) +// CHECK: Categories: SNSomeClass(), SNSomeClass(Category1) + +// CHECK-OMIT-NEEDLESS-WORDS: <> +// CHECK-OMIT-NEEDLESS-WORDS-NOT: lookup table +// CHECK-OMIT-NEEDLESS-WORDS: respondsTo: +// CHECK-OMIT-NEEDLESS-WORDS-NEXT: -[NSObject respondsToSelector:] -// CHECK-OMIT-NEEDLESS-WORDS: Full name -> entry mappings: -// CHECK-OMIT-NEEDLESS-WORDS: methodWith(_:): +// CHECK-OMIT-NEEDLESS-WORDS: Base name -> entry mappings: +// CHECK-OMIT-NEEDLESS-WORDS: methodWith: // CHECK-OMIT-NEEDLESS-WORDS: NSErrorImports: -[NSErrorImports methodWithFloat:error:] diff --git a/test/IDE/print_ast_tc_decls.swift b/test/IDE/print_ast_tc_decls.swift index 674a9d1a838b4..643eb5853c167 100644 --- a/test/IDE/print_ast_tc_decls.swift +++ b/test/IDE/print_ast_tc_decls.swift @@ -228,7 +228,7 @@ struct d0100_FooStruct { // PASS_COMMON-NEXT: {{^}} enum NestedEnum {{{$}} // PASS_COMMON-NEXT: {{^}} }{{$}} - // Can not declare a nested protocol. + // Cannot declare a nested protocol. // protocol NestedProtocol {} typealias NestedTypealias = Int @@ -629,8 +629,8 @@ struct d0200_EscapedIdentifiers { // PASS_COMMON-NEXT: {{^}} }{{$}} func `func`<`let`: `protocol`, `where` where `where` : `protocol`>( - `class`: Int, `struct`: `protocol`, `foo`: `let`, `bar`: `where`) {} -// PASS_COMMON-NEXT: {{^}} func `func`<`let` : `protocol`, `where` where `where` : `protocol`>(`class`: Int, `struct`: `protocol`, foo: `let`, bar: `where`){{$}} + class: Int, struct: `protocol`, foo: `let`, bar: `where`) {} +// PASS_COMMON-NEXT: {{^}} func `func`<`let` : `protocol`, `where` where `where` : `protocol`>(class: Int, struct: `protocol`, foo: `let`, bar: `where`){{$}} var `var`: `struct` = `struct`() // PASS_COMMON-NEXT: {{^}} var `var`: {{(d0200_EscapedIdentifiers.)?}}`struct`{{$}} @@ -644,8 +644,8 @@ struct d0200_EscapedIdentifiers { } // PASS_COMMON-NEXT: {{^}} var accessors1: Int{{( { get set })?}}{{$}} - static func `static`(`protocol`: Int) {} -// PASS_COMMON-NEXT: {{^}} static func `static`(`protocol`: Int){{$}} + static func `static`(protocol: Int) {} +// PASS_COMMON-NEXT: {{^}} static func `static`(protocol: Int){{$}} // PASS_COMMON-NEXT: {{^}} init(`var`: {{(d0200_EscapedIdentifiers.)?}}`struct`, tupleType: (`var`: Int, `let`: {{(d0200_EscapedIdentifiers.)?}}`struct`)){{$}} // PASS_COMMON-NEXT: {{^}}}{{$}} diff --git a/test/IDE/print_ast_tc_decls_errors.swift b/test/IDE/print_ast_tc_decls_errors.swift index 5abbc2acdfdbb..37e1dee9e2fdc 100644 --- a/test/IDE/print_ast_tc_decls_errors.swift +++ b/test/IDE/print_ast_tc_decls_errors.swift @@ -168,6 +168,9 @@ typealias Typealias1 = FooNonExistentProtocol // expected-error {{use of undecla // NO-TYREPR: {{^}}typealias Typealias1 = <>{{$}} // TYREPR: {{^}}typealias Typealias1 = FooNonExistentProtocol{{$}} +// sr-197 +func foo(bar: Typealias1) {} // Should not generate error "cannot specialize non-generic type '<>'" + // Associated types. protocol AssociatedType1 { diff --git a/test/IDE/print_clang_header_swift_name.swift b/test/IDE/print_clang_header_swift_name.swift new file mode 100644 index 0000000000000..9afc97c9e5750 --- /dev/null +++ b/test/IDE/print_clang_header_swift_name.swift @@ -0,0 +1,27 @@ +// RUN: echo '#include "print_clang_header_swift_name.h"' > %t.m +// RUN: %target-swift-ide-test -source-filename %s -print-header -header-to-print \ +// RUN: %S/Inputs/print_clang_header_swift_name.h --cc-args %target-cc-options \ +// RUN: -isysroot %clang-importer-sdk-path -fsyntax-only %t.m -I %S/Inputs | FileCheck %s + +// REQUIRES: objc_interop + +// CHECK: enum Normal : Int { +// CHECK-NOT: {{^}}} +// CHECK: case One +// CHECK-NEXT: case Two +// CHECK-NEXT: case Three +// CHECK-NEXT: } + +// CHECK: enum SwiftEnum : Int { +// CHECK-NOT: {{^}}} +// CHECK: case One +// CHECK-NEXT: case Two +// CHECK-NEXT: case Three +// CHECK-NEXT: } + +// CHECK: enum SwiftEnumTwo : Int { +// CHECK-NOT: {{^}}} +// CHECK: case SwiftEnumTwoA +// CHECK-NEXT: case SwiftEnumTwoB +// CHECK-NEXT: case SwiftEnumTwoC +// CHECK-NEXT: } diff --git a/test/IDE/print_module_without_deinit.swift b/test/IDE/print_module_without_deinit.swift index db09119283ce8..1b6bde828dcf6 100644 --- a/test/IDE/print_module_without_deinit.swift +++ b/test/IDE/print_module_without_deinit.swift @@ -39,7 +39,7 @@ public class ImplicitOptionalInitContainer { // ATTR1: class AttributeContainer1 { public class AttributeContainer1 { // ATTR1: func m1(@autoclosure a: () -> Int) - public func m1(@autoclosure a : ()->Int) {} + public func m1(@autoclosure a : () -> Int) {} // ATTR1: func m2(@noescape a: () -> Int) - public func m2(@noescape a : ()->Int) {} + public func m2(@noescape a : () -> Int) {} } diff --git a/test/IDE/print_omit_needless_words.swift b/test/IDE/print_omit_needless_words.swift index ddf0a5625194e..16fc17585ff17 100644 --- a/test/IDE/print_omit_needless_words.swift +++ b/test/IDE/print_omit_needless_words.swift @@ -64,6 +64,9 @@ // Note: Typedefs with a "_t" suffix". // CHECK-FOUNDATION: func subtract(_: Int32) -> NSNumber +// Note: Respect the getter name for BOOL properties. +// CHECK-FOUNDATION: var isMakingHoney: Bool + // Note: multi-word enum name matching; "with" splits the first piece. // CHECK-FOUNDATION: func someMethod(deprecatedOptions _: NSDeprecatedOptions = []) @@ -138,8 +141,8 @@ // Collection element types. // CHECK-FOUNDATION: func adding(_: AnyObject) -> Set -// Boolean properties get an "is" prefix. -// CHECK-FOUNDATION: var isEmpty: Bool { get } +// Boolean properties follow the getter. +// CHECK-FOUNDATION: var empty: Bool { get } // CHECK-FOUNDATION: func nonEmpty() -> Bool // CHECK-FOUNDATION: var isStringSet: Bool { get } // CHECK-FOUNDATION: var wantsAUnion: Bool { get } @@ -147,6 +150,9 @@ // CHECK-FOUNDATION: var appliesForAJob: Bool { get } // CHECK-FOUNDATION: var setShouldBeInfinite: Bool { get } +// "UTF8" initialisms. +// CHECK-FOUNDATION: init?(utf8String: UnsafePointer) + // Note: class method name stripping context type. // CHECK-APPKIT: class func red() -> NSColor @@ -160,7 +166,7 @@ // CHECK-APPKIT: func drawInAirAt(_: Point3D) // Note: with -> -// CHECK-APPKIT: func drawAt(_: Point3D, withAttributes: [String : AnyObject]?) +// CHECK-APPKIT: func drawAt(_: Point3D, withAttributes: [String : AnyObject]? = [:]) // Note: Don't strip names that aren't preceded by a verb or preposition. // CHECK-APPKIT: func setTextColor(_: NSColor?) @@ -168,6 +174,10 @@ // Note: Splitting with default arguments. // CHECK-APPKIT: func drawIn(_: NSView?) +// Note: NSDictionary default arguments for "options" +// CHECK-APPKIT: func drawAnywhereIn(_: NSView?, options: [NSObject : AnyObject] = [:]) +// CHECK-APPKIT: func drawAnywhere(options _: [NSObject : AnyObject] = [:]) + // Note: Skipping over "Ref" // CHECK-CORECOOLING: func replace(_: CCPowerSupply!) diff --git a/test/IDE/print_usrs.swift b/test/IDE/print_usrs.swift index b963a4d58ba84..69c4fbe45d268 100644 --- a/test/IDE/print_usrs.swift +++ b/test/IDE/print_usrs.swift @@ -46,7 +46,7 @@ class GenericClass { } // CHECK: [[@LINE+2]]:3 s:iC14swift_ide_test12GenericClass9subscriptFSiSf{{$}} - // CHECK: [[@LINE+1]]:13 s:vC14swift_ide_test12GenericClass1iSi{{$}} + // CHECK: [[@LINE+1]]:13 s:vC14swift_ide_test12GenericClassL_1iSi{{$}} subscript(i: Int) -> Float { // CHECK: [[@LINE+1]]:5 s:FC14swift_ide_test12GenericClassg9subscriptFSiSf{{$}} get { return 0.0 } diff --git a/test/IDE/structure.swift b/test/IDE/structure.swift index 666f683a7d16e..c038f26c1021e 100644 --- a/test/IDE/structure.swift +++ b/test/IDE/structure.swift @@ -9,7 +9,7 @@ class MyCls : OtherClass { var anotherBar : Int = 42 class var cbar : Int = 0 - // CHECK: func foo(arg1: Int, name: String, param par: String) { + // CHECK: func foo(arg1: Int, name: String, param par: String) { // CHECK: var abc // CHECK: if 1 { // CHECK: foo(1, name:"test", param:"test2") @@ -22,7 +22,7 @@ class MyCls : OtherClass { } } - // CHECK: init (x: Int) + // CHECK: init (x: Int) init (x: Int) // CHECK: class func cfoo() @@ -152,7 +152,7 @@ enum Rawness : Int { case Two = 2, Three = 3 } -// CHECK: func rethrowFunc(f: () throws -> ()) rethrows {} +// CHECK: func rethrowFunc(f: () throws -> ()) rethrows {} func rethrowFunc(f: () throws -> ()) rethrows {} class NestedPoundIf{ diff --git a/test/IRGen/Inputs/ObjcSuperClass.swift b/test/IRGen/Inputs/ObjcSuperClass.swift deleted file mode 100644 index cb3fcdf5a9791..0000000000000 --- a/test/IRGen/Inputs/ObjcSuperClass.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - -public class ObjCSubclass : NSObject { - // This properties will have a non constant field access due to the objc super - // class. - public final var field : Int32 - - public override init () { - field = 10 - } - -}; diff --git a/test/IRGen/Inputs/report_dead_method_call/main.swift b/test/IRGen/Inputs/report_dead_method_call/main.swift index 962f09c1c5eac..6151ddb1f43ed 100644 --- a/test/IRGen/Inputs/report_dead_method_call/main.swift +++ b/test/IRGen/Inputs/report_dead_method_call/main.swift @@ -38,5 +38,5 @@ case 3: callPublicClass() default: - break; + break } diff --git a/test/IRGen/NonConstantAddressFieldAccess.swift b/test/IRGen/NonConstantAddressFieldAccess.swift deleted file mode 100644 index 2ec20e4aaf64e..0000000000000 --- a/test/IRGen/NonConstantAddressFieldAccess.swift +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %target-build-swift %S/Inputs/ObjcSuperClass.swift %s -module-name a -emit-ir 2>&1 | FileCheck %s -// REQUIRES: executable_test - -// REQUIRES: objc_interop - -// CHECK: @_TWvdvC1a12ObjCSubclass5fieldVs5Int32 = global i{{[0-9]+}} -// CHECK: @_TWvdvC1a12ObjCSubclass5fieldVs5Int32 = external global i{{[0-9]+}} - -func test(o: ObjCSubclass) { - o.field = 10 -} diff --git a/test/IRGen/UseObjCMethod.swift b/test/IRGen/UseObjCMethod.swift index 35d61b8f31ee0..b3522b913433f 100644 --- a/test/IRGen/UseObjCMethod.swift +++ b/test/IRGen/UseObjCMethod.swift @@ -21,7 +21,7 @@ func testDemo() { testDemo() -// Make sure the clang importer puts the selectors and co into the lllvm.compiler used variable. +// Make sure the clang importer puts the selectors and co into the llvm.compiler used variable. // CHECK: @llvm.compiler.used = appending global [{{.*}} x i8*] [{{.*}} @"OBJC_CLASSLIST_REFERENCES_$_"{{.*}}@OBJC_METH_VAR_NAME_{{.*}}@OBJC_SELECTOR_REFERENCES_{{.*}}@OBJC_METH_VAR_NAME_.1{{.*}}@OBJC_SELECTOR_REFERENCES_.2{{.*}}] diff --git a/test/IRGen/abitypes.swift b/test/IRGen/abitypes.swift index faed12c278607..b03cfc02fb01d 100644 --- a/test/IRGen/abitypes.swift +++ b/test/IRGen/abitypes.swift @@ -61,7 +61,7 @@ class Foo { } // Call from Swift entrypoint with exploded Rect to @objc entrypoint - // with unexploaded ABI-coerced type. + // with unexploded ABI-coerced type. // x86_64-macosx: define hidden float @_TFC8abitypes3Foo17getXFromRectSwift{{.*}}(%VSC6MyRect* noalias nocapture dereferenceable({{.*}}), [[SELF:%.*]]*) {{.*}} { // x86_64-macosx: [[COERCED:%.*]] = alloca [[MYRECT:%.*MyRect.*]], align 4 // x86_64-macosx: [[SEL:%.*]] = load i8*, i8** @"\01L_selector(getXFromRect:)", align 8 @@ -103,7 +103,7 @@ class Foo { // Make sure the caller-side from Swift also uses indirect-byval for the argument // x86_64-macosx: define hidden float @_TFC8abitypes3Foo25getXFromRectIndirectSwift{{.*}}(%VSC6MyRect* noalias nocapture dereferenceable({{.*}}), %C8abitypes3Foo*) {{.*}} { func getXFromRectIndirectSwift(r: MyRect) -> Float { - let f : Float = 1.0; + let f : Float = 1.0 // x86_64-macosx: [[TEMP:%.*]] = alloca [[TEMPTYPE:%.*]], align 4 // x86_64-macosx: [[RESULT:%.*]] = call float bitcast (void ()* @objc_msgSend to float (i8*, i8*, float, float, float, float, float, float, float, [[TEMPTYPE]]*)*)(i8* %{{.*}}, i8* %{{.*}}, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, [[TEMPTYPE]]* byval align 4 [[TEMP]]) // x86_64-macosx: ret float [[RESULT]] @@ -172,9 +172,13 @@ class Foo { // x86_64-macosx: define hidden { i32, i32 } @_TFC8abitypes3Foo9getnested{{.*}}(%CSo13StructReturns*, %C8abitypes3Foo*) {{.*}} { // x86_64-macosx: call i64 bitcast (void ()* @objc_msgSend to i64 ([[OPAQUE:.*]]*, i8*)*) + // x86_64-macosx-NEXT: bitcast + // x86_64-macosx-NEXT: llvm.lifetime.start // x86_64-macosx-NEXT: store i64 // x86_64-macosx-NEXT: bitcast i64* {{[^ ]*}} to { i32, i32 }* // x86_64-macosx-NEXT: load { i32, i32 }, { i32, i32 }* + // x86_64-macosx-NEXT: bitcast + // x86_64-macosx-NEXT: llvm.lifetime.end // x86_64-macosx: ret { i32, i32 } func getnested(p: StructReturns) -> NestedInts { return p.newNestedInts() @@ -427,7 +431,7 @@ class Foo { // Test that the makeOne() that we generate somewhere below doesn't // use arm_aapcscc for armv7. func callInline() -> Float { - return makeOne(3,5).second; + return makeOne(3,5).second } } diff --git a/test/IRGen/alignment.sil b/test/IRGen/alignment.sil index c637765c60337..b0b22c0df4608 100644 --- a/test/IRGen/alignment.sil +++ b/test/IRGen/alignment.sil @@ -27,52 +27,52 @@ entry: // CHECK: load float{{.*}}, align 4 // CHECK: load float{{.*}}, align 8 // CHECK: load float{{.*}}, align 4 - %z = load %a#1 : $*Foo + %z = load %a : $*Foo // CHECK: store float{{.*}}, align 16 // CHECK: store float{{.*}}, align 4 // CHECK: store float{{.*}}, align 8 // CHECK: store float{{.*}}, align 4 - store %z to %a#1 : $*Foo + store %z to %a : $*Foo // CHECK: load float{{.*}}, align 16 // CHECK: load float{{.*}}, align 4 // CHECK: load float{{.*}}, align 8 // CHECK: load float{{.*}}, align 4 - %y = load %b#1 : $*Singleton + %y = load %b : $*Singleton // CHECK: store float{{.*}}, align 16 // CHECK: store float{{.*}}, align 4 // CHECK: store float{{.*}}, align 8 // CHECK: store float{{.*}}, align 4 - store %y to %b#1 : $*Singleton + store %y to %b : $*Singleton - %x = load %c#1 : $*Empty - store %x to %c#1 : $*Empty + %x = load %c : $*Empty + store %x to %c : $*Empty // CHECK: load i2{{.*}}, align 16 - %w = load %d#1 : $*NoPayload + %w = load %d : $*NoPayload // CHECK: store i2{{.*}}, align 16 - store %w to %d#1 : $*NoPayload + store %w to %d : $*NoPayload // CHECK: load i32{{.*}}, align 16 // CHECK: load i1{{.*}}, align 4 - %v = load %e#1 : $*SinglePayload + %v = load %e : $*SinglePayload // CHECK: store i32{{.*}}, align 16 // CHECK: store i1{{.*}}, align 4 - store %v to %e#1 : $*SinglePayload + store %v to %e : $*SinglePayload // CHECK: load i32{{.*}}, align 16 // CHECK: load i2{{.*}}, align 4 - %u = load %f#1 : $*MultiPayload + %u = load %f : $*MultiPayload // CHECK: store i32{{.*}}, align 16 // CHECK: store i2{{.*}}, align 4 - store %u to %f#1 : $*MultiPayload + store %u to %f : $*MultiPayload - dealloc_stack %f#0 : $*@local_storage MultiPayload - dealloc_stack %e#0 : $*@local_storage SinglePayload - dealloc_stack %d#0 : $*@local_storage NoPayload - dealloc_stack %c#0 : $*@local_storage Empty - dealloc_stack %b#0 : $*@local_storage Singleton - dealloc_stack %a#0 : $*@local_storage Foo + dealloc_stack %f : $*MultiPayload + dealloc_stack %e : $*SinglePayload + dealloc_stack %d : $*NoPayload + dealloc_stack %c : $*Empty + dealloc_stack %b : $*Singleton + dealloc_stack %a : $*Foo return undef : $() } diff --git a/test/IRGen/associated_type_witness.swift b/test/IRGen/associated_type_witness.swift new file mode 100644 index 0000000000000..4f190e825c193 --- /dev/null +++ b/test/IRGen/associated_type_witness.swift @@ -0,0 +1,154 @@ +// RUN: %target-swift-frontend -primary-file %s -emit-ir > %t.ll +// RUN: FileCheck %s -check-prefix=GLOBAL < %t.ll +// RUN: FileCheck %s < %t.ll +// REQUIRES: CPU=x86_64 + +protocol P {} +protocol Q {} + +protocol Assocked { + typealias Assoc : P, Q +} + +struct Universal : P, Q {} + +// Witness table access functions for Universal : P and Universal : Q. +// CHECK-LABEL: define hidden i8** @_TWaV23associated_type_witness9UniversalS_1PS_() +// CHECK: ret i8** getelementptr inbounds ([0 x i8*], [0 x i8*]* @_TWPV23associated_type_witness9UniversalS_1PS_, i32 0, i32 0) +// CHECK-LABEL: define hidden i8** @_TWaV23associated_type_witness9UniversalS_1QS_() +// CHECK: ret i8** getelementptr inbounds ([0 x i8*], [0 x i8*]* @_TWPV23associated_type_witness9UniversalS_1QS_, i32 0, i32 0) + +// Witness table for WithUniversal : Assocked. +// GLOBAL-LABEL: @_TWPV23associated_type_witness13WithUniversalS_8AssockedS_ = hidden constant [3 x i8*] [ +// GLOBAL-SAME: i8* bitcast (%swift.type* ()* @_TMaV23associated_type_witness9Universal to i8*) +// GLOBAL-SAME: i8* bitcast (i8** ()* @_TWaV23associated_type_witness9UniversalS_1PS_ to i8*) +// GLOBAL-SAME: i8* bitcast (i8** ()* @_TWaV23associated_type_witness9UniversalS_1QS_ to i8*) +// GLOBAL-SAME: ] +struct WithUniversal : Assocked { + typealias Assoc = Universal +} + +// Witness table for GenericWithUniversal : Assocked. +// GLOBAL-LABEL: @_TWPurGV23associated_type_witness20GenericWithUniversalx_S_8AssockedS_ = hidden constant [3 x i8*] [ +// GLOBAL-SAME: i8* bitcast (%swift.type* ()* @_TMaV23associated_type_witness9Universal to i8*) +// GLOBAL-SAME: i8* bitcast (i8** ()* @_TWaV23associated_type_witness9UniversalS_1PS_ to i8*) +// GLOBAL-SAME: i8* bitcast (i8** ()* @_TWaV23associated_type_witness9UniversalS_1QS_ to i8*) +// GLOBAL-SAME: ] +struct GenericWithUniversal : Assocked { + typealias Assoc = Universal +} + +// Witness table for Fulfilled : Assocked. +// GLOBAL-LABEL: @_TWPuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_ = hidden constant [3 x i8*] [ +// GLOBAL-SAME: i8* bitcast (%swift.type* (%swift.type*, i8**)* @_TWtuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5Assoc to i8*) +// GLOBAL-SAME: i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @_TWTuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5AssocPS_1P_ to i8*) +// GLOBAL-SAME: i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @_TWTuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5AssocPS_1Q_ to i8*) +// GLOBAL-SAME: ] +struct Fulfilled > : Assocked { + typealias Assoc = T +} + +// Associated type metadata access function for Fulfilled.Assoc. +// CHECK-LABEL: define internal %swift.type* @_TWtuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5Assoc(%swift.type* %Self, i8** %wtable) +// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type** +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3 +// CHECK-NEXT: [[T2:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load +// CHECK-NEXT: ret %swift.type* [[T2]] + +// Associated type witness table access function for Fulfilled.Assoc : P. +// CHECK-LABEL: define internal i8** @_TWTuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5AssocPS_1P_(%swift.type* %Self.Assoc, %swift.type* %Self, i8** %wtable) +// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to i8*** +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 4 +// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load +// CHECK-NEXT: ret i8** [[T2]] + +// Associated type witness table access function for Fulfilled.Assoc : Q. +// CHECK-LABEL: define internal i8** @_TWTuRx23associated_type_witness1PxS_1QrGVS_9Fulfilledx_S_8AssockedS_5AssocPS_1Q_(%swift.type* %Self.Assoc, %swift.type* %Self, i8** %wtable) +// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to i8*** +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 5 +// CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** [[T1]], align 8, !invariant.load +// CHECK-NEXT: ret i8** [[T2]] + +struct Pair : P, Q {} + +// Generic witness table pattern for Computed : Assocked. +// GLOBAL-LABEL: @_TWPu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_ = hidden constant [3 x i8*] [ +// GLOBAL-SAME: i8* bitcast (%swift.type* (%swift.type*, i8**)* @_TWtu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_5Assoc to i8*) +// GLOBAL-SAME: i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @_TWTu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_5AssocPS_1P_ to i8*) +// GLOBAL-SAME: i8* bitcast (i8** (%swift.type*, %swift.type*, i8**)* @_TWTu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_5AssocPS_1Q_ to i8*) +// GLOBAL-SAME: ] +// Generic witness table cache for Computed : Assocked. +// GLOBAL-LABEL: @_TWGu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_ = internal global %swift.generic_witness_table_cache { +// GLOBAL-SAME: i16 4, +// GLOBAL-SAME: i16 3, +// GLOBAL-SAME: i32 trunc (i64 sub (i64 ptrtoint ([3 x i8*]* @_TWPu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_ to i64), i64 ptrtoint (i32* getelementptr inbounds (%swift.generic_witness_table_cache, %swift.generic_witness_table_cache* @_TWGu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_, i32 0, i32 2) to i64)) to i32) +// GLOBAL-SAME: i32 0, +// GLOBAL-SAME: [16 x i8*] zeroinitializer +// GLOBAL-SAME: } +struct Computed : Assocked { + typealias Assoc = Pair +} + +// Associated type metadata access function for Computed.Assoc. +// CHECK-LABEL: define internal %swift.type* @_TWtu0_rGV23associated_type_witness8Computedxq__S_8AssockedS_5Assoc(%swift.type* %Self, i8** %wtable) +// CHECK: entry: +// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** %wtable, i32 3 +// CHECK-NEXT: [[CACHE:%.*]] = bitcast i8** [[T0]] to %swift.type** +// CHECK-NEXT: [[CACHE_RESULT:%.*]] = load %swift.type*, %swift.type** [[CACHE]], align 8 +// CHECK-NEXT: [[T1:%.*]] = icmp eq %swift.type* [[CACHE_RESULT]], null +// CHECK-NEXT: br i1 [[T1]], label %fetch, label %cont +// CHECK: cont: +// CHECK-NEXT: [[T0:%.*]] = phi %swift.type* [ [[CACHE_RESULT]], %entry ], [ [[FETCH_RESULT:%.*]], %fetch ] +// CHECK-NEXT: ret %swift.type* [[T0]] +// CHECK: fetch: +// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type** +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 3 +// CHECK-NEXT: [[T:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load +// CHECK: [[T0:%.*]] = bitcast %swift.type* %Self to %swift.type** +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i64 4 +// CHECK-NEXT: [[U:%.*]] = load %swift.type*, %swift.type** [[T1]], align 8, !invariant.load +// CHECK: [[T0:%.*]] = bitcast %swift.type* [[T]] to i8* +// CHECK-NEXT: [[T1:%.*]] = bitcast %swift.type* [[U]] to i8* +// CHECK-NEXT: [[FETCH_RESULT]] = call %swift.type* @swift_getGenericMetadata2({{.*}}, i8* [[T0]], i8* [[T1]]) +// CHECK-NEXT: store atomic %swift.type* [[FETCH_RESULT]], %swift.type** [[CACHE]] release, align 8 +// CHECK-NEXT: br label %cont + +struct PBox {} +protocol HasSimpleAssoc { + typealias Assoc +} +protocol DerivedFromSimpleAssoc : HasSimpleAssoc {} + + +// Generic witness table pattern for GenericComputed : DerivedFromSimpleAssoc. +// GLOBAL-LABEL: @_TWPuRx23associated_type_witness1PrGVS_15GenericComputedx_S_22DerivedFromSimpleAssocS_ = hidden constant [1 x i8*] zeroinitializer +// Generic witness table cache for GenericComputed : DerivedFromSimpleAssoc. +// GLOBAL-LABEL: @_TWGuRx23associated_type_witness1PrGVS_15GenericComputedx_S_22DerivedFromSimpleAssocS_ = internal global %swift.generic_witness_table_cache { +// GLOBAL-SAME: i16 1, +// GLOBAL-SAME: i16 1, +// GLOBAL-SAME: i32 trunc (i64 sub (i64 ptrtoint ([1 x i8*]* @_TWPuRx23associated_type_witness1PrGVS_15GenericComputedx_S_22DerivedFromSimpleAssocS_ to i64), i64 ptrtoint (i32* getelementptr inbounds (%swift.generic_witness_table_cache, %swift.generic_witness_table_cache* @_TWGuRx23associated_type_witness1PrGVS_15GenericComputedx_S_22DerivedFromSimpleAssocS_, i32 0, i32 2) to i64)) to i32) +// GLOBAL-SAME: i32 trunc (i64 sub (i64 ptrtoint (void (i8**, %swift.type*, i8**)* @_TWIuRx23associated_type_witness1PrGVS_15GenericComputedx_S_22DerivedFromSimpleAssocS_ to i64), i64 ptrtoint (i32* getelementptr inbounds (%swift.generic_witness_table_cache, %swift.generic_witness_table_cache* @_TWGuRx23associated_type_witness1PrGVS_15GenericComputedx_S_22DerivedFromSimpleAssocS_, i32 0, i32 3) to i64)) to i32), +// GLOBAL-SAME: [16 x i8*] zeroinitializer +// GLOBAL-SAME: } +struct GenericComputed : DerivedFromSimpleAssoc { + typealias Assoc = PBox +} + +// Instantiation function for GenericComputed : DerivedFromSimpleAssoc. +// CHECK-LABEL: define internal void @_TWIuRx23associated_type_witness1PrGVS_15GenericComputedx_S_22DerivedFromSimpleAssocS_(i8**, %swift.type*, i8**) +// CHECK: [[T0:%.*]] = call i8** @_TWauRx23associated_type_witness1PrGVS_15GenericComputedx_S_14HasSimpleAssocS_(%swift.type* %1) +// CHECK-NEXT: [[T1:%.*]] = bitcast i8** [[T0]] to i8* +// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8*, i8** %0, i32 0 +// CHECK-NEXT: store i8* [[T1]], i8** [[T2]], align 8 +// CHECK-NEXT: ret void + +protocol HasAssocked { + typealias Contents : Assocked +} +struct FulfilledFromAssociatedType : HasSimpleAssoc { + typealias Assoc = PBox +} + +struct UsesVoid : HasSimpleAssoc { + typealias Assoc = () +} \ No newline at end of file diff --git a/test/IRGen/autorelease.sil b/test/IRGen/autorelease.sil index 9c1bf0e7a91da..60bcd16791c61 100644 --- a/test/IRGen/autorelease.sil +++ b/test/IRGen/autorelease.sil @@ -21,7 +21,7 @@ bb0(%0 : $C): sil @foo : $@convention(thin) (@owned C?) -> @autoreleased C? { bb0(%0 : $C?): - autorelease_return %0 : $C? + return %0 : $C? } // x86_64: define i64 @foo(i64) {{.*}} { // x86_64: [[T0:%.*]] = tail call i64 bitcast ([[OBJC]]* ([[OBJC]]*)* @objc_autoreleaseReturnValue to i64 (i64)*)(i64 %0) @@ -48,7 +48,6 @@ sil @bar : $@convention(thin) (@owned C?) -> @owned C? { bb0(%0 : $C?): %1 = function_ref @foo : $@convention(thin) (@owned C?) -> @autoreleased C? %2 = apply %1(%0) : $@convention(thin) (@owned C?) -> @autoreleased C? - strong_retain_autoreleased %2 : $C? return %2 : $C? } // x86_64: define i64 @bar(i64) diff --git a/test/IRGen/autorelease_optimized.sil b/test/IRGen/autorelease_optimized.sil index e3e18e0396eca..a40361683b4a2 100644 --- a/test/IRGen/autorelease_optimized.sil +++ b/test/IRGen/autorelease_optimized.sil @@ -25,9 +25,8 @@ sil @baz : $@convention(thin) (@owned C) -> () { bb0(%0 : $C): %1 = function_ref @foo : $@convention(thin) (@owned C) -> @autoreleased C %2 = apply %1(%0) : $@convention(thin) (@owned C) -> @autoreleased C - strong_retain_autoreleased %2 : $C -// This call is just so that we won't tail-call + // This call is just so that we won't tail-call // objc_retainAutoreleasedReturnValue, which complicates the test. %3 = function_ref @bar : $@convention(thin) (@owned C) -> () apply %3(%2) : $@convention(thin) (@owned C) -> () diff --git a/test/IRGen/bitcast.sil b/test/IRGen/bitcast.sil index c01fe621033dd..e225c9bfb465b 100644 --- a/test/IRGen/bitcast.sil +++ b/test/IRGen/bitcast.sil @@ -91,9 +91,9 @@ bb0(%0 : $ImplicitlyUnwrappedOptional): // CHECK-x86_64: store i64 %{{.*}}, i64* %bitcast.elt._value, align 8 // CHECK-x86_64: store i64 %{{.*}}, i64* %bitcast.elt1._value, align 8 // CHECK-x86_64-NEXT: %{{.*}} = bitcast <{ %Si, %Si }>* %bitcast to %Si* -// CHECK-x86_64-NEXT: [[VAL:%.*]] = getelementptr inbounds %Si, %Si* %2, i32 0, i32 0 +// CHECK-x86_64-NEXT: [[VAL:%.*]] = getelementptr inbounds %Si, %Si* %{{.*}}, i32 0, i32 0 // CHECK-x86_64-NEXT: [[RESULT:%.*]] = load i64, i64* [[VAL]], align 8 -// CHECK-x86_64-NEXT: ret i64 [[RESULT]] +// CHECK-x86_64: ret i64 [[RESULT]] // CHECK-x86_64-NEXT: } sil hidden @unchecked_bitwise_cast : $@convention(thin) (Int, Int) -> Int { bb0(%0 : $Int, %1 : $Int): @@ -120,9 +120,9 @@ bb0(%0 : $Int, %1 : $Int): sil @unchecked_ref_cast_addr : $@convention(thin) (@out U, @in T) -> () { bb0(%0 : $*U, %1 : $*T): %a = alloc_stack $T - copy_addr %1 to [initialization] %a#1 : $*T - unchecked_ref_cast_addr T in %a#1 : $*T to U in %0 : $*U - dealloc_stack %a#0 : $*@local_storage T + copy_addr %1 to [initialization] %a : $*T + unchecked_ref_cast_addr T in %a : $*T to U in %0 : $*U + dealloc_stack %a : $*T destroy_addr %1 : $*T %r = tuple () return %r : $() diff --git a/test/IRGen/bitcast_specialization.swift b/test/IRGen/bitcast_specialization.swift index 26618be64cab5..689e6a2f2616a 100644 --- a/test/IRGen/bitcast_specialization.swift +++ b/test/IRGen/bitcast_specialization.swift @@ -5,7 +5,7 @@ // specialized version fo myDictionaryBridge. // -// A miminized version of _dictionaryBridgeToObjectiveC in the stdlib +// A minimized version of _dictionaryBridgeToObjectiveC in the stdlib public func myDictionaryBridge< SrcType, DestType >( diff --git a/test/IRGen/class.sil b/test/IRGen/class.sil index 61403091c2d6b..d79646b635ec2 100644 --- a/test/IRGen/class.sil +++ b/test/IRGen/class.sil @@ -152,7 +152,7 @@ bb0(%0 : $@thick C.Type): // CHECK: %1 = bitcast %C5class1C* %0 to %objc_object* // CHECK: call %objc_object* @objc_autorelease(%objc_object* %1) // CHECK: ret %C5class1C* %0 -sil @autorelease : $@convention(thin) (@owned C) -> @autoreleased C { +sil @autorelease : $@convention(thin) (@owned C) -> C { entry(%c : $C): autorelease_value %c : $C return %c : $C @@ -162,7 +162,7 @@ entry(%c : $C): // CHECK: %1 = inttoptr i64 %0 to %objc_object* // CHECK: call %objc_object* @objc_autorelease(%objc_object* %1) // CHECK: ret i64 %0 -sil @autorelease_optional : $@convention(thin) (@owned C?) -> @autoreleased C? { +sil @autorelease_optional : $@convention(thin) (@owned C?) -> C? { entry(%c : $C?): autorelease_value %c : $C? return %c : $C? diff --git a/test/IRGen/class_bounded_generics.swift b/test/IRGen/class_bounded_generics.swift index 04d0bb80d7ab3..f6907441651f9 100644 --- a/test/IRGen/class_bounded_generics.swift +++ b/test/IRGen/class_bounded_generics.swift @@ -93,7 +93,7 @@ func class_bounded_archetype_method(x: T, y: T) { x.classBoundBinaryMethod(y) // CHECK: [[WITNESS_ENTRY:%.*]] = getelementptr inbounds i8*, i8** %T.ClassBoundBinary, i32 1 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ENTRY]], align 8 - // CHECK: call void bitcast (void (%swift.refcounted*)* @swift_unknownRetain to void (%objc_object*)*)(%objc_object* [[Y:%.*]]) + // CHECK: call void @swift_unknownRetain(%objc_object* [[Y:%.*]]) // CHECK: [[WITNESS_FUNC:%.*]] = bitcast i8* [[WITNESS]] to void (%objc_object*, %objc_object*, %swift.type*) // CHECK: call void [[WITNESS_FUNC]](%objc_object* [[Y]], %objc_object* %0, %swift.type* {{.*}}) } @@ -257,6 +257,6 @@ func class_bounded_metatype(t : T) { t.dynamicType.foo() } -class WeakRef { +class WeakRef { weak var value: T? } diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift index 03eaee43a2967..2c3d68a38b485 100644 --- a/test/IRGen/class_resilience.swift +++ b/test/IRGen/class_resilience.swift @@ -1,75 +1,260 @@ -// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | FileCheck %s +// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime // RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-ir -enable-resilience -O %s -// CHECK: %Si = type <{ [[INT:i32|i64]] }> +// CHECK: %swift.type = type { [[INT:i32|i64]] } +// CHECK: @_TWvdvC16class_resilience26ClassWithResilientProperty1sV16resilient_struct4Size = global [[INT]] 0 +// CHECK: @_TWvdvC16class_resilience26ClassWithResilientProperty5colorVs5Int32 = global [[INT]] 0 + +// CHECK: @_TWvdvC16class_resilience33ClassWithResilientlySizedProperty1rV16resilient_struct9Rectangle = global [[INT]] 0 +// CHECK: @_TWvdvC16class_resilience33ClassWithResilientlySizedProperty5colorVs5Int32 = global [[INT]] 0 + +// CHECK: @_TWvdvC16class_resilience14ResilientChild5fieldVs5Int32 = global [[INT]] {{12|16}} +// CHECK: @_TWvivC16class_resilience21ResilientGenericChild5fieldVs5Int32 = global [[INT]] {{56|88}} + +// CHECK: @_TWvdvC16class_resilience28ClassWithMyResilientProperty1rVS_17MyResilientStruct = constant [[INT]] {{12|16}} +// CHECK: @_TWvdvC16class_resilience28ClassWithMyResilientProperty5colorVs5Int32 = constant [[INT]] {{16|20}} + +// CHECK: @_TWvdvC16class_resilience30ClassWithIndirectResilientEnum1sO14resilient_enum10FunnyShape = constant [[INT]] {{12|16}} +// CHECK: @_TWvdvC16class_resilience30ClassWithIndirectResilientEnum5colorVs5Int32 = constant [[INT]] {{16|24}} + +import resilient_class import resilient_struct import resilient_enum + // Concrete class with resilient stored property -public class MyRectangle { +public class ClassWithResilientProperty { public let p: Point public let s: Size - public let color: Int + public let color: Int32 - public init(p: Point, s: Size, color: Int) { + public init(p: Point, s: Size, color: Int32) { self.p = p self.s = s self.color = color } } + // Concrete class with non-fixed size stored property -public class ClassWithResilientLayout { +public class ClassWithResilientlySizedProperty { public let r: Rectangle - public let color: Int + public let color: Int32 + + public init(r: Rectangle, color: Int32) { + self.r = r + self.color = color + } +} + + +// Concrete class with resilient stored property that +// is fixed-layout inside this resilience domain + +public struct MyResilientStruct { + public let x: Int32 +} + +public class ClassWithMyResilientProperty { + public let r: MyResilientStruct + public let color: Int32 - public init(r: Rectangle, color: Int) { + public init(r: MyResilientStruct, color: Int32) { self.r = r self.color = color } } + // Enums with indirect payloads are fixed-size public class ClassWithIndirectResilientEnum { public let s: FunnyShape - public let color: Int + public let color: Int32 - public init(s: FunnyShape, color: Int) { + public init(s: FunnyShape, color: Int32) { self.s = s self.color = color } } -// FIXME: This is bogus since we don't emit code to initialize the -// global ivar offsets yet. +// Superclass is resilient, so the number of fields and their +// offsets is not known at compile time + +public class ResilientChild : ResilientOutsideParent { + public let field: Int32 = 0 +} + + +// Superclass is resilient, so the number of fields and their +// offsets is not known at compile time + +public class ResilientGenericChild : ResilientGenericOutsideParent { + public let field: Int32 = 0 +} + + +// Superclass is resilient and has a resilient value type payload, +// but everything is in one module + + +public class MyResilientParent { + public let s: MyResilientStruct = MyResilientStruct(x: 0) +} + +public class MyResilientChild : MyResilientParent { + public let field: Int32 = 0 +} + + +// ClassWithResilientProperty metadata accessor -// CHECK-LABEL: define {{i32|i64}} @_TFC16class_resilience11MyRectangleg5colorSi(%C16class_resilience11MyRectangle*) -// CHECK: [[OFFSET:%.*]] = load [[INT]], [[INT]]* @_TWvdvC16class_resilience11MyRectangle5colorSi -// CHECK-NEXT: [[PTR:%.*]] = bitcast %C16class_resilience11MyRectangle* %0 to i8* +// CHECK-LABEL: define %swift.type* @_TMaC16class_resilience26ClassWithResilientProperty() +// CHECK: [[CACHE:%.*]] = load %swift.type*, %swift.type** @_TMLC16class_resilience26ClassWithResilientProperty +// CHECK-NEXT: [[COND:%.*]] = icmp eq %swift.type* [[CACHE]], null +// CHECK-NEXT: br i1 [[COND]], label %cacheIsNull, label %cont + +// CHECK: cacheIsNull: +// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_getResilientMetadata( +// CHECK-NEXT: store %swift.type* [[METADATA]], %swift.type** @_TMLC16class_resilience26ClassWithResilientProperty +// CHECK-NEXT: br label %cont + +// CHECK: cont: +// CHECK-NEXT: [[RESULT:%.*]] = phi %swift.type* [ [[CACHE]], %entry ], [ [[METADATA]], %cacheIsNull ] +// CHECK-NEXT: ret %swift.type* [[RESULT]] + + +// ClassWithResilientProperty.color getter + +// CHECK-LABEL: define i32 @_TFC16class_resilience26ClassWithResilientPropertyg5colorVs5Int32(%C16class_resilience26ClassWithResilientProperty*) +// CHECK: [[OFFSET:%.*]] = load [[INT]], [[INT]]* @_TWvdvC16class_resilience26ClassWithResilientProperty5colorVs5Int32 +// CHECK-NEXT: [[PTR:%.*]] = bitcast %C16class_resilience26ClassWithResilientProperty* %0 to i8* // CHECK-NEXT: [[FIELD_ADDR:%.*]] = getelementptr inbounds i8, i8* [[PTR]], [[INT]] [[OFFSET]] -// CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %Si* -// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Si, %Si* [[FIELD_PTR]], i32 0, i32 0 -// CHECK-NEXT: [[FIELD_VALUE:%.*]] = load [[INT]], [[INT]]* [[FIELD_PAYLOAD]] -// CHECK-NEXT: ret [[INT]] [[FIELD_VALUE]] +// CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %Vs5Int32* +// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_PTR]], i32 0, i32 0 +// CHECK-NEXT: [[FIELD_VALUE:%.*]] = load i32, i32* [[FIELD_PAYLOAD]] +// CHECK-NEXT: ret i32 [[FIELD_VALUE]] + + +// ClassWithResilientlySizedProperty metadata accessor + +// CHECK-LABEL: define %swift.type* @_TMaC16class_resilience33ClassWithResilientlySizedProperty() +// CHECK: [[CACHE:%.*]] = load %swift.type*, %swift.type** @_TMLC16class_resilience33ClassWithResilientlySizedProperty +// CHECK-NEXT: [[COND:%.*]] = icmp eq %swift.type* [[CACHE]], null +// CHECK-NEXT: br i1 [[COND]], label %cacheIsNull, label %cont + +// CHECK: cacheIsNull: +// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_getResilientMetadata( +// CHECK-NEXT: store %swift.type* [[METADATA]], %swift.type** @_TMLC16class_resilience33ClassWithResilientlySizedProperty +// CHECK-NEXT: br label %cont +// CHECK: cont: +// CHECK-NEXT: [[RESULT:%.*]] = phi %swift.type* [ [[CACHE]], %entry ], [ [[METADATA]], %cacheIsNull ] +// CHECK-NEXT: ret %swift.type* [[RESULT]] -// CHECK-LABEL: define {{i32|i64}} @_TFC16class_resilience24ClassWithResilientLayoutg5colorSi(%C16class_resilience24ClassWithResilientLayout*) -// CHECK: [[OFFSET:%.*]] = load [[INT]], [[INT]]* @_TWvdvC16class_resilience24ClassWithResilientLayout5colorSi -// CHECK-NEXT: [[PTR:%.*]] = bitcast %C16class_resilience24ClassWithResilientLayout* %0 to i8* + +// ClassWithResilientlySizedProperty.color getter + +// CHECK-LABEL: define i32 @_TFC16class_resilience33ClassWithResilientlySizedPropertyg5colorVs5Int32(%C16class_resilience33ClassWithResilientlySizedProperty*) +// CHECK: [[OFFSET:%.*]] = load [[INT]], [[INT]]* @_TWvdvC16class_resilience33ClassWithResilientlySizedProperty5colorVs5Int32 +// CHECK-NEXT: [[PTR:%.*]] = bitcast %C16class_resilience33ClassWithResilientlySizedProperty* %0 to i8* // CHECK-NEXT: [[FIELD_ADDR:%.*]] = getelementptr inbounds i8, i8* [[PTR]], [[INT]] [[OFFSET]] -// CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %Si* -// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Si, %Si* %.color, i32 0, i32 0 -// CHECK-NEXT: [[FIELD_VALUE:%.*]] = load [[INT]], [[INT]]* [[FIELD_PAYLOAD]] -// CHECK-NEXT: ret [[INT]] [[FIELD_VALUE]] +// CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %Vs5Int32* +// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_PTR]], i32 0, i32 0 +// CHECK-NEXT: [[FIELD_VALUE:%.*]] = load i32, i32* [[FIELD_PAYLOAD]] +// CHECK-NEXT: ret i32 [[FIELD_VALUE]] + + +// ClassWithIndirectResilientEnum.color getter + +// CHECK-LABEL: define i32 @_TFC16class_resilience30ClassWithIndirectResilientEnumg5colorVs5Int32(%C16class_resilience30ClassWithIndirectResilientEnum*) +// CHECK: [[FIELD_PTR:%.*]] = getelementptr inbounds %C16class_resilience30ClassWithIndirectResilientEnum, %C16class_resilience30ClassWithIndirectResilientEnum* %0, i32 0, i32 2 +// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_PTR]], i32 0, i32 0 +// CHECK-NEXT: [[FIELD_VALUE:%.*]] = load i32, i32* [[FIELD_PAYLOAD]] +// CHECK-NEXT: ret i32 [[FIELD_VALUE]] + + +// ResilientChild.field getter + +// CHECK-LABEL: define i32 @_TFC16class_resilience14ResilientChildg5fieldVs5Int32(%C16class_resilience14ResilientChild*) +// CHECK: [[OFFSET:%.*]] = load [[INT]], [[INT]]* @_TWvdvC16class_resilience14ResilientChild5fieldVs5Int32 +// CHECK-NEXT: [[PTR:%.*]] = bitcast %C16class_resilience14ResilientChild* %0 to i8* +// CHECK-NEXT: [[FIELD_ADDR:%.*]] = getelementptr inbounds i8, i8* [[PTR]], [[INT]] [[OFFSET]] +// CHECK-NEXT: [[FIELD_PTR:%.*]] = bitcast i8* [[FIELD_ADDR]] to %Vs5Int32* +// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_PTR]], i32 0, i32 0 +// CHECK-NEXT: [[FIELD_VALUE:%.*]] = load i32, i32* [[FIELD_PAYLOAD]] +// CHECK-NEXT: ret i32 [[FIELD_VALUE]] + + +// ResilientGenericChild.field getter + + +// CHECK-LABEL: define i32 @_TFC16class_resilience21ResilientGenericChildg5fieldVs5Int32(%C16class_resilience21ResilientGenericChild*) + +// FIXME: we could eliminate the unnecessary isa load by lazily emitting +// metadata sources in EmitPolymorphicParameters + +// CHECK: [[T_BOX:%.*]] = alloca %swift.type* +// CHECK: store {{.*}}, %swift.type** [[T_BOX]] + +// CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds %C16class_resilience21ResilientGenericChild, %C16class_resilience21ResilientGenericChild* %0, i32 0, i32 0, i32 0 +// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]] +// CHECK-NEXT: [[INDIRECT_OFFSET:%.*]] = load [[INT]], [[INT]]* @_TWvivC16class_resilience21ResilientGenericChild5fieldVs5Int32 +// CHECK-NEXT: [[ISA_ADDR:%.*]] = bitcast %swift.type* [[ISA]] to i8* +// CHECK-NEXT: [[FIELD_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[ISA_ADDR]], [[INT]] [[INDIRECT_OFFSET]] +// CHECK-NEXT: [[FIELD_OFFSET_ADDR:%.*]] = bitcast i8* [[FIELD_OFFSET_TMP]] to [[INT]]* +// CHECK-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_ADDR:%.*]] +// CHECK-NEXT: [[OBJECT:%.*]] = bitcast %C16class_resilience21ResilientGenericChild* %0 to i8* +// CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds i8, i8* [[OBJECT]], [[INT]] [[FIELD_OFFSET]] +// CHECK-NEXT: [[FIELD_ADDR:%.*]] = bitcast i8* [[ADDR]] to %Vs5Int32* +// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_ADDR]], i32 0, i32 0 +// CHECK-NEXT: [[RESULT:%.*]] = load i32, i32* [[PAYLOAD_ADDR]] +// CHECK-NEXT: ret i32 [[RESULT]] + + +// MyResilientChild.field getter + +// CHECK-LABEL: define i32 @_TFC16class_resilience16MyResilientChildg5fieldVs5Int32(%C16class_resilience16MyResilientChild*) +// CHECK: [[FIELD_ADDR:%.*]] = getelementptr inbounds %C16class_resilience16MyResilientChild, %C16class_resilience16MyResilientChild* %0, i32 0, i32 2 +// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_ADDR]], i32 0, i32 0 +// CHECK-NEXT: [[RESULT:%.*]] = load i32, i32* [[PAYLOAD_ADDR]] +// CHECK-NEXT: ret i32 [[RESULT]] + + +// ClassWithResilientProperty metadata instantiation function + + +// CHECK-LABEL: define private %swift.type* @create_generic_metadata_ClassWithResilientProperty(%swift.type_pattern*, i8**) +// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata( +// CHECK: [[SIZE_METADATA:%.*]] = call %swift.type* @_TMaV16resilient_struct4Size() +// CHECK: call void @swift_initClassMetadata_UniversalStrategy( +// CHECK-native: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to [[INT]]* +// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_PTR]], [[INT]] 12 +// CHECK-native-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]] +// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @_TWvdvC16class_resilience26ClassWithResilientProperty1sV16resilient_struct4Size +// CHECK-native-NEXT: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to [[INT]]* +// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_PTR]], [[INT]] 13 +// CHECK-native-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]] +// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @_TWvdvC16class_resilience26ClassWithResilientProperty5colorVs5Int32 +// CHECK: ret %swift.type* [[METADATA]] + +// ClassWithResilientlySizedProperty metadata instantiation function -// CHECK-LABEL: define {{i32|i64}} @_TFC16class_resilience30ClassWithIndirectResilientEnumg5colorSi(%C16class_resilience30ClassWithIndirectResilientEnum*) -// CHECK: [[FIELD_PTR:%.*]] = getelementptr inbounds %C16class_resilience30ClassWithIndirectResilientEnum, %C16class_resilience30ClassWithIndirectResilientEnum* %0, i32 0, i32 2 -// CHECK-NEXT: [[FIELD_PAYLOAD:%.*]] = getelementptr inbounds %Si, %Si* [[FIELD_PTR]], i32 0, i32 0 -// CHECK-NEXT: [[FIELD_VALUE:%.*]] = load [[INT]], [[INT]]* [[FIELD_PAYLOAD]] -// CHECK-NEXT: ret [[INT]] [[FIELD_VALUE]] +// CHECK-LABEL: define private %swift.type* @create_generic_metadata_ClassWithResilientlySizedProperty(%swift.type_pattern*, i8**) +// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata( +// CHECK: [[RECTANGLE_METADATA:%.*]] = call %swift.type* @_TMaV16resilient_struct9Rectangle() +// CHECK: call void @swift_initClassMetadata_UniversalStrategy( +// CHECK-native: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to [[INT]]* +// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_PTR]], [[INT]] 11 +// CHECK-native-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]] +// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @_TWvdvC16class_resilience33ClassWithResilientlySizedProperty1rV16resilient_struct9Rectangle +// CHECK-native-NEXT: [[METADATA_PTR:%.*]] = bitcast %swift.type* [[METADATA]] to [[INT]]* +// CHECK-native-NEXT: [[FIELD_OFFSET_PTR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_PTR]], [[INT]] 12 +// CHECK-native-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_PTR]] +// CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @_TWvdvC16class_resilience33ClassWithResilientlySizedProperty5colorVs5Int32 +// CHECK: ret %swift.type* [[METADATA]] diff --git a/test/IRGen/class_resilience_objc.swift b/test/IRGen/class_resilience_objc.swift new file mode 100644 index 0000000000000..a98dba7d5d1e5 --- /dev/null +++ b/test/IRGen/class_resilience_objc.swift @@ -0,0 +1,85 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-source-import -emit-ir -o - -primary-file %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize + +// REQUIRES: objc_interop + +// CHECK: %swift.type = type { [[INT:i32|i64]] } + +import Foundation + +public class FixedLayoutObjCSubclass : NSObject { + // This field uses constant direct access because NSObject has fixed layout. + public final var field: Int32 = 0 +}; + +// CHECK-LABEL: define hidden void @_TF21class_resilience_objc29testConstantDirectFieldAccessFCS_23FixedLayoutObjCSubclassT_(%C21class_resilience_objc23FixedLayoutObjCSubclass*) +// CHECK: [[FIELD_ADDR:%.*]] = getelementptr inbounds %C21class_resilience_objc23FixedLayoutObjCSubclass, %C21class_resilience_objc23FixedLayoutObjCSubclass* %0, i32 0, i32 1 +// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* %1, i32 0, i32 0 +// CHECK-NEXT: store i32 10, i32* [[PAYLOAD_ADDR]] + +func testConstantDirectFieldAccess(o: FixedLayoutObjCSubclass) { + o.field = 10 +} + +public class NonFixedLayoutObjCSubclass : NSCoder { + // This field uses non-constant direct access because NSCoder has resilient + // layout. + public final var field: Int32 = 0 +} + +// CHECK-LABEL: define hidden void @_TF21class_resilience_objc32testNonConstantDirectFieldAccessFCS_26NonFixedLayoutObjCSubclassT_(%C21class_resilience_objc26NonFixedLayoutObjCSubclass*) +// CHECK: [[OFFSET:%.*]] = load [[INT]], [[INT]]* @_TWvdvC21class_resilience_objc26NonFixedLayoutObjCSubclass5fieldVs5Int32 +// CHECK-NEXT: [[OBJECT:%.*]] = bitcast %C21class_resilience_objc26NonFixedLayoutObjCSubclass* %0 to i8* +// CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds i8, i8* [[OBJECT]], [[INT]] [[OFFSET]] +// CHECK-NEXT: [[FIELD_ADDR:%.*]] = bitcast i8* [[ADDR]] to %Vs5Int32* +// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_ADDR]], i32 0, i32 0 +// CHECK-NEXT: store i32 10, i32* [[PAYLOAD_ADDR]] + +func testNonConstantDirectFieldAccess(o: NonFixedLayoutObjCSubclass) { + o.field = 10 +} + +public class GenericObjCSubclass : NSCoder { + public final var content: T + public final var field: Int32 = 0 + + public init(content: T) { + self.content = content + } +} + +// CHECK-LABEL: define hidden void @_TF21class_resilience_objc31testConstantIndirectFieldAccessurFGCS_19GenericObjCSubclassx_T_(%C21class_resilience_objc19GenericObjCSubclass*) + +// FIXME: we could eliminate the unnecessary isa load by lazily emitting +// metadata sources in EmitPolymorphicParameters + +// CHECK: [[T_BOX:%.*]] = alloca %swift.type* +// CHECK: store {{.*}}, %swift.type** [[T_BOX]] + +// CHECK-32-NEXT: [[ADDR:%.*]] = bitcast %C21class_resilience_objc19GenericObjCSubclass* %0 to %swift.type** +// CHECK-32-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]] + +// CHECK-64-NEXT: [[ADDR:%.*]] = bitcast %C21class_resilience_objc19GenericObjCSubclass* %0 to [[INT]]* +// CHECK-64-NEXT: [[ISA:%.*]] = load [[INT]], [[INT]]* [[ADDR]] +// CHECK-64-NEXT: [[ISA_MASK:%.*]] = load [[INT]], [[INT]]* @swift_isaMask +// CHECK-64-NEXT: [[ISA_VALUE:%.*]] = and [[INT]] [[ISA]], [[ISA_MASK]] +// CHECK-64-NEXT: [[ISA:%.*]] = inttoptr [[INT]] [[ISA_VALUE]] to %swift.type* + +// CHECK-NEXT: [[ISA_ADDR:%.*]] = bitcast %swift.type* [[ISA]] to [[INT]]* + +// CHECK-32-NEXT: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[ISA_ADDR]], [[INT]] 16 + +// CHECK-64-NEXT: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[ISA_ADDR]], [[INT]] 13 + +// CHECK-NEXT: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* [[FIELD_OFFSET_ADDR:%.*]] +// CHECK-NEXT: [[OBJECT:%.*]] = bitcast %C21class_resilience_objc19GenericObjCSubclass* %0 to i8* +// CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds i8, i8* [[OBJECT]], [[INT]] [[FIELD_OFFSET]] +// CHECK-NEXT: [[FIELD_ADDR:%.*]] = bitcast i8* [[ADDR]] to %Vs5Int32* +// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = getelementptr inbounds %Vs5Int32, %Vs5Int32* [[FIELD_ADDR]], i32 0, i32 0 +// CHECK-NEXT: store i32 10, i32* [[PAYLOAD_ADDR]] + +func testConstantIndirectFieldAccess(o: GenericObjCSubclass) { + // This field uses constant indirect access because NSCoder has resilient + // layout. Non-constant indirect is never needed for Objective-C classes + // because the field offset vector only contains Swift field offsets. + o.field = 10 +} diff --git a/test/IRGen/class_stack_alloc.sil b/test/IRGen/class_stack_alloc.sil index 0bbf36b515d00..65a2af2b6b0d1 100644 --- a/test/IRGen/class_stack_alloc.sil +++ b/test/IRGen/class_stack_alloc.sil @@ -54,9 +54,9 @@ bb0: %s1 = alloc_stack $TestStruct %f = function_ref @unknown_func : $@convention(thin) (@inout TestStruct) -> () - %a = apply %f(%s1#1) : $@convention(thin) (@inout TestStruct) -> () + %a = apply %f(%s1) : $@convention(thin) (@inout TestStruct) -> () - dealloc_stack %s1#0 : $*@local_storage TestStruct + dealloc_stack %s1 : $*TestStruct strong_release %o1 : $TestClass strong_release %o2 : $TestClass diff --git a/test/IRGen/closure.swift b/test/IRGen/closure.swift index 65f7527b3a3dd..d93d516457b16 100644 --- a/test/IRGen/closure.swift +++ b/test/IRGen/closure.swift @@ -26,25 +26,23 @@ func b(seq seq: T) -> (Int) -> Int { // CHECK: } // -- Closure entry point -// CHECK: define linkonce_odr hidden i64 @[[CLOSURE2:_TFF7closure1buRxS_9OrdinablerFT3seqx_FSiSiU_FSiSi]](i64, %swift.refcounted*, %swift.opaque* nocapture, %swift.type* %T, i8** %T.Ordinable) {{.*}} { +// CHECK: define linkonce_odr hidden i64 @[[CLOSURE2:_TFF7closure1buRxS_9OrdinablerFT3seqx_FSiSiU_FSiSi]](i64, %swift.refcounted*, %swift.type* %T, i8** %T.Ordinable) {{.*}} { // -- partial_apply stub // CHECK: define internal i64 @_TPA_[[CLOSURE2]](i64, %swift.refcounted*) {{.*}} { // CHECK: entry: -// CHECK: [[CONTEXT:%.*]] = bitcast %swift.refcounted* %1 to <{ %swift.refcounted, [16 x i8], %swift.refcounted*, %swift.opaque* }>* -// CHECK: [[BINDINGSADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [16 x i8], %swift.refcounted*, %swift.opaque* }>, <{ %swift.refcounted, [16 x i8], %swift.refcounted*, %swift.opaque* }>* [[CONTEXT]], i32 0, i32 1 +// CHECK: [[CONTEXT:%.*]] = bitcast %swift.refcounted* %1 to <{ %swift.refcounted, [16 x i8], %swift.refcounted* }>* +// CHECK: [[BINDINGSADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [16 x i8], %swift.refcounted* }>, <{ %swift.refcounted, [16 x i8], %swift.refcounted* }>* [[CONTEXT]], i32 0, i32 1 // CHECK: [[TYPEADDR:%.*]] = bitcast [16 x i8]* [[BINDINGSADDR]] // CHECK: [[TYPE:%.*]] = load %swift.type*, %swift.type** [[TYPEADDR]], align 8 // CHECK: [[WITNESSADDR_0:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[TYPEADDR]], i32 1 // CHECK: [[WITNESSADDR:%.*]] = bitcast %swift.type** [[WITNESSADDR_0]] // CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[WITNESSADDR]], align 8 -// CHECK: [[BOXADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [16 x i8], %swift.refcounted*, %swift.opaque* }>, <{ %swift.refcounted, [16 x i8], %swift.refcounted*, %swift.opaque* }>* [[CONTEXT]], i32 0, i32 2 +// CHECK: [[BOXADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [16 x i8], %swift.refcounted* }>, <{ %swift.refcounted, [16 x i8], %swift.refcounted* }>* [[CONTEXT]], i32 0, i32 2 // CHECK: [[BOX:%.*]] = load %swift.refcounted*, %swift.refcounted** [[BOXADDR]], align 8 // CHECK: call void @swift_retain(%swift.refcounted* [[BOX]]) -// CHECK: [[ADDRADDR:%.*]] = getelementptr inbounds <{ %swift.refcounted, [16 x i8], %swift.refcounted*, %swift.opaque* }>, <{ %swift.refcounted, [16 x i8], %swift.refcounted*, %swift.opaque* }>* [[CONTEXT]], i32 0, i32 3 -// CHECK: [[ADDR:%.*]] = load %swift.opaque*, %swift.opaque** [[ADDRADDR]], align 8 // CHECK: call void @swift_release(%swift.refcounted* %1) -// CHECK: [[RES:%.*]] = tail call i64 @[[CLOSURE2]](i64 %0, %swift.refcounted* [[BOX]], %swift.opaque* nocapture [[ADDR]], %swift.type* [[TYPE]], i8** [[WITNESS]]) +// CHECK: [[RES:%.*]] = tail call i64 @[[CLOSURE2]](i64 %0, %swift.refcounted* [[BOX]], %swift.type* [[TYPE]], i8** [[WITNESS]]) // CHECK: ret i64 [[RES]] // CHECK: } diff --git a/test/IRGen/concrete_inherits_generic_base.swift b/test/IRGen/concrete_inherits_generic_base.swift index 388b3e5b3a94d..6e7351669454a 100644 --- a/test/IRGen/concrete_inherits_generic_base.swift +++ b/test/IRGen/concrete_inherits_generic_base.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -module-name foo -emit-ir %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -module-name foo -emit-ir %s | FileCheck %s // -- Classes with generic bases can't go in the @objc_classes list, since // they need runtime initialization before they're valid. @@ -18,14 +18,33 @@ class Base { } // CHECK-LABEL: define %swift.type* @_TMaC3foo12SuperDerived() -// CHECK: [[SUPER:%.*]] = call %swift.type* @_TMaC3foo7Derived() -// CHECK: call void @swift_initializeSuperclass({{.*}}@_TMfC3foo12SuperDerived{{.*}}, %swift.type* [[SUPER]]) +// CHECK: [[CACHE:%.*]] = load %swift.type*, %swift.type** @_TMLC3foo12SuperDerived +// CHECK-NEXT: [[COND:%.*]] = icmp eq %swift.type* [[CACHE]], null +// CHECK-NEXT: br i1 [[COND]], label %cacheIsNull, label %cont + +// CHECK: cacheIsNull: +// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_getResilientMetadata( +// CHECK-NEXT: store %swift.type* [[METADATA]], %swift.type** @_TMLC3foo12SuperDerived +// CHECK-NEXT: br label %cont +// CHECK: cont: +// CHECK-NEXT: [[RESULT:%.*]] = phi %swift.type* [ [[CACHE]], %entry ], [ [[METADATA]], %cacheIsNull ] +// CHECK-NEXT: ret %swift.type* [[RESULT]] + class SuperDerived: Derived { } // CHECK-LABEL: define %swift.type* @_TMaC3foo7Derived() -// CHECK: [[SUPER:%.*]] = call %swift.type* @_TMaGC3foo4BaseSS_() -// CHECK: call void @swift_initializeSuperclass({{.*}}@_TMfC3foo7Derived{{.*}}, %swift.type* [[SUPER]]) +// CHECK: [[CACHE:%.*]] = load %swift.type*, %swift.type** @_TMLC3foo7Derived +// CHECK-NEXT: [[COND:%.*]] = icmp eq %swift.type* [[CACHE]], null +// CHECK-NEXT: br i1 [[COND]], label %cacheIsNull, label %cont + +// CHECK: cacheIsNull: +// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_getResilientMetadata( +// CHECK-NEXT: store %swift.type* [[METADATA]], %swift.type** @_TMLC3foo7Derived +// CHECK-NEXT: br label %cont +// CHECK: cont: +// CHECK-NEXT: [[RESULT:%.*]] = phi %swift.type* [ [[CACHE]], %entry ], [ [[METADATA]], %cacheIsNull ] +// CHECK-NEXT: ret %swift.type* [[RESULT]] class Derived: Base { var third: String @@ -49,3 +68,10 @@ presentBase(SuperDerived(x: "two")) presentBase(Derived(x: "two")) presentBase(Base(x: "two")) presentBase(Base(x: 2)) + +// CHECK-LABEL: define private %swift.type* @create_generic_metadata_SuperDerived(%swift.type_pattern*, i8**) +// CHECK: [[TMP:%.*]] = call %swift.type* @_TMaC3foo7Derived() +// CHECK-NEXT: [[SUPER:%.*]] = bitcast %swift.type* [[TMP:%.*]] to %objc_class* +// CHECK-NEXT: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]]) +// CHECK: call void @swift_initializeSuperclass(%swift.type* [[METADATA]], i1 false) +// CHECK-NEXT: ret %swift.type* [[METADATA]] diff --git a/test/IRGen/dynamic_cast.sil b/test/IRGen/dynamic_cast.sil index e73a0a3094a86..4e0d7b26137c6 100644 --- a/test/IRGen/dynamic_cast.sil +++ b/test/IRGen/dynamic_cast.sil @@ -28,9 +28,9 @@ bb0(%0 : $*P): // CHECK: [[T3:%.*]] = call [[TYPE:%.*]]* @_TMaP12dynamic_cast1P_() // CHECK: call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], [[TYPE]]* [[T3]], [[TYPE]]* {{.*}}, [[LLVM_PTRSIZE_INT]] 7) %1 = alloc_stack $S - unconditional_checked_cast_addr take_always P in %0 : $*P to S in %1#1 : $*S - destroy_addr %1#1 : $*S - dealloc_stack %1#0 : $*@local_storage S + unconditional_checked_cast_addr take_always P in %0 : $*P to S in %1 : $*S + destroy_addr %1 : $*S + dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } @@ -47,9 +47,9 @@ bb0(%0 : $*P): // CHECK: [[T3:%.*]] = call [[TYPE:%.*]]* @_TMaP12dynamic_cast1P_() // CHECK: call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], [[TYPE]]* [[T3]], [[TYPE]]* {{.*}}, [[LLVM_PTRSIZE_INT]] 3) %1 = alloc_stack $S - unconditional_checked_cast_addr take_on_success P in %0 : $*P to S in %1#1 : $*S - destroy_addr %1#1 : $*S - dealloc_stack %1#0 : $*@local_storage S + unconditional_checked_cast_addr take_on_success P in %0 : $*P to S in %1 : $*S + destroy_addr %1 : $*S + dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } @@ -63,9 +63,9 @@ bb0(%0 : $*P): // CHECK: [[T3:%.*]] = call [[TYPE:%.*]]* @_TMaP12dynamic_cast1P_() // CHECK: call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], [[TYPE]]* [[T3]], [[TYPE]]* {{.*}}, [[LLVM_PTRSIZE_INT]] 1) %1 = alloc_stack $S - unconditional_checked_cast_addr copy_on_success P in %0 : $*P to S in %1#1 : $*S - destroy_addr %1#1 : $*S - dealloc_stack %1#0 : $*@local_storage S + unconditional_checked_cast_addr copy_on_success P in %0 : $*P to S in %1 : $*S + destroy_addr %1 : $*S + dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } @@ -80,12 +80,12 @@ bb0(%0 : $*P): // CHECK: [[T4:%.*]] = call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], [[TYPE]]* [[T3]], [[TYPE]]* {{.*}}, [[LLVM_PTRSIZE_INT]] 6) // CHECK: br i1 [[T4]], %1 = alloc_stack $S - checked_cast_addr_br take_always P in %0 : $*P to S in %1#1 : $*S, bb1, bb2 + checked_cast_addr_br take_always P in %0 : $*P to S in %1 : $*S, bb1, bb2 bb1: br bb2 bb2: - destroy_addr %1#1 : $*S - dealloc_stack %1#0 : $*@local_storage S + destroy_addr %1 : $*S + dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } @@ -100,12 +100,12 @@ bb0(%0 : $*P): // CHECK: [[T4:%.*]] = call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], [[TYPE]]* [[T3]], [[TYPE]]* {{.*}}, [[LLVM_PTRSIZE_INT]] 2) // CHECK: br i1 [[T4]], %1 = alloc_stack $S - checked_cast_addr_br take_on_success P in %0 : $*P to S in %1#1 : $*S, bb1, bb2 + checked_cast_addr_br take_on_success P in %0 : $*P to S in %1 : $*S, bb1, bb2 bb1: br bb2 bb2: - destroy_addr %1#1 : $*S - dealloc_stack %1#0 : $*@local_storage S + destroy_addr %1 : $*S + dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } @@ -120,12 +120,12 @@ bb0(%0 : $*P): // CHECK: [[T4:%.*]] = call i1 @swift_dynamicCast([[OPAQUE]]* [[T1]], [[OPAQUE]]* [[T2]], [[TYPE]]* [[T3]], [[TYPE]]* {{.*}}, [[LLVM_PTRSIZE_INT]] 0) // CHECK: br i1 [[T4]], %1 = alloc_stack $S - checked_cast_addr_br copy_on_success P in %0 : $*P to S in %1#1 : $*S, bb1, bb2 + checked_cast_addr_br copy_on_success P in %0 : $*P to S in %1 : $*S, bb1, bb2 bb1: br bb2 bb2: - destroy_addr %1#1 : $*S - dealloc_stack %1#0 : $*@local_storage S + destroy_addr %1 : $*S + dealloc_stack %1 : $*S %2 = tuple () return %2 : $() } diff --git a/test/IRGen/dynamic_lookup.sil b/test/IRGen/dynamic_lookup.sil index 9aab8d395d326..31bb8d6fd4e25 100644 --- a/test/IRGen/dynamic_lookup.sil +++ b/test/IRGen/dynamic_lookup.sil @@ -62,8 +62,9 @@ bb0(%0 : $AnyObject): %6 = open_existential_ref %4 : $AnyObject to $@opened("01234567-89ab-cdef-0123-000000000000") AnyObject %7 = unchecked_ref_cast %6 : $@opened("01234567-89ab-cdef-0123-000000000000") AnyObject to $Builtin.UnknownObject - // CHECK: [[SEL:%[0-9]+]] = load i8*, i8** @"\01L_selector(f)", align {{(4|8)}} - // CHECK: [[HAS_SEL:%[0-9]]] = call i1 @swift_objcRespondsToSelector(%objc_object* [[OBJECT:%[0-9]+]], i8* [[SEL]]) + // CHECK: [[SEL:%[0-9]+]] = load i8*, i8** @"\01L_selector(f)" + // CHECK: [[RESPONDS:%[0-9]+]] = load i8*, i8** @"\01L_selector(respondsToSelector:)" + // CHECK: [[HAS_SEL:%[0-9]]] = call i1 {{.*}}@objc_msgSend {{.*}}(%objc_object* [[OBJECT:%[0-9]+]], i8* [[RESPONDS]], i8* [[SEL]]) // CHECK: br i1 [[HAS_SEL]] dynamic_method_br %7 : $Builtin.UnknownObject, #X.f!1.foreign, bb1, bb2 @@ -82,7 +83,8 @@ bb3: sil @dynamic_lookup_static_br : $@convention(thin) (@thick AnyObject.Type) -> () { bb0(%0 : $@thick AnyObject.Type): // CHECK: [[SEL:%[0-9]+]] = load i8*, i8** @"\01L_selector(g)", align {{(4|8)}} - // CHECK: [[HAS_SEL:%[0-9]]] = call i1 @swift_objcRespondsToSelector(%objc_object* [[OBJECT:%[0-9]+]], i8* [[SEL]]) + // CHECK: [[RESPONDS:%[0-9]+]] = load i8*, i8** @"\01L_selector(respondsToSelector:)" + // CHECK: [[HAS_SEL:%[0-9]]] = call i1 {{.*}}@objc_msgSend {{.*}}(%objc_object* [[OBJECT:%[0-9]+]], i8* [[RESPONDS]], i8* [[SEL]]) // CHECK: br i1 [[HAS_SEL]] %1 = open_existential_metatype %0 : $@thick AnyObject.Type to $@thick (@opened("EF9BE7CA-DFBF-11E4-99CB-28CFE91AF28F") AnyObject).Type dynamic_method_br %1 : $@thick (@opened("EF9BE7CA-DFBF-11E4-99CB-28CFE91AF28F") AnyObject).Type, #X.g!1.foreign, bb1, bb2 @@ -131,7 +133,8 @@ bb0(%0 : $AnyObject, %1 : $Int): %10 = open_existential_ref %8 : $AnyObject to $@opened("01234567-89ab-cdef-0123-111111111111") AnyObject %11 = unchecked_ref_cast %10 : $@opened("01234567-89ab-cdef-0123-111111111111") AnyObject to $Builtin.UnknownObject // CHECK: [[SEL:%[0-9]+]] = load i8*, i8** @"\01L_selector(objectAtIndexedSubscript:)", align {{(4|8)}} - // CHECK-NEXT: [[HAS_SEL:%[0-9]+]] = call i1 @swift_objcRespondsToSelector(%objc_object* %0, i8* [[SEL]]) + // CHECK: [[RESPONDS:%[0-9]+]] = load i8*, i8** @"\01L_selector(respondsToSelector:)" + // CHECK-NEXT: [[HAS_SEL:%[0-9]]] = call i1 {{.*}}@objc_msgSend {{.*}}(%objc_object* [[OBJECT:%[0-9]+]], i8* [[RESPONDS]], i8* [[SEL]]) // CHECK-NEXT: br i1 [[HAS_SEL]], label [[HAS_METHOD:%[0-9]+]], label [[HAS_METHOD:%[0-9]+]] dynamic_method_br %11 : $Builtin.UnknownObject, #X.subscript!getter.1.foreign, bb1, bb2 diff --git a/test/IRGen/dynamic_self.sil b/test/IRGen/dynamic_self.sil index e4cbbb5d685d8..981871540bb02 100644 --- a/test/IRGen/dynamic_self.sil +++ b/test/IRGen/dynamic_self.sil @@ -14,13 +14,13 @@ protocol P { // CHECK-LABEL: define void @_TF12dynamic_self23testExistentialDispatchFT1pPS_1P__T_ sil @_TF12dynamic_self23testExistentialDispatchFT1pPS_1P__T_ : $@convention(thin) (@in P) -> () { bb0(%0 : $*P): - debug_value_addr %0 : $*P // let p // id: %1 + debug_value_addr %0 : $*P, let, name "p" // id: %1 %2 = alloc_stack $P // users: %3, %4, %12 - copy_addr %0 to [initialization] %2#1 : $*P // id: %3 + copy_addr %0 to [initialization] %2 : $*P // id: %3 // CHECK: call %swift.opaque* // CHECK: call %swift.opaque* - %4 = open_existential_addr %2#1 : $*P to $*@opened("01234567-89ab-cdef-0123-000000000000") P // users: %8, %10 - dealloc_stack %2#0 : $*@local_storage P // id: %12 + %4 = open_existential_addr %2 : $*P to $*@opened("01234567-89ab-cdef-0123-000000000000") P // users: %8, %10 + dealloc_stack %2 : $*P // id: %12 destroy_addr %0 : $*P // id: %13 %14 = tuple () // user: %15 return %14 : $() // id: %15 diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil index 5a199b4049279..1a1affa4898e0 100644 --- a/test/IRGen/enum.sil +++ b/test/IRGen/enum.sil @@ -130,7 +130,7 @@ import Swift // -- No-payload enums have extra inhabitants in // their value witness table. -// CHECK: @_TWVO4enum10NoPayloads = constant [25 x i8*] [ +// CHECK: @_TWVO4enum10NoPayloads = constant [26 x i8*] [ // -- ... // -- size // CHECK: i8* inttoptr ([[WORD]] 1 to i8*), @@ -148,7 +148,7 @@ import Swift // -- Single-payload enums take unused extra inhabitants from their payload // as their own. -// CHECK: @_TWVO4enum19SinglePayloadNested = constant [25 x i8*] [ +// CHECK: @_TWVO4enum19SinglePayloadNested = constant [26 x i8*] [ // -- ... // -- size // CHECK: i8* inttoptr ([[WORD]] 1 to i8*), @@ -171,7 +171,7 @@ import Swift // CHECK: i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @_TwxsO4enum20DynamicSinglePayload to i8*) // CHECK: i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @_TwxgO4enum20DynamicSinglePayload to i8*) -// CHECK: @_TWVO4enum18MultiPayloadNested = constant [25 x i8*] [ +// CHECK: @_TWVO4enum18MultiPayloadNested = constant [26 x i8*] [ // CHECK: i8* inttoptr ([[WORD]] 9 to i8*), // CHECK: i8* inttoptr ([[WORD]] 16 to i8*) // CHECK: ] @@ -2441,8 +2441,10 @@ struct ContainsUnownedObjC { unowned let x: C } // CHECK-LABEL: define {{.*}} @optional_unowned() {{.*}} { -// CHECK-64: ret { [[WORD]], [[WORD]] } { [[WORD]] 0, [[WORD]] 2 } -// CHECK-32: ret { [[WORD]], [[WORD]] } { [[WORD]] 0, [[WORD]] 1 } +// CHECK-objc-64: ret { [[WORD]], [[WORD]], i1 } { [[WORD]] 0, [[WORD]] 0, i1 true } +// CHECK-native-64: ret { [[WORD]], [[WORD]] } { [[WORD]] 0, [[WORD]] 2 } +// CHECK-objc-32: ret { [[WORD]], [[WORD]], i1 } { [[WORD]] 0, [[WORD]] 0, i1 true } +// CHECK-native-32: ret { [[WORD]], [[WORD]] } { [[WORD]] 0, [[WORD]] 1 } sil @optional_unowned : $@convention(thin) () -> (Optionable, Optionable>) { entry: %a = enum $Optionable, #Optionable.None!enumelt @@ -2451,8 +2453,10 @@ entry: return %t : $(Optionable, Optionable>) } // CHECK-LABEL: define {{.*}} @optional_unowned_objc() {{.*}} { -// CHECK-64: ret { [[WORD]], [[WORD]] } { [[WORD]] 0, [[WORD]] 2 } -// CHECK-32: ret { [[WORD]], [[WORD]] } { [[WORD]] 0, [[WORD]] 1 } +// CHECK-objc-64: ret { [[WORD]], [[WORD]], i1 } { [[WORD]] 0, [[WORD]] 0, i1 true } +// CHECK-native-64: ret { [[WORD]], [[WORD]] } { [[WORD]] 0, [[WORD]] 2 } +// CHECK-objc-32: ret { [[WORD]], [[WORD]], i1 } { [[WORD]] 0, [[WORD]] 0, i1 true } +// CHECK-native-32: ret { [[WORD]], [[WORD]] } { [[WORD]] 0, [[WORD]] 1 } sil @optional_unowned_objc : $@convention(thin) () -> (Optionable, Optionable>) { entry: %a = enum $Optionable, #Optionable.None!enumelt @@ -2535,7 +2539,7 @@ enum Target { // Ensure that we generate IR that does not run into verification // issues for the case where there is a single tag bit and extra -// enhabitants. +// inhabitants. // CHECK-LABEL: define void @generate_conditional_branch sil @generate_conditional_branch : $@convention(thin) (@owned Target) -> () { bb0(%0 : $Target): diff --git a/test/IRGen/enum_dynamic_multi_payload.sil b/test/IRGen/enum_dynamic_multi_payload.sil index 8a8ce3ec03037..fb4ae50758e01 100644 --- a/test/IRGen/enum_dynamic_multi_payload.sil +++ b/test/IRGen/enum_dynamic_multi_payload.sil @@ -42,27 +42,29 @@ entry(%e : $Either<(), ()>): fix_lifetime %e : $Either<(), ()> // CHECK-NEXT: alloca + // CHECK-NEXT: bitcast + // CHECK-NEXT: llvm.lifetime.start %s = alloc_stack $Either<(), ()> %l = enum $Either<(), ()>, #Either.Left!enumelt.1, undef : $() - // CHECK-NEXT: bitcast + // CHECK-NEXT: bitcast {{.*}} to i1* // CHECK-NEXT: store i1 false - store %l to %s#1 : $*Either<(), ()> + store %l to %s : $*Either<(), ()> %r = enum $Either<(), ()>, #Either.Right!enumelt.1, undef : $() - // CHECK-NEXT: bitcast + // CHECK-NEXT: bitcast {{.*}} to i1* // CHECK-NEXT: store i1 true - store %r to %s#1 : $*Either<(), ()> + store %r to %s : $*Either<(), ()> %a = unchecked_enum_data %l : $Either<(), ()>, #Either.Left!enumelt.1 %b = unchecked_enum_data %r : $Either<(), ()>, #Either.Right!enumelt.1 // CHECK-NEXT: switch - // CHECK-NEXT: i1 false, label %5 - // CHECK-NEXT: i1 true, label %6 - // CHECK: { +} \ No newline at end of file diff --git a/test/IRGen/generic_structs.swift b/test/IRGen/generic_structs.swift new file mode 100644 index 0000000000000..cebba8148c062 --- /dev/null +++ b/test/IRGen/generic_structs.swift @@ -0,0 +1,27 @@ +// RUN: %target-swift-frontend -primary-file %s -emit-ir + +struct A +{ + var b: T1 + var c: T2 + var d: B +} +struct B +{ + var c: T1 + var d: T2 +} + +struct C +{} +struct D +{} + +struct Foo +{ + var a: A1 + var b: Bar +} + +struct Bar { +} diff --git a/test/IRGen/generic_tuples.swift b/test/IRGen/generic_tuples.swift index 2cdb26773292a..df8839b97b8a1 100644 --- a/test/IRGen/generic_tuples.swift +++ b/test/IRGen/generic_tuples.swift @@ -20,6 +20,8 @@ func dup(x: T) -> (T, T) { // CHECK-NEXT: alloca %swift.type*, align 8 // CHECK-NEXT: [[XBUF:%.*]] = alloca [[BUFFER:.*]], align 8 // CHECK-NEXT: store %swift.type* +// CHECK-NEXT: [[XBUFLIFE:%.*]] = bitcast {{.*}} [[XBUF]] +// CHECK-NEXT: call void @llvm.lifetime.start({{.*}} [[XBUFLIFE]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[TYPE]]* %T to i8*** // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1 // CHECK-NEXT: [[T_VALUE:%.*]] = load i8**, i8*** [[T1]], align 8 diff --git a/test/IRGen/generic_types.swift b/test/IRGen/generic_types.swift index 591c02196e84d..04fa2f4e3ffc4 100644 --- a/test/IRGen/generic_types.swift +++ b/test/IRGen/generic_types.swift @@ -1,7 +1,6 @@ -// RUN: %target-swift-frontend %s -emit-ir | FileCheck %s +// RUN: %target-swift-frontend %s -emit-ir | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime // REQUIRES: CPU=x86_64 -// XFAIL: linux import Swift @@ -11,17 +10,19 @@ import Swift // CHECK: [[C:%C13generic_types1C]] = type // CHECK: [[D:%C13generic_types1D]] = type -// CHECK: @_TMPC13generic_types1A = global [[A_METADATA_T:{.*\* } }]] { +// CHECK: @_TMPC13generic_types1A = global // CHECK: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_A, -// CHECK: i32 344, +// CHECK-native: i32 160, +// CHECK-objc: i32 344, // CHECK: i16 1, // CHECK: i16 16, // CHECK: [{{[0-9]+}} x i8*] zeroinitializer, // CHECK: void ([[A]]*)* @_TFC13generic_types1AD, // CHECK: i8** @_TWVBo, // CHECK: i64 0, -// CHECK: %objc_class* @"OBJC_CLASS_$_SwiftObject", -// CHECK: %swift.opaque* @_objc_empty_cache, +// CHECK: %swift.type* null, +// CHECK-native: %swift.opaque* null, +// CHECK-objc: %swift.opaque* @_objc_empty_cache, // CHECK: %swift.opaque* null, // CHECK: i64 1, // CHECK: i32 3, @@ -35,17 +36,19 @@ import Swift // CHECK: void (%swift.opaque*, [[A]]*)* @_TFC13generic_types1A3run // CHECK: %C13generic_types1A* (i64, %C13generic_types1A*)* @_TFC13generic_types1AcfT1ySi_GS0_x_ // CHECK: } -// CHECK: @_TMPC13generic_types1B = global [[B_METADATA_T:{.* } }]] { +// CHECK: @_TMPC13generic_types1B = global // CHECK: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_B, -// CHECK: i32 336, +// CHECK-native: i32 152, +// CHECK-objc: i32 336, // CHECK: i16 1, // CHECK: i16 16, // CHECK: [{{[0-9]+}} x i8*] zeroinitializer, // CHECK: void ([[B]]*)* @_TFC13generic_types1BD, // CHECK: i8** @_TWVBo, // CHECK: i64 0, -// CHECK: %objc_class* @"OBJC_CLASS_$_SwiftObject", -// CHECK: %swift.opaque* @_objc_empty_cache, +// CHECK: %swift.type* null, +// CHECK-native: %swift.opaque* null, +// CHECK-objc: %swift.opaque* @_objc_empty_cache, // CHECK: %swift.opaque* null, // CHECK: i64 1, // CHECK: i32 3, @@ -57,22 +60,24 @@ import Swift // CHECK: i32 16, // CHECK: %swift.type* null // CHECK: } -// CHECK: @_TMPC13generic_types1C = global [[C_METADATA_T:{.*\* } }]] { +// CHECK: @_TMPC13generic_types1C = global // CHECK: void ([[C]]*)* @_TFC13generic_types1CD, // CHECK: i8** @_TWVBo, // CHECK: i64 0, // CHECK: %swift.type* null, -// CHECK: %swift.opaque* @_objc_empty_cache, +// CHECK-native: %swift.opaque* null, +// CHECK-objc: %swift.opaque* @_objc_empty_cache, // CHECK: %swift.opaque* null, // CHECK: i64 1, // CHECK: void (%swift.opaque*, [[A]]*)* @_TFC13generic_types1A3run // CHECK: } -// CHECK: @_TMPC13generic_types1D = global [[D_METADATA_T:{.*\* } }]] { +// CHECK: @_TMPC13generic_types1D = global // CHECK: void ([[D]]*)* @_TFC13generic_types1DD, // CHECK: i8** @_TWVBo, // CHECK: i64 0, // CHECK: %swift.type* null, -// CHECK: %swift.opaque* @_objc_empty_cache, +// CHECK-native: %swift.opaque* null, +// CHECK-objc: %swift.opaque* @_objc_empty_cache, // CHECK: %swift.opaque* null, // CHECK: i64 1, // CHECK: void (%Si*, [[D]]*)* @_TTVFC13generic_types1D3runfSiT_ @@ -82,8 +87,9 @@ import Swift // CHECK: entry: // CHECK: [[T0:%.*]] = load i8*, i8** %1 // CHECK: %T = bitcast i8* [[T0]] to %swift.type* -// CHECK: [[SUPER:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* @"OBJC_CLASS_$_SwiftObject") -// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]]) +// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* null) +// CHECK-objc: [[SUPER:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* @"OBJC_CLASS_$_SwiftObject") +// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]]) // CHECK: [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8** // CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8* // CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 10 @@ -95,8 +101,9 @@ import Swift // CHECK: entry: // CHECK: [[T0:%.*]] = load i8*, i8** %1 // CHECK: %T = bitcast i8* [[T0]] to %swift.type* -// CHECK: [[SUPER:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* @"OBJC_CLASS_$_SwiftObject") -// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]]) +// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* null) +// CHECK-objc: [[SUPER:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* @"OBJC_CLASS_$_SwiftObject") +// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[SUPER]]) // CHECK: [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8** // CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8* // CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i32 10 diff --git a/test/IRGen/ivar_destroyer.sil b/test/IRGen/ivar_destroyer.sil index 15ef0d4271d30..c86227d69fc5e 100644 --- a/test/IRGen/ivar_destroyer.sil +++ b/test/IRGen/ivar_destroyer.sil @@ -24,7 +24,7 @@ // \ CHECK: i32 16, // \ CHECK: { {{.*}} }* @_TMnC14ivar_destroyer17NonTrivialDerived, // \ CHECK: void (%C14ivar_destroyer17NonTrivialDerived*)* @_TFC14ivar_destroyer17NonTrivialDerivedE, -// \ CHECK: i8* bitcast (void ()* @swift_reportMissingMethod to i8*), +// \ CHECK: i8* bitcast (void ()* @swift_deletedMethodError to i8*), // \ CHECK: %C14ivar_destroyer17NonTrivialDerived* ([[TYPE]]*)* @alloc_NonTrivialDerived, // \ CHECK: i64 16 // \ CHECK: } diff --git a/test/IRGen/lifetime.sil b/test/IRGen/lifetime.sil index c8d907e65d26d..251ba4c2308ab 100644 --- a/test/IRGen/lifetime.sil +++ b/test/IRGen/lifetime.sil @@ -1,48 +1,72 @@ // RUN: %target-swift-frontend -gnone -emit-ir %s | FileCheck %s -// REQUIRES: CPU=x86_64 - // CHECK: [[OPAQUE:%swift.opaque]] = type opaque // CHECK: [[TYPE:%swift.type]] = type sil_stage canonical -sil @generic_tuple : $@convention(thin) (@in T) -> () { +import Builtin + +sil @generic : $@convention(thin) (@in T) -> () { bb0(%x : $*T): %y = alloc_stack $T - copy_addr %x to [initialization] %y#1 : $*T - destroy_addr %y#1 : $*T - dealloc_stack %y#0 : $*@local_storage T + copy_addr %x to [initialization] %y : $*T + destroy_addr %y : $*T + dealloc_stack %y : $*T destroy_addr %x : $*T %0 = tuple () return %0 : $() } -// CHECK: define void @generic_tuple([[OPAQUE]]* noalias nocapture, [[TYPE]]* %T) {{.*}} { +// CHECK: define void @generic([[OPAQUE]]* noalias nocapture, [[TYPE]]* %T) {{.*}} { // Type metadata. // CHECK: alloca // The fixed-size buffer. -// CHECK: [[YBUF:%.*]] = alloca [[BUFFER:.*]], align 8 +// CHECK: [[YBUF:%.*]] = alloca [[BUFFER:.*]], align // CHECK-NEXT: store %swift.type +// CHECK-NEXT: [[YBUFLIFE:%.*]] = bitcast [[BUFFER]]* [[YBUF]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start(i64 [[BUFFER_SIZE:12|24]], i8* [[YBUFLIFE]]) // Allocate it. // CHECK-NEXT: [[T0:%.*]] = bitcast [[TYPE]]* %T to i8*** -// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1 -// CHECK-NEXT: [[VWTABLE:%.*]] = load i8**, i8*** [[T1]], align 8 +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1 +// CHECK-NEXT: [[VWTABLE:%.*]] = load i8**, i8*** [[T1]], align // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWTABLE]], i32 5 -// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align 8 +// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align // CHECK-NEXT: [[BUFFER_COPY_FN:%.*]] = bitcast i8* [[T4]] to [[OPAQUE]]* ([[BUFFER]]*, [[OPAQUE]]*, [[TYPE]]*)* // Copy 'x' into 'y'. // CHECK-NEXT: [[Y:%.*]] = call [[OPAQUE]]* [[BUFFER_COPY_FN]]([[BUFFER]]* [[YBUF]], [[OPAQUE]]* [[X:%.*]], [[TYPE]]* %T) // Destroy 'y'. // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWTABLE]], i32 4 -// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align 8 +// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align // CHECK-NEXT: [[DESTROY_FN:%.*]] = bitcast i8* [[T4]] to void ([[OPAQUE]]*, [[TYPE]]*)* // CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* [[Y]], [[TYPE]]* %T) // Deallocate 'y'. // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8*, i8** [[VWTABLE]], i32 3 -// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align 8 +// CHECK-NEXT: [[T4:%.*]] = load i8*, i8** [[T3]], align // CHECK-NEXT: [[DEALLOC_FN:%.*]] = bitcast i8* [[T4]] to void ([[BUFFER]]*, [[TYPE]]*)* // CHECK-NEXT: call void [[DEALLOC_FN]]([[BUFFER]]* [[YBUF]], [[TYPE]]* %T) +// CHECK-NEXT: [[YBUFLIFE:%.*]] = bitcast [[BUFFER]]* [[YBUF]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end(i64 [[BUFFER_SIZE]], i8* [[YBUFLIFE]]) // Destroy 'x'. // CHECK-NEXT: call void [[DESTROY_FN]]([[OPAQUE]]* [[X]], [[TYPE]]* %T) // Return. // CHECK-NEXT: ret void + +sil @fixed_size : $@convention(thin) (@in Builtin.Int64) -> () { +bb0(%x : $*Builtin.Int64): + %y = alloc_stack $Builtin.Int64 + copy_addr %x to [initialization] %y : $*Builtin.Int64 + destroy_addr %y : $*Builtin.Int64 + dealloc_stack %y : $*Builtin.Int64 + destroy_addr %x : $*Builtin.Int64 + %0 = tuple () + return %0 : $() +} +// CHECK-LABEL: define void @fixed_size(i64* noalias nocapture dereferenceable(8)) +// CHECK: [[XBUF:%.*]] = alloca i64 +// CHECK-NEXT: [[XBUFLIFE:%.*]] = bitcast i64* [[XBUF]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.start(i64 8, i8* [[XBUFLIFE]]) +// CHECK-NEXT: load +// CHECK-NEXT: store +// CHECK-NEXT: [[XBUFLIFE:%.*]] = bitcast i64* [[XBUF]] to i8* +// CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[XBUFLIFE]]) + diff --git a/test/IRGen/mangle-anonclosure.swift b/test/IRGen/mangle-anonclosure.swift index 1df3b75062995..f173a54a39221 100644 --- a/test/IRGen/mangle-anonclosure.swift +++ b/test/IRGen/mangle-anonclosure.swift @@ -4,7 +4,7 @@ import Swift class HeapStorage { public final func withUnsafeMutablePointerToElements( - body: (UnsafeMutablePointer)->R + body: (UnsafeMutablePointer) -> R ) -> R { return body(UnsafeMutablePointer()) } } struct CountAndCapacity {} @@ -14,7 +14,7 @@ class TestHeapStorage : HeapStorage { // Don't crash when mangling this closure's name. // CHECK: _TFFC4main15TestHeapStoragedU_FGSpQ__T_ // ---> main.TestHeapStorage.deinit.(closure #1) - (p: UnsafeMutablePointer)->() in + (p: UnsafeMutablePointer) -> () in } } } diff --git a/test/IRGen/metadata_dominance.swift b/test/IRGen/metadata_dominance.swift new file mode 100644 index 0000000000000..5e0709509f524 --- /dev/null +++ b/test/IRGen/metadata_dominance.swift @@ -0,0 +1,51 @@ +// RUN: %target-swift-frontend -emit-ir -primary-file %s | FileCheck %s + +func use_metadata(f: F) {} + +func voidToVoid() {} +func intToInt(x: Int) -> Int { return x } + +func cond() -> Bool { return true } + +// CHECK: define hidden void @_TF18metadata_dominance5test1FT_T_() +func test1() { +// CHECK: call i1 @_TF18metadata_dominance4condFT_Sb() + if cond() { +// CHECK: [[T0:%.*]] = call %swift.type* @_TMaFT_T_() +// CHECK: call void @_TF18metadata_dominance12use_metadataurFxT_(%swift.opaque* {{.*}}, %swift.type* [[T0]]) + use_metadata(voidToVoid) +// CHECK: call i1 @_TF18metadata_dominance4condFT_Sb() +// CHECK-NOT: @_TMaFT_T_ +// CHECK: call void @_TF18metadata_dominance12use_metadataurFxT_(%swift.opaque* {{.*}}, %swift.type* [[T0]]) + if cond() { + use_metadata(voidToVoid) + } else { +// CHECK-NOT: @_TMaFT_T_ +// CHECK: call void @_TF18metadata_dominance12use_metadataurFxT_(%swift.opaque* {{.*}}, %swift.type* [[T0]]) + use_metadata(voidToVoid) + } + } +// CHECK: [[T1:%.*]] = call %swift.type* @_TMaFT_T_() +// CHECK: call void @_TF18metadata_dominance12use_metadataurFxT_(%swift.opaque* {{.*}}, %swift.type* [[T1]]) + use_metadata(voidToVoid) +} + +// CHECK: define hidden void @_TF18metadata_dominance5test2FT_T_() +func test2() { +// CHECK: call i1 @_TF18metadata_dominance4condFT_Sb() + if cond() { +// CHECK: call i1 @_TF18metadata_dominance4condFT_Sb() +// CHECK: [[T0:%.*]] = call %swift.type* @_TMaFT_T_() +// CHECK: call void @_TF18metadata_dominance12use_metadataurFxT_(%swift.opaque* {{.*}}, %swift.type* [[T0]]) + if cond() { + use_metadata(voidToVoid) + } else { +// CHECK: [[T1:%.*]] = call %swift.type* @_TMaFT_T_() +// CHECK: call void @_TF18metadata_dominance12use_metadataurFxT_(%swift.opaque* {{.*}}, %swift.type* [[T1]]) + use_metadata(voidToVoid) + } + } +// CHECK: [[T2:%.*]] = call %swift.type* @_TMaFT_T_() +// CHECK: call void @_TF18metadata_dominance12use_metadataurFxT_(%swift.opaque* {{.*}}, %swift.type* [[T2]]) + use_metadata(voidToVoid) +} diff --git a/test/IRGen/objc_attr_NSManaged.sil b/test/IRGen/objc_attr_NSManaged.sil index 813e28fe7fc93..1cc3dca84fc7f 100644 --- a/test/IRGen/objc_attr_NSManaged.sil +++ b/test/IRGen/objc_attr_NSManaged.sil @@ -27,7 +27,7 @@ sil_vtable X {} // The getter/setter should not show up in the Swift metadata. /* FIXME: sil_vtable parser picks the wrong 'init' overload. Both vtable entries ought to be nonnull here. rdar://problem/19572342 */ -// CHECK: @_TMfC19objc_attr_NSManaged10SwiftGizmo = internal global { {{.*}} } { void (%C19objc_attr_NSManaged10SwiftGizmo*)* @_TFC19objc_attr_NSManaged10SwiftGizmoD, i8** @_TWVBO, i64 ptrtoint (%objc_class* @"OBJC_METACLASS_$__TtC19objc_attr_NSManaged10SwiftGizmo" to i64), %objc_class* @"OBJC_CLASS_$_Gizmo", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, { i32, i32, [2 x { i8*, i8*, i8* }] }*, i8*, i8*, i8*, { i32, i32, [1 x { i8*, i8* }] }* }* @_DATA__TtC19objc_attr_NSManaged10SwiftGizmo to i64), i64 1), i32 1, i32 0, i32 16, i16 7, i16 0, i32 112, i32 16, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnC19objc_attr_NSManaged10SwiftGizmo, i8* null, %C19objc_attr_NSManaged10SwiftGizmo* (i64, %C19objc_attr_NSManaged10SwiftGizmo*)* @_TFC19objc_attr_NSManaged10SwiftGizmocfT7bellsOnSi_S0_, i8* bitcast (void ()* @swift_reportMissingMethod to i8*) } +// CHECK: @_TMfC19objc_attr_NSManaged10SwiftGizmo = internal global { {{.*}} } { void (%C19objc_attr_NSManaged10SwiftGizmo*)* @_TFC19objc_attr_NSManaged10SwiftGizmoD, i8** @_TWVBO, i64 ptrtoint (%objc_class* @"OBJC_METACLASS_$__TtC19objc_attr_NSManaged10SwiftGizmo" to i64), %objc_class* @"OBJC_CLASS_$_Gizmo", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, { i32, i32, [2 x { i8*, i8*, i8* }] }*, i8*, i8*, i8*, { i32, i32, [1 x { i8*, i8* }] }* }* @_DATA__TtC19objc_attr_NSManaged10SwiftGizmo to i64), i64 1), i32 1, i32 0, i32 16, i16 7, i16 0, i32 112, i32 16, { i64, i8*, i32, i32, i8*, %swift.type** (%swift.type*)*, %swift.type_pattern*, i32, i32, i32 }* @_TMnC19objc_attr_NSManaged10SwiftGizmo, i8* null, %C19objc_attr_NSManaged10SwiftGizmo* (i64, %C19objc_attr_NSManaged10SwiftGizmo*)* @_TFC19objc_attr_NSManaged10SwiftGizmocfT7bellsOnSi_S0_, i8* bitcast (void ()* @swift_deletedMethodError to i8*) } @objc class SwiftGizmo : Gizmo { @objc @NSManaged var x: X diff --git a/test/IRGen/objc_block_storage.sil b/test/IRGen/objc_block_storage.sil index 6430d6f469a3a..085d86320df2b 100644 --- a/test/IRGen/objc_block_storage.sil +++ b/test/IRGen/objc_block_storage.sil @@ -42,7 +42,7 @@ import gizmo // CHECK-NEXT: %2 = load i8*, i8** %1, align 8 // CHECK-NEXT: ret i8* %2 // CHECK-NEXT: } -sil @project_block_storage : $@convention(thin) (@inout @block_storage Builtin.RawPointer) -> Builtin.RawPointer { +sil @project_block_storage : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> Builtin.RawPointer { entry(%0 : $*@block_storage Builtin.RawPointer): %c = project_block_storage %0 : $*@block_storage Builtin.RawPointer %p = load %c : $*Builtin.RawPointer @@ -55,7 +55,7 @@ entry(%0 : $*@block_storage Builtin.RawPointer): // CHECK-NEXT: %2 = load fp128, fp128* %1, align 16 // CHECK-NEXT: ret fp128 %2 // CHECK-NEXT: } -sil @overaligned_project_block_storage : $@convention(thin) (@inout @block_storage Builtin.FPIEEE128) -> Builtin.FPIEEE128 { +sil @overaligned_project_block_storage : $@convention(thin) (@inout_aliasable @block_storage Builtin.FPIEEE128) -> Builtin.FPIEEE128 { entry(%0 : $*@block_storage Builtin.FPIEEE128): %c = project_block_storage %0 : $*@block_storage Builtin.FPIEEE128 %p = load %c : $*Builtin.FPIEEE128 @@ -74,34 +74,34 @@ entry(%0 : $*@block_storage Builtin.FPIEEE128): // CHECK: }, %objc_block* %1 // CHECK: %2 = bitcast {{.*}} %0 to %objc_block* // CHECK: ret %objc_block* %2 -sil @init_block_header_trivial : $@convention(thin) (@inout @block_storage Builtin.RawPointer) -> @convention(block) () -> () { +sil @init_block_header_trivial : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> @convention(block) () -> () { entry(%0 : $*@block_storage Builtin.RawPointer): - %i = function_ref @invoke_trivial : $@convention(c) (@inout @block_storage Builtin.RawPointer) -> () - %b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout @block_storage Builtin.RawPointer) -> (), type $@convention(block) () -> () + %i = function_ref @invoke_trivial : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> () + %b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> (), type $@convention(block) () -> () return %b : $@convention(block) () -> () } // CHECK-LABEL: define void @invoke_trivial(void (...)*) {{.*}} { // CHECK: %1 = bitcast void (...)* %0 to { %objc_block, i8* }* // CHECK: %2 = getelementptr inbounds { %objc_block, i8* }, { %objc_block, i8* }* %1, i32 0, i32 1 -sil @invoke_trivial : $@convention(c) (@inout @block_storage Builtin.RawPointer) -> () { +sil @invoke_trivial : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> () { entry(%0 : $*@block_storage Builtin.RawPointer): %c = project_block_storage %0 : $*@block_storage Builtin.RawPointer return undef : $() } -sil @init_block_header_trivial_block_param : $@convention(thin) (@inout @block_storage Builtin.RawPointer) -> @convention(block) (@convention(block) (Int) -> Int) -> () { +sil @init_block_header_trivial_block_param : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> @convention(block) (@convention(block) (Int) -> Int) -> () { entry(%0 : $*@block_storage Builtin.RawPointer): - %i = function_ref @invoke_trivial_block_param : $@convention(c) (@inout @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> () - %b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> (), type $@convention(block) (@convention(block) (Int) -> Int) -> () + %i = function_ref @invoke_trivial_block_param : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> () + %b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> (), type $@convention(block) (@convention(block) (Int) -> Int) -> () return %b : $@convention(block) (@convention(block) (Int) -> Int) -> () } -sil @invoke_trivial_block_param : $@convention(c) (@inout @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> () +sil @invoke_trivial_block_param : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> () // CHECK-LABEL: define i64 @invoke_trivial_with_arg(void (...)*, i64) {{.*}} { // CHECK: ret i64 %1 -sil @invoke_trivial_with_arg : $@convention(c) (@inout @block_storage Builtin.RawPointer, Int) -> Int { +sil @invoke_trivial_with_arg : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer, Int) -> Int { entry(%0 : $*@block_storage Builtin.RawPointer, %1 : $Int): return %1 : $Int } @@ -115,10 +115,10 @@ entry(%0 : $*@block_storage Builtin.RawPointer, %1 : $Int): // CHECK: i8* {{.*}} @invoke_nontrivial // CHECK: i8* bitcast {{.*}} [[NONTRIVIAL_BLOCK_DESCRIPTOR]] // CHECK: }, %objc_block* %1 -sil @init_block_header_nontrivial : $@convention(thin) (@inout @block_storage Builtin.NativeObject) -> @convention(block) () -> () { +sil @init_block_header_nontrivial : $@convention(thin) (@inout_aliasable @block_storage Builtin.NativeObject) -> @convention(block) () -> () { entry(%0 : $*@block_storage Builtin.NativeObject): - %i = function_ref @invoke_nontrivial : $@convention(c) (@inout @block_storage Builtin.NativeObject) -> () - %b = init_block_storage_header %0 : $*@block_storage Builtin.NativeObject, invoke %i : $@convention(c) (@inout @block_storage Builtin.NativeObject) -> (), type $@convention(block) () -> () + %i = function_ref @invoke_nontrivial : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> () + %b = init_block_storage_header %0 : $*@block_storage Builtin.NativeObject, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> (), type $@convention(block) () -> () return %b : $@convention(block) () -> () } @@ -138,7 +138,7 @@ entry(%0 : $*@block_storage Builtin.NativeObject): // CHECK-NEXT: call void @swift_release(%swift.refcounted* %toDestroy) {{#[0-9]+}} // CHECK-NEXT: ret void -sil public_external @invoke_nontrivial : $@convention(c) (@inout @block_storage Builtin.NativeObject) -> () +sil public_external @invoke_nontrivial : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> () // CHECK-LABEL: define %objc_block* @init_block_header_stret({ %objc_block, i8* }* nocapture dereferenceable({{.*}})) {{.*}} { // CHECK: store %objc_block { @@ -149,11 +149,11 @@ sil public_external @invoke_nontrivial : $@convention(c) (@inout @block_storage // CHECK: i8* {{.*}} @invoke_stret // CHECK: i8* bitcast {{.*}} [[STRET_BLOCK_DESCRIPTOR]] // CHECK: }, %objc_block* %1 -sil @init_block_header_stret : $@convention(thin) (@inout @block_storage Builtin.RawPointer) -> @convention(block) () -> NSRect { +sil @init_block_header_stret : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> @convention(block) () -> NSRect { entry(%0 : $*@block_storage Builtin.RawPointer): - %i = function_ref @invoke_stret : $@convention(c) (@inout @block_storage Builtin.RawPointer) -> NSRect - %b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout @block_storage Builtin.RawPointer) -> NSRect, type $@convention(block) () -> NSRect + %i = function_ref @invoke_stret : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> NSRect + %b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> NSRect, type $@convention(block) () -> NSRect return %b : $@convention(block) () -> NSRect } -sil public_external @invoke_stret : $@convention(c) (@inout @block_storage Builtin.RawPointer) -> NSRect +sil public_external @invoke_stret : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> NSRect diff --git a/test/IRGen/objc_class_export.swift b/test/IRGen/objc_class_export.swift index 35f89b2049a39..4c8423e197760 100644 --- a/test/IRGen/objc_class_export.swift +++ b/test/IRGen/objc_class_export.swift @@ -96,7 +96,7 @@ struct BigStructWithNativeObjects { // CHECK: call void @_TFC17objc_class_export3Foo6boundsfT_VSC6NSRect([[NSRECT]]* noalias nocapture sret {{.*}}, [[FOO]]* [[CAST]]) func convertRectToBacking(r r: NSRect) -> NSRect { - return r; + return r } // CHECK: define internal void @_TToFC17objc_class_export3Foo20convertRectToBackingfT1rVSC6NSRect_S1_([[NSRECT]]* noalias nocapture sret, [[OPAQUE5:%.*]]*, i8*, [[NSRECT]]* byval align 8) unnamed_addr {{.*}} { // CHECK: [[CAST:%[a-zA-Z0-9]+]] = bitcast [[OPAQUE5]]* %1 to [[FOO]]* diff --git a/test/IRGen/objc_dealloc.sil b/test/IRGen/objc_dealloc.sil index 0a3c54fa7635f..971c183fd2fbe 100644 --- a/test/IRGen/objc_dealloc.sil +++ b/test/IRGen/objc_dealloc.sil @@ -51,7 +51,7 @@ bb0(%0 : $SwiftGizmo): %1 = ref_element_addr %0 : $SwiftGizmo, #SwiftGizmo.x // user: %2 %2 = load %1 : $*X // users: %4, %3 strong_retain %2 : $X // id: %3 - autorelease_return %2 : $X // id: %4 + return %2 : $X // id: %4 } sil @_TToFC12objc_dealloc10SwiftGizmos1xC12objc_dealloc1X : $@convention(objc_method) (X, SwiftGizmo) -> () { diff --git a/test/IRGen/objc_subclass.swift b/test/IRGen/objc_subclass.swift index ae6b8e35fd16c..2f7a5f27cb622 100644 --- a/test/IRGen/objc_subclass.swift +++ b/test/IRGen/objc_subclass.swift @@ -280,7 +280,7 @@ class SwiftGizmo : Gizmo { var x = Int() func getX() -> Int { - return x; + return x } override func duplicate() -> Gizmo { diff --git a/test/IRGen/objc_type_encoding.swift b/test/IRGen/objc_type_encoding.swift index 95fc039e92aee..03309db2c3b30 100644 --- a/test/IRGen/objc_type_encoding.swift +++ b/test/IRGen/objc_type_encoding.swift @@ -112,7 +112,7 @@ func testArchetype(work: P3) { // CHECK-tvos: private unnamed_addr constant [11 x i8] c"v24@0:8@16\00" @objc func foo(x: Int -> Int) -> Int { - return 1; + return 1 } // CHECK-macosx: private unnamed_addr constant [12 x i8] c"q24@0:8@?16\00" // CHECK-ios: private unnamed_addr constant [12 x i8] c"q24@0:8@?16\00" diff --git a/test/IRGen/partial_apply.sil b/test/IRGen/partial_apply.sil index 887ae9bdd3d93..d6778d4e47917 100644 --- a/test/IRGen/partial_apply.sil +++ b/test/IRGen/partial_apply.sil @@ -198,10 +198,10 @@ sil public_external @generic_captured_param : $@convention(thin) (Int, @inou sil @partial_apply_generic_capture : $@convention(thin) Int -> @callee_owned Int -> Int { entry(%x : $Int): %a = alloc_stack $Int - store %x to %a#1 : $*Int + store %x to %a : $*Int %f = function_ref @generic_captured_param : $@convention(thin) (Int, @inout T) -> Int - %p = partial_apply %f(%a#1) : $@convention(thin) (Int, @inout T) -> Int - dealloc_stack %a#0 : $*@local_storage Int + %p = partial_apply %f(%a) : $@convention(thin) (Int, @inout T) -> Int + dealloc_stack %a : $*Int return %p : $@callee_owned Int -> Int } diff --git a/test/IRGen/protocol_extensions.sil b/test/IRGen/protocol_extensions.sil index b7b06ca5d376e..f1b829ca1a1d3 100644 --- a/test/IRGen/protocol_extensions.sil +++ b/test/IRGen/protocol_extensions.sil @@ -16,7 +16,7 @@ extension P1 { // CHECK-LABEL: define hidden void @_TFP19protocol_extensions2P16extP1aUS0___fQPS0_FT_T_ sil hidden @_TFP19protocol_extensions2P16extP1aUS0___fQPS0_FT_T_ : $@convention(method) (@in Self) -> () { bb0(%0 : $*Self): - debug_value_addr %0 : $*Self // let self // id: %1 + debug_value_addr %0 : $*Self, let, name "self" // id: %1 %2 = witness_method $Self, #P1.reqP1a!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> () // user: %3 %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> () destroy_addr %0 : $*Self // id: %4 @@ -27,14 +27,14 @@ bb0(%0 : $*Self): // CHECK-LABEL: define void @_TFP19protocol_extensions2P16extP1bUS0___fQPS0_FT_T_ sil @_TFP19protocol_extensions2P16extP1bUS0___fQPS0_FT_T_ : $@convention(method) (@in Self) -> () { bb0(%0 : $*Self): - debug_value_addr %0 : $*Self // let self // id: %1 + debug_value_addr %0 : $*Self, let, name "self" // id: %1 // function_ref protocol_extensions.P1.extP1a (protocol_extensions.P1.Self)() -> () %2 = function_ref @_TFP19protocol_extensions2P16extP1aUS0___fQPS0_FT_T_ : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in τ_0_0) -> () // user: %5 %3 = alloc_stack $Self // users: %4, %5, %6 - copy_addr %0 to [initialization] %3#1 : $*Self // id: %4 + copy_addr %0 to [initialization] %3 : $*Self // id: %4 // CHECK: call void @_TFP19protocol_extensions2P16extP1aUS0___fQPS0_FT_T_ - %5 = apply %2(%3#1) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in τ_0_0) -> () - dealloc_stack %3#0 : $*@local_storage Self // id: %6 + %5 = apply %2(%3) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in τ_0_0) -> () + dealloc_stack %3 : $*Self // id: %6 destroy_addr %0 : $*Self // id: %7 %8 = tuple () // user: %9 return %8 : $() // id: %9 diff --git a/test/IRGen/report_dead_method_call.swift b/test/IRGen/report_dead_method_call.swift index ef094bb7ad555..abce2943de59e 100644 --- a/test/IRGen/report_dead_method_call.swift +++ b/test/IRGen/report_dead_method_call.swift @@ -9,7 +9,7 @@ // The -disable-access-control option let us "call" methods, which are removed // by dead method elimination. -// CHECK: fatal error: call of removed method +// CHECK: fatal error: call of deleted method private protocol PrivateProto { func abc() diff --git a/test/IRGen/select_enum_single_payload.sil b/test/IRGen/select_enum_single_payload.sil new file mode 100644 index 0000000000000..6cb86c659ee36 --- /dev/null +++ b/test/IRGen/select_enum_single_payload.sil @@ -0,0 +1,34 @@ +// RUN: %target-swift-frontend %s -emit-ir | FileCheck %s +sil_stage canonical + +import Builtin + +enum ManyEmptyCases { + case A + case B + case C(Builtin.Int32) +} + +// CHECK-LABEL: define i1 @select_enum_A(i32, i1) +// CHECK: [[PAYLOAD:%.*]] = icmp eq i32 %0, 0 +// CHECK: [[EXTRA:%.*]] = and i1 %1, [[PAYLOAD]] +// CHECK: ret i1 [[EXTRA]] +sil @select_enum_A : $@convention(thin) (ManyEmptyCases) -> Builtin.Int1 { +entry(%0 : $ManyEmptyCases): + %4 = integer_literal $Builtin.Int1, -1 // user: %6 + %5 = integer_literal $Builtin.Int1, 0 // user: %6 + %6 = select_enum %0 : $ManyEmptyCases, case #ManyEmptyCases.A!enumelt: %4, default %5 : $Builtin.Int1 + return %6 : $Builtin.Int1 +} + +// CHECK-LABEL: define i1 @select_enum_B(i32, i1) +// CHECK: [[PAYLOAD:%.*]] = icmp eq i32 %0, 1 +// CHECK: [[EXTRA:%.*]] = and i1 %1, [[PAYLOAD]] +// CHECK: ret i1 [[EXTRA]] +sil @select_enum_B : $@convention(thin) (ManyEmptyCases) -> Builtin.Int1 { +entry(%0 : $ManyEmptyCases): + %4 = integer_literal $Builtin.Int1, -1 // user: %6 + %5 = integer_literal $Builtin.Int1, 0 // user: %6 + %6 = select_enum %0 : $ManyEmptyCases, case #ManyEmptyCases.B!enumelt: %4, default %5 : $Builtin.Int1 + return %6 : $Builtin.Int1 +} diff --git a/test/IRGen/sil_witness_methods.sil b/test/IRGen/sil_witness_methods.sil index f405637ecb2fe..1560faddf2d0a 100644 --- a/test/IRGen/sil_witness_methods.sil +++ b/test/IRGen/sil_witness_methods.sil @@ -118,10 +118,10 @@ entry(%z : $*Z, %x : $@thick Bar.Type): sil @call_concrete_witness : $(Foo) -> () { entry(%x : $Foo): %m = alloc_stack $Foo - store %x to %m#1 : $*Foo + store %x to %m : $*Foo %w = function_ref @concrete_type_concrete_method_witness : $@convention(witness_method) (@in Foo) -> @thick Foo.Type - %z = apply %w(%m#1) : $@convention(witness_method) (@in Foo) -> @thick Foo.Type - dealloc_stack %m#0 : $*@local_storage Foo + %z = apply %w(%m) : $@convention(witness_method) (@in Foo) -> @thick Foo.Type + dealloc_stack %m : $*Foo return undef : $() } diff --git a/test/IRGen/sil_witness_tables.swift b/test/IRGen/sil_witness_tables.swift index d5dddb8fd595e..50225ce396f52 100644 --- a/test/IRGen/sil_witness_tables.swift +++ b/test/IRGen/sil_witness_tables.swift @@ -42,9 +42,8 @@ struct Conformer: Q, QQ { // CHECK: i8* bitcast (void (%V18sil_witness_tables9Conformer*, %swift.type*)* @_TTWV18sil_witness_tables9ConformerS_1QS_FS1_7qMethod{{.*}} to i8*) // CHECK: ] // CHECK: [[CONFORMER_P_WITNESS_TABLE]] = hidden constant [4 x i8*] [ -// -- FIXME: associated type and witness table -// CHECK: i8* null, -// CHECK: i8* null, +// CHECK: i8* bitcast (%swift.type* ()* @_TMaV18sil_witness_tables14AssocConformer to i8*), +// CHECK: i8* bitcast (i8** ()* @_TWaV18sil_witness_tables14AssocConformerS_1AS_ to i8*) // CHECK: i8* bitcast (void (%swift.type*, %swift.type*)* @_TTWV18sil_witness_tables9ConformerS_1PS_ZFS1_12staticMethod{{.*}} to i8*), // CHECK: i8* bitcast (void (%V18sil_witness_tables9Conformer*, %swift.type*)* @_TTWV18sil_witness_tables9ConformerS_1PS_FS1_14instanceMethod{{.*}} to i8*) // CHECK: ] @@ -71,3 +70,11 @@ func erasure(c c: Conformer) -> QQ { func externalErasure(c c: ExternalConformer) -> ExternalP { return c } + +// FIXME: why do these have different linkages? + +// CHECK-LABEL: define %swift.type* @_TMaV18sil_witness_tables14AssocConformer() +// CHECK: ret %swift.type* bitcast (i64* getelementptr inbounds {{.*}} @_TMfV18sil_witness_tables14AssocConformer, i32 0, i32 1) to %swift.type*) + +// CHECK-LABEL: define hidden i8** @_TWaV18sil_witness_tables9ConformerS_1PS_() +// CHECK: ret i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_TWPV18sil_witness_tables9ConformerS_1PS_, i32 0, i32 0) diff --git a/test/IRGen/sil_witness_tables_inherited_conformance.swift b/test/IRGen/sil_witness_tables_inherited_conformance.swift index 94f2e6484816b..daf07af320acc 100644 --- a/test/IRGen/sil_witness_tables_inherited_conformance.swift +++ b/test/IRGen/sil_witness_tables_inherited_conformance.swift @@ -11,7 +11,7 @@ class Cat : Panda { required init() { } func getCutenessLevel() -> Int { - return 3; + return 3 } } @@ -19,7 +19,7 @@ class Veterinarian { func disentangle(t: T) { } } -class Anasthesiologist : Veterinarian { } +class Anesthesiologist : Veterinarian { } func breed(t: T) { } @@ -41,4 +41,4 @@ func wangle(t: T.Type) { feed(Cat()) wangle(Cat) -Anasthesiologist().disentangle(Cat()) +Anesthesiologist().disentangle(Cat()) diff --git a/test/IRGen/struct_resilience.swift b/test/IRGen/struct_resilience.swift index 41eed00dbbbfe..10dcd71092c2b 100644 --- a/test/IRGen/struct_resilience.swift +++ b/test/IRGen/struct_resilience.swift @@ -85,6 +85,8 @@ public struct MySize { public func functionWithMyResilientTypes(s: MySize, f: MySize -> MySize) -> MySize { // CHECK: [[TEMP:%.*]] = alloca %V17struct_resilience6MySize +// CHECK: bitcast +// CHECK: llvm.lifetime.start // CHECK: [[COPY:%.*]] = bitcast %V17struct_resilience6MySize* %4 to i8* // CHECK: [[ARG:%.*]] = bitcast %V17struct_resilience6MySize* %1 to i8* // CHECK: call void @llvm.memcpy{{.*}}(i8* [[COPY]], i8* [[ARG]], {{i32 8|i64 16}}, i32 {{.*}}, i1 false) diff --git a/test/IRGen/super.sil b/test/IRGen/super.sil new file mode 100644 index 0000000000000..a37ebe494894c --- /dev/null +++ b/test/IRGen/super.sil @@ -0,0 +1,183 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: %target-swift-frontend -emit-module -enable-resilience -module-name resilient_class -o %t %S/../Inputs/resilient_class.swift +// RUN: %target-swift-frontend -use-native-super-method -enable-resilience -parse-sil -parse-as-library -emit-ir -I %t %s | FileCheck %s + +sil_stage canonical + +import Builtin +import Swift +import SwiftShims +import resilient_class + +public class ChildToResilientParent : ResilientOutsideParent { + public override func method() + public override class func classMethod() + deinit + override init() +} + +public class ChildToFixedParent : OutsideParent { + public override func method() + public override class func classMethod() + deinit + override init() +} + +public extension ResilientOutsideChild { + public func callSuperMethod() + public class func callSuperClassMethod() +} + +// resilient_class.ResilientOutsideParent.method () -> () +sil @_TFC15resilient_class22ResilientOutsideParent6methodfT_T_ : $@convention(method) (@guaranteed ResilientOutsideParent) -> () + +// static resilient_class.ResilientOutsideParent.classMethod () -> () +sil @_TZFC15resilient_class22ResilientOutsideParent11classMethodfT_T_ : $@convention(thin) (@thick ResilientOutsideParent.Type) -> () + +// super.ChildToResilientParent.method () -> () +sil @_TFC5super22ChildToResilientParent6methodfT_T_ : $@convention(method) (@guaranteed ChildToResilientParent) -> () { +// %0 +bb0(%0 : $ChildToResilientParent): + debug_value %0 : $ChildToResilientParent, let, name "self", argno 1 + strong_retain %0 : $ChildToResilientParent + %3 = upcast %0 : $ChildToResilientParent to $ResilientOutsideParent + %4 = super_method %0 : $ChildToResilientParent, #ResilientOutsideParent.method!1 : ResilientOutsideParent -> () -> () , $@convention(method) (@guaranteed ResilientOutsideParent) -> () + %5 = apply %4(%3) : $@convention(method) (@guaranteed ResilientOutsideParent) -> () + strong_release %3 : $ResilientOutsideParent + %7 = tuple () + return %7 : $() +} + +// ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly. +// CHECK-LABEL: define void @_TFC5super22ChildToResilientParent6methodfT_T_(%C5super22ChildToResilientParent*) +// CHECK: [[SUPER_METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class22ResilientOutsideParent() +// CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%C15resilient_class22ResilientOutsideParent*)** +// CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%C15resilient_class22ResilientOutsideParent*)*, void (%C15resilient_class22ResilientOutsideParent*)** [[OPAQUE_SUPER_METADATA]] +// CHECK: [[FN_PTR:%[0-9]+]] = load void (%C15resilient_class22ResilientOutsideParent*)*, void (%C15resilient_class22ResilientOutsideParent*)** [[VTABLE_SLOT]] +// CHECK: call void + +// static super.ChildToResilientParent.classMethod () -> () +sil @_TZFC5super22ChildToResilientParent11classMethodfT_T_ : $@convention(thin) (@thick ChildToResilientParent.Type) -> () { +bb0(%0 : $@thick ChildToResilientParent.Type): + debug_value %0 : $@thick ChildToResilientParent.Type, let, name "self", argno 1 + %2 = upcast %0 : $@thick ChildToResilientParent.Type to $@thick ResilientOutsideParent.Type + %3 = super_method %0 : $@thick ChildToResilientParent.Type, #ResilientOutsideParent.classMethod!1 : ResilientOutsideParent.Type -> () -> () , $@convention(thin) (@thick ResilientOutsideParent.Type) -> () + %4 = apply %3(%2) : $@convention(thin) (@thick ResilientOutsideParent.Type) -> () + %5 = tuple () + return %5 : $() +} + +// ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly. +// CHECK-LABEL: define void @_TZFC5super22ChildToResilientParent11classMethodfT_T_(%swift.type*) +// CHECK: [[SUPER_METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class22ResilientOutsideParent() +// CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%swift.type*)** +// CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%swift.type*)*, void (%swift.type*)** [[OPAQUE_SUPER_METADATA]] +// CHECK: [[FN_PTR:%[0-9]+]] = load void (%swift.type*)*, void (%swift.type*)** [[VTABLE_SLOT]] +// CHECK: call void + +// resilient_class.OutsideParent.method () -> () +sil @_TFC15resilient_class13OutsideParent6methodfT_T_ : $@convention(method) (@guaranteed OutsideParent) -> () + +// static resilient_class.OutsideParent.classMethod () -> () +sil @_TZFC15resilient_class13OutsideParent11classMethodfT_T_ : $@convention(thin) (@thick OutsideParent.Type) -> () + +// super.ChildToFixedParent.method () -> () +sil @_TFC5super18ChildToFixedParent6methodfT_T_ : $@convention(method) (@guaranteed ChildToFixedParent) -> () { +// %0 +bb0(%0 : $ChildToFixedParent): + debug_value %0 : $ChildToFixedParent, let, name "self", argno 1 + strong_retain %0 : $ChildToFixedParent + %3 = upcast %0 : $ChildToFixedParent to $OutsideParent + %4 = super_method %0 : $ChildToFixedParent, #OutsideParent.method!1 : OutsideParent -> () -> () , $@convention(method) (@guaranteed OutsideParent) -> () + %5 = apply %4(%3) : $@convention(method) (@guaranteed OutsideParent) -> () + strong_release %3 : $OutsideParent + %7 = tuple () + return %7 : $() +} + +// CHECK-LABEL: define void @_TFC5super18ChildToFixedParent6methodfT_T_(%C5super18ChildToFixedParent*) +// CHECK: [[SUPER_METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class13OutsideParent() +// CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%C15resilient_class13OutsideParent*)** +// CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%C15resilient_class13OutsideParent*)*, void (%C15resilient_class13OutsideParent*)** [[OPAQUE_SUPER_METADATA]] +// CHECK: [[FN_PTR:%[0-9]+]] = load void (%C15resilient_class13OutsideParent*)*, void (%C15resilient_class13OutsideParent*)** [[VTABLE_SLOT]] +// CHECK: call void + +// static super.ChildToFixedParent.classMethod () -> () +sil @_TZFC5super18ChildToFixedParent11classMethodfT_T_ : $@convention(thin) (@thick ChildToFixedParent.Type) -> () { +// %0 +bb0(%0 : $@thick ChildToFixedParent.Type): + debug_value %0 : $@thick ChildToFixedParent.Type, let, name "self", argno 1 + %2 = upcast %0 : $@thick ChildToFixedParent.Type to $@thick OutsideParent.Type + %3 = super_method %0 : $@thick ChildToFixedParent.Type, #OutsideParent.classMethod!1 : OutsideParent.Type -> () -> () , $@convention(thin) (@thick OutsideParent.Type) -> () + %4 = apply %3(%2) : $@convention(thin) (@thick OutsideParent.Type) -> () + %5 = tuple () + return %5 : $() +} + +// ChildToFixedParent is in our resilience domain - load super metadata directly. +// CHECK-LABEL: define void @_TZFC5super18ChildToFixedParent11classMethodfT_T_(%swift.type*) +// CHECK: [[SUPER_METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class13OutsideParent() +// CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%swift.type*)** +// CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%swift.type*)*, void (%swift.type*)** [[OPAQUE_SUPER_METADATA]] +// CHECK: [[FN_PTR:%[0-9]+]] = load void (%swift.type*)*, void (%swift.type*)** [[VTABLE_SLOT]] +// CHECK: call void + +// ext.super.resilient_class.ResilientOutsideChild.callSuperMethod () -> () +sil @_TFE5superC15resilient_class21ResilientOutsideChild15callSuperMethodfT_T_ : $@convention(method) (@guaranteed ResilientOutsideChild) -> () { +// %0 +bb0(%0 : $ResilientOutsideChild): + debug_value %0 : $ResilientOutsideChild, let, name "self", argno 1 + strong_retain %0 : $ResilientOutsideChild + %3 = upcast %0 : $ResilientOutsideChild to $ResilientOutsideParent + %4 = super_method %0 : $ResilientOutsideChild, #ResilientOutsideParent.method!1 : ResilientOutsideParent -> () -> () , $@convention(method) (@guaranteed ResilientOutsideParent) -> () + %5 = apply %4(%3) : $@convention(method) (@guaranteed ResilientOutsideParent) -> () + strong_release %3 : $ResilientOutsideParent + %7 = tuple () + return %7 : $() +} + +// Extending a resilient class - load super metadata indirectly. +// CHECK-LABEL: define void @_TFE5superC15resilient_class21ResilientOutsideChild15callSuperMethodfT_T_(%C15resilient_class21ResilientOutsideChild*) +// CHECK: [[METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class21ResilientOutsideChild() +// CHECK: [[OPAQUE_METADATA:%[0-9]+]] = bitcast %swift.type* [[METADATA]] to %swift.type** +// CHECK: [[SUPER_METADATA_PTR:%[0-9]+]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1 +// CHECK: [[SUPER_METADATA:%[0-9]+]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]] +// CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%C15resilient_class22ResilientOutsideParent*)** +// CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%C15resilient_class22ResilientOutsideParent*)*, void (%C15resilient_class22ResilientOutsideParent*)** [[OPAQUE_SUPER_METADATA]] +// CHECK: [[FN_PTR:%[0-9]+]] = load void (%C15resilient_class22ResilientOutsideParent*)*, void (%C15resilient_class22ResilientOutsideParent*)** [[VTABLE_SLOT]] +// CHECK: call void + +// static ext.super.resilient_class.ResilientOutsideChild.callSuperClassMethod () -> () +sil @_TZFE5superC15resilient_class21ResilientOutsideChild20callSuperClassMethodfT_T_ : $@convention(thin) (@thick ResilientOutsideChild.Type) -> () { +// %0 +bb0(%0 : $@thick ResilientOutsideChild.Type): + debug_value %0 : $@thick ResilientOutsideChild.Type, let, name "self", argno 1 + %2 = upcast %0 : $@thick ResilientOutsideChild.Type to $@thick ResilientOutsideParent.Type + %3 = super_method %0 : $@thick ResilientOutsideChild.Type, #ResilientOutsideParent.classMethod!1 : ResilientOutsideParent.Type -> () -> () , $@convention(thin) (@thick ResilientOutsideParent.Type) -> () + %4 = apply %3(%2) : $@convention(thin) (@thick ResilientOutsideParent.Type) -> () + %5 = tuple () + return %5 : $() +} + +// Extending a resilient class - load super metadata indirectly. +// CHECK-LABEL: define void @_TZFE5superC15resilient_class21ResilientOutsideChild20callSuperClassMethodfT_T_(%swift.type*) +// CHECK: [[METADATA:%[0-9]+]] = call %swift.type* @_TMaC15resilient_class21ResilientOutsideChild() +// CHECK: [[OPAQUE_METADATA:%[0-9]+]] = bitcast %swift.type* [[METADATA]] to %swift.type** +// CHECK: [[SUPER_METADATA_PTR:%[0-9]+]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1 +// CHECK: [[SUPER_METADATA:%[0-9]+]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]] +// CHECK: [[OPAQUE_SUPER_METADATA:%[0-9]+]] = bitcast %swift.type* [[SUPER_METADATA]] to void (%swift.type*)** +// CHECK: [[VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%swift.type*)*, void (%swift.type*)** [[OPAQUE_SUPER_METADATA]] +// CHECK: [[FN_PTR:%[0-9]+]] = load void (%swift.type*)*, void (%swift.type*)** [[VTABLE_SLOT]] +// CHECK: call void + +sil_vtable ChildToResilientParent { + #ResilientOutsideParent.method!1: _TFC5super22ChildToResilientParent6methodfT_T_ // super.ChildToResilientParent.method () -> () + #ResilientOutsideParent.classMethod!1: _TZFC5super22ChildToResilientParent11classMethodfT_T_ // static super.ChildToResilientParent.classMethod () -> () +} + +sil_vtable ChildToFixedParent { + #OutsideParent.method!1: _TFC5super18ChildToFixedParent6methodfT_T_ // super.ChildToFixedParent.method () -> () + #OutsideParent.classMethod!1: _TZFC5super18ChildToFixedParent11classMethodfT_T_ // static super.ChildToFixedParent.classMethod () -> () +} + diff --git a/test/IRGen/super_class_method.sil b/test/IRGen/super_class_method.sil deleted file mode 100644 index 1bbe789196e81..0000000000000 --- a/test/IRGen/super_class_method.sil +++ /dev/null @@ -1,57 +0,0 @@ -// RUN: %target-swift-frontend -emit-ir %s | FileCheck %s - -sil_stage canonical - -import Builtin -import Swift -import SwiftShims - -public class Parent { - public class func foo() {} -} - -public class Child : Parent {} - -public class Grandchild : Child { - override public class func foo() { - super.foo() - } -} - -sil @Parent_foo : $@convention(thin) (@thick Parent.Type) -> () { -bb0(%0 : $@thick Parent.Type): - debug_value %0 : $@thick Parent.Type - %2 = tuple () - return %2 : $() -} - -sil @Grandchild_foo : $@convention(thin) (@thick Grandchild.Type) -> () { -bb0(%0 : $@thick Grandchild.Type): - debug_value %0 : $@thick Grandchild.Type - %2 = upcast %0 : $@thick Grandchild.Type to $@thick Child.Type - %3 = upcast %2 : $@thick Child.Type to $@thick Parent.Type - %4 = super_method %0 : $@thick Grandchild.Type, #Parent.foo!1 : (Parent.Type) -> () -> (), $@convention(thin) (@thick Parent.Type) -> () - %5 = apply %4(%3) : $@convention(thin) (@thick Parent.Type) -> () - %6 = tuple () - return %6 : $() -} - -sil_vtable Parent { - #Parent.foo!1: Parent_foo -} - -sil_vtable Child { - #Parent.foo!1: Parent_foo -} - -sil_vtable Grandchild { - #Parent.foo!1: Grandchild_foo -} - -// CHECK-LABEL: define void @Grandchild_foo(%swift.type*) #0 -// CHECK: [[CHILD_METADATA_PTR:%[0-9]+]] = call %swift.type* @_TMaC18super_class_method5Child() -// CHECK: [[CASTED_CHILD_METADATA_PTR:%[0-9]+]] = bitcast %swift.type* [[CHILD_METADATA_PTR]] to void (%swift.type*)** -// CHECK: [[FOO_VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%swift.type*)*, void (%swift.type*)** [[CASTED_CHILD_METADATA_PTR]] -// CHECK: [[FOO_FNPTR:%[0-9]+]] = load void (%swift.type*)*, void (%swift.type*)** [[FOO_VTABLE_SLOT]] -// CHECK: call void - diff --git a/test/IRGen/super_instance_method.sil b/test/IRGen/super_instance_method.sil deleted file mode 100644 index 1548e05f2a199..0000000000000 --- a/test/IRGen/super_instance_method.sil +++ /dev/null @@ -1,57 +0,0 @@ -// RUN: %target-swift-frontend -emit-ir %s | FileCheck %s - -sil_stage canonical - -import Builtin -import Swift -import SwiftShims - -public class Parent { - public func foo() {} -} - -public class Child : Parent {} - -public class Grandchild : Child { - override public func foo() { super.foo() } -} - -sil @Parent_foo : $@convention(method) (@guaranteed Parent) -> () { -bb0(%0 : $Parent): - debug_value %0 : $Parent - %2 = tuple () - return %2 : $() -} - -sil @Grandchild_foo : $@convention(method) (@guaranteed Grandchild) -> () { -bb0(%0 : $Grandchild): - debug_value %0 : $Grandchild - strong_retain %0 : $Grandchild - %3 = upcast %0 : $Grandchild to $Child - %4 = upcast %3 : $Child to $Parent - %5 = super_method %0 : $Grandchild, #Parent.foo!1 : (Parent) -> () -> (), $@convention(method) (@guaranteed Parent) -> () - %6 = apply %5(%4) : $@convention(method) (@guaranteed Parent) -> () - strong_release %4 : $Parent - %8 = tuple () - return %8 : $() -} - -sil_vtable Parent { - #Parent.foo!1: Parent_foo -} - -sil_vtable Child { - #Parent.foo!1: Parent_foo -} - -sil_vtable Grandchild { - #Parent.foo!1: Grandchild_foo -} - -// CHECK-LABEL: define void @Grandchild_foo(%C21super_instance_method10Grandchild*) -// CHECK: [[CHILD_METADATA_PTR:%[0-9]+]] = call %swift.type* @_TMaC21super_instance_method5Child() -// CHECK: [[CASTED_CHILD_METADATA_PTR:%[0-9]+]] = bitcast %swift.type* [[CHILD_METADATA_PTR]] to void (%C21super_instance_method6Parent*)** -// CHECK: [[FOO_VTABLE_SLOT:%[0-9]+]] = getelementptr inbounds void (%C21super_instance_method6Parent*)*, void (%C21super_instance_method6Parent*)** [[CASTED_CHILD_METADATA_PTR]] -// CHECK: [[FOO_FN_PTR:%[0-9]+]] = load void (%C21super_instance_method6Parent*)*, void (%C21super_instance_method6Parent*)** [[FOO_VTABLE_SLOT]] -// CHECK: call void - diff --git a/test/IRGen/type_layout_reference_storage.swift b/test/IRGen/type_layout_reference_storage.swift index 764feb97455db..f8097ec4d3eae 100644 --- a/test/IRGen/type_layout_reference_storage.swift +++ b/test/IRGen/type_layout_reference_storage.swift @@ -20,11 +20,13 @@ struct ReferenceStorageTypeLayout { weak var cwi: C! // -- Open-code layout for protocol types with witness tables. - // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_[[REF_XI:[0-9a-f]+]]_bt, i32 0, i32 0) - // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[REF_XI:[0-9a-f]+]]_bt, i32 0, i32 0) + // Note that the layouts for unowned(safe) references are + // only bitwise takable when ObjC interop is disabled. + // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_[[UNOWNED_XI:[0-9a-f]+]]{{(,|_bt,)}} i32 0, i32 0) + // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[UNOWNED_XI:[0-9a-f]+]]{{(,|_bt,)}} i32 0, i32 0) unowned(safe) var ps: P - // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_[[REF_XI]]_pod, i32 0, i32 0) - // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[REF_XI]]_pod, i32 0, i32 0) + // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_[[REF_XI:[0-9a-f]+]]_pod, i32 0, i32 0) + // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[REF_XI:[0-9a-f]+]]_pod, i32 0, i32 0) unowned(unsafe) var pu: P // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_[[WEAK_XI:[0-9a-f]+]], i32 0, i32 0) // CHECK-32: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_8_4_[[WEAK_XI:[0-9a-f]+]], i32 0, i32 0) @@ -33,8 +35,8 @@ struct ReferenceStorageTypeLayout { // CHECK-32: store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_8_4_[[WEAK_XI]], i32 0, i32 0) weak var pwi: P! - // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_[[REF_XI]]_bt, i32 0, i32 0) - // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_[[REF_XI]]_bt, i32 0, i32 0) + // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_[[UNOWNED_XI]]{{(,|_bt,)}} i32 0, i32 0) + // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_[[UNOWNED_XI]]{{(,|_bt,)}} i32 0, i32 0) unowned(safe) var pqs: protocol // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_24_8_[[REF_XI]]_pod, i32 0, i32 0) // CHECK-32: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_12_4_[[REF_XI]]_pod, i32 0, i32 0) diff --git a/test/IRGen/unowned.sil b/test/IRGen/unowned.sil index dffb3017f5c1f..f07b7ef8294b6 100644 --- a/test/IRGen/unowned.sil +++ b/test/IRGen/unowned.sil @@ -1,13 +1,11 @@ -// RUN: %target-swift-frontend -emit-ir %s | FileCheck %s +// RUN: %target-swift-frontend -disable-objc-interop -emit-ir %s | FileCheck %s // REQUIRES: CPU=x86_64 -// XFAIL: linux -// CHECK: [[OPAQUE:%swift.opaque]] = type opaque // CHECK: [[TYPE:%swift.type]] = type // CHECK: [[C:%C7unowned1C]] = type <{ [[REF:%swift.refcounted]] }> -// CHECK: [[UNKNOWN:%objc_object]] = type opaque -// CHECK: [[A:%V7unowned1A]] = type <{ [[C]]* }> +// CHECK: [[OPAQUE:%swift.opaque]] = type opaque +// CHECK: [[A:%V7unowned1A]] = type <{ %swift.unowned }> class C {} sil_vtable C {} @@ -29,8 +27,8 @@ bb0(%0 : $@sil_unowned C): %4 = return %3 : $() } // CHECK: define void @test_weak_rr_class([[C]]*) {{.*}} { -// CHECK: call void bitcast (void ([[REF]]*)* @swift_weakRetain to void ([[C]]*)*)([[C]]* %0) -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRelease to void ([[C]]*)*)([[C]]* %0) +// CHECK: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* %0) +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* %0) // CHECK-NEXT: ret void sil @test_weak_rr_proto : $@convention(thin) (@sil_unowned P) -> () { @@ -40,9 +38,9 @@ bb0(%0 : $@sil_unowned P): %3 = tuple () %4 = return %3 : $() } -// CHECK: define void @test_weak_rr_proto([[UNKNOWN]]*, i8**) {{.*}} { -// CHECK: call void bitcast (void ([[REF]]*)* @swift_unknownWeakRetain to void ([[UNKNOWN]]*)*)([[UNKNOWN]]* %0) -// CHECK: call void bitcast (void ([[REF]]*)* @swift_unknownWeakRelease to void ([[UNKNOWN]]*)*)([[UNKNOWN]]* %0) +// CHECK: define void @test_weak_rr_proto(%swift.refcounted*, i8**) {{.*}} { +// CHECK: call void @swift_unownedRetain(%swift.refcounted* %0) +// CHECK: call void @swift_unownedRelease(%swift.refcounted* %0) // CHECK-NEXT: ret void // Value witnesses for A: @@ -51,8 +49,9 @@ bb0(%0 : $@sil_unowned P): // CHECK: define linkonce_odr hidden void @_TwXXV7unowned1A([[BUFFER:\[24 x i8\]]]* [[ARG:%.*]], [[TYPE]]* // CHECK: [[T0:%.*]] = bitcast [[BUFFER]]* [[ARG]] to [[A]]* // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0 -// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1]], align 8 -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRelease to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[T2]]) // CHECK-NEXT: ret void // initializeBufferWithCopyOfBuffer @@ -61,9 +60,11 @@ bb0(%0 : $@sil_unowned P): // CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]* // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 -// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1]], align 8 -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRetain to void ([[C]]*)*)([[C]]* [[T2]]) -// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0]], align 8 +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: [[T0C:%.*]] = bitcast %swift.unowned* [[T0]] to [[C]]* +// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0C]], align 8 // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] @@ -71,8 +72,9 @@ bb0(%0 : $@sil_unowned P): // CHECK: define linkonce_odr hidden void @_TwxxV7unowned1A([[OPAQUE]]* [[ARG:%.*]], [[TYPE]]* // CHECK: [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]* // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0 -// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1]], align 8 -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRelease to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[T2]]) // CHECK-NEXT: ret void // initializeBufferWithCopy @@ -81,9 +83,11 @@ bb0(%0 : $@sil_unowned P): // CHECK-NEXT: [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]* // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 -// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1]], align 8 -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRetain to void ([[C]]*)*)([[C]]* [[T2]]) -// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0]], align 8 +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: [[T0C:%.*]] = bitcast %swift.unowned* [[T0]] to [[C]]* +// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0C]], align 8 // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] @@ -93,9 +97,11 @@ bb0(%0 : $@sil_unowned P): // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 -// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1]], align 8 -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRetain to void ([[C]]*)*)([[C]]* [[T2]]) -// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0]], align 8 +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: [[T0C:%.*]] = bitcast %swift.unowned* [[T0]] to [[C]]* +// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0C]], align 8 // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] @@ -105,11 +111,13 @@ bb0(%0 : $@sil_unowned P): // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 // CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 -// CHECK-NEXT: [[NEW:%.*]] = load [[C]]*, [[C]]** [[SRC_X]], align 8 -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRetain to void ([[C]]*)*)([[C]]* [[NEW]]) -// CHECK-NEXT: [[OLD:%.*]] = load [[C]]*, [[C]]** [[DEST_X]], align 8 -// CHECK-NEXT: store [[C]]* [[NEW]], [[C]]** [[DEST_X]], align 8 -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRelease to void ([[C]]*)*)([[C]]* [[OLD]]) +// CHECK-NEXT: [[SRC_X_C:%.*]] = bitcast %swift.unowned* [[SRC_X]] to [[C]]* +// CHECK-NEXT: [[NEW:%.*]] = load [[C]]*, [[C]]** [[SRC_X_C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* [[NEW]]) +// CHECK-NEXT: [[DEST_X_C:%.*]] = bitcast %swift.unowned* [[DEST_X]] to [[C]]* +// CHECK-NEXT: [[OLD:%.*]] = load [[C]]*, [[C]]** [[DEST_X_C]], align 8 +// CHECK-NEXT: store [[C]]* [[NEW]], [[C]]** [[DEST_X_C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[OLD]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] @@ -119,9 +127,11 @@ bb0(%0 : $@sil_unowned P): // CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* // CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 // CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 -// CHECK-NEXT: [[NEW:%.*]] = load [[C]]*, [[C]]** [[SRC_X]], align 8 -// CHECK-NEXT: [[OLD:%.*]] = load [[C]]*, [[C]]** [[DEST_X]], align 8 -// CHECK-NEXT: store [[C]]* [[NEW]], [[C]]** [[DEST_X]], align 8 -// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_weakRelease to void ([[C]]*)*)([[C]]* [[OLD]]) +// CHECK-NEXT: [[SRC_X_C:%.*]] = bitcast %swift.unowned* [[SRC_X]] to [[C]]* +// CHECK-NEXT: [[NEW:%.*]] = load [[C]]*, [[C]]** [[SRC_X_C]], align 8 +// CHECK-NEXT: [[DEST_X_C:%.*]] = bitcast %swift.unowned* [[DEST_X]] to [[C]]* +// CHECK-NEXT: [[OLD:%.*]] = load [[C]]*, [[C]]** [[DEST_X_C]], align 8 +// CHECK-NEXT: store [[C]]* [[NEW]], [[C]]** [[DEST_X_C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[OLD]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* // CHECK-NEXT: ret [[OPAQUE]]* [[T0]] diff --git a/test/IRGen/unowned_objc.sil b/test/IRGen/unowned_objc.sil new file mode 100644 index 0000000000000..44cf29c525d8b --- /dev/null +++ b/test/IRGen/unowned_objc.sil @@ -0,0 +1,240 @@ +// RUN: %target-swift-frontend -emit-ir %s | FileCheck %s + +// REQUIRES: CPU=x86_64 +// XFAIL: linux + +// These types end up in a completely different order with interop disabled. +// CHECK: [[OPAQUE:%swift.opaque]] = type opaque +// CHECK: [[TYPE:%swift.type]] = type +// CHECK: [[C:%C12unowned_objc1C]] = type <{ [[REF:%swift.refcounted]] }> +// CHECK: [[UNKNOWN:%objc_object]] = type +// CHECK: [[A:%V12unowned_objc1A]] = type <{ %swift.unowned }> + +class C {} +sil_vtable C {} +protocol P : class { + func explode() +} + +sil @_TFC12unowned_objc1CD : $@convention(method) (C) -> () + +struct A { + unowned var x : C +} + +struct B { + unowned var x : P +} + +sil @test_weak_rr_class : $@convention(thin) (@sil_unowned C) -> () { +bb0(%0 : $@sil_unowned C): + %1 = unowned_retain %0 : $@sil_unowned C + %2 = unowned_release %0 : $@sil_unowned C + %3 = tuple () + %4 = return %3 : $() +} +// CHECK: define void @test_weak_rr_class([[C]]*) {{.*}} { +// CHECK: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* %0) +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* %0) +// CHECK-NEXT: ret void + +// CHECK: define void @test_unknown_unowned_copies([[UNKNOWN]]*, i8**, [[UNKNOWN]]*, i8**) +sil @test_unknown_unowned_copies : $@convention(thin) (@owned P, @owned P) -> () { +bb0(%p : $P, %q : $P): + + // CHECK: [[X:%.*]] = alloca [[UREF:{ %swift.unowned, i8.. }]], align 8 + // CHECK-NEXT: [[Y:%.*]] = alloca [[UREF]], align 8 + + // CHECK-NEXT: bitcast + // CHECK-NEXT: llvm.lifetime.start + %x = alloc_stack $@sil_unowned P + // CHECK-NEXT: bitcast + // CHECK-NEXT: llvm.lifetime.start + %y = alloc_stack $@sil_unowned P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 1 + // CHECK-NEXT: store i8** [[PP:%1]], i8*** [[T0]], align 8 + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 0 + // CHECK-NEXT: call void @swift_unknownUnownedInit(%swift.unowned* [[T0]], [[UNKNOWN]]* [[PV:%0]]) + store_unowned %p to [initialization] %x : $*@sil_unowned P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 0 + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 0 + // CHECK-NEXT: call void @swift_unknownUnownedCopyInit(%swift.unowned* [[T0]], %swift.unowned* [[T1]]) + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 1 + // CHECK-NEXT: [[WT:%.*]] = load i8**, i8*** [[T0]], align 8 + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 1 + // CHECK-NEXT: store i8** [[WT]], i8*** [[T0]], align 8 + copy_addr %x to [initialization] %y : $*@sil_unowned P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 0 + // CHECK-NEXT: [[TV:%.*]] = call [[UNKNOWN]]* @swift_unknownUnownedLoadStrong(%swift.unowned* [[T0]]) + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 1 + // CHECK-NEXT: [[TP:%.*]] = load i8**, i8*** [[T0]], align 8 + %t0 = load_unowned %x : $*@sil_unowned P + + // CHECK-NEXT: call void @swift_unknownRelease([[UNKNOWN]]* [[TV]]) + strong_release %t0 : $P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 0 + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 0 + // CHECK-NEXT: call void @swift_unknownUnownedCopyAssign(%swift.unowned* [[T0]], %swift.unowned* [[T1]]) + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 1 + // CHECK-NEXT: [[WT:%.*]] = load i8**, i8*** [[T0]], align 8 + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 1 + // CHECK-NEXT: store i8** [[WT]], i8*** [[T0]], align 8 + copy_addr %x to %y : $*@sil_unowned P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 1 + // CHECK-NEXT: store i8** [[QP:%3]], i8*** [[T0]], align 8 + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 0 + // CHECK-NEXT: call void @swift_unknownUnownedAssign(%swift.unowned* [[T0]], [[UNKNOWN]]* [[QV:%2]]) + store_unowned %q to %y : $*@sil_unowned P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 0 + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 0 + // CHECK-NEXT: call void @swift_unknownUnownedTakeAssign(%swift.unowned* [[T0]], %swift.unowned* [[T1]]) + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 1 + // CHECK-NEXT: [[WT:%.*]] = load i8**, i8*** [[T0]], align 8 + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 1 + // CHECK-NEXT: store i8** [[WT]], i8*** [[T0]], align 8 + copy_addr [take] %x to %y : $*@sil_unowned P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 0 + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 0 + // CHECK-NEXT: call void @swift_unknownUnownedTakeInit(%swift.unowned* [[T0]], %swift.unowned* [[T1]]) + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 1 + // CHECK-NEXT: [[WT:%.*]] = load i8**, i8*** [[T0]], align 8 + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 1 + // CHECK-NEXT: store i8** [[WT]], i8*** [[T0]], align 8 + copy_addr [take] %y to [initialization] %x : $*@sil_unowned P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 0 + // CHECK-NEXT: [[TV:%.*]] = call [[UNKNOWN]]* @swift_unknownUnownedTakeStrong(%swift.unowned* [[T0]]) + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[Y]], i32 0, i32 1 + // CHECK-NEXT: [[TP:%.*]] = load i8**, i8*** [[T0]], align 8 + %t1 = load_unowned [take] %y : $*@sil_unowned P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 1 + // CHECK-NEXT: store i8** [[TP]], i8*** [[T0]], align 8 + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 0 + // CHECK-NEXT: call void @swift_unknownUnownedInit(%swift.unowned* [[T0]], [[UNKNOWN]]* [[TV]]) + store_unowned %t1 to [initialization] %x : $*@sil_unowned P + + // CHECK-NEXT: call void @swift_unknownRelease([[UNKNOWN]]* [[TV]]) + strong_release %t1 : $P + + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[UREF]], [[UREF]]* [[X]], i32 0, i32 0 + // CHECK-NEXT: call void @swift_unknownUnownedDestroy(%swift.unowned* [[T0]]) + destroy_addr %x : $*@sil_unowned P + + // CHECK-NEXT: bitcast + // CHECK-NEXT: llvm.lifetime.end + dealloc_stack %y : $*@sil_unowned P + // CHECK-NEXT: bitcast + // CHECK-NEXT: llvm.lifetime.end + dealloc_stack %x : $*@sil_unowned P + + // CHECK-NEXT: call void @swift_unknownRelease([[UNKNOWN]]* [[PV]]) + strong_release %p : $P + + // CHECK-NEXT: call void @swift_unknownRelease([[UNKNOWN]]* [[QV]]) + strong_release %q : $P + + // CHECK-NEXT: ret void + %0 = tuple () + return %0 : $() +} + +// Value witnesses for A: + +// destroyBuffer +// CHECK: define linkonce_odr hidden void @_TwXXV12unowned_objc1A([[BUFFER:\[24 x i8\]]]* [[ARG:%.*]], [[TYPE]]* +// CHECK: [[T0:%.*]] = bitcast [[BUFFER]]* [[ARG]] to [[A]]* +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0 +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: ret void + +// initializeBufferWithCopyOfBuffer +// CHECK: define linkonce_odr hidden [[OPAQUE]]* @_TwCPV12unowned_objc1A([[BUFFER]]* [[DESTBUF:%.*]], [[BUFFER]]* [[SRCBUF:%.*]], [[TYPE]]* +// CHECK: [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]* +// CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]* +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: [[T0C:%.*]] = bitcast %swift.unowned* [[T0]] to [[C]]* +// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0C]], align 8 +// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* +// CHECK-NEXT: ret [[OPAQUE]]* [[T0]] + +// destroy +// CHECK: define linkonce_odr hidden void @_TwxxV12unowned_objc1A([[OPAQUE]]* [[ARG:%.*]], [[TYPE]]* +// CHECK: [[T0:%.*]] = bitcast [[OPAQUE]]* [[ARG]] to [[A]]* +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i32 0, i32 0 +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: ret void + +// initializeBufferWithCopy +// CHECK: define linkonce_odr hidden [[OPAQUE]]* @_TwCpV12unowned_objc1A([[BUFFER]]* [[DESTBUF:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]* +// CHECK: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* +// CHECK-NEXT: [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]* +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: [[T0C:%.*]] = bitcast %swift.unowned* [[T0]] to [[C]]* +// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0C]], align 8 +// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* +// CHECK-NEXT: ret [[OPAQUE]]* [[T0]] + +// initializeWithCopy +// CHECK: define linkonce_odr hidden [[OPAQUE]]* @_TwcpV12unowned_objc1A([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]* +// CHECK: [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]* +// CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 +// CHECK-NEXT: [[T1C:%.*]] = bitcast %swift.unowned* [[T1]] to [[C]]* +// CHECK-NEXT: [[T2:%.*]] = load [[C]]*, [[C]]** [[T1C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* [[T2]]) +// CHECK-NEXT: [[T0C:%.*]] = bitcast %swift.unowned* [[T0]] to [[C]]* +// CHECK-NEXT: store [[C]]* [[T2]], [[C]]** [[T0C]], align 8 +// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* +// CHECK-NEXT: ret [[OPAQUE]]* [[T0]] + +// assignWithCopy +// CHECK: define linkonce_odr hidden [[OPAQUE]]* @_TwcaV12unowned_objc1A([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]* +// CHECK: [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]* +// CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* +// CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 +// CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 +// CHECK-NEXT: [[SRC_X_C:%.*]] = bitcast %swift.unowned* [[SRC_X]] to [[C]]* +// CHECK-NEXT: [[NEW:%.*]] = load [[C]]*, [[C]]** [[SRC_X_C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRetain to void ([[C]]*)*)([[C]]* [[NEW]]) +// CHECK-NEXT: [[DEST_X_C:%.*]] = bitcast %swift.unowned* [[DEST_X]] to [[C]]* +// CHECK-NEXT: [[OLD:%.*]] = load [[C]]*, [[C]]** [[DEST_X_C]], align 8 +// CHECK-NEXT: store [[C]]* [[NEW]], [[C]]** [[DEST_X_C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[OLD]]) +// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* +// CHECK-NEXT: ret [[OPAQUE]]* [[T0]] + +// assignWithTake +// CHECK: define linkonce_odr hidden [[OPAQUE]]* @_TwtaV12unowned_objc1A([[OPAQUE]]* [[DEST_OPQ:%.*]], [[OPAQUE]]* [[SRC_OPQ:%.*]], [[TYPE]]* +// CHECK: [[DEST:%.*]] = bitcast [[OPAQUE]]* [[DEST_OPQ]] to [[A]]* +// CHECK-NEXT: [[SRC:%.*]] = bitcast [[OPAQUE]]* [[SRC_OPQ]] to [[A]]* +// CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0 +// CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0 +// CHECK-NEXT: [[SRC_X_C:%.*]] = bitcast %swift.unowned* [[SRC_X]] to [[C]]* +// CHECK-NEXT: [[NEW:%.*]] = load [[C]]*, [[C]]** [[SRC_X_C]], align 8 +// CHECK-NEXT: [[DEST_X_C:%.*]] = bitcast %swift.unowned* [[DEST_X]] to [[C]]* +// CHECK-NEXT: [[OLD:%.*]] = load [[C]]*, [[C]]** [[DEST_X_C]], align 8 +// CHECK-NEXT: store [[C]]* [[NEW]], [[C]]** [[DEST_X_C]], align 8 +// CHECK-NEXT: call void bitcast (void ([[REF]]*)* @swift_unownedRelease to void ([[C]]*)*)([[C]]* [[OLD]]) +// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]* +// CHECK-NEXT: ret [[OPAQUE]]* [[T0]] diff --git a/test/IRGen/weak.sil b/test/IRGen/weak.sil index 6783da6673247..c6e600ea69526 100644 --- a/test/IRGen/weak.sil +++ b/test/IRGen/weak.sil @@ -77,14 +77,14 @@ bb0(%0 : $*B, %1 : $Optional

): // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { [[WEAK]], i8** }, { [[WEAK]], i8** }* [[X]], i32 0, i32 0 // CHECK-NEXT: call void @swift_unknownWeakAssign([[WEAK]]* [[T0]], [[UNKNOWN]]* [[TMPOBJ]]) // CHECK: [[RECOMPUTED_TMPOBJ:%.*]] = inttoptr {{.*}} to %objc_object* -// CHECK: call void bitcast (void (%swift.refcounted*)* @swift_unknownRelease to void (%objc_object*)*)(%objc_object* [[RECOMPUTED_TMPOBJ]]) +// CHECK: call void @swift_unknownRelease(%objc_object* [[RECOMPUTED_TMPOBJ]]) sil @test_weak_alloc_stack : $@convention(thin) (Optional

) -> () { bb0(%0 : $Optional

): %1 = alloc_stack $@sil_weak Optional

- store_weak %0 to [initialization] %1#1 : $*@sil_weak Optional

- destroy_addr %1#1 : $*@sil_weak Optional

- dealloc_stack %1#0 : $*@local_storage @sil_weak Optional

+ store_weak %0 to [initialization] %1 : $*@sil_weak Optional

+ destroy_addr %1 : $*@sil_weak Optional

+ dealloc_stack %1 : $*@sil_weak Optional

%4 = tuple () return %4 : $() } @@ -98,6 +98,8 @@ bb0(%0 : $Optional

): // CHECK-NEXT: call void @swift_unknownWeakInit([[WEAK]]* [[T0]], [[UNKNOWN]]* [[TMPOBJ:%.*]]) // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds { [[WEAK]], i8** }, { [[WEAK]], i8** }* [[X]], i32 0, i32 0 // CHECK-NEXT: call void @swift_unknownWeakDestroy([[WEAK]]* [[T0]]) +// CHECK-NEXT: bitcast +// CHECK-NEXT: llvm.lifetime.end // CHECK-NEXT: ret void // Value witnesses for A: diff --git a/test/IRGen/witness_table_objc_associated_type.swift b/test/IRGen/witness_table_objc_associated_type.swift index 52617035b8520..91a565e5e75e3 100644 --- a/test/IRGen/witness_table_objc_associated_type.swift +++ b/test/IRGen/witness_table_objc_associated_type.swift @@ -20,8 +20,8 @@ struct SB: B { func foo() {} } // CHECK-LABEL: @_TWPV34witness_table_objc_associated_type2SBS_1BS_ = hidden constant [3 x i8*] [ -// CHECK: i8* null -// CHECK: i8* null +// CHECK: i8* bitcast (%swift.type* ()* @_TMaV34witness_table_objc_associated_type2SA to i8*) +// CHECK: i8* bitcast (i8** ()* @_TWaV34witness_table_objc_associated_type2SAS_1AS_ to i8*) // CHECK: i8* bitcast {{.*}} @_TTWV34witness_table_objc_associated_type2SBS_1BS_FS1_3foofT_T_ // CHECK: ] @@ -31,7 +31,7 @@ struct SO: C { func foo() {} } // CHECK-LABEL: @_TWPV34witness_table_objc_associated_type2SOS_1CS_ = hidden constant [2 x i8*] [ -// CHECK: i8* null +// CHECK: i8* bitcast (%swift.type* ()* @_TMaC34witness_table_objc_associated_type2CO to i8*) // CHECK: i8* bitcast {{.*}} @_TTWV34witness_table_objc_associated_type2SOS_1CS_FS1_3foofT_T_ // CHECK: ] diff --git a/test/Inputs/clang-importer-sdk/usr/include/AppKit.h b/test/Inputs/clang-importer-sdk/usr/include/AppKit.h index ef44fdd85d461..4961a41caa8d7 100644 --- a/test/Inputs/clang-importer-sdk/usr/include/AppKit.h +++ b/test/Inputs/clang-importer-sdk/usr/include/AppKit.h @@ -126,7 +126,7 @@ +(instancetype)havingConvenienceFactoryAndLaterConvenienceInitWithFlim:(NSInteger)flim; -(instancetype)initWithFlim:(NSInteger)flim __attribute__((availability(macosx,introduced=10.11))); -// Convenience convenience init declaration followed by convenience factory +// Convenience init declaration followed by convenience factory -(instancetype)initWithFlam:(NSInteger)flam __attribute__((availability(macosx,introduced=10.11))); +(instancetype)havingConvenienceFactoryAndLaterConvenienceInitWithFlam:(NSInteger)flam; @end @@ -253,6 +253,8 @@ struct Point3D { double x, y, z; }; -(void)drawAtPoint:(struct Point3D)point withAttributes:(nullable NSDictionary *)attributes; -(void)setTextColor:(nullable NSColor *)color; -(void)drawInView:(nullable NSView *)view; +-(void)drawAnywhereInView:(nullable NSView *)view options:(nonnull NSDictionary *)options; +-(void)drawAnywhereWithOptions:(nonnull NSDictionary *)options; @end @interface NSBezierPath : NSObject diff --git a/test/Inputs/clang-importer-sdk/usr/include/Foundation.h b/test/Inputs/clang-importer-sdk/usr/include/Foundation.h index ac3d8cd072e56..785dfcb22941f 100644 --- a/test/Inputs/clang-importer-sdk/usr/include/Foundation.h +++ b/test/Inputs/clang-importer-sdk/usr/include/Foundation.h @@ -985,3 +985,7 @@ typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions) { int variadicFunc1(int A, ...); int variadicFunc2(int A, ...); + +@interface NSString (UTF8) +-(nullable instancetype)initWithUTF8String:(const char *)bytes; +@end diff --git a/test/Inputs/comment_to_something_conversion.swift b/test/Inputs/comment_to_something_conversion.swift index b701185819822..5cc956dfeb4f3 100644 --- a/test/Inputs/comment_to_something_conversion.swift +++ b/test/Inputs/comment_to_something_conversion.swift @@ -115,7 +115,7 @@ enum A012_AttachToEntities { /// f0() // WOW! /// f0() // WOW! func f0() {} -// CHECK: DocCommentAsXML=[f0()s:FC14swift_ide_test9CodeBlock2f0FT_T_func f0()This is how you use this code.] +// CHECK: DocCommentAsXML=[f0()s:FC14swift_ide_test9CodeBlock2f0FT_T_func f0()This is how you use this code.] } @objc class EmptyComments { @@ -378,7 +378,7 @@ func f0(x: Int, y: Int, z: Int) {} var z = 3 */ func f1() {} -// CHECK: DocCommentAsXML=[f1()s:FC14swift_ide_test20IndentedBlockComment2f1FT_T_func f1()Brief.First paragraph line. Second paragraph line.Now for a code sample:] +// CHECK: DocCommentAsXML=[f1()s:FC14swift_ide_test20IndentedBlockComment2f1FT_T_func f1()Brief.First paragraph line. Second paragraph line.Now for a code sample:] /** Hugely indented brief. @@ -392,7 +392,7 @@ func f0(x: Int, y: Int, z: Int) {} var z = 3 */ func f2() {} -// CHECK: {{.*}}DocCommentAsXML=[f2()s:FC14swift_ide_test20IndentedBlockComment2f2FT_T_func f2()Hugely indented brief.First paragraph line. Second paragraph line.Now for a code sample:] +// CHECK: {{.*}}DocCommentAsXML=[f2()s:FC14swift_ide_test20IndentedBlockComment2f2FT_T_func f2()Hugely indented brief.First paragraph line. Second paragraph line.Now for a code sample:] } @objc class MultiLineBrief { @@ -405,3 +405,20 @@ func f0(x: Int, y: Int, z: Int) {} func f0() {} // CHECK: {{.*}}DocCommentAsXML=[f0()s:FC14swift_ide_test14MultiLineBrief2f0FT_T_func f0()Brief first line. Brief after softbreak.Some paragraph text.] } + +/// Brief. +/// +/// ``` +/// thisIsASwiftCodeExample() +/// ``` +func codeListingWithDefaultLanguage() {} +// CHECK: DocCommentAsXML=[codeListingWithDefaultLanguage()s:F14swift_ide_test30codeListingWithDefaultLanguageFT_T_func codeListingWithDefaultLanguage()Brief.] CommentXMLValid + + +/// Brief. +/// +/// ```c++ +/// Something::Something::create(); +/// ``` +func codeListingWithOtherLanguage() {} +// CHECK: DocCommentAsXML=[codeListingWithOtherLanguage()s:F14swift_ide_test28codeListingWithOtherLanguageFT_T_func codeListingWithOtherLanguage()Brief.] diff --git a/test/Inputs/getmtime.py b/test/Inputs/getmtime.py index 0a7a1397b6a8b..6791b7b88b86b 100755 --- a/test/Inputs/getmtime.py +++ b/test/Inputs/getmtime.py @@ -1,6 +1,8 @@ #!/usr/bin/env python +from __future__ import print_function + import os import sys -print os.path.getmtime(sys.argv[1]) +print(os.path.getmtime(sys.argv[1])) diff --git a/test/Inputs/resilient_class.swift b/test/Inputs/resilient_class.swift new file mode 100644 index 0000000000000..64c966f99656c --- /dev/null +++ b/test/Inputs/resilient_class.swift @@ -0,0 +1,218 @@ + +import resilient_struct + + +// Fixed-layout, fixed-size base class + +@_fixed_layout +public class OutsideParent { + public var property: String = "OutsideParent.property" + + public class var classProperty: String { + return "OutsideParent.classProperty" + } + + public init() { + print("OutsideParent.init()") + } + + public func method() { + print("OutsideParent.method()") + } + + public class func classMethod() { + print("OutsideParent.classMethod()") + } +} + + +// Fixed-layout, resiliently-sized base class + +@_fixed_layout +public class OutsideParentWithResilientProperty { + public let p: Point + public let s: Size + public let color: Int32 + + public init(p: Point, s: Size, color: Int32) { + self.p = p + self.s = s + self.color = color + } +} + + +// Resilient base class + +public class ResilientOutsideParent { + public var property: String = "ResilientOutsideParent.property" + public final var finalProperty: String = "ResilientOutsideParent.finalProperty" + + public class var classProperty: String { + return "ResilientOutsideParent.classProperty" + } + + public init() { + print("ResilientOutsideParent.init()") + } + + public func method() { + print("ResilientOutsideParent.method()") + } + + public class func classMethod() { + print("ResilientOutsideParent.classMethod()") + } +} + + +// Fixed-layout, fixed-size subclass + +@_fixed_layout +public class OutsideChild : OutsideParent { + public override func method() { + print("OutsideChild.method()") + super.method() + } + + public override class func classMethod() { + print("OutsideChild.classMethod()") + super.classMethod() + } +} + + +// Resilient subclass + +public class ResilientOutsideChild : ResilientOutsideParent { + public override func method() { + print("ResilientOutsideChild.method()") + super.method() + } + + public override class func classMethod() { + print("ResilientOutsideChild.classMethod()") + super.classMethod() + } +} + + +// Fixed-layout, dependently-sized, generic base class + +@_fixed_layout +public class GenericOutsideParent { + public var property: A + public init(property: A) { + self.property = property + print("GenericOutsideParent.init()") + } + + public func method() { + print("GenericOutsideParent.method()") + } + + public class func classMethod() { + print("GenericOutsideParent.classMethod()") + } +} + + +// Resilient generic base class + +public class ResilientGenericOutsideParent { + public var property: A + public init(property: A) { + self.property = property + print("ResilientGenericOutsideParent.init()") + } + + public func method() { + print("ResilientGenericOutsideParent.method()") + } + + public class func classMethod() { + print("ResilientGenericOutsideParent.classMethod()") + } +} + + +// Fixed-layout, dependently-sized, generic subclass + +@_fixed_layout +public class GenericOutsideChild : GenericOutsideParent { + public override init(property: A) { + print("GenericOutsideGenericChild.init(a: A)") + super.init(property: property) + } + + public override func method() { + print("GenericOutsideChild.method()") + super.method() + } + + public override class func classMethod() { + print("GenericOutsideChild.classMethod()") + super.classMethod() + } +} + + +// Resilient generic subclass + +public class ResilientGenericOutsideChild : ResilientGenericOutsideParent { + public override init(property: A) { + print("ResilientGenericOutsideGenericChild.init(a: A)") + super.init(property: property) + } + + public override func method() { + print("ResilientGenericOutsideChild.method()") + super.method() + } + + public override class func classMethod() { + print("ResilientGenericOutsideChild.classMethod()") + super.classMethod() + } +} + + +// Fixed-layout, fixed-size subclass of generic class + +@_fixed_layout +public class ConcreteOutsideChild : GenericOutsideParent { + public override init(property: String) { + print("ConcreteOutsideChild.init(property: String)") + super.init(property: property) + } + + public override func method() { + print("ConcreteOutsideChild.method()") + super.method() + } + + public override class func classMethod() { + print("ConcreteOutsideChild.classMethod()") + super.classMethod() + } +} + + +// Resilient subclass of generic class + +public class ResilientConcreteOutsideChild : ResilientGenericOutsideParent { + public override init(property: String) { + print("ResilientConcreteOutsideChild.init(property: String)") + super.init(property: property) + } + + public override func method() { + print("ResilientConcreteOutsideChild.method()") + super.method() + } + + public override class func classMethod() { + print("ResilientConcreteOutsideChild.classMethod()") + super.classMethod() + } +} diff --git a/test/Inputs/resilient_enum.swift b/test/Inputs/resilient_enum.swift index 37fed4878fc31..0dd8c7ea0d169 100644 --- a/test/Inputs/resilient_enum.swift +++ b/test/Inputs/resilient_enum.swift @@ -1,9 +1,16 @@ import resilient_struct +// Fixed-layout enum with resilient members +@_fixed_layout public enum SimpleShape { + case KleinBottle + case Triangle(Size) +} + // Fixed-layout enum with resilient members @_fixed_layout public enum Shape { + case Point case Rect(Size) - case RoundedRect(Size) + case RoundedRect(Size, Size) } // Fixed-layout enum with indirect resilient members @@ -12,6 +19,27 @@ import resilient_struct indirect case Trapezoid(Size) } +// The enum payload has fixed layout inside this module, but +// resilient layout outside. Make sure we emit the payload +// size in the metadata. + +public struct Color { + public let r: Int, g: Int, b: Int + + public init(r: Int, g: Int, b: Int) { + self.r = r + self.g = g + self.b = b + } +} + +@_fixed_layout public enum CustomColor { + case Black + case White + case Custom(Color) + case Bespoke(Color, Color) +} + // Resilient enum public enum Medium { // Empty cases @@ -29,3 +57,136 @@ public enum Medium { public indirect enum IndirectApproach { case Angle(Double) } + +// Resilient enum with resilient empty payload case +public struct EmptyStruct { + public init() {} +} + +public enum ResilientEnumWithEmptyCase { + case A // should always be case 1 + case B // should always be case 2 + case Empty(EmptyStruct) // should always be case 0 +} + +public func getResilientEnumWithEmptyCase() -> [ResilientEnumWithEmptyCase] { + return [.A, .B, .Empty(EmptyStruct())] +} + +// Specific enum implementations for executable tests +public enum ResilientEmptyEnum { + case X +} + +public enum ResilientSingletonEnum { + case X(AnyObject) +} + +public enum ResilientSingletonGenericEnum { + case X(T) +} + +public enum ResilientNoPayloadEnum { + case A + case B + case C +} + +public enum ResilientSinglePayloadEnum { + case A + case B + case C + case X(AnyObject) +} + +public enum ResilientSinglePayloadGenericEnum { + case A + case B + case C + case X(T) +} + +public class ArtClass { + public init() {} +} + +public enum ResilientMultiPayloadEnum { + case A + case B + case C + case X(Int) + case Y(Int) +} + +public func makeResilientMultiPayloadEnum(n: Int, i: Int) + -> ResilientMultiPayloadEnum { + switch i { + case 0: + return .A + case 1: + return .B + case 2: + return .C + case 3: + return .X(n) + case 4: + return .Y(n) + default: + while true {} + } +} + +public enum ResilientMultiPayloadEnumSpareBits { + case A + case B + case C + case X(ArtClass) + case Y(ArtClass) +} + +public func makeResilientMultiPayloadEnumSpareBits(o: ArtClass, i: Int) + -> ResilientMultiPayloadEnumSpareBits { + switch i { + case 0: + return .A + case 1: + return .B + case 2: + return .C + case 3: + return .X(o) + case 4: + return .Y(o) + default: + while true {} + } +} + +public typealias SevenSpareBits = (Bool, Int8, Int8, Int8, Int8, Int8, Int8, Int8) + +public enum ResilientMultiPayloadEnumSpareBitsAndExtraBits { + // On 64-bit little endian, 7 spare bits at the LSB end + case P1(SevenSpareBits) + // On 64-bit, 8 spare bits at the MSB end and 3 at the LSB end + case P2(ArtClass) + case P3(ArtClass) + case P4(ArtClass) + case P5(ArtClass) + case P6(ArtClass) + case P7(ArtClass) + case P8(ArtClass) +} + +public enum ResilientMultiPayloadGenericEnum { + case A + case B + case C + case X(T) + case Y(T) +} + +public enum ResilientIndirectEnum { + case Base + indirect case A(ResilientIndirectEnum) + indirect case B(ResilientIndirectEnum, ResilientIndirectEnum) +} diff --git a/test/Interpreter/FunctionConversion.swift b/test/Interpreter/FunctionConversion.swift index c0dd0b892e3fd..9af96d8fc5010 100644 --- a/test/Interpreter/FunctionConversion.swift +++ b/test/Interpreter/FunctionConversion.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -16,6 +16,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var FunctionConversionTestSuite = TestSuite("FunctionConversion") protocol Quilt { diff --git a/test/Interpreter/Inputs/ObjCClasses/ObjCClasses.h b/test/Interpreter/Inputs/ObjCClasses/ObjCClasses.h index 125a835618738..6c5763db1977c 100644 --- a/test/Interpreter/Inputs/ObjCClasses/ObjCClasses.h +++ b/test/Interpreter/Inputs/ObjCClasses/ObjCClasses.h @@ -6,7 +6,10 @@ /* This class has instance variables which are not apparent in the interface. Subclasses will need to be slid by the ObjC runtime. */ @interface HasHiddenIvars : NSObject -@property NSInteger count; +@property NSInteger x; +@property NSInteger y; +@property NSInteger z; +@property NSInteger t; @end /* This class has a method that doesn't fill in the error properly. */ diff --git a/test/Interpreter/Inputs/ObjCClasses/ObjCClasses.m b/test/Interpreter/Inputs/ObjCClasses/ObjCClasses.m index 692a8e607ca4b..b0c135da9dd68 100644 --- a/test/Interpreter/Inputs/ObjCClasses/ObjCClasses.m +++ b/test/Interpreter/Inputs/ObjCClasses/ObjCClasses.m @@ -1,7 +1,10 @@ #include "ObjCClasses.h" @implementation HasHiddenIvars -@synthesize count; +@synthesize x; +@synthesize y; +@synthesize z; +@synthesize t; @end @implementation NilError diff --git a/test/Interpreter/SDK/Foundation_test.swift b/test/Interpreter/SDK/Foundation_test.swift index 32802620625cb..a933aa9b1cf44 100644 --- a/test/Interpreter/SDK/Foundation_test.swift +++ b/test/Interpreter/SDK/Foundation_test.swift @@ -7,6 +7,14 @@ import Foundation import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + // rdar://problem/18884272 // Make sure that NSObject conforms to NSObjectProtocol. This // particular bug is ridiculously hard to trigger without a complete diff --git a/test/Interpreter/SDK/Reflection_KVO.swift b/test/Interpreter/SDK/Reflection_KVO.swift index 330bfbcca7a27..3004ee014656d 100644 --- a/test/Interpreter/SDK/Reflection_KVO.swift +++ b/test/Interpreter/SDK/Reflection_KVO.swift @@ -40,7 +40,7 @@ let value = ObservedValue() value.amount = 42 let observer = ValueObserver(value: value) // CHECK: updated to 43 -value.amount++ +value.amount += 1 // CHECK: amount: 43 dump(value) diff --git a/test/Interpreter/SDK/archiving_generic_swift_class_renamed.swift b/test/Interpreter/SDK/archiving_generic_swift_class_renamed.swift new file mode 100644 index 0000000000000..44bccb5e74c80 --- /dev/null +++ b/test/Interpreter/SDK/archiving_generic_swift_class_renamed.swift @@ -0,0 +1,213 @@ +// RUN: %target-build-swift -parse %s -F %S/Inputs -Xfrontend -enable-omit-needless-words -Xfrontend -verify + +// REQUIRES: objc_interop +// UNSUPPORTED: OS=tvos +// UNSUPPORTED: OS=watchos + +import Foundation + +final class Foo: NSObject, NSCoding { + var one, two: T + + init(one: T, two: T) { + self.one = one + self.two = two + } + + @objc required convenience init(coder: NSCoder) { + let one = coder.decodeObjectForKey("one") as! T + let two = coder.decodeObjectForKey("two") as! T + self.init(one: one, two: two) + } + + @objc(encodeWithCoder:) func encodeWith(encoder: NSCoder) { + encoder.encode(one, forKey: "one") + encoder.encode(two, forKey: "two") + } +} + +// FIXME: W* macro equivalents should be in the Darwin/Glibc overlay +func WIFEXITED(status: Int32) -> Bool { + return (status & 0o177) == 0 +} +func WEXITSTATUS(status: Int32) -> Int32 { + return (status >> 8) & 0xFF +} + +// FIXME: "environ" should be in the Darwin overlay too +@_silgen_name("_NSGetEnviron") +func _NSGetEnviron() -> UnsafeMutablePointer>> + +var environ: UnsafeMutablePointer> { + return _NSGetEnviron().memory +} + +func driver() { + // Create a pipe to connect the archiver to the unarchiver. + var pipes: [Int32] = [0, 0] + guard pipe(&pipes) == 0 else { fatalError("pipe failed") } + + let pipeRead = pipes[0], pipeWrite = pipes[1] + + var archiver: pid_t = 0, unarchiver: pid_t = 0 + + let envp = environ + + do { + // Set up the archiver's stdout to feed into our pipe. + var archiverActions = posix_spawn_file_actions_t() + guard posix_spawn_file_actions_init(&archiverActions) == 0 else { + fatalError("posix_spawn_file_actions_init failed") + } + defer { posix_spawn_file_actions_destroy(&archiverActions) } + guard posix_spawn_file_actions_adddup2(&archiverActions, + pipeWrite, + STDOUT_FILENO) == 0 + && posix_spawn_file_actions_addclose(&archiverActions, + pipeRead) == 0 + else { + fatalError("posix_spawn_file_actions_add failed") + } + + // Spawn the archiver process. + let archiverArgv: [UnsafeMutablePointer] = [ + Process.unsafeArgv[0], + UnsafeMutablePointer(("-archive" as StaticString).utf8Start), + nil + ] + guard posix_spawn(&archiver, Process.unsafeArgv[0], + &archiverActions, nil, + archiverArgv, envp) == 0 else { + fatalError("posix_spawn failed") + } + } + + do { + // Set up the unarchiver's stdin to read from our pipe. + var unarchiverActions = posix_spawn_file_actions_t() + guard posix_spawn_file_actions_init(&unarchiverActions) == 0 else { + fatalError("posix_spawn_file_actions_init failed") + } + defer { posix_spawn_file_actions_destroy(&unarchiverActions) } + guard posix_spawn_file_actions_adddup2(&unarchiverActions, + pipeRead, + STDIN_FILENO) == 0 + && posix_spawn_file_actions_addclose(&unarchiverActions, + pipeWrite) == 0 + else { + fatalError("posix_spawn_file_actions_add failed") + } + + // Spawn the unarchiver process. + var unarchiver: pid_t = 0 + let unarchiverArgv: [UnsafeMutablePointer] = [ + Process.unsafeArgv[0], + UnsafeMutablePointer(("-unarchive" as StaticString).utf8Start), + nil + ] + guard posix_spawn(&unarchiver, Process.unsafeArgv[0], + &unarchiverActions, nil, + unarchiverArgv, envp) == 0 else { + fatalError("posix_spawn failed") + } + } + + // Wash our hands of the pipe, now that the subprocesses have started. + close(pipeRead) + close(pipeWrite) + + // Wait for the subprocesses to finish. + var waiting: Set = [archiver, unarchiver] + while !waiting.isEmpty { + var status: Int32 = 0 + let pid = wait(&status) + if pid == -1 { + // If the error was EINTR, just wait again. + if errno == EINTR { continue } + // If we have no children to wait for, stop. + if errno == ECHILD { break } + fatalError("wait failed") + } + waiting.remove(pid) + // Ensure the process exited successfully. + guard WIFEXITED(status) && WEXITSTATUS(status) == 0 else { + fatalError("subprocess exited abnormally") + } + } +} + +func archive() { + let data = NSMutableData() + let archiver = NSKeyedArchiver(forWritingWith: data) + archiver.encode(Foo(one: "one", two: "two"), forKey: "strings") + archiver.encode(Foo(one: 1, two: 2), forKey: "numbers") + archiver.finishEncoding() + + // Output the archived data over stdout, which should be piped to stdin + // on the unarchiver process. + while true { + let status = write(STDOUT_FILENO, data.bytes, data.length) + if status == data.length { break } + if errno == EINTR { continue } + fatalError("write failed") + } +} + +func unarchive() { + // FIXME: Pre-instantiate the generic classes that were archived, since + // the ObjC runtime doesn't know how. + NSStringFromClass(Foo.self) + NSStringFromClass(Foo.self) + + // Read in the data from stdin, where the archiver process should have + // written it. + var rawData: [UInt8] = [] + + var buffer = [UInt8](count: 4096, repeatedValue: 0) + + while true { + let count = read(STDIN_FILENO, &buffer, 4096) + if count == 0 { break } + if count == -1 { + if errno == EINTR { continue } + fatalError("read failed") + } + rawData += buffer[0.. else { + fatalError("unable to unarchive Foo") + } + guard let numbers + = unarchiver.decodeObjectForKey("numbers") as? Foo else { + fatalError("unable to unarchive Foo") + } + + // CHECK-LABEL: Foo + // CHECK: one: one + // CHECK: two: two + // CHECK-LABEL: Foo + // CHECK: one: 1 + // CHECK: two: 2 + dump(strings) + dump(numbers) +} + +// Pick a mode based on the command-line arguments. +// The test launches as a "driver" which then respawns itself into reader +// and writer subprocesses. +if Process.arguments.count < 2 { + driver() +} else if Process.arguments[1] == "-archive" { + archive() +} else if Process.arguments[1] == "-unarchive" { + unarchive() +} else { + fatalError("invalid commandline argument") +} + diff --git a/test/Interpreter/SDK/missing_imports_repl.swift b/test/Interpreter/SDK/missing_imports_repl.swift index 8931b6ce11b4c..944f28941293f 100644 --- a/test/Interpreter/SDK/missing_imports_repl.swift +++ b/test/Interpreter/SDK/missing_imports_repl.swift @@ -15,10 +15,10 @@ import MapKit let x = MKMapRectMake(0.0, 1.0, 2.0, 3.0) // CHECK-NEXT: x : MKMapRect -import Nonexistant_Module_Name -// CHECK-ERROR: error: no such module 'Nonexistant_Module_Name' +import Nonexistent_Module_Name +// CHECK-ERROR: error: no such module 'Nonexistent_Module_Name' -import SpriteKit.Nonexistant_Submodule +import SpriteKit.Nonexistent_Submodule // CHECK-ERROR: error: no such module SKScene() diff --git a/test/Interpreter/SDK/objc_cast.swift b/test/Interpreter/SDK/objc_cast.swift index f65415883d0df..e05790f5c4ba3 100644 --- a/test/Interpreter/SDK/objc_cast.swift +++ b/test/Interpreter/SDK/objc_cast.swift @@ -341,7 +341,7 @@ if let strArr = obj as? [NSString] { // CHECK-NEXT: Object-to-bridged-array cast failed due to bridge mismatch if let strArr = obj as? [Int] { - print("Object-to-bridged-array cast should not have succedded") + print("Object-to-bridged-array cast should not have succeeded") } else { print("Object-to-bridged-array cast failed due to bridge mismatch") } @@ -376,7 +376,7 @@ if let strArr = objOpt as? [NSString] { // CHECK: Object-to-bridged-array cast failed due to bridge mismatch if let intArr = objOpt as? [Int] { - print("Object-to-bridged-array cast should not have succedded") + print("Object-to-bridged-array cast should not have succeeded") } else { print("Object-to-bridged-array cast failed due to bridge mismatch") } @@ -412,7 +412,7 @@ if let strArr = objImplicitOpt as? [NSString] { // CHECK: Object-to-bridged-array cast failed due to bridge mismatch if let intArr = objImplicitOpt as? [Int] { - print("Object-to-bridged-array cast should not have succedded") + print("Object-to-bridged-array cast should not have succeeded") } else { print("Object-to-bridged-array cast failed due to bridge mismatch") } @@ -426,16 +426,18 @@ if let strArr = objImplicitOpt as? [String] { } // Casting an array of numbers to different numbers. -// CHECK: Numbers-as-doubles cast produces [3.14159, 2.71828, 0.0] -obj = ([3.14159, 2.71828, 0] as [Double]) as AnyObject +// CHECK: Numbers-as-doubles cast produces [3.9375, 2.71828, 0.0] +obj = ([3.9375, 2.71828, 0] as [Double]) as AnyObject if let doubleArr = obj as? [Double] { + print(sizeof(Double.self)) print("Numbers-as-doubles cast produces \(doubleArr)") } else { print("Numbers-as-doubles failed") } -// CHECK: Numbers-as-floats cast produces [3.14159{{.*}}, 2.71828{{.*}}, 0.0] +// CHECK: Numbers-as-floats cast produces [3.9375, 2.71828{{.*}}, 0.0] if let floatArr = obj as? [Float] { + print(sizeof(Float.self)) print("Numbers-as-floats cast produces \(floatArr)") } else { print("Numbers-as-floats failed") diff --git a/test/Interpreter/SDK/objc_implicit_unwrapped_bridge.swift b/test/Interpreter/SDK/objc_implicit_unwrapped_bridge.swift index 7b25689de11bd..62516aff9225c 100644 --- a/test/Interpreter/SDK/objc_implicit_unwrapped_bridge.swift +++ b/test/Interpreter/SDK/objc_implicit_unwrapped_bridge.swift @@ -13,11 +13,11 @@ class X { init(value: Int) { self.value = value - ++activeXObjects + activeXObjects += 1 } deinit { - --activeXObjects + activeXObjects -= 1 } } diff --git a/test/Interpreter/availability_weak_linking.swift b/test/Interpreter/availability_weak_linking.swift index cd09c11baa6e4..f02dd348d5850 100644 --- a/test/Interpreter/availability_weak_linking.swift +++ b/test/Interpreter/availability_weak_linking.swift @@ -8,7 +8,7 @@ // These tests emulate deploying back to an older OS where newer APIs are not // available by linking to an Objective-C framework where APIs have been // annotated to only be available in the far future (version 1066.0 of all -// platforms) and then moving the famework aside so that it can't be found +// platforms) and then moving the framework aside so that it can't be found // at run time. // RUN: mv %t/FakeUnavailableObjCFramework.framework %t/FakeUnavailableObjCFramework-MovedAside.framework @@ -114,7 +114,7 @@ func useUnavailableObjCClass() { o.someMethod() } - for var i = 0; i < getInt(5); ++i { + for var i = 0; i < getInt(5); i += 1 { if #available(OSX 1066.0, iOS 1066.0, watchOS 1066.0, tvOS 1066.0, *) { let o: UnavailableObjCClass = printClassMetadataViaGeneric() _blackHole(o) @@ -124,14 +124,14 @@ func useUnavailableObjCClass() { class SomeClass { } let someObject: AnyObject = _opaqueIdentity(SomeClass() as AnyObject) - for var i = 0; i < getInt(5); ++i { + for var i = 0; i < getInt(5); i += 1 { if #available(OSX 1066.0, iOS 1066.0, watchOS 1066.0, tvOS 1066.0, *) { let isUnavailable = someObject is UnavailableObjCClass _blackHole(isUnavailable) } } - for var i = 0; i < getInt(5); ++i { + for var i = 0; i < getInt(5); i += 1 { if #available(OSX 1066.0, iOS 1066.0, watchOS 1066.0, tvOS 1066.0, *) { let asUnavailable = someObject as? UnavailableObjCClass _blackHole(asUnavailable) diff --git a/test/Interpreter/break_continue.swift b/test/Interpreter/break_continue.swift index 930b09b704b48..8643f13aeff59 100644 --- a/test/Interpreter/break_continue.swift +++ b/test/Interpreter/break_continue.swift @@ -4,7 +4,7 @@ func test1() { print("test1") var i : Int - for i=0;;++i { + for i=0;;i += 1 { if i > 2 { break } @@ -15,7 +15,7 @@ func test1() { func test2() { print("test2") var i : Int - for i=0;i<10;++i { + for i=0;i<10;i += 1 { if i > 2 { continue } @@ -25,7 +25,7 @@ func test2() { func test3() { print("test3") var i : Int - for i=0;i<10;++i { + for i=0;i<10;i += 1 { if i > 2 { break } @@ -57,7 +57,7 @@ func test6() { while (i < 10) { if i < 2 { print(i) - ++i + i += 1 continue } return @@ -78,7 +78,7 @@ func test7() { func test8() { print("test8") var i : Int - for i=0;;++i { + for i=0;;i += 1 { for j in 0..<10 { if j > 1 { break diff --git a/test/Interpreter/c_bitfields.swift b/test/Interpreter/c_bitfields.swift index 7e6ed373bd5b1..4d8e571236252 100644 --- a/test/Interpreter/c_bitfields.swift +++ b/test/Interpreter/c_bitfields.swift @@ -5,6 +5,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import ctypes var BitfieldTestSuite = TestSuite("Bitfields") diff --git a/test/Interpreter/c_unions.swift b/test/Interpreter/c_unions.swift index 366fb47de5936..ca06d6cf9276a 100644 --- a/test/Interpreter/c_unions.swift +++ b/test/Interpreter/c_unions.swift @@ -5,6 +5,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import ctypes var UnionTestSuite = TestSuite("Unions") diff --git a/test/Interpreter/class_resilience.swift b/test/Interpreter/class_resilience.swift new file mode 100644 index 0000000000000..ef2557782eade --- /dev/null +++ b/test/Interpreter/class_resilience.swift @@ -0,0 +1,224 @@ +// RUN: rm -rf %t && mkdir %t + +// RUN: %target-build-swift -emit-library -Xfrontend -enable-resilience -c %S/../Inputs/resilient_struct.swift -o %t/resilient_struct.o +// RUN: %target-build-swift -emit-module -Xfrontend -enable-resilience -c %S/../Inputs/resilient_struct.swift -o %t/resilient_struct.o + +// RUN: %target-build-swift -emit-library -Xfrontend -enable-resilience -c %S/../Inputs/resilient_class.swift -I %t/ -o %t/resilient_class.o +// RUN: %target-build-swift -emit-module -Xfrontend -enable-resilience -c %S/../Inputs/resilient_class.swift -I %t/ -o %t/resilient_class.o + +// RUN: %target-build-swift %s -Xlinker %t/resilient_struct.o -Xlinker %t/resilient_class.o -I %t -L %t -o %t/main + +// RUN: %target-run %t/main + +import StdlibUnittest +import resilient_class +import resilient_struct + +var ResilientClassTestSuite = TestSuite("ResilientClass") + +// Concrete class with resilient stored property + +public class ClassWithResilientProperty { + public let p: Point + public let s: Size + public let color: Int32 + + public init(p: Point, s: Size, color: Int32) { + self.p = p + self.s = s + self.color = color + } +} + +ResilientClassTestSuite.test("ClassWithResilientProperty") { + let c = ClassWithResilientProperty( + p: Point(x: 10, y: 20), + s: Size(w: 30, h: 40), + color: 50) + + expectEqual(c.p.x, 10) + expectEqual(c.p.y, 20) + expectEqual(c.s.w, 30) + expectEqual(c.s.h, 40) + expectEqual(c.color, 50) +} + + +// Generic class with resilient stored property + +public class GenericClassWithResilientProperty { + public let s1: Size + public let t: T + public let s2: Size + + public init(s1: Size, t: T, s2: Size) { + self.s1 = s1 + self.t = t + self.s2 = s2 + } +} + +ResilientClassTestSuite.test("GenericClassWithResilientProperty") { + let c = GenericClassWithResilientProperty( + s1: Size(w: 10, h: 20), + t: 30, + s2: Size(w: 40, h: 50)) + + expectEqual(c.s1.w, 10) + expectEqual(c.s1.h, 20) + expectEqual(c.t, 30) + expectEqual(c.s2.w, 40) + expectEqual(c.s2.h, 50) +} + + +// Concrete class with non-fixed size stored property + +public class ClassWithResilientlySizedProperty { + public let r: Rectangle + public let color: Int32 + + public init(r: Rectangle, color: Int32) { + self.r = r + self.color = color + } +} + +ResilientClassTestSuite.test("ClassWithResilientlySizedProperty") { + let c = ClassWithResilientlySizedProperty( + r: Rectangle( + p: Point(x: 10, y: 20), + s: Size(w: 30, h: 40), + color: 50), + color: 60) + + expectEqual(c.r.p.x, 10) + expectEqual(c.r.p.y, 20) + expectEqual(c.r.s.w, 30) + expectEqual(c.r.s.h, 40) + expectEqual(c.r.color, 50) + expectEqual(c.color, 60) +} + + +// Concrete subclass of fixed-layout class with resilient stored property + +public class ChildOfParentWithResilientStoredProperty : ClassWithResilientProperty { + let enabled: Int32 + + public init(p: Point, s: Size, color: Int32, enabled: Int32) { + self.enabled = enabled + super.init(p: p, s: s, color: color) + } +} + +ResilientClassTestSuite.test("ChildOfParentWithResilientStoredProperty") { + let c = ChildOfParentWithResilientStoredProperty( + p: Point(x: 10, y: 20), + s: Size(w: 30, h: 40), + color: 50, + enabled: 60) + + expectEqual(c.p.x, 10) + expectEqual(c.p.y, 20) + expectEqual(c.s.w, 30) + expectEqual(c.s.h, 40) + expectEqual(c.color, 50) + expectEqual(c.enabled, 60) +} + + +// Concrete subclass of fixed-layout class with resilient stored property + +public class ChildOfOutsideParentWithResilientStoredProperty : OutsideParentWithResilientProperty { + let enabled: Int32 + + public init(p: Point, s: Size, color: Int32, enabled: Int32) { + self.enabled = enabled + super.init(p: p, s: s, color: color) + } +} + +ResilientClassTestSuite.test("ChildOfOutsideParentWithResilientStoredProperty") { + let c = ChildOfOutsideParentWithResilientStoredProperty( + p: Point(x: 10, y: 20), + s: Size(w: 30, h: 40), + color: 50, + enabled: 60) + + expectEqual(c.p.x, 10) + expectEqual(c.p.y, 20) + expectEqual(c.s.w, 30) + expectEqual(c.s.h, 40) + expectEqual(c.color, 50) + expectEqual(c.enabled, 60) +} + + +// Resilient class from a different resilience domain + +ResilientClassTestSuite.test("ResilientOutsideParent") { + let c = ResilientOutsideParent() + + expectEqual(c.property, "ResilientOutsideParent.property") + expectEqual(c.finalProperty, "ResilientOutsideParent.finalProperty") +} + + +// FIXME: needs indirect metadata access + +#if false +// Concrete subclass of resilient class + +public class ChildOfResilientOutsideParent : ResilientOutsideParent { + let enabled: Int32 + + public init(enabled: Int32) { + self.enabled = enabled + super.init() + } +} + +ResilientClassTestSuite.test("ChildOfResilientOutsideParent") { + let c = ChildOfResilientOutsideParent(enabled: 60) + + expectEqual(c.property, "ResilientOutsideParent.property") + expectEqual(c.finalProperty, "ResilientOutsideParent.finalProperty") + expectEqual(c.enabled, 60) +} + + +// Concrete subclass of resilient class + +public class ChildOfResilientOutsideParentWithResilientStoredProperty : ResilientOutsideParent { + public let p: Point + public let s: Size + public let color: Int32 + + public init(p: Point, s: Size, color: Int32) { + self.p = p + self.s = s + self.color = color + super.init() + } +} + +ResilientClassTestSuite.test("ChildOfResilientOutsideParentWithResilientStoredProperty") { + let c = ChildOfResilientOutsideParentWithResilientStoredProperty( + p: Point(x: 10, y: 20), + s: Size(w: 30, h: 40), + color: 50) + + expectEqual(c.property, "ResilientOutsideParent.property") + expectEqual(c.finalProperty, "ResilientOutsideParent.finalProperty") + + expectEqual(c.p.x, 10) + expectEqual(c.p.y, 20) + expectEqual(c.s.w, 30) + expectEqual(c.s.h, 40) + expectEqual(c.color, 50) +} +#endif + + +runAllTests() diff --git a/test/Interpreter/closures.swift b/test/Interpreter/closures.swift index c57f0cd805a1b..041983f6edbbd 100644 --- a/test/Interpreter/closures.swift +++ b/test/Interpreter/closures.swift @@ -35,11 +35,11 @@ func test() { test() // -func map(fn: T->()) { +func map(fn: T -> ()) { print("Void overload") } -func map(fn: T->U) { +func map(fn: T -> U) { print("Non-void overload") } diff --git a/test/Interpreter/enum_resilience.swift b/test/Interpreter/enum_resilience.swift new file mode 100644 index 0000000000000..e70c0409ee163 --- /dev/null +++ b/test/Interpreter/enum_resilience.swift @@ -0,0 +1,403 @@ +// RUN: rm -rf %t && mkdir %t + +// RUN: %target-build-swift -emit-library -Xfrontend -enable-resilience -c %S/../Inputs/resilient_struct.swift -o %t/resilient_struct.o +// RUN: %target-build-swift -emit-module -Xfrontend -enable-resilience -c %S/../Inputs/resilient_struct.swift -o %t/resilient_struct.o + +// RUN: %target-build-swift -emit-library -Xfrontend -enable-resilience -c %S/../Inputs/resilient_enum.swift -I %t/ -o %t/resilient_enum.o +// RUN: %target-build-swift -emit-module -Xfrontend -enable-resilience -c %S/../Inputs/resilient_enum.swift -I %t/ -o %t/resilient_enum.o + +// RUN: %target-build-swift %s -Xlinker %t/resilient_struct.o -Xlinker %t/resilient_enum.o -I %t -L %t -o %t/main +// RUN: %target-run %t/main + +import StdlibUnittest +import resilient_enum +import resilient_struct + +var ResilientEnumTestSuite = TestSuite("ResilientEnum") + +ResilientEnumTestSuite.test("ResilientEmptyEnum") { + let e = ResilientEmptyEnum.X + let n: Int + switch e { + case .X: n = 0 + default: n = -1 + } + expectEqual(n, 0) +} + +ResilientEnumTestSuite.test("ResilientSingletonEnum") { + let o: AnyObject = ArtClass() + let e = ResilientSingletonEnum.X(o) + let n: Int + switch e { + case .X(let oo): + n = 0 + expectTrue(o === oo) + default: + n = -1 + } + expectEqual(n, 0) +} + +ResilientEnumTestSuite.test("ResilientSingletonGenericEnum") { + let o = ArtClass() + let e = ResilientSingletonGenericEnum.X(o) + let n: Int + switch e { + case .X(let oo): + n = 0 + expectEqual(o === oo, true) + default: + n = -1 + } + expectEqual(n, 0) +} + +ResilientEnumTestSuite.test("ResilientNoPayloadEnum") { + let a: [ResilientNoPayloadEnum] = [.A, .B, .C] + let b: [Int] = a.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .C: + return 2 + default: + return -1 + } + } + + expectEqual(b, [0, 1, 2]) +} + +ResilientEnumTestSuite.test("ResilientSinglePayloadEnum") { + let o = ArtClass() + let a: [ResilientSinglePayloadEnum] = [.A, .B, .C, .X(o)] + let b: [Int] = a.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .C: + return 2 + case .X(let oo): + expectTrue(o === oo) + return 3 + default: + return -1 + } + } + + expectEqual(b, [0, 1, 2, 3]) +} + +ResilientEnumTestSuite.test("ResilientSinglePayloadGenericEnum") { + let o = ArtClass() + let a: [ResilientSinglePayloadGenericEnum] = [.A, .B, .C, .X(o)] + let b: [Int] = a.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .C: + return 2 + case .X(let oo): + expectTrue(o === oo) + return 3 + default: + return -1 + } + } + + expectEqual(b, [0, 1, 2, 3]) +} + +ResilientEnumTestSuite.test("ResilientMultiPayloadEnum") { + let a: [ResilientMultiPayloadEnum] = + [.A, .B, .C, .X(1), .Y(2)] + let b: [Int] = a.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .C: + return 2 + case .X(let x): + expectEqual(x, 1) + return 3 + case .Y(let y): + expectEqual(y, 2) + return 4 + default: + return -1 + } + } + + expectEqual(b, [0, 1, 2, 3, 4]) +} + +ResilientEnumTestSuite.test("ResilientMultiPayloadEnumRoundTrip") { + let a = [0, 1, 2, 3, 4] + let b = a.map { makeResilientMultiPayloadEnum(1122, i: $0) } + let c: [Int] = b.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .C: + return 2 + case .X(let x): + expectEqual(x, 1122) + return 3 + case .Y(let y): + expectEqual(y, 1122) + return 4 + default: + return -1 + } + } + + expectEqual(c, a) +} + +ResilientEnumTestSuite.test("ResilientMultiPayloadEnumSpareBits") { + let o1 = ArtClass() + let o2 = ArtClass() + let a: [ResilientMultiPayloadEnumSpareBits] = + [.A, .B, .C, .X(o1), .Y(o2)] + let b: [Int] = a.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .C: + return 2 + case .X(let oo1): + expectTrue(oo1 === o1) + return 3 + case .Y(let oo2): + expectTrue(oo2 === o2) + return 4 + default: + return -1 + } + } + + expectEqual(b, [0, 1, 2, 3, 4]) +} + +ResilientEnumTestSuite.test("ResilientMultiPayloadEnumSpareBitsRoundTrip") { + let o = ArtClass() + let a = [0, 1, 2, 3, 4] + let b = a.map { makeResilientMultiPayloadEnumSpareBits(o, i: $0) } + let c: [Int] = b.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .C: + return 2 + case .X(let oo): + expectTrue(oo === o) + return 3 + case .Y(let oo): + expectTrue(oo === o) + return 4 + default: + return -1 + } + } + + expectEqual(c, a) +} + +ResilientEnumTestSuite.test("ResilientMultiPayloadEnumSpareBitsAndExtraBits") { + let o = ArtClass() + let s: SevenSpareBits = (false, 1, 2, 3, 4, 5, 6, 7) + let a: [ResilientMultiPayloadEnumSpareBitsAndExtraBits] + = [.P1(s), .P2(o), .P3(o), .P4(o), .P5(o), .P6(o), .P7(o), .P8(o)] + let b: [Int] = a.map { + switch $0 { + case .P1(let ss): + // FIXME: derive Equatable conformances for arbitrary tuples :-) + expectEqual(ss.0, s.0) + expectEqual(ss.1, s.1) + expectEqual(ss.2, s.2) + expectEqual(ss.3, s.3) + expectEqual(ss.4, s.4) + expectEqual(ss.5, s.5) + expectEqual(ss.6, s.6) + expectEqual(ss.7, s.7) + return 0 + case .P2(let oo): + expectTrue(oo === o) + return 1 + case .P3(let oo): + expectTrue(oo === o) + return 2 + case .P4(let oo): + expectTrue(oo === o) + return 3 + case .P5(let oo): + expectTrue(oo === o) + return 4 + case .P6(let oo): + expectTrue(oo === o) + return 5 + case .P7(let oo): + expectTrue(oo === o) + return 6 + case .P8(let oo): + expectTrue(oo === o) + return 7 + default: + return -1 + } + } + + expectEqual(b, [0, 1, 2, 3, 4, 5, 6, 7]) +} + +ResilientEnumTestSuite.test("ResilientMultiPayloadGenericEnum") { + let o1 = ArtClass() + let o2 = ArtClass() + let a: [ResilientMultiPayloadGenericEnum] = + [.A, .B, .C, .X(o1), .Y(o2)] + let b: [Int] = a.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .C: + return 2 + case .X(let oo1): + expectTrue(oo1 === o1) + return 3 + case .Y(let oo2): + expectTrue(oo2 === o2) + return 4 + default: + return -1 + } + } + + expectEqual(b, [0, 1, 2, 3, 4]) +} + +public func getMetadata() -> Any.Type { + return Shape.self +} + +ResilientEnumTestSuite.test("DynamicLayoutMetatype") { + do { + var output = "" + let expected = "- resilient_enum.Shape #0\n" + dump(getMetadata(), &output) + expectEqual(output, expected) + } + do { + expectEqual(true, getMetadata() == getMetadata()) + } +} + +ResilientEnumTestSuite.test("DynamicLayoutSinglePayload") { + let s = Size(w: 10, h: 20) + let a: [SimpleShape] = [.KleinBottle, .Triangle(s)] + + let b: [Int] = a.map { + switch $0 { + case .KleinBottle: + return 0 + case .Triangle(let s): + expectEqual(s.w, 10) + expectEqual(s.h, 20) + return 1 + } + } + + expectEqual(b, [0, 1]) +} + +ResilientEnumTestSuite.test("DynamicLayoutMultiPayload") { + let s = Size(w: 10, h: 20) + let a: [Shape] = [.Point, .Rect(s), .RoundedRect(s, s)] + + let b: [Int] = a.map { + switch $0 { + case .Point: + return 0 + case .Rect(let s): + expectEqual(s.w, 10) + expectEqual(s.h, 20) + return 1 + case .RoundedRect(let s, let ss): + expectEqual(s.w, 10) + expectEqual(s.h, 20) + expectEqual(ss.w, 10) + expectEqual(ss.h, 20) + return 2 + } + } + + expectEqual(b, [0, 1, 2]) +} + +ResilientEnumTestSuite.test("DynamicLayoutMultiPayload2") { + let c = Color(r: 1, g: 2, b: 3) + let a: [CustomColor] = [.Black, .White, .Custom(c), .Bespoke(c, c)] + + let b: [Int] = a.map { + switch $0 { + case .Black: + return 0 + case .White: + return 1 + case .Custom(let c): + expectEqual(c.r, 1) + expectEqual(c.g, 2) + expectEqual(c.b, 3) + return 2 + case .Bespoke(let c, let cc): + expectEqual(c.r, 1) + expectEqual(c.g, 2) + expectEqual(c.b, 3) + expectEqual(cc.r, 1) + expectEqual(cc.g, 2) + expectEqual(cc.b, 3) + return 3 + } + } + + expectEqual(b, [0, 1, 2, 3]) +} + +// Make sure case numbers round-trip if payload has zero size + +ResilientEnumTestSuite.test("ResilientEnumWithEmptyCase") { + let a: [ResilientEnumWithEmptyCase] = getResilientEnumWithEmptyCase() + + let b: [Int] = a.map { + switch $0 { + case .A: + return 0 + case .B: + return 1 + case .Empty: + return 2 + default: + return -1 + } + } + + expectEqual(b, [0, 1, 2]) +} + +runAllTests() diff --git a/test/Interpreter/failable_initializers.swift b/test/Interpreter/failable_initializers.swift index f6667c01e5f9d..181f7e50ee049 100644 --- a/test/Interpreter/failable_initializers.swift +++ b/test/Interpreter/failable_initializers.swift @@ -3,17 +3,25 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var FailableInitTestSuite = TestSuite("FailableInit") class Canary { static var count: Int = 0 init() { - Canary.count++ + Canary.count += 1 } deinit { - Canary.count-- + Canary.count -= 1 } } diff --git a/test/Interpreter/formal_access.swift b/test/Interpreter/formal_access.swift index 1ca67b250eb2f..59257b48ad2bd 100644 --- a/test/Interpreter/formal_access.swift +++ b/test/Interpreter/formal_access.swift @@ -44,7 +44,7 @@ func doit(inout local: C) { // CHECK-NEXT: 5. global[0] == 2 // This assignment structurally changes 'global' while a - // simultaneous modification is occuring to it. This is + // simultaneous modification is occurring to it. This is // allowed to have unspecified behavior but not to crash. global.append(C(3)) print("6. local == \(local)") diff --git a/test/Interpreter/fractal.swift b/test/Interpreter/fractal.swift index fb487b24643ba..c59cc368ea656 100644 --- a/test/Interpreter/fractal.swift +++ b/test/Interpreter/fractal.swift @@ -35,7 +35,7 @@ func getMandelbrotIterations(c: Complex, maxIterations: Int) -> Int { var z = Complex() while (n < maxIterations && z.magnitude() < 4.0) { z = z*z + c - ++n + n += 1 } return n } @@ -111,7 +111,7 @@ func getBurningShipIterations(c: Complex, maxIterations: Int) -> Int { while (n < maxIterations && z.magnitude() < 4.0) { var zTmp = Complex(real: z.real.abs(), imag: z.imag.abs()) z = zTmp*zTmp + c - ++n + n += 1 } return n } diff --git a/test/Interpreter/generic_class.swift b/test/Interpreter/generic_class.swift index 19815db267807..57512e7c06a69 100644 --- a/test/Interpreter/generic_class.swift +++ b/test/Interpreter/generic_class.swift @@ -187,3 +187,50 @@ var u = MoreConcreteQuadruple(10, 17, State.CA, "Hella") // CHECK: 10 17 printConcretePair(u) + +class RootGenericFixedLayout { + let a: [T] + let b: Int + + init(a: [T], b: Int) { + self.a = a + self.b = b + } +} + +func checkRootGenericFixedLayout(r: RootGenericFixedLayout) { + print(r.a) + print(r.b) +} + +let rg = RootGenericFixedLayout(a: [1, 2, 3], b: 4) + +// CHECK: [1, 2, 3] +// CHECK: 4 +checkRootGenericFixedLayout(rg) + +class GenericInheritsGenericFixedLayout : RootGenericFixedLayout { + let c: Int + + init(a: [T], b: Int, c: Int) { + self.c = c + super.init(a: a, b: b) + } +} + +let gg = GenericInheritsGenericFixedLayout(a: [1, 2, 3], b: 4, c: 5) + +func checkGenericInheritsGenericFixedLayout(g: GenericInheritsGenericFixedLayout) { + print(g.a) + print(g.b) + print(g.c) +} + +// CHECK: [1, 2, 3] +// CHECK: 4 +checkRootGenericFixedLayout(gg) + +// CHECK: [1, 2, 3] +// CHECK: 4 +// CHECK: 5 +checkGenericInheritsGenericFixedLayout(gg) diff --git a/test/Interpreter/generic_objc_subclass.swift b/test/Interpreter/generic_objc_subclass.swift index 11740be8e97f3..d3aa42adbbceb 100644 --- a/test/Interpreter/generic_objc_subclass.swift +++ b/test/Interpreter/generic_objc_subclass.swift @@ -4,11 +4,9 @@ // RUN: %target-clang -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o // RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ -Xlinker %t/ObjCClasses.o %s -o %t/a.out // RUN: %target-run %t/a.out | FileCheck %s -// REQUIRES: executable_test - -// XFAIL: linux -// rdar://19583881 +// REQUIRES: executable_test +// REQUIRES: objc_interop import Foundation import ObjCClasses @@ -18,9 +16,9 @@ import ObjCClasses } class A : HasHiddenIvars, P { - var x: Int = 16 - var t: T? = nil - var y: Int = 61 + var first: Int = 16 + var second: T? = nil + var third: Int = 61 override var description: String { return "Grilled artichokes" @@ -38,68 +36,38 @@ let a = A() print(a.description) print((a as NSObject).description) -// CHECK: 0 -// CHECK: 16 -// CHECK: nil -// CHECK: 61 -print(a.count) -print(a.x) -print(a.t) -print(a.y) - -// CHECK: 25 -// CHECK: 16 -// CHECK: nil -// CHECK: 61 -a.count = 25 -print(a.count) -print(a.x) -print(a.t) -print(a.y) - -// CHECK: 25 -// CHECK: 36 -// CHECK: nil -// CHECK: 61 +let f = { (a.x, a.y, a.z, a.t, a.first, a.second, a.third) } + +// CHECK: (0, 0, 0, 0, 16, nil, 61) +print(f()) + +// CHECK: (25, 225, 255, 2255, 16, nil, 61) +a.x = 25 +a.y = 225 +a.z = 255 +a.t = 2255 +print(f()) + +// CHECK: (36, 225, 255, 2255, 16, nil, 61) a.x = 36 -print(a.count) -print(a.x) -print(a.t) -print(a.y) - -// CHECK: 25 -// CHECK: 36 -// CHECK: 121 -// CHECK: 61 -a.t = 121 -print(a.count) -print(a.x) -print(a.t) -print(a.y) +print(f()) + +// CHECK: (36, 225, 255, 2255, 16, Optional(121), 61) +a.second = 121 +print(f()) let aa = A<(Int, Int)>() +let ff = { (aa.x, aa.y, aa.z, aa.t, aa.first, aa.second, aa.third) } -// CHECK: 0 -// CHECK: 16 -// CHECK: nil -// CHECK: 61 -print(aa.count) -print(aa.x) -print(aa.t) -print(aa.y) - -aa.count = 101 -aa.t = (19, 84) -aa.y = 17 - -// CHECK: 101 -// CHECK: 16 -// CHECK: (19, 84) -// CHECK: 17 -print(aa.count) -print(aa.x) -print(aa.t) -print(aa.y) +// CHECK: (0, 0, 0, 0, 16, nil, 61) +print(ff()) + +aa.x = 101 +aa.second = (19, 84) +aa.third = 17 + +// CHECK: (101, 0, 0, 0, 16, Optional((19, 84)), 17) +print(ff()) class B : A<(Int, Int)> { override var description: String { @@ -111,6 +79,8 @@ class B : A<(Int, Int)> { } } +class BB : B {} + class C : A<(Int, Int)> { @nonobjc override var description: String { return "Invisible Chicken" @@ -121,8 +91,10 @@ class C : A<(Int, Int)> { } } +// CHECK: 400 // CHECK: 400 // CHECK: 650 +print((BB() as P).calculatePrice()) print((B() as P).calculatePrice()) print((C() as P).calculatePrice()) @@ -130,3 +102,86 @@ print((C() as P).calculatePrice()) // CHECK: Grilled artichokes print((B() as NSObject).description) print((C() as NSObject).description) + +let b = B() +let g = { (b.x, b.y, b.z, b.t, b.first, b.second, b.third) } + +// CHECK: (0, 0, 0, 0, 16, nil, 61) +print(g()) + +b.x = 101 +b.second = (19, 84) +b.third = 17 + +// CHECK: (101, 0, 0, 0, 16, Optional((19, 84)), 17) +print(g()) + +class FixedA : HasHiddenIvars, P { + var first: Int = 16 + var second: [T] = [] + var third: Int = 61 + + override var description: String { + return "Grilled artichokes" + } + + func calculatePrice() -> Int { + return 400 + } +} + +let fixedA = FixedA() + +// CHECK: Grilled artichokes +// CHECK: Grilled artichokes +print(fixedA.description) +print((fixedA as NSObject).description) + +let fixedF = { (fixedA.x, fixedA.y, fixedA.z, fixedA.t, fixedA.first, fixedA.second, fixedA.third) } + +// CHECK: (0, 0, 0, 0, 16, [], 61) +print(fixedF()) + +// CHECK: (25, 225, 255, 2255, 16, [], 61) +fixedA.x = 25 +fixedA.y = 225 +fixedA.z = 255 +fixedA.t = 2255 +print(fixedF()) + +// CHECK: (36, 225, 255, 2255, 16, [], 61) +fixedA.x = 36 +print(fixedF()) + +// CHECK: (36, 225, 255, 2255, 16, [121], 61) +fixedA.second = [121] +print(fixedF()) + +class FixedB : FixedA { + override var description: String { + return "Salmon" + } + + override func calculatePrice() -> Int { + return 1675 + } +} + +// CHECK: 675 +print((FixedB() as P).calculatePrice()) + +// CHECK: Salmon +print((FixedB() as NSObject).description) + +let fixedB = FixedB() +let fixedG = { (fixedB.x, fixedB.y, fixedB.z, fixedB.t, fixedB.first, fixedB.second, fixedB.third) } + +// CHECK: (0, 0, 0, 0, 16, [], 61) +print(fixedG()) + +fixedB.x = 101 +fixedB.second = [19, 84] +fixedB.third = 17 + +// CHECK: (101, 0, 0, 0, 16, [19, 84], 17) +print(fixedG()) diff --git a/test/Interpreter/generics.swift b/test/Interpreter/generics.swift index 79186cdcec767..a7253f05be339 100644 --- a/test/Interpreter/generics.swift +++ b/test/Interpreter/generics.swift @@ -93,7 +93,7 @@ func checkOverloadResolution() { } checkOverloadResolution() -class Base { +class Base { var v = 0 required init() {} func map() { @@ -108,7 +108,7 @@ class D1 : Base { } } -func parse()->T { +func parse() -> T { let inst = T() inst.map() return inst diff --git a/test/Interpreter/initializers.swift b/test/Interpreter/initializers.swift index 2810dd215ca66..7650f66d75c25 100644 --- a/test/Interpreter/initializers.swift +++ b/test/Interpreter/initializers.swift @@ -15,17 +15,17 @@ class A { convenience init() { printAtDepth("Starting A.init()") - ++depth + depth += 1 self.init(int:5) - --depth + depth -= 1 printAtDepth("Ending A.init()") } convenience init(int i:Int) { printAtDepth("Starting A.init withInt(\(i))") - ++depth + depth += 1 self.init(int:i, string:"hello") - --depth + depth -= 1 printAtDepth("Ending A.init withInt(\(i))") } @@ -46,18 +46,18 @@ class B : A { convenience override init(int i:Int, string: String) { printAtDepth("Starting B.init withInt(\(i)) string(\(string))") - ++depth + depth += 1 self.init(int: i, string:string, double:3.14159) - --depth + depth -= 1 printAtDepth("Ending B.init withInt(\(i)) string(\(string))") } init(int i:Int, string: String, double:Double) { printAtDepth("Starting B.init withInt(\(i)) string(\(string)) double(\(double))") self.double = double - ++depth + depth += 1 super.init(int: i, string: string) - --depth + depth -= 1 printAtDepth("Ending B.init withInt(\(i)) string(\(string)) double(\(double))") } @@ -69,9 +69,9 @@ class B : A { class C : B { override init(int i:Int, string: String, double: Double) { printAtDepth("Starting C.init withInt(\(i)) string(\(string)) double(\(double))") - ++depth + depth += 1 super.init(int: i, string: string, double: double) - --depth + depth -= 1 printAtDepth("Ending C.init withInt(\(i)) string(\(string)) double(\(double))") } diff --git a/test/Interpreter/mandelbrot.swift b/test/Interpreter/mandelbrot.swift index 9f0c23b225560..400c56f8fd4b8 100644 --- a/test/Interpreter/mandelbrot.swift +++ b/test/Interpreter/mandelbrot.swift @@ -26,7 +26,7 @@ func getMandelbrotIterations(c: Complex, _ maxIterations: Int) -> Int { var z = Complex() while (n < maxIterations && z.magnitude() < 4.0) { z = z*z + c - ++n + n += 1 } return n } diff --git a/test/Interpreter/optional.swift b/test/Interpreter/optional.swift index 7b38c2df6fbe5..531e3a6e196b8 100644 --- a/test/Interpreter/optional.swift +++ b/test/Interpreter/optional.swift @@ -9,7 +9,7 @@ class B : A { } func printA(v: A) { v.printA() } -func printOpt(subprint: T->())(x: T?) { +func printOpt(subprint: T -> ())(x: T?) { switch (x) { case .Some(let y): print(".Some(", terminator: ""); subprint(y); print(")", terminator: "") case .None: print(".None", terminator: "") diff --git a/test/Interpreter/optional_lvalues.swift b/test/Interpreter/optional_lvalues.swift index fe8550ff5c1b3..68a299eccf154 100644 --- a/test/Interpreter/optional_lvalues.swift +++ b/test/Interpreter/optional_lvalues.swift @@ -4,7 +4,7 @@ var x: Int! = 0 x! = 2 print(x) // CHECK: 2 -x!++ +x! += 1 print(x) // CHECK-NEXT: 3 var sequences = ["fibonacci": [1, 1, 2, 3, 0]] diff --git a/test/Interpreter/properties.swift b/test/Interpreter/properties.swift index 35fbdda228826..a0da585882e1e 100644 --- a/test/Interpreter/properties.swift +++ b/test/Interpreter/properties.swift @@ -249,7 +249,7 @@ class r17192398Failure { let x = r17192398Failure() x.testLazy() -// Setting an lazy optional property to nil has a strange behavior (Swift) +// Setting a lazy optional property to nil has a strange behavior (Swift) class r17226384Class { lazy var x : Int? = { print("propertyRun"); return 42 }() } diff --git a/test/Interpreter/protocol_extensions.swift b/test/Interpreter/protocol_extensions.swift index 705f0b55ad36a..fc184176390bd 100644 --- a/test/Interpreter/protocol_extensions.swift +++ b/test/Interpreter/protocol_extensions.swift @@ -6,7 +6,7 @@ extension SequenceType { final var myCount: Int { var result = 0 for _ in self { - ++result + result += 1 } return result } diff --git a/test/Interpreter/struct_resilience.swift b/test/Interpreter/struct_resilience.swift index 844a81189100a..4071b3bafc928 100644 --- a/test/Interpreter/struct_resilience.swift +++ b/test/Interpreter/struct_resilience.swift @@ -57,7 +57,7 @@ struct MyResilientLayoutRuntimeTest { } } -@inline(never) func getMetadata() -> MyResilientLayoutRuntimeTest.Type { +@inline(never) func getMetadata() -> Any.Type { return MyResilientLayoutRuntimeTest.self } diff --git a/test/Interpreter/throwing_initializers.swift b/test/Interpreter/throwing_initializers.swift index 503846f4a4bca..c8a2f706250b7 100644 --- a/test/Interpreter/throwing_initializers.swift +++ b/test/Interpreter/throwing_initializers.swift @@ -3,6 +3,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var ThrowingInitTestSuite = TestSuite("ThrowingInit") enum E : ErrorType { @@ -20,11 +28,11 @@ class Canary { static var count: Int = 0 init() { - Canary.count++ + Canary.count += 1 } deinit { - Canary.count-- + Canary.count -= 1 } } diff --git a/test/LLVMPasses/basic.ll b/test/LLVMPasses/basic.ll index 389570ba2a8a5..16a60223e79fb 100644 --- a/test/LLVMPasses/basic.ll +++ b/test/LLVMPasses/basic.ll @@ -15,7 +15,6 @@ declare void @objc_release(%objc_object*) declare %swift.refcounted* @swift_allocObject(%swift.heapmetadata* , i64, i64) nounwind declare void @swift_release(%swift.refcounted* nocapture) declare void @swift_retain(%swift.refcounted* ) nounwind -declare void @swift_fixLifetime(%swift.refcounted* ) nounwind declare %swift.bridge* @swift_bridgeObjectRetain(%swift.bridge*) declare void @swift_bridgeObjectRelease(%swift.bridge*) declare void @swift_retainUnowned(%swift.refcounted*) @@ -24,6 +23,11 @@ declare void @user(%swift.refcounted *) nounwind declare void @user_objc(%objc_object*) nounwind declare void @unknown_func() +define private void @__swift_fixLifetime(%swift.refcounted*) noinline nounwind { +entry: + ret void +} + ; CHECK-LABEL: @trivial_objc_canonicalization( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[RET0:%.+]] = bitcast i8* %O to %objc_object* @@ -142,7 +146,7 @@ define void @objc_retain_release_opt(%objc_object* %P, i32* %IP) { define void @swift_fixLifetimeTest(%swift.refcounted* %A) { tail call void @swift_retain(%swift.refcounted* %A) call void @user(%swift.refcounted* %A) nounwind - call void @swift_fixLifetime(%swift.refcounted* %A) + call void @__swift_fixLifetime(%swift.refcounted* %A) tail call void @swift_release(%swift.refcounted* %A) nounwind ret void } @@ -183,17 +187,17 @@ define i32 @move_retain_across_load(%swift.refcounted* %A, i32* %ptr) { } ; CHECK-LABEL: @move_retain_but_not_release_across_objc_fix_lifetime -; CHECK: call void @swift_fixLifetime +; CHECK: call void @__swift_fixLifetime ; CHECK-NEXT: tail call void @swift_retain ; CHECK-NEXT: call void @user -; CHECK-NEXT: call void @swift_fixLifetime +; CHECK-NEXT: call void @__swift_fixLifetime ; CHECK-NEXT: call void @swift_release ; CHECK-NEXT: ret define void @move_retain_but_not_release_across_objc_fix_lifetime(%swift.refcounted* %A) { tail call void @swift_retain(%swift.refcounted* %A) - call void @swift_fixLifetime(%swift.refcounted* %A) nounwind + call void @__swift_fixLifetime(%swift.refcounted* %A) nounwind call void @user(%swift.refcounted* %A) nounwind - call void @swift_fixLifetime(%swift.refcounted* %A) nounwind + call void @__swift_fixLifetime(%swift.refcounted* %A) nounwind tail call void @swift_release(%swift.refcounted* %A) nounwind ret void } @@ -230,7 +234,7 @@ define void @dont_optimize_retain_unowned(%swift.refcounted* %A) { %value = bitcast %swift.refcounted* %A to i64** %L1 = load i64*, i64** %value, align 8 - ; Use of a potential garbabe address from a load of %A. + ; Use of a potential garbage address from a load of %A. %L2 = load i64, i64* %L1, align 8 tail call void @swift_release(%swift.refcounted* %A) diff --git a/test/Misc/Inputs/dumped_api.swift b/test/Misc/Inputs/dumped_api.swift new file mode 100644 index 0000000000000..58791d3bb4bf7 --- /dev/null +++ b/test/Misc/Inputs/dumped_api.swift @@ -0,0 +1,55 @@ + +public class _AnyGeneratorBase { +} + +/// An abstract `GeneratorType` base class over `T` elements. +/// +/// Use this as a `Sequence`'s associated `Generator` type when you +/// don't want to expose details of the concrete generator, a subclass. +/// +/// It is an error to create instances of `AnyGenerator` that are not +/// also instances of an `AnyGenerator` subclass. +/// +/// See also: +/// +/// struct AnySequence +/// func anyGenerator(base: G) -> AnyGenerator +/// func anyGenerator(nextImplementation: () -> T?) -> AnyGenerator +public class AnyGenerator : _AnyGeneratorBase, GeneratorType { + /// Initialize the instance. May only be called from a subclass + /// initializer. + override public init() + /// Advance to the next element and return it, or `nil` if no next + /// element exists. + /// + /// Note: subclasses must override this method. + public func next() -> T? +} + +/// Every `GeneratorType` can also be a `SequenceType`. Note that +/// traversing the sequence consumes the generator. +extension AnyGenerator : SequenceType { + /// Returns `self`. + public func generate() -> AnyGenerator +} +/// Return a `GeneratorType` instance that wraps `base` but whose type +/// depends only on the type of `G.Element`. +/// +/// Example: +/// +/// func countStrings() -> AnyGenerator { +/// let lazyStrings = lazy(0..<10).map { String($0) } +/// +/// // This is a really complicated type of no interest to our +/// // clients. +/// let g: MapSequenceGenerator, String> +/// = lazyStrings.generate() +/// return anyGenerator(g) +/// } +public func anyGenerator(base: G) -> AnyGenerator + +public class FooGeneratorBox< + Base: GeneratorType +> : AnyGenerator { + public override func next() -> Base.Element? +} diff --git a/test/Misc/dump_api.swift b/test/Misc/dump_api.swift new file mode 100644 index 0000000000000..bbeec45596651 --- /dev/null +++ b/test/Misc/dump_api.swift @@ -0,0 +1,65 @@ +// RUN: %target-swift-frontend -parse %s -dump-api-path %t.dump +// RUN: diff -du %S/Inputs/dumped_api.swift %t.dump/dump_api.swift + +public class _AnyGeneratorBase {} + +/// An abstract `GeneratorType` base class over `T` elements. +/// +/// Use this as a `Sequence`'s associated `Generator` type when you +/// don't want to expose details of the concrete generator, a subclass. +/// +/// It is an error to create instances of `AnyGenerator` that are not +/// also instances of an `AnyGenerator` subclass. +/// +/// See also: +/// +/// struct AnySequence +/// func anyGenerator(base: G) -> AnyGenerator +/// func anyGenerator(nextImplementation: () -> T?) -> AnyGenerator +public class AnyGenerator : _AnyGeneratorBase, GeneratorType { + /// Initialize the instance. May only be called from a subclass + /// initializer. + override public init() { + super.init() + } + + /// Advance to the next element and return it, or `nil` if no next + /// element exists. + /// + /// Note: subclasses must override this method. + public func next() -> T? {fatalError("abstract")} +} + +/// Every `GeneratorType` can also be a `SequenceType`. Note that +/// traversing the sequence consumes the generator. +extension AnyGenerator : SequenceType { + /// Returns `self`. + public func generate() -> AnyGenerator { return self } +} + +/// Return a `GeneratorType` instance that wraps `base` but whose type +/// depends only on the type of `G.Element`. +/// +/// Example: +/// +/// func countStrings() -> AnyGenerator { +/// let lazyStrings = lazy(0..<10).map { String($0) } +/// +/// // This is a really complicated type of no interest to our +/// // clients. +/// let g: MapSequenceGenerator, String> +/// = lazyStrings.generate() +/// return anyGenerator(g) +/// } +public func anyGenerator(base: G) -> AnyGenerator { + return FooGeneratorBox(base) +} + +public class FooGeneratorBox< + Base: GeneratorType +> : AnyGenerator { + init(_ base: Base) { self.base = base } + public override func next() -> Base.Element? { return base.next() } + var base: Base +} + diff --git a/test/Misc/misc_diagnostics.swift b/test/Misc/misc_diagnostics.swift index f8a97ed0385bd..582b88370193b 100644 --- a/test/Misc/misc_diagnostics.swift +++ b/test/Misc/misc_diagnostics.swift @@ -111,11 +111,9 @@ func test17875634() { match += coord // expected-error{{binary operator '+=' cannot be applied to operands of type '[(Int, Int)]' and '(Int, Int)'}} // expected-note @-1 {{overloads for '+=' exist with these partially matching parameter lists:}} - match.append(row, col) // expected-error{{cannot invoke 'append' with an argument list of type '(Int, Int)'}} - // expected-note @-1 {{expected an argument list of type '(Int, Int)'}} + match.append(row, col) // expected-error{{extra argument in call}} - match.append(1, 2) // expected-error{{cannot invoke 'append' with an argument list of type '(Int, Int)'}} - // expected-note @-1 {{expected an argument list of type '(Int, Int)'}} + match.append(1, 2) // expected-error{{extra argument in call}} match.append(coord) match.append((1, 2)) diff --git a/test/Misc/single_expr_closure_conversion.swift b/test/Misc/single_expr_closure_conversion.swift index 06ee8a03c9c56..3960180c1db3f 100644 --- a/test/Misc/single_expr_closure_conversion.swift +++ b/test/Misc/single_expr_closure_conversion.swift @@ -32,7 +32,7 @@ withBlob { stmt.bind(["1": 1, "2": 2.0, "3": "3", "4": $0]) } // // We shouldn't crash on the call to 'a.dispatch' below. class A { - func dispatch(f : ()-> Void) { + func dispatch(f : () -> Void) { f() } } @@ -44,4 +44,4 @@ class C { func act() { a.dispatch({() -> Void in self.prop}) } -} \ No newline at end of file +} diff --git a/test/NameBinding/Inputs/reference-dependencies-helper.swift b/test/NameBinding/Inputs/reference-dependencies-helper.swift index 1ad2f6f535159..7dd29b1637c9d 100644 --- a/test/NameBinding/Inputs/reference-dependencies-helper.swift +++ b/test/NameBinding/Inputs/reference-dependencies-helper.swift @@ -130,3 +130,9 @@ protocol PrivateProto3 {} struct OtherFileElementType {} struct OtherFileTypeToBeExtended {} + +struct TypeReferencedOnlyBySubscript {} +struct TypeReferencedOnlyByPrivateSubscript {} + +protocol ProtoReferencedOnlyInGeneric {} +protocol ProtoReferencedOnlyInPrivateGeneric {} diff --git a/test/NameBinding/name_lookup.swift b/test/NameBinding/name_lookup.swift index 229581f3c3235..f395a8038e39e 100644 --- a/test/NameBinding/name_lookup.swift +++ b/test/NameBinding/name_lookup.swift @@ -223,11 +223,11 @@ class ThisDerived1 : ThisBase1 { self.baseInstanceVar = 42 // expected-error {{member 'baseInstanceVar' cannot be used on type 'ThisDerived1'}} self.baseProp = 42 // expected-error {{member 'baseProp' cannot be used on type 'ThisDerived1'}} self.baseFunc0() // expected-error {{missing argument}} - self.baseFunc0(ThisBase1())() // expected-error {{'(ThisBase1) -> _' is not convertible to 'ThisDerived1 -> () -> ()'}} + self.baseFunc0(ThisBase1())() // expected-error {{'(ThisBase1) -> () -> ()' is not convertible to 'ThisDerived1 -> () -> ()'}} self.baseFunc0(ThisDerived1())() self.baseFunc1(42) // expected-error {{cannot convert value of type 'Int' to expected argument type 'ThisBase1'}} - self.baseFunc1(ThisBase1())(42) // expected-error {{'(ThisBase1) -> _' is not convertible to 'ThisDerived1 -> (Int) -> ()'}} + self.baseFunc1(ThisBase1())(42) // expected-error {{'(ThisBase1) -> (Int) -> ()' is not convertible to 'ThisDerived1 -> (Int) -> ()'}} self.baseFunc1(ThisDerived1())(42) self[0] = 42.0 // expected-error {{instance member 'subscript' cannot be used on type 'ThisDerived1'}} self.baseStaticVar = 42 diff --git a/test/NameBinding/reference-dependencies-dynamic-lookup.swift b/test/NameBinding/reference-dependencies-dynamic-lookup.swift index 3807c0e677465..bcc5321e27108 100644 --- a/test/NameBinding/reference-dependencies-dynamic-lookup.swift +++ b/test/NameBinding/reference-dependencies-dynamic-lookup.swift @@ -53,7 +53,8 @@ func testDynamicLookup(obj: AnyObject) { _ = obj.method(5, withDouble: 5.0) // CHECK-DAG: - !private "subscript" - _ = obj[2] + _ = obj[2] as AnyObject + _ = obj[2] as AnyObject! } // CHECK-DAG: - "counter" diff --git a/test/NameBinding/reference-dependencies.swift b/test/NameBinding/reference-dependencies.swift index af65657d7916d..aae7fbe099daa 100644 --- a/test/NameBinding/reference-dependencies.swift +++ b/test/NameBinding/reference-dependencies.swift @@ -55,6 +55,13 @@ struct IntWrapper: Comparable { var value: Int struct InnerForNoReason {} + + // CHECK-DAG: - "TypeReferencedOnlyBySubscript" + subscript(_: TypeReferencedOnlyBySubscript) -> Void { return () } + + // CHECK-DAG: - "TypeReferencedOnlyByPrivateSubscript" + // FIXME: This should be marked "!private". + private subscript(_: TypeReferencedOnlyByPrivateSubscript) -> Void { return () } } // CHECK-DAG: "IntWrapper" @@ -319,6 +326,11 @@ private struct PrivateTy6 {} // CHECK-DAG: !private "PrivateProto3" extension PrivateTy6 : PrivateProto3 {} +// CHECK-DAG: - "ProtoReferencedOnlyInGeneric" +func genericTest(_: T) {} +// CHECK-DAG: !private "ProtoReferencedOnlyInPrivateGeneric" +private func privateGenericTest(_: T) {} + struct Sentinel1 {} private protocol ExtensionProto {} diff --git a/test/Parse/consecutive_statements.swift b/test/Parse/consecutive_statements.swift index d8802ed77f52e..219acf4ade51f 100644 --- a/test/Parse/consecutive_statements.swift +++ b/test/Parse/consecutive_statements.swift @@ -1,7 +1,7 @@ // RUN: %target-parse-verify-swift func statement_starts() { - var f : Int-> () + var f : Int -> () f = { (x : Int) -> () in } f(0) diff --git a/test/Parse/foreach.swift b/test/Parse/foreach.swift index c204cfd596aa9..4a07f7b875798 100644 --- a/test/Parse/foreach.swift +++ b/test/Parse/foreach.swift @@ -30,10 +30,12 @@ func for_each(r: Range, iir: IntRange) { } // Parse errors - for i r { // expected-error 2{{expected ';' in 'for' statement}} expected-error {{use of unresolved identifier 'i'}} + for i r { // expected-error 2{{expected ';' in 'for' statement}} expected-error {{use of unresolved identifier 'i'}} expected-error {{type 'Range' does not conform to protocol 'BooleanType'}} } for i in r sum = sum + i; // expected-error{{expected '{' to start the body of for-each loop}} for let x in 0..<10 {} // expected-error {{'let' pattern is already in an immutable context}} {{7-11=}} - for var x in 0..<10 {} // expected-error {{Use of 'var' binding here is not allowed}} {{7-11=}} + // FIXME: rdar://problem/23378003 + // This will eventually become an error. + for var x in 0..<10 {} // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{7-11=}} } diff --git a/test/Parse/identifiers.swift b/test/Parse/identifiers.swift index 2ee851fceffca..9c47767262e98 100644 --- a/test/Parse/identifiers.swift +++ b/test/Parse/identifiers.swift @@ -17,7 +17,7 @@ class 你好 { 你好.שלום.வணக்கம்.Γειά.привет() // Identifiers cannot start with combining chars. -_ = .́duh() // expected-error {{an identifier cannot begin with this character}} // expected-error{{expected identifier after '.' expression}} +_ = .́duh() // expected-error {{use of unresolved operator '.́'}} // expected-error{{use of unresolved identifier 'duh'}} // Combining characters can be used within identifiers. func s̈pin̈al_tap̈() {} diff --git a/test/Parse/invalid.swift b/test/Parse/invalid.swift index a15ea2acf1129..89cd99776a8eb 100644 --- a/test/Parse/invalid.swift +++ b/test/Parse/invalid.swift @@ -46,9 +46,8 @@ func test4() { // rdar://problem/18507467 func d(b: String -> () -> T) {} // expected-error {{expected type for function result}} // expected-error @-1 {{expected ',' separator}} {{20-20=,}} -// expected-error @-2 {{type annotation missing in pattern}} -// expected-error @-3 {{expected parameter type following ':'}} -// expected-error @-4 {{expected ',' separator}} +// expected-error @-2 {{expected parameter type following ':'}} +// expected-error @-3 {{expected ',' separator}} // QoI: terrible diagnostic when trying to form a generic protocol diff --git a/test/Parse/line-directive.swift b/test/Parse/line-directive.swift index d2ca8be0aab6b..27939673c8e08 100644 --- a/test/Parse/line-directive.swift +++ b/test/Parse/line-directive.swift @@ -14,7 +14,7 @@ x // expected-error {{parameterless closing #line directive}} #line 1 x.swift // expected-error{{expected filename string literal}} #line 42 "x.swift" -x x ; // should be ignored by expeted_error because it is in a different file +x x ; // should be ignored by expected_error because it is in a different file x #line x diff --git a/test/Parse/matching_patterns.swift b/test/Parse/matching_patterns.swift index 1c0f92d29a1f3..9cc454cfc6b14 100644 --- a/test/Parse/matching_patterns.swift +++ b/test/Parse/matching_patterns.swift @@ -32,9 +32,11 @@ case let (let b): // expected-error {{'let' cannot appear nested inside another print(b) // 'var' patterns (not allowed) -case var a: // expected-error {{Use of 'var' binding here is not allowed}} {{6-9=let}} +// FIXME: rdar://problem/23378003 +// This will eventually be an error. +case var a: // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{6-9=let}} a += 1 -case var let a: // expected-error {{Use of 'var' binding here is not allowed}} {{6-9=let}} +case var let a: // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{6-9=let}} // expected-error@-1 {{'let' cannot appear nested inside another 'var' or 'let' pattern}} print(a, terminator: "") @@ -207,13 +209,13 @@ case let .Payload(x): case let .Payload(name: x): acceptInt(x) acceptString("\(x)") -case let .Payload((name: x)): // expected-error {{label is not allowed on single element tuple pattern}} expected-note {{remove the parentheses to make this a type annotation}} {{19-20=}} {{27-28=}} expected-note {{remove the label to make this a tuple pattern}} {{20-25=}} +case let .Payload((name: x)): acceptInt(x) acceptString("\(x)") -case .Payload(let (name: x)): // expected-error {{label is not allowed on single element tuple pattern}} expected-note {{remove the parentheses to make this a type annotation}} {{19-20=}} {{27-28=}} expected-note {{remove the label to make this a tuple pattern}} {{20-25=}} +case .Payload(let (name: x)): acceptInt(x) acceptString("\(x)") -case .Payload(let (name: x)): // expected-error {{label is not allowed on single element tuple pattern}} expected-note {{remove the parentheses to make this a type annotation}} {{19-20=}} {{27-28=}} expected-note {{remove the label to make this a tuple pattern}} {{20-25=}} +case .Payload(let (name: x)): acceptInt(x) acceptString("\(x)") case .Payload(let x): @@ -354,9 +356,6 @@ case (_?)?: break // Bogus diagnostic "refutable pattern match can fail" -// expected-error @+3 {{label is not allowed on single element tuple pattern}} -// expected-note @+2 {{remove the parentheses to make this a type annotation}} {{5-6=}} {{26-27=}} -// expected-note @+1 {{remove the label to make this a tuple pattern}} {{6-21=}} let (responseObject: Int?) = op1 // expected-error @-1 2 {{expected ',' separator}} {{25-25=,}} {{25-25=,}} // expected-error @-2 {{expected pattern}} diff --git a/test/Parse/objc_enum.swift b/test/Parse/objc_enum.swift index 425d6527b94a3..5031f32442f52 100644 --- a/test/Parse/objc_enum.swift +++ b/test/Parse/objc_enum.swift @@ -8,7 +8,7 @@ case Zim, Zang, Zung } -@objc(EnumRuntimeName) enum RuntimeNamed: Int { // expected-error{{'@objc' enum cannot have a name}} +@objc(EnumRuntimeName) enum RuntimeNamed: Int { case Zim, Zang, Zung } diff --git a/test/Parse/optional_chain_lvalues.swift b/test/Parse/optional_chain_lvalues.swift index a2a80c0945685..ceff09366347c 100644 --- a/test/Parse/optional_chain_lvalues.swift +++ b/test/Parse/optional_chain_lvalues.swift @@ -25,7 +25,7 @@ mutT?.mutateT() immT?.mutateT() // expected-error{{cannot use mutating member on immutable value: 'immT' is a 'let' constant}} mutT?.mutS?.mutateS() mutT?.immS?.mutateS() // expected-error{{cannot use mutating member on immutable value: 'immS' is a 'let' constant}} -mutT?.mutS?.x++ +mutT?.mutS?.x += 1 mutT?.mutS?.y++ // expected-error{{cannot pass immutable value to mutating operator: 'y' is a 'let' constant}} // Prefix operators don't chain diff --git a/test/Parse/recovery.swift b/test/Parse/recovery.swift index e88eeccedba79..9105bc677346c 100644 --- a/test/Parse/recovery.swift +++ b/test/Parse/recovery.swift @@ -26,10 +26,9 @@ class Container { func useContainer() -> () { var a : Container] >, b : Int // expected-error{{expected '>' to complete generic argument list}} expected-note{{to match this opening '<'}} b = 5 // no-warning - a.exists() // expected-warnin + a.exists() } - @xyz class BadAttributes { // expected-error{{unknown attribute 'xyz'}} func exists() -> Bool { return true } } @@ -162,16 +161,16 @@ func missingControllingExprInFor() { } // Ensure that we don't do recovery in the following cases. - for ; ; { + for ; ; { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} } - for { true }(); ; { + for { true }(); ; { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} } - for ; { true }() ; { + for ; { true }() ; { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} } - for acceptsClosure { 42 }; ; { + for acceptsClosure { 42 }; ; { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} } // A trailing closure is not accepted for the condition. @@ -185,7 +184,7 @@ func missingControllingExprInFor() { #if true // compiler crashes on "for{{" // expected-error @+2 {{missing initialization in a 'for' statement}} // expected-note @+1 2 {{to match this opening '{'}} -for{{ +for{{ // expected-error {{expression resolves to an unused function}} #endif // expected-error 2 {{expected '}' at end of closure}} #if true @@ -228,7 +227,7 @@ func missingControllingExprInSwitch() { } switch { // expected-error {{expected expression in 'switch' statement}} - case Int: return // expected-error {{'is' keyword required to pattern match against type name}} {{10-10=is }} expected-warning {{cast from '<>' to unrelated type 'Int' always fails}} + case Int: return // expected-error {{'is' keyword required to pattern match against type name}} {{10-10=is }} case _: return } @@ -349,125 +348,62 @@ struct ErrorTypeInVarDeclFunctionType1 { } struct ErrorTypeInVarDeclArrayType1 { - var v1 : Int[+] // expected-error {{expected expression after unary operator}} expected-error {{expected expression for size of array type}} + var v1 : Int[+] // expected-error {{expected declaration}} expected-error {{consecutive declarations on a line must be separated by ';'}} + // expected-error @-1 {{expected expression after unary operator}} + // expected-error @-2 {{expected expression}} var v2 : Int } struct ErrorTypeInVarDeclArrayType2 { - var v1 : Int[+ // expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}} expected-error {{unary operator cannot be separated from its operand}} {{17-3=}} expected-error {{expected expression for size of array type}} - var v2 : Int + var v1 : Int[+ // expected-error {{unary operator cannot be separated from its operand}} + var v2 : Int // expected-error {{expected expression}} } struct ErrorTypeInVarDeclArrayType3 { - var v1 : Int[ // expected-note {{to match this opening '['}} - // expected-error @-1{{expected expression for size of array type}} - // expected-error @-2{{expected ']' in array type}} - ; - var v2 : Int + var v1 : Int[ + ; // expected-error {{expected expression}} + var v2 : Int } struct ErrorTypeInVarDeclArrayType4 { var v1 : Int[1 // expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}} - // expected-error @-1{{fixed-length arrays are not yet supported}} + } struct ErrorInFunctionSignatureResultArrayType1 { - func foo() -> Int[ { // expected-error {{expected '{' in body of function declaration}} expected-note {{to match this opening '['}} + func foo() -> Int[ { // expected-error {{expected '{' in body of function declaration}} return [0] - } // expected-error {{expected ']' in array type}} + } } struct ErrorInFunctionSignatureResultArrayType2 { func foo() -> Int[0 { // expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}} - // expected-error@-1{{fixed-length arrays are not yet supported}} - return [0] + return [0] // expected-error {{contextual type 'Int' cannot be used with array literal}} } } struct ErrorInFunctionSignatureResultArrayType3 { - func foo() -> Int[0] { // expected-error {{fixed-length arrays are not yet supported}} + func foo() -> Int[0] { // expected-error {{array types are now written with the brackets around the element type}} {{17-17=[}} {{20-21=}} return [0] } } struct ErrorInFunctionSignatureResultArrayType4 { - func foo() -> Int[0_1] { // expected-error {{fixed-length arrays are not yet supported}} + func foo() -> Int[0_1] { // expected-error {{array types are now written with the brackets around the element type}} {{17-17=[}} {{20-21=}} return [0] } } struct ErrorInFunctionSignatureResultArrayType5 { - func foo() -> Int[0b1] { // expected-error {{fixed-length arrays are not yet supported}} - return [0] - } -} - -struct ErrorInFunctionSignatureResultArrayType6 { - func foo() -> Int[0o1] { // expected-error {{fixed-length arrays are not yet supported}} - return [0] - } -} - -struct ErrorInFunctionSignatureResultArrayType7 { - func foo() -> Int[0x1] { // expected-error {{fixed-length arrays are not yet supported}} - return [0] - } -} - -struct ErrorInFunctionSignatureResultArrayType8 { - func foo() -> Int[1.0] { // expected-error {{expected expression for size of array type}} + func foo() -> Int[0b1] { // expected-error {{array types are now written with the brackets around the element type}} {{17-17=[}} {{20-21=}} return [0] } } -struct ErrorInFunctionSignatureResultArrayType9 { - func foo() -> Int["1.0"] { // expected-error {{expected expression for size of array type}} - return [0] - } -} - -struct ErrorInFunctionSignatureResultArrayType10 { - func foo() -> Int[true] { // expected-error {{expected expression for size of array type}} - return [0] - } -} struct ErrorInFunctionSignatureResultArrayType11 { func foo() -> Int[(a){a++}] { // expected-error {{consecutive declarations on a line must be separated by ';'}} {{29-29=;}} expected-error {{expected ']' in array type}} expected-note {{to match this opening '['}} expected-error {{use of unresolved identifier 'a'}} expected-error {{expected declaration}} - // expected-error @-1{{expected expression for size of array type}} - } -} - -struct ErrorInFunctionSignatureResultArrayType12 { - var x = 0 - func foo() -> Int[x++] { // expected-error {{expected expression for size of array type}} - return [0] - } -} - -struct ErrorInFunctionSignatureResultArrayType13 { - var x = 0 - func foo() -> Int[self.x] { // expected-error {{expected expression for size of array type}} - return [0] - } -} - -struct ErrorInFunctionSignatureResultArrayType14 { - func foo() -> Int[true ? 1 : 0] { // expected-error {{expected expression for size of array type}} - return [0] - } -} - -struct ErrorInFunctionSignatureResultArrayType15 { - func foo() -> Int[(1, 2)] { // expected-error {{expected expression for size of array type}} - } -} - -// Note: If we decide to support integer constant expressions, this should pass -struct ErrorInFunctionSignatureResultArrayType16 { - func foo() -> Int[1 && 1] { // expected-error {{expected expression for size of array type}} - return [0] } } @@ -585,13 +521,11 @@ case let (jeb): } // rdar://19605164 -// expected-note@+4{{to match this opening '('}} -// expected-note@+3{{to match this opening '['}} +// expected-note@+3{{to match this opening '('}} // expected-error@+2{{use of undeclared type 'S'}} struct Foo19605164 { func a(s: S[{{g) -> Int {} -// expected-error@+5{{expected parameter type following ':'}} -// expected-error@+4{{expected ']' in array type}} +// expected-error@+4{{expected parameter type following ':'}} // expected-error@+3{{expected ')' in parameter}} // expected-error@+2{{expected ',' separator}} {{3-3=,}} // expected-error@+1{{expected ',' separator}} {{3-3=,}} @@ -680,8 +614,8 @@ class r22240342 { // QoI: Common errors: 'let x= 5' and 'let x =5' could use Fix-its func r22387625() { - let _= 5 // expected-error{{postfix '=' is reserved}} {{8-8= }} - let _ =5 // expected-error{{prefix '=' is reserved}} {{10-10= }} + let _= 5 // expected-error{{'=' must have consistent whitespace on both sides}} {{8-8= }} + let _ =5 // expected-error{{'=' must have consistent whitespace on both sides}} {{10-10= }} } @@ -705,4 +639,15 @@ func test23719432() { &(Int:x) // expected-error {{'&' can only appear immediately in a call argument list}} } +// QoI: terrible recovery when using '·' for an operator +infix operator · { // expected-error {{'·' is considered to be an identifier, not an operator}} + associativity none precedence 150 +} + +// Swift Compiler bug: String subscripts with range should require closing bracket. +func r21712891(s : String) -> String { + let a = s.startIndex.. Int { get }; +} + +struct D1: D { + let foo = { return 42; }; +} +func e() -> Bool { + return false; +} + +import Swift; + +for i in 1..<1000 { + if i % 2 == 1 { + break; + }; +} + +let six = (1..<3).reduce(0, combine: +); + +func lessThanTwo(input: UInt) -> Bool { + switch input { + case 0: return true; + case 1, 2: return true; + default: + return false; + } +} + +enum StarWars { + enum Quality { case 😀; case 🙂; case 😐; case 😏; case 😞 }; + case Ep4; case Ep5; case Ep6 + case Ep1, Ep2; case Ep3; +}; + diff --git a/test/Parse/subscripting.swift b/test/Parse/subscripting.swift index 543ca597facc7..6ace34a87fc52 100644 --- a/test/Parse/subscripting.swift +++ b/test/Parse/subscripting.swift @@ -59,8 +59,7 @@ struct X4 { struct Y1 { var stored: Int - // FIXME: diagnostic spew is horrible here - subscript(_: i, j: Int) -> Int { // expected-error 3{{use of undeclared type 'i'}} + subscript(_: i, j: Int) -> Int { // expected-error {{use of undeclared type 'i'}} get { return stored + j } @@ -127,7 +126,7 @@ struct A4 { } struct A5 { - subscript(i : Int) -> Int // expected-error {{expected '{' for subscripting}} + subscript(i : Int) -> Int // expected-error {{expected '{' in subscript to specify getter and setter implementation}} } struct A6 { @@ -155,7 +154,7 @@ struct A7b { } struct A8 { - subscript(i : Int) -> Int // expected-error{{expected '{' for subscripting}} + subscript(i : Int) -> Int // expected-error{{expected '{' in subscript to specify getter and setter implementation}} get { // expected-error{{expected declaration}} return stored } diff --git a/test/Parse/switch.swift b/test/Parse/switch.swift index b9f8261f3288a..f6711e15b136f 100644 --- a/test/Parse/switch.swift +++ b/test/Parse/switch.swift @@ -216,9 +216,9 @@ case (1, let b): // let bindings // var bindings are not allowed in cases. // FIXME: rdar://problem/23378003 // This will eventually be an error. -case (1, var b): // expected-error {{Use of 'var' binding here is not allowed}} {{10-13=let}} +case (1, var b): // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{10-13=let}} () -case (var a, 2): // expected-error {{Use of 'var' binding here is not allowed}} {{7-10=let}} +case (var a, 2): // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{7-10=let}} () case (let a, 2), (1, let b): // expected-error {{'case' labels with multiple patterns cannot declare variables}} @@ -261,3 +261,11 @@ func enumElementSyntaxOnTuple() { } } +// sr-176 +enum Whatever { case Thing } +func f0(values: [Whatever]) { + switch value { // expected-error {{use of unresolved identifier 'value'}} + case .Thing: // Ok. Don't emit diagnostics about enum case not found in type <>. + break + } +} diff --git a/test/Parse/trailing-semi.swift b/test/Parse/trailing-semi.swift index 6405d48833ab7..110a1738502cb 100644 --- a/test/Parse/trailing-semi.swift +++ b/test/Parse/trailing-semi.swift @@ -14,7 +14,7 @@ struct SpuriousSemi { } class C { - var a : Int = 10; + var a : Int = 10 func b () {}; class func c () {}; } diff --git a/test/Parse/try.swift b/test/Parse/try.swift index 5fc7cb4b7b180..2055367dc641a 100644 --- a/test/Parse/try.swift +++ b/test/Parse/try.swift @@ -92,8 +92,8 @@ func rethrowsDispatchError(handleError: ((ErrorType) throws -> ()), body: () thr // Calling rethrows from rethrows crashes Swift compiler struct r21432429 { - func x(f: () throws ->()) rethrows {} - func y(f: () throws ->()) rethrows { + func x(f: () throws -> ()) rethrows {} + func y(f: () throws -> ()) rethrows { x(f) // expected-error {{call can throw but is not marked with 'try'}} expected-note {{call is to 'rethrows' function, but argument function can throw}} } } diff --git a/test/PlaygroundTransform/placeholder.swift b/test/PlaygroundTransform/placeholder.swift new file mode 100644 index 0000000000000..42e5704e17864 --- /dev/null +++ b/test/PlaygroundTransform/placeholder.swift @@ -0,0 +1,29 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: cp %s %t/main.swift +// RUN: %target-build-swift -Xfrontend -playground -Xfrontend -disable-playground-transform -o %t/main %t/main.swift +// RUN: %target-run %t/main | FileCheck %s +// RUN: ! %target-run %t/main --crash 2>&1 | FileCheck -check-prefix=CRASH-CHECK %s +// REQUIRES: executable_test + +// NOTE: "!" is used above instead of "not --crash" because simctl's exit +// status doesn't reflect whether its child process crashed or not. So "not +// --crash %target-run ..." always fails when testing for the iOS Simulator. +// The more precise solution would be to use a version of 'not' cross-compiled +// for the simulator. + +func f(crash crash: Bool) -> Int { + if crash { + return <#T#> + // CRASH-CHECK: fatal error: attempt to evaluate editor placeholder: file {{.*}}/main.swift, line [[@LINE-1]] + } else { + return 42 + } +} + +if Process.arguments.last == "--crash" { + print("the value is \(f(crash: true))") +} else { + print("the value is \(f(crash: false))") + // CHECK: the value is 42 +} diff --git a/test/PrintAsObjC/blocks.swift b/test/PrintAsObjC/blocks.swift index 9d0a536e2413e..6108689527996 100644 --- a/test/PrintAsObjC/blocks.swift +++ b/test/PrintAsObjC/blocks.swift @@ -15,22 +15,22 @@ typealias MyTuple = (a: Int, b: AnyObject?) typealias MyInt = Int // CHECK-LABEL: @interface Callbacks -// CHECK-NEXT: - (void (^ __nonnull)(void))voidBlocks:(void (^ __nonnull)(void))input; -// CHECK-NEXT: - (void)manyArguments:(void (^ __nonnull)(float, float, double, double))input; -// CHECK-NEXT: - (void)blockTakesBlock:(void (^ __nonnull)(void (^ __nonnull)(void)))input; -// CHECK-NEXT: - (void)blockReturnsBlock:(void (^ __nonnull (^ __nonnull)(void))(void))input; -// CHECK-NEXT: - (void)blockTakesAndReturnsBlock:(uint8_t (^ __nonnull (^ __nonnull)(uint16_t (^ __nonnull)(int16_t)))(int8_t))input; -// CHECK-NEXT: - (void)blockTakesTwoBlocksAndReturnsBlock:(uint8_t (^ __nonnull (^ __nonnull)(uint16_t (^ __nonnull)(int16_t), uint32_t (^ __nonnull)(int32_t)))(int8_t))input; -// CHECK-NEXT: - (void (^ __nullable)(NSObject * __nonnull))returnsBlockWithInput; -// CHECK-NEXT: - (void (^ __nullable)(NSObject * __nonnull))returnsBlockWithParenthesizedInput; -// CHECK-NEXT: - (void (^ __nullable)(NSObject * __nonnull, NSObject * __nonnull))returnsBlockWithTwoInputs; -// CHECK-NEXT: - (void)blockWithTypealias:(NSInteger (^ __nonnull)(NSInteger, id __nullable))input; -// CHECK-NEXT: - (void)blockWithSimpleTypealias:(NSInteger (^ __nonnull)(NSInteger))input; -// CHECK-NEXT: - (NSInteger (* __nonnull)(NSInteger))functionPointers:(NSInteger (* __nonnull)(NSInteger))input; -// CHECK-NEXT: - (void)functionPointerTakesAndReturnsFunctionPointer:(NSInteger (* __nonnull (^ __nonnull (* __nonnull)(NSInteger))(NSInteger))(NSInteger))input; -// CHECK-NEXT: @property (nonatomic, copy) NSInteger (^ __nullable savedBlock)(NSInteger); -// CHECK-NEXT: @property (nonatomic) NSInteger (* __nonnull savedFunctionPointer)(NSInteger); -// CHECK-NEXT: @property (nonatomic) NSInteger (* __nullable savedFunctionPointer2)(NSInteger); +// CHECK-NEXT: - (void (^ _Nonnull)(void))voidBlocks:(void (^ _Nonnull)(void))input; +// CHECK-NEXT: - (void)manyArguments:(void (^ _Nonnull)(float, float, double, double))input; +// CHECK-NEXT: - (void)blockTakesBlock:(void (^ _Nonnull)(void (^ _Nonnull)(void)))input; +// CHECK-NEXT: - (void)blockReturnsBlock:(void (^ _Nonnull (^ _Nonnull)(void))(void))input; +// CHECK-NEXT: - (void)blockTakesAndReturnsBlock:(uint8_t (^ _Nonnull (^ _Nonnull)(uint16_t (^ _Nonnull)(int16_t)))(int8_t))input; +// CHECK-NEXT: - (void)blockTakesTwoBlocksAndReturnsBlock:(uint8_t (^ _Nonnull (^ _Nonnull)(uint16_t (^ _Nonnull)(int16_t), uint32_t (^ _Nonnull)(int32_t)))(int8_t))input; +// CHECK-NEXT: - (void (^ _Nullable)(NSObject * _Nonnull))returnsBlockWithInput; +// CHECK-NEXT: - (void (^ _Nullable)(NSObject * _Nonnull))returnsBlockWithParenthesizedInput; +// CHECK-NEXT: - (void (^ _Nullable)(NSObject * _Nonnull, NSObject * _Nonnull))returnsBlockWithTwoInputs; +// CHECK-NEXT: - (void)blockWithTypealias:(NSInteger (^ _Nonnull)(NSInteger, id _Nullable))input; +// CHECK-NEXT: - (void)blockWithSimpleTypealias:(NSInteger (^ _Nonnull)(NSInteger))input; +// CHECK-NEXT: - (NSInteger (* _Nonnull)(NSInteger))functionPointers:(NSInteger (* _Nonnull)(NSInteger))input; +// CHECK-NEXT: - (void)functionPointerTakesAndReturnsFunctionPointer:(NSInteger (* _Nonnull (^ _Nonnull (* _Nonnull)(NSInteger))(NSInteger))(NSInteger))input; +// CHECK-NEXT: @property (nonatomic, copy) NSInteger (^ _Nullable savedBlock)(NSInteger); +// CHECK-NEXT: @property (nonatomic) NSInteger (* _Nonnull savedFunctionPointer)(NSInteger); +// CHECK-NEXT: @property (nonatomic) NSInteger (* _Nullable savedFunctionPointer2)(NSInteger); // CHECK-NEXT: init // CHECK-NEXT: @end @objc class Callbacks { diff --git a/test/PrintAsObjC/classes.swift b/test/PrintAsObjC/classes.swift index eda482dcbc082..e53cf1f16ad63 100644 --- a/test/PrintAsObjC/classes.swift +++ b/test/PrintAsObjC/classes.swift @@ -43,8 +43,8 @@ import CoreFoundation @objc class B1 : A1 {} // CHECK-LABEL: @interface BridgedTypes -// CHECK-NEXT: - (NSDictionary * __nonnull)dictBridge:(NSDictionary * __nonnull)x; -// CHECK-NEXT: - (NSSet * __nonnull)setBridge:(NSSet * __nonnull)x; +// CHECK-NEXT: - (NSDictionary * _Nonnull)dictBridge:(NSDictionary * _Nonnull)x; +// CHECK-NEXT: - (NSSet * _Nonnull)setBridge:(NSSet * _Nonnull)x; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class BridgedTypes { @@ -60,7 +60,7 @@ import CoreFoundation // CHECK: @class CustomName2; // CHECK-LABEL: SWIFT_CLASS_NAMED("ClassWithCustomName") // CHECK-NEXT: @interface CustomName{{$}} -// CHECK-NEXT: - (void)forwardCustomName:(CustomName2 * __nonnull)_; +// CHECK-NEXT: - (void)forwardCustomName:(CustomName2 * _Nonnull)_; // CHECK-NEXT: init // CHECK-NEXT: @end @objc(CustomName) @@ -84,9 +84,9 @@ class ClassWithCustomNameSub : ClassWithCustomName {} // CHECK-LABEL: @interface ClassWithNSObjectProtocol -// CHECK-NEXT: @property (nonatomic, readonly, copy) NSString * __nonnull description; -// CHECK-NEXT: - (BOOL)conformsToProtocol:(Protocol * __nonnull)_; -// CHECK-NEXT: - (BOOL)isKindOfClass:(Class __nonnull)aClass; +// CHECK-NEXT: @property (nonatomic, readonly, copy) NSString * _Nonnull description; +// CHECK-NEXT: - (BOOL)conformsToProtocol:(Protocol * _Nonnull)_; +// CHECK-NEXT: - (BOOL)isKindOfClass:(Class _Nonnull)aClass; // CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; // CHECK-NEXT: @end @objc class ClassWithNSObjectProtocol : NSObjectProtocol { @@ -99,7 +99,7 @@ class ClassWithCustomNameSub : ClassWithCustomName {} // CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; // CHECK-NEXT: - (nonnull instancetype)initWithInt:(NSInteger)_; // CHECK-NEXT: - (nonnull instancetype)initWithFloat:(float)f; -// CHECK-NEXT: - (nonnull instancetype)initWithString:(NSString * __nonnull)s boolean:(BOOL)b; +// CHECK-NEXT: - (nonnull instancetype)initWithString:(NSString * _Nonnull)s boolean:(BOOL)b; // CHECK-NEXT: - (nullable instancetype)initWithBoolean:(BOOL)b; // CHECK-NEXT: - (nonnull instancetype)initForFun OBJC_DESIGNATED_INITIALIZER; // CHECK-NEXT: @end @@ -122,9 +122,9 @@ class NotObjC {} // CHECK-LABEL: @interface Methods{{$}} // CHECK-NEXT: - (void)test; // CHECK-NEXT: + (void)test2; -// CHECK-NEXT: - (void * __null_unspecified)testPrimitives:(BOOL)b i:(NSInteger)i f:(float)f d:(double)d u:(NSUInteger)u; -// CHECK-NEXT: - (void)testString:(NSString * __nonnull)s; -// CHECK-NEXT: - (void)testSelector:(SEL __null_unspecified)sel boolean:(BOOL)b; +// CHECK-NEXT: - (void * _Null_unspecified)testPrimitives:(BOOL)b i:(NSInteger)i f:(float)f d:(double)d u:(NSUInteger)u; +// CHECK-NEXT: - (void)testString:(NSString * _Nonnull)s; +// CHECK-NEXT: - (void)testSelector:(SEL _Null_unspecified)sel boolean:(BOOL)b; // CHECK-NEXT: - (void)testCSignedTypes:(signed char)a b:(short)b c:(int)c d:(long)d e:(long long)e; // CHECK-NEXT: - (void)testCUnsignedTypes:(unsigned char)a b:(unsigned short)b c:(unsigned int)c d:(unsigned long)d e:(unsigned long long)e; // CHECK-NEXT: - (void)testCChars:(char)basic wchar:(wchar_t)wide char16:(char16_t)char16 char32:(char32_t)char32; @@ -134,26 +134,26 @@ class NotObjC {} // CHECK-NEXT: - (void)testSizedUnsignedTypes:(uint8_t)a b:(uint16_t)b c:(uint32_t)c d:(uint64_t)d; // CHECK-NEXT: - (void)testSizedFloats:(float)a b:(double)b; // CHECK-NEXT: - (nonnull instancetype)getDynamicSelf; -// CHECK-NEXT: + (SWIFT_METATYPE(Methods) __nonnull)getSelf; -// CHECK-NEXT: - (Methods * __nullable)maybeGetSelf; -// CHECK-NEXT: + (SWIFT_METATYPE(Methods) __nullable)maybeGetSelf; -// CHECK-NEXT: - (Methods * __null_unspecified)uncheckedGetSelf; -// CHECK-NEXT: + (SWIFT_METATYPE(Methods) __null_unspecified)uncheckedGetSelf; -// CHECK-NEXT: + (SWIFT_METATYPE(CustomName) __nonnull)getCustomNameType; +// CHECK-NEXT: + (SWIFT_METATYPE(Methods) _Nonnull)getSelf; +// CHECK-NEXT: - (Methods * _Nullable)maybeGetSelf; +// CHECK-NEXT: + (SWIFT_METATYPE(Methods) _Nullable)maybeGetSelf; +// CHECK-NEXT: - (Methods * _Null_unspecified)uncheckedGetSelf; +// CHECK-NEXT: + (SWIFT_METATYPE(Methods) _Null_unspecified)uncheckedGetSelf; +// CHECK-NEXT: + (SWIFT_METATYPE(CustomName) _Nonnull)getCustomNameType; // CHECK-NEXT: - (void)testParens:(NSInteger)a; // CHECK-NEXT: - (void)testIgnoredParam:(NSInteger)_; // CHECK-NEXT: - (void)testIgnoredParams:(NSInteger)_ again:(NSInteger)_; -// CHECK-NEXT: - (void)testArrayBridging:(NSArray * __nonnull)a; -// CHECK-NEXT: - (void)testArrayBridging2:(NSArray * __nonnull)a; -// CHECK-NEXT: - (void)testArrayBridging3:(NSArray * __nonnull)a; -// CHECK-NEXT: - (void)testDictionaryBridging:(NSDictionary * __nonnull)a; -// CHECK-NEXT: - (void)testDictionaryBridging2:(NSDictionary * __nonnull)a; -// CHECK-NEXT: - (void)testDictionaryBridging3:(NSDictionary * __nonnull)a; -// CHECK-NEXT: - (void)testSetBridging:(NSSet * __nonnull)a; -// CHECK-NEXT: - (IBAction)actionMethod:(id __nonnull)_; -// CHECK-NEXT: - (void)methodWithReservedParameterNames:(id __nonnull)long_ protected:(id __nonnull)protected_; -// CHECK-NEXT: - (void)honorRenames:(CustomName * __nonnull)_; -// CHECK-NEXT: - (Methods * __nullable __unsafe_unretained)unmanaged:(id __nonnull __unsafe_unretained)_; +// CHECK-NEXT: - (void)testArrayBridging:(NSArray * _Nonnull)a; +// CHECK-NEXT: - (void)testArrayBridging2:(NSArray * _Nonnull)a; +// CHECK-NEXT: - (void)testArrayBridging3:(NSArray * _Nonnull)a; +// CHECK-NEXT: - (void)testDictionaryBridging:(NSDictionary * _Nonnull)a; +// CHECK-NEXT: - (void)testDictionaryBridging2:(NSDictionary * _Nonnull)a; +// CHECK-NEXT: - (void)testDictionaryBridging3:(NSDictionary * _Nonnull)a; +// CHECK-NEXT: - (void)testSetBridging:(NSSet * _Nonnull)a; +// CHECK-NEXT: - (IBAction)actionMethod:(id _Nonnull)_; +// CHECK-NEXT: - (void)methodWithReservedParameterNames:(id _Nonnull)long_ protected:(id _Nonnull)protected_; +// CHECK-NEXT: - (void)honorRenames:(CustomName * _Nonnull)_; +// CHECK-NEXT: - (Methods * _Nullable __unsafe_unretained)unmanaged:(id _Nonnull __unsafe_unretained)_; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class Methods { @@ -219,13 +219,13 @@ typealias AliasForNSRect = NSRect // CHECK-NEXT: - (NSPoint)getOrigin:(NSRect)r; // CHECK-NEXT: - (CGFloat)getOriginX:(NSRect)r; // CHECK-NEXT: - (CGFloat)getOriginY:(CGRect)r; -// CHECK-NEXT: - (NSArray * __nonnull)emptyArray; -// CHECK-NEXT: - (NSArray * __nullable)maybeArray; +// CHECK-NEXT: - (NSArray * _Nonnull)emptyArray; +// CHECK-NEXT: - (NSArray * _Nullable)maybeArray; // CHECK-NEXT: - (NSRuncingMode)someEnum; -// CHECK-NEXT: - (struct _NSZone * __null_unspecified)zone; -// CHECK-NEXT: - (CFTypeRef __nullable)cf:(CFTreeRef __nonnull)x str:(CFStringRef __nonnull)str str2:(CFMutableStringRef __nonnull)str2 obj:(CFAliasForTypeRef __nonnull)obj; +// CHECK-NEXT: - (struct _NSZone * _Null_unspecified)zone; +// CHECK-NEXT: - (CFTypeRef _Nullable)cf:(CFTreeRef _Nonnull)x str:(CFStringRef _Nonnull)str str2:(CFMutableStringRef _Nonnull)str2 obj:(CFAliasForTypeRef _Nonnull)obj; // CHECK-NEXT: - (void)appKitInImplementation; -// CHECK-NEXT: - (NSURL * __nullable)returnsURL; +// CHECK-NEXT: - (NSURL * _Nullable)returnsURL; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class MethodsWithImports { @@ -250,10 +250,10 @@ typealias AliasForNSRect = NSRect } // CHECK-LABEL: @interface MethodsWithPointers -// CHECK-NEXT: - (id __nonnull * __null_unspecified)test:(NSInteger * __null_unspecified)a; -// CHECK-NEXT: - (void)testNested:(NSInteger * __null_unspecified * __null_unspecified)a; -// CHECK-NEXT: - (void)testBridging:(NSInteger const * __null_unspecified)a b:(NSInteger * __null_unspecified)b c:(Methods * __nonnull * __null_unspecified)c; -// CHECK-NEXT: - (void)testBridgingVoid:(void * __null_unspecified)a b:(void const * __null_unspecified)b; +// CHECK-NEXT: - (id _Nonnull * _Null_unspecified)test:(NSInteger * _Null_unspecified)a; +// CHECK-NEXT: - (void)testNested:(NSInteger * _Null_unspecified * _Null_unspecified)a; +// CHECK-NEXT: - (void)testBridging:(NSInteger const * _Null_unspecified)a b:(NSInteger * _Null_unspecified)b c:(Methods * _Nonnull * _Null_unspecified)c; +// CHECK-NEXT: - (void)testBridgingVoid:(void * _Null_unspecified)a b:(void const * _Null_unspecified)b; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class MethodsWithPointers { @@ -303,14 +303,14 @@ class MyObject : NSObject {} // CHECK-LABEL: @class Inner2; // CHECK-LABEL: @interface NestedMembers -// CHECK-NEXT: @property (nonatomic, strong) Inner2 * __nullable ref2; -// CHECK-NEXT: @property (nonatomic, strong) Inner3 * __nullable ref3; +// CHECK-NEXT: @property (nonatomic, strong) Inner2 * _Nullable ref2; +// CHECK-NEXT: @property (nonatomic, strong) Inner3 * _Nullable ref3; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class NestedMembers { // NEGATIVE-NOT: @class NestedMembers; // CHECK-LABEL: @interface Inner2 - // CHECK-NEXT: @property (nonatomic, strong) NestedMembers * __nullable ref; + // CHECK-NEXT: @property (nonatomic, strong) NestedMembers * _Nullable ref; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class Inner2 { @@ -321,7 +321,7 @@ class MyObject : NSObject {} var ref3: Inner3? = nil // CHECK-LABEL: @interface Inner3 - // CHECK-NEXT: @property (nonatomic, strong) NestedMembers * __nullable ref; + // CHECK-NEXT: @property (nonatomic, strong) NestedMembers * _Nullable ref; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class Inner3 { @@ -355,47 +355,47 @@ public class NonObjCClass { } // CHECK-LABEL: @interface Properties // CHECK-NEXT: @property (nonatomic) NSInteger i; -// CHECK-NEXT: @property (nonatomic, readonly, strong) Properties * __nonnull mySelf; +// CHECK-NEXT: @property (nonatomic, readonly, strong) Properties * _Nonnull mySelf; // CHECK-NEXT: @property (nonatomic, readonly) double pi; // CHECK-NEXT: @property (nonatomic) NSInteger computed; -// CHECK-NEXT: + (Properties * __nonnull)shared; -// CHECK-NEXT: + (void)setShared:(Properties * __nonnull)newValue; -// CHECK-NEXT: @property (nonatomic, weak) Properties * __nullable weakOther; -// CHECK-NEXT: @property (nonatomic, assign) Properties * __nonnull unownedOther; -// CHECK-NEXT: @property (nonatomic, unsafe_unretained) Properties * __nonnull unmanagedOther; -// CHECK-NEXT: @property (nonatomic, unsafe_unretained) Properties * __nullable unmanagedByDecl; -// CHECK-NEXT: @property (nonatomic, weak) id __nullable weakProto; -// CHECK-NEXT: @property (nonatomic) CFTypeRef __nullable weakCF; -// CHECK-NEXT: @property (nonatomic) CFStringRef __nullable weakCFString; -// CHECK-NEXT: @property (nonatomic) CFTypeRef __nullable strongCF; -// CHECK-NEXT: @property (nonatomic) CFTypeRef __nullable strongCFAlias; -// CHECK-NEXT: @property (nonatomic) CFAliasForTypeRef __nullable anyCF; -// CHECK-NEXT: @property (nonatomic) CFAliasForTypeRef __nullable anyCF2; -// CHECK-NEXT: @property (nonatomic, weak) IBOutlet id __null_unspecified outlet; -// CHECK-NEXT: @property (nonatomic, strong) IBOutlet Properties * __null_unspecified typedOutlet; -// CHECK-NEXT: @property (nonatomic, copy) NSString * __nonnull string; -// CHECK-NEXT: @property (nonatomic, copy) NSArray * __nonnull array; -// CHECK-NEXT: @property (nonatomic, copy) NSArray *> * __nonnull arrayOfArrays; -// CHECK-NEXT: @property (nonatomic, copy) NSArray * __nonnull arrayOfBlocks; -// CHECK-NEXT: @property (nonatomic, copy) NSArray *> * __nonnull arrayOfArrayOfBlocks; -// CHECK-NEXT: @property (nonatomic, copy) NSDictionary * __nonnull dictionary; -// CHECK-NEXT: @property (nonatomic, copy) NSDictionary * __nonnull dictStringInt; -// CHECK-NEXT: @property (nonatomic, copy) NSSet * __nonnull stringSet; -// CHECK-NEXT: @property (nonatomic, copy) NSSet * __nonnull intSet; -// CHECK-NEXT: @property (nonatomic, copy) NSArray * __nonnull cgFloatArray; -// CHECK-NEXT: @property (nonatomic, copy) NSArray * __nonnull rangeArray; -// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(Properties) NSArray * __null_unspecified outletCollection; -// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(CustomName) NSArray * __nullable outletCollectionOptional; -// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(id) NSArray * __nullable outletCollectionAnyObject; -// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(id) NSArray> * __nullable outletCollectionProto; +// CHECK-NEXT: + (Properties * _Nonnull)shared; +// CHECK-NEXT: + (void)setShared:(Properties * _Nonnull)newValue; +// CHECK-NEXT: @property (nonatomic, weak) Properties * _Nullable weakOther; +// CHECK-NEXT: @property (nonatomic, assign) Properties * _Nonnull unownedOther; +// CHECK-NEXT: @property (nonatomic, unsafe_unretained) Properties * _Nonnull unmanagedOther; +// CHECK-NEXT: @property (nonatomic, unsafe_unretained) Properties * _Nullable unmanagedByDecl; +// CHECK-NEXT: @property (nonatomic, weak) id _Nullable weakProto; +// CHECK-NEXT: @property (nonatomic) CFTypeRef _Nullable weakCF; +// CHECK-NEXT: @property (nonatomic) CFStringRef _Nullable weakCFString; +// CHECK-NEXT: @property (nonatomic) CFTypeRef _Nullable strongCF; +// CHECK-NEXT: @property (nonatomic) CFTypeRef _Nullable strongCFAlias; +// CHECK-NEXT: @property (nonatomic) CFAliasForTypeRef _Nullable anyCF; +// CHECK-NEXT: @property (nonatomic) CFAliasForTypeRef _Nullable anyCF2; +// CHECK-NEXT: @property (nonatomic, weak) IBOutlet id _Null_unspecified outlet; +// CHECK-NEXT: @property (nonatomic, strong) IBOutlet Properties * _Null_unspecified typedOutlet; +// CHECK-NEXT: @property (nonatomic, copy) NSString * _Nonnull string; +// CHECK-NEXT: @property (nonatomic, copy) NSArray * _Nonnull array; +// CHECK-NEXT: @property (nonatomic, copy) NSArray *> * _Nonnull arrayOfArrays; +// CHECK-NEXT: @property (nonatomic, copy) NSArray * _Nonnull arrayOfBlocks; +// CHECK-NEXT: @property (nonatomic, copy) NSArray *> * _Nonnull arrayOfArrayOfBlocks; +// CHECK-NEXT: @property (nonatomic, copy) NSDictionary * _Nonnull dictionary; +// CHECK-NEXT: @property (nonatomic, copy) NSDictionary * _Nonnull dictStringInt; +// CHECK-NEXT: @property (nonatomic, copy) NSSet * _Nonnull stringSet; +// CHECK-NEXT: @property (nonatomic, copy) NSSet * _Nonnull intSet; +// CHECK-NEXT: @property (nonatomic, copy) NSArray * _Nonnull cgFloatArray; +// CHECK-NEXT: @property (nonatomic, copy) NSArray * _Nonnull rangeArray; +// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(Properties) NSArray * _Null_unspecified outletCollection; +// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(CustomName) NSArray * _Nullable outletCollectionOptional; +// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(id) NSArray * _Nullable outletCollectionAnyObject; +// CHECK-NEXT: @property (nonatomic, copy) IBOutletCollection(id) NSArray> * _Nullable outletCollectionProto; // CHECK-NEXT: + (NSInteger)staticInt; -// CHECK-NEXT: + (NSString * __nonnull)staticString; -// CHECK-NEXT: + (void)setStaticString:(NSString * __nonnull)value; +// CHECK-NEXT: + (NSString * _Nonnull)staticString; +// CHECK-NEXT: + (void)setStaticString:(NSString * _Nonnull)value; // CHECK-NEXT: + (double)staticDouble; -// CHECK-NEXT: @property (nonatomic, strong) Properties * __nullable wobble; +// CHECK-NEXT: @property (nonatomic, strong) Properties * _Nullable wobble; // CHECK-NEXT: @property (nonatomic, getter=isEnabled, setter=setIsEnabled:) BOOL enabled; // CHECK-NEXT: @property (nonatomic, getter=register, setter=setRegister:) BOOL register_; -// CHECK-NEXT: @property (nonatomic, readonly, strong, getter=this) Properties * __nonnull this_; +// CHECK-NEXT: @property (nonatomic, readonly, strong, getter=this) Properties * _Nonnull this_; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class Properties { @@ -473,9 +473,9 @@ public class NonObjCClass { } } // CHECK-LABEL: @interface PropertiesOverridden -// CHECK-NEXT: @property (nonatomic, copy) NSArray * __nonnull bees; +// CHECK-NEXT: @property (nonatomic, copy) NSArray * _Nonnull bees; // CHECK-NEXT: - (null_unspecified instancetype)init -// CHECK-NEXT: - (null_unspecified instancetype)initWithCoder:(NSCoder * __null_unspecified)aDecoder OBJC_DESIGNATED_INITIALIZER; +// CHECK-NEXT: - (null_unspecified instancetype)initWithCoder:(NSCoder * _Null_unspecified)aDecoder OBJC_DESIGNATED_INITIALIZER; // CHECK-NEXT: @end @objc class PropertiesOverridden : Hive { override var bees : [Bee] { @@ -500,8 +500,8 @@ public class NonObjCClass { } // CHECK-LABEL: @interface Subscripts1 -// CHECK-NEXT: - (Subscripts1 * __nonnull)objectAtIndexedSubscript:(NSInteger)i; -// CHECK-NEXT: - (Subscripts1 * __nonnull)objectForKeyedSubscript:(Subscripts1 * __nonnull)o; +// CHECK-NEXT: - (Subscripts1 * _Nonnull)objectAtIndexedSubscript:(NSInteger)i; +// CHECK-NEXT: - (Subscripts1 * _Nonnull)objectForKeyedSubscript:(Subscripts1 * _Nonnull)o; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class Subscripts1 { @@ -515,11 +515,11 @@ public class NonObjCClass { } } // CHECK-LABEL: @interface Subscripts2 -// CHECK-NEXT: - (Subscripts2 * __nonnull)objectAtIndexedSubscript:(int16_t)i; -// CHECK-NEXT: - (void)setObject:(Subscripts2 * __nonnull)newValue atIndexedSubscript:(int16_t)i; -// CHECK-NEXT: - (NSObject * __nonnull)objectForKeyedSubscript:(NSObject * __nonnull)o; -// CHECK-NEXT: - (void)setObject:(NSObject * __nonnull)newValue forKeyedSubscript:(NSObject * __nonnull)o; -// CHECK-NEXT: @property (nonatomic, copy) NSArray * __nonnull cardPaths; +// CHECK-NEXT: - (Subscripts2 * _Nonnull)objectAtIndexedSubscript:(int16_t)i; +// CHECK-NEXT: - (void)setObject:(Subscripts2 * _Nonnull)newValue atIndexedSubscript:(int16_t)i; +// CHECK-NEXT: - (NSObject * _Nonnull)objectForKeyedSubscript:(NSObject * _Nonnull)o; +// CHECK-NEXT: - (void)setObject:(NSObject * _Nonnull)newValue forKeyedSubscript:(NSObject * _Nonnull)o; +// CHECK-NEXT: @property (nonatomic, copy) NSArray * _Nonnull cardPaths; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class Subscripts2 { @@ -546,7 +546,7 @@ public class NonObjCClass { } } // CHECK-LABEL: @interface Subscripts3 -// CHECK-NEXT: - (Subscripts3 * __nonnull)objectAtIndexedSubscript:(unsigned long)_; +// CHECK-NEXT: - (Subscripts3 * _Nonnull)objectAtIndexedSubscript:(unsigned long)_; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class Subscripts3 { @@ -560,13 +560,13 @@ public class NonObjCClass { } } // CHECK-LABEL: @interface Throwing1 -// CHECK-NEXT: - (BOOL)method1AndReturnError:(NSError * __nullable * __null_unspecified)error; -// CHECK-NEXT: - (Throwing1 * __nullable)method2AndReturnError:(NSError * __nullable * __null_unspecified)error; -// CHECK-NEXT: - (NSArray * __nullable)method3:(NSInteger)x error:(NSError * __nullable * __null_unspecified)error; -// CHECK-NEXT: - (nullable instancetype)method4AndReturnError:(NSError * __nullable * __null_unspecified)error; -// CHECK-NEXT: - (nullable instancetype)initAndReturnError:(NSError * __nullable * __null_unspecified)error OBJC_DESIGNATED_INITIALIZER; -// CHECK-NEXT: - (nullable instancetype)initWithString:(NSString * __nonnull)string error:(NSError * __nullable * __null_unspecified)error OBJC_DESIGNATED_INITIALIZER; -// CHECK-NEXT: - (nullable instancetype)initAndReturnError:(NSError * __nullable * __null_unspecified)error fn:(NSInteger (^ __nonnull)(NSInteger))fn OBJC_DESIGNATED_INITIALIZER; +// CHECK-NEXT: - (BOOL)method1AndReturnError:(NSError * _Nullable * _Null_unspecified)error; +// CHECK-NEXT: - (Throwing1 * _Nullable)method2AndReturnError:(NSError * _Nullable * _Null_unspecified)error; +// CHECK-NEXT: - (NSArray * _Nullable)method3:(NSInteger)x error:(NSError * _Nullable * _Null_unspecified)error; +// CHECK-NEXT: - (nullable instancetype)method4AndReturnError:(NSError * _Nullable * _Null_unspecified)error; +// CHECK-NEXT: - (nullable instancetype)initAndReturnError:(NSError * _Nullable * _Null_unspecified)error OBJC_DESIGNATED_INITIALIZER; +// CHECK-NEXT: - (nullable instancetype)initWithString:(NSString * _Nonnull)string error:(NSError * _Nullable * _Null_unspecified)error OBJC_DESIGNATED_INITIALIZER; +// CHECK-NEXT: - (nullable instancetype)initAndReturnError:(NSError * _Nullable * _Null_unspecified)error fn:(NSInteger (^ _Nonnull)(NSInteger))fn OBJC_DESIGNATED_INITIALIZER; // CHECK-NEXT: @end @objc class Throwing1 { func method1() throws { } diff --git a/test/PrintAsObjC/enums.swift b/test/PrintAsObjC/enums.swift index 524a6f0de5d45..45bb5e8c94c3f 100644 --- a/test/PrintAsObjC/enums.swift +++ b/test/PrintAsObjC/enums.swift @@ -26,6 +26,28 @@ import Foundation @objc func acceptPlainEnum(_: NSMalformedEnumMissingTypedef) {} } +// CHECK-LABEL: typedef SWIFT_ENUM_NAMED(NSInteger, ObjcEnumNamed, "EnumNamed") { +// CHECK-NEXT: ObjcEnumNamedA = 0, +// CHECK-NEXT: ObjcEnumNamedB = 1, +// CHECK-NEXT: ObjcEnumNamedC = 2, +// CHECK-NEXT: }; + +@objc(ObjcEnumNamed) enum EnumNamed: Int { + case A, B, C +} + +// CHECK-LABEL: typedef SWIFT_ENUM(NSInteger, EnumWithNamedConstants) { +// CHECK-NEXT: kEnumA SWIFT_COMPILE_NAME("A") = 0, +// CHECK-NEXT: kEnumB SWIFT_COMPILE_NAME("B") = 1, +// CHECK-NEXT: kEnumC SWIFT_COMPILE_NAME("C") = 2, +// CHECK-NEXT: }; + +@objc enum EnumWithNamedConstants: Int { + @objc(kEnumA) case A + @objc(kEnumB) case B + @objc(kEnumC) case C +} + // CHECK-LABEL: typedef SWIFT_ENUM(unsigned int, ExplicitValues) { // CHECK-NEXT: ExplicitValuesZim = 0, // CHECK-NEXT: ExplicitValuesZang = 219, @@ -68,7 +90,7 @@ import Foundation // CHECK-NEXT: SomeErrorTypeBadness = 9001, // CHECK-NEXT: SomeErrorTypeWorseness = 9002, // CHECK-NEXT: }; -// CHECK-NEXT: static NSString * __nonnull const SomeErrorTypeDomain = @"enums.SomeErrorType"; +// CHECK-NEXT: static NSString * _Nonnull const SomeErrorTypeDomain = @"enums.SomeErrorType"; @objc enum SomeErrorType: Int, ErrorType { case Badness = 9001 case Worseness @@ -77,7 +99,7 @@ import Foundation // CHECK-LABEL: typedef SWIFT_ENUM(NSInteger, SomeOtherErrorType) { // CHECK-NEXT: SomeOtherErrorTypeDomain = 0, // CHECK-NEXT: }; -// NEGATIVE-NOT: NSString * __nonnull const SomeOtherErrorTypeDomain +// NEGATIVE-NOT: NSString * _Nonnull const SomeOtherErrorTypeDomain @objc enum SomeOtherErrorType: Int, ErrorType { case Domain // collision! } diff --git a/test/PrintAsObjC/extensions.swift b/test/PrintAsObjC/extensions.swift index d927ad104bd62..fc318d40b2f01 100644 --- a/test/PrintAsObjC/extensions.swift +++ b/test/PrintAsObjC/extensions.swift @@ -98,7 +98,7 @@ extension NSObject {} // CHECK-LABEL: @interface NSString (SWIFT_EXTENSION(extensions)) // CHECK-NEXT: - (void)test; // CHECK-NEXT: + (void)test2; -// CHECK-NEXT: + (NSString * __nullable)fromColor:(NSColor * __nonnull)color; +// CHECK-NEXT: + (NSString * _Nullable)fromColor:(NSColor * _Nonnull)color; // CHECK-NEXT: @end extension NSString { func test() {} diff --git a/test/PrintAsObjC/imports.swift b/test/PrintAsObjC/imports.swift index 4999c2239998b..f8d24f97266c7 100644 --- a/test/PrintAsObjC/imports.swift +++ b/test/PrintAsObjC/imports.swift @@ -25,12 +25,12 @@ import ctypes.bits import Foundation import Base -import Base.ImplicitSub; -import Base.ImplicitSub.ImSub; -import Base.ImplicitSub.ExSub; -import Base.ExplicitSub; -import Base.ExplicitSub.ImSub; -import Base.ExplicitSub.ExSub; +import Base.ImplicitSub +import Base.ImplicitSub.ImSub +import Base.ImplicitSub.ExSub +import Base.ExplicitSub +import Base.ExplicitSub.ImSub +import Base.ExplicitSub.ExSub @objc class Test { let word: DWORD = 0 diff --git a/test/PrintAsObjC/local-types.swift b/test/PrintAsObjC/local-types.swift index 8192ecd935af0..3be84c2750a23 100644 --- a/test/PrintAsObjC/local-types.swift +++ b/test/PrintAsObjC/local-types.swift @@ -33,18 +33,18 @@ class ANonObjCClass {} // CHECK-NEXT: @class ZForwardClass3; // CHECK-LABEL: @interface UseForward -// CHECK-NEXT: - (void)definedAlready:(AFullyDefinedClass * __nonnull)a; -// CHECK-NEXT: - (void)a:(ZForwardClass1 * __nonnull)a; -// CHECK-NEXT: - (ZForwardClass2 * __nonnull)b; -// CHECK-NEXT: - (void)c:(ZForwardAliasClass * __nonnull)c; -// CHECK-NEXT: - (void)d:(id __nonnull)d; -// CHECK-NEXT: - (void)e:(Class __nonnull)e; -// CHECK-NEXT: - (void)e2:(id __nonnull)e; -// CHECK-NEXT: - (void)f:(id __nonnull (^ __nonnull)(id __nonnull, id __nonnull))f; -// CHECK-NEXT: - (void)g:(id __nonnull)g; -// CHECK-NEXT: - (void)i:(id __nonnull)_; -// CHECK-NEXT: @property (nonatomic, readonly, strong) ZForwardClass3 * __nonnull j; -// CHECK-NEXT: @property (nonatomic, readonly) SWIFT_METATYPE(ZForwardClass4) __nonnull k; +// CHECK-NEXT: - (void)definedAlready:(AFullyDefinedClass * _Nonnull)a; +// CHECK-NEXT: - (void)a:(ZForwardClass1 * _Nonnull)a; +// CHECK-NEXT: - (ZForwardClass2 * _Nonnull)b; +// CHECK-NEXT: - (void)c:(ZForwardAliasClass * _Nonnull)c; +// CHECK-NEXT: - (void)d:(id _Nonnull)d; +// CHECK-NEXT: - (void)e:(Class _Nonnull)e; +// CHECK-NEXT: - (void)e2:(id _Nonnull)e; +// CHECK-NEXT: - (void)f:(id _Nonnull (^ _Nonnull)(id _Nonnull, id _Nonnull))f; +// CHECK-NEXT: - (void)g:(id _Nonnull)g; +// CHECK-NEXT: - (void)i:(id _Nonnull)_; +// CHECK-NEXT: @property (nonatomic, readonly, strong) ZForwardClass3 * _Nonnull j; +// CHECK-NEXT: @property (nonatomic, readonly) SWIFT_METATYPE(ZForwardClass4) _Nonnull k; // CHECK-NEXT: init // CHECK-NEXT: @end @@ -72,8 +72,8 @@ class ANonObjCClass {} // CHECK-NOT: @protocol ZForwardProtocol1; // CHECK-LABEL: @interface UseForwardAgain -// CHECK-NEXT: - (void)a:(ZForwardClass1 * __nonnull)a; -// CHECK-NEXT: - (void)b:(id __nonnull)b; +// CHECK-NEXT: - (void)a:(ZForwardClass1 * _Nonnull)a; +// CHECK-NEXT: - (void)b:(id _Nonnull)b; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class UseForwardAgain { @@ -81,13 +81,13 @@ class ANonObjCClass {} func b(b: ZForwardProtocol1) {} } -typealias ZForwardAlias = ZForwardAliasClass; +typealias ZForwardAlias = ZForwardAliasClass @objc class ZForwardAliasClass {} // CHECK-NOT: @class UseForward; // CHECK-LABEL: @interface ZForwardClass1 -// CHECK-NEXT: - (void)circular:(UseForward * __nonnull)a; +// CHECK-NEXT: - (void)circular:(UseForward * _Nonnull)a; // CHECK-NEXT: init // CHECK-NEXT: @end @objc class ZForwardClass1 { diff --git a/test/PrintAsObjC/override.swift b/test/PrintAsObjC/override.swift index 4b0b1377f4410..d2f3c637ef91d 100644 --- a/test/PrintAsObjC/override.swift +++ b/test/PrintAsObjC/override.swift @@ -23,7 +23,7 @@ import OverrideBase class A_Child : Base { // CHECK-NEXT: @property (nonatomic, readonly, getter=getProp) NSUInteger prop; override var prop: Int { return 0 } - // CHECK-NEXT: - (id __nullable)objectAtIndexedSubscript:(NSUInteger)x; + // CHECK-NEXT: - (id _Nullable)objectAtIndexedSubscript:(NSUInteger)x; override subscript(x: Int) -> AnyObject? { return nil } // CHECK-NEXT: - (NSUInteger)foo; @@ -34,10 +34,10 @@ class A_Child : Base { override func foo(x: Int, y: Int) -> Int { return x + y } - // CHECK-NEXT: - (BOOL)doThingAndReturnError:(NSError * __nullable * __null_unspecified)error; + // CHECK-NEXT: - (BOOL)doThingAndReturnError:(NSError * _Nullable * _Null_unspecified)error; override func doThing() throws {} - // CHECK-NEXT: - (BOOL)doAnotherThingWithError:(NSError * __nullable * __null_unspecified)error; + // CHECK-NEXT: - (BOOL)doAnotherThingWithError:(NSError * _Nullable * _Null_unspecified)error; override func doAnotherThing() throws {} // CHECK-NEXT: - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; @@ -47,7 +47,7 @@ class A_Child : Base { class A_Grandchild : A_Child { // CHECK-NEXT: @property (nonatomic, readonly, getter=getProp) NSUInteger prop; override var prop: Int { return 0 } - // CHECK-NEXT: - (id __nullable)objectAtIndexedSubscript:(NSUInteger)x; + // CHECK-NEXT: - (id _Nullable)objectAtIndexedSubscript:(NSUInteger)x; override subscript(x: Int) -> AnyObject? { return nil } // CHECK-NEXT: - (NSUInteger)foo; @@ -73,8 +73,8 @@ class B_GrandchildViaEmpty : B_EmptyChild { set {} } - // CHECK-NEXT: - (id __nullable)objectAtIndexedSubscript:(NSUInteger)x; - // CHECK-NEXT: - (void)setObject:(id __nullable)newValue atIndexedSubscript:(NSUInteger)x; + // CHECK-NEXT: - (id _Nullable)objectAtIndexedSubscript:(NSUInteger)x; + // CHECK-NEXT: - (void)setObject:(id _Nullable)newValue atIndexedSubscript:(NSUInteger)x; override subscript(x: Int) -> AnyObject? { get { return nil } set {} @@ -93,7 +93,7 @@ class B_GrandchildViaEmpty : B_EmptyChild { // The output in this class doesn't yet preserve NSUInteger correctly. // CHECK-LABEL: @interface FixMe : Base class FixMe : Base { - // CHECK-NEXT: - (void)callback:(NSInteger (^ __nullable)(void))fn; + // CHECK-NEXT: - (void)callback:(NSInteger (^ _Nullable)(void))fn; // CLANG: error: conflicting parameter types in declaration of 'callback:' override func callback(fn: (() -> Int)?) {} diff --git a/test/PrintAsObjC/protocols.swift b/test/PrintAsObjC/protocols.swift index a7d7569f92b38..25277dc617207 100644 --- a/test/PrintAsObjC/protocols.swift +++ b/test/PrintAsObjC/protocols.swift @@ -30,7 +30,7 @@ import Foundation // CHECK: @protocol CustomName2; // CHECK-LABEL: SWIFT_PROTOCOL_NAMED("CustomNameType") // CHECK-NEXT: @protocol CustomName{{$}} -// CHECK-NEXT: - (void)forwardCustomName:(id __nonnull)_; +// CHECK-NEXT: - (void)forwardCustomName:(id _Nonnull)_; // CHECK-NEXT: @end @objc(CustomName) protocol CustomNameType { @@ -45,7 +45,7 @@ protocol CustomNameType2 {} // CHECK-LABEL: @protocol Initializers{{$}} // CHECK-NEXT: - (nonnull instancetype)init; -// CHECK-NEXT: - (nonnull instancetype)initWithObject:(id __nonnull)any; +// CHECK-NEXT: - (nonnull instancetype)initWithObject:(id _Nonnull)any; // CHECK-NEXT: @end @objc protocol Initializers { init() @@ -55,11 +55,11 @@ protocol CustomNameType2 {} // CHECK-LABEL: @protocol Methods{{$}} // CHECK-NEXT: - (void)test; // CHECK-NEXT: + (void)test2; -// CHECK-NEXT: - (void)testRawAnyTypes:(id __nonnull)any other:(Class __nonnull)other; -// CHECK-NEXT: - (void)testSingleProtocolTypes:(id __nonnull)a aAgain:(id __nonnull)a2 b:(id __nonnull)b bAgain:(id __nonnull)b2 both:(id __nonnull)both; -// CHECK-NEXT: - (void)testSingleProtocolClassTypes:(Class __nonnull)a aAgain:(Class __nonnull)a2 b:(Class __nonnull)b bAgain:(Class __nonnull)b2 both:(Class __nonnull)both; -// CHECK-NEXT: - (void)testComposition:(id __nonnull)x meta:(Class __nonnull)xClass; -// CHECK-NEXT: - (void)testOptional:(id __nullable)opt meta:(Class __nullable)m; +// CHECK-NEXT: - (void)testRawAnyTypes:(id _Nonnull)any other:(Class _Nonnull)other; +// CHECK-NEXT: - (void)testSingleProtocolTypes:(id _Nonnull)a aAgain:(id _Nonnull)a2 b:(id _Nonnull)b bAgain:(id _Nonnull)b2 both:(id _Nonnull)both; +// CHECK-NEXT: - (void)testSingleProtocolClassTypes:(Class _Nonnull)a aAgain:(Class _Nonnull)a2 b:(Class _Nonnull)b bAgain:(Class _Nonnull)b2 both:(Class _Nonnull)both; +// CHECK-NEXT: - (void)testComposition:(id _Nonnull)x meta:(Class _Nonnull)xClass; +// CHECK-NEXT: - (void)testOptional:(id _Nullable)opt meta:(Class _Nullable)m; // CHECK-NEXT: @end @objc protocol Methods { func test() @@ -133,9 +133,9 @@ extension NSString : A, ZZZ {} // CHECK-LABEL: @protocol Properties // CHECK-NEXT: @property (nonatomic, readonly) NSInteger a; -// CHECK-NEXT: @property (nonatomic, strong) id __nullable b; +// CHECK-NEXT: @property (nonatomic, strong) id _Nullable b; // CHECK-NEXT: @optional -// CHECK-NEXT: @property (nonatomic, readonly, copy) NSString * __nonnull c; +// CHECK-NEXT: @property (nonatomic, readonly, copy) NSString * _Nonnull c; // CHECK-NEXT: @end @objc protocol Properties { var a: Int { get } diff --git a/test/Prototypes/CollectionTransformers.swift b/test/Prototypes/CollectionTransformers.swift index 1ad174d751a8b..bcfed727ced5c 100644 --- a/test/Prototypes/CollectionTransformers.swift +++ b/test/Prototypes/CollectionTransformers.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -24,7 +24,7 @@ public protocol ApproximateCountableSequenceType : SequenceType { var approximateCount: ApproximateCount { get } } -/// A collection that provides an efficient way to spilt its index ranges. +/// A collection that provides an efficient way to split its index ranges. public protocol SplittableCollectionType : CollectionType { // We need this protocol so that collections with only forward or bidirectional // traversals could customize their splitting behavior. @@ -32,7 +32,7 @@ public protocol SplittableCollectionType : CollectionType { // FIXME: all collections with random access should conform to this protocol // automatically. - /// Splits a given range of indicies into a set of disjoint ranges covering + /// Splits a given range of indices into a set of disjoint ranges covering /// the same elements. /// /// Complexity: amortized O(1). @@ -44,7 +44,7 @@ public protocol SplittableCollectionType : CollectionType { /// FIXME: a better name. Users will never want to call this method /// directly. /// - /// FIXME: return an optional for the common case when split() can not + /// FIXME: return an optional for the common case when split() cannot /// subdivide the range further. func split(range: Range) -> [Range] } diff --git a/test/Prototypes/CollectionsMoveIndices.swift b/test/Prototypes/CollectionsMoveIndices.swift new file mode 100644 index 0000000000000..0299e244072c1 --- /dev/null +++ b/test/Prototypes/CollectionsMoveIndices.swift @@ -0,0 +1,1011 @@ +// RUN: %target-run-simple-swift +// REQUIRES: executable_test + +// https://bugs.swift.org/browse/SR-122 +// +// Summary +// ======= +// +// This file implements a prototype for a collection model where +// indices can't move themselves forward or backward. Instead, the +// corresponding collection moves the indices. +// +// Problem +// ======= +// +// In practice it has turned out that every one of our concrete +// collection's non random-access indices holds a reference to the +// collection it traverses. This introduces complexity in +// implementations (especially as we try to avoid multiple-reference +// effects that can cause unnecessary COW copies -- see `Dictionary` +// and `Set`) and presumably translates into less-efficient codegen. +// We should consider other schemes. +// +// Solution +// ======== +// +// Change indices so that they can't be moved forward or backward by +// themselves (`i.successor()`). Then indices can store the minimal +// amount of information about the element position in the collection, +// and avoid keeping a reference to the whole collection. + +public protocol MyGeneratorType { + typealias Element + mutating func next() -> Element? +} +public protocol MySequenceType { + typealias Generator : MyGeneratorType + typealias SubSequence /* : MySequenceType */ + func generate() -> Generator + @warn_unused_result + func map( + @noescape transform: (Generator.Element) throws -> T + ) rethrows -> [T] +} +extension MySequenceType { + @warn_unused_result + public func map( + @noescape transform: (Generator.Element) throws -> T + ) rethrows -> [T] { + var result: [T] = [] + for element in OldSequence(self) { + result.append(try transform(element)) + } + return result + } +} + +//------------------------------------------------------------------------ +// Bridge between the old world and the new world + +struct OldSequence : SequenceType { + let _base: S + init(_ base: S) { + self._base = base + } + func generate() -> OldGenerator { + return OldGenerator(_base.generate()) + } +} + +struct OldGenerator : GeneratorType { + var _base: G + init(_ base: G) { + self._base = base + } + mutating func next() -> G.Element? { + return _base.next() + } +} + +// End of the bridge +//------------------------------------------------------------------------ + +public protocol MyIndexableType { + typealias Index : MyIndexType + typealias _Element + typealias UnownedHandle + var startIndex: Index { get } + var endIndex: Index { get } + subscript(i: Index) -> _Element { get } + + init(from handle: UnownedHandle) + var unownedHandle: UnownedHandle { get } + + @warn_unused_result + func next(i: Index) -> Index + + func _nextInPlace(inout i: Index) + + func _failEarlyRangeCheck(index: Index, bounds: MyRange) + + func _failEarlyRangeCheck2( + rangeStart: Index, rangeEnd: Index, boundsStart: Index, boundsEnd: Index) +} +extension MyIndexableType { + @inline(__always) + public func _nextInPlace(inout i: Index) { + i = next(i) + } +} + +public protocol MyForwardCollectionType : MySequenceType, MyIndexableType { + typealias Generator = DefaultGenerator + typealias Index : MyIndexType + typealias SubSequence : MySequenceType /* : MyForwardCollectionType */ + = MySlice + typealias UnownedHandle = Self // DefaultUnownedForwardCollection + typealias IndexRange : MyIndexRangeType, MySequenceType, MyIndexableType /* : MyForwardCollectionType */ + // FIXME: where IndexRange.Generator.Element == Index + // FIXME: where IndexRange.Index == Index + = DefaultForwardIndexRange + + var startIndex: Index { get } + var endIndex: Index { get } + subscript(i: Index) -> Generator.Element { get } + subscript(bounds: MyRange) -> SubSequence { get } + + init(from handle: UnownedHandle) + var unownedHandle: UnownedHandle { get } + + @warn_unused_result + func next(i: Index) -> Index + + @warn_unused_result + func advance(i: Index, by: Index.Distance) -> Index + + @warn_unused_result + func advance(i: Index, by: Index.Distance, limit: Index) -> Index + + @warn_unused_result + func distanceFrom(start: Index, to: Index) -> Index.Distance + + func _failEarlyRangeCheck(index: Index, bounds: MyRange) + + func _failEarlyRangeCheck2( + rangeStart: Index, rangeEnd: Index, boundsStart: Index, boundsEnd: Index) + + var indices: IndexRange { get } + + @warn_unused_result + func _customIndexOfEquatableElement(element: Generator.Element) -> Index?? + + var first: Generator.Element? { get } + + var isEmpty: Bool { get } + + var count: Index.Distance { get } +} +extension MyForwardCollectionType + // FIXME: this constraint shouldn't be necessary. + where IndexRange.Index == Index + { + + // FIXME: do we want this overload? Would we provide such an overload + // for every method that accepts ranges of indices? + // FIXME: can we have a generic subscript on MyIndexRangeType instead? + public subscript(bounds: IndexRange) -> SubSequence { + return self[MyRange(start: bounds.startIndex, end: bounds.endIndex)] + } +} + +extension MyForwardCollectionType { + /// Do not use this method directly; call advancedBy(n) instead. + @inline(__always) + @warn_unused_result + internal func _advanceForward(i: Index, by n: Index.Distance) -> Index { + _precondition(n >= 0, + "Only BidirectionalIndexType can be advanced by a negative amount") + + var i = i + for var offset: Index.Distance = 0; offset != n; offset = offset + 1 { + _nextInPlace(&i) + } + return i + } + + /// Do not use this method directly; call advancedBy(n, limit) instead. + @inline(__always) + @warn_unused_result + internal func _advanceForward( + i: Index, by n: Index.Distance, limit: Index + ) -> Index { + _precondition(n >= 0, + "Only BidirectionalIndexType can be advanced by a negative amount") + + var i = i + for var offset: Index.Distance = 0; offset != n && i != limit; offset = offset + 1 { + _nextInPlace(&i) + } + return i + } + + @warn_unused_result + public func advance(i: Index, by n: Index.Distance) -> Index { + return self._advanceForward(i, by: n) + } + + @warn_unused_result + public func advance(i: Index, by n: Index.Distance, limit: Index) -> Index { + return self._advanceForward(i, by: n, limit: limit) + } + + @warn_unused_result + public func distanceFrom(start: Index, to end: Index) -> Index.Distance { + var start = start + var count: Index.Distance = 0 + while start != end { + count = count + 1 + _nextInPlace(&start) + } + return count + } + + public func _failEarlyRangeCheck( + index: Index, bounds: MyRange) { + // Can't perform range checks in O(1) on forward indices. + } + + public func _failEarlyRangeCheck2( + rangeStart: Index, rangeEnd: Index, boundsStart: Index, boundsEnd: Index + ) { + // Can't perform range checks in O(1) on forward indices. + } + + @warn_unused_result + public func _customIndexOfEquatableElement( + element: Generator.Element + ) -> Index?? { + return nil + } + + public var first: Generator.Element? { + return isEmpty ? nil : self[startIndex] + } + + public var isEmpty: Bool { + return startIndex == endIndex + } + + public var count: Index.Distance { + return distanceFrom(startIndex, to: endIndex) + } +} +extension MyForwardCollectionType + where Generator == DefaultGenerator { + + public func generate() -> DefaultGenerator { + return DefaultGenerator(self) + } +} +extension MyForwardCollectionType + where UnownedHandle == Self + // where UnownedHandle == DefaultUnownedForwardCollection +{ + + public init(from handle: UnownedHandle) { + self = handle + } + + public var unownedHandle: UnownedHandle { + return self + } +} +extension MyForwardCollectionType + where SubSequence == MySlice { + + public subscript(bounds: MyRange) -> SubSequence { + return MySlice(base: self, start: bounds.startIndex, end: bounds.endIndex) + } +} +extension MyForwardCollectionType + where IndexRange == DefaultForwardIndexRange { + + public var indices: IndexRange { + return DefaultForwardIndexRange( + collection: self, startIndex: startIndex, endIndex: endIndex) + } +} +extension MyForwardCollectionType + where Index : MyRandomAccessIndex { + + @warn_unused_result + public func next(i: Index) -> Index { + return advance(i, by: 1) + } + + @warn_unused_result + public func advance(i: Index, by n: Index.Distance) -> Index { + _precondition(n >= 0, + "Can't advance an Index of MyForwardCollectionType by a negative amount") + return i.advancedBy(n) + } + + @warn_unused_result + public func advance(i: Index, by n: Index.Distance, limit: Index) -> Index { + _precondition(n >= 0, + "Can't advance an Index of MyForwardCollectionType by a negative amount") + let d = i.distanceTo(limit) + _precondition(d >= 0, + "The specified limit is behind the index") + if d <= n { + return limit + } + return i.advancedBy(n) + } +} +extension MyForwardCollectionType + where + Generator.Element : Equatable, + IndexRange.Generator.Element == Index // FIXME +{ + public func indexOf(element: Generator.Element) -> Index? { + if let result = _customIndexOfEquatableElement(element) { + return result + } + for i in OldSequence(self.indices) { + if self[i] == element { + return i + } + } + return nil + } + + public func indexOf_optimized(element: Generator.Element) -> Index? { + if let result = _customIndexOfEquatableElement(element) { + return result + } + var i = startIndex + while i != endIndex { + if self[i] == element { + return i + } + _nextInPlace(&i) + } + return nil + } +} +extension MyForwardCollectionType + where SubSequence == Self { + + @warn_unused_result + public mutating func popFirst() -> Generator.Element? { + guard !isEmpty else { return nil } + let element = first! + self = self[MyRange(start: self.next(startIndex), end: endIndex)] + return element + } +} + +public protocol MyBidirectionalCollectionType : MyForwardCollectionType { + @warn_unused_result + func previous(i: Index) -> Index + + func _previousInPlace(inout i: Index) +} + +extension MyBidirectionalCollectionType { + @inline(__always) + public func _previousInPlace(inout i: Index) { + i = previous(i) + } + + @warn_unused_result + public func advance(i: Index, by n: Index.Distance) -> Index { + if n >= 0 { + return _advanceForward(i, by: n) + } + var i = i + for var offset: Index.Distance = n; offset != 0; offset = offset + 1 { + _previousInPlace(&i) + } + return i + } + + @warn_unused_result + public func advance(i: Index, by n: Index.Distance, limit: Index) -> Index { + if n >= 0 { + return _advanceForward(i, by: n, limit: limit) + } + var i = i + for var offset: Index.Distance = n; offset != 0 && i != limit; + offset = offset + 1 { + _previousInPlace(&i) + } + return i + } +} +extension MyBidirectionalCollectionType + where Index : MyRandomAccessIndex { + + @warn_unused_result + public func previous(i: Index) -> Index { + return advance(i, by: -1) + } + + @warn_unused_result + public func advance(i: Index, by n: Index.Distance) -> Index { + return i.advancedBy(n) + } + + @warn_unused_result + public func advance(i: Index, by n: Index.Distance, limit: Index) -> Index { + let d = i.distanceTo(limit) + if d == 0 || (d > 0 ? d <= n : d >= n) { + return limit + } + return i.advancedBy(n) + } +} + +public protocol MyRandomAccessCollectionType : MyBidirectionalCollectionType { + typealias Index : MyRandomAccessIndex +} + +public struct DefaultUnownedForwardCollection { + internal let _collection: Collection + + public init(_ collection: Collection) { + self._collection = collection + } +} +public struct DefaultForwardIndexRange + : MyForwardCollectionType, MyIndexRangeType +{ + internal let _unownedCollection: Collection.UnownedHandle + public let startIndex: Collection.Index + public let endIndex: Collection.Index + + // FIXME: remove explicit typealiases. + public typealias _Element = Collection.Index + public typealias Generator = DefaultForwardIndexRangeGenerator + public typealias Index = Collection.Index + public typealias SubSequence = DefaultForwardIndexRange + public typealias UnownedHandle = DefaultForwardIndexRange + + public init( + collection: Collection, + startIndex: Collection.Index, + endIndex: Collection.Index + ) { + self._unownedCollection = collection.unownedHandle + self.startIndex = startIndex + self.endIndex = endIndex + } + + // FIXME: use DefaultGenerator when the type checker bug is fixed. + public func generate() -> Generator { + return DefaultForwardIndexRangeGenerator( + Collection(from: _unownedCollection), + start: startIndex, + end: endIndex) + } + + public subscript(i: Collection.Index) -> Collection.Index { + return i + } + + public subscript(bounds: MyRange) -> DefaultForwardIndexRange { + fatalError("implement") + } + + public init(from handle: UnownedHandle) { + self = handle + } + + public var unownedHandle: UnownedHandle { + return self + } + + @warn_unused_result + public func next(i: Index) -> Index { + return Collection(from: _unownedCollection).next(i) + } +} + +// FIXME: use DefaultGenerator when the type checker bug is fixed. +public struct DefaultForwardIndexRangeGenerator + : MyGeneratorType +{ + internal let _collection: Collection + internal var _i: Collection.Index + internal var _endIndex: Collection.Index + + public init( + _ collection: Collection, + start: Collection.Index, + end: Collection.Index + ) { + self._collection = collection + self._i = collection.startIndex + self._endIndex = end + } + + public mutating func next() -> Collection.Index? { + if _i == _endIndex { + return nil + } + let result = _i + _i = _collection.next(_i) + return result + } +} + +public struct MyRange : MyIndexRangeType { + public let startIndex: Index + public let endIndex: Index + + public init(start: Index, end: Index) { + self.startIndex = start + self.endIndex = end + } + + public subscript(i: Index) -> Index { + return i + } +} + +// FIXME: in order for all this to be usable, we need to unify MyRange and +// MyHalfOpenInterval. We can do that by constraining the Bound to comparable, +// and providing a conditional conformance to collection when the Bound is +// strideable. +public struct MyHalfOpenInterval { + public let start: Bound + public let end: Bound +} +public struct MySlice + : MyForwardCollectionType +// : MyIndexableType +{ + internal let _base: Collection + public let startIndex: Collection.Index + public let endIndex: Collection.Index + // FIXME: remove explicit typealiases. + public typealias _Element = Collection._Element + public typealias Index = Collection.Index + public init( + base: Collection, start: Collection.Index, end: Collection.Index) { + self._base = base + self.startIndex = start + self.endIndex = end + } + public subscript(i: Collection.Index) -> Collection._Element { + _base._failEarlyRangeCheck( + i, bounds: MyRange(start: startIndex, end: endIndex)) + return _base[i] + } + + public typealias Generator = DefaultGenerator + public func generate() -> Generator { + return DefaultGenerator(self) + } + + public typealias SubSequence = MySlice + public subscript(bounds: MyRange) -> SubSequence { + _base._failEarlyRangeCheck2( + bounds.startIndex, rangeEnd: bounds.endIndex, + boundsStart: startIndex, boundsEnd: endIndex) + return MySlice(base: _base, start: bounds.startIndex, end: bounds.endIndex) + } + + @warn_unused_result + public func next(i: Index) -> Index { + return _base.next(i) + } + + public func _failEarlyRangeCheck(index: Index, bounds: MyRange) { + fatalError("FIXME") + } + + public func _failEarlyRangeCheck2( + rangeStart: Index, rangeEnd: Index, boundsStart: Index, boundsEnd: Index) { + fatalError("FIXME") + } + + // FIXME: use Collection.UnownedHandle instead. + public typealias UnownedHandle = MySlice + public var unownedHandle: UnownedHandle { return self } + public init(from handle: UnownedHandle) { + self = handle + } + + // FIXME: use DefaultForwardIndexRange instead. + public typealias IndexRange = MySliceIndexRange + public var indices: IndexRange { + return MySliceIndexRange( + collection: self, startIndex: startIndex, endIndex: endIndex) + } +} +public struct MySliceIndexRange + //: MyForwardCollectionType + : MyIndexRangeType, MySequenceType, MyIndexableType +{ + internal let _unownedCollection: Collection.UnownedHandle + public let startIndex: Collection.Index + public let endIndex: Collection.Index + + // FIXME: remove explicit typealiases. + public typealias _Element = Collection.Index + public typealias Generator = DefaultForwardIndexRangeGenerator + public typealias Index = Collection.Index + public typealias SubSequence = MySliceIndexRange + public typealias UnownedHandle = MySliceIndexRange + + public init( + collection: Collection, + startIndex: Collection.Index, + endIndex: Collection.Index + ) { + self._unownedCollection = collection.unownedHandle + self.startIndex = startIndex + self.endIndex = endIndex + } + + public func generate() -> Generator { + return DefaultForwardIndexRangeGenerator( + Collection(from: _unownedCollection), + start: startIndex, + end: endIndex) + } + + public subscript(i: Collection.Index) -> Collection.Index { + return i + } + + public subscript(bounds: MyRange) -> MySliceIndexRange { + fatalError("implement") + } + + public init(from handle: UnownedHandle) { + self = handle + } + + public var unownedHandle: UnownedHandle { + return self + } + + @warn_unused_result + public func next(i: Index) -> Index { + return Collection(from: _unownedCollection).next(i) + } + + public func _failEarlyRangeCheck(index: Index, bounds: MyRange) { + } + + public func _failEarlyRangeCheck2( + rangeStart: Index, rangeEnd: Index, boundsStart: Index, boundsEnd: Index) { + } + + public typealias IndexRange = MySliceIndexRange + public var indices: IndexRange { + return self + } +} + +public struct MyMutableSlice {} +public struct MyAnyGenerator : MyGeneratorType { + public init(_ g: G) { + fatalError("FIXME") + } + public mutating func next() -> Element? { + fatalError("FIXME") + } +} +public struct MyAnySequence : MySequenceType { + public typealias SubSequence = MyAnySequence + public init(_ s: S) { + fatalError("FIXME") + } + public func generate() -> MyAnyGenerator { + fatalError("FIXME") + } +} +public struct DefaultGenerator + : MyGeneratorType { + internal let _collection: Collection + internal var _i: Collection.Index + + public init(_ collection: Collection) { + self._collection = collection + self._i = collection.startIndex + } + + public mutating func next() -> Collection._Element? { + if _i == _collection.endIndex { + return nil + } + let result = _collection[_i] + _i = _collection.next(_i) + return result + } +} +public protocol MyMutableCollectionType : MyForwardCollectionType { + typealias SubSequence : MyForwardCollectionType = MyMutableSlice + subscript(i: Index) -> Generator.Element { get set } +} + +public protocol MyIndexType : Equatable { + // Move to CollectionType? + typealias Distance : SignedIntegerType = Int +} +public protocol MyIndexRangeType : Equatable { + typealias Index : MyIndexType + var startIndex: Index { get } + var endIndex: Index { get } +} + +public func == (lhs: IR, rhs: IR) -> Bool { + return + lhs.startIndex == rhs.startIndex && + lhs.endIndex == rhs.endIndex +} + +/* +public protocol MyRandomAccessIndexType : MyBidirectionalIndexType, MyStrideable, + _RandomAccessAmbiguity { + + @warn_unused_result + func distanceTo(other: Self) -> Distance + + @warn_unused_result + func advancedBy(n: Distance) -> Self + + @warn_unused_result + func advancedBy(n: Distance, limit: Self) -> Self +} + +extension MyRandomAccessIndexType { + public func _failEarlyRangeCheck(index: Self, bounds: MyRange) { + _precondition( + bounds.startIndex <= index, + "index is out of bounds: index designates a position before bounds.startIndex") + _precondition( + index < bounds.endIndex, + "index is out of bounds: index designates the bounds.endIndex position or a position after it") + } + + public func _failEarlyRangeCheck2( + rangeStart: Self, rangeEnd: Self, boundsStart: Self, boundsEnd: Self + ) { + let range = MyRange(startIndex: rangeStart, endIndex: rangeEnd) + let bounds = MyRange(startIndex: boundsStart, endIndex: boundsEnd) + _precondition( + bounds.startIndex <= range.startIndex, + "range.startIndex is out of bounds: index designates a position before bounds.startIndex") + _precondition( + bounds.startIndex <= range.endIndex, + "range.endIndex is out of bounds: index designates a position before bounds.startIndex") + + _precondition( + range.startIndex <= bounds.endIndex, + "range.startIndex is out of bounds: index designates a position after bounds.endIndex") + _precondition( + range.endIndex <= bounds.endIndex, + "range.startIndex is out of bounds: index designates a position after bounds.endIndex") + } + + @transparent + @warn_unused_result + public func advancedBy(n: Distance, limit: Self) -> Self { + let d = self.distanceTo(limit) + if d == 0 || (d > 0 ? d <= n : d >= n) { + return limit + } + return self.advancedBy(n) + } +} +*/ +//------------ + +public protocol MyStrideable : Comparable { + typealias Distance : SignedNumberType + + @warn_unused_result + func distanceTo(other: Self) -> Distance + + @warn_unused_result + func advancedBy(n: Distance) -> Self +} + +public protocol MyRandomAccessIndex : MyIndexType, MyStrideable {} + +extension Int : MyIndexType {} +extension Int : MyStrideable {} +extension Int : MyRandomAccessIndex {} + +//------------------------------------------------------------------------ +// Array + +public struct MyArray : MyForwardCollectionType { + internal var _elements: [Element] = [] + + init() {} + init(_ elements: [Element]) { + self._elements = elements + } + + public var startIndex: Int { + return _elements.startIndex + } + public var endIndex: Int { + return _elements.endIndex + } + public subscript(i: Int) -> Element { + return _elements[i] + } +} + +//------------------------------------------------------------------------ +// Simplest Forward Collection + +public struct MySimplestForwardCollection : MyForwardCollectionType { + internal let _elements: [Element] + + public init(_ elements: [Element]) { + self._elements = elements + } + + public var startIndex: MySimplestForwardCollectionIndex { + return MySimplestForwardCollectionIndex(_elements.startIndex) + } + + public var endIndex: MySimplestForwardCollectionIndex { + return MySimplestForwardCollectionIndex(_elements.endIndex) + } + + @warn_unused_result + public func next(i: MySimplestForwardCollectionIndex) -> MySimplestForwardCollectionIndex { + return MySimplestForwardCollectionIndex(i._index + 1) + } + + public subscript(i: MySimplestForwardCollectionIndex) -> Element { + return _elements[i._index] + } +} + +public struct MySimplestForwardCollectionIndex : MyIndexType { + internal let _index: Int + internal init(_ index: Int) { + self._index = index + } +} + +public func == ( + lhs: MySimplestForwardCollectionIndex, + rhs: MySimplestForwardCollectionIndex +) -> Bool { + return lhs._index == rhs._index +} + +//------------------------------------------------------------------------ +// Simplest Bidirectional Collection + +public struct MySimplestBidirectionalCollection : MyBidirectionalCollectionType { + internal let _elements: [Element] + + public init(_ elements: [Element]) { + self._elements = elements + } + + public var startIndex: MySimplestBidirectionalCollectionIndex { + return MySimplestBidirectionalCollectionIndex(_elements.startIndex) + } + + public var endIndex: MySimplestBidirectionalCollectionIndex { + return MySimplestBidirectionalCollectionIndex(_elements.endIndex) + } + + @warn_unused_result + public func next(i: MySimplestBidirectionalCollectionIndex) -> MySimplestBidirectionalCollectionIndex { + return MySimplestBidirectionalCollectionIndex(i._index + 1) + } + + @warn_unused_result + public func previous(i: MySimplestBidirectionalCollectionIndex) -> MySimplestBidirectionalCollectionIndex { + return MySimplestBidirectionalCollectionIndex(i._index - 1) + } + + public subscript(i: MySimplestBidirectionalCollectionIndex) -> Element { + return _elements[i._index] + } +} + +public struct MySimplestBidirectionalCollectionIndex : MyIndexType { + internal let _index: Int + internal init(_ index: Int) { + self._index = index + } +} + +public func == ( + lhs: MySimplestBidirectionalCollectionIndex, + rhs: MySimplestBidirectionalCollectionIndex +) -> Bool { + return lhs._index == rhs._index +} + +//------------------------------------------------------------------------ +// Simplest Bidirectional Collection + +public struct MySimplestRandomAccessCollection : MyRandomAccessCollectionType { + internal let _elements: [Element] + + public init(_ elements: [Element]) { + self._elements = elements + } + + // FIXME: 'typealias Index' should be inferred. + public typealias Index = MySimplestRandomAccessCollectionIndex + + public var startIndex: MySimplestRandomAccessCollectionIndex { + return MySimplestRandomAccessCollectionIndex(_elements.startIndex) + } + + public var endIndex: MySimplestRandomAccessCollectionIndex { + return MySimplestRandomAccessCollectionIndex(_elements.endIndex) + } + + public subscript(i: MySimplestRandomAccessCollectionIndex) -> Element { + return _elements[i._index] + } +} + +public struct MySimplestRandomAccessCollectionIndex : MyRandomAccessIndex { + internal let _index: Int + internal init(_ index: Int) { + self._index = index + } + + @warn_unused_result + public func distanceTo(other: MySimplestRandomAccessCollectionIndex) -> Int { + return other._index - _index + } + + @warn_unused_result + public func advancedBy(n: Int) -> MySimplestRandomAccessCollectionIndex { + return MySimplestRandomAccessCollectionIndex(_index + n) + } +} + +public func == ( + lhs: MySimplestRandomAccessCollectionIndex, + rhs: MySimplestRandomAccessCollectionIndex +) -> Bool { + return lhs._index == rhs._index +} + +public func < ( + lhs: MySimplestRandomAccessCollectionIndex, + rhs: MySimplestRandomAccessCollectionIndex +) -> Bool { + return lhs._index < rhs._index +} + +//------------------------------------------------------------------------ + +// FIXME: how does AnyCollection look like in the new scheme? + +import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + +var NewCollection = TestSuite("NewCollection") + +NewCollection.test("indexOf") { + expectEqual(1, MyArray([1,2,3]).indexOf(2)) + expectEmpty(MyArray([1,2,3]).indexOf(42)) +} + +NewCollection.test("first") { + expectOptionalEqual(1, MyArray([1,2,3]).first) + expectEmpty(MyArray().first) +} + +NewCollection.test("count") { + expectEqual(3, MyArray([1,2,3]).count) + expectEqual(0, MyArray().count) +} + +NewCollection.test("isEmpty") { + expectFalse(MyArray([1,2,3]).isEmpty) + expectTrue(MyArray().isEmpty) +} + +NewCollection.test("popFirst") { + let c = MyArray([1,2,3]) + var s0 = c[c.indices] + var s = c[MyRange(start: c.startIndex, end: c.endIndex)] + expectOptionalEqual(1, s.popFirst()) + expectOptionalEqual(2, s.popFirst()) + expectOptionalEqual(3, s.popFirst()) + expectEmpty(s.popFirst()) +} + +runAllTests() + diff --git a/test/Prototypes/FloatingPoint.swift b/test/Prototypes/FloatingPoint.swift index 5c00af67b4d19..327225e04fdcd 100644 --- a/test/Prototypes/FloatingPoint.swift +++ b/test/Prototypes/FloatingPoint.swift @@ -139,7 +139,7 @@ FloatLiteralConvertible { /// For other values of `x`, `x.significand` is defined as follows: /// /// - If `x` is zero, then `x.significand` is 0.0. - /// - If `x` is infinity, then `x.signficand` is 1.0. + /// - If `x` is infinity, then `x.significand` is 1.0. /// - If `x` is NaN, then `x.significand` is NaN. /// /// For all floating-point `x`, if we define y by: @@ -154,14 +154,14 @@ FloatLiteralConvertible { /// the payload of NaN are preserved. var significand: Self { get } - /// Combines a signbit, exponent, and signficand to produce a floating-point + /// Combines a signbit, exponent, and significand to produce a floating-point /// datum. /// /// In common usage, `significand` will generally be a number in the range /// `[1,2)`, but this is not required; the initializer supports any valid /// floating-point datum. The result is: /// - /// `(-1)^signbit * signficand * 2^exponent` + /// `(-1)^signbit * significand * 2^exponent` /// /// (where ^ denotes the mathematical operation of exponentiation) computed /// as if by a single correctly-rounded floating-point operation. If this @@ -194,7 +194,7 @@ FloatLiteralConvertible { /// edge cases to be aware of: /// /// - `greatestFiniteMagnitude.ulp` is a finite number, even though - /// the next greater respresentable value is `infinity`. + /// the next greater representable value is `infinity`. /// - `x.ulp` is `NaN` if `x` is not a finite number. /// - If `x` is very small in magnitude, then `x.ulp` may be a subnormal /// number. On targets that do not support subnormals, `x.ulp` may be @@ -329,7 +329,7 @@ FloatLiteralConvertible { // TODO: do we actually want to provide remainder as an operator? It's // definitely not obvious to me that we should, but we have until now. - // See further discustion with func remainder(x,y) above. + // See further discussion with func remainder(x,y) above. func %(x: Self, y: Self) -> Self // Conversions from all integer types. @@ -517,7 +517,7 @@ extension FloatingPointType { public protocol BinaryFloatingPointType: FloatingPointType { - /// Values that parametrize the type: + /// Values that parameterize the type: static var _exponentBitCount: UInt { get } static var _fractionalBitCount: UInt { get } @@ -529,12 +529,12 @@ public protocol BinaryFloatingPointType: FloatingPointType { /// The least-magnitude member of the binade of `self`. /// - /// If `x` is `+/-signficand * 2^exponent`, then `x.binade` is + /// If `x` is `+/-significand * 2^exponent`, then `x.binade` is /// `+/- 2^exponent`; i.e. the floating point number with the same sign /// and exponent, but a significand of 1.0. var binade: Self { get } - /// Combines a signbit, exponent and signficand bit patterns to produce a + /// Combines a signbit, exponent and significand bit patterns to produce a /// floating-point datum. No error-checking is performed by this function; /// the bit patterns are simply concatenated to produce the floating-point /// encoding of the result. @@ -770,7 +770,7 @@ extension BinaryFloatingPointType { } public static func sqrt(x: X) -> Self { - if X._fractionalBitCount <= Self._fractionalBitCount { return sqrt(Self(x)) } + if X._fractionalBitCount <= Self._fractionalBitCount { return sqrt(Self(x)) } return Self(X._sqrtStickyRounding(x)) } @@ -1032,7 +1032,7 @@ extension Float80 : BinaryFloatingPointType { // If the exponent is non-zero and the leading bit of the significand // is clear, then we have an invalid operand (unnormal, pseudo-inf, or // pseudo-nan). All of these are treated as NaN by the hardware, so - // we make sure that bit of the signficand field is set. + // we make sure that bit of the significand field is set. return _representation.explicitSignificand | Float80._quietBitMask } // Otherwise we always get the "right" significand by simply clearing the @@ -1117,6 +1117,15 @@ public func ==(lhs: FloatingPointClassification, rhs: FloatingPointClassificatio //===--- tests ------------------------------------------------------------===// import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var tests = TestSuite("Floating Point") tests.test("Parts") { diff --git a/test/Prototypes/GenericDispatch.swift b/test/Prototypes/GenericDispatch.swift index 51aff897c7f7f..a913fc6692cfb 100644 --- a/test/Prototypes/GenericDispatch.swift +++ b/test/Prototypes/GenericDispatch.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -123,7 +123,7 @@ struct X : D { // Here's a generic function that uses our dispatching distance func sort(x: T) { // In here, we don't know whether T is an R or just a plain F, or - // whether it has its own specialized impelementation of + // whether it has its own specialized implementation of distance(x, x) } // CHECK-NEXT: F diff --git a/test/Prototypes/Integers.swift.gyb b/test/Prototypes/Integers.swift.gyb index 40526f0fa4a7d..e7d1ce2f1597f 100644 --- a/test/Prototypes/Integers.swift.gyb +++ b/test/Prototypes/Integers.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// // RUN: rm -rf %t && mkdir -p %t && %S/../../utils/gyb -DWORD_BITS=%target-ptrsize %s -o %t/out.swift -// RUN: %S/../../utils/line-directive %t/out.swift -- %target-build-swift -parse-stdlib %t/out.swift -o %t/a.out +// RUN: %S/../../utils/line-directive %t/out.swift -- %target-build-swift -parse-stdlib %t/out.swift -o %t/a.out -Onone // RUN: %S/../../utils/line-directive %t/out.swift -- %target-run %t/a.out // REQUIRES: executable_test import Swift @@ -105,7 +105,7 @@ infix operator &>>= { associativity right precedence 90 assignment } @_transparent public func _assertCond( @autoclosure condition: () -> Bool, - @autoclosure _ message: ()->String, + @autoclosure _ message: () -> String, file: StaticString = __FILE__, line: UInt = __LINE__) { let ok = condition() if _isDebugAssertConfiguration() { @@ -116,6 +116,13 @@ public func _assertCond( //===--- Prototype Implementation -----------------------------------------===// +/// Prints the message if the body is uncommented; used for +/// diagnostics. +@_transparent +public func _log(@autoclosure message: ()->String) { + // print(message()) +} + //===----------------------------------------------------------------------===// //===--- ArithmeticType ---------------------------------------------------===// //===----------------------------------------------------------------------===// @@ -168,8 +175,18 @@ public typealias UWord = UInt${word_bits} public protocol IntegerType : Comparable, ArithmeticType, - IntegerLiteralConvertible, CustomStringConvertible { + IntegerLiteralConvertible, CustomStringConvertible { + // FIXME: Ideally, this constraint would just be : IntegerType. + // Until we get recursive protocol requirements, that isn't + // possible, and we really need to factor IntegerType differently + // than it currently is so we can remove the constraints on + // AbsoluteValue in the multiprecision multiplication routines. + typealias AbsoluteValue : Comparable, ArithmeticType, + IntegerLiteralConvertible, CustomStringConvertible + + var absoluteValue: AbsoluteValue { get } + // Dispatching through these puts less stress on the user reading // the interface and error messages (and on the type checker) than // does having many operator overloads. @@ -186,11 +203,53 @@ public protocol IntegerType var mostSignificantBit: Word { get } @warn_unused_result - func word(n: Word) -> Word + func uword(n: Word) -> UWord + + var countRepresentedWords: Word { get } + /// Replace as many bits as possible of the `n`th UWord of our + /// representation with newBits, returning `true` iff all of the + /// bits were replaced. + mutating func replaceUWord(n: Word, with newBits: UWord) -> Bool + init(_ source: T) - init(extendingOrTruncating source: T) + init(extendingOrTruncating source: T) + + mutating func addInPlace(rhs: RHS) -> ArithmeticOverflow + + /// The most significant word in a signed representation of `self`. + /// + /// (x.word(x.signWordIndex) < 0) == (self < 0) + /// + /// and, for all `i` > `x.signWordIndex`, + /// + /// x.word(i) == x.word(x.signWordIndex) >> (Word.bitWidth - 1) + /// + var signWordIndex: Word { get } + + mutating func signedOverflowIntoWord( + wordIndex: Word, overflow: Bool, originalSign: Word) -> ArithmeticOverflow + + static var isSigned: Bool { get } +} + +extension IntegerType { + @_transparent + @warn_unused_result + public func word(n: Word) -> Word { + return Word(uword(n)._storage) + } + + /// The number of words required to represent our value. If `self` + /// is negative, returns the index of the least significant words of + /// our representation such that all more-significant words are -1. + /// Has the value -1 if `self` is 0. + @_transparent + public // transparent + var _mostSignificantWord: Word { + return mostSignificantBit &>> ${int(log(word_bits,2))} + } } //===--- Homogeneous comparison -------------------------------------------===// @@ -275,6 +334,12 @@ public func > (lhs: T, rhs: U) -> Bool { // // (T,T) -> Bool +@_transparent +@warn_unused_result +public func != (lhs:T, rhs: T) -> Bool { + return !(lhs == rhs) +} + @inline(__always) @warn_unused_result public func <= (lhs: T, rhs: T) -> Bool { @@ -296,7 +361,11 @@ public func > (lhs: T, rhs: T) -> Bool { //===----------------------------------------------------------------------===// //===--- FixedWidthIntegerType --------------------------------------------===// //===----------------------------------------------------------------------===// -public enum ArithmeticOverflow { case None, Overflow } +public enum ArithmeticOverflow { + @_transparent + public init(_ overflow: Bool) { self = overflow ? .Overflow : .None } + case None, Overflow +} public protocol FixedWidthIntegerType : IntegerType { static var bitWidth : Word { get } @@ -329,9 +398,9 @@ ${comment} @warn_unused_result func countLeadingZeros() -> Word - init(_truncatingBits bits: Word) + init(_truncatingBits bits: UWord) - var _lowWord: Word { get } + var _lowUWord: UWord { get } } % for x in binaryBitwise: @@ -392,7 +461,7 @@ public func ${x.nonMaskingOperator} < public func ${x.nonMaskingOperator} < T: FixedWidthIntegerType >(lhs: T, rhs: Word) -> T { - let overshiftR = T.min < 0 ? lhs &>> (T.bitWidth - 1) : 0 + let overshiftR = T.isSigned ? lhs &>> (T.bitWidth - 1) : 0 let overshiftL: T = 0 if _fastPath(rhs >= 0) { if _fastPath(rhs < T.bitWidth) { @@ -477,18 +546,18 @@ extension FixedWidthIntegerType { @_transparent public init(extendingOrTruncating source: T) { if Self.bitWidth <= ${word_bits} { - self = Self.init(_truncatingBits: source.word(0)) + self = Self.init(_truncatingBits: source.uword(0)) } else { var result: Self = source < 0 ? ~0 : 0 // start with the most significant word - var n = source.mostSignificantBit / ${word_bits} + var n = source._mostSignificantWord while n >= 0 { // masking is OK here because this we have already ensured // that Self.bitWidth > ${word_bits}. Not masking results in // infinite recursion. result &<<= ${word_bits} - result |= Self(_truncatingBits: source.word(n)) + result |= Self(_truncatingBits: source.uword(n)) n -= 1 } @@ -497,26 +566,69 @@ extension FixedWidthIntegerType { } @_transparent - public func word(n: Word) -> Word { - var n = n + public func uword(n: Word) -> UWord { _precondition(n >= 0, "Negative word index") - var x = self - while n > 0 { - // Using a masking shift here allows us to make more things - // transparent, but this would have the wrong semantics if the - // masking ever had an effect. - _sanityCheck(Self.bitWidth > ${word_bits}) - x &>>= ${word_bits} - n -= 1 + if _fastPath(n < countRepresentedWords) { + let shift = UWord(n._storage) &* ${word_bits} + let bitWidth = UWord(Self.bitWidth._storage) + _sanityCheck(shift < bitWidth) + return (self &>> Self(_truncatingBits: shift))._lowUWord } - return x._lowWord + return self < 0 ? ~0 : 0 } + public var countRepresentedWords: Word { + return (Self.bitWidth + ${word_bits} - 1) / ${word_bits} + } + + // @_transparent + public mutating func replaceUWord(n: Word, with newBits: UWord) -> Bool { + let flippedBits = uword(n) ^ newBits + self ^= Self(_truncatingBits: flippedBits) << (${word_bits} * n) + if uword(n) != newBits { + _log("###### overflow replacing word \(n) with \(newBits.hex)") + } + return uword(n) == newBits + } + @_transparent public // transparent static var _highBitIndex: Self { - return Self.init(_truncatingBits: Self.bitWidth - 1) + return Self.init(_truncatingBits: UWord(Self.bitWidth._storage) &- 1) + } +} + +extension UWord { + public typealias AdditiveOperator + = (UWord) -> (UWord, carryIn: Bool) + -> (result: UWord, carryFlag: Bool, overflowFlag: Bool) + + % for name in 'add', 'subtract': + // @_transparent + public // transparent + func _${name}ing( + rhs: UWord, carryIn: Bool + ) -> (result: UWord, carryFlag: Bool, overflowFlag: Bool) { + _log("**** \(self.hex)._${name}ing(\(rhs.hex), carryIn: \(carryIn))") + let signedRHS = Word(bitPattern: rhs) + + let (uResult0, carry0) = self.${name}WithOverflow(rhs) + let (sResult0, overflow0) + = Word(bitPattern: self).${name}WithOverflow(signedRHS) + + let (uResult1, carry1) = uResult0.${name}WithOverflow(carryIn ? 1 : 0) + let (_, overflow1) = sResult0.${name}WithOverflow(carryIn ? 1 : 0) + + let result = ( + result: uResult1, + carryFlag: carry0 != .None || carry1 != .None, + overflowFlag: overflow0 != .None || overflow1 != .None + ) + _log("**** -> sum: \(result.result.hex), " + + "carry: \(result.carryFlag), overflow: \(result.overflowFlag)") + return result } + % end } % for x in binaryArithmetic: @@ -532,8 +644,16 @@ public func &${x.operator} (lhs: T, rhs: T) -> T { //===--- UnsignedIntegerType ----------------------------------------------===// //===----------------------------------------------------------------------===// public protocol UnsignedIntegerType : IntegerType { + typealias AbsoluteValue : IntegerType } + extension UnsignedIntegerType { + @_transparent + public var absoluteValue: Self { return self } + + @_transparent + public static var isSigned: Bool { return false } + public var description: String { if self == 0 { return "0" @@ -582,6 +702,23 @@ extension UnsignedIntegerType where Self : FixedWidthIntegerType { public var mostSignificantBit: Word { return Self.bitWidth - 1 - self.countLeadingZeros() } + + @_transparent + public var signWordIndex: Word { + // If our high bit is set, then our signed representation contains + // one additional word. + let ifHighBitSetThen0Else1 = Word((~self &>> (Self.bitWidth - 1))._lowUWord) + return (Self.bitWidth - ifHighBitSetThen0Else1) / ${word_bits} + } + + @_transparent + public mutating func signedOverflowIntoWord( + wordIndex: Word, overflow: Bool, originalSign: Word + ) -> ArithmeticOverflow { + // We were performing a signed operation on unsigned storage. If + // the result was negative, we've overflowed. + return word(countRepresentedWords - 1) < 0 ? .Overflow : .None + } } //===----------------------------------------------------------------------===// @@ -590,7 +727,6 @@ extension UnsignedIntegerType where Self : FixedWidthIntegerType { public protocol SignedIntegerType : IntegerType { typealias AbsoluteValue : IntegerType - var absoluteValue: AbsoluteValue { get } } extension SignedIntegerType { @@ -598,6 +734,9 @@ extension SignedIntegerType { let base = String(absoluteValue) return self < 0 ? "-" + base : base } + + @_transparent + public static var isSigned: Bool { return true } } extension SignedIntegerType where Self : FixedWidthIntegerType { @@ -626,6 +765,18 @@ extension SignedIntegerType where Self : FixedWidthIntegerType { let x = self < 0 ? ~self : self return Self.bitWidth - 1 - x.countLeadingZeros() } + + @_transparent + public var signWordIndex: Word { + return (Self.bitWidth - 1) / ${word_bits} + } + + @_transparent + public mutating func signedOverflowIntoWord( + wordIndex: Word, overflow: Bool, originalSign: Word + ) -> ArithmeticOverflow { + return overflow ? .Overflow : .None + } } //===--- Concrete FixedWidthIntegers --------------------------------------===// @@ -650,6 +801,11 @@ public struct ${Self} _storage), x)) } + @_transparent + public init(bitPattern x: ${'U' if signed else ''}Int${bits}) { + _storage = x._storage + } + @warn_unused_result public func isEqualTo(rhs: ${Self}) -> Bool { return Bool(Builtin.cmp_eq_Int${bits}(_storage, rhs._storage)) @@ -693,7 +849,7 @@ public struct ${Self} return ( partialValue: ${Self}(newStorage), - overflow: Bool(overflow) ? .Overflow : .None) + overflow: ArithmeticOverflow(Bool(overflow))) } % end @@ -727,31 +883,24 @@ public struct ${Self} @_transparent @warn_unused_result public func countLeadingZeros() -> Word { - return ${Self}( - Builtin.int_ctlz_Int${bits}(self._storage, false.__value))._lowWord - } - - @_transparent - public // transparent - var _lowWord: Word { - % truncOrExt = z + 'ext' if bits <= word_bits else 'trunc' return Word( - Builtin.${truncOrExt}OrBitCast_Int${bits}_Int${word_bits}(_storage) - ) + ${Self}( + Builtin.int_ctlz_Int${bits}(self._storage, false.__value) + )._lowUWord._storage) } @_transparent public // transparent - var _lowUnsignedWord: Word { + var _lowUWord: UWord { % truncOrExt = z + 'ext' if bits <= word_bits else 'trunc' - return Word( + return UWord( Builtin.${truncOrExt}OrBitCast_Int${bits}_Int${word_bits}(_storage) ) } @_transparent public // transparent - init(_truncatingBits bits: Word) { + init(_truncatingBits bits: UWord) { % truncOrExt = 'zext' if bits > word_bits else 'trunc' self.init( Builtin.${truncOrExt}OrBitCast_Int${word_bits}_Int${bits}(bits._storage)) @@ -771,12 +920,327 @@ public struct ${Self} % end % end +//===----------------------------------------------------------------------===// +//===--- Multiprecision ---------------------------------------------------===// +//===----------------------------------------------------------------------===// + +//===--- Addition and Subtraction -----------------------------------------===// +// +// * Treat both operands as infinite-precision numbers, proceeding a +// word-at-a-time. +// +// * Signed/Unsigned mixes treat the unsigned number as signed, +// thereby adding 1 significant bit (which could result in using an +// extra word), and doing a signed operation. +// +// * Operations proceed one word at a time. Signed operations are +// composed of unsigned operations for all but the highest word. +// +// * Overflows in fixed-width integers are detected by two methods: +// - Checking the overflow flag when the most significant word of the +// result is computed. +// - Attempting to store bits that can't be represented. +// +// * In [un]signed operations, the maximum number of bits required to +// store a result is one more than the maximum number of bits +// required to store the [un]signed representation of both operands. +// When that number is one more than the number of bits +// representable by the [un]signed result type, we can use the +// carry/overflow flag to detect overflow. +// +extension IntegerType { + public mutating func unsignedAddInPlace( + rhs: RHS, uwordOperator: UWord.AdditiveOperator + ) -> ArithmeticOverflow { + _log("* \(Self.self)(\(self.hex)).unsignedAddInPlace" + + "(\(RHS.self)(\(rhs.hex)))") + let (carry, knownOverflow) = self.unsignedAddInPlace( + rhs, + countWords: max(self.countRepresentedWords, rhs.countRepresentedWords), + uwordOperator: uwordOperator + ) + return knownOverflow ?? ArithmeticOverflow(carry) + } + + public mutating func unsignedAddInPlace( + rhs: RHS, countWords: Word, uwordOperator: UWord.AdditiveOperator + ) -> (carry: Bool, knownOverflow: ArithmeticOverflow?) { + _log("** \(Self.self)(\(self.hex)).unsignedAddInPlace" + + "(\(RHS.self)(\(rhs.hex)), countWords: \(countWords))") + _log("*** rhs.countRepresentedWords: \(rhs.countRepresentedWords)") + + var i: Word = 0 + var carry: Bool = false + + while i < countWords { + let sum: UWord + (sum, carry, _) = uwordOperator(uword(i))(rhs.uword(i), carryIn: carry) + + if !self.replaceUWord(i, with: sum) { + return (false, .Overflow) + } + i += 1 + // optimization: if we've processed all represented words on the + // rhs and there's no carry out, the lhs can not be further + // affected and no overflow can occur. This probably doesn't + // matter for fixed-width integers but may be significant with + // larger BigNums. On the other hand, we may not want to + // optimize for that :-) + if carry == (rhs < 0) && i >= rhs.countRepresentedWords { + _log("*** early exit; carry can't affect lhs") + return (carry, .None as ArithmeticOverflow) + } + } + return (carry, nil) + } + + public mutating func signedAddInPlace( + rhs: RHS, uwordOperator: UWord.AdditiveOperator + ) -> ArithmeticOverflow { + _log("* \(Self.self)(\(self.hex)).signedAddInPlace" + + "(\(RHS.self)(\(rhs.hex)))") + // Do a multiword unsigned operation on all the words below the sign + // word. We may overflow here or discover that there is no + // overflow. + let lowWordCount = self.signWordIndex + + let (lowCarry, lowOverflowKnown) + = self.unsignedAddInPlace( + rhs, countWords: lowWordCount, uwordOperator: uwordOperator) + + if let finalOverflow = lowOverflowKnown { return finalOverflow } + + // Save off the sign word so that we don't lose it if the highest + // stored bit of the lhs flips. When this addition proceeds past + // the highest stored word, we still need to be able to retrieve + // the old sign word. + var oldSign = self.word(lowWordCount) + + var wordIndex: Word = lowWordCount + var overflow: Bool, carry: Bool = lowCarry + + repeat { + let bits: UWord + (bits, carry, overflow) = uwordOperator(oldSign._lowUWord)( + rhs.uword(wordIndex), carryIn: carry) + if !self.replaceUWord(wordIndex, with: bits) { + return .Overflow + } + oldSign &>>= ${word_bits - 1} // further sign words are 0 or -1 + wordIndex += 1 + } + while wordIndex <= rhs.signWordIndex + + return signedOverflowIntoWord( + wordIndex, overflow: overflow, originalSign: oldSign) + } +} + +extension IntegerType { + % for name in 'add', 'subtract': + public mutating func ${name}InPlace( + rhs: RHS + ) -> ArithmeticOverflow { + return Self.isSigned || RHS.isSigned + ? signedAddInPlace(rhs, uwordOperator: UWord._${name}ing) + : unsignedAddInPlace(rhs, uwordOperator: UWord._${name}ing) + } + % end +} + +% for x in binaryArithmetic: +@_transparent +public func ${x.operator}= < + T: IntegerType + // FIXME: remove this constraint by refactoring IntegerType + where T.AbsoluteValue : IntegerType +>(inout lhs: T, rhs: T) { + lhs.${x.name}InPlace(rhs) +} +% end + +@inline(__always) +public func +=(inout lhs: T, rhs: U) { + let overflow = lhs.addInPlace(rhs) + _assertCond(overflow == .None, "overflow in multiprecision add.") +} + +@inline(__always) +public func -=(inout lhs: T, rhs: U) { + let overflow = lhs.subtractInPlace(rhs) + _assertCond(overflow == .None, "overflow in multiprecision subtract.") +} + +//===--- Multiplication ---------------------------------------------------===// +// +// * Use the log-space algorithm given at +// https://en.wikipedia.org/wiki/Multiplication_algorithm#Space_complexity: +// +// multiply(a[1..p], b[1..q], base) +// tot = 0 +// for ri = 1 to p + q - 1 +// for bi = MAX(1, ri - p + 1) to MIN(ri, q) +// ai = ri − bi + 1 +// tot = tot + (a[ai] * b[bi]) +// product[ri] = tot mod base +// tot = floor(tot / base) +// product[p+q] = tot mod base +// return product +// +// +// * Treat each word as a "digit." +extension IntegerType { + static func multiplyNonNegative< + LHS: IntegerType, RHS: IntegerType + >(a: LHS, _ b: RHS, negativeResult: Bool) -> (Self, ArithmeticOverflow) { + _log("* \(self).multiplyNonNegative(\(a.hex), \(b.hex), negativeResult: \(negativeResult))") + + var product: Self = 0 + var total: UDWord = negativeResult ? ~0 : 0 + let p = a.countRepresentedWords, q = b.countRepresentedWords + var ri: Word = 1 + var overflow = false + _log("p = \(p), q = \(q)") + + while ri <= p + q - 1 { + _log("** ri = \(ri)") + var bi: Word = Swift.max(1, ri - p + 1) + while bi <= Swift.min(ri, q) { + let ai = ri - bi + 1 + _log("*** ai = \(ai), bi = \(bi)") + let p2 = UDWord(a.uword(ai - 1)) * UDWord(b.uword(bi - 1)) + total = total &+ p2 + _log("*** total += p2: \(p2.hex) => \(total.hex)") + bi += 1 + } + + _log("** total = \(total.hex)") + let u = negativeResult ? ~total._lowUWord : total._lowUWord + _log("** product word \(ri - 1) = \(u.hex)") + if !product.replaceUWord(ri - 1, with: u) { + overflow = true + } + if !negativeResult { + total &>>= UWord.bitWidth + } + else { + let signedTotal = DWord(bitPattern: total) + total = UDWord(bitPattern: signedTotal &>> UWord.bitWidth) + } + _log("** total shifted to \(total.hex)") + ri += 1 + } + let u = negativeResult ? ~total._lowUWord : total._lowUWord + _log("** product word \(p + q - 1) = \(u.hex)") + + if !product.replaceUWord(p + q - 1, with: u) { overflow = true } + if (product < 0) != negativeResult { overflow = true } + + return (product, overflow ? .Overflow : .None) + } + + static func multiply< + LHS: IntegerType, RHS: IntegerType + // FIXME: remove this constraint by refactoring IntegerType + where LHS.AbsoluteValue : IntegerType, RHS.AbsoluteValue : IntegerType + >(lhs: LHS, _ rhs: RHS) -> (Self, ArithmeticOverflow) { + return multiplyNonNegative( + lhs.absoluteValue, rhs.absoluteValue, + negativeResult: (lhs < 0) != (rhs < 0)) + } +} + +func *= < + LHS : IntegerType, RHS : IntegerType + // FIXME: remove this constraint by refactoring IntegerType + where LHS.AbsoluteValue : IntegerType, RHS.AbsoluteValue : IntegerType +>(inout lhs: LHS, rhs: RHS) { + + let (newLHS, overflow) = LHS.multiply(lhs, rhs) + _assertCond(overflow == .None, "Overflow in multiprecision in-place multiply") + lhs = newLHS +} //===--- Tests ------------------------------------------------------------===// + +extension IntegerType { + /// a hex representation of every bit in the number + func hexBits(bitWidth: Word) -> String { + let hexDigits: [UnicodeScalar] = [ + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", "A", "B", "C", "D", "E", "F"] + + var result = "".unicodeScalars + var x = self + var nibbles: Word = 0 + repeat { + if nibbles % 4 == 0 && nibbles != 0 { + result.insert("_", atIndex: result.startIndex) + } + let lowUWord = x.uword(0) + result.insert( + hexDigits[Swift.Int(lowUWord._storage) & 0xF], + atIndex: result.startIndex + ) + x.replaceUWord(0, with: lowUWord & ~0xF) + x /= 16 + nibbles += 1 + } + while (nibbles << 2 < bitWidth || (x != 0 && x + 1 != 0)) + return (self < 0 ? "[-]" : "[+]") + String(result) + } + + var hex: String { return hexBits(0) } +} + typealias DWord = Int${word_bits*2} typealias UDWord = UInt${word_bits*2} import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + +func expectEqual( + expected: T, _ actual: T, + @autoclosure _ message: () -> String = "", + showFrame: Bool = true, + stackTrace: SourceLocStack = SourceLocStack(), + file: String = __FILE__, line: UInt = __LINE__ +) { + if expected != actual { + expectationFailure( + "expected: \(String(reflecting: expected))" + + " (of type \(String(reflecting: expected.dynamicType)))\n" + + " = \(expected.hex)\n" + + "actual: \(String(reflecting: actual))" + + " (of type \(String(reflecting: actual.dynamicType)))\n" + + " = \(actual.hex)\n", + trace: message(), + stackTrace: stackTrace.pushIf(showFrame, file: file, line: line)) + } +} + +func expectEqual( + expected: (T, ArithmeticOverflow), _ actual: (T, ArithmeticOverflow), + @autoclosure _ message: () -> String = "", + showFrame: Bool = true, + stackTrace: SourceLocStack = SourceLocStack(), + file: String = __FILE__, line: UInt = __LINE__ +) { +% for i in 0, 1: + expectEqual( + expected.${i}, actual.${i}, message(), + showFrame: false, + stackTrace: stackTrace.pushIf(showFrame, file: file, line: line)) +% end +} + var tests = TestSuite("Integers") tests.test("Literals") { @@ -875,6 +1339,7 @@ tests.test("mostSignificantBit") { expectEqual(7, UInt8.max.mostSignificantBit) expectEqual(-1, UInt8.min.mostSignificantBit) expectEqual(6, Int8.max.mostSignificantBit) + expectEqual(-1, (0 as Int8).mostSignificantBit) expectEqual(6, Int8.min.mostSignificantBit) } @@ -1132,4 +1597,438 @@ tests.test("Basics") { expectEqual(32, Int32.bitWidth) } +tests.test("uword") { + let x = UDWord(Word.max) + expectEqual(Word.max._lowUWord, x.uword(0)) + expectEqual(0, x.uword(1)) + + let y = DWord(Word.min) + expectEqual(Word.min._lowUWord, y.uword(0)) + expectEqual(~0, y.uword(1)) + + let z = UWord(~Word.min) + 1 + expectEqual(Word.min._lowUWord, z.uword(0)) + expectEqual(0, z.uword(1)) +} + +tests.test("Multiprecision/+/DWord") { + var x = DWord.max - 2 + x += (1 as UInt8) + expectEqual(DWord.max - 1, x) + x += (-1 as Int8) + expectEqual(DWord.max - 2, x) + + x = DWord.min + x += (1 as UInt8) + expectEqual(DWord.min + 1, x) + + x += (-1 as Int8) + expectEqual(DWord.min, x) + + x = DWord(UWord.max) + x += (1 as Int8) + expectEqual(DWord(UWord.max) + 1, x) + x += (-1 as Int8) + expectEqual(DWord(UWord.max), x) + x += (1 as UDWord) + expectEqual(DWord(UWord.max) + 1, x) + + x = DWord(Word.max) + var overflow: ArithmeticOverflow + overflow = x.addInPlace(Word.min) + expectEqual(.None, overflow) + expectEqual(-1, x) + + overflow = x.addInPlace(DWord.min) + expectEqual(.Overflow, overflow) + expectEqual(DWord.max, x) + + overflow = x.addInPlace(1 as Word) + expectEqual(.Overflow, overflow) + expectEqual(DWord.min, x) + + x = 1 + overflow = x.addInPlace(DWord.max) + expectEqual(.Overflow, overflow) + expectEqual(DWord.min, x) +} + +tests.test("Multiprecision/+/UDWord") { + var x = UDWord.max - 2 + x += (1 as UInt8) + expectEqual(UDWord.max - 1, x) + x += (-1 as Int8) + expectEqual(UDWord.max - 2, x) + + x = UDWord.min + x += (1 as UInt8) + expectEqual(1, x) + + x += (-1 as Int8) + expectEqual(UDWord.min, x) + + x = UDWord(UWord.max) + x += (1 as Int8) + expectEqual(UDWord(UWord.max) + 1, x) + x += (-1 as Int8) + expectEqual(UDWord(UWord.max), x) + x += (1 as DWord) + expectEqual(UDWord(UWord.max) + 1, x) + x += (-1 as DWord) + expectEqual(UDWord(UWord.max), x) + + x = UDWord(Word.max) + var overflow: ArithmeticOverflow + overflow = x.addInPlace(Word.min) + expectEqual(.Overflow, overflow) + expectEqual(UDWord.max, x) + + overflow = x.addInPlace(DWord.min) + expectEqual(.None, overflow) + overflow = x.addInPlace(DWord.min) + expectEqual(.Overflow, overflow) + expectEqual(UDWord.max, x) + + overflow = x.addInPlace(1 as Int8) + expectEqual(.Overflow, overflow) + expectEqual(0, x) + + x = 1 + overflow = x.addInPlace(UDWord.max) + expectEqual(.Overflow, overflow) + expectEqual(0, x) +} + +tests.test("Multiprecision/-/DWord") { + var x = DWord.max - 2 + x -= (-1 as Int8) + expectEqual(DWord.max - 1, x) + x -= (1 as Int8) + expectEqual(DWord.max - 2, x) + + x = DWord.min + x -= (-1 as Int8) + expectEqual(DWord.min + 1, x) + + x -= (1 as Int8) + expectEqual(DWord.min, x) + + x = DWord(UWord.max) + x -= (-1 as Int8) + expectEqual(DWord(UWord.max) + 1, x) + x -= (1 as Int8) + expectEqual(DWord(UWord.max), x) + x -= (-1 as DWord) + expectEqual(DWord(UWord.max) + 1, x) + + x = DWord(Word.max) + var overflow: ArithmeticOverflow + overflow = x.subtractInPlace(UWord(~Word.min) + 1) + expectEqual(.None, overflow) + expectEqual(-1, x) + + overflow = x.subtractInPlace(UDWord(~DWord.min) + 1) + expectEqual(.Overflow, overflow) + expectEqual(DWord.max, x) + + overflow = x.subtractInPlace(-1 as Word) + expectEqual(.Overflow, overflow) + expectEqual(DWord.min, x) + + x = 1 + overflow = x.subtractInPlace(DWord.min + 1) + expectEqual(.Overflow, overflow) + expectEqual(DWord.min, x) +} + +tests.test("Multiprecision/-/UDWord") { + var x = UDWord.max - 2 + x -= (-1 as Int8) + expectEqual(UDWord.max - 1, x) + x -= (1 as UInt8) + expectEqual(UDWord.max - 2, x) + + x = UDWord.min + x -= (-1 as Int8) + expectEqual(1, x) + + x -= (1 as Int8) + expectEqual(UDWord.min, x) + + x = UDWord(UWord.max) + x -= (-1 as Int8) + expectEqual(UDWord(UWord.max) + 1, x) + x -= (1 as Int8) + expectEqual(UDWord(UWord.max), x) + x -= (-1 as DWord) + expectEqual(UDWord(UWord.max) + 1, x) + x -= (1 as DWord) + expectEqual(UDWord(UWord.max), x) + + x = UDWord(Word.max) + var overflow: ArithmeticOverflow + overflow = x.subtractInPlace(UWord(~Word.min) + 1) + expectEqual(.Overflow, overflow) + expectEqual(UDWord.max, x) + + overflow = x.subtractInPlace(UDWord(DWord.max) + 1) + expectEqual(.None, overflow) + overflow = x.subtractInPlace(UDWord(DWord.max) + 1) + expectEqual(.Overflow, overflow) + expectEqual(UDWord.max, x) + + overflow = x.subtractInPlace(DWord.max) + expectEqual(.None, overflow) + overflow = x.subtractInPlace(DWord.max) + expectEqual(.None, overflow) + expectEqual(1, x) + + overflow = x.subtractInPlace(2 as UDWord) + expectEqual(.Overflow, overflow) + expectEqual(UDWord.max, x) + + overflow = x.subtractInPlace(-1 as Int8) + expectEqual(.Overflow, overflow) + expectEqual(0, x) + + x = 1 + overflow = x.subtractInPlace(UDWord.max) + expectEqual(.Overflow, overflow) + expectEqual(2, x) +} + +tests.test("Multiprecision/+/Int16") { + var x = Int16.max - 2 + x += (1 as UDWord) + expectEqual(Int16.max - 1, x) + x += (-1 as DWord) + expectEqual(Int16.max - 2, x) + + x = Int16.min + x += (1 as UDWord) + expectEqual(Int16.min + 1, x) + + x += (-1 as DWord) + expectEqual(Int16.min, x) +} + +tests.test("Multiprecision/*/Int8") { + let uShift = Int8.bitWidth - 1 + expectEqual((42, .None), Int8.multiply(7 as Int8, 6 as Int8)) + expectEqual((42, .None), Int8.multiply(-7 as Int8, -6 as Int8)) + expectEqual((-42, .None), Int8.multiply(-7 as DWord, 6 as Int8)) + expectEqual((-42, .None), Int8.multiply(7 as Int8, -6 as DWord)) + + expectEqual((UInt8.max - 1, .None), UInt8.multiply(Int8.max, 2 as Int8)) + expectEqual((UInt8.max - 1, .None), UInt8.multiply(-Int8.max, -2 as Int8)) + expectEqual( + (0, .Overflow), + UInt8.multiply((1 as UInt8) << (UInt8.bitWidth - 1), 2 as Int8)) + + expectEqual( + (Int8.max - 1, .None), + Int8.multiply(Int8.max >> 1, 2 as Int8)) + + expectEqual( + (Int8.max - 1, .None), + Int8.multiply(-(Int8.max >> 1), -2 as Int8)) + + expectEqual( + (-Int8.max + 1, .None), + Int8.multiply(-(Int8.max >> 1), 2 as Int8)) + + let shift = Int8.bitWidth - 2 + expectEqual( + (Int8.min, .Overflow), + Int8.multiply((1 << shift) as Int8, 2 as Int8)) + + expectEqual( + (Int8.min, .Overflow), + Int8.multiply(-(1 << shift) as Int8, -2 as Int8)) + + expectEqual( + (Int8.min, .None), Int8.multiply((1 << shift) as Int8, -2 as Int8)) + + expectEqual( + (Int8.min, .None), Int8.multiply(-(1 << shift) as Int8, 2 as Int8)) +} + +tests.test("Multiprecision/*/Word") { + expectEqual((42, .None), Word.multiply(7 as Word, 6 as Word)) + expectEqual((42, .None), Word.multiply(-7 as Word, -6 as Word)) + expectEqual((-42, .None), Word.multiply(-7 as DWord, 6 as Word)) + expectEqual((-42, .None), Word.multiply(7 as Word, -6 as DWord)) + + expectEqual((UWord.max - 1, .None), UWord.multiply(Word.max, 2 as Word)) + expectEqual((UWord.max - 1, .None), UWord.multiply(-Word.max, -2 as Word)) + expectEqual( + (0, .Overflow), + UWord.multiply((1 as UWord) << (UWord.bitWidth - 1), 2 as Word)) + + expectEqual( + (Word.max - 1, .None), + Word.multiply(Word.max >> 1, 2 as Word)) + + expectEqual( + (Word.max - 1, .None), + Word.multiply(-(Word.max >> 1), -2 as Word)) + + expectEqual( + (-Word.max + 1, .None), + Word.multiply(-(Word.max >> 1), 2 as Word)) + + let shift = Word.bitWidth - 2 + expectEqual( + (Word.min, .Overflow), + Word.multiply((1 << shift) as Word, 2 as Word)) + + expectEqual( + (Word.min, .Overflow), + Word.multiply(-(1 << shift) as Word, -2 as Word)) + + expectEqual( + (Word.min, .None), + Word.multiply((1 << shift) as Word, -2 as Word)) + + expectEqual( + (Word.min, .None), + Word.multiply(-(1 << shift) as Word, 2 as Word)) +} + +tests.test("Multiprecision/*/DWord") { + let uShift = DWord.bitWidth - 1 + expectEqual((42, .None), DWord.multiply(7 as DWord, 6 as DWord)) + expectEqual((42, .None), DWord.multiply(-7 as DWord, -6 as DWord)) + expectEqual((-42, .None), DWord.multiply(-7 as DWord, 6 as DWord)) + expectEqual((-42, .None), DWord.multiply(7 as DWord, -6 as DWord)) + + expectEqual((UDWord.max - 1, .None), UDWord.multiply(DWord.max, 2 as DWord)) + expectEqual((UDWord.max - 1, .None), UDWord.multiply(-DWord.max, -2 as DWord)) + expectEqual( + (0, .Overflow), + UDWord.multiply((1 as UDWord) << (UDWord.bitWidth - 1), 2 as DWord)) + + expectEqual( + (DWord.max - 1, .None), + DWord.multiply(DWord.max >> 1, 2 as DWord)) + + expectEqual( + (DWord.max - 1, .None), + DWord.multiply(-(DWord.max >> 1), -2 as DWord)) + + expectEqual( + (-DWord.max + 1, .None), + DWord.multiply(-(DWord.max >> 1), 2 as DWord)) + + let shift = DWord.bitWidth - 2 + expectEqual( + (DWord.min, .Overflow), + DWord.multiply((1 << shift) as DWord, 2 as DWord)) + + expectEqual( + (DWord.min, .Overflow), + DWord.multiply(-(1 << shift) as DWord, -2 as DWord)) + + expectEqual( + (DWord.min, .None), + DWord.multiply((1 << shift) as DWord, -2 as DWord)) + + expectEqual( + (DWord.min, .None), + DWord.multiply(-(1 << shift) as DWord, 2 as DWord)) + + expectEqual( + ((-2 << Word.bitWidth) + 1, .Overflow), + DWord.multiply(UWord.max, UWord.max)) +} + +tests.test("Multiprecision/Overflow/+/Int16") { + var x = Int16.max - 1 + x += 1 as UInt16 + expectCrashLater() + x += 1 as UInt16 +} + +tests.test("Multiprecision/Underflow/+/Int16") { + var x = Int16.min + 1 + x += -1 as Int32 + expectCrashLater() + x += -1 as Int32 +} + + +tests.test("Multiprecision/Overflow/+/UInt16") { + var x = UInt16.max - 1 + x += 1 as Int16 + expectCrashLater() + x += 1 as Int16 +} + +tests.test("Multiprecision/Underflow/+/UInt16") { + var x = UInt16.min + 1 + x += -1 as DWord + expectCrashLater() + x += -1 as DWord +} + + +tests.test("Multiprecision/Overflow/+/Word") { + var x = Word.max - 1 + x += 1 as UWord + expectCrashLater() + x += 1 as UWord +} + +tests.test("Multiprecision/Underflow/+/Word") { + var x = Word.min + 1 + x += -1 as Int32 + expectCrashLater() + x += -1 as Int32 +} + + +tests.test("Multiprecision/Overflow/+/UWord") { + var x = UWord.max - 1 + x += 1 as Word + expectCrashLater() + x += 1 as Word +} + +tests.test("Multiprecision/Underflow/+/UWord") { + var x = UWord.min + 1 + x += -1 as DWord + expectCrashLater() + x += -1 as DWord +} + +tests.test("Multiprecision/Overflow/+/DWord") { + var x = DWord.max - 1 + x += 1 as UWord + expectCrashLater() + x += 1 as UWord +} + +tests.test("Multiprecision/Underflow/+/DWord") { + var x = DWord.min + 1 + x += -1 as Int32 + expectCrashLater() + x += -1 as Int32 +} + + +tests.test("Multiprecision/Overflow/+/UDWord") { + var x = UDWord.max - 1 + x += 1 as Word + expectCrashLater() + x += 1 as Word +} + +tests.test("Multiprecision/Underflow/+/UDWord") { + var x = UDWord.min + 1 + x += -1 as DWord + expectCrashLater() + x += -1 as DWord +} + + runAllTests() diff --git a/test/Prototypes/MutableIndexableDict.swift b/test/Prototypes/MutableIndexableDict.swift index 06496d288cbeb..b7b425dffa7b0 100644 --- a/test/Prototypes/MutableIndexableDict.swift +++ b/test/Prototypes/MutableIndexableDict.swift @@ -200,7 +200,7 @@ struct DictionaryIndex : BidirectionalIndexType { break } // end workaround - ++i + i += 1 } return Index(buffer: buffer, offset: i) } diff --git a/test/Prototypes/Result.swift b/test/Prototypes/Result.swift index 98c1e0b62426d..b2d2b4b4d2f2c 100644 --- a/test/Prototypes/Result.swift +++ b/test/Prototypes/Result.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -24,14 +24,14 @@ case Error(ErrorType) self = Error(error) } - func map(@noescape transform: (Value)->U) -> Result { + func map(@noescape transform: (Value) -> U) -> Result { switch self { case Success(let x): return .Success(transform(x)) case Error(let e): return .Error(e) } } - func flatMap(@noescape transform: (Value)->Result) -> Result { + func flatMap(@noescape transform: (Value) -> Result) -> Result { switch self { case Success(let x): return transform(x) case Error(let e): return .Error(e) diff --git a/test/Prototypes/TextFormatting.swift b/test/Prototypes/TextFormatting.swift index 17d863c9bace2..49fedd2add0e6 100644 --- a/test/Prototypes/TextFormatting.swift +++ b/test/Prototypes/TextFormatting.swift @@ -217,19 +217,19 @@ func _writeSigned( if value == 0 { result = "0" - ++width + width += 1 } else { var absVal = abs(value) if (value < 0) { target.append("-") - ++width + width += 1 } width += _writePositive(absVal, &result, args) } while width < args.width { - ++width + width += 1 target.append(args.fill) } target.append(result) diff --git a/test/SIL/Parser/apply_with_conformance.sil b/test/SIL/Parser/apply_with_conformance.sil index 023ed03ae5fe1..7567f484516c9 100644 --- a/test/SIL/Parser/apply_with_conformance.sil +++ b/test/SIL/Parser/apply_with_conformance.sil @@ -28,9 +28,9 @@ bb0(%0 : $S, %1 : $X): // function_ref test.S.foo (test.S)(A) -> () %4 = function_ref @_TFV4test1S3foofS0_US_1P__FQ_T_ : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, S) -> () // user: %7 %5 = alloc_stack $X // users: %6, %7, %8 - store %1 to %5#1 : $*X // id: %6 - %7 = apply %4(%5#1, %0) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, S) -> () - dealloc_stack %5#0 : $*@local_storage X // id: %8 + store %1 to %5 : $*X // id: %6 + %7 = apply %4(%5, %0) : $@convention(method) <τ_0_0 where τ_0_0 : P> (@in τ_0_0, S) -> () + dealloc_stack %5 : $*X // id: %8 %9 = tuple () // user: %10 return %9 : $() // id: %10 } diff --git a/test/SIL/Parser/apply_with_substitution.sil b/test/SIL/Parser/apply_with_substitution.sil index 7c9599effeb9e..2be6f3e751d10 100644 --- a/test/SIL/Parser/apply_with_substitution.sil +++ b/test/SIL/Parser/apply_with_substitution.sil @@ -14,31 +14,31 @@ bb0(%0 : $Optional<() -> ()>): %3 = alloc_stack $Optional<()> // users: %22, %28, %30, %31 %4 = alloc_stack $() // users: %12, %22, %25 %5 = alloc_stack $Optional<() -> ()> // users: %6, %8, %10, %11, %16, %24 - copy_addr %1#1 to [initialization] %5#1 : $*Optional<() -> ()> // id: %6 + copy_addr %1#1 to [initialization] %5 : $*Optional<() -> ()> // id: %6 %7 = function_ref @_TFs22_doesOptionalHaveValueU__FT1vRGSqQ___Bi1_ : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 // user: %8 - %8 = apply %7<() -> ()>(%5#1) : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 // user: %9 + %8 = apply %7<() -> ()>(%5) : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 // user: %9 br bb2 // id: %13 bb2: // Preds: bb0 %14 = function_ref @_TFs17_getOptionalValueU__FT1vGSqQ___Q_ : $@convention(thin) <τ_0_0> (@out τ_0_0, @in Optional<τ_0_0>) -> () // user: %16 %15 = alloc_stack $@callee_owned (@out (), @in ()) -> () // users: %16, %17, %23 - // CHECK: apply %{{[0-9]+}}<() -> ()>(%{{[0-9]+}}#1, %{{[0-9]+}}#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in Optional<τ_0_0>) -> () - %16 = apply %14<() -> ()>(%15#1, %5#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in Optional<τ_0_0>) -> () - %17 = load %15#1 : $*@callee_owned (@out (), @in ()) -> () // user: %19 + // CHECK: apply %{{[0-9]+}}<() -> ()>(%{{[0-9]+}}, %{{[0-9]+}}) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in Optional<τ_0_0>) -> () + %16 = apply %14<() -> ()>(%15, %5) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in Optional<τ_0_0>) -> () + %17 = load %15 : $*@callee_owned (@out (), @in ()) -> () // user: %19 %18 = function_ref @_TTRXFo_iT__iT__XFo__dT__ : $@convention(thin) (@owned @callee_owned (@out (), @in ()) -> ()) -> () // user: %19 %19 = partial_apply %18(%17) : $@convention(thin) (@owned @callee_owned (@out (), @in ()) -> ()) -> () // user: %20 %20 = apply %19() : $@callee_owned () -> () %21 = function_ref @_TFs24_injectValueIntoOptionalU__FT1vQ__GSqQ__ : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0) -> () // user: %22 - // CHECK: apply %{{[0-9]+}}<()>(%{{[0-9]+}}#1, %{{[0-9]+}}#1) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0) -> () - %22 = apply %21<()>(%3#1, %4#1) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0) -> () - dealloc_stack %15#0 : $*@local_storage @callee_owned (@out (), @in ()) -> () // id: %23 - dealloc_stack %5#0 : $*@local_storage Optional<() -> ()> // id: %24 - dealloc_stack %4#0 : $*@local_storage () // id: %25 + // CHECK: apply %{{[0-9]+}}<()>(%{{[0-9]+}}, %{{[0-9]+}}) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0) -> () + %22 = apply %21<()>(%3, %4) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0) -> () + dealloc_stack %15 : $*@callee_owned (@out (), @in ()) -> () // id: %23 + dealloc_stack %5 : $*Optional<() -> ()> // id: %24 + dealloc_stack %4 : $*() // id: %25 br bb4 // id: %26 bb4: // Preds: bb2 bb3 - %30 = load %3#1 : $*Optional<()> - dealloc_stack %3#0 : $*@local_storage Optional<()> // id: %31 + %30 = load %3 : $*Optional<()> + dealloc_stack %3 : $*Optional<()> // id: %31 strong_release %1#0 : $@box Optional<() -> ()> %33 = tuple () // user: %34 return %33 : $() // id: %34 diff --git a/test/SIL/Parser/attributes.sil b/test/SIL/Parser/attributes.sil new file mode 100644 index 0000000000000..c3aad2f791574 --- /dev/null +++ b/test/SIL/Parser/attributes.sil @@ -0,0 +1,7 @@ +// RUN: %target-sil-opt %s | FileCheck %s + +// CHECK-LABEL: sil [_semantics "123"] [_semantics "456"] @foo : $@convention(thin) () -> () { +sil [_semantics "123"] [_semantics "456"] @foo : $@convention(thin) () -> () { +bb0: + return undef : $() +} diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil index f9a1cc07ed958..5fc31fa593a88 100644 --- a/test/SIL/Parser/basic.sil +++ b/test/SIL/Parser/basic.sil @@ -1,7 +1,5 @@ // RUN: %target-swift-frontend %s -emit-silgen | FileCheck %s -// XFAIL: linux - sil_stage raw // CHECK: sil_stage raw import Builtin @@ -80,22 +78,22 @@ sil @named_tuple : $() -> (x: Builtin.Word, Builtin.Word) { sil @return_int : $@convention(thin) (Int) -> Int { // CHECK: $@convention(thin) (Int) -> Int { bb0(%0 : $Int): // CHECK: bb0(%0 : $Int): %1 = alloc_stack $Int // CHECK: alloc_stack $Int - store %0 to %1#1 : $*Int // CHECK: store %0 to %1#1 : $*Int - %3 = load %1#1 : $*Int // CHECK: load {{.*}} : $*Int - dealloc_stack %1#0 : $*@local_storage Int // CHECK: dealloc_stack {{.*}} : $*@local_storage Int + store %0 to %1 : $*Int // CHECK: store %0 to %1 : $*Int + %3 = load %1 : $*Int // CHECK: load {{.*}} : $*Int + dealloc_stack %1 : $*Int // CHECK: dealloc_stack {{.*}} : $*Int return %3 : $Int // CHECK: return {{.*}} : $Int } sil @call_fn_pointer : $@convention(thin) (() -> Int) -> Int { bb0(%0 : $() -> Int): %1 = alloc_stack $() -> Int // CHECK: alloc_stack $() -> Int - store %0 to %1#1 : $*() -> Int // CHECK: store %0 to %1#1 : $*() -> Int - %3 = load %1#1 : $*() -> Int // CHECK: load %1#1 : $*() -> Int + store %0 to %1 : $*() -> Int // CHECK: store %0 to %1 : $*() -> Int + %3 = load %1 : $*() -> Int // CHECK: load %1 : $*() -> Int strong_retain %3 : $() -> Int // CHECK: strong_retain %3 : $() -> Int %5 = apply %3() : $() -> Int // CHECK: apply %3() : $() -> Int - %6 = load %1#1 : $*() -> Int // CHECK: load %1#1 : $*() -> Int + %6 = load %1 : $*() -> Int // CHECK: load %1 : $*() -> Int strong_release %3 : $() -> Int // CHECK: release {{.*}} : $() -> Int - dealloc_stack %1#0 : $*@local_storage () -> Int // CHECK: dealloc_stack %1#0 : $*@local_storage () -> Int + dealloc_stack %1 : $*() -> Int // CHECK: dealloc_stack %1 : $*() -> Int return %5 : $Int // CHECK: return %5 : $Int } @@ -130,11 +128,11 @@ bb0(%0 : $Bool): // CHECK: alloc_stack $Bool %1 = alloc_stack $Bool // CHECK: store - %2 = store %0 to %1#1 : $*Bool + %2 = store %0 to %1 : $*Bool // CHECK: function_ref @_TSb13getLogicValuefRSbFT_Bi1_ : $@convention(method) (@inout Bool) -> Builtin.Int1 %3 = function_ref @_TSb13getLogicValuefRSbFT_Bi1_ : $@convention(method) (@inout Bool) -> Builtin.Int1 // CHECK: apply - %4 = apply %3(%1#1) : $@convention(method) (@inout Bool) -> Builtin.Int1 + %4 = apply %3(%1) : $@convention(method) (@inout Bool) -> Builtin.Int1 // CHECK: cond_br %5 = cond_br %4, bb1, bb2 @@ -149,7 +147,7 @@ bb1: // CHECK: apply %9 = apply %6(%8, %7) : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int // CHECK: dealloc_stack - %10 = dealloc_stack %1#0 : $*@local_storage Bool + %10 = dealloc_stack %1 : $*Bool // CHECK: br br bb3(%9 : $Int) @@ -164,7 +162,7 @@ bb2: // CHECK: apply %15 = apply %12(%14, %13) : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int // CHECK: dealloc_stack - %16 = dealloc_stack %1#0 : $*@local_storage Bool + %16 = dealloc_stack %1 : $*Bool // CHECK: br br bb3(%15 : $Int) @@ -265,12 +263,12 @@ bb0(%0 : $*T): // C/HECK: witness_method $*T, #Runcible.associated_method!1 %4 = witness_method $*T, #Runcible.associated_method!1 : $@cc(method) (@inout T) -> @thick T.U.Type %5 = apply %4(%0) : $@cc(method) (@inout T) -> @thick T.U.Type - %6 = store %5 to %3#1 : $*@thick T.U.Type + %6 = store %5 to %3 : $*@thick T.U.Type %7 = metatype $@thick T.Type // C/HECK: witness_method [volatile] $*T, #Runcible.static_method!1 %8 = witness_method [volatile] $*T, #Runcible.static_method!1 : $(@thick T.Type) -> () %9 = apply %8(%7) : $(@thick T.Type) -> () - %10 = dealloc_stack %3#0 : $*@local_storage @thick T.U.Type + %10 = dealloc_stack %3 : $*@thick T.U.Type %11 = tuple () %12 = destroy_addr %0 : $*T %13 = return %11 : $() @@ -289,12 +287,12 @@ bb0(%0 : $*Runcible, %1 : $*protocol): // CHECK: alloc_stack %4 = alloc_stack $protocol // CHECK: copy_addr {{.*}} to [initialization] {{.*}} : $*protocol - %5 = copy_addr %2#1 to [initialization] %4#1 : $*protocol + %5 = copy_addr %2#1 to [initialization] %4 : $*protocol %7 = tuple () // CHECK: destroy_addr - %8 = destroy_addr %4#1 : $*protocol + %8 = destroy_addr %4 : $*protocol // CHECK: dealloc_stack - %9 = dealloc_stack %4#0 : $*@local_storage protocol + %9 = dealloc_stack %4 : $*protocol // CHECK: release %10 = strong_release %2#0 : $@box protocol // CHECK: return @@ -329,8 +327,8 @@ struct Val { sil @_TV4todo3ValCfMS0_FT_S0_ : $@convention(thin) (@thin Val.Type) -> Val { bb0(%0 : $@thin Val.Type): %1 = alloc_stack $Val // CHECK: alloc_stack - %3 = load %1#1 : $*Val - dealloc_stack %1#0 : $*@local_storage Val + %3 = load %1 : $*Val + dealloc_stack %1 : $*Val %4 = return %3 : $Val } @@ -579,12 +577,12 @@ bb0(%0 : $*T): %2 = copy_addr [take] %0 to [initialization] %1#1 : $*T %3 = metatype $@thick T.Type // CHECK: metatype %5 = alloc_stack $T // CHECK: alloc_stack - %6 = copy_addr %1#1 to [initialization] %5#1 : $*T + %6 = copy_addr %1#1 to [initialization] %5 : $*T // CHECK: value_metatype $@thick T.Type, {{%.*}} : $*T - %7 = value_metatype $@thick T.Type, %5#1 : $*T + %7 = value_metatype $@thick T.Type, %5 : $*T %8 = tuple (%3 : $@thick T.Type, %7 : $@thick T.Type) // CHECK: tuple - %9 = destroy_addr %5#1 : $*T - %10 = dealloc_stack %5#0 : $*@local_storage T + %9 = destroy_addr %5 : $*T + %10 = dealloc_stack %5 : $*T %11 = strong_release %1#0 : $@box T %12 = return %8 : $(@thick T.Type, @thick T.Type) } @@ -594,11 +592,11 @@ bb0(%0 : $*SomeProtocol): %1 = alloc_box $SomeProtocol // CHECK: alloc_box %2 = copy_addr [take] %0 to [initialization] %1#1 : $*SomeProtocol %4 = alloc_stack $SomeProtocol // CHECK: alloc_stack - %5 = copy_addr %1#1 to [initialization] %4#1 : $*SomeProtocol + %5 = copy_addr %1#1 to [initialization] %4 : $*SomeProtocol // CHECK: existential_metatype $@thick SomeProtocol.Type, {{%.*}} : $*SomeProtocol - %6 = existential_metatype $@thick SomeProtocol.Type, %4#1 : $*SomeProtocol - %7 = destroy_addr %4#1 : $*SomeProtocol - %8 = dealloc_stack %4#0 : $*@local_storage SomeProtocol + %6 = existential_metatype $@thick SomeProtocol.Type, %4 : $*SomeProtocol + %7 = destroy_addr %4 : $*SomeProtocol + %8 = dealloc_stack %4 : $*SomeProtocol %9 = strong_release %1#0 : $@box SomeProtocol %10 = return %6 : $@thick SomeProtocol.Type } @@ -1064,35 +1062,35 @@ bb0(%0 : $Int32, %1 : $Int32, %2 : $Foo): %3 = tuple () %4 = alloc_stack $Int32 // var x // users: %17, %6 %5 = alloc_stack $Int32 // var y // users: %16, %7 - store %0 to %4#1 : $*Int32 - store %1 to %5#1 : $*Int32 + store %0 to %4 : $*Int32 + store %1 to %5 : $*Int32 %8 = alloc_stack $Foo // var self // users: %15, %14, %9 - store %2 to %8#1 : $*Foo + store %2 to %8 : $*Foo %10 = metatype $@thin Int32.Type %12 = integer_literal $Builtin.Int32, 0 // user: %13 %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %18 - destroy_addr %8#1 : $*Foo - dealloc_stack %8#0 : $*@local_storage Foo - dealloc_stack %5#0 : $*@local_storage Int32 - dealloc_stack %4#0 : $*@local_storage Int32 + destroy_addr %8 : $*Foo + dealloc_stack %8 : $*Foo + dealloc_stack %5 : $*Int32 + dealloc_stack %4 : $*Int32 return %13 : $Int32 } sil @_TFC3tmp3Foos9subscriptFTVs5Int32S1__S1_ : $@convention(method) (Int32, Int32, Int32, Foo) -> () { bb0(%0 : $Int32, %1 : $Int32, %2 : $Int32, %3 : $Foo): %4 = alloc_stack $Int32 // var value // users: %16, %5 - store %0 to %4#1 : $*Int32 + store %0 to %4 : $*Int32 %6 = alloc_stack $Int32 // var x // users: %15, %8 %7 = alloc_stack $Int32 // var y // users: %14, %9 - store %1 to %6#1 : $*Int32 - store %2 to %7#1 : $*Int32 + store %1 to %6 : $*Int32 + store %2 to %7 : $*Int32 %10 = alloc_stack $Foo // var self // users: %13, %12, %11 - store %3 to %10#1 : $*Foo - destroy_addr %10#1 : $*Foo - dealloc_stack %10#0 : $*@local_storage Foo - dealloc_stack %7#0 : $*@local_storage Int32 - dealloc_stack %6#0 : $*@local_storage Int32 - dealloc_stack %4#0 : $*@local_storage Int32 + store %3 to %10 : $*Foo + destroy_addr %10 : $*Foo + dealloc_stack %10 : $*Foo + dealloc_stack %7 : $*Int32 + dealloc_stack %6 : $*Int32 + dealloc_stack %4 : $*Int32 %17 = tuple () // user: %18 return %17 : $() } @@ -1155,21 +1153,21 @@ sil @block_storage_type : $@convention(thin) Int -> @convention(block) () -> () entry(%0 : $Int): // CHECK: [[STORAGE:%.*]] = alloc_stack $@block_storage Int %s = alloc_stack $@block_storage Int - // CHECK: [[PROJECT:%.*]] = project_block_storage [[STORAGE]]#1 : $*@block_storage Int - %c = project_block_storage %s#1 : $*@block_storage Int + // CHECK: [[PROJECT:%.*]] = project_block_storage [[STORAGE]] : $*@block_storage Int + %c = project_block_storage %s : $*@block_storage Int // CHECK: store %0 to [[PROJECT]] store %0 to %c : $*Int // CHECK: [[FUNC:%.*]] = function_ref - %f = function_ref @block_invoke : $@convention(c) (@inout @block_storage Int) -> () - // CHECK: [[BLOCK:%.*]] = init_block_storage_header [[STORAGE]]#1 : $*@block_storage Int, invoke [[FUNC]] : $@convention(c) (@inout @block_storage Int) -> (), type $@convention(block) () -> () - %b = init_block_storage_header %s#1 : $*@block_storage Int, invoke %f : $@convention(c) (@inout @block_storage Int) -> (), type $@convention(block) () -> () - // CHECK: dealloc_stack [[STORAGE]]#0 : $*@local_storage @block_storage Int - dealloc_stack %s#0 : $*@local_storage @block_storage Int + %f = function_ref @block_invoke : $@convention(c) (@inout_aliasable @block_storage Int) -> () + // CHECK: [[BLOCK:%.*]] = init_block_storage_header [[STORAGE]] : $*@block_storage Int, invoke [[FUNC]] : $@convention(c) (@inout_aliasable @block_storage Int) -> (), type $@convention(block) () -> () + %b = init_block_storage_header %s : $*@block_storage Int, invoke %f : $@convention(c) (@inout_aliasable @block_storage Int) -> (), type $@convention(block) () -> () + // CHECK: dealloc_stack [[STORAGE]] : $*@block_storage Int + dealloc_stack %s : $*@block_storage Int // CHECK: return [[BLOCK]] : $@convention(block) () -> () return %b : $@convention(block) () -> () } -sil @block_invoke : $@convention(c) (@inout @block_storage Int) -> () { +sil @block_invoke : $@convention(c) (@inout_aliasable @block_storage Int) -> () { entry(%0 : $*@block_storage Int): return undef : $() } diff --git a/test/SIL/Parser/bound_generic.sil b/test/SIL/Parser/bound_generic.sil index 694ebd9877dde..96ea496cc9202 100644 --- a/test/SIL/Parser/bound_generic.sil +++ b/test/SIL/Parser/bound_generic.sil @@ -14,28 +14,28 @@ bb0(%0 : $Optional<() -> ()>): %3 = alloc_stack $Optional<()> %4 = alloc_stack $() %5 = alloc_stack $Optional<() -> ()> - copy_addr %1#1 to [initialization] %5#1 : $*Optional<() -> ()> + copy_addr %1#1 to [initialization] %5 : $*Optional<() -> ()> // function_ref Swift._doesOptionalHaveValue (v : @inout Swift.Optional) -> Builtin.Int1 %7 = function_ref @_TFs22_doesOptionalHaveValueU__FT1vRGSqQ___Bi1_ : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 - // CHECK: apply %{{[0-9]+}}<() -> ()>(%{{[0-9]+}}#1) : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 - %8 = apply %7<() -> ()>(%5#1) : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 + // CHECK: apply %{{[0-9]+}}<() -> ()>(%{{[0-9]+}}) : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 + %8 = apply %7<() -> ()>(%5) : $@convention(thin) <τ_0_0> (@inout Optional<τ_0_0>) -> Builtin.Int1 br bb1 bb1: - destroy_addr %5#1 : $*Optional<() -> ()> - dealloc_stack %5#0 : $*@local_storage Optional<() -> ()> - dealloc_stack %4#0 : $*@local_storage () + destroy_addr %5 : $*Optional<() -> ()> + dealloc_stack %5 : $*Optional<() -> ()> + dealloc_stack %4 : $*() br bb3 bb3: %27 = function_ref @_TFs26_injectNothingIntoOptionalU__FT_GSqQ__ : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>) -> () - // CHECK: apply %{{[0-9]+}}<()>(%{{[0-9]+}}#1) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>) -> () - %28 = apply %27<()>(%3#1) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>) -> () + // CHECK: apply %{{[0-9]+}}<()>(%{{[0-9]+}}) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>) -> () + %28 = apply %27<()>(%3) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>) -> () br bb4 bb4: - %30 = load %3#1 : $*Optional<()> - dealloc_stack %3#0 : $*@local_storage Optional<()> + %30 = load %3 : $*Optional<()> + dealloc_stack %3 : $*Optional<()> strong_release %1#0 : $@box Optional<() -> ()> %33 = tuple () return %33 : $() diff --git a/test/SIL/Parser/generic_signature_with_depth.swift b/test/SIL/Parser/generic_signature_with_depth.swift index 1a56638082a4f..371003cf09911 100644 --- a/test/SIL/Parser/generic_signature_with_depth.swift +++ b/test/SIL/Parser/generic_signature_with_depth.swift @@ -20,7 +20,7 @@ protocol mmExt : mmCollectionType { // CHECK-LABEL: @_TF28generic_signature_with_depth4testu0_RxS_5mmExt_S0_Wx9Generator7Element_zW_S1_S2__rFTxq__x : $@convention(thin) (@out EC1, @in EC1, @in EC2) -> () { // CHECK: witness_method $EC1, #mmExt.extend!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : mmExt, τ_0_0.Generator : mmGeneratorType><τ_1_0 where τ_1_0 : mmSequenceType, τ_1_0.Generator : mmGeneratorType, τ_1_0.Generator.Element == τ_0_0.Generator.Element> (@in τ_1_0, @inout τ_0_0) -> () -// CHECK: apply {{%[0-9]+}}(%{{[0-9]+}}#1, %{{[0-9]+}}#1) : $@convention(witness_method) <τ_0_0 where τ_0_0 : mmExt, τ_0_0.Generator : mmGeneratorType><τ_1_0 where τ_1_0 : mmSequenceType, τ_1_0.Generator : mmGeneratorType, τ_1_0.Generator.Element == τ_0_0.Generator.Element> (@in τ_1_0, @inout τ_0_0) -> () +// CHECK: apply {{%[0-9]+}}(%{{[0-9]+}}, %{{[0-9]+}}#1) : $@convention(witness_method) <τ_0_0 where τ_0_0 : mmExt, τ_0_0.Generator : mmGeneratorType><τ_1_0 where τ_1_0 : mmSequenceType, τ_1_0.Generator : mmGeneratorType, τ_1_0.Generator.Element == τ_0_0.Generator.Element> (@in τ_1_0, @inout τ_0_0) -> () func test< EC1 : mmExt, diff --git a/test/SIL/Parser/generics.sil b/test/SIL/Parser/generics.sil index 30d9a9a265d4a..193f04526de0b 100644 --- a/test/SIL/Parser/generics.sil +++ b/test/SIL/Parser/generics.sil @@ -19,42 +19,42 @@ struct Bas {} // CHECK-LABEL: sil @ref_foo_1 : $@convention(thin) () -> () { // CHECK: %2 = function_ref @foo : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () -// CHECK: %3 = apply %2(%1#1, %0#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () +// CHECK: %3 = apply %2(%1, %0) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () sil @ref_foo_1 : $@convention(thin) () -> () { entry: %i = alloc_stack $Bar %o = alloc_stack $Bar %f = function_ref @foo : $@convention(thin) (@out XYZ, @in XYZ) -> () - %z = apply %f(%o#1, %i#1) : $@convention(thin) (@out ZYX, @in ZYX) -> () - dealloc_stack %o#0 : $*@local_storage Bar - dealloc_stack %i#0 : $*@local_storage Bar + %z = apply %f(%o, %i) : $@convention(thin) (@out ZYX, @in ZYX) -> () + dealloc_stack %o : $*Bar + dealloc_stack %i : $*Bar return %z : $() } // CHECK-LABEL: sil @ref_foo_2 : $@convention(thin) () -> () { // CHECK: %2 = function_ref @foo : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () -// CHECK: %3 = apply %2(%1#1, %0#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () +// CHECK: %3 = apply %2(%1, %0) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () sil @ref_foo_2 : $@convention(thin) () -> () { entry: %i = alloc_stack $Bas %o = alloc_stack $Bas %f = function_ref @foo : $@convention(thin) (@out ABC, @in ABC) -> () - %z = apply %f(%o#1, %i#1) : $@convention(thin) (@out CBA, @in CBA) -> () - dealloc_stack %o#0 : $*@local_storage Bas - dealloc_stack %i#0 : $*@local_storage Bas + %z = apply %f(%o, %i) : $@convention(thin) (@out CBA, @in CBA) -> () + dealloc_stack %o : $*Bas + dealloc_stack %i : $*Bas return %z : $() } // CHECK-LABEL: sil @ref_foo_partial_apply : $@convention(thin) () -> @owned @callee_owned (@out Bas) -> () { // CHECK: %1 = function_ref @foo : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () -// CHECK: %2 = partial_apply %1(%0#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () +// CHECK: %2 = partial_apply %1(%0) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () // CHECK: return %2 : $@callee_owned (@out Bas) -> () sil @ref_foo_partial_apply : $@convention(thin) () -> @owned @callee_owned (@out Bas) -> () { entry: %i = alloc_stack $Bas %f = function_ref @foo : $@convention(thin) (@out Z, @in Z) -> () - %g = partial_apply %f(%i#1) : $@convention(thin) (@out Y, @in Y) -> () - dealloc_stack %i#0 : $*@local_storage Bas + %g = partial_apply %f(%i) : $@convention(thin) (@out Y, @in Y) -> () + dealloc_stack %i : $*Bas return %g : $@callee_owned (@out Bas) -> () } @@ -70,14 +70,14 @@ bb0: %3 = function_ref @_TF16generic_closures24generic_curried_functionU___FT1xQ__FT1yQ0__T_ : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0) -> @owned @callee_owned (@in τ_0_1) -> () %4 = load %1 : $*Builtin.Int64 %5 = alloc_stack $Builtin.Int64 - store %4 to %5#1 : $*Builtin.Int64 + store %4 to %5 : $*Builtin.Int64 // CHECK: apply %{{[0-9]+}}<{{.*}}Int64, {{.*}}Int32>(%{{.*}}) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0) -> @owned @callee_owned (@in τ_0_1) -> () - %7 = apply %3(%5#1) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0) -> @owned @callee_owned (@in τ_0_1) -> () + %7 = apply %3(%5) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0) -> @owned @callee_owned (@in τ_0_1) -> () %8 = function_ref @_TTRXFo_iBi32__dT__XFo_dBi32__dT__ : $@convention(thin) (Builtin.Int32, @owned @callee_owned (@in Builtin.Int32) -> ()) -> () // CHECK: partial_apply %{{[0-9]+}}(%{{[0-9]+}}) : $@convention(thin) (Builtin.Int32, @owned @callee_owned (@in Builtin.Int32) -> ()) -> () %9 = partial_apply %8(%7) : $@convention(thin) (Builtin.Int32, @owned @callee_owned (@in Builtin.Int32) -> ()) -> () store %9 to %2 : $*@callee_owned (Builtin.Int32) -> () - dealloc_stack %5#0 : $*@local_storage Builtin.Int64 + dealloc_stack %5 : $*Builtin.Int64 %12 = tuple () return %12 : $() } @@ -99,13 +99,13 @@ protocol FooProto { sil @protocol_extension_with_constrained_associated_type : $@convention(method) (@in I, @in_guaranteed Self) -> () { bb0(%0 : $*I, %1 : $*Self): %2 = alloc_stack $I // users: %3, %6, %7, %9 - copy_addr %0 to [initialization] %2#1 : $*I // id: %3 + copy_addr %0 to [initialization] %2 : $*I // id: %3 %4 = witness_method $I, #FooProto.value!getter.1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : FooProto, τ_0_0.Assoc : FooProtoHelper> (@out τ_0_0.Assoc, @in_guaranteed τ_0_0) -> () // user: %6 %5 = alloc_stack $Self.Assoc // users: %6, %8 - %6 = apply %4(%5#1, %2#1) : $@convention(witness_method) <τ_0_0 where τ_0_0 : FooProto, τ_0_0.Assoc : FooProtoHelper> (@out τ_0_0.Assoc, @in_guaranteed τ_0_0) -> () - destroy_addr %2#1 : $*I // id: %7 - dealloc_stack %5#0 : $*@local_storage Self.Assoc // id: %8 - dealloc_stack %2#0 : $*@local_storage I // id: %9 + %6 = apply %4(%5, %2) : $@convention(witness_method) <τ_0_0 where τ_0_0 : FooProto, τ_0_0.Assoc : FooProtoHelper> (@out τ_0_0.Assoc, @in_guaranteed τ_0_0) -> () + destroy_addr %2 : $*I // id: %7 + dealloc_stack %5 : $*Self.Assoc // id: %8 + dealloc_stack %2 : $*I // id: %9 destroy_addr %0 : $*I // id: %10 %11 = tuple () // user: %12 return %11 : $() // id: %12 diff --git a/test/SIL/Parser/polymorphic_function.sil b/test/SIL/Parser/polymorphic_function.sil index 7280efd50168f..126ada43c960d 100644 --- a/test/SIL/Parser/polymorphic_function.sil +++ b/test/SIL/Parser/polymorphic_function.sil @@ -15,10 +15,10 @@ public protocol mmStreamable { sil @test : $() -> () { bb0: %281 = alloc_stack $mmStreamable - %282 = open_existential_addr %281#1 : $*mmStreamable to $*@opened("01234567-89ab-cdef-0123-000000000000") mmStreamable + %282 = open_existential_addr %281 : $*mmStreamable to $*@opened("01234567-89ab-cdef-0123-000000000000") mmStreamable // CHECK: witness_method $@opened({{.*}}) mmStreamable, #mmStreamable.writeTo!1 %293 = witness_method $@opened("01234567-89ab-cdef-0123-000000000000") mmStreamable, #mmStreamable.writeTo!1, %282 : $*@opened("01234567-89ab-cdef-0123-000000000000") mmStreamable : $@convention(witness_method) @callee_owned (@inout T_1_0, @inout T_0_0) -> () - dealloc_stack %281#0 : $*@local_storage mmStreamable + dealloc_stack %281 : $*mmStreamable %1 = tuple () return %1 : $() } diff --git a/test/SIL/Parser/undef.sil b/test/SIL/Parser/undef.sil new file mode 100644 index 0000000000000..03a7b30189cd3 --- /dev/null +++ b/test/SIL/Parser/undef.sil @@ -0,0 +1,20 @@ +// RUN: %target-sil-opt %s | %target-sil-opt | FileCheck %s +sil_stage raw + +import Builtin +import Swift + +// CHECK-LABEL: sil @undef_in_switch_value_case : $@convention(thin) () -> () +sil @undef_in_switch_value_case : $@convention(thin) () -> () { +bb0: + %0 = integer_literal $Builtin.Int1, 0 + // CHECK: case undef: bb1 + switch_value %0 : $Builtin.Int1, case undef: bb1 +bb1: + %1 = function_ref @undef_in_switch_value_case : $@convention(thin) () -> () + // CHECK: case undef: bb2 + switch_value %1 : $@convention(thin) () -> (), case undef: bb2 +bb2: + %2 = tuple () + return %2 : $() +} diff --git a/test/SIL/Parser/unnamed_struct_identifiers.sil b/test/SIL/Parser/unnamed_struct_identifiers.sil index c78defed2d044..fecd0d1511ae3 100644 --- a/test/SIL/Parser/unnamed_struct_identifiers.sil +++ b/test/SIL/Parser/unnamed_struct_identifiers.sil @@ -20,10 +20,10 @@ bb0(%0 : $UnnamedStructs): %2 = function_ref @_TF4blah6typeofU__FQ_MQ_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @thick τ_0_0.Type // user: %6 %3 = struct_extract %0 : $UnnamedStructs, #UnnamedStructs.x // user: %5 %4 = alloc_stack $UnnamedStructs.__Unnamed_struct_x // users: %5, %6, %8 - store %3 to %4#1 : $*UnnamedStructs.__Unnamed_struct_x // id: %5 - %6 = apply %2(%4#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @thick τ_0_0.Type + store %3 to %4 : $*UnnamedStructs.__Unnamed_struct_x // id: %5 + %6 = apply %2(%4) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @thick τ_0_0.Type %7 = metatype $@thin UnnamedStructs.__Unnamed_struct_x.Type - dealloc_stack %4#0 : $*@local_storage UnnamedStructs.__Unnamed_struct_x // id: %8 + dealloc_stack %4 : $*UnnamedStructs.__Unnamed_struct_x // id: %8 %9 = tuple () // user: %10 return %9 : $() // id: %10 } diff --git a/test/SIL/Serialization/Inputs/clang_conformances.sil b/test/SIL/Serialization/Inputs/clang_conformances.sil index c6288d1e45884..48e497174792c 100644 --- a/test/SIL/Serialization/Inputs/clang_conformances.sil +++ b/test/SIL/Serialization/Inputs/clang_conformances.sil @@ -11,12 +11,12 @@ bb0: %0 = function_ref @_TFsoi2neUs9Equatable__FTQ_Q__Sb : $@convention(thin) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0) -> Bool // user: %7 %1 = alloc_stack $ComparisonResult // users: %3, %7, %9 %2 = enum $ComparisonResult, #ComparisonResult.Same!enumelt // user: %3 - store %2 to %1#1 : $*ComparisonResult // id: %3 + store %2 to %1 : $*ComparisonResult // id: %3 %4 = alloc_stack $ComparisonResult // users: %6, %7, %8 %5 = enum $ComparisonResult, #ComparisonResult.Same!enumelt // user: %6 - store %5 to %4#1 : $*ComparisonResult // id: %6 - %7 = apply %0(%1#1, %4#1) : $@convention(thin) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0) -> Bool // user: %10 - dealloc_stack %4#0 : $*@local_storage ComparisonResult // id: %8 - dealloc_stack %1#0 : $*@local_storage ComparisonResult // id: %9 + store %5 to %4 : $*ComparisonResult // id: %6 + %7 = apply %0(%1, %4) : $@convention(thin) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0) -> Bool // user: %10 + dealloc_stack %4 : $*ComparisonResult // id: %8 + dealloc_stack %1 : $*ComparisonResult // id: %9 return %7 : $Bool // id: %10 } diff --git a/test/SIL/Serialization/deserialize_appkit.sil b/test/SIL/Serialization/deserialize_appkit.sil index b4131884f5210..641954d92e62d 100644 --- a/test/SIL/Serialization/deserialize_appkit.sil +++ b/test/SIL/Serialization/deserialize_appkit.sil @@ -6,3 +6,5 @@ // REQUIRES: OS=macosx // CHECK-NOT: Unknown + +// REQUIRES: rdar://23805004 diff --git a/test/SIL/Serialization/deserialize_foundation.sil b/test/SIL/Serialization/deserialize_foundation.sil index 7659beed0da1a..b94ac4623b57f 100644 --- a/test/SIL/Serialization/deserialize_foundation.sil +++ b/test/SIL/Serialization/deserialize_foundation.sil @@ -5,3 +5,5 @@ // REQUIRES: objc_interop // CHECK-NOT: Unknown + +// REQUIRES: rdar://23805004 diff --git a/test/SIL/Serialization/function_param_convention.sil b/test/SIL/Serialization/function_param_convention.sil index facfa0d0e0606..5b89855e87ff9 100644 --- a/test/SIL/Serialization/function_param_convention.sil +++ b/test/SIL/Serialization/function_param_convention.sil @@ -14,10 +14,10 @@ sil @foo : $@convention(thin) (@out X, @in X, @inout X, @in_guaranteed X, @owned sil @foo_caller : $@convention(thin) () -> () { bb0: %0 = alloc_stack $X - %1 = load %0#1 : $*X + %1 = load %0 : $*X %2 = function_ref @foo : $@convention(thin) (@out X, @in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X, @deallocating X) -> () - apply %2(%0#1, %0#1, %0#1, %0#1, %1, %1, %1, %1) : $@convention(thin) (@out X, @in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X, @deallocating X) -> () - dealloc_stack %0#0 : $*@local_storage X + apply %2(%0, %0, %0, %0, %1, %1, %1, %1) : $@convention(thin) (@out X, @in X, @inout X, @in_guaranteed X, @owned X, X, @guaranteed X, @deallocating X) -> () + dealloc_stack %0 : $*X %9999 = tuple() return %9999 : $() } diff --git a/test/SIL/Serialization/semanticsattr.sil b/test/SIL/Serialization/semanticsattr.sil new file mode 100644 index 0000000000000..e6f4fc440a1ac --- /dev/null +++ b/test/SIL/Serialization/semanticsattr.sil @@ -0,0 +1,27 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: %target-swift-frontend -parse-sil -emit-sib -parse-as-library -parse-stdlib -module-name SemanticsAttr -o %t/SemanticsAttr.sib %s +// RUN: %target-sil-opt %t/SemanticsAttr.sib -o - | FileCheck %s + +sil_stage canonical + +import Builtin + +// CHECK: @_semantics("123") @_semantics("456") func semanticsFunction() -> Builtin.Int64 +@_semantics("123") @_semantics("456") +func semanticsFunction() -> Builtin.Int64 + +// CHECK: sil [_semantics "789"] [_semantics "ABC"] @foo1 : $@convention(thin) () -> () { +sil public [_semantics "789"] [_semantics "ABC"] @foo1 : $@convention(thin) () -> () { +bb0: + return undef : $() +} + +// Make sure that we can parse with multiple generics that are after the semantic attributes. +// +// CHECK: sil [_semantics "DEF"] [_semantics "GHI"] @foo2 : $@convention(thin) () -> () { +sil public [_semantics "DEF"] [_semantics "GHI"] @foo2 : $@convention(thin) () -> () { +bb0: + return undef : $() +} + diff --git a/test/SILAnalysis/basic-aa.sil b/test/SILAnalysis/basic-aa.sil deleted file mode 100644 index d574c7657ad21..0000000000000 --- a/test/SILAnalysis/basic-aa.sil +++ /dev/null @@ -1,517 +0,0 @@ -// RUN: %target-sil-opt %s -aa=basic-aa -aa-dump -o /dev/null | FileCheck %s - -// REQUIRES: asserts - -import Builtin -import Swift - -// Address Arguments don't alias if they are arguments to the first BB. -// -// CHECK-LABEL: @address_args_dont_alias_in_first_bb -// CHECK: PAIR #0. -// CHECK-NEXT: %0 = argument of bb0 : $*Builtin.NativeObject -// CHECK-NEXT: %0 = argument of bb0 : $*Builtin.NativeObject -// CHECK-NEXT: MustAlias -// CHECK: PAIR #1. -// CHECK-NEXT: %0 = argument of bb0 -// CHECK-NEXT: %1 = argument of bb0 -// CHECK-NEXT: NoAlias -sil @address_args_dont_alias_in_first_bb : $@convention(thin) (@inout Builtin.NativeObject, @inout Builtin.NativeObject) -> () { -bb0(%0 : $*Builtin.NativeObject, %1 : $*Builtin.NativeObject): - %2 = tuple() - return %2 : $() -} - -// Address Arguments may alias if they are arguments to a BB besides the first. -// -// FIXME: Once we support looking through PHIs, we will allow for must alias here. -// -// CHECK-LABEL: @address_args_may_alias_in_non_first_bb -// CHECK-NOT: NoAlias -sil @address_args_may_alias_in_non_first_bb : $@convention(thin) (@inout Builtin.NativeObject) -> () { -bb0(%0 : $*Builtin.NativeObject): - br bb1(%0 : $*Builtin.NativeObject, %0 : $*Builtin.NativeObject) - -bb1(%1 : $*Builtin.NativeObject, %2 : $*Builtin.NativeObject): - %3 = tuple() - return %3 : $() -} - -struct StructLvl2 { - var tup : (Builtin.Int64, Builtin.Int32) -} - -struct StructLvl1 { - var sub : StructLvl2 - var x : Builtin.Int64 -} - -// Two values with different underlying alloc_stack can not alias. -// -// CHECK-LABEL: @different_alloc_stack_dont_alias - -// @local_storage can not alias non @local_storage types. -// CHECK: PAIR #0. -// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: MustAlias -// CHECK: PAIR #1. -// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (1): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: NoAlias -// CHECK: PAIR #2. -// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %1 = alloc_stack $StructLvl1 -// CHECK-NEXT: NoAlias -// CHECK: PAIR #3. -// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (1): %1 = alloc_stack $StructLvl1 -// CHECK-NEXT: NoAlias -// CHECK: PAIR #4. -// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %2 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub -// CHECK-NEXT: NoAlias -// CHECK: PAIR #14. -// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %14 = tuple () -// CHECK-NEXT: MayAlias - -// CHECK: PAIR #15. -// CHECK-NEXT: (1): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (1): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: MustAlias -// CHECK: PAIR #16. -// CHECK-NEXT: (1): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %1 = alloc_stack $StructLvl1 -// CHECK-NEXT: NoAlias -// CHECK: PAIR #17. -// CHECK-NEXT: (1): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (1): %1 = alloc_stack $StructLvl1 -// CHECK-NEXT: NoAlias -// CHECK: PAIR #18. -// CHECK-NEXT: (1): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %2 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub -// CHECK-NEXT: PartialAlias -// CHECK: PAIR #19. -// CHECK-NEXT: (1): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %3 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.x -// CHECK-NEXT: PartialAlias -// CHECK: PAIR #20. -// CHECK-NEXT: (1): %0 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %4 = struct_element_addr %2 : $*StructLvl2, #StructLvl2.tup -// CHECK-NEXT: PartialAlias - -// CHECK: PAIR #50. -// CHECK-NEXT: (1): %1 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %9 = struct_element_addr %7 : $*StructLvl2, #StructLvl2.tup -// CHECK-NEXT: PartialAlias -// CHECK: PAIR #51. -// CHECK-NEXT: (1): %1 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %10 = tuple_element_addr %9 : $*(Builtin.Int64, Builtin.Int32), 0 -// CHECK-NEXT: PartialAlias -// CHECK: PAIR #52. -// CHECK-NEXT: (1): %1 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %11 = tuple_element_addr %9 : $*(Builtin.Int64, Builtin.Int32), 1 -// CHECK-NEXT: PartialAlias -// CHECK: PAIR #53. -// CHECK-NEXT: (1): %1 = alloc_stack $StructLvl1 -// CHECK-NEXT: (0): %14 = tuple () -// CHECK-NEXT: MayAlias -// CHECK: PAIR #55. -// CHECK-NEXT: (0): %2 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub -// CHECK-NEXT: (0): %3 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.x -// CHECK-NEXT: NoAlias -// CHECK: PAIR #56. -// CHECK-NEXT: (0): %2 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub -// CHECK-NEXT: (0): %4 = struct_element_addr %2 : $*StructLvl2, #StructLvl2.tup -// CHECK-NEXT: PartialAlias -// CHECK: PAIR #57. -// CHECK-NEXT: (0): %2 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub -// CHECK-NEXT: (0): %5 = tuple_element_addr %4 : $*(Builtin.Int64, Builtin.Int32), 0 -// CHECK-NEXT: PartialAlias -// CHECK: PAIR #58. -// CHECK-NEXT: (0): %2 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub -// CHECK-NEXT: (0): %6 = tuple_element_addr %4 : $*(Builtin.Int64, Builtin.Int32), 1 -// CHECK-NEXT: PartialAlias -sil @different_alloc_stack_dont_alias : $@convention(thin) () -> () { - %0 = alloc_stack $StructLvl1 - %1 = alloc_stack $StructLvl1 - - %2 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub - %3 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.x - %4 = struct_element_addr %2 : $*StructLvl2, #StructLvl2.tup - %5 = tuple_element_addr %4 : $*(Builtin.Int64, Builtin.Int32), 0 - %6 = tuple_element_addr %4 : $*(Builtin.Int64, Builtin.Int32), 1 - - %7 = struct_element_addr %1#1 : $*StructLvl1, #StructLvl1.sub - %8 = struct_element_addr %1#1 : $*StructLvl1, #StructLvl1.x - %9 = struct_element_addr %7 : $*StructLvl2, #StructLvl2.tup - %10 = tuple_element_addr %9 : $*(Builtin.Int64, Builtin.Int32), 0 - %11 = tuple_element_addr %9 : $*(Builtin.Int64, Builtin.Int32), 1 - - dealloc_stack %1#0 : $*@local_storage StructLvl1 - dealloc_stack %0#0 : $*@local_storage StructLvl1 - - %12 = tuple() - return %12 : $() -} - -// Function Arguments can not alias with no alias arguments or with identified -// function locals. -// -// @args_dont_alias_with_identified_function_locals -// CHECK: PAIR #1. -// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: MayAlias -// CHECK: PAIR #2. -// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %2 = argument of bb0 : $*Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #3. -// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #4. -// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #5. -// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %5 = tuple () -// CHECK-NEXT: MayAlias -// CHECK: PAIR #7. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %2 = argument of bb0 : $*Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #8. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #9. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #12. -// CHECK-NEXT: (0): %2 = argument of bb0 : $*Builtin.NativeObject -// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #13. -// CHECK-NEXT: (0): %2 = argument of bb0 : $*Builtin.NativeObject -// CHECK-NEXT: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -sil @args_dont_alias_with_identified_function_locals : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject, @inout Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject, %2 : $*Builtin.NativeObject): - %3 = alloc_stack $Builtin.NativeObject - dealloc_stack %3#0 : $*@local_storage Builtin.NativeObject - %4 = tuple() - return %4 : $() -} - -sil @create_native_object : $@convention(thin) () -> (Builtin.NativeObject) -sil @use_native_object : $@convention(thin) (Builtin.NativeObject) -> () - -// For this test, we care about the following results: -// %1, %3, %5, %7, %8, %9 -// Check every alias query involving those. - -// @escapesource_functionlocal_test_readwrite_nonescaping_alloca -// Test %0 - -// CHECK: PAIR #1. -// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject -// CHECK: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #3. -// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject -// CHECK: (1): %2 = alloc_stack $Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #5. -// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject -// CHECK: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #7. -// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject -// CHECK: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #10. -// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject -// CHECK: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #11. -// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject -// CHECK: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK: NoAlias - -// Test %1 (the aliasing argument) - -// CHECK: PAIR #13. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: MustAlias -// CHECK: PAIR #14. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %2 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #15. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (1): %2 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #16. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #17. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #19. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: MayAlias -// CHECK: PAIR #20. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %6 = load %0 : $*Builtin.NativeObject -// CHECK-NEXT: MayAlias -// CHECK: PAIR #22. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK-NEXT: MayAlias -// CHECK: PAIR #23. -// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject -// CHECK-NEXT: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK-NEXT: MayAlias - -// Test %2 -// CHECK: PAIR #38. -// CHECK: (1): %2 = alloc_stack $Builtin.NativeObject -// CHECK: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #40. -// CHECK: (1): %2 = alloc_stack $Builtin.NativeObject -// CHECK: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #41. -// CHECK: (1): %2 = alloc_stack $Builtin.NativeObject -// CHECK: (0): %6 = load %0 : $*Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #43. -// CHECK: (1): %2 = alloc_stack $Builtin.NativeObject -// CHECK: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK: NoAlias -// CHECK: PAIR #44. -// CHECK: (1): %2 = alloc_stack $Builtin.NativeObject -// CHECK: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK: NoAlias - -// Test %3 (the escaping alloca). - -// CHECK: PAIR #49. -// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #50. -// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: (0): %6 = load %0 : $*Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #52. -// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #53. -// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK-NEXT: NoAlias -// CHECK: PAIR #57. -// CHECK-NEXT: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #58. -// CHECK-NEXT: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: (0): %6 = load %0 : $*Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #60. -// CHECK-NEXT: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK-NEXT: NoAlias -// CHECK: PAIR #61. -// CHECK-NEXT: (1): %3 = alloc_stack $Builtin.NativeObject -// CHECK-NEXT: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK-NEXT: NoAlias - -// Test %5 (the read write apply inst). - -// CHECK: PAIR #70. -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: MustAlias -// CHECK: PAIR #71. -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: (0): %6 = load %0 : $*Builtin.NativeObject -// CHECK-NEXT: MayAlias -// CHECK: PAIR #72. -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: function_ref use_native_object -// CHECK-NEXT: %7 = function_ref @use_native_object : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK-NEXT: MayAlias -// CHECK: PAIR #73. -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK-NEXT: MayAlias -// CHECK: PAIR #74. -// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject -// CHECK-NEXT: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK-NEXT: MayAlias - -// Test %8 (the escaping load) - -// CHECK: PAIR #85. -// CHECK-NEXT: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK-NEXT: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK-NEXT: MustAlias -// CHECK: PAIR #86. -// CHECK-NEXT: (0): %8 = load %3#1 : $*Builtin.NativeObject -// CHECK-NEXT: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK-NEXT: MayAlias -sil @escapesource_functionlocal_test_escapesource_nonescapinglocal : $@convention(thin) (@inout Builtin.NativeObject, Builtin.NativeObject) -> () { -bb0(%0 : $*Builtin.NativeObject, %1 : $Builtin.NativeObject): - %2 = alloc_stack $Builtin.NativeObject - %3 = alloc_stack $Builtin.NativeObject - %4 = function_ref @create_native_object : $@convention(thin) () -> Builtin.NativeObject - %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject - %6 = load %0 : $*Builtin.NativeObject - %7 = function_ref @use_native_object : $@convention(thin) (Builtin.NativeObject) -> () - %8 = load %3#1 : $*Builtin.NativeObject - %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () - dealloc_stack %3#0 : $*@local_storage Builtin.NativeObject - dealloc_stack %2#0 : $*@local_storage Builtin.NativeObject - %12 = tuple () - return %12 : $() -} - -// CHECK-LABEL: @projections_from_the_same_source_with_the_same_projection_path_mustalias -// CHECK: PAIR #33. -// CHECK-NEXT: (0): %3 = tuple_element_addr %2 : $*(Builtin.Int64, Builtin.Int32), 1 -// CHECK-NEXT: (0): %6 = tuple_element_addr %5 : $*(Builtin.Int64, Builtin.Int32), 1 -// CHECK-NEXT: MustAlias -sil @projections_from_the_same_source_with_the_same_projection_path_mustalias : $@convention(thin) () -> () { - %0 = alloc_stack $StructLvl1 - %1 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub - %2 = struct_element_addr %1 : $*StructLvl2, #StructLvl2.tup - %3 = tuple_element_addr %2 : $*(Builtin.Int64, Builtin.Int32), 1 - %4 = struct_element_addr %0#1 : $*StructLvl1, #StructLvl1.sub - %5 = struct_element_addr %4 : $*StructLvl2, #StructLvl2.tup - %6 = tuple_element_addr %5 : $*(Builtin.Int64, Builtin.Int32), 1 - dealloc_stack %0#0 : $*@local_storage StructLvl1 - %7 = tuple() - return %7 : $() -} - -sil_global public @sil_global1 : $Builtin.Int32 -sil_global public @sil_global2 : $Builtin.Int32 - -class X { } - -// CHECK-LABEL: @globals_dont_alias -// CHECK: PAIR #0. -// CHECK-NEXT: (0): %0 = global_addr @sil_global1 : $*Builtin.Int32 -// CHECK-NEXT: (0): %0 = global_addr @sil_global1 : $*Builtin.Int32 -// CHECK-NEXT: MustAlias -// CHECK: PAIR #1. -// CHECK-NEXT: (0): %0 = global_addr @sil_global1 : $*Builtin.Int32 -// CHECK-NEXT: (0): %1 = global_addr @sil_global2 : $*Builtin.Int32 -// CHECK-NEXT: NoAlias -sil @globals_dont_alias : $@convention(thin) () -> () { - %0 = global_addr @sil_global1 : $*Builtin.Int32 - %1 = global_addr @sil_global2 : $*Builtin.Int32 - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: @globals_and_allocs_dont_alias -// CHECK: PAIR #1. -// CHECK-NEXT: (0): %0 = global_addr @sil_global1 : $*Builtin.Int32 -// CHECK-NEXT: (0): %1 = alloc_ref $X -// CHECK-NEXT: NoAlias -sil @globals_and_allocs_dont_alias : $@convention(thin) () -> () { - %0 = global_addr @sil_global1 : $*Builtin.Int32 - %1 = alloc_ref $X - %4 = tuple() - return %4 : $() -} - - -sil_global @sil_global3 : $Int32 - -// CHECK-LABEL: @globals_alias -// CHECK: PAIR #0. -// CHECK-NEXT: (0): %0 = global_addr @sil_global3 : $*Int32 -// CHECK-NEXT: (0): %0 = global_addr @sil_global3 : $*Int32 -// CHECK-NEXT: MustAlias -// CHECK: PAIR #1. -// CHECK-NEXT: (0): %0 = global_addr @sil_global3 : $*Int32 -// CHECK-NEXT: (0): %1 = global_addr @sil_global3 : $*Int32 -// CHECK-NEXT: MustAlias -// CHECK: PAIR #2. -// CHECK-NEXT: (0): %0 = global_addr @sil_global3 : $*Int32 -// CHECK-NEXT: (0): %2 = struct_element_addr %1 : $*Int32, #Int32._value -// CHECK-NEXT: PartialAlias -sil @globals_alias : $@convention(thin) () -> () { - %0 = global_addr @sil_global3 : $*Int32 - %1 = global_addr @sil_global3 : $*Int32 - %2 = struct_element_addr %1 : $*Int32, #Int32._value - %4 = tuple() - return %4 : $() -} - -class HalfOpenRange { - final var current: Int32 - final let end: Int32 - init(start: Int32, end: Int32) -} -// CHECK-LABEL: @different_fields -// CHECK: PAIR #51. -// CHECK-NEXT: (0): %5 = ref_element_addr %4 : $HalfOpenRange, #HalfOpenRange.current -// CHECK-NEXT: (0): %7 = ref_element_addr %4 : $HalfOpenRange, #HalfOpenRange.end -// CHECK-NEXT: NoAlias -// CHECK: PAIR #64. -// CHECK-NEXT: (0): %9 = struct_element_addr %5 : $*Int32, #Int32._value -// CHECK-NEXT: (0): %10 = struct_element_addr %7 : $*Int32, #Int32._value -// CHECK-NEXT: NoAlias -sil @different_fields : $@convention(thin) () -> () { - %0 = integer_literal $Builtin.Int32, 0 - %1 = struct $Int32 (%0 : $Builtin.Int32) - %2 = integer_literal $Builtin.Int32, 10 - %3 = struct $Int32 (%2 : $Builtin.Int32) - %4 = alloc_ref $HalfOpenRange - %5 = ref_element_addr %4 : $HalfOpenRange, #HalfOpenRange.current - store %1 to %5 : $*Int32 - %7 = ref_element_addr %4 : $HalfOpenRange, #HalfOpenRange.end - store %3 to %7 : $*Int32 - %9 = struct_element_addr %5 : $*Int32, #Int32._value - %10 = struct_element_addr %7 : $*Int32, #Int32._value - %11 = load %9 : $*Builtin.Int32 - %12 = load %10 : $*Builtin.Int32 - %13 = tuple() - return %13 : $() -} - -public final class C { - @sil_stored final var a: Int { get set } - @sil_stored final var b: Int { get set } - deinit - init() -} - -// CHECK-LABEL: @different_fields_of_different_refs -// CHECK: PAIR #13. -// CHECK-NEXT: (0): %3 = ref_element_addr %0 : $C, #C.a -// CHECK-NEXT: (0): %4 = ref_element_addr %1 : $C, #C.b -// CHECK-NEXT: NoAlias -sil @different_fields_of_different_refs : $@convention(thin) (@owned C, @owned C, Int) -> Int { -bb0(%0 : $C, %1 : $C, %2 : $Int): - %6 = ref_element_addr %0 : $C, #C.a - %8 = ref_element_addr %1 : $C, #C.b - return %2 : $Int -} - diff --git a/test/SILAnalysis/callgraph.sil b/test/SILAnalysis/callgraph.sil deleted file mode 100644 index 59eb4b048b615..0000000000000 --- a/test/SILAnalysis/callgraph.sil +++ /dev/null @@ -1,968 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -call-graph-printer -o /dev/null | FileCheck --check-prefix=CHECK --check-prefix=CHECK-NOWMO %s -// RUN: %target-sil-opt -enable-sil-verify-all %s -wmo -call-graph-printer -o /dev/null | FileCheck --check-prefix=CHECK --check-prefix=CHECK-WMO %s - -sil_stage canonical - -// CHECK: *** Call Graph *** -// CHECK: Function #1: private_bottom -// CHECK: Demangled: private_bottom -// CHECK: Trivially dead: no -// CHECK: All callers known: yes -// CHECK: Callers: - -// CHECK: Name: private_middle -// CHECK: Demangled: private_middle -sil private @private_bottom : $@convention(thin) () -> () { -bb0: - %0 = tuple () - return %0 : $() -} - - -// CHECK: Function #2: private_middle -// CHECK: Demangled: private_middle -// CHECK: Trivially dead: no -// CHECK: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #0: %1 = apply %0() : $@convention(thin) () -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: private_bottom -// CHECK: Demangled: private_bottom - -// CHECK: Callers: - -// CHECK: Name: private_top -// CHECK: Demangled: private_top -sil private @private_middle : $@convention(thin) () -> () { -bb0: - %0 = function_ref @private_bottom : $@convention(thin) () -> () - %1 = apply %0() : $@convention(thin) () -> () - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #3: private_top -// CHECK: Demangled: private_top -// CHECK: Trivially dead: yes -// CHECK: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #1: %1 = apply %0() : $@convention(thin) () -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: private_middle -// CHECK: Demangled: private_middle -sil private @private_top : $@convention(thin) () -> () { -bb0: - %0 = function_ref @private_middle : $@convention(thin) () -> () - %1 = apply %0() : $@convention(thin) () -> () - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #4: internal_bottom -// CHECK: Demangled: internal_bottom -// CHECK: Trivially dead: no -// CHECK-NOWMO: All callers known: no -// CHECK-WMO: All callers known: yes -// CHECK-NOWMO: Known Callers: -// CHECK-WMO: Callers: - -// CHECK: Name: internal_middle -// CHECK: Demangled: internal_middle -sil hidden @internal_bottom : $@convention(thin) () -> () { -bb0: - %0 = tuple () - return %0 : $() -} - - -// CHECK: Function #5: internal_middle -// CHECK: Demangled: internal_middle -// CHECK: Trivially dead: no -// CHECK-NOWMO: All callers known: no -// CHECK-WMO: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #2: %1 = apply %0() : $@convention(thin) () -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: internal_bottom -// CHECK: Demangled: internal_bottom - -// CHECK-NOWMO: Known Callers: -// CHECK-WMO: Callers: - -// CHECK: Name: internal_top -// CHECK: Demangled: internal_top -sil hidden @internal_middle : $@convention(thin) () -> () { -bb0: - %0 = function_ref @internal_bottom : $@convention(thin) () -> () - %1 = apply %0() : $@convention(thin) () -> () - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #6: internal_top -// CHECK: Demangled: internal_top -// CHECK-NOWMO: Trivially dead: no -// CHECK-NOWMO: All callers known: no -// CHECK-WMO: Trivially dead: yes -// CHECK-WMO: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #3: %1 = apply %0() : $@convention(thin) () -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: internal_middle -// CHECK: Demangled: internal_middle -sil hidden @internal_top : $@convention(thin) () -> () { -bb0: - %0 = function_ref @internal_middle : $@convention(thin) () -> () - %1 = apply %0() : $@convention(thin) () -> () - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #7: public_bottom -// CHECK: Demangled: public_bottom -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: public_middle -// CHECK: Demangled: public_middle -sil @public_bottom : $@convention(thin) () -> () { -bb0: - %0 = tuple () - return %0 : $() -} - - -// CHECK: Function #8: public_middle -// CHECK: Demangled: public_middle -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Call sites: - -// CHECK: Call site #4: %1 = apply %0() : $@convention(thin) () -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: public_bottom -// CHECK: Demangled: public_bottom - -// CHECK: Known Callers: - -// CHECK: Name: public_top -// CHECK: Demangled: public_top -sil @public_middle : $@convention(thin) () -> () { -bb0: - %0 = function_ref @public_bottom : $@convention(thin) () -> () - %1 = apply %0() : $@convention(thin) () -> () - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #9: public_top -// CHECK: Demangled: public_top -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Call sites: - -// CHECK: Call site #5: %1 = apply %0() : $@convention(thin) () -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: public_middle -// CHECK: Demangled: public_middle -sil @public_top : $@convention(thin) () -> () { -bb0: - %0 = function_ref @public_middle : $@convention(thin) () -> () - %1 = apply %0() : $@convention(thin) () -> () - %2 = tuple () - return %2 : $() -} - - -private class private_base { - func foo() -} - -private class private_derived : private_base { - override func foo() -} - -@inline(never) private func call_private(b: private_base) - -class internal_base { - func foo() - private func bar() -} - -class internal_derived : internal_base { - override func foo() - override func bar() -} - -@inline(never) func call_internal(b: internal_base) - -public class public_base { - func foo() - public func bar() - private func baz() -} - -public class public_derived : public_base { - override func foo() - public override func bar() - public override func baz() -} - - -// CHECK: Function #10: private_base_foo -// CHECK: Demangled: private_base_foo -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_private -// CHECK: Demangled: call_private - -sil private @private_base_foo : $@convention(method) (@guaranteed private_base) -> () { -bb0(%0 : $private_base): - debug_value %0 : $private_base - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #11: private_derived_foo -// CHECK: Demangled: private_derived_foo -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_private -// CHECK: Demangled: call_private - - -sil private @private_derived_foo : $@convention(method) (@guaranteed private_derived) -> () { -bb0(%0 : $private_derived): - debug_value %0 : $private_derived - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #12: call_private -// CHECK: Demangled: call_private -// CHECK: Trivially dead: yes -// CHECK: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #6: %3 = apply %2(%0) : $@convention(method) (@guaranteed private_base) -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: private_base_foo -// CHECK: Demangled: private_base_foo - -// CHECK: Name: private_derived_foo -// CHECK: Demangled: private_derived_foo - - -sil private [noinline] @call_private : $@convention(thin) (@owned private_base) -> () { -bb0(%0 : $private_base): - debug_value %0 : $private_base - %2 = class_method %0 : $private_base, #private_base.foo!1 : private_base -> () -> () , $@convention(method) (@guaranteed private_base) -> () - %3 = apply %2(%0) : $@convention(method) (@guaranteed private_base) -> () - strong_release %0 : $private_base - %5 = tuple () - return %5 : $() -} - - -// CHECK: Function #13: internal_base_foo -// CHECK: Demangled: internal_base_foo -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_internal -// CHECK: Demangled: call_internal - - -sil hidden @internal_base_foo : $@convention(method) (@guaranteed internal_base) -> () { -bb0(%0 : $internal_base): - debug_value %0 : $internal_base - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #14: internal_base_bar -// CHECK: Demangled: internal_base_bar -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_internal -// CHECK: Demangled: call_internal - - -sil private @internal_base_bar : $@convention(method) (@guaranteed internal_base) -> () { -bb0(%0 : $internal_base): - debug_value %0 : $internal_base - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #15: internal_derived_foo -// CHECK: Demangled: internal_derived_foo -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_internal -// CHECK: Demangled: call_internal - - -sil hidden @internal_derived_foo : $@convention(method) (@guaranteed internal_derived) -> () { -bb0(%0 : $internal_derived): - debug_value %0 : $internal_derived - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #16: internal_derived_bar -// CHECK: Demangled: internal_derived_bar -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_internal -// CHECK: Demangled: call_internal - - -sil hidden @internal_derived_bar : $@convention(method) (@guaranteed internal_derived) -> () { -bb0(%0 : $internal_derived): - debug_value %0 : $internal_derived - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #17: call_internal -// CHECK: Demangled: call_internal -// CHECK-NOWMO: Trivially dead: no -// CHECK-NOWMO: All callers known: no -// CHECK-WMO: Trivially dead: yes -// CHECK-WMO: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #7: %3 = apply %2(%0) : $@convention(method) (@guaranteed internal_base) -> () -// CHECK-NOWMO: Unknown callees: yes -// CHECK-WMO: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: internal_base_foo -// CHECK: Demangled: internal_base_foo - -// CHECK: Name: internal_derived_foo -// CHECK: Demangled: internal_derived_foo - -// CHECK: Call site #8: %5 = apply %4(%0) : $@convention(method) (@guaranteed internal_base) -> () -// CHECK-NOWMO: Unknown callees: yes -// CHECK-WMO: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: internal_base_bar -// CHECK: Demangled: internal_base_bar - -// CHECK: Name: internal_derived_bar -// CHECK: Demangled: internal_derived_bar - - -sil hidden [noinline] @call_internal : $@convention(thin) (@owned internal_base) -> () { -bb0(%0 : $internal_base): - debug_value %0 : $internal_base - %2 = class_method %0 : $internal_base, #internal_base.foo!1 : internal_base -> () -> () , $@convention(method) (@guaranteed internal_base) -> () - %3 = apply %2(%0) : $@convention(method) (@guaranteed internal_base) -> () - %4 = class_method %0 : $internal_base, #internal_base.bar!1 : internal_base -> () -> () , $@convention(method) (@guaranteed internal_base) -> () - %5 = apply %4(%0) : $@convention(method) (@guaranteed internal_base) -> () - strong_release %0 : $internal_base - %7 = tuple () - return %7 : $() -} - - -// CHECK: Function #18: public_base_foo -// CHECK: Demangled: public_base_foo -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_public -// CHECK: Demangled: call_public - - -sil hidden @public_base_foo : $@convention(method) (@guaranteed public_base) -> () { -bb0(%0 : $public_base): - debug_value %0 : $public_base - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #19: public_base_bar -// CHECK: Demangled: public_base_bar -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_public -// CHECK: Demangled: call_public - - -sil @public_base_bar : $@convention(method) (@guaranteed public_base) -> () { -bb0(%0 : $public_base): - debug_value %0 : $public_base - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #20: public_base_baz -// CHECK: Demangled: public_base_baz -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_public -// CHECK: Demangled: call_public - - -sil private @public_base_baz : $@convention(method) (@guaranteed public_base) -> () { -bb0(%0 : $public_base): - debug_value %0 : $public_base - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #21: public_derived_foo -// CHECK: Demangled: public_derived_foo -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_public -// CHECK: Demangled: call_public - - -sil hidden @public_derived_foo : $@convention(method) (@guaranteed public_derived) -> () { -bb0(%0 : $public_derived): - debug_value %0 : $public_derived - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #22: public_derived_bar -// CHECK: Demangled: public_derived_bar -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_public -// CHECK: Demangled: call_public - - -sil @public_derived_bar : $@convention(method) (@guaranteed public_derived) -> () { -bb0(%0 : $public_derived): - debug_value %0 : $public_derived - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #23: public_derived_baz -// CHECK: Demangled: public_derived_baz -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: call_public -// CHECK: Demangled: call_public - - -sil @public_derived_baz : $@convention(method) (@guaranteed public_derived) -> () { -bb0(%0 : $public_derived): - debug_value %0 : $public_derived - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #24: call_public -// CHECK: Demangled: call_public -// CHECK-NOWMO: Trivially dead: no -// CHECK-NOWMO: All callers known: no -// CHECK-WMO: Trivially dead: yes -// CHECK-WMO: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #9: %3 = apply %2(%0) : $@convention(method) (@guaranteed public_base) -> () -// CHECK-NOWMO: Unknown callees: yes -// CHECK-WMO: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: public_base_foo -// CHECK: Demangled: public_base_foo - -// CHECK: Name: public_derived_foo -// CHECK: Demangled: public_derived_foo - -// CHECK: Call site #10: %5 = apply %4(%0) : $@convention(method) (@guaranteed public_base) -> () -// CHECK: Unknown callees: yes -// CHECK: Known callees: -// CHECK: Name: public_base_bar -// CHECK: Demangled: public_base_bar - -// CHECK: Name: public_derived_bar -// CHECK: Demangled: public_derived_bar - -// CHECK: Call site #11: %7 = apply %6(%0) : $@convention(method) (@guaranteed public_base) -> () -// CHECK: Unknown callees: yes -// CHECK: Known callees: -// CHECK: Name: public_base_baz -// CHECK: Demangled: public_base_baz - -// CHECK: Name: public_derived_baz -// CHECK: Demangled: public_derived_baz - - -sil hidden [noinline] @call_public : $@convention(thin) (@owned public_base) -> () { -bb0(%0 : $public_base): - debug_value %0 : $public_base - %2 = class_method %0 : $public_base, #public_base.foo!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () - %3 = apply %2(%0) : $@convention(method) (@guaranteed public_base) -> () - %4 = class_method %0 : $public_base, #public_base.bar!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () - %5 = apply %4(%0) : $@convention(method) (@guaranteed public_base) -> () - %6 = class_method %0 : $public_base, #public_base.baz!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () - %7 = apply %6(%0) : $@convention(method) (@guaranteed public_base) -> () - strong_release %0 : $public_base - %9 = tuple () - return %9 : $() -} - -sil_vtable private_base { - #private_base.foo!1: private_base_foo -} - -sil_vtable private_derived { - #private_base.foo!1: private_derived_foo -} - -sil_vtable internal_base { - #internal_base.foo!1: internal_base_foo - #internal_base.bar!1: internal_base_bar -} - -sil_vtable internal_derived { - #internal_base.foo!1: internal_derived_foo - #internal_base.bar!1: internal_derived_bar -} - -sil_vtable public_base { - #public_base.foo!1: public_base_foo - #public_base.bar!1: public_base_bar - #public_base.baz!1: public_base_baz -} - -sil_vtable public_derived { - #public_base.foo!1: public_derived_foo - #public_base.bar!1: public_derived_bar - #public_base.baz!1: public_derived_baz -} - -private protocol private_proto_1 { - func theMethod() -} - -private class private_proto_private_class : private_proto_1 { - func theMethod() -} - -private func call_through_private_proto_1(x: T) - -private protocol private_proto_2 { - func theMethod() -} - -class private_proto_internal_class : private_proto_2 { - func theMethod() -} - -private func call_through_private_proto_2(x: T) - -private protocol private_proto_3 { - func theMethod() -} - -public class private_proto_public_class : private_proto_3 { - public func theMethod() -} - -private func call_through_private_proto_3(x: T) - -private protocol private_proto_4 { - func theMethod() -} - -public class private_proto_public_class_private_method : private_proto_4 { - private func theMethod() -} - -private func call_through_private_proto_4(x: T) - -// CHECK: Function #25: private_proto_private_class_theMethod -// CHECK: Demangled: private_proto_private_class_theMethod -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: private_proto_1_private_class_witness -// CHECK: Demangled: private_proto_1_private_class_witness - - -sil private @private_proto_private_class_theMethod : $@convention(method) (@guaranteed private_proto_private_class) -> () { -bb0(%0 : $private_proto_private_class): - debug_value %0 : $private_proto_private_class - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #26: private_proto_1_private_class_witness -// CHECK: Demangled: private_proto_1_private_class_witness -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Call sites: - -// CHECK: Call site #12: %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_private_class) -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: private_proto_private_class_theMethod -// CHECK: Demangled: private_proto_private_class_theMethod - -// CHECK: Known Callers: - -// CHECK: Name: call_through_private_proto_1 -// CHECK: Demangled: call_through_private_proto_1 - - -sil private [transparent] [thunk] @private_proto_1_private_class_witness : $@convention(witness_method) (@in_guaranteed private_proto_private_class) -> () { -bb0(%0 : $*private_proto_private_class): - %1 = load %0 : $*private_proto_private_class - strong_retain %1 : $private_proto_private_class - %3 = class_method %1 : $private_proto_private_class, #private_proto_private_class.theMethod!1 : private_proto_private_class -> () -> () , $@convention(method) (@guaranteed private_proto_private_class) -> () - %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_private_class) -> () - strong_release %1 : $private_proto_private_class - return %4 : $() -} - - -// CHECK: Function #27: call_through_private_proto_1 -// CHECK: Demangled: call_through_private_proto_1 -// CHECK: Trivially dead: yes -// CHECK: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #13: %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_1> (@in_guaranteed τ_0_0) -> () -// CHECK: Unknown callees: yes -// CHECK: Known callees: -// CHECK: Name: private_proto_1_private_class_witness -// CHECK: Demangled: private_proto_1_private_class_witness - - -sil private @call_through_private_proto_1 : $@convention(thin) (@in T) -> () { -bb0(%0 : $*T): - debug_value_addr %0 : $*T - %2 = witness_method $T, #private_proto_1.theMethod!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_1> (@in_guaranteed τ_0_0) -> () - %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_1> (@in_guaranteed τ_0_0) -> () - destroy_addr %0 : $*T - %5 = tuple () - return %5 : $() -} - - -// CHECK: Function #28: private_proto_internal_class_theMethod -// CHECK: Demangled: private_proto_internal_class_theMethod -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: private_proto_2_internal_class_witness -// CHECK: Demangled: private_proto_2_internal_class_witness - - -sil hidden @private_proto_internal_class_theMethod : $@convention(method) (@guaranteed private_proto_internal_class) -> () { -bb0(%0 : $private_proto_internal_class): - debug_value %0 : $private_proto_internal_class - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #29: private_proto_2_internal_class_witness -// CHECK: Demangled: private_proto_2_internal_class_witness -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Call sites: - -// CHECK: Call site #14: %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_internal_class) -> () -// CHECK-NOWMO: Unknown callees: yes -// CHECK-WMO: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: private_proto_internal_class_theMethod -// CHECK: Demangled: private_proto_internal_class_theMethod - -// CHECK: Known Callers: - -// CHECK: Name: call_through_private_proto_2 -// CHECK: Demangled: call_through_private_proto_2 - - -sil private [transparent] [thunk] @private_proto_2_internal_class_witness : $@convention(witness_method) (@in_guaranteed private_proto_internal_class) -> () { -bb0(%0 : $*private_proto_internal_class): - %1 = load %0 : $*private_proto_internal_class - strong_retain %1 : $private_proto_internal_class - %3 = class_method %1 : $private_proto_internal_class, #private_proto_internal_class.theMethod!1 : private_proto_internal_class -> () -> () , $@convention(method) (@guaranteed private_proto_internal_class) -> () - %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_internal_class) -> () - strong_release %1 : $private_proto_internal_class - return %4 : $() -} - - -// CHECK: Function #30: call_through_private_proto_2 -// CHECK: Demangled: call_through_private_proto_2 -// CHECK: Trivially dead: yes -// CHECK: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #15: %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_2> (@in_guaranteed τ_0_0) -> () -// CHECK: Unknown callees: yes -// CHECK: Known callees: -// CHECK: Name: private_proto_2_internal_class_witness -// CHECK: Demangled: private_proto_2_internal_class_witness - - -sil private @call_through_private_proto_2 : $@convention(thin) (@in T) -> () { -bb0(%0 : $*T): - debug_value_addr %0 : $*T - %2 = witness_method $T, #private_proto_2.theMethod!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_2> (@in_guaranteed τ_0_0) -> () - %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_2> (@in_guaranteed τ_0_0) -> () - destroy_addr %0 : $*T - %5 = tuple () - return %5 : $() -} - - -// CHECK: Function #31: private_proto_public_class_theMethod -// CHECK: Demangled: private_proto_public_class_theMethod -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: private_proto_3_public_class_witness -// CHECK: Demangled: private_proto_3_public_class_witness - - -sil @private_proto_public_class_theMethod : $@convention(method) (@guaranteed private_proto_public_class) -> () { -bb0(%0 : $private_proto_public_class): - debug_value %0 : $private_proto_public_class - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #32: private_proto_3_public_class_witness -// CHECK: Demangled: private_proto_3_public_class_witness -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Call sites: - -// CHECK: Call site #16: %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_public_class) -> () -// CHECK: Unknown callees: yes -// CHECK: Known callees: -// CHECK: Name: private_proto_public_class_theMethod -// CHECK: Demangled: private_proto_public_class_theMethod - -// CHECK: Known Callers: - -// CHECK: Name: call_through_private_proto_3 -// CHECK: Demangled: call_through_private_proto_3 - - -sil private [transparent] [thunk] @private_proto_3_public_class_witness : $@convention(witness_method) (@in_guaranteed private_proto_public_class) -> () { -bb0(%0 : $*private_proto_public_class): - %1 = load %0 : $*private_proto_public_class - strong_retain %1 : $private_proto_public_class - %3 = class_method %1 : $private_proto_public_class, #private_proto_public_class.theMethod!1 : private_proto_public_class -> () -> () , $@convention(method) (@guaranteed private_proto_public_class) -> () - %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_public_class) -> () - strong_release %1 : $private_proto_public_class - return %4 : $() -} - - -// CHECK: Function #33: call_through_private_proto_3 -// CHECK: Demangled: call_through_private_proto_3 -// CHECK: Trivially dead: yes -// CHECK: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #17: %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_3> (@in_guaranteed τ_0_0) -> () -// CHECK: Unknown callees: yes -// CHECK: Known callees: -// CHECK: Name: private_proto_3_public_class_witness -// CHECK: Demangled: private_proto_3_public_class_witness - - -sil private @call_through_private_proto_3 : $@convention(thin) (@in T) -> () { -bb0(%0 : $*T): - debug_value_addr %0 : $*T - %2 = witness_method $T, #private_proto_3.theMethod!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_3> (@in_guaranteed τ_0_0) -> () - %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_3> (@in_guaranteed τ_0_0) -> () - destroy_addr %0 : $*T - %5 = tuple () - return %5 : $() -} - - -// CHECK: Function #34: private_proto_public_class_private_method_theMethod -// CHECK: Demangled: private_proto_public_class_private_method_theMethod -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Known Callers: - -// CHECK: Name: private_proto_4_public_class_private_method_witness -// CHECK: Demangled: private_proto_4_public_class_private_method_witness - - -sil private @private_proto_public_class_private_method_theMethod : $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () { -bb0(%0 : $private_proto_public_class_private_method): - debug_value %0 : $private_proto_public_class_private_method - %2 = tuple () - return %2 : $() -} - - -// CHECK: Function #35: private_proto_4_public_class_private_method_witness -// CHECK: Demangled: private_proto_4_public_class_private_method_witness -// CHECK: Trivially dead: no -// CHECK: All callers known: no -// CHECK: Call sites: - -// CHECK: Call site #18: %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () -// CHECK: Unknown callees: no -// CHECK: Known callees: -// CHECK: Name: private_proto_public_class_private_method_theMethod -// CHECK: Demangled: private_proto_public_class_private_method_theMethod - -// CHECK: Known Callers: - -// CHECK: Name: call_through_private_proto_4 -// CHECK: Demangled: call_through_private_proto_4 - - -sil private [transparent] [thunk] @private_proto_4_public_class_private_method_witness : $@convention(witness_method) (@in_guaranteed private_proto_public_class_private_method) -> () { -bb0(%0 : $*private_proto_public_class_private_method): - %1 = load %0 : $*private_proto_public_class_private_method - strong_retain %1 : $private_proto_public_class_private_method - %3 = class_method %1 : $private_proto_public_class_private_method, #private_proto_public_class_private_method.theMethod!1 : private_proto_public_class_private_method -> () -> () , $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () - %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () - strong_release %1 : $private_proto_public_class_private_method - return %4 : $() -} - - -// CHECK: Function #36: call_through_private_proto_4 -// CHECK: Demangled: call_through_private_proto_4 -// CHECK: Trivially dead: yes -// CHECK: All callers known: yes -// CHECK: Call sites: - -// CHECK: Call site #19: %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_4> (@in_guaranteed τ_0_0) -> () -// CHECK: Unknown callees: yes -// CHECK: Known callees: -// CHECK: Name: private_proto_4_public_class_private_method_witness -// CHECK: Demangled: private_proto_4_public_class_private_method_witness - - -sil private @call_through_private_proto_4 : $@convention(thin) (@in T) -> () { -bb0(%0 : $*T): - debug_value_addr %0 : $*T - %2 = witness_method $T, #private_proto_4.theMethod!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_4> (@in_guaranteed τ_0_0) -> () - %3 = apply %2(%0) : $@convention(witness_method) <τ_0_0 where τ_0_0 : private_proto_4> (@in_guaranteed τ_0_0) -> () - destroy_addr %0 : $*T - %5 = tuple () - return %5 : $() -} - - -sil_vtable private_proto_private_class { - #private_proto_private_class.theMethod!1: private_proto_private_class_theMethod -} - -sil_vtable private_proto_internal_class { - #private_proto_internal_class.theMethod!1: private_proto_internal_class_theMethod -} - -sil_vtable private_proto_public_class { - #private_proto_public_class.theMethod!1: private_proto_public_class_theMethod -} - -sil_vtable private_proto_public_class_private_method { - #private_proto_public_class_private_method.theMethod!1: private_proto_public_class_private_method_theMethod -} - -sil_witness_table private private_proto_private_class: private_proto_1 module witness { - method #private_proto_1.theMethod!1: @private_proto_1_private_class_witness -} - -sil_witness_table private private_proto_internal_class: private_proto_2 module witness { - method #private_proto_2.theMethod!1: @private_proto_2_internal_class_witness -} - -sil_witness_table private private_proto_public_class: private_proto_3 module witness { - method #private_proto_3.theMethod!1: @private_proto_3_public_class_witness -} - -sil_witness_table private private_proto_public_class_private_method: private_proto_4 module witness { - method #private_proto_4.theMethod!1: @private_proto_4_public_class_private_method_witness -} - -// CHECK: *** Call Graph Statistics *** -// CHECK: Number of call graph nodes: 36 -// CHECK: Number of call graph edges: 20 -// CHECK: Histogram of number of call sites per function: -// CHECK: 0: 19 -// CHECK: 1: 15 -// CHECK: 2: 1 -// CHECK: 3: 1 - -// CHECK: Histogram of number of callees per call site: -// CHECK: 1: 14 -// CHECK: 2: 6 - -// CHECK: Histogram of number of callers per function: -// CHECK: 0: 10 -// CHECK: 1: 26 - -// CHECK: Bump pointer allocated memory (bytes): 12288 -// CHECK: Number of callee sets allocated: 20 diff --git a/test/SILAnalysis/mem-behavior.sil b/test/SILAnalysis/mem-behavior.sil deleted file mode 100644 index 9656caadeb0c1..0000000000000 --- a/test/SILAnalysis/mem-behavior.sil +++ /dev/null @@ -1,129 +0,0 @@ -// RUN: %target-sil-opt %s -aa=basic-aa -mem-behavior-dump -o /dev/null | FileCheck %s - -// REQUIRES: asserts - -import Builtin -import Swift - -class X { - @sil_stored var a: Int32 - @sil_stored var x: X - - init() -} - -sil @unknown_func : $@convention(thin) (Int32, @inout Int32) -> () - -sil @nouser_func : $@convention(thin) () -> () - -sil @store_to_int : $@convention(thin) (Int32, @inout Int32) -> () { -bb0(%0 : $Int32, %1 : $*Int32): - store %0 to %1 : $*Int32 - %r = tuple () - return %r : $() -} - -sil @only_retain : $@convention(thin) (@guaranteed X) -> () { -bb0(%0 : $X): - strong_retain %0 : $X - - %r = tuple () - return %r : $() -} - -// CHECK-LABEL: @call_unknown_func -// CHECK: PAIR #1. -// CHECK-NEXT: (0): %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () -// CHECK-NEXT: (0): %1 = argument of bb0 : $*Int32 // user: %4 -// CHECK-NEXT: r=1,w=1,se=1 -// CHECK: PAIR #2. -// CHECK-NEXT: (0): %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () -// CHECK-NEXT: (0): %2 = argument of bb0 : $*Int32 -// CHECK-NEXT: r=1,w=1,se=1 -sil @call_unknown_func : $@convention(thin) (Int32, @inout Int32, @inout Int32) -> () { -bb0(%0 : $Int32, %1 : $*Int32, %2 : $*Int32): - %3 = function_ref @unknown_func : $@convention(thin) (Int32, @inout Int32) -> () - %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () - - %r = tuple () - return %r : $() -} - -// CHECK-LABEL: @call_store_to_int_not_aliased -// CHECK: PAIR #1. -// CHECK-NEXT: (0): %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () -// CHECK-NEXT: (0): %1 = argument of bb0 : $*Int32 // user: %4 -// CHECK-NEXT: r=0,w=1,se=1 -// CHECK: PAIR #2. -// CHECK-NEXT: (0): %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () -// CHECK-NEXT: (0): %2 = argument of bb0 : $*Int32 -// CHECK-NEXT: r=0,w=0,se=0 -sil @call_store_to_int_not_aliased : $@convention(thin) (Int32, @inout Int32, @inout Int32) -> () { -bb0(%0 : $Int32, %1 : $*Int32, %2 : $*Int32): - %3 = function_ref @store_to_int : $@convention(thin) (Int32, @inout Int32) -> () - %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () - - %r = tuple () - return %r : $() -} - -// CHECK-LABEL: @call_store_to_int_aliased -// CHECK: PAIR #3. -// CHECK-NEXT: (0): %6 = apply %5(%0, %3) : $@convention(thin) (Int32, @inout Int32) -> () -// CHECK-NEXT: (0): %3 = ref_element_addr %1 : $X, #X.a // user: %6 -// CHECK-NEXT: r=0,w=1,se=1 -// CHECK: PAIR #4. -// CHECK-NEXT: (0): %6 = apply %5(%0, %3) : $@convention(thin) (Int32, @inout Int32) -> () -// CHECK-NEXT: (0): %4 = ref_element_addr %2 : $X, #X.a -// CHECK-NEXT: r=0,w=1,se=1 -sil @call_store_to_int_aliased : $@convention(thin) (Int32, @guaranteed X, @guaranteed X) -> () { -bb0(%0 : $Int32, %1 : $X, %2 : $X): - %3 = ref_element_addr %1 : $X, #X.a - %4 = ref_element_addr %2 : $X, #X.a - %5 = function_ref @store_to_int : $@convention(thin) (Int32, @inout Int32) -> () - %6 = apply %5(%0, %3) : $@convention(thin) (Int32, @inout Int32) -> () - - %r = tuple () - return %r : $() -} - -sil @call_only_retain : $@convention(thin) (@guaranteed X, @guaranteed X) -> () { -bb0(%0 : $X, %1 : $X): - %2 = function_ref @only_retain : $@convention(thin) (@guaranteed X) -> () - %3 = apply %2(%0) : $@convention(thin) (@guaranteed X) -> () - - %r = tuple () - return %r : $() -} - -// CHECK-LABEL: @allocstack_apply_no_side_effect -// CHECK: PAIR #2 -// CHECK-NEXT: (0): %3 = apply %2() : $@convention(thin) () -> () -// CHECK-NEXT: (1): %1 = alloc_stack $Int32 // user: %5 -// CHECK-NEXT: r=0,w=0,se=0 -sil @allocstack_apply_no_side_effect : $@convention(thin) (Int32) -> () { -bb0(%0 : $Int32): - %1 = alloc_stack $Int32 // user: %5 - %2 = function_ref @nouser_func : $@convention(thin) () -> () // user: %3 - %3 = apply %2() : $@convention(thin) () -> () - %4 = tuple () // user: %6 - dealloc_stack %1#0 : $*@local_storage Int32 // id: %5 - return %4 : $() -} - -// CHECK-LABEL: @allocstack_apply_side_effect -// CHECK: PAIR #2. -// CHECK-NEXT: (0): %3 = apply %2(%0, %1#1) : $@convention(thin) (Int32, @inout Int32) -> () -// CHECK-NEXT: (1): %1 = alloc_stack $Int32 -// CHECK-NEXT: r=0,w=1,se=1 -sil @allocstack_apply_side_effect : $@convention(thin) (Int32) -> () { -bb0(%0 : $Int32): - %1 = alloc_stack $Int32 // users: %3, %5 - // function_ref store_to_int - %2 = function_ref @store_to_int : $@convention(thin) (Int32, @inout Int32) -> () // user: %3 - %3 = apply %2(%0, %1#1) : $@convention(thin) (Int32, @inout Int32) -> () - %4 = tuple () // user: %6 - dealloc_stack %1#0 : $*@local_storage Int32 // id: %5 - return %4 : $() // id: %6 -} - diff --git a/test/SILGen/Inputs/usr/include/Gizmo.h b/test/SILGen/Inputs/usr/include/Gizmo.h index 8ed5e8a9020c0..4b5856e716068 100644 --- a/test/SILGen/Inputs/usr/include/Gizmo.h +++ b/test/SILGen/Inputs/usr/include/Gizmo.h @@ -36,7 +36,7 @@ typedef long NSInteger; - (Gizmo*) initWithBellsOn:(NSInteger)x OBJC_DESIGNATED_INITIALIZER; - (instancetype) initWithoutBells:(NSInteger)x; - (void) fork NS_CONSUMES_SELF; -- (void) enumerateSubGizmos: (void (^)(Gizmo*))f; +- (void) enumerateSubGizmos: (void (^ _Nullable)(Gizmo*))f; + (void) consume: (NS_CONSUMED Gizmo*) gizmo; + (void) inspect: (Gizmo*) gizmo; + (void) runWithRect: (struct Rect) rect andGizmo: (Gizmo*) gizmo; diff --git a/test/SILGen/accessors.swift b/test/SILGen/accessors.swift index 36d9fe8ef74c1..d90c68b336060 100644 --- a/test/SILGen/accessors.swift +++ b/test/SILGen/accessors.swift @@ -48,7 +48,7 @@ func test0(ref: A) { // CHECK-NEXT: [[BUFFER:%.*]] = alloc_stack $OrdinarySub // CHECK-NEXT: [[T0:%.*]] = address_to_pointer [[BUFFER]] // CHECK-NEXT: [[T1:%.*]] = class_method %0 : $A, #A.array!materializeForSet.1 -// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE]]#1, %0) +// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE]], %0) // CHECK-NEXT: [[T3:%.*]] = tuple_extract [[T2]] {{.*}}, 0 // CHECK-NEXT: [[T4:%.*]] = pointer_to_address [[T3]] // CHECK-NEXT: [[OPT_CALLBACK:%.*]] = tuple_extract [[T2]] {{.*}}, 1 @@ -59,11 +59,11 @@ func test0(ref: A) { // CHECK-NEXT: switch_enum [[OPT_CALLBACK]] : $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout A, @thick A.Type) -> ()>, case #Optional.Some!enumelt.1: [[WRITEBACK:bb[0-9]+]], case #Optional.None!enumelt: [[CONT:bb[0-9]+]] // CHECK: [[WRITEBACK]]([[CALLBACK:%.*]] : $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout A, @thick A.Type) -> ()): // CHECK-NEXT: [[TEMP2:%.*]] = alloc_stack $A -// CHECK-NEXT: store %0 to [[TEMP2]]#1 : $*A +// CHECK-NEXT: store %0 to [[TEMP2]] : $*A // CHECK-NEXT: [[T0:%.*]] = metatype $@thick A.Type // CHECK-NEXT: [[T1:%.*]] = address_to_pointer [[ADDR]] : $*OrdinarySub to $Builtin.RawPointer -// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE]]#1, [[TEMP2]]#1, [[T0]]) -// CHECK-NEXT: dealloc_stack [[TEMP2]]#0 +// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE]], [[TEMP2]], [[T0]]) +// CHECK-NEXT: dealloc_stack [[TEMP2]] // CHECK-NEXT: br [[CONT]] // CHECK: [[CONT]]: // CHECK-NEXT: dealloc_stack [[BUFFER]] @@ -103,7 +103,7 @@ func test1(ref: B) { // CHECK-NEXT: [[BUFFER:%.*]] = alloc_stack $MutatingSub // CHECK-NEXT: [[T0:%.*]] = address_to_pointer [[BUFFER]] // CHECK-NEXT: [[T1:%.*]] = class_method %0 : $B, #B.array!materializeForSet.1 -// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE]]#1, %0) +// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE]], %0) // CHECK-NEXT: [[T3:%.*]] = tuple_extract [[T2]] {{.*}}, 0 // CHECK-NEXT: [[T4:%.*]] = pointer_to_address [[T3]] // CHECK-NEXT: [[OPT_CALLBACK:%.*]] = tuple_extract [[T2]] {{.*}}, 1 @@ -114,11 +114,11 @@ func test1(ref: B) { // CHECK-NEXT: switch_enum [[OPT_CALLBACK]] : $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout B, @thick B.Type) -> ()>, case #Optional.Some!enumelt.1: [[WRITEBACK:bb[0-9]+]], case #Optional.None!enumelt: [[CONT:bb[0-9]+]] // CHECK: [[WRITEBACK]]([[CALLBACK:%.*]] : $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout B, @thick B.Type) -> ()): // CHECK-NEXT: [[TEMP2:%.*]] = alloc_stack $B -// CHECK-NEXT: store %0 to [[TEMP2]]#1 : $*B +// CHECK-NEXT: store %0 to [[TEMP2]] : $*B // CHECK-NEXT: [[T0:%.*]] = metatype $@thick B.Type // CHECK-NEXT: [[T1:%.*]] = address_to_pointer [[ADDR]] : $*MutatingSub to $Builtin.RawPointer -// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE]]#1, [[TEMP2]]#1, [[T0]]) -// CHECK-NEXT: dealloc_stack [[TEMP2]]#0 +// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE]], [[TEMP2]], [[T0]]) +// CHECK-NEXT: dealloc_stack [[TEMP2]] // CHECK-NEXT: br [[CONT]] // CHECK: [[CONT]]: // Formal access to LHS. @@ -126,7 +126,7 @@ func test1(ref: B) { // CHECK-NEXT: [[BUFFER2:%.*]] = alloc_stack $MutatingSub // CHECK-NEXT: [[T0:%.*]] = address_to_pointer [[BUFFER2]] // CHECK-NEXT: [[T1:%.*]] = class_method %0 : $B, #B.array!materializeForSet.1 -// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE2]]#1, %0) +// CHECK-NEXT: [[T2:%.*]] = apply [[T1]]([[T0]], [[STORAGE2]], %0) // CHECK-NEXT: [[T3:%.*]] = tuple_extract [[T2]] {{.*}}, 0 // CHECK-NEXT: [[T4:%.*]] = pointer_to_address [[T3]] // CHECK-NEXT: [[OPT_CALLBACK:%.*]] = tuple_extract [[T2]] {{.*}}, 1 @@ -137,11 +137,11 @@ func test1(ref: B) { // CHECK-NEXT: switch_enum [[OPT_CALLBACK]] : $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout B, @thick B.Type) -> ()>, case #Optional.Some!enumelt.1: [[WRITEBACK:bb[0-9]+]], case #Optional.None!enumelt: [[CONT:bb[0-9]+]] // CHECK: [[WRITEBACK]]([[CALLBACK:%.*]] : $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout B, @thick B.Type) -> ()): // CHECK-NEXT: [[TEMP2:%.*]] = alloc_stack $B -// CHECK-NEXT: store %0 to [[TEMP2]]#1 : $*B +// CHECK-NEXT: store %0 to [[TEMP2]] : $*B // CHECK-NEXT: [[T0:%.*]] = metatype $@thick B.Type // CHECK-NEXT: [[T1:%.*]] = address_to_pointer [[ADDR]] : $*MutatingSub to $Builtin.RawPointer -// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE2]]#1, [[TEMP2]]#1, [[T0]]) -// CHECK-NEXT: dealloc_stack [[TEMP2]]#0 +// CHECK-NEXT: apply [[CALLBACK]]([[T1]], [[STORAGE2]], [[TEMP2]], [[T0]]) +// CHECK-NEXT: dealloc_stack [[TEMP2]] // CHECK-NEXT: br [[CONT]] // CHECK: [[CONT]]: // CHECK-NEXT: dealloc_stack [[BUFFER2]] diff --git a/test/SILGen/address_only_types.swift b/test/SILGen/address_only_types.swift index 2e625921be557..a6d30e51b9054 100644 --- a/test/SILGen/address_only_types.swift +++ b/test/SILGen/address_only_types.swift @@ -30,8 +30,8 @@ func address_only_ignored_argument(_: Unloadable) { // CHECK-LABEL: sil hidden @_TF18address_only_types30address_only_curried_arguments func address_only_curried_arguments(x: Unloadable)(y: Unloadable) { // CHECK: bb0([[YARG:%[0-9]+]] : $*Unloadable, [[XARG:%[0-9]+]] : $*Unloadable): - // CHECK-NEXT: debug_value_addr [[YARG]] : $*Unloadable // let y - // CHECK-NEXT: debug_value_addr [[XARG]] : $*Unloadable // let x + // CHECK-NEXT: debug_value_addr [[YARG]] : $*Unloadable, let, name "y" + // CHECK-NEXT: debug_value_addr [[XARG]] : $*Unloadable, let, name "x" // CHECK-NEXT: destroy_addr [[XARG]] // CHECK-NEXT: destroy_addr [[YARG]] // CHECK-NEXT: tuple @@ -41,8 +41,8 @@ func address_only_curried_arguments(x: Unloadable)(y: Unloadable) { // CHECK-LABEL: sil hidden @_TF18address_only_types41address_only_curried_arguments_and_return func address_only_curried_arguments_and_return(x: Unloadable)(y: Unloadable) -> Unloadable { // CHECK: bb0([[RET:%[0-9]+]] : $*Unloadable, [[YARG:%[0-9]+]] : $*Unloadable, [[XARG:%[0-9]+]] : $*Unloadable): - // CHECK-NEXT: debug_value_addr [[YARG]] : $*Unloadable // let y - // CHECK-NEXT: debug_value_addr [[XARG]] : $*Unloadable // let x + // CHECK-NEXT: debug_value_addr [[YARG]] : $*Unloadable, let, name "y" + // CHECK-NEXT: debug_value_addr [[XARG]] : $*Unloadable, let, name "x" // CHECK-NEXT: copy_addr [take] [[XARG]] to [initialization] [[RET]] // CHECK-NEXT: destroy_addr [[YARG]] // CHECK-NEXT: tuple @@ -53,8 +53,8 @@ func address_only_curried_arguments_and_return(x: Unloadable)(y: Unloadable) -> // CHECK-LABEL: sil hidden @_TF18address_only_types19address_only_return func address_only_return(x: Unloadable, y: Int) -> Unloadable { // CHECK: bb0([[RET:%[0-9]+]] : $*Unloadable, [[XARG:%[0-9]+]] : $*Unloadable, [[YARG:%[0-9]+]] : $Builtin.Int64): - // CHECK-NEXT: debug_value_addr [[XARG]] : $*Unloadable // let x - // CHECK-NEXT: debug_value [[YARG]] : $Builtin.Int64 // let y + // CHECK-NEXT: debug_value_addr [[XARG]] : $*Unloadable, let, name "x" + // CHECK-NEXT: debug_value [[YARG]] : $Builtin.Int64, let, name "y" // CHECK-NEXT: copy_addr [take] [[XARG]] to [initialization] [[RET]] // CHECK-NEXT: [[VOID:%[0-9]+]] = tuple () // CHECK-NEXT: return [[VOID]] @@ -64,8 +64,8 @@ func address_only_return(x: Unloadable, y: Int) -> Unloadable { // CHECK-LABEL: sil hidden @_TF18address_only_types27address_only_curried_return func address_only_curried_return(x: Unloadable)(y: Int) -> Unloadable { // CHECK: bb0([[RET:%[0-9]+]] : $*Unloadable, [[YARG:%[0-9]+]] : $Builtin.Int64, [[XADDR:%[0-9]+]] : $*Unloadable): - // CHECK-NEXT: debug_value [[YARG]] : $Builtin.Int64 // let y - // CHECK-NEXT: debug_value_addr [[XADDR]] : $*Unloadable // let x + // CHECK-NEXT: debug_value [[YARG]] : $Builtin.Int64, let, name "y" + // CHECK-NEXT: debug_value_addr [[XADDR]] : $*Unloadable, let, name "x" // CHECK-NEXT: copy_addr [take] [[XADDR]] to [initialization] [[RET]] // CHECK-NEXT: [[VOID:%[0-9]+]] = tuple () // CHECK-NEXT: return [[VOID]] @@ -139,9 +139,9 @@ func address_only_call_1_ignore_return() { some_address_only_function_1() // CHECK: [[FUNC:%[0-9]+]] = function_ref @_TF18address_only_types28some_address_only_function_1FT_PS_10Unloadable_ // CHECK: [[TEMP:%[0-9]+]] = alloc_stack $Unloadable - // CHECK: apply [[FUNC]]([[TEMP]]#1) - // CHECK: destroy_addr [[TEMP]]#1 - // CHECK: dealloc_stack [[TEMP]]#0 + // CHECK: apply [[FUNC]]([[TEMP]]) + // CHECK: destroy_addr [[TEMP]] + // CHECK: dealloc_stack [[TEMP]] // CHECK: return } @@ -153,8 +153,8 @@ func address_only_call_2(x: Unloadable) { // CHECK: [[FUNC:%[0-9]+]] = function_ref @_TF18address_only_types28some_address_only_function_2 // CHECK: [[X_CALL_ARG:%[0-9]+]] = alloc_stack $Unloadable // CHECK: copy_addr [[XARG]] to [initialization] [[X_CALL_ARG]] - // CHECK: apply [[FUNC]]([[X_CALL_ARG]]#1) - // CHECK: dealloc_stack [[X_CALL_ARG]]#0 + // CHECK: apply [[FUNC]]([[X_CALL_ARG]]) + // CHECK: dealloc_stack [[X_CALL_ARG]] // CHECK: return } @@ -165,9 +165,9 @@ func address_only_call_1_in_2() { // CHECK: [[FUNC2:%[0-9]+]] = function_ref @_TF18address_only_types28some_address_only_function_2 // CHECK: [[FUNC1:%[0-9]+]] = function_ref @_TF18address_only_types28some_address_only_function_1 // CHECK: [[TEMP:%[0-9]+]] = alloc_stack $Unloadable - // CHECK: apply [[FUNC1]]([[TEMP]]#1) - // CHECK: apply [[FUNC2]]([[TEMP]]#1) - // CHECK: dealloc_stack [[TEMP]]#0 + // CHECK: apply [[FUNC1]]([[TEMP]]) + // CHECK: apply [[FUNC2]]([[TEMP]]) + // CHECK: dealloc_stack [[TEMP]] // CHECK: return } @@ -177,12 +177,12 @@ func address_only_materialize() -> Int { return some_address_only_function_1().foo() // CHECK: [[FUNC:%[0-9]+]] = function_ref @_TF18address_only_types28some_address_only_function_1 // CHECK: [[TEMP:%[0-9]+]] = alloc_stack $Unloadable - // CHECK: apply [[FUNC]]([[TEMP]]#1) - // CHECK: [[TEMP_PROJ:%[0-9]+]] = open_existential_addr [[TEMP]]#1 : $*Unloadable to $*[[OPENED:@opened(.*) Unloadable]] + // CHECK: apply [[FUNC]]([[TEMP]]) + // CHECK: [[TEMP_PROJ:%[0-9]+]] = open_existential_addr [[TEMP]] : $*Unloadable to $*[[OPENED:@opened(.*) Unloadable]] // CHECK: [[FOO_METHOD:%[0-9]+]] = witness_method $[[OPENED]], #Unloadable.foo!1 // CHECK: [[RET:%[0-9]+]] = apply [[FOO_METHOD]]<[[OPENED]]>([[TEMP_PROJ]]) // CHECK: destroy_addr [[TEMP_PROJ]] - // CHECK: dealloc_stack [[TEMP]]#0 + // CHECK: dealloc_stack [[TEMP]] // CHECK: return [[RET]] } @@ -193,9 +193,9 @@ func address_only_assignment_from_temp(inout dest: Unloadable) { // CHECK: copy_addr [[DEST]] to [initialization] [[DEST_LOCAL]]#1 dest = some_address_only_function_1() // CHECK: [[TEMP:%[0-9]+]] = alloc_stack $Unloadable - // CHECK: copy_addr [take] [[TEMP]]#1 to [[DEST_LOCAL]]#1 : - // CHECK-NOT: destroy_addr [[TEMP]]#1 - // CHECK: dealloc_stack [[TEMP]]#0 + // CHECK: copy_addr [take] [[TEMP]] to [[DEST_LOCAL]]#1 : + // CHECK-NOT: destroy_addr [[TEMP]] + // CHECK: dealloc_stack [[TEMP]] // CHECK: copy_addr [[DEST_LOCAL]]#1 to [[DEST]] // CHECK: release [[DEST_LOCAL]]#0 } @@ -229,8 +229,8 @@ func address_only_assignment_from_temp_to_property() { global_prop = some_address_only_function_1() // CHECK: [[TEMP:%[0-9]+]] = alloc_stack $Unloadable // CHECK: [[SETTER:%[0-9]+]] = function_ref @_TF18address_only_typess11global_propPS_10Unloadable_ - // CHECK: apply [[SETTER]]([[TEMP]]#1) - // CHECK: dealloc_stack [[TEMP]]#0 + // CHECK: apply [[SETTER]]([[TEMP]]) + // CHECK: dealloc_stack [[TEMP]] } // CHECK-LABEL: sil hidden @_TF18address_only_types43address_only_assignment_from_lv_to_property @@ -240,8 +240,8 @@ func address_only_assignment_from_lv_to_property(v: Unloadable) { // CHECK: [[TEMP:%[0-9]+]] = alloc_stack $Unloadable // CHECK: copy_addr [[VARG]] to [initialization] [[TEMP]] // CHECK: [[SETTER:%[0-9]+]] = function_ref @_TF18address_only_typess11global_propPS_10Unloadable_ - // CHECK: apply [[SETTER]]([[TEMP]]#1) - // CHECK: dealloc_stack [[TEMP]]#0 + // CHECK: apply [[SETTER]]([[TEMP]]) + // CHECK: dealloc_stack [[TEMP]] global_prop = v } diff --git a/test/SILGen/addressors.swift b/test/SILGen/addressors.swift index 61f5267871b1e..b4234aa1d8621 100644 --- a/test/SILGen/addressors.swift +++ b/test/SILGen/addressors.swift @@ -35,7 +35,7 @@ func test0() { // CHECK: [[T0:%.*]] = function_ref @_TFV10addressors1AC // CHECK: [[T1:%.*]] = metatype $@thin A.Type // CHECK: [[AVAL:%.*]] = apply [[T0]]([[T1]]) -// CHECK: store [[AVAL]] to [[A]]#1 +// CHECK: store [[AVAL]] to [[A]] var a = A() // CHECK: [[T0:%.*]] = function_ref @_TFV10addressors1Alu9subscriptFVs5Int32S1_ : @@ -46,7 +46,7 @@ func test0() { let z = a[10] // CHECK: [[T0:%.*]] = function_ref @_TFV10addressors1Aau9subscriptFVs5Int32S1_ : -// CHECK: [[T1:%.*]] = apply [[T0]]({{%.*}}, [[A]]#1) +// CHECK: [[T1:%.*]] = apply [[T0]]({{%.*}}, [[A]]) // CHECK: [[T2:%.*]] = struct_extract [[T1]] : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue // CHECK: [[T3:%.*]] = pointer_to_address [[T2]] : $Builtin.RawPointer to $*Int32 // CHECK: load @@ -55,7 +55,7 @@ func test0() { a[5] += z // CHECK: [[T0:%.*]] = function_ref @_TFV10addressors1Aau9subscriptFVs5Int32S1_ : -// CHECK: [[T1:%.*]] = apply [[T0]]({{%.*}}, [[A]]#1) +// CHECK: [[T1:%.*]] = apply [[T0]]({{%.*}}, [[A]]) // CHECK: [[T2:%.*]] = struct_extract [[T1]] : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue // CHECK: [[T3:%.*]] = pointer_to_address [[T2]] : $Builtin.RawPointer to $*Int32 // CHECK: store {{%.*}} to [[T3]] @@ -194,10 +194,10 @@ struct D : Subscriptable { // SILGEN: [[INIT:%.*]] = function_ref @_TFSqC // SILGEN: [[META:%.*]] = metatype $@thin Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout D, @thick D.Type) -> ()>.Type // SILGEN: [[T0:%.*]] = alloc_stack $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout D, @thick D.Type) -> ()> -// SILGEN: [[OPT:%.*]] = apply [[INIT]]<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout D, @thick D.Type) -> ()>([[T0]]#1, [[META]]) -// SILGEN: [[T1:%.*]] = load [[T0]]#1 +// SILGEN: [[OPT:%.*]] = apply [[INIT]]<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout D, @thick D.Type) -> ()>([[T0]], [[META]]) +// SILGEN: [[T1:%.*]] = load [[T0]] // SILGEN: [[T2:%.*]] = tuple ([[ADDR]] : $Builtin.RawPointer, [[T1]] : $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout D, @thick D.Type) -> ()>) -// SILGEN: dealloc_stack [[T0]]#0 +// SILGEN: dealloc_stack [[T0]] // SILGEN: copy_addr [[BOX]]#1 to [[SELF]] // SILGEN: strong_release [[BOX]]#0 // SILGEN: return [[T2]] : diff --git a/test/SILGen/apply_abstraction_nested.swift b/test/SILGen/apply_abstraction_nested.swift index 8c13fb33b1034..eff15419c7586 100644 --- a/test/SILGen/apply_abstraction_nested.swift +++ b/test/SILGen/apply_abstraction_nested.swift @@ -9,8 +9,8 @@ func baz(inout _: T)(_:Int) {} func ~> ( inout x: T, - m: (inout x: T)->((Args)->Result) -) -> (Args->Result) { + m: (inout x: T) -> ((Args) -> Result) +) -> (Args -> Result) { return m(x: &x) } diff --git a/test/SILGen/auto_closures.swift b/test/SILGen/auto_closures.swift index 3f50e866bb6c5..edc1012f8c972 100644 --- a/test/SILGen/auto_closures.swift +++ b/test/SILGen/auto_closures.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -parse-stdlib -emit-silgen %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -parse-stdlib -emit-silgen %s | FileCheck %s struct Bool {} var false_ = Bool() @@ -40,7 +40,7 @@ public class Sub : Base { // CHECK: } // CHECK-LABEL: sil shared [transparent] @_TFFC13auto_closures3Subg1xVS_4Boolu_KT_S1_ : $@convention(thin) (@owned Sub) -> Bool { - // CHECK: [[SUPER:%.*]] = function_ref @_TFC13auto_closures4Baseg1xVS_4Bool + // CHECK: [[SUPER:%[0-9]+]] = super_method %{{[0-9]+}} : $Sub, #Base.x!getter.1 : (Base) -> () -> Bool , $@convention(method) (@guaranteed Base) -> Bool // CHECK: [[RET:%.*]] = apply [[SUPER]]({{%.*}}) // CHECK: return [[RET]] override var x: Bool { return call_auto_closure(super.x) } diff --git a/test/SILGen/auto_generated_super_init_call.swift b/test/SILGen/auto_generated_super_init_call.swift index 3be913f04db71..bd7a7e8be3dab 100644 --- a/test/SILGen/auto_generated_super_init_call.swift +++ b/test/SILGen/auto_generated_super_init_call.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-silgen %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -emit-silgen %s | FileCheck %s // Test that we emit a call to super.init at the end of the initializer, when none has been previously added. @@ -16,8 +16,7 @@ class SomeDerivedClass : Parent { // CHECK: integer_literal $Builtin.Int2048, 42 // CHECK: [[SELFLOAD:%[0-9]+]] = load [[SELF:%[0-9]+]] : $*SomeDerivedClass // CHECK-NEXT: [[PARENT:%[0-9]+]] = upcast [[SELFLOAD]] : $SomeDerivedClass to $Parent -// CHECK-NEXT: function_ref auto_generated_super_init_call.Parent.init -// CHECK-NEXT: [[INITCALL1:%[0-9]+]] = function_ref @_TFC30auto_generated_super_init_call6Parentc +// CHECK-NEXT: [[INITCALL1:%[0-9]+]] = super_method [[SELFLOAD]] : $SomeDerivedClass, #Parent.init!initializer.1 // CHECK-NEXT: [[RES1:%[0-9]+]] = apply [[INITCALL1]]([[PARENT]]) // CHECK-NEXT: [[DOWNCAST:%[0-9]+]] = unchecked_ref_cast [[RES1]] : $Parent to $SomeDerivedClass // CHECK-NEXT: store [[DOWNCAST]] to [[SELF]] : $*SomeDerivedClass @@ -26,7 +25,7 @@ class SomeDerivedClass : Parent { init(x: Int) { y = x // CHECK-LABEL: sil hidden @_TFC30auto_generated_super_init_call16SomeDerivedClassc{{.*}} : $@convention(method) (Int, @owned SomeDerivedClass) -> @owned SomeDerivedClass -// CHECK: function_ref @_TFC30auto_generated_super_init_call6Parentc{{.*}} : $@convention(method) (@owned Parent) -> @owned Parent +// CHECK: super_method {{%[0-9]+}} : $SomeDerivedClass, #Parent.init!initializer.1 : Parent.Type -> () -> Parent , $@convention(method) (@owned Parent) -> @owned Parent } init(b: Bool) { @@ -37,12 +36,12 @@ class SomeDerivedClass : Parent { y = 10 } return -// Check that we are emittng the super.init expr into the epilog block. +// Check that we are emitting the super.init expr into the epilog block. // CHECK-LABEL: sil hidden @_TFC30auto_generated_super_init_call16SomeDerivedClassc{{.*}} : $@convention(method) (Bool, @owned SomeDerivedClass) -> @owned SomeDerivedClass // CHECK: bb4: // CHECK: [[SELFLOAD:%[0-9]+]] = load [[SELF:%[0-9]+]] : $*SomeDerivedClass -// CHECK: function_ref @_TFC30auto_generated_super_init_call6Parentc{{.*}} : $@convention(method) (@owned Parent) -> @owned Parent +// CHECK: super_method [[SELFLOAD]] : $SomeDerivedClass, #Parent.init!initializer.1 : Parent.Type -> () -> Parent , $@convention(method) (@owned Parent) -> @owned Parent // CHECK-NEXT: apply // CHECK-NEXT: unchecked_ref_cast // CHECK-NEXT: store @@ -52,7 +51,7 @@ class SomeDerivedClass : Parent { // CHECK-NEXT: return } - // One init has a call to super init. Make sure we don't instert more than one. + // One init has a call to super init. Make sure we don't insert more than one. init(b: Bool, i: Int) { if (b) { y = i @@ -62,7 +61,7 @@ class SomeDerivedClass : Parent { super.init() // CHECK-LABEL: sil hidden @_TFC30auto_generated_super_init_call16SomeDerivedClassc{{.*}} : $@convention(method) (Bool, Int, @owned SomeDerivedClass) -> @owned SomeDerivedClass -// CHECK: function_ref @_TFC30auto_generated_super_init_call6Parentc{{.*}} : $@convention(method) (@owned Parent) -> @owned Parent +// CHECK: super_method {{%[0-9]+}} : $SomeDerivedClass, #Parent.init!initializer.1 : Parent.Type -> () -> Parent , $@convention(method) (@owned Parent) -> @owned Parent // CHECK-NOT: function_ref @_TFC30auto_generated_super_init_call6Parentc // CHECK: return } @@ -72,7 +71,7 @@ class SomeDerivedClass : Parent { class HasNoIVars : Parent { override init() { // CHECK-LABEL: sil hidden @_TFC30auto_generated_super_init_call10HasNoIVarsc{{.*}} : $@convention(method) (@owned HasNoIVars) -> @owned HasNoIVars -// CHECK: function_ref @_TFC30auto_generated_super_init_call6Parentc +// CHECK: super_method {{%[0-9]+}} : $HasNoIVars, #Parent.init!initializer.1 } } @@ -96,7 +95,7 @@ class ChildOfParentWithNoExplicitInit : ParentWithNoExplicitInit { override init() { y = 10 // CHECK-LABEL: sil hidden @_TFC30auto_generated_super_init_call31ChildOfParentWithNoExplicitInitc -// CHECK: function_ref @_TFC30auto_generated_super_init_call24ParentWithNoExplicitInitc{{.*}} : $@convention(method) (@owned ParentWithNoExplicitInit) -> @owned ParentWithNoExplicitInit +// CHECK: super_method {{%[0-9]+}} : $ChildOfParentWithNoExplicitInit, #ParentWithNoExplicitInit.init!initializer.1 : ParentWithNoExplicitInit.Type -> () -> ParentWithNoExplicitInit , $@convention(method) (@owned ParentWithNoExplicitInit) -> @owned ParentWithNoExplicitInit } } @@ -110,7 +109,7 @@ class ChildOfParentWithNoExplicitInit2 : ParentWithNoExplicitInit2 { override init() { y = 10 // CHECK-LABEL: sil hidden @_TFC30auto_generated_super_init_call32ChildOfParentWithNoExplicitInit2c -// CHECK: function_ref @_TFC30auto_generated_super_init_call25ParentWithNoExplicitInit2c{{.*}} : $@convention(method) (@owned ParentWithNoExplicitInit2) -> @owned ParentWithNoExplicitInit2 +// CHECK: super_method {{%[0-9]+}} : $ChildOfParentWithNoExplicitInit2, #ParentWithNoExplicitInit2.init!initializer.1 : ParentWithNoExplicitInit2.Type -> () -> ParentWithNoExplicitInit2 , $@convention(method) (@owned ParentWithNoExplicitInit2) -> @owned ParentWithNoExplicitInit2 } } diff --git a/test/SILGen/boxed_existentials.swift b/test/SILGen/boxed_existentials.swift index 05f9e09d6ffe6..2fface195d6ec 100644 --- a/test/SILGen/boxed_existentials.swift +++ b/test/SILGen/boxed_existentials.swift @@ -52,11 +52,11 @@ func test_property(x: ErrorType) -> String { // CHECK: [[VALUE:%.*]] = open_existential_box %0 : $ErrorType to $*[[VALUE_TYPE:@opened\(.*\) ErrorType]] // FIXME: Extraneous copy here // CHECK-NEXT: [[COPY:%[0-9]+]] = alloc_stack $[[VALUE_TYPE]] -// CHECK-NEXT: copy_addr [[VALUE]] to [initialization] [[COPY]]#1 : $*[[VALUE_TYPE]] +// CHECK-NEXT: copy_addr [[VALUE]] to [initialization] [[COPY]] : $*[[VALUE_TYPE]] // CHECK: [[METHOD:%.*]] = witness_method $[[VALUE_TYPE]], #ErrorType._domain!getter.1 // -- self parameter of witness is @in_guaranteed; no need to copy since // value in box is immutable and box is guaranteed -// CHECK: [[RESULT:%.*]] = apply [[METHOD]]<[[VALUE_TYPE]]>([[COPY]]#1) +// CHECK: [[RESULT:%.*]] = apply [[METHOD]]<[[VALUE_TYPE]]>([[COPY]]) // CHECK: strong_release %0 // CHECK: return [[RESULT]] @@ -71,11 +71,11 @@ func test_property_of_lvalue(x: ErrorType) -> String { // CHECK-NEXT: strong_retain [[VALUE_BOX]] // CHECK-NEXT: [[VALUE:%.*]] = open_existential_box [[VALUE_BOX]] : $ErrorType to $*[[VALUE_TYPE:@opened\(.*\) ErrorType]] // CHECK-NEXT: [[COPY:%.*]] = alloc_stack $[[VALUE_TYPE]] -// CHECK-NEXT: copy_addr [[VALUE]] to [initialization] [[COPY]]#1 +// CHECK-NEXT: copy_addr [[VALUE]] to [initialization] [[COPY]] // CHECK-NEXT: [[METHOD:%.*]] = witness_method $[[VALUE_TYPE]], #ErrorType._domain!getter.1 -// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]<[[VALUE_TYPE]]>([[COPY]]#1) -// CHECK-NEXT: destroy_addr [[COPY]]#1 -// CHECK-NEXT: dealloc_stack [[COPY]]#0 +// CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]<[[VALUE_TYPE]]>([[COPY]]) +// CHECK-NEXT: destroy_addr [[COPY]] +// CHECK-NEXT: dealloc_stack [[COPY]] // CHECK-NEXT: strong_release [[VALUE_BOX]] // CHECK-NEXT: strong_release [[VAR]]#0 // CHECK-NEXT: strong_release %0 diff --git a/test/SILGen/builtins.swift b/test/SILGen/builtins.swift index ffc4331560b72..de45010399b61 100644 --- a/test/SILGen/builtins.swift +++ b/test/SILGen/builtins.swift @@ -487,8 +487,8 @@ func reinterpretAddrOnlyToTrivial(t: T) -> Int { // CHECK-LABEL: sil hidden @_TF8builtins27reinterpretAddrOnlyLoadable func reinterpretAddrOnlyLoadable(a: Int, _ b: T) -> (T, Int) { // CHECK: [[BUF:%.*]] = alloc_stack $Int - // CHECK: store {{%.*}} to [[BUF]]#1 - // CHECK: [[RES1:%.*]] = unchecked_addr_cast [[BUF]]#1 : $*Int to $*T + // CHECK: store {{%.*}} to [[BUF]] + // CHECK: [[RES1:%.*]] = unchecked_addr_cast [[BUF]] : $*Int to $*T // CHECK: copy_addr [[RES1]] to [initialization] return (Builtin.reinterpretCast(a) as T, // CHECK: [[RES:%.*]] = unchecked_addr_cast {{%.*}} : $*T to $*Int @@ -547,7 +547,7 @@ func pinUnpin(object : Builtin.NativeObject) { // CHECK-LABEL: sil hidden @_TF8builtins19allocateValueBuffer // CHECK: bb0([[BUFFER:%.*]] : $*Builtin.UnsafeValueBuffer): -// CHECK-NEXT: debug_value_addr %0 : $*Builtin.UnsafeValueBuffer // var buffer, argno: 1 +// CHECK-NEXT: debug_value_addr %0 : $*Builtin.UnsafeValueBuffer, var, name "buffer", argno 1 // CHECK-NEXT: metatype $@thin Int.Type // CHECK-NEXT: [[T0:%.*]] = alloc_value_buffer $Int in [[BUFFER]] : $*Builtin.UnsafeValueBuffer // CHECK-NEXT: [[T1:%.*]] = address_to_pointer [[T0]] : $*Int to $Builtin.RawPointer @@ -558,7 +558,7 @@ func allocateValueBuffer(inout buffer: Builtin.UnsafeValueBuffer) -> Builtin.Raw // CHECK-LABEL: sil hidden @_TF8builtins18projectValueBuffer // CHECK: bb0([[BUFFER:%.*]] : $*Builtin.UnsafeValueBuffer): -// CHECK-NEXT: debug_value_addr %0 : $*Builtin.UnsafeValueBuffer // var buffer, argno: 1 +// CHECK-NEXT: debug_value_addr %0 : $*Builtin.UnsafeValueBuffer, var, name "buffer", argno 1 // CHECK-NEXT: metatype $@thin Int.Type // CHECK-NEXT: [[T0:%.*]] = project_value_buffer $Int in [[BUFFER]] : $*Builtin.UnsafeValueBuffer // CHECK-NEXT: [[T1:%.*]] = address_to_pointer [[T0]] : $*Int to $Builtin.RawPointer @@ -569,7 +569,7 @@ func projectValueBuffer(inout buffer: Builtin.UnsafeValueBuffer) -> Builtin.RawP // CHECK-LABEL: sil hidden @_TF8builtins18deallocValueBuffer // CHECK: bb0([[BUFFER:%.*]] : $*Builtin.UnsafeValueBuffer): -//CHECK-NEXT: debug_value_addr %0 : $*Builtin.UnsafeValueBuffer // var buffer, argno: 1 +//CHECK-NEXT: debug_value_addr %0 : $*Builtin.UnsafeValueBuffer, var, name "buffer", argno 1 // CHECK-NEXT: metatype $@thin Int.Type // CHECK-NEXT: dealloc_value_buffer $Int in [[BUFFER]] : $*Builtin.UnsafeValueBuffer // CHECK-NEXT: tuple () @@ -737,7 +737,7 @@ protocol PUnknown {} protocol PClass : class {} // CHECK-LABEL: sil hidden @_TF8builtins19refcast_generic_any -// CHECK: unchecked_ref_cast_addr T in %{{.*}}#1 : $*T to AnyObject in %{{.*}}#1 : $*AnyObject +// CHECK: unchecked_ref_cast_addr T in %{{.*}} : $*T to AnyObject in %{{.*}} : $*AnyObject func refcast_generic_any(o: T) -> AnyObject { return Builtin.castReference(o) } @@ -750,7 +750,7 @@ func refcast_class_any(o: A) -> AnyObject { } // CHECK-LABEL: sil hidden @_TF8builtins20refcast_punknown_any -// CHECK: unchecked_ref_cast_addr PUnknown in %{{.*}}#1 : $*PUnknown to AnyObject in %{{.*}}#1 : $*AnyObject +// CHECK: unchecked_ref_cast_addr PUnknown in %{{.*}} : $*PUnknown to AnyObject in %{{.*}} : $*AnyObject func refcast_punknown_any(o: PUnknown) -> AnyObject { return Builtin.castReference(o) } @@ -763,7 +763,7 @@ func refcast_pclass_any(o: PClass) -> AnyObject { } // CHECK-LABEL: sil hidden @_TF8builtins20refcast_any_punknown -// CHECK: unchecked_ref_cast_addr AnyObject in %{{.*}}#1 : $*AnyObject to PUnknown in %{{.*}}#1 : $*PUnknown +// CHECK: unchecked_ref_cast_addr AnyObject in %{{.*}} : $*AnyObject to PUnknown in %{{.*}} : $*PUnknown func refcast_any_punknown(o: AnyObject) -> PUnknown { return Builtin.castReference(o) } diff --git a/test/SILGen/capture_inout.swift b/test/SILGen/capture_inout.swift index cf78357e7be8f..22205d44f5d03 100644 --- a/test/SILGen/capture_inout.swift +++ b/test/SILGen/capture_inout.swift @@ -5,10 +5,10 @@ typealias Int = Builtin.Int64 // CHECK: sil hidden @_TF13capture_inout3foo // CHECK: bb0([[X_INOUT:%.*]] : $*Builtin.Int64): // CHECK: [[X_LOCAL:%.*]] = alloc_box $Builtin.Int64 -// CHECK: [[FUNC:%.*]] = function_ref [[CLOSURE:@.*]] : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 -// CHECK: partial_apply [[FUNC]]([[X_LOCAL]]#0, [[X_LOCAL]]#1) +// CHECK: [[FUNC:%.*]] = function_ref [[CLOSURE:@.*]] : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 +// CHECK: partial_apply [[FUNC]]([[X_LOCAL]]#0) // CHECK: } -// CHECK: sil shared [[CLOSURE]] : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 +// CHECK: sil shared [[CLOSURE]] : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 func foo(inout x: Int) -> () -> Int { func bar() -> Int { return x diff --git a/test/SILGen/capture_typed_boxes.swift b/test/SILGen/capture_typed_boxes.swift index 1e76eea0d6def..2f3934fbba597 100644 --- a/test/SILGen/capture_typed_boxes.swift +++ b/test/SILGen/capture_typed_boxes.swift @@ -4,8 +4,8 @@ func foo(x: Int) -> () -> Int { var x = x return { x } } -// CHECK-LABEL: sil shared @_TFF19capture_typed_boxes3fooFSiFT_SiU_FT_Si : $@convention(thin) (@owned @box Int, @inout Int) -> Int { -// CHECK: bb0(%0 : $@box Int, %1 : $*Int): +// CHECK-LABEL: sil shared @_TFF19capture_typed_boxes3fooFSiFT_SiU_FT_Si : $@convention(thin) (@owned @box Int) -> Int { +// CHECK: bb0(%0 : $@box Int): func closure(f: Int -> Int) -> Int { var f = f @@ -15,8 +15,8 @@ func closure(f: Int -> Int) -> Int { return bar(0) } -// CHECK-LABEL: sil shared @_TFF19capture_typed_boxes7closureFFSiSiSiL_3barfSiSi : $@convention(thin) (Int, @owned @box @callee_owned (Int) -> Int, @inout @callee_owned (Int) -> Int) -> Int { -// CHECK: bb0(%0 : $Int, %1 : $@box @callee_owned (Int) -> Int, %2 : $*@callee_owned (Int) -> Int): +// CHECK-LABEL: sil shared @_TFF19capture_typed_boxes7closureFFSiSiSiL_3barfSiSi : $@convention(thin) (Int, @owned @box @callee_owned (Int) -> Int) -> Int { +// CHECK: bb0(%0 : $Int, %1 : $@box @callee_owned (Int) -> Int): func closure_generic(f: T -> T, x: T) -> T { var f = f @@ -26,6 +26,6 @@ func closure_generic(f: T -> T, x: T) -> T { return bar(x) } -// CHECK-LABEL: sil shared @_TFF19capture_typed_boxes15closure_generic{{.*}} : $@convention(thin) (@out T, @in T, @owned @box @callee_owned (@out T, @in T) -> (), @inout @callee_owned (@out T, @in T) -> ()) -> () { -// CHECK-LABEL: bb0(%0 : $*T, %1 : $*T, %2 : $@box @callee_owned (@out T, @in T) -> (), %3 : $*@callee_owned (@out T, @in T) -> ()): +// CHECK-LABEL: sil shared @_TFF19capture_typed_boxes15closure_generic{{.*}} : $@convention(thin) (@out T, @in T, @owned @box @callee_owned (@out T, @in T) -> ()) -> () { +// CHECK-LABEL: bb0(%0 : $*T, %1 : $*T, %2 : $@box @callee_owned (@out T, @in T) -> ()): diff --git a/test/SILGen/casts.swift b/test/SILGen/casts.swift index a7a24085ed87a..1abf917121395 100644 --- a/test/SILGen/casts.swift +++ b/test/SILGen/casts.swift @@ -65,23 +65,23 @@ struct S : P {} // CHECK: sil hidden @_TF5casts32downcast_existential_conditional // CHECK: bb0([[IN:%.*]] : $*P): // CHECK: [[COPY:%.*]] = alloc_stack $P -// CHECK: copy_addr [[IN]] to [initialization] [[COPY]]#1 +// CHECK: copy_addr [[IN]] to [initialization] [[COPY]] // CHECK: [[TMP:%.*]] = alloc_stack $S -// CHECK: checked_cast_addr_br take_always P in [[COPY]]#1 : $*P to S in [[TMP]]#1 : $*S, bb1, bb2 +// CHECK: checked_cast_addr_br take_always P in [[COPY]] : $*P to S in [[TMP]] : $*S, bb1, bb2 // Success block. // CHECK: bb1: -// CHECK: [[T0:%.*]] = load [[TMP]]#1 : $*S +// CHECK: [[T0:%.*]] = load [[TMP]] : $*S // CHECK: [[T1:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[T0]] : $S -// CHECK: dealloc_stack [[TMP]]#0 +// CHECK: dealloc_stack [[TMP]] // CHECK: br bb3([[T1]] : $Optional) // Failure block. // CHECK: bb2: // CHECK: [[T0:%.*]] = enum $Optional, #Optional.None!enumelt -// CHECK: dealloc_stack [[TMP]]#0 +// CHECK: dealloc_stack [[TMP]] // CHECK: br bb3([[T0]] : $Optional) // Continuation block. // CHECK: bb3([[RESULT:%.*]] : $Optional): -// CHECK: dealloc_stack [[COPY]]#0 +// CHECK: dealloc_stack [[COPY]] // CHECK: destroy_addr [[IN]] : $*P // CHECK: return [[RESULT]] func downcast_existential_conditional(p: P) -> S? { diff --git a/test/SILGen/class_resilience.swift b/test/SILGen/class_resilience.swift new file mode 100644 index 0000000000000..ee9fd85f366e2 --- /dev/null +++ b/test/SILGen/class_resilience.swift @@ -0,0 +1,28 @@ +// RUN: %target-swift-frontend -I %S/../Inputs -enable-source-import -emit-silgen -enable-resilience %s | FileCheck %s + +import resilient_class + +// Accessing final property of resilient class from different resilience domain +// through accessor + +// CHECK-LABEL: sil @_TF16class_resilience20finalPropertyOfOtherFC15resilient_class22ResilientOutsideParentT_ +// CHECK: function_ref @_TFC15resilient_class22ResilientOutsideParentg13finalPropertySS + +public func finalPropertyOfOther(other: ResilientOutsideParent) { + _ = other.finalProperty +} + +public class MyResilientClass { + public final var finalProperty: String = "MyResilientClass.finalProperty" +} + +// Accessing final property of resilient class from my resilience domain +// directly + +// CHECK-LABEL: sil @_TF16class_resilience19finalPropertyOfMineFCS_16MyResilientClassT_ +// CHECK: ref_element_addr %0 : $MyResilientClass, #MyResilientClass.finalProperty + +public func finalPropertyOfMine(other: MyResilientClass) { + _ = other.finalProperty +} + diff --git a/test/SILGen/closures.swift b/test/SILGen/closures.swift index 606ab4605f92d..60d18b1a71439 100644 --- a/test/SILGen/closures.swift +++ b/test/SILGen/closures.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -parse-stdlib -parse-as-library -emit-silgen %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -parse-stdlib -parse-as-library -emit-silgen %s | FileCheck %s import Swift @@ -27,14 +27,15 @@ func read_only_capture(x: Int) -> Int { } return cap() - // CHECK: [[CAP:%[0-9]+]] = function_ref @[[CAP_NAME:_TFF8closures17read_only_capture.*]] : $@convention(thin) (@owned @box Int, @inout Int) -> Int - // CHECK: [[RET:%[0-9]+]] = apply [[CAP]]([[XBOX]]#0, [[XBOX]]#1) + // CHECK: [[CAP:%[0-9]+]] = function_ref @[[CAP_NAME:_TFF8closures17read_only_capture.*]] : $@convention(thin) (@owned @box Int) -> Int + // CHECK: [[RET:%[0-9]+]] = apply [[CAP]]([[XBOX]]#0) // CHECK: release [[XBOX]]#0 // CHECK: return [[RET]] } // CHECK: sil shared @[[CAP_NAME]] -// CHECK: bb0([[XBOX:%[0-9]+]] : $@box Int, [[XADDR:%[0-9]+]] : $*Int): +// CHECK: bb0([[XBOX:%[0-9]+]] : $@box Int): +// CHECK: [[XADDR:%[0-9]+]] = project_box [[XBOX]] // CHECK: [[X:%[0-9]+]] = load [[XADDR]] // CHECK: release [[XBOX]] // CHECK: return [[X]] @@ -52,8 +53,8 @@ func write_to_capture(x: Int) -> Int { } scribble() - // CHECK: [[SCRIB:%[0-9]+]] = function_ref @[[SCRIB_NAME:_TFF8closures16write_to_capture.*]] : $@convention(thin) (@owned @box Int, @inout Int) -> () - // CHECK: apply [[SCRIB]]([[X2BOX]]#0, [[X2BOX]]#1) + // CHECK: [[SCRIB:%[0-9]+]] = function_ref @[[SCRIB_NAME:_TFF8closures16write_to_capture.*]] : $@convention(thin) (@owned @box Int) -> () + // CHECK: apply [[SCRIB]]([[X2BOX]]#0) // CHECK: [[RET:%[0-9]+]] = load [[X2BOX]]#1 // CHECK: release [[X2BOX]]#0 // CHECK: release [[XBOX]]#0 @@ -62,7 +63,8 @@ func write_to_capture(x: Int) -> Int { } // CHECK: sil shared @[[SCRIB_NAME]] -// CHECK: bb0([[XBOX:%[0-9]+]] : $@box Int, [[XADDR:%[0-9]+]] : $*Int): +// CHECK: bb0([[XBOX:%[0-9]+]] : $@box Int): +// CHECK: [[XADDR:%[0-9]+]] = project_box [[XBOX]] // CHECK: copy_addr {{%[0-9]+}} to [[XADDR]] // CHECK: release [[XBOX]] // CHECK: return @@ -75,9 +77,9 @@ func multiple_closure_refs(x: Int) -> (() -> Int, () -> Int) { } return (cap, cap) - // CHECK: [[CAP:%[0-9]+]] = function_ref @[[CAP_NAME:_TFF8closures21multiple_closure_refs.*]] : $@convention(thin) (@owned @box Int, @inout Int) -> Int + // CHECK: [[CAP:%[0-9]+]] = function_ref @[[CAP_NAME:_TFF8closures21multiple_closure_refs.*]] : $@convention(thin) (@owned @box Int) -> Int // CHECK: [[CAP_CLOSURE_1:%[0-9]+]] = partial_apply [[CAP]] - // CHECK: [[CAP:%[0-9]+]] = function_ref @[[CAP_NAME:_TFF8closures21multiple_closure_refs.*]] : $@convention(thin) (@owned @box Int, @inout Int) -> Int + // CHECK: [[CAP:%[0-9]+]] = function_ref @[[CAP_NAME:_TFF8closures21multiple_closure_refs.*]] : $@convention(thin) (@owned @box Int) -> Int // CHECK: [[CAP_CLOSURE_2:%[0-9]+]] = partial_apply [[CAP]] // CHECK: [[RET:%[0-9]+]] = tuple ([[CAP_CLOSURE_1]] : {{.*}}, [[CAP_CLOSURE_2]] : {{.*}}) // CHECK: return [[RET]] @@ -91,20 +93,20 @@ func capture_local_func(x: Int) -> () -> () -> Int { func aleph() -> Int { return x } func beth() -> () -> Int { return aleph } - // CHECK: [[BETH_REF:%[0-9]+]] = function_ref @[[BETH_NAME:_TFF8closures18capture_local_funcFSiFT_FT_SiL_4bethfT_FT_Si]] : $@convention(thin) (@owned @box Int, @inout Int) -> @owned @callee_owned () -> Int - // CHECK: [[BETH_CLOSURE:%[0-9]+]] = partial_apply [[BETH_REF]]([[XBOX]]#0, [[XBOX]]#1) + // CHECK: [[BETH_REF:%[0-9]+]] = function_ref @[[BETH_NAME:_TFF8closures18capture_local_funcFSiFT_FT_SiL_4bethfT_FT_Si]] : $@convention(thin) (@owned @box Int) -> @owned @callee_owned () -> Int + // CHECK: [[BETH_CLOSURE:%[0-9]+]] = partial_apply [[BETH_REF]]([[XBOX]]#0) return beth // CHECK: release [[XBOX]]#0 // CHECK: return [[BETH_CLOSURE]] } // CHECK: sil shared @[[ALEPH_NAME:_TFF8closures18capture_local_funcFSiFT_FT_SiL_5alephfT_Si]] -// CHECK: bb0([[XBOX:%[0-9]+]] : $@box Int, [[XADDR:%[0-9]+]] : $*Int): +// CHECK: bb0([[XBOX:%[0-9]+]] : $@box Int): // CHECK: sil shared @[[BETH_NAME]] -// CHECK: bb0([[XBOX:%[0-9]+]] : $@box Int, [[XADDR:%[0-9]+]] : $*Int): -// CHECK: [[ALEPH_REF:%[0-9]+]] = function_ref @[[ALEPH_NAME]] : $@convention(thin) (@owned @box Int, @inout Int) -> Int -// CHECK: [[ALEPH_CLOSURE:%[0-9]+]] = partial_apply [[ALEPH_REF]]([[XBOX]], [[XADDR]]) +// CHECK: bb0([[XBOX:%[0-9]+]] : $@box Int): +// CHECK: [[ALEPH_REF:%[0-9]+]] = function_ref @[[ALEPH_NAME]] : $@convention(thin) (@owned @box Int) -> Int +// CHECK: [[ALEPH_CLOSURE:%[0-9]+]] = partial_apply [[ALEPH_REF]]([[XBOX]]) // CHECK: return [[ALEPH_CLOSURE]] // CHECK-LABEL: sil hidden @_TF8closures22anon_read_only_capture @@ -115,7 +117,7 @@ func anon_read_only_capture(x: Int) -> Int { return ({ x })() // -- func expression - // CHECK: [[ANON:%[0-9]+]] = function_ref @[[CLOSURE_NAME:_TFF8closures22anon_read_only_capture.*]] : $@convention(thin) (@inout Int) -> Int + // CHECK: [[ANON:%[0-9]+]] = function_ref @[[CLOSURE_NAME:_TFF8closures22anon_read_only_capture.*]] : $@convention(thin) (@inout_aliasable Int) -> Int // -- apply expression // CHECK: [[RET:%[0-9]+]] = apply [[ANON]]([[XBOX]]#1) // -- cleanup @@ -135,7 +137,7 @@ func small_closure_capture(x: Int) -> Int { return { x }() // -- func expression - // CHECK: [[ANON:%[0-9]+]] = function_ref @[[CLOSURE_NAME:_TFF8closures21small_closure_capture.*]] : $@convention(thin) (@inout Int) -> Int + // CHECK: [[ANON:%[0-9]+]] = function_ref @[[CLOSURE_NAME:_TFF8closures21small_closure_capture.*]] : $@convention(thin) (@inout_aliasable Int) -> Int // -- apply expression // CHECK: [[RET:%[0-9]+]] = apply [[ANON]]([[XBOX]]#1) // -- cleanup @@ -155,15 +157,16 @@ func small_closure_capture_with_argument(x: Int) -> (y: Int) -> Int { return { x + $0 } // -- func expression - // CHECK: [[ANON:%[0-9]+]] = function_ref @[[CLOSURE_NAME:_TFF8closures35small_closure_capture_with_argument.*]] : $@convention(thin) (Int, @owned @box Int, @inout Int) -> Int + // CHECK: [[ANON:%[0-9]+]] = function_ref @[[CLOSURE_NAME:_TFF8closures35small_closure_capture_with_argument.*]] : $@convention(thin) (Int, @owned @box Int) -> Int // CHECK: retain [[XBOX]]#0 - // CHECK: [[ANON_CLOSURE_APP:%[0-9]+]] = partial_apply [[ANON]]([[XBOX]]#0, [[XBOX]]#1) + // CHECK: [[ANON_CLOSURE_APP:%[0-9]+]] = partial_apply [[ANON]]([[XBOX]]#0) // -- return // CHECK: release [[XBOX]]#0 // CHECK: return [[ANON_CLOSURE_APP]] } -// CHECK: sil shared @[[CLOSURE_NAME]] : $@convention(thin) (Int, @owned @box Int, @inout Int) -> Int -// CHECK: bb0([[DOLLAR0:%[0-9]+]] : $Int, [[XBOX:%[0-9]+]] : $@box Int, [[XADDR:%[0-9]+]] : $*Int): +// CHECK: sil shared @[[CLOSURE_NAME]] : $@convention(thin) (Int, @owned @box Int) -> Int +// CHECK: bb0([[DOLLAR0:%[0-9]+]] : $Int, [[XBOX:%[0-9]+]] : $@box Int): +// CHECK: [[XADDR:%[0-9]+]] = project_box [[XBOX]] // CHECK: [[PLUS:%[0-9]+]] = function_ref @_TZFsoi1pFTSiSi_Si{{.*}} // CHECK: [[LHS:%[0-9]+]] = load [[XADDR]] // CHECK: [[RET:%[0-9]+]] = apply [[PLUS]]([[LHS]], [[DOLLAR0]]) @@ -206,8 +209,8 @@ class SomeClass { class SomeGenericClass { deinit { var i: Int = zero - // CHECK: [[C1REF:%[0-9]+]] = function_ref @_TFFC8closures16SomeGenericClassdU_FT_Si : $@convention(thin) (@inout Int) -> Int - // CHECK: apply [[C1REF]]([[IBOX:%[0-9]+]]#1) : $@convention(thin) (@inout Int) -> Int + // CHECK: [[C1REF:%[0-9]+]] = function_ref @_TFFC8closures16SomeGenericClassdU_FT_Si : $@convention(thin) (@inout_aliasable Int) -> Int + // CHECK: apply [[C1REF]]([[IBOX:%[0-9]+]]#1) : $@convention(thin) (@inout_aliasable Int) -> Int var x = { i + zero } () // CHECK: [[C2REF:%[0-9]+]] = function_ref @_TFFC8closures16SomeGenericClassdU0_FT_Si : $@convention(thin) () -> Int @@ -219,7 +222,7 @@ class SomeGenericClass { var z = { _ = T.self } () } - // CHECK-LABEL: sil shared @_TFFC8closures16SomeGenericClassdU_FT_Si : $@convention(thin) (@inout Int) -> Int + // CHECK-LABEL: sil shared @_TFFC8closures16SomeGenericClassdU_FT_Si : $@convention(thin) (@inout_aliasable Int) -> Int // CHECK-LABEL: sil shared @_TFFC8closures16SomeGenericClassdU0_FT_Si : $@convention(thin) () -> Int @@ -236,7 +239,7 @@ func generateWithConstant(x : SomeSpecificClass) { } // CHECK-LABEL: sil shared @_TFF8closures20generateWithConstant // CHECK: bb0([[T0:%.*]] : $SomeSpecificClass): -// CHECK-NEXT: debug_value %0 : $SomeSpecificClass // let x, argno: 1 +// CHECK-NEXT: debug_value %0 : $SomeSpecificClass, let, name "x", argno 1 // CHECK-NEXT: [[T1:%.*]] = upcast [[T0]] : $SomeSpecificClass to $SomeClass // CHECK-NEXT: return [[T1]] @@ -300,13 +303,13 @@ func closeOverLetLValue() { // is loadable even though we capture the value. // CHECK-LABEL: sil shared @_TFF8closures18closeOverLetLValueFT_T_U_FT_Si // CHECK: bb0(%0 : $ClassWithIntProperty): -// CHECK-NEXT: [[TMP:%.*]] = alloc_stack $ClassWithIntProperty // let a, argno: 1 -// CHECK-NEXT: store %0 to [[TMP]]#1 : $*ClassWithIntProperty -// CHECK-NEXT: {{.*}} = load [[TMP]]#1 : $*ClassWithIntProperty +// CHECK-NEXT: [[TMP:%.*]] = alloc_stack $ClassWithIntProperty, let, name "a", argno 1 +// CHECK-NEXT: store %0 to [[TMP]] : $*ClassWithIntProperty +// CHECK-NEXT: {{.*}} = load [[TMP]] : $*ClassWithIntProperty // CHECK-NEXT: {{.*}} = ref_element_addr {{.*}} : $ClassWithIntProperty, #ClassWithIntProperty.x // CHECK-NEXT: {{.*}} = load {{.*}} : $*Int -// CHECK-NEXT: destroy_addr [[TMP]]#1 : $*ClassWithIntProperty -// CHECK-NEXT: dealloc_stack %1#0 : $*@local_storage ClassWithIntProperty +// CHECK-NEXT: destroy_addr [[TMP]] : $*ClassWithIntProperty +// CHECK-NEXT: dealloc_stack %1 : $*ClassWithIntProperty // CHECK-NEXT: return @@ -328,13 +331,13 @@ struct StructWithMutatingMethod { // CHECK-LABEL: sil hidden @_TFV8closures24StructWithMutatingMethod14mutatingMethod // CHECK: bb0(%0 : $*StructWithMutatingMethod): -// CHECK-NEXT: %1 = alloc_box $StructWithMutatingMethod // var self, argno: 1 // users: %2, %5, %7, %8 +// CHECK-NEXT: %1 = alloc_box $StructWithMutatingMethod, var, name "self", argno 1 // users: %2, %5, %7, %8 // CHECK-NEXT: copy_addr %0 to [initialization] %1#1 : $*StructWithMutatingMethod // id: %2 -// CHECK: [[CLOSURE:%[0-9]+]] = function_ref @_TFFV8closures24StructWithMutatingMethod14mutatingMethod{{.*}} : $@convention(thin) (@inout StructWithMutatingMethod) -> Int -// CHECK: partial_apply [[CLOSURE]](%1#1) : $@convention(thin) (@inout StructWithMutatingMethod) -> Int +// CHECK: [[CLOSURE:%[0-9]+]] = function_ref @_TFFV8closures24StructWithMutatingMethod14mutatingMethod{{.*}} : $@convention(thin) (@inout_aliasable StructWithMutatingMethod) -> Int +// CHECK: partial_apply [[CLOSURE]](%1#1) : $@convention(thin) (@inout_aliasable StructWithMutatingMethod) -> Int // Check that the closure body only takes the pointer. -// CHECK-LABEL: sil shared @_TFFV8closures24StructWithMutatingMethod14mutatingMethod{{.*}} : $@convention(thin) (@inout StructWithMutatingMethod) -> Int { +// CHECK-LABEL: sil shared @_TFFV8closures24StructWithMutatingMethod14mutatingMethod{{.*}} : $@convention(thin) (@inout_aliasable StructWithMutatingMethod) -> Int { // CHECK: bb0(%0 : $*StructWithMutatingMethod): class SuperBase { @@ -352,7 +355,7 @@ class SuperSub : SuperBase { // CHECK: [[CLASS_METHOD:%.*]] = class_method %0 : $SuperSub, #SuperSub.boom!1 // CHECK: = apply [[CLASS_METHOD]](%0) // CHECK: [[SUPER:%.*]] = upcast %0 : $SuperSub to $SuperBase - // CHECK: [[SUPER_METHOD:%.*]] = function_ref @_TFC8closures9SuperBase4boom + // CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $SuperSub, #SuperBase.boom!1 // CHECK: = apply [[SUPER_METHOD]]([[SUPER]]) // CHECK: return func a1() { @@ -376,8 +379,8 @@ class SuperSub : SuperBase { // CHECK: [[CLASS_METHOD:%.*]] = class_method %0 : $SuperSub, #SuperSub.boom!1 // CHECK: = apply [[CLASS_METHOD]](%0) // CHECK: [[SUPER:%.*]] = upcast %0 : $SuperSub to $SuperBase - // CHECK: [[METHOD:%.*]] = function_ref @_TFC8closures9SuperBase4boom - // CHECK: = apply [[METHOD]]([[SUPER]]) + // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $SuperSub, #SuperBase.boom!1 + // CHECK: = apply [[SUPER_METHOD]]([[SUPER]]) // CHECK: return func b2() { self.boom() @@ -397,8 +400,8 @@ class SuperSub : SuperBase { // CHECK: [[CLASS_METHOD:%.*]] = class_method %0 : $SuperSub, #SuperSub.boom!1 // CHECK: = apply [[CLASS_METHOD]](%0) // CHECK: [[SUPER:%.*]] = upcast %0 : $SuperSub to $SuperBase - // CHECK: [[METHOD:%.*]] = function_ref @_TFC8closures9SuperBase4boom - // CHECK: = apply [[METHOD]]([[SUPER]]) + // CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $SuperSub, #SuperBase.boom!1 + // CHECK: = apply [[SUPER_METHOD]]([[SUPER]]) // CHECK: return let c1 = { () -> Void in self.boom() @@ -419,8 +422,8 @@ class SuperSub : SuperBase { let d1 = { () -> Void in // CHECK-LABEL: sil shared @_TFFFC8closures8SuperSub1d // CHECK: [[SUPER:%.*]] = upcast %0 : $SuperSub to $SuperBase - // CHECK: [[METHOD:%.*]] = function_ref @_TFC8closures9SuperBase4boom - // CHECK: = apply [[METHOD]]([[SUPER]]) + // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $SuperSub, #SuperBase.boom!1 + // CHECK: = apply [[SUPER_METHOD]]([[SUPER]]) // CHECK: return func d2() { super.boom() @@ -442,8 +445,8 @@ class SuperSub : SuperBase { func e1() { // CHECK-LABEL: sil shared @_TFFFC8closures8SuperSub1e // CHECK: [[SUPER:%.*]] = upcast %0 : $SuperSub to $SuperBase - // CHECK: [[METHOD:%.*]] = function_ref @_TFC8closures9SuperBase4boom - // CHECK: = apply [[METHOD]]([[SUPER]]) + // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $SuperSub, #SuperBase.boom!1 + // CHECK: = apply [[SUPER_METHOD]]([[SUPER]]) // CHECK: return let e2 = { super.boom() @@ -465,8 +468,8 @@ class SuperSub : SuperBase { let f1 = { // CHECK-LABEL: sil shared [transparent] @_TFFFC8closures8SuperSub1f // CHECK: [[SUPER:%.*]] = upcast %0 : $SuperSub to $SuperBase - // CHECK: [[METHOD:%.*]] = function_ref @_TFC8closures9SuperBase4boom - // CHECK: = apply [[METHOD]]([[SUPER]]) + // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $SuperSub, #SuperBase.boom!1 + // CHECK: = apply [[SUPER_METHOD]]([[SUPER]]) // CHECK: return nil ?? super.boom() } @@ -484,8 +487,8 @@ class SuperSub : SuperBase { func g1() { // CHECK-LABEL: sil shared [transparent] @_TFFFC8closures8SuperSub1g // CHECK: [[SUPER:%.*]] = upcast %0 : $SuperSub to $SuperBase - // CHECK: [[METHOD:%.*]] = function_ref @_TFC8closures9SuperBase4boom - // CHECK: = apply [[METHOD]]([[SUPER]]) + // CHECK: [[SUPER_METHOD:%.*]] = super_method %0 : $SuperSub, #SuperBase.boom!1 + // CHECK: = apply [[SUPER_METHOD]]([[SUPER]]) // CHECK: return nil ?? super.boom() } diff --git a/test/SILGen/collection_downcast.swift b/test/SILGen/collection_downcast.swift index ce97793872935..dd73bb2bb20e5 100644 --- a/test/SILGen/collection_downcast.swift +++ b/test/SILGen/collection_downcast.swift @@ -49,14 +49,14 @@ func testArrayDowncast(array: [AnyObject]) -> [BridgedObjC] { // CHECK-LABEL: sil hidden @_TF19collection_downcast27testArrayDowncastFromObject // CHECK: bb0([[OBJ:%[0-9]+]] : $AnyObject): func testArrayDowncastFromObject(obj: AnyObject) -> [BridgedObjC] { - // CHECK: unconditional_checked_cast_addr take_always AnyObject in [[OBJECT_ALLOC:%[0-9]+]]#1 : $*AnyObject to Array in [[VALUE_ALLOC:%[0-9]+]]#1 : $*Array + // CHECK: unconditional_checked_cast_addr take_always AnyObject in [[OBJECT_ALLOC:%[0-9]+]] : $*AnyObject to Array in [[VALUE_ALLOC:%[0-9]+]] : $*Array return obj as! [BridgedObjC] } // CHECK-LABEL: sil hidden @_TF19collection_downcast28testArrayDowncastFromNSArray // CHECK: bb0([[NSARRAY_OBJ:%[0-9]+]] : $NSArray): func testArrayDowncastFromNSArray(obj: NSArray) -> [BridgedObjC] { - // CHECK: unconditional_checked_cast_addr take_always NSArray in [[OBJECT_ALLOC:%[0-9]+]]#1 : $*NSArray to Array in [[VALUE_ALLOC:%[0-9]+]]#1 : $*Array + // CHECK: unconditional_checked_cast_addr take_always NSArray in [[OBJECT_ALLOC:%[0-9]+]] : $*NSArray to Array in [[VALUE_ALLOC:%[0-9]+]] : $*Array return obj as! [BridgedObjC] } @@ -104,7 +104,7 @@ func testArrayIsaBridged(array: [AnyObject]) -> Bool { // CHECK: bb0([[OBJ:%[0-9]+]] : $AnyObject): func testDictionaryDowncastFromObject(obj: AnyObject) -> Dictionary { - // CHECK: unconditional_checked_cast_addr take_always AnyObject in [[OBJECT_ALLOC:%[0-9]+]]#1 : $*AnyObject to Dictionary in [[VALUE_ALLOC:%[0-9]+]]#1 : $*Dictionary + // CHECK: unconditional_checked_cast_addr take_always AnyObject in [[OBJECT_ALLOC:%[0-9]+]] : $*AnyObject to Dictionary in [[VALUE_ALLOC:%[0-9]+]] : $*Dictionary return obj as! Dictionary } @@ -166,7 +166,7 @@ func testDictionaryDowncastBridgedKVConditional(dict: Dictionary Set { - // CHECK: unconditional_checked_cast_addr take_always AnyObject in [[OBJECT_ALLOC:%[0-9]+]]#1 : $*AnyObject to Set in [[VALUE_ALLOC:%[0-9]+]]#1 : $*Set + // CHECK: unconditional_checked_cast_addr take_always AnyObject in [[OBJECT_ALLOC:%[0-9]+]] : $*AnyObject to Set in [[VALUE_ALLOC:%[0-9]+]] : $*Set return obj as! Set } diff --git a/test/SILGen/coverage_guard.swift b/test/SILGen/coverage_guard.swift index f1df5dcef000a..747ee628c89f7 100644 --- a/test/SILGen/coverage_guard.swift +++ b/test/SILGen/coverage_guard.swift @@ -14,7 +14,7 @@ func foo(x : Int32) { // CHECK: [[@LINE]]:21 -> [[END:[0-9]+:2]] : 0 return } // CHECK: [[@LINE]]:4 -> [[END]] : (((0 - 1) - 2) - 4) - let z = x; + let z = x } foo(1); diff --git a/test/SILGen/coverage_member_closure.swift b/test/SILGen/coverage_member_closure.swift index 1733304855788..713cfda7d7f66 100644 --- a/test/SILGen/coverage_member_closure.swift +++ b/test/SILGen/coverage_member_closure.swift @@ -10,6 +10,6 @@ class C { // Closures in members show up at the end of the constructor's map. // CHECK-NOT: sil_coverage_map - // CHECK: [[@LINE+1]]:55 -> [[@LINE+1]]:77 : 2 - var completionHandler: (String, [String]) -> Void = {(foo, bar) in return} + // CHECK: [[@LINE+1]]:55 -> [[@LINE+1]]:79 : 2 + var completionHandler: (String, [String]) -> Void = { (foo, bar) in return } } diff --git a/test/SILGen/coverage_while.swift b/test/SILGen/coverage_while.swift index af4dee3210d22..40064d7f58119 100644 --- a/test/SILGen/coverage_while.swift +++ b/test/SILGen/coverage_while.swift @@ -5,7 +5,7 @@ func foo() -> Int32 { var x : Int32 = 0 // CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:17 : (0 + 1) while (x < 10) { - x++ + x += 1 } // CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:18 : (0 + 2) @@ -20,7 +20,7 @@ func foo() -> Int32 { // CHECK: [[@LINE+1]]:9 -> [[@LINE+1]]:18 : ((0 + 6) - 9) while (x < 100) { - x++ + x += 1 while (true) { break } if (x % 2 == 0) { continue } // CHECK: [[@LINE-1]]:33 -> [[@LINE+2]]:4 : (6 - 8) @@ -29,7 +29,7 @@ func foo() -> Int32 { // CHECK: [[@LINE+1]]:10 -> [[@LINE+4]]:4 : 10 repeat { - x-- + x -= 1 // CHECK: [[@LINE+1]]:11 -> [[@LINE+1]]:16 : 10 } while x > 0 @@ -38,7 +38,7 @@ func foo() -> Int32 { if (x == 40) { // CHECK: [[@LINE]]:18 -> [[@LINE+2]]:6 : 12 return x } - ++x + x += 1 } var y : Int32? = 2 diff --git a/test/SILGen/crashers_silgen.swift b/test/SILGen/crashers_silgen.swift new file mode 100644 index 0000000000000..5d9e2b64977f4 --- /dev/null +++ b/test/SILGen/crashers_silgen.swift @@ -0,0 +1,17 @@ +// RUN: %target-swift-frontend -emit-silgen -o /dev/null %s + +// Crash on Subscript taking a tuple argument list +class r22000564 { + subscript (position: (Int, Int)) -> Int { + get { return 32 } + set {} + } + subscript(native native: Int) -> Int { + get { return native } + set {} + } + subscript (position position: (Int, Int)) -> Int { + get { return 32 } + set {} + } +} diff --git a/test/SILGen/default_arguments_imported.swift b/test/SILGen/default_arguments_imported.swift new file mode 100644 index 0000000000000..c346dbc0a9822 --- /dev/null +++ b/test/SILGen/default_arguments_imported.swift @@ -0,0 +1,15 @@ +// RUN: %target-swift-frontend -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -emit-silgen -enable-infer-default-arguments | FileCheck %s + +// Test SIL generation for imported default arguments. + +// REQUIRES: objc_interop + +import gizmo + +// CHECK-LABEL: sil hidden @_TF26default_arguments_imported9testGizmo +func testGizmo(gizmo: Gizmo) { + // CHECK: class_method [volatile] [[SELF:%[0-9]+]] : $Gizmo, #Gizmo.enumerateSubGizmos!1.foreign + // CHECK-NOT: return + // CHECK: function_ref @_TFSqCfT10nilLiteralT__GSqx_ + gizmo.enumerateSubGizmos() +} diff --git a/test/SILGen/default_constructor.swift b/test/SILGen/default_constructor.swift index cbf3da4c619df..c2fccbe6b321b 100644 --- a/test/SILGen/default_constructor.swift +++ b/test/SILGen/default_constructor.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-silgen %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -emit-silgen %s | FileCheck %s struct B { var i : Int, j : Float @@ -52,7 +52,7 @@ class F : E { } // CHECK-NEXT: store [[ORIGSELF]] to [[SELF]] : $*F // CHECK-NEXT: [[SELFP:%[0-9]+]] = load [[SELF]] : $*F // CHECK-NEXT: [[E:%[0-9]]] = upcast [[SELFP]] : $F to $E -// CHECK: [[E_CTOR:%[0-9]+]] = function_ref @_TFC19default_constructor1Ec{{.*}} : $@convention(method) (@owned E) -> @owned E +// CHECK: [[E_CTOR:%[0-9]+]] = super_method [[SELFP]] : $F, #E.init!initializer.1 : E.Type -> () -> E , $@convention(method) (@owned E) -> @owned E // CHECK-NEXT: [[ESELF:%[0-9]]] = apply [[E_CTOR]]([[E]]) : $@convention(method) (@owned E) -> @owned E // CHECK-NEXT: [[ESELFW:%[0-9]+]] = unchecked_ref_cast [[ESELF]] : $E to $F diff --git a/test/SILGen/downcast_reabstraction.swift b/test/SILGen/downcast_reabstraction.swift index 520e9ed8ce809..c69ae3a7d069b 100644 --- a/test/SILGen/downcast_reabstraction.swift +++ b/test/SILGen/downcast_reabstraction.swift @@ -1,9 +1,9 @@ // RUN: %target-swift-frontend -emit-silgen %s | FileCheck %s // CHECK-LABEL: sil hidden @_TF22downcast_reabstraction19condFunctionFromAnyFP_T_ -// CHECK: checked_cast_addr_br take_always protocol<> in [[IN:%.*]]#1 : $*protocol<> to () -> () in [[OUT:%.*]]#1 : $*@callee_owned (@out (), @in ()) -> (), [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] +// CHECK: checked_cast_addr_br take_always protocol<> in [[IN:%.*]] : $*protocol<> to () -> () in [[OUT:%.*]] : $*@callee_owned (@out (), @in ()) -> (), [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] // CHECK: [[YES]]: -// CHECK: [[ORIG_VAL:%.*]] = load [[OUT]]#1 +// CHECK: [[ORIG_VAL:%.*]] = load [[OUT]] // CHECK: [[REABSTRACT:%.*]] = function_ref @_TTRXFo_iT__iT__XFo__dT__ // CHECK: [[SUBST_VAL:%.*]] = partial_apply [[REABSTRACT]]([[ORIG_VAL]]) @@ -14,8 +14,8 @@ func condFunctionFromAny(x: Any) { } // CHECK-LABEL: sil hidden @_TF22downcast_reabstraction21uncondFunctionFromAnyFP_T_ : $@convention(thin) (@in protocol<>) -> () { -// CHECK: unconditional_checked_cast_addr take_always protocol<> in [[IN:%.*]]#1 : $*protocol<> to () -> () in [[OUT:%.*]]#1 : $*@callee_owned (@out (), @in ()) -> () -// CHECK: [[ORIG_VAL:%.*]] = load [[OUT]]#1 +// CHECK: unconditional_checked_cast_addr take_always protocol<> in [[IN:%.*]] : $*protocol<> to () -> () in [[OUT:%.*]] : $*@callee_owned (@out (), @in ()) -> () +// CHECK: [[ORIG_VAL:%.*]] = load [[OUT]] // CHECK: [[REABSTRACT:%.*]] = function_ref @_TTRXFo_iT__iT__XFo__dT__ // CHECK: [[SUBST_VAL:%.*]] = partial_apply [[REABSTRACT]]([[ORIG_VAL]]) // CHECK: apply [[SUBST_VAL]]() diff --git a/test/SILGen/dynamic.swift b/test/SILGen/dynamic.swift index 917cd0ba2950b..a01b0b1d45d80 100644 --- a/test/SILGen/dynamic.swift +++ b/test/SILGen/dynamic.swift @@ -1,5 +1,5 @@ -// RUN: %target-swift-frontend -sdk %S/Inputs -I %S/Inputs -enable-source-import -primary-file %s %S/Inputs/dynamic_other.swift -emit-silgen | FileCheck %s -// RUN: %target-swift-frontend -sdk %S/Inputs -I %S/Inputs -enable-source-import -primary-file %s %S/Inputs/dynamic_other.swift -emit-sil -verify +// RUN: %target-swift-frontend -use-native-super-method -sdk %S/Inputs -I %S/Inputs -enable-source-import -primary-file %s %S/Inputs/dynamic_other.swift -emit-silgen | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -sdk %S/Inputs -I %S/Inputs -enable-source-import -primary-file %s %S/Inputs/dynamic_other.swift -emit-sil -verify // REQUIRES: objc_interop @@ -148,54 +148,54 @@ class Subclass: Foo { super.nativeMethod() } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclass12nativeMethod - // CHECK: function_ref @_TFC7dynamic3Foo12nativeMethod + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.nativeMethod!1 override var nativeProp: Int { get { return super.nativeProp } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclassg10nativePropSi - // CHECK: function_ref @_TFC7dynamic3Foog10nativePropSi + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.nativeProp!getter.1 set { super.nativeProp = newValue } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclasss10nativePropSi - // CHECK: function_ref @_TFC7dynamic3Foos10nativePropSi + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.nativeProp!setter.1 } override subscript(native native: Int) -> Int { get { return super[native: native] } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclassg9subscriptFT6nativeSi_Si - // CHECK: function_ref @_TFC7dynamic3Foog9subscriptFT6nativeSi_Si + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.subscript!getter.1 set { super[native: native] = newValue } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclasss9subscriptFT6nativeSi_Si - // CHECK: function_ref @_TFC7dynamic3Foos9subscriptFT6nativeSi_Si + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.subscript!setter.1 } override init(objc: Int) { super.init(objc: objc) } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclassc - // CHECK: function_ref @_TFC7dynamic3Fooc + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.init!initializer.1 override func objcMethod() { super.objcMethod() } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclass10objcMethod - // CHECK: function_ref @_TFC7dynamic3Foo10objcMethod + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.objcMethod!1 override var objcProp: Int { get { return super.objcProp } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclassg8objcPropSi - // CHECK: function_ref @_TFC7dynamic3Foog8objcPropSi + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.objcProp!getter.1 set { super.objcProp = newValue } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclasss8objcPropSi - // CHECK: function_ref @_TFC7dynamic3Foos8objcPropSi + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.objcProp!setter.1 } override subscript(objc objc: AnyObject) -> Int { get { return super[objc: objc] } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclassg9subscriptFT4objcPs9AnyObject__Si - // CHECK: function_ref @_TFC7dynamic3Foog9subscriptFT4objcPs9AnyObject__Si + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.subscript!getter.1 set { super[objc: objc] = newValue } // CHECK-LABEL: sil hidden @_TFC7dynamic8Subclasss9subscriptFT4objcPs9AnyObject__Si - // CHECK: function_ref @_TFC7dynamic3Foos9subscriptFT4objcPs9AnyObject__Si + // CHECK: super_method {{%[0-9]+}} : $Subclass, #Foo.subscript!setter.1 } // Dynamic methods are super-dispatched by objc_msgSend @@ -331,7 +331,7 @@ extension Gizmo { // CHECK-LABEL: sil hidden @_TF7dynamic24foreignExtensionDispatchFCSo5GizmoT_ func foreignExtensionDispatch(g: Gizmo) { - // CHECK: class_method [volatile] %0 : $Gizmo, #Gizmo.foreignObjCExtension!1.foreign : Gizmo + // CHECK: class_method [volatile] %0 : $Gizmo, #Gizmo.foreignObjCExtension!1.foreign : (Gizmo) g.foreignObjCExtension() // CHECK: class_method [volatile] %0 : $Gizmo, #Gizmo.foreignDynamicExtension!1.foreign g.foreignDynamicExtension() @@ -427,7 +427,7 @@ public class Sub : Base { // CHECK: } // CHECK-LABEL: sil shared [transparent] @_TFFC7dynamic3Subg1xSbu_KzT_Sb : $@convention(thin) (@owned Sub) -> (Bool, @error ErrorType) { - // CHECK: [[SUPER:%.*]] = super_method [volatile] %0 : $Sub, #Base.x!getter.1.foreign : Base -> () -> Bool , $@convention(objc_method) (Base) -> ObjCBool + // CHECK: [[SUPER:%.*]] = super_method [volatile] %0 : $Sub, #Base.x!getter.1.foreign : (Base) -> () -> Bool , $@convention(objc_method) (Base) -> ObjCBool // CHECK: = apply [[SUPER]]({{%.*}}) // CHECK: return {{%.*}} : $Bool // CHECK: } diff --git a/test/SILGen/dynamic_lookup.swift b/test/SILGen/dynamic_lookup.swift index 085819affc2d0..a62fcce77ec7e 100644 --- a/test/SILGen/dynamic_lookup.swift +++ b/test/SILGen/dynamic_lookup.swift @@ -24,7 +24,7 @@ class X { // CHECK-LABEL: sil hidden @_TF14dynamic_lookup15direct_to_class func direct_to_class(obj: AnyObject) { // CHECK: [[OBJ_SELF:%[0-9]+]] = open_existential_ref [[EX:%[0-9]+]] : $AnyObject to $@opened({{.*}}) AnyObject - // CHECK: [[METHOD:%[0-9]+]] = dynamic_method [volatile] [[OBJ_SELF]] : $@opened({{.*}}) AnyObject, #X.f!1.foreign : X -> () -> (), $@convention(objc_method) (@opened({{.*}}) AnyObject) -> () + // CHECK: [[METHOD:%[0-9]+]] = dynamic_method [volatile] [[OBJ_SELF]] : $@opened({{.*}}) AnyObject, #X.f!1.foreign : (X) -> () -> (), $@convention(objc_method) (@opened({{.*}}) AnyObject) -> () // CHECK: apply [[METHOD]]([[OBJ_SELF]]) : $@convention(objc_method) (@opened({{.*}}) AnyObject) -> () obj.f!() } @@ -32,7 +32,7 @@ func direct_to_class(obj: AnyObject) { // CHECK-LABEL: sil hidden @_TF14dynamic_lookup18direct_to_protocol func direct_to_protocol(obj: AnyObject) { // CHECK: [[OBJ_SELF:%[0-9]+]] = open_existential_ref [[EX:%[0-9]+]] : $AnyObject to $@opened({{.*}}) AnyObject - // CHECK: [[METHOD:%[0-9]+]] = dynamic_method [volatile] [[OBJ_SELF]] : $@opened({{.*}}) AnyObject, #P.g!1.foreign : <`Self` : P> Self -> () -> (), $@convention(objc_method) (@opened({{.*}}) AnyObject) -> () + // CHECK: [[METHOD:%[0-9]+]] = dynamic_method [volatile] [[OBJ_SELF]] : $@opened({{.*}}) AnyObject, #P.g!1.foreign : <`Self` : P> (Self) -> () -> (), $@convention(objc_method) (@opened({{.*}}) AnyObject) -> () // CHECK: apply [[METHOD]]([[OBJ_SELF]]) : $@convention(objc_method) (@opened({{.*}}) AnyObject) -> () obj.g!() } @@ -47,7 +47,7 @@ func direct_to_static_method(obj: AnyObject) { // CHECK-NEXT: [[OBJCOPY:%[0-9]+]] = load [[OBJBOX]]#1 : $*AnyObject // CHECK-NEXT: [[OBJMETA:%[0-9]+]] = existential_metatype $@thick AnyObject.Type, [[OBJCOPY]] : $AnyObject // CHECK-NEXT: [[OPENMETA:%[0-9]+]] = open_existential_metatype [[OBJMETA]] : $@thick AnyObject.Type to $@thick (@opened([[UUID:".*"]]) AnyObject).Type - // CHECK-NEXT: [[METHOD:%[0-9]+]] = dynamic_method [volatile] [[OPENMETA]] : $@thick (@opened([[UUID]]) AnyObject).Type, #X.staticF!1.foreign : X.Type -> () -> (), $@convention(objc_method) (@thick (@opened([[UUID]]) AnyObject).Type) -> () + // CHECK-NEXT: [[METHOD:%[0-9]+]] = dynamic_method [volatile] [[OPENMETA]] : $@thick (@opened([[UUID]]) AnyObject).Type, #X.staticF!1.foreign : (X.Type) -> () -> (), $@convention(objc_method) (@thick (@opened([[UUID]]) AnyObject).Type) -> () // CHECK: apply [[METHOD]]([[OPENMETA]]) : $@convention(objc_method) (@thick (@opened([[UUID]]) AnyObject).Type) -> () obj.dynamicType.staticF!() } @@ -84,9 +84,9 @@ func opt_to_class(obj: AnyObject) { // Continuation block // CHECK: [[CONTBB]]: - // CHECK-NEXT: [[OPT:%.*]] = load [[OPTTEMP]]#1 + // CHECK-NEXT: [[OPT:%.*]] = load [[OPTTEMP]] // CHECK-NEXT: store [[OPT]] to [[OPTBOX]]#1 : $*ImplicitlyUnwrappedOptional<() -> ()> - // CHECK-NEXT: dealloc_stack [[OPTTEMP]]#0 + // CHECK-NEXT: dealloc_stack [[OPTTEMP]] var of = obj.f // Exit diff --git a/test/SILGen/dynamic_self.swift b/test/SILGen/dynamic_self.swift index 8b273ee193751..b23dc2ee19341 100644 --- a/test/SILGen/dynamic_self.swift +++ b/test/SILGen/dynamic_self.swift @@ -36,7 +36,7 @@ func testDynamicSelfDispatch(y: Y) { // CHECK: bb0([[Y:%[0-9]+]] : $Y): // CHECK: strong_retain [[Y]] // CHECK: [[Y_AS_X:%[0-9]+]] = upcast [[Y]] : $Y to $X -// CHECK: [[X_F:%[0-9]+]] = class_method [[Y_AS_X]] : $X, #X.f!1 : Self -> () -> Self , $@convention(method) (@guaranteed X) -> @owned X +// CHECK: [[X_F:%[0-9]+]] = class_method [[Y_AS_X]] : $X, #X.f!1 : (Self) -> () -> Self , $@convention(method) (@guaranteed X) -> @owned X // CHECK: [[X_RESULT:%[0-9]+]] = apply [[X_F]]([[Y_AS_X]]) : $@convention(method) (@guaranteed X) -> @owned X // CHECK: strong_release [[Y_AS_X]] // CHECK: [[Y_RESULT:%[0-9]+]] = unchecked_ref_cast [[X_RESULT]] : $X to $Y @@ -50,7 +50,7 @@ func testDynamicSelfDispatchGeneric(gy: GY) { // CHECK: bb0([[GY:%[0-9]+]] : $GY): // CHECK: strong_retain [[GY]] // CHECK: [[GY_AS_GX:%[0-9]+]] = upcast [[GY]] : $GY to $GX> - // CHECK: [[GX_F:%[0-9]+]] = class_method [[GY_AS_GX]] : $GX>, #GX.f!1 : Self -> () -> Self , $@convention(method) <τ_0_0> (@guaranteed GX<τ_0_0>) -> @owned GX<τ_0_0> + // CHECK: [[GX_F:%[0-9]+]] = class_method [[GY_AS_GX]] : $GX>, #GX.f!1 : (Self) -> () -> Self , $@convention(method) <τ_0_0> (@guaranteed GX<τ_0_0>) -> @owned GX<τ_0_0> // CHECK: [[GX_RESULT:%[0-9]+]] = apply [[GX_F]]<[Int]>([[GY_AS_GX]]) : $@convention(method) <τ_0_0> (@guaranteed GX<τ_0_0>) -> @owned GX<τ_0_0> // CHECK: strong_release [[GY_AS_GX]] // CHECK: [[GY_RESULT:%[0-9]+]] = unchecked_ref_cast [[GX_RESULT]] : $GX> to $GY @@ -64,7 +64,7 @@ func testArchetypeDispatch(t: T) { // CHECK: bb0([[T:%[0-9]+]] : $*T): // CHECK: [[ARCHETYPE_F:%[0-9]+]] = witness_method $T, #P.f!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @in_guaranteed τ_0_0) -> () // CHECK: [[T_RESULT:%[0-9]+]] = alloc_stack $T - // CHECK: [[SELF_RESULT:%[0-9]+]] = apply [[ARCHETYPE_F]]([[T_RESULT]]#1, [[T]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @in_guaranteed τ_0_0) -> () + // CHECK: [[SELF_RESULT:%[0-9]+]] = apply [[ARCHETYPE_F]]([[T_RESULT]], [[T]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @in_guaranteed τ_0_0) -> () t.f() } @@ -73,11 +73,11 @@ func testExistentialDispatch(p: P) { // CHECK: bb0([[P:%[0-9]+]] : $*P): // CHECK: [[PCOPY_ADDR:%[0-9]+]] = open_existential_addr [[P]] : $*P to $*@opened([[N:".*"]]) P // CHECK: [[P_RESULT:%[0-9]+]] = alloc_stack $P -// CHECK: [[P_RESULT_ADDR:%[0-9]+]] = init_existential_addr [[P_RESULT]]#1 : $*P, $@opened([[N]]) P +// CHECK: [[P_RESULT_ADDR:%[0-9]+]] = init_existential_addr [[P_RESULT]] : $*P, $@opened([[N]]) P // CHECK: [[P_F_METHOD:%[0-9]+]] = witness_method $@opened([[N]]) P, #P.f!1, [[PCOPY_ADDR]]{{.*}} : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @in_guaranteed τ_0_0) -> () // CHECK: apply [[P_F_METHOD]]<@opened([[N]]) P>([[P_RESULT_ADDR]], [[PCOPY_ADDR]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @in_guaranteed τ_0_0) -> () -// CHECK: destroy_addr [[P_RESULT]]#1 : $*P -// CHECK: dealloc_stack [[P_RESULT]]#0 : $*@local_storage P +// CHECK: destroy_addr [[P_RESULT]] : $*P +// CHECK: dealloc_stack [[P_RESULT]] : $*P // CHECK: destroy_addr [[P]] : $*P p.f() } @@ -144,7 +144,7 @@ func testOptionalResult(v : OptionalResultInheritor) { v.foo()?.bar() } // CHECK-LABEL: sil hidden @_TF12dynamic_self18testOptionalResult{{.*}} : $@convention(thin) (@owned OptionalResultInheritor) -> () -// CHECK: [[T0:%.*]] = class_method [[V:%.*]] : $OptionalResult, #OptionalResult.foo!1 : Self -> () -> Self? , $@convention(method) (@guaranteed OptionalResult) -> @owned Optional +// CHECK: [[T0:%.*]] = class_method [[V:%.*]] : $OptionalResult, #OptionalResult.foo!1 : (Self) -> () -> Self? , $@convention(method) (@guaranteed OptionalResult) -> @owned Optional // CHECK-NEXT: [[RES:%.*]] = apply [[T0]]([[V]]) // CHECK: select_enum [[RES]] // CHECK: [[T1:%.*]] = unchecked_enum_data [[RES]] diff --git a/test/SILGen/enum.swift b/test/SILGen/enum.swift index ad31a074a08e3..dd0c59c74e407 100644 --- a/test/SILGen/enum.swift +++ b/test/SILGen/enum.swift @@ -1,14 +1,185 @@ // RUN: %target-swift-frontend -parse-as-library -parse-stdlib -emit-silgen %s | FileCheck %s +enum Boolish { + case falsy + case truthy +} + +// CHECK-LABEL: sil hidden @_TF4enum13Boolish_casesFT_T_ +func Boolish_cases() { + // CHECK: [[BOOLISH:%[0-9]+]] = metatype $@thin Boolish.Type + // CHECK-NEXT: [[FALSY:%[0-9]+]] = enum $Boolish, #Boolish.falsy!enumelt + _ = Boolish.falsy + + // CHECK-NEXT: [[BOOLISH:%[0-9]+]] = metatype $@thin Boolish.Type + // CHECK-NEXT: [[TRUTHY:%[0-9]+]] = enum $Boolish, #Boolish.truthy!enumelt + _ = Boolish.truthy +} + +struct Int {} + +enum Optionable { + case nought + case mere(Int) +} + +// CHECK-LABEL: sil hidden @_TF4enum16Optionable_casesFVS_3IntT_ +func Optionable_cases(x: Int) { + + // CHECK: [[FN:%.*]] = function_ref @_TFO4enum10Optionable4mereFMS0_FVS_3IntS0_ + // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin Optionable.Type + // CHECK-NEXT: [[CTOR:%.*]] = apply [[FN]]([[METATYPE]]) + // CHECK-NEXT: strong_release [[CTOR]] + _ = Optionable.mere + + // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin Optionable.Type + // CHECK-NEXT: [[RES:%.*]] = enum $Optionable, #Optionable.mere!enumelt.1, %0 : $Int + _ = Optionable.mere(x) +} + +// CHECK-LABEL: sil shared [transparent] @_TFO4enum10Optionable4mereFMS0_FVS_3IntS0_ +// CHECK: [[FN:%.*]] = function_ref @_TFO4enum10Optionable4merefMS0_FVS_3IntS0_ +// CHECK-NEXT: [[METHOD:%.*]] = partial_apply [[FN]](%0) +// CHECK-NEXT: return [[METHOD]] +// CHECK-NEXT: } + +// CHECK-LABEL: sil shared [transparent] @_TFO4enum10Optionable4merefMS0_FVS_3IntS0_ +// CHECK: [[RES:%.*]] = enum $Optionable, #Optionable.mere!enumelt.1, %0 : $Int +// CHECK-NEXT: return [[RES]] : $Optionable +// CHECK-NEXT: } + protocol P {} +struct S : P {} + +enum AddressOnly { + case nought + case mere(P) + case phantom(S) +} + +// CHECK-LABEL: sil hidden @_TF4enum17AddressOnly_casesFVS_1ST_ +func AddressOnly_cases(s: S) { + + // CHECK: [[FN:%.*]] = function_ref @_TFO4enum11AddressOnly4mereFMS0_FPS_1P_S0_ + // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin AddressOnly.Type + // CHECK-NEXT: [[CTOR:%.*]] = apply [[FN]]([[METATYPE]]) + // CHECK-NEXT: strong_release [[CTOR]] + _ = AddressOnly.mere + + // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin AddressOnly.Type + // CHECK-NEXT: [[NOUGHT:%.*]] = alloc_stack $AddressOnly + // CHECK-NEXT: inject_enum_addr [[NOUGHT]] + // CHECK-NEXT: destroy_addr [[NOUGHT]] + // CHECK-NEXT: dealloc_stack [[NOUGHT]] + _ = AddressOnly.nought + + // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin AddressOnly.Type + // CHECK-NEXT: [[MERE:%.*]] = alloc_stack $AddressOnly + // CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[MERE]] + // CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = init_existential_addr [[PAYLOAD]] + // CHECK-NEXT: store %0 to [[PAYLOAD_ADDR]] + // CHECK-NEXT: inject_enum_addr [[MERE]] + // CHECK-NEXT: destroy_addr [[MERE]] + // CHECK-NEXT: dealloc_stack [[MERE]] + _ = AddressOnly.mere(s) + + // Address-only enum vs loadable payload + + // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin AddressOnly.Type + // CHECK-NEXT: [[PHANTOM:%.*]] = alloc_stack $AddressOnly + // CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[PHANTOM]] : $*AddressOnly, #AddressOnly.phantom!enumelt.1 + // CHECK-NEXT: store %0 to [[PAYLOAD]] + // CHECK-NEXT: inject_enum_addr [[PHANTOM]] : $*AddressOnly, #AddressOnly.phantom!enumelt.1 + // CHECK-NEXT: destroy_addr [[PHANTOM]] + // CHECK-NEXT: dealloc_stack [[PHANTOM]] + + _ = AddressOnly.phantom(s) + // CHECK: return +} + +// CHECK-LABEL: sil shared [transparent] @_TFO4enum11AddressOnly4mereFMS0_FPS_1P_S0_ +// CHECK: [[FN:%.*]] = function_ref @_TFO4enum11AddressOnly4merefMS0_FPS_1P_S0_ +// CHECK-NEXT: [[METHOD:%.*]] = partial_apply [[FN]](%0) +// CHECK-NEXT: return [[METHOD]] : $@callee_owned (@out AddressOnly, @in P) -> () +// CHECK-NEXT: } + +// CHECK-LABEL: sil shared [transparent] @_TFO4enum11AddressOnly4merefMS0_FPS_1P_S0_ +// CHECK: [[RET_DATA:%.*]] = init_enum_data_addr %0 : $*AddressOnly, #AddressOnly.mere!enumelt.1 +// CHECK-NEXT: copy_addr [take] %1 to [initialization] [[RET_DATA]] : $*P +// CHECK-NEXT: inject_enum_addr %0 : $*AddressOnly, #AddressOnly.mere!enumelt.1 +// CHECK: return +// CHECK-NEXT: } + +enum PolyOptionable { + case nought + case mere(T) +} + +// CHECK-LABEL: sil hidden @_TF4enum20PolyOptionable_casesurFxT_ +func PolyOptionable_cases(t: T) { + +// CHECK: [[METATYPE:%.*]] = metatype $@thin PolyOptionable.Type +// CHECK-NEXT: [[NOUGHT:%.*]] = alloc_stack $PolyOptionable +// CHECK-NEXT: inject_enum_addr [[NOUGHT]] +// CHECK-NEXT: destroy_addr [[NOUGHT]] +// CHECK-NEXT: dealloc_stack [[NOUGHT]] + _ = PolyOptionable.nought + +// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin PolyOptionable.Type +// CHECK-NEXT: [[MERE:%.*]] = alloc_stack $PolyOptionable +// CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[MERE]] +// CHECK-NEXT: copy_addr %0 to [initialization] [[PAYLOAD]] +// CHECK-NEXT: inject_enum_addr [[MERE]] +// CHECK-NEXT: destroy_addr [[MERE]] +// CHECK-NEXT: dealloc_stack [[MERE]] + + _ = PolyOptionable.mere(t) + +// CHECK-NEXT: destroy_addr %0 +// CHECK: return + +} + +// The substituted type is loadable and trivial here + +// CHECK-LABEL: sil hidden @_TF4enum32PolyOptionable_specialized_casesFVS_3IntT_ +func PolyOptionable_specialized_cases(t: Int) { + +// CHECK: [[METATYPE:%.*]] = metatype $@thin PolyOptionable.Type +// CHECK-NEXT: [[NOUGHT:%.*]] = enum $PolyOptionable, #PolyOptionable.nought!enumelt + _ = PolyOptionable.nought + +// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin PolyOptionable.Type +// CHECK-NEXT: [[NOUGHT:%.*]] = enum $PolyOptionable, #PolyOptionable.mere!enumelt.1, %0 + _ = PolyOptionable.mere(t) + +// CHECK: return + +} -struct String { var ptr: Builtin.NativeObject } // Regression test for a bug where temporary allocations created as a result of // tuple implosion were not deallocated in enum constructors. +struct String { var ptr: Builtin.NativeObject } + enum Foo { case A(P, String) } -// CHECK: sil hidden [transparent] @_TFO4enum3Foo1AfMS0_FTPS_1P_VS_6String_S0_ : $@convention(thin) (@out Foo, @in P, @owned String, @thin Foo.Type) -> () { -// CHECK: [[ALLOC:%.*]] = alloc_stack $(P, String) -// CHECK: dealloc_stack [[ALLOC]]#0 -// CHECK: } +// CHECK-LABEL: sil shared [transparent] @_TFO4enum3Foo1AFMS0_FTPS_1P_VS_6String_S0_ +// CHECK: [[FN:%.*]] = function_ref @_TFO4enum3Foo1AfMS0_FTPS_1P_VS_6String_S0_ +// CHECK-NEXT: [[METHOD:%.*]] = partial_apply [[FN]](%0) +// CHECK-NEXT: return [[METHOD]] +// CHECK-NEXT: } + +// CHECK-LABEL: sil shared [transparent] @_TFO4enum3Foo1AfMS0_FTPS_1P_VS_6String_S0_ +// CHECK: [[PAYLOAD:%.*]] = init_enum_data_addr %0 : $*Foo, #Foo.A!enumelt.1 +// CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[PAYLOAD]] : $*(P, String), 0 +// CHECK-NEXT: [[RIGHT:%.*]] = tuple_element_addr [[PAYLOAD]] : $*(P, String), 1 +// CHECK-NEXT: copy_addr [take] %1 to [initialization] [[LEFT]] : $*P +// CHECK-NEXT: store %2 to [[RIGHT]] +// CHECK-NEXT: inject_enum_addr %0 : $*Foo, #Foo.A!enumelt.1 +// CHECK: return +// CHECK-NEXT: } + +func Foo_cases() { + _ = Foo.A +} diff --git a/test/SILGen/enum_resilience.swift b/test/SILGen/enum_resilience.swift index b5a0d4309aad5..f19d2833b03cf 100644 --- a/test/SILGen/enum_resilience.swift +++ b/test/SILGen/enum_resilience.swift @@ -7,25 +7,25 @@ import resilient_enum // CHECK-LABEL: sil hidden @_TF15enum_resilience15resilientSwitchFO14resilient_enum6MediumT_ : $@convention(thin) (@in Medium) -> () // CHECK: [[BOX:%.*]] = alloc_stack $Medium -// CHECK-NEXT: copy_addr %0 to [initialization] [[BOX]]#1 -// CHECK-NEXT: switch_enum_addr [[BOX]]#1 : $*Medium, case #Medium.Paper!enumelt: bb1, case #Medium.Canvas!enumelt: bb2, case #Medium.Pamphlet!enumelt.1: bb3, case #Medium.Postcard!enumelt.1: bb4, default bb5 +// CHECK-NEXT: copy_addr %0 to [initialization] [[BOX]] +// CHECK-NEXT: switch_enum_addr [[BOX]] : $*Medium, case #Medium.Paper!enumelt: bb1, case #Medium.Canvas!enumelt: bb2, case #Medium.Pamphlet!enumelt.1: bb3, case #Medium.Postcard!enumelt.1: bb4, default bb5 // CHECK: bb1: -// CHECK-NEXT: dealloc_stack [[BOX]]#0 +// CHECK-NEXT: dealloc_stack [[BOX]] // CHECK-NEXT: br bb6 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[BOX]]#0 +// CHECK-NEXT: dealloc_stack [[BOX]] // CHECK-NEXT: br bb6 // CHECK: bb3: -// CHECK-NEXT: [[INDIRECT_ADDR:%.*]] = unchecked_take_enum_data_addr [[BOX]]#1 +// CHECK-NEXT: [[INDIRECT_ADDR:%.*]] = unchecked_take_enum_data_addr [[BOX]] // CHECK-NEXT: [[INDIRECT:%.*]] = load [[INDIRECT_ADDR]] // CHECK-NEXT: [[PAYLOAD:%.*]] = project_box [[INDIRECT]] // CHECK-NEXT: strong_release [[INDIRECT]] -// CHECK-NEXT: dealloc_stack [[BOX]]#0 +// CHECK-NEXT: dealloc_stack [[BOX]] // CHECK-NEXT: br bb6 // CHECK: bb4: -// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = unchecked_take_enum_data_addr [[BOX]]#1 +// CHECK-NEXT: [[PAYLOAD_ADDR:%.*]] = unchecked_take_enum_data_addr [[BOX]] // CHECK-NEXT: destroy_addr [[PAYLOAD_ADDR]] -// CHECK-NEXT: dealloc_stack [[BOX]]#0 +// CHECK-NEXT: dealloc_stack [[BOX]] // CHECK-NEXT: br bb6 // CHECK: bb5: // CHECK-NEXT: unreachable diff --git a/test/SILGen/errors.swift b/test/SILGen/errors.swift index 4595cf2c81ae2..5622e81587b67 100644 --- a/test/SILGen/errors.swift +++ b/test/SILGen/errors.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -parse-stdlib -emit-silgen -verify %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -parse-stdlib -emit-silgen -verify %s | FileCheck %s import Swift @@ -21,10 +21,9 @@ func make_a_cat() throws -> Cat { // CHECK: sil hidden @_TF6errors15dont_make_a_cat{{.*}} : $@convention(thin) () -> (@owned Cat, @error ErrorType) { // CHECK: [[BOX:%.*]] = alloc_existential_box $ErrorType, $HomeworkError -// CHECK: [[T0:%.*]] = function_ref @_TFO6errors13HomeworkError7TooHardFMS0_S0_ : $@convention(thin) (@thin HomeworkError.Type) -> @owned HomeworkError -// CHECK-NEXT: [[T1:%.*]] = metatype $@thin HomeworkError.Type -// CHECK-NEXT: [[T2:%.*]] = apply [[T0]]([[T1]]) -// CHECK-NEXT: store [[T2]] to [[BOX]]#1 +// CHECK-NEXT: [[T0:%.*]] = metatype $@thin HomeworkError.Type +// CHECK-NEXT: [[T1:%.*]] = enum $HomeworkError, #HomeworkError.TooHard!enumelt +// CHECK-NEXT: store [[T1]] to [[BOX]]#1 // CHECK-NEXT: builtin "willThrow" // CHECK-NEXT: throw [[BOX]]#0 func dont_make_a_cat() throws -> Cat { @@ -33,10 +32,9 @@ func dont_make_a_cat() throws -> Cat { // CHECK: sil hidden @_TF6errors11dont_return{{.*}} : $@convention(thin) (@out T, @in T) -> @error ErrorType { // CHECK: [[BOX:%.*]] = alloc_existential_box $ErrorType, $HomeworkError -// CHECK: [[T0:%.*]] = function_ref @_TFO6errors13HomeworkError7TooMuchFMS0_S0_ : $@convention(thin) (@thin HomeworkError.Type) -> @owned HomeworkError -// CHECK-NEXT: [[T1:%.*]] = metatype $@thin HomeworkError.Type -// CHECK-NEXT: [[T2:%.*]] = apply [[T0]]([[T1]]) -// CHECK-NEXT: store [[T2]] to [[BOX]]#1 +// CHECK-NEXT: [[T0:%.*]] = metatype $@thin HomeworkError.Type +// CHECK-NEXT: [[T1:%.*]] = enum $HomeworkError, #HomeworkError.TooMuch!enumelt +// CHECK-NEXT: store [[T1]] to [[BOX]]#1 // CHECK-NEXT: builtin "willThrow" // CHECK-NEXT: destroy_addr %1 : $*T // CHECK-NEXT: throw [[BOX]]#0 @@ -68,13 +66,13 @@ func dont_return(argument: T) throws -> T { // Merge point for the ternary operator. Call dont_return with the result. // CHECK: [[TERNARY_CONT]]([[T0:%.*]] : $Cat): // CHECK-NEXT: [[ARG_TEMP:%.*]] = alloc_stack $Cat -// CHECK-NEXT: store [[T0]] to [[ARG_TEMP]]#1 +// CHECK-NEXT: store [[T0]] to [[ARG_TEMP]] // CHECK-NEXT: [[RET_TEMP:%.*]] = alloc_stack $Cat -// CHECK-NEXT: try_apply [[DR_FN]]([[RET_TEMP]]#1, [[ARG_TEMP]]#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> @error ErrorType, normal [[DR_NORMAL:bb[0-9]+]], error [[DR_ERROR:bb[0-9]+]] +// CHECK-NEXT: try_apply [[DR_FN]]([[RET_TEMP]], [[ARG_TEMP]]) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> @error ErrorType, normal [[DR_NORMAL:bb[0-9]+]], error [[DR_ERROR:bb[0-9]+]] // CHECK: [[DR_NORMAL]]({{%.*}} : $()): -// CHECK-NEXT: [[T0:%.*]] = load [[RET_TEMP]]#1 : $*Cat -// CHECK-NEXT: dealloc_stack [[RET_TEMP]]#0 -// CHECK-NEXT: dealloc_stack [[ARG_TEMP]]#0 +// CHECK-NEXT: [[T0:%.*]] = load [[RET_TEMP]] : $*Cat +// CHECK-NEXT: dealloc_stack [[RET_TEMP]] +// CHECK-NEXT: dealloc_stack [[ARG_TEMP]] // CHECK-NEXT: br [[RETURN:bb[0-9]+]]([[T0]] : $Cat) // Return block. @@ -84,33 +82,33 @@ func dont_return(argument: T) throws -> T { // Catch dispatch block. // CHECK: [[CATCH:bb[0-9]+]]([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: [[SRC_TEMP:%.*]] = alloc_stack $ErrorType -// CHECK-NEXT: store [[ERROR]] to [[SRC_TEMP]]#1 +// CHECK-NEXT: store [[ERROR]] to [[SRC_TEMP]] // CHECK-NEXT: [[DEST_TEMP:%.*]] = alloc_stack $HomeworkError -// CHECK-NEXT: checked_cast_addr_br copy_on_success ErrorType in [[SRC_TEMP]]#1 : $*ErrorType to HomeworkError in [[DEST_TEMP]]#1 : $*HomeworkError, [[IS_HWE:bb[0-9]+]], [[NOT_HWE:bb[0-9]+]] +// CHECK-NEXT: checked_cast_addr_br copy_on_success ErrorType in [[SRC_TEMP]] : $*ErrorType to HomeworkError in [[DEST_TEMP]] : $*HomeworkError, [[IS_HWE:bb[0-9]+]], [[NOT_HWE:bb[0-9]+]] // Catch HomeworkError. // CHECK: [[IS_HWE]]: -// CHECK-NEXT: [[T0:%.*]] = load [[DEST_TEMP]]#1 : $*HomeworkError +// CHECK-NEXT: [[T0:%.*]] = load [[DEST_TEMP]] : $*HomeworkError // CHECK-NEXT: switch_enum [[T0]] : $HomeworkError, case #HomeworkError.CatAteIt!enumelt.1: [[MATCH:bb[0-9]+]], default [[NO_MATCH:bb[0-9]+]] // Catch HomeworkError.CatAteIt. // CHECK: [[MATCH]]([[T0:%.*]] : $Cat): // CHECK-NEXT: debug_value -// CHECK-NEXT: dealloc_stack [[DEST_TEMP]]#0 -// CHECK-NEXT: destroy_addr [[SRC_TEMP]]#1 -// CHECK-NEXT: dealloc_stack [[SRC_TEMP]]#0 +// CHECK-NEXT: dealloc_stack [[DEST_TEMP]] +// CHECK-NEXT: destroy_addr [[SRC_TEMP]] +// CHECK-NEXT: dealloc_stack [[SRC_TEMP]] // CHECK-NEXT: br [[RETURN]]([[T0]] : $Cat) // Catch other HomeworkErrors. // CHECK: [[NO_MATCH]]: -// CHECK-NEXT: dealloc_stack [[DEST_TEMP]]#0 -// CHECK-NEXT: dealloc_stack [[SRC_TEMP]]#0 +// CHECK-NEXT: dealloc_stack [[DEST_TEMP]] +// CHECK-NEXT: dealloc_stack [[SRC_TEMP]] // CHECK-NEXT: br [[CATCHALL:bb[0-9]+]] // Catch other types. // CHECK: [[NOT_HWE]]: -// CHECK-NEXT: dealloc_stack [[DEST_TEMP]]#0 -// CHECK-NEXT: dealloc_stack [[SRC_TEMP]]#0 +// CHECK-NEXT: dealloc_stack [[DEST_TEMP]] +// CHECK-NEXT: dealloc_stack [[SRC_TEMP]] // CHECK-NEXT: br [[CATCHALL:bb[0-9]+]] // Catch all. @@ -205,16 +203,16 @@ protocol Doomed { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWV6errors12DoomedStructS_6DoomedS_FS1_5check{{.*}} : $@convention(witness_method) (@in_guaranteed DoomedStruct) -> @error ErrorType // CHECK: [[TEMP:%.*]] = alloc_stack $DoomedStruct -// CHECK: copy_addr %0 to [initialization] [[TEMP]]#1 -// CHECK: [[SELF:%.*]] = load [[TEMP]]#1 : $*DoomedStruct +// CHECK: copy_addr %0 to [initialization] [[TEMP]] +// CHECK: [[SELF:%.*]] = load [[TEMP]] : $*DoomedStruct // CHECK: [[T0:%.*]] = function_ref @_TFV6errors12DoomedStruct5check{{.*}} : $@convention(method) (DoomedStruct) -> @error ErrorType // CHECK-NEXT: try_apply [[T0]]([[SELF]]) // CHECK: bb1([[T0:%.*]] : $()): -// CHECK: dealloc_stack [[TEMP]]#0 +// CHECK: dealloc_stack [[TEMP]] // CHECK: return [[T0]] : $() // CHECK: bb2([[T0:%.*]] : $ErrorType): // CHECK: builtin "willThrow"([[T0]] : $ErrorType) -// CHECK: dealloc_stack [[TEMP]]#0 +// CHECK: dealloc_stack [[TEMP]] // CHECK: throw [[T0]] : $ErrorType struct DoomedStruct : Doomed { func check() throws {} @@ -222,18 +220,18 @@ struct DoomedStruct : Doomed { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWC6errors11DoomedClassS_6DoomedS_FS1_5check{{.*}} : $@convention(witness_method) (@in_guaranteed DoomedClass) -> @error ErrorType { // CHECK: [[TEMP:%.*]] = alloc_stack $DoomedClass -// CHECK: copy_addr %0 to [initialization] [[TEMP]]#1 -// CHECK: [[SELF:%.*]] = load [[TEMP]]#1 : $*DoomedClass -// CHECK: [[T0:%.*]] = class_method [[SELF]] : $DoomedClass, #DoomedClass.check!1 : DoomedClass -> () throws -> () , $@convention(method) (@guaranteed DoomedClass) -> @error ErrorType +// CHECK: copy_addr %0 to [initialization] [[TEMP]] +// CHECK: [[SELF:%.*]] = load [[TEMP]] : $*DoomedClass +// CHECK: [[T0:%.*]] = class_method [[SELF]] : $DoomedClass, #DoomedClass.check!1 : (DoomedClass) -> () throws -> () , $@convention(method) (@guaranteed DoomedClass) -> @error ErrorType // CHECK-NEXT: try_apply [[T0]]([[SELF]]) // CHECK: bb1([[T0:%.*]] : $()): // CHECK: strong_release [[SELF]] : $DoomedClass -// CHECK: dealloc_stack [[TEMP]]#0 +// CHECK: dealloc_stack [[TEMP]] // CHECK: return [[T0]] : $() // CHECK: bb2([[T0:%.*]] : $ErrorType): // CHECK: builtin "willThrow"([[T0]] : $ErrorType) // CHECK: strong_release [[SELF]] : $DoomedClass -// CHECK: dealloc_stack [[TEMP]]#0 +// CHECK: dealloc_stack [[TEMP]] // CHECK: throw [[T0]] : $ErrorType class DoomedClass : Doomed { func check() throws {} @@ -241,11 +239,11 @@ class DoomedClass : Doomed { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWV6errors11HappyStructS_6DoomedS_FS1_5check{{.*}} : $@convention(witness_method) (@in_guaranteed HappyStruct) -> @error ErrorType // CHECK: [[TEMP:%.*]] = alloc_stack $HappyStruct -// CHECK: copy_addr %0 to [initialization] [[TEMP]]#1 -// CHECK: [[SELF:%.*]] = load [[TEMP]]#1 : $*HappyStruct +// CHECK: copy_addr %0 to [initialization] [[TEMP]] +// CHECK: [[SELF:%.*]] = load [[TEMP]] : $*HappyStruct // CHECK: [[T0:%.*]] = function_ref @_TFV6errors11HappyStruct5check{{.*}} : $@convention(method) (HappyStruct) -> () // CHECK: [[T1:%.*]] = apply [[T0]]([[SELF]]) -// CHECK: dealloc_stack [[TEMP]]#0 +// CHECK: dealloc_stack [[TEMP]] // CHECK: return [[T1]] : $() struct HappyStruct : Doomed { func check() {} @@ -253,12 +251,12 @@ struct HappyStruct : Doomed { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWC6errors10HappyClassS_6DoomedS_FS1_5check{{.*}} : $@convention(witness_method) (@in_guaranteed HappyClass) -> @error ErrorType // CHECK: [[TEMP:%.*]] = alloc_stack $HappyClass -// CHECK: copy_addr %0 to [initialization] [[TEMP]]#1 -// CHECK: [[SELF:%.*]] = load [[TEMP]]#1 : $*HappyClass -// CHECK: [[T0:%.*]] = class_method [[SELF]] : $HappyClass, #HappyClass.check!1 : HappyClass -> () -> () , $@convention(method) (@guaranteed HappyClass) -> () +// CHECK: copy_addr %0 to [initialization] [[TEMP]] +// CHECK: [[SELF:%.*]] = load [[TEMP]] : $*HappyClass +// CHECK: [[T0:%.*]] = class_method [[SELF]] : $HappyClass, #HappyClass.check!1 : (HappyClass) -> () -> () , $@convention(method) (@guaranteed HappyClass) -> () // CHECK: [[T1:%.*]] = apply [[T0]]([[SELF]]) // CHECK: strong_release [[SELF]] : $HappyClass -// CHECK: dealloc_stack [[TEMP]]#0 +// CHECK: dealloc_stack [[TEMP]] // CHECK: return [[T1]] : $() class HappyClass : Doomed { func check() {} @@ -467,8 +465,7 @@ class BaseThrowingInit : HasThrowingInit { // Super delegation. // CHECK-NEXT: [[T0:%.*]] = load [[MARKED_BOX]] // CHECK-NEXT: [[T2:%.*]] = upcast [[T0]] : $BaseThrowingInit to $HasThrowingInit -// CHECK-NEXT: function_ref -// CHECK-NEXT: [[T3:%.*]] = function_ref @_TFC6errors15HasThrowingInitc +// CHECK-NEXT: [[T3:%[0-9]+]] = super_method [[T0]] : $BaseThrowingInit, #HasThrowingInit.init!initializer.1 // CHECK-NEXT: apply [[T3]](%0, [[T2]]) // Cleanups for writebacks. @@ -488,9 +485,9 @@ func supportFirstStructure(inout b: B) throws { // CHECK: [[SUPPORT:%.*]] = witness_method $B.Structure, #Supportable.support!1 : // CHECK: [[MATBUFFER:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer // CHECK: [[BUFFER:%.*]] = alloc_stack $B.Structure -// CHECK: [[BUFFER_CAST:%.*]] = address_to_pointer [[BUFFER]]#1 : $*B.Structure to $Builtin.RawPointer +// CHECK: [[BUFFER_CAST:%.*]] = address_to_pointer [[BUFFER]] : $*B.Structure to $Builtin.RawPointer // CHECK: [[MAT:%.*]] = witness_method $B, #Buildable.firstStructure!materializeForSet.1 : -// CHECK: [[T1:%.*]] = apply [[MAT]]([[BUFFER_CAST]], [[MATBUFFER]]#1, [[BASE:%.*#1]]) +// CHECK: [[T1:%.*]] = apply [[MAT]]([[BUFFER_CAST]], [[MATBUFFER]], [[BASE:%.*#1]]) // CHECK: [[T2:%.*]] = tuple_extract [[T1]] : {{.*}}, 0 // CHECK: [[T3:%.*]] = pointer_to_address [[T2]] : $Builtin.RawPointer to $*B.Structure // CHECK: [[CALLBACK:%.*]] = tuple_extract [[T1]] : {{.*}}, 1 @@ -519,9 +516,9 @@ func supportStructure(inout b: B, name: String) throws { // CHECK: retain_value [[INDEX:%1]] : $String // CHECK: [[MATBUFFER:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer // CHECK: [[BUFFER:%.*]] = alloc_stack $B.Structure -// CHECK: [[BUFFER_CAST:%.*]] = address_to_pointer [[BUFFER]]#1 : $*B.Structure to $Builtin.RawPointer +// CHECK: [[BUFFER_CAST:%.*]] = address_to_pointer [[BUFFER]] : $*B.Structure to $Builtin.RawPointer // CHECK: [[MAT:%.*]] = witness_method $B, #Buildable.subscript!materializeForSet.1 : -// CHECK: [[T1:%.*]] = apply [[MAT]]([[BUFFER_CAST]], [[MATBUFFER]]#1, [[INDEX]], [[BASE:%.*#1]]) +// CHECK: [[T1:%.*]] = apply [[MAT]]([[BUFFER_CAST]], [[MATBUFFER]], [[INDEX]], [[BASE:%.*#1]]) // CHECK: [[T2:%.*]] = tuple_extract [[T1]] : {{.*}}, 0 // CHECK: [[T3:%.*]] = pointer_to_address [[T2]] : $Builtin.RawPointer to $*B.Structure // CHECK: [[CALLBACK:%.*]] = tuple_extract [[T1]] : {{.*}}, 1 @@ -571,15 +568,15 @@ func supportStructure(inout b: Bridge, name: String) throws { // CHECK-NEXT: [[GETTER:%.*]] = function_ref @_TFV6errors6Bridgeg9subscriptFSSVS_5Pylon : // CHECK-NEXT: [[T0:%.*]] = apply [[GETTER]]([[INDEX]], [[BASE]]) // CHECK-NEXT: release_value [[BASE]] -// CHECK-NEXT: store [[T0]] to [[TEMP]]#1 -// CHECK-NEXT: try_apply [[SUPPORT]]([[TEMP]]#1) : {{.*}}, normal [[BB_NORMAL:bb[0-9]+]], error [[BB_ERROR:bb[0-9]+]] +// CHECK-NEXT: store [[T0]] to [[TEMP]] +// CHECK-NEXT: try_apply [[SUPPORT]]([[TEMP]]) : {{.*}}, normal [[BB_NORMAL:bb[0-9]+]], error [[BB_ERROR:bb[0-9]+]] // CHECK: [[BB_NORMAL]] -// CHECK-NEXT: [[T0:%.*]] = load [[TEMP]]#1 +// CHECK-NEXT: [[T0:%.*]] = load [[TEMP]] // CHECK-NEXT: function_ref // CHECK-NEXT: [[SETTER:%.*]] = function_ref @_TFV6errors6Bridges9subscriptFSSVS_5Pylon : // CHECK-NEXT: apply [[SETTER]]([[T0]], [[INDEX]], [[B]]) -// CHECK-NEXT: dealloc_stack [[TEMP]]#0 +// CHECK-NEXT: dealloc_stack [[TEMP]] // CHECK-NEXT: release_value [[INDEX]] : $String // CHECK-NEXT: copy_addr // CHECK-NEXT: strong_release @@ -589,14 +586,14 @@ func supportStructure(inout b: Bridge, name: String) throws { // We end up with ugly redundancy here because we don't want to // consume things during cleanup emission. It's questionable. // CHECK: [[BB_ERROR]]([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: [[T0:%.*]] = load [[TEMP]]#1 +// CHECK-NEXT: [[T0:%.*]] = load [[TEMP]] // CHECK-NEXT: retain_value [[T0]] // CHECK-NEXT: retain_value [[INDEX]] : $String // CHECK-NEXT: function_ref // CHECK-NEXT: [[SETTER:%.*]] = function_ref @_TFV6errors6Bridges9subscriptFSSVS_5Pylon : // CHECK-NEXT: apply [[SETTER]]([[T0]], [[INDEX]], [[B]]) -// CHECK-NEXT: destroy_addr [[TEMP]]#1 -// CHECK-NEXT: dealloc_stack [[TEMP]]#0 +// CHECK-NEXT: destroy_addr [[TEMP]] +// CHECK-NEXT: dealloc_stack [[TEMP]] // CHECK-NEXT: release_value [[INDEX]] : $String // CHECK-NEXT: release_value [[INDEX]] : $String // CHECK-NEXT: copy_addr @@ -733,26 +730,26 @@ func testOptionalTryVar() { // CHECK-LABEL: sil hidden @_TF6errors26testOptionalTryAddressOnly // CHECK: bb0(%0 : $*T): // CHECK: [[BOX:%.+]] = alloc_stack $Optional -// CHECK-NEXT: [[BOX_DATA:%.+]] = init_enum_data_addr [[BOX]]#1 : $*Optional, #Optional.Some!enumelt.1 +// CHECK-NEXT: [[BOX_DATA:%.+]] = init_enum_data_addr [[BOX]] : $*Optional, #Optional.Some!enumelt.1 // CHECK: [[FN:%.+]] = function_ref @_TF6errors11dont_return // CHECK-NEXT: [[ARG_BOX:%.+]] = alloc_stack $T -// CHECK-NEXT: copy_addr %0 to [initialization] [[ARG_BOX]]#1 : $*T -// CHECK-NEXT: try_apply [[FN]]([[BOX_DATA]], [[ARG_BOX]]#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> @error ErrorType, normal [[SUCCESS:[^ ]+]], error [[CLEANUPS:[^ ]+]] +// CHECK-NEXT: copy_addr %0 to [initialization] [[ARG_BOX]] : $*T +// CHECK-NEXT: try_apply [[FN]]([[BOX_DATA]], [[ARG_BOX]]) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> @error ErrorType, normal [[SUCCESS:[^ ]+]], error [[CLEANUPS:[^ ]+]] // CHECK: [[SUCCESS]]({{%.+}} : $()): -// CHECK-NEXT: inject_enum_addr [[BOX]]#1 : $*Optional, #Optional.Some!enumelt.1 -// CHECK-NEXT: dealloc_stack [[ARG_BOX]]#0 : $*@local_storage T +// CHECK-NEXT: inject_enum_addr [[BOX]] : $*Optional, #Optional.Some!enumelt.1 +// CHECK-NEXT: dealloc_stack [[ARG_BOX]] : $*T // CHECK-NEXT: br [[DONE:[^ ]+]] // CHECK: [[DONE]]: -// CHECK-NEXT: destroy_addr [[BOX]]#1 : $*Optional -// CHECK-NEXT: dealloc_stack [[BOX]]#0 : $*@local_storage Optional +// CHECK-NEXT: destroy_addr [[BOX]] : $*Optional +// CHECK-NEXT: dealloc_stack [[BOX]] : $*Optional // CHECK-NEXT: destroy_addr %0 : $*T // CHECK-NEXT: [[VOID:%.+]] = tuple () // CHECK-NEXT: return [[VOID]] : $() // CHECK: [[FAILURE:.+]]({{%.+}} : $ErrorType): -// CHECK-NEXT: inject_enum_addr [[BOX]]#1 : $*Optional, #Optional.None!enumelt +// CHECK-NEXT: inject_enum_addr [[BOX]] : $*Optional, #Optional.None!enumelt // CHECK-NEXT: br [[DONE]] // CHECK: [[CLEANUPS]]([[ERROR:%.+]] : $ErrorType): -// CHECK-NEXT: dealloc_stack [[ARG_BOX]]#0 : $*@local_storage T +// CHECK-NEXT: dealloc_stack [[ARG_BOX]] : $*T // CHECK-NEXT: br [[FAILURE]]([[ERROR]] : $ErrorType) // CHECK: {{^}$}} func testOptionalTryAddressOnly(obj: T) { @@ -765,11 +762,11 @@ func testOptionalTryAddressOnly(obj: T) { // CHECK-NEXT: [[BOX_DATA:%.+]] = init_enum_data_addr [[BOX]]#1 : $*Optional, #Optional.Some!enumelt.1 // CHECK: [[FN:%.+]] = function_ref @_TF6errors11dont_return // CHECK-NEXT: [[ARG_BOX:%.+]] = alloc_stack $T -// CHECK-NEXT: copy_addr %0 to [initialization] [[ARG_BOX]]#1 : $*T -// CHECK-NEXT: try_apply [[FN]]([[BOX_DATA]], [[ARG_BOX]]#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> @error ErrorType, normal [[SUCCESS:[^ ]+]], error [[CLEANUPS:[^ ]+]] +// CHECK-NEXT: copy_addr %0 to [initialization] [[ARG_BOX]] : $*T +// CHECK-NEXT: try_apply [[FN]]([[BOX_DATA]], [[ARG_BOX]]) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> @error ErrorType, normal [[SUCCESS:[^ ]+]], error [[CLEANUPS:[^ ]+]] // CHECK: [[SUCCESS]]({{%.+}} : $()): // CHECK-NEXT: inject_enum_addr [[BOX]]#1 : $*Optional, #Optional.Some!enumelt.1 -// CHECK-NEXT: dealloc_stack [[ARG_BOX]]#0 : $*@local_storage T +// CHECK-NEXT: dealloc_stack [[ARG_BOX]] : $*T // CHECK-NEXT: br [[DONE:[^ ]+]] // CHECK: [[DONE]]: // CHECK-NEXT: strong_release [[BOX]]#0 : $@box Optional @@ -780,7 +777,7 @@ func testOptionalTryAddressOnly(obj: T) { // CHECK-NEXT: inject_enum_addr [[BOX]]#1 : $*Optional, #Optional.None!enumelt // CHECK-NEXT: br [[DONE]] // CHECK: [[CLEANUPS]]([[ERROR:%.+]] : $ErrorType): -// CHECK-NEXT: dealloc_stack [[ARG_BOX]]#0 : $*@local_storage T +// CHECK-NEXT: dealloc_stack [[ARG_BOX]] : $*T // CHECK-NEXT: br [[FAILURE]]([[ERROR]] : $ErrorType) // CHECK: {{^}$}} func testOptionalTryAddressOnlyVar(obj: T) { @@ -842,11 +839,11 @@ func testOptionalTryNeverFailsVar() { // CHECK-LABEL: sil hidden @_TF6errors36testOptionalTryNeverFailsAddressOnly // CHECK: bb0(%0 : $*T): // CHECK: [[BOX:%.+]] = alloc_stack $Optional -// CHECK-NEXT: [[BOX_DATA:%.+]] = init_enum_data_addr [[BOX]]#1 : $*Optional, #Optional.Some!enumelt.1 +// CHECK-NEXT: [[BOX_DATA:%.+]] = init_enum_data_addr [[BOX]] : $*Optional, #Optional.Some!enumelt.1 // CHECK-NEXT: copy_addr %0 to [initialization] [[BOX_DATA]] : $*T -// CHECK-NEXT: inject_enum_addr [[BOX]]#1 : $*Optional, #Optional.Some!enumelt.1 -// CHECK-NEXT: destroy_addr [[BOX]]#1 : $*Optional -// CHECK-NEXT: dealloc_stack [[BOX]]#0 : $*@local_storage Optional +// CHECK-NEXT: inject_enum_addr [[BOX]] : $*Optional, #Optional.Some!enumelt.1 +// CHECK-NEXT: destroy_addr [[BOX]] : $*Optional +// CHECK-NEXT: dealloc_stack [[BOX]] : $*Optional // CHECK-NEXT: destroy_addr %0 : $*T // CHECK-NEXT: [[VOID:%.+]] = tuple () // CHECK-NEXT: return [[VOID]] : $() diff --git a/test/SILGen/existential_erasure.swift b/test/SILGen/existential_erasure.swift index f1e088c1c1ee9..b5b4c54fea41a 100644 --- a/test/SILGen/existential_erasure.swift +++ b/test/SILGen/existential_erasure.swift @@ -24,10 +24,10 @@ func throwingFunc() throws -> Bool { return true } // CHECK-LABEL: sil hidden @_TF19existential_erasure5PQtoPFT_T_ : $@convention(thin) () -> () { func PQtoP() { - // CHECK: [[PQ_PAYLOAD:%.*]] = open_existential_addr [[PQ:%.*]]#1 : $*protocol to $*[[OPENED_TYPE:@opened(.*) protocol]] - // CHECK: [[P_PAYLOAD:%.*]] = init_existential_addr [[P:%.*]]#1 : $*P, $[[OPENED_TYPE]] + // CHECK: [[PQ_PAYLOAD:%.*]] = open_existential_addr [[PQ:%.*]] : $*protocol to $*[[OPENED_TYPE:@opened(.*) protocol]] + // CHECK: [[P_PAYLOAD:%.*]] = init_existential_addr [[P:%.*]] : $*P, $[[OPENED_TYPE]] // CHECK: copy_addr [take] [[PQ_PAYLOAD]] to [initialization] [[P_PAYLOAD]] - // CHECK: deinit_existential_addr [[PQ]]#1 + // CHECK: deinit_existential_addr [[PQ]] // CHECK-NOT: destroy_addr [[P]] // CHECK-NOT: destroy_addr [[P_PAYLOAD]] // CHECK-NOT: destroy_addr [[PQ]] @@ -43,20 +43,20 @@ func openExistentialToP1(p: P) throws { // CHECK: bb0(%0 : $*P): // CHECK: [[OPEN:%.*]] = open_existential_addr %0 : $*P to $*[[OPEN_TYPE:@opened\(.*\) P]] // CHECK: [[RESULT:%.*]] = alloc_stack $P -// CHECK: [[RESULT_ADDR:%.*]] = init_existential_addr [[RESULT]]#1 : $*P, $[[OPEN_TYPE]] +// CHECK: [[RESULT_ADDR:%.*]] = init_existential_addr [[RESULT]] : $*P, $[[OPEN_TYPE]] // CHECK: [[METHOD:%.*]] = witness_method $[[OPEN_TYPE]], #P.downgrade!1, [[OPEN]] // CHECK: [[FUNC:%.*]] = function_ref @_TF19existential_erasure12throwingFuncFzT_Sb // CHECK: try_apply [[FUNC]]() // // CHECK: bb1([[SUCCESS:%.*]] : $Bool): // CHECK: apply [[METHOD]]<[[OPEN_TYPE]]>([[RESULT_ADDR]], [[SUCCESS]], [[OPEN]]) -// CHECK: dealloc_stack [[RESULT]]#0 +// CHECK: dealloc_stack [[RESULT]] // CHECK: destroy_addr %0 // CHECK: return // // CHECK: bb2([[FAILURE:%.*]] : $ErrorType): -// CHECK: deinit_existential_addr [[RESULT]]#1 -// CHECK: dealloc_stack [[RESULT]]#0 +// CHECK: deinit_existential_addr [[RESULT]] +// CHECK: dealloc_stack [[RESULT]] // CHECK: destroy_addr %0 // CHECK: throw [[FAILURE]] // @@ -68,18 +68,18 @@ func openExistentialToP2(p: P) throws { // CHECK: bb0(%0 : $*P): // CHECK: [[OPEN:%.*]] = open_existential_addr %0 : $*P to $*[[OPEN_TYPE:@opened\(.*\) P]] // CHECK: [[RESULT:%.*]] = alloc_stack $P -// CHECK: [[RESULT_ADDR:%.*]] = init_existential_addr [[RESULT]]#1 : $*P, $[[OPEN_TYPE]] +// CHECK: [[RESULT_ADDR:%.*]] = init_existential_addr [[RESULT]] : $*P, $[[OPEN_TYPE]] // CHECK: [[METHOD:%.*]] = witness_method $[[OPEN_TYPE]], #P.upgrade!1, [[OPEN]] // CHECK: try_apply [[METHOD]]<[[OPEN_TYPE]]>([[RESULT_ADDR]], [[OPEN]]) // // CHECK: bb1 -// CHECK: dealloc_stack [[RESULT]]#0 +// CHECK: dealloc_stack [[RESULT]] // CHECK: destroy_addr %0 // CHECK: return // // CHECK: bb2([[FAILURE:%.*]]: $ErrorType): -// CHECK: deinit_existential_addr [[RESULT]]#1 -// CHECK: dealloc_stack [[RESULT]]#0 +// CHECK: deinit_existential_addr [[RESULT]] +// CHECK: dealloc_stack [[RESULT]] // CHECK: destroy_addr %0 // CHECK: throw [[FAILURE]] // diff --git a/test/SILGen/existential_metatypes.swift b/test/SILGen/existential_metatypes.swift index 1fe12d3e1df5e..993a9f9d47f26 100644 --- a/test/SILGen/existential_metatypes.swift +++ b/test/SILGen/existential_metatypes.swift @@ -17,7 +17,7 @@ func existentialMetatype(x: P) { let type1 = x.dynamicType // CHECK: [[INSTANCE1:%.*]] = alloc_stack $P // CHECK: [[OPEN_TYPE1:%.*]] = open_existential_metatype [[TYPE1]] - // CHECK: [[INSTANCE1_VALUE:%.*]] = init_existential_addr [[INSTANCE1]]#1 : $*P + // CHECK: [[INSTANCE1_VALUE:%.*]] = init_existential_addr [[INSTANCE1]] : $*P // CHECK: [[INIT:%.*]] = witness_method {{.*}} #P.init!allocator // CHECK: apply [[INIT]]<{{.*}}>([[INSTANCE1_VALUE]], [[OPEN_TYPE1]]) let instance1 = type1.init() @@ -27,7 +27,7 @@ func existentialMetatype(x: P) { let type2: P.Type = S.self // CHECK: [[INSTANCE2:%.*]] = alloc_stack $P // CHECK: [[OPEN_TYPE2:%.*]] = open_existential_metatype [[TYPE2]] - // CHECK: [[INSTANCE2_VALUE:%.*]] = init_existential_addr [[INSTANCE2]]#1 : $*P + // CHECK: [[INSTANCE2_VALUE:%.*]] = init_existential_addr [[INSTANCE2]] : $*P // CHECK: [[STATIC_METHOD:%.*]] = witness_method {{.*}} #P.staticMethod // CHECK: apply [[STATIC_METHOD]]<{{.*}}>([[INSTANCE2_VALUE]], [[OPEN_TYPE2]]) let instance2 = type2.staticMethod() diff --git a/test/SILGen/expressions.swift b/test/SILGen/expressions.swift index 1ea685a6139e9..c26585d1928d7 100644 --- a/test/SILGen/expressions.swift +++ b/test/SILGen/expressions.swift @@ -308,9 +308,9 @@ func archetype_member_ref(x: T) { x.free_method() // CHECK: witness_method $T, #Runcible.free_method!1 // CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $T - // CHECK-NEXT: copy_addr [[X:%.*]] to [initialization] [[TEMP]]#1 + // CHECK-NEXT: copy_addr [[X:%.*]] to [initialization] [[TEMP]] // CHECK-NEXT: apply - // CHECK-NEXT: destroy_addr [[TEMP]]#1 + // CHECK-NEXT: destroy_addr [[TEMP]] var u = x.associated_method() // CHECK: witness_method $T, #Runcible.associated_method!1 // CHECK-NEXT: apply @@ -542,8 +542,8 @@ func implodeRecursiveTuple(expr: ((Int, Int), Int)?) { // CHECK-NEXT: [[WHOLE1:%[0-9]+]] = tuple_extract [[WHOLE]] : $((Int, Int), Int), 1 // CHECK-NEXT: [[X:%[0-9]+]] = tuple ([[WHOLE00]] : $Int, [[WHOLE01]] : $Int) - // CHECK-NEXT: debug_value [[X]] : $(Int, Int) // let x - // CHECK-NEXT: debug_value [[WHOLE1]] : $Int // let y + // CHECK-NEXT: debug_value [[X]] : $(Int, Int), let, name "x" + // CHECK-NEXT: debug_value [[WHOLE1]] : $Int, let, name "y" let (x, y) = expr! } diff --git a/test/SILGen/external_definitions.swift b/test/SILGen/external_definitions.swift index e8e9a71c8661b..40fed45ee1d9a 100644 --- a/test/SILGen/external_definitions.swift +++ b/test/SILGen/external_definitions.swift @@ -17,7 +17,6 @@ hasNoPrototype() // CHECK: [[NSOBJECT_CTOR:%.*]] = function_ref @_TFCSo8NSObjectC{{.*}} : $@convention(thin) (@thick NSObject.Type) -> @owned NSObject // CHECK: [[ANSIBLE:%.*]] = apply [[ANSIBLE_CTOR]] // CHECK: [[NSANSE_RESULT:%.*]] = apply [[NSANSE]]([[ANSIBLE]]) -// CHECK: retain_autoreleased [[NSANSE_RESULT]] // CHECK: release_value [[ANSIBLE]] : $ImplicitlyUnwrappedOptional // -- Referencing unapplied C function goes through a thunk // CHECK: [[NSANSE:%.*]] = function_ref @_TTOFSC6NSAnseFGSQCSo7Ansible_GSQS__ : $@convention(thin) (@owned ImplicitlyUnwrappedOptional) -> @owned ImplicitlyUnwrappedOptional @@ -37,7 +36,6 @@ hasNoPrototype() // CHECK: bb0(%0 : $ImplicitlyUnwrappedOptional): // CHECK: %1 = function_ref @NSAnse : $@convention(c) (ImplicitlyUnwrappedOptional) -> @autoreleased ImplicitlyUnwrappedOptional // CHECK: %2 = apply %1(%0) : $@convention(c) (ImplicitlyUnwrappedOptional) -> @autoreleased ImplicitlyUnwrappedOptional -// CHECK: strong_retain_autoreleased %2 : $ImplicitlyUnwrappedOptional // CHECK: release_value %0 : $ImplicitlyUnwrappedOptional // CHECK: return %2 : $ImplicitlyUnwrappedOptional // CHECK: } diff --git a/test/SILGen/force_cast_chained_optional.swift b/test/SILGen/force_cast_chained_optional.swift index dc395392bab9e..a966f18e33be9 100644 --- a/test/SILGen/force_cast_chained_optional.swift +++ b/test/SILGen/force_cast_chained_optional.swift @@ -12,7 +12,7 @@ class C {} class D: C {} // CHECK-LABEL: sil hidden @_TF27force_cast_chained_optional4testFCS_3FooCS_1D -// CHECK: class_method %0 : $Foo, #Foo.bar!getter.1 : Foo -> () -> Bar! , $@convention(method) (@guaranteed Foo) -> +// CHECK: class_method %0 : $Foo, #Foo.bar!getter.1 : (Foo) -> () -> Bar! , $@convention(method) (@guaranteed Foo) -> // CHECK: select_enum_addr // CHECK: cond_br {{%.*}}, [[SOME_BAR:bb[0-9]+]], [[NO_BAR:bb[0-9]+]] // CHECK: [[NO_BAR]]: @@ -20,7 +20,7 @@ class D: C {} // CHECK: [[SOME_BAR]]: // CHECK: [[PAYLOAD_ADDR:%.*]] = unchecked_take_enum_data_addr {{%.*}} : $*ImplicitlyUnwrappedOptional // CHECK: [[BAR:%.*]] = load [[PAYLOAD_ADDR]] -// CHECK: class_method {{%.*}} : $Bar, #Bar.bas!getter.1 : Bar -> () -> C! , $@convention(method) (@guaranteed Bar) -> +// CHECK: class_method {{%.*}} : $Bar, #Bar.bas!getter.1 : (Bar) -> () -> C! , $@convention(method) (@guaranteed Bar) -> // CHECK: function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue // CHECK: unconditional_checked_cast {{%.*}} : $C to $D // CHECK: [[TRAP]]: diff --git a/test/SILGen/foreign_errors.swift b/test/SILGen/foreign_errors.swift index a64d57589c21d..93906aa04a77c 100644 --- a/test/SILGen/foreign_errors.swift +++ b/test/SILGen/foreign_errors.swift @@ -13,22 +13,22 @@ func test0() throws { // Create a strong temporary holding nil. // CHECK: [[ERR_TEMP0:%.*]] = alloc_stack $Optional - // CHECK: inject_enum_addr [[ERR_TEMP0]]#1 : $*Optional, #Optional.None!enumelt + // CHECK: inject_enum_addr [[ERR_TEMP0]] : $*Optional, #Optional.None!enumelt // Create an unmanaged temporary, copy into it, and make a AutoreleasingUnsafeMutablePointer. // CHECK: [[ERR_TEMP1:%.*]] = alloc_stack $@sil_unmanaged Optional - // CHECK: [[T0:%.*]] = load [[ERR_TEMP0:%.*]]#1 + // CHECK: [[T0:%.*]] = load [[ERR_TEMP0]] // CHECK: [[T1:%.*]] = ref_to_unmanaged [[T0]] - // CHECK: store [[T1]] to [[ERR_TEMP1]]#1 - // CHECK: address_to_pointer [[ERR_TEMP1]]#1 + // CHECK: store [[T1]] to [[ERR_TEMP1]] + // CHECK: address_to_pointer [[ERR_TEMP1]] // Call the method. // CHECK: [[RESULT:%.*]] = apply [[METHOD]]({{.*}}, [[OBJC_SELF]]) // Writeback to the first temporary. - // CHECK: [[T0:%.*]] = load [[ERR_TEMP1]]#1 + // CHECK: [[T0:%.*]] = load [[ERR_TEMP1]] // CHECK: [[T1:%.*]] = unmanaged_to_ref [[T0]] // CHECK: retain_value [[T1]] - // CHECK: assign [[T1]] to [[ERR_TEMP0]]#1 + // CHECK: assign [[T1]] to [[ERR_TEMP0]] // Pull out the boolean value and compare it to zero. // CHECK: [[T0:%.*]] = struct_extract [[RESULT]] @@ -43,7 +43,7 @@ func test0() throws { // Error path: fall out and rethrow. // CHECK: [[ERROR_BB]]: - // CHECK: [[T0:%.*]] = load [[ERR_TEMP0]]#1 + // CHECK: [[T0:%.*]] = load [[ERR_TEMP0]] // CHECK: [[T1:%.*]] = function_ref @swift_convertNSErrorToErrorType : $@convention(thin) (@owned Optional) -> @owned ErrorType // CHECK: [[T2:%.*]] = apply [[T1]]([[T0]]) // CHECK: throw [[T2]] : $ErrorType @@ -66,9 +66,9 @@ extension NSObject { // CHECK: [[OBJCERR:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[T1]] : $NSError // CHECK: [[SETTER:%.*]] = function_ref @_TFVs33AutoreleasingUnsafeMutablePointers6memoryx : // CHECK: [[TEMP:%.*]] = alloc_stack $Optional -// CHECK: store [[OBJCERR]] to [[TEMP]]#1 -// CHECK: apply [[SETTER]]>([[TEMP]]#1, %0) -// CHECK: dealloc_stack [[TEMP]]#0 +// CHECK: store [[OBJCERR]] to [[TEMP]] +// CHECK: apply [[SETTER]]>([[TEMP]], %0) +// CHECK: dealloc_stack [[TEMP]] // CHECK: [[T0:%.*]] = integer_literal $Builtin.Int1, 0 // CHECK: [[T1:%.*]] = struct $Bool ([[T0]] : $Builtin.Int1) // CHECK: br bb3([[T1]] : $Bool) @@ -92,13 +92,13 @@ extension NSObject { // CHECK: [[OBJCERR:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[T1]] : $NSError // CHECK: [[SETTER:%.*]] = function_ref @_TFVs33AutoreleasingUnsafeMutablePointers6memoryx : // CHECK: [[TEMP:%.*]] = alloc_stack $Optional -// CHECK: store [[OBJCERR]] to [[TEMP]]#1 -// CHECK: apply [[SETTER]]>([[TEMP]]#1, %0) -// CHECK: dealloc_stack [[TEMP]]#0 +// CHECK: store [[OBJCERR]] to [[TEMP]] +// CHECK: apply [[SETTER]]>([[TEMP]], %0) +// CHECK: dealloc_stack [[TEMP]] // CHECK: [[T0:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK: br bb3([[T0]] : $Optional) // CHECK: bb3([[T0:%.*]] : $Optional): -// CHECK: autorelease_return [[T0]] : $Optional +// CHECK: return [[T0]] : $Optional // CHECK-LABEL: sil hidden [thunk] @_TToFE14foreign_errorsCSo8NSObject7takeInt{{.*}} : $@convention(objc_method) (Int, AutoreleasingUnsafeMutablePointer>, NSObject) -> Bool // CHECK: bb0([[I:%[0-9]+]] : $Int, [[ERROR:%[0-9]+]] : $AutoreleasingUnsafeMutablePointer>, [[SELF:%[0-9]+]] : $NSObject) @@ -124,7 +124,7 @@ let fn = ErrorProne.fail // CHECK: [[RESULT:%.*]] = apply [[METHOD]]({{%.*}}, [[SELF]]) // CHECK: cond_br // CHECK: return -// CHECK: [[T0:%.*]] = load [[TEMP]]#1 +// CHECK: [[T0:%.*]] = load [[TEMP]] // CHECK: [[T1:%.*]] = apply {{%.*}}([[T0]]) // CHECK: throw [[T1]] @@ -188,8 +188,8 @@ func testNonNilError() throws -> Float { // CHECK: [[T1:%.*]] = class_method [volatile] [[T0]] : $@thick ErrorProne.Type, #ErrorProne.bounce!1.foreign : ErrorProne.Type -> () throws -> Float , $@convention(objc_method) (AutoreleasingUnsafeMutablePointer>, @objc_metatype ErrorProne.Type) -> Float // CHECK: [[OPTERR:%.*]] = alloc_stack $Optional // CHECK: [[RESULT:%.*]] = apply [[T1]]( -// CHECK: assign {{%.*}} to [[OPTERR]]#1 -// CHECK: [[T0:%.*]] = load [[OPTERR]]#1 +// CHECK: assign {{%.*}} to [[OPTERR]] +// CHECK: [[T0:%.*]] = load [[OPTERR]] // CHECK: switch_enum [[T0]] : $Optional, case #Optional.Some!enumelt.1: [[ERROR_BB:bb[0-9]+]], case #Optional.None!enumelt: [[NORMAL_BB:bb[0-9]+]] // CHECK: [[NORMAL_BB]]: // CHECK-NOT: release diff --git a/test/SILGen/function_conversion.swift b/test/SILGen/function_conversion.swift index 2156428e76800..7cfffb55d40c7 100644 --- a/test/SILGen/function_conversion.swift +++ b/test/SILGen/function_conversion.swift @@ -156,11 +156,11 @@ func convOptionalAddrOnly(a1: AddrOnly? -> AddrOnly) { // CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo_iGSqV19function_conversion8AddrOnly__iS0__XFo_iGSqS0___iGSqS0___ : $@convention(thin) (@out Optional, @in Optional, @owned @callee_owned (@out AddrOnly, @in Optional) -> ()) -> () // CHECK: alloc_stack $AddrOnly -// CHECK-NEXT: apply %2(%3#1, %1) +// CHECK-NEXT: apply %2(%3, %1) // CHECK-NEXT: init_enum_data_addr %0 : $*Optional // CHECK-NEXT: copy_addr [take] {{.*}} to [initialization] {{.*}} : $*AddrOnly // CHECK-NEXT: inject_enum_addr %0 : $*Optional -// CHECK-NEXT: dealloc_stack {{.*}} : $*@local_storage AddrOnly +// CHECK-NEXT: dealloc_stack {{.*}} : $*AddrOnly // CHECK-NEXT: return // CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo_iGSqV19function_conversion8AddrOnly__iS0__XFo_iGSQS0___iGSqS0___ : $@convention(thin) (@out Optional, @in ImplicitlyUnwrappedOptional, @owned @callee_owned (@out AddrOnly, @in Optional) -> ()) -> () @@ -168,12 +168,12 @@ func convOptionalAddrOnly(a1: AddrOnly? -> AddrOnly) { // CHECK-NEXT: unchecked_addr_cast %1 : $*ImplicitlyUnwrappedOptional to $*Optional // CHECK-NEXT: copy_addr [take] {{.*}} to [initialization] {{.*}} : $*Optional // CHECK-NEXT: alloc_stack $AddrOnly -// CHECK-NEXT: apply %2(%6#1, %3#1) +// CHECK-NEXT: apply %2(%6, %3) // CHECK-NEXT: init_enum_data_addr %0 : $*Optional // CHECK-NEXT: copy_addr [take] {{.*}} to [initialization] {{.*}} : $*AddrOnly // CHECK-NEXT: inject_enum_addr %0 : $*Optional -// CHECK-NEXT: dealloc_stack {{.*}} : $*@local_storage AddrOnly -// CHECK-NEXT: dealloc_stack {{.*}} : $*@local_storage Optional +// CHECK-NEXT: dealloc_stack {{.*}} : $*AddrOnly +// CHECK-NEXT: dealloc_stack {{.*}} : $*Optional // CHECK-NEXT: return // ==== Existentials @@ -232,7 +232,7 @@ func convExistentialTrivial(t2: Q -> Trivial, t3: Q? -> Trivial) { // CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo_iP19function_conversion1Q__dVS_7Trivial_XFo_iPS_1P__iPS2___ : $@convention(thin) (@out P, @in P, @owned @callee_owned (@in Q) -> Trivial) -> () // CHECK: alloc_stack $Q // CHECK-NEXT: open_existential_addr %1 : $*P -// CHECK-NEXT: init_existential_addr %3#1 : $*Q +// CHECK-NEXT: init_existential_addr %3 : $*Q // CHECK-NEXT: copy_addr [take] {{.*}} to [initialization] {{.*}} // CHECK-NEXT: apply // CHECK-NEXT: init_existential_addr @@ -349,7 +349,7 @@ func convFuncExistential(f1: Any -> Int -> Int) { // CHECK: alloc_stack $protocol<> // CHECK: function_ref @_TTRXFo_dSi_dSi_XFo_iSi_iSi_ // CHECK-NEXT: partial_apply -// CHECK-NEXT: init_existential_addr %3#1 : $*protocol<>, $Int -> Int +// CHECK-NEXT: init_existential_addr %3 : $*protocol<>, $Int -> Int // CHECK-NEXT: store // CHECK-NEXT: apply // CHECK: function_ref @_TTRXFo_dSi_dSi_XFo_iSi_iSi_ diff --git a/test/SILGen/functions.swift b/test/SILGen/functions.swift index 5ade82dbbfb97..364625e087712 100644 --- a/test/SILGen/functions.swift +++ b/test/SILGen/functions.swift @@ -53,8 +53,8 @@ func curried_function_returns_function(x: Int)(y: Int) -> (z:Int) -> Int { return { z in standalone_function(standalone_function(x, y), z) } } // -- Local function has extra uncurry level with context -// CHECK-LABEL: sil shared @_TFF9functions33curried_function_returns_function{{.*}} : $@convention(thin) (Builtin.Int64, @owned @box Builtin.Int64, @inout Builtin.Int64, @owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 -// bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64, %2 : $@box Builtin.Int64, %3 : $*Builtin.Int64, %4 : $Builtin.Int64): +// CHECK-LABEL: sil shared @_TFF9functions33curried_function_returns_function{{.*}} : $@convention(thin) (Builtin.Int64, @owned @box Builtin.Int64, @owned @box Builtin.Int64) -> Builtin.Int64 +// bb0(%0 : $@box Builtin.Int64, %1 : $@box Builtin.Int64, %4 : $Builtin.Int64): struct SomeStruct { // -- Constructors and methods are uncurried in 'self' @@ -327,14 +327,14 @@ func calls(i: Int, j: Int, k: Int) { // CHECK: [[C:%[0-9]+]] = load [[CADDR]] // CHECK: [[I:%[0-9]+]] = load [[IADDR]] - // CHECK: [[SETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.someProperty!setter.1 : SomeClass -> (Builtin.Int64) -> () + // CHECK: [[SETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.someProperty!setter.1 : (SomeClass) -> (Builtin.Int64) -> () // CHECK: apply [[SETTER]]([[I]], [[C]]) c.someProperty = i // CHECK: [[C:%[0-9]+]] = load [[CADDR]] // CHECK: [[J:%[0-9]+]] = load [[JADDR]] // CHECK: [[K:%[0-9]+]] = load [[KADDR]] - // CHECK: [[GETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.subscript!getter.1 : SomeClass -> (Builtin.Int64, Builtin.Int64) -> Builtin.Int64 , $@convention(method) (Builtin.Int64, Builtin.Int64, @guaranteed SomeClass) -> Builtin.Int64 + // CHECK: [[GETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.subscript!getter.1 : (SomeClass) -> (Builtin.Int64, Builtin.Int64) -> Builtin.Int64 , $@convention(method) (Builtin.Int64, Builtin.Int64, @guaranteed SomeClass) -> Builtin.Int64 // CHECK: apply [[GETTER]]([[J]], [[K]], [[C]]) i = c[j, k] @@ -342,7 +342,7 @@ func calls(i: Int, j: Int, k: Int) { // CHECK: [[I:%[0-9]+]] = load [[IADDR]] // CHECK: [[J:%[0-9]+]] = load [[JADDR]] // CHECK: [[K:%[0-9]+]] = load [[KADDR]] - // CHECK: [[SETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.subscript!setter.1 : SomeClass -> (Builtin.Int64, Builtin.Int64, Builtin.Int64) -> () , $@convention(method) (Builtin.Int64, Builtin.Int64, Builtin.Int64, @guaranteed SomeClass) -> () + // CHECK: [[SETTER:%[0-9]+]] = class_method [[C]] : $SomeClass, #SomeClass.subscript!setter.1 : (SomeClass) -> (Builtin.Int64, Builtin.Int64, Builtin.Int64) -> () , $@convention(method) (Builtin.Int64, Builtin.Int64, Builtin.Int64, @guaranteed SomeClass) -> () // CHECK: apply [[SETTER]]([[K]], [[I]], [[J]], [[C]]) c[i, j] = k @@ -353,14 +353,14 @@ func calls(i: Int, j: Int, k: Int) { var p : SomeProtocol = ConformsToSomeProtocol() // CHECK: [[TEMP:%.*]] = alloc_stack $SomeProtocol - // CHECK: copy_addr [[PADDR]]#1 to [initialization] [[TEMP]]#1 - // CHECK: [[PVALUE:%[0-9]+]] = open_existential_addr [[TEMP]]#1 : $*SomeProtocol to $*[[OPENED:@opened(.*) SomeProtocol]] + // CHECK: copy_addr [[PADDR]]#1 to [initialization] [[TEMP]] + // CHECK: [[PVALUE:%[0-9]+]] = open_existential_addr [[TEMP]] : $*SomeProtocol to $*[[OPENED:@opened(.*) SomeProtocol]] // CHECK: [[PMETHOD:%[0-9]+]] = witness_method $[[OPENED]], #SomeProtocol.method!1 // CHECK: [[I:%[0-9]+]] = load [[IADDR]] // CHECK: apply [[PMETHOD]]<[[OPENED]]>([[I]], [[PVALUE]]) // CHECK: destroy_addr [[PVALUE]] - // CHECK: deinit_existential_addr [[TEMP]]#1 - // CHECK: dealloc_stack [[TEMP]]#0 + // CHECK: deinit_existential_addr [[TEMP]] + // CHECK: dealloc_stack [[TEMP]] p.method(i) // CHECK: [[PVALUE:%[0-9]+]] = open_existential_addr [[PADDR:%.*]] : $*SomeProtocol to $*[[OPENED:@opened(.*) SomeProtocol]] @@ -388,21 +388,21 @@ func calls(i: Int, j: Int, k: Int) { // CHECK: [[METHOD_GEN:%[0-9]+]] = class_method [[G]] : {{.*}}, #SomeGeneric.method!1 // CHECK: [[TMPI:%.*]] = alloc_stack $Builtin.Int64 // CHECK: [[TMPR:%.*]] = alloc_stack $Builtin.Int64 - // CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]]#1, [[TMPI]]#1, [[G]]) + // CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]], [[TMPI]], [[G]]) g.method(i) // CHECK: [[G:%[0-9]+]] = load [[GADDR]] // CHECK: [[METHOD_GEN:%[0-9]+]] = class_method [[G]] : {{.*}}, #SomeGeneric.generic!1 // CHECK: [[TMPJ:%.*]] = alloc_stack $Builtin.Int64 // CHECK: [[TMPR:%.*]] = alloc_stack $Builtin.Int64 - // CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]]#1, [[TMPJ]]#1, [[G]]) + // CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]], [[TMPJ]], [[G]]) g.generic(j) // CHECK: [[C:%[0-9]+]] = load [[CADDR]] // CHECK: [[METHOD_GEN:%[0-9]+]] = class_method [[C]] : {{.*}}, #SomeClass.generic!1 // CHECK: [[TMPK:%.*]] = alloc_stack $Builtin.Int64 // CHECK: [[TMPR:%.*]] = alloc_stack $Builtin.Int64 - // CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]]#1, [[TMPK]]#1, [[C]]) + // CHECK: apply [[METHOD_GEN]]<{{.*}}>([[TMPR]], [[TMPK]], [[C]]) c.generic(k) // FIXME: curried generic entry points @@ -466,7 +466,7 @@ func calls(i: Int, j: Int, k: Int) { // CHECK-LABEL: sil shared @_TFC9functions9SomeClass6method{{.*}} : $@convention(thin) (@owned SomeClass) -> @owned @callee_owned (Builtin.Int64) -> () // CHECK: bb0(%0 : $SomeClass): -// CHECK: class_method %0 : $SomeClass, #SomeClass.method!1 : SomeClass -> (Builtin.Int64) -> () +// CHECK: class_method %0 : $SomeClass, #SomeClass.method!1 : (SomeClass) -> (Builtin.Int64) -> () // CHECK: %2 = partial_apply %1(%0) // CHECK: return %2 @@ -506,7 +506,7 @@ func return_generic_tuple() @noreturn func testNoReturnAttrPoly(x: T) -> () {} // CHECK-LABEL: sil hidden @_TF9functions21testNoReturnAttrParam{{.*}} : $@convention(thin) (@owned @noreturn @callee_owned () -> ()) -> () -func testNoReturnAttrParam(fptr: @noreturn ()->()) -> () {} +func testNoReturnAttrParam(fptr: @noreturn () -> ()) -> () {} // CHECK-LABEL: sil hidden [transparent] @_TF9functions15testTransparent{{.*}} : $@convention(thin) (Builtin.Int1) -> Builtin.Int1 @_transparent func testTransparent(x: Bool) -> Bool { @@ -581,12 +581,12 @@ func testNoescape() { // CHECK-LABEL: functions.testNoescape () -> () // CHECK-NEXT: sil hidden @_TF9functions12testNoescapeFT_T_ : $@convention(thin) () -> () // CHECK: function_ref functions.(testNoescape () -> ()).(closure #1) -// CHECK-NEXT: function_ref @_TFF9functions12testNoescapeFT_T_U_FT_T_ : $@convention(thin) (@owned @box Int, @inout Int) -> () +// CHECK-NEXT: function_ref @_TFF9functions12testNoescapeFT_T_U_FT_T_ : $@convention(thin) (@owned @box Int) -> () // Despite being a noescape closure, this needs to capture 'a' by-box so it can // be passed to the capturing closure.closure // CHECK: functions.(testNoescape () -> ()).(closure #1) -// CHECK-NEXT: sil shared @_TFF9functions12testNoescapeFT_T_U_FT_T_ : $@convention(thin) (@owned @box Int, @inout Int) -> () { +// CHECK-NEXT: sil shared @_TFF9functions12testNoescapeFT_T_U_FT_T_ : $@convention(thin) (@owned @box Int) -> () { @@ -606,10 +606,10 @@ func testNoescape2() { // CHECK-LABEL: sil hidden @_TF9functions13testNoescape2FT_T_ : $@convention(thin) () -> () { // CHECK: // functions.(testNoescape2 () -> ()).(closure #1) -// CHECK-NEXT: sil shared @_TFF9functions13testNoescape2FT_T_U_FT_T_ : $@convention(thin) (@owned @box Int, @inout Int) -> () { +// CHECK-NEXT: sil shared @_TFF9functions13testNoescape2FT_T_U_FT_T_ : $@convention(thin) (@owned @box Int) -> () { // CHECK: // functions.(testNoescape2 () -> ()).(closure #1).(closure #1) -// CHECK-NEXT: sil shared @_TFFF9functions13testNoescape2FT_T_U_FT_T_U_FT_T_ : $@convention(thin) (@owned @box Int, @inout Int) -> () { +// CHECK-NEXT: sil shared @_TFFF9functions13testNoescape2FT_T_U_FT_T_U_FT_T_ : $@convention(thin) (@owned @box Int) -> () { enum PartialApplyEnumPayload { case Left(T) diff --git a/test/SILGen/generic_casts.swift b/test/SILGen/generic_casts.swift index 93808021451bd..81c65a7c21d78 100644 --- a/test/SILGen/generic_casts.swift +++ b/test/SILGen/generic_casts.swift @@ -19,10 +19,10 @@ func opaque_archetype_to_opaque_archetype func opaque_archetype_is_opaque_archetype (t:T, u:U.Type) -> Bool { return t is U - // CHECK: checked_cast_addr_br take_always T in [[VAL:%.*]]#1 : $*T to U in [[DEST:%.*]]#1 : $*U, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] + // CHECK: checked_cast_addr_br take_always T in [[VAL:%.*]] : $*T to U in [[DEST:%.*]] : $*U, [[YES:bb[0-9]+]], [[NO:bb[0-9]+]] // CHECK: [[YES]]: // CHECK: [[Y:%.*]] = integer_literal $Builtin.Int1, -1 - // CHECK: destroy_addr [[DEST]]#1 + // CHECK: destroy_addr [[DEST]] // CHECK: br [[CONT:bb[0-9]+]]([[Y]] : $Builtin.Int1) // CHECK: [[NO]]: // CHECK: [[N:%.*]] = integer_literal $Builtin.Int1, 0 @@ -121,9 +121,9 @@ func opaque_existential_to_opaque_archetype return p as! T // CHECK: bb0([[RET:%.*]] : $*T, [[ARG:%.*]] : $*NotClassBound): // CHECK: [[TEMP:%.*]] = alloc_stack $NotClassBound - // CHECK-NEXT: copy_addr [[ARG]] to [initialization] [[TEMP]]#1 - // CHECK-NEXT: unconditional_checked_cast_addr take_always NotClassBound in [[TEMP]]#1 : $*NotClassBound to T in [[RET]] : $*T - // CHECK-NEXT: dealloc_stack [[TEMP]]#0 + // CHECK-NEXT: copy_addr [[ARG]] to [initialization] [[TEMP]] + // CHECK-NEXT: unconditional_checked_cast_addr take_always NotClassBound in [[TEMP]] : $*NotClassBound to T in [[RET]] : $*T + // CHECK-NEXT: dealloc_stack [[TEMP]] // CHECK-NEXT: destroy_addr [[ARG]] // CHECK-NEXT: [[T0:%.*]] = tuple () // CHECK-NEXT: return [[T0]] diff --git a/test/SILGen/generic_closures.swift b/test/SILGen/generic_closures.swift index 4e2bdc7bb23b2..1eff96f42dd3c 100644 --- a/test/SILGen/generic_closures.swift +++ b/test/SILGen/generic_closures.swift @@ -8,7 +8,7 @@ var zero: Int func generic_nondependent_context(x: T, y: Int) -> Int { var y = y func foo() -> Int { return y } - // CHECK: [[FOO:%.*]] = function_ref @_TFF16generic_closures28generic_nondependent_context{{.*}} : $@convention(thin) (@owned @box Int, @inout Int) -> Int + // CHECK: [[FOO:%.*]] = function_ref @_TFF16generic_closures28generic_nondependent_context{{.*}} : $@convention(thin) (@owned @box Int) -> Int // CHECK: [[FOO_CLOSURE:%.*]] = apply [[FOO]] return foo() } @@ -44,7 +44,7 @@ func generic_nocapture_existential(x: T, y: Concept) -> Bool { // CHECK-LABEL: sil hidden @_TF16generic_closures25generic_dependent_context{{.*}} func generic_dependent_context(x: T, y: Int) -> T { func foo() -> T { return x } - // CHECK: [[FOO:%.*]] = function_ref @_TFF16generic_closures25generic_dependent_context{{.*}} : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0, @inout τ_0_0) -> () + // CHECK: [[FOO:%.*]] = function_ref @_TFF16generic_closures25generic_dependent_context{{.*}} : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0) -> () // CHECK: [[FOO_CLOSURE:%.*]] = apply [[FOO]] return foo() } @@ -95,9 +95,9 @@ var f: (Int) -> () = generic_curried_function(zero) // CHECK: sil hidden @_TF16generic_closures25nested_closure_in_generic{{.*}} : $@convention(thin) (@out T, @in T) -> () // CHECK: function_ref [[OUTER_CLOSURE:@_TFF16generic_closures25nested_closure_in_genericurFxxU_FT_Q_]] - // CHECK: sil shared [[OUTER_CLOSURE]] : $@convention(thin) (@out T, @inout T) -> () + // CHECK: sil shared [[OUTER_CLOSURE]] : $@convention(thin) (@out T, @inout_aliasable T) -> () // CHECK: function_ref [[INNER_CLOSURE:@_TFFF16generic_closures25nested_closure_in_genericurFxxU_FT_Q_U_FT_Q_]] - // CHECK: sil shared [[INNER_CLOSURE]] : $@convention(thin) (@out T, @inout T) -> () { + // CHECK: sil shared [[INNER_CLOSURE]] : $@convention(thin) (@out T, @inout_aliasable T) -> () { func nested_closure_in_generic(x:T) -> T { return { { x }() }() } @@ -114,11 +114,11 @@ func local_properties(inout t: T) { } } - // CHECK: [[GETTER_REF:%[0-9]+]] = function_ref [[GETTER_CLOSURE:@_TFF16generic_closures16local_properties.*]] : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0, @inout τ_0_0) -> () + // CHECK: [[GETTER_REF:%[0-9]+]] = function_ref [[GETTER_CLOSURE:@_TFF16generic_closures16local_properties.*]] : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0) -> () // CHECK: apply [[GETTER_REF]] t = prop - // CHECK: [[SETTER_REF:%[0-9]+]] = function_ref [[SETTER_CLOSURE:@_TFF16generic_closures16local_properties.*]] : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned @box τ_0_0, @inout τ_0_0) -> () + // CHECK: [[SETTER_REF:%[0-9]+]] = function_ref [[SETTER_CLOSURE:@_TFF16generic_closures16local_properties.*]] : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned @box τ_0_0) -> () // CHECK: apply [[SETTER_REF]] prop = t @@ -131,7 +131,7 @@ func local_properties(inout t: T) { } } - // CHECK: [[GETTER2_REF:%[0-9]+]] = function_ref [[GETTER2_CLOSURE:@_TFF16generic_closures16local_properties.*]] : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0, @inout τ_0_0) -> () + // CHECK: [[GETTER2_REF:%[0-9]+]] = function_ref [[GETTER2_CLOSURE:@_TFF16generic_closures16local_properties.*]] : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0) -> () // CHECK: apply [[GETTER2_REF]] t = prop2 diff --git a/test/SILGen/generic_literals.swift b/test/SILGen/generic_literals.swift index 95aa3fbb085a2..d29db5feca0e9 100644 --- a/test/SILGen/generic_literals.swift +++ b/test/SILGen/generic_literals.swift @@ -9,9 +9,9 @@ func genericIntegerLiteral(x: T) { // CHECK: [[LITMETA:%.*]] = metatype $@thick T.IntegerLiteralType.Type // CHECK: [[INTLIT:%.*]] = integer_literal $Builtin.Int2048, 17 // CHECK: [[LITVAR:%.*]] = alloc_stack $T.IntegerLiteralType - // CHECK: [[LIT:%.*]] = apply [[BUILTINCONV]]([[LITVAR]]#1, [[INTLIT]], [[LITMETA]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : _BuiltinIntegerLiteralConvertible> (@out τ_0_0, Builtin.Int2048, @thick τ_0_0.Type) -> () + // CHECK: [[LIT:%.*]] = apply [[BUILTINCONV]]([[LITVAR]], [[INTLIT]], [[LITMETA]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : _BuiltinIntegerLiteralConvertible> (@out τ_0_0, Builtin.Int2048, @thick τ_0_0.Type) -> () // CHECK: [[ADDR:%.*]] = alloc_stack $T - // CHECK: apply [[TCONV]]([[ADDR]]#1, [[LITVAR]]#1, [[TMETA]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : IntegerLiteralConvertible, τ_0_0.IntegerLiteralType : _BuiltinIntegerLiteralConvertible> (@out τ_0_0, @in τ_0_0.IntegerLiteralType, @thick τ_0_0.Type) -> () + // CHECK: apply [[TCONV]]([[ADDR]], [[LITVAR]], [[TMETA]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : IntegerLiteralConvertible, τ_0_0.IntegerLiteralType : _BuiltinIntegerLiteralConvertible> (@out τ_0_0, @in τ_0_0.IntegerLiteralType, @thick τ_0_0.Type) -> () x = 17 } @@ -25,9 +25,9 @@ func genericFloatingLiteral(x: T) { // CHECK: [[TFLT_META:%.*]] = metatype $@thick T.FloatLiteralType.Type // CHECK: [[LIT_VALUE:%.*]] = float_literal $Builtin.FPIEEE{{64|80}}, {{0x4004000000000000|0x4000A000000000000000}} // CHECK: [[FLT_VAL:%.*]] = alloc_stack $T.FloatLiteralType - // CHECK: apply [[BUILTIN_CONV]]([[FLT_VAL]]#1, [[LIT_VALUE]], [[TFLT_META]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : _BuiltinFloatLiteralConvertible> (@out τ_0_0, Builtin.FPIEEE{{64|80}}, @thick τ_0_0.Type) -> () + // CHECK: apply [[BUILTIN_CONV]]([[FLT_VAL]], [[LIT_VALUE]], [[TFLT_META]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : _BuiltinFloatLiteralConvertible> (@out τ_0_0, Builtin.FPIEEE{{64|80}}, @thick τ_0_0.Type) -> () // CHECK: [[TVAL:%.*]] = alloc_stack $T - // CHECK: apply [[CONV]]([[TVAL]]#1, [[FLT_VAL]]#1, [[TMETA]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : FloatLiteralConvertible, τ_0_0.FloatLiteralType : _BuiltinFloatLiteralConvertible> (@out τ_0_0, @in τ_0_0.FloatLiteralType, @thick τ_0_0.Type) -> () + // CHECK: apply [[CONV]]([[TVAL]], [[FLT_VAL]], [[TMETA]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : FloatLiteralConvertible, τ_0_0.FloatLiteralType : _BuiltinFloatLiteralConvertible> (@out τ_0_0, @in τ_0_0.FloatLiteralType, @thick τ_0_0.Type) -> () x = 2.5 } diff --git a/test/SILGen/generic_property_base_lifetime.swift b/test/SILGen/generic_property_base_lifetime.swift index 3c9dd1f7ecdfa..b6adc362dd75b 100644 --- a/test/SILGen/generic_property_base_lifetime.swift +++ b/test/SILGen/generic_property_base_lifetime.swift @@ -52,10 +52,10 @@ func setIntPropGeneric(a: T) { // CHECK-LABEL: sil hidden @_TF30generic_property_base_lifetime21getIntPropExistentialFPS_9ProtocolB_Si // CHECK: [[PROJECTION:%.*]] = open_existential_addr %0 // CHECK: [[STACK:%[0-9]+]] = alloc_stack $@opened({{".*"}}) ProtocolB -// CHECK: copy_addr [[PROJECTION]] to [initialization] [[STACK]]#1 -// CHECK: apply {{%.*}}([[STACK]]#1) -// CHECK: destroy_addr [[STACK]]#1 -// CHECK: dealloc_stack [[STACK]]#0 +// CHECK: copy_addr [[PROJECTION]] to [initialization] [[STACK]] +// CHECK: apply {{%.*}}([[STACK]]) +// CHECK: destroy_addr [[STACK]] +// CHECK: dealloc_stack [[STACK]] // CHECK: destroy_addr %0 func getIntPropExistential(a: ProtocolB) -> Int { return a.intProp @@ -63,10 +63,10 @@ func getIntPropExistential(a: ProtocolB) -> Int { // CHECK-LABEL: sil hidden @_TF30generic_property_base_lifetime17getIntPropGeneric // CHECK: [[STACK:%[0-9]+]] = alloc_stack $T -// CHECK: copy_addr %0 to [initialization] [[STACK]]#1 -// CHECK: apply {{%.*}}([[STACK]]#1) -// CHECK: destroy_addr [[STACK]]#1 -// CHECK: dealloc_stack [[STACK]]#0 +// CHECK: copy_addr %0 to [initialization] [[STACK]] +// CHECK: apply {{%.*}}([[STACK]]) +// CHECK: destroy_addr [[STACK]] +// CHECK: dealloc_stack [[STACK]] // CHECK: destroy_addr %0 func getIntPropGeneric(a: T) -> Int { return a.intProp diff --git a/test/SILGen/generic_tuples.swift b/test/SILGen/generic_tuples.swift index ee3ed83d89d84..161be88a2dcca 100644 --- a/test/SILGen/generic_tuples.swift +++ b/test/SILGen/generic_tuples.swift @@ -4,7 +4,7 @@ func dup(x: T) -> (T, T) { return (x,x) } // CHECK-LABEL: sil hidden @_TF14generic_tuples3dup // CHECK: ([[RESULT:%.*]] : $*(T, T), [[XVAR:%.*]] : $*T): -// CHECK-NEXT: debug_value_addr [[XVAR]] : $*T // let x +// CHECK-NEXT: debug_value_addr [[XVAR]] : $*T, let, name "x" // CHECK-NEXT: [[T0:%.*]] = tuple_element_addr [[RESULT]] : {{.*}}, 0 // CHECK-NEXT: [[T1:%.*]] = tuple_element_addr [[RESULT]] : {{.*}}, 1 // CHECK-NEXT: copy_addr [[XVAR]] to [initialization] [[T0]] diff --git a/test/SILGen/generic_witness.swift b/test/SILGen/generic_witness.swift index bb9af4267b6df..b217194ee36e5 100644 --- a/test/SILGen/generic_witness.swift +++ b/test/SILGen/generic_witness.swift @@ -17,7 +17,7 @@ func bar(x: Runcible) { var x = x // CHECK: [[BOX:%.*]] = alloc_box $Runcible // CHECK: [[TEMP:%.*]] = alloc_stack $Runcible - // CHECK: [[EXIST:%.*]] = open_existential_addr [[TEMP]]#1 : $*Runcible to $*[[OPENED:@opened(.*) Runcible]] + // CHECK: [[EXIST:%.*]] = open_existential_addr [[TEMP]] : $*Runcible to $*[[OPENED:@opened(.*) Runcible]] // CHECK: [[METHOD:%.*]] = witness_method $[[OPENED]], #Runcible.runce!1 // CHECK: apply [[METHOD]]<[[OPENED]], Int> x.runce(5) diff --git a/test/SILGen/guaranteed_closure_context.swift b/test/SILGen/guaranteed_closure_context.swift new file mode 100644 index 0000000000000..1865341167339 --- /dev/null +++ b/test/SILGen/guaranteed_closure_context.swift @@ -0,0 +1,69 @@ +// RUN: %target-swift-frontend -parse-as-library -emit-silgen -enable-guaranteed-closure-contexts %s | FileCheck %s + +func use(_: T) {} + +func escape(f: () -> ()) {} + +protocol P {} +class C: P {} +struct S {} + +// CHECK-LABEL: sil hidden @_TF26guaranteed_closure_context19guaranteed_capturesFT_T_ +func guaranteed_captures() { + // CHECK: [[MUTABLE_TRIVIAL_BOX:%.*]] = alloc_box $S + var mutableTrivial = S() + // CHECK: [[MUTABLE_RETAINABLE_BOX:%.*]] = alloc_box $C + var mutableRetainable = C() + // CHECK: [[MUTABLE_ADDRESS_ONLY_BOX:%.*]] = alloc_box $P + var mutableAddressOnly: P = C() + + // CHECK: [[IMMUTABLE_TRIVIAL:%.*]] = apply {{.*}} -> S + let immutableTrivial = S() + // CHECK: [[IMMUTABLE_RETAINABLE:%.*]] = apply {{.*}} -> @owned C + let immutableRetainable = C() + // CHECK: [[IMMUTABLE_ADDRESS_ONLY:%.*]] = alloc_stack $P + let immutableAddressOnly: P = C() + + func captureEverything() { + use((mutableTrivial, mutableRetainable, mutableAddressOnly, + immutableTrivial, immutableRetainable, immutableAddressOnly)) + } + + // CHECK-NOT: strong_retain [[MUTABLE_TRIVIAL_BOX]] + // CHECK-NOT: strong_retain [[MUTABLE_RETAINABLE_BOX]] + // CHECK-NOT: strong_retain [[MUTABLE_ADDRESS_ONLY_BOX]] + // CHECK-NOT: strong_retain [[IMMUTABLE_RETAINABLE]] + // CHECK: [[IMMUTABLE_AO_BOX:%.*]] = alloc_box $P + + // CHECK: [[FN:%.*]] = function_ref [[FN_NAME:@_TFF26guaranteed_closure_context19guaranteed_capturesFT_T_L_17captureEverythingfT_T_]] + // CHECK: apply [[FN]]([[MUTABLE_TRIVIAL_BOX]]#0, [[MUTABLE_RETAINABLE_BOX]]#0, [[MUTABLE_ADDRESS_ONLY_BOX]]#0, [[IMMUTABLE_TRIVIAL]], [[IMMUTABLE_RETAINABLE]], [[IMMUTABLE_AO_BOX]]#0) + captureEverything() + + // CHECK: strong_release [[IMMUTABLE_AO_BOX]] + + // CHECK-NOT: strong_retain [[MUTABLE_TRIVIAL_BOX]] + // CHECK-NOT: strong_retain [[MUTABLE_RETAINABLE_BOX]] + // CHECK-NOT: strong_retain [[MUTABLE_ADDRESS_ONLY_BOX]] + // CHECK-NOT: strong_retain [[IMMUTABLE_RETAINABLE]] + + // -- partial_apply still takes ownership of its arguments. + // CHECK: [[FN:%.*]] = function_ref [[FN_NAME]] + // CHECK: strong_retain [[MUTABLE_TRIVIAL_BOX]] + // CHECK: strong_retain [[MUTABLE_RETAINABLE_BOX]] + // CHECK: strong_retain [[MUTABLE_ADDRESS_ONLY_BOX]] + // CHECK: strong_retain [[IMMUTABLE_RETAINABLE]] + // CHECK: [[IMMUTABLE_AO_BOX:%.*]] = alloc_box $P + // CHECK: [[CLOSURE:%.*]] = partial_apply {{.*}}([[MUTABLE_TRIVIAL_BOX]]#0, [[MUTABLE_RETAINABLE_BOX]]#0, [[MUTABLE_ADDRESS_ONLY_BOX]]#0, [[IMMUTABLE_TRIVIAL]], [[IMMUTABLE_RETAINABLE]], [[IMMUTABLE_AO_BOX]]#0) + // CHECK: apply {{.*}}[[CLOSURE]] + + // CHECK-NOT: strong_retain [[MUTABLE_TRIVIAL_BOX]] + // CHECK-NOT: strong_retain [[MUTABLE_RETAINABLE_BOX]] + // CHECK-NOT: strong_retain [[MUTABLE_ADDRESS_ONLY_BOX]] + // CHECK-NOT: strong_retain [[IMMUTABLE_RETAINABLE]] + // CHECK-NOT: strong_release [[IMMUTABLE_AO_BOX]] + + escape(captureEverything) + +} + +// CHECK: sil shared [[FN_NAME]] : $@convention(thin) (@guaranteed @box S, @guaranteed @box C, @guaranteed @box P, S, @guaranteed C, @guaranteed @box P) diff --git a/test/SILGen/guaranteed_self.swift b/test/SILGen/guaranteed_self.swift index 7e3cc518e6c9d..b5a96a5be54da 100644 --- a/test/SILGen/guaranteed_self.swift +++ b/test/SILGen/guaranteed_self.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-silgen %s -disable-objc-attr-requires-foundation-module | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -emit-silgen %s -disable-objc-attr-requires-foundation-module | FileCheck %s protocol Fooable { init() @@ -253,7 +253,7 @@ struct AO: Fooable { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWurGV15guaranteed_self2AOx_S_7FooableS_FS1_3foo{{.*}} : $@convention(witness_method) (Int, @in_guaranteed AO) -> () // CHECK: bb0({{.*}} [[SELF_ADDR:%.*]] : $*AO): // TODO: This copy isn't necessary. -// CHECK: copy_addr [[SELF_ADDR]] to [initialization] [[SELF_COPY:%.*]]#1 +// CHECK: copy_addr [[SELF_ADDR]] to [initialization] [[SELF_COPY:%.*]] : // CHECK: apply {{.*}} [[SELF_COPY]] // CHECK: destroy_addr [[SELF_COPY]] // CHECK-NOT: destroy_addr [[SELF_ADDR]] @@ -263,7 +263,7 @@ struct AO: Fooable { // CHECK: bb0([[SELF_ADDR:%.*]] : $*AO): // -- NB: This copy *is* necessary, unless we're willing to assume an inout // parameter is not mutably aliased. -// CHECK: copy_addr [[SELF_ADDR]] to [initialization] [[SELF_COPY:%.*]]#1 +// CHECK: copy_addr [[SELF_ADDR]] to [initialization] [[SELF_COPY:%.*]] : // CHECK: apply {{.*}} [[SELF_COPY]] // CHECK: destroy_addr [[SELF_COPY]] // CHECK-NOT: destroy_addr [[SELF_ADDR]] @@ -362,7 +362,6 @@ class D: C { // CHECK: [[SELF1:%.*]] = load [[SELF_ADDR]] // CHECK-NEXT: [[SUPER1:%.*]] = upcast [[SELF1]] // CHECK-NOT: [[SELF_ADDR]] - // CHECK-NOT: [[SELF1]] // CHECK: [[SUPER2:%.*]] = apply {{.*}}([[SUPER1]]) // CHECK-NEXT: [[SELF2:%.*]] = unchecked_ref_cast [[SUPER2]] // CHECK-NEXT: store [[SELF2]] to [[SELF_ADDR]] @@ -406,15 +405,15 @@ func AO_curryThunk(ao: AO) -> (AO -> Int -> ()/*, Int -> ()*/) { // CHECK-LABEL: sil [transparent] [thunk] @_TTWV15guaranteed_self9FakeArrayS_12SequenceTypeS_FS1_17_constrainElement{{.*}} : $@convention(witness_method) (@in FakeElement, @in_guaranteed FakeArray) -> () { // CHECK: bb0([[ARG0_PTR:%.*]] : $*FakeElement, [[ARG1_PTR:%.*]] : $*FakeArray): // CHECK: [[GUARANTEED_COPY_STACK_SLOT:%.*]] = alloc_stack $FakeArray -// CHECK: copy_addr [[ARG1_PTR]] to [initialization] [[GUARANTEED_COPY_STACK_SLOT]]#1 +// CHECK: copy_addr [[ARG1_PTR]] to [initialization] [[GUARANTEED_COPY_STACK_SLOT]] // CHECK: [[ARG0:%.*]] = load [[ARG0_PTR]] -// CHECK: [[GUARANTEED_COPY:%.*]] = load [[GUARANTEED_COPY_STACK_SLOT]]#1 +// CHECK: [[GUARANTEED_COPY:%.*]] = load [[GUARANTEED_COPY_STACK_SLOT]] // CHECK: function_ref ext.guaranteed_self.guaranteed_self.SequenceDefaultsType._constrainElement // CHECK: [[FUN:%.*]] = function_ref @_{{.*}} // CHECK: [[TRANSLATION_STACK_SLOT:%.*]] = alloc_stack $FakeArray -// CHECK: store [[GUARANTEED_COPY]] to [[TRANSLATION_STACK_SLOT:%.*]]#1 -// CHECK: apply [[FUN]]([[ARG0]], [[TRANSLATION_STACK_SLOT]]#1) -// CHECK: destroy_addr [[TRANSLATION_STACK_SLOT]]#1 +// CHECK: store [[GUARANTEED_COPY]] to [[TRANSLATION_STACK_SLOT]] +// CHECK: apply [[FUN]]([[ARG0]], [[TRANSLATION_STACK_SLOT]]) +// CHECK: destroy_addr [[TRANSLATION_STACK_SLOT]] class Z {} @@ -534,7 +533,7 @@ func curried_test2() { // CHECK: [[KRAKEN:%.*]] = apply [[KRAKEN_CONSTRUCTOR]]( // CHECK: [[CTB_CONSTRUCTOR:%.*]] = function_ref @_TFC15guaranteed_self14CurriedTestBarC{{.*}} // CHECK: [[CTB:%.*]] = apply [[CTB_CONSTRUCTOR]]( -// CHECK: [[CLASS_METHOD:%.*]] = class_method [[CTB]] : $CurriedTestBar, #CurriedTestBar.bar!3 : CurriedTestBar -> (Kraken) -> (Kraken) -> (Kraken) -> Kraken , $@convention(method) (@owned Kraken, @owned Kraken, @owned Kraken, @guaranteed CurriedTestBar) -> @owned Kraken +// CHECK: [[CLASS_METHOD:%.*]] = class_method [[CTB]] : $CurriedTestBar, #CurriedTestBar.bar!3 : (CurriedTestBar) -> (Kraken) -> (Kraken) -> (Kraken) -> Kraken , $@convention(method) (@owned Kraken, @owned Kraken, @owned Kraken, @guaranteed CurriedTestBar) -> @owned Kraken // CHECK-NOT: strong_retain [[CTB]] // CHECK: strong_retain [[KRAKEN]] // CHECK-NEXT: strong_retain [[KRAKEN]] @@ -598,18 +597,18 @@ class LetFieldClass { // CHECK-LABEL: sil hidden @_TFC15guaranteed_self13LetFieldClass10varkMethod{{.*}} : $@convention(method) (@guaranteed LetFieldClass) -> () { // CHECK: bb0([[CLS:%.*]] : $LetFieldClass): - // CHECK: [[KRAKEN_GETTER_FUN:%.*]] = class_method [[CLS]] : $LetFieldClass, #LetFieldClass.vark!getter.1 : LetFieldClass -> () -> Kraken , $@convention(method) (@guaranteed LetFieldClass) -> @owned Kraken + // CHECK: [[KRAKEN_GETTER_FUN:%.*]] = class_method [[CLS]] : $LetFieldClass, #LetFieldClass.vark!getter.1 : (LetFieldClass) -> () -> Kraken , $@convention(method) (@guaranteed LetFieldClass) -> @owned Kraken // CHECK-NEXT: [[KRAKEN:%.*]] = apply [[KRAKEN_GETTER_FUN]]([[CLS]]) // CHECK-NEXT: [[KRAKEN_METH:%.*]] = class_method [[KRAKEN]] // CHECK-NEXT: apply [[KRAKEN_METH]]([[KRAKEN]]) // CHECK-NEXT: strong_release [[KRAKEN]] - // CHECK-NEXT: [[KRAKEN_GETTER_FUN:%.*]] = class_method [[CLS]] : $LetFieldClass, #LetFieldClass.vark!getter.1 : LetFieldClass -> () -> Kraken , $@convention(method) (@guaranteed LetFieldClass) -> @owned Kraken + // CHECK-NEXT: [[KRAKEN_GETTER_FUN:%.*]] = class_method [[CLS]] : $LetFieldClass, #LetFieldClass.vark!getter.1 : (LetFieldClass) -> () -> Kraken , $@convention(method) (@guaranteed LetFieldClass) -> @owned Kraken // CHECK-NEXT: [[KRAKEN:%.*]] = apply [[KRAKEN_GETTER_FUN]]([[CLS]]) // CHECK: [[DESTROY_SHIP_FUN:%.*]] = function_ref @_TF15guaranteed_self11destroyShipFCS_6KrakenT_ : $@convention(thin) (@owned Kraken) -> () // CHECK-NEXT: strong_retain [[KRAKEN]] // CHECK-NEXT: apply [[DESTROY_SHIP_FUN]]([[KRAKEN]]) // CHECK-NEXT: [[KRAKEN_BOX:%.*]] = alloc_box $Kraken - // CHECK-NEXT: [[KRAKEN_GETTER_FUN:%.*]] = class_method [[CLS]] : $LetFieldClass, #LetFieldClass.vark!getter.1 : LetFieldClass -> () -> Kraken , $@convention(method) (@guaranteed LetFieldClass) -> @owned Kraken + // CHECK-NEXT: [[KRAKEN_GETTER_FUN:%.*]] = class_method [[CLS]] : $LetFieldClass, #LetFieldClass.vark!getter.1 : (LetFieldClass) -> () -> Kraken , $@convention(method) (@guaranteed LetFieldClass) -> @owned Kraken // CHECK-NEXT: [[KRAKEN2:%.*]] = apply [[KRAKEN_GETTER_FUN]]([[CLS]]) // CHECK-NEXT: store [[KRAKEN2]] to [[KRAKEN_BOX]]#1 // CHECK: [[DESTROY_SHIP_FUN:%.*]] = function_ref @_TF15guaranteed_self11destroyShipFCS_6KrakenT_ : $@convention(thin) (@owned Kraken) -> () diff --git a/test/SILGen/if_expr.swift b/test/SILGen/if_expr.swift index 8d01d7535f53d..25c2bf2b1b0b6 100644 --- a/test/SILGen/if_expr.swift +++ b/test/SILGen/if_expr.swift @@ -32,9 +32,9 @@ func consumeAddressOnly(_: AddressOnly) {} // CHECK: sil hidden @_TF7if_expr19addr_only_ternary_1 func addr_only_ternary_1(x: Bool) -> AddressOnly { // CHECK: bb0([[RET:%.*]] : $*AddressOnly, {{.*}}): - // CHECK: [[a:%[0-9]+]] = alloc_box $AddressOnly // var a + // CHECK: [[a:%[0-9]+]] = alloc_box $AddressOnly, var, name "a" var a : AddressOnly = A() - // CHECK: [[b:%[0-9]+]] = alloc_box $AddressOnly // var b + // CHECK: [[b:%[0-9]+]] = alloc_box $AddressOnly, var, name "b" var b : AddressOnly = B() // CHECK: cond_br {{%.*}}, [[TRUE:bb[0-9]+]], [[FALSE:bb[0-9]+]] diff --git a/test/SILGen/if_while_binding.swift b/test/SILGen/if_while_binding.swift index 93829cccc16f4..fffd4e0c112f1 100644 --- a/test/SILGen/if_while_binding.swift +++ b/test/SILGen/if_while_binding.swift @@ -37,7 +37,7 @@ func if_else_chain() { // CHECK: switch_enum [[XVAL]] : $Optional, case #Optional.Some!enumelt.1: [[YESX:bb[0-9]+]], default [[NOX:bb[0-9]+]] if let x = foo() { // CHECK: [[YESX]]([[XVAL:%[0-9]+]] : $String): - // CHECK: debug_value [[XVAL]] : $String // let x + // CHECK: debug_value [[XVAL]] : $String, let, name "x" // CHECK: [[A:%.*]] = function_ref @_TF16if_while_binding1aFSST_ // CHECK: retain_value [[XVAL]] // CHECK: apply [[A]]([[XVAL]]) @@ -102,16 +102,16 @@ func while_loop() { // CHECK-LABEL: sil hidden @_TF16if_while_binding18while_loop_generic // CHECK: br [[COND:bb[0-9]+]] // CHECK: [[COND]]: -// CHECK: [[X:%.*]] = alloc_stack $T // let x +// CHECK: [[X:%.*]] = alloc_stack $T, let, name "x" // CHECK: [[OPTBUF:%[0-9]+]] = alloc_stack $Optional // CHECK: switch_enum_addr {{.*}}, case #Optional.Some!enumelt.1: [[LOOPBODY:bb.*]], default [[OUT:bb[0-9]+]] // CHECK: [[OUT]]: -// CHECK: dealloc_stack [[OPTBUF]]#0 +// CHECK: dealloc_stack [[OPTBUF]] // CHECK: dealloc_stack [[X]] // CHECK: br [[DONE:bb[0-9]+]] // CHECK: [[LOOPBODY]]: // CHECK: [[ENUMVAL:%.*]] = unchecked_take_enum_data_addr -// CHECK: copy_addr [take] [[ENUMVAL]] to [initialization] [[X]]#1 +// CHECK: copy_addr [take] [[ENUMVAL]] to [initialization] [[X]] // CHECK: destroy_addr [[X]] // CHECK: dealloc_stack [[X]] // CHECK: br [[COND]] @@ -130,7 +130,7 @@ func while_loop_multi() { // CHECK: switch_enum {{.*}}, case #Optional.Some!enumelt.1: [[CHECKBUF2:bb.*]], default [[LOOP_EXIT0:bb[0-9]+]] // CHECK: [[CHECKBUF2]]([[A:%[0-9]+]] : $String): - // CHECK: debug_value [[A]] : $String // let a + // CHECK: debug_value [[A]] : $String, let, name "a" // CHECK: switch_enum {{.*}}, case #Optional.Some!enumelt.1: [[LOOP_BODY:bb.*]], default [[LOOP_EXIT2a:bb[0-9]+]] @@ -140,8 +140,8 @@ func while_loop_multi() { // CHECK: [[LOOP_BODY]]([[B:%[0-9]+]] : $String): while let a = foo(), b = bar() { - // CHECK: debug_value [[B]] : $String // let b - // CHECK: debug_value [[A]] : $String // let c + // CHECK: debug_value [[B]] : $String, let, name "b" + // CHECK: debug_value [[A]] : $String, let, name "c" // CHECK: release_value [[B]] // CHECK: release_value [[A]] // CHECK: br [[LOOP_ENTRY]] @@ -262,7 +262,7 @@ func if_multi_where() { func if_leading_boolean(a : Int) { // Test the boolean condition. - // CHECK: debug_value %0 : $Int // let a + // CHECK: debug_value %0 : $Int, let, name "a" // CHECK: [[EQRESULT:%[0-9]+]] = apply {{.*}}(%0, %0) : $@convention(thin) (Int, Int) -> Bool // CHECK-NEXT: [[EQRESULTI1:%[0-9]+]] = apply %2([[EQRESULT]]) : $@convention(method) (Bool) -> Builtin.Int1 @@ -275,8 +275,8 @@ func if_leading_boolean(a : Int) { // CHECK: switch_enum [[OPTRESULT]] : $Optional, case #Optional.Some!enumelt.1: [[SUCCESS:bb.*]], default [[IF_DONE:bb[0-9]+]] // CHECK: [[SUCCESS]]([[B:%[0-9]+]] : $String): - // CHECK-NEXT: debug_value [[B:%[0-9]+]] : $String // let b - // CHECK-NEXT: debug_value [[B:%[0-9]+]] : $String // let c + // CHECK-NEXT: debug_value [[B:%[0-9]+]] : $String, let, name "b" + // CHECK-NEXT: debug_value [[B:%[0-9]+]] : $String, let, name "c" // CHECK-NEXT: release_value [[B]] // CHECK-NEXT: br [[IFDONE]] if a == a, let b = foo() { @@ -295,7 +295,7 @@ class DerivedClass : BaseClass {} // CHECK-LABEL: sil hidden @_TF16if_while_binding20testAsPatternInIfLetFGSqCS_9BaseClass_T_ func testAsPatternInIfLet(a : BaseClass?) { // CHECK: bb0(%0 : $Optional): - // CHECK-NEXT: debug_value %0 : $Optional // let a + // CHECK-NEXT: debug_value %0 : $Optional, let, name "a" // CHECK-NEXT: retain_value %0 : $Optional // CHECK-NEXT: switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: [[OPTPRESENTBB:bb[0-9]+]], default [[NILBB:bb[0-9]+]] diff --git a/test/SILGen/implicitly_unwrapped_optional.swift b/test/SILGen/implicitly_unwrapped_optional.swift index 6aef64741c72a..f579741541664 100644 --- a/test/SILGen/implicitly_unwrapped_optional.swift +++ b/test/SILGen/implicitly_unwrapped_optional.swift @@ -1,6 +1,6 @@ // RUN: %target-swift-frontend -emit-silgen %s | FileCheck %s -func foo(f f: (()->())!) { +func foo(f f: (() -> ())!) { var f = f f?() } diff --git a/test/SILGen/indirect_enum.swift b/test/SILGen/indirect_enum.swift index 01772d9d3bc7c..bf5584d023a9d 100644 --- a/test/SILGen/indirect_enum.swift +++ b/test/SILGen/indirect_enum.swift @@ -1,63 +1,145 @@ // RUN: %target-swift-frontend -emit-silgen %s | FileCheck %s indirect enum TreeA { - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum5TreeA3Nil{{.*}} : $@convention(thin) (@thin TreeA.Type) -> @owned TreeA { - // CHECK: enum $TreeA, #TreeA.Nil!enumelt case Nil + case Leaf(T) + case Branch(left: TreeA, right: TreeA) +} +// CHECK-LABEL: sil hidden @_TF13indirect_enum11TreeA_casesurFTx1lGOS_5TreeAx_1rGS0_x__T_ +func TreeA_cases(t: T, l: TreeA, r: TreeA) { + +// CHECK: [[METATYPE:%.*]] = metatype $@thin TreeA.Type +// CHECK-NEXT: [[NIL:%.*]] = enum $TreeA, #TreeA.Nil!enumelt +// CHECK-NEXT: release_value [[NIL]] + let _ = TreeA.Nil + +// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeA.Type +// CHECK-NEXT: [[BOX:%.*]] = alloc_box $T +// CHECK-NEXT: copy_addr %0 to [initialization] [[BOX]]#1 +// CHECK-NEXT: [[LEAF:%.*]] = enum $TreeA, #TreeA.Leaf!enumelt.1, [[BOX]]#0 +// CHECK-NEXT: release_value [[LEAF]] + let _ = TreeA.Leaf(t) + +// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeA.Type +// CHECK-NEXT: [[BOX:%.*]] = alloc_box $(left: TreeA, right: TreeA) +// CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[BOX]]#1 : $*(left: TreeA, right: TreeA), 0 +// CHECK-NEXT: [[RIGHT:%.*]] = tuple_element_addr [[BOX]]#1 : $*(left: TreeA, right: TreeA), 1 +// CHECK-NEXT: retain_value %1 +// CHECK-NEXT: store %1 to [[LEFT]] +// CHECK-NEXT: retain_value %2 +// CHECK-NEXT: store %2 to [[RIGHT]] +// CHECK-NEXT: [[BRANCH:%.*]] = enum $TreeA, #TreeA.Branch!enumelt.1, [[BOX]]#0 +// CHECK-NEXT: release_value [[BRANCH]] +// CHECK-NEXT: release_value %2 +// CHECK-NEXT: release_value %1 +// CHECK-NEXT: destroy_addr %0 + let _ = TreeA.Branch(left: l, right: r) + +// CHECK: return - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum5TreeA4Leaf{{.*}} : $@convention(thin) (@in T, @thin TreeA.Type) -> @owned TreeA { - // CHECK: [[BOX:%.*]] = alloc_box $T - // CHECK: copy_addr [take] %0 to [initialization] [[BOX]]#1 : $*T - // CHECK: enum $TreeA, #TreeA.Leaf!enumelt.1, [[BOX]]#0 : $@box T - case Leaf(T) +} - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum5TreeA6Branch{{.*}} - // CHECK: [[TUPLE:%.*]] = tuple $(left: TreeA, right: TreeA) (%0, %1) - // CHECK: [[BOX:%.*]] = alloc_box $(left: TreeA, right: TreeA) - // CHECK: store [[TUPLE]] to [[BOX]]#1 : $*(left: TreeA, right: TreeA) - // CHECK: enum $TreeA, #TreeA.Branch!enumelt.1, [[BOX]]#0 : $@box (left: TreeA, right: TreeA) - case Branch(left: TreeA, right: TreeA) +// CHECK-LABEL: sil hidden @_TF13indirect_enum16TreeA_reabstractFFSiSiT_ +func TreeA_reabstract(f: Int -> Int) { + +// CHECK: [[METATYPE:%.*]] = metatype $@thin TreeA Int>.Type +// CHECK-NEXT: [[BOX:%.*]] = alloc_box $@callee_owned (@out Int, @in Int) -> () +// CHECK-NEXT: strong_retain %0 +// CHECK: [[THUNK:%.*]] = function_ref @_TTRXFo_dSi_dSi_XFo_iSi_iSi_ +// CHECK-NEXT: [[FN:%.*]] = partial_apply [[THUNK]](%0) +// CHECK-NEXT: store [[FN]] to [[BOX]]#1 +// CHECK-NEXT: [[LEAF:%.*]] = enum $TreeA Int>, #TreeA.Leaf!enumelt.1, [[BOX]]#0 +// CHECK-NEXT: release_value [[LEAF]] +// CHECK-NEXT: strong_release %0 +// CHECK: return + let _ = TreeA Int>.Leaf(f) } enum TreeB { - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum5TreeB3Nil{{.*}} : $@convention(thin) (@out TreeB, @thin TreeB.Type) -> () { - // CHECK: inject_enum_addr %0 : $*TreeB, #TreeB.Nil!enumelt case Nil - - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum5TreeB4Leaf{{.*}} : $@convention(thin) (@out TreeB, @in T, @thin TreeB.Type) -> () { - // CHECK: [[ADDR:%.*]] = init_enum_data_addr %0 : $*TreeB, #TreeB.Leaf!enumelt.1 - // CHECK: copy_addr [take] %1 to [initialization] [[ADDR]] : $*T - // CHECK: inject_enum_addr %0 : $*TreeB, #TreeB.Leaf!enumelt.1 case Leaf(T) - - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum5TreeB6Branch{{.*}} : $@convention(thin) (@out TreeB, @in TreeB, @in TreeB, @thin TreeB.Type) -> () - // CHECK: [[TUPLE:%.*]] = alloc_stack $(left: TreeB, right: TreeB - // CHECK: [[BOX:%.*]] = alloc_box $(left: TreeB, right: TreeB) - // CHECK: copy_addr [take] [[TUPLE]]#1 to [initialization] [[BOX]]#1 : $*(left: TreeB, right: TreeB) - // CHECK: [[ADDR:%.*]] = init_enum_data_addr %0 : $*TreeB, #TreeB.Branch!enumelt.1 - // CHECK: store [[BOX]]#0 to [[ADDR]] : $*@box (left: TreeB, right: TreeB) - // CHECK: inject_enum_addr %0 : $*TreeB, #TreeB.Branch!enumelt.1 indirect case Branch(left: TreeB, right: TreeB) } +// CHECK-LABEL: sil hidden @_TF13indirect_enum11TreeB_casesurFTx1lGOS_5TreeBx_1rGS0_x__T_ +func TreeB_cases(t: T, l: TreeB, r: TreeB) { + +// CHECK: [[METATYPE:%.*]] = metatype $@thin TreeB.Type +// CHECK: [[NIL:%.*]] = alloc_stack $TreeB +// CHECK-NEXT: inject_enum_addr [[NIL]] : $*TreeB, #TreeB.Nil!enumelt +// CHECK-NEXT: destroy_addr [[NIL]] +// CHECK-NEXT: dealloc_stack [[NIL]] + let _ = TreeB.Nil + +// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeB.Type +// CHECK-NEXT: [[LEAF:%.*]] = alloc_stack $TreeB +// CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[LEAF]] : $*TreeB, #TreeB.Leaf!enumelt.1 +// CHECK-NEXT: copy_addr %0 to [initialization] [[PAYLOAD]] +// CHECK-NEXT: inject_enum_addr [[LEAF]] : $*TreeB, #TreeB.Leaf!enumelt +// CHECK-NEXT: destroy_addr [[LEAF]] +// CHECK-NEXT: dealloc_stack [[LEAF]] + let _ = TreeB.Leaf(t) + +// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeB.Type +// CHECK-NEXT: [[BOX:%.*]] = alloc_box $(left: TreeB, right: TreeB) +// CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[BOX]]#1 +// CHECK-NEXT: [[RIGHT:%.*]] = tuple_element_addr [[BOX]]#1 +// CHECK-NEXT: copy_addr %1 to [initialization] [[LEFT]] : $*TreeB +// CHECK-NEXT: copy_addr %2 to [initialization] [[RIGHT]] : $*TreeB +// CHECK-NEXT: [[BRANCH:%.*]] = alloc_stack $TreeB +// CHECK-NEXT: [[PAYLOAD:%.*]] = init_enum_data_addr [[BRANCH]] +// CHECK-NEXT: store [[BOX]]#0 to [[PAYLOAD]] +// CHECK-NEXT: inject_enum_addr [[BRANCH]] : $*TreeB, #TreeB.Branch!enumelt.1 +// CHECK-NEXT: destroy_addr [[BRANCH]] +// CHECK-NEXT: dealloc_stack [[BRANCH]] +// CHECK-NEXT: destroy_addr %2 +// CHECK-NEXT: destroy_addr %1 +// CHECK-NEXT: destroy_addr %0 + let _ = TreeB.Branch(left: l, right: r) + +// CHECK: return + +} + +// CHECK-LABEL: sil hidden @_TF13indirect_enum13TreeInt_casesFTSi1lOS_7TreeInt1rS0__T_ : $@convention(thin) (Int, @owned TreeInt, @owned TreeInt) -> () +func TreeInt_cases(t: Int, l: TreeInt, r: TreeInt) { + +// CHECK: [[METATYPE:%.*]] = metatype $@thin TreeInt.Type +// CHECK-NEXT: [[NIL:%.*]] = enum $TreeInt, #TreeInt.Nil!enumelt +// CHECK-NEXT: release_value [[NIL]] + let _ = TreeInt.Nil + +// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeInt.Type +// CHECK-NEXT: [[LEAF:%.*]] = enum $TreeInt, #TreeInt.Leaf!enumelt.1, %0 +// CHECK-NEXT: release_value [[LEAF]] + let _ = TreeInt.Leaf(t) + +// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin TreeInt.Type +// CHECK-NEXT: [[BOX:%.*]] = alloc_box $(left: TreeInt, right: TreeInt) +// CHECK-NEXT: [[LEFT:%.*]] = tuple_element_addr [[BOX]]#1 +// CHECK-NEXT: [[RIGHT:%.*]] = tuple_element_addr [[BOX]]#1 +// CHECK-NEXT: retain_value %1 +// CHECK-NEXT: store %1 to [[LEFT]] +// CHECK-NEXT: retain_value %2 +// CHECK-NEXT: store %2 to [[RIGHT]] +// CHECK-NEXT: [[BRANCH:%.*]] = enum $TreeInt, #TreeInt.Branch!enumelt.1, [[BOX]] +// CHECK-NEXT: release_value [[BRANCH]] +// CHECK-NEXT: release_value %2 +// CHECK-NEXT: release_value %1 + let _ = TreeInt.Branch(left: l, right: r) + +// CHECK: return + +} + enum TreeInt { - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum7TreeInt3Nil{{.*}} : $@convention(thin) (@thin TreeInt.Type) -> @owned TreeInt { - // CHECK: enum $TreeInt, #TreeInt.Nil!enumelt case Nil - - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum7TreeInt4Leaf{{.*}} : $@convention(thin) (Int, @thin TreeInt.Type) -> @owned TreeInt - // CHECK: enum $TreeInt, #TreeInt.Leaf!enumelt.1, %0 : $Int case Leaf(Int) - - // CHECK-LABEL: sil hidden [transparent] @_TFO13indirect_enum7TreeInt6Branch{{.*}} : $@convention(thin) (@owned TreeInt, @owned TreeInt, @thin TreeInt.Type) -> @owned TreeInt - // CHECK: [[TUPLE:%.*]] = tuple $(left: TreeInt, right: TreeInt) (%0, %1) - // CHECK: [[BOX:%.*]] = alloc_box $(left: TreeInt, right: TreeInt) - // CHECK: store [[TUPLE]] to [[BOX]]#1 : $*(left: TreeInt, right: TreeInt) - // CHECK: enum $TreeInt, #TreeInt.Branch!enumelt.1, [[BOX]]#0 : $@box (left: TreeInt, right: TreeInt) indirect case Branch(left: TreeInt, right: TreeInt) } + enum TrivialButIndirect { case Direct(Int) indirect case Indirect(Int) @@ -80,10 +162,10 @@ func switchTreeA(x: TreeA) { a() // CHECK: bb{{.*}}([[LEAF_BOX:%.*]] : $@box T): // CHECK: [[VALUE:%.*]] = project_box [[LEAF_BOX]] - // CHECK: copy_addr [[VALUE]] to [initialization] [[X:%.*]]#1 : $*T + // CHECK: copy_addr [[VALUE]] to [initialization] [[X:%.*]] : $*T // CHECK: function_ref @_TF13indirect_enum1b - // CHECK: destroy_addr [[X]]#1 - // CHECK: dealloc_stack [[X]]#0 + // CHECK: destroy_addr [[X]] + // CHECK: dealloc_stack [[X]] // -- x +1 // CHECK: strong_release [[LEAF_BOX]] // CHECK: br [[OUTER_CONT:bb[0-9]+]] @@ -132,8 +214,8 @@ func switchTreeA(x: TreeA) { // CHECK-LABEL: sil hidden @_TF13indirect_enum11switchTreeB func switchTreeB(x: TreeB) { - // CHECK: copy_addr %0 to [initialization] [[SCRATCH:%.*]]#1 - // CHECK: switch_enum_addr [[SCRATCH]]#1 + // CHECK: copy_addr %0 to [initialization] [[SCRATCH:%.*]] : + // CHECK: switch_enum_addr [[SCRATCH]] switch x { // CHECK: bb{{.*}}: @@ -145,9 +227,9 @@ func switchTreeB(x: TreeB) { a() // CHECK: bb{{.*}}: - // CHECK: copy_addr [[SCRATCH]]#1 to [initialization] [[LEAF_COPY:%.*]]#1 + // CHECK: copy_addr [[SCRATCH]] to [initialization] [[LEAF_COPY:%.*]] : // CHECK: [[LEAF_ADDR:%.*]] = unchecked_take_enum_data_addr [[LEAF_COPY]] - // CHECK: copy_addr [take] [[LEAF_ADDR]] to [initialization] [[LEAF:%.*]]#1 + // CHECK: copy_addr [take] [[LEAF_ADDR]] to [initialization] [[LEAF:%.*]] : // CHECK: function_ref @_TF13indirect_enum1b // CHECK: destroy_addr [[LEAF]] // CHECK: dealloc_stack [[LEAF]] @@ -160,7 +242,7 @@ func switchTreeB(x: TreeB) { b(x) // CHECK: bb{{.*}}: - // CHECK: copy_addr [[SCRATCH]]#1 to [initialization] [[TREE_COPY:%.*]]#1 + // CHECK: copy_addr [[SCRATCH]] to [initialization] [[TREE_COPY:%.*]] : // CHECK: [[TREE_ADDR:%.*]] = unchecked_take_enum_data_addr [[TREE_COPY]] // -- box +1 immutable // CHECK: [[BOX:%.*]] = load [[TREE_ADDR]] @@ -170,15 +252,15 @@ func switchTreeB(x: TreeB) { // CHECK: switch_enum_addr [[RIGHT]] {{.*}}, default [[RIGHT_FAIL:bb[0-9]+]] // CHECK: bb{{.*}}: - // CHECK: copy_addr [[RIGHT]] to [initialization] [[RIGHT_COPY:%.*]]#1 - // CHECK: [[RIGHT_LEAF:%.*]] = unchecked_take_enum_data_addr [[RIGHT_COPY]]#1 : $*TreeB, #TreeB.Leaf + // CHECK: copy_addr [[RIGHT]] to [initialization] [[RIGHT_COPY:%.*]] : + // CHECK: [[RIGHT_LEAF:%.*]] = unchecked_take_enum_data_addr [[RIGHT_COPY]] : $*TreeB, #TreeB.Leaf // CHECK: switch_enum_addr [[LEFT]] {{.*}}, default [[LEFT_FAIL:bb[0-9]+]] // CHECK: bb{{.*}}: - // CHECK: copy_addr [[LEFT]] to [initialization] [[LEFT_COPY:%.*]]#1 - // CHECK: [[LEFT_LEAF:%.*]] = unchecked_take_enum_data_addr [[LEFT_COPY]]#1 : $*TreeB, #TreeB.Leaf - // CHECK: copy_addr [take] [[LEFT_LEAF]] to [initialization] [[X:%.*]]#1 - // CHECK: copy_addr [take] [[RIGHT_LEAF]] to [initialization] [[Y:%.*]]#1 + // CHECK: copy_addr [[LEFT]] to [initialization] [[LEFT_COPY:%.*]] : + // CHECK: [[LEFT_LEAF:%.*]] = unchecked_take_enum_data_addr [[LEFT_COPY]] : $*TreeB, #TreeB.Leaf + // CHECK: copy_addr [take] [[LEFT_LEAF]] to [initialization] [[X:%.*]] : + // CHECK: copy_addr [take] [[RIGHT_LEAF]] to [initialization] [[Y:%.*]] : // CHECK: function_ref @_TF13indirect_enum1c // CHECK: destroy_addr [[Y]] // CHECK: dealloc_stack [[Y]] @@ -243,8 +325,8 @@ func guardTreeA(tree: TreeA) { // CHECK: [[YES]]([[BOX:%.*]] : $@box T): // CHECK: [[VALUE_ADDR:%.*]] = project_box [[BOX]] // CHECK: [[TMP:%.*]] = alloc_stack - // CHECK: copy_addr [[VALUE_ADDR]] to [initialization] [[TMP]]#1 - // CHECK: copy_addr [take] [[TMP]]#1 to [initialization] [[X]]#1 + // CHECK: copy_addr [[VALUE_ADDR]] to [initialization] [[TMP]] + // CHECK: copy_addr [take] [[TMP]] to [initialization] [[X]] // CHECK: strong_release [[BOX]] guard case .Leaf(let x) = tree else { return } @@ -283,8 +365,8 @@ func guardTreeA(tree: TreeA) { // CHECK: [[YES]]([[BOX:%.*]] : $@box T): // CHECK: [[VALUE_ADDR:%.*]] = project_box [[BOX]] // CHECK: [[TMP:%.*]] = alloc_stack - // CHECK: copy_addr [[VALUE_ADDR]] to [initialization] [[TMP]]#1 - // CHECK: copy_addr [take] [[TMP]]#1 to [initialization] [[X]]#1 + // CHECK: copy_addr [[VALUE_ADDR]] to [initialization] [[TMP]] + // CHECK: copy_addr [take] [[TMP]] to [initialization] [[X]] // CHECK: strong_release [[BOX]] // CHECK: destroy_addr [[X]] if case .Leaf(let x) = tree { } @@ -310,8 +392,8 @@ func guardTreeA(tree: TreeA) { // CHECK-LABEL: sil hidden @_TF13indirect_enum10guardTreeB func guardTreeB(tree: TreeB) { do { - // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]]#1 - // CHECK: switch_enum_addr [[TMP]]#1 : $*TreeB, case #TreeB.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] + // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]] : + // CHECK: switch_enum_addr [[TMP]] : $*TreeB, case #TreeB.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] // CHECK: [[NO]]: // CHECK: destroy_addr [[TMP]] // CHECK: [[YES]]: @@ -319,8 +401,8 @@ func guardTreeB(tree: TreeB) { guard case .Nil = tree else { return } // CHECK: [[X:%.*]] = alloc_stack $T - // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]]#1 - // CHECK: switch_enum_addr [[TMP]]#1 : $*TreeB, case #TreeB.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] + // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]] : + // CHECK: switch_enum_addr [[TMP]] : $*TreeB, case #TreeB.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] // CHECK: [[NO]]: // CHECK: destroy_addr [[TMP]] // CHECK: [[YES]]: @@ -331,15 +413,15 @@ func guardTreeB(tree: TreeB) { // CHECK: [[L:%.*]] = alloc_stack $TreeB // CHECK: [[R:%.*]] = alloc_stack $TreeB - // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]]#1 - // CHECK: switch_enum_addr [[TMP]]#1 : $*TreeB, case #TreeB.Branch!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] + // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]] : + // CHECK: switch_enum_addr [[TMP]] : $*TreeB, case #TreeB.Branch!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] // CHECK: [[NO]]: // CHECK: destroy_addr [[TMP]] // CHECK: [[YES]]: // CHECK: [[BOX_ADDR:%.*]] = unchecked_take_enum_data_addr [[TMP]] // CHECK: [[BOX:%.*]] = load [[BOX_ADDR]] // CHECK: [[TUPLE_ADDR:%.*]] = project_box [[BOX]] - // CHECK: copy_addr [[TUPLE_ADDR]] to [initialization] [[TUPLE_COPY:%.*]]#1 + // CHECK: copy_addr [[TUPLE_ADDR]] to [initialization] [[TUPLE_COPY:%.*]] : // CHECK: [[L_COPY:%.*]] = tuple_element_addr [[TUPLE_COPY]] // CHECK: copy_addr [take] [[L_COPY]] to [initialization] [[L]] // CHECK: [[R_COPY:%.*]] = tuple_element_addr [[TUPLE_COPY]] @@ -353,8 +435,8 @@ func guardTreeB(tree: TreeB) { } do { - // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]]#1 - // CHECK: switch_enum_addr [[TMP]]#1 : $*TreeB, case #TreeB.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] + // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]] : + // CHECK: switch_enum_addr [[TMP]] : $*TreeB, case #TreeB.Nil!enumelt: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] // CHECK: [[NO]]: // CHECK: destroy_addr [[TMP]] // CHECK: [[YES]]: @@ -362,8 +444,8 @@ func guardTreeB(tree: TreeB) { if case .Nil = tree { } // CHECK: [[X:%.*]] = alloc_stack $T - // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]]#1 - // CHECK: switch_enum_addr [[TMP]]#1 : $*TreeB, case #TreeB.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] + // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]] : + // CHECK: switch_enum_addr [[TMP]] : $*TreeB, case #TreeB.Leaf!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] // CHECK: [[NO]]: // CHECK: destroy_addr [[TMP]] // CHECK: [[YES]]: @@ -375,15 +457,15 @@ func guardTreeB(tree: TreeB) { // CHECK: [[L:%.*]] = alloc_stack $TreeB // CHECK: [[R:%.*]] = alloc_stack $TreeB - // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]]#1 - // CHECK: switch_enum_addr [[TMP]]#1 : $*TreeB, case #TreeB.Branch!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] + // CHECK: copy_addr %0 to [initialization] [[TMP:%.*]] : + // CHECK: switch_enum_addr [[TMP]] : $*TreeB, case #TreeB.Branch!enumelt.1: [[YES:bb[0-9]+]], default [[NO:bb[0-9]+]] // CHECK: [[NO]]: // CHECK: destroy_addr [[TMP]] // CHECK: [[YES]]: // CHECK: [[BOX_ADDR:%.*]] = unchecked_take_enum_data_addr [[TMP]] // CHECK: [[BOX:%.*]] = load [[BOX_ADDR]] // CHECK: [[TUPLE_ADDR:%.*]] = project_box [[BOX]] - // CHECK: copy_addr [[TUPLE_ADDR]] to [initialization] [[TUPLE_COPY:%.*]]#1 + // CHECK: copy_addr [[TUPLE_ADDR]] to [initialization] [[TUPLE_COPY:%.*]] : // CHECK: [[L_COPY:%.*]] = tuple_element_addr [[TUPLE_COPY]] // CHECK: copy_addr [take] [[L_COPY]] to [initialization] [[L]] // CHECK: [[R_COPY:%.*]] = tuple_element_addr [[TUPLE_COPY]] diff --git a/test/SILGen/init_ref_delegation.swift b/test/SILGen/init_ref_delegation.swift index 7eaba444b6f12..039624f4d9b64 100644 --- a/test/SILGen/init_ref_delegation.swift +++ b/test/SILGen/init_ref_delegation.swift @@ -64,10 +64,10 @@ struct S2 { // CHECK: [[X_META:%[0-9]+]] = metatype $@thin X.Type // CHECK: [[X:%[0-9]+]] = apply [[X_INIT]]([[X_META]]) : $@convention(thin) (@thin X.Type) -> X // CHECK: [[X_BOX:%[0-9]+]] = alloc_stack $X - // CHECK: store [[X]] to [[X_BOX]]#1 : $*X - // CHECK: [[SELF_BOX1:%[0-9]+]] = apply [[S2_DELEG_INIT]]([[X_BOX]]#1, [[S2_META]]) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin S2.Type) -> S2 + // CHECK: store [[X]] to [[X_BOX]] : $*X + // CHECK: [[SELF_BOX1:%[0-9]+]] = apply [[S2_DELEG_INIT]]([[X_BOX]], [[S2_META]]) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin S2.Type) -> S2 // CHECK: assign [[SELF_BOX1]] to [[SELF]] : $*S2 - // CHECK: dealloc_stack [[X_BOX]]#0 : $*@local_storage X + // CHECK: dealloc_stack [[X_BOX]] : $*X // CHECK: [[SELF_BOX4:%[0-9]+]] = load [[SELF]] : $*S2 self.init(t: X()) // CHECK: strong_release [[SELF_BOX]]#0 : $@box S2 diff --git a/test/SILGen/lazy_global_access.swift b/test/SILGen/lazy_global_access.swift index 1a9e6f7395887..9c028835fe4f7 100644 --- a/test/SILGen/lazy_global_access.swift +++ b/test/SILGen/lazy_global_access.swift @@ -17,7 +17,7 @@ struct Fooo { // MAIN: function_ref @_TFV18lazy_global_access4Foooau10staticPropSi : $@convention(thin) () -> Builtin.RawPointer // LIBRARY: sil hidden @_TF18lazy_global_access8usePropsFT_TSiSi_ : $@convention(thin) () -> (Int, Int) { // LIBRARY: function_ref @_TF18lazy_global_accessau10globalPropSi : $@convention(thin) () -> Builtin.RawPointer -// LIRBARY: function_ref @_TFV18lazy_global_access4Foooau10staticPropSi : $@convention(thin) () -> Builtin.RawPointer +// LIBRARY: function_ref @_TFV18lazy_global_access4Foooau10staticPropSi : $@convention(thin) () -> Builtin.RawPointer func useProps() -> (Int, Int) { return (globalProp, Fooo.staticProp) } diff --git a/test/SILGen/let_decls.swift b/test/SILGen/let_decls.swift index 8e2d69c2b2903..67681ea9d2d64 100644 --- a/test/SILGen/let_decls.swift +++ b/test/SILGen/let_decls.swift @@ -94,8 +94,8 @@ func testAddressOnlyStructString(a : T) -> String { // CHECK: [[PRODFN:%[0-9]+]] = function_ref @{{.*}}produceAddressOnlyStruct // CHECK: [[TMPSTRUCT:%[0-9]+]] = alloc_stack $AddressOnlyStruct - // CHECK: apply [[PRODFN]]([[TMPSTRUCT]]#1, - // CHECK-NEXT: [[STRADDR:%[0-9]+]] = struct_element_addr [[TMPSTRUCT]]#1 : $*AddressOnlyStruct, #AddressOnlyStruct.str + // CHECK: apply [[PRODFN]]([[TMPSTRUCT]], + // CHECK-NEXT: [[STRADDR:%[0-9]+]] = struct_element_addr [[TMPSTRUCT]] : $*AddressOnlyStruct, #AddressOnlyStruct.str // CHECK-NEXT: [[STRVAL:%[0-9]+]] = load [[STRADDR]] // CHECK-NEXT: retain_value [[STRVAL]] // CHECK-NEXT: destroy_addr [[TMPSTRUCT]] @@ -109,8 +109,8 @@ func testAddressOnlyStructElt(a : T) -> T { // CHECK: [[PRODFN:%[0-9]+]] = function_ref @{{.*}}produceAddressOnlyStruct // CHECK: [[TMPSTRUCT:%[0-9]+]] = alloc_stack $AddressOnlyStruct - // CHECK: apply [[PRODFN]]([[TMPSTRUCT]]#1, - // CHECK-NEXT: [[ELTADDR:%[0-9]+]] = struct_element_addr [[TMPSTRUCT]]#1 : $*AddressOnlyStruct, #AddressOnlyStruct.elt + // CHECK: apply [[PRODFN]]([[TMPSTRUCT]], + // CHECK-NEXT: [[ELTADDR:%[0-9]+]] = struct_element_addr [[TMPSTRUCT]] : $*AddressOnlyStruct, #AddressOnlyStruct.elt // CHECK-NEXT: copy_addr [[ELTADDR]] to [initialization] %0 : $*T // CHECK-NEXT: destroy_addr [[TMPSTRUCT]] } @@ -152,7 +152,7 @@ func testGetOnlySubscript(x : GetOnlySubscriptStruct, idx : Int) -> Int { extension Optional { func getLV() -> Int { } } -struct CloseOverAddressOnlyConstant { +struct CloseOverAddressOnlyConstant { func isError() { let AOV = Optional() takeClosure({ AOV.getLV() }) @@ -315,11 +315,11 @@ func testLetArchetypeBases(p : T) { // CHECK-LABEL: sil hidden @{{.*}}testDebugValue // CHECK: bb0(%0 : $Int, %1 : $*SimpleProtocol): -// CHECK-NEXT: debug_value %0 : $Int // let a -// CHECK-NEXT: debug_value_addr %1 : $*SimpleProtocol // let b +// CHECK-NEXT: debug_value %0 : $Int, let, name "a" +// CHECK-NEXT: debug_value_addr %1 : $*SimpleProtocol, let, name "b" func testDebugValue(a : Int, b : SimpleProtocol) -> Int { - // CHECK-NEXT: debug_value %0 : $Int // let x + // CHECK-NEXT: debug_value %0 : $Int, let, name "x" let x = a // CHECK: apply @@ -335,14 +335,14 @@ func testDebugValue(a : Int, b : SimpleProtocol) -> Int { // CHECK-LABEL: sil hidden @{{.*}}testAddressOnlyTupleArgument func testAddressOnlyTupleArgument(bounds: (start: SimpleProtocol, pastEnd: Int)) { // CHECK: bb0(%0 : $*SimpleProtocol, %1 : $Int): -// CHECK-NEXT: %2 = alloc_stack $(start: SimpleProtocol, pastEnd: Int) // let bounds -// CHECK-NEXT: %3 = tuple_element_addr %2#1 : $*(start: SimpleProtocol, pastEnd: Int), 0 +// CHECK-NEXT: %2 = alloc_stack $(start: SimpleProtocol, pastEnd: Int), let, name "bounds" +// CHECK-NEXT: %3 = tuple_element_addr %2 : $*(start: SimpleProtocol, pastEnd: Int), 0 // CHECK-NEXT: copy_addr [take] %0 to [initialization] %3 : $*SimpleProtocol -// CHECK-NEXT: %5 = tuple_element_addr %2#1 : $*(start: SimpleProtocol, pastEnd: Int), 1 +// CHECK-NEXT: %5 = tuple_element_addr %2 : $*(start: SimpleProtocol, pastEnd: Int), 1 // CHECK-NEXT: store %1 to %5 : $*Int // CHECK-NEXT: debug_value_addr %2 -// CHECK-NEXT: destroy_addr %2#1 : $*(start: SimpleProtocol, pastEnd: Int) -// CHECK-NEXT: dealloc_stack %2#0 : $*@local_storage (start: SimpleProtocol, pastEnd: Int) +// CHECK-NEXT: destroy_addr %2 : $*(start: SimpleProtocol, pastEnd: Int) +// CHECK-NEXT: dealloc_stack %2 : $*(start: SimpleProtocol, pastEnd: Int) } @@ -389,7 +389,7 @@ struct StructMemberTest { } // CHECK-LABEL: sil hidden @{{.*}}testIntMemberLoad{{.*}} : $@convention(method) (@guaranteed StructMemberTest) // CHECK: bb0(%0 : $StructMemberTest): - // CHECK: debug_value %0 : $StructMemberTest // let self + // CHECK: debug_value %0 : $StructMemberTest, let, name "self" // CHECK: %2 = struct_extract %0 : $StructMemberTest, #StructMemberTest.i // CHECK-NOT: release_value %0 : $StructMemberTest // CHECK: return %2 : $Int @@ -400,7 +400,7 @@ struct StructMemberTest { } // CHECK-LABEL: sil hidden @{{.*}}testRecursiveIntMemberLoad{{.*}} : $@convention(method) (@guaranteed StructMemberTest) // CHECK: bb0(%0 : $StructMemberTest): - // CHECK: debug_value %0 : $StructMemberTest // let self + // CHECK: debug_value %0 : $StructMemberTest, let, name "self" // CHECK: %2 = struct_extract %0 : $StructMemberTest, #StructMemberTest.s // CHECK: %3 = struct_extract %2 : $AnotherStruct, #AnotherStruct.i // CHECK-NOT: release_value %0 : $StructMemberTest @@ -411,7 +411,7 @@ struct StructMemberTest { } // CHECK-LABEL: sil hidden @{{.*}}testTupleMemberLoad{{.*}} : $@convention(method) (@guaranteed StructMemberTest) // CHECK: bb0(%0 : $StructMemberTest): - // CHECK-NEXT: debug_value %0 : $StructMemberTest // let self + // CHECK-NEXT: debug_value %0 : $StructMemberTest, let, name "self" // CHECK-NEXT: [[T0:%.*]] = struct_extract %0 : $StructMemberTest, #StructMemberTest.t // CHECK-NEXT: [[T1:%.*]] = tuple_extract [[T0]] : $(Int, AnotherStruct), 0 // CHECK-NEXT: [[T2:%.*]] = tuple_extract [[T0]] : $(Int, AnotherStruct), 1 @@ -429,7 +429,7 @@ struct GenericStruct { } // CHECK-LABEL: sil hidden @{{.*}}GenericStruct4getA{{.*}} : $@convention(method) (@out T, @in_guaranteed GenericStruct) // CHECK: bb0(%0 : $*T, %1 : $*GenericStruct): - // CHECK-NEXT: debug_value_addr %1 : $*GenericStruct // let self + // CHECK-NEXT: debug_value_addr %1 : $*GenericStruct, let, name "self" // CHECK-NEXT: %3 = struct_element_addr %1 : $*GenericStruct, #GenericStruct.a // CHECK-NEXT: copy_addr %3 to [initialization] %0 : $*T // CHECK-NEXT: %5 = tuple () @@ -441,7 +441,7 @@ struct GenericStruct { // CHECK-LABEL: sil hidden @{{.*}}GenericStruct4getB{{.*}} : $@convention(method) (@in_guaranteed GenericStruct) -> Int // CHECK: bb0(%0 : $*GenericStruct): - // CHECK-NEXT: debug_value_addr %0 : $*GenericStruct // let self + // CHECK-NEXT: debug_value_addr %0 : $*GenericStruct, let, name "self" // CHECK-NEXT: %2 = struct_element_addr %0 : $*GenericStruct, #GenericStruct.b // CHECK-NEXT: %3 = load %2 : $*Int // CHECK-NOT: destroy_addr %0 : $*GenericStruct @@ -497,8 +497,8 @@ struct LetDeclInStruct { func test_unassigned_let_constant() { let string : String } -// CHECK: [[S:%[0-9]+]] = alloc_stack $String // let string -// CHECK-NEXT: [[MUI:%[0-9]+]] = mark_uninitialized [var] [[S]]#1 : $*String +// CHECK: [[S:%[0-9]+]] = alloc_stack $String, let, name "string" +// CHECK-NEXT: [[MUI:%[0-9]+]] = mark_uninitialized [var] [[S]] : $*String // CHECK-NEXT: destroy_addr [[MUI]] : $*String -// CHECK-NEXT: dealloc_stack [[S]]#0 : $*@local_storage String +// CHECK-NEXT: dealloc_stack [[S]] : $*String diff --git a/test/SILGen/lifetime.swift b/test/SILGen/lifetime.swift index a4c537c3ef1dd..a7361366886a4 100644 --- a/test/SILGen/lifetime.swift +++ b/test/SILGen/lifetime.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -parse-as-library -emit-silgen -primary-file %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -parse-as-library -emit-silgen -primary-file %s | FileCheck %s struct Buh { var x: Int { @@ -354,7 +354,7 @@ func logical_lvalue_lifetime(r: RefWithProp, _ i: Int, _ v: Val) { r.int_prop = i // CHECK: [[R1:%[0-9]+]] = load [[RADDR]] // CHECK: strong_retain [[R1]] - // CHECK: [[SETTER_METHOD:%[0-9]+]] = class_method {{.*}} : $RefWithProp, #RefWithProp.int_prop!setter.1 : RefWithProp -> (Int) -> () , $@convention(method) (Int, @guaranteed RefWithProp) -> () + // CHECK: [[SETTER_METHOD:%[0-9]+]] = class_method {{.*}} : $RefWithProp, #RefWithProp.int_prop!setter.1 : (RefWithProp) -> (Int) -> () , $@convention(method) (Int, @guaranteed RefWithProp) -> () // CHECK: apply [[SETTER_METHOD]]({{.*}}, [[R1]]) // CHECK: strong_release [[R1]] @@ -363,17 +363,17 @@ func logical_lvalue_lifetime(r: RefWithProp, _ i: Int, _ v: Val) { // CHECK: strong_retain [[R2]] // CHECK: [[STORAGE:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer // CHECK: [[ALEPH_PROP_TEMP:%[0-9]+]] = alloc_stack $Aleph - // CHECK: [[T0:%.*]] = address_to_pointer [[ALEPH_PROP_TEMP]]#1 + // CHECK: [[T0:%.*]] = address_to_pointer [[ALEPH_PROP_TEMP]] // CHECK: [[MATERIALIZE_METHOD:%[0-9]+]] = class_method {{.*}} : $RefWithProp, #RefWithProp.aleph_prop!materializeForSet.1 : - // CHECK: [[MATERIALIZE:%.*]] = apply [[MATERIALIZE_METHOD]]([[T0]], [[STORAGE]]#1, [[R2]]) + // CHECK: [[MATERIALIZE:%.*]] = apply [[MATERIALIZE_METHOD]]([[T0]], [[STORAGE]], [[R2]]) // CHECK: [[PTR:%.*]] = tuple_extract [[MATERIALIZE]] : {{.*}}, 0 // CHECK: [[ADDR:%.*]] = pointer_to_address [[PTR]] // CHECK: [[OPTCALLBACK:%.*]] = tuple_extract [[MATERIALIZE]] : {{.*}}, 1 // CHECK: [[MARKED_ADDR:%.*]] = mark_dependence [[ADDR]] : $*Aleph on [[R2]] // CHECK: {{.*}}([[CALLBACK:%.*]] : // CHECK: [[TEMP:%.*]] = alloc_stack $RefWithProp - // CHECK: store [[R2]] to [[TEMP]]#1 - // CHECK: apply [[CALLBACK]]({{.*}}, [[STORAGE]]#1, [[TEMP]]#1, {{%.*}}) + // CHECK: store [[R2]] to [[TEMP]] + // CHECK: apply [[CALLBACK]]({{.*}}, [[STORAGE]], [[TEMP]], {{%.*}}) } func bar() -> Int {} @@ -624,7 +624,7 @@ class D : B { super.init(y: y) // CHECK: [[THIS1:%[0-9]+]] = load [[THISADDR]] // CHECK: [[THIS1_SUP:%[0-9]+]] = upcast [[THIS1]] : ${{.*}} to $B - // CHECK: [[SUPER_CTOR:%[0-9]+]] = function_ref @_TFC8lifetime1Bc{{.*}} + // CHECK: [[SUPER_CTOR:%[0-9]+]] = super_method %12 : $D, #B.init!initializer.1 // CHECK: [[Y:%[0-9]+]] = load [[YADDR]] // CHECK: [[THIS2_SUP:%[0-9]+]] = apply [[SUPER_CTOR]]([[Y]], [[THIS1_SUP]]) // CHECK: [[THIS2:%[0-9]+]] = unchecked_ref_cast [[THIS2_SUP]] : $B to $D diff --git a/test/SILGen/lifetime_unions.swift b/test/SILGen/lifetime_unions.swift index bcf37def5ff30..c2442c0ac0e40 100644 --- a/test/SILGen/lifetime_unions.swift +++ b/test/SILGen/lifetime_unions.swift @@ -69,9 +69,9 @@ func destroyUnionRValues() { // C/HECK: [[GET_ADDRESS_ONLY_UNION:%.*]] = function_ref @_TF15lifetime_unions19getAddressOnlyUnionU__FMQ_GOS_16AddressOnlyUnionQ__ : $@convention(thin) T.Type -> AddressOnlyUnion // C/HECK: [[GET_ADDRESS_ONLY_UNION_SPEC:%.*]] = specialize [[GET_ADDRESS_ONLY_UNION]] : $@convention(thin) T.Type -> AddressOnlyUnion, $@thin Int64.Type -> AddressOnlyUnion, T = Int // C/HECK: [[ADDRESS_ONLY_UNION_ADDR:%.*]] = alloc_stack $AddressOnlyUnion - // C/HECK: apply [[GET_ADDRESS_ONLY_UNION_SPEC]]([[ADDRESS_ONLY_UNION_ADDR]]#1, {{%.*}}) : $@thin Int64.Type -> AddressOnlyUnion - // C/HECK: destroy_addr [[ADDRESS_ONLY_UNION_ADDR]]#1 : $*AddressOnlyUnion - // C/HECK: dealloc_stack [[ADDRESS_ONLY_UNION_ADDR]]#0 : $*@local_storage AddressOnlyUnion + // C/HECK: apply [[GET_ADDRESS_ONLY_UNION_SPEC]]([[ADDRESS_ONLY_UNION_ADDR]], {{%.*}}) : $@thin Int64.Type -> AddressOnlyUnion + // C/HECK: destroy_addr [[ADDRESS_ONLY_UNION_ADDR]] : $*AddressOnlyUnion + // C/HECK: dealloc_stack [[ADDRESS_ONLY_UNION_ADDR]] : $*AddressOnlyUnion getAddressOnlyUnion(Int) */ } diff --git a/test/SILGen/mangling.swift b/test/SILGen/mangling.swift index 46388196e01d6..a9a167a81caed 100644 --- a/test/SILGen/mangling.swift +++ b/test/SILGen/mangling.swift @@ -97,12 +97,14 @@ func uses_clang_struct(r r: NSRect) {} func uses_optionals(x x: Int?) -> UnicodeScalar? { return Optional() } enum GenericUnion { - // CHECK-LABEL: sil hidden [transparent] @_TFO8mangling12GenericUnion3FoourfMGS0_x_FSiGS0_x_ + // CHECK-LABEL: sil shared [transparent] @_TFO8mangling12GenericUnion3FoourfMGS0_x_FSiGS0_x_ case Foo(Int) - // CHECK-LABEL: sil hidden [transparent] @_TFO8mangling12GenericUnion3BarurFMGS0_x_GS0_x_ - case Bar } - + +func instantiateGenericUnionConstructor(t: T) { + _ = GenericUnion.Foo +} + struct HasVarInit { static var state = true && false } diff --git a/test/SILGen/materializeForSet.swift b/test/SILGen/materializeForSet.swift index cfaf33b52d289..2239b23ed803b 100644 --- a/test/SILGen/materializeForSet.swift +++ b/test/SILGen/materializeForSet.swift @@ -47,8 +47,8 @@ class Base { // CHECK: bb0([[BUFFER:%.*]] : $Builtin.RawPointer, [[STORAGE:%.*]] : $*Builtin.UnsafeValueBuffer, [[SELF:%.*]] : $Base): // CHECK: [[T0:%.*]] = ref_element_addr [[SELF]] : $Base, #Base.stored // CHECK: [[T1:%.*]] = address_to_pointer [[T0]] : $*Int to $Builtin.RawPointer -// CHECK: inject_enum_addr [[TMP:%.*]]#1 : $*Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Base, @thick Base.Type) -> ()>, #Optional.None -// CHECK: [[T2:%.*]] = load [[TMP]]#1 +// CHECK: inject_enum_addr [[TMP:%.*]] : $*Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Base, @thick Base.Type) -> ()>, #Optional.None +// CHECK: [[T2:%.*]] = load [[TMP]] // CHECK: [[T3:%.*]] = tuple ([[T1]] : $Builtin.RawPointer, [[T2]] : $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Base, @thick Base.Type) -> ()>) // CHECK: return [[T3]] : $(Builtin.RawPointer, Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Base, @thick Base.Type) -> ()>) // CHECK: } @@ -112,7 +112,7 @@ extension Derived : Abstractable {} // SILGEN-NEXT: function_ref // SILGEN-NEXT: [[REABSTRACTOR:%.*]] = function_ref @_TTRXFo__iSi_XFo__dSi_ : $@convention(thin) (@owned @callee_owned (@out Int) -> ()) -> Int // SILGEN-NEXT: [[NEWVALUE:%.*]] = partial_apply [[REABSTRACTOR]]([[VALUE]]) -// SILGEN-NEXT: [[FN:%.*]] = class_method [[SELF]] : $Base, #Base.storedFunction!setter.1 : Base -> (() -> Int) -> () +// SILGEN-NEXT: [[FN:%.*]] = class_method [[SELF]] : $Base, #Base.storedFunction!setter.1 : (Base) -> (() -> Int) -> () // SILGEN-NEXT: apply [[FN]]([[NEWVALUE]], [[SELF]]) // SILGEN-NEXT: tuple () // SILGEN-NEXT: return @@ -247,17 +247,17 @@ func improveWizard(inout wizard: Wizard) { // SILGEN-NEXT: function_ref // SILGEN-NEXT: [[GETTER:%.*]] = function_ref @_TFE17materializeForSetPS_5Magicg5hocusSi // SILGEN-NEXT: [[WTEMP:%.*]] = alloc_stack $Wizard -// SILGEN-NEXT: store [[T0]] to [[WTEMP]]#1 -// SILGEN-NEXT: [[T0:%.*]] = apply [[GETTER]]([[WTEMP]]#1) -// SILGEN-NEXT: store [[T0]] to [[TEMP]]#1 +// SILGEN-NEXT: store [[T0]] to [[WTEMP]] +// SILGEN-NEXT: [[T0:%.*]] = apply [[GETTER]]([[WTEMP]]) +// SILGEN-NEXT: store [[T0]] to [[TEMP]] // Call improve. -// SILGEN-NEXT: apply [[IMPROVE]]([[TEMP]]#1) -// SILGEN-NEXT: [[T0:%.*]] = load [[TEMP]]#1 +// SILGEN-NEXT: apply [[IMPROVE]]([[TEMP]]) +// SILGEN-NEXT: [[T0:%.*]] = load [[TEMP]] // SILGEN-NEXT: function_ref // SILGEN-NEXT: [[SETTER:%.*]] = function_ref @_TFE17materializeForSetPS_5Magics5hocusSi // SILGEN-NEXT: apply [[SETTER]]([[T0]], [[WIZARD]]) -// SILGEN-NEXT: dealloc_stack [[WTEMP]]#0 -// SILGEN-NEXT: dealloc_stack [[TEMP]]#0 +// SILGEN-NEXT: dealloc_stack [[WTEMP]] +// SILGEN-NEXT: dealloc_stack [[TEMP]] protocol Totalled { var total: Int { get set } @@ -277,8 +277,8 @@ struct Bill : Totalled { // SILGEN: [[INIT:%.*]] = function_ref @_TFSqC // SILGEN: [[META:%.*]] = metatype $@thin Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Bill, @thick Bill.Type) -> ()>.Type // SILGEN: [[T2:%.*]] = alloc_stack $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Bill, @thick Bill.Type) -> ()> -// SILGEN: [[OPT:%.*]] = apply [[INIT]]<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Bill, @thick Bill.Type) -> ()>([[T2]]#1, [[META]]) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @thin Optional<τ_0_0>.Type) -> () -// SILGEN: [[T3:%.*]] = load [[T2]]#1 +// SILGEN: [[OPT:%.*]] = apply [[INIT]]<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Bill, @thick Bill.Type) -> ()>([[T2]], [[META]]) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @thin Optional<τ_0_0>.Type) -> () +// SILGEN: [[T3:%.*]] = load [[T2]] // SILGEN: [[T4:%.*]] = tuple ([[T1]] : $Builtin.RawPointer, [[T3]] : $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Bill, @thick Bill.Type) -> ()>) // SILGEN: return [[T4]] : $(Builtin.RawPointer, Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Bill, @thick Bill.Type) -> ()>) // SILGEN: } diff --git a/test/SILGen/metatype_abstraction.swift b/test/SILGen/metatype_abstraction.swift index 68f49d5a27aa2..987f151c6d5f7 100644 --- a/test/SILGen/metatype_abstraction.swift +++ b/test/SILGen/metatype_abstraction.swift @@ -42,7 +42,7 @@ func staticMetatypeFromGeneric(x: Generic) -> S.Type { // CHECK: [[META:%.*]] = load [[ADDR]] : $*@thick T.Type // CHECK: return [[META]] : $@thick T.Type // CHECK: } -func genericMetatypeFromGenericMetatype(x: GenericMetatype)-> T.Type { +func genericMetatypeFromGenericMetatype(x: GenericMetatype) -> T.Type { var x = x return x.value } @@ -69,8 +69,8 @@ func takeGenericMetatype(x: T.Type) {} // CHECK-LABEL: sil hidden @_TF20metatype_abstraction23staticMetatypeToGeneric // CHECK: [[MAT:%.*]] = alloc_stack $@thick S.Type // CHECK: [[META:%.*]] = metatype $@thick S.Type -// CHECK: store [[META]] to [[MAT]]#1 : $*@thick S.Type -// CHECK: apply {{%.*}}([[MAT]]#1) +// CHECK: store [[META]] to [[MAT]] : $*@thick S.Type +// CHECK: apply {{%.*}}([[MAT]]) func staticMetatypeToGeneric(x: S.Type) { takeGeneric(x) } @@ -82,7 +82,7 @@ func staticMetatypeToGenericMetatype(x: S.Type) { } // CHECK-LABEL: sil hidden @_TF20metatype_abstraction24dynamicMetatypeToGeneric // CHECK: [[MAT:%.*]] = alloc_stack $@thick C.Type -// CHECK: apply {{%.*}}([[MAT]]#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () +// CHECK: apply {{%.*}}([[MAT]]) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () func dynamicMetatypeToGeneric(x: C.Type) { var x = x takeGeneric(x) @@ -96,7 +96,7 @@ func dynamicMetatypeToGenericMetatype(x: C.Type) { } // CHECK-LABEL: sil hidden @_TF20metatype_abstraction24genericMetatypeToGeneric // CHECK: [[MAT:%.*]] = alloc_stack $@thick U.Type -// CHECK: apply {{%.*}}([[MAT]]#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () +// CHECK: apply {{%.*}}([[MAT]]) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () func genericMetatypeToGeneric(x: U.Type) { var x = x takeGeneric(x) diff --git a/test/SILGen/metatypes.swift b/test/SILGen/metatypes.swift index d581a5aa8408c..08966efd16a4d 100644 --- a/test/SILGen/metatypes.swift +++ b/test/SILGen/metatypes.swift @@ -90,7 +90,7 @@ func existential_metatype_from_thin() -> Any.Type { // CHECK: [[T0:%.*]] = function_ref @_TFV9metatypes10SomeStructC // CHECK-NEXT: [[T1:%.*]] = metatype $@thin SomeStruct.Type // CHECK-NEXT: [[T2:%.*]] = apply [[T0]]([[T1]]) -// CHECK-NEXT: debug_value [[T2]] : $SomeStruct // let s +// CHECK-NEXT: debug_value [[T2]] : $SomeStruct, let, name "s" // CHECK-NEXT: [[T0:%.*]] = metatype $@thin SomeStruct.Type // CHECK-NEXT: [[T1:%.*]] = metatype $@thick SomeStruct.Type // CHECK-NEXT: [[T2:%.*]] = init_existential_metatype [[T1]] : $@thick SomeStruct.Type, $@thick Any.Type diff --git a/test/SILGen/multi_file.swift b/test/SILGen/multi_file.swift index 4c335686081cb..244699ec88f13 100644 --- a/test/SILGen/multi_file.swift +++ b/test/SILGen/multi_file.swift @@ -18,7 +18,7 @@ func lazyPropertiesAreNotStored(container: LazyContainer) { // CHECK-LABEL: sil hidden @_TF10multi_file29lazyRefPropertiesAreNotStored func lazyRefPropertiesAreNotStored(container: LazyContainerClass) { - // CHECK: {{%[0-9]+}} = class_method %0 : $LazyContainerClass, #LazyContainerClass.lazyVar!getter.1 : LazyContainerClass -> () -> Int , $@convention(method) (@guaranteed LazyContainerClass) -> Int + // CHECK: {{%[0-9]+}} = class_method %0 : $LazyContainerClass, #LazyContainerClass.lazyVar!getter.1 : (LazyContainerClass) -> () -> Int , $@convention(method) (@guaranteed LazyContainerClass) -> Int markUsed(container.lazyVar) } @@ -33,7 +33,7 @@ func finalVarsAreDevirtualized(obj: FinalPropertyClass) { // rdar://18448869 // CHECK-LABEL: sil hidden @_TF10multi_file34finalVarsDontNeedMaterializeForSetFCS_27ObservingPropertyFinalClassT_ func finalVarsDontNeedMaterializeForSet(obj: ObservingPropertyFinalClass) { - obj.foo++ + obj.foo += 1 // CHECK: function_ref @_TFC10multi_file27ObservingPropertyFinalClassg3fooSi // CHECK: function_ref @_TFC10multi_file27ObservingPropertyFinalClasss3fooSi } diff --git a/test/SILGen/objc_attr_NSManaged.swift b/test/SILGen/objc_attr_NSManaged.swift index 0482683112b66..7df9f56eef098 100644 --- a/test/SILGen/objc_attr_NSManaged.swift +++ b/test/SILGen/objc_attr_NSManaged.swift @@ -23,10 +23,10 @@ class SwiftGizmo : Gizmo { // Make sure that we're calling through the @objc entry points. // CHECK-LABEL: sil hidden @_TFC19objc_attr_NSManaged10SwiftGizmo7modifyX{{.*}} : $@convention(method) (@guaranteed SwiftGizmo) -> () { func modifyX() { - // CHECK: [[GETTER:%[0-9]+]] = class_method [volatile] [[SELF:%.*]] : $SwiftGizmo, #SwiftGizmo.x!getter.1.foreign : SwiftGizmo -> () -> X , $@convention(objc_method) (SwiftGizmo) -> @autoreleased X + // CHECK: [[GETTER:%[0-9]+]] = class_method [volatile] [[SELF:%.*]] : $SwiftGizmo, #SwiftGizmo.x!getter.1.foreign : (SwiftGizmo) -> () -> X , $@convention(objc_method) (SwiftGizmo) -> @autoreleased X // CHECK-NEXT: apply [[GETTER]]([[SELF]]) : $@convention(objc_method) (SwiftGizmo) -> @autoreleased X // CHECK-NOT: return - // CHECK: [[SETTER:%[0-9]+]] = class_method [volatile] [[SELF]] : $SwiftGizmo, #SwiftGizmo.x!setter.1.foreign : SwiftGizmo -> (X) -> () , $@convention(objc_method) (X, SwiftGizmo) -> () + // CHECK: [[SETTER:%[0-9]+]] = class_method [volatile] [[SELF]] : $SwiftGizmo, #SwiftGizmo.x!setter.1.foreign : (SwiftGizmo) -> (X) -> () , $@convention(objc_method) (X, SwiftGizmo) -> () // CHECK: apply [[SETTER]]([[XMOD:%.*]], [[SELF]]) : $@convention(objc_method) (X, SwiftGizmo) -> () x = x.foo() // CHECK: return @@ -34,7 +34,7 @@ class SwiftGizmo : Gizmo { // CHECK-LABEL: sil hidden @_TFC19objc_attr_NSManaged10SwiftGizmo8testFunc func testFunc() { - // CHECK: = class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.kvc!1.foreign : SwiftGizmo -> () -> () , $@convention(objc_method) (SwiftGizmo) -> () + // CHECK: = class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.kvc!1.foreign : (SwiftGizmo) -> () -> () , $@convention(objc_method) (SwiftGizmo) -> () // CHECK: return kvc() } @@ -45,7 +45,7 @@ extension SwiftGizmo { // CHECK-LABEL: _TFC19objc_attr_NSManaged10SwiftGizmo7testExt func testExt() { - // CHECK: = class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.extKVC!1.foreign : SwiftGizmo -> () -> () , $@convention(objc_method) (SwiftGizmo) -> () + // CHECK: = class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.extKVC!1.foreign : (SwiftGizmo) -> () -> () , $@convention(objc_method) (SwiftGizmo) -> () // CHECK: return extKVC() } @@ -62,7 +62,7 @@ extension FinalGizmo { // CHECK-LABEL: _TFC19objc_attr_NSManaged10FinalGizmo8testExt2 func testExt2() { - // CHECK: = class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.extKVC2!1.foreign : FinalGizmo -> () -> () , $@convention(objc_method) (FinalGizmo) -> () + // CHECK: = class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.extKVC2!1.foreign : (FinalGizmo) -> () -> () , $@convention(objc_method) (FinalGizmo) -> () // CHECK: return extKVC2() } @@ -70,9 +70,9 @@ extension FinalGizmo { // CHECK-LABEL: sil hidden @_TF19objc_attr_NSManaged9testFinalFCS_10FinalGizmoSS : $@convention(thin) (@owned FinalGizmo) -> @owned String { func testFinal(obj: FinalGizmo) -> String { - // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.kvc2!1.foreign : FinalGizmo -> () -> () , $@convention(objc_method) (FinalGizmo) -> () + // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.kvc2!1.foreign : (FinalGizmo) -> () -> () , $@convention(objc_method) (FinalGizmo) -> () // CHECK-NOT: return - // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.y!getter.1.foreign : FinalGizmo -> () -> String , $@convention(objc_method) (FinalGizmo) -> @autoreleased NSString + // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.y!getter.1.foreign : (FinalGizmo) -> () -> String , $@convention(objc_method) (FinalGizmo) -> @autoreleased NSString // CHECK: return obj.kvc2() return obj.y diff --git a/test/SILGen/objc_attr_NSManaged_multi.swift b/test/SILGen/objc_attr_NSManaged_multi.swift index 110bb281d41e1..b8263de53655f 100644 --- a/test/SILGen/objc_attr_NSManaged_multi.swift +++ b/test/SILGen/objc_attr_NSManaged_multi.swift @@ -6,11 +6,11 @@ import Foundation // CHECK-LABEL: sil hidden @_TF25objc_attr_NSManaged_multi9testMultiFCS_10SwiftGizmoPs9AnyObject_ : $@convention(thin) (@owned SwiftGizmo) -> @owned AnyObject { func testMulti(obj: SwiftGizmo) -> AnyObject { - // CHECK: = class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.kvc!1.foreign : SwiftGizmo -> () -> () , $@convention(objc_method) (SwiftGizmo) -> () + // CHECK: = class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.kvc!1.foreign : (SwiftGizmo) -> () -> () , $@convention(objc_method) (SwiftGizmo) -> () // CHECK-NOT: return - // CHECK: = class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.extKVC!1.foreign : SwiftGizmo -> () -> () , $@convention(objc_method) (SwiftGizmo) -> () + // CHECK: = class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.extKVC!1.foreign : (SwiftGizmo) -> () -> () , $@convention(objc_method) (SwiftGizmo) -> () // CHECK-NOT: return - // CHECK: class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.x!getter.1.foreign : SwiftGizmo -> () -> X , $@convention(objc_method) (SwiftGizmo) -> @autoreleased X + // CHECK: class_method [volatile] %0 : $SwiftGizmo, #SwiftGizmo.x!getter.1.foreign : (SwiftGizmo) -> () -> X , $@convention(objc_method) (SwiftGizmo) -> @autoreleased X // CHECK: return obj.kvc() obj.extKVC() @@ -19,11 +19,11 @@ func testMulti(obj: SwiftGizmo) -> AnyObject { // CHECK-LABEL: sil hidden @_TF25objc_attr_NSManaged_multi14testFinalMultiFCS_10FinalGizmoSS : $@convention(thin) (@owned FinalGizmo) -> @owned String { func testFinalMulti(obj: FinalGizmo) -> String { - // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.kvc2!1.foreign : FinalGizmo -> () -> () , $@convention(objc_method) (FinalGizmo) -> () + // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.kvc2!1.foreign : (FinalGizmo) -> () -> () , $@convention(objc_method) (FinalGizmo) -> () // CHECK-NOT: return - // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.extKVC2!1.foreign : FinalGizmo -> () -> () , $@convention(objc_method) (FinalGizmo) -> () + // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.extKVC2!1.foreign : (FinalGizmo) -> () -> () , $@convention(objc_method) (FinalGizmo) -> () // CHECK-NOT: return - // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.y!getter.1.foreign : FinalGizmo -> () -> String , $@convention(objc_method) (FinalGizmo) -> @autoreleased NSString + // CHECK: class_method [volatile] %0 : $FinalGizmo, #FinalGizmo.y!getter.1.foreign : (FinalGizmo) -> () -> String , $@convention(objc_method) (FinalGizmo) -> @autoreleased NSString // CHECK: return obj.kvc2() obj.extKVC2() diff --git a/test/SILGen/objc_blocks_bridging.swift b/test/SILGen/objc_blocks_bridging.swift index 38550ab9dbca4..1283048f2eaf0 100644 --- a/test/SILGen/objc_blocks_bridging.swift +++ b/test/SILGen/objc_blocks_bridging.swift @@ -73,10 +73,10 @@ func callBlocks(x: Foo, ) -> (Int, String, String?, String?) { // CHECK: [[FOO:%.*]] = class_method [volatile] %0 : $Foo, #Foo.foo!1.foreign // CHECK: [[F_BLOCK_STORAGE:%.*]] = alloc_stack $@block_storage - // CHECK: [[F_BLOCK_CAPTURE:%.*]] = project_block_storage [[F_BLOCK_STORAGE]]#1 + // CHECK: [[F_BLOCK_CAPTURE:%.*]] = project_block_storage [[F_BLOCK_STORAGE]] // CHECK: store %1 to [[F_BLOCK_CAPTURE]] // CHECK: [[F_BLOCK_INVOKE:%.*]] = function_ref @_TTRXFo_dSi_dSi_XFdCb_dSi_dSi_ - // CHECK: [[F_STACK_BLOCK:%.*]] = init_block_storage_header [[F_BLOCK_STORAGE]]#1 : {{.*}}, invoke [[F_BLOCK_INVOKE]] + // CHECK: [[F_STACK_BLOCK:%.*]] = init_block_storage_header [[F_BLOCK_STORAGE]] : {{.*}}, invoke [[F_BLOCK_INVOKE]] // CHECK: [[F_BLOCK:%.*]] = copy_block [[F_STACK_BLOCK]] // CHECK: apply [[FOO]]([[F_BLOCK]] @@ -115,14 +115,14 @@ func clearDraggingItemImageComponentsProvider(x: NSDraggingItem) { // CHECK: [[CONVERT:%.*]] = function_ref @_TF10Foundation22_convertArrayToNSArray // CHECK: [[CONVERTED:%.*]] = apply [[CONVERT]] // CHECK: [[OPTIONAL:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[CONVERTED]] -// CHECK: autorelease_return [[OPTIONAL]] +// CHECK: return [[OPTIONAL]] // CHECK-LABEL: sil hidden @{{.*}}bridgeNonnullBlockResult{{.*}} // CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo__oSS_XFdCb__aGSqCSo8NSString__ // CHECK: [[CONVERT:%.*]] = function_ref @swift_StringToNSString // CHECK: [[BRIDGED:%.*]] = apply [[CONVERT]] // CHECK: [[OPTIONAL_BRIDGED:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[BRIDGED]] -// CHECK: autorelease_return [[OPTIONAL_BRIDGED]] +// CHECK: return [[OPTIONAL_BRIDGED]] func bridgeNonnullBlockResult() { nonnullStringBlockResult { return "test" } } diff --git a/test/SILGen/objc_bridged_results.swift b/test/SILGen/objc_bridged_results.swift index c95f8e0e574ba..9d18a663651d2 100644 --- a/test/SILGen/objc_bridged_results.swift +++ b/test/SILGen/objc_bridged_results.swift @@ -8,7 +8,6 @@ import Foundation func testNonnull(obj: Test) -> [AnyObject] { // CHECK: [[METHOD:%[0-9]+]] = class_method [volatile] %0 : $Test, #Test.nonnullArray!getter.1.foreign : Test -> () -> [AnyObject] , $@convention(objc_method) (Test) -> @autoreleased Optional // CHECK: [[COCOA_VAL:%[0-9]+]] = apply [[METHOD]](%0) : $@convention(objc_method) (Test) -> @autoreleased Optional - // CHECK: strong_retain_autoreleased [[COCOA_VAL]] // CHECK: [[CONVERT:%[0-9]+]] = function_ref @_TF10Foundation22_convertNSArrayToArray // CHECK: [[RESULT:%[0-9]+]] = apply [[CONVERT]]([[COCOA_VAL]]) : $@convention(thin) <τ_0_0> (@owned Optional) -> @owned Array<τ_0_0> // CHECK: strong_release %0 : $Test @@ -20,7 +19,6 @@ func testNonnull(obj: Test) -> [AnyObject] { func testNullable(obj: Test) -> [AnyObject]? { // CHECK: [[METHOD:%[0-9]+]] = class_method [volatile] %0 : $Test, #Test.nullableArray!getter.1.foreign : Test -> () -> [AnyObject]? , $@convention(objc_method) (Test) -> @autoreleased Optional // CHECK: [[COCOA_VAL:%[0-9]+]] = apply [[METHOD]](%0) : $@convention(objc_method) (Test) -> @autoreleased Optional - // CHECK: strong_retain_autoreleased [[COCOA_VAL]] // CHECK: [[IS_NON_NIL:%[0-9]+]] = select_enum [[COCOA_VAL]] : $Optional // CHECK: cond_br [[IS_NON_NIL]], [[CASE_NON_NIL:[^, ]+]], [[CASE_NIL:[^, ]+]] @@ -47,7 +45,6 @@ func testNullable(obj: Test) -> [AnyObject]? { func testNullUnspecified(obj: Test) -> [AnyObject]! { // CHECK: [[METHOD:%[0-9]+]] = class_method [volatile] %0 : $Test, #Test.nullUnspecifiedArray!getter.1.foreign : Test -> () -> [AnyObject]! , $@convention(objc_method) (Test) -> @autoreleased ImplicitlyUnwrappedOptional // CHECK: [[COCOA_VAL:%[0-9]+]] = apply [[METHOD]](%0) : $@convention(objc_method) (Test) -> @autoreleased ImplicitlyUnwrappedOptional - // CHECK: strong_retain_autoreleased [[COCOA_VAL]] // CHECK: [[IS_NON_NIL:%[0-9]+]] = select_enum [[COCOA_VAL]] : $ImplicitlyUnwrappedOptional // CHECK: cond_br [[IS_NON_NIL]], [[CASE_NON_NIL:[^, ]+]], [[CASE_NIL:[^, ]+]] @@ -74,7 +71,6 @@ func testNullUnspecified(obj: Test) -> [AnyObject]! { func testNonnullDictionary(obj: Test) -> [NSObject: AnyObject] { // CHECK: [[METHOD:%[0-9]+]] = class_method [volatile] %0 : $Test, #Test.nonnullDictionary!getter.1.foreign : Test -> () -> [NSObject : AnyObject] , $@convention(objc_method) (Test) -> @autoreleased Optional // CHECK: [[COCOA_VAL:%[0-9]+]] = apply [[METHOD]](%0) : $@convention(objc_method) (Test) -> @autoreleased Optional - // CHECK: strong_retain_autoreleased [[COCOA_VAL]] // CHECK: [[CONVERT:%[0-9]+]] = function_ref @_TF10Foundation32_convertNSDictionaryToDictionary // CHECK: [[RESULT:%[0-9]+]] = apply [[CONVERT]]([[COCOA_VAL]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : NSObject, τ_0_0 : Hashable, τ_0_1 : AnyObject> (@owned Optional) -> @owned Dictionary<τ_0_0, τ_0_1> // CHECK: strong_release %0 : $Test @@ -86,7 +82,6 @@ func testNonnullDictionary(obj: Test) -> [NSObject: AnyObject] { func testNonnullSet(obj: Test) -> Set { // CHECK: [[METHOD:%[0-9]+]] = class_method [volatile] %0 : $Test, #Test.nonnullSet!getter.1.foreign : Test -> () -> Set , $@convention(objc_method) (Test) -> @autoreleased Optional // CHECK: [[COCOA_VAL:%[0-9]+]] = apply [[METHOD]](%0) : $@convention(objc_method) (Test) -> @autoreleased Optional - // CHECK: strong_retain_autoreleased [[COCOA_VAL]] // CHECK: [[CONVERT:%[0-9]+]] = function_ref @_TF10Foundation18_convertNSSetToSet // CHECK: [[RESULT:%[0-9]+]] = apply [[CONVERT]]([[COCOA_VAL]]) : $@convention(thin) <τ_0_0 where τ_0_0 : NSObject, τ_0_0 : Hashable> (@owned Optional) -> @owned Set<τ_0_0> // CHECK: strong_release %0 : $Test @@ -98,7 +93,6 @@ func testNonnullSet(obj: Test) -> Set { func testNonnullString(obj: Test) -> String { // CHECK: [[METHOD:%[0-9]+]] = class_method [volatile] %0 : $Test, #Test.nonnullString!getter.1.foreign : Test -> () -> String , $@convention(objc_method) (Test) -> @autoreleased Optional // CHECK: [[COCOA_VAL:%[0-9]+]] = apply [[METHOD]](%0) : $@convention(objc_method) (Test) -> @autoreleased Optional - // CHECK: strong_retain_autoreleased [[COCOA_VAL]] // CHECK: [[CONVERT:%[0-9]+]] = function_ref @swift_NSStringToString : $@convention(thin) (@owned Optional) -> @owned String // CHECK: [[RESULT:%[0-9]+]] = apply [[CONVERT]]([[COCOA_VAL]]) : $@convention(thin) (@owned Optional) -> @owned String // CHECK: strong_release %0 : $Test @@ -112,9 +106,8 @@ func testNonnullString(obj: Test) -> String { // not to crash trying to generate the thunk. // CHECK-LABEL: sil hidden @_TF20objc_bridged_results20testNonnullSubscriptFCSo4TestGSaPs9AnyObject__ func testNonnullSubscript(obj: Test) -> [AnyObject] { - // CHECK: [[METHOD:%[0-9]+]] = class_method [volatile] %0 : $Test, #Test.subscript!getter.1.foreign : Test -> (Int) -> [AnyObject] , $@convention(objc_method) (Int, Test) -> @autoreleased Optional + // CHECK: [[METHOD:%[0-9]+]] = class_method [volatile] %0 : $Test, #Test.subscript!getter.1.foreign : (Test) -> (Int) -> [AnyObject] , $@convention(objc_method) (Int, Test) -> @autoreleased Optional // CHECK: [[COCOA_VAL:%[0-9]+]] = apply [[METHOD]]({{%[0-9]+}}, %0) : $@convention(objc_method) (Int, Test) -> @autoreleased Optional - // CHECK: strong_retain_autoreleased [[COCOA_VAL]] // CHECK: [[CONVERT:%[0-9]+]] = function_ref @_TF10Foundation22_convertNSArrayToArray // CHECK: [[RESULT:%[0-9]+]] = apply [[CONVERT]]([[COCOA_VAL]]) : $@convention(thin) <τ_0_0> (@owned Optional) -> @owned Array<τ_0_0> // CHECK: strong_release %0 : $Test diff --git a/test/SILGen/objc_bridging.swift b/test/SILGen/objc_bridging.swift index 40a21cbb63a16..12121dd7a71e8 100644 --- a/test/SILGen/objc_bridging.swift +++ b/test/SILGen/objc_bridging.swift @@ -11,7 +11,6 @@ func getDescription(o: NSObject) -> String { // CHECK: bb0({{%.*}} : $NSObject): // CHECK: [[DESCRIPTION:%.*]] = class_method [volatile] {{%.*}} : {{.*}}, #NSObject.description!getter.1.foreign // CHECK: [[OPT_BRIDGED:%.*]] = apply [[DESCRIPTION]]({{%.*}}) -// CHECK: strong_retain_autoreleased [[OPT_BRIDGED]] // CHECK: select_enum [[OPT_BRIDGED]] // CHECK: [[BRIDGED:%.*]] = unchecked_enum_data [[OPT_BRIDGED]] // CHECK: [[NSSTRING_TO_STRING:%.*]] = function_ref @swift_NSStringToString @@ -19,7 +18,7 @@ func getDescription(o: NSObject) -> String { // CHECK: [[NATIVE:%.*]] = apply [[NSSTRING_TO_STRING]]([[BRIDGED_BOX]]) // CHECK: [[OPT_NATIVE:%.*]] = enum $ImplicitlyUnwrappedOptional, #ImplicitlyUnwrappedOptional.Some!enumelt.1, [[NATIVE]] // CHECK: [[T0:%.*]] = function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue -// CHECK: apply [[T0]]([[NATIVE_BUF:%.*]]#1, +// CHECK: apply [[T0]]([[NATIVE_BUF:%[0-9]*]], // CHECK: [[NATIVE:%.*]] = load [[NATIVE_BUF]] // CHECK: return [[NATIVE]] // CHECK:} @@ -34,7 +33,6 @@ func getUppercaseString(s: NSString) -> String { // CHECK-NOT: function_ref @swift_StringToNSString // CHECK: [[UPPERCASE_STRING:%.*]] = class_method [volatile] {{%.*}} : {{.*}}, #NSString.uppercaseString!1.foreign // CHECK: [[OPT_BRIDGED:%.*]] = apply [[UPPERCASE_STRING]]({{%.*}}) -// CHECK: retain_autoreleased [[OPT_BRIDGED]] // CHECK: select_enum [[OPT_BRIDGED]] // CHECK: [[BRIDGED:%.*]] = unchecked_enum_data [[OPT_BRIDGED]] // CHECK: [[NSSTRING_TO_STRING:%.*]] = function_ref @swift_NSStringToString @@ -42,7 +40,7 @@ func getUppercaseString(s: NSString) -> String { // CHECK: [[NATIVE:%.*]] = apply [[NSSTRING_TO_STRING]]([[BRIDGED_BOX]]) // CHECK: [[OPT_NATIVE:%.*]] = enum $ImplicitlyUnwrappedOptional, #ImplicitlyUnwrappedOptional.Some!enumelt.1, [[NATIVE]] // CHECK: [[T0:%.*]] = function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue -// CHECK: apply [[T0]]([[NATIVE_BUF:%.*]]#1, +// CHECK: apply [[T0]]([[NATIVE_BUF:%[0-9]*]], // CHECK: [[NATIVE:%.*]] = load [[NATIVE_BUF]] // CHECK: return [[NATIVE]] // CHECK: } @@ -156,7 +154,6 @@ func callBar() -> String { // CHECK: bb0: // CHECK: [[BAR:%.*]] = function_ref @bar // CHECK: [[OPT_BRIDGED:%.*]] = apply [[BAR]]() -// CHECK: retain_autoreleased [[OPT_BRIDGED]] // CHECK: select_enum [[OPT_BRIDGED]] // CHECK: [[BRIDGED:%.*]] = unchecked_enum_data [[OPT_BRIDGED]] // CHECK: [[NSSTRING_TO_STRING:%.*]] = function_ref @swift_NSStringToString @@ -164,7 +161,7 @@ func callBar() -> String { // CHECK: [[NATIVE:%.*]] = apply [[NSSTRING_TO_STRING]]([[BRIDGED_BOX]]) // CHECK: [[OPT_NATIVE:%.*]] = enum $ImplicitlyUnwrappedOptional, #ImplicitlyUnwrappedOptional.Some!enumelt.1, [[NATIVE]] // CHECK: [[T0:%.*]] = function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue -// CHECK: apply [[T0]]([[NATIVE_BUF:%.*]]#1, +// CHECK: apply [[T0]]([[NATIVE_BUF:%[0-9]*]], // CHECK: [[NATIVE:%.*]] = load [[NATIVE_BUF]] // CHECK: return [[NATIVE]] // CHECK: } @@ -232,7 +229,7 @@ class Bas : NSObject { // CHECK: strong_release [[THIS]] // CHECK: [[STRING_TO_NSSTRING:%.*]] = function_ref @swift_StringToNSString // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[PROP_COPY]]) - // CHECK: autorelease_return [[NSSTR]] + // CHECK: return [[NSSTR]] // CHECK: } @@ -268,7 +265,7 @@ class Bas : NSObject { // CHECK: [[STR:%.*]] = apply [[GETTER]]([[THIS]]) // CHECK: [[STRING_TO_NSSTRING:%.*]] = function_ref @swift_StringToNSString // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[STR]]) - // CHECK: autorelease_return [[NSSTR]] + // CHECK: return [[NSSTR]] // CHECK: } // CHECK-LABEL: sil hidden [thunk] @_TToFC13objc_bridging3Bass11strFakePropSS : $@convention(objc_method) (NSString, Bas) -> () { @@ -304,7 +301,7 @@ class Bas : NSObject { // CHECK: [[STR:%.*]] = apply [[METHOD]]([[THIS]]) // CHECK: [[STRING_TO_NSSTRING:%.*]] = function_ref @swift_StringToNSString // CHECK: [[NSSTR:%.*]] = apply [[STRING_TO_NSSTRING]]([[STR]]) - // CHECK: autorelease_return [[NSSTR]] + // CHECK: return [[NSSTR]] // CHECK: } func strArg(s: String) { } // CHECK-LABEL: sil hidden [thunk] @_TToFC13objc_bridging3Bas6strArg @@ -354,7 +351,7 @@ class Bas : NSObject { // CHECK: strong_release [[SELF]] // CHECK: [[CONV_FN:%[0-9]+]] = function_ref @_TF10Foundation22_convertArrayToNSArray{{.*}} : $@convention(thin) <τ_0_0> (@owned Array<τ_0_0>) -> @owned NSArray // CHECK: [[NSARRAY:%[0-9]+]] = apply [[CONV_FN]]([[ARRAY]]) : $@convention(thin) <τ_0_0> (@owned Array<τ_0_0>) -> @owned NSArray - // CHECK: autorelease_return [[NSARRAY]] + // CHECK: return [[NSARRAY]] func arrayResult() -> [AnyObject] { return [] } // CHECK-LABEL: sil hidden [transparent] [thunk] @_TToFC13objc_bridging3Basg9arrayPropGSaSS_ : $@convention(objc_method) (Bas) -> @autoreleased NSArray diff --git a/test/SILGen/objc_currying.swift b/test/SILGen/objc_currying.swift index 8825a4775f712..71419cb10738b 100644 --- a/test/SILGen/objc_currying.swift +++ b/test/SILGen/objc_currying.swift @@ -46,7 +46,6 @@ func curry_bridged(x: CurryTest) -> String! -> String! { // CHECK: function_ref @swift_StringToNSString // CHECK: [[METHOD:%.*]] = class_method [volatile] %1 : $CurryTest, #CurryTest.bridged!1.foreign // CHECK: [[RES:%.*]] = apply [[METHOD]]({{%.*}}, %1) : $@convention(objc_method) (ImplicitlyUnwrappedOptional, CurryTest) -> @autoreleased ImplicitlyUnwrappedOptional -// CHECK: strong_retain_autoreleased [[RES]] // CHECK: function_ref @swift_NSStringToString // CHECK: strong_release %1 // CHECK: return {{%.*}} : $ImplicitlyUnwrappedOptional diff --git a/test/SILGen/objc_dealloc.swift b/test/SILGen/objc_dealloc.swift index 49a0aa1f7444b..80ca05c19a6be 100644 --- a/test/SILGen/objc_dealloc.swift +++ b/test/SILGen/objc_dealloc.swift @@ -53,7 +53,7 @@ class SwiftGizmo : Gizmo { // Objective-C IVar initializer (i.e., -.cxx_construct) // CHECK-LABEL: sil hidden @_TToFC12objc_dealloc10SwiftGizmoe : $@convention(objc_method) (@owned SwiftGizmo) -> @owned SwiftGizmo // CHECK: bb0([[SELF_PARAM:%[0-9]+]] : $SwiftGizmo): - // CHECK-NEXT: debug_value [[SELF_PARAM]] : $SwiftGizmo // let self + // CHECK-NEXT: debug_value [[SELF_PARAM]] : $SwiftGizmo, let, name "self" // CHECK-NEXT: [[SELF:%[0-9]+]] = mark_uninitialized [rootself] [[SELF_PARAM]] : $SwiftGizmo // CHECK: [[XCTOR:%[0-9]+]] = function_ref @_TFC12objc_dealloc1XC // CHECK-NEXT: [[XMETA:%[0-9]+]] = metatype $@thick X.Type @@ -65,7 +65,7 @@ class SwiftGizmo : Gizmo { // Objective-C IVar destroyer (i.e., -.cxx_destruct) // CHECK-LABEL: sil hidden @_TToFC12objc_dealloc10SwiftGizmoE : $@convention(objc_method) (SwiftGizmo) -> () // CHECK: bb0([[SELF:%[0-9]+]] : $SwiftGizmo): - // CHECK-NEXT: debug_value [[SELF]] : $SwiftGizmo // let self + // CHECK-NEXT: debug_value [[SELF]] : $SwiftGizmo, let, name "self" // CHECK-NEXT: [[X:%[0-9]+]] = ref_element_addr [[SELF]] : $SwiftGizmo, #SwiftGizmo.x // CHECK-NEXT: destroy_addr [[X]] : $*X // CHECK-NEXT: [[RESULT:%[0-9]+]] = tuple () diff --git a/test/SILGen/objc_dictionary_bridging.swift b/test/SILGen/objc_dictionary_bridging.swift index e34866e7d1bdb..117801df3ee26 100644 --- a/test/SILGen/objc_dictionary_bridging.swift +++ b/test/SILGen/objc_dictionary_bridging.swift @@ -28,7 +28,7 @@ import gizmo // CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TF10Foundation32_convertDictionaryToNSDictionary{{.*}} : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary // CHECK-NEXT: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]([[DICT]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary - // CHECK-NEXT: autorelease_return [[NSDICT]] : $NSDictionary + // CHECK-NEXT: return [[NSDICT]] : $NSDictionary } var property: Dictionary = [:] @@ -41,7 +41,7 @@ import gizmo // CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TF10Foundation32_convertDictionaryToNSDictionary{{.*}} : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary // CHECK: [[NSDICT:%[0-9]+]] = apply [[CONVERTER]]([[DICT]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@owned Dictionary<τ_0_0, τ_0_1>) -> @owned NSDictionary - // CHECK: autorelease_return [[NSDICT]] : $NSDictionary + // CHECK: return [[NSDICT]] : $NSDictionary // Property setter // CHECK-LABEL: sil hidden [transparent] [thunk] @_TToFC24objc_dictionary_bridging3Foos8propertyGVs10DictionaryS0_S0__ : $@convention(objc_method) (NSDictionary, Foo) -> () diff --git a/test/SILGen/objc_enum.swift b/test/SILGen/objc_enum.swift index 81a86f2ea7967..f74adeb0f8b3c 100644 --- a/test/SILGen/objc_enum.swift +++ b/test/SILGen/objc_enum.swift @@ -11,9 +11,9 @@ import gizmo // CHECK-DAG: sil shared @_TFOSC16NSRuncingOptionsg8rawValueSi // CHECK-DAG: sil shared @_TFOSC16NSRuncingOptionsg9hashValueSi -// CHECK-DAG: sil shared [transparent] @_TFOSC16NSRuncingOptions5MinceFMS_S_ -// CHECK-DAG: sil shared [transparent] @_TFOSC16NSRuncingOptions12QuinceSlicedFMS_S_ -// Unused enum ctors don't need to be instantiated. +// Non-payload enum ctors don't need to be instantiated at all. +// NEGATIVE-NOT: sil shared [transparent] @_TFOSC16NSRuncingOptions5MinceFMS_S_ +// NEGATIVE-NOT: sil shared [transparent] @_TFOSC16NSRuncingOptions12QuinceSlicedFMS_S_ // NEGATIVE-NOT: sil shared [transparent] @_TFOSC16NSRuncingOptions15QuinceJuliennedFMS_S_ // NEGATIVE-NOT: sil shared [transparent] @_TFOSC16NSRuncingOptions11QuinceDicedFMS_S_ @@ -47,6 +47,6 @@ _ = NSFungingMask.ToTheMax // CHECK-DAG: sil shared [transparent] [thunk] @_TTWOSC16NSRuncingOptionss16RawRepresentable5gizmoFS0_C -// Extension conformances get linkage occording to the protocol's accessibility, as normal. +// Extension conformances get linkage according to the protocol's accessibility, as normal. // CHECK-DAG: sil_witness_table hidden NSRuncingOptions: Bub module objc_enum diff --git a/test/SILGen/objc_init_ref_delegation.swift b/test/SILGen/objc_init_ref_delegation.swift index bb1a6244f9934..457ede867ffc8 100644 --- a/test/SILGen/objc_init_ref_delegation.swift +++ b/test/SILGen/objc_init_ref_delegation.swift @@ -14,7 +14,7 @@ extension Gizmo { // CHECK: [[SELF:%[0-9]+]] = load [[SELFMUI]] : $*Gizmo // CHECK: [[INIT_DELEG:%[0-9]+]] = class_method [volatile] [[SELF]] : $Gizmo, #Gizmo.init!initializer.1.foreign : Gizmo.Type -> (bellsOn: Int) -> Gizmo! , $@convention(objc_method) (Int, @owned Gizmo) -> @owned ImplicitlyUnwrappedOptional // CHECK: [[SELF_RET:%[0-9]+]] = apply [[INIT_DELEG]]([[I]], [[SELF]]) : $@convention(objc_method) (Int, @owned Gizmo) -> @owned ImplicitlyUnwrappedOptional - // CHECK: store [[SELF_RET]] to [[SELFMUI:%[0-9]+]]#1 : $*ImplicitlyUnwrappedOptional + // CHECK: store [[SELF_RET]] to [[SELFMUI:%[0-9]+]] : $*ImplicitlyUnwrappedOptional // CHECK: strong_retain [[SELF4:%[0-9]+]] : $Gizmo // CHECK: strong_release [[SELF_BOX:%[0-9]+]]#0 : $@box Gizmo // CHECK: return [[SELF4]] : $Gizmo diff --git a/test/SILGen/objc_ownership_conventions.swift b/test/SILGen/objc_ownership_conventions.swift index 07e09e413f8f3..47e5e9c926a93 100644 --- a/test/SILGen/objc_ownership_conventions.swift +++ b/test/SILGen/objc_ownership_conventions.swift @@ -36,7 +36,7 @@ func test5(g: Gizmo) { // CHECK: [[CLASS:%.*]] = metatype $@thick Gizmo.Type // CHECK-NEXT: [[METHOD:%.*]] = class_method [volatile] [[CLASS]] : {{.*}}, #Gizmo.inspect!1.foreign // CHECK-NEXT: [[OBJC_CLASS:%[0-9]+]] = thick_to_objc_metatype [[CLASS]] : $@thick Gizmo.Type to $@objc_metatype Gizmo.Type - // CHECK: [[V:%.*]] = load %2#1 + // CHECK: [[V:%.*]] = load %2 // CHECK: strong_retain [[V]] // CHECK: [[G:%.*]] = enum $ImplicitlyUnwrappedOptional, #ImplicitlyUnwrappedOptional.Some!enumelt.1, [[V]] // CHECK-NEXT: apply [[METHOD]]([[G]], [[OBJC_CLASS]]) @@ -50,7 +50,7 @@ func test6(g: Gizmo) { // CHECK: [[CLASS:%.*]] = metatype $@thick Gizmo.Type // CHECK-NEXT: [[METHOD:%.*]] = class_method [volatile] [[CLASS]] : {{.*}}, #Gizmo.consume!1.foreign // CHECK-NEXT: [[OBJC_CLASS:%.*]] = thick_to_objc_metatype [[CLASS]] : $@thick Gizmo.Type to $@objc_metatype Gizmo.Type - // CHECK: [[V:%.*]] = load %2#1 + // CHECK: [[V:%.*]] = load %2 // CHECK: strong_retain [[V]] // CHECK: [[G:%.*]] = enum $ImplicitlyUnwrappedOptional, #ImplicitlyUnwrappedOptional.Some! // CHECK-NEXT: apply [[METHOD]]([[G]], [[OBJC_CLASS]]) @@ -97,7 +97,6 @@ func test9(g: Gizmo) -> Gizmo { // CHECK: alloc_stack // CHECK-NEXT: [[METHOD:%.*]] = class_method [volatile] [[G]] : {{.*}}, #Gizmo.duplicate!1.foreign // CHECK-NEXT: [[RESULT:%.*]] = apply [[METHOD]]([[G]]) - // CHECK-NEXT: retain_autoreleased [[RESULT]] // CHECK-NEXT: store [[RESULT]] // CHECK-NEXT: function_ref // CHECK-NEXT: function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue @@ -123,8 +122,8 @@ func test10(g: Gizmo) -> AnyClass { // CHECK-NEXT: [[THICK:%.*]] = objc_to_thick_metatype [[OBJC]] // CHECK: [[T0:%.*]] = enum $ImplicitlyUnwrappedOptional, #ImplicitlyUnwrappedOptional.Some!enumelt.1, [[THICK]] // CHECK: [[T0:%.*]] = function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue - // CHECK: apply [[T0]]([[THICK_BUF:%.*]]#1, {{.*}}) - // CHECK-NEXT: [[RES:%.*]] = load [[THICK_BUF]]#1 + // CHECK: apply [[T0]]([[THICK_BUF:%[0-9]*]], {{.*}}) + // CHECK-NEXT: [[RES:%.*]] = load [[THICK_BUF]] // CHECK: strong_release [[G]] : $Gizmo // CHECK: strong_release [[G]] : $Gizmo // CHECK-NEXT: return [[RES]] : $@thick AnyObject.Type @@ -143,8 +142,8 @@ func test11(g: Gizmo) -> AnyClass { // CHECK-NEXT: [[THICK:%.*]] = objc_to_thick_metatype [[OBJC]] // CHECK: [[T0:%.*]] = enum $ImplicitlyUnwrappedOptional, #ImplicitlyUnwrappedOptional.Some!enumelt.1, [[THICK]] // CHECK: [[T0:%.*]] = function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue - // CHECK: apply [[T0]]([[THICK_BUF:%.*]]#1, {{.*}}) - // CHECK-NEXT: [[RES:%.*]] = load [[THICK_BUF]]#1 + // CHECK: apply [[T0]]([[THICK_BUF:%[0-9]*]], {{.*}}) + // CHECK-NEXT: [[RES:%.*]] = load [[THICK_BUF]] // CHECK: strong_release [[G]] : $Gizmo // CHECK: strong_release [[G]] : $Gizmo // CHECK-NEXT: return [[RES]] : $@thick AnyObject.Type @@ -159,7 +158,6 @@ func applyBlock(f: @convention(block) Gizmo -> Gizmo, x: Gizmo) -> Gizmo { // CHECK: [[BLOCK_COPY:%.*]] = copy_block [[BLOCK]] // CHECK: strong_retain [[BLOCK_COPY]] // CHECK: [[RESULT:%.*]] = apply [[BLOCK_COPY]]([[ARG]]) - // CHECK: strong_retain_autoreleased [[RESULT]] // CHECK: strong_release [[BLOCK_COPY]] // CHECK: strong_release [[ARG]] // CHECK: strong_release [[BLOCK_COPY]] diff --git a/test/SILGen/objc_properties.swift b/test/SILGen/objc_properties.swift index ef45cfdb8983f..0485b792446a2 100644 --- a/test/SILGen/objc_properties.swift +++ b/test/SILGen/objc_properties.swift @@ -59,25 +59,25 @@ class A { // CHECK-LABEL: sil hidden @_TF15objc_properties11testPropGet func testPropGet(a: A) -> Int { - // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.prop!getter.1.foreign : A -> () -> Int , $@convention(objc_method) (A) -> Int + // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.prop!getter.1.foreign : (A) -> () -> Int , $@convention(objc_method) (A) -> Int return a.prop } // CHECK-LABEL: sil hidden @_TF15objc_properties11testPropSet func testPropSet(a: A, i: Int) { - // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.prop!setter.1.foreign : A -> (Int) -> () , $@convention(objc_method) (Int, A) -> () + // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.prop!setter.1.foreign : (A) -> (Int) -> () , $@convention(objc_method) (Int, A) -> () a.prop = i } // CHECK-LABEL: sil hidden @_TF15objc_properties19testComputedPropGet func testComputedPropGet(a: A) -> Int { - // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.computedProp!getter.1.foreign : A -> () -> Int , $@convention(objc_method) (A) -> Int + // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.computedProp!getter.1.foreign : (A) -> () -> Int , $@convention(objc_method) (A) -> Int return a.computedProp } // CHECK-LABEL: sil hidden @_TF15objc_properties19testComputedPropSet func testComputedPropSet(a: A, i: Int) { - // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.computedProp!setter.1.foreign : A -> (Int) -> () , $@convention(objc_method) (Int, A) -> () + // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.computedProp!setter.1.foreign : (A) -> (Int) -> () , $@convention(objc_method) (Int, A) -> () a.computedProp = i } @@ -86,12 +86,12 @@ class B : A { @objc override var computedProp: Int { // CHECK-LABEL: sil hidden @_TFC15objc_properties1Bg12computedPropSi : $@convention(method) (@guaranteed B) -> Int get { - // CHECK: super_method [volatile] [[SELF:%[0-9]+]] : $B, #A.computedProp!getter.1.foreign : A -> () -> Int , $@convention(objc_method) (A) -> Int + // CHECK: super_method [volatile] [[SELF:%[0-9]+]] : $B, #A.computedProp!getter.1.foreign : (A) -> () -> Int , $@convention(objc_method) (A) -> Int return super.computedProp } // CHECK-LABEL: sil hidden @_TFC15objc_properties1Bs12computedPropSi : $@convention(method) (Int, @guaranteed B) -> () set(value) { - // CHECK: super_method [volatile] [[SELF:%[0-9]+]] : $B, #A.computedProp!setter.1.foreign : A -> (Int) -> () , $@convention(objc_method) (Int, A) -> () + // CHECK: super_method [volatile] [[SELF:%[0-9]+]] : $B, #A.computedProp!setter.1.foreign : (A) -> (Int) -> () , $@convention(objc_method) (Int, A) -> () super.computedProp = value } } diff --git a/test/SILGen/objc_protocols.swift b/test/SILGen/objc_protocols.swift index 69d944fc113a8..fb129041f67f7 100644 --- a/test/SILGen/objc_protocols.swift +++ b/test/SILGen/objc_protocols.swift @@ -10,6 +10,8 @@ import objc_protocols_Bas func copyRuncing() -> NSObject func foo() + + static func mince() -> NSObject } @objc protocol NSFunging { @@ -25,39 +27,89 @@ protocol Ansible { // CHECK-LABEL: sil hidden @_TF14objc_protocols12objc_generic func objc_generic(x: T) -> (NSObject, NSObject) { return (x.runce(), x.copyRuncing()) - // -- Result of runce is retain_autoreleased according to default objc conv + // -- Result of runce is autoreleased according to default objc conv // CHECK: [[METHOD:%.*]] = witness_method [volatile] {{\$.*}}, #NSRuncing.runce!1.foreign // CHECK: [[RESULT1:%.*]] = apply [[METHOD]]([[THIS1:%.*]]) : $@convention(objc_method) <τ_0_0 where τ_0_0 : NSRuncing> (τ_0_0) -> @autoreleased NSObject - // CHECK: retain_autoreleased [[RESULT1]] : $NSObject // -- Result of copyRuncing is received retained according to -copy family // CHECK: [[METHOD:%.*]] = witness_method [volatile] {{\$.*}}, #NSRuncing.copyRuncing!1.foreign // CHECK: [[RESULT2:%.*]] = apply [[METHOD]]([[THIS2:%.*]]) : $@convention(objc_method) <τ_0_0 where τ_0_0 : NSRuncing> (τ_0_0) -> @owned NSObject - // CHECK-NOT: retain_autoreleased // -- Arguments are not consumed by objc calls // CHECK: release [[THIS2]] } +func objc_generic_partial_apply(x: T) { + // CHECK: [[FN:%.*]] = function_ref @_TTOFP14objc_protocols9NSRuncing5runceFT_CSo8NSObject + // CHECK-NEXT: strong_retain %0 + // CHECK-NEXT: [[METHOD:%.*]] = apply [[FN]](%0) + // CHECK-NEXT: strong_release [[METHOD]] + _ = x.runce + + // CHECK: [[FN:%.*]] = function_ref @_TTOFP14objc_protocols9NSRuncing5runceFT_CSo8NSObject + // CHECK-NEXT: [[METHOD:%.*]] = partial_apply [[FN]]() + // CHECK-NEXT: strong_release [[METHOD]] + _ = T.runce + + // CHECK: [[FN:%.*]] = function_ref @_TTOZFP14objc_protocols9NSRuncing5minceFT_CSo8NSObject + // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick T.Type + // CHECK-NEXT: [[METHOD:%.*]] = apply [[FN]]([[METATYPE]]) + // CHECK-NEXT: strong_release [[METHOD:%.*]] + _ = T.mince +} + +// CHECK-LABEL: sil shared @_TTOFP14objc_protocols9NSRuncing5runceFT_CSo8NSObject +// CHECK: [[FN:%.*]] = function_ref @_TTOFP14objc_protocols9NSRuncing5runcefT_CSo8NSObject +// CHECK-NEXT: [[METHOD:%.*]] = partial_apply [[FN]](%0) +// CHECK-NEXT: return [[METHOD]] + +// CHECK-LABEL: sil shared @_TTOFP14objc_protocols9NSRuncing5runcefT_CSo8NSObject +// CHECK: strong_retain %0 +// CHECK-NEXT: [[FN:%.*]] = witness_method $Self, #NSRuncing.runce!1.foreign +// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]](%0) +// CHECK-NEXT: strong_release %0 +// CHECK-NEXT: return [[RESULT]] + +// CHECK-LABEL: sil shared @_TTOZFP14objc_protocols9NSRuncing5minceFT_CSo8NSObject +// CHECK: [[FN:%.*]] = function_ref @_TTOZFP14objc_protocols9NSRuncing5mincefT_CSo8NSObject +// CHECK-NEXT: [[METHOD:%.*]] = partial_apply [[FN]](%0) +// CHECK-NEXT: return [[METHOD]] + +// CHECK-LABEL: sil shared @_TTOZFP14objc_protocols9NSRuncing5mincefT_CSo8NSObject +// CHECK: [[FN:%.*]] = witness_method $Self, #NSRuncing.mince!1.foreign +// CHECK-NEXT: [[RESULT:%.*]] = apply [[FN]](%0) +// CHECK-NEXT: return [[RESULT]] + // CHECK-LABEL: sil hidden @_TF14objc_protocols13objc_protocol func objc_protocol(x: NSRuncing) -> (NSObject, NSObject) { return (x.runce(), x.copyRuncing()) - // -- Result of runce is retain_autoreleased according to default objc conv + // -- Result of runce is autoreleased according to default objc conv // CHECK: [[THIS1:%.*]] = open_existential_ref [[THIS1_ORIG:%.*]] : $NSRuncing to $[[OPENED:@opened(.*) NSRuncing]] // CHECK: [[METHOD:%.*]] = witness_method [volatile] $[[OPENED]], #NSRuncing.runce!1.foreign // CHECK: [[RESULT1:%.*]] = apply [[METHOD]]<[[OPENED]]>([[THIS1]]) - // CHECK: retain_autoreleased [[RESULT1]] : $NSObject // -- Result of copyRuncing is received retained according to -copy family // CHECK: [[THIS2:%.*]] = open_existential_ref [[THIS2_ORIG:%.*]] : $NSRuncing to $[[OPENED2:@opened(.*) NSRuncing]] // CHECK: [[METHOD:%.*]] = witness_method [volatile] $[[OPENED2]], #NSRuncing.copyRuncing!1.foreign // CHECK: [[RESULT2:%.*]] = apply [[METHOD]]<[[OPENED2]]>([[THIS2:%.*]]) - // CHECK-NOT: retain_autoreleased // -- Arguments are not consumed by objc calls // CHECK: release [[THIS2_ORIG]] } +func objc_protocol_partial_apply(x: NSRuncing) { + // CHECK: [[THIS1:%.*]] = open_existential_ref %0 : $NSRuncing to $[[OPENED:@opened(.*) NSRuncing]] + // CHECK: [[FN:%.*]] = function_ref @_TTOFP14objc_protocols9NSRuncing5runceFT_CSo8NSObject + // CHECK: strong_retain [[THIS1]] + // CHECK: [[RESULT:%.*]] = apply [[FN]]<[[OPENED]]>([[THIS1]]) + // CHECK: strong_release [[RESULT]] + // CHECK: strong_release %0 + _ = x.runce + + // FIXME: rdar://21289579 + // _ = NSRuncing.runce +} + // CHECK-LABEL: sil hidden @_TF14objc_protocols25objc_protocol_composition func objc_protocol_composition(x: protocol) { // CHECK: [[THIS:%.*]] = open_existential_ref [[THIS_ORIG:%.*]] : $protocol to $[[OPENED:@opened(.*) protocol]] @@ -77,6 +129,8 @@ class Foo : NSRuncing, NSFunging, Ansible { @objc func runce() -> NSObject { return NSObject() } @objc func copyRuncing() -> NSObject { return NSObject() } + @objc static func mince() -> NSObject { return NSObject() } + // -- NSFunging @objc func funge() {} @@ -99,6 +153,7 @@ extension Bar : NSRuncing { @objc func runce() -> NSObject { return NSObject() } @objc func copyRuncing() -> NSObject { return NSObject() } @objc func foo() {} + @objc static func mince() -> NSObject { return NSObject() } } // CHECK-LABEL: sil hidden [thunk] @_TToFC14objc_protocols3Bar5runce @@ -110,6 +165,7 @@ extension Bas : NSRuncing { // runce() implementation from the original definition of Bas @objc func copyRuncing() -> NSObject { return NSObject() } @objc func foo() {} + @objc static func mince() -> NSObject { return NSObject() } } // CHECK-LABEL: sil hidden [thunk] @_TToFE14objc_protocolsC18objc_protocols_Bas3Bas11copyRuncing diff --git a/test/SILGen/objc_set_bridging.swift b/test/SILGen/objc_set_bridging.swift index 0c453c5979420..1bc570245a0b5 100644 --- a/test/SILGen/objc_set_bridging.swift +++ b/test/SILGen/objc_set_bridging.swift @@ -29,7 +29,7 @@ import gizmo // CHECK: [[SET:%[0-9]+]] = apply [[SWIFT_FN]]([[SELF]]) : $@convention(method) (@guaranteed Foo) -> @owned Set // CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TF10Foundation18_convertSetToNSSet{{.*}} : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@owned Set<τ_0_0>) -> @owned NSSet // CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]([[SET]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@owned Set<τ_0_0>) -> @owned NSSet - // CHECK: autorelease_return [[NSSET]] : $NSSet + // CHECK: return [[NSSET]] : $NSSet } var property: Set = Set() @@ -42,7 +42,7 @@ import gizmo // CHECK: [[SET:%[0-9]+]] = apply [[GETTER]]([[SELF]]) : $@convention(method) (@guaranteed Foo) -> @owned Set // CHECK: [[CONVERTER:%[0-9]+]] = function_ref @_TF10Foundation18_convertSetToNSSet{{.*}} : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@owned Set<τ_0_0>) -> @owned NSSet // CHECK: [[NSSET:%[0-9]+]] = apply [[CONVERTER]]([[SET]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Hashable> (@owned Set<τ_0_0>) -> @owned NSSet - // CHECK: autorelease_return [[NSSET]] : $NSSet + // CHECK: return [[NSSET]] : $NSSet // Property setter // CHECK-LABEL: sil hidden [transparent] [thunk] @_TToFC17objc_set_bridging3Foos8property{{.*}} : $@convention(objc_method) (NSSet, Foo) -> () { diff --git a/test/SILGen/objc_subscript.swift b/test/SILGen/objc_subscript.swift index 4deffbc6cfa2b..bde28363a7092 100644 --- a/test/SILGen/objc_subscript.swift +++ b/test/SILGen/objc_subscript.swift @@ -15,13 +15,13 @@ class A { // CHECK-LABEL: sil hidden @_TF14objc_subscript16testSubscriptGet func testSubscriptGet(a: A, i: Int) -> ObjCClass { - // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.subscript!getter.1.foreign : A -> (Int) -> ObjCClass , $@convention(objc_method) (Int, A) -> @autoreleased ObjCClass + // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.subscript!getter.1.foreign : (A) -> (Int) -> ObjCClass , $@convention(objc_method) (Int, A) -> @autoreleased ObjCClass return a[i] } // CHECK-LABEL: sil hidden @_TF14objc_subscript16testSubscriptSet func testSubscriptSet(a: A, i: Int, v: ObjCClass) { - // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.subscript!setter.1.foreign : A -> (ObjCClass, Int) -> () , $@convention(objc_method) (ObjCClass, Int, A) -> () + // CHECK: class_method [volatile] [[OBJ:%[0-9]+]] : $A, #A.subscript!setter.1.foreign : (A) -> (ObjCClass, Int) -> () , $@convention(objc_method) (ObjCClass, Int, A) -> () a[i] = v } @@ -30,12 +30,12 @@ class B : A { @objc override subscript (i: Int) -> ObjCClass { // CHECK-LABEL: sil hidden @_TFC14objc_subscript1Bg9subscriptFSiCS_9ObjCClass : $@convention(method) (Int, @guaranteed B) -> @owned ObjCClass get { - // CHECK: super_method [volatile] [[SELF:%[0-9]+]] : $B, #A.subscript!getter.1.foreign : A -> (Int) -> ObjCClass , $@convention(objc_method) (Int, A) -> @autoreleased ObjCClass + // CHECK: super_method [volatile] [[SELF:%[0-9]+]] : $B, #A.subscript!getter.1.foreign : (A) -> (Int) -> ObjCClass , $@convention(objc_method) (Int, A) -> @autoreleased ObjCClass return super[i] } // CHECK-LABEL: sil hidden @_TFC14objc_subscript1Bs9subscriptFSiCS_9ObjCClass : $@convention(method) (@owned ObjCClass, Int, @guaranteed B) -> () set(value) { - // CHECK: super_method [volatile] [[SELF:%[0-9]+]] : $B, #A.subscript!setter.1.foreign : A -> (ObjCClass, Int) -> () , $@convention(objc_method) (ObjCClass, Int, A) -> () + // CHECK: super_method [volatile] [[SELF:%[0-9]+]] : $B, #A.subscript!setter.1.foreign : (A) -> (ObjCClass, Int) -> () , $@convention(objc_method) (ObjCClass, Int, A) -> () super[i] = value } } diff --git a/test/SILGen/objc_super.swift b/test/SILGen/objc_super.swift index b8872046cd4f6..f1485d3a30c14 100644 --- a/test/SILGen/objc_super.swift +++ b/test/SILGen/objc_super.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -emit-silgen | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -emit-silgen | FileCheck %s // REQUIRES: objc_interop @@ -42,7 +42,7 @@ class Wotsit : Hoozit { class NonObjCSuperInit : Wotsit { // CHECK-LABEL: sil hidden @_TFC10objc_super16NonObjCSuperInitc{{.*}} : $@convention(method) (@owned NonObjCSuperInit) -> @owned NonObjCSuperInit init() { - // CHECK: function_ref @_TFC10objc_super6Wotsitc{{.*}} : $@convention(method) (NotInObjC, @owned Wotsit) -> @owned Wotsit + // CHECK: super_method {{%[0-9]+}} : $NonObjCSuperInit, #Wotsit.init!initializer.1 : Wotsit.Type -> (nope: NotInObjC) -> Wotsit , $@convention(method) (NotInObjC, @owned Wotsit) -> @owned Wotsit super.init(nope: NotInObjC()) } } diff --git a/test/SILGen/objc_thunks.swift b/test/SILGen/objc_thunks.swift index 0b8bb7003417e..9e0c68891e170 100644 --- a/test/SILGen/objc_thunks.swift +++ b/test/SILGen/objc_thunks.swift @@ -15,7 +15,7 @@ class Hoozit : Gizmo { // CHECK-NEXT: [[NATIVE:%.*]] = function_ref @_TFC11objc_thunks6Hoozit7typical{{.*}} : $@convention(method) (Int, @owned Gizmo, @guaranteed Hoozit) -> @owned Gizmo // CHECK-NEXT: [[RES:%.*]] = apply [[NATIVE]]([[X]], [[Y]], [[THIS]]) {{.*}} line:[[@LINE-7]]:8:auto_gen // CHECK-NEXT: strong_release [[THIS]] : $Hoozit // {{.*}} - // CHECK-NEXT: autorelease_return [[RES]] : $Gizmo // {{.*}} line:[[@LINE-9]]:8:auto_gen + // CHECK-NEXT: return [[RES]] : $Gizmo // {{.*}} line:[[@LINE-9]]:8:auto_gen // CHECK-NEXT: } // NS_CONSUMES_SELF by inheritance @@ -48,7 +48,6 @@ class Hoozit : Gizmo { // CHECK-NEXT: [[NATIVE:%.*]] = function_ref @_TFC11objc_thunks6Hoozit7copyFoo{{.*}} : $@convention(method) (@guaranteed Hoozit) -> @owned Gizmo // CHECK-NEXT: [[RES:%.*]] = apply [[NATIVE]]([[THIS]]) // CHECK: release [[THIS]] - // CHECK-NOT: autorelease_return // CHECK-NEXT: return [[RES]] // CHECK-NEXT: } @@ -61,7 +60,7 @@ class Hoozit : Gizmo { // CHECK-NEXT: [[GETIMPL:%.*]] = function_ref @_TFC11objc_thunks6Hoozitg15typicalPropertyCSo5Gizmo // CHECK-NEXT: [[RES:%.*]] = apply [[GETIMPL]](%0) // CHECK-NEXT: strong_release %0 - // CHECK-NEXT: autorelease_return [[RES]] : $Gizmo + // CHECK-NEXT: return [[RES]] : $Gizmo // CHECK-NEXT: } // CHECK-LABEL: sil hidden [transparent] @_TFC11objc_thunks6Hoozitg15typicalPropertyCSo5Gizmo : $@convention(method) (@guaranteed Hoozit) -> @owned Gizmo @@ -132,7 +131,7 @@ class Hoozit : Gizmo { // CHECK-NEXT: [[NATIVE:%.*]] = function_ref @_TFC11objc_thunks6Hoozitg10roPropertyCSo5Gizmo : $@convention(method) (@guaranteed Hoozit) -> @owned Gizmo // CHECK-NEXT: [[RES:%.*]] = apply [[NATIVE]]([[THIS]]) // CHECK-NEXT: release [[THIS]] : $Hoozit - // CHECK-NEXT: autorelease_return [[RES]] : $Gizmo + // CHECK-NEXT: return [[RES]] : $Gizmo // CHECK-NEXT: } // -- no setter @@ -173,7 +172,7 @@ class Hoozit : Gizmo { // CHECK-NEXT: [[NATIVE:%.*]] = function_ref @_TFC11objc_thunks6Hoozitg14copyRWPropertyCSo5Gizmo : $@convention(method) (@guaranteed Hoozit) -> @owned Gizmo // CHECK-NEXT: [[RES:%.*]] = apply [[NATIVE]]([[THIS]]) // CHECK-NEXT: release [[THIS]] - // CHECK-NOT: autorelease_return + // CHECK-NOT: return // CHECK-NEXT: return [[RES]] // CHECK-NEXT: } @@ -218,7 +217,7 @@ class Hoozit : Gizmo { // CHECK: [[NATIVE:%[0-9]+]] = function_ref @_TFC11objc_thunks6Hoozitg9subscript{{.*}} : $@convention(method) (Int, @guaranteed Hoozit) -> @owned Hoozit // CHECK-NEXT: [[RESULT:%[0-9]+]] = apply [[NATIVE]]([[I]], [[SELF]]) : $@convention(method) (Int, @guaranteed Hoozit) -> @owned Hoozit // CHECK-NEXT: strong_release [[SELF]] - // CHECK-NEXT: autorelease_return [[RESULT]] : $Hoozit + // CHECK-NEXT: return [[RESULT]] : $Hoozit get { return self } @@ -267,7 +266,7 @@ class Wotsit : Gizmo { // CHECK-NEXT: // function_ref // CHECK-NEXT: [[BRIDGE:%.*]] = function_ref @swift_StringToNSString : $@convention(thin) (@owned String) -> @owned NSString // CHECK-NEXT: [[NSRESULT:%.*]] = apply [[BRIDGE]]([[RESULT]]) : $@convention(thin) (@owned String) -> @owned NSString - // CHECK-NEXT: autorelease_return [[NSRESULT]] : $NSString + // CHECK-NEXT: return [[NSRESULT]] : $NSString // CHECK-NEXT: } override var description : String { return "Hello, world." @@ -401,7 +400,7 @@ func registerAnsible() { // FIXME: would be nice if we didn't need to re-abstract as much here. -// CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo_oGSQFT_T___dT__XFdCb_dGSQbT_T___dT__ : $@convention(c) (@inout @block_storage @callee_owned (@owned ImplicitlyUnwrappedOptional<() -> ()>) -> (), ImplicitlyUnwrappedOptional<@convention(block) () -> ()>) -> () +// CHECK-LABEL: sil shared [transparent] [reabstraction_thunk] @_TTRXFo_oGSQFT_T___dT__XFdCb_dGSQbT_T___dT__ : $@convention(c) (@inout_aliasable @block_storage @callee_owned (@owned ImplicitlyUnwrappedOptional<() -> ()>) -> (), ImplicitlyUnwrappedOptional<@convention(block) () -> ()>) -> () // CHECK: [[HEAP_BLOCK_IUO:%.*]] = copy_block %1 // CHECK: select_enum [[HEAP_BLOCK_IUO]] // CHECK: bb1: diff --git a/test/SILGen/objc_witnesses.swift b/test/SILGen/objc_witnesses.swift index f419d9aa03105..618d4245e3cdd 100644 --- a/test/SILGen/objc_witnesses.swift +++ b/test/SILGen/objc_witnesses.swift @@ -30,8 +30,8 @@ class Phoûx : NSObject, Fooable { // CHECK-LABEL: _TFC14objc_witnessesX8Phox_xra3foo // CHECK: bb0([[IN_ADDR:%.*]] : // CHECK: [[STACK_SLOT:%.*]] = alloc_stack $Phoûx -// CHECK: copy_addr [[IN_ADDR]] to [initialization] [[STACK_SLOT]]#1 -// CHECK: [[VALUE:%.*]] = load [[STACK_SLOT]]#1 +// CHECK: copy_addr [[IN_ADDR]] to [initialization] [[STACK_SLOT]] +// CHECK: [[VALUE:%.*]] = load [[STACK_SLOT]] // CHECK: class_method [[VALUE]] : $Phoûx, #Phoûx.foo!1 protocol Bells { @@ -47,15 +47,15 @@ extension Gizmo : Bells { // CHECK: [[INIT:%[0-9]+]] = function_ref @_TFCSo5GizmoC{{.*}} : $@convention(thin) (Int, @thick Gizmo.Type) -> @owned ImplicitlyUnwrappedOptional // CHECK: [[IUO_RESULT:%[0-9]+]] = apply [[INIT]]([[I]], [[META]]) : $@convention(thin) (Int, @thick Gizmo.Type) -> @owned ImplicitlyUnwrappedOptional // CHECK: [[IUO_RESULT_TEMP:%[0-9]+]] = alloc_stack $ImplicitlyUnwrappedOptional -// CHECK: store [[IUO_RESULT]] to [[IUO_RESULT_TEMP]]#1 : $*ImplicitlyUnwrappedOptional +// CHECK: store [[IUO_RESULT]] to [[IUO_RESULT_TEMP]] : $*ImplicitlyUnwrappedOptional // CHECK: [[UNWRAP_FUNC:%[0-9]+]] = function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue // CHECK: [[UNWRAPPED_RESULT_TEMP:%[0-9]+]] = alloc_stack $Gizmo -// CHECK: apply [[UNWRAP_FUNC]]([[UNWRAPPED_RESULT_TEMP]]#1, [[IUO_RESULT_TEMP]]#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in ImplicitlyUnwrappedOptional<τ_0_0>) -> () -// CHECK: [[UNWRAPPED_RESULT:%[0-9]+]] = load [[UNWRAPPED_RESULT_TEMP]]#1 : $*Gizmo +// CHECK: apply [[UNWRAP_FUNC]]([[UNWRAPPED_RESULT_TEMP]], [[IUO_RESULT_TEMP]]) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in ImplicitlyUnwrappedOptional<τ_0_0>) -> () +// CHECK: [[UNWRAPPED_RESULT:%[0-9]+]] = load [[UNWRAPPED_RESULT_TEMP]] : $*Gizmo // CHECK: store [[UNWRAPPED_RESULT]] to [[SELF]] : $*Gizmo -// CHECK: dealloc_stack [[UNWRAPPED_RESULT_TEMP]]#0 : $*@local_storage Gizmo -// CHECK: dealloc_stack [[IUO_RESULT_TEMP]]#0 : $*@local_storage ImplicitlyUnwrappedOptional +// CHECK: dealloc_stack [[UNWRAPPED_RESULT_TEMP]] : $*Gizmo +// CHECK: dealloc_stack [[IUO_RESULT_TEMP]] : $*ImplicitlyUnwrappedOptional // Test extension of a native @objc class to conform to a protocol with a // subscript requirement. rdar://problem/20371661 diff --git a/test/SILGen/optional-cast.swift b/test/SILGen/optional-cast.swift index 5caacee4a12c1..27c030c2663e7 100644 --- a/test/SILGen/optional-cast.swift +++ b/test/SILGen/optional-cast.swift @@ -5,7 +5,7 @@ class B : A {} // CHECK-LABEL: sil hidden @_TF4main3foo -// CHECK: [[X:%.*]] = alloc_box $Optional // var x +// CHECK: [[X:%.*]] = alloc_box $Optional, var, name "x" // Check whether the temporary holds a value. // CHECK: [[T1:%.*]] = select_enum %0 // CHECK-NEXT: cond_br [[T1]], [[IS_PRESENT:bb.*]], [[NOT_PRESENT:bb[0-9]+]] @@ -40,7 +40,7 @@ func foo(y : A?) { } // CHECK-LABEL: sil hidden @_TF4main3bar -// CHECK: [[X:%.*]] = alloc_box $Optional>> // var x +// CHECK: [[X:%.*]] = alloc_box $Optional>>, var, name "x" // Check for Some(...) // CHECK-NEXT: retain_value %0 @@ -103,7 +103,7 @@ func bar(y : A????) { } // CHECK-LABEL: sil hidden @_TF4main3baz -// CHECK: [[X:%.*]] = alloc_box $Optional // var x +// CHECK: [[X:%.*]] = alloc_box $Optional, var, name "x" // CHECK-NEXT: retain_value %0 // CHECK: [[T1:%.*]] = select_enum %0 // CHECK: [[VAL:%.*]] = unchecked_enum_data %0 @@ -118,7 +118,7 @@ func baz(y : AnyObject?) { // CHECK-LABEL: sil hidden @_TF4main18opt_to_opt_trivialFGSqSi_GSQSi_ // CHECK: bb0(%0 : $Optional): -// CHECK-NEXT: debug_value %0 : $Optional // let x +// CHECK-NEXT: debug_value %0 : $Optional, let, name "x" // CHECK-NEXT: %2 = unchecked_trivial_bit_cast %0 : $Optional to $ImplicitlyUnwrappedOptional // CHECK-NEXT: return %2 : $ImplicitlyUnwrappedOptional // CHECK-NEXT:} @@ -128,7 +128,7 @@ func opt_to_opt_trivial(x: Int?) -> Int! { // CHECK-LABEL: sil hidden @_TF4main20opt_to_opt_referenceFGSQCS_1C_GSqS0__ // CHECK: bb0(%0 : $ImplicitlyUnwrappedOptional): -// CHECK-NEXT: debug_value %0 : $ImplicitlyUnwrappedOptional // let x +// CHECK-NEXT: debug_value %0 : $ImplicitlyUnwrappedOptional, let, name "x" // CHECK-NEXT: %2 = unchecked_ref_cast %0 : $ImplicitlyUnwrappedOptional to $Optional // CHECK-NEXT: return %2 : $Optional // CHECK-NEXT:} @@ -136,7 +136,7 @@ func opt_to_opt_reference(x : C!) -> C? { return x } // CHECK-LABEL: sil hidden @_TF4main22opt_to_opt_addressOnly // CHECK: bb0(%0 : $*Optional, %1 : $*ImplicitlyUnwrappedOptional): -// CHECK-NEXT: debug_value_addr %1 : $*ImplicitlyUnwrappedOptional // let x +// CHECK-NEXT: debug_value_addr %1 : $*ImplicitlyUnwrappedOptional, let, name "x" // CHECK-NEXT: %3 = unchecked_addr_cast %0 : $*Optional to $*ImplicitlyUnwrappedOptional // CHECK-NEXT: copy_addr [take] %1 to [initialization] %3 func opt_to_opt_addressOnly(x : T!) -> T? { return x } @@ -149,9 +149,9 @@ public struct TestAddressOnlyStruct { // CHECK-LABEL: sil hidden @_TFV4main21TestAddressOnlyStruct8testCall // CHECK: bb0(%0 : $*ImplicitlyUnwrappedOptional, %1 : $TestAddressOnlyStruct): // CHECK: [[TMPBUF:%.*]] = alloc_stack $Optional - // CHECK: [[TMPCAST:%.*]] = unchecked_addr_cast [[TMPBUF]]#1 + // CHECK: [[TMPCAST:%.*]] = unchecked_addr_cast [[TMPBUF]] // CHECK-NEXT: copy_addr %0 to [initialization] [[TMPCAST]] - // CHECK-NEXT: apply {{.*}}([[TMPBUF]]#1, %1) + // CHECK-NEXT: apply {{.*}}([[TMPBUF]], %1) func testCall(a : T!) { f(a) } @@ -159,8 +159,8 @@ public struct TestAddressOnlyStruct { // CHECK-LABEL: sil hidden @_TF4main35testContextualInitOfNonAddrOnlyTypeFGSqSi_T_ // CHECK: bb0(%0 : $Optional): -// CHECK-NEXT: debug_value %0 : $Optional // let a -// CHECK-NEXT: %2 = alloc_box $ImplicitlyUnwrappedOptional // var x +// CHECK-NEXT: debug_value %0 : $Optional, let, name "a" +// CHECK-NEXT: %2 = alloc_box $ImplicitlyUnwrappedOptional, var, name "x" // CHECK-NEXT: %3 = unchecked_addr_cast %2#1 : $*ImplicitlyUnwrappedOptional to $*Optional // CHECK-NEXT: store %0 to %3 : $*Optional // CHECK-NEXT: strong_release %2#0 : $@box ImplicitlyUnwrappedOptional diff --git a/test/SILGen/optional.swift b/test/SILGen/optional.swift index 16d677af5ff27..32d085204ca08 100644 --- a/test/SILGen/optional.swift +++ b/test/SILGen/optional.swift @@ -1,6 +1,6 @@ // RUN: %target-swift-frontend -emit-silgen %s | FileCheck %s -func testCall(f: (()->())?) { +func testCall(f: (() -> ())?) { f?() } // CHECK: sil hidden @{{.*}}testCall{{.*}} @@ -23,16 +23,16 @@ func testCall(f: (()->())?) { // CHECK-NEXT: enum $Optional<()>, #Optional.None!enumelt // CHECK-NEXT: br bb2 -func testAddrOnlyCallResult(f: (()->T)?) { +func testAddrOnlyCallResult(f: (() -> T)?) { var f = f var x = f?() } // CHECK-LABEL: sil hidden @{{.*}}testAddrOnlyCallResult{{.*}} : $@convention(thin) (@owned Optional<() -> T>) -> () // CHECK: bb0([[T0:%.*]] : $Optional<() -> T>): -// CHECK: [[F:%.*]] = alloc_box $Optional<() -> T> // var f +// CHECK: [[F:%.*]] = alloc_box $Optional<() -> T>, var, name "f" // CHECK-NEXT: retain_value [[T0]] // CHECK-NEXT: store [[T0]] to [[F]]#1 -// CHECK-NEXT: [[X:%.*]] = alloc_box $Optional // var x +// CHECK-NEXT: [[X:%.*]] = alloc_box $Optional, var, name "x" // CHECK-NEXT: [[TEMP:%.*]] = init_enum_data_addr [[X]] // Check whether 'f' holds a value. // CHECK: [[T1:%.*]] = select_enum_addr [[F]]#1 diff --git a/test/SILGen/partial_apply_super.swift b/test/SILGen/partial_apply_super.swift index bd97cdc422e80..b1bdaa671cb28 100644 --- a/test/SILGen/partial_apply_super.swift +++ b/test/SILGen/partial_apply_super.swift @@ -1,41 +1,96 @@ -// RUN: %target-swift-frontend -emit-silgen %s | FileCheck %s +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: %target-swift-frontend -emit-module -emit-module-path=%t/resilient_class.swiftmodule -module-name resilient_class %S/../Inputs/resilient_class.swift +// RUN: %target-swift-frontend -use-native-super-method -emit-silgen -parse-as-library -I %t %s | FileCheck %s -class B { - func foo() { } - func bar()() { } +import resilient_class + +func doFoo(f: () -> ()) { + f() } -class D: B { - override func foo() { } - override func bar()() { } +public class Parent { + public init() {} + public func method() {} + public final func finalMethod() {} + public class func classMethod() {} + public final class func finalClassMethod() {} +} - // CHECK-LABEL: sil hidden @_TFC19partial_apply_super1D7getFoos - // CHECK: function_ref @_TFC19partial_apply_super1D3foo - // CHECK: function_ref @_TTdFC19partial_apply_super1B3foo - func getFoos() -> (() -> (), () -> ()) { - return (self.foo, super.foo) +public class GenericParent { + let a: A + public init(a: A) { + self.a = a } + public func method() {} + public final func finalMethod() {} + public class func classMethod() {} + public final class func finalClassMethod() {} +} - // CHECK-LABEL: sil shared @_TFC19partial_apply_super1D3foo - // CHECK: class_method %0 : $D, #D.foo!1 +class Child : Parent { + // CHECK-LABEL: sil hidden @_TFC19partial_apply_super5Child6methodfT_T_ : $@convention(method) (@guaranteed Child) -> () + // CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () + // CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $Child to $Parent + // CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $Child, #Parent.method!1 : (Parent) -> () -> () , $@convention(method) (@guaranteed Parent) -> () + // CHECK: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@guaranteed Parent) -> () + // CHECK: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> () + override func method() { + doFoo(super.method) + } - // CHECK-LABEL: sil shared @_TTdFC19partial_apply_super1B3foo - // CHECK: function_ref @_TFC19partial_apply_super1B3foo + // CHECK-LABEL: sil hidden @_TZFC19partial_apply_super5Child11classMethodfT_T_ : $@convention(thin) (@thick Child.Type) -> () { + // CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () + // CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $@thick Child.Type to $@thick Parent.Type + // CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $@thick Child.Type, #Parent.classMethod!1 : (Parent.Type) -> () -> () , $@convention(thin) (@thick Parent.Type) -> () + // CHECK: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@thick Parent.Type) -> () + // CHECK: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> () + override class func classMethod() { + doFoo(super.classMethod) + } - // CHECK-LABEL: sil hidden @_TFC19partial_apply_super1D7getBars - // CHECK: function_ref @_TFC19partial_apply_super1D3bar - // CHECK: function_ref @_TTdFC19partial_apply_super1B3bar - func getBars() -> (() -> () -> (), () -> () -> ()) { - return (self.bar, super.bar) + // CHECK-LABEL: sil hidden @_TFC19partial_apply_super5Child20callFinalSuperMethodfT_T_ : $@convention(method) (@guaranteed Child) -> () + // CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () + // CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $Child to $Parent + // CHECK: [[SUPER_METHOD:%[0-9]+]] = function_ref @_TFC19partial_apply_super6Parent11finalMethodFT_T_ : $@convention(thin) (@owned Parent) -> @owned @callee_owned () -> () + // CHECK: [[APPLIED_SELF:%[0-9]+]] = apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@owned Parent) -> @owned @callee_owned () -> () + // CHECK: apply [[DOFOO]]([[APPLIED_SELF]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> () + func callFinalSuperMethod() { + doFoo(super.finalMethod) } - // CHECK-LABEL: sil shared @_TFC19partial_apply_super1D3bar - // CHECK: function_ref @_TFC19partial_apply_super1D3bar - // CHECK-LABEL: sil shared @_TFC19partial_apply_super1D3bar - // CHECK: class_method %0 : $D, #D.bar!2 + // CHECK-LABEL: sil hidden @_TZFC19partial_apply_super5Child25callFinalSuperClassMethodfT_T_ : $@convention(thin) (@thick Child.Type) -> () + // CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () + // CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $@thick Child.Type to $@thick Parent.Type + // CHECK: [[SUPER_METHOD:%[0-9]+]] = function_ref @_TZFC19partial_apply_super6Parent16finalClassMethodFT_T_ : $@convention(thin) (@thick Parent.Type) -> @owned @callee_owned () -> () + // CHECK: [[APPLIED_SELF:%[0-9]+]] = apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@thick Parent.Type) -> @owned @callee_owned () -> () + // CHECK: apply [[DOFOO]]([[APPLIED_SELF]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> () + class func callFinalSuperClassMethod() { + doFoo(super.finalClassMethod) + } +} - // CHECK-LABEL: sil shared @_TTdFC19partial_apply_super1B3bar - // CHECK: function_ref @_TTdFC19partial_apply_super1B3bar - // CHECK-LABEL: sil shared @_TTdFC19partial_apply_super1B3bar - // CHECK: function_ref @_TFC19partial_apply_super1B3bar +class GenericChild : GenericParent { + override init(a: A) { + super.init(a: a) + } + // CHECK-LABEL: sil hidden @_TFC19partial_apply_super12GenericChild6methodfT_T_ : $@convention(method) (@guaranteed GenericChild) -> () + // CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () + // CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $GenericChild to $GenericParent + // CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $GenericChild, #GenericParent.method!1 : (GenericParent) -> () -> () , $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> () + // CHECK: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> () + // CHECK: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> () + override func method() { + doFoo(super.method) + } + + // CHECK-LABEL: sil hidden @_TZFC19partial_apply_super12GenericChild11classMethodfT_T_ : $@convention(thin) (@thick GenericChild.Type) -> () + // CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () + // CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $@thick GenericChild.Type to $@thick GenericParent.Type + // CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $@thick GenericChild.Type, #GenericParent.classMethod!1 : (GenericParent.Type) -> () -> () , $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> () + // CHECK: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply %4(%3) : $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> () + // CHECK: apply %2(%5) : $@convention(thin) (@owned @callee_owned () -> ()) -> () + override class func classMethod() { + doFoo(super.classMethod) + } } diff --git a/test/SILGen/pointer_conversion.swift b/test/SILGen/pointer_conversion.swift index 69f66a27ac51b..c824249035c51 100644 --- a/test/SILGen/pointer_conversion.swift +++ b/test/SILGen/pointer_conversion.swift @@ -45,8 +45,8 @@ func arrayToPointer() { takesMutablePointer(&ints) // CHECK: [[TAKES_MUTABLE_POINTER:%.*]] = function_ref @_TF18pointer_conversion19takesMutablePointer // CHECK: [[CONVERT_MUTABLE:%.*]] = function_ref @_TFs37_convertMutableArrayToPointerArgument - // CHECK: apply [[CONVERT_MUTABLE]]>([[TUPLE_BUF:%.*]]#1, - // CHECK: [[TUPLE:%.*]] = load [[TUPLE_BUF]]#1 + // CHECK: apply [[CONVERT_MUTABLE]]>([[TUPLE_BUF:%[0-9]*]], + // CHECK: [[TUPLE:%.*]] = load [[TUPLE_BUF]] // CHECK: [[OWNER:%.*]] = tuple_extract [[TUPLE]] : ${{.*}}, 0 // CHECK: [[POINTER:%.*]] = tuple_extract [[TUPLE]] : ${{.*}}, 1 // CHECK: apply [[TAKES_MUTABLE_POINTER]]([[POINTER]]) @@ -55,8 +55,8 @@ func arrayToPointer() { takesConstPointer(ints) // CHECK: [[TAKES_CONST_POINTER:%.*]] = function_ref @_TF18pointer_conversion17takesConstPointerFGSPSi_T_ // CHECK: [[CONVERT_CONST:%.*]] = function_ref @_TFs35_convertConstArrayToPointerArgument - // CHECK: apply [[CONVERT_CONST]]>([[TUPLE_BUF:%.*]]#1, - // CHECK: [[TUPLE:%.*]] = load [[TUPLE_BUF]]#1 + // CHECK: apply [[CONVERT_CONST]]>([[TUPLE_BUF:%[0-9]*]], + // CHECK: [[TUPLE:%.*]] = load [[TUPLE_BUF]] // CHECK: [[OWNER:%.*]] = tuple_extract [[TUPLE]] : ${{.*}}, 0 // CHECK: [[POINTER:%.*]] = tuple_extract [[TUPLE]] : ${{.*}}, 1 // CHECK: apply [[TAKES_CONST_POINTER]]([[POINTER]]) @@ -68,8 +68,8 @@ func stringToPointer(s: String) { takesConstVoidPointer(s) // CHECK: [[TAKES_CONST_VOID_POINTER:%.*]] = function_ref @_TF18pointer_conversion21takesConstVoidPointerFGSPT__T_ // CHECK: [[CONVERT_STRING:%.*]] = function_ref @_TFs40_convertConstStringToUTF8PointerArgument - // CHECK: apply [[CONVERT_STRING]]>([[TUPLE_BUF:%.*]]#1, - // CHECK: [[TUPLE:%.*]] = load [[TUPLE_BUF]]#1 + // CHECK: apply [[CONVERT_STRING]]>([[TUPLE_BUF:%[0-9]*]], + // CHECK: [[TUPLE:%.*]] = load [[TUPLE_BUF]] // CHECK: [[OWNER:%.*]] = tuple_extract [[TUPLE]] : ${{.*}}, 0 // CHECK: [[POINTER:%.*]] = tuple_extract [[TUPLE]] : ${{.*}}, 1 // CHECK: apply [[TAKES_CONST_VOID_POINTER]]([[POINTER]]) @@ -82,7 +82,7 @@ func inoutToPointer() { // CHECK: [[INT:%.*]] = alloc_box $Int takesMutablePointer(&int) // CHECK: [[TAKES_MUTABLE:%.*]] = function_ref @_TF18pointer_conversion19takesMutablePointer - // CHECK: [[POINTER:%.*]] = address_to_pointer [[INT]]#1 + // CHECK: [[POINTER:%.*]] = address_to_pointer [[INT]] // CHECK: [[CONVERT:%.*]] = function_ref @_TFs30_convertInOutToPointerArgument // CHECK: apply [[CONVERT]]>({{%.*}}, [[POINTER]]) // CHECK: apply [[TAKES_MUTABLE]] @@ -114,7 +114,7 @@ func classInoutToPointer() { // CHECK: [[VAR:%.*]] = alloc_box $C takesPlusOnePointer(&c) // CHECK: [[TAKES_PLUS_ONE:%.*]] = function_ref @_TF18pointer_conversion19takesPlusOnePointer - // CHECK: [[POINTER:%.*]] = address_to_pointer [[INT]]#1 + // CHECK: [[POINTER:%.*]] = address_to_pointer [[INT]] // CHECK: [[CONVERT:%.*]] = function_ref @_TFs30_convertInOutToPointerArgument // CHECK: apply [[CONVERT]]>({{%.*}}, [[POINTER]]) // CHECK: apply [[TAKES_PLUS_ONE]] @@ -153,6 +153,6 @@ func functionInoutToPointer() { var f: () -> () = {} // CHECK: [[REABSTRACT_BUF:%.*]] = alloc_stack $@callee_owned (@out (), @in ()) -> () - // CHECK: address_to_pointer [[REABSTRACT_BUF]]#1 + // CHECK: address_to_pointer [[REABSTRACT_BUF]] takesMutableVoidPointer(&f) } diff --git a/test/SILGen/properties.swift b/test/SILGen/properties.swift index cf553df07ceee..24878016beb6e 100644 --- a/test/SILGen/properties.swift +++ b/test/SILGen/properties.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -parse-as-library -emit-silgen -disable-objc-attr-requires-foundation-module %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -parse-as-library -emit-silgen -disable-objc-attr-requires-foundation-module %s | FileCheck %s var zero: Int = 0 @@ -113,7 +113,7 @@ func physical_struct_lvalue(c: Int) { r.y = a // strong_retain %0 : $RefSubclass // CHECK: [[R_SUP:%[0-9]+]] = upcast %0 : $RefSubclass to $Ref - // CHECK: [[FN:%[0-9]+]] = class_method [[R_SUP]] : $Ref, #Ref.y!setter.1 : Ref -> (Int) -> () , $@convention(method) (Int, @guaranteed Ref) -> () + // CHECK: [[FN:%[0-9]+]] = class_method [[R_SUP]] : $Ref, #Ref.y!setter.1 : (Ref) -> (Int) -> () , $@convention(method) (Int, @guaranteed Ref) -> () // CHECK: apply [[FN]](%1, [[R_SUP]]) : // CHECK: strong_release [[R_SUP]] r.w = a @@ -191,9 +191,9 @@ func logical_struct_in_reftype_set(inout value: Val, z1: Int) { // -- val.ref.val_prop // CHECK: [[STORAGE:%.*]] = alloc_stack $Builtin.UnsafeValueBuffer // CHECK: [[VAL_REF_VAL_PROP_TEMP:%.*]] = alloc_stack $Val - // CHECK: [[T0:%.*]] = address_to_pointer [[VAL_REF_VAL_PROP_TEMP]]#1 : $*Val to $Builtin.RawPointer - // CHECK: [[MAT_VAL_PROP_METHOD:%[0-9]+]] = class_method {{.*}} : $Ref, #Ref.val_prop!materializeForSet.1 : Ref -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, (@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Ref, @thick Ref.Type) -> ())?) - // CHECK: [[MAT_RESULT:%[0-9]+]] = apply [[MAT_VAL_PROP_METHOD]]([[T0]], [[STORAGE]]#1, [[VAL_REF]]) + // CHECK: [[T0:%.*]] = address_to_pointer [[VAL_REF_VAL_PROP_TEMP]] : $*Val to $Builtin.RawPointer + // CHECK: [[MAT_VAL_PROP_METHOD:%[0-9]+]] = class_method {{.*}} : $Ref, #Ref.val_prop!materializeForSet.1 : (Ref) -> (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer) -> (Builtin.RawPointer, (@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Ref, @thick Ref.Type) -> ())?) + // CHECK: [[MAT_RESULT:%[0-9]+]] = apply [[MAT_VAL_PROP_METHOD]]([[T0]], [[STORAGE]], [[VAL_REF]]) // CHECK: [[T0:%.*]] = tuple_extract [[MAT_RESULT]] : $(Builtin.RawPointer, Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Ref, @thick Ref.Type) -> ()>), 0 // CHECK: [[T1:%[0-9]+]] = pointer_to_address [[T0]] : $Builtin.RawPointer to $*Val // CHECK: [[OPT_CALLBACK:%.*]] = tuple_extract [[MAT_RESULT]] : $(Builtin.RawPointer, Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Ref, @thick Ref.Type) -> ()>), 1 @@ -204,27 +204,27 @@ func logical_struct_in_reftype_set(inout value: Val, z1: Int) { // -- val.ref.val_prop.z_tuple // CHECK: [[GET_Z_TUPLE_METHOD:%[0-9]+]] = function_ref @_TFV10properties3Valg7z_tupleT // CHECK: [[V_R_VP_Z_TUPLE:%[0-9]+]] = apply [[GET_Z_TUPLE_METHOD]]([[LD]]) - // CHECK: store [[V_R_VP_Z_TUPLE]] to [[V_R_VP_Z_TUPLE_MAT]]#1 + // CHECK: store [[V_R_VP_Z_TUPLE]] to [[V_R_VP_Z_TUPLE_MAT]] // -- write to val.ref.val_prop.z_tuple.1 - // CHECK: [[V_R_VP_Z_TUPLE_1:%[0-9]+]] = tuple_element_addr [[V_R_VP_Z_TUPLE_MAT]]#1 : {{.*}}, 1 + // CHECK: [[V_R_VP_Z_TUPLE_1:%[0-9]+]] = tuple_element_addr [[V_R_VP_Z_TUPLE_MAT]] : {{.*}}, 1 // CHECK: assign [[Z1]] to [[V_R_VP_Z_TUPLE_1]] // -- writeback to val.ref.val_prop.z_tuple - // CHECK: [[WB_V_R_VP_Z_TUPLE:%[0-9]+]] = load [[V_R_VP_Z_TUPLE_MAT]]#1 + // CHECK: [[WB_V_R_VP_Z_TUPLE:%[0-9]+]] = load [[V_R_VP_Z_TUPLE_MAT]] // CHECK: [[SET_Z_TUPLE_METHOD:%[0-9]+]] = function_ref @_TFV10properties3Vals7z_tupleT // CHECK: apply [[SET_Z_TUPLE_METHOD]]({{%[0-9]+, %[0-9]+}}, [[VAL_REF_VAL_PROP_MAT]]) // -- writeback to val.ref.val_prop // CHECK: switch_enum [[OPT_CALLBACK]] : $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Ref, @thick Ref.Type) -> ()>, case #Optional.Some!enumelt.1: [[WRITEBACK:bb[0-9]+]], case #Optional.None!enumelt: [[CONT:bb[0-9]+]] // CHECK: [[WRITEBACK]]([[CALLBACK:%.*]] : $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout Ref, @thick Ref.Type) -> ()): // CHECK: [[REF_MAT:%.*]] = alloc_stack $Ref - // CHECK: store [[VAL_REF]] to [[REF_MAT]]#1 + // CHECK: store [[VAL_REF]] to [[REF_MAT]] // CHECK: [[T0:%.*]] = metatype $@thick Ref.Type // CHECK: [[T1:%.*]] = address_to_pointer [[VAL_REF_VAL_PROP_MAT]] - // CHECK: apply [[CALLBACK]]([[T1]], [[STORAGE]]#1, [[REF_MAT]]#1, [[T0]]) + // CHECK: apply [[CALLBACK]]([[T1]], [[STORAGE]], [[REF_MAT]], [[T0]]) // CHECK: br [[CONT]] // CHECK: [[CONT]]: // -- cleanup - // CHECK: dealloc_stack [[V_R_VP_Z_TUPLE_MAT]]#0 - // CHECK: dealloc_stack [[VAL_REF_VAL_PROP_TEMP]]#0 + // CHECK: dealloc_stack [[V_R_VP_Z_TUPLE_MAT]] + // CHECK: dealloc_stack [[VAL_REF_VAL_PROP_TEMP]] // -- don't need to write back to val.ref because it's a ref type } @@ -245,13 +245,13 @@ func tuple_in_logical_struct_set(inout value: Val, z1: Int) { // CHECK: retain_value [[VAL1]] // CHECK: [[Z_GET_METHOD:%[0-9]+]] = function_ref @_TFV10properties3Valg7z_tupleT // CHECK: [[Z_TUPLE:%[0-9]+]] = apply [[Z_GET_METHOD]]([[VAL1]]) - // CHECK: store [[Z_TUPLE]] to [[Z_TUPLE_MATERIALIZED]]#1 - // CHECK: [[Z_TUPLE_1:%[0-9]+]] = tuple_element_addr [[Z_TUPLE_MATERIALIZED]]#1 : {{.*}}, 1 + // CHECK: store [[Z_TUPLE]] to [[Z_TUPLE_MATERIALIZED]] + // CHECK: [[Z_TUPLE_1:%[0-9]+]] = tuple_element_addr [[Z_TUPLE_MATERIALIZED]] : {{.*}}, 1 // CHECK: assign [[Z1]] to [[Z_TUPLE_1]] - // CHECK: [[Z_TUPLE_MODIFIED:%[0-9]+]] = load [[Z_TUPLE_MATERIALIZED]]#1 + // CHECK: [[Z_TUPLE_MODIFIED:%[0-9]+]] = load [[Z_TUPLE_MATERIALIZED]] // CHECK: [[Z_SET_METHOD:%[0-9]+]] = function_ref @_TFV10properties3Vals7z_tupleT // CHECK: apply [[Z_SET_METHOD]]({{%[0-9]+, %[0-9]+}}, [[VAL_LOCAL]]#1) - // CHECK: dealloc_stack [[Z_TUPLE_MATERIALIZED]]#0 + // CHECK: dealloc_stack [[Z_TUPLE_MATERIALIZED]] // CHECK: return } @@ -526,7 +526,7 @@ struct DidSetWillSetTests: ForceAccessors { // CHECK-NEXT: [[AADDR:%.*]] = struct_element_addr [[SELFBOX:%.*]]#1 : $*DidSetWillSetTests, #DidSetWillSetTests.a // CHECK-NEXT: [[OLDVAL:%.*]] = load [[AADDR]] : $*Int - // CHECK-NEXT: debug_value [[OLDVAL]] : $Int // let tmp + // CHECK-NEXT: debug_value [[OLDVAL]] : $Int, let, name "tmp" // CHECK-NEXT: // function_ref {{.*}}.DidSetWillSetTests.a.willset : Swift.Int // CHECK-NEXT: [[WILLSETFN:%.*]] = function_ref @_TFV10properties18DidSetWillSetTestsw1a @@ -638,7 +638,7 @@ class rdar16151899Derived : rdar16151899Base { override init() { super.init() // CHECK: upcast {{.*}} : $rdar16151899Derived to $rdar16151899Base - // CHECK-NEXT: function_ref properties.rdar16151899Base.init + // CHECK-NEXT: super_method {{%[0-9]+}} : $rdar16151899Derived, #rdar16151899Base.init!initializer.1 // This should not be a direct access, it should call the setter in the // base. @@ -646,7 +646,7 @@ class rdar16151899Derived : rdar16151899Base { // CHECK: [[BASEPTR:%[0-9]+]] = upcast {{.*}} : $rdar16151899Derived to $rdar16151899Base // CHECK: load{{.*}}Int - // CHECK-NEXT: [[SETTER:%[0-9]+]] = class_method {{.*}} : $rdar16151899Base, #rdar16151899Base.x!setter.1 : rdar16151899Base + // CHECK-NEXT: [[SETTER:%[0-9]+]] = class_method {{.*}} : $rdar16151899Base, #rdar16151899Base.x!setter.1 : (rdar16151899Base) // CHECK-NEXT: apply [[SETTER]]({{.*}}, [[BASEPTR]]) } } @@ -667,19 +667,21 @@ func propertyWithDidSetTakingOldValue() { // CHECK: // properties.(propertyWithDidSetTakingOldValue () -> ()).(p #1).setter : Swift.Int // CHECK-NEXT: sil {{.*}} @_TFF10properties32propertyWithDidSetTakingOldValue -// CHECK: bb0(%0 : $Int, %1 : $@box Int, %2 : $*Int): -// CHECK-NEXT: debug_value %0 : $Int // let newValue, argno: 1 -// CHECK-NEXT: debug_value_addr %2 : $*Int // var p, argno: 2 -// CHECK-NEXT: %5 = load %2 : $*Int +// CHECK: bb0(%0 : $Int, %1 : $@box Int): +// CHECK-NEXT: debug_value %0 : $Int, let, name "newValue", argno 1 +// CHECK-NEXT: %3 = project_box %1 +// CHECK-NEXT: debug_value_addr %3 : $*Int, var, name "p", argno 2 +// CHECK-NEXT: %5 = load %3 : $*Int // CHECK-NEXT: debug_value %5 : $Int -// CHECK-NEXT: assign %0 to %2 : $*Int +// CHECK-NEXT: assign %0 to %3 : $*Int // CHECK-NEXT: strong_retain %1 : $@box Int +// CHECK-NEXT: mark_function_escape %3 // CHECK-NEXT: // function_ref -// CHECK-NEXT: %9 = function_ref @_TFF10properties32propertyWithDidSetTakingOldValueFT_T_WL_1pSi : $@convention(thin) (Int, @owned @box Int, @inout Int) -> () -// CHECK-NEXT: %10 = apply %9(%5, %1, %2) : $@convention(thin) (Int, @owned @box Int, @inout Int) -> () +// CHECK-NEXT: %10 = function_ref @_TFF10properties32propertyWithDidSetTakingOldValueFT_T_WL_1pSi : $@convention(thin) (Int, @owned @box Int) -> () +// CHECK-NEXT: %11 = apply %10(%5, %1) : $@convention(thin) (Int, @owned @box Int) -> () // CHECK-NEXT: strong_release %1 : $@box Int -// CHECK-NEXT: %12 = tuple () -// CHECK-NEXT: return %12 : $() +// CHECK-NEXT: %13 = tuple () +// CHECK-NEXT: return %13 : $() // CHECK-NEXT:} @@ -700,8 +702,7 @@ class DerivedProperty : BaseProperty { // CHECK: sil hidden @_TFC10properties15DerivedProperty24super_property_reference // CHECK: bb0(%0 : $DerivedProperty): // CHECK: [[BASEPTR:%[0-9]+]] = upcast %0 : $DerivedProperty to $BaseProperty -// CHECK: // function_ref properties.BaseProperty.x.getter -// CHECK: [[FN:%[0-9]+]] = function_ref @_TFC10properties12BasePropertyg1x +// CHECK: [[FN:%[0-9]+]] = super_method %0 : $DerivedProperty, #BaseProperty.x!getter.1 // CHECK: apply [[FN]]([[BASEPTR]]) : $@convention(method) (@guaranteed BaseProperty) -> Int // user: %7 @@ -963,11 +964,11 @@ func addressOnlyNonmutatingProperty(x: AddressOnlyNonmutatingSet) } // CHECK-LABEL: sil hidden @_TF10properties30addressOnlyNonmutatingProperty // CHECK: [[SET:%.*]] = function_ref @_TFV10properties25AddressOnlyNonmutatingSets4propSi -// CHECK: apply [[SET]]({{%.*}}, [[TMP:%.*]]#1) +// CHECK: apply [[SET]]({{%.*}}, [[TMP:%[0-9]*]]) // CHECK: destroy_addr [[TMP]] // CHECK: dealloc_stack [[TMP]] // CHECK: [[GET:%.*]] = function_ref @_TFV10properties25AddressOnlyNonmutatingSetg4propSi -// CHECK: apply [[GET]]([[TMP:%.*]]#1) +// CHECK: apply [[GET]]([[TMP:%[0-9]*]]) // CHECK: destroy_addr [[TMP]] // CHECK: dealloc_stack [[TMP]] @@ -980,9 +981,9 @@ struct AddressOnlyReadOnlySubscript { // CHECK-LABEL: sil hidden @_TF10properties43addressOnlyReadOnlySubscriptFromMutableBase // CHECK: [[BASE:%.*]] = alloc_box $AddressOnlyReadOnlySubscript -// CHECK: copy_addr [[BASE:%.*]]#1 to [initialization] [[COPY:%.*]]#1 +// CHECK: copy_addr [[BASE:%.*]] to [initialization] [[COPY:%.*]] : // CHECK: [[GETTER:%.*]] = function_ref @_TFV10properties28AddressOnlyReadOnlySubscriptg9subscript -// CHECK: apply [[GETTER]]({{%.*}}, [[COPY]]#1) +// CHECK: apply [[GETTER]]({{%.*}}, [[COPY]]) func addressOnlyReadOnlySubscriptFromMutableBase(x: Int) { var base = AddressOnlyReadOnlySubscript() _ = base[x] @@ -997,7 +998,7 @@ struct MutatingGetterStruct { } // CHECK-LABEL: sil hidden @_TZFV10properties20MutatingGetterStruct4test - // CHECK: [[X:%.*]] = alloc_box $MutatingGetterStruct // var x + // CHECK: [[X:%.*]] = alloc_box $MutatingGetterStruct, var, name "x" // CHECK: store {{.*}} to [[X]]#1 : $*MutatingGetterStruct // CHECK: apply {{%.*}}([[X]]#1) : $@convention(method) (@inout MutatingGetterStruct) -> Int static func test() { diff --git a/test/SILGen/property_abstraction.swift b/test/SILGen/property_abstraction.swift index 513f13f78d470..5fbfc092f5232 100644 --- a/test/SILGen/property_abstraction.swift +++ b/test/SILGen/property_abstraction.swift @@ -40,7 +40,7 @@ func inOutFunc(inout f: (Int -> Int)) { } // CHECK: [[REABSTRACT_FN:%.*]] = function_ref @_TTR // CHECK: [[F_SUBST_IN:%.*]] = partial_apply [[REABSTRACT_FN]]([[F_ORIG]]) // CHECK: store [[F_SUBST_IN]] to [[F_SUBST_MAT]] -// CHECK: apply [[INOUTFUNC]]([[F_SUBST_MAT]]#1) +// CHECK: apply [[INOUTFUNC]]([[F_SUBST_MAT]]) // CHECK: [[F_SUBST_OUT:%.*]] = load [[F_SUBST_MAT]] // CHECK: [[REABSTRACT_FN:%.*]] = function_ref @_TTR // CHECK: [[F_ORIG:%.*]] = partial_apply [[REABSTRACT_FN]]([[F_SUBST_OUT]]) diff --git a/test/SILGen/protocol_class_refinement.swift b/test/SILGen/protocol_class_refinement.swift index 6abd8538cd24b..687cc2b8921a1 100644 --- a/test/SILGen/protocol_class_refinement.swift +++ b/test/SILGen/protocol_class_refinement.swift @@ -33,9 +33,9 @@ func getObjectUID(x: T) -> (Int, Int, Int, Int) { // CHECK: [[X:%.*]] = load [[XBOX]] // CHECK: strong_retain [[X]] // CHECK: [[X_TMP:%.*]] = alloc_stack - // CHECK: store [[X]] to [[X_TMP]]#1 + // CHECK: store [[X]] to [[X_TMP]] // CHECK: [[GET_UID:%.*]] = witness_method $T, #UID.uid!1 - // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]#1) + // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]) // CHECK: [[X2:%.*]] = load [[X_TMP]] // CHECK: strong_release [[X2]] // -- call set x.clsid @@ -47,9 +47,9 @@ func getObjectUID(x: T) -> (Int, Int, Int, Int) { // CHECK: [[X:%.*]] = load [[XBOX]] // CHECK: strong_retain [[X]] // CHECK: [[X_TMP:%.*]] = alloc_stack - // CHECK: store [[X]] to [[X_TMP]]#1 + // CHECK: store [[X]] to [[X_TMP]] // CHECK: [[GET_UID:%.*]] = witness_method $T, #UID.uid!1 - // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]#1) + // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]) // CHECK: [[X2:%.*]] = load [[X_TMP]] // CHECK: strong_release [[X2]] // -- call nextCLSID from protocol ext @@ -63,9 +63,9 @@ func getObjectUID(x: T) -> (Int, Int, Int, Int) { // CHECK: [[X:%.*]] = load [[XBOX]] // CHECK: strong_retain [[X]] // CHECK: [[X_TMP:%.*]] = alloc_stack - // CHECK: store [[X]] to [[X_TMP]]#1 + // CHECK: store [[X]] to [[X_TMP]] // CHECK: [[GET_UID:%.*]] = witness_method $T, #UID.uid!1 - // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]#1) + // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]) // CHECK: [[X2:%.*]] = load [[X_TMP]] // CHECK: strong_release [[X2]] // -- call secondNextCLSID from class-constrained protocol ext @@ -84,9 +84,9 @@ func getBaseObjectUID(x: T) -> (Int, Int, Int) { // CHECK: [[X:%.*]] = load [[XBOX]] // CHECK: strong_retain [[X]] // CHECK: [[X_TMP:%.*]] = alloc_stack - // CHECK: store [[X]] to [[X_TMP]]#1 + // CHECK: store [[X]] to [[X_TMP]] // CHECK: [[GET_UID:%.*]] = witness_method $T, #UID.uid!1 - // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]#1) + // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]) // CHECK: [[X2:%.*]] = load [[X_TMP]] // CHECK: strong_release [[X2]] // -- call set x.clsid @@ -98,9 +98,9 @@ func getBaseObjectUID(x: T) -> (Int, Int, Int) { // CHECK: [[X:%.*]] = load [[XBOX]] // CHECK: strong_retain [[X]] // CHECK: [[X_TMP:%.*]] = alloc_stack - // CHECK: store [[X]] to [[X_TMP]]#1 + // CHECK: store [[X]] to [[X_TMP]] // CHECK: [[GET_UID:%.*]] = witness_method $T, #UID.uid!1 - // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]#1) + // CHECK: [[UID:%.*]] = apply [[GET_UID]]([[X_TMP]]) // CHECK: [[X2:%.*]] = load [[X_TMP]] // CHECK: strong_release [[X2]] // -- call nextCLSID from protocol ext diff --git a/test/SILGen/protocol_extensions.swift b/test/SILGen/protocol_extensions.swift index 242f120ca99b6..015a270152539 100644 --- a/test/SILGen/protocol_extensions.swift +++ b/test/SILGen/protocol_extensions.swift @@ -101,9 +101,9 @@ func testD(m: MetaHolder, dd: D.Type, d: D) { // CHECK: [[D2:%[0-9]+]] = alloc_box $D // CHECK: [[FN:%[0-9]+]] = function_ref @_TFE19protocol_extensionsPS_2P111returnsSelf{{.*}} // CHECK: [[DCOPY:%[0-9]+]] = alloc_stack $D - // CHECK: store [[D]] to [[DCOPY]]#1 : $*D + // CHECK: store [[D]] to [[DCOPY]] : $*D // CHECK: [[RESULT:%[0-9]+]] = alloc_stack $D - // CHECK: apply [[FN]]([[RESULT]]#1, [[DCOPY]]#1) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@out τ_0_0, @in_guaranteed τ_0_0) -> () + // CHECK: apply [[FN]]([[RESULT]], [[DCOPY]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@out τ_0_0, @in_guaranteed τ_0_0) -> () var d2: D = d.returnsSelf() // CHECK: metatype $@thick D.Type @@ -510,18 +510,18 @@ func testExistentials1(p1: P1, b: Bool, i: Int64) { p1.curried1(b)(i) // CHECK: [[POPENED:%[0-9]+]] = open_existential_addr [[P]] : $*P1 to $*@opened([[UUID:".*"]]) P1 - // CHECK: copy_addr [[POPENED]] to [initialization] [[POPENED_COPY:%.*]]#1 + // CHECK: copy_addr [[POPENED]] to [initialization] [[POPENED_COPY:%.*]] : // CHECK: [[GETTER:%[0-9]+]] = function_ref @_TFE19protocol_extensionsPS_2P1g9subscriptFVs5Int64Sb - // CHECK: apply [[GETTER]]<@opened([[UUID]]) P1>([[I]], [[POPENED_COPY]]#1) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (Int64, @in_guaranteed τ_0_0) -> Bool - // CHECK: destroy_addr [[POPENED_COPY]]#1 + // CHECK: apply [[GETTER]]<@opened([[UUID]]) P1>([[I]], [[POPENED_COPY]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (Int64, @in_guaranteed τ_0_0) -> Bool + // CHECK: destroy_addr [[POPENED_COPY]] // CHECK: store{{.*}} : $*Bool // CHECK: dealloc_stack [[POPENED_COPY]] var b2 = p1[i] // CHECK: [[POPENED:%[0-9]+]] = open_existential_addr [[P]] : $*P1 to $*@opened([[UUID:".*"]]) P1 - // CHECK: copy_addr [[POPENED]] to [initialization] [[POPENED_COPY:%.*]]#1 + // CHECK: copy_addr [[POPENED]] to [initialization] [[POPENED_COPY:%.*]] : // CHECK: [[GETTER:%[0-9]+]] = function_ref @_TFE19protocol_extensionsPS_2P1g4propSb - // CHECK: apply [[GETTER]]<@opened([[UUID]]) P1>([[POPENED_COPY]]#1) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> Bool + // CHECK: apply [[GETTER]]<@opened([[UUID]]) P1>([[POPENED_COPY]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> Bool // CHECK: store{{.*}} : $*Bool // CHECK: dealloc_stack [[POPENED_COPY]] var b3 = p1.prop @@ -542,15 +542,15 @@ func testExistentials2(p1: P1) { // CHECK: bb0([[P:%[0-9]+]] : $*P1): func testExistentialsGetters(p1: P1) { // CHECK: [[POPENED:%[0-9]+]] = open_existential_addr [[P]] : $*P1 to $*@opened([[UUID:".*"]]) P1 - // CHECK: copy_addr [[POPENED]] to [initialization] [[POPENED_COPY:%.*]]#1 + // CHECK: copy_addr [[POPENED]] to [initialization] [[POPENED_COPY:%.*]] : // CHECK: [[FN:%[0-9]+]] = function_ref @_TFE19protocol_extensionsPS_2P1g5prop2Sb - // CHECK: [[B:%[0-9]+]] = apply [[FN]]<@opened([[UUID]]) P1>([[POPENED_COPY]]#1) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> Bool + // CHECK: [[B:%[0-9]+]] = apply [[FN]]<@opened([[UUID]]) P1>([[POPENED_COPY]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (@in_guaranteed τ_0_0) -> Bool let b: Bool = p1.prop2 // CHECK: [[POPENED:%[0-9]+]] = open_existential_addr [[P]] : $*P1 to $*@opened([[UUID:".*"]]) P1 - // CHECK: copy_addr [[POPENED]] to [initialization] [[POPENED_COPY:%.*]]#1 + // CHECK: copy_addr [[POPENED]] to [initialization] [[POPENED_COPY:%.*]] : // CHECK: [[GETTER:%[0-9]+]] = function_ref @_TFE19protocol_extensionsPS_2P1g9subscriptFSbSb - // CHECK: apply [[GETTER]]<@opened([[UUID]]) P1>([[B]], [[POPENED_COPY]]#1) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (Bool, @in_guaranteed τ_0_0) -> Bool + // CHECK: apply [[GETTER]]<@opened([[UUID]]) P1>([[B]], [[POPENED_COPY]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (Bool, @in_guaranteed τ_0_0) -> Bool let b2: Bool = p1[b] } @@ -592,14 +592,14 @@ func testLogicalExistentialSetters(hasAP1: HasAP1, _ b: Bool) { // CHECK-NEXT: copy_addr [[HASP1]] to [initialization] [[HASP1_BOX]]#1 : $*HasAP1 // CHECK: [[P1_COPY:%[0-9]+]] = alloc_stack $P1 // CHECK-NEXT: [[HASP1_COPY:%[0-9]+]] = alloc_stack $HasAP1 - // CHECK-NEXT: copy_addr [[HASP1_BOX]]#1 to [initialization] [[HASP1_COPY]]#1 : $*HasAP1 + // CHECK-NEXT: copy_addr [[HASP1_BOX]]#1 to [initialization] [[HASP1_COPY]] : $*HasAP1 // CHECK: [[SOMEP1_GETTER:%[0-9]+]] = function_ref @_TFV19protocol_extensions6HasAP1g6someP1PS_2P1_ : $@convention(method) (@out P1, @in_guaranteed HasAP1) -> () - // CHECK: [[RESULT:%[0-9]+]] = apply [[SOMEP1_GETTER]]([[P1_COPY]]#1, [[HASP1_COPY]]#1) : $@convention(method) (@out P1, @in_guaranteed HasAP1) -> () - // CHECK: [[P1_OPENED:%[0-9]+]] = open_existential_addr [[P1_COPY]]#1 : $*P1 to $*@opened([[UUID:".*"]]) P1 + // CHECK: [[RESULT:%[0-9]+]] = apply [[SOMEP1_GETTER]]([[P1_COPY]], [[HASP1_COPY]]) : $@convention(method) (@out P1, @in_guaranteed HasAP1) -> () + // CHECK: [[P1_OPENED:%[0-9]+]] = open_existential_addr [[P1_COPY]] : $*P1 to $*@opened([[UUID:".*"]]) P1 // CHECK: [[PROP2_SETTER:%[0-9]+]] = function_ref @_TFE19protocol_extensionsPS_2P1s5prop2Sb : $@convention(method) <τ_0_0 where τ_0_0 : P1> (Bool, @inout τ_0_0) -> () // CHECK: apply [[PROP2_SETTER]]<@opened([[UUID]]) P1>([[B]], [[P1_OPENED]]) : $@convention(method) <τ_0_0 where τ_0_0 : P1> (Bool, @inout τ_0_0) -> () // CHECK: [[SOMEP1_SETTER:%[0-9]+]] = function_ref @_TFV19protocol_extensions6HasAP1s6someP1PS_2P1_ : $@convention(method) (@in P1, @inout HasAP1) -> () - // CHECK: apply [[SOMEP1_SETTER]]([[P1_COPY]]#1, [[HASP1_BOX]]#1) : $@convention(method) (@in P1, @inout HasAP1) -> () + // CHECK: apply [[SOMEP1_SETTER]]([[P1_COPY]], [[HASP1_BOX]]#1) : $@convention(method) (@in P1, @inout HasAP1) -> () // CHECK-NOT: deinit_existential_addr hasAP1.someP1.prop2 = b // CHECK: return @@ -619,8 +619,8 @@ func test_open_existential_semantics_opaque(guaranteed: P1, guaranteed.f1() // -- Need a guaranteed copy because it's immutable - // CHECK: copy_addr [[IMMEDIATE_BOX]]#1 to [initialization] [[IMMEDIATE:%.*]]#1 - // CHECK: [[VALUE:%.*]] = open_existential_addr [[IMMEDIATE]]#1 + // CHECK: copy_addr [[IMMEDIATE_BOX]]#1 to [initialization] [[IMMEDIATE:%.*]] : + // CHECK: [[VALUE:%.*]] = open_existential_addr [[IMMEDIATE]] // CHECK: [[METHOD:%.*]] = function_ref // -- Can consume the value from our own copy // CHECK: apply [[METHOD]]<{{.*}}>([[VALUE]]) @@ -629,7 +629,7 @@ func test_open_existential_semantics_opaque(guaranteed: P1, immediate.f1() // CHECK: [[PLUS_ONE:%.*]] = alloc_stack $P1 - // CHECK: [[VALUE:%.*]] = open_existential_addr [[PLUS_ONE]]#1 + // CHECK: [[VALUE:%.*]] = open_existential_addr [[PLUS_ONE]] // CHECK: [[METHOD:%.*]] = function_ref // -- Can consume the value from our own copy // CHECK: apply [[METHOD]]<{{.*}}>([[VALUE]]) diff --git a/test/SILGen/protocols.swift b/test/SILGen/protocols.swift index df85e2b8a8610..4f03d74f98fd2 100644 --- a/test/SILGen/protocols.swift +++ b/test/SILGen/protocols.swift @@ -24,11 +24,11 @@ func use_subscript_rvalue_get(i : Int) -> Int { // CHECK: [[GLOB:%[0-9]+]] = global_addr @_Tv9protocols16subscriptableGetPS_16SubscriptableGet_ : $*SubscriptableGet // CHECK: [[PROJ:%[0-9]+]] = open_existential_addr [[GLOB]] : $*SubscriptableGet to $*[[OPENED:@opened(.*) SubscriptableGet]] // CHECK: [[ALLOCSTACK:%[0-9]+]] = alloc_stack $[[OPENED]] -// CHECK: copy_addr [[PROJ]] to [initialization] [[ALLOCSTACK]]#1 : $*[[OPENED]] +// CHECK: copy_addr [[PROJ]] to [initialization] [[ALLOCSTACK]] : $*[[OPENED]] // CHECK-NEXT: [[METH:%[0-9]+]] = witness_method $[[OPENED]], #SubscriptableGet.subscript!getter.1 -// CHECK-NEXT: [[RESULT:%[0-9]+]] = apply [[METH]]<[[OPENED]]>(%0, [[ALLOCSTACK]]#1) -// CHECK-NEXT: destroy_addr [[ALLOCSTACK]]#1 -// CHECK-NEXT: dealloc_stack [[ALLOCSTACK]]#0 : $*@local_storage [[OPENED]] +// CHECK-NEXT: [[RESULT:%[0-9]+]] = apply [[METH]]<[[OPENED]]>(%0, [[ALLOCSTACK]]) +// CHECK-NEXT: destroy_addr [[ALLOCSTACK]] +// CHECK-NEXT: dealloc_stack [[ALLOCSTACK]] : $*[[OPENED]] // CHECK-NEXT: return [[RESULT]] func use_subscript_lvalue_get(i : Int) -> Int { @@ -40,11 +40,11 @@ func use_subscript_lvalue_get(i : Int) -> Int { // CHECK: [[GLOB:%[0-9]+]] = global_addr @_Tv9protocols19subscriptableGetSetPS_19SubscriptableGetSet_ : $*SubscriptableGetSet // CHECK: [[PROJ:%[0-9]+]] = open_existential_addr [[GLOB]] : $*SubscriptableGetSet to $*[[OPENED:@opened(.*) SubscriptableGetSet]] // CHECK: [[ALLOCSTACK:%[0-9]+]] = alloc_stack $[[OPENED]] -// CHECK: copy_addr [[PROJ]] to [initialization] [[ALLOCSTACK]]#1 : $*[[OPENED]] +// CHECK: copy_addr [[PROJ]] to [initialization] [[ALLOCSTACK]] : $*[[OPENED]] // CHECK-NEXT: [[METH:%[0-9]+]] = witness_method $[[OPENED]], #SubscriptableGetSet.subscript!getter.1 -// CHECK-NEXT: [[RESULT:%[0-9]+]] = apply [[METH]]<[[OPENED]]>(%0, [[ALLOCSTACK]]#1) -// CHECK-NEXT: destroy_addr [[ALLOCSTACK]]#1 : $*[[OPENED]] -// CHECK-NEXT: dealloc_stack [[ALLOCSTACK]]#0 : $*@local_storage [[OPENED]] +// CHECK-NEXT: [[RESULT:%[0-9]+]] = apply [[METH]]<[[OPENED]]>(%0, [[ALLOCSTACK]]) +// CHECK-NEXT: destroy_addr [[ALLOCSTACK]] : $*[[OPENED]] +// CHECK-NEXT: dealloc_stack [[ALLOCSTACK]] : $*[[OPENED]] // CHECK-NEXT: return [[RESULT]] func use_subscript_lvalue_set(i : Int) { @@ -69,11 +69,11 @@ func use_subscript_archetype_rvalue_get(generic : T, idx : // CHECK-LABEL: sil hidden @{{.*}}use_subscript_archetype_rvalue_get // CHECK: bb0(%0 : $*T, %1 : $Int): // CHECK: [[STACK:%[0-9]+]] = alloc_stack $T -// CHECK: copy_addr %0 to [initialization] [[STACK]]#1 +// CHECK: copy_addr %0 to [initialization] [[STACK]] // CHECK: [[METH:%[0-9]+]] = witness_method $T, #SubscriptableGet.subscript!getter.1 -// CHECK-NEXT: apply [[METH]](%1, [[STACK]]#1) -// CHECK-NEXT: destroy_addr [[STACK]]#1 : $*T -// CHECK-NEXT: dealloc_stack [[STACK]]#0 : $*@local_storage T +// CHECK-NEXT: apply [[METH]](%1, [[STACK]]) +// CHECK-NEXT: destroy_addr [[STACK]] : $*T +// CHECK-NEXT: dealloc_stack [[STACK]] : $*T // CHECK-NEXT: destroy_addr %0 @@ -82,13 +82,13 @@ func use_subscript_archetype_lvalue_get(inout generic : } // CHECK-LABEL: sil hidden @{{.*}}use_subscript_archetype_lvalue_get // CHECK: bb0(%0 : $*T, %1 : $Int): -// CHECK: [[INOUTBOX:%[0-9]+]] = alloc_box $T // var generic +// CHECK: [[INOUTBOX:%[0-9]+]] = alloc_box $T, var, name "generic" // CHECK: [[GUARANTEEDSTACK:%[0-9]+]] = alloc_stack $T // CHECK: copy_addr [[INOUTBOX]]#1 to [initialization] // CHECK: [[METH:%[0-9]+]] = witness_method $T, #SubscriptableGetSet.subscript!getter.1 -// CHECK-NEXT: [[APPLYRESULT:%[0-9]+]] = apply [[METH]](%1, [[GUARANTEEDSTACK]]#1) -// CHECK-NEXT: destroy_addr [[GUARANTEEDSTACK]]#1 : $*T -// CHECK-NEXT: dealloc_stack [[GUARANTEEDSTACK]]#0 : $*@local_storage T +// CHECK-NEXT: [[APPLYRESULT:%[0-9]+]] = apply [[METH]](%1, [[GUARANTEEDSTACK]]) +// CHECK-NEXT: destroy_addr [[GUARANTEEDSTACK]] : $*T +// CHECK-NEXT: dealloc_stack [[GUARANTEEDSTACK]] : $*T // CHECK-NEXT: copy_addr [[INOUTBOX]]#1 to %0 : $*T // CHECK-NEXT: strong_release [[INOUTBOX]]#0 : $@box T // CHECK: return [[APPLYRESULT]] @@ -128,9 +128,9 @@ func use_property_rvalue_get() -> Int { // CHECK: [[GLOB:%[0-9]+]] = global_addr @_Tv9protocols11propertyGetPS_18PropertyWithGetter_ : $*PropertyWithGetter // CHECK: [[PROJ:%[0-9]+]] = open_existential_addr [[GLOB]] : $*PropertyWithGetter to $*[[OPENED:@opened(.*) PropertyWithGetter]] // CHECK: [[COPY:%.*]] = alloc_stack $[[OPENED]] -// CHECK-NEXT: copy_addr [[PROJ]] to [initialization] [[COPY]]#1 : $*[[OPENED]] +// CHECK-NEXT: copy_addr [[PROJ]] to [initialization] [[COPY]] : $*[[OPENED]] // CHECK-NEXT: [[METH:%[0-9]+]] = witness_method $[[OPENED]], #PropertyWithGetter.a!getter.1 -// CHECK-NEXT: apply [[METH]]<[[OPENED]]>([[COPY]]#1) +// CHECK-NEXT: apply [[METH]]<[[OPENED]]>([[COPY]]) func use_property_lvalue_get() -> Int { return propertyGetSet.b @@ -139,9 +139,9 @@ func use_property_lvalue_get() -> Int { // CHECK: [[GLOB:%[0-9]+]] = global_addr @_Tv9protocols14propertyGetSetPS_24PropertyWithGetterSetter_ : $*PropertyWithGetterSetter // CHECK: [[PROJ:%[0-9]+]] = open_existential_addr [[GLOB]] : $*PropertyWithGetterSetter to $*[[OPENED:@opened(.*) PropertyWithGetterSetter]] // CHECK: [[STACK:%[0-9]+]] = alloc_stack $[[OPENED]] -// CHECK: copy_addr [[PROJ]] to [initialization] [[STACK]]#1 +// CHECK: copy_addr [[PROJ]] to [initialization] [[STACK]] // CHECK-NEXT: [[METH:%[0-9]+]] = witness_method $[[OPENED]], #PropertyWithGetterSetter.b!getter.1 -// CHECK-NEXT: apply [[METH]]<[[OPENED]]>([[STACK]]#1) +// CHECK-NEXT: apply [[METH]]<[[OPENED]]>([[STACK]]) func use_property_lvalue_set(x : Int) { propertyGetSet.b = x @@ -165,11 +165,11 @@ func use_property_archetype_rvalue_get(generic : T) -> I // CHECK-LABEL: sil hidden @{{.*}}use_property_archetype_rvalue_get // CHECK: bb0(%0 : $*T): // CHECK: [[STACK:%[0-9]+]] = alloc_stack $T -// CHECK: copy_addr %0 to [initialization] [[STACK]]#1 +// CHECK: copy_addr %0 to [initialization] [[STACK]] // CHECK: [[METH:%[0-9]+]] = witness_method $T, #PropertyWithGetter.a!getter.1 -// CHECK-NEXT: apply [[METH]]([[STACK]]#1) -// CHECK-NEXT: destroy_addr [[STACK]]#1 -// CHECK-NEXT: dealloc_stack [[STACK]]#0 +// CHECK-NEXT: apply [[METH]]([[STACK]]) +// CHECK-NEXT: destroy_addr [[STACK]] +// CHECK-NEXT: dealloc_stack [[STACK]] // CHECK-NEXT: destroy_addr %0 @@ -180,11 +180,11 @@ func use_property_archetype_lvalue_get(generic : T // CHECK-LABEL: sil hidden @{{.*}}use_property_archetype_lvalue_get // CHECK: bb0(%0 : $*T): // CHECK: [[STACK:%[0-9]+]] = alloc_stack $T -// CHECK: copy_addr %0 to [initialization] [[STACK]]#1 : $*T +// CHECK: copy_addr %0 to [initialization] [[STACK]] : $*T // CHECK: [[METH:%[0-9]+]] = witness_method $T, #PropertyWithGetterSetter.b!getter.1 -// CHECK-NEXT: apply [[METH]]([[STACK]]#1) -// CHECK-NEXT: destroy_addr [[STACK]]#1 : $*T -// CHECK-NEXT: dealloc_stack [[STACK]]#0 : $*@local_storage T +// CHECK-NEXT: apply [[METH]]([[STACK]]) +// CHECK-NEXT: destroy_addr [[STACK]] : $*T +// CHECK-NEXT: dealloc_stack [[STACK]] : $*T // CHECK-NEXT: destroy_addr %0 @@ -210,9 +210,9 @@ func use_initializable_archetype(t: T, i: Int) { // CHECK: [[T_INIT:%[0-9]+]] = witness_method $T, #Initializable.init!allocator.1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : Initializable> (@out τ_0_0, Int, @thick τ_0_0.Type) -> () // CHECK: [[T_META:%[0-9]+]] = metatype $@thick T.Type // CHECK: [[T_RESULT:%[0-9]+]] = alloc_stack $T - // CHECK: [[T_RESULT_ADDR:%[0-9]+]] = apply [[T_INIT]]([[T_RESULT]]#1, %1, [[T_META]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Initializable> (@out τ_0_0, Int, @thick τ_0_0.Type) -> () - // CHECK: destroy_addr [[T_RESULT]]#1 : $*T - // CHECK: dealloc_stack [[T_RESULT]]#0 : $*@local_storage T + // CHECK: [[T_RESULT_ADDR:%[0-9]+]] = apply [[T_INIT]]([[T_RESULT]], %1, [[T_META]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Initializable> (@out τ_0_0, Int, @thick τ_0_0.Type) -> () + // CHECK: destroy_addr [[T_RESULT]] : $*T + // CHECK: dealloc_stack [[T_RESULT]] : $*T // CHECK: destroy_addr [[VAR_0:%[0-9]+]] : $*T // CHECK: [[RESULT:%[0-9]+]] = tuple () // CHECK: return [[RESULT]] : $() @@ -224,11 +224,11 @@ func use_initializable_existential(im: Initializable.Type, i: Int) { // CHECK: bb0([[IM:%[0-9]+]] : $@thick Initializable.Type, [[I:%[0-9]+]] : $Int): // CHECK: [[ARCHETYPE_META:%[0-9]+]] = open_existential_metatype [[IM]] : $@thick Initializable.Type to $@thick (@opened([[N:".*"]]) Initializable).Type // CHECK: [[TEMP_VALUE:%[0-9]+]] = alloc_stack $Initializable -// CHECK: [[TEMP_ADDR:%[0-9]+]] = init_existential_addr [[TEMP_VALUE]]#1 : $*Initializable, $@opened([[N]]) Initializable +// CHECK: [[TEMP_ADDR:%[0-9]+]] = init_existential_addr [[TEMP_VALUE]] : $*Initializable, $@opened([[N]]) Initializable // CHECK: [[INIT_WITNESS:%[0-9]+]] = witness_method $@opened([[N]]) Initializable, #Initializable.init!allocator.1, [[ARCHETYPE_META]]{{.*}} : $@convention(witness_method) <τ_0_0 where τ_0_0 : Initializable> (@out τ_0_0, Int, @thick τ_0_0.Type) -> () // CHECK: [[INIT_RESULT:%[0-9]+]] = apply [[INIT_WITNESS]]<@opened([[N]]) Initializable>([[TEMP_ADDR]], [[I]], [[ARCHETYPE_META]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Initializable> (@out τ_0_0, Int, @thick τ_0_0.Type) -> () -// CHECK: destroy_addr [[TEMP_VALUE]]#1 : $*Initializable -// CHECK: dealloc_stack [[TEMP_VALUE]]#0 : $*@local_storage Initializable +// CHECK: destroy_addr [[TEMP_VALUE]] : $*Initializable +// CHECK: dealloc_stack [[TEMP_VALUE]] : $*Initializable im.init(int: i) // CHECK: [[RESULT:%[0-9]+]] = tuple () // CHECK: return [[RESULT]] : $() @@ -251,12 +251,12 @@ class ClassWithGetter : PropertyWithGetter { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWC9protocols15ClassWithGetterS_18PropertyWithGetterS_FS1_g1aSi : $@convention(witness_method) (@in_guaranteed ClassWithGetter) -> Int { // CHECK: bb0([[C:%.*]] : $*ClassWithGetter): // CHECK-NEXT: [[CCOPY:%.*]] = alloc_stack $ClassWithGetter -// CHECK-NEXT: copy_addr [[C]] to [initialization] [[CCOPY]]#1 -// CHECK-NEXT: [[CCOPY_LOADED:%.*]] = load [[CCOPY]]#1 -// CHECK-NEXT: [[FUN:%.*]] = class_method [[CCOPY_LOADED]] : $ClassWithGetter, #ClassWithGetter.a!getter.1 : ClassWithGetter -> () -> Int , $@convention(method) (@guaranteed ClassWithGetter) -> Int +// CHECK-NEXT: copy_addr [[C]] to [initialization] [[CCOPY]] +// CHECK-NEXT: [[CCOPY_LOADED:%.*]] = load [[CCOPY]] +// CHECK-NEXT: [[FUN:%.*]] = class_method [[CCOPY_LOADED]] : $ClassWithGetter, #ClassWithGetter.a!getter.1 : (ClassWithGetter) -> () -> Int , $@convention(method) (@guaranteed ClassWithGetter) -> Int // CHECK-NEXT: apply [[FUN]]([[CCOPY_LOADED]]) // CHECK-NEXT: strong_release [[CCOPY_LOADED]] -// CHECK-NEXT: dealloc_stack [[CCOPY]]#0 +// CHECK-NEXT: dealloc_stack [[CCOPY]] // CHECK-NEXT: return class ClassWithGetterSetter : PropertyWithGetterSetter, PropertyWithGetter { @@ -277,12 +277,12 @@ class ClassWithGetterSetter : PropertyWithGetterSetter, PropertyWithGetter { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWC9protocols21ClassWithGetterSetterS_24PropertyWithGetterSetterS_FS1_g1bSi : $@convention(witness_method) (@in_guaranteed ClassWithGetterSetter) -> Int { // CHECK: bb0([[C:%.*]] : $*ClassWithGetterSetter): // CHECK-NEXT: [[CCOPY:%.*]] = alloc_stack $ClassWithGetterSetter -// CHECK-NEXT: copy_addr [[C]] to [initialization] [[CCOPY]]#1 -// CHECK-NEXT: [[CCOPY_LOADED:%.*]] = load [[CCOPY]]#1 -// CHECK-NEXT: [[FUN:%.*]] = class_method [[CCOPY_LOADED]] : $ClassWithGetterSetter, #ClassWithGetterSetter.b!getter.1 : ClassWithGetterSetter -> () -> Int , $@convention(method) (@guaranteed ClassWithGetterSetter) -> Int +// CHECK-NEXT: copy_addr [[C]] to [initialization] [[CCOPY]] +// CHECK-NEXT: [[CCOPY_LOADED:%.*]] = load [[CCOPY]] +// CHECK-NEXT: [[FUN:%.*]] = class_method [[CCOPY_LOADED]] : $ClassWithGetterSetter, #ClassWithGetterSetter.b!getter.1 : (ClassWithGetterSetter) -> () -> Int , $@convention(method) (@guaranteed ClassWithGetterSetter) -> Int // CHECK-NEXT: apply [[FUN]]([[CCOPY_LOADED]]) // CHECK-NEXT: strong_release [[CCOPY_LOADED]] -// CHECK-NEXT: dealloc_stack [[CCOPY]]#0 +// CHECK-NEXT: dealloc_stack [[CCOPY]] // CHECK-NEXT: return // Stored variables fulfilling property requirements @@ -298,7 +298,7 @@ class ClassWithStoredProperty : PropertyWithGetter { // CHECK: bb0([[ARG:%.*]] : $ClassWithStoredProperty): // CHECK-NEXT: debug_value [[ARG]] // CHECK-NOT: strong_retain - // CHECK-NEXT: [[FUN:%.*]] = class_method [[ARG]] : $ClassWithStoredProperty, #ClassWithStoredProperty.a!getter.1 : ClassWithStoredProperty -> () -> Int , $@convention(method) (@guaranteed ClassWithStoredProperty) -> Int + // CHECK-NEXT: [[FUN:%.*]] = class_method [[ARG]] : $ClassWithStoredProperty, #ClassWithStoredProperty.a!getter.1 : (ClassWithStoredProperty) -> () -> Int , $@convention(method) (@guaranteed ClassWithStoredProperty) -> Int // CHECK-NEXT: [[RESULT:%.*]] = apply [[FUN]]([[ARG]]) // CHECK-NOT: strong_release // CHECK-NEXT: return [[RESULT]] : $Int @@ -318,12 +318,12 @@ struct StructWithStoredProperty : PropertyWithGetter { // CHECK-NEXT: return %2 : $Int } -// Make sure that we generate direct function calls for out struct protocl +// Make sure that we generate direct function calls for out struct protocol // witness since structs don't do virtual calls for methods. // // *NOTE* Even though at first glance the copy_addr looks like a leak // here, StructWithStoredProperty is a trivial struct implying that no -// leak is occuring. See the test with StructWithStoredClassProperty +// leak is occurring. See the test with StructWithStoredClassProperty // that makes sure in such a case we don't leak. This is due to the // thunking code being too dumb but it is harmless to program // correctness. @@ -331,12 +331,12 @@ struct StructWithStoredProperty : PropertyWithGetter { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWV9protocols24StructWithStoredPropertyS_18PropertyWithGetterS_FS1_g1aSi : $@convention(witness_method) (@in_guaranteed StructWithStoredProperty) -> Int { // CHECK: bb0([[C:%.*]] : $*StructWithStoredProperty): // CHECK-NEXT: [[CCOPY:%.*]] = alloc_stack $StructWithStoredProperty -// CHECK-NEXT: copy_addr [[C]] to [initialization] [[CCOPY]]#1 -// CHECK-NEXT: [[CCOPY_LOADED:%.*]] = load [[CCOPY]]#1 +// CHECK-NEXT: copy_addr [[C]] to [initialization] [[CCOPY]] +// CHECK-NEXT: [[CCOPY_LOADED:%.*]] = load [[CCOPY]] // CHECK-NEXT: function_ref // CHECK-NEXT: [[FUN:%.*]] = function_ref @_TFV9protocols24StructWithStoredPropertyg1aSi : $@convention(method) (StructWithStoredProperty) -> Int // CHECK-NEXT: apply [[FUN]]([[CCOPY_LOADED]]) -// CHECK-NEXT: dealloc_stack [[CCOPY]]#0 +// CHECK-NEXT: dealloc_stack [[CCOPY]] // CHECK-NEXT: return class C {} @@ -361,13 +361,13 @@ struct StructWithStoredClassProperty : PropertyWithGetter { // CHECK-LABEL: sil hidden [transparent] [thunk] @_TTWV9protocols29StructWithStoredClassPropertyS_18PropertyWithGetterS_FS1_g1aSi : $@convention(witness_method) (@in_guaranteed StructWithStoredClassProperty) -> Int { // CHECK: bb0([[C:%.*]] : $*StructWithStoredClassProperty): // CHECK-NEXT: [[CCOPY:%.*]] = alloc_stack $StructWithStoredClassProperty -// CHECK-NEXT: copy_addr [[C]] to [initialization] [[CCOPY]]#1 -// CHECK-NEXT: [[CCOPY_LOADED:%.*]] = load [[CCOPY]]#1 +// CHECK-NEXT: copy_addr [[C]] to [initialization] [[CCOPY]] +// CHECK-NEXT: [[CCOPY_LOADED:%.*]] = load [[CCOPY]] // CHECK-NEXT: function_ref // CHECK-NEXT: [[FUN:%.*]] = function_ref @_TFV9protocols29StructWithStoredClassPropertyg1aSi : $@convention(method) (@guaranteed StructWithStoredClassProperty) -> Int // CHECK-NEXT: apply [[FUN]]([[CCOPY_LOADED]]) // CHECK-NEXT: release_value [[CCOPY_LOADED]] -// CHECK-NEXT: dealloc_stack [[CCOPY]]#0 +// CHECK-NEXT: dealloc_stack [[CCOPY]] // CHECK-NEXT: return // rdar://22676810 @@ -384,16 +384,16 @@ func testExistentialPropertyRead(inout t: T) { // CHECK: copy_addr %0 to [initialization] [[T]]#1 : $*T // CHECK: [[P_TEMP:%.*]] = alloc_stack $PropertyWithGetterSetter // CHECK: [[T_TEMP:%.*]] = alloc_stack $T -// CHECK: copy_addr [[T]]#1 to [initialization] [[T_TEMP]]#1 : $*T +// CHECK: copy_addr [[T]]#1 to [initialization] [[T_TEMP]] : $*T // CHECK: [[P_GETTER:%.*]] = witness_method $T, #ExistentialProperty.p!getter.1 : -// CHECK-NEXT: apply [[P_GETTER]]([[P_TEMP]]#1, [[T_TEMP]]#1) -// CHECK-NEXT: destroy_addr [[T_TEMP]]#1 -// CHECK-NEXT: [[OPEN:%.*]] = open_existential_addr [[P_TEMP]]#1 : $*PropertyWithGetterSetter to $*[[P_OPENED:@opened(.*) PropertyWithGetterSetter]] +// CHECK-NEXT: apply [[P_GETTER]]([[P_TEMP]], [[T_TEMP]]) +// CHECK-NEXT: destroy_addr [[T_TEMP]] +// CHECK-NEXT: [[OPEN:%.*]] = open_existential_addr [[P_TEMP]] : $*PropertyWithGetterSetter to $*[[P_OPENED:@opened(.*) PropertyWithGetterSetter]] // CHECK-NEXT: [[T0:%.*]] = alloc_stack $[[P_OPENED]] -// CHECK-NEXT: copy_addr [[OPEN]] to [initialization] [[T0]]#1 +// CHECK-NEXT: copy_addr [[OPEN]] to [initialization] [[T0]] // CHECK-NEXT: [[B_GETTER:%.*]] = witness_method $[[P_OPENED]], #PropertyWithGetterSetter.b!getter.1 -// CHECK-NEXT: apply [[B_GETTER]]<[[P_OPENED]]>([[T0]]#1) -// CHECK-NEXT: destroy_addr [[T0]]#1 +// CHECK-NEXT: apply [[B_GETTER]]<[[P_OPENED]]>([[T0]]) +// CHECK-NEXT: destroy_addr [[T0]] // CHECK-NOT: witness_method // CHECK: return diff --git a/test/SILGen/reabstract_lvalue.swift b/test/SILGen/reabstract_lvalue.swift index a65c98c584105..655e2a1f11f5a 100644 --- a/test/SILGen/reabstract_lvalue.swift +++ b/test/SILGen/reabstract_lvalue.swift @@ -22,9 +22,9 @@ func reabstractFunctionInOut() { // CHECK: strong_retain [[THICK_ARG]] // CHECK: [[THUNK1:%.*]] = function_ref @_TTRXFo_dSi_dSd_XFo_iSi_iSd_ // CHECK: [[ABSTRACTED_ARG:%.*]] = partial_apply [[THUNK1]]([[THICK_ARG]]) - // CHECK: store [[ABSTRACTED_ARG]] to [[ABSTRACTED_BOX]]#1 - // CHECK: apply [[FUNC]]<(Int) -> Double>([[ABSTRACTED_BOX]]#1) - // CHECK: [[NEW_ABSTRACTED_ARG:%.*]] = load [[ABSTRACTED_BOX]]#1 + // CHECK: store [[ABSTRACTED_ARG]] to [[ABSTRACTED_BOX]] + // CHECK: apply [[FUNC]]<(Int) -> Double>([[ABSTRACTED_BOX]]) + // CHECK: [[NEW_ABSTRACTED_ARG:%.*]] = load [[ABSTRACTED_BOX]] // CHECK: [[THUNK2:%.*]] = function_ref @_TTRXFo_iSi_iSd_XFo_dSi_dSd_ // CHECK: [[NEW_ARG:%.*]] = partial_apply [[THUNK2]]([[NEW_ABSTRACTED_ARG]]) var minimallyAbstracted = transform @@ -40,7 +40,7 @@ func reabstractMetatypeInOut() { // CHECK: [[FUNC:%.*]] = function_ref @_TF17reabstract_lvalue19consumeGenericInOut // CHECK: [[BOX:%.*]] = alloc_stack $@thick MyMetatypeIsThin.Type // CHECK: [[THICK:%.*]] = metatype $@thick MyMetatypeIsThin.Type - // CHECK: store [[THICK]] to [[BOX]]#1 - // CHECK: apply [[FUNC]]([[BOX]]#1) + // CHECK: store [[THICK]] to [[BOX]] + // CHECK: apply [[FUNC]]([[BOX]]) consumeGenericInOut(&thinMetatype) } diff --git a/test/SILGen/semanticsattr.swift b/test/SILGen/semanticsattr.swift new file mode 100644 index 0000000000000..d9c3d1b8ec957 --- /dev/null +++ b/test/SILGen/semanticsattr.swift @@ -0,0 +1,5 @@ +// RUN: %target-swift-frontend -parse-stdlib -emit-silgen %s | FileCheck %s + +// CHECK: [_semantics "123"] [_semantics "223"] @func1 +@_semantics("223") @_semantics("123") +@_silgen_name("func1") func func1() { } diff --git a/test/SILGen/sil_locations.swift b/test/SILGen/sil_locations.swift index efa00f0b048c7..45059bdb61042 100644 --- a/test/SILGen/sil_locations.swift +++ b/test/SILGen/sil_locations.swift @@ -3,11 +3,11 @@ // FIXME: Not sure if this an ideal source info for the branch - // it points to if, not the last instruction in the block. func ifexpr() -> Int { - var x : Int = 0; + var x : Int = 0 if true { x++; } - return x; + return x // CHECK-LABEL: sil hidden @_TF13sil_locations6ifexprFT_Si // CHECK: apply {{.*}} line:[[@LINE-5]]:6 // CHECK: cond_br {{%.*}}, [[TRUE_BB:bb[0-9]+]], [[FALSE_BB:bb[0-9]+]] // {{.*}} line:[[@LINE-6]]:6 @@ -16,13 +16,13 @@ func ifexpr() -> Int { } func ifelseexpr() -> Int { - var x : Int = 0; + var x : Int = 0 if true { x++; } else { x--; } - return x; + return x // CHECK-LABEL: sil hidden @_TF13sil_locations10ifelseexprFT_Si // CHECK: cond_br {{%.*}}, [[TRUE_BB:bb[0-9]+]], [[FALSE_BB:bb[0-9]+]] // {{.*}} line:[[@LINE-7]]:6 // CHECK: [[TRUE_BB]]: @@ -37,9 +37,9 @@ func ifelseexpr() -> Int { // in the branch. func ifexpr_return() -> Int { if true { - return 5; + return 5 } - return 6; + return 6 // CHECK-LABEL: sil hidden @_TF13sil_locations13ifexpr_returnFT_Si // CHECK: apply {{.*}} line:[[@LINE-5]]:6 // CHECK: cond_br {{%.*}}, [[TRUE_BB:bb[0-9]+]], [[FALSE_BB:bb[0-9]+]] // {{.*}} line:[[@LINE-6]]:6 @@ -51,8 +51,8 @@ func ifexpr_return() -> Int { } func ifexpr_rval() -> Int { - var x = true ? 5 : 6; - return x; + var x = true ? 5 : 6 + return x // CHECK-LABEL: sil hidden @_TF13sil_locations11ifexpr_rvalFT_Si // CHECK: apply {{.*}} line:[[@LINE-3]]:11 // CHECK: cond_br {{%.*}}, [[TRUE_BB:bb[0-9]+]], [[FALSE_BB:bb[0-9]+]] // {{.*}} line:[[@LINE-4]]:11 @@ -104,7 +104,7 @@ class LocationClass { func mem() {} } func testMethodCall() { - var l: LocationClass; + var l: LocationClass l.mem(); // CHECK-LABEL: sil hidden @_TF13sil_locations14testMethodCallFT_T_ @@ -112,9 +112,9 @@ func testMethodCall() { } func multipleReturnsImplicitAndExplicit() { - var x = 5+3; + var x = 5+3 if x > 10 { - return; + return } x++; // CHECK-LABEL: sil hidden @_TF13sil_locations34multipleReturnsImplicitAndExplicitFT_T_ @@ -145,20 +145,20 @@ func testSwitch() { // CHECK: cond_br // var z: Int = 200 - // CHECK: [[VAR_Z:%[0-9]+]] = alloc_box $Int // {{.*}} line:[[@LINE-1]]:9 + // CHECK: [[VAR_Z:%[0-9]+]] = alloc_box $Int, var, name "z"{{.*}}line:[[@LINE-1]]:9 // CHECK: integer_literal $Builtin.Int2048, 200 // {{.*}} line:[[@LINE-2]]:18 x = z // CHECK: strong_release [[VAR_Z]]{{.*}} // {{.*}} line:[[@LINE-1]]:9:cleanup case (3, let y): - x++ + x += 1 } } func testIf() { if true { - var y:Int; + var y:Int } else { - var x:Int; + var x:Int } // CHECK-LABEL: sil hidden @_TF13sil_locations6testIfFT_T_ // @@ -176,17 +176,17 @@ func testIf() { func testFor() { for (var i:Int = 0; i<10; i++) { - var y: Int = 300; + var y: Int = 300 y++; if true { - break; + break } y--; - continue; + continue } // CHECK-LABEL: sil hidden @_TF13sil_locations7testForFT_T_ - // CHECK: [[VAR_Y_IN_FOR:%[0-9]+]] = alloc_box $Int // {{.*}} line:[[@LINE-10]]:9 + // CHECK: [[VAR_Y_IN_FOR:%[0-9]+]] = alloc_box $Int, var, name "y" // {{.*}} line:[[@LINE-10]]:9 // CHECK: integer_literal $Builtin.Int2048, 300 // {{.*}} line:[[@LINE-11]]:18 // CHECK: strong_release [[VAR_Y_IN_FOR]]#0 : $@box Int // CHECK: br bb{{.*}} // {{.*}} line:[[@LINE-10]]:7 @@ -210,7 +210,7 @@ func testTuples() { // CHECK: tuple_element_addr {{.*}} line:[[@LINE-9]]:16 } -// Test tuple emploding/exploding. +// Test tuple imploding/exploding. protocol Ordinable { func ord() -> Int } @@ -324,9 +324,9 @@ func printSinglePayloadAddressOnly(v:SinglePayloadAddressOnly) { func testStringForEachStmt() { - var i = 0; + var i = 0 for index in 1..<20 { - i++ + i += 1 if i == 15 { break } @@ -350,10 +350,10 @@ func testStringForEachStmt() { func testForStmt() { - var i = 0; - var m = 0; + var i = 0 + var m = 0 for (i = 0; i < 10; ++i) { - m++ + m += 1 if m == 15 { break } else { @@ -380,9 +380,9 @@ func testForStmt() { func testRepeatWhile() { - var m = 0; + var m = 0 repeat { - m++ + m += 1 } while (m < 200) @@ -396,13 +396,13 @@ func testRepeatWhile() { func testWhile() { - var m = 0; + var m = 0 while m < 100 { - m++ + m += 1 if m > 5 { break } - m++ + m += 1 } // CHECK-LABEL: sil hidden @_TF13sil_locations9testWhileFT_T_ diff --git a/test/SILGen/statements.swift b/test/SILGen/statements.swift index 4cfdc52c65bc8..141cdb1e4583f 100644 --- a/test/SILGen/statements.swift +++ b/test/SILGen/statements.swift @@ -93,13 +93,13 @@ func nested_if_merge_ret(x: Int, y: Bool, z: Bool) -> Int { if (z) { bar(x); } - return 1; + return 1 } else { if (z) { foo(x, y); } } - return 2; + return 2 } // CHECK-LABEL: sil hidden @_TF10statements19nested_if_merge_ret @@ -119,7 +119,7 @@ func loop_with_break(x: Int, _ y: Bool, _ z: Bool) -> Int { while (x > 2) { if (y) { bar(x); - break; + break } } } @@ -130,7 +130,7 @@ func loop_with_continue(x: Int, y: Bool, z: Bool) -> Int { while (x > 2) { if (y) { bar(x); - continue; + continue } loop_with_break(x, y, z); } @@ -143,7 +143,7 @@ func do_loop_with_continue(x: Int, y: Bool, z: Bool) -> Int { repeat { if (x < 42) { bar(x); - continue; + continue } loop_with_break(x, y, z); } @@ -161,15 +161,15 @@ func for_loops1(x: Int, c: Bool) { markUsed(i) } - for ; x < 40; { + for ; x < 40; { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} markUsed(x) - ++x + x += 1 } - for var i = 0; i < 100; ++i { + for var i = 0; i < 100; i += 1 { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} } - for let i = 0; i < 100; i { + for let i = 0; i < 100; i { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} } } @@ -515,7 +515,7 @@ func defer_mutable(x: Int) { var x = x // CHECK: [[BOX:%.*]] = alloc_box $Int // CHECK-NOT: [[BOX]]#0 - // CHECK: function_ref @_TFF10statements13defer_mutableFSiT_L_6$deferfT_T_ : $@convention(thin) (@inout Int) -> () + // CHECK: function_ref @_TFF10statements13defer_mutableFSiT_L_6$deferfT_T_ : $@convention(thin) (@inout_aliasable Int) -> () // CHECK-NOT: [[BOX]]#0 // CHECK: strong_release [[BOX]]#0 defer { _ = x } @@ -564,12 +564,12 @@ func testRequireExprPattern(a : Int) { // CHECK-LABEL: sil hidden @_TF10statements20testRequireOptional1FGSqSi_Si // CHECK: bb0(%0 : $Optional): -// CHECK-NEXT: debug_value %0 : $Optional // let a +// CHECK-NEXT: debug_value %0 : $Optional, let, name "a" // CHECK-NEXT: switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: bb1, default bb2 func testRequireOptional1(a : Int?) -> Int { // CHECK: bb1(%3 : $Int): - // CHECK-NEXT: debug_value %3 : $Int // let t + // CHECK-NEXT: debug_value %3 : $Int, let, name "t" // CHECK-NEXT: return %3 : $Int guard let t = a else { abort() } @@ -583,14 +583,14 @@ func testRequireOptional1(a : Int?) -> Int { // CHECK-LABEL: sil hidden @_TF10statements20testRequireOptional2FGSqSS_SS // CHECK: bb0(%0 : $Optional): -// CHECK-NEXT: debug_value %0 : $Optional // let a +// CHECK-NEXT: debug_value %0 : $Optional, let, name "a" // CHECK-NEXT: retain_value %0 : $Optional // CHECK-NEXT: switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: bb1, default bb2 func testRequireOptional2(a : String?) -> String { guard let t = a else { abort() } // CHECK: bb1(%4 : $String): - // CHECK-NEXT: debug_value %4 : $String // let t + // CHECK-NEXT: debug_value %4 : $String, let, name "t" // CHECK-NEXT: release_value %0 : $Optional // CHECK-NEXT: return %4 : $String @@ -608,24 +608,24 @@ enum MyOpt { // CHECK-LABEL: sil hidden @_TF10statements28testAddressOnlyEnumInRequire // CHECK: bb0(%0 : $*T, %1 : $*MyOpt): -// CHECK-NEXT: debug_value_addr %1 : $*MyOpt // let a -// CHECK-NEXT: %3 = alloc_stack $T // let t +// CHECK-NEXT: debug_value_addr %1 : $*MyOpt, let, name "a" +// CHECK-NEXT: %3 = alloc_stack $T, let, name "t" // CHECK-NEXT: %4 = alloc_stack $MyOpt -// CHECK-NEXT: copy_addr %1 to [initialization] %4#1 : $*MyOpt -// CHECK-NEXT: switch_enum_addr %4#1 : $*MyOpt, case #MyOpt.Some!enumelt.1: bb2, default bb1 +// CHECK-NEXT: copy_addr %1 to [initialization] %4 : $*MyOpt +// CHECK-NEXT: switch_enum_addr %4 : $*MyOpt, case #MyOpt.Some!enumelt.1: bb2, default bb1 func testAddressOnlyEnumInRequire(a : MyOpt) -> T { // CHECK: bb1: - // CHECK-NEXT: dealloc_stack %4#0 - // CHECK-NEXT: dealloc_stack %3#0 + // CHECK-NEXT: dealloc_stack %4 + // CHECK-NEXT: dealloc_stack %3 // CHECK-NEXT: br bb3 guard let t = a else { abort() } // CHECK: bb2: - // CHECK-NEXT: %10 = unchecked_take_enum_data_addr %4#1 : $*MyOpt, #MyOpt.Some!enumelt.1 - // CHECK-NEXT: copy_addr [take] %10 to [initialization] %3#1 : $*T - // CHECK-NEXT: dealloc_stack %4#0 - // CHECK-NEXT: copy_addr [take] %3#1 to [initialization] %0 : $*T - // CHECK-NEXT: dealloc_stack %3#0 + // CHECK-NEXT: %10 = unchecked_take_enum_data_addr %4 : $*MyOpt, #MyOpt.Some!enumelt.1 + // CHECK-NEXT: copy_addr [take] %10 to [initialization] %3 : $*T + // CHECK-NEXT: dealloc_stack %4 + // CHECK-NEXT: copy_addr [take] %3 to [initialization] %0 : $*T + // CHECK-NEXT: dealloc_stack %3 // CHECK-NEXT: destroy_addr %1 : $*MyOpt // CHECK-NEXT: tuple () // CHECK-NEXT: return @@ -667,7 +667,7 @@ func test_as_pattern(y : BaseClass) -> DerivedClass { // CHECK: bb{{.*}}([[PTR:%[0-9]+]] : $DerivedClass): - // CHECK-NEXT: debug_value [[PTR]] : $DerivedClass // let result + // CHECK-NEXT: debug_value [[PTR]] : $DerivedClass, let, name "result" // CHECK-NEXT: strong_release %0 : $BaseClass // CHECK-NEXT: return [[PTR]] : $DerivedClass return result @@ -676,7 +676,7 @@ func test_as_pattern(y : BaseClass) -> DerivedClass { func let_else_tuple_binding(a : (Int, Int)?) -> Int { // CHECK: bb0(%0 : $Optional<(Int, Int)>): - // CHECK-NEXT: debug_value %0 : $Optional<(Int, Int)> // let a + // CHECK-NEXT: debug_value %0 : $Optional<(Int, Int)>, let, name "a" // CHECK-NEXT: switch_enum %0 : $Optional<(Int, Int)>, case #Optional.Some!enumelt.1: bb1, default bb2 guard let (x, y) = a else { } @@ -685,9 +685,9 @@ func let_else_tuple_binding(a : (Int, Int)?) -> Int { // CHECK: bb1(%3 : $(Int, Int)): // CHECK-NEXT: %4 = tuple_extract %3 : $(Int, Int), 0 - // CHECK-NEXT: debug_value %4 : $Int // let x + // CHECK-NEXT: debug_value %4 : $Int, let, name "x" // CHECK-NEXT: %6 = tuple_extract %3 : $(Int, Int), 1 - // CHECK-NEXT: debug_value %6 : $Int // let y + // CHECK-NEXT: debug_value %6 : $Int, let, name "y" // CHECK-NEXT: return %4 : $Int } diff --git a/test/SILGen/struct_resilience.swift b/test/SILGen/struct_resilience.swift index 22fdf878f774a..505733c31afed 100644 --- a/test/SILGen/struct_resilience.swift +++ b/test/SILGen/struct_resilience.swift @@ -14,20 +14,20 @@ func functionWithResilientTypes(s: Size, f: Size -> Size) -> Size { // CHECK: copy_addr %1 to [initialization] [[OTHER_SIZE_BOX:%.*]]#1 : $*Size var s2 = s -// CHECK: copy_addr %1 to [initialization] [[SIZE_BOX:%.*]]#1 : $*Size +// CHECK: copy_addr %1 to [initialization] [[SIZE_BOX:%.*]] : $*Size // CHECK: [[FN:%.*]] = function_ref @_TFV16resilient_struct4Sizeg1wSi : $@convention(method) (@in_guaranteed Size) -> Int -// CHECK: [[RESULT:%.*]] = apply [[FN]]([[SIZE_BOX]]#1) +// CHECK: [[RESULT:%.*]] = apply [[FN]]([[SIZE_BOX]]) // CHECK: [[FN:%.*]] = function_ref @_TFV16resilient_struct4Sizes1wSi : $@convention(method) (Int, @inout Size) -> () // CHECK: apply [[FN]]([[RESULT]], [[OTHER_SIZE_BOX]]#1) s2.w = s.w -// CHECK: copy_addr %1 to [initialization] [[SIZE_BOX:%.*]]#1 : $*Size +// CHECK: copy_addr %1 to [initialization] [[SIZE_BOX:%.*]] : $*Size // CHECK: [[FN:%.*]] = function_ref @_TFV16resilient_struct4Sizeg1hSi : $@convention(method) (@in_guaranteed Size) -> Int -// CHECK: [[RESULT:%.*]] = apply [[FN]]([[SIZE_BOX]]#1) +// CHECK: [[RESULT:%.*]] = apply [[FN]]([[SIZE_BOX]]) _ = s.h -// CHECK: copy_addr %1 to [initialization] [[SIZE_BOX:%.*]]#1 : $*Size -// CHECK: apply %2(%0, [[SIZE_BOX]]#1) +// CHECK: copy_addr %1 to [initialization] [[SIZE_BOX:%.*]] : $*Size +// CHECK: apply %2(%0, [[SIZE_BOX]]) // CHECK: return return f(s) } @@ -95,8 +95,8 @@ public func functionWithMyResilientTypes(s: MySize, f: MySize -> MySize) -> MySi // CHECK: [[RESULT:%.*]] = load [[RESULT_ADDR]] : $*Int _ = s.h -// CHECK: copy_addr %1 to [initialization] [[SIZE_BOX:%.*]]#1 : $*MySize -// CHECK: apply %2(%0, [[SIZE_BOX]]#1) +// CHECK: copy_addr %1 to [initialization] [[SIZE_BOX:%.*]] : $*MySize +// CHECK: apply %2(%0, [[SIZE_BOX]]) // CHECK: return return f(s) } diff --git a/test/SILGen/super.swift b/test/SILGen/super.swift new file mode 100644 index 0000000000000..10b478b6bf963 --- /dev/null +++ b/test/SILGen/super.swift @@ -0,0 +1,101 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: %target-swift-frontend -emit-module -emit-module-path=%t/resilient_class.swiftmodule -module-name resilient_class %S/../Inputs/resilient_class.swift +// RUN: %target-swift-frontend -use-native-super-method -emit-silgen -parse-as-library -I %t %s | FileCheck %s + +import resilient_class + +public class Parent { + public final var finalProperty: String { + return "Parent.finalProperty" + } + + public var property: String { + return "Parent.property" + } + + public final class var finalClassProperty: String { + return "Parent.finalProperty" + } + + public class var classProperty: String { + return "Parent.property" + } + + public func methodOnlyInParent() {} + public final func finalMethodOnlyInParent() {} + public func method() {} + + public final class func finalClassMethodOnlyInParent() {} + public class func classMethod() {} +} + +public class Child : Parent { + // CHECK-LABEL: sil @_TFC5super5Childg8propertySS + // CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $Child to $Parent + // CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $Child, #Parent.property!getter.1 + public override var property: String { + return super.property + } + + // CHECK-LABEL: sil @_TFC5super5Childg13otherPropertySS + // CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $Child to $Parent + // CHECK: [[SUPER_METHOD:%[0-9]+]] = function_ref @_TFC5super6Parentg13finalPropertySS + public var otherProperty: String { + return super.finalProperty + } +} + +public class Grandchild : Child { + // CHECK-LABEL: sil @_TFC5super10Grandchild16onlyInGrandchildfT_T_ + public func onlyInGrandchild() { + // CHECK: super_method %0 : $Grandchild, #Parent.methodOnlyInParent!1 : (Parent) -> () -> () + super.methodOnlyInParent() + // CHECK: function_ref @_TFC5super6Parent23finalMethodOnlyInParentfT_T_ + super.finalMethodOnlyInParent() + } + + // CHECK-LABEL: sil @_TFC5super10Grandchild6methodfT_T_ + public override func method() { + // CHECK: super_method %0 : $Grandchild, #Parent.method!1 : (Parent) -> () -> () + super.method() + } +} + +public class GreatGrandchild : Grandchild { + // CHECK-LABEL: sil @_TFC5super15GreatGrandchild6methodfT_T_ + public override func method() { + // CHECK: super_method {{%[0-9]+}} : $GreatGrandchild, #Grandchild.method!1 : (Grandchild) -> () -> () , $@convention(method) (@guaranteed Grandchild) -> () + super.method() + } +} + +public class ChildToResilientParent : ResilientOutsideParent { + public override func method() { + super.method() + } + + public override class func classMethod() { + super.classMethod() + } +} + +public class ChildToFixedParent : OutsideParent { + public override func method() { + super.method() + } + + public override class func classMethod() { + super.classMethod() + } +} + +public extension ResilientOutsideChild { + public func callSuperMethod() { + super.method() + } + + public class func callSuperClassMethod() { + super.classMethod() + } +} diff --git a/test/SILGen/super_class_method.swift b/test/SILGen/super_class_method.swift deleted file mode 100644 index eb8bcc959fbbf..0000000000000 --- a/test/SILGen/super_class_method.swift +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %target-swift-frontend -emit-silgen -sdk %S/Inputs -I %S/Inputs -enable-source-import %s | FileCheck %s - -// REQUIRES: objc_interop - -import Foundation -class MyFunkyDictionary: NSDictionary { - // CHECK-LABEL: sil hidden @_TZFC18super_class_method17MyFunkyDictionary10initialize - // CHECK: super_method [volatile] %0 : $@thick MyFunkyDictionary.Type, #NSObject.initialize!1.foreign : NSObject.Type -> () -> () - override class func initialize() { - super.initialize() - } -} - diff --git a/test/SILGen/super_init_refcounting.swift b/test/SILGen/super_init_refcounting.swift index 8b8a31e59c2bc..bb0e4b89c4299 100644 --- a/test/SILGen/super_init_refcounting.swift +++ b/test/SILGen/super_init_refcounting.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-silgen %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -emit-silgen %s | FileCheck %s class Foo { init() {} @@ -14,7 +14,7 @@ class Bar: Foo { // CHECK-NOT: strong_retain [[ORIG_SELF]] // CHECK: [[ORIG_SELF_UP:%.*]] = upcast [[ORIG_SELF]] // CHECK-NOT: strong_retain [[ORIG_SELF_UP]] - // CHECK: [[SUPER_INIT:%.*]] = function_ref @_TFC22super_init_refcounting3Fooc + // CHECK: [[SUPER_INIT:%[0-9]+]] = super_method [[ORIG_SELF]] : $Bar, #Foo.init!initializer.1 // CHECK: [[NEW_SELF:%.*]] = apply [[SUPER_INIT]]([[ORIG_SELF_UP]]) // CHECK: [[NEW_SELF_DOWN:%.*]] = unchecked_ref_cast [[NEW_SELF]] // CHECK: store [[NEW_SELF_DOWN]] to [[SELF_MUI]] @@ -42,7 +42,7 @@ class Zim: Foo { // CHECK-LABEL: sil hidden @_TFC22super_init_refcounting3Zimc // CHECK-NOT: strong_retain // CHECK-NOT: strong_release - // CHECK: function_ref @_TFC22super_init_refcounting3Fooc + // CHECK: super_method {{%[0-9]+}} : $Zim, #Foo.init!initializer.1 } class Zang: Foo { @@ -55,7 +55,7 @@ class Zang: Foo { // CHECK-LABEL: sil hidden @_TFC22super_init_refcounting4Zangc // CHECK-NOT: strong_retain // CHECK-NOT: strong_release - // CHECK: function_ref @_TFC22super_init_refcounting3Fooc + // CHECK: super_method {{%[0-9]+}} : $Zang, #Foo.init!initializer.1 } class Bad: Foo { @@ -78,7 +78,7 @@ class Good: Foo { // CHECK: assign {{.*}} to [[X_ADDR]] : $*Int // CHECK: [[SELF_OBJ:%.*]] = load [[SELF]] : $*Good // CHECK: [[SUPER_OBJ:%.*]] = upcast [[SELF_OBJ]] : $Good to $Foo - // CHECK: [[SUPER_INIT:%.*]] = function_ref @_TFC22super_init_refcounting3Fooc + // CHECK: [[SUPER_INIT:%.*]] = super_method [[SELF_OBJ]] : $Good, #Foo.init!initializer.1 // CHECK: [[SELF_OBJ:%.*]] = load [[SELF]] // CHECK: [[X_ADDR:%.*]] = ref_element_addr [[SELF_OBJ]] : $Good, #Good.x // CHECK: [[X:%.*]] = load [[X_ADDR]] : $*Int diff --git a/test/SILGen/super_objc_class_method.swift b/test/SILGen/super_objc_class_method.swift new file mode 100644 index 0000000000000..42e9c57fb4e75 --- /dev/null +++ b/test/SILGen/super_objc_class_method.swift @@ -0,0 +1,13 @@ +// RUN: %target-swift-frontend -emit-silgen -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -use-native-super-method | FileCheck %s + +// REQUIRES: objc_interop + +import Foundation +class MyFunkyDictionary: NSDictionary { + // CHECK-LABEL: sil hidden @_TZFC23super_objc_class_method17MyFunkyDictionary10initializefT_T_ + // CHECK: super_method [volatile] %0 : $@thick MyFunkyDictionary.Type, #NSObject.initialize!1.foreign : NSObject.Type -> () -> () + override class func initialize() { + super.initialize() + } +} + diff --git a/test/SILGen/switch.swift b/test/SILGen/switch.swift index 2a738e8f5a99b..621411abf7517 100644 --- a/test/SILGen/switch.swift +++ b/test/SILGen/switch.swift @@ -316,17 +316,17 @@ struct Z : P { func p() {} } // CHECK-LABEL: sil hidden @_TF6switch10test_isa_1FT1pPS_1P__T_ func test_isa_1(p p: P) { // CHECK: [[PTMPBUF:%[0-9]+]] = alloc_stack $P - // CHECK-NEXT: copy_addr %0 to [initialization] [[PTMPBUF]]#1 : $*P + // CHECK-NEXT: copy_addr %0 to [initialization] [[PTMPBUF]] : $*P switch p { // CHECK: [[TMPBUF:%[0-9]+]] = alloc_stack $X - // CHECK: checked_cast_addr_br copy_on_success P in [[P:%.*]] : $*P to X in [[TMPBUF]]#1 : $*X, [[IS_X:bb[0-9]+]], [[IS_NOT_X:bb[0-9]+]] + // CHECK: checked_cast_addr_br copy_on_success P in [[P:%.*]] : $*P to X in [[TMPBUF]] : $*X, [[IS_X:bb[0-9]+]], [[IS_NOT_X:bb[0-9]+]] case is X: // CHECK: [[IS_X]]: - // CHECK-NEXT: load [[TMPBUF]]#1 - // CHECK-NEXT: dealloc_stack [[TMPBUF]]#0 - // CHECK-NEXT: destroy_addr [[PTMPBUF]]#1 - // CHECK-NEXT: dealloc_stack [[PTMPBUF]]#0 + // CHECK-NEXT: load [[TMPBUF]] + // CHECK-NEXT: dealloc_stack [[TMPBUF]] + // CHECK-NEXT: destroy_addr [[PTMPBUF]] + // CHECK-NEXT: dealloc_stack [[PTMPBUF]] a() // CHECK: function_ref @_TF6switch1aFT_T_ // CHECK: br [[CONT:bb[0-9]+]] @@ -939,20 +939,20 @@ func ~=(a: P, b: P) -> Bool { return true } // CHECK-LABEL: sil hidden @_TF6switch22test_struct_pattern_aoFT1sVS_19StructPatternTestAO1pPS_1P__T_ func test_struct_pattern_ao(s s: StructPatternTestAO, p: P) { // CHECK: [[S:%.*]] = alloc_stack $StructPatternTestAO - // CHECK: copy_addr %0 to [initialization] [[S]]#1 - // CHECK: [[T0:%.*]] = struct_element_addr [[S]]#1 : $*StructPatternTestAO, #StructPatternTestAO.x + // CHECK: copy_addr %0 to [initialization] [[S]] + // CHECK: [[T0:%.*]] = struct_element_addr [[S]] : $*StructPatternTestAO, #StructPatternTestAO.x // CHECK: [[X:%.*]] = load [[T0]] - // CHECK: [[T0:%.*]] = struct_element_addr [[S]]#1 : $*StructPatternTestAO, #StructPatternTestAO.y + // CHECK: [[T0:%.*]] = struct_element_addr [[S]] : $*StructPatternTestAO, #StructPatternTestAO.y // CHECK: [[Y:%.*]] = alloc_stack $P - // CHECK: copy_addr [[T0]] to [initialization] [[Y]]#1 + // CHECK: copy_addr [[T0]] to [initialization] [[Y]] switch s { // CHECK: cond_br {{%.*}}, [[IS_CASE1:bb[0-9]+]], [[IS_NOT_CASE1:bb[0-9]+]] // CHECK: [[IS_CASE1]]: - // CHECK: destroy_addr [[Y]]#1 - // CHECK: dealloc_stack [[Y]]#0 - // CHECK: destroy_addr [[S]]#1 - // CHECK: dealloc_stack [[S]]#0 + // CHECK: destroy_addr [[Y]] + // CHECK: dealloc_stack [[Y]] + // CHECK: destroy_addr [[S]] + // CHECK: dealloc_stack [[S]] case StructPatternTestAO(x: 0): // CHECK: function_ref @_TF6switch1aFT_T_ // CHECK: br [[CONT:bb[0-9]+]] @@ -960,30 +960,30 @@ func test_struct_pattern_ao(s s: StructPatternTestAO, p: P) { // CHECK: [[IS_NOT_CASE1]]: // CHECK: [[TEMP:%.*]] = alloc_stack $P - // CHECK: copy_addr [[Y]]#1 to [initialization] [[TEMP]]#1 + // CHECK: copy_addr [[Y]] to [initialization] [[TEMP]] // CHECK: cond_br {{%.*}}, [[IS_CASE2:bb[0-9]+]], [[IS_NOT_CASE2:bb[0-9]+]] // CHECK: [[IS_CASE2]]: case StructPatternTestAO(y: p): - // CHECK: destroy_addr [[TEMP]]#1 - // CHECK: dealloc_stack [[TEMP]]#0 - // CHECK: destroy_addr [[Y]]#1 - // CHECK: dealloc_stack [[Y]]#0 - // CHECK: destroy_addr [[S]]#1 - // CHECK: dealloc_stack [[S]]#0 + // CHECK: destroy_addr [[TEMP]] + // CHECK: dealloc_stack [[TEMP]] + // CHECK: destroy_addr [[Y]] + // CHECK: dealloc_stack [[Y]] + // CHECK: destroy_addr [[S]] + // CHECK: dealloc_stack [[S]] // CHECK: function_ref @_TF6switch1bFT_T_ // CHECK: br [[CONT]] b() // CHECK: [[IS_NOT_CASE2]]: - // CHECK: destroy_addr [[TEMP]]#1 - // CHECK: dealloc_stack [[TEMP]]#0 + // CHECK: destroy_addr [[TEMP]] + // CHECK: dealloc_stack [[TEMP]] // CHECK: br [[IS_CASE3:bb[0-9]+]] // CHECK: [[IS_CASE3]]: - // CHECK: destroy_addr [[Y]]#1 - // CHECK: dealloc_stack [[Y]]#0 - // CHECK: destroy_addr [[S]]#1 - // CHECK: dealloc_stack [[S]]#0 + // CHECK: destroy_addr [[Y]] + // CHECK: dealloc_stack [[Y]] + // CHECK: destroy_addr [[S]] + // CHECK: dealloc_stack [[S]] case StructPatternTestAO(x: _): // CHECK: function_ref @_TF6switch1cFT_T_ // CHECK: br [[CONT]] @@ -1236,14 +1236,14 @@ func testOptionalPattern(value : Int?) { // switch on the enum kind. There should be no unreachable generated. // CHECK-LABEL: sil hidden @_TF6switch19testOptionalEnumMixFGSqSi_Si func testOptionalEnumMix(a : Int?) -> Int { - // CHECK: debug_value %0 : $Optional // let a + // CHECK: debug_value %0 : $Optional, let, name "a" // CHECK-NEXT: switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: [[SOMEBB:bb[0-9]+]], case #Optional.None!enumelt: [[NILBB:bb[0-9]+]] switch a { case let x?: return 0 // CHECK: [[SOMEBB]](%3 : $Int): - // CHECK-NEXT: debug_value %3 : $Int // let x + // CHECK-NEXT: debug_value %3 : $Int, let, name "x" // CHECK: integer_literal $Builtin.Int2048, 0 case .None: @@ -1258,14 +1258,14 @@ func testOptionalEnumMix(a : Int?) -> Int { // switch on the enum kind. There should be no unreachable generated. // CHECK-LABEL: sil hidden @_TF6switch26testOptionalEnumMixWithNilFGSqSi_Si func testOptionalEnumMixWithNil(a : Int?) -> Int { - // CHECK: debug_value %0 : $Optional // let a + // CHECK: debug_value %0 : $Optional, let, name "a" // CHECK-NEXT: switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: [[SOMEBB:bb[0-9]+]], case #Optional.None!enumelt: [[NILBB:bb[0-9]+]] switch a { case let x?: return 0 // CHECK: [[SOMEBB]](%3 : $Int): - // CHECK-NEXT: debug_value %3 : $Int // let x + // CHECK-NEXT: debug_value %3 : $Int, let, name "x" // CHECK: integer_literal $Builtin.Int2048, 0 case nil: diff --git a/test/SILGen/switch_isa.swift b/test/SILGen/switch_isa.swift index 74023ce942a66..ace03189b0daf 100644 --- a/test/SILGen/switch_isa.swift +++ b/test/SILGen/switch_isa.swift @@ -13,11 +13,11 @@ func testSwitchOnExistential(value: Any) { // CHECK-LABEL: sil hidden @_TF10switch_isa23testSwitchOnExistentialFP_T_ : // CHECK: [[ANY:%.*]] = alloc_stack $protocol<> -// CHECK: copy_addr %0 to [initialization] [[ANY]]#1 +// CHECK: copy_addr %0 to [initialization] [[ANY]] // CHECK: [[BOOL:%.*]] = alloc_stack $Bool -// CHECK: checked_cast_addr_br copy_on_success protocol<> in [[ANY]]#1 : $*protocol<> to Bool in [[BOOL]]#1 : $*Bool, [[IS_BOOL:bb[0-9]+]], [[IS_NOT_BOOL:bb[0-9]+]] +// CHECK: checked_cast_addr_br copy_on_success protocol<> in [[ANY]] : $*protocol<> to Bool in [[BOOL]] : $*Bool, [[IS_BOOL:bb[0-9]+]], [[IS_NOT_BOOL:bb[0-9]+]] // CHECK: [[IS_BOOL]]: -// CHECK: [[T0:%.*]] = load [[BOOL]]#1 +// CHECK: [[T0:%.*]] = load [[BOOL]] enum Foo { case A diff --git a/test/SILGen/toplevel.swift b/test/SILGen/toplevel.swift index 5a19c3a6a8ea7..dce4b991cddf0 100644 --- a/test/SILGen/toplevel.swift +++ b/test/SILGen/toplevel.swift @@ -73,7 +73,7 @@ print_y() // CHECK: [[SOME_CASE]]([[VALUE:%.+]] : $A): // CHECK: [[SINK:%.+]] = function_ref @_TF8toplevel8markUsed // CHECK-NOT: release -// CHECK: store [[VALUE]] to [[BOX:%.+]]#1 : $*A +// CHECK: store [[VALUE]] to [[BOX:%.+]] : $*A // CHECK-NOT: release // CHECK: apply [[SINK]]({{%.+}}) class A {} diff --git a/test/SILGen/toplevel_errors.swift b/test/SILGen/toplevel_errors.swift index 6ffbdfcfb857a..dc684a5bca7a0 100644 --- a/test/SILGen/toplevel_errors.swift +++ b/test/SILGen/toplevel_errors.swift @@ -8,9 +8,8 @@ throw MyError.A // CHECK: sil @main // CHECK: [[ERR:%.*]] = alloc_existential_box $ErrorType, $MyError -// CHECK: [[T0:%.*]] = function_ref @_TFO15toplevel_errors7MyError1AFMS0_S0_ -// CHECK: [[T1:%.*]] = apply [[T0]]( -// CHECK: store [[T1]] to [[ERR]]#1 : $*MyError +// CHECK: [[T0:%.*]] = enum $MyError, #MyError.A!enumelt +// CHECK: store [[T0]] to [[ERR]]#1 : $*MyError // CHECK: builtin "willThrow"([[ERR]]#0 : $ErrorType) // CHECK: br bb2([[ERR]]#0 : $ErrorType) @@ -21,4 +20,4 @@ throw MyError.A // CHECK: builtin "errorInMain"([[T0]] : $ErrorType) // CHECK: [[T0:%.*]] = integer_literal $Builtin.Int32, 1 // CHECK: [[T1:%.*]] = struct $Int32 ([[T0]] : $Builtin.Int32) -// CHECK: br bb1([[T1]] : $Int32) \ No newline at end of file +// CHECK: br bb1([[T1]] : $Int32) diff --git a/test/SILGen/transparent_attribute.swift b/test/SILGen/transparent_attribute.swift index c5393dfa128c8..4ec33e6eeab3c 100644 --- a/test/SILGen/transparent_attribute.swift +++ b/test/SILGen/transparent_attribute.swift @@ -1,12 +1,12 @@ // RUN: %target-swift-frontend -emit-silgen -emit-verbose-sil %s | FileCheck %s -// Test if 'transparent' atribute gets propagated correctly to apply instructions. +// Test if 'transparent' attribute gets propagated correctly to apply instructions. // Test that the attribute gets set on default argument generators. @_transparent func transparentFuncWithDefaultArgument (x: Int = 1) -> Int { return x } -func useTransparentFuncWithDefaultArgument() ->Int { +func useTransparentFuncWithDefaultArgument() -> Int { return transparentFuncWithDefaultArgument(); // CHECK-LABEL: sil hidden @_TF21transparent_attribute37useTransparentFuncWithDefaultArgumentFT_Si @@ -71,8 +71,8 @@ var x2 : MySt { func testProperty(z: MySt) { x1 = z x2 = z - var m1 : MySt = x1; - var m2 : MySt = x2; + var m1 : MySt = x1 + var m2 : MySt = x2 // CHECK-APPLY: sil hidden @_TF21transparent_attribute12testPropertyFT1zVS_4MySt_T_ // CHECK: function_ref @_TF21transparent_attributes2x1VS_4MySt // CHECK-NEXT: apply @@ -142,9 +142,8 @@ func testEnumExtension() { MyEnum.onetransp.tr3() // CHECK-APPLY: sil hidden @_TF21transparent_attribute17testEnumExtensionFT_T_ // CHECK: [[TR3:%[0-9]+]] = function_ref @_TFO21transparent_attribute6MyEnum3tr3 - // CHECK: [[INIT:%[0-9]+]] = function_ref @_TFO21transparent_attribute6MyEnum9onetransp - // CHECK: apply [[INIT]] - // CHECK: apply [[TR3]] + // CHECK: [[INIT:%[0-9]+]] = enum $MyEnum, #MyEnum.onetransp!enumelt + // CHECK: apply [[TR3]]([[INIT]]) } struct testVarDecl { diff --git a/test/SILGen/tuples.swift b/test/SILGen/tuples.swift index 61cffb9372305..bee4b05ba59bd 100644 --- a/test/SILGen/tuples.swift +++ b/test/SILGen/tuples.swift @@ -28,10 +28,10 @@ func testShuffleOpaque() { // CHECK: [[T0:%.*]] = function_ref @_TF6tuples7make_xyFT_T1xSi1yPS_1P__ // CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $(x: Int, y: P) - // CHECK-NEXT: apply [[T0]]([[TEMP]]#1) - // CHECK-NEXT: [[T0:%.*]] = tuple_element_addr [[TEMP]]#1 : $*(x: Int, y: P), 0 + // CHECK-NEXT: apply [[T0]]([[TEMP]]) + // CHECK-NEXT: [[T0:%.*]] = tuple_element_addr [[TEMP]] : $*(x: Int, y: P), 0 // CHECK-NEXT: [[T1:%.*]] = load [[T0]] : $*Int - // CHECK-NEXT: [[T2:%.*]] = tuple_element_addr [[TEMP]]#1 : $*(x: Int, y: P), 1 + // CHECK-NEXT: [[T2:%.*]] = tuple_element_addr [[TEMP]] : $*(x: Int, y: P), 1 // CHECK-NEXT: store [[T1]] to [[Y]]#1 // CHECK-NEXT: copy_addr [take] [[T2]] to [initialization] [[X]]#1 // CHECK-NEXT: dealloc_stack [[TEMP]] @@ -43,10 +43,10 @@ func testShuffleOpaque() { // CHECK-NEXT: // function_ref // CHECK-NEXT: [[T0:%.*]] = function_ref @_TF6tuples7make_xyFT_T1xSi1yPS_1P__ // CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $(x: Int, y: P) - // CHECK-NEXT: apply [[T0]]([[TEMP]]#1) - // CHECK-NEXT: [[T0:%.*]] = tuple_element_addr [[TEMP]]#1 : $*(x: Int, y: P), 0 + // CHECK-NEXT: apply [[T0]]([[TEMP]]) + // CHECK-NEXT: [[T0:%.*]] = tuple_element_addr [[TEMP]] : $*(x: Int, y: P), 0 // CHECK-NEXT: [[T1:%.*]] = load [[T0]] : $*Int - // CHECK-NEXT: [[T2:%.*]] = tuple_element_addr [[TEMP]]#1 : $*(x: Int, y: P), 1 + // CHECK-NEXT: [[T2:%.*]] = tuple_element_addr [[TEMP]] : $*(x: Int, y: P), 1 // CHECK-NEXT: store [[T1]] to [[PAIR_1]] // CHECK-NEXT: copy_addr [take] [[T2]] to [initialization] [[PAIR_0]] // CHECK-NEXT: dealloc_stack [[TEMP]] @@ -55,16 +55,16 @@ func testShuffleOpaque() { // CHECK-NEXT: // function_ref // CHECK-NEXT: [[T0:%.*]] = function_ref @_TF6tuples7make_xyFT_T1xSi1yPS_1P__ // CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $(x: Int, y: P) - // CHECK-NEXT: apply [[T0]]([[TEMP]]#1) - // CHECK-NEXT: [[T0:%.*]] = tuple_element_addr [[TEMP]]#1 : $*(x: Int, y: P), 0 + // CHECK-NEXT: apply [[T0]]([[TEMP]]) + // CHECK-NEXT: [[T0:%.*]] = tuple_element_addr [[TEMP]] : $*(x: Int, y: P), 0 // CHECK-NEXT: [[T1:%.*]] = load [[T0]] : $*Int - // CHECK-NEXT: [[T2:%.*]] = tuple_element_addr [[TEMP]]#1 : $*(x: Int, y: P), 1 + // CHECK-NEXT: [[T2:%.*]] = tuple_element_addr [[TEMP]] : $*(x: Int, y: P), 1 // CHECK-NEXT: [[TEMP2:%.*]] = alloc_stack $(y: P, x: Int) - // CHECK-NEXT: [[TEMP2_0:%.*]] = tuple_element_addr [[TEMP2]]#1 : $*(y: P, x: Int), 0 + // CHECK-NEXT: [[TEMP2_0:%.*]] = tuple_element_addr [[TEMP2]] : $*(y: P, x: Int), 0 // CHECK-NEXT: copy_addr [take] [[T2]] to [initialization] [[TEMP2_0]] - // CHECK-NEXT: [[TEMP2_1:%.*]] = tuple_element_addr [[TEMP2]]#1 : $*(y: P, x: Int), 1 + // CHECK-NEXT: [[TEMP2_1:%.*]] = tuple_element_addr [[TEMP2]] : $*(y: P, x: Int), 1 // CHECK-NEXT: store [[T1]] to [[TEMP2_1]] - // CHECK-NEXT: copy_addr [take] [[TEMP2]]#1 to [[PAIR]]#1 + // CHECK-NEXT: copy_addr [take] [[TEMP2]] to [[PAIR]]#1 // CHECK-NEXT: dealloc_stack [[TEMP2]] // CHECK-NEXT: dealloc_stack [[TEMP]] pair = make_xy() @@ -102,13 +102,13 @@ func testShuffleTuple() { // CHECK-NEXT: // function_ref // CHECK-NEXT: [[T0:%.*]] = function_ref @_TF6tuples6make_pFT_PS_1P_ // CHECK-NEXT: [[TEMP:%.*]] = alloc_stack $P - // CHECK-NEXT: apply [[T0]]([[TEMP]]#1) + // CHECK-NEXT: apply [[T0]]([[TEMP]]) // CHECK-NEXT: [[TEMP2:%.*]] = alloc_stack $(y: P, x: Int) - // CHECK-NEXT: [[TEMP2_0:%.*]] = tuple_element_addr [[TEMP2]]#1 : $*(y: P, x: Int), 0 - // CHECK-NEXT: copy_addr [take] [[TEMP]]#1 to [initialization] [[TEMP2_0]] - // CHECK-NEXT: [[TEMP2_1:%.*]] = tuple_element_addr [[TEMP2]]#1 : $*(y: P, x: Int), 1 + // CHECK-NEXT: [[TEMP2_0:%.*]] = tuple_element_addr [[TEMP2]] : $*(y: P, x: Int), 0 + // CHECK-NEXT: copy_addr [take] [[TEMP]] to [initialization] [[TEMP2_0]] + // CHECK-NEXT: [[TEMP2_1:%.*]] = tuple_element_addr [[TEMP2]] : $*(y: P, x: Int), 1 // CHECK-NEXT: store [[INT]] to [[TEMP2_1]] - // CHECK-NEXT: copy_addr [take] [[TEMP2]]#1 to [[PAIR]]#1 + // CHECK-NEXT: copy_addr [take] [[TEMP2]] to [[PAIR]]#1 // CHECK-NEXT: dealloc_stack [[TEMP2]] // CHECK-NEXT: dealloc_stack [[TEMP]] pair = (x: make_int(), y: make_p()) diff --git a/test/SILGen/union.swift b/test/SILGen/union.swift deleted file mode 100644 index 3ddbec2e8ee05..0000000000000 --- a/test/SILGen/union.swift +++ /dev/null @@ -1,74 +0,0 @@ -// RUN: %target-swift-frontend -emit-silgen -parse-as-library %s | FileCheck %s - -enum Boolish { - case falsy - case truthy -} - -// CHECK-LABEL: sil hidden [transparent] @_TFO5union7Boolish5falsyFMS0_S0_ : $@convention(thin) (@thin Boolish.Type) -> Boolish { -// CHECK: bb0({{%.*}} : $@thin Boolish.Type): -// CHECK: [[RES:%.*]] = enum $Boolish, #Boolish.falsy!enumelt -// CHECK: return [[RES]] : $Boolish -// CHECK: } - -// CHECK-LABEL: sil hidden [transparent] @_TFO5union7Boolish6truthyFMS0_S0_ : $@convention(thin) (@thin Boolish.Type) -> Boolish { -// CHECK: bb0({{%.*}} : $@thin Boolish.Type): -// CHECK: [[RES:%.*]] = enum $Boolish, #Boolish.truthy!enumelt -// CHECK: return [[RES]] : $Boolish -// CHECK: } - -enum Optionable { - case nought - case mere(Int) -} - -// CHECK-LABEL: sil hidden [transparent] @_TFO5union10Optionable6noughtFMS0_S0_ : $@convention(thin) (@thin Optionable.Type) -> Optionable { -// CHECK: bb0({{%.*}} : $@thin Optionable.Type): -// CHECK: [[RES:%.*]] = enum $Optionable, #Optionable.nought!enumelt -// CHECK: return [[RES]] : $Optionable -// CHECK: } - -// CHECK-LABEL: sil hidden [transparent] @_TFO5union10Optionable4merefMS0_FSiS0_ : $@convention(thin) (Int, @thin Optionable.Type) -> Optionable { -// CHECK: bb0([[ARG:%.*]] : $Int, {{%.*}} : $@thin Optionable.Type): -// CHECK: [[RES:%.*]] = enum $Optionable, #Optionable.mere!enumelt.1, [[ARG]] : $Int -// CHECK: return [[RES]] : $Optionable -// CHECK: } - -// CHECK-LABEL: sil hidden @_TF5uniong6truthyOS_7Boolish -var truthy : Boolish { - // CHECK: [[TRUTHY:%[0-9]+]] = function_ref @_TFO5union7Boolish6truthyFMS0_S0_ - // CHECK: [[BOOLISH:%[0-9]+]] = metatype $@thin Boolish.Type - // CHECK: [[RESULT:%[0-9]+]] = apply [[TRUTHY]]([[BOOLISH]]) - // CHECK: return [[RESULT]] - return .truthy -} - -// CHECK-LABEL: sil hidden @_TF5uniong5falsyOS_7Boolish -var falsy : Boolish { - // CHECK: [[FALSY:%[0-9]+]] = function_ref @_TFO5union7Boolish5falsyFMS0_S0_ - // CHECK: [[BOOLISH:%[0-9]+]] = metatype $@thin Boolish.Type - // CHECK: [[RESULT:%[0-9]+]] = apply [[FALSY]]([[BOOLISH]]) - // CHECK: return [[RESULT]] - return .falsy -} - -protocol P {} - -enum AddressOnly { - case nought - case mere(P) -} - -// CHECK-LABEL: sil hidden [transparent] @_TFO5union11AddressOnly6noughtFMS0_S0_ : $@convention(thin) (@out AddressOnly, @thin AddressOnly.Type) -> () { -// CHECK: bb0([[RET:%.*]] : $*AddressOnly, {{%.*}} : $@thin AddressOnly.Type): -// CHECK: inject_enum_addr [[RET]] : $*AddressOnly, #AddressOnly.nought!enumelt -// CHECK: return -// CHECK: } - -// CHECK-LABEL: sil hidden [transparent] @_TFO5union11AddressOnly4merefMS0_FPS_1P_S0_ : $@convention(thin) (@out AddressOnly, @in P, @thin AddressOnly.Type) -> () { -// CHECK: bb0([[RET:%.*]] : $*AddressOnly, [[DATA:%.*]] : $*P, {{%.*}} : $@thin AddressOnly.Type): -// CHECK: [[RET_DATA:%.*]] = init_enum_data_addr [[RET]] : $*AddressOnly, #AddressOnly.mere!enumelt.1 // user: %4 -// CHECK: copy_addr [take] [[DATA]] to [initialization] [[RET_DATA]] : $*P -// CHECK: inject_enum_addr [[RET]] : $*AddressOnly, #AddressOnly.mere!enumelt.1 -// CHECK: return -// CHECK: } diff --git a/test/SILGen/unmanaged.swift b/test/SILGen/unmanaged.swift index 55ccdf6290414..ba499e1d7cebb 100644 --- a/test/SILGen/unmanaged.swift +++ b/test/SILGen/unmanaged.swift @@ -32,7 +32,7 @@ func get(inout holder holder: Holder) -> C { } // CHECK-LABEL:sil hidden @_TF9unmanaged3getFT6holderRVS_6Holder_CS_1C : $@convention(thin) (@inout Holder) -> @owned C // CHECK: bb0([[ADDR:%.*]] : $*Holder): -// CHECK-NEXT: debug_value_addr %0 : $*Holder // var holder, argno: 1 +// CHECK-NEXT: debug_value_addr %0 : $*Holder, var, name "holder", argno 1 // CHECK-NEXT: [[T0:%.*]] = struct_element_addr [[ADDR]] : $*Holder, #Holder.value // CHECK-NEXT: [[T1:%.*]] = load [[T0]] : $*@sil_unmanaged C // CHECK-NEXT: [[T2:%.*]] = unmanaged_to_ref [[T1]] diff --git a/test/SILGen/unowned.swift b/test/SILGen/unowned.swift index f25c369024c26..8ff8f5f2a333a 100644 --- a/test/SILGen/unowned.swift +++ b/test/SILGen/unowned.swift @@ -72,7 +72,7 @@ func unowned_local() -> C { // CHECK: [[c:%.*]] = apply let c = C() - // CHECK: [[uc:%.*]] = alloc_box $@sil_unowned C // let uc + // CHECK: [[uc:%.*]] = alloc_box $@sil_unowned C, let, name "uc" // CHECK-NEXT: [[tmp1:%.*]] = ref_to_unowned [[c]] : $C to $@sil_unowned C // CHECK-NEXT: unowned_retain [[tmp1]] // CHECK-NEXT: store [[tmp1]] to [[uc]]#1 @@ -96,10 +96,10 @@ func test_unowned_let_capture(aC : C) { // CHECK-LABEL: sil shared @_TFF7unowned24test_unowned_let_captureFCS_1CT_U_FT_Si : $@convention(thin) (@owned @sil_unowned C) -> Int { // CHECK: bb0([[ARG:%.*]] : $@sil_unowned C): -// CHECK-NEXT: debug_value %0 : $@sil_unowned C // let bC, argno: 1 +// CHECK-NEXT: debug_value %0 : $@sil_unowned C, let, name "bC", argno 1 // CHECK-NEXT: strong_retain_unowned [[ARG]] : $@sil_unowned C // CHECK-NEXT: [[UNOWNED_ARG:%.*]] = unowned_to_ref [[ARG]] : $@sil_unowned C to $C -// CHECK-NEXT: [[FUN:%.*]] = class_method [[UNOWNED_ARG]] : $C, #C.f!1 : C -> () -> Int , $@convention(method) (@guaranteed C) -> Int +// CHECK-NEXT: [[FUN:%.*]] = class_method [[UNOWNED_ARG]] : $C, #C.f!1 : (C) -> () -> Int , $@convention(method) (@guaranteed C) -> Int // CHECK-NEXT: [[RESULT:%.*]] = apply [[FUN]]([[UNOWNED_ARG]]) : $@convention(method) (@guaranteed C) -> Int // CHECK-NEXT: strong_release [[UNOWNED_ARG]] // CHECK-NEXT: unowned_release [[ARG]] : $@sil_unowned C diff --git a/test/SILGen/unreachable_code.swift b/test/SILGen/unreachable_code.swift index 7c39a7205b769..a39cf9335b007 100644 --- a/test/SILGen/unreachable_code.swift +++ b/test/SILGen/unreachable_code.swift @@ -1,9 +1,9 @@ // RUN: %target-swift-frontend -emit-sil %s -o /dev/null -verify func testUnreachableAfterReturn() -> Int { - var x: Int = 3; - return x; - x++ //expected-warning {{code after 'return' will never be executed}} + var x: Int = 3 + return x + x += 1 //expected-warning {{code after 'return' will never be executed}} } func testUnreachableAfterIfReturn(a: Bool) -> Int { @@ -16,43 +16,43 @@ func testUnreachableAfterIfReturn(a: Bool) -> Int { } func testUnreachableForAfterContinue(b: Bool) { - for (var i:Int = 0; i<10; i++) { - var y: Int = 300; - y++; + for (var i:Int = 0; i<10; i+=1) { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + var y: Int = 300 + y += 1 if b { - break; - y++; // expected-warning {{code after 'break' will never be executed}} + break + y += 1 // expected-warning {{code after 'break' will never be executed}} } - continue; - y--; // expected-warning {{code after 'continue' will never be executed}} + continue + y -= 1 // expected-warning {{code after 'continue' will never be executed}} } } func testUnreachableWhileAfterContinue(b: Bool) { - var i:Int = 0; + var i:Int = 0 while (i<10) { - var y: Int = 300; - y++; + var y: Int = 300 + y += 1 if b { - break; - y++; // expected-warning {{code after 'break' will never be executed}} + break + y += 1 // expected-warning {{code after 'break' will never be executed}} } - continue; - i++; // expected-warning {{code after 'continue' will never be executed}} + continue + i += 1 // expected-warning {{code after 'continue' will never be executed}} } } func testBreakAndContinue() { - var i = 0; - var m = 0; - for (i = 0; i < 10; ++i) { - m++ + var i = 0 + var m = 0 + for (i = 0; i < 10; i += 1) { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + m += 1 if m == 15 { break } else { continue } - m++ // expected-warning {{will never be executed}} + m += 1 // expected-warning {{will never be executed}} } } diff --git a/test/SILGen/vtable_thunks.swift b/test/SILGen/vtable_thunks.swift index cc676c018a932..797f235604add 100644 --- a/test/SILGen/vtable_thunks.swift +++ b/test/SILGen/vtable_thunks.swift @@ -92,7 +92,7 @@ class F: D { // CHECK-LABEL: sil private @_TTVFC13vtable_thunks1D3iuo // CHECK: [[WRAP_X:%.*]] = enum $Optional // CHECK: [[FORCE_UNWRAP_FN:%.*]] = function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue -// CHECK: apply [[FORCE_UNWRAP_FN]]([[UNWRAP_Y_ADDR:%.*]]#1, +// CHECK: apply [[FORCE_UNWRAP_FN]]([[UNWRAP_Y_ADDR:%[0-9]*]], // CHECK: [[UNWRAP_Y:%.*]] = load [[UNWRAP_Y_ADDR]] // CHECK: [[RES:%.*]] = apply {{%.*}}([[WRAP_X]], [[UNWRAP_Y]], %2, %3) // CHECK: [[WRAP_RES:%.*]] = enum $Optional, {{.*}} [[RES]] @@ -104,9 +104,9 @@ class F: D { // CHECK: copy_addr [take] {{%.*}} to [initialization] [[WRAPPED_X_ADDR]] // CHECK: inject_enum_addr [[WRAP_X_ADDR]] // CHECK: [[RES_ADDR:%.*]] = alloc_stack -// CHECK: apply {{%.*}}([[RES_ADDR]]#1, [[WRAP_X_ADDR]], %2, %3) +// CHECK: apply {{%.*}}([[RES_ADDR]], [[WRAP_X_ADDR]], %2, %3) // CHECK: [[DEST_ADDR:%.*]] = init_enum_data_addr %0 -// CHECK: copy_addr [take] [[RES_ADDR]]#1 to [initialization] [[DEST_ADDR]] +// CHECK: copy_addr [take] [[RES_ADDR]] to [initialization] [[DEST_ADDR]] // CHECK: inject_enum_addr %0 class ThrowVariance { diff --git a/test/SILGen/weak.swift b/test/SILGen/weak.swift index 2777e25a9545c..fa4b90ac04c9b 100644 --- a/test/SILGen/weak.swift +++ b/test/SILGen/weak.swift @@ -21,7 +21,7 @@ func test0(c c: C) { // CHECK: [[A:%.*]] = mark_uninitialized [var] [[A1]]#1 weak var x = c -// CHECK: [[X:%.*]] = alloc_box $@sil_weak Optional // var x +// CHECK: [[X:%.*]] = alloc_box $@sil_weak Optional, var, name "x" // Implicit conversion // CHECK-NEXT: [[TMP:%.*]] = load [[C]]#1 : $*C // CHECK-NEXT: strong_retain [[TMP]] : $C @@ -45,12 +45,13 @@ func test0(c c: C) { // silgen crashes on weak capture // CHECK: weak.(testClosureOverWeak () -> ()).(closure #1) -// CHECK-LABEL: sil shared @_TFF4weak19testClosureOverWeakFT_T_U_FT_Si : $@convention(thin) (@owned @box @sil_weak Optional, @inout @sil_weak Optional) -> Int { -// CHECK: bb0(%0 : $@box @sil_weak Optional, %1 : $*@sil_weak Optional): -// CHECK-NEXT: debug_value_addr %1 : $*@sil_weak Optional // var bC, argno: 1 +// CHECK-LABEL: sil shared @_TFF4weak19testClosureOverWeakFT_T_U_FT_Si : $@convention(thin) (@owned @box @sil_weak Optional) -> Int { +// CHECK: bb0(%0 : $@box @sil_weak Optional): +// CHECK-NEXT: %1 = project_box %0 +// CHECK-NEXT: debug_value_addr %1 : $*@sil_weak Optional, var, name "bC", argno 1 // CHECK-NEXT: %3 = alloc_stack $Optional // CHECK-NEXT: %4 = load_weak %1 : $*@sil_weak Optional -// CHECK-NEXT: store %4 to %3#1 : $*Optional +// CHECK-NEXT: store %4 to %3 : $*Optional func testClosureOverWeak() { weak var bC = C() takeClosure { bC!.f() } diff --git a/test/SILGen/witnesses.swift b/test/SILGen/witnesses.swift index d029f3f20ad1f..8f75f3c9dbbe5 100644 --- a/test/SILGen/witnesses.swift +++ b/test/SILGen/witnesses.swift @@ -226,14 +226,14 @@ struct ConformsWithMoreGeneric : X, Y { // CHECK-NEXT: // function_ref // CHECK-NEXT: %4 = function_ref @_TFV9witnesses23ConformsWithMoreGeneric9selfTypes{{.*}} : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @inout ConformsWithMoreGeneric) -> () // CHECK-NEXT: %5 = alloc_stack $ConformsWithMoreGeneric - // CHECK-NEXT: store %3 to %5#1 : $*ConformsWithMoreGeneric + // CHECK-NEXT: store %3 to %5 : $*ConformsWithMoreGeneric // CHECK-NEXT: %7 = alloc_stack $ConformsWithMoreGeneric - // CHECK-NEXT: %8 = apply %4(%7#1, %5#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @inout ConformsWithMoreGeneric) -> () - // CHECK-NEXT: %9 = load %7#1 : $*ConformsWithMoreGeneric + // CHECK-NEXT: %8 = apply %4(%7, %5, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @inout ConformsWithMoreGeneric) -> () + // CHECK-NEXT: %9 = load %7 : $*ConformsWithMoreGeneric // CHECK-NEXT: store %9 to %0 : $*ConformsWithMoreGeneric // CHECK-NEXT: %11 = tuple () - // CHECK-NEXT: dealloc_stack %7#0 : $*@local_storage ConformsWithMoreGeneric - // CHECK-NEXT: dealloc_stack %5#0 : $*@local_storage ConformsWithMoreGeneric + // CHECK-NEXT: dealloc_stack %7 : $*ConformsWithMoreGeneric + // CHECK-NEXT: dealloc_stack %5 : $*ConformsWithMoreGeneric // CHECK-NEXT: return %11 : $() // CHECK-NEXT: } func loadable(x x: F) -> F { return x } @@ -264,12 +264,12 @@ struct ConformsWithMoreGeneric : X, Y { // CHECK-NEXT: // function_ref witnesses.ConformsWithMoreGeneric.classes // CHECK-NEXT: %2 = function_ref @_TFV9witnesses23ConformsWithMoreGeneric7classes{{.*}} : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @inout ConformsWithMoreGeneric) -> () // CHECK-NEXT: %3 = alloc_stack $A2 - // CHECK-NEXT: store %0 to %3#1 : $*A2 + // CHECK-NEXT: store %0 to %3 : $*A2 // CHECK-NEXT: %5 = alloc_stack $A2 - // CHECK-NEXT: %6 = apply %2(%5#1, %3#1, %1) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @inout ConformsWithMoreGeneric) -> () - // CHECK-NEXT: %7 = load %5#1 : $*A2 - // CHECK-NEXT: dealloc_stack %5#0 : $*@local_storage A2 - // CHECK-NEXT: dealloc_stack %3#0 : $*@local_storage A2 + // CHECK-NEXT: %6 = apply %2(%5, %3, %1) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @inout ConformsWithMoreGeneric) -> () + // CHECK-NEXT: %7 = load %5 : $*A2 + // CHECK-NEXT: dealloc_stack %5 : $*A2 + // CHECK-NEXT: dealloc_stack %3 : $*A2 // CHECK-NEXT: return %7 : $A2 // CHECK-NEXT: } } @@ -281,17 +281,17 @@ func <~> (x: J, y: K) -> K { return y } // CHECK-NEXT: // function_ref // CHECK-NEXT: %6 = function_ref @_TZF9witnessesoi3ltg{{.*}} : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Y, τ_0_1 : Y> (@out τ_0_1, @in τ_0_0, @in τ_0_1) -> () // CHECK-NEXT: %7 = alloc_stack $ConformsWithMoreGeneric -// CHECK-NEXT: store %4 to %7#1 : $*ConformsWithMoreGeneric +// CHECK-NEXT: store %4 to %7 : $*ConformsWithMoreGeneric // CHECK-NEXT: %9 = alloc_stack $ConformsWithMoreGeneric -// CHECK-NEXT: store %5 to %9#1 : $*ConformsWithMoreGeneric +// CHECK-NEXT: store %5 to %9 : $*ConformsWithMoreGeneric // CHECK-NEXT: %11 = alloc_stack $ConformsWithMoreGeneric -// CHECK-NEXT: %12 = apply %6(%11#1, %7#1, %9#1) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Y, τ_0_1 : Y> (@out τ_0_1, @in τ_0_0, @in τ_0_1) -> () -// CHECK-NEXT: %13 = load %11#1 : $*ConformsWithMoreGeneric +// CHECK-NEXT: %12 = apply %6(%11, %7, %9) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Y, τ_0_1 : Y> (@out τ_0_1, @in τ_0_0, @in τ_0_1) -> () +// CHECK-NEXT: %13 = load %11 : $*ConformsWithMoreGeneric // CHECK-NEXT: store %13 to %0 : $*ConformsWithMoreGeneric // CHECK-NEXT: %15 = tuple () -// CHECK-NEXT: dealloc_stack %11#0 : $*@local_storage ConformsWithMoreGeneric -// CHECK-NEXT: dealloc_stack %9#0 : $*@local_storage ConformsWithMoreGeneric -// CHECK-NEXT: dealloc_stack %7#0 : $*@local_storage ConformsWithMoreGeneric +// CHECK-NEXT: dealloc_stack %11 : $*ConformsWithMoreGeneric +// CHECK-NEXT: dealloc_stack %9 : $*ConformsWithMoreGeneric +// CHECK-NEXT: dealloc_stack %7 : $*ConformsWithMoreGeneric // CHECK-NEXT: return %15 : $() // CHECK-NEXT: } @@ -382,15 +382,15 @@ struct IUOFailableModel : NonFailableRefinement, IUOFailableRequirement { // CHECK: [[INIT:%[0-9]+]] = function_ref @_TFV9witnesses16IUOFailableModelC{{.*}} : $@convention(thin) (Int, @thin IUOFailableModel.Type) -> ImplicitlyUnwrappedOptional // CHECK: [[IUO_RESULT:%[0-9]+]] = apply [[INIT]]([[FOO]], [[META]]) : $@convention(thin) (Int, @thin IUOFailableModel.Type) -> ImplicitlyUnwrappedOptional // CHECK: [[IUO_RESULT_TEMP:%[0-9]+]] = alloc_stack $ImplicitlyUnwrappedOptional - // CHECK: store [[IUO_RESULT]] to [[IUO_RESULT_TEMP]]#1 : $*ImplicitlyUnwrappedOptional + // CHECK: store [[IUO_RESULT]] to [[IUO_RESULT_TEMP]] : $*ImplicitlyUnwrappedOptional // CHECK: [[FORCE_FN:%[0-9]+]] = function_ref @_TFs36_getImplicitlyUnwrappedOptionalValue{{.*}} : $@convention(thin) <τ_0_0> (@out τ_0_0, @in ImplicitlyUnwrappedOptional<τ_0_0>) -> () // CHECK: [[RESULT_TEMP:%[0-9]+]] = alloc_stack $IUOFailableModel - // CHECK: apply [[FORCE_FN]]([[RESULT_TEMP]]#1, [[IUO_RESULT_TEMP]]#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in ImplicitlyUnwrappedOptional<τ_0_0>) -> () - // CHECK: [[RESULT:%[0-9]+]] = load [[RESULT_TEMP]]#1 : $*IUOFailableModel + // CHECK: apply [[FORCE_FN]]([[RESULT_TEMP]], [[IUO_RESULT_TEMP]]) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in ImplicitlyUnwrappedOptional<τ_0_0>) -> () + // CHECK: [[RESULT:%[0-9]+]] = load [[RESULT_TEMP]] : $*IUOFailableModel // CHECK: store [[RESULT]] to [[SELF]] : $*IUOFailableModel - // CHECK: dealloc_stack [[RESULT_TEMP]]#0 : $*@local_storage IUOFailableModel - // CHECK: dealloc_stack [[IUO_RESULT_TEMP]]#0 : $*@local_storage ImplicitlyUnwrappedOptional + // CHECK: dealloc_stack [[RESULT_TEMP]] : $*IUOFailableModel + // CHECK: dealloc_stack [[IUO_RESULT_TEMP]] : $*ImplicitlyUnwrappedOptional // CHECK: return init!(foo: Int) { return nil } } diff --git a/test/SILGen/writeback.swift b/test/SILGen/writeback.swift index 7631970c25101..194998a513969 100644 --- a/test/SILGen/writeback.swift +++ b/test/SILGen/writeback.swift @@ -51,12 +51,12 @@ x.foo() // CHECK: [[X_TEMP:%.*]] = alloc_stack $Foo // CHECK: [[GET_X:%.*]] = function_ref @_TF9writebackg1xVS_3Foo : $@convention(thin) () -> Foo // CHECK: [[X:%.*]] = apply [[GET_X]]() : $@convention(thin) () -> Foo -// CHECK: store [[X]] to [[X_TEMP]]#1 -// CHECK: apply [[FOO]]([[X_TEMP]]#1) : $@convention(method) (@inout Foo) -> () -// CHECK: [[X1:%.*]] = load [[X_TEMP]]#1 : $*Foo +// CHECK: store [[X]] to [[X_TEMP]] +// CHECK: apply [[FOO]]([[X_TEMP]]) : $@convention(method) (@inout Foo) -> () +// CHECK: [[X1:%.*]] = load [[X_TEMP]] : $*Foo // CHECK: [[SET_X:%.*]] = function_ref @_TF9writebacks1xVS_3Foo : $@convention(thin) (Foo) -> () // CHECK: apply [[SET_X]]([[X1]]) : $@convention(thin) (Foo) -> () -// CHECK: dealloc_stack [[X_TEMP]]#0 : $*@local_storage Foo +// CHECK: dealloc_stack [[X_TEMP]] : $*Foo // Writeback to inout argument bar(x: &x) @@ -64,12 +64,12 @@ bar(x: &x) // CHECK: [[X_TEMP:%.*]] = alloc_stack $Foo // CHECK: [[GET_X:%.*]] = function_ref @_TF9writebackg1xVS_3Foo : $@convention(thin) () -> Foo // CHECK: [[X:%.*]] = apply [[GET_X]]() : $@convention(thin) () -> Foo -// CHECK: store [[X]] to [[X_TEMP]]#1 : $*Foo -// CHECK: apply [[BAR]]([[X_TEMP]]#1) : $@convention(thin) (@inout Foo) -> () -// CHECK: [[X1:%.*]] = load [[X_TEMP]]#1 : $*Foo +// CHECK: store [[X]] to [[X_TEMP]] : $*Foo +// CHECK: apply [[BAR]]([[X_TEMP]]) : $@convention(thin) (@inout Foo) -> () +// CHECK: [[X1:%.*]] = load [[X_TEMP]] : $*Foo // CHECK: [[SET_X:%.*]] = function_ref @_TF9writebacks1xVS_3Foo : $@convention(thin) (Foo) -> () // CHECK: apply [[SET_X]]([[X1]]) : $@convention(thin) (Foo) -> () -// CHECK: dealloc_stack [[X_TEMP]]#0 : $*@local_storage Foo +// CHECK: dealloc_stack [[X_TEMP]] : $*Foo // Writeback to curried arguments bas(x: &x)(y: &y) @@ -143,11 +143,11 @@ funge(x: &addressOnly) // CHECK: [[FUNGE:%.*]] = function_ref @_TF9writeback5fungeFT1xRPS_8Fungible__T_ : $@convention(thin) (@inout Fungible) -> () // CHECK: [[TEMP:%.*]] = alloc_stack $Fungible // CHECK: [[GET:%.*]] = function_ref @_TF9writebackg11addressOnlyPS_8Fungible_ : $@convention(thin) (@out Fungible) -> () -// CHECK: apply [[GET]]([[TEMP]]#1) : $@convention(thin) (@out Fungible) -> () -// CHECK: apply [[FUNGE]]([[TEMP]]#1) : $@convention(thin) (@inout Fungible) -> () +// CHECK: apply [[GET]]([[TEMP]]) : $@convention(thin) (@out Fungible) -> () +// CHECK: apply [[FUNGE]]([[TEMP]]) : $@convention(thin) (@inout Fungible) -> () // CHECK: [[SET:%.*]] = function_ref @_TF9writebacks11addressOnlyPS_8Fungible_ : $@convention(thin) (@in Fungible) -> () -// CHECK: apply [[SET]]([[TEMP]]#1) : $@convention(thin) (@in Fungible) -> () -// CHECK: dealloc_stack [[TEMP]]#0 : $*@local_storage Fungible +// CHECK: apply [[SET]]([[TEMP]]) : $@convention(thin) (@in Fungible) -> () +// CHECK: dealloc_stack [[TEMP]] : $*Fungible // Test that writeback occurs with generic properties. // diff --git a/test/SILAnalysis/DestructorAnalysis.swift b/test/SILOptimizer/DestructorAnalysis.swift similarity index 100% rename from test/SILAnalysis/DestructorAnalysis.swift rename to test/SILOptimizer/DestructorAnalysis.swift diff --git a/test/SILPasses/Inputs/BaseProblem.swift b/test/SILOptimizer/Inputs/BaseProblem.swift similarity index 100% rename from test/SILPasses/Inputs/BaseProblem.swift rename to test/SILOptimizer/Inputs/BaseProblem.swift diff --git a/test/SILPasses/Inputs/Problems.swift b/test/SILOptimizer/Inputs/Problems.swift similarity index 100% rename from test/SILPasses/Inputs/Problems.swift rename to test/SILOptimizer/Inputs/Problems.swift diff --git a/test/SILPasses/Inputs/TestMod.sil b/test/SILOptimizer/Inputs/TestMod.sil similarity index 100% rename from test/SILPasses/Inputs/TestMod.sil rename to test/SILOptimizer/Inputs/TestMod.sil diff --git a/test/SILPasses/Inputs/TestModule.swift b/test/SILOptimizer/Inputs/TestModule.swift similarity index 100% rename from test/SILPasses/Inputs/TestModule.swift rename to test/SILOptimizer/Inputs/TestModule.swift diff --git a/test/SILPasses/Inputs/capture_propagation_linkage/main.swift b/test/SILOptimizer/Inputs/capture_propagation_linkage/main.swift similarity index 100% rename from test/SILPasses/Inputs/capture_propagation_linkage/main.swift rename to test/SILOptimizer/Inputs/capture_propagation_linkage/main.swift diff --git a/test/SILPasses/Inputs/devirt_access_helper.swift b/test/SILOptimizer/Inputs/devirt_access_helper.swift similarity index 100% rename from test/SILPasses/Inputs/devirt_access_helper.swift rename to test/SILOptimizer/Inputs/devirt_access_helper.swift diff --git a/test/SILPasses/Inputs/devirt_access_other_module.swift b/test/SILOptimizer/Inputs/devirt_access_other_module.swift similarity index 100% rename from test/SILPasses/Inputs/devirt_access_other_module.swift rename to test/SILOptimizer/Inputs/devirt_access_other_module.swift diff --git a/test/SILPasses/Inputs/include/Gizmo.h b/test/SILOptimizer/Inputs/include/Gizmo.h similarity index 100% rename from test/SILPasses/Inputs/include/Gizmo.h rename to test/SILOptimizer/Inputs/include/Gizmo.h diff --git a/test/SILPasses/Inputs/include/module.map b/test/SILOptimizer/Inputs/include/module.map similarity index 100% rename from test/SILPasses/Inputs/include/module.map rename to test/SILOptimizer/Inputs/include/module.map diff --git a/test/SILPasses/Inputs/internal_func.swift b/test/SILOptimizer/Inputs/internal_func.swift similarity index 100% rename from test/SILPasses/Inputs/internal_func.swift rename to test/SILOptimizer/Inputs/internal_func.swift diff --git a/test/SILPasses/Inputs/linker_pass_input.swift b/test/SILOptimizer/Inputs/linker_pass_input.swift similarity index 100% rename from test/SILPasses/Inputs/linker_pass_input.swift rename to test/SILOptimizer/Inputs/linker_pass_input.swift diff --git a/test/SILPasses/Inputs/public_class.swift b/test/SILOptimizer/Inputs/public_class.swift similarity index 100% rename from test/SILPasses/Inputs/public_class.swift rename to test/SILOptimizer/Inputs/public_class.swift diff --git a/test/SILPasses/Inputs/sil_witness_tables_external_input.swift b/test/SILOptimizer/Inputs/sil_witness_tables_external_input.swift similarity index 100% rename from test/SILPasses/Inputs/sil_witness_tables_external_input.swift rename to test/SILOptimizer/Inputs/sil_witness_tables_external_input.swift diff --git a/test/SILPasses/abcopts.sil b/test/SILOptimizer/abcopts.sil similarity index 92% rename from test/SILPasses/abcopts.sil rename to test/SILOptimizer/abcopts.sil index 5765dca8d11d4..1b0e5fe15b8c3 100644 --- a/test/SILPasses/abcopts.sil +++ b/test/SILOptimizer/abcopts.sil @@ -6,6 +6,7 @@ sil_stage canonical import Builtin import Swift +struct _DependenceToken {} struct ArrayIntBuffer { var storage : Builtin.NativeObject } @@ -31,14 +32,14 @@ bb0(%0 : $*ArrayInt, %1 : $*ArrayInt): // Don't assert on functions that are marked with array semantics but are not // methods. - %302 = function_ref @checkbounds_no_meth : $@convention(thin) (Int32, Bool, @owned ArrayInt) -> () + %302 = function_ref @checkbounds_no_meth : $@convention(thin) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %303 = load %0 : $*ArrayInt %304 = struct_extract %303 : $ArrayInt, #ArrayInt.buffer %305 = struct_extract %304 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %305 : $Builtin.NativeObject %306 = integer_literal $Builtin.Int32, 0 %307 = struct $Int32(%306 : $Builtin.Int32) - %308 = apply %302(%307, %102, %303) : $@convention(thin) (Int32, Bool, @owned ArrayInt) -> () + %308 = apply %302(%307, %102, %303) : $@convention(thin) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: [[CHECKBOUNDSNO:%[0-9]+]] = function_ref @checkbounds_no_meth %200 = function_ref @arrayinit: $@convention(thin) () -> @owned ArrayInt @@ -47,7 +48,7 @@ bb0(%0 : $*ArrayInt, %1 : $*ArrayInt): // CHECK: [[CHECKBOUNDS:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD1:%[0-9]+]] = load %0 - %2 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %2 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %3 = load %0 : $*ArrayInt %4 = struct_extract %3 : $ArrayInt, #ArrayInt.buffer %5 = struct_extract %4 : $ArrayIntBuffer, #ArrayIntBuffer.storage @@ -56,32 +57,32 @@ bb0(%0 : $*ArrayInt, %1 : $*ArrayInt): // First check. %x1 = integer_literal $Builtin.Int32, 1 %i1 = struct $Int32(%x1 : $Builtin.Int32) - %8 = apply %2(%i1, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %8 = apply %2(%i1, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: [[IDX1:%[0-9]+]] = struct $Int32 // CHECK: apply [[CHECKBOUNDS]]([[IDX1]] // Redundant same index and array. retain_value %5 : $Builtin.NativeObject - %9 = apply %2(%i1, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %9 = apply %2(%i1, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK-NOT: apply [[CHECKBOUNDS]]([[IDX1]] // Redundant same index and array and retain the array directly instead of // through the array buffer storage. retain_value %3 : $ArrayInt - %r9 = apply %2(%i1, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %r9 = apply %2(%i1, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK-NOT: apply [[CHECKBOUNDS]]([[IDX1]] // Redundant same index and array, but loaded again. %l0 = load %0 : $*ArrayInt retain_value %5 : $Builtin.NativeObject - %10 = apply %2(%i1, %102, %l0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %10 = apply %2(%i1, %102, %l0) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK-NOT: apply [[CHECKBOUNDS]]([[IDX1]] // Not redundant - different index. %x2 = integer_literal $Builtin.Int32, 2 %i2 = struct $Int32(%x2 : $Builtin.Int32) retain_value %5 : $Builtin.NativeObject - %12 = apply %2(%i2, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %12 = apply %2(%i2, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: [[IDX2:%[0-9]+]] = struct $Int32 // CHECK: apply [[CHECKBOUNDS]]([[IDX2]] @@ -90,17 +91,17 @@ bb0(%0 : $*ArrayInt, %1 : $*ArrayInt): %14 = struct_extract %13 : $ArrayInt, #ArrayInt.buffer %15 = struct_extract %14 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %15 : $Builtin.NativeObject - %16 = apply %2(%i1, %102, %13) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %16 = apply %2(%i1, %102, %13) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: [[LD2:%[0-9]+]] = load %1 // CHECK: apply [[CHECKBOUNDS]]([[IDX1]], {{.*}}[[LD2]] // Not redundant same index and array but append in between. %17 = function_ref @append : $@convention(method) (@in Int32, @inout ArrayInt) -> () %18 = alloc_stack $Int32 - %19 = apply %17(%18#1, %0) : $@convention(method) (@in Int32, @inout ArrayInt) -> () + %19 = apply %17(%18, %0) : $@convention(method) (@in Int32, @inout ArrayInt) -> () retain_value %5 : $Builtin.NativeObject %l2 = load %0 : $*ArrayInt - %20 = apply %2(%i1, %102, %l2) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %20 = apply %2(%i1, %102, %l2) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: [[LD2:%[0-9]+]] = load %0 // CHECK: apply [[CHECKBOUNDS]]([[IDX1]], {{.*}}[[LD2]] @@ -109,7 +110,7 @@ bb0(%0 : $*ArrayInt, %1 : $*ArrayInt): %x3 = integer_literal $Builtin.Int32, 3 %i3 = struct $Int32(%x3 : $Builtin.Int32) retain_value %5 : $Builtin.NativeObject - %21 = apply %2(%i3, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %21 = apply %2(%i3, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: [[IDX3:%[0-9]+]] = struct $Int32 // CHECK: apply [[CHECKBOUNDS]]([[IDX3]], {{.*}}[[LD1]] %22 = function_ref @unknown_func : $@convention(thin) () -> () @@ -119,14 +120,14 @@ bb0(%0 : $*ArrayInt, %1 : $*ArrayInt): %l3 = load %0 : $*ArrayInt // CHECK: [[LD3:%[0-9]+]] = load %0 retain_value %5 : $Builtin.NativeObject - %24 = apply %2(%i3, %102, %l3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %24 = apply %2(%i3, %102, %l3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: apply [[CHECKBOUNDS]]([[IDX3]], {{.*}}[[LD3]] // Not redundant same index and array but odd store in between. %x4 = integer_literal $Builtin.Int32, 4 %i4 = struct $Int32(%x4 : $Builtin.Int32) retain_value %5 : $Builtin.NativeObject - %25 = apply %2(%i4, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %25 = apply %2(%i4, %102, %3) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: [[IDX4:%[0-9]+]] = struct $Int32 // CHECK: apply [[CHECKBOUNDS]]([[IDX4]], {{.*}}[[LD1]] %26 = ref_to_raw_pointer %5 : $Builtin.NativeObject to $Builtin.RawPointer @@ -134,12 +135,12 @@ bb0(%0 : $*ArrayInt, %1 : $*ArrayInt): %29 = store %x1 to %27 : $*Builtin.Int32 %l4 = load %0 : $*ArrayInt retain_value %5 : $Builtin.NativeObject - %30 = apply %2(%i4, %102, %l4) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %30 = apply %2(%i4, %102, %l4) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: store // CHECK: [[LD4:%[0-9]+]] = load %0 // CHECK: apply [[CHECKBOUNDS]]([[IDX4]], {{.*}}[[LD4]] - %98 = dealloc_stack %18#0 : $*@local_storage Int32 + %98 = dealloc_stack %18 : $*Int32 %99 = tuple () return %99 : $() // CHECK: return @@ -167,12 +168,12 @@ bb4: // CHECK: [[IDX1:%[0-9]+]] = struct $Int32 bb5: - %32 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %32 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %33 = load %24 : $*ArrayInt %34 = struct_extract %33 : $ArrayInt, #ArrayInt.buffer %35 = struct_extract %34 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %35 : $Builtin.NativeObject - %38 = apply %32(%37, %101, %33) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %38 = apply %32(%37, %101, %33) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken br bb2 // CHECK: [[CHECKBOUNDS:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD1:%[0-9]+]] = load {{.*}} : $*ArrayInt @@ -181,12 +182,12 @@ bb5: bb6: // CHECK: [[CHECKBOUNDS2:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD2:%[0-9]+]] = load {{.*}} : $*ArrayInt - %42 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %42 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %43 = load %24 : $*ArrayInt %44 = struct_extract %43 : $ArrayInt, #ArrayInt.buffer %45 = struct_extract %44 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %45 : $Builtin.NativeObject - %48 = apply %42(%37, %101, %43) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %48 = apply %42(%37, %101, %43) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: apply [[CHECKBOUNDS2]]([[IDX1]] br bb2 @@ -230,24 +231,24 @@ bb4: // CHECK: [[IDX1:%[0-9]+]] = struct $Int32 // CHECK: [[CHECKBOUNDS3:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD3:%[0-9]+]] = load {{.*}} : $*ArrayInt - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %53 = load %24 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: apply [[CHECKBOUNDS3]]([[IDX1]], {{.*}}[[LD3]] cond_br %8, bb5, bb6 bb5: // CHECK: [[CHECKBOUNDS:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD1:%[0-9]+]] = load {{.*}} : $*ArrayInt - %32 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %32 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %33 = load %24 : $*ArrayInt %34 = struct_extract %33 : $ArrayInt, #ArrayInt.buffer %35 = struct_extract %34 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %35 : $Builtin.NativeObject - %38 = apply %32(%37, %101, %33) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %38 = apply %32(%37, %101, %33) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK-NOT: apply [[CHECKBOUNDS]]([[IDX1]], {{.*}}[[LD1]] br bb2 @@ -255,12 +256,12 @@ bb5: bb6: // CHECK: [[CHECKBOUNDS2:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD2:%[0-9]+]] = load {{.*}} : $*ArrayInt - %42 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %42 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %43 = load %24 : $*ArrayInt %44 = struct_extract %43 : $ArrayInt, #ArrayInt.buffer %45 = struct_extract %44 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %45 : $Builtin.NativeObject - %48 = apply %42(%37, %101, %43) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %48 = apply %42(%37, %101, %43) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK-NOT: apply [[CHECKBOUNDS2]]([[IDX1]], {{.*}}[[LD2]] br bb2 @@ -304,36 +305,36 @@ bb4: // CHECK: [[IDX1:%[0-9]+]] = struct $Int32 // CHECK: [[CHECKBOUNDS3:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD3:%[0-9]+]] = load {{.*}} : $*ArrayInt - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %53 = load %24 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: apply [[CHECKBOUNDS3]]([[IDX1]], {{.*}}[[LD3]] cond_br %8, bb5, bb6 bb5: // CHECK: [[CHECKBOUNDS:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD1:%[0-9]+]] = load {{.*}} : $*ArrayInt - %32 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %32 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %33 = load %24 : $*ArrayInt %34 = struct_extract %33 : $ArrayInt, #ArrayInt.buffer %35 = struct_extract %34 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %35 : $Builtin.NativeObject - %38 = apply %32(%37, %101, %33) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %38 = apply %32(%37, %101, %33) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: apply [[CHECKBOUNDS]]([[IDX1]], {{.*}}[[LD1]] br bb2 bb6: // CHECK: [[CHECKBOUNDS2:%[0-9]+]] = function_ref @checkbounds // CHECK: [[LD2:%[0-9]+]] = load {{.*}} : $*ArrayInt - %42 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %42 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %43 = load %24 : $*ArrayInt %44 = struct_extract %43 : $ArrayInt, #ArrayInt.buffer %45 = struct_extract %44 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %45 : $Builtin.NativeObject - %48 = apply %42(%37, %101, %43) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %48 = apply %42(%37, %101, %43) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken // CHECK: apply [[CHECKBOUNDS2]]([[IDX1]], {{.*}}[[LD2]] br bb2 @@ -350,10 +351,10 @@ bb2: %21 = tuple_extract %20 : $(Builtin.Int32, Builtin.Int1), 0 %117 = function_ref @append : $@convention(method) (@in Int32, @inout ArrayInt) -> () %118 = alloc_stack $Int32 - %119 = apply %117(%118#1, %24) : $@convention(method) (@in Int32, @inout ArrayInt) -> () + %119 = apply %117(%118, %24) : $@convention(method) (@in Int32, @inout ArrayInt) -> () retain_value %55 : $Builtin.NativeObject - %120 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () - dealloc_stack %118#0 : $*@local_storage Int32 + %120 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken + dealloc_stack %118 : $*Int32 // CHECK: [[APPEND:%[0-9]+]] = function_ref @append // CHECK: apply [[APPEND]] // CHECK: apply [[CHECKBOUNDS3]] @@ -420,12 +421,12 @@ bb1(%4 : $Builtin.Int32): bb4: %37 = struct $Int32(%4 : $Builtin.Int32) - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %53 = load %24 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %10 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %10 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) @@ -480,12 +481,12 @@ bb1(%4 : $Builtin.Int32): cond_br %8, bb3, bb4 bb4: - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %53 = load %24 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %10 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %10 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) @@ -524,8 +525,8 @@ bb0(%0 : $Int32): br bb1(%2 : $Builtin.Int32) bb1(%4 : $Builtin.Int32): - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () - %58 = apply %52(%37, %101, %x53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken + %58 = apply %52(%37, %101, %x53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %10 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %10 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) @@ -578,12 +579,12 @@ bb1(%4 : $Builtin.Int32): bb4: %37 = struct $Int32(%4 : $Builtin.Int32) - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %53 = load %24 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %10 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %10 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) @@ -625,14 +626,14 @@ bb2(%i0 : $Builtin.Int32): cond_br undef, bb3, bb4 bb3: - %f2 = function_ref @checkbounds2 : $@convention(method) (Int32, Bool, @owned Array) -> () + %f2 = function_ref @checkbounds2 : $@convention(method) (Int32, Bool, @owned Array) -> _DependenceToken retain_value %0 : $Array %t3 = struct $Int32(%i0 : $Builtin.Int32) // This subscript check can be completely eliminated because the loop goes // from 0 to array.count. // It's even not required that this loop block dominates the exit block. - %t4 = apply %f2(%t3, %101, %0) : $@convention(method) (Int32, Bool, @owned Array) -> () + %t4 = apply %f2(%t3, %101, %0) : $@convention(method) (Int32, Bool, @owned Array) -> _DependenceToken br bb4 bb4: @@ -667,13 +668,13 @@ bb0(%0 : $ArraySlice): cond_br %t2, bb2, bb1(%z0 : $Builtin.Int32) bb1(%i0 : $Builtin.Int32): - %f2 = function_ref @checkbounds3 : $@convention(method) (Int32, Bool, @owned ArraySlice) -> () + %f2 = function_ref @checkbounds3 : $@convention(method) (Int32, Bool, @owned ArraySlice) -> _DependenceToken retain_value %0 : $ArraySlice %t3 = struct $Int32(%i0 : $Builtin.Int32) - // Slices don't necessarily have a zero lower bound. So we can't elminate the + // Slices don't necessarily have a zero lower bound. So we can't eliminate the // subscript check for 0..) -> () + %t4 = apply %f2(%t3, %101, %0) : $@convention(method) (Int32, Bool, @owned ArraySlice) -> _DependenceToken %t5 = integer_literal $Builtin.Int1, 0 %i2 = integer_literal $Builtin.Int32, 1 @@ -725,12 +726,12 @@ bb1(%4 : $Builtin.Int32): bb4: %37 = struct $Int32(%4 : $Builtin.Int32) - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %53 = load %24 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %10 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %10 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) @@ -795,12 +796,12 @@ bb1(%4 : $Builtin.Int32): bb4: %37 = struct $Int32(%4 : $Builtin.Int32) - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %53 = load %24 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %10 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %10 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) @@ -851,17 +852,17 @@ bb1(%4 : $Builtin.Int32): bb4: %36 = alloc_stack $ArrayInt %37 = struct $Int32(%4 : $Builtin.Int32) - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () - %53 = load %36#1 : $*ArrayInt + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken + %53 = load %36 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %101, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %10 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %10 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) %21 = tuple_extract %20 : $(Builtin.Int32, Builtin.Int1), 0 - dealloc_stack %36 : $*@local_storage ArrayInt + dealloc_stack %36 : $*ArrayInt br bb1(%21 : $Builtin.Int32) bb3: @@ -890,12 +891,12 @@ bb1(%4 : $Builtin.Int32): bb4: %37 = struct $Int32(%4 : $Builtin.Int32) - %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %52 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %53 = load %24 : $*ArrayInt %54 = struct_extract %53 : $ArrayInt, #ArrayInt.buffer %55 = struct_extract %54 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %55 : $Builtin.NativeObject - %58 = apply %52(%37, %106, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %58 = apply %52(%37, %106, %53) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %10 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%4 : $Builtin.Int32, %10 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) @@ -937,12 +938,12 @@ bb1: bb2(%10 : $Builtin.Int32): %11 = struct $Int32 (%10 : $Builtin.Int32) - %12 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %12 = function_ref @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %13 = load %1 : $*ArrayInt %14 = struct_extract %13 : $ArrayInt, #ArrayInt.buffer %15 = struct_extract %14 : $ArrayIntBuffer, #ArrayIntBuffer.storage retain_value %15 : $Builtin.NativeObject - %17 = apply %12(%11, %3, %13) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %17 = apply %12(%11, %3, %13) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken %18 = integer_literal $Builtin.Int32, 1 %19 = integer_literal $Builtin.Int1, -1 %20 = builtin "sadd_with_overflow_Int32"(%10 : $Builtin.Int32, %18 : $Builtin.Int32, %19 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) @@ -956,7 +957,7 @@ bb3(%28 : $Builtin.Int32): %t1 = function_ref @take_array : $@convention(thin) (@inout ArrayInt) -> () %t2 = apply %t1(%1) : $@convention(thin) (@inout ArrayInt) -> () %29 = load %1 : $*ArrayInt - %30 = apply %12(%11, %3, %29) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () + %30 = apply %12(%11, %3, %29) : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken br bb4(%28 : $Builtin.Int32) bb4(%31 : $Builtin.Int32): @@ -964,17 +965,17 @@ bb4(%31 : $Builtin.Int32): return %32 : $Int32 } -sil public_external [_semantics "array.check_subscript"] @checkbounds_no_meth : $@convention(thin) (Int32, Bool, @owned ArrayInt) -> () { +sil public_external [_semantics "array.check_subscript"] @checkbounds_no_meth : $@convention(thin) (Int32, Bool, @owned ArrayInt) -> _DependenceToken { bb0(%0: $Int32, %1: $Bool, %2: $ArrayInt): unreachable } -sil public_external [_semantics "array.props.isNative"] @arrayPropertyIsNative : $@convention(method) (@owned ArrayInt) -> Bool { +sil public_external [_semantics "array.props.isNativeTypeChecked"] @arrayPropertyIsNative : $@convention(method) (@owned ArrayInt) -> Bool { bb0(%0: $ArrayInt): unreachable } -sil public_external [_semantics "array.check_subscript"] @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> () { +sil public_external [_semantics "array.check_subscript"] @checkbounds : $@convention(method) (Int32, Bool, @owned ArrayInt) -> _DependenceToken { bb0(%0: $Int32, %1: $Bool, %2: $ArrayInt): unreachable } @@ -1012,8 +1013,8 @@ bb0(%0 : $*ArrayInt): sil @getArray : $@convention(thin) () -> ArrayInt sil [_semantics "array.get_count"] @getCount2 : $@convention(method) (@owned Array) -> Int32 -sil [_semantics "array.check_subscript"] @checkbounds2 : $@convention(method) (Int32, Bool, @owned Array) -> () +sil [_semantics "array.check_subscript"] @checkbounds2 : $@convention(method) (Int32, Bool, @owned Array) -> _DependenceToken sil [_semantics "array.get_count"] @getCount3 : $@convention(method) (@owned ArraySlice) -> Int32 -sil [_semantics "array.check_subscript"] @checkbounds3 : $@convention(method) (Int32, Bool, @owned ArraySlice) -> () +sil [_semantics "array.check_subscript"] @checkbounds3 : $@convention(method) (Int32, Bool, @owned ArraySlice) -> _DependenceToken diff --git a/test/SILAnalysis/alias-crash.sil b/test/SILOptimizer/alias-crash.sil similarity index 75% rename from test/SILAnalysis/alias-crash.sil rename to test/SILOptimizer/alias-crash.sil index 0598e71aa0603..9f2e1ba7fa1cb 100644 --- a/test/SILAnalysis/alias-crash.sil +++ b/test/SILOptimizer/alias-crash.sil @@ -23,18 +23,18 @@ enum MyEnum { sil @testit : $@convention(method) (MyEnum) -> Builtin.FPIEEE64 { bb0(%0 : $MyEnum): %x1 = alloc_stack $MyEnum - store %0 to %x1#1 : $*MyEnum - %x7 = unchecked_take_enum_data_addr %x1#1 : $*MyEnum, #MyEnum.Some!enumelt.1 + store %0 to %x1 : $*MyEnum + %x7 = unchecked_take_enum_data_addr %x1 : $*MyEnum, #MyEnum.Some!enumelt.1 %x8 = struct_element_addr %x7 : $*MyStruct, #MyStruct.value %x11 = alloc_stack $MyEnum - store %0 to %x11#1 : $*MyEnum - %x19 = unchecked_take_enum_data_addr %x11#1 : $*MyEnum, #MyEnum.Some!enumelt.1 + store %0 to %x11 : $*MyEnum + %x19 = unchecked_take_enum_data_addr %x11 : $*MyEnum, #MyEnum.Some!enumelt.1 %x20 = struct_element_addr %x19 : $*MyStruct, #MyStruct.value %x24 = load %x20 : $*Builtin.FPIEEE64 %x27 = load %x8 : $*Builtin.FPIEEE64 %x28 = builtin "fsub_FPIEEE64"(%x27 : $Builtin.FPIEEE64, %x24 : $Builtin.FPIEEE64) : $Builtin.FPIEEE64 - dealloc_stack %x11#0 : $*@local_storage MyEnum - dealloc_stack %x1#0 : $*@local_storage MyEnum + dealloc_stack %x11 : $*MyEnum + dealloc_stack %x1 : $*MyEnum return %x28 : $Builtin.FPIEEE64 } diff --git a/test/SILPasses/allocbox_to_stack.sil b/test/SILOptimizer/allocbox_to_stack.sil similarity index 81% rename from test/SILPasses/allocbox_to_stack.sil rename to test/SILOptimizer/allocbox_to_stack.sil index 6eb875577a2c3..8c555cf496287 100644 --- a/test/SILPasses/allocbox_to_stack.sil +++ b/test/SILOptimizer/allocbox_to_stack.sil @@ -31,7 +31,7 @@ bb0: // CHECK-NOT: alloc_box // CHECK-NOT: strong_release // CHECK-NOT: destroy_addr -// CHECK: dealloc_stack %0#0 : $*@local_storage Int +// CHECK: dealloc_stack %0 : $*Int // CHECK: return } @@ -51,7 +51,7 @@ bb1: // CHECK: %0 = alloc_stack // CHECK: bb1: -// CHECK: dealloc_stack %0#0 : $*@local_storage Int +// CHECK: dealloc_stack %0 : $*Int // CHECK: return } @@ -158,8 +158,8 @@ bb0(%0 : $*LogicValue, %1 : $@thin Bool.Type): %7 = witness_method $@opened("01234567-89ab-cdef-0123-000000000000") LogicValue, #LogicValue.getLogicValue!1, %6 : $*@opened("01234567-89ab-cdef-0123-000000000000") LogicValue : $@convention(witness_method) @callee_owned (@inout T) -> Bool %8 = apply %7<@opened("01234567-89ab-cdef-0123-000000000000") LogicValue>(%6) : $@convention(witness_method) @callee_owned (@inout T) -> Bool strong_release %2#0 : $@box LogicValue -// CHECK: destroy_addr %2#1 : $*LogicValue -// CHECK-NEXT: dealloc_stack %2#0 : $*@local_storage LogicValue +// CHECK: destroy_addr %2 : $*LogicValue +// CHECK-NEXT: dealloc_stack %2 : $*LogicValue // CHECK-NEXT: return return %8 : $Bool } @@ -300,7 +300,7 @@ bb1: // CHECK: bb2 bb2: %17 = tuple () - // CHECK: dealloc_stack [[STACK]]#0 + // CHECK: dealloc_stack [[STACK]] // CHECK-NEXT: return return %17 : $() @@ -314,7 +314,7 @@ bb3: // struct.apply (f : () -> Swift.Int) -> Swift.Int sil @_TF6struct5applyFT1fFT_Si_Si : $@convention(thin) (@owned @callee_owned () -> Int) -> Int { bb0(%0 : $@callee_owned () -> Int): - debug_value %0 : $@callee_owned () -> Int // let f // id: %1 + debug_value %0 : $@callee_owned () -> Int, let, name "f" // id: %1 strong_retain %0 : $@callee_owned () -> Int // id: %2 %3 = apply %0() : $@callee_owned () -> Int // user: %5 strong_release %0 : $@callee_owned () -> Int // id: %4 @@ -325,7 +325,7 @@ bb0(%0 : $@callee_owned () -> Int): // struct.escape (f : () -> Swift.Int) -> () -> Swift.Int sil @_TF6struct6escapeFT1fFT_Si_FT_Si : $@convention(thin) (@owned @callee_owned () -> Int) -> @owned @callee_owned () -> Int { bb0(%0 : $@callee_owned () -> Int): - debug_value %0 : $@callee_owned () -> Int // let f // id: %1 + debug_value %0 : $@callee_owned () -> Int, let, name "f" // id: %1 return %0 : $@callee_owned () -> Int // id: %2 } @@ -333,35 +333,36 @@ bb0(%0 : $@callee_owned () -> Int): // struct.useStack (t : Swift.Int) -> () sil @_TF6struct8useStackFT1tSi_T_ : $@convention(thin) (Int) -> () { bb0(%0 : $Int): - debug_value %0 : $Int // let t // id: %1 + debug_value %0 : $Int, let, name "t" // id: %1 // CHECK: alloc_stack - %2 = alloc_box $Int // var s // users: %3, %6, %7, %7, %9 + %2 = alloc_box $Int, var, name "s" // users: %3, %6, %7, %7, %9 store %0 to %2#1 : $*Int // id: %3 // function_ref struct.apply (f : () -> Swift.Int) -> Swift.Int %4 = function_ref @_TF6struct5applyFT1fFT_Si_Si : $@convention(thin) (@owned @callee_owned () -> Int) -> Int // user: %8 - // CHECK: [[FUNC:%[a-zA-Z0-9]+]] = function_ref @_TTSf0d_n___TFF6struct8useStackFT1tSi_T_U_FT_Si + // CHECK: [[FUNC:%[a-zA-Z0-9]+]] = function_ref @_TTSf0k___TFF6struct8useStackFT1tSi_T_U_FT_Si // function_ref struct.(useStack (t : Swift.Int) -> ()).(closure #1) - %5 = function_ref @_TFF6struct8useStackFT1tSi_T_U_FT_Si : $@convention(thin) (@owned @box Int, @inout Int) -> Int // user: %7 + %5 = function_ref @_TFF6struct8useStackFT1tSi_T_U_FT_Si : $@convention(thin) (@owned @box Int) -> Int // user: %7 strong_retain %2#0 : $@box Int // id: %6 // CHECK: [[PA:%[a-zA-Z0-9]+]] = partial_apply [[FUNC]] - %7 = partial_apply %5(%2#0, %2#1) : $@convention(thin) (@owned @box Int, @inout Int) -> Int // user: %8 + %7 = partial_apply %5(%2#0) : $@convention(thin) (@owned @box Int) -> Int // user: %8 %8 = apply %4(%7) : $@convention(thin) (@owned @callee_owned () -> Int) -> Int strong_release %2#0 : $@box Int // id: %9 %10 = tuple () // user: %11 return %10 : $() // id: %11 } -// CHECK-LABEL: sil shared @_TTSf0d_n___TFF6struct8useStackFT1tSi_T_U_FT_Si +// CHECK-LABEL: sil shared @_TTSf0k___TFF6struct8useStackFT1tSi_T_U_FT_Si // CHECK-LABEL: sil private @_TFF6struct8useStackFT1tSi_T_U_FT_Si // struct.(useStack (t : Swift.Int) -> ()).(closure #1) -sil private @_TFF6struct8useStackFT1tSi_T_U_FT_Si : $@convention(thin) (@owned @box Int, @inout Int) -> Int { -bb0(%0 : $@box Int, %1 : $*Int): +sil private @_TFF6struct8useStackFT1tSi_T_U_FT_Si : $@convention(thin) (@owned @box Int) -> Int { +bb0(%0 : $@box Int): + %1 = project_box %0 : $@box Int // function_ref Swift.++ @postfix (x : @inout A) -> A %2 = function_ref @_TFsoP2ppUs14_Incrementable__FT1xRQ__Q_ : $@convention(thin) <τ_0_0 where τ_0_0 : My_Incrementable> (@out τ_0_0, @inout τ_0_0) -> () // user: %4 %3 = alloc_stack $Int // users: %4, %5, %6 - %4 = apply %2(%3#1, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : My_Incrementable> (@out τ_0_0, @inout τ_0_0) -> () - %5 = load %3#1 : $*Int // user: %8 - dealloc_stack %3#0 : $*@local_storage Int // id: %6 + %4 = apply %2(%3, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : My_Incrementable> (@out τ_0_0, @inout τ_0_0) -> () + %5 = load %3 : $*Int // user: %8 + dealloc_stack %3 : $*Int // id: %6 strong_release %0 : $@box Int // id: %7 return %5 : $Int // id: %8 } @@ -373,16 +374,16 @@ sil [transparent] @_TFsoP2ppUs14_Incrementable__FT1xRQ__Q_ : $@convention(thin) // struct.useBox (t : Swift.Int) -> () sil @_TF6struct6useBoxFT1tSi_T_ : $@convention(thin) (Int) -> () { bb0(%0 : $Int): - debug_value %0 : $Int // let t // id: %1 + debug_value %0 : $Int, let, name "t" // id: %1 // CHECK: alloc_box - %2 = alloc_box $Int // var s // users: %3, %6, %7, %7, %10 + %2 = alloc_box $Int, var, name "s" // users: %3, %6, %7, %7, %10 store %0 to %2#1 : $*Int // id: %3 // function_ref struct.escape (f : () -> Swift.Int) -> () -> Swift.Int %4 = function_ref @_TF6struct6escapeFT1fFT_Si_FT_Si : $@convention(thin) (@owned @callee_owned () -> Int) -> @owned @callee_owned () -> Int // user: %8 // function_ref struct.(useBox (t : Swift.Int) -> ()).(closure #1) - %5 = function_ref @_TFF6struct6useBoxFT1tSi_T_U_FT_Si : $@convention(thin) (@owned @box Int, @inout Int) -> Int // user: %7 + %5 = function_ref @_TFF6struct6useBoxFT1tSi_T_U_FT_Si : $@convention(thin) (@owned @box Int) -> Int // user: %7 strong_retain %2#0 : $@box Int // id: %6 - %7 = partial_apply %5(%2#0, %2#1) : $@convention(thin) (@owned @box Int, @inout Int) -> Int // user: %8 + %7 = partial_apply %5(%2#0) : $@convention(thin) (@owned @box Int) -> Int // user: %8 %8 = apply %4(%7) : $@convention(thin) (@owned @callee_owned () -> Int) -> @owned @callee_owned () -> Int // user: %9 %9 = apply %8() : $@callee_owned () -> Int strong_release %2#0 : $@box Int // id: %10 @@ -392,20 +393,21 @@ bb0(%0 : $Int): // CHECK-LABEL: sil private @_TFF6struct6useBoxFT1tSi_T_U_FT_Si // struct.(useBox (t : Swift.Int) -> ()).(closure #1) -sil private @_TFF6struct6useBoxFT1tSi_T_U_FT_Si : $@convention(thin) (@owned @box Int, @inout Int) -> Int { -bb0(%0 : $@box Int, %1 : $*Int): +sil private @_TFF6struct6useBoxFT1tSi_T_U_FT_Si : $@convention(thin) (@owned @box Int) -> Int { +bb0(%0 : $@box Int): + %1 = project_box %0 : $@box Int // function_ref Swift.++ @postfix (x : @inout A) -> A %2 = function_ref @_TFsoP2ppUs14_Incrementable__FT1xRQ__Q_ : $@convention(thin) <τ_0_0 where τ_0_0 : My_Incrementable> (@out τ_0_0, @inout τ_0_0) -> () // user: %4 %3 = alloc_stack $Int // users: %4, %5, %6 - %4 = apply %2(%3#1, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : My_Incrementable> (@out τ_0_0, @inout τ_0_0) -> () - %5 = load %3#1 : $*Int // user: %8 - dealloc_stack %3#0 : $*@local_storage Int // id: %6 + %4 = apply %2(%3, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : My_Incrementable> (@out τ_0_0, @inout τ_0_0) -> () + %5 = load %3 : $*Int // user: %8 + dealloc_stack %3 : $*Int // id: %6 strong_release %0 : $@box Int // id: %7 return %5 : $Int // id: %8 } // CHECK-LABEL: sil @closure -sil @closure : $@convention(thin) (@owned @box Int, @inout Int) -> () +sil @closure : $@convention(thin) (@owned @box Int) -> () // CHECK-LABEL: sil @no_final_release sil @no_final_release : $@convention(thin) (Int) -> Bool { @@ -413,9 +415,9 @@ bb0(%0 : $Int): %1 = alloc_box $Int store %0 to %1#1 : $*Int // function_ref main.(newFoo (Swift.Int) -> Swift.Bool).(modify #1) (())() - %3 = function_ref @closure : $@convention(thin) (@owned @box Int, @inout Int) -> () + %3 = function_ref @closure : $@convention(thin) (@owned @box Int) -> () strong_retain %1#0 : $@box Int - %5 = partial_apply %3(%1#0, %1#1) : $@convention(thin) (@owned @box Int, @inout Int) -> () + %5 = partial_apply %3(%1#0) : $@convention(thin) (@owned @box Int) -> () strong_retain %5 : $@callee_owned () -> () %7 = apply %5() : $@callee_owned () -> () strong_release %5 : $@callee_owned () -> () @@ -429,9 +431,9 @@ bb0(%0 : $@callee_owned (@out U) -> ()): debug_value %0 : $@callee_owned (@out U) -> () strong_retain %0 : $@callee_owned (@out U) -> () %3 = alloc_stack $U - %4 = apply %0(%3#1) : $@callee_owned (@out U) -> () - destroy_addr %3#1 : $*U - dealloc_stack %3#0 : $*@local_storage U + %4 = apply %0(%3) : $@callee_owned (@out U) -> () + destroy_addr %3 : $*U + dealloc_stack %3 : $*U strong_release %0 : $@callee_owned (@out U) -> () %8 = tuple () // CHECK: return @@ -447,28 +449,29 @@ bb0(%0 : $*T): debug_value_addr %0 : $*T // CHECK: function_ref @mightApply %2 = function_ref @mightApply : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@owned @callee_owned (@out τ_0_0) -> ()) -> () - %3 = function_ref @closure_to_specialize : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @owned @box τ_0_0, @inout τ_0_0) -> () + %3 = function_ref @closure_to_specialize : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @owned @box τ_0_0) -> () // CHECK-NOT: alloc_box %4 = alloc_box $T - // CHECK: copy_addr %0 to [initialization] [[STACK]]#1 : $*T + // CHECK: copy_addr %0 to [initialization] [[STACK]] : $*T copy_addr %0 to [initialization] %4#1 : $*T - // CHECK: [[CLOSURE:%[0-9a-zA-Z]+]] = function_ref @_TTSf0n_d_n__closure_to_specialize - // CHECK: partial_apply [[CLOSURE]]([[STACK]]#1) - %6 = partial_apply %3(%4#0, %4#1) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @owned @box τ_0_0, @inout τ_0_0) -> () + // CHECK: [[CLOSURE:%[0-9a-zA-Z]+]] = function_ref @_TTSf0n_k__closure_to_specialize + // CHECK: partial_apply [[CLOSURE]]([[STACK]]) + %6 = partial_apply %3(%4#0) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, @owned @box τ_0_0) -> () %7 = apply %2(%6) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@owned @callee_owned (@out τ_0_0) -> ()) -> () - // CHECK: destroy_addr [[STACK]]#1 : $*T + // CHECK: destroy_addr [[STACK]] : $*T destroy_addr %0 : $*T %9 = tuple () - // CHECK: dealloc_stack [[STACK]]#0 : $*@local_storage T + // CHECK: dealloc_stack [[STACK]] : $*T // CHECK: return return %9 : $() } -// CHECK-LABEL: sil shared @_TTSf0n_d_n__closure_to_specialize : $@convention(thin) (@out T, @inout T) -> () -sil shared @closure_to_specialize : $@convention(thin) (@out T, @owned @box T, @inout T) -> () { +// CHECK-LABEL: sil shared @_TTSf0n_k__closure_to_specialize : $@convention(thin) (@out T, @inout_aliasable T) -> () +sil shared @closure_to_specialize : $@convention(thin) (@out T, @owned @box T) -> () { // CHECK: bb0 -bb0(%0 : $*T, %1 : $@box T, %2 : $*T): -// CHECK-NEXT: copy_addr +bb0(%0 : $*T, %1 : $@box T): + %2 = project_box %1 : $@box T + // CHECK-NEXT: copy_addr copy_addr %2 to [initialization] %0 : $*T // CHECK-NOT: strong_release strong_release %1 : $@box T @@ -527,10 +530,10 @@ bb0(%0 : $Int, %1 : $*S): debug_value %0 : $Int debug_value_addr %1 : $*S %4 = function_ref @outer : $@convention(thin) (@owned @callee_owned () -> Bool) -> Bool - %5 = function_ref @closure1 : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>, @inout S<τ_0_0>) -> Bool + %5 = function_ref @closure1 : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>) -> Bool %6 = alloc_box $S copy_addr %1 to [initialization] %6#1 : $*S - %8 = partial_apply %5(%0, %6#0, %6#1) : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>, @inout S<τ_0_0>) -> Bool + %8 = partial_apply %5(%0, %6#0) : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>) -> Bool %9 = apply %4(%8) : $@convention(thin) (@owned @callee_owned () -> Bool) -> Bool destroy_addr %1 : $*S // CHECK: return @@ -544,10 +547,10 @@ bb0(%0 : $Int, %1 : $*S): debug_value %0 : $Int debug_value_addr %1 : $*S %4 = function_ref @outer : $@convention(thin) (@owned @callee_owned () -> Bool) -> Bool - %5 = function_ref @closure1 : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>, @inout S<τ_0_0>) -> Bool + %5 = function_ref @closure1 : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>) -> Bool %6 = alloc_box $S copy_addr %1 to [initialization] %6#1 : $*S - %8 = partial_apply %5(%0, %6#0, %6#1) : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>, @inout S<τ_0_0>) -> Bool + %8 = partial_apply %5(%0, %6#0) : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>) -> Bool %9 = apply %4(%8) : $@convention(thin) (@owned @callee_owned () -> Bool) -> Bool destroy_addr %1 : $*S // CHECK: return @@ -555,36 +558,38 @@ bb0(%0 : $Int, %1 : $*S): } // CHECK-LABEL: sil shared @closure1 -sil shared @closure1 : $@convention(thin) (Int, @owned @box S, @inout S) -> Bool { +sil shared @closure1 : $@convention(thin) (Int, @owned @box S) -> Bool { // CHECK: bb0 -bb0(%0 : $Int, %1 : $@box S, %2 : $*S): +bb0(%0 : $Int, %1 : $@box S): + %2 = project_box %1 : $@box S %3 = function_ref @inner : $@convention(thin) (@owned @callee_owned () -> Bool) -> Bool - %4 = function_ref @closure2 : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>, @inout S<τ_0_0>) -> Bool + %4 = function_ref @closure2 : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>) -> Bool %5 = alloc_box $S copy_addr %2 to [initialization] %5#1 : $*S - %7 = partial_apply %4(%0, %5#0, %5#1) : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>, @inout S<τ_0_0>) -> Bool + %7 = partial_apply %4(%0, %5#0) : $@convention(thin) <τ_0_0 where τ_0_0 : Count> (Int, @owned @box S<τ_0_0>) -> Bool %8 = apply %3(%7) : $@convention(thin) (@owned @callee_owned () -> Bool) -> Bool strong_release %1 : $@box S // CHECK: return return %8 : $Bool } -// CHECK-LABEL: sil shared @_TTSf0n_d_n__closure2 +// CHECK-LABEL: sil shared @_TTSf0n_k__closure2 // CHECK: bb0 // CHECK: return // CHECK-NOT: bb1 // CHECK-LABEL: sil shared @closure2 -sil shared @closure2 : $@convention(thin) (Int, @owned @box S, @inout S) -> Bool { +sil shared @closure2 : $@convention(thin) (Int, @owned @box S) -> Bool { // CHECK: bb0 -bb0(%0 : $Int, %1 : $@box S, %2 : $*S): +bb0(%0 : $Int, %1 : $@box S): + %2 = project_box %1 : $@box S %3 = function_ref @binary : $@convention(thin) (Int, Int) -> Bool %4 = alloc_stack $S - copy_addr %2 to [initialization] %4#1 : $*S + copy_addr %2 to [initialization] %4 : $*S %6 = function_ref @get : $@convention(method) <τ_0_0 where τ_0_0 : Count> (@in S<τ_0_0>) -> Int - %7 = apply %6(%4#1) : $@convention(method) <τ_0_0 where τ_0_0 : Count> (@in S<τ_0_0>) -> Int + %7 = apply %6(%4) : $@convention(method) <τ_0_0 where τ_0_0 : Count> (@in S<τ_0_0>) -> Int %8 = apply %3(%0, %7) : $@convention(thin) (Int, Int) -> Bool - dealloc_stack %4#0 : $*@local_storage S + dealloc_stack %4 : $*S strong_release %1 : $@box S // CHECK: return return %8 : $Bool @@ -598,13 +603,13 @@ sil @destroy_stack_value_after_closure : $@convention(thin) (@out T, @in T) // CHECK: bb0 bb0(%0 : $*T, %1 : $*T): // CHECK: [[STACK:%.*]] = alloc_stack - // CHECK: copy_addr %1 to [initialization] [[STACK]]#1 + // CHECK: copy_addr %1 to [initialization] [[STACK]] // CHECK: [[APPLIED:%.*]] = function_ref - %3 = function_ref @applied : $@convention(thin) <τ_0_0> (@owned @box τ_0_0, @inout τ_0_0) -> () + %3 = function_ref @applied : $@convention(thin) <τ_0_0> (@owned @box τ_0_0) -> () %4 = alloc_box $T copy_addr %1 to [initialization] %4#1 : $*T - // CHECK: [[PARTIAL:%.*]] = partial_apply [[APPLIED]]([[STACK]]#1) - %6 = partial_apply %3(%4#0, %4#1) : $@convention(thin) <τ_0_0> (@owned @box τ_0_0, @inout τ_0_0) -> () + // CHECK: [[PARTIAL:%.*]] = partial_apply [[APPLIED]]([[STACK]]) + %6 = partial_apply %3(%4#0) : $@convention(thin) <τ_0_0> (@owned @box τ_0_0) -> () // CHECK: debug_value [[PARTIAL]] debug_value %6 : $@callee_owned () -> () // CHECK: strong_retain [[PARTIAL]] @@ -614,20 +619,21 @@ bb0(%0 : $*T, %1 : $*T): copy_addr %1 to [initialization] %0 : $*T // CHECK: strong_release [[PARTIAL]] strong_release %6 : $@callee_owned () -> () - // CHECK: destroy_addr [[STACK]]#1 + // CHECK: destroy_addr [[STACK]] // CHECK: destroy_addr %1 destroy_addr %1 : $*T %13 = tuple () return %13 : $() } -sil @applied : $@convention(thin) (@owned @box T, @inout T) -> () { -bb0(%0 : $@box T, %1 : $*T): +sil @applied : $@convention(thin) (@owned @box T) -> () { +bb0(%0 : $@box T): + %1 = project_box %0 : $@box T %2 = function_ref @consume : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () %3 = alloc_stack $T - copy_addr %1 to [initialization] %3#1 : $*T - %5 = apply %2(%3#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - dealloc_stack %3#0 : $*@local_storage T + copy_addr %1 to [initialization] %3 : $*T + %5 = apply %2(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %3 : $*T strong_release %0 : $@box T %8 = tuple () return %8 : $() diff --git a/test/SILPasses/allocbox_to_stack_with_false.swift b/test/SILOptimizer/allocbox_to_stack_with_false.swift similarity index 82% rename from test/SILPasses/allocbox_to_stack_with_false.swift rename to test/SILOptimizer/allocbox_to_stack_with_false.swift index 4d1cf7f79d328..6e2082964b1ba 100644 --- a/test/SILPasses/allocbox_to_stack_with_false.swift +++ b/test/SILOptimizer/allocbox_to_stack_with_false.swift @@ -16,11 +16,11 @@ func g() { infix operator ~> { precedence 255 } protocol Target {} -func ~> (inout x: Target, f: (inout _: Target, _: Arg0)->Result) -> (Arg0)->Result { +func ~> (inout x: Target, f: (inout _: Target, _: Arg0) -> Result) -> (Arg0) -> Result { return { f(&x, $0) } } -func ~> (inout x: Int, f: (inout _: Int, _: Target)->Target) -> (Target)->Target { +func ~> (inout x: Int, f: (inout _: Int, _: Target) -> Target) -> (Target) -> Target { return { f(&x, $0) } } diff --git a/test/SILPasses/always_inline.sil b/test/SILOptimizer/always_inline.sil similarity index 76% rename from test/SILPasses/always_inline.sil rename to test/SILOptimizer/always_inline.sil index 0bfd86215d004..20dfa4c6a3340 100644 --- a/test/SILPasses/always_inline.sil +++ b/test/SILOptimizer/always_inline.sil @@ -7,16 +7,16 @@ import Builtin // CHECK-LABEL: @caller_of_noinline sil @caller_of_noinline : $@convention(thin) () -> () { bb0: - // CHECK-NOT: function_ref @noinlin_callee + // CHECK-NOT: function_ref @noinline_callee // CHECK-NOT: apply - %0 = function_ref @noinlin_callee : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 + %0 = function_ref @noinline_callee : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 %2 = integer_literal $Builtin.Int64, 0 %3 = apply %0(%2) : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 %4 = tuple () return %4 : $() } -// CHECK-LABEL: [always_inline] @noinlin_callee -sil [always_inline] @noinlin_callee : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 { +// CHECK-LABEL: [always_inline] @noinline_callee +sil [always_inline] @noinline_callee : $@convention(thin) (Builtin.Int64) -> Builtin.Int64 { bb0(%0 : $Builtin.Int64): %2 = integer_literal $Builtin.Int1, 0 %3 = builtin "umul_with_overflow_Int64"(%0 : $Builtin.Int64, %0 : $Builtin.Int64, %2 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) diff --git a/test/SILOptimizer/arcsequenceopts.sil b/test/SILOptimizer/arcsequenceopts.sil new file mode 100644 index 0000000000000..020706b42ea96 --- /dev/null +++ b/test/SILOptimizer/arcsequenceopts.sil @@ -0,0 +1,2065 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all -arc-loop-opts %s | FileCheck %s + +sil_stage canonical + +import Builtin + +// Utilities + +sil @user : $@convention(thin) (@box Builtin.Int32) -> () + +sil @owned_user : $@convention(thin) (@owned @box Builtin.Int32) -> () + +struct S { + var x : Builtin.NativeObject +} +sil @S_user : $@convention(thin) (S) -> () + +struct S2 { + var x : Builtin.Int32 + var y : Builtin.NativeObject + var z : Builtin.Int32 +} + +struct S3 { + var x : Builtin.Int32 + var y : Builtin.NativeObject + var y1 : Builtin.NativeObject + var z : Builtin.Int32 +} + +class Cls { + var random : Builtin.Int32 + + init() +} + +public enum FakeOptional { + case None + case Some(T) +} + +class C { + init() + var w : FakeOptional +} + +class Container { + @sil_stored var c : Cls + init() +} + + +class RetainUser { } + +sil @rawpointer_use: $@convention(thin) (Builtin.RawPointer) -> () + +enum Either { + case Left(LTy) + case Right(RTy) +} + +struct StaticString { + /// Either a pointer to the start of UTF-8 data, or an integer representation + /// of a single Unicode scalar. + var _startPtrOrData: Builtin.RawPointer + + /// If `_startPtrOrData` is a pointer, contains the length of the UTF-8 data + /// in bytes. + var _byteSize: Builtin.Word + + /// Extra flags: + /// + /// - bit 0: set to 0 if `_startPtrOrData` is a pointer, or to 1 if it is a + /// Unicode scalar. + /// + /// - bit 1: set to 1 if `_startPtrOrData` is a pointer and string data is + /// ASCII. + var _flags: Builtin.Int8 +} + +public protocol ErrorType { + var _domain: Builtin.Int32 { get } + var _code: Builtin.Int32 { get } +} + +sil [fragile] @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + +sil [fragile] @owned_return : $@convention(thin) () -> (@owned @box Builtin.Int32) + +sil [fragile] @guaranteed_throwing_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error ErrorType + +///////////////// +// Basic Tests // +///////////////// + +// CHECK-LABEL: sil @simple_retain_release_pair : $@convention(thin) (Builtin.NativeObject) -> () +// CHECK: bb0 +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @simple_retain_release_pair : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + strong_release %0 : $Builtin.NativeObject + %1 = tuple () + return %1 : $() +} + +// CHECK-LABEL: sil @simple_copyvalue_destroyvalue_pair : $@convention(thin) (S) -> S +// CHECK: bb0({{%[0-9]+}} : $S) +// CHECK-NEXT: return +sil @simple_copyvalue_destroyvalue_pair : $@convention(thin) (S) -> S { +bb0(%0 : $S): + retain_value %0 : $S + release_value %0 : $S + retain_value %0 : $S + release_value %0 : $S + retain_value %0 : $S + release_value %0 : $S + return %0 : $S +} + +// CHECK-LABEL: sil @delete_retain_over_non_side_effect_instructions : $@convention(thin) (Builtin.NativeObject, Builtin.Int64) -> Builtin.Int1 +// CHECK: bb0 +// CHECK-NEXT: builtin +// CHECK-NEXT: return +sil @delete_retain_over_non_side_effect_instructions : $@convention(thin) (Builtin.NativeObject, Builtin.Int64) -> (Builtin.Int1) { +bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Int64): + strong_retain %0 : $Builtin.NativeObject + %3 = builtin "cmp_eq_Int64"(%1 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 + strong_release %0 : $Builtin.NativeObject + return %3 : $Builtin.Int1 +} + +// CHECK-LABEL: sil @delete_copyvalue_over_non_side_effect_instructions : $@convention(thin) (S, Builtin.Int64) -> Builtin.Int1 +// CHECK: bb0 +// CHECK-NEXT: builtin +// CHECK-NEXT: return +sil @delete_copyvalue_over_non_side_effect_instructions : $@convention(thin) (S, Builtin.Int64) -> (Builtin.Int1) { +bb0(%0 : $S, %1 : $Builtin.Int64): + retain_value %0 : $S + %3 = builtin "cmp_eq_Int64"(%1 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 + release_value %0 : $S + return %3 : $Builtin.Int1 +} + +// CHECK-LABEL: sil @delete_retain_over_single_potential_decrement : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () +// CHECK: bb0 +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @delete_retain_over_single_potential_decrement : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + strong_release %1 : $Builtin.NativeObject + strong_release %0 : $Builtin.NativeObject + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @delete_copyvalue_over_single_potential_decrement : $@convention(thin) (S, Builtin.NativeObject) -> () +// CHECK: bb0 +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @delete_copyvalue_over_single_potential_decrement : $@convention(thin) (S, Builtin.NativeObject) -> () { +bb0(%0 : $S, %1 : $Builtin.NativeObject): + retain_value %0 : $S + strong_release %1 : $Builtin.NativeObject + release_value %0 : $S + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @dont_delete_retain_over_decrement_use : $@convention(thin) (@box Builtin.Int32) -> () +// CHECK: bb0 +// CHECK: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @dont_delete_retain_over_decrement_use : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @dont_delete_copyvalue_over_decrement_use : $@convention(thin) (S) -> () +// CHECK: bb0 +// CHECK: retain_value +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: release_value +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @dont_delete_copyvalue_over_decrement_use : $@convention(thin) (S) -> () { +bb0(%0 : $S): + %1 = function_ref @S_user : $@convention(thin) (S) -> () + retain_value %0 : $S + apply %1 (%0) : $@convention(thin) (S) -> () + apply %1 (%0) : $@convention(thin) (S) -> () + release_value %0 : $S + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @move_delete_retain_over_decrement_use_when_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () +// CHECK: bb0 +// CHECK: integer_literal +// CHECK-NEXT: integer_literal +// CHECK-NEXT: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @move_delete_retain_over_decrement_use_when_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + %2 = integer_literal $Builtin.Int32, 1 + %3 = integer_literal $Builtin.Int32, 2 + strong_retain %0 : $@box Builtin.Int32 + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + strong_release %0 : $@box Builtin.Int32 + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @delete_copyvalue_over_decrement_use_when_knownsafe : $@convention(thin) (S) -> () +// CHECK: bb0 +// CHECK: integer_literal +// CHECK-NEXT: integer_literal +// CHECK-NEXT: retain_value +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: release_value +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @delete_copyvalue_over_decrement_use_when_knownsafe : $@convention(thin) (S) -> () { +bb0(%0 : $S): + %1 = function_ref @S_user : $@convention(thin) (S) -> () + retain_value %0 : $S + %2 = integer_literal $Builtin.Int32, 1 + %3 = integer_literal $Builtin.Int32, 2 + retain_value %0 : $S + apply %1 (%0) : $@convention(thin) (S) -> () + apply %1 (%0) : $@convention(thin) (S) -> () + release_value %0 : $S + release_value %0 : $S + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @literals_do_not_use_values_with_reference_semantics : $@convention(thin) (@box Builtin.Int32) -> () +// CHECK: bb0 +// CHECK-NEXT: function_ref +// CHECK-NEXT: function_ref +// CHECK-NEXT: apply +// CHECK-NEXT: function_ref +// CHECK-NEXT: function_ref +// CHECK-NEXT: integer_literal +// CHECK-NEXT: string_literal +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @literals_do_not_use_values_with_reference_semantics : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + strong_retain %0 : $@box Builtin.Int32 + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + %4 = integer_literal $Builtin.Int64, 0 + %5 = string_literal utf8 "123" + strong_release %0 : $@box Builtin.Int32 + %6 = tuple() + return %6 : $() +} + +// CHECK-LABEL: sil @owned_arguments_are_known_safe_in_the_first_bb +// CHECK: bb0 +// CHECK-NEXT: function_ref +// CHECK-NEXT: function_ref +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +// CHECK-NEXT: br +// CHECK: bb1: +// CHECK-NEXT: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @owned_arguments_are_known_safe_in_the_first_bb : $@convention(thin) (@owned @box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + strong_release %0 : $@box Builtin.Int32 + br bb1 + +bb1: + strong_retain %0 : $@box Builtin.Int32 + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// FIXME: Should be able to eliminate the r/r pair here. + +// CHECK-LABEL: @simple_alias_store_use_test : $@convention(thin) (@box Builtin.Int32) -> () { +// SHOULD-NOT: strong_retain +// SHOULD-NOT: strong_release +sil @simple_alias_store_use_test : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = project_box %0 : $@box Builtin.Int32 + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + %3 = integer_literal $Builtin.Int32, 2 + strong_retain %0 : $@box Builtin.Int32 + apply %2 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + store %3 to %1 : $*Builtin.Int32 + strong_release %0 : $@box Builtin.Int32 + %4 = tuple() + return %4: $() +} + +// We can't remove the retain-release pair because the apply may be +// decrementing the refcount on our object. +// CHECK-LABEL: @simple_alias_load_use_test : $@convention(thin) (@inout Builtin.Int32) -> () { +// CHECK: bb0 +// CHECK-NEXT: alloc_box +// CHECK-NEXT: function_ref +// CHECK-NEXT: function_ref +// CHECK-NEXT: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: load +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @simple_alias_load_use_test : $@convention(thin) (@inout Builtin.Int32) -> () { +bb0(%0 : $*Builtin.Int32): + %1 = alloc_box $Builtin.Int32 + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %1#0 : $@box Builtin.Int32 + apply %2 (%1#0) : $@convention(thin) (@box Builtin.Int32) -> () + %3 = load %1#1 : $*Builtin.Int32 + strong_release %1#0 : $@box Builtin.Int32 + %4 = tuple() + return %4: $() +} + +// We *CAN* remove the pair if we have an iterated strong_release though. +// +// CHECK-LABEL: @simple_alias_load_use_test_two_release : $@convention(thin) (@inout Builtin.Int32) -> () { +// CHECK: bb0 +// CHECK-NEXT: alloc_box +// CHECK-NEXT: function_ref +// CHECK-NEXT: function_ref +// CHECK-NEXT: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: load +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @simple_alias_load_use_test_two_release : $@convention(thin) (@inout Builtin.Int32) -> () { +bb0(%0 : $*Builtin.Int32): + %1 = alloc_box $Builtin.Int32 + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %1#0 : $@box Builtin.Int32 + strong_retain %1#0 : $@box Builtin.Int32 + apply %2 (%1#0) : $@convention(thin) (@box Builtin.Int32) -> () + %3 = load %1#1 : $*Builtin.Int32 + strong_release %1#0 : $@box Builtin.Int32 + strong_release %1#0 : $@box Builtin.Int32 + %4 = tuple() + return %4: $() +} + +// CHECK-LABEL: sil @silargument_retain_iterated : $@convention(thin) (@owned @box Builtin.Int32) -> () +// CHECK: bb0 +// CHECK-NEXT: function_ref user +// CHECK-NEXT: function_ref @user +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +// CHECK-NEXT: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +sil @silargument_retain_iterated : $@convention(thin) (@owned @box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + strong_release %0 : $@box Builtin.Int32 + strong_retain %0 : $@box Builtin.Int32 + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @value_that_does_not_alias_pointer_args_cannot_be_decremented : $@convention(thin) (Cls) -> () +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @value_that_does_not_alias_pointer_args_cannot_be_decremented : $@convention(thin) (Cls) -> () { +bb0(%0 : $Cls): + %1 = alloc_ref $Cls + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + %3 = unchecked_ref_cast %0 : $Cls to $@box Builtin.Int32 + strong_retain %1 : $Cls + apply %2(%3) : $@convention(thin) (@box Builtin.Int32) -> () + apply %2(%3) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %1 : $Cls + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @escaping_pointer_can_have_refcount_decremented_indirectly : $@convention(thin) (@box Builtin.Int32) -> () +// CHECK: strong_retain +// CHECK: strong_release + +sil @the_kraken : $@convention(thin) () -> () +sil @escaping_pointer_can_have_refcount_decremented_indirectly : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @the_kraken : $@convention(thin) () -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1() : $@convention(thin) () -> () + apply %1() : $@convention(thin) () -> () + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// Make sure that we clear state and don't do anything in the fact of +// autorelease push/pop. +sil @objc_autoreleasePoolPush : $@convention(thin) () -> Builtin.RawPointer +sil @objc_autoreleasePoolPop : $@convention(thin) (Builtin.RawPointer) -> () + +// CHECK-LABEL: sil @clear_state_in_fact_of_autorelease_pool_ops : $@convention(thin) (Builtin.RawPointer) -> () { +// CHECK: bb0 +// CHECK-NEXT: function_ref objc_autoreleasePoolPush +// CHECK-NEXT: function_ref @objc_autoreleasePoolPush +// CHECK-NEXT: function_ref objc_autoreleasePoolPop +// CHECK-NEXT: function_ref @objc_autoreleasePoolPop +// CHECK-NEXT: alloc_box +// CHECK-NEXT: retain +// CHECK-NEXT: apply +// CHECK-NEXT: release +// CHECK-NEXT: retain +// CHECK-NEXT: apply +// CHECK-NEXT: release +// CHECK-NEXT: release +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @clear_state_in_fact_of_autorelease_pool_ops : $@convention(thin) (Builtin.RawPointer) -> () { +bb0(%0 : $Builtin.RawPointer): + %1 = function_ref @objc_autoreleasePoolPush : $@convention(thin) () -> Builtin.RawPointer + %2 = function_ref @objc_autoreleasePoolPop : $@convention(thin) (Builtin.RawPointer) -> () + %3 = alloc_box $Builtin.Int32 + strong_retain %3#0 : $@box Builtin.Int32 + apply %1() : $@convention(thin) () -> Builtin.RawPointer + strong_release %3#0 : $@box Builtin.Int32 + strong_retain %3#0 : $@box Builtin.Int32 + apply %2(%0) : $@convention(thin) (Builtin.RawPointer) -> () + strong_release %3#0 : $@box Builtin.Int32 + strong_release %3#0 : $@box Builtin.Int32 + %4 = tuple() + return %4 : $() +} + + +// CHECK-LABEL: sil @release_can_decrement_other_releases : $@convention(thin) () -> () { +// CHECK: strong_retain +// CHECK: strong_release +// CHECK: strong_release +sil @release_can_decrement_other_releases : $@convention(thin) () -> () { +bb0: + %1 = alloc_box $Builtin.Int32 + %2 = alloc_stack $@box Builtin.Int32 + store %1#0 to %2 : $*@box Builtin.Int32 + %4 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %1#0 : $@box Builtin.Int32 + %6 = load %2 : $*@box Builtin.Int32 + %7 = apply %4(%6) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %6 : $@box Builtin.Int32 + strong_release %1#0 : $@box Builtin.Int32 + dealloc_stack %2 : $*@box Builtin.Int32 + %11 = tuple () + return %11 : $() +} + +// CHECK-LABEL: sil @retain_can_be_used_by_other_pointer : $@convention(thin) (RetainUser, @box Builtin.Int32) -> @box Builtin.Int32 { +// CHECK: strong_retain +// CHECK: strong_retain +// CHECK: strong_release +sil @retain_can_be_used_by_other_pointer : $@convention(thin) (RetainUser, @box Builtin.Int32) -> @box Builtin.Int32 { +bb0(%0 : $RetainUser, %1 : $@box Builtin.Int32): + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $RetainUser + apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %1 : $@box Builtin.Int32 + strong_release %0 : $RetainUser + return %1 : $@box Builtin.Int32 +} + +// CHECK-LABEL: sil @remove_retain_release_over_no_release_func +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @remove_retain_release_over_no_release_func : $@convention(thin) (Cls) -> () { +bb0(%0 : $Cls): + %1 = function_ref @no_release_func : $@convention(thin) (Cls) -> () + strong_retain %0 : $Cls + apply %1 (%0) : $@convention(thin) (Cls) -> () + apply %1 (%0) : $@convention(thin) (Cls) -> () + strong_release %0 : $Cls + %r = tuple() + return %r : $() +} + +// CHECK-LABEL: sil @dont_remove_as_arg0_may_be_indirectly_released_by_callee +// CHECK: strong_retain +// CHECK: strong_release +sil @dont_remove_as_arg0_may_be_indirectly_released_by_callee : $@convention(thin) (Cls, Cls) -> () { +bb0(%0 : $Cls, %1 : $Cls): + %2 = function_ref @release_arg1 : $@convention(thin) (Cls, Cls) -> () + retain_value %0 : $Cls + apply %2 (%0, %1) : $@convention(thin) (Cls, Cls) -> () + apply %2 (%0, %1) : $@convention(thin) (Cls, Cls) -> () + release_value %0 : $Cls + %r = tuple() + return %r : $() +} + +// CHECK-LABEL: sil @remove_as_local_object_does_not_escape_to_callee +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @remove_as_local_object_does_not_escape_to_callee : $@convention(thin) (Cls) -> () { +bb0(%0 : $Cls): + %1 = alloc_ref $Cls + retain_value %1 : $Cls + %f1 = function_ref @release_arg1 : $@convention(thin) (Cls, Cls) -> () + apply %f1 (%0, %0) : $@convention(thin) (Cls, Cls) -> () + apply %f1 (%0, %0) : $@convention(thin) (Cls, Cls) -> () + release_value %1 : $Cls + %f2 = function_ref @no_release_func : $@convention(thin) (Cls) -> () + apply %f2 (%1) : $@convention(thin) (Cls) -> () + %r = tuple() + return %r : $() +} + +// CHECK-LABEL: sil @dont_remove_as_local_object_indirectly_escapes_to_callee +// CHECK: strong_retain +// CHECK: strong_release +sil @dont_remove_as_local_object_indirectly_escapes_to_callee : $@convention(thin) (Cls) -> () { +bb0(%0 : $Cls): + %1 = alloc_ref $Cls + %2 = alloc_ref $Container + %3 = ref_element_addr %2 : $Container, #Container.c + store %1 to %3 : $*Cls + retain_value %1 : $Cls + %f1 = function_ref @release_container : $@convention(thin) (Container) -> () + apply %f1 (%2) : $@convention(thin) (Container) -> () + apply %f1 (%2) : $@convention(thin) (Container) -> () + release_value %1 : $Cls + %r = tuple() + return %r : $() +} + +sil @release_arg1 : $@convention(thin) (Cls, Cls) -> () { +bb0(%0 : $Cls, %1 : $Cls): + strong_release %1 : $Cls + %r = tuple() + return %r : $() +} + +sil @release_container : $@convention(thin) (Container) -> () { +bb0(%0 : $Container): + strong_release %0 : $Container + %r = tuple() + return %r : $() +} + +sil @no_release_func : $@convention(thin) (Cls) -> () { +bb0(%0 : $Cls): + %r = tuple() + return %r : $() +} + +//////////////////// +// Multi-BB tests // +//////////////////// + +////////////// +// Hammocks // +////////////// + +// CHECK-LABEL: sil @hammock1 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @hammock1 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + br bb2 + +bb2: + strong_release %0 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// This hammock cannot be optimized. +// CHECK-LABEL: sil @hammock2 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK: bb1: +// CHECK-NEXT: strong_retain +// CHECK: bb2: +// CHECK-NEXT: strong_release +sil @hammock2 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $Builtin.NativeObject + br bb2 + +bb2: + strong_release %0 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +/// This hammock can't be optimized. +// CHECK-LABEL: sil @hammock3 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK: bb1: +// CHECK-NEXT: strong_release +// CHECK: bb2: +// CHECK-NEXT: strong_release +sil @hammock3 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + br bb2 + +bb2: + strong_release %0 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// This should not be optimizable. +// CHECK-LABEL: sil @hammock4 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +// CHECK: bb1: +// CHECK-NEXT: strong_retain +// CHECK: bb2: +// CHECK-NEXT: strong_release +sil @hammock4 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $Builtin.NativeObject + br bb2 + +bb2: + strong_release %0 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @hammock5 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NOT: strong_release +// CHECK-NOT: strong_retain +// CHECK: bb1: +// CHECK-NEXT: strong_release +// CHECK: bb2: +// CHECK-NEXT: strong_release +sil @hammock5 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + br bb2 + +bb2: + strong_release %0 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @hammock6 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +// CHECK: bb1: +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +// CHECK: bb2: +// CHECK-NEXT: strong_release +sil @hammock6 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + cond_br undef, bb1, bb2 + +bb1: + br bb2 + +bb2: + strong_release %0 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @hammock7 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK: bb1: +// CHECK-NEXT: strong_retain +// CHECK: bb2: +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @hammock7 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $Builtin.NativeObject + br bb2 + +bb2: + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @hammock8 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK-NOT: strong_release +// CHECK: bb1: +// CHECK-NEXT: strong_release +// CHECK-NOT: strong_retain +// CHECK: bb2: +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @hammock8 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + br bb2 + +bb2: + %9999 = tuple() + return %9999 : $() +} + +//////////////////// +// Double Hammock // +//////////////////// + +// Make sure we do not do anything in the presence of double partial +// applies. This is due to issues related to the two branches of the two +// diamonds not being control dependent. +// CHECK-LABEL: sil @double_hammock1 : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK: bb0 +// CHECK-NEXT: function_ref user +// CHECK-NEXT: function_ref @user +// CHECK-NEXT: strong_retain +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: apply +// CHECK-NEXT: bb2 +// CHECK: bb2: +// CHECK-NEXT: cond_br +// CHECK: bb3: +// CHECK-NEXT: apply +// CHECK-NEXT: br +// CHECK: bb4: +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @double_hammock1 : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + cond_br undef, bb1, bb2 + +bb1: + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + br bb2 + +bb2: + cond_br undef, bb3, bb4 + +bb3: + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + br bb4 + +bb4: + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +////////////// +// Diamonds // +////////////// + +// CHECK-LABEL: sil @diamond1 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @diamond1 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond2 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: strong_release +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond2 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + br bb3 + +bb2: + strong_release %0 : $Builtin.NativeObject + br bb3 + +bb3: + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond3 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: strong_release +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond3 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + br bb3 + +bb2: + br bb3 + +bb3: + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond4 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @diamond4 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + br bb3 + +bb2: + strong_release %0 : $Builtin.NativeObject + br bb3 + +bb3: + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond5 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: strong_release +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond5 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond6 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: strong_release +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond6 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + br bb3 + +bb2: + strong_release %0 : $Builtin.NativeObject + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond7 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond7 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + br bb3 + +bb2: + strong_release %0 : $Builtin.NativeObject + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond8 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: strong_retain +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond8 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $Builtin.NativeObject + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +/// CHECK-LABEL: sil @diamond9 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: strong_retain +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond9 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + cond_br undef, bb1, bb2 + +bb1: + br bb3 + +bb2: + strong_retain %0 : $Builtin.NativeObject + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond10 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @diamond10 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $Builtin.NativeObject + br bb3 + +bb2: + strong_retain %0 : $Builtin.NativeObject + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +/// CHECK-LABEL: sil @diamond11 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: strong_retain +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond11 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $Builtin.NativeObject + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @diamond12 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: bb0 +// CHECK-NEXT: strong_retain +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: br +// CHECK: bb2: +// CHECK-NEXT: strong_retain +// CHECK-NEXT: br +// CHECK: bb3: +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple () +// CHECK-NEXT: return +sil @diamond12 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + br bb3 + +bb2: + strong_retain %0 : $Builtin.NativeObject + br bb3 + +bb3: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() +} + +// CHECK: sil @unreachable_bb : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @unreachable_bb : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() + +bb2: + %3 = builtin "int_trap"() : $() + unreachable +} + +// CHECK: sil @dont_move_values_in_face_of_partial_merges : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK: strong_retain +// CHECK: strong_release +sil @dont_move_values_in_face_of_partial_merges : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + cond_br undef, bb1, bb2 + +bb1: + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @do_remove_values_in_face_of_partial_merges : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK: strong_retain +// CHECK-NOT: strong_retain +// CHECK-NEXT: cond_br +// CHECK: bb3: +// CHECK-NEXT: strong_release +// CHECK-NOT: strong_release +sil @do_remove_values_in_face_of_partial_merges : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + strong_retain %0 : $@box Builtin.Int32 + cond_br undef, bb1, bb2 + +bb1: + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %0 : $@box Builtin.Int32 + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @release_use_optimization : $@convention(thin) (@owned @box Builtin.Int32) -> () { +// CHECK-NOT: strong_retain +// CHECK: strong_release +// CHECK-NOT: strong_release +sil @release_use_optimization : $@convention(thin) (@owned @box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @increment_known_safe_merge_with_last_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK: bb1: +// CHECK-NEXT: strong_retain +// CHECK-NEXT: br bb3 +// CHECK: bb2: +// CHECK-NEXT: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: br bb3 +// CHECK: bb3: +// CHECK-NEXT: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @increment_known_safe_merge_with_last_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $@box Builtin.Int32 + strong_retain %0 : $@box Builtin.Int32 + br bb3 + +bb2: + strong_retain %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + br bb3 + +bb3: + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @decrement_known_safe_merge_with_last_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK: bb0( +// CHECK-NEXT: function_ref +// CHECK-NEXT: function_ref +// CHECK-NEXT: strong_retain +// CHECK-NEXT: apply +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +// CHECK-NEXT: cond_br +// CHECK: bb1: +// CHECK-NEXT: strong_release +// CHECK-NEXT: br bb3 +// CHECK-NOT: strong_release +sil @decrement_known_safe_merge_with_last_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $@box Builtin.Int32 + strong_release %0 : $@box Builtin.Int32 + br bb3 + +bb2: + strong_release %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + br bb3 + +bb3: + %2 = tuple() + return %2 : $() +} + +// Just make sure we don't crash on this. +// CHECK-LABEL: sil @unreachable_pred : $@convention(thin) (Builtin.NativeObject) -> () { +sil @unreachable_pred : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + br bb2 + +bb1: + br bb2 + +bb2: + %1 = tuple() + return %1 : $() +} + +// CHECK-LABEL: sil @arg_merge : $@convention(thin) (@owned S) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @arg_merge : $@convention(thin) (@owned S) -> () { +bb0(%0 : $S): + %1 = struct_extract %0 : $S, #S.x + strong_retain %1 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %1 : $Builtin.NativeObject + %2 = tuple() + return %2 : $() +} + + +/// Make sure we strip off casts when inserting new retains, releases. Otherwise +/// we run into dominance problems if the bitcast is in a branch. +// CHECK-LABEL: sil @switch_merge_with_bit_cast_in_branches : $@convention(thin) (@owned S) -> () { +// CHECK: bb1: +// CHECK-NOT: strong_retain +// CHECK: bb2: +// CHECK-NOT: strong_retain +// CHECK: bb3: +// CHECK: retain_value +// CHECK: release_value +sil @switch_merge_with_bit_cast_in_branches : $@convention(thin) (@owned S) -> () { +bb0(%0 : $S): + cond_br undef, bb1, bb2 + +bb1: + %1 = struct_extract %0 : $S, #S.x + %2 = unchecked_ref_cast %1 : $Builtin.NativeObject to $@box Builtin.Int32 + strong_retain %2 : $@box Builtin.Int32 + br bb3 + +bb2: + %3 = struct_extract %0 : $S, #S.x + %4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $@box Builtin.Int32 + strong_retain %4 : $@box Builtin.Int32 + br bb3 + +bb3: + %5 = struct_extract %0 : $S, #S.x + %6 = unchecked_ref_cast %5 : $Builtin.NativeObject to $@box Builtin.Int32 + %7 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %7(%6) : $@convention(thin) (@box Builtin.Int32) -> () + apply %7(%6) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %6 : $@box Builtin.Int32 + %11 = tuple() + return %11 : $() +} + +// CHECK-LABEL: sil @strip_off_layout_compatible_typed_geps : $@convention(thin) (S, FakeOptional) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +sil @strip_off_layout_compatible_typed_geps : $@convention(thin) (S, FakeOptional) -> () { +bb0(%0 : $S, %1 : $FakeOptional): + %2 = struct_extract %0 : $S, #S.x + strong_retain %2 : $Builtin.NativeObject + release_value %0 : $S + %3 = unchecked_enum_data %1 : $FakeOptional, #FakeOptional.Some!enumelt.1 + strong_retain %3 : $Builtin.NativeObject + release_value %1 : $FakeOptional + %5 = tuple() + return %5 : $() +} + +// CHECK-LABEL: sil @strip_off_single_pred_args : $@convention(thin) (FakeOptional) -> () { +// CHECK-NOT: retain_value +// CHECK-NOT: strong_release +sil @strip_off_single_pred_args : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1(%1 : $Builtin.NativeObject): + retain_value %0 : $FakeOptional + strong_release %1 : $Builtin.NativeObject + br bb3 + +bb2: + br bb3 + +bb3: + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @unreachable_bb_2 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @unreachable_bb_2 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + %4 = integer_literal $Builtin.Int1, -1 + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() + +bb2: + cond_fail %4 : $Builtin.Int1 + unreachable +} + +// CHECK-LABEL: sil @unreachable_bb_3 : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @unreachable_bb_3 : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb1, bb2 + +bb1: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() + +bb2: + %4 = integer_literal $Builtin.Int1, -1 + cond_fail %4 : $Builtin.Int1 + unreachable +} + +// CHECK-LABEL: sil @strip_off_multi_payload_unchecked_enum_data : $@convention(thin) (Either) -> () { +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @strip_off_multi_payload_unchecked_enum_data : $@convention(thin) (Either) -> () { +bb0(%0 : $Either): + retain_value %0 : $Either + %1 = unchecked_enum_data %0 : $Either, #Either.Right!enumelt.1 + release_value %1 : $S + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @strip_off_structs_only_non_trivial_field : $@convention(thin) (S2, S3) -> () { +// CHECK: bb0([[ARG0:%[0-9]+]] : $S2, [[ARG1:%[0-9]+]] : $S3): +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +// CHECK: retain_value [[ARG1]] +// CHECK-NEXT: [[EXT:%[0-9]+]] = struct_extract [[ARG1]] +// CHECK-NEXT: release_value [[EXT]] +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +sil @strip_off_structs_only_non_trivial_field : $@convention(thin) (S2, S3) -> () { +bb0(%0 : $S2, %1 : $S3): + retain_value %0 : $S2 + %2 = struct_extract %0 : $S2, #S2.y + release_value %2 : $Builtin.NativeObject + retain_value %1 : $S3 + %3 = struct_extract %1 : $S3, #S3.y + release_value %3 : $Builtin.NativeObject + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @strip_off_enum_from_payload : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @strip_off_enum_from_payload : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + %1 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %0 : $Builtin.NativeObject + strong_retain %0 : $Builtin.NativeObject + release_value %1 : $FakeOptional + %2 = tuple() + return %2 : $() +} + +// For now make sure we don't eliminate this. +// CHECK-LABEL: sil @guaranteed_is_always_known_safe : $@convention(thin) (@guaranteed @box Builtin.Int32) -> () { +// CHECK: retain +// CHECK: release +sil @guaranteed_is_always_known_safe : $@convention(thin) (@guaranteed @box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +sil [_semantics "arc.programtermination_point"] @fatalError : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () // user: %43 + +// CHECK-LABEL: sil @ignore_fatalErrorMsgBB : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @ignore_fatalErrorMsgBB : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb4, bb5 + +bb2: + strong_retain %0 : $Builtin.NativeObject + cond_br undef, bb3, bb4 + +bb3: + cond_br undef, bb4, bb5 + +bb4: + strong_release %0 : $Builtin.NativeObject + %1 = tuple() + return %1 : $() + +bb5: + %39 = function_ref @fatalError : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () // user: %43 + %40 = string_literal utf8 "fatal error" + %41 = integer_literal $Builtin.Word, 11 + %42 = integer_literal $Builtin.Int8, 11 + %43 = struct $StaticString (%40 : $Builtin.RawPointer, %41 : $Builtin.Word, %42 : $Builtin.Int8) + %44 = apply %39(%43, %43, %43) : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () + unreachable +} + +// CHECK-LABEL: sil @propagate_postdominating_owned_release_info : $@convention(thin) (@owned @box Builtin.Int32) -> () { +// CHECK: bb0( +// CHECK-NOT: retain +// CHECK-NOT: release +// CHECK: bb1: +// CHECK-NOT: retain +// CHECK-NOT: release +// CHECK: bb2: +// CHECK: strong_release +sil @propagate_postdominating_owned_release_info : $@convention(thin) (@owned @box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + br bb1 + +bb1: + cond_br undef, bb1, bb2 + +bb2: + strong_release %0 : $@box Builtin.Int32 + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @guaranteed_is_a_mayuse_maydecrement : $@convention(thin) (@owned Builtin.NativeObject) -> () { +// CHECK: retain +// CHECK: release +sil @guaranteed_is_a_mayuse_maydecrement : $@convention(thin) (@owned Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + %1 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + strong_retain %0 : $Builtin.NativeObject + apply %1(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + strong_release %0 : $Builtin.NativeObject + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @guaranteed_is_a_mayuse_maydecrement_can_remove_if_known_safe : $@convention(thin) (@owned Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK: strong_retain +// CHECK-NEXT: apply +// CHECK: strong_release +// CHECK-NOT: strong_release +sil @guaranteed_is_a_mayuse_maydecrement_can_remove_if_known_safe : $@convention(thin) (@owned Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + %1 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + strong_retain %0 : $Builtin.NativeObject + strong_retain %0 : $Builtin.NativeObject + apply %1(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + strong_release %0 : $Builtin.NativeObject + strong_release %0 : $Builtin.NativeObject + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @guaranteed_check_if_we_already_have_insertion_pt_we_use_that_one : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { +// CHECK: function_ref @guaranteed_use +// CHECK: strong_retain +// CHECK: strong_release +// CHECK: apply +// CHECK: function_ref @guaranteed_use +// CHECK: strong_retain +// CHECK: strong_release +// CHECK: function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () +sil @guaranteed_check_if_we_already_have_insertion_pt_we_use_that_one : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + %2 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + strong_release %1 : $Builtin.NativeObject + %3 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + apply %2(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + %4 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + strong_retain %1 : $Builtin.NativeObject + %5 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + strong_release %0 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// Make sure that we handle ARC branch uses correctly. + +// In the face of partial merges, we *can* remove retains, releases, but we can +// not move them. So remove these retains, releases. +// +// CHECK-LABEL: sil @branch_use1 : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @branch_use1 : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $@box Builtin.Int32 + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + br bb3 + +bb2: + strong_retain %0 : $@box Builtin.Int32 + br bb3 + +bb3: + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// We currently do not move this retain, release since we are very conservative with partial merges and code motion. +// +// CHECK-LABEL: sil @branch_use2 : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK: strong_retain +// CHECK: strong_retain +// CHECK: strong_release +sil @branch_use2 : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $@box Builtin.Int32 + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + br bb3 + +bb2: + strong_retain %0 : $@box Builtin.Int32 + br bb3 + +bb3: + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// We can ignore this branch since bb3's use of %0 is dead. +// +// CHECK-LABEL: sil @branch_use3 : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @branch_use3 : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + cond_br undef, bb1, bb2 + +bb1: + strong_retain %0 : $@box Builtin.Int32 + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + br bb3(undef : $@box Builtin.Int32) + +bb2: + strong_retain %0 : $@box Builtin.Int32 + br bb3(%0 : $@box Builtin.Int32) + +bb3(%2 : $@box Builtin.Int32): + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// Make sure that we properly ignore the cond_br and do not try to compare the +// pointer with the Builtin.Int1 arg. +// +// CHECK-LABEL: sil @cond_branch_use1 : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @cond_branch_use1 : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + strong_retain %0 : $@box Builtin.Int32 + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + %2 = integer_literal $Builtin.Int1, 0 + cond_br %2, bb1, bb2 + +bb1: + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// In this case, we can eliminate the retain, release pair since a cond_br does +// not have any side-effects and is effectively a dead PHI. LLVM will clean up +// the use if we do not. +// +// CHECK-LABEL: sil @cond_branch_use2 : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @cond_branch_use2 : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + strong_retain %0 : $@box Builtin.Int32 + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + %2 = integer_literal $Builtin.Int1, 0 + cond_br %2, bb1(%0 : $@box Builtin.Int32), bb2 + +bb1(%3 : $@box Builtin.Int32): + br bb3 + +bb2: + br bb3 + +bb3: + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @cond_branch_use3 : $@convention(thin) (@box Builtin.Int32) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @cond_branch_use3 : $@convention(thin) (@box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + strong_retain %0 : $@box Builtin.Int32 + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + %2 = integer_literal $Builtin.Int1, 0 + cond_br %2, bb2(%0 : $@box Builtin.Int32), bb1 + +bb2(%3 : $@box Builtin.Int32): + br bb3 + +bb1: + br bb3 + +bb3: + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @owned_return_value_test : $@convention(thin) () -> () { +// CHECK-NOT: strong_retain +// CHECK: strong_release +// CHECK-NOT: strong_release +sil @owned_return_value_test : $@convention(thin) () -> () { +bb0: + %0 = function_ref @owned_return : $@convention(thin) () -> (@owned @box Builtin.Int32) + %1 = apply %0() : $@convention(thin) () -> (@owned @box Builtin.Int32) + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %1 : $@box Builtin.Int32 + apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () + apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %1 : $@box Builtin.Int32 + strong_release %1 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @retains_that_are_not_removed_preserves_known_safety : $@convention(thin) (@owned @box Builtin.Int32, @box Builtin.Int32) -> () { +// CHECK-NOT: strong_retain +// CHECK: apply +// CHECK: apply +// CHECK-NOT: strong_release +// CHECK: strong_retain +// CHECK: apply +// CHECK: apply +// CHECK: strong_release +sil @retains_that_are_not_removed_preserves_known_safety : $@convention(thin) (@owned @box Builtin.Int32, @box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32, %1 : $@box Builtin.Int32): + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %2(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %2(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + strong_retain %0 : $@box Builtin.Int32 + apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () + apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @retains_that_are_removed_do_not_preserve_known_safety : $@convention(thin) (@owned @box Builtin.Int32, @box Builtin.Int32) -> () { +// CHECK: strong_retain +// CHECK: apply +// CHECK: apply +// CHECK: strong_release +// CHECK-NOT: strong_retain +// CHECK: apply +// CHECK-NOT: strong_release +sil @retains_that_are_removed_do_not_preserve_known_safety : $@convention(thin) (@owned @box Builtin.Int32, @box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32, %1 : $@box Builtin.Int32): + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %2(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %2(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + strong_retain %0 : $@box Builtin.Int32 + apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @alloc_ref_returns_at_p1 : $@convention(thin) () -> () { +// CHECK: alloc_ref +// CHECK-NOT: strong_retain +// CHECK: apply +// CHECK: apply +// CHECK: strong_release +// CHECK-NOT: strong_release +sil @alloc_ref_returns_at_p1 : $@convention(thin) () -> () { +bb0: + %0 = alloc_ref $Cls + %1 = unchecked_ref_cast %0 : $Cls to $@box Builtin.Int32 + strong_retain %0 : $Cls + %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () + apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %1 : $@box Builtin.Int32 + strong_release %1 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @alloc_ref_dynamic_returns_at_p1 : $@convention(thin) () -> () { +// CHECK: alloc_ref_dynamic +// CHECK-NOT: strong_retain +// CHECK: apply +// CHECK: apply +// CHECK: strong_release +// CHECK-NOT: strong_release +sil @alloc_ref_dynamic_returns_at_p1 : $@convention(thin) () -> () { +bb0: + %0 = metatype $@thick Cls.Type + %1 = alloc_ref_dynamic %0 : $@thick Cls.Type, $Cls + %2 = unchecked_ref_cast %1 : $Cls to $@box Builtin.Int32 + strong_retain %1 : $Cls + %3 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %3(%2) : $@convention(thin) (@box Builtin.Int32) -> () + apply %3(%2) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %2 : $@box Builtin.Int32 + strong_release %2 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @must_use_test : $@convention(thin) (@owned @box Builtin.Int32) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @must_use_test : $@convention(thin) (@owned @box Builtin.Int32) -> () { +bb0(%0 : $@box Builtin.Int32): + %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + strong_retain %0 : $@box Builtin.Int32 + apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @alloc_box_returns_at_p1 : $@convention(thin) () -> () { +// CHECK: alloc_box +// CHECK-NOT: strong_retain +// CHECK: apply +// CHECK: apply +// CHECK: strong_release +// CHECK-NOT: strong_release +sil @alloc_box_returns_at_p1 : $@convention(thin) () -> () { +bb0: + %0 = alloc_box $Builtin.Int32 + strong_retain %0#0 : $@box Builtin.Int32 + %3 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + apply %3(%0#0) : $@convention(thin) (@box Builtin.Int32) -> () + apply %3(%0#0) : $@convention(thin) (@box Builtin.Int32) -> () + strong_release %0#0 : $@box Builtin.Int32 + strong_release %0#0 : $@box Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @copyArrayDoesntDecrementRefCounts : $@convention(thin) (Builtin.RawPointer, Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @copyArrayDoesntDecrementRefCounts : $@convention(thin) (Builtin.RawPointer, Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.NativeObject): + %2 = metatype $@thick Builtin.Int32.Type + %3 = integer_literal $Builtin.Word, 1 + strong_retain %1 : $Builtin.NativeObject + %4 = builtin "copyArray"(%2 : $@thick Builtin.Int32.Type, %0 : $Builtin.RawPointer, %0 : $Builtin.RawPointer, %3 : $Builtin.Word) : $() + fix_lifetime %1 : $Builtin.NativeObject + strong_release %1 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @clibraryintrinsicsdonttouchrefcounts : $@convention(thin) (Builtin.RawPointer, Builtin.NativeObject) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @clibraryintrinsicsdonttouchrefcounts : $@convention(thin) (Builtin.RawPointer, Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.NativeObject): + %3 = integer_literal $Builtin.Int64, 1 + %4 = integer_literal $Builtin.Int32, 1 + %5 = integer_literal $Builtin.Int1, 0 + strong_retain %1 : $Builtin.NativeObject + %6 = builtin "int_memcpy_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %0 : $Builtin.RawPointer, %3 : $Builtin.Int64, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $() + fix_lifetime %1 : $Builtin.NativeObject + strong_release %1 : $Builtin.NativeObject + strong_retain %1 : $Builtin.NativeObject + %7 = builtin "int_memset_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %0 : $Builtin.RawPointer, %3 : $Builtin.Int64, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $() + fix_lifetime %1 : $Builtin.NativeObject + strong_release %1 : $Builtin.NativeObject + strong_retain %1 : $Builtin.NativeObject + %8 = builtin "int_memmove_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %0 : $Builtin.RawPointer, %3 : $Builtin.Int64, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $() + fix_lifetime %1 : $Builtin.NativeObject + strong_release %1 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @convert_function_preserves_rc_identity : $@convention(thin) () -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @convert_function_preserves_rc_identity : $@convention(thin) () -> () { +bb0: + %0 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () + %1 = partial_apply %0() : $@convention(thin) (@box Builtin.Int32) -> () + strong_retain %1 : $@callee_owned (@box Builtin.Int32) -> () + %2 = convert_function %1 : $@callee_owned (@box Builtin.Int32) -> () to $@callee_owned (@box Builtin.Int32) -> () + strong_release %2 : $@callee_owned (@box Builtin.Int32) -> () + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil [fragile] @try_apply_test_1 : $@convention(thin) (Builtin.NativeObject) -> @error ErrorType { +// CHECK: bb0 +// CHECK: strong_retain +// CHECK: bb1 +// CHECK: strong_release +// CHECK: bb2 +// CHECK: strong_release +sil [fragile] @try_apply_test_1 : $@convention(thin) (Builtin.NativeObject) -> @error ErrorType { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + %1 = function_ref @guaranteed_throwing_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error ErrorType + try_apply %1(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error ErrorType, normal bb1, error bb2 + +bb1(%2 : $()): + strong_release %0 : $Builtin.NativeObject + return undef : $() + +bb2(%3 : $ErrorType): + strong_release %0 : $Builtin.NativeObject + throw %3 : $ErrorType +} + +// CHECK-LABEL: sil [fragile] @try_apply_test_2 : $@convention(thin) (Builtin.NativeObject) -> @error ErrorType { +// CHECK: bb0( +// CHECK: strong_retain +// CHECK: try_apply +// CHECK: bb1( +// CHECK: strong_release +// CHECK: bb2( +// CHECK: strong_release +sil [fragile] @try_apply_test_2 : $@convention(thin) (Builtin.NativeObject) -> @error ErrorType { +bb0(%0 : $Builtin.NativeObject): + strong_retain %0 : $Builtin.NativeObject + %1 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + apply %1(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () + %2 = function_ref @guaranteed_throwing_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error ErrorType + try_apply %2(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error ErrorType, normal bb1, error bb2 + +bb1(%3 : $()): + strong_release %0 : $Builtin.NativeObject + return undef : $() + +bb2(%4 : $ErrorType): + strong_release %0 : $Builtin.NativeObject + throw %4 : $ErrorType +} diff --git a/test/SILOptimizer/arcsequenceopts_casts.sil b/test/SILOptimizer/arcsequenceopts_casts.sil new file mode 100644 index 0000000000000..43f89572faf8f --- /dev/null +++ b/test/SILOptimizer/arcsequenceopts_casts.sil @@ -0,0 +1,46 @@ +// RUN: %target-sil-opt -module-name Swift -enable-sil-verify-all -arc-sequence-opts -enable-loop-arc=0 %s | FileCheck %s +// RUN: %target-sil-opt -module-name Swift -enable-sil-verify-all -arc-sequence-opts -enable-loop-arc=1 %s | FileCheck %s + +import Builtin + +public enum Optional { + case None + case Some(T) +} + +class C { + init() +} + +// Simple test that stripping works. +// CHECK-LABEL: sil @test1 : $@convention(thin) (C) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @test1 : $@convention(thin) (C) -> () { +bb0(%0 : $C): + strong_retain %0 : $C + %1 = unchecked_ref_cast %0 : $C to $Builtin.NativeObject + strong_release %1 : $Builtin.NativeObject + %2 = tuple() + return %2 : $() +} + +// We allow for matching up of retain_value, strong_release now that we +// have unchecked_ref_cast. + +// CHECK-LABEL: sil @test2 : $@convention(thin) (Optional, Optional) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +sil @test2 : $@convention(thin) (Optional, Optional) -> () { +bb0(%0 : $Optional, %1 : $Optional): + retain_value %0 : $Optional + %2 = unchecked_ref_cast %0 : $Optional to $C + strong_release %2 : $C + %3 = unchecked_ref_cast %1 : $Optional to $C + strong_retain %3 : $C + release_value %1 : $Optional + %9999 = tuple() + return %9999 : $() +} diff --git a/test/SILPasses/globalarcopts_loops.sil b/test/SILOptimizer/arcsequenceopts_loops.sil similarity index 100% rename from test/SILPasses/globalarcopts_loops.sil rename to test/SILOptimizer/arcsequenceopts_loops.sil diff --git a/test/SILPasses/global_arc_opts_loops.sil.gyb b/test/SILOptimizer/arcsequenceopts_loops.sil.gyb similarity index 100% rename from test/SILPasses/global_arc_opts_loops.sil.gyb rename to test/SILOptimizer/arcsequenceopts_loops.sil.gyb diff --git a/test/SILOptimizer/arcsequenceopts_rcidentityanalysis.sil b/test/SILOptimizer/arcsequenceopts_rcidentityanalysis.sil new file mode 100644 index 0000000000000..82d75cbfa3b1d --- /dev/null +++ b/test/SILOptimizer/arcsequenceopts_rcidentityanalysis.sil @@ -0,0 +1,594 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | FileCheck %s + +sil_stage canonical + +import Builtin + +// Utilities + +sil @user : $@convention(thin) (Builtin.NativeObject) -> () + +struct S { + var x : Builtin.NativeObject +} +sil @S_user : $@convention(thin) (S) -> () + +struct S2 { + var x : Builtin.Int32 + var y : Builtin.NativeObject + var z : Builtin.Int32 +} + +struct S3 { + var x : Builtin.Int32 + var y : Builtin.NativeObject + var y1 : Builtin.NativeObject + var z : Builtin.Int32 +} + +class Cls { + var random : Builtin.Int32 + + init() +} + +public enum FakeOptional { + case None + case Some(T) +} + +public protocol AnyObject : class {} + +class C { + init() + var w : FakeOptional +} + +class RetainUser { } + +sil @rawpointer_use: $@convention(thin) (Builtin.RawPointer) -> () + +sil @fakeoptional_user : $@convention(thin) (FakeOptional) -> () + +enum Either { + case Left(LTy) + case Right(RTy) +} + +/// This type allows us to make sure we are skipping cases correctly when +/// stripping off ref count identical opts. +enum FakeCasesOptional { + case None + case None1 + case Some(T) + case None2 + case Some2(T) + case None3 +} + +/////////// +// Tests // +/////////// + +// CHECK-LABEL: sil @silargument_strip_single_payload_case_enum1 : $@convention(thin) (FakeOptional) -> () { +// CHECK-NOT: retain +// CHECK-NOT: release +sil @silargument_strip_single_payload_case_enum1 : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1: + br bb3(%0 : $FakeOptional) + +bb2: + br bb3(%0 : $FakeOptional) + +bb3(%1 : $FakeOptional): + retain_value %1 : $FakeOptional + release_value %0 : $FakeOptional + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: sil @silargument_strip_single_payload_case_enum2 : $@convention(thin) (FakeOptional) -> () { +// CHECK-NOT: retain +// CHECK-NOT: release +sil @silargument_strip_single_payload_case_enum2 : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1: + br bb3(%0 : $FakeOptional) + +bb2: + %1 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%1 : $FakeOptional) + +bb3(%2 : $FakeOptional): + retain_value %2 : $FakeOptional + release_value %0 : $FakeOptional + %3 = tuple() + return %3 : $() +} + +// This is supposed to fail b/c %0 is not .None down bb1. +// +// CHECK-LABEL: sil @silargument_strip_single_payload_case_enum3 : $@convention(thin) (FakeOptional) -> () { +// CHECK: retain +// CHECK: release +sil @silargument_strip_single_payload_case_enum3 : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1: + %1 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%1 : $FakeOptional) + +bb2: + br bb3(%0 : $FakeOptional) + +bb3(%2 : $FakeOptional): + retain_value %2 : $FakeOptional + release_value %0 : $FakeOptional + %3 = tuple() + return %3 : $() +} + +// Make sure we do not do anything dumb when we have two enums without payloads. +// CHECK-LABEL: sil @silargument_strip_single_payload_case_enum4 : $@convention(thin) (FakeOptional) -> () { +// CHECK: retain_value +// CHECK: release_value +sil @silargument_strip_single_payload_case_enum4 : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1: + %1 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%1 : $FakeOptional) + +bb2: + %2 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%2 : $FakeOptional) + +bb3(%3 : $FakeOptional): + retain_value %3 : $FakeOptional + release_value %0 : $FakeOptional + %4 = tuple() + return %4 : $() +} + +// Make sure that we can handle the multi payload case with interleaved empty +// payloads. +// CHECK-LABEL: sil @silargument_strip_multipayload_with_fake_nopayload_cases : $@convention(thin) (FakeCasesOptional) -> () { +// CHECK-NOT: retain +// CHECK-NOT: release +sil @silargument_strip_multipayload_with_fake_nopayload_cases : $@convention(thin) (FakeCasesOptional) -> () { +bb0(%0 : $FakeCasesOptional): + switch_enum %0 : $FakeCasesOptional, case #FakeCasesOptional.None!enumelt: bb1, case #FakeCasesOptional.None1!enumelt: bb2, case #FakeCasesOptional.Some!enumelt.1: bb3, case #FakeCasesOptional.None2!enumelt: bb4, case #FakeCasesOptional.Some2!enumelt.1: bb5, case #FakeCasesOptional.None3!enumelt: bb6 + +bb1: + %1 = enum $FakeCasesOptional, #FakeCasesOptional.None!enumelt + br bb7(%1 : $FakeCasesOptional) + +bb2: + %2 = enum $FakeCasesOptional, #FakeCasesOptional.None1!enumelt + br bb7(%2 : $FakeCasesOptional) + +bb3: + br bb7(%0 : $FakeCasesOptional) + +bb4: + %3 = enum $FakeCasesOptional, #FakeCasesOptional.None2!enumelt + br bb7(%3 : $FakeCasesOptional) + +bb5: + br bb7(%0 : $FakeCasesOptional) + +bb6: + %4 = enum $FakeCasesOptional, #FakeCasesOptional.None3!enumelt + br bb7(%4 : $FakeCasesOptional) + +bb7(%5 : $FakeCasesOptional): + retain_value %5 : $FakeCasesOptional + release_value %0 : $FakeCasesOptional + %6 = tuple() + return %6 : $() +} + +// This looks like we are reforming an enum, but we are not really. Make sure +// that we do not remove the retain, release in this case. +// CHECK-LABEL: sil @silargument_fake_enum_reform : $@convention(thin) (Builtin.NativeObject) -> () { +// CHECK: retain_value +// CHECK: release_value +sil @silargument_fake_enum_reform : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + cond_br undef, bb1, bb2 + +bb1: + %1 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%1 : $FakeOptional) + +bb2: + %2 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %0 : $Builtin.NativeObject + br bb3(%2 : $FakeOptional) + +bb3(%3 : $FakeOptional): + retain_value %0 : $Builtin.NativeObject + release_value %3 : $FakeOptional + %9999 = tuple() + return %9999 : $() +} + +// Make sure that we can handle multiple-iterated enum args where the +// switch_enum or unchecked_enum_data is before the next diamond. +// CHECK-LABEL: sil @silargument_iterated_silargument_strips : $@convention(thin) (FakeOptional) -> () { +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +sil @silargument_iterated_silargument_strips : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1: + br bb3(%0 : $FakeOptional) + +bb2: + %1 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%1 : $FakeOptional) + +bb3(%2 : $FakeOptional): + switch_enum %2 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb4, case #FakeOptional.None!enumelt: bb5 + +bb4: + br bb6(%2 : $FakeOptional) + +bb5: + %3 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb6(%3 : $FakeOptional) + +bb6(%4 : $FakeOptional): + retain_value %0 : $FakeOptional + release_value %4 : $FakeOptional + %9999 = tuple() + return %9999 : $() +} + +// Make sure that (for now) we do not look past %2 to see that %0 can be matched +// up with %0, %4. +// +// I think this is in general safe, but for now I want to be more than less +// conservative. +// +// CHECK-LABEL: sil @silargument_iterated_silargument_strips_too_far_up_domtree : $@convention(thin) (FakeOptional) -> () { +// CHECK: retain_value +// CHECK: release_value +sil @silargument_iterated_silargument_strips_too_far_up_domtree : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1: + br bb3(%0 : $FakeOptional) + +bb2: + %1 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%1 : $FakeOptional) + +bb3(%2 : $FakeOptional): + cond_br undef, bb4, bb5 + +bb4: + br bb6(%2 : $FakeOptional) + +bb5: + %3 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb6(%3 : $FakeOptional) + +bb6(%4 : $FakeOptional): + retain_value %0 : $FakeOptional + release_value %4 : $FakeOptional + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @silargument_dont_strip_over_relevant_loop : $@convention(thin) (FakeOptional) -> () { +// CHECK: retain_value +// CHECK: release_value +sil @silargument_dont_strip_over_relevant_loop : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1: + br bb3(%0 : $FakeOptional) + +bb2: + %1 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%1 : $FakeOptional) + +bb3(%2 : $FakeOptional): + cond_br undef, bb3(%2 : $FakeOptional), bb4 + +bb4: + retain_value %0 : $FakeOptional + release_value %2 : $FakeOptional + %9999 = tuple() + return %9999 : $() +} + +// Make sure we are properly iterating up the domtree by checking if we properly +// look past the loop in bb4 and match up %0 and %2. +// +// CHECK-LABEL: sil @silargument_do_strip_over_irrelevant_loop : $@convention(thin) (FakeOptional) -> () { +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +sil @silargument_do_strip_over_irrelevant_loop : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 + +bb1: + br bb3(%0 : $FakeOptional) + +bb2: + %1 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%1 : $FakeOptional) + +bb3(%2 : $FakeOptional): + cond_br undef, bb4, bb5 + +bb4: + cond_br undef, bb4, bb5 + +bb5: + retain_value %0 : $FakeOptional + release_value %2 : $FakeOptional + %9999 = tuple() + return %9999 : $() +} + + + +// CHECK-LABEL: sil @silargument_nondominated_strip : $@convention(thin) (@in FakeOptional) -> () { +// CHECK: retain_value +// CHECK: release_value +sil @silargument_nondominated_strip : $@convention(thin) (@in FakeOptional) -> () { +bb0(%0 : $*FakeOptional): + cond_br undef, bb1, bb2 + +bb1: + %1 = load %0 : $*FakeOptional + br bb3(%1 : $FakeOptional) + +bb2: + %2 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb3(%2 : $FakeOptional) + +bb3(%3 : $FakeOptional): + %4 = function_ref @fakeoptional_user : $@convention(thin) (FakeOptional) -> () + retain_value %3 : $FakeOptional + apply %4(%3) : $@convention(thin) (FakeOptional) -> () + apply %4(%3) : $@convention(thin) (FakeOptional) -> () + release_value %3 : $FakeOptional + %5 = tuple() + return %5 : $() +} + +struct _SwiftEmptyArrayStorage { +} + +sil_global [fragile] @_swiftEmptyArrayStorage : $_SwiftEmptyArrayStorage + +// CHECK-LABEL: sil @dont_strip_rawpointer_to_address +// CHECK: raw_pointer_to_ref +// CHECK: strong_retain +// CHECK: return +sil @dont_strip_rawpointer_to_address : $@convention(thin) (FakeOptional) -> () { +bb0(%0 : $FakeOptional): + %2 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage + %3 = address_to_pointer %2 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer + %4 = raw_pointer_to_ref %3 : $Builtin.RawPointer to $Builtin.NativeObject + strong_retain %4 : $Builtin.NativeObject + %5 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () + apply %5(%4) : $@convention(thin) (Builtin.NativeObject) -> () + apply %5(%4) : $@convention(thin) (Builtin.NativeObject) -> () + strong_release %4 : $Builtin.NativeObject + %6 = tuple() + return %6 : $() +} + +// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_1bb : $@convention(thin) () -> () { +// CHECK: retain_value +// CHECK: release_value +sil @dont_strip_phi_nodes_over_backedges_1bb : $@convention(thin) () -> () { +bb0: + %0 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb1(%0 : $FakeOptional) + +bb1(%1 : $FakeOptional): + %2 = alloc_ref $Cls + retain_value %2 : $Cls + release_value %1 : $FakeOptional + %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls + cond_br undef, bb1(%3 : $FakeOptional), bb2 + +bb2: + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb1 : $@convention(thin) () -> () { +// CHECK: retain_value +// CHECK: release_value +sil @dont_strip_phi_nodes_over_backedges_multibb1 : $@convention(thin) () -> () { +bb0: + %0 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb1(%0 : $FakeOptional) + +bb1(%1 : $FakeOptional): + %2 = alloc_ref $Cls + retain_value %2 : $Cls + br bb2 + +bb2: + release_value %1 : $FakeOptional + %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls + br bb3 + +bb3: + cond_br undef, bb1(%3 : $FakeOptional), bb4 + +bb4: + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb2 : $@convention(thin) () -> () { +// CHECK: retain_value +// CHECK: release_value +sil @dont_strip_phi_nodes_over_backedges_multibb2 : $@convention(thin) () -> () { +bb0: + %0 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb1(%0 : $FakeOptional) + +bb1(%1 : $FakeOptional): + br bb2 + +bb2: + %2 = alloc_ref $Cls + retain_value %2 : $Cls + release_value %1 : $FakeOptional + %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls + br bb3 + +bb3: + cond_br undef, bb1(%3 : $FakeOptional), bb4 + +bb4: + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb3 : $@convention(thin) () -> () { +// CHECK: retain_value +// CHECK: release_value +sil @dont_strip_phi_nodes_over_backedges_multibb3 : $@convention(thin) () -> () { +bb0: + %0 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb1(%0 : $FakeOptional) + +bb1(%1 : $FakeOptional): + br bb2 + +bb2: + %2 = alloc_ref $Cls + retain_value %2 : $Cls + br bb3 + +bb3: + release_value %1 : $FakeOptional + %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls + cond_br undef, bb1(%3 : $FakeOptional), bb4 + +bb4: + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb4 : $@convention(thin) () -> () { +// CHECK: retain_value +// CHECK: release_value +sil @dont_strip_phi_nodes_over_backedges_multibb4 : $@convention(thin) () -> () { +bb0: + %0 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb1(%0 : $FakeOptional) + +bb1(%1 : $FakeOptional): + br bb2 + +bb2: + br bb3 + +bb3: + %2 = alloc_ref $Cls + retain_value %2 : $Cls + release_value %1 : $FakeOptional + %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls + cond_br undef, bb1(%3 : $FakeOptional), bb4 + +bb4: + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb5 : $@convention(thin) () -> () { +// CHECK: retain_value +// CHECK: release_value +sil @dont_strip_phi_nodes_over_backedges_multibb5 : $@convention(thin) () -> () { +bb0: + %0 = enum $FakeOptional, #FakeOptional.None!enumelt + br bb1(%0 : $FakeOptional) + +bb1(%1 : $FakeOptional): + %2 = alloc_ref $Cls + retain_value %2 : $Cls + br bb2 + +bb2: + br bb3 + +bb3: + release_value %1 : $FakeOptional + %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls + cond_br undef, bb1(%3 : $FakeOptional), bb4 + +bb4: + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: sil @strip_off_structs_tuples_tuple_extracts : $@convention(thin) (Builtin.NativeObject, (Builtin.Int32, Builtin.NativeObject, Builtin.Int32)) -> () { +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +sil @strip_off_structs_tuples_tuple_extracts : $@convention(thin) (Builtin.NativeObject, (Builtin.Int32, Builtin.NativeObject, Builtin.Int32)) -> () { +bb0(%0 : $Builtin.NativeObject, %1 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32)): + %2 = integer_literal $Builtin.Int32, 0 + %3 = struct $S2(%2 : $Builtin.Int32, %0 : $Builtin.NativeObject, %2 : $Builtin.Int32) + retain_value %3 : $S2 + %4 = tuple(%2 : $Builtin.Int32, %0 : $Builtin.NativeObject, %2 : $Builtin.Int32) + release_value %4 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32) + retain_value %1 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32) + %5 = tuple_extract %1 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32), 1 + release_value %5 : $Builtin.NativeObject + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @strip_off_initopen_existential_ref : $@convention(thin) (C) -> () { +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +// CHECK-NOT: retain_value +// CHECK-NOT: release_value +sil @strip_off_initopen_existential_ref : $@convention(thin) (C) -> () { +bb0(%0 : $C): + %1 = init_existential_ref %0 : $C : $C, $AnyObject + %2 = open_existential_ref %1 : $AnyObject to $@opened("A2E21C52-6089-11E4-9866-3C0754723233") AnyObject + strong_retain %0 : $C + release_value %2 : $@opened("A2E21C52-6089-11E4-9866-3C0754723233") AnyObject + %3 = tuple() + return %3 : $() +} + +// CHECK-LABEL: sil @strip_off_bridge_object +// CHECK-NOT: strong_retain +// CHECK-NOT: strong_release +sil @strip_off_bridge_object : $@convention(thin) (Builtin.BridgeObject, C) -> () { +bb0(%0 : $Builtin.BridgeObject, %5 : $C): + %1 = bridge_object_to_ref %0 : $Builtin.BridgeObject to $C + strong_retain %1 : $C + strong_release %0 : $Builtin.BridgeObject + %4 = integer_literal $Builtin.Word, 0 + %2 = ref_to_bridge_object %5 : $C, %4 : $Builtin.Word + strong_retain %5 : $C + strong_release %2 : $Builtin.BridgeObject + %3 = tuple() + return %3 : $() +} + diff --git a/test/SILOptimizer/arcsequenceopts_uniquecheck.sil b/test/SILOptimizer/arcsequenceopts_uniquecheck.sil new file mode 100644 index 0000000000000..72d94dae56438 --- /dev/null +++ b/test/SILOptimizer/arcsequenceopts_uniquecheck.sil @@ -0,0 +1,106 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | FileCheck %s + +import Builtin +import Swift +import SwiftShims + +class MD5 { + init() + final var w: [UInt32] +} + +// CHECK-LABEL:sil @test_unique_check_arc : $@convention(method) (@owned MD5) -> () +sil @test_unique_check_arc : $@convention(method) (@owned MD5) -> () { +// CHECK: bb0 +bb0(%0 : $MD5): + %1 = integer_literal $Builtin.Int32, 0 + %2 = integer_literal $Builtin.Int32, 16 + %3 = struct $Int32 (%1 : $Builtin.Int32) + br bb1(%1 : $Builtin.Int32) + +// CHECK: bb1 +bb1(%5 : $Builtin.Int32): + %7 = builtin "cmp_eq_Int32"(%5 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int1 + cond_br %7, bb3, bb2 + +// CHECK: bb2 +bb2: + %9 = integer_literal $Builtin.Int32, 1 + %11 = integer_literal $Builtin.Int1, -1 + %12 = builtin "sadd_with_overflow_Int32"(%5 : $Builtin.Int32, %9 : $Builtin.Int32, %11 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) + %13 = tuple_extract %12 : $(Builtin.Int32, Builtin.Int1), 0 + // CHECK-NOT: strong_retain + // CHECK-NOT: strong_release + strong_retain %0 : $MD5 + %314 = ref_element_addr %0 : $MD5, #MD5.w + %318 = load %314 : $*Array + %319 = alloc_stack $Array + store %318 to %319 : $*Array + dealloc_stack %319 : $*Array + %179 = is_unique %314 : $*Array + cond_br %179, bb4, bb5 + +// CHECK: bb3 +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple +// CHECK-NEXT: return +bb3: + strong_release %0 : $MD5 + %273 = tuple () + return %273 : $() + +bb4: + br bb5 + +// CHECK-NOT: strong_release +bb5: + strong_release %0 : $MD5 + br bb1(%13 : $Builtin.Int32) + +} + +class C {} + +// Check that retains are not moved across an is_unique that may alias. +sil @test_uniq_alias : $@convention(method) (@owned C) -> Builtin.Int1 { +// CHECK: bb0 +bb0(%0 : $C): + %1 = alloc_stack $C, var, name "x" + store %0 to %1 : $*C +// CHECK: strong_retain %0 : $C + strong_retain %0 : $C +// CHECK: is_unique %1 : $*C + %4 = is_unique %1 : $*C +// CHECK-NOT: strong_retain + fix_lifetime %0 : $C +// CHECK: strong_release %0 : $C + strong_release %0 : $C +// CHECK: [[LOADED:%[0-9]+]] = load %1 : $*C + %8 = load %1 : $*C +// CHECK: strong_release [[LOADED]] : $C + strong_release %8 : $C + dealloc_stack %1 : $*C + return %4 : $Builtin.Int1 +} + +// The following test could optimize to: +// %2 = load %1 : $*C // user: %4 +// %3 = is_unique %0 : $*C // user: %5 +// fix_lifetime %2 : $C // id: %4 +// +// But ARC is currently conservative. When this is fixed, +// change _CHECK: strong... into _CHECK_NOT: strong... +sil @test_uniq_noalias : $@convention(thin) (@inout C, @inout C) -> Builtin.Int1 { +// CHECK: bb0 +bb0(%0 : $*C, %1 : $*C): + %2 = load %1 : $*C +// CHECK: strong_retain %2 : $C + strong_retain %2 : $C +// CHECK: is_unique %0 : $*C + %4 = is_unique %0 : $*C + fix_lifetime %2 : $C +// CHECK: strong_release %2 : $C + strong_release %2 : $C + return %4 : $Builtin.Int1 +} diff --git a/test/SILPasses/array_count_propagation.sil b/test/SILOptimizer/array_count_propagation.sil similarity index 94% rename from test/SILPasses/array_count_propagation.sil rename to test/SILOptimizer/array_count_propagation.sil index b047528090b2e..ac58dbd80b926 100644 --- a/test/SILPasses/array_count_propagation.sil +++ b/test/SILOptimizer/array_count_propagation.sil @@ -83,9 +83,9 @@ bb0: %15 = function_ref @getElement : $@convention(method) (@out MyInt, MyInt, MyBool, @guaranteed MyArray) -> () %16 = alloc_stack $MyInt %17 = struct $MyBool() - %18 = apply %15(%16#1, %3, %17, %7) : $@convention(method) (@out MyInt, MyInt, MyBool, @guaranteed MyArray) -> () + %18 = apply %15(%16, %3, %17, %7) : $@convention(method) (@out MyInt, MyInt, MyBool, @guaranteed MyArray) -> () strong_release %14 : $Builtin.BridgeObject - dealloc_stack %16#0 : $*@local_storage MyInt + dealloc_stack %16 : $*MyInt return %10 : $MyInt } @@ -101,10 +101,10 @@ bb0: %0 = integer_literal $Builtin.Int64, 3 %1 = alloc_stack $MyInt %3 = struct $MyInt(%0 : $Builtin.Int64) - store %3 to %1#1: $*MyInt + store %3 to %1: $*MyInt %4 = metatype $@thin MyArray.Type %5 = function_ref @initCountRepeatedValue : $@convention(thin) (MyInt, @in MyInt, @thin MyArray.Type) -> @owned MyArray - %6 = apply %5(%3, %1#1, %4) : $@convention(thin) (MyInt, @in MyInt, @thin MyArray.Type) -> @owned MyArray + %6 = apply %5(%3, %1, %4) : $@convention(thin) (MyInt, @in MyInt, @thin MyArray.Type) -> @owned MyArray debug_value %6 : $MyArray %9 = function_ref @getCount : $@convention(method) (@guaranteed MyArray) -> MyInt %10 = apply %9(%6) : $@convention(method) (@guaranteed MyArray) -> MyInt @@ -114,10 +114,10 @@ bb0: %15 = function_ref @getElement : $@convention(method) (@out MyInt, MyInt, MyBool, @guaranteed MyArray) -> () %16 = alloc_stack $MyInt %17 = struct $MyBool() - %18 = apply %15(%16#1, %3, %17, %6) : $@convention(method) (@out MyInt, MyInt, MyBool, @guaranteed MyArray) -> () + %18 = apply %15(%16, %3, %17, %6) : $@convention(method) (@out MyInt, MyInt, MyBool, @guaranteed MyArray) -> () strong_release %14 : $Builtin.BridgeObject - dealloc_stack %16#0 : $*@local_storage MyInt - dealloc_stack %1#0 : $*@local_storage MyInt + dealloc_stack %16 : $*MyInt + dealloc_stack %1 : $*MyInt return %10 : $MyInt } @@ -139,7 +139,7 @@ bb0: %6 = apply %5(%2, %3, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray.Type) -> @owned (MyArray, UnsafeMutablePointer) %7 = tuple_extract %6 : $(MyArray, UnsafeMutablePointer), 0 %8 = tuple_extract %6 : $(MyArray, UnsafeMutablePointer), 1 - store %7 to %15#1 : $*MyArray + store %7 to %15 : $*MyArray debug_value %7 : $MyArray %9 = function_ref @getCount : $@convention(method) (@guaranteed MyArray) -> MyInt %10 = apply %9(%7) : $@convention(method) (@guaranteed MyArray) -> MyInt @@ -147,7 +147,7 @@ bb0: %13 = struct_extract %12 : $_MyArrayBuffer, #_MyArrayBuffer._storage %14 = struct_extract %13 : $_MyBridgeStorage, #_MyBridgeStorage.rawValue strong_release %14 : $Builtin.BridgeObject - dealloc_stack %15#0 : $*@local_storage MyArray + dealloc_stack %15 : $*MyArray return %10 : $MyInt } diff --git a/test/SILOptimizer/array_element_propagation.sil b/test/SILOptimizer/array_element_propagation.sil new file mode 100644 index 0000000000000..752c30edd0649 --- /dev/null +++ b/test/SILOptimizer/array_element_propagation.sil @@ -0,0 +1,208 @@ +// RUN: %target-sil-opt -array-element-propagation %s | FileCheck %s +sil_stage canonical + +import Builtin +import Swift + +struct MyInt { + @sil_stored var _value: Builtin.Int64 +} + +struct MyBool {} +struct _MyDependenceToken {} + +struct _MyBridgeStorage { + @sil_stored var rawValue : Builtin.BridgeObject +} + +struct _MyArrayBuffer { + @sil_stored var _storage : _MyBridgeStorage +} + + +struct MyArray { + @sil_stored var _buffer : _MyArrayBuffer +} + +sil @swift_bufferAllocate : $@convention(thin)() -> @owned AnyObject +sil [_semantics "array.uninitialized"] @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray.Type) -> @owned (MyArray, UnsafeMutablePointer) +sil [_semantics "array.props.isNativeTypeChecked"] @hoistableIsNativeTypeChecked : $@convention(method) (@guaranteed MyArray) -> MyBool +sil [_semantics "array.check_subscript"] @checkSubscript : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken +sil [_semantics "array.get_element"] @getElement : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () +sil @unknown_array_use : $@convention(method) (@guaranteed MyArray) -> MyBool + +// CHECK-LABEL: sil @propagate01 +// CHECK: struct $MyInt +// CHECK: [[V0:%.*]] = integer_literal $Builtin.Int64, 0 +// CHECK: [[I0:%.*]] = struct $MyInt ([[V0]] : $Builtin.Int64) +// CHECK: [[V1:%.*]] = integer_literal $Builtin.Int64, 1 +// CHECK: [[I1:%.*]] = struct $MyInt ([[V1]] : $Builtin.Int64) +// CHECK: [[V2:%.*]] = integer_literal $Builtin.Int64, 2 +// CHECK: [[I2:%.*]] = struct $MyInt ([[V2]] : $Builtin.Int64) +// CHECK: [[S0:%.*]] = alloc_stack $MyInt +// CHECK: [[HFUN:%.*]] = function_ref @hoistableIsNativeTypeChecked +// CHECK-NOT: apply [[HFUN]] +// CHECK: [[CFUN:%.*]] = function_ref @checkSubscript +// CHECK-NOT: apply [[CFUN]] +// CHECK: [[GFUN:%.*]] = function_ref @getElement +// CHECK-NOT: apply [[GFUN]] +// CHECK-NOT: apply [[HFUN]] +// CHECK-NOT: apply [[CFUN]] +// CHECK-NOT: apply [[GFUN]] +// CHECK: store [[I0]] to [[S0]] +// CHECK: [[S1:%.*]] = alloc_stack $MyInt +// CHECK: store [[I1]] to [[S1]] +// CHECK: [[S2:%.*]] = alloc_stack $MyInt +// CHECK: store [[I2]] to [[S2]] +// CHECK: return + +sil @propagate01 : $@convention(thin) () -> () { + %0 = function_ref @swift_bufferAllocate : $@convention(thin) () -> @owned AnyObject + %1 = integer_literal $Builtin.Int64, 3 + %2 = struct $MyInt (%1 : $Builtin.Int64) + %3 = apply %0() : $@convention(thin) () -> @owned AnyObject + %4 = metatype $@thin MyArray.Type + %5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray.Type) -> @owned (MyArray, UnsafeMutablePointer) + %6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray.Type) -> @owned (MyArray, UnsafeMutablePointer) + %7 = tuple_extract %6 : $(MyArray, UnsafeMutablePointer), 0 + %8 = tuple_extract %6 : $(MyArray, UnsafeMutablePointer), 1 + debug_value %7 : $MyArray + debug_value %8 : $UnsafeMutablePointer + %9 = struct_extract %8 : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue + %10 = pointer_to_address %9 : $Builtin.RawPointer to $*MyInt + %11 = integer_literal $Builtin.Int64, 0 + %12 = struct $MyInt (%11 : $Builtin.Int64) + store %12 to %10 : $*MyInt + %13 = integer_literal $Builtin.Word, 1 + %14 = index_addr %10 : $*MyInt, %13 : $Builtin.Word + %15 = integer_literal $Builtin.Int64, 1 + %16 = struct $MyInt (%15 : $Builtin.Int64) + store %16 to %14 : $*MyInt + %17 = integer_literal $Builtin.Word, 2 + %18 = index_addr %10 : $*MyInt, %17 : $Builtin.Word + %19 = integer_literal $Builtin.Int64, 2 + %20 = struct $MyInt (%19 : $Builtin.Int64) + store %20 to %18 : $*MyInt + %23 = struct_extract %7 : $MyArray, #MyArray._buffer + %24 = struct_extract %23 : $_MyArrayBuffer, #_MyArrayBuffer._storage + %25 = struct_extract %24 : $_MyBridgeStorage, #_MyBridgeStorage.rawValue + %26 = alloc_stack $MyInt + debug_value %7 : $MyArray + %27 = function_ref @hoistableIsNativeTypeChecked : $@convention(method) (@guaranteed MyArray) -> MyBool + %28 = apply %27(%7) : $@convention(method) (@guaranteed MyArray) -> MyBool + debug_value %28 : $MyBool // id: %104 + %29 = function_ref @checkSubscript : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + %30 = apply %29(%12, %28, %7) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + debug_value %30 : $_MyDependenceToken + %31 = function_ref @getElement : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + %32 = apply %31(%26, %12, %28, %30, %7) : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + %35 = alloc_stack $MyInt + debug_value %16 : $MyInt + debug_value %7 : $MyArray + debug_value %28 : $MyBool + strong_retain %25 : $Builtin.BridgeObject + %36 = apply %29(%16, %28, %7) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + debug_value %36 : $_MyDependenceToken + %37 = apply %31(%35, %16, %28, %36, %7) : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + strong_release %25 : $Builtin.BridgeObject + %44 = alloc_stack $MyInt + debug_value %7 : $MyArray + debug_value %28 : $MyBool + strong_retain %25 : $Builtin.BridgeObject + %45 = apply %29(%20, %28, %7) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + debug_value %45 : $_MyDependenceToken + %46 = apply %31(%44, %20, %28, %45, %7) : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + strong_release %25 : $Builtin.BridgeObject + %52 = tuple () + dealloc_stack %44 : $*MyInt + dealloc_stack %35 : $*MyInt + dealloc_stack %26 : $*MyInt + strong_release %25 : $Builtin.BridgeObject + return %52 : $() +} + +// CHECK-LABEL: sil @repeated_initialization +// CHECK: [[GFUN:%.*]] = function_ref @getElement +// CHECK: apply [[GFUN]] +// CHECK: apply [[GFUN]] +// CHECK: return + +sil @repeated_initialization : $@convention(thin) () -> () { + %0 = function_ref @swift_bufferAllocate : $@convention(thin) () -> @owned AnyObject + %1 = integer_literal $Builtin.Int64, 2 + %2 = struct $MyInt (%1 : $Builtin.Int64) + %3 = apply %0() : $@convention(thin) () -> @owned AnyObject + %4 = metatype $@thin MyArray.Type + %5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray.Type) -> @owned (MyArray, UnsafeMutablePointer) + %6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray.Type) -> @owned (MyArray, UnsafeMutablePointer) + %7 = tuple_extract %6 : $(MyArray, UnsafeMutablePointer), 0 + %8 = tuple_extract %6 : $(MyArray, UnsafeMutablePointer), 1 + %9 = struct_extract %8 : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue + %10 = pointer_to_address %9 : $Builtin.RawPointer to $*MyInt + %11 = integer_literal $Builtin.Int64, 0 + %12 = struct $MyInt (%11 : $Builtin.Int64) + store %12 to %10 : $*MyInt + %13 = integer_literal $Builtin.Word, 0 + %14 = index_addr %10 : $*MyInt, %13 : $Builtin.Word + %15 = integer_literal $Builtin.Int64, 1 + %16 = struct $MyInt (%15 : $Builtin.Int64) + store %16 to %14 : $*MyInt + %23 = struct_extract %7 : $MyArray, #MyArray._buffer + %24 = struct_extract %23 : $_MyArrayBuffer, #_MyArrayBuffer._storage + %25 = struct_extract %24 : $_MyBridgeStorage, #_MyBridgeStorage.rawValue + %26 = alloc_stack $MyInt + %27 = function_ref @hoistableIsNativeTypeChecked : $@convention(method) (@guaranteed MyArray) -> MyBool + %28 = apply %27(%7) : $@convention(method) (@guaranteed MyArray) -> MyBool + %29 = function_ref @checkSubscript : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + %30 = apply %29(%12, %28, %7) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + %31 = function_ref @getElement : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + %32 = apply %31(%26, %12, %28, %30, %7) : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + %35 = alloc_stack $MyInt + strong_retain %25 : $Builtin.BridgeObject + %36 = apply %29(%16, %28, %7) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + %37 = apply %31(%35, %16, %28, %36, %7) : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + strong_release %25 : $Builtin.BridgeObject + %52 = tuple () + dealloc_stack %35 : $*MyInt + dealloc_stack %26 : $*MyInt + strong_release %25 : $Builtin.BridgeObject + return %52 : $() +} + +// CHECK-LABEL: sil @unknown_use +// CHECK: [[GFUN:%.*]] = function_ref @getElement +// CHECK: apply [[GFUN]] +// CHECK: return + +sil @unknown_use : $@convention(thin) () -> () { + %0 = function_ref @swift_bufferAllocate : $@convention(thin) () -> @owned AnyObject + %1 = integer_literal $Builtin.Int64, 2 + %2 = struct $MyInt (%1 : $Builtin.Int64) + %3 = apply %0() : $@convention(thin) () -> @owned AnyObject + %4 = metatype $@thin MyArray.Type + %5 = function_ref @adoptStorage : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray.Type) -> @owned (MyArray, UnsafeMutablePointer) + %6 = apply %5(%3, %2, %4) : $@convention(thin) (@owned AnyObject, MyInt, @thin MyArray.Type) -> @owned (MyArray, UnsafeMutablePointer) + %7 = tuple_extract %6 : $(MyArray, UnsafeMutablePointer), 0 + %8 = tuple_extract %6 : $(MyArray, UnsafeMutablePointer), 1 + %9 = struct_extract %8 : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue + %10 = pointer_to_address %9 : $Builtin.RawPointer to $*MyInt + %11 = integer_literal $Builtin.Int64, 0 + %12 = struct $MyInt (%11 : $Builtin.Int64) + store %12 to %10 : $*MyInt + %23 = struct_extract %7 : $MyArray, #MyArray._buffer + %24 = struct_extract %23 : $_MyArrayBuffer, #_MyArrayBuffer._storage + %25 = struct_extract %24 : $_MyBridgeStorage, #_MyBridgeStorage.rawValue + %26 = alloc_stack $MyInt + %27 = function_ref @hoistableIsNativeTypeChecked : $@convention(method) (@guaranteed MyArray) -> MyBool + %28 = apply %27(%7) : $@convention(method) (@guaranteed MyArray) -> MyBool + %29 = function_ref @checkSubscript : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + %30 = apply %29(%12, %28, %7) : $@convention(method) (MyInt, MyBool, @guaranteed MyArray) -> _MyDependenceToken + %31 = function_ref @getElement : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + %32 = apply %31(%26, %12, %28, %30, %7) : $@convention(method) (@out MyInt, MyInt, MyBool, _MyDependenceToken, @guaranteed MyArray) -> () + %33 = function_ref @unknown_array_use : $@convention(method) (@guaranteed MyArray) -> MyBool + %34 = apply %33(%7) : $@convention(method) (@guaranteed MyArray) -> MyBool + %52 = tuple () + dealloc_stack %26 : $*MyInt + strong_release %25 : $Builtin.BridgeObject + return %52 : $() +} diff --git a/test/SILPasses/array_mutable_assertonly.swift b/test/SILOptimizer/array_mutable_assertonly.swift similarity index 100% rename from test/SILPasses/array_mutable_assertonly.swift rename to test/SILOptimizer/array_mutable_assertonly.swift diff --git a/test/SILPasses/array_specialize.sil b/test/SILOptimizer/array_specialize.sil similarity index 95% rename from test/SILPasses/array_specialize.sil rename to test/SILOptimizer/array_specialize.sil index 14dc5a54f2654..1e9af3e2717ea 100644 --- a/test/SILPasses/array_specialize.sil +++ b/test/SILOptimizer/array_specialize.sil @@ -74,7 +74,7 @@ bb4: return %4 : $MyBool } -sil public_external [_semantics "array.props.isNative"] @arrayPropertyIsNative : $@convention(method) (@owned MyArray) -> Bool { +sil public_external [_semantics "array.props.isNativeTypeChecked"] @arrayPropertyIsNative : $@convention(method) (@owned MyArray) -> Bool { bb0(%0: $MyArray): unreachable } diff --git a/test/SILPasses/assert_configuration.sil b/test/SILOptimizer/assert_configuration.sil similarity index 100% rename from test/SILPasses/assert_configuration.sil rename to test/SILOptimizer/assert_configuration.sil diff --git a/test/SILOptimizer/basic-aa.sil b/test/SILOptimizer/basic-aa.sil new file mode 100644 index 0000000000000..bc4569bf16b80 --- /dev/null +++ b/test/SILOptimizer/basic-aa.sil @@ -0,0 +1,510 @@ +// RUN: %target-sil-opt %s -aa=basic-aa -aa-dump -o /dev/null | FileCheck %s + +// REQUIRES: asserts + +import Builtin +import Swift + +// Address Arguments don't alias if they are arguments to the first BB. +// +// CHECK-LABEL: @address_args_dont_alias_in_first_bb +// CHECK: PAIR #0. +// CHECK-NEXT: %0 = argument of bb0 : $*Builtin.NativeObject +// CHECK-NEXT: %0 = argument of bb0 : $*Builtin.NativeObject +// CHECK-NEXT: MustAlias +// CHECK: PAIR #1. +// CHECK-NEXT: %0 = argument of bb0 +// CHECK-NEXT: %1 = argument of bb0 +// CHECK-NEXT: NoAlias +sil @address_args_dont_alias_in_first_bb : $@convention(thin) (@in Builtin.NativeObject, @in Builtin.NativeObject) -> () { +bb0(%0 : $*Builtin.NativeObject, %1 : $*Builtin.NativeObject): + %2 = tuple() + return %2 : $() +} + +// Address Arguments may alias if they are arguments to a BB besides the first. +// +// FIXME: Once we support looking through PHIs, we will allow for must alias here. +// +// CHECK-LABEL: @address_args_may_alias_in_non_first_bb +// CHECK-NOT: NoAlias +sil @address_args_may_alias_in_non_first_bb : $@convention(thin) (@inout Builtin.NativeObject) -> () { +bb0(%0 : $*Builtin.NativeObject): + br bb1(%0 : $*Builtin.NativeObject, %0 : $*Builtin.NativeObject) + +bb1(%1 : $*Builtin.NativeObject, %2 : $*Builtin.NativeObject): + %3 = tuple() + return %3 : $() +} + +// Assume that inout arguments alias to preserve memory safety. +// +// CHECK-LABEL: @inout_args_may_alias +// CHECK: PAIR #1. +// CHECK-NEXT: %0 = argument of bb0 +// CHECK-NEXT: %1 = argument of bb0 +// CHECK-NEXT: MayAlias +sil @inout_args_may_alias: $@convention(thin) (@inout Builtin.NativeObject, @inout Builtin.NativeObject) -> () { +bb0(%0 : $*Builtin.NativeObject, %1 : $*Builtin.NativeObject): + %2 = tuple() + return %2 : $() +} + +struct StructLvl2 { + var tup : (Builtin.Int64, Builtin.Int32) +} + +struct StructLvl1 { + var sub : StructLvl2 + var x : Builtin.Int64 +} + +// Two values with different underlying alloc_stack cannot alias. +// +// CHECK-LABEL: @different_alloc_stack_dont_alias + +// cannot alias non types. +// CHECK: PAIR #0. +// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 +// CHECK-NEXT: MustAlias +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %1 = alloc_stack $StructLvl1 +// CHECK-NEXT: NoAlias +// CHECK: PAIR #2. +// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %2 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.sub +// CHECK-NEXT: PartialAlias +// CHECK: PAIR #3. +// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %3 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.x +// CHECK-NEXT: PartialAlias +// CHECK: PAIR #4. +// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %4 = struct_element_addr %2 : $*StructLvl2, #StructLvl2.tup +// CHECK-NEXT: PartialAlias + +// CHECK: PAIR #12. +// CHECK-NEXT: (0): %0 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %14 = tuple () +// CHECK-NEXT: MayAlias + +// CHECK: PAIR #21. +// CHECK-NEXT: (0): %1 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %9 = struct_element_addr %7 : $*StructLvl2, #StructLvl2.tup +// CHECK-NEXT: PartialAlias +// CHECK: PAIR #22. +// CHECK-NEXT: (0): %1 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %10 = tuple_element_addr %9 : $*(Builtin.Int64, Builtin.Int32), 0 +// CHECK-NEXT: PartialAlias +// CHECK: PAIR #23. +// CHECK-NEXT: (0): %1 = alloc_stack $StructLvl1 +// CHECK-NEXT: (0): %11 = tuple_element_addr %9 : $*(Builtin.Int64, Builtin.Int32), 1 +// CHECK-NEXT: PartialAlias +// CHECK: PAIR #26. +// CHECK-NEXT: (0): %2 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.sub +// CHECK-NEXT: (0): %3 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.x +// CHECK-NEXT: NoAlias +// CHECK: PAIR #27. +// CHECK-NEXT: (0): %2 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.sub +// CHECK-NEXT: (0): %4 = struct_element_addr %2 : $*StructLvl2, #StructLvl2.tup +// CHECK-NEXT: PartialAlias +// CHECK: PAIR #28. +// CHECK-NEXT: (0): %2 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.sub +// CHECK-NEXT: (0): %5 = tuple_element_addr %4 : $*(Builtin.Int64, Builtin.Int32), 0 +// CHECK-NEXT: PartialAlias +// CHECK: PAIR #29. +// CHECK-NEXT: (0): %2 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.sub +// CHECK-NEXT: (0): %6 = tuple_element_addr %4 : $*(Builtin.Int64, Builtin.Int32), 1 +// CHECK-NEXT: PartialAlias +sil @different_alloc_stack_dont_alias : $@convention(thin) () -> () { + %0 = alloc_stack $StructLvl1 + %1 = alloc_stack $StructLvl1 + + %2 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.sub + %3 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.x + %4 = struct_element_addr %2 : $*StructLvl2, #StructLvl2.tup + %5 = tuple_element_addr %4 : $*(Builtin.Int64, Builtin.Int32), 0 + %6 = tuple_element_addr %4 : $*(Builtin.Int64, Builtin.Int32), 1 + + %7 = struct_element_addr %1 : $*StructLvl1, #StructLvl1.sub + %8 = struct_element_addr %1 : $*StructLvl1, #StructLvl1.x + %9 = struct_element_addr %7 : $*StructLvl2, #StructLvl2.tup + %10 = tuple_element_addr %9 : $*(Builtin.Int64, Builtin.Int32), 0 + %11 = tuple_element_addr %9 : $*(Builtin.Int64, Builtin.Int32), 1 + + dealloc_stack %1 : $*StructLvl1 + dealloc_stack %0 : $*StructLvl1 + + %12 = tuple() + return %12 : $() +} + +// Function Arguments cannot alias with no alias arguments or with identified +// function locals. +// +// CHECK-LABEL: @args_dont_alias_with_identified_function_locals +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: MayAlias +// CHECK: PAIR #2. +// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %2 = argument of bb0 : $*Builtin.NativeObject +// CHECK-NEXT: NoAlias +// CHECK: PAIR #3. +// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK-NEXT: NoAlias +// CHECK: PAIR #4. +// CHECK-NEXT: (0): %0 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %5 = tuple () +// CHECK-NEXT: MayAlias +// CHECK: PAIR #6. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %2 = argument of bb0 : $*Builtin.NativeObject +// CHECK-NEXT: NoAlias +// CHECK: PAIR #7. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK-NEXT: NoAlias +// CHECK: PAIR #10. +// CHECK-NEXT: (0): %2 = argument of bb0 : $*Builtin.NativeObject +// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK-NEXT: NoAlias +sil @args_dont_alias_with_identified_function_locals : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject, @in Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject, %2 : $*Builtin.NativeObject): + %3 = alloc_stack $Builtin.NativeObject + dealloc_stack %3 : $*Builtin.NativeObject + %4 = tuple() + return %4 : $() +} + +sil @create_native_object : $@convention(thin) () -> (Builtin.NativeObject) +sil @use_native_object : $@convention(thin) (Builtin.NativeObject) -> () + +// For this test, we care about the following results: +// %1, %3, %5, %7, %8, %9 +// Check every alias query involving those. + +// CHECK-LABEL: @escapesource_functionlocal_test_escapesource_nonescapinglocal +// Test %0 + +// CHECK: PAIR #1. +// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject +// CHECK: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK: NoAlias +// CHECK: PAIR #2. +// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject +// CHECK: (0): %2 = alloc_stack $Builtin.NativeObject +// CHECK: NoAlias +// CHECK: PAIR #3. +// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject +// CHECK: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK: NoAlias +// CHECK: PAIR #5. +// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject +// CHECK: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK: NoAlias +// CHECK: PAIR #8. +// CHECK: (0): %0 = argument of bb0 : $*Builtin.NativeObject +// CHECK: (0): %8 = load %3 : $*Builtin.NativeObject +// CHECK: NoAlias + +// Test %1 (the aliasing argument) + +// CHECK: PAIR #11. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: MustAlias +// CHECK: PAIR #12. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %2 = alloc_stack $Builtin.NativeObject +// CHECK-NEXT: NoAlias +// CHECK: PAIR #13. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK-NEXT: NoAlias +// CHECK: PAIR #15. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK-NEXT: MayAlias +// CHECK: PAIR #16. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %6 = load %0 : $*Builtin.NativeObject +// CHECK-NEXT: MayAlias +// CHECK: PAIR #18. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %8 = load %3 : $*Builtin.NativeObject +// CHECK-NEXT: MayAlias +// CHECK: PAIR #19. +// CHECK-NEXT: (0): %1 = argument of bb0 : $Builtin.NativeObject +// CHECK-NEXT: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () +// CHECK-NEXT: MayAlias + +// Test %2 +// CHECK: PAIR #22. +// CHECK: (0): %2 = alloc_stack $Builtin.NativeObject +// CHECK: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK: NoAlias +// CHECK: PAIR #24. +// CHECK: (0): %2 = alloc_stack $Builtin.NativeObject +// CHECK: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK: NoAlias +// CHECK: PAIR #25. +// CHECK: (0): %2 = alloc_stack $Builtin.NativeObject +// CHECK: (0): %6 = load %0 : $*Builtin.NativeObject +// CHECK: NoAlias +// CHECK: PAIR #27. +// CHECK: (0): %2 = alloc_stack $Builtin.NativeObject +// CHECK: (0): %8 = load %3 : $*Builtin.NativeObject +// CHECK: NoAlias +// CHECK: PAIR #28. +// CHECK: (0): %2 = alloc_stack $Builtin.NativeObject +// CHECK: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () +// CHECK: NoAlias + +// Test %3 (the escaping alloca). + +// CHECK: PAIR #32. +// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK-NEXT: NoAlias +// CHECK: PAIR #33. +// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK-NEXT: (0): %6 = load %0 : $*Builtin.NativeObject +// CHECK-NEXT: NoAlias +// CHECK: PAIR #35. +// CHECK-NEXT: (0): %3 = alloc_stack $Builtin.NativeObject +// CHECK-NEXT: (0): %8 = load %3 : $*Builtin.NativeObject +// CHECK-NEXT: NoAlias + +// Test %5 (the read write apply inst). + +// CHECK: PAIR #45. +// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK-NEXT: MustAlias +// CHECK: PAIR #46. +// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK-NEXT: (0): %6 = load %0 : $*Builtin.NativeObject +// CHECK-NEXT: MayAlias +// CHECK: PAIR #47. +// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK-NEXT: function_ref use_native_object +// CHECK-NEXT: %7 = function_ref @use_native_object : $@convention(thin) (Builtin.NativeObject) -> () +// CHECK-NEXT: MayAlias +// CHECK: PAIR #48. +// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK-NEXT: (0): %8 = load %3 : $*Builtin.NativeObject +// CHECK-NEXT: MayAlias +// CHECK: PAIR #49. +// CHECK-NEXT: (0): %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject +// CHECK-NEXT: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () +// CHECK-NEXT: MayAlias + +// Test %8 (the escaping load) + +// CHECK: PAIR #60. +// CHECK-NEXT: (0): %8 = load %3 : $*Builtin.NativeObject +// CHECK-NEXT: (0): %8 = load %3 : $*Builtin.NativeObject +// CHECK-NEXT: MustAlias +// CHECK: PAIR #61. +// CHECK-NEXT: (0): %8 = load %3 : $*Builtin.NativeObject +// CHECK-NEXT: (0): %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () +// CHECK-NEXT: MayAlias +sil @escapesource_functionlocal_test_escapesource_nonescapinglocal : $@convention(thin) (@in Builtin.NativeObject, Builtin.NativeObject) -> () { +bb0(%0 : $*Builtin.NativeObject, %1 : $Builtin.NativeObject): + %2 = alloc_stack $Builtin.NativeObject + %3 = alloc_stack $Builtin.NativeObject + %4 = function_ref @create_native_object : $@convention(thin) () -> Builtin.NativeObject + %5 = apply %4() : $@convention(thin) () -> Builtin.NativeObject + %6 = load %0 : $*Builtin.NativeObject + %7 = function_ref @use_native_object : $@convention(thin) (Builtin.NativeObject) -> () + %8 = load %3 : $*Builtin.NativeObject + %9 = apply %7(%8) : $@convention(thin) (Builtin.NativeObject) -> () + dealloc_stack %3 : $*Builtin.NativeObject + dealloc_stack %2 : $*Builtin.NativeObject + %12 = tuple () + return %12 : $() +} + +// CHECK-LABEL: @projections_from_the_same_source_with_the_same_projection_path_mustalias +// CHECK: PAIR #24. +// CHECK-NEXT: (0): %3 = tuple_element_addr %2 : $*(Builtin.Int64, Builtin.Int32), 1 +// CHECK-NEXT: (0): %6 = tuple_element_addr %5 : $*(Builtin.Int64, Builtin.Int32), 1 +// CHECK-NEXT: MustAlias +sil @projections_from_the_same_source_with_the_same_projection_path_mustalias : $@convention(thin) () -> () { + %0 = alloc_stack $StructLvl1 + %1 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.sub + %2 = struct_element_addr %1 : $*StructLvl2, #StructLvl2.tup + %3 = tuple_element_addr %2 : $*(Builtin.Int64, Builtin.Int32), 1 + %4 = struct_element_addr %0 : $*StructLvl1, #StructLvl1.sub + %5 = struct_element_addr %4 : $*StructLvl2, #StructLvl2.tup + %6 = tuple_element_addr %5 : $*(Builtin.Int64, Builtin.Int32), 1 + dealloc_stack %0 : $*StructLvl1 + %7 = tuple() + return %7 : $() +} + +sil_global public @sil_global1 : $Builtin.Int32 +sil_global public @sil_global2 : $Builtin.Int32 + +class X { } + +// CHECK-LABEL: @globals_dont_alias +// CHECK: PAIR #0. +// CHECK-NEXT: (0): %0 = global_addr @sil_global1 : $*Builtin.Int32 +// CHECK-NEXT: (0): %0 = global_addr @sil_global1 : $*Builtin.Int32 +// CHECK-NEXT: MustAlias +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %0 = global_addr @sil_global1 : $*Builtin.Int32 +// CHECK-NEXT: (0): %1 = global_addr @sil_global2 : $*Builtin.Int32 +// CHECK-NEXT: NoAlias +sil @globals_dont_alias : $@convention(thin) () -> () { + %0 = global_addr @sil_global1 : $*Builtin.Int32 + %1 = global_addr @sil_global2 : $*Builtin.Int32 + %4 = tuple() + return %4 : $() +} + +// CHECK-LABEL: @globals_and_allocs_dont_alias +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %0 = global_addr @sil_global1 : $*Builtin.Int32 +// CHECK-NEXT: (0): %1 = alloc_ref $X +// CHECK-NEXT: NoAlias +sil @globals_and_allocs_dont_alias : $@convention(thin) () -> () { + %0 = global_addr @sil_global1 : $*Builtin.Int32 + %1 = alloc_ref $X + %4 = tuple() + return %4 : $() +} + + +sil_global @sil_global3 : $Int32 + +// CHECK-LABEL: @globals_alias +// CHECK: PAIR #0. +// CHECK-NEXT: (0): %0 = global_addr @sil_global3 : $*Int32 +// CHECK-NEXT: (0): %0 = global_addr @sil_global3 : $*Int32 +// CHECK-NEXT: MustAlias +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %0 = global_addr @sil_global3 : $*Int32 +// CHECK-NEXT: (0): %1 = global_addr @sil_global3 : $*Int32 +// CHECK-NEXT: MustAlias +// CHECK: PAIR #2. +// CHECK-NEXT: (0): %0 = global_addr @sil_global3 : $*Int32 +// CHECK-NEXT: (0): %2 = struct_element_addr %1 : $*Int32, #Int32._value +// CHECK-NEXT: PartialAlias +sil @globals_alias : $@convention(thin) () -> () { + %0 = global_addr @sil_global3 : $*Int32 + %1 = global_addr @sil_global3 : $*Int32 + %2 = struct_element_addr %1 : $*Int32, #Int32._value + %4 = tuple() + return %4 : $() +} + +class HalfOpenRange { + final var current: Int32 + final let end: Int32 + init(start: Int32, end: Int32) +} +// CHECK-LABEL: @different_fields +// CHECK: PAIR #51. +// CHECK-NEXT: (0): %5 = ref_element_addr %4 : $HalfOpenRange, #HalfOpenRange.current +// CHECK-NEXT: (0): %7 = ref_element_addr %4 : $HalfOpenRange, #HalfOpenRange.end +// CHECK-NEXT: NoAlias +// CHECK: PAIR #64. +// CHECK-NEXT: (0): %9 = struct_element_addr %5 : $*Int32, #Int32._value +// CHECK-NEXT: (0): %10 = struct_element_addr %7 : $*Int32, #Int32._value +// CHECK-NEXT: NoAlias +sil @different_fields : $@convention(thin) () -> () { + %0 = integer_literal $Builtin.Int32, 0 + %1 = struct $Int32 (%0 : $Builtin.Int32) + %2 = integer_literal $Builtin.Int32, 10 + %3 = struct $Int32 (%2 : $Builtin.Int32) + %4 = alloc_ref $HalfOpenRange + %5 = ref_element_addr %4 : $HalfOpenRange, #HalfOpenRange.current + store %1 to %5 : $*Int32 + %7 = ref_element_addr %4 : $HalfOpenRange, #HalfOpenRange.end + store %3 to %7 : $*Int32 + %9 = struct_element_addr %5 : $*Int32, #Int32._value + %10 = struct_element_addr %7 : $*Int32, #Int32._value + %11 = load %9 : $*Builtin.Int32 + %12 = load %10 : $*Builtin.Int32 + %13 = tuple() + return %13 : $() +} + +public final class C { + @sil_stored final var a: Int { get set } + @sil_stored final var b: Int { get set } + deinit + init() +} + +// CHECK-LABEL: @ref_element_addr_and_object_itself +// CHECK: PAIR #0. +// CHECK-NEXT: (0): %0 = alloc_ref $C // user: %1 +// CHECK-NEXT: (0): %0 = alloc_ref $C // user: %1 +// CHECK-NEXT: MustAlias +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %0 = alloc_ref $C // user: %1 +// CHECK-NEXT: (0): %1 = ref_element_addr %0 : $C, #C.a +// CHECK-NEXT: PartialAlias +sil @ref_element_addr_and_object_itself : $@convention(thin) () -> () { +bb0: + %0 = alloc_ref $C + %1 = ref_element_addr %0 : $C, #C.a + %2 = tuple() + return %2 : $() +} + +// CHECK-LABEL: @different_fields_of_different_refs +// CHECK: PAIR #13. +// CHECK-NEXT: (0): %3 = ref_element_addr %0 : $C, #C.a +// CHECK-NEXT: (0): %4 = ref_element_addr %1 : $C, #C.b +// CHECK-NEXT: NoAlias +sil @different_fields_of_different_refs : $@convention(thin) (@owned C, @owned C, Int) -> Int { +bb0(%0 : $C, %1 : $C, %2 : $Int): + %6 = ref_element_addr %0 : $C, #C.a + %8 = ref_element_addr %1 : $C, #C.b + return %2 : $Int +} + +// CHECK-LABEL: @non_escaping_local_object_does_not_alias_with_unknown +// CHECK: PAIR #7. +// CHECK-NEXT: (0): %1 = alloc_ref $X // user: %3 +// CHECK-NEXT: (0): %3 = apply %2(%1) : $@convention(thin) (X) -> X +// CHECK-NEXT: NoAlias +sil @non_escaping_local_object_does_not_alias_with_unknown : $@convention(thin) (X) -> () { +bb0(%0 : $X): + %1 = alloc_ref $X + + %f = function_ref @not_escaping : $@convention(thin) (X) -> X + %2 = apply %f(%1) : $@convention(thin) (X) -> X + + %12 = tuple() + return %12 : $() +} + +sil @not_escaping: $@convention(thin) (X) -> X { +bb0(%0 : $X): + %1 = alloc_ref $X + return %1 : $X +} + +// CHECK-LABEL: @alloc_stack_and_addr_cast +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %0 = alloc_stack $C // users: %1, %2 +// CHECK-NEXT: (0): %1 = unchecked_addr_cast %0 : $*C to $*Optional +// CHECK-NEXT: MayAlias +sil @alloc_stack_and_addr_cast : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $C + %1 = unchecked_addr_cast %0 : $*C to $*Optional + dealloc_stack %0 : $*C + %2 = tuple() + return %2 : $() +} diff --git a/test/SILAnalysis/basic-callee-printer.sil b/test/SILOptimizer/basic-callee-printer.sil similarity index 90% rename from test/SILAnalysis/basic-callee-printer.sil rename to test/SILOptimizer/basic-callee-printer.sil index e7b3f3c430c5a..f7fcf34ff21f3 100644 --- a/test/SILAnalysis/basic-callee-printer.sil +++ b/test/SILOptimizer/basic-callee-printer.sil @@ -171,7 +171,7 @@ bb0(%0 : $private_derived): // CHECK: Function call site: -// CHECK: %2 = class_method %0 : $private_base, #private_base.foo!1 : private_base -> () -> () , $@convention(method) (@guaranteed private_base) -> () // user: %3 +// CHECK: %2 = class_method %0 : $private_base, #private_base.foo!1 : (private_base) -> () -> () , $@convention(method) (@guaranteed private_base) -> () // user: %3 // CHECK: %3 = apply %2(%0) : $@convention(method) (@guaranteed private_base) -> () // CHECK: Incomplete callee list? : No // CHECK: Known callees: @@ -221,7 +221,7 @@ bb0(%0 : $internal_derived): // CHECK: Function call site: -// CHECK: %4 = class_method %0 : $internal_base, #internal_base.bar!1 : internal_base -> () -> () , $@convention(method) (@guaranteed internal_base) -> () // user: %5 +// CHECK: %4 = class_method %0 : $internal_base, #internal_base.bar!1 : (internal_base) -> () -> () , $@convention(method) (@guaranteed internal_base) -> () // user: %5 // CHECK: %5 = apply %4(%0) : $@convention(method) (@guaranteed internal_base) -> () // CHECK-NOWMO: Incomplete callee list? : Yes // CHECK-WMO: Incomplete callee list? : No @@ -290,7 +290,7 @@ bb0(%0 : $public_derived): // CHECK: Function call site: -// CHECK: %2 = class_method %0 : $public_base, #public_base.foo!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () // user: %3 +// CHECK: %2 = class_method %0 : $public_base, #public_base.foo!1 : (public_base) -> () -> () , $@convention(method) (@guaranteed public_base) -> () // user: %3 // CHECK: %3 = apply %2(%0) : $@convention(method) (@guaranteed public_base) -> () // CHECK-NOWMO: Incomplete callee list? : Yes // CHECK-WMO: Incomplete callee list? : No @@ -299,7 +299,7 @@ bb0(%0 : $public_derived): // CHECK: public_derived_foo // // CHECK: Function call site: -// CHECK: %4 = class_method %0 : $public_base, #public_base.bar!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () // user: %5 +// CHECK: %4 = class_method %0 : $public_base, #public_base.bar!1 : (public_base) -> () -> () , $@convention(method) (@guaranteed public_base) -> () // user: %5 // CHECK: %5 = apply %4(%0) : $@convention(method) (@guaranteed public_base) -> () // CHECK: Incomplete callee list? : Yes // CHECK: Known callees: @@ -307,7 +307,7 @@ bb0(%0 : $public_derived): // CHECK: public_derived_bar // // CHECK: Function call site: -// CHECK: %6 = class_method %0 : $public_base, #public_base.baz!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () // user: %7 +// CHECK: %6 = class_method %0 : $public_base, #public_base.baz!1 : (public_base) -> () -> () , $@convention(method) (@guaranteed public_base) -> () // user: %7 // CHECK: %7 = apply %6(%0) : $@convention(method) (@guaranteed public_base) -> () // CHECK: Incomplete callee list? : Yes // CHECK: Known callees: @@ -316,11 +316,11 @@ bb0(%0 : $public_derived): sil hidden [noinline] @call_public : $@convention(thin) (@owned public_base) -> () { bb0(%0 : $public_base): debug_value %0 : $public_base - %2 = class_method %0 : $public_base, #public_base.foo!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () + %2 = class_method %0 : $public_base, #public_base.foo!1 : (public_base) -> () -> () , $@convention(method) (@guaranteed public_base) -> () %3 = apply %2(%0) : $@convention(method) (@guaranteed public_base) -> () - %4 = class_method %0 : $public_base, #public_base.bar!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () + %4 = class_method %0 : $public_base, #public_base.bar!1 : (public_base) -> () -> () , $@convention(method) (@guaranteed public_base) -> () %5 = apply %4(%0) : $@convention(method) (@guaranteed public_base) -> () - %6 = class_method %0 : $public_base, #public_base.baz!1 : public_base -> () -> () , $@convention(method) (@guaranteed public_base) -> () + %6 = class_method %0 : $public_base, #public_base.baz!1 : (public_base) -> () -> () , $@convention(method) (@guaranteed public_base) -> () %7 = apply %6(%0) : $@convention(method) (@guaranteed public_base) -> () strong_release %0 : $public_base %9 = tuple () @@ -406,7 +406,7 @@ bb0(%0 : $private_proto_private_class): // CHECK: Function call site: -// CHECK: %3 = class_method %1 : $private_proto_private_class, #private_proto_private_class.theMethod!1 : private_proto_private_class -> () -> () , $@convention(method) (@guaranteed private_proto_private_class) -> () // user: %4 +// CHECK: %3 = class_method %1 : $private_proto_private_class, #private_proto_private_class.theMethod!1 : (private_proto_private_class) -> () -> () , $@convention(method) (@guaranteed private_proto_private_class) -> () // user: %4 // CHECK: %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_private_class) -> () // user: %6 // CHECK: Incomplete callee list? : No // CHECK: Known callees: @@ -415,7 +415,7 @@ sil private [transparent] [thunk] @private_proto_1_private_class_witness : $@con bb0(%0 : $*private_proto_private_class): %1 = load %0 : $*private_proto_private_class strong_retain %1 : $private_proto_private_class - %3 = class_method %1 : $private_proto_private_class, #private_proto_private_class.theMethod!1 : private_proto_private_class -> () -> () , $@convention(method) (@guaranteed private_proto_private_class) -> () + %3 = class_method %1 : $private_proto_private_class, #private_proto_private_class.theMethod!1 : (private_proto_private_class) -> () -> () , $@convention(method) (@guaranteed private_proto_private_class) -> () %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_private_class) -> () strong_release %1 : $private_proto_private_class return %4 : $() @@ -448,7 +448,7 @@ bb0(%0 : $private_proto_internal_class): // CHECK: Function call site: -// CHECK: %3 = class_method %1 : $private_proto_internal_class, #private_proto_internal_class.theMethod!1 : private_proto_internal_class -> () -> () , $@convention(method) (@guaranteed private_proto_internal_class) -> () // user: %4 +// CHECK: %3 = class_method %1 : $private_proto_internal_class, #private_proto_internal_class.theMethod!1 : (private_proto_internal_class) -> () -> () , $@convention(method) (@guaranteed private_proto_internal_class) -> () // user: %4 // CHECK: %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_internal_class) -> () // user: %6 // CHECK-NOWMO: Incomplete callee list? : Yes // CHECK-WMO: Incomplete callee list? : No @@ -458,7 +458,7 @@ sil private [transparent] [thunk] @private_proto_2_internal_class_witness : $@co bb0(%0 : $*private_proto_internal_class): %1 = load %0 : $*private_proto_internal_class strong_retain %1 : $private_proto_internal_class - %3 = class_method %1 : $private_proto_internal_class, #private_proto_internal_class.theMethod!1 : private_proto_internal_class -> () -> () , $@convention(method) (@guaranteed private_proto_internal_class) -> () + %3 = class_method %1 : $private_proto_internal_class, #private_proto_internal_class.theMethod!1 : (private_proto_internal_class) -> () -> () , $@convention(method) (@guaranteed private_proto_internal_class) -> () %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_internal_class) -> () strong_release %1 : $private_proto_internal_class return %4 : $() @@ -491,7 +491,7 @@ bb0(%0 : $private_proto_public_class): // CHECK: Function call site: -// CHECK: %3 = class_method %1 : $private_proto_public_class, #private_proto_public_class.theMethod!1 : private_proto_public_class -> () -> () , $@convention(method) (@guaranteed private_proto_public_class) -> () // user: %4 +// CHECK: %3 = class_method %1 : $private_proto_public_class, #private_proto_public_class.theMethod!1 : (private_proto_public_class) -> () -> () , $@convention(method) (@guaranteed private_proto_public_class) -> () // user: %4 // CHECK: %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_public_class) -> () // user: %6 // CHECK: Incomplete callee list? : Yes // CHECK: Known callees: @@ -500,7 +500,7 @@ sil private [transparent] [thunk] @private_proto_3_public_class_witness : $@conv bb0(%0 : $*private_proto_public_class): %1 = load %0 : $*private_proto_public_class strong_retain %1 : $private_proto_public_class - %3 = class_method %1 : $private_proto_public_class, #private_proto_public_class.theMethod!1 : private_proto_public_class -> () -> () , $@convention(method) (@guaranteed private_proto_public_class) -> () + %3 = class_method %1 : $private_proto_public_class, #private_proto_public_class.theMethod!1 : (private_proto_public_class) -> () -> () , $@convention(method) (@guaranteed private_proto_public_class) -> () %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_public_class) -> () strong_release %1 : $private_proto_public_class return %4 : $() @@ -533,7 +533,7 @@ bb0(%0 : $private_proto_public_class_private_method): // CHECK: Function call site: -// CHECK: %3 = class_method %1 : $private_proto_public_class_private_method, #private_proto_public_class_private_method.theMethod!1 : private_proto_public_class_private_method -> () -> () , $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () // user: %4 +// CHECK: %3 = class_method %1 : $private_proto_public_class_private_method, #private_proto_public_class_private_method.theMethod!1 : (private_proto_public_class_private_method) -> () -> () , $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () // user: %4 // CHECK: %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () // user: %6 // CHECK: Incomplete callee list? : No // CHECK: Known callees: @@ -542,7 +542,7 @@ sil private [transparent] [thunk] @private_proto_4_public_class_private_method_w bb0(%0 : $*private_proto_public_class_private_method): %1 = load %0 : $*private_proto_public_class_private_method strong_retain %1 : $private_proto_public_class_private_method - %3 = class_method %1 : $private_proto_public_class_private_method, #private_proto_public_class_private_method.theMethod!1 : private_proto_public_class_private_method -> () -> () , $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () + %3 = class_method %1 : $private_proto_public_class_private_method, #private_proto_public_class_private_method.theMethod!1 : (private_proto_public_class_private_method) -> () -> () , $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () %4 = apply %3(%1) : $@convention(method) (@guaranteed private_proto_public_class_private_method) -> () strong_release %1 : $private_proto_public_class_private_method return %4 : $() diff --git a/test/SILPasses/bridged_casts_folding.swift b/test/SILOptimizer/bridged_casts_folding.swift similarity index 99% rename from test/SILPasses/bridged_casts_folding.swift rename to test/SILOptimizer/bridged_casts_folding.swift index a0412d41e819e..94c8f926400f4 100644 --- a/test/SILPasses/bridged_casts_folding.swift +++ b/test/SILOptimizer/bridged_casts_folding.swift @@ -761,7 +761,7 @@ print(testCondCastSwiftToNSDictDouble()) print(testForcedCastSwiftToNSDictString()) print(testCondCastSwiftToNSDictString()) -print("Swift to NS dictionariess: End") +print("Swift to NS dictionaries: End") // Sets print("Swift to NS sets: Start") diff --git a/test/SILPasses/bridging_checked_cast.sil b/test/SILOptimizer/bridging_checked_cast.sil similarity index 80% rename from test/SILPasses/bridging_checked_cast.sil rename to test/SILOptimizer/bridging_checked_cast.sil index e040f10e388bb..bc8cdaff570cd 100644 --- a/test/SILPasses/bridging_checked_cast.sil +++ b/test/SILOptimizer/bridging_checked_cast.sil @@ -21,7 +21,7 @@ entry: %b = alloc_stack $NSCloud %c = alloc_stack $Butt - checked_cast_addr_br take_always NSCloud in %b#1 : $*NSCloud to Butt in %c#1 : $*Butt, bb1, bb2 + checked_cast_addr_br take_always NSCloud in %b : $*NSCloud to Butt in %c : $*Butt, bb1, bb2 bb1: br bb3 @@ -30,8 +30,8 @@ bb2: br bb3 bb3: - dealloc_stack %c#0 : $*@local_storage Butt - dealloc_stack %b#0 : $*@local_storage NSCloud + dealloc_stack %c : $*Butt + dealloc_stack %b : $*NSCloud return undef : $() } @@ -40,7 +40,7 @@ entry: %b = alloc_stack $NSCloud %c = alloc_stack $Butt - checked_cast_addr_br take_always Butt in %c#1 : $*Butt to NSCloud in %b#1 : $*NSCloud, bb1, bb2 + checked_cast_addr_br take_always Butt in %c : $*Butt to NSCloud in %b : $*NSCloud, bb1, bb2 bb1: br bb3 @@ -49,8 +49,8 @@ bb2: br bb3 bb3: - dealloc_stack %c#0 : $*@local_storage Butt - dealloc_stack %b#0 : $*@local_storage NSCloud + dealloc_stack %c : $*Butt + dealloc_stack %b : $*NSCloud return undef : $() } diff --git a/test/SILPasses/canonicalize_switch_enum.sil b/test/SILOptimizer/canonicalize_switch_enum.sil similarity index 85% rename from test/SILPasses/canonicalize_switch_enum.sil rename to test/SILOptimizer/canonicalize_switch_enum.sil index 6da20a36ec1fb..8b1de4ebd21aa 100644 --- a/test/SILPasses/canonicalize_switch_enum.sil +++ b/test/SILOptimizer/canonicalize_switch_enum.sil @@ -47,9 +47,9 @@ bb4(%8 : $Builtin.Int32): sil @test_switch_enum_addr : $@convention(thin) (@in GenE) -> Int32 { bb0(%0 : $*GenE): %1 = alloc_stack $GenE - copy_addr %0 to [initialization] %1#1 : $*GenE - // CHECK: switch_enum_addr %1#1 : $*GenE, case #GenE.A!enumelt: bb1, case #GenE.B!enumelt: bb2, case #GenE.C!enumelt.1: bb3 - switch_enum_addr %1#1 : $*GenE, case #GenE.A!enumelt: bb1, case #GenE.B!enumelt: bb2, default bb3 + copy_addr %0 to [initialization] %1 : $*GenE + // CHECK: switch_enum_addr %1 : $*GenE, case #GenE.A!enumelt: bb1, case #GenE.B!enumelt: bb2, case #GenE.C!enumelt.1: bb3 + switch_enum_addr %1 : $*GenE, case #GenE.A!enumelt: bb1, case #GenE.B!enumelt: bb2, default bb3 bb1: %4 = integer_literal $Builtin.Int32, 10 @@ -60,13 +60,13 @@ bb2: br bb4(%6 : $Builtin.Int32) bb3: - destroy_addr %1#1 : $*GenE + destroy_addr %1 : $*GenE %9 = integer_literal $Builtin.Int32, 30 br bb4(%9 : $Builtin.Int32) bb4(%11 : $Builtin.Int32): %12 = struct $Int32 (%11 : $Builtin.Int32) - dealloc_stack %1#0 : $*@local_storage GenE + dealloc_stack %1 : $*GenE destroy_addr %0 : $*GenE return %12 : $Int32 } diff --git a/test/SILPasses/capture_promotion.sil b/test/SILOptimizer/capture_promotion.sil similarity index 80% rename from test/SILPasses/capture_promotion.sil rename to test/SILOptimizer/capture_promotion.sil index e0e0d9a3b5c8e..56fdc381d6586 100644 --- a/test/SILPasses/capture_promotion.sil +++ b/test/SILOptimizer/capture_promotion.sil @@ -49,7 +49,7 @@ bb0: store %15 to %11#1 : $*Int // CHECK-NOT: function_ref @closure0 : -// CHECK: [[CLOSURE_PROMOTE:%.*]] = function_ref @_TTSf2d_i_d_i_d_i__closure0 +// CHECK: [[CLOSURE_PROMOTE:%.*]] = function_ref @_TTSf2i_i_i__closure0 // CHECK-NOT: function_ref @closure0 : // The three strong retains are removed @@ -70,11 +70,11 @@ bb0: // previously used to capture and pass the variable by reference // CHECK-NEXT: {{.*}} = partial_apply [[CLOSURE_PROMOTE]]([[LOADFOO]], [[LOADBAZ]], [[LOADINT]]) - %17 = function_ref @closure0 : $@convention(thin) (@owned @box Foo, @inout Foo, @owned @box Baz, @inout Baz, @owned @box Int, @inout Int) -> Int + %17 = function_ref @closure0 : $@convention(thin) (@owned @box Foo, @owned @box Baz, @owned @box Int) -> Int strong_retain %1#0 : $@box Foo strong_retain %6#0 : $@box Baz strong_retain %11#0 : $@box Int - %21 = partial_apply %17(%1#0, %1#1, %6#0, %6#1, %11#0, %11#1) : $@convention(thin) (@owned @box Foo, @inout Foo, @owned @box Baz, @inout Baz, @owned @box Int, @inout Int) -> Int + %21 = partial_apply %17(%1#0, %6#0, %11#0) : $@convention(thin) (@owned @box Foo, @owned @box Baz, @owned @box Int) -> Int strong_release %11#0 : $@box Int strong_release %6#0 : $@box Baz @@ -82,12 +82,12 @@ bb0: return %21 : $@callee_owned () -> Int } -// CHECK-LABEL: sil private @_TTSf2d_i_d_i_d_i__closure0 : $@convention(thin) (@owned Foo, @owned Baz, Int) -> Int +// CHECK-LABEL: sil private @_TTSf2i_i_i__closure0 : $@convention(thin) (@owned Foo, @owned Baz, Int) -> Int // CHECK: [[DUMMY_FUNC:%.*]] = function_ref @dummy_func : $@convention(thin) (Int, Int, Int) -> Int // The load of %1 is removed, and its uses replaced with the Foo argument // CHECK-NEXT: strong_retain {{.*}} : $Foo -// CHECK-NEXT: [[METHOD_FOO:%.*]] = class_method {{.*}} : $Foo, #Foo.foo!1 : Foo -> () -> Int , $@convention(method) (@guaranteed Foo) -> Int +// CHECK-NEXT: [[METHOD_FOO:%.*]] = class_method {{.*}} : $Foo, #Foo.foo!1 : (Foo) -> () -> Int , $@convention(method) (@guaranteed Foo) -> Int // CHECK-NEXT: [[APPLY_FOO:%.*]] = apply [[METHOD_FOO]]({{.*}}) : $@convention(method) (@guaranteed Foo) -> Int // The struct_element_addr of %3 followed by a load is replaced by a struct_extract of the Baz argument @@ -102,13 +102,16 @@ bb0: // CHECK-NEXT: release_value {{.*}} : $Baz // The release of %0 is replaced by a strong_release of the Foo argument, since -// is is a reference type +// it is a reference type // CHECK-NEXT: strong_release {{.*}} : $Foo // CHECK-NEXT: return [[RETVAL]] : $Int -sil private @closure0 : $@convention(thin) (@owned @box Foo, @inout Foo, @owned @box Baz, @inout Baz, @owned @box Int, @inout Int) -> Int { -bb0(%0 : $@box Foo, %1 : $*Foo, %2 : $@box Baz, %3 : $*Baz, %4 : $@box Int, %5 : $*Int): +sil private @closure0 : $@convention(thin) (@owned @box Foo, @owned @box Baz, @owned @box Int) -> Int { +bb0(%0 : $@box Foo, %2 : $@box Baz, %4 : $@box Int): + %1 = project_box %0 : $@box Foo + %3 = project_box %2 : $@box Baz + %5 = project_box %4 : $@box Int %6 = tuple () // function_ref test14.plus (a : Swift.Int, b : Swift.Int, c : Swift.Int) -> Swift.Int %7 = function_ref @dummy_func : $@convention(thin) (Int, Int, Int) -> Int @@ -137,18 +140,19 @@ bb0: %3 = metatype $@thick Foo.Type %4 = apply %2(%3) : $@convention(thin) (@thick Foo.Type) -> @owned Foo store %4 to %1#1 : $*Foo - %17 = function_ref @closure1 : $@convention(thin) (@box Foo, @inout Foo) -> Int + %17 = function_ref @closure1 : $@convention(thin) (@box Foo) -> Int strong_retain %1#0 : $@box Foo - // CHECK: partial_apply {{%.*}}({{%.*}}#0, {{%.*}}#1) - %21 = partial_apply %17(%1#0, %1#1) : $@convention(thin) (@box Foo, @inout Foo) -> Int + // CHECK: partial_apply {{%.*}}({{%.*}}#0) + %21 = partial_apply %17(%1#0) : $@convention(thin) (@box Foo) -> Int strong_release %1#0 : $@box Foo return %21 : $@callee_owned () -> Int } sil @mutate_foo : $@convention(thin) (@inout Foo) -> () -sil private @closure1 : $@convention(thin) (@box Foo, @inout Foo) -> Int { -bb0(%0 : $@box Foo, %1 : $*Foo): +sil private @closure1 : $@convention(thin) (@box Foo) -> Int { +bb0(%0 : $@box Foo): + %1 = project_box %0 : $@box Foo %6 = tuple () // function_ref test14.plus (a : Swift.Int, b : Swift.Int, c : Swift.Int) -> Swift.Int %7 = function_ref @dummy_func : $@convention(thin) (Int, Int, Int) -> Int @@ -173,12 +177,12 @@ bb0(%0 : $*Int, %1 : $*Int): %4 = alloc_box $Int copy_addr %1 to [initialization] %4#1 : $*Int %6 = function_ref @apply : $@convention(thin) (@owned @callee_owned () -> ()) -> () - // CHECK: [[PROMOTED:%[0-9a-zA-Z]+]] = function_ref @_TTSf2n_n_d_i__closureWithGenericSignature : $@convention(thin) <τ_0_0> (@owned @box Int, @inout Int, Int) -> () - %7 = function_ref @closureWithGenericSignature : $@convention(thin) <τ_0_0> (@owned @box Int, @inout Int, @owned @box Int, @inout Int) -> () + // CHECK: [[PROMOTED:%[0-9a-zA-Z]+]] = function_ref @_TTSf2n_i__closureWithGenericSignature : $@convention(thin) <τ_0_0> (@owned @box Int, Int) -> () + %7 = function_ref @closureWithGenericSignature : $@convention(thin) <τ_0_0> (@owned @box Int, @owned @box Int) -> () strong_retain %4#0 : $@box Int strong_retain %2#0 : $@box Int // CHECK: partial_apply [[PROMOTED]]<{{[^>]+}}>( - %10 = partial_apply %7(%4#0, %4#1, %2#0, %2#1) : $@convention(thin) <τ_0_0> (@owned @box Int, @inout Int, @owned @box Int, @inout Int) -> () + %10 = partial_apply %7(%4#0, %2#0) : $@convention(thin) <τ_0_0> (@owned @box Int, @owned @box Int) -> () %11 = apply %6(%10) : $@convention(thin) (@owned @callee_owned () -> ()) -> () copy_addr %4#1 to %1 : $*Int strong_release %4#0 : $@box Int @@ -188,9 +192,11 @@ bb0(%0 : $*Int, %1 : $*Int): return %16 : $() } -// CHECK: sil @_TTSf2n_n_d_i__closureWithGenericSignature : $@convention(thin) <{{[^>]+}}> (@owned @box Int, @inout Int, Int) -> () -sil @closureWithGenericSignature : $@convention(thin) (@owned @box Int, @inout Int, @owned @box Int, @inout Int) -> () { -bb0(%0 : $@box Int, %1 : $*Int, %2 : $@box Int, %3 : $*Int): +// CHECK: sil @_TTSf2n_i__closureWithGenericSignature : $@convention(thin) <{{[^>]+}}> (@owned @box Int, Int) -> () +sil @closureWithGenericSignature : $@convention(thin) (@owned @box Int, @owned @box Int) -> () { +bb0(%0 : $@box Int, %2 : $@box Int): + %1 = project_box %0 : $@box Int + %3 = project_box %2 : $@box Int %4 = function_ref @_TFsoi1pFTSiSi_Si : $@convention(thin) (Int, Int) -> Int %5 = load %3 : $*Int %6 = load %3 : $*Int diff --git a/test/SILOptimizer/capture_promotion.swift b/test/SILOptimizer/capture_promotion.swift new file mode 100644 index 0000000000000..6fd1949dfa183 --- /dev/null +++ b/test/SILOptimizer/capture_promotion.swift @@ -0,0 +1,32 @@ +// RUN: %target-swift-frontend %s -emit-sil -o - -verify | FileCheck %s + +class Foo { + func foo() -> Int { + return 1 + } +} + +class Bar { +} + +struct Baz { + var bar = Bar() + var x = 42 +} + +// CHECK: sil hidden @_TF17capture_promotion22test_capture_promotionFT_FT_Si +func test_capture_promotion() -> () -> Int { + var x : Int = 1; x = 1 + var y : Foo = Foo(); y = Foo() + var z : Baz = Baz(); z = Baz() + +// CHECK-NOT: alloc_box + +// CHECK: [[CLOSURE0_PROMOTE0:%.*]] = function_ref @_TTSf2i_i_i___TFF17capture_promotion22test_capture_promotionFT_FT_SiU_FT_Si +// CHECK: partial_apply [[CLOSURE0_PROMOTE0]]({{%[0-9]*}}, {{%[0-9]*}}, {{%[0-9]*}}) + + return { x + y.foo() + z.x } +} + +// CHECK: sil shared @_TTSf2i_i_i___TFF17capture_promotion22test_capture_promotionFT_FT_SiU_FT_Si : $@convention(thin) (Int, @owned Foo, @owned Baz) -> Int + diff --git a/test/SILOptimizer/capture_promotion_reachability.sil b/test/SILOptimizer/capture_promotion_reachability.sil new file mode 100644 index 0000000000000..df48ea33bb8d5 --- /dev/null +++ b/test/SILOptimizer/capture_promotion_reachability.sil @@ -0,0 +1,319 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -capture-promotion | FileCheck %s + +sil_stage raw + +import Builtin +import Swift + +// top_level_code +sil private @top_level_code : $() -> () { +bb0: + %0 = tuple () + return %0 : $() +} + +/* +func test_reachability_1(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) { + if (b) { + x = y + } + var t : () -> Builtin.Int64 = { x } // promotable + if (b) { + t = { x } // promotable + } +} +*/ + +// CHECK-LABEL: sil @test_reachability_1 +sil @test_reachability_1 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () { +bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64): + %3 = alloc_box $Builtin.Int1 + %4 = alloc_box $Builtin.Int64 + %5 = alloc_box $Builtin.Int64 + store %0 to %3#1 : $*Builtin.Int1 + store %1 to %4#1 : $*Builtin.Int64 + store %2 to %5#1 : $*Builtin.Int64 + %9 = load %3#1 : $*Builtin.Int1 + cond_br %9, bb1, bb2 + +bb1: + %11 = load %5#1 : $*Builtin.Int64 + assign %11 to %4#1 : $*Builtin.Int64 + br bb2 + +bb2: + %14 = alloc_box $@callee_owned () -> Builtin.Int64 + // CHECK: [[CLOSURE0_PROMOTE0:%.*]] = function_ref @_TTSf2i__closure0 : + %15 = function_ref @closure0 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + strong_retain %4#0 : $@box Builtin.Int64 + // CHECK: partial_apply [[CLOSURE0_PROMOTE0]]({{%.*}}) + %17 = partial_apply %15(%4#0) : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + store %17 to %14#1 : $*@callee_owned () -> Builtin.Int64 + %19 = load %3#1 : $*Builtin.Int1 + cond_br %19, bb3, bb4 + +bb3: + // CHECK: [[CLOSURE1_PROMOTE0:%.*]] = function_ref @_TTSf2i__closure1 : + %21 = function_ref @closure1 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + strong_retain %4#0 : $@box Builtin.Int64 + // CHECK: partial_apply [[CLOSURE1_PROMOTE0]]({{%.*}}) + %23 = partial_apply %21(%4#0) : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + assign %23 to %14#1 : $*@callee_owned () -> Builtin.Int64 + br bb4 + +bb4: + strong_release %14#0 : $@box @callee_owned () -> Builtin.Int64 + strong_release %5#0 : $@box Builtin.Int64 + strong_release %4#0 : $@box Builtin.Int64 + strong_release %3#0 : $@box Builtin.Int1 + %30 = tuple () + return %30 : $() +} + +// closure0 +sil private @closure0 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 { +bb0(%0 : $@box Builtin.Int64): + %1 = project_box %0 : $@box Builtin.Int64 + %2 = tuple () + %3 = load %1 : $*Builtin.Int64 + strong_release %0 : $@box Builtin.Int64 + return %3 : $Builtin.Int64 +} + +// closure1 +sil private @closure1 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 { +bb0(%0 : $@box Builtin.Int64): + %1 = project_box %0 : $@box Builtin.Int64 + %2 = tuple () + %3 = load %1 : $*Builtin.Int64 + strong_release %0 : $@box Builtin.Int64 + return %3 : $Builtin.Int64 +} + +/* +func test_reachability_2(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) { + var t : () -> Builtin.Int64 = { x } // unpromotable + if (b) { + x = y + } + if (b) { + t = { x } // promotable + } +} +*/ + +// CHECK-LABEL: sil @test_reachability_2 +sil @test_reachability_2 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () { +bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64): + %3 = alloc_box $Builtin.Int1 + %4 = alloc_box $Builtin.Int64 + %5 = alloc_box $Builtin.Int64 + store %0 to %3#1 : $*Builtin.Int1 + store %1 to %4#1 : $*Builtin.Int64 + store %2 to %5#1 : $*Builtin.Int64 + %9 = alloc_box $@callee_owned () -> Builtin.Int64 + // CHECK: [[CLOSURE2:%.*]] = function_ref @closure2 : + %10 = function_ref @closure2 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + strong_retain %4#0 : $@box Builtin.Int64 + // CHECK: partial_apply [[CLOSURE2]]({{%.*}}) + %12 = partial_apply %10(%4#0) : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + store %12 to %9#1 : $*@callee_owned () -> Builtin.Int64 + %14 = load %3#1 : $*Builtin.Int1 + cond_br %14, bb1, bb2 + +bb1: + %16 = load %5#1 : $*Builtin.Int64 + assign %16 to %4#1 : $*Builtin.Int64 + br bb2 + +bb2: + %19 = load %3#1 : $*Builtin.Int1 + cond_br %19, bb3, bb4 + +bb3: + // CHECK: [[CLOSURE3_PROMOTE0:%.*]] = function_ref @_TTSf2i__closure3 : + %21 = function_ref @closure3 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + strong_retain %4#0 : $@box Builtin.Int64 + // CHECK: partial_apply [[CLOSURE3_PROMOTE0]]({{%.*}}) + %23 = partial_apply %21(%4#0) : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + assign %23 to %9#1 : $*@callee_owned () -> Builtin.Int64 + br bb4 + +bb4: + strong_release %9#0 : $@box @callee_owned () -> Builtin.Int64 + strong_release %5#0 : $@box Builtin.Int64 + strong_release %4#0 : $@box Builtin.Int64 + strong_release %3#0 : $@box Builtin.Int1 + %30 = tuple () + return %30 : $() +} + +// closure2 +sil private @closure2 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 { +bb0(%0 : $@box Builtin.Int64): + %1 = project_box %0 : $@box Builtin.Int64 + %2 = tuple () + %3 = load %1 : $*Builtin.Int64 + strong_release %0 : $@box Builtin.Int64 + return %3 : $Builtin.Int64 +} + +// closure3 +sil private @closure3 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 { +bb0(%0 : $@box Builtin.Int64): + %1 = project_box %0 : $@box Builtin.Int64 + %2 = tuple () + %3 = load %1 : $*Builtin.Int64 + strong_release %0 : $@box Builtin.Int64 + return %3 : $Builtin.Int64 +} + +/* +func test_reachability_3(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) { + var t : () -> Builtin.Int64 = { x } // unpromotable + if (b) { + t = { x } // unpromotable + } + if (b) { + x = y + } +} +*/ + +// CHECK-LABEL: sil @test_reachability_3 +sil @test_reachability_3 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () { +bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64): + %3 = alloc_box $Builtin.Int1 + %4 = alloc_box $Builtin.Int64 + %5 = alloc_box $Builtin.Int64 + store %0 to %3#1 : $*Builtin.Int1 + store %1 to %4#1 : $*Builtin.Int64 + store %2 to %5#1 : $*Builtin.Int64 + %9 = alloc_box $@callee_owned () -> Builtin.Int64 + // CHECK: [[CLOSURE4:%.*]] = function_ref @closure4 : + %10 = function_ref @closure4 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + strong_retain %4#0 : $@box Builtin.Int64 + // CHECK: partial_apply [[CLOSURE4]]({{%.*}}) + %12 = partial_apply %10(%4#0) : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + store %12 to %9#1 : $*@callee_owned () -> Builtin.Int64 + %14 = load %3#1 : $*Builtin.Int1 + cond_br %14, bb1, bb2 + +bb1: + // CHECK: [[CLOSURE5:%.*]] = function_ref @closure5 : + %16 = function_ref @closure5 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + strong_retain %4#0 : $@box Builtin.Int64 + // CHECK: partial_apply [[CLOSURE5]]({{%.*}}) + %18 = partial_apply %16(%4#0) : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + assign %18 to %9#1 : $*@callee_owned () -> Builtin.Int64 + br bb2 + +bb2: + %21 = load %3#1 : $*Builtin.Int1 + cond_br %21, bb3, bb4 + +bb3: + %23 = load %5#1 : $*Builtin.Int64 + assign %23 to %4#1 : $*Builtin.Int64 + br bb4 + +bb4: + strong_release %9#0 : $@box @callee_owned () -> Builtin.Int64 + strong_release %5#0 : $@box Builtin.Int64 + strong_release %4#0 : $@box Builtin.Int64 + strong_release %3#0 : $@box Builtin.Int1 + %30 = tuple () + return %30 : $() +} + +// closure4 +sil private @closure4 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 { +bb0(%0 : $@box Builtin.Int64): + %1 = project_box %0 : $@box Builtin.Int64 + %2 = tuple () + %3 = load %1 : $*Builtin.Int64 + strong_release %0 : $@box Builtin.Int64 + return %3 : $Builtin.Int64 +} + +// closure5 +sil private @closure5 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 { +bb0(%0 : $@box Builtin.Int64): + %1 = project_box %0 : $@box Builtin.Int64 + %2 = tuple () + %3 = load %1 : $*Builtin.Int64 + strong_release %0 : $@box Builtin.Int64 + return %3 : $Builtin.Int64 +} + +/* +func test_reachability_4(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) { + var t : () -> Builtin.Int64 = { x } // unpromotable + while (b) { + x = y + t = { x } // unpromotable + } +} +*/ + +// CHECK-LABEL: sil @test_reachability_4 +sil @test_reachability_4 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () { +bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64): + %3 = alloc_box $Builtin.Int1 + %4 = alloc_box $Builtin.Int64 + %5 = alloc_box $Builtin.Int64 + store %0 to %3#1 : $*Builtin.Int1 + store %1 to %4#1 : $*Builtin.Int64 + store %2 to %5#1 : $*Builtin.Int64 + %9 = alloc_box $@callee_owned () -> Builtin.Int64 + // CHECK: [[CLOSURE6:%.*]] = function_ref @closure6 : + %10 = function_ref @closure6 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + strong_retain %4#0 : $@box Builtin.Int64 + // CHECK: partial_apply [[CLOSURE6]]({{%.*}}) + %12 = partial_apply %10(%4#0) : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + store %12 to %9#1 : $*@callee_owned () -> Builtin.Int64 + br bb1 + +bb1: + %15 = load %3#1 : $*Builtin.Int1 + cond_br %15, bb2, bb3 + +bb2: + %17 = load %5#1 : $*Builtin.Int64 + assign %17 to %4#1 : $*Builtin.Int64 + // CHECK: [[CLOSURE7:%.*]] = function_ref @closure7 : + %19 = function_ref @closure7 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + strong_retain %4#0 : $@box Builtin.Int64 + // CHECK: partial_apply [[CLOSURE7]]({{%.*}}) + %21 = partial_apply %19(%4#0) : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 + assign %21 to %9#1 : $*@callee_owned () -> Builtin.Int64 + br bb1 + +bb3: + strong_release %9#0 : $@box @callee_owned () -> Builtin.Int64 + strong_release %5#0 : $@box Builtin.Int64 + strong_release %4#0 : $@box Builtin.Int64 + strong_release %3#0 : $@box Builtin.Int1 + %28 = tuple () + return %28 : $() +} + +// closure6 +sil private @closure6 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 { +bb0(%0 : $@box Builtin.Int64): + %1 = project_box %0 : $@box Builtin.Int64 + %2 = tuple () + %3 = load %1 : $*Builtin.Int64 + strong_release %0 : $@box Builtin.Int64 + return %3 : $Builtin.Int64 +} + +// closure7 +sil private @closure7 : $@convention(thin) (@owned @box Builtin.Int64) -> Builtin.Int64 { +bb0(%0 : $@box Builtin.Int64): + %1 = project_box %0 : $@box Builtin.Int64 + %2 = tuple () + %3 = load %1 : $*Builtin.Int64 + strong_release %0 : $@box Builtin.Int64 + return %3 : $Builtin.Int64 +} diff --git a/test/SILPasses/capture_propagation.sil b/test/SILOptimizer/capture_propagation.sil similarity index 93% rename from test/SILPasses/capture_propagation.sil rename to test/SILOptimizer/capture_propagation.sil index ce7a7d59e6d09..88d23535cafd7 100644 --- a/test/SILPasses/capture_propagation.sil +++ b/test/SILOptimizer/capture_propagation.sil @@ -17,7 +17,7 @@ bb0: %0 = alloc_stack $Int32 // users: %3, %9, %10 %1 = integer_literal $Builtin.Int32, 3 // user: %2 %2 = struct $Int32 (%1 : $Builtin.Int32) // user: %3 - store %2 to %0#1 : $*Int32 // id: %3 + store %2 to %0 : $*Int32 // id: %3 // function_ref capturep.helper (Swift.Int32) -> () %4 = function_ref @_TF8capturep6helperFSiT_ : $@convention(thin) (Int32) -> () // user: %5 %5 = thin_to_thick_function %4 : $@convention(thin) (Int32) -> () to $@callee_owned (Int32) -> () // user: %7 @@ -26,14 +26,14 @@ bb0: %7 = partial_apply %6(%5) : $@convention(thin) (@in Int32, @owned @callee_owned (Int32) -> ()) -> () // user: %9 // function_ref specialization of capturep.generic (A, (A) -> ()) -> () %8 = function_ref @_TTSgSi___TF8capturep7genericU__FTQ_FQ_T__T_ : $@convention(thin) (@in Int32, @owned @callee_owned (@in Int32) -> ()) -> () // user: %9 - %9 = apply %8(%0#1, %7) : $@convention(thin) (@in Int32, @owned @callee_owned (@in Int32) -> ()) -> () + %9 = apply %8(%0, %7) : $@convention(thin) (@in Int32, @owned @callee_owned (@in Int32) -> ()) -> () %11 = thin_to_thick_function %4 : $@convention(thin) (Int32) -> () to $@callee_owned (Int32) -> () // user: %7 %12 = function_ref @bad_thunk : $@convention(thin) (@in Int32, @owned @callee_owned (Int32) -> ()) -> () %13 = partial_apply %12(%11) : $@convention(thin) (@in Int32, @owned @callee_owned (Int32) -> ()) -> () // user: %9 - %14 = apply %8(%0#1, %13) : $@convention(thin) (@in Int32, @owned @callee_owned (@in Int32) -> ()) -> () + %14 = apply %8(%0, %13) : $@convention(thin) (@in Int32, @owned @callee_owned (@in Int32) -> ()) -> () - dealloc_stack %0#0 : $*@local_storage Int32 // id: %10 + dealloc_stack %0 : $*Int32 // id: %10 %15 = tuple () // user: %12 return %15 : $() // id: %12 } @@ -60,9 +60,9 @@ sil shared [noinline] @_TTSgSi___TF8capturep7genericU__FTQ_FQ_T__T_ : $@conventi bb0(%0 : $*Int32, %1 : $@callee_owned (@in Int32) -> ()): %2 = alloc_stack $Int32 // users: %4, %5, %6 %3 = load %0 : $*Int32 // user: %4 - store %3 to %2#1 : $*Int32 // id: %4 - %5 = apply %1(%2#1) : $@callee_owned (@in Int32) -> () - dealloc_stack %2#0 : $*@local_storage Int32 // id: %6 + store %3 to %2 : $*Int32 // id: %4 + %5 = apply %1(%2) : $@callee_owned (@in Int32) -> () + dealloc_stack %2 : $*Int32 // id: %6 %7 = tuple () // user: %8 return %7 : $() // id: %8 } diff --git a/test/SILPasses/capture_propagation_linkage.swift b/test/SILOptimizer/capture_propagation_linkage.swift similarity index 100% rename from test/SILPasses/capture_propagation_linkage.swift rename to test/SILOptimizer/capture_propagation_linkage.swift diff --git a/test/SILPasses/cast_folding.swift b/test/SILOptimizer/cast_folding.swift similarity index 100% rename from test/SILPasses/cast_folding.swift rename to test/SILOptimizer/cast_folding.swift diff --git a/test/SILPasses/cast_folding_no_bridging.sil b/test/SILOptimizer/cast_folding_no_bridging.sil similarity index 82% rename from test/SILPasses/cast_folding_no_bridging.sil rename to test/SILOptimizer/cast_folding_no_bridging.sil index 7e1777d911302..5791961a41ea8 100644 --- a/test/SILPasses/cast_folding_no_bridging.sil +++ b/test/SILOptimizer/cast_folding_no_bridging.sil @@ -22,18 +22,18 @@ import Foundation sil @testSwiftToSwift : $@convention(thin) (@in Set, @guaranteed Set) -> @owned Set { bb0(%0 : $*Set, %1 : $Set): %3 = alloc_stack $Set - copy_addr %0 to [initialization] %3#1 : $*Set + copy_addr %0 to [initialization] %3 : $*Set %5 = alloc_stack $Set - checked_cast_addr_br take_always Set in %3#1 : $*Set to Set in %5#1 : $*Set, bb1, bb3 + checked_cast_addr_br take_always Set in %3 : $*Set to Set in %5 : $*Set, bb1, bb3 bb1: destroy_addr %0 : $*Set - %8 = load %5#1 : $*Set + %8 = load %5 : $*Set br bb2(%8 : $Set) bb2(%14 : $Set): - dealloc_stack %5#0 : $*@local_storage Set - dealloc_stack %3#0 : $*@local_storage Set + dealloc_stack %5 : $*Set + dealloc_stack %3 : $*Set return %14 : $Set bb3: diff --git a/test/SILPasses/cast_folding_objc.swift b/test/SILOptimizer/cast_folding_objc.swift similarity index 98% rename from test/SILPasses/cast_folding_objc.swift rename to test/SILOptimizer/cast_folding_objc.swift index b20736e56b223..c300e8c107d3d 100644 --- a/test/SILPasses/cast_folding_objc.swift +++ b/test/SILOptimizer/cast_folding_objc.swift @@ -78,7 +78,7 @@ public func testBridgedCastFromSwiftToObjC(s: String) -> NSString { // Check that this cast does not get eliminated, because // the compiler does not statically know if this object -// is NSNumber can can be converted into Int. +// is NSNumber can be converted into Int. // CHECK-LABEL: sil [noinline] @_TF17cast_folding_objc35testMayBeBridgedCastFromObjCtoSwiftFPs9AnyObject_Si // CHECK: unconditional_checked_cast_addr // CHECK: return @@ -89,7 +89,7 @@ public func testMayBeBridgedCastFromObjCtoSwift(o: AnyObject) -> Int { // Check that this cast does not get eliminated, because // the compiler does not statically know if this object -// is NSString can can be converted into String. +// is NSString can be converted into String. // CHECK-LABEL: sil [noinline] @_TF17cast_folding_objc41testConditionalBridgedCastFromObjCtoSwiftFPs9AnyObject_GSqSS_ // CHECK: unconditional_checked_cast_addr // CHECK: return diff --git a/test/SILPasses/cast_folding_objc_no_foundation.swift b/test/SILOptimizer/cast_folding_objc_no_foundation.swift similarity index 88% rename from test/SILPasses/cast_folding_objc_no_foundation.swift rename to test/SILOptimizer/cast_folding_objc_no_foundation.swift index 781472bc0a675..ed85ae726e406 100644 --- a/test/SILPasses/cast_folding_objc_no_foundation.swift +++ b/test/SILOptimizer/cast_folding_objc_no_foundation.swift @@ -9,7 +9,7 @@ struct DoesNotBridgeToObjC {} // CHECK: bb0(%0 : $AnyObject): // CHECK: [[SOURCE:%.*]] = alloc_stack $AnyObject // CHECK: [[TARGET:%.*]] = alloc_stack $Array -// CHECK: checked_cast_addr_br take_always AnyObject in [[SOURCE]]#1 : $*AnyObject to Array in [[TARGET]]#1 : $*Array, bb1, bb2 +// CHECK: checked_cast_addr_br take_always AnyObject in [[SOURCE]] : $*AnyObject to Array in [[TARGET]] : $*Array, bb1, bb2 @inline(never) func testAnyObjectToArrayInt(a: AnyObject) -> Bool { return a is [Int] @@ -19,7 +19,7 @@ func testAnyObjectToArrayInt(a: AnyObject) -> Bool { // CHECK: bb0(%0 : $AnyObject): // CHECK: [[SOURCE:%.*]] = alloc_stack $AnyObject // CHECK: [[TARGET:%.*]] = alloc_stack $Array -// CHECK: checked_cast_addr_br take_always AnyObject in [[SOURCE]]#1 : $*AnyObject to Array in [[TARGET]]#1 : $*Array, bb1, bb2 +// CHECK: checked_cast_addr_br take_always AnyObject in [[SOURCE]] : $*AnyObject to Array in [[TARGET]] : $*Array, bb1, bb2 @inline(never) func testAnyObjectToArrayString(a: AnyObject) -> Bool { return a is [String] @@ -39,7 +39,7 @@ func testAnyObjectToArrayNotBridged(a: AnyObject) -> Bool { // CHECK: bb0(%0 : $AnyObject): // CHECK: [[SOURCE:%.*]] = alloc_stack $AnyObject // CHECK: [[TARGET:%.*]] = alloc_stack $Dictionary -// CHECK: checked_cast_addr_br take_always AnyObject in [[SOURCE]]#1 : $*AnyObject to Dictionary in [[TARGET]]#1 : $*Dictionary, bb1, bb2 +// CHECK: checked_cast_addr_br take_always AnyObject in [[SOURCE]] : $*AnyObject to Dictionary in [[TARGET]] : $*Dictionary, bb1, bb2 @inline(never) func testAnyObjectToDictionary(a: AnyObject) -> Bool { return a is [Int:String] @@ -49,7 +49,7 @@ func testAnyObjectToDictionary(a: AnyObject) -> Bool { // CHECK: bb0(%0 : $AnyObject): // CHECK: [[SOURCE:%.*]] = alloc_stack $AnyObject // CHECK: [[TARGET:%.*]] = alloc_stack $String -// CHECK: checked_cast_addr_br take_always AnyObject in [[SOURCE]]#1 : $*AnyObject to String in [[TARGET]]#1 : $*String, bb1, bb2 +// CHECK: checked_cast_addr_br take_always AnyObject in [[SOURCE]] : $*AnyObject to String in [[TARGET]] : $*String, bb1, bb2 @inline(never) func testAnyObjectToString(a: AnyObject) -> Bool { return a is String diff --git a/test/SILPasses/cast_foldings.sil b/test/SILOptimizer/cast_foldings.sil similarity index 93% rename from test/SILPasses/cast_foldings.sil rename to test/SILOptimizer/cast_foldings.sil index a159bd9c70c97..342003b5b7a14 100644 --- a/test/SILPasses/cast_foldings.sil +++ b/test/SILOptimizer/cast_foldings.sil @@ -16,9 +16,9 @@ struct S {} sil @dont_fold_unconditional_checked_cast_to_existentials : $@convention(thin) () -> AnyObject { entry: %0 = alloc_stack $NSCloud - %1 = load %0#1 : $*NSCloud + %1 = load %0 : $*NSCloud %2 = unconditional_checked_cast %1 : $NSCloud to $AnyObject - dealloc_stack %0#0 : $*@local_storage NSCloud + dealloc_stack %0 : $*NSCloud return %2 : $AnyObject } @@ -96,11 +96,11 @@ sil @function_ref_cast_struct : $@convention(thin) () -> @owned AnyObject { bb0: %0 = struct $S () %1 = alloc_stack $S - store %0 to %1#1 : $*S + store %0 to %1 : $*S %4 = alloc_stack $AnyObject - unchecked_ref_cast_addr S in %1#1 : $*S to AnyObject in %4#1 : $*AnyObject - %6 = load %4#1 : $*AnyObject - dealloc_stack %4#0 : $*@local_storage AnyObject - dealloc_stack %1#0 : $*@local_storage S + unchecked_ref_cast_addr S in %1 : $*S to AnyObject in %4 : $*AnyObject + %6 = load %4 : $*AnyObject + dealloc_stack %4 : $*AnyObject + dealloc_stack %1 : $*S return %6 : $AnyObject } diff --git a/test/SILPasses/cast_promote.sil b/test/SILOptimizer/cast_promote.sil similarity index 77% rename from test/SILPasses/cast_promote.sil rename to test/SILOptimizer/cast_promote.sil index 247eb77054ba0..9bee66d7bb921 100644 --- a/test/SILPasses/cast_promote.sil +++ b/test/SILOptimizer/cast_promote.sil @@ -19,10 +19,10 @@ public protocol NativeProto {} sil @promote_super : $@convention(thin) (@owned AnyObject) -> @owned T { bb0(%0 : $AnyObject): %1 = alloc_stack $AnyObject - store %0 to %1#1 : $*AnyObject - %3 = unchecked_addr_cast %1#1 : $*AnyObject to $*T + store %0 to %1 : $*AnyObject + %3 = unchecked_addr_cast %1 : $*AnyObject to $*T %4 = load %3 : $*T - dealloc_stack %1#0 : $*@local_storage AnyObject + dealloc_stack %1 : $*AnyObject return %4 : $T } @@ -32,10 +32,10 @@ bb0(%0 : $AnyObject): sil @promote_anyobject : $@convention(thin) (@owned AnyObject) -> @owned T { bb0(%0 : $AnyObject): %1 = alloc_stack $AnyObject - store %0 to %1#1 : $*AnyObject - %3 = unchecked_addr_cast %1#1 : $*AnyObject to $*T + store %0 to %1 : $*AnyObject + %3 = unchecked_addr_cast %1 : $*AnyObject to $*T %4 = load %3 : $*T - dealloc_stack %1#0 : $*@local_storage AnyObject + dealloc_stack %1 : $*AnyObject return %4 : $T } @@ -45,10 +45,10 @@ bb0(%0 : $AnyObject): sil @promote_objc : $@convention(thin) (@owned AnyObject) -> @owned T { bb0(%0 : $AnyObject): %1 = alloc_stack $AnyObject - store %0 to %1#1 : $*AnyObject - %3 = unchecked_addr_cast %1#1 : $*AnyObject to $*T + store %0 to %1 : $*AnyObject + %3 = unchecked_addr_cast %1 : $*AnyObject to $*T %4 = load %3 : $*T - dealloc_stack %1#0 : $*@local_storage AnyObject + dealloc_stack %1 : $*AnyObject return %4 : $T } @@ -58,10 +58,10 @@ bb0(%0 : $AnyObject): sil @promote_objcproto : $@convention(thin) (@owned AnyObject) -> @owned ObjCProto { bb0(%0 : $AnyObject): %1 = alloc_stack $AnyObject - store %0 to %1#1 : $*AnyObject - %3 = unchecked_addr_cast %1#1 : $*AnyObject to $*ObjCProto + store %0 to %1 : $*AnyObject + %3 = unchecked_addr_cast %1 : $*AnyObject to $*ObjCProto %4 = load %3 : $*ObjCProto - dealloc_stack %1#0 : $*@local_storage AnyObject + dealloc_stack %1 : $*AnyObject return %4 : $ObjCProto } @@ -71,10 +71,10 @@ bb0(%0 : $AnyObject): sil @nopromote_nativeproto : $@convention(thin) (@out NativeProto, @owned AnyObject) -> () { bb0(%0 : $*NativeProto, %1 : $AnyObject): %3 = alloc_stack $AnyObject - store %1 to %3#1 : $*AnyObject - %5 = unchecked_addr_cast %3#1 : $*AnyObject to $*NativeProto + store %1 to %3 : $*AnyObject + %5 = unchecked_addr_cast %3 : $*AnyObject to $*NativeProto copy_addr %5 to [initialization] %0 : $*NativeProto - dealloc_stack %3#0 : $*@local_storage AnyObject + dealloc_stack %3 : $*AnyObject strong_release %1 : $AnyObject %9 = tuple () return %9 : $() @@ -191,8 +191,8 @@ struct Agg { // CHECK: load %2 : $*Agg // CHECK: unchecked_trivial_bit_cast %{{.*}} : $Agg to $PtrInt // CHECK: [[LOCAL:%.*]] = alloc_stack $Agg -// CHECK: store %{{.*}} to [[LOCAL]]#1 : $*Agg -// CHECK: [[CAST:%.*]] = unchecked_addr_cast [[LOCAL]]#1 : $*Agg to $*PtrInt2 +// CHECK: store %{{.*}} to [[LOCAL]] : $*Agg +// CHECK: [[CAST:%.*]] = unchecked_addr_cast [[LOCAL]] : $*Agg to $*PtrInt2 // CHECK: load [[CAST]] : $*PtrInt2 // CHECK: dealloc_stack // CHECK: return @@ -200,28 +200,28 @@ sil @unchecked_addr_cast_struct_promote : $@convention(thin) (@inout PtrInt, @in bb0(%0 : $*PtrInt, %1 : $*PtrInt2, %2 : $*Agg): %3 = load %0 : $*PtrInt %4 = alloc_stack $PtrInt - store %3 to %4#1 : $*PtrInt - %6 = unchecked_addr_cast %4#1 : $*PtrInt to $*Builtin.RawPointer + store %3 to %4 : $*PtrInt + %6 = unchecked_addr_cast %4 : $*PtrInt to $*Builtin.RawPointer %7 = load %6 : $*Builtin.RawPointer %8 = load %1 : $*PtrInt2 %9 = alloc_stack $PtrInt2 - store %8 to %9#1 : $*PtrInt2 - %11 = unchecked_addr_cast %9#1 : $*PtrInt2 to $*PtrInt + store %8 to %9 : $*PtrInt2 + %11 = unchecked_addr_cast %9 : $*PtrInt2 to $*PtrInt %12 = load %11 : $*PtrInt %13 = load %2 : $*Agg %14 = alloc_stack $Agg - store %13 to %14#1 : $*Agg - %16 = unchecked_addr_cast %14#1 : $*Agg to $*PtrInt + store %13 to %14 : $*Agg + %16 = unchecked_addr_cast %14 : $*Agg to $*PtrInt %17 = load %16 : $*PtrInt %18 = alloc_stack $Agg - store %13 to %18#1 : $*Agg - %20 = unchecked_addr_cast %18#1 : $*Agg to $*PtrInt2 + store %13 to %18 : $*Agg + %20 = unchecked_addr_cast %18 : $*Agg to $*PtrInt2 %21 = load %20 : $*PtrInt2 %22 = tuple (%7 : $Builtin.RawPointer, %12 : $PtrInt, %17 : $PtrInt, %21 : $PtrInt2) - dealloc_stack %18#0 : $*@local_storage Agg - dealloc_stack %14#0 : $*@local_storage Agg - dealloc_stack %9#0 : $*@local_storage PtrInt2 - dealloc_stack %4#0 : $*@local_storage PtrInt + dealloc_stack %18 : $*Agg + dealloc_stack %14 : $*Agg + dealloc_stack %9 : $*PtrInt2 + dealloc_stack %4 : $*PtrInt return %22 : $(Builtin.RawPointer, PtrInt, PtrInt, PtrInt2) } @@ -252,53 +252,53 @@ public enum PX3 {case X(Int), Y, Z} // CHECK: unchecked_trivial_bit_cast %{{.*}} : $PB2 to $Int // CHECK: unchecked_trivial_bit_cast %{{.*}} : $PB2 to $PX2 // CHECK: alloc_stack $PB2 -// CHECK: store %{{.*}} to %{{.*}}#1 : $*PB2 -// CHECK: unchecked_addr_cast %{{.*}}#1 : $*PB2 to $*PX3 +// CHECK: store %{{.*}} to %{{.*}} : $*PB2 +// CHECK: unchecked_addr_cast %{{.*}} : $*PB2 to $*PX3 // CHECK: load %{{.*}} : $*PX3 // CHECK: load %3 : $*PAB2 // CHECK: alloc_stack $PAB2 -// CHECK: store %{{.*}} to %{{.*}}#1 : $*PAB2 -// CHECK: unchecked_addr_cast %{{.*}}#1 : $*PAB2 to $*PXY2 +// CHECK: store %{{.*}} to %{{.*}} : $*PAB2 +// CHECK: unchecked_addr_cast %{{.*}} : $*PAB2 to $*PXY2 // CHECK: load %{{.*}} : $*PXY2 -// CHECK: dealloc_stack %{{.*}}#0 : $*@local_storage PAB2 -// CHECK: dealloc_stack %{{.*}}#0 : $*@local_storage PB2 +// CHECK: dealloc_stack %{{.*}} : $*PAB2 +// CHECK: dealloc_stack %{{.*}} : $*PB2 // CHECK: return %{{.*}} : $(E0_, E1, Int, PX2, PX3, PXY2) sil @unchecked_addr_cast_enum_promote : $@convention(thin) (@inout E0, @inout E2, @inout PB2, @inout PAB2) -> (E0_, E1, Int, PX2, PX3, PXY2) { bb0(%0 : $*E0, %1 : $*E2, %2 : $*PB2, %3 : $*PAB2): %9 = load %0 : $*E0 // user: %11 %10 = alloc_stack $E0 // users: %11, %12, %43 - store %9 to %10#1 : $*E0 // id: %11 - %12 = unchecked_addr_cast %10#1 : $*E0 to $*E0_ // user: %13 + store %9 to %10 : $*E0 // id: %11 + %12 = unchecked_addr_cast %10 : $*E0 to $*E0_ // user: %13 %13 = load %12 : $*E0_ // user: %37 %14 = load %1 : $*E2 // user: %16 %15 = alloc_stack $E2 // users: %16, %17, %42 - store %14 to %15#1 : $*E2 // id: %16 - %17 = unchecked_addr_cast %15#1 : $*E2 to $*E1 // user: %18 + store %14 to %15 : $*E2 // id: %16 + %17 = unchecked_addr_cast %15 : $*E2 to $*E1 // user: %18 %18 = load %17 : $*E1 // user: %37 %19 = load %2 : $*PB2 // users: %21, %25, %29 %20 = alloc_stack $PB2 // users: %21, %22, %41 - store %19 to %20#1 : $*PB2 // id: %21 - %22 = unchecked_addr_cast %20#1 : $*PB2 to $*Int // user: %23 + store %19 to %20 : $*PB2 // id: %21 + %22 = unchecked_addr_cast %20 : $*PB2 to $*Int // user: %23 %23 = load %22 : $*Int // user: %37 %24 = alloc_stack $PB2 // users: %25, %26, %40 - store %19 to %24#1 : $*PB2 // id: %25 - %26 = unchecked_addr_cast %24#1 : $*PB2 to $*PX2 // user: %27 + store %19 to %24 : $*PB2 // id: %25 + %26 = unchecked_addr_cast %24 : $*PB2 to $*PX2 // user: %27 %27 = load %26 : $*PX2 // user: %37 %28 = alloc_stack $PB2 // users: %29, %30, %39 - store %19 to %28#1 : $*PB2 // id: %29 - %30 = unchecked_addr_cast %28#1 : $*PB2 to $*PX3 // user: %31 + store %19 to %28 : $*PB2 // id: %29 + %30 = unchecked_addr_cast %28 : $*PB2 to $*PX3 // user: %31 %31 = load %30 : $*PX3 // user: %37 %32 = load %3 : $*PAB2 // user: %34 %33 = alloc_stack $PAB2 // users: %34, %35, %38 - store %32 to %33#1 : $*PAB2 // id: %34 - %35 = unchecked_addr_cast %33#1 : $*PAB2 to $*PXY2 // user: %36 + store %32 to %33 : $*PAB2 // id: %34 + %35 = unchecked_addr_cast %33 : $*PAB2 to $*PXY2 // user: %36 %36 = load %35 : $*PXY2 // user: %37 %37 = tuple (%13 : $E0_, %18 : $E1, %23 : $Int, %27 : $PX2, %31 : $PX3, %36 : $PXY2) // user: %44 - dealloc_stack %33#0 : $*@local_storage PAB2 // id: %38 - dealloc_stack %28#0 : $*@local_storage PB2 // id: %39 - dealloc_stack %24#0 : $*@local_storage PB2 // id: %40 - dealloc_stack %20#0 : $*@local_storage PB2 // id: %41 - dealloc_stack %15#0 : $*@local_storage E2 // id: %42 - dealloc_stack %10#0 : $*@local_storage E0 // id: %43 + dealloc_stack %33 : $*PAB2 // id: %38 + dealloc_stack %28 : $*PB2 // id: %39 + dealloc_stack %24 : $*PB2 // id: %40 + dealloc_stack %20 : $*PB2 // id: %41 + dealloc_stack %15 : $*E2 // id: %42 + dealloc_stack %10 : $*E0 // id: %43 return %37 : $(E0_, E1, Int, PX2, PX3, PXY2) // id: %44 } diff --git a/test/SILOptimizer/closure_specialize.sil b/test/SILOptimizer/closure_specialize.sil new file mode 100644 index 0000000000000..b929378ea236d --- /dev/null +++ b/test/SILOptimizer/closure_specialize.sil @@ -0,0 +1,277 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -closure-specialize %s | FileCheck %s + +import Builtin +import Swift + +// CHECK-LABEL: sil shared [noinline] @_TTSf1cl35_TFF7specgen6callerFSiT_U_FTSiSi_T_Si___TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (Int) -> () { +// CHECK: bb0(%0 : $Int) +// CHECK: function_ref @_TFF7specgen6callerFSiT_U_FTSiSi_T_ +// CHECK: partial_apply + +// CHECK-LABEL: sil shared [noinline] @_TTSf1cl27_TF7specgen6calleeFTSiSi_T____TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) () -> () { +// CHECK-NEXT: bb0: +// CHECK: [[FUN:%.*]] = function_ref @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () +// CHECK: thin_to_thick_function [[FUN]] : $@convention(thin) (Int, Int) -> () to $@callee_owned (Int, Int) -> () + +// CHECK-LABEL: sil [noinline] @_TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () { +sil [noinline] @_TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () { +bb0(%0 : $@callee_owned (Int, Int) -> ()): + %1 = alloc_stack $Int + %2 = load %1 : $*Int + %3 = apply %0(%2, %2) : $@callee_owned (Int, Int) -> () + dealloc_stack %1 : $*Int + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil shared [noinline] @_TTSf1cl35_TFF7specgen6callerFSiT_U_FTSiSi_T_Si___TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (Int) -> () { +// CHECK: bb0(%0 : $Int) +// CHECK: [[FUN:%.*]] = function_ref @_TFF7specgen6callerFSiT_U_FTSiSi_T_ +// CHECK: partial_apply [[FUN]]( + +// CHECK-LABEL: sil shared [noinline] @_TTSf1cl27_TF7specgen6calleeFTSiSi_T____TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) () -> () { +// CHECK-NEXT: bb0: +// CHECK: [[FUN:%.*]] = function_ref @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () +// CHECK: thin_to_thick_function [[FUN]] : $@convention(thin) (Int, Int) -> () to $@callee_owned (Int, Int) -> () + +// CHECK-LABEL: sil [noinline] @_TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () { +sil [noinline] @_TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () { +bb0(%0 : $@callee_owned (Int, Int) -> ()): + %1 = alloc_stack $Int + %2 = load %1 : $*Int + %3 = apply %0(%2, %2) : $@callee_owned (Int, Int) -> () + dealloc_stack %1 : $*Int + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil [noinline] @_TF7specgen6calleeFTSiSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () { +// specgen.callee (Swift.Int, Swift.Int, Swift.Int) -> () +sil [noinline] @_TF7specgen6calleeFTSiSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () { +bb0(%0 : $Int, %1 : $Int, %2 : $Int): + %6 = tuple () // user: %7 + return %6 : $() // id: %7 +} + +// CHECK-LABEL: sil @_TF7specgen6callerFSiT_ : $@convention(thin) (Int) -> () { +// CHECK: [[ID1:%[0-9]+]] = function_ref @_TTSf1cl35_TFF7specgen6callerFSiT_U_FTSiSi_T_Si___TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (Int) -> () +// CHECK: [[ID2:%[0-9]+]] = function_ref @_TTSf1cl35_TFF7specgen6callerFSiT_U_FTSiSi_T_Si___TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (Int) -> () +// CHECK: apply [[ID2]](%0) : $@convention(thin) (Int) -> () +// CHECK: apply [[ID1]](%0) : $@convention(thin) (Int) -> () +sil @_TF7specgen6callerFSiT_ : $@convention(thin) (Int) -> () { +bb0(%0 : $Int): + // function_ref specgen.take_closure ((Swift.Int, Swift.Int) -> ()) -> () + %2 = function_ref @_TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () // user: %5 + // function_ref specgen.(caller (Swift.Int) -> ()).(closure #1) + %3 = function_ref @_TFF7specgen6callerFSiT_U_FTSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () // user: %4 + %4 = partial_apply %3(%0) : $@convention(thin) (Int, Int, Int) -> () // user: %5 + strong_retain %4 : $@callee_owned (Int, Int) -> () + %5 = apply %2(%4) : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () + %6 = function_ref @_TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () // user: %5 + strong_retain %4 : $@callee_owned (Int, Int) -> () + %7 = apply %6(%4) : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () + strong_release %4 : $@callee_owned (Int, Int) -> () + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil shared @_TFF7specgen6callerFSiT_U_FTSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () { +sil shared @_TFF7specgen6callerFSiT_U_FTSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () { +bb0(%0 : $Int, %1 : $Int, %2 : $Int): + %5 = alloc_box $Int, var, name "p" // users: %6, %10, %14 + store %0 to %5#1 : $*Int // id: %6 + %7 = alloc_box $Int, var, name "q" // users: %8, %11, %13 + store %1 to %7#1 : $*Int // id: %8 + // function_ref specgen.callee (Swift.Int, Swift.Int, Swift.Int) -> () + %9 = function_ref @_TF7specgen6calleeFTSiSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () // user: %12 + %10 = load %5#1 : $*Int // user: %12 + %11 = load %7#1 : $*Int // user: %12 + %12 = apply %9(%10, %11, %2) : $@convention(thin) (Int, Int, Int) -> () + strong_release %7#0 : $@box Int + strong_release %5#0 : $@box Int + %15 = tuple () // user: %16 + return %15 : $() // id: %16 +} + +////////////////////////////////// +// Thin To Thick Function Tests // +////////////////////////////////// + +// CHECK-LABEL: sil [noinline] @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () { +// specgen.callee (Swift.Int, Swift.Int) -> () +sil [noinline] @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () { +bb0(%0 : $Int, %1 : $Int): + %6 = tuple () // user: %7 + return %6 : $() // id: %7 +} + +// CHECK-LABEL: sil @_TF7specgen11tttficallerFSiT_ : $@convention(thin) (Int) -> () { +// CHECK: [[ID1:%[0-9]+]] = function_ref @_TTSf1cl27_TF7specgen6calleeFTSiSi_T____TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) () -> () +// CHECK: [[ID2:%[0-9]+]] = function_ref @_TTSf1cl27_TF7specgen6calleeFTSiSi_T____TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) () -> () +// CHECK: apply [[ID2]]() : $@convention(thin) () -> () +// CHECK: apply [[ID1]]() : $@convention(thin) () -> () +sil @_TF7specgen11tttficallerFSiT_ : $@convention(thin) (Int) -> () { +bb0(%0 : $Int): + // function_ref specgen.take_closure ((Swift.Int, Swift.Int) -> ()) -> () + %2 = function_ref @_TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () // user: %5 + // function_ref specgen.(caller (Swift.Int) -> ()).(closure #1) + %3 = function_ref @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () // user: %4 + %4 = thin_to_thick_function %3 : $@convention(thin) (Int, Int) -> () to $@callee_owned (Int, Int) -> () // user: %5 + %5 = apply %2(%4) : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () + %6 = function_ref @_TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () + %7 = apply %6(%4) : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () + %9999 = tuple () // user: %7 + return %9999 : $() // id: %7 +} + +// We don't handle closures that close over address types (*NOTE* this includes +// address and non-address only types). This is a temporary limitation. +// CHECK-LABEL: sil @address_closure : $@convention(thin) (@in Int) -> () { +sil @address_closure : $@convention(thin) (@in Int) -> () { +bb0(%0 : $*Int): + %6 = tuple() + return %6 : $() +} + +// CHECK-LABEL: sil @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () { +sil @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () { +bb0(%0 : $@callee_owned () -> ()): + %1 = apply %0() : $@callee_owned () -> () + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @address_caller : $@convention(thin) (@in Int) -> () { +// CHECK-NOT: _TTSf1cl15address_closureSi__address_closure_user +sil @address_caller : $@convention(thin) (@in Int) -> () { +bb0(%0 : $*Int): + %1 = function_ref @address_closure : $@convention(thin) (@in Int) -> () + %2 = partial_apply %1(%0) : $@convention(thin) (@in Int) -> () + %3 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () + %4 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> () + %9999 = tuple() + return %9999 : $() +} + +class A {} + +sil hidden [noinline] @closure : $@convention(thin) (@owned A, @owned A) -> () { +bb0(%0 : $A, %1 : $A): + strong_release %1 : $A + strong_release %0 : $A + %4 = tuple () + return %4 : $() +} + +// CHECK-LABEL: sil shared {{.*}} @_TTS{{.*}}use_closure : $@convention(thin) (@owned A) -> () { +sil hidden [noinline] @use_closure : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> () { +bb0(%0 : $@callee_owned (@owned A) -> ()): + %1 = alloc_ref $A + %2 = apply %0(%1) : $@callee_owned (@owned A) -> () + %3 = tuple () + return %3 : $() +} + +// CHECK-LABEL: sil {{.*}} @different_execution_counts +// CHECK: bb0([[ARG:%.*]] : $A +// CHECK: strong_retain [[ARG]] +// CHECK-NOT: partial_apply +// CHECK: [[SPECIALIZED_CLOSURE_USER:%.*]] = function_ref @_TTS{{.*}}use_closure +// CHECK: retain_value [[ARG]] +// CHECK-NOT: partial_apply +// CHECK: integer_literal $Builtin.Int64, 0 +// CHECK: br bb2 + +// CHECK: bb1: +// CHECK: strong_release [[ARG]] +// CHECK: release_value [[ARG]] +// CHECK: return + +// CHECK: bb2({{.*}}): +// Match the partial_apply consume of arg. +// CHECK: retain_value [[ARG]] +// CHECK: apply [[SPECIALIZED_CLOSURE_USER]]([[ARG]]) +// CHECK: cond_br {{.*}}, bb1, bb3 + +sil hidden [noinline] @different_execution_counts : $@convention(thin) (@guaranteed A) -> () { +bb0(%0 : $A): + strong_retain %0 : $A + %2 = function_ref @closure : $@convention(thin) (@owned A, @owned A) -> () + %3 = partial_apply %2(%0) : $@convention(thin) (@owned A, @owned A) -> () + %4 = integer_literal $Builtin.Int64, 0 + %5 = integer_literal $Builtin.Int64, 5 + %6 = integer_literal $Builtin.Int64, 1 + %7 = integer_literal $Builtin.Int1, 0 + %8 = function_ref @use_closure : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> () + br bb2(%4 : $Builtin.Int64) + +bb1: + strong_release %3 : $@callee_owned (@owned A) -> () + %11 = tuple () + return %11 : $() + +bb2(%13 : $Builtin.Int64): + %14 = builtin "sadd_with_overflow_Int64"(%13 : $Builtin.Int64, %6 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %15 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 0 + strong_retain %3 : $@callee_owned (@owned A) -> () + %17 = apply %8(%3) : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> () + %18 = builtin "cmp_eq_Int64"(%15 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1 + cond_br %18, bb1, bb3 + +bb3: + br bb2(%15 : $Builtin.Int64) +} + + +// Ensure that we can specialize and properly mangle functions that take closures with @box arguments. + + +// CHECK-LABEL: sil shared [noinline] @_TTSf1n_cl25closure_with_box_argumentXbBi32____TF4main5innerFTRVs5Int32FS0_T__T_ : $@convention(thin) (@inout Builtin.Int32, @owned @box Builtin.Int32) -> () +// CHECK: bb0 +// CHECK: [[FN:%.*]] = function_ref @closure_with_box_argument +// CHECK: [[PARTIAL:%.*]] = partial_apply [[FN]](%1) +// CHECK: [[ARG:%.*]] = load %0 +// CHECK: apply [[PARTIAL]]([[ARG]]) + +// CHECK-LABEL: {{.*}} @_TF4main5innerFTRVs5Int32FS0_T__T_ +sil hidden [noinline] @_TF4main5innerFTRVs5Int32FS0_T__T_ : $@convention(thin) (@inout Builtin.Int32, @owned @callee_owned (Builtin.Int32) -> ()) -> () { +bb0(%0 : $*Builtin.Int32, %1 : $@callee_owned (Builtin.Int32) -> ()): + strong_retain %1 : $@callee_owned (Builtin.Int32) -> () + %5 = load %0 : $*Builtin.Int32 + %6 = apply %1(%5) : $@callee_owned (Builtin.Int32) -> () + %11 = tuple () + return %11 : $() +} + +// CHECK-LABEL: sil @pass_a_closure +sil @pass_a_closure: $@convention(thin) () -> Builtin.Int32 { +bb0: + %0 = alloc_box $Builtin.Int32, var, name "i" + %1 = integer_literal $Builtin.Int32, 0 + store %1 to %0#1 : $*Builtin.Int32 + %4 = function_ref @closure_with_box_argument : $@convention(thin) (Builtin.Int32, @owned @box Builtin.Int32) -> () + strong_retain %0#0 : $@box Builtin.Int32 + %6 = partial_apply %4(%0#0) : $@convention(thin) (Builtin.Int32, @owned @box Builtin.Int32) -> () + %7 = alloc_stack $Builtin.Int32 + %9 = integer_literal $Builtin.Int32, 1 + store %9 to %7 : $*Builtin.Int32 + %12 = function_ref @_TF4main5innerFTRVs5Int32FS0_T__T_: $@convention(thin) (@inout Builtin.Int32, @owned @callee_owned (Builtin.Int32) -> ()) -> () + strong_retain %6 : $@callee_owned (Builtin.Int32) -> () + %14 = apply %12(%7, %6) : $@convention(thin) (@inout Builtin.Int32, @owned @callee_owned (Builtin.Int32) -> ()) -> () + strong_release %6 : $@callee_owned (Builtin.Int32) -> () + %16 = tuple () + dealloc_stack %7 : $*Builtin.Int32 + %18 = load %0#1 : $*Builtin.Int32 + strong_release %0#0 : $@box Builtin.Int32 + return %18 : $Builtin.Int32 +} + +// CHECK-LABEL: sil shared @closure_with_box_argument +sil shared @closure_with_box_argument : $@convention(thin) (Builtin.Int32, @owned @box Builtin.Int32) -> () { +bb0(%0 : $Builtin.Int32, %1 : $@box Builtin.Int32): + %3 = project_box %1 : $@box Builtin.Int32 + store %0 to %3 : $*Builtin.Int32 + strong_release %1 : $@box Builtin.Int32 + %7 = tuple () + return %7 : $() +} diff --git a/test/SILPasses/closure_specialize_consolidated.sil b/test/SILOptimizer/closure_specialize_consolidated.sil similarity index 93% rename from test/SILPasses/closure_specialize_consolidated.sil rename to test/SILOptimizer/closure_specialize_consolidated.sil index 3b622bbcf2b1a..f46fb01d02f08 100644 --- a/test/SILPasses/closure_specialize_consolidated.sil +++ b/test/SILOptimizer/closure_specialize_consolidated.sil @@ -87,14 +87,14 @@ bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Int32, %2 : $Builtin.NativeObject, return %9999 : $() } -// CHECK-LABEL: sil @_TTSf1cl20large_closure_calleeBoBi32_BoBo_n_n_n_n__owned_apply_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { +// CHECK-LABEL: sil shared @_TTSf1cl20large_closure_calleeBoBi32_BoBo_n_n_n_n__owned_apply_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { // CHECK: bb0 // CHECK: [[FUN:%.*]] = function_ref @large_closure_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () // CHECK: [[CLOSURE:%.*]] = partial_apply [[FUN]]( // CHECK: apply [[CLOSURE]]( // CHECK: release_value [[CLOSURE]] -// CHECK-LABEL: sil @_TTSf1cl20small_closure_callee_n_n_n_n__owned_apply_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () { +// CHECK-LABEL: sil shared @_TTSf1cl20small_closure_callee_n_n_n_n__owned_apply_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () { // CHECK: bb0 // CHECK: [[FUN:%.*]] = function_ref @small_closure_callee // CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[FUN]] : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () to $@callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () @@ -112,14 +112,14 @@ bb0(%0 : $@callee_owned (Builtin.NativeObject, Builtin.Int32, @owned Builtin.Nat return %9999 : $() } -// CHECK-LABEL: sil @_TTSf1cl20large_closure_calleeBoBi32_BoBo_n_n_n_n__guaranteed_apply_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { +// CHECK-LABEL: sil shared @_TTSf1cl20large_closure_calleeBoBi32_BoBo_n_n_n_n__guaranteed_apply_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, @owned Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { // CHECK: bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Int32, %2 : $Builtin.NativeObject, %3 : $Builtin.NativeObject, %4 : $Builtin.NativeObject, %5 : $Builtin.Int32, %6 : $Builtin.NativeObject, %7 : $Builtin.NativeObject): // CHECK: [[FUN:%.*]] = function_ref @large_closure_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject, Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () // CHECK: [[CLOSURE:%.*]] = partial_apply [[FUN]]( // CHECK: apply [[CLOSURE]]( // CHECK: release_value [[CLOSURE]] -// CHECK-LABEL: sil @_TTSf1cl20small_closure_callee_n_n_n_n__guaranteed_apply_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () { +// CHECK-LABEL: sil shared @_TTSf1cl20small_closure_callee_n_n_n_n__guaranteed_apply_callee : $@convention(thin) (Builtin.NativeObject, Builtin.Int32, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () { // CHECK: bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Int32, %2 : $Builtin.NativeObject, %3 : $Builtin.NativeObject): // CHECK: [[FUN:%.*]] = function_ref @small_closure_callee // CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[FUN]] : @@ -262,7 +262,7 @@ bb0(%0 : $Builtin.Int32): unreachable } -sil hidden [fragile] @thunk : $@convention(thin) (@out (), @owned @callee_owned ()->()) -> () { +sil hidden [fragile] @thunk : $@convention(thin) (@out (), @owned @callee_owned () -> ()) -> () { bb0(%0 : $*(), %1 : $@callee_owned () -> ()): apply %1() : $@callee_owned () -> () %9999 = tuple() @@ -279,7 +279,7 @@ bb0: %p1 = partial_apply %f1(%i1) : $@convention(thin) (Builtin.Int32) -> () %f2 = function_ref @thunk : $@convention(thin) (@out (), @owned @callee_owned () -> ()) -> () %s1 = alloc_stack $() - %a1 = apply %f2(%s1#1, %p1) : $@convention(thin) (@out (), @owned @callee_owned () -> ()) -> () - dealloc_stack %s1#0 : $*@local_storage () + %a1 = apply %f2(%s1, %p1) : $@convention(thin) (@out (), @owned @callee_owned () -> ()) -> () + dealloc_stack %s1 : $*() unreachable } diff --git a/test/SILPasses/closure_specialize_simple.sil b/test/SILOptimizer/closure_specialize_simple.sil similarity index 82% rename from test/SILPasses/closure_specialize_simple.sil rename to test/SILOptimizer/closure_specialize_simple.sil index 54df3f01ea3ea..1d0461a89e8d6 100644 --- a/test/SILPasses/closure_specialize_simple.sil +++ b/test/SILOptimizer/closure_specialize_simple.sil @@ -5,7 +5,7 @@ import Swift sil @simple_partial_apply_fun : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 -// CHECK-LABEL: sil @_TTSf1cl24simple_partial_apply_funBi1___simple_partial_apply_caller : $@convention(thin) (Builtin.Int1) -> Builtin.Int1 { +// CHECK-LABEL: sil shared @_TTSf1cl24simple_partial_apply_funBi1___simple_partial_apply_caller : $@convention(thin) (Builtin.Int1) -> Builtin.Int1 { // CHECK: bb0([[CAPTURED_ARG:%.*]] : $Builtin.Int1): // CHECK: [[CLOSED_OVER_FUN:%.*]] = function_ref @simple_partial_apply_fun : // CHECK: [[NEW_PAI:%.*]] = partial_apply [[CLOSED_OVER_FUN]] @@ -16,7 +16,7 @@ bb0(%0 : $@callee_owned (Builtin.Int1) -> Builtin.Int1): bb1: %1 = integer_literal $Builtin.Int1, 0 - // We can not do anything here for now but in the future I think we should try + // We cannot do anything here for now but in the future I think we should try // to handle this in closure specialization potentially. %2 = apply %0(%1) : $@callee_owned (Builtin.Int1) -> Builtin.Int1 strong_release %0 : $@callee_owned (Builtin.Int1) -> Builtin.Int1 @@ -34,7 +34,7 @@ bb0(%0 : $@callee_owned (Builtin.Int1) -> Builtin.Int1, %1 : $@callee_owned (Bui bb1: %2 = integer_literal $Builtin.Int1, 0 - // We can not do anything here for now but in the future I think we should try + // We cannot do anything here for now but in the future I think we should try // to handle this in closure specialization potentially. apply %0(%2) : $@callee_owned (Builtin.Int1) -> Builtin.Int1 strong_release %0 : $@callee_owned (Builtin.Int1) -> Builtin.Int1 @@ -53,7 +53,7 @@ bb0(%0 : $@callee_owned (Builtin.Int1) -> Builtin.Int1): bb1: %1 = integer_literal $Builtin.Int1, 0 - // We can not do anything here for now but in the future I think we should try + // We cannot do anything here for now but in the future I think we should try // to handle this in closure specialization potentially. %2 = apply %0(%1) : $@callee_owned (Builtin.Int1) -> Builtin.Int1 strong_release %0 : $@callee_owned (Builtin.Int1) -> Builtin.Int1 @@ -73,8 +73,8 @@ bb0(%0 : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in bb1: %1 = alloc_stack $Builtin.Int1 %2 = integer_literal $Builtin.Int1, 0 - apply %0(%1#1, %1#1, %2, %1#1) : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () - dealloc_stack %1#0 : $*@local_storage Builtin.Int1 + apply %0(%1, %1, %2, %1) : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () + dealloc_stack %1 : $*Builtin.Int1 cond_br undef, bb1, bb2 bb2: @@ -89,8 +89,8 @@ bb0(%0 : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1) -> ( bb1: %1 = alloc_stack $Builtin.Int1 %2 = integer_literal $Builtin.Int1, 0 - apply %0(%1#1, %1#1, %2) : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1) -> () - dealloc_stack %1#0 : $*@local_storage Builtin.Int1 + apply %0(%1, %1, %2) : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1) -> () + dealloc_stack %1 : $*Builtin.Int1 cond_br undef, bb1, bb2 bb2: @@ -104,8 +104,8 @@ bb0(%0 : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1) -> ()): bb1: %1 = alloc_stack $Builtin.Int1 - apply %0(%1#1, %1#1) : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1) -> () - dealloc_stack %1#0 : $*@local_storage Builtin.Int1 + apply %0(%1, %1) : $@callee_owned (@out Builtin.Int1, @in Builtin.Int1) -> () + dealloc_stack %1 : $*Builtin.Int1 cond_br undef, bb1, bb2 bb2: @@ -119,8 +119,8 @@ bb0(%0 : $@callee_owned (@out Builtin.Int1) -> ()): bb1: %1 = alloc_stack $Builtin.Int1 - apply %0(%1#1) : $@callee_owned (@out Builtin.Int1) -> () - dealloc_stack %1#0 : $*@local_storage Builtin.Int1 + apply %0(%1) : $@callee_owned (@out Builtin.Int1) -> () + dealloc_stack %1 : $*Builtin.Int1 cond_br undef, bb1, bb2 bb2: @@ -189,10 +189,10 @@ bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): %10 = function_ref @indirect_parameter_partial_apply_fun : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () %11 = partial_apply %10() : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () - %12 = partial_apply %10(%9#1) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () - %13 = partial_apply %10(%1, %9#1) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () - %14 = partial_apply %10(%9#1, %1, %9#1) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () - %15 = partial_apply %10(%9#1, %9#1, %1, %9#1) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () + %12 = partial_apply %10(%9) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () + %13 = partial_apply %10(%1, %9) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () + %14 = partial_apply %10(%9, %1, %9) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () + %15 = partial_apply %10(%9, %9, %1, %9) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () %16 = function_ref @indirect_parameter_partial_apply_caller1 : $@convention(thin) (@callee_owned (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> ()) -> () %17 = function_ref @indirect_parameter_partial_apply_caller2 : $@convention(thin) (@callee_owned (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1) -> ()) -> () @@ -210,13 +210,13 @@ bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): %21 = alloc_stack $(Builtin.Int1, Builtin.Int1) %22 = function_ref @indirect_parameter_partial_apply_caller6 : $@convention(thin) (@out Builtin.Int1, @callee_owned () -> ()) -> () %23 = function_ref @indirect_parameter_partial_apply_caller7 : $@convention(thin) (@out (Builtin.Int1, Builtin.Int1), @callee_owned () -> ()) -> () - %24 = partial_apply %10(%9#1, %9#1, %1, %9#1) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () - %25 = partial_apply %10(%9#1, %9#1, %1, %9#1) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () - apply %22(%9#1, %24) : $@convention(thin) (@out Builtin.Int1, @callee_owned () -> ()) -> () - apply %23(%21#1, %25) : $@convention(thin) (@out (Builtin.Int1, Builtin.Int1), @callee_owned () -> ()) -> () + %24 = partial_apply %10(%9, %9, %1, %9) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () + %25 = partial_apply %10(%9, %9, %1, %9) : $@convention(thin) (@out Builtin.Int1, @in Builtin.Int1, Builtin.Int1, @in Builtin.Int1) -> () + apply %22(%9, %24) : $@convention(thin) (@out Builtin.Int1, @callee_owned () -> ()) -> () + apply %23(%21, %25) : $@convention(thin) (@out (Builtin.Int1, Builtin.Int1), @callee_owned () -> ()) -> () - dealloc_stack %21#0 : $*@local_storage (Builtin.Int1, Builtin.Int1) - dealloc_stack %9#0 : $*@local_storage Builtin.Int1 + dealloc_stack %21 : $*(Builtin.Int1, Builtin.Int1) + dealloc_stack %9 : $*Builtin.Int1 %26 = partial_apply %2(%0) : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 %27 = partial_apply %2(%0) : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 diff --git a/test/SILPasses/constant_propagation.sil b/test/SILOptimizer/constant_propagation.sil similarity index 100% rename from test/SILPasses/constant_propagation.sil rename to test/SILOptimizer/constant_propagation.sil diff --git a/test/SILPasses/constant_propagation2.sil b/test/SILOptimizer/constant_propagation2.sil similarity index 100% rename from test/SILPasses/constant_propagation2.sil rename to test/SILOptimizer/constant_propagation2.sil diff --git a/test/SILPasses/constant_propagation_castopt_analysis_invalidation.sil b/test/SILOptimizer/constant_propagation_castopt_analysis_invalidation.sil similarity index 100% rename from test/SILPasses/constant_propagation_castopt_analysis_invalidation.sil rename to test/SILOptimizer/constant_propagation_castopt_analysis_invalidation.sil diff --git a/test/SILPasses/constant_propagation_diagnostics.swift b/test/SILOptimizer/constant_propagation_diagnostics.swift similarity index 100% rename from test/SILPasses/constant_propagation_diagnostics.swift rename to test/SILOptimizer/constant_propagation_diagnostics.swift diff --git a/test/SILOptimizer/copyforward.sil b/test/SILOptimizer/copyforward.sil new file mode 100644 index 0000000000000..101d7f6f7d55d --- /dev/null +++ b/test/SILOptimizer/copyforward.sil @@ -0,0 +1,535 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -copy-forwarding -enable-copyforwarding -enable-destroyhoisting | FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +class AClass {} +sil @f_in : $@convention(thin) (@in T) -> () +sil @f_in_guaranteed : $@convention(thin) (@in_guaranteed T) -> () +sil @f_out : $@convention(thin) (@out T) -> () +sil @f_owned : $@convention(thin) (@owned T) -> () + +protocol P { + init(_ i : Int32) + mutating func poke() +}; + +// CHECK-LABEL: nrvo +// CHECK-NOT: copy_addr +// CHECK: return +sil hidden @nrvo : $@convention(thin) (@out T, Bool) -> () { +bb0(%0 : $*T, %1 : $Bool): + %2 = alloc_stack $T, var, name "ro" // users: %9, %15, %17, %19 + debug_value_addr %0 : $*T + debug_value_addr %2 : $*T + %3 = struct_extract %1 : $Bool, #Bool._value // user: %4 + cond_br %3, bb1, bb2 // id: %4 + +bb1: // Preds: bb0 + %5 = metatype $@thick T.Type // user: %9 + %6 = witness_method $T, #P.init!allocator.1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () // user: %9 + %7 = integer_literal $Builtin.Int32, 10 // user: %8 + %8 = struct $Int32 (%7 : $Builtin.Int32) // user: %9 + %9 = apply %6(%2, %8, %5) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () + br bb3 // id: %10 + +bb2: // Preds: bb0 + %11 = metatype $@thick T.Type // user: %15 + %12 = witness_method $T, #P.init!allocator.1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () // user: %15 + %13 = integer_literal $Builtin.Int32, 1 // user: %14 + %14 = struct $Int32 (%13 : $Builtin.Int32) // user: %15 + %15 = apply %12(%2, %14, %11) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () + br bb3 // id: %16 + +bb3: // Preds: bb1 bb2 + copy_addr [take] %2 to [initialization] %0 : $*T // id: %17 + %18 = tuple () // user: %20 + debug_value_addr %0 : $*T + debug_value_addr %2 : $*T + dealloc_stack %2 : $*T // id: %19 + return %18 : $() // id: %20 +} + +//CHECK-LABEL: forward_init +//CHECK-NOT: copy_addr +//CHECK-NOT: destroy_addr +//CHECK: return +sil hidden @forward_init : $@convention(thin) (@in T) -> () { +bb0(%0 : $*T): + debug_value_addr %0 : $*T + %l1 = alloc_stack $T + copy_addr %0 to [initialization] %l1 : $*T + %f1 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + %c1 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + debug_value_addr %l1 : $*T + dealloc_stack %l1 : $*T + debug_value_addr %0 : $*T + destroy_addr %0 : $*T + %r1 = tuple () + return %r1 : $() +} + +//CHECK-LABEL: forward_noinit +//CHECK-NOT: copy_addr +//CHECK: destroy_addr +//CHECK: return +sil hidden @forward_noinit : $@convention(thin) (@in T) -> () { +bb0(%0 : $*T): + debug_value_addr %0 : $*T + %l1 = alloc_stack $T + %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + %c1 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + copy_addr %0 to %l1 : $*T + debug_value_addr %l1 : $*T + debug_value_addr %0 : $*T + %f2 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + %c2 = apply %f2(%l1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %l1 : $*T + destroy_addr %0 : $*T + %r1 = tuple () + return %r1 : $() +} + +//CHECK-LABEL: forward_takeinit +//CHECK-NOT: copy_addr +//CHECK-NOT: destroy_addr +//CHECK: return +sil hidden @forward_takeinit : $@convention(thin) (@in T) -> () { +bb0(%0 : $*T): + debug_value_addr %0 : $*T + %l1 = alloc_stack $T + copy_addr [take] %0 to [initialization] %l1 : $*T + %f1 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + %c1 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + debug_value_addr %0 : $*T + debug_value_addr %l1 : $*T + dealloc_stack %l1 : $*T + %r1 = tuple () + return %r1 : $() +} + +//CHECK-LABEL: forward_takenoinit +//CHECK-NOT: copy_addr +//CHECK: destroy_addr +//CHECK: return +sil hidden @forward_takenoinit : $@convention(thin) (@in T) -> () { +bb0(%0 : $*T): + debug_value_addr %0 : $*T + %l1 = alloc_stack $T + %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + %c1 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + copy_addr [take] %0 to %l1 : $*T + %f2 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + %c2 = apply %f2(%l1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + debug_value_addr %0 : $*T + debug_value_addr %l1 : $*T + dealloc_stack %l1 : $*T + %r1 = tuple () + return %r1 : $() +} + +//CHECK-LABEL: backward_init +//CHECK-NOT: copy_addr +//CHECK-NOT: destroy_addr +//CHECK: return +sil hidden @backward_init : $@convention(thin) (@out T) -> () { +bb0(%0 : $*T): + %l1 = alloc_stack $T + %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + %c1 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + debug_value_addr %0 : $*T + debug_value_addr %l1 : $*T + copy_addr %l1 to [initialization] %0 : $*T + debug_value_addr %0 : $*T + debug_value_addr %l1 : $*T + destroy_addr %l1 : $*T + dealloc_stack %l1 : $*T + %t = tuple () + return %t : $() +} + +//CHECK-LABEL: backward_noinit +//CHECK: copy_addr +//CHECK: destroy_addr +//CHECK: return +sil hidden @backward_noinit : $@convention(thin) (@out T) -> () { +bb0(%0 : $*T): + %l1 = alloc_stack $T + %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + %c1 = apply %f1(%0) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + %c2 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + copy_addr %l1 to %0 : $*T + destroy_addr %l1 : $*T + dealloc_stack %l1 : $*T + %t = tuple () + return %t : $() +} + + +//CHECK-LABEL: backward_takeinit +//CHECK-NOT: copy_addr +//CHECK-NOT: destroy_addr +//CHECK: return +sil hidden @backward_takeinit : $@convention(thin) (@out T) -> () { +bb0(%0 : $*T): + %l1 = alloc_stack $T + %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + %c1 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + debug_value_addr %0 : $*T + debug_value_addr %l1 : $*T + copy_addr [take] %l1 to [initialization] %0 : $*T + debug_value_addr %0 : $*T + debug_value_addr %l1 : $*T + dealloc_stack %l1 : $*T + %t = tuple () + return %t : $() +} + +//CHECK-LABEL: backward_takenoinit +//CHECK: copy_addr +//CHECK-NOT: destroy_addr +//CHECK: return +sil hidden @backward_takenoinit : $@convention(thin) (@out T) -> () { +bb0(%0 : $*T): + %l1 = alloc_stack $T + %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + %c1 = apply %f1(%0) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + %c2 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + copy_addr [take] %l1 to %0 : $*T + dealloc_stack %l1 : $*T + %t = tuple () + return %t : $() +} + +//CHECK-LABEL: branch +//CHECK-NOT: copy_addr +//CHECK: return +sil hidden @branch : $@convention(thin) (@in T, Bool) -> () { +bb0(%0 : $*T, %1 : $Bool): + %2 = struct_extract %1 : $Bool, #Bool._value // user: %3 + cond_br %2, bb1, bb2 // id: %3 + +bb1: // Preds: bb0 + %4 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %7 + %5 = alloc_stack $T // users: %6, %7, %8 + copy_addr %0 to [initialization] %5 : $*T // id: %6 + %7 = apply %4(%5) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %5 : $*T // id: %8 + br bb2 // id: %9 + +bb2: // Preds: bb0 bb1 + destroy_addr %0 : $*T // id: %10 + %11 = tuple () // user: %12 + return %11 : $() // id: %12 +} + +enum A { + case Val(T) + init(_ val: T) +} + +sil [transparent] @_TFO8enuminit1A3ValU__fMGS0_Q__FQ_GS0_Q__ : $@convention(thin) (@out A, @in T, @thin A.Type) -> () + +//CHECK-LABEL: enuminit +//CHECK-NOT: copy_addr +//CHECK: return +sil @enuminit : $@convention(thin) (@out A, @in T, @thin A.Type) -> () { +bb0(%0 : $*A, %1 : $*T, %2 : $@thin A.Type): + %3 = alloc_stack $A, var, name "sf" // users: %10, %14, %16 + // function_ref enuminit.A.Val (enuminit.A.Type)(A) -> enuminit.A + %4 = function_ref @_TFO8enuminit1A3ValU__fMGS0_Q__FQ_GS0_Q__ : $@convention(thin) <τ_0_0> (@out A<τ_0_0>, @in τ_0_0, @thin A<τ_0_0>.Type) -> () // user: %9 + %5 = metatype $@thin A.Type // user: %9 + %6 = alloc_stack $T // users: %7, %9, %12 + copy_addr %1 to [initialization] %6 : $*T // id: %7 + %8 = alloc_stack $A // users: %9, %10, %11 + %9 = apply %4(%8, %6, %5) : $@convention(thin) <τ_0_0> (@out A<τ_0_0>, @in τ_0_0, @thin A<τ_0_0>.Type) -> () + copy_addr [take] %8 to [initialization] %3 : $*A // id: %10 + dealloc_stack %8 : $*A // id: %11 + dealloc_stack %6 : $*T // id: %12 + destroy_addr %1 : $*T // id: %13 + copy_addr [take] %3 to [initialization] %0 : $*A // id: %14 + %15 = tuple () // user: %17 + dealloc_stack %3 : $*A // id: %16 + return %15 : $() // id: %17 +} + +//CHECK-LABEL: make_addronly +//CHECK-NOT: copy_addr +//CHECK: return +sil hidden @make_addronly : $@convention(thin) (@out T) -> () { +bb0(%0 : $*T): + %1 = alloc_stack $T, let, name "t" // users: %3, %4, %5 + %2 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () // user: %3 + %3 = apply %2(%1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + copy_addr [take] %1 to [initialization] %0 : $*T // id: %4 + dealloc_stack %1 : $*T // id: %5 + %6 = tuple () // user: %7 + return %6 : $() // id: %7 +} + +sil @_TFSq4SomeU__fMGSqQ__FQ_GSqQ__ : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0, @thin Optional<τ_0_0>.Type) -> () + +sil @_TFsoi2neU__FTGSqQ__Vs26_OptionalNilComparisonType_Sb : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, _OptionalNilComparisonType) -> Bool + +//CHECK-LABEL: option_init +//CHECK: alloc_stack +//CHECK: alloc_stack +//CHECK: alloc_stack +//CHECK: copy_addr +//CHECK: copy_addr +//CHECK-NOT: copy_addr +//CHECK: alloc_stack +//CHECK: alloc_stack +//CHECK: copy_addr +//CHECK-NOT: copy_addr +//CHECK: alloc_stack +//CHECK-NOT: copy_addr +//CHECK: copy_addr +//CHECK-NOT: copy_addr +//CHECK: alloc_stack +//CHECK-NOT: copy_addr +//CHECK: return +sil hidden @option_init : $@convention(thin) (@in AnyObject) -> () { +bb0(%0 : $*AnyObject): + %g0 = alloc_stack $GeneratorOfOne // 831 + %s0 = struct_element_addr %g0 : $*GeneratorOfOne, #GeneratorOfOne.elements + + %l0 = alloc_stack $Optional + // function_ref Swift.Optional.Some (Swift.Optional.Type)(A) -> Swift.Optional + %f0 = function_ref @_TFSq4SomeU__fMGSqQ__FQ_GSqQ__ : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0, @thin Optional<τ_0_0>.Type) -> () + %t0 = metatype $@thin Optional.Type + %i0 = apply %f0(%l0, %0, %t0) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0, @thin Optional<τ_0_0>.Type) -> () + + %g1 = alloc_stack $GeneratorOfOne // 850 + %s1 = struct_element_addr %g1 : $*GeneratorOfOne, #GeneratorOfOne.elements + // We can't backward propagate this yet because we can't analyze struct_element_addr copy dest. + copy_addr [take] %l0 to [initialization] %s1 : $*Optional + // We ignore this copy because its Def is used by struct_element_addr + copy_addr [take] %g1 to [initialization] %g0 : $*GeneratorOfOne + + %l1 = alloc_stack $Optional // 869 + + %l2 = alloc_stack $Optional // 873 + // We ignore this copy because its Def is used by struct_element_addr + copy_addr %s0 to [initialization] %l2 : $*Optional + + %l3 = alloc_stack $Optional // 877 + %o1 = enum $Optional, #Optional.None!enumelt + store %o1 to %l3 : $*Optional + // We can't backward propagate this yet because we can't analyze struct_element_addr copy dest. + copy_addr [take] %l3 to %s0 : $*Optional + dealloc_stack %l3 : $*Optional + // We can't forward propagate this because l2 is deallocated, but we can backward propagate l1. + copy_addr [take] %l2 to [initialization] %l1 : $*Optional + dealloc_stack %l2 : $*Optional + %l4 = alloc_stack $Optional // 889 + %o2 = load %l1 : $*Optional + store %o2 to %l4 : $*Optional + %s5 = struct $_OptionalNilComparisonType () + retain_value %o2 : $Optional + + %f1 = function_ref @_TFsoi2neU__FTGSqQ__Vs26_OptionalNilComparisonType_Sb : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, _OptionalNilComparisonType) -> Bool + %c5 = apply %f1(%l4, %s5) : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, _OptionalNilComparisonType) -> Bool + dealloc_stack %l4 : $*Optional + destroy_addr %l1 : $*Optional + dealloc_stack %l1 : $*Optional + dealloc_stack %g1 : $*GeneratorOfOne + dealloc_stack %l0 : $*Optional + destroy_addr %g0 : $*GeneratorOfOne + dealloc_stack %g0 : $*GeneratorOfOne + %p0 = tuple () + return %p0 : $() +} + +// Premature release of optional NSData +// after optimization +// +// Check that destroy is not hoisted above a retain of a transitively +// referenced object. +// +// CHECK-LABEL: load_nontrivial +// CHECK: load %0 : $*Optional +// CHECK-NOT: destroy_addr +// CHECK: unchecked_enum_data %{{.*}} : $Optional +// CHECK-NOT: destroy_addr +// CHECK: strong_retain %{{.*}} : $AClass +// CHECK: destroy_addr %0 +sil hidden @load_nontrivial : $@convention(thin) () -> () { +bb0: + %v0 = alloc_stack $Optional + %v1 = alloc_stack $Optional + + %f0 = function_ref @f_out : $@convention(thin) (@out A) -> () + %c0 = apply %f0(%v0) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () + + copy_addr %v0 to [initialization] %v1 : $*Optional + + %f1 = function_ref @f_in : $@convention(thin) (@in A) -> () + %c1 = apply %f1(%v1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + + dealloc_stack %v1 : $*Optional + %l1 = load %v0 : $*Optional + %d1 = unchecked_enum_data %l1 : $Optional, #Optional.Some!enumelt.1 + %f2 = function_ref @f_owned : $@convention(thin) (@owned A) -> () + %c2 = apply %f2(%d1) : $@convention(thin) <τ_0_0> (@owned τ_0_0) -> () + strong_retain %d1 : $AClass + destroy_addr %v0 : $*Optional + %34 = tuple () + dealloc_stack %v0 : $*Optional + return %34 : $() +} + +// CHECK-LABEL: sil @nil_comparison +// CHECK: alloc_stack +// CHECK-NOT: copy_addr +// CHECK-NOT destroy_addr +// CHECK: switch_enum_addr %0 +// CHECK: [[D:%.*]] = unchecked_take_enum_data_addr %0 +// CHECK: destroy_addr [[D]] +// CHECK: return +sil @nil_comparison : $@convention(thin) (@in Optional) -> Bool { +bb0(%0 : $*Optional): + %2 = alloc_stack $Optional + copy_addr %0 to [initialization] %2 : $*Optional + destroy_addr %0 : $*Optional + switch_enum_addr %2 : $*Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb2 + +bb1: + %6 = unchecked_take_enum_data_addr %2 : $*Optional, #Optional.Some!enumelt.1 + destroy_addr %6 : $*T + %8 = integer_literal $Builtin.Int1, -1 + br bb3(%8 : $Builtin.Int1) + +bb2: + %10 = integer_literal $Builtin.Int1, 0 + br bb3(%10 : $Builtin.Int1) + +bb3(%12 : $Builtin.Int1): + %13 = struct $Bool (%12 : $Builtin.Int1) + dealloc_stack %2 : $*Optional + return %13 : $Bool +} + +sil @use: $@convention(thin) (@inout T) -> () + +// We currently don't handle reasoning about multiple copy_addr instructions at +// once. With the current logic we must not optimize this case (we would have to +// prove that we can replace both copy_addr to be able to optimize). + +// CHECK-LABEL: sil @not_dominated_uses +// CHECK: alloc_stack +// CHECK: cond_br +// CHECK: bb1 +// CHECK: copy_addr +// CHECK: apply +// CHECK: br bb3 +// CHECK: bb2 +// CHECK: copy_addr +// CHECK: apply +// CHECK: br bb3 +// CHECK: bb3 +// CHECK: apply +// CHECK: destroy_addr + +sil @not_dominated_uses: $@convention(thin) (@in Optional, @in Optional, Bool) -> () { +bb0(%0 : $*Optional, %1 : $*Optional, %3 : $Bool): + %4 = alloc_stack $Optional + %5 = struct_extract %3 : $Bool, #Bool._value + %f = function_ref @use : $@convention(thin) (@inout T2) -> () + cond_br %5, bb1, bb2 + +bb1: + copy_addr [take] %0 to [initialization] %4 : $*Optional + %r1 = apply %f>(%4) : $@convention(thin) (@inout T2) -> () + br bb3 + +bb2: + copy_addr [take] %1 to [initialization] %4 : $*Optional + %r2 = apply %f>(%4) : $@convention(thin) (@inout T2) -> () + br bb3 + +bb3: + %r3 = apply %f>(%4) : $@convention(thin) (@inout T2) -> () + destroy_addr %4 : $*Optional + dealloc_stack %4 : $*Optional + %13 = tuple() + return %13 : $() +} + +//CHECK-LABEL: test_in_guaranteed +//CHECK: copy_addr %1 to [initialization] +//CHECK-NOT: copy_addr +//CHECK-NOT: destroy_addr +//CHECK: return +sil hidden @test_in_guaranteed : $@convention(thin) (@out T, @in T) -> () { +bb0(%0 : $*T, %1 : $*T): + %l1 = alloc_stack $T + copy_addr %1 to [initialization] %l1 : $*T + %f1 = function_ref @f_in_guaranteed : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> () + %c2 = apply %f1(%l1) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> () + copy_addr %l1 to [initialization] %0 : $*T + destroy_addr %l1 : $*T + dealloc_stack %l1 : $*T + %t = tuple () + return %t : $() +} + +// CHECK-LABEL: forward_unchecked_ref_cast_addr +// CHECK: unchecked_ref_cast_addr +// CHECK-NOT: copy_addr +// CHECK: return +sil hidden @forward_unchecked_ref_cast_addr : $@convention(thin) (@out AClass, @in AnyObject) -> () { +bb0(%0 : $*AClass, %1 : $*AnyObject): + %3 = alloc_stack $AnyObject // user: %10 + %4 = alloc_stack $AnyObject // user: %9 + %5 = alloc_stack $AClass // users: %6, %7, %8 + unchecked_ref_cast_addr AnyObject in %1 : $*AnyObject to AClass in %5 : $*AClass // id: %6 + copy_addr [take] %5 to [initialization] %0 : $*AClass // id: %7 + dealloc_stack %5 : $*AClass // id: %8 + dealloc_stack %4 : $*AnyObject // id: %9 + dealloc_stack %3 : $*AnyObject // id: %10 + %11 = tuple () // user: %12 + return %11 : $() // id: %12 +} + +sil @element_use : $@convention(thin) (@inout P) -> () + +// CHECK-LABEL: backward_propagate_enum_init +// CHECK-NOT: copy_addr +// CHECK: %[[TMP:.*]] = init_enum_data_addr %0 : $*Optional

+// CHECK: copy_addr %1 to [initialization] %[[TMP]] +// CHECK-NOT: copy_addr +sil @backward_propagate_enum_init : $@convention(thin) (@out Optional

, @inout P) -> () { +bb0(%0 : $*Optional

, %1 : $*P): + %2 = alloc_stack $P + copy_addr %1 to [initialization] %2 : $*P + %3 = function_ref @element_use : $@convention(thin) (@inout P) -> () + %4 = apply %3(%1) : $@convention(thin) (@inout P) -> () + %5 = init_enum_data_addr %0 : $*Optional

, #Optional.Some!enumelt.1 + copy_addr %2 to [initialization] %5 : $*P + inject_enum_addr %0 : $*Optional

, #Optional.Some!enumelt.1 + destroy_addr %2 : $*P + dealloc_stack %2 : $*P + %27 = tuple () + return %27 : $() +} + +// CHECK-LABEL: backward_propagate_exi_init +// CHECK-NOT: copy_addr +// CHECK: %[[TMP:.*]] = init_existential_addr %0 : $*P, $T +// CHECK: copy_addr %1 to [initialization] %[[TMP]] : $*T +// CHECK-NOT: copy_addr +sil @backward_propagate_exi_init : $@convention(thin) (@out P, @inout T) -> () { +bb0(%0 : $*P, %1 : $*T): + %2 = alloc_stack $T + copy_addr %1 to [initialization] %2 : $*T + %3 = witness_method $T, #P.poke!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@inout τ_0_0) -> () + %4 = apply %3(%1) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@inout τ_0_0) -> () + %5 = init_existential_addr %0 : $*P, $T + copy_addr [take] %2 to [initialization] %5 : $*T + dealloc_stack %2 : $*T + %27 = tuple () + return %27 : $() +} diff --git a/test/SILPasses/cowarray_opt.sil b/test/SILOptimizer/cowarray_opt.sil similarity index 86% rename from test/SILPasses/cowarray_opt.sil rename to test/SILOptimizer/cowarray_opt.sil index 0c0589e1250c9..6f992ee23cb14 100644 --- a/test/SILPasses/cowarray_opt.sil +++ b/test/SILOptimizer/cowarray_opt.sil @@ -56,6 +56,7 @@ sil @unknown : $@convention(thin) () -> () // CHECK-NOT: apply [[FUN]] sil @simple_hoist : $@convention(thin) (@inout MyArray, @inout Builtin.Int1) -> () { bb0(%0 : $*MyArray, %1 : $*Builtin.Int1): + debug_value_addr %0 : $*MyArray %2 = load %0 : $*MyArray br bb1 @@ -1102,3 +1103,106 @@ bb2: %7 = tuple() return %7 : $() } + + +sil [_semantics "array.props.isNativeTypeChecked"] @hoistableIsNativeTypeChecked : $@convention(method) (@guaranteed My2dArray>) -> Bool +sil [_semantics "array.check_subscript"] @checkSubscript3 : $@convention(method) (MyInt, Bool, @guaranteed My2dArray>) -> _DependenceToken +sil [_semantics "array.get_element"] @getElement3 : $@convention(method) (@out My2dArray, MyInt, Bool, _DependenceToken, @guaranteed My2dArray>) -> () +sil [_semantics "array.props.isNativeTypeChecked"] @hoistableIsNativeTypeChecked2 : $@convention(method) (@guaranteed My2dArray) -> Bool +sil [_semantics "array.check_subscript"] @checkSubscript4 : $@convention(method) (MyInt, Bool, @guaranteed My2dArray) -> _DependenceToken +sil [_semantics "array.get_element"] @getElement4 : $@convention(method) (@out MyInt, MyInt, Bool, _DependenceToken, @guaranteed My2dArray) -> () +sil [_semantics "array.make_mutable"] @makeMutable3 : $@convention(method) (@inout My2dArray>) -> () +sil [_semantics "array.get_element_address"] @getElementAddress3 : $@convention(method) (MyInt, @guaranteed My2dArray>) -> UnsafeMutablePointer> +sil [_semantics "array.make_mutable"] @makeMutable4 : $@convention(method) (@inout My2dArray) -> () +sil [_semantics "array.get_element_address"] @getElementAddress4 : $@convention(method) (MyInt, @guaranteed My2dArray) -> UnsafeMutablePointer + +// CHECK-LABEL: sil @hoist2DArray_2 +// CHECK: bb0 +// CHECK: apply {{.*}} : $@convention(method) (@inout My2dArray>) -> () +// CHECK: apply {{.*}} : $@convention(method) (@inout My2dArray) -> () +// CHECK: br bb2 +// CHECK: bb1 +// CHECK: return +// CHECK: bb2 +// CHECK-NOT: apply {{.*}} : $@convention(method) (@inout My2dArray>) -> () +// CHECK-NOT: apply {{.*}} : $@convention(method) (@inout My2dArray) -> () +// CHECK: cond_br + +sil @hoist2DArray_2 : $@convention(thin) (@inout My2dArray>, MyInt) -> () { +bb0(%0 : $*My2dArray>, %1 : $MyInt): + %4 = integer_literal $Builtin.Int64, 0 + %5 = integer_literal $Builtin.Int64, 1024 + %6 = integer_literal $Builtin.Int64, 1 + %7 = integer_literal $Builtin.Int1, 0 + %9 = function_ref @hoistableIsNativeTypeChecked : $@convention(method) (@guaranteed My2dArray>) -> Bool + %10 = function_ref @checkSubscript3 : $@convention(method) (MyInt, Bool, @guaranteed My2dArray>) -> _DependenceToken + %11 = function_ref @getElement3 : $@convention(method) (@out My2dArray, MyInt, Bool, _DependenceToken, @guaranteed My2dArray>) -> () + %12 = function_ref @hoistableIsNativeTypeChecked2 : $@convention(method) (@guaranteed My2dArray) -> Bool + %13 = function_ref @checkSubscript4 : $@convention(method) (MyInt, Bool, @guaranteed My2dArray) -> _DependenceToken + %14 = function_ref @getElement4 : $@convention(method) (@out MyInt, MyInt, Bool, _DependenceToken, @guaranteed My2dArray) -> () + %15 = integer_literal $Builtin.Int1, -1 + %18 = function_ref @makeMutable3 : $@convention(method) (@inout My2dArray>) -> () + %20 = struct $Bool (%15 : $Builtin.Int1) + %21 = function_ref @getElementAddress3 : $@convention(method) (MyInt, @guaranteed My2dArray>) -> UnsafeMutablePointer> + %22 = function_ref @makeMutable4 : $@convention(method) (@inout My2dArray) -> () + %23 = function_ref @getElementAddress4 : $@convention(method) (MyInt, @guaranteed My2dArray) -> UnsafeMutablePointer + br bb2(%4 : $Builtin.Int64) + +bb1: + %25 = tuple () + return %25 : $() + +bb2(%27 : $Builtin.Int64): + %28 = struct $MyInt (%27 : $Builtin.Int64) + %29 = builtin "sadd_with_overflow_Int64"(%27 : $Builtin.Int64, %6 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %30 = tuple_extract %29 : $(Builtin.Int64, Builtin.Int1), 0 + %32 = load %0 : $*My2dArray> + %33 = alloc_stack $My2dArray + %35 = apply %9(%32) : $@convention(method) (@guaranteed My2dArray>) -> Bool + %37 = apply %10(%1, %35, %32) : $@convention(method) (MyInt, Bool, @guaranteed My2dArray>) -> _DependenceToken + %39 = apply %11(%33, %1, %35, %37, %32) : $@convention(method) (@out My2dArray, MyInt, Bool, _DependenceToken, @guaranteed My2dArray>) -> () + %40 = load %33 : $*My2dArray + %41 = alloc_stack $MyInt + %44 = apply %12(%40) : $@convention(method) (@guaranteed My2dArray) -> Bool + %46 = apply %13(%28, %44, %40) : $@convention(method) (MyInt, Bool, @guaranteed My2dArray) -> _DependenceToken + %48 = apply %14(%41, %28, %44, %46, %40) : $@convention(method) (@out MyInt, MyInt, Bool, _DependenceToken, @guaranteed My2dArray) -> () + %49 = struct_extract %40 : $My2dArray, #My2dArray._buffer + %50 = struct_extract %49 : $_My2dArrayBuffer, #_My2dArrayBuffer._storage + %51 = struct_extract %50 : $_MyBridgeStorage, #_MyBridgeStorage.rawValue + strong_release %51 : $Builtin.BridgeObject + %53 = struct_element_addr %41 : $*MyInt, #MyInt._value + %54 = load %53 : $*Builtin.Int64 + %55 = builtin "sadd_with_overflow_Int64"(%54 : $Builtin.Int64, %6 : $Builtin.Int64, %15 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %56 = tuple_extract %55 : $(Builtin.Int64, Builtin.Int1), 0 + %57 = tuple_extract %55 : $(Builtin.Int64, Builtin.Int1), 1 + cond_fail %57 : $Builtin.Int1 + %59 = struct $MyInt (%56 : $Builtin.Int64) + %60 = apply %18(%0) : $@convention(method) (@inout My2dArray>) -> () + %61 = load %0 : $*My2dArray> + %63 = apply %21(%1, %61) : $@convention(method) (MyInt, @guaranteed My2dArray>) -> UnsafeMutablePointer> + %65 = struct_extract %61 : $My2dArray>, #My2dArray._buffer + %66 = struct_extract %65 : $_My2dArrayBuffer>, #_My2dArrayBuffer._storage + %67 = struct_extract %66 : $_MyBridgeStorage, #_MyBridgeStorage.rawValue + %72 = unchecked_ref_cast %67 : $Builtin.BridgeObject to $Builtin.NativeObject + %73 = enum $Optional, #Optional.Some!enumelt.1, %72 : $Builtin.NativeObject + %74 = struct_extract %63 : $UnsafeMutablePointer>, #UnsafeMutablePointer._rawValue + %75 = pointer_to_address %74 : $Builtin.RawPointer to $*My2dArray + %76 = mark_dependence %75 : $*My2dArray on %73 : $Optional + %79 = apply %22(%76) : $@convention(method) (@inout My2dArray) -> () + %80 = load %76 : $*My2dArray + %83 = apply %13(%28, %20, %80) : $@convention(method) (MyInt, Bool, @guaranteed My2dArray) -> _DependenceToken + %84 = apply %23(%28, %80) : $@convention(method) (MyInt, @guaranteed My2dArray) -> UnsafeMutablePointer + %86 = struct_extract %80 : $My2dArray, #My2dArray._buffer + %87 = struct_extract %86 : $_My2dArrayBuffer, #_My2dArrayBuffer._storage + %88 = struct_extract %87 : $_MyBridgeStorage, #_MyBridgeStorage.rawValue + %93 = unchecked_ref_cast %88 : $Builtin.BridgeObject to $Builtin.NativeObject + %94 = enum $Optional, #Optional.Some!enumelt.1, %93 : $Builtin.NativeObject + %95 = struct_extract %84 : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue + %96 = pointer_to_address %95 : $Builtin.RawPointer to $*MyInt + %97 = mark_dependence %96 : $*MyInt on %94 : $Optional + store %59 to %97 : $*MyInt + dealloc_stack %41 : $*MyInt + dealloc_stack %33 : $*My2dArray + %101 = builtin "cmp_eq_Int64"(%30 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1 + cond_br %101, bb1, bb2(%30 : $Builtin.Int64) +} diff --git a/test/SILPasses/cropoverflow.sil b/test/SILOptimizer/cropoverflow.sil similarity index 96% rename from test/SILPasses/cropoverflow.sil rename to test/SILOptimizer/cropoverflow.sil index 8d8d45a5eb48f..d27cd376fb2c0 100644 --- a/test/SILPasses/cropoverflow.sil +++ b/test/SILOptimizer/cropoverflow.sil @@ -223,7 +223,7 @@ bb0(%0 : $Int64): %24 = integer_literal $Builtin.Int64, 10 // user: %25 %25 = builtin "ssub_with_overflow_Int64"(%2 : $Builtin.Int64, %24 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // user: %26 %26 = tuple_extract %25 : $(Builtin.Int64, Builtin.Int1), 1 // user: %27 -// Keep this condfail because it is not in the guraded range. +// Keep this condfail because it is not in the guarded range. // CHECK: cond_fail cond_fail %26 : $Builtin.Int1 // id: %27 %28 = apply %7() : $@convention(thin) () -> () @@ -712,3 +712,34 @@ bb3: // Preds: bb1 bb2 return %3 : $() // id: %17 } +// Check that we are not crashing on arithmetic of different kinds +// that makes formulas of different types. +sil hidden @mixed_types : $@convention(thin) (Int8) -> () { +bb0(%0 : $Int8): + %1 = integer_literal $Builtin.Int8, -128 + %2 = struct_extract %0 : $Int8, #Int8._value + %3 = integer_literal $Builtin.Int1, -1 + %4 = builtin "smul_with_overflow_Int8"(%2 : $Builtin.Int8, %1 : $Builtin.Int8, %3 : $Builtin.Int1) : $(Builtin.Int8, Builtin.Int1) + %5 = tuple_extract %4 : $(Builtin.Int8, Builtin.Int1), 1 + cond_fail %5 : $Builtin.Int1 + + %v0 = integer_literal $Builtin.Int32, 128 + %v1 = integer_literal $Builtin.Int32, 128 + %v4 = builtin "smul_with_overflow_Int32"(%v1 : $Builtin.Int32, %v0 : $Builtin.Int32, %3 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) + %v5 = tuple_extract %v4 : $(Builtin.Int32, Builtin.Int1), 1 + cond_fail %v5 : $Builtin.Int1 + + + %g0 = integer_literal $Builtin.Int64, 2 + %g1 = integer_literal $Builtin.Int64, 1 + %g3 = builtin "cmp_slt_Int64"(%g0 : $Builtin.Int64, %g1 : $Builtin.Int64) : $Builtin.Int1 + cond_fail %g3 : $Builtin.Int1 + + %t0 = integer_literal $Builtin.Int32, 2 + %t1 = integer_literal $Builtin.Int32, 1 + %t3 = builtin "cmp_slt_Int32"(%t0 : $Builtin.Int32, %t1 : $Builtin.Int32) : $Builtin.Int1 + cond_fail %t3 : $Builtin.Int1 + + %ret = tuple () + return %ret : $() +} diff --git a/test/SILPasses/cse.sil b/test/SILOptimizer/cse.sil similarity index 86% rename from test/SILPasses/cse.sil rename to test/SILOptimizer/cse.sil index bba6053a45286..f8c175c245221 100644 --- a/test/SILPasses/cse.sil +++ b/test/SILOptimizer/cse.sil @@ -1,10 +1,7 @@ // RUN: %target-sil-opt -enable-sil-verify-all %s -cse | FileCheck %s -// XFAIL: linux - import Builtin import Swift -import Foundation ////////////////////// // Simple DCE Tests // @@ -154,8 +151,8 @@ bb2: sil @dead_use_of_alloc_stack : $@convention(thin) () -> () { bb0: %1 = alloc_stack $((), (), ()) - %2 = tuple_element_addr %1#1 : $*((), (), ()), 0 - dealloc_stack %1#0 : $*@local_storage ((), (), ()) + %2 = tuple_element_addr %1 : $*((), (), ()), 0 + dealloc_stack %1 : $*((), (), ()) %3 = tuple () return %3 : $() } @@ -453,20 +450,20 @@ sil @tupleextract_test : $@convention(thin) () -> (Builtin.Int32) { sil @init_tuple_addr : $@convention(thin) (@out (Builtin.Int32, Builtin.Int32)) -> () // CHECK-LABEL: tupleelementaddr_test -// CHECK: tuple_element_addr {{%[0-9]#1}} : $*(Builtin.Int32, Builtin.Int32), 0 -// CHECK-NOT: tuple_element_addr {{%[0-9]#1}} : $*(Builtin.Int32, Builtin.Int32), 0 +// CHECK: tuple_element_addr {{%[0-9]}} : $*(Builtin.Int32, Builtin.Int32), 0 +// CHECK-NOT: tuple_element_addr {{%[0-9]}} : $*(Builtin.Int32, Builtin.Int32), 0 sil @tupleelementaddr_test : $@convention(thin) () -> (Builtin.Int32) { %0 = alloc_stack $(Builtin.Int32, Builtin.Int32) %1 = function_ref @init_tuple_addr : $@convention(thin) (@out (Builtin.Int32, Builtin.Int32)) -> () - apply %1(%0#1) : $@convention(thin) (@out (Builtin.Int32, Builtin.Int32)) -> () - %2 = tuple_element_addr %0#1 : $*(Builtin.Int32, Builtin.Int32), 0 - %3 = tuple_element_addr %0#1 : $*(Builtin.Int32, Builtin.Int32), 0 + apply %1(%0) : $@convention(thin) (@out (Builtin.Int32, Builtin.Int32)) -> () + %2 = tuple_element_addr %0 : $*(Builtin.Int32, Builtin.Int32), 0 + %3 = tuple_element_addr %0 : $*(Builtin.Int32, Builtin.Int32), 0 %5 = integer_literal $Builtin.Int1, 0 %6 = load %2 : $*Builtin.Int32 %7 = load %3 : $*Builtin.Int32 %8 = builtin "sadd_with_overflow_Int32" (%6 : $Builtin.Int32, %7 : $Builtin.Int32, %5 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) %9 = tuple_extract %8 : $(Builtin.Int32, Builtin.Int1), 0 - dealloc_stack %0#0 : $* @local_storage (Builtin.Int32, Builtin.Int32) + dealloc_stack %0 : $* (Builtin.Int32, Builtin.Int32) return %9 : $(Builtin.Int32) } @@ -757,31 +754,18 @@ bb0(%0 : $XX): sil @nocse_existential_metatype_addr : $@convention(thin) (@owned B, @owned B) -> (@thick protocol<>.Type, @thick protocol<>.Type) { bb0(%0 : $B, %1 : $B): %2 = alloc_stack $protocol<> - %3 = init_existential_addr %2#1 : $*protocol<>, $B + %3 = init_existential_addr %2 : $*protocol<>, $B store %0 to %3 : $*B - %5 = existential_metatype $@thick protocol<>.Type, %2#1 : $*protocol<> + %5 = existential_metatype $@thick protocol<>.Type, %2 : $*protocol<> store %1 to %3 : $*B - %7 = existential_metatype $@thick protocol<>.Type, %2#1 : $*protocol<> + %7 = existential_metatype $@thick protocol<>.Type, %2 : $*protocol<> strong_release %1 : $B strong_release %0 : $B %99 = tuple (%5 : $@thick protocol<>.Type, %7 : $@thick protocol<>.Type) - dealloc_stack %2#0 : $*@local_storage protocol<> + dealloc_stack %2 : $*protocol<> return %99 : $(@thick protocol<>.Type, @thick protocol<>.Type) } -// CHECK-LABEL: sil @cse_objc_protocol -// CHECK: objc_protocol #XX : $Protocol -// CHECK-NOT: objc_protocol -// CHECK: tuple (%0 : $Protocol, %0 : $Protocol) -// CHECK: return -sil @cse_objc_protocol : $@convention(thin) () -> @owned (Protocol, Protocol) { -bb0: - %0 = objc_protocol #XX : $Protocol - %1 = objc_protocol #XX : $Protocol - %2 = tuple (%0: $Protocol, %1: $Protocol) - return %2 : $(Protocol, Protocol) -} - // CHECK-LABEL: sil @cse_objc_metatype_to_object // CHECK: value_metatype $@objc_metatype @@ -843,14 +827,14 @@ bb0(%0 : $Builtin.RawPointer): sil @cse_unchecked_addr_cast : $@convention(thin) () -> (Builtin.RawPointer, Builtin.RawPointer) { bb0: %1 = alloc_stack $COpaquePointer - %2 = unchecked_addr_cast %1#1: $*COpaquePointer to $*UnsafeMutablePointer - %3 = unchecked_addr_cast %1#1: $*COpaquePointer to $*UnsafeMutablePointer + %2 = unchecked_addr_cast %1: $*COpaquePointer to $*UnsafeMutablePointer + %3 = unchecked_addr_cast %1: $*COpaquePointer to $*UnsafeMutablePointer %4 = struct_element_addr %2 : $*UnsafeMutablePointer, #UnsafeMutablePointer._rawValue %5 = load %4 : $*Builtin.RawPointer %6 = struct_element_addr %3 : $*UnsafeMutablePointer, #UnsafeMutablePointer._rawValue %7 = load %6 : $*Builtin.RawPointer %8 = tuple (%5: $Builtin.RawPointer, %7: $Builtin.RawPointer) - dealloc_stack %1#0 : $*@local_storage COpaquePointer + dealloc_stack %1 : $*COpaquePointer return %8: $(Builtin.RawPointer, Builtin.RawPointer) } @@ -1096,7 +1080,7 @@ func foo(x: T, a: Int) // p.T.reach (p.T)() -> () sil hidden @_TFC1p1T5reachfS0_FT_T_ : $@convention(method) (@guaranteed T) -> () { bb0(%0 : $T): - debug_value %0 : $T // let self // id: %1 + debug_value %0 : $T, let, name "self" // id: %1 %2 = tuple () // user: %3 return %2 : $() // id: %3 } @@ -1104,7 +1088,7 @@ bb0(%0 : $T): // p.T.__deallocating_deinit sil hidden @_TFC1p1TD : $@convention(method) (@owned T) -> () { bb0(%0 : $T): - debug_value %0 : $T // let self // id: %1 + debug_value %0 : $T, let, name "self" // id: %1 %6 = tuple () // user: %7 return %6 : $() // id: %7 } @@ -1112,7 +1096,7 @@ bb0(%0 : $T): // p.T.deinit sil hidden @_TFC1p1Td : $@convention(method) (@guaranteed T) -> @owned Builtin.NativeObject { bb0(%0 : $T): - debug_value %0 : $T // let self // id: %1 + debug_value %0 : $T, let, name "self" // id: %1 %2 = unchecked_ref_cast %0 : $T to $Builtin.NativeObject // user: %3 return %2 : $Builtin.NativeObject // id: %3 } @@ -1120,7 +1104,7 @@ bb0(%0 : $T): // p.T.init (p.T.Type)() -> p.T sil hidden @_TFC1p1TcfMS0_FT_S0_ : $@convention(method) (@owned T) -> @owned T { bb0(%0 : $T): - debug_value %0 : $T // let self // id: %1 + debug_value %0 : $T, let, name "self" // id: %1 return %0 : $T // id: %2 } @@ -1191,7 +1175,7 @@ func trytofly(a: Flyable) // p2.Airplane.fly (p2.Airplane)() -> () sil hidden @_TFV2p28Airplane3flyfS0_FT_T_ : $@convention(method) (Airplane) -> () { bb0(%0 : $Airplane): - debug_value %0 : $Airplane // let self // id: %1 + debug_value %0 : $Airplane, let, name "self" // id: %1 %2 = tuple () // user: %3 return %2 : $() // id: %3 } @@ -1200,12 +1184,12 @@ bb0(%0 : $Airplane): sil hidden [transparent] [thunk] @_TTWV2p28AirplaneS_7FlyableS_FS1_3flyuRq_S1__fq_FT_T_ : $@convention(witness_method) (@in_guaranteed Airplane) -> () { bb0(%0 : $*Airplane): %1 = alloc_stack $Airplane // users: %2, %6 - copy_addr %0 to [initialization] %1#1 : $*Airplane // id: %2 + copy_addr %0 to [initialization] %1 : $*Airplane // id: %2 %3 = struct $Airplane () // user: %5 // function_ref p2.Airplane.fly (p2.Airplane)() -> () %4 = function_ref @_TFV2p28Airplane3flyfS0_FT_T_ : $@convention(method) (Airplane) -> () // user: %5 %5 = apply %4(%3) : $@convention(method) (Airplane) -> () // user: %7 - dealloc_stack %1#0 : $*@local_storage Airplane // id: %6 + dealloc_stack %1 : $*Airplane // id: %6 return %5 : $() // id: %7 } @@ -1246,107 +1230,3 @@ bb0(%0 : $*Flyable): sil_witness_table hidden Airplane: Flyable module p2 { method #Flyable.fly!1: @_TTWV2p28AirplaneS_7FlyableS_FS1_3flyuRq_S1__fq_FT_T_ // protocol witness for p2.Flyable.fly (A)() -> () in conformance p2.Airplane : p2.Flyable in p2 } - -@objc protocol Walkable { - func walk() -} - - class Bar : NSObject, Walkable { - override init() - func walk() - deinit -} - -func trytowalk(f: Walkable) - -// test.Bar.init (test.Bar.Type)() -> test.Bar -sil hidden @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar { -bb0(%0 : $Bar): - %1 = alloc_stack $Bar // let self // users: %2, %6, %9, %10 - store %0 to %1#1 : $*Bar // id: %2 - %3 = upcast %0 : $Bar to $NSObject // user: %7 - %4 = super_method [volatile] %0 : $Bar, #NSObject.init!initializer.1.foreign : NSObject.Type -> () -> NSObject , $@convention(objc_method) (@owned NSObject) -> @owned NSObject // user: %7 - %7 = apply %4(%3) : $@convention(objc_method) (@owned NSObject) -> @owned NSObject // user: %8 - %8 = unchecked_ref_cast %7 : $NSObject to $Bar // users: %9, %11 - store %8 to %1#1 : $*Bar // id: %9 - dealloc_stack %1#0 : $*@local_storage Bar // id: %10 - return %8 : $Bar // id: %11 -} - -// test.Bar.__allocating_init (test.Bar.Type)() -> test.Bar -sil hidden @_TFC4test3BarCfMS0_FT_S0_ : $@convention(thin) (@thick Bar.Type) -> @owned Bar { -bb0(%0 : $@thick Bar.Type): - %1 = alloc_ref [objc] $Bar // user: %3 - // function_ref test.Bar.init (test.Bar.Type)() -> test.Bar - %2 = function_ref @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar // user: %3 - %3 = apply %2(%1) : $@convention(method) (@owned Bar) -> @owned Bar // user: %4 - return %3 : $Bar // id: %4 -} - -// @objc test.Bar.init (test.Bar.Type)() -> test.Bar -sil hidden @_TToFC4test3BarcfMS0_FT_S0_ : $@convention(objc_method) (@owned Bar) -> @owned Bar { -bb0(%0 : $Bar): - // function_ref test.Bar.init (test.Bar.Type)() -> test.Bar - %1 = function_ref @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar // user: %2 - %2 = apply %1(%0) : $@convention(method) (@owned Bar) -> @owned Bar // user: %3 - return %2 : $Bar // id: %3 -} - -// test.Bar.walk (test.Bar)() -> () -sil hidden @_TFC4test3Bar4walkfS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> () { -bb0(%0 : $Bar): - debug_value %0 : $Bar // let self // id: %1 - %2 = tuple () // user: %3 - return %2 : $() // id: %3 -} - -// @objc test.Bar.walk (test.Bar)() -> () -sil hidden @_TToFC4test3Bar4walkfS0_FT_T_ : $@convention(objc_method) (Bar) -> () { -bb0(%0 : $Bar): - strong_retain %0 : $Bar // id: %1 - // function_ref test.Bar.walk (test.Bar)() -> () - %2 = function_ref @_TFC4test3Bar4walkfS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> () // user: %3 - %3 = apply %2(%0) : $@convention(method) (@guaranteed Bar) -> () // user: %5 - strong_release %0 : $Bar // id: %4 - return %3 : $() // id: %5 -} - -// test.Bar.__deallocating_deinit -sil hidden @_TFC4test3BarD : $@convention(method) (@owned Bar) -> () { -bb0(%0 : $Bar): - debug_value %0 : $Bar // let self // id: %1 - %2 = super_method %0 : $Bar, #NSObject.deinit!deallocator.foreign : NSObject -> () , $@convention(objc_method) (NSObject) -> () // user: %4 - %3 = upcast %0 : $Bar to $NSObject // user: %4 - %4 = apply %2(%3) : $@convention(objc_method) (NSObject) -> () - %5 = tuple () // user: %6 - return %5 : $() // id: %6 -} - -// CHECK-LABEL: _TF4test9trytowalkFPS_8Walkable_T_ -// CHECK: bb0(%0 : $Walkable): -// CHECK-NEXT: open_existential_ref -// CHECK-NEXT: witness_method -// CHECK-NEXT: apply -// CHECK-NEXT: witness_method -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple -// CHECK-NEXT: return -// test.trytowalk (test.Walkable) -> () -sil hidden @_TF4test9trytowalkFPS_8Walkable_T_ : $@convention(thin) (@owned Walkable) -> () { -bb0(%0 : $Walkable): - %2 = open_existential_ref %0 : $Walkable to $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable // users: %3, %4 - %3 = witness_method [volatile] $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable, #Walkable.walk!1.foreign, %2 : $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () // user: %4 - %4 = apply %3<@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable>(%2) : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () - %5 = witness_method [volatile] $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable, #Walkable.walk!1.foreign, %2 : $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () // user: %6 - %6 = apply %5<@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable>(%2) : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () - strong_release %0 : $Walkable // id: %8 - %9 = tuple () // user: %10 - return %9 : $() // id: %10 -} - -sil_vtable Bar { - #Bar.init!initializer.1: _TFC4test3BarcfMS0_FT_S0_ // test.Bar.init (test.Bar.Type)() -> test.Bar - #Bar.walk!1: _TFC4test3Bar4walkfS0_FT_T_ // test.Bar.walk (test.Bar)() -> () - #Bar.deinit!deallocator: _TFC4test3BarD // test.Bar.__deallocating_deinit -} diff --git a/test/SILPasses/cse_apply.sil b/test/SILOptimizer/cse_apply.sil similarity index 96% rename from test/SILPasses/cse_apply.sil rename to test/SILOptimizer/cse_apply.sil index c1bcfb6ba75fa..9100a9ae6a5e8 100644 --- a/test/SILPasses/cse_apply.sil +++ b/test/SILOptimizer/cse_apply.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -side-effects -cse | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -cse | FileCheck %s sil_stage canonical @@ -18,8 +18,8 @@ import Swift //CHECK: return sil @simply_arith : $@convention(thin) (Int32, Int32) -> Int32 { bb0(%0 : $Int32, %1 : $Int32): - debug_value %0 : $Int32 // let x // id: %2 - debug_value %1 : $Int32 // let y // id: %3 + debug_value %0 : $Int32, let, name "x" // id: %2 + debug_value %1 : $Int32, let, name "y" // id: %3 %5 = struct_extract %0 : $Int32, #Int32._value // user: %8 %6 = struct_extract %1 : $Int32, #Int32._value // user: %8 %7 = integer_literal $Builtin.Int1, -1 // user: %8 diff --git a/test/SILOptimizer/cse_objc.sil b/test/SILOptimizer/cse_objc.sil new file mode 100644 index 0000000000000..cb71e95b9616e --- /dev/null +++ b/test/SILOptimizer/cse_objc.sil @@ -0,0 +1,126 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -cse | FileCheck %s +// REQUIRES: objc_interop + +import Builtin +import Swift +import Foundation + +@objc(XX) protocol XX { +} + +// CHECK-LABEL: sil @cse_objc_protocol +// CHECK: objc_protocol #XX : $Protocol +// CHECK-NOT: objc_protocol +// CHECK: tuple (%0 : $Protocol, %0 : $Protocol) +// CHECK: return +sil @cse_objc_protocol : $@convention(thin) () -> @owned (Protocol, Protocol) { +bb0: + %0 = objc_protocol #XX : $Protocol + %1 = objc_protocol #XX : $Protocol + %2 = tuple (%0: $Protocol, %1: $Protocol) + return %2 : $(Protocol, Protocol) +} + +@objc protocol Walkable { + func walk() +} + + class Bar : NSObject, Walkable { + override init() + func walk() + deinit +} + +func trytowalk(f: Walkable) + +// test.Bar.init (test.Bar.Type)() -> test.Bar +sil hidden @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar { +bb0(%0 : $Bar): + %1 = alloc_stack $Bar, let, name "sf" // users: %2, %6, %9, %10 + store %0 to %1 : $*Bar // id: %2 + %3 = upcast %0 : $Bar to $NSObject // user: %7 + %4 = super_method [volatile] %0 : $Bar, #NSObject.init!initializer.1.foreign : NSObject.Type -> () -> NSObject , $@convention(objc_method) (@owned NSObject) -> @owned NSObject // user: %7 + %7 = apply %4(%3) : $@convention(objc_method) (@owned NSObject) -> @owned NSObject // user: %8 + %8 = unchecked_ref_cast %7 : $NSObject to $Bar // users: %9, %11 + store %8 to %1 : $*Bar // id: %9 + dealloc_stack %1 : $*Bar // id: %10 + return %8 : $Bar // id: %11 +} + +// test.Bar.__allocating_init (test.Bar.Type)() -> test.Bar +sil hidden @_TFC4test3BarCfMS0_FT_S0_ : $@convention(thin) (@thick Bar.Type) -> @owned Bar { +bb0(%0 : $@thick Bar.Type): + %1 = alloc_ref [objc] $Bar // user: %3 + // function_ref test.Bar.init (test.Bar.Type)() -> test.Bar + %2 = function_ref @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar // user: %3 + %3 = apply %2(%1) : $@convention(method) (@owned Bar) -> @owned Bar // user: %4 + return %3 : $Bar // id: %4 +} + +// @objc test.Bar.init (test.Bar.Type)() -> test.Bar +sil hidden @_TToFC4test3BarcfMS0_FT_S0_ : $@convention(objc_method) (@owned Bar) -> @owned Bar { +bb0(%0 : $Bar): + // function_ref test.Bar.init (test.Bar.Type)() -> test.Bar + %1 = function_ref @_TFC4test3BarcfMS0_FT_S0_ : $@convention(method) (@owned Bar) -> @owned Bar // user: %2 + %2 = apply %1(%0) : $@convention(method) (@owned Bar) -> @owned Bar // user: %3 + return %2 : $Bar // id: %3 +} + +// test.Bar.walk (test.Bar)() -> () +sil hidden @_TFC4test3Bar4walkfS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> () { +bb0(%0 : $Bar): + debug_value %0 : $Bar, let, name "self" // id: %1 + %2 = tuple () // user: %3 + return %2 : $() // id: %3 +} + +// @objc test.Bar.walk (test.Bar)() -> () +sil hidden @_TToFC4test3Bar4walkfS0_FT_T_ : $@convention(objc_method) (Bar) -> () { +bb0(%0 : $Bar): + strong_retain %0 : $Bar // id: %1 + // function_ref test.Bar.walk (test.Bar)() -> () + %2 = function_ref @_TFC4test3Bar4walkfS0_FT_T_ : $@convention(method) (@guaranteed Bar) -> () // user: %3 + %3 = apply %2(%0) : $@convention(method) (@guaranteed Bar) -> () // user: %5 + strong_release %0 : $Bar // id: %4 + return %3 : $() // id: %5 +} + +// test.Bar.__deallocating_deinit +sil hidden @_TFC4test3BarD : $@convention(method) (@owned Bar) -> () { +bb0(%0 : $Bar): + debug_value %0 : $Bar, let, name "self" // id: %1 + %2 = super_method %0 : $Bar, #NSObject.deinit!deallocator.foreign : NSObject -> () , $@convention(objc_method) (NSObject) -> () // user: %4 + %3 = upcast %0 : $Bar to $NSObject // user: %4 + %4 = apply %2(%3) : $@convention(objc_method) (NSObject) -> () + %5 = tuple () // user: %6 + return %5 : $() // id: %6 +} + +// CHECK-LABEL: _TF4test9trytowalkFPS_8Walkable_T_ +// CHECK: bb0(%0 : $Walkable): +// CHECK-NEXT: open_existential_ref +// CHECK-NEXT: witness_method +// CHECK-NEXT: apply +// CHECK-NEXT: witness_method +// CHECK-NEXT: apply +// CHECK-NEXT: strong_release +// CHECK-NEXT: tuple +// CHECK-NEXT: return +// test.trytowalk (test.Walkable) -> () +sil hidden @_TF4test9trytowalkFPS_8Walkable_T_ : $@convention(thin) (@owned Walkable) -> () { +bb0(%0 : $Walkable): + %2 = open_existential_ref %0 : $Walkable to $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable // users: %3, %4 + %3 = witness_method [volatile] $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable, #Walkable.walk!1.foreign, %2 : $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () // user: %4 + %4 = apply %3<@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable>(%2) : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () + %5 = witness_method [volatile] $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable, #Walkable.walk!1.foreign, %2 : $@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () // user: %6 + %6 = apply %5<@opened("7813D5BE-4C48-11E5-BD72-AC87A3294C0A") Walkable>(%2) : $@convention(objc_method) <τ_0_0 where τ_0_0 : Walkable> (τ_0_0) -> () + strong_release %0 : $Walkable // id: %8 + %9 = tuple () // user: %10 + return %9 : $() // id: %10 +} + +sil_vtable Bar { + #Bar.init!initializer.1: _TFC4test3BarcfMS0_FT_S0_ // test.Bar.init (test.Bar.Type)() -> test.Bar + #Bar.walk!1: _TFC4test3Bar4walkfS0_FT_T_ // test.Bar.walk (test.Bar)() -> () + #Bar.deinit!deallocator: _TFC4test3BarD // test.Bar.__deallocating_deinit +} diff --git a/test/SILPasses/dead_alloc_elim.sil b/test/SILOptimizer/dead_alloc_elim.sil similarity index 98% rename from test/SILPasses/dead_alloc_elim.sil rename to test/SILOptimizer/dead_alloc_elim.sil index 241f9ebe3accb..94d41f18c16bc 100644 --- a/test/SILPasses/dead_alloc_elim.sil +++ b/test/SILOptimizer/dead_alloc_elim.sil @@ -19,7 +19,7 @@ bb0(%0 : $TrivialDestructor): // Alloc/Dealloc stack should not disrupt elimination of the // alloc_ref. %1 = alloc_stack $Builtin.Int64 - dealloc_stack %1#0 : $*@local_storage Builtin.Int64 + dealloc_stack %1 : $*Builtin.Int64 // Storing into the struct should not disrupt elimination of the // alloc_ref. @@ -310,7 +310,7 @@ sil @non_trivial_destructor_objc_destructor : $@convention(thin) () -> () { // CHECK: return sil @non_trivial_destructor_on_stack : $@convention(thin) () -> () { %0 = alloc_stack $NonTrivialDestructor - dealloc_stack %0#0 : $*@local_storage NonTrivialDestructor + dealloc_stack %0 : $*NonTrivialDestructor %1 = tuple() return %1 : $() } @@ -321,8 +321,8 @@ sil @non_trivial_destructor_on_stack : $@convention(thin) () -> () { // CHECK: return sil @trivial_destructor_on_stack : $@convention(thin) () -> () { %0 = alloc_stack $Int - destroy_addr %0#1 : $*Int - dealloc_stack %0#0 : $*@local_storage Int + destroy_addr %0 : $*Int + dealloc_stack %0 : $*Int %1 = tuple() return %1 : $() } diff --git a/test/SILPasses/dead_array_elim.sil b/test/SILOptimizer/dead_array_elim.sil similarity index 100% rename from test/SILPasses/dead_array_elim.sil rename to test/SILOptimizer/dead_array_elim.sil diff --git a/test/SILPasses/dead_code_elimination.sil b/test/SILOptimizer/dead_code_elimination.sil similarity index 100% rename from test/SILPasses/dead_code_elimination.sil rename to test/SILOptimizer/dead_code_elimination.sil diff --git a/test/SILPasses/dead_func.swift b/test/SILOptimizer/dead_func.swift similarity index 100% rename from test/SILPasses/dead_func.swift rename to test/SILOptimizer/dead_func.swift diff --git a/test/SILPasses/dead_func_init_method.sil b/test/SILOptimizer/dead_func_init_method.sil similarity index 100% rename from test/SILPasses/dead_func_init_method.sil rename to test/SILOptimizer/dead_func_init_method.sil diff --git a/test/SILPasses/dead_function_elimination.swift b/test/SILOptimizer/dead_function_elimination.swift similarity index 100% rename from test/SILPasses/dead_function_elimination.swift rename to test/SILOptimizer/dead_function_elimination.swift diff --git a/test/SILPasses/dead_inlined_func.swift b/test/SILOptimizer/dead_inlined_func.swift similarity index 100% rename from test/SILPasses/dead_inlined_func.swift rename to test/SILOptimizer/dead_inlined_func.swift diff --git a/test/SILPasses/dead_internal_func.swift b/test/SILOptimizer/dead_internal_func.swift similarity index 100% rename from test/SILPasses/dead_internal_func.swift rename to test/SILOptimizer/dead_internal_func.swift diff --git a/test/SILPasses/dead_method.swift b/test/SILOptimizer/dead_method.swift similarity index 100% rename from test/SILPasses/dead_method.swift rename to test/SILOptimizer/dead_method.swift diff --git a/test/SILOptimizer/dead_store_elim.sil b/test/SILOptimizer/dead_store_elim.sil new file mode 100644 index 0000000000000..0be7c1316ade4 --- /dev/null +++ b/test/SILOptimizer/dead_store_elim.sil @@ -0,0 +1,1415 @@ +// RUN: %target-sil-opt %s -dead-store-elim -enable-sil-verify-all | FileCheck %s + +sil_stage canonical + +import Swift +import Builtin + +/////////////////////// +// Type Declarations // +/////////////////////// + +struct Int { + var value : Builtin.Int64 +} + +struct Int64 { + var value : Builtin.Int64 +} + +struct Bool { + var value : Builtin.Int1 +} + +struct A { + var i : Builtin.Int32 +} + +struct AA { + var a : A + var i : Builtin.Int32 +} + +struct S1 { + var a: Int + init(a: Int, b: Int) + init() +} + +struct S2 { + var x: S1 + var a: Int + var b: Int + init(x: S1, a: Int, b: Int) + init() +} + +struct S3 { + var a: Int + var b: Int + init(a: Int, b: Int) + init() +} + +struct S4 { + var a: Int + var b: Int + init(a: Int, b: Int) + init() +} + +struct S5 { + var x: S4 + var y: Int + init(x: S4, y: Int) + init() +} + +struct S6 { + var x: Int + var y: Int + var z: Int + init(x: Int, y: Int, z: Int) + init() +} + +struct S7 { + var x: Int + var y: Int + var z: Int + var a: Int + var b: Int + var c: Int + init(x: Int, y: Int, z: Int, a: Int, b: Int, c: Int) + init() +} + +class SelfLoop { + var a: SelfLoop + init() + deinit +} + +struct S8 { + var i: SelfLoop + var k: Int + init(i: SelfLoop, k: Int) + init() +} + +class foo { + var a: Int + deinit + init() +} + +class B { + var i : Builtin.Int32 + init() +} + +enum Example { + case A(Int64, Int64) + case B(Int64) + case C + case D +} + +sil @foo_user : $@convention(thin) (@guaranteed foo) -> () +sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1 +sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2 +sil @S3_init : $@convention(thin) (@thin S3.Type) -> S3 +sil @S5_init : $@convention(thin) (@thin S5.Type) -> S5 +sil @S6_init : $@convention(thin) (@thin S6.Type) -> S6 +sil @S7_init : $@convention(thin) (@thin S7.Type) -> S7 +sil @S8_init : $@convention(thin) (@thin S8.Type) -> @owned S8 +sil @escaped_a : $@convention(thin) () -> Builtin.RawPointer + +// We should be able to remove the local store that is not read. +// +// CHECK-LABEL: trivial_local_dead_store +// CHECK: bb0 +// CHECK-NOT: store +// CHECK: return +sil hidden @trivial_local_dead_store : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $Int, var, name "a" // users: %3, %5 + %1 = integer_literal $Builtin.Int64, 1 // user: %2 + %2 = struct $Int (%1 : $Builtin.Int64) // user: %3 + store %2 to %0 : $*Int // id: %3 + %4 = tuple () // user: %6 + dealloc_stack %0 : $*Int // id: %5 + return %4 : $() // id: %6 +} + +// We cannot remove the local store that is read. +// +// CHECK-LABEL: blocking_read_on_local_store +// CHECK: bb0 +// CHECK: store +// CHECK: return +sil hidden @blocking_read_on_local_store : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $Int, var, name "a" // users: %3, %5 + %1 = integer_literal $Builtin.Int64, 1 // user: %2 + %2 = struct $Int (%1 : $Builtin.Int64) // user: %3 + store %2 to %0 : $*Int // id: %3 + %4 = tuple () // user: %6 + %99 = load %0 : $*Int + dealloc_stack %0 : $*Int // id: %5 + return %4 : $() // id: %6 +} + +// CHECK-LABEL: sil @store_after_store +// CHECK: bb0 +// CHECK-NOT: store +// CHECK: return +sil @store_after_store : $@convention(thin) (@owned B) -> () { +bb0(%0 : $B): + %1 = alloc_box $B + %2 = store %0 to %1#1 : $*B + %3 = store %0 to %1#1 : $*B + %4 = tuple() + %5 = return %4 : $() +} + +// CHECK-LABEL: sil @dead_store_elimination_over_noread_builtins +// CHECK: bb0 +// CHECK-NEXT: load +// CHECK-NEXT: integer_literal +// CHECK-NEXT: builtin +// CHECK-NEXT: tuple_extract +// CHECK-NEXT: store +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @dead_store_elimination_over_noread_builtins : $@convention(thin) (@inout Builtin.Int64, @inout Builtin.Int64) -> () { +bb0(%0 : $*Builtin.Int64, %1 : $*Builtin.Int64): + %2 = load %0 : $*Builtin.Int64 + %4 = integer_literal $Builtin.Int1, 0 + %5 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %2 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %6 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 0 + store %6 to %1 : $*Builtin.Int64 + %8 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %2 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 0 + store %9 to %1 : $*Builtin.Int64 + %10 = tuple() + return %10 : $() +} + +// CHECK-LABEL: sil @post_dominating_dead_store : $@convention(thin) (@inout Builtin.Int32) -> () { +// CHECK: store +// CHECK-NOT: store +// CHECK: return +sil @post_dominating_dead_store : $@convention(thin) (@inout Builtin.Int32) -> () { +bb0(%0 : $*Builtin.Int32): + %1 = integer_literal $Builtin.Int32, 0 + store %1 to %0 : $*Builtin.Int32 + cond_br undef, bb1, bb2 + +bb1: + br bb3 + +bb2: + br bb3 + +bb3: + store %1 to %0 : $*Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: sil @post_dominating_dead_store_partial : $@convention(thin) (@inout Builtin.Int32) -> () { +// CHECK: bb0( +// CHECK-NOT: store +// CHECK: bb1: +// CHECK_NOT: store +// CHECK: bb2: +// CHECK: bb3: +// CHECK: store +// CHECK: return +sil @post_dominating_dead_store_partial : $@convention(thin) (@inout Builtin.Int32) -> () { +bb0(%0 : $*Builtin.Int32): + %1 = integer_literal $Builtin.Int32, 0 + %2 = integer_literal $Builtin.Int32, 1 + %3 = integer_literal $Builtin.Int32, 2 + store %1 to %0 : $*Builtin.Int32 + cond_br undef, bb1, bb2 + +bb1: + store %2 to %0 : $*Builtin.Int32 + br bb3 + +bb2: + br bb3 + +bb3: + store %3 to %0 : $*Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// We can't eliminate any stores here. +// CHECK-LABEL: sil @post_dominating_dead_store_fail : $@convention(thin) (@inout Builtin.Int32) -> () { +// CHECK: store +// CHECK: store +// CHECK-NOT: store +// CHECK: return +sil @post_dominating_dead_store_fail : $@convention(thin) (@inout Builtin.Int32) -> () { +bb0(%0 : $*Builtin.Int32): + %1 = integer_literal $Builtin.Int32, 0 + %2 = integer_literal $Builtin.Int32, 1 + store %1 to %0 : $*Builtin.Int32 + cond_br undef, bb1, bb2 + +bb1: + store %2 to %0 : $*Builtin.Int32 + br bb2 + +bb2: + %9999 = tuple() + return %9999 : $() +} + +// We cannot remove the local store as the debug_value_addr could +// be turned to a debug_value and thus act as a read on the memory +// location.. +// +// CHECK-LABEL: blocking_debug_value_addr_on_dead_store +// CHECK: bb0 +// CHECK: store +// CHECK: debug_value_addr +sil hidden @blocking_debug_value_addr_on_dead_store : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $Int, var, name "a" // users: %3, %5 + %1 = integer_literal $Builtin.Int64, 1 // user: %2 + %2 = struct $Int (%1 : $Builtin.Int64) // user: %3 + store %2 to %0 : $*Int // id: %3 + debug_value_addr %0 : $*Int + %4 = tuple () // user: %6 + dealloc_stack %0 : $*Int // id: %5 + return %4 : $() // id: %6 +} + +// CHECK-LABEL: sil @test_read_dependence_allows_forwarding : $@convention(thin) (@inout A, A) -> A { +// CHECK: bb0 +// CHECK-NEXT: store +// CHECK-NEXT: unchecked_addr_cast +// CHECK-NEXT: unchecked_addr_cast +// CHECK-NEXT: load +// CHECK-NEXT: store +// CHECK-NEXT: return +sil @test_read_dependence_allows_forwarding : $@convention(thin) (@inout A, A) -> A { +bb0(%0 : $*A, %1 : $A): + store %1 to %0 : $*A + %2 = unchecked_addr_cast %0 : $*A to $*A + %3 = unchecked_addr_cast %2 : $*A to $*A + // This means that the first store is not dead. + %4 = load %3 : $*A + store %1 to %0 : $*A + return %4 : $A +} + +// Make sure that we do not eliminate a partially dead store as if it +// was a full dead store. +// +// CHECK-LABEL: sil @partially_dead_store1 : $@convention(thin) (@inout AA, AA, A) -> () { +// CHECK: store +// CHECK: store +sil @partially_dead_store1 : $@convention(thin) (@inout AA, AA, A) -> () { +bb0(%0 : $*AA, %1 : $AA, %2 : $A): + store %1 to %0 : $*AA + %3 = unchecked_addr_cast %0 : $*AA to $*A + store %2 to %3 : $*A + %9999 = tuple() + return %9999 : $() +} + +// Make sure that we do not eliminate a partially dead store as if it +// was a full dead store. +// +// CHECK-LABEL: sil @partially_dead_store2 : $@convention(thin) (@inout AA, AA, A) -> () { +// CHECK: store +// CHECK: store +sil @partially_dead_store2 : $@convention(thin) (@inout AA, AA, A) -> () { +bb0(%0 : $*AA, %1 : $AA, %2 : $A): + store %1 to %0 : $*AA + %3 = struct_element_addr %0 : $*AA, #AA.a + store %2 to %3 : $*A + %9999 = tuple() + return %9999 : $() +} + +// Make sure that we properly eliminate the stores in bb1, bb2 from StoreMap. +// +// CHECK-LABEL: sil @store_map_failed_dead_object_elim_invalidation : $@convention(thin) () -> () { +// CHECK: bb1: +// CHECK: store +// CHECK: bb2: +// CHECK: store +// CHECK: bb3: +// CHECK: store +sil @store_map_failed_dead_object_elim_invalidation : $@convention(thin) () -> () { +bb0: + %0 = integer_literal $Builtin.Int32, 32 + %1 = integer_literal $Builtin.Int32, 64 + %2 = function_ref @escaped_a : $@convention(thin) () -> Builtin.RawPointer + %3 = apply %2() : $@convention(thin) () -> Builtin.RawPointer + %4 = pointer_to_address %3 : $Builtin.RawPointer to $*Builtin.Int32 + %5 = apply %2() : $@convention(thin) () -> Builtin.RawPointer + %6 = pointer_to_address %5 : $Builtin.RawPointer to $*Builtin.Int32 + cond_br undef, bb1, bb2 + +bb1: + store %0 to %4 : $*Builtin.Int32 + br bb3 + +bb2: + store %1 to %4 : $*Builtin.Int32 + br bb3 + +bb3: + store %0 to %6 : $*Builtin.Int32 + %9999 = tuple() + return %9999 : $() +} + +// We should be able to remove the store in bb0, but we currently +// cant due to deficiency in alias analysis. +// +// CHECK-LABEL: DeadStoreWithAliasingBasesSimpleClass +// CHECK: bb0([[RET0:%.+]] : $Bool): +// CHECK: store +// CHECK: store +sil hidden @DeadStoreWithAliasingBasesSimpleClass : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_ref $foo // users: %3, %6 + %2 = alloc_stack $foo // users: %3, %8, %15 + store %1 to %2 : $*foo // id: %3 + %8 = load %2 : $*foo // user: %11 + %4 = integer_literal $Builtin.Int64, 12 // user: %5 + %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 + %6 = ref_element_addr %1 : $foo, #foo.a // user: %7 + store %5 to %6 : $*Int // id: %7 + %9 = ref_element_addr %8 : $foo, #foo.a // user: %12 + store %5 to %9 : $*Int // id: %12 + %14 = tuple () // user: %16 + dealloc_stack %2 : $*foo // id: %15 + return %14 : $() // id: %16 +} + +// Remove dead stores in if-else block on a simple struct as there are stores +// in the joint block. +// +// CHECK-LABEL: diamond_control_flow_dead_store +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: bb2: +// CHECK-NOT: store +// CHECK: br +sil hidden @diamond_control_flow_dead_store : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1 // users: %6, %11, %16, %21, %24 + // function_ref S1_init + %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 + %4 = metatype $@thin S1.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 + store %5 to %2 : $*S1 // id: %6 + %7 = struct_extract %0 : $Bool, #Bool.value // user: %8 + cond_br %7, bb1, bb2 // id: %8 + +bb1: // Preds: bb0 + %9 = integer_literal $Builtin.Int64, 0 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %2 : $*S1, #S1.a // user: %12 + store %10 to %11 : $*Int // id: %12 + br bb3 // id: %13 + +bb2: // Preds: bb0 + %14 = integer_literal $Builtin.Int64, 1 // user: %15 + %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 + %16 = struct_element_addr %2 : $*S1, #S1.a // user: %17 + store %15 to %16 : $*Int // id: %17 + br bb3 // id: %18 + +bb3: // Preds: bb1 bb2 + %19 = integer_literal $Builtin.Int64, 2 // user: %20 + %20 = struct $Int (%19 : $Builtin.Int64) // user: %22 + %21 = struct_element_addr %2 : $*S1, #S1.a // user: %22 + store %20 to %21 : $*Int // id: %22 + %23 = tuple () // user: %25 + dealloc_stack %2 : $*S1 // id: %24 + return %23 : $() // id: %25 +} + +// Remove a dead store in the split block as there are stores in the if-else +// blocks. +// +// CHECK-LABEL: DeadStoreInSplitSimpleStruct +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: cond_br +sil hidden @DeadStoreInSplitSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1 // users: %6, %11, %16, %21, %25 + // function_ref S1_init + %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 + %4 = metatype $@thin S1.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 + store %5 to %2 : $*S1 // id: %6 + br bb1 // id: %7 + +bb1: // Preds: bb0 + %8 = struct_extract %0 : $Bool, #Bool.value // user: %13 + %9 = integer_literal $Builtin.Int64, 0 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %2 : $*S1, #S1.a // user: %12 + store %10 to %11 : $*Int // id: %12 + cond_br %8, bb2, bb3 // id: %13 + +bb2: // Preds: bb1 + %14 = integer_literal $Builtin.Int64, 0 // user: %15 + %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 + %16 = struct_element_addr %2 : $*S1, #S1.a // user: %17 + store %15 to %16 : $*Int // id: %17 + br bb4 // id: %18 + +bb3: // Preds: bb1 + %19 = integer_literal $Builtin.Int64, 1 // user: %20 + %20 = struct $Int (%19 : $Builtin.Int64) // user: %22 + %21 = struct_element_addr %2 : $*S1, #S1.a // user: %22 + store %20 to %21 : $*Int // id: %22 + br bb4 // id: %23 + +bb4: // Preds: bb2 bb3 + %24 = tuple () // user: %26 + dealloc_stack %2 : $*S1 // id: %25 + return %24 : $() // id: %26 +} + +// Remove dead stores in split and else block. +// +// CHECK-LABEL: DeadStoreInSplitElseBlockSimpleStruct +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: cond_br +sil hidden @DeadStoreInSplitElseBlockSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1 // users: %6, %11, %17, %22, %25 + // function_ref S1_init + %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 + %4 = metatype $@thin S1.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 + store %5 to %2 : $*S1 // id: %6 + br bb1 // id: %7 + +bb1: // Preds: bb0 + %8 = struct_extract %0 : $Bool, #Bool.value // user: %13 + %9 = integer_literal $Builtin.Int64, 0 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %2 : $*S1, #S1.a // user: %12 + store %10 to %11 : $*Int // id: %12 + cond_br %8, bb2, bb3 // id: %13 + +bb2: // Preds: bb1 + br bb4 // id: %14 + +bb3: // Preds: bb1 + %15 = integer_literal $Builtin.Int64, 1 // user: %16 + %16 = struct $Int (%15 : $Builtin.Int64) // user: %18 + %17 = struct_element_addr %2 : $*S1, #S1.a // user: %18 + store %16 to %17 : $*Int // id: %18 + br bb4 // id: %19 + +bb4: // Preds: bb2 bb3 + %20 = integer_literal $Builtin.Int64, 0 // user: %21 + %21 = struct $Int (%20 : $Builtin.Int64) // user: %23 + %22 = struct_element_addr %2 : $*S1, #S1.a // user: %23 + store %21 to %22 : $*Int // id: %23 + %24 = tuple () // user: %26 + dealloc_stack %2 : $*S1 // id: %25 + return %24 : $() // id: %26 +} + +// Remove dead stores in else block, store is only partially dead +// for split block. +// +// CHECK-LABEL: DeadStoreInElsePartialDeadStoreInSplitSimpleStruct +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: cond_br +sil hidden @DeadStoreInElsePartialDeadStoreInSplitSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1 // users: %6, %11, %18, %23, %26 + // function_ref S1_init + %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 + %4 = metatype $@thin S1.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 + store %5 to %2 : $*S1 // id: %6 + br bb1 // id: %7 + +bb1: // Preds: bb0 + %8 = struct_extract %0 : $Bool, #Bool.value // user: %14 + %9 = integer_literal $Builtin.Int64, 0 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %13 + %11 = struct_element_addr %2 : $*S1, #S1.a // users: %12, %13 + %12 = load %11 : $*Int + store %10 to %11 : $*Int // id: %13 + cond_br %8, bb2, bb3 // id: %14 + +bb2: // Preds: bb1 + br bb4 // id: %15 + +bb3: // Preds: bb1 + %16 = integer_literal $Builtin.Int64, 1 // user: %17 + %17 = struct $Int (%16 : $Builtin.Int64) // user: %19 + %18 = struct_element_addr %2 : $*S1, #S1.a // user: %19 + store %17 to %18 : $*Int // id: %19 + br bb4 // id: %20 + +bb4: // Preds: bb2 bb3 + %21 = integer_literal $Builtin.Int64, 0 // user: %22 + %22 = struct $Int (%21 : $Builtin.Int64) // user: %24 + %23 = struct_element_addr %2 : $*S1, #S1.a // user: %24 + store %22 to %23 : $*Int // id: %24 + %25 = tuple () // user: %27 + dealloc_stack %2 : $*S1 // id: %26 + return %25 : $() // id: %27 +} + +// Remove a dead store in the split block as there are stores in the if-else +// blocks. +// +// Store in bb1 is still alive as post-order does not iterate over unreachable +// block. +// +// CHECK-LABEL: DeadStoreInUnreachablePredecessorSimpleStruct +// CHECK: bb0 +// CHECK-NOT: store +// CHECK: br +// CHECK: bb1 +// CHECK-NOT: store +// CHECK: br +sil hidden @DeadStoreInUnreachablePredecessorSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1 // users: %6, %11, %16, %21, %25 + // function_ref S1_init + %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 + %4 = metatype $@thin S1.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 + store %5 to %2 : $*S1 // id: %6 + br bb1 // id: %7 + +bb1: // Preds: bb0 + %8 = struct_extract %0 : $Bool, #Bool.value + %9 = integer_literal $Builtin.Int64, 0 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %2 : $*S1, #S1.a // user: %12 + store %10 to %11 : $*Int // id: %12 + br bb3 // id: %13 + +bb2: + %14 = integer_literal $Builtin.Int64, 0 // user: %15 + %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 + %16 = struct_element_addr %2 : $*S1, #S1.a // user: %17 + store %15 to %16 : $*Int // id: %17 + br bb3 // id: %18 + +bb3: // Preds: bb1 bb2 + %19 = integer_literal $Builtin.Int64, 1 // user: %20 + %20 = struct $Int (%19 : $Builtin.Int64) // user: %22 + %21 = struct_element_addr %2 : $*S1, #S1.a // user: %22 + store %20 to %21 : $*Int // id: %22 + br bb4 // id: %23 + +bb4: // Preds: bb3 + %24 = tuple () // user: %26 + dealloc_stack %2 : $*S1 // id: %25 + return %24 : $() // id: %26 +} + +// CHECK-LABEL: DeadStoreInIfElseBlockComplexStruct +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: br +// CHECK: bb2: +// CHECK-NOT: store +// CHECK: br +sil hidden @DeadStoreInIfElseBlockComplexStruct : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $S2 // users: %5, %10, %16, %22, %26 + // function_ref S2_init + %2 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %4 + %3 = metatype $@thin S2.Type // user: %4 + %4 = apply %2(%3) : $@convention(thin) (@thin S2.Type) -> S2 // user: %5 + store %4 to %1 : $*S2 // id: %5 + %6 = struct_extract %0 : $Bool, #Bool.value // user: %7 + cond_br %6, bb1, bb2 // id: %7 + +bb1: // Preds: bb0 + %8 = integer_literal $Builtin.Int64, 0 // user: %9 + %9 = struct $Int (%8 : $Builtin.Int64) // user: %12 + %10 = struct_element_addr %1 : $*S2, #S2.x // user: %11 + %11 = struct_element_addr %10 : $*S1, #S1.a // user: %12 + store %9 to %11 : $*Int // id: %12 + br bb3 // id: %13 + +bb2: // Preds: bb0 + %14 = integer_literal $Builtin.Int64, 1 // user: %15 + %15 = struct $Int (%14 : $Builtin.Int64) // user: %18 + %16 = struct_element_addr %1 : $*S2, #S2.x // user: %17 + %17 = struct_element_addr %16 : $*S1, #S1.a // user: %18 + store %15 to %17 : $*Int // id: %18 + br bb3 // id: %19 + +bb3: // Preds: bb1 bb2 + %20 = integer_literal $Builtin.Int64, 2 // user: %21 + %21 = struct $Int (%20 : $Builtin.Int64) // user: %24 + %22 = struct_element_addr %1 : $*S2, #S2.x // user: %23 + %23 = struct_element_addr %22 : $*S1, #S1.a // user: %24 + store %21 to %23 : $*Int // id: %24 + %25 = tuple () // user: %27 + dealloc_stack %1 : $*S2 // id: %26 + return %25 : $() // id: %27 +} + +// Remove dead stores in split and else block on a complex struct. +// +// CHECK-LABEL: DeadStoreInSplitElseBlockComplexStruct +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: br +// CHECK: bb3: +// CHECK-NOT: store +// CHECK: br +sil hidden @DeadStoreInSplitElseBlockComplexStruct : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $S2 // users: %5, %9, %17, %23, %27 + // function_ref S2_init + %2 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %4 + %3 = metatype $@thin S2.Type // user: %4 + %4 = apply %2(%3) : $@convention(thin) (@thin S2.Type) -> S2 // user: %5 + store %4 to %1 : $*S2 // id: %5 + br bb1 // id: %6 + +bb1: // Preds: bb0 + %7 = integer_literal $Builtin.Int64, 0 // user: %8 + %8 = struct $Int (%7 : $Builtin.Int64) // user: %11 + %9 = struct_element_addr %1 : $*S2, #S2.x // user: %10 + %10 = struct_element_addr %9 : $*S1, #S1.a // user: %11 + store %8 to %10 : $*Int // id: %11 + %12 = struct_extract %0 : $Bool, #Bool.value // user: %13 + cond_br %12, bb2, bb3 // id: %13 + +bb2: // Preds: bb1 + br bb4 // id: %14 + +bb3: // Preds: bb1 + %15 = integer_literal $Builtin.Int64, 1 // user: %16 + %16 = struct $Int (%15 : $Builtin.Int64) // user: %19 + %17 = struct_element_addr %1 : $*S2, #S2.x // user: %18 + %18 = struct_element_addr %17 : $*S1, #S1.a // user: %19 + store %16 to %18 : $*Int // id: %19 + br bb4 // id: %20 + +bb4: // Preds: bb2 bb3 + %21 = integer_literal $Builtin.Int64, 2 // user: %22 + %22 = struct $Int (%21 : $Builtin.Int64) // user: %25 + %23 = struct_element_addr %1 : $*S2, #S2.x // user: %24 + %24 = struct_element_addr %23 : $*S1, #S1.a // user: %25 + store %22 to %24 : $*Int // id: %25 + %26 = tuple () // user: %28 + dealloc_stack %1 : $*S2 // id: %27 + return %26 : $() // id: %28 +} + +// Remove dead store in 1 loop block, as the store in exit block kills it. +// +// CHECK-LABEL: DeadStoreSingleLoopBlockSimpleStruct +// CHECK: bb2: +// CHECK: store +// CHECK: br +sil hidden @DeadStoreSingleLoopBlockSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1, var, name "x" // users: %8, %13, %18, %23, %26 + %5 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %7 + %6 = metatype $@thin S1.Type // user: %7 + %7 = apply %5(%6) : $@convention(thin) (@thin S1.Type) -> S1 // user: %8 + store %7 to %2 : $*S1 // id: %8 + br bb1 + +bb1: // Preds: bb0 + %11 = integer_literal $Builtin.Int64, 0 // user: %12 + %12 = struct $Int (%11 : $Builtin.Int64) // user: %14 + %13 = struct_element_addr %2 : $*S1, #S1.a // user: %14 + %14 = load %13 : $*Int + br bb2 // id: %15 + +bb2: // Preds: bb0 + %16 = integer_literal $Builtin.Int64, 1 // user: %17 + %17 = struct $Int (%16 : $Builtin.Int64) // user: %19 + %18 = struct_element_addr %2 : $*S1, #S1.a // user: %19 + store %17 to %18 : $*Int // id: %19 + %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 + cond_br %9, bb1, bb3 // id: %10 + +bb3: // Preds: bb1 bb2 + %21 = integer_literal $Builtin.Int64, 2 // user: %22 + %22 = struct $Int (%21 : $Builtin.Int64) // user: %24 + %23 = struct_element_addr %2 : $*S1, #S1.a // user: %24 + store %22 to %23 : $*Int // id: %24 + %25 = tuple () // user: %27 + dealloc_stack %2 : $*S1 // id: %26 + return %25 : $() // id: %27 +} + +// Remove dead stores in loop blocks, as the store in exit block kills them. +// +// CHECK-LABEL: DeadStoreInMultiLoopBlocksSimpleStruct +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: br +// CHECK: bb2: +// CHECK-NOT: store +// CHECK: br +sil hidden @DeadStoreInMultiLoopBlocksSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1, var, name "x" // users: %8, %13, %18, %23, %26 + %5 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %7 + %6 = metatype $@thin S1.Type // user: %7 + %7 = apply %5(%6) : $@convention(thin) (@thin S1.Type) -> S1 // user: %8 + store %7 to %2 : $*S1 // id: %8 + br bb1 + +bb1: // Preds: bb0 + %11 = integer_literal $Builtin.Int64, 0 // user: %12 + %12 = struct $Int (%11 : $Builtin.Int64) // user: %14 + %13 = struct_element_addr %2 : $*S1, #S1.a // user: %14 + store %12 to %13 : $*Int // id: %14 + br bb2 // id: %15 + +bb2: // Preds: bb0 + %16 = integer_literal $Builtin.Int64, 1 // user: %17 + %17 = struct $Int (%16 : $Builtin.Int64) // user: %19 + %18 = struct_element_addr %2 : $*S1, #S1.a // user: %19 + store %17 to %18 : $*Int // id: %19 + %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 + cond_br %9, bb1, bb3 // id: %10 + +bb3: // Preds: bb1 bb2 + %21 = integer_literal $Builtin.Int64, 2 // user: %22 + %22 = struct $Int (%21 : $Builtin.Int64) // user: %24 + %23 = struct_element_addr %2 : $*S1, #S1.a // user: %24 + store %22 to %23 : $*Int // id: %24 + %25 = tuple () // user: %27 + dealloc_stack %2 : $*S1 // id: %26 + return %25 : $() // id: %27 +} + +// Remove dead store in the tuple data structure. +// +// CHECK-LABEL: DeadStoreInSimpleTuple +// CHECK: bb0: +// CHECK: store +// CHECK: store +// CHECK-NOT: store +// CHECK: load +sil hidden @DeadStoreInSimpleTuple : $@convention(thin) () -> Int { +bb0: + %0 = alloc_stack $(a: Int, b: Int), var, name "x" // users: %1, %2, %11, %15, %20 + %1 = tuple_element_addr %0 : $*(a: Int, b: Int), 0 // user: %5 + %2 = tuple_element_addr %0 : $*(a: Int, b: Int), 1 // user: %8 + %3 = integer_literal $Builtin.Int64, 2 // user: %4 + %4 = struct $Int (%3 : $Builtin.Int64) // user: %5 + store %4 to %1 : $*Int // id: %5 + %6 = integer_literal $Builtin.Int64, 2 // user: %7 + %7 = struct $Int (%6 : $Builtin.Int64) // user: %8 + store %7 to %2 : $*Int // id: %8 + %9 = integer_literal $Builtin.Int64, 10 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = tuple_element_addr %0 : $*(a: Int, b: Int), 0 // user: %12 + store %10 to %11 : $*Int // id: %12 + %13 = integer_literal $Builtin.Int64, 12 // user: %14 + %14 = struct $Int (%13 : $Builtin.Int64) // user: %16 + %15 = tuple_element_addr %0 : $*(a: Int, b: Int), 1 // user: %16 + store %14 to %15 : $*Int // id: %16 + %22 = load %15 : $*Int + %23 = load %11 : $*Int + %24 = load %2 : $*Int + %25 = load %1 : $*Int + %17 = integer_literal $Builtin.Int64, 22 // user: %19 + %18 = tuple () + %19 = struct $Int (%17 : $Builtin.Int64) // user: %21 + dealloc_stack %0 : $*(a: Int, b: Int) // id: %20 + return %19 : $Int // id: %21 +} + +// Remove dead stores in if else blocks for simple class. +// +// CHECK-LABEL: DeadStoreInIfElseSimpleClass +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: br +// CHECK: bb2: +// CHECK-NOT: store +// CHECK: br +sil hidden @DeadStoreInIfElseSimpleClass : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $foo // users: %8, %36 + %3 = alloc_ref $foo // users: %6, %8, %11, %14, %17, %19, %22, %25, %27, %30, %33, %34 + %4 = integer_literal $Builtin.Int64, 10 // user: %5 + %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 + %6 = ref_element_addr %3 : $foo, #foo.a // user: %7 + store %5 to %6 : $*Int // id: %7 + store %3 to %1 : $*foo // id: %8 + %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 + cond_br %9, bb1, bb2 // id: %10 + +bb1: // Preds: bb0 + %12 = integer_literal $Builtin.Int64, 11 // user: %13 + %13 = struct $Int (%12 : $Builtin.Int64) // user: %15 + %14 = ref_element_addr %3 : $foo, #foo.a // user: %15 + store %13 to %14 : $*Int // id: %15 + %16 = tuple () + br bb3 // id: %18 + +bb2: // Preds: bb0 + %20 = integer_literal $Builtin.Int64, 12 // user: %21 + %21 = struct $Int (%20 : $Builtin.Int64) // user: %23 + %22 = ref_element_addr %3 : $foo, #foo.a // user: %23 + store %21 to %22 : $*Int // id: %23 + %24 = tuple () + br bb3 // id: %26 + +bb3: // Preds: bb1 bb2 + strong_retain %3 : $foo // id: %27 + %28 = integer_literal $Builtin.Int64, 13 // user: %29 + %29 = struct $Int (%28 : $Builtin.Int64) // user: %31 + %30 = ref_element_addr %3 : $foo, #foo.a // user: %31 + store %29 to %30 : $*Int // id: %31 + %32 = tuple () + strong_release %3 : $foo // id: %33 + strong_release %3 : $foo // id: %34 + %35 = tuple () // user: %37 + dealloc_stack %1 : $*foo // id: %36 + return %35 : $() // id: %37 +} + +// Remove dead store in split block for simple class. +// +// CHECK-LABEL: DeadStoreInSplitSimpleClass +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: cond_br +sil hidden @DeadStoreInSplitSimpleClass : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $foo // users: %3, %25 + %2 = alloc_ref $foo // users: %3, %7, %13, %19, %23 + store %2 to %1 : $*foo // id: %3 + br bb1 // id: %4 + +bb1: // Preds: bb0 + %5 = integer_literal $Builtin.Int64, 10 // user: %6 + %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 + %7 = ref_element_addr %2 : $foo, #foo.a // user: %8 + store %6 to %7 : $*Int // id: %8 + %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 + cond_br %9, bb2, bb3 // id: %10 + +bb2: // Preds: bb1 + %11 = integer_literal $Builtin.Int64, 11 // user: %12 + %12 = struct $Int (%11 : $Builtin.Int64) // user: %14 + %13 = ref_element_addr %2 : $foo, #foo.a // user: %14 + store %12 to %13 : $*Int // id: %14 + %15 = tuple () + br bb4 // id: %16 + +bb3: // Preds: bb1 + %17 = integer_literal $Builtin.Int64, 12 // user: %18 + %18 = struct $Int (%17 : $Builtin.Int64) // user: %20 + %19 = ref_element_addr %2 : $foo, #foo.a // user: %20 + store %18 to %19 : $*Int // id: %20 + %21 = tuple () + br bb4 // id: %22 + +bb4: // Preds: bb2 bb3 + strong_release %2 : $foo // id: %23 + %24 = tuple () // user: %26 + dealloc_stack %1 : $*foo // id: %25 + return %24 : $() // id: %26 +} + +// Cannot remove partially dead store in split block for simple class. +// +// CHECK-LABEL: partial_dead_store_simple_class +// CHECK: bb1: +// CHECK: store +// CHECK: cond_br +sil hidden @partial_dead_store_simple_class : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $foo // users: %3, %20 + %2 = alloc_ref $foo // users: %3, %7, %14, %18 + store %2 to %1 : $*foo // id: %3 + br bb1 // id: %4 + +bb1: // Preds: bb0 + %5 = integer_literal $Builtin.Int64, 10 // user: %6 + %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 + %7 = ref_element_addr %2 : $foo, #foo.a // user: %8 + store %6 to %7 : $*Int // id: %8 + %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 + cond_br %9, bb2, bb3 // id: %10 + +bb2: // Preds: bb1 + br bb4 // id: %11 + +bb3: // Preds: bb1 + %12 = integer_literal $Builtin.Int64, 12 // user: %13 + %13 = struct $Int (%12 : $Builtin.Int64) // user: %15 + %14 = ref_element_addr %2 : $foo, #foo.a // user: %15 + store %13 to %14 : $*Int // id: %15 + %16 = tuple () + br bb4 // id: %17 + +bb4: // Preds: bb2 bb3 + strong_release %2 : $foo // id: %18 + %19 = tuple () // user: %21 + dealloc_stack %1 : $*foo // id: %20 + return %19 : $() // id: %21 +} + +// Cannot remove partially dead store in split block for simple class. +// +// CHECK-LABEL: partial_dead_store_with_function_call +// CHECK: bb1: +// CHECK: store +// CHECK: cond_br +sil hidden @partial_dead_store_with_function_call : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $foo // users: %8, %36 + %3 = alloc_ref $foo // users: %6, %8, %11, %14, %17, %19, %22, %25, %27, %30, %33, %34 + store %3 to %1 : $*foo // id: %8 + br bb1 + +bb1: + %4 = integer_literal $Builtin.Int64, 10 // user: %5 + %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 + %6 = ref_element_addr %3 : $foo, #foo.a // user: %7 + store %5 to %6 : $*Int // id: %7 + %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 + cond_br %9, bb2, bb3 // id: %10 + +bb2: // Preds: bb0 + %32 = function_ref @foo_user : $@convention(thin) (@guaranteed foo) -> ()// user: %4 + %33 = apply %32(%3) : $@convention(thin) (@guaranteed foo) -> () // users: %6, %15 + %120 = integer_literal $Builtin.Int64, 12 // user: %21 + %121 = struct $Int (%120 : $Builtin.Int64) // user: %23 + store %121 to %6 : $*Int // id: %23 + %124 = tuple () + br bb4 // id: %18 + +bb3: // Preds: bb0 + %20 = integer_literal $Builtin.Int64, 12 // user: %21 + %21 = struct $Int (%20 : $Builtin.Int64) // user: %23 + store %21 to %6 : $*Int // id: %23 + %24 = tuple () + br bb4 // id: %26 + +bb4: // Preds: bb1 bb2 + strong_release %3 : $foo // id: %34 + %35 = tuple () // user: %37 + dealloc_stack %1 : $*foo // id: %36 + return %35 : $() // id: %37 +} + +// Remove dead store in same basic block, test for alias analysis/side effect. +// Currently, %14 = apply %13(%10) is marked as having side effect on the +// store %8 to %9 : $*Int // id: %15 +// +// CHECK-LABEL: DeadStoreSameBlockAcrossFunctionCallSimpleStruct +// CHECK: bb1: +// CHECK-NOT: store +// CHECK: function_ref +sil hidden @DeadStoreSameBlockAcrossFunctionCallSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1 // users: %6, %9, %18 + // function_ref S1_init + %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 + %4 = metatype $@thin S1.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 + store %5 to %2 : $*S1 // id: %6 + %7 = integer_literal $Builtin.Int64, 0 // user: %8 + %8 = struct $Int (%7 : $Builtin.Int64) // users: %12, %15 + %9 = struct_element_addr %2 : $*S1, #S1.a // users: %12, %15 + %10 = alloc_ref $foo // user: %14 + br bb1 // id: %11 + +bb1: // Preds: bb0 + store %8 to %9 : $*Int // id: %12 + %13 = function_ref @foo_user : $@convention(thin) (@guaranteed foo) -> () // user: %14 + %14 = apply %13(%10) : $@convention(thin) (@guaranteed foo) -> () + store %8 to %9 : $*Int // id: %15 + br bb2 // id: %16 + +bb2: // Preds: bb1 + %17 = tuple () // user: %19 + dealloc_stack %2 : $*S1 // id: %18 + return %17 : $() // id: %19 +} + + +// store to stack allocated memory cannot alias with incoming argument. +// +// CHECK-LABEL: DeadStoreInoutAndStackAlias +// CHECK: bb0 +// CHECK : struct_element_addr +// CHECK-NOT: store +// CHECK: load +sil hidden @DeadStoreInoutAndStackAlias : $@convention(thin) (@inout A) -> () { +bb0(%0 : $*A): + %1 = alloc_stack $A // users: %4, %8 + %2 = integer_literal $Builtin.Int32, 0 // users: %5, %7 + %3 = struct_element_addr %0 : $*A, #A.i // user: %6 + %4 = struct_element_addr %1 : $*A, #A.i // users: %5, %7 + store %2 to %4 : $*Builtin.Int32 // id: %5 + %6 = load %3 : $*Builtin.Int32 + store %2 to %4 : $*Builtin.Int32 // id: %7 + dealloc_stack %1 : $*A // id: %8 + %9 = tuple () // user: %10 + return %9 : $() // id: %10 +} + +// test dead store for enums. there should be only 1 store left. +// +// CHECK-LABEL: DeadStoreEnumSameCase +// CHECK: store +// CHECK-NOT: store +// CHECK: return +sil hidden @DeadStoreEnumSameCase : $@convention(thin) (@inout Example) -> Int64 { +bb0(%0 : $*Example): + %1 = integer_literal $Builtin.Int64, 64 // user: %2 + %2 = struct $Int64 (%1 : $Builtin.Int64) // user: %5 + %3 = integer_literal $Builtin.Int64, 64 // user: %4 + %4 = struct $Int64 (%3 : $Builtin.Int64) // user: %5 + %5 = tuple (%2 : $Int64, %4 : $Int64) // user: %6 + %6 = enum $Example, #Example.A!enumelt.1, %5 : $(Int64, Int64) // users: %7, %15 + store %6 to %0 : $*Example // id: %7 + %8 = integer_literal $Builtin.Int64, 64 // user: %9 + %9 = struct $Int64 (%8 : $Builtin.Int64) // user: %12 + %10 = integer_literal $Builtin.Int64, 64 // user: %11 + %11 = struct $Int64 (%10 : $Builtin.Int64) // user: %12 + %12 = tuple (%9 : $Int64, %11 : $Int64) // user: %13 + %13 = enum $Example, #Example.A!enumelt.1, %12 : $(Int64, Int64) // users: %14, %18 + store %13 to %0 : $*Example // id: %14 + release_value %6 : $Example // id: %15 + %16 = integer_literal $Builtin.Int64, 0 // user: %17 + %17 = struct $Int64 (%16 : $Builtin.Int64) // user: %20 + release_value %13 : $Example // id: %18 + return %17 : $Int64 // id: %20 +} + +// The store in bb0 as the its only partially dead, i.e. +// the structure S3 has 2 fields. +// +// CHECK-LABEL: PartialDeadStoreSimpleStruct +// CHECK: bb0 +// CHECK-NEXT: [[RET0:%.+]] = alloc_stack +// CHECK: [[RET1:%.+]] = function_ref @S3_init +// CHECK-NEXT: [[RET2:%.+]] = metatype $@thin S3.Type +// CHECK-NEXT: [[RET3:%.+]] = apply [[RET1:%.+]]([[RET2:%.+]]) +// CHECK-NOT: store [[RET3:%.+]] to [[RET0:%.+]]#1 : $*S3 +sil hidden @PartialDeadStoreSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S3 // users: %6, %11, %16, %20 + // function_ref S3_init + %3 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %5 + %4 = metatype $@thin S3.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S3.Type) -> S3 // user: %6 + store %5 to %2 : $*S3 // id: %6 + %7 = struct_extract %0 : $Bool, #Bool.value // user: %8 + cond_br %7, bb1, bb2 // id: %8 + +bb1: // Preds: bb0 + %9 = integer_literal $Builtin.Int64, 0 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %2 : $*S3, #S3.a // user: %12 + store %10 to %11 : $*Int // id: %12 + br bb3 // id: %13 + +bb2: // Preds: bb0 + %14 = integer_literal $Builtin.Int64, 1 // user: %15 + %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 + %16 = struct_element_addr %2 : $*S3, #S3.a // user: %17 + store %15 to %16 : $*Int // id: %17 + br bb3 // id: %18 + +bb3: // Preds: bb1 bb2 + %19 = tuple () // user: %21 + dealloc_stack %2 : $*S3 // id: %20 + return %19 : $() // id: %21 +} + +/// Make sure we can coalesce the 2 live stores to the 2 fields in S4. +/// +/// CHECK-LABEL : PartialDeadStoreStructInStruct +/// CHECK: [[RET0:%.+]] = struct_extract +/// CHECK: [[RET1:%.+]] = struct_element_addr +/// CHECK: store [[RET0:%.+]] to [[RET1:%.+]] : $*S4 +sil hidden @PartialDeadStoreStructInStruct : $@convention(thin) (@inout S5) -> () { +bb0(%0 : $*S5): + %1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> S5 // user: %3 + %2 = metatype $@thin S5.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> S5 // user: %4 + store %3 to %0 : $*S5 // id: %4 + %5 = integer_literal $Builtin.Int64, 11 // user: %6 + %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 + %7 = struct_element_addr %0 : $*S5, #S5.y // user: %8 + store %6 to %7 : $*Int // id: %8 + %9 = tuple () // user: %11 + return %9 : $() // id: %11 +} + +/// Make sure we do not coalesce the 2 live stores to the 2 fields in S6. +/// +/// CHECK-LABEL : DiscontiguousPartialDeadStoreInSimpleStruct +/// CHECK: store +/// CHECK: store +/// CHECK: store +sil hidden @DiscontiguousPartialDeadStoreInSimpleStruct : $@convention(thin) (@inout S6) -> () { +bb0(%0 : $*S6): + %1 = function_ref @S6_init : $@convention(thin) (@thin S6.Type) -> S6 // user: %3 + %2 = metatype $@thin S6.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S6.Type) -> S6 // user: %4 + store %3 to %0 : $*S6 // id: %4 + %5 = integer_literal $Builtin.Int64, 10 // user: %6 + %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 + %7 = struct_element_addr %0 : $*S6, #S6.y // user: %8 + store %6 to %7 : $*Int // id: %8 + %9 = tuple () // user: %11 + return %9 : $() // id: %11 +} + +/// Make sure we do not generate too many stores from a large store that +/// is partially dead. +/// +/// CHECK-LABEL : DiscontiguousPartialDeadStoreInSimpleLargeStruct +/// CHECK: store +/// CHECK-NOT: store +/// CHECK: store +sil hidden @DiscontiguousPartialDeadStoreInSimpleLargeStruct : $@convention(thin) (@inout S7) -> () { +bb0(%0 : $*S7): + %1 = function_ref @S7_init : $@convention(thin) (@thin S7.Type) -> S7 // user: %3 + %2 = metatype $@thin S7.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S7.Type) -> S7 // user: %4 + store %3 to %0 : $*S7 // id: %4 + %5 = integer_literal $Builtin.Int64, 10 // user: %6 + %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 + %7 = struct_element_addr %0 : $*S7, #S7.y // user: %8 + store %6 to %7 : $*Int // id: %8 + %9 = tuple () // user: %11 + return %9 : $() // id: %11 +} + +/// We are not performing partial dead store for store %3 to %0#1 : $*S7, +/// i.e. too many stores generated, but make sure we track the store correctly +/// so that we can get rid of store %56 to %57 : $*Int. +/// +/// CHECK-LABEL : PartialDeadStoreBailOutProperPropagation +/// CHECK: bb0 +/// CHECK-NOT: store +/// CHECK: function_ref +sil hidden @PartialDeadStoreBailOutProperPropagation : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S7, var, name "a" // users: %4, %7, %10 + %55 = integer_literal $Builtin.Int64, 10 // user: %6 + %56 = struct $Int (%55 : $Builtin.Int64) // user: %8 + %57 = struct_element_addr %0 : $*S7, #S7.a // user: %8 + store %56 to %57 : $*Int // id: %8 + %1 = function_ref @S7_init : $@convention(thin) (@thin S7.Type) -> S7 // user: %3 + %2 = metatype $@thin S7.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S7.Type) -> S7 // user: %4 + store %3 to %0 : $*S7 // id: %4 + %5 = integer_literal $Builtin.Int64, 10 // user: %6 + %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 + %7 = struct_element_addr %0 : $*S7, #S7.y // user: %8 + store %6 to %7 : $*Int // id: %8 + %9 = tuple () // user: %11 + dealloc_stack %0 : $*S7 // id: %10 + return %9 : $() // id: %11 +} + +/// Make sure we do perform partial dead store for the first store. +/// we have a case which partial dead store miscompiles a program, +/// in that case the bitvector is not tracked correctly and we end +/// up deleting the entire larger store, store %3 to %0#1 : $*S3 in +/// this case. +/// +/// CHECK-LABEL: PartialDeadStoreInSimpleSmallStruct +/// CHECK: apply +/// CHECK-NEXT: struct_extract +sil hidden @PartialDeadStoreInSimpleSmallStruct : $@convention(thin) (@inout S3) -> () { +bb0(%0 : $*S3): + %1 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %3 + %2 = metatype $@thin S3.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S3.Type) -> S3 // user: %4 + store %3 to %0 : $*S3 // id: %4 + %5 = integer_literal $Builtin.Int64, 10 // user: %6 + %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 + %7 = struct_element_addr %0 : $*S3, #S3.a // user: %8 + store %6 to %7 : $*Int // id: %8 + %9 = tuple () // user: %11 + return %9 : $() // id: %11 +} + +/// Make sure we do not hang in this test case. Test for Location::expand. +/// expand should stop on class type. Also need to get rid of the partial +/// dead store. +/// +/// CHECK-LABEL: SelfLoopClassTestTypeExpansion +/// CHECK: [[RET0:%.+]] = struct_extract +/// CHECK: [[RET1:%.+]] = struct_element_addr +/// CHECK-NEXT: store [[RET0:%.+]] to [[RET1:%.+]] : $*SelfLoop +sil hidden @SelfLoopClassTestTypeExpansion : $@convention(thin) (@inout S8) -> () { +bb0(%0 : $*S8): + %1 = function_ref @S8_init : $@convention(thin) (@thin S8.Type) -> @owned S8 // user: %3 + %2 = metatype $@thin S8.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S8.Type) -> @owned S8 // users: %4, %9 + store %3 to %0 : $*S8 // id: %4 + %5 = integer_literal $Builtin.Int64, 12 // user: %6 + %6 = struct $Int (%5 : $Builtin.Int64) // users: %8, %10 + %7 = struct_element_addr %0 : $*S8, #S8.k // user: %8 + store %6 to %7 : $*Int // id: %8 + %9 = struct_extract %3 : $S8, #S8.i // user: %10 + %10 = struct $S8 (%9 : $SelfLoop, %6 : $Int) // user: %11 + release_value %10 : $S8 // id: %11 + %12 = tuple () // user: %14 + return %12 : $() // id: %14 +} + +/// Make sure we do not remove the first store as there is no way to prove +/// %0 and %1 cannot alias here. +/// +/// CHECK-LABEL: NoDeadStoreWithInterferingLoad +/// CHECK: store +/// CHECK: load +/// CHECK: store +sil hidden @NoDeadStoreWithInterferingLoad : $@convention(thin) (@owned foo, @owned foo) -> () { +bb0(%0 : $foo, %1 : $foo): + debug_value %0 : $foo, let, name "x" // id: %2 + debug_value %1 : $foo, let, name "a" // id: %3 + %4 = integer_literal $Builtin.Int64, 10 // user: %5 + %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 + %6 = ref_element_addr %0 : $foo, #foo.a // user: %7 + store %5 to %6 : $*Int // id: %7 + %8 = tuple () + %9 = integer_literal $Builtin.Int64, 12 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = ref_element_addr %1 : $foo, #foo.a // user: %12 + %99 = load %11 : $*Int // id: %12 + %13 = tuple () + %14 = integer_literal $Builtin.Int64, 10 // user: %15 + %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 + %16 = ref_element_addr %0 : $foo, #foo.a // user: %17 + store %15 to %16 : $*Int // id: %17 + %18 = tuple () + strong_release %1 : $foo // id: %19 + strong_release %0 : $foo // id: %20 + %21 = tuple () // user: %22 + return %21 : $() // id: %22 +} + +// Remove the dead stores in the entry block as the store in bb2 +// kills them. This test how the optimistic data flow works. +// +// CHECK-LABEL: DeadStoreAcrossLoopSimpleStruct +// CHECK: bb0 +// CHECK-NOT: store +// CHECK: br +sil hidden @DeadStoreAcrossLoopSimpleStruct : $@convention(thin) (Bool, Int) -> () { +bb0(%0 : $Bool, %1 : $Int): + %2 = alloc_stack $S1 // users: %6, %9, %16, %19 + %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 + %4 = metatype $@thin S1.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 + store %5 to %2 : $*S1 // id: %6 + %7 = integer_literal $Builtin.Int64, 2 // user: %8 + %8 = struct $Int (%7 : $Builtin.Int64) // user: %10 + %9 = struct_element_addr %2 : $*S1, #S1.a // user: %10 + store %8 to %9 : $*Int // id: %10 + br bb1 // id: %11 + +bb1: // Preds: bb0 bb1 + %12 = struct_extract %0 : $Bool, #Bool.value // user: %13 + cond_br %12, bb1, bb2 // id: %13 + +bb2: // Preds: bb1 + %14 = integer_literal $Builtin.Int64, 2 // user: %15 + %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 + %16 = struct_element_addr %2 : $*S1, #S1.a // user: %17 + store %15 to %16 : $*Int // id: %17 + %18 = tuple () // user: %20 + dealloc_stack %2 : $*S1 // id: %19 + return %18 : $() // id: %20 +} + + +// Make sure the load in bb1 prevents the store in bb0 to be eliminated. we have a bug +// in constructing kill set when it is not conservative enough. i.e. this test case +// makes sure the killset for bb1 includes the kill for the store in bb2. +// +// CHECK-LABEL: conservative_kill_set_class +// CHECK: bb0 +// CHECK: store +// CHECK: br bb1 +sil hidden @conservative_kill_set_class : $@convention(thin) (@owned foo, @owned foo) -> () { +bb0(%0 : $foo, %1 : $foo): + %4 = integer_literal $Builtin.Int64, 10 // user: %5 + %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 + %6 = ref_element_addr %0 : $foo, #foo.a // user: %17 + store %5 to %6 : $*Int + br bb1 + +bb1: + %7 = ref_element_addr %1 : $foo, #foo.a // user: %17 + %8 = load %7 : $*Int + br bb2 + +bb2: + %9 = integer_literal $Builtin.Int64, 10 // user: %5 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %7 + %11 = ref_element_addr %0 : $foo, #foo.a // user: %17 + store %5 to %6 : $*Int + %18 = tuple () // user: %19 + return %18 : $() // id: %19 +} + +/// Make sure we DO NOT get rid of the first store as a dead store. +/// +/// CHECK-LABEL: tbaa_no_alias_no_dead_store +/// CHECK: store +/// CHECK: load +sil @tbaa_no_alias_no_dead_store : $@convention(thin) (Optional.Type>) -> Int { +bb0(%0 : $Optional.Type>): + %2 = alloc_stack $Optional.Type> // users: %3, %17, %19, %26 + store %0 to %2 : $*Optional.Type> // id: %3 + %17 = unchecked_addr_cast %2 : $*Optional.Type> to $*Int // user: %18 + %18 = load %17 : $*Int // user: %27 + dealloc_stack %2 : $*Optional.Type> // id: %26 + return %18 : $Int // id: %27 +} + +/// Make sure we DO get rid of the store as a dead store, i.e. no read to a store +/// to a local variable. +/// +/// CHECK-LABEL: local_dead_store +/// CHECK: load +/// CHECK-NOT: store +/// CHECK: return +sil @local_dead_store : $@convention(thin) (Optional.Type>) -> Int { +bb0(%0 : $Optional.Type>): + %2 = alloc_stack $Optional.Type> // users: %3, %17, %19, %26 + %17 = unchecked_addr_cast %2 : $*Optional.Type> to $*Int // user: %18 + %18 = load %17 : $*Int // user: %27 + store %0 to %2 : $*Optional.Type> // id: %3 + dealloc_stack %2 : $*Optional.Type> // id: %26 + return %18 : $Int // id: %27 +} diff --git a/test/SILPasses/dead_witness_module.swift b/test/SILOptimizer/dead_witness_module.swift similarity index 100% rename from test/SILPasses/dead_witness_module.swift rename to test/SILOptimizer/dead_witness_module.swift diff --git a/test/SILPasses/definite_init.sil b/test/SILOptimizer/definite_init.sil similarity index 91% rename from test/SILPasses/definite_init.sil rename to test/SILOptimizer/definite_init.sil index ff3d738a7a9d0..90c6c3becdf3a 100644 --- a/test/SILPasses/definite_init.sil +++ b/test/SILOptimizer/definite_init.sil @@ -143,7 +143,7 @@ bb0(%0 : $*T, %1 : $*T): sil @takes_closure : $@convention(thin) (@callee_owned () -> ()) -> () -sil @closure0 : $@convention(thin) (@owned @box Int, @inout Int) -> () +sil @closure0 : $@convention(thin) (@owned @box Int) -> () // CHECK-LABEL: sil @closure_test sil @closure_test : $@convention(thin) () -> () { @@ -152,9 +152,10 @@ bb0: %0 = mark_uninitialized [var] %1#1 : $*Int // expected-note {{variable defined here}} %5 = function_ref @takes_closure : $@convention(thin) (@callee_owned () -> ()) -> () - %6 = function_ref @closure0 : $@convention(thin) (@owned @box Int, @inout Int) -> () + %6 = function_ref @closure0 : $@convention(thin) (@owned @box Int) -> () strong_retain %1#0 : $@box Int - %8 = partial_apply %6(%1#0, %0) : $@convention(thin) (@owned @box Int, @inout Int) -> () // expected-error {{variable '' captured by a closure before being initialized}} + mark_function_escape %0 : $*Int // expected-error {{variable '' used by function definition before being initialized}} + %8 = partial_apply %6(%1#0) : $@convention(thin) (@owned @box Int) -> () %9 = apply %5(%8) : $@convention(thin) (@callee_owned () -> ()) -> () strong_release %1#0 : $@box Int @@ -406,13 +407,13 @@ sil @release_not_constructed : $@convention(thin) () -> () { bb0: // CHECK: bb0: %3 = alloc_stack $SomeClass // CHECK-NEXT: alloc_stack - %c = mark_uninitialized [var] %3#1 : $*SomeClass + %c = mark_uninitialized [var] %3 : $*SomeClass // This should get removed. destroy_addr %c : $*SomeClass - dealloc_stack %3#0 : $*@local_storage SomeClass + dealloc_stack %3 : $*SomeClass // CHECK-NEXT: dealloc_stack // CHECK-NEXT: tuple () @@ -425,7 +426,7 @@ sil @release_some_constructed : $@convention(thin) () -> () { bb0: %0 = tuple () %b = alloc_stack $(SomeClass, SomeClass) - %1 = mark_uninitialized [var] %b#1 : $*(SomeClass, SomeClass) + %1 = mark_uninitialized [var] %b : $*(SomeClass, SomeClass) %2 = function_ref @getSomeClass : $@convention(thin) () -> @owned SomeClass %3 = apply %2() : $@convention(thin) () -> @owned SomeClass @@ -440,7 +441,7 @@ bb0: destroy_addr %1 : $*(SomeClass, SomeClass) // CHECK-NEXT: dealloc_stack - dealloc_stack %b#0 : $*@local_storage (SomeClass, SomeClass) + dealloc_stack %b : $*(SomeClass, SomeClass) %8 = tuple () return %8 : $() } @@ -452,7 +453,7 @@ bb0: sil @init_existential_with_class : $@convention(thin) (@inout C) -> () { entry(%a : $*C): %p = alloc_stack $P - %b = mark_uninitialized [var] %p#1 : $*P + %b = mark_uninitialized [var] %p : $*P %q = init_existential_addr %b : $*P, $C @@ -460,7 +461,7 @@ entry(%a : $*C): copy_addr %a to [initialization] %q : $*C %u = function_ref @use : $@convention(thin) (@in P) -> () %v = apply %u(%b) : $@convention(thin) (@in P) -> () - dealloc_stack %p#0 : $*@local_storage P + dealloc_stack %p : $*P %z = tuple () return %z : $() } @@ -473,11 +474,11 @@ entry(%a : $*C): sil @conditional_init : $@convention(thin) (Bool) -> () { bb0(%0 : $Bool): %2 = alloc_stack $SomeClass - %3 = mark_uninitialized [var] %2#1 : $*SomeClass + %3 = mark_uninitialized [var] %2 : $*SomeClass // CHECK: [[CONTROL:%[0-9]+]] = alloc_stack $Builtin.Int1 // CHECK: [[ZERO:%[0-9]+]] = integer_literal $Builtin.Int1, 0 -// CHECK: store [[ZERO]] to [[CONTROL]]#1 : $*Builtin.Int1 +// CHECK: store [[ZERO]] to [[CONTROL]] : $*Builtin.Int1 %5 = integer_literal $Builtin.Int1, 1 cond_br %5, bb1, bb2 @@ -485,7 +486,7 @@ bb1: // CHECK: bb1: // CHECK: function_ref @getSomeClass // CHECK: [[ONE:%[0-9]+]] = integer_literal $Builtin.Int1, -1 -// CHECK: store [[ONE]] to [[CONTROL]]#1 : $*Builtin.Int1 +// CHECK: store [[ONE]] to [[CONTROL]] : $*Builtin.Int1 %f = function_ref @getSomeClass : $@convention(thin) () -> @owned SomeClass %6 = apply %f() : $@convention(thin) () -> @owned SomeClass assign %6 to %3 : $*SomeClass @@ -493,7 +494,7 @@ bb1: bb2: destroy_addr %3 : $*SomeClass - dealloc_stack %2#0 : $*@local_storage SomeClass + dealloc_stack %2 : $*SomeClass %14 = tuple () return %14 : $() } @@ -506,7 +507,7 @@ bb0(%0 : $Builtin.Int1): // CHECK: integer_literal $Builtin.Int1, 0 // CHECK: store %5 = alloc_stack $SomeClass - %6 = mark_uninitialized [var] %5#1 : $*SomeClass + %6 = mark_uninitialized [var] %5 : $*SomeClass cond_br %0, bb1, bb2 bb1: @@ -541,7 +542,7 @@ bb2: assign %17 to %6 : $*SomeClass // id: %18 destroy_addr %6 : $*SomeClass // id: %19 - dealloc_stack %5#0 : $*@local_storage SomeClass // id: %20 + dealloc_stack %5 : $*SomeClass // id: %20 %23 = tuple () // user: %24 return %23 : $() // id: %24 } @@ -670,15 +671,15 @@ struct MyStruct : P {} //CHECK: return sil @self_init_assert_instruction : $@convention(thin) (Int, @thin MyStruct.Type) -> MyStruct { bb0(%0 : $Int, %1 : $@thin MyStruct.Type): - %2 = alloc_stack $MyStruct // var self // users: %3, %10 - %3 = mark_uninitialized [delegatingself] %2#1 : $*MyStruct // users: %8, %9 - debug_value %0 : $Int // let i // id: %4 + %2 = alloc_stack $MyStruct, var, name "sf" // users: %3, %10 + %3 = mark_uninitialized [delegatingself] %2 : $*MyStruct // users: %8, %9 + debug_value %0 : $Int, let, name "i" // id: %4 %6 = function_ref @selfinit : $@convention(thin) () -> MyStruct %7 = apply %6() : $@convention(thin) () -> MyStruct assign %7 to %3 : $*MyStruct %9 = load %3 : $*MyStruct - dealloc_stack %2#0 : $*@local_storage MyStruct + dealloc_stack %2 : $*MyStruct return %9 : $MyStruct } @@ -697,24 +698,24 @@ sil @selfinit_delegate : $@convention(thin) (@out MyStruct2, @thin MyStruct2.Typ sil @self_init_copyaddr : $@convention(thin) (@out MyStruct2, @thin MyStruct2.Type) -> () { bb0(%0 : $*MyStruct2, %1 : $@thin MyStruct2.Type): // CHECK: [[SELF:%[0-9]+]] = alloc_stack $MyStruct2 - %2 = alloc_stack $MyStruct2 // var self - %3 = mark_uninitialized [delegatingself] %2#1 : $*MyStruct2 + %2 = alloc_stack $MyStruct2, var, name "sf" + %3 = mark_uninitialized [delegatingself] %2 : $*MyStruct2 %6 = metatype $@thin MyStruct2.Type %7 = function_ref @selfinit_delegate : $@convention(thin) (@out MyStruct2, @thin MyStruct2.Type) -> () %8 = alloc_stack $MyStruct2 // Make sure this copy_addr ends up being an initialization. - apply %7(%8#1, %6) : $@convention(thin) (@out MyStruct2, @thin MyStruct2.Type) -> () - copy_addr [take] %8#1 to %3 : $*MyStruct2 - dealloc_stack %8#0 : $*@local_storage MyStruct2 + apply %7(%8, %6) : $@convention(thin) (@out MyStruct2, @thin MyStruct2.Type) -> () + copy_addr [take] %8 to %3 : $*MyStruct2 + dealloc_stack %8 : $*MyStruct2 // CHECK: apply - // CHECK-NEXT: copy_addr [take] {{.*}} to [initialization] [[SELF]]#1 : $*MyStruct2 + // CHECK-NEXT: copy_addr [take] {{.*}} to [initialization] [[SELF]] : $*MyStruct2 // CHECK-NEXT: dealloc_stack copy_addr [take] %3 to [initialization] %0 : $*MyStruct2 %13 = tuple () - dealloc_stack %2#0 : $*@local_storage MyStruct2 + dealloc_stack %2 : $*MyStruct2 return %13 : $() } @@ -769,7 +770,7 @@ bb0(%0 : $RootClassWithNontrivialStoredProperties): // CHECK: bb0(%0 : $DerivedClassWithNontrivialStoredProperties): // CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_stack // CHECK-NEXT: store -// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]]#1 +// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]] // CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thick DerivedClassWithNontrivialStoredProperties.Type // CHECK-NEXT: dealloc_partial_ref [[SELF]] : $DerivedClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick DerivedClassWithNontrivialStoredProperties.Type // CHECK-NEXT: dealloc_stack [[SELFBOX]] @@ -777,11 +778,11 @@ bb0(%0 : $RootClassWithNontrivialStoredProperties): sil @test_derived_release : $@convention(method) (@owned DerivedClassWithNontrivialStoredProperties) -> () { bb0(%0 : $DerivedClassWithNontrivialStoredProperties): %1 = alloc_stack $DerivedClassWithNontrivialStoredProperties - %4 = mark_uninitialized [derivedself] %1#1 : $*DerivedClassWithNontrivialStoredProperties + %4 = mark_uninitialized [derivedself] %1 : $*DerivedClassWithNontrivialStoredProperties store %0 to %4 : $*DerivedClassWithNontrivialStoredProperties destroy_addr %4 : $*DerivedClassWithNontrivialStoredProperties - dealloc_stack %1#0 : $*@local_storage DerivedClassWithNontrivialStoredProperties + dealloc_stack %1 : $*DerivedClassWithNontrivialStoredProperties %13 = tuple () return %13 : $() @@ -793,13 +794,13 @@ bb0(%0 : $DerivedClassWithNontrivialStoredProperties): // CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_stack // CHECK-NEXT: store // CHECK-NEXT: alloc_ref -// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]]#1 +// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]] // CHECK-NEXT: ref_element_addr [[SELF]] // CHECK-NEXT: store -// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]]#1 +// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]] // CHECK-NEXT: ref_element_addr [[SELF]] // CHECK-NEXT: destroy_addr -// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]]#1 +// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]] // CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thick DerivedClassWithNontrivialStoredProperties.Type // CHECK-NEXT: dealloc_partial_ref [[SELF]] : $DerivedClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick DerivedClassWithNontrivialStoredProperties.Type // CHECK-NEXT: dealloc_stack [[SELFBOX]] @@ -807,7 +808,7 @@ bb0(%0 : $DerivedClassWithNontrivialStoredProperties): sil @test_derived_partial_release : $@convention(method) (@owned DerivedClassWithNontrivialStoredProperties) -> () { bb0(%0 : $DerivedClassWithNontrivialStoredProperties): %1 = alloc_stack $DerivedClassWithNontrivialStoredProperties - %4 = mark_uninitialized [derivedself] %1#1 : $*DerivedClassWithNontrivialStoredProperties + %4 = mark_uninitialized [derivedself] %1 : $*DerivedClassWithNontrivialStoredProperties store %0 to %4 : $*DerivedClassWithNontrivialStoredProperties %8 = alloc_ref $SomeClass @@ -816,7 +817,7 @@ bb0(%0 : $DerivedClassWithNontrivialStoredProperties): assign %8 to %10 : $*SomeClass destroy_addr %4 : $*DerivedClassWithNontrivialStoredProperties - dealloc_stack %1#0 : $*@local_storage DerivedClassWithNontrivialStoredProperties + dealloc_stack %1 : $*DerivedClassWithNontrivialStoredProperties %13 = tuple () return %13 : $() @@ -868,19 +869,19 @@ bb0(%0 : $RootClassWithNontrivialStoredProperties): // CHECK-LABEL: sil @test_delegating_derived_release // CHECK: bb0(%0 : $DerivedClassWithNontrivialStoredProperties): // CHECK-NEXT: [[SELFBOX:%[0-9]+]] = alloc_stack $DerivedClassWithNontrivialStoredProperties -// CHECK-NEXT: store %0 to [[SELFBOX]]#1 -// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]]#1 +// CHECK-NEXT: store %0 to [[SELFBOX]] +// CHECK-NEXT: [[SELF:%[0-9]+]] = load [[SELFBOX]] // CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick DerivedClassWithNontrivialStoredProperties.Type, [[SELF]] : $DerivedClassWithNontrivialStoredProperties // CHECK-NEXT: dealloc_partial_ref [[SELF]] : $DerivedClassWithNontrivialStoredProperties, [[METATYPE]] : $@thick DerivedClassWithNontrivialStoredProperties.Type -// CHECK-NEXT: dealloc_stack [[SELFBOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELFBOX]] sil @test_delegating_derived_release : $@convention(method) (@owned DerivedClassWithNontrivialStoredProperties) -> () { bb0(%0 : $DerivedClassWithNontrivialStoredProperties): %2 = alloc_stack $DerivedClassWithNontrivialStoredProperties - %4 = mark_uninitialized [delegatingself] %2#1 : $*DerivedClassWithNontrivialStoredProperties + %4 = mark_uninitialized [delegatingself] %2 : $*DerivedClassWithNontrivialStoredProperties store %0 to %4 : $*DerivedClassWithNontrivialStoredProperties destroy_addr %4 : $*DerivedClassWithNontrivialStoredProperties - dealloc_stack %2#0 : $*@local_storage DerivedClassWithNontrivialStoredProperties + dealloc_stack %2 : $*DerivedClassWithNontrivialStoredProperties %13 = tuple () return %13 : $() @@ -936,7 +937,7 @@ bb0(%0 : $Builtin.Int1): // CHECK-NEXT: [[SELF_BOX:%[0-9]+]] = alloc_stack $MyStruct3 %2 = alloc_stack $MyStruct3 - %3 = mark_uninitialized [delegatingself] %2#1 : $*MyStruct3 + %3 = mark_uninitialized [delegatingself] %2 : $*MyStruct3 // CHECK: cond_br %0, [[SUCCESS:bb[0-9]+]], [[EXIT:bb[0-9]+]] cond_br %0, bb1, bb2 @@ -949,8 +950,8 @@ bb1: // CHECK: [[NEW_SELF:%[0-9]+]] = apply {{.*}}() : $@convention(thin) () -> @owned MyStruct3 // CHECK-NEXT: [[SET:%[0-9]+]] = integer_literal $Builtin.Int1, -1 -// CHECK-NEXT: store [[SET]] to [[CONTROL]]#1 : $*Builtin.Int1 -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 : $*MyStruct3 +// CHECK-NEXT: store [[SET]] to [[CONTROL]] : $*Builtin.Int1 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] : $*MyStruct3 // CHECK-NEXT: br [[CHECK:bb[0-9]+]] br bb2 @@ -958,11 +959,11 @@ bb1: // CHECK: [[CHECK]]: bb2: -// CHECK-NEXT: [[BIT:%[0-9]+]] = load [[CONTROL]]#1 : $*Builtin.Int1 +// CHECK-NEXT: [[BIT:%[0-9]+]] = load [[CONTROL]] : $*Builtin.Int1 // CHECK-NEXT: cond_br [[BIT]], [[INITIALIZED:bb[0-9]+]], [[UNINITIALIZED:bb[0-9]+]] // CHECK: [[INITIALIZED]]: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 : $*MyStruct3 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] : $*MyStruct3 // CHECK-NEXT: br [[EXIT:bb[0-9]+]] // CHECK: [[UNINITIALIZED]]: @@ -971,7 +972,7 @@ bb2: // CHECK: [[EXIT]]: destroy_addr %3 : $*MyStruct3 - dealloc_stack %2#0 : $*@local_storage MyStruct3 + dealloc_stack %2 : $*MyStruct3 %15 = tuple () return %15 : $() } @@ -989,7 +990,7 @@ bb0(%0 : $Builtin.Int1): // CHECK-NEXT: [[SELF_BOX:%[0-9]+]] = alloc_stack $MyClass3 %2 = alloc_stack $MyClass3 - %3 = mark_uninitialized [delegatingself] %2#1 : $*MyClass3 + %3 = mark_uninitialized [delegatingself] %2 : $*MyClass3 // CHECK: cond_br %0, [[SUCCESS:bb[0-9]+]], [[EXIT:bb[0-9]+]] cond_br %0, bb1, bb2 @@ -1002,9 +1003,9 @@ bb1: store %6 to %3 : $*MyClass3 // CHECK: [[SET:%[0-9]+]] = integer_literal $Builtin.Int1, -1 -// CHECK-NEXT: store [[SET]] to [[CONTROL]]#1 : $*Builtin.Int1 +// CHECK-NEXT: store [[SET]] to [[CONTROL]] : $*Builtin.Int1 // CHECK: [[NEW_SELF:%[0-9]+]] = apply {{.*}}({{.*}}) : $@convention(thin) (@owned MyClass3) -> @owned MyClass3 -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 : $*MyClass3 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] : $*MyClass3 // CHECK-NEXT: br [[CHECK:bb[0-9]+]] br bb2 @@ -1012,15 +1013,15 @@ bb1: // CHECK: [[CHECK]]: bb2: -// CHECK-NEXT: [[BIT:%[0-9]+]] = load [[CONTROL]]#1 : $*Builtin.Int1 +// CHECK-NEXT: [[BIT:%[0-9]+]] = load [[CONTROL]] : $*Builtin.Int1 // CHECK-NEXT: cond_br [[BIT]], [[INITIALIZED:bb[0-9]+]], [[UNINITIALIZED:bb[0-9]+]] // CHECK: [[INITIALIZED]]: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 : $*MyClass3 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] : $*MyClass3 // CHECK-NEXT: br [[EXIT:bb[0-9]+]] // CHECK: [[UNINITIALIZED]]: -// CHECK-NEXT: [[OLD_SELF:%[0-9]+]] = load [[SELF_BOX]]#1 : $*MyClass3 +// CHECK-NEXT: [[OLD_SELF:%[0-9]+]] = load [[SELF_BOX]] : $*MyClass3 // CHECK-NEXT: [[METATYPE:%[0-9]+]] = value_metatype $@thick MyClass3.Type, [[OLD_SELF]] : $MyClass3 // CHECK-NEXT: dealloc_partial_ref [[OLD_SELF]] : $MyClass3, [[METATYPE]] : $@thick MyClass3.Type // CHECK-NEXT: br [[EXIT]] @@ -1028,7 +1029,7 @@ bb2: // CHECK: [[EXIT]]: destroy_addr %3 : $*MyClass3 - dealloc_stack %2#0 : $*@local_storage MyClass3 + dealloc_stack %2 : $*MyClass3 %7 = tuple () return %7 : $() } diff --git a/test/SILPasses/definite_init.swift b/test/SILOptimizer/definite_init.swift similarity index 98% rename from test/SILPasses/definite_init.swift rename to test/SILOptimizer/definite_init.swift index 2a71800c9f461..1e648eb3141a0 100644 --- a/test/SILPasses/definite_init.swift +++ b/test/SILOptimizer/definite_init.swift @@ -10,7 +10,7 @@ func partialInit() { func trivial(ni : Int) { var n = ni while (n > 0) { - --n + n -= 1 var x : Int if (n > 2) { continue } x = 1 diff --git a/test/SILPasses/definite_init_crashes.sil b/test/SILOptimizer/definite_init_crashes.sil similarity index 100% rename from test/SILPasses/definite_init_crashes.sil rename to test/SILOptimizer/definite_init_crashes.sil diff --git a/test/SILPasses/definite_init_diagnostics.swift b/test/SILOptimizer/definite_init_diagnostics.swift similarity index 95% rename from test/SILPasses/definite_init_diagnostics.swift rename to test/SILOptimizer/definite_init_diagnostics.swift index 47880f0bd2cce..ad3d6ec08e6e0 100644 --- a/test/SILPasses/definite_init_diagnostics.swift +++ b/test/SILOptimizer/definite_init_diagnostics.swift @@ -1,10 +1,6 @@ -// RUN: %target-swift-frontend -emit-sil -sdk %S/../SILGen/Inputs %s -I %S/../SILGen/Inputs -enable-source-import -parse-stdlib -o /dev/null -verify - -// FIXME: rdar://problem/19648117 Needs splitting objc parts out -// XFAIL: linux +// RUN: %target-swift-frontend -emit-sil %s -parse-stdlib -o /dev/null -verify import Swift -import gizmo func markUsed(t: T) {} @@ -57,10 +53,16 @@ func test2() { // expected-warning @+1 {{variable 'b1' was never mutated}} {{3-6=let}} var b1 : Int // expected-note {{variable defined here}} - takes_closure { // expected-error {{variable 'b1' used before being initialized}} + takes_closure { // expected-error {{variable 'b1' captured by a closure before being initialized}} markUsed(b1) } + var b1a : Int // expected-note {{variable defined here}} + takes_closure { // expected-error {{variable 'b1a' captured by a closure before being initialized}} + b1a += 1 + markUsed(b1a) + } + var b2 = 4 takes_closure { // ok. markUsed(b2) @@ -72,6 +74,12 @@ func test2() { takes_closure { // ok. markUsed(b3) } + + var b4 : Int? + takes_closure { // ok. + markUsed(b4!) + } + b4 = 7 // Structs var s1 : SomeStruct @@ -133,7 +141,7 @@ func test4() { markUsed(t3.2) - // Partially set, wholey read. + // Partially set, wholly read. var t4 : (Int, Int, Int) // expected-note 1 {{variable defined here}} t4.0 = 1; t4.2 = 42 _ = t4 // expected-error {{variable 't4.1' used before being initialized}} @@ -278,7 +286,7 @@ func emptyStructTest() { func takesTuplePair(inout a : (SomeClass, SomeClass)) {} -// This tests cases where an store might be an init or assign based on control +// This tests cases where a store might be an init or assign based on control // flow path reaching it. func conditionalInitOrAssign(c : Bool, x : Int) { var t : Int // Test trivial types. @@ -567,38 +575,6 @@ enum TrivialEnum : TriviallyConstructible { } } -@requires_stored_property_inits -class RequiresInitsDerived : Gizmo { - var a = 1 - var b = 2 - var c = 3 - - override init() { - super.init() - } - - init(i: Int) { - if i > 0 { - super.init() - } - } // expected-error{{super.init isn't called on all paths before returning from initializer}} - - init(d: Double) { - f() // expected-error {{use of 'self' in method call 'f' before super.init initializes self}} - super.init() - } - - init(t: ()) { - a = 5 // expected-error {{use of 'self' in property access 'a' before super.init initializes self}} - b = 10 // expected-error {{use of 'self' in property access 'b' before super.init initializes self}} - super.init() - c = 15 - } - - func f() { } -} - - // rdar://16119509 - Dataflow problem where we reject valid code. class rdar16119509_Buffer { init(x : Int) { } @@ -715,7 +691,7 @@ class ClassWhoseInitDoesntReturn : BaseWithConvenienceInits { } // DI: Incorrectly diagnostic in delegating init with generic enum -enum r17233681Lazy { +enum r17233681Lazy { case Thunk(() -> T) case Value(T) @@ -1034,7 +1010,7 @@ struct StructMutatingMethodTest { let y : Int init() { x = 42 - ++x // expected-error {{mutating operator '++' may not be used on immutable value 'self.x'}} + x += 1 // expected-error {{mutating operator '+=' may not be used on immutable value 'self.x'}} y = 12 myTransparentFunction(&y) // expected-error {{immutable value 'self.y' may not be passed inout}} @@ -1178,3 +1154,9 @@ func test22436880() { x = 1 bug22436880(&x) // expected-error {{immutable value 'x' may not be passed inout}} } + +// sr-184 +let x: String? // expected-note 2 {{constant defined here}} +print(x?.characters.count) // expected-error {{constant 'x' used before being initialized}} +print(x!) // expected-error {{constant 'x' used before being initialized}} + diff --git a/test/SILOptimizer/definite_init_diagnostics_objc.swift b/test/SILOptimizer/definite_init_diagnostics_objc.swift new file mode 100644 index 0000000000000..c5d62c863d467 --- /dev/null +++ b/test/SILOptimizer/definite_init_diagnostics_objc.swift @@ -0,0 +1,36 @@ +// RUN: %target-swift-frontend -emit-sil -sdk %S/../SILGen/Inputs %s -I %S/../SILGen/Inputs -enable-source-import -parse-stdlib -o /dev/null -verify +// REQUIRES: objc_interop + +import Swift +import gizmo + +@requires_stored_property_inits +class RequiresInitsDerived : Gizmo { + var a = 1 + var b = 2 + var c = 3 + + override init() { + super.init() + } + + init(i: Int) { + if i > 0 { + super.init() + } + } // expected-error{{super.init isn't called on all paths before returning from initializer}} + + init(d: Double) { + f() // expected-error {{use of 'self' in method call 'f' before super.init initializes self}} + super.init() + } + + init(t: ()) { + a = 5 // expected-error {{use of 'self' in property access 'a' before super.init initializes self}} + b = 10 // expected-error {{use of 'self' in property access 'b' before super.init initializes self}} + super.init() + c = 15 + } + + func f() { } +} diff --git a/test/SILPasses/definite_init_failable_initializers.swift b/test/SILOptimizer/definite_init_failable_initializers.swift similarity index 85% rename from test/SILPasses/definite_init_failable_initializers.swift rename to test/SILOptimizer/definite_init_failable_initializers.swift index b4b40c8567617..f353c36f19c06 100644 --- a/test/SILPasses/definite_init_failable_initializers.swift +++ b/test/SILOptimizer/definite_init_failable_initializers.swift @@ -1,4 +1,4 @@ -// RUN: %target-swift-frontend -emit-sil -disable-objc-attr-requires-foundation-module %s | FileCheck %s +// RUN: %target-swift-frontend -use-native-super-method -emit-sil -disable-objc-attr-requires-foundation-module %s | FileCheck %s // High-level tests that DI handles early returns from failable and throwing // initializers properly. The main complication is conditional release of self @@ -43,7 +43,7 @@ struct FailableStruct { // CHECK-NEXT: [[SELF:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[SELF]] init?(failBeforeInitialization: ()) { return nil @@ -53,16 +53,16 @@ struct FailableStruct { // CHECK: bb0(%0 : $@thin FailableStruct.Type): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableStruct // CHECK: [[CANARY:%.*]] = apply -// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]#1 +// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]] // CHECK-NEXT: store [[CANARY]] to [[X_ADDR]] // CHECK-NEXT: br bb1 // CHECK: bb1: -// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]#1 +// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]] // CHECK-NEXT: strong_release [[CANARY]] // CHECK-NEXT: [[SELF:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[SELF]] init?(failAfterPartialInitialization: ()) { x = Canary() @@ -73,10 +73,10 @@ struct FailableStruct { // CHECK: bb0 // CHECK: [[SELF_BOX:%.*]] = alloc_stack $FailableStruct // CHECK: [[CANARY1:%.*]] = apply -// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]#1 +// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]] // CHECK-NEXT: store [[CANARY1]] to [[X_ADDR]] // CHECK: [[CANARY2:%.*]] = apply -// CHECK-NEXT: [[Y_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]#1 +// CHECK-NEXT: [[Y_ADDR:%.*]] = struct_element_addr [[SELF_BOX]] // CHECK-NEXT: store [[CANARY2]] to [[Y_ADDR]] // CHECK-NEXT: br bb1 // CHECK: bb1: @@ -85,7 +85,7 @@ struct FailableStruct { // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] init?(failAfterFullInitialization: ()) { x = Canary() @@ -97,14 +97,14 @@ struct FailableStruct { // CHECK: bb0 // CHECK: [[SELF_BOX:%.*]] = alloc_stack $FailableStruct // CHECK: [[CANARY]] = apply -// CHECK-NEXT: store [[CANARY]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[CANARY]] to [[SELF_BOX]] // CHECK-NEXT: br bb1 // CHECK: bb1: // CHECK-NEXT: release_value [[CANARY]] // CHECK-NEXT: [[SELF_VALUE:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[SELF_VALUE]] init?(failAfterWholeObjectInitializationByAssignment: ()) { self = FailableStruct(noFail: ()) @@ -116,14 +116,14 @@ struct FailableStruct { // CHECK: [[SELF_BOX:%.*]] = alloc_stack $FailableStruct // CHECK: [[INIT_FN:%.*]] = function_ref @_TFV35definite_init_failable_initializers14FailableStructCfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%0) -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK-NEXT: br bb1 // CHECK: bb1: // CHECK-NEXT: release_value [[NEW_SELF]] // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] init?(failAfterWholeObjectInitializationByDelegation: ()) { self.init(noFail: ()) @@ -139,14 +139,14 @@ struct FailableStruct { // CHECK-NEXT: cond_br [[COND]], bb1, bb2 // CHECK: bb1: // CHECK-NEXT: [[SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]] -// CHECK-NEXT: store [[SELF_VALUE]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[SELF_VALUE]] to [[SELF_BOX]] // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[SELF_VALUE]] // CHECK-NEXT: br bb3([[NEW_SELF]] : $Optional) // CHECK: bb2: // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb3([[NEW_SELF]] : $Optional) // CHECK: bb3([[NEW_SELF:%.*]] : $Optional) -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // Optional to optional init?(failDuringDelegation: ()) { @@ -200,7 +200,7 @@ struct FailableAddrOnlyStruct { // CHECK-NEXT: inject_enum_addr %0 // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK: dealloc_stack [[SELF_BOX]]#0 +// CHECK: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return init?(failBeforeInitialization: ()) { return nil @@ -212,18 +212,18 @@ struct FailableAddrOnlyStruct { // CHECK: [[T_INIT_FN:%.*]] = witness_method $T, #Pachyderm.init!allocator.1 // CHECK-NEXT: [[T_TYPE:%.*]] = metatype $@thick T.Type // CHECK-NEXT: [[X_BOX:%.*]] = alloc_stack $T -// CHECK-NEXT: apply [[T_INIT_FN]]([[X_BOX]]#1, [[T_TYPE]]) -// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]#1 -// CHECK-NEXT: copy_addr [take] [[X_BOX]]#1 to [initialization] [[X_ADDR]] +// CHECK-NEXT: apply [[T_INIT_FN]]([[X_BOX]], [[T_TYPE]]) +// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]] +// CHECK-NEXT: copy_addr [take] [[X_BOX]] to [initialization] [[X_ADDR]] // CHECK-NEXT: dealloc_stack [[X_BOX]] // CHECK-NEXT: br bb1 // CHECK: bb1: -// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]#1 +// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]] // CHECK-NEXT: destroy_addr [[X_ADDR]] // CHECK-NEXT: inject_enum_addr %0 // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK: dealloc_stack [[SELF_BOX]]#0 +// CHECK: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return init?(failAfterPartialInitialization: ()) { x = T() @@ -236,24 +236,24 @@ struct FailableAddrOnlyStruct { // CHECK: [[T_INIT_FN:%.*]] = witness_method $T, #Pachyderm.init!allocator.1 // CHECK-NEXT: [[T_TYPE:%.*]] = metatype $@thick T.Type // CHECK-NEXT: [[X_BOX:%.*]] = alloc_stack $T -// CHECK-NEXT: apply [[T_INIT_FN]]([[X_BOX]]#1, [[T_TYPE]]) -// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]#1 -// CHECK-NEXT: copy_addr [take] [[X_BOX]]#1 to [initialization] [[X_ADDR]] -// CHECK-NEXT: dealloc_stack [[X_BOX]]#0 +// CHECK-NEXT: apply [[T_INIT_FN]]([[X_BOX]], [[T_TYPE]]) +// CHECK-NEXT: [[X_ADDR:%.*]] = struct_element_addr [[SELF_BOX]] +// CHECK-NEXT: copy_addr [take] [[X_BOX]] to [initialization] [[X_ADDR]] +// CHECK-NEXT: dealloc_stack [[X_BOX]] // CHECK-NEXT: [[T_INIT_FN:%.*]] = witness_method $T, #Pachyderm.init!allocator.1 // CHECK-NEXT: [[T_TYPE:%.*]] = metatype $@thick T.Type // CHECK-NEXT: [[Y_BOX:%.*]] = alloc_stack $T -// CHECK-NEXT: apply [[T_INIT_FN]]([[Y_BOX]]#1, [[T_TYPE]]) -// CHECK-NEXT: [[Y_ADDR:%.*]] = struct_element_addr [[SELF_BOX]]#1 -// CHECK-NEXT: copy_addr [take] [[Y_BOX]]#1 to [initialization] [[Y_ADDR]] -// CHECK-NEXT: dealloc_stack [[Y_BOX]]#0 +// CHECK-NEXT: apply [[T_INIT_FN]]([[Y_BOX]], [[T_TYPE]]) +// CHECK-NEXT: [[Y_ADDR:%.*]] = struct_element_addr [[SELF_BOX]] +// CHECK-NEXT: copy_addr [take] [[Y_BOX]] to [initialization] [[Y_ADDR]] +// CHECK-NEXT: dealloc_stack [[Y_BOX]] // CHECK-NEXT: br bb1 // CHECK: bb1: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] // CHECK-NEXT: inject_enum_addr %0 // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK: dealloc_stack [[SELF_BOX]]#0 +// CHECK: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return init?(failAfterFullInitialization: ()) { x = T() @@ -323,11 +323,11 @@ struct ThrowStruct { // CHECK: bb1([[RESULT:%.*]] : $Int): // CHECK: [[INIT_FN:%.*]] = function_ref @_TFV35definite_init_failable_initializers11ThrowStructCfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1) -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failBeforeDelegation: Int) throws { try unwrap(failBeforeDelegation) @@ -343,15 +343,15 @@ struct ThrowStruct { // CHECK: [[INIT_FN:%.*]] = function_ref @_TFV35definite_init_failable_initializers11ThrowStructCfzT4failT__S0_ // CHECK-NEXT: try_apply [[INIT_FN]](%1) // CHECK: bb2([[NEW_SELF:%.*]] : $ThrowStruct): -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failBeforeOrDuringDelegation: Int) throws { try unwrap(failBeforeOrDuringDelegation) @@ -367,15 +367,15 @@ struct ThrowStruct { // CHECK: bb1([[RESULT:%.*]] : $Int): // CHECK-NEXT: try_apply [[INIT_FN]]([[RESULT]], %1) // CHECK: bb2([[NEW_SELF:%.*]] : $ThrowStruct): -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failBeforeOrDuringDelegation2: Int) throws { try self.init(failBeforeDelegation: unwrap(failBeforeOrDuringDelegation2)) @@ -387,11 +387,11 @@ struct ThrowStruct { // CHECK: [[INIT_FN:%.*]] = function_ref @_TFV35definite_init_failable_initializers11ThrowStructCfzT4failT__S0_ // CHECK-NEXT: try_apply [[INIT_FN]](%1) // CHECK: bb1([[NEW_SELF:%.*]] : $ThrowStruct): -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): -// CHECK: dealloc_stack [[SELF_BOX]]#0 +// CHECK: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failDuringDelegation: Int) throws { try self.init(fail: ()) @@ -402,15 +402,15 @@ struct ThrowStruct { // CHECK: [[SELF_BOX:%.*]] = alloc_stack $ThrowStruct // CHECK: [[INIT_FN:%.*]] = function_ref @_TFV35definite_init_failable_initializers11ThrowStructCfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1) -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): // CHECK: release_value [[NEW_SELF]] -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failAfterDelegation: Int) throws { self.init(noFail: ()) @@ -422,34 +422,34 @@ struct ThrowStruct { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowStruct // CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] // CHECK: [[INIT_FN:%.*]] = function_ref @_TFV35definite_init_failable_initializers11ThrowStructCfzT4failT__S0_ // CHECK-NEXT: try_apply [[INIT_FN]](%1) // CHECK: bb1([[NEW_SELF:.*]] : $ThrowStruct): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb2([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: cond_br [[COND]], bb6, bb7 // CHECK: bb6: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] // CHECK-NEXT: br bb8 // CHECK: bb7: // CHECK-NEXT: br bb8 // CHECK: bb8: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failDuringOrAfterDelegation: Int) throws { try self.init(fail: ()) @@ -461,36 +461,36 @@ struct ThrowStruct { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowStruct // CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): // CHECK: [[INIT_FN:%.*]] = function_ref @_TFV35definite_init_failable_initializers11ThrowStructCfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1) // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb2([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: cond_br [[COND]], bb6, bb7 // CHECK: bb6: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] // CHECK-NEXT: br bb8 // CHECK: bb7: // CHECK-NEXT: br bb8 // CHECK: bb8: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failBeforeOrAfterDelegation: Int) throws { try unwrap(failBeforeOrAfterDelegation) @@ -511,14 +511,14 @@ struct ThrowStruct { // CHECK-NEXT: cond_br [[COND]], bb3, bb4 // CHECK: bb3: // CHECK-NEXT: [[SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]] -// CHECK-NEXT: store [[SELF_VALUE]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[SELF_VALUE]] to [[SELF_BOX]] // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[SELF_VALUE]] // CHECK-NEXT: br bb5([[NEW_SELF]] : $Optional) // CHECK: bb4: // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb5([[NEW_SELF]] : $Optional) // CHECK: bb5([[NEW_SELF:%.*]] : $Optional): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] : $Optional // CHECK: bb6: // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.None!enumelt @@ -557,11 +557,11 @@ struct ThrowStruct { // CHECK-NEXT: [[SELF_TYPE:%.*]] = metatype $@thin ThrowStruct.Type // CHECK-NEXT: try_apply [[INIT_FN]]([[SELF_TYPE]]) // CHECK: bb1([[NEW_SELF:%.*]] : $ThrowStruct): -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failDuringSelfReplacement: Int) throws { try self = ThrowStruct(fail: ()) @@ -573,15 +573,15 @@ struct ThrowStruct { // CHECK: [[INIT_FN:%.*]] = function_ref @_TFV35definite_init_failable_initializers11ThrowStructCfT6noFailT__S0_ // CHECK-NEXT: [[SELF_TYPE:%.*]] = metatype $@thin ThrowStruct.Type // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]]([[SELF_TYPE]]) -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: release_value [[NEW_SELF]] -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failAfterSelfReplacement: Int) throws { self = ThrowStruct(noFail: ()) @@ -722,7 +722,7 @@ class FailableBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17FailableBaseClasscfT20failBeforeDelegationT__GSqS0__ // CHECK: bb0(%0 : $FailableBaseClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass -// CHECK: store %0 to [[SELF_BOX]]#1 +// CHECK: store %0 to [[SELF_BOX]] // CHECK-NEXT: br bb1 // CHECK: bb1: // CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick FailableBaseClass.Type, %0 : $FailableBaseClass @@ -730,7 +730,7 @@ class FailableBaseClass { // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[RESULT]] convenience init?(failBeforeDelegation: ()) { return nil @@ -739,17 +739,17 @@ class FailableBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17FailableBaseClasscfT19failAfterDelegationT__GSqS0__ // CHECK: bb0(%0 : $FailableBaseClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass -// CHECK: store %0 to [[SELF_BOX]]#1 +// CHECK: store %0 to [[SELF_BOX]] // CHECK: [[INIT_FN:%.*]] = class_method %0 // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%0) -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK-NEXT: br bb1 // CHECK: bb1: // CHECK-NEXT: strong_release [[NEW_SELF]] // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[RESULT]] convenience init?(failAfterDelegation: ()) { self.init(noFail: ()) @@ -759,21 +759,21 @@ class FailableBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17FailableBaseClasscfT20failDuringDelegationT__GSqS0__ // CHECK: bb0(%0 : $FailableBaseClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableBaseClass -// CHECK: store %0 to [[SELF_BOX]]#1 +// CHECK: store %0 to [[SELF_BOX]] // CHECK: [[INIT_FN:%.*]] = class_method %0 // CHECK-NEXT: [[SELF_OPTIONAL:%.*]] = apply [[INIT_FN]](%0) // CHECK: [[COND:%.*]] = select_enum [[SELF_OPTIONAL]] // CHECK-NEXT: cond_br [[COND]], bb1, bb2 // CHECK: bb1: // CHECK-NEXT: [[SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]] -// CHECK-NEXT: store [[SELF_VALUE]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[SELF_VALUE]] to [[SELF_BOX]] // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[SELF_VALUE]] // CHECK-NEXT: br bb3([[NEW_SELF]] : $Optional) // CHECK: bb2: // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb3([[NEW_SELF]] : $Optional) // CHECK: bb3([[NEW_SELF:%.*]] : $Optional): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // Optional to optional convenience init?(failDuringDelegation: ()) { @@ -809,7 +809,7 @@ class FailableDerivedClass : FailableBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers20FailableDerivedClasscfT27derivedFailBeforeDelegationT__GSqS0__ // CHECK: bb0(%0 : $FailableDerivedClass): // CHECK: [[SELF_BOX:%.*]] = alloc_stack $FailableDerivedClass -// CHECK: store %0 to [[SELF_BOX]]#1 +// CHECK: store %0 to [[SELF_BOX]] // CHECK-NEXT: br bb1 // CHECK: bb1: // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick FailableDerivedClass.Type @@ -817,7 +817,7 @@ class FailableDerivedClass : FailableBaseClass { // CHECK-NEXT: [[RESULT:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb2 // CHECK: bb2: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[RESULT]] init?(derivedFailBeforeDelegation: ()) { return nil @@ -826,7 +826,7 @@ class FailableDerivedClass : FailableBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers20FailableDerivedClasscfT27derivedFailDuringDelegationT__GSqS0__ // CHECK: bb0(%0 : $FailableDerivedClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $FailableDerivedClass -// CHECK: store %0 to [[SELF_BOX]]#1 +// CHECK: store %0 to [[SELF_BOX]] // CHECK: [[CANARY:%.*]] = apply // CHECK-NEXT: [[MEMBER_ADDR:%.*]] = ref_element_addr %0 // CHECK-NEXT: store [[CANARY]] to [[MEMBER_ADDR]] @@ -838,14 +838,14 @@ class FailableDerivedClass : FailableBaseClass { // CHECK: bb1: // CHECK-NEXT: [[BASE_SELF_VALUE:%.*]] = unchecked_enum_data [[SELF_OPTIONAL]] // CHECK-NEXT: [[SELF_VALUE:%.*]] = unchecked_ref_cast [[BASE_SELF_VALUE]] -// CHECK-NEXT: store [[SELF_VALUE]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[SELF_VALUE]] to [[SELF_BOX]] // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[SELF_VALUE]] // CHECK-NEXT: br bb3([[NEW_SELF]] : $Optional) // CHECK: bb2: // CHECK-NEXT: [[NEW_SELF:%.*]] = enum $Optional, #Optional.None!enumelt // CHECK-NEXT: br bb3([[NEW_SELF]] : $Optional) // CHECK: bb3([[NEW_SELF:%.*]] : $Optional): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] : $Optional init?(derivedFailDuringDelegation: ()) { self.otherMember = Canary() @@ -890,17 +890,17 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT_S0_ // CHECK: bb0(%0 : $ThrowDerivedClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass -// CHECK: store %0 to [[SELF_BOX]]#1 +// CHECK: store %0 to [[SELF_BOX]] // CHECK-NEXT: [[BASE_SELF:%.*]] = upcast %0 // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers14ThrowBaseClasscfzT_S0_ // CHECK-NEXT: try_apply [[INIT_FN]]([[BASE_SELF]]) // CHECK: bb1([[NEW_SELF:%.*]] : $ThrowBaseClass): // CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]] -// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[DERIVED_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] required init() throws { try super.init() @@ -913,7 +913,7 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT28failBeforeFullInitializationSi_S0_ // CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK: store %1 to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): @@ -921,13 +921,13 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers14ThrowBaseClasscfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]]([[BASE_SELF]]) // CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]] -// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[DERIVED_SELF]] : $ThrowDerivedClass // CHECK: bb2([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick ThrowDerivedClass.Type // CHECK-NEXT: dealloc_partial_ref %1 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failBeforeFullInitialization: Int) throws { try unwrap(failBeforeFullInitialization) @@ -939,30 +939,28 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass // CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 -// CHECK: store %2 to [[SELF_BOX]]#1 : $*ThrowDerivedClass +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] +// CHECK: store %2 to [[SELF_BOX]] : $*ThrowDerivedClass // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int) // CHECK-NEXT: [[BASE_SELF:%.*]] = upcast %2 // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers14ThrowBaseClasscfzT_S0_ -// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, 1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 // CHECK-NEXT: try_apply [[INIT_FN]]([[BASE_SELF]]) // CHECK: bb2([[NEW_SELF:%.*]] : $ThrowBaseClass): // CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]] -// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[DERIVED_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1 // CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) // CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2) @@ -974,8 +972,8 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: dealloc_partial_ref %2 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type // CHECK-NEXT: br bb8 // CHECK: bb8: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failBeforeFullInitialization: Int, failDuringFullInitialization: Int) throws { try unwrap(failBeforeFullInitialization) @@ -985,20 +983,20 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT27failAfterFullInitializationSi_S0_ // CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK: store %1 to [[SELF_BOX]] // CHECK-NEXT: [[BASE_SELF:%.*]] = upcast %1 // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers14ThrowBaseClasscfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]]([[BASE_SELF]]) // CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]] -// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[DERIVED_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: strong_release [[DERIVED_SELF]] -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failAfterFullInitialization: Int) throws { super.init(noFail: ()) @@ -1010,30 +1008,28 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass // CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 -// CHECK: store %2 to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] +// CHECK: store %2 to [[SELF_BOX]] // CHECK-NEXT: [[DERIVED_SELF:%.*]] = upcast %2 // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers14ThrowBaseClasscfzT_S0_ -// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, 1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 // CHECK-NEXT: try_apply [[INIT_FN]]([[DERIVED_SELF]]) // CHECK: bb1([[NEW_SELF:%.*]] : $ThrowBaseClass): // CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]] -// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb2([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[DERIVED_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1 // CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) // CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2) @@ -1041,11 +1037,11 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK: bb6: // CHECK-NEXT: br bb8 // CHECK: bb7: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] // CHECK-NEXT: br bb8 // CHECK: bb8: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failAfterFullInitialization: Int, failDuringFullInitialization: Int) throws { try super.init() @@ -1057,42 +1053,40 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass // CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 -// CHECK: store %2 to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] +// CHECK: store %2 to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): // CHECK-NEXT: [[BASE_SELF:%.*]] = upcast %2 // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers14ThrowBaseClasscfT6noFailT__S0_ -// CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1 -// CHECK-NEXT: store [[BIT:%.*]] to [[BITMAP_BOX]]#1 // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]]([[BASE_SELF]]) // CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]] -// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%1) // CHECK: bb2([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[DERIVED_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: cond_br [[COND:%.*]], bb6, bb7 // CHECK: bb6: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] // CHECK-NEXT: br bb8 // CHECK: bb7: -// CHECK-NEXT: [[BITMAP:%.*]] = load [[SELF_BOX]]#1 +// CHECK-NEXT: [[BITMAP:%.*]] = load [[SELF_BOX]] // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick ThrowDerivedClass.Type // CHECK-NEXT: dealloc_partial_ref [[BITMAP]] : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type // CHECK-NEXT: br bb8 // CHECK: bb8: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR]] : $ErrorType init(failBeforeFullInitialization: Int, failAfterFullInitialization: Int) throws { try unwrap(failBeforeFullInitialization) @@ -1105,35 +1099,33 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass // CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 -// CHECK: store %3 to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] +// CHECK: store %3 to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): // CHECK-NEXT: [[BASE_SELF:%.*]] = upcast %3 // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers14ThrowBaseClasscfzT_S0_ -// CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1 -// CHECK-NEXT: store [[ONE]] to [[BITMAP_BOX]]#1 // CHECK-NEXT: try_apply [[INIT_FN]]([[BASE_SELF]]) // CHECK: bb2([[NEW_SELF:%.*]] : $ThrowBaseClass): // CHECK-NEXT: [[DERIVED_SELF:%.*]] = unchecked_ref_cast [[NEW_SELF]] -// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[DERIVED_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%2) // CHECK: bb3([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[DERIVED_SELF]] // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb7([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK-NEXT: br bb7([[ERROR]] : $ErrorType) // CHECK: bb6([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb7([[ERROR]] : $ErrorType) // CHECK: bb7([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1 // CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) // CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2) @@ -1144,18 +1136,18 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP]] : $Builtin.Int2) // CHECK-NEXT: cond_br [[COND]], bb10, bb11 // CHECK: bb10: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] // CHECK-NEXT: br bb12 // CHECK: bb11: -// CHECK-NEXT: [[SELF:%.*]] = load [[SELF_BOX]]#1 +// CHECK-NEXT: [[SELF:%.*]] = load [[SELF_BOX]] // CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thick ThrowDerivedClass.Type // CHECK-NEXT: dealloc_partial_ref [[SELF]] : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type // CHECK-NEXT: br bb12 // CHECK: bb12: // CHECK-NEXT: br bb13 // CHECK: bb13: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR]] init(failBeforeFullInitialization: Int, failDuringFullInitialization: Int, failAfterFullInitialization: Int) throws { try unwrap(failBeforeFullInitialization) @@ -1170,19 +1162,19 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT20failBeforeDelegationSi_S0_ // CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK: store %1 to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[ARG:%.*]] : $Int): // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1) -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, %1 : $ThrowDerivedClass // CHECK-NEXT: dealloc_partial_ref %1 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] convenience init(failBeforeDelegation: Int) throws { try unwrap(failBeforeDelegation) @@ -1192,15 +1184,15 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT20failDuringDelegationSi_S0_ // CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK: store %1 to [[SELF_BOX]] // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT_S0_ // CHECK-NEXT: try_apply [[INIT_FN]](%1) // CHECK: bb1([[NEW_SELF:%.*]] : $ThrowDerivedClass): -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] : $ErrorType convenience init(failDuringDelegation: Int) throws { try self.init() @@ -1211,28 +1203,28 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass // CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 : $*Builtin.Int2 -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] : $*Builtin.Int2 +// CHECK: store %1 to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[ARG:%.*]] : $Int): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, 1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT_S0_ // CHECK-NEXT: try_apply [[INIT_FN]](%1) // CHECK: bb2([[NEW_SELF:%.*]] : $ThrowDerivedClass): -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb3([[ERROR1:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR1]] : $ErrorType) // CHECK: bb4([[ERROR2:%.*]] : $ErrorType): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK-NEXT: br bb5([[ERROR2]] : $ErrorType) // CHECK: bb5([[ERROR3:%.*]] : $ErrorType): -// CHECK-NEXT: [[BITMAP_VALUE:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[BITMAP_VALUE:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: [[BIT_NUM:%.*]] = integer_literal $Builtin.Int2, 1 // CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP_VALUE]] : $Builtin.Int2, [[BIT_NUM]] : $Builtin.Int2) // CHECK-NEXT: [[CONDITION:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2) @@ -1244,8 +1236,8 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: dealloc_partial_ref %1 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type // CHECK-NEXT: br bb8 // CHECK: bb8: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR3]] convenience init(failBeforeOrDuringDelegation: Int) throws { try unwrap(failBeforeOrDuringDelegation) @@ -1257,28 +1249,28 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass // CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 : $*Builtin.Int2 -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] : $*Builtin.Int2 +// CHECK: store %1 to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[ARG:%.*]] : $Int): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, 1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT20failBeforeDelegationSi_S0_ // CHECK-NEXT: try_apply [[INIT_FN]]([[ARG]], %1) // CHECK: bb2([[NEW_SELF:%.*]] : $ThrowDerivedClass): -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR1:%.*]] : $ErrorType): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK-NEXT: br bb5([[ERROR1]] : $ErrorType) // CHECK: bb5([[ERROR2:%.*]] : $ErrorType): -// CHECK-NEXT: [[BITMAP_VALUE:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[BITMAP_VALUE:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: [[BIT_NUM:%.*]] = integer_literal $Builtin.Int2, 1 // CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP_VALUE]] : $Builtin.Int2, [[BIT_NUM]] : $Builtin.Int2) // CHECK-NEXT: [[CONDITION:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2) @@ -1290,8 +1282,8 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: dealloc_partial_ref %1 : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type // CHECK-NEXT: br bb8 // CHECK: bb8: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR2]] convenience init(failBeforeOrDuringDelegation2: Int) throws { try self.init(failBeforeDelegation: unwrap(failBeforeOrDuringDelegation2)) @@ -1300,18 +1292,18 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-LABEL: sil hidden @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT19failAfterDelegationSi_S0_ // CHECK: bb0(%0 : $Int, %1 : $ThrowDerivedClass): // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK: store %1 to [[SELF_BOX]] // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1) -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb2([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: strong_release [[NEW_SELF]] -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] // CHECK-NEXT: throw [[ERROR]] convenience init(failAfterDelegation: Int) throws { self.init(noFail: ()) @@ -1323,28 +1315,28 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int2 // CHECK: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass // CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int2, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] +// CHECK: store %1 to [[SELF_BOX]] // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, 1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfzT_S0_ // CHECK-NEXT: try_apply [[INIT_FN]](%1) // CHECK: bb1([[NEW_SELF:%.*]] : $ThrowDerivedClass): -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb2([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb3([[ERROR1:%.*]] : $ErrorType): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int2, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK-NEXT: br bb5([[ERROR1]] : $ErrorType) // CHECK: bb4([[ERROR2:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR2]] : $ErrorType) // CHECK: bb5([[ERROR3:%.*]] : $ErrorType): -// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[BITMAP:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: [[ONE:%.*]] = integer_literal $Builtin.Int2, 1 // CHECK-NEXT: [[BITMAP_MSB:%.*]] = builtin "lshr_Int2"([[BITMAP]] : $Builtin.Int2, [[ONE]] : $Builtin.Int2) // CHECK-NEXT: [[COND:%.*]] = builtin "trunc_Int2_Int1"([[BITMAP_MSB]] : $Builtin.Int2) @@ -1352,11 +1344,11 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK: bb6: // CHECK-NEXT: br bb8 // CHECK: bb7: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] // CHECK-NEXT: br bb8 // CHECK: bb8: -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: throw [[ERROR3]] convenience init(failDuringOrAfterDelegation: Int) throws { try self.init() @@ -1368,34 +1360,34 @@ class ThrowDerivedClass : ThrowBaseClass { // CHECK-NEXT: [[BITMAP_BOX:%.*]] = alloc_stack $Builtin.Int1 // CHECK-NEXT: [[SELF_BOX:%.*]] = alloc_stack $ThrowDerivedClass // CHECK-NEXT: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0 -// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]]#1 -// CHECK: store %1 to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[ZERO]] to [[BITMAP_BOX]] +// CHECK: store %1 to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb1([[RESULT:%.*]] : $Int): // CHECK-NEXT: [[BIT:%.*]] = integer_literal $Builtin.Int1, -1 -// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]]#1 +// CHECK-NEXT: store [[BIT]] to [[BITMAP_BOX]] // CHECK: [[INIT_FN:%.*]] = function_ref @_TFC35definite_init_failable_initializers17ThrowDerivedClasscfT6noFailT__S0_ // CHECK-NEXT: [[NEW_SELF:%.*]] = apply [[INIT_FN]](%1) -// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]]#1 +// CHECK-NEXT: store [[NEW_SELF]] to [[SELF_BOX]] // CHECK: [[UNWRAP_FN:%.*]] = function_ref @_TF35definite_init_failable_initializers6unwrapFzSiSi // CHECK-NEXT: try_apply [[UNWRAP_FN]](%0) // CHECK: bb2([[RESULT:%.*]] : $Int): -// CHECK-NEXT: dealloc_stack [[SELF_BOX]]#0 -// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]]#0 +// CHECK-NEXT: dealloc_stack [[SELF_BOX]] +// CHECK-NEXT: dealloc_stack [[BITMAP_BOX]] // CHECK-NEXT: return [[NEW_SELF]] // CHECK: bb3([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb4([[ERROR:%.*]] : $ErrorType): // CHECK-NEXT: br bb5([[ERROR]] : $ErrorType) // CHECK: bb5([[ERROR:%.*]] : $ErrorType): -// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]]#1 +// CHECK-NEXT: [[COND:%.*]] = load [[BITMAP_BOX]] // CHECK-NEXT: cond_br [[COND]], bb6, bb7 // CHECK: bb6: -// CHECK-NEXT: destroy_addr [[SELF_BOX]]#1 +// CHECK-NEXT: destroy_addr [[SELF_BOX]] // CHECK-NEXT: br bb8 // CHECK: bb7: -// CHECK-NEXT: [[OLD_SELF:%.*]] = load [[SELF_BOX]]#1 +// CHECK-NEXT: [[OLD_SELF:%.*]] = load [[SELF_BOX]] // CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick ThrowDerivedClass.Type, [[OLD_SELF]] : $ThrowDerivedClass // CHECK-NEXT: dealloc_partial_ref [[OLD_SELF]] : $ThrowDerivedClass, [[METATYPE]] : $@thick ThrowDerivedClass.Type // CHECK-NEXT: br bb8 diff --git a/test/SILPasses/definite_init_failable_initializers_diagnostics.swift b/test/SILOptimizer/definite_init_failable_initializers_diagnostics.swift similarity index 100% rename from test/SILPasses/definite_init_failable_initializers_diagnostics.swift rename to test/SILOptimizer/definite_init_failable_initializers_diagnostics.swift diff --git a/test/SILPasses/definite_init_hang.swift b/test/SILOptimizer/definite_init_hang.swift similarity index 96% rename from test/SILPasses/definite_init_hang.swift rename to test/SILOptimizer/definite_init_hang.swift index 4ac0604f79e69..cc932ae262ea3 100644 --- a/test/SILPasses/definite_init_hang.swift +++ b/test/SILOptimizer/definite_init_hang.swift @@ -7,7 +7,7 @@ func f1() { } func f2() { } // The old implementation of the LifetimeChecker in DefiniteInitialization had -// an exponential compuation complexity in some cases. +// an exponential computation complexity in some cases. // This test should finish in almost no time. With the old implementation it // took about 8 minutes. diff --git a/test/SILPasses/definite_init_objc_factory_init.swift b/test/SILOptimizer/definite_init_objc_factory_init.swift similarity index 91% rename from test/SILPasses/definite_init_objc_factory_init.swift rename to test/SILOptimizer/definite_init_objc_factory_init.swift index 41d655aba4bf5..e575ec274197e 100644 --- a/test/SILPasses/definite_init_objc_factory_init.swift +++ b/test/SILOptimizer/definite_init_objc_factory_init.swift @@ -10,7 +10,6 @@ func testInstanceTypeFactoryMethod(queen: Bee) { // CHECK-NEXT: [[HIVE_META_OBJC:%[0-9]+]] = thick_to_objc_metatype [[HIVE_META]] : $@thick Hive.Type to $@objc_metatype Hive.Type // CHECK-NEXT: [[FACTORY:%[0-9]+]] = class_method [volatile] [[HIVE_META_OBJC]] : $@objc_metatype Hive.Type, #Hive.init!allocator.1.foreign : Hive.Type -> (queen: Bee!) -> Hive! , $@convention(objc_method) (ImplicitlyUnwrappedOptional, @objc_metatype Hive.Type) -> @autoreleased ImplicitlyUnwrappedOptional // CHECK-NEXT: [[HIVE:%[0-9]+]] = apply [[FACTORY]]([[QUEEN]], [[HIVE_META_OBJC]]) : $@convention(objc_method) (ImplicitlyUnwrappedOptional, @objc_metatype Hive.Type) -> @autoreleased ImplicitlyUnwrappedOptional - // CHECK-NEXT: strong_retain_autoreleased [[HIVE]] : $ImplicitlyUnwrappedOptional // CHECK-NEXT: release_value [[QUEEN]] // CHECK-NEXT: return [[HIVE]] : $ImplicitlyUnwrappedOptional var hive1 = Hive(queen: queen) @@ -24,14 +23,14 @@ extension Hive { // CHECK-LABEL: sil hidden @_TFE31definite_init_objc_factory_initCSo4HivecfT10otherQueenCSo3Bee_S0_ : $@convention(method) (@owned Bee, @owned Hive) -> @owned Hive convenience init(otherQueen other: Bee) { // CHECK: [[SELF_ADDR:%[0-9]+]] = alloc_stack $Hive - // CHECK: store [[OLD_SELF:%[0-9]+]] to [[SELF_ADDR]]#1 + // CHECK: store [[OLD_SELF:%[0-9]+]] to [[SELF_ADDR]] // CHECK: [[META:%[0-9]+]] = value_metatype $@thick Hive.Type, [[OLD_SELF]] : $Hive // CHECK: [[FACTORY:%[0-9]+]] = class_method [volatile] [[META]] : $@thick Hive.Type, #Hive.init!allocator.1.foreign : Hive.Type -> (queen: Bee!) -> Hive! , $@convention(objc_method) (ImplicitlyUnwrappedOptional, @objc_metatype Hive.Type) -> @autoreleased ImplicitlyUnwrappedOptional // CHECK: [[OBJC_META:%[0-9]+]] = thick_to_objc_metatype [[META]] : $@thick Hive.Type to $@objc_metatype Hive.Type // CHECK: apply [[FACTORY]]([[QUEEN:%[0-9]+]], [[OBJC_META]]) : $@convention(objc_method) (ImplicitlyUnwrappedOptional, @objc_metatype Hive.Type) -> @autoreleased ImplicitlyUnwrappedOptional - // CHECK: store [[NEW_SELF:%[0-9]+]] to [[SELF_ADDR]]#1 + // CHECK: store [[NEW_SELF:%[0-9]+]] to [[SELF_ADDR]] // CHECK: strong_release [[OLD_SELF]] : $Hive - // CHECK: dealloc_stack [[SELF_ADDR]]#0 + // CHECK: dealloc_stack [[SELF_ADDR]] // CHECK: return [[NEW_SELF]] self.init(queen: other) } diff --git a/test/SILPasses/destructor_analysis.sil b/test/SILOptimizer/destructor_analysis.sil similarity index 100% rename from test/SILPasses/destructor_analysis.sil rename to test/SILOptimizer/destructor_analysis.sil diff --git a/test/SILPasses/devirt_access.sil b/test/SILOptimizer/devirt_access.sil similarity index 93% rename from test/SILPasses/devirt_access.sil rename to test/SILOptimizer/devirt_access.sil index a68e373208a53..8beb4a256fedc 100644 --- a/test/SILPasses/devirt_access.sil +++ b/test/SILOptimizer/devirt_access.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inline | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -devirtualizer | FileCheck %s sil_stage canonical @@ -92,7 +92,7 @@ sil @_TFC14devirt_access21BCfMS0_FT_S0_ : $@convention(thin) (@thick B.Type) -> //CHECK: return sil @Case1 : $@convention(thin) (@owned X) -> Int { bb0(%0 : $X): - debug_value %0 : $X // let a // id: %1 + debug_value %0 : $X, let, name "a" // id: %1 strong_retain %0 : $X // id: %2 %3 = class_method %0 : $X, #X.ping!1 : X -> () -> Int , $@convention(method) (@guaranteed X) -> Int // user: %4 %4 = apply %3(%0) : $@convention(method) (@guaranteed X) -> Int // user: %6 @@ -102,11 +102,15 @@ bb0(%0 : $X): //CHECK-LABEL: sil @Case2 //CHECK: function_ref @_TFC14devirt_access21X4pingfS0_FT_Si -//CHECK-NEXT: apply +// Y is an internal class, it has no subclasses and it is a wmo compilation, +// therefore ping method invocation can be devirtualized. +//CHECK-NOT: class_method +//CHECK: apply +//CHECK-NOT: class_method //CHECK: return sil @Case2 : $@convention(thin) (@owned Y) -> Int { bb0(%0 : $Y): - debug_value %0 : $Y // let a // id: %1 + debug_value %0 : $Y, let, name "a" // id: %1 strong_retain %0 : $Y // id: %2 %3 = upcast %0 : $Y to $X // users: %4, %5 %4 = class_method %3 : $X, #X.ping!1 : X -> () -> Int , $@convention(method) (@guaranteed X) -> Int // user: %5 @@ -120,7 +124,7 @@ bb0(%0 : $Y): //CHECK: return sil @Case3 : $@convention(thin) (@owned A) -> Int { bb0(%0 : $A): - debug_value %0 : $A // let a // id: %1 + debug_value %0 : $A, let, name "a" // id: %1 strong_retain %0 : $A // id: %2 %3 = class_method %0 : $A, #A.ping!1 : A -> () -> Int , $@convention(method) (@guaranteed A) -> Int // user: %4 %4 = apply %3(%0) : $@convention(method) (@guaranteed A) -> Int // user: %6 @@ -133,7 +137,7 @@ bb0(%0 : $A): //CHECK: return sil @Case4 : $@convention(thin) (@owned B) -> Int { bb0(%0 : $B): - debug_value %0 : $B // let a // id: %1 + debug_value %0 : $B, let, name "a" // id: %1 strong_retain %0 : $B // id: %2 %3 = class_method %0 : $B, #B.ping!1 : B -> () -> Int , $@convention(method) (@guaranteed B) -> Int // user: %4 %4 = apply %3(%0) : $@convention(method) (@guaranteed B) -> Int // user: %6 diff --git a/test/SILPasses/devirt_access.swift b/test/SILOptimizer/devirt_access.swift similarity index 100% rename from test/SILPasses/devirt_access.swift rename to test/SILOptimizer/devirt_access.swift diff --git a/test/SILPasses/devirt_access_other_module.swift b/test/SILOptimizer/devirt_access_other_module.swift similarity index 100% rename from test/SILPasses/devirt_access_other_module.swift rename to test/SILOptimizer/devirt_access_other_module.swift diff --git a/test/SILPasses/devirt_alloc_ref_dynamic.sil b/test/SILOptimizer/devirt_alloc_ref_dynamic.sil similarity index 97% rename from test/SILPasses/devirt_alloc_ref_dynamic.sil rename to test/SILOptimizer/devirt_alloc_ref_dynamic.sil index b101f5b10dd4b..f9c2025e36a49 100644 --- a/test/SILPasses/devirt_alloc_ref_dynamic.sil +++ b/test/SILOptimizer/devirt_alloc_ref_dynamic.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -inline -dce | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -devirtualizer -dce | FileCheck %s sil_stage canonical diff --git a/test/SILPasses/devirt_archetype_method.swift b/test/SILOptimizer/devirt_archetype_method.swift similarity index 97% rename from test/SILPasses/devirt_archetype_method.swift rename to test/SILOptimizer/devirt_archetype_method.swift index b0ccd8dba8ca9..c290cefe41033 100644 --- a/test/SILPasses/devirt_archetype_method.swift +++ b/test/SILOptimizer/devirt_archetype_method.swift @@ -20,7 +20,7 @@ func generic_call(x: T) { //CHECK-NOT: apply //CHECK: return func interesting_code_here() { - var x = ABC() + _ = ABC() // Make sure that we can specialize the function generic_call that has a // generic call to x.ping(). generic_call(ABC()) @@ -47,7 +47,7 @@ func aMethod(x : T) { //CHECK-NOT: apply //CHECK: return func main() { - var x = Foo() + let x = Foo() aMethod(x) } diff --git a/test/SILPasses/devirt_base_class.swift b/test/SILOptimizer/devirt_base_class.swift similarity index 82% rename from test/SILPasses/devirt_base_class.swift rename to test/SILOptimizer/devirt_base_class.swift index 414c829e469a0..664c38332383e 100644 --- a/test/SILPasses/devirt_base_class.swift +++ b/test/SILOptimizer/devirt_base_class.swift @@ -19,18 +19,11 @@ private class C : A { private func foo(a: A) -> Int { -// Check that invocation of addConstraint() gets completely devirtualized and inlined -// -// CHECK-LABEL: sil private [noinline] @_TFC17devirt_base_classP33_C1ED27807F941A622F32D66AB60A15CD2F24test -// CHECK-NOT: class_method -// CHECK-NOT: function_ref -// CHECK: return - // Check that a.f() call can be devirtualized, even // though f is defined by one of the A's superclasses. // -// CHECK-LABEL: sil private [noinline] @_TTSf4g___TF17devirt_base_classP33_C1ED27807F941A622F32D66AB60A15CD3fooFCS_P33_C1ED27807F941A622F32D66AB60A15CD1ASi +// CHECK-LABEL: sil private [noinline] @{{.*}}foo // CHECK-NOT: class_method // CHECK: checked_cast_br // CHECK: function_ref @@ -39,6 +32,15 @@ private func foo(a: A) -> Int { return a.f() } +// Check that invocation of addConstraint() gets completely devirtualized and inlined +// +// CHECK-LABEL: sil private [noinline] @{{.*}}_TFC17devirt_base_classP33_C1ED27807F941A622F32D66AB60A15CD2F24test +// CHECK-NOT: class_method +// CHECK-NOT: function_ref +// CHECK: return + + + print("foo(C()) = \(foo(C()))") private class F1 { diff --git a/test/SILPasses/devirt_bound_generic.swift b/test/SILOptimizer/devirt_bound_generic.swift similarity index 90% rename from test/SILPasses/devirt_bound_generic.swift rename to test/SILOptimizer/devirt_bound_generic.swift index a699caa9e2612..79fdae04ad1db 100644 --- a/test/SILPasses/devirt_bound_generic.swift +++ b/test/SILOptimizer/devirt_bound_generic.swift @@ -2,7 +2,7 @@ // We used to crash on this when trying to devirtualize a.doSomething(), // because a is A and B is a subclass of A, but not a -// subclass A. And we were not filtring the results of the +// subclass A. And we were not filtering the results of the // ClassHierarchyAnalysis to handle such cases properly and // as a result, we were trying to cast A into B, which is // impossible. diff --git a/test/SILPasses/devirt_concrete_subclass_of_generic_class.swift b/test/SILOptimizer/devirt_concrete_subclass_of_generic_class.swift similarity index 100% rename from test/SILPasses/devirt_concrete_subclass_of_generic_class.swift rename to test/SILOptimizer/devirt_concrete_subclass_of_generic_class.swift diff --git a/test/SILPasses/devirt_contravariant_args.swift b/test/SILOptimizer/devirt_contravariant_args.swift similarity index 93% rename from test/SILPasses/devirt_contravariant_args.swift rename to test/SILOptimizer/devirt_contravariant_args.swift index 5449e36f21e57..51dedd43cd61c 100644 --- a/test/SILPasses/devirt_contravariant_args.swift +++ b/test/SILOptimizer/devirt_contravariant_args.swift @@ -73,13 +73,13 @@ func doSomething(b : B, _ t : T) { } func driver() -> () { - var b = B() - var b2 = B2() - var b3 = B3() + let b = B() + let b2 = B2() + let b3 = B3() - var c0 = C0() - var c1 = C1() - var c2 = C2() + let c0 = C0() + let c1 = C1() + let c2 = C2() doSomething(b, c2) doSomething(b2, c1) diff --git a/test/SILPasses/devirt_covariant_return.swift b/test/SILOptimizer/devirt_covariant_return.swift similarity index 98% rename from test/SILPasses/devirt_covariant_return.swift rename to test/SILOptimizer/devirt_covariant_return.swift index ea281492403fb..0a8001bc0ef0d 100644 --- a/test/SILPasses/devirt_covariant_return.swift +++ b/test/SILOptimizer/devirt_covariant_return.swift @@ -13,7 +13,7 @@ // CHECK: alloc_ref [stack] // CHECK: function_ref @unknown1a : $@convention(thin) () -> () // CHECK: apply -// CHECK: function_ref @defrenestrate : $@convention(thin) () -> () +// CHECK: function_ref @defenestrate : $@convention(thin) () -> () // CHECK: apply // CHECK: function_ref @unknown2a : $@convention(thin) () -> () // CHECK: apply @@ -39,8 +39,8 @@ func unknown2b() -> () func unknown3a() -> () @_silgen_name("unknown3b") func unknown3b() -> () -@_silgen_name("defrenestrate") -func defrenestrate() -> () +@_silgen_name("defenestrate") +func defenestrate() -> () class B { // We do not specialize typealias's correctly now. @@ -56,7 +56,7 @@ class B { //} func doSomethingElse() { - defrenestrate() + defenestrate() } } diff --git a/test/SILPasses/devirt_ctors.sil b/test/SILOptimizer/devirt_ctors.sil similarity index 100% rename from test/SILPasses/devirt_ctors.sil rename to test/SILOptimizer/devirt_ctors.sil diff --git a/test/SILPasses/devirt_default_case.swift b/test/SILOptimizer/devirt_default_case.swift similarity index 98% rename from test/SILPasses/devirt_default_case.swift rename to test/SILOptimizer/devirt_default_case.swift index 732979559dd54..fc0d989272f5f 100644 --- a/test/SILPasses/devirt_default_case.swift +++ b/test/SILOptimizer/devirt_default_case.swift @@ -2,7 +2,7 @@ // RUN: %target-swift-frontend -O -module-name devirt_default_case -emit-sil -enable-testing %s | FileCheck -check-prefix=CHECK -check-prefix=CHECK-TESTABLE %s @_silgen_name("action") -func action(n:Int)->() +func action(n:Int) -> () // public class public class Base1 { @@ -106,7 +106,7 @@ class E3 :C3 {} // B has its own implementation. @inline(never) func foo(a: A3) -> Int { -// Check that call to A3.f() can be devirualized. +// Check that call to A3.f() can be devirtualized. // // CHECK-LABEL: sil{{( hidden)?}} [noinline] @_TF19devirt_default_case3fooFCS_2A3Si // CHECK: function_ref @{{.*}}TFC19devirt_default_case2B31f @@ -206,7 +206,7 @@ public class M { public class M1: M { @inline(never) - override func foo()->Int32 { + override func foo() -> Int32 { return 1 } } diff --git a/test/SILPasses/devirt_dependent_types.swift b/test/SILOptimizer/devirt_dependent_types.swift similarity index 97% rename from test/SILPasses/devirt_dependent_types.swift rename to test/SILOptimizer/devirt_dependent_types.swift index 455f4a02c68cd..86f16c218867d 100644 --- a/test/SILPasses/devirt_dependent_types.swift +++ b/test/SILOptimizer/devirt_dependent_types.swift @@ -33,7 +33,7 @@ struct BarImpl : BarType { // CHECK-NOT: bb1 // CHECK: return public func zzz() { - var xs = BarImpl() + let xs = BarImpl() var source: FooImplBase = FooImplDerived(xs) source = source.virtualMethod() source = source.virtualMethod() diff --git a/test/SILPasses/devirt_extension.swift b/test/SILOptimizer/devirt_extension.swift similarity index 91% rename from test/SILPasses/devirt_extension.swift rename to test/SILOptimizer/devirt_extension.swift index 2f21d21f3a7ce..028ff66720e14 100644 --- a/test/SILPasses/devirt_extension.swift +++ b/test/SILOptimizer/devirt_extension.swift @@ -16,7 +16,7 @@ struct D : DrawingElementType { var boundingBox: Int32 = 42 } -// Check that that boundingBox is devirtualized and inlined. +// Check that boundingBox is devirtualized and inlined. // CHECK: sil @{{.*}}test1111 // bb0: // CHECK-NOT: class_method diff --git a/test/SILPasses/devirt_inherited_conformance.swift b/test/SILOptimizer/devirt_inherited_conformance.swift similarity index 98% rename from test/SILPasses/devirt_inherited_conformance.swift rename to test/SILOptimizer/devirt_inherited_conformance.swift index 89ae013dee5f5..662f42d66e311 100644 --- a/test/SILPasses/devirt_inherited_conformance.swift +++ b/test/SILOptimizer/devirt_inherited_conformance.swift @@ -109,12 +109,12 @@ public protocol Comparable { // Define a custom operator to be used instead of == infix operator --- { associativity left precedence 140 } -// Simple is a protocol tat simply defines an operator and +// Simple is a protocol that simply defines an operator and // a few methods with different number of arguments. public protocol Simple { func foo(_: Self) -> Bool func boo(_: Self, _: Self) -> Bool - func ---(_: Self, _: Self)->Bool + func ---(_: Self, _: Self) -> Bool } public class C: Equatable, Comparable, Simple { diff --git a/test/SILPasses/devirt_jump_thread.sil b/test/SILOptimizer/devirt_jump_thread.sil similarity index 99% rename from test/SILPasses/devirt_jump_thread.sil rename to test/SILOptimizer/devirt_jump_thread.sil index 6d2cbb0c05490..30ecc983e4d4e 100644 --- a/test/SILPasses/devirt_jump_thread.sil +++ b/test/SILOptimizer/devirt_jump_thread.sil @@ -247,7 +247,7 @@ bb2(%4 : $Int32): // Preds: bb5 bb6 %9 = tuple_extract %8 : $(Builtin.Int32, Builtin.Int1), 0 // user: %12 %10 = tuple_extract %8 : $(Builtin.Int32, Builtin.Int1), 1 // user: %11 cond_fail %10 : $Builtin.Int1 // id: %11 - dealloc_stack %60#0 : $*@local_storage Int32 + dealloc_stack %60 : $*Int32 %12 = struct $Int32 (%9 : $Builtin.Int32) // user: %13 return %12 : $Int32 // id: %13 @@ -355,7 +355,7 @@ class C { } // Check that checked_cast_br jump-threading works properly when both -// condititions are arguments of the function's entry block. +// conditions are arguments of the function's entry block. // CHECK: sil @test_checked_cast_br_jump_threading_with_entry_bb_arguments // CHECK: checked_cast_br %0 // CHECK: checked_cast_br %1 diff --git a/test/SILPasses/devirt_jump_thread_crasher.sil b/test/SILOptimizer/devirt_jump_thread_crasher.sil similarity index 81% rename from test/SILPasses/devirt_jump_thread_crasher.sil rename to test/SILOptimizer/devirt_jump_thread_crasher.sil index d9cd4f90eaa29..943bef986684e 100644 --- a/test/SILPasses/devirt_jump_thread_crasher.sil +++ b/test/SILOptimizer/devirt_jump_thread_crasher.sil @@ -39,26 +39,26 @@ bb1(%5 : $Derived1): // Preds: bb0 %6 = function_ref @method1 : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Derived1) -> () // user: %9 strong_retain %1 : $@callee_owned (@out R, S) -> () // id: %7 strong_retain %2 : $Base // id: %8 - %9 = apply %6(%3#1, %1, %5) : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Derived1) -> () + %9 = apply %6(%3, %1, %5) : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Derived1) -> () br bb3 // id: %10 bb2: // Preds: bb0 checked_cast_br [exact] %2 : $Base to $Derived2, bb6, bb7 // id: %11 bb3: // Preds: bb1 bb6 bb8 bb10 - switch_enum_addr %3#1 : $*MyOptional, case #MyOptional.Some!enumelt.1: bb4, case #MyOptional.None!enumelt: bb5 // id: %12 + switch_enum_addr %3 : $*MyOptional, case #MyOptional.Some!enumelt.1: bb4, case #MyOptional.None!enumelt: bb5 // id: %12 bb4: // Preds: bb3 - %13 = unchecked_take_enum_data_addr %3#1 : $*MyOptional, #MyOptional.Some!enumelt.1 // user: %14 + %13 = unchecked_take_enum_data_addr %3 : $*MyOptional, #MyOptional.Some!enumelt.1 // user: %14 copy_addr [take] %13 to [initialization] %0 : $*R // id: %14 - dealloc_stack %3#0 : $*@local_storage MyOptional // id: %15 + dealloc_stack %3 : $*MyOptional // id: %15 strong_release %2 : $Base // id: %16 strong_release %1 : $@callee_owned (@out R, S) -> () // id: %17 %18 = tuple () // user: %19 return %18 : $() // id: %19 bb5: // Preds: bb3 - dealloc_stack %3#0 : $*@local_storage MyOptional // id: %20 + dealloc_stack %3 : $*MyOptional // id: %20 unreachable // id: %21 bb6(%22 : $Derived2): // Preds: bb2 @@ -73,7 +73,7 @@ bb8(%29 : $Base): // Preds: bb7 %30 = function_ref @method2 : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Base) -> () // user: %33 strong_retain %1 : $@callee_owned (@out R, S) -> () // id: %31 strong_retain %2 : $Base // id: %32 - %33 = apply %30(%3#1, %1, %29) : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Base) -> () + %33 = apply %30(%3, %1, %29) : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Base) -> () br bb3 // id: %34 bb9: // Preds: bb7 @@ -86,7 +86,7 @@ bb10(%37 : $()): // Preds: bb11 bb13 bb11(%39 : $Derived1): // Preds: bb9 strong_retain %39 : $Derived1 // id: %40 %41 = function_ref @method1 : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Derived1) -> () // user: %42 - %42 = apply %41(%3#1, %1, %39) : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Derived1) -> () // user: %43 + %42 = apply %41(%3, %1, %39) : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Derived1) -> () // user: %43 br bb10(%42 : $()) // id: %43 bb12: // Preds: bb9 @@ -98,7 +98,7 @@ bb13(%45 : $()): // Preds: bb14 bb15 bb14(%47 : $Base): // Preds: bb12 strong_retain %47 : $Base // id: %48 %49 = function_ref @method2 : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Base) -> () // user: %50 - %50 = apply %49(%3#1, %1, %47) : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Base) -> () // user: %51 + %50 = apply %49(%3, %1, %47) : $@convention(method) <τ_0_0> (@out MyOptional<τ_0_0>, @owned @callee_owned (@out τ_0_0, S) -> (), @guaranteed Base) -> () // user: %51 br bb13(%50 : $()) // id: %51 bb15: // Preds: bb12 diff --git a/test/SILPasses/devirt_materializeForSet.swift b/test/SILOptimizer/devirt_materializeForSet.swift similarity index 100% rename from test/SILPasses/devirt_materializeForSet.swift rename to test/SILOptimizer/devirt_materializeForSet.swift diff --git a/test/SILPasses/devirt_method_with_generic_params.swift b/test/SILOptimizer/devirt_method_with_generic_params.swift similarity index 95% rename from test/SILPasses/devirt_method_with_generic_params.swift rename to test/SILOptimizer/devirt_method_with_generic_params.swift index 1381405a5da8c..923489b36ae36 100644 --- a/test/SILPasses/devirt_method_with_generic_params.swift +++ b/test/SILOptimizer/devirt_method_with_generic_params.swift @@ -15,6 +15,6 @@ class S { // CHECK-NOT: apply // CHECK: return public func testDevirtMethodWithItsOwnGenericParam() -> Int { - var s: S = S() + let s: S = S() return s.f(0, 0.0) } diff --git a/test/SILPasses/devirt_override.sil b/test/SILOptimizer/devirt_override.sil similarity index 100% rename from test/SILPasses/devirt_override.sil rename to test/SILOptimizer/devirt_override.sil diff --git a/test/SILPasses/devirt_protocol_method_invocations.swift b/test/SILOptimizer/devirt_protocol_method_invocations.swift similarity index 86% rename from test/SILPasses/devirt_protocol_method_invocations.swift rename to test/SILOptimizer/devirt_protocol_method_invocations.swift index 7bc2ee945e186..5b9dc1b9e9214 100644 --- a/test/SILPasses/devirt_protocol_method_invocations.swift +++ b/test/SILOptimizer/devirt_protocol_method_invocations.swift @@ -1,7 +1,7 @@ // RUN: %target-swift-frontend -O -emit-sil %s | FileCheck %s public protocol Foo { - func foo(x:Int)->Int + func foo(x:Int) -> Int } public extension Foo { @@ -14,30 +14,33 @@ public extension Foo { } } +var gg = 1111 + public class C : Foo { @inline(never) public func foo(x:Int) -> Int { - return 1111 + x + gg += 1 + return gg + x } } @_transparent -func callfoo(f: Foo)->Int { +func callfoo(f: Foo) -> Int { return f.foo(2) + f.foo(2) } @_transparent -func callboo(f: Foo)->Int32 { +func callboo(f: Foo) -> Int32 { return f.boo(2) + f.boo(2) } @_transparent -func callGetSelf(f: Foo)->Foo { +func callGetSelf(f: Foo) -> Foo { return f.getSelf() } -// Check that calls to f.foo() get devirtalized and are not invoked -// via the expensive witness_method instruciton. +// Check that calls to f.foo() get devirtualized and are not invoked +// via the expensive witness_method instruction. // To achieve that the information about a concrete type C should // be propagated from init_existential_addr into witness_method and // apply instructions. @@ -61,12 +64,12 @@ func callGetSelf(f: Foo)->Foo { // CHECK: apply // CHECK: br bb1( @inline(never) -public func test_devirt_protocol_method_invocation(c: C)->Int { +public func test_devirt_protocol_method_invocation(c: C) -> Int { return callfoo(c) } // Check that calls of a method boo() from the protocol extension -// get devirtalized and are not invoked via the expensive witness_method instruciton +// get devirtualized and are not invoked via the expensive witness_method instruction // or by passing an existential as a parameter. // To achieve that the information about a concrete type C should // be propagated from init_existential_addr into apply instructions. @@ -81,7 +84,7 @@ public func test_devirt_protocol_method_invocation(c: C)->Int { // CHECK: integer_literal // CHECK: return @inline(never) -public func test_devirt_protocol_extension_method_invocation(c: C)->Int32 { +public func test_devirt_protocol_extension_method_invocation(c: C) -> Int32 { return callboo(c) } diff --git a/test/SILPasses/devirt_release.sil b/test/SILOptimizer/devirt_release.sil similarity index 93% rename from test/SILPasses/devirt_release.sil rename to test/SILOptimizer/devirt_release.sil index 2908c647e7554..d0cf8d1e54f06 100644 --- a/test/SILPasses/devirt_release.sil +++ b/test/SILOptimizer/devirt_release.sil @@ -73,6 +73,25 @@ bb0(%0 : $B): return %r : $() } +// CHECK-LABEL: sil @dont_crash_with_missing_release +// CHECK: [[A:%[0-9]+]] = alloc_ref +// CHECK-NOT: strong_release +// CHECK: [[D:%[0-9]+]] = function_ref @_TFC4test1Bd +// CHECK: apply [[D]]([[A]]) +// CHECK-NEXT: dealloc_ref [stack] [[A]] +// CHECK: return +sil @dont_crash_with_missing_release : $@convention(thin) () -> () { +bb0: + %1 = alloc_ref [stack] $B + strong_release %1 : $B + dealloc_ref [stack] %1 : $B + %2 = alloc_ref [stack] $B + dealloc_ref [stack] %2 : $B + %r = tuple () + return %r : $() +} + + class MyArrayStorage { } @@ -223,7 +242,7 @@ sil @unknown_func : $@convention(thin) () -> () sil hidden @_TFC4test1BD : $@convention(method) (@owned B) -> () { // %0 // users: %1, %3 bb0(%0 : $B): - debug_value %0 : $B // let self // id: %1 + debug_value %0 : $B, let, name "self" // id: %1 // function_ref test.B.deinit %2 = function_ref @_TFC4test1Bd : $@convention(method) (@guaranteed B) -> @owned Builtin.NativeObject // user: %3 %3 = apply %2(%0) : $@convention(method) (@guaranteed B) -> @owned Builtin.NativeObject // user: %4 @@ -237,7 +256,7 @@ bb0(%0 : $B): sil hidden @_TFC4test1Bd : $@convention(method) (@guaranteed B) -> @owned Builtin.NativeObject { // %0 // users: %1, %2 bb0(%0 : $B): - debug_value %0 : $B // let self // id: %1 + debug_value %0 : $B, let, name "self" // id: %1 %2 = unchecked_ref_cast %0 : $B to $Builtin.NativeObject // user: %3 return %2 : $Builtin.NativeObject // id: %3 } @@ -246,7 +265,7 @@ bb0(%0 : $B): sil hidden @_TFC4test1BcfT_S0_ : $@convention(method) (@owned B) -> @owned B { // %0 // users: %1, %2 bb0(%0 : $B): - debug_value %0 : $B // let self // id: %1 + debug_value %0 : $B, let, name "self" // id: %1 return %0 : $B // id: %2 } @@ -259,7 +278,7 @@ sil_vtable B { sil hidden @_TFC4test14MyArrayStorageD : $@convention(method) (@owned MyArrayStorage) -> () { // %0 // users: %1, %3 bb0(%0 : $MyArrayStorage): - debug_value %0 : $MyArrayStorage // let self // id: %1 + debug_value %0 : $MyArrayStorage, let, name "self" // id: %1 // function_ref test.MyArrayStorage.deinit %2 = function_ref @_TFC4test14MyArrayStoraged : $@convention(method) <τ_0_0> (@guaranteed MyArrayStorage<τ_0_0>) -> @owned Builtin.NativeObject // user: %3 %3 = apply %2(%0) : $@convention(method) <τ_0_0> (@guaranteed MyArrayStorage<τ_0_0>) -> @owned Builtin.NativeObject // user: %4 @@ -273,7 +292,7 @@ bb0(%0 : $MyArrayStorage): sil hidden @_TFC4test14MyArrayStoraged : $@convention(method) (@guaranteed MyArrayStorage) -> @owned Builtin.NativeObject { // %0 // users: %1, %2 bb0(%0 : $MyArrayStorage): - debug_value %0 : $MyArrayStorage // let self // id: %1 + debug_value %0 : $MyArrayStorage, let, name "self" // id: %1 %2 = unchecked_ref_cast %0 : $MyArrayStorage to $Builtin.NativeObject // user: %3 return %2 : $Builtin.NativeObject // id: %3 } @@ -282,7 +301,7 @@ bb0(%0 : $MyArrayStorage): sil hidden @_TFC4test14MyArrayStoragecfT_GS0_x_ : $@convention(method) (@owned MyArrayStorage) -> @owned MyArrayStorage { // %0 // users: %1, %2 bb0(%0 : $MyArrayStorage): - debug_value %0 : $MyArrayStorage // let self // id: %1 + debug_value %0 : $MyArrayStorage, let, name "self" // id: %1 return %0 : $MyArrayStorage // id: %2 } diff --git a/test/SILPasses/devirt_single_module_in_multiple_files.swift b/test/SILOptimizer/devirt_single_module_in_multiple_files.swift similarity index 79% rename from test/SILPasses/devirt_single_module_in_multiple_files.swift rename to test/SILOptimizer/devirt_single_module_in_multiple_files.swift index 44b2652f3b82e..9d51b560df4b7 100644 --- a/test/SILPasses/devirt_single_module_in_multiple_files.swift +++ b/test/SILOptimizer/devirt_single_module_in_multiple_files.swift @@ -7,11 +7,11 @@ public func test() { } // CHECK-LABEL: sil shared @_TFFC38devirt_single_module_in_multiple_files9Evaluatorc -// CHECK: %{{.*}} = class_method %{{.*}} : $Problem1, #Problem1.run!1 : Problem1 -> () -> Int , $@convention(method) (@guaranteed Problem1) -> Int +// CHECK: %{{.*}} = class_method %{{.*}} : $Problem1, #Problem1.run!1 : (Problem1) -> () -> Int , $@convention(method) (@guaranteed Problem1) -> Int // CHECK-NEXT: apply // CHECK: return // CHECK-LABEL: sil shared @_TFFC38devirt_single_module_in_multiple_files9Evaluatorc -// CHECK: %{{.*}} = class_method %{{.*}} : $Problem2, #Problem2.run!1 : Problem2 -> () -> Int , $@convention(method) (@guaranteed Problem2) -> Int +// CHECK: %{{.*}} = class_method %{{.*}} : $Problem2, #Problem2.run!1 : (Problem2) -> () -> Int , $@convention(method) (@guaranteed Problem2) -> Int // CHECK-NEXT: apply // CHECK: return diff --git a/test/SILPasses/devirt_specialized_conformance.swift b/test/SILOptimizer/devirt_specialized_conformance.swift similarity index 100% rename from test/SILPasses/devirt_specialized_conformance.swift rename to test/SILOptimizer/devirt_specialized_conformance.swift diff --git a/test/SILPasses/devirt_specialized_inherited_interplay.swift b/test/SILOptimizer/devirt_specialized_inherited_interplay.swift similarity index 100% rename from test/SILPasses/devirt_specialized_inherited_interplay.swift rename to test/SILOptimizer/devirt_specialized_inherited_interplay.swift diff --git a/test/SILPasses/devirt_static_witness_method.sil b/test/SILOptimizer/devirt_static_witness_method.sil similarity index 93% rename from test/SILPasses/devirt_static_witness_method.sil rename to test/SILOptimizer/devirt_static_witness_method.sil index 81b9bd9514fab..496c554e725ed 100644 --- a/test/SILPasses/devirt_static_witness_method.sil +++ b/test/SILOptimizer/devirt_static_witness_method.sil @@ -5,7 +5,7 @@ import Builtin import Swift import SwiftShims -protocol CanAdd { +protocol CanAdd { func +(lhs: Self, rhs: Self) -> Self } @@ -77,9 +77,9 @@ bb0(%0 : $*S): %1 = alloc_stack $S %5 = metatype $@thick S.Type %6 = witness_method $S, #CanAdd."+"!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : CanAdd> (@out τ_0_0, @in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> () - %7 = apply %6>(%1#1, %0, %0, %5) : $@convention(witness_method) <τ_0_0 where τ_0_0 : CanAdd> (@out τ_0_0, @in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> () - %8 = load %1#1: $*S - dealloc_stack %1#0 : $*@local_storage S + %7 = apply %6>(%1, %0, %0, %5) : $@convention(witness_method) <τ_0_0 where τ_0_0 : CanAdd> (@out τ_0_0, @in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> () + %8 = load %1: $*S + dealloc_stack %1 : $*S return %8 : $S } diff --git a/test/SILPasses/devirt_try_apply.sil b/test/SILOptimizer/devirt_try_apply.sil similarity index 91% rename from test/SILPasses/devirt_try_apply.sil rename to test/SILOptimizer/devirt_try_apply.sil index 6fbbcde0f2eaa..56b321f52406b 100644 --- a/test/SILPasses/devirt_try_apply.sil +++ b/test/SILOptimizer/devirt_try_apply.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -inline -redundant-load-elim -inline | FileCheck %s --check-prefix=CHECK-INLINE +// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -devirtualizer -redundant-load-elim -inline | FileCheck %s --check-prefix=CHECK-DEVIRT // RUN: %target-sil-opt -enable-sil-verify-all %s -early-inline | FileCheck %s --check-prefix=CHECK-EARLY-INLINE // RUN: %target-sil-opt -enable-sil-verify-all %s -specdevirt | FileCheck %s --check-prefix=CHECK-SPECDEVIRT // RUN: %target-sil-opt -enable-sil-verify-all %s -mandatory-inlining | FileCheck %s --check-prefix=CHECK-MANDATORY-INLINING @@ -220,14 +220,14 @@ bb0(%0 : $Derived1): sil hidden @_TFC16devirt_try_apply8Derived1cfMS0_FT_S0_ : $@convention(method) (@owned Derived1) -> @owned Derived1 { bb0(%0 : $Derived1): %1 = alloc_stack $Derived1 - store %0 to %1#1 : $*Derived1 + store %0 to %1 : $*Derived1 %3 = upcast %0 : $Derived1 to $Base %4 = function_ref @_TFC16devirt_try_apply4BasecfMS0_FT_S0_ : $@convention(method) (@owned Base) -> @owned Base %7 = apply %4(%3) : $@convention(method) (@owned Base) -> @owned Base %8 = unchecked_ref_cast %7 : $Base to $Derived1 - store %8 to %1#1 : $*Derived1 - dealloc_stack %1#0 : $*@local_storage Derived1 + store %8 to %1 : $*Derived1 + dealloc_stack %1 : $*Derived1 return %8 : $Derived1 } @@ -310,14 +310,14 @@ bb0(%0 : $Derived2): sil hidden @_TFC16devirt_try_apply8Derived2cfMS0_FT_S0_ : $@convention(method) (@owned Derived2) -> @owned Derived2 { bb0(%0 : $Derived2): %1 = alloc_stack $Derived2 - store %0 to %1#1 : $*Derived2 + store %0 to %1 : $*Derived2 %3 = upcast %0 : $Derived2 to $Base %4 = function_ref @_TFC16devirt_try_apply4BasecfMS0_FT_S0_ : $@convention(method) (@owned Base) -> @owned Base %7 = apply %4(%3) : $@convention(method) (@owned Base) -> @owned Base %8 = unchecked_ref_cast %7 : $Base to $Derived2 - store %8 to %1#1 : $*Derived2 - dealloc_stack %1#0 : $*@local_storage Derived2 + store %8 to %1 : $*Derived2 + dealloc_stack %1 : $*Derived2 return %8 : $Derived2 } @@ -423,14 +423,14 @@ bb0(%0 : $CP2): sil hidden @_TFC16devirt_try_apply3CP2cfMS0_FT_S0_ : $@convention(method) (@owned CP2) -> @owned CP2 { bb0(%0 : $CP2): %1 = alloc_stack $CP2 - store %0 to %1#1 : $*CP2 + store %0 to %1 : $*CP2 %3 = upcast %0 : $CP2 to $CP1 %4 = function_ref @_TFC16devirt_try_apply3CP1cfMS0_FT_S0_ : $@convention(method) (@owned CP1) -> @owned CP1 %7 = apply %4(%3) : $@convention(method) (@owned CP1) -> @owned CP1 %8 = unchecked_ref_cast %7 : $CP1 to $CP2 - store %8 to %1#1 : $*CP2 - dealloc_stack %1#0 : $*@local_storage CP2 + store %8 to %1 : $*CP2 + dealloc_stack %1 : $*CP2 return %8 : $CP2 } @@ -455,22 +455,22 @@ bb0(%0 : $Base): %1 = alloc_stack $Optional debug_value %0 : $Base %3 = alloc_stack $Optional - inject_enum_addr %3#1 : $*Optional, #Optional.None!enumelt + inject_enum_addr %3 : $*Optional, #Optional.None!enumelt %5 = tuple () - %6 = load %3#1 : $*Optional - store %6 to %1#1 : $*Optional - dealloc_stack %3#0 : $*@local_storage Optional + %6 = load %3 : $*Optional + store %6 to %1 : $*Optional + dealloc_stack %3 : $*Optional %9 = class_method %0 : $Base, #Base.foo!1 : Base -> () throws -> Int32? , $@convention(method) (@guaranteed Base) -> (Optional, @error ErrorType) try_apply %9(%0) : $@convention(method) (@guaranteed Base) -> (Optional, @error ErrorType), normal bb1, error bb4 bb1(%11 : $Optional): - store %11 to %1#1 : $*Optional + store %11 to %1 : $*Optional br bb2 bb2: - %14 = load %1#1 : $*Optional + %14 = load %1 : $*Optional strong_release %0 : $Base - dealloc_stack %1#0 : $*@local_storage Optional + dealloc_stack %1 : $*Optional return %14 : $Optional bb3: @@ -495,26 +495,26 @@ bb0(%0 : $Base): %1 = alloc_stack $Optional debug_value %0 : $Base %3 = alloc_stack $Optional - inject_enum_addr %3#1 : $*Optional, #Optional.None!enumelt + inject_enum_addr %3 : $*Optional, #Optional.None!enumelt %5 = tuple () - %6 = load %3#1 : $*Optional - store %6 to %1#1 : $*Optional - dealloc_stack %3#0 : $*@local_storage Optional + %6 = load %3 : $*Optional + store %6 to %1 : $*Optional + dealloc_stack %3 : $*Optional %9 = class_method %0 : $Base, #Base.boo1!1 : Base -> () throws -> Base , $@convention(method) (@guaranteed Base) -> (@owned Base, @error ErrorType) try_apply %9(%0) : $@convention(method) (@guaranteed Base) -> (@owned Base, @error ErrorType), normal bb1, error bb4 bb1(%11 : $Base): %12 = enum $Optional, #Optional.Some!enumelt.1, %11 : $Base - store %12 to %1#1 : $*Optional + store %12 to %1 : $*Optional release_value %6 : $Optional br bb2 bb2: - %16 = load %1#1 : $*Optional + %16 = load %1 : $*Optional retain_value %16 : $Optional - destroy_addr %1#1 : $*Optional + destroy_addr %1 : $*Optional strong_release %0 : $Base - dealloc_stack %1#0 : $*@local_storage Optional + dealloc_stack %1 : $*Optional return %16 : $Optional bb3: @@ -536,25 +536,25 @@ bb0(%0 : $Base): %1 = alloc_stack $Optional debug_value %0 : $Base %3 = alloc_stack $Optional - inject_enum_addr %3#1 : $*Optional, #Optional.None!enumelt + inject_enum_addr %3 : $*Optional, #Optional.None!enumelt %5 = tuple () - %6 = load %3#1 : $*Optional - store %6 to %1#1 : $*Optional - dealloc_stack %3#0 : $*@local_storage Optional + %6 = load %3 : $*Optional + store %6 to %1 : $*Optional + dealloc_stack %3 : $*Optional %9 = class_method %0 : $Base, #Base.boo2!1 : Base -> () throws -> Base? , $@convention(method) (@guaranteed Base) -> (@owned Optional, @error ErrorType) try_apply %9(%0) : $@convention(method) (@guaranteed Base) -> (@owned Optional, @error ErrorType), normal bb1, error bb4 bb1(%11 : $Optional): - store %11 to %1#1 : $*Optional + store %11 to %1 : $*Optional release_value %6 : $Optional br bb2 bb2: - %15 = load %1#1 : $*Optional + %15 = load %1 : $*Optional retain_value %15 : $Optional - destroy_addr %1#1 : $*Optional + destroy_addr %1 : $*Optional strong_release %0 : $Base - dealloc_stack %1#0 : $*@local_storage Optional + dealloc_stack %1 : $*Optional return %15 : $Optional bb3: @@ -615,10 +615,10 @@ bb0: // CHECK-SPECDEVIRT: checked_cast_br [exact] // CHECK-SPECDEVIRT: } -// CHECK-INLINE-LABEL: sil @_TF16devirt_try_apply5test4FT_Vs5Int32 -// CHECK-INLINE-NOT: checked_cast_br [exact] -// CHECK-INLINE-NOT: class_method -// CHECK-INLINE: } +// CHECK-DEVIRT-LABEL: sil @_TF16devirt_try_apply5test4FT_Vs5Int32 +// CHECK-DEVIRT-NOT: checked_cast_br [exact] +// CHECK-DEVIRT-NOT: class_method +// CHECK-DEVIRT: } // CHECK-EARLY-INLINE-LABEL: sil @_TF16devirt_try_apply5test4FT_Vs5Int32 // CHECK-EARLY-INLINE-NOT: checked_cast_br [exact] @@ -634,18 +634,18 @@ bb0: debug_value %3 : $CP2 %5 = integer_literal $Builtin.Int32, 0 %6 = struct $Int32 (%5 : $Builtin.Int32) - store %6 to %0#1 : $*Int32 + store %6 to %0 : $*Int32 %8 = class_method %3 : $CP2, #CP2.foo!1 : CP2 -> () throws -> Int32 , $@convention(method) (@guaranteed CP2) -> (Int32, @error ErrorType) try_apply %8(%3) : $@convention(method) (@guaranteed CP2) -> (Int32, @error ErrorType), normal bb1, error bb4 bb1(%10 : $Int32): - store %10 to %0#1 : $*Int32 + store %10 to %0 : $*Int32 br bb2 bb2: - %13 = load %0#1 : $*Int32 + %13 = load %0 : $*Int32 strong_release %3 : $CP2 - dealloc_stack %0#0 : $*@local_storage Int32 + dealloc_stack %0 : $*Int32 return %13 : $Int32 bb3: @@ -658,15 +658,15 @@ bb4(%19 : $ErrorType): // DISABLE THIS TEST CASE FOR NOW. AS RLE GETS BETTER. WILL RE-ENABLE. // -// DISABLECHECK-INLINE-LABEL: sil @_TF16devirt_try_apply5test5FT_Vs5Int32 -// DISABLECHECK-INLINE-NOT: = witness_method -// DISABLECHECK-INLINE-NOT: = class_method -// DISABLECHECK-INLINE: } +// DISABLECHECK-DEVIRT-LABEL: sil @_TF16devirt_try_apply5test5FT_Vs5Int32 +// DISABLECHECK-DEVIRT-NOT: = witness_method +// DISABLECHECK-DEVIRT-NOT: = class_method +// DISABLECHECK-DEVIRT: } sil @_TF16devirt_try_apply5test5FT_Vs5Int32 : $@convention(thin) () -> Int32 { bb0: %0 = alloc_stack $Int32 %1 = alloc_stack $P - %2 = init_existential_addr %1#1 : $*P, $CP1 + %2 = init_existential_addr %1 : $*P, $CP1 %3 = function_ref @_TFC16devirt_try_apply3CP1CfMS0_FT_S0_ : $@convention(thin) (@thick CP1.Type) -> @owned CP1 %4 = metatype $@thick CP1.Type @@ -674,20 +674,20 @@ bb0: store %5 to %2 : $*CP1 %7 = integer_literal $Builtin.Int32, 0 %8 = struct $Int32 (%7 : $Builtin.Int32) - store %8 to %0#1 : $*Int32 - %10 = open_existential_addr %1#1 : $*P to $*@opened("3F4928FC-364E-11E5-9488-B8E856428C60") P + store %8 to %0 : $*Int32 + %10 = open_existential_addr %1 : $*P to $*@opened("3F4928FC-364E-11E5-9488-B8E856428C60") P %11 = witness_method $@opened("3F4928FC-364E-11E5-9488-B8E856428C60") P, #P.foo!1, %10 : $*@opened("3F4928FC-364E-11E5-9488-B8E856428C60") P : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> (Int32, @error ErrorType) try_apply %11<@opened("3F4928FC-364E-11E5-9488-B8E856428C60") P>(%10) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> (Int32, @error ErrorType), normal bb1, error bb4 bb1(%13 : $Int32): - store %13 to %0#1 : $*Int32 + store %13 to %0 : $*Int32 br bb2 bb2: - %16 = load %0#1 : $*Int32 - destroy_addr %1#1 : $*P - dealloc_stack %1#0 : $*@local_storage P - dealloc_stack %0#0 : $*@local_storage Int32 + %16 = load %0 : $*Int32 + destroy_addr %1 : $*P + dealloc_stack %1 : $*P + dealloc_stack %0 : $*Int32 return %16 : $Int32 bb3: @@ -705,9 +705,9 @@ bb4(%23 : $ErrorType): // CHECK-SPECDEVIRT: checked_cast_br [exact] // CHECK-SPECDEVIRT: } -// CHECK-INLINE-LABEL: sil @_TF16devirt_try_apply5test6FT_GSqVs5Int32_ -// CHECK-INLINE-NOT: class_method -// CHECK-INLINE: } +// CHECK-DEVIRT-LABEL: sil @_TF16devirt_try_apply5test6FT_GSqVs5Int32_ +// CHECK-DEVIRT-NOT: class_method +// CHECK-DEVIRT: } // CHECK-EARLY-INLINE-LABEL: sil @_TF16devirt_try_apply5test6FT_GSqVs5Int32_ // CHECK-EARLY-INLINE-NOT: class_method @@ -724,18 +724,18 @@ bb0: %5 = integer_literal $Builtin.Int32, 0 %6 = struct $Int32 (%5 : $Builtin.Int32) %7 = enum $Optional, #Optional.Some!enumelt.1, %6 : $Int32 - store %7 to %0#1 : $*Optional + store %7 to %0 : $*Optional %9 = class_method %3 : $Derived1, #Derived1.foo!1 : Derived1 -> () throws -> Int32? , $@convention(method) (@guaranteed Derived1) -> (Optional, @error ErrorType) try_apply %9(%3) : $@convention(method) (@guaranteed Derived1) -> (Optional, @error ErrorType), normal bb1, error bb4 bb1(%11 : $Optional): - store %11 to %0#1 : $*Optional + store %11 to %0 : $*Optional br bb2 bb2: - %14 = load %0#1 : $*Optional + %14 = load %0 : $*Optional strong_release %3 : $Derived1 - dealloc_stack %0#0 : $*@local_storage Optional + dealloc_stack %0 : $*Optional return %14 : $Optional bb3: @@ -751,10 +751,10 @@ bb4(%20 : $ErrorType): // CHECK-SPECDEVIRT: checked_cast_br [exact] // CHECK-SPECDEVIRT: } -// CHECK-INLINE-LABEL: sil @_TF16devirt_try_apply5test7FT_Vs5Int32 -// CHECK-INLINE-NOT: checked_cast_br [exact] -// CHECK-INLINE-NOT: class_method -// CHECK-INLINE: } +// CHECK-DEVIRT-LABEL: sil @_TF16devirt_try_apply5test7FT_Vs5Int32 +// CHECK-DEVIRT-NOT: checked_cast_br [exact] +// CHECK-DEVIRT-NOT: class_method +// CHECK-DEVIRT: } // CHECK-EARLY-INLINE-LABEL: sil @_TF16devirt_try_apply5test7FT_Vs5Int32 // CHECK-EARLY-INLINE-NOT: checked_cast_br [exact] @@ -772,18 +772,18 @@ bb0: %1 = alloc_ref $CP2 %5 = integer_literal $Builtin.Int32, 0 %6 = struct $Int32 (%5 : $Builtin.Int32) - store %6 to %0#1 : $*Int32 + store %6 to %0 : $*Int32 %8 = class_method %1 : $CP2, #CP2.foo!1 : CP2 -> () throws -> Int32 , $@convention(method) (@guaranteed CP2) -> (Int32, @error ErrorType) try_apply %8(%1) : $@convention(method) (@guaranteed CP2) -> (Int32, @error ErrorType), normal bb1, error bb4 bb1(%10 : $Int32): - store %10 to %0#1 : $*Int32 + store %10 to %0 : $*Int32 br bb2 bb2: - %13 = load %0#1 : $*Int32 + %13 = load %0 : $*Int32 strong_release %1 : $CP2 - dealloc_stack %0#0 : $*@local_storage Int32 + dealloc_stack %0 : $*Int32 return %13 : $Int32 bb3: diff --git a/test/SILPasses/devirt_type_subst_bug.swift b/test/SILOptimizer/devirt_type_subst_bug.swift similarity index 100% rename from test/SILPasses/devirt_type_subst_bug.swift rename to test/SILOptimizer/devirt_type_subst_bug.swift diff --git a/test/SILOptimizer/devirt_unbound_generic.swift b/test/SILOptimizer/devirt_unbound_generic.swift new file mode 100644 index 0000000000000..f257d5528192a --- /dev/null +++ b/test/SILOptimizer/devirt_unbound_generic.swift @@ -0,0 +1,75 @@ +// RUN: %target-swift-frontend -emit-sil -O -emit-sil %s | FileCheck %s + +// We used to crash on this when trying to devirtualize t.boo(a, 1), +// because it is an "apply" with unbound generic arguments and +// devirtualizer is not able to devirtualize unbound generic +// invocations yet. +// +// rdar://19912272 + +protocol P { + typealias Node +} + +class C { + typealias Node = T.Node + + func foo(n:Node) { + } + + func boo(n:Node, s:S) { + } +} + +func test1(t:C, a: T.Node) { + t.boo(a, s:1) +} + + +class Base { + func foo() { + } + + class func boo() { + } +} + +class Derived : Base { + override func foo() { + } + + override class func boo() { + } +} + +// Check that the instance method Derived.foo can be devirtualized, because Derived.foo is an internal function, +// Derived has no subclasses and it is a WMO compilation. +// CHECK: sil hidden [noinline] @_TF22devirt_unbound_generic5test2urFGCS_7Derivedx_T_ +// CHECK-NOT: class_method +// CHECK: function_ref @_TFC22devirt_unbound_generic7Derived3foofT_T_ +// CHECK-NOT: class_method +// CHECK: return +@inline(never) +func test2(d: Derived) { + d.foo() +} + +public func doTest2(t:T) { + test2(Derived()) +} + +// Check that the class method Derived.boo can be devirtualized, because Derived.boo is an internal function, +// Derived has no subclasses and it is a WMO compilation. +// CHECK: sil hidden [noinline] @_TF22devirt_unbound_generic5test3urFGCS_7Derivedx_T_ +// CHECK-NOT: class_method +// CHECK: function_ref @_TZFC22devirt_unbound_generic7Derived3boofT_T_ +// CHECK-NOT: class_method +// CHECK: return +@inline(never) +func test3(d: Derived) { + d.dynamicType.boo() +} + +public func doTest3(t:T) { + test3(Derived()) +} diff --git a/test/SILPasses/devirt_value_metatypes.swift b/test/SILOptimizer/devirt_value_metatypes.swift similarity index 77% rename from test/SILPasses/devirt_value_metatypes.swift rename to test/SILOptimizer/devirt_value_metatypes.swift index be517e8a8e7f4..1e4477477b025 100644 --- a/test/SILPasses/devirt_value_metatypes.swift +++ b/test/SILOptimizer/devirt_value_metatypes.swift @@ -33,10 +33,13 @@ public class D : C { } // CHECK-LABEL: sil @_TF22devirt_value_metatypes5testDFCS_1DSi -// CHECK: value_metatype $@thick D.Type -// CHECK: checked_cast_br -// CHECK: function_ref -// CHECK: class_method +// CHECK-NOT: value_metatype % +// D.foo is an internal method, D has no subclasses and it is a wmo compilation, +// therefore D.foo method invocation can be devirtualized. +// CHECK: function_ref @_TTSf4d___TZFC22devirt_value_metatypes1D3foofT_Si +// CHECK-NOT: value_metatype % +// CHECK-NOT: checked_cast_br +// CHECK-NOT: class_method // CHECK: } public func testD(x: D) -> Int { return (x.dynamicType as C.Type).foo() diff --git a/test/SILPasses/devirtualize.sil b/test/SILOptimizer/devirtualize.sil similarity index 97% rename from test/SILPasses/devirtualize.sil rename to test/SILOptimizer/devirtualize.sil index 066185318608b..6c73ad07d405a 100644 --- a/test/SILPasses/devirtualize.sil +++ b/test/SILOptimizer/devirtualize.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -dce | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -devirtualizer -dce | FileCheck %s sil_stage canonical diff --git a/test/SILPasses/devirtualize1.swift b/test/SILOptimizer/devirtualize1.swift similarity index 100% rename from test/SILPasses/devirtualize1.swift rename to test/SILOptimizer/devirtualize1.swift diff --git a/test/SILPasses/devirtualize2.sil b/test/SILOptimizer/devirtualize2.sil similarity index 96% rename from test/SILPasses/devirtualize2.sil rename to test/SILOptimizer/devirtualize2.sil index 528176bfd9d83..d2268a66e98ba 100644 --- a/test/SILPasses/devirtualize2.sil +++ b/test/SILOptimizer/devirtualize2.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -dce | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -devirtualizer -dce | FileCheck %s sil_stage canonical diff --git a/test/SILPasses/devirtualize_cast.swift b/test/SILOptimizer/devirtualize_cast.swift similarity index 100% rename from test/SILPasses/devirtualize_cast.swift rename to test/SILOptimizer/devirtualize_cast.swift diff --git a/test/SILPasses/devirtualize_existential.swift b/test/SILOptimizer/devirtualize_existential.swift similarity index 100% rename from test/SILPasses/devirtualize_existential.swift rename to test/SILOptimizer/devirtualize_existential.swift diff --git a/test/SILPasses/diagnose_unreachable.sil b/test/SILOptimizer/diagnose_unreachable.sil similarity index 99% rename from test/SILPasses/diagnose_unreachable.sil rename to test/SILOptimizer/diagnose_unreachable.sil index fce13fcdb151c..c75a460de2131 100644 --- a/test/SILPasses/diagnose_unreachable.sil +++ b/test/SILOptimizer/diagnose_unreachable.sil @@ -243,8 +243,8 @@ bb2: // Preds: bb1 bb0 sil @dead_use_of_alloc_stack : $@convention(thin) () -> () { bb0: %1 = alloc_stack $((), (), ()) - %2 = tuple_element_addr %1#1 : $*((), (), ()), 0 - dealloc_stack %1#0 : $*@local_storage ((), (), ()) + %2 = tuple_element_addr %1 : $*((), (), ()), 0 + dealloc_stack %1 : $*((), (), ()) %3 = tuple () return %3 : $() } diff --git a/test/SILPasses/diagnostic_constant_propagation.swift b/test/SILOptimizer/diagnostic_constant_propagation.swift similarity index 76% rename from test/SILPasses/diagnostic_constant_propagation.swift rename to test/SILOptimizer/diagnostic_constant_propagation.swift index ad6e064247624..ee03087c5a2c9 100644 --- a/test/SILPasses/diagnostic_constant_propagation.swift +++ b/test/SILOptimizer/diagnostic_constant_propagation.swift @@ -2,7 +2,7 @@ // REQUIRES: PTRSIZE=64 -// FIXME: Extend test/SILPasses/diagnostic_constant_propagation.swift to 32-bit platforms +// FIXME: Extend test/SILOptimizer/diagnostic_constant_propagation.swift to 32-bit platforms // These are tests for diagnostics produced by constant propagation pass. @@ -51,7 +51,7 @@ func testGenericArithmeticOverflowMessage() { myaddUnsigned(250, 250, 250) // expected-error{{arithmetic operation '250 + 250' (on unsigned 8-bit integer type) results in an overflow}} } -typealias MyInt = UInt8; +typealias MyInt = UInt8 func testConvertOverflow() { var _ /*int8_minus_two*/ : Int8 = (-2) @@ -106,7 +106,7 @@ func testConvertOverflow() { var _ /*int8_max_pa*/ : Int8 = -13333; //expected-error{{integer literal '-13333' overflows when stored into 'Int8}} var _ /*int32_max_p_hex*/ : Int32 = 0xFFFF_FFFF; //expected-error{{integer literal '4294967295' overflows when stored into 'Int32'}} - var _ /*uint32_max_hex*/ : UInt32 = 0xFFFF_FFFF; + var _ /*uint32_max_hex*/ : UInt32 = 0xFFFF_FFFF var _ /*uint32_max_p_hex*/ : UInt32 = 0xFFFF_FFFF_F; //expected-error{{integer literal '68719476735' overflows when stored into 'UInt32'}} var _ /*uint0_typealias*/ : MyInt = 256; //expected-error{{integer literal '256' overflows when stored into 'MyInt'}} @@ -242,130 +242,66 @@ func testDivision() { func testPostIncOverflow() { var s_max = Int.max - s_max++ // expected-error {{arithmetic operation '9223372036854775807 + 1' (on signed 64-bit integer type) results in an overflow}} + s_max += 1 // expected-error {{arithmetic operation '9223372036854775807 + 1' (on type 'Int') results in an overflow}} var u_max = UInt.max - u_max++ // expected-error {{arithmetic operation '18446744073709551615 + 1' (on unsigned 64-bit integer type) results in an overflow}} + u_max += 1 // expected-error {{arithmetic operation '18446744073709551615 + 1' (on type 'UInt') results in an overflow}} var s8_max = Int8.max - s8_max++ // expected-error {{arithmetic operation '127 + 1' (on signed 8-bit integer type) results in an overflow}} + s8_max += 1 // expected-error {{arithmetic operation '127 + 1' (on type 'Int8') results in an overflow}} var u8_max = UInt8.max - u8_max++ // expected-error {{arithmetic operation '255 + 1' (on unsigned 8-bit integer type) results in an overflow}} + u8_max += 1 // expected-error {{arithmetic operation '255 + 1' (on type 'UInt8') results in an overflow}} var s16_max = Int16.max - s16_max++ // expected-error {{arithmetic operation '32767 + 1' (on signed 16-bit integer type) results in an overflow}} + s16_max += 1 // expected-error {{arithmetic operation '32767 + 1' (on type 'Int16') results in an overflow}} var u16_max = UInt16.max - u16_max++ // expected-error {{arithmetic operation '65535 + 1' (on unsigned 16-bit integer type) results in an overflow}} + u16_max += 1 // expected-error {{arithmetic operation '65535 + 1' (on type 'UInt16') results in an overflow}} var s32_max = Int32.max - s32_max++ // expected-error {{arithmetic operation '2147483647 + 1' (on signed 32-bit integer type) results in an overflow}} + s32_max += 1 // expected-error {{arithmetic operation '2147483647 + 1' (on type 'Int32') results in an overflow}} var u32_max = UInt32.max - u32_max++ // expected-error {{arithmetic operation '4294967295 + 1' (on unsigned 32-bit integer type) results in an overflow}} + u32_max += 1 // expected-error {{arithmetic operation '4294967295 + 1' (on type 'UInt32') results in an overflow}} var s64_max = Int64.max - s64_max++ // expected-error {{arithmetic operation '9223372036854775807 + 1' (on signed 64-bit integer type) results in an overflow}} + s64_max += 1 // expected-error {{arithmetic operation '9223372036854775807 + 1' (on type 'Int64') results in an overflow}} var u64_max = UInt64.max - u64_max++ // expected-error {{arithmetic operation '18446744073709551615 + 1' (on unsigned 64-bit integer type) results in an overflow}} -} - -func testPreIncOverflow() { - var s_max = Int.max - ++s_max // expected-error {{arithmetic operation '9223372036854775807 + 1' (on signed 64-bit integer type) results in an overflow}} - - var u_max = UInt.max - ++u_max // expected-error {{arithmetic operation '18446744073709551615 + 1' (on unsigned 64-bit integer type) results in an overflow}} - - var s8_max = Int8.max - ++s8_max // expected-error {{arithmetic operation '127 + 1' (on signed 8-bit integer type) results in an overflow}} - - var u8_max = UInt8.max - ++u8_max // expected-error {{arithmetic operation '255 + 1' (on unsigned 8-bit integer type) results in an overflow}} - - var s16_max = Int16.max - ++s16_max // expected-error {{arithmetic operation '32767 + 1' (on signed 16-bit integer type) results in an overflow}} - - var u16_max = UInt16.max - ++u16_max // expected-error {{arithmetic operation '65535 + 1' (on unsigned 16-bit integer type) results in an overflow}} - - var s32_max = Int32.max - ++s32_max // expected-error {{arithmetic operation '2147483647 + 1' (on signed 32-bit integer type) results in an overflow}} - - var u32_max = UInt32.max - ++u32_max // expected-error {{arithmetic operation '4294967295 + 1' (on unsigned 32-bit integer type) results in an overflow}} - - var s64_max = Int64.max - ++s64_max // expected-error {{arithmetic operation '9223372036854775807 + 1' (on signed 64-bit integer type) results in an overflow}} - - var u64_max = UInt64.max - ++u64_max // expected-error {{arithmetic operation '18446744073709551615 + 1' (on unsigned 64-bit integer type) results in an overflow}} + u64_max += 1 // expected-error {{arithmetic operation '18446744073709551615 + 1' (on type 'UInt64') results in an overflow}} } func testPostDecOverflow() { var s_min = Int.min - s_min-- // expected-error {{arithmetic operation '-9223372036854775808 - 1' (on signed 64-bit integer type) results in an overflow}} - - var u_min = UInt.min - u_min-- // expected-error {{arithmetic operation '0 - 1' (on unsigned 64-bit integer type) results in an overflow}} - - var s8_min = Int8.min - s8_min-- // expected-error {{arithmetic operation '-128 - 1' (on signed 8-bit integer type) results in an overflow}} - - var u8_min = UInt8.min - u8_min-- // expected-error {{arithmetic operation '0 - 1' (on unsigned 8-bit integer type) results in an overflow}} - - var s16_min = Int16.min - s16_min-- // expected-error {{arithmetic operation '-32768 - 1' (on signed 16-bit integer type) results in an overflow}} - - var u16_min = UInt16.min - u16_min-- // expected-error {{arithmetic operation '0 - 1' (on unsigned 16-bit integer type) results in an overflow}} - - var s32_min = Int32.min - s32_min-- // expected-error {{arithmetic operation '-2147483648 - 1' (on signed 32-bit integer type) results in an overflow}} - - var u32_min = UInt32.min - u32_min-- // expected-error {{arithmetic operation '0 - 1' (on unsigned 32-bit integer type) results in an overflow}} - - var s64_min = Int64.min - s64_min-- // expected-error {{arithmetic operation '-9223372036854775808 - 1' (on signed 64-bit integer type) results in an overflow}} - - var u64_min = UInt64.min - u64_min-- // expected-error {{arithmetic operation '0 - 1' (on unsigned 64-bit integer type) results in an overflow}} -} - -func testPreDecOverflow() { - var s_min = Int.min - --s_min // expected-error {{arithmetic operation '-9223372036854775808 - 1' (on signed 64-bit integer type) results in an overflow}} + s_min -= 1 // expected-error {{arithmetic operation '-9223372036854775808 - 1' (on type 'Int') results in an overflow}} var u_min = UInt.min - --u_min // expected-error {{arithmetic operation '0 - 1' (on unsigned 64-bit integer type) results in an overflow}} + u_min -= 1 // expected-error {{arithmetic operation '0 - 1' (on type 'UInt') results in an overflow}} var s8_min = Int8.min - --s8_min // expected-error {{arithmetic operation '-128 - 1' (on signed 8-bit integer type) results in an overflow}} + s8_min -= 1 // expected-error {{arithmetic operation '-128 - 1' (on type 'Int8') results in an overflow}} var u8_min = UInt8.min - --u8_min // expected-error {{arithmetic operation '0 - 1' (on unsigned 8-bit integer type) results in an overflow}} + u8_min -= 1 // expected-error {{arithmetic operation '0 - 1' (on type 'UInt8') results in an overflow}} var s16_min = Int16.min - --s16_min // expected-error {{arithmetic operation '-32768 - 1' (on signed 16-bit integer type) results in an overflow}} + s16_min -= 1 // expected-error {{arithmetic operation '-32768 - 1' (on type 'Int16') results in an overflow}} var u16_min = UInt16.min - --u16_min // expected-error {{arithmetic operation '0 - 1' (on unsigned 16-bit integer type) results in an overflow}} + u16_min -= 1 // expected-error {{arithmetic operation '0 - 1' (on type 'UInt16') results in an overflow}} var s32_min = Int32.min - --s32_min // expected-error {{arithmetic operation '-2147483648 - 1' (on signed 32-bit integer type) results in an overflow}} + s32_min -= 1 // expected-error {{arithmetic operation '-2147483648 - 1' (on type 'Int32') results in an overflow}} var u32_min = UInt32.min - --u32_min // expected-error {{arithmetic operation '0 - 1' (on unsigned 32-bit integer type) results in an overflow}} + u32_min -= 1 // expected-error {{arithmetic operation '0 - 1' (on type 'UInt32') results in an overflow}} var s64_min = Int64.min - --s64_min // expected-error {{arithmetic operation '-9223372036854775808 - 1' (on signed 64-bit integer type) results in an overflow}} + s64_min -= 1 // expected-error {{arithmetic operation '-9223372036854775808 - 1' (on type 'Int64') results in an overflow}} var u64_min = UInt64.min - --u64_min // expected-error {{arithmetic operation '0 - 1' (on unsigned 64-bit integer type) results in an overflow}} + u64_min -= 1 // expected-error {{arithmetic operation '0 - 1' (on type 'UInt64') results in an overflow}} } func testAssumeNonNegative() { @@ -393,7 +329,7 @@ func add(left: T, _ right: T) -> T { } @_transparent -func applyBinary(fn: (T, T)->(T), _ left: T, _ right: T) -> T { +func applyBinary(fn: (T, T) -> (T), _ left: T, _ right: T) -> T { return fn(left, right) } diff --git a/test/SILPasses/diagnostic_constant_propagation_int.swift b/test/SILOptimizer/diagnostic_constant_propagation_int.swift similarity index 97% rename from test/SILPasses/diagnostic_constant_propagation_int.swift rename to test/SILOptimizer/diagnostic_constant_propagation_int.swift index 4d43411e42afb..e6613919b071d 100644 --- a/test/SILPasses/diagnostic_constant_propagation_int.swift +++ b/test/SILOptimizer/diagnostic_constant_propagation_int.swift @@ -6,11 +6,11 @@ // // For the same reason, this test is using FileCheck instead of -verify. -// FIXME: Extend test/SILPasses/diagnostic_constant_propagation.swift to 32-bit platforms +// FIXME: Extend test/SILOptimizer/diagnostic_constant_propagation.swift to 32-bit platforms #if arch(i386) || arch(arm) func testArithmeticOverflow_Int_32bit() { - if true { + do { // Literals. var t1: Int = 0x7fff_ffff // OK var t2: Int = 0x8000_0000 @@ -21,7 +21,7 @@ func testArithmeticOverflow_Int_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: integer literal {{.*}}overflows when stored into 'Int'{{$}} } - if true { + do { // Negation. var t1: Int = -(-0x7fff_ffff) // OK var t2: Int = -(-0x8000_0000) @@ -29,7 +29,7 @@ func testArithmeticOverflow_Int_32bit() { // Overflow in arithmetic negation is not detected at compile time } - if true { + do { // Addition. var t1: Int = 0x7fff_fffe + 1 // OK var t2: Int = 0x7fff_fffe + 2 @@ -40,7 +40,7 @@ func testArithmeticOverflow_Int_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '-2147483647 + -2' (on type 'Int') results in an overflow{{$}} } - if true { + do { // Subtraction. var t1: Int = 0x7fff_fffe - (-1) // OK var t2: Int = 0x7fff_fffe - (-2) @@ -51,7 +51,7 @@ func testArithmeticOverflow_Int_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '-2147483647 - 2' (on type 'Int') results in an overflow{{$}} } - if true { + do { // Multiplication. var t1: Int = 0x7fff_fffe * 1 // OK var t2: Int = 0x7fff_fffe * 2 @@ -62,7 +62,7 @@ func testArithmeticOverflow_Int_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '-2147483647 * 2' (on type 'Int') results in an overflow{{$}} } - if true { + do { // Division. var t1: Int = 0x7fff_fffe / 2 // OK var t2: Int = 0x7fff_fffe / 0 @@ -76,7 +76,7 @@ func testArithmeticOverflow_Int_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: division '-2147483648 / -1' results in an overflow{{$}} } - if true { + do { // Remainder. var t1: Int = 0x7fff_fffe % 2 // OK var t2: Int = 0x7fff_fffe % 0 @@ -90,7 +90,7 @@ func testArithmeticOverflow_Int_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: division '-2147483648 % -1' results in an overflow{{$}} } - if true { + do { // Right shift. var t1: Int = 0 >> 0 var t2: Int = 0 >> 1 @@ -116,7 +116,7 @@ func testArithmeticOverflow_Int_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: shift amount is greater than or equal to type size in bits{{$}} } - if true { + do { // Left shift. var t1: Int = 0 << 0 var t2: Int = 0 << 1 @@ -144,7 +144,7 @@ func testArithmeticOverflow_Int_32bit() { } func testArithmeticOverflow_UInt_32bit() { - if true { + do { // Literals. var t1: UInt = 0x7fff_ffff // OK var t2: UInt = 0x8000_0000 @@ -161,11 +161,11 @@ func testArithmeticOverflow_UInt_32bit() { // Obscure diagnostic for assigning negative numbers to unsigned } - if true { + do { // There is no negation for unsigned integers. } - if true { + do { // Addition. var t1: UInt = 0 + 0 // OK var t2: UInt = 0xffff_ffff + 0 // OK @@ -177,7 +177,7 @@ func testArithmeticOverflow_UInt_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '4294967294 + 2' (on type 'UInt') results in an overflow{{$}} } - if true { + do { // Subtraction. var t1: UInt = 0xffff_fffe - 1 // OK var t2: UInt = 0xffff_fffe - 0xffff_ffff @@ -188,7 +188,7 @@ func testArithmeticOverflow_UInt_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '0 - 1' (on type 'UInt') results in an overflow{{$}} } - if true { + do { // Multiplication. var t1: UInt = 0xffff_ffff * 0 // OK var t2: UInt = 0xffff_ffff * 1 // OK @@ -205,7 +205,7 @@ func testArithmeticOverflow_UInt_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '2147483646 * 3' (on type 'UInt') results in an overflow{{$}} } - if true { + do { // Division. var t1: UInt = 0x7fff_fffe / 2 // OK var t2: UInt = 0x7fff_fffe / 0 @@ -217,7 +217,7 @@ func testArithmeticOverflow_UInt_32bit() { } - if true { + do { // Remainder. var t1: UInt = 0x7fff_fffe % 2 // OK var t2: UInt = 0x7fff_fffe % 0 @@ -228,7 +228,7 @@ func testArithmeticOverflow_UInt_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: division by zero{{$}} } - if true { + do { // Right shift. var t1: UInt = 0 >> 0 var t2: UInt = 0 >> 1 @@ -246,7 +246,7 @@ func testArithmeticOverflow_UInt_32bit() { // CHECK-32-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: shift amount is greater than or equal to type size in bits{{$}} } - if true { + do { // Left shift. var t1: UInt = 0 << 0 var t2: UInt = 0 << 1 @@ -268,7 +268,7 @@ func testArithmeticOverflow_UInt_32bit() { #elseif arch(x86_64) || arch(arm64) func testArithmeticOverflow_Int_64bit() { - if true { + do { // Literals. var t1: Int = 0x7fff_ffff_ffff_ffff // OK var t2: Int = 0x8000_0000_0000_0000 @@ -279,7 +279,7 @@ func testArithmeticOverflow_Int_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: integer literal {{.*}} overflows when stored into 'Int'{{$}} } - if true { + do { // Negation. var t1: Int = -(-0x7fff_ffff_ffff_ffff) // OK var t2: Int = -(-0x8000_0000_0000_0000) @@ -287,7 +287,7 @@ func testArithmeticOverflow_Int_64bit() { // Overflow in arithmetic negation is not detected at compile time } - if true { + do { // Addition. var t1: Int = 0x7fff_ffff_ffff_fffe + 1 // OK var t2: Int = 0x7fff_ffff_ffff_fffe + 2 @@ -298,7 +298,7 @@ func testArithmeticOverflow_Int_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '-9223372036854775807 + -2' (on type 'Int') results in an overflow{{$}} } - if true { + do { // Subtraction. var t1: Int = 0x7fff_ffff_ffff_fffe - (-1) // OK var t2: Int = 0x7fff_ffff_ffff_fffe - (-2) @@ -309,7 +309,7 @@ func testArithmeticOverflow_Int_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '-9223372036854775807 - 2' (on type 'Int') results in an overflow{{$}} } - if true { + do { // Multiplication. var t1: Int = 0x7fff_ffff_ffff_fffe * 1 // OK var t2: Int = 0x7fff_ffff_ffff_fffe * 2 @@ -320,7 +320,7 @@ func testArithmeticOverflow_Int_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '-9223372036854775807 * 2' (on type 'Int') results in an overflow{{$}} } - if true { + do { // Division. var t1: Int = 0x7fff_ffff_ffff_fffe / 2 // OK var t2: Int = 0x7fff_ffff_ffff_fffe / 0 @@ -334,7 +334,7 @@ func testArithmeticOverflow_Int_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: division '-9223372036854775808 / -1' results in an overflow{{$}} } - if true { + do { // Remainder. var t1: Int = 0x7fff_ffff_ffff_fffe % 2 // OK var t2: Int = 0x7fff_ffff_ffff_fffe % 0 @@ -348,7 +348,7 @@ func testArithmeticOverflow_Int_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: division '-9223372036854775808 % -1' results in an overflow{{$}} } - if true { + do { // Right shift. var t1: Int = 0 >> 0 var t2: Int = 0 >> 1 @@ -374,7 +374,7 @@ func testArithmeticOverflow_Int_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: shift amount is greater than or equal to type size in bits{{$}} } - if true { + do { // Left shift. var t1: Int = 0 << 0 var t2: Int = 0 << 1 @@ -402,7 +402,7 @@ func testArithmeticOverflow_Int_64bit() { } func testArithmeticOverflow_UInt_64bit() { - if true { + do { // Literals. var t1: UInt = 0x7fff_ffff_ffff_ffff // OK var t2: UInt = 0x8000_0000_0000_0000 @@ -415,11 +415,11 @@ func testArithmeticOverflow_UInt_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: negative integer {{.*}} overflows when stored into unsigned type 'UInt'{{$}} } - if true { + do { // There is no negation for unsigned integers. } - if true { + do { // Addition. var t1: UInt = 0 + 0 // OK var t2: UInt = 0xffff_ffff_ffff_ffff + 0 // OK @@ -431,7 +431,7 @@ func testArithmeticOverflow_UInt_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '18446744073709551614 + 2' (on type 'UInt') results in an overflow{{$}} } - if true { + do { // Subtraction. var t1: UInt = 0xffff_ffff_ffff_fffe - 1 // OK var t2: UInt = 0xffff_ffff_ffff_fffe - 0xffff_ffff_ffff_ffff @@ -442,7 +442,7 @@ func testArithmeticOverflow_UInt_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '0 - 1' (on type 'UInt') results in an overflow{{$}} } - if true { + do { // Multiplication. var t1: UInt = 0xffff_ffff_ffff_ffff * 0 // OK var t2: UInt = 0xffff_ffff_ffff_ffff * 1 // OK @@ -459,7 +459,7 @@ func testArithmeticOverflow_UInt_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: arithmetic operation '9223372036854775806 * 3' (on type 'UInt') results in an overflow{{$}} } - if true { + do { // Division. var t1: UInt = 0x7fff_ffff_ffff_fffe / 2 // OK var t2: UInt = 0x7fff_ffff_ffff_fffe / 0 @@ -471,7 +471,7 @@ func testArithmeticOverflow_UInt_64bit() { } - if true { + do { // Remainder. var t1: UInt = 0x7fff_ffff_ffff_fffe % 2 // OK var t2: UInt = 0x7fff_ffff_ffff_fffe % 0 @@ -482,7 +482,7 @@ func testArithmeticOverflow_UInt_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: division by zero{{$}} } - if true { + do { // Right shift. var t1: UInt = 0 >> 0 var t2: UInt = 0 >> 1 @@ -500,7 +500,7 @@ func testArithmeticOverflow_UInt_64bit() { // CHECK-64-DAG: .swift:[[@LINE-1]]:{{[0-9]+}}: error: shift amount is greater than or equal to type size in bits{{$}} } - if true { + do { // Left shift. var t1: UInt = 0 << 0 var t2: UInt = 0 << 1 diff --git a/test/SILPasses/earlycodemotion.sil b/test/SILOptimizer/earlycodemotion.sil similarity index 97% rename from test/SILPasses/earlycodemotion.sil rename to test/SILOptimizer/earlycodemotion.sil index 74732c1eb45d5..69a722717f058 100644 --- a/test/SILPasses/earlycodemotion.sil +++ b/test/SILOptimizer/earlycodemotion.sil @@ -186,7 +186,7 @@ bb0(%0 : $Optional): apply %1() : $@convention(thin) () -> () %3 = alloc_stack $Builtin.Int32 retain_value %0 : $Optional - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb2 bb1(%2 : $Builtin.NativeObject): @@ -281,7 +281,7 @@ bb4: return %2 : $() } -// This test makes sure that we do move ref counts over instructions that can not reference it. +// This test makes sure that we do move ref counts over instructions that cannot reference it. // CHECK-LABEL: sil @sink_ref_count_ops_enum_over_switch_enum_4 : // CHECK: bb0({{%[0-9]+}} : $Optional, [[ARG1:%[0-9]+]] : $Optional): // CHECK-NOT: retain_value [[ARG1]] @@ -313,7 +313,7 @@ bb2: br bb3 bb3: - dealloc_stack %3#0 : $*@local_storage Optional + dealloc_stack %3 : $*Optional return %1 : $Optional } @@ -343,7 +343,7 @@ bb10: %1 = function_ref @blocker : $@convention(thin) () -> () retain_value %0 : $Optional %3 = alloc_stack $Builtin.Int32 - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 release_value %0 : $Optional switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb2 @@ -390,7 +390,7 @@ bb0(%0 : $Optional): apply %1() : $@convention(thin) () -> () %3 = alloc_stack $Builtin.Int32 retain_value %0 : $Optional - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 %100 = select_enum %0 : $Optional, case #Optional.Some!enumelt.1: %t, case #Optional.None!enumelt: %f : $Builtin.Int1 cond_br %100, bb1, bb2 @@ -556,7 +556,7 @@ bb10: %1 = function_ref @blocker : $@convention(thin) () -> () retain_value %0 : $Optional %3 = alloc_stack $Builtin.Int32 - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 %100 = select_enum %0 : $Optional, case #Optional.Some!enumelt.1: %t, case #Optional.None!enumelt: %f : $Builtin.Int1 release_value %0 : $Optional cond_br %100, bb1, bb2 @@ -884,7 +884,7 @@ bb3: return %9999 : $() } -// Because our enum is not local to this function, we can not move retain_value +// Because our enum is not local to this function, we cannot move retain_value // %0 past blocker. // // CHECK-LABEL: sil @enum_simplification_test6b : $@convention(thin) (Optional) -> () { @@ -1333,11 +1333,11 @@ class G {} sil @cast_consumption : $@convention(thin) (@owned F) -> () { bb0(%0 : $F): %1 = alloc_stack $F - store %0 to %1#1 : $*F + store %0 to %1 : $*F strong_retain %0 : $F - unconditional_checked_cast_addr take_always F in %1#1 : $*F to G in %1#1 : $*F + unconditional_checked_cast_addr take_always F in %1 : $*F to G in %1 : $*F strong_release %0 : $F - dealloc_stack %1#0 : $*@local_storage F + dealloc_stack %1 : $*F %2 = tuple () return %2 : $() } @@ -1416,7 +1416,7 @@ class Y : X { } sil @canonicalize_releases : $@convention(thin) (@owned Optional) -> () { bb0(%0 : $Optional): - debug_value %0 : $Optional // let x // id: %1 + debug_value %0 : $Optional, let, name "x" // id: %1 switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb3 // id: %2 bb1: // Preds: bb0 @@ -1463,11 +1463,11 @@ bb5: // Preds: bb1 // Make sure we are replacing all uses of %3 with %0. sil @canonicalize_casts: $@convention(thin) (@owned X) -> Int32 { bb0(%0 : $X): - debug_value %0 : $X // let x // id: %1 + debug_value %0 : $X, let, name "x" // id: %1 checked_cast_br %0 : $X to $Y, bb1, bb3 // id: %2 bb1(%3 : $Y): // Preds: bb0 - debug_value %3 : $Y // let z // id: %4 + debug_value %3 : $Y, let, name "z" // id: %4 %5 = upcast %3 : $Y to $X // users: %6, %7, %21, %23 %6 = class_method %5 : $X, #X.ping!1 : X -> () -> () , $@convention(method) (@guaranteed X) -> () // users: %21, %23 checked_cast_br [exact] %5 : $X to $Y, bb5, bb6 // id: %7 @@ -1561,19 +1561,19 @@ bb3(%z1 : $Builtin.RawPointer): // CHECK-LABEL: sil hidden @sink_allocation_inst sil hidden @sink_allocation_inst : $@convention(thin) (Boo, Boo) -> Bool { bb0(%0 : $Boo, %1 : $Boo): - debug_value %0 : $Boo // let x // id: %2 + debug_value %0 : $Boo, let, name "x" // id: %2 debug_value %0 : $Boo // id: %3 - debug_value %0 : $Boo // let self // id: %4 + debug_value %0 : $Boo, let, name "self" // id: %4 switch_enum %0 : $Boo, case #Boo.one!enumelt: bb1, case #Boo.two!enumelt: bb3 // id: %5 bb1: // Preds: bb0 %6 = alloc_ref $fuzz // users: %7, %8 - debug_value %6 : $fuzz // let self // id: %7 + debug_value %6 : $fuzz, let, name "self" // id: %7 br bb2(%6 : $fuzz) // id: %8 bb3: // Preds: bb0 %15 = alloc_ref $fuzz // users: %16, %17 - debug_value %15 : $fuzz // let self // id: %16 + debug_value %15 : $fuzz, let, name "self" // id: %16 br bb2(%15 : $fuzz) // id: %17 bb2(%9 : $fuzz): @@ -1581,7 +1581,7 @@ bb2(%9 : $fuzz): // CHECK: alloc_ref // CHECK-NOT: alloc_ref // CHECK: return - debug_value %9 : $fuzz // let lhs // id: %10 + debug_value %9 : $fuzz, let, name "lhs" // id: %10 %11 = integer_literal $Builtin.Int1, -1 // user: %12 %12 = struct $Bool (%11 : $Builtin.Int1) // user: %14 strong_release %9 : $fuzz // id: %13 @@ -1649,14 +1649,14 @@ bb0(%0 : $Bool): %3 = function_ref @foo_init : $@convention(thin) (@thin foo.Type) -> foo // user: %5 %4 = metatype $@thin foo.Type // user: %5 %5 = apply %3(%4) : $@convention(thin) (@thin foo.Type) -> foo // user: %6 - store %5 to %1#1 : $*foo // id: %6 + store %5 to %1 : $*foo // id: %6 %7 = struct_extract %0 : $Bool, #Bool.value // user: %8 cond_br %7, bb1, bb2 // id: %8 bb1: // Preds: bb0 %9 = integer_literal $Builtin.Int64, 11 // user: %10 %10 = struct $Int (%9 : $Builtin.Int64) // user: %13 - %11 = struct_element_addr %1#1 : $*foo, #foo.a // users: %12, %13 + %11 = struct_element_addr %1 : $*foo, #foo.a // users: %12, %13 %12 = load %11 : $*Int // user: %14 store %10 to %11 : $*Int // id: %13 br bb3(%12 : $Int) // id: %14 @@ -1664,7 +1664,7 @@ bb1: // Preds: bb0 bb2: // Preds: bb0 %15 = integer_literal $Builtin.Int64, 12 // user: %16 %16 = struct $Int (%15 : $Builtin.Int64) - %17 = struct_element_addr %1#1 : $*foo, #foo.a // user: %18 + %17 = struct_element_addr %1 : $*foo, #foo.a // user: %18 %18 = load %17 : $*Int // user: %19 br bb3(%18 : $Int) // id: %19 @@ -1674,7 +1674,7 @@ bb3(%20 : $Int): // Preds: bb1 bb2 %21 = function_ref @user_int : $@convention(thin) (Int) -> () // user: %22 %22 = apply %21(%20) : $@convention(thin) (Int) -> () %23 = tuple () // user: %25 - dealloc_stack %1#0 : $*@local_storage foo // id: %24 + dealloc_stack %1 : $*foo // id: %24 return %23 : $() // id: %25 } diff --git a/test/SILPasses/enum_jump_thread.sil b/test/SILOptimizer/enum_jump_thread.sil similarity index 100% rename from test/SILPasses/enum_jump_thread.sil rename to test/SILOptimizer/enum_jump_thread.sil diff --git a/test/SILAnalysis/escape_analysis.sil b/test/SILOptimizer/escape_analysis.sil similarity index 77% rename from test/SILAnalysis/escape_analysis.sil rename to test/SILOptimizer/escape_analysis.sil index 7a8a875a3062a..670f75677539b 100644 --- a/test/SILAnalysis/escape_analysis.sil +++ b/test/SILOptimizer/escape_analysis.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt %s -update-escapes -sil-print-escapes -o /dev/null | FileCheck %s +// RUN: %target-sil-opt %s -escapes-dump -o /dev/null | FileCheck %s // REQUIRES: asserts @@ -8,27 +8,46 @@ import Builtin import Swift import SwiftShims -class X { +protocol ClassP : class { + func foo() +} + +class X : ClassP { + func foo() +} + +class Derived : X { } class Y { - @sil_stored var x: X + @sil_stored var x: X + + init(newx: X) +} - init(newx: X) +protocol P { + func foo() } -struct Pointer { - let y : Y +struct Pointer : P { + let y : Y + func foo() } enum PointerEnum { - case B(Pointer, Pointer) + case B(Pointer, Pointer) +} + +enum PointerEnum2 { + case A + case B(Pointer) + case C } class LinkedNode { - @sil_stored var next: LinkedNode; + @sil_stored var next: LinkedNode; - init(_ n: LinkedNode) + init(_ n: LinkedNode) } struct MyError : ErrorType { @@ -60,9 +79,9 @@ bb0(%0 : $*Y, %1 : $X): return %7 : $() } -// Test if a defering edge is created for a block argument. +// Test if a deferring edge is created for a block argument. -// CHECK-LABEL: CG of deferingEdge +// CHECK-LABEL: CG of deferringEdge // CHECK-NEXT: Arg %0 Esc: A, Succ: (%3.1) // CHECK-NEXT: Arg %1 Esc: A, Succ: // CHECK-NEXT: Val %3 Esc: %3, Succ: (%3.1), %0 @@ -70,7 +89,7 @@ bb0(%0 : $*Y, %1 : $X): // CHECK-NEXT: Con %3.2 Esc: A, Succ: %1 // CHECK-NEXT: Ret Esc: R, Succ: %0 // CHECK-NEXT: End -sil @deferingEdge : $@convention(thin) (@owned LinkedNode, @owned LinkedNode) -> @owned LinkedNode { +sil @deferringEdge : $@convention(thin) (@owned LinkedNode, @owned LinkedNode) -> @owned LinkedNode { bb0(%0 : $LinkedNode, %1 : $LinkedNode): br bb1(%0 : $LinkedNode) @@ -308,10 +327,10 @@ bb0(%0 : $Int64, %1 : $X, %2 : $Y): store %0 to %3#1 : $*Int64 %5 = alloc_box $Y store %2 to %5#1 : $*Y - %7 = function_ref @closure1 : $@convention(thin) (@owned X, @owned @box Int64, @inout Int64, @owned @box Y, @inout Y) -> Int64 + %7 = function_ref @closure1 : $@convention(thin) (@owned X, @owned @box Int64, @owned @box Y) -> Int64 strong_retain %3#0 : $@box Int64 strong_retain %5#0 : $@box Y - %10 = partial_apply %7(%3#0, %3#1, %5#0, %5#1) : $@convention(thin) (@owned X, @owned @box Int64, @inout Int64, @owned @box Y, @inout Y) -> Int64 + %10 = partial_apply %7(%3#0, %5#0) : $@convention(thin) (@owned X, @owned @box Int64, @owned @box Y) -> Int64 strong_retain %10 : $@callee_owned (@owned X) -> Int64 %12 = apply %10(%1) : $@callee_owned (@owned X) -> Int64 strong_release %10 : $@callee_owned (@owned X) -> Int64 @@ -325,36 +344,34 @@ bb0(%0 : $Int64, %1 : $X, %2 : $Y): // CHECK-NEXT: Arg %1 Esc: A, Succ: (%1.1) // CHECK-NEXT: Con %1.1 Esc: A, Succ: (%1.2) // CHECK-NEXT: Con %1.2 Esc: G, Succ: -// CHECK-NEXT: Arg %2 Esc: A, Succ: -// CHECK-NEXT: Arg %3 Esc: A, Succ: (%7.1) -// CHECK-NEXT: Arg %4 Esc: A, Succ: (%7.1) -// CHECK-NEXT: Val %7 Esc: %8, Succ: %3, %4 -// CHECK-NEXT: Con %7.1 Esc: A, Succ: (%7.2) -// CHECK-NEXT: Con %7.2 Esc: G, Succ: (%7.3) -// CHECK-NEXT: Con %7.3 Esc: G, Succ: %0 -// CHECK-NEXT: End -sil @closure1 : $@convention(thin) (@owned X, @owned @box Int64, @inout Int64, @owned @box Y, @inout Y) -> Int64 { -bb0(%0 : $X, %1 : $@box Int64, %2 : $*Int64, %3 : $@box Y, %4 : $*Y): - %5 = load %2 : $*Int64 - %6 = function_ref @closure2 : $@convention(thin) (@owned X, @owned @box Y, @inout Y) -> () - %7 = partial_apply %6(%3, %4) : $@convention(thin) (@owned X, @owned @box Y, @inout Y) -> () +// CHECK-NEXT: Arg %2 Esc: A, Succ: (%2.1) +// CHECK-NEXT: Con %2.1 Esc: A, Succ: (%2.2) +// CHECK-NEXT: Con %2.2 Esc: G, Succ: +// CHECK-NEXT: Val %7 Esc: %8, Succ: %2 +// CHECK-NEXT: End +sil @closure1 : $@convention(thin) (@owned X, @owned @box Int64, @owned @box Y) -> Int64 { +bb0(%0 : $X, %1 : $@box Int64, %2 : $@box Y): + %3 = project_box %1 : $@box Int64 + %4 = project_box %2 : $@box Y + %5 = load %3 : $*Int64 + %6 = function_ref @closure2 : $@convention(thin) (@owned X, @owned @box Y) -> () + %7 = partial_apply %6(%2) : $@convention(thin) (@owned X, @owned @box Y) -> () %8 = apply %7(%0) : $@callee_owned (@owned X) -> () strong_release %1 : $@box Int64 return %5 : $Int64 } // CHECK-LABEL: CG of closure2 -// CHECK-NEXT: Arg %0 Esc: A, Succ: +// CHECK-NEXT: Arg %0 Esc: G, Succ: // CHECK-NEXT: Arg %1 Esc: A, Succ: (%1.1) // CHECK-NEXT: Con %1.1 Esc: A, Succ: (%1.2) -// CHECK-NEXT: Con %1.2 Esc: G, Succ: -// CHECK-NEXT: Arg %2 Esc: A, Succ: (%2.1) -// CHECK-NEXT: Con %2.1 Esc: A, Succ: (%2.2) -// CHECK-NEXT: Con %2.2 Esc: A, Succ: (%2.3) -// CHECK-NEXT: Con %2.3 Esc: A, Succ: %0 +// CHECK-NEXT: Con %1.2 Esc: G, Succ: (%1.3) +// CHECK-NEXT: Con %1.3 Esc: G, Succ: (%1.4) +// CHECK-NEXT: Con %1.4 Esc: G, Succ: %0 // CHECK-NEXT: End -sil @closure2 : $@convention(thin) (@owned X, @owned @box Y, @inout Y) -> () { -bb0(%0 : $X, %1 : $@box Y, %2 : $*Y): +sil @closure2 : $@convention(thin) (@owned X, @owned @box Y) -> () { +bb0(%0 : $X, %1 : $@box Y): + %2 = project_box %1 : $@box Y %3 = load %2 : $*Y %4 = ref_element_addr %3 : $Y, #Y.x store %0 to %4 : $*X @@ -376,9 +393,9 @@ bb0(%0 : $Int64): %1 = alloc_box $Int64 store %0 to %1#1 : $*Int64 - %3 = function_ref @let_box_escape : $@convention(thin) (@owned @box Int64, @inout Int64) -> Int64 + %3 = function_ref @let_box_escape : $@convention(thin) (@owned @box Int64) -> Int64 strong_retain %1#0 : $@box Int64 - %5 = partial_apply %3(%1#0, %1#1) : $@convention(thin) (@owned @box Int64, @inout Int64) -> Int64 + %5 = partial_apply %3(%1#0) : $@convention(thin) (@owned @box Int64) -> Int64 strong_retain %5 : $@callee_owned () -> Int64 %7 = apply %5() : $@callee_owned () -> Int64 strong_release %5 : $@callee_owned () -> Int64 @@ -391,10 +408,10 @@ bb0(%0 : $Int64): // CHECK-NEXT: Arg %0 Esc: G, Succ: (%0.1) // CHECK-NEXT: Con %0.1 Esc: G, Succ: (%0.2) // CHECK-NEXT: Con %0.2 Esc: G, Succ: -// CHECK-NEXT: Arg %1 Esc: A, Succ: // CHECK-NEXT: End -sil @let_box_escape : $@convention(thin) (@owned @box Int64, @inout Int64) -> Int64 { -bb0(%0 : $@box Int64, %1 : $*Int64): +sil @let_box_escape : $@convention(thin) (@owned @box Int64) -> Int64 { +bb0(%0 : $@box Int64): + %1 = project_box %0 : $@box Int64 %2 = load %1 : $*Int64 %3 = function_ref @takebox : $@convention(thin) (@owned @box Int64) -> () @@ -417,9 +434,9 @@ sil @test_escaped_partial_apply : $@convention(thin) (Int64) -> () { bb0(%0 : $Int64): %1 = alloc_box $Int64 store %0 to %1#1 : $*Int64 - %3 = function_ref @closure3 : $@convention(thin) (@owned @box Int64, @inout Int64) -> Int64 + %3 = function_ref @closure3 : $@convention(thin) (@owned @box Int64) -> Int64 strong_retain %1#0 : $@box Int64 - %5 = partial_apply %3(%1#0, %1#1) : $@convention(thin) (@owned @box Int64, @inout Int64) -> Int64 + %5 = partial_apply %3(%1#0) : $@convention(thin) (@owned @box Int64) -> Int64 strong_retain %5 : $@callee_owned () -> Int64 %6 = function_ref @take_partial_apply : $@convention(thin) (@owned @callee_owned () -> Int64) -> () %7 = apply %6(%5) : $@convention(thin) (@owned @callee_owned () -> Int64) -> () @@ -431,10 +448,10 @@ bb0(%0 : $Int64): // CHECK-NEXT: Arg %0 Esc: A, Succ: (%0.1) // CHECK-NEXT: Con %0.1 Esc: A, Succ: (%0.2) // CHECK-NEXT: Con %0.2 Esc: G, Succ: -// CHECK-NEXT: Arg %1 Esc: A, Succ: // CHECK-NEXT: End -sil @closure3 : $@convention(thin) (@owned @box Int64, @inout Int64) -> Int64 { -bb0(%0 : $@box Int64, %1 : $*Int64): +sil @closure3 : $@convention(thin) (@owned @box Int64) -> Int64 { +bb0(%0 : $@box Int64): + %1 = project_box %0 : $@box Int64 %2 = load %1 : $*Int64 strong_release %0 : $@box Int64 return %2 : $Int64 @@ -450,7 +467,7 @@ sil_global @global_ln : $LinkedNode // CHECK-NEXT: Arg %0 Esc: A, Succ: (%0.1) // CHECK-NEXT: Con %0.1 Esc: A, Succ: (%0.2) // CHECK-NEXT: Con %0.2 Esc: G, Succ: (%4.1) -// CHECK-NEXT: Val %4 Esc: R, Succ: (%4.1), %0.2 +// CHECK-NEXT: Val %4 Esc: R, Succ: %0.2 // CHECK-NEXT: Con %4.1 Esc: G, Succ: // CHECK-NEXT: Ret Esc: R, Succ: %4 // CHECK-NEXT: End @@ -465,11 +482,10 @@ bb0(%0 : $LinkedNode): // CHECK-LABEL: CG of let_escape // CHECK-NEXT: Arg %0 Esc: G, Succ: (%0.1) -// CHECK-NEXT: Con %0.1 Esc: G, Succ: (%0.2) -// CHECK-NEXT: Con %0.2 Esc: G, Succ: +// CHECK-NEXT: Con %0.1 Esc: G, Succ: // CHECK-NEXT: Val %1 Esc: G, Succ: (%1.1) // CHECK-NEXT: Con %1.1 Esc: G, Succ: %0 -// CHECK-NEXT: Val %4 Esc: R, Succ: (%0.1), %0 +// CHECK-NEXT: Val %4 Esc: R, Succ: %0 // CHECK-NEXT: Ret Esc: R, Succ: %4 // CHECK-NEXT: End sil @let_escape : $@convention(thin) (@owned LinkedNode) -> @owned LinkedNode { @@ -510,7 +526,7 @@ bb2(%5 : $LinkedNode): // CHECK-NEXT: Con %0.2 Esc: A, Succ: (%0.3) // CHECK-NEXT: Con %0.3 Esc: A, Succ: (%0.4) // CHECK-NEXT: Con %0.4 Esc: A, Succ: (%4.1) -// CHECK-NEXT: Val %4 Esc: R, Succ: %0.4, %4.2 +// CHECK-NEXT: Val %4 Esc: R, Succ: %0.4 // CHECK-NEXT: Con %4.1 Esc: A, Succ: (%4.2) // CHECK-NEXT: Con %4.2 Esc: A, Succ: (%4.1) // CHECK-NEXT: Ret Esc: R, Succ: %4 @@ -577,7 +593,7 @@ bb2(%5 : $LinkedNode): return %5 : $LinkedNode } -// Test if a try_apply is repressented correctly in the connection graph. +// Test if a try_apply is represented correctly in the connection graph. // CHECK-LABEL: CG of call_throwing_func // CHECK-NEXT: Arg %0 Esc: A, Succ: @@ -691,7 +707,100 @@ bb1(%7 : $(Pointer, Pointer)): return %9 : $Y } -// We don't handle existentials currently. +// CHECK-LABEL: CG of defer_edge_cycle +// CHECK-NEXT: Arg %0 Esc: A, Succ: (%0.1) +// CHECK-NEXT: Con %0.1 Esc: A, Succ: %1.1 +// CHECK-NEXT: Con %0.2 Esc: A, Succ: (%0.3) +// CHECK-NEXT: Con %0.3 Esc: A, Succ: +// CHECK-NEXT: Arg %1 Esc: A, Succ: (%1.1) +// CHECK-NEXT: Con %1.1 Esc: A, Succ: (%0.2), %0.1 +// CHECK-NEXT: End +sil @defer_edge_cycle : $@convention(thin) (@inout Y, @inout Y) -> () { +entry(%0 : $*Y, %1 : $*Y): + %l1 = load %0 : $*Y + store %l1 to %1 : $*Y + %l2 = load %1 : $*Y + store %l2 to %0 : $*Y + %x = ref_element_addr %l1 : $Y, #Y.x + %l3 = load %x : $*X + %r = tuple () + return %r : $() +} + +// CHECK-LABEL: CG of test_select_enum +// CHECK-NEXT: Arg %0 Esc: A, Succ: +// CHECK-NEXT: Arg %1 Esc: A, Succ: +// CHECK-NEXT: Arg %2 Esc: A, Succ: +// CHECK-NEXT: Arg %3 Esc: A, Succ: +// CHECK-NEXT: Val %4 Esc: R, Succ: %1, %2, %3 +// CHECK-NEXT: Ret Esc: R, Succ: %4 +// CHECK-NEXT: End +sil @test_select_enum : $@convention(thin) (PointerEnum2, @owned X, @owned X, @owned X) -> @owned X { +bb0(%0 : $PointerEnum2, %1 : $X, %2 : $X, %3 : $X): + %4 = select_enum %0 : $PointerEnum2, case #PointerEnum2.A!enumelt: %1, case #PointerEnum2.B!enumelt: %2, default %3 : $X + return %4 : $X +} + +// CHECK-LABEL: CG of test_select_enum_addr +// CHECK-NEXT: Arg %0 Esc: A, Succ: +// CHECK-NEXT: Arg %1 Esc: A, Succ: +// CHECK-NEXT: Arg %2 Esc: A, Succ: +// CHECK-NEXT: Arg %3 Esc: A, Succ: +// CHECK-NEXT: Val %4 Esc: R, Succ: %1, %2, %3 +// CHECK-NEXT: Ret Esc: R, Succ: %4 +// CHECK-NEXT: End +sil @test_select_enum_addr : $@convention(thin) (@in PointerEnum2, @owned X, @owned X, @owned X) -> @owned X { +bb0(%0 : $*PointerEnum2, %1 : $X, %2 : $X, %3 : $X): + %4 = select_enum_addr %0 : $*PointerEnum2, case #PointerEnum2.A!enumelt: %1, case #PointerEnum2.B!enumelt: %2, default %3 : $X + return %4 : $X +} + +// CHECK-LABEL: CG of test_select_value +// CHECK-NEXT: Arg %1 Esc: A, Succ: +// CHECK-NEXT: Arg %2 Esc: A, Succ: +// CHECK-NEXT: Arg %3 Esc: A, Succ: +// CHECK-NEXT: Val %6 Esc: R, Succ: %1, %2, %3 +// CHECK-NEXT: Ret Esc: R, Succ: %6 +// CHECK-NEXT: End +sil @test_select_value : $@convention(thin) (Builtin.Int64, @owned X, @owned X, @owned X) -> @owned X { +bb0(%0 : $Builtin.Int64, %1 : $X, %2 : $X, %3 : $X): + %4 = integer_literal $Builtin.Int64, 0 + %5 = integer_literal $Builtin.Int64, 1 + %6 = select_value %0 : $Builtin.Int64, case %4: %1, case %5: %2, default %3 : $X + return %6 : $X +} + +// CHECK-LABEL: CG of test_existential_addr +// CHECK-NEXT: Arg %0 Esc: A, Succ: +// CHECK-NEXT: Val %1 Esc: , Succ: (%1.1) +// CHECK-NEXT: Con %1.1 Esc: , Succ: (%1.2) +// CHECK-NEXT: Con %1.2 Esc: , Succ: %0 +// CHECK-NEXT: End +sil @test_existential_addr : $@convention(thin) (@owned Pointer) -> () { +bb0(%0 : $Pointer): + %1 = alloc_stack $P + %2 = init_existential_addr %1 : $*P, $Pointer + store %0 to %2 : $*Pointer + %4 = open_existential_addr %1 : $*P to $*@opened("C62B1408-97C8-11E5-8D7C-685B35C48C83") P + %5 = witness_method $@opened("C62B1408-97C8-11E5-8D7C-685B35C48C83") P, #P.foo!1, %4 : $*@opened("C62B1408-97C8-11E5-8D7C-685B35C48C83") P : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> () + dealloc_stack %1 : $*P + %7 = tuple () + return %7 : $() +} + +// CHECK-LABEL: CG of test_existential_ref +// CHECK-NEXT: Arg %0 Esc: A, Succ: +// CHECK-NEXT: End +sil @test_existential_ref : $@convention(thin) (@owned X) -> () { +bb0(%0 : $X): + %1 = init_existential_ref %0 : $X : $X, $ClassP + %2 = open_existential_ref %1 : $ClassP to $@opened("EC6B6A86-9887-11E5-926E-685B35C48C83") ClassP + %3 = witness_method $@opened("EC6B6A86-9887-11E5-926E-685B35C48C83") ClassP, #ClassP.foo!1, %2 : $@opened("EC6B6A86-9887-11E5-926E-685B35C48C83") ClassP : $@convention(witness_method) <τ_0_0 where τ_0_0 : ClassP> (@guaranteed τ_0_0) -> () + %7 = tuple () + return %7 : $() +} + +// We don't handle existential boxes currently. // Check that we don't crash on this. // CHECK-LABEL: CG of test_unknown_store @@ -706,16 +815,62 @@ bb0(%0 : $ErrorClass): return %4 : $() } -// CHECK-LABEL: CG of arraysemantics_is_native +// CHECK-LABEL: CG of test_raw_pointer_to_ref // CHECK-NEXT: Arg %0 Esc: A, Succ: +// CHECK-NEXT: Ret Esc: R, Succ: %0 // CHECK-NEXT: End -sil @arraysemantics_is_native : $@convention(thin) (Array) -> () { -bb0(%0 : $Array): - %f = function_ref @is_native : $@convention(method) (@guaranteed Array) -> Bool - %a = apply %f(%0) : $@convention(method) (@guaranteed Array) -> Bool +sil @test_raw_pointer_to_ref : $@convention(thin) (@owned X) -> @owned X { +bb0(%0 : $X): + %1 = ref_to_raw_pointer %0 : $X to $Builtin.RawPointer + %2 = raw_pointer_to_ref %1 : $Builtin.RawPointer to $X + return %2 : $X +} - %r = tuple() - return %r : $() +// CHECK-LABEL: CG of test_bridge_object_to_ref +// CHECK-NEXT: Arg %0 Esc: A, Succ: +// CHECK-NEXT: Ret Esc: R, Succ: %0 +// CHECK-NEXT: End +sil @test_bridge_object_to_ref : $@convention(thin) (@owned X, Builtin.Word) -> @owned X { +bb0(%0 : $X, %1 : $Builtin.Word): + %2 = ref_to_bridge_object %0 : $X, %1 : $Builtin.Word + %3 = bridge_object_to_ref %2 : $Builtin.BridgeObject to $X + return %3 : $X +} + +// CHECK-LABEL: CG of test_address_to_pointer +// CHECK-NEXT: Arg %0 Esc: A, Succ: (%0.1) +// CHECK-NEXT: Con %0.1 Esc: A, Succ: %1 +// CHECK-NEXT: Arg %1 Esc: A, Succ: +// CHECK-NEXT: End +sil @test_address_to_pointer : $@convention(thin) (@out X, @owned X) -> () { +bb0(%0 : $*X, %1 : $X): + %2 = address_to_pointer %0 : $*X to $Builtin.RawPointer + %3 = pointer_to_address %2 : $Builtin.RawPointer to $*X + store %1 to %3 : $*X + %7 = tuple () + return %7 : $() +} + +// CHECK-LABEL: CG of test_casts +// CHECK-NEXT: Arg %0 Esc: A, Succ: +// CHECK-NEXT: Ret Esc: R, Succ: %0 +// CHECK-NEXT: End +sil @test_casts : $@convention(thin) (@owned AnyObject) -> @owned X { +bb0(%0 : $AnyObject): + %1 = unchecked_ref_cast %0 : $AnyObject to $Derived + %2 = upcast %1 : $Derived to $X + return %2 : $X +} + +// CHECK-LABEL: CG of test_unchecked_ref_cast_addr +// CHECK-NEXT: Arg %0 Esc: A, Succ: %1 +// CHECK-NEXT: Arg %1 Esc: A, Succ: +// CHECK-NEXT: End +sil @test_unchecked_ref_cast_addr : $@convention(thin) (@out U, @in T, @thick U.Type) -> () { +bb0(%0 : $*U, %1 : $*T, %2 : $@thick U.Type): + unchecked_ref_cast_addr T in %1 : $*T to U in %0 : $*U + %5 = tuple () + return %5 : $() } // CHECK-LABEL: CG of arraysemantics_is_native_no_typecheck @@ -838,7 +993,6 @@ bb0(%0 : $Array): return %r : $() } -sil [_semantics "array.props.isNative"] @is_native : $@convention(method) (@guaranteed Array) -> Bool sil [_semantics "array.props.isNativeTypeChecked"] @is_native_type_checked : $@convention(method) (@guaranteed Array) -> Bool sil [_semantics "array.check_subscript"] @check_subscript : $@convention(method) (Int32, Bool, @guaranteed Array) -> () sil [_semantics "array.check_index"] @check_index : $@convention(method) (Int32, @guaranteed Array) -> () diff --git a/test/SILPasses/existential_type_propagation.sil b/test/SILOptimizer/existential_type_propagation.sil similarity index 86% rename from test/SILPasses/existential_type_propagation.sil rename to test/SILOptimizer/existential_type_propagation.sil index a897d8eece7fc..6bd7d97804375 100644 --- a/test/SILPasses/existential_type_propagation.sil +++ b/test/SILOptimizer/existential_type_propagation.sil @@ -52,23 +52,23 @@ bb0: %0 = alloc_stack $Int32 %1 = alloc_stack $ReaderWriterType // Here we set the concrete type information. - %2 = init_existential_addr %1#1 : $*ReaderWriterType, $ArrayClassReaderWriter + %2 = init_existential_addr %1 : $*ReaderWriterType, $ArrayClassReaderWriter %3 = function_ref @_TFC28existential_type_propagation22ArrayClassReaderWriterCfMS0_FT_S0_ : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter %4 = metatype $@thick ArrayClassReaderWriter.Type %5 = apply %3(%4) : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter store %5 to %2 : $*ArrayClassReaderWriter - %7 = open_existential_addr %1#1 : $*ReaderWriterType to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType - // Check that the type information reaches the witness_method instruction and allows for divirtualization. + %7 = open_existential_addr %1 : $*ReaderWriterType to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType + // Check that the type information reaches the witness_method instruction and allows for devirtualization. %8 = witness_method $@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType, #ReaderWriterType.read!1, %7 : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType : $@convention(witness_method) <τ_0_0 where τ_0_0 : ReaderWriterType> (Int32, @in_guaranteed τ_0_0) -> Int32 %9 = integer_literal $Builtin.Int32, 0 %10 = struct $Int32 (%9 : $Builtin.Int32) %11 = apply %8<@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType>(%10, %7) : $@convention(witness_method) <τ_0_0 where τ_0_0 : ReaderWriterType> (Int32, @in_guaranteed τ_0_0) -> Int32 %12 = integer_literal $Builtin.Int32, 0 %13 = struct $Int32 (%12 : $Builtin.Int32) - store %13 to %0#1 : $*Int32 - destroy_addr %1#1 : $*ReaderWriterType - dealloc_stack %1#0 : $*@local_storage ReaderWriterType - dealloc_stack %0#0 : $*@local_storage Int32 + store %13 to %0 : $*Int32 + destroy_addr %1 : $*ReaderWriterType + dealloc_stack %1 : $*ReaderWriterType + dealloc_stack %0 : $*Int32 return %13 : $Int32 } @@ -85,27 +85,27 @@ bb0: %1 = alloc_stack $ReaderWriterType %2 = alloc_stack $ReaderWriterType // Here we set the concrete type information. - %3 = init_existential_addr %1#1 : $*ReaderWriterType, $ArrayClassReaderWriter + %3 = init_existential_addr %1 : $*ReaderWriterType, $ArrayClassReaderWriter %4 = function_ref @_TFC28existential_type_propagation22ArrayClassReaderWriterCfMS0_FT_S0_ : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter %5 = metatype $@thick ArrayClassReaderWriter.Type %6 = apply %4(%5) : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter store %6 to %3 : $*ArrayClassReaderWriter // Check that the type information set for %1 is propagated here to %2. - copy_addr %1#1 to [initialization] %2#1 : $*ReaderWriterType - %9 = open_existential_addr %2#1 : $*ReaderWriterType to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType - // Check that the type information reaches the witness_method instruction and allows for divirtualization. + copy_addr %1 to [initialization] %2 : $*ReaderWriterType + %9 = open_existential_addr %2 : $*ReaderWriterType to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType + // Check that the type information reaches the witness_method instruction and allows for devirtualization. %10 = witness_method $@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType, #ReaderWriterType.read!1, %9 : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType : $@convention(witness_method) <τ_0_0 where τ_0_0 : ReaderWriterType> (Int32, @in_guaranteed τ_0_0) -> Int32 %11 = integer_literal $Builtin.Int32, 0 %12 = struct $Int32 (%11 : $Builtin.Int32) %13 = apply %10<@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType>(%12, %9) : $@convention(witness_method) <τ_0_0 where τ_0_0 : ReaderWriterType> (Int32, @in_guaranteed τ_0_0) -> Int32 %14 = integer_literal $Builtin.Int32, 0 %15 = struct $Int32 (%14 : $Builtin.Int32) - store %15 to %0#1 : $*Int32 - destroy_addr %2#1 : $*ReaderWriterType - dealloc_stack %2#0 : $*@local_storage ReaderWriterType - destroy_addr %1#1 : $*ReaderWriterType - dealloc_stack %1#0 : $*@local_storage ReaderWriterType - dealloc_stack %0#0 : $*@local_storage Int32 + store %15 to %0 : $*Int32 + destroy_addr %2 : $*ReaderWriterType + dealloc_stack %2 : $*ReaderWriterType + destroy_addr %1 : $*ReaderWriterType + dealloc_stack %1 : $*ReaderWriterType + dealloc_stack %0 : $*Int32 return %15 : $Int32 } diff --git a/test/SILPasses/external_defs_to_decls.sil b/test/SILOptimizer/external_defs_to_decls.sil similarity index 100% rename from test/SILPasses/external_defs_to_decls.sil rename to test/SILOptimizer/external_defs_to_decls.sil diff --git a/test/SILPasses/fold_enums.sil b/test/SILOptimizer/fold_enums.sil similarity index 83% rename from test/SILPasses/fold_enums.sil rename to test/SILOptimizer/fold_enums.sil index 013803bf1e426..68e91de4b7bf0 100644 --- a/test/SILPasses/fold_enums.sil +++ b/test/SILOptimizer/fold_enums.sil @@ -23,11 +23,11 @@ public enum E { // CHECK: return %0 : $Optional sil @_TF10fold_enums18recreate_optional1FGSqVs5Int32_GSqS0__ : $@convention(thin) (Optional) -> Optional { bb0(%0 : $Optional): - debug_value %0 : $Optional // let x // id: %1 + debug_value %0 : $Optional, let, name "x" // id: %1 switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: bb1, default bb2 // id: %2 bb1(%3 : $Int32): // Preds: bb0 - debug_value %3 : $Int32 // let y // id: %4 + debug_value %3 : $Int32, let, name "y" // id: %4 %5 = enum $Optional, #Optional.Some!enumelt.1, %3 : $Int32 // user: %6 br bb3(%5 : $Optional) // id: %6 @@ -71,20 +71,20 @@ bb3(%8 : $Optional): // CHECK: return %0 : $Optional sil @_TF10fold_enums18recreate_optional2FGSqVs5Int32_GSqS0__ : $@convention(thin) (Optional) -> Optional { bb0(%0 : $Optional): - debug_value %0 : $Optional // let x // id: %1 + debug_value %0 : $Optional, let, name "x" // id: %1 switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: bb1, default bb2 // id: %2 bb1(%3 : $Int32): // Preds: bb0 - debug_value %3 : $Int32 // let y // id: %4 + debug_value %3 : $Int32, let, name "y" // id: %4 %5 = enum $Optional, #Optional.Some!enumelt.1, %3 : $Int32 // user: %6 br bb3(%5 : $Optional) // id: %6 bb2: // Preds: bb0 %7 = alloc_stack $Optional // users: %8, %10, %11 - inject_enum_addr %7#1 : $*Optional, #Optional.None!enumelt // id: %8 + inject_enum_addr %7 : $*Optional, #Optional.None!enumelt // id: %8 %9 = tuple () - %10 = load %7#1 : $*Optional // user: %12 - dealloc_stack %7#0 : $*@local_storage Optional // id: %11 + %10 = load %7 : $*Optional // user: %12 + dealloc_stack %7 : $*Optional // id: %11 br bb3(%10 : $Optional) // id: %12 bb3(%13 : $Optional): // Preds: bb1 bb2 @@ -98,21 +98,21 @@ bb3(%13 : $Optional): // Preds: bb1 bb2 // CHECK: return %0 : $E sil @_TF10fold_enums13recreate_enumFOS_1ES0_ : $@convention(thin) (E) -> E { bb0(%0 : $E): - debug_value %0 : $E // let e // id: %1 + debug_value %0 : $E, let, name "e" // id: %1 switch_enum %0 : $E, case #E.C1!enumelt.1: bb1, case #E.C2!enumelt.1: bb2, case #E.C3!enumelt.1: bb3 // id: %2 bb1(%3 : $Int32): // Preds: bb0 - debug_value %3 : $Int32 // let x // id: %4 + debug_value %3 : $Int32, let, name "x" // id: %4 %5 = enum $E, #E.C1!enumelt.1, %3 : $Int32 // user: %6 br bb4(%5 : $E) // id: %6 bb2(%7 : $Int32): // Preds: bb0 - debug_value %7 : $Int32 // let x // id: %8 + debug_value %7 : $Int32, let, name "x" // id: %8 %9 = enum $E, #E.C2!enumelt.1, %7 : $Int32 // user: %10 br bb4(%9 : $E) // id: %10 bb3(%11 : $Int32): // Preds: bb0 - debug_value %11 : $Int32 // let x // id: %12 + debug_value %11 : $Int32, let, name "x" // id: %12 %13 = enum $E, #E.C3!enumelt.1, %11 : $Int32 // user: %14 br bb4(%13 : $E) // id: %14 @@ -129,21 +129,21 @@ bb4(%15 : $E): // Preds: bb1 bb2 bb3 // CHECK: return sil @_TF10fold_enums26create_different_enum_caseFOS_1ES0_ : $@convention(thin) (E) -> E { bb0(%0 : $E): - debug_value %0 : $E // let e // id: %1 + debug_value %0 : $E, let, name "e" // id: %1 switch_enum %0 : $E, case #E.C1!enumelt.1: bb1, case #E.C2!enumelt.1: bb2, case #E.C3!enumelt.1: bb3 // id: %2 bb1(%3 : $Int32): // Preds: bb0 - debug_value %3 : $Int32 // let x // id: %4 + debug_value %3 : $Int32, let, name "x" // id: %4 %5 = enum $E, #E.C2!enumelt.1, %3 : $Int32 // user: %6 br bb4(%5 : $E) // id: %6 bb2(%7 : $Int32): // Preds: bb0 - debug_value %7 : $Int32 // let x // id: %8 + debug_value %7 : $Int32, let, name "x" // id: %8 %9 = enum $E, #E.C3!enumelt.1, %7 : $Int32 // user: %10 br bb4(%9 : $E) // id: %10 bb3(%11 : $Int32): // Preds: bb0 - debug_value %11 : $Int32 // let x // id: %12 + debug_value %11 : $Int32, let, name "x" // id: %12 %13 = enum $E, #E.C1!enumelt.1, %11 : $Int32 // user: %14 br bb4(%13 : $E) // id: %14 @@ -163,15 +163,15 @@ public enum F { // CHECK: return %0 : $F sil @_TF10fold_enums13recreate_enumFOS_1FS0_ : $@convention(thin) (@owned F) -> @owned F { bb0(%0 : $F): - debug_value %0 : $F // let e // id: %1 + debug_value %0 : $F, let, name "e" // id: %1 retain_value %0 : $F // id: %2 switch_enum %0 : $F, case #F.F1!enumelt.1: bb1, case #F.F2!enumelt.1: bb2, case #F.F3!enumelt.1: bb3 // id: %3 bb1(%4 : $(Int32, Int32)): // Preds: bb0 %5 = tuple_extract %4 : $(Int32, Int32), 0 // users: %7, %9 %6 = tuple_extract %4 : $(Int32, Int32), 1 // users: %8, %9 - debug_value %5 : $Int32 // let x // id: %7 - debug_value %6 : $Int32 // let y // id: %8 + debug_value %5 : $Int32, let, name "x" // id: %7 + debug_value %6 : $Int32, let, name "y" // id: %8 %9 = tuple (%5 : $Int32, %6 : $Int32) // user: %10 %10 = enum $F, #F.F1!enumelt.1, %9 : $(Int32, Int32) // user: %11 br bb4(%10 : $F) // id: %11 @@ -179,8 +179,8 @@ bb1(%4 : $(Int32, Int32)): // Preds: bb0 bb2(%12 : $(Int32, String)): // Preds: bb0 %13 = tuple_extract %12 : $(Int32, String), 0 // users: %15, %18 %14 = tuple_extract %12 : $(Int32, String), 1 // users: %16, %17, %18, %20 - debug_value %13 : $Int32 // let x // id: %15 - debug_value %14 : $String // let y // id: %16 + debug_value %13 : $Int32, let, name "x" // id: %15 + debug_value %14 : $String, let, name "y" // id: %16 retain_value %14 : $String // id: %17 %18 = tuple (%13 : $Int32, %14 : $String) // user: %19 %19 = enum $F, #F.F2!enumelt.1, %18 : $(Int32, String) // user: %21 @@ -191,9 +191,9 @@ bb3(%22 : $(Float, Float, Float)): // Preds: bb0 %23 = tuple_extract %22 : $(Float, Float, Float), 0 // users: %26, %29 %24 = tuple_extract %22 : $(Float, Float, Float), 1 // users: %27, %29 %25 = tuple_extract %22 : $(Float, Float, Float), 2 // users: %28, %29 - debug_value %23 : $Float // let x // id: %26 - debug_value %24 : $Float // let y // id: %27 - debug_value %25 : $Float // let z // id: %28 + debug_value %23 : $Float, let, name "x" // id: %26 + debug_value %24 : $Float, let, name "y" // id: %27 + debug_value %25 : $Float, let, name "z" // id: %28 %29 = tuple (%23 : $Float, %24 : $Float, %25 : $Float) // user: %30 %30 = enum $F, #F.F3!enumelt.1, %29 : $(Float, Float, Float) // user: %31 br bb4(%30 : $F) // id: %31 diff --git a/test/SILAnalysis/function-order.sil b/test/SILOptimizer/function-order.sil similarity index 100% rename from test/SILAnalysis/function-order.sil rename to test/SILOptimizer/function-order.sil diff --git a/test/SILPasses/functionsigopts.sil b/test/SILOptimizer/functionsigopts.sil similarity index 99% rename from test/SILPasses/functionsigopts.sil rename to test/SILOptimizer/functionsigopts.sil index 4facf2cbf77ce..1e62f02ab1ed9 100644 --- a/test/SILPasses/functionsigopts.sil +++ b/test/SILOptimizer/functionsigopts.sil @@ -256,7 +256,7 @@ bb2: return %2 : $() } -// In this case the release is not in the exit, so we can not specialize. +// In this case the release is not in the exit, so we cannot specialize. // CHECK-LABEL: sil [fragile] @owned_to_guaranteed_multibb_callee_with_release_not_in_exit : $@convention(thin) (@owned Builtin.NativeObject) -> () { // CHECK-NOT: @guaranteed sil [fragile] @owned_to_guaranteed_multibb_callee_with_release_not_in_exit : $@convention(thin) (@owned Builtin.NativeObject) -> () { diff --git a/test/SILPasses/functionsigopts_self.swift b/test/SILOptimizer/functionsigopts_self.swift similarity index 100% rename from test/SILPasses/functionsigopts_self.swift rename to test/SILOptimizer/functionsigopts_self.swift diff --git a/test/SILPasses/functionsigopts_sroa.sil b/test/SILOptimizer/functionsigopts_sroa.sil similarity index 99% rename from test/SILPasses/functionsigopts_sroa.sil rename to test/SILOptimizer/functionsigopts_sroa.sil index 4e72aa3baf427..29e1da9b2925a 100644 --- a/test/SILPasses/functionsigopts_sroa.sil +++ b/test/SILOptimizer/functionsigopts_sroa.sil @@ -188,7 +188,7 @@ bb0(%0 : $S1): return %9999 : $() } -// This test checks where we have a multiple level heirarchy, the root is dead, +// This test checks where we have a multiple level hierarchy, the root is dead, // but the root has all fields used. This means that we should extract // everything, but we should not "reform" the aggregate. // CHECK-LABEL: sil [fragile] [thunk] @multiple_level_all_root_fields_used_callee : $@convention(thin) (S2) -> (Builtin.Int16, Builtin.Int64) { @@ -563,7 +563,7 @@ bb0(%0 : $*S1): // (including each subtype's field in that count). This fixes a bug where we // were not handling the possibility of an std::vector resize invalidated // references. This cause the this pointer to become invalidated and other -// schinanigans. So just make sure we don't crash +// shenanigans. So just make sure we don't crash // CHECK-LABEL: sil [fragile] @more_than_32_type_sized_caller : $@convention(thin) (ThirtySixFieldStruct) -> () { sil [fragile] @more_than_32_type_sized_caller : $@convention(thin) (ThirtySixFieldStruct) -> () { bb0(%0 : $ThirtySixFieldStruct): diff --git a/test/SILPasses/global_lsopts_crash.sil b/test/SILOptimizer/global_lsopts_crash.sil similarity index 100% rename from test/SILPasses/global_lsopts_crash.sil rename to test/SILOptimizer/global_lsopts_crash.sil diff --git a/test/SILPasses/global_property_opt.sil b/test/SILOptimizer/global_property_opt.sil similarity index 96% rename from test/SILPasses/global_property_opt.sil rename to test/SILOptimizer/global_property_opt.sil index 8c38727765981..c778320f9f885 100644 --- a/test/SILPasses/global_property_opt.sil +++ b/test/SILOptimizer/global_property_opt.sil @@ -42,15 +42,15 @@ bb0: %1 = alloc_stack $Array %3 = function_ref @_array_X_init : $@convention(thin) () -> @owned Array %4 = apply %3() : $@convention(thin) () -> @owned Array - store %4 to %1#1 : $*Array + store %4 to %1 : $*Array %m1 = function_ref @_array_X_mutate : $@convention(method) (@inout Array) -> () - %m2 = apply %m1(%1#1) : $@convention(method) (@inout Array) -> () + %m2 = apply %m1(%1) : $@convention(method) (@inout Array) -> () - %5 = load %1#1 : $*Array + %5 = load %1 : $*Array %6 = function_ref @_is_native_X_no_type_check : $@convention(method) (@guaranteed Array) -> Bool %10 = apply %6(%5) : $@convention(method) (@guaranteed Array) -> Bool - dealloc_stack %1#0 : $*@local_storage Array + dealloc_stack %1 : $*Array return %10 : $Bool } @@ -63,15 +63,15 @@ bb0: %1 = alloc_stack $Array %3 = function_ref @_array_X_init : $@convention(thin) () -> @owned Array %4 = apply %3() : $@convention(thin) () -> @owned Array - store %4 to %1#1 : $*Array + store %4 to %1 : $*Array %m1 = function_ref @_take_array_addr : $@convention(method) (@inout Array) -> () - %m2 = apply %m1(%1#1) : $@convention(method) (@inout Array) -> () + %m2 = apply %m1(%1) : $@convention(method) (@inout Array) -> () - %5 = load %1#1 : $*Array + %5 = load %1 : $*Array %6 = function_ref @_is_native_X_no_type_check : $@convention(method) (@guaranteed Array) -> Bool %10 = apply %6(%5) : $@convention(method) (@guaranteed Array) -> Bool - dealloc_stack %1#0 : $*@local_storage Array + dealloc_stack %1 : $*Array return %10 : $Bool } @@ -84,14 +84,14 @@ bb0(%0 : $Array): %1 = alloc_stack $Array %3 = function_ref @_array_X_init : $@convention(thin) () -> @owned Array %4 = apply %3() : $@convention(thin) () -> @owned Array - store %4 to %1#1 : $*Array + store %4 to %1 : $*Array - store %0 to %1#1 : $*Array + store %0 to %1 : $*Array - %5 = load %1#1 : $*Array + %5 = load %1 : $*Array %6 = function_ref @_is_native_X_no_type_check : $@convention(method) (@guaranteed Array) -> Bool %10 = apply %6(%5) : $@convention(method) (@guaranteed Array) -> Bool - dealloc_stack %1#0 : $*@local_storage Array + dealloc_stack %1 : $*Array return %10 : $Bool } @@ -196,15 +196,15 @@ bb0: sil @test_tuple_member_escapes : $@convention(thin) () -> Bool { bb0: %s1 = alloc_stack $(Array, Builtin.Int64) - %a1 = tuple_element_addr %s1#1 : $*(Array, Builtin.Int64), 0 + %a1 = tuple_element_addr %s1 : $*(Array, Builtin.Int64), 0 %f1 = function_ref @_take_array_addr : $@convention(method) (@inout Array) -> () %x1 = apply %f1(%a1) : $@convention(method) (@inout Array) -> () - %t1 = load %s1#1 : $*(Array, Builtin.Int64) + %t1 = load %s1 : $*(Array, Builtin.Int64) %a2 = tuple_extract %t1 : $(Array, Builtin.Int64), 0 %f2 = function_ref @_is_native_X_no_type_check : $@convention(method) (@guaranteed Array) -> Bool %r1 = apply %f2(%a2) : $@convention(method) (@guaranteed Array) -> Bool - dealloc_stack %s1#0 : $*@local_storage (Array, Builtin.Int64) + dealloc_stack %s1 : $*(Array, Builtin.Int64) return %r1 : $Bool } diff --git a/test/SILPasses/global_property_opt_objc.sil b/test/SILOptimizer/global_property_opt_objc.sil similarity index 90% rename from test/SILPasses/global_property_opt_objc.sil rename to test/SILOptimizer/global_property_opt_objc.sil index 743c939be5c65..c74fb16568ce8 100644 --- a/test/SILPasses/global_property_opt_objc.sil +++ b/test/SILOptimizer/global_property_opt_objc.sil @@ -33,15 +33,15 @@ bb0(%0 : $_ArrayBuffer): %1 = alloc_stack $Array %3 = function_ref @_array_X_init : $@convention(thin) () -> @owned Array %4 = apply %3() : $@convention(thin) () -> @owned Array - store %4 to %1#1 : $*Array + store %4 to %1 : $*Array - %b1 = struct_element_addr %1#1 : $*Array, #Array._buffer + %b1 = struct_element_addr %1 : $*Array, #Array._buffer store %0 to %b1 : $*_ArrayBuffer - %5 = load %1#1 : $*Array + %5 = load %1 : $*Array %6 = function_ref @_is_native_X_no_type_check : $@convention(method) (@guaranteed Array) -> Bool %10 = apply %6(%5) : $@convention(method) (@guaranteed Array) -> Bool - dealloc_stack %1#0 : $*@local_storage Array + dealloc_stack %1 : $*Array return %10 : $Bool } diff --git a/test/SILPasses/globalloadstoreopts_self_cycle_bug.sil b/test/SILOptimizer/globalloadstoreopts_self_cycle_bug.sil similarity index 100% rename from test/SILPasses/globalloadstoreopts_self_cycle_bug.sil rename to test/SILOptimizer/globalloadstoreopts_self_cycle_bug.sil diff --git a/test/SILPasses/globalopt.sil b/test/SILOptimizer/globalopt.sil similarity index 97% rename from test/SILPasses/globalopt.sil rename to test/SILOptimizer/globalopt.sil index f4855e5d1205d..f5051df22dd80 100644 --- a/test/SILPasses/globalopt.sil +++ b/test/SILOptimizer/globalopt.sil @@ -97,7 +97,7 @@ bb2: // Preds: bb1 bb3(%17 : $Builtin.Int32, %18 : $Optional): // Preds: bb2 bb4 %19 = alloc_stack $Optional // users: %20, %26, %27, %40 - store %18 to %19#1 : $*Optional // id: %20 + store %18 to %19 : $*Optional // id: %20 switch_enum %18 : $Optional, case #Optional.Some!enumelt.1: bb5, case #Optional.None!enumelt: bb6 // id: %21 bb4: // Preds: bb1 @@ -107,12 +107,12 @@ bb4: // Preds: bb1 br bb3(%23 : $Builtin.Int32, %24 : $Optional) // id: %25 bb5: // Preds: bb3 - %26 = unchecked_take_enum_data_addr %19#1 : $*Optional, #Optional.Some!enumelt.1 - dealloc_stack %19#0 : $*@local_storage Optional // id: %27 + %26 = unchecked_take_enum_data_addr %19 : $*Optional, #Optional.Some!enumelt.1 + dealloc_stack %19 : $*Optional // id: %27 %28 = alloc_stack $Optional // users: %29, %30, %31 - store %18 to %28#1 : $*Optional // id: %29 - %30 = unchecked_take_enum_data_addr %28#1 : $*Optional, #Optional.Some!enumelt.1 - dealloc_stack %28#0 : $*@local_storage Optional // id: %31 + store %18 to %28 : $*Optional // id: %29 + %30 = unchecked_take_enum_data_addr %28 : $*Optional, #Optional.Some!enumelt.1 + dealloc_stack %28 : $*Optional // id: %31 // function_ref ginit.MyConst.mutableAddressor : Swift.Int32 %32 = function_ref @_TF5ginita7MyConstSi : $@convention(thin) () -> Builtin.RawPointer // user: %33 %33 = apply %32() : $@convention(thin) () -> Builtin.RawPointer // user: %34 @@ -124,7 +124,7 @@ bb5: // Preds: bb3 br bb1(%38 : $Builtin.Int32, %17 : $Builtin.Int32) // id: %39 bb6: // Preds: bb3 - dealloc_stack %19#0 : $*@local_storage Optional // id: %40 + dealloc_stack %19 : $*Optional // id: %40 %41 = struct $Int32 (%9 : $Builtin.Int32) // user: %42 return %41 : $Int32 // id: %42 } diff --git a/test/SILPasses/globalopt_global_propagation.swift b/test/SILOptimizer/globalopt_global_propagation.swift similarity index 100% rename from test/SILPasses/globalopt_global_propagation.swift rename to test/SILOptimizer/globalopt_global_propagation.swift diff --git a/test/SILPasses/globalopt_let_propagation.swift b/test/SILOptimizer/globalopt_let_propagation.swift similarity index 100% rename from test/SILPasses/globalopt_let_propagation.swift rename to test/SILOptimizer/globalopt_let_propagation.swift diff --git a/test/SILPasses/globalredundantloadelimination.sil b/test/SILOptimizer/globalredundantloadelimination.sil similarity index 82% rename from test/SILPasses/globalredundantloadelimination.sil rename to test/SILOptimizer/globalredundantloadelimination.sil index ddb745ef4de39..e3f8e9d4f3249 100644 --- a/test/SILPasses/globalredundantloadelimination.sil +++ b/test/SILOptimizer/globalredundantloadelimination.sil @@ -77,23 +77,23 @@ bb0(%0 : $B, %1 : $*Agg1): // CHECK-NEXT: [[ALLOCA:%[0-9]+]] = alloc_stack $Builtin.Int32 // CHECK-NEXT: [[INT_LITERAL:%[0-9]+]] = integer_literal // CHECK-NEXT: [[INT_LOADED:%[0-9]+]] = load [[INPUT_PTR1]] : $*Builtin.Int32 -// CHECK-NEXT: store [[INT_LITERAL]] to [[ALLOCA]]#1 : $*Builtin.Int32 +// CHECK-NEXT: store [[INT_LITERAL]] to [[ALLOCA]] : $*Builtin.Int32 // CHECK-NEXT: store [[INT_LITERAL]] to [[INPUT_PTR2]] : $*Builtin.Int32 -// CHECK-NEXT: dealloc_stack [[ALLOCA]]#0 +// CHECK-NEXT: dealloc_stack [[ALLOCA]] // CHECK-NEXT: tuple ([[INT_LOADED]] : $Builtin.Int32, [[INT_LOADED]] : $Builtin.Int32, [[INT_LITERAL]] : $Builtin.Int32) // CHECK-NEXT: return sil @dead_store_removal_not_stopped_by_nonaliasing_readwrites : $@convention(thin) (@inout Builtin.Int32, @inout Builtin.Int32) -> (Builtin.Int32, Builtin.Int32, Builtin.Int32) { bb0(%0 : $*Builtin.Int32, %1 : $*Builtin.Int32): %2 = alloc_stack $Builtin.Int32 %3 = integer_literal $Builtin.Int32, 32 - store %3 to %2#1 : $*Builtin.Int32 + store %3 to %2 : $*Builtin.Int32 %4 = load %0 : $*Builtin.Int32 store %3 to %1 : $*Builtin.Int32 - store %3 to %2#1 : $*Builtin.Int32 + store %3 to %2 : $*Builtin.Int32 %5 = load %0 : $*Builtin.Int32 store %3 to %1 : $*Builtin.Int32 - %6 = load %2#1 : $*Builtin.Int32 - dealloc_stack %2#0 : $*@local_storage Builtin.Int32 + %6 = load %2 : $*Builtin.Int32 + dealloc_stack %2 : $*Builtin.Int32 %7 = tuple(%4 : $Builtin.Int32, %5 : $Builtin.Int32, %6 : $Builtin.Int32) return %7 : $(Builtin.Int32, Builtin.Int32, Builtin.Int32) } @@ -104,31 +104,31 @@ bb0(%0 : $*Builtin.Int32, %1 : $*Builtin.Int32): // CHECK-NEXT: [[LOCAL:%[0-9]+]] = alloc_stack // CHECK: unchecked_trivial_bit_cast [[INPUT]] : $Optional to $Builtin.Int32 // CHECK: unchecked_trivial_bit_cast [[INPUT]] : $Optional to $A -// CHECK: unchecked_addr_cast [[LOCAL]]#1 : $*Optional to $*Builtin.RawPointer -// CHECK: unchecked_addr_cast [[LOCAL]]#1 : $*Optional to $*Builtin.NativeObject +// CHECK: unchecked_addr_cast [[LOCAL]] : $*Optional to $*Builtin.RawPointer +// CHECK: unchecked_addr_cast [[LOCAL]] : $*Optional to $*Builtin.NativeObject // CHECK: unchecked_trivial_bit_cast [[INPUT]] : $Optional to $Optional -// CHECK: unchecked_addr_cast [[LOCAL]]#1 : $*Optional to $*Optional -// CHECK: unchecked_addr_cast [[LOCAL]]#1 : $*Optional to $*Optional +// CHECK: unchecked_addr_cast [[LOCAL]] : $*Optional to $*Optional +// CHECK: unchecked_addr_cast [[LOCAL]] : $*Optional to $*Optional // CHECK: return sil @store_to_load_forward_unchecked_addr_cast_struct : $@convention(thin) (Optional) -> () { bb0(%0 : $Optional): %1 = alloc_stack $Optional - store %0 to %1#1 : $*Optional - %2 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.Int32 + store %0 to %1 : $*Optional + %2 = unchecked_addr_cast %1 : $*Optional to $*Builtin.Int32 %3 = load %2 : $*Builtin.Int32 - %4 = unchecked_addr_cast %1#1 : $*Optional to $*A + %4 = unchecked_addr_cast %1 : $*Optional to $*A %5 = load %4 : $*A - %6 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.RawPointer + %6 = unchecked_addr_cast %1 : $*Optional to $*Builtin.RawPointer %7 = load %6 : $*Builtin.RawPointer - %8 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.NativeObject + %8 = unchecked_addr_cast %1 : $*Optional to $*Builtin.NativeObject %9 = load %8 : $*Builtin.NativeObject - %10 = unchecked_addr_cast %1#1 : $*Optional to $*Optional + %10 = unchecked_addr_cast %1 : $*Optional to $*Optional %11 = load %10 : $*Optional - %12 = unchecked_addr_cast %1#1 : $*Optional to $*Optional + %12 = unchecked_addr_cast %1 : $*Optional to $*Optional %13 = load %12 : $*Optional - %14 = unchecked_addr_cast %1#1 : $*Optional to $*Optional + %14 = unchecked_addr_cast %1 : $*Optional to $*Optional %15 = load %14 : $*Optional - dealloc_stack %1#0 : $*@local_storage Optional + dealloc_stack %1 : $*Optional %9999 = tuple() return %9999 : $() } @@ -157,7 +157,7 @@ bb0(%0 : $*IntPtr): store %3 to %2 : $*Builtin.Int32 %5 = unchecked_addr_cast %2 : $*Builtin.Int32 to $*IntPtr %6 = load %5 : $*IntPtr - dealloc_stack %1#0 : $*@local_storage Builtin.Int32 + dealloc_stack %1 : $*Builtin.Int32 %9999 = tuple() return %9999 : $() } @@ -181,22 +181,22 @@ bb0(%0 : $*IntPtr): sil @store_to_load_forward_unchecked_addr_cast_class : $@convention(thin) (Optional) -> () { bb0(%0 : $Optional): %1 = alloc_stack $Optional - store %0 to %1#1 : $*Optional - %2 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.Int32 + store %0 to %1 : $*Optional + %2 = unchecked_addr_cast %1 : $*Optional to $*Builtin.Int32 %3 = load %2 : $*Builtin.Int32 - %4 = unchecked_addr_cast %1#1 : $*Optional to $*B + %4 = unchecked_addr_cast %1 : $*Optional to $*B %5 = load %4 : $*B - %6 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.RawPointer + %6 = unchecked_addr_cast %1 : $*Optional to $*Builtin.RawPointer %7 = load %6 : $*Builtin.RawPointer - %8 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.NativeObject + %8 = unchecked_addr_cast %1 : $*Optional to $*Builtin.NativeObject %9 = load %8 : $*Builtin.NativeObject - %10 = unchecked_addr_cast %1#1 : $*Optional to $*Optional + %10 = unchecked_addr_cast %1 : $*Optional to $*Optional %11 = load %10 : $*Optional - %12 = unchecked_addr_cast %1#1 : $*Optional to $*Optional + %12 = unchecked_addr_cast %1 : $*Optional to $*Optional %13 = load %12 : $*Optional - %14 = unchecked_addr_cast %1#1 : $*Optional to $*Optional + %14 = unchecked_addr_cast %1 : $*Optional to $*Optional %15 = load %14 : $*Optional - dealloc_stack %1#0 : $*@local_storage Optional + dealloc_stack %1 : $*Optional %9999 = tuple() return %9999 : $() } @@ -274,10 +274,10 @@ bb0(%0 : $*Optional): sil @store_to_load_forward_unchecked_addr_cast_different_sized_struct : $@convention(thin) (C) -> () { bb0(%0 : $C): %1 = alloc_stack $C - store %0 to %1#1 : $*C - %2 = unchecked_addr_cast %1#1 : $*C to $*A + store %0 to %1 : $*C + %2 = unchecked_addr_cast %1 : $*C to $*A %3 = load %2 : $*A - dealloc_stack %1#0 : $*@local_storage C + dealloc_stack %1 : $*C %9999 = tuple() return %9999 : $() } @@ -295,7 +295,7 @@ bb0(%0 : $C): // CHECK: [[EXT_LOAD_INPUT:%.*]] = struct_extract [[LOAD_INPUT]] : $AA, #AA.i // CHECK: apply [[USE_FUN]]([[EXT_LOAD_INPUT]]) // CHECK: [[ALLOC_STACK:%.*]] = alloc_stack $AA -// CHECK: [[STACK_GEP1:%.*]] = struct_element_addr [[ALLOC_STACK]]#1 : $*AA, #AA.a +// CHECK: [[STACK_GEP1:%.*]] = struct_element_addr [[ALLOC_STACK]] : $*AA, #AA.a // CHECK: [[STACK_GEP2:%.*]] = struct_element_addr [[STACK_GEP1]] : $*A, #A.i // CHECK: [[LOAD_STACK_GEP2:%.*]] = load [[STACK_GEP2]] // CHECK: apply [[USE_FUN]]([[LOAD_STACK_GEP2]]) @@ -318,18 +318,18 @@ bb0(%0 : $*AA): %9 = alloc_stack $AA - %10 = struct_element_addr %9#1 : $*AA, #AA.a + %10 = struct_element_addr %9 : $*AA, #AA.a %11 = struct_element_addr %10 : $*A, #A.i %12 = load %11 : $*Builtin.Int32 - %13 = load %9#1 : $*AA + %13 = load %9 : $*AA %14 = struct_extract %13 : $AA, #AA.a %15 = struct_extract %14 : $A, #A.i apply %7(%12) : $@convention(thin) (Builtin.Int32) -> () apply %7(%15) : $@convention(thin) (Builtin.Int32) -> () - dealloc_stack %9#0 : $*@local_storage AA + dealloc_stack %9 : $*AA %9999 = tuple() return %9999 : $() @@ -346,17 +346,17 @@ bb0(%0 : $C, %1 : $C): cond_br undef, bb1, bb2 bb1: - store %0 to %2#1 : $*C + store %0 to %2 : $*C br bb3 bb2: - store %0 to %2#1 : $*C + store %0 to %2 : $*C br bb3 bb3: - %3 = unchecked_addr_cast %2#1 : $*C to $*A + %3 = unchecked_addr_cast %2 : $*C to $*A %4 = load %3 : $*A - dealloc_stack %2#0 : $*@local_storage C + dealloc_stack %2 : $*C %9999 = tuple() return %9999 : $() } @@ -366,24 +366,24 @@ bb3: // CHECK: [[ALLOC:%.*]] = alloc_stack $A // CHECK: [[CONST0:%.*]] = integer_literal $Builtin.Int32, 0 // CHECK: [[STRUCT:%.*]] = struct $A ([[CONST0]] : $Builtin.Int32) -// CHECK: store [[STRUCT]] to [[ALLOC]]#1 : $*A -// CHECK: [[STRUCTADDR:%.*]] = struct_element_addr [[ALLOC]]#1 : $*A, #A.i +// CHECK: store [[STRUCT]] to [[ALLOC]] : $*A +// CHECK: [[STRUCTADDR:%.*]] = struct_element_addr [[ALLOC]] : $*A, #A.i // CHECK: [[CONST1:%.*]] = integer_literal $Builtin.Int32, 1 // CHECK: store [[CONST1]] to [[STRUCTADDR]] : $*Builtin.Int32 -// CHECK: [[LD:%.*]] = load [[ALLOC]]#1 : $*A +// CHECK: [[LD:%.*]] = load [[ALLOC]] : $*A // CHECK: store [[LD]] to %0 : $*A sil @aliasing_store : $@convention(thin) (@inout A) -> () { bb0(%0: $*A): %1 = alloc_stack $A %2 = integer_literal $Builtin.Int32, 0 %3 = struct $A (%2 : $Builtin.Int32) - store %3 to %1#1 : $*A - %4 = struct_element_addr %1#1 : $*A, #A.i + store %3 to %1 : $*A + %4 = struct_element_addr %1 : $*A, #A.i %5 = integer_literal $Builtin.Int32, 1 store %5 to %4 : $*Builtin.Int32 - %6 = load %1#1 : $*A + %6 = load %1 : $*A store %6 to %0: $*A - dealloc_stack %1#0 : $*@local_storage A + dealloc_stack %1 : $*A %7 = tuple() return %7 : $() } @@ -406,10 +406,10 @@ bb0: %0 = alloc_stack $Optional %1 = integer_literal $Builtin.Int32, 0 %2 = enum $Optional, #Optional.Some!enumelt.1, %1 : $Builtin.Int32 - %3 = load %0#1 : $*Optional - store %3 to %0#1 : $*Optional - %5 = unchecked_take_enum_data_addr %0#1 : $*Optional, #Optional.Some!enumelt.1 - dealloc_stack %0#0 : $*@local_storage Optional + %3 = load %0 : $*Optional + store %3 to %0 : $*Optional + %5 = unchecked_take_enum_data_addr %0 : $*Optional, #Optional.Some!enumelt.1 + dealloc_stack %0 : $*Optional %9999 = tuple() return %9999 : $() } @@ -431,8 +431,8 @@ bb0(%0 : $Optional): // CHECK: bb1([[ARG:%.*]] : ${{.*}}): bb1(%3 : $HoldsRef): -// CHECK: store [[ARG]] to [[LOC]]#1 - store %3 to %1#1 : $*HoldsRef +// CHECK: store [[ARG]] to [[LOC]] + store %3 to %1 : $*HoldsRef // CHECK-NOT: br bb3( br bb3 @@ -441,8 +441,8 @@ bb2: %6 = alloc_ref $Empty // CHECK: [[STRUCT:%.*]] = struct %7 = struct $HoldsRef (%6 : $Empty) -// CHECK: store [[STRUCT]] to [[LOC]]#1 - store %7 to %1#1 : $*HoldsRef +// CHECK: store [[STRUCT]] to [[LOC]] + store %7 to %1 : $*HoldsRef // CHECK-NOT: br bb3( br bb3 @@ -452,16 +452,16 @@ bb3: // CHECK: [[FNREF:%.*]] = function_ref %10 = function_ref @mutator : $@convention(method) (@inout HoldsRef) -> () retain_value %0 : $Optional -// CHECK: apply [[FNREF]]([[LOC]]#1) - %12 = apply %10(%1#1) : $@convention(method) (@inout HoldsRef) -> () -// CHECK: [[ELEM:%.*]] = struct_element_addr [[LOC]]#1 - %13 = struct_element_addr %1#1 : $*HoldsRef, #HoldsRef.c +// CHECK: apply [[FNREF]]([[LOC]]) + %12 = apply %10(%1) : $@convention(method) (@inout HoldsRef) -> () +// CHECK: [[ELEM:%.*]] = struct_element_addr [[LOC]] + %13 = struct_element_addr %1 : $*HoldsRef, #HoldsRef.c // CHECK: [[REF:%.*]] = load [[ELEM]] %14 = load %13 : $*Empty // CHECK: strong_release [[REF]] strong_release %14 : $Empty %16 = tuple () - dealloc_stack %1#0 : $*@local_storage HoldsRef + dealloc_stack %1 : $*HoldsRef return %16 : $() } @@ -473,9 +473,9 @@ bb3: // CHECK: bb0([[ARG1:%.*]] : $D, [[ARG2:%.*]] : $D): // CHECK-NEXT: [[BOX1:%.*]] = alloc_stack $D // CHECK-NEXT: [[BOX2:%.*]] = alloc_stack $D -// CHECK-NEXT: store [[ARG2]] to [[BOX2]]#1 : $*D +// CHECK-NEXT: store [[ARG2]] to [[BOX2]] : $*D // CHECK-NEXT: [[RESULT:%.*]] = unchecked_trivial_bit_cast [[ARG2]] -// CHECK-NEXT: store [[ARG2]] to [[BOX1]]#1 : $*D +// CHECK-NEXT: store [[ARG2]] to [[BOX1]] : $*D // CHECK-NEXT: dealloc_stack // CHECK-NEXT: dealloc_stack // CHECK-NEXT: return [[RESULT]] @@ -483,13 +483,13 @@ sil @test_unchecked_addr_cast_3 : $@convention(thin) (D, D) -> Builtin.RawPointe bb0(%x : $D, %y : $D): %1 = alloc_stack $D %2 = alloc_stack $D - store %x to %1#1 : $*D - store %y to %2#1 : $*D - %3 = unchecked_addr_cast %2#1 : $*D to $*Builtin.RawPointer + store %x to %1 : $*D + store %y to %2 : $*D + %3 = unchecked_addr_cast %2 : $*D to $*Builtin.RawPointer %l1 = load %3 : $*Builtin.RawPointer - store %y to %1#1 : $*D - dealloc_stack %2#0 : $*@local_storage D - dealloc_stack %1#0 : $*@local_storage D + store %y to %1 : $*D + dealloc_stack %2 : $*D + dealloc_stack %1 : $*D return %l1 : $Builtin.RawPointer } @@ -510,7 +510,7 @@ typealias I32 = Builtin.Int32 // CHECK: tuple_extract %{{.*}} : $(Builtin.Int32, Builtin.Int32), 0 // CHECK: unchecked_trivial_bit_cast %{{.*}} : $(Builtin.Int32, Builtin.Int32, Builtin.Int32) to $(Builtin.Int32, Builtin.Int32) // CHECK: tuple_extract %{{.*}} : $(Builtin.Int32, Builtin.Int32), 1 -// CHECK: dealloc_stack %{{.*}}#0 : $*@local_storage (Builtin.Int32, Builtin.Int32, Builtin.Int32) +// CHECK: dealloc_stack %{{.*}}#0 : $*(Builtin.Int32, Builtin.Int32, Builtin.Int32) // CHECK: load %1 : $*((Builtin.Int32, Builtin.Int32), Builtin.Int32) // CHECK: alloc_stack $((Builtin.Int32, Builtin.Int32), Builtin.Int32) // CHECK: store %{{.*}} to %{{.*}}#1 : $*((Builtin.Int32, Builtin.Int32), Builtin.Int32) @@ -518,7 +518,7 @@ typealias I32 = Builtin.Int32 // CHECK: tuple_extract %{{.*}} : $(Builtin.Int32, Builtin.Int32), 0 // CHECK: unchecked_trivial_bit_cast %{{.*}} : $((Builtin.Int32, Builtin.Int32), Builtin.Int32) to $(Builtin.Int32, Builtin.Int32) // CHECK: tuple_extract %{{.*}} : $(Builtin.Int32, Builtin.Int32), 1 -// CHECK: dealloc_stack %{{.*}}#0 : $*@local_storage ((Builtin.Int32, Builtin.Int32), Builtin.Int32) +// CHECK: dealloc_stack %{{.*}}#0 : $*((Builtin.Int32, Builtin.Int32), Builtin.Int32) // CHECK: alloc_stack $((Builtin.Int32, Builtin.Int32), Builtin.Int32) // CHECK: store %{{.*}} to %{{.*}}#1 : $*((Builtin.Int32, Builtin.Int32), Builtin.Int32) // CHECK: unchecked_addr_cast %{{.*}}#1 : $*((Builtin.Int32, Builtin.Int32), Builtin.Int32) to $*(Builtin.Int32, Builtin.Int32, Builtin.Int32) @@ -528,38 +528,38 @@ typealias I32 = Builtin.Int32 // CHECK: load %{{.*}} : $*Builtin.Int32 // CHECK: load %{{.*}} : $*Builtin.Int32 // CHECK: load %{{.*}} : $*Builtin.Int32 -// CHECK: dealloc_stack %{{.*}}#0 : $*@local_storage ((Builtin.Int32, Builtin.Int32), Builtin.Int32) +// CHECK: dealloc_stack %{{.*}}#0 : $*((Builtin.Int32, Builtin.Int32), Builtin.Int32) // CHECK: return %{{.*}} : $((Builtin.Int32, Builtin.Int32), (Builtin.Int32, Builtin.Int32), (Builtin.Int32, Builtin.Int32, Builtin.Int32)) sil @unchecked_addr_cast_tuple_promote : $@convention(thin) (@inout (I32, I32, I32), @inout ((I32, I32), I32)) -> ((I32, I32), (I32, I32), (I32, I32, I32)) { bb0(%0 : $*(I32, I32, I32), %1 : $*((I32, I32), I32)): %2 = load %0 : $*(I32, I32, I32) %3 = alloc_stack $(I32, I32, I32) - store %2 to %3#1 : $*(I32, I32, I32) - %5 = unchecked_addr_cast %3#1 : $*(I32, I32, I32) to $*(I32, I32) + store %2 to %3 : $*(I32, I32, I32) + %5 = unchecked_addr_cast %3 : $*(I32, I32, I32) to $*(I32, I32) %6 = tuple_element_addr %5 : $*(I32, I32), 0 %7 = tuple_element_addr %5 : $*(I32, I32), 1 %8 = load %6 : $*I32 %9 = load %7 : $*I32 - dealloc_stack %3#0 : $*@local_storage (I32, I32, I32) + dealloc_stack %3 : $*(I32, I32, I32) %11 = load %1 : $*((I32, I32), I32) %12 = alloc_stack $((I32, I32), I32) - store %11 to %12#1 : $*((I32, I32), I32) - %14 = unchecked_addr_cast %12#1 : $*((I32, I32), I32) to $*(I32, I32) + store %11 to %12 : $*((I32, I32), I32) + %14 = unchecked_addr_cast %12 : $*((I32, I32), I32) to $*(I32, I32) %15 = tuple_element_addr %14 : $*(I32, I32), 0 %16 = tuple_element_addr %14 : $*(I32, I32), 1 %17 = load %15 : $*I32 %18 = load %16 : $*I32 - dealloc_stack %12#0 : $*@local_storage ((I32, I32), I32) + dealloc_stack %12 : $*((I32, I32), I32) %20 = alloc_stack $((I32, I32), I32) - store %11 to %20#1 : $*((I32, I32), I32) - %22 = unchecked_addr_cast %20#1 : $*((I32, I32), I32) to $*(I32, I32, I32) + store %11 to %20 : $*((I32, I32), I32) + %22 = unchecked_addr_cast %20 : $*((I32, I32), I32) to $*(I32, I32, I32) %23 = tuple_element_addr %22 : $*(I32, I32, I32), 0 %24 = tuple_element_addr %22 : $*(I32, I32, I32), 1 %25 = tuple_element_addr %22 : $*(I32, I32, I32), 2 %26 = load %23 : $*I32 %27 = load %24 : $*I32 %28 = load %25 : $*I32 - dealloc_stack %20#0 : $*@local_storage ((I32, I32), I32) + dealloc_stack %20 : $*((I32, I32), I32) %30 = tuple (%8 : $I32, %9 : $I32) %31 = tuple (%17 : $I32, %18 : $I32) %32 = tuple (%26 : $I32, %27 : $I32, %28 : $I32) @@ -616,18 +616,18 @@ bb0(%0 : $*(I32, I32, I32), %1 : $*((I32, I32), I32)): %8 = tuple_element_addr %0 : $*(I32, I32, I32), 2 %9 = load %8 : $*I32 %10 = alloc_stack $(I32, I32, I32) - %11 = tuple_element_addr %10#1 : $*(I32, I32, I32), 0 - %12 = tuple_element_addr %10#1 : $*(I32, I32, I32), 1 - %13 = tuple_element_addr %10#1 : $*(I32, I32, I32), 2 + %11 = tuple_element_addr %10 : $*(I32, I32, I32), 0 + %12 = tuple_element_addr %10 : $*(I32, I32, I32), 1 + %13 = tuple_element_addr %10 : $*(I32, I32, I32), 2 store %5 to %11 : $*I32 store %7 to %12 : $*I32 store %9 to %13 : $*I32 - %17 = unchecked_addr_cast %10#1 : $*(I32, I32, I32) to $*(I32, I32) + %17 = unchecked_addr_cast %10 : $*(I32, I32, I32) to $*(I32, I32) %18 = tuple_element_addr %17 : $*(I32, I32), 0 %19 = tuple_element_addr %17 : $*(I32, I32), 1 %20 = load %18 : $*I32 %21 = load %19 : $*I32 - dealloc_stack %10#0 : $*@local_storage (I32, I32, I32) + dealloc_stack %10 : $*(I32, I32, I32) %23 = tuple_element_addr %1 : $*((I32, I32), I32), 0 %24 = tuple_element_addr %23 : $*(I32, I32), 0 %25 = load %24 : $*I32 @@ -636,35 +636,35 @@ bb0(%0 : $*(I32, I32, I32), %1 : $*((I32, I32), I32)): %28 = tuple_element_addr %1 : $*((I32, I32), I32), 1 %29 = load %28 : $*I32 %30 = alloc_stack $((I32, I32), I32) - %31 = tuple_element_addr %30#1 : $*((I32, I32), I32), 0 - %32 = tuple_element_addr %30#1 : $*((I32, I32), I32), 1 + %31 = tuple_element_addr %30 : $*((I32, I32), I32), 0 + %32 = tuple_element_addr %30 : $*((I32, I32), I32), 1 %33 = tuple_element_addr %31 : $*(I32, I32), 0 %34 = tuple_element_addr %31 : $*(I32, I32), 1 store %25 to %33 : $*I32 store %27 to %34 : $*I32 store %29 to %32 : $*I32 - %38 = unchecked_addr_cast %30#1 : $*((I32, I32), I32) to $*(I32, I32) + %38 = unchecked_addr_cast %30 : $*((I32, I32), I32) to $*(I32, I32) %39 = tuple_element_addr %38 : $*(I32, I32), 0 %40 = tuple_element_addr %38 : $*(I32, I32), 1 %41 = load %39 : $*I32 %42 = load %40 : $*I32 - dealloc_stack %30#0 : $*@local_storage ((I32, I32), I32) + dealloc_stack %30 : $*((I32, I32), I32) %44 = alloc_stack $((I32, I32), I32) - %45 = tuple_element_addr %44#1 : $*((I32, I32), I32), 0 - %46 = tuple_element_addr %44#1 : $*((I32, I32), I32), 1 + %45 = tuple_element_addr %44 : $*((I32, I32), I32), 0 + %46 = tuple_element_addr %44 : $*((I32, I32), I32), 1 %47 = tuple_element_addr %45 : $*(I32, I32), 0 %48 = tuple_element_addr %45 : $*(I32, I32), 1 store %25 to %47 : $*I32 store %27 to %48 : $*I32 store %29 to %46 : $*I32 - %52 = unchecked_addr_cast %44#1 : $*((I32, I32), I32) to $*(I32, I32, I32) + %52 = unchecked_addr_cast %44 : $*((I32, I32), I32) to $*(I32, I32, I32) %53 = tuple_element_addr %52 : $*(I32, I32, I32), 0 %54 = tuple_element_addr %52 : $*(I32, I32, I32), 1 %55 = tuple_element_addr %52 : $*(I32, I32, I32), 2 %56 = load %53 : $*I32 %57 = load %54 : $*I32 %58 = load %55 : $*I32 - dealloc_stack %44#0 : $*@local_storage ((I32, I32), I32) + dealloc_stack %44 : $*((I32, I32), I32) %60 = tuple (%20 : $I32, %21 : $I32) %61 = tuple (%41 : $I32, %42 : $I32) %62 = tuple (%56 : $I32, %57 : $I32, %58 : $I32) diff --git a/test/SILPasses/high_level_cse.sil b/test/SILOptimizer/high_level_cse.sil similarity index 100% rename from test/SILPasses/high_level_cse.sil rename to test/SILOptimizer/high_level_cse.sil diff --git a/test/SILPasses/high_level_licm.sil b/test/SILOptimizer/high_level_licm.sil similarity index 100% rename from test/SILPasses/high_level_licm.sil rename to test/SILOptimizer/high_level_licm.sil diff --git a/test/SILPasses/inline_addressor.swift b/test/SILOptimizer/inline_addressor.swift similarity index 92% rename from test/SILPasses/inline_addressor.swift rename to test/SILOptimizer/inline_addressor.swift index 12ca61165b52c..d409e187a929e 100644 --- a/test/SILPasses/inline_addressor.swift +++ b/test/SILOptimizer/inline_addressor.swift @@ -18,8 +18,8 @@ var totalsum = nonTrivialInit(true) //CHECK-NOT: totalsum //CHECK-NOT: inputval //CHECK: {{^}$}} -func testit() { - for i in 0...10 { +func testit(x: Int) { + for _ in 0...10000000 { totalsum += inputval } } diff --git a/test/SILPasses/inline_caches.sil b/test/SILOptimizer/inline_caches.sil similarity index 96% rename from test/SILPasses/inline_caches.sil rename to test/SILOptimizer/inline_caches.sil index 20b0773a0802b..3da16183a776f 100644 --- a/test/SILPasses/inline_caches.sil +++ b/test/SILOptimizer/inline_caches.sil @@ -60,7 +60,7 @@ bb0(%0 : $@thick C.Type): // CHECK: apply [[REF]] // CHECK: br bb1 // CHECK: bb3 - // CHECK: [[METHOD:%.*]] = class_method %0 : $@thick C.Type, #C.foo!1 : C.Type -> () -> () , $@convention(thin) (@thick C.Type) -> () + // CHECK: [[METHOD:%.*]] = class_method %0 : $@thick C.Type, #C.foo!1 : (C.Type) -> () -> () , $@convention(thin) (@thick C.Type) -> () // CHECK: apply [[METHOD]] %2 = class_method %0 : $@thick C.Type, #C.foo!1 : C.Type -> () -> () , $@convention(thin) (@thick C.Type) -> () %3 = apply %2(%0) : $@convention(thin) (@thick C.Type) -> () diff --git a/test/SILPasses/inline_deep.sil b/test/SILOptimizer/inline_deep.sil similarity index 81% rename from test/SILPasses/inline_deep.sil rename to test/SILOptimizer/inline_deep.sil index 7f9138323e7f3..7ab9b9be85f1b 100644 --- a/test/SILPasses/inline_deep.sil +++ b/test/SILOptimizer/inline_deep.sil @@ -39,10 +39,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l0!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -57,10 +57,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l1!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -75,10 +75,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l2!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -93,10 +93,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l3!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -111,10 +111,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l4!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -129,10 +129,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l5!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -147,10 +147,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l6!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -165,10 +165,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l7!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -183,10 +183,10 @@ bb0(%0 : $*T, %1 : $*T, %2 : $S): strong_retain %2 : $S %6 = class_method %2 : $S, #S.l8!1 : S -> (T) -> T , $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () %7 = alloc_stack $T - copy_addr %1 to [initialization] %7#1 : $*T - %9 = apply %6(%0, %7#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + copy_addr %1 to [initialization] %7 : $*T + %9 = apply %6(%0, %7, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - dealloc_stack %7#0 : $*@local_storage T + dealloc_stack %7 : $*T destroy_addr %1 : $*T %13 = tuple () // CHECK: return @@ -222,14 +222,14 @@ bb0: %3 = integer_literal $Builtin.Int32, 709 %4 = struct $Int32 (%3 : $Builtin.Int32) %5 = alloc_stack $Int32 - store %4 to %5#1 : $*Int32 + store %4 to %5 : $*Int32 %7 = alloc_stack $Int32 %8 = function_ref @_TFC5depth1S2l9U__fGS0_Q__FQ_Q_ : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () - %9 = apply %8(%7#1, %5#1, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () + %9 = apply %8(%7, %5, %2) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @guaranteed S<τ_0_0>) -> () strong_release %2 : $S - %11 = load %7#1 : $*Int32 - dealloc_stack %7#0 : $*@local_storage Int32 - dealloc_stack %5#0 : $*@local_storage Int32 + %11 = load %7 : $*Int32 + dealloc_stack %7 : $*Int32 + dealloc_stack %5 : $*Int32 // CHECK: return return %11 : $Int32 } diff --git a/test/SILPasses/inline_devirtualize_specialize.sil b/test/SILOptimizer/inline_devirtualize_specialize.sil similarity index 100% rename from test/SILPasses/inline_devirtualize_specialize.sil rename to test/SILOptimizer/inline_devirtualize_specialize.sil diff --git a/test/SILPasses/inline_heuristics.sil b/test/SILOptimizer/inline_heuristics.sil similarity index 98% rename from test/SILPasses/inline_heuristics.sil rename to test/SILOptimizer/inline_heuristics.sil index cd17dffde1de1..86d3219a63810 100644 --- a/test/SILPasses/inline_heuristics.sil +++ b/test/SILOptimizer/inline_heuristics.sil @@ -107,13 +107,13 @@ bb0: %1 = function_ref @closure : $@convention(thin) (Int32) -> Int32 %2 = thin_to_thick_function %1 : $@convention(thin) (Int32) -> Int32 to $@callee_owned (Int32) -> Int32 %3 = struct $Cont (%2 : $@callee_owned (Int32) -> Int32) - store %3 to %0#1 : $*Cont + store %3 to %0 : $*Cont %5 = function_ref @takeStructAddrClosure : $@convention(thin) (@inout Cont) -> Int32 - %6 = apply %5(%0#1) : $@convention(thin) (@inout Cont) -> Int32 - %7 = struct_element_addr %0#1 : $*Cont, #Cont.cl + %6 = apply %5(%0) : $@convention(thin) (@inout Cont) -> Int32 + %7 = struct_element_addr %0 : $*Cont, #Cont.cl %8 = load %7 : $*@callee_owned (Int32) -> Int32 strong_release %8 : $@callee_owned (Int32) -> Int32 - dealloc_stack %0#0 : $*@local_storage Cont + dealloc_stack %0 : $*Cont return %6 : $Int32 } diff --git a/test/SILOptimizer/inline_recursive.swift b/test/SILOptimizer/inline_recursive.swift new file mode 100644 index 0000000000000..a0de02efe01cf --- /dev/null +++ b/test/SILOptimizer/inline_recursive.swift @@ -0,0 +1,39 @@ +// RUN: %target-swift-frontend -primary-file %s -parse-as-library -emit-sil -O | FileCheck %s + +private func recFunc(x: Int32) -> Int32 { + if x > 0 { + return recFunc(x - 1) + } + return 0 +} + +//CHECK-LABEL: sil {{.*}}callit +// CHECK: bb0: +// CHECK-NEXT: integer_literal $Builtin.Int32, 0 +// CHECK-NEXT: struct +// CHECK-NEXT: return + +func callit() -> Int32 { + return recFunc(3) +} + +private func recFuncManyCalls(x: Int32) -> Int32 { + if x > 4 { + return recFuncManyCalls(x - 1) + + recFuncManyCalls(x - 2) + + recFuncManyCalls(x - 3) + + recFuncManyCalls(x - 4) + + recFuncManyCalls(x - 5) + } + return 0 +} + +// CHECK-LABEL: sil hidden {{.*}}callother +// CHECK: bb0: +// CHECK: [[FN:%.*]] = function_ref {{.*}}recFuncManyCalls +// CHECK: [[APPLY:%.*]] = apply [[FN]] +// CHECK-NOT: apply +// CHECK: return [[APPLY]] +func callother() -> Int32 { + return recFuncManyCalls(10) +} diff --git a/test/SILPasses/inline_self.swift b/test/SILOptimizer/inline_self.swift similarity index 100% rename from test/SILPasses/inline_self.swift rename to test/SILOptimizer/inline_self.swift diff --git a/test/SILPasses/inline_semantics.sil b/test/SILOptimizer/inline_semantics.sil similarity index 95% rename from test/SILPasses/inline_semantics.sil rename to test/SILOptimizer/inline_semantics.sil index 1daf87e26f526..c75c2b962548e 100644 --- a/test/SILPasses/inline_semantics.sil +++ b/test/SILOptimizer/inline_semantics.sil @@ -23,7 +23,7 @@ bb0: return %1 : $Int32 // id: %2 } -// A function annocated with the @effects(readonly) attribute. +// A function annotated with the @effects(readonly) attribute. sil [readonly] @callee_func2 : $@convention(thin) () -> Int32 { bb0: %0 = integer_literal $Builtin.Int32, 3 // user: %1 diff --git a/test/SILPasses/inline_thunk.swift b/test/SILOptimizer/inline_thunk.swift similarity index 100% rename from test/SILPasses/inline_thunk.swift rename to test/SILOptimizer/inline_thunk.swift diff --git a/test/SILPasses/inline_tryApply.sil b/test/SILOptimizer/inline_tryApply.sil similarity index 100% rename from test/SILPasses/inline_tryApply.sil rename to test/SILOptimizer/inline_tryApply.sil diff --git a/test/SILPasses/inlinecaches_arc.sil b/test/SILOptimizer/inlinecaches_arc.sil similarity index 95% rename from test/SILPasses/inlinecaches_arc.sil rename to test/SILOptimizer/inlinecaches_arc.sil index a7beeab742e41..444a7bda62db5 100644 --- a/test/SILPasses/inlinecaches_arc.sil +++ b/test/SILOptimizer/inlinecaches_arc.sil @@ -31,7 +31,7 @@ sil @_TFC4main3FoocfMS0_FT_S0_ : $@convention(method) (@owned Foo) -> @owned Foo // CHECK-NOT: strong_release sil @_TF4main7my_mainFCS_3FooSi : $@convention(thin) (@owned Foo) -> Int { bb0(%0 : $Foo): - debug_value %0 : $Foo // let x // id: %1 + debug_value %0 : $Foo, let, name "x" // id: %1 %3 = class_method %0 : $Foo, #Foo.ping!1 : Foo -> () -> Int , $@convention(method) (@guaranteed Foo) -> Int // user: %4 %4 = apply %3(%0) : $@convention(method) (@guaranteed Foo) -> Int // user: %6 strong_release %0 : $Foo // id: %5 diff --git a/test/SILPasses/inlinecaches_invalidate_failure.sil b/test/SILOptimizer/inlinecaches_invalidate_failure.sil similarity index 93% rename from test/SILPasses/inlinecaches_invalidate_failure.sil rename to test/SILOptimizer/inlinecaches_invalidate_failure.sil index ca6344e9eda55..66ba46eead75f 100644 --- a/test/SILPasses/inlinecaches_invalidate_failure.sil +++ b/test/SILOptimizer/inlinecaches_invalidate_failure.sil @@ -64,14 +64,14 @@ sil @_TFC4test3Food : $@convention(method) (@guaranteed Foo) -> @owned Builtin.N sil hidden @_TFC4test4Foo2cfMS0_FT_S0_ : $@convention(method) (@owned Foo2) -> @owned Foo2 { bb0(%0 : $Foo2): %1 = alloc_stack $Foo2 // users: %2, %6, %9, %10 - store %0 to %1#1 : $*Foo2 // id: %2 + store %0 to %1 : $*Foo2 // id: %2 %3 = upcast %0 : $Foo2 to $Foo // user: %7 // function_ref test.Foo.init (test.Foo.Type)() -> test.Foo %4 = function_ref @_TFC4test3FoocfMS0_FT_S0_ : $@convention(method) (@owned Foo) -> @owned Foo // user: %7 %7 = apply %4(%3) : $@convention(method) (@owned Foo) -> @owned Foo // user: %8 %8 = unchecked_ref_cast %7 : $Foo to $Foo2 // users: %9, %11 - store %8 to %1#1 : $*Foo2 // id: %9 - dealloc_stack %1#0 : $*@local_storage Foo2 // id: %10 + store %8 to %1 : $*Foo2 // id: %9 + dealloc_stack %1 : $*Foo2 // id: %10 return %8 : $Foo2 // id: %11 } @@ -80,14 +80,14 @@ sil hidden @_TFC4test4Foo2CfMS0_FT_S0_ : $@convention(thin) (@thick Foo2.Type) - bb0(%0 : $@thick Foo2.Type): %1 = alloc_ref $Foo2 // users: %3, %4 %2 = alloc_stack $Foo2 // users: %3, %7, %10, %11 - store %1 to %2#1 : $*Foo2 // id: %3 + store %1 to %2 : $*Foo2 // id: %3 %4 = upcast %1 : $Foo2 to $Foo // user: %8 // function_ref test.Foo.init (test.Foo.Type)() -> test.Foo %5 = function_ref @_TFC4test3FoocfMS0_FT_S0_ : $@convention(method) (@owned Foo) -> @owned Foo // user: %8 %8 = apply %5(%4) : $@convention(method) (@owned Foo) -> @owned Foo // user: %9 %9 = unchecked_ref_cast %8 : $Foo to $Foo2 // users: %10, %12 - store %9 to %2#1 : $*Foo2 // id: %10 - dealloc_stack %2#0 : $*@local_storage Foo2 // id: %11 + store %9 to %2 : $*Foo2 // id: %10 + dealloc_stack %2 : $*Foo2 // id: %11 return %9 : $Foo2 // id: %12 } diff --git a/test/SILPasses/inlinecaches_objc.sil b/test/SILOptimizer/inlinecaches_objc.sil similarity index 95% rename from test/SILPasses/inlinecaches_objc.sil rename to test/SILOptimizer/inlinecaches_objc.sil index 887644216b1b1..728038c0ceb91 100644 --- a/test/SILPasses/inlinecaches_objc.sil +++ b/test/SILOptimizer/inlinecaches_objc.sil @@ -17,7 +17,7 @@ sil @_TFC4main1XcfMS0_FT_S0_ : $@convention(method) (@owned X) -> @owned X // CHECK: return sil @_TF4main1fFCS_1XT_ : $@convention(thin) (@owned X) -> () { bb0(%0 : $X): - debug_value %0 : $X // let x // id: %1 + debug_value %0 : $X, let, name "x" // id: %1 strong_retain %0 : $X // id: %2 %3 = class_method [volatile] %0 : $X, #X.ping!1.foreign : X -> () -> () , $@convention(objc_method) (X) -> () // user: %4 %4 = apply %3(%0) : $@convention(objc_method) (X) -> () diff --git a/test/SILPasses/inliner_loop.swift b/test/SILOptimizer/inliner_loop.swift similarity index 100% rename from test/SILPasses/inliner_loop.swift rename to test/SILOptimizer/inliner_loop.swift diff --git a/test/SILOptimizer/inout_deshadow.sil b/test/SILOptimizer/inout_deshadow.sil new file mode 100644 index 0000000000000..e7faff41c4791 --- /dev/null +++ b/test/SILOptimizer/inout_deshadow.sil @@ -0,0 +1,144 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -inout-deshadow | FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +protocol P { + func foo() +} + +sil @takeInt : $@convention(method) (@inout Int64) -> () + +sil @TrivialTest : $@convention(thin) (@inout Int64) -> () { +bb0(%0 : $*Int64): + %1 = alloc_stack $Int64, var, name "a" // users: %6, %2, %4, %5 + copy_addr %0 to [initialization] %1 : $*Int64 + %3 = function_ref @takeInt : $@convention(method) (@inout Int64) -> () // user: %4 + %4 = apply %3(%1) : $@convention(method) (@inout Int64) -> () + copy_addr %1 to %0 : $*Int64 + dealloc_stack %1 : $*Int64 + %7 = tuple () // user: %8 + return %7 : $() +} + + +// CHECK-LABEL: sil @AddressOnlyTest +sil @AddressOnlyTest : $@convention(thin) (@inout P) -> () { +bb0(%0 : $*P): // CHECK: bb0(%0 : $*P): + %1 = alloc_stack $P + copy_addr %0 to [initialization] %1 : $*P + + // CHECK-NEXT: debug_value_addr %0 + // CHECK-NEXT: open_existential_addr %0 : $*P + %3 = open_existential_addr %1 : $*P to $*@opened("01234567-89ab-cdef-0123-000000000000") P + %4 = witness_method $@opened("01234567-89ab-cdef-0123-000000000000") P, #P.foo!1, %3 : $*@opened("01234567-89ab-cdef-0123-000000000000") P : $@convention(witness_method) @callee_owned (@inout T) -> () + + // CHECK: apply + %5 = apply %4<@opened("01234567-89ab-cdef-0123-000000000000") P>(%3) : $@convention(witness_method) @callee_owned (@inout T) -> () + + copy_addr [take] %1 to %0 : $*P + dealloc_stack %1 : $*P + + // CHECK-NEXT: tuple () + %9 = tuple () + // CHECK-NEXT: return + return %9 : $() +} + +class C { +} + +struct NontrivialStruct { + var a: Int + var b: C + func foo() +} + + +sil @takeNontrivial : $@convention(method) (@inout NontrivialStruct) -> () + +// CHECK-LABEL: sil @NontrivialTest +sil @NontrivialTest : $@convention(thin) (@inout NontrivialStruct) -> () { +bb0(%0 : $*NontrivialStruct): +// CHECK: bb0(%0 : $*NontrivialStruct): + + %1 = alloc_stack $NontrivialStruct + copy_addr %0 to [initialization] %1 : $*NontrivialStruct + + // CHECK-NEXT: debug_value_addr %0 + // CHECK-NEXT: // function_ref takeNontrivial + // CHECK-NEXT: function_ref @takeNontrivial + %3 = function_ref @takeNontrivial : $@convention(method) (@inout NontrivialStruct) -> () // user: %4 + + // CHECK-NEXT: apply + %4 = apply %3(%1) : $@convention(method) (@inout NontrivialStruct) -> () + copy_addr [take] %1 to %0 : $*NontrivialStruct + dealloc_stack %1 : $*NontrivialStruct + + // CHECK-NEXT: tuple + %9 = tuple () + // CHECK-NEXT: return + return %9 : $() +} + +// Inout deshadowing should *not* deshadow inouts that are copied to temporaries for use by +// @in arguments. + +sil @in_argument : $@convention(thin) (@in protocol<>) -> () + +// CHECK-LABEL: sil @inout_argument_passed_to_in_argument +sil @inout_argument_passed_to_in_argument : $@convention(thin) (@inout protocol<>) -> () { +// CHECK: bb0([[INOUT:%.*]] : $*protocol<>): +entry(%0 : $*protocol<>): + %f = function_ref @in_argument : $@convention(thin) (@in protocol<>) -> () + %x = alloc_stack $protocol<> + // CHECK: copy_addr [[INOUT]] to [initialization] + copy_addr %0 to [initialization] %x : $*protocol<> + %z = apply %f(%x) : $@convention(thin) (@in protocol<>) -> () + dealloc_stack %x : $*protocol<> + return %z : $() +} + +sil @makeError : $@convention(thin) () -> @owned ErrorType + +struct MyStruct { + @sil_stored var placeholder: T + @sil_stored var value: Bool + mutating func throwing(value: Bool) throws + init(placeholder: T, value: Bool) +} + +// Verify that we deshadow in functions that throw. +// CHECK-LABEL: throwing +sil hidden @throwing : $@convention(method) (Bool, @inout MyStruct) -> @error ErrorType { +// CHECK: bb0 +bb0(%0 : $Bool, %1 : $*MyStruct): + %2 = alloc_stack $MyStruct + debug_value %0 : $Bool +// CHECK-NOT: copy_addr + copy_addr %1 to [initialization] %2 : $*MyStruct + %5 = struct_extract %0 : $Bool, #Bool._value + cond_br %5, bb1, bb2 + +// CHECK: bb1 +bb1: + %7 = function_ref @makeError : $@convention(thin) () -> @owned ErrorType + %8 = apply %7() : $@convention(thin) () -> @owned ErrorType + %9 = builtin "willThrow"(%8 : $ErrorType) : $() +// CHECK-NOT: copy_addr + copy_addr [take] %2 to %1 : $*MyStruct + dealloc_stack %2 : $*MyStruct + throw %8 : $ErrorType + +// CHECK: bb2 +bb2: + %12 = struct_element_addr %2 : $*MyStruct, #MyStruct.value + store %0 to %12 : $*Bool +// CHECK-NOT: copy_addr + copy_addr [take] %2 to %1 : $*MyStruct + %15 = tuple () + dealloc_stack %2 : $*MyStruct + return %15 : $() +} diff --git a/test/SILPasses/inout_deshadow_integration.swift b/test/SILOptimizer/inout_deshadow_integration.swift similarity index 100% rename from test/SILPasses/inout_deshadow_integration.swift rename to test/SILOptimizer/inout_deshadow_integration.swift diff --git a/test/SILPasses/iv_info_printer.sil b/test/SILOptimizer/iv_info_printer.sil similarity index 100% rename from test/SILPasses/iv_info_printer.sil rename to test/SILOptimizer/iv_info_printer.sil diff --git a/test/SILPasses/latecodemotion.sil b/test/SILOptimizer/latecodemotion.sil similarity index 98% rename from test/SILPasses/latecodemotion.sil rename to test/SILOptimizer/latecodemotion.sil index d1d3cf6801e0e..454a6ee9a04f0 100644 --- a/test/SILPasses/latecodemotion.sil +++ b/test/SILOptimizer/latecodemotion.sil @@ -364,7 +364,7 @@ bb0(%0 : $FakeOptional): apply %1() : $@convention(thin) () -> () %3 = alloc_stack $Builtin.Int32 retain_value %0 : $FakeOptional - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 bb1(%2 : $Builtin.NativeObject): @@ -459,7 +459,7 @@ bb4: return %2 : $() } -// This test makes sure that we do move ref counts over instructions that can not reference it. +// This test makes sure that we do move ref counts over instructions that cannot reference it. // CHECK-LABEL: sil @sink_ref_count_ops_enum_over_switch_enum_4 : // CHECK: bb0({{%[0-9]+}} : $FakeOptional, [[ARG1:%[0-9]+]] : $FakeOptional): // CHECK-NOT: retain_value [[ARG1]] @@ -491,7 +491,7 @@ bb2: br bb3 bb3: - dealloc_stack %3#0 : $*@local_storage FakeOptional + dealloc_stack %3 : $*FakeOptional return %1 : $FakeOptional } @@ -521,7 +521,7 @@ bb10: %1 = function_ref @blocker : $@convention(thin) () -> () retain_value %0 : $FakeOptional %3 = alloc_stack $Builtin.Int32 - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 release_value %0 : $FakeOptional switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 @@ -568,7 +568,7 @@ bb0(%0 : $FakeOptional): apply %1() : $@convention(thin) () -> () %3 = alloc_stack $Builtin.Int32 retain_value %0 : $FakeOptional - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 %100 = select_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: %t, case #FakeOptional.None!enumelt: %f : $Builtin.Int1 cond_br %100, bb1, bb2 @@ -734,7 +734,7 @@ bb10: %1 = function_ref @blocker : $@convention(thin) () -> () retain_value %0 : $FakeOptional %3 = alloc_stack $Builtin.Int32 - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 %100 = select_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: %t, case #FakeOptional.None!enumelt: %f : $Builtin.Int1 release_value %0 : $FakeOptional cond_br %100, bb1, bb2 @@ -1062,7 +1062,7 @@ bb3: return %9999 : $() } -// Because our enum is not local to this function, we can not move retain_value +// Because our enum is not local to this function, we cannot move retain_value // %0 past blocker. // // CHECK-LABEL: sil @enum_simplification_test6b : $@convention(thin) (FakeOptional) -> () { @@ -1625,11 +1625,11 @@ class G {} sil @cast_consumption : $@convention(thin) (@owned F) -> () { bb0(%0 : $F): %1 = alloc_stack $F - store %0 to %1#1 : $*F + store %0 to %1 : $*F strong_retain %0 : $F - unconditional_checked_cast_addr take_always F in %1#1 : $*F to G in %1#1 : $*F + unconditional_checked_cast_addr take_always F in %1 : $*F to G in %1 : $*F strong_release %0 : $F - dealloc_stack %1#0 : $*@local_storage F + dealloc_stack %1 : $*F %2 = tuple () return %2 : $() } diff --git a/test/SILPasses/let_propagation.swift b/test/SILOptimizer/let_propagation.swift similarity index 97% rename from test/SILPasses/let_propagation.swift rename to test/SILOptimizer/let_propagation.swift index 9660239ac58b7..0fb1b0cd70d95 100644 --- a/test/SILPasses/let_propagation.swift +++ b/test/SILOptimizer/let_propagation.swift @@ -5,7 +5,7 @@ // This is safe, because once assigned, these variables cannot change their value. // Helper function, which models an external functions with unknown side-effects. -// It is calle just to trigger flushing of all known stored in LoadStore optimizations. +// It is called just to trigger flushing of all known stored in LoadStore optimizations. @inline(never) func action() { print("") @@ -295,7 +295,7 @@ final public class S3 { // DISABLECHECK: load %[[X]] // DISABLECHECK-NOT: load %[[X]] // DISABLECHECK: return -public func testLetTuple(s: S3) ->Int32 { +public func testLetTuple(s: S3) -> Int32 { var counter: Int32 = 0 counter += s.x.0 action() @@ -318,7 +318,7 @@ public func testLetTuple(s: S3) ->Int32 { // CHECK: load %[[X]] // CHECK: load %[[X]] // CHECK: return -public func testVarTuple(s: S3) ->Int32 { +public func testVarTuple(s: S3) -> Int32 { var counter: Int32 = 0 counter += s.y.0 action() diff --git a/test/SILPasses/let_properties_opts.swift b/test/SILOptimizer/let_properties_opts.swift similarity index 95% rename from test/SILPasses/let_properties_opts.swift rename to test/SILOptimizer/let_properties_opts.swift index fa5e554462f99..7dc1959655cbd 100644 --- a/test/SILPasses/let_properties_opts.swift +++ b/test/SILOptimizer/let_properties_opts.swift @@ -3,14 +3,14 @@ // Test propagation of non-static let properties with compile-time constant values. -// TODO: Once this optimization can remove the propagated private/internal let propeties or +// TODO: Once this optimization can remove the propagated private/internal let properties or // mark them as ones without a storage, new tests should be added here to check for this // functionality. // FIXME: This test is written in Swift instead of SIL, because there are some problems // with SIL deserialization (rdar://22636911) -// Check that intializers do not contain a code to intialize private or +// Check that initializers do not contain a code to initialize private or // internal (if used with WMO) properties, because their values are propagated into // their uses and they cannot be accessed from other modules. Therefore the // initialization code could be removed. @@ -36,7 +36,7 @@ // CHECK-WMO: ref_element_addr %{{[0-9]+}} : $Foo, #Foo.Prop3 // CHECK-WMO: return -// Check that intializers do not contain a code to intialize private properties, +// Check that initializers do not contain a code to initialize private properties, // because their values are propagated into their uses and they cannot be accessed // from other modules. Therefore the initialization code could be removed. // Specifically, the initialization code for Prop2 can be removed. @@ -86,7 +86,7 @@ public struct Boo { public init(i:Int64) {} } -// Check that Foo1.Prop1 is not constant-folded, because its value is unkown, since it is initialized differently +// Check that Foo1.Prop1 is not constant-folded, because its value is unknown, since it is initialized differently // by Foo1 initializers. // CHECK-LABEL: sil @_TF19let_properties_opts13testClassLet1FCS_4Foo1Vs5Int32 : $@convention(thin) (@owned Foo1) -> Int32 @@ -99,7 +99,7 @@ public func testClassLet1(f: Foo1) -> Int32 { return f.Prop1 + f.Prop2 + f.Prop3 } -// Check that Foo1.Prop1 is not constant-folded, because its value is unkown, since it is initialized differently +// Check that Foo1.Prop1 is not constant-folded, because its value is unknown, since it is initialized differently // by Foo1 initializers. // CHECK-LABEL: sil @_TF19let_properties_opts13testClassLet1FRCS_4Foo1Vs5Int32 : $@convention(thin) (@inout Foo1) -> Int32 diff --git a/test/SILPasses/licm.sil b/test/SILOptimizer/licm.sil similarity index 91% rename from test/SILPasses/licm.sil rename to test/SILOptimizer/licm.sil index fb417f80b075a..e36c3dde3b828 100644 --- a/test/SILPasses/licm.sil +++ b/test/SILOptimizer/licm.sil @@ -180,3 +180,27 @@ bb2: %r1 = tuple () return %r1 : $() } + +// CHECK-LABEL: sil @dont_hoist_aliased_stack_location +// CHECK: {{^}}bb0 +// CHECK-NOT: load +// CHECK: {{^}}bb1: +// CHECK: store +// CHECK: load +// CHECK: {{^}}bb2: +// CHECK: return +sil @dont_hoist_aliased_stack_location : $@convention(thin) (Int32) -> () { +bb0(%0 : $Int32): + %313 = alloc_stack $Int32 + br bb1 + +bb1: + store %0 to %313 : $*Int32 + %l1 = load %313 : $*Int32 + cond_br undef, bb1, bb2 + +bb2: + dealloc_stack %313 : $*Int32 + %52 = tuple () + return %52 : $() +} diff --git a/test/SILPasses/licm_apply.sil b/test/SILOptimizer/licm_apply.sil similarity index 87% rename from test/SILPasses/licm_apply.sil rename to test/SILOptimizer/licm_apply.sil index 60beb9cca16ad..5f036914a6a30 100644 --- a/test/SILPasses/licm_apply.sil +++ b/test/SILOptimizer/licm_apply.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -side-effects -licm | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -licm | FileCheck %s sil_stage canonical @@ -21,7 +21,7 @@ bb0(%0 : $*Int64, %1 : $Int64): sil @licm_readonly_apply : $@convention(thin) (Int64, @inout Int64) -> () { bb0(%0 : $Int64, %1 : $*Int64): %2 = alloc_stack $Int64 - store %0 to %2#1 : $*Int64 + store %0 to %2 : $*Int64 %9 = function_ref @read_from_param : $@convention(thin) (@inout Int64, Int64) -> Int64 %10 = integer_literal $Builtin.Int64, 3 %11 = struct $Int64 (%10 : $Builtin.Int64) @@ -30,7 +30,7 @@ bb0(%0 : $Int64, %1 : $*Int64): br bb1 bb1: - %21 = apply %9(%2#1, %11) : $@convention(thin) (@inout Int64, Int64) -> Int64 + %21 = apply %9(%2, %11) : $@convention(thin) (@inout Int64, Int64) -> Int64 %22 = load %12 : $*Builtin.Int64 %23 = struct_extract %21 : $Int64, #Int64._value %24 = builtin "sadd_with_overflow_Int64"(%22 : $Builtin.Int64, %23 : $Builtin.Int64, %13 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) @@ -43,7 +43,7 @@ bb1: bb2: %15 = tuple () - dealloc_stack %2#0 : $*@local_storage Int64 + dealloc_stack %2 : $*Int64 return %15 : $() } @@ -54,7 +54,7 @@ bb2: sil @dont_licm_readonly_apply : $@convention(thin) (Int64, @inout Int64) -> () { bb0(%0 : $Int64, %1 : $*Int64): %2 = alloc_stack $Int64 - store %0 to %2#1 : $*Int64 + store %0 to %2 : $*Int64 %9 = function_ref @read_from_param : $@convention(thin) (@inout Int64, Int64) -> Int64 %10 = integer_literal $Builtin.Int64, 3 %11 = struct $Int64 (%10 : $Builtin.Int64) @@ -63,7 +63,7 @@ bb0(%0 : $Int64, %1 : $*Int64): br bb1 bb1: - %21 = apply %9(%2#1, %11) : $@convention(thin) (@inout Int64, Int64) -> Int64 + %21 = apply %9(%2, %11) : $@convention(thin) (@inout Int64, Int64) -> Int64 %22 = load %12 : $*Builtin.Int64 %23 = struct_extract %21 : $Int64, #Int64._value %24 = builtin "sadd_with_overflow_Int64"(%22 : $Builtin.Int64, %23 : $Builtin.Int64, %13 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) @@ -71,12 +71,12 @@ bb1: %28 = struct $Int64 (%25 : $Builtin.Int64) // This store does alias with the read in @read_from_param - store %28 to %2#1 : $*Int64 + store %28 to %2 : $*Int64 cond_br undef, bb1, bb2 bb2: %15 = tuple () - dealloc_stack %2#0 : $*@local_storage Int64 + dealloc_stack %2 : $*Int64 return %15 : $() } diff --git a/test/SILPasses/linker.swift b/test/SILOptimizer/linker.swift similarity index 93% rename from test/SILPasses/linker.swift rename to test/SILOptimizer/linker.swift index 41e62341fec3b..69d6b62b51414 100644 --- a/test/SILPasses/linker.swift +++ b/test/SILOptimizer/linker.swift @@ -6,7 +6,7 @@ // CHECK: sil public_external [fragile] @_TFs11doSomethingFT_T_ : $@convention(thin) () -> () { doSomething() -// Make sure we are not linking doSomethign2 because it is marked with 'noimport' +// Make sure we are not linking doSomething2 because it is marked with 'noimport' // CHECK: sil [_semantics "stdlib_binary_only"] @_TFs12doSomething2FT_T_ : $@convention(thin) () -> () // CHECK-NOT: return diff --git a/test/SILAnalysis/loop-region-analysis.sil b/test/SILOptimizer/loop-region-analysis.sil similarity index 77% rename from test/SILAnalysis/loop-region-analysis.sil rename to test/SILOptimizer/loop-region-analysis.sil index b19f5960a5c8b..7ac4ef7b7c68c 100644 --- a/test/SILAnalysis/loop-region-analysis.sil +++ b/test/SILOptimizer/loop-region-analysis.sil @@ -35,13 +35,15 @@ sil @no_return_func : $@convention(thin) @noreturn () -> () // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:3 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:loop ucfh:false ucft:false parent:3 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -49,19 +51,23 @@ sil @no_return_func : $@convention(thin) @noreturn () -> () // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:1))) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:4 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:3 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @one_natural_self_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -89,13 +95,15 @@ bb2: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:6) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:loop ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -105,33 +113,39 @@ bb2: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:3))) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @one_natural_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -167,13 +181,15 @@ bb4: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -184,7 +200,9 @@ bb4: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2) @@ -192,34 +210,39 @@ bb4: // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @one_natural_loop_with_diamond : $@convention(thin) () -> () { bb0: br bb1 @@ -256,13 +279,15 @@ bb5: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:6) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:loop ucfh:true ucft:true parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -272,33 +297,39 @@ bb5: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:3))) // CHECK: (region id:3 kind:bb ucfh:false ucft:true parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:true parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:true ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @one_natural_loop_multiple_backedges : $@convention(thin) () -> () { bb0: br bb1 @@ -329,13 +360,15 @@ bb4: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:loop ucfh:false ucft:true parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -344,7 +377,9 @@ bb4: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:8)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:8))) // CHECK: (region id:8 kind:loop ucfh:true ucft:true parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -354,39 +389,46 @@ bb4: // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:true parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:true parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:true ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @inner_natural_loop_with_multiple_backedges : $@convention(thin) () -> () { bb0: br bb1 @@ -425,13 +467,15 @@ bb5: // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:7)) @@ -440,20 +484,24 @@ bb5: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -462,26 +510,31 @@ bb5: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2))) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @two_separate_natural_loops : $@convention(thin) () -> () { bb0: br bb1 @@ -513,7 +566,7 @@ bb5: // | | | | // -------- -------- // -// CHECK-LABEL: @two_separate_natural_loops_seperated_by_diamond@ +// CHECK-LABEL: @two_separate_natural_loops_separated_by_diamond@ // CHECK: (region id:7 kind:func ucfh:false ucft:false // CHECK-NEXT: (preds) // CHECK-NEXT: (succs) @@ -523,13 +576,15 @@ bb5: // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:9) // CHECK-NEXT: (region id:6)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:9 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3) @@ -539,27 +594,32 @@ bb5: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:5))) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:5)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -569,7 +629,9 @@ bb5: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2))) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -577,20 +639,23 @@ bb5: // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs // CHECK-NEXT: (parentindex:0) -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) -sil @two_separate_natural_loops_seperated_by_diamond : $@convention(thin) () -> () { +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) +sil @two_separate_natural_loops_separated_by_diamond : $@convention(thin) () -> () { bb0: br bb1 @@ -628,7 +693,7 @@ bb6: // | | | | // -------- -------- // -// CHECK-LABEL: @two_separate_natural_loops_seperated_by_diamond_with_loop@ +// CHECK-LABEL: @two_separate_natural_loops_separated_by_diamond_with_loop@ // CHECK: (region id:8 kind:func ucfh:false ucft:false // CHECK-NEXT: (preds) // CHECK-NEXT: (succs) @@ -638,14 +703,16 @@ bb6: // CHECK-NEXT: (region id:10) // CHECK-NEXT: (region id:11) // CHECK-NEXT: (region id:7)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:10) // CHECK-NEXT: (region id:11)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:11 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9) @@ -655,20 +722,24 @@ bb6: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:5) // CHECK-NEXT: (region id:6)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:6))) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:5)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:10 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9)) @@ -678,7 +749,9 @@ bb6: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) @@ -686,13 +759,15 @@ bb6: // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs // CHECK-NEXT: (parentindex:0) -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:9 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -702,7 +777,9 @@ bb6: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2))) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -710,20 +787,23 @@ bb6: // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs // CHECK-NEXT: (parentindex:0) -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) -sil @two_separate_natural_loops_seperated_by_diamond_with_loop : $@convention(thin) () -> () { +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) +sil @two_separate_natural_loops_separated_by_diamond_with_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -761,14 +841,16 @@ bb7: // CHECK-NEXT: (region id:10) // CHECK-NEXT: (region id:11) // CHECK-NEXT: (region id:7)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:10) // CHECK-NEXT: (region id:11)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:11 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9)) @@ -777,20 +859,24 @@ bb7: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:5) // CHECK-NEXT: (region id:6)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:6))) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:5)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:10 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) @@ -798,20 +884,24 @@ bb7: // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:10)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:9 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -821,7 +911,9 @@ bb7: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2))) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -829,19 +921,22 @@ bb7: // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs // CHECK-NEXT: (parentindex:0) -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @three_separate_natural_loops : $@convention(thin) () -> () { bb0: br bb1 @@ -884,13 +979,15 @@ bb7: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:6) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:loop ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -900,14 +997,17 @@ bb7: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:3)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:3))) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -915,25 +1015,30 @@ bb7: // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2))) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @two_level_natural_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -968,13 +1073,15 @@ bb4: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -985,7 +1092,9 @@ bb4: // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3) @@ -993,7 +1102,8 @@ bb4: // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1) @@ -1001,7 +1111,8 @@ bb4: // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -1010,27 +1121,32 @@ bb4: // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2))) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs // CHECK-NEXT: (parentindex:0) -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @two_level_natural_loop_with_diamond_and_multiple_loop_exits : $@convention(thin) () -> () { bb0: br bb1 @@ -1060,13 +1176,15 @@ bb5: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -1077,7 +1195,9 @@ bb5: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2) @@ -1085,7 +1205,8 @@ bb5: // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -1093,33 +1214,39 @@ bb5: // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:3)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:3))) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @three_level_natural_loop_with_inner_loop_in_diamond : $@convention(thin) () -> () { bb0: br bb1 @@ -1155,13 +1282,15 @@ bb5: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:true ucft:true parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0) @@ -1169,7 +1298,8 @@ bb5: // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:true ucft:true parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1) @@ -1179,7 +1309,8 @@ bb5: // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:true ucft:true parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0) @@ -1187,14 +1318,16 @@ bb5: // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @one_level_irreducible_loop : $@convention(thin) () -> () { bb0: cond_br undef, bb1, bb3 @@ -1223,13 +1356,15 @@ bb5: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:6)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -1241,14 +1376,17 @@ bb5: // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:5))) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:true ucft:true parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1) @@ -1256,7 +1394,8 @@ bb5: // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:true ucft:true parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2) @@ -1266,7 +1405,8 @@ bb5: // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:5)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:true ucft:true parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1) @@ -1274,20 +1414,23 @@ bb5: // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @natural_loop_containing_irreducible_loop : $@convention(thin) () -> () { bb0: br bb6 @@ -1326,13 +1469,15 @@ bb7: // CHECK-NEXT: (region id:10) // CHECK-NEXT: (region id:11) // CHECK-NEXT: (region id:8)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:11)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:11 kind:loop ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:10)) @@ -1341,20 +1486,24 @@ bb7: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:6) // CHECK-NEXT: (region id:7)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:7))) // CHECK: (region id:7 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:10 kind:loop ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -1366,14 +1515,17 @@ bb7: // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:5))) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:true ucft:true parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1) @@ -1381,7 +1533,8 @@ bb7: // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:true ucft:true parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2) @@ -1391,7 +1544,8 @@ bb7: // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:5)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:true ucft:true parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1) @@ -1399,20 +1553,23 @@ bb7: // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:10)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @two_natural_loop_one_with_irreducible_loop : $@convention(thin) () -> () { bb0: br bb6 @@ -1443,7 +1600,7 @@ bb9: return %9999 : $() } -// CHECK-LABEL: @multiple_level_natural_loop_with_irreducible_loop_sandwhich@ +// CHECK-LABEL: @multiple_level_natural_loop_with_irreducible_loop_sandwich@ // CHECK: (region id:12 kind:func ucfh:false ucft:false // CHECK-NEXT: (preds) // CHECK-NEXT: (succs) @@ -1452,13 +1609,15 @@ bb9: // CHECK-NEXT: (region id:13) // CHECK-NEXT: (region id:16) // CHECK-NEXT: (region id:11)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:11 kind:bb ucfh:false ucft:false parent:12 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:16)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:16 kind:loop ucfh:false ucft:false parent:12 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:13)) @@ -1467,20 +1626,24 @@ bb9: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:9) // CHECK-NEXT: (region id:10)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:10))) // CHECK: (region id:10 kind:bb ucfh:false ucft:false parent:16 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:9 kind:bb ucfh:false ucft:false parent:16 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:10)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:13 kind:loop ucfh:false ucft:false parent:12 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -1492,14 +1655,17 @@ bb9: // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:14) // CHECK-NEXT: (region id:8)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:8))) // CHECK: (region id:8 kind:bb ucfh:false ucft:false parent:13 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:14 kind:loop ucfh:true ucft:true parent:13 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1) @@ -1510,13 +1676,16 @@ bb9: // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:15) // CHECK-NEXT: (region id:7)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4))) // CHECK: (region id:7 kind:bb ucfh:false ucft:false parent:14 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:15)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:15 kind:loop ucfh:false ucft:false parent:14 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:4)) @@ -1525,27 +1694,32 @@ bb9: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:5) // CHECK-NEXT: (region id:6)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:6))) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:15 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:5)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:15 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:true ucft:true parent:14 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:15)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:true ucft:true parent:13 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2) @@ -1555,7 +1729,8 @@ bb9: // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:14)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:true ucft:true parent:13 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1) @@ -1563,21 +1738,24 @@ bb9: // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:13 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:14)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:12 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:13)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) -sil @multiple_level_natural_loop_with_irreducible_loop_sandwhich : $@convention(thin) () -> () { +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) +sil @multiple_level_natural_loop_with_irreducible_loop_sandwich : $@convention(thin) () -> () { bb0: br bb6 @@ -1625,19 +1803,22 @@ bb12: // CHECK-NEXT: (region id:6) // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:loop ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -1647,27 +1828,33 @@ bb12: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:1) +// CHECK-NEXT: (region id:2))) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @unreachable_bb_in_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -1694,19 +1881,22 @@ bb4: // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:5) // CHECK-NEXT: (region id:6)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -1717,14 +1907,18 @@ bb4: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:9) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4) +// CHECK-NEXT: (region id:9))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:9 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -1734,33 +1928,40 @@ bb4: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2) +// CHECK-NEXT: (region id:3))) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @unreachable_bb_in_inner_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -1793,19 +1994,22 @@ bb6: // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:5) // CHECK-NEXT: (region id:6)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -1816,14 +2020,18 @@ bb6: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:9) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:4) +// CHECK-NEXT: (region id:9))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:9 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -1833,7 +2041,10 @@ bb6: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2) +// CHECK-NEXT: (region id:3))) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) @@ -1841,26 +2052,30 @@ bb6: // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs // CHECK-NEXT: (parentindex:0) -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @unreachable_bb_in_inner_loop_with_multiple_edges : $@convention(thin) () -> () { bb0: br bb1 @@ -1894,19 +2109,22 @@ bb6: // CHECK-NEXT: (region id:6) // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:loop ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -1916,27 +2134,33 @@ bb6: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:2)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:1) +// CHECK-NEXT: (region id:2))) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @noreturn_bb_in_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -1967,19 +2191,22 @@ bb4: // CHECK-NEXT: (region id:13) // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:9)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:9 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:11)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:13)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:13 kind:loop ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:11)) @@ -1988,26 +2215,31 @@ bb4: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:6) // CHECK-NEXT: (region id:7)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:7))) // CHECK: (region id:7 kind:bb ucfh:false ucft:false parent:13 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:13 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:11)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:11 kind:loop ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -2019,14 +2251,19 @@ bb4: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:12) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:1) +// CHECK-NEXT: (region id:4) +// CHECK-NEXT: (region id:12))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:12)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:2))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:12 kind:loop ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -2036,34 +2273,41 @@ bb4: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:2)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2) +// CHECK-NEXT: (region id:3))) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:12 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:12 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:12)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:10 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:11)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @noreturn_bb_in_three_level_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -2152,13 +2396,15 @@ bb4: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:6) // CHECK-NEXT: (region id:3)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:loop ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -2167,7 +2413,9 @@ bb4: // CHECK-NEXT: (subregs // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:7)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:7))) // CHECK: (region id:7 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -2176,32 +2424,38 @@ bb4: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:5 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @exit_block_that_is_a_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -2231,28 +2485,32 @@ bb4: // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:8)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:4) // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:10)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:10)) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:10 kind:loop ucfh:true ucft:true parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -2263,7 +2521,10 @@ bb4: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:11) // CHECK-NEXT: (region id:12)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:11) +// CHECK-NEXT: (region id:12))) // CHECK: (region id:12 kind:loop ucfh:false ucft:true parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -2272,20 +2533,24 @@ bb4: // CHECK-NEXT: (region id:5) // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:6))) // CHECK: (region id:6 kind:bb ucfh:false ucft:true parent:12 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:5)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:12 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:6)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:11 kind:loop ucfh:false ucft:true parent:10 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -2294,33 +2559,39 @@ bb4: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:3))) // CHECK: (region id:3 kind:bb ucfh:false ucft:true parent:11 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:11 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:true ucft:false parent:10 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:11) // CHECK-NEXT: (region id:12)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:10)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @multiple_exit_blocks_that_are_loops : $@convention(thin) () -> () { bb0: br bb1 @@ -2358,13 +2629,15 @@ bb8: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -2375,14 +2648,19 @@ bb8: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2) +// CHECK-NEXT: (region id:3) +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) @@ -2390,7 +2668,8 @@ bb8: // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -2398,19 +2677,22 @@ bb8: // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @loop_with_multiple_early_exit : $@convention(thin) () -> () { bb0: br bb1 @@ -2449,13 +2731,15 @@ bb5: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:7) // CHECK-NEXT: (region id:3)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:7 kind:loop ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -2465,13 +2749,16 @@ bb5: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:8)) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -2481,33 +2768,40 @@ bb5: // CHECK-NEXT: (region id:2) // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2) +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:6 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:7)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @loop_with_one_early_exit_from_inner_loop : $@convention(thin) () -> () { bb0: br bb1 @@ -2536,13 +2830,15 @@ bb5: // CHECK-NEXT: (region id:0) // CHECK-NEXT: (region id:8) // CHECK-NEXT: (region id:6)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:6 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:8 kind:loop ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:0)) @@ -2552,14 +2848,18 @@ bb5: // CHECK-NEXT: (region id:1) // CHECK-NEXT: (region id:9) // CHECK-NEXT: (region id:5)) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:5) +// CHECK-NEXT: (region id:9))) // CHECK: (region id:5 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:9 kind:loop ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:1)) @@ -2570,14 +2870,19 @@ bb5: // CHECK-NEXT: (region id:3) // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs +// CHECK-NEXT: (region id:2) +// CHECK-NEXT: (region id:3) +// CHECK-NEXT: (region id:4))) // CHECK: (region id:4 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (succs) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:1))) +// CHECK-NEXT: (parentindex:1)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:3 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds // CHECK-NEXT: (region id:2)) @@ -2585,26 +2890,30 @@ bb5: // CHECK-NEXT: (region id:4)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:2 kind:bb ucfh:false ucft:false parent:9 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:3)) // CHECK-NEXT: (subregs) // CHECK-NEXT: (non-local-succs -// CHECK-NEXT: (parentindex:0))) +// CHECK-NEXT: (parentindex:0)) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:1 kind:bb ucfh:false ucft:false parent:8 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:9)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) // CHECK: (region id:0 kind:bb ucfh:false ucft:false parent:7 // CHECK-NEXT: (preds) // CHECK-NEXT: (succs // CHECK-NEXT: (region id:8)) // CHECK-NEXT: (subregs) -// CHECK-NEXT: (non-local-succs)) +// CHECK-NEXT: (non-local-succs) +// CHECK-NEXT: (exiting-subregs)) sil @loop_with_multiple_early_exit_from_inner_loop : $@convention(thin) () -> () { bb0: br bb1 diff --git a/test/SILOptimizer/loop_canonicalizer.sil b/test/SILOptimizer/loop_canonicalizer.sil new file mode 100644 index 0000000000000..f2446e730831b --- /dev/null +++ b/test/SILOptimizer/loop_canonicalizer.sil @@ -0,0 +1,243 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -compute-dominance-info -compute-loop-info -loop-canonicalizer %s | FileCheck %s + +sil_stage canonical + +import Builtin + +// CHECK-LABEL: sil @insert_preheader_1 : $@convention(thin) () -> () { +// CHECK: bb0: +// CHECK: cond_br undef, bb1, bb4 +// CHECK: bb1: +// CHECK: br bb2 +// CHECK: bb2: +// CHECK: cond_br undef, bb2, bb3 +// CHECK: bb3: +// CHECK: br bb4 +// CHECK: bb4: +// CHECK: return undef +sil @insert_preheader_1 : $@convention(thin) () -> () { +bb0: + cond_br undef, bb1, bb3 + +// A bb will be inserted along the edge from bb0 -> bb1. +bb1: + cond_br undef, bb1, bb2 + +// This is the exit block of the loop on bb1. We do this so this test *only* +// tests the preheader insertion vs the exit block canonicalization. +bb2: + br bb3 + +bb3: + return undef : $() +} + +// Make sure that we insert the pre-header correctly given a header with +// multiple predecessors. +// +// CHECK-LABEL: sil @insert_preheader_2 : $@convention(thin) () -> () { +// CHECK: bb0: +// CHECK: cond_br undef, bb1, [[PREHEADER:bb[0-9]+]] +// CHECK: bb1: +// CHECK: br [[PREHEADER]] +// CHECK: [[PREHEADER]]: +// CHECK: br bb3 +// CHECK: bb3: +// CHECK: cond_br undef, bb3, bb4 +// CHECK: return undef : $() +sil @insert_preheader_2 : $@convention(thin) () -> () { +bb0: + cond_br undef, bb1, bb2 + +bb1: + br bb2 + +bb2: + cond_br undef, bb2, bb3 + +bb3: + return undef : $() +} + +// Make sure that we can handle pre-header insertion for loops in sequence +// (i.e. where one loop branches into another loop) correctly in terms of +// updating loop info. +// +// CHECK-LABEL: sil @insert_preheader_3 : $@convention(thin) () -> () { +// CHECK: bb0: +// CHECK: cond_br undef, bb1, bb4 +// CHECK: bb1: +// CHECK: br bb2 +// CHECK: bb2: +// CHECK: cond_br undef, bb2, bb3 +// CHECK: bb3: +// CHECK: br bb7 +// CHECK: bb4: +// CHECK: br bb5 +// CHECK: bb5: +// CHECK: cond_br undef, bb5, bb6 +// CHECK: bb6: +// CHECK: br bb7 +// CHECK: bb7 +// CHECK: br bb8 +// CHECK: bb8: +// CHECK: cond_br undef, bb8, bb9 +// CHECK: bb9: +// CHECK: return undef +sil @insert_preheader_3 : $@convention(thin) () -> () { +bb0: + cond_br undef, bb1, bb2 + +bb1: + cond_br undef, bb1, bb3 + +bb2: + cond_br undef, bb2, bb3 + +bb3: + cond_br undef, bb3, bb4 + +bb4: + return undef : $() +} + +// Make sure that we insert pre-headers correctly for nested loops I am using +// patterns in more places than I need to, to make the test case more obvious to +// the reader. +// +// CHECK-LABEL: sil @insert_preheader_4 : $@convention(thin) () -> () { +// CHECK: bb0: +// CHECK: br bb1 +// CHECK: bb1: +// CHECK: cond_br undef, bb2, [[PREHEADER_1:bb[0-9]+]] +// CHECK: bb2: +// CHECK: br [[PREHEADER_1]] +// First pre-header +// CHECK: [[PREHEADER_1]]: +// CHECK: br bb4 +// CHECK: bb4: +// CHECK: cond_br undef, bb8, [[PREHEADER_2:bb[0-9]+]] +// CHECK: [[PREHEADER_2]]: +// CHECK: br bb6 +// CHECK: bb6: +// CHECK: cond_br undef, bb6, bb7 +// This is an exit bb for bb6. +// CHECK: bb7: +// CHECK: cond_br undef, bb8, bb9 +// CHECK: bb8: +// CHECK: br bb4 +// CHECK: bb9: +// CHECK: return undef +sil @insert_preheader_4 : $@convention(thin) () -> () { +bb0: + br bb1 + +bb1: + cond_br undef, bb2, bb3 + +bb2: + br bb3 + +bb3: + cond_br undef, bb3, bb4 + +bb4: + cond_br undef, bb4, bb5 + +bb5: + cond_br undef, bb3, bb6 + +bb6: + return undef : $() +} + +// Test insertBackedgeBlock. +// +// CHECK-LABEL: insert_backedge_block +// CHECK: bb2: +// CHECK: cond_br undef, bb3, bb4 +// CHECK: bb3: +// CHECK: br bb1 +// CHECK: bb4: +// CHECK: cond_br undef, bb3, bb5 +sil @insert_backedge_block : $@convention(thin) () -> () { +bb0: + br bb1 + +bb1: + br bb2 + +bb2: + cond_br undef, bb1, bb3 + +bb3: + cond_br undef, bb1, bb4 + +bb4: + return undef : $() +} + +// CHECK-LABEL: sil @insert_backedge_block_inner_loop : $@convention(thin) () -> () { +// CHECK: bb1: +// CHECK: br bb2 +// CHECK: bb2: +// CHECK: br bb3 +// CHECK: bb3: +// CHECK: cond_br undef, bb4, bb5 +// CHECK: bb4: +// CHECK: br bb2 +// CHECK: bb5: +// CHECK: cond_br undef, bb4, bb6 +// CHECK: bb6: +// CHECK: cond_br undef, bb1, bb7 +// CHECK: bb7: +// CHECK: return undef +sil @insert_backedge_block_inner_loop : $@convention(thin) () -> () { +bb0: + br bb1 + +bb1: + br bb2 + +bb2: + br bb3 + +bb3: + cond_br undef, bb2, bb4 + +bb4: + cond_br undef, bb2, bb5 + +bb5: + cond_br undef, bb1, bb6 + +bb6: + return undef : $() +} + +// CHECK-LABEL: sil @exit_blocks_should_only_have_exiting_blocks_as_predecessors : $@convention(thin) () -> () { +// CHECK: bb0: +// CHECK: cond_br undef, bb1, bb4 +// CHECK: bb1: +// CHECK: br bb2 +// CHECK: bb2: +// CHECK: cond_br undef, bb2, bb3 +// CHECK: bb3: +// CHECK: br bb4 +// CHECK: bb4: +// CHECK: return undef +sil @exit_blocks_should_only_have_exiting_blocks_as_predecessors : $@convention(thin) () -> () { +bb0: + cond_br undef, bb1, bb3 + +// Header +bb1: + br bb2 + +bb2: + cond_br undef, bb2, bb3 + +// Exit with multiple predecessors. The edge from bb2 -> bb3 will be split. +bb3: + return undef : $() +} diff --git a/test/SILPasses/loop_info_printer.sil b/test/SILOptimizer/loop_info_printer.sil similarity index 100% rename from test/SILPasses/loop_info_printer.sil rename to test/SILOptimizer/loop_info_printer.sil diff --git a/test/SILOptimizer/loop_unroll.sil b/test/SILOptimizer/loop_unroll.sil new file mode 100644 index 0000000000000..2f55bdc9e3a31 --- /dev/null +++ b/test/SILOptimizer/loop_unroll.sil @@ -0,0 +1,72 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -loop-unroll %s | FileCheck %s + +sil_stage canonical + +import Builtin + +// CHECK-LABEL: sil @loop_unroll_1 +// CHECK: bb0 +// CHECK: br bb1 +// CHECK: bb1 +// CHECK: builtin "sadd_with_overflow_Int64 +// CHECK: cond_br {{.*}}, bb2, bb3 +// CHECK: bb2: +// CHECK: return +// CHECK: bb3 +// CHECK: builtin "sadd_with_overflow_Int64 +// CHECK: br bb2 + +sil @loop_unroll_1 : $@convention(thin) () -> () { +bb0: + %0 = integer_literal $Builtin.Int64, 0 + %1 = integer_literal $Builtin.Int64, 1 + %2 = integer_literal $Builtin.Int64, 2 + %3 = integer_literal $Builtin.Int1, 1 + br bb1(%0 : $Builtin.Int64) + +bb1(%4 : $Builtin.Int64): + %5 = builtin "sadd_with_overflow_Int64"(%4 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %6 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 0 + %7 = builtin "cmp_eq_Int64"(%6 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int1 + cond_br %7, bb2, bb1(%6 : $Builtin.Int64) + +bb2: + %8 = tuple() + return %8 : $() +} + +// CHECK-LABEL: sil @loop_unroll_2 +// CHECK: bb0: +// CHECK: br bb1 +// CHECK: bb1 +// CHECK: = builtin "sadd_with_overflow_Int64 +// CHECK: cond_br {{.*}}, bb3, bb2 +// CHECK: bb2: +// CHECK: br bb4 +// CHECK: bb3: +// CHECK: return +// CHECK: bb4 +// CHECK: = builtin "sadd_with_overflow_Int64 +// CHECK: br bb3 + +sil @loop_unroll_2 : $@convention(thin) () -> () { +bb0: + %0 = integer_literal $Builtin.Int64, 0 + %1 = integer_literal $Builtin.Int64, 1 + %2 = integer_literal $Builtin.Int64, 2 + %3 = integer_literal $Builtin.Int1, 1 + br bb1(%0 : $Builtin.Int64) + +bb1(%4 : $Builtin.Int64): + %5 = builtin "sadd_with_overflow_Int64"(%4 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %6 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 0 + %7 = builtin "cmp_eq_Int64"(%6 : $Builtin.Int64, %2 : $Builtin.Int64) : $Builtin.Int1 + cond_br %7, bb3, bb2 + +bb2: + br bb1(%6 : $Builtin.Int64) + +bb3: + %8 = tuple() + return %8 : $() +} diff --git a/test/SILPasses/looprotate.sil b/test/SILOptimizer/looprotate.sil similarity index 100% rename from test/SILPasses/looprotate.sil rename to test/SILOptimizer/looprotate.sil diff --git a/test/SILPasses/loweraggregateinstrs.sil b/test/SILOptimizer/loweraggregateinstrs.sil similarity index 100% rename from test/SILPasses/loweraggregateinstrs.sil rename to test/SILOptimizer/loweraggregateinstrs.sil diff --git a/test/SILOptimizer/lslocation_expansion.sil b/test/SILOptimizer/lslocation_expansion.sil new file mode 100644 index 0000000000000..c242cd4321bac --- /dev/null +++ b/test/SILOptimizer/lslocation_expansion.sil @@ -0,0 +1,303 @@ +// RUN: %target-sil-opt %s -lslocation-dump -ml=only-expansion | FileCheck %s + +sil_stage canonical + +import Builtin + +/////////////////////// +// Type Declarations // +/////////////////////// + +struct Int { + var value : Builtin.Int64 +} + +struct Int64 { + var value : Builtin.Int64 +} + +struct Bool { + var value : Builtin.Int1 +} + +class B { + var i : Builtin.Int32 + init() +} + +struct S1 { + var a: Int + init(a: Int, b: Int) + init() +} + +struct S2 { + var a: Int + var b: Int + init(a: Int, b: Int) + init() +} + +struct S3 { + var a: S2 + var b: Int + var c: S2 + init(a: S2, b: Int, c: S2) + init() +} + +struct S4 { + var x: S3 + var y: S3 + init(x: S3, y: S3) + init() +} + +class SelfLoop { + var a: Int + var b: Int + var c: SelfLoop + deinit + init() +} + +struct S5 { + var a: SelfLoop + init(a: SelfLoop) + init() +} + +sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1 +sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2 +sil @S3_init : $@convention(thin) (@thin S3.Type) -> S3 +sil @S4_init : $@convention(thin) (@thin S4.Type) -> S4 +sil @S5_init : $@convention(thin) (@thin S5.Type) -> S5 + +// CHECK-LABEL: @stack_store +// CHECK: #0 store +// CHECK-NEXT: alloc_stack +sil @stack_store : $@convention(thin) () -> () { + %1 = alloc_stack $Builtin.Int64 + %9 = integer_literal $Builtin.Int64, 0 + store %9 to %1 : $*Builtin.Int64 + %4 = tuple() + dealloc_stack %1 : $*Builtin.Int64 // id: %13 + %5 = return %4 : $() +} + +// CHECK-LABEL: @store_after_store +// CHECK: #0 store +// CHECK-NEXT: [[RET0:%.+]] = alloc_box +// CHECK: #1 store +// CHECK-NEXT: [[RET0:%.+]] = alloc_box +sil @store_after_store : $@convention(thin) (@owned B) -> () { +bb0(%0 : $B): + %1 = alloc_box $B + %2 = store %0 to %1#1 : $*B + %3 = store %0 to %1#1 : $*B + %4 = tuple() + %5 = return %4 : $() +} + +// CHECK-LABEL: @store_after_store_struct +// CHECK: #0 store +// CHECK-NEXT: [[RET0:%.+]] = alloc_stack +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK: #1 store +// CHECK-NEXT: [[RET0:%.+]] = alloc_stack +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +sil @store_after_store_struct : $@convention(thin) () -> () { + %1 = alloc_stack $S1 + %9 = integer_literal $Builtin.Int64, 0 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %1 : $*S1, #S1.a // user: %12 + store %10 to %11 : $*Int // id: %12 + store %10 to %11 : $*Int + %4 = tuple() + dealloc_stack %1 : $*S1 // id: %13 + %5 = return %4 : $() +} + +// Make sure all the structs get expanded correctly. +// +// CHECK-LABEL: @many_struct_allocs +// CHECK: #0 store +// CHECK-NEXT: alloc_stack $S2 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: alloc_stack $S2 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK: #1 store +// CHECK-NEXT: alloc_stack $S3 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var c: S2 +// CHECK-NEXT: alloc_stack $S3 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var c: S2 +// CHECK-NEXT: alloc_stack $S3 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: alloc_stack $S3 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: alloc_stack $S3 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK: #2 store +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var c: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var y: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var c: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var y: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var y: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var y: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var y: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var c: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var x: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var c: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var x: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var x: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var x: S3 +// CHECK-NEXT: alloc_stack $S4 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Field Type: var x: S3 +sil hidden @many_struct_allocs : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S2, var, name "a" // users: %6, %18 + %1 = alloc_stack $S3, var, name "b" // users: %10, %17 + %2 = alloc_stack $S4, var, name "c" // users: %14, %16 + %3 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %5 + %4 = metatype $@thin S2.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S2.Type) -> S2 // user: %6 + store %5 to %0 : $*S2 // id: %6 + // function_ref struct.S3.init (struct.S3.Type)() -> struct.S3 + %7 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %9 + %8 = metatype $@thin S3.Type // user: %9 + %9 = apply %7(%8) : $@convention(thin) (@thin S3.Type) -> S3 // user: %10 + store %9 to %1 : $*S3 // id: %10 + %11 = function_ref @S4_init : $@convention(thin) (@thin S4.Type) -> S4 // user: %13 + %12 = metatype $@thin S4.Type // user: %13 + %13 = apply %11(%12) : $@convention(thin) (@thin S4.Type) -> S4 // user: %14 + store %13 to %2 : $*S4 // id: %14 + %15 = tuple () // user: %19 + dealloc_stack %2 : $*S4 // id: %16 + dealloc_stack %1 : $*S3 // id: %17 + dealloc_stack %0 : $*S2 // id: %18 + return %15 : $() // id: %19 +} + +// CHECK-LABEL: self_loop +// CHECK: #0 store +// CHECK-NEXT: alloc_stack $S5, var, name "b" // users: %4, %7 +// CHECK-NEXT: Address Projection Type: $*SelfLoop +// CHECK-NEXT: Field Type: var a: SelfLoop +sil hidden @self_loop : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S5, var, name "b" // users: %4, %7 + %1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> S5 // user: %3 + %2 = metatype $@thin S5.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> S5 // users: %4, %5 + store %3 to %0 : $*S5 // id: %4 + release_value %3 : $S5 // id: %5 + %6 = tuple () // user: %8 + dealloc_stack %0 : $*S5 // id: %7 + return %6 : $() // id: %8 +} diff --git a/test/SILOptimizer/lslocation_reduction.sil b/test/SILOptimizer/lslocation_reduction.sil new file mode 100644 index 0000000000000..efd6661ecc714 --- /dev/null +++ b/test/SILOptimizer/lslocation_reduction.sil @@ -0,0 +1,171 @@ +// RUN: %target-sil-opt %s -lslocation-dump -ml=only-reduction | FileCheck %s + +sil_stage canonical + +import Builtin + +/////////////////////// +// Type Declarations // +/////////////////////// + +struct Int { + var value : Builtin.Int64 +} + +struct Int64 { + var value : Builtin.Int64 +} + +struct Bool { + var value : Builtin.Int1 +} + +class B { + var i : Builtin.Int32 + init() +} + +struct S1 { + var a: Int + init(a: Int, b: Int) + init() +} + +struct S2 { + var a: Int + var b: Int + init(a: Int, b: Int) + init() +} + +struct S3 { + var a: S2 + var b: Int + var c: S2 + init(a: S2, b: Int, c: S2) + init() +} + +struct S4 { + var x: S3 + var y: S3 + init(x: S3, y: S3) + init() +} + +class SelfLoop { + var a: Int + var b: Int + var c: SelfLoop + deinit + init() +} + +struct S5 { + var a: SelfLoop + init(a: SelfLoop) + init() +} + +sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1 +sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2 +sil @S3_init : $@convention(thin) (@thin S3.Type) -> S3 +sil @S4_init : $@convention(thin) (@thin S4.Type) -> S4 +sil @S5_init : $@convention(thin) (@thin S5.Type) -> S5 + +// CHECK-LABEL: @stack_store +// CHECK: #0 store +// CHECK-NEXT: alloc_stack +sil @stack_store : $@convention(thin) () -> () { + %1 = alloc_stack $Builtin.Int64 + %9 = integer_literal $Builtin.Int64, 0 + store %9 to %1 : $*Builtin.Int64 + %4 = tuple() + dealloc_stack %1 : $*Builtin.Int64 // id: %13 + %5 = return %4 : $() +} + +// CHECK-LABEL: @store_after_store +// CHECK: #0 store +// CHECK-NEXT: [[RET0:%.+]] = alloc_box +// CHECK: #1 store +// CHECK-NEXT: [[RET0:%.+]] = alloc_box +sil @store_after_store : $@convention(thin) (@owned B) -> () { +bb0(%0 : $B): + %1 = alloc_box $B + %2 = store %0 to %1#1 : $*B + %3 = store %0 to %1#1 : $*B + %4 = tuple() + %5 = return %4 : $() +} + +// CHECK-LABEL: @store_after_store_struct +// CHECK: #0 store +// CHECK-NEXT: [[RET0:%.+]] = alloc_stack +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK: #1 store +// CHECK-NEXT: [[RET0:%.+]] = alloc_stack +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +sil @store_after_store_struct : $@convention(thin) () -> () { + %1 = alloc_stack $S1 + %9 = integer_literal $Builtin.Int64, 0 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %1 : $*S1, #S1.a // user: %12 + store %10 to %11 : $*Int // id: %12 + store %10 to %11 : $*Int + %4 = tuple() + dealloc_stack %1 : $*S1 // id: %13 + %5 = return %4 : $() +} + +// Make sure all the structs get expanded correctly. +// +// CHECK-LABEL: @many_struct_allocs +// CHECK: #0 store +// CHECK-NEXT: alloc_stack $S2 +// CHECK: #1 store +// CHECK-NEXT: alloc_stack $S3 +// CHECK: #2 store +// CHECK-NEXT: alloc_stack $S4 +sil hidden @many_struct_allocs : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S2, var, name "a" // users: %6, %18 + %1 = alloc_stack $S3, var, name "b" // users: %10, %17 + %2 = alloc_stack $S4, var, name "c" // users: %14, %16 + %3 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %5 + %4 = metatype $@thin S2.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin S2.Type) -> S2 // user: %6 + store %5 to %0 : $*S2 // id: %6 + // function_ref struct.S3.init (struct.S3.Type)() -> struct.S3 + %7 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %9 + %8 = metatype $@thin S3.Type // user: %9 + %9 = apply %7(%8) : $@convention(thin) (@thin S3.Type) -> S3 // user: %10 + store %9 to %1 : $*S3 // id: %10 + %11 = function_ref @S4_init : $@convention(thin) (@thin S4.Type) -> S4 // user: %13 + %12 = metatype $@thin S4.Type // user: %13 + %13 = apply %11(%12) : $@convention(thin) (@thin S4.Type) -> S4 // user: %14 + store %13 to %2 : $*S4 // id: %14 + %15 = tuple () // user: %19 + dealloc_stack %2 : $*S4 // id: %16 + dealloc_stack %1 : $*S3 // id: %17 + dealloc_stack %0 : $*S2 // id: %18 + return %15 : $() // id: %19 +} + +// CHECK-LABEL: self_loop +// CHECK: #0 store +// CHECK-NEXT: alloc_stack $S5, var, name "b" // users: %4, %7 +sil hidden @self_loop : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S5, var, name "b" // users: %4, %7 + %1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> S5 // user: %3 + %2 = metatype $@thin S5.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> S5 // users: %4, %5 + store %3 to %0 : $*S5 // id: %4 + release_value %3 : $S5 // id: %5 + %6 = tuple () // user: %8 + dealloc_stack %0 : $*S5 // id: %7 + return %6 : $() // id: %8 +} diff --git a/test/SILOptimizer/lslocation_type_only_expansion.sil b/test/SILOptimizer/lslocation_type_only_expansion.sil new file mode 100644 index 0000000000000..3bea193e13d20 --- /dev/null +++ b/test/SILOptimizer/lslocation_type_only_expansion.sil @@ -0,0 +1,362 @@ +// RUN: %target-sil-opt %s -lslocation-dump -ml=only-type-expansion | FileCheck %s +// RUN: %target-sil-opt %s -lslocation-dump-use-new-projection -lslocation-dump -ml=only-type-expansion | FileCheck %s + +sil_stage canonical + +import Builtin + +struct Int { + var value : Builtin.Int64 +} + +struct Int32{ + var value : Builtin.Int32 +} + +struct Int64 { + var value : Builtin.Int64 +} + +struct Bool { + var value : Builtin.Int1 +} + +struct S1 { + var a: Int + var b: Int + init(a: Int, b: Int) + init() +} + +struct S2 { + var a: Int + var b: S1 + init(a: Int, b: S1) + init() +} + +class C1 { + var a : Int + deinit + init(a: Int) +} + +struct S3 { + var c: C1 + var a: S2 + var b: C1 + init(c: C1, a: S2, b: C1) + init() +} + +struct S4 { + var c: (Int, Int, S1) + init(c: (Int, Int, S1)) + init() +} + +struct S5 { + var c: (Int, Int, S3) + init(c: (Int, Int, S3)) + init() +} + +struct S6 { + var tuple: (Int, Int) +} + +enum Example { + case A(Int64) + case B(Int32) +} + + +sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1 +sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2 +sil @C1_init : $@convention(thin) (@thick C1.Type) -> @owned C1 +sil @S3_init : $@convention(thin) (@thin S3.Type) -> @owned S3 +sil @S4_init : $@convention(thin) (@thin S4.Type) -> @owned S4 +sil @S5_init : $@convention(thin) (@thin S5.Type) -> @owned S5 +sil @S6_init : $@convention(thin) (@thin S6.Type) -> S6 + +// CHECK-LABEL: @test_struct_type_expansion +// CHECK: #0 store +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK: #1 store +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S1 +// CHECK-NEXT: Field Type: var b: S1 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S1 +// CHECK-NEXT: Field Type: var b: S1 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +sil hidden @test_struct_type_expansion : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S1, var, name "a" // users: %5, %12 + %1 = alloc_stack $S2, var, name "b" // users: %9, %11 + %2 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %4 + %3 = metatype $@thin S1.Type // user: %4 + %4 = apply %2(%3) : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 + store %4 to %0 : $*S1 // id: %5 + %6 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %8 + %7 = metatype $@thin S2.Type // user: %8 + %8 = apply %6(%7) : $@convention(thin) (@thin S2.Type) -> S2 // user: %9 + store %8 to %1 : $*S2 // id: %9 + %10 = tuple () // user: %13 + dealloc_stack %1 : $*S2 // id: %11 + dealloc_stack %0 : $*S1 // id: %12 + return %10 : $() // id: %13 +} + +// Make sure we do not expand the reference type. +// +// CHECK-LABEL: test_class_stack_slot +// CHECK: #0 store +// CHECK-NOT: var +// CHECK: #1 store +sil hidden @test_class_stack_slot : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $C1, var, name "a" // users: %4, %7 + %1 = function_ref @C1_init : $@convention(thin) (@thick C1.Type) -> @owned C1 // user: %3 + %2 = metatype $@thick C1.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thick C1.Type) -> @owned C1 // users: %4, %5 + store %3 to %0 : $*C1 // id: %4 + store %3 to %0 : $*C1 // id: %4 + strong_release %3 : $C1 // id: %5 + %6 = tuple () // user: %8 + dealloc_stack %0 : $*C1 // id: %7 + return %6 : $() // id: %8 +} + +// CHECK-LABEL: test_struct_and_class_slot +// CHECK: #0 store +// CHECK-NEXT: Address Projection Type: $*C1 +// CHECK-NEXT: Field Type: var b: C1 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S1 +// CHECK-NEXT: Field Type: var b: S1 +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S1 +// CHECK-NEXT: Field Type: var b: S1 +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*C1 +// CHECK-NEXT: Field Type: var c: C1 +sil hidden @test_struct_and_class_slot : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S3, var, name "a" // users: %4, %7 + // function_ref test.S3.init (test.S3.Type)() -> test.S3 + %1 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> @owned S3 // user: %3 + %2 = metatype $@thin S3.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S3.Type) -> @owned S3 // users: %4, %5 + store %3 to %0 : $*S3 // id: %4 + release_value %3 : $S3 // id: %5 + %6 = tuple () // user: %8 + dealloc_stack %0 : $*S3 // id: %7 + return %6 : $() // id: %8 +} + +// Test tuple expansion. +// +// CHECK-LABEL: test_tuple +// CHECK: #0 store +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S1 +// CHECK-NEXT: Index: 2 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S1) +// CHECK-NEXT: Field Type: var c: (Int, Int, S1) +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S1 +// CHECK-NEXT: Index: 2 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S1) +// CHECK-NEXT: Field Type: var c: (Int, Int, S1) +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Index: 1 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S1) +// CHECK-NEXT: Field Type: var c: (Int, Int, S1) +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Index: 0 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S1) +// CHECK-NEXT: Field Type: var c: (Int, Int, S1) +sil hidden @test_tuple : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S4, var, name "x" // users: %4, %7 + // function_ref test.S4.init (test.S4.Type)() -> test.S4 + %1 = function_ref @S4_init : $@convention(thin) (@thin S4.Type) -> @owned S4 // user: %3 + %2 = metatype $@thin S4.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S4.Type) -> @owned S4 // users: %4, %5 + store %3 to %0 : $*S4 // id: %4 + release_value %3 : $S4 // id: %5 + %6 = tuple () // user: %8 + dealloc_stack %0 : $*S4 // id: %7 + return %6 : $() // id: %8 +} + +// CHECK-LABEL: tuple_test_with_reference +// CHECK: #0 store +// CHECK-NEXT: Address Projection Type: $*C1 +// CHECK-NEXT: Field Type: var b: C1 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Index: 2 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) +// CHECK-NEXT: Field Type: var c: (Int, Int, S3) +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var b: Int +// CHECK-NEXT: Address Projection Type: $*S1 +// CHECK-NEXT: Field Type: var b: S1 +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Index: 2 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) +// CHECK-NEXT: Field Type: var c: (Int, Int, S3) +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S1 +// CHECK-NEXT: Field Type: var b: S1 +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Index: 2 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) +// CHECK-NEXT: Field Type: var c: (Int, Int, S3) +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Field Type: var a: Int +// CHECK-NEXT: Address Projection Type: $*S2 +// CHECK-NEXT: Field Type: var a: S2 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Index: 2 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) +// CHECK-NEXT: Field Type: var c: (Int, Int, S3) +// CHECK-NEXT: Address Projection Type: $*C1 +// CHECK-NEXT: Field Type: var c: C1 +// CHECK-NEXT: Address Projection Type: $*S3 +// CHECK-NEXT: Index: 2 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) +// CHECK-NEXT: Field Type: var c: (Int, Int, S3) +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Index: 1 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) +// CHECK-NEXT: Field Type: var c: (Int, Int, S3) +// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +// CHECK-NEXT: Field Type: var value: Int64 +// CHECK-NEXT: Address Projection Type: $*Int +// CHECK-NEXT: Index: 0 +// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) +// CHECK-NEXT: Field Type: var c: (Int, Int, S3) +sil hidden @tuple_test_with_reference : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S5, var, name "x" // users: %4, %7 + // function_ref test.S5.init (test.S5.Type)() -> test.S5 + %1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> @owned S5 // user: %3 + %2 = metatype $@thin S5.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> @owned S5 // users: %4, %5 + store %3 to %0 : $*S5 // id: %4 + release_value %3 : $S5 // id: %5 + %6 = tuple () // user: %8 + dealloc_stack %0 : $*S5 // id: %7 + return %6 : $() // id: %8 +} + +/// CHECK-LABEL: tuple_inside_struct +/// CHECK: #0 store +/// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +/// CHECK-NEXT: Field Type: var value: Int64 +/// CHECK-NEXT: Address Projection Type: $*Int +/// CHECK-NEXT: Index: 1 +/// CHECK-NEXT: Address Projection Type: $*(Int, Int) +/// CHECK-NEXT: Field Type: var tuple: (Int, Int) +/// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +/// CHECK-NEXT: Field Type: var value: Int64 +/// CHECK-NEXT: Address Projection Type: $*Int +/// CHECK-NEXT: Index: 0 +/// CHECK-NEXT: Address Projection Type: $*(Int, Int) +/// CHECK-NEXT: Field Type: var tuple: (Int, Int) +sil hidden @tuple_inside_struct : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $S6, var, name "x" // users: %4, %7 + %1 = function_ref @S6_init : $@convention(thin) (@thin S6.Type) -> S6 // user: %3 + %2 = metatype $@thin S6.Type // user: %3 + %3 = apply %1(%2) : $@convention(thin) (@thin S6.Type) -> S6 // users: %4, %5 + store %3 to %0 : $*S6 // id: %4 + %6 = tuple () // user: %8 + dealloc_stack %0 : $*S6 // id: %7 + return %6 : $() // id: %8 +} + +/// Given an enum type, we expands it into nothing as its meaningless to call +/// getStoredProperties on enum without specifying the tag. Enum is sort of +/// like union in C, i.e. its memory can be interpreted differently depending +/// on the chosen tag. +/// +/// CHECK-LABEL: enum_test +/// CHECK: #0 store +/// CHECK-NOT: Int64 +/// CHECK-NOT: Int32 +/// CHECK: #1 store +/// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 +/// CHECK-NEXT: Field Type: var value: Int64 +sil hidden @enum_test : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $Example, var, name "ee" // users: %5, %11 + %1 = alloc_stack $Int, var, name "a" // users: %8, %10 + %2 = integer_literal $Builtin.Int64, 10 // user: %3 + %3 = struct $Int64 (%2 : $Builtin.Int64) // user: %4 + %4 = enum $Example, #Example.A!enumelt.1, %3 : $Int64 // user: %5 + store %4 to %0 : $*Example // id: %5 + %6 = integer_literal $Builtin.Int64, 10 // user: %7 + %7 = struct $Int (%6 : $Builtin.Int64) // user: %8 + store %7 to %1 : $*Int // id: %8 + %9 = tuple () // user: %12 + dealloc_stack %1 : $*Int // id: %10 + dealloc_stack %0 : $*Example // id: %11 + return %9 : $() // id: %12 +} diff --git a/test/SILPasses/mandatory_inlining.sil b/test/SILOptimizer/mandatory_inlining.sil similarity index 92% rename from test/SILPasses/mandatory_inlining.sil rename to test/SILOptimizer/mandatory_inlining.sil index 60592ec3242e5..449eeb01491d4 100644 --- a/test/SILPasses/mandatory_inlining.sil +++ b/test/SILOptimizer/mandatory_inlining.sil @@ -153,10 +153,10 @@ bb0(%0 : $*SomeProtocol): %1 = alloc_box $SomeProtocol copy_addr [take] %0 to [initialization] %1#1 : $*SomeProtocol %4 = alloc_stack $SomeProtocol - copy_addr %1#1 to [initialization] %4#1 : $*SomeProtocol - %6 = existential_metatype $@thick SomeProtocol.Type, %4#1 : $*SomeProtocol - destroy_addr %4#1 : $*SomeProtocol - dealloc_stack %4#0 : $*@local_storage SomeProtocol + copy_addr %1#1 to [initialization] %4 : $*SomeProtocol + %6 = existential_metatype $@thick SomeProtocol.Type, %4 : $*SomeProtocol + destroy_addr %4 : $*SomeProtocol + dealloc_stack %4 : $*SomeProtocol strong_release %1#0 : $@box SomeProtocol return %6 : $@thick SomeProtocol.Type } @@ -167,10 +167,10 @@ sil @inline_test_existential_metatype : $@convention(thin) (@in SomeProtocol) -> // CHECK: [[VAL1:%.*]] = alloc_box $SomeProtocol // CHECK: copy_addr [take] %0 to [initialization] [[VAL1]]#1 // CHECK: [[VAL4:%.*]] = alloc_stack $SomeProtocol - // CHECK: copy_addr [[VAL1]]#1 to [initialization] [[VAL4]]#1 - // CHECK: [[VAL6:%.*]] = existential_metatype $@thick SomeProtocol.Type, [[VAL4]]#1 - // CHECK: destroy_addr [[VAL4]]#1 - // CHECK: dealloc_stack [[VAL4]]#0 + // CHECK: copy_addr [[VAL1]]#1 to [initialization] [[VAL4]] + // CHECK: [[VAL6:%.*]] = existential_metatype $@thick SomeProtocol.Type, [[VAL4]] + // CHECK: destroy_addr [[VAL4]] + // CHECK: dealloc_stack [[VAL4]] // CHECK: strong_release [[VAL1]]#0 // CHECK: return [[VAL6]] @@ -207,9 +207,9 @@ bb0(%0 : $Float, %1 : $Float): %9 = load %3#1 : $*Float %10 = apply %7(%8, %9) : $@convention(thin) (Float, Float) -> Bool %11 = alloc_stack $Bool - store %10 to %11#1 : $*Bool - %13 = apply %6(%11#1) : $@convention(method) (@inout Bool) -> Builtin.Int1 - dealloc_stack %11#0 : $*@local_storage Bool + store %10 to %11 : $*Bool + %13 = apply %6(%11) : $@convention(method) (@inout Bool) -> Builtin.Int1 + dealloc_stack %11 : $*Bool cond_br %13, bb1, bb2 bb1: @@ -225,9 +225,9 @@ bb3: %21 = load %3#1 : $*Float %22 = apply %20(%21) : $@convention(thin) (Float) -> Bool %23 = alloc_stack $Bool - store %22 to %23#1 : $*Bool - %25 = apply %19(%23#1) : $@convention(method) (@inout Bool) -> Builtin.Int1 - dealloc_stack %23#0 : $*@local_storage Bool + store %22 to %23 : $*Bool + %25 = apply %19(%23) : $@convention(method) (@inout Bool) -> Builtin.Int1 + dealloc_stack %23 : $*Bool cond_br %25, bb4, bb5 bb4: @@ -279,9 +279,9 @@ sil @inline_test_control_flow : $@convention(thin) (Float) -> Float { // CHECK: [[VAL22:%.*]] = load [[VAL16]]#1 // CHECK: [[VAL23:%.*]] = apply [[VAL20]]([[VAL21]], [[VAL22]]) // CHECK: [[VAL24:%.*]] = alloc_stack $Bool - // CHECK: store [[VAL23]] to [[VAL24]]#1 - // CHECK: [[VAL26:%.*]] = apply [[VAL19]]([[VAL24]]#1) - // CHECK: dealloc_stack [[VAL24]]#0 + // CHECK: store [[VAL23]] to [[VAL24]] + // CHECK: [[VAL26:%.*]] = apply [[VAL19]]([[VAL24]]) + // CHECK: dealloc_stack [[VAL24]] // CHECK: cond_br [[VAL26]], [[BB1:bb[0-9]+]], [[BB2:bb[0-9]+]] // CHECK: [[BB1]]: @@ -297,9 +297,9 @@ sil @inline_test_control_flow : $@convention(thin) (Float) -> Float { // CHECK: [[VAL34:%.*]] = load [[VAL16]]#1 // CHECK: [[VAL35:%.*]] = apply [[VAL33]]([[VAL34]]) // CHECK: [[VAL36:%.*]] = alloc_stack $Bool - // CHECK: store [[VAL35]] to [[VAL36]]#1 - // CHECK: [[VAL38:%.*]] = apply [[VAL32]]([[VAL36]]#1) - // CHECK: dealloc_stack [[VAL36]]#0 + // CHECK: store [[VAL35]] to [[VAL36]] + // CHECK: [[VAL38:%.*]] = apply [[VAL32]]([[VAL36]]) + // CHECK: dealloc_stack [[VAL36]] // CHECK: cond_br [[VAL38]], [[BB4:bb[0-9]+]], [[BB5:bb[0-9]+]] // CHECK: [[BB4]]: @@ -449,8 +449,9 @@ bb3(%16 : $Bool): return %16 : $Bool } -sil private [transparent] @closure0 : $@convention(thin) (@owned @box Bool, @inout Bool) -> Bool { -bb0(%0 : $@box Bool, %1 : $*Bool): +sil private [transparent] @closure0 : $@convention(thin) (@owned @box Bool) -> Bool { +bb0(%0 : $@box Bool): + %1 = project_box %0 : $@box Bool %2 = tuple () %3 = load %1 : $*Bool strong_release %0 : $@box Bool @@ -471,8 +472,9 @@ sil @test_short_circuit : $@convention(thin) (Bool, Bool) -> Bool { // CHECK: [[BB3]]: // CHECK: strong_retain [[VAL3:.*]]#0 + // CHECK: [[ADDR3:%.*]] = project_box [[VAL3]]#0 // CHECK: {{%.*}} = tuple () - // CHECK: {{%.*}} = load [[VAL3]]#1 + // CHECK: {{%.*}} = load [[ADDR3]] // CHECK: strong_release [[VAL3]]#0 // CHECK: br [[BB2]]( @@ -487,9 +489,9 @@ bb0(%0 : $Bool, %1 : $Bool): store %1 to %3#1 : $*Bool %6 = function_ref @short_circuit_or : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool %7 = load %2#1 : $*Bool - %8 = function_ref @closure0 : $@convention(thin) (@owned @box Bool, @inout Bool) -> Bool + %8 = function_ref @closure0 : $@convention(thin) (@owned @box Bool) -> Bool strong_retain %3#0 : $@box Bool - %10 = partial_apply %8(%3#0, %3#1) : $@convention(thin) (@owned @box Bool, @inout Bool) -> Bool + %10 = partial_apply %8(%3#0) : $@convention(thin) (@owned @box Bool) -> Bool %11 = apply %6(%7, %10) : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool strong_release %3#0 : $@box Bool strong_release %2#0 : $@box Bool @@ -510,8 +512,9 @@ sil @test_short_circuit2 : $@convention(thin) (Bool, Bool) -> Bool { // CHECK: [[BB3]]: // CHECK: strong_retain [[VAL3:.*]]#0 + // CHECK: [[ADDR3:%.*]] = project_box [[VAL3]]#0 // CHECK: {{%.*}} = tuple () - // CHECK: {{%.*}} = load [[VAL3]]#1 + // CHECK: {{%.*}} = load [[ADDR3]] // CHECK: strong_release [[VAL3]]#0 // CHECK: br [[BB2]]( @@ -526,9 +529,9 @@ bb0(%0 : $Bool, %1 : $Bool): store %1 to %3#1 : $*Bool %6 = function_ref @short_circuit_or : $@convention(thin) (Bool, @callee_owned () -> Bool) -> Bool %7 = load %2#1 : $*Bool - %8 = function_ref @closure0 : $@convention(thin) (@owned @box Bool, @inout Bool) -> Bool + %8 = function_ref @closure0 : $@convention(thin) (@owned @box Bool) -> Bool strong_retain %3#0 : $@box Bool - %10 = partial_apply %8(%3#0, %3#1) : $@convention(thin) (@owned @box Bool, @inout Bool) -> Bool + %10 = partial_apply %8(%3#0) : $@convention(thin) (@owned @box Bool) -> Bool strong_retain %10 : $@callee_owned () -> Bool %12 = tuple () @@ -540,7 +543,7 @@ bb0(%0 : $Bool, %1 : $Bool): -sil [transparent] @convertFromBultinIntegerLiteral : $@convention(thin) (Builtin.Int2048, @thin Int64.Type) -> Int64 { +sil [transparent] @convertFromBuiltinIntegerLiteral : $@convention(thin) (Builtin.Int2048, @thin Int64.Type) -> Int64 { bb0(%0 : $Builtin.Int2048, %1 : $@thin Int64.Type): %3 = builtin "s_to_s_checked_trunc_Int2048_Int64"(%0 : $Builtin.Int2048) : $(Builtin.Int64, Builtin.Int1) %4 = tuple_extract %3 : $(Builtin.Int64, Builtin.Int1), 0 @@ -552,7 +555,7 @@ sil @test_with_dead_argument : $@convention(thin) () -> () { bb0: %0 = tuple () %1 = alloc_box $Int64 - %2 = function_ref @convertFromBultinIntegerLiteral : $@convention(thin) (Builtin.Int2048, @thin Int64.Type) -> Int64 + %2 = function_ref @convertFromBuiltinIntegerLiteral : $@convention(thin) (Builtin.Int2048, @thin Int64.Type) -> Int64 %3 = metatype $@thin Int64.Type %4 = integer_literal $Builtin.Int2048, 1 %5 = apply %2(%4, %3) : $@convention(thin) (Builtin.Int2048, @thin Int64.Type) -> Int64 @@ -640,13 +643,13 @@ bb0(%0 : $*T, %1 : $Int, %2 : $*T): // CHECK-NOT: [[REF:%[a-zA-Z0-9]+]] = function_ref @inner %5 = function_ref @inner : $@convention(thin) <τ_0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @in τ_0_1) -> () %6 = alloc_stack $Int - store %1 to %6#1 : $*Int + store %1 to %6 : $*Int %8 = alloc_stack $T - copy_addr %2 to [initialization] %8#1 : $*T + copy_addr %2 to [initialization] %8 : $*T // CHECK-NOT: apply - %10 = apply %5(%0, %6#1, %8#1) : $@convention(thin) <τ_0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @in τ_0_1) -> () - dealloc_stack %8#0 : $*@local_storage T - dealloc_stack %6#0 : $*@local_storage Int + %10 = apply %5(%0, %6, %8) : $@convention(thin) <τ_0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @in τ_0_1) -> () + dealloc_stack %8 : $*T + dealloc_stack %6 : $*Int destroy_addr %2 : $*T %14 = tuple () return %14 : $() @@ -659,13 +662,13 @@ bb0(%0 : $Int): // CHECK-NOT: function_ref @middle %2 = function_ref @middle : $@convention(thin) <τ_0_0> (@out τ_0_0, Int, @in τ_0_0) -> () %7 = alloc_stack $Int - store %0 to %7#1 : $*Int + store %0 to %7 : $*Int %9 = alloc_stack $Int // CHECK-NOT: apply - %10 = apply %2(%9#1, %0, %7#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, Int, @in τ_0_0) -> () - %11 = load %9#1 : $*Int - dealloc_stack %9#0 : $*@local_storage Int - dealloc_stack %7#0 : $*@local_storage Int + %10 = apply %2(%9, %0, %7) : $@convention(thin) <τ_0_0> (@out τ_0_0, Int, @in τ_0_0) -> () + %11 = load %9 : $*Int + dealloc_stack %9 : $*Int + dealloc_stack %7 : $*Int return %11 : $Int } @@ -716,10 +719,10 @@ bb0(%0 : $*T, %1 : $*T): debug_value_addr %1 : $*T %3 = function_ref @identity : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () %4 = alloc_stack $T - copy_addr %1 to [initialization] %4#1 : $*T + copy_addr %1 to [initialization] %4 : $*T // CHECK-NOT: apply - %6 = apply %3(%0, %4#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () - dealloc_stack %4#0 : $*@local_storage T + %6 = apply %3(%0, %4) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () + dealloc_stack %4 : $*T destroy_addr %1 : $*T %9 = tuple () // CHECK: return @@ -733,10 +736,10 @@ bb0(%0 : $*U, %1 : $*T, %2 : $@callee_owned (@out U, @in T) -> ()): debug_value %2 : $@callee_owned (@out U, @in T) -> () strong_retain %2 : $@callee_owned (@out U, @in T) -> () %6 = alloc_stack $T - copy_addr %1 to [initialization] %6#1 : $*T + copy_addr %1 to [initialization] %6 : $*T // CHECK: apply %2 - %8 = apply %2(%0, %6#1) : $@callee_owned (@out U, @in T) -> () - dealloc_stack %6#0 : $*@local_storage T + %8 = apply %2(%0, %6) : $@callee_owned (@out U, @in T) -> () + dealloc_stack %6 : $*T strong_release %2 : $@callee_owned (@out U, @in T) -> () destroy_addr %1 : $*T %12 = tuple () @@ -751,7 +754,7 @@ bb0(%0 : $*U, %1 : $Builtin.Int32, %2 : $@callee_owned (@out U, Builtin.Int32) - debug_value %2 : $@callee_owned (@out U, Builtin.Int32) -> () %5 = function_ref @partial : $@convention(thin) <τ_0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @owned @callee_owned (@out τ_0_1, @in τ_0_0) -> ()) -> () %6 = alloc_stack $Builtin.Int32 - store %1 to %6#1 : $*Builtin.Int32 + store %1 to %6 : $*Builtin.Int32 strong_retain %2 : $@callee_owned (@out U, Builtin.Int32) -> () // CHECK-NOT: function_ref @reabstractionThunk %9 = function_ref @reabstractionThunk : $@convention(thin) <τ_0_0> (@out τ_0_0, @in Builtin.Int32, @owned @callee_owned (@out τ_0_0, Builtin.Int32) -> ()) -> () @@ -759,8 +762,8 @@ bb0(%0 : $*U, %1 : $Builtin.Int32, %2 : $@callee_owned (@out U, Builtin.Int32) - %10 = partial_apply %9(%2) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in Builtin.Int32, @owned @callee_owned (@out τ_0_0, Builtin.Int32) -> ()) -> () // CHECK-NOT: apply // CHECK: apply %2 - %11 = apply %5(%0, %6#1, %10) : $@convention(thin) <τ_0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @owned @callee_owned (@out τ_0_1, @in τ_0_0) -> ()) -> () - dealloc_stack %6#0 : $*@local_storage Builtin.Int32 + %11 = apply %5(%0, %6, %10) : $@convention(thin) <τ_0_0, τ_0_1> (@out τ_0_1, @in τ_0_0, @owned @callee_owned (@out τ_0_1, @in τ_0_0) -> ()) -> () + dealloc_stack %6 : $*Builtin.Int32 strong_release %2 : $@callee_owned (@out U, Builtin.Int32) -> () %14 = tuple () // CHECK: return diff --git a/test/SILPasses/mandatory_inlining.swift b/test/SILOptimizer/mandatory_inlining.swift similarity index 95% rename from test/SILPasses/mandatory_inlining.swift rename to test/SILOptimizer/mandatory_inlining.swift index d4419d9c07550..0bcfda31f09cb 100644 --- a/test/SILPasses/mandatory_inlining.swift +++ b/test/SILOptimizer/mandatory_inlining.swift @@ -10,7 +10,7 @@ func foo(x: Float) -> Float { // CHECK-LABEL: sil hidden @_TF18mandatory_inlining3foo // CHECK: bb0(%0 : $Float): -// CHECK-NEXT: debug_value %0 : $Float // let x +// CHECK-NEXT: debug_value %0 : $Float, let, name "x" // CHECK-NEXT: return %0 @_transparent func bar(x: Float) -> Float { @@ -23,7 +23,7 @@ func foo(x: Float) -> Float { // CHECK: return @_transparent func baz(x: Float) -> Float { - return x; + return x } // CHECK-LABEL: sil hidden [transparent] @_TF18mandatory_inlining3baz @@ -112,7 +112,7 @@ infix operator ||| { precedence 110 } -@_transparent func &&& (lhs: Bool, @autoclosure rhs: ()->Bool) -> Bool { +@_transparent func &&& (lhs: Bool, @autoclosure rhs: () -> Bool) -> Bool { if lhs { return rhs() } @@ -120,7 +120,7 @@ infix operator ||| { return false } -@_transparent func ||| (lhs: Bool, @autoclosure rhs: ()->Bool) -> Bool { +@_transparent func ||| (lhs: Bool, @autoclosure rhs: () -> Bool) -> Bool { if lhs { return true } @@ -148,7 +148,7 @@ enum X { } func testInlineUnionElement() -> X { - return X.onetransp; + return X.onetransp // CHECK-LABEL: sil hidden @_TF18mandatory_inlining22testInlineUnionElementFT_OS_1X // CHECK: enum $X, #X.onetransp!enumelt // CHECK-NOT = apply diff --git a/test/SILPasses/mandatory_inlining_circular.sil b/test/SILOptimizer/mandatory_inlining_circular.sil similarity index 100% rename from test/SILPasses/mandatory_inlining_circular.sil rename to test/SILOptimizer/mandatory_inlining_circular.sil diff --git a/test/SILPasses/mandatory_inlining_circular.swift b/test/SILOptimizer/mandatory_inlining_circular.swift similarity index 100% rename from test/SILPasses/mandatory_inlining_circular.swift rename to test/SILOptimizer/mandatory_inlining_circular.swift diff --git a/test/SILOptimizer/mem-behavior.sil b/test/SILOptimizer/mem-behavior.sil new file mode 100644 index 0000000000000..cd93adfc6dcaf --- /dev/null +++ b/test/SILOptimizer/mem-behavior.sil @@ -0,0 +1,198 @@ +// RUN: %target-sil-opt %s -aa=basic-aa -mem-behavior-dump -o /dev/null | FileCheck %s + +// REQUIRES: asserts + +import Builtin +import Swift + +class X { + @sil_stored var a: Int32 + @sil_stored var x: X + + init() +} + +sil @unknown_func : $@convention(thin) (Int32, @in Int32) -> () + +sil @nouser_func : $@convention(thin) () -> () + +sil @store_to_int : $@convention(thin) (Int32, @inout Int32) -> () { +bb0(%0 : $Int32, %1 : $*Int32): + store %0 to %1 : $*Int32 + %r = tuple () + return %r : $() +} + +sil @only_retain : $@convention(thin) (@guaranteed X) -> () { +bb0(%0 : $X): + strong_retain %0 : $X + + %r = tuple () + return %r : $() +} + +// CHECK-LABEL: @call_unknown_func +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @in Int32) -> () +// CHECK-NEXT: (0): %1 = argument of bb0 : $*Int32 // user: %4 +// CHECK-NEXT: r=1,w=1,se=1 +// CHECK: PAIR #2. +// CHECK-NEXT: (0): %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @in Int32) -> () +// CHECK-NEXT: (0): %2 = argument of bb0 : $*Int32 +// CHECK-NEXT: r=0,w=0,se=0 +sil @call_unknown_func : $@convention(thin) (Int32, @in Int32, @in Int32) -> () { +bb0(%0 : $Int32, %1 : $*Int32, %2 : $*Int32): + %3 = function_ref @unknown_func : $@convention(thin) (Int32, @in Int32) -> () + %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @in Int32) -> () + + %r = tuple () + return %r : $() +} + +// CHECK-LABEL: @call_store_to_int_not_aliased +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () +// CHECK-NEXT: (0): %1 = argument of bb0 : $*Int32 // user: %4 +// CHECK-NEXT: r=0,w=1,se=1 +// CHECK: PAIR #2. +// CHECK-NEXT: (0): %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () +// CHECK-NEXT: (0): %2 = argument of bb0 : $*Int32 +// CHECK-NEXT: r=0,w=0,se=0 +sil @call_store_to_int_not_aliased : $@convention(thin) (Int32, @inout Int32, @in Int32) -> () { +bb0(%0 : $Int32, %1 : $*Int32, %2 : $*Int32): + %3 = function_ref @store_to_int : $@convention(thin) (Int32, @inout Int32) -> () + %4 = apply %3(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () + + %r = tuple () + return %r : $() +} + +// CHECK-LABEL: @call_store_to_int_aliased +// CHECK: PAIR #3. +// CHECK-NEXT: (0): %6 = apply %5(%0, %3) : $@convention(thin) (Int32, @inout Int32) -> () +// CHECK-NEXT: (0): %3 = ref_element_addr %1 : $X, #X.a // user: %6 +// CHECK-NEXT: r=0,w=1,se=1 +// CHECK: PAIR #4. +// CHECK-NEXT: (0): %6 = apply %5(%0, %3) : $@convention(thin) (Int32, @inout Int32) -> () +// CHECK-NEXT: (0): %4 = ref_element_addr %2 : $X, #X.a +// CHECK-NEXT: r=0,w=1,se=1 +sil @call_store_to_int_aliased : $@convention(thin) (Int32, @guaranteed X, @guaranteed X) -> () { +bb0(%0 : $Int32, %1 : $X, %2 : $X): + %3 = ref_element_addr %1 : $X, #X.a + %4 = ref_element_addr %2 : $X, #X.a + %5 = function_ref @store_to_int : $@convention(thin) (Int32, @inout Int32) -> () + %6 = apply %5(%0, %3) : $@convention(thin) (Int32, @inout Int32) -> () + + %r = tuple () + return %r : $() +} + +sil @call_only_retain : $@convention(thin) (@guaranteed X, @guaranteed X) -> () { +bb0(%0 : $X, %1 : $X): + %2 = function_ref @only_retain : $@convention(thin) (@guaranteed X) -> () + %3 = apply %2(%0) : $@convention(thin) (@guaranteed X) -> () + + %r = tuple () + return %r : $() +} + +// CHECK-LABEL: @allocstack_apply_no_side_effect +// CHECK: PAIR #1 +// CHECK-NEXT: (0): %3 = apply %2() : $@convention(thin) () -> () +// CHECK-NEXT: (0): %1 = alloc_stack $Int32 // user: %5 +// CHECK-NEXT: r=0,w=0,se=0 +sil @allocstack_apply_no_side_effect : $@convention(thin) (Int32) -> () { +bb0(%0 : $Int32): + %1 = alloc_stack $Int32 // user: %5 + %2 = function_ref @nouser_func : $@convention(thin) () -> () // user: %3 + %3 = apply %2() : $@convention(thin) () -> () + %4 = tuple () // user: %6 + dealloc_stack %1 : $*Int32 // id: %5 + return %4 : $() +} + +// CHECK-LABEL: @allocstack_apply_side_effect +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %3 = apply %2(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () +// CHECK-NEXT: (0): %1 = alloc_stack $Int32 +// CHECK-NEXT: r=0,w=1,se=1 +sil @allocstack_apply_side_effect : $@convention(thin) (Int32) -> () { +bb0(%0 : $Int32): + %1 = alloc_stack $Int32 // users: %3, %5 + // function_ref store_to_int + %2 = function_ref @store_to_int : $@convention(thin) (Int32, @inout Int32) -> () // user: %3 + %3 = apply %2(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () + %4 = tuple () // user: %6 + dealloc_stack %1 : $*Int32 // id: %5 + return %4 : $() // id: %6 +} + +// CHECK-LABEL: @allocstack_apply_no_escaping +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %3 = apply %2() : $@convention(thin) () -> () +// CHECK-NEXT: (0): %1 = alloc_stack $Int32 // users: %5, %7 +// CHECK-NEXT: r=0,w=0,se=0 +sil @allocstack_apply_no_escaping : $@convention(thin) (Int32) -> () { +bb0(%0 : $Int32): + %1 = alloc_stack $Int32 // users: %3, %5 + %2 = function_ref @nouser_func : $@convention(thin) () -> () // user: %3 + %3 = apply %2() : $@convention(thin) () -> () + %4 = function_ref @store_to_int: $@convention(thin) (Int32, @inout Int32) -> () // user: %3 + %5 = apply %4(%0, %1) : $@convention(thin) (Int32, @inout Int32) -> () + %6 = tuple () // user: %6 + dealloc_stack %1 : $*Int32 // id: %5 + return %6 : $() // id: %6 +} + +// CHECK-LABEL: @allocstack_apply_read_only +// CHECK: PAIR #1. +// CHECK-NEXT: (0): %4 = apply %3(%1) : $@convention(thin) (@in X) -> () +// CHECK-NEXT: (0): %1 = alloc_stack $X // users: %2, %4, %5 +// CHECK-NEXT: r=1,w=0,se=0 +sil @allocstack_apply_read_only : $@convention(thin) (X) -> () { +bb0(%0 : $X): + %1 = alloc_stack $X + store %0 to %1 : $*X + %3 = function_ref @load_from_in : $@convention(thin) (@in X) -> () + %4 = apply %3(%1) : $@convention(thin) (@in X) -> () + dealloc_stack %1 : $*X + %6 = tuple () + return %6 : $() +} + +sil @load_from_in : $@convention(thin) (@in X) -> () { +bb0(%0 : $*X): + %1 = load %0 : $*X + %2 = tuple () + return %2 : $() +} + +struct TwoInts { + var i1 : Int32 + var i2 : Int32 +} + +// CHECK-LABEL: @combination_of_read_and_write_effects +// CHECK: PAIR #0. +// CHECK-NEXT: (0): %4 = apply %3(%1, %2) : $@convention(thin) (@inout Int32, @inout Int32) -> () +// CHECK-NEXT: (0): %0 = alloc_stack $TwoInts // users: %1, %2, %5 +// CHECK-NEXT: r=1,w=1,se=1 +sil @combination_of_read_and_write_effects : $@convention(thin) () -> () { +bb0: + %0 = alloc_stack $TwoInts + %1 = struct_element_addr %0 : $*TwoInts, #TwoInts.i1 + %2 = struct_element_addr %0 : $*TwoInts, #TwoInts.i2 + %3 = function_ref @copy_ints : $@convention(thin) (@inout Int32, @inout Int32) -> () + apply %3 (%1, %2) : $@convention(thin) (@inout Int32, @inout Int32) -> () + dealloc_stack %0 : $*TwoInts + %r = tuple() + return %r : $() +} + +sil @copy_ints : $@convention(thin) (@inout Int32, @inout Int32) -> () { +bb0(%0 : $*Int32, %1 : $*Int32): + %2 = load %0 : $*Int32 + store %2 to %1 : $*Int32 + %r = tuple() + return %r : $() +} diff --git a/test/SILPasses/mem2reg.sil b/test/SILOptimizer/mem2reg.sil similarity index 76% rename from test/SILPasses/mem2reg.sil rename to test/SILOptimizer/mem2reg.sil index 26e3e9d967326..84d858f173409 100644 --- a/test/SILPasses/mem2reg.sil +++ b/test/SILOptimizer/mem2reg.sil @@ -9,12 +9,12 @@ import Swift // simple.foo0 (c : Swift.Int64) -> () sil @store_only_allocas : $@convention(thin) (Int64) -> () { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var c // users: %5, %2 - store %0 to %1#1 : $*Int64 // id: %2 + %1 = alloc_stack $Int64, var, name "c" // users: %5, %2 + store %0 to %1 : $*Int64 // id: %2 // function_ref Swift.print (val : Swift.Int64) -> () %3 = function_ref @_Ts5printFT3valSi_T_ : $@convention(thin) (Int64) -> () // user: %4 %4 = apply %3(%0) : $@convention(thin) (Int64) -> () - dealloc_stack %1#0 : $*@local_storage Int64 // id: %5 + dealloc_stack %1 : $*Int64 // id: %5 %6 = tuple () // user: %7 return %6 : $() // id: %7 } @@ -28,20 +28,20 @@ sil @_Ts5printFT3valSi_T_ : $@convention(thin) (Int64) -> () // simple.foo1 (c : Swift.Int64) -> Swift.Int64 sil @multiple_store_vals : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var c // users: %14, %2 - store %0 to %1#1 : $*Int64 // id: %2 - %3 = alloc_stack $Int64 // var x // users: %12, %11, %13, %6 + %1 = alloc_stack $Int64, var, name "c" // users: %14, %2 + store %0 to %1 : $*Int64 // id: %2 + %3 = alloc_stack $Int64, var, name "x" // users: %12, %11, %13, %6 %4 = integer_literal $Builtin.Int64, 2 // user: %5 %5 = struct $Int64 (%4 : $Builtin.Int64) // user: %6 - store %5 to %3#1 : $*Int64 // id: %6 + store %5 to %3 : $*Int64 // id: %6 %7 = integer_literal $Builtin.Int64, 5 // user: %9 %8 = integer_literal $Builtin.Int1, 0 // user: %10 %9 = struct $Int64 (%7 : $Builtin.Int64) // users: %12, %15, %11 cond_fail %8 : $Builtin.Int1 // id: %10 - store %9 to %3#1 : $*Int64 // id: %11 - store %9 to %3#1 : $*Int64 // id: %12 - dealloc_stack %3#0 : $*@local_storage Int64 // id: %13 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %14 + store %9 to %3 : $*Int64 // id: %11 + store %9 to %3 : $*Int64 // id: %12 + dealloc_stack %3 : $*Int64 // id: %13 + dealloc_stack %1 : $*Int64 // id: %14 return %9 : $Int64 // id: %15 } @@ -51,9 +51,9 @@ bb0(%0 : $Int64): // simple.foo2 (c : Swift.Int64) -> Swift.Int64 sil @multiple_store_vals2 : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var c // users: %19, %2 - store %0 to %1#1 : $*Int64 // id: %2 - %3 = alloc_box $Int64 // var x // users: %16, %11, %6 + %1 = alloc_stack $Int64, var, name "c" // users: %19, %2 + store %0 to %1 : $*Int64 // id: %2 + %3 = alloc_box $Int64, var, name "x" // users: %16, %11, %6 %4 = integer_literal $Builtin.Int64, 2 // users: %9, %5 %5 = struct $Int64 (%4 : $Builtin.Int64) // users: %12, %6 store %5 to %3#1 : $*Int64 // id: %6 @@ -73,7 +73,7 @@ bb2: // Preds: bb0 br bb3(%14 : $Int64) // id: %17 bb3(%18 : $Int64): // Preds: bb2 bb1 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %19 + dealloc_stack %1 : $*Int64 // id: %19 return %18 : $Int64 // id: %20 } @@ -81,9 +81,9 @@ bb3(%18 : $Int64): // Preds: bb2 bb1 // simple.foo2 (c : Swift.Int64) -> Swift.Int64 sil @with_loads : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var c // users: %19, %2, (%20) - store %0 to %1#1 : $*Int64 // id: %2 - %3 = alloc_box $Int64 // var x // users: %16, %11, %6 + %1 = alloc_stack $Int64, var, name "c" // users: %19, %2, (%20) + store %0 to %1 : $*Int64 // id: %2 + %3 = alloc_box $Int64, var, name "x" // users: %16, %11, %6 %4 = integer_literal $Builtin.Int64, 2 // users: %9, %5 %5 = struct $Int64 (%4 : $Builtin.Int64) // users: %12, %6 store %5 to %3#1 : $*Int64 // id: %6 @@ -104,8 +104,8 @@ bb2: // Preds: bb0 //CHECK: bb3([[RET:%[0-9]+]] : $Int64): bb3(%18 : $Int64): // Preds: bb2 bb1 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %19 - %20 = load %1#1 : $*Int64 + dealloc_stack %1 : $*Int64 // id: %19 + %20 = load %1 : $*Int64 //CHECK: return [[RET]] return %18 : $Int64 // id: %20 } @@ -116,26 +116,26 @@ bb3(%18 : $Int64): // Preds: bb2 bb1 // test.foo3 (c : Swift.Int64) -> () sil @basic_block_with_loads_and_stores : $@convention(thin) (Int64) -> () { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var c // users: %20, %2 - store %0 to %1#1 : $*Int64 // id: %2 - %3 = alloc_stack $Int64 // var x // users: %14, %19, %6, %17 + %1 = alloc_stack $Int64, var, name "c" // users: %20, %2 + store %0 to %1 : $*Int64 // id: %2 + %3 = alloc_stack $Int64, var, name "x" // users: %14, %19, %6, %17 %4 = integer_literal $Builtin.Int64, 3 // user: %5 %5 = struct $Int64 (%4 : $Builtin.Int64) // user: %6 - store %5 to %3#1 : $*Int64 // id: %6 + store %5 to %3 : $*Int64 // id: %6 %7 = integer_literal $Builtin.Int64, 3 // user: %10 %9 = struct_extract %0 : $Int64, #Int64._value // user: %10 %10 = builtin "cmp_sgt_Int64"(%9 : $Builtin.Int64, %7 : $Builtin.Int64) : $Builtin.Int1 // user: %11 %12 = integer_literal $Builtin.Int64, 2 // user: %13 %13 = struct $Int64 (%12 : $Builtin.Int64) // user: %14 - store %13 to %3#1 : $*Int64 // id: %14 + store %13 to %3 : $*Int64 // id: %14 // function_ref Swift.print (val : Swift.Int64) -> () %16 = function_ref @_Ts5printFT3valSi_T_ : $@convention(thin) (Int64) -> () // user: %18 - %17 = load %3#1 : $*Int64 // user: %18 + %17 = load %3 : $*Int64 // user: %18 %18 = apply %16(%17) : $@convention(thin) (Int64) -> () - dealloc_stack %3#0 : $*@local_storage Int64 // id: %19 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %20 + dealloc_stack %3 : $*Int64 // id: %19 + dealloc_stack %1 : $*Int64 // id: %20 %21 = tuple () // user: %22 return %21 : $() // id: %22 } @@ -146,9 +146,9 @@ bb0(%0 : $Int64): sil @load_uninitialized_empty : $@convention(thin) (@inout ()) -> () { bb0(%0 : $*()): %1 = alloc_stack $() - %2 = load %1#1 : $*() + %2 = load %1 : $*() store %2 to %0 : $*() - dealloc_stack %1#0 : $*@local_storage () + dealloc_stack %1 : $*() %3 = tuple () return %3 : $() } @@ -161,10 +161,10 @@ bb0(%0 : $*()): sil @mem2reg_debug_value_addr : $@convention(thin) (Int) -> Int { bb0(%0 : $Int): %1 = alloc_stack $Int - store %0 to %1#1 : $*Int - debug_value_addr %1#1 : $*Int - %2 = load %1#1 : $*Int - dealloc_stack %1#0 : $*@local_storage Int + store %0 to %1 : $*Int + debug_value_addr %1 : $*Int + %2 = load %1 : $*Int + dealloc_stack %1 : $*Int return %2 : $Int } @@ -175,10 +175,10 @@ bb0(%0 : $Int): sil @mem2reg_struct_addr : $@convention(thin) (Int64) -> Builtin.Int64 { bb0(%0 : $Int64): %1 = alloc_stack $Int64 - store %0 to %1#1 : $*Int64 - %2 = struct_element_addr %1#1 : $*Int64, #Int64._value + store %0 to %1 : $*Int64 + %2 = struct_element_addr %1 : $*Int64, #Int64._value %3 = load %2 : $*Builtin.Int64 - dealloc_stack %1#0 : $*@local_storage Int64 + dealloc_stack %1 : $*Int64 return %3 : $Builtin.Int64 } @@ -190,10 +190,10 @@ sil @mem2reg_tuple_addr : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): %1 = alloc_stack $(Int64, Int64) %2 = tuple (%0 : $Int64, %0 : $Int64) - store %2 to %1#1 : $*(Int64, Int64) - %4 = tuple_element_addr %1#1 : $*(Int64, Int64), 0 + store %2 to %1 : $*(Int64, Int64) + %4 = tuple_element_addr %1 : $*(Int64, Int64), 0 %5 = load %4 : $*Int64 - dealloc_stack %1#0 : $*@local_storage (Int64, Int64) + dealloc_stack %1 : $*(Int64, Int64) return %5 : $Int64 } @@ -202,11 +202,11 @@ bb0(%0 : $Int64): sil @struct_extract_if_then_else : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): %1 = alloc_stack $Int64 - store %0 to %1#1 : $*Int64 + store %0 to %1 : $*Int64 %3 = integer_literal $Builtin.Int64, 2 %4 = struct_extract %0 : $Int64, #Int64._value %5 = builtin "cmp_sgt_Int64"(%4 : $Builtin.Int64, %3 : $Builtin.Int64) : $Builtin.Int1 - %6 = struct_element_addr %1#1 : $*Int64, #Int64._value + %6 = struct_element_addr %1 : $*Int64, #Int64._value cond_br %5, bb1, bb2 // CHECK: bb1: @@ -231,7 +231,7 @@ bb2: // CHECK-NOT: dealloc_stack bb3(%20 : $Builtin.Int64): - dealloc_stack %1#0 : $*@local_storage Int64 + dealloc_stack %1 : $*Int64 %22 = struct $Int64 (%20 : $Builtin.Int64) return %22 : $Int64 } @@ -256,7 +256,7 @@ bb1: // CHECK: [[FIRSTTHICK:%.*]] = thin_to_thick_function [[FIRSTREF]] %6 = thin_to_thick_function %5 : $@convention(thin) () -> Int to $@callee_owned () -> Int // CHECK-NOT: store - store %6 to %1#1 : $*@callee_owned () -> Int + store %6 to %1 : $*@callee_owned () -> Int // CHECK: br bb3([[FIRSTTHICK]] : $@callee_owned () -> Int br bb3 @@ -267,14 +267,14 @@ bb2: // CHECK: [[SECONDTHICK:%.*]] = thin_to_thick_function [[SECONDREF]] %10 = thin_to_thick_function %9 : $@convention(thin) () -> Int to $@callee_owned () -> Int // CHECK-NOT: store - store %10 to %1#1 : $*@callee_owned () -> Int + store %10 to %1 : $*@callee_owned () -> Int // CHECK: br bb3([[SECONDTHICK]] : $@callee_owned () -> Int) br bb3 // CHECK: bb3([[ARG:%.*]] : $@callee_owned () -> Int): bb3: -// CHECK-NOT: load [[STACK]]#1 - %13 = load %1#1 : $*@callee_owned () -> Int +// CHECK-NOT: load [[STACK]] + %13 = load %1 : $*@callee_owned () -> Int // CHECK: strong_retain [[ARG]] strong_retain %13 : $@callee_owned () -> Int // CHECK: [[RESULT:%.*]] = apply [[ARG]] @@ -282,15 +282,15 @@ bb3: br bb4 // NOTE: This block and the branch above exist to ensure that we - // test what happens when %1#1 hasn't already been loaded in this + // test what happens when %1 hasn't already been loaded in this // block. // CHECK: bb4 bb4: -// CHECK-NOT: destroy_addr [[STACK]]#1 +// CHECK-NOT: destroy_addr [[STACK]] // CHECK: strong_release [[ARG]] - destroy_addr %1#1 : $*@callee_owned () -> Int -// CHECK-NOT: dealloc_stack [[STACK]]#1 - dealloc_stack %1#0 : $*@local_storage @callee_owned () -> Int + destroy_addr %1 : $*@callee_owned () -> Int +// CHECK-NOT: dealloc_stack [[STACK]] + dealloc_stack %1 : $*@callee_owned () -> Int // CHECK: return [[RESULT]] return %15 : $Int } diff --git a/test/SILPasses/mem2reg_liveness.sil b/test/SILOptimizer/mem2reg_liveness.sil similarity index 82% rename from test/SILPasses/mem2reg_liveness.sil rename to test/SILOptimizer/mem2reg_liveness.sil index 8e95c7b8cc19a..7833a24f3c27d 100644 --- a/test/SILPasses/mem2reg_liveness.sil +++ b/test/SILOptimizer/mem2reg_liveness.sil @@ -9,18 +9,18 @@ sil @_Ts5printFT3valSi_T_ : $@convention(thin) (Int64) -> () // CHECK-NOT: alloc_stack sil @liveness0 : $@convention(thin) (Int64) -> () { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var x // users: %39, %2 - store %0 to %1#1 : $*Int64 // id: %2 + %1 = alloc_stack $Int64, var, name "x" // users: %39, %2 + store %0 to %1 : $*Int64 // id: %2 %3 = integer_literal $Builtin.Int64, 10 // user: %6 %5 = struct_extract %0 : $Int64, #Int64._value // user: %6 %6 = builtin "cmp_eq_Int64"(%5 : $Builtin.Int64, %3 : $Builtin.Int64) : $Builtin.Int1 // user: %7 cond_br %6, bb1, bb5 // id: %7 bb1: // Preds: bb0 - %8 = alloc_stack $Int64 // var y // users: %23, %19, %37, %11, %26 + %8 = alloc_stack $Int64, var, name "y" // users: %23, %19, %37, %11, %26 %9 = integer_literal $Builtin.Int64, 20 // user: %10 %10 = struct $Int64 (%9 : $Builtin.Int64) // user: %11 - store %10 to %8#1 : $*Int64 // id: %11 + store %10 to %8 : $*Int64 // id: %11 %12 = integer_literal $Builtin.Int64, 3 // user: %15 %14 = struct_extract %0 : $Int64, #Int64._value // user: %15 %15 = builtin "cmp_sgt_Int64"(%14 : $Builtin.Int64, %12 : $Builtin.Int64) : $Builtin.Int1 // user: %16 @@ -29,19 +29,19 @@ bb1: // Preds: bb0 bb2: // Preds: bb1 %17 = integer_literal $Builtin.Int64, 0 // user: %18 %18 = struct $Int64 (%17 : $Builtin.Int64) // user: %19 - store %18 to %8#1 : $*Int64 // id: %19 + store %18 to %8 : $*Int64 // id: %19 br bb4 // id: %20 bb3: // Preds: bb1 %21 = integer_literal $Builtin.Int64, 2 // user: %22 %22 = struct $Int64 (%21 : $Builtin.Int64) // user: %23 - store %22 to %8#1 : $*Int64 // id: %23 + store %22 to %8 : $*Int64 // id: %23 br bb4 // id: %24 bb4: // Preds: bb3 bb2 // function_ref %25 = function_ref @_Ts5printFT3valSi_T_ : $@convention(thin) (Int64) -> () // user: %36 - %26 = load %8#1 : $*Int64 // user: %30 + %26 = load %8 : $*Int64 // user: %30 %27 = integer_literal $Builtin.Int64, 2 // user: %31 %28 = integer_literal $Builtin.Int1, -1 // user: %31 %30 = struct_extract %26 : $Int64, #Int64._value // user: %31 @@ -51,13 +51,13 @@ bb4: // Preds: bb3 bb2 %34 = struct $Int64 (%32 : $Builtin.Int64) // user: %36 cond_fail %33 : $Builtin.Int1 // id: %35 %36 = apply %25(%34) : $@convention(thin) (Int64) -> () - dealloc_stack %8#0 : $*@local_storage Int64 // id: %37 + dealloc_stack %8 : $*Int64 // id: %37 br bb5 // id: %38 // We don't need a PHI node here because the value is dead! // CHECK: bb5: bb5: // Preds: bb4 bb0 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %39 + dealloc_stack %1 : $*Int64 // id: %39 %40 = tuple () // user: %41 // CHECK: return return %40 : $() // id: %41 diff --git a/test/SILPasses/mem2reg_simple.sil b/test/SILOptimizer/mem2reg_simple.sil similarity index 82% rename from test/SILPasses/mem2reg_simple.sil rename to test/SILOptimizer/mem2reg_simple.sil index 6006014efe4a4..d6266a0d3e855 100644 --- a/test/SILPasses/mem2reg_simple.sil +++ b/test/SILOptimizer/mem2reg_simple.sil @@ -20,12 +20,12 @@ import Swift sil @place_phi : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var v // users: %45, %2 - store %0 to %1#1 : $*Int64 // id: %2 - %3 = alloc_stack $Int64 // var x // users: %19, %13, %44, %6, %42 + %1 = alloc_stack $Int64, var, name "v" // users: %45, %2 + store %0 to %1 : $*Int64 // id: %2 + %3 = alloc_stack $Int64, var, name "x" // users: %19, %13, %44, %6, %42 %4 = integer_literal $Builtin.Int64, 0 // user: %5 %5 = struct $Int64 (%4 : $Builtin.Int64) // users: %23, %6 - store %5 to %3#1 : $*Int64 // id: %6 + store %5 to %3 : $*Int64 // id: %6 %7 = integer_literal $Builtin.Int64, 3 // users: %12, %10 %9 = struct_extract %0 : $Int64, #Int64._value // users: %16, %10 %10 = builtin "cmp_eq_Int64"(%9 : $Builtin.Int64, %7 : $Builtin.Int64) : $Builtin.Int1 // user: %11 @@ -33,7 +33,7 @@ bb0(%0 : $Int64): bb1: // Preds: bb0 %12 = struct $Int64 (%7 : $Builtin.Int64) // user: %13 - store %12 to %3#1 : $*Int64 // id: %13 + store %12 to %3 : $*Int64 // id: %13 br bb5 // id: %14 bb2: // Preds: bb0 @@ -43,7 +43,7 @@ bb2: // Preds: bb0 bb3: // Preds: bb2 %18 = struct $Int64 (%15 : $Builtin.Int64) // user: %19 - store %18 to %3#1 : $*Int64 // id: %19 + store %18 to %3 : $*Int64 // id: %19 br bb4 // id: %20 bb4: // Preds: bb3 bb2 @@ -52,14 +52,14 @@ bb4: // Preds: bb3 bb2 //CHECK: bb5([[PHI:%[0-9]+]] : $Int64): //CHECK-NOT: alloc_stack bb5: // Preds: bb4 bb1 - %22 = alloc_stack $Int64 // var i // users: %31, %25, %40, %43, %23 - store %5 to %22#1 : $*Int64 // id: %23 + %22 = alloc_stack $Int64, var, name "i" // users: %31, %25, %40, %43, %23 + store %5 to %22 : $*Int64 // id: %23 br bb6 // id: %24 //CHECK: bb6([[PHI2:%[0-9]+]] : $Int64): bb6: // Preds: bb7 bb5 //CHECK: struct_extract [[PHI2]] - %25 = struct_element_addr %22#1 : $*Int64, #Int64._value // user: %26 + %25 = struct_element_addr %22 : $*Int64, #Int64._value // user: %26 %26 = load %25 : $*Builtin.Int64 // user: %29 %27 = integer_literal $Builtin.Int64, 10 // user: %29 %29 = builtin "cmp_slt_Int64"(%26 : $Builtin.Int64, %27 : $Builtin.Int64) : $Builtin.Int1 // users: %35, %30 @@ -67,7 +67,7 @@ bb6: // Preds: bb7 bb5 bb7: // Preds: bb6 //CHECK: struct_extract [[PHI2]] - %31 = struct_element_addr %22#1 : $*Int64, #Int64._value // user: %32 + %31 = struct_element_addr %22 : $*Int64, #Int64._value // user: %32 %32 = load %31 : $*Builtin.Int64 // user: %35 %33 = integer_literal $Builtin.Int64, 1 // user: %35 %35 = builtin "sadd_with_overflow_Int64"(%32 : $Builtin.Int64, %33 : $Builtin.Int64, %29 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // users: %37, %36 @@ -75,14 +75,14 @@ bb7: // Preds: bb6 %37 = tuple_extract %35 : $(Builtin.Int64, Builtin.Int1), 1 // user: %39 %38 = struct $Int64 (%36 : $Builtin.Int64) // user: %40 cond_fail %37 : $Builtin.Int1 // id: %39 - store %38 to %22#1 : $*Int64 // id: %40 + store %38 to %22 : $*Int64 // id: %40 br bb6 // id: %41 bb8: // Preds: bb6 - %42 = load %3#1 : $*Int64 // user: %46 - dealloc_stack %22#0 : $*@local_storage Int64 // id: %43 - dealloc_stack %3#0 : $*@local_storage Int64 // id: %44 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %45 + %42 = load %3 : $*Int64 // user: %46 + dealloc_stack %22 : $*Int64 // id: %43 + dealloc_stack %3 : $*Int64 // id: %44 + dealloc_stack %1 : $*Int64 // id: %45 //CHECK: return [[PHI]] return %42 : $Int64 // id: %46 } @@ -97,24 +97,24 @@ bb8: // Preds: bb6 //CHECK-NOT: alloc_stack sil @func_loop: $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var c // users: %28, %2 - store %0 to %1#1 : $*Int64 // id: %2 - %3 = alloc_stack $Int64 // var x // users: %24, %27, %6, %8, %14, %26 + %1 = alloc_stack $Int64, var, name "c" // users: %28, %2 + store %0 to %1 : $*Int64 // id: %2 + %3 = alloc_stack $Int64, var, name "x" // users: %24, %27, %6, %8, %14, %26 %4 = integer_literal $Builtin.Int64, 0 // user: %5 %5 = struct $Int64 (%4 : $Builtin.Int64) // user: %6 - store %5 to %3#1 : $*Int64 // id: %6 + store %5 to %3 : $*Int64 // id: %6 br bb1 // id: %7 //CHECK: bb1([[VAR:%[0-9]+]] : $Int64): bb1: // Preds: bb2 bb0 - %8 = load %3#1 : $*Int64 // user: %10 + %8 = load %3 : $*Int64 // user: %10 %10 = struct_extract %8 : $Int64, #Int64._value // user: %12 %11 = struct_extract %0 : $Int64, #Int64._value // user: %12 %12 = builtin "cmp_slt_Int64"(%10 : $Builtin.Int64, %11 : $Builtin.Int64) : $Builtin.Int1 // user: %13 cond_br %12, bb2, bb3 // id: %13 bb2: // Preds: bb1 - %14 = load %3#1 : $*Int64 // user: %18 + %14 = load %3 : $*Int64 // user: %18 %15 = integer_literal $Builtin.Int64, 1 // user: %19 %16 = integer_literal $Builtin.Int1, -1 // user: %19 %18 = struct_extract %14 : $Int64, #Int64._value // user: %19 @@ -123,13 +123,13 @@ bb2: // Preds: bb1 %21 = tuple_extract %19 : $(Builtin.Int64, Builtin.Int1), 1 // user: %23 %22 = struct $Int64 (%20 : $Builtin.Int64) // user: %24 cond_fail %21 : $Builtin.Int1 // id: %23 - store %22 to %3#1 : $*Int64 // id: %24 + store %22 to %3 : $*Int64 // id: %24 br bb1 // id: %25 bb3: // Preds: bb1 - %26 = load %3#1 : $*Int64 // user: %29 - dealloc_stack %3#0 : $*@local_storage Int64 // id: %27 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %28 + %26 = load %3 : $*Int64 // user: %29 + dealloc_stack %3 : $*Int64 // id: %27 + dealloc_stack %1 : $*Int64 // id: %28 //CHECK-NOT: dealloc_stack //CHECK: return [[VAR]] return %26 : $Int64 // id: %29 @@ -153,12 +153,12 @@ bb3: // Preds: bb1 //CHECK: return sil @high_nest : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var c // users: %114, %2 - store %0 to %1#1 : $*Int64 // id: %2 - %3 = alloc_stack $Int64 // var x // users: %94, %113, %6, %112 + %1 = alloc_stack $Int64, var, name "c" // users: %114, %2 + store %0 to %1 : $*Int64 // id: %2 + %3 = alloc_stack $Int64, var, name "x" // users: %94, %113, %6, %112 %4 = integer_literal $Builtin.Int64, 0 // user: %5 %5 = struct $Int64 (%4 : $Builtin.Int64) // user: %6 - store %5 to %3#1 : $*Int64 // id: %6 + store %5 to %3 : $*Int64 // id: %6 %7 = integer_literal $Builtin.Int64, 1 // user: %10 %9 = struct_extract %0 : $Int64, #Int64._value // user: %10 %10 = builtin "cmp_sgt_Int64"(%9 : $Builtin.Int64, %7 : $Builtin.Int64) : $Builtin.Int1 @@ -264,7 +264,7 @@ bb16: // Preds: bb15 bb17: // Preds: bb16 %92 = integer_literal $Builtin.Int64, 7 // user: %93 %93 = struct $Int64 (%92 : $Builtin.Int64) // user: %94 - store %93 to %3#1 : $*Int64 // id: %94 + store %93 to %3 : $*Int64 // id: %94 br bb18 // id: %95 bb18: // Preds: bb17 bb16 @@ -316,9 +316,9 @@ bb33: // Preds: bb32 bb1 br bb34 // id: %111 bb34: // Preds: bb33 bb0 - %112 = load %3#1 : $*Int64 // user: %115 - dealloc_stack %3#0 : $*@local_storage Int64 // id: %113 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %114 + %112 = load %3 : $*Int64 // user: %115 + dealloc_stack %3 : $*Int64 // id: %113 + dealloc_stack %1 : $*Int64 // id: %114 return %112 : $Int64 // id: %115 } @@ -326,13 +326,13 @@ bb34: // Preds: bb33 bb0 //CHECK-NOT: alloc_stack sil @simple_if : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): - %1 = alloc_stack $Int64 // var c // users: %17, %2 - store %0 to %1#1 : $*Int64 // id: %2 - %3 = alloc_stack $Int64 // var x // users: %13, %16, %6, %15 + %1 = alloc_stack $Int64, var, name "c" // users: %17, %2 + store %0 to %1 : $*Int64 // id: %2 + %3 = alloc_stack $Int64, var, name "x" // users: %13, %16, %6, %15 %4 = integer_literal $Builtin.Int64, 0 // users: %9, %5 //CHECK: [[INIT:%[0-9]+]] = struct $Int64 %5 = struct $Int64 (%4 : $Builtin.Int64) // user: %6 - store %5 to %3#1 : $*Int64 // id: %6 + store %5 to %3 : $*Int64 // id: %6 %8 = struct_extract %0 : $Int64, #Int64._value // user: %9 %9 = builtin "cmp_sgt_Int64"(%4 : $Builtin.Int64, %8 : $Builtin.Int64) : $Builtin.Int1 //CHECK: bb2([[INIT]] : $Int64) @@ -342,14 +342,14 @@ bb1: // Preds: bb0 %11 = integer_literal $Builtin.Int64, 2 // user: %12 //CHECK: [[INIT2:%[0-9]+]] = struct $Int64 %12 = struct $Int64 (%11 : $Builtin.Int64) // user: %13 - store %12 to %3#1 : $*Int64 // id: %13 + store %12 to %3 : $*Int64 // id: %13 //CHECK: bb2([[INIT2]] : $Int64) br bb2 // id: %14 bb2: // Preds: bb1 bb0 - %15 = load %3#1 : $*Int64 // user: %18 - dealloc_stack %3#0 : $*@local_storage Int64 // id: %16 - dealloc_stack %1#0 : $*@local_storage Int64 // id: %17 + %15 = load %3 : $*Int64 // user: %18 + dealloc_stack %3 : $*Int64 // id: %16 + dealloc_stack %1 : $*Int64 // id: %17 //CHECK: return return %15 : $Int64 // id: %18 } @@ -366,12 +366,12 @@ enum X { //CHECK-NOT: dealloc_stack sil @test_switch: $@convention(thin) (Int64, X) -> Int64 { bb0(%0 : $Int64, %1 : $X): - %2 = alloc_stack $Int64 // var xi // users: %28, %4 - %3 = alloc_stack $X // var c // users: %27, %5 - store %0 to %2#1 : $*Int64 // id: %4 - store %1 to %3#1 : $*X // id: %5 - %6 = alloc_stack $Int64 // var x // users: %7, %23, %18, %13, %26, %25 - store %0 to %6#1 : $*Int64 // id: %7 + %2 = alloc_stack $Int64, var, name "xi" // users: %28, %4 + %3 = alloc_stack $X, var, name "c" // users: %27, %5 + store %0 to %2 : $*Int64 // id: %4 + store %1 to %3 : $*X // id: %5 + %6 = alloc_stack $Int64, var, name "x" // users: %7, %23, %18, %13, %26, %25 + store %0 to %6 : $*Int64 // id: %7 %8 = tuple () switch_enum %1 : $X, case #X.One!enumelt: bb1, case #X.Two!enumelt: bb3, case #X.Three!enumelt: bb5 // id: %9 @@ -381,7 +381,7 @@ bb1: // Preds: bb0 bb2: // Preds: bb1 %11 = integer_literal $Builtin.Int64, 3 // user: %12 %12 = struct $Int64 (%11 : $Builtin.Int64) // user: %13 - store %12 to %6#1 : $*Int64 // id: %13 + store %12 to %6 : $*Int64 // id: %13 br bb7 // id: %14 bb3: // Preds: bb0 @@ -390,7 +390,7 @@ bb3: // Preds: bb0 bb4: // Preds: bb3 %16 = integer_literal $Builtin.Int64, 2 // user: %17 %17 = struct $Int64 (%16 : $Builtin.Int64) // user: %18 - store %17 to %6#1 : $*Int64 // id: %18 + store %17 to %6 : $*Int64 // id: %18 br bb7 // id: %19 bb5: // Preds: bb0 @@ -399,14 +399,14 @@ bb5: // Preds: bb0 bb6: // Preds: bb5 %21 = integer_literal $Builtin.Int64, 1 // user: %22 %22 = struct $Int64 (%21 : $Builtin.Int64) // user: %23 - store %22 to %6#1 : $*Int64 // id: %23 + store %22 to %6 : $*Int64 // id: %23 br bb7 // id: %24 bb7: // Preds: bb6 bb4 bb2 - %25 = load %6#1 : $*Int64 // user: %29 - dealloc_stack %6#0 : $*@local_storage Int64 // id: %26 - dealloc_stack %3#0 : $*@local_storage X // id: %27 - dealloc_stack %2#0 : $*@local_storage Int64 // id: %28 + %25 = load %6 : $*Int64 // user: %29 + dealloc_stack %6 : $*Int64 // id: %26 + dealloc_stack %3 : $*X // id: %27 + dealloc_stack %2 : $*Int64 // id: %28 //CHECK: return return %25 : $Int64 // id: %29 } diff --git a/test/SILPasses/mem2reg_unreachable.sil b/test/SILOptimizer/mem2reg_unreachable.sil similarity index 75% rename from test/SILPasses/mem2reg_unreachable.sil rename to test/SILOptimizer/mem2reg_unreachable.sil index d94ffe8992de2..c5747a5e2a773 100644 --- a/test/SILPasses/mem2reg_unreachable.sil +++ b/test/SILOptimizer/mem2reg_unreachable.sil @@ -9,9 +9,9 @@ import Swift sil @_TF4main3fooFT1xSi1ySi_Si : $@convention(thin) (Int32, Int32) -> Int32 { bb0(%0 : $Int32, %1 : $Int32): - debug_value %0 : $Int32 // let x // id: %2 - debug_value %1 : $Int32 // let y // id: %3 - %4 = alloc_stack $Int32 // var g // users: %14, %18, %20, %21 + debug_value %0 : $Int32, let, name "x" // id: %2 + debug_value %1 : $Int32, let, name "y" // id: %3 + %4 = alloc_stack $Int32, var, name "g" // users: %14, %18, %20, %21 %6 = struct_extract %1 : $Int32, #Int32._value // user: %8 %7 = struct_extract %0 : $Int32, #Int32._value // user: %8 %8 = builtin "cmp_sgt_Word"(%6 : $Builtin.Int32, %7 : $Builtin.Int32) : $Builtin.Int1 // user: %9 @@ -22,18 +22,18 @@ bb0(%0 : $Int32, %1 : $Int32): bb1: // Preds: bb0 %12 = integer_literal $Builtin.Int32, 5 // user: %13 %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14 - store %13 to %4#1 : $*Int32 // id: %14 + store %13 to %4 : $*Int32 // id: %14 br bb3 // id: %15 bb2: // Preds: bb0 %16 = integer_literal $Builtin.Int32, 4 // user: %17 %17 = struct $Int32 (%16 : $Builtin.Int32) // user: %18 - store %17 to %4#1 : $*Int32 // id: %18 + store %17 to %4 : $*Int32 // id: %18 br bb3 // id: %19 bb3: // Preds: bb1 bb2 - %20 = load %4#1 : $*Int32 // user: %22 - dealloc_stack %4#0 : $*@local_storage Int32 // id: %21 + %20 = load %4 : $*Int32 // user: %22 + dealloc_stack %4 : $*Int32 // id: %21 return %20 : $Int32 // id: %22 } diff --git a/test/SILPasses/merge_cond_fail.sil b/test/SILOptimizer/merge_cond_fail.sil similarity index 100% rename from test/SILPasses/merge_cond_fail.sil rename to test/SILOptimizer/merge_cond_fail.sil diff --git a/test/SILPasses/mm_inlinecaches_multiple.sil b/test/SILOptimizer/mm_inlinecaches_multiple.sil similarity index 100% rename from test/SILPasses/mm_inlinecaches_multiple.sil rename to test/SILOptimizer/mm_inlinecaches_multiple.sil diff --git a/test/SILPasses/move_cond_fail.sil b/test/SILOptimizer/move_cond_fail.sil similarity index 100% rename from test/SILPasses/move_cond_fail.sil rename to test/SILOptimizer/move_cond_fail.sil diff --git a/test/SILPasses/no-external-defs-onone.sil b/test/SILOptimizer/no-external-defs-onone.sil similarity index 100% rename from test/SILPasses/no-external-defs-onone.sil rename to test/SILOptimizer/no-external-defs-onone.sil diff --git a/test/SILPasses/no_opt.swift b/test/SILOptimizer/no_opt.swift similarity index 100% rename from test/SILPasses/no_opt.swift rename to test/SILOptimizer/no_opt.swift diff --git a/test/SILPasses/noreturn_folding.sil b/test/SILOptimizer/noreturn_folding.sil similarity index 100% rename from test/SILPasses/noreturn_folding.sil rename to test/SILOptimizer/noreturn_folding.sil diff --git a/test/SILPasses/optimize_never.sil b/test/SILOptimizer/optimize_never.sil similarity index 92% rename from test/SILPasses/optimize_never.sil rename to test/SILOptimizer/optimize_never.sil index fb2997b316acb..ef07ac2b490af 100644 --- a/test/SILPasses/optimize_never.sil +++ b/test/SILOptimizer/optimize_never.sil @@ -126,14 +126,14 @@ bb0(%0 : $D): sil hidden @_TFC14optimize_never1DcfT_S0_ : $@convention(method) (@owned D) -> @owned D { bb0(%0 : $D): %1 = alloc_stack $D - store %0 to %1#1 : $*D + store %0 to %1 : $*D %3 = upcast %0 : $D to $C %4 = function_ref @_TFC14optimize_never1CcfT_S0_ : $@convention(method) (@owned C) -> @owned C %5 = apply %4(%3) : $@convention(method) (@owned C) -> @owned C %6 = unchecked_ref_cast %5 : $C to $D - store %6 to %1#1 : $*D - dealloc_stack %1#0 : $*@local_storage D + store %6 to %1 : $*D + dealloc_stack %1 : $*D return %6 : $D } @@ -154,15 +154,15 @@ bb0(%0 : $*T): // CHECK: function_ref @_TF14optimize_never10transform1urFxVs5Int32 // CHECK: apply // CHECK-NOT: checked_cast_br -// CHECK: class_method {{%.*}} : $C, #C.foo!1 : C -> () -> Int32 , $@convention(method) (@guaranteed C) -> Int32 +// CHECK: class_method {{%.*}} : $C, #C.foo!1 : (C) -> () -> Int32 , $@convention(method) (@guaranteed C) -> Int32 // CHECK: apply // CHECK: return sil [_semantics "optimize.sil.never"] @_TF14optimize_never4foo1urFTxCS_1C_Vs5Int32 : $@convention(thin) (@in T, @owned C) -> Int32 { bb0(%0 : $*T, %1 : $C): %4 = function_ref @_TF14optimize_never10transform1urFxVs5Int32 : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32 %5 = alloc_stack $T - copy_addr %0 to [initialization] %5#1 : $*T - %7 = apply %4(%5#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32 + copy_addr %0 to [initialization] %5 : $*T + %7 = apply %4(%5) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32 %8 = class_method %1 : $C, #C.foo!1 : C -> () -> Int32 , $@convention(method) (@guaranteed C) -> Int32 %9 = apply %8(%1) : $@convention(method) (@guaranteed C) -> Int32 %10 = struct_extract %7 : $Int32, #Int32._value @@ -173,7 +173,7 @@ bb0(%0 : $*T, %1 : $C): %15 = tuple_extract %13 : $(Builtin.Int32, Builtin.Int1), 1 cond_fail %15 : $Builtin.Int1 %17 = struct $Int32 (%14 : $Builtin.Int32) - dealloc_stack %5#0 : $*@local_storage T + dealloc_stack %5 : $*T strong_release %1 : $C destroy_addr %0 : $*T return %17 : $Int32 @@ -195,10 +195,10 @@ bb0(%0 : $C): %3 = integer_literal $Builtin.Int32, 1 %4 = struct $Int32 (%3 : $Builtin.Int32) %5 = alloc_stack $Int32 - store %4 to %5#1 : $*Int32 + store %4 to %5 : $*Int32 strong_retain %0 : $C - %8 = apply %2(%5#1, %0) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> Int32 - dealloc_stack %5#0 : $*@local_storage Int32 + %8 = apply %2(%5, %0) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> Int32 + dealloc_stack %5 : $*Int32 strong_release %0 : $C return %8 : $Int32 } @@ -219,7 +219,7 @@ bb0(%0 : $Int32): // CHECK: function_ref @_TF14optimize_never10transform2FVs5Int32S0_ // CHECK: apply // CHECK-NOT: checked_cast_br -// CHECK: class_method {{%.*}} : $C, #C.foo!1 : C -> () -> Int32 , $@convention(method) (@guaranteed C) -> Int32 +// CHECK: class_method {{%.*}} : $C, #C.foo!1 : (C) -> () -> Int32 , $@convention(method) (@guaranteed C) -> Int32 // CHECK: apply // CHECK: return sil [_semantics "optimize.sil.never"] @_TF14optimize_never4foo2FTVs5Int32CS_1C_S0_ : $@convention(thin) (Int32, @owned C) -> Int32 { @@ -277,8 +277,8 @@ sil @_TF14optimize_never4foo3urFTxCS_1C_Vs5Int32 : $@convention(thin) (@in T bb0(%0 : $*T, %1 : $C): %4 = function_ref @_TF14optimize_never10transform3urFxVs5Int32 : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32 %5 = alloc_stack $T - copy_addr %0 to [initialization] %5#1 : $*T - %7 = apply %4(%5#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32 + copy_addr %0 to [initialization] %5 : $*T + %7 = apply %4(%5) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Int32 %8 = class_method %1 : $C, #C.foo!1 : C -> () -> Int32 , $@convention(method) (@guaranteed C) -> Int32 %9 = apply %8(%1) : $@convention(method) (@guaranteed C) -> Int32 %10 = struct_extract %7 : $Int32, #Int32._value @@ -289,7 +289,7 @@ bb0(%0 : $*T, %1 : $C): %15 = tuple_extract %13 : $(Builtin.Int32, Builtin.Int1), 1 cond_fail %15 : $Builtin.Int1 %17 = struct $Int32 (%14 : $Builtin.Int32) - dealloc_stack %5#0 : $*@local_storage T + dealloc_stack %5 : $*T strong_release %1 : $C destroy_addr %0 : $*T return %17 : $Int32 @@ -297,8 +297,8 @@ bb0(%0 : $*T, %1 : $C): // Everything in this function should get devirtualized, inlined and folded together, -// because neither this function nor any of its callees are anootated to be -// excuded from the optimization. +// because neither this function nor any of its callees are annotated to be +// excluded from the optimization. // CHECK-LABEL: sil @_TF14optimize_never4boo3FCS_1CVs5Int32 // CHECK: bb0 // CHECK-NOT: function_ref @_TF14optimize_never4foo3urFTxCS_1C_Vs5Int32 @@ -312,10 +312,10 @@ bb0(%0 : $C): %3 = integer_literal $Builtin.Int32, 1 %4 = struct $Int32 (%3 : $Builtin.Int32) %5 = alloc_stack $Int32 - store %4 to %5#1 : $*Int32 + store %4 to %5 : $*Int32 strong_retain %0 : $C - %8 = apply %2(%5#1, %0) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> Int32 - dealloc_stack %5#0 : $*@local_storage Int32 + %8 = apply %2(%5, %0) : $@convention(thin) <τ_0_0> (@in τ_0_0, @owned C) -> Int32 + dealloc_stack %5 : $*Int32 strong_release %0 : $C return %8 : $Int32 } @@ -347,8 +347,8 @@ bb0(%0 : $Int32, %1 : $C): // Everything in this function should get devirtualized and inlined, -// because neither this function nor any of its callees are anootated to be -// excuded from the optimization. +// because neither this function nor any of its callees are annotated to be +// excluded from the optimization. // CHECK-LABEL: sil @_TF14optimize_never4boo4FCS_1CVs5Int32 // CHECK: bb0 // CHECK-NOT: function_ref @_TF14optimize_never4foo4FTVs5Int32CS_1C_S0_ diff --git a/test/SILPasses/pa_removal.sil b/test/SILOptimizer/pa_removal.sil similarity index 100% rename from test/SILPasses/pa_removal.sil rename to test/SILOptimizer/pa_removal.sil diff --git a/test/SILPasses/peephole_thick_to_objc_metatype.sil b/test/SILOptimizer/peephole_thick_to_objc_metatype.sil similarity index 94% rename from test/SILPasses/peephole_thick_to_objc_metatype.sil rename to test/SILOptimizer/peephole_thick_to_objc_metatype.sil index f0f30fde9b341..73f34a56bfcaa 100644 --- a/test/SILPasses/peephole_thick_to_objc_metatype.sil +++ b/test/SILOptimizer/peephole_thick_to_objc_metatype.sil @@ -42,11 +42,11 @@ bb0: // peephole_thick_to_objc_metatype.test_thick_to_objc_metatype_existential_metatype (peephole_thick_to_objc_metatype.X) -> Swift.AnyObject sil @_TF31peephole_thick_to_objc_metatype48test_thick_to_objc_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @owned AnyObject { bb0(%0 : $X): - debug_value %0 : $X // let o // id: %1 + debug_value %0 : $X, let, name "o" // id: %1 %2 = existential_metatype $@thick X.Type, %0 : $X // user: %3 %3 = thick_to_objc_metatype %2 : $@thick X.Type to $@objc_metatype X.Type // user: %4 %4 = objc_existential_metatype_to_object %3 : $@objc_metatype X.Type to $AnyObject // users: %5, %7 - debug_value %4 : $AnyObject // let Ty // id: %5 + debug_value %4 : $AnyObject, let, name "Ty" // id: %5 strong_release %0 : $X // id: %6 return %4 : $AnyObject // id: %7 } @@ -61,11 +61,11 @@ bb0(%0 : $X): // peephole_thick_to_objc_metatype.test_thick_to_objc_metatype_value_metatype (A) -> Swift.AnyObject sil @_TF31peephole_thick_to_objc_metatype42test_thick_to_objc_metatype_value_metatypeUs9AnyObject__FQ_PS0__ : $@convention(thin) (@owned T) -> @owned AnyObject { bb0(%0 : $T): - debug_value %0 : $T // let o // id: %1 + debug_value %0 : $T, let, name "o" // id: %1 %2 = value_metatype $@thick T.Type, %0 : $T // user: %3 %3 = thick_to_objc_metatype %2 : $@thick T.Type to $@objc_metatype T.Type // user: %4 %4 = objc_metatype_to_object %3 : $@objc_metatype T.Type to $AnyObject // users: %5, %7 - debug_value %4 : $AnyObject // let Ty // id: %5 + debug_value %4 : $AnyObject, let, name "Ty" // id: %5 strong_release %0 : $T // id: %6 return %4 : $AnyObject // id: %7 } @@ -93,7 +93,7 @@ bb0: // CHECK: return sil @_TF31peephole_thick_to_objc_metatype48test_objc_to_thick_metatype_existential_metatypeFPS_1X_Ps9AnyObject_ : $@convention(thin) (@owned X) -> @thick X.Type { bb0(%0 : $X): - debug_value %0 : $X // let o // id: %1 + debug_value %0 : $X, let, name "o" // id: %1 %2 = existential_metatype $@objc_metatype X.Type, %0 : $X // user: %3 %3 = objc_to_thick_metatype %2 : $@objc_metatype X.Type to $@thick X.Type // user: %4 strong_release %0 : $X @@ -109,7 +109,7 @@ bb0(%0 : $X): // CHECK: return sil @_TF31peephole_thick_to_objc_metatype42test_objc_to_thick_metatype_value_metatypeUs9AnyObject__FQ_PS0__ : $@convention(thin) (@owned T) -> @thick T.Type { bb0(%0 : $T): - debug_value %0 : $T // let o // id: %1 + debug_value %0 : $T, let, name "o" // id: %1 %2 = value_metatype $@objc_metatype T.Type, %0 : $T // user: %3 %3 = objc_to_thick_metatype %2 : $@objc_metatype T.Type to $@thick T.Type // user: %4 strong_release %0 : $T diff --git a/test/SILPasses/peephole_trunc_and_ext.sil b/test/SILOptimizer/peephole_trunc_and_ext.sil similarity index 95% rename from test/SILPasses/peephole_trunc_and_ext.sil rename to test/SILOptimizer/peephole_trunc_and_ext.sil index 9c5a104e847e2..d173dc94c176e 100644 --- a/test/SILPasses/peephole_trunc_and_ext.sil +++ b/test/SILOptimizer/peephole_trunc_and_ext.sil @@ -31,7 +31,7 @@ struct BuiltinUWord { // test.test_trunc_u_to_s_zext_lshr_1 (BuiltinUWord) -> Swift.BuiltinWord sil @_TF4test29test_trunc_u_to_s_zext_lshr_1FSuSi : $@convention(thin) (BuiltinUWord) -> BuiltinWord { bb0(%0 : $BuiltinUWord): - debug_value %0 : $BuiltinUWord // let x // id: %1 + debug_value %0 : $BuiltinUWord, let, name "x" // id: %1 %2 = integer_literal $Builtin.Word, 1 // user: %7 br bb1 // id: %3 @@ -55,7 +55,7 @@ bb3: // Preds: bb2 %19 = struct_extract %18 : $Int64, #Int64._value // user: %21 %21 = builtin "truncOrBitCast_Int64_Word"(%19 : $Builtin.Int64) : $Builtin.Word // user: %22 %22 = struct $BuiltinWord (%21 : $Builtin.Word) // users: %23, %24 - debug_value %22 : $BuiltinWord // let v1 // id: %23 + debug_value %22 : $BuiltinWord, let, name "v1" // id: %23 return %22 : $BuiltinWord // id: %24 } @@ -70,7 +70,7 @@ bb3: // Preds: bb2 // test.test_trunc_u_to_s_zext_lshr_10 (Swift.BuiltinUWord) -> Swift.BuiltinWord sil @_TF4test30test_trunc_u_to_s_zext_lshr_10FSuSi : $@convention(thin) (BuiltinUWord) -> BuiltinWord { bb0(%0 : $BuiltinUWord): - debug_value %0 : $BuiltinUWord // let x // id: %1 + debug_value %0 : $BuiltinUWord, let, name "x" // id: %1 %2 = integer_literal $Builtin.Word, 10 // user: %7 br bb1 // id: %3 @@ -94,7 +94,7 @@ bb3: // Preds: bb2 %19 = struct_extract %18 : $Int64, #Int64._value // user: %21 %21 = builtin "truncOrBitCast_Int64_Word"(%19 : $Builtin.Int64) : $Builtin.Word // user: %22 %22 = struct $BuiltinWord (%21 : $Builtin.Word) // users: %23, %24 - debug_value %22 : $BuiltinWord // let v1 // id: %23 + debug_value %22 : $BuiltinWord, let, name "v1" // id: %23 return %22 : $BuiltinWord // id: %24 } @@ -107,8 +107,8 @@ bb3: // Preds: bb2 // test.test_trunc_u_to_s_zext_lshr_var (Swift.BuiltinUWord, Swift.BuiltinUWord) -> Swift.BuiltinWord sil @_TF4test31test_trunc_u_to_s_zext_lshr_varFTSuSu_Si : $@convention(thin) (BuiltinUWord, BuiltinUWord) -> BuiltinWord { bb0(%0 : $BuiltinUWord, %1 : $BuiltinUWord): - debug_value %0 : $BuiltinUWord // let x // id: %2 - debug_value %1 : $BuiltinUWord // let c // id: %3 + debug_value %0 : $BuiltinUWord, let, name "x" // id: %2 + debug_value %1 : $BuiltinUWord, let, name "c" // id: %3 %4 = tuple () %5 = tuple () %6 = tuple () @@ -154,7 +154,7 @@ bb4: // Preds: bb2 %43 = struct_extract %42 : $Int64, #Int64._value // user: %45 %45 = builtin "truncOrBitCast_Int64_Word"(%43 : $Builtin.Int64) : $Builtin.Word // user: %46 %46 = struct $BuiltinWord (%45 : $Builtin.Word) // users: %47, %48 - debug_value %46 : $BuiltinWord // let v1 // id: %47 + debug_value %46 : $BuiltinWord, let, name "v1" // id: %47 return %46 : $BuiltinWord // id: %48 } @@ -168,7 +168,7 @@ bb4: // Preds: bb2 // test.test_uint16_trunc_u_to_s_zext_lshr_1 (Swift.UInt16) -> Swift.UInt16 sil @_TF4test36test_uint16_trunc_u_to_s_zext_lshr_1FVs6UInt16S0_ : $@convention(thin) (UInt16) -> UInt16 { bb0(%0 : $UInt16): - debug_value %0 : $UInt16 // let x // id: %1 + debug_value %0 : $UInt16, let, name "x" // id: %1 %2 = integer_literal $Builtin.Int16, 1 // user: %7 br bb1 // id: %3 @@ -191,7 +191,7 @@ bb3: // Preds: bb2 %18 = tuple_extract %16 : $(Builtin.Int16, Builtin.Int1), 1 // user: %19 cond_fail %18 : $Builtin.Int1 // id: %19 %20 = struct $UInt16 (%17 : $Builtin.Int16) // users: %21, %22 - debug_value %20 : $UInt16 // let v1 // id: %21 + debug_value %20 : $UInt16, let, name "v1" // id: %21 return %20 : $UInt16 // id: %22 } @@ -206,7 +206,7 @@ bb3: // Preds: bb2 // test.test_int16_trunc_u_to_s_zext_lshr_1 (Swift.UInt16) -> Swift.Int16 sil @_TF4test35test_int16_trunc_u_to_s_zext_lshr_1FVs6UInt16Vs5Int16 : $@convention(thin) (UInt16) -> Int16 { bb0(%0 : $UInt16): - debug_value %0 : $UInt16 // let x // id: %1 + debug_value %0 : $UInt16, let, name "x" // id: %1 %2 = integer_literal $Builtin.Int16, 1 // user: %7 br bb1 // id: %3 @@ -229,7 +229,7 @@ bb3: // Preds: bb2 %18 = tuple_extract %16 : $(Builtin.Int16, Builtin.Int1), 1 // user: %19 cond_fail %18 : $Builtin.Int1 // id: %19 %20 = struct $Int16 (%17 : $Builtin.Int16) // users: %21, %22 - debug_value %20 : $Int16 // let v1 // id: %21 + debug_value %20 : $Int16, let, name "v1" // id: %21 return %20 : $Int16 // id: %22 } @@ -243,7 +243,7 @@ bb3: // Preds: bb2 // test.test_trunc_s_to_u_zext_var (Swift.BuiltinWord) -> Swift.BuiltinUWord sil @_TF4test26test_trunc_s_to_u_zext_varFSiSu : $@convention(thin) (BuiltinWord) -> BuiltinUWord { bb0(%0 : $BuiltinWord): - debug_value %0 : $BuiltinWord // let x // id: %1 + debug_value %0 : $BuiltinWord, let, name "x" // id: %1 %3 = struct_extract %0 : $BuiltinWord, #BuiltinWord.value // user: %4 %4 = builtin "zextOrBitCast_Word_Int64"(%3 : $Builtin.Word) : $Builtin.Int64 // user: %6 %6 = builtin "s_to_u_checked_conversion_Int64"(%4 : $Builtin.Int64) : $(Builtin.Int64, Builtin.Int1) // users: %7, %8 @@ -288,7 +288,7 @@ bb0: // sizeof is known to return strictly positive values -// But Word->Int64 is not a safe conversion +// But Word ->Int64 is not a safe conversion // No peephole for UInt16(UInt32(sizeof(Int))) // CHECK-LABEL: sil @_TF4test35test_int16_trunc_s_to_u_zext_sizeofFT_Vs6UInt16 : $@convention(thin) () -> UInt16 // CHECK: builtin "zextOrBitCast_Word_Int64" @@ -331,7 +331,7 @@ bb0: // test.test_int16_trunc_s_to_u_zext_int16 (Swift.UInt16) -> Swift.UInt16 sil @_TF4test34test_int16_trunc_s_to_u_zext_int16FVs6UInt16S0_ : $@convention(thin) (UInt16) -> UInt16 { bb0(%0 : $UInt16): - debug_value %0 : $UInt16 // let x // id: %1 + debug_value %0 : $UInt16, let, name "x" // id: %1 %2 = integer_literal $Builtin.Int16, 1 // user: %7 br bb1 // id: %3 @@ -376,7 +376,7 @@ bb3: // Preds: bb2 // peephole_trunc_and_ext.test_s_to_s_checked_trunc_of_and (Swift.Int32) -> Swift.Int8 sil @_TF22peephole_trunc_and_ext32test_s_to_s_checked_trunc_of_andFVs5Int32Vs4Int8 : $@convention(thin) (Int32) -> Int8 { bb0(%0 : $Int32): - debug_value %0 : $Int32 // let x // id: %1 + debug_value %0 : $Int32, let, name "x" // id: %1 %2 = integer_literal $Builtin.Int32, 127 // user: %5 %4 = struct_extract %0 : $Int32, #Int32._value // user: %5 %5 = builtin "and_Int32"(%4 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int32 // user: %6 @@ -399,7 +399,7 @@ bb0(%0 : $Int32): // peephole_trunc_and_ext.test_s_to_u_checked_trunc_of_and (Swift.Int32) -> Swift.UInt8 sil @_TF22peephole_trunc_and_ext32test_s_to_u_checked_trunc_of_andFVs5Int32Vs5UInt8 : $@convention(thin) (Int32) -> UInt8 { bb0(%0 : $Int32): - debug_value %0 : $Int32 // let x // id: %1 + debug_value %0 : $Int32, let, name "x" // id: %1 %2 = integer_literal $Builtin.Int32, 255 // user: %5 %4 = struct_extract %0 : $Int32, #Int32._value // user: %5 %5 = builtin "and_Int32"(%4 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int32 // user: %6 @@ -422,7 +422,7 @@ bb0(%0 : $Int32): // peephole_trunc_and_ext.test_u_to_u_checked_trunc_of_and (Swift.UInt32) -> Swift.UInt8 sil @_TF22peephole_trunc_and_ext32test_u_to_u_checked_trunc_of_andFVs6UInt32Vs5UInt8 : $@convention(thin) (UInt32) -> UInt8 { bb0(%0 : $UInt32): - debug_value %0 : $UInt32 // let x // id: %1 + debug_value %0 : $UInt32, let, name "x" // id: %1 %2 = integer_literal $Builtin.Int32, 255 // user: %5 %4 = struct_extract %0 : $UInt32, #UInt32._value // user: %5 %5 = builtin "and_Int32"(%4 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int32 // user: %6 @@ -445,7 +445,7 @@ bb0(%0 : $UInt32): // peephole_trunc_and_ext.test_u_to_s_checked_trunc_of_and (Swift.UInt32) -> Swift.Int8 sil @_TF22peephole_trunc_and_ext32test_u_to_s_checked_trunc_of_andFVs6UInt32Vs4Int8 : $@convention(thin) (UInt32) -> Int8 { bb0(%0 : $UInt32): - debug_value %0 : $UInt32 // let x // id: %1 + debug_value %0 : $UInt32, let, name "x" // id: %1 %2 = integer_literal $Builtin.Int32, 127 // user: %5 %4 = struct_extract %0 : $UInt32, #UInt32._value // user: %5 %5 = builtin "and_Int32"(%4 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int32 // user: %6 diff --git a/test/SILPasses/performance_inliner.sil b/test/SILOptimizer/performance_inliner.sil similarity index 95% rename from test/SILPasses/performance_inliner.sil rename to test/SILOptimizer/performance_inliner.sil index 62f38f0be4556..4474d18a4116e 100644 --- a/test/SILPasses/performance_inliner.sil +++ b/test/SILOptimizer/performance_inliner.sil @@ -6,11 +6,11 @@ import Builtin import Swift ///////////////////// -// CallGraph Tests // +// Inlining Tests // ///////////////////// -// *NOTE* These tests currently validate whether or not the callgraph -// visits nodes in the correct order since we do not explore inlined +// *NOTE* These tests currently validate whether or not we +// visit nodes in the correct order since we do not explore inlined // code for more apply inst to inline. After that point, we will // probably need to do one of the following: // @@ -298,10 +298,10 @@ bb0(%0 : $*Builtin.Int64): sil @trivial_witness_method_caller : $@convention(thin) () -> () { %0 = alloc_stack $Builtin.Int64 %1 = integer_literal $Builtin.Int64, 0 - store %1 to %0#1 : $*Builtin.Int64 + store %1 to %0 : $*Builtin.Int64 %2 = function_ref @trivial_witness_method : $@convention(witness_method) (@inout Builtin.Int64) -> Builtin.Int64 - apply %2 (%0#1) : $@convention(witness_method) (@inout Builtin.Int64) -> Builtin.Int64 - dealloc_stack %0#0 : $*@local_storage Builtin.Int64 + apply %2 (%0) : $@convention(witness_method) (@inout Builtin.Int64) -> Builtin.Int64 + dealloc_stack %0 : $*Builtin.Int64 %3 = tuple() return %3 : $() } @@ -319,10 +319,10 @@ bb0(%0 : $*Builtin.Int64): sil @trivial_c_caller : $@convention(thin) () -> () { %0 = alloc_stack $Builtin.Int64 %1 = integer_literal $Builtin.Int64, 0 - store %1 to %0#1 : $*Builtin.Int64 + store %1 to %0 : $*Builtin.Int64 %2 = function_ref @trivial_c : $@convention(c) (@inout Builtin.Int64) -> Builtin.Int64 - apply %2 (%0#1) : $@convention(c) (@inout Builtin.Int64) -> Builtin.Int64 - dealloc_stack %0#0 : $*@local_storage Builtin.Int64 + apply %2 (%0) : $@convention(c) (@inout Builtin.Int64) -> Builtin.Int64 + dealloc_stack %0 : $*Builtin.Int64 %3 = tuple() return %3 : $() } @@ -345,10 +345,10 @@ bb0(%0 : $*Builtin.Int64): sil @trivial_objc_caller : $@convention(thin) () -> () { %0 = alloc_stack $Builtin.Int64 %1 = integer_literal $Builtin.Int64, 0 - store %1 to %0#1 : $*Builtin.Int64 + store %1 to %0 : $*Builtin.Int64 %2 = function_ref @trivial_objc : $@convention(objc_method) (@inout Builtin.Int64) -> Builtin.Int64 - apply %2 (%0#1) : $@convention(objc_method) (@inout Builtin.Int64) -> Builtin.Int64 - dealloc_stack %0#0 : $*@local_storage Builtin.Int64 + apply %2 (%0) : $@convention(objc_method) (@inout Builtin.Int64) -> Builtin.Int64 + dealloc_stack %0 : $*Builtin.Int64 %3 = tuple() return %3 : $() } @@ -598,8 +598,8 @@ entry: return %z : $() } -// Visiblity Tests -// These tests stem from a time where visiblity had an influence +// Visibility Tests +// These tests stem from a time where visibility had an influence // on the inlining. This is no longer the case so we just check // if everything can be inlined, regardless of visibility. @@ -819,15 +819,15 @@ sil public_external @public_external_function_test : $@convention(thin) () -> () // CHECK-LABEL: @caller_of_noinline sil @caller_of_noinline : $@convention(thin) () -> () { bb0: - // CHECK: function_ref @noinlin_callee + // CHECK: function_ref @noinline_callee // CHECK: apply - %0 = function_ref @noinlin_callee : $@convention(thin) () -> Int + %0 = function_ref @noinline_callee : $@convention(thin) () -> Int %1 = apply %0() : $@convention(thin) () -> Int %2 = tuple () return %2 : $() } -// CHECK-LABEL: [noinline] @noinlin_callee -sil [noinline] @noinlin_callee : $@convention(thin) () -> Int { +// CHECK-LABEL: [noinline] @noinline_callee +sil [noinline] @noinline_callee : $@convention(thin) () -> Int { bb0: %0 = function_ref @_TFSi33_convertFromBuiltinIntegerLiteralfMSiFBi2048_Si : $@convention(thin) (Builtin.Int2048, @thin Int.Type) -> Int %1 = metatype $@thin Int.Type @@ -874,11 +874,11 @@ bb0(%0 : $Int32): %4 = struct_extract %0 : $Int32, #Int32._value // user: %5 %5 = builtin "cmp_eq_Word"(%4 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int1 // user: %6 %6 = struct $Bool (%5 : $Builtin.Int1) // user: %7 - store %6 to %1#1 : $*Bool // id: %7 + store %6 to %1 : $*Bool // id: %7 %8 = function_ref @_TTSgSbSbs11BooleanType___TFs9_slowPathUs11BooleanType__FQ_Sb : $@convention(thin) (@in Bool) -> Bool // user: %9 - %9 = apply %8(%1#1) : $@convention(thin) (@in Bool) -> Bool // user: %10 + %9 = apply %8(%1) : $@convention(thin) (@in Bool) -> Bool // user: %10 %10 = struct_extract %9 : $Bool, #Bool._value // user: %12 - dealloc_stack %1#0 : $*@local_storage Bool // id: %11 + dealloc_stack %1 : $*Bool // id: %11 cond_br %10, bb1, bb2 // id: %12 bb1: // Preds: bb0 @@ -915,10 +915,10 @@ bb0: %v9 = alloc_stack $Bool %v12 = integer_literal $Builtin.Int1, 0 %v16 = struct $Bool (%v12 : $Builtin.Int1) - store %v16 to %v9#1 : $*Bool // id: %17 - %v18 = apply %f1(%v9#1) : $@convention(thin) <τ_0_0 where τ_0_0 : BooleanType> (@in τ_0_0) -> Bool + store %v16 to %v9 : $*Bool // id: %17 + %v18 = apply %f1(%v9) : $@convention(thin) <τ_0_0 where τ_0_0 : BooleanType> (@in τ_0_0) -> Bool %v19 = struct_extract %v18 : $Bool, #Bool._value - dealloc_stack %v9#0 : $*@local_storage Bool // id: %20 + dealloc_stack %v9 : $*Bool // id: %20 cond_br %v19, bb2, bb1 // id: %21 bb1: @@ -943,10 +943,10 @@ bb0: %v9 = alloc_stack $Bool %v12 = integer_literal $Builtin.Int1, 0 %v16 = struct $Bool (%v12 : $Builtin.Int1) - store %v16 to %v9#1 : $*Bool // id: %17 - %v18 = apply %f1(%v9#1) : $@convention(thin) <τ_0_0 where τ_0_0 : BooleanType> (@in τ_0_0) -> Bool + store %v16 to %v9 : $*Bool // id: %17 + %v18 = apply %f1(%v9) : $@convention(thin) <τ_0_0 where τ_0_0 : BooleanType> (@in τ_0_0) -> Bool %v19 = struct_extract %v18 : $Bool, #Bool._value - dealloc_stack %v9#0 : $*@local_storage Bool // id: %20 + dealloc_stack %v9 : $*Bool // id: %20 cond_br %v19, bb2, bb1 // id: %21 bb1: @@ -997,17 +997,17 @@ bb0(%0 : $C): %1 = integer_literal $Builtin.Int32, 1 %2 = struct $Int32 (%1 : $Builtin.Int32) %3 = alloc_stack $Int32 - store %2 to %3#1 : $*Int32 + store %2 to %3 : $*Int32 %5 = function_ref @theClosure : $@convention(thin) () -> (Int32, @error ErrorType) %6 = thin_to_thick_function %5 : $@convention(thin) () -> (Int32, @error ErrorType) to $@callee_owned () -> (Int32, @error ErrorType) %7 = function_ref @reabstractionThunk : $@convention(thin) (@out Int32, @owned @callee_owned () -> (Int32, @error ErrorType)) -> @error ErrorType %8 = partial_apply %7(%6) : $@convention(thin) (@out Int32, @owned @callee_owned () -> (Int32, @error ErrorType)) -> @error ErrorType %9 = alloc_stack $Int32 %10 = function_ref @callThrowing : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @owned @callee_owned (@out τ_0_0) -> @error ErrorType, @guaranteed C) -> () - %11 = apply %10(%9#1, %3#1, %8, %0) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @owned @callee_owned (@out τ_0_0) -> @error ErrorType, @guaranteed C) -> () - %12 = load %9#1 : $*Int32 - dealloc_stack %9#0 : $*@local_storage Int32 - dealloc_stack %3#0 : $*@local_storage Int32 + %11 = apply %10(%9, %3, %8, %0) : $@convention(method) <τ_0_0> (@out τ_0_0, @in τ_0_0, @owned @callee_owned (@out τ_0_0) -> @error ErrorType, @guaranteed C) -> () + %12 = load %9 : $*Int32 + dealloc_stack %9 : $*Int32 + dealloc_stack %3 : $*Int32 strong_release %0 : $C // CHECK: return return %12 : $Int32 diff --git a/test/SILPasses/polymorphic_inline_caches.sil b/test/SILOptimizer/polymorphic_inline_caches.sil similarity index 100% rename from test/SILPasses/polymorphic_inline_caches.sil rename to test/SILOptimizer/polymorphic_inline_caches.sil diff --git a/test/SILOptimizer/postdomtree_verification_crash.sil b/test/SILOptimizer/postdomtree_verification_crash.sil new file mode 100644 index 0000000000000..56afe090b5b07 --- /dev/null +++ b/test/SILOptimizer/postdomtree_verification_crash.sil @@ -0,0 +1,21 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -sil-verify-without-invalidation %s -compute-dominance-info + +// Check if post-dominator verification does not crash on multiple roots. + +sil_stage canonical + +import Builtin +import Swift + +sil @testit : $@convention(thin) () -> () { +bb0: + cond_br undef, bb1, bb2 + +bb1: + br bb1 + +bb2: + %r = tuple () + return %r : $() +} + diff --git a/test/SILPasses/predictable_memopt.sil b/test/SILOptimizer/predictable_memopt.sil similarity index 80% rename from test/SILPasses/predictable_memopt.sil rename to test/SILOptimizer/predictable_memopt.sil index 858a8d1e86ad4..5b9aa0024c698 100644 --- a/test/SILPasses/predictable_memopt.sil +++ b/test/SILOptimizer/predictable_memopt.sil @@ -61,7 +61,7 @@ sil @takes_Int_inout : $@convention(thin) (@inout Int) -> () // CHECK-LABEL: sil @used_by_inout sil @used_by_inout : $@convention(thin) (Int) -> (Int, Int) { bb0(%0 : $Int): - // This alloc_stack can't be removed since it is used by a inout call. + // This alloc_stack can't be removed since it is used by an inout call. // CHECK: %1 = alloc_box $Int %1 = alloc_box $Int %2 = store %0 to %1#1 : $*Int @@ -94,7 +94,7 @@ sil @returns_generic_struct : $@convention(thin) (@out AddressOnlyStruct) -> () sil @takes_closure : $@convention(thin) (@callee_owned () -> ()) -> () -sil @closure0 : $@convention(thin) (@owned @box Int, @inout Int) -> () +sil @closure0 : $@convention(thin) (@owned @box Int) -> () // CHECK-LABEL: sil @closure_test2 @@ -104,9 +104,9 @@ bb0(%1 : $Int): store %1 to %0#1 : $*Int // CHECK: store %5 = function_ref @takes_closure : $@convention(thin) (@callee_owned () -> ()) -> () - %6 = function_ref @closure0 : $@convention(thin) (@owned @box Int, @inout Int) -> () + %6 = function_ref @closure0 : $@convention(thin) (@owned @box Int) -> () strong_retain %0#0 : $@box Int - %8 = partial_apply %6(%0#0, %0#1) : $@convention(thin) (@owned @box Int, @inout Int) -> () + %8 = partial_apply %6(%0#0) : $@convention(thin) (@owned @box Int) -> () %9 = apply %5(%8) : $@convention(thin) (@callee_owned () -> ()) -> () strong_release %0#0 : $@box Int @@ -160,10 +160,10 @@ bb0(%0 : $Int32): // CHECK-NOT: alloc_stack - store %18 to %22#1 : $*Int32 - %24 = struct_element_addr %22#1 : $*Int32, #Int32._value + store %18 to %22 : $*Int32 + %24 = struct_element_addr %22 : $*Int32, #Int32._value %25 = load %24 : $*Builtin.Int32 - dealloc_stack %22#0 : $*@local_storage Int32 + dealloc_stack %22 : $*Int32 // CHECK-NEXT: return [[IL]] return %25 : $Builtin.Int32 } @@ -172,15 +172,15 @@ bb0(%0 : $Int32): sil @copy_addr_to_load : $@convention(thin) (Int) -> Int { bb0(%0 : $Int): // CHECK: bb0(%0 : $Int): %1 = alloc_stack $Int - store %0 to %1#1 : $*Int + store %0 to %1 : $*Int %2 = alloc_stack $Int - copy_addr %1#1 to [initialization] %2#1 : $*Int + copy_addr %1 to [initialization] %2 : $*Int - %3 = load %2#1 : $*Int + %3 = load %2 : $*Int - dealloc_stack %2#0 : $*@local_storage Int - dealloc_stack %1#0 : $*@local_storage Int + dealloc_stack %2 : $*Int + dealloc_stack %1 : $*Int // CHECK-NEXT: return %0 return %3 : $Int } @@ -190,14 +190,14 @@ bb0(%0 : $Int): // CHECK: bb0(%0 : $Int): sil @store_to_copyaddr : $(Bool) -> Bool { bb0(%0 : $Bool): // CHECK: bb0(%0 : %1 = alloc_stack $Bool - store %0 to %1#1 : $*Bool + store %0 to %1 : $*Bool %3 = alloc_stack $Bool - copy_addr %1#1 to [initialization] %3#1 : $*Bool - %5 = load %3#1 : $*Bool - copy_addr %3#1 to %1#1 : $*Bool - %12 = load %1#1 : $*Bool - dealloc_stack %3#0 : $*@local_storage Bool - dealloc_stack %1#0 : $*@local_storage Bool + copy_addr %1 to [initialization] %3 : $*Bool + %5 = load %3 : $*Bool + copy_addr %3 to %1 : $*Bool + %12 = load %1 : $*Bool + dealloc_stack %3 : $*Bool + dealloc_stack %1 : $*Bool return %12 : $Bool // CHECK-NEXT: return %0 } @@ -205,7 +205,7 @@ bb0(%0 : $Bool): // CHECK: bb0(%0 : sil @cross_block_load_promotion : $@convention(thin) (Int) -> Int { bb0(%0 : $Int): %1 = alloc_stack $Int - store %0 to %1#1 : $*Int + store %0 to %1 : $*Int %11 = integer_literal $Builtin.Int1, 1 cond_br %11, bb1, bb2 @@ -216,8 +216,8 @@ bb2: br bb5 bb5: - %15 = load %1#1 : $*Int - dealloc_stack %1#0 : $*@local_storage Int + %15 = load %1 : $*Int + dealloc_stack %1 : $*Int return %15 : $Int // CHECK: return %0 : $Int @@ -234,16 +234,16 @@ bb0(%0 : $Int, %2 : $Int): %7 = function_ref @init_xy_struct : $@convention(thin) () -> XYStruct %9 = apply %7() : $@convention(thin) () -> XYStruct - store %9 to %1#1 : $*XYStruct + store %9 to %1 : $*XYStruct - %11 = struct_element_addr %1#1 : $*XYStruct, #XYStruct.y + %11 = struct_element_addr %1 : $*XYStruct, #XYStruct.y store %0 to %11 : $*Int %12 = integer_literal $Builtin.Int1, 1 // user: %3 cond_br %12, bb1, bb2 bb1: // Preds: bb3 - %13 = struct_element_addr %1#1 : $*XYStruct, #XYStruct.x + %13 = struct_element_addr %1 : $*XYStruct, #XYStruct.x store %2 to %13 : $*Int br bb5 @@ -252,7 +252,7 @@ bb2: // Preds: bb0 bb5: // Preds: bb4 %15 = load %11 : $*Int - dealloc_stack %1#0 : $*@local_storage XYStruct + dealloc_stack %1 : $*XYStruct return %15 : $Int // CHECK: return %0 : $Int @@ -265,16 +265,16 @@ bb0(%0 : $Int, %2 : $Int): %7 = function_ref @init_xy_struct : $@convention(thin) () -> XYStruct %9 = apply %7() : $@convention(thin) () -> XYStruct - store %9 to %1#1 : $*XYStruct + store %9 to %1 : $*XYStruct - %11 = struct_element_addr %1#1 : $*XYStruct, #XYStruct.x + %11 = struct_element_addr %1 : $*XYStruct, #XYStruct.x store %0 to %11 : $*Int %12 = integer_literal $Builtin.Int1, 1 // user: %3 cond_br %12, bb1, bb2 bb1: // Preds: bb3 - %13 = struct_element_addr %1#1 : $*XYStruct, #XYStruct.x + %13 = struct_element_addr %1 : $*XYStruct, #XYStruct.x store %0 to %13 : $*Int br bb5 @@ -283,7 +283,7 @@ bb2: // Preds: bb0 bb5: // Preds: bb4 %15 = load %11 : $*Int - dealloc_stack %1#0 : $*@local_storage XYStruct + dealloc_stack %1 : $*XYStruct return %15 : $Int // CHECK: return %0 : $Int @@ -295,14 +295,14 @@ sil @destroy_addr : $@convention(method) (@owned SomeClass) -> @owned SomeClass bb0(%0 : $SomeClass): %1 = alloc_stack $SomeClass %2 = tuple () - store %0 to %1#1 : $*SomeClass - %7 = load %1#1 : $*SomeClass + store %0 to %1 : $*SomeClass + %7 = load %1 : $*SomeClass strong_retain %7 : $SomeClass strong_release %7 : $SomeClass - %12 = load %1#1 : $*SomeClass // users: %16, %13 + %12 = load %1 : $*SomeClass // users: %16, %13 strong_retain %12 : $SomeClass // id: %13 - destroy_addr %1#1 : $*SomeClass // id: %14 - dealloc_stack %1#0 : $*@local_storage SomeClass // id: %15 + destroy_addr %1 : $*SomeClass // id: %14 + dealloc_stack %1 : $*SomeClass // id: %15 return %12 : $SomeClass // id: %16 } @@ -321,9 +321,9 @@ bb0: %9 = apply %f() : $@convention(thin) () -> @owned SomeClass // CHECK: [[CVAL:%[0-9]+]] = apply - assign %9 to %3#1 : $*SomeClass - destroy_addr %3#1 : $*SomeClass - dealloc_stack %3#0 : $*@local_storage SomeClass + assign %9 to %3 : $*SomeClass + destroy_addr %3 : $*SomeClass + dealloc_stack %3 : $*SomeClass %15 = tuple () return %15 : $() // CHECK-NEXT: strong_release [[CVAL]] @@ -333,13 +333,13 @@ bb0: // CHECK-LABEL: sil @init_existential_crash sil @init_existential_crash : $() -> () { %99 = alloc_stack $BooleanType - %100 = init_existential_addr %99#1 : $*BooleanType, $Bool + %100 = init_existential_addr %99 : $*BooleanType, $Bool %105 = integer_literal $Builtin.Int1, 0 %106 = struct $Bool (%105 : $Builtin.Int1) store %106 to %100 : $*Bool %108 = struct_element_addr %100 : $*Bool, #Bool._value %109 = load %108 : $*Builtin.Int1 - dealloc_stack %99#0 : $*@local_storage BooleanType + dealloc_stack %99 : $*BooleanType return undef : $() } @@ -350,11 +350,11 @@ sil @dead_allocation_1 : $@convention(thin) (Optional) -> () { // CHECK: retain_value %0 %1 = alloc_stack $Optional %2 = alloc_stack $Optional - store %0 to %2#1 : $*Optional + store %0 to %2 : $*Optional // CHECK-NOT: copy_addr - copy_addr %2#1 to [initialization] %1#1 : $*Optional - dealloc_stack %2#0 : $*@local_storage Optional - dealloc_stack %1#0 : $*@local_storage Optional + copy_addr %2 to [initialization] %1 : $*Optional + dealloc_stack %2 : $*Optional + dealloc_stack %1 : $*Optional %3 = tuple () return %3 : $() } @@ -366,11 +366,11 @@ sil @dead_allocation_2 : $@convention(thin) (Optional) -> () { // CHECK-NOT: alloc_stack %1 = alloc_stack $Optional %2 = alloc_stack $Optional - store %0 to %1#1 : $*Optional + store %0 to %1 : $*Optional // CHECK-NOT: copy_addr - copy_addr %1#1 to [initialization] %2#1 : $*Optional - dealloc_stack %2#0 : $*@local_storage Optional - dealloc_stack %1#0 : $*@local_storage Optional + copy_addr %1 to [initialization] %2 : $*Optional + dealloc_stack %2 : $*Optional + dealloc_stack %1 : $*Optional %3 = tuple () return %3 : $() } diff --git a/test/SILPasses/predictable_memopt_unreferenceable_storage.swift b/test/SILOptimizer/predictable_memopt_unreferenceable_storage.swift similarity index 100% rename from test/SILPasses/predictable_memopt_unreferenceable_storage.swift rename to test/SILOptimizer/predictable_memopt_unreferenceable_storage.swift diff --git a/test/SILPasses/prespecialize.swift b/test/SILOptimizer/prespecialize.swift similarity index 100% rename from test/SILPasses/prespecialize.swift rename to test/SILOptimizer/prespecialize.swift diff --git a/test/SILPasses/protocol_lookup.swift b/test/SILOptimizer/protocol_lookup.swift similarity index 100% rename from test/SILPasses/protocol_lookup.swift rename to test/SILOptimizer/protocol_lookup.swift diff --git a/test/SILPasses/pure_apply.swift b/test/SILOptimizer/pure_apply.swift similarity index 92% rename from test/SILPasses/pure_apply.swift rename to test/SILOptimizer/pure_apply.swift index 0c7a18b7a8af2..9141f0bd5f3c1 100644 --- a/test/SILPasses/pure_apply.swift +++ b/test/SILOptimizer/pure_apply.swift @@ -11,14 +11,14 @@ class Foo { sil @_TFC4main3Food : $@convention(method) (@owned Foo) -> @owned Builtin.NativeObject { bb0(%0 : $Foo): - debug_value %0 : $Foo // let self // id: %1 + debug_value %0 : $Foo, let, name "self" // id: %1 %2 = unchecked_ref_cast %0 : $Foo to $Builtin.NativeObject // user: %3 return %2 : $Builtin.NativeObject // id: %3 } sil @_TFC4main3FooD : $@convention(method) (@owned Foo) -> () { bb0(%0 : $Foo): - debug_value %0 : $Foo // let self // id: %1 + debug_value %0 : $Foo, let, name "self" // id: %1 // function_ref main.Foo.deinit %2 = function_ref @_TFC4main3Food : $@convention(method) (@owned Foo) -> @owned Builtin.NativeObject // user: %3 %3 = apply %2(%0) : $@convention(method) (@owned Foo) -> @owned Builtin.NativeObject // user: %4 @@ -30,7 +30,7 @@ bb0(%0 : $Foo): sil @_TFC4main3FoocfMS0_FT_S0_ : $@convention(method) (@owned Foo) -> @owned Foo { bb0(%0 : $Foo): - debug_value %0 : $Foo // let self // id: %1 + debug_value %0 : $Foo, let, name "self" // id: %1 return %0 : $Foo // id: %2 } @@ -62,7 +62,7 @@ bb0: // function_ref main.readonly_func () -> main.Foo %0 = function_ref @_TF4main9readonly_funcFT_CS_3Foo : $@convention(thin) () -> @owned Foo // user: %1 %1 = apply %0() : $@convention(thin) () -> @owned Foo // users: %2, %3 - debug_value %1 : $Foo // let unused // id: %2 + debug_value %1 : $Foo, let, name "unused" // id: %2 strong_release %1 : $Foo // id: %3 %4 = tuple () // user: %5 return %4 : $() // id: %5 diff --git a/test/SILOptimizer/rcidentity.sil b/test/SILOptimizer/rcidentity.sil new file mode 100644 index 0000000000000..24ea9c529b60d --- /dev/null +++ b/test/SILOptimizer/rcidentity.sil @@ -0,0 +1,110 @@ +// RUN: %target-sil-opt -rc-id-dumper %s -o /dev/null | FileCheck %s + +import Builtin + +/////////////////////// +// NonTest Utilities // +/////////////////////// + +protocol FakeAnyObject : class {} + +class C : FakeAnyObject { + init() +} + +class D : C { + override init() +} + +class E { + init() +} + +sil @foo : $@convention(thin) (Builtin.Word) -> () + +struct S1 { + var f1 : Builtin.Word + var f2 : Builtin.NativeObject + var f3 : Builtin.NativeObject +} + +struct S2 { + var f1 : Builtin.Word + var f2 : S1 + var f3 : Builtin.Word +} + +struct S3 { + var f1 : Builtin.Word + var f2 : Builtin.Word + var f3 : Builtin.NativeObject +} + +struct S4 { + var f1 : S3 + var f2 : Builtin.Word + var f5 : Builtin.Word +} + +enum E1 { + case Case1 + case Case2(S1) + case Case3(Builtin.Word) +} + +/////////// +// Tests // +/////////// + +// Make sure that we see all the way through the chain of casts that %9 has an RCIdentity of %0 and that %12 is really the partial apply. +// CHECK-LABEL: @test_rcid_preserving_casts@ +// CHECK: RESULT #9: 9 = 0 +// CHECK: RESULT #12: 12 = 11 +sil @test_rcid_preserving_casts : $@convention(thin) (Builtin.NativeObject) -> () { +bb0(%0 : $Builtin.NativeObject): + %1 = unconditional_checked_cast %0 : $Builtin.NativeObject to $D + %2 = upcast %1 : $D to $C + %3 = unchecked_ref_cast %2 : $C to $E + %4 = integer_literal $Builtin.Word, 0 + %5 = ref_to_bridge_object %3 : $E, %4 : $Builtin.Word + %6 = bridge_object_to_ref %5 : $Builtin.BridgeObject to $C + %7 = init_existential_ref %6 : $C : $C, $FakeAnyObject + %8 = open_existential_ref %7 : $FakeAnyObject to $@opened("A2E21C52-6089-11E4-9866-3C0754723233") FakeAnyObject + %9 = unchecked_ref_cast %8 : $@opened("A2E21C52-6089-11E4-9866-3C0754723233") FakeAnyObject to $Builtin.NativeObject + %10 = function_ref @foo : $@convention(thin) (Builtin.Word) -> () + %11 = partial_apply %10(%4) : $@convention(thin) (Builtin.Word) -> () + %12 = convert_function %11 : $@callee_owned @convention(thick) () -> () to $@callee_owned @convention(thick) () -> () + return undef : $() +} + +// Make sure that we look through structs with only one reference counted fields +// and that we do not look through structs without that property. +// +// CHECK-LABEL: @test_single_refcount_field_structs@ +// CHECK: RESULT #2: 2 = 0 +// CHECK: RESULT #3: 3 = 0 +// CHECK: RESULT #4: 4 = 4 +// CHECK: RESULT #5: 5 = 4 +sil @test_single_refcount_field_structs : $@convention(thin) (Builtin.NativeObject, Builtin.Word) -> () { +bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Word): + %2 = struct $S3(%1 : $Builtin.Word, %1 : $Builtin.Word, %0 : $Builtin.NativeObject) + %3 = struct $S4(%2 : $S3, %1 : $Builtin.Word, %1 : $Builtin.Word) + + %4 = struct $S1(%1 : $Builtin.Word, %0 : $Builtin.NativeObject, %0 : $Builtin.NativeObject) + %5 = struct $S2(%1 : $Builtin.Word, %4 : $S1, %1 : $Builtin.Word) + return undef : $() +} + +// CHECK-LABEL: @test_single_refcount_field_tuples@ +// CHECK: RESULT #2: 2 = 0 +// CHECK: RESULT #3: 3 = 0 +// CHECK: RESULT #4: 4 = 4 +// CHECK: RESULT #5: 5 = 4 +sil @test_single_refcount_field_tuples : $@convention(thin) (Builtin.NativeObject, Builtin.Word) -> () { +bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Word): + %2 = tuple(%1 : $Builtin.Word, %1 : $Builtin.Word, %0 : $Builtin.NativeObject) + %3 = tuple(%2 : $(Builtin.Word, Builtin.Word, Builtin.NativeObject), %1 : $Builtin.Word, %1 : $Builtin.Word) + %4 = tuple(%1 : $Builtin.Word, %0 : $Builtin.NativeObject, %0 : $Builtin.NativeObject) + %5 = tuple(%1 : $Builtin.Word, %4 : $(Builtin.Word, Builtin.NativeObject, Builtin.NativeObject), %1 : $Builtin.Word) + return undef : $() +} diff --git a/test/SILPasses/recursive_func.sil b/test/SILOptimizer/recursive_func.sil similarity index 95% rename from test/SILPasses/recursive_func.sil rename to test/SILOptimizer/recursive_func.sil index 797c10de82785..55ef7dbf5d5e4 100644 --- a/test/SILPasses/recursive_func.sil +++ b/test/SILOptimizer/recursive_func.sil @@ -31,8 +31,8 @@ bb0(%c : $Builtin.Int32, %v : $Builtin.RawPointer): sil @REC_recursive : $@convention(method) (Int, @guaranteed REC) -> () { bb0(%0 : $Int, %1 : $REC): - debug_value %0 : $Int // let a // id: %2 - debug_value %1 : $REC // let self // id: %3 + debug_value %0 : $Int, let, name "a" // id: %2 + debug_value %1 : $REC, let, name "self" // id: %3 // function_ref Swift.Bool._getBuiltinLogicValue (Swift.Bool)() -> Builtin.Int1 %4 = function_ref @_TFSb21_getBuiltinLogicValuefSbFT_Bi1_ : $@convention(method) (Bool) -> Builtin.Int1 // user: %11 // function_ref Swift.>= @infix (Swift.Int, Swift.Int) -> Swift.Bool @@ -92,7 +92,7 @@ sil [transparent] @_TFsoi1sFTSiSi_Si : $@convention(thin) (Int, Int) -> Int // test.REC.deinit sil @_TFC4test3RECd : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject { bb0(%0 : $REC): - debug_value %0 : $REC // let self // id: %1 + debug_value %0 : $REC, let, name "self" // id: %1 %2 = unchecked_ref_cast %0 : $REC to $Builtin.NativeObject // user: %3 return %2 : $Builtin.NativeObject // id: %3 } @@ -100,7 +100,7 @@ bb0(%0 : $REC): // test.REC.__deallocating_deinit sil @_TFC4test3RECD : $@convention(method) (@owned REC) -> () { bb0(%0 : $REC): - debug_value %0 : $REC // let self // id: %1 + debug_value %0 : $REC, let, name "self" // id: %1 // function_ref test.REC.deinit %2 = function_ref @_TFC4test3RECd : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject // user: %3 %3 = apply %2(%0) : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject // user: %4 @@ -113,7 +113,7 @@ bb0(%0 : $REC): // test.REC.init (test.REC.Type)() -> test.REC sil @_TFC4test3RECcfMS0_FT_S0_ : $@convention(method) (@owned REC) -> @owned REC { bb0(%0 : $REC): - debug_value %0 : $REC // let self // id: %1 + debug_value %0 : $REC, let, name "self" // id: %1 %2 = mark_uninitialized [rootself] %0 : $REC // user: %3 return %2 : $REC // id: %3 } @@ -131,12 +131,12 @@ bb0(%0 : $@thick REC.Type): // test.test (Swift.Int) -> () sil @_TF4test4testFSiT_ : $@convention(thin) (Int) -> () { bb0(%0 : $Int): - debug_value %0 : $Int // let N // id: %1 + debug_value %0 : $Int, let, name "N" // id: %1 // function_ref test.REC.__allocating_init (test.REC.Type)() -> test.REC %2 = function_ref @_TFC4test3RECCfMS0_FT_S0_ : $@convention(thin) (@thick REC.Type) -> @owned REC // user: %4 %3 = metatype $@thick REC.Type // user: %4 %4 = apply %2(%3) : $@convention(thin) (@thick REC.Type) -> @owned REC // users: %5, %6, %7, %8, %9 - debug_value %4 : $REC // let rec // id: %5 + debug_value %4 : $REC, let, name "rec" // id: %5 strong_retain %4 : $REC // id: %6 %7 = class_method %4 : $REC, #REC.recursive!1 : REC -> (Int) -> () , $@convention(method) (Int, @guaranteed REC) -> () // user: %8 %8 = apply %7(%0, %4) : $@convention(method) (Int, @guaranteed REC) -> () diff --git a/test/SILPasses/recursive_single.sil b/test/SILOptimizer/recursive_single.sil similarity index 94% rename from test/SILPasses/recursive_single.sil rename to test/SILOptimizer/recursive_single.sil index 070c8e9439c05..83ad8cb2870aa 100644 --- a/test/SILPasses/recursive_single.sil +++ b/test/SILOptimizer/recursive_single.sil @@ -33,8 +33,8 @@ bb0(%c : $Builtin.Int32, %v : $Builtin.RawPointer): // single.REC.recursive (single.REC)(Swift.Int) -> () sil @_TFC6single3REC9recursivefS0_FSiT_ : $@convention(method) (Int, @guaranteed REC) -> () { bb0(%0 : $Int, %1 : $REC): - debug_value %0 : $Int // let a // id: %2 - debug_value %1 : $REC // let self // id: %3 + debug_value %0 : $Int, let, name "a" // id: %2 + debug_value %1 : $REC, let, name "self" // id: %3 // function_ref Swift.Bool._getBuiltinLogicValue (Swift.Bool)() -> Builtin.Int1 %4 = function_ref @_TFSb21_getBuiltinLogicValuefSbFT_Bi1_ : $@convention(method) (Bool) -> Builtin.Int1 // user: %11 // function_ref Swift.>= @infix (Swift.Int, Swift.Int) -> Swift.Bool @@ -83,7 +83,7 @@ sil [transparent] @_TFsoi1sFTSiSi_Si : $@convention(thin) (Int, Int) -> Int // single.REC.deinit sil @_TFC6single3RECd : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject { bb0(%0 : $REC): - debug_value %0 : $REC // let self // id: %1 + debug_value %0 : $REC, let, name "self" // id: %1 %2 = unchecked_ref_cast %0 : $REC to $Builtin.NativeObject // user: %3 return %2 : $Builtin.NativeObject // id: %3 } @@ -91,7 +91,7 @@ bb0(%0 : $REC): // single.REC.__deallocating_deinit sil @_TFC6single3RECD : $@convention(method) (@owned REC) -> () { bb0(%0 : $REC): - debug_value %0 : $REC // let self // id: %1 + debug_value %0 : $REC, let, name "self" // id: %1 // function_ref single.REC.deinit %2 = function_ref @_TFC6single3RECd : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject // user: %3 %3 = apply %2(%0) : $@convention(method) (@owned REC) -> @owned Builtin.NativeObject // user: %4 @@ -104,7 +104,7 @@ bb0(%0 : $REC): // single.REC.init (single.REC.Type)() -> single.REC sil @_TFC6single3RECcfMS0_FT_S0_ : $@convention(method) (@owned REC) -> @owned REC { bb0(%0 : $REC): - debug_value %0 : $REC // let self // id: %1 + debug_value %0 : $REC, let, name "self" // id: %1 %2 = mark_uninitialized [rootself] %0 : $REC // user: %3 return %2 : $REC // id: %3 } @@ -122,12 +122,12 @@ bb0(%0 : $@thick REC.Type): // single.test (Swift.Int) -> () sil @_TF6single4testFSiT_ : $@convention(thin) (Int) -> () { bb0(%0 : $Int): - debug_value %0 : $Int // let N // id: %1 + debug_value %0 : $Int, let, name "N" // id: %1 // function_ref single.REC.__allocating_init (single.REC.Type)() -> single.REC %2 = function_ref @_TFC6single3RECCfMS0_FT_S0_ : $@convention(thin) (@thick REC.Type) -> @owned REC // user: %4 %3 = metatype $@thick REC.Type // user: %4 %4 = apply %2(%3) : $@convention(thin) (@thick REC.Type) -> @owned REC // users: %5, %6, %7, %8, %9 - debug_value %4 : $REC // let rec // id: %5 + debug_value %4 : $REC, let, name "rec" // id: %5 strong_retain %4 : $REC // id: %6 %7 = class_method %4 : $REC, #REC.recursive!1 : REC -> (Int) -> () , $@convention(method) (Int, @guaranteed REC) -> () // user: %8 %8 = apply %7(%0, %4) : $@convention(method) (Int, @guaranteed REC) -> () diff --git a/test/SILOptimizer/redundantloadelimination.sil b/test/SILOptimizer/redundantloadelimination.sil new file mode 100644 index 0000000000000..ce18781f62067 --- /dev/null +++ b/test/SILOptimizer/redundantloadelimination.sil @@ -0,0 +1,899 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -module-name Swift -redundant-load-elim -dce | FileCheck %s + +import Builtin + +typealias I32 = Builtin.Int32 + +/////////////////////// +// Type Declarations // +/////////////////////// + +struct Int { + var value : Builtin.Int64 +} + +struct Int32 { + var value : Builtin.Int32 +} + +struct Int64 { + var value : Builtin.Int64 +} + +struct Bool { + var value : Builtin.Int1 +} + +class AX { + final var current: Int32 + init() +} + +struct A { + var i : Builtin.Int32 +} + +struct AA { + var a : A + var i : Builtin.Int32 +} + +class B { + var i : Builtin.Int32 + init() +} + +struct X { + var c : B + init() +} + +struct Agg2 { + var t : (Builtin.Int64, Builtin.Int32) +} + +struct Agg1 { + var a : Agg2 +} + +enum Optional { + case None + case Some(T) +} + +class E : B { } + +struct C { + var i : Builtin.Int16 +} + +struct D { + var p : Builtin.RawPointer +} + +struct Wrapper { + var value : Builtin.Int32 +} + +class AB { + var value: Int + init(value: Int) + deinit +} + +enum XYZ { + case A + case B((Int32, Int32)) + case C(Int32) +} + +struct TwoField { + var a: Int + var b: Int + init(a: Int, b: Int) + init() +} + + +sil @use : $@convention(thin) (Builtin.Int32) -> () +sil @use_Int : $@convention(thin) (Int) -> () +sil @use_64 : $@convention(thin) (Builtin.Int64) -> () +sil @use_2_64 : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () +sil @use_a : $@convention(thin) (A) -> () +sil @use_twofield : $@convention(thin) (TwoField) -> () +sil @escaped_a_ptr : $@convention(thin) (@out A) -> () +sil @escaped_a : $@convention(thin) () -> Builtin.RawPointer +sil @init_twofield : $@convention(thin) (@thin TwoField.Type) -> TwoField + +// Check that we don't crash if the address is an unchecked_addr_cast. +// CHECK-LABEL: sil @test_unchecked_addr_cast +// CHECK-NOT: load +// CHECK: return +sil @test_unchecked_addr_cast : $@convention(thin) (@inout A, A) -> A { +bb0(%0 : $*A, %1 : $A): + %2 = unchecked_addr_cast %0 : $*A to $*A + store %1 to %2 : $*A + %l1 = load %2 : $*A + return %l1 : $A +} + +// Multi-BB version of the previous test. +// CHECK-LABEL: sil @test_forwarding_ignoring_unchecked_addr_cast2 : $@convention(thin) (@inout A, A, A) -> A { +// CHECK: bb1 +// CHECK-NOT: load +// CHECK: cond_br +sil @test_forwarding_ignoring_unchecked_addr_cast2 : $@convention(thin) (@inout A, A, A) -> A { +bb0(%0 : $*A, %1 : $A, %2: $A): + %3 = unchecked_addr_cast %0 : $*A to $*A + store %1 to %3 : $*A + br bb1 + +bb1: + %5 = load %3 : $*A + %6 = load %3 : $*A + store %2 to %3 : $*A + cond_br undef, bb1, bb2 + +bb2: + return %5 : $A +} + +// CHECK-LABEL: sil @test_read_dependence_allows_forwarding_multi_bb_1 : $@convention(thin) (@inout A, A) -> A { +// CHECK: bb0 +// CHECK: store +// CHECK: bb1 +// CHECK: store +// CHECK-NOT: load +// CHECK: cond_br +sil @test_read_dependence_allows_forwarding_multi_bb_1 : $@convention(thin) (@inout A, A) -> A { +bb0(%0 : $*A, %1 : $A): + store %1 to %0 : $*A + %2 = unchecked_addr_cast %0 : $*A to $*A + %3 = unchecked_addr_cast %2 : $*A to $*A + br bb1 + +bb1: + // This means that the first store is not dead. + %4 = load %3 : $*A + // But we still should be able to forward this load. + %5 = load %0 : $*A + // We need to dedup this store to trigger the self loop + // forwarding. Once we do the full optimistic data flow this will no + // longer be needed. + %6 = load %0 : $*A + store %1 to %0 : $*A + cond_br undef, bb1, bb2 + +bb2: + return %5 : $A +} + +// DISABLE this test for now. it seems DCE is not getting rid of the load in bb8 after the RLE happens. +// +// Make sure the switch does not affect the forwarding of the load. +// switch_enum cannot have BBArgument, but the %17 = load %2 : $*Int32 is not produced in the +// switch basic block. +// DISABLE_CHECK-LABEL: load_elimination_disregard_switch_enum +// DISABLE_CHECK: bb8 +// DISABLE_CHECK-NOT: load +// DISABLE_CHECK: return +sil @load_elimination_disregard_switch_enum : $@convention(thin) (Int32, Int32, @inout Int32) -> Int32 { +// %0 // user: %4 +// %1 // user: %4 +// %2 // users: %17, %19 +bb0(%0 : $Int32, %1 : $Int32, %2 : $*Int32): + cond_br undef, bb7, bb1 // id: %3 + +bb1: // Preds: bb0 + %4 = tuple (%0 : $Int32, %1 : $Int32) // user: %5 + %5 = enum $XYZ, #XYZ.B!enumelt.1, %4 : $(Int32, Int32) // user: %6 + switch_enum %5 : $XYZ, case #XYZ.A!enumelt: bb2, case #XYZ.B!enumelt.1: bb4, case #XYZ.C!enumelt.1: bb6 // id: %6 + +bb2: // Preds: bb1 + br bb3 // id: %7 + +bb3: // Preds: bb2 + %8 = integer_literal $Builtin.Int32, 0 // user: %9 + %9 = struct $Int32 (%8 : $Builtin.Int32) + br bb5 // id: %10 + +// %11 // user: %12 +bb4(%11 : $(Int32, Int32)): // Preds: bb1 + %12 = tuple_extract %11 : $(Int32, Int32), 0 + br bb5 // id: %13 + +bb5: // Preds: bb4 bb5 bb6 + br bb5 // id: %14 + +bb6(%15 : $Int32): // Preds: bb1 + br bb5 // id: %16 + +bb7: // Preds: bb0 + %17 = load %2 : $*Int32 + br bb8 // id: %18 + +bb8: // Preds: bb3 bb7 + %19 = load %2 : $*Int32 // user: %20 + return %19 : $Int32 // id: %20 +} + + +// The load should be eliminated here. but currently is not ... Look into why +// +// CHECK-LABEL: sil @load_store_forwarding_from_aggregate_to_field +sil @load_store_forwarding_from_aggregate_to_field : $@convention(thin) (Agg1) -> (Builtin.Int32) { +bb0(%0 : $Agg1): + %1 = alloc_stack $Agg1 + store %0 to %1 : $*Agg1 + %2 = struct_element_addr %1 : $*Agg1, #Agg1.a + %3 = struct_element_addr %2 : $*Agg2, #Agg2.t + %4 = tuple_element_addr %3 : $*(Builtin.Int64, Builtin.Int32), 1 + %5 = load %4 : $*Builtin.Int32 + dealloc_stack %1 : $*Agg1 + return %5 : $Builtin.Int32 +} + +sil_global @total : $Int32 + +// CHECK-LABEL: sil @store_promotion +// CHECK: store +// CHECK-NEXT: strong_retain +// CHECK-NEXT: strong_retain +// CHECK: return +sil @store_promotion : $@convention(thin) (@owned B) -> () { +bb0(%0 : $B): + %1 = alloc_box $B + %2 = store %0 to %1#1 : $*B + %3 = load %1#1 : $*B + %4 = load %1#1 : $*B + %5 = strong_retain %3 : $B + %6 = strong_retain %4 : $B + %7 = tuple() + %8 = return %7 : $() +} + +// CHECK-LABEL: sil @eliminate_duplicate_loads_over_noread_builtins +// CHECK: bb0 +// CHECK-NEXT: [[LOAD_RESULT:%[0-9]+]] = load +// CHECK-NEXT: integer_literal +// CHECK-NEXT: builtin "sadd_with_overflow_Int64"([[LOAD_RESULT]] : ${{.*}}, [[LOAD_RESULT]] +// CHECK-NEXT: [[APPLY_RESULT:%[0-9]+]] = tuple_extract +// CHECK-NEXT: builtin "sadd_with_overflow_Int64"([[LOAD_RESULT]] : ${{.*}}, [[APPLY_RESULT]] +// CHECK-NEXT: tuple_extract +// CHECK-NEXT: return +sil @eliminate_duplicate_loads_over_noread_builtins : $@convention(thin) (@inout Builtin.Int64) -> (Builtin.Int64) { +bb0(%0 : $*Builtin.Int64): + %1 = load %0 : $*Builtin.Int64 + %3 = integer_literal $Builtin.Int1, 0 + %4 = builtin "sadd_with_overflow_Int64"(%1 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %5 = load %0 : $*Builtin.Int64 + %6 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 0 + %7 = builtin "sadd_with_overflow_Int64"(%5 : $Builtin.Int64, %6 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %8 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 0 + return %8 : $Builtin.Int64 +} + +// CHECK-LABEL: sil @load_store_forwarding_over_noread_builtins +// CHECK: bb0 +// CHECK-NEXT: load +// CHECK-NEXT: integer_literal +// CHECK-NEXT: builtin +// CHECK-NEXT: tuple_extract +// CHECK-NEXT: store +// CHECK-NEXT: builtin +// CHECK-NEXT: tuple_extract +// CHECK-NEXT: builtin +// CHECK-NEXT: tuple_extract +// CHECK-NEXT: return +sil @load_store_forwarding_over_noread_builtins : $@convention(thin) (@inout Builtin.Int64, @inout Builtin.Int64) -> (Builtin.Int64) { +bb0(%0 : $*Builtin.Int64, %1 : $*Builtin.Int64): + %2 = load %0 : $*Builtin.Int64 + %4 = integer_literal $Builtin.Int1, 0 + %5 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %2 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %6 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 0 + store %6 to %1 : $*Builtin.Int64 + %8 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %2 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 0 + %10 = load %1 : $*Builtin.Int64 + %11 = builtin "sadd_with_overflow_Int64"(%10 : $Builtin.Int64, %9 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) + %12 = tuple_extract %11 : $(Builtin.Int64, Builtin.Int1), 0 + return %12 : $Builtin.Int64 +} + +// CHECK-LABEL: sil @load_store_forwarding_over_dealloc_stack +// CHECK: bb0 +// CHECK-NEXT: alloc_stack $Builtin.Int64 +// CHECK-NEXT: alloc_stack $Builtin.Int64 +// CHECK-NEXT: store +// CHECK-NEXT: alloc_stack $Builtin.Int64 +// CHECK-NEXT: load +// CHECK: dealloc_stack +// CHECK-NOT: load +// CHECK: return +sil @load_store_forwarding_over_dealloc_stack : $@convention(thin) (Builtin.Int64) -> (Builtin.Int64) { +bb0(%0 : $Builtin.Int64): + %1 = alloc_stack $Builtin.Int64 + %2 = alloc_stack $Builtin.Int64 + store %0 to %1 : $*Builtin.Int64 + %3 = alloc_stack $Builtin.Int64 + %5 = load %2 : $*Builtin.Int64 + %22 = function_ref @use_64 : $@convention(thin) (Builtin.Int64) -> () + %23 = apply %22(%5) : $@convention(thin) (Builtin.Int64) -> () + dealloc_stack %3 : $*Builtin.Int64 + %4 = load %1 : $*Builtin.Int64 + store %0 to %1 : $*Builtin.Int64 + %6 = load %2 : $*Builtin.Int64 + %222 = function_ref @use_2_64 : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () + %232 = apply %222(%4, %6) : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () + dealloc_stack %2 : $*Builtin.Int64 + dealloc_stack %1 : $*Builtin.Int64 + return %4 : $Builtin.Int64 +} + +// CHECK-LABEL: sil @load_dedup_forwarding_from_aggregate_to_field +// CHECK: bb0([[INPUT_PTR:%[0-9]+]] +// CHECK-NEXT: load [[INPUT_PTR]] +// CHECK-NEXT: struct_extract +// CHECK-NEXT: struct_extract +// CHECK-NEXT: tuple_extract +// CHECK-NEXT: return +sil @load_dedup_forwarding_from_aggregate_to_field : $@convention(thin) (@inout Agg1) -> (Builtin.Int32) { +bb0(%0 : $*Agg1): + %1 = load %0 : $*Agg1 + %2 = struct_element_addr %0 : $*Agg1, #Agg1.a + %3 = struct_element_addr %2 : $*Agg2, #Agg2.t + %4 = tuple_element_addr %3 : $*(Builtin.Int64, Builtin.Int32), 1 + %5 = load %4 : $*Builtin.Int32 + return %5 : $Builtin.Int32 +} + +// CHECK-LABEL: promote_partial_load +// CHECK: alloc_stack +// CHECK-NOT: load +// CHECK: [[RESULT:%[0-9]+]] = struct_extract +// CHECK: return [[RESULT]] +sil @promote_partial_load : $@convention(thin) (Builtin.Int32) -> Builtin.Int32 { +bb0(%0 : $Builtin.Int32): + %1 = alloc_stack $Wrapper + %2 = struct $Wrapper (%0 : $Builtin.Int32) + store %2 to %1 : $*Wrapper + %3 = struct_element_addr %1 : $*Wrapper, #Wrapper.value + %4 = load %3 : $*Builtin.Int32 + dealloc_stack %1 : $*Wrapper + return %4 : $Builtin.Int32 +} + +// TODO: HANDLE THIS, THIS IS SAME VALUE STORES. +// +// CHECK-LABEL: sil @store_loaded_value +sil @store_loaded_value : $@convention(thin) (@inout Agg2, @inout Agg1) -> () { +bb0(%0 : $*Agg2, %1 : $*Agg1): + %2 = load %1 : $*Agg1 + %3 = load %0 : $*Agg2 + %4 = store %2 to %1 : $*Agg1 + %5 = store %3 to %0 : $*Agg2 + %6 = tuple() + %7 = return %6 : $() +} + +// *NOTE* This does not handle raw pointer since raw pointer is only layout compatible with heap references. +// CHECK-LABEL: sil @store_to_load_forward_unchecked_addr_cast_struct : $@convention(thin) (Optional) -> () { +// CHECK: bb0([[INPUT:%[0-9]+]] +// CHECK-NOT: load +// CHECK: return +sil @store_to_load_forward_unchecked_addr_cast_struct : $@convention(thin) (Optional) -> () { +bb0(%0 : $Optional): + %1 = alloc_stack $Optional + store %0 to %1 : $*Optional + %2 = unchecked_addr_cast %1 : $*Optional to $*Builtin.Int32 + %3 = load %2 : $*Builtin.Int32 + %4 = unchecked_addr_cast %1 : $*Optional to $*A + %5 = load %4 : $*A + %6 = unchecked_addr_cast %1 : $*Optional to $*Builtin.RawPointer + %7 = load %6 : $*Builtin.RawPointer + %8 = unchecked_addr_cast %1 : $*Optional to $*Builtin.NativeObject + %9 = load %8 : $*Builtin.NativeObject + %10 = unchecked_addr_cast %1 : $*Optional to $*Optional + %11 = load %10 : $*Optional + %12 = unchecked_addr_cast %1 : $*Optional to $*Optional + %13 = load %12 : $*Optional + %14 = unchecked_addr_cast %1 : $*Optional to $*Optional + %15 = load %14 : $*Optional + dealloc_stack %1 : $*Optional + %9999 = tuple() + return %9999 : $() +} + +// Check load forwarding across strong_release in case the stored memory does +// not escape. +// CHECK-LABEL: sil @test_store_forwarding_strong_release +// CHECK: strong_release +// CHECK-NOT: [[BOX0:%.*]] = load +// CHECK: apply +sil @test_store_forwarding_strong_release : $@convention(thin) (B, X) -> () { +bb0(%0 : $B, %1 : $X): + %2 = alloc_stack $A // users: %3, %13 + %3 = struct_element_addr %2 : $*A, #A.i // users: %5, %10 + %4 = integer_literal $Builtin.Int32, 32 // user: %5 + store %4 to %3 : $*Builtin.Int32 // id: %5 + %6 = ref_to_unowned %0 : $B to $@sil_unowned B // user: %7 + unowned_release %6 : $@sil_unowned B // id: %7 + strong_release %0 : $B // id: %8 + release_value %1 : $X // id: %9 + %10 = load %3 : $*Builtin.Int32 // user: %12 + // function_ref use + %11 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %12 + %12 = apply %11(%10) : $@convention(thin) (Builtin.Int32) -> () + dealloc_stack %2 : $*A // id: %13 + %14 = tuple () // user: %15 + return %14 : $() +} + +// Check load forwarding across strong_release in case the loaded memory does +// not escape. +// CHECK-LABEL: sil @test_load_forwarding_strong_release +// CHECK: strong_release +// CHECK-NOT: [[BOX0:%.*]] = load +// CHECK: apply +sil @test_load_forwarding_strong_release : $@convention(thin) (B, X) -> () { +bb0(%0 : $B, %1 : $X): + %2 = alloc_stack $A // users: %3, %12 + %3 = struct_element_addr %2 : $*A, #A.i // users: %4, %9 + %4 = load %3 : $*Builtin.Int32 + %5 = ref_to_unowned %0 : $B to $@sil_unowned B // user: %6 + unowned_release %5 : $@sil_unowned B // id: %6 + strong_release %0 : $B // id: %7 + release_value %1 : $X // id: %8 + %9 = load %3 : $*Builtin.Int32 // user: %11 + // function_ref use + %10 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %11 + %11 = apply %10(%9) : $@convention(thin) (Builtin.Int32) -> () + dealloc_stack %2 : $*A // id: %12 + %13 = tuple () // user: %14 + return %13 : $() // id: %14 +} + +// Make sure we RLE the second load. +// +// CHECK-LABEL: test_simple_rle_in_class +// CHECK: load +// CHECK-NOT: load +// CHECK: cond_fail +sil hidden @test_simple_rle_in_class : $@convention(thin) (@owned AB) -> Int { +bb0(%0 : $AB): + %2 = ref_element_addr %0 : $AB, #AB.value // user: %3 + %3 = load %2 : $*Int // user: %6 + %4 = ref_element_addr %0 : $AB, #AB.value // user: %5 + %5 = load %4 : $*Int // user: %7 + %6 = struct_extract %3 : $Int, #Int.value // user: %9 + %7 = struct_extract %5 : $Int, #Int.value // user: %9 + %8 = integer_literal $Builtin.Int1, -1 // user: %9 + %9 = builtin "sadd_with_overflow_Int64"(%6 : $Builtin.Int64, %7 : $Builtin.Int64, %8 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // users: %10, %11 + %10 = tuple_extract %9 : $(Builtin.Int64, Builtin.Int1), 0 // user: %13 + %11 = tuple_extract %9 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12 + cond_fail %11 : $Builtin.Int1 // id: %12 + %13 = struct $Int (%10 : $Builtin.Int64) // user: %15 + strong_release %0 : $AB // id: %14 + return %13 : $Int // id: %15 +} + +// Make sure we RLE the load in BB2. +// +// CHECK-LABEL: test_silargument_rle +// CHECK: bb2 +// CHECK-NOT: load +// CHECK: cond_br +sil @test_silargument_rle : $@convention(thin) () -> () { +bb0: + %0 = global_addr @total : $*Int32 + %1 = integer_literal $Builtin.Int32, 0 + %2 = struct $Int32 (%1 : $Builtin.Int32) + store %2 to %0 : $*Int32 + %6 = alloc_ref $AX + %8 = ref_element_addr %6 : $AX, #AX.current + store %2 to %8 : $*Int32 + // %10 = load %8 : $*Int32 + cond_br undef, bb3, bb2 + +bb2: + %24 = integer_literal $Builtin.Int1, -1 + %31 = struct_element_addr %0 : $*Int32, #Int32.value + %32 = load %31 : $*Builtin.Int32 + %33 = builtin "sadd_with_overflow_Int32"(%32 : $Builtin.Int32, %1 : $Builtin.Int32, %24 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) + %34 = tuple_extract %33 : $(Builtin.Int32, Builtin.Int1), 0 + %37 = struct $Int32 (%34 : $Builtin.Int32) + store %37 to %0 : $*Int32 + cond_br undef, bb3, bb2 + +bb3: + strong_release %6 : $AX + %44 = tuple () + return %44 : $() +} + +// CHECK-LABEL: sil @load_to_load_forwarding_diamonds : $@convention(thin) (@inout Builtin.Int32) -> Builtin.Int32 { +// CHECK: load +// CHECK-NOT: load +// CHECK: return +sil @load_to_load_forwarding_diamonds : $@convention(thin) (@inout Builtin.Int32) -> Builtin.Int32 { +bb0(%0 : $*Builtin.Int32): + %1 = load %0 : $*Builtin.Int32 + // Simple diamond. + cond_br undef, bb1, bb2 + +bb1: + br bb3 + +bb2: + br bb3 + +bb3: + // Triangle + cond_br undef, bb4, bb5 + +bb4: + br bb5 + +bb5: + %2 = load %0 : $*Builtin.Int32 + return %2 : $Builtin.Int32 +} + + +// CHECK-LABEL: sil @load_to_load_conflicting_branches_diamond : $@convention(thin) (@inout Builtin.Int32) -> () { +// CHECK: bb0( +// CHECK: load +// CHECK: bb1: +// CHECK-NOT: load +// CHECK: store +// CHECK-NOT: load +// CHECK: bb2: +// CHECK: bb3: +// CHECK: load +sil @load_to_load_conflicting_branches_diamond : $@convention(thin) (@inout Builtin.Int32) -> () { +// %0 // users: %1, %4, %9, %11, %16, %21 +bb0(%0 : $*Builtin.Int32): + %1 = load %0 : $*Builtin.Int32 // user: %2 + %2 = builtin "trunc_Int32_Int1"(%1 : $Builtin.Int32) : $Builtin.Int1 + cond_br undef, bb1, bb2 // id: %3 + +bb1: // Preds: bb0 + %4 = load %0 : $*Builtin.Int32 // users: %6, %8, %10 + // function_ref use + %5 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %6 + %6 = apply %5(%4) : $@convention(thin) (Builtin.Int32) -> () + %7 = integer_literal $Builtin.Int32, 2 // user: %9 + %8 = builtin "trunc_Int32_Int1"(%4 : $Builtin.Int32) : $Builtin.Int1 + store %7 to %0 : $*Builtin.Int32 // id: %9 + %10 = builtin "trunc_Int32_Int1"(%4 : $Builtin.Int32) : $Builtin.Int1 + %11 = load %0 : $*Builtin.Int32 // users: %13, %14 + // function_ref use + %12 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %13 + %13 = apply %12(%11) : $@convention(thin) (Builtin.Int32) -> () + %14 = builtin "trunc_Int32_Int1"(%11 : $Builtin.Int32) : $Builtin.Int1 + br bb3 // id: %15 + +bb2: // Preds: bb0 + %16 = load %0 : $*Builtin.Int32 // users: %18, %19 + // function_ref use + %17 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %18 + %18 = apply %17(%16) : $@convention(thin) (Builtin.Int32) -> () + %19 = builtin "trunc_Int32_Int1"(%16 : $Builtin.Int32) : $Builtin.Int1 + br bb3 // id: %20 + +bb3: // Preds: bb1 bb2 + %21 = load %0 : $*Builtin.Int32 // user: %23 + // function_ref use + %22 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 + %23 = apply %22(%21) : $@convention(thin) (Builtin.Int32) -> () + %24 = tuple () // user: %25 + return %24 : $() // id: %25 +} + +// Forward store %1 and store %2 such that load %3 becomes an identity trivial cast. +// Both loads from %0 will be eliminated. +// CHECK-LABEL: sil @test_read_dependence_allows_forwarding_multi_bb_2 : $@convention(thin) (@inout A, A, A) -> A { +// CHECK: bb1 +// CHECK: load +// CHECK-NOT: load +// CHECK: bb2 +sil @test_read_dependence_allows_forwarding_multi_bb_2 : $@convention(thin) (@inout A, A, A) -> A { +bb0(%0 : $*A, %1 : $A, %2 : $A): + store %1 to %0 : $*A + %3 = unchecked_addr_cast %0 : $*A to $*A + %4 = unchecked_addr_cast %3 : $*A to $*A + br bb1 + +bb1: + // This means that the first store is not dead. + %6 = load %3 : $*A + %7 = load %0 : $*A + %8 = load %0 : $*A + %22 = function_ref @use_a : $@convention(thin) (A) -> () + %123 = apply %22(%6) : $@convention(thin) (A) -> () + %223 = apply %22(%7) : $@convention(thin) (A) -> () + %323 = apply %22(%8) : $@convention(thin) (A) -> () + store %2 to %0 : $*A + cond_br undef, bb1, bb2 + +bb2: + return %7 : $A +} + +// CHECK-LABEL: sil @load_to_load_loop +sil @load_to_load_loop : $@convention(thin) () -> () { +bb0: + %101 = alloc_stack $Int32 + %102 = alloc_stack $Int32 + %0 = struct_element_addr %101 : $*Int32, #Int32.value + %1 = struct_element_addr %102 : $*Int32, #Int32.value + %2 = load %0 : $*Builtin.Int32 + %99 = load %1 : $*Builtin.Int32 + %125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 + %126 = apply %125(%2) : $@convention(thin) (Builtin.Int32) -> () + %127 = apply %125(%99) : $@convention(thin) (Builtin.Int32) -> () + br bb1 + +bb1: + %4 = load %0 : $*Builtin.Int32 + %5 = integer_literal $Builtin.Int32, 2 + %1125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 + %1126 = apply %1125(%4) : $@convention(thin) (Builtin.Int32) -> () + store %5 to %0 : $*Builtin.Int32 + builtin "trunc_Int32_Int1"(%4 : $Builtin.Int32) : $Builtin.Int1 + %6 = load %0 : $*Builtin.Int32 + %11125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 + %11126 = apply %11125(%6) : $@convention(thin) (Builtin.Int32) -> () + cond_br undef, bb1, bb2 + +bb2: + %7 = load %0 : $*Builtin.Int32 + %111125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 + %111126 = apply %111125(%7) : $@convention(thin) (Builtin.Int32) -> () + dealloc_stack %102 : $*Int32 + dealloc_stack %101 : $*Int32 + %9999 = tuple() + return %9999 : $() +} + +// CHECK-LABEL: store_and_load_to_load_branches_diamond +// CHECK: bb3 +// CHECK-NOT: load +// CHECK: return +sil @store_and_load_to_load_branches_diamond : $@convention(thin) (@inout Builtin.Int32) -> () { +// %0 // users: %1, %4, %9, %11, %16, %21 +bb0(%0 : $*Builtin.Int32): + cond_br undef, bb1, bb2 // id: %3 + +bb1: // Preds: bb0 + %1 = load %0 : $*Builtin.Int32 // user: %2 + br bb3 // id: %15 + +bb2: // Preds: bb0 + %5 = integer_literal $Builtin.Int32, 2 + store %5 to %0 : $*Builtin.Int32 + br bb3 // id: %20 + +bb3: // Preds: bb1 bb2 + %21 = load %0 : $*Builtin.Int32 // user: %23 + // function_ref use + %22 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 + %23 = apply %22(%21) : $@convention(thin) (Builtin.Int32) -> () + %24 = tuple () // user: %25 + return %24 : $() // id: %25 +} + +// CHECK-LABEL: agg_and_field_store_branches_diamond +// CHECK: bb3 +// CHECK-NOT: load +// CHECK: return +sil hidden @agg_and_field_store_branches_diamond : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $TwoField, var, name "x" // users: %6, %11, %16, %21, %24 + %7 = struct_extract %0 : $Bool, #Bool.value // user: %8 + cond_br %7, bb1, bb2 // id: %8 + +bb1: // Preds: bb0 + %9 = integer_literal $Builtin.Int64, 10 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %12 + store %10 to %11 : $*Int // id: %12 + %14 = integer_literal $Builtin.Int64, 20 // user: %15 + %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 + %16 = struct_element_addr %1 : $*TwoField, #TwoField.b // user: %17 + store %15 to %16 : $*Int // id: %17 + br bb3 // id: %13 + +bb2: // Preds: bb0 + %3 = function_ref @init_twofield : $@convention(thin) (@thin TwoField.Type) -> TwoField // user: %5 + %4 = metatype $@thin TwoField.Type // user: %5 + %5 = apply %3(%4) : $@convention(thin) (@thin TwoField.Type) -> TwoField // user: %6 + store %5 to %1 : $*TwoField // id: %6 + br bb3 // id: %18 + +bb3: // Preds: bb1 bb2 + %99 = load %1 : $*TwoField // id: %6 + %991 = function_ref @use_twofield : $@convention(thin) (TwoField) -> () // user: %5 + %55 = apply %991(%99) : $@convention(thin) (TwoField) -> () // user: %6 + %23 = tuple () // user: %25 + dealloc_stack %1 : $*TwoField // id: %24 + return %23 : $() // id: %25 +} + +// CHECK-LABEL: agg_and_field_store_with_the_same_value +// CHECK: bb2 +// CHECK-NOT: load +// CHECK: return +sil hidden @agg_and_field_store_with_the_same_value : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $TwoField, var, name "x" // users: %6, %11, %16, %21, %24 + %7 = struct_extract %0 : $Bool, #Bool.value // user: %8 + br bb1 + +bb1: // Preds: bb0 + %9 = integer_literal $Builtin.Int64, 10 // user: %10 + %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 + %11 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %12 + store %10 to %11 : $*Int // id: %12 + %16 = struct_element_addr %1 : $*TwoField, #TwoField.b // user: %17 + store %10 to %16 : $*Int // id: %17 + br bb2 // id: %13 + +bb2: // Preds: bb1 bb2 + %99 = load %1 : $*TwoField // id: %6 + %991 = function_ref @use_twofield : $@convention(thin) (TwoField) -> () // user: %5 + %55 = apply %991(%99) : $@convention(thin) (TwoField) -> () // user: %6 + %23 = tuple () // user: %25 + dealloc_stack %1 : $*TwoField // id: %24 + return %23 : $() // id: %25 +} + +// Make sure we form a single SILArgument. +// +// CHECK-LABEL: single_silargument_agg_in_one_block +// CHECK: bb3([[ARG:%.*]] : $TwoField): +// CHECK-NOT: load +// CHECK: return +sil hidden @single_silargument_agg_in_one_block : $@convention(thin) (Bool) -> () { +bb0(%0 : $Bool): + %1 = alloc_stack $TwoField, var, name "x" // users: %5, %7, %13, %15, %19 + cond_br undef, bb1, bb2 // id: %2 + +bb1: // Preds: bb0 + %3 = integer_literal $Builtin.Int64, 10 // user: %4 + %4 = struct $Int (%3 : $Builtin.Int64) // users: %6, %8 + %5 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %6 + store %4 to %5 : $*Int // id: %6 + %7 = struct_element_addr %1 : $*TwoField, #TwoField.b // user: %8 + store %4 to %7 : $*Int // id: %8 + br bb3 // id: %9 + +bb2: // Preds: bb0 + %10 = integer_literal $Builtin.Int64, 10 // user: %11 + %11 = struct $Int (%10 : $Builtin.Int64) // users: %12, %12 + %12 = struct $TwoField (%11 : $Int, %11 : $Int) // user: %13 + store %12 to %1 : $*TwoField // id: %13 + br bb3 // id: %14 + +bb3: // Preds: bb1 bb2 + %15 = load %1 : $*TwoField // user: %17 + // function_ref use_twofield + %16 = function_ref @use_twofield : $@convention(thin) (TwoField) -> () // user: %17 + %17 = apply %16(%15) : $@convention(thin) (TwoField) -> () + %18 = tuple () // user: %20 + dealloc_stack %1 : $*TwoField // id: %19 + return %18 : $() // id: %20 +} + +// CHECK-LABEL: large_diamond_silargument_forwarding +// CHECK: bb9 +// CHECK-NOT: load +// CHECK: return +sil hidden @large_diamond_silargument_forwarding : $@convention(thin) (Bool) -> Int { +bb0(%0 : $Bool): + %1 = alloc_stack $TwoField, var, name "x" // users: %7, %10, %13, %16, %21, %23 + %2 = integer_literal $Builtin.Int64, 10 // user: %3 + %3 = struct $Int (%2 : $Builtin.Int64) // users: %8, %11, %14, %17 + cond_br undef, bb1, bb2 // id: %4 + +bb1: // Preds: bb0 + cond_br undef, bb3, bb4 // id: %5 + +bb2: // Preds: bb0 + cond_br undef, bb5, bb6 // id: %6 + +bb3: // Preds: bb1 + %7 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %8 + store %3 to %7 : $*Int // id: %8 + br bb7 // id: %9 + +bb4: // Preds: bb1 + %10 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %11 + store %3 to %10 : $*Int // id: %11 + br bb7 // id: %12 + +bb5: // Preds: bb2 + %13 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %14 + store %3 to %13 : $*Int // id: %14 + br bb8 // id: %15 + +bb6: // Preds: bb2 + %16 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %17 + store %3 to %16 : $*Int // id: %17 + br bb8 // id: %18 + +bb7: // Preds: bb3 bb4 + br bb9 // id: %19 + +bb8: // Preds: bb5 bb6 + br bb9 // id: %20 + +bb9: // Preds: bb7 bb8 + %21 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %22 + %22 = load %21 : $*Int // user: %24 + dealloc_stack %1 : $*TwoField // id: %23 + return %22 : $Int // id: %24 +} + +// Make sure we can re-use the SILArgument inserted in bb8 for forwarding +// in bb9 and bb10. +// +// CHECK-LABEL: reuse_silargument_multiple_bb_forwarding +// CHECK: bb8([[ARG:%.*]] : $Int) +// CHECK: bb9 +// CHECK-NOT: load +// CHECK: bb10 +// CHECK-NOT: load +// CHECK: return +sil hidden @reuse_silargument_multiple_bb_forwarding : $@convention(thin) (Bool) -> Int { +bb0(%0 : $Bool): + %1 = alloc_stack $TwoField, var, name "x" // users: %7, %10, %13, %16, %21, %26, %28 + %2 = integer_literal $Builtin.Int64, 10 // user: %3 + %3 = struct $Int (%2 : $Builtin.Int64) // users: %8, %11, %14, %17 + cond_br undef, bb1, bb2 // id: %4 + +bb1: // Preds: bb0 + cond_br undef, bb3, bb4 // id: %5 + +bb2: // Preds: bb0 + cond_br undef, bb5, bb6 // id: %6 + +bb3: // Preds: bb1 + %7 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %8 + store %3 to %7 : $*Int // id: %8 + br bb7 // id: %9 + +bb4: // Preds: bb1 + %10 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %11 + store %3 to %10 : $*Int // id: %11 + br bb7 // id: %12 + +bb5: // Preds: bb2 + %13 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %14 + store %3 to %13 : $*Int // id: %14 + br bb8 // id: %15 + +bb6: // Preds: bb2 + %16 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %17 + store %3 to %16 : $*Int // id: %17 + br bb8 // id: %18 + +bb7: // Preds: bb3 bb4 + br bb10 // id: %19 + +bb8: // Preds: bb5 bb6 + cond_br undef, bb9, bb10 // id: %20 + +bb9: // Preds: bb8 + %21 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %22 + %22 = load %21 : $*Int // user: %24 + %23 = function_ref @use_Int : $@convention(thin) (Int) -> () // user: %24 + %24 = apply %23(%22) : $@convention(thin) (Int) -> () + br bb10 // id: %25 + +bb10: // Preds: bb7 bb8 bb9 + %26 = struct_element_addr %1 : $*TwoField, #TwoField.a // user: %27 + %27 = load %26 : $*Int // user: %29 + dealloc_stack %1 : $*TwoField // id: %28 + return %27 : $Int // id: %29 +} diff --git a/test/SILPasses/ref_elt_addr.sil b/test/SILOptimizer/ref_elt_addr.sil similarity index 100% rename from test/SILPasses/ref_elt_addr.sil rename to test/SILOptimizer/ref_elt_addr.sil diff --git a/test/SILPasses/remove_pins.sil b/test/SILOptimizer/remove_pins.sil similarity index 100% rename from test/SILPasses/remove_pins.sil rename to test/SILOptimizer/remove_pins.sil diff --git a/test/SILPasses/remove_unused_func.sil b/test/SILOptimizer/remove_unused_func.sil similarity index 100% rename from test/SILPasses/remove_unused_func.sil rename to test/SILOptimizer/remove_unused_func.sil diff --git a/test/SILPasses/return.swift b/test/SILOptimizer/return.swift similarity index 94% rename from test/SILPasses/return.swift rename to test/SILOptimizer/return.swift index d50a89f99d660..35cf71232fe67 100644 --- a/test/SILPasses/return.swift +++ b/test/SILOptimizer/return.swift @@ -6,7 +6,7 @@ func singleBlock() -> Int { func singleBlock2() -> Int { var y = 0 - y++ + y += 1 } // expected-error {{missing return in a function expected to return 'Int'}} class MyClassWithClosure { @@ -18,24 +18,24 @@ func multipleBlocksSingleMissing(b: Bool) -> (String, Int) { if b { return ("a", 1) } else if (y == 0) { - y++ + y += 1 } } // expected-error {{missing return in a function expected to return '(String, Int)'}} func multipleBlocksAllMissing(x: Int) -> Int { var y : Int = x + 1 while (y > 0 ) { - --y; - break; + y -= 1 + break } var x = 0 - x++ + x += 1 } // expected-error {{missing return in a function expected to return 'Int'}} @noreturn func MYsubscriptNonASCII(idx: Int) -> UnicodeScalar { } // no-warning -@noreturn @_silgen_name("exit") func exit ()->() +@noreturn @_silgen_name("exit") func exit () -> () @noreturn func tryingToReturn (x: Bool) -> () { if x { return // expected-error {{return from a 'noreturn' function}} @@ -76,22 +76,22 @@ func diagnose_missing_return_no_error_after_noreturn_method() -> Int { } // no error func whileLoop(flag: Bool) -> Int { - var b = 1; + var b = 1 while (flag) { if b == 3 { return 3 } - b++ + b += 1 } } //expected-error {{missing return in a function expected to return 'Int'}} func whileTrueLoop() -> Int { - var b = 1; + var b = 1 while (true) { if b == 3 { return 3 } - b++ + b += 1 } // no-error } @@ -101,7 +101,7 @@ func testUnreachableAfterNoReturn(x: Int) -> Int { } func testUnreachableAfterNoReturnInADifferentBlock() -> Int { - let x:Int = 5; + let x:Int = 5 if true { // expected-note {{condition always evaluates to true}} exit(); } @@ -116,10 +116,10 @@ func testReachableAfterNoReturnInADifferentBlock(x: Int) -> Int { } func testUnreachableAfterNoReturnFollowedByACall() -> Int { - let x:Int = 5; + let x:Int = 5 exit(); // expected-note{{a call to a noreturn function}} exit(); // expected-warning {{will never be executed}} - return x; + return x } func testUnreachableAfterNoReturnMethod() -> Int { diff --git a/test/SILPasses/select_enum_addr_reads_memory.sil b/test/SILOptimizer/select_enum_addr_reads_memory.sil similarity index 75% rename from test/SILPasses/select_enum_addr_reads_memory.sil rename to test/SILOptimizer/select_enum_addr_reads_memory.sil index 23af3c7c3abe9..2995da1b38270 100644 --- a/test/SILPasses/select_enum_addr_reads_memory.sil +++ b/test/SILOptimizer/select_enum_addr_reads_memory.sil @@ -14,7 +14,7 @@ bb0: %i1 = integer_literal $Builtin.Int1, -1 %0 = alloc_stack $TestEnum %1 = enum $TestEnum, #TestEnum.A!enumelt - store %1 to %0#1 : $*TestEnum + store %1 to %0 : $*TestEnum br bb1 // CHECK: bb1: @@ -24,17 +24,17 @@ bb1: // CHECK: apply // CHECK: [[X:%[0-9]+]] = select_enum_addr // CHECK: cond_br [[X]] - %x1 = select_enum_addr %0#1 : $*TestEnum, case #TestEnum.A!enumelt: %i0, default %i1 : $Builtin.Int1 + %x1 = select_enum_addr %0 : $*TestEnum, case #TestEnum.A!enumelt: %i0, default %i1 : $Builtin.Int1 cond_br %x1, bb2, bb3 bb2: %6 = function_ref @writeEnum: $@convention(thin) (@inout TestEnum) -> () - %7 = apply %6(%0#1) : $@convention(thin) (@inout TestEnum) -> () + %7 = apply %6(%0) : $@convention(thin) (@inout TestEnum) -> () br bb1 bb3: %9 = tuple () - dealloc_stack %0#0 : $*@local_storage TestEnum + dealloc_stack %0 : $*TestEnum return %9 : $() } diff --git a/test/SILAnalysis/side-effect.sil b/test/SILOptimizer/side-effect.sil similarity index 94% rename from test/SILAnalysis/side-effect.sil rename to test/SILOptimizer/side-effect.sil index 5ed9b23be36a5..1bce9c843cd49 100644 --- a/test/SILAnalysis/side-effect.sil +++ b/test/SILOptimizer/side-effect.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt %s -side-effects -sil-print-side-effects -o /dev/null | FileCheck %s +// RUN: %target-sil-opt %s -side-effects-dump -o /dev/null | FileCheck %s // REQUIRES: asserts @@ -34,9 +34,9 @@ bb0(%0 : $X, %1 : $*Int32, %2 : $*Int32): %s = alloc_stack $Int32 %f = function_ref @load_store_to_args : $@convention(thin) (@inout Int32, @inout Int32, @guaranteed X) -> () - %ap = apply %f(%1, %s#1, %0) : $@convention(thin) (@inout Int32, @inout Int32, @guaranteed X) -> () + %ap = apply %f(%1, %s, %0) : $@convention(thin) (@inout Int32, @inout Int32, @guaranteed X) -> () - dealloc_stack %s#0 : $*@local_storage Int32 + dealloc_stack %s : $*Int32 %r = tuple () return %r : $() } @@ -128,9 +128,9 @@ bb0(%0 : $Int32): %l2 = load %b#1 : $*Int32 %s = alloc_stack $Int32 - store %0 to %s#1 : $*Int32 - %l3 = load %s#1 : $*Int32 - dealloc_stack %s#0 : $*@local_storage Int32 + store %0 to %s : $*Int32 + %l3 = load %s : $*Int32 + dealloc_stack %s : $*Int32 %r = tuple () return %r : $() @@ -246,17 +246,6 @@ bb0(%0 : $EP): return %l : $Builtin.Int32 } -// CHECK-LABEL: sil @arraysemantics_is_native -// CHECK: -sil @arraysemantics_is_native : $@convention(thin) (Array) -> () { -bb0(%0 : $Array): - %f = function_ref @isNative_Int : $@convention(method) (@guaranteed Array) -> Bool - %a = apply %f(%0) : $@convention(method) (@guaranteed Array) -> Bool - - %r = tuple() - return %r : $() -} - // CHECK-LABEL: sil @arraysemantics_is_native_no_typecheck // CHECK: sil @arraysemantics_is_native_no_typecheck : $@convention(thin) (Array) -> () { @@ -377,7 +366,6 @@ bb0(%0 : $Array): return %r : $() } -sil [_semantics "array.props.isNative"] @isNative_Int : $@convention(method) (@guaranteed Array) -> Bool sil [_semantics "array.props.isNativeTypeChecked"] @isNativeTypeChecked_Int : $@convention(method) (@guaranteed Array) -> Bool sil [_semantics "array.check_subscript"] @check_subscript_Int : $@convention(method) (Int32, Bool, @guaranteed Array) -> () sil [_semantics "array.check_index"] @check_index_Int : $@convention(method) (Int32, @guaranteed Array) -> () @@ -392,8 +380,14 @@ sil [_semantics "array.get_count"] @get_count_X : $@convention(method) (@guarant // CHECK: sil @call_noreturn : $@convention(thin) () -> () { bb0: + cond_br undef, bb1, bb2 + +bb1: %u = function_ref @exitfunc : $@convention(thin) @noreturn () -> () %a = apply %u() : $@convention(thin) @noreturn () -> () + unreachable + +bb2: %r = tuple () return %r : $() } diff --git a/test/SILPasses/sil_combine.sil b/test/SILOptimizer/sil_combine.sil similarity index 88% rename from test/SILPasses/sil_combine.sil rename to test/SILOptimizer/sil_combine.sil index 6322a556bf4f4..4c61bc23c1221 100644 --- a/test/SILPasses/sil_combine.sil +++ b/test/SILOptimizer/sil_combine.sil @@ -1,7 +1,5 @@ // RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -verify-skip-unreachable-must-be-last | FileCheck %s -// XFAIL: linux - sil_stage canonical import Builtin @@ -178,8 +176,8 @@ bb2: sil @dead_use_of_alloc_stack : $@convention(thin) () -> () { bb0: %1 = alloc_stack $((), (), ()) - %2 = tuple_element_addr %1#1 : $*((), (), ()), 0 - dealloc_stack %1#0 : $*@local_storage ((), (), ()) + %2 = tuple_element_addr %1 : $*((), (), ()), 0 + dealloc_stack %1 : $*((), (), ()) %3 = tuple () return %3 : $() } @@ -694,48 +692,6 @@ bb0(%0 : $*X): return %19 : $() } -sil @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> -sil @reabstruction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - -// CHECK-LABEL: sil @dead_closure_elimination : $@convention(thin) (@owned _StringCore) -> () -// CHECK: bb0 -// CHECK-NEXT: release_value -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @dead_closure_elimination : $@convention(thin) (@owned _StringCore) -> () { -bb0(%0 : $_StringCore): - %1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> - %2 = partial_apply %1(%0) : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> - %3 = function_ref @reabstruction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - %4 = partial_apply %3(%2) : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () - %5 = tuple() - return %5 : $() -} - -// CHECK-LABEL: sil @dead_closure_elimination2 -// CHECK: bb0 -// CHECK-NEXT: br bb1 -// CHECK: bb1 -// CHECK-NEXT: release_value -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @dead_closure_elimination2 : $@convention(thin) (@owned _StringCore) -> () { -bb0(%0 : $_StringCore): - %1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> - %2 = partial_apply %1(%0) : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> - %3 = function_ref @reabstruction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - %4 = partial_apply %3(%2) : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () - br bb1 - -bb1: - strong_retain %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () - strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () - strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () - %5 = tuple() - return %5 : $() -} - sil @unbalanced_closure : $@convention(thin) (@guaranteed B) -> () // CHECK-LABEL: sil @partial_apply_unbalanced_retain_release @@ -847,16 +803,16 @@ bb0(%0 : $Builtin.Int32): %6 = alloc_stack $Builtin.Int32 // CHECK-NOT: strong_retain strong_retain %5 : $@callee_owned (@out Builtin.Int32, Builtin.Int32) -> () - // CHECK: apply [[REABSTRACT]]([[TMP]]#1, %0, [[THICK]]) - %8 = apply %5(%6#1, %0) : $@callee_owned (@out Builtin.Int32, Builtin.Int32) -> () + // CHECK: apply [[REABSTRACT]]([[TMP]], %0, [[THICK]]) + %8 = apply %5(%6, %0) : $@callee_owned (@out Builtin.Int32, Builtin.Int32) -> () // CHECK-NOT: strong_release strong_release %5 : $@callee_owned (@out Builtin.Int32, Builtin.Int32) -> () // CHECK-NOT: tuple %10 = tuple () - // CHECK: [[RESULT:%.*]] = load [[TMP]]#1 - %11 = load %6#1 : $*Builtin.Int32 - // CHECK: dealloc_stack [[TMP]]#0 - dealloc_stack %6#0 : $*@local_storage Builtin.Int32 + // CHECK: [[RESULT:%.*]] = load [[TMP]] + %11 = load %6 : $*Builtin.Int32 + // CHECK: dealloc_stack [[TMP]] + dealloc_stack %6 : $*Builtin.Int32 // CHECK: return [[RESULT]] return %11 : $Builtin.Int32 } @@ -878,12 +834,12 @@ bb0(%0 : $*Builtin.Int32, %1 : $Builtin.Int32, %2 : $@callee_owned (Builtin.Int3 sil @remove_init_ex : $@convention(thin) (Int) -> () { bb0(%0 : $Int): %1 = alloc_stack $BooleanType - %2 = init_existential_addr %1#1 : $*BooleanType, $Bool + %2 = init_existential_addr %1 : $*BooleanType, $Bool %3 = integer_literal $Builtin.Int1, 1 %4 = struct $Bool (%3 : $Builtin.Int1) store %4 to %2 : $*Bool - destroy_addr %1#1 : $*BooleanType - dealloc_stack %1#0 : $*@local_storage BooleanType + destroy_addr %1 : $*BooleanType + dealloc_stack %1 : $*BooleanType %8 = tuple () return %8 : $() } @@ -984,13 +940,13 @@ bb3(%16 : $Int32): // Preds: bb1 bb2 // CHECK: bb0([[INT_PTR:%[0-9]+]] // CHECK-NEXT: [[ALLOCA1:%[0-9]+]] = alloc_stack $FakeOptional // CHECK-NEXT: [[ENUM1:%[0-9]+]] = enum $FakeOptional, #FakeOptional.None!enumelt -// CHECK-NEXT: store [[ENUM1]] to [[ALLOCA1]]#1 +// CHECK-NEXT: store [[ENUM1]] to [[ALLOCA1]] // CHECK-NEXT: [[ALLOCA2:%[0-9]+]] = alloc_stack $FakeOptional // CHECK-NEXT: [[INT:%[0-9]+]] = load [[INT_PTR]] : $*Builtin.Int1 // CHECK-NEXT: [[ENUM2:%[0-9]+]] = enum $FakeOptional, #FakeOptional.Some!enumelt.1, [[INT]] : $Builtin.Int1 -// CHECK-NEXT: store [[ENUM2]] to [[ALLOCA2]]#1 : $*FakeOptional -// CHECK-NEXT: [[RESULT1:%[0-9]+]] = load [[ALLOCA1:%[0-9]+]]#1 -// CHECK-NEXT: [[RESULT2:%[0-9]+]] = load [[ALLOCA2:%[0-9]+]]#1 +// CHECK-NEXT: store [[ENUM2]] to [[ALLOCA2]] : $*FakeOptional +// CHECK-NEXT: [[RESULT1:%[0-9]+]] = load [[ALLOCA1]] +// CHECK-NEXT: [[RESULT2:%[0-9]+]] = load [[ALLOCA2]] // CHECK-NEXT: [[RESULT:%[0-9]+]] = tuple ([[RESULT1]] : $FakeOptional, [[RESULT2]] : $FakeOptional) // CHECK-NEXT: dealloc_stack // CHECK-NEXT: dealloc_stack @@ -998,22 +954,22 @@ bb3(%16 : $Int32): // Preds: bb1 bb2 sil @enum_promotion_of_concrete_types : $@convention(thin) (@in Builtin.Int1) -> (FakeOptional, FakeOptional) { bb0(%0 : $*Builtin.Int1): %1 = alloc_stack $FakeOptional - inject_enum_addr %1#1 : $*FakeOptional, #FakeOptional.None!enumelt + inject_enum_addr %1 : $*FakeOptional, #FakeOptional.None!enumelt %2 = integer_literal $Builtin.Int1, 1 %3 = alloc_stack $FakeOptional - %4 = init_enum_data_addr %3#1 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + %4 = init_enum_data_addr %3 : $*FakeOptional, #FakeOptional.Some!enumelt.1 %5 = load %0 : $*Builtin.Int1 store %5 to %4 : $*Builtin.Int1 - inject_enum_addr %3#1 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + inject_enum_addr %3 : $*FakeOptional, #FakeOptional.Some!enumelt.1 - %6 = load %1#1 : $*FakeOptional - %7 = load %3#1 : $*FakeOptional + %6 = load %1 : $*FakeOptional + %7 = load %3 : $*FakeOptional %8 = tuple(%6 : $FakeOptional, %7 : $FakeOptional) - dealloc_stack %3#0 : $*@local_storage FakeOptional - dealloc_stack %1#0 : $*@local_storage FakeOptional + dealloc_stack %3 : $*FakeOptional + dealloc_stack %1 : $*FakeOptional return %8 : $(FakeOptional, FakeOptional) } @@ -1022,24 +978,24 @@ bb0(%0 : $*Builtin.Int1): // CHECK-NEXT: [[ALLOCA:%[0-9]+]] = alloc_stack $FakeOptional // CHECK-NEXT: strong_retain [[B_PTR]] // CHECK-NEXT: [[ENUM:%[0-9]+]] = enum $FakeOptional, #FakeOptional.Some!enumelt.1, [[B_PTR]] : $B -// CHECK-NEXT: store [[ENUM]] to [[ALLOCA]]#1 : $*FakeOptional -// CHECK-NEXT: [[RESULT:%[0-9]+]] = load [[ALLOCA:%[0-9]+]]#1 +// CHECK-NEXT: store [[ENUM]] to [[ALLOCA]] : $*FakeOptional +// CHECK-NEXT: [[RESULT:%[0-9]+]] = load [[ALLOCA]] // CHECK-NEXT: dealloc_stack // CHECK-NEXT: strong_release [[B_PTR]] // CHECK-NEXT: return [[RESULT]] sil @enum_promotion_case2 : $@convention(thin) (@owned B) -> @owned FakeOptional { bb0(%0 : $B): %2 = alloc_stack $FakeOptional - %3 = init_enum_data_addr %2#1 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + %3 = init_enum_data_addr %2 : $*FakeOptional, #FakeOptional.Some!enumelt.1 store %0 to %3 : $*B // This instruction between the store and the inject_enum_addr should not prevent // the optimization. strong_retain %0 : $B - inject_enum_addr %2#1 : $*FakeOptional, #FakeOptional.Some!enumelt.1 - %7 = load %2#1 : $*FakeOptional - dealloc_stack %2#0 : $*@local_storage FakeOptional + inject_enum_addr %2 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + %7 = load %2 : $*FakeOptional + dealloc_stack %2 : $*FakeOptional strong_release %0 : $B return %7 : $FakeOptional } @@ -1048,9 +1004,9 @@ bb0(%0 : $B): // CHECK-LABEL: sil @no_enum_promotion_of_non_concrete_types // CHECK: bb0 // CHECK-NEXT: alloc_stack $FakeOptional -// CHECK-NEXT: inject_enum_addr {{%[0-9]+}}#1 : $*FakeOptional, #FakeOptional.None!enumelt +// CHECK-NEXT: inject_enum_addr {{%[0-9]+}} : $*FakeOptional, #FakeOptional.None!enumelt // CHECK-NEXT: alloc_stack $FakeOptional -// CHECK-NEXT: init_enum_data_addr {{%[0-9]+}}#1 : $*FakeOptional, #FakeOptional.Some!enumelt.1 +// CHECK-NEXT: init_enum_data_addr {{%[0-9]+}} : $*FakeOptional, #FakeOptional.Some!enumelt.1 // CHECK-NEXT: copy_addr // CHECK-NEXT: inject_enum_addr // CHECK-NEXT: cond_br @@ -1067,24 +1023,24 @@ bb0(%0 : $B): sil @no_enum_promotion_of_non_concrete_types : $@convention(thin) (@out FakeOptional, @inout T, Builtin.Int1) -> () { bb0(%0 : $*FakeOptional, %1 : $*T, %2 : $Builtin.Int1): %3 = alloc_stack $FakeOptional - inject_enum_addr %3#1 : $*FakeOptional, #FakeOptional.None!enumelt + inject_enum_addr %3 : $*FakeOptional, #FakeOptional.None!enumelt %4 = alloc_stack $FakeOptional - %5 = init_enum_data_addr %4#1 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + %5 = init_enum_data_addr %4 : $*FakeOptional, #FakeOptional.Some!enumelt.1 copy_addr [take] %1 to [initialization] %5 : $*T - inject_enum_addr %4#1 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + inject_enum_addr %4 : $*FakeOptional, #FakeOptional.Some!enumelt.1 cond_br %2, bb1, bb2 bb1: - br bb3(%3#1 : $*FakeOptional) + br bb3(%3 : $*FakeOptional) bb2: - br bb3(%4#1 : $*FakeOptional) + br bb3(%4 : $*FakeOptional) bb3(%6 : $*FakeOptional): copy_addr [take] %6 to [initialization] %0 : $*FakeOptional %7 = tuple() - dealloc_stack %4#0 : $*@local_storage FakeOptional - dealloc_stack %3#0 : $*@local_storage FakeOptional + dealloc_stack %4 : $*FakeOptional + dealloc_stack %3 : $*FakeOptional return %7 : $() } @@ -1392,12 +1348,12 @@ bb0: return %3 : $() } -// CHECK-LABEL: sil @eliminiate_thin_to_thick_apply : $@convention(thin) () -> () { +// CHECK-LABEL: sil @eliminate_thin_to_thick_apply : $@convention(thin) () -> () { // CHECK: bb0 // CHECK: function_ref @eliminate_dead_thin_to_thick_function_fun // CHECK-NEXT: apply // CHECK-NEXT: return -sil @eliminiate_thin_to_thick_apply : $@convention(thin) () -> () { +sil @eliminate_thin_to_thick_apply : $@convention(thin) () -> () { bb0: %0 = function_ref @eliminate_dead_thin_to_thick_function_fun : $@convention(thin) () -> () %1 = thin_to_thick_function %0 : $@convention(thin) () -> () to $@callee_owned () -> () @@ -1531,17 +1487,17 @@ bb0: %2 = partial_apply %0() : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () %3 = alloc_stack $Builtin.Int32 %4 = alloc_stack $Builtin.Int32 - %5 = apply %2(%3#1, %4#1) : $@callee_owned (@out Builtin.Int32, @in Builtin.Int32) -> () + %5 = apply %2(%3, %4) : $@callee_owned (@out Builtin.Int32, @in Builtin.Int32) -> () %6 = partial_apply %1() : $@convention(thin) <τ_0_0> (@in τ_0_0) -> Bool - %7 = apply %6(%3#1) : $@callee_owned (@in Builtin.Int32) -> Bool + %7 = apply %6(%3) : $@callee_owned (@in Builtin.Int32) -> Bool %8 = integer_literal $Builtin.Int32, 0 %9 = function_ref @generic_call_with_direct_result : $@convention(thin) <τ_0_0> (τ_0_0) -> τ_0_0 %10 = partial_apply %9() : $@convention(thin) <τ_0_0> (τ_0_0) -> τ_0_0 %11 = apply %10(%8) : $@callee_owned (Builtin.Int32) -> Builtin.Int32 %12 = partial_apply %9(%8) : $@convention(thin) <τ_0_0> (τ_0_0) -> τ_0_0 %13 = apply %12() : $@callee_owned () -> Builtin.Int32 - dealloc_stack %4#0 : $*@local_storage Builtin.Int32 - dealloc_stack %3#0 : $*@local_storage Builtin.Int32 + dealloc_stack %4 : $*Builtin.Int32 + dealloc_stack %3 : $*Builtin.Int32 %9999 = tuple() return %9999 : $() } @@ -1855,32 +1811,6 @@ bb3(%a : $ZZZ): return %a : $ZZZ } - -// FIXME: Add dead array elimination to DeadObjectElimination -// CHECK-LABEL: test_dead_array -// CHECK: bb0(%0 : $ZZZ): -// DISABLED-CHECK-NEXT: strong_release %0 -// DISABLED-CHECK-NEXT: tuple -// DISABLED-CHECK-NEXT: return -sil @test_dead_array : $@convention(thin) (@owned ZZZ) -> () { -bb0(%0 : $ZZZ): - %1 = integer_literal $Builtin.Word, 1 - %2 = function_ref @_allocate_uninitialized_ZZZ : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) - %3 = apply %2(%1) : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) - %4 = tuple_extract %3 : $(Array, Builtin.RawPointer), 0 - %5 = tuple_extract %3 : $(Array, Builtin.RawPointer), 1 - %6 = pointer_to_address %5 : $Builtin.RawPointer to $*ZZZ - store %0 to %6 : $*ZZZ - %8 = struct_extract %4 : $Array, #Array._buffer - %9 = struct_extract %8 : $_ArrayBuffer, #_ArrayBuffer._storage - %10 = struct_extract %9 : $_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCoreType>, #_BridgeStorage.rawValue - strong_release %10 : $Builtin.BridgeObject - %12 = tuple () - return %12 : $() -} - -sil [_semantics "array.uninitialized"] @_allocate_uninitialized_ZZZ : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) - struct FakeInt16 { var val : Builtin.Int16 } @@ -1938,7 +1868,7 @@ bb0(%0 : $XX): %2 = existential_metatype $@thick XX.Type, %0 : $XX // user: %3 %3 = thick_to_objc_metatype %2 : $@thick XX.Type to $@objc_metatype XX.Type // user: %4 %4 = objc_existential_metatype_to_object %3 : $@objc_metatype XX.Type to $AnyObject // users: %5, %6 - debug_value %4 : $AnyObject // let obj1 // id: %5 + debug_value %4 : $AnyObject, let, name "obj1" // id: %5 strong_release %4 : $AnyObject // id: %6 strong_release %0 : $XX // id: %7 %8 = tuple () // user: %9 @@ -2002,15 +1932,15 @@ bb0(%0: $MyClass): // CHECK-LABEL: sil @load_fixlifetime_address // CHECK: [[Stck:%.*]] = alloc_stack // CHECK-NOT: fix_lifetime [[Stck]]#1 -// CHECK: [[StckVal:%.*]] = load [[Stck]]#1 +// CHECK: [[StckVal:%.*]] = load [[Stck]] // CHECK: fix_lifetime [[StckVal]] sil @load_fixlifetime_address : $@convention(thin) (Builtin.NativeObject) -> () { bb0(%0: $Builtin.NativeObject): %1 = alloc_stack $Builtin.NativeObject - store %0 to %1#1: $*Builtin.NativeObject - fix_lifetime %1#1 : $*Builtin.NativeObject - dealloc_stack %1#0 : $*@local_storage Builtin.NativeObject + store %0 to %1: $*Builtin.NativeObject + fix_lifetime %1 : $*Builtin.NativeObject + dealloc_stack %1 : $*Builtin.NativeObject %6 = tuple () return %6 : $() } @@ -2211,7 +2141,7 @@ bb0(%0 : $Builtin.RawPointer, %1 : $*Builtin.UnsafeValueBuffer, %2 : $*GenContai // CHECK: apply [[FUN]]( // CHECK: return -sil @combine_cast_of_materializeForSet_function_nested_subsitutions : $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout GenContainer2) -> () { +sil @combine_cast_of_materializeForSet_function_nested_substitutions : $@convention(thin) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout GenContainer2) -> () { bbO(%0 : $Builtin.RawPointer, %1 : $*Builtin.UnsafeValueBuffer, %2: $*GenContainer2): %3 = metatype $@thick GenContainer2.Type %4 = function_ref @materializeForSetClosure2 : $@convention(thin) <τ_0_0 : AnIndexable> (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout GenContainer2<τ_0_0>, @thick GenContainer2<τ_0_0>.Type) -> () @@ -2353,15 +2283,15 @@ sil @sil_combine_partial_apply_caller : $@convention(thin) (@in Builtin.NativeOb bb0(%0 : $*Builtin.NativeObject, %1 : $*Builtin.NativeObject, %2 : $Builtin.NativeObject, %3 : $Builtin.NativeObject, %4 : $Builtin.NativeObject): %100 = function_ref @sil_combine_partial_apply_callee : $@convention(thin) (@in Builtin.NativeObject, @inout Builtin.NativeObject, Builtin.NativeObject, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () %101 = alloc_stack $Builtin.NativeObject - copy_addr %0 to [initialization] %101#1 : $*Builtin.NativeObject + copy_addr %0 to [initialization] %101 : $*Builtin.NativeObject strong_retain %2 : $Builtin.NativeObject strong_retain %3 : $Builtin.NativeObject strong_retain %4 : $Builtin.NativeObject - %102 = partial_apply %100(%101#1, %1, %2, %3, %4) : $@convention(thin) (@in Builtin.NativeObject, @inout Builtin.NativeObject, Builtin.NativeObject, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () + %102 = partial_apply %100(%101, %1, %2, %3, %4) : $@convention(thin) (@in Builtin.NativeObject, @inout Builtin.NativeObject, Builtin.NativeObject, @owned Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () strong_release %102 : $@callee_owned () -> () strong_release %3 : $Builtin.NativeObject destroy_addr %0 : $*Builtin.NativeObject - dealloc_stack %101#0 : $*@local_storage Builtin.NativeObject + dealloc_stack %101 : $*Builtin.NativeObject %9999 = tuple() return %9999 : $() } @@ -2463,9 +2393,9 @@ bb3 (%10: $Builtin.Int32): sil @delete_dead_alloc_stack : $(@inout B) -> () { bb0(%0 : $*B): %1 = alloc_stack $B - copy_addr %0 to [initialization] %1#1 : $*B - destroy_addr %1#1 : $*B - dealloc_stack %1#0 : $*@local_storage B + copy_addr %0 to [initialization] %1 : $*B + destroy_addr %1 : $*B + dealloc_stack %1 : $*B %2 = tuple() return %2 : $() } @@ -2478,9 +2408,9 @@ bb0(%0 : $*B): sil @delete_dead_alloc_stack2 : $(@in B) -> () { bb0(%0 : $*B): %1 = alloc_stack $B - copy_addr [take] %0 to [initialization] %1#1 : $*B - destroy_addr %1#1 : $*B - dealloc_stack %1#0 : $*@local_storage B + copy_addr [take] %0 to [initialization] %1 : $*B + destroy_addr %1 : $*B + dealloc_stack %1 : $*B %2 = tuple() return %2 : $() } @@ -2495,11 +2425,11 @@ sil @use_b : $@convention(thin) (@inout B) -> () sil @dont_delete_dead_alloc_stack : $(@inout B) -> () { bb0(%0 : $*B): %1 = alloc_stack $B - copy_addr %0 to [initialization] %1#1 : $*B + copy_addr %0 to [initialization] %1 : $*B %2 = function_ref @use_b : $@convention(thin) (@inout B) -> () - %3 = apply %2(%1#1) : $@convention(thin) (@inout B) -> () - destroy_addr %1#1 : $*B - dealloc_stack %1#0 : $*@local_storage B + %3 = apply %2(%1) : $@convention(thin) (@inout B) -> () + destroy_addr %1 : $*B + dealloc_stack %1 : $*B %4 = tuple() return %4 : $() } @@ -2520,14 +2450,14 @@ protocol someProtocol { sil @witness_archetype : $@convention(thin) (@in T) -> () { bb0(%0 : $*T): %3 = alloc_stack $someProtocol // users: %4, %7, %10, %13, %15 - %4 = init_existential_addr %3#1 : $*someProtocol, $T // user: %5 + %4 = init_existential_addr %3 : $*someProtocol, $T // user: %5 copy_addr %0 to [initialization] %4 : $*T // id: %5 destroy_addr %0 : $*T // id: %6 - %7 = open_existential_addr %3#1 : $*someProtocol to $*@opened("105977B0-D8EB-11E4-AC00-3C0754644993") someProtocol // users: %8, %9 + %7 = open_existential_addr %3 : $*someProtocol to $*@opened("105977B0-D8EB-11E4-AC00-3C0754644993") someProtocol // users: %8, %9 %8 = witness_method $@opened("105977B0-D8EB-11E4-AC00-3C0754644993") someProtocol, #someProtocol.i!getter.1, %7 : $*@opened("105977B0-D8EB-11E4-AC00-3C0754644993") someProtocol : $@convention(witness_method) <τ_0_0 where τ_0_0 : someProtocol> (@in_guaranteed τ_0_0) -> Int // user: %9 %9 = apply %8<@opened("105977B0-D8EB-11E4-AC00-3C0754644993") someProtocol>(%7) : $@convention(witness_method) <τ_0_0 where τ_0_0 : someProtocol> (@in_guaranteed τ_0_0) -> Int - destroy_addr %3#1 : $*someProtocol // id: %13 - dealloc_stack %3#0 : $*@local_storage someProtocol // id: %15 + destroy_addr %3 : $*someProtocol // id: %13 + dealloc_stack %3 : $*someProtocol // id: %15 %16 = tuple () // user: %17 return %16 : $() // id: %17 } @@ -2555,17 +2485,17 @@ bb0: %1 = metatype $@thick T.Type %2 = init_existential_metatype %1 : $@thick T.Type, $@thick P.Type %3 = alloc_stack $@thick P.Type - store %2 to %3#1 : $*@thick P.Type + store %2 to %3 : $*@thick P.Type %5 = alloc_stack $@thick Q.Type - checked_cast_addr_br take_always P.Type in %3#1 : $*@thick P.Type to Q.Type in %5#1 : $*@thick Q.Type, bb1, bb3 + checked_cast_addr_br take_always P.Type in %3 : $*@thick P.Type to Q.Type in %5 : $*@thick Q.Type, bb1, bb3 bb1: %7 = integer_literal $Builtin.Int1, -1 br bb2(%7 : $Builtin.Int1) bb2(%9 : $Builtin.Int1): - dealloc_stack %5#0 : $*@local_storage @thick Q.Type - dealloc_stack %3#0 : $*@local_storage @thick P.Type + dealloc_stack %5 : $*@thick Q.Type + dealloc_stack %3 : $*@thick P.Type %12 = struct $Bool (%9 : $Builtin.Int1) return %12 : $Bool @@ -2587,7 +2517,7 @@ bb0(%0 : $Builtin.NativeObject): return %0 : $Builtin.NativeObject } -// CHECK-LABEL: sil @test_cmp_xor_cannonicalization +// CHECK-LABEL: sil @test_cmp_xor_canonicalization // CHECK:bb0([[ARG:%.*]] : $Builtin.Int1 // CHECK: [[TRUE:%.*]] = integer_literal $Builtin.Int1, -1 // CHECK: [[FALSE:%.*]] = integer_literal $Builtin.Int1, 0 @@ -2595,62 +2525,13 @@ bb0(%0 : $Builtin.NativeObject): // CHECK: [[NOT:%.*]] = builtin "xor_Int1"([[EQ]] : $Builtin.Int1, [[TRUE]] : $Builtin.Int1) // CHECK: return [[NOT]] -sil @test_cmp_xor_cannonicalization : $@convention(thin) (Builtin.Int1) -> Builtin.Int1 { +sil @test_cmp_xor_canonicalization : $@convention(thin) (Builtin.Int1) -> Builtin.Int1 { bb0(%0 : $Builtin.Int1): %1 = integer_literal $Builtin.Int1, -1 %2 = builtin "cmp_eq_Int1"(%0 : $Builtin.Int1, %1 : $Builtin.Int1) : $Builtin.Int1 return %2 : $Builtin.Int1 } -// dead_array test helpers -sil [thunk] @dead_array_run_closure : $@convention(thin) (@owned @callee_owned () -> Bool) -> () { -bb0(%0 : $@callee_owned () -> Bool): - %1 = apply %0() : $@callee_owned () -> Bool - %2 = tuple () - return %2 : $() -} - -sil @dead_array_closure : $@convention(thin) (@inout _HeapBuffer) -> Bool { -bb0(%0 : $*_HeapBuffer): - %1 = struct_element_addr %0 : $*_HeapBuffer, #_HeapBuffer._storage // user: %2 - %2 = is_unique %1 : $*Optional // user: %3 - %3 = struct $Bool (%2 : $Builtin.Int1) // user: %4 - return %3 : $Bool // id: %4 -} - -// Mimicks Swift._allocateUninitializedArray -sil [_semantics "array.uninitialized"] @dead_array_alloc : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) - -// HeapBuffer.swift test case spuriously reports a "unique" buffer -// CHECK-LABEL: sil @dead_array -// CHECK-NOT: release -// CHECK: retain_value %{{[0-9]+}} : $Optional -// CHECK: apply -// CHECK: strong_release %{{[0-9]+}} : $Builtin.BridgeObject -sil @dead_array : $@convention(thin) (@inout _HeapBuffer) -> () { -bb0(%0 : $*_HeapBuffer): - %1 = integer_literal $Builtin.Word, 1 // user: %3 - %2 = function_ref @dead_array_alloc : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) - %3 = apply %2<_HeapBuffer>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) - %4 = tuple_extract %3 : $(Array<_HeapBuffer>, Builtin.RawPointer), 0 // user: %15 - %5 = tuple_extract %3 : $(Array<_HeapBuffer>, Builtin.RawPointer), 1 // user: %6 - %6 = pointer_to_address %5 : $Builtin.RawPointer to $*_HeapBuffer // user: %9 - %7 = load %0 : $*_HeapBuffer // users: %8, %9 - %8 = struct_extract %7 : $_HeapBuffer, #_HeapBuffer._storage // user: %13 - store %7 to %6 : $*_HeapBuffer // id: %9 - %10 = function_ref @dead_array_run_closure : $@convention(thin) (@owned @callee_owned () -> Bool) -> () // user: %14 - %11 = function_ref @dead_array_closure : $@convention(thin) (@inout _HeapBuffer) -> Bool // user: %12 - %12 = partial_apply %11(%0) : $@convention(thin) (@inout _HeapBuffer) -> Bool // user: %14 - retain_value %8 : $Optional // id: %13 - %14 = apply %10(%12) : $@convention(thin) (@owned @callee_owned () -> Bool) -> () - %15 = struct_extract %4 : $Array<_HeapBuffer>, #Array._buffer // user: %16 - %16 = struct_extract %15 : $_ArrayBuffer<_HeapBuffer>, #_ArrayBuffer._storage // user: %17 - %17 = struct_extract %16 : $_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCoreType>, #_BridgeStorage.rawValue // user: %18 - strong_release %17 : $Builtin.BridgeObject // id: %18 - %19 = tuple () // user: %20 - return %19 : $() // id: %20 -} - struct NStruct { var a:Int var b:Int @@ -2670,10 +2551,10 @@ final class NClass { // CHECK: return [[R]] sil @narrow_load_with_debug_value : $@convention(thin) (@owned NClass) -> Int { bb0(%0 : $NClass): - debug_value %0 : $NClass // let c // id: %1 + debug_value %0 : $NClass, let, name "c" // id: %1 %2 = ref_element_addr %0 : $NClass, #NClass.s // user: %3 %3 = load %2 : $*NStruct // users: %4, %5 - debug_value %3 : $NStruct // let xx // id: %4 + debug_value %3 : $NStruct, let, name "xx" // id: %4 %5 = struct_extract %3 : $NStruct, #NStruct.a // user: %7 strong_release %0 : $NClass // id: %6 return %5 : $Int // id: %7 @@ -2706,7 +2587,7 @@ enum VendingMachineError: ErrorType { // CHECK: return sil hidden @RemoveUnusedException : $@convention(thin) (Int32) -> (Double, @error ErrorType) { bb0(%0 : $Int32): - debug_value %0 : $Int32 // let x // id: %1 + debug_value %0 : $Int32, let, name "x" // id: %1 %2 = integer_literal $Builtin.Int32, 10 // user: %4 %3 = struct_extract %0 : $Int32, #Int32._value // user: %4 %4 = builtin "cmp_sgt_Int32"(%3 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int1 // user: %5 @@ -2716,7 +2597,7 @@ bb1: // Preds: bb0 %6 = alloc_existential_box $ErrorType, $VendingMachineError // users: %8, %9, %13 %7 = enum $VendingMachineError, #VendingMachineError.OutOfStock!enumelt // user: %8 store %7 to %6#1 : $*VendingMachineError // id: %8 - debug_value %6#0 : $ErrorType // let error // id: %9 + debug_value %6#0 : $ErrorType, let, name "error" // id: %9 %10 = float_literal $Builtin.FPIEEE80, 0x3FFF8000000000000000 // 1 // user: %11 %11 = builtin "fptrunc_FPIEEE80_FPIEEE64"(%10 : $Builtin.FPIEEE80) : $Builtin.FPIEEE64 // user: %12 %12 = struct $Double (%11 : $Builtin.FPIEEE64) // user: %14 @@ -2739,10 +2620,10 @@ sil [reabstraction_thunk] @_TTRXFo_iSS_iSb_XFo_oSS_dSb_ : $@convention(thin) (@o // CHECK-LABEL: sil @remove_identity_reabstraction_thunks // CHECK: [[STK:%.*]] = alloc_stack $@callee_owned (@owned String) -> Bool // CHECK-NOT: partial_apply -// CHECK: store %0 to [[STK]]#1 -// CHECK: [[LD:%.*]] = load [[STK]]#1 +// CHECK: store %0 to [[STK]] +// CHECK: [[LD:%.*]] = load [[STK]] // CHECK: strong_release [[LD]] -// CHECK: dealloc_stack [[STK]]#0 +// CHECK: dealloc_stack [[STK]] sil @remove_identity_reabstraction_thunks : $@convention(thin) (@owned @callee_owned (@owned String) -> Bool) -> () { bb0(%0 : $@callee_owned (@owned String) -> Bool): @@ -2754,10 +2635,10 @@ bb0(%0 : $@callee_owned (@owned String) -> Bool): // function_ref reabstraction thunk helper from @callee_owned (@in Swift.String) -> (@out Swift.Bool) to @callee_owned (@owned Swift.String) -> (@unowned Swift.Bool) %4 = function_ref @_TTRXFo_iSS_iSb_XFo_oSS_dSb_ : $@convention(thin) (@owned String, @owned @callee_owned (@out Bool, @in String) -> ()) -> Bool %5 = partial_apply %4(%3) : $@convention(thin) (@owned String, @owned @callee_owned (@out Bool, @in String) -> ()) -> Bool - store %5 to %1#1 : $*@callee_owned (@owned String) -> Bool - %6 = load %1#1 : $*@callee_owned (@owned String) -> Bool + store %5 to %1 : $*@callee_owned (@owned String) -> Bool + %6 = load %1 : $*@callee_owned (@owned String) -> Bool strong_release %6 : $@callee_owned (@owned String) -> Bool - dealloc_stack %1#0 : $*@local_storage @callee_owned (@owned String) -> Bool + dealloc_stack %1 : $*@callee_owned (@owned String) -> Bool %7 = tuple () return %7 : $() } @@ -2777,7 +2658,7 @@ bb0(%0 : $*B, %1 : $B, %2 : $Builtin.Int1): } // Make sure that we do not crash when determining if a value is not zero and -// has a value that can not be stored in a UInt64. The specific issue is that we +// has a value that cannot be stored in a UInt64. The specific issue is that we // were using getZExtValue before which assumes that an APInt can be stored in a // UInt64. // @@ -2792,25 +2673,6 @@ bb0: return %2 : $Builtin.Int1 } -// Check that it does not creash the compiler. -// Int is ObjC-bridgeable in this case, but its conformance is not know, -// because Foundation is not imported yet. -// Therefore the cast may sucseed from the compiler point of view. -// CHECK-LABEL: sil @cast_of_class_to_int -// CHECK: unconditional_checked_cast_addr -// CHECK: return -sil @cast_of_class_to_int : $@convention(thin) (C) -> Int { -bb0(%0 : $C): - %1 = alloc_stack $Int - %2 = alloc_stack $C - store %0 to %2#1 : $*C - unconditional_checked_cast_addr take_always C in %2#1 : $*C to Int in %1#1 : $*Int - %4 = load %1#1 : $*Int - dealloc_stack %2#0 : $*@local_storage C - dealloc_stack %1#0 : $*@local_storage Int - return %4 : $Int -} - class CC1 { deinit init() @@ -2833,7 +2695,7 @@ class CC4 { // Function that takes different kinds of arguments: @in, @guaranteed, @owned, -sil @closure_with_in_guaranteed_owened_in_args : $@convention(method) (@in CC2, @guaranteed CC1, @owned CC3, @in CC4) -> Optional +sil @closure_with_in_guaranteed_owned_in_args : $@convention(method) (@in CC2, @guaranteed CC1, @owned CC3, @in CC4) -> Optional // Test the peephole performing apply{partial_apply(x,y,z)}(a) -> apply(a,x,y,z) // We need to check the following: @@ -2841,7 +2703,7 @@ sil @closure_with_in_guaranteed_owened_in_args : $@convention(method) (@in CC2, // should be copied into temporaries. This should happen just before that partial_apply instruction. // - The temporaries are allocated at the beginning of the function and deallocated at the end. // - Before each apply of the partial_apply, we retain values of any arguments which are of non-address type. -// This is required because they could be consumed (i.e. relased by the callee). +// This is required because they could be consumed (i.e. released by the callee). // - After each apply of the partial_apply, we release values of any arguments which are non-consumed by the callee (e.g. @guaranteed ones) // CHECK-LABEL: sil @test_apply_of_partial_apply @@ -2849,9 +2711,9 @@ sil @closure_with_in_guaranteed_owened_in_args : $@convention(method) (@in CC2, // CHECK: bb0{{.*}}: // A new temporary should have been created for each alloc_stack argument passed to partial_apply // CHECK: [[TMP:%[0-9]+]] = alloc_stack $CC4 -// CHECK: [[CLOSURE:%[0-9]+]] = function_ref @closure_with_in_guaranteed_owened_in_args +// CHECK: [[CLOSURE:%[0-9]+]] = function_ref @closure_with_in_guaranteed_owned_in_args // Copy the original value of the argument into a temporary -// CHECK: copy_addr {{.*}} to [initialization] [[TMP]]#1 : $*CC4 +// CHECK: copy_addr {{.*}} to [initialization] [[TMP]] : $*CC4 // CHECK-NOT: partial_apply // CHECK: bb1: @@ -2868,9 +2730,9 @@ sil @closure_with_in_guaranteed_owened_in_args : $@convention(method) (@in CC2, // CHECK: strong_retain %{{[0-9]+}} : $CC1 // Retain the owned argument // CHECK: strong_retain %{{[0-9]+}} : $CC3 -// CHECK: apply [[CLOSURE]]({{.*}}, [[TMP]]#1) +// CHECK: apply [[CLOSURE]]({{.*}}, [[TMP]]) // Release the @owned CC4 argument of the function -// CHECK: load {{%[0-9]+}}#1 : $*CC4 +// CHECK: load {{%[0-9]+}} : $*CC4 // CHECK: strong_release {{%[0-9]+}} : $CC4 // Check that the peephole inserted a release the guaranteed argument // CHECK: strong_release %{{[0-9]+}} : $CC1 @@ -2882,9 +2744,9 @@ sil @closure_with_in_guaranteed_owened_in_args : $@convention(method) (@in CC2, // CHECK: strong_retain %{{[0-9]+}} : $CC1 // Check that the peephole inserted a retain of the closure's owned argument // CHECK: strong_retain %{{[0-9]+}} : $CC3 -// CHECK: apply [[CLOSURE]]({{.*}}, [[TMP]]#1) +// CHECK: apply [[CLOSURE]]({{.*}}, [[TMP]]) // Release the @owned CC4 argument of the function -// CHECK: load {{%[0-9]+}}#1 : $*CC4 +// CHECK: load {{%[0-9]+}} : $*CC4 // CHECK: strong_release {{%[0-9]+}} : $CC4 // Check that the peephole inserted a release the closure's guaranteed argument // CHECK: strong_release %{{[0-9]+}} : $CC1 @@ -2896,67 +2758,67 @@ sil @closure_with_in_guaranteed_owened_in_args : $@convention(method) (@in CC2, sil @test_apply_of_partial_apply : $@convention(thin) (@in Optional, @guaranteed CC1, @guaranteed CC3, @guaranteed CC4, @guaranteed CC2) -> Optional { bb0(%0 : $*Optional, %1 : $CC1, %2 : $CC3, %3 : $CC4, %4 : $CC2): - %5 = function_ref @closure_with_in_guaranteed_owened_in_args : $@convention(method) (@in CC2, @guaranteed CC1, @owned CC3, @in CC4) -> Optional + %5 = function_ref @closure_with_in_guaranteed_owned_in_args : $@convention(method) (@in CC2, @guaranteed CC1, @owned CC3, @in CC4) -> Optional %6 = alloc_stack $CC3 - store %2 to %6#1 : $*CC3 - %8 = load %6#1 : $*CC3 + store %2 to %6 : $*CC3 + %8 = load %6 : $*CC3 %9 = alloc_stack $CC4 - store %3 to %9#1 : $*CC4 - %11 = load %9#1 : $*CC4 + store %3 to %9 : $*CC4 + %11 = load %9 : $*CC4 strong_retain %1 : $CC1 - %12 = partial_apply %5(%1, %8, %9#1) : $@convention(method) (@in CC2, @guaranteed CC1, @owned CC3, @in CC4) -> Optional - dealloc_stack %9#0 : $*@local_storage CC4 - dealloc_stack %6#0 : $*@local_storage CC3 + %12 = partial_apply %5(%1, %8, %9) : $@convention(method) (@in CC2, @guaranteed CC1, @owned CC3, @in CC4) -> Optional + dealloc_stack %9 : $*CC4 + dealloc_stack %6 : $*CC3 %15 = convert_function %12 : $@callee_owned (@in CC2) -> Optional to $@callee_owned (@in CC2) -> (Optional, @error ErrorType) %16 = alloc_stack $Optional %17 = alloc_stack $Optional - copy_addr %0 to [initialization] %17#1 : $*Optional - switch_enum_addr %17#1 : $*Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb2 + copy_addr %0 to [initialization] %17 : $*Optional + switch_enum_addr %17 : $*Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb2 bb1: - %21 = unchecked_take_enum_data_addr %17#1 : $*Optional, #Optional.Some!enumelt.1 + %21 = unchecked_take_enum_data_addr %17 : $*Optional, #Optional.Some!enumelt.1 %22 = alloc_stack $CC2 - copy_addr [take] %21 to [initialization] %22#1 : $*CC2 + copy_addr [take] %21 to [initialization] %22 : $*CC2 %24 = alloc_stack $CC2 - copy_addr %22#1 to [initialization] %24#1 : $*CC2 - destroy_addr %22#1 : $*CC2 + copy_addr %22 to [initialization] %24 : $*CC2 + destroy_addr %22 : $*CC2 strong_retain %15 : $@callee_owned (@in CC2) -> (Optional, @error ErrorType) - %28 = apply %12(%24#1) : $@callee_owned (@in CC2) -> Optional - store %28 to %16#1 : $*Optional - dealloc_stack %24#0 : $*@local_storage CC2 - dealloc_stack %22#0 : $*@local_storage CC2 + %28 = apply %12(%24) : $@callee_owned (@in CC2) -> Optional + store %28 to %16 : $*Optional + dealloc_stack %24 : $*CC2 + dealloc_stack %22 : $*CC2 %102 = alloc_stack $CC2 - copy_addr [take] %21 to [initialization] %102#1 : $*CC2 + copy_addr [take] %21 to [initialization] %102 : $*CC2 %104 = alloc_stack $CC2 - copy_addr %102#1 to [initialization] %104#1 : $*CC2 - destroy_addr %102#1 : $*CC2 + copy_addr %102 to [initialization] %104 : $*CC2 + destroy_addr %102 : $*CC2 strong_retain %15 : $@callee_owned (@in CC2) -> (Optional, @error ErrorType) - %108 = apply %12(%104#1) : $@callee_owned (@in CC2) -> Optional - store %108 to %16#1 : $*Optional - dealloc_stack %104#0 : $*@local_storage CC2 - dealloc_stack %102#0 : $*@local_storage CC2 + %108 = apply %12(%104) : $@callee_owned (@in CC2) -> Optional + store %108 to %16 : $*Optional + dealloc_stack %104 : $*CC2 + dealloc_stack %102 : $*CC2 - dealloc_stack %17#0 : $*@local_storage Optional + dealloc_stack %17 : $*Optional br bb3 bb2: %39 = alloc_stack $CC2 - store %4 to %39#1 : $*CC2 + store %4 to %39 : $*CC2 strong_retain %15 : $@callee_owned (@in CC2) -> (Optional, @error ErrorType) - %42 = apply %12(%39#1) : $@callee_owned (@in CC2) -> Optional - store %42 to %16#1 : $*Optional - dealloc_stack %39#0 : $*@local_storage CC2 - dealloc_stack %17#0 : $*@local_storage Optional + %42 = apply %12(%39) : $@callee_owned (@in CC2) -> Optional + store %42 to %16 : $*Optional + dealloc_stack %39 : $*CC2 + dealloc_stack %17 : $*Optional br bb3 bb3: destroy_addr %0 : $*Optional strong_release %15 : $@callee_owned (@in CC2) -> (Optional, @error ErrorType) - %36 = load %16#1 : $*Optional - dealloc_stack %16#0 : $*@local_storage Optional + %36 = load %16 : $*Optional + dealloc_stack %16 : $*Optional return %36 : $Optional } @@ -2993,3 +2855,69 @@ bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word): return %90 : $() } +// CHECK-LABEL: sil @enum_promotion_case3 +// CHECK: bb0([[B_PTR:%[0-9]+]] +// CHECK-NEXT: [[ALLOCA:%[0-9]+]] = alloc_stack $FakeOptional +// CHECK-NEXT: strong_release [[B_PTR]] +// CHECK-NEXT: [[ENUM:%[0-9]+]] = enum $FakeOptional, #FakeOptional.Some!enumelt.1, [[B_PTR]] : $B +// CHECK-NEXT: store [[ENUM]] to [[ALLOCA]] : $*FakeOptional +// CHECK-NEXT: [[RESULT:%[0-9]+]] = load [[ALLOCA]] +// CHECK-NEXT: dealloc_stack +// CHECK-NEXT: strong_release [[B_PTR]] +// CHECK-NEXT: return [[RESULT]] +sil @enum_promotion_case3 : $@convention(thin) (@owned B) -> @owned FakeOptional { +bb0(%0 : $B): + %2 = alloc_stack $FakeOptional + %3 = init_enum_data_addr %2 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + store %0 to %3 : $*B + + // This instruction between the store and the inject_enum_addr should not prevent + // the optimization. + strong_release %0 : $B + + inject_enum_addr %2 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + %7 = load %2 : $*FakeOptional + dealloc_stack %2 : $*FakeOptional + strong_release %0 : $B + return %7 : $FakeOptional +} + +// CHECK-LABEL: sil @project_alloc_box +sil @project_alloc_box : $@convention(thin) () -> Builtin.Int32 { +entry: + // CHECK: [[BOX:%.*]] = alloc_box + %b = alloc_box $Builtin.Int32 + %0 = integer_literal $Builtin.Int32, 0 + store %0 to %b#1 : $*Builtin.Int32 + %p = project_box %b#0 : $@box Builtin.Int32 + // CHECK: [[RET:%.*]] = load [[BOX]]#1 + // CHECK: return [[RET]] + %r = load %p : $*Builtin.Int32 + return %r : $Builtin.Int32 +} + +sil @init_enum : $@convention(thin) (@out B) -> () + + +// Localize the initialization of the enum payload to enable mem2reg for the enum. + +// CHECK-LABEL: sil @enum_promotion_case4 +// CHECK: [[V1:%.*]] = alloc_stack $FakeOptional +// CHECK: [[V2:%.*]] = function_ref @init_enum +// CHECK: [[V3:%.*]] = alloc_stack $B +// CHECK: apply [[V2]]([[V3]]) +// CHECK: [[V4:%.*]] = load [[V3]] +// CHECK: [[V5:%.*]] = enum $FakeOptional, #FakeOptional.Some!enumelt.1, [[V4]] +// CHECK: store [[V5]] to [[V1]] + +sil @enum_promotion_case4 : $@convention(thin) () -> @owned FakeOptional { +bb0: + %2 = alloc_stack $FakeOptional + %3 = init_enum_data_addr %2 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + %4 = function_ref @init_enum : $@convention(thin) (@out B) -> () + %5 = apply %4(%3) : $@convention(thin) (@out B) -> () + inject_enum_addr %2 : $*FakeOptional, #FakeOptional.Some!enumelt.1 + %7 = load %2 : $*FakeOptional + dealloc_stack %2 : $*FakeOptional + return %7 : $FakeOptional +} diff --git a/test/SILPasses/sil_combine_bitops.sil b/test/SILOptimizer/sil_combine_bitops.sil similarity index 100% rename from test/SILPasses/sil_combine_bitops.sil rename to test/SILOptimizer/sil_combine_bitops.sil diff --git a/test/SILPasses/sil_combine_devirt.sil b/test/SILOptimizer/sil_combine_devirt.sil similarity index 95% rename from test/SILPasses/sil_combine_devirt.sil rename to test/SILOptimizer/sil_combine_devirt.sil index 81927ca0f5ab2..baddc779a5b21 100644 --- a/test/SILPasses/sil_combine_devirt.sil +++ b/test/SILOptimizer/sil_combine_devirt.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inline | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -devirtualizer | FileCheck %s sil_stage canonical diff --git a/test/SILOptimizer/sil_combine_enum_addr.sil b/test/SILOptimizer/sil_combine_enum_addr.sil new file mode 100644 index 0000000000000..b134a273f712a --- /dev/null +++ b/test/SILOptimizer/sil_combine_enum_addr.sil @@ -0,0 +1,252 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -simplify-cfg | FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +// CHECK-LABEL: sil @convert_inject_enum_addr_select_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () +// CHECK: unconditional_checked_cast_addr +// CHECK: inject_enum_addr +// CHECK-NOT: select_enum_addr +// CHECK-NOT: bb1 +// CHECK: unchecked_take_enum_data_addr +// CHECK: return +sil @convert_inject_enum_addr_select_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () { +bb0(%0 : $*Int, %1 : $*_Stdout): + %2 = alloc_stack $CustomStringConvertible + %3 = alloc_stack $Optional + %4 = init_enum_data_addr %3 : $*Optional, #Optional.Some!enumelt.1 + %5 = alloc_stack $Int + %6 = load %0 : $*Int + store %6 to %5 : $*Int + unconditional_checked_cast_addr take_always Int in %5 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible + inject_enum_addr %3 : $*Optional, #Optional.Some!enumelt.1 + dealloc_stack %5 : $*Int + %11 = integer_literal $Builtin.Int1, -1 + %12 = integer_literal $Builtin.Int1, 0 + %13 = select_enum_addr %3 : $*Optional, case #Optional.Some!enumelt.1: %11, case #Optional.None!enumelt: %12 : $Builtin.Int1 + cond_br %13, bb2, bb1 + +bb1: + %15 = tuple () + dealloc_stack %3 : $*Optional + dealloc_stack %2 : $*CustomStringConvertible + return %15 : $() + +bb2: + %19 = unchecked_take_enum_data_addr %3 : $*Optional, #Optional.Some!enumelt.1 + copy_addr [take] %19 to [initialization] %2 : $*CustomStringConvertible + br bb1 +} + + +// CHECK-LABEL: sil @convert_inject_enum_addr_switch_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () +// CHECK: unconditional_checked_cast_addr +// CHECK: inject_enum_addr +// CHECK-NOT: switch_enum_addr +// CHECK-NOT: bb1 +// CHECK: unchecked_take_enum_data_addr +// CHECK: return +sil @convert_inject_enum_addr_switch_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () { +bb0(%0 : $*Int, %1 : $*_Stdout): + %2 = alloc_stack $CustomStringConvertible + %3 = alloc_stack $Optional + %4 = init_enum_data_addr %3 : $*Optional, #Optional.Some!enumelt.1 + %5 = alloc_stack $Int + %6 = load %0 : $*Int + store %6 to %5 : $*Int + unconditional_checked_cast_addr take_always Int in %5 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible + inject_enum_addr %3 : $*Optional, #Optional.Some!enumelt.1 + dealloc_stack %5 : $*Int + %13 = switch_enum_addr %3 : $*Optional, case #Optional.Some!enumelt.1: bb3, case #Optional.None!enumelt: bb2 + +bb1: + %15 = tuple () + dealloc_stack %3 : $*Optional + dealloc_stack %2 : $*CustomStringConvertible + return %15 : $() + +bb2: + br bb1 + +bb3: + %19 = unchecked_take_enum_data_addr %3 : $*Optional, #Optional.Some!enumelt.1 + copy_addr [take] %19 to [initialization] %2 : $*CustomStringConvertible + br bb1 +} + + +// Check that a checked_cast_addr_br converting a known type into a protocol type +// is performed at the compile-time if protocol conformances are statically known. +// +// CHECK-LABEL: sil @convert_checked_cast_addr_br_into_unconditional_checked_cast_addr_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () +// CHECK: store +// CHECK-NOT: checked_cast_addr_br +// CHECK-NOT: bb1 +// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.Some!enumelt.1 +// CHECK: dealloc_stack +// CHECK: return +sil @convert_checked_cast_addr_br_into_unconditional_checked_cast_addr_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () { +bb0(%0 : $*Int, %1 : $*_Stdout): + %2 = alloc_stack $CustomStringConvertible + %3 = alloc_stack $Optional + %4 = init_enum_data_addr %3 : $*Optional, #Optional.Some!enumelt.1 + %5 = alloc_stack $Int + %6 = load %0 : $*Int + store %6 to %5 : $*Int + checked_cast_addr_br take_always Int in %5 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22 + +bb1: + inject_enum_addr %3 : $*Optional, #Optional.Some!enumelt.1 + br bb2 + +bb2: + dealloc_stack %5 : $*Int + dealloc_stack %3 : $*Optional + %12 = integer_literal $Builtin.Int1, -1 + %13 = integer_literal $Builtin.Int1, 0 + %26 = tuple () + dealloc_stack %2 : $*CustomStringConvertible + return %26 : $() + +bb22: + inject_enum_addr %3 : $*Optional, #Optional.None!enumelt + br bb2 +} + + +class A { + +} + +private final class B { +} + +public class C { +} + +// D cannot be extended elsewhere, but C can! +private class D : C { +} + +// Check that a checked_cast_addr_br converting a known type into a protocol type +// is performed at the compile-time if protocol conformances are statically known. +// In a negative case, take care that check for internal types are not folded (unless +// a whole module optimization is used), because an extension implementing a conformance +// could be defined elsewhere. +// +// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_internal_type : $@convention(thin) (@in A, @inout _Stdout) -> () +// CHECK: checked_cast_addr_br +// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.Some!enumelt.1 +// CHECK: dealloc_stack +// CHECK: return +// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.None!enumelt +// CHECK: } +sil @convert_checked_cast_addr_br_with_internal_type : $@convention(thin) (@in A, @inout _Stdout) -> () { +bb0(%0 : $*A, %1 : $*_Stdout): + %2 = alloc_stack $CustomStringConvertible + %3 = alloc_stack $Optional + %4 = init_enum_data_addr %3 : $*Optional, #Optional.Some!enumelt.1 + %5 = alloc_stack $A + %6 = load %0 : $*A + store %6 to %5 : $*A + checked_cast_addr_br take_always A in %5 : $*A to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22 + +bb1: + inject_enum_addr %3 : $*Optional, #Optional.Some!enumelt.1 + br bb2 + +bb2: + dealloc_stack %5 : $*A + dealloc_stack %3 : $*Optional + %12 = integer_literal $Builtin.Int1, -1 + %13 = integer_literal $Builtin.Int1, 0 + %26 = tuple () + dealloc_stack %2 : $*CustomStringConvertible + return %26 : $() + +bb22: + inject_enum_addr %3 : $*Optional, #Optional.None!enumelt + br bb2 +} + +// Check that a checked_cast_addr_br converting a known type into a protocol type +// is performed at the compile-time if protocol conformances are statically known. +// In a negative case, if the source type is private, it is safe to fold the check, +// because a conformance for this type cannot be defined elsewhere. +// +// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_private_type : $@convention(thin) (@in B, @inout _Stdout) -> () +// CHECK: store +// CHECK-NOT: checked_cast_addr_br +// CHECK-NOT: bb1 +// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.None!enumelt +// CHECK: dealloc_stack +// CHECK: return +sil @convert_checked_cast_addr_br_with_private_type : $@convention(thin) (@in B, @inout _Stdout) -> () { +bb0(%0 : $*B, %1 : $*_Stdout): + %2 = alloc_stack $CustomStringConvertible + %3 = alloc_stack $Optional + %4 = init_enum_data_addr %3 : $*Optional, #Optional.Some!enumelt.1 + %5 = alloc_stack $B + %6 = load %0 : $*B + store %6 to %5 : $*B + checked_cast_addr_br take_always B in %5 : $*B to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22 + +bb1: + inject_enum_addr %3 : $*Optional, #Optional.Some!enumelt.1 + br bb2 + +bb2: + dealloc_stack %5 : $*B + dealloc_stack %3 : $*Optional + %12 = integer_literal $Builtin.Int1, -1 + %13 = integer_literal $Builtin.Int1, 0 + %26 = tuple () + dealloc_stack %2 : $*CustomStringConvertible + return %26 : $() + +bb22: + inject_enum_addr %3 : $*Optional, #Optional.None!enumelt + br bb2 +} + +// Check that a checked_cast_addr_br converting a known type into a protocol type +// is performed at the compile-time if protocol conformances are statically known. +// In a negative case, take care that cast for private types are not folded if one +// of its superclasses could have a conformance extension defined elsewhere. +// +// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_non_private_superclass : $@convention(thin) (@in D, @inout _Stdout) -> () +// CHECK: checked_cast_addr_br +// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.Some!enumelt.1 +// CHECK: dealloc_stack +// CHECK: return +// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.None!enumelt +// CHECK: } +sil @convert_checked_cast_addr_br_with_non_private_superclass : $@convention(thin) (@in D, @inout _Stdout) -> () { +bb0(%0 : $*D, %1 : $*_Stdout): + %2 = alloc_stack $CustomStringConvertible + %3 = alloc_stack $Optional + %4 = init_enum_data_addr %3 : $*Optional, #Optional.Some!enumelt.1 + %5 = alloc_stack $D + %6 = load %0 : $*D + store %6 to %5 : $*D + checked_cast_addr_br take_always D in %5 : $*D to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22 + +bb1: + inject_enum_addr %3 : $*Optional, #Optional.Some!enumelt.1 + br bb2 + +bb2: + dealloc_stack %5 : $*D + dealloc_stack %3 : $*Optional + %12 = integer_literal $Builtin.Int1, -1 + %13 = integer_literal $Builtin.Int1, 0 + %26 = tuple () + dealloc_stack %2 : $*CustomStringConvertible + return %26 : $() + +bb22: + inject_enum_addr %3 : $*Optional, #Optional.None!enumelt + br bb2 +} diff --git a/test/SILPasses/sil_combine_enums.sil b/test/SILOptimizer/sil_combine_enums.sil similarity index 79% rename from test/SILPasses/sil_combine_enums.sil rename to test/SILOptimizer/sil_combine_enums.sil index b09ef3b0f74e8..5e5101a99ac3a 100644 --- a/test/SILPasses/sil_combine_enums.sil +++ b/test/SILOptimizer/sil_combine_enums.sil @@ -17,28 +17,28 @@ sil @external_func: $@convention(thin) () -> () //CHECK: return sil @eliminate_sw_enum_addr : $@convention(thin) () -> Int { bb0: - %0 = alloc_stack $Optional // var x // users: %2, %4, %5, %17, %19 + %0 = alloc_stack $Optional, var, name "x" // users: %2, %4, %5, %17, %19 %1 = alloc_ref $SomeClass // user: %3 - %2 = init_enum_data_addr %0#1 : $*Optional, #Optional.Some!enumelt.1 // user: %3 + %2 = init_enum_data_addr %0 : $*Optional, #Optional.Some!enumelt.1 // user: %3 store %1 to %2 : $*SomeClass // id: %3 - inject_enum_addr %0#1 : $*Optional, #Optional.Some!enumelt.1 // id: %4 - %5 = load %0#1 : $*Optional // users: %6, %8, %9, %14 + inject_enum_addr %0 : $*Optional, #Optional.Some!enumelt.1 // id: %4 + %5 = load %0 : $*Optional // users: %6, %8, %9, %14 %6 = retain_value %5 : $Optional %7 = alloc_stack $Optional // users: %9, %10, %11, %13 %8 = retain_value %5 : $Optional - store %5 to %7#1 : $*Optional // id: %9 - switch_enum_addr %7#1 : $*Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb2 // id: %10 + store %5 to %7 : $*Optional // id: %9 + switch_enum_addr %7 : $*Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb2 // id: %10 bb1: // Preds: bb0 - %11 = unchecked_take_enum_data_addr %7#1 : $*Optional, #Optional.Some!enumelt.1 // user: %12 + %11 = unchecked_take_enum_data_addr %7 : $*Optional, #Optional.Some!enumelt.1 // user: %12 %12 = load %11 : $*SomeClass // users: %15, %16 - dealloc_stack %7#0 : $*@local_storage Optional // id: %13 + dealloc_stack %7 : $*Optional // id: %13 release_value %5 : $Optional // id: %14 %15 = class_method %12 : $SomeClass, #SomeClass.hash!1 : SomeClass -> () -> Int , $@convention(method) (@guaranteed SomeClass) -> Int // user: %16 %16 = apply %15(%12) : $@convention(method) (@guaranteed SomeClass) -> Int // user: %20 - %17 = load %0#1 : $*Optional // user: %18 + %17 = load %0 : $*Optional // user: %18 release_value %17 : $Optional // id: %18 - dealloc_stack %0#0 : $*@local_storage Optional // id: %19 + dealloc_stack %0 : $*Optional // id: %19 return %16 : $Int // id: %20 bb2: // Preds: bb0 @@ -54,36 +54,36 @@ sil @eliminate_select_enum_addr : $@convention(thin) () -> Int { bb0: %0 = alloc_stack $Optional %1 = alloc_ref $SomeClass - %2 = init_enum_data_addr %0#1 : $*Optional, #Optional.Some!enumelt.1 + %2 = init_enum_data_addr %0 : $*Optional, #Optional.Some!enumelt.1 store %1 to %2 : $*SomeClass - inject_enum_addr %0#1 : $*Optional, #Optional.Some!enumelt.1 - %5 = load %0#1 : $*Optional + inject_enum_addr %0 : $*Optional, #Optional.Some!enumelt.1 + %5 = load %0 : $*Optional %6 = retain_value %5 : $Optional %7 = alloc_stack $Optional %8 = retain_value %5 : $Optional - store %5 to %7#1 : $*Optional + store %5 to %7 : $*Optional %t = integer_literal $Builtin.Int1, -1 %f = integer_literal $Builtin.Int1, 0 - %b = select_enum_addr %7#1 : $*Optional, case #Optional.Some!enumelt.1: %t, case #Optional.None!enumelt: %f : $Builtin.Int1 + %b = select_enum_addr %7 : $*Optional, case #Optional.Some!enumelt.1: %t, case #Optional.None!enumelt: %f : $Builtin.Int1 cond_br %b, bb1, bb2 bb1: - %11 = unchecked_take_enum_data_addr %7#1 : $*Optional, #Optional.Some!enumelt.1 + %11 = unchecked_take_enum_data_addr %7 : $*Optional, #Optional.Some!enumelt.1 %12 = load %11 : $*SomeClass // users: %15, %16 - dealloc_stack %7#0 : $*@local_storage Optional + dealloc_stack %7 : $*Optional release_value %5 : $Optional %15 = class_method %12 : $SomeClass, #SomeClass.hash!1 : SomeClass -> () -> Int , $@convention(method) (@guaranteed SomeClass) -> Int %16 = apply %15(%12) : $@convention(method) (@guaranteed SomeClass) -> Int - %17 = load %0#1 : $*Optional + %17 = load %0 : $*Optional release_value %17 : $Optional - dealloc_stack %0#0 : $*@local_storage Optional + dealloc_stack %0 : $*Optional return %16 : $Int bb2: - // Invoke something here and jump to bb1. This prevents an cond_br(select_enum) -> switch_enum conversion, + // Invoke something here and jump to bb1. This prevents a cond_br(select_enum) -> switch_enum conversion, // since it would introduce a critical edge. - %20 = function_ref @external_func: $@convention(thin) ()->() - apply %20(): $@convention(thin) ()->() + %20 = function_ref @external_func: $@convention(thin) () -> () + apply %20(): $@convention(thin) () -> () br bb1 } @@ -136,7 +136,7 @@ bb0(%0 : $*G): sil @canonicalize_init_enum_data_addr : $@convention(thin) (@inout Int32, Builtin.Int32) -> Int32 { bb0(%0 : $*Int32, %1 : $Builtin.Int32): %s1 = alloc_stack $Optional - %e1 = init_enum_data_addr %s1#1 : $*Optional, #Optional.Some!enumelt.1 + %e1 = init_enum_data_addr %s1 : $*Optional, #Optional.Some!enumelt.1 %v = load %0 : $*Int32 store %v to %e1 : $*Int32 %i1 = integer_literal $Builtin.Int32, 1 @@ -145,8 +145,8 @@ bb0(%0 : $*Int32, %1 : $Builtin.Int32): %w = tuple_extract %a : $(Builtin.Int32, Builtin.Int1), 0 %i = struct $Int32 (%w : $Builtin.Int32) store %i to %0 : $*Int32 - inject_enum_addr %s1#1 : $*Optional, #Optional.Some!enumelt.1 - dealloc_stack %s1#0 : $*@local_storage Optional + inject_enum_addr %s1 : $*Optional, #Optional.Some!enumelt.1 + dealloc_stack %s1 : $*Optional return %i : $Int32 } @@ -201,8 +201,8 @@ bb1: return %7 : $Int bb2: - %10 = function_ref @external_func: $@convention(thin) ()->() - apply %10(): $@convention(thin) ()->() + %10 = function_ref @external_func: $@convention(thin) () -> () + apply %10(): $@convention(thin) () -> () br bb1 } diff --git a/test/SILOptimizer/sil_combine_objc.sil b/test/SILOptimizer/sil_combine_objc.sil new file mode 100644 index 0000000000000..492faff5f9acf --- /dev/null +++ b/test/SILOptimizer/sil_combine_objc.sil @@ -0,0 +1,150 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -verify-skip-unreachable-must-be-last | FileCheck %s +// REQUIRES: objc_interop + +sil_stage canonical + +import Builtin +import Swift + +class ZZZ { + @objc deinit + init() +} + +class C {} + +sil @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> +sil @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + +// CHECK-LABEL: sil @dead_closure_elimination : $@convention(thin) (@owned _StringCore) -> () +// CHECK: bb0 +// CHECK-NEXT: release_value +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @dead_closure_elimination : $@convention(thin) (@owned _StringCore) -> () { +bb0(%0 : $_StringCore): + %1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> + %2 = partial_apply %1(%0) : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> + %3 = function_ref @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + %4 = partial_apply %3(%2) : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () + %5 = tuple() + return %5 : $() +} + +// CHECK-LABEL: sil @dead_closure_elimination2 +// CHECK: bb0 +// CHECK-NEXT: br bb1 +// CHECK: bb1 +// CHECK-NEXT: release_value +// CHECK-NEXT: tuple +// CHECK-NEXT: return +sil @dead_closure_elimination2 : $@convention(thin) (@owned _StringCore) -> () { +bb0(%0 : $_StringCore): + %1 = function_ref @stringcore_invariant_check : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> + %2 = partial_apply %1(%0) : $@convention(thin) (@owned _StringCore) -> @owned Optional<_CocoaStringType> + %3 = function_ref @reabstraction_thunk : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + %4 = partial_apply %3(%2) : $@convention(thin) (@out Optional<_CocoaStringType>, @owned @callee_owned () -> @owned Optional<_CocoaStringType>) -> () + br bb1 + +bb1: + strong_retain %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () + strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () + strong_release %4 : $@callee_owned (@out Optional<_CocoaStringType>) -> () + %5 = tuple() + return %5 : $() +} + +// FIXME: Add dead array elimination to DeadObjectElimination +// CHECK-LABEL: test_dead_array +// CHECK: bb0(%0 : $ZZZ): +// DISABLED-CHECK-NEXT: strong_release %0 +// DISABLED-CHECK-NEXT: tuple +// DISABLED-CHECK-NEXT: return +sil @test_dead_array : $@convention(thin) (@owned ZZZ) -> () { +bb0(%0 : $ZZZ): + %1 = integer_literal $Builtin.Word, 1 + %2 = function_ref @_allocate_uninitialized_ZZZ : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) + %3 = apply %2(%1) : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) + %4 = tuple_extract %3 : $(Array, Builtin.RawPointer), 0 + %5 = tuple_extract %3 : $(Array, Builtin.RawPointer), 1 + %6 = pointer_to_address %5 : $Builtin.RawPointer to $*ZZZ + store %0 to %6 : $*ZZZ + %8 = struct_extract %4 : $Array, #Array._buffer + %9 = struct_extract %8 : $_ArrayBuffer, #_ArrayBuffer._storage + %10 = struct_extract %9 : $_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCoreType>, #_BridgeStorage.rawValue + strong_release %10 : $Builtin.BridgeObject + %12 = tuple () + return %12 : $() +} + +sil [_semantics "array.uninitialized"] @_allocate_uninitialized_ZZZ : $@convention(thin) (Builtin.Word) -> @owned (Array, Builtin.RawPointer) + +// dead_array test helpers +sil [thunk] @dead_array_run_closure : $@convention(thin) (@owned @callee_owned () -> Bool) -> () { +bb0(%0 : $@callee_owned () -> Bool): + %1 = apply %0() : $@callee_owned () -> Bool + %2 = tuple () + return %2 : $() +} + +sil @dead_array_closure : $@convention(thin) (@inout _HeapBuffer) -> Bool { +bb0(%0 : $*_HeapBuffer): + %1 = struct_element_addr %0 : $*_HeapBuffer, #_HeapBuffer._storage // user: %2 + %2 = is_unique %1 : $*Optional // user: %3 + %3 = struct $Bool (%2 : $Builtin.Int1) // user: %4 + return %3 : $Bool // id: %4 +} + +// Mimicks Swift._allocateUninitializedArray +sil [_semantics "array.uninitialized"] @dead_array_alloc : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) + +// HeapBuffer.swift test case spuriously reports a "unique" buffer +// CHECK-LABEL: sil @dead_array +// CHECK-NOT: release +// CHECK: retain_value %{{[0-9]+}} : $Optional +// CHECK: apply +// CHECK: strong_release %{{[0-9]+}} : $Builtin.BridgeObject +sil @dead_array : $@convention(thin) (@inout _HeapBuffer) -> () { +bb0(%0 : $*_HeapBuffer): + %1 = integer_literal $Builtin.Word, 1 // user: %3 + %2 = function_ref @dead_array_alloc : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) + %3 = apply %2<_HeapBuffer>(%1) : $@convention(thin) <τ_0_0> (Builtin.Word) -> @owned (Array<τ_0_0>, Builtin.RawPointer) + %4 = tuple_extract %3 : $(Array<_HeapBuffer>, Builtin.RawPointer), 0 // user: %15 + %5 = tuple_extract %3 : $(Array<_HeapBuffer>, Builtin.RawPointer), 1 // user: %6 + %6 = pointer_to_address %5 : $Builtin.RawPointer to $*_HeapBuffer // user: %9 + %7 = load %0 : $*_HeapBuffer // users: %8, %9 + %8 = struct_extract %7 : $_HeapBuffer, #_HeapBuffer._storage // user: %13 + store %7 to %6 : $*_HeapBuffer // id: %9 + %10 = function_ref @dead_array_run_closure : $@convention(thin) (@owned @callee_owned () -> Bool) -> () // user: %14 + %11 = function_ref @dead_array_closure : $@convention(thin) (@inout _HeapBuffer) -> Bool // user: %12 + %12 = partial_apply %11(%0) : $@convention(thin) (@inout _HeapBuffer) -> Bool // user: %14 + retain_value %8 : $Optional // id: %13 + %14 = apply %10(%12) : $@convention(thin) (@owned @callee_owned () -> Bool) -> () + %15 = struct_extract %4 : $Array<_HeapBuffer>, #Array._buffer // user: %16 + %16 = struct_extract %15 : $_ArrayBuffer<_HeapBuffer>, #_ArrayBuffer._storage // user: %17 + %17 = struct_extract %16 : $_BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCoreType>, #_BridgeStorage.rawValue // user: %18 + strong_release %17 : $Builtin.BridgeObject // id: %18 + %19 = tuple () // user: %20 + return %19 : $() // id: %20 +} + +// Check that it does not crash the compiler. +// Int is ObjC-bridgeable in this case, but its conformance is not know, +// because Foundation is not imported yet. +// Therefore the cast may succeed from the compiler point of view. +// CHECK-LABEL: sil @cast_of_class_to_int +// CHECK: unconditional_checked_cast_addr +// CHECK: return +sil @cast_of_class_to_int : $@convention(thin) (C) -> Int { +bb0(%0 : $C): + %1 = alloc_stack $Int + %2 = alloc_stack $C + store %0 to %2 : $*C + unconditional_checked_cast_addr take_always C in %2 : $*C to Int in %1 : $*Int + %4 = load %1 : $*Int + dealloc_stack %2 : $*C + dealloc_stack %1 : $*Int + return %4 : $Int +} + diff --git a/test/SILPasses/sil_combine_objc_bridge.sil b/test/SILOptimizer/sil_combine_objc_bridge.sil similarity index 97% rename from test/SILPasses/sil_combine_objc_bridge.sil rename to test/SILOptimizer/sil_combine_objc_bridge.sil index 2c5cabb884d9d..b45ee3f5903ef 100644 --- a/test/SILPasses/sil_combine_objc_bridge.sil +++ b/test/SILOptimizer/sil_combine_objc_bridge.sil @@ -187,9 +187,9 @@ bb0(%0 : $AnNSArray): sil shared @bridge_from_swift_array_to_NSObject_cast: $@convention(thin) (@out NSObject, @in Array) -> () { bb0(%0 : $*NSObject, %1 : $*Array): %2 = alloc_stack $Array - copy_addr %1 to [initialization] %2#1 : $*Array - unconditional_checked_cast_addr take_always Array in %2#1 : $*Array to NSObject in %0 : $*NSObject - dealloc_stack %2#0 : $*@local_storage Array + copy_addr %1 to [initialization] %2 : $*Array + unconditional_checked_cast_addr take_always Array in %2 : $*Array to NSObject in %0 : $*NSObject + dealloc_stack %2 : $*Array destroy_addr %1 : $*Array %7 = tuple () return %7 : $() diff --git a/test/SILPasses/sil_combine_same_ops.sil b/test/SILOptimizer/sil_combine_same_ops.sil similarity index 100% rename from test/SILPasses/sil_combine_same_ops.sil rename to test/SILOptimizer/sil_combine_same_ops.sil diff --git a/test/SILPasses/sil_combine_uncheck.sil b/test/SILOptimizer/sil_combine_uncheck.sil similarity index 100% rename from test/SILPasses/sil_combine_uncheck.sil rename to test/SILOptimizer/sil_combine_uncheck.sil diff --git a/test/SILPasses/sil_concat_string_literals.sil b/test/SILOptimizer/sil_concat_string_literals.sil similarity index 93% rename from test/SILPasses/sil_concat_string_literals.sil rename to test/SILOptimizer/sil_concat_string_literals.sil index 76879b3932039..4f82b7698c55c 100644 --- a/test/SILPasses/sil_concat_string_literals.sil +++ b/test/SILOptimizer/sil_concat_string_literals.sil @@ -14,7 +14,7 @@ import Swift // StringConcat.testStringConcat_UnicodeScalarLiteral_UnicodeScalarLiteral () -> Swift.String sil @_TF12StringConcat58testStringConcat_UnicodeScalarLiteral_UnicodeScalarLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinStringLiteral (Swift.String.Type)(Builtin.RawPointer, byteSize : Builtin.Word, isASCII : Builtin.Int1) -> Swift.String @@ -32,8 +32,8 @@ bb0: %12 = integer_literal $Builtin.Int1, -1 // user: %13 %13 = apply %8(%10, %11, %12, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -44,7 +44,7 @@ bb0: // StringConcat.testStringConcat_UnicodeScalarLiteral_ExtendedGraphemeClusterLiteral () -> Swift.String sil @_TF12StringConcat68testStringConcat_UnicodeScalarLiteral_ExtendedGraphemeClusterLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinStringLiteral (Swift.String.Type)(Builtin.RawPointer, byteSize : Builtin.Word, isASCII : Builtin.Int1) -> Swift.String @@ -62,8 +62,8 @@ bb0: %12 = integer_literal $Builtin.Int1, 0 %13 = apply %8(%10, %11, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -83,7 +83,7 @@ sil [readonly] [_semantics "string.makeUTF16"] @_TFSS37_convertFromBuiltinUTF16S // StringConcat.testStringConcat_UnicodeScalarLiteral_StringLiteral () -> Swift.String sil @_TF12StringConcat51testStringConcat_UnicodeScalarLiteral_StringLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinStringLiteral (Swift.String.Type)(Builtin.RawPointer, byteSize : Builtin.Word, isASCII : Builtin.Int1) -> Swift.String @@ -101,8 +101,8 @@ bb0: %12 = integer_literal $Builtin.Int1, -1 // user: %13 %13 = apply %8(%10, %11, %12, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -113,7 +113,7 @@ bb0: // StringConcat.testStringConcat_ExtendedGraphemeClusterLiteral_UnicodeScalarLiteral () -> Swift.String sil @_TF12StringConcat68testStringConcat_ExtendedGraphemeClusterLiteral_UnicodeScalarLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinUTF16StringLiteral (Swift.String.Type)(Builtin.RawPointer, numberOfCodeUnits : Builtin.Word) -> Swift.String @@ -131,8 +131,8 @@ bb0: %12 = integer_literal $Builtin.Int1, -1 // user: %13 %13 = apply %8(%10, %11, %12, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -143,7 +143,7 @@ bb0: // StringConcat.testStringConcat_ExtendedGraphemeClusterLiteral_ExtendedGraphemeClusterLiteral () -> Swift.String sil @_TF12StringConcat78testStringConcat_ExtendedGraphemeClusterLiteral_ExtendedGraphemeClusterLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinUTF16StringLiteral (Swift.String.Type)(Builtin.RawPointer, numberOfCodeUnits : Builtin.Word) -> Swift.String @@ -161,8 +161,8 @@ bb0: %12 = integer_literal $Builtin.Int1, 0 %13 = apply %8(%10, %11, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -173,7 +173,7 @@ bb0: // StringConcat.testStringConcat_ExtendedGraphemeClusterLiteral_StringLiteral () -> Swift.String sil @_TF12StringConcat61testStringConcat_ExtendedGraphemeClusterLiteral_StringLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinUTF16StringLiteral (Swift.String.Type)(Builtin.RawPointer, numberOfCodeUnits : Builtin.Word) -> Swift.String @@ -191,8 +191,8 @@ bb0: %12 = integer_literal $Builtin.Int1, -1 // user: %13 %13 = apply %8(%10, %11, %12, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -203,7 +203,7 @@ bb0: // StringConcat.testStringConcat_StringLiteral_UnicodeScalarLiteral () -> Swift.String sil @_TF12StringConcat51testStringConcat_StringLiteral_UnicodeScalarLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinStringLiteral (Swift.String.Type)(Builtin.RawPointer, byteSize : Builtin.Word, isASCII : Builtin.Int1) -> Swift.String @@ -221,8 +221,8 @@ bb0: %12 = integer_literal $Builtin.Int1, -1 // user: %13 %13 = apply %8(%10, %11, %12, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -233,7 +233,7 @@ bb0: // StringConcat.testStringConcat_StringLiteral_ExtendedGraphemeClusterLiteral () -> Swift.String sil @_TF12StringConcat61testStringConcat_StringLiteral_ExtendedGraphemeClusterLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinStringLiteral (Swift.String.Type)(Builtin.RawPointer, byteSize : Builtin.Word, isASCII : Builtin.Int1) -> Swift.String @@ -251,8 +251,8 @@ bb0: %12 = integer_literal $Builtin.Int1, 0 %13 = apply %8(%10, %11, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -263,7 +263,7 @@ bb0: // StringConcat.testStringConcat_StringLiteral_StringLiteral () -> Swift.String sil @_TF12StringConcat44testStringConcat_StringLiteral_StringLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %15, %16 + %0 = alloc_stack $String, var, name "s" // users: %15, %16 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %14 // function_ref Swift.String._convertFromBuiltinStringLiteral (Swift.String.Type)(Builtin.RawPointer, byteSize : Builtin.Word, isASCII : Builtin.Int1) -> Swift.String @@ -281,8 +281,8 @@ bb0: %12 = integer_literal $Builtin.Int1, -1 // user: %13 %13 = apply %8(%10, %11, %12, %9) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %14 %14 = apply %1(%7, %13) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %15, %17 - store %14 to %0#1 : $*String // id: %15 - dealloc_stack %0#0 : $*@local_storage String // id: %16 + store %14 to %0 : $*String // id: %15 + dealloc_stack %0 : $*String // id: %16 return %14 : $String // id: %17 } @@ -295,7 +295,7 @@ bb0: // StringConcat.testStringConcat_StringLiteral_StringLiteral_StringLiteral_StringLiteral () -> Swift.String sil @_TF12StringConcat72testStringConcat_StringLiteral_StringLiteral_StringLiteral_StringLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %31, %32 + %0 = alloc_stack $String, var, name "s" // users: %31, %32 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %30 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String @@ -333,8 +333,8 @@ bb0: %28 = integer_literal $Builtin.Int1, -1 // user: %29 %29 = apply %24(%26, %27, %28, %25) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> @owned String // user: %30 %30 = apply %1(%23, %29) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %31, %33 - store %30 to %0#1 : $*String // id: %31 - dealloc_stack %0#0 : $*@local_storage String // id: %32 + store %30 to %0 : $*String // id: %31 + dealloc_stack %0 : $*String // id: %32 return %30 : $String // id: %33 } @@ -346,7 +346,7 @@ bb0: // StringConcat.testStringConcat_StringLiteral_UnicodeScalarLiteral_ExtendedGraphemeClusterLiteral () -> Swift.String sil @_TF12StringConcat82testStringConcat_StringLiteral_UnicodeScalarLiteral_ExtendedGraphemeClusterLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %23, %24 + %0 = alloc_stack $String, var, name "s" // users: %23, %24 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %22 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String @@ -374,8 +374,8 @@ bb0: %20 = integer_literal $Builtin.Int1, 0 %21 = apply %16(%18, %19, %17) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, @thin String.Type) -> @owned String // user: %22 %22 = apply %1(%15, %21) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %23, %25 - store %22 to %0#1 : $*String // id: %23 - dealloc_stack %0#0 : $*@local_storage String // id: %24 + store %22 to %0 : $*String // id: %23 + dealloc_stack %0 : $*String // id: %24 return %22 : $String // id: %25 } @@ -388,7 +388,7 @@ bb0: // StringConcat.testStringConcat_ExtendedGraphemeClusterLiteral_ExtendedGraphemeClusterLiteral_ExtendedGraphemeClusterLiteral () -> Swift.String sil @_TF12StringConcat109testStringConcat_ExtendedGraphemeClusterLiteral_ExtendedGraphemeClusterLiteral_ExtendedGraphemeClusterLiteralFT_SS : $@convention(thin) () -> @owned String { bb0: - %0 = alloc_stack $String // var s // users: %23, %24 + %0 = alloc_stack $String, var, name "s" // users: %23, %24 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String %1 = function_ref @_TFsoi1pFTSSSS_SS : $@convention(thin) (@owned String, @owned String) -> @owned String // user: %22 // function_ref Swift.+ infix (Swift.String, Swift.String) -> Swift.String @@ -416,8 +416,8 @@ bb0: %20 = integer_literal $Builtin.Int1, 0 %21 = apply %16(%18, %19, %17) : $@convention(thin) (Builtin.RawPointer, Builtin.Word, @thin String.Type) -> @owned String // user: %22 %22 = apply %1(%15, %21) : $@convention(thin) (@owned String, @owned String) -> @owned String // users: %23, %25 - store %22 to %0#1 : $*String // id: %23 - dealloc_stack %0#0 : $*@local_storage String // id: %24 + store %22 to %0 : $*String // id: %23 + dealloc_stack %0 : $*String // id: %24 return %22 : $String // id: %25 } diff --git a/test/SILPasses/sil_locations.sil b/test/SILOptimizer/sil_locations.sil similarity index 100% rename from test/SILPasses/sil_locations.sil rename to test/SILOptimizer/sil_locations.sil diff --git a/test/SILPasses/sil_locations.swift b/test/SILOptimizer/sil_locations.swift similarity index 100% rename from test/SILPasses/sil_locations.swift rename to test/SILOptimizer/sil_locations.swift diff --git a/test/SILPasses/sil_simplify_instrs.sil b/test/SILOptimizer/sil_simplify_instrs.sil similarity index 100% rename from test/SILPasses/sil_simplify_instrs.sil rename to test/SILOptimizer/sil_simplify_instrs.sil diff --git a/test/SILPasses/sil_witness_tables_external_witnesstable.swift b/test/SILOptimizer/sil_witness_tables_external_witnesstable.swift similarity index 100% rename from test/SILPasses/sil_witness_tables_external_witnesstable.swift rename to test/SILOptimizer/sil_witness_tables_external_witnesstable.swift diff --git a/test/SILOptimizer/simp_enum.sil b/test/SILOptimizer/simp_enum.sil new file mode 100644 index 0000000000000..bf2f2de850857 --- /dev/null +++ b/test/SILOptimizer/simp_enum.sil @@ -0,0 +1,53 @@ +// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine | FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +enum SimpleEnum { + case Empty + case HasInt(Int) + case HasInt2(Int) +} + +//CHECK: _TF4main12test_union_1FT1EOS_10SimpleEnum_S0_ +//CHECK: switch_enum +//CHECK: bb2 +//CHECK: enum $SimpleEnum, #SimpleEnum.HasInt2!enumelt.1, %{{[0-9]+}} : $Int +//CHECK: bb3 +//CHECK: enum $SimpleEnum, #SimpleEnum.HasInt!enumelt.1, %{{[0-9]+}} : $Int +//CHECK: bb4 +//CHECK: return + +// main.test_union_1 (E : main.SimpleEnum) -> main.SimpleEnum +sil @_TF4main12test_union_1FT1EOS_10SimpleEnum_S0_ : $@convention(thin) (SimpleEnum) -> SimpleEnum { +bb0(%0 : $SimpleEnum): + %1 = alloc_stack $SimpleEnum, var, name "E" // users: %16, %2 + store %0 to %1 : $*SimpleEnum // id: %2 + %3 = tuple () + switch_enum %0 : $SimpleEnum, case #SimpleEnum.Empty!enumelt: bb1, case #SimpleEnum.HasInt!enumelt.1: bb3, case #SimpleEnum.HasInt2!enumelt.1:bb4 // id: %4 + +bb1: // Preds: bb0 + %6 = enum $SimpleEnum, #SimpleEnum.Empty!enumelt // user: %7 + br bb5(%6 : $SimpleEnum) // id: %7 + +bb3(%8 : $Int): // Preds: bb0 + %9 = alloc_stack $Int, var, name "N" // users: %13, %10 + store %8 to %9 : $*Int // id: %10 + %12 = enum $SimpleEnum, #SimpleEnum.HasInt2!enumelt.1, %8 : $Int // user: %14 + dealloc_stack %9 : $*Int // id: %13 + br bb5(%12 : $SimpleEnum) // id: %14 + +bb4(%13 : $Int): // Preds: bb0 + %14 = alloc_stack $Int, var, name "N" // users: %13, %10 + store %13 to %14 : $*Int // id: %10 + %15 = enum $SimpleEnum, #SimpleEnum.HasInt!enumelt.1, %13 : $Int // user: %14 + dealloc_stack %14 : $*Int // id: %13 + br bb5(%15 : $SimpleEnum) // id: %14 + +bb5(%16 : $SimpleEnum): // Preds: bb2 bb4 + dealloc_stack %1 : $*SimpleEnum // id: %16 + return %16 : $SimpleEnum // id: %17 +} + diff --git a/test/SILPasses/simplify_cfg.sil b/test/SILOptimizer/simplify_cfg.sil similarity index 93% rename from test/SILPasses/simplify_cfg.sil rename to test/SILOptimizer/simplify_cfg.sil index fbc5aafdfa5f6..922cc31d2a1a4 100644 --- a/test/SILPasses/simplify_cfg.sil +++ b/test/SILOptimizer/simplify_cfg.sil @@ -369,7 +369,7 @@ bb4(%6 : $Int64): } // Make sure the cond_br is not simplified as it would create -// a crticial edge. +// a critical edge. // CHECK-LABEL: @elim_trampoline4 // CHECK: cond_br %0, bb1, bb2 // CHECK: bb1: @@ -380,7 +380,7 @@ bb4(%6 : $Int64): // CHECK: return // CHECK: } -sil @external_f : $@convention(thin) ()->() +sil @external_f : $@convention(thin) () -> () sil @elim_trampoline4 : $@convention(thin) (Builtin.Int1, Int64, Int64) -> Int64 { bb0(%0 : $Builtin.Int1, %1 : $Int64, %2 : $Int64): @@ -393,8 +393,8 @@ bb2: br bb4(%2 : $Int64) bb4(%4 : $Int64): - %55 = function_ref @external_f : $@convention(thin) ()->() - apply %55() : $@convention(thin) ()->() + %55 = function_ref @external_f : $@convention(thin) () -> () + apply %55() : $@convention(thin) () -> () br bb5(%4: $Int64) bb3(%5 : $Int64): @@ -473,15 +473,15 @@ bb4(%6 : $Int64): // CHECK-NEXT: return %1 sil @elim_common_arg : $@convention(thin) (Builtin.Int1, Int64) -> Int64 { bb0(%0 : $Builtin.Int1, %1 : $Int64): - %f1 = function_ref @external_f : $@convention(thin) ()->() + %f1 = function_ref @external_f : $@convention(thin) () -> () cond_br %0, bb1, bb2 bb1: - apply %f1() : $@convention(thin) ()->() + apply %f1() : $@convention(thin) () -> () br bb3(%1 : $Int64) bb2: - apply %f1() : $@convention(thin) ()->() + apply %f1() : $@convention(thin) () -> () br bb3(%1 : $Int64) bb3(%a1 : $Int64): @@ -632,14 +632,14 @@ bb3(%12 : $Bool): // CHECK-NOT: bb4: bb4: %21 = alloc_stack $Optional - store %0 to %21#1 : $*Optional + store %0 to %21 : $*Optional // CHECK-NOT: switch_enum switch_enum %0 : $Optional, case #Optional.Some!enumelt.1: bb5, case #Optional.None!enumelt: bb6 bb5: - %25 = unchecked_take_enum_data_addr %21#1 : $*Optional, #Optional.Some!enumelt.1 + %25 = unchecked_take_enum_data_addr %21 : $*Optional, #Optional.Some!enumelt.1 %26 = load %25 : $*C - dealloc_stack %21#0 : $*@local_storage Optional + dealloc_stack %21 : $*Optional %29 = ref_element_addr %26 : $C, #C.value %30 = load %29 : $*Int32 br bb8(%30 : $Int32) @@ -668,11 +668,11 @@ sil @cannot_optimize_switch_enum : $@convention(thin) (A) -> () { bb0(%0 : $A): // CHECK: %1 = function_ref // CHECK-NEXT: switch_enum %0 : $A, case #A.B!enumelt: bb1, default [[BB:bb[0-9a-zA-Z]+]] - %f1 = function_ref @external_f : $@convention(thin) ()->() + %f1 = function_ref @external_f : $@convention(thin) () -> () switch_enum %0 : $A, case #A.B!enumelt: bb1, default bb2 bb1: - apply %f1() : $@convention(thin) ()->() + apply %f1() : $@convention(thin) () -> () br bb5 // CHECK: [[BB]] @@ -681,11 +681,11 @@ bb2: switch_enum %0 : $A, case #A.C!enumelt: bb3, default bb4 bb3: - apply %f1() : $@convention(thin) ()->() + apply %f1() : $@convention(thin) () -> () br bb5 bb4: - apply %f1() : $@convention(thin) ()->() + apply %f1() : $@convention(thin) () -> () br bb5 bb5: @@ -993,7 +993,7 @@ sil @_TFC3ccb4Base6middlefS0_FT_T_ : $@convention(method) (@guaranteed Base) -> // CHECK-LABEL: sil @redundant_checked_cast_br sil @redundant_checked_cast_br : $@convention(method) (@guaranteed Base) -> () { bb0(%0 : $Base): -// CHECK: [[METHOD:%.*]] = class_method %0 : $Base, #Base.middle!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () +// CHECK: [[METHOD:%.*]] = class_method %0 : $Base, #Base.middle!1 : (Base) -> () -> () , $@convention(method) (@guaranteed Base) -> () %1 = class_method %0 : $Base, #Base.middle!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () // CHECK: checked_cast_br [exact] %0 : $Base to $Base, [[SUCCESS:bb[0-9]+]], [[FAIL:bb[0-9]+]] checked_cast_br [exact] %0 : $Base to $Base, bb2, bb7 @@ -1041,7 +1041,7 @@ bb7: // CHECK-LABEL: sil @not_redundant_checked_cast_br : $@convention(method) (@guaranteed Base) -> () { sil @not_redundant_checked_cast_br : $@convention(method) (@guaranteed Base) -> () { bb0(%0 : $Base): -// CHECK: [[METHOD:%.*]] = class_method %0 : $Base, #Base.middle!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () +// CHECK: [[METHOD:%.*]] = class_method %0 : $Base, #Base.middle!1 : (Base) -> () -> () , $@convention(method) (@guaranteed Base) -> () %1 = class_method %0 : $Base, #Base.middle!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () // CHECK: checked_cast_br [exact] %0 : $Base to $Base, [[SUCCESS:bb[0-9]+]], [[FAIL:bb[0-9]+]] checked_cast_br [exact] %0 : $Base to $Base, bb2, bb7 @@ -1052,7 +1052,7 @@ bb1: bb2(%5 : $Base): // CHECK: [[SUCCESS]] -// CHECK: [[METHOD2:%.*]] = class_method %0 : $Base, #Base.inner!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () +// CHECK: [[METHOD2:%.*]] = class_method %0 : $Base, #Base.inner!1 : (Base) -> () -> () , $@convention(method) (@guaranteed Base) -> () %7 = class_method %0 : $Base, #Base.inner!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () %8 = apply %7(%0) : $@convention(method) (@guaranteed Base) -> () br bb4 @@ -1067,7 +1067,7 @@ bb4: br bb6(%13 : $()) bb5: - %14 = class_method %0 : $Base, #Base.inner!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () + %14 = class_method %0 : $Base, #Base.inner!1 : (Base) -> () -> () , $@convention(method) (@guaranteed Base) -> () %15 = apply %14(%0) : $@convention(method) (@guaranteed Base) -> () br bb4 @@ -1086,7 +1086,7 @@ bb7: // CHECK-LABEL: sil @failing_checked_cast_br sil @failing_checked_cast_br : $@convention(method) (@guaranteed Base) -> () { bb0(%0 : $Base): -// CHECK: [[METHOD:%.*]] = class_method %0 : $Base, #Base.middle!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () +// CHECK: [[METHOD:%.*]] = class_method %0 : $Base, #Base.middle!1 : (Base) -> () -> () , $@convention(method) (@guaranteed Base) -> () %1 = class_method %0 : $Base, #Base.middle!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () // CHECK: checked_cast_br [exact] %0 : $Base to $Base, [[SUCCESS:bb[0-9]+]], [[FAIL:bb[0-9]+]] checked_cast_br [exact] %0 : $Base to $Base, bb2, bb7 @@ -1098,7 +1098,7 @@ bb1: bb2(%5 : $Base): // CHECK: [[SUCCESS]] -// CHECK: [[METHOD2:%.*]] = class_method %0 : $Base, #Base.inner!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () +// CHECK: [[METHOD2:%.*]] = class_method %0 : $Base, #Base.inner!1 : (Base) -> () -> () , $@convention(method) (@guaranteed Base) -> () %7 = class_method %0 : $Base, #Base.inner!1 : Base -> () -> () , $@convention(method) (@guaranteed Base) -> () // CHECK-NOT: checked_cast_br [exact] %0 : $Base to $Derived // CHECK: apply [[METHOD2]] @@ -1546,8 +1546,8 @@ bb1: bb2: // Make bb1 not dominated from bb0 to prevent that dominator based // simplification does the same thing. - %55 = function_ref @external_f : $@convention(thin) ()->() - apply %55() : $@convention(thin) ()->() + %55 = function_ref @external_f : $@convention(thin) () -> () + apply %55() : $@convention(thin) () -> () cond_br %1, bb1, bb3 bb3: %2 = tuple() @@ -1573,8 +1573,8 @@ bb1: bb2: // Make bb1 not dominated from bb0 to prevent that dominator based // simplification does the same thing. - %55 = function_ref @external_f : $@convention(thin) ()->() - apply %55() : $@convention(thin) ()->() + %55 = function_ref @external_f : $@convention(thin) () -> () + apply %55() : $@convention(thin) () -> () cond_br %1, bb1, bb3 bb3: %2 = tuple() @@ -1598,8 +1598,8 @@ bb1: bb2: // Make bb1 not dominated from bb0 to prevent that dominator based // simplification does the same thing. - %55 = function_ref @external_f : $@convention(thin) ()->() - apply %55() : $@convention(thin) ()->() + %55 = function_ref @external_f : $@convention(thin) () -> () + apply %55() : $@convention(thin) () -> () cond_br %1, bb1, bb3 bb3: %2 = tuple() @@ -1620,8 +1620,8 @@ bb1: unreachable bb2: // Make bb1 not dominated from bb0. - %55 = function_ref @external_f : $@convention(thin) ()->() - apply %55() : $@convention(thin) ()->() + %55 = function_ref @external_f : $@convention(thin) () -> () + apply %55() : $@convention(thin) () -> () cond_br %1, bb1, bb3 bb3: %2 = tuple() @@ -1643,16 +1643,16 @@ bb3: // CHECK: return sil @move_cond_fail : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> () { bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): - %f1 = function_ref @external_f : $@convention(thin) ()->() + %f1 = function_ref @external_f : $@convention(thin) () -> () cond_br %0, bb2, bb1 bb1: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations %i1 = integer_literal $Builtin.Int1, -1 br bb3(%i1 : $Builtin.Int1) bb2: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations br bb3(%1 : $Builtin.Int1) bb3(%a3 : $Builtin.Int1): @@ -1680,15 +1680,15 @@ bb3(%a3 : $Builtin.Int1): sil @move_cond_fail_inverted : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> () { bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): %2 = integer_literal $Builtin.Int1, -1 - %f1 = function_ref @external_f : $@convention(thin) ()->() + %f1 = function_ref @external_f : $@convention(thin) () -> () cond_br %0, bb2, bb1 bb1: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations br bb3(%2 : $Builtin.Int1) bb2: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations br bb3(%1 : $Builtin.Int1) bb3(%a3 : $Builtin.Int1): @@ -1709,15 +1709,15 @@ bb3(%a3 : $Builtin.Int1): // CHECK-NEXT: cond_fail sil @dont_move_cond_fail_no_const : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1) -> () { bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1, %2 : $Builtin.Int1): - %f1 = function_ref @external_f : $@convention(thin) ()->() + %f1 = function_ref @external_f : $@convention(thin) () -> () cond_br %0, bb2, bb1 bb1: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations br bb3(%1 : $Builtin.Int1) bb2: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations br bb3(%2 : $Builtin.Int1) bb3(%a3 : $Builtin.Int1): @@ -1741,20 +1741,20 @@ bb3(%a3 : $Builtin.Int1): // CHECK-NEXT: cond_fail sil @dont_move_cond_fail_no_postdom : $@convention(thin) (Builtin.Int1, Builtin.Int1, Builtin.Int1) -> () { bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1, %2 : $Builtin.Int1): - %f1 = function_ref @external_f : $@convention(thin) ()->() + %f1 = function_ref @external_f : $@convention(thin) () -> () cond_br %0, bb2, bb1 bb1: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations %i1 = integer_literal $Builtin.Int1, -1 br bb3(%i1 : $Builtin.Int1) bb2: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations cond_br %2, bb3(%1 : $Builtin.Int1), bb4 bb3(%a3 : $Builtin.Int1): - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations cond_fail %a3 : $Builtin.Int1 br bb4 @@ -1775,16 +1775,16 @@ bb4: // CHECK-NEXT: cond_fail sil @dont_move_cond_fail_multiple_uses : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 { bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): - %f1 = function_ref @external_f : $@convention(thin) ()->() + %f1 = function_ref @external_f : $@convention(thin) () -> () cond_br %0, bb2, bb1 bb1: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations %i1 = integer_literal $Builtin.Int1, -1 br bb3(%i1 : $Builtin.Int1) bb2: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations br bb3(%1 : $Builtin.Int1) bb3(%a3 : $Builtin.Int1): @@ -1805,16 +1805,16 @@ bb3(%a3 : $Builtin.Int1): // CHECK-NEXT: return sil @dont_move_cond_fail_multiple_uses2 : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 { bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): - %f1 = function_ref @external_f : $@convention(thin) ()->() + %f1 = function_ref @external_f : $@convention(thin) () -> () %i1 = integer_literal $Builtin.Int1, -1 cond_br %0, bb2, bb1 bb1: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations br bb3(%i1 : $Builtin.Int1) bb2: - apply %f1() : $@convention(thin) ()->() // prevent other CFG optimizations + apply %f1() : $@convention(thin) () -> () // prevent other CFG optimizations br bb3(%1 : $Builtin.Int1) bb3(%a3 : $Builtin.Int1): @@ -1921,7 +1921,7 @@ bb4: return %41 : $() } -sil @f_use : $@convention(thin) (Builtin.Int32)->() +sil @f_use : $@convention(thin) (Builtin.Int32) -> () // CHECK-LABEL: sil @switch_enum_jumpthreading_bug // CHECK: bb1: @@ -1962,8 +1962,8 @@ bb4: unreachable bb5(%9 : $Builtin.Int32): - %f = function_ref @f_use : $@convention(thin) (Builtin.Int32)->() - %a = apply %f(%10) : $@convention(thin) (Builtin.Int32)->() + %f = function_ref @f_use : $@convention(thin) (Builtin.Int32) -> () + %a = apply %f(%10) : $@convention(thin) (Builtin.Int32) -> () cond_br %3, bb6, bb10 bb6: @@ -1977,10 +1977,10 @@ bb11(%100 : $Builtin.Int32): return %100 : $Builtin.Int32 } -sil @a : $@convention(thin) ()->() -sil @b : $@convention(thin) ()->() -sil @c : $@convention(thin) ()->() -sil @d : $@convention(thin) ()->() +sil @a : $@convention(thin) () -> () +sil @b : $@convention(thin) () -> () +sil @c : $@convention(thin) () -> () +sil @d : $@convention(thin) () -> () // CHECK-LABEL: sil @jump_thread_diamond // CHECK: bb1: @@ -2105,8 +2105,8 @@ bb10: return %21 : $() } -sil @fB : $@convention(thin) ()->() -sil @fC : $@convention(thin) ()->() +sil @fB : $@convention(thin) () -> () +sil @fC : $@convention(thin) () -> () // Make sure that we correctly thread such that we end up calling @fB on the @@ -2258,17 +2258,17 @@ sil [noinline] @initCC : $@convention(thin) (@thick CC.Type) -> @owned @callee_o sil [noinline] @takeBB : $@convention(thin) (@owned BB) -> @owned BB // Check that we don't crash on this. -// The compiler should be able to cast between the labled and unlabled return tuple types. -// CHECK-LABEL: @try_apply_with_convert_function_returning_casted_unlabled_tuple +// The compiler should be able to cast between the labeled and unlabeled return tuple types. +// CHECK-LABEL: @try_apply_with_convert_function_returning_casted_unlabeled_tuple // CHECK: apply {{%[0-9]+}} // Proper tuple is created by deconstructing the old one and creating a new one using its elements. // CHECK: tuple_extract // CHECK: tuple_extract // CHECK: tuple // CHECK: return -sil @try_apply_with_convert_function_returning_casted_unlabled_tuple: $@convention(thin) () -> (Int32, Int32) { +sil @try_apply_with_convert_function_returning_casted_unlabeled_tuple: $@convention(thin) () -> (Int32, Int32) { bb0: - %3 = function_ref @returnLabledTuple : $@convention(thin) () -> (first: Int32, second: Int32) + %3 = function_ref @returnLabeledTuple : $@convention(thin) () -> (first: Int32, second: Int32) %6 = convert_function %3 : $@convention(thin) () -> (first: Int32, second: Int32) to $@convention(thin) () -> ((Int32, Int32), @error ErrorType) try_apply %6() : $@convention(thin) () -> ((Int32, Int32), @error ErrorType), normal bb1, error bb2 @@ -2283,17 +2283,17 @@ bb2(%10 : $ErrorType): } // Check that we don't crash on this. -// The compiler should be able to cast between the labled and unlabled return tuple types. -// CHECK-LABEL: @try_apply_with_convert_function_returning_casted_labled_tuple +// The compiler should be able to cast between the labeled and unlabeled return tuple types. +// CHECK-LABEL: @try_apply_with_convert_function_returning_casted_labeled_tuple // CHECK: apply {{%[0-9]+}} // Proper tuple is created by deconstructing the old one and creating a new one using its elements. // CHECK: tuple_extract // CHECK: tuple_extract // CHECK: tuple // CHECK: return -sil @try_apply_with_convert_function_returning_casted_labled_tuple: $@convention(thin) () -> (first: Int32, second: Int32) { +sil @try_apply_with_convert_function_returning_casted_labeled_tuple: $@convention(thin) () -> (first: Int32, second: Int32) { bb0: - %3 = function_ref @returnUnlabledTuple : $@convention(thin) () -> (Int32, Int32) + %3 = function_ref @returnUnlabeledTuple : $@convention(thin) () -> (Int32, Int32) %6 = convert_function %3 : $@convention(thin) () -> (Int32, Int32) to $@convention(thin) () -> ((first: Int32, second: Int32), @error ErrorType) try_apply %6() : $@convention(thin) () -> ((first: Int32, second: Int32), @error ErrorType), normal bb1, error bb2 @@ -2307,8 +2307,8 @@ bb2(%10 : $ErrorType): unreachable } -sil [noinline] @returnLabledTuple: $@convention(thin) () -> (first: Int32, second: Int32) -sil [noinline] @returnUnlabledTuple : $@convention(thin) () -> (Int32, Int32) +sil [noinline] @returnLabeledTuple: $@convention(thin) () -> (first: Int32, second: Int32) +sil [noinline] @returnUnlabeledTuple : $@convention(thin) () -> (Int32, Int32) public class AAA { } @@ -2316,13 +2316,13 @@ public class AAA { public class BBB : AAA { } -@inline(never) func returnUnlabledTuple(b: BBB) -> (BBB, BBB) +@inline(never) func returnUnlabeledTuple(b: BBB) -> (BBB, BBB) func testit(f: (BBB) throws -> (AAA, AAA), _ b: BBB) throws -> (AAA, AAA) func callit(b: BBB) throws -> (AAA, AAA) -sil [noinline] @returnUnlabledTupleOfClasses : $@convention(thin) (@owned BBB) -> @owned (BBB, BBB) { +sil [noinline] @returnUnlabeledTupleOfClasses : $@convention(thin) (@owned BBB) -> @owned (BBB, BBB) { bb0(%0 : $BBB): debug_value %0 : $BBB strong_retain %0 : $BBB @@ -2365,7 +2365,7 @@ bb0(%0 : $BBB): %2 = function_ref @testFunctorReturningUnlabeledTuple : $@convention(thin) (@owned @callee_owned (@owned BBB) -> (@owned (AAA, AAA), @error ErrorType), @owned BBB) -> (@owned (AAA, AAA), @error ErrorType) - %3 = function_ref @returnUnlabledTupleOfClasses : $@convention(thin) (@owned BBB) -> @owned (BBB, BBB) + %3 = function_ref @returnUnlabeledTupleOfClasses : $@convention(thin) (@owned BBB) -> @owned (BBB, BBB) %4 = thin_to_thick_function %3 : $@convention(thin) (@owned BBB) -> @owned (BBB, BBB) to $@callee_owned (@owned BBB) -> @owned (BBB, BBB) %5 = convert_function %4 : $@callee_owned (@owned BBB) -> @owned (BBB, BBB) to $@callee_owned (@owned BBB) -> (@owned (AAA, AAA), @error ErrorType) strong_retain %0 : $BBB @@ -2414,15 +2414,39 @@ bb0(%0 : $CAB): %6 = function_ref @thunk_helper : $@convention(thin) <τ_0_0> (@out UP<()>, UBP<τ_0_0>, @owned @callee_owned (UBP<τ_0_0>) -> (UP<()>, @error ErrorType)) -> @error ErrorType %7 = partial_apply %6(%5) : $@convention(thin) <τ_0_0> (@out UP<()>, UBP<τ_0_0>, @owned @callee_owned (UBP<τ_0_0>) -> (UP<()>, @error ErrorType)) -> @error ErrorType %8 = alloc_stack $UP<()> - %9 = unchecked_addr_cast %8#1 : $*UP<()> to $*UP<()> + %9 = unchecked_addr_cast %8 : $*UP<()> to $*UP<()> %10 = convert_function %7 : $@callee_owned (@out UP<()>, UBP) -> @error ErrorType to $@callee_owned (@out UP<()>, UBP) -> @error ErrorType - try_apply %2>(%8#1, %7, %0) : $@convention(method) <τ_0_0><τ_1_0> (@out τ_1_0, @owned @callee_owned (@out τ_1_0, UBP<τ_0_0>) -> @error ErrorType, @guaranteed CAB<τ_0_0>) -> @error ErrorType, normal bb1, error bb2 + try_apply %2>(%8, %7, %0) : $@convention(method) <τ_0_0><τ_1_0> (@out τ_1_0, @owned @callee_owned (@out τ_1_0, UBP<τ_0_0>) -> @error ErrorType, @guaranteed CAB<τ_0_0>) -> @error ErrorType, normal bb1, error bb2 bb1(%12 : $()): - %13 = load %8#1 : $*UP<()> - dealloc_stack %8#0 : $*@local_storage UP<()> + %13 = load %8 : $*UP<()> + dealloc_stack %8 : $*UP<()> return %13 : $UP<()> bb2(%16 : $ErrorType): unreachable } + + +// Check that we don't crash on this. + +// CHECK-LABEL: @simplified_branch_arg_has_result_value_1 +// CHECK: [[B:%[0-9]+]] = alloc_box +// CHECK: br bb1([[B]]#1 : $*Builtin.Int32) +sil @simplified_branch_arg_has_result_value_1 : $@convention(thin) (@in Builtin.Int32) -> Builtin.Int32 { +entry(%0 : $*Builtin.Int32): + %b = alloc_box $Builtin.Int32 + %i = integer_literal $Builtin.Int32, 0 + store %i to %b#1 : $*Builtin.Int32 + %p = project_box %b#0 : $@box Builtin.Int32 + br bb1(%p : $*Builtin.Int32) + +bb1(%a : $*Builtin.Int32): + %r = load %a : $*Builtin.Int32 + cond_br undef, bb1(%0 : $*Builtin.Int32), bb2 + +bb2: + return %r : $Builtin.Int32 +} + + diff --git a/test/SILPasses/simplify_cfg_and_combine.sil b/test/SILOptimizer/simplify_cfg_and_combine.sil similarity index 92% rename from test/SILPasses/simplify_cfg_and_combine.sil rename to test/SILOptimizer/simplify_cfg_and_combine.sil index 7e67636283f08..25a95eaed9d2d 100644 --- a/test/SILPasses/simplify_cfg_and_combine.sil +++ b/test/SILOptimizer/simplify_cfg_and_combine.sil @@ -7,10 +7,10 @@ sil_stage canonical import Builtin import Swift -sil @external_f1 : $@convention(thin) ()->() -sil @external_f2 : $@convention(thin) ()->() -sil @external_f3 : $@convention(thin) ()->() -sil @external_f4 : $@convention(thin) ()->() +sil @external_f1 : $@convention(thin) () -> () +sil @external_f2 : $@convention(thin) () -> () +sil @external_f3 : $@convention(thin) () -> () +sil @external_f4 : $@convention(thin) () -> () // CHECK-LABEL: sil @select_enum_dominance_simplification : $@convention(thin) (Optional) -> () { // CHECK-NOT: external_f2 @@ -34,23 +34,23 @@ bb2: cond_br %3, bb5, bb6 bb3: - %f1 = function_ref @external_f1 : $@convention(thin) ()->() - apply %f1() : $@convention(thin) ()->() + %f1 = function_ref @external_f1 : $@convention(thin) () -> () + apply %f1() : $@convention(thin) () -> () br bb7 bb4: - %f2 = function_ref @external_f2 : $@convention(thin) ()->() - apply %f2() : $@convention(thin) ()->() + %f2 = function_ref @external_f2 : $@convention(thin) () -> () + apply %f2() : $@convention(thin) () -> () br bb7 bb5: - %f3 = function_ref @external_f3 : $@convention(thin) ()->() - apply %f3() : $@convention(thin) ()->() + %f3 = function_ref @external_f3 : $@convention(thin) () -> () + apply %f3() : $@convention(thin) () -> () br bb7 bb6: - %f4 = function_ref @external_f4 : $@convention(thin) ()->() - apply %f4() : $@convention(thin) ()->() + %f4 = function_ref @external_f4 : $@convention(thin) () -> () + apply %f4() : $@convention(thin) () -> () br bb7 bb7: @@ -74,18 +74,18 @@ bb1: cond_br %c, bb2, bb3 bb2: - %f1 = function_ref @external_f1 : $@convention(thin) ()->() - apply %f1() : $@convention(thin) ()->() + %f1 = function_ref @external_f1 : $@convention(thin) () -> () + apply %f1() : $@convention(thin) () -> () br bb5 bb3: - %f2 = function_ref @external_f2 : $@convention(thin) ()->() - apply %f2() : $@convention(thin) ()->() + %f2 = function_ref @external_f2 : $@convention(thin) () -> () + apply %f2() : $@convention(thin) () -> () br bb5 bb4: - %f3 = function_ref @external_f3 : $@convention(thin) ()->() - apply %f3() : $@convention(thin) ()->() + %f3 = function_ref @external_f3 : $@convention(thin) () -> () + apply %f3() : $@convention(thin) () -> () br bb5 bb5: diff --git a/test/SILPasses/simplify_cfg_args.sil b/test/SILOptimizer/simplify_cfg_args.sil similarity index 98% rename from test/SILPasses/simplify_cfg_args.sil rename to test/SILOptimizer/simplify_cfg_args.sil index 25726c7b931e4..0b14ba4567aa5 100644 --- a/test/SILPasses/simplify_cfg_args.sil +++ b/test/SILOptimizer/simplify_cfg_args.sil @@ -25,7 +25,7 @@ bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.NativeObject, %2 : $Builtin.Int32): %12 = function_ref @globalinit_func11 : $@convention(thin) () -> () // users: %26, %13 %14 = builtin "once"(%11 : $Builtin.RawPointer, %12 : $@convention(thin) () -> ()) : $() %15 = alloc_stack $Int32 // users: %38, %40, %41 - %16 = struct_element_addr %15#1 : $*Int32, #Int32._value // users: %28, %17 + %16 = struct_element_addr %15 : $*Int32, #Int32._value // users: %28, %17 %17 = load %16 : $*Builtin.Int32 // user: %20 %18 = integer_literal $Builtin.Int32, -1 // user: %20 %20 = builtin "xor_Int32"(%17 : $Builtin.Int32, %18 : $Builtin.Int32) : $Builtin.Int32 // user: %22 @@ -53,7 +53,7 @@ bb3(%35 : $()): // Preds: bb2 strong_retain %1 : $Builtin.NativeObject // id: %38 strong_release %1 : $Builtin.NativeObject // id: %39 strong_release %1 : $Builtin.NativeObject // id: %40 - dealloc_stack %15#0 : $*@local_storage Int32 // id: %41 + dealloc_stack %15 : $*Int32 // id: %41 // CHECK: return return %0 : $Builtin.RawPointer } @@ -366,7 +366,7 @@ bb4(%20 : $Builtin.Int1): // Preds: bb1 bb2 bb3 sil @external_f : $@convention(thin) () -> () // Check that switch_enum to select_enum conversion does not -// take place in a peresence of side-effects. +// take place in a presence of side-effects. // CHECK-LABEL: simplify_switch_to_select_enum_with_side_effects sil @simplify_switch_to_select_enum_with_side_effects : $@convention(thin) (X) -> Int32 { bb0(%0 : $X): @@ -465,7 +465,7 @@ public enum Numbers { // CHECK_WITH_CODEMOTION: return sil @FormSelectEnumFromTwoSelectSwitches : $@convention(thin) (Numbers) -> Int32 { bb0(%0 : $Numbers): - debug_value %0 : $Numbers // let e // id: %1 + debug_value %0 : $Numbers, let, name "e" // id: %1 switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb1, case #Numbers.Second!enumelt: bb3, case #Numbers.Third!enumelt: bb4, default bb6 // id: %2 bb1: // Preds: bb0 @@ -542,7 +542,7 @@ bb20(%34 : $Builtin.Int32): // Preds: bb2 bb5 bb11 bb14 bb // CHECK_WITH_CODEMOTION: return sil @FormSelectEnumIntResult : $@convention(thin) (Numbers) -> Int32 { bb0(%0 : $Numbers): - debug_value %0 : $Numbers // let e // id: %1 + debug_value %0 : $Numbers, let, name "e" // id: %1 switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb1, case #Numbers.Second!enumelt: bb3, case #Numbers.Third!enumelt: bb4, case #Numbers.Fourth!enumelt: bb6, default bb8 // id: %2 bb1: // Preds: bb0 @@ -590,7 +590,7 @@ bb11(%21 : $Builtin.Int32): // Preds: bb2 bb5 bb7 bb10 // CHECK_WITH_CODEMOTION: return sil @FormSelectEnumBoolResult : $@convention(thin) (Numbers) -> Bool { bb0(%0 : $Numbers): - debug_value %0 : $Numbers // let e // id: %1 + debug_value %0 : $Numbers, let, name "e" // id: %1 switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb1, case #Numbers.Second!enumelt: bb3, case #Numbers.Third!enumelt: bb4, default bb6 // id: %2 bb1: // Preds: bb0 @@ -631,7 +631,7 @@ bb9(%17 : $Builtin.Int1): // Preds: bb2 bb5 bb8 // CHECK_WITH_CODEMOTION: return sil @DontFormSelectEnumBoolResult : $@convention(thin) (Numbers, Bool) -> Bool { bb0(%0 : $Numbers, %1 : $Bool): - debug_value %0 : $Numbers // let e // id: %2 + debug_value %0 : $Numbers, let, name "e" // id: %2 %2 = struct_extract %1 : $Bool, #Bool._value switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb1, case #Numbers.Second!enumelt: bb3, case #Numbers.Third!enumelt: bb4, default bb6 // id: %4 diff --git a/test/SILPasses/simplify_cfg_args_crash.sil b/test/SILOptimizer/simplify_cfg_args_crash.sil similarity index 100% rename from test/SILPasses/simplify_cfg_args_crash.sil rename to test/SILOptimizer/simplify_cfg_args_crash.sil diff --git a/test/SILPasses/simplify_cfg_jump_thread_crash.sil b/test/SILOptimizer/simplify_cfg_jump_thread_crash.sil similarity index 100% rename from test/SILPasses/simplify_cfg_jump_thread_crash.sil rename to test/SILOptimizer/simplify_cfg_jump_thread_crash.sil diff --git a/test/SILPasses/simplify_cfg_select_enum.sil b/test/SILOptimizer/simplify_cfg_select_enum.sil similarity index 99% rename from test/SILPasses/simplify_cfg_select_enum.sil rename to test/SILOptimizer/simplify_cfg_select_enum.sil index 30bed10fbaded..68613334966ef 100644 --- a/test/SILPasses/simplify_cfg_select_enum.sil +++ b/test/SILOptimizer/simplify_cfg_select_enum.sil @@ -2,7 +2,7 @@ // Two select_enum instructions must not be considered as the same "condition", // even if they have the same enum operand. -// This test checks that SimplifyCFG does not remove a dominated terminater with +// This test checks that SimplifyCFG does not remove a dominated terminator with // such a condition. sil_stage canonical diff --git a/test/SILPasses/sink.sil b/test/SILOptimizer/sink.sil similarity index 100% rename from test/SILPasses/sink.sil rename to test/SILOptimizer/sink.sil diff --git a/test/SILPasses/spec_archetype_method.swift b/test/SILOptimizer/spec_archetype_method.swift similarity index 100% rename from test/SILPasses/spec_archetype_method.swift rename to test/SILOptimizer/spec_archetype_method.swift diff --git a/test/SILPasses/spec_conf1.swift b/test/SILOptimizer/spec_conf1.swift similarity index 97% rename from test/SILPasses/spec_conf1.swift rename to test/SILOptimizer/spec_conf1.swift index 87a5fd7825aec..97115bafe2c2f 100644 --- a/test/SILPasses/spec_conf1.swift +++ b/test/SILOptimizer/spec_conf1.swift @@ -21,7 +21,6 @@ func outer_function(In In : T) { inner_function(In: In) } //CHECK: sil shared [noinline] @_TTSg5C10spec_conf13FooS0_S_1PS____TF10spec_conf114outer_function //CHECK: _TTSg5C10spec_conf13FooS0_S_1PS____TF10spec_conf114inner_function -//CHECK-NEXT: retain //CHECK-NEXT: apply //CHECK: return diff --git a/test/SILPasses/spec_conf2.swift b/test/SILOptimizer/spec_conf2.swift similarity index 97% rename from test/SILPasses/spec_conf2.swift rename to test/SILOptimizer/spec_conf2.swift index c28f041455a87..61d3233ee6244 100644 --- a/test/SILPasses/spec_conf2.swift +++ b/test/SILOptimizer/spec_conf2.swift @@ -20,7 +20,6 @@ func outer_function >(In In : T) { inner_function(In: In) } //CHECK: sil shared [noinline] @_TTSg5C10spec_conf23FooS0_S_1PS_S0_S_1QS____TF10spec_conf214outer_function //CHECK: function_ref @_TTSg5C10spec_conf23FooS0_S_1PS_S0_S_1QS____TF10spec_conf214inner_function -//CHECK-NEXT: retain //CHECK-NEXT: apply //CHECK: return diff --git a/test/SILPasses/spec_recursion.swift b/test/SILOptimizer/spec_recursion.swift similarity index 100% rename from test/SILPasses/spec_recursion.swift rename to test/SILOptimizer/spec_recursion.swift diff --git a/test/SILPasses/specialization_of_stdlib_binary_only.swift b/test/SILOptimizer/specialization_of_stdlib_binary_only.swift similarity index 100% rename from test/SILPasses/specialization_of_stdlib_binary_only.swift rename to test/SILOptimizer/specialization_of_stdlib_binary_only.swift diff --git a/test/SILPasses/specialize.sil b/test/SILOptimizer/specialize.sil similarity index 79% rename from test/SILPasses/specialize.sil rename to test/SILOptimizer/specialize.sil index f267aaaeacb03..d2ace92a4718f 100644 --- a/test/SILPasses/specialize.sil +++ b/test/SILOptimizer/specialize.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -inline %s | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all -generic-specializer %s | FileCheck %s sil_stage canonical @@ -32,29 +32,29 @@ bb0: // specialize.XXX.init (specialize.XXX.Type)(t : A) -> specialize.XXX sil [noinline] @_TFV10specialize3XXXCU__fMGS0_Q__FT1tQ__GS0_Q__ : $@convention(thin) (@out XXX, @in T, @thin XXX.Type) -> () { bb0(%0 : $*XXX, %1 : $*T, %2 : $@thin XXX.Type): - %3 = alloc_stack $XXX // var self // users: %7, %11, %13 - debug_value_addr %1 : $*T // let t // id: %4 + %3 = alloc_stack $XXX, var, name "sf" // users: %7, %11, %13 + debug_value_addr %1 : $*T, let, name "t" // id: %4 %5 = alloc_stack $T // users: %6, %8, %9 - copy_addr %1 to [initialization] %5#1 : $*T // id: %6 - %7 = struct_element_addr %3#1 : $*XXX, #XXX.m_t // user: %8 - copy_addr [take] %5#1 to [initialization] %7 : $*T // id: %8 - dealloc_stack %5#0 : $*@local_storage T // id: %9 + copy_addr %1 to [initialization] %5 : $*T // id: %6 + %7 = struct_element_addr %3 : $*XXX, #XXX.m_t // user: %8 + copy_addr [take] %5 to [initialization] %7 : $*T // id: %8 + dealloc_stack %5 : $*T // id: %9 destroy_addr %1 : $*T // id: %10 - copy_addr [take] %3#1 to [initialization] %0 : $*XXX // id: %11 + copy_addr [take] %3 to [initialization] %0 : $*XXX // id: %11 %12 = tuple () // user: %14 - dealloc_stack %3#0 : $*@local_storage XXX // id: %13 + dealloc_stack %3 : $*XXX // id: %13 return %12 : $() // id: %14 } // specialize.XXX.foo (@inout specialize.XXX)(t : A) -> Swift.Int32 sil [noinline] @_TFV10specialize3XXX3fooU__fRGS0_Q__FT1tQ__Si : $@convention(method) (@in T, @inout XXX) -> Int32 { bb0(%0 : $*T, %1 : $*XXX): - debug_value_addr %0 : $*T // let t // id: %2 + debug_value_addr %0 : $*T, let, name "t" // id: %2 %3 = alloc_stack $T // users: %4, %6, %7 - copy_addr %0 to [initialization] %3#1 : $*T // id: %4 + copy_addr %0 to [initialization] %3 : $*T // id: %4 %5 = struct_element_addr %1 : $*XXX, #XXX.m_t // user: %6 - copy_addr [take] %3#1 to %5 : $*T // id: %6 - dealloc_stack %3#0 : $*@local_storage T // id: %7 + copy_addr [take] %3 to %5 : $*T // id: %6 + dealloc_stack %3 : $*T // id: %7 %8 = integer_literal $Builtin.Int32, 4 // user: %9 %9 = struct $Int32 (%8 : $Builtin.Int32) // user: %11 destroy_addr %0 : $*T // id: %10 @@ -73,7 +73,7 @@ bb0(%0 : $Builtin.Int2048, %1 : $@thin Int32.Type): // specialize.acceptsInt (Swift.Int32) -> () sil [noinline] @_TF10specialize10acceptsIntFSiT_ : $@convention(thin) (Int32) -> () { bb0(%0 : $Int32): - debug_value %0 : $Int32 // let x // id: %1 + debug_value %0 : $Int32, let, name "x" // id: %1 %2 = tuple () // user: %3 return %2 : $() // id: %3 } @@ -81,16 +81,16 @@ bb0(%0 : $Int32): // specialize.exp1 () -> () sil @_TF10specialize4exp1FT_T_ : $@convention(thin) () -> () { bb0: - %0 = alloc_stack $XXX // var II // users: %7, %15, %19 + %0 = alloc_stack $XXX, var, name "II" // users: %7, %15, %19 // function_ref specialize.XXX.init (specialize.XXX.Type)(t : A) -> specialize.XXX %1 = function_ref @_TFV10specialize3XXXCU__fMGS0_Q__FT1tQ__GS0_Q__ : $@convention(thin) <τ_0_0> (@out XXX<τ_0_0>, @in τ_0_0, @thin XXX<τ_0_0>.Type) -> () // user: %7 %2 = metatype $@thin XXX.Type // user: %7 %3 = alloc_stack $Int32 // users: %6, %7, %8 %4 = integer_literal $Builtin.Int32, 5 // user: %5 %5 = struct $Int32 (%4 : $Builtin.Int32) // user: %6 - store %5 to %3#1 : $*Int32 // id: %6 - %7 = apply %1(%0#1, %3#1, %2) : $@convention(thin) <τ_0_0> (@out XXX<τ_0_0>, @in τ_0_0, @thin XXX<τ_0_0>.Type) -> () - dealloc_stack %3#0 : $*@local_storage Int32 // id: %8 + store %5 to %3 : $*Int32 // id: %6 + %7 = apply %1(%0, %3, %2) : $@convention(thin) <τ_0_0> (@out XXX<τ_0_0>, @in τ_0_0, @thin XXX<τ_0_0>.Type) -> () + dealloc_stack %3 : $*Int32 // id: %8 // function_ref specialize.acceptsInt (Swift.Int32) -> () %9 = function_ref @_TF10specialize10acceptsIntFSiT_ : $@convention(thin) (Int32) -> () // user: %16 // function_ref specialize.XXX.foo (@inout specialize.XXX)(t : A) -> Swift.Int32 @@ -98,28 +98,28 @@ bb0: %11 = alloc_stack $Int32 // users: %14, %15, %17 %12 = integer_literal $Builtin.Int32, 4 // user: %13 %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14 - store %13 to %11#1 : $*Int32 // id: %14 - %15 = apply %10(%11#1, %0#1) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 + store %13 to %11 : $*Int32 // id: %14 + %15 = apply %10(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 %16 = apply %9(%15) : $@convention(thin) (Int32) -> () - dealloc_stack %11#0 : $*@local_storage Int32 // id: %17 + dealloc_stack %11 : $*Int32 // id: %17 %18 = tuple () // user: %20 - dealloc_stack %0#0 : $*@local_storage XXX // id: %19 + dealloc_stack %0 : $*XXX // id: %19 return %18 : $() // id: %20 } // specialize.exp2 () -> () sil @_TF10specialize4exp2FT_T_ : $@convention(thin) () -> () { bb0: - %0 = alloc_stack $XXX // var II8 // users: %7, %15, %19 + %0 = alloc_stack $XXX, var, name "I8" // users: %7, %15, %19 // function_ref specialize.XXX.init (specialize.XXX.Type)(t : A) -> specialize.XXX %1 = function_ref @_TFV10specialize3XXXCU__fMGS0_Q__FT1tQ__GS0_Q__ : $@convention(thin) <τ_0_0> (@out XXX<τ_0_0>, @in τ_0_0, @thin XXX<τ_0_0>.Type) -> () // user: %7 %2 = metatype $@thin XXX.Type // user: %7 %3 = alloc_stack $UInt8 // users: %6, %7, %8 %4 = integer_literal $Builtin.Int8, 5 // user: %5 %5 = struct $UInt8 (%4 : $Builtin.Int8) // user: %6 - store %5 to %3#1 : $*UInt8 // id: %6 - %7 = apply %1(%0#1, %3#1, %2) : $@convention(thin) <τ_0_0> (@out XXX<τ_0_0>, @in τ_0_0, @thin XXX<τ_0_0>.Type) -> () - dealloc_stack %3#0 : $*@local_storage UInt8 // id: %8 + store %5 to %3 : $*UInt8 // id: %6 + %7 = apply %1(%0, %3, %2) : $@convention(thin) <τ_0_0> (@out XXX<τ_0_0>, @in τ_0_0, @thin XXX<τ_0_0>.Type) -> () + dealloc_stack %3 : $*UInt8 // id: %8 // function_ref specialize.acceptsInt (Swift.Int32) -> () %9 = function_ref @_TF10specialize10acceptsIntFSiT_ : $@convention(thin) (Int32) -> () // user: %16 // function_ref specialize.XXX.foo (@inout specialize.XXX)(t : A) -> Swift.Int32 @@ -127,12 +127,12 @@ bb0: %11 = alloc_stack $UInt8 // users: %14, %15, %17 %12 = integer_literal $Builtin.Int8, 4 // user: %13 %13 = struct $UInt8 (%12 : $Builtin.Int8) // user: %14 - store %13 to %11#1 : $*UInt8 // id: %14 - %15 = apply %10(%11#1, %0#1) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 + store %13 to %11 : $*UInt8 // id: %14 + %15 = apply %10(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 %16 = apply %9(%15) : $@convention(thin) (Int32) -> () - dealloc_stack %11#0 : $*@local_storage UInt8 // id: %17 + dealloc_stack %11 : $*UInt8 // id: %17 %18 = tuple () // user: %20 - dealloc_stack %0#0 : $*@local_storage XXX // id: %19 + dealloc_stack %0 : $*XXX // id: %19 return %18 : $() // id: %20 } @@ -152,7 +152,7 @@ bb0(%0 : $Int32, %1 : $@thin UInt8.Type): // specialize.useClosure (fun : () -> A) -> A sil @_TF10specialize10useClosureU__FT3funFT_Q__Q_ : $@convention(thin) (@out T, @owned @callee_owned (@out T) -> ()) -> () { bb0(%0 : $*T, %1 : $@callee_owned (@out T) -> ()): - debug_value %1 : $@callee_owned (@out T) -> () // let fun // id: %2 + debug_value %1 : $@callee_owned (@out T) -> (), let, name "fun" // id: %2 strong_retain %1 : $@callee_owned (@out T) -> () // id: %3 %4 = apply %1(%0) : $@callee_owned (@out T) -> () strong_release %1 : $@callee_owned (@out T) -> () // id: %5 @@ -163,19 +163,20 @@ bb0(%0 : $*T, %1 : $@callee_owned (@out T) -> ()): // specialize.getGenericClosure (t : A) -> () -> A sil @_TF10specialize17getGenericClosureU__FT1tQ__FT_Q_ : $@convention(thin) (@in T) -> @owned @callee_owned (@out T) -> () { bb0(%0 : $*T): - debug_value_addr %0 : $*T // let t // id: %1 + debug_value_addr %0 : $*T, let, name "t" // id: %1 // function_ref specialize.(getGenericClosure (t : A) -> () -> A).(tmp #1) (())A - %2 = function_ref @_TFF10specialize17getGenericClosureU__FT1tQ__FT_Q_L_3tmpfT_Q_ : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0, @inout τ_0_0) -> () // user: %5 + %2 = function_ref @_TFF10specialize17getGenericClosureU__FT1tQ__FT_Q_L_3tmpfT_Q_ : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0) -> () // user: %5 %3 = alloc_box $T // users: %4, %5, %5 copy_addr %0 to [initialization] %3#1 : $*T // id: %4 - %5 = partial_apply %2(%3#0, %3#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0, @inout τ_0_0) -> () // user: %7 + %5 = partial_apply %2(%3#0) : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @box τ_0_0) -> () // user: %7 destroy_addr %0 : $*T // id: %6 return %5 : $@callee_owned (@out T) -> () // id: %7 } // specialize.(getGenericClosure (t : A) -> () -> A).(tmp #1) (()) -sil shared @_TFF10specialize17getGenericClosureU__FT1tQ__FT_Q_L_3tmpfT_Q_ : $@convention(thin) (@out T, @owned @box T, @inout T) -> () { -bb0(%0 : $*T, %1 : $@box T, %2 : $*T): +sil shared @_TFF10specialize17getGenericClosureU__FT1tQ__FT_Q_L_3tmpfT_Q_ : $@convention(thin) (@out T, @owned @box T) -> () { +bb0(%0 : $*T, %1 : $@box T): + %2 = project_box %1 : $@box T copy_addr %2 to [initialization] %0 : $*T // id: %3 strong_release %1 : $@box T // id: %4 %5 = tuple () // user: %6 @@ -185,17 +186,17 @@ bb0(%0 : $*T, %1 : $@box T, %2 : $*T): // specialize.specializePartialApplies () -> Swift.UInt8 sil @_TF10specialize24specializePartialAppliesFT_Vs5UInt8 : $@convention(thin) () -> UInt8 { bb0: - %0 = alloc_stack $UInt8 // var i // users: %3, %18 + %0 = alloc_stack $UInt8, var, name "i" // users: %3, %18 %1 = integer_literal $Builtin.Int8, 5 // user: %2 %2 = struct $UInt8 (%1 : $Builtin.Int8) // users: %3, %7 - store %2 to %0#1 : $*UInt8 // id: %3 + store %2 to %0 : $*UInt8 // id: %3 // function_ref specialize.useClosure (fun : () -> A) -> A %4 = function_ref @_TF10specialize10useClosureU__FT3funFT_Q__Q_ : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @callee_owned (@out τ_0_0) -> ()) -> () // user: %14 // function_ref specialize.getGenericClosure (t : A) -> () -> A %5 = function_ref @_TF10specialize17getGenericClosureU__FT1tQ__FT_Q_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned (@out τ_0_0) -> () // user: %8 %6 = alloc_stack $UInt8 // users: %7, %8, %17 - store %2 to %6#1 : $*UInt8 // id: %7 - %8 = apply %5(%6#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned (@out τ_0_0) -> () // user: %10 + store %2 to %6 : $*UInt8 // id: %7 + %8 = apply %5(%6) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned (@out τ_0_0) -> () // user: %10 // function_ref reabstraction thunk helper from @callee_owned () -> (@out Swift.UInt8) to @callee_owned () -> (@unowned Swift.UInt8) %9 = function_ref @_TTRXFo__iVs5UInt8_XFo__dS__ : $@convention(thin) (@owned @callee_owned (@out UInt8) -> ()) -> UInt8 // user: %10 %10 = partial_apply %9(%8) : $@convention(thin) (@owned @callee_owned (@out UInt8) -> ()) -> UInt8 // user: %12 @@ -203,11 +204,11 @@ bb0: %11 = function_ref @_TTRXFo__dVs5UInt8_XFo__iS__ : $@convention(thin) (@out UInt8, @owned @callee_owned () -> UInt8) -> () // user: %12 %12 = partial_apply %11(%10) : $@convention(thin) (@out UInt8, @owned @callee_owned () -> UInt8) -> () // user: %14 %13 = alloc_stack $UInt8 // users: %14, %15, %16 - %14 = apply %4(%13#1, %12) : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @callee_owned (@out τ_0_0) -> ()) -> () - %15 = load %13#1 : $*UInt8 // user: %19 - dealloc_stack %13#0 : $*@local_storage UInt8 // id: %16 - dealloc_stack %6#0 : $*@local_storage UInt8 // id: %17 - dealloc_stack %0#0 : $*@local_storage UInt8 // id: %18 + %14 = apply %4(%13, %12) : $@convention(thin) <τ_0_0> (@out τ_0_0, @owned @callee_owned (@out τ_0_0) -> ()) -> () + %15 = load %13 : $*UInt8 // user: %19 + dealloc_stack %13 : $*UInt8 // id: %16 + dealloc_stack %6 : $*UInt8 // id: %17 + dealloc_stack %0 : $*UInt8 // id: %18 return %15 : $UInt8 // id: %19 } @@ -215,9 +216,9 @@ bb0: sil shared [transparent] @_TTRXFo__iVs5UInt8_XFo__dS__ : $@convention(thin) (@owned @callee_owned (@out UInt8) -> ()) -> UInt8 { bb0(%0 : $@callee_owned (@out UInt8) -> ()): %1 = alloc_stack $UInt8 // users: %2, %3, %4 - %2 = apply %0(%1#1) : $@callee_owned (@out UInt8) -> () - %3 = load %1#1 : $*UInt8 // user: %5 - dealloc_stack %1#0 : $*@local_storage UInt8 // id: %4 + %2 = apply %0(%1) : $@callee_owned (@out UInt8) -> () + %3 = load %1 : $*UInt8 // user: %5 + dealloc_stack %1 : $*UInt8 // id: %4 return %3 : $UInt8 // id: %5 } @@ -263,7 +264,7 @@ struct C : P { func get() -> Int32 } // test4.C.get (test4.C)() -> Swift.Int32 sil hidden @_TFV5test41C3getfS0_FT_Vs5Int32 : $@convention(method) (C) -> Int32 { bb0(%0 : $C): - debug_value %0 : $C // let self // id: %1 + debug_value %0 : $C, let, name "self" // id: %1 %2 = integer_literal $Builtin.Int32, 1 // user: %3 %3 = struct $Int32 (%2 : $Builtin.Int32) // user: %4 return %3 : $Int32 // id: %4 @@ -272,9 +273,9 @@ bb0(%0 : $C): // test4.C.init (test4.C.Type)() -> test4.C sil hidden [noinline] @_TFV5test41CCfMS0_FT_S0_ : $@convention(thin) (@thin C.Type) -> C { bb0(%0 : $@thin C.Type): - %1 = alloc_stack $C // var self // user: %3 + %1 = alloc_stack $C, var, name "sf" // user: %3 %2 = struct $C () // user: %4 - dealloc_stack %1#0 : $*@local_storage C // id: %3 + dealloc_stack %1 : $*C // id: %3 return %2 : $C // id: %4 } @@ -291,21 +292,22 @@ bb0(%0 : $*C): // test4.boo (A) -> (Swift.Int32, B) -> Swift.Int32 sil hidden [noinline] @_TF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_ : $@convention(thin) (@in U) -> @owned @callee_owned (Int32, @in T) -> Int32 { bb0(%0 : $*U): - debug_value_addr %0 : $*U // let y // id: %1 + debug_value_addr %0 : $*U, let, name "y" // id: %1 // function_ref test4.(boo (A) -> (Swift.Int32, B) -> Swift.Int32).(closure #1) - %2 = function_ref @_TFF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_U_FTS1_Q0__S1_ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned @box τ_0_0, @inout τ_0_0) -> Int32 // user: %5 + %2 = function_ref @_TFF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_U_FTS1_Q0__S1_ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned @box τ_0_0) -> Int32 // user: %5 %3 = alloc_box $U // users: %4, %5, %5 copy_addr %0 to [initialization] %3#1 : $*U // id: %4 - %5 = partial_apply %2(%3#0, %3#1) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned @box τ_0_0, @inout τ_0_0) -> Int32 // user: %7 + %5 = partial_apply %2(%3#0) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned @box τ_0_0) -> Int32 // user: %7 destroy_addr %0 : $*U // id: %6 return %5 : $@callee_owned (Int32, @in T) -> Int32 // id: %7 } // test4.(boo (A) -> (Swift.Int32, B) -> Swift.Int32).(closure #1) -sil shared [noinline] @_TFF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_U_FTS1_Q0__S1_ : $@convention(thin) (Int32, @in T, @owned @box U, @inout U) -> Int32 { -bb0(%0 : $Int32, %1 : $*T, %2 : $@box U, %3 : $*U): - debug_value %0 : $Int32 // let x // id: %4 - debug_value_addr %1 : $*T // let z // id: %5 +sil shared [noinline] @_TFF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_U_FTS1_Q0__S1_ : $@convention(thin) (Int32, @in T, @owned @box U) -> Int32 { +bb0(%0 : $Int32, %1 : $*T, %2 : $@box U): + %3 = project_box %2 : $@box U + debug_value %0 : $Int32, let, name "x" // id: %4 + debug_value_addr %1 : $*T, let, name "z" // id: %5 %6 = witness_method $U, #P.get!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %7 %7 = apply %6(%3) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %8 %8 = struct_extract %7 : $Int32, #Int32._value // user: %11 @@ -338,17 +340,17 @@ bb0(%0 : $Int32, %1 : $Int32): // test4.foo (A, B) -> (Swift.Int32, Swift.Float) -> Swift.Int32 sil hidden [noinline] @_TF5test43fooUS_1P_S0___FTQ_Q0__FTVs5Int32Sf_S1_ : $@convention(thin) (@in T, @in U) -> @owned @callee_owned (Int32, Float) -> Int32 { bb0(%0 : $*T, %1 : $*U): - debug_value_addr %0 : $*T // let x // id: %2 - debug_value_addr %1 : $*U // let y // id: %3 + debug_value_addr %0 : $*T, let, name "x" // id: %2 + debug_value_addr %1 : $*U, let, name "y" // id: %3 // function_ref test4.boo (A) -> (Swift.Int32, B) -> Swift.Int32 %4 = function_ref @_TF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %7 %5 = alloc_stack $U // users: %6, %7, %10 - copy_addr %1 to [initialization] %5#1 : $*U // id: %6 - %7 = apply %4(%5#1) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %9 + copy_addr %1 to [initialization] %5 : $*U // id: %6 + %7 = apply %4(%5) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %9 // function_ref reabstraction thunk helper from @callee_owned (@unowned Swift.Int32, @in Swift.Float) -> (@unowned Swift.Int32) to @callee_owned (@unowned Swift.Int32, @unowned Swift.Float) -> (@unowned Swift.Int32) %8 = function_ref @_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 // user: %9 %9 = partial_apply %8(%7) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 // user: %13 - dealloc_stack %5#0 : $*@local_storage U // id: %10 + dealloc_stack %5 : $*U // id: %10 destroy_addr %1 : $*U // id: %11 destroy_addr %0 : $*T // id: %12 return %9 : $@callee_owned (Int32, Float) -> Int32 // id: %13 @@ -358,29 +360,30 @@ bb0(%0 : $*T, %1 : $*U): sil shared [transparent] [thunk] @_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ : $@convention(thin) (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 { bb0(%0 : $Int32, %1 : $Float, %2 : $@callee_owned (Int32, @in Float) -> Int32): %3 = alloc_stack $Float // users: %4, %5, %6 - store %1 to %3#1 : $*Float // id: %4 - %5 = apply %2(%0, %3#1) : $@callee_owned (Int32, @in Float) -> Int32 // user: %7 - dealloc_stack %3#0 : $*@local_storage Float // id: %6 + store %1 to %3 : $*Float // id: %4 + %5 = apply %2(%0, %3) : $@callee_owned (Int32, @in Float) -> Int32 // user: %7 + dealloc_stack %3 : $*Float // id: %6 return %5 : $Int32 // id: %7 } // test4.gen1 (A) -> (Swift.Int32) -> Swift.Int32 sil hidden [noinline] @_TF5test44gen1US_1P__FQ_FVs5Int32S1_ : $@convention(thin) (@in T) -> @owned @callee_owned (Int32) -> Int32 { bb0(%0 : $*T): - debug_value_addr %0 : $*T // let x // id: %1 + debug_value_addr %0 : $*T, let, name "x" // id: %1 // function_ref test4.(gen1 (A) -> (Swift.Int32) -> Swift.Int32).(closure #1) - %2 = function_ref @_TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned @box τ_0_0, @inout τ_0_0) -> Int32 // user: %5 + %2 = function_ref @_TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned @box τ_0_0) -> Int32 // user: %5 %3 = alloc_box $T // users: %4, %5, %5 copy_addr %0 to [initialization] %3#1 : $*T // id: %4 - %5 = partial_apply %2(%3#0, %3#1) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned @box τ_0_0, @inout τ_0_0) -> Int32 // user: %7 + %5 = partial_apply %2(%3#0) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned @box τ_0_0) -> Int32 // user: %7 destroy_addr %0 : $*T // id: %6 return %5 : $@callee_owned (Int32) -> Int32 // id: %7 } // test4.(gen1 (A) -> (Swift.Int32) -> Swift.Int32).(closure #1) -sil shared [noinline] @_TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) (Int32, @owned @box T, @inout T) -> Int32 { -bb0(%0 : $Int32, %1 : $@box T, %2 : $*T): - debug_value %0 : $Int32 // let $0 // id: %3 +sil shared [noinline] @_TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) (Int32, @owned @box T) -> Int32 { +bb0(%0 : $Int32, %1 : $@box T): + %2 = project_box %1 : $@box T + debug_value %0 : $Int32 , let, name "$0" // id: %3 %4 = witness_method $T, #P.get!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %5 %5 = apply %4(%2) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %6 %6 = struct_extract %5 : $Int32, #Int32._value // user: %9 @@ -426,7 +429,7 @@ bb0(%0 : $Int32, %1 : $@box T, %2 : $*T): // CHECK: return // Check that there is a generic specialization of a closure from gen1 -// CHECK-LABEL: sil shared [noinline] @_TTSg5V4main1CS0_S_1PS____TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) (Int32, @owned @box C, @inout C) -> Int32 +// CHECK-LABEL: sil shared [noinline] @_TTSg5V4main1CS0_S_1PS____TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) (Int32, @owned @box C) -> Int32 // CHECK: return @@ -439,22 +442,22 @@ bb0(%0 : $Int32, %1 : $@box T, %2 : $*T): // CHECK: function_ref @_TTSg5V4main1CS0_S_1PS__S0_S0_S1_S____TF5test43fooUS_1P_S0___FTQ_Q0__FTVs5Int32Sf_S1_ sil hidden @_TF5test43barFT_Vs5Int32 : $@convention(thin) () -> Int32 { bb0: - %0 = alloc_stack $@callee_owned (Int32, Float) -> Int32 // var f // users: %11, %22 + %0 = alloc_stack $@callee_owned (Int32, Float) -> Int32, var, name "f" // users: %11, %22 // function_ref test4.C.init (test4.C.Type)() -> test4.C %1 = function_ref @_TFV5test41CCfMS0_FT_S0_ : $@convention(thin) (@thin C.Type) -> C // user: %3 %2 = metatype $@thin C.Type // user: %3 %3 = apply %1(%2) : $@convention(thin) (@thin C.Type) -> C // users: %4, %7, %9 - debug_value %3 : $C // let c // id: %4 + debug_value %3 : $C, let, name "c" // id: %4 // function_ref test4.foo (A, B) -> (Swift.Int32, Swift.Float) -> Swift.Int32 %5 = function_ref @_TF5test43fooUS_1P_S0___FTQ_Q0__FTVs5Int32Sf_S1_ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // user: %10 %6 = alloc_stack $C // users: %7, %10, %13 - store %3 to %6#1 : $*C // id: %7 + store %3 to %6 : $*C // id: %7 %8 = alloc_stack $C // users: %9, %10, %12 - store %3 to %8#1 : $*C // id: %9 - %10 = apply %5(%6#1, %8#1) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // users: %11, %14, %20, %21 - store %10 to %0#1 : $*@callee_owned (Int32, Float) -> Int32 // id: %11 - dealloc_stack %8#0 : $*@local_storage C // id: %12 - dealloc_stack %6#0 : $*@local_storage C // id: %13 + store %3 to %8 : $*C // id: %9 + %10 = apply %5(%6, %8) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // users: %11, %14, %20, %21 + store %10 to %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %11 + dealloc_stack %8 : $*C // id: %12 + dealloc_stack %6 : $*C // id: %13 strong_retain %10 : $@callee_owned (Int32, Float) -> Int32 // id: %14 %15 = integer_literal $Builtin.Int32, 3 // user: %16 %16 = struct $Int32 (%15 : $Builtin.Int32) // user: %20 @@ -463,7 +466,7 @@ bb0: %19 = struct $Float (%18 : $Builtin.FPIEEE32) // user: %20 %20 = apply %10(%16, %19) : $@callee_owned (Int32, Float) -> Int32 // user: %23 strong_release %10 : $@callee_owned (Int32, Float) -> Int32 // id: %21 - dealloc_stack %0#0 : $*@local_storage @callee_owned (Int32, Float) -> Int32 // id: %22 + dealloc_stack %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %22 return %20 : $Int32 // id: %23 } @@ -485,24 +488,24 @@ bb0: // CHECK: function_ref @_TTSg5V4main1CS0_S_1PS____TF5test44gen1US_1P__FQ_FVs5Int32S1_ : $@convention(thin) (@in C) -> @owned @callee_owned (Int32) -> Int32 sil @_TF5test48testGen1FT_Vs5Int32 : $@convention(thin) () -> Int32 { bb0: - %0 = alloc_stack $@callee_owned (Int32) -> Int32 // var f // users: %9, %16 + %0 = alloc_stack $@callee_owned (Int32) -> Int32, var, name "f" // users: %9, %16 // function_ref test4.C.init (test4.C.Type)() -> test4.C %1 = function_ref @_TFV5test41CCfMS0_FT_S0_ : $@convention(thin) (@thin C.Type) -> C // user: %3 %2 = metatype $@thin C.Type // user: %3 %3 = apply %1(%2) : $@convention(thin) (@thin C.Type) -> C // users: %4, %7 - debug_value %3 : $C // let c // id: %4 + debug_value %3 : $C, let, name "c" // id: %4 // function_ref test4.gen1 (A) -> (Swift.Int32) -> Swift.Int32 %5 = function_ref @_TF5test44gen1US_1P__FQ_FVs5Int32S1_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // user: %8 %6 = alloc_stack $C // users: %7, %8, %10 - store %3 to %6#1 : $*C // id: %7 - %8 = apply %5(%6#1) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // users: %9, %11, %14, %15 - store %8 to %0#1 : $*@callee_owned (Int32) -> Int32 // id: %9 - dealloc_stack %6#0 : $*@local_storage C // id: %10 + store %3 to %6 : $*C // id: %7 + %8 = apply %5(%6) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // users: %9, %11, %14, %15 + store %8 to %0 : $*@callee_owned (Int32) -> Int32 // id: %9 + dealloc_stack %6 : $*C // id: %10 strong_retain %8 : $@callee_owned (Int32) -> Int32 // id: %11 %12 = integer_literal $Builtin.Int32, 3 // user: %13 %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14 %14 = apply %8(%13) : $@callee_owned (Int32) -> Int32 // user: %17 strong_release %8 : $@callee_owned (Int32) -> Int32 // id: %15 - dealloc_stack %0#0 : $*@local_storage @callee_owned (Int32) -> Int32 // id: %16 + dealloc_stack %0 : $*@callee_owned (Int32) -> Int32 // id: %16 return %14 : $Int32 // id: %17 } diff --git a/test/SILPasses/specialize_anyobject.swift b/test/SILOptimizer/specialize_anyobject.swift similarity index 100% rename from test/SILPasses/specialize_anyobject.swift rename to test/SILOptimizer/specialize_anyobject.swift diff --git a/test/SILPasses/specialize_apply_conf.swift b/test/SILOptimizer/specialize_apply_conf.swift similarity index 97% rename from test/SILPasses/specialize_apply_conf.swift rename to test/SILOptimizer/specialize_apply_conf.swift index 0f816fbb317f3..d9bfe9e8d4acb 100644 --- a/test/SILPasses/specialize_apply_conf.swift +++ b/test/SILOptimizer/specialize_apply_conf.swift @@ -14,7 +14,7 @@ class Foo : Pingable { } func main_func(In In : T) { - var x = Foo() + let x = Foo() x.ping(x: In) } diff --git a/test/SILPasses/specialize_cg_update_crash.sil b/test/SILOptimizer/specialize_cg_update_crash.sil similarity index 84% rename from test/SILPasses/specialize_cg_update_crash.sil rename to test/SILOptimizer/specialize_cg_update_crash.sil index a76a88aa2fb26..ab3826456b245 100644 --- a/test/SILPasses/specialize_cg_update_crash.sil +++ b/test/SILOptimizer/specialize_cg_update_crash.sil @@ -23,10 +23,10 @@ bb0: %13 = function_ref @_TF7TestMod11genlibfunc2urFq_q_ : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () %14 = alloc_stack $MyStruct %16 = alloc_stack $MyStruct - %17 = apply %13(%16#1, %14#1) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () + %17 = apply %13(%16, %14) : $@convention(thin) <τ_0_0> (@out τ_0_0, @in τ_0_0) -> () %18 = struct $MyStruct () - dealloc_stack %16#0 : $*@local_storage MyStruct - dealloc_stack %14#0 : $*@local_storage MyStruct + dealloc_stack %16 : $*MyStruct + dealloc_stack %14 : $*MyStruct return %18 : $MyStruct } diff --git a/test/SILOptimizer/specialize_chain.swift b/test/SILOptimizer/specialize_chain.swift new file mode 100644 index 0000000000000..581a2c267ad72 --- /dev/null +++ b/test/SILOptimizer/specialize_chain.swift @@ -0,0 +1,50 @@ +// RUN: %target-swift-frontend -O -emit-sil -primary-file %s | FileCheck %s + +// We can't deserialize apply_inst with subst lists. When radar://14443304 +// is fixed then we should convert this test to a SIL test. + +struct YYY { + @inline(never) + init(t : T) {m_t = t} + @inline(never) mutating + func AAA9(t t : T) -> Int { return AAA8(t: t) } + @inline(never) mutating + func AAA8(t t : T) -> Int { return AAA7(t: t) } + @inline(never) mutating + func AAA7(t t : T) -> Int { return AAA6(t: t) } + @inline(never) mutating + func AAA6(t t : T) -> Int { return AAA5(t: t) } + @inline(never) mutating + func AAA5(t t : T) -> Int { return AAA4(t: t) } + @inline(never) mutating + func AAA4(t t : T) -> Int { return AAA3(t: t) } + @inline(never) mutating + func AAA3(t t : T) -> Int { return AAA2(t: t) } + @inline(never) mutating + func AAA2(t t : T) -> Int { return AAA1(t: t) } + @inline(never) mutating + func AAA1(t t : T) -> Int { return AAA0(t: t) } + @inline(never) mutating + func AAA0(t t : T) -> Int { return foo(t: t) } + @inline(never) mutating + func foo(t t : T) -> Int { m_t = t; return 4 } + var m_t : T +} + +func exp1() { + var II = YYY(t: 5) + print(II.AAA9(t: 4), terminator: "") +} +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA9 +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA8 +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA7 +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA6 +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA5 +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA4 +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA3 +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA2 +//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA1 +//CHECK: exp1 +//CHECK: function_ref @_TTSg5Si___TFV16specialize_chain3YYYC +//CHECK: function_ref @_TTSg5Si___TFV16specialize_chain3YYY4AAA9 +//CHECK: return diff --git a/test/SILPasses/specialize_checked_cast_branch.swift b/test/SILOptimizer/specialize_checked_cast_branch.swift similarity index 99% rename from test/SILPasses/specialize_checked_cast_branch.swift rename to test/SILOptimizer/specialize_checked_cast_branch.swift index 7a9f9308dde1c..12576fc3087ca 100644 --- a/test/SILPasses/specialize_checked_cast_branch.swift +++ b/test/SILOptimizer/specialize_checked_cast_branch.swift @@ -64,12 +64,12 @@ ArchetypeToArchetypeCast(t1: c, t2: b) // CHECK: checked_cast_br [[V]] : $C to $D, // CHECK: bb1([[T0:%.*]] : $D): // CHECK: [[T1:%.*]] = enum $Optional, #Optional.Some!enumelt.1, [[T0]] : $D -// CHECK: store [[T1]] to [[TMP]]#1 : $*Optional +// CHECK: store [[T1]] to [[TMP]] : $*Optional // CHECK: strong_retain [[V]] : $C // CHECK: br bb3 // CHECK: bb2: // CHECK: [[T0:%.*]] = enum $Optional, #Optional.None -// CHECK: store [[T0]] to [[TMP]]#1 : $*Optional +// CHECK: store [[T0]] to [[TMP]] : $*Optional // CHECK: br bb3 ArchetypeToArchetypeCast(t1: c, t2: d) diff --git a/test/SILPasses/specialize_ext.swift b/test/SILOptimizer/specialize_ext.swift similarity index 100% rename from test/SILPasses/specialize_ext.swift rename to test/SILOptimizer/specialize_ext.swift diff --git a/test/SILPasses/specialize_inherited.sil b/test/SILOptimizer/specialize_inherited.sil similarity index 75% rename from test/SILPasses/specialize_inherited.sil rename to test/SILOptimizer/specialize_inherited.sil index 31fb574a022f9..73f8b26bed01e 100644 --- a/test/SILPasses/specialize_inherited.sil +++ b/test/SILOptimizer/specialize_inherited.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -module-name inherit | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -generic-specializer -module-name inherit | FileCheck %s import Builtin import Swift @@ -29,9 +29,9 @@ bb0(%0 : $Int, %1 : $Int): %37 = alloc_stack $MMString // CHECK: [[ID:%[0-9]+]] = function_ref @_TTSg5C7inherit8MMStringCS_8MMObjects8HashableS__GSQCS_6MMFont___callee : $@convention(method) (@in MMString, Int, @owned MMStorage>) -> Bool %34 = function_ref @callee : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in τ_0_0, Int, @owned MMStorage<τ_0_0, τ_0_1>) -> Bool - // CHECK: apply [[ID]]([[STACK]]#1, %1, %{{[0-9]+}}) : $@convention(method) (@in MMString, Int, @owned MMStorage>) -> Bool - %45 = apply %34(%37#1, %1, %14) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in τ_0_0, Int, @owned MMStorage<τ_0_0, τ_0_1>) -> Bool - dealloc_stack %37#0 : $*@local_storage MMString + // CHECK: apply [[ID]]([[STACK]], %1, %{{[0-9]+}}) : $@convention(method) (@in MMString, Int, @owned MMStorage>) -> Bool + %45 = apply %34(%37, %1, %14) : $@convention(method) <τ_0_0, τ_0_1 where τ_0_0 : Hashable> (@in τ_0_0, Int, @owned MMStorage<τ_0_0, τ_0_1>) -> Bool + dealloc_stack %37 : $*MMString return %14 : $MMStorage> } @@ -41,7 +41,7 @@ bb0(%0 : $Int, %1 : $Int): // CHECK: [[ID3:%[0-9]+]] = witness_method $MMObject, #Equatable."=="!1 : // CHECK: [[STACK2:%[0-9]+]] = alloc_stack $MMString // CHECK: [[STACK3:%[0-9]+]] = alloc_stack $MMString -// CHECK: apply [[ID3]]([[STACK2]]#1, [[STACK3]]#1, [[META]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> Bool +// CHECK: apply [[ID3]]([[STACK2]], [[STACK3]], [[META]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> Bool // CHECK-LABEL: @callee : $@convention(method) (@in Key, Int, @owned MMStorage) -> Bool { sil [noinline] @callee : $@convention(method) (@in Key, Int, @owned MMStorage) -> Bool { @@ -52,9 +52,9 @@ bb0(%0 : $*Key, %1 : $Int, %2 : $MMStorage): %27 = alloc_stack $Key %33 = alloc_stack $Key // CHECK: apply [[ID2]] - %35 = apply %26(%27#1, %33#1, %25) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> Bool - dealloc_stack %33#0 : $*@local_storage Key - dealloc_stack %27#0 : $*@local_storage Key + %35 = apply %26(%27, %33, %25) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Equatable> (@in τ_0_0, @in τ_0_0, @thick τ_0_0.Type) -> Bool + dealloc_stack %33 : $*Key + dealloc_stack %27 : $*Key return %35 : $Bool } diff --git a/test/SILPasses/specialize_metatypes_with_nondefault_representation.sil b/test/SILOptimizer/specialize_metatypes_with_nondefault_representation.sil similarity index 95% rename from test/SILPasses/specialize_metatypes_with_nondefault_representation.sil rename to test/SILOptimizer/specialize_metatypes_with_nondefault_representation.sil index 0d2f6a000e396..d9dd12a611bb9 100644 --- a/test/SILPasses/specialize_metatypes_with_nondefault_representation.sil +++ b/test/SILOptimizer/specialize_metatypes_with_nondefault_representation.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inline | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -generic-specializer | FileCheck %s // REQUIRES: objc_interop @@ -6,7 +6,7 @@ // functions for the @thick, @thin, and @objc_metatype metatypes. // // This can occur if we do not properly mangle in the metatype representation -// into the name of functions and thus reuse the incorrect already specisalized +// into the name of functions and thus reuse the incorrect already specialized // method instead of the new specialized method. sil_stage canonical diff --git a/test/SILPasses/specialize_recursive_generics.sil b/test/SILOptimizer/specialize_recursive_generics.sil similarity index 76% rename from test/SILPasses/specialize_recursive_generics.sil rename to test/SILOptimizer/specialize_recursive_generics.sil index 8501b1b243942..1091e6aab5fd6 100644 --- a/test/SILPasses/specialize_recursive_generics.sil +++ b/test/SILOptimizer/specialize_recursive_generics.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inline | FileCheck %s +// RUN: %target-sil-opt -enable-sil-verify-all %s -generic-specializer | FileCheck %s // Check that SIL cloner can correctly handle specialization of recursive // functions with generic arguments. @@ -14,13 +14,13 @@ import Swift // CHECK: return sil [noinline] @_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_ : $@convention(thin) (@in T) -> () { bb0(%0 : $*T): - debug_value_addr %0 : $*T // let t // id: %1 + debug_value_addr %0 : $*T, let, name "t" // id: %1 // function_ref specialize_recursive_generics.recursive_generics (A) -> () %2 = function_ref @_TF29specialize_recursive_generics18recursive_genericsU__FQ_T_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %5 %3 = alloc_stack $T // users: %4, %5, %6 - copy_addr %0 to [initialization] %3#1 : $*T // id: %4 - %5 = apply %2(%3#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - dealloc_stack %3#0 : $*@local_storage T // id: %6 + copy_addr %0 to [initialization] %3 : $*T // id: %4 + %5 = apply %2(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %3 : $*T // id: %6 destroy_addr %0 : $*T // id: %7 %8 = tuple () // user: %9 return %8 : $() // id: %9 @@ -39,17 +39,17 @@ bb0(%0 : $*T): sil [noinline] @_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_ : $@convention(thin) (@in T, @in U) -> () { bb0(%0 : $*T, %1 : $*U): - debug_value_addr %0 : $*T // let t // id: %2 - debug_value_addr %1 : $*U // let u // id: %3 + debug_value_addr %0 : $*T, let, name "t" // id: %2 + debug_value_addr %1 : $*U, let, name "u" // id: %3 // function_ref specialize_recursive_generics.recursive_generics_with_different_substitutions (A, B) -> () %4 = function_ref @_TF29specialize_recursive_generics47recursive_generics_with_different_substitutionsU___FTQ_Q0__T_ : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () // user: %9 %5 = alloc_stack $U // users: %6, %9, %11 - copy_addr %1 to [initialization] %5#1 : $*U // id: %6 + copy_addr %1 to [initialization] %5 : $*U // id: %6 %7 = alloc_stack $T // users: %8, %9, %10 - copy_addr %0 to [initialization] %7#1 : $*T // id: %8 - %9 = apply %4(%5#1, %7#1) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () - dealloc_stack %7#0 : $*@local_storage T // id: %10 - dealloc_stack %5#0 : $*@local_storage U // id: %11 + copy_addr %0 to [initialization] %7 : $*T // id: %8 + %9 = apply %4(%5, %7) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () + dealloc_stack %7 : $*T // id: %10 + dealloc_stack %5 : $*U // id: %11 destroy_addr %1 : $*U // id: %12 destroy_addr %0 : $*T // id: %13 %14 = tuple () // user: %15 @@ -63,9 +63,9 @@ bb0: %1 = integer_literal $Builtin.Int32, 3 // user: %2 %2 = struct $Int32 (%1 : $Builtin.Int32) // user: %4 %3 = alloc_stack $Int32 // users: %4, %5, %6 - store %2 to %3#1 : $*Int32 // id: %4 - %5 = apply %0(%3#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - dealloc_stack %3#0 : $*@local_storage Int32 // id: %6 + store %2 to %3 : $*Int32 // id: %4 + %5 = apply %0(%3) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () + dealloc_stack %3 : $*Int32 // id: %6 %7 = tuple () // user: %8 return %7 : $() // id: %8 } @@ -78,14 +78,14 @@ bb0: %2 = builtin "fptrunc_FPIEEE80_FPIEEE64"(%1 : $Builtin.FPIEEE80) : $Builtin.FPIEEE64 // user: %3 %3 = struct $Double (%2 : $Builtin.FPIEEE64) // user: %5 %4 = alloc_stack $Double // users: %5, %10, %12 - store %3 to %4#1 : $*Double // id: %5 + store %3 to %4 : $*Double // id: %5 %6 = integer_literal $Builtin.Int32, 1 // user: %7 %7 = struct $Int32 (%6 : $Builtin.Int32) // user: %9 %8 = alloc_stack $Int32 // users: %9, %10, %11 - store %7 to %8#1 : $*Int32 // id: %9 - %10 = apply %0(%4#1, %8#1) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () - dealloc_stack %8#0 : $*@local_storage Int32 // id: %11 - dealloc_stack %4#0 : $*@local_storage Double // id: %12 + store %7 to %8 : $*Int32 // id: %9 + %10 = apply %0(%4, %8) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () + dealloc_stack %8 : $*Int32 // id: %11 + dealloc_stack %4 : $*Double // id: %12 %13 = tuple () // user: %14 return %13 : $() // id: %14 } diff --git a/test/SILPasses/specialize_self.swift b/test/SILOptimizer/specialize_self.swift similarity index 100% rename from test/SILPasses/specialize_self.swift rename to test/SILOptimizer/specialize_self.swift diff --git a/test/SILPasses/specialize_unconditional_checked_cast.swift b/test/SILOptimizer/specialize_unconditional_checked_cast.swift similarity index 95% rename from test/SILPasses/specialize_unconditional_checked_cast.swift rename to test/SILOptimizer/specialize_unconditional_checked_cast.swift index 7a09a6acea2c3..acc64ecf6b09a 100644 --- a/test/SILPasses/specialize_unconditional_checked_cast.swift +++ b/test/SILOptimizer/specialize_unconditional_checked_cast.swift @@ -33,48 +33,48 @@ ArchetypeToArchetype(t: d, t2: c) ArchetypeToArchetype(t: c, t2: e) ArchetypeToArchetype(t: b, t2: f) -// x -> y where x and y are unrelated non classes. -// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8_Vs6UInt64___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out UInt64, @in UInt8, @in UInt64) -> () { -// CHECK-NOT: unconditional_checked_cast archetype_to_archetype +// x -> x where x is not a class. +// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8_S____TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out UInt8, @in UInt8, @in UInt8) -> () { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype -// CHECK: builtin "int_trap" + +// x -> x where x is a class. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C_S0____TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out C, @in C, @in C) -> () { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype -// x -> y where x and y are unrelated classes. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C_CS_1E___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out E, @in C, @in E) -> () { +// x -> y where x is not a class but y is. +// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8_C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out C, @in UInt8, @in C) -> () { +// CHECK-NOT: unconditional_checked_cast_addr +// CHECK-NOT: unconditional_checked_cast_addr +// CHECK: builtin "int_trap" +// CHECK-NOT: unconditional_checked_cast_addr + +// y -> x where x is not a class but y is. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C_Vs5UInt8___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out UInt8, @in C, @in UInt8) -> () { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // CHECK: builtin "int_trap" // CHECK-NOT: unconditional_checked_cast archetype_to_archetype +// x -> y where x is a super class of y. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C_CS_1D___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out D, @in C, @in D) -> () { +// CHECK: unconditional_checked_cast_addr take_always C in %1 : $*C to D in + // y -> x where x is a super class of y. // CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1D_CS_1C___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out C, @in D, @in C) -> () { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // CHECK: upcast {{%[0-9]+}} : $D to $C // CHECK-NOT: unconditional_checked_cast archetype_to_archetype -// x -> y where x is a super class of y. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C_CS_1D___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out D, @in C, @in D) -> () { -// CHECK: unconditional_checked_cast_addr take_always C in %1 : $*C to D in - -// y -> x where x is not a class but y is. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C_Vs5UInt8___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out UInt8, @in C, @in UInt8) -> () { +// x -> y where x and y are unrelated classes. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C_CS_1E___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out E, @in C, @in E) -> () { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype // CHECK: builtin "int_trap" // CHECK-NOT: unconditional_checked_cast archetype_to_archetype -// x -> y where x is not a class but y is. -// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8_C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out C, @in UInt8, @in C) -> () { -// CHECK-NOT: unconditional_checked_cast_addr -// CHECK-NOT: unconditional_checked_cast_addr -// CHECK: builtin "int_trap" -// CHECK-NOT: unconditional_checked_cast_addr - -// x -> x where x is a class. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C_S0____TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out C, @in C, @in C) -> () { +// x -> y where x and y are unrelated non classes. +// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8_Vs6UInt64___TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out UInt64, @in UInt8, @in UInt64) -> () { // CHECK-NOT: unconditional_checked_cast archetype_to_archetype - -// x -> x where x is not a class. -// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8_S____TF37specialize_unconditional_checked_cast20ArchetypeToArchetype{{.*}} : $@convention(thin) (@out UInt8, @in UInt8, @in UInt8) -> () { +// CHECK-NOT: unconditional_checked_cast archetype_to_archetype +// CHECK: builtin "int_trap" // CHECK-NOT: unconditional_checked_cast archetype_to_archetype @@ -90,7 +90,6 @@ ArchetypeToConcreteConvertUInt8(t: b) ArchetypeToConcreteConvertUInt8(t: c) ArchetypeToConcreteConvertUInt8(t: f) -// order 57% // x -> x where x is not a class. // CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8___TF37specialize_unconditional_checked_cast31ArchetypeToConcreteConvertUInt8{{.*}} : $@convention(thin) (@in UInt8) -> UInt8 { // CHECK: bb0 @@ -98,21 +97,19 @@ ArchetypeToConcreteConvertUInt8(t: f) // CHECK-NEXT: load // CHECK-NEXT: return -// order: 59% -// x -> y where x,y are classes and x is a super class of y. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1D___TF37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{.*}} : $@convention(thin) (@in D) -> @owned C { +// x -> x where x is a class. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{.*}} : $@convention(thin) (@in C) -> @owned C { // CHECK: bb0 // CHECK-NEXT: debug_value_addr // CHECK-NEXT: load -// CHECK-NEXT: upcast // CHECK-NEXT: return -// order: 60% -// x -> x where x is a class. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{.*}} : $@convention(thin) (@in C) -> @owned C { +// x -> y where x,y are classes and x is a super class of y. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1D___TF37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC{{.*}} : $@convention(thin) (@in D) -> @owned C { // CHECK: bb0 // CHECK-NEXT: debug_value_addr // CHECK-NEXT: load +// CHECK-NEXT: upcast // CHECK-NEXT: return @@ -167,12 +164,13 @@ ConcreteToArchetypeConvertUInt8(t: b, t2: b) ConcreteToArchetypeConvertUInt8(t: b, t2: c) ConcreteToArchetypeConvertUInt8(t: b, t2: f) -// x -> y where x,y are different non class types. -// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs6UInt64___TF37specialize_unconditional_checked_cast31ConcreteToArchetypeConvertUInt8{{.*}} : $@convention(thin) (@out UInt64, UInt8, @in UInt64) -> () { +// x -> x where x is not a class. +// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8___TF37specialize_unconditional_checked_cast31ConcreteToArchetypeConvertUInt8{{.*}} : $@convention(thin) (@out UInt8, UInt8, @in UInt8) -> () { // CHECK: bb0 -// CHECK: builtin "int_trap" -// CHECK: unreachable -// CHECK-NEXT: } +// CHECK-NEXT: debug_value +// CHECK-NEXT: store +// CHECK-NEXT: tuple +// CHECK-NEXT: return // x -> y where x is not a class but y is a class. // CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast31ConcreteToArchetypeConvertUInt8{{.*}} : $@convention(thin) (@out C, UInt8, @in C) -> () { @@ -181,13 +179,12 @@ ConcreteToArchetypeConvertUInt8(t: b, t2: f) // CHECK: unreachable // CHECK-NEXT: } -// x -> x where x is not a class. -// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8___TF37specialize_unconditional_checked_cast31ConcreteToArchetypeConvertUInt8{{.*}} : $@convention(thin) (@out UInt8, UInt8, @in UInt8) -> () { +// x -> y where x,y are different non class types. +// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs6UInt64___TF37specialize_unconditional_checked_cast31ConcreteToArchetypeConvertUInt8{{.*}} : $@convention(thin) (@out UInt64, UInt8, @in UInt64) -> () { // CHECK: bb0 -// CHECK-NEXT: debug_value -// CHECK-NEXT: store -// CHECK-NEXT: tuple -// CHECK-NEXT: return +// CHECK: builtin "int_trap" +// CHECK: unreachable +// CHECK-NEXT: } @inline(never) public func ConcreteToArchetypeConvertC(t t: C, t2: T) -> T { @@ -199,28 +196,15 @@ ConcreteToArchetypeConvertC(t: c, t2: b) ConcreteToArchetypeConvertC(t: c, t2: d) ConcreteToArchetypeConvertC(t: c, t2: e) -// x -> y where x and y are unrelated classes. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1E___TF37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{.*}} : $@convention(thin) (@out E, @owned C, @in E) -> () { -// CHECK: bb0 -// CHECK-NEXT: debug_value -// CHECK-NEXT: strong_retain -// CHECK-NEXT: builtin "int_trap" -// CHECK: unreachable -// CHECK-NEXT: } -// x -> y where x is a super class of y. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1D___TF37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{.*}} : $@convention(thin) (@out D, @owned C, @in D) -> () { +// x -> x where x is a class. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{.*}} : $@convention(thin) (@out C, @owned C, @in C) -> () { // CHECK: bb0 // CHECK-NEXT: debug_value // CHECK-NEXT: debug_value_addr -// CHECK-NEXT: alloc_stack // CHECK-NEXT: store -// CHECK-NEXT: strong_retain -// CHECK-NEXT: unconditional_checked_cast_addr take_always -// CHECK-NEXT: dealloc_stack // CHECK-NEXT: load // CHECK-NEXT: strong_release -// CHECK-NEXT: strong_release // CHECK-NEXT: tuple // CHECK-NEXT: return @@ -231,17 +215,30 @@ ConcreteToArchetypeConvertC(t: c, t2: e) // CHECK: unreachable // CHECK-NEXT: } -// x -> x where x is a class. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{.*}} : $@convention(thin) (@out C, @owned C, @in C) -> () { +// x -> y where x is a super class of y. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1D___TF37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{.*}} : $@convention(thin) (@out D, @owned C, @in D) -> () { // CHECK: bb0 // CHECK-NEXT: debug_value // CHECK-NEXT: debug_value_addr +// CHECK-NEXT: alloc_stack // CHECK-NEXT: store +// CHECK-NEXT: strong_retain +// CHECK-NEXT: unconditional_checked_cast_addr take_always +// CHECK-NEXT: dealloc_stack // CHECK-NEXT: load // CHECK-NEXT: strong_release +// CHECK-NEXT: strong_release // CHECK-NEXT: tuple // CHECK-NEXT: return +// x -> y where x and y are unrelated classes. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1E___TF37specialize_unconditional_checked_cast27ConcreteToArchetypeConvertC{{.*}} : $@convention(thin) (@out E, @owned C, @in E) -> () { +// CHECK: bb0 +// CHECK-NEXT: builtin "int_trap" +// CHECK-NEXT: store undef to %0 : $*E +// CHECK: unreachable +// CHECK-NEXT: } + @inline(never) public func ConcreteToArchetypeConvertD(t t: D, t2: T) -> T { return t as! T @@ -275,17 +272,6 @@ SuperToArchetypeC(c: c, t: c) SuperToArchetypeC(c: c, t: d) SuperToArchetypeC(c: c, t: b) -// x -> y where x is a class and y is not. -// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8___TF37specialize_unconditional_checked_cast17SuperToArchetypeC{{.*}} : $@convention(thin) (@out UInt8, @owned C, @in UInt8) -> () { -// CHECK: bb0 -// CHECK: builtin "int_trap" -// CHECK: unreachable -// CHECK-NEXT: } - -// x -> y where x is a super class of y. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1D___TF37specialize_unconditional_checked_cast17SuperToArchetypeC{{.*}} : $@convention(thin) (@out D, @owned C, @in D) -> () { -// CHECK: bb0 -// CHECK: unconditional_checked_cast_addr take_always C in // x -> x where x is a class. // CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast17SuperToArchetypeC{{.*}} : $@convention(thin) (@out C, @owned C, @in C) -> () { @@ -298,6 +284,18 @@ SuperToArchetypeC(c: c, t: b) // CHECK-NEXT: tuple // CHECK-NEXT: return +// x -> y where x is a super class of y. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1D___TF37specialize_unconditional_checked_cast17SuperToArchetypeC{{.*}} : $@convention(thin) (@out D, @owned C, @in D) -> () { +// CHECK: bb0 +// CHECK: unconditional_checked_cast_addr take_always C in + +// x -> y where x is a class and y is not. +// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8___TF37specialize_unconditional_checked_cast17SuperToArchetypeC{{.*}} : $@convention(thin) (@out UInt8, @owned C, @in UInt8) -> () { +// CHECK: bb0 +// CHECK: builtin "int_trap" +// CHECK: unreachable +// CHECK-NEXT: } + @inline(never) public func SuperToArchetypeD(d d : D, t : T) -> T { return d as! T @@ -306,6 +304,13 @@ public func SuperToArchetypeD(d d : D, t : T) -> T { SuperToArchetypeD(d: d, t: c) SuperToArchetypeD(d: d, t: d) +// *NOTE* The frontend is smart enough to turn this into an upcast. When this +// test is converted to SIL, this should be fixed appropriately. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast17SuperToArchetypeD{{.*}} : $@convention(thin) (@out C, @owned D, @in C) -> () { +// CHECK-NOT: unconditional_checked_cast super_to_archetype +// CHECK: upcast +// CHECK-NOT: unconditional_checked_cast super_to_archetype + // CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1D___TF37specialize_unconditional_checked_cast17SuperToArchetypeD{{.*}} : $@convention(thin) (@out D, @owned D, @in D) -> () { // CHECK: bb0 // CHECK-NEXT: debug_value @@ -316,13 +321,6 @@ SuperToArchetypeD(d: d, t: d) // CHECK-NEXT: tuple // CHECK-NEXT: return -// *NOTE* The frontend is smart enough to turn this into an upcast. When this -// test is converted to SIL, this should be fixed appropriately. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast17SuperToArchetypeD{{.*}} : $@convention(thin) (@out C, @owned D, @in C) -> () { -// CHECK-NOT: unconditional_checked_cast super_to_archetype -// CHECK: upcast -// CHECK-NOT: unconditional_checked_cast super_to_archetype - ////////////////////////////// // Existential To Archetype // ////////////////////////////// @@ -332,6 +330,16 @@ public func ExistentialToArchetype(o o : AnyObject, t : T) -> T { return o as! T } +// AnyObject -> Class. +// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast22ExistentialToArchetype{{.*}} : $@convention(thin) (@out C, @owned AnyObject, @in C) -> () { +// CHECK: unconditional_checked_cast_addr take_always AnyObject in {{%.*}} : $*AnyObject to C + +// AnyObject -> Non Class (should always fail) +// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8___TF37specialize_unconditional_checked_cast22ExistentialToArchetype{{.*}} : $@convention(thin) (@out UInt8, @owned AnyObject, @in UInt8) -> () { +// CHECK: builtin "int_trap"() +// CHECK: unreachable +// CHECK-NEXT: } + // AnyObject -> AnyObject // CHECK-LABEL: sil shared [noinline] @_TTSg5Ps9AnyObject____TF37specialize_unconditional_checked_cast22ExistentialToArchetype{{.*}} : $@convention(thin) (@out AnyObject, @owned AnyObject, @in AnyObject) -> () { // CHECK: bb0 @@ -343,21 +351,25 @@ public func ExistentialToArchetype(o o : AnyObject, t : T) -> T { // CHECK-NEXT: tuple // CHECK-NEXT: return -// AnyObject -> Non Class (should always fail) -// CHECK-LABEL: sil shared [noinline] @_TTSg5Vs5UInt8___TF37specialize_unconditional_checked_cast22ExistentialToArchetype{{.*}} : $@convention(thin) (@out UInt8, @owned AnyObject, @in UInt8) -> () { -// CHECK: builtin "int_trap"() -// CHECK: unreachable -// CHECK-NEXT: } - -// AnyObject -> Class. -// CHECK-LABEL: sil shared [noinline] @_TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast22ExistentialToArchetype{{.*}} : $@convention(thin) (@out C, @owned AnyObject, @in C) -> () { -// CHECK: unconditional_checked_cast_addr take_always AnyObject in {{%.*}} : $*AnyObject to C - ExistentialToArchetype(o: o, t: c) ExistentialToArchetype(o: o, t: b) ExistentialToArchetype(o: o, t: o) -//order: -5 +// Ensure that a downcast from an Optional source is not promoted to a +// value cast. We could do the promotion, but the optimizer would need +// to insert the Optional unwrapping logic before the cast. +// +// CHECK-LABEL: sil shared [noinline] @_TTSg5GSqC37specialize_unconditional_checked_cast1C__CS_1D___TF37specialize_unconditional_checked_cast15genericDownCastu0_rFTxMq__q_ : $@convention(thin) (@out D, @in Optional, @thick D.Type) -> () { +// CHECK: unconditional_checked_cast_addr take_always Optional in %1 : $*Optional to D in %0 : $*D +@inline(never) +public func genericDownCast(a: T, _ : U.Type) -> U { + return a as! U +} + +public func callGenericDownCast(c: C?) -> D { + return genericDownCast(c, D.self) +} + // x -> y where y is a class but x is not. // CHECK-LABEL: sil shared [noinline] @_TTSf4d___TTSg5C37specialize_unconditional_checked_cast1C___TF37specialize_unconditional_checked_cast31ArchetypeToConcreteConvertUInt8 // CHECK: bb0 @@ -365,7 +377,6 @@ ExistentialToArchetype(o: o, t: o) // CHECK: unreachable // CHECK-NEXT: } -//order: -4 // x -> y where x,y are not classes and x is a different type from y. // CHECK-LABEL: sil shared [noinline] @_TTSf4d___TTSg5Vs6UInt64___TF37specialize_unconditional_checked_cast31ArchetypeToConcreteConvertUInt8 // CHECK: bb0 @@ -373,7 +384,6 @@ ExistentialToArchetype(o: o, t: o) // CHECK: unreachable // CHECK-NEXT: } -// order -3 // x -> y where x is a class but y is not. // CHECK-LABEL: sil shared [noinline] @_TTSf4d___TTSg5Vs5UInt8___TF37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC // CHECK: bb0 @@ -381,7 +391,6 @@ ExistentialToArchetype(o: o, t: o) // CHECK: unreachable // CHECK-NEXT: } -// order -2 // x -> y where x,y are classes, but x is unrelated to y. // CHECK-LABEL: sil shared [noinline] @_TTSf4d___TTSg5C37specialize_unconditional_checked_cast1E___TF37specialize_unconditional_checked_cast27ArchetypeToConcreteConvertC // CHECK: bb0 @@ -389,7 +398,6 @@ ExistentialToArchetype(o: o, t: o) // CHECK: unreachable // CHECK-NEXT: } -// order -1 // x -> y where x,y are classes, but y is unrelated to x. The idea is // to make sure that the fact that y is concrete does not affect the // result. diff --git a/test/SILPasses/split_critical_edges.sil b/test/SILOptimizer/split_critical_edges.sil similarity index 100% rename from test/SILPasses/split_critical_edges.sil rename to test/SILOptimizer/split_critical_edges.sil diff --git a/test/SILOptimizer/sroa.sil b/test/SILOptimizer/sroa.sil new file mode 100644 index 0000000000000..729f2578db758 --- /dev/null +++ b/test/SILOptimizer/sroa.sil @@ -0,0 +1,423 @@ +// RUN: %target-sil-opt -enable-sil-verify-all -sroa %s | FileCheck %s + +sil_stage canonical + +import Builtin +import Swift + +/////////////////////////////// +// Struct with Scalar Fields // +/////////////////////////////// + +struct S1 { + var x : Builtin.Int1 + var y : Builtin.Int32 + var z : Builtin.Int64 +} + +sil @use_int32 : $@convention(thin) (Builtin.Int32) -> () + +// CHECK-LABEL: sil @struct_with_scalar_fields : $@convention(thin) (S1) -> () +// CHECK: bb0([[VAR_0:%[0-9]+]] : $S1): +// CHECK: [[VAR_1:%[0-9]+]] = alloc_stack $Builtin.Int1 +// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32 +// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64 +// CHECK: [[VAR_4:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.x +// CHECK: store [[VAR_4]] to [[VAR_1]] : $*Builtin.Int1 +// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.y +// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.z +// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int64 +// CHECK: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_11:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_12:%[0-9]+]] = apply [[VAR_10]]([[VAR_11]]) : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_1]] : $*Builtin.Int1 +// CHECK: [[VAR_14:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_15:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int64 +// CHECK: [[VAR_16:%[0-9]+]] = struct $S1 ([[VAR_13]] : $Builtin.Int1, [[VAR_14]] : $Builtin.Int32, [[VAR_15]] : $Builtin.Int64) +// CHECK: dealloc_stack [[VAR_3]] : $*Builtin.Int64 +// CHECK: dealloc_stack [[VAR_2]] : $*Builtin.Int32 +// CHECK: dealloc_stack [[VAR_1]] : $*Builtin.Int1 +// CHECK: [[VAR_20:%[0-9]+]] = tuple () +// CHECK: return [[VAR_20]] : $() +sil @struct_with_scalar_fields : $@convention(thin) (S1) -> () { +bb0(%0 : $S1): + %1 = alloc_stack $S1 + debug_value %1 : $*S1 // should not prevent the optimization + debug_value %1 : $*S1 // should not prevent the optimization + store %0 to %1 : $*S1 + %2 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () + %3 = struct_element_addr %1 : $*S1, #S1.y + %4 = load %3 : $*Builtin.Int32 + apply %2(%4) : $@convention(thin) (Builtin.Int32) -> () + %5 = load %1 : $*S1 + dealloc_stack %1 : $*S1 + %6 = tuple () + return %6 : $() +} + +/////////////////////////////// +// Struct With Struct Fields // +/////////////////////////////// + +sil @use_s1 : $@convention(thin) (S1) -> () + +struct S2 { + var alpha : Builtin.FPIEEE32 + var beta : S1 +} + +// CHECK-LABEL: sil @struct_with_struct_fields : $@convention(thin) (S2, Builtin.Int64) -> () +// CHECK: bb0([[VAR_0:%[0-9]+]] : $S2, [[VAR_1:%[0-9]+]] : $Builtin.Int64): +// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.FPIEEE32 +// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int1 +// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int32 +// CHECK: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.Int64 +// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S2, #S2.alpha +// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.FPIEEE32 +// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_0]] : $S2, #S2.beta +// CHECK: [[VAR_9:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.x +// CHECK: store [[VAR_9]] to [[VAR_3]] : $*Builtin.Int1 +// CHECK: [[VAR_11:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.y +// CHECK: store [[VAR_11]] to [[VAR_4]] : $*Builtin.Int32 +// CHECK: [[VAR_13:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.z +// CHECK: store [[VAR_13]] to [[VAR_5]] : $*Builtin.Int64 +// CHECK: [[VAR_15:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int1 +// CHECK: [[VAR_16:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int32 +// CHECK: [[VAR_17:%[0-9]+]] = load [[VAR_5]] : $*Builtin.Int64 +// CHECK: [[VAR_18:%[0-9]+]] = struct $S1 ([[VAR_15]] : $Builtin.Int1, [[VAR_16]] : $Builtin.Int32, [[VAR_17]] : $Builtin.Int64) +// CHECK: [[VAR_19:%[0-9]+]] = function_ref @use_s1 : $@convention(thin) (S1) -> () +// CHECK: [[VAR_20:%[0-9]+]] = apply [[VAR_19]]([[VAR_18]]) : $@convention(thin) (S1) -> () +// CHECK: [[VAR_21:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_22:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int32 +// CHECK: [[VAR_23:%[0-9]+]] = apply [[VAR_21]]([[VAR_22]]) : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_24:%[0-9]+]] = load [[VAR_2]] : $*Builtin.FPIEEE32 +// CHECK: [[VAR_25:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int1 +// CHECK: [[VAR_26:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int32 +// CHECK: [[VAR_27:%[0-9]+]] = load [[VAR_5]] : $*Builtin.Int64 +// CHECK: [[VAR_28:%[0-9]+]] = struct $S1 ([[VAR_25]] : $Builtin.Int1, [[VAR_26]] : $Builtin.Int32, [[VAR_27]] : $Builtin.Int64) +// CHECK: [[VAR_29:%[0-9]+]] = struct $S2 ([[VAR_24]] : $Builtin.FPIEEE32, [[VAR_28]] : $S1) +// CHECK: store [[VAR_1]] to [[VAR_5]] : $*Builtin.Int64 +// CHECK: dealloc_stack [[VAR_5]] : $*Builtin.Int64 +// CHECK: dealloc_stack [[VAR_4]] : $*Builtin.Int32 +// CHECK: dealloc_stack [[VAR_3]] : $*Builtin.Int1 +// CHECK: dealloc_stack [[VAR_2]] : $*Builtin.FPIEEE32 +// CHECK: [[VAR_35:%[0-9]+]] = tuple () +// CHECK: return [[VAR_35]] : $() +sil @struct_with_struct_fields : $@convention(thin) (S2, Builtin.Int64) -> () { +bb0(%0 : $S2, %1 : $Builtin.Int64): + %2 = alloc_stack $S2 + store %0 to %2 : $*S2 + %3 = struct_element_addr %2 : $*S2, #S2.beta + %4 = load %3 : $*S1 + %5 = function_ref @use_s1 : $@convention(thin) (S1) -> () + apply %5(%4) : $@convention(thin) (S1) -> () + %6 = struct_element_addr %3 : $*S1, #S1.y + %7 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () + %8 = load %6 : $*Builtin.Int32 + apply %7(%8) : $@convention(thin) (Builtin.Int32) -> () + %9 = load %2 : $*S2 + %10 = struct_element_addr %3 : $*S1, #S1.z + store %1 to %10 : $*Builtin.Int64 + dealloc_stack %2 : $*S2 + %11 = tuple() + return %11 : $() +} + +////////////////////////////// +// Struct with Tuple Fields // +////////////////////////////// + +sil @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () + +struct S3 { + var gamma : (Builtin.Int32, Builtin.Int64, Builtin.Int16) + var delta : Builtin.FPIEEE32 +} + +// CHECK-LABEL: sil @struct_with_tuple_fields : $@convention(thin) (S3, Builtin.Int64) -> () +// CHECK: bb0([[VAR_0:%[0-9]+]] : $S3, [[VAR_1:%[0-9]+]] : $Builtin.Int64): +// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32 +// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64 +// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16 +// CHECK: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.FPIEEE32 +// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S3, #S3.gamma +// CHECK: [[VAR_7:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 0 +// CHECK: store [[VAR_7]] to [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_9:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 1 +// CHECK: store [[VAR_9]] to [[VAR_3]] : $*Builtin.Int64 +// CHECK: [[VAR_11:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 2 +// CHECK: store [[VAR_11]] to [[VAR_4]] : $*Builtin.Int16 +// CHECK: [[VAR_13:%[0-9]+]] = struct_extract [[VAR_0]] : $S3, #S3.delta +// CHECK: store [[VAR_13]] to [[VAR_5]] : $*Builtin.FPIEEE32 +// CHECK: [[VAR_15:%[0-9]+]] = function_ref @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () +// CHECK: [[VAR_16:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_17:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int64 +// CHECK: [[VAR_18:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int16 +// CHECK: [[VAR_19:%[0-9]+]] = tuple ([[VAR_16]] : $Builtin.Int32, [[VAR_17]] : $Builtin.Int64, [[VAR_18]] : $Builtin.Int16) +// CHECK: [[VAR_20:%[0-9]+]] = apply [[VAR_15]]([[VAR_19]]) : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () +// CHECK: [[VAR_21:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_22:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_23:%[0-9]+]] = apply [[VAR_22]]([[VAR_21]]) : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_24:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_25:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int64 +// CHECK: [[VAR_26:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int16 +// CHECK: [[VAR_27:%[0-9]+]] = tuple ([[VAR_24]] : $Builtin.Int32, [[VAR_25]] : $Builtin.Int64, [[VAR_26]] : $Builtin.Int16) +// CHECK: [[VAR_28:%[0-9]+]] = load [[VAR_5]] : $*Builtin.FPIEEE32 +// CHECK: [[VAR_29:%[0-9]+]] = struct $S3 ([[VAR_27]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), [[VAR_28]] : $Builtin.FPIEEE32) +// CHECK: store [[VAR_1]] to [[VAR_3]] : $*Builtin.Int64 +// CHECK: dealloc_stack [[VAR_5]] : $*Builtin.FPIEEE32 +// CHECK: dealloc_stack [[VAR_4]] : $*Builtin.Int16 +// CHECK: dealloc_stack [[VAR_3]] : $*Builtin.Int64 +// CHECK: dealloc_stack [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_35:%[0-9]+]] = tuple () +// CHECK: return [[VAR_35]] : $() +sil @struct_with_tuple_fields : $@convention(thin) (S3, Builtin.Int64) -> () { +bb0(%0 : $S3, %1 : $Builtin.Int64): + %2 = alloc_stack $S3 + store %0 to %2 : $*S3 + %3 = function_ref @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () + %4 = struct_element_addr %2 : $*S3, #S3.gamma + %5 = load %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16) + apply %3(%5) : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () + %6 = tuple_element_addr %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16), 0 + %7 = load %6 : $*Builtin.Int32 + %8 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () + apply %8(%7) : $@convention(thin) (Builtin.Int32) -> () + %9 = load %2 : $*S3 + %10 = tuple_element_addr %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16), 1 + store %1 to %10 : $*Builtin.Int64 + dealloc_stack %2 : $*S3 + %11 = tuple () + return %11 : $() +} + +////////////////////////////// +// Tuple with Scalar Fields // +////////////////////////////// + +// CHECK-LABEL: sil @tuple_with_scalar_fields : $@convention(thin) ((Builtin.Int1, Builtin.Int32, Builtin.Int64)) -> () +// CHECK: bb0([[VAR_0:%[0-9]+]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64)): +// CHECK: [[VAR_1:%[0-9]+]] = alloc_stack $Builtin.Int1 +// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32 +// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64 +// CHECK: [[VAR_4:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 0 +// CHECK: store [[VAR_4]] to [[VAR_1]] : $*Builtin.Int1 +// CHECK: [[VAR_6:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 1 +// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_8:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 2 +// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int64 +// CHECK: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_11:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_12:%[0-9]+]] = apply [[VAR_10]]([[VAR_11]]) : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_1]] : $*Builtin.Int1 +// CHECK: [[VAR_14:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int32 +// CHECK: [[VAR_15:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int64 +// CHECK: [[VAR_16:%[0-9]+]] = tuple ([[VAR_13]] : $Builtin.Int1, [[VAR_14]] : $Builtin.Int32, [[VAR_15]] : $Builtin.Int64) +// CHECK: dealloc_stack [[VAR_3]] : $*Builtin.Int64 +// CHECK: dealloc_stack [[VAR_2]] : $*Builtin.Int32 +// CHECK: dealloc_stack [[VAR_1]] : $*Builtin.Int1 +// CHECK: [[VAR_20:%[0-9]+]] = tuple () +// CHECK: return [[VAR_20]] : $() +sil @tuple_with_scalar_fields : $@convention(thin) ((Builtin.Int1, Builtin.Int32, Builtin.Int64)) -> () { +bb0(%0 : $(Builtin.Int1, Builtin.Int32, Builtin.Int64)): + %1 = alloc_stack $(Builtin.Int1, Builtin.Int32, Builtin.Int64) + store %0 to %1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64) + %2 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () + %3 = tuple_element_addr %1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64), 1 + %4 = load %3 : $*Builtin.Int32 + apply %2(%4) : $@convention(thin) (Builtin.Int32) -> () + %5 = load %1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64) + dealloc_stack %1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64) + %6 = tuple() + return %6 : $() +} + +////////////////////////////// +// Tuple With Struct Fields // +////////////////////////////// + +struct S4 { + var aleph : Builtin.Int64 + var bet : Builtin.Int32 +} + +sil @use_str4 : $@convention(thin) (S4) -> () + +// CHECK-LABEL: sil @tuple_with_struct_fields : $@convention(thin) ((S4, Builtin.Int16), Builtin.Int16) -> () +// CHECK: bb0([[VAR_0:%[0-9]+]] : $(S4, Builtin.Int16), [[VAR_1:%[0-9]+]] : $Builtin.Int16): +// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int64 +// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32 +// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16 +// CHECK: [[VAR_5:%[0-9]+]] = tuple_extract [[VAR_0]] : $(S4, Builtin.Int16), 0 +// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_5]] : $S4, #S4.aleph +// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int64 +// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_5]] : $S4, #S4.bet +// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_10:%[0-9]+]] = tuple_extract [[VAR_0]] : $(S4, Builtin.Int16), 1 +// CHECK: store [[VAR_10]] to [[VAR_4]] : $*Builtin.Int16 +// CHECK: [[VAR_12:%[0-9]+]] = function_ref @use_str4 : $@convention(thin) (S4) -> () +// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int64 +// CHECK: [[VAR_14:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_15:%[0-9]+]] = struct $S4 ([[VAR_13]] : $Builtin.Int64, [[VAR_14]] : $Builtin.Int32) +// CHECK: [[VAR_16:%[0-9]+]] = apply [[VAR_12]]([[VAR_15]]) : $@convention(thin) (S4) -> () +// CHECK: [[VAR_17:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_18:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_19:%[0-9]+]] = apply [[VAR_18]]([[VAR_17]]) : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_20:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int64 +// CHECK: [[VAR_21:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_22:%[0-9]+]] = struct $S4 ([[VAR_20]] : $Builtin.Int64, [[VAR_21]] : $Builtin.Int32) +// CHECK: [[VAR_23:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int16 +// CHECK: [[VAR_24:%[0-9]+]] = tuple ([[VAR_22]] : $S4, [[VAR_23]] : $Builtin.Int16) +// CHECK: store [[VAR_1]] to [[VAR_4]] : $*Builtin.Int16 +// CHECK: dealloc_stack [[VAR_4]] : $*Builtin.Int16 +// CHECK: dealloc_stack [[VAR_3]] : $*Builtin.Int32 +// CHECK: dealloc_stack [[VAR_2]] : $*Builtin.Int64 +// CHECK: [[VAR_29:%[0-9]+]] = tuple () +// CHECK: return [[VAR_29]] : $() +sil @tuple_with_struct_fields : $@convention(thin) ((S4, Builtin.Int16), Builtin.Int16) -> () { +bb0(%0 : $(S4, Builtin.Int16), %1 : $Builtin.Int16): + %2 = alloc_stack $(S4, Builtin.Int16) + store %0 to %2 : $*(S4, Builtin.Int16) + %3 = function_ref @use_str4 : $@convention(thin) (S4) -> () + %4 = tuple_element_addr %2 : $*(S4, Builtin.Int16), 0 + %5 = load %4 : $*S4 + apply %3(%5) : $@convention(thin) (S4) -> () + %6 = struct_element_addr %4 : $*S4, #S4.bet + %7 = load %6 : $*Builtin.Int32 + %8 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () + apply %8(%7) : $@convention(thin) (Builtin.Int32) -> () + %9 = load %2 : $*(S4, Builtin.Int16) + %10 = tuple_element_addr %2 : $*(S4, Builtin.Int16), 1 + store %1 to %10 : $*Builtin.Int16 + dealloc_stack %2 : $*(S4, Builtin.Int16) + %11 = tuple() + return %11 : $() +} + +///////////////////////////////// +// Tuple with Tuple Field Test // +///////////////////////////////// + +sil @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () +sil @use_int16 : $@convention(thin) (Builtin.Int16) -> () + +// CHECK-LABEL: sil @tuple_with_tuple_fields : $@convention(thin) (((Builtin.Int64, Builtin.Int32), Builtin.Int16), Builtin.Int16) -> () +// CHECK: bb0([[VAR_0:%[0-9]+]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), [[VAR_1:%[0-9]+]] : $Builtin.Int16): +// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int64 +// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32 +// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16 +// CHECK: [[VAR_5:%[0-9]+]] = tuple_extract [[VAR_0]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), 0 +// CHECK: [[VAR_6:%[0-9]+]] = tuple_extract [[VAR_5]] : $(Builtin.Int64, Builtin.Int32), 0 +// CHECK: store [[VAR_6]] to [[VAR_2]] : $*Builtin.Int64 +// CHECK: [[VAR_8:%[0-9]+]] = tuple_extract [[VAR_5]] : $(Builtin.Int64, Builtin.Int32), 1 +// CHECK: store [[VAR_8]] to [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_10:%[0-9]+]] = tuple_extract [[VAR_0]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), 1 +// CHECK: store [[VAR_10]] to [[VAR_4]] : $*Builtin.Int16 +// CHECK: [[VAR_12:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int64 +// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_14:%[0-9]+]] = tuple ([[VAR_12]] : $Builtin.Int64, [[VAR_13]] : $Builtin.Int32) +// CHECK: [[VAR_15:%[0-9]+]] = function_ref @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () +// CHECK: [[VAR_16:%[0-9]+]] = apply [[VAR_15]]([[VAR_14]]) : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () +// CHECK: [[VAR_17:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_18:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_19:%[0-9]+]] = apply [[VAR_17]]([[VAR_18]]) : $@convention(thin) (Builtin.Int32) -> () +// CHECK: [[VAR_20:%[0-9]+]] = load [[VAR_2]] : $*Builtin.Int64 +// CHECK: [[VAR_21:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_22:%[0-9]+]] = tuple ([[VAR_20]] : $Builtin.Int64, [[VAR_21]] : $Builtin.Int32) +// CHECK: [[VAR_23:%[0-9]+]] = load [[VAR_4]] : $*Builtin.Int16 +// CHECK: [[VAR_24:%[0-9]+]] = tuple ([[VAR_22]] : $(Builtin.Int64, Builtin.Int32), [[VAR_23]] : $Builtin.Int16) +// CHECK: store [[VAR_1]] to [[VAR_4]] : $*Builtin.Int16 +// CHECK: dealloc_stack [[VAR_4]] : $*Builtin.Int16 +// CHECK: dealloc_stack [[VAR_3]] : $*Builtin.Int32 +// CHECK: dealloc_stack [[VAR_2]] : $*Builtin.Int64 +// CHECK: [[VAR_29:%[0-9]+]] = tuple () +// CHECK: return [[VAR_29]] : $() +sil @tuple_with_tuple_fields : $@convention(thin) (((Builtin.Int64, Builtin.Int32), Builtin.Int16), Builtin.Int16) -> () { +bb0(%0 : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), %1 : $Builtin.Int16): + %2 = alloc_stack $((Builtin.Int64, Builtin.Int32), Builtin.Int16) + store %0 to %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16) + %3 = tuple_element_addr %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16), 0 + %4 = load %3 : $*(Builtin.Int64, Builtin.Int32) + %5 = function_ref @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () + apply %5(%4) : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () + %6 = tuple_element_addr %3 : $*(Builtin.Int64, Builtin.Int32), 1 + %7 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () + %8 = load %6 : $*Builtin.Int32 + apply %7(%8) : $@convention(thin) (Builtin.Int32) -> () + %9 = load %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16) + %10 = tuple_element_addr %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16), 1 + store %1 to %10 : $*Builtin.Int16 + dealloc_stack %2 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16) + %11 = tuple() + return %11 : $() +} + +///////////////////////// +// Capture Struct Test // +///////////////////////// + +struct CapturedS { + var x : Builtin.Int32 +} + +sil @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> () + +// CHECK-LABEL: sil @captured_struct : $@convention(thin) (CapturedS) -> () +// CHECK: bb0([[VAR_0:%[0-9]+]] : $CapturedS): +// CHECK: [[VAR_1:%[0-9]+]] = alloc_stack $CapturedS +// CHECK: store [[VAR_0]] to [[VAR_1]] : $*CapturedS +// CHECK: [[VAR_3:%[0-9]+]] = struct_element_addr [[VAR_1]] : $*CapturedS, #CapturedS.x +// CHECK: [[VAR_4:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_5:%[0-9]+]] = function_ref @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> () +// CHECK: [[VAR_6:%[0-9]+]] = apply [[VAR_5]]([[VAR_1]]) : $@convention(thin) (@inout CapturedS) -> () +// CHECK: [[VAR_7:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: dealloc_stack [[VAR_1]] : $*CapturedS +// CHECK: [[VAR_9:%[0-9]+]] = tuple () +// CHECK: return [[VAR_9]] : $() +sil @captured_struct : $@convention(thin) (CapturedS) -> () { +bb0(%0 : $CapturedS): + %1 = alloc_stack $CapturedS + store %0 to %1 : $*CapturedS + %3 = struct_element_addr %1 : $*CapturedS, #CapturedS.x + %4 = load %3 : $*Builtin.Int32 + %5 = function_ref @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> () + %6 = apply %5(%1) : $@convention(thin) (@inout CapturedS) -> () + %7 = load %3 : $*Builtin.Int32 + dealloc_stack %1 : $*CapturedS + %9 = tuple () + return %9 : $() +} + +///////////////////////// +// Captured Tuple Test // +///////////////////////// + +sil @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () + +// CHECK-LABEL: sil @captured_tuple : $@convention(thin) ((Builtin.Int32, Builtin.Int64)) -> () +// CHECK: bb0([[VAR_0:%[0-9]+]] : $(Builtin.Int32, Builtin.Int64)): +// CHECK: [[VAR_1:%[0-9]+]] = alloc_stack $(Builtin.Int32, Builtin.Int64) +// CHECK: store [[VAR_0]] to [[VAR_1]] : $*(Builtin.Int32, Builtin.Int64) +// CHECK: [[VAR_3:%[0-9]+]] = tuple_element_addr [[VAR_1]] : $*(Builtin.Int32, Builtin.Int64), 0 +// CHECK: [[VAR_4:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: [[VAR_5:%[0-9]+]] = function_ref @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () +// CHECK: [[VAR_6:%[0-9]+]] = apply [[VAR_5]]([[VAR_1]]) : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () +// CHECK: [[VAR_7:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 +// CHECK: dealloc_stack [[VAR_1]] : $*(Builtin.Int32, Builtin.Int64) +// CHECK: [[VAR_9:%[0-9]+]] = tuple () +// CHECK: return [[VAR_9]] : $() +sil @captured_tuple : $@convention(thin) ((Builtin.Int32, Builtin.Int64)) -> () { +bb0(%0 : $(Builtin.Int32, Builtin.Int64)): + %1 = alloc_stack $(Builtin.Int32, Builtin.Int64) + store %0 to %1 : $*(Builtin.Int32, Builtin.Int64) + %3 = tuple_element_addr %1 : $*(Builtin.Int32, Builtin.Int64), 0 + %4 = load %3 : $*Builtin.Int32 + %5 = function_ref @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () + %6 = apply %5(%1) : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () + %7 = load %3 : $*Builtin.Int32 + dealloc_stack %1 : $*(Builtin.Int32, Builtin.Int64) + %9 = tuple () + return %9 : $() +} + diff --git a/test/SILPasses/sroa_bbargs.sil b/test/SILOptimizer/sroa_bbargs.sil similarity index 100% rename from test/SILPasses/sroa_bbargs.sil rename to test/SILOptimizer/sroa_bbargs.sil diff --git a/test/SILPasses/sroa_unreferenced_members.swift b/test/SILOptimizer/sroa_unreferenced_members.swift similarity index 86% rename from test/SILPasses/sroa_unreferenced_members.swift rename to test/SILOptimizer/sroa_unreferenced_members.swift index bbecae4ae3318..7b626e4b1dd2e 100644 --- a/test/SILPasses/sroa_unreferenced_members.swift +++ b/test/SILOptimizer/sroa_unreferenced_members.swift @@ -6,7 +6,7 @@ import gizmo // CHECK: %1 = alloc_stack $Drill // CHECK: ret func ModifyStruct(inDrill : Drill) -> Int32 { - var D : Drill = inDrill; + var D : Drill = inDrill D.x += 3 - return D.x; + return D.x } diff --git a/test/SILPasses/stack_promotion.sil b/test/SILOptimizer/stack_promotion.sil similarity index 98% rename from test/SILPasses/stack_promotion.sil rename to test/SILOptimizer/stack_promotion.sil index 58cbeda8d0f81..4c2bce7cc56f8 100644 --- a/test/SILPasses/stack_promotion.sil +++ b/test/SILOptimizer/stack_promotion.sil @@ -1,4 +1,4 @@ -// RUN: %target-sil-opt -update-escapes -stack-promotion -enable-sil-verify-all %s | FileCheck %s +// RUN: %target-sil-opt -stack-promotion -enable-sil-verify-all %s | FileCheck %s sil_stage canonical @@ -243,7 +243,7 @@ bb4(%a1 : $Int32): cond_br undef, bb1, bb5 bb5: - dealloc_stack %s1#0 : $*@local_storage Int32 + dealloc_stack %s1 : $*Int32 return %a1 : $Int32 } @@ -267,7 +267,7 @@ bb2: %o1 = alloc_ref $XX %f1 = function_ref @xx_init : $@convention(thin) (@guaranteed XX) -> XX %n1 = apply %f1(%o1) : $@convention(thin) (@guaranteed XX) -> XX - dealloc_stack %s1#0 : $*@local_storage Int32 + dealloc_stack %s1 : $*Int32 %l1 = ref_element_addr %n1 : $XX, #XX.x %l2 = load %l1 : $*Int32 strong_release %n1 : $XX diff --git a/test/SILPasses/static_initializer.sil b/test/SILOptimizer/static_initializer.sil similarity index 100% rename from test/SILPasses/static_initializer.sil rename to test/SILOptimizer/static_initializer.sil diff --git a/test/SILPasses/static_report.sil b/test/SILOptimizer/static_report.sil similarity index 100% rename from test/SILPasses/static_report.sil rename to test/SILOptimizer/static_report.sil diff --git a/test/SILPasses/strip_debug_info.sil b/test/SILOptimizer/strip_debug_info.sil similarity index 100% rename from test/SILPasses/strip_debug_info.sil rename to test/SILOptimizer/strip_debug_info.sil diff --git a/test/SILOptimizer/super_class_method.swift b/test/SILOptimizer/super_class_method.swift new file mode 100644 index 0000000000000..05fd94840be7f --- /dev/null +++ b/test/SILOptimizer/super_class_method.swift @@ -0,0 +1,30 @@ +// RUN: %target-swift-frontend -emit-sil %s -use-native-super-method | FileCheck %s + +class Parent { + @inline(never) + class func onlyInParent() {} + @inline(never) + final class func finalOnlyInParent() {} + @inline(never) + class func foo() {} +} + +class Child : Parent {} + +class Grandchild : Child { + class func onlyInGrandchild() { + // CHECK-LABEL: sil hidden @_TZFC18super_class_method10Grandchild16onlyInGrandchildfT_T_ + // CHECK-NOT: super_method %0 : $@thick Grandchild.Type, #Parent.onlyInParent!1 : Parent.Type -> () -> () , $@convention(thin) (@thick Parent.Type) -> () // user: %5 + // CHECK: function_ref @_TZFC18super_class_method6Parent12onlyInParentfT_T_ + super.onlyInParent() + // CHECK: function_ref @_TZFC18super_class_method6Parent17finalOnlyInParentfT_T_ + super.finalOnlyInParent() + } + + override class func foo() { + // CHECK: sil hidden @_TZFC18super_class_method10Grandchild3foofT_T_ : $@convention(thin) (@thick Grandchild.Type) -> () { + // CHECK-NOT: super_method %0 : $@thick Grandchild.Type, #Parent.foo!1 : Parent.Type -> () -> () , $@convention(thin) (@thick Parent.Type) -> () + // CHECK: function_ref @_TZFC18super_class_method6Parent3foofT_T_ + super.foo() + } +} diff --git a/test/SILOptimizer/super_init.swift b/test/SILOptimizer/super_init.swift new file mode 100644 index 0000000000000..9169cc34399a3 --- /dev/null +++ b/test/SILOptimizer/super_init.swift @@ -0,0 +1,79 @@ +// RUN: %target-swift-frontend -use-native-super-method -emit-sil %s | FileCheck %s + +// CHECK-LABEL: sil hidden [noinline] @_TFC10super_init3FooCfSiS0_ : $@convention(thin) (Int, @thick Foo.Type) -> @owned Foo +// CHECK-NOT: class_method +// CHECK-NOT: super_method +// CHECK: [[SUPER_INIT:%.*]] = function_ref @_TFC10super_init3FoocfSiS0_ +// CHECK: [[NEW_SELF:%.*]] = apply [[SUPER_INIT]] + +// CHECK-LABEL: sil hidden [noinline] @_TFC10super_init3Barc +// CHECK-NOT: super_method [[ORIG_SELF]] : $Bar, #Foo.init!initializer.1 +// CHECK: function_ref @_TFC10super_init3FoocfT_S0_ + +class Foo { + @inline(never) + init() {} + @inline(never) + init(_ x: Foo) {} + @inline(never) + init(_ x: Int) {} +} + +class Bar: Foo { + @inline(never) + override init() { + super.init() + } +} + +extension Foo { + @inline(never) + convenience init(x: Int) { + self.init() + } +} + +class Zim: Foo { + var foo = Foo() + // CHECK-LABEL: sil hidden @_TFC10super_init3Zimc + // CHECK-NOT: super_method {{%[0-9]+}} : $Zim, #Foo.init!initializer.1 + // CHECK: function_ref @_TFC10super_init3FooCfT_S0_ + // CHECK: function_ref @_TFC10super_init3FoocfT_S0_ +} + +class Zang: Foo { + var foo: Foo + + @inline(never) + override init() { + foo = Foo() + super.init() + } + // CHECK-LABEL: sil hidden [noinline] @_TFC10super_init4ZangcfT_S0_ + // CHECK-NOT: super_method {{%[0-9]+}} : $Zang, #Foo.init!initializer.1 + // CHECK: function_ref @_TFC10super_init3FooCfT_S0_ + // CHECK: function_ref @_TFC10super_init3FoocfT_S0_ +} + +class Bad: Foo { + // Invalid code, but it's not diagnosed till DI. We at least shouldn't + // crash on it. + @inline(never) + override init() { + super.init(self) + } +} + +class Good: Foo { + let x: Int + + // CHECK-LABEL: sil hidden [noinline] @_TFC10super_init4GoodcfT_S0_ + // CHECK-NOT: super_method {{%[0-9]+}} : $Good, #Foo.init!initializer.1 + // CHECK: [[SUPER_INIT:%.*]] = function_ref @_TFC10super_init3FoocfSiS0_ + // CHECK: apply [[SUPER_INIT]] + @inline(never) + override init() { + x = 10 + super.init(x) + } +} diff --git a/test/SILOptimizer/super_method.swift b/test/SILOptimizer/super_method.swift new file mode 100644 index 0000000000000..a0a6016811277 --- /dev/null +++ b/test/SILOptimizer/super_method.swift @@ -0,0 +1,98 @@ +// RUN: %target-swift-frontend -emit-sil %s -use-native-super-method | FileCheck %s + +class Parent { + @inline(never) + func onlyInParent() {} + @inline(never) + final func finalOnlyInParent() {} + @inline(never) + func foo() {} +} + +class Child : Parent {} + +class Grandchild : Child { + // CHECK: sil hidden @_TFC12super_method10Grandchild16onlyInGrandchildfT_T_ + func onlyInGrandchild() { + // CHECK-NOT: super_method %0 : $Grandchild, #Parent.onlyInParent!1 : Parent -> () -> () + // CHECK: function_ref @_TFC12super_method6Parent12onlyInParentfT_T_ + super.onlyInParent() + // CHECK: function_ref @_TFC12super_method6Parent17finalOnlyInParentfT_T_ + super.finalOnlyInParent() + } + + // CHECK: sil hidden @_TFC12super_method10Grandchild3foofT_T_ + override func foo() { + // CHECK-NOT: super_method %0 : $Grandchild, #Parent.foo!1 : Parent -> () -> () + // CHECK: function_ref @_TFC12super_method6Parent3foofT_T_ + super.foo() + } +} + +class GenericParent { + let a: A + init(a: A) { + self.a = a + } + + func onlyInParent() {} + + @inline(never) + final func finalOnlyInParent() {} + + @inline(never) + func method() {} + + @inline(never) + class func classMethod() {} +} + +class GenericChild : GenericParent {} + +class GenericGrandchild : GenericChild { + // CHECK-LABEL: sil hidden @_TFC12super_method17GenericGrandchild16onlyInGrandchildfT_T_ : $@convention(method) (@guaranteed GenericGrandchild) -> () + func onlyInGrandchild() { + // CHECK-NOT: super_method % + // CHECK: function_ref @_TFC12super_method13GenericParent12onlyInParentfT_T_ + // CHECK-NOT: super_method % + super.onlyInParent() + // CHECK-NOT: super_method % + // CHECK: function_ref @_TFC12super_method13GenericParent17finalOnlyInParentfT_T_ : $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> () + // CHECK-NOT: super_method % + super.finalOnlyInParent() + } + // CHECK-LABEL: sil hidden @_TFC12super_method17GenericGrandchild6methodfT_T_ : $@convention(method) (@guaranteed GenericGrandchild) -> () + override func method() { + // CHECK-NOT: super_method % + // CHECK: function_ref @_TFC12super_method13GenericParent6methodfT_T_ + // CHECK-NOT: super_method % + super.method() + } +} + +class ConcreteChild : GenericParent { + // CHECK-LABEL: sil hidden @_TFC12super_method13ConcreteChildcfT1aSS_S0_ : $@convention(method) (@owned String, @owned ConcreteChild) -> @owned ConcreteChild + override init(a: String) { + // CHECK-NOT: super_method {{%[0-9]+}} : $ConcreteChild, #GenericParent.init!initializer.1 + // CHECK: [[INIT_FN_REF:%[0-9]+]] = function_ref @_TFC12super_method13GenericParentcfT1ax_GS0_x_ : $@convention(method) <τ_0_0> (@in τ_0_0, @owned GenericParent<τ_0_0>) -> @owned GenericParent<τ_0_0> // user: %10 + // CHECK-NEXT: apply [[INIT_FN_REF]] + super.init(a: a) + } +} + +class ConcreteGrandchild : ConcreteChild { + // CHECK-LABEL: sil hidden @_TFC12super_method18ConcreteGrandchild16onlyInGrandchildfT_T_ : $@convention(method) (@guaranteed ConcreteGrandchild) -> () + func onlyInGrandchild() { + // CHECK-NOT: super_method {{%[0-9]+}} : $ConcreteGrandchild, #GenericParent.onlyInParent!1 + // CHECK: function_ref @_TFC12super_method13GenericParent12onlyInParentfT_T_ : $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> () + super.onlyInParent() + // CHECK: function_ref @_TFC12super_method13GenericParent17finalOnlyInParentfT_T_ : $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> () + super.finalOnlyInParent() + } + // CHECK-LABEL: sil hidden @_TFC12super_method18ConcreteGrandchild6methodfT_T_ : $@convention(method) (@guaranteed ConcreteGrandchild) -> () + override func method() { + // CHECK-NOT: super_method {{%[0-9]+}} : $ConcreteGrandchild, #GenericParent.method!1 + // CHECK: function_ref @_TFC12super_method13GenericParent6methodfT_T_ : $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> () + super.method() + } +} diff --git a/test/SILOptimizer/super_objc_class_method.swift b/test/SILOptimizer/super_objc_class_method.swift new file mode 100644 index 0000000000000..eb44b8c18ba98 --- /dev/null +++ b/test/SILOptimizer/super_objc_class_method.swift @@ -0,0 +1,14 @@ +// RUN: %target-swift-frontend -emit-sil %s -use-native-super-method | FileCheck %s +// RN: %target-swift-frontend -emit-sil -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -use-native-super-method | FileCheck %s + +// REQUIRES: objc_interop + +import Foundation +class MyFunkyDictionary: NSDictionary { + // CHECK-LABEL: sil hidden @_TZFC23super_objc_class_method17MyFunkyDictionary10initializefT_T_ + // CHECK: super_method [volatile] %0 : $@thick MyFunkyDictionary.Type, #NSObject.initialize!1.foreign : NSObject.Type -> () -> () + override class func initialize() { + super.initialize() + } +} + diff --git a/test/SILPasses/swap_refcnt.swift b/test/SILOptimizer/swap_refcnt.swift similarity index 100% rename from test/SILPasses/swap_refcnt.swift rename to test/SILOptimizer/swap_refcnt.swift diff --git a/test/SILPasses/switch.swift b/test/SILOptimizer/switch.swift similarity index 85% rename from test/SILPasses/switch.swift rename to test/SILOptimizer/switch.swift index 187c5e38d2b0f..c51fc7bb70da3 100644 --- a/test/SILPasses/switch.swift +++ b/test/SILOptimizer/switch.swift @@ -4,10 +4,10 @@ func non_fully_covered_switch(x: Int) -> Int { var x = x switch x { case 0: - x++ + x += 1 case 3: - x-- + x -= 1 } // expected-error{{switch must be exhaustive}} - return x; + return x } diff --git a/test/SILPasses/throw_inline.swift b/test/SILOptimizer/throw_inline.swift similarity index 100% rename from test/SILPasses/throw_inline.swift rename to test/SILOptimizer/throw_inline.swift diff --git a/test/SILAnalysis/typed-access-tb-aa.sil b/test/SILOptimizer/typed-access-tb-aa.sil similarity index 96% rename from test/SILAnalysis/typed-access-tb-aa.sil rename to test/SILOptimizer/typed-access-tb-aa.sil index 86ba7679a8eb9..d2370c9350110 100644 --- a/test/SILAnalysis/typed-access-tb-aa.sil +++ b/test/SILOptimizer/typed-access-tb-aa.sil @@ -33,53 +33,53 @@ sil @baz_init : $@convention(thin) (@thick baz.Type) -> @owned baz sil @goo_init : $@convention(thin) (@thick goo.Type) -> @owned goo // CHECK-LABEL: no_parent_child_relation_reftype_tests -// CHECK: PAIR #13. -// CHECK: (1): %0 = alloc_stack $boo -// CHECK: (1): %1 = alloc_stack $baz +// CHECK: PAIR #1. +// CHECK: (0): %0 = alloc_stack $boo +// CHECK: (0): %1 = alloc_stack $baz // CHECK: NoAlias sil hidden @no_parent_child_relation_reftype_tests : $@convention(thin) () -> () { bb0: - %0 = alloc_stack $boo // var a // users: %5, %14 - %1 = alloc_stack $baz // var b // users: %9, %13 + %0 = alloc_stack $boo, var, name "a" // users: %5, %14 + %1 = alloc_stack $baz, var, name "b" // users: %9, %13 %2 = function_ref @boo_init : $@convention(thin) (@thick boo.Type) -> @owned boo // user: %4 %3 = metatype $@thick boo.Type // user: %4 %4 = apply %2(%3) : $@convention(thin) (@thick boo.Type) -> @owned boo // users: %5, %11 - store %4 to %0#1 : $*boo // id: %5 + store %4 to %0 : $*boo // id: %5 %6 = function_ref @baz_init : $@convention(thin) (@thick baz.Type) -> @owned baz // user: %8 %7 = metatype $@thick baz.Type // user: %8 %8 = apply %6(%7) : $@convention(thin) (@thick baz.Type) -> @owned baz // users: %9, %10 - store %8 to %1#1 : $*baz // id: %9 + store %8 to %1 : $*baz // id: %9 strong_release %8 : $baz // id: %10 strong_release %4 : $boo // id: %11 %12 = tuple () // user: %15 - dealloc_stack %1#0 : $*@local_storage baz // id: %13 - dealloc_stack %0#0 : $*@local_storage boo // id: %14 + dealloc_stack %1 : $*baz // id: %13 + dealloc_stack %0 : $*boo // id: %14 return %12 : $() // id: %15 } // CHECK-LABEL: with_parent_child_relation_reftype_tests -// CHECK: PAIR #54. +// CHECK: PAIR #33. // CHECK: (0): %4 = apply %2(%3) : $@convention(thin) (@thick boo.Type) -> @owned boo // CHECK: (0): %8 = apply %6(%7) : $@convention(thin) (@thick goo.Type) -> @owned goo // CHECK: MayAlias sil hidden @with_parent_child_relation_reftype_tests : $@convention(thin) () -> () { bb0: - %0 = alloc_stack $boo // var a // users: %5, %14 - %1 = alloc_stack $goo // var b // users: %9, %13 + %0 = alloc_stack $boo, var, name "a" // users: %5, %14 + %1 = alloc_stack $goo, var, name "b" // users: %9, %13 %2 = function_ref @boo_init : $@convention(thin) (@thick boo.Type) -> @owned boo // user: %4 %3 = metatype $@thick boo.Type // user: %4 %4 = apply %2(%3) : $@convention(thin) (@thick boo.Type) -> @owned boo // users: %5, %11 - store %4 to %0#1 : $*boo // id: %5 + store %4 to %0 : $*boo // id: %5 %6 = function_ref @goo_init : $@convention(thin) (@thick goo.Type) -> @owned goo // user: %8 %7 = metatype $@thick goo.Type // user: %8 %8 = apply %6(%7) : $@convention(thin) (@thick goo.Type) -> @owned goo // users: %9, %10 - store %8 to %1#1 : $*goo // id: %9 + store %8 to %1 : $*goo // id: %9 strong_release %8 : $goo // id: %10 strong_release %4 : $boo // id: %11 %12 = tuple () // user: %15 - dealloc_stack %1#0 : $*@local_storage goo // id: %13 - dealloc_stack %0#0 : $*@local_storage boo // id: %14 + dealloc_stack %1 : $*goo // id: %13 + dealloc_stack %0 : $*boo // id: %14 return %12 : $() // id: %15 } @@ -243,7 +243,7 @@ bb0: // CHECK: NoAlias // Next check that Int8 addresses can only alias Int8 addresses and raw -// pointers. This includes ensuring that Int8 can not alias Int32 addresses. +// pointers. This includes ensuring that Int8 cannot alias Int32 addresses. // CHECK: PAIR #184. // CHECK: (1): %3 = alloc_box $Builtin.Int8 // CHECK: (1): %4 = alloc_box $Builtin.Int32 @@ -287,7 +287,7 @@ bb0: // Finally conclude by checking that FPIEEE32 addresses only can alias raw // pointer addresses and other FPIEEE32 addresses. Again this includes proving -// that FPIEEE64 addresses can not alias FPIEEE32. +// that FPIEEE64 addresses cannot alias FPIEEE32. // CHECK: PAIR #266. // CHECK: (1): %5 = alloc_box $Builtin.FPIEEE32 // CHECK: (1): %6 = alloc_box $Builtin.FPIEEE64 diff --git a/test/SILPasses/unexpected_error.sil b/test/SILOptimizer/unexpected_error.sil similarity index 100% rename from test/SILPasses/unexpected_error.sil rename to test/SILOptimizer/unexpected_error.sil diff --git a/test/SILPasses/unreachable_code.swift b/test/SILOptimizer/unreachable_code.swift similarity index 96% rename from test/SILPasses/unreachable_code.swift rename to test/SILOptimizer/unreachable_code.swift index b56bd09063353..9f3a0b0bafc37 100644 --- a/test/SILPasses/unreachable_code.swift +++ b/test/SILOptimizer/unreachable_code.swift @@ -22,7 +22,7 @@ func userCode() {} func whileTrue() { var x = 0 while true { // expected-note {{always evaluates to true}} - x++ + x += 1 } userCode() // expected-warning {{will never be executed}} } @@ -38,9 +38,9 @@ func whileTrueReachable(v: Int) -> () { if v == 0 { break } - x++ + x += 1 } - x-- + x -= 1 } func whileTrueTwoPredecessorsEliminated() -> () { @@ -49,7 +49,7 @@ func whileTrueTwoPredecessorsEliminated() -> () { if false { break } - x++ + x += 1 } userCode() // expected-warning {{will never be executed}} } @@ -119,36 +119,36 @@ func testSwitchEnum(xi: Int) -> Int { case .One: userCode() // expected-note {{will never be executed}} case .Two: - x-- + x -= 1 case .Three: - x-- + x -= 1 } switch cond { // no warning default: - x++ + x += 1 } switch cond { // no warning case .Two: - x++ + x += 1 } switch cond { case .One: - x++ + x += 1 } // expected-error{{switch must be exhaustive}} switch cond { case .One: - x++ + x += 1 case .Three: - x++ + x += 1 } // expected-error{{switch must be exhaustive}} switch cond { // expected-warning{{switch condition evaluates to a constant}} case .Two: - x++ + x += 1 default: userCode() // expected-note{{will never be executed}} } @@ -157,10 +157,10 @@ func testSwitchEnum(xi: Int) -> Int { case .One: userCode() // expected-note{{will never be executed}} default: - x-- + x -= 1 } - return x; + return x } @@ -183,24 +183,24 @@ func testSwitchEnumBool(b: Bool, xi: Int) -> Int { switch Cond { // no warning default: - x++ + x += 1 } switch Cond { case true: - x++ + x += 1 } // expected-error{{switch must be exhaustive}} switch Cond { case false: - x++ + x += 1 } // expected-error{{switch must be exhaustive}} switch Cond { // no warning case true: - x++ + x += 1 case false: - x-- + x -= 1 } return x @@ -210,18 +210,18 @@ func testSwitchOptionalBool (b:Bool?, xi: Int) -> Int { var x = xi switch b { // No warning case .Some(true): - x++ + x += 1 case .Some(false): - x++ + x += 1 case .None: - x-- + x -= 1 } switch b { case .Some(true): - x++ + x += 1 case .None: - x-- + x -= 1 } // expected-error{{switch must be exhaustive}} return xi @@ -235,32 +235,32 @@ func testSwitchEnumBoolTuple(b1: Bool, b2: Bool, xi: Int) -> Int { switch Cond { // no warning default: - x++ + x += 1 } switch Cond { case (true, true): - x++ + x += 1 // FIXME: Two expect statements are written, because unreachable diagnostics produces N errors // for non-exhaustive switches on tuples of N elements } // expected-error{{switch must be exhaustive}} expected-error{{switch must be exhaustive}} switch Cond { case (false, true): - x++ + x += 1 // FIXME: Two expect statements are written, because unreachable diagnostics produces N errors // for non-exhaustive switches on tuples of N elements } // expected-error{{switch must be exhaustive}} expected-error{{switch must be exhaustive}} switch Cond { // no warning case (true, true): - x++ + x += 1 case (true, false): - x++ + x += 1 case (false, true): - x-- + x -= 1 case (false, false): - x-- + x -= 1 } return x diff --git a/test/SILPasses/unused_containers.swift b/test/SILOptimizer/unused_containers.swift similarity index 100% rename from test/SILPasses/unused_containers.swift rename to test/SILOptimizer/unused_containers.swift diff --git a/test/SILPasses/verifier.sil b/test/SILOptimizer/verifier.sil similarity index 80% rename from test/SILPasses/verifier.sil rename to test/SILOptimizer/verifier.sil index 75e3fde0dca9b..4d65b1b8ed47a 100644 --- a/test/SILPasses/verifier.sil +++ b/test/SILOptimizer/verifier.sil @@ -6,7 +6,7 @@ import Builtin -// Don't fail in the verifier on an shared unreachable exit block of two loops. +// Don't fail in the verifier on a shared unreachable exit block of two loops. sil @dont_fail: $@convention(thin) (Builtin.Int1) -> () { bb0(%0 : $Builtin.Int1): %2 = integer_literal $Builtin.Int1, -1 @@ -18,7 +18,7 @@ bb1: cond_br %0, bb2, bb3 bb2: - dealloc_stack %4#0 : $*@local_storage Builtin.Int32 + dealloc_stack %4 : $*Builtin.Int32 cond_br %0, bb4, bb1 // Cloned loop. @@ -27,7 +27,7 @@ bb5: cond_br %0, bb6, bb3 bb6: - dealloc_stack %6#0 : $*@local_storage Builtin.Int32 + dealloc_stack %6 : $*Builtin.Int32 cond_br %0, bb4, bb5 // Shared unreachable exit block. @@ -52,7 +52,7 @@ bb1: cond_br %0, bb2, bb3 bb2: - dealloc_stack %4#0 : $*@local_storage Builtin.Int32 + dealloc_stack %4 : $*Builtin.Int32 cond_br %0, bb4, bb1 // Cloned loop. @@ -61,7 +61,7 @@ bb5: cond_br %0, bb6, bb3 bb6: - dealloc_stack %6#0 : $*@local_storage Builtin.Int32 + dealloc_stack %6 : $*Builtin.Int32 cond_br %0, bb4, bb5 // Shared unreachable exit block. diff --git a/test/SILPasses/verifier_reject.sil b/test/SILOptimizer/verifier_reject.sil similarity index 88% rename from test/SILPasses/verifier_reject.sil rename to test/SILOptimizer/verifier_reject.sil index 845faf48b17b9..28fb40fe02aa7 100644 --- a/test/SILPasses/verifier_reject.sil +++ b/test/SILOptimizer/verifier_reject.sil @@ -21,7 +21,7 @@ bb1: cond_br %0, bb2, bb3 bb2: - dealloc_stack %4#0 : $*@local_storage Builtin.Int32 + dealloc_stack %4 : $*Builtin.Int32 cond_br %0, bb4, bb1 // Cloned loop. @@ -30,7 +30,7 @@ bb5: cond_br %0, bb6, bb3 bb6: - dealloc_stack %6#0 : $*@local_storage Builtin.Int32 + dealloc_stack %6 : $*Builtin.Int32 cond_br %0, bb4, bb5 // Shared partially unreachable exit block. diff --git a/test/SILPasses/capture_promotion.swift b/test/SILPasses/capture_promotion.swift deleted file mode 100644 index ce3d891e5705b..0000000000000 --- a/test/SILPasses/capture_promotion.swift +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %target-swift-frontend %s -emit-sil -o - -verify | FileCheck %s - -class Foo { - func foo() -> Int { - return 1 - } -} - -class Bar { -} - -struct Baz { - var bar = Bar() - var x = 42 -} - -// CHECK: sil hidden @_TF17capture_promotion22test_capture_promotionFT_FT_Si -func test_capture_promotion() -> () -> Int { - var x : Int = 1; x = 1 - var y : Foo = Foo(); y = Foo() - var z : Baz = Baz(); z = Baz() - -// CHECK-NOT: alloc_box - -// CHECK: [[CLOSURE0_PROMOTE0:%.*]] = function_ref @_TTSf2d_i_d_i_d_i___TFF17capture_promotion22test_capture_promotionFT_FT_SiU_FT_Si -// CHECK: partial_apply [[CLOSURE0_PROMOTE0]]({{%[0-9]*}}, {{%[0-9]*}}, {{%[0-9]*}}) - - return { x + y.foo() + z.x } -} - -// CHECK: sil shared @_TTSf2d_i_d_i_d_i___TFF17capture_promotion22test_capture_promotionFT_FT_SiU_FT_Si : $@convention(thin) (Int, @owned Foo, @owned Baz) -> Int - diff --git a/test/SILPasses/capture_promotion_reachability.sil b/test/SILPasses/capture_promotion_reachability.sil deleted file mode 100644 index 095aec3daf2a6..0000000000000 --- a/test/SILPasses/capture_promotion_reachability.sil +++ /dev/null @@ -1,311 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -capture-promotion | FileCheck %s - -sil_stage raw - -import Builtin -import Swift - -// top_level_code -sil private @top_level_code : $() -> () { -bb0: - %0 = tuple () - return %0 : $() -} - -/* -func test_reachability_1(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) { - if (b) { - x = y - } - var t : () -> Builtin.Int64 = { x } // promotable - if (b) { - t = { x } // promotable - } -} -*/ - -// CHECK-LABEL: sil @test_reachability_1 -sil @test_reachability_1 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () { -bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64): - %3 = alloc_box $Builtin.Int1 - %4 = alloc_box $Builtin.Int64 - %5 = alloc_box $Builtin.Int64 - store %0 to %3#1 : $*Builtin.Int1 - store %1 to %4#1 : $*Builtin.Int64 - store %2 to %5#1 : $*Builtin.Int64 - %9 = load %3#1 : $*Builtin.Int1 - cond_br %9, bb1, bb2 - -bb1: - %11 = load %5#1 : $*Builtin.Int64 - assign %11 to %4#1 : $*Builtin.Int64 - br bb2 - -bb2: - %14 = alloc_box $@callee_owned () -> Builtin.Int64 - // CHECK: [[CLOSURE0_PROMOTE0:%.*]] = function_ref @_TTSf2d_i__closure0 : - %15 = function_ref @closure0 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - strong_retain %4#0 : $@box Builtin.Int64 - // CHECK: partial_apply [[CLOSURE0_PROMOTE0]]({{%.*}}) - %17 = partial_apply %15(%4#0, %4#1) : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - store %17 to %14#1 : $*@callee_owned () -> Builtin.Int64 - %19 = load %3#1 : $*Builtin.Int1 - cond_br %19, bb3, bb4 - -bb3: - // CHECK: [[CLOSURE1_PROMOTE0:%.*]] = function_ref @_TTSf2d_i__closure1 : - %21 = function_ref @closure1 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - strong_retain %4#0 : $@box Builtin.Int64 - // CHECK: partial_apply [[CLOSURE1_PROMOTE0]]({{%.*}}) - %23 = partial_apply %21(%4#0, %4#1) : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - assign %23 to %14#1 : $*@callee_owned () -> Builtin.Int64 - br bb4 - -bb4: - strong_release %14#0 : $@box @callee_owned () -> Builtin.Int64 - strong_release %5#0 : $@box Builtin.Int64 - strong_release %4#0 : $@box Builtin.Int64 - strong_release %3#0 : $@box Builtin.Int1 - %30 = tuple () - return %30 : $() -} - -// closure0 -sil private @closure0 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 { -bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64): - %2 = tuple () - %3 = load %1 : $*Builtin.Int64 - strong_release %0 : $@box Builtin.Int64 - return %3 : $Builtin.Int64 -} - -// closure1 -sil private @closure1 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 { -bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64): - %2 = tuple () - %3 = load %1 : $*Builtin.Int64 - strong_release %0 : $@box Builtin.Int64 - return %3 : $Builtin.Int64 -} - -/* -func test_reachability_2(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) { - var t : () -> Builtin.Int64 = { x } // unpromotable - if (b) { - x = y - } - if (b) { - t = { x } // promotable - } -} -*/ - -// CHECK-LABEL: sil @test_reachability_2 -sil @test_reachability_2 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () { -bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64): - %3 = alloc_box $Builtin.Int1 - %4 = alloc_box $Builtin.Int64 - %5 = alloc_box $Builtin.Int64 - store %0 to %3#1 : $*Builtin.Int1 - store %1 to %4#1 : $*Builtin.Int64 - store %2 to %5#1 : $*Builtin.Int64 - %9 = alloc_box $@callee_owned () -> Builtin.Int64 - // CHECK: [[CLOSURE2:%.*]] = function_ref @closure2 : - %10 = function_ref @closure2 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - strong_retain %4#0 : $@box Builtin.Int64 - // CHECK: partial_apply [[CLOSURE2]]({{%.*}}, {{%.*}}) - %12 = partial_apply %10(%4#0, %4#1) : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - store %12 to %9#1 : $*@callee_owned () -> Builtin.Int64 - %14 = load %3#1 : $*Builtin.Int1 - cond_br %14, bb1, bb2 - -bb1: - %16 = load %5#1 : $*Builtin.Int64 - assign %16 to %4#1 : $*Builtin.Int64 - br bb2 - -bb2: - %19 = load %3#1 : $*Builtin.Int1 - cond_br %19, bb3, bb4 - -bb3: - // CHECK: [[CLOSURE3_PROMOTE0:%.*]] = function_ref @_TTSf2d_i__closure3 : - %21 = function_ref @closure3 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - strong_retain %4#0 : $@box Builtin.Int64 - // CHECK: partial_apply [[CLOSURE3_PROMOTE0]]({{%.*}}) - %23 = partial_apply %21(%4#0, %4#1) : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - assign %23 to %9#1 : $*@callee_owned () -> Builtin.Int64 - br bb4 - -bb4: - strong_release %9#0 : $@box @callee_owned () -> Builtin.Int64 - strong_release %5#0 : $@box Builtin.Int64 - strong_release %4#0 : $@box Builtin.Int64 - strong_release %3#0 : $@box Builtin.Int1 - %30 = tuple () - return %30 : $() -} - -// closure2 -sil private @closure2 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 { -bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64): - %2 = tuple () - %3 = load %1 : $*Builtin.Int64 - strong_release %0 : $@box Builtin.Int64 - return %3 : $Builtin.Int64 -} - -// closure3 -sil private @closure3 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 { -bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64): - %2 = tuple () - %3 = load %1 : $*Builtin.Int64 - strong_release %0 : $@box Builtin.Int64 - return %3 : $Builtin.Int64 -} - -/* -func test_reachability_3(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) { - var t : () -> Builtin.Int64 = { x } // unpromotable - if (b) { - t = { x } // unpromotable - } - if (b) { - x = y - } -} -*/ - -// CHECK-LABEL: sil @test_reachability_3 -sil @test_reachability_3 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () { -bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64): - %3 = alloc_box $Builtin.Int1 - %4 = alloc_box $Builtin.Int64 - %5 = alloc_box $Builtin.Int64 - store %0 to %3#1 : $*Builtin.Int1 - store %1 to %4#1 : $*Builtin.Int64 - store %2 to %5#1 : $*Builtin.Int64 - %9 = alloc_box $@callee_owned () -> Builtin.Int64 - // CHECK: [[CLOSURE4:%.*]] = function_ref @closure4 : - %10 = function_ref @closure4 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - strong_retain %4#0 : $@box Builtin.Int64 - // CHECK: partial_apply [[CLOSURE4]]({{%.*}}, {{%.*}}) - %12 = partial_apply %10(%4#0, %4#1) : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - store %12 to %9#1 : $*@callee_owned () -> Builtin.Int64 - %14 = load %3#1 : $*Builtin.Int1 - cond_br %14, bb1, bb2 - -bb1: - // CHECK: [[CLOSURE5:%.*]] = function_ref @closure5 : - %16 = function_ref @closure5 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - strong_retain %4#0 : $@box Builtin.Int64 - // CHECK: partial_apply [[CLOSURE5]]({{%.*}}, {{%.*}}) - %18 = partial_apply %16(%4#0, %4#1) : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - assign %18 to %9#1 : $*@callee_owned () -> Builtin.Int64 - br bb2 - -bb2: - %21 = load %3#1 : $*Builtin.Int1 - cond_br %21, bb3, bb4 - -bb3: - %23 = load %5#1 : $*Builtin.Int64 - assign %23 to %4#1 : $*Builtin.Int64 - br bb4 - -bb4: - strong_release %9#0 : $@box @callee_owned () -> Builtin.Int64 - strong_release %5#0 : $@box Builtin.Int64 - strong_release %4#0 : $@box Builtin.Int64 - strong_release %3#0 : $@box Builtin.Int1 - %30 = tuple () - return %30 : $() -} - -// closure4 -sil private @closure4 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 { -bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64): - %2 = tuple () - %3 = load %1 : $*Builtin.Int64 - strong_release %0 : $@box Builtin.Int64 - return %3 : $Builtin.Int64 -} - -// closure5 -sil private @closure5 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 { -bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64): - %2 = tuple () - %3 = load %1 : $*Builtin.Int64 - strong_release %0 : $@box Builtin.Int64 - return %3 : $Builtin.Int64 -} - -/* -func test_reachability_4(b: Builtin.Int1, x: Builtin.Int64, y: Builtin.Int64) { - var t : () -> Builtin.Int64 = { x } // unpromotable - while (b) { - x = y - t = { x } // unpromotable - } -} -*/ - -// CHECK-LABEL: sil @test_reachability_4 -sil @test_reachability_4 : $@convention(thin) (Builtin.Int1, Builtin.Int64, Builtin.Int64) -> () { -bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64, %2 : $Builtin.Int64): - %3 = alloc_box $Builtin.Int1 - %4 = alloc_box $Builtin.Int64 - %5 = alloc_box $Builtin.Int64 - store %0 to %3#1 : $*Builtin.Int1 - store %1 to %4#1 : $*Builtin.Int64 - store %2 to %5#1 : $*Builtin.Int64 - %9 = alloc_box $@callee_owned () -> Builtin.Int64 - // CHECK: [[CLOSURE6:%.*]] = function_ref @closure6 : - %10 = function_ref @closure6 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - strong_retain %4#0 : $@box Builtin.Int64 - // CHECK: partial_apply [[CLOSURE6]]({{%.*}}, {{%.*}}) - %12 = partial_apply %10(%4#0, %4#1) : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - store %12 to %9#1 : $*@callee_owned () -> Builtin.Int64 - br bb1 - -bb1: - %15 = load %3#1 : $*Builtin.Int1 - cond_br %15, bb2, bb3 - -bb2: - %17 = load %5#1 : $*Builtin.Int64 - assign %17 to %4#1 : $*Builtin.Int64 - // CHECK: [[CLOSURE7:%.*]] = function_ref @closure7 : - %19 = function_ref @closure7 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - strong_retain %4#0 : $@box Builtin.Int64 - // CHECK: partial_apply [[CLOSURE7]]({{%.*}}, {{%.*}}) - %21 = partial_apply %19(%4#0, %4#1) : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 - assign %21 to %9#1 : $*@callee_owned () -> Builtin.Int64 - br bb1 - -bb3: - strong_release %9#0 : $@box @callee_owned () -> Builtin.Int64 - strong_release %5#0 : $@box Builtin.Int64 - strong_release %4#0 : $@box Builtin.Int64 - strong_release %3#0 : $@box Builtin.Int1 - %28 = tuple () - return %28 : $() -} - -// closure6 -sil private @closure6 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 { -bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64): - %2 = tuple () - %3 = load %1 : $*Builtin.Int64 - strong_release %0 : $@box Builtin.Int64 - return %3 : $Builtin.Int64 -} - -// closure7 -sil private @closure7 : $@convention(thin) (@owned @box Builtin.Int64, @inout Builtin.Int64) -> Builtin.Int64 { -bb0(%0 : $@box Builtin.Int64, %1 : $*Builtin.Int64): - %2 = tuple () - %3 = load %1 : $*Builtin.Int64 - strong_release %0 : $@box Builtin.Int64 - return %3 : $Builtin.Int64 -} diff --git a/test/SILPasses/closure_specialize.sil b/test/SILPasses/closure_specialize.sil deleted file mode 100644 index 2e8d9c985b92c..0000000000000 --- a/test/SILPasses/closure_specialize.sil +++ /dev/null @@ -1,222 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -closure-specialize %s | FileCheck %s - -import Builtin -import Swift - -// CHECK-LABEL: sil [noinline] @_TTSf1cl35_TFF7specgen6callerFSiT_U_FTSiSi_T_Si___TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (Int) -> () { -// CHECK: bb0(%0 : $Int) -// CHECK: function_ref @_TFF7specgen6callerFSiT_U_FTSiSi_T_ -// CHECK: partial_apply - -// CHECK-LABEL: sil [noinline] @_TTSf1cl27_TF7specgen6calleeFTSiSi_T____TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) () -> () { -// CHECK-NEXT: bb0: -// CHECK: [[FUN:%.*]] = function_ref @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () -// CHECK: thin_to_thick_function [[FUN]] : $@convention(thin) (Int, Int) -> () to $@callee_owned (Int, Int) -> () - -// CHECK-LABEL: sil [noinline] @_TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () { -sil [noinline] @_TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () { -bb0(%0 : $@callee_owned (Int, Int) -> ()): - %1 = alloc_stack $Int - %2 = load %1#1 : $*Int - %3 = apply %0(%2, %2) : $@callee_owned (Int, Int) -> () - dealloc_stack %1#0 : $*@local_storage Int - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil [noinline] @_TTSf1cl35_TFF7specgen6callerFSiT_U_FTSiSi_T_Si___TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (Int) -> () { -// CHECK: bb0(%0 : $Int) -// CHECK: [[FUN:%.*]] = function_ref @_TFF7specgen6callerFSiT_U_FTSiSi_T_ -// CHECK: partial_apply [[FUN]]( - -// CHECK-LABEL: sil [noinline] @_TTSf1cl27_TF7specgen6calleeFTSiSi_T____TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) () -> () { -// CHECK-NEXT: bb0: -// CHECK: [[FUN:%.*]] = function_ref @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () -// CHECK: thin_to_thick_function [[FUN]] : $@convention(thin) (Int, Int) -> () to $@callee_owned (Int, Int) -> () - -// CHECK-LABEL: sil [noinline] @_TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () { -sil [noinline] @_TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () { -bb0(%0 : $@callee_owned (Int, Int) -> ()): - %1 = alloc_stack $Int - %2 = load %1#1 : $*Int - %3 = apply %0(%2, %2) : $@callee_owned (Int, Int) -> () - dealloc_stack %1#0 : $*@local_storage Int - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil [noinline] @_TF7specgen6calleeFTSiSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () { -// specgen.callee (Swift.Int, Swift.Int, Swift.Int) -> () -sil [noinline] @_TF7specgen6calleeFTSiSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () { -bb0(%0 : $Int, %1 : $Int, %2 : $Int): - %6 = tuple () // user: %7 - return %6 : $() // id: %7 -} - -// CHECK-LABEL: sil @_TF7specgen6callerFSiT_ : $@convention(thin) (Int) -> () { -// CHECK: [[ID1:%[0-9]+]] = function_ref @_TTSf1cl35_TFF7specgen6callerFSiT_U_FTSiSi_T_Si___TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (Int) -> () -// CHECK: [[ID2:%[0-9]+]] = function_ref @_TTSf1cl35_TFF7specgen6callerFSiT_U_FTSiSi_T_Si___TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (Int) -> () -// CHECK: apply [[ID2]](%0) : $@convention(thin) (Int) -> () -// CHECK: apply [[ID1]](%0) : $@convention(thin) (Int) -> () -sil @_TF7specgen6callerFSiT_ : $@convention(thin) (Int) -> () { -bb0(%0 : $Int): - // function_ref specgen.take_closure ((Swift.Int, Swift.Int) -> ()) -> () - %2 = function_ref @_TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () // user: %5 - // function_ref specgen.(caller (Swift.Int) -> ()).(closure #1) - %3 = function_ref @_TFF7specgen6callerFSiT_U_FTSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () // user: %4 - %4 = partial_apply %3(%0) : $@convention(thin) (Int, Int, Int) -> () // user: %5 - strong_retain %4 : $@callee_owned (Int, Int) -> () - %5 = apply %2(%4) : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () - %6 = function_ref @_TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () // user: %5 - strong_retain %4 : $@callee_owned (Int, Int) -> () - %7 = apply %6(%4) : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () - strong_release %4 : $@callee_owned (Int, Int) -> () - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil shared @_TFF7specgen6callerFSiT_U_FTSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () { -sil shared @_TFF7specgen6callerFSiT_U_FTSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () { -bb0(%0 : $Int, %1 : $Int, %2 : $Int): - %5 = alloc_box $Int // var p // users: %6, %10, %14 - store %0 to %5#1 : $*Int // id: %6 - %7 = alloc_box $Int // var q // users: %8, %11, %13 - store %1 to %7#1 : $*Int // id: %8 - // function_ref specgen.callee (Swift.Int, Swift.Int, Swift.Int) -> () - %9 = function_ref @_TF7specgen6calleeFTSiSiSi_T_ : $@convention(thin) (Int, Int, Int) -> () // user: %12 - %10 = load %5#1 : $*Int // user: %12 - %11 = load %7#1 : $*Int // user: %12 - %12 = apply %9(%10, %11, %2) : $@convention(thin) (Int, Int, Int) -> () - strong_release %7#0 : $@box Int - strong_release %5#0 : $@box Int - %15 = tuple () // user: %16 - return %15 : $() // id: %16 -} - -////////////////////////////////// -// Thin To Thick Function Tests // -////////////////////////////////// - -// CHECK-LABEL: sil [noinline] @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () { -// specgen.callee (Swift.Int, Swift.Int) -> () -sil [noinline] @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () { -bb0(%0 : $Int, %1 : $Int): - %6 = tuple () // user: %7 - return %6 : $() // id: %7 -} - -// CHECK-LABEL: sil @_TF7specgen11tttficallerFSiT_ : $@convention(thin) (Int) -> () { -// CHECK: [[ID1:%[0-9]+]] = function_ref @_TTSf1cl27_TF7specgen6calleeFTSiSi_T____TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) () -> () -// CHECK: [[ID2:%[0-9]+]] = function_ref @_TTSf1cl27_TF7specgen6calleeFTSiSi_T____TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) () -> () -// CHECK: apply [[ID2]]() : $@convention(thin) () -> () -// CHECK: apply [[ID1]]() : $@convention(thin) () -> () -sil @_TF7specgen11tttficallerFSiT_ : $@convention(thin) (Int) -> () { -bb0(%0 : $Int): - // function_ref specgen.take_closure ((Swift.Int, Swift.Int) -> ()) -> () - %2 = function_ref @_TF7specgen12take_closureFFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () // user: %5 - // function_ref specgen.(caller (Swift.Int) -> ()).(closure #1) - %3 = function_ref @_TF7specgen6calleeFTSiSi_T_ : $@convention(thin) (Int, Int) -> () // user: %4 - %4 = thin_to_thick_function %3 : $@convention(thin) (Int, Int) -> () to $@callee_owned (Int, Int) -> () // user: %5 - %5 = apply %2(%4) : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () - %6 = function_ref @_TF7specgen13take_closure2FFTSiSi_T_T_ : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () - %7 = apply %6(%4) : $@convention(thin) (@owned @callee_owned (Int, Int) -> ()) -> () - %9999 = tuple () // user: %7 - return %9999 : $() // id: %7 -} - -// We don't handle closures that close over address types (*NOTE* this includes -// address and non-address only types). This is a temporary limitation. -// CHECK-LABEL: sil @address_closure : $@convention(thin) (@in Int) -> () { -sil @address_closure : $@convention(thin) (@in Int) -> () { -bb0(%0 : $*Int): - %6 = tuple() - return %6 : $() -} - -// CHECK-LABEL: sil @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () { -sil @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () { -bb0(%0 : $@callee_owned () -> ()): - %1 = apply %0() : $@callee_owned () -> () - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @address_caller : $@convention(thin) (@in Int) -> () { -// CHECK-NOT: _TTSf1cl15address_closureSi__address_closure_user -sil @address_caller : $@convention(thin) (@in Int) -> () { -bb0(%0 : $*Int): - %1 = function_ref @address_closure : $@convention(thin) (@in Int) -> () - %2 = partial_apply %1(%0) : $@convention(thin) (@in Int) -> () - %3 = function_ref @address_closure_user : $@convention(thin) (@owned @callee_owned () -> ()) -> () - %4 = apply %3(%2) : $@convention(thin) (@owned @callee_owned () -> ()) -> () - %9999 = tuple() - return %9999 : $() -} - -class A {} - -sil hidden [noinline] @closure : $@convention(thin) (@owned A, @owned A) -> () { -bb0(%0 : $A, %1 : $A): - strong_release %1 : $A - strong_release %0 : $A - %4 = tuple () - return %4 : $() -} - -sil hidden [noinline] @use_closure : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> () { -bb0(%0 : $@callee_owned (@owned A) -> ()): - %1 = alloc_ref $A - %2 = apply %0(%1) : $@callee_owned (@owned A) -> () - %3 = tuple () - return %3 : $() -} - -// CHECK-LABEL: sil {{.*}} @different_execution_counts -// CHECK: bb0([[ARG:%.*]] : $A -// CHECK: strong_retain [[ARG]] -// CHECK-NOT: partial_apply -// CHECK: [[SPECIALIZED_CLOSURE_USER:%.*]] = function_ref @_TTS{{.*}}use_closure -// CHECK: retain_value [[ARG]] -// CHECK-NOT: partial_apply -// CHECK: integer_literal $Builtin.Int64, 0 -// CHECK: br bb2 - -// CHECK: bb1: -// CHECK: strong_release [[ARG]] -// CHECK: release_value [[ARG]] -// CHECK: return - -// CHECK: bb2({{.*}}): -// Match the partial_apply consume of arg. -// CHECK: retain_value [[ARG]] -// CHECK: apply [[SPECIALIZED_CLOSURE_USER]]([[ARG]]) -// CHECK: cond_br {{.*}}, bb1, bb3 - -sil hidden [noinline] @different_execution_counts : $@convention(thin) (@guaranteed A) -> () { -bb0(%0 : $A): - strong_retain %0 : $A - %2 = function_ref @closure : $@convention(thin) (@owned A, @owned A) -> () - %3 = partial_apply %2(%0) : $@convention(thin) (@owned A, @owned A) -> () - %4 = integer_literal $Builtin.Int64, 0 - %5 = integer_literal $Builtin.Int64, 5 - %6 = integer_literal $Builtin.Int64, 1 - %7 = integer_literal $Builtin.Int1, 0 - %8 = function_ref @use_closure : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> () - br bb2(%4 : $Builtin.Int64) - -bb1: - strong_release %3 : $@callee_owned (@owned A) -> () - %11 = tuple () - return %11 : $() - -bb2(%13 : $Builtin.Int64): - %14 = builtin "sadd_with_overflow_Int64"(%13 : $Builtin.Int64, %6 : $Builtin.Int64, %7 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) - %15 = tuple_extract %14 : $(Builtin.Int64, Builtin.Int1), 0 - strong_retain %3 : $@callee_owned (@owned A) -> () - %17 = apply %8(%3) : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> () - %18 = builtin "cmp_eq_Int64"(%15 : $Builtin.Int64, %5 : $Builtin.Int64) : $Builtin.Int1 - cond_br %18, bb1, bb3 - -bb3: - br bb2(%15 : $Builtin.Int64) -} diff --git a/test/SILPasses/copyforward.sil b/test/SILPasses/copyforward.sil deleted file mode 100644 index bc1ac47056818..0000000000000 --- a/test/SILPasses/copyforward.sil +++ /dev/null @@ -1,494 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -copy-forwarding -enable-copyforwarding -enable-destroyhoisting | FileCheck %s - -sil_stage canonical - -import Builtin -import Swift - -class AClass {} -sil @f_in : $@convention(thin) (@in T) -> () -sil @f_in_guaranteed : $@convention(thin) (@in_guaranteed T) -> () -sil @f_out : $@convention(thin) (@out T) -> () -sil @f_owned : $@convention(thin) (@owned T) -> () - -protocol P { - init(_ i : Int32) -}; - -// CHECK-LABEL: nrvo -// CHECK-NOT: copy_addr -// CHECK: return -sil hidden @nrvo : $@convention(thin) (@out T, Bool) -> () { -bb0(%0 : $*T, %1 : $Bool): - %2 = alloc_stack $T // var rvo // users: %9, %15, %17, %19 - debug_value_addr %0 : $*T - debug_value_addr %2#1 : $*T - %3 = struct_extract %1 : $Bool, #Bool._value // user: %4 - cond_br %3, bb1, bb2 // id: %4 - -bb1: // Preds: bb0 - %5 = metatype $@thick T.Type // user: %9 - %6 = witness_method $T, #P.init!allocator.1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () // user: %9 - %7 = integer_literal $Builtin.Int32, 10 // user: %8 - %8 = struct $Int32 (%7 : $Builtin.Int32) // user: %9 - %9 = apply %6(%2#1, %8, %5) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () - br bb3 // id: %10 - -bb2: // Preds: bb0 - %11 = metatype $@thick T.Type // user: %15 - %12 = witness_method $T, #P.init!allocator.1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () // user: %15 - %13 = integer_literal $Builtin.Int32, 1 // user: %14 - %14 = struct $Int32 (%13 : $Builtin.Int32) // user: %15 - %15 = apply %12(%2#1, %14, %11) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@out τ_0_0, Int32, @thick τ_0_0.Type) -> () - br bb3 // id: %16 - -bb3: // Preds: bb1 bb2 - copy_addr [take] %2#1 to [initialization] %0 : $*T // id: %17 - %18 = tuple () // user: %20 - debug_value_addr %0 : $*T - debug_value_addr %2#1 : $*T - dealloc_stack %2#0 : $*@local_storage T // id: %19 - return %18 : $() // id: %20 -} - -//CHECK-LABEL: forward_init -//CHECK-NOT: copy_addr -//CHECK-NOT: destroy_addr -//CHECK: return -sil hidden @forward_init : $@convention(thin) (@in T) -> () { -bb0(%0 : $*T): - debug_value_addr %0 : $*T - %l1 = alloc_stack $T - copy_addr %0 to [initialization] %l1#1 : $*T - %f1 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - %c1 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - debug_value_addr %l1#1 : $*T - dealloc_stack %l1#0 : $*@local_storage T - debug_value_addr %0 : $*T - destroy_addr %0 : $*T - %r1 = tuple () - return %r1 : $() -} - -//CHECK-LABEL: forward_noinit -//CHECK-NOT: copy_addr -//CHECK: destroy_addr -//CHECK: return -sil hidden @forward_noinit : $@convention(thin) (@in T) -> () { -bb0(%0 : $*T): - debug_value_addr %0 : $*T - %l1 = alloc_stack $T - %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - %c1 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - copy_addr %0 to %l1#1 : $*T - debug_value_addr %l1#1 : $*T - debug_value_addr %0 : $*T - %f2 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - %c2 = apply %f2(%l1#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - dealloc_stack %l1#0 : $*@local_storage T - destroy_addr %0 : $*T - %r1 = tuple () - return %r1 : $() -} - -//CHECK-LABEL: forward_takeinit -//CHECK-NOT: copy_addr -//CHECK-NOT: destroy_addr -//CHECK: return -sil hidden @forward_takeinit : $@convention(thin) (@in T) -> () { -bb0(%0 : $*T): - debug_value_addr %0 : $*T - %l1 = alloc_stack $T - copy_addr [take] %0 to [initialization] %l1#1 : $*T - %f1 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - %c1 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - debug_value_addr %0 : $*T - debug_value_addr %l1#1 : $*T - dealloc_stack %l1#0 : $*@local_storage T - %r1 = tuple () - return %r1 : $() -} - -//CHECK-LABEL: forward_takenoinit -//CHECK-NOT: copy_addr -//CHECK: destroy_addr -//CHECK: return -sil hidden @forward_takenoinit : $@convention(thin) (@in T) -> () { -bb0(%0 : $*T): - debug_value_addr %0 : $*T - %l1 = alloc_stack $T - %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - %c1 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - copy_addr [take] %0 to %l1#1 : $*T - %f2 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - %c2 = apply %f2(%l1#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - debug_value_addr %0 : $*T - debug_value_addr %l1#1 : $*T - dealloc_stack %l1#0 : $*@local_storage T - %r1 = tuple () - return %r1 : $() -} - -//CHECK-LABEL: backward_init -//CHECK-NOT: copy_addr -//CHECK-NOT: destroy_addr -//CHECK: return -sil hidden @backward_init : $@convention(thin) (@out T) -> () { -bb0(%0 : $*T): - %l1 = alloc_stack $T - %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - %c1 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - debug_value_addr %0 : $*T - debug_value_addr %l1#1 : $*T - copy_addr %l1#1 to [initialization] %0 : $*T - debug_value_addr %0 : $*T - debug_value_addr %l1#1 : $*T - destroy_addr %l1#1 : $*T - dealloc_stack %l1#0 : $*@local_storage T - %t = tuple () - return %t : $() -} - -//CHECK-LABEL: backward_noinit -//CHECK: copy_addr -//CHECK: destroy_addr -//CHECK: return -sil hidden @backward_noinit : $@convention(thin) (@out T) -> () { -bb0(%0 : $*T): - %l1 = alloc_stack $T - %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - %c1 = apply %f1(%0) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - %c2 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - copy_addr %l1#1 to %0 : $*T - destroy_addr %l1#1 : $*T - dealloc_stack %l1#0 : $*@local_storage T - %t = tuple () - return %t : $() -} - - -//CHECK-LABEL: backward_takeinit -//CHECK-NOT: copy_addr -//CHECK-NOT: destroy_addr -//CHECK: return -sil hidden @backward_takeinit : $@convention(thin) (@out T) -> () { -bb0(%0 : $*T): - %l1 = alloc_stack $T - %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - %c1 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - debug_value_addr %0 : $*T - debug_value_addr %l1#1 : $*T - copy_addr [take] %l1#1 to [initialization] %0 : $*T - debug_value_addr %0 : $*T - debug_value_addr %l1#1 : $*T - dealloc_stack %l1#0 : $*@local_storage T - %t = tuple () - return %t : $() -} - -//CHECK-LABEL: backward_takenoinit -//CHECK: copy_addr -//CHECK-NOT: destroy_addr -//CHECK: return -sil hidden @backward_takenoinit : $@convention(thin) (@out T) -> () { -bb0(%0 : $*T): - %l1 = alloc_stack $T - %f1 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - %c1 = apply %f1(%0) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - %c2 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - copy_addr [take] %l1#1 to %0 : $*T - dealloc_stack %l1#0 : $*@local_storage T - %t = tuple () - return %t : $() -} - -//CHECK-LABEL: branch -//CHECK-NOT: copy_addr -//CHECK: return -sil hidden @branch : $@convention(thin) (@in T, Bool) -> () { -bb0(%0 : $*T, %1 : $Bool): - %2 = struct_extract %1 : $Bool, #Bool._value // user: %3 - cond_br %2, bb1, bb2 // id: %3 - -bb1: // Preds: bb0 - %4 = function_ref @f_in : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () // user: %7 - %5 = alloc_stack $T // users: %6, %7, %8 - copy_addr %0 to [initialization] %5#1 : $*T // id: %6 - %7 = apply %4(%5#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - dealloc_stack %5#0 : $*@local_storage T // id: %8 - br bb2 // id: %9 - -bb2: // Preds: bb0 bb1 - destroy_addr %0 : $*T // id: %10 - %11 = tuple () // user: %12 - return %11 : $() // id: %12 -} - -enum A { - case Val(T) - init(_ val: T) -} - -sil [transparent] @_TFO8enuminit1A3ValU__fMGS0_Q__FQ_GS0_Q__ : $@convention(thin) (@out A, @in T, @thin A.Type) -> () - -//CHECK-LABEL: enuminit -//CHECK-NOT: copy_addr -//CHECK: return -sil @enuminit : $@convention(thin) (@out A, @in T, @thin A.Type) -> () { -bb0(%0 : $*A, %1 : $*T, %2 : $@thin A.Type): - %3 = alloc_stack $A // var self // users: %10, %14, %16 - // function_ref enuminit.A.Val (enuminit.A.Type)(A) -> enuminit.A - %4 = function_ref @_TFO8enuminit1A3ValU__fMGS0_Q__FQ_GS0_Q__ : $@convention(thin) <τ_0_0> (@out A<τ_0_0>, @in τ_0_0, @thin A<τ_0_0>.Type) -> () // user: %9 - %5 = metatype $@thin A.Type // user: %9 - %6 = alloc_stack $T // users: %7, %9, %12 - copy_addr %1 to [initialization] %6#1 : $*T // id: %7 - %8 = alloc_stack $A // users: %9, %10, %11 - %9 = apply %4(%8#1, %6#1, %5) : $@convention(thin) <τ_0_0> (@out A<τ_0_0>, @in τ_0_0, @thin A<τ_0_0>.Type) -> () - copy_addr [take] %8#1 to [initialization] %3#1 : $*A // id: %10 - dealloc_stack %8#0 : $*@local_storage A // id: %11 - dealloc_stack %6#0 : $*@local_storage T // id: %12 - destroy_addr %1 : $*T // id: %13 - copy_addr [take] %3#1 to [initialization] %0 : $*A // id: %14 - %15 = tuple () // user: %17 - dealloc_stack %3#0 : $*@local_storage A // id: %16 - return %15 : $() // id: %17 -} - -//CHECK-LABEL: make_addronly -//CHECK-NOT: copy_addr -//CHECK: return -sil hidden @make_addronly : $@convention(thin) (@out T) -> () { -bb0(%0 : $*T): - %1 = alloc_stack $T // let t // users: %3, %4, %5 - %2 = function_ref @f_out : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () // user: %3 - %3 = apply %2(%1#1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - copy_addr [take] %1#1 to [initialization] %0 : $*T // id: %4 - dealloc_stack %1#0 : $*@local_storage T // id: %5 - %6 = tuple () // user: %7 - return %6 : $() // id: %7 -} - -sil @_TFSq4SomeU__fMGSqQ__FQ_GSqQ__ : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0, @thin Optional<τ_0_0>.Type) -> () - -sil @_TFsoi2neU__FTGSqQ__Vs26_OptionalNilComparisonType_Sb : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, _OptionalNilComparisonType) -> Bool - -//CHECK-LABEL: option_init -//CHECK: alloc_stack -//CHECK: alloc_stack -//CHECK: alloc_stack -//CHECK: copy_addr -//CHECK: copy_addr -//CHECK-NOT: copy_addr -//CHECK: alloc_stack -//CHECK: alloc_stack -//CHECK: copy_addr -//CHECK-NOT: copy_addr -//CHECK: alloc_stack -//CHECK-NOT: copy_addr -//CHECK: copy_addr -//CHECK-NOT: copy_addr -//CHECK: alloc_stack -//CHECK-NOT: copy_addr -//CHECK: return -sil hidden @option_init : $@convention(thin) (@in AnyObject) -> () { -bb0(%0 : $*AnyObject): - %g0 = alloc_stack $GeneratorOfOne // 831 - %s0 = struct_element_addr %g0#1 : $*GeneratorOfOne, #GeneratorOfOne.elements - - %l0 = alloc_stack $Optional - // function_ref Swift.Optional.Some (Swift.Optional.Type)(A) -> Swift.Optional - %f0 = function_ref @_TFSq4SomeU__fMGSqQ__FQ_GSqQ__ : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0, @thin Optional<τ_0_0>.Type) -> () - %t0 = metatype $@thin Optional.Type - %i0 = apply %f0(%l0#1, %0, %t0) : $@convention(thin) <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0, @thin Optional<τ_0_0>.Type) -> () - - %g1 = alloc_stack $GeneratorOfOne // 850 - %s1 = struct_element_addr %g1#1 : $*GeneratorOfOne, #GeneratorOfOne.elements - // We can't backward propagate this yet because we can't analyze struct_element_addr copy dest. - copy_addr [take] %l0#1 to [initialization] %s1 : $*Optional - // We ignore this copy because its Def is used by struct_element_addr - copy_addr [take] %g1#1 to [initialization] %g0#1 : $*GeneratorOfOne - - %l1 = alloc_stack $Optional // 869 - - %l2 = alloc_stack $Optional // 873 - // We ignore this copy because its Def is used by struct_element_addr - copy_addr %s0 to [initialization] %l2#1 : $*Optional - - %l3 = alloc_stack $Optional // 877 - %o1 = enum $Optional, #Optional.None!enumelt - store %o1 to %l3#1 : $*Optional - // We can't backward propagate this yet because we can't analyze struct_element_addr copy dest. - copy_addr [take] %l3#1 to %s0 : $*Optional - dealloc_stack %l3#0 : $*@local_storage Optional - // We can't forward propagate this because l2 is deallocated, but we can backward propagate l1. - copy_addr [take] %l2#1 to [initialization] %l1#1 : $*Optional - dealloc_stack %l2#0 : $*@local_storage Optional - %l4 = alloc_stack $Optional // 889 - %o2 = load %l1#1 : $*Optional - store %o2 to %l4#1 : $*Optional - %s5 = struct $_OptionalNilComparisonType () - retain_value %o2 : $Optional - - %f1 = function_ref @_TFsoi2neU__FTGSqQ__Vs26_OptionalNilComparisonType_Sb : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, _OptionalNilComparisonType) -> Bool - %c5 = apply %f1(%l4#1, %s5) : $@convention(thin) <τ_0_0> (@in Optional<τ_0_0>, _OptionalNilComparisonType) -> Bool - dealloc_stack %l4#0 : $*@local_storage Optional - destroy_addr %l1#1 : $*Optional - dealloc_stack %l1#0 : $*@local_storage Optional - dealloc_stack %g1#0 : $*@local_storage GeneratorOfOne - dealloc_stack %l0#0 : $*@local_storage Optional - destroy_addr %g0#1 : $*GeneratorOfOne - dealloc_stack %g0#0 : $*@local_storage GeneratorOfOne - %p0 = tuple () - return %p0 : $() -} - -// Premature release of optional NSData -// after optimization -// -// Check that destroy is not hoisted above a retain of a transitively -// referenced object. -// -// CHECK-LABEL: load_nontrivial -// CHECK: load %0#1 : $*Optional -// CHECK-NOT: destroy_addr -// CHECK: unchecked_enum_data %{{.*}} : $Optional -// CHECK-NOT: destroy_addr -// CHECK: strong_retain %{{.*}} : $AClass -// CHECK: destroy_addr %0#1 -sil hidden @load_nontrivial : $@convention(thin) () -> () { -bb0: - %v0 = alloc_stack $Optional - %v1 = alloc_stack $Optional - - %f0 = function_ref @f_out : $@convention(thin) (@out A) -> () - %c0 = apply %f0(%v0#1) : $@convention(thin) <τ_0_0> (@out τ_0_0) -> () - - copy_addr %v0#1 to [initialization] %v1#1 : $*Optional - - %f1 = function_ref @f_in : $@convention(thin) (@in A) -> () - %c1 = apply %f1(%v1#1) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> () - - dealloc_stack %v1#0 : $*@local_storage Optional - %l1 = load %v0#1 : $*Optional - %d1 = unchecked_enum_data %l1 : $Optional, #Optional.Some!enumelt.1 - %f2 = function_ref @f_owned : $@convention(thin) (@owned A) -> () - %c2 = apply %f2(%d1) : $@convention(thin) <τ_0_0> (@owned τ_0_0) -> () - strong_retain %d1 : $AClass - destroy_addr %v0#1 : $*Optional - %34 = tuple () - dealloc_stack %v0#0 : $*@local_storage Optional - return %34 : $() -} - -// CHECK-LABEL: sil @nil_comparison -// CHECK: alloc_stack -// CHECK-NOT: copy_addr -// CHECK-NOT destroy_addr -// CHECK: switch_enum_addr %0 -// CHECK: [[D:%.*]] = unchecked_take_enum_data_addr %0 -// CHECK: destroy_addr [[D]] -// CHECK: return -sil @nil_comparison : $@convention(thin) (@in Optional) -> Bool { -bb0(%0 : $*Optional): - %2 = alloc_stack $Optional - copy_addr %0 to [initialization] %2#1 : $*Optional - destroy_addr %0 : $*Optional - switch_enum_addr %2#1 : $*Optional, case #Optional.Some!enumelt.1: bb1, case #Optional.None!enumelt: bb2 - -bb1: - %6 = unchecked_take_enum_data_addr %2#1 : $*Optional, #Optional.Some!enumelt.1 - destroy_addr %6 : $*T - %8 = integer_literal $Builtin.Int1, -1 - br bb3(%8 : $Builtin.Int1) - -bb2: - %10 = integer_literal $Builtin.Int1, 0 - br bb3(%10 : $Builtin.Int1) - -bb3(%12 : $Builtin.Int1): - %13 = struct $Bool (%12 : $Builtin.Int1) - dealloc_stack %2#0 : $*@local_storage Optional - return %13 : $Bool -} - -sil @use: $@convention(thin) (@inout T) -> () - -// We currently don't handle reasoning about multiple copy_addr instructions at -// once. With the current logic we must not optimize this case (we would have to -// prove that we can replace both copy_addr to be able to optimize). - -// CHECK-LABEL: sil @not_dominated_uses -// CHECK: alloc_stack -// CHECK: cond_br -// CHECK: bb1 -// CHECK: copy_addr -// CHECK: apply -// CHECK: br bb3 -// CHECK: bb2 -// CHECK: copy_addr -// CHECK: apply -// CHECK: br bb3 -// CHECK: bb3 -// CHECK: apply -// CHECK: destroy_addr - -sil @not_dominated_uses: $@convention(thin) (@in Optional, @in Optional, Bool) -> () { -bb0(%0 : $*Optional, %1 : $*Optional, %3 : $Bool): - %4 = alloc_stack $Optional - %5 = struct_extract %3 : $Bool, #Bool._value - %f = function_ref @use : $@convention(thin) (@inout T2) -> () - cond_br %5, bb1, bb2 - -bb1: - copy_addr [take] %0 to [initialization] %4#1 : $*Optional - %r1 = apply %f>(%4#1) : $@convention(thin) (@inout T2) -> () - br bb3 - -bb2: - copy_addr [take] %1 to [initialization] %4#1 : $*Optional - %r2 = apply %f>(%4#1) : $@convention(thin) (@inout T2) -> () - br bb3 - -bb3: - %r3 = apply %f>(%4#1) : $@convention(thin) (@inout T2) -> () - destroy_addr %4#1 : $*Optional - dealloc_stack %4#0 : $*@local_storage Optional - %13 = tuple() - return %13 : $() -} - -//CHECK-LABEL: test_in_guaranteed -//CHECK: copy_addr %1 to [initialization] -//CHECK-NOT: copy_addr -//CHECK-NOT: destroy_addr -//CHECK: return -sil hidden @test_in_guaranteed : $@convention(thin) (@out T, @in T) -> () { -bb0(%0 : $*T, %1 : $*T): - %l1 = alloc_stack $T - copy_addr %1 to [initialization] %l1#1 : $*T - %f1 = function_ref @f_in_guaranteed : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> () - %c2 = apply %f1(%l1#1) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> () - copy_addr %l1#1 to [initialization] %0 : $*T - destroy_addr %l1#1 : $*T - dealloc_stack %l1#0 : $*@local_storage T - %t = tuple () - return %t : $() -} - -// CHECK-LABEL: forward_unchecked_ref_cast_addr -// CHECK: unchecked_ref_cast_addr -// CHECK-NOT: copy_addr -// CHECK: return -sil hidden @forward_unchecked_ref_cast_addr : $@convention(thin) (@out AClass, @in AnyObject) -> () { -bb0(%0 : $*AClass, %1 : $*AnyObject): - %3 = alloc_stack $AnyObject // user: %10 - %4 = alloc_stack $AnyObject // user: %9 - %5 = alloc_stack $AClass // users: %6, %7, %8 - unchecked_ref_cast_addr AnyObject in %1 : $*AnyObject to AClass in %5#1 : $*AClass // id: %6 - copy_addr [take] %5#1 to [initialization] %0 : $*AClass // id: %7 - dealloc_stack %5#0 : $*@local_storage AClass // id: %8 - dealloc_stack %4#0 : $*@local_storage AnyObject // id: %9 - dealloc_stack %3#0 : $*@local_storage AnyObject // id: %10 - %11 = tuple () // user: %12 - return %11 : $() // id: %12 -} diff --git a/test/SILPasses/deadstoreelimination.sil b/test/SILPasses/deadstoreelimination.sil deleted file mode 100644 index e992b9ab42d9e..0000000000000 --- a/test/SILPasses/deadstoreelimination.sil +++ /dev/null @@ -1,1432 +0,0 @@ -// RUN: %target-sil-opt %s -dead-store-elim -enable-sil-verify-all | FileCheck %s - -sil_stage canonical - -import Builtin - -/////////////////////// -// Type Declarations // -/////////////////////// - -struct Int { - var value : Builtin.Int64 -} - -struct Int64 { - var value : Builtin.Int64 -} - -struct Bool { - var value : Builtin.Int1 -} - -struct A { - var i : Builtin.Int32 -} - -struct AA { - var a : A - var i : Builtin.Int32 -} - -struct S1 { - var a: Int - init(a: Int, b: Int) - init() -} - -struct S2 { - var x: S1 - var a: Int - var b: Int - init(x: S1, a: Int, b: Int) - init() -} - -struct S3 { - var a: Int - var b: Int - init(a: Int, b: Int) - init() -} - -struct S4 { - var a: Int - var b: Int - init(a: Int, b: Int) - init() -} - -struct S5 { - var x: S4 - var y: Int - init(x: S4, y: Int) - init() -} - -struct S6 { - var x: Int - var y: Int - var z: Int - init(x: Int, y: Int, z: Int) - init() -} - -struct S7 { - var x: Int - var y: Int - var z: Int - var a: Int - var b: Int - var c: Int - init(x: Int, y: Int, z: Int, a: Int, b: Int, c: Int) - init() -} - -class SelfLoop { - var a: SelfLoop - init() - deinit -} - -struct S8 { - var i: SelfLoop - var k: Int - init(i: SelfLoop, k: Int) - init() -} - -class foo { - var a: Int - deinit - init() -} - -class B { - var i : Builtin.Int32 - init() -} - -enum Example { - case A(Int64, Int64) - case B(Int64) - case C - case D -} - -sil @foo_user : $@convention(thin) (@guaranteed foo) -> () -sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1 -sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2 -sil @S3_init : $@convention(thin) (@thin S3.Type) -> S3 -sil @S5_init : $@convention(thin) (@thin S5.Type) -> S5 -sil @S6_init : $@convention(thin) (@thin S6.Type) -> S6 -sil @S7_init : $@convention(thin) (@thin S7.Type) -> S7 -sil @S8_init : $@convention(thin) (@thin S8.Type) -> @owned S8 -sil @escaped_a : $@convention(thin) () -> Builtin.RawPointer - -////////////////////////////////////////////////////////////// -// Tests for LoadStoreOpts.cpp from globalloadstoreopts.sil // -////////////////////////////////////////////////////////////// - -// TEST CASE CURRENTLY DISABLED. -// There is currently a outstand radar in the swift type/aa system, will -// take this flag off once thats fixed. -// -// We should be able to remove the local store that is not read. -// -// DISABLECHECK-LABEL: DeadLocalStoreSimpleStruct -// DISABLECHECK: bb0 -// DISABLECHECK-NOT: store -// DISABLECHECK: return -sil hidden @DeadLocalStoreSimpleStruct : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $Int // var a // users: %3, %5 - %1 = integer_literal $Builtin.Int64, 1 // user: %2 - %2 = struct $Int (%1 : $Builtin.Int64) // user: %3 - store %2 to %0#1 : $*Int // id: %3 - %4 = tuple () // user: %6 - dealloc_stack %0#0 : $*@local_storage Int // id: %5 - return %4 : $() // id: %6 -} - -// TEST CASE CURRENTLY DISABLED. -// There is currently a outstand radar in the swift type/aa system, will -// take this flag off once thats fixed. -// -// We can not remove the local store that is read. -// -// DISABLECHECK-LABEL: NoDeadLocalStoreSimpleStruct -// DISABLECHECK: bb0 -// DISABLECHECK: store -// DISABLECHECK: return -sil hidden @NoDeadLocalStoreSimpleStruct : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $Int // var a // users: %3, %5 - %1 = integer_literal $Builtin.Int64, 1 // user: %2 - %2 = struct $Int (%1 : $Builtin.Int64) // user: %3 - store %2 to %0#1 : $*Int // id: %3 - %4 = tuple () // user: %6 - %99 = load %0#1 : $*Int - dealloc_stack %0#0 : $*@local_storage Int // id: %5 - return %4 : $() // id: %6 -} - -// TEST CASE CURRENTLY DISABLED. -// There is currently a outstand radar in the swift type/aa system, will -// take this flag off once thats fixed. -// -// We can not remove the local store as the debug_value_addr could -// be turned to a debug_value and thus act as a read on the memory -// location.. -// -// DISABLECHECK-LABEL: NoDeadStoreDebugValueAddr -// DISABLECHECK: bb0 -// DISABLECHECK: store -// DISABLECHECK: debug_value_addr -sil hidden @NoDeadStoreDebugValueAddr : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $Int // var a // users: %3, %5 - %1 = integer_literal $Builtin.Int64, 1 // user: %2 - %2 = struct $Int (%1 : $Builtin.Int64) // user: %3 - store %2 to %0#1 : $*Int // id: %3 - debug_value_addr %0#1 : $*Int - %4 = tuple () // user: %6 - dealloc_stack %0#0 : $*@local_storage Int // id: %5 - return %4 : $() // id: %6 -} - -// CHECK-LABEL: sil @store_after_store -// CHECK: alloc_box -// CHECK-NEXT: store -// CHECK-NEXT: tuple -// CHECK: return -sil @store_after_store : $@convention(thin) (@owned B) -> () { -bb0(%0 : $B): - %1 = alloc_box $B - %2 = store %0 to %1#1 : $*B - %3 = store %0 to %1#1 : $*B - %4 = tuple() - %5 = return %4 : $() -} - -// CHECK-LABEL: sil @dead_store_elimination_over_noread_builtins -// CHECK: bb0 -// CHECK-NEXT: load -// CHECK-NEXT: integer_literal -// CHECK-NEXT: builtin -// CHECK-NEXT: tuple_extract -// CHECK-NEXT: store -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @dead_store_elimination_over_noread_builtins : $@convention(thin) (@inout Builtin.Int64, @inout Builtin.Int64) -> () { -bb0(%0 : $*Builtin.Int64, %1 : $*Builtin.Int64): - %2 = load %0 : $*Builtin.Int64 - %4 = integer_literal $Builtin.Int1, 0 - %5 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %2 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) - %6 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 0 - store %6 to %1 : $*Builtin.Int64 - %8 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %2 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) - %9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 0 - store %9 to %1 : $*Builtin.Int64 - %10 = tuple() - return %10 : $() -} - -// CHECK-LABEL: sil @post_dominating_dead_store : $@convention(thin) (@inout Builtin.Int32) -> () { -// CHECK: store -// CHECK-NOT: store -// CHECK: return -sil @post_dominating_dead_store : $@convention(thin) (@inout Builtin.Int32) -> () { -bb0(%0 : $*Builtin.Int32): - %1 = integer_literal $Builtin.Int32, 0 - store %1 to %0 : $*Builtin.Int32 - cond_br undef, bb1, bb2 - -bb1: - br bb3 - -bb2: - br bb3 - -bb3: - store %1 to %0 : $*Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @post_dominating_dead_store_partial : $@convention(thin) (@inout Builtin.Int32) -> () { -// CHECK: bb0( -// CHECK-NOT: store -// CHECK: bb1: -// CHECK_NOT: store -// CHECK: bb2: -// CHECK: bb3: -// CHECK: store -// CHECK: return -sil @post_dominating_dead_store_partial : $@convention(thin) (@inout Builtin.Int32) -> () { -bb0(%0 : $*Builtin.Int32): - %1 = integer_literal $Builtin.Int32, 0 - %2 = integer_literal $Builtin.Int32, 1 - %3 = integer_literal $Builtin.Int32, 2 - store %1 to %0 : $*Builtin.Int32 - cond_br undef, bb1, bb2 - -bb1: - store %2 to %0 : $*Builtin.Int32 - br bb3 - -bb2: - br bb3 - -bb3: - store %3 to %0 : $*Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// We can't eliminate any stores here. -// CHECK-LABEL: sil @post_dominating_dead_store_fail : $@convention(thin) (@inout Builtin.Int32) -> () { -// CHECK: store -// CHECK: store -// CHECK-NOT: store -// CHECK: return -sil @post_dominating_dead_store_fail : $@convention(thin) (@inout Builtin.Int32) -> () { -bb0(%0 : $*Builtin.Int32): - %1 = integer_literal $Builtin.Int32, 0 - %2 = integer_literal $Builtin.Int32, 1 - store %1 to %0 : $*Builtin.Int32 - cond_br undef, bb1, bb2 - -bb1: - store %2 to %0 : $*Builtin.Int32 - br bb2 - -bb2: - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @test_read_dependence_allows_forwarding : $@convention(thin) (@inout A, A) -> A { -// CHECK: bb0 -// CHECK-NEXT: store -// CHECK-NEXT: unchecked_addr_cast -// CHECK-NEXT: unchecked_addr_cast -// CHECK-NEXT: load -// CHECK-NEXT: store -// CHECK-NEXT: return -sil @test_read_dependence_allows_forwarding : $@convention(thin) (@inout A, A) -> A { -bb0(%0 : $*A, %1 : $A): - store %1 to %0 : $*A - %2 = unchecked_addr_cast %0 : $*A to $*A - %3 = unchecked_addr_cast %2 : $*A to $*A - // This means that the first store is not dead. - %4 = load %3 : $*A - store %1 to %0 : $*A - return %4 : $A -} - -// Make sure that we do not eliminate a partially dead store as if it -// was a full dead store. -// -// CHECK-LABEL: sil @partially_dead_store1 : $@convention(thin) (@inout AA, AA, A) -> () { -// CHECK: store -// CHECK: store -sil @partially_dead_store1 : $@convention(thin) (@inout AA, AA, A) -> () { -bb0(%0 : $*AA, %1 : $AA, %2 : $A): - store %1 to %0 : $*AA - %3 = unchecked_addr_cast %0 : $*AA to $*A - store %2 to %3 : $*A - %9999 = tuple() - return %9999 : $() -} - -// Make sure that we do not eliminate a partially dead store as if it -// was a full dead store. -// -// CHECK-LABEL: sil @partially_dead_store2 : $@convention(thin) (@inout AA, AA, A) -> () { -// CHECK: store -// CHECK: store -sil @partially_dead_store2 : $@convention(thin) (@inout AA, AA, A) -> () { -bb0(%0 : $*AA, %1 : $AA, %2 : $A): - store %1 to %0 : $*AA - %3 = struct_element_addr %0 : $*AA, #AA.a - store %2 to %3 : $*A - %9999 = tuple() - return %9999 : $() -} - -// Make sure that we properly eliminate the stores in bb1, bb2 from StoreMap. -// -// CHECK-LABEL: sil @store_map_failed_dead_object_elim_invalidation : $@convention(thin) () -> () { -// CHECK: bb1: -// CHECK: store -// CHECK: bb2: -// CHECK: store -// CHECK: bb3: -// CHECK: store -sil @store_map_failed_dead_object_elim_invalidation : $@convention(thin) () -> () { -bb0: - %0 = integer_literal $Builtin.Int32, 32 - %1 = integer_literal $Builtin.Int32, 64 - %2 = function_ref @escaped_a : $@convention(thin) () -> Builtin.RawPointer - %3 = apply %2() : $@convention(thin) () -> Builtin.RawPointer - %4 = pointer_to_address %3 : $Builtin.RawPointer to $*Builtin.Int32 - %5 = apply %2() : $@convention(thin) () -> Builtin.RawPointer - %6 = pointer_to_address %5 : $Builtin.RawPointer to $*Builtin.Int32 - cond_br undef, bb1, bb2 - -bb1: - store %0 to %4 : $*Builtin.Int32 - br bb3 - -bb2: - store %1 to %4 : $*Builtin.Int32 - br bb3 - -bb3: - store %0 to %6 : $*Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -////////////////////////////////////////////// -// Tests for GlobalDeadStoreElimination.cpp // -////////////////////////////////////////////// - -// We should be able to remove the store in bb0, but we currently -// cant due to deficiency in alias analysis. -// -// CHECK-LABEL: DeadStoreWithAliasingBasesSimpleClass -// CHECK: bb0([[RET0:%.+]] : $Bool): -// CHECK-NEXT: [[RET1:%.+]] = alloc_ref -// CHECK-NEXT: [[RET2:%.+]] = alloc_stack -// CHECK-NEXT: store [[RET1:%.+]] to [[RET2:%.+]] -// CHECK-NEXT: [[RET2:%.+]] = load -// CHECK-NEXT: [[RET3:%.+]] = integer_literal -// CHECK-NEXT: [[RET4:%.+]] = struct $Int -// CHECK-NEXT: [[RET5:%.+]] = ref_element_addr -// CHECK-NEXT: store [[RET4:%.+]] to [[RET5:%.+]] -// CHECK-NEXT: [[RET6:%.+]] = ref_element_addr -// CHECK-NEXT: store [[RET4:%.+]] to [[RET6:%.+]] -sil hidden @DeadStoreWithAliasingBasesSimpleClass : $@convention(thin) (Bool) -> () { -bb0(%0 : $Bool): - %1 = alloc_ref $foo // users: %3, %6 - %2 = alloc_stack $foo // users: %3, %8, %15 - store %1 to %2#1 : $*foo // id: %3 - %8 = load %2#1 : $*foo // user: %11 - %4 = integer_literal $Builtin.Int64, 12 // user: %5 - %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 - %6 = ref_element_addr %1 : $foo, #foo.a // user: %7 - store %5 to %6 : $*Int // id: %7 - %9 = ref_element_addr %8 : $foo, #foo.a // user: %12 - store %5 to %9 : $*Int // id: %12 - br bb1 // id: %13 - -bb1: // Preds: bb0 - %14 = tuple () // user: %16 - dealloc_stack %2#0 : $*@local_storage foo // id: %15 - return %14 : $() // id: %16 -} - -// Remove dead stores in if-else block on a simple struct as there are stores -// in the joint block. -// -// CHECK-LABEL: DeadStoreInIfElseBlockSimpleStruct -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: br -// CHECK: bb2: -// CHECK-NOT: store -// CHECK: br -sil hidden @DeadStoreInIfElseBlockSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // users: %6, %11, %16, %21, %24 - // function_ref S1_init - %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 - %4 = metatype $@thin S1.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 - store %5 to %2#1 : $*S1 // id: %6 - %7 = struct_extract %0 : $Bool, #Bool.value // user: %8 - cond_br %7, bb1, bb2 // id: %8 - -bb1: // Preds: bb0 - %9 = integer_literal $Builtin.Int64, 0 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = struct_element_addr %2#1 : $*S1, #S1.a // user: %12 - store %10 to %11 : $*Int // id: %12 - br bb3 // id: %13 - -bb2: // Preds: bb0 - %14 = integer_literal $Builtin.Int64, 1 // user: %15 - %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 - %16 = struct_element_addr %2#1 : $*S1, #S1.a // user: %17 - store %15 to %16 : $*Int // id: %17 - br bb3 // id: %18 - -bb3: // Preds: bb1 bb2 - %19 = integer_literal $Builtin.Int64, 2 // user: %20 - %20 = struct $Int (%19 : $Builtin.Int64) // user: %22 - %21 = struct_element_addr %2#1 : $*S1, #S1.a // user: %22 - store %20 to %21 : $*Int // id: %22 - %23 = tuple () // user: %25 - dealloc_stack %2#0 : $*@local_storage S1 // id: %24 - return %23 : $() // id: %25 -} - -// Remove a dead store in the split block as there are stores in the if-else -// blocks. -// -// CHECK-LABEL: DeadStoreInSplitSimpleStruct -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: cond_br -sil hidden @DeadStoreInSplitSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // users: %6, %11, %16, %21, %25 - // function_ref S1_init - %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 - %4 = metatype $@thin S1.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 - store %5 to %2#1 : $*S1 // id: %6 - br bb1 // id: %7 - -bb1: // Preds: bb0 - %8 = struct_extract %0 : $Bool, #Bool.value // user: %13 - %9 = integer_literal $Builtin.Int64, 0 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = struct_element_addr %2#1 : $*S1, #S1.a // user: %12 - store %10 to %11 : $*Int // id: %12 - cond_br %8, bb2, bb3 // id: %13 - -bb2: // Preds: bb1 - %14 = integer_literal $Builtin.Int64, 0 // user: %15 - %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 - %16 = struct_element_addr %2#1 : $*S1, #S1.a // user: %17 - store %15 to %16 : $*Int // id: %17 - br bb4 // id: %18 - -bb3: // Preds: bb1 - %19 = integer_literal $Builtin.Int64, 1 // user: %20 - %20 = struct $Int (%19 : $Builtin.Int64) // user: %22 - %21 = struct_element_addr %2#1 : $*S1, #S1.a // user: %22 - store %20 to %21 : $*Int // id: %22 - br bb4 // id: %23 - -bb4: // Preds: bb2 bb3 - %24 = tuple () // user: %26 - dealloc_stack %2#0 : $*@local_storage S1 // id: %25 - return %24 : $() // id: %26 -} - -// Remove dead stores in split and else block. -// -// CHECK-LABEL: DeadStoreInSplitElseBlockSimpleStruct -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: cond_br -sil hidden @DeadStoreInSplitElseBlockSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // users: %6, %11, %17, %22, %25 - // function_ref S1_init - %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 - %4 = metatype $@thin S1.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 - store %5 to %2#1 : $*S1 // id: %6 - br bb1 // id: %7 - -bb1: // Preds: bb0 - %8 = struct_extract %0 : $Bool, #Bool.value // user: %13 - %9 = integer_literal $Builtin.Int64, 0 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = struct_element_addr %2#1 : $*S1, #S1.a // user: %12 - store %10 to %11 : $*Int // id: %12 - cond_br %8, bb2, bb3 // id: %13 - -bb2: // Preds: bb1 - br bb4 // id: %14 - -bb3: // Preds: bb1 - %15 = integer_literal $Builtin.Int64, 1 // user: %16 - %16 = struct $Int (%15 : $Builtin.Int64) // user: %18 - %17 = struct_element_addr %2#1 : $*S1, #S1.a // user: %18 - store %16 to %17 : $*Int // id: %18 - br bb4 // id: %19 - -bb4: // Preds: bb2 bb3 - %20 = integer_literal $Builtin.Int64, 0 // user: %21 - %21 = struct $Int (%20 : $Builtin.Int64) // user: %23 - %22 = struct_element_addr %2#1 : $*S1, #S1.a // user: %23 - store %21 to %22 : $*Int // id: %23 - %24 = tuple () // user: %26 - dealloc_stack %2#0 : $*@local_storage S1 // id: %25 - return %24 : $() // id: %26 -} - -// Remove dead stores in else block, store is only partially dead -// for split block. -// -// CHECK-LABEL: DeadStoreInElsePartialDeadStoreInSplitSimpleStruct -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: cond_br -sil hidden @DeadStoreInElsePartialDeadStoreInSplitSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // users: %6, %11, %18, %23, %26 - // function_ref S1_init - %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 - %4 = metatype $@thin S1.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 - store %5 to %2#1 : $*S1 // id: %6 - br bb1 // id: %7 - -bb1: // Preds: bb0 - %8 = struct_extract %0 : $Bool, #Bool.value // user: %14 - %9 = integer_literal $Builtin.Int64, 0 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %13 - %11 = struct_element_addr %2#1 : $*S1, #S1.a // users: %12, %13 - %12 = load %11 : $*Int - store %10 to %11 : $*Int // id: %13 - cond_br %8, bb2, bb3 // id: %14 - -bb2: // Preds: bb1 - br bb4 // id: %15 - -bb3: // Preds: bb1 - %16 = integer_literal $Builtin.Int64, 1 // user: %17 - %17 = struct $Int (%16 : $Builtin.Int64) // user: %19 - %18 = struct_element_addr %2#1 : $*S1, #S1.a // user: %19 - store %17 to %18 : $*Int // id: %19 - br bb4 // id: %20 - -bb4: // Preds: bb2 bb3 - %21 = integer_literal $Builtin.Int64, 0 // user: %22 - %22 = struct $Int (%21 : $Builtin.Int64) // user: %24 - %23 = struct_element_addr %2#1 : $*S1, #S1.a // user: %24 - store %22 to %23 : $*Int // id: %24 - %25 = tuple () // user: %27 - dealloc_stack %2#0 : $*@local_storage S1 // id: %26 - return %25 : $() // id: %27 -} - -// Remove a dead store in the split block as there are stores in the if-else -// blocks. -// -// Store in bb1 is still alive as post-order does not iterate over unreachable -// block. -// -// CHECK-LABEL: DeadStoreInUnreachablePredecessorSimpleStruct -// CHECK: bb0 -// CHECK-NOT: store -// CHECK: br -// CHECK: bb1 -// CHECK-NOT: store -// CHECK: br -sil hidden @DeadStoreInUnreachablePredecessorSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // users: %6, %11, %16, %21, %25 - // function_ref S1_init - %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 - %4 = metatype $@thin S1.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 - store %5 to %2#1 : $*S1 // id: %6 - br bb1 // id: %7 - -bb1: // Preds: bb0 - %8 = struct_extract %0 : $Bool, #Bool.value - %9 = integer_literal $Builtin.Int64, 0 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = struct_element_addr %2#1 : $*S1, #S1.a // user: %12 - store %10 to %11 : $*Int // id: %12 - br bb3 // id: %13 - -bb2: - %14 = integer_literal $Builtin.Int64, 0 // user: %15 - %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 - %16 = struct_element_addr %2#1 : $*S1, #S1.a // user: %17 - store %15 to %16 : $*Int // id: %17 - br bb3 // id: %18 - -bb3: // Preds: bb1 bb2 - %19 = integer_literal $Builtin.Int64, 1 // user: %20 - %20 = struct $Int (%19 : $Builtin.Int64) // user: %22 - %21 = struct_element_addr %2#1 : $*S1, #S1.a // user: %22 - store %20 to %21 : $*Int // id: %22 - br bb4 // id: %23 - -bb4: // Preds: bb3 - %24 = tuple () // user: %26 - dealloc_stack %2#0 : $*@local_storage S1 // id: %25 - return %24 : $() // id: %26 -} - -// CHECK-LABEL: DeadStoreInIfElseBlockComplexStruct -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: br -// CHECK: bb2: -// CHECK-NOT: store -// CHECK: br -sil hidden @DeadStoreInIfElseBlockComplexStruct : $@convention(thin) (Bool) -> () { -bb0(%0 : $Bool): - %1 = alloc_stack $S2 // users: %5, %10, %16, %22, %26 - // function_ref S2_init - %2 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %4 - %3 = metatype $@thin S2.Type // user: %4 - %4 = apply %2(%3) : $@convention(thin) (@thin S2.Type) -> S2 // user: %5 - store %4 to %1#1 : $*S2 // id: %5 - %6 = struct_extract %0 : $Bool, #Bool.value // user: %7 - cond_br %6, bb1, bb2 // id: %7 - -bb1: // Preds: bb0 - %8 = integer_literal $Builtin.Int64, 0 // user: %9 - %9 = struct $Int (%8 : $Builtin.Int64) // user: %12 - %10 = struct_element_addr %1#1 : $*S2, #S2.x // user: %11 - %11 = struct_element_addr %10 : $*S1, #S1.a // user: %12 - store %9 to %11 : $*Int // id: %12 - br bb3 // id: %13 - -bb2: // Preds: bb0 - %14 = integer_literal $Builtin.Int64, 1 // user: %15 - %15 = struct $Int (%14 : $Builtin.Int64) // user: %18 - %16 = struct_element_addr %1#1 : $*S2, #S2.x // user: %17 - %17 = struct_element_addr %16 : $*S1, #S1.a // user: %18 - store %15 to %17 : $*Int // id: %18 - br bb3 // id: %19 - -bb3: // Preds: bb1 bb2 - %20 = integer_literal $Builtin.Int64, 2 // user: %21 - %21 = struct $Int (%20 : $Builtin.Int64) // user: %24 - %22 = struct_element_addr %1#1 : $*S2, #S2.x // user: %23 - %23 = struct_element_addr %22 : $*S1, #S1.a // user: %24 - store %21 to %23 : $*Int // id: %24 - %25 = tuple () // user: %27 - dealloc_stack %1#0 : $*@local_storage S2 // id: %26 - return %25 : $() // id: %27 -} - -// Remove dead stores in split and else block on a complex struct. -// -// CHECK-LABEL: DeadStoreInSplitElseBlockComplexStruct -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: br -// CHECK: bb3: -// CHECK-NOT: store -// CHECK: br -sil hidden @DeadStoreInSplitElseBlockComplexStruct : $@convention(thin) (Bool) -> () { -bb0(%0 : $Bool): - %1 = alloc_stack $S2 // users: %5, %9, %17, %23, %27 - // function_ref S2_init - %2 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %4 - %3 = metatype $@thin S2.Type // user: %4 - %4 = apply %2(%3) : $@convention(thin) (@thin S2.Type) -> S2 // user: %5 - store %4 to %1#1 : $*S2 // id: %5 - br bb1 // id: %6 - -bb1: // Preds: bb0 - %7 = integer_literal $Builtin.Int64, 0 // user: %8 - %8 = struct $Int (%7 : $Builtin.Int64) // user: %11 - %9 = struct_element_addr %1#1 : $*S2, #S2.x // user: %10 - %10 = struct_element_addr %9 : $*S1, #S1.a // user: %11 - store %8 to %10 : $*Int // id: %11 - %12 = struct_extract %0 : $Bool, #Bool.value // user: %13 - cond_br %12, bb2, bb3 // id: %13 - -bb2: // Preds: bb1 - br bb4 // id: %14 - -bb3: // Preds: bb1 - %15 = integer_literal $Builtin.Int64, 1 // user: %16 - %16 = struct $Int (%15 : $Builtin.Int64) // user: %19 - %17 = struct_element_addr %1#1 : $*S2, #S2.x // user: %18 - %18 = struct_element_addr %17 : $*S1, #S1.a // user: %19 - store %16 to %18 : $*Int // id: %19 - br bb4 // id: %20 - -bb4: // Preds: bb2 bb3 - %21 = integer_literal $Builtin.Int64, 2 // user: %22 - %22 = struct $Int (%21 : $Builtin.Int64) // user: %25 - %23 = struct_element_addr %1#1 : $*S2, #S2.x // user: %24 - %24 = struct_element_addr %23 : $*S1, #S1.a // user: %25 - store %22 to %24 : $*Int // id: %25 - %26 = tuple () // user: %28 - dealloc_stack %1#0 : $*@local_storage S2 // id: %27 - return %26 : $() // id: %28 -} - -// Remove dead store in 1 loop block, as the store in exit block kills it. -// -// CHECK-LABEL: DeadStoreSingleLoopBlockSimpleStruct -// CHECK: bb2: -// CHECK: store -// CHECK: br -sil hidden @DeadStoreSingleLoopBlockSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // var x // users: %8, %13, %18, %23, %26 - %5 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %7 - %6 = metatype $@thin S1.Type // user: %7 - %7 = apply %5(%6) : $@convention(thin) (@thin S1.Type) -> S1 // user: %8 - store %7 to %2#1 : $*S1 // id: %8 - br bb1 - -bb1: // Preds: bb0 - %11 = integer_literal $Builtin.Int64, 0 // user: %12 - %12 = struct $Int (%11 : $Builtin.Int64) // user: %14 - %13 = struct_element_addr %2#1 : $*S1, #S1.a // user: %14 - %14 = load %13 : $*Int - br bb2 // id: %15 - -bb2: // Preds: bb0 - %16 = integer_literal $Builtin.Int64, 1 // user: %17 - %17 = struct $Int (%16 : $Builtin.Int64) // user: %19 - %18 = struct_element_addr %2#1 : $*S1, #S1.a // user: %19 - store %17 to %18 : $*Int // id: %19 - %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 - cond_br %9, bb1, bb3 // id: %10 - -bb3: // Preds: bb1 bb2 - %21 = integer_literal $Builtin.Int64, 2 // user: %22 - %22 = struct $Int (%21 : $Builtin.Int64) // user: %24 - %23 = struct_element_addr %2#1 : $*S1, #S1.a // user: %24 - store %22 to %23 : $*Int // id: %24 - %25 = tuple () // user: %27 - dealloc_stack %2#0 : $*@local_storage S1 // id: %26 - return %25 : $() // id: %27 -} - -// Remove dead stores in loop blocks, as the store in exit block kills them. -// -// CHECK-LABEL: DeadStoreInMultiLoopBlocksSimpleStruct -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: br -// CHECK: bb2: -// CHECK-NOT: store -// CHECK: br -sil hidden @DeadStoreInMultiLoopBlocksSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // var x // users: %8, %13, %18, %23, %26 - %5 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %7 - %6 = metatype $@thin S1.Type // user: %7 - %7 = apply %5(%6) : $@convention(thin) (@thin S1.Type) -> S1 // user: %8 - store %7 to %2#1 : $*S1 // id: %8 - br bb1 - -bb1: // Preds: bb0 - %11 = integer_literal $Builtin.Int64, 0 // user: %12 - %12 = struct $Int (%11 : $Builtin.Int64) // user: %14 - %13 = struct_element_addr %2#1 : $*S1, #S1.a // user: %14 - store %12 to %13 : $*Int // id: %14 - br bb2 // id: %15 - -bb2: // Preds: bb0 - %16 = integer_literal $Builtin.Int64, 1 // user: %17 - %17 = struct $Int (%16 : $Builtin.Int64) // user: %19 - %18 = struct_element_addr %2#1 : $*S1, #S1.a // user: %19 - store %17 to %18 : $*Int // id: %19 - %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 - cond_br %9, bb1, bb3 // id: %10 - -bb3: // Preds: bb1 bb2 - %21 = integer_literal $Builtin.Int64, 2 // user: %22 - %22 = struct $Int (%21 : $Builtin.Int64) // user: %24 - %23 = struct_element_addr %2#1 : $*S1, #S1.a // user: %24 - store %22 to %23 : $*Int // id: %24 - %25 = tuple () // user: %27 - dealloc_stack %2#0 : $*@local_storage S1 // id: %26 - return %25 : $() // id: %27 -} - -// Remove dead store in the tuple data structure. -// -// CHECK-LABEL: DeadStoreInSimpleTuple -// CHECK: bb0: -// CHECK-NEXT: alloc_stack -// CHECK-NEXT: integer_literal -// CHECK-NEXT: struct -// CHECK-NEXT: tuple_element_addr -// CHECK-NEXT: store -// CHECK-NEXT: integer_literal -// CHECK-NEXT: struct -// CHECK-NEXT: tuple_element_addr -// CHECK-NEXT: store -sil hidden @DeadStoreInSimpleTuple : $@convention(thin) () -> Int { -bb0: - %0 = alloc_stack $(a: Int, b: Int) // var x // users: %1, %2, %11, %15, %20 - %1 = tuple_element_addr %0#1 : $*(a: Int, b: Int), 0 // user: %5 - %2 = tuple_element_addr %0#1 : $*(a: Int, b: Int), 1 // user: %8 - %3 = integer_literal $Builtin.Int64, 2 // user: %4 - %4 = struct $Int (%3 : $Builtin.Int64) // user: %5 - store %4 to %1 : $*Int // id: %5 - %6 = integer_literal $Builtin.Int64, 2 // user: %7 - %7 = struct $Int (%6 : $Builtin.Int64) // user: %8 - store %7 to %2 : $*Int // id: %8 - %9 = integer_literal $Builtin.Int64, 10 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = tuple_element_addr %0#1 : $*(a: Int, b: Int), 0 // user: %12 - store %10 to %11 : $*Int // id: %12 - %13 = integer_literal $Builtin.Int64, 12 // user: %14 - %14 = struct $Int (%13 : $Builtin.Int64) // user: %16 - %15 = tuple_element_addr %0#1 : $*(a: Int, b: Int), 1 // user: %16 - store %14 to %15 : $*Int // id: %16 - %17 = integer_literal $Builtin.Int64, 22 // user: %19 - %18 = tuple () - %19 = struct $Int (%17 : $Builtin.Int64) // user: %21 - dealloc_stack %0#0 : $*@local_storage (a: Int, b: Int) // id: %20 - return %19 : $Int // id: %21 -} - -// Remove dead stores in if else blocks for simple class. -// -// CHECK-LABEL: DeadStoreInIfElseSimpleClass -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: br -// CHECK: bb2: -// CHECK-NOT: store -// CHECK: br -sil hidden @DeadStoreInIfElseSimpleClass : $@convention(thin) (Bool) -> () { -bb0(%0 : $Bool): - %1 = alloc_stack $foo // users: %8, %36 - %3 = alloc_ref $foo // users: %6, %8, %11, %14, %17, %19, %22, %25, %27, %30, %33, %34 - %4 = integer_literal $Builtin.Int64, 10 // user: %5 - %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 - %6 = ref_element_addr %3 : $foo, #foo.a // user: %7 - store %5 to %6 : $*Int // id: %7 - store %3 to %1#1 : $*foo // id: %8 - %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 - cond_br %9, bb1, bb2 // id: %10 - -bb1: // Preds: bb0 - %12 = integer_literal $Builtin.Int64, 11 // user: %13 - %13 = struct $Int (%12 : $Builtin.Int64) // user: %15 - %14 = ref_element_addr %3 : $foo, #foo.a // user: %15 - store %13 to %14 : $*Int // id: %15 - %16 = tuple () - br bb3 // id: %18 - -bb2: // Preds: bb0 - %20 = integer_literal $Builtin.Int64, 12 // user: %21 - %21 = struct $Int (%20 : $Builtin.Int64) // user: %23 - %22 = ref_element_addr %3 : $foo, #foo.a // user: %23 - store %21 to %22 : $*Int // id: %23 - %24 = tuple () - br bb3 // id: %26 - -bb3: // Preds: bb1 bb2 - strong_retain %3 : $foo // id: %27 - %28 = integer_literal $Builtin.Int64, 13 // user: %29 - %29 = struct $Int (%28 : $Builtin.Int64) // user: %31 - %30 = ref_element_addr %3 : $foo, #foo.a // user: %31 - store %29 to %30 : $*Int // id: %31 - %32 = tuple () - strong_release %3 : $foo // id: %33 - strong_release %3 : $foo // id: %34 - %35 = tuple () // user: %37 - dealloc_stack %1#0 : $*@local_storage foo // id: %36 - return %35 : $() // id: %37 -} - -// Remove dead store in split block for simple class. -// -// CHECK-LABEL: DeadStoreInSplitSimpleClass -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: cond_br -sil hidden @DeadStoreInSplitSimpleClass : $@convention(thin) (Bool) -> () { -bb0(%0 : $Bool): - %1 = alloc_stack $foo // users: %3, %25 - %2 = alloc_ref $foo // users: %3, %7, %13, %19, %23 - store %2 to %1#1 : $*foo // id: %3 - br bb1 // id: %4 - -bb1: // Preds: bb0 - %5 = integer_literal $Builtin.Int64, 10 // user: %6 - %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 - %7 = ref_element_addr %2 : $foo, #foo.a // user: %8 - store %6 to %7 : $*Int // id: %8 - %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 - cond_br %9, bb2, bb3 // id: %10 - -bb2: // Preds: bb1 - %11 = integer_literal $Builtin.Int64, 11 // user: %12 - %12 = struct $Int (%11 : $Builtin.Int64) // user: %14 - %13 = ref_element_addr %2 : $foo, #foo.a // user: %14 - store %12 to %13 : $*Int // id: %14 - %15 = tuple () - br bb4 // id: %16 - -bb3: // Preds: bb1 - %17 = integer_literal $Builtin.Int64, 12 // user: %18 - %18 = struct $Int (%17 : $Builtin.Int64) // user: %20 - %19 = ref_element_addr %2 : $foo, #foo.a // user: %20 - store %18 to %19 : $*Int // id: %20 - %21 = tuple () - br bb4 // id: %22 - -bb4: // Preds: bb2 bb3 - strong_release %2 : $foo // id: %23 - %24 = tuple () // user: %26 - dealloc_stack %1#0 : $*@local_storage foo // id: %25 - return %24 : $() // id: %26 -} - -// Can not remove partially dead store in split block for simple class. -// -// CHECK-LABEL: PartialDeadStoreInSplitSimpleClass -// CHECK: bb1: -// CHECK-NEXT: [[RET0:%.+]] = integer_literal $Builtin.Int64, 10 -// CHECK-NEXT: [[RET1:%.+]] = struct $Int ([[RET0:%.+]] : $Builtin.Int64) -// CHECK-NEXT: [[RET2:%.+]] = ref_element_addr -// CHECK-NEXT: store [[RET1:%.+]] to [[RET2:%.+]] -sil hidden @PartialDeadStoreInSplitSimpleClass : $@convention(thin) (Bool) -> () { -bb0(%0 : $Bool): - %1 = alloc_stack $foo // users: %3, %20 - %2 = alloc_ref $foo // users: %3, %7, %14, %18 - store %2 to %1#1 : $*foo // id: %3 - br bb1 // id: %4 - -bb1: // Preds: bb0 - %5 = integer_literal $Builtin.Int64, 10 // user: %6 - %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 - %7 = ref_element_addr %2 : $foo, #foo.a // user: %8 - store %6 to %7 : $*Int // id: %8 - %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 - cond_br %9, bb2, bb3 // id: %10 - -bb2: // Preds: bb1 - br bb4 // id: %11 - -bb3: // Preds: bb1 - %12 = integer_literal $Builtin.Int64, 12 // user: %13 - %13 = struct $Int (%12 : $Builtin.Int64) // user: %15 - %14 = ref_element_addr %2 : $foo, #foo.a // user: %15 - store %13 to %14 : $*Int // id: %15 - %16 = tuple () - br bb4 // id: %17 - -bb4: // Preds: bb2 bb3 - strong_release %2 : $foo // id: %18 - %19 = tuple () // user: %21 - dealloc_stack %1#0 : $*@local_storage foo // id: %20 - return %19 : $() // id: %21 -} - -// Can not remove partially dead store in split block for simple class. -// -// CHECK-LABEL: PartialDeadStoreInSplitWithFunctionCallSimpleClass -// CHECK: bb1: -// CHECK-NEXT: [[RET0:%.+]] = integer_literal $Builtin.Int64, 10 -// CHECK-NEXT: [[RET1:%.+]] = struct $Int ([[RET0:%.+]] : $Builtin.Int64) -// CHECK-NEXT: [[RET2:%.+]] = ref_element_addr -// CHECK-NEXT: store [[RET1:%.+]] to [[RET2:%.+]] -sil hidden @PartialDeadStoreInSplitWithFunctionCallSimpleClass : $@convention(thin) (Bool) -> () { -bb0(%0 : $Bool): - %1 = alloc_stack $foo // users: %8, %36 - %3 = alloc_ref $foo // users: %6, %8, %11, %14, %17, %19, %22, %25, %27, %30, %33, %34 - store %3 to %1#1 : $*foo // id: %8 - br bb1 - -bb1: - %4 = integer_literal $Builtin.Int64, 10 // user: %5 - %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 - %6 = ref_element_addr %3 : $foo, #foo.a // user: %7 - store %5 to %6 : $*Int // id: %7 - %9 = struct_extract %0 : $Bool, #Bool.value // user: %10 - cond_br %9, bb2, bb3 // id: %10 - -bb2: // Preds: bb0 - %32 = function_ref @foo_user : $@convention(thin) (@guaranteed foo) -> ()// user: %4 - %33 = apply %32(%3) : $@convention(thin) (@guaranteed foo) -> () // users: %6, %15 - %120 = integer_literal $Builtin.Int64, 12 // user: %21 - %121 = struct $Int (%120 : $Builtin.Int64) // user: %23 - store %121 to %6 : $*Int // id: %23 - %124 = tuple () - br bb4 // id: %18 - -bb3: // Preds: bb0 - %20 = integer_literal $Builtin.Int64, 12 // user: %21 - %21 = struct $Int (%20 : $Builtin.Int64) // user: %23 - store %21 to %6 : $*Int // id: %23 - %24 = tuple () - br bb4 // id: %26 - -bb4: // Preds: bb1 bb2 - strong_release %3 : $foo // id: %34 - %35 = tuple () // user: %37 - dealloc_stack %1#0 : $*@local_storage foo // id: %36 - return %35 : $() // id: %37 -} - -// Remove dead store in same basic block, test for alias analysis/side effect. -// Currently, %14 = apply %13(%10) is marked as having side effect on the -// store %8 to %9 : $*Int // id: %15 -// -// CHECK-LABEL: DeadStoreSameBlockAcrossFunctionCallSimpleStruct -// CHECK: bb1: -// CHECK-NOT: store -// CHECK: function_ref -sil hidden @DeadStoreSameBlockAcrossFunctionCallSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // users: %6, %9, %18 - // function_ref S1_init - %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 - %4 = metatype $@thin S1.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 - store %5 to %2#1 : $*S1 // id: %6 - %7 = integer_literal $Builtin.Int64, 0 // user: %8 - %8 = struct $Int (%7 : $Builtin.Int64) // users: %12, %15 - %9 = struct_element_addr %2#1 : $*S1, #S1.a // users: %12, %15 - %10 = alloc_ref $foo // user: %14 - br bb1 // id: %11 - -bb1: // Preds: bb0 - store %8 to %9 : $*Int // id: %12 - %13 = function_ref @foo_user : $@convention(thin) (@guaranteed foo) -> () // user: %14 - %14 = apply %13(%10) : $@convention(thin) (@guaranteed foo) -> () - store %8 to %9 : $*Int // id: %15 - br bb2 // id: %16 - -bb2: // Preds: bb1 - %17 = tuple () // user: %19 - dealloc_stack %2#0 : $*@local_storage S1 // id: %18 - return %17 : $() // id: %19 -} - - -// store to stack allocated memory can not alias with incoming argument. -// -// CHECK-LABEL: DeadStoreInoutAndStackAlias -// CHECK: bb0 -// CHECK : struct_element_addr -// CHECK-NOT: store -// CHECK: load -sil hidden @DeadStoreInoutAndStackAlias : $@convention(thin) (@inout A) -> () { -bb0(%0 : $*A): - %1 = alloc_stack $A // users: %4, %8 - %2 = integer_literal $Builtin.Int32, 0 // users: %5, %7 - %3 = struct_element_addr %0 : $*A, #A.i // user: %6 - %4 = struct_element_addr %1#1 : $*A, #A.i // users: %5, %7 - store %2 to %4 : $*Builtin.Int32 // id: %5 - %6 = load %3 : $*Builtin.Int32 - store %2 to %4 : $*Builtin.Int32 // id: %7 - dealloc_stack %1#0 : $*@local_storage A // id: %8 - %9 = tuple () // user: %10 - return %9 : $() // id: %10 -} - -// test dead store for enums. there should be only 1 store left. -// -// CHECK-LABEL: DeadStoreEnumSameCase -// CHECK: store -// CHECK-NOT: store -// CHECK: return -sil hidden @DeadStoreEnumSameCase : $@convention(thin) () -> Int64 { -bb0: - %0 = alloc_stack $Example // var x // users: %7, %14, %19 - %1 = integer_literal $Builtin.Int64, 64 // user: %2 - %2 = struct $Int64 (%1 : $Builtin.Int64) // user: %5 - %3 = integer_literal $Builtin.Int64, 64 // user: %4 - %4 = struct $Int64 (%3 : $Builtin.Int64) // user: %5 - %5 = tuple (%2 : $Int64, %4 : $Int64) // user: %6 - %6 = enum $Example, #Example.A!enumelt.1, %5 : $(Int64, Int64) // users: %7, %15 - store %6 to %0#1 : $*Example // id: %7 - %8 = integer_literal $Builtin.Int64, 64 // user: %9 - %9 = struct $Int64 (%8 : $Builtin.Int64) // user: %12 - %10 = integer_literal $Builtin.Int64, 64 // user: %11 - %11 = struct $Int64 (%10 : $Builtin.Int64) // user: %12 - %12 = tuple (%9 : $Int64, %11 : $Int64) // user: %13 - %13 = enum $Example, #Example.A!enumelt.1, %12 : $(Int64, Int64) // users: %14, %18 - store %13 to %0#1 : $*Example // id: %14 - release_value %6 : $Example // id: %15 - %16 = integer_literal $Builtin.Int64, 0 // user: %17 - %17 = struct $Int64 (%16 : $Builtin.Int64) // user: %20 - release_value %13 : $Example // id: %18 - dealloc_stack %0#0 : $*@local_storage Example // id: %19 - return %17 : $Int64 // id: %20 -} - -// The store in bb0 as the its only partially dead, i.e. -// the structure S3 has 2 fields. -// -// CHECK-LABEL: PartialDeadStoreSimpleStruct -// CHECK: bb0 -// CHECK-NEXT: [[RET0:%.+]] = alloc_stack -// CHECK: [[RET1:%.+]] = function_ref @S3_init -// CHECK-NEXT: [[RET2:%.+]] = metatype $@thin S3.Type -// CHECK-NEXT: [[RET3:%.+]] = apply [[RET1:%.+]]([[RET2:%.+]]) -// CHECK-NOT: store [[RET3:%.+]] to [[RET0:%.+]]#1 : $*S3 -sil hidden @PartialDeadStoreSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S3 // users: %6, %11, %16, %20 - // function_ref S3_init - %3 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %5 - %4 = metatype $@thin S3.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S3.Type) -> S3 // user: %6 - store %5 to %2#1 : $*S3 // id: %6 - %7 = struct_extract %0 : $Bool, #Bool.value // user: %8 - cond_br %7, bb1, bb2 // id: %8 - -bb1: // Preds: bb0 - %9 = integer_literal $Builtin.Int64, 0 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = struct_element_addr %2#1 : $*S3, #S3.a // user: %12 - store %10 to %11 : $*Int // id: %12 - br bb3 // id: %13 - -bb2: // Preds: bb0 - %14 = integer_literal $Builtin.Int64, 1 // user: %15 - %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 - %16 = struct_element_addr %2#1 : $*S3, #S3.a // user: %17 - store %15 to %16 : $*Int // id: %17 - br bb3 // id: %18 - -bb3: // Preds: bb1 bb2 - %19 = tuple () // user: %21 - dealloc_stack %2#0 : $*@local_storage S3 // id: %20 - return %19 : $() // id: %21 -} - -/// Make sure we can coalesce the 2 live stores to the 2 fields in S4. -/// -/// CHECK-LABEL : PartialDeadStoreStructInStruct -/// CHECK: [[RET0:%.+]] = struct_extract -/// CHECK: [[RET1:%.+]] = struct_element_addr -/// CHECK: store [[RET0:%.+]] to [[RET1:%.+]] : $*S4 -sil hidden @PartialDeadStoreStructInStruct : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S5 // var i // users: %4, %7, %10 - %1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> S5 // user: %3 - %2 = metatype $@thin S5.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> S5 // user: %4 - store %3 to %0#1 : $*S5 // id: %4 - %5 = integer_literal $Builtin.Int64, 11 // user: %6 - %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 - %7 = struct_element_addr %0#1 : $*S5, #S5.y // user: %8 - store %6 to %7 : $*Int // id: %8 - %9 = tuple () // user: %11 - dealloc_stack %0#0 : $*@local_storage S5 // id: %10 - return %9 : $() // id: %11 -} - -/// Make sure we do not coalesce the 2 live stores to the 2 fields in S6. -/// -/// CHECK-LABEL : DiscontiguosPartialDeadStoreInSimpleStruct -/// CHECK: store -/// CHECK: store -/// CHECK: store -sil hidden @DiscontiguosPartialDeadStoreInSimpleStruct : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S6 // var a // users: %4, %7, %10 - %1 = function_ref @S6_init : $@convention(thin) (@thin S6.Type) -> S6 // user: %3 - %2 = metatype $@thin S6.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S6.Type) -> S6 // user: %4 - store %3 to %0#1 : $*S6 // id: %4 - %5 = integer_literal $Builtin.Int64, 10 // user: %6 - %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 - %7 = struct_element_addr %0#1 : $*S6, #S6.y // user: %8 - store %6 to %7 : $*Int // id: %8 - %9 = tuple () // user: %11 - dealloc_stack %0#0 : $*@local_storage S6 // id: %10 - return %9 : $() // id: %11 -} - -/// Make sure we do not generate too many stores from a large store that -/// is partially dead. -/// -/// CHECK-LABEL : DiscontiguosPartialDeadStoreInSimpleLargeStruct -/// CHECK: store -/// CHECK-NOT: store -/// CHECK: store -sil hidden @DiscontiguosPartialDeadStoreInSimpleLargeStruct : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S7 // var a // users: %4, %7, %10 - %1 = function_ref @S7_init : $@convention(thin) (@thin S7.Type) -> S7 // user: %3 - %2 = metatype $@thin S7.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S7.Type) -> S7 // user: %4 - store %3 to %0#1 : $*S7 // id: %4 - %5 = integer_literal $Builtin.Int64, 10 // user: %6 - %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 - %7 = struct_element_addr %0#1 : $*S7, #S7.y // user: %8 - store %6 to %7 : $*Int // id: %8 - %9 = tuple () // user: %11 - dealloc_stack %0#0 : $*@local_storage S7 // id: %10 - return %9 : $() // id: %11 -} - -/// We are not performing partial dead store for store %3 to %0#1 : $*S7, -/// i.e. too many stores generated, but make sure we track the store correctly -/// so that we can get rid of store %56 to %57 : $*Int. -/// -/// CHECK-LABEL : PartialDeadStoreBailOutProperPropagation -/// CHECK: bb0 -/// CHECK-NOT: store -/// CHECK: function_ref -sil hidden @PartialDeadStoreBailOutProperPropagation : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S7 // var a // users: %4, %7, %10 - %55 = integer_literal $Builtin.Int64, 10 // user: %6 - %56 = struct $Int (%55 : $Builtin.Int64) // user: %8 - %57 = struct_element_addr %0#1 : $*S7, #S7.a // user: %8 - store %56 to %57 : $*Int // id: %8 - %1 = function_ref @S7_init : $@convention(thin) (@thin S7.Type) -> S7 // user: %3 - %2 = metatype $@thin S7.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S7.Type) -> S7 // user: %4 - store %3 to %0#1 : $*S7 // id: %4 - %5 = integer_literal $Builtin.Int64, 10 // user: %6 - %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 - %7 = struct_element_addr %0#1 : $*S7, #S7.y // user: %8 - store %6 to %7 : $*Int // id: %8 - %9 = tuple () // user: %11 - dealloc_stack %0#0 : $*@local_storage S7 // id: %10 - return %9 : $() // id: %11 -} - -/// Make sure we do perform partial dead store for the first store. -/// we have a case which partial dead store miscompiles a program, -/// in that case the bitvector is not tracked correctly and we end -/// up deleting the entire larger store, store %3 to %0#1 : $*S3 in -/// this case. -/// -/// CHECK-LABEL: PartialDeadStoreInSimpleSmallStruct -/// CHECK: apply -/// CHECK-NEXT: struct_extract -sil hidden @PartialDeadStoreInSimpleSmallStruct : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S3 // var a // users: %4, %7, %10 - %1 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %3 - %2 = metatype $@thin S3.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S3.Type) -> S3 // user: %4 - store %3 to %0#1 : $*S3 // id: %4 - %5 = integer_literal $Builtin.Int64, 10 // user: %6 - %6 = struct $Int (%5 : $Builtin.Int64) // user: %8 - %7 = struct_element_addr %0#1 : $*S3, #S3.a // user: %8 - store %6 to %7 : $*Int // id: %8 - %9 = tuple () // user: %11 - dealloc_stack %0#0 : $*@local_storage S3 // id: %10 - return %9 : $() // id: %11 -} - -/// Make sure we do not hang in this test case. Test for Location::expand. -/// expand should stop on class type. Also need to get rid of the partial -/// dead store. -/// -/// CHECK-LABEL: SelfLoopClassTestTypeExpansion -/// CHECK: [[RET0:%.+]] = struct_extract -/// CHECK: [[RET1:%.+]] = struct_element_addr -/// CHECK-NEXT: store [[RET0:%.+]] to [[RET1:%.+]] : $*SelfLoop -sil hidden @SelfLoopClassTestTypeExpansion : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S8 // var h // users: %4, %7, %13 - %1 = function_ref @S8_init : $@convention(thin) (@thin S8.Type) -> @owned S8 // user: %3 - %2 = metatype $@thin S8.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S8.Type) -> @owned S8 // users: %4, %9 - store %3 to %0#1 : $*S8 // id: %4 - %5 = integer_literal $Builtin.Int64, 12 // user: %6 - %6 = struct $Int (%5 : $Builtin.Int64) // users: %8, %10 - %7 = struct_element_addr %0#1 : $*S8, #S8.k // user: %8 - store %6 to %7 : $*Int // id: %8 - %9 = struct_extract %3 : $S8, #S8.i // user: %10 - %10 = struct $S8 (%9 : $SelfLoop, %6 : $Int) // user: %11 - release_value %10 : $S8 // id: %11 - %12 = tuple () // user: %14 - dealloc_stack %0#0 : $*@local_storage S8 // id: %13 - return %12 : $() // id: %14 -} - -/// Make sure we do not remove the first store as there is no way to prove -/// %0 and %1 can not alias here. -/// -/// CHECK-LABEL: NoDeadStoreWithInterferingLoad -/// CHECK: store -/// CHECK: load -/// CHECK: store -sil hidden @NoDeadStoreWithInterferingLoad : $@convention(thin) (@owned foo, @owned foo) -> () { -bb0(%0 : $foo, %1 : $foo): - debug_value %0 : $foo // let x // id: %2 - debug_value %1 : $foo // let a // id: %3 - %4 = integer_literal $Builtin.Int64, 10 // user: %5 - %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 - %6 = ref_element_addr %0 : $foo, #foo.a // user: %7 - store %5 to %6 : $*Int // id: %7 - %8 = tuple () - %9 = integer_literal $Builtin.Int64, 12 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = ref_element_addr %1 : $foo, #foo.a // user: %12 - %99 = load %11 : $*Int // id: %12 - %13 = tuple () - %14 = integer_literal $Builtin.Int64, 10 // user: %15 - %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 - %16 = ref_element_addr %0 : $foo, #foo.a // user: %17 - store %15 to %16 : $*Int // id: %17 - %18 = tuple () - strong_release %1 : $foo // id: %19 - strong_release %0 : $foo // id: %20 - %21 = tuple () // user: %22 - return %21 : $() // id: %22 -} - -// Remove the dead stores in the entry block as the store in bb2 -// kills them. This test how the optimistic data flow works. -// -// CHECK-LABEL: DeadStoreAcrossLoopSimpleStruct -// CHECK: bb0 -// CHECK-NOT: store -// CHECK: br -sil hidden @DeadStoreAcrossLoopSimpleStruct : $@convention(thin) (Bool, Int) -> () { -bb0(%0 : $Bool, %1 : $Int): - %2 = alloc_stack $S1 // users: %6, %9, %16, %19 - %3 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 - %4 = metatype $@thin S1.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S1.Type) -> S1 // user: %6 - store %5 to %2#1 : $*S1 // id: %6 - %7 = integer_literal $Builtin.Int64, 2 // user: %8 - %8 = struct $Int (%7 : $Builtin.Int64) // user: %10 - %9 = struct_element_addr %2#1 : $*S1, #S1.a // user: %10 - store %8 to %9 : $*Int // id: %10 - br bb1 // id: %11 - -bb1: // Preds: bb0 bb1 - %12 = struct_extract %0 : $Bool, #Bool.value // user: %13 - cond_br %12, bb1, bb2 // id: %13 - -bb2: // Preds: bb1 - %14 = integer_literal $Builtin.Int64, 2 // user: %15 - %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 - %16 = struct_element_addr %2#1 : $*S1, #S1.a // user: %17 - store %15 to %16 : $*Int // id: %17 - %18 = tuple () // user: %20 - dealloc_stack %2#0 : $*@local_storage S1 // id: %19 - return %18 : $() // id: %20 -} - - -// Make sure the load in bb1 prevents the store in bb0 to be eliminated. we have a bug -// in constructing kill set when it is not conservative enough. i.e. this test case -// makes sure the killset for bb1 includes the kill for the store in bb2. -// -// CHECK-LABEL: conservative_kill_set_class -// CHECK: bb0 -// CHECK: store -// CHECK: br bb1 -sil hidden @conservative_kill_set_class : $@convention(thin) (@owned foo, @owned foo) -> () { -bb0(%0 : $foo, %1 : $foo): - %4 = integer_literal $Builtin.Int64, 10 // user: %5 - %5 = struct $Int (%4 : $Builtin.Int64) // user: %7 - %6 = ref_element_addr %0 : $foo, #foo.a // user: %17 - store %5 to %6 : $*Int - br bb1 - -bb1: - %7 = ref_element_addr %1 : $foo, #foo.a // user: %17 - %8 = load %7 : $*Int - br bb2 - -bb2: - %9 = integer_literal $Builtin.Int64, 10 // user: %5 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %7 - %11 = ref_element_addr %0 : $foo, #foo.a // user: %17 - store %5 to %6 : $*Int - %18 = tuple () // user: %19 - return %18 : $() // id: %19 -} diff --git a/test/SILPasses/devirt_unbound_generic.swift b/test/SILPasses/devirt_unbound_generic.swift deleted file mode 100644 index 26cb07c766e03..0000000000000 --- a/test/SILPasses/devirt_unbound_generic.swift +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %target-swift-frontend -emit-sil -O -emit-object %s - -// We used to crash on this when trying to devirtualize t.boo(a, 1), -// because it is an "apply" with unbound generic arguments and -// devirtualizer is not able to devirtualize unbound generic -// invocations yet. -// -// rdar://19912272 - -protocol P { - typealias Node -} - -class C { - typealias Node = T.Node - - func foo(n:Node) { - } - - func boo(n:Node, s:S) { - } -} - -func test1(t:C, a: T.Node) { - t.boo(a, s:1) -} diff --git a/test/SILPasses/global_arc_opts_layout_compatible_casts.sil b/test/SILPasses/global_arc_opts_layout_compatible_casts.sil deleted file mode 100644 index ac66582eba179..0000000000000 --- a/test/SILPasses/global_arc_opts_layout_compatible_casts.sil +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -arc-sequence-opts -enable-loop-arc=0 %s | FileCheck %s -// RUN: %target-sil-opt -enable-sil-verify-all -arc-sequence-opts -enable-loop-arc=1 %s | FileCheck %s - -// This file is separate from the normal ARC optimizer tests to make -// it easy to remove when layout compatible types are removed. - -import Builtin -import Swift - -class C {} - -// Simple test that stripping works. -// CHECK-LABEL: sil @test1 : $@convention(thin) (C) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @test1 : $@convention(thin) (C) -> () { -bb0(%0 : $C): - strong_retain %0 : $C - %1 = unchecked_ref_cast %0 : $C to $Builtin.NativeObject - strong_release %1 : $Builtin.NativeObject - %2 = tuple() - return %2 : $() -} - -// We allow for matching up of retain_value, strong_release now that we -// have unchecked_ref_cast. - -// CHECK-LABEL: sil @test2 : $@convention(thin) (Optional, Optional) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -sil @test2 : $@convention(thin) (Optional, Optional) -> () { -bb0(%0 : $Optional, %1 : $Optional): - retain_value %0 : $Optional - %2 = unchecked_ref_cast %0 : $Optional to $C - strong_release %2 : $C - %3 = unchecked_ref_cast %1 : $Optional to $C - strong_retain %3 : $C - release_value %1 : $Optional - %9999 = tuple() - return %9999 : $() -} diff --git a/test/SILPasses/global_arc_unique_check.sil b/test/SILPasses/global_arc_unique_check.sil deleted file mode 100644 index 252327f6caaac..0000000000000 --- a/test/SILPasses/global_arc_unique_check.sil +++ /dev/null @@ -1,106 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | FileCheck %s -// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | FileCheck %s - -import Builtin -import Swift -import SwiftShims - -class MD5 { - init() - final var w: [UInt32] -} - -// CHECK-LABEL:sil @test_unique_check_arc : $@convention(method) (@owned MD5) -> () -sil @test_unique_check_arc : $@convention(method) (@owned MD5) -> () { -// CHECK: bb0 -bb0(%0 : $MD5): - %1 = integer_literal $Builtin.Int32, 0 - %2 = integer_literal $Builtin.Int32, 16 - %3 = struct $Int32 (%1 : $Builtin.Int32) - br bb1(%1 : $Builtin.Int32) - -// CHECK: bb1 -bb1(%5 : $Builtin.Int32): - %7 = builtin "cmp_eq_Int32"(%5 : $Builtin.Int32, %2 : $Builtin.Int32) : $Builtin.Int1 - cond_br %7, bb3, bb2 - -// CHECK: bb2 -bb2: - %9 = integer_literal $Builtin.Int32, 1 - %11 = integer_literal $Builtin.Int1, -1 - %12 = builtin "sadd_with_overflow_Int32"(%5 : $Builtin.Int32, %9 : $Builtin.Int32, %11 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) - %13 = tuple_extract %12 : $(Builtin.Int32, Builtin.Int1), 0 - // CHECK-NOT: strong_retain - // CHECK-NOT: strong_release - strong_retain %0 : $MD5 - %314 = ref_element_addr %0 : $MD5, #MD5.w - %318 = load %314 : $*Array - %319 = alloc_stack $Array - store %318 to %319#1 : $*Array - dealloc_stack %319#0 : $*@local_storage Array - %179 = is_unique %314 : $*Array - cond_br %179, bb4, bb5 - -// CHECK: bb3 -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple -// CHECK-NEXT: return -bb3: - strong_release %0 : $MD5 - %273 = tuple () - return %273 : $() - -bb4: - br bb5 - -// CHECK-NOT: strong_release -bb5: - strong_release %0 : $MD5 - br bb1(%13 : $Builtin.Int32) - -} - -class C {} - -// Check that retains are not moved across an is_unique that may alias. -sil @test_uniq_alias : $@convention(method) (@owned C) -> Builtin.Int1 { -// CHECK: bb0 -bb0(%0 : $C): - %1 = alloc_stack $C // var x - store %0 to %1#1 : $*C -// CHECK: strong_retain %0 : $C - strong_retain %0 : $C -// CHECK: is_unique %1#1 : $*C - %4 = is_unique %1#1 : $*C -// CHECK-NOT: strong_retain - fix_lifetime %0 : $C -// CHECK: strong_release %0 : $C - strong_release %0 : $C -// CHECK: [[LOADED:%[0-9]+]] = load %1#1 : $*C - %8 = load %1#1 : $*C -// CHECK: strong_release [[LOADED]] : $C - strong_release %8 : $C - dealloc_stack %1#0 : $*@local_storage C - return %4 : $Builtin.Int1 -} - -// The following test could optimize to: -// %2 = load %1 : $*C // user: %4 -// %3 = is_unique %0 : $*C // user: %5 -// fix_lifetime %2 : $C // id: %4 -// -// But ARC is currently conservative. When this is fixed, -// change _CHECK: strong... into _CHECK_NOT: strong... -sil @test_uniq_noalias : $@convention(thin) (@inout C, @inout C) -> Builtin.Int1 { -// CHECK: bb0 -bb0(%0 : $*C, %1 : $*C): - %2 = load %1 : $*C -// CHECK: strong_retain %2 : $C - strong_retain %2 : $C -// CHECK: is_unique %0 : $*C - %4 = is_unique %0 : $*C - fix_lifetime %2 : $C -// CHECK: strong_release %2 : $C - strong_release %2 : $C - return %4 : $Builtin.Int1 -} diff --git a/test/SILPasses/globalarcopts.sil b/test/SILPasses/globalarcopts.sil deleted file mode 100644 index 63e4bb38f2f55..0000000000000 --- a/test/SILPasses/globalarcopts.sil +++ /dev/null @@ -1,1933 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | FileCheck %s -// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | FileCheck %s - -sil_stage canonical - -import Swift -import Builtin - -// Utilities - -sil @user : $@convention(thin) (@box Builtin.Int32) -> () - -struct S { - var x : Builtin.NativeObject -} -sil @S_user : $@convention(thin) (S) -> () - -struct S2 { - var x : Builtin.Int32 - var y : Builtin.NativeObject - var z : Builtin.Int32 -} - -struct S3 { - var x : Builtin.Int32 - var y : Builtin.NativeObject - var y1 : Builtin.NativeObject - var z : Builtin.Int32 -} - -class Cls { - var random : Builtin.Int32 - - init() -} - -class C { - var w : Optional -} - -class RetainUser { } - -sil @rawpointer_use: $@convention(thin) (Builtin.RawPointer) -> Bool - -enum FakeOptional { - case None - case Some(T) -} - -enum Either { - case Left(LTy) - case Right(RTy) -} - -sil [fragile] @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - -sil [fragile] @owned_return : $@convention(thin) () -> (@owned @box Builtin.Int32) - -sil [fragile] @guaranteed_throwing_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error ErrorType - -///////////////// -// Basic Tests // -///////////////// - -// CHECK-LABEL: sil @simple_retain_release_pair : $@convention(thin) (Builtin.NativeObject) -> () -// CHECK: bb0 -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @simple_retain_release_pair : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - strong_release %0 : $Builtin.NativeObject - %1 = tuple () - return %1 : $() -} - -// CHECK-LABEL: sil @simple_copyvalue_destroyvalue_pair : $@convention(thin) (S) -> S -// CHECK: bb0({{%[0-9]+}} : $S) -// CHECK-NEXT: return -sil @simple_copyvalue_destroyvalue_pair : $@convention(thin) (S) -> S { -bb0(%0 : $S): - retain_value %0 : $S - release_value %0 : $S - retain_value %0 : $S - release_value %0 : $S - retain_value %0 : $S - release_value %0 : $S - return %0 : $S -} - -// CHECK-LABEL: sil @delete_retain_over_non_side_effect_instructions : $@convention(thin) (Builtin.NativeObject, Builtin.Int64) -> Builtin.Int1 -// CHECK: bb0 -// CHECK-NEXT: builtin -// CHECK-NEXT: return -sil @delete_retain_over_non_side_effect_instructions : $@convention(thin) (Builtin.NativeObject, Builtin.Int64) -> (Builtin.Int1) { -bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.Int64): - strong_retain %0 : $Builtin.NativeObject - %3 = builtin "cmp_eq_Int64"(%1 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 - strong_release %0 : $Builtin.NativeObject - return %3 : $Builtin.Int1 -} - -// CHECK-LABEL: sil @delete_copyvalue_over_non_side_effect_instructions : $@convention(thin) (S, Builtin.Int64) -> Builtin.Int1 -// CHECK: bb0 -// CHECK-NEXT: builtin -// CHECK-NEXT: return -sil @delete_copyvalue_over_non_side_effect_instructions : $@convention(thin) (S, Builtin.Int64) -> (Builtin.Int1) { -bb0(%0 : $S, %1 : $Builtin.Int64): - retain_value %0 : $S - %3 = builtin "cmp_eq_Int64"(%1 : $Builtin.Int64, %1 : $Builtin.Int64) : $Builtin.Int1 - release_value %0 : $S - return %3 : $Builtin.Int1 -} - -// CHECK-LABEL: sil @delete_retain_over_single_potential_decrement : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () -// CHECK: bb0 -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @delete_retain_over_single_potential_decrement : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - strong_release %1 : $Builtin.NativeObject - strong_release %0 : $Builtin.NativeObject - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @delete_copyvalue_over_single_potential_decrement : $@convention(thin) (S, Builtin.NativeObject) -> () -// CHECK: bb0 -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @delete_copyvalue_over_single_potential_decrement : $@convention(thin) (S, Builtin.NativeObject) -> () { -bb0(%0 : $S, %1 : $Builtin.NativeObject): - retain_value %0 : $S - strong_release %1 : $Builtin.NativeObject - release_value %0 : $S - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @dont_delete_retain_over_decrement_use : $@convention(thin) (@box Builtin.Int32) -> () -// CHECK: bb0 -// CHECK: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @dont_delete_retain_over_decrement_use : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @dont_delete_copyvalue_over_decrement_use : $@convention(thin) (S) -> () -// CHECK: bb0 -// CHECK: retain_value -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: release_value -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @dont_delete_copyvalue_over_decrement_use : $@convention(thin) (S) -> () { -bb0(%0 : $S): - %1 = function_ref @S_user : $@convention(thin) (S) -> () - retain_value %0 : $S - apply %1 (%0) : $@convention(thin) (S) -> () - apply %1 (%0) : $@convention(thin) (S) -> () - release_value %0 : $S - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @move_delete_retain_over_decrement_use_when_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () -// CHECK: bb0 -// CHECK: integer_literal -// CHECK-NEXT: integer_literal -// CHECK-NEXT: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @move_delete_retain_over_decrement_use_when_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - %2 = integer_literal $Builtin.Int32, 1 - %3 = integer_literal $Builtin.Int32, 2 - strong_retain %0 : $@box Builtin.Int32 - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - strong_release %0 : $@box Builtin.Int32 - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @delete_copyvalue_over_decrement_use_when_knownsafe : $@convention(thin) (S) -> () -// CHECK: bb0 -// CHECK: integer_literal -// CHECK-NEXT: integer_literal -// CHECK-NEXT: retain_value -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: release_value -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @delete_copyvalue_over_decrement_use_when_knownsafe : $@convention(thin) (S) -> () { -bb0(%0 : $S): - %1 = function_ref @S_user : $@convention(thin) (S) -> () - retain_value %0 : $S - %2 = integer_literal $Builtin.Int32, 1 - %3 = integer_literal $Builtin.Int32, 2 - retain_value %0 : $S - apply %1 (%0) : $@convention(thin) (S) -> () - apply %1 (%0) : $@convention(thin) (S) -> () - release_value %0 : $S - release_value %0 : $S - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @literals_do_not_use_values_with_reference_semantics : $@convention(thin) (@box Builtin.Int32) -> () -// CHECK: bb0 -// CHECK-NEXT: function_ref -// CHECK-NEXT: function_ref -// CHECK-NEXT: apply -// CHECK-NEXT: function_ref -// CHECK-NEXT: function_ref -// CHECK-NEXT: integer_literal -// CHECK-NEXT: string_literal -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @literals_do_not_use_values_with_reference_semantics : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - strong_retain %0 : $@box Builtin.Int32 - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - %4 = integer_literal $Builtin.Int64, 0 - %5 = string_literal utf8 "123" - strong_release %0 : $@box Builtin.Int32 - %6 = tuple() - return %6 : $() -} - -// CHECK-LABEL: sil @owned_arguments_are_known_safe_in_the_first_bb -// CHECK: bb0 -// CHECK-NEXT: function_ref -// CHECK-NEXT: function_ref -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -// CHECK-NEXT: br -// CHECK: bb1: -// CHECK-NEXT: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @owned_arguments_are_known_safe_in_the_first_bb : $@convention(thin) (@owned @box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - strong_release %0 : $@box Builtin.Int32 - br bb1 - -bb1: - strong_retain %0 : $@box Builtin.Int32 - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: @simple_alias_store_use_test : $@convention(thin) (@box Builtin.Int32, @inout Builtin.Int32) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @simple_alias_store_use_test : $@convention(thin) (@box Builtin.Int32, @inout Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32, %1 : $*Builtin.Int32): - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - %3 = integer_literal $Builtin.Int32, 2 - strong_retain %0 : $@box Builtin.Int32 - apply %2 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - store %3 to %1 : $*Builtin.Int32 - strong_release %0 : $@box Builtin.Int32 - %4 = tuple() - return %4: $() -} - -// We can't remove the retain-release pair because the apply may be -// decrementing the refcount on our object. -// CHECK-LABEL: @simple_alias_load_use_test : $@convention(thin) (@inout Builtin.Int32) -> () { -// CHECK: bb0 -// CHECK-NEXT: alloc_box -// CHECK-NEXT: function_ref -// CHECK-NEXT: function_ref -// CHECK-NEXT: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: load -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @simple_alias_load_use_test : $@convention(thin) (@inout Builtin.Int32) -> () { -bb0(%0 : $*Builtin.Int32): - %1 = alloc_box $Builtin.Int32 - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %1#0 : $@box Builtin.Int32 - apply %2 (%1#0) : $@convention(thin) (@box Builtin.Int32) -> () - %3 = load %1#1 : $*Builtin.Int32 - strong_release %1#0 : $@box Builtin.Int32 - %4 = tuple() - return %4: $() -} - -// We *CAN* remove the pair if we have an iterated strong_release though. -// -// CHECK-LABEL: @simple_alias_load_use_test_two_release : $@convention(thin) (@inout Builtin.Int32) -> () { -// CHECK: bb0 -// CHECK-NEXT: alloc_box -// CHECK-NEXT: function_ref -// CHECK-NEXT: function_ref -// CHECK-NEXT: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: load -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @simple_alias_load_use_test_two_release : $@convention(thin) (@inout Builtin.Int32) -> () { -bb0(%0 : $*Builtin.Int32): - %1 = alloc_box $Builtin.Int32 - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %1#0 : $@box Builtin.Int32 - strong_retain %1#0 : $@box Builtin.Int32 - apply %2 (%1#0) : $@convention(thin) (@box Builtin.Int32) -> () - %3 = load %1#1 : $*Builtin.Int32 - strong_release %1#0 : $@box Builtin.Int32 - strong_release %1#0 : $@box Builtin.Int32 - %4 = tuple() - return %4: $() -} - -// CHECK-LABEL: sil @silargument_retain_iterated : $@convention(thin) (@owned @box Builtin.Int32) -> () -// CHECK: bb0 -// CHECK-NEXT: function_ref user -// CHECK-NEXT: function_ref @user -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -// CHECK-NEXT: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -sil @silargument_retain_iterated : $@convention(thin) (@owned @box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - strong_release %0 : $@box Builtin.Int32 - strong_retain %0 : $@box Builtin.Int32 - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1 (%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @value_that_does_not_alias_pointer_args_cannot_be_decremented : $@convention(thin) (Cls) -> () -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @value_that_does_not_alias_pointer_args_cannot_be_decremented : $@convention(thin) (Cls) -> () { -bb0(%0 : $Cls): - %1 = alloc_ref $Cls - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - %3 = unchecked_ref_cast %0 : $Cls to $@box Builtin.Int32 - strong_retain %1 : $Cls - apply %2(%3) : $@convention(thin) (@box Builtin.Int32) -> () - apply %2(%3) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %1 : $Cls - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @escaping_pointer_can_have_refcount_decremented_indirectly : $@convention(thin) (@box Builtin.Int32) -> () -// CHECK: strong_retain -// CHECK: strong_release - -sil @the_kraken : $@convention(thin) () -> () -sil @escaping_pointer_can_have_refcount_decremented_indirectly : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @the_kraken : $@convention(thin) () -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1() : $@convention(thin) () -> () - apply %1() : $@convention(thin) () -> () - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// Make sure that we clear state and don't do anything in the fact of -// autorelease push/pop. -sil @objc_autoreleasePoolPush : $@convention(thin) () -> Builtin.RawPointer -sil @objc_autoreleasePoolPop : $@convention(thin) (Builtin.RawPointer) -> () - -// CHECK-LABEL: sil @clear_state_in_fact_of_autorelease_pool_ops : $@convention(thin) (Builtin.RawPointer) -> () { -// CHECK: bb0 -// CHECK-NEXT: function_ref objc_autoreleasePoolPush -// CHECK-NEXT: function_ref @objc_autoreleasePoolPush -// CHECK-NEXT: function_ref objc_autoreleasePoolPop -// CHECK-NEXT: function_ref @objc_autoreleasePoolPop -// CHECK-NEXT: alloc_box -// CHECK-NEXT: retain -// CHECK-NEXT: apply -// CHECK-NEXT: release -// CHECK-NEXT: retain -// CHECK-NEXT: apply -// CHECK-NEXT: release -// CHECK-NEXT: release -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @clear_state_in_fact_of_autorelease_pool_ops : $@convention(thin) (Builtin.RawPointer) -> () { -bb0(%0 : $Builtin.RawPointer): - %1 = function_ref @objc_autoreleasePoolPush : $@convention(thin) () -> Builtin.RawPointer - %2 = function_ref @objc_autoreleasePoolPop : $@convention(thin) (Builtin.RawPointer) -> () - %3 = alloc_box $Builtin.Int32 - strong_retain %3#0 : $@box Builtin.Int32 - apply %1() : $@convention(thin) () -> Builtin.RawPointer - strong_release %3#0 : $@box Builtin.Int32 - strong_retain %3#0 : $@box Builtin.Int32 - apply %2(%0) : $@convention(thin) (Builtin.RawPointer) -> () - strong_release %3#0 : $@box Builtin.Int32 - strong_release %3#0 : $@box Builtin.Int32 - %4 = tuple() - return %4 : $() -} - - -// CHECK-LABEL: sil @release_can_decrement_other_releases : $@convention(thin) () -> () { -// CHECK: strong_retain -// CHECK: strong_release -// CHECK: strong_release -sil @release_can_decrement_other_releases : $@convention(thin) () -> () { -bb0: - %1 = alloc_box $Builtin.Int32 - %2 = alloc_stack $@box Builtin.Int32 - store %1#0 to %2#1 : $*@box Builtin.Int32 - %4 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %1#0 : $@box Builtin.Int32 - %6 = load %2#1 : $*@box Builtin.Int32 - %7 = apply %4(%6) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %6 : $@box Builtin.Int32 - strong_release %1#0 : $@box Builtin.Int32 - dealloc_stack %2#0 : $*@local_storage @box Builtin.Int32 - %11 = tuple () - return %11 : $() -} - -// CHECK-LABEL: sil @retain_can_be_used_by_other_pointer : $@convention(thin) (RetainUser, @box Builtin.Int32) -> @box Builtin.Int32 { -// CHECK: strong_retain -// CHECK: strong_retain -// CHECK: strong_release -sil @retain_can_be_used_by_other_pointer : $@convention(thin) (RetainUser, @box Builtin.Int32) -> @box Builtin.Int32 { -bb0(%0 : $RetainUser, %1 : $@box Builtin.Int32): - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $RetainUser - apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %1 : $@box Builtin.Int32 - strong_release %0 : $RetainUser - return %1 : $@box Builtin.Int32 -} - - -//////////////////// -// Multi-BB tests // -//////////////////// - -////////////// -// Hammocks // -////////////// - -// CHECK-LABEL: sil @hammock1 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @hammock1 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - br bb2 - -bb2: - strong_release %0 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// This hammock can not be optimized. -// CHECK-LABEL: sil @hammock2 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK: bb1: -// CHECK-NEXT: strong_retain -// CHECK: bb2: -// CHECK-NEXT: strong_release -sil @hammock2 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $Builtin.NativeObject - br bb2 - -bb2: - strong_release %0 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -/// This hammock can't be optimized. -// CHECK-LABEL: sil @hammock3 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK: bb1: -// CHECK-NEXT: strong_release -// CHECK: bb2: -// CHECK-NEXT: strong_release -sil @hammock3 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - br bb2 - -bb2: - strong_release %0 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// This should not be optimizable. -// CHECK-LABEL: sil @hammock4 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -// CHECK: bb1: -// CHECK-NEXT: strong_retain -// CHECK: bb2: -// CHECK-NEXT: strong_release -sil @hammock4 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $Builtin.NativeObject - br bb2 - -bb2: - strong_release %0 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @hammock5 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NOT: strong_release -// CHECK-NOT: strong_retain -// CHECK: bb1: -// CHECK-NEXT: strong_release -// CHECK: bb2: -// CHECK-NEXT: strong_release -sil @hammock5 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - br bb2 - -bb2: - strong_release %0 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @hammock6 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -// CHECK: bb1: -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -// CHECK: bb2: -// CHECK-NEXT: strong_release -sil @hammock6 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - cond_br undef, bb1, bb2 - -bb1: - br bb2 - -bb2: - strong_release %0 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @hammock7 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK: bb1: -// CHECK-NEXT: strong_retain -// CHECK: bb2: -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @hammock7 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $Builtin.NativeObject - br bb2 - -bb2: - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @hammock8 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK-NOT: strong_release -// CHECK: bb1: -// CHECK-NEXT: strong_release -// CHECK-NOT: strong_retain -// CHECK: bb2: -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @hammock8 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - br bb2 - -bb2: - %9999 = tuple() - return %9999 : $() -} - -//////////////////// -// Double Hammock // -//////////////////// - -// Make sure we do not do anything in the presense of double partial -// applies. This is due to issues related to the two branches of the two -// diamonds not being control dependent. -// CHECK-LABEL: sil @double_hammock1 : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: bb0 -// CHECK-NEXT: function_ref user -// CHECK-NEXT: function_ref @user -// CHECK-NEXT: strong_retain -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: apply -// CHECK-NEXT: bb2 -// CHECK: bb2: -// CHECK-NEXT: cond_br -// CHECK: bb3: -// CHECK-NEXT: apply -// CHECK-NEXT: br -// CHECK: bb4: -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @double_hammock1 : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - cond_br undef, bb1, bb2 - -bb1: - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - br bb2 - -bb2: - cond_br undef, bb3, bb4 - -bb3: - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - br bb4 - -bb4: - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -////////////// -// Diamonds // -////////////// - -// CHECK-LABEL: sil @diamond1 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @diamond1 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond2 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: strong_release -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond2 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - br bb3 - -bb2: - strong_release %0 : $Builtin.NativeObject - br bb3 - -bb3: - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond3 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: strong_release -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond3 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - br bb3 - -bb2: - br bb3 - -bb3: - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond4 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @diamond4 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - br bb3 - -bb2: - strong_release %0 : $Builtin.NativeObject - br bb3 - -bb3: - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond5 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: strong_release -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond5 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond6 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: strong_release -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond6 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - br bb3 - -bb2: - strong_release %0 : $Builtin.NativeObject - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond7 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond7 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - br bb3 - -bb2: - strong_release %0 : $Builtin.NativeObject - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond8 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: strong_retain -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond8 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $Builtin.NativeObject - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -/// CHECK-LABEL: sil @diamond9 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: strong_retain -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond9 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - cond_br undef, bb1, bb2 - -bb1: - br bb3 - -bb2: - strong_retain %0 : $Builtin.NativeObject - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond10 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @diamond10 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $Builtin.NativeObject - br bb3 - -bb2: - strong_retain %0 : $Builtin.NativeObject - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -/// CHECK-LABEL: sil @diamond11 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: strong_retain -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond11 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $Builtin.NativeObject - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @diamond12 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: bb0 -// CHECK-NEXT: strong_retain -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: br -// CHECK: bb2: -// CHECK-NEXT: strong_retain -// CHECK-NEXT: br -// CHECK: bb3: -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple () -// CHECK-NEXT: return -sil @diamond12 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - br bb3 - -bb2: - strong_retain %0 : $Builtin.NativeObject - br bb3 - -bb3: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() -} - -// CHECK: sil @unreachable_bb : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @unreachable_bb : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() - -bb2: - %3 = builtin "int_trap"() : $() - unreachable -} - -// CHECK: sil @dont_move_values_in_face_of_partial_merges : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: strong_retain -// CHECK: strong_release -sil @dont_move_values_in_face_of_partial_merges : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - cond_br undef, bb1, bb2 - -bb1: - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @do_remove_values_in_face_of_partial_merges : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: strong_retain -// CHECK-NOT: strong_retain -// CHECK-NEXT: cond_br -// CHECK: bb3: -// CHECK-NEXT: strong_release -// CHECK-NOT: strong_release -sil @do_remove_values_in_face_of_partial_merges : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - strong_retain %0 : $@box Builtin.Int32 - cond_br undef, bb1, bb2 - -bb1: - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %0 : $@box Builtin.Int32 - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @release_use_optimization : $@convention(thin) (@owned @box Builtin.Int32) -> () { -// CHECK-NOT: strong_retain -// CHECK: strong_release -// CHECK-NOT: strong_release -sil @release_use_optimization : $@convention(thin) (@owned @box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @increment_known_safe_merge_with_last_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: bb1: -// CHECK-NEXT: strong_retain -// CHECK-NEXT: br bb3 -// CHECK: bb2: -// CHECK-NEXT: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: br bb3 -// CHECK: bb3: -// CHECK-NEXT: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -// CHECK-NEXT: tuple -// CHECK-NEXT: return -sil @increment_known_safe_merge_with_last_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $@box Builtin.Int32 - strong_retain %0 : $@box Builtin.Int32 - br bb3 - -bb2: - strong_retain %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - br bb3 - -bb3: - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @decrement_known_safe_merge_with_last_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: bb0( -// CHECK-NEXT: function_ref -// CHECK-NEXT: function_ref -// CHECK-NEXT: strong_retain -// CHECK-NEXT: apply -// CHECK-NEXT: apply -// CHECK-NEXT: strong_release -// CHECK-NEXT: cond_br -// CHECK: bb1: -// CHECK-NEXT: strong_release -// CHECK-NEXT: br bb3 -// CHECK-NOT: strong_release -sil @decrement_known_safe_merge_with_last_knownsafe : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $@box Builtin.Int32 - strong_release %0 : $@box Builtin.Int32 - br bb3 - -bb2: - strong_release %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - br bb3 - -bb3: - %2 = tuple() - return %2 : $() -} - -// Just make sure we don't crash on this. -// CHECK-LABEL: sil @unreachable_pred : $@convention(thin) (Builtin.NativeObject) -> () { -sil @unreachable_pred : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - br bb2 - -bb1: - br bb2 - -bb2: - %1 = tuple() - return %1 : $() -} - -// CHECK-LABEL: sil @arg_merge : $@convention(thin) (@owned S) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @arg_merge : $@convention(thin) (@owned S) -> () { -bb0(%0 : $S): - %1 = struct_extract %0 : $S, #S.x - strong_retain %1 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %1 : $Builtin.NativeObject - %2 = tuple() - return %2 : $() -} - - -/// Make sure we strip off casts when inserting new retains, releases. Otherwise -/// we run into dominance problems if the bitcast is in a branch. -// CHECK-LABEL: sil @switch_merge_with_bit_cast_in_branches : $@convention(thin) (@owned S) -> () { -// CHECK: bb1: -// CHECK-NOT: strong_retain -// CHECK: bb2: -// CHECK-NOT: strong_retain -// CHECK: bb3: -// CHECK: retain_value -// CHECK: release_value -sil @switch_merge_with_bit_cast_in_branches : $@convention(thin) (@owned S) -> () { -bb0(%0 : $S): - cond_br undef, bb1, bb2 - -bb1: - %1 = struct_extract %0 : $S, #S.x - %2 = unchecked_ref_cast %1 : $Builtin.NativeObject to $@box Builtin.Int32 - strong_retain %2 : $@box Builtin.Int32 - br bb3 - -bb2: - %3 = struct_extract %0 : $S, #S.x - %4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $@box Builtin.Int32 - strong_retain %4 : $@box Builtin.Int32 - br bb3 - -bb3: - %5 = struct_extract %0 : $S, #S.x - %6 = unchecked_ref_cast %5 : $Builtin.NativeObject to $@box Builtin.Int32 - %7 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %7(%6) : $@convention(thin) (@box Builtin.Int32) -> () - apply %7(%6) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %6 : $@box Builtin.Int32 - %11 = tuple() - return %11 : $() -} - -// CHECK-LABEL: sil @strip_off_layout_compatible_typed_geps : $@convention(thin) (S, FakeOptional) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -sil @strip_off_layout_compatible_typed_geps : $@convention(thin) (S, FakeOptional) -> () { -bb0(%0 : $S, %1 : $FakeOptional): - %2 = struct_extract %0 : $S, #S.x - strong_retain %2 : $Builtin.NativeObject - release_value %0 : $S - %3 = unchecked_enum_data %1 : $FakeOptional, #FakeOptional.Some!enumelt.1 - strong_retain %3 : $Builtin.NativeObject - release_value %1 : $FakeOptional - %5 = tuple() - return %5 : $() -} - -// CHECK-LABEL: sil @strip_off_single_pred_args : $@convention(thin) (FakeOptional) -> () { -// CHECK-NOT: retain_value -// CHECK-NOT: strong_release -sil @strip_off_single_pred_args : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1(%1 : $Builtin.NativeObject): - retain_value %0 : $FakeOptional - strong_release %1 : $Builtin.NativeObject - br bb3 - -bb2: - br bb3 - -bb3: - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @unreachable_bb_2 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @unreachable_bb_2 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - %4 = integer_literal $Builtin.Int1, -1 - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() - -bb2: - cond_fail %4 : $Builtin.Int1 - unreachable -} - -// CHECK-LABEL: sil @unreachable_bb_3 : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @unreachable_bb_3 : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb1, bb2 - -bb1: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() - -bb2: - %4 = integer_literal $Builtin.Int1, -1 - cond_fail %4 : $Builtin.Int1 - unreachable -} - -// CHECK-LABEL: sil @strip_off_multi_payload_unchecked_enum_data : $@convention(thin) (Either) -> () { -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @strip_off_multi_payload_unchecked_enum_data : $@convention(thin) (Either) -> () { -bb0(%0 : $Either): - retain_value %0 : $Either - %1 = unchecked_enum_data %0 : $Either, #Either.Right!enumelt.1 - release_value %1 : $S - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @strip_off_structs_only_non_trivial_field : $@convention(thin) (S2, S3) -> () { -// CHECK: bb0([[ARG0:%[0-9]+]] : $S2, [[ARG1:%[0-9]+]] : $S3): -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -// CHECK: retain_value [[ARG1]] -// CHECK-NEXT: [[EXT:%[0-9]+]] = struct_extract [[ARG1]] -// CHECK-NEXT: release_value [[EXT]] -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -sil @strip_off_structs_only_non_trivial_field : $@convention(thin) (S2, S3) -> () { -bb0(%0 : $S2, %1 : $S3): - retain_value %0 : $S2 - %2 = struct_extract %0 : $S2, #S2.y - release_value %2 : $Builtin.NativeObject - retain_value %1 : $S3 - %3 = struct_extract %1 : $S3, #S3.y - release_value %3 : $Builtin.NativeObject - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @strip_off_enum_from_payload : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @strip_off_enum_from_payload : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - %1 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %0 : $Builtin.NativeObject - strong_retain %0 : $Builtin.NativeObject - release_value %1 : $FakeOptional - %2 = tuple() - return %2 : $() -} - -// For now make sure we don't eliminate this. -// CHECK-LABEL: sil @guaranteed_is_always_known_safe : $@convention(thin) (@guaranteed @box Builtin.Int32) -> () { -// CHECK: retain -// CHECK: release -sil @guaranteed_is_always_known_safe : $@convention(thin) (@guaranteed @box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -sil @_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_ : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () // user: %43 - -sil @random_prefix_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_ : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () // user: %43 - -// CHECK-LABEL: sil @ignore_fatalErrorMsgBB : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @ignore_fatalErrorMsgBB : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb4, bb5 - -bb2: - strong_retain %0 : $Builtin.NativeObject - cond_br undef, bb3, bb4 - -bb3: - cond_br undef, bb4, bb6 - -bb4: - strong_release %0 : $Builtin.NativeObject - %1 = tuple() - return %1 : $() - -bb5: - %39 = function_ref @_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_ : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () // user: %43 - %40 = string_literal utf8 "fatal error" - %41 = integer_literal $Builtin.Word, 11 - %42 = integer_literal $Builtin.Int8, 11 - %43 = struct $StaticString (%40 : $Builtin.RawPointer, %41 : $Builtin.Word, %42 : $Builtin.Int8) - %44 = apply %39(%43, %43, %43) : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () - unreachable - -bb6: - %45 = function_ref @random_prefix_TFs18_fatalErrorMessageFTVs12StaticStringS_S_Su_T_ : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () // user: %43 - %46 = string_literal utf8 "fatal error" - %47 = integer_literal $Builtin.Word, 11 - %48 = integer_literal $Builtin.Int8, 11 - %49 = struct $StaticString (%46 : $Builtin.RawPointer, %47 : $Builtin.Word, %48 : $Builtin.Int8) - %50 = apply %45(%49, %49, %49) : $@convention(thin) @noreturn (StaticString, StaticString, StaticString) -> () - unreachable -} - -// CHECK-LABEL: sil @propagate_postdominating_owned_release_info : $@convention(thin) (@owned @box Builtin.Int32) -> () { -// CHECK: bb0( -// CHECK-NOT: retain -// CHECK-NOT: release -// CHECK: bb1: -// CHECK-NOT: retain -// CHECK-NOT: release -// CHECK: bb2: -// CHECK: strong_release -sil @propagate_postdominating_owned_release_info : $@convention(thin) (@owned @box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - br bb1 - -bb1: - cond_br undef, bb1, bb2 - -bb2: - strong_release %0 : $@box Builtin.Int32 - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @guaranteed_is_a_mayuse_maydecrement : $@convention(thin) (@owned Builtin.NativeObject) -> () { -// CHECK: retain -// CHECK: release -sil @guaranteed_is_a_mayuse_maydecrement : $@convention(thin) (@owned Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - %1 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - strong_retain %0 : $Builtin.NativeObject - apply %1(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - strong_release %0 : $Builtin.NativeObject - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @guaranteed_is_a_mayuse_maydecrement_can_remove_if_known_safe : $@convention(thin) (@owned Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK: strong_retain -// CHECK-NEXT: apply -// CHECK: strong_release -// CHECK-NOT: strong_release -sil @guaranteed_is_a_mayuse_maydecrement_can_remove_if_known_safe : $@convention(thin) (@owned Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - %1 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - strong_retain %0 : $Builtin.NativeObject - strong_retain %0 : $Builtin.NativeObject - apply %1(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - strong_release %0 : $Builtin.NativeObject - strong_release %0 : $Builtin.NativeObject - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @guaranteed_check_if_we_already_have_insertion_pt_we_use_that_one : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { -// CHECK: function_ref @guaranteed_use -// CHECK: strong_retain -// CHECK: strong_release -// CHECK: apply -// CHECK: function_ref @guaranteed_use -// CHECK: strong_retain -// CHECK: strong_release -// CHECK: function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () -sil @guaranteed_check_if_we_already_have_insertion_pt_we_use_that_one : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - %2 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - strong_release %1 : $Builtin.NativeObject - %3 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - apply %2(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - %4 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - strong_retain %1 : $Builtin.NativeObject - %5 = function_ref @guaranteed_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () - strong_release %0 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// Make sure that we handle ARC branch uses correctly. - -// In the face of partial merges, we *can* remove retains, releases, but we can -// not move them. So remove these retains, releases. -// -// CHECK-LABEL: sil @branch_use1 : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @branch_use1 : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $@box Builtin.Int32 - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - br bb3 - -bb2: - strong_retain %0 : $@box Builtin.Int32 - br bb3 - -bb3: - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// We currently do not move this retain, release since we are very conservative with partial merges and code motion. -// -// CHECK-LABEL: sil @branch_use2 : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: strong_retain -// CHECK: strong_retain -// CHECK: strong_release -sil @branch_use2 : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $@box Builtin.Int32 - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - br bb3 - -bb2: - strong_retain %0 : $@box Builtin.Int32 - br bb3 - -bb3: - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// We can not ignore this branch since bb3 uses %0. -// -// CHECK-LABEL: sil @branch_use3 : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: strong_retain -// CHECK: strong_retain -// CHECK: strong_release -sil @branch_use3 : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - cond_br undef, bb1, bb2 - -bb1: - strong_retain %0 : $@box Builtin.Int32 - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - br bb3(undef : $@box Builtin.Int32) - -bb2: - strong_retain %0 : $@box Builtin.Int32 - br bb3(%0 : $@box Builtin.Int32) - -bb3(%2 : $@box Builtin.Int32): - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// Make sure that we properly ignore the cond_br and do not try to compare the -// pointer with the Builtin.Int1 arg. -// -// CHECK-LABEL: sil @cond_branch_use1 : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @cond_branch_use1 : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - strong_retain %0 : $@box Builtin.Int32 - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - %2 = integer_literal $Builtin.Int1, 0 - cond_br %2, bb1, bb2 - -bb1: - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// Make sure that we do not ignore the cond_br and do not try to compare the -// pointer with the Builtin.Int1 arg. -// -// CHECK-LABEL: sil @cond_branch_use2 : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: strong_retain -// CHECK: strong_release -sil @cond_branch_use2 : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - strong_retain %0 : $@box Builtin.Int32 - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - %2 = integer_literal $Builtin.Int1, 0 - cond_br %2, bb1(%0 : $@box Builtin.Int32), bb2 - -bb1(%3 : $@box Builtin.Int32): - br bb3 - -bb2: - br bb3 - -bb3: - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @cond_branch_use3 : $@convention(thin) (@box Builtin.Int32) -> () { -// CHECK: strong_retain -// CHECK: strong_release -sil @cond_branch_use3 : $@convention(thin) (@box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - strong_retain %0 : $@box Builtin.Int32 - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - %2 = integer_literal $Builtin.Int1, 0 - cond_br %2, bb2(%0 : $@box Builtin.Int32), bb1 - -bb2(%3 : $@box Builtin.Int32): - br bb3 - -bb1: - br bb3 - -bb3: - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @owned_return_value_test : $@convention(thin) () -> () { -// CHECK-NOT: strong_retain -// CHECK: strong_release -// CHECK-NOT: strong_release -sil @owned_return_value_test : $@convention(thin) () -> () { -bb0: - %0 = function_ref @owned_return : $@convention(thin) () -> (@owned @box Builtin.Int32) - %1 = apply %0() : $@convention(thin) () -> (@owned @box Builtin.Int32) - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %1 : $@box Builtin.Int32 - apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () - apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %1 : $@box Builtin.Int32 - strong_release %1 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @retains_that_are_not_removed_preserves_known_safety : $@convention(thin) (@owned @box Builtin.Int32, @box Builtin.Int32) -> () { -// CHECK-NOT: strong_retain -// CHECK: apply -// CHECK: apply -// CHECK-NOT: strong_release -// CHECK: strong_retain -// CHECK: apply -// CHECK: apply -// CHECK: strong_release -sil @retains_that_are_not_removed_preserves_known_safety : $@convention(thin) (@owned @box Builtin.Int32, @box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32, %1 : $@box Builtin.Int32): - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %2(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %2(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - strong_retain %0 : $@box Builtin.Int32 - apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () - apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @retains_that_are_removed_do_not_preserve_known_safety : $@convention(thin) (@owned @box Builtin.Int32, @box Builtin.Int32) -> () { -// CHECK: strong_retain -// CHECK: apply -// CHECK: apply -// CHECK: strong_release -// CHECK-NOT: strong_retain -// CHECK: apply -// CHECK-NOT: strong_release -sil @retains_that_are_removed_do_not_preserve_known_safety : $@convention(thin) (@owned @box Builtin.Int32, @box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32, %1 : $@box Builtin.Int32): - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %2(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %2(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - strong_retain %0 : $@box Builtin.Int32 - apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @alloc_ref_returns_at_p1 : $@convention(thin) () -> () { -// CHECK: alloc_ref -// CHECK-NOT: strong_retain -// CHECK: apply -// CHECK: apply -// CHECK: strong_release -// CHECK-NOT: strong_release -sil @alloc_ref_returns_at_p1 : $@convention(thin) () -> () { -bb0: - %0 = alloc_ref $Cls - %1 = unchecked_ref_cast %0 : $Cls to $@box Builtin.Int32 - strong_retain %0 : $Cls - %2 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () - apply %2(%1) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %1 : $@box Builtin.Int32 - strong_release %1 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @alloc_ref_dynamic_returns_at_p1 : $@convention(thin) () -> () { -// CHECK: alloc_ref_dynamic -// CHECK-NOT: strong_retain -// CHECK: apply -// CHECK: apply -// CHECK: strong_release -// CHECK-NOT: strong_release -sil @alloc_ref_dynamic_returns_at_p1 : $@convention(thin) () -> () { -bb0: - %0 = metatype $@thick Cls.Type - %1 = alloc_ref_dynamic %0 : $@thick Cls.Type, $Cls - %2 = unchecked_ref_cast %1 : $Cls to $@box Builtin.Int32 - strong_retain %1 : $Cls - %3 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %3(%2) : $@convention(thin) (@box Builtin.Int32) -> () - apply %3(%2) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %2 : $@box Builtin.Int32 - strong_release %2 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @must_use_test : $@convention(thin) (@owned @box Builtin.Int32) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @must_use_test : $@convention(thin) (@owned @box Builtin.Int32) -> () { -bb0(%0 : $@box Builtin.Int32): - %1 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - strong_retain %0 : $@box Builtin.Int32 - apply %1(%0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @alloc_box_returns_at_p1 : $@convention(thin) () -> () { -// CHECK: alloc_box -// CHECK-NOT: strong_retain -// CHECK: apply -// CHECK: apply -// CHECK: strong_release -// CHECK-NOT: strong_release -sil @alloc_box_returns_at_p1 : $@convention(thin) () -> () { -bb0: - %0 = alloc_box $Builtin.Int32 - strong_retain %0#0 : $@box Builtin.Int32 - %3 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - apply %3(%0#0) : $@convention(thin) (@box Builtin.Int32) -> () - apply %3(%0#0) : $@convention(thin) (@box Builtin.Int32) -> () - strong_release %0#0 : $@box Builtin.Int32 - strong_release %0#0 : $@box Builtin.Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @copyArrayDoesntDecrementRefCounts : $@convention(thin) (Builtin.RawPointer, Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @copyArrayDoesntDecrementRefCounts : $@convention(thin) (Builtin.RawPointer, Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.NativeObject): - %2 = metatype $@thick Builtin.Int32.Type - %3 = integer_literal $Builtin.Word, 1 - strong_retain %1 : $Builtin.NativeObject - %4 = builtin "copyArray"(%2 : $@thick Builtin.Int32.Type, %0 : $Builtin.RawPointer, %0 : $Builtin.RawPointer, %3 : $Builtin.Word) : $() - fix_lifetime %1 : $Builtin.NativeObject - strong_release %1 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @clibraryintrinsicsdonttouchrefcounts : $@convention(thin) (Builtin.RawPointer, Builtin.NativeObject) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @clibraryintrinsicsdonttouchrefcounts : $@convention(thin) (Builtin.RawPointer, Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.NativeObject): - %3 = integer_literal $Builtin.Int64, 1 - %4 = integer_literal $Builtin.Int32, 1 - %5 = integer_literal $Builtin.Int1, 0 - strong_retain %1 : $Builtin.NativeObject - %6 = builtin "int_memcpy_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %0 : $Builtin.RawPointer, %3 : $Builtin.Int64, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $() - fix_lifetime %1 : $Builtin.NativeObject - strong_release %1 : $Builtin.NativeObject - strong_retain %1 : $Builtin.NativeObject - %7 = builtin "int_memset_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %0 : $Builtin.RawPointer, %3 : $Builtin.Int64, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $() - fix_lifetime %1 : $Builtin.NativeObject - strong_release %1 : $Builtin.NativeObject - strong_retain %1 : $Builtin.NativeObject - %8 = builtin "int_memmove_RawPointer_RawPointer_Int64"(%0 : $Builtin.RawPointer, %0 : $Builtin.RawPointer, %3 : $Builtin.Int64, %4 : $Builtin.Int32, %5 : $Builtin.Int1) : $() - fix_lifetime %1 : $Builtin.NativeObject - strong_release %1 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @convert_function_preserves_rc_identity : $@convention(thin) () -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @convert_function_preserves_rc_identity : $@convention(thin) () -> () { -bb0: - %0 = function_ref @user : $@convention(thin) (@box Builtin.Int32) -> () - %1 = partial_apply %0() : $@convention(thin) (@box Builtin.Int32) -> () - strong_retain %1 : $@callee_owned (@box Builtin.Int32) -> () - %2 = convert_function %1 : $@callee_owned (@box Builtin.Int32) -> () to $@callee_owned (@box Builtin.Int32) -> () - strong_release %2 : $@callee_owned (@box Builtin.Int32) -> () - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil [fragile] @try_apply_test : $@convention(thin) (Builtin.NativeObject) -> @error ErrorType { -// CHECK: bb0 -// CHECK: strong_retain -// CHECK: bb1 -// CHECK: strong_release -// CHECK: bb2 -// CHECK: strong_release -sil [fragile] @try_apply_test : $@convention(thin) (Builtin.NativeObject) -> @error ErrorType { -bb0(%0 : $Builtin.NativeObject): - strong_retain %0 : $Builtin.NativeObject - %1 = function_ref @guaranteed_throwing_use : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error ErrorType - try_apply %1(%0) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error ErrorType, normal bb1, error bb2 - -bb1(%2 : $()): - strong_release %0 : $Builtin.NativeObject - return undef : $() - -bb2(%3 : $ErrorType): - strong_release %0 : $Builtin.NativeObject - throw %3 : $ErrorType -} diff --git a/test/SILPasses/globalarcopts_rcidentityanalysis.sil b/test/SILPasses/globalarcopts_rcidentityanalysis.sil deleted file mode 100644 index 403608b81d307..0000000000000 --- a/test/SILPasses/globalarcopts_rcidentityanalysis.sil +++ /dev/null @@ -1,591 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=0 -arc-sequence-opts %s | FileCheck %s -// RUN: %target-sil-opt -enable-sil-verify-all -enable-loop-arc=1 -arc-sequence-opts %s | FileCheck %s - -sil_stage canonical - -import Swift -import Builtin - -// Utilities - -sil @user : $@convention(thin) (Builtin.NativeObject) -> () - -struct S { - var x : Builtin.NativeObject -} -sil @S_user : $@convention(thin) (S) -> () - -struct S2 { - var x : Builtin.Int32 - var y : Builtin.NativeObject - var z : Builtin.Int32 -} - -struct S3 { - var x : Builtin.Int32 - var y : Builtin.NativeObject - var y1 : Builtin.NativeObject - var z : Builtin.Int32 -} - -class Cls { - var random : Builtin.Int32 - - init() -} - -class C { - var w : Optional -} - -class RetainUser { } - -sil @rawpointer_use: $@convention(thin) (Builtin.RawPointer) -> Bool - -enum FakeOptional { - case None - case Some(T) -} -sil @fakeoptional_user : $@convention(thin) (FakeOptional) -> () - -enum Either { - case Left(LTy) - case Right(RTy) -} - -/// This type allows us to make sure we are skipping cases correctly when -/// stripping off ref count identical opts. -enum FakeCasesOptional { - case None - case None1 - case Some(T) - case None2 - case Some2(T) - case None3 -} - -/////////// -// Tests // -/////////// - -// CHECK-LABEL: sil @silargument_strip_single_payload_case_enum1 : $@convention(thin) (FakeOptional) -> () { -// CHECK-NOT: retain -// CHECK-NOT: release -sil @silargument_strip_single_payload_case_enum1 : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1: - br bb3(%0 : $FakeOptional) - -bb2: - br bb3(%0 : $FakeOptional) - -bb3(%1 : $FakeOptional): - retain_value %1 : $FakeOptional - release_value %0 : $FakeOptional - %2 = tuple() - return %2 : $() -} - -// CHECK-LABEL: sil @silargument_strip_single_payload_case_enum2 : $@convention(thin) (FakeOptional) -> () { -// CHECK-NOT: retain -// CHECK-NOT: release -sil @silargument_strip_single_payload_case_enum2 : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1: - br bb3(%0 : $FakeOptional) - -bb2: - %1 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%1 : $FakeOptional) - -bb3(%2 : $FakeOptional): - retain_value %2 : $FakeOptional - release_value %0 : $FakeOptional - %3 = tuple() - return %3 : $() -} - -// This is supposed to fail b/c %0 is not .None down bb1. -// -// CHECK-LABEL: sil @silargument_strip_single_payload_case_enum3 : $@convention(thin) (FakeOptional) -> () { -// CHECK: retain -// CHECK: release -sil @silargument_strip_single_payload_case_enum3 : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1: - %1 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%1 : $FakeOptional) - -bb2: - br bb3(%0 : $FakeOptional) - -bb3(%2 : $FakeOptional): - retain_value %2 : $FakeOptional - release_value %0 : $FakeOptional - %3 = tuple() - return %3 : $() -} - -// Make sure we do not do anything dumb when we have two enums without payloads. -// CHECK-LABEL: sil @silargument_strip_single_payload_case_enum4 : $@convention(thin) (FakeOptional) -> () { -// CHECK: retain_value -// CHECK: release_value -sil @silargument_strip_single_payload_case_enum4 : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1: - %1 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%1 : $FakeOptional) - -bb2: - %2 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%2 : $FakeOptional) - -bb3(%3 : $FakeOptional): - retain_value %3 : $FakeOptional - release_value %0 : $FakeOptional - %4 = tuple() - return %4 : $() -} - -// Make sure that we can handle the multi payload case with interleaved empty -// payloads. -// CHECK-LABEL: sil @silargument_strip_multipayload_with_fake_nopayload_cases : $@convention(thin) (FakeCasesOptional) -> () { -// CHECK-NOT: retain -// CHECK-NOT: release -sil @silargument_strip_multipayload_with_fake_nopayload_cases : $@convention(thin) (FakeCasesOptional) -> () { -bb0(%0 : $FakeCasesOptional): - switch_enum %0 : $FakeCasesOptional, case #FakeCasesOptional.None!enumelt: bb1, case #FakeCasesOptional.None1!enumelt: bb2, case #FakeCasesOptional.Some!enumelt.1: bb3, case #FakeCasesOptional.None2!enumelt: bb4, case #FakeCasesOptional.Some2!enumelt.1: bb5, case #FakeCasesOptional.None3!enumelt: bb6 - -bb1: - %1 = enum $FakeCasesOptional, #FakeCasesOptional.None!enumelt - br bb7(%1 : $FakeCasesOptional) - -bb2: - %2 = enum $FakeCasesOptional, #FakeCasesOptional.None1!enumelt - br bb7(%2 : $FakeCasesOptional) - -bb3: - br bb7(%0 : $FakeCasesOptional) - -bb4: - %3 = enum $FakeCasesOptional, #FakeCasesOptional.None2!enumelt - br bb7(%3 : $FakeCasesOptional) - -bb5: - br bb7(%0 : $FakeCasesOptional) - -bb6: - %4 = enum $FakeCasesOptional, #FakeCasesOptional.None3!enumelt - br bb7(%4 : $FakeCasesOptional) - -bb7(%5 : $FakeCasesOptional): - retain_value %5 : $FakeCasesOptional - release_value %0 : $FakeCasesOptional - %6 = tuple() - return %6 : $() -} - -// This looks like we are reforming an enum, but we are not really. Make sure -// that we do not remove the retain, release in this case. -// CHECK-LABEL: sil @silargument_fake_enum_reform : $@convention(thin) (Builtin.NativeObject) -> () { -// CHECK: retain_value -// CHECK: release_value -sil @silargument_fake_enum_reform : $@convention(thin) (Builtin.NativeObject) -> () { -bb0(%0 : $Builtin.NativeObject): - cond_br undef, bb1, bb2 - -bb1: - %1 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%1 : $FakeOptional) - -bb2: - %2 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %0 : $Builtin.NativeObject - br bb3(%2 : $FakeOptional) - -bb3(%3 : $FakeOptional): - retain_value %0 : $Builtin.NativeObject - release_value %3 : $FakeOptional - %9999 = tuple() - return %9999 : $() -} - -// Make sure that we can handle multiple-iterated enum args where the -// switch_enum or unchecked_enum_data is before the next diamond. -// CHECK-LABEL: sil @silargument_iterated_silargument_strips : $@convention(thin) (FakeOptional) -> () { -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -sil @silargument_iterated_silargument_strips : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1: - br bb3(%0 : $FakeOptional) - -bb2: - %1 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%1 : $FakeOptional) - -bb3(%2 : $FakeOptional): - switch_enum %2 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb4, case #FakeOptional.None!enumelt: bb5 - -bb4: - br bb6(%2 : $FakeOptional) - -bb5: - %3 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb6(%3 : $FakeOptional) - -bb6(%4 : $FakeOptional): - retain_value %0 : $FakeOptional - release_value %4 : $FakeOptional - %9999 = tuple() - return %9999 : $() -} - -// Make sure that (for now) we do not look past %2 to see that %0 can be matched -// up with %0, %4. -// -// I think this is in general safe, but for now I want to be more than less -// conservative. -// -// CHECK-LABEL: sil @silargument_iterated_silargument_strips_too_far_up_domtree : $@convention(thin) (FakeOptional) -> () { -// CHECK: retain_value -// CHECK: release_value -sil @silargument_iterated_silargument_strips_too_far_up_domtree : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1: - br bb3(%0 : $FakeOptional) - -bb2: - %1 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%1 : $FakeOptional) - -bb3(%2 : $FakeOptional): - cond_br undef, bb4, bb5 - -bb4: - br bb6(%2 : $FakeOptional) - -bb5: - %3 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb6(%3 : $FakeOptional) - -bb6(%4 : $FakeOptional): - retain_value %0 : $FakeOptional - release_value %4 : $FakeOptional - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @silargument_dont_strip_over_relevent_loop : $@convention(thin) (FakeOptional) -> () { -// CHECK: retain_value -// CHECK: release_value -sil @silargument_dont_strip_over_relevent_loop : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1: - br bb3(%0 : $FakeOptional) - -bb2: - %1 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%1 : $FakeOptional) - -bb3(%2 : $FakeOptional): - cond_br undef, bb3(%2 : $FakeOptional), bb4 - -bb4: - retain_value %0 : $FakeOptional - release_value %2 : $FakeOptional - %9999 = tuple() - return %9999 : $() -} - -// Make sure we are properly iterating up the domtree by checking if we properly -// look past the loop in bb4 and match up %0 and %2. -// -// CHECK-LABEL: sil @silargument_do_strip_over_irrelevent_loop : $@convention(thin) (FakeOptional) -> () { -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -sil @silargument_do_strip_over_irrelevent_loop : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - switch_enum %0 : $FakeOptional, case #FakeOptional.Some!enumelt.1: bb1, case #FakeOptional.None!enumelt: bb2 - -bb1: - br bb3(%0 : $FakeOptional) - -bb2: - %1 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%1 : $FakeOptional) - -bb3(%2 : $FakeOptional): - cond_br undef, bb4, bb5 - -bb4: - cond_br undef, bb4, bb5 - -bb5: - retain_value %0 : $FakeOptional - release_value %2 : $FakeOptional - %9999 = tuple() - return %9999 : $() -} - - - -// CHECK-LABEL: sil @silargument_nondominated_strip : $@convention(thin) (@in FakeOptional) -> () { -// CHECK: retain_value -// CHECK: release_value -sil @silargument_nondominated_strip : $@convention(thin) (@in FakeOptional) -> () { -bb0(%0 : $*FakeOptional): - cond_br undef, bb1, bb2 - -bb1: - %1 = load %0 : $*FakeOptional - br bb3(%1 : $FakeOptional) - -bb2: - %2 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb3(%2 : $FakeOptional) - -bb3(%3 : $FakeOptional): - %4 = function_ref @fakeoptional_user : $@convention(thin) (FakeOptional) -> () - retain_value %3 : $FakeOptional - apply %4(%3) : $@convention(thin) (FakeOptional) -> () - apply %4(%3) : $@convention(thin) (FakeOptional) -> () - release_value %3 : $FakeOptional - %5 = tuple() - return %5 : $() -} - -struct _SwiftEmptyArrayStorage { -} - -sil_global [fragile] @_swiftEmptyArrayStorage : $_SwiftEmptyArrayStorage - -// CHECK-LABEL: sil @dont_strip_rawpointer_to_address -// CHECK: raw_pointer_to_ref -// CHECK: strong_retain -// CHECK: return -sil @dont_strip_rawpointer_to_address : $@convention(thin) (FakeOptional) -> () { -bb0(%0 : $FakeOptional): - %2 = global_addr @_swiftEmptyArrayStorage : $*_SwiftEmptyArrayStorage - %3 = address_to_pointer %2 : $*_SwiftEmptyArrayStorage to $Builtin.RawPointer - %4 = raw_pointer_to_ref %3 : $Builtin.RawPointer to $Builtin.NativeObject - strong_retain %4 : $Builtin.NativeObject - %5 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () - apply %5(%4) : $@convention(thin) (Builtin.NativeObject) -> () - apply %5(%4) : $@convention(thin) (Builtin.NativeObject) -> () - strong_release %4 : $Builtin.NativeObject - %6 = tuple() - return %6 : $() -} - -// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_1bb : $@convention(thin) () -> () { -// CHECK: retain_value -// CHECK: release_value -sil @dont_strip_phi_nodes_over_backedges_1bb : $@convention(thin) () -> () { -bb0: - %0 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb1(%0 : $FakeOptional) - -bb1(%1 : $FakeOptional): - %2 = alloc_ref $Cls - retain_value %2 : $Cls - release_value %1 : $FakeOptional - %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls - cond_br undef, bb1(%3 : $FakeOptional), bb2 - -bb2: - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb1 : $@convention(thin) () -> () { -// CHECK: retain_value -// CHECK: release_value -sil @dont_strip_phi_nodes_over_backedges_multibb1 : $@convention(thin) () -> () { -bb0: - %0 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb1(%0 : $FakeOptional) - -bb1(%1 : $FakeOptional): - %2 = alloc_ref $Cls - retain_value %2 : $Cls - br bb2 - -bb2: - release_value %1 : $FakeOptional - %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls - br bb3 - -bb3: - cond_br undef, bb1(%3 : $FakeOptional), bb4 - -bb4: - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb2 : $@convention(thin) () -> () { -// CHECK: retain_value -// CHECK: release_value -sil @dont_strip_phi_nodes_over_backedges_multibb2 : $@convention(thin) () -> () { -bb0: - %0 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb1(%0 : $FakeOptional) - -bb1(%1 : $FakeOptional): - br bb2 - -bb2: - %2 = alloc_ref $Cls - retain_value %2 : $Cls - release_value %1 : $FakeOptional - %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls - br bb3 - -bb3: - cond_br undef, bb1(%3 : $FakeOptional), bb4 - -bb4: - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb3 : $@convention(thin) () -> () { -// CHECK: retain_value -// CHECK: release_value -sil @dont_strip_phi_nodes_over_backedges_multibb3 : $@convention(thin) () -> () { -bb0: - %0 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb1(%0 : $FakeOptional) - -bb1(%1 : $FakeOptional): - br bb2 - -bb2: - %2 = alloc_ref $Cls - retain_value %2 : $Cls - br bb3 - -bb3: - release_value %1 : $FakeOptional - %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls - cond_br undef, bb1(%3 : $FakeOptional), bb4 - -bb4: - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb4 : $@convention(thin) () -> () { -// CHECK: retain_value -// CHECK: release_value -sil @dont_strip_phi_nodes_over_backedges_multibb4 : $@convention(thin) () -> () { -bb0: - %0 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb1(%0 : $FakeOptional) - -bb1(%1 : $FakeOptional): - br bb2 - -bb2: - br bb3 - -bb3: - %2 = alloc_ref $Cls - retain_value %2 : $Cls - release_value %1 : $FakeOptional - %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls - cond_br undef, bb1(%3 : $FakeOptional), bb4 - -bb4: - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @dont_strip_phi_nodes_over_backedges_multibb5 : $@convention(thin) () -> () { -// CHECK: retain_value -// CHECK: release_value -sil @dont_strip_phi_nodes_over_backedges_multibb5 : $@convention(thin) () -> () { -bb0: - %0 = enum $FakeOptional, #FakeOptional.None!enumelt - br bb1(%0 : $FakeOptional) - -bb1(%1 : $FakeOptional): - %2 = alloc_ref $Cls - retain_value %2 : $Cls - br bb2 - -bb2: - br bb3 - -bb3: - release_value %1 : $FakeOptional - %3 = enum $FakeOptional, #FakeOptional.Some!enumelt.1, %2 : $Cls - cond_br undef, bb1(%3 : $FakeOptional), bb4 - -bb4: - %4 = tuple() - return %4 : $() -} - -// CHECK-LABEL: sil @strip_off_structs_tuples_tuple_extracts : $@convention(thin) (Builtin.NativeObject, (Builtin.Int32, Builtin.NativeObject, Builtin.Int32)) -> () { -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -sil @strip_off_structs_tuples_tuple_extracts : $@convention(thin) (Builtin.NativeObject, (Builtin.Int32, Builtin.NativeObject, Builtin.Int32)) -> () { -bb0(%0 : $Builtin.NativeObject, %1 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32)): - %2 = integer_literal $Builtin.Int32, 0 - %3 = struct $S2(%2 : $Builtin.Int32, %0 : $Builtin.NativeObject, %2 : $Builtin.Int32) - retain_value %3 : $S2 - %4 = tuple(%2 : $Builtin.Int32, %0 : $Builtin.NativeObject, %2 : $Builtin.Int32) - release_value %4 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32) - retain_value %1 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32) - %5 = tuple_extract %1 : $(Builtin.Int32, Builtin.NativeObject, Builtin.Int32), 1 - release_value %5 : $Builtin.NativeObject - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: sil @strip_off_initopen_existential_ref : $@convention(thin) (C) -> () { -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -// CHECK-NOT: retain_value -// CHECK-NOT: release_value -sil @strip_off_initopen_existential_ref : $@convention(thin) (C) -> () { -bb0(%0 : $C): - %1 = init_existential_ref %0 : $C : $C, $AnyObject - %2 = open_existential_ref %1 : $AnyObject to $@opened("A2E21C52-6089-11E4-9866-3C0754723233") AnyObject - strong_retain %0 : $C - release_value %2 : $@opened("A2E21C52-6089-11E4-9866-3C0754723233") AnyObject - %3 = tuple() - return %3 : $() -} - -// CHECK-LABEL: sil @strip_off_bridge_object -// CHECK-NOT: strong_retain -// CHECK-NOT: strong_release -sil @strip_off_bridge_object : $@convention(thin) (Builtin.BridgeObject, C) -> () { -bb0(%0 : $Builtin.BridgeObject, %5 : $C): - %1 = bridge_object_to_ref %0 : $Builtin.BridgeObject to $C - strong_retain %1 : $C - strong_release %0 : $Builtin.BridgeObject - %4 = integer_literal $Builtin.Word, 0 - %2 = ref_to_bridge_object %5 : $C, %4 : $Builtin.Word - strong_retain %5 : $C - strong_release %2 : $Builtin.BridgeObject - %3 = tuple() - return %3 : $() -} - diff --git a/test/SILPasses/inline_recursive.swift b/test/SILPasses/inline_recursive.swift deleted file mode 100644 index f9a7c5cf36cd3..0000000000000 --- a/test/SILPasses/inline_recursive.swift +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %target-swift-frontend -primary-file %s -parse-as-library -emit-sil -O | FileCheck %s - -private func recFunc(x: Int) -> Int { - if x > 0 { - return recFunc(x - 1) - } - return 0 -} - -//CHECK-LABEL: sil {{.*}}callit -// CHECK: bb0: -// CHECK-NEXT: integer_literal {{.*}}, 0 -// CHECK-NEXT: struct -// CHECK-NEXT: return - -func callit() -> Int { - return recFunc(3) -} - diff --git a/test/SILPasses/inout_deshadow.sil b/test/SILPasses/inout_deshadow.sil deleted file mode 100644 index a70da77e374bd..0000000000000 --- a/test/SILPasses/inout_deshadow.sil +++ /dev/null @@ -1,144 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -inout-deshadow | FileCheck %s - -sil_stage canonical - -import Builtin -import Swift - -protocol P { - func foo() -} - -sil @takeInt : $@convention(method) (@inout Int64) -> () - -sil @TrivialTest : $@convention(thin) (@inout Int64) -> () { -bb0(%0 : $*Int64): - %1 = alloc_stack $Int64 // var a // users: %6, %2, %4, %5 - copy_addr %0 to [initialization] %1#1 : $*Int64 - %3 = function_ref @takeInt : $@convention(method) (@inout Int64) -> () // user: %4 - %4 = apply %3(%1#1) : $@convention(method) (@inout Int64) -> () - copy_addr %1#1 to %0 : $*Int64 - dealloc_stack %1#0 : $*@local_storage Int64 - %7 = tuple () // user: %8 - return %7 : $() -} - - -// CHECK-LABEL: sil @AddressOnlyTest -sil @AddressOnlyTest : $@convention(thin) (@inout P) -> () { -bb0(%0 : $*P): // CHECK: bb0(%0 : $*P): - %1 = alloc_stack $P - copy_addr %0 to [initialization] %1#1 : $*P - - // CHECK-NEXT: debug_value_addr %0 - // CHECK-NEXT: open_existential_addr %0 : $*P - %3 = open_existential_addr %1#1 : $*P to $*@opened("01234567-89ab-cdef-0123-000000000000") P - %4 = witness_method $@opened("01234567-89ab-cdef-0123-000000000000") P, #P.foo!1, %3 : $*@opened("01234567-89ab-cdef-0123-000000000000") P : $@convention(witness_method) @callee_owned (@inout T) -> () - - // CHECK: apply - %5 = apply %4<@opened("01234567-89ab-cdef-0123-000000000000") P>(%3) : $@convention(witness_method) @callee_owned (@inout T) -> () - - copy_addr [take] %1#1 to %0 : $*P - dealloc_stack %1#0 : $*@local_storage P - - // CHECK-NEXT: tuple () - %9 = tuple () - // CHECK-NEXT: return - return %9 : $() -} - -class C { -} - -struct NontrivialStruct { - var a: Int - var b: C - func foo() -} - - -sil @takeNontrivial : $@convention(method) (@inout NontrivialStruct) -> () - -// CHECK-LABEL: sil @NontrivialTest -sil @NontrivialTest : $@convention(thin) (@inout NontrivialStruct) -> () { -bb0(%0 : $*NontrivialStruct): -// CHECK: bb0(%0 : $*NontrivialStruct): - - %1 = alloc_stack $NontrivialStruct - copy_addr %0 to [initialization] %1#1 : $*NontrivialStruct - - // CHECK-NEXT: debug_value_addr %0 - // CHECK-NEXT: // function_ref takeNontrivial - // CHECK-NEXT: function_ref @takeNontrivial - %3 = function_ref @takeNontrivial : $@convention(method) (@inout NontrivialStruct) -> () // user: %4 - - // CHECK-NEXT: apply - %4 = apply %3(%1#1) : $@convention(method) (@inout NontrivialStruct) -> () - copy_addr [take] %1#1 to %0 : $*NontrivialStruct - dealloc_stack %1#0 : $*@local_storage NontrivialStruct - - // CHECK-NEXT: tuple - %9 = tuple () - // CHECK-NEXT: return - return %9 : $() -} - -// Inout deshadowing should *not* deshadow inouts that are copied to temporaries for use by -// @in arguments. - -sil @in_argument : $@convention(thin) (@in protocol<>) -> () - -// CHECK-LABEL: sil @inout_argument_passed_to_in_argument -sil @inout_argument_passed_to_in_argument : $@convention(thin) (@inout protocol<>) -> () { -// CHECK: bb0([[INOUT:%.*]] : $*protocol<>): -entry(%0 : $*protocol<>): - %f = function_ref @in_argument : $@convention(thin) (@in protocol<>) -> () - %x = alloc_stack $protocol<> - // CHECK: copy_addr [[INOUT]] to [initialization] - copy_addr %0 to [initialization] %x#1 : $*protocol<> - %z = apply %f(%x#1) : $@convention(thin) (@in protocol<>) -> () - dealloc_stack %x#0 : $*@local_storage protocol<> - return %z : $() -} - -sil @makeError : $@convention(thin) () -> @owned ErrorType - -struct MyStruct { - @sil_stored var placeholder: T - @sil_stored var value: Bool - mutating func throwing(value: Bool) throws - init(placeholder: T, value: Bool) -} - -// Verify that we deshadow in functions that throw. -// CHECK-LABEL: throwing -sil hidden @throwing : $@convention(method) (Bool, @inout MyStruct) -> @error ErrorType { -// CHECK: bb0 -bb0(%0 : $Bool, %1 : $*MyStruct): - %2 = alloc_stack $MyStruct - debug_value %0 : $Bool -// CHECK-NOT: copy_addr - copy_addr %1 to [initialization] %2#1 : $*MyStruct - %5 = struct_extract %0 : $Bool, #Bool._value - cond_br %5, bb1, bb2 - -// CHECK: bb1 -bb1: - %7 = function_ref @makeError : $@convention(thin) () -> @owned ErrorType - %8 = apply %7() : $@convention(thin) () -> @owned ErrorType - %9 = builtin "willThrow"(%8 : $ErrorType) : $() -// CHECK-NOT: copy_addr - copy_addr [take] %2#1 to %1 : $*MyStruct - dealloc_stack %2#0 : $*@local_storage MyStruct - throw %8 : $ErrorType - -// CHECK: bb2 -bb2: - %12 = struct_element_addr %2#1 : $*MyStruct, #MyStruct.value - store %0 to %12 : $*Bool -// CHECK-NOT: copy_addr - copy_addr [take] %2#1 to %1 : $*MyStruct - %15 = tuple () - dealloc_stack %2#0 : $*@local_storage MyStruct - return %15 : $() -} diff --git a/test/SILPasses/loop_canonicalizer.sil b/test/SILPasses/loop_canonicalizer.sil deleted file mode 100644 index 716a524896fff..0000000000000 --- a/test/SILPasses/loop_canonicalizer.sil +++ /dev/null @@ -1,126 +0,0 @@ -// RUN: %target-sil-opt -loop-canonicalizer %s | FileCheck %s - -sil_stage canonical - -import Builtin -import Swift - -// Test insertPreheader -// CHECK-LABEL: sil @insert_preheader : $@convention(thin) () -> () { -// CHECK: bb0: -// CHECK: cond_br undef, bb1, bb4 -// CHECK: bb1: -// CHECK: br bb2 -// CHECK: bb2: -// CHECK: cond_br undef, bb2, bb3 -// CHECK: bb3: -// CHECK: br bb4 -// CHECK: bb4: -// CHECK: return undef -sil @insert_preheader : $@convention(thin) () -> () { -bb0: - cond_br undef, bb1, bb3 - -// A bb will be inserted along the edge from bb0 -> bb1. -bb1: - cond_br undef, bb1, bb2 - -// This is the exit block of the loop on bb1. We do this so this test *only* -// tests the preheader insertion vs the exit block canonicalization. -bb2: - br bb3 - -bb3: - return undef : $() -} - -// Test insertBackedgeBlock. -// -// CHECK-LABEL: insert_backedge_block -// CHECK: bb2: -// CHECK: cond_br undef, bb3, bb4 -// CHECK: bb3: -// CHECK: br bb1 -// CHECK: bb4: -// CHECK: cond_br undef, bb3, bb5 -sil @insert_backedge_block : $@convention(thin) () -> () { -bb0: - br bb1 - -bb1: - br bb2 - -bb2: - cond_br undef, bb1, bb3 - -bb3: - cond_br undef, bb1, bb4 - -bb4: - return undef : $() -} - -// CHECK-LABEL: sil @insert_backedge_block_inner_loop : $@convention(thin) () -> () { -// CHECK: bb1: -// CHECK: br bb2 -// CHECK: bb2: -// CHECK: br bb3 -// CHECK: bb3: -// CHECK: cond_br undef, bb4, bb5 -// CHECK: bb4: -// CHECK: br bb2 -// CHECK: bb5: -// CHECK: cond_br undef, bb4, bb6 -// CHECK: bb6: -// CHECK: cond_br undef, bb1, bb7 -// CHECK: bb7: -// CHECK: return undef -sil @insert_backedge_block_inner_loop : $@convention(thin) () -> () { -bb0: - br bb1 - -bb1: - br bb2 - -bb2: - br bb3 - -bb3: - cond_br undef, bb2, bb4 - -bb4: - cond_br undef, bb2, bb5 - -bb5: - cond_br undef, bb1, bb6 - -bb6: - return undef : $() -} - -// CHECK-LABEL: sil @exit_blocks_should_only_have_exiting_blocks_as_predecessors : $@convention(thin) () -> () { -// CHECK: bb0: -// CHECK: cond_br undef, bb1, bb4 -// CHECK: bb1: -// CHECK: br bb2 -// CHECK: bb2: -// CHECK: cond_br undef, bb2, bb3 -// CHECK: bb3: -// CHECK: br bb4 -// CHECK: bb4: -// CHECK: return undef -sil @exit_blocks_should_only_have_exiting_blocks_as_predecessors : $@convention(thin) () -> () { -bb0: - cond_br undef, bb1, bb3 - -// Header -bb1: - br bb2 - -bb2: - cond_br undef, bb2, bb3 - -// Exit with multiple predecessors. The edge from bb2 -> bb3 will be split. -bb3: - return undef : $() -} diff --git a/test/SILPasses/memlocation_expansion.sil b/test/SILPasses/memlocation_expansion.sil deleted file mode 100644 index 866a1d1f763bc..0000000000000 --- a/test/SILPasses/memlocation_expansion.sil +++ /dev/null @@ -1,303 +0,0 @@ -// RUN: %target-sil-opt %s -memlocation-dump -ml=only-expansion | FileCheck %s - -sil_stage canonical - -import Builtin - -/////////////////////// -// Type Declarations // -/////////////////////// - -struct Int { - var value : Builtin.Int64 -} - -struct Int64 { - var value : Builtin.Int64 -} - -struct Bool { - var value : Builtin.Int1 -} - -class B { - var i : Builtin.Int32 - init() -} - -struct S1 { - var a: Int - init(a: Int, b: Int) - init() -} - -struct S2 { - var a: Int - var b: Int - init(a: Int, b: Int) - init() -} - -struct S3 { - var a: S2 - var b: Int - var c: S2 - init(a: S2, b: Int, c: S2) - init() -} - -struct S4 { - var x: S3 - var y: S3 - init(x: S3, y: S3) - init() -} - -class SelfLoop { - var a: Int - var b: Int - var c: SelfLoop - deinit - init() -} - -struct S5 { - var a: SelfLoop - init(a: SelfLoop) - init() -} - -sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1 -sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2 -sil @S3_init : $@convention(thin) (@thin S3.Type) -> S3 -sil @S4_init : $@convention(thin) (@thin S4.Type) -> S4 -sil @S5_init : $@convention(thin) (@thin S5.Type) -> S5 - -// CHECK-LABEL: @stack_store -// CHECK: #0 store -// CHECK-NEXT: alloc_stack -sil @stack_store : $@convention(thin) () -> () { - %1 = alloc_stack $Builtin.Int64 - %9 = integer_literal $Builtin.Int64, 0 - store %9 to %1#1 : $*Builtin.Int64 - %4 = tuple() - dealloc_stack %1#0 : $*@local_storage Builtin.Int64 // id: %13 - %5 = return %4 : $() -} - -// CHECK-LABEL: @store_after_store -// CHECK: #0 store -// CHECK-NEXT: [[RET0:%.+]] = alloc_box -// CHECK: #1 store -// CHECK-NEXT: [[RET0:%.+]] = alloc_box -sil @store_after_store : $@convention(thin) (@owned B) -> () { -bb0(%0 : $B): - %1 = alloc_box $B - %2 = store %0 to %1#1 : $*B - %3 = store %0 to %1#1 : $*B - %4 = tuple() - %5 = return %4 : $() -} - -// CHECK-LABEL: @store_after_store_struct -// CHECK: #0 store -// CHECK-NEXT: [[RET0:%.+]] = alloc_stack -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK: #1 store -// CHECK-NEXT: [[RET0:%.+]] = alloc_stack -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -sil @store_after_store_struct : $@convention(thin) () -> () { - %1 = alloc_stack $S1 - %9 = integer_literal $Builtin.Int64, 0 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = struct_element_addr %1#1 : $*S1, #S1.a // user: %12 - store %10 to %11 : $*Int // id: %12 - store %10 to %11 : $*Int - %4 = tuple() - dealloc_stack %1#0 : $*@local_storage S1 // id: %13 - %5 = return %4 : $() -} - -// Make sure all the structs get expanded correctly. -// -// CHECK-LABEL: @many_struct_allocs -// CHECK: #0 store -// CHECK-NEXT: alloc_stack $S2 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: alloc_stack $S2 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK: #1 store -// CHECK-NEXT: alloc_stack $S3 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var c: S2 -// CHECK-NEXT: alloc_stack $S3 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var c: S2 -// CHECK-NEXT: alloc_stack $S3 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: alloc_stack $S3 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: alloc_stack $S3 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK: #2 store -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var c: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var y: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var c: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var y: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var y: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var y: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var y: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var c: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var x: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var c: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var x: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var x: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var x: S3 -// CHECK-NEXT: alloc_stack $S4 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Field Type: var x: S3 -sil hidden @many_struct_allocs : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S2 // var a // users: %6, %18 - %1 = alloc_stack $S3 // var b // users: %10, %17 - %2 = alloc_stack $S4 // var c // users: %14, %16 - %3 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %5 - %4 = metatype $@thin S2.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S2.Type) -> S2 // user: %6 - store %5 to %0#1 : $*S2 // id: %6 - // function_ref struct.S3.init (struct.S3.Type)() -> struct.S3 - %7 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %9 - %8 = metatype $@thin S3.Type // user: %9 - %9 = apply %7(%8) : $@convention(thin) (@thin S3.Type) -> S3 // user: %10 - store %9 to %1#1 : $*S3 // id: %10 - %11 = function_ref @S4_init : $@convention(thin) (@thin S4.Type) -> S4 // user: %13 - %12 = metatype $@thin S4.Type // user: %13 - %13 = apply %11(%12) : $@convention(thin) (@thin S4.Type) -> S4 // user: %14 - store %13 to %2#1 : $*S4 // id: %14 - %15 = tuple () // user: %19 - dealloc_stack %2#0 : $*@local_storage S4 // id: %16 - dealloc_stack %1#0 : $*@local_storage S3 // id: %17 - dealloc_stack %0#0 : $*@local_storage S2 // id: %18 - return %15 : $() // id: %19 -} - -// CHECK-LABEL: self_loop -// CHECK: #0 store -// CHECK-NEXT: alloc_stack $S5 // users: %4, %7 -// CHECK-NEXT: Address Projection Type: $*SelfLoop -// CHECK-NEXT: Field Type: var a: SelfLoop -sil hidden @self_loop : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S5 // var b // users: %4, %7 - %1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> S5 // user: %3 - %2 = metatype $@thin S5.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> S5 // users: %4, %5 - store %3 to %0#1 : $*S5 // id: %4 - release_value %3 : $S5 // id: %5 - %6 = tuple () // user: %8 - dealloc_stack %0#0 : $*@local_storage S5 // id: %7 - return %6 : $() // id: %8 -} diff --git a/test/SILPasses/memlocation_reduction.sil b/test/SILPasses/memlocation_reduction.sil deleted file mode 100644 index dfb03dc169f28..0000000000000 --- a/test/SILPasses/memlocation_reduction.sil +++ /dev/null @@ -1,171 +0,0 @@ -// RUN: %target-sil-opt %s -memlocation-dump -ml=only-reduction | FileCheck %s - -sil_stage canonical - -import Builtin - -/////////////////////// -// Type Declarations // -/////////////////////// - -struct Int { - var value : Builtin.Int64 -} - -struct Int64 { - var value : Builtin.Int64 -} - -struct Bool { - var value : Builtin.Int1 -} - -class B { - var i : Builtin.Int32 - init() -} - -struct S1 { - var a: Int - init(a: Int, b: Int) - init() -} - -struct S2 { - var a: Int - var b: Int - init(a: Int, b: Int) - init() -} - -struct S3 { - var a: S2 - var b: Int - var c: S2 - init(a: S2, b: Int, c: S2) - init() -} - -struct S4 { - var x: S3 - var y: S3 - init(x: S3, y: S3) - init() -} - -class SelfLoop { - var a: Int - var b: Int - var c: SelfLoop - deinit - init() -} - -struct S5 { - var a: SelfLoop - init(a: SelfLoop) - init() -} - -sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1 -sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2 -sil @S3_init : $@convention(thin) (@thin S3.Type) -> S3 -sil @S4_init : $@convention(thin) (@thin S4.Type) -> S4 -sil @S5_init : $@convention(thin) (@thin S5.Type) -> S5 - -// CHECK-LABEL: @stack_store -// CHECK: #0 store -// CHECK-NEXT: alloc_stack -sil @stack_store : $@convention(thin) () -> () { - %1 = alloc_stack $Builtin.Int64 - %9 = integer_literal $Builtin.Int64, 0 - store %9 to %1#1 : $*Builtin.Int64 - %4 = tuple() - dealloc_stack %1#0 : $*@local_storage Builtin.Int64 // id: %13 - %5 = return %4 : $() -} - -// CHECK-LABEL: @store_after_store -// CHECK: #0 store -// CHECK-NEXT: [[RET0:%.+]] = alloc_box -// CHECK: #1 store -// CHECK-NEXT: [[RET0:%.+]] = alloc_box -sil @store_after_store : $@convention(thin) (@owned B) -> () { -bb0(%0 : $B): - %1 = alloc_box $B - %2 = store %0 to %1#1 : $*B - %3 = store %0 to %1#1 : $*B - %4 = tuple() - %5 = return %4 : $() -} - -// CHECK-LABEL: @store_after_store_struct -// CHECK: #0 store -// CHECK-NEXT: [[RET0:%.+]] = alloc_stack -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK: #1 store -// CHECK-NEXT: [[RET0:%.+]] = alloc_stack -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -sil @store_after_store_struct : $@convention(thin) () -> () { - %1 = alloc_stack $S1 - %9 = integer_literal $Builtin.Int64, 0 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = struct_element_addr %1#1 : $*S1, #S1.a // user: %12 - store %10 to %11 : $*Int // id: %12 - store %10 to %11 : $*Int - %4 = tuple() - dealloc_stack %1#0 : $*@local_storage S1 // id: %13 - %5 = return %4 : $() -} - -// Make sure all the structs get expanded correctly. -// -// CHECK-LABEL: @many_struct_allocs -// CHECK: #0 store -// CHECK-NEXT: alloc_stack $S2 -// CHECK: #1 store -// CHECK-NEXT: alloc_stack $S3 -// CHECK: #2 store -// CHECK-NEXT: alloc_stack $S4 -sil hidden @many_struct_allocs : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S2 // var a // users: %6, %18 - %1 = alloc_stack $S3 // var b // users: %10, %17 - %2 = alloc_stack $S4 // var c // users: %14, %16 - %3 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %5 - %4 = metatype $@thin S2.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin S2.Type) -> S2 // user: %6 - store %5 to %0#1 : $*S2 // id: %6 - // function_ref struct.S3.init (struct.S3.Type)() -> struct.S3 - %7 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %9 - %8 = metatype $@thin S3.Type // user: %9 - %9 = apply %7(%8) : $@convention(thin) (@thin S3.Type) -> S3 // user: %10 - store %9 to %1#1 : $*S3 // id: %10 - %11 = function_ref @S4_init : $@convention(thin) (@thin S4.Type) -> S4 // user: %13 - %12 = metatype $@thin S4.Type // user: %13 - %13 = apply %11(%12) : $@convention(thin) (@thin S4.Type) -> S4 // user: %14 - store %13 to %2#1 : $*S4 // id: %14 - %15 = tuple () // user: %19 - dealloc_stack %2#0 : $*@local_storage S4 // id: %16 - dealloc_stack %1#0 : $*@local_storage S3 // id: %17 - dealloc_stack %0#0 : $*@local_storage S2 // id: %18 - return %15 : $() // id: %19 -} - -// CHECK-LABEL: self_loop -// CHECK: #0 store -// CHECK-NEXT: alloc_stack $S5 // users: %4, %7 -sil hidden @self_loop : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S5 // var b // users: %4, %7 - %1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> S5 // user: %3 - %2 = metatype $@thin S5.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> S5 // users: %4, %5 - store %3 to %0#1 : $*S5 // id: %4 - release_value %3 : $S5 // id: %5 - %6 = tuple () // user: %8 - dealloc_stack %0#0 : $*@local_storage S5 // id: %7 - return %6 : $() // id: %8 -} diff --git a/test/SILPasses/memlocation_type_only_expansion.sil b/test/SILPasses/memlocation_type_only_expansion.sil deleted file mode 100644 index 44a727b8f06cf..0000000000000 --- a/test/SILPasses/memlocation_type_only_expansion.sil +++ /dev/null @@ -1,361 +0,0 @@ -// RUN: %target-sil-opt %s -memlocation-dump -ml=only-type-expansion | FileCheck %s - -sil_stage canonical - -import Builtin - -struct Int { - var value : Builtin.Int64 -} - -struct Int32{ - var value : Builtin.Int32 -} - -struct Int64 { - var value : Builtin.Int64 -} - -struct Bool { - var value : Builtin.Int1 -} - -struct S1 { - var a: Int - var b: Int - init(a: Int, b: Int) - init() -} - -struct S2 { - var a: Int - var b: S1 - init(a: Int, b: S1) - init() -} - -class C1 { - var a : Int - deinit - init(a: Int) -} - -struct S3 { - var c: C1 - var a: S2 - var b: C1 - init(c: C1, a: S2, b: C1) - init() -} - -struct S4 { - var c: (Int, Int, S1) - init(c: (Int, Int, S1)) - init() -} - -struct S5 { - var c: (Int, Int, S3) - init(c: (Int, Int, S3)) - init() -} - -struct S6 { - var tuple: (Int, Int) -} - -enum Example { - case A(Int64) - case B(Int32) -} - - -sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1 -sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2 -sil @C1_init : $@convention(thin) (@thick C1.Type) -> @owned C1 -sil @S3_init : $@convention(thin) (@thin S3.Type) -> @owned S3 -sil @S4_init : $@convention(thin) (@thin S4.Type) -> @owned S4 -sil @S5_init : $@convention(thin) (@thin S5.Type) -> @owned S5 -sil @S6_init : $@convention(thin) (@thin S6.Type) -> S6 - -// CHECK-LABEL: @test_struct_type_expansion -// CHECK: #0 store -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK: #1 store -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S1 -// CHECK-NEXT: Field Type: var b: S1 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S1 -// CHECK-NEXT: Field Type: var b: S1 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -sil hidden @test_struct_type_expansion : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S1 // var a // users: %5, %12 - %1 = alloc_stack $S2 // var b // users: %9, %11 - %2 = function_ref @S1_init : $@convention(thin) (@thin S1.Type) -> S1 // user: %4 - %3 = metatype $@thin S1.Type // user: %4 - %4 = apply %2(%3) : $@convention(thin) (@thin S1.Type) -> S1 // user: %5 - store %4 to %0#1 : $*S1 // id: %5 - %6 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %8 - %7 = metatype $@thin S2.Type // user: %8 - %8 = apply %6(%7) : $@convention(thin) (@thin S2.Type) -> S2 // user: %9 - store %8 to %1#1 : $*S2 // id: %9 - %10 = tuple () // user: %13 - dealloc_stack %1#0 : $*@local_storage S2 // id: %11 - dealloc_stack %0#0 : $*@local_storage S1 // id: %12 - return %10 : $() // id: %13 -} - -// Make sure we do not expand the reference type. -// -// CHECK-LABEL: test_class_stack_slot -// CHECK: #0 store -// CHECK-NOT: var -// CHECK: #1 store -sil hidden @test_class_stack_slot : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $C1 // var a // users: %4, %7 - %1 = function_ref @C1_init : $@convention(thin) (@thick C1.Type) -> @owned C1 // user: %3 - %2 = metatype $@thick C1.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thick C1.Type) -> @owned C1 // users: %4, %5 - store %3 to %0#1 : $*C1 // id: %4 - store %3 to %0#1 : $*C1 // id: %4 - strong_release %3 : $C1 // id: %5 - %6 = tuple () // user: %8 - dealloc_stack %0#0 : $*@local_storage C1 // id: %7 - return %6 : $() // id: %8 -} - -// CHECK-LABEL: test_struct_and_class_slot -// CHECK: #0 store -// CHECK-NEXT: Address Projection Type: $*C1 -// CHECK-NEXT: Field Type: var b: C1 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S1 -// CHECK-NEXT: Field Type: var b: S1 -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S1 -// CHECK-NEXT: Field Type: var b: S1 -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*C1 -// CHECK-NEXT: Field Type: var c: C1 -sil hidden @test_struct_and_class_slot : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S3 // var a // users: %4, %7 - // function_ref test.S3.init (test.S3.Type)() -> test.S3 - %1 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> @owned S3 // user: %3 - %2 = metatype $@thin S3.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S3.Type) -> @owned S3 // users: %4, %5 - store %3 to %0#1 : $*S3 // id: %4 - release_value %3 : $S3 // id: %5 - %6 = tuple () // user: %8 - dealloc_stack %0#0 : $*@local_storage S3 // id: %7 - return %6 : $() // id: %8 -} - -// Test tuple expansion. -// -// CHECK-LABEL: test_tuple -// CHECK: #0 store -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S1 -// CHECK-NEXT: Index: 2 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S1) -// CHECK-NEXT: Field Type: var c: (Int, Int, S1) -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S1 -// CHECK-NEXT: Index: 2 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S1) -// CHECK-NEXT: Field Type: var c: (Int, Int, S1) -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Index: 1 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S1) -// CHECK-NEXT: Field Type: var c: (Int, Int, S1) -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Index: 0 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S1) -// CHECK-NEXT: Field Type: var c: (Int, Int, S1) -sil hidden @test_tuple : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S4 // var x // users: %4, %7 - // function_ref test.S4.init (test.S4.Type)() -> test.S4 - %1 = function_ref @S4_init : $@convention(thin) (@thin S4.Type) -> @owned S4 // user: %3 - %2 = metatype $@thin S4.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S4.Type) -> @owned S4 // users: %4, %5 - store %3 to %0#1 : $*S4 // id: %4 - release_value %3 : $S4 // id: %5 - %6 = tuple () // user: %8 - dealloc_stack %0#0 : $*@local_storage S4 // id: %7 - return %6 : $() // id: %8 -} - -// CHECK-LABEL: tuple_test_with_reference -// CHECK: #0 store -// CHECK-NEXT: Address Projection Type: $*C1 -// CHECK-NEXT: Field Type: var b: C1 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Index: 2 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) -// CHECK-NEXT: Field Type: var c: (Int, Int, S3) -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var b: Int -// CHECK-NEXT: Address Projection Type: $*S1 -// CHECK-NEXT: Field Type: var b: S1 -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Index: 2 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) -// CHECK-NEXT: Field Type: var c: (Int, Int, S3) -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S1 -// CHECK-NEXT: Field Type: var b: S1 -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Index: 2 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) -// CHECK-NEXT: Field Type: var c: (Int, Int, S3) -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Field Type: var a: Int -// CHECK-NEXT: Address Projection Type: $*S2 -// CHECK-NEXT: Field Type: var a: S2 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Index: 2 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) -// CHECK-NEXT: Field Type: var c: (Int, Int, S3) -// CHECK-NEXT: Address Projection Type: $*C1 -// CHECK-NEXT: Field Type: var c: C1 -// CHECK-NEXT: Address Projection Type: $*S3 -// CHECK-NEXT: Index: 2 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) -// CHECK-NEXT: Field Type: var c: (Int, Int, S3) -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Index: 1 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) -// CHECK-NEXT: Field Type: var c: (Int, Int, S3) -// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -// CHECK-NEXT: Field Type: var value: Int64 -// CHECK-NEXT: Address Projection Type: $*Int -// CHECK-NEXT: Index: 0 -// CHECK-NEXT: Address Projection Type: $*(Int, Int, S3) -// CHECK-NEXT: Field Type: var c: (Int, Int, S3) -sil hidden @tuple_test_with_reference : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S5 // var x // users: %4, %7 - // function_ref test.S5.init (test.S5.Type)() -> test.S5 - %1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> @owned S5 // user: %3 - %2 = metatype $@thin S5.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> @owned S5 // users: %4, %5 - store %3 to %0#1 : $*S5 // id: %4 - release_value %3 : $S5 // id: %5 - %6 = tuple () // user: %8 - dealloc_stack %0#0 : $*@local_storage S5 // id: %7 - return %6 : $() // id: %8 -} - -/// CHECK-LABEL: tuple_inside_struct -/// CHECK: #0 store -/// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -/// CHECK-NEXT: Field Type: var value: Int64 -/// CHECK-NEXT: Address Projection Type: $*Int -/// CHECK-NEXT: Index: 1 -/// CHECK-NEXT: Address Projection Type: $*(Int, Int) -/// CHECK-NEXT: Field Type: var tuple: (Int, Int) -/// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -/// CHECK-NEXT: Field Type: var value: Int64 -/// CHECK-NEXT: Address Projection Type: $*Int -/// CHECK-NEXT: Index: 0 -/// CHECK-NEXT: Address Projection Type: $*(Int, Int) -/// CHECK-NEXT: Field Type: var tuple: (Int, Int) -sil hidden @tuple_inside_struct : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $S6 // var x // users: %4, %7 - %1 = function_ref @S6_init : $@convention(thin) (@thin S6.Type) -> S6 // user: %3 - %2 = metatype $@thin S6.Type // user: %3 - %3 = apply %1(%2) : $@convention(thin) (@thin S6.Type) -> S6 // users: %4, %5 - store %3 to %0#1 : $*S6 // id: %4 - %6 = tuple () // user: %8 - dealloc_stack %0#0 : $*@local_storage S6 // id: %7 - return %6 : $() // id: %8 -} - -/// Given an enum type, we expands it into nothing as its meaningless to call -/// getStoredProperties on enum without specifying the tag. Enum is sort of -/// like union in C, i.e. its memory can be interpreted differently depending -/// on the chosen tag. -/// -/// CHECK-LABEL: enum_test -/// CHECK: #0 store -/// CHECK-NOT: Int64 -/// CHECK-NOT: Int32 -/// CHECK: #1 store -/// CHECK-NEXT: Address Projection Type: $*Builtin.Int64 -/// CHECK-NEXT: Field Type: var value: Int64 -sil hidden @enum_test : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $Example // var example // users: %5, %11 - %1 = alloc_stack $Int // var a // users: %8, %10 - %2 = integer_literal $Builtin.Int64, 10 // user: %3 - %3 = struct $Int64 (%2 : $Builtin.Int64) // user: %4 - %4 = enum $Example, #Example.A!enumelt.1, %3 : $Int64 // user: %5 - store %4 to %0#1 : $*Example // id: %5 - %6 = integer_literal $Builtin.Int64, 10 // user: %7 - %7 = struct $Int (%6 : $Builtin.Int64) // user: %8 - store %7 to %1#1 : $*Int // id: %8 - %9 = tuple () // user: %12 - dealloc_stack %1#0 : $*@local_storage Int // id: %10 - dealloc_stack %0#0 : $*@local_storage Example // id: %11 - return %9 : $() // id: %12 -} diff --git a/test/SILPasses/redundantloadelimination.sil b/test/SILPasses/redundantloadelimination.sil deleted file mode 100644 index 9bfedbcdb14a5..0000000000000 --- a/test/SILPasses/redundantloadelimination.sil +++ /dev/null @@ -1,768 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -module-name Swift -redundant-load-elim -dce | FileCheck %s - -import Builtin - -typealias I32 = Builtin.Int32 - -/////////////////////// -// Type Declarations // -/////////////////////// - -struct Int { - var value : Builtin.Int64 -} - -struct Int32 { - var value : Builtin.Int32 -} - -struct Int64 { - var value : Builtin.Int64 -} - -struct Bool { - var value : Builtin.Int1 -} - -class AX { - final var current: Int32 - init() -} - -struct A { - var i : Builtin.Int32 -} - -struct AA { - var a : A - var i : Builtin.Int32 -} - -class B { - var i : Builtin.Int32 - init() -} - -struct X { - var c : B - init() -} - -struct Agg2 { - var t : (Builtin.Int64, Builtin.Int32) -} - -struct Agg1 { - var a : Agg2 -} - -enum Optional { - case None - case Some(T) -} - -class E : B { } - -struct C { - var i : Builtin.Int16 -} - -struct D { - var p : Builtin.RawPointer -} - -struct Wrapper { - var value : Builtin.Int32 -} - -class AB { - var value: Int - init(value: Int) - deinit -} - -enum XYZ { - case A - case B((Int32, Int32)) - case C(Int32) -} - -struct TwoField { - var a: Int - var b: Int - init(a: Int, b: Int) - init() -} - - -sil @use : $@convention(thin) (Builtin.Int32) -> () -sil @use_64 : $@convention(thin) (Builtin.Int64) -> () -sil @use_2_64 : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () -sil @use_a : $@convention(thin) (A) -> () -sil @use_twofield : $@convention(thin) (TwoField) -> () -sil @escaped_a_ptr : $@convention(thin) (@out A) -> () -sil @escaped_a : $@convention(thin) () -> Builtin.RawPointer -sil @init_twofield : $@convention(thin) (@thin TwoField.Type) -> TwoField - -// Check that we don't crash if the address is an unchecked_addr_cast. -// CHECK-LABEL: sil @test_unchecked_addr_cast -// CHECK-NOT: load -// CHECK: return -sil @test_unchecked_addr_cast : $@convention(thin) (@inout A, A) -> A { -bb0(%0 : $*A, %1 : $A): - %2 = unchecked_addr_cast %0 : $*A to $*A - store %1 to %2 : $*A - %l1 = load %2 : $*A - return %l1 : $A -} - -// Multi-BB version of the previous test. -// CHECK-LABEL: sil @test_forwarding_ignoring_unchecked_addr_cast2 : $@convention(thin) (@inout A, A, A) -> A { -// CHECK: bb1 -// CHECK-NOT: load -// CHECK: cond_br -sil @test_forwarding_ignoring_unchecked_addr_cast2 : $@convention(thin) (@inout A, A, A) -> A { -bb0(%0 : $*A, %1 : $A, %2: $A): - %3 = unchecked_addr_cast %0 : $*A to $*A - store %1 to %3 : $*A - br bb1 - -bb1: - %5 = load %3 : $*A - %6 = load %3 : $*A - store %2 to %3 : $*A - cond_br undef, bb1, bb2 - -bb2: - return %5 : $A -} - -// CHECK-LABEL: sil @test_read_dependence_allows_forwarding_multi_bb_1 : $@convention(thin) (@inout A, A) -> A { -// CHECK: bb0 -// CHECK: store -// CHECK: bb1 -// CHECK: store -// CHECK-NOT: load -// CHECK: cond_br -sil @test_read_dependence_allows_forwarding_multi_bb_1 : $@convention(thin) (@inout A, A) -> A { -bb0(%0 : $*A, %1 : $A): - store %1 to %0 : $*A - %2 = unchecked_addr_cast %0 : $*A to $*A - %3 = unchecked_addr_cast %2 : $*A to $*A - br bb1 - -bb1: - // This means that the first store is not dead. - %4 = load %3 : $*A - // But we still should be able to forward this load. - %5 = load %0 : $*A - // We need to dedup this store to trigger the self loop - // forwarding. Once we do the full optimistic data flow this will no - // longer be needed. - %6 = load %0 : $*A - store %1 to %0 : $*A - cond_br undef, bb1, bb2 - -bb2: - return %5 : $A -} - -// DISABLE this test for now. it seems DCE is not getting rid of the load in bb8 after the RLE happens. -// -// Make sure the switch does not affect the forwarding of the load. -// switch_enum can not have BBArgument, but the %17 = load %2 : $*Int32 is not produced in the -// switch basic block. -// DISABLE_CHECK-LABEL: load_elimination_disregard_switch_enum -// DISABLE_CHECK: bb8 -// DISABLE_CHECK-NOT: load -// DISABLE_CHECK: return -sil @load_elimination_disregard_switch_enum : $@convention(thin) (Int32, Int32, @inout Int32) -> Int32 { -// %0 // user: %4 -// %1 // user: %4 -// %2 // users: %17, %19 -bb0(%0 : $Int32, %1 : $Int32, %2 : $*Int32): - cond_br undef, bb7, bb1 // id: %3 - -bb1: // Preds: bb0 - %4 = tuple (%0 : $Int32, %1 : $Int32) // user: %5 - %5 = enum $XYZ, #XYZ.B!enumelt.1, %4 : $(Int32, Int32) // user: %6 - switch_enum %5 : $XYZ, case #XYZ.A!enumelt: bb2, case #XYZ.B!enumelt.1: bb4, case #XYZ.C!enumelt.1: bb6 // id: %6 - -bb2: // Preds: bb1 - br bb3 // id: %7 - -bb3: // Preds: bb2 - %8 = integer_literal $Builtin.Int32, 0 // user: %9 - %9 = struct $Int32 (%8 : $Builtin.Int32) - br bb5 // id: %10 - -// %11 // user: %12 -bb4(%11 : $(Int32, Int32)): // Preds: bb1 - %12 = tuple_extract %11 : $(Int32, Int32), 0 - br bb5 // id: %13 - -bb5: // Preds: bb4 bb5 bb6 - br bb5 // id: %14 - -bb6(%15 : $Int32): // Preds: bb1 - br bb5 // id: %16 - -bb7: // Preds: bb0 - %17 = load %2 : $*Int32 - br bb8 // id: %18 - -bb8: // Preds: bb3 bb7 - %19 = load %2 : $*Int32 // user: %20 - return %19 : $Int32 // id: %20 -} - - -// The load should be eliminated here. but currently is not ... Look into why -// -// CHECK-LABEL: sil @load_store_forwarding_from_aggregate_to_field -sil @load_store_forwarding_from_aggregate_to_field : $@convention(thin) (Agg1) -> (Builtin.Int32) { -bb0(%0 : $Agg1): - %1 = alloc_stack $Agg1 - store %0 to %1#1 : $*Agg1 - %2 = struct_element_addr %1#1 : $*Agg1, #Agg1.a - %3 = struct_element_addr %2 : $*Agg2, #Agg2.t - %4 = tuple_element_addr %3 : $*(Builtin.Int64, Builtin.Int32), 1 - %5 = load %4 : $*Builtin.Int32 - dealloc_stack %1#0 : $*@local_storage Agg1 - return %5 : $Builtin.Int32 -} - -sil_global @total : $Int32 - -// CHECK-LABEL: sil @store_promotion -// CHECK: store -// CHECK-NEXT: strong_retain -// CHECK-NEXT: strong_retain -// CHECK: return -sil @store_promotion : $@convention(thin) (@owned B) -> () { -bb0(%0 : $B): - %1 = alloc_box $B - %2 = store %0 to %1#1 : $*B - %3 = load %1#1 : $*B - %4 = load %1#1 : $*B - %5 = strong_retain %3 : $B - %6 = strong_retain %4 : $B - %7 = tuple() - %8 = return %7 : $() -} - -// CHECK-LABEL: sil @eliminate_duplicate_loads_over_noread_builtins -// CHECK: bb0 -// CHECK-NEXT: [[LOAD_RESULT:%[0-9]+]] = load -// CHECK-NEXT: integer_literal -// CHECK-NEXT: builtin "sadd_with_overflow_Int64"([[LOAD_RESULT]] : ${{.*}}, [[LOAD_RESULT]] -// CHECK-NEXT: [[APPLY_RESULT:%[0-9]+]] = tuple_extract -// CHECK-NEXT: builtin "sadd_with_overflow_Int64"([[LOAD_RESULT]] : ${{.*}}, [[APPLY_RESULT]] -// CHECK-NEXT: tuple_extract -// CHECK-NEXT: return -sil @eliminate_duplicate_loads_over_noread_builtins : $@convention(thin) (@inout Builtin.Int64) -> (Builtin.Int64) { -bb0(%0 : $*Builtin.Int64): - %1 = load %0 : $*Builtin.Int64 - %3 = integer_literal $Builtin.Int1, 0 - %4 = builtin "sadd_with_overflow_Int64"(%1 : $Builtin.Int64, %1 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) - %5 = load %0 : $*Builtin.Int64 - %6 = tuple_extract %4 : $(Builtin.Int64, Builtin.Int1), 0 - %7 = builtin "sadd_with_overflow_Int64"(%5 : $Builtin.Int64, %6 : $Builtin.Int64, %3 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) - %8 = tuple_extract %7 : $(Builtin.Int64, Builtin.Int1), 0 - return %8 : $Builtin.Int64 -} - -// CHECK-LABEL: sil @load_store_forwarding_over_noread_builtins -// CHECK: bb0 -// CHECK-NEXT: load -// CHECK-NEXT: integer_literal -// CHECK-NEXT: builtin -// CHECK-NEXT: tuple_extract -// CHECK-NEXT: store -// CHECK-NEXT: builtin -// CHECK-NEXT: tuple_extract -// CHECK-NEXT: builtin -// CHECK-NEXT: tuple_extract -// CHECK-NEXT: return -sil @load_store_forwarding_over_noread_builtins : $@convention(thin) (@inout Builtin.Int64, @inout Builtin.Int64) -> (Builtin.Int64) { -bb0(%0 : $*Builtin.Int64, %1 : $*Builtin.Int64): - %2 = load %0 : $*Builtin.Int64 - %4 = integer_literal $Builtin.Int1, 0 - %5 = builtin "sadd_with_overflow_Int64"(%2 : $Builtin.Int64, %2 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) - %6 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 0 - store %6 to %1 : $*Builtin.Int64 - %8 = builtin "smul_with_overflow_Int64"(%2 : $Builtin.Int64, %2 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) - %9 = tuple_extract %8 : $(Builtin.Int64, Builtin.Int1), 0 - %10 = load %1 : $*Builtin.Int64 - %11 = builtin "sadd_with_overflow_Int64"(%10 : $Builtin.Int64, %9 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) - %12 = tuple_extract %11 : $(Builtin.Int64, Builtin.Int1), 0 - return %12 : $Builtin.Int64 -} - -// CHECK-LABEL: sil @load_store_forwarding_over_dealloc_stack -// CHECK: bb0 -// CHECK-NEXT: alloc_stack $Builtin.Int64 -// CHECK-NEXT: alloc_stack $Builtin.Int64 -// CHECK-NEXT: store -// CHECK-NEXT: alloc_stack $Builtin.Int64 -// CHECK-NEXT: load -// CHECK: dealloc_stack -// CHECK-NOT: load -// CHECK: return -sil @load_store_forwarding_over_dealloc_stack : $@convention(thin) (Builtin.Int64) -> (Builtin.Int64) { -bb0(%0 : $Builtin.Int64): - %1 = alloc_stack $Builtin.Int64 - %2 = alloc_stack $Builtin.Int64 - store %0 to %1#1 : $*Builtin.Int64 - %3 = alloc_stack $Builtin.Int64 - %5 = load %2#1 : $*Builtin.Int64 - %22 = function_ref @use_64 : $@convention(thin) (Builtin.Int64) -> () - %23 = apply %22(%5) : $@convention(thin) (Builtin.Int64) -> () - dealloc_stack %3#0 : $*@local_storage Builtin.Int64 - %4 = load %1#1 : $*Builtin.Int64 - store %0 to %1#1 : $*Builtin.Int64 - %6 = load %2#1 : $*Builtin.Int64 - %222 = function_ref @use_2_64 : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () - %232 = apply %222(%4, %6) : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> () - dealloc_stack %2#0 : $*@local_storage Builtin.Int64 - dealloc_stack %1#0 : $*@local_storage Builtin.Int64 - return %4 : $Builtin.Int64 -} - -// CHECK-LABEL: sil @load_dedup_forwarding_from_aggregate_to_field -// CHECK: bb0([[INPUT_PTR:%[0-9]+]] -// CHECK-NEXT: load [[INPUT_PTR]] -// CHECK-NEXT: struct_extract -// CHECK-NEXT: struct_extract -// CHECK-NEXT: tuple_extract -// CHECK-NEXT: return -sil @load_dedup_forwarding_from_aggregate_to_field : $@convention(thin) (@inout Agg1) -> (Builtin.Int32) { -bb0(%0 : $*Agg1): - %1 = load %0 : $*Agg1 - %2 = struct_element_addr %0 : $*Agg1, #Agg1.a - %3 = struct_element_addr %2 : $*Agg2, #Agg2.t - %4 = tuple_element_addr %3 : $*(Builtin.Int64, Builtin.Int32), 1 - %5 = load %4 : $*Builtin.Int32 - return %5 : $Builtin.Int32 -} - -// CHECK-LABEL: promote_partial_load -// CHECK: alloc_stack -// CHECK-NOT: load -// CHECK: [[RESULT:%[0-9]+]] = struct_extract -// CHECK: return [[RESULT]] -sil @promote_partial_load : $@convention(thin) (Builtin.Int32) -> Builtin.Int32 { -bb0(%0 : $Builtin.Int32): - %1 = alloc_stack $Wrapper - %2 = struct $Wrapper (%0 : $Builtin.Int32) - store %2 to %1#1 : $*Wrapper - %3 = struct_element_addr %1#1 : $*Wrapper, #Wrapper.value - %4 = load %3 : $*Builtin.Int32 - dealloc_stack %1#0 : $*@local_storage Wrapper - return %4 : $Builtin.Int32 -} - -// TODO: HANDLE THIS, THIS IS SAME VALUE STORES. -// -// CHECK-LABEL: sil @store_loaded_value -sil @store_loaded_value : $@convention(thin) (@inout Agg2, @inout Agg1) -> () { -bb0(%0 : $*Agg2, %1 : $*Agg1): - %2 = load %1 : $*Agg1 - %3 = load %0 : $*Agg2 - %4 = store %2 to %1 : $*Agg1 - %5 = store %3 to %0 : $*Agg2 - %6 = tuple() - %7 = return %6 : $() -} - -// *NOTE* This does not handle raw pointer since raw pointer is only layout compatible with heap references. -// CHECK-LABEL: sil @store_to_load_forward_unchecked_addr_cast_struct : $@convention(thin) (Optional) -> () { -// CHECK: bb0([[INPUT:%[0-9]+]] -// CHECK-NOT: load -// CHECK: return -sil @store_to_load_forward_unchecked_addr_cast_struct : $@convention(thin) (Optional) -> () { -bb0(%0 : $Optional): - %1 = alloc_stack $Optional - store %0 to %1#1 : $*Optional - %2 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.Int32 - %3 = load %2 : $*Builtin.Int32 - %4 = unchecked_addr_cast %1#1 : $*Optional to $*A - %5 = load %4 : $*A - %6 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.RawPointer - %7 = load %6 : $*Builtin.RawPointer - %8 = unchecked_addr_cast %1#1 : $*Optional to $*Builtin.NativeObject - %9 = load %8 : $*Builtin.NativeObject - %10 = unchecked_addr_cast %1#1 : $*Optional to $*Optional - %11 = load %10 : $*Optional - %12 = unchecked_addr_cast %1#1 : $*Optional to $*Optional - %13 = load %12 : $*Optional - %14 = unchecked_addr_cast %1#1 : $*Optional to $*Optional - %15 = load %14 : $*Optional - dealloc_stack %1#0 : $*@local_storage Optional - %9999 = tuple() - return %9999 : $() -} - -// Check load forwarding across strong_release in case the stored memory does -// not escape. -// CHECK-LABEL: sil @test_store_forwarding_strong_release -// CHECK: strong_release -// CHECK-NOT: [[BOX0:%.*]] = load -// CHECK: apply -sil @test_store_forwarding_strong_release : $@convention(thin) (B, X) -> () { -bb0(%0 : $B, %1 : $X): - %2 = alloc_stack $A // users: %3, %13 - %3 = struct_element_addr %2#1 : $*A, #A.i // users: %5, %10 - %4 = integer_literal $Builtin.Int32, 32 // user: %5 - store %4 to %3 : $*Builtin.Int32 // id: %5 - %6 = ref_to_unowned %0 : $B to $@sil_unowned B // user: %7 - unowned_release %6 : $@sil_unowned B // id: %7 - strong_release %0 : $B // id: %8 - release_value %1 : $X // id: %9 - %10 = load %3 : $*Builtin.Int32 // user: %12 - // function_ref use - %11 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %12 - %12 = apply %11(%10) : $@convention(thin) (Builtin.Int32) -> () - dealloc_stack %2#0 : $*@local_storage A // id: %13 - %14 = tuple () // user: %15 - return %14 : $() -} - -// Check load forwarding across strong_release in case the loaded memory does -// not escape. -// CHECK-LABEL: sil @test_load_forwarding_strong_release -// CHECK: strong_release -// CHECK-NOT: [[BOX0:%.*]] = load -// CHECK: apply -sil @test_load_forwarding_strong_release : $@convention(thin) (B, X) -> () { -bb0(%0 : $B, %1 : $X): - %2 = alloc_stack $A // users: %3, %12 - %3 = struct_element_addr %2#1 : $*A, #A.i // users: %4, %9 - %4 = load %3 : $*Builtin.Int32 - %5 = ref_to_unowned %0 : $B to $@sil_unowned B // user: %6 - unowned_release %5 : $@sil_unowned B // id: %6 - strong_release %0 : $B // id: %7 - release_value %1 : $X // id: %8 - %9 = load %3 : $*Builtin.Int32 // user: %11 - // function_ref use - %10 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %11 - %11 = apply %10(%9) : $@convention(thin) (Builtin.Int32) -> () - dealloc_stack %2#0 : $*@local_storage A // id: %12 - %13 = tuple () // user: %14 - return %13 : $() // id: %14 -} - -// Make sure we RLE the second load. -// -// CHECK-LABEL: test_simple_rle_in_class -// CHECK: load -// CHECK-NOT: load -// CHECK: cond_fail -sil hidden @test_simple_rle_in_class : $@convention(thin) (@owned AB) -> Int { -bb0(%0 : $AB): - %2 = ref_element_addr %0 : $AB, #AB.value // user: %3 - %3 = load %2 : $*Int // user: %6 - %4 = ref_element_addr %0 : $AB, #AB.value // user: %5 - %5 = load %4 : $*Int // user: %7 - %6 = struct_extract %3 : $Int, #Int.value // user: %9 - %7 = struct_extract %5 : $Int, #Int.value // user: %9 - %8 = integer_literal $Builtin.Int1, -1 // user: %9 - %9 = builtin "sadd_with_overflow_Int64"(%6 : $Builtin.Int64, %7 : $Builtin.Int64, %8 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) // users: %10, %11 - %10 = tuple_extract %9 : $(Builtin.Int64, Builtin.Int1), 0 // user: %13 - %11 = tuple_extract %9 : $(Builtin.Int64, Builtin.Int1), 1 // user: %12 - cond_fail %11 : $Builtin.Int1 // id: %12 - %13 = struct $Int (%10 : $Builtin.Int64) // user: %15 - strong_release %0 : $AB // id: %14 - return %13 : $Int // id: %15 -} - -// Make sure we RLE the load in BB2. -// -// CHECK-LABEL: test_silargument_rle -// CHECK: bb2 -// CHECK-NOT: load -// CHECK: cond_br -sil @test_silargument_rle : $@convention(thin) () -> () { -bb0: - %0 = global_addr @total : $*Int32 - %1 = integer_literal $Builtin.Int32, 0 - %2 = struct $Int32 (%1 : $Builtin.Int32) - store %2 to %0 : $*Int32 - %6 = alloc_ref $AX - %8 = ref_element_addr %6 : $AX, #AX.current - store %2 to %8 : $*Int32 - // %10 = load %8 : $*Int32 - cond_br undef, bb3, bb2 - -bb2: - %24 = integer_literal $Builtin.Int1, -1 - %31 = struct_element_addr %0 : $*Int32, #Int32.value - %32 = load %31 : $*Builtin.Int32 - %33 = builtin "sadd_with_overflow_Int32"(%32 : $Builtin.Int32, %1 : $Builtin.Int32, %24 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) - %34 = tuple_extract %33 : $(Builtin.Int32, Builtin.Int1), 0 - %37 = struct $Int32 (%34 : $Builtin.Int32) - store %37 to %0 : $*Int32 - cond_br undef, bb3, bb2 - -bb3: - strong_release %6 : $AX - %44 = tuple () - return %44 : $() -} - -// CHECK-LABEL: sil @load_to_load_forwarding_diamonds : $@convention(thin) (@inout Builtin.Int32) -> Builtin.Int32 { -// CHECK: load -// CHECK-NOT: load -// CHECK: return -sil @load_to_load_forwarding_diamonds : $@convention(thin) (@inout Builtin.Int32) -> Builtin.Int32 { -bb0(%0 : $*Builtin.Int32): - %1 = load %0 : $*Builtin.Int32 - // Simple diamond. - cond_br undef, bb1, bb2 - -bb1: - br bb3 - -bb2: - br bb3 - -bb3: - // Triangle - cond_br undef, bb4, bb5 - -bb4: - br bb5 - -bb5: - %2 = load %0 : $*Builtin.Int32 - return %2 : $Builtin.Int32 -} - - -// CHECK-LABEL: sil @load_to_load_conflicting_branches_diamond : $@convention(thin) (@inout Builtin.Int32) -> () { -// CHECK: bb0( -// CHECK: load -// CHECK: bb1: -// CHECK-NOT: load -// CHECK: store -// CHECK-NOT: load -// CHECK: bb2: -// CHECK: bb3: -// CHECK: load -sil @load_to_load_conflicting_branches_diamond : $@convention(thin) (@inout Builtin.Int32) -> () { -// %0 // users: %1, %4, %9, %11, %16, %21 -bb0(%0 : $*Builtin.Int32): - %1 = load %0 : $*Builtin.Int32 // user: %2 - %2 = builtin "trunc_Int32_Int1"(%1 : $Builtin.Int32) : $Builtin.Int1 - cond_br undef, bb1, bb2 // id: %3 - -bb1: // Preds: bb0 - %4 = load %0 : $*Builtin.Int32 // users: %6, %8, %10 - // function_ref use - %5 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %6 - %6 = apply %5(%4) : $@convention(thin) (Builtin.Int32) -> () - %7 = integer_literal $Builtin.Int32, 2 // user: %9 - %8 = builtin "trunc_Int32_Int1"(%4 : $Builtin.Int32) : $Builtin.Int1 - store %7 to %0 : $*Builtin.Int32 // id: %9 - %10 = builtin "trunc_Int32_Int1"(%4 : $Builtin.Int32) : $Builtin.Int1 - %11 = load %0 : $*Builtin.Int32 // users: %13, %14 - // function_ref use - %12 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %13 - %13 = apply %12(%11) : $@convention(thin) (Builtin.Int32) -> () - %14 = builtin "trunc_Int32_Int1"(%11 : $Builtin.Int32) : $Builtin.Int1 - br bb3 // id: %15 - -bb2: // Preds: bb0 - %16 = load %0 : $*Builtin.Int32 // users: %18, %19 - // function_ref use - %17 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %18 - %18 = apply %17(%16) : $@convention(thin) (Builtin.Int32) -> () - %19 = builtin "trunc_Int32_Int1"(%16 : $Builtin.Int32) : $Builtin.Int1 - br bb3 // id: %20 - -bb3: // Preds: bb1 bb2 - %21 = load %0 : $*Builtin.Int32 // user: %23 - // function_ref use - %22 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %23 = apply %22(%21) : $@convention(thin) (Builtin.Int32) -> () - %24 = tuple () // user: %25 - return %24 : $() // id: %25 -} - -// CHECK-LABEL: load_to_load_irreducible_loop -// CHECK: bb0 -// CHECK: load -// CHECK: bb1 -// CHECK-NOT: load -// CHECK: store -// CHECK: bb2 -// CHECK-NOT: load -// CHECK: bb3 -// CHECK-NOT: load -// CHECK: return -sil @load_to_load_irreducible_loop : $@convention(thin) () -> () { -bb0: - %0 = alloc_stack $Int32 - %99 = struct_element_addr %0#1 : $*Int32, #Int32.value - %1 = load %99 : $*Builtin.Int32 - builtin "trunc_Int32_Int1"(%1 : $Builtin.Int32) : $Builtin.Int1 - cond_br undef, bb1, bb2 - -bb1: - %3 = load %99 : $*Builtin.Int32 - %4 = integer_literal $Builtin.Int32, 2 - %22 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %23 = apply %22(%3) : $@convention(thin) (Builtin.Int32) -> () - store %4 to %99 : $*Builtin.Int32 - builtin "trunc_Int32_Int1"(%3 : $Builtin.Int32) : $Builtin.Int1 - %5 = load %99 : $*Builtin.Int32 - %24 = apply %22(%5) : $@convention(thin) (Builtin.Int32) -> () - builtin "trunc_Int32_Int1"(%5 : $Builtin.Int32) : $Builtin.Int1 - cond_br undef, bb2, bb3 - -bb2: - %6 = load %99 : $*Builtin.Int32 - %25 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %26 = apply %25(%6) : $@convention(thin) (Builtin.Int32) -> () - builtin "trunc_Int32_Int1"(%6 : $Builtin.Int32) : $Builtin.Int1 - cond_br undef, bb1, bb3 - -bb3: - %7 = load %99 : $*Builtin.Int32 - %125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %126 = apply %125(%7) : $@convention(thin) (Builtin.Int32) -> () - builtin "trunc_Int32_Int1"(%7 : $Builtin.Int32) : $Builtin.Int1 - dealloc_stack %0#0 : $*@local_storage Int32 - %9999 = tuple() - return %9999 : $() -} - -// Forward store %1 and store %2 such that load %3 becomes an identity trivial cast. -// Both loads from %0 will be eliminated. -// CHECK-LABEL: sil @test_read_dependence_allows_forwarding_multi_bb_2 : $@convention(thin) (@inout A, A, A) -> A { -// CHECK: bb1 -// CHECK: load -// CHECK-NOT: load -// CHECK: bb2 -sil @test_read_dependence_allows_forwarding_multi_bb_2 : $@convention(thin) (@inout A, A, A) -> A { -bb0(%0 : $*A, %1 : $A, %2 : $A): - store %1 to %0 : $*A - %3 = unchecked_addr_cast %0 : $*A to $*A - %4 = unchecked_addr_cast %3 : $*A to $*A - br bb1 - -bb1: - // This means that the first store is not dead. - %6 = load %3 : $*A - %7 = load %0 : $*A - %8 = load %0 : $*A - %22 = function_ref @use_a : $@convention(thin) (A) -> () - %123 = apply %22(%6) : $@convention(thin) (A) -> () - %223 = apply %22(%7) : $@convention(thin) (A) -> () - %323 = apply %22(%8) : $@convention(thin) (A) -> () - store %2 to %0 : $*A - cond_br undef, bb1, bb2 - -bb2: - return %7 : $A -} - -// CHECK-LABEL: sil @load_to_load_loop -sil @load_to_load_loop : $@convention(thin) () -> () { -bb0: - %101 = alloc_stack $Int32 - %102 = alloc_stack $Int32 - %0 = struct_element_addr %101#1 : $*Int32, #Int32.value - %1 = struct_element_addr %102#1 : $*Int32, #Int32.value - %2 = load %0 : $*Builtin.Int32 - %99 = load %1 : $*Builtin.Int32 - %125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %126 = apply %125(%2) : $@convention(thin) (Builtin.Int32) -> () - %127 = apply %125(%99) : $@convention(thin) (Builtin.Int32) -> () - br bb1 - -bb1: - %4 = load %0 : $*Builtin.Int32 - %5 = integer_literal $Builtin.Int32, 2 - %1125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %1126 = apply %1125(%4) : $@convention(thin) (Builtin.Int32) -> () - store %5 to %0 : $*Builtin.Int32 - builtin "trunc_Int32_Int1"(%4 : $Builtin.Int32) : $Builtin.Int1 - %6 = load %0 : $*Builtin.Int32 - %11125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %11126 = apply %11125(%6) : $@convention(thin) (Builtin.Int32) -> () - cond_br undef, bb1, bb2 - -bb2: - %7 = load %0 : $*Builtin.Int32 - %111125 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %111126 = apply %111125(%7) : $@convention(thin) (Builtin.Int32) -> () - dealloc_stack %102#0 : $*@local_storage Int32 - dealloc_stack %101#0 : $*@local_storage Int32 - %9999 = tuple() - return %9999 : $() -} - -// CHECK-LABEL: store_and_load_to_load_branches_diamond -// CHECK: bb3 -// CHECK-NOT: load -// CHECK: return -sil @store_and_load_to_load_branches_diamond : $@convention(thin) (@inout Builtin.Int32) -> () { -// %0 // users: %1, %4, %9, %11, %16, %21 -bb0(%0 : $*Builtin.Int32): - cond_br undef, bb1, bb2 // id: %3 - -bb1: // Preds: bb0 - %1 = load %0 : $*Builtin.Int32 // user: %2 - br bb3 // id: %15 - -bb2: // Preds: bb0 - %5 = integer_literal $Builtin.Int32, 2 - store %5 to %0 : $*Builtin.Int32 - br bb3 // id: %20 - -bb3: // Preds: bb1 bb2 - %21 = load %0 : $*Builtin.Int32 // user: %23 - // function_ref use - %22 = function_ref @use : $@convention(thin) (Builtin.Int32) -> () // user: %23 - %23 = apply %22(%21) : $@convention(thin) (Builtin.Int32) -> () - %24 = tuple () // user: %25 - return %24 : $() // id: %25 -} - -// CHECK-LABEL: agg_and_field_store_branches_diamond -// CHECK: bb3 -// CHECK-NOT: load -// CHECK: return -sil hidden @agg_and_field_store_branches_diamond : $@convention(thin) (Bool) -> () { -bb0(%0 : $Bool): - %1 = alloc_stack $TwoField // var x // users: %6, %11, %16, %21, %24 - %7 = struct_extract %0 : $Bool, #Bool.value // user: %8 - cond_br %7, bb1, bb2 // id: %8 - -bb1: // Preds: bb0 - %9 = integer_literal $Builtin.Int64, 10 // user: %10 - %10 = struct $Int (%9 : $Builtin.Int64) // user: %12 - %11 = struct_element_addr %1#1 : $*TwoField, #TwoField.a // user: %12 - store %10 to %11 : $*Int // id: %12 - %14 = integer_literal $Builtin.Int64, 20 // user: %15 - %15 = struct $Int (%14 : $Builtin.Int64) // user: %17 - %16 = struct_element_addr %1#1 : $*TwoField, #TwoField.b // user: %17 - store %15 to %16 : $*Int // id: %17 - br bb3 // id: %13 - -bb2: // Preds: bb0 - %3 = function_ref @init_twofield : $@convention(thin) (@thin TwoField.Type) -> TwoField // user: %5 - %4 = metatype $@thin TwoField.Type // user: %5 - %5 = apply %3(%4) : $@convention(thin) (@thin TwoField.Type) -> TwoField // user: %6 - store %5 to %1#1 : $*TwoField // id: %6 - br bb3 // id: %18 - -bb3: // Preds: bb1 bb2 - %99 = load %1#1 : $*TwoField // id: %6 - %991 = function_ref @use_twofield : $@convention(thin) (TwoField) -> () // user: %5 - %55 = apply %991(%99) : $@convention(thin) (TwoField) -> () // user: %6 - %23 = tuple () // user: %25 - dealloc_stack %1#0 : $*@local_storage TwoField // id: %24 - return %23 : $() // id: %25 -} diff --git a/test/SILPasses/sil_combine_enum_addr.sil b/test/SILPasses/sil_combine_enum_addr.sil deleted file mode 100644 index 79e97f22ecbf3..0000000000000 --- a/test/SILPasses/sil_combine_enum_addr.sil +++ /dev/null @@ -1,252 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -simplify-cfg | FileCheck %s - -sil_stage canonical - -import Builtin -import Swift - -// CHECK-LABEL: sil @convert_inject_enum_addr_select_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () -// CHECK: unconditional_checked_cast_addr -// CHECK: inject_enum_addr -// CHECK-NOT: select_enum_addr -// CHECK-NOT: bb1 -// CHECK: unchecked_take_enum_data_addr -// CHECK: return -sil @convert_inject_enum_addr_select_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () { -bb0(%0 : $*Int, %1 : $*_Stdout): - %2 = alloc_stack $CustomStringConvertible - %3 = alloc_stack $Optional - %4 = init_enum_data_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - %5 = alloc_stack $Int - %6 = load %0 : $*Int - store %6 to %5#1 : $*Int - unconditional_checked_cast_addr take_always Int in %5#1 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible - inject_enum_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - dealloc_stack %5#0 : $*@local_storage Int - %11 = integer_literal $Builtin.Int1, -1 - %12 = integer_literal $Builtin.Int1, 0 - %13 = select_enum_addr %3#1 : $*Optional, case #Optional.Some!enumelt.1: %11, case #Optional.None!enumelt: %12 : $Builtin.Int1 - cond_br %13, bb2, bb1 - -bb1: - %15 = tuple () - dealloc_stack %3#0 : $*@local_storage Optional - dealloc_stack %2#0 : $*@local_storage CustomStringConvertible - return %15 : $() - -bb2: - %19 = unchecked_take_enum_data_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - copy_addr [take] %19 to [initialization] %2#1 : $*CustomStringConvertible - br bb1 -} - - -// CHECK-LABEL: sil @convert_inject_enum_addr_switch_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () -// CHECK: unconditional_checked_cast_addr -// CHECK: inject_enum_addr -// CHECK-NOT: switch_enum_addr -// CHECK-NOT: bb1 -// CHECK: unchecked_take_enum_data_addr -// CHECK: return -sil @convert_inject_enum_addr_switch_enum_addr_into_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () { -bb0(%0 : $*Int, %1 : $*_Stdout): - %2 = alloc_stack $CustomStringConvertible - %3 = alloc_stack $Optional - %4 = init_enum_data_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - %5 = alloc_stack $Int - %6 = load %0 : $*Int - store %6 to %5#1 : $*Int - unconditional_checked_cast_addr take_always Int in %5#1 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible - inject_enum_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - dealloc_stack %5#0 : $*@local_storage Int - %13 = switch_enum_addr %3#1 : $*Optional, case #Optional.Some!enumelt.1: bb3, case #Optional.None!enumelt: bb2 - -bb1: - %15 = tuple () - dealloc_stack %3#0 : $*@local_storage Optional - dealloc_stack %2#0 : $*@local_storage CustomStringConvertible - return %15 : $() - -bb2: - br bb1 - -bb3: - %19 = unchecked_take_enum_data_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - copy_addr [take] %19 to [initialization] %2#1 : $*CustomStringConvertible - br bb1 -} - - -// Check that a checked_cast_addr_br converting a known type into a protocol type -// is performed at the compile-time if protocol conformances are statically known. -// -// CHECK-LABEL: sil @convert_checked_cast_addr_br_into_unconditional_checked_cast_addr_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () -// CHECK: store -// CHECK-NOT: checked_cast_addr_br -// CHECK-NOT: bb1 -// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.Some!enumelt.1 -// CHECK: dealloc_stack -// CHECK: return -sil @convert_checked_cast_addr_br_into_unconditional_checked_cast_addr_cond_br : $@convention(thin) (@in Int, @inout _Stdout) -> () { -bb0(%0 : $*Int, %1 : $*_Stdout): - %2 = alloc_stack $CustomStringConvertible - %3 = alloc_stack $Optional - %4 = init_enum_data_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - %5 = alloc_stack $Int - %6 = load %0 : $*Int - store %6 to %5#1 : $*Int - checked_cast_addr_br take_always Int in %5#1 : $*Int to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22 - -bb1: - inject_enum_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - br bb2 - -bb2: - dealloc_stack %5#0 : $*@local_storage Int - dealloc_stack %3#0 : $*@local_storage Optional - %12 = integer_literal $Builtin.Int1, -1 - %13 = integer_literal $Builtin.Int1, 0 - %26 = tuple () - dealloc_stack %2#0 : $*@local_storage CustomStringConvertible - return %26 : $() - -bb22: - inject_enum_addr %3#1 : $*Optional, #Optional.None!enumelt - br bb2 -} - - -class A { - -} - -private final class B { -} - -public class C { -} - -// D cannot be extended elsewhere, but C can! -private class D : C { -} - -// Check that a checked_cast_addr_br converting a known type into a protocol type -// is performed at the compile-time if protocol conformances are statically known. -// In a negative case, take care that check for internal types are not folded (unless -// a whole module optimization is used), because an extension implementing a conformance -// could be defined elsewhere. -// -// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_internal_type : $@convention(thin) (@in A, @inout _Stdout) -> () -// CHECK: checked_cast_addr_br -// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.Some!enumelt.1 -// CHECK: dealloc_stack -// CHECK: return -// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.None!enumelt -// CHECK: } -sil @convert_checked_cast_addr_br_with_internal_type : $@convention(thin) (@in A, @inout _Stdout) -> () { -bb0(%0 : $*A, %1 : $*_Stdout): - %2 = alloc_stack $CustomStringConvertible - %3 = alloc_stack $Optional - %4 = init_enum_data_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - %5 = alloc_stack $A - %6 = load %0 : $*A - store %6 to %5#1 : $*A - checked_cast_addr_br take_always A in %5#1 : $*A to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22 - -bb1: - inject_enum_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - br bb2 - -bb2: - dealloc_stack %5#0 : $*@local_storage A - dealloc_stack %3#0 : $*@local_storage Optional - %12 = integer_literal $Builtin.Int1, -1 - %13 = integer_literal $Builtin.Int1, 0 - %26 = tuple () - dealloc_stack %2#0 : $*@local_storage CustomStringConvertible - return %26 : $() - -bb22: - inject_enum_addr %3#1 : $*Optional, #Optional.None!enumelt - br bb2 -} - -// Check that a checked_cast_addr_br converting a known type into a protocol type -// is performed at the compile-time if protocol conformances are statically known. -// In a negative case, if the source type is private, it is safe to fold the check, -// because a conformance for this type cannot be defined elsewhere. -// -// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_private_type : $@convention(thin) (@in B, @inout _Stdout) -> () -// CHECK: store -// CHECK-NOT: checked_cast_addr_br -// CHECK-NOT: bb1 -// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.None!enumelt -// CHECK: dealloc_stack -// CHECK: return -sil @convert_checked_cast_addr_br_with_private_type : $@convention(thin) (@in B, @inout _Stdout) -> () { -bb0(%0 : $*B, %1 : $*_Stdout): - %2 = alloc_stack $CustomStringConvertible - %3 = alloc_stack $Optional - %4 = init_enum_data_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - %5 = alloc_stack $B - %6 = load %0 : $*B - store %6 to %5#1 : $*B - checked_cast_addr_br take_always B in %5#1 : $*B to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22 - -bb1: - inject_enum_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - br bb2 - -bb2: - dealloc_stack %5#0 : $*@local_storage B - dealloc_stack %3#0 : $*@local_storage Optional - %12 = integer_literal $Builtin.Int1, -1 - %13 = integer_literal $Builtin.Int1, 0 - %26 = tuple () - dealloc_stack %2#0 : $*@local_storage CustomStringConvertible - return %26 : $() - -bb22: - inject_enum_addr %3#1 : $*Optional, #Optional.None!enumelt - br bb2 -} - -// Check that a checked_cast_addr_br converting a known type into a protocol type -// is performed at the compile-time if protocol conformances are statically known. -// In a negative case, take care that cast for private types are not folded if one -// of its superclasses could have a conformance extension defined elsewere. -// -// CHECK-LABEL: sil @convert_checked_cast_addr_br_with_non_private_superclass : $@convention(thin) (@in D, @inout _Stdout) -> () -// CHECK: checked_cast_addr_br -// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.Some!enumelt.1 -// CHECK: dealloc_stack -// CHECK: return -// CHECK: inject_enum_addr %{{.*}} : $*Optional, #Optional.None!enumelt -// CHECK: } -sil @convert_checked_cast_addr_br_with_non_private_superclass : $@convention(thin) (@in D, @inout _Stdout) -> () { -bb0(%0 : $*D, %1 : $*_Stdout): - %2 = alloc_stack $CustomStringConvertible - %3 = alloc_stack $Optional - %4 = init_enum_data_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - %5 = alloc_stack $D - %6 = load %0 : $*D - store %6 to %5#1 : $*D - checked_cast_addr_br take_always D in %5#1 : $*D to CustomStringConvertible in %4 : $*CustomStringConvertible, bb1, bb22 - -bb1: - inject_enum_addr %3#1 : $*Optional, #Optional.Some!enumelt.1 - br bb2 - -bb2: - dealloc_stack %5#0 : $*@local_storage D - dealloc_stack %3#0 : $*@local_storage Optional - %12 = integer_literal $Builtin.Int1, -1 - %13 = integer_literal $Builtin.Int1, 0 - %26 = tuple () - dealloc_stack %2#0 : $*@local_storage CustomStringConvertible - return %26 : $() - -bb22: - inject_enum_addr %3#1 : $*Optional, #Optional.None!enumelt - br bb2 -} diff --git a/test/SILPasses/simp_enum.sil b/test/SILPasses/simp_enum.sil deleted file mode 100644 index 297bab80d4b44..0000000000000 --- a/test/SILPasses/simp_enum.sil +++ /dev/null @@ -1,53 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine | FileCheck %s - -sil_stage canonical - -import Builtin -import Swift - -enum SimpleEnum { - case Empty - case HasInt(Int) - case HasInt2(Int) -} - -//CHECK: _TF4main12test_union_1FT1EOS_10SimpleEnum_S0_ -//CHECK: switch_enum -//CHECK: bb2 -//CHECK: enum $SimpleEnum, #SimpleEnum.HasInt2!enumelt.1, %{{[0-9]+}} : $Int -//CHECK: bb3 -//CHECK: enum $SimpleEnum, #SimpleEnum.HasInt!enumelt.1, %{{[0-9]+}} : $Int -//CHECK: bb4 -//CHECK: return - -// main.test_union_1 (E : main.SimpleEnum) -> main.SimpleEnum -sil @_TF4main12test_union_1FT1EOS_10SimpleEnum_S0_ : $@convention(thin) (SimpleEnum) -> SimpleEnum { -bb0(%0 : $SimpleEnum): - %1 = alloc_stack $SimpleEnum // var E // users: %16, %2 - store %0 to %1#1 : $*SimpleEnum // id: %2 - %3 = tuple () - switch_enum %0 : $SimpleEnum, case #SimpleEnum.Empty!enumelt: bb1, case #SimpleEnum.HasInt!enumelt.1: bb3, case #SimpleEnum.HasInt2!enumelt.1:bb4 // id: %4 - -bb1: // Preds: bb0 - %6 = enum $SimpleEnum, #SimpleEnum.Empty!enumelt // user: %7 - br bb5(%6 : $SimpleEnum) // id: %7 - -bb3(%8 : $Int): // Preds: bb0 - %9 = alloc_stack $Int // var N // users: %13, %10 - store %8 to %9#1 : $*Int // id: %10 - %12 = enum $SimpleEnum, #SimpleEnum.HasInt2!enumelt.1, %8 : $Int // user: %14 - dealloc_stack %9#0 : $*@local_storage Int // id: %13 - br bb5(%12 : $SimpleEnum) // id: %14 - -bb4(%13 : $Int): // Preds: bb0 - %14 = alloc_stack $Int // var N // users: %13, %10 - store %13 to %14#1 : $*Int // id: %10 - %15 = enum $SimpleEnum, #SimpleEnum.HasInt!enumelt.1, %13 : $Int // user: %14 - dealloc_stack %14#0 : $*@local_storage Int // id: %13 - br bb5(%15 : $SimpleEnum) // id: %14 - -bb5(%16 : $SimpleEnum): // Preds: bb2 bb4 - dealloc_stack %1#0 : $*@local_storage SimpleEnum // id: %16 - return %16 : $SimpleEnum // id: %17 -} - diff --git a/test/SILPasses/specialize_chain.swift b/test/SILPasses/specialize_chain.swift deleted file mode 100644 index b87483e41cb67..0000000000000 --- a/test/SILPasses/specialize_chain.swift +++ /dev/null @@ -1,50 +0,0 @@ -// RUN: %target-swift-frontend -O -emit-sil -primary-file %s | FileCheck %s - -// We can't deserialize apply_inst with subst lists. When radar://14443304 -// is fixed then we should convert this test to a SIL test. - -struct YYY { - @inline(never) - init(t : T) {m_t = t} - @inline(never) mutating - func AAA9(t t : T) -> Int { return AAA8(t: t)} - @inline(never) mutating - func AAA8(t t : T) -> Int { return AAA7(t: t)} - @inline(never) mutating - func AAA7(t t : T) -> Int { return AAA6(t: t)} - @inline(never) mutating - func AAA6(t t : T) -> Int { return AAA5(t: t)} - @inline(never) mutating - func AAA5(t t : T) -> Int { return AAA4(t: t)} - @inline(never) mutating - func AAA4(t t : T) -> Int { return AAA3(t: t)} - @inline(never) mutating - func AAA3(t t : T) -> Int { return AAA2(t: t)} - @inline(never) mutating - func AAA2(t t : T) -> Int { return AAA1(t: t)} - @inline(never) mutating - func AAA1(t t : T) -> Int { return AAA0(t: t)} - @inline(never) mutating - func AAA0(t t : T) -> Int { return foo(t: t)} - @inline(never) mutating - func foo(t t : T) -> Int {m_t = t; return 4} - var m_t : T -} - -func exp1() { - var II = YYY(t: 5) - print(II.AAA9(t: 4), terminator: "") -} -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA9 -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA8 -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA7 -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA6 -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA5 -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA4 -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA3 -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA2 -//CHECK: sil shared [noinline] @_TTSg5Si___TFV16specialize_chain3YYY4AAA1 -//CHECK: exp1 -//CHECK: function_ref @_TTSg5Si___TFV16specialize_chain3YYYC -//CHECK: function_ref @_TTSg5Si___TFV16specialize_chain3YYY4AAA9 -//CHECK: return diff --git a/test/SILPasses/sroa.sil b/test/SILPasses/sroa.sil deleted file mode 100644 index b2aea4b512222..0000000000000 --- a/test/SILPasses/sroa.sil +++ /dev/null @@ -1,423 +0,0 @@ -// RUN: %target-sil-opt -enable-sil-verify-all -sroa %s | FileCheck %s - -sil_stage canonical - -import Builtin -import Swift - -/////////////////////////////// -// Struct with Scalar Fields // -/////////////////////////////// - -struct S1 { - var x : Builtin.Int1 - var y : Builtin.Int32 - var z : Builtin.Int64 -} - -sil @use_int32 : $@convention(thin) (Builtin.Int32) -> () - -// CHECK-LABEL: sil @struct_with_scalar_fields : $@convention(thin) (S1) -> () -// CHECK: bb0([[VAR_0:%[0-9]+]] : $S1): -// CHECK: [[VAR_1:%[0-9]+]] = alloc_stack $Builtin.Int1 -// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32 -// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64 -// CHECK: [[VAR_4:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.x -// CHECK: store [[VAR_4]] to [[VAR_1]]#1 : $*Builtin.Int1 -// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.y -// CHECK: store [[VAR_6]] to [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_0]] : $S1, #S1.z -// CHECK: store [[VAR_8]] to [[VAR_3]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_11:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_12:%[0-9]+]] = apply [[VAR_10]]([[VAR_11]]) : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_1]]#1 : $*Builtin.Int1 -// CHECK: [[VAR_14:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_15:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_16:%[0-9]+]] = struct $S1 ([[VAR_13]] : $Builtin.Int1, [[VAR_14]] : $Builtin.Int32, [[VAR_15]] : $Builtin.Int64) -// CHECK: dealloc_stack [[VAR_3]]#0 : $*@local_storage Builtin.Int64 -// CHECK: dealloc_stack [[VAR_2]]#0 : $*@local_storage Builtin.Int32 -// CHECK: dealloc_stack [[VAR_1]]#0 : $*@local_storage Builtin.Int1 -// CHECK: [[VAR_20:%[0-9]+]] = tuple () -// CHECK: return [[VAR_20]] : $() -sil @struct_with_scalar_fields : $@convention(thin) (S1) -> () { -bb0(%0 : $S1): - %1 = alloc_stack $S1 - debug_value %1#0 : $*@local_storage S1 // should not prevent the optimization - debug_value %1#1 : $*S1 // should not prevent the optimization - store %0 to %1#1 : $*S1 - %2 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () - %3 = struct_element_addr %1#1 : $*S1, #S1.y - %4 = load %3 : $*Builtin.Int32 - apply %2(%4) : $@convention(thin) (Builtin.Int32) -> () - %5 = load %1#1 : $*S1 - dealloc_stack %1#0 : $*@local_storage S1 - %6 = tuple () - return %6 : $() -} - -/////////////////////////////// -// Struct With Struct Fields // -/////////////////////////////// - -sil @use_s1 : $@convention(thin) (S1) -> () - -struct S2 { - var alpha : Builtin.FPIEEE32 - var beta : S1 -} - -// CHECK-LABEL: sil @struct_with_struct_fields : $@convention(thin) (S2, Builtin.Int64) -> () -// CHECK: bb0([[VAR_0:%[0-9]+]] : $S2, [[VAR_1:%[0-9]+]] : $Builtin.Int64): -// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.FPIEEE32 -// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int1 -// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int32 -// CHECK: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.Int64 -// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S2, #S2.alpha -// CHECK: store [[VAR_6]] to [[VAR_2]]#1 : $*Builtin.FPIEEE32 -// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_0]] : $S2, #S2.beta -// CHECK: [[VAR_9:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.x -// CHECK: store [[VAR_9]] to [[VAR_3]]#1 : $*Builtin.Int1 -// CHECK: [[VAR_11:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.y -// CHECK: store [[VAR_11]] to [[VAR_4]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_13:%[0-9]+]] = struct_extract [[VAR_8]] : $S1, #S1.z -// CHECK: store [[VAR_13]] to [[VAR_5]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_15:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int1 -// CHECK: [[VAR_16:%[0-9]+]] = load [[VAR_4]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_17:%[0-9]+]] = load [[VAR_5]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_18:%[0-9]+]] = struct $S1 ([[VAR_15]] : $Builtin.Int1, [[VAR_16]] : $Builtin.Int32, [[VAR_17]] : $Builtin.Int64) -// CHECK: [[VAR_19:%[0-9]+]] = function_ref @use_s1 : $@convention(thin) (S1) -> () -// CHECK: [[VAR_20:%[0-9]+]] = apply [[VAR_19]]([[VAR_18]]) : $@convention(thin) (S1) -> () -// CHECK: [[VAR_21:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_22:%[0-9]+]] = load [[VAR_4]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_23:%[0-9]+]] = apply [[VAR_21]]([[VAR_22]]) : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_24:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.FPIEEE32 -// CHECK: [[VAR_25:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int1 -// CHECK: [[VAR_26:%[0-9]+]] = load [[VAR_4]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_27:%[0-9]+]] = load [[VAR_5]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_28:%[0-9]+]] = struct $S1 ([[VAR_25]] : $Builtin.Int1, [[VAR_26]] : $Builtin.Int32, [[VAR_27]] : $Builtin.Int64) -// CHECK: [[VAR_29:%[0-9]+]] = struct $S2 ([[VAR_24]] : $Builtin.FPIEEE32, [[VAR_28]] : $S1) -// CHECK: store [[VAR_1]] to [[VAR_5]]#1 : $*Builtin.Int64 -// CHECK: dealloc_stack [[VAR_5]]#0 : $*@local_storage Builtin.Int64 -// CHECK: dealloc_stack [[VAR_4]]#0 : $*@local_storage Builtin.Int32 -// CHECK: dealloc_stack [[VAR_3]]#0 : $*@local_storage Builtin.Int1 -// CHECK: dealloc_stack [[VAR_2]]#0 : $*@local_storage Builtin.FPIEEE32 -// CHECK: [[VAR_35:%[0-9]+]] = tuple () -// CHECK: return [[VAR_35]] : $() -sil @struct_with_struct_fields : $@convention(thin) (S2, Builtin.Int64) -> () { -bb0(%0 : $S2, %1 : $Builtin.Int64): - %2 = alloc_stack $S2 - store %0 to %2#1 : $*S2 - %3 = struct_element_addr %2#1 : $*S2, #S2.beta - %4 = load %3 : $*S1 - %5 = function_ref @use_s1 : $@convention(thin) (S1) -> () - apply %5(%4) : $@convention(thin) (S1) -> () - %6 = struct_element_addr %3 : $*S1, #S1.y - %7 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () - %8 = load %6 : $*Builtin.Int32 - apply %7(%8) : $@convention(thin) (Builtin.Int32) -> () - %9 = load %2#1 : $*S2 - %10 = struct_element_addr %3 : $*S1, #S1.z - store %1 to %10 : $*Builtin.Int64 - dealloc_stack %2#0 : $*@local_storage S2 - %11 = tuple() - return %11 : $() -} - -////////////////////////////// -// Struct with Tuple Fields // -////////////////////////////// - -sil @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () - -struct S3 { - var gamma : (Builtin.Int32, Builtin.Int64, Builtin.Int16) - var delta : Builtin.FPIEEE32 -} - -// CHECK-LABEL: sil @struct_with_tuple_fields : $@convention(thin) (S3, Builtin.Int64) -> () -// CHECK: bb0([[VAR_0:%[0-9]+]] : $S3, [[VAR_1:%[0-9]+]] : $Builtin.Int64): -// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32 -// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64 -// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16 -// CHECK: [[VAR_5:%[0-9]+]] = alloc_stack $Builtin.FPIEEE32 -// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_0]] : $S3, #S3.gamma -// CHECK: [[VAR_7:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 0 -// CHECK: store [[VAR_7]] to [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_9:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 1 -// CHECK: store [[VAR_9]] to [[VAR_3]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_11:%[0-9]+]] = tuple_extract [[VAR_6]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), 2 -// CHECK: store [[VAR_11]] to [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: [[VAR_13:%[0-9]+]] = struct_extract [[VAR_0]] : $S3, #S3.delta -// CHECK: store [[VAR_13]] to [[VAR_5]]#1 : $*Builtin.FPIEEE32 -// CHECK: [[VAR_15:%[0-9]+]] = function_ref @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () -// CHECK: [[VAR_16:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_17:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_18:%[0-9]+]] = load [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: [[VAR_19:%[0-9]+]] = tuple ([[VAR_16]] : $Builtin.Int32, [[VAR_17]] : $Builtin.Int64, [[VAR_18]] : $Builtin.Int16) -// CHECK: [[VAR_20:%[0-9]+]] = apply [[VAR_15]]([[VAR_19]]) : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () -// CHECK: [[VAR_21:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_22:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_23:%[0-9]+]] = apply [[VAR_22]]([[VAR_21]]) : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_24:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_25:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_26:%[0-9]+]] = load [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: [[VAR_27:%[0-9]+]] = tuple ([[VAR_24]] : $Builtin.Int32, [[VAR_25]] : $Builtin.Int64, [[VAR_26]] : $Builtin.Int16) -// CHECK: [[VAR_28:%[0-9]+]] = load [[VAR_5]]#1 : $*Builtin.FPIEEE32 -// CHECK: [[VAR_29:%[0-9]+]] = struct $S3 ([[VAR_27]] : $(Builtin.Int32, Builtin.Int64, Builtin.Int16), [[VAR_28]] : $Builtin.FPIEEE32) -// CHECK: store [[VAR_1]] to [[VAR_3]]#1 : $*Builtin.Int64 -// CHECK: dealloc_stack [[VAR_5]]#0 : $*@local_storage Builtin.FPIEEE32 -// CHECK: dealloc_stack [[VAR_4]]#0 : $*@local_storage Builtin.Int16 -// CHECK: dealloc_stack [[VAR_3]]#0 : $*@local_storage Builtin.Int64 -// CHECK: dealloc_stack [[VAR_2]]#0 : $*@local_storage Builtin.Int32 -// CHECK: [[VAR_35:%[0-9]+]] = tuple () -// CHECK: return [[VAR_35]] : $() -sil @struct_with_tuple_fields : $@convention(thin) (S3, Builtin.Int64) -> () { -bb0(%0 : $S3, %1 : $Builtin.Int64): - %2 = alloc_stack $S3 - store %0 to %2#1 : $*S3 - %3 = function_ref @use_tup : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () - %4 = struct_element_addr %2#1 : $*S3, #S3.gamma - %5 = load %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16) - apply %3(%5) : $@convention(thin) ((Builtin.Int32, Builtin.Int64, Builtin.Int16)) -> () - %6 = tuple_element_addr %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16), 0 - %7 = load %6 : $*Builtin.Int32 - %8 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () - apply %8(%7) : $@convention(thin) (Builtin.Int32) -> () - %9 = load %2#1 : $*S3 - %10 = tuple_element_addr %4 : $*(Builtin.Int32, Builtin.Int64, Builtin.Int16), 1 - store %1 to %10 : $*Builtin.Int64 - dealloc_stack %2#0 : $*@local_storage S3 - %11 = tuple () - return %11 : $() -} - -////////////////////////////// -// Tuple with Scalar Fields // -////////////////////////////// - -// CHECK-LABEL: sil @tuple_with_scalar_fields : $@convention(thin) ((Builtin.Int1, Builtin.Int32, Builtin.Int64)) -> () -// CHECK: bb0([[VAR_0:%[0-9]+]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64)): -// CHECK: [[VAR_1:%[0-9]+]] = alloc_stack $Builtin.Int1 -// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int32 -// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int64 -// CHECK: [[VAR_4:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 0 -// CHECK: store [[VAR_4]] to [[VAR_1]]#1 : $*Builtin.Int1 -// CHECK: [[VAR_6:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 1 -// CHECK: store [[VAR_6]] to [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_8:%[0-9]+]] = tuple_extract [[VAR_0]] : $(Builtin.Int1, Builtin.Int32, Builtin.Int64), 2 -// CHECK: store [[VAR_8]] to [[VAR_3]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_10:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_11:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_12:%[0-9]+]] = apply [[VAR_10]]([[VAR_11]]) : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_1]]#1 : $*Builtin.Int1 -// CHECK: [[VAR_14:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_15:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_16:%[0-9]+]] = tuple ([[VAR_13]] : $Builtin.Int1, [[VAR_14]] : $Builtin.Int32, [[VAR_15]] : $Builtin.Int64) -// CHECK: dealloc_stack [[VAR_3]]#0 : $*@local_storage Builtin.Int64 -// CHECK: dealloc_stack [[VAR_2]]#0 : $*@local_storage Builtin.Int32 -// CHECK: dealloc_stack [[VAR_1]]#0 : $*@local_storage Builtin.Int1 -// CHECK: [[VAR_20:%[0-9]+]] = tuple () -// CHECK: return [[VAR_20]] : $() -sil @tuple_with_scalar_fields : $@convention(thin) ((Builtin.Int1, Builtin.Int32, Builtin.Int64)) -> () { -bb0(%0 : $(Builtin.Int1, Builtin.Int32, Builtin.Int64)): - %1 = alloc_stack $(Builtin.Int1, Builtin.Int32, Builtin.Int64) - store %0 to %1#1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64) - %2 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () - %3 = tuple_element_addr %1#1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64), 1 - %4 = load %3 : $*Builtin.Int32 - apply %2(%4) : $@convention(thin) (Builtin.Int32) -> () - %5 = load %1#1 : $*(Builtin.Int1, Builtin.Int32, Builtin.Int64) - dealloc_stack %1#0 : $*@local_storage (Builtin.Int1, Builtin.Int32, Builtin.Int64) - %6 = tuple() - return %6 : $() -} - -////////////////////////////// -// Tuple With Struct Fields // -////////////////////////////// - -struct S4 { - var aleph : Builtin.Int64 - var bet : Builtin.Int32 -} - -sil @use_str4 : $@convention(thin) (S4) -> () - -// CHECK-LABEL: sil @tuple_with_struct_fields : $@convention(thin) ((S4, Builtin.Int16), Builtin.Int16) -> () -// CHECK: bb0([[VAR_0:%[0-9]+]] : $(S4, Builtin.Int16), [[VAR_1:%[0-9]+]] : $Builtin.Int16): -// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int64 -// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32 -// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16 -// CHECK: [[VAR_5:%[0-9]+]] = tuple_extract [[VAR_0]] : $(S4, Builtin.Int16), 0 -// CHECK: [[VAR_6:%[0-9]+]] = struct_extract [[VAR_5]] : $S4, #S4.aleph -// CHECK: store [[VAR_6]] to [[VAR_2]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_8:%[0-9]+]] = struct_extract [[VAR_5]] : $S4, #S4.bet -// CHECK: store [[VAR_8]] to [[VAR_3]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_10:%[0-9]+]] = tuple_extract [[VAR_0]] : $(S4, Builtin.Int16), 1 -// CHECK: store [[VAR_10]] to [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: [[VAR_12:%[0-9]+]] = function_ref @use_str4 : $@convention(thin) (S4) -> () -// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_14:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_15:%[0-9]+]] = struct $S4 ([[VAR_13]] : $Builtin.Int64, [[VAR_14]] : $Builtin.Int32) -// CHECK: [[VAR_16:%[0-9]+]] = apply [[VAR_12]]([[VAR_15]]) : $@convention(thin) (S4) -> () -// CHECK: [[VAR_17:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_18:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_19:%[0-9]+]] = apply [[VAR_18]]([[VAR_17]]) : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_20:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_21:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_22:%[0-9]+]] = struct $S4 ([[VAR_20]] : $Builtin.Int64, [[VAR_21]] : $Builtin.Int32) -// CHECK: [[VAR_23:%[0-9]+]] = load [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: [[VAR_24:%[0-9]+]] = tuple ([[VAR_22]] : $S4, [[VAR_23]] : $Builtin.Int16) -// CHECK: store [[VAR_1]] to [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: dealloc_stack [[VAR_4]]#0 : $*@local_storage Builtin.Int16 -// CHECK: dealloc_stack [[VAR_3]]#0 : $*@local_storage Builtin.Int32 -// CHECK: dealloc_stack [[VAR_2]]#0 : $*@local_storage Builtin.Int64 -// CHECK: [[VAR_29:%[0-9]+]] = tuple () -// CHECK: return [[VAR_29]] : $() -sil @tuple_with_struct_fields : $@convention(thin) ((S4, Builtin.Int16), Builtin.Int16) -> () { -bb0(%0 : $(S4, Builtin.Int16), %1 : $Builtin.Int16): - %2 = alloc_stack $(S4, Builtin.Int16) - store %0 to %2#1 : $*(S4, Builtin.Int16) - %3 = function_ref @use_str4 : $@convention(thin) (S4) -> () - %4 = tuple_element_addr %2#1 : $*(S4, Builtin.Int16), 0 - %5 = load %4 : $*S4 - apply %3(%5) : $@convention(thin) (S4) -> () - %6 = struct_element_addr %4 : $*S4, #S4.bet - %7 = load %6 : $*Builtin.Int32 - %8 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () - apply %8(%7) : $@convention(thin) (Builtin.Int32) -> () - %9 = load %2#1 : $*(S4, Builtin.Int16) - %10 = tuple_element_addr %2#1 : $*(S4, Builtin.Int16), 1 - store %1 to %10 : $*Builtin.Int16 - dealloc_stack %2#0 : $*@local_storage (S4, Builtin.Int16) - %11 = tuple() - return %11 : $() -} - -///////////////////////////////// -// Tuple with Tuple Field Test // -///////////////////////////////// - -sil @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () -sil @use_int16 : $@convention(thin) (Builtin.Int16) -> () - -// CHECK-LABEL: sil @tuple_with_tuple_fields : $@convention(thin) (((Builtin.Int64, Builtin.Int32), Builtin.Int16), Builtin.Int16) -> () -// CHECK: bb0([[VAR_0:%[0-9]+]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), [[VAR_1:%[0-9]+]] : $Builtin.Int16): -// CHECK: [[VAR_2:%[0-9]+]] = alloc_stack $Builtin.Int64 -// CHECK: [[VAR_3:%[0-9]+]] = alloc_stack $Builtin.Int32 -// CHECK: [[VAR_4:%[0-9]+]] = alloc_stack $Builtin.Int16 -// CHECK: [[VAR_5:%[0-9]+]] = tuple_extract [[VAR_0]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), 0 -// CHECK: [[VAR_6:%[0-9]+]] = tuple_extract [[VAR_5]] : $(Builtin.Int64, Builtin.Int32), 0 -// CHECK: store [[VAR_6]] to [[VAR_2]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_8:%[0-9]+]] = tuple_extract [[VAR_5]] : $(Builtin.Int64, Builtin.Int32), 1 -// CHECK: store [[VAR_8]] to [[VAR_3]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_10:%[0-9]+]] = tuple_extract [[VAR_0]] : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), 1 -// CHECK: store [[VAR_10]] to [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: [[VAR_12:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_13:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_14:%[0-9]+]] = tuple ([[VAR_12]] : $Builtin.Int64, [[VAR_13]] : $Builtin.Int32) -// CHECK: [[VAR_15:%[0-9]+]] = function_ref @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () -// CHECK: [[VAR_16:%[0-9]+]] = apply [[VAR_15]]([[VAR_14]]) : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () -// CHECK: [[VAR_17:%[0-9]+]] = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_18:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_19:%[0-9]+]] = apply [[VAR_17]]([[VAR_18]]) : $@convention(thin) (Builtin.Int32) -> () -// CHECK: [[VAR_20:%[0-9]+]] = load [[VAR_2]]#1 : $*Builtin.Int64 -// CHECK: [[VAR_21:%[0-9]+]] = load [[VAR_3]]#1 : $*Builtin.Int32 -// CHECK: [[VAR_22:%[0-9]+]] = tuple ([[VAR_20]] : $Builtin.Int64, [[VAR_21]] : $Builtin.Int32) -// CHECK: [[VAR_23:%[0-9]+]] = load [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: [[VAR_24:%[0-9]+]] = tuple ([[VAR_22]] : $(Builtin.Int64, Builtin.Int32), [[VAR_23]] : $Builtin.Int16) -// CHECK: store [[VAR_1]] to [[VAR_4]]#1 : $*Builtin.Int16 -// CHECK: dealloc_stack [[VAR_4]]#0 : $*@local_storage Builtin.Int16 -// CHECK: dealloc_stack [[VAR_3]]#0 : $*@local_storage Builtin.Int32 -// CHECK: dealloc_stack [[VAR_2]]#0 : $*@local_storage Builtin.Int64 -// CHECK: [[VAR_29:%[0-9]+]] = tuple () -// CHECK: return [[VAR_29]] : $() -sil @tuple_with_tuple_fields : $@convention(thin) (((Builtin.Int64, Builtin.Int32), Builtin.Int16), Builtin.Int16) -> () { -bb0(%0 : $((Builtin.Int64, Builtin.Int32), Builtin.Int16), %1 : $Builtin.Int16): - %2 = alloc_stack $((Builtin.Int64, Builtin.Int32), Builtin.Int16) - store %0 to %2#1 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16) - %3 = tuple_element_addr %2#1 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16), 0 - %4 = load %3 : $*(Builtin.Int64, Builtin.Int32) - %5 = function_ref @use_tup2 : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () - apply %5(%4) : $@convention(thin) ((Builtin.Int64, Builtin.Int32)) -> () - %6 = tuple_element_addr %3 : $*(Builtin.Int64, Builtin.Int32), 1 - %7 = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> () - %8 = load %6 : $*Builtin.Int32 - apply %7(%8) : $@convention(thin) (Builtin.Int32) -> () - %9 = load %2#1 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16) - %10 = tuple_element_addr %2#1 : $*((Builtin.Int64, Builtin.Int32), Builtin.Int16), 1 - store %1 to %10 : $*Builtin.Int16 - dealloc_stack %2#0 : $*@local_storage ((Builtin.Int64, Builtin.Int32), Builtin.Int16) - %11 = tuple() - return %11 : $() -} - -///////////////////////// -// Capture Struct Test // -///////////////////////// - -struct CapturedS { - var x : Builtin.Int32 -} - -sil @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> () - -// CHECK-LABEL: sil @captured_struct : $@convention(thin) (CapturedS) -> () -// CHECK: bb0([[VAR_0:%[0-9]+]] : $CapturedS): -// CHECK: [[VAR_1:%[0-9]+]] = alloc_stack $CapturedS -// CHECK: store [[VAR_0]] to [[VAR_1]]#1 : $*CapturedS -// CHECK: [[VAR_3:%[0-9]+]] = struct_element_addr [[VAR_1]]#1 : $*CapturedS, #CapturedS.x -// CHECK: [[VAR_4:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 -// CHECK: [[VAR_5:%[0-9]+]] = function_ref @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> () -// CHECK: [[VAR_6:%[0-9]+]] = apply [[VAR_5]]([[VAR_1]]#1) : $@convention(thin) (@inout CapturedS) -> () -// CHECK: [[VAR_7:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 -// CHECK: dealloc_stack [[VAR_1]]#0 : $*@local_storage CapturedS -// CHECK: [[VAR_9:%[0-9]+]] = tuple () -// CHECK: return [[VAR_9]] : $() -sil @captured_struct : $@convention(thin) (CapturedS) -> () { -bb0(%0 : $CapturedS): - %1 = alloc_stack $CapturedS - store %0 to %1#1 : $*CapturedS - %3 = struct_element_addr %1#1 : $*CapturedS, #CapturedS.x - %4 = load %3 : $*Builtin.Int32 - %5 = function_ref @use_capturedstruct : $@convention(thin) (@inout CapturedS) -> () - %6 = apply %5(%1#1) : $@convention(thin) (@inout CapturedS) -> () - %7 = load %3 : $*Builtin.Int32 - dealloc_stack %1#0 : $*@local_storage CapturedS - %9 = tuple () - return %9 : $() -} - -///////////////////////// -// Captured Tuple Test // -///////////////////////// - -sil @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () - -// CHECK-LABEL: sil @captured_tuple : $@convention(thin) ((Builtin.Int32, Builtin.Int64)) -> () -// CHECK: bb0([[VAR_0:%[0-9]+]] : $(Builtin.Int32, Builtin.Int64)): -// CHECK: [[VAR_1:%[0-9]+]] = alloc_stack $(Builtin.Int32, Builtin.Int64) -// CHECK: store [[VAR_0]] to [[VAR_1]]#1 : $*(Builtin.Int32, Builtin.Int64) -// CHECK: [[VAR_3:%[0-9]+]] = tuple_element_addr [[VAR_1]]#1 : $*(Builtin.Int32, Builtin.Int64), 0 -// CHECK: [[VAR_4:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 -// CHECK: [[VAR_5:%[0-9]+]] = function_ref @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () -// CHECK: [[VAR_6:%[0-9]+]] = apply [[VAR_5]]([[VAR_1]]#1) : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () -// CHECK: [[VAR_7:%[0-9]+]] = load [[VAR_3]] : $*Builtin.Int32 -// CHECK: dealloc_stack [[VAR_1]]#0 : $*@local_storage (Builtin.Int32, Builtin.Int64) -// CHECK: [[VAR_9:%[0-9]+]] = tuple () -// CHECK: return [[VAR_9]] : $() -sil @captured_tuple : $@convention(thin) ((Builtin.Int32, Builtin.Int64)) -> () { -bb0(%0 : $(Builtin.Int32, Builtin.Int64)): - %1 = alloc_stack $(Builtin.Int32, Builtin.Int64) - store %0 to %1#1 : $*(Builtin.Int32, Builtin.Int64) - %3 = tuple_element_addr %1#1 : $*(Builtin.Int32, Builtin.Int64), 0 - %4 = load %3 : $*Builtin.Int32 - %5 = function_ref @use_capturedtuple : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () - %6 = apply %5(%1#1) : $@convention(thin) (@inout (Builtin.Int32, Builtin.Int64)) -> () - %7 = load %3 : $*Builtin.Int32 - dealloc_stack %1#0 : $*@local_storage (Builtin.Int32, Builtin.Int64) - %9 = tuple () - return %9 : $() -} - diff --git a/test/Sema/accessibility.swift b/test/Sema/accessibility.swift index 625e9442ee0fb..3ac2ebf904a5f 100644 --- a/test/Sema/accessibility.swift +++ b/test/Sema/accessibility.swift @@ -309,6 +309,7 @@ struct DefaultGeneric {} struct DefaultGenericPrivate {} // expected-error {{generic struct must be declared private because its generic parameter uses a private type}} struct DefaultGenericPrivate2 {} // expected-error {{generic struct must be declared private because its generic parameter uses a private type}} struct DefaultGenericPrivateReq {} // expected-error {{same-type requirement makes generic parameter 'T' non-generic}} +// expected-error@-1 {{generic struct must be declared private because its generic requirement uses a private type}} struct DefaultGenericPrivateReq2 {} // expected-error {{generic struct must be declared private because its generic requirement uses a private type}} public struct PublicGenericInternal {} // expected-error {{generic struct cannot be declared public because its generic parameter uses an internal type}} diff --git a/test/Sema/availability_versions.swift b/test/Sema/availability_versions.swift index ceb523bf4f441..9c95bdea824e7 100644 --- a/test/Sema/availability_versions.swift +++ b/test/Sema/availability_versions.swift @@ -757,7 +757,7 @@ class ClassWithDeclarationsOfUnavailableClasses { func unavailableMethodWithUnavailableParameterType(o : ClassAvailableOn10_10) { } - func methodWithUnavailableReturnType() -> ClassAvailableOn10_10 { // expected-error {{'ClassAvailableOn10_10' is only available on OS X 10.10 or newer}} + func methodWithUnavailableReturnType() -> ClassAvailableOn10_10 { // expected-error {{'ClassAvailableOn10_10' is only available on OS X 10.10 or newer}} // expected-note@-1 {{add @available attribute to enclosing class}} // expected-note@-2 {{add @available attribute to enclosing instance method}} @@ -768,7 +768,7 @@ class ClassWithDeclarationsOfUnavailableClasses { } @available(OSX, introduced=10.10) - func unavailableMethodWithUnavailableReturnType() -> ClassAvailableOn10_10 { + func unavailableMethodWithUnavailableReturnType() -> ClassAvailableOn10_10 { return ClassAvailableOn10_10() } diff --git a/test/Sema/availability_versions_objc_api.swift b/test/Sema/availability_versions_objc_api.swift index a5a9c9c2827c6..7d56be22a7d0b 100644 --- a/test/Sema/availability_versions_objc_api.swift +++ b/test/Sema/availability_versions_objc_api.swift @@ -204,7 +204,7 @@ class SubclassOfFrameworkClassConformingToUnannotatedFrameworkProtocol : Framewo } @available(OSX 10.11, *) -class SubclassOfLaterFameworkClassConformingToUnannotatedFrameworkProtocol : LaterFrameworkClassConformingToUnannotatedFrameworkProtocol { +class SubclassOfLaterFrameworkClassConformingToUnannotatedFrameworkProtocol : LaterFrameworkClassConformingToUnannotatedFrameworkProtocol { @available(OSX 10.11, *) override func doSomethingWithNonNullableClass(k: AnnotatedFrameworkClass) { } diff --git a/test/Sema/diag_c_style_for.swift b/test/Sema/diag_c_style_for.swift new file mode 100644 index 0000000000000..0905e10622917 --- /dev/null +++ b/test/Sema/diag_c_style_for.swift @@ -0,0 +1,57 @@ +// RUN: %target-parse-verify-swift + +// expected-warning @+1 {{'++' is deprecated: it will be removed in Swift 3}} +for var a = 0; a < 10; a++ { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} {{10-13= in }} {{14-20= ..< }} {{22-27=}} +} + +// expected-warning @+1 {{'++' is deprecated: it will be removed in Swift 3}} +for var b = 0; b < 10; ++b { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} {{10-13= in }} {{14-20= ..< }} {{22-27=}} +} + +// expected-warning @+1 {{'++' is deprecated: it will be removed in Swift 3}} +for var c=1;c != 5 ;++c { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} {{10-11= in }} {{12-18= ..< }} {{20-24=}} +} + +// expected-warning @+1 {{'++' is deprecated: it will be removed in Swift 3}} +for var d=100;d<5;d++ { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} {{10-11= in }} {{14-17= ..< }} {{18-22=}} +} + +// next three aren't auto-fixable +// expected-warning @+1 {{'++' is deprecated: it will be removed in Swift 3}} +for var e = 3; e > 4; e++ { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} {{none}} +} + +// expected-warning @+1 {{'--' is deprecated: it will be removed in Swift 3}} +for var f = 3; f < 4; f-- { // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} {{none}} +} + +let start = Int8(4) +let count = Int8(10) +var other = Int8(2) + +// expected-warning @+1 {{'++' is deprecated: it will be removed in Swift 3}} +for ; other) // expected-error {{editor placeholder}} expected-error {{use of undeclared type 'Undeclared'}} + +func f(n: Int) {} +let a1 = <#T#> // expected-error{{editor placeholder in source file}} +f(a1) // expected-error{{cannot convert value of type '()' to expected argument type 'Int'}} +let a2 = <#T##Int#> // expected-error{{editor placeholder in source file}} +f(a2) +<#T#> // expected-error{{editor placeholder in source file}} + +// FIXME: Lexer yields "editor placeholder in source file" error twice when placeholder is first token +<#T##Int#> // expected-error 2{{editor placeholder in source file}} + +f(<#T#> + 1) // expected-error{{editor placeholder in source file}} +f(<#T##Int#>) // expected-error{{editor placeholder in source file}} +f(<#T##String#>) // expected-error{{editor placeholder in source file}} expected-error{{cannot convert value of type 'String' to expected argument type 'Int'}} + +for x in <#T#> { // expected-error{{editor placeholder in source file}} expected-error{{type '()' does not conform to protocol 'SequenceType'}} +} diff --git a/test/Sema/immutability.swift b/test/Sema/immutability.swift index a9cbd110a773c..022d7394cb6e2 100644 --- a/test/Sema/immutability.swift +++ b/test/Sema/immutability.swift @@ -23,7 +23,7 @@ func foreach_variable() { } } -func takeClosure(fn : (Int)->Int) {} +func takeClosure(fn : (Int) -> Int) {} func passClosure() { takeClosure { a in @@ -221,10 +221,10 @@ func test_mutability() { func test_arguments(a : Int, - var b : Int, // expected-error {{Use of 'var' binding here is not allowed}} {{21-25=}} - let c : Int) { // expected-warning {{'let' keyword is unnecessary; function parameters are immutable by default}} {{21-25=}} + var b : Int, // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{21-25=}} + let c : Int) { // expected-warning {{Use of 'let' binding here is deprecated and will be removed in a future version of Swift}} {{21-25=}} a = 1 // expected-error {{cannot assign to value: 'a' is a 'let' constant}} - var b = 2 // ok. + b = 2 // ok. c = 3 // expected-error {{cannot assign to value: 'c' is a 'let' constant}} } @@ -317,7 +317,7 @@ func testSubscriptNoGetter(iis: SubscriptNoGetter) { func testSelectorStyleArguments1(x: Int, bar y: Int) { var x = x var y = y - ++x; ++y + x += 1; y += 1 } func testSelectorStyleArguments2(x: Int, diff --git a/test/Sema/object_literals.swift b/test/Sema/object_literals.swift deleted file mode 100644 index 67c0eab8d6941..0000000000000 --- a/test/Sema/object_literals.swift +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %target-parse-verify-swift - -struct S: _ColorLiteralConvertible { - init(colorLiteralRed: Float, green: Float, blue: Float, alpha: Float) {} -} - -let y: S = [#Color(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)#] - -struct I: _ImageLiteralConvertible { - init(imageLiteral: String) {} -} - -let z: I = [#Image(imageLiteral: "hello.png")#] - -struct Path: _FileReferenceLiteralConvertible { - init(fileReferenceLiteral: String) {} -} - -let p1: Path = [#FileReference(fileReferenceLiteral: "what.txt")#] diff --git a/test/Sema/object_literals_ios.swift b/test/Sema/object_literals_ios.swift new file mode 100644 index 0000000000000..23893c7e4496c --- /dev/null +++ b/test/Sema/object_literals_ios.swift @@ -0,0 +1,24 @@ +// RUN: %target-parse-verify-swift +// REQUIRES: OS=ios + +struct S: _ColorLiteralConvertible { + init(colorLiteralRed: Float, green: Float, blue: Float, alpha: Float) {} +} + +let y: S = [#Color(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)#] +let y2 = [#Color(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)#] // expected-error{{could not infer type of color literal}} expected-note{{import UIKit to use 'UIColor' as the default color literal type}} +let y3 = [#Color(colorLiteralRed: 1, bleen: 0, grue: 0, alpha: 1)#] // expected-error{{cannot convert value of type '(colorLiteralRed: Int, bleen: Int, grue: Int, alpha: Int)' to expected argument type '(colorLiteralRed: Float, green: Float, blue: Float, alpha: Float)'}} + +struct I: _ImageLiteralConvertible { + init(imageLiteral: String) {} +} + +let z: I = [#Image(imageLiteral: "hello.png")#] +let z2 = [#Image(imageLiteral: "hello.png")#] // expected-error{{could not infer type of image literal}} expected-note{{import UIKit to use 'UIImage' as the default image literal type}} + +struct Path: _FileReferenceLiteralConvertible { + init(fileReferenceLiteral: String) {} +} + +let p1: Path = [#FileReference(fileReferenceLiteral: "what.txt")#] +let p2 = [#FileReference(fileReferenceLiteral: "what.txt")#] // expected-error{{could not infer type of file reference literal}} expected-note{{import Foundation to use 'NSURL' as the default file reference literal type}} diff --git a/test/Sema/object_literals_osx.swift b/test/Sema/object_literals_osx.swift new file mode 100644 index 0000000000000..bbdb5527b411c --- /dev/null +++ b/test/Sema/object_literals_osx.swift @@ -0,0 +1,24 @@ +// RUN: %target-parse-verify-swift +// REQUIRES: OS=macosx + +struct S: _ColorLiteralConvertible { + init(colorLiteralRed: Float, green: Float, blue: Float, alpha: Float) {} +} + +let y: S = [#Color(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)#] +let y2 = [#Color(colorLiteralRed: 1, green: 0, blue: 0, alpha: 1)#] // expected-error{{could not infer type of color literal}} expected-note{{import AppKit to use 'NSColor' as the default color literal type}} +let y3 = [#Color(colorLiteralRed: 1, bleen: 0, grue: 0, alpha: 1)#] // expected-error{{cannot convert value of type '(colorLiteralRed: Int, bleen: Int, grue: Int, alpha: Int)' to expected argument type '(colorLiteralRed: Float, green: Float, blue: Float, alpha: Float)'}} + +struct I: _ImageLiteralConvertible { + init(imageLiteral: String) {} +} + +let z: I = [#Image(imageLiteral: "hello.png")#] +let z2 = [#Image(imageLiteral: "hello.png")#] // expected-error{{could not infer type of image literal}} expected-note{{import AppKit to use 'NSImage' as the default image literal type}} + +struct Path: _FileReferenceLiteralConvertible { + init(fileReferenceLiteral: String) {} +} + +let p1: Path = [#FileReference(fileReferenceLiteral: "what.txt")#] +let p2 = [#FileReference(fileReferenceLiteral: "what.txt")#] // expected-error{{could not infer type of file reference literal}} expected-note{{import Foundation to use 'NSURL' as the default file reference literal type}} diff --git a/test/Sema/omit_needless_words.swift b/test/Sema/omit_needless_words.swift index 51199d7ac759c..5c4c6bf692005 100644 --- a/test/Sema/omit_needless_words.swift +++ b/test/Sema/omit_needless_words.swift @@ -30,3 +30,5 @@ extension String { class NSArray { func arrayByAddingObject(x: AnyObject) -> NSArray { return NSArray() } // expected-warning{{'arrayByAddingObject' could be named 'adding' [-Womit-needless-words]}}{{8-27=adding}} } + +func emptyFirstParamName(_: Int) { } diff --git a/test/Serialization/Inputs/def_basic.sil b/test/Serialization/Inputs/def_basic.sil index a4c25374f10c6..9753878d9c6c0 100644 --- a/test/Serialization/Inputs/def_basic.sil +++ b/test/Serialization/Inputs/def_basic.sil @@ -2,7 +2,6 @@ sil_stage raw // CHECK: sil_stage raw import Builtin import Swift -import Foundation // Test SIL Global variable. // TODO: Handling of global variables has changed: the globalinit_* symbols are now mangled. @@ -30,7 +29,7 @@ bb0: return %7 : $Builtin.RawPointer } -// This references a public global so we *SHOULD* derserialize this. +// This references a public global so we *SHOULD* deserialize this. // CHECK-LABEL: sil public_external [fragile] @_TFV18lazy_global_access4Type10staticPropSia_public : $@convention(thin) () -> Builtin.RawPointer { sil [fragile] @_TFV18lazy_global_access4Type10staticPropSia_public : $@convention(thin) () -> Builtin.RawPointer { bb0: @@ -107,9 +106,9 @@ bb0(%0 : $Int): // CHECK: bb0(%0 : $Int): // CHECK: alloc_stack $Int // CHECK: store %1 = alloc_stack $Int - store %0 to %1#1 : $*Int - %3 = load %1#1 : $*Int - dealloc_stack %1#0 : $*@local_storage Int + store %0 to %1 : $*Int + %3 = load %1 : $*Int + dealloc_stack %1 : $*Int return %3 : $Int // CHECK: return {{.*}} : $Int } @@ -117,16 +116,16 @@ bb0(%0 : $Int): // CHECK: bb0(%0 : $Int): sil [fragile] @call_fn_pointer : $@convention(thin) (() -> Int) -> Int { bb0(%0 : $() -> Int): %1 = alloc_stack $() -> Int - store %0 to %1#1 : $*() -> Int - %3 = load %1#1 : $*() -> Int + store %0 to %1 : $*() -> Int + %3 = load %1 : $*() -> Int strong_retain %3 : $() -> Int // CHECK: strong_retain %{{.*}} : $() -> Int %5 = apply %3() : $() -> Int // CHECK: apply %{{.*}}() : $() -> Int - %6 = load %1#1 : $*() -> Int + %6 = load %1 : $*() -> Int strong_release %3 : $() -> Int // CHECK: strong_release {{.*}} : $() -> Int - dealloc_stack %1#0 : $*@local_storage () -> Int + dealloc_stack %1 : $*() -> Int return %5 : $Int // CHECK: return %{{.*}} : $Int } @@ -212,19 +211,6 @@ bb0: %7 = return %6 : $() } -// CHECK-LABEL: @objc_classes : $@convention(thin) (@thick NSObject.Type) -> () -sil [fragile] @objc_classes : $@convention(thin) (@thick NSObject.Type) -> () { -bb0(%0 : $@thick NSObject.Type): - %1 = thick_to_objc_metatype %0 : $@thick NSObject.Type to $@objc_metatype NSObject.Type - // CHECK: %2 = alloc_ref_dynamic [objc] %1 : $@objc_metatype NSObject.Type, $NSObject - %2 = alloc_ref_dynamic [objc] %1 : $@objc_metatype NSObject.Type, $NSObject - %3 = value_metatype $@thick NSObject.Type, %2 : $NSObject - dealloc_partial_ref %2 : $NSObject, %3 : $@thick NSObject.Type - - %void = tuple () - return %void : $() -} // CHECK: {{^}$}} - // Generated from: // func archetype_member_ref(x: T) { // x.free_method() @@ -250,7 +236,7 @@ protocol Runcible { //%7 = metatype $@thick T.Type //%8 = witness_method [volatile] $*T, #Runcible.static_method!1 : $(@thick T.Type) -> () //%9 = apply %8(%7) : $((), @thick T.Type) -> () - //%10 = dealloc_stack %3#0 : $*@local_storage @thick T.U.Type + //%10 = dealloc_stack %3#0 : $*@thick T.U.Type //%11 = tuple () //%12 = destroy_addr %0 : $*T //%13 = return %11 : $() @@ -268,12 +254,12 @@ bb0(%0 : $*Runcible, %1 : $*protocol): // CHECK: alloc_stack %4 = alloc_stack $protocol // CHECK: copy_addr {{.*}} to [initialization] {{.*}} : $*protocol - %5 = copy_addr %2#1 to [initialization] %4#1 : $*protocol + %5 = copy_addr %2#1 to [initialization] %4 : $*protocol %7 = tuple () // CHECK: destroy_addr - %8 = destroy_addr %4#1 : $*protocol + %8 = destroy_addr %4 : $*protocol // CHECK: dealloc_stack - %9 = dealloc_stack %4#0 : $*@local_storage protocol + %9 = dealloc_stack %4 : $*protocol %10 = strong_release %2#0 : $@box protocol // CHECK: return %11 = return %7 : $() @@ -547,12 +533,12 @@ bb0(%0 : $*SomeProtocol): %2 = copy_addr [take] %0 to [initialization] %1#1 : $*SomeProtocol // CHECK: alloc_stack %4 = alloc_stack $SomeProtocol - // CHECK: copy_addr %1#1 to [initialization] %{{.*}}#1 : $*SomeProtocol - %5 = copy_addr %1#1 to [initialization] %4#1 : $*SomeProtocol + // CHECK: copy_addr %1#1 to [initialization] %{{.*}} : $*SomeProtocol + %5 = copy_addr %1#1 to [initialization] %4 : $*SomeProtocol // CHECK: existential_metatype $@thick SomeProtocol.Type, {{%.*}} : $*SomeProtocol - %6 = existential_metatype $@thick SomeProtocol.Type, %4#1 : $*SomeProtocol - %7 = destroy_addr %4#1 : $*SomeProtocol - %8 = dealloc_stack %4#0 : $*@local_storage SomeProtocol + %6 = existential_metatype $@thick SomeProtocol.Type, %4 : $*SomeProtocol + %7 = destroy_addr %4 : $*SomeProtocol + %8 = dealloc_stack %4 : $*SomeProtocol %9 = strong_release %1#0 : $@box SomeProtocol %10 = return %6 : $@thick SomeProtocol.Type } @@ -610,16 +596,6 @@ bb3(%4 : $Int): return %4 : $Int } -class Bas : NSObject { - var strRealProp : String - override init() -} -sil [fragile] @test_autorelease_return : $@convention(objc_method) (Bas) -> NSString -sil [fragile] @test_super_method : $@convention(method) (@guaranteed Bas) -> Bas - -sil [fragile] @swift_StringToNSString : $@convention(thin) (@inout String) -> @owned NSString -sil [fragile] @_TFSSCfMSSFT_SS : $@convention(thin) (@thin String.Type) -> @owned String - // CHECK-LABEL: sil public_external [fragile] @test_builtin_func_ref sil [fragile] @test_builtin_func_ref : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 { bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1): @@ -956,33 +932,20 @@ sil [fragile] @block_storage_type : $@convention(thin) Int -> @convention(block) entry(%0 : $Int): // CHECK: [[STORAGE:%.*]] = alloc_stack $@block_storage Int %s = alloc_stack $@block_storage Int - // CHECK: [[PROJECT:%.*]] = project_block_storage [[STORAGE]]#1 : $*@block_storage Int - %c = project_block_storage %s#1 : $*@block_storage Int + // CHECK: [[PROJECT:%.*]] = project_block_storage [[STORAGE]] : $*@block_storage Int + %c = project_block_storage %s : $*@block_storage Int // CHECK: store %0 to [[PROJECT]] store %0 to %c : $*Int // CHECK: [[FUNC:%.*]] = function_ref - %f = function_ref @block_invoke : $@convention(c) (@inout @block_storage Int) -> () - // CHECK: [[BLOCK:%.*]] = init_block_storage_header [[STORAGE]]#1 : $*@block_storage Int, invoke [[FUNC]] : $@convention(c) (@inout @block_storage Int) -> (), type $@convention(block) () -> () - %b = init_block_storage_header %s#1 : $*@block_storage Int, invoke %f : $@convention(c) (@inout @block_storage Int) -> (), type $@convention(block) () -> () - // CHECK: dealloc_stack [[STORAGE]]#0 : $*@local_storage @block_storage Int - dealloc_stack %s#0 : $*@local_storage @block_storage Int + %f = function_ref @block_invoke : $@convention(c) (@inout_aliasable @block_storage Int) -> () + // CHECK: [[BLOCK:%.*]] = init_block_storage_header [[STORAGE]] : $*@block_storage Int, invoke [[FUNC]] : $@convention(c) (@inout_aliasable @block_storage Int) -> (), type $@convention(block) () -> () + %b = init_block_storage_header %s : $*@block_storage Int, invoke %f : $@convention(c) (@inout_aliasable @block_storage Int) -> (), type $@convention(block) () -> () + // CHECK: dealloc_stack [[STORAGE]] : $*@block_storage Int + dealloc_stack %s : $*@block_storage Int // CHECK: return [[BLOCK]] : $@convention(block) () -> () return %b : $@convention(block) () -> () } -protocol SomeClassProtocol : class {} - -// CHECK-LABEL: sil public_external [fragile] @metatype_to_object -// CHECK: {{%.*}} = objc_metatype_to_object {{%.*}} : $@objc_metatype SomeClass.Type to $AnyObject -// CHECK: {{%.*}} = objc_existential_metatype_to_object {{%.*}} : $@objc_metatype SomeClassProtocol.Type to $AnyObject -sil [fragile] @metatype_to_object : $@convention(thin) (@objc_metatype SomeClass.Type, @objc_metatype SomeClassProtocol.Type) -> @owned (AnyObject, AnyObject) { -entry(%a : $@objc_metatype SomeClass.Type, %b : $@objc_metatype SomeClassProtocol.Type): - %x = objc_metatype_to_object %a : $@objc_metatype SomeClass.Type to $AnyObject - %y = objc_existential_metatype_to_object %b : $@objc_metatype SomeClassProtocol.Type to $AnyObject - %z = tuple (%x : $AnyObject, %y : $AnyObject) - return %z : $(AnyObject, AnyObject) -} - // CHECK-LABEL: sil public_external [fragile] @bitcasts : $@convention(thin) (@owned Class1) -> @owned (Class2, Int) { // CHECK: bb0(%0 : $Class1): // CHECK-NEXT: %1 = unchecked_ref_cast %0 : $Class1 to $Class2 @@ -997,17 +960,7 @@ entry(%0 : $Class1): return %3 : $(Class2, Int) } -@objc protocol ObjCProto {} - -// CHECK-LABEL: sil public_external [fragile] @protocol_conversion -sil [fragile] @protocol_conversion : $@convention(thin) () -> @owned Protocol { -entry: - // CHECK: {{%.*}} = objc_protocol #ObjCProto : $Protocol - %p = objc_protocol #ObjCProto : $Protocol - return %p : $Protocol -} - -sil [fragile] @block_invoke : $@convention(c) (@inout @block_storage Int) -> () +sil [fragile] @block_invoke : $@convention(c) (@inout_aliasable @block_storage Int) -> () // Test try_apply and throws @@ -1062,9 +1015,9 @@ sil [fragile] @partial_apply : $@convention(thin) (@convention(thin) (@out Int, entry(%f : $@convention(thin) (@out Int, Int) -> (), %x : $Int): %p = partial_apply %f(%x) : $@convention(thin) (@out Int, Int) -> () %i = alloc_stack $Int - %z = apply %p(%i#1) : $@callee_owned (@out Int) -> () - %y = load %i#1 : $*Int - dealloc_stack %i#0 : $*@local_storage Int + %z = apply %p(%i) : $@callee_owned (@out Int) -> () + %y = load %i : $*Int + dealloc_stack %i : $*Int return %y : $Int } @@ -1184,17 +1137,17 @@ bb0(%0 : $Int, %1 : $Int, %2 : $Foo): %3 = tuple () %4 = alloc_stack $Int // var x // users: %17, %6 %5 = alloc_stack $Int // var y // users: %16, %7 - store %0 to %4#1 : $*Int - store %1 to %5#1 : $*Int + store %0 to %4 : $*Int + store %1 to %5 : $*Int %8 = alloc_stack $Foo // var self // users: %15, %14, %9 - store %2 to %8#1 : $*Foo + store %2 to %8 : $*Foo %10 = metatype $@thin Int.Type %12 = integer_literal $Builtin.Int32, 0 // user: %13 %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %18 - destroy_addr %8#1 : $*Foo - dealloc_stack %8#0 : $*@local_storage Foo - dealloc_stack %5#0 : $*@local_storage Int - dealloc_stack %4#0 : $*@local_storage Int + destroy_addr %8 : $*Foo + dealloc_stack %8 : $*Foo + dealloc_stack %5 : $*Int + dealloc_stack %4 : $*Int return %13 : $Int32 } @@ -1203,18 +1156,18 @@ bb0(%0 : $Int, %1 : $Int, %2 : $Foo): sil [fragile] @_TFC3tmp3Foos9subscriptFT1xSi1ySi_Si : $@convention(method) (Int32, Int, Int, @guaranteed Foo) -> () { bb0(%0 : $Int32, %1 : $Int, %2 : $Int, %3 : $Foo): %4 = alloc_stack $Int32 // var value // users: %16, %5 - store %0 to %4#1 : $*Int32 + store %0 to %4 : $*Int32 %6 = alloc_stack $Int // var x // users: %15, %8 %7 = alloc_stack $Int // var y // users: %14, %9 - store %1 to %6#1 : $*Int - store %2 to %7#1 : $*Int + store %1 to %6 : $*Int + store %2 to %7 : $*Int %10 = alloc_stack $Foo // var self // users: %13, %12, %11 - store %3 to %10#1 : $*Foo - destroy_addr %10#1 : $*Foo - dealloc_stack %10#0 : $*@local_storage Foo - dealloc_stack %7#0 : $*@local_storage Int - dealloc_stack %6#0 : $*@local_storage Int - dealloc_stack %4#0 : $*@local_storage Int32 + store %3 to %10 : $*Foo + destroy_addr %10 : $*Foo + dealloc_stack %10 : $*Foo + dealloc_stack %7 : $*Int + dealloc_stack %6 : $*Int + dealloc_stack %4 : $*Int32 %17 = tuple () // user: %18 return %17 : $() } @@ -1311,7 +1264,6 @@ bb0: %13 = function_ref @return_constant : $@convention(thin) () -> Int %23 = function_ref @existentials : $@convention(thin) (@in P) -> () %25 = function_ref @classes : $@convention(thin) () -> () - %26 = function_ref @objc_classes : $@convention(thin) (@thick NSObject.Type) -> () %27 = function_ref @_TF4todo18erasure_from_protoFT1xPS_8RuncibleS_8Bendable__PS0__ : $@convention(thin) (@out Runcible, @in protocol) -> () %29 = function_ref @_TF4todo18class_bound_methodFT1xPS_10ClassBound__T_ : $@convention(thin) (@owned ClassBound) -> () %31 = function_ref @_TFV6struct5AlephCfMS0_FT1aCS_3Ref1bVS_3Val_S0_ : $@convention(thin) (Ref, Val, @thin Aleph.Type) -> Aleph @@ -1337,8 +1289,6 @@ bb0: %73 = function_ref @test_basic_block_arguments : $@convention(thin) (Builtin.Int1) -> Builtin.Word %75 = function_ref @test_cond_branch_basic_block_args : $@convention(thin) (Int, Builtin.Int1) -> Int - %77 = function_ref @test_autorelease_return : $@convention(objc_method) (Bas) -> NSString - %79 = function_ref @test_super_method : $@convention(method) (@guaranteed Bas) -> Bas %81 = function_ref @test_builtin_func_ref : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 %83 = function_ref @test_dealloc_ref : $@convention(thin) () -> () %84 = function_ref @test_dealloc_partial_ref : $@convention(thin) () -> () @@ -1364,9 +1314,7 @@ bb0: %118 = function_ref @cond_fail_test : $@convention(thin) Builtin.Int1 -> () %124 = function_ref @block_storage_type : $@convention(thin) Int -> @convention(block) () -> () - %125 = function_ref @metatype_to_object : $@convention(thin) (@objc_metatype SomeClass.Type, @objc_metatype SomeClassProtocol.Type) -> @owned (AnyObject, AnyObject) %127 = function_ref @bitcasts : $@convention(thin) (@owned Class1) -> @owned (Class2, Int) - %126 = function_ref @protocol_conversion : $@convention(thin) () -> @owned Protocol %133 = function_ref @test_try_apply : $@convention(thin) (@convention(thin) () -> @error ErrorType) -> @error ErrorType %135 = function_ref @test_try_nothrow : $@convention(thin) (@convention(thin) () -> @error ErrorType) -> () %134 = function_ref @box_type : $@convention(thin) (@box Int, Int) -> () diff --git a/test/Serialization/Inputs/def_basic_objc.sil b/test/Serialization/Inputs/def_basic_objc.sil new file mode 100644 index 0000000000000..7f20e7d613dc3 --- /dev/null +++ b/test/Serialization/Inputs/def_basic_objc.sil @@ -0,0 +1,70 @@ +sil_stage raw // CHECK: sil_stage raw + +import Builtin +import Swift +import Foundation + +protocol SomeProtocol { } +class SomeClass : SomeProtocol { } + +// CHECK-LABEL: @objc_classes : $@convention(thin) (@thick NSObject.Type) -> () +sil [fragile] @objc_classes : $@convention(thin) (@thick NSObject.Type) -> () { +bb0(%0 : $@thick NSObject.Type): + %1 = thick_to_objc_metatype %0 : $@thick NSObject.Type to $@objc_metatype NSObject.Type + // CHECK: %2 = alloc_ref_dynamic [objc] %1 : $@objc_metatype NSObject.Type, $NSObject + %2 = alloc_ref_dynamic [objc] %1 : $@objc_metatype NSObject.Type, $NSObject + %3 = value_metatype $@thick NSObject.Type, %2 : $NSObject + dealloc_partial_ref %2 : $NSObject, %3 : $@thick NSObject.Type + + %void = tuple () + return %void : $() +} // CHECK: {{^}$}} + +class Bas : NSObject { + var strRealProp : String + override init() +} + +sil [fragile] @test_super_method : $@convention(method) (@guaranteed Bas) -> Bas +sil [fragile] @swift_StringToNSString : $@convention(thin) (@inout String) -> @owned NSString +sil [fragile] @_TFSSCfMSSFT_SS : $@convention(thin) (@thin String.Type) -> @owned String + +protocol SomeClassProtocol : class {} + +// CHECK-LABEL: sil public_external [fragile] @metatype_to_object +// CHECK: {{%.*}} = objc_metatype_to_object {{%.*}} : $@objc_metatype SomeClass.Type to $AnyObject +// CHECK: {{%.*}} = objc_existential_metatype_to_object {{%.*}} : $@objc_metatype SomeClassProtocol.Type to $AnyObject +sil [fragile] @metatype_to_object : $@convention(thin) (@objc_metatype SomeClass.Type, @objc_metatype SomeClassProtocol.Type) -> @owned (AnyObject, AnyObject) { +entry(%a : $@objc_metatype SomeClass.Type, %b : $@objc_metatype SomeClassProtocol.Type): + %x = objc_metatype_to_object %a : $@objc_metatype SomeClass.Type to $AnyObject + %y = objc_existential_metatype_to_object %b : $@objc_metatype SomeClassProtocol.Type to $AnyObject + %z = tuple (%x : $AnyObject, %y : $AnyObject) + return %z : $(AnyObject, AnyObject) +} + +@objc protocol ObjCProto {} + +// CHECK-LABEL: sil public_external [fragile] @protocol_conversion +sil [fragile] @protocol_conversion : $@convention(thin) () -> @owned Protocol { +entry: + // CHECK: {{%.*}} = objc_protocol #ObjCProto : $Protocol + %p = objc_protocol #ObjCProto : $Protocol + return %p : $Protocol +} + +public func serialize_all() { +} + +sil [fragile] [transparent] @_TF14def_basic_objc13serialize_allFT_T_ : $@convention(thin) () -> () { +bb0: + %26 = function_ref @objc_classes : $@convention(thin) (@thick NSObject.Type) -> () + + %79 = function_ref @test_super_method : $@convention(method) (@guaranteed Bas) -> Bas + + %125 = function_ref @metatype_to_object : $@convention(thin) (@objc_metatype SomeClass.Type, @objc_metatype SomeClassProtocol.Type) -> @owned (AnyObject, AnyObject) + + %126 = function_ref @protocol_conversion : $@convention(thin) () -> @owned Protocol + + %119 = tuple () + return %119 : $() +} diff --git a/test/Serialization/Inputs/def_func.swift b/test/Serialization/Inputs/def_func.swift index 829f3af48a679..fa031f7d50383 100644 --- a/test/Serialization/Inputs/def_func.swift +++ b/test/Serialization/Inputs/def_func.swift @@ -51,7 +51,7 @@ public func differentWrapped< return a.getValue() != b.getValue() } -@noreturn @_silgen_name("exit") public func exit ()->() +@noreturn @_silgen_name("exit") public func exit () -> () @noreturn public func testNoReturnAttr() -> () { exit() } @noreturn public func testNoReturnAttrPoly(x x: T) -> () { exit() } diff --git a/test/Serialization/Inputs/def_transparent.swift b/test/Serialization/Inputs/def_transparent.swift index 718f52d14857a..bac59a9508b69 100644 --- a/test/Serialization/Inputs/def_transparent.swift +++ b/test/Serialization/Inputs/def_transparent.swift @@ -3,7 +3,7 @@ } @_transparent public func testBuiltin() -> Int32 { - var y: Int32 = 300; + var y: Int32 = 300 var z = "foo" return y } diff --git a/test/Serialization/basic_sil.swift b/test/Serialization/basic_sil.swift index 731f5ab794dae..3d10937e98a52 100644 --- a/test/Serialization/basic_sil.swift +++ b/test/Serialization/basic_sil.swift @@ -1,15 +1,13 @@ // RUN: rm -rf %t // RUN: mkdir %t -// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -I %S/../Inputs/clang-importer-sdk/swift-modules -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-all -force-single-frontend-invocation -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil +// RUN: %target-build-swift -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-all -force-single-frontend-invocation -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil // RUN: llvm-bcanalyzer %t/def_basic.swiftmodule | FileCheck %s -// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -emit-silgen -Xfrontend -sil-link-all -I %t %s | FileCheck %S/Inputs/def_basic.sil +// RUN: %target-build-swift -emit-silgen -Xfrontend -sil-link-all -I %t %s | FileCheck %S/Inputs/def_basic.sil // RUN: rm -rf %t // RUN: mkdir %t -// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -emit-module -Xfrontend -disable-diagnostic-passes -force-single-frontend-invocation -Xfrontend -sil-serialize-all -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil -// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -emit-silgen -Xfrontend -sil-link-all -I %t %s | FileCheck -check-prefix=CHECK_DECL %S/Inputs/def_basic.sil - -// XFAIL: linux +// RUN: %target-build-swift -emit-module -Xfrontend -disable-diagnostic-passes -force-single-frontend-invocation -Xfrontend -sil-serialize-all -o %t/def_basic.swiftmodule %S/Inputs/def_basic.sil +// RUN: %target-build-swift -emit-silgen -Xfrontend -sil-link-all -I %t %s | FileCheck -check-prefix=CHECK_DECL %S/Inputs/def_basic.sil // This test currently is written such that no optimizations are assumed. // REQUIRES: swift_test_mode_optimize_none diff --git a/test/Serialization/basic_sil_objc.swift b/test/Serialization/basic_sil_objc.swift new file mode 100644 index 0000000000000..998f110b39ee9 --- /dev/null +++ b/test/Serialization/basic_sil_objc.swift @@ -0,0 +1,17 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -I %S/../Inputs/clang-importer-sdk/swift-modules -emit-module -Xfrontend -disable-diagnostic-passes -Xfrontend -sil-serialize-all -force-single-frontend-invocation -o %t/def_basic_objc.swiftmodule %S/Inputs/def_basic_objc.sil +// RUN: llvm-bcanalyzer %t/def_basic_objc.swiftmodule | FileCheck %s +// RUN: %target-build-swift -Xfrontend %clang-importer-sdk -emit-silgen -Xfrontend -sil-link-all -I %t %s | FileCheck %S/Inputs/def_basic_objc.sil + +// This test currently is written such that no optimizations are assumed. +// REQUIRES: swift_test_mode_optimize_none +// REQUIRES: objc_interop + +// CHECK-NOT: UnknownCode + +import def_basic_objc + +func test_all() { + serialize_all() +} diff --git a/test/Serialization/sil-serialize-all-with-cross-module-conformance.swift b/test/Serialization/sil-serialize-all-with-cross-module-conformance.swift new file mode 100644 index 0000000000000..46a3054d7d8cc --- /dev/null +++ b/test/Serialization/sil-serialize-all-with-cross-module-conformance.swift @@ -0,0 +1,44 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: %target-swift-frontend -emit-module -parse-as-library -module-name ProtoModule -o %t/ProtoModule.swiftmodule %s -DPROTO +// RUN: %target-swift-frontend -emit-module -parse-as-library -module-name ModelModule -o %t/ModelModule.swiftmodule %s -DMODEL -I %t -sil-serialize-all +// RUN: %target-swift-frontend -emit-sil -O -sil-verify-all -o /dev/null %s -DUSE -I %t + +#if PROTO + +public protocol Proto { + func method(_: T?) +} + +extension Proto { + public func method(_: T?) {} +} + +#elseif MODEL + +import ProtoModule + +public struct Model : Proto { + public init() {} +} + + +#elseif USE + +import ProtoModule +import ModelModule + +struct OtherStruct {} + +func test(x: T) { + x.method(OtherStruct()) +} + +func main() { + test(Model()) +} + +#else + +let _ = invalid_configuration() + +#endif diff --git a/test/SourceKit/CodeComplete/Inputs/popular.h b/test/SourceKit/CodeComplete/Inputs/popular.h index 8ab1004b2ee8c..1dbe62f6a2168 100644 --- a/test/SourceKit/CodeComplete/Inputs/popular.h +++ b/test/SourceKit/CodeComplete/Inputs/popular.h @@ -7,7 +7,7 @@ @end @interface DDModuleColor @end -@interface ModuleColaborate +@interface ModuleCollaborate @end @interface BY_NAME_BAD1 diff --git a/test/SourceKit/CodeComplete/complete_crash1.swift b/test/SourceKit/CodeComplete/complete_crash1.swift new file mode 100644 index 0000000000000..757dd8c7dade7 --- /dev/null +++ b/test/SourceKit/CodeComplete/complete_crash1.swift @@ -0,0 +1,8 @@ +// RUN: %complete-test -tok=TOK1 -hide-none %s -- %s + +import QuartzCore + +class Cl{ + var L : CALayer = { + let layer = CALayer() + layer.transform = #^TOK1^# diff --git a/test/SourceKit/CodeComplete/complete_group_overloads.swift b/test/SourceKit/CodeComplete/complete_group_overloads.swift index c10bd8ac9c6a1..f963258069874 100644 --- a/test/SourceKit/CodeComplete/complete_group_overloads.swift +++ b/test/SourceKit/CodeComplete/complete_group_overloads.swift @@ -5,7 +5,7 @@ func aaa() {} func aaa(x: A) {} func aaa(x: B) {} func aaa(x: B, y: B) {} -func aaa(#x: B, y: B) {} +func aaa(x x: B, y: B) {} func aab() {} func test001() { @@ -25,7 +25,7 @@ struct Foo { func aaa(x: A) {} func aaa(x: B) {} func aaa(x: B, y: B) {} - func aaa(#x: B, y: B) {} + func aaa(x x: B, y: B) {} func aab() {} } diff --git a/test/SourceKit/CodeComplete/complete_popular_api.swift b/test/SourceKit/CodeComplete/complete_popular_api.swift index 5228bdad1f0dd..657178d5f362f 100644 --- a/test/SourceKit/CodeComplete/complete_popular_api.swift +++ b/test/SourceKit/CodeComplete/complete_popular_api.swift @@ -83,9 +83,9 @@ struct OuterNominal { // POPULAR_STMT_0: CCModuleColor // POPULAR_STMT_0: EEModuleColor // bad() ends up here because it's an unpopular global but that's still better -// than a random "other module" result like ModuleColaborate. +// than a random "other module" result like ModuleCollaborate. // POPULAR_STMT_0: bad() -// POPULAR_STMT_0: ModuleColaborate +// POPULAR_STMT_0: ModuleCollaborate // POPULAR_STMT_0: ] // POPULAR_STMT_0-LABEL: Results for filterText: col [ // POPULAR_STMT_0: argColor @@ -97,7 +97,7 @@ struct OuterNominal { // POPULAR_STMT_0: DDModuleColor // POPULAR_STMT_0: CCModuleColor // POPULAR_STMT_0: EEModuleColor -// POPULAR_STMT_0: ModuleColaborate +// POPULAR_STMT_0: ModuleCollaborate // POPULAR_STMT_0: BBModuleColor // POPULAR_STMT_0: AAModuleColor // POPULAR_STMT_0: ] diff --git a/test/SourceKit/CodeComplete/complete_sort_order.swift b/test/SourceKit/CodeComplete/complete_sort_order.swift index 86e6b7a9253e3..d13b71204978c 100644 --- a/test/SourceKit/CodeComplete/complete_sort_order.swift +++ b/test/SourceKit/CodeComplete/complete_sort_order.swift @@ -26,7 +26,7 @@ func test() { // RUN: %sourcekitd-test -req=complete.open -pos=7:1 -req-opts=sort.byname=1,hidelowpriority=0,hideunderscores=0 %s -- %s > %t.off // RUN: FileCheck -check-prefix=CONTEXT %s < %t.default // RUN: FileCheck -check-prefix=NAME %s < %t.off -// FIXME: rdar://problem/20109989 non-determinisitic sort order +// FIXME: rdar://problem/20109989 non-deterministic sort order // RUN-disabled: diff %t.on %t.default // RUN: FileCheck -check-prefix=CONTEXT %s < %t.on diff --git a/test/SourceKit/CodeComplete/complete_structure.swift b/test/SourceKit/CodeComplete/complete_structure.swift index a7f64987aa0fc..3f7cca0b508bb 100644 --- a/test/SourceKit/CodeComplete/complete_structure.swift +++ b/test/SourceKit/CodeComplete/complete_structure.swift @@ -15,7 +15,7 @@ struct S1 { func method4(_: Int, _: Int) {} func method5(inout _: Int, inout b: Int) {} func method6(c: Int) throws {} - func method7(callback: ()->() throws) rethrows {} + func method7(callback: () -> () throws) rethrows {} func method8(d: (T, U) -> T, e: T -> U) {} let v1: Int = 1 @@ -68,7 +68,7 @@ func test5() { // S1_INIT: ({params:{n:a:}{t: Int}, {n:b:}{t: Int}}) // S1_INIT: ({params:{n:c:}{t: Int}}) -func test6(xyz: S1, fgh: (S1)->S1) { +func test6(xyz: S1, fgh: (S1) -> S1) { #^STMT_0^# } // STMT_0: {name:func} @@ -92,8 +92,8 @@ func test7(x: E1) { // ENUM_0: {name:C3}({params:{n:l1:}{t: S1}, {n:l2:}{t: S1}}) class C1 { - func foo(x: S1, y: S1, z: (S1)->S1) -> S1 {} - func zap(x: T, y: U, z: (T)->U) -> T {} + func foo(x: S1, y: S1, z: (S1) -> S1) -> S1 {} + func zap(x: T, y: U, z: (T) -> U) -> T {} } class C2 : C1 { diff --git a/test/SourceKit/CodeComplete/complete_with_closure_param.swift b/test/SourceKit/CodeComplete/complete_with_closure_param.swift index f686c217945b2..1886871716aca 100644 --- a/test/SourceKit/CodeComplete/complete_with_closure_param.swift +++ b/test/SourceKit/CodeComplete/complete_with_closure_param.swift @@ -1,6 +1,6 @@ -typealias MyFnTy = Int->Int +typealias MyFnTy = Int ->Int class C { - func foo(x: Int->Int) {} + func foo(x: Int ->Int) {} func foo2(x: MyFnTy) {} } diff --git a/test/SourceKit/CodeExpand/code-expand.swift b/test/SourceKit/CodeExpand/code-expand.swift index 5c4068d024b12..0353c7c60e230 100644 --- a/test/SourceKit/CodeExpand/code-expand.swift +++ b/test/SourceKit/CodeExpand/code-expand.swift @@ -1,11 +1,11 @@ // RUN: %sourcekitd-test -req=expand-placeholder %s | FileCheck %s -foo(x: <#T##()->Void#>) +foo(x: <#T##() -> Void#>) // CHECK: foo { // CHECK-NEXT: <#code#> // CHECK-NEXT: } -foo(x: <#T##()->Void#>, y: <#T##Int#>) +foo(x: <#T##() -> Void#>, y: <#T##Int#>) // CHECK: foo(x: { // CHECK-NEXT: <#code#> // CHECK-NEXT: }, y: Int) @@ -49,3 +49,8 @@ func f() { store.requestAccessToEntityType(<#T##entityType: EKEntityType##EKEntityType#>, completion: nil) } // CHECK: store.requestAccessToEntityType(EKEntityType, completion: nil) + +func f1() { + bar(<#T##d: () -> ()##() -> ()#>) +} +// CHECK-NOT: bar { () -> () in diff --git a/test/SourceKit/CodeFormat/indent-closure.swift b/test/SourceKit/CodeFormat/indent-closure.swift index e568eeb5a8e98..722cb11afbed8 100644 --- a/test/SourceKit/CodeFormat/indent-closure.swift +++ b/test/SourceKit/CodeFormat/indent-closure.swift @@ -14,8 +14,8 @@ class C { }() } -func foo1(a: Int, handler : ()->()) {} -func foo2(handler : () ->()) {} +func foo1(a: Int, handler : () -> ()) {} +func foo2(handler : () -> ()) {} func foo3() { foo1(1) diff --git a/test/SourceKit/CodeFormat/indent-sibling.swift b/test/SourceKit/CodeFormat/indent-sibling.swift index 06efc2b8dc43f..4407b9fa50a4a 100644 --- a/test/SourceKit/CodeFormat/indent-sibling.swift +++ b/test/SourceKit/CodeFormat/indent-sibling.swift @@ -1,3 +1,5 @@ +// XFAIL: * + class Foo { func foo(Value1 : Int, Value2 : Int) { diff --git a/test/SourceKit/DocSupport/Inputs/main.swift b/test/SourceKit/DocSupport/Inputs/main.swift index 8f8ff0648771e..37d68bfd28159 100644 --- a/test/SourceKit/DocSupport/Inputs/main.swift +++ b/test/SourceKit/DocSupport/Inputs/main.swift @@ -96,10 +96,10 @@ func test1(cp: ComputedProperty, sub: CC2) { var x = cp.value x = cp.readOnly cp.value = x - ++cp.value + cp.value += 1 x = sub[0] sub[0] = x - ++sub[0] + sub[0] += 1 } struct S2 { diff --git a/test/SourceKit/DocSupport/doc_source_file.swift.response b/test/SourceKit/DocSupport/doc_source_file.swift.response index f7a99989d1673..e37f243c2256f 100644 --- a/test/SourceKit/DocSupport/doc_source_file.swift.response +++ b/test/SourceKit/DocSupport/doc_source_file.swift.response @@ -1152,621 +1152,631 @@ key.offset: 1306, key.length: 1 }, - { - key.kind: source.lang.swift.ref.function.operator.prefix, - key.name: "++(_:)", - key.usr: "s:ZFsop2ppFRSiSi", - key.offset: 1310, - key.length: 2 - }, { key.kind: source.lang.swift.ref.var.local, key.name: "cp", - key.offset: 1312, + key.offset: 1310, key.length: 2 }, { key.kind: source.lang.swift.ref.var.instance, key.name: "value", key.usr: "s:vC8__main__16ComputedProperty5valueSi", - key.offset: 1315, + key.offset: 1313, key.length: 5 }, + { + key.kind: source.lang.swift.ref.function.operator.infix, + key.name: "+=(_:_:)", + key.usr: "s:ZFsoi2peFTRSiSi_T_", + key.offset: 1319, + key.length: 2 + }, + { + key.kind: source.lang.swift.syntaxtype.number, + key.offset: 1322, + key.length: 1 + }, { key.kind: source.lang.swift.ref.var.local, key.name: "x", - key.offset: 1323, + key.offset: 1326, key.length: 1 }, { key.kind: source.lang.swift.ref.var.local, key.name: "sub", - key.offset: 1327, + key.offset: 1330, key.length: 3 }, { key.kind: source.lang.swift.ref.function.subscript, key.name: "subscript(_:)", key.usr: "s:iC8__main__3CC29subscriptFSiSi", - key.offset: 1330, + key.offset: 1333, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.number, - key.offset: 1331, + key.offset: 1334, key.length: 1 }, { key.kind: source.lang.swift.ref.function.subscript, key.name: "subscript(_:)", key.usr: "s:iC8__main__3CC29subscriptFSiSi", - key.offset: 1332, + key.offset: 1335, key.length: 1 }, { key.kind: source.lang.swift.ref.var.local, key.name: "sub", - key.offset: 1336, + key.offset: 1339, key.length: 3 }, { key.kind: source.lang.swift.ref.function.subscript, key.name: "subscript(_:)", key.usr: "s:iC8__main__3CC29subscriptFSiSi", - key.offset: 1339, + key.offset: 1342, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.number, - key.offset: 1340, + key.offset: 1343, key.length: 1 }, { key.kind: source.lang.swift.ref.function.subscript, key.name: "subscript(_:)", key.usr: "s:iC8__main__3CC29subscriptFSiSi", - key.offset: 1341, + key.offset: 1344, key.length: 1 }, { key.kind: source.lang.swift.ref.var.local, key.name: "x", - key.offset: 1345, + key.offset: 1348, key.length: 1 }, - { - key.kind: source.lang.swift.ref.function.operator.prefix, - key.name: "++(_:)", - key.usr: "s:ZFsop2ppFRSiSi", - key.offset: 1349, - key.length: 2 - }, { key.kind: source.lang.swift.ref.var.local, key.name: "sub", - key.offset: 1351, + key.offset: 1352, key.length: 3 }, { key.kind: source.lang.swift.ref.function.subscript, key.name: "subscript(_:)", key.usr: "s:iC8__main__3CC29subscriptFSiSi", - key.offset: 1354, + key.offset: 1355, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.number, - key.offset: 1355, + key.offset: 1356, key.length: 1 }, { key.kind: source.lang.swift.ref.function.subscript, key.name: "subscript(_:)", key.usr: "s:iC8__main__3CC29subscriptFSiSi", - key.offset: 1356, + key.offset: 1357, + key.length: 1 + }, + { + key.kind: source.lang.swift.ref.function.operator.infix, + key.name: "+=(_:_:)", + key.usr: "s:ZFsoi2peFTRSiSi_T_", + key.offset: 1359, + key.length: 2 + }, + { + key.kind: source.lang.swift.syntaxtype.number, + key.offset: 1362, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1361, + key.offset: 1367, key.length: 6 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1368, + key.offset: 1374, key.length: 2 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1375, + key.offset: 1381, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1380, + key.offset: 1386, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1393, + key.offset: 1399, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1397, + key.offset: 1403, key.length: 12 }, { key.kind: source.lang.swift.ref.struct, key.name: "S2", key.usr: "s:V8__main__2S2", - key.offset: 1412, + key.offset: 1418, key.length: 2 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1419, + key.offset: 1425, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1429, + key.offset: 1435, key.length: 6 }, { key.kind: source.lang.swift.ref.function.constructor, key.name: "init()", key.usr: "s:FV8__main__2S2cFT_S0_", - key.offset: 1436, + key.offset: 1442, key.length: 2 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1449, + key.offset: 1455, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1454, + key.offset: 1460, key.length: 5 }, { key.kind: source.lang.swift.ref.var.global, key.name: "globReadOnly", key.usr: "s:v8__main__12globReadOnlyVS_2S2", - key.offset: 1466, + key.offset: 1472, key.length: 12 }, { key.kind: source.lang.swift.ref.function.method.instance, key.name: "sfoo()", key.usr: "s:FV8__main__2S24sfooFT_T_", - key.offset: 1479, + key.offset: 1485, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1489, + key.offset: 1495, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1495, + key.offset: 1501, key.length: 2 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1502, + key.offset: 1508, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1507, + key.offset: 1513, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1519, + key.offset: 1525, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1525, + key.offset: 1531, key.length: 3 }, { key.kind: source.lang.swift.ref.class, key.name: "B1", key.usr: "s:C8__main__2B1", - key.offset: 1531, + key.offset: 1537, key.length: 2 }, { key.kind: source.lang.swift.syntaxtype.attribute.builtin, - key.offset: 1538, + key.offset: 1544, key.length: 8 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1547, + key.offset: 1553, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1552, + key.offset: 1558, key.length: 3 }, { key.kind: source.lang.swift.ref.function.method.instance, key.name: "foo()", key.usr: "s:FC8__main__3SB13fooFT_T_", - key.offset: 1564, + key.offset: 1570, key.length: 3 }, { key.kind: source.lang.swift.ref.var.local, key.name: "self", - key.offset: 1574, + key.offset: 1580, key.length: 4 }, { key.kind: source.lang.swift.ref.function.method.instance, key.name: "foo()", key.usr: "s:FC8__main__3SB13fooFT_T_", - key.offset: 1579, + key.offset: 1585, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1589, + key.offset: 1595, key.length: 5 }, { key.kind: source.lang.swift.ref.function.method.instance, key.name: "foo()", key.usr: "s:FC8__main__2B13fooFT_T_", - key.offset: 1595, + key.offset: 1601, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1608, + key.offset: 1614, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1613, + key.offset: 1619, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.parameter, - key.offset: 1619, + key.offset: 1625, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1619, + key.offset: 1625, key.length: 1 }, { key.kind: source.lang.swift.ref.class, key.name: "SB1", key.usr: "s:C8__main__3SB1", - key.offset: 1622, + key.offset: 1628, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.parameter, - key.offset: 1627, + key.offset: 1633, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1627, + key.offset: 1633, key.length: 1 }, { key.kind: source.lang.swift.ref.struct, key.name: "S2", key.usr: "s:V8__main__2S2", - key.offset: 1630, + key.offset: 1636, key.length: 2 }, { key.kind: source.lang.swift.ref.function.free, key.name: "test2()", key.usr: "s:F8__main__5test2FT_T_", - key.offset: 1638, + key.offset: 1644, key.length: 5 }, { key.kind: source.lang.swift.ref.var.local, key.name: "c", - key.offset: 1648, + key.offset: 1654, key.length: 1 }, { key.kind: source.lang.swift.ref.function.method.instance, key.name: "foo()", key.usr: "s:FC8__main__3SB13fooFT_T_", - key.offset: 1650, + key.offset: 1656, key.length: 3 }, { key.kind: source.lang.swift.ref.var.local, key.name: "s", - key.offset: 1658, + key.offset: 1664, key.length: 1 }, { key.kind: source.lang.swift.ref.function.method.instance, key.name: "sfoo()", key.usr: "s:FV8__main__2S24sfooFT_T_", - key.offset: 1660, + key.offset: 1666, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1670, + key.offset: 1676, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1675, + key.offset: 1681, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1681, + key.offset: 1687, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.parameter, - key.offset: 1687, + key.offset: 1693, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1687, + key.offset: 1693, key.length: 1 }, { key.kind: source.lang.swift.ref.struct, key.name: "Int", key.usr: "s:Si", - key.offset: 1690, + key.offset: 1696, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1699, + key.offset: 1705, key.length: 8 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1708, + key.offset: 1714, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1718, + key.offset: 1724, key.length: 9 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1728, + key.offset: 1734, key.length: 7 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1738, + key.offset: 1744, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1742, + key.offset: 1748, key.length: 1 }, { key.kind: source.lang.swift.ref.struct, key.name: "Int", key.usr: "s:Si", - key.offset: 1746, + key.offset: 1752, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1752, + key.offset: 1758, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1760, + key.offset: 1766, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1765, + key.offset: 1771, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1774, + key.offset: 1780, key.length: 6 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1781, + key.offset: 1787, key.length: 2 }, { key.kind: source.lang.swift.ref.protocol, key.name: "Prot2", key.usr: "s:P8__main__5Prot2", - key.offset: 1786, + key.offset: 1792, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1796, + key.offset: 1802, key.length: 9 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1806, + key.offset: 1812, key.length: 7 }, { key.kind: source.lang.swift.ref.struct, key.name: "Int", key.usr: "s:Si", - key.offset: 1816, + key.offset: 1822, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1822, + key.offset: 1828, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1826, + key.offset: 1832, key.length: 1 }, { key.kind: source.lang.swift.ref.struct, key.name: "Int", key.usr: "s:Si", - key.offset: 1830, + key.offset: 1836, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.number, - key.offset: 1836, + key.offset: 1842, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1840, + key.offset: 1846, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1845, + key.offset: 1851, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1857, + key.offset: 1863, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1862, + key.offset: 1868, key.length: 6 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1869, + key.offset: 1875, key.length: 1 }, { key.kind: source.lang.swift.ref.protocol, key.name: "Prot2", key.usr: "s:P8__main__5Prot2", - key.offset: 1873, + key.offset: 1879, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1879, + key.offset: 1885, key.length: 5 }, { key.kind: source.lang.swift.ref.generic_type_param, key.name: "T", key.usr: "s:tF8__main__6genfoouRxS_5Prot2wx7ElementzSirFxT_L_1TMx", - key.offset: 1885, + key.offset: 1891, key.length: 1 }, { key.kind: source.lang.swift.ref.typealias, key.name: "Element", key.usr: "s:P8__main__5Prot27Element", - key.offset: 1887, + key.offset: 1893, key.length: 7 }, { key.kind: source.lang.swift.ref.struct, key.name: "Int", key.usr: "s:Si", - key.offset: 1898, + key.offset: 1904, key.length: 3 }, { key.kind: source.lang.swift.syntaxtype.parameter, - key.offset: 1903, + key.offset: 1909, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1903, + key.offset: 1909, key.length: 1 }, { key.kind: source.lang.swift.ref.generic_type_param, key.name: "T", key.usr: "s:tF8__main__6genfoouRxS_5Prot2wx7ElementzSirFxT_L_1TMx", - key.offset: 1906, + key.offset: 1912, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1913, + key.offset: 1919, key.length: 8 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1922, + key.offset: 1928, key.length: 5 }, { key.kind: source.lang.swift.syntaxtype.keyword, - key.offset: 1932, + key.offset: 1938, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.parameter, - key.offset: 1939, + key.offset: 1945, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1939, + key.offset: 1945, key.length: 1 }, { key.kind: source.lang.swift.ref.generic_type_param, key.name: "Self", key.usr: "s:tP8__main__5Prot34SelfMx", - key.offset: 1942, + key.offset: 1948, key.length: 4 }, { key.kind: source.lang.swift.syntaxtype.parameter, - key.offset: 1948, + key.offset: 1954, key.length: 1 }, { key.kind: source.lang.swift.syntaxtype.identifier, - key.offset: 1948, + key.offset: 1954, key.length: 1 }, { key.kind: source.lang.swift.ref.generic_type_param, key.name: "Self", key.usr: "s:tP8__main__5Prot34SelfMx", - key.offset: 1951, + key.offset: 1957, key.length: 4 } ] @@ -2261,7 +2271,7 @@ key.name: "test1(_:sub:)", key.usr: "s:F8__main__5test1FTCS_16ComputedProperty3subCS_3CC2_T_", key.offset: 1211, - key.length: 147, + key.length: 153, key.entities: [ { key.kind: source.lang.swift.decl.var.local, @@ -2283,14 +2293,14 @@ key.kind: source.lang.swift.decl.struct, key.name: "S2", key.usr: "s:V8__main__2S2", - key.offset: 1361, + key.offset: 1367, key.length: 29, key.entities: [ { key.kind: source.lang.swift.decl.function.method.instance, key.name: "sfoo()", key.usr: "s:FV8__main__2S24sfooFT_T_", - key.offset: 1375, + key.offset: 1381, key.length: 13 } ] @@ -2303,28 +2313,28 @@ { key.kind: source.lang.swift.decl.function.accessor.getter, key.usr: "s:F8__main__g12globReadOnlyVS_2S2", - key.offset: 1419, + key.offset: 1425, key.length: 25 }, { key.kind: source.lang.swift.decl.function.free, key.name: "test2()", key.usr: "s:F8__main__5test2FT_T_", - key.offset: 1449, + key.offset: 1455, key.length: 37 }, { key.kind: source.lang.swift.decl.class, key.name: "B1", key.usr: "s:C8__main__2B1", - key.offset: 1489, + key.offset: 1495, key.length: 27, key.entities: [ { key.kind: source.lang.swift.decl.function.method.instance, key.name: "foo()", key.usr: "s:FC8__main__2B13fooFT_T_", - key.offset: 1502, + key.offset: 1508, key.length: 12 } ] @@ -2333,7 +2343,7 @@ key.kind: source.lang.swift.decl.class, key.name: "SB1", key.usr: "s:C8__main__3SB1", - key.offset: 1519, + key.offset: 1525, key.length: 86, key.inherits: [ { @@ -2347,7 +2357,7 @@ key.kind: source.lang.swift.decl.function.method.instance, key.name: "foo()", key.usr: "s:FC8__main__3SB13fooFT_T_", - key.offset: 1547, + key.offset: 1553, key.length: 56, key.inherits: [ { @@ -2363,21 +2373,21 @@ key.kind: source.lang.swift.decl.function.free, key.name: "test3(_:s:)", key.usr: "s:F8__main__5test3FTCS_3SB11sVS_2S2_T_", - key.offset: 1608, + key.offset: 1614, key.length: 59, key.entities: [ { key.kind: source.lang.swift.decl.var.local, key.keyword: "_", key.name: "c", - key.offset: 1622, + key.offset: 1628, key.length: 3 }, { key.kind: source.lang.swift.decl.var.local, key.keyword: "s", key.name: "s", - key.offset: 1630, + key.offset: 1636, key.length: 2 } ] @@ -2386,14 +2396,14 @@ key.kind: source.lang.swift.decl.function.free, key.name: "test4(_:)", key.usr: "s:F8__main__5test4FRSiT_", - key.offset: 1670, + key.offset: 1676, key.length: 26, key.entities: [ { key.kind: source.lang.swift.decl.var.local, key.keyword: "_", key.name: "a", - key.offset: 1690, + key.offset: 1696, key.length: 3 } ] @@ -2402,14 +2412,14 @@ key.kind: source.lang.swift.decl.protocol, key.name: "Prot2", key.usr: "s:P8__main__5Prot2", - key.offset: 1699, + key.offset: 1705, key.length: 72, key.entities: [ { key.kind: source.lang.swift.decl.typealias, key.name: "Element", key.usr: "s:P8__main__5Prot27Element", - key.offset: 1718, + key.offset: 1724, key.length: 10 }, { @@ -2425,7 +2435,7 @@ key.kind: source.lang.swift.decl.function.method.instance, key.name: "foo()", key.usr: "s:FP8__main__5Prot23fooFT_T_", - key.offset: 1760, + key.offset: 1766, key.length: 9 } ] @@ -2434,7 +2444,7 @@ key.kind: source.lang.swift.decl.struct, key.name: "S1", key.usr: "s:V8__main__2S1", - key.offset: 1774, + key.offset: 1780, key.length: 80, key.conforms: [ { @@ -2448,7 +2458,7 @@ key.kind: source.lang.swift.decl.typealias, key.name: "Element", key.usr: "s:V8__main__2S17Element", - key.offset: 1796, + key.offset: 1802, key.length: 20, key.conforms: [ { @@ -2474,7 +2484,7 @@ key.kind: source.lang.swift.decl.function.method.instance, key.name: "foo()", key.usr: "s:FV8__main__2S13fooFT_T_", - key.offset: 1840, + key.offset: 1846, key.length: 12, key.conforms: [ { @@ -2501,14 +2511,14 @@ key.description: "T.Element == Int" } ], - key.offset: 1857, + key.offset: 1863, key.length: 53, key.entities: [ { key.kind: source.lang.swift.decl.var.local, key.keyword: "_", key.name: "x", - key.offset: 1906, + key.offset: 1912, key.length: 1 } ] @@ -2517,28 +2527,28 @@ key.kind: source.lang.swift.decl.protocol, key.name: "Prot3", key.usr: "s:P8__main__5Prot3", - key.offset: 1913, + key.offset: 1919, key.length: 44, key.entities: [ { key.kind: source.lang.swift.decl.function.operator.infix, key.name: "+(_:_:)", key.usr: "s:ZFP8__main__5Prot3oi1pFTxx_T_", - key.offset: 1932, + key.offset: 1938, key.length: 23, key.entities: [ { key.kind: source.lang.swift.decl.var.local, key.keyword: "_", key.name: "x", - key.offset: 1942, + key.offset: 1948, key.length: 4 }, { key.kind: source.lang.swift.decl.var.local, key.keyword: "_", key.name: "y", - key.offset: 1951, + key.offset: 1957, key.length: 4 } ] diff --git a/test/SourceKit/DocumentStructure/structure.swift.response b/test/SourceKit/DocumentStructure/structure.swift.response index e7b49361b1d76..751c03241cdbf 100644 --- a/test/SourceKit/DocumentStructure/structure.swift.response +++ b/test/SourceKit/DocumentStructure/structure.swift.response @@ -256,7 +256,7 @@ key.kind: source.lang.swift.decl.var.parameter, key.name: "arg1", key.offset: 445, - key.length: 4, + key.length: 9, key.typename: "Int", key.nameoffset: 0, key.namelength: 0 @@ -265,7 +265,7 @@ key.kind: source.lang.swift.decl.var.parameter, key.name: "name", key.offset: 456, - key.length: 4, + key.length: 12, key.typename: "String", key.nameoffset: 456, key.namelength: 4 @@ -345,7 +345,7 @@ key.kind: source.lang.swift.decl.var.parameter, key.name: "arg1", key.offset: 576, - key.length: 4, + key.length: 9, key.typename: "Int", key.nameoffset: 0, key.namelength: 0 @@ -354,7 +354,7 @@ key.kind: source.lang.swift.decl.var.parameter, key.name: "par", key.offset: 587, - key.length: 9, + key.length: 14, key.typename: "Int", key.nameoffset: 587, key.namelength: 5 @@ -414,7 +414,7 @@ key.kind: source.lang.swift.decl.var.parameter, key.name: "arg1", key.offset: 693, - key.length: 4, + key.length: 10, key.typename: "Bool", key.nameoffset: 0, key.namelength: 0 @@ -479,7 +479,7 @@ key.kind: source.lang.swift.decl.var.parameter, key.name: "arg1", key.offset: 854, - key.length: 4, + key.length: 10, key.typename: "Bool", key.nameoffset: 0, key.namelength: 0 diff --git a/test/SourceKit/Indexing/index.swift b/test/SourceKit/Indexing/index.swift index 76d9dd53198f1..1668a85c5e37d 100644 --- a/test/SourceKit/Indexing/index.swift +++ b/test/SourceKit/Indexing/index.swift @@ -180,7 +180,7 @@ class rdar18640140 { // didSet is not compatible with set/get var S1: Int { get { - return 1; + return 1 } set { } diff --git a/test/SourceKit/InterfaceGen/Inputs/Foo3.swift b/test/SourceKit/InterfaceGen/Inputs/Foo3.swift new file mode 100644 index 0000000000000..70bb7d9e038a3 --- /dev/null +++ b/test/SourceKit/InterfaceGen/Inputs/Foo3.swift @@ -0,0 +1,8 @@ +public class C { + public func f1() { + { (error : NSError?) -> Void in + dispatch_async(dispatch_get_main_queue(), { () -> Void in + }) + } + } +} diff --git a/test/SourceKit/InterfaceGen/Inputs/header2.h b/test/SourceKit/InterfaceGen/Inputs/header2.h new file mode 100644 index 0000000000000..672f12ec125eb --- /dev/null +++ b/test/SourceKit/InterfaceGen/Inputs/header2.h @@ -0,0 +1,5 @@ + +typedef struct { + long width; + long height; +} NUPixelSize; diff --git a/test/SourceKit/InterfaceGen/gen_clang_module.swift.helper.explicit.response b/test/SourceKit/InterfaceGen/gen_clang_module.swift.helper.explicit.response index 5d13d259f0721..f6a622a64e84e 100644 --- a/test/SourceKit/InterfaceGen/gen_clang_module.swift.helper.explicit.response +++ b/test/SourceKit/InterfaceGen/gen_clang_module.swift.helper.explicit.response @@ -61,7 +61,7 @@ public func fooHelperExplicitFrameworkFunc1(a: Int32) -> Int32 key.kind: source.lang.swift.decl.var.parameter, key.name: "a", key.offset: 45, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 diff --git a/test/SourceKit/InterfaceGen/gen_clang_module.swift.helper.response b/test/SourceKit/InterfaceGen/gen_clang_module.swift.helper.response index 3e79dd2756b7d..39308edca4743 100644 --- a/test/SourceKit/InterfaceGen/gen_clang_module.swift.helper.response +++ b/test/SourceKit/InterfaceGen/gen_clang_module.swift.helper.response @@ -179,7 +179,7 @@ public var FooHelperUnnamedEnumeratorA2: Int { get } key.kind: source.lang.swift.decl.var.parameter, key.name: "a", key.offset: 94, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 diff --git a/test/SourceKit/InterfaceGen/gen_clang_module.swift.response b/test/SourceKit/InterfaceGen/gen_clang_module.swift.response index e825cbb10fe6c..1919849f53788 100644 --- a/test/SourceKit/InterfaceGen/gen_clang_module.swift.response +++ b/test/SourceKit/InterfaceGen/gen_clang_module.swift.response @@ -3802,7 +3802,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 254, - key.length: 10, + key.length: 18, key.typename: "UInt32", key.nameoffset: 0, key.namelength: 0 @@ -3822,7 +3822,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 290, - key.length: 8, + key.length: 16, key.typename: "UInt32", key.nameoffset: 290, key.namelength: 8 @@ -3897,7 +3897,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 481, - key.length: 10, + key.length: 18, key.typename: "UInt32", key.nameoffset: 0, key.namelength: 0 @@ -3917,7 +3917,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 517, - key.length: 8, + key.length: 16, key.typename: "UInt32", key.nameoffset: 517, key.namelength: 8 @@ -4003,7 +4003,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 718, - key.length: 10, + key.length: 18, key.typename: "UInt32", key.nameoffset: 0, key.namelength: 0 @@ -4023,7 +4023,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 754, - key.length: 8, + key.length: 16, key.typename: "UInt32", key.nameoffset: 754, key.namelength: 8 @@ -4180,7 +4180,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 1195, - key.length: 8, + key.length: 13, key.typename: "Int", key.nameoffset: 1195, key.namelength: 8 @@ -4266,7 +4266,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "x", key.offset: 1498, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 1498, key.namelength: 1 @@ -4275,7 +4275,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "y", key.offset: 1508, - key.length: 1, + key.length: 9, key.typename: "Double", key.nameoffset: 1508, key.namelength: 1 @@ -4339,7 +4339,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "x", key.offset: 1632, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 1632, key.namelength: 1 @@ -4348,7 +4348,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "y", key.offset: 1642, - key.length: 1, + key.length: 9, key.typename: "Double", key.nameoffset: 1642, key.namelength: 1 @@ -4412,7 +4412,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "x", key.offset: 1821, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 1821, key.namelength: 1 @@ -4421,7 +4421,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "y", key.offset: 1831, - key.length: 1, + key.length: 9, key.typename: "Double", key.nameoffset: 1831, key.namelength: 1 @@ -4454,7 +4454,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "a", key.offset: 2015, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 @@ -4473,7 +4473,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { { key.kind: source.lang.swift.decl.var.parameter, key.offset: 2070, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 @@ -4493,7 +4493,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "a", key.offset: 2110, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 @@ -4502,7 +4502,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "b", key.offset: 2120, - key.length: 3, + key.length: 10, key.typename: "Float", key.nameoffset: 0, key.namelength: 0 @@ -4511,7 +4511,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "c", key.offset: 2132, - key.length: 3, + key.length: 11, key.typename: "Double", key.nameoffset: 0, key.namelength: 0 @@ -4520,7 +4520,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "d", key.offset: 2145, - key.length: 3, + key.length: 32, key.typename: "UnsafeMutablePointer", key.nameoffset: 0, key.namelength: 0 @@ -4540,7 +4540,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "blk", key.offset: 2265, - key.length: 3, + key.length: 24, key.typename: "((Float) -> Int32)!", key.nameoffset: 0, key.namelength: 0 @@ -4560,7 +4560,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "fptr", key.offset: 2331, - key.length: 4, + key.length: 40, key.typename: "(@convention(c) (Float) -> Int32)!", key.nameoffset: 0, key.namelength: 0 @@ -4653,7 +4653,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "a", key.offset: 3005, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 @@ -4806,7 +4806,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "anObject", key.offset: 3794, - key.length: 8, + key.length: 20, key.typename: "AnyObject!", key.nameoffset: 0, key.namelength: 0 @@ -4840,7 +4840,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "f", key.offset: 3881, - key.length: 7, + key.length: 14, key.typename: "Float", key.nameoffset: 3881, key.namelength: 5 @@ -4954,7 +4954,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "a", key.offset: 4354, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 @@ -4974,7 +4974,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "a", key.offset: 4397, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 @@ -4983,7 +4983,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "b", key.offset: 4407, - key.length: 7, + key.length: 14, key.typename: "Int32", key.nameoffset: 4407, key.namelength: 5 @@ -5149,7 +5149,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "x", key.offset: 5035, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 5035, key.namelength: 1 @@ -5431,7 +5431,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { key.kind: source.lang.swift.decl.var.parameter, key.name: "i", key.offset: 5902, - key.length: 5, + key.length: 12, key.typename: "Int32", key.nameoffset: 5902, key.namelength: 3 @@ -5494,7 +5494,7 @@ public class FooOverlayClassDerived : Foo.FooOverlayClassBase { { key.kind: source.lang.swift.decl.var.parameter, key.offset: 6245, - key.length: 1, + key.length: 15, key.typename: "FooCFTypeRef", key.nameoffset: 0, key.namelength: 0 diff --git a/test/SourceKit/InterfaceGen/gen_clang_module.swift.sub.response b/test/SourceKit/InterfaceGen/gen_clang_module.swift.sub.response index e9eff5ae0b29e..186563cf4633a 100644 --- a/test/SourceKit/InterfaceGen/gen_clang_module.swift.sub.response +++ b/test/SourceKit/InterfaceGen/gen_clang_module.swift.sub.response @@ -315,7 +315,7 @@ public var FooSubUnnamedEnumeratorA1: Int { get } key.kind: source.lang.swift.decl.var.parameter, key.name: "a", key.offset: 54, - key.length: 1, + key.length: 8, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 @@ -366,7 +366,7 @@ public var FooSubUnnamedEnumeratorA1: Int { get } key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 148, - key.length: 10, + key.length: 18, key.typename: "UInt32", key.nameoffset: 0, key.namelength: 0 @@ -386,7 +386,7 @@ public var FooSubUnnamedEnumeratorA1: Int { get } key.kind: source.lang.swift.decl.var.parameter, key.name: "rawValue", key.offset: 184, - key.length: 8, + key.length: 16, key.typename: "UInt32", key.nameoffset: 184, key.namelength: 8 diff --git a/test/SourceKit/InterfaceGen/gen_header.swift b/test/SourceKit/InterfaceGen/gen_header.swift index dee84ca8f398d..dd7f43d830e81 100644 --- a/test/SourceKit/InterfaceGen/gen_header.swift +++ b/test/SourceKit/InterfaceGen/gen_header.swift @@ -1,3 +1,8 @@ // RUN: echo '#include "header.h"' > %t.m // RUN: %sourcekitd-test -req=interface-gen -header %S/Inputs/header.h -- -fsyntax-only %t.m -I %S/Inputs > %t.response // RUN: diff -u %s.response %t.response +// RUN: rm %t.m + +// RUN: echo '#include "header2.h"' > %t.m +// RUN: %sourcekitd-test -req=interface-gen -header %S/Inputs/header2.h -- -fsyntax-only %t.m -I %S/Inputs > %t.header2.response +// RUN: diff -u %s.header2.response %t.header2.response diff --git a/test/SourceKit/InterfaceGen/gen_header.swift.header2.response b/test/SourceKit/InterfaceGen/gen_header.swift.header2.response new file mode 100644 index 0000000000000..441eed1951ee4 --- /dev/null +++ b/test/SourceKit/InterfaceGen/gen_header.swift.header2.response @@ -0,0 +1,206 @@ + +public struct NUPixelSize { + public var width: Int + public var height: Int + public init() + public init(width: Int, height: Int) +} + +[ + { + key.kind: source.lang.swift.syntaxtype.attribute.builtin, + key.offset: 1, + key.length: 6 + }, + { + key.kind: source.lang.swift.syntaxtype.keyword, + key.offset: 8, + key.length: 6 + }, + { + key.kind: source.lang.swift.syntaxtype.identifier, + key.offset: 15, + key.length: 11 + }, + { + key.kind: source.lang.swift.syntaxtype.attribute.builtin, + key.offset: 33, + key.length: 6 + }, + { + key.kind: source.lang.swift.syntaxtype.keyword, + key.offset: 40, + key.length: 3 + }, + { + key.kind: source.lang.swift.syntaxtype.identifier, + key.offset: 44, + key.length: 5 + }, + { + key.kind: source.lang.swift.syntaxtype.typeidentifier, + key.offset: 51, + key.length: 3 + }, + { + key.kind: source.lang.swift.syntaxtype.attribute.builtin, + key.offset: 59, + key.length: 6 + }, + { + key.kind: source.lang.swift.syntaxtype.keyword, + key.offset: 66, + key.length: 3 + }, + { + key.kind: source.lang.swift.syntaxtype.identifier, + key.offset: 70, + key.length: 6 + }, + { + key.kind: source.lang.swift.syntaxtype.typeidentifier, + key.offset: 78, + key.length: 3 + }, + { + key.kind: source.lang.swift.syntaxtype.attribute.builtin, + key.offset: 86, + key.length: 6 + }, + { + key.kind: source.lang.swift.syntaxtype.keyword, + key.offset: 93, + key.length: 4 + }, + { + key.kind: source.lang.swift.syntaxtype.attribute.builtin, + key.offset: 104, + key.length: 6 + }, + { + key.kind: source.lang.swift.syntaxtype.keyword, + key.offset: 111, + key.length: 4 + }, + { + key.kind: source.lang.swift.syntaxtype.identifier, + key.offset: 116, + key.length: 5 + }, + { + key.kind: source.lang.swift.syntaxtype.typeidentifier, + key.offset: 123, + key.length: 3 + }, + { + key.kind: source.lang.swift.syntaxtype.identifier, + key.offset: 128, + key.length: 6 + }, + { + key.kind: source.lang.swift.syntaxtype.typeidentifier, + key.offset: 136, + key.length: 3 + } +] +[ + { + key.kind: source.lang.swift.ref.struct, + key.offset: 51, + key.length: 3, + key.is_system: 1 + }, + { + key.kind: source.lang.swift.ref.struct, + key.offset: 78, + key.length: 3, + key.is_system: 1 + }, + { + key.kind: source.lang.swift.ref.struct, + key.offset: 123, + key.length: 3, + key.is_system: 1 + }, + { + key.kind: source.lang.swift.ref.struct, + key.offset: 136, + key.length: 3, + key.is_system: 1 + } +] +[ + { + key.kind: source.lang.swift.decl.struct, + key.accessibility: source.lang.swift.accessibility.public, + key.name: "NUPixelSize", + key.offset: 8, + key.length: 134, + key.nameoffset: 15, + key.namelength: 11, + key.bodyoffset: 28, + key.bodylength: 113, + key.substructure: [ + { + key.kind: source.lang.swift.decl.var.instance, + key.accessibility: source.lang.swift.accessibility.public, + key.setter_accessibility: source.lang.swift.accessibility.public, + key.name: "width", + key.offset: 40, + key.length: 14, + key.typename: "Int", + key.nameoffset: 44, + key.namelength: 5 + }, + { + key.kind: source.lang.swift.decl.var.instance, + key.accessibility: source.lang.swift.accessibility.public, + key.setter_accessibility: source.lang.swift.accessibility.public, + key.name: "height", + key.offset: 66, + key.length: 15, + key.typename: "Int", + key.nameoffset: 70, + key.namelength: 6 + }, + { + key.kind: source.lang.swift.decl.function.method.instance, + key.accessibility: source.lang.swift.accessibility.public, + key.name: "init()", + key.offset: 93, + key.length: 6, + key.nameoffset: 93, + key.namelength: 6 + }, + { + key.kind: source.lang.swift.decl.function.method.instance, + key.accessibility: source.lang.swift.accessibility.public, + key.name: "init(width:height:)", + key.offset: 111, + key.length: 29, + key.nameoffset: 111, + key.namelength: 29, + key.substructure: [ + { + key.kind: source.lang.swift.decl.var.parameter, + key.name: "width", + key.offset: 116, + key.length: 10, + key.typename: "Int", + key.nameoffset: 116, + key.namelength: 5 + }, + { + key.kind: source.lang.swift.decl.var.parameter, + key.name: "height", + key.offset: 128, + key.length: 11, + key.typename: "Int", + key.nameoffset: 128, + key.namelength: 6 + } + ] + } + ] + } +] diff --git a/test/SourceKit/InterfaceGen/gen_header.swift.response b/test/SourceKit/InterfaceGen/gen_header.swift.response index d0f52c9b58bc4..6a359c38c84af 100644 --- a/test/SourceKit/InterfaceGen/gen_header.swift.response +++ b/test/SourceKit/InterfaceGen/gen_header.swift.response @@ -160,7 +160,7 @@ public protocol SameNameProtocol { key.kind: source.lang.swift.decl.var.parameter, key.name: "arg", key.offset: 30, - key.length: 3, + key.length: 10, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 @@ -192,7 +192,7 @@ public protocol SameNameProtocol { key.kind: source.lang.swift.decl.var.parameter, key.name: "arg", key.offset: 90, - key.length: 3, + key.length: 10, key.typename: "Int32", key.nameoffset: 0, key.namelength: 0 diff --git a/test/SourceKit/InterfaceGen/gen_swift_source.swift b/test/SourceKit/InterfaceGen/gen_swift_source.swift index d30280a560834..e706b18dc8b50 100644 --- a/test/SourceKit/InterfaceGen/gen_swift_source.swift +++ b/test/SourceKit/InterfaceGen/gen_swift_source.swift @@ -11,3 +11,6 @@ // RUN: %sourcekitd-test -req=interface-gen %S/Inputs/UnresolvedExtension.swift -- %S/Inputs/UnresolvedExtension.swift | FileCheck -check-prefix=CHECK2 %s // CHECK2: extension ET + +// RUN: %sourcekitd-test -req=interface-gen %S/Inputs/Foo3.swift -- %S/Inputs/Foo3.swift | FileCheck -check-prefix=CHECK3 %s +// CHECK3: public class C { diff --git a/test/SourceKit/Sema/placeholders.swift.placeholders.response b/test/SourceKit/Sema/placeholders.swift.placeholders.response index dc83a3cc2a71f..d1af3b914f78e 100644 --- a/test/SourceKit/Sema/placeholders.swift.placeholders.response +++ b/test/SourceKit/Sema/placeholders.swift.placeholders.response @@ -13,5 +13,13 @@ key.length: 14 } ] + }, + { + key.line: 4, + key.column: 19, + key.filepath: placeholders.swift, + key.severity: source.diagnostic.severity.error, + key.description: "type '()' does not conform to protocol 'SequenceType'", + key.diagnostic_stage: source.diagnostic.stage.swift.sema } ] diff --git a/test/SourceKit/SourceDocInfo/cursor_info.swift b/test/SourceKit/SourceDocInfo/cursor_info.swift index df9574d44f4e1..2723a418860b8 100644 --- a/test/SourceKit/SourceDocInfo/cursor_info.swift +++ b/test/SourceKit/SourceDocInfo/cursor_info.swift @@ -146,7 +146,7 @@ public class SubscriptCursorTest { // RUN: %sourcekitd-test -req=cursor -pos=28:24 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck -check-prefix=CHECK12 %s // CHECK12: source.lang.swift.decl.var.local (28:23-28:27) -// CHECK12: let arg1: Int +// CHECK12: var arg1: Int // RUN: %sourcekitd-test -req=cursor -pos=31:7 %s -- -F %S/../Inputs/libIDE-mock-sdk -I %t.tmp %mcp_opt %s | FileCheck -check-prefix=CHECK13 %s // CHECK13: source.lang.swift.decl.function.free (31:6-31:37) diff --git a/test/SourceKit/SourceDocInfo/cursor_overrides.swift b/test/SourceKit/SourceDocInfo/cursor_overrides.swift index 4e826f6026534..f2fd76b87a6d0 100644 --- a/test/SourceKit/SourceDocInfo/cursor_overrides.swift +++ b/test/SourceKit/SourceDocInfo/cursor_overrides.swift @@ -16,10 +16,10 @@ func goo(x: SubCls) { x.meth() } -// RUN: %sourcekitd-test -req=cursor -pos=16:7 %s -- -triple x86_64-apple-macosx10.9 -I %S/Inputs/cursor-overrides %mcp_opt %s | FileCheck -check-prefix=CHECK1 %s +// RUN: %sourcekitd-test -req=cursor -pos=16:7 %s -- -embed-bitcode -triple x86_64-apple-macosx10.9 -I %S/Inputs/cursor-overrides %mcp_opt %s | FileCheck -check-prefix=CHECK1 %s // CHECK1: source.lang.swift.ref.function.method.instance (12:8-12:14) // CHECK1: s:FC16cursor_overrides6SubCls4methFT_T_ -// CHECK1: SubCls -> () -> () +// CHECK1: (SubCls) -> () -> () // CHECK1: OVERRIDES BEGIN // CHECK1-NEXT: s:FC16cursor_overrides3Cls4methFT_T_ // CHECK1-NEXT: s:FP16cursor_overrides4Prot4methFT_T_ diff --git a/test/SourceKit/lit.local.cfg b/test/SourceKit/lit.local.cfg index e88ba7ad2749f..b2c25eab20c46 100644 --- a/test/SourceKit/lit.local.cfg +++ b/test/SourceKit/lit.local.cfg @@ -1,4 +1,4 @@ -if 'sourcekit' not in config.available_features: +if 'OS=macosx' not in config.available_features: config.unsupported = True else: diff --git a/test/TypeCoercion/integer_literals.swift b/test/TypeCoercion/integer_literals.swift index 51a3601659370..5766fcdb6c9c6 100644 --- a/test/TypeCoercion/integer_literals.swift +++ b/test/TypeCoercion/integer_literals.swift @@ -54,9 +54,9 @@ struct supermeters : IntegerLiteralConvertible { // expected-error{{type 'superm } func chaining() { - var length : meters = 17; + var length : meters = 17 // FIXME: missing truncation warning . - var long_length : meters = 500; + var long_length : meters = 500 var really_long_length : supermeters = 10 } diff --git a/test/TypeCoercion/overload_member.swift b/test/TypeCoercion/overload_member.swift index 8aa9932839c7e..4d0f2e692e31c 100644 --- a/test/TypeCoercion/overload_member.swift +++ b/test/TypeCoercion/overload_member.swift @@ -41,8 +41,8 @@ func test_method_overload_coerce(a: A, inout x: X, inout y: Y, z: Z) { } func test_method_value_coerce(a: A) { - var _ : (X) -> X = a.f; - var _ : (A) -> (X) -> X = A.f; + var _ : (X) -> X = a.f + var _ : (A) -> (X) -> X = A.f } func test_static_method_overload(a: A, x: X, y: Y) { @@ -62,8 +62,8 @@ func test_static_method_overload_coerce(a: A, inout x: X, inout y: Y, z: Z) { } func test_static_method_value_coerce(a: A) { - var _ : (X) -> X = A.sf; - var _ : (Y) -> Y = A.sf; + var _ : (X) -> X = A.sf + var _ : (Y) -> Y = A.sf } func test_mixed_overload(a: A, x: X, y: Y) { @@ -71,7 +71,7 @@ func test_mixed_overload(a: A, x: X, y: Y) { x1 = x var y1 = a.mixed(y: y) // expected-error{{incorrect argument label in call (have 'y:', expected 'x:')}} - A.mixed(x) // expected-error{{cannot convert value of type 'X' to expected argument type 'Y'}} + A.mixed(x) // expected-error{{missing argument label 'y:' in call}} var x2 = A.mixed(a)(x: x) x2 = x var y2 = A.mixed(y: y) @@ -87,10 +87,10 @@ func test_mixed_overload_coerce(a: A, inout x: X, y: Y, z: Z) { } func test_mixed_method_value_coerce(a: A) { - var _ : (X) -> X = a.mixed; - var _ : (Y) -> Y = A.mixed; + var _ : (X) -> X = a.mixed + var _ : (Y) -> Y = A.mixed var _ : (Y) -> Y = a.mixed; // expected-error{{cannot convert value of type '(x: X) -> X' to specified type '(Y) -> Y'}} - var _ : (A) -> (X) -> X = A.mixed; + var _ : (A) -> (X) -> X = A.mixed } extension A { @@ -118,9 +118,9 @@ extension A { } func test_method_value_coerce() { - var _ : (X) -> X = f; - var _ : (A) -> (X) -> X = A.f; - var _ : (A) -> (X) -> X = A.f; + var _ : (X) -> X = f + var _ : (A) -> (X) -> X = A.f + var _ : (A) -> (X) -> X = A.f } func test_mixed_overload_coerce(inout x x: X, y: Y, z: Z) { @@ -129,10 +129,10 @@ extension A { } func test_mixed_method_value_coerce() { - var _ : (X) -> X = mixed; + var _ : (X) -> X = mixed var _ : (Y) -> Y = mixed; // expected-error{{cannot convert value of type '(x: X) -> X' to specified type '(Y) -> Y'}} var _ : (Y) -> Y = mixed; // expected-error{{cannot convert value of type '(x: X) -> X' to specified type '(Y) -> Y'}} - var _ : (A) -> (X) -> X = A.mixed; + var _ : (A) -> (X) -> X = A.mixed } class func test_method_overload_static(x x: X, y: Y, z: Z) { @@ -157,7 +157,7 @@ extension A { } class func test_mixed_overload_static(a a: A, x: X, y: Y) { - mixed(x) // expected-error{{cannot convert value of type 'X' to expected argument type 'Y'}} + mixed(x) // expected-error{{missing argument label 'y:' in call}} var x2 = mixed(a)(x: x) x2 = x var y2 = mixed(y: y) @@ -171,12 +171,12 @@ extension A { } class func test_mixed_method_value_coerce_static() { - var _ : (Y) -> Y = mixed; - var _ : (A) -> (X) -> X = mixed; + var _ : (Y) -> Y = mixed + var _ : (A) -> (X) -> X = mixed } } -var clams : X; +var clams : X struct WeirdIvarLookupBehavior { var clams : Y diff --git a/test/TypeCoercion/overload_noncall.swift b/test/TypeCoercion/overload_noncall.swift index d5922531da721..162b51ec96be1 100644 --- a/test/TypeCoercion/overload_noncall.swift +++ b/test/TypeCoercion/overload_noncall.swift @@ -25,10 +25,10 @@ func test_conv() { a8 = a9 a9 = a7 - var _ : ((X)->X) -> ((Y) -> Y) = f2; - var _ : ((x2 : X)-> (X)) -> (((y2 : Y) -> (Y))) = f2; + var _ : ((X) -> X) -> ((Y) -> Y) = f2 + var _ : ((x2 : X) -> (X)) -> (((y2 : Y) -> (Y))) = f2 - typealias fp = ((X)->X) -> ((Y) -> Y) + typealias fp = ((X) -> X) -> ((Y) -> Y) var _ = f2 } @@ -43,7 +43,7 @@ func accept_XY(inout y: Y) -> Y { } func accept_Z(inout z: Z) -> Z { } func test_inout() { - var x : X; + var x : X accept_X(&x); accept_X(xy); // expected-error{{passing value of type 'X' to an inout parameter requires explicit '&'}} {{12-12=&}} accept_X(&xy); @@ -51,7 +51,7 @@ func test_inout() { accept_XY(&x); x = accept_XY(&xy); - x = xy; + x = xy x = &xy; // expected-error{{'&' used with non-inout argument of type 'X'}} accept_Z(&xy); // expected-error{{cannot convert value of type 'X' to expected argument type 'Z'}} } @@ -60,8 +60,8 @@ func lvalue_or_rvalue(inout x: X) -> X { } func lvalue_or_rvalue(x: X) -> Y { } func test_lvalue_or_rvalue() { - var x : X; - var y : Y; + var x : X + var y : Y let x1 = lvalue_or_rvalue(&x) x = x1 let y1 = lvalue_or_rvalue(x) diff --git a/test/TypeCoercion/unknowable.swift b/test/TypeCoercion/unknowable.swift index 66aa76e1f38c9..ca0630e778de9 100644 --- a/test/TypeCoercion/unknowable.swift +++ b/test/TypeCoercion/unknowable.swift @@ -16,7 +16,7 @@ func ovlLitA(_: Int32) -> Int32 {} func ovlLitA(_: Int64) -> Int64 {} func ovlLitB(_: Int32) -> Int32 {} // expected-note{{}} func ovlLitB(_: Int64) -> Int64 {} // expected-note{{}} -func testLiteralOverloadinovlLitB() { +func testLiteralOverloadingovlLitB() { var y32 : Int32 = ovlLitA(ovlLitB(0)) var y64 : Int64 = ovlLitA(ovlLitB(0)) var y /*: Int*/ = ovlLitA(ovlLitB(0)) // expected-error{{ambiguous use of 'ovlLitB'}} diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg index ba0172da4b5cc..093dec2b93bc5 100644 --- a/test/Unit/lit.cfg +++ b/test/Unit/lit.cfg @@ -1,6 +1,12 @@ -# -*- Python -*- - -# Configuration file for the 'lit' test runner. +# test/Unit/lit.cfg - Configuration for the 'lit' test runner. -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors import os diff --git a/test/attr/attr_autoclosure.swift b/test/attr/attr_autoclosure.swift index 0460d3b50bece..48a557894323d 100644 --- a/test/attr/attr_autoclosure.swift +++ b/test/attr/attr_autoclosure.swift @@ -23,20 +23,8 @@ func func8(@autoclosure inout x: () -> Bool) -> Bool { // expected-error {{@aut } -// Should have good QoI: -func migrate1(fp fpx : @autoclosure () -> Int) {} // expected-error {{@autoclosure is now an attribute of the parameter declaration, not its type}} {{15-15=@autoclosure }} {{24-37=}} -struct MethodHolder { - func migrate2(a : Int, _ fp : @autoclosure () -> Int) {} // expected-error {{@autoclosure is now an attribute of the parameter declaration, not its type}} {{26-26=@autoclosure }} {{33-46=}} -} -func migrate3(fp fp : @autoclosure () -> Int) {} // expected-error {{@autoclosure is now an attribute of the parameter declaration, not its type}} {{15-15=@autoclosure }} {{23-36=}} -public func || ( - lhs: T, rhs: @autoclosure () -> Bool // expected-error {{@autoclosure is now an attribute of the parameter declaration, not its type}} {{11-11=@autoclosure }} {{16-29=}} - ) -> Bool { - return lhs.boolValue ? true : rhs().boolValue -} - // QoI: @autoclosure declaration change fixit -let migrate4 : @autoclosure() -> () // expected-error {{@autoclosure is now an attribute of the parameter declaration, not its type}} {{1-1=@autoclosure }} {{16-28=}} +let migrate4 : @autoclosure() -> () // expected-error {{attribute can only be applied to declarations, not types}} {{1-1=@autoclosure }} {{16-28=}} struct SomeStruct { @@ -124,7 +112,7 @@ class TestFunc12 { enum AutoclosureFailableOf { - case Success(@autoclosure () -> T) // expected-error {{@autoclosure is only allowed on parameters, not on enum cases}} + case Success(@autoclosure () -> T) // expected-error {{attribute can only be applied to declarations, not types}} case Failure() } diff --git a/test/attr/attr_availability.swift b/test/attr/attr_availability.swift index 4e004b04bd20f..db698581b95b9 100644 --- a/test/attr/attr_availability.swift +++ b/test/attr/attr_availability.swift @@ -56,7 +56,7 @@ func useWithEscapedMessage() { // More complicated parsing. @available(OSX, message="x", unavailable) -let _: Int; +let _: Int @available(OSX, introduced=1, deprecated=2.0, obsoleted=3.0.0) let _: Int @@ -66,7 +66,7 @@ let _: Int // Meaningless but accepted. @available(OSX, message="x") -let _: Int; +let _: Int // Parse errors. @@ -79,19 +79,19 @@ let _: Int @available(OSX, message) // expected-error{{expected '=' after 'message' in 'available' attribute}} let _: Int -@available(OSX, message=) // expected-error{{expected string literal in 'available' attribute}} expected-error{{postfix '=' is reserved}} +@available(OSX, message=) // expected-error{{expected string literal in 'available' attribute}} expected-error{{'=' must have consistent whitespace on both sides}} let _: Int @available(OSX, message=x) // expected-error{{expected string literal in 'available' attribute}} let _: Int -@available(OSX, unavailable=) // expected-error{{expected ')' in 'available' attribute}} expected-error{{postfix '=' is reserved}} expected-error{{expected declaration}} +@available(OSX, unavailable=) // expected-error{{expected ')' in 'available' attribute}} expected-error{{'=' must have consistent whitespace on both sides}} expected-error{{expected declaration}} let _: Int @available(OSX, introduced) // expected-error{{expected '=' after 'introduced' in 'available' attribute}} let _: Int -@available(OSX, introduced=) // expected-error{{expected version number in 'available' attribute}} expected-error{{postfix '=' is reserved}} +@available(OSX, introduced=) // expected-error{{expected version number in 'available' attribute}} expected-error{{'=' must have consistent whitespace on both sides}} let _: Int @available(OSX, introduced=x) // expected-error{{expected version number in 'available' attribute}} @@ -193,3 +193,10 @@ func shortFormMissingWildcard() {} @availability(OSX, introduced=10.10) // expected-error {{@availability has been renamed to @available}} {{2-14=available}} func someFuncUsingOldAttribute() { } + + +// Compiler crash on call to unavailable "print" +func OutputStreamTest(message: String, inout to: OutputStreamType) { + print(message, &to) // expected-error {{'print' is unavailable: Please use the 'toStream' label for the target stream: 'print((...), toStream: &...)'}} +} + diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift index 75e8cdc0753d2..481291422df3f 100644 --- a/test/attr/attr_objc.swift +++ b/test/attr/attr_objc.swift @@ -42,7 +42,7 @@ var subject_getterSetter: Int { } } -var subject_global_observingAccesorsVar1: Int = 0 { +var subject_global_observingAccessorsVar1: Int = 0 { @objc willSet { // expected-error {{@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes}} {{3-9=}} } @@ -194,9 +194,21 @@ extension subject_genericClass { @objc enum subject_enum: Int { - @objc // expected-error {{@objc cannot be applied to this declaration}} {{3-9=}} + @objc // expected-error {{attribute has no effect; cases within an '@objc' enum are already exposed to Objective-C}} {{3-9=}} case subject_enumElement1 + @objc(subject_enumElement2) + case subject_enumElement2 + + @objc(subject_enumElement3) + case subject_enumElement3, subject_enumElement4 // expected-error {{'@objc' enum case declaration defines multiple enum cases with the same Objective-C name}}{{3-8=}} + + @objc // expected-error {{attribute has no effect; cases within an '@objc' enum are already exposed to Objective-C}} {{3-9=}} + case subject_enumElement5, subject_enumElement6 + + @nonobjc // expected-error {{@nonobjc cannot be applied to this declaration}} + case subject_enumElement7 + @objc init() {} // expected-error {{@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes}} {{3-9=}} @@ -204,6 +216,11 @@ enum subject_enum: Int { func subject_instanceFunc() {} // expected-error {{@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes}} {{3-8=}} } +enum subject_enum2 { + @objc(subject_enum2Element1) + case subject_enumElement1 // expected-error{{'@objc' enum case is not allowed outside of an '@objc' enum}}{{3-8=}} +} + @objc protocol subject_protocol1 { @objc @@ -804,16 +821,16 @@ class infer_instanceVar1 { // CHECK-NEXT: @objc set {} } - var observingAccesorsVar1: Int { - // CHECK: @objc var observingAccesorsVar1: Int { + var observingAccessorsVar1: Int { + // CHECK: @objc var observingAccessorsVar1: Int { willSet {} // CHECK-NEXT: {{^}} final willSet {} didSet {} // CHECK-NEXT: {{^}} final didSet {} } - @objc var observingAccesorsVar1_: Int { - // CHECK: {{^}} @objc var observingAccesorsVar1_: Int { + @objc var observingAccessorsVar1_: Int { + // CHECK: {{^}} @objc var observingAccessorsVar1_: Int { willSet {} // CHECK-NEXT: {{^}} final willSet {} didSet {} @@ -1749,6 +1766,15 @@ class BadClass1 { } @objc(Protocol:) // expected-error{{'@objc' protocol must have a simple name}}{{15-16=}} protocol BadProto1 { } +@objc(Enum:) // expected-error{{'@objc' enum must have a simple name}}{{11-12=}} +enum BadEnum1: Int { case X } + +@objc +enum BadEnum2: Int { + @objc(X:) // expected-error{{'@objc' enum case must have a simple name}}{{10-11=}} + case X +} + class BadClass2 { @objc(badprop:foo:wibble:) // expected-error{{'@objc' property must have a simple name}}{{16-28=}} var badprop: Int = 5 diff --git a/test/attr/attr_semantics.swift b/test/attr/attr_semantics.swift index 56481c03e6c18..77f55fa786043 100644 --- a/test/attr/attr_semantics.swift +++ b/test/attr/attr_semantics.swift @@ -1,17 +1,21 @@ // RUN: %target-parse-verify-swift -@_semantics("foo") // expected-note {{attribute already specified here}} -@_semantics("bar") // expected-error {{duplicate attribute}} +@_semantics("foo") +@_semantics("bar") func duplicatesemantics() {} +func func_with_nested_semantics_1() { + @_semantics("exit") // expected-error {{attribute '_semantics' can only be used in a non-local scope}} + func exit(code : UInt32) -> Void + exit(0) +} + // Test parser recovery by having something that // should parse fine. func somethingThatShouldParseFine() {} - -func func_with_nested_semantics() { +func func_with_nested_semantics_2() { @_semantics("exit") // expected-error {{attribute '_semantics' can only be used in a non-local scope}} func exit(code : UInt32) -> Void exit(0) } - diff --git a/test/attr/attr_asmname.swift b/test/attr/attr_silgen_name.swift similarity index 100% rename from test/attr/attr_asmname.swift rename to test/attr/attr_silgen_name.swift diff --git a/test/attr/attr_warn_unused_result.swift b/test/attr/attr_warn_unused_result.swift index 86e48ab4b03a2..a2ec1eb3bc851 100644 --- a/test/attr/attr_warn_unused_result.swift +++ b/test/attr/attr_warn_unused_result.swift @@ -86,7 +86,7 @@ struct BadAttributes1 { @warn_unused_result(blarg) func f1() { } // expected-warning{{unknown parameter 'blarg' in 'warn_unused_result' attribute}} @warn_unused_result(wibble="foo") func f2() { } // expected-warning{{unknown parameter 'wibble' in 'warn_unused_result' attribute}} @warn_unused_result(message) func f3() { } // expected-error{{expected '=' following 'message' parameter}} - @warn_unused_result(message=) func f4() { } // expected-error{{postfix '=' is reserved}} + @warn_unused_result(message=) func f4() { } // expected-error{{'=' must have consistent whitespace on both sides}} // expected-error@-1{{expected a string following '=' for 'message' parameter}} @warn_unused_result(message=blah) func f5() { } // expected-error{{expected a string following '=' for 'message' parameter}} diff --git a/test/attr/attributes.swift b/test/attr/attributes.swift index 7459b09ac2caa..cf5053751946e 100644 --- a/test/attr/attributes.swift +++ b/test/attr/attributes.swift @@ -203,6 +203,17 @@ var thinFunc : @thin () -> () // expected-error {{attribute is not supported}} @inline(__always) class FooClass2 { // expected-error {{@inline(__always) cannot be applied to this declaration}} {{1-19=}} } +@_migration_id("blah1") +func migrating1() {} +@_migration_id("blah2", pattern="yoda") +func migrating2() {} +@_migration_id(pattern="yoda") // expected-error {{expected string literal in '_migration_id' attribute}} +func migrating3() {} +@_migration_id() // expected-error {{expected string literal in '_migration_id' attribute}} +func migrating4() {} +@_migration_id // expected-error {{expected '(' in '_migration_id' attribute}} +func migrating5() {} + class A { @inline(never) init(a : Int) {} var b : Int { diff --git a/test/decl/enum/Inputs/objc_enum_multi_file_helper.swift b/test/decl/enum/Inputs/objc_enum_multi_file_helper.swift index 049fa6a7c1739..30afc19d4c49e 100644 --- a/test/decl/enum/Inputs/objc_enum_multi_file_helper.swift +++ b/test/decl/enum/Inputs/objc_enum_multi_file_helper.swift @@ -3,6 +3,6 @@ func useEnum(x: TheEnum) { case A: print("a!") default: - break; + break } } diff --git a/test/decl/enum/enumtest.swift b/test/decl/enum/enumtest.swift index b526ac2b1a961..63b220d6c04ae 100644 --- a/test/decl/enum/enumtest.swift +++ b/test/decl/enum/enumtest.swift @@ -267,11 +267,11 @@ func testDirection() { switch dir { case .North(let x): i = x - break; + break case .NorthEast(let x): i = x.distanceEast - break; + break } _ = i } @@ -287,7 +287,7 @@ enum SimpleEnum { func testSimpleEnum() { let _ : SimpleEnum = .X let _ : SimpleEnum = (.X) - let _ : SimpleEnum=.X // expected-error {{postfix '=' is reserved}} + let _ : SimpleEnum=.X // expected-error {{'=' must have consistent whitespace on both sides}} } diff --git a/test/decl/ext/protocol.swift b/test/decl/ext/protocol.swift index 9fa5d0c5d1048..60ee3282d510d 100644 --- a/test/decl/ext/protocol.swift +++ b/test/decl/ext/protocol.swift @@ -361,7 +361,7 @@ struct MyIndexedGenerator : GeneratorType { mutating func next() -> C._Element? { if index == container.myEndIndex { return nil } let result = container[index] - ++index + index = index.successor() return result } } @@ -373,7 +373,7 @@ struct OtherIndexedGenerator : GeneratorType { mutating func next() -> C._Element? { if index == container.myEndIndex { return nil } let result = container[index] - ++index + index = index.successor() return result } } @@ -446,7 +446,7 @@ func test(x: T) -> Int { return x.f() } struct PConforms6Impl : PConforms6 { } -// Extensions of a protocol that directly satify requirements (i.e., +// Extensions of a protocol that directly satisfy requirements (i.e., // default implementations hack N+1). protocol PConforms7 { func method() diff --git a/test/decl/func/arg_rename.swift b/test/decl/func/arg_rename.swift index 724b9a74bbff3..800514b2fbbc3 100644 --- a/test/decl/func/arg_rename.swift +++ b/test/decl/func/arg_rename.swift @@ -23,23 +23,13 @@ GS(a: 5, b: 7) // expected-warning{{unused}} func f1(a a: Int, b: Int) { } f1(a: 1, b: 2) -func f2(`class` cls: Int) { } -f2(`class`: 5) +func f2(class cls: Int) { } +f2(class: 5) -// # diagnostics. -func g1(#a x: Int, #b y: Int) { } -// expected-warning@-1{{extraneous '#' in parameter}}{{9-10=}} -// expected-warning@-2{{extraneous '#' in parameter}}{{20-21=}} func g2(a a: Int) { } -func g3(#:Int) { } -// expected-error@-1{{expected parameter name after '#'}} - -func g4(#_:Int) { } -// expected-error@-1{{expected non-empty parameter name after '#'}}{{9-10=}} - func g5(_ a: Int) { } // expected-warning@-1{{extraneous '_' in parameter: 'a' has no keyword argument name}}{{9-11=}} @@ -54,7 +44,7 @@ class X { // Operators never have keyword arguments. infix operator +++ { } -func +++(#lhs: Int, // expected-error{{operator cannot have keyword arguments}}{{10-11=}} +func +++(lhs lhs: Int, // expected-error{{operator cannot have keyword arguments}}{{10-14=}} rhs x: Int) -> Int { // expected-error{{operator cannot have keyword arguments}}{{10-14=}} return lhs + x } diff --git a/test/decl/func/complete_object_init.swift b/test/decl/func/complete_object_init.swift index 3af0994e78756..7fb6795dd234b 100644 --- a/test/decl/func/complete_object_init.swift +++ b/test/decl/func/complete_object_init.swift @@ -94,7 +94,7 @@ class B2 : A { func testConstructB2(i: Int) { var b2a = B2() - var b2b = B2(int: i) // expected-error{{extra argument 'int' in call}} + var b2b = B2(int: i) // expected-error{{argument passed to call that takes no arguments}} var b2: B2 = b2a } diff --git a/test/decl/func/constructor.swift b/test/decl/func/constructor.swift index bff568596798e..205b8970ea3cb 100644 --- a/test/decl/func/constructor.swift +++ b/test/decl/func/constructor.swift @@ -95,11 +95,8 @@ class ArgParamSep { init(_ b: Int, _: Int, forInt int: Int, c _: Int, d: Int) { } } -//===--- -//===--- Tests for crashes. -//===--- - -//===--- rdar://14082378 +// Tests for crashes. +// rdar://14082378 struct NoCrash1a { init(_: NoCrash1b) {} // expected-error {{use of undeclared type 'NoCrash1b'}} diff --git a/test/decl/func/functions.swift b/test/decl/func/functions.swift index 4a91f55c1c365..93c37d7f4a492 100644 --- a/test/decl/func/functions.swift +++ b/test/decl/func/functions.swift @@ -62,26 +62,26 @@ func recover_missing_body_2() // expected-error {{expected '{' in body of functi // should produce the error about missing right paren. // // FIXME: The errors are awful. We should produce just the error about paren. -func f_recover_missing_tuple_paren(a: Int // expected-error {{expected parameter type following ':'}} expected-note {{to match this opening '('}} expected-error{{expected '{' in body of function declaration}} expected-error {{expected ')' in parameter}} expected-error 2{{expected ',' separator}} {{42-42=,}} {{42-42=,}} +func f_recover_missing_tuple_paren(a: Int // expected-note {{to match this opening '('}} expected-error{{expected '{' in body of function declaration}} expected-error {{expected ')' in parameter}} func g_recover_missing_tuple_paren(b: Int) { } //===--- Parse errors. -func parseError1a(a: ) {} // expected-error {{type annotation missing in pattern}} expected-error {{expected parameter type following ':'}} +func parseError1a(a: ) {} // expected-error {{expected parameter type following ':'}} -func parseError1b(a: // expected-error {{type annotation missing in pattern}} expected-error {{expected parameter type following ':'}} +func parseError1b(a: // expected-error {{expected parameter type following ':'}} ) {} -func parseError2(a: Int, b: ) {} // expected-error {{type annotation missing in pattern}} expected-error {{expected parameter type following ':'}} +func parseError2(a: Int, b: ) {} // expected-error {{expected parameter type following ':'}} -func parseError3(a: unknown_type, b: ) {} // expected-error {{use of undeclared type 'unknown_type'}} expected-error {{type annotation missing in pattern}} expected-error {{expected parameter type following ':'}} +func parseError3(a: unknown_type, b: ) {} // expected-error {{use of undeclared type 'unknown_type'}} expected-error {{expected parameter type following ':'}} -func parseError4(a: , b: ) {} // expected-error 2{{type annotation missing in pattern}} expected-error 2{{expected parameter type following ':'}} +func parseError4(a: , b: ) {} // expected-error 2{{expected parameter type following ':'}} func parseError5(a: b: ) {} // expected-error {{use of undeclared type 'b'}} expected-error 2{{expected ',' separator}} {{22-22=,}} {{22-22=,}} expected-error {{expected parameter type following ':'}} -func parseError6(a: unknown_type, b: ) {} // expected-error {{use of undeclared type 'unknown_type'}} expected-error {{type annotation missing in pattern}} expected-error {{expected parameter type following ':'}} +func parseError6(a: unknown_type, b: ) {} // expected-error {{use of undeclared type 'unknown_type'}} expected-error {{expected parameter type following ':'}} func parseError7(a: Int, goo b: unknown_type) {} // expected-error {{use of undeclared type 'unknown_type'}} @@ -121,10 +121,8 @@ func testObjCMethodCurry(a : ClassWithObjCMethod) -> (Int) -> () { } // We used to crash on this. -func rdar16786220(var let c: Int) -> () { // expected-error {{Use of 'var' binding here is not allowed}} {{19-22=}} expected-error {{parameter may not have multiple 'inout', 'var', or 'let' specifiers}} - var c = c +func rdar16786220(var let c: Int) -> () { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{19-22=}} expected-error {{parameter may not have multiple 'inout', 'var', or 'let' specifiers}} c = 42 - _ = c } @@ -138,11 +136,9 @@ func !!!(lhs: UnsafePointer, rhs: UnsafePointer) -> Bool { return false // Functions currently permit 'var inout' parameters func inout_inout_error(inout inout x : Int) {} // expected-error {{parameter may not have multiple 'inout', 'var', or 'let' specifiers}} {{30-36=}} -// expected-error@+1 {{Use of 'var' binding here is not allowed}} {{22-25=}} +// expected-warning@+1 {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{22-25=}} func var_inout_error(var inout x : Int) { // expected-error {{parameter may not have multiple 'inout', 'var', or 'let' specifiers}} {{26-32=}} - var x = x x = 2 - _ = x } // Unnamed parameters require the name "_": diff --git a/test/decl/func/keyword-argument-defaults.swift b/test/decl/func/keyword-argument-defaults.swift index 4491a6124fd12..c369ed69dec9f 100644 --- a/test/decl/func/keyword-argument-defaults.swift +++ b/test/decl/func/keyword-argument-defaults.swift @@ -116,7 +116,3 @@ func +(_ a: String, // expected-warning{{extraneous '_' in parameter: 'a' has n b b: Double) { } // expected-error{{operator cannot have keyword arguments}} {{8-10=}} func +(a: Double, b: String)(_ c: Int)(d e: Int) { } // okay; expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} - -// # is being removed -func pound(#a: Int, // expected-error{{'#' has been removed from Swift; double up 'a a' to make the argument label the same as the parameter name}}{{12-13=a }} - #b: Int) { } // expected-error{{'#' has been removed from Swift; 'b' already has an argument label}}{{12-13=}} diff --git a/test/decl/func/keyword-argument-labels.swift b/test/decl/func/keyword-argument-labels.swift new file mode 100644 index 0000000000000..4c29f3351ed12 --- /dev/null +++ b/test/decl/func/keyword-argument-labels.swift @@ -0,0 +1,51 @@ +// RUN: %target-parse-verify-swift + +struct SomeRange { } + +// Function declarations. +func paramName(func: Int, in: SomeRange) { } +func firstArgumentLabelWithParamName(in range: SomeRange) { } +func firstArgumentLabelWithParamName2(range in: SomeRange) { } + +func escapedInout(`inout` value: SomeRange) { } + +struct SomeType { + // Initializers + init(func: () -> ()) { } + init(init func: () -> ()) { } + + // Subscripts + subscript (class index: AnyClass) -> Int { + return 0 + } + + subscript (class: AnyClass) -> Int { + return 0 + } + + subscript (struct: Any.Type) -> Int { + return 0 + } +} + +class SomeClass { } + +// Function types. +typealias functionType = (in: SomeRange) -> Bool + +// Calls +func testCalls(range: SomeRange) { + paramName(0, in: range) + firstArgumentLabelWithParamName(in: range) + firstArgumentLabelWithParamName2(range: range) + var st = SomeType(func: {}) + st = SomeType(init: {}) + _ = st[class: SomeClass.self] + _ = st[SomeClass.self] + _ = st[SomeType.self] + + escapedInout(`inout`: range) + + // Fix-Its + paramName(0, `in`: range) // expected-warning{{keyword 'in' does not need to be escaped in argument list}}{{16-17=}}{{19-20=}} +} diff --git a/test/decl/func/rethrows.swift b/test/decl/func/rethrows.swift index 4b882ac1c5388..9d0229b89fcef 100644 --- a/test/decl/func/rethrows.swift +++ b/test/decl/func/rethrows.swift @@ -14,7 +14,7 @@ func f3(f: UndeclaredFunctionType) rethrows { f() } // expected-error {{use of u func cf1(f: () throws -> ())() rethrows { try f() } // expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} func cf2(f: () -> ())() rethrows { f() } // expected-error {{'rethrows' function must take a throwing function argument}} expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} func cf3(f: UndeclaredFunctionType)() rethrows { f() } // expected-error {{use of undeclared type 'UndeclaredFunctionType'}} expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} -func cf4(f: () ->())(g: () throws -> ()) rethrows {} // expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} +func cf4(f: () -> ())(g: () throws -> ()) rethrows {} // expected-warning{{curried function declaration syntax will be removed in a future version of Swift}} func cf5() rethrows -> () throws -> () {} // expected-error {{'rethrows' function must take a throwing function argument}} /** Protocol conformance checking ********************************************/ diff --git a/test/decl/import/import.swift b/test/decl/import/import.swift index 54e6b118c1f98..29a7c589a8673 100644 --- a/test/decl/import/import.swift +++ b/test/decl/import/import.swift @@ -27,7 +27,7 @@ func f1(a: Swift.Int) -> Swift.Void { print(a) } import func Swift.print // rdar://14418336 -#import something_nonexistant // expected-error {{expected expression}} expected-error {{no such module 'something_nonexistant'}} +#import something_nonexistent // expected-error {{expected expression}} expected-error {{no such module 'something_nonexistent'}} // Import specific decls import typealias Swift.Int diff --git a/test/decl/nested.swift b/test/decl/nested.swift index 1885ed6624f68..641a17c2ab89c 100644 --- a/test/decl/nested.swift +++ b/test/decl/nested.swift @@ -34,6 +34,13 @@ struct OuterGeneric { func flip(r: Rooster) func flop(t: D) } + + func nonGenericMethod(d: D) { + // FIXME: local generic functions can't capture generic parameters yet + func genericFunction(d: D, e: E) {} + + genericFunction(d, e: ()) + } } class OuterNonGenericClass { @@ -41,6 +48,42 @@ class OuterNonGenericClass { case Baz case Zab } + + class InnerNonGenericBase { + init() {} + } + + class InnerNonGenericClass1 : InnerNonGenericBase { + override init() { + super.init() + } + } + + class InnerNonGenericClass2 : OuterNonGenericClass { + override init() { + super.init() + } + } + + class InnerGenericClass : OuterNonGenericClass { // expected-error {{generic type 'InnerGenericClass' nested in type 'OuterNonGenericClass'}} + override init() { + super.init() + } + } + + func genericFunction(t: T) { + class InnerNonGenericClass : OuterNonGenericClass { // expected-error {{type 'InnerNonGenericClass' nested in generic function}} + let t: T + + init(t: T) { super.init(); self.t = t } + } + + class InnerGenericClass : OuterNonGenericClass { // expected-error {{type 'InnerGenericClass' nested in generic function}} + let t: T + + init(t: T) { super.init(); self.t = t } + } + } } class OuterGenericClass { @@ -55,9 +98,65 @@ class OuterGenericClass { func flop(t: T) } - class InnerNonGenericClass : InnerNonGenericBase {} // expected-error {{type 'InnerNonGenericClass' nested in generic type 'OuterGenericClass' is not allowed}} + class InnerNonGenericBase { // expected-error {{type 'InnerNonGenericBase' nested in generic type 'OuterGenericClass' is not allowed}} + init() {} + } + + class InnerNonGenericClass1 : InnerNonGenericBase { // expected-error {{type 'InnerNonGenericClass1' nested in generic type 'OuterGenericClass' is not allowed}} + override init() { + super.init() + } + } + + class InnerNonGenericClass2 : OuterGenericClass { // expected-error {{type 'InnerNonGenericClass2' nested in generic type 'OuterGenericClass' is not allowed}} + override init() { + super.init() + } + } + + class InnerNonGenericClass3 : OuterGenericClass { // expected-error {{type 'InnerNonGenericClass3' nested in generic type 'OuterGenericClass' is not allowed}} + override init() { + super.init() + } + } + + class InnerNonGenericClass4 : OuterGenericClass { // expected-error {{type 'InnerNonGenericClass4' nested in generic type 'OuterGenericClass' is not allowed}} + override init() { + super.init() + } + } + + class InnerGenericClass : OuterGenericClass { // expected-error {{type 'InnerGenericClass' nested in type 'OuterGenericClass' is not allowed}} + override init() { + super.init() + } + } + + func genericFunction(t: U) { + class InnerNonGenericClass1 : OuterGenericClass { // expected-error {{type 'InnerNonGenericClass1' nested in generic function}} + let t: T + + init(t: T) { super.init(); self.t = t } + } + + class InnerNonGenericClass2 : OuterGenericClass { // expected-error {{type 'InnerNonGenericClass2' nested in generic function}} + let t: T - class InnerNonGenericBase {} // expected-error {{type 'InnerNonGenericBase' nested in generic type 'OuterGenericClass' is not allowed}} + init(t: T) { super.init(); self.t = t } + } + + class InnerNonGenericClass3 : OuterGenericClass { // expected-error {{type 'InnerNonGenericClass3' nested in generic function}} + let t: T + + init(t: T) { super.init(); self.t = t } + } + + class InnerGenericClass : OuterGenericClass { // expected-error {{type 'InnerGenericClass' nested in generic function}} + let t: T + + init(t: T) { super.init(); self.t = t } + } + } } protocol OuterProtocol { @@ -83,3 +182,15 @@ enum OuterEnum { protocol C {} // expected-error{{declaration is only valid at file scope}} case C(C) } + +func outerGenericFunction(t: T) { + struct InnerNonGeneric { // expected-error{{type 'InnerNonGeneric' nested in generic function 'outerGenericFunction' }} + func nonGenericMethod(t: T) {} + func genericMethod(t: T) -> V {} + } + + struct InnerGeneric { // expected-error{{type 'InnerGeneric' nested in generic function 'outerGenericFunction' }} + func nonGenericMethod(t: T, u: U) {} + func genericMethod(t: T, u: U) -> V {} + } +} diff --git a/test/decl/operators.swift b/test/decl/operators.swift index 8b5b51f3a714b..272c9fc31210b 100644 --- a/test/decl/operators.swift +++ b/test/decl/operators.swift @@ -163,7 +163,7 @@ func operator_in_func_bad () { // expected-error {{use of unresolved identifier 'input'}} } -infix operator ? {} // expected-error {{expected operator name in operator declaration}} expected-error {{braced block of statements is an unused closure}} expected-error{{begin with a closure}} expected-note{{discard the result}} {{18-18=_ = }} expected-error{{expression resolves to an unused function}} +infix operator ? {} // expected-error {{expected operator name in operator declaration}} infix operator ??= {} @@ -171,3 +171,28 @@ func ??= (inout result : T?, rhs : Int) { // ok } + +// [QoI] Poor diagnostic/recovery when two operators (e.g., == and -) are adjacted without spaces. +_ = n*-4 // expected-error {{missing whitespace between '*' and '-' operators}} {{6-6= }} {{7-7= }} +if n==-1 {} // expected-error {{missing whitespace between '==' and '-' operators}} {{5-5= }} {{7-7= }} + +prefix operator ☃⃠ {} +prefix func☃⃠(a : Int) -> Int { return a } +postfix operator ☃⃠ {} +postfix func☃⃠(a : Int) -> Int { return a } + +_ = n☃⃠ ☃⃠ n // Ok. +_ = n ☃⃠ ☃⃠n // Ok. +_ = n ☃⃠☃⃠ n // expected-error {{use of unresolved operator '☃⃠☃⃠'}} +_ = n☃⃠☃⃠n // expected-error {{ambiguous missing whitespace between unary and binary operators}} +// expected-note @-1 {{could be binary '☃⃠' and prefix '☃⃠'}} {{12-12= }} {{18-18= }} +// expected-note @-2 {{could be postfix '☃⃠' and binary '☃⃠'}} {{6-6= }} {{12-12= }} + +_ = n☃⃠☃⃠ // expected-error {{unary operators may not be juxtaposed; parenthesize inner expression}} +_ = ~!n // expected-error {{unary operators may not be juxtaposed; parenthesize inner expression}} +_ = -+n // expected-error {{unary operators may not be juxtaposed; parenthesize inner expression}} +_ = -++n // expected-error {{unary operators may not be juxtaposed; parenthesize inner expression}} + +// Cannot use a negative constant as the second operator of ... operator +_ = 3...-5 // expected-error {{missing whitespace between '...' and '-' operators}} + diff --git a/test/decl/overload.swift b/test/decl/overload.swift index 440a69685ff87..ced23e7f889fe 100644 --- a/test/decl/overload.swift +++ b/test/decl/overload.swift @@ -218,11 +218,11 @@ func != (lhs : T, rhs : NoneType) -> Bool { // expected-error{{invalid redecl } // -func &&(lhs: BooleanType, @autoclosure rhs: ()->BooleanType) -> Bool { // expected-note{{previously declared}} +func &&(lhs: BooleanType, @autoclosure rhs: () -> BooleanType) -> Bool { // expected-note{{previously declared}} return lhs.boolValue && rhs().boolValue } -func &&(lhs: BooleanType, @autoclosure rhs: ()->BooleanType) -> Bool { // expected-error{{invalid redeclaration of '&&'}} +func &&(lhs: BooleanType, @autoclosure rhs: () -> BooleanType) -> Bool { // expected-error{{invalid redeclaration of '&&'}} return lhs.boolValue || rhs().boolValue } diff --git a/test/decl/protocol/req/associated_type_inference.swift b/test/decl/protocol/req/associated_type_inference.swift index 3ca968ea8b0df..c1ace1753b956 100644 --- a/test/decl/protocol/req/associated_type_inference.swift +++ b/test/decl/protocol/req/associated_type_inference.swift @@ -31,7 +31,7 @@ struct X0c : P0 { // okay: Assoc1 == Int struct X0d : P0 { // okay: Assoc1 == Int func f0(_: Int) { } - func g0(_: Double) { } // viable, but no correspinding f0 + func g0(_: Double) { } // viable, but no corresponding f0 func g0(_: Int) { } } diff --git a/test/decl/protocol/req/recursion.swift b/test/decl/protocol/req/recursion.swift index 0a18a54b79d77..9dc0c00a293e0 100644 --- a/test/decl/protocol/req/recursion.swift +++ b/test/decl/protocol/req/recursion.swift @@ -14,5 +14,9 @@ public struct S> {} // rdar://problem/19840527 class X { // expected-error{{same-type requirement makes generic parameter 'T' non-generic}} - var type: T { return self.dynamicType } // expected-error{{use of undeclared type 'T'}} + var type: T { return self.dynamicType } // expected-error{{cannot convert return expression of type 'X.Type' to return type 'T'}} +} + +protocol Y { + typealias Z = Z // expected-error{{type alias 'Z' circularly references itself}} } diff --git a/test/decl/subscript/subscripting.swift b/test/decl/subscript/subscripting.swift index c932807f9cf5f..e9ed3aa05e556 100644 --- a/test/decl/subscript/subscripting.swift +++ b/test/decl/subscript/subscripting.swift @@ -228,16 +228,14 @@ struct tuple_index { struct SubscriptTest1 { - subscript(keyword:String) -> Bool { return true } // expected-note 3 {{found this candidate}} - subscript(keyword:String) -> String? {return nil } // expected-note 3 {{found this candidate}} + subscript(keyword:String) -> Bool { return true } // expected-note 2 {{found this candidate}} + subscript(keyword:String) -> String? {return nil } // expected-note 2 {{found this candidate}} } func testSubscript1(s1 : SubscriptTest1) { let _ : Int = s1["hello"] // expected-error {{ambiguous subscript with base type 'SubscriptTest1' and index type 'String'}} - // FIXME: This is a sema bug, it should not be ambiguous due to its contextual boolean type. - // rdar://18741539 - if s1["hello"] {} // expected-error {{ambiguous subscript with base type 'SubscriptTest1' and index type 'String'}} + if s1["hello"] {} let _ = s1["hello"] // expected-error {{ambiguous use of 'subscript'}} @@ -259,3 +257,29 @@ func testSubscript1(s2 : SubscriptTest2) { let b = s2[1, "foo"] // expected-error {{cannot subscript a value of type 'SubscriptTest2' with an index of type '(Int, String)'}} // expected-note @-1 {{expected an argument list of type '(String, String)'}} } + +// sr-114 & rdar://22007370 + +class Foo { + subscript(key: String) -> String { // expected-note {{'subscript' previously declared here}} + get { a } // expected-error {{use of unresolved identifier 'a'}} + set { b } // expected-error {{use of unresolved identifier 'b'}} + } + + subscript(key: String) -> String { // expected-error {{invalid redeclaration of 'subscript'}} + get { a } // expected-error {{use of unresolved identifier 'a'}} + set { b } // expected-error {{use of unresolved identifier 'b'}} + } +} + +// QoI: Subscript in protocol with missing {}, better diagnostic please +protocol r23952125 { + typealias ItemType + var count: Int { get } + subscript(index: Int) -> ItemType // expected-error {{subscript in protocol must have explicit { get } or { get set } specifier}} {{36-36= { get set \}}} + + var c : Int // expected-error {{property in protocol must have explicit { get } or { get set } specifier}} +} + + + diff --git a/test/decl/var/lazy_properties.swift b/test/decl/var/lazy_properties.swift index ba6829368cac1..c7da26462ef85 100644 --- a/test/decl/var/lazy_properties.swift +++ b/test/decl/var/lazy_properties.swift @@ -44,7 +44,7 @@ class TestClass { init() { lazy var localvar = 42 // expected-error {{lazy is only valid for members of a struct or class}} {{5-10=}} - localvar++ + localvar += 1 _ = localvar } } diff --git a/test/decl/var/properties.swift b/test/decl/var/properties.swift index 4f1117d3e10df..f17f1376570cd 100644 --- a/test/decl/var/properties.swift +++ b/test/decl/var/properties.swift @@ -110,7 +110,7 @@ var implicitGet3: Int { // Here we used apply weak to the getter itself, not to the variable. var x15: Int { - // For the purpose of this test we need to use an attribute that can not be + // For the purpose of this test we need to use an attribute that cannot be // applied to the getter. weak var foo: SomeClass? = SomeClass() // expected-warning {{variable 'foo' was written to, but never read}} @@ -1138,7 +1138,7 @@ extension rdar17391625derived { struct r19874152S1 { let number : Int = 42 } -_ = r19874152S1(number:64) // expected-error {{extra argument 'number' in call}} +_ = r19874152S1(number:64) // expected-error {{argument passed to call that takes no arguments}} _ = r19874152S1() // Ok struct r19874152S2 { @@ -1159,7 +1159,7 @@ _ = r19874152S3() // expected-error {{missing argument for parameter 'flavour' struct r19874152S4 { let number : Int? = nil } -_ = r19874152S4(number:64) // expected-error {{extra argument 'number' in call}} +_ = r19874152S4(number:64) // expected-error {{argument passed to call that takes no arguments}} _ = r19874152S4() // Ok diff --git a/test/decl/var/usage.swift b/test/decl/var/usage.swift index 5ce87625960e8..723b82499e172 100644 --- a/test/decl/var/usage.swift +++ b/test/decl/var/usage.swift @@ -12,13 +12,11 @@ func basicTests() -> Int { return y } -// expected-error@+2 {{Use of 'var' binding here is not allowed}} {{41-45=}} -// expected-error@+1 {{Use of 'var' binding here is not allowed}} {{54-58=}} +// expected-warning@+2 {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{41-45=}} +// expected-warning@+1 {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{54-58=}} func mutableParameter(a : Int, h : Int, var i : Int, var j: Int, - var g : Int) -> Int { // expected-error {{Use of 'var' binding here is not allowed}} {{8-12=}} - // expected-error@+1 {{left side of mutating operator isn't mutable: 'g' is a 'let' constant}} + var g : Int) -> Int { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{8-12=}} g += 1 - // expected-error@+1 {{cannot pass immutable value as inout argument: 'i' is a 'let' constant}} swap(&i, &j) return i+g } @@ -102,10 +100,9 @@ func testSubscript() -> [Int] { } -func testTuple(var x : Int) -> Int { // expected-error {{Use of 'var' binding here is not allowed}} {{16-19=}} +func testTuple(var x : Int) -> Int { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{16-19=}} var y : Int // Ok, stored by a tuple - // expected-error@+1 {{cannot assign to value: 'x' is a 'let' constant}} (x, y) = (1,2) return y } @@ -140,7 +137,7 @@ func testTuple() { tup.x = 1 // QoI: 'variable was never mutated' noisy when only part of a destructured tuple is mutated - var (tupA, tupB) = (1,2) // don't warn about tupB being changable to a 'let'. + var (tupA, tupB) = (1,2) // don't warn about tupB being changeable to a 'let'. tupA += tupB } @@ -166,9 +163,8 @@ protocol Fooable { mutating func mutFoo() func immutFoo() } -func testOpenExistential(var x: Fooable, // expected-error {{Use of 'var' binding here is not allowed}} {{26-29=}} +func testOpenExistential(var x: Fooable, // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{26-29=}} y: Fooable) { - // expected-error@+1 {{cannot use mutating member on immutable value}} x.mutFoo() y.immutFoo() } @@ -177,8 +173,10 @@ func testOpenExistential(var x: Fooable, // expected-error {{Use of 'var' bindin func couldThrow() throws {} func testFixitsInStatementsWithPatterns(a : Int?) { - if var b = a, // expected-error {{Use of 'var' binding here is not allowed}} {{6-9=let}} - var b2 = a { // expected-error {{Use of 'var' binding here is not allowed}} {{7-10=let}} + // FIXME: rdar://problem/23378003 + // This will eventually be an error. + if var b = a, // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{6-9=let}} + var b2 = a { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{7-10=let}} b = 1 b2 = 1 _ = b @@ -186,18 +184,24 @@ func testFixitsInStatementsWithPatterns(a : Int?) { } var g = [1,2,3].generate() - while var x = g.next() { // expected-error {{Use of 'var' binding here is not allowed}} {{9-12=let}} + // FIXME: rdar://problem/23378003 + // This will eventually be an error. + while var x = g.next() { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{9-12=let}} x = 0 _ = x } - guard var y = Optional.Some(1) else { // expected-error {{Use of 'var' binding here is not allowed}} {{9-12=let}} + // FIXME: rdar://problem/23378003 + // This will eventually be an error. + guard var y = Optional.Some(1) else { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{9-12=let}} return } y = 0 _ = y - for var b in [42] { // expected-error {{Use of 'var' binding here is not allowed}} {{7-11=}} + // FIXME: rdar://problem/23378003 + // This will eventually be an error. + for var b in [42] { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{7-11=}} b = 42 _ = b } @@ -208,14 +212,18 @@ func testFixitsInStatementsWithPatterns(a : Int?) { do { try couldThrow() - } catch var err { // expected-error {{Use of 'var' binding here is not allowed}} {{11-14=let}} + // FIXME: rdar://problem/23378003 + // This will eventually be an error. + } catch var err { // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{11-14=let}} // expected-warning@-1 {{variable 'err' was never mutated; consider changing to 'let' constant}} _ = err } switch a { - case var b: // expected-error {{Use of 'var' binding here is not allowed}} {{10-13=let}} - // expected-warning@-1 {{was never mutated; consider changing to 'let' constant}} + // FIXME: rdar://problem/23378003 + // This will eventually be an error. + case var b: // expected-warning {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{10-13=let}} + // expected-warning@-1 {{variable 'b' was never mutated; consider changing to 'let' constant}} _ = b } } diff --git a/test/expr/cast/array_coerce.swift b/test/expr/cast/array_coerce.swift index b452ccde175a8..43ce6969e5446 100644 --- a/test/expr/cast/array_coerce.swift +++ b/test/expr/cast/array_coerce.swift @@ -1,7 +1,7 @@ // RUN: %target-parse-verify-swift class C { - var x = 0; + var x = 0 } class D: C {} diff --git a/test/expr/cast/array_iteration.swift b/test/expr/cast/array_iteration.swift index c88558d034aa5..8144f955b6bdd 100644 --- a/test/expr/cast/array_iteration.swift +++ b/test/expr/cast/array_iteration.swift @@ -16,7 +16,9 @@ for view in rootView.subviews as! [View] { doFoo() } -for view:View in rootView.subviews { // expected-error{{'AnyObject' is not convertible to 'View'}} +// FIXME: Diagnostic below should be "'AnyObject' is not convertible to +// 'View'", but IUO type gets in the way of proper diagnosis. +for view:View in rootView.subviews { // expected-error{{type 'Array!' does not conform to protocol 'SequenceType'}} doFoo() } diff --git a/test/expr/closure/basic.swift b/test/expr/closure/basic.swift index 10fe3c82fcedb..800922bb5af0a 100644 --- a/test/expr/closure/basic.swift +++ b/test/expr/closure/basic.swift @@ -26,7 +26,7 @@ func variadic() { f(1, 2) f(1, 3) - let D = { (Ss ...) in 1 } // expected-error{{'...' cannot be applied to a subpattern which is not explicitly typed}}, expected-error{{unable to infer closure return type in current context}} + let D = { (Ss ...) in 1 } // expected-error{{'...' cannot be applied to a subpattern which is not explicitly typed}}, expected-error{{unable to infer closure type in the current context}} } // Closures with attributes in the parameter list. diff --git a/test/expr/closure/closures.swift b/test/expr/closure/closures.swift index a03eaf3b5e700..0c31f6dfe91f0 100644 --- a/test/expr/closure/closures.swift +++ b/test/expr/closure/closures.swift @@ -10,8 +10,8 @@ func func6c(f: (Int, Int) -> Int, _ n: Int = 0) {} // expected-warning{{prior to // from their definition. var closure1 : () -> Int = {4} // Function producing 4 whenever it is called. var closure2 : (Int,Int) -> Int = { 4 } // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{36-36= _,_ in}} -var closure3a : ()->()->(Int,Int) = {{ (4, 2) }} // multi-level closing. -var closure3b : (Int,Int)->(Int)->(Int,Int) = {{ (4, 2) }} // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{48-48=_,_ in }} +var closure3a : () -> () -> (Int,Int) = {{ (4, 2) }} // multi-level closing. +var closure3b : (Int,Int) -> (Int) -> (Int,Int) = {{ (4, 2) }} // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{52-52=_,_ in }} var closure4 : (Int,Int) -> Int = { $0 + $1 } var closure5 : (Double) -> Int = { $0 + 1.0 // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} @@ -24,7 +24,7 @@ var closure7 : Int = func funcdecl1(a: Int, _ y: Int) {} func funcdecl3() -> Int {} -func funcdecl4(a: ((Int)->Int), _ b: Int) {} +func funcdecl4(a: ((Int) -> Int), _ b: Int) {} func funcdecl5(a: Int, _ y: Int) { // Pass in a closure containing the call to funcdecl3. @@ -37,8 +37,7 @@ func funcdecl5(a: Int, _ y: Int) { var testfunc : ((), Int) -> Int - testfunc( - {$0+1}) // expected-error {{missing argument for parameter #2 in call}} + testfunc({$0+1}) // expected-error {{missing argument for parameter #2 in call}} funcdecl5(1, 2) // recursion. @@ -60,7 +59,7 @@ func funcdecl5(a: Int, _ y: Int) { func6(fn: { a,b in a+b }) // Infer incompatible type. - func6(fn: {a,b->Float in 4.0 }) // expected-error {{declared closure result 'Float' is incompatible with contextual type 'Int'}} {{19-24=Int}} // Pattern doesn't need to name arguments. + func6(fn: {a,b -> Float in 4.0 }) // expected-error {{declared closure result 'Float' is incompatible with contextual type 'Int'}} {{21-26=Int}} // Pattern doesn't need to name arguments. func6(fn: { _,_ in 4 }) func6(fn: {a,b in 4.0 }) // expected-error {{cannot convert value of type 'Double' to closure result type 'Int'}} @@ -74,7 +73,7 @@ func funcdecl5(a: Int, _ y: Int) { var fn2 = { 4 } - var c : Int = { a,b-> Int in a+b} // expected-error{{cannot convert value of type '(Int, Int) -> Int' to specified type 'Int'}} + var c : Int = { a,b -> Int in a+b} // expected-error{{cannot convert value of type '(Int, Int) -> Int' to specified type 'Int'}} } @@ -137,9 +136,9 @@ class ExplicitSelfRequiredTest { var x = 42 func method() -> Int { // explicit closure requires an explicit "self." base. - doStuff({ ++self.x }) - doStuff({ ++x }) // expected-error {{reference to property 'x' in closure requires explicit 'self.' to make capture semantics explicit}} {{17-17=self.}} - doVoidStuff({ ++x }) // expected-error {{reference to property 'x' in closure requires explicit 'self.' to make capture semantics explicit}} {{21-21=self.}} + doVoidStuff({ self.x += 1 }) + doStuff({ x+1 }) // expected-error {{reference to property 'x' in closure requires explicit 'self.' to make capture semantics explicit}} {{15-15=self.}} + doVoidStuff({ x += 1 }) // expected-error {{reference to property 'x' in closure requires explicit 'self.' to make capture semantics explicit}} {{19-19=self.}} // Methods follow the same rules as properties, uses of 'self' must be marked with "self." doStuff { method() } // expected-error {{call to method 'method' in closure requires explicit 'self.' to make capture semantics explicit}} {{15-15=self.}} @@ -158,8 +157,8 @@ class ExplicitSelfRequiredTest { } } -// expected-error@+2 {{Use of 'var' binding here is not allowed}} {{57-60=}} -// expected-warning@+1 {{'let' keyword is unnecessary; function parameters are immutable by default}} {{64-68=}} +// expected-warning@+2 {{Use of 'var' binding here is deprecated and will be removed in a future version of Swift}} {{57-60=}} +// expected-warning@+1 {{Use of 'let' binding here is deprecated and will be removed in a future version of Swift}} {{64-68=}} var testClosureArgumentPatterns: (Int, Int) -> Int = { (var x, let y) in x+y+1 } class SomeClass { @@ -245,18 +244,18 @@ func rdar19179412() -> Int -> Int { } // Test coercion of single-expression closure return types to void. -func takesVoidFunc(f: ()->()) {} +func takesVoidFunc(f: () -> ()) {} var i: Int = 1 takesVoidFunc({i}) -var f1: ()->() = {i} +var f1: () -> () = {i} var x = {return $0}(1) func returnsInt() -> Int { return 0 } takesVoidFunc(returnsInt) // expected-error {{cannot convert value of type '() -> Int' to expected argument type '() -> ()'}} -takesVoidFunc({()->Int in 0}) // expected-error {{declared closure result 'Int' is incompatible with contextual type '()'}} {{20-23=()}} +takesVoidFunc({() -> Int in 0}) // expected-error {{declared closure result 'Int' is incompatible with contextual type '()'}} {{22-25=()}} -// These used to crash the compiler, but were fixed to support the implemenation of rdar://problem/17228969 +// These used to crash the compiler, but were fixed to support the implementation of rdar://problem/17228969 Void(0) // expected-error{{argument passed to call that takes no arguments}} _ = {0} @@ -267,7 +266,7 @@ let samples = { }() // expected-error {{cannot invoke closure of type '() -> _' with an argument list of type '()'}} // Swift error: cannot capture '$0' before it is declared -func f(fp : (Bool, Bool)-> Bool) {} +func f(fp : (Bool, Bool) -> Bool) {} f { $0 && !$1 } @@ -306,7 +305,7 @@ class r22344208 { } } -var f = { (s: Undeclared)-> Int in 0 } // expected-error {{use of undeclared type 'Undeclared'}} +var f = { (s: Undeclared) -> Int in 0 } // expected-error {{use of undeclared type 'Undeclared'}} // Swift compiler crashes when using closure, declared to return illegal type. func r21375863() { diff --git a/test/expr/closure/default_args.swift b/test/expr/closure/default_args.swift index b72cc880c8c10..9949cb9945c6b 100644 --- a/test/expr/closure/default_args.swift +++ b/test/expr/closure/default_args.swift @@ -2,8 +2,8 @@ func simple_default_args() { let _ : (Int) -> Int = {(x : Int = 1) in x+1} // expected-error{{default argument is only permitted for a non-curried function parameter}} {{36-39=}} - let _ : () -> Int = {(x : Int = 1) in x+1} // expected-error{{cannot convert value of type 'Int -> Int' to specified type '() -> Int'}} expected-error {{default argument is only permitted for a non-curried function parameter}} {{33-36=}} - let _ : () -> Int = {(x : Int) in x+1} // expected-error{{cannot convert value of type 'Int -> Int' to specified type '() -> Int'}} + let _ : () -> Int = {(x : Int = 1) in x+1} // expected-error{{cannot convert value of type '(Int) -> Int' to specified type '() -> Int'}} expected-error {{default argument is only permitted for a non-curried function parameter}} {{33-36=}} + let _ : () -> Int = {(x : Int) in x+1} // expected-error{{cannot convert value of type '(Int) -> Int' to specified type '() -> Int'}} } func func_default_args() { diff --git a/test/expr/closure/trailing.swift b/test/expr/closure/trailing.swift index 23fbd0c719cdb..753e45e432f22 100644 --- a/test/expr/closure/trailing.swift +++ b/test/expr/closure/trailing.swift @@ -83,7 +83,7 @@ func labeledArgumentAndTrailingClosure() { // Trailing closure binds to last parameter, always. takeTwoFuncsWithDefaults { "Hello, " + $0 } - takeTwoFuncsWithDefaults { $0 + 1 } // expected-error {{cannot convert value of type '_ -> Int' to expected argument type '(String -> String)?'}} + takeTwoFuncsWithDefaults { $0 + 1 } // expected-error {{cannot convert value of type '(_) -> Int' to expected argument type '(String -> String)?'}} takeTwoFuncsWithDefaults(f1: {$0 + 1 }) } diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift index de47c43bbe900..dc4fe6226780e 100644 --- a/test/expr/expressions.swift +++ b/test/expr/expressions.swift @@ -448,13 +448,11 @@ func testSingleQuoteStringLiterals() { 'abc" // expected-error{{unterminated string literal}} "a'c" - // FIXME: QoI: Single-quote => double-quote string literal fixit should escape quote chars - // FIXME: The suggested replacement should un-escape the single quote - // character. - 'ab\'c' // expected-error{{single-quoted string literal found, use '"'}}{{3-10="ab\\'c"}} + 'ab\'c' // expected-error{{single-quoted string literal found, use '"'}}{{3-10="ab'c"}} - // FIXME: The suggested replacement should escape the double-quote character. - 'ab"c' // expected-error{{single-quoted string literal found, use '"'}}{{3-9="ab"c"}} + 'ab"c' // expected-error{{single-quoted string literal found, use '"'}}{{3-9="ab\\"c"}} + 'ab\"c' // expected-error{{single-quoted string literal found, use '"'}}{{3-10="ab\\"c"}} + 'ab\\"c' // expected-error{{single-quoted string literal found, use '"'}}{{3-11="ab\\\\\\"c"}} } // @@ -534,7 +532,7 @@ struct Rule { } var ruleVar: Rule -ruleVar = Rule("a") // expected-error {{cannot convert value of type 'String' to expected argument type '(target: String, dependencies: String)'}} +ruleVar = Rule("a") // expected-error {{missing argument for parameter 'dependencies' in call}} class C { @@ -544,7 +542,8 @@ class C { func method() {} } -var c = C(3) // expected-error {{cannot convert value of type 'Int' to expected argument type 'C?'}} +_ = C(3) // expected-error {{missing argument label 'other:' in call}} +_ = C(other: 3) // expected-error {{cannot convert value of type 'Int' to expected argument type 'C?'}} //===----------------------------------------------------------------------===// // Unary Operators @@ -552,17 +551,17 @@ var c = C(3) // expected-error {{cannot convert value of type 'Int' to expected func unaryOps(inout i8: Int8, inout i64: Int64) { i8 = ~i8 - ++i64 - --i8 + i64 += 1 + i8 -= 1 - ++Int64(5) // expected-error{{cannot pass immutable value to mutating operator: function call returns immutable value}} + Int64(5) += 1 // expected-error{{left side of mutating operator isn't mutable: function call returns immutable value}} // attempt to modify a 'let' variable with ++ results in typecheck error not being able to apply ++ to Float let a = i8 // expected-note {{change 'let' to 'var' to make it mutable}} {{3-6=var}} - ++a // expected-error {{cannot pass immutable value to mutating operator: 'a' is a 'let' constant}} + a += 1 // expected-error {{left side of mutating operator isn't mutable: 'a' is a 'let' constant}} var b : Int { get { }} - ++b // expected-error {{cannot pass immutable value to mutating operator: 'b' is a get-only property}} + b += 1 // expected-error {{left side of mutating operator isn't mutable: 'b' is a get-only property}} } //===----------------------------------------------------------------------===// @@ -598,7 +597,7 @@ func +-+= (inout x: Int, y: Int) -> Int { return 0} func lvalue_processing() { var i = 0 - ++i // obviously ok + i += 1 // obviously ok var fn = (+-+=) @@ -779,11 +778,11 @@ func r22211854() { func f(x: Int, _ y: Int, _ z: String = "") {} func g(x: T, _ y: T, _ z: String = "") {} - f(1) // expected-error{{cannot invoke 'f' with an argument list of type '(Int)'}} expected-note{{expected an argument list of type '(Int, Int, String)'}} - g(1) // expected-error{{cannot invoke 'g' with an argument list of type '(Int)'}} expected-note{{expected an argument list of type '(T, T, String)'}} + f(1) // expected-error{{missing argument for parameter #2 in call}} + g(1) // expected-error{{missing argument for parameter #2 in call}} func h() -> Int { return 1 } - f(h() == 1) // expected-error{{cannot invoke 'f' with an argument list of type '(Bool)'}} expected-note{{expected an argument list of type '(Int, Int, String)'}} - g(h() == 1) // expected-error{{cannot invoke 'g' with an argument list of type '(Bool)'}} expected-note{{expected an argument list of type '(T, T, String)'}} + f(h() == 1) // expected-error{{missing argument for parameter #2 in call}} + g(h() == 1) // expected-error{{missing argument for parameter #2 in call}} } // Compiler crash on invoking function with labeled defaulted param with non-labeled argument @@ -797,3 +796,35 @@ protocol P { var y: String? { get } } func r23185177(x: P?) -> [String] { return x?.y // expected-error{{cannot convert return expression of type 'String?' to return type '[String]'}} } + +// Miscompile: wrong argument parsing when calling a function in swift2.0 +func r22913570() { + func f(from: Int = 0, to: Int) {} + f(1 + 1) // expected-error{{missing argument for parameter 'to' in call}} +} + + +// Emit deprecation warnings for ++/-- in Swift 2.2 +func swift22_deprecation_increment_decrement() { + var i = 0 + var f = 1.0 + var si = "foo".startIndex + + i++ // expected-warning {{'++' is deprecated: it will be removed in Swift 3}} {{4-6= += 1}} + --i // expected-warning {{'--' is deprecated: it will be removed in Swift 3}} {{3-5=}} {{6-6= -= 1}} + _ = i++ // expected-warning {{'++' is deprecated: it will be removed in Swift 3}} + + ++f // expected-warning {{'++' is deprecated: it will be removed in Swift 3}} {{3-5=}} {{6-6= += 1}} + f-- // expected-warning {{'--' is deprecated: it will be removed in Swift 3}} {{4-6= -= 1}} + _ = f-- // expected-warning {{'--' is deprecated: it will be removed in Swift 3}} + + + ++si // expected-warning {{'++' is deprecated: it will be removed in Swift 3}} {{3-5=}} {{7-7= = si.successor()}} + --si // expected-warning {{'--' is deprecated: it will be removed in Swift 3}} {{3-5=}} {{7-7= = si.predecessor()}} + si++ // expected-warning {{'++' is deprecated: it will be removed in Swift 3}} {{5-7= = si.successor()}} + si-- // expected-warning {{'--' is deprecated: it will be removed in Swift 3}} {{5-7= = si.predecessor()}} + _ = --si // expected-warning {{'--' is deprecated: it will be removed in Swift 3}} +} + + + diff --git a/test/expr/postfix/dot/init_ref_delegation.swift b/test/expr/postfix/dot/init_ref_delegation.swift index 84cdf2401103c..2f90f6a742d3a 100644 --- a/test/expr/postfix/dot/init_ref_delegation.swift +++ b/test/expr/postfix/dot/init_ref_delegation.swift @@ -168,7 +168,7 @@ class RDar16666631 { self.init(i: i, d: 0.1, s: s) } } -let rdar16666631 = RDar16666631(i: 5, d: 6) // expected-error {{missing argument for parameter 's' in call}} +let rdar16666631 = RDar16666631(i: 5, d: 6) // expected-error {{incorrect argument label in call (have 'i:d:', expected 'i:s:')}} struct S { diff --git a/test/lit.cfg b/test/lit.cfg index 01d94428ef0af..ff997ea3dea07 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -1,14 +1,14 @@ -##===--- lit.cfg ---------------------------------------------*- Python -*-===## -## -## This source file is part of the Swift.org open source project -## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -## Licensed under Apache License v2.0 with Runtime Library Exception -## -## See http://swift.org/LICENSE.txt for license information -## See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -## -##===----------------------------------------------------------------------===## +# swift/test/lit.cfg - Configuration for the 'lit' test runner -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ----------------------------------------------------------------------------- # # This is a configuration file for the 'lit' test runner. # @@ -16,12 +16,13 @@ # # Update docs/Testing.rst when changing this file. # -##===----------------------------------------------------------------------===## +# ----------------------------------------------------------------------------- import os import platform import re import subprocess +import sys import tempfile import lit.formats @@ -31,9 +32,7 @@ import lit.util # Helper functions. # -def darwin_get_sdk_version(xcrun_sdk_name): - sdk_path = subprocess.check_output( - [ "xcrun", "--sdk", xcrun_sdk_name, "--show-sdk-path" ]).rstrip() +def darwin_get_sdk_version(sdk_path): system_version_plist_path = os.path.join( sdk_path, "System", "Library", "CoreServices", "SystemVersion.plist") name = subprocess.check_output( @@ -72,8 +71,8 @@ def darwin_get_sw_vers(commandPrefix=[]): # Returns the "prefix" command that should be prepended to the command line to # run an executable compiled for iOS or AppleTV simulator. -def get_simulator_command(run_os, xcrun_sdk_name): - (name, vers, build) = darwin_get_sdk_version(xcrun_sdk_name) +def get_simulator_command(run_os, sdk_path): + (name, vers, build) = darwin_get_sdk_version(sdk_path) if run_os == 'ios': # There are two binaries for the iOS simulator: 'sim' and 'simctl'. # 'sim' is only supported for iOS <= 8.1 and early versions of 8.2. @@ -170,13 +169,6 @@ if swift_obj_root is not None: build_mode = lit_config.params.get('build_mode', '') append_to_env_path(os.path.join(swift_obj_root, build_mode, 'bin')) - llvm_libs_dir = getattr(config, 'llvm_libs_dir', None) - if not llvm_libs_dir: - lit_config.fatal('No LLVM libs dir set!') - path = os.path.join(llvm_libs_dir, - config.environment.get('LD_LIBRARY_PATH','')) - config.environment['LD_LIBRARY_PATH'] = path - native_llvm_tools_path = lit_config.params.get('native_llvm_tools_path') if native_llvm_tools_path is not None: append_to_env_path(native_llvm_tools_path) @@ -229,7 +221,6 @@ config.inferSwiftBinary = inferSwiftBinary config.swift = inferSwiftBinary('swift') config.swiftc = inferSwiftBinary('swiftc') -config.swift_autolink_extract = inferSwiftBinary('swift-autolink-extract') config.sil_opt = inferSwiftBinary('sil-opt') config.sil_extract = inferSwiftBinary('sil-extract') config.lldb_moduleimport_test = inferSwiftBinary('lldb-moduleimport-test') @@ -241,9 +232,6 @@ config.swift_llvm_opt = inferSwiftBinary('swift-llvm-opt') config.gyb = os.path.join(config.swift_src_root, 'utils', 'gyb') config.swift_lib_dir = os.path.join(os.path.dirname(os.path.dirname(config.swift)), 'lib') -if os.path.isabs(config.swift_autolink_extract): - config.available_features.add('swift-autolink-extract') - # Find the resource directory. Assume it's near the swift compiler if not set. test_resource_dir = lit_config.params.get('test_resource_dir') if test_resource_dir: @@ -284,6 +272,7 @@ completion_cache_path = tempfile.mkdtemp(prefix="swift-testsuite-completion-cach ccp_opt = "-completion-cache-path %r" % completion_cache_path lit_config.note("Using code completion cache: " + completion_cache_path) +config.substitutions.append( ('%{python}', sys.executable) ) config.substitutions.append( ('%mcp_opt', mcp_opt) ) config.substitutions.append( ('%swift_driver_plain', "%r" % config.swift) ) config.substitutions.append( ('%swiftc_driver_plain', "%r" % config.swiftc) ) @@ -442,6 +431,19 @@ if run_vendor == 'apple': config.target_object_format = "macho" config.target_runtime = "objc" + xcrun_prefix = ( + "xcrun --toolchain %s --sdk %s" % + (config.darwin_xcrun_toolchain, config.variant_sdk)) + extra_frameworks_dir = os.path.join(config.variant_sdk, + "..", "..", "..", "Developer", "Library", "Frameworks") + target_options = ( + "-target %s %s %s" % + (config.variant_triple, resource_dir_opt, mcp_opt)) + target_options_for_mock_sdk = ( + "-target %s %s %s" % + (config.variant_triple, stdlib_resource_dir_opt, mcp_opt)) + target_options_for_mock_sdk_after = sdk_overlay_dir_opt + if 'arm' in run_cpu: raise RuntimeError('Device tests are not currently supported.') @@ -457,47 +459,16 @@ if run_vendor == 'apple': lit_config.note("Testing AppleTV simulator " + config.variant_triple) xcrun_sdk_name = "appletvsimulator" - xcrun_prefix = ( - "xcrun --toolchain XcodeDefault --sdk %s" % - (xcrun_sdk_name, )) - sdk_path = subprocess.check_output( - [ "xcrun", "--sdk", xcrun_sdk_name, "--show-sdk-path" ]).rstrip() - extra_frameworks_dir = os.path.join( - sdk_path, "..", "..", "..", "Developer", "Library", "Frameworks") - target_options = ( - "-target %s %s %s" % - (config.variant_triple, resource_dir_opt, mcp_opt)) - target_options_for_mock_sdk = ( - "-target %s %s %s" % - (config.variant_triple, stdlib_resource_dir_opt, mcp_opt)) - target_options_for_mock_sdk_after = sdk_overlay_dir_opt - target_cc_options = ( + config.target_cc_options = ( "-arch %s -m%s-simulator-version-min=%s %s" % (run_cpu, run_os, run_vers, clang_mcp_opt)) - config.target_cc_options = target_cc_options config.target_build_swift = ( "%s %s %s -F %s %s %s %s" % (xcrun_prefix, config.swiftc, target_options, extra_frameworks_dir, sdk_overlay_linker_opt, config.swift_test_options, swift_execution_tests_extra_flags)) - config.target_swift_frontend = ( - "%s -frontend %s -sdk %s %s" % - (config.swiftc, target_options, config.variant_sdk, - config.swift_test_options)) - subst_target_swift_frontend_mock_sdk = ( - "%s -frontend %s -sdk %s %s" % - (config.swiftc, target_options_for_mock_sdk, config.variant_sdk, - config.swift_test_options)) - config.target_swift_modulewrap = ( - '%s -modulewrap -target %s' % - (config.swiftc, config.variant_triple)) - subst_target_swift_frontend_mock_sdk_after = \ - target_options_for_mock_sdk_after - config.target_clang = ( - "%s clang++ %s" % - (xcrun_prefix, target_cc_options)) # FIXME: allow specification of simulator and version # # Note: don't pass '--adopt-pid' to sim. This can trigger a kernel @@ -507,24 +478,10 @@ if run_vendor == 'apple': # segmentation faults) config.target_run = ( "%s %s " % - (xcrun_prefix, get_simulator_command(run_os, xcrun_sdk_name))) - config.target_sil_opt = ( - "%s %s %s" % - (xcrun_prefix, config.sil_opt, target_options)) - config.target_swift_ide_test = ( - "%s %s %s %s" % - (xcrun_prefix, config.swift_ide_test, target_options, ccp_opt)) - subst_target_swift_ide_test_mock_sdk = ( - "%s %s %s %s" % - (xcrun_prefix, config.swift_ide_test, target_options_for_mock_sdk, ccp_opt)) - subst_target_swift_ide_test_mock_sdk_after = \ - target_options_for_mock_sdk_after - config.target_swiftc_driver = ( - "%s %s %s" % - (xcrun_prefix, config.swiftc, target_options)) + (xcrun_prefix, get_simulator_command(run_os, config.variant_sdk))) (sw_vers_name, sw_vers_vers, sw_vers_build) = \ - darwin_get_sdk_version(xcrun_sdk_name) + darwin_get_sdk_version(config.variant_sdk) if (sw_vers_name == '' or sw_vers_vers == '' or sw_vers_build == ''): lit_config.fatal('Could not get or decode sw_vers output. ' + @@ -535,48 +492,18 @@ if run_vendor == 'apple': lit_config.note("Testing OS X " + config.variant_triple) xcrun_sdk_name = "macosx" - xcrun_prefix = ( - "xcrun --toolchain XcodeDefault --sdk %s " % - (xcrun_sdk_name, )) - sdk_path = subprocess.check_output( - [ "xcrun", "--sdk", xcrun_sdk_name, "--show-sdk-path" ]).rstrip() - extra_frameworks_dir = os.path.join( - sdk_path, "..", "..", "..", "Developer", "Library", "Frameworks") - target_options = ( - "-target %s %s %s" % - (config.variant_triple, resource_dir_opt, mcp_opt)) - target_options_for_mock_sdk = ( - "-target %s %s %s" % - (config.variant_triple, stdlib_resource_dir_opt, mcp_opt)) - target_options_for_mock_sdk_after = sdk_overlay_dir_opt - target_cc_options = ( + config.target_cc_options = ( "-arch %s -m%s-version-min=%s %s" % (run_cpu, run_os, run_vers, clang_mcp_opt)) - config.target_cc_options = target_cc_options config.target_build_swift = ( "%s %s %s -F %s -Xlinker -rpath -Xlinker %s %s %s %s" % (xcrun_prefix, config.swiftc, target_options, extra_frameworks_dir, extra_frameworks_dir, sdk_overlay_linker_opt, config.swift_test_options, swift_execution_tests_extra_flags)) - config.target_swift_frontend = ( - "%s -frontend %s -sdk %s %s" % - (config.swiftc, target_options, config.variant_sdk, - config.swift_test_options)) - subst_target_swift_frontend_mock_sdk = ( - "%s -frontend %s -sdk %s %s" % - (config.swiftc, target_options_for_mock_sdk, config.variant_sdk, - config.swift_test_options)) - config.target_swift_modulewrap = ( - '%s -modulewrap -target %s' % - (config.swiftc, config.variant_triple)) - subst_target_swift_frontend_mock_sdk_after = \ - target_options_for_mock_sdk_after - config.target_clang = ( - "%s clang++ %s" % - (xcrun_prefix, target_cc_options)) config.target_run = "" + if 'interpret' in lit_config.params: target_run_base = ( xcrun_prefix + '%s %s -module-name main %s %s' @@ -587,20 +514,6 @@ if run_vendor == 'apple': config.target_run_stdlib_swift = ( "%s -Xfrontend -disable-access-control %%s" % (target_run_base)) config.available_features.add('interpret') - config.target_sil_opt = ( - "%s %s %s" % - (xcrun_prefix, config.sil_opt, target_options)) - config.target_swift_ide_test = ( - "%s %s %s %s" % - (xcrun_prefix, config.swift_ide_test, target_options, ccp_opt)) - subst_target_swift_ide_test_mock_sdk = ( - "%s %s %s %s" % - (xcrun_prefix, config.swift_ide_test, target_options_for_mock_sdk, ccp_opt)) - subst_target_swift_ide_test_mock_sdk_after = \ - target_options_for_mock_sdk_after - config.target_swiftc_driver = ( - "%s %s %s" % - (xcrun_prefix, config.swiftc, target_options)) (sw_vers_name, sw_vers_vers, sw_vers_build) = \ darwin_get_sw_vers() @@ -617,14 +530,47 @@ if run_vendor == 'apple': config.target_ld = ( "%s ld -L%s" % (xcrun_prefix, os.path.join(test_resource_dir, config.target_sdk_name))) + config.target_swift_frontend = ( + "%s -frontend %s -sdk %s %s" % + (config.swiftc, target_options, config.variant_sdk, + config.swift_test_options)) + subst_target_swift_frontend_mock_sdk = ( + "%s -frontend %s -sdk %s %s" % + (config.swiftc, target_options_for_mock_sdk, config.variant_sdk, + config.swift_test_options)) + config.target_swift_modulewrap = ( + '%s -modulewrap -target %s' % + (config.swiftc, config.variant_triple)) + subst_target_swift_frontend_mock_sdk_after = \ + target_options_for_mock_sdk_after + config.target_sil_opt = ( + "%s %s %s" % + (xcrun_prefix, config.sil_opt, target_options)) + config.target_swift_ide_test = ( + "%s %s %s %s" % + (xcrun_prefix, config.swift_ide_test, target_options, ccp_opt)) + subst_target_swift_ide_test_mock_sdk = ( + "%s %s %s %s" % + (xcrun_prefix, config.swift_ide_test, target_options_for_mock_sdk, ccp_opt)) + subst_target_swift_ide_test_mock_sdk_after = \ + target_options_for_mock_sdk_after + config.target_swiftc_driver = ( + "%s %s %s" % + (xcrun_prefix, config.swiftc, target_options)) + config.target_clang = ( + "%s clang++ %s" % + (xcrun_prefix, config.target_cc_options)) -elif run_os == 'linux-gnu': - # Linux - lit_config.note("Testing Linux " + config.variant_triple) +elif run_os == 'linux-gnu' or run_os == 'linux-gnueabihf' or run_os == 'freebsd': + # Linux/FreeBSD + if run_os == 'freebsd': + lit_config.note("Testing FreeBSD " + config.variant_triple) + else: + lit_config.note("Testing Linux " + config.variant_triple) config.target_object_format = "elf" config.target_runtime = "native" config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract") - config.target_sdk_name = "linux" + config.target_sdk_name = "freebsd" if run_os == "freebsd" else "linux" config.target_build_swift = ( '%s -target %s %s %s %s %s' % (config.swiftc, config.variant_triple, resource_dir_opt, mcp_opt, diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in index dfef7404c3497..fc0feadfc8562 100644 --- a/test/lit.site.cfg.in +++ b/test/lit.site.cfg.in @@ -16,6 +16,7 @@ config.targets_to_build = "@TARGETS_TO_BUILD@" config.variant_triple = "@VARIANT_TRIPLE@" config.variant_sdk = "@VARIANT_SDK@" config.swiftlib_dir = "@LIT_SWIFTLIB_DIR@" +config.darwin_xcrun_toolchain = "@SWIFT_DARWIN_XCRUN_TOOLCHAIN@" if "@SWIFT_ASAN_BUILD@" == "TRUE": config.available_features.add("asan") @@ -41,9 +42,6 @@ if "@SWIFT_OPTIMIZED@" == "TRUE": if "@SWIFT_HAVE_WORKING_STD_REGEX@" == "FALSE": config.available_features.add('broken_std_regex') -if "@SWIFT_BUILD_SOURCEKIT@" == "TRUE" or "@SWIFT_BUILD_SOURCEKIT@" == "ON": - config.available_features.add('sourcekit') - # Let the main config do the real work. if config.test_exec_root is None: config.test_exec_root = os.path.dirname(os.path.realpath(__file__)) diff --git a/test/sil-extract/basic.swift b/test/sil-extract/basic.swift index 0de4b11a74603..6891af78088f7 100644 --- a/test/sil-extract/basic.swift +++ b/test/sil-extract/basic.swift @@ -69,17 +69,17 @@ struct X { } class Vehicle { - var num_of_wheels: Int + var numOfWheels: Int init(n: Int) { - num_of_wheels = n + numOfWheels = n } func now() -> Int { - return num_of_wheels; + return numOfWheels } } func foo() -> Int { - return 7; + return 7 } diff --git a/test/stmt/errors.swift b/test/stmt/errors.swift index dee78099d290e..76b17cc2f5869 100644 --- a/test/stmt/errors.swift +++ b/test/stmt/errors.swift @@ -158,7 +158,7 @@ func ==(a: Thirteen, b: Thirteen) -> Bool { return true } func thirteen_helper(fn: (Thirteen) -> ()) {} func thirteen() { - thirteen_helper { (a) in // expected-error {{invalid conversion from throwing function of type '_ throws -> ()' to non-throwing function type '(Thirteen) -> ()'}} + thirteen_helper { (a) in // expected-error {{invalid conversion from throwing function of type '(_) throws -> ()' to non-throwing function type '(Thirteen) -> ()'}} do { try thrower() } catch a { diff --git a/test/stmt/statements.swift b/test/stmt/statements.swift index c3d9a04b2ceb3..0af65927154d5 100644 --- a/test/stmt/statements.swift +++ b/test/stmt/statements.swift @@ -120,23 +120,23 @@ SomeGeneric func for_loop() { var x = 0 - for ;; { } - for x = 1; x != 42; ++x { } - for infloopbooltest(); x != 12; infloopbooltest() {} + for ;; { } // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + for x = 1; x != 42; x += 1 { } // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + for infloopbooltest(); x != 12; infloopbooltest() {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} for ; { } // expected-error {{expected ';' in 'for' statement}} - for var y = 1; y != 42; ++y {} - for (var y = 1; y != 42; ++y) {} + for var y = 1; y != 42; y += 1 {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + for (var y = 1; y != 42; y += 1) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} var z = 10 - for (; z != 0; --z) {} - for (z = 10; z != 0; --z) {} - for var (a,b) = (0,12); a != b; --b {++a} - for (var (a,b) = (0,12); a != b; --b) {++a} + for (; z != 0; z -= 1) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + for (z = 10; z != 0; z -= 1) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + for var (a,b) = (0,12); a != b; b -= 1 {a += 1} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + for (var (a,b) = (0,12); a != b; b -= 1) {a += 1} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} var j, k : Int - for ((j,k) = (0,10); j != k; --k) {} - for var i = 0, j = 0; i * j < 10; i++, j++ {} - for j = 0, k = 52; j < k; ++j, --k { } + for ((j,k) = (0,10); j != k; k -= 1) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + for var i = 0, j = 0; i * j < 10; i += 1, j += 1 {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + for j = 0, k = 52; j < k; j += 1, k -= 1 { } // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} // rdar://19540536 // expected-error@+4{{expected var declaration in a 'for' statement}} // expected-error@+3{{expression resolves to an unused function}} @@ -145,7 +145,7 @@ func for_loop() { for @ {} // Is increment in for loop optional? - for (let i = 0; i < 10; ) {} + for (let i = 0; i < 10; ) {} // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} } break // expected-error {{'break' is only allowed inside a loop, if, do, or switch}} @@ -187,7 +187,7 @@ func tuple_assign() { func missing_semicolons() { var w = 321 func g() {} - g() ++w // expected-error{{consecutive statements}} {{6-6=;}} + g() w += 1 // expected-error{{consecutive statements}} {{6-6=;}} var z = w"hello" // expected-error{{consecutive statements}} {{12-12=;}} class C {}class C2 {} // expected-error{{consecutive statements}} {{14-14=;}} struct S {}struct S2 {} // expected-error{{consecutive statements}} {{14-14=;}} @@ -305,7 +305,7 @@ Loop: // expected-note {{previously declared here}} } - // Following a 'break' statment by another statement on a new line result in an error/fit-it + // Following a 'break' statement by another statement on a new line result in an error/fit-it switch 5 { case 5: markUsed("before the break") @@ -403,7 +403,7 @@ func test_is_as_patterns() { func matching_pattern_recursion() { switch 42 { case { // expected-error {{expression pattern of type '() -> ()' cannot match values of type 'Int'}} - for i in zs { // expected-error {{use of unresolved identifier 'zs'}} + for i in zs { } }: break } @@ -426,16 +426,27 @@ func testThrowNil() throws { // func for_ignored_lvalue_init() { var i = 0 - for i; // expected-error {{expression resolves to an unused l-value}} - i < 10; ++i {} + for i; // expected-error {{expression resolves to an unused l-value}} expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} + i < 10; i += 1 {} } // rdar://problem/18643692 func for_loop_multi_iter() { - for (var i = 0, x = 0; i < 10; i++, + for (var i = 0, x = 0; i < 10; i += 1, // expected-warning {{C-style for statement is deprecated and will be removed in a future version of Swift}} x) { // expected-error {{expression resolves to an unused l-value}} - --x + x -= 1 } } +// rdar://problem/23684220 +// Even if the condition fails to typecheck, save it in the AST anyway; the old +// condition may have contained a SequenceExpr. +func r23684220(b: Any) { + if let _ = b ?? b {} // expected-error {{initializer for conditional binding must have Optional type, not 'Any' (aka 'protocol<>')}} +} +// Errors in case syntax +class +case, // expected-error {{expected identifier in enum 'case' declaration}} expected-error {{expected pattern}} +case // expected-error {{expected identifier after comma in enum 'case' declaration}} expected-error {{expected identifier in enum 'case' declaration}} expected-error {{enum 'case' is not allowed outside of an enum}} expected-error {{expected pattern}} +// NOTE: EOF is important here to properly test a code path that used to crash the parser diff --git a/test/type/array.swift b/test/type/array.swift index ef9618e4cb1e9..53c2166aaae77 100644 --- a/test/type/array.swift +++ b/test/type/array.swift @@ -41,6 +41,4 @@ func constructArray(n: Int) { // Fix-Its from the old syntax to the new. typealias FixIt0 = Int[] // expected-error{{array types are now written with the brackets around the element type}}{{20-20=[}}{{23-24=}} -typealias FixIt1 = Int[][] // expected-error{{array types are now written with the brackets around the element type}}{{20-20=[}}{{25-26=}} -// expected-error@-1{{array types are now written with the brackets around the element type}}{{20-20=[}}{{23-24=}} diff --git a/test/type/dictionary.swift b/test/type/dictionary.swift index 024937331cb42..498b29f9391b8 100644 --- a/test/type/dictionary.swift +++ b/test/type/dictionary.swift @@ -32,4 +32,4 @@ var y2: [String : ] // expected-error{{expected dictionary value type}} struct NotHashable { } -var nh1 : [NotHashable : Int ] // expected-error{{'NotHashable' does not conform to protocol 'Hashable'}} +var nh1 : [NotHashable : Int] // expected-error{{'NotHashable' does not conform to protocol 'Hashable'}} diff --git a/test/type/infer/global_variables.swift b/test/type/infer/global_variables.swift index b708e470b67c8..c6cac0f24cc3b 100644 --- a/test/type/infer/global_variables.swift +++ b/test/type/infer/global_variables.swift @@ -2,7 +2,7 @@ var b = true, i = 17 -var d : Dictionary = [0 : "Zero", 1 : "One", 2 : "Two" ] +var d : Dictionary = [0 : "Zero", 1 : "One", 2 : "Two"] func testGlobals() { b = false diff --git a/test/type/infer/instance_variables.swift b/test/type/infer/instance_variables.swift index 3e9817de73711..48ae7e7384b69 100644 --- a/test/type/infer/instance_variables.swift +++ b/test/type/infer/instance_variables.swift @@ -3,7 +3,7 @@ struct X { var b = true, i = 17 - var d : Dictionary = [0 : "Zero", 1 : "One", 2 : "Two" ] + var d : Dictionary = [0 : "Zero", 1 : "One", 2 : "Two"] } func testX(inout x: X) { diff --git a/test/type/types.swift b/test/type/types.swift index 18734858e773e..9bd5626087b9f 100644 --- a/test/type/types.swift +++ b/test/type/types.swift @@ -7,13 +7,13 @@ func test() { var z : y // expected-error {{'y' is not a type}} } -var b : Int -> Int = {$0} +var b : Int -> Int = { $0 } var c2 : (field : Int) // expected-error {{cannot create a single-element tuple with an element label}}{{11-19=}} -var d2 : () -> Int = { 4} +var d2 : () -> Int = { 4 } -var d3 : () -> Float = {4 } +var d3 : () -> Float = { 4 } var d4 : () -> Int = { d2 } // expected-error{{function produces expected type 'Int'; did you mean to call it with '()'?}} {{26-26=()}} @@ -55,8 +55,6 @@ func test_array_construct(_: T) { _ = [UnsafeMutablePointer]() // Nesting. _ = [([UnsafeMutablePointer])]() _ = [(String, Float)]() - - } // default constructing an optional fails to typecheck diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 5a703581d3e2f..3acdcebe42e31 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -5,6 +5,7 @@ add_subdirectory(swift-demangle) add_subdirectory(lldb-moduleimport-test) add_subdirectory(sil-extract) add_subdirectory(swift-llvm-opt) +add_subdirectory(swift-compress) if(SWIFT_BUILD_SOURCEKIT) add_subdirectory(SourceKit) diff --git a/tools/SourceKit/README.txt b/tools/SourceKit/README.txt index 707c3b5cbb5e2..d1f2e988e878a 100644 --- a/tools/SourceKit/README.txt +++ b/tools/SourceKit/README.txt @@ -1,5 +1,5 @@ //===----------------------------------------------------------------------===// -// SourceKit README +// SourceKit README //===----------------------------------------------------------------------===// Welcome to SourceKit! SourceKit is a framework for supporting IDE features like @@ -9,7 +9,7 @@ infrastructure that an IDE needs for excellent language support. SourceKit currently only supports the Swift language. //===----------------------------------------------------------------------===// -// Linking to the SourceKit C API +// Linking to the SourceKit C API //===----------------------------------------------------------------------===// The stable C API for SourceKit is provided via the sourcekitd.framework which diff --git a/tools/SourceKit/bindings/python/sourcekitd/__init__.py b/tools/SourceKit/bindings/python/sourcekitd/__init__.py index 959ea2b6bafe3..9a642635eb619 100644 --- a/tools/SourceKit/bindings/python/sourcekitd/__init__.py +++ b/tools/SourceKit/bindings/python/sourcekitd/__init__.py @@ -1,14 +1,12 @@ -#===- __init__.py - sourcekitd Python Bindings ---------------*- python -*--===# +# __init__.py - sourcekitd Python Bindings -*- python -*- # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -# -#===------------------------------------------------------------------------===# r""" sourcekitd framework bindings diff --git a/tools/SourceKit/bindings/python/sourcekitd/capi.py b/tools/SourceKit/bindings/python/sourcekitd/capi.py index 6989c47b5361b..9113f7baa99d8 100644 --- a/tools/SourceKit/bindings/python/sourcekitd/capi.py +++ b/tools/SourceKit/bindings/python/sourcekitd/capi.py @@ -1,16 +1,29 @@ -#===- capi.py - sourcekitd Python Bindings -------------------*- python -*--===# +# capi.py - sourcekitd Python Bindings -*- python -*- # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -# -#===------------------------------------------------------------------------===# -from ctypes import * +from ctypes import ( + CFUNCTYPE, + POINTER, + Structure, + addressof, + c_bool, + c_char_p, + c_int, + c_int64, + c_size_t, + c_uint64, + c_void_p, + cdll, + py_object, + string_at, +) # ctypes doesn't implicitly convert c_void_p to the appropriate wrapper # object. This is a problem, because it means that from_parameter will see an @@ -156,7 +169,7 @@ def __init__(self, value): if value >= len(ErrorKind._kinds): ErrorKind._kinds += [None] * (value - len(ErrorKind._kinds) + 1) if ErrorKind._kinds[value] is not None: - raise ValueError,'ErrorKind already loaded' + raise ValueError('ErrorKind already loaded') self.value = value ErrorKind._kinds[value] = self ErrorKind._name_map = None @@ -177,7 +190,7 @@ def name(self): @staticmethod def from_id(id): if id >= len(ErrorKind._kinds) or ErrorKind._kinds[id] is None: - raise ValueError,'Unknown type kind %d' % id + raise ValueError('Unknown type kind {}'.format(id)) return ErrorKind._kinds[id] def __repr__(self): @@ -239,7 +252,7 @@ def __init__(self, value): if value >= len(VariantType._kinds): VariantType._kinds += [None] * (value - len(VariantType._kinds) + 1) if VariantType._kinds[value] is not None: - raise ValueError,'VariantType already loaded' + raise ValueError('VariantType already loaded') self.value = value VariantType._kinds[value] = self VariantType._name_map = None @@ -260,7 +273,7 @@ def name(self): @staticmethod def from_id(id): if id >= len(VariantType._kinds) or VariantType._kinds[id] is None: - raise ValueError,'Unknown type kind %d' % id + raise ValueError('Unknown type kind {}'.format(id)) return VariantType._kinds[id] def __repr__(self): @@ -540,7 +553,7 @@ class Config: def set_library_path(path): """Set the path in which to search for sourcekitd""" if Config.loaded: - raise Exception("library path must be set before before using " \ + raise Exception("library path must be set before before using " "any other functionalities in sourcekitd.") Config.library_path = path @@ -549,7 +562,7 @@ def set_library_path(path): def set_library_file(filename): """Set the exact location of sourcekitd""" if Config.loaded: - raise Exception("library file must be set before before using " \ + raise Exception("library file must be set before before using " "any other functionalities in sourcekitd.") Config.library_file = filename diff --git a/tools/SourceKit/bindings/python/sourcekitd/request.py b/tools/SourceKit/bindings/python/sourcekitd/request.py index 2b60cd8fc9b91..739cdc32938f6 100644 --- a/tools/SourceKit/bindings/python/sourcekitd/request.py +++ b/tools/SourceKit/bindings/python/sourcekitd/request.py @@ -1,14 +1,12 @@ -#===- request.py - sourcekitd Python Bindings ----------------*- python -*--===# +# request.py - sourcekitd Python Bindings -*- python -*- # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -# -#===------------------------------------------------------------------------===# import capi diff --git a/tools/SourceKit/docs/Protocol.txt b/tools/SourceKit/docs/Protocol.txt index 81936ee6ac8e2..8c2ae1be407da 100644 --- a/tools/SourceKit/docs/Protocol.txt +++ b/tools/SourceKit/docs/Protocol.txt @@ -173,7 +173,7 @@ response for the cursor-info request will have an entry for the module name: key.modulename: "" Also if there is already a generated-interface document for this module -previously opened, there will be an entry with the "virtual name" assosiated +previously opened, there will be an entry with the "virtual name" associated with this document (from the previous 'editor.open.interface' request): key.module_interface_name: "" diff --git a/tools/SourceKit/include/SourceKit/Core/Context.h b/tools/SourceKit/include/SourceKit/Core/Context.h index e05c28de65035..a552bcbd38c56 100644 --- a/tools/SourceKit/include/SourceKit/Core/Context.h +++ b/tools/SourceKit/include/SourceKit/Core/Context.h @@ -1,8 +1,8 @@ -//===--- Context.h - ---------------------------------------------*- C++ -*-==// +//===--- Context.h - --------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/include/SourceKit/Core/LLVM.h b/tools/SourceKit/include/SourceKit/Core/LLVM.h index 4965554c24013..449b72c740e96 100644 --- a/tools/SourceKit/include/SourceKit/Core/LLVM.h +++ b/tools/SourceKit/include/SourceKit/Core/LLVM.h @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/include/SourceKit/Core/LangSupport.h b/tools/SourceKit/include/SourceKit/Core/LangSupport.h index 5fd3a2a416317..3c95d579c3e4a 100644 --- a/tools/SourceKit/include/SourceKit/Core/LangSupport.h +++ b/tools/SourceKit/include/SourceKit/Core/LangSupport.h @@ -1,8 +1,8 @@ -//===--- LangSupport.h - -----------------------------------------*- C++ -*-==// +//===--- LangSupport.h - ----------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -258,7 +258,7 @@ struct CursorInfo { StringRef USR; StringRef TypeName; StringRef DocComment; - StringRef TypeInteface; + StringRef TypeInterface; /// Annotated XML pretty printed declaration. StringRef AnnotatedDeclaration; /// Non-empty if the symbol was imported from a clang module. diff --git a/tools/SourceKit/include/SourceKit/Core/NotificationCenter.h b/tools/SourceKit/include/SourceKit/Core/NotificationCenter.h index d19d7eeede6c0..53a0d6c7db30a 100644 --- a/tools/SourceKit/include/SourceKit/Core/NotificationCenter.h +++ b/tools/SourceKit/include/SourceKit/Core/NotificationCenter.h @@ -1,8 +1,8 @@ -//===--- NotificationCenter.h - ----------------------------------*- C++ -*-==// +//===--- NotificationCenter.h - ---------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/include/SourceKit/Support/Concurrency.h b/tools/SourceKit/include/SourceKit/Support/Concurrency.h index 6b2b645c7f9e7..e7e89e6be9bb3 100644 --- a/tools/SourceKit/include/SourceKit/Support/Concurrency.h +++ b/tools/SourceKit/include/SourceKit/Support/Concurrency.h @@ -1,8 +1,8 @@ -//===--- Concurrency.h - -----------------------------------------*- C++ -*-==// +//===--- Concurrency.h - ----------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/include/SourceKit/Support/FuzzyStringMatcher.h b/tools/SourceKit/include/SourceKit/Support/FuzzyStringMatcher.h index fcf10a5f3a257..35ad715612db6 100644 --- a/tools/SourceKit/include/SourceKit/Support/FuzzyStringMatcher.h +++ b/tools/SourceKit/include/SourceKit/Support/FuzzyStringMatcher.h @@ -1,8 +1,8 @@ -//===--- Concurrency.h - -----------------------------------------*- C++ -*-==// +//===--- FuzzyStringMatcher.h - ---------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/include/SourceKit/Support/ImmutableTextBuffer.h b/tools/SourceKit/include/SourceKit/Support/ImmutableTextBuffer.h index c91ddccd74c36..7708e5560a714 100644 --- a/tools/SourceKit/include/SourceKit/Support/ImmutableTextBuffer.h +++ b/tools/SourceKit/include/SourceKit/Support/ImmutableTextBuffer.h @@ -1,8 +1,8 @@ -//===--- ImmutableTextBuffer.h - ---------------------------------*- C++ -*-==// +//===--- ImmutableTextBuffer.h - --------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/include/SourceKit/Support/Logging.h b/tools/SourceKit/include/SourceKit/Support/Logging.h index ab7f6f8642604..7b11ee6855c2d 100644 --- a/tools/SourceKit/include/SourceKit/Support/Logging.h +++ b/tools/SourceKit/include/SourceKit/Support/Logging.h @@ -1,8 +1,8 @@ -//===- Logging.h - Logging Interface ----------------------------*- C++ -*-===// +//===--- Logging.h - Logging Interface --------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/include/SourceKit/Support/ThreadSafeRefCntPtr.h b/tools/SourceKit/include/SourceKit/Support/ThreadSafeRefCntPtr.h index 84a077d390574..35391f64a1611 100644 --- a/tools/SourceKit/include/SourceKit/Support/ThreadSafeRefCntPtr.h +++ b/tools/SourceKit/include/SourceKit/Support/ThreadSafeRefCntPtr.h @@ -1,8 +1,8 @@ -//===--- ThreadSafeRefCntPtr.h - ---------------------------------*- C++ -*-==// +//===--- ThreadSafeRefCntPtr.h - --------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/include/SourceKit/Support/Tracing.h b/tools/SourceKit/include/SourceKit/Support/Tracing.h index 986b429f69844..73455337e38fc 100644 --- a/tools/SourceKit/include/SourceKit/Support/Tracing.h +++ b/tools/SourceKit/include/SourceKit/Support/Tracing.h @@ -1,8 +1,8 @@ -//===- Tracing.h - Tracing Interface ----------------------------*- C++ -*-===// +//===--- Tracing.h - Tracing Interface --------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -67,7 +67,7 @@ class TraceConsumer { virtual ~TraceConsumer() = default; // Trace start of SourceKit operation - virtual void opertationStarted(uint64_t OpId, OperationKind OpKind, + virtual void operationStarted(uint64_t OpId, OperationKind OpKind, const SwiftInvocation &Inv, const StringPairs &OpArgs) = 0; @@ -85,9 +85,9 @@ void enable(); void disable(); // Trace start of SourceKit operation, returns OpId -uint64_t startOpertation(OperationKind OpKind, - const SwiftInvocation &Inv, - const StringPairs &OpArgs = StringPairs()); +uint64_t startOperation(OperationKind OpKind, + const SwiftInvocation &Inv, + const StringPairs &OpArgs = StringPairs()); // Operation previously started with startXXX has finished void operationFinished(uint64_t OpId); @@ -114,7 +114,7 @@ class TracedOperation final { const SwiftInvocation &Inv, const StringPairs &OpArgs = StringPairs()) { finish(); - OpId = startOpertation(OpKind, Inv, OpArgs); + OpId = startOperation(OpKind, Inv, OpArgs); } void finish() { diff --git a/tools/SourceKit/include/SourceKit/Support/UIdent.h b/tools/SourceKit/include/SourceKit/Support/UIdent.h index d4838bafe5147..3e7fa9cab0bcc 100644 --- a/tools/SourceKit/include/SourceKit/Support/UIdent.h +++ b/tools/SourceKit/include/SourceKit/Support/UIdent.h @@ -1,8 +1,8 @@ -//===--- UIdent.h - ----------------------------------------------*- C++ -*-==// +//===--- UIdent.h - ---------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/Core/Context.cpp b/tools/SourceKit/lib/Core/Context.cpp index 0f071c5f439c1..abd6c57c324a9 100644 --- a/tools/SourceKit/lib/Core/Context.cpp +++ b/tools/SourceKit/lib/Core/Context.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -17,9 +17,9 @@ using namespace SourceKit; SourceKit::Context::Context(StringRef RuntimeLibPath) - : RuntimeLibPath(RuntimeLibPath) { - NotificationCtr.reset(new NotificationCenter()); - SwiftLang = std::move(LangSupport::createSwiftLangSupport(*this)); + : RuntimeLibPath(RuntimeLibPath), + SwiftLang(LangSupport::createSwiftLangSupport(*this)), + NotificationCtr(new NotificationCenter()) { } SourceKit::Context::~Context() { diff --git a/tools/SourceKit/lib/Core/LangSupport.cpp b/tools/SourceKit/lib/Core/LangSupport.cpp index f41a0f01d1cf0..8bd23a817f31c 100644 --- a/tools/SourceKit/lib/Core/LangSupport.cpp +++ b/tools/SourceKit/lib/Core/LangSupport.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/Core/NotificationCenter.cpp b/tools/SourceKit/lib/Core/NotificationCenter.cpp index 7772c6e1cb1ed..e46f2b17e0741 100644 --- a/tools/SourceKit/lib/Core/NotificationCenter.cpp +++ b/tools/SourceKit/lib/Core/NotificationCenter.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/Support/Concurrency-Mac.cpp b/tools/SourceKit/lib/Support/Concurrency-Mac.cpp index db08860224226..95c4571e35cc4 100644 --- a/tools/SourceKit/lib/Support/Concurrency-Mac.cpp +++ b/tools/SourceKit/lib/Support/Concurrency-Mac.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/Support/FuzzyStringMatcher.cpp b/tools/SourceKit/lib/Support/FuzzyStringMatcher.cpp index efb3b02a104a9..1ccd03f08b940 100644 --- a/tools/SourceKit/lib/Support/FuzzyStringMatcher.cpp +++ b/tools/SourceKit/lib/Support/FuzzyStringMatcher.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -154,7 +154,7 @@ struct CandidateSpecificMatcher { /// Calculates the candidate's score, matching the candidate from /// \p firstPatternPos or later. /// - /// This drives drives scoreCandidateTrial by trying the possible matches. + /// This drives scoreCandidateTrial by trying the possible matches. double scoreCandidate(unsigned firstPatternPos); /// Calculates the candidate's score, matching the candidate from diff --git a/tools/SourceKit/lib/Support/ImmutableTextBuffer.cpp b/tools/SourceKit/lib/Support/ImmutableTextBuffer.cpp index df80d7d604e9f..a277f01b5c319 100644 --- a/tools/SourceKit/lib/Support/ImmutableTextBuffer.cpp +++ b/tools/SourceKit/lib/Support/ImmutableTextBuffer.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/Support/Logging.cpp b/tools/SourceKit/lib/Support/Logging.cpp index aef8166ae1471..35914a737f93e 100644 --- a/tools/SourceKit/lib/Support/Logging.cpp +++ b/tools/SourceKit/lib/Support/Logging.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/Support/ThreadSafeRefCntPtr.cpp b/tools/SourceKit/lib/Support/ThreadSafeRefCntPtr.cpp index f256acc0a6a5a..7603fc473ab0c 100644 --- a/tools/SourceKit/lib/Support/ThreadSafeRefCntPtr.cpp +++ b/tools/SourceKit/lib/Support/ThreadSafeRefCntPtr.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/Support/Tracing.cpp b/tools/SourceKit/lib/Support/Tracing.cpp index 0f5b59ee8237d..00321e871c40b 100644 --- a/tools/SourceKit/lib/Support/Tracing.cpp +++ b/tools/SourceKit/lib/Support/Tracing.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -22,16 +22,16 @@ using namespace llvm; -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // General -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// static std::atomic tracing_enabled(false); static std::atomic operation_id(0); -//----------------------------------------------------------------------------// -// Copnsumers -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// +// Consumers +//===----------------------------------------------------------------------===// struct TraceConsumerListNode { trace::TraceConsumer *const Consumer; TraceConsumerListNode *Next; @@ -39,9 +39,9 @@ struct TraceConsumerListNode { static std::atomic consumers(nullptr); -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Trace commands -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Is tracing enabled bool trace::enabled() { @@ -57,14 +57,14 @@ void trace::disable() { } // Trace start of perform sema call, returns OpId -uint64_t trace::startOpertation(trace::OperationKind OpKind, - const trace::SwiftInvocation &Inv, - const trace::StringPairs &OpArgs) { +uint64_t trace::startOperation(trace::OperationKind OpKind, + const trace::SwiftInvocation &Inv, + const trace::StringPairs &OpArgs) { auto OpId = ++operation_id; if (trace::enabled()) { auto Node = consumers.load(std::memory_order_acquire); while (Node) { - Node->Consumer->opertationStarted(OpId, OpKind, Inv, OpArgs); + Node->Consumer->operationStarted(OpId, OpKind, Inv, OpArgs); Node = Node->Next; } } diff --git a/tools/SourceKit/lib/Support/UIDRegistry.cpp b/tools/SourceKit/lib/Support/UIDRegistry.cpp index 48dd09298a22e..4c0106f9db41e 100644 --- a/tools/SourceKit/lib/Support/UIDRegistry.cpp +++ b/tools/SourceKit/lib/Support/UIDRegistry.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/CMakeLists.txt b/tools/SourceKit/lib/SwiftLang/CMakeLists.txt index 6a0b1dfcb45c4..97c9d81fae3b1 100644 --- a/tools/SourceKit/lib/SwiftLang/CMakeLists.txt +++ b/tools/SourceKit/lib/SwiftLang/CMakeLists.txt @@ -9,9 +9,9 @@ add_sourcekit_library(SourceKitSwiftLang SwiftLangSupport.cpp SwiftSourceDocInfo.cpp DEPENDS SourceKitCore swiftDriver swiftFrontend swiftClangImporter swiftIDE - swiftAST swiftMarkup swiftParse swiftSIL swiftSILGen swiftSILPasses - swiftSILPassesUtils swiftSema swiftBasic swiftSerialization - swiftSILAnalysis swiftOption cmark + swiftAST swiftMarkup swiftParse swiftSIL swiftSILGen swiftSILOptimizer + swiftSema swiftBasic swiftSerialization + swiftOption cmark # Clang dependencies. clangFormat clangToolingCore diff --git a/tools/SourceKit/lib/SwiftLang/CodeCompletion.h b/tools/SourceKit/lib/SwiftLang/CodeCompletion.h index f2455c13dfa62..877226f99ed61 100644 --- a/tools/SourceKit/lib/SwiftLang/CodeCompletion.h +++ b/tools/SourceKit/lib/SwiftLang/CodeCompletion.h @@ -1,8 +1,8 @@ -//===--- CodeCompletion.h - --------------------------------------*- C++ -*-==// +//===--- CodeCompletion.h - -------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp index db484b7c3cd0d..5f5d1f976cbd7 100644 --- a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp +++ b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -75,9 +75,9 @@ struct CodeCompletion::Group : public Item { } }; -//==========================================================================// +//===----------------------------------------------------------------------===// // extendCompletions -//==========================================================================// +//===----------------------------------------------------------------------===// std::vector SourceKit::CodeCompletion::extendCompletions( ArrayRef swiftResults, CompletionSink &sink, @@ -181,9 +181,9 @@ bool SourceKit::CodeCompletion::addCustomCompletions( return changed; } -//==========================================================================// +//===----------------------------------------------------------------------===// // CodeCompletionOrganizer::Impl declaration -//==========================================================================// +//===----------------------------------------------------------------------===// class CodeCompletionOrganizer::Impl { std::unique_ptr rootGroup; @@ -243,9 +243,9 @@ class CodeCompletionOrganizer::Impl { } }; -//==========================================================================// +//===----------------------------------------------------------------------===// // CodeCompletionOrganizer implementation -//==========================================================================// +//===----------------------------------------------------------------------===// CodeCompletionOrganizer::CodeCompletionOrganizer(const Options &options, CompletionKind kind) @@ -288,9 +288,9 @@ CodeCompletionViewRef CodeCompletionOrganizer::takeResultsView() { return impl.takeView(); } -//==========================================================================// +//===----------------------------------------------------------------------===// // ImportDepth -//==========================================================================// +//===----------------------------------------------------------------------===// ImportDepth::ImportDepth(ASTContext &context, CompilerInvocation &invocation) { llvm::DenseSet seen; @@ -352,9 +352,9 @@ ImportDepth::ImportDepth(ASTContext &context, CompilerInvocation &invocation) { } } -//==========================================================================// +//===----------------------------------------------------------------------===// // CodeCompletionOrganizer::Impl utilities -//==========================================================================// +//===----------------------------------------------------------------------===// static StringRef copyString(llvm::BumpPtrAllocator &allocator, StringRef str) { char *newStr = allocator.Allocate(str.size()); @@ -377,9 +377,9 @@ static std::unique_ptr make_result(Completion *result) { } -//==========================================================================// +//===----------------------------------------------------------------------===// // CodeCompletionOrganizer::Impl implementation -//==========================================================================// +//===----------------------------------------------------------------------===// CodeCompletionOrganizer::Impl::Impl(CompletionKind kind) : completionKind(kind) { @@ -789,9 +789,9 @@ void CodeCompletionOrganizer::Impl::groupStemsRecursive( group->contents = std::move(newContents); } -//==========================================================================// +//===----------------------------------------------------------------------===// // CodeCompletionView -//==========================================================================// +//===----------------------------------------------------------------------===// static bool walkRecursive(CodeCompletionView::Walker &walker, const Item *item) { if (auto *result = dyn_cast(item)) @@ -843,9 +843,9 @@ bool LimitedResultView::walk(CodeCompletionView::Walker &walker) const { return true; } -//==========================================================================// +//===----------------------------------------------------------------------===// // CompletionBuilder -//==========================================================================// +//===----------------------------------------------------------------------===// void CompletionBuilder::getFilterName(CodeCompletionString *str, raw_ostream &OS) { @@ -994,9 +994,9 @@ Completion *CompletionBuilder::finish() { return result; } -//==========================================================================// +//===----------------------------------------------------------------------===// // NameStyle -//==========================================================================// +//===----------------------------------------------------------------------===// NameStyle::NameStyle(StringRef name) : leadingUnderscores(0), trailingUnderscores(0) { diff --git a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h index 5aece7b26c735..001d28c24ad76 100644 --- a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h +++ b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.h @@ -1,8 +1,8 @@ -//===--- CodeCompletionOrganizer.h - -----------------------------*- C++ -*-==// +//===--- CodeCompletionOrganizer.h - ----------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp index 912b690dc154a..2fb3014a78d0f 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,7 +25,7 @@ #include "swift/Frontend/PrintingDiagnosticConsumer.h" #include "swift/Strings.h" #include "swift/Subsystems.h" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" // This is included only for createLazyResolver(). Move to different header ? #include "swift/Sema/CodeCompletionTypeChecking.h" @@ -61,9 +61,9 @@ class StreamDiagConsumer : public DiagnosticConsumer { void SwiftASTConsumer::failed(StringRef Error) { } -//============================================================================// +//===----------------------------------------------------------------------===// // SwiftInvocation -//============================================================================// +//===----------------------------------------------------------------------===// namespace { @@ -149,9 +149,9 @@ void InvocationOptions::profile(llvm::FoldingSetNodeID &ID) const { ID.AddString(PrimaryFile); } -//============================================================================// +//===----------------------------------------------------------------------===// // SwiftASTManager -//============================================================================// +//===----------------------------------------------------------------------===// namespace SourceKit { struct ASTUnit::Implementation { @@ -364,6 +364,8 @@ static void sanitizeCompilerArgs(ArrayRef Args, continue; if (Arg == "-Xfrontend") continue; + if (Arg == "-embed-bitcode") + continue; NewArgs.push_back(CArg); } } @@ -676,7 +678,7 @@ static void collectModuleDependencies(Module *TopMod, Module *Mod = Import.second; if (Mod->isSystemModule()) continue; - // FIXME: Setup dependecies on the included headers. + // FIXME: Setup dependencies on the included headers. if (ClangModuleLoader && Mod == ClangModuleLoader->getImportedHeaderModule()) continue; diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h index 644c6277e1ec7..6b3927052e642 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h +++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.h @@ -1,8 +1,8 @@ -//===--- SwiftASTManager.h - -------------------------------------*- C++ -*-==// +//===--- SwiftASTManager.h - ------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp b/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp index 2d218c76a43c9..723c3bbe2a93c 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -167,7 +167,7 @@ static bool swiftCodeCompleteImpl(SwiftLangSupport &Lang, auto swiftCache = Lang.getCodeCompletionCache(); // Pin the cache. ide::CodeCompletionContext CompletionContext(swiftCache->getCache()); - // Cerate a factory for code completion callbacks that will feed the + // Create a factory for code completion callbacks that will feed the // Consumer. std::unique_ptr CompletionCallbacksFactory( ide::makeCodeCompletionCallbacksFactory(CompletionContext, @@ -450,7 +450,7 @@ bool SwiftToSourceKitCompletionAdapter::handleResult( llvm::SmallString<64> LogMessage; llvm::raw_svector_ostream LogMessageOs(LogMessage); - LogMessageOs << "Code cpompletion result with empty name and/or " + LogMessageOs << "Code completion result with empty name and/or " "description was ignored: \n"; Result->print(LogMessageOs); @@ -634,9 +634,9 @@ void SwiftToSourceKitCompletionAdapter::getResultAssociatedUSRs( } } -//==========================================================================// +//===----------------------------------------------------------------------===// // CodeCompletion::SessionCache -//==========================================================================// +//===----------------------------------------------------------------------===// void CodeCompletion::SessionCache::setSortedCompletions( std::vector &&completions) { llvm::sys::ScopedLock L(mtx); @@ -659,9 +659,9 @@ CompletionKind CodeCompletion::SessionCache::getCompletionKind() { return completionKind; } -//==========================================================================// +//===----------------------------------------------------------------------===// // CodeCompletion::SessionCacheMap -//==========================================================================// +//===----------------------------------------------------------------------===// unsigned CodeCompletion::SessionCacheMap::getBufferID(StringRef name) const { auto pair = nameToBufferMap.insert(std::make_pair(name, nextBufferID)); @@ -691,9 +691,9 @@ bool CodeCompletion::SessionCacheMap::remove(StringRef name, unsigned offset) { return sessions.erase(key); } -//==========================================================================// +//===----------------------------------------------------------------------===// // (New) Code completion interface -//==========================================================================// +//===----------------------------------------------------------------------===// namespace { class SwiftGroupedCodeCompletionConsumer : public CodeCompletionView::Walker { diff --git a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp index e8e9716687e94..1bd817b16d53b 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -511,48 +511,33 @@ static void collectFuncEntities(std::vector &Ents, } static void addParameters(ArrayRef &ArgNames, - const Pattern *Pat, + const ParameterList *paramList, TextEntity &Ent, SourceManager &SM, unsigned BufferID) { - if (auto ParenPat = dyn_cast(Pat)) { - addParameters(ArgNames, ParenPat->getSubPattern(), Ent, SM, BufferID); - return; - } - - if (auto Tuple = dyn_cast(Pat)) { - for (const auto &Elt : Tuple->getElements()) - addParameters(ArgNames, Elt.getPattern(), Ent, SM, BufferID); - - return; - } - - StringRef Arg; - if (!ArgNames.empty()) { - Identifier Id = ArgNames.front(); - Arg = Id.empty() ? "_" : Id.str(); - ArgNames = ArgNames.slice(1); - } - - if (auto Typed = dyn_cast(Pat)) { - VarDecl *VD = nullptr; - if (auto Named = dyn_cast(Typed->getSubPattern())) { - VD = Named->getDecl(); + for (auto ¶m : *paramList) { + StringRef Arg; + if (!ArgNames.empty()) { + Identifier Id = ArgNames.front(); + Arg = Id.empty() ? "_" : Id.str(); + ArgNames = ArgNames.slice(1); } - SourceRange TypeRange = Typed->getTypeLoc().getSourceRange(); - if (auto InOutTyR = - dyn_cast_or_null(Typed->getTypeLoc().getTypeRepr())) { - TypeRange = InOutTyR->getBase()->getSourceRange(); + + if (auto typeRepr = param->getTypeLoc().getTypeRepr()) { + SourceRange TypeRange = param->getTypeLoc().getSourceRange(); + if (auto InOutTyR = dyn_cast_or_null(typeRepr)) + TypeRange = InOutTyR->getBase()->getSourceRange(); + if (TypeRange.isInvalid()) + continue; + + unsigned StartOffs = SM.getLocOffsetInBuffer(TypeRange.Start, BufferID); + unsigned EndOffs = + SM.getLocOffsetInBuffer(Lexer::getLocForEndOfToken(SM, TypeRange.End), + BufferID); + TextRange TR{ StartOffs, EndOffs-StartOffs }; + TextEntity Param(param, Arg, TR, StartOffs); + Ent.SubEntities.push_back(std::move(Param)); } - if (TypeRange.isInvalid()) - return; - unsigned StartOffs = SM.getLocOffsetInBuffer(TypeRange.Start, BufferID); - unsigned EndOffs = - SM.getLocOffsetInBuffer(Lexer::getLocForEndOfToken(SM, TypeRange.End), - BufferID); - TextRange TR{ StartOffs, EndOffs-StartOffs }; - TextEntity Param(VD, Arg, TR, StartOffs); - Ent.SubEntities.push_back(std::move(Param)); } } @@ -560,19 +545,18 @@ static void addParameters(const AbstractFunctionDecl *FD, TextEntity &Ent, SourceManager &SM, unsigned BufferID) { - auto Pats = FD->getBodyParamPatterns(); + auto params = FD->getParameterLists(); // Ignore 'self'. - if (FD->getDeclContext()->isTypeContext() && - !Pats.empty() && isa(Pats.front())) { - Pats = Pats.slice(1); - } + if (FD->getDeclContext()->isTypeContext()) + params = params.slice(1); + ArrayRef ArgNames; DeclName Name = FD->getFullName(); if (Name) { ArgNames = Name.getArgumentNames(); } - for (auto Pat : Pats) { - addParameters(ArgNames, Pat, Ent, SM, BufferID); + for (auto paramList : params) { + addParameters(ArgNames, paramList, Ent, SM, BufferID); } } diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp index 1fd79e133d73b..ff229fb1b1c3c 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -1051,6 +1051,7 @@ static Accessibility inferAccessibility(const ValueDecl *D) { case DeclContextKind::Initializer: case DeclContextKind::TopLevelCodeDecl: case DeclContextKind::AbstractFunctionDecl: + case DeclContextKind::SubscriptDecl: return Accessibility::Private; case DeclContextKind::Module: case DeclContextKind::FileUnit: @@ -1129,7 +1130,7 @@ std::vector UIDsFromDeclAttributes(const DeclAttributes &Attrs) { continue; } - // We handle accessibility explicitely. + // We handle accessibility explicitly. case DAK_Accessibility: case DAK_SetterAccessibility: continue; @@ -1783,7 +1784,7 @@ class FormatContext SM.getLineAndColumn(If->getElseLoc()).first == Line) return false; - // If we're in an DoCatchStmt and at a 'catch', don't add an indent. + // If we're in a DoCatchStmt and at a 'catch', don't add an indent. if (auto *DoCatchS = dyn_cast_or_null(Cursor->getAsStmt())) { for (CatchStmt *CatchS : DoCatchS->getCatches()) { SourceLoc Loc = CatchS->getCatchLoc(); @@ -1837,7 +1838,7 @@ class FormatWalker: public ide::SourceEntityWalker { SourceLoc &TargetLoc; TokenIt TI; - bool isImmediateAfterSeparator(SourceLoc End, tok Seperator) { + bool isImmediateAfterSeparator(SourceLoc End, tok Separator) { auto BeforeE = [&]() { return TI != Tokens.end() && !SM.isBeforeInBuffer(End, TI->getLoc()); @@ -1845,7 +1846,7 @@ class FormatWalker: public ide::SourceEntityWalker { if (!BeforeE()) return false; for (; BeforeE(); TI ++); - if (TI == Tokens.end() || TI->getKind() != Seperator) + if (TI == Tokens.end() || TI->getKind() != Separator) return false; auto SeparatorLoc = TI->getLoc(); TI ++; @@ -1910,12 +1911,10 @@ class FormatWalker: public ide::SourceEntityWalker { } // Function parameters are siblings. - for (auto P : AFD->getBodyParamPatterns()) { - if (auto TU = dyn_cast(P)) { - for (unsigned I = 0, N = TU->getNumElements(); I < N; I ++) { - addPair(TU->getElement(I).getPattern()->getEndLoc(), - FindAlignLoc(TU->getElement(I).getLabelLoc()), tok::comma); - } + for (auto P : AFD->getParameterLists()) { + for (auto param : *P) { + addPair(param->getEndLoc(), + FindAlignLoc(param->getStartLoc()), tok::comma); } } } @@ -2594,6 +2593,13 @@ void SwiftEditorDocument::formatText(unsigned Line, unsigned Length, Consumer.recordAffectedLineRange(LineRange.startLine(), LineRange.lineCount()); } +bool isReturningVoid(SourceManager &SM, CharSourceRange Range) { + if (Range.isInvalid()) + return false; + StringRef Text = SM.extractText(Range); + return "()" == Text || "Void" == Text; +} + void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length, EditorConsumer &Consumer) { auto SyntaxInfo = Impl.getSyntaxInfo(); @@ -2656,7 +2662,7 @@ void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length, // For example: // foo.bar(a, <#closure#>) turns into foo.bar(a) <#closure#>. - // If the preceeding token in the call is the leading parameter + // If the preceding token in the call is the leading parameter // separator, we'll expand replacement to cover that. assert(Elems.size() > 1); SourceLoc BeforeLoc = Lexer::getLocForEndOfToken(SM, @@ -2672,8 +2678,7 @@ void SwiftEditorDocument::expandPlaceholder(unsigned Offset, unsigned Length, OS << "{ "; - bool ReturningVoid = ClosureReturnTypeRange.isValid() && - "Void" == SM.extractText(ClosureReturnTypeRange); + bool ReturningVoid = isReturningVoid(SM, ClosureReturnTypeRange); bool HasSignature = !ClosureParams.empty() || (ClosureReturnTypeRange.isValid() && !ReturningVoid); @@ -2801,9 +2806,9 @@ void SwiftEditorDocument::reportDocumentStructure(swift::SourceFile &SrcFile, ModelContext.walk(Walker); } -//============================================================================// +//===----------------------------------------------------------------------===// // EditorOpen -//============================================================================// +//===----------------------------------------------------------------------===// void SwiftLangSupport::editorOpen(StringRef Name, llvm::MemoryBuffer *Buf, bool EnableSyntaxMap, @@ -2819,7 +2824,7 @@ void SwiftLangSupport::editorOpen(StringRef Name, llvm::MemoryBuffer *Buf, EditorDoc->parse(Snapshot, *this); if (EditorDocuments.getOrUpdate(Name, *this, EditorDoc)) { // Document already exists, re-initialize it. This should only happen - // if we get OPEN request while the prevous document is not closed. + // if we get OPEN request while the previous document is not closed. LOG_WARN_FUNC("Document already exists in editorOpen(..): " << Name); Snapshot = nullptr; } @@ -2839,9 +2844,9 @@ void SwiftLangSupport::editorOpen(StringRef Name, llvm::MemoryBuffer *Buf, } -//============================================================================// +//===----------------------------------------------------------------------===// // EditorClose -//============================================================================// +//===----------------------------------------------------------------------===// void SwiftLangSupport::editorClose(StringRef Name, bool RemoveCache) { auto Removed = EditorDocuments.remove(Name); @@ -2853,9 +2858,9 @@ void SwiftLangSupport::editorClose(StringRef Name, bool RemoveCache) { } -//============================================================================// +//===----------------------------------------------------------------------===// // EditorReplaceText -//============================================================================// +//===----------------------------------------------------------------------===// void SwiftLangSupport::editorReplaceText(StringRef Name, llvm::MemoryBuffer *Buf, unsigned Offset, unsigned Length, @@ -2881,9 +2886,9 @@ void SwiftLangSupport::editorReplaceText(StringRef Name, llvm::MemoryBuffer *Buf } -//============================================================================// +//===----------------------------------------------------------------------===// // EditorFormatText -//============================================================================// +//===----------------------------------------------------------------------===// void SwiftLangSupport::editorApplyFormatOptions(StringRef Name, OptionsDictionary &FmtOptions) { auto EditorDoc = EditorDocuments.getByUnresolvedName(Name); @@ -2908,9 +2913,9 @@ void SwiftLangSupport::editorExtractTextFromComment(StringRef Source, Consumer.handleSourceText(extractPlainTextFromComment(Source)); } -//============================================================================// +//===----------------------------------------------------------------------===// // EditorExpandPlaceholder -//============================================================================// +//===----------------------------------------------------------------------===// void SwiftLangSupport::editorExpandPlaceholder(StringRef Name, unsigned Offset, unsigned Length, EditorConsumer &Consumer) { diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditorDiagConsumer.h b/tools/SourceKit/lib/SwiftLang/SwiftEditorDiagConsumer.h index 10c314270e0dc..5e36df8a4f8f7 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftEditorDiagConsumer.h +++ b/tools/SourceKit/lib/SwiftLang/SwiftEditorDiagConsumer.h @@ -1,8 +1,8 @@ -//===--- SwiftEditorDiagConsumer.h - -----------------------------*- C++ -*-==// +//===--- SwiftEditorDiagConsumer.h - ----------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/SwiftEditorInterfaceGen.cpp b/tools/SourceKit/lib/SwiftLang/SwiftEditorInterfaceGen.cpp index c52f101bd5208..c74bf4615fa6f 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftEditorInterfaceGen.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftEditorInterfaceGen.cpp @@ -1,8 +1,8 @@ -//===--- SwiftEditorIntefaceGen.cpp ---------------------------------------===// +//===--- SwiftEditorInterfaceGen.cpp --------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -542,9 +542,9 @@ SwiftInterfaceGenMap::find(StringRef ModuleName, return nullptr; } -//============================================================================// +//===----------------------------------------------------------------------===// // EditorOpenInterface -//============================================================================// +//===----------------------------------------------------------------------===// void SwiftLangSupport::editorOpenInterface(EditorConsumer &Consumer, StringRef Name, diff --git a/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp b/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp index 1a6357744b658..a31bce4644396 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -725,15 +725,11 @@ static bool isTestCandidate(ValueDecl *D) { if (!NTD) return false; Type RetTy = FD->getResultType(); - if (FD->getBodyParamPatterns().size() != 2) + if (FD->getParameterLists().size() != 2) return false; - TuplePattern *ArgP = dyn_cast(FD->getBodyParamPatterns()[1]); - if (!ArgP) - return false; - if (RetTy && RetTy->isVoid() && - isa(NTD) && - ArgP->getNumElements() == 0 && - FD->getName().str().startswith("test")) + auto paramList = FD->getParameterList(1); + if (RetTy && RetTy->isVoid() && isa(NTD) && + paramList->size() == 0 && FD->getName().str().startswith("test")) return true; } @@ -1009,9 +1005,9 @@ static void indexModule(llvm::MemoryBuffer *Input, } -//============================================================================// +//===----------------------------------------------------------------------===// // IndexSource -//============================================================================// +//===----------------------------------------------------------------------===// void trace::initTraceInfo(trace::SwiftInvocation &SwiftArgs, StringRef InputFile, diff --git a/tools/SourceKit/lib/SwiftLang/SwiftInterfaceGenContext.h b/tools/SourceKit/lib/SwiftLang/SwiftInterfaceGenContext.h index 3c8ae185a788f..13c4aea56c887 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftInterfaceGenContext.h +++ b/tools/SourceKit/lib/SwiftLang/SwiftInterfaceGenContext.h @@ -1,8 +1,8 @@ -//===--- SwiftInterfaceGenContext.h - ----------------------------*- C++ -*-==// +//===--- SwiftInterfaceGenContext.h - ---------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/SwiftInvocation.h b/tools/SourceKit/lib/SwiftLang/SwiftInvocation.h index 39325eb068a3d..f9170a47872e1 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftInvocation.h +++ b/tools/SourceKit/lib/SwiftLang/SwiftInvocation.h @@ -1,8 +1,8 @@ -//===--- SwiftInvocation.h - -------------------------------------*- C++ -*-==// +//===--- SwiftInvocation.h - ------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp index c5ade1de03308..0062067d0932b 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h index 8a44a6827ae0a..459b6279768b9 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h +++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h @@ -1,8 +1,8 @@ -//===--- SwiftLangSupport.h - ------------------------------------*- C++ -*-==// +//===--- SwiftLangSupport.h - -----------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp index 8361690fd482a..d4e8d7a1f9539 100644 --- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp +++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -99,9 +99,9 @@ void walkRelatedDecls(const ValueDecl *VD, const FnTy &Fn) { } } -//============================================================================// +//===----------------------------------------------------------------------===// // SwiftLangSupport::getCursorInfo -//============================================================================// +//===----------------------------------------------------------------------===// static StringRef getSourceToken(unsigned Offset, ImmutableTextSnapshotRef Snap) { @@ -391,8 +391,8 @@ static bool passCursorInfoForDecl(const ValueDecl *VD, Info.OverrideUSRs = OverUSRs; Info.AnnotatedRelatedDeclarations = AnnotatedRelatedDecls; Info.IsSystem = IsSystem; - Info.TypeInteface = ASTPrinter::printTypeInterface(Ty, VD->getDeclContext(), - TypeInterface) ? + Info.TypeInterface = ASTPrinter::printTypeInterface(Ty, VD->getDeclContext(), + TypeInterface) ? StringRef(TypeInterface) : StringRef(); Receiver(Info); return false; @@ -562,7 +562,7 @@ void SwiftLangSupport::getCursorInfo( if (trace::enabled()) { trace::SwiftInvocation SwiftArgs; trace::initTraceInfo(SwiftArgs, InputFile, Args); - // Do we nedd to record any files? If yes -- which ones? + // Do we need to record any files? If yes -- which ones? trace::StringPairs OpArgs { std::make_pair("DocumentName", IFaceGenRef->getDocumentName()), std::make_pair("ModuleOrHeaderName", IFaceGenRef->getModuleOrHeaderName()), @@ -605,9 +605,9 @@ void SwiftLangSupport::getCursorInfo( Receiver); } -//============================================================================// +//===----------------------------------------------------------------------===// // SwiftLangSupport::findUSRRange -//============================================================================// +//===----------------------------------------------------------------------===// llvm::Optional> SwiftLangSupport::findUSRRange(StringRef DocumentName, StringRef USR) { @@ -619,9 +619,9 @@ SwiftLangSupport::findUSRRange(StringRef DocumentName, StringRef USR) { return None; } -//============================================================================// +//===----------------------------------------------------------------------===// // SwiftLangSupport::findRelatedIdentifiersInFile -//============================================================================// +//===----------------------------------------------------------------------===// namespace { class RelatedIdScanner : public ide::SourceEntityWalker { diff --git a/tools/SourceKit/tools/complete-test/complete-test.cpp b/tools/SourceKit/tools/complete-test/complete-test.cpp index 41528ffa41937..16facf000b9da 100644 --- a/tools/SourceKit/tools/complete-test/complete-test.cpp +++ b/tools/SourceKit/tools/complete-test/complete-test.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd-repl/sourcekitd-repl.cpp b/tools/SourceKit/tools/sourcekitd-repl/sourcekitd-repl.cpp index b120c980b8d93..e814b17e8b2f0 100644 --- a/tools/SourceKit/tools/sourcekitd-repl/sourcekitd-repl.cpp +++ b/tools/SourceKit/tools/sourcekitd-repl/sourcekitd-repl.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd-test/Options.td b/tools/SourceKit/tools/sourcekitd-test/Options.td index 24c69fea04ac9..366163df4b998 100644 --- a/tools/SourceKit/tools/sourcekitd-test/Options.td +++ b/tools/SourceKit/tools/sourcekitd-test/Options.td @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp index d03490b32359c..76e67da1bb3e6 100644 --- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp +++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd-test/TestOptions.h b/tools/SourceKit/tools/sourcekitd-test/TestOptions.h index 1b1d8842d50a9..3db1bed5a87ad 100644 --- a/tools/SourceKit/tools/sourcekitd-test/TestOptions.h +++ b/tools/SourceKit/tools/sourcekitd-test/TestOptions.h @@ -1,8 +1,8 @@ -//===--- TestOptions.h - -----------------------------------------*- C++ -*-==// +//===--- TestOptions.h - ----------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp index 9305dcde8a4b7..c89a47d648458 100644 --- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp +++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp b/tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp index a4f85eea072b0..d5ee3b29e4668 100644 --- a/tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp +++ b/tools/SourceKit/tools/sourcekitd/bin/InProc/sourcekitdInProc.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -79,7 +79,7 @@ UIdent sourcekitd::UIdentFromSKDUID(sourcekitd_uid_t uid) { } std::string sourcekitd::getRuntimeLibPath() { - // FIXME: Move to a llvm API. Note that libclang does the same thing. + // FIXME: Move to an LLVM API. Note that libclang does the same thing. #ifdef LLVM_ON_WIN32 #error Not implemented #else @@ -97,9 +97,9 @@ void sourcekitd::set_interrupted_connection_handler( sourcekitd_interrupted_connection_handler_t handler) { } -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // sourcekitd_request_sync -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// sourcekitd_response_t sourcekitd_send_request_sync(sourcekitd_object_t req) { dispatch_semaphore_t sema = dispatch_semaphore_create(0); diff --git a/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp b/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp index 738540637531c..0e4191f43266c 100644 --- a/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp +++ b/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -108,9 +108,9 @@ sourcekitd_set_notification_handler(sourcekitd_response_receiver_t receiver) { }); } -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // sourcekitd_request_sync -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// static xpc_connection_t getGlobalConnection(); @@ -455,7 +455,7 @@ static void handleInterruptedConnection(xpc_object_t event, xpc_connection_t con sendNotification(event); // Retain connection while we try to ping it. - // Since this happens implicitely, we can't blame the client if it shutsdown + // Since this happens implicitly, we can't blame the client if it shuts down // while we are trying to ping. pingService((xpc_connection_t)xpc_retain(conn)); } diff --git a/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/tracer.cpp b/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/tracer.cpp index 1dd0f6f48e144..e7be374428390 100644 --- a/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/tracer.cpp +++ b/tools/SourceKit/tools/sourcekitd/bin/XPC/Client/tracer.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -38,9 +38,9 @@ using namespace sourcekitd; -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Generic -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// static std::string trace_root_dir; @@ -150,9 +150,9 @@ struct llvm::yaml::MappingTraits> { -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // State -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// class State { typedef std::map OperationsType; @@ -307,9 +307,9 @@ void State::persist() { -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Init & trace -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// void initializeTracing() { const char *EnvOpt = ::getenv("SOURCEKIT_TRACE_ROOT"); diff --git a/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XPCService.cpp b/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XPCService.cpp index 12ce78679652b..aa58c31f1a4ec 100644 --- a/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XPCService.cpp +++ b/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XPCService.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XpcTracing.cpp b/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XpcTracing.cpp index 0ba4ef44c1519..d64dba2d7b568 100644 --- a/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XpcTracing.cpp +++ b/tools/SourceKit/tools/sourcekitd/bin/XPC/Service/XpcTracing.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,9 +25,9 @@ using namespace llvm; -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // General -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// static std::atomic operation_id(0); static uint64_t tracing_session = llvm::sys::TimeValue::now().msec(); @@ -81,7 +81,7 @@ struct llvm::yaml::MappingTraits { }; static std::string serializeCompilerArguments(const SwiftArguments &Args) { - // Serialize comiler instance + // Serialize compiler instance std::string OptionsAsYaml; llvm::raw_string_ostream OptionsStream(OptionsAsYaml); llvm::yaml::Output YamlOutput(OptionsStream); @@ -92,9 +92,9 @@ static std::string serializeCompilerArguments(const SwiftArguments &Args) { -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// // Trace consumer -//----------------------------------------------------------------------------// +//===----------------------------------------------------------------------===// class XpcTraceConsumer : public SourceKit::trace::TraceConsumer { public: @@ -104,16 +104,16 @@ class XpcTraceConsumer : public SourceKit::trace::TraceConsumer { virtual void operationFinished(uint64_t OpId) override; // Trace start of SourceKit operation - virtual void opertationStarted(uint64_t OpId, OperationKind OpKind, - const SwiftInvocation &Inv, - const StringPairs &OpArgs) override; + virtual void operationStarted(uint64_t OpId, OperationKind OpKind, + const SwiftInvocation &Inv, + const StringPairs &OpArgs) override; }; // Trace start of SourceKit operation -void XpcTraceConsumer::opertationStarted(uint64_t OpId, - OperationKind OpKind, - const SwiftInvocation &Inv, - const StringPairs &OpArgs) { +void XpcTraceConsumer::operationStarted(uint64_t OpId, + OperationKind OpKind, + const SwiftInvocation &Inv, + const StringPairs &OpArgs) { xpc_object_t Contents = xpc_array_create(nullptr, 0); append(Contents, ActionKind::OperationStarted); append(Contents, OpId); diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/CodeCompletionResultsArray.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/CodeCompletionResultsArray.h index c0e6e46dda22d..0c8f86459d525 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/CodeCompletionResultsArray.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/CodeCompletionResultsArray.h @@ -1,8 +1,8 @@ -//===--- CodeCompletionResultsArray.h - --------------------------*- C++ -*-==// +//===--- CodeCompletionResultsArray.h - -------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/CompactArray.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/CompactArray.h index 57b6fbdba66bc..23f24c945673e 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/CompactArray.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/CompactArray.h @@ -1,8 +1,8 @@ -//===--- CompactArray.h - ----------------------------------------*- C++ -*-==// +//===--- CompactArray.h - ---------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/DocSupportAnnotationArray.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/DocSupportAnnotationArray.h index c717c757b5150..737c79ae5c222 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/DocSupportAnnotationArray.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/DocSupportAnnotationArray.h @@ -1,8 +1,8 @@ -//===--- DocSupportAnnotationArray.h - ---------------------------*- C++ -*-==// +//===--- DocSupportAnnotationArray.h - --------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal-XPC.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal-XPC.h index 7c980919ebe62..0d83d74e6a39b 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal-XPC.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal-XPC.h @@ -1,8 +1,8 @@ -//===--- Internal-XPC.h - ----------------------------------------*- C++ -*-==// +//===--- Internal-XPC.h - ---------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h index 67b7b62573d66..3601578c0d64d 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h @@ -1,8 +1,8 @@ -//===--- Internal.h - --------------------------------------------*- C++ -*-==// +//===--- Internal.h - -------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Logging.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Logging.h index 2d4659657c19b..e7caf628a8741 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Logging.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/Logging.h @@ -1,8 +1,8 @@ -//===--- Logging.h - ---------------------------------------------*- C++ -*-==// +//===--- Logging.h - --------------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/TokenAnnotationsArray.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/TokenAnnotationsArray.h index f65a59e0e9561..e2272106a5869 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/TokenAnnotationsArray.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/TokenAnnotationsArray.h @@ -1,8 +1,8 @@ -//===--- TokenAnnotationsArray.h - -------------------------------*- C++ -*-==// +//===--- TokenAnnotationsArray.h - ------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/XpcTracing.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/XpcTracing.h index 8dc01e4954397..0a8927559e958 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/XpcTracing.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/XpcTracing.h @@ -1,8 +1,8 @@ -//===- XpcTracing.h - XPC-side Tracing Interface ----------------*- C++ -*-===// +//===--- XpcTracing.h - XPC-side Tracing Interface --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/sourcekitd.h b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/sourcekitd.h index 1a91a8638534e..5e9b8851bfa2c 100644 --- a/tools/SourceKit/tools/sourcekitd/include/sourcekitd/sourcekitd.h +++ b/tools/SourceKit/tools/sourcekitd/include/sourcekitd/sourcekitd.h @@ -1,8 +1,8 @@ -//===--- sourcekitd.h - ------------------------------------------*- C++ -*-==// +//===--- sourcekitd.h - -----------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -122,7 +122,7 @@ typedef void(^sourcekitd_interrupted_connection_handler_t)(void); /** * \brief Sets the handler which should be called whenever the connection to - * SourceKit is interupted. + * SourceKit is interrupted. * * The handler should reestablish any necessary state, such as re-opening any * documents which were open before the connection was interrupted. diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp index e00e731e246d2..072398eda84eb 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp +++ b/tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/CompactArray.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/CompactArray.cpp index 1a8dd3ac82438..7cde45a5e36c8 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/API/CompactArray.cpp +++ b/tools/SourceKit/tools/sourcekitd/lib/API/CompactArray.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/DictionaryKeys.h b/tools/SourceKit/tools/sourcekitd/lib/API/DictionaryKeys.h index 88403e21aae0e..9517629857aec 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/API/DictionaryKeys.h +++ b/tools/SourceKit/tools/sourcekitd/lib/API/DictionaryKeys.h @@ -1,8 +1,8 @@ -//===--- DictionaryKeys.h - --------------------------------------*- C++ -*-==// +//===--- DictionaryKeys.h - -------------------------------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/DocSupportAnnotationArray.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/DocSupportAnnotationArray.cpp index 488a0eb5c4d59..06498e3dcc8af 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/API/DocSupportAnnotationArray.cpp +++ b/tools/SourceKit/tools/sourcekitd/lib/API/DocSupportAnnotationArray.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp index 0fc82bb0a3653..ce1801a749fc2 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp +++ b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -625,9 +625,9 @@ handleSemanticRequest(RequestDict Req, return Rec(createErrorRequestInvalid(ErrBuf.c_str())); } -//============================================================================// +//===----------------------------------------------------------------------===// // Index -//============================================================================// +//===----------------------------------------------------------------------===// namespace { class SKIndexingConsumer : public IndexingConsumer { @@ -667,6 +667,7 @@ class SKIndexingConsumer : public IndexingConsumer { ~SKIndexingConsumer() { assert(Cancelled || (EntitiesStack.size() == 1 && DependenciesStack.size() == 1)); + (void) Cancelled; } void failed(StringRef ErrDescription) override; @@ -815,13 +816,14 @@ bool SKIndexingConsumer::recordRelatedEntity(const EntityInfo &Info) { bool SKIndexingConsumer::finishSourceEntity(UIdent Kind) { Entity &CurrEnt = EntitiesStack.back(); assert(CurrEnt.Kind == Kind); + (void) CurrEnt; EntitiesStack.pop_back(); return true; } -//============================================================================// +//===----------------------------------------------------------------------===// // ReportDocInfo -//============================================================================// +//===----------------------------------------------------------------------===// namespace { @@ -865,6 +867,7 @@ class SKDocConsumer : public DocInfoConsumer { } ~SKDocConsumer() { assert(Cancelled || EntitiesStack.size() == 1); + (void) Cancelled; } sourcekitd_response_t createResponse() { @@ -1036,6 +1039,7 @@ bool SKDocConsumer::handleAvailableAttribute(const AvailableAttrInfo &Info) { bool SKDocConsumer::finishSourceEntity(UIdent Kind) { Entity &CurrEnt = EntitiesStack.back(); assert(CurrEnt.Kind == Kind); + (void) CurrEnt; EntitiesStack.pop_back(); return true; } @@ -1071,9 +1075,9 @@ bool SKDocConsumer::handleDiagnostic(const DiagnosticEntryInfo &Info) { return true; } -//============================================================================// +//===----------------------------------------------------------------------===// // ReportCursorInfo -//============================================================================// +//===----------------------------------------------------------------------===// static void reportCursorInfo(StringRef Filename, int64_t Offset, @@ -1125,16 +1129,16 @@ static void reportCursorInfo(StringRef Filename, } if (Info.IsSystem) Elem.setBool(KeyIsSystem, true); - if (!Info.TypeInteface.empty()) - Elem.set(KeyTypeInterface, Info.TypeInteface); + if (!Info.TypeInterface.empty()) + Elem.set(KeyTypeInterface, Info.TypeInterface); return Rec(RespBuilder.createResponse()); }); } -//============================================================================// +//===----------------------------------------------------------------------===// // FindRelatedIdents -//============================================================================// +//===----------------------------------------------------------------------===// static void findRelatedIdents(StringRef Filename, int64_t Offset, @@ -1158,9 +1162,9 @@ static void findRelatedIdents(StringRef Filename, }); } -//============================================================================// +//===----------------------------------------------------------------------===// // CodeComplete -//============================================================================// +//===----------------------------------------------------------------------===// namespace { class SKCodeCompletionConsumer : public CodeCompletionConsumer { @@ -1233,9 +1237,9 @@ bool SKCodeCompletionConsumer::handleResult(const CodeCompletionInfo &R) { } -//============================================================================// +//===----------------------------------------------------------------------===// // (New) CodeComplete -//============================================================================// +//===----------------------------------------------------------------------===// namespace { class SKGroupedCodeCompletionConsumer : public GroupedCodeCompletionConsumer { @@ -1303,7 +1307,7 @@ static sourcekitd_response_t codeCompleteOpen(StringRef Name, SKGroupedCodeCompletionConsumer CCC(RespBuilder); std::unique_ptr options; if (optionsDict) - options = std::move(llvm::make_unique(*optionsDict)); + options = llvm::make_unique(*optionsDict); LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); Lang.codeCompleteOpen(Name, InputBuf, Offset, options.get(), CCC, Args); return CCC.createResponse(); @@ -1324,7 +1328,7 @@ codeCompleteUpdate(StringRef name, int64_t offset, SKGroupedCodeCompletionConsumer CCC(RespBuilder); std::unique_ptr options; if (optionsDict) - options = std::move(llvm::make_unique(*optionsDict)); + options = llvm::make_unique(*optionsDict); LangSupport &Lang = getGlobalContext().getSwiftLangSupport(); Lang.codeCompleteUpdate(name, offset, options.get(), CCC); return CCC.createResponse(); @@ -1413,9 +1417,9 @@ void SKGroupedCodeCompletionConsumer::setNextRequestStart(unsigned offset) { Response.set(KeyNextRequestStart, offset); } -//============================================================================// +//===----------------------------------------------------------------------===// // Editor -//============================================================================// +//===----------------------------------------------------------------------===// namespace { class SKEditorConsumer : public EditorConsumer { diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/TokenAnnotationsArray.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/TokenAnnotationsArray.cpp index 7f7d809ee97fd..d5809f785ab87 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/API/TokenAnnotationsArray.cpp +++ b/tools/SourceKit/tools/sourcekitd/lib/API/TokenAnnotationsArray.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-Common.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-Common.cpp index 10079a3d05f99..9bb6f51be4e2c 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-Common.cpp +++ b/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-Common.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -393,9 +393,9 @@ void sourcekitd::enableLogging(StringRef LoggerName) { Logger::enableLogging(LoggerName, LogLevel); } -//============================================================================// +//===----------------------------------------------------------------------===// // Public API -//============================================================================// +//===----------------------------------------------------------------------===// static llvm::sys::Mutex GlobalInitMtx; static unsigned gInitRefCount = 0; @@ -452,9 +452,9 @@ sourcekitd_response_description_copy(sourcekitd_response_t resp) { return strdup(Desc.c_str()); } -//============================================================================// +//===----------------------------------------------------------------------===// // Variant API -//============================================================================// +//===----------------------------------------------------------------------===// #define VAR_FN(var, name) ((var).data[0] ? \ ((VariantFunctions*)(var).data[0])->name : nullptr) diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-XPC.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-XPC.cpp index c8cf5b5f5b234..1fadc2dbd12db 100644 --- a/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-XPC.cpp +++ b/tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-XPC.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -200,9 +200,9 @@ void sourcekitd::printRequestObject(sourcekitd_object_t Obj, raw_ostream &OS) { SKDObjectPrinter(OS).visit(Obj); } -//============================================================================// +//===----------------------------------------------------------------------===// // Internal API -//============================================================================// +//===----------------------------------------------------------------------===// ResponseBuilder::ResponseBuilder() { Impl = xpc_dictionary_create(nullptr, nullptr, 0); @@ -412,9 +412,9 @@ sourcekitd::createErrorRequestCancelled() { return CustomXPCData::createErrorRequestCancelled("").getXObj(); } -//============================================================================// +//===----------------------------------------------------------------------===// // Public API -//============================================================================// +//===----------------------------------------------------------------------===// sourcekitd_uid_t sourcekitd_uid_get_from_cstr(const char *string) { @@ -438,9 +438,9 @@ sourcekitd_uid_get_string_ptr(sourcekitd_uid_t uid) { return UID.getName().begin(); } -//============================================================================// +//===----------------------------------------------------------------------===// // Public Request API -//============================================================================// +//===----------------------------------------------------------------------===// static inline const char *strFromUID(sourcekitd_uid_t uid) { return UIdentFromSKDUID(uid).c_str(); @@ -572,9 +572,9 @@ sourcekitd_request_description_copy(sourcekitd_object_t obj) { return strdup(Desc.c_str()); } -//============================================================================// +//===----------------------------------------------------------------------===// // Public Response API -//============================================================================// +//===----------------------------------------------------------------------===// void sourcekitd_response_dispose(sourcekitd_response_t obj) { @@ -643,9 +643,9 @@ sourcekitd_response_get_value(sourcekitd_response_t resp) { return variantFromXPCObject(resp); } -//============================================================================// +//===----------------------------------------------------------------------===// // Variant functions -//============================================================================// +//===----------------------------------------------------------------------===// #define XPC_OBJ(var) ((xpc_object_t)(var).data[1]) diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt index 5afa31d9181f4..41e9a679d57cc 100644 --- a/tools/driver/CMakeLists.txt +++ b/tools/driver/CMakeLists.txt @@ -5,7 +5,7 @@ add_swift_executable(swift modulewrap_main.cpp LINK_LIBRARIES swiftIDE - swiftDriver swiftIRGen swiftSIL swiftSILGen swiftSILPasses + swiftDriver swiftIRGen swiftSIL swiftSILGen swiftSILOptimizer swiftImmediate swiftSerialization swiftPrintAsObjC diff --git a/tools/driver/autolink_extract_main.cpp b/tools/driver/autolink_extract_main.cpp index a7ada2f03534b..550c339d714cc 100644 --- a/tools/driver/autolink_extract_main.cpp +++ b/tools/driver/autolink_extract_main.cpp @@ -1,8 +1,8 @@ -//===-- autolink_extract_main.cpp - autolink extraction utility -----------===// +//===--- autolink_extract_main.cpp - autolink extraction utility ----------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index 57f00bf56e25f..ecd5145dbdd55 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -1,8 +1,8 @@ -//===-- driver.cpp - Swift Compiler Driver --------------------------------===// +//===--- driver.cpp - Swift Compiler Driver -------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/driver/frontend_main.cpp b/tools/driver/frontend_main.cpp index 2600cee4a5d80..ce9a535664748 100644 --- a/tools/driver/frontend_main.cpp +++ b/tools/driver/frontend_main.cpp @@ -1,8 +1,8 @@ -//===-- frontend_main.cpp - Swift Compiler Frontend -----------------------===// +//===--- frontend_main.cpp - Swift Compiler Frontend ----------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -28,6 +28,7 @@ #include "swift/Basic/Fallthrough.h" #include "swift/Basic/FileSystem.h" #include "swift/Basic/SourceManager.h" +#include "swift/Basic/Timer.h" #include "swift/Frontend/DiagnosticVerifier.h" #include "swift/Frontend/Frontend.h" #include "swift/Frontend/PrintingDiagnosticConsumer.h" @@ -36,7 +37,7 @@ #include "swift/Option/Options.h" #include "swift/PrintAsObjC/PrintAsObjC.h" #include "swift/Serialization/SerializationOptions.h" -#include "swift/SILPasses/Passes.h" +#include "swift/SILOptimizer/PassManager/Passes.h" // FIXME: We're just using CompilerInstance::createOutputFile. // This API should be sunk down to LLVM. @@ -52,6 +53,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/Timer.h" #include "llvm/Support/YAMLParser.h" #include @@ -166,10 +168,10 @@ static bool extendedTypeIsPrivate(TypeLoc inheritedType) { return std::all_of(protocols.begin(), protocols.end(), declIsPrivate); } -template -static void mangleTypeAsContext(StreamTy &&out, const NominalTypeDecl *type) { - Mangle::Mangler mangler(out, /*debug style=*/false, /*Unicode=*/true); +static std::string mangleTypeAsContext(const NominalTypeDecl *type) { + Mangle::Mangler mangler(/*debug style=*/false, /*Unicode=*/true); mangler.mangleContext(type, Mangle::Mangler::BindGenerics::None); + return mangler.finalize(); } /// Emits a Swift-style dependencies file. @@ -299,22 +301,21 @@ static bool emitReferenceDependencies(DiagnosticEngine &diags, if (!entry.second) continue; out << "- \""; - mangleTypeAsContext(out, entry.first); + out << mangleTypeAsContext(entry.first); out << "\"\n"; } out << "provides-member:\n"; for (auto entry : extendedNominals) { out << "- [\""; - mangleTypeAsContext(out, entry.first); + out << mangleTypeAsContext(entry.first); out << "\", \"\"]\n"; } // This is also part of "provides-member". for (auto *ED : extensionsWithJustMembers) { - SmallString<32> mangledName; - mangleTypeAsContext(llvm::raw_svector_ostream(mangledName), - ED->getExtendedType()->getAnyNominal()); + auto mangledName = mangleTypeAsContext( + ED->getExtendedType()->getAnyNominal()); for (auto *member : ED->getMembers()) { auto *VD = dyn_cast(member); @@ -322,7 +323,7 @@ static bool emitReferenceDependencies(DiagnosticEngine &diags, VD->getFormalAccess() == Accessibility::Private) { continue; } - out << "- [\"" << mangledName.str() << "\", \"" + out << "- [\"" << mangledName << "\", \"" << escape(VD->getName()) << "\"]\n"; } } @@ -376,12 +377,9 @@ static bool emitReferenceDependencies(DiagnosticEngine &diags, return lhs->first.first->getName().compare(rhs->first.first->getName()); // Break type name ties by mangled name. - SmallString<32> lhsMangledName, rhsMangledName; - mangleTypeAsContext(llvm::raw_svector_ostream(lhsMangledName), - lhs->first.first); - mangleTypeAsContext(llvm::raw_svector_ostream(rhsMangledName), - rhs->first.first); - return lhsMangledName.str().compare(rhsMangledName.str()); + auto lhsMangledName = mangleTypeAsContext(lhs->first.first); + auto rhsMangledName = mangleTypeAsContext(rhs->first.first); + return lhsMangledName.compare(rhsMangledName); }); for (auto &entry : sortedMembers) { @@ -394,7 +392,7 @@ static bool emitReferenceDependencies(DiagnosticEngine &diags, if (!entry.second) out << "!private "; out << "[\""; - mangleTypeAsContext(out, entry.first.first); + out << mangleTypeAsContext(entry.first.first); out << "\", \""; if (!entry.first.second.empty()) out << escape(entry.first.second); @@ -417,7 +415,7 @@ static bool emitReferenceDependencies(DiagnosticEngine &diags, if (!isCascading) out << "!private "; out << "\""; - mangleTypeAsContext(out, i->first.first); + out << mangleTypeAsContext(i->first.first); out << "\"\n"; } @@ -561,9 +559,7 @@ class JSONFixitWriter : public DiagnosticConsumer { if (Kind == DiagnosticKind::Error) return true; - if (Info.ID == diag::parameter_extraneous_pound.ID || - Info.ID == diag::parameter_pound_double_up.ID || - Info.ID == diag::forced_downcast_coercion.ID || + if (Info.ID == diag::forced_downcast_coercion.ID || Info.ID == diag::forced_downcast_noop.ID || Info.ID == diag::variable_never_mutated.ID) return true; @@ -795,22 +791,32 @@ static bool performCompile(CompilerInstance &Instance, if (Invocation.getSILOptions().LinkMode == SILOptions::LinkAll) performSILLinking(SM.get(), true); - SM->verify(); + { + SharedTimer timer("SIL verification (pre-optimization)"); + SM->verify(); + } // Perform SIL optimization passes if optimizations haven't been disabled. // These may change across compiler versions. - if (IRGenOpts.Optimize) { - StringRef CustomPipelinePath = - Invocation.getSILOptions().ExternalPassPipelineFilename; - if (!CustomPipelinePath.empty()) { - runSILOptimizationPassesWithFileSpecification(*SM, CustomPipelinePath); + { + SharedTimer timer("SIL optimization"); + if (IRGenOpts.Optimize) { + StringRef CustomPipelinePath = + Invocation.getSILOptions().ExternalPassPipelineFilename; + if (!CustomPipelinePath.empty()) { + runSILOptimizationPassesWithFileSpecification(*SM, CustomPipelinePath); + } else { + runSILOptimizationPasses(*SM); + } } else { - runSILOptimizationPasses(*SM); + runSILPassesForOnone(*SM); } - } else { - runSILPassesForOnone(*SM); } - SM->verify(); + + { + SharedTimer timer("SIL verification (post-optimization)"); + SM->verify(); + } // Gather instruction counts if we are asked to do so. if (SM->getOptions().PrintInstCounts) { @@ -1086,6 +1092,9 @@ int frontend_main(ArrayRefArgs, if (Invocation.getDiagnosticOptions().UseColor) PDC.forceColors(); + if (Invocation.getFrontendOptions().DebugTimeCompilation) + SharedTimer::enableCompilationTimers(); + if (Invocation.getFrontendOptions().PrintStats) { llvm::EnableStatistics(); } diff --git a/tools/driver/modulewrap_main.cpp b/tools/driver/modulewrap_main.cpp index 5dbebd78e0903..6e8489ed51bbb 100644 --- a/tools/driver/modulewrap_main.cpp +++ b/tools/driver/modulewrap_main.cpp @@ -1,8 +1,8 @@ -//===-- modulewrap_main.cpp - module wrapping utility -----------===// +//===--- modulewrap_main.cpp - module wrapping utility --------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -30,7 +30,6 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" -#include "llvm/Support/Path.h" #include "llvm/Support/TargetSelect.h" using namespace llvm::opt; diff --git a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp index 2c54f73323405..8d548701d81b2 100644 --- a/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp +++ b/tools/lldb-moduleimport-test/lldb-moduleimport-test.cpp @@ -1,8 +1,8 @@ -//===-- lldb-moduleimport-test.cpp - LLDB moduleimport tester -------------===// +//===--- lldb-moduleimport-test.cpp - LLDB moduleimport tester ------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/sil-extract/CMakeLists.txt b/tools/sil-extract/CMakeLists.txt index d87c6c17ee86d..d81ac373548f0 100644 --- a/tools/sil-extract/CMakeLists.txt +++ b/tools/sil-extract/CMakeLists.txt @@ -3,7 +3,7 @@ add_swift_executable(sil-extract LINK_LIBRARIES swiftFrontend swiftSILGen - swiftSILPasses + swiftSILOptimizer swiftSerialization swiftClangImporter ) diff --git a/tools/sil-extract/SILExtract.cpp b/tools/sil-extract/SILExtract.cpp index 07e302c4a8119..22c5fd383765a 100644 --- a/tools/sil-extract/SILExtract.cpp +++ b/tools/sil-extract/SILExtract.cpp @@ -1,8 +1,8 @@ -//===-- SILExtract.cpp - SIL function extraction utility ------------------===// +//===--- SILExtract.cpp - SIL function extraction utility -----------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -25,9 +25,9 @@ #include "swift/Frontend/PrintingDiagnosticConsumer.h" #include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Serialization/SerializedSILLoader.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/PassManager.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILUndef.h" #include "llvm/Support/CommandLine.h" diff --git a/tools/sil-opt/CMakeLists.txt b/tools/sil-opt/CMakeLists.txt index b5d2d72293198..e0d3c5a8889bb 100644 --- a/tools/sil-opt/CMakeLists.txt +++ b/tools/sil-opt/CMakeLists.txt @@ -4,7 +4,7 @@ add_swift_executable(sil-opt swiftFrontend swiftIRGen swiftSILGen - swiftSILPasses + swiftSILOptimizer ) swift_install_in_component(tools diff --git a/tools/sil-opt/SILOpt.cpp b/tools/sil-opt/SILOpt.cpp index 3aaecf3b3e3a3..5c062d76aae0d 100644 --- a/tools/sil-opt/SILOpt.cpp +++ b/tools/sil-opt/SILOpt.cpp @@ -1,8 +1,8 @@ -//===-- SILOpt.cpp - SIL Optimization Driver ------------------------------===// +//===--- SILOpt.cpp - SIL Optimization Driver -----------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -23,9 +23,9 @@ #include "swift/Frontend/DiagnosticVerifier.h" #include "swift/Frontend/Frontend.h" #include "swift/Frontend/PrintingDiagnosticConsumer.h" -#include "swift/SILAnalysis/Analysis.h" -#include "swift/SILPasses/Passes.h" -#include "swift/SILPasses/PassManager.h" +#include "swift/SILOptimizer/Analysis/Analysis.h" +#include "swift/SILOptimizer/PassManager/Passes.h" +#include "swift/SILOptimizer/PassManager/PassManager.h" #include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Serialization/SerializedSILLoader.h" #include "swift/Serialization/SerializationOptions.h" @@ -90,7 +90,7 @@ static llvm::cl::list Passes(llvm::cl::desc("Passes:"), llvm::cl::values( #define PASS(ID, NAME, DESCRIPTION) clEnumValN(PassKind::ID, NAME, DESCRIPTION), -#include "swift/SILPasses/Passes.def" +#include "swift/SILOptimizer/PassManager/Passes.def" clEnumValEnd)); static llvm::cl::opt diff --git a/tools/swift-compress/CMakeLists.txt b/tools/swift-compress/CMakeLists.txt new file mode 100644 index 0000000000000..34e13820f2323 --- /dev/null +++ b/tools/swift-compress/CMakeLists.txt @@ -0,0 +1,9 @@ +add_swift_executable(swift-compress + swift-compress.cpp + LINK_LIBRARIES swiftBasic swiftABI + COMPONENT_DEPENDS support) + +swift_install_in_component(compiler + TARGETS swift-compress + RUNTIME DESTINATION "bin") + diff --git a/tools/swift-compress/swift-compress.cpp b/tools/swift-compress/swift-compress.cpp new file mode 100644 index 0000000000000..a7d0c9e839506 --- /dev/null +++ b/tools/swift-compress/swift-compress.cpp @@ -0,0 +1,105 @@ +//===--- swift-compress.cpp - Swift compression tool ---------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// Swift compression tool. +// +//===----------------------------------------------------------------------===// + +#include "swift/ABI/Compression.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Regex.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include + +using EncodingKind = swift::Compress::EncodingKind; + +static llvm::cl::opt +DecompressMode("decompress", llvm::cl::desc("Decompress the input.")); +// Decompress only using the (CBC code book compression) dictionary +// compression. +static llvm::cl::opt +CBCOnly("cbc-only", llvm::cl::desc("Only use CBC compression.")); +// Decompress only using the (CBC code book compression) dictionary +// compression. +static llvm::cl::opt +HuffOnly("huff-only", llvm::cl::desc("Only use variable length encoding.")); + +static std::string Compress(const std::string &In, bool Compress) { + // Only inspect Swift mangled names. + if (In.substr(0, 2) != "_T") return In; + + auto Prefix = std::string("_T"); + auto Payload = In.substr(2, std::string::npos); + + if (CBCOnly) { + return Prefix + (Compress ? + swift::Compress::EncodeCBCString(Payload) : + swift::Compress::DecodeCBCString(Payload)); + } + + if (HuffOnly) { + if (Compress) { + llvm::APInt num = EncodeStringAsNumber(Payload, EncodingKind::Variable); + return Prefix + DecodeStringFromNumber(num, EncodingKind::Fixed); + } else { + llvm::APInt num = EncodeStringAsNumber(Payload, EncodingKind::Fixed); + return Prefix + DecodeStringFromNumber(num, EncodingKind::Variable); + } + } + + return Prefix + (Compress ? + swift::Compress::CompressName(Payload) : + swift::Compress::DecompressName(Payload)); +} +static llvm::StringRef substrBefore(llvm::StringRef whole, + llvm::StringRef part) { + return whole.slice(0, part.data() - whole.data()); +} + +static llvm::StringRef substrAfter(llvm::StringRef whole, + llvm::StringRef part) { + return whole.substr((part.data() - whole.data()) + part.size()); +} + +int main(int argc, char **argv) { + llvm::cl::ParseCommandLineOptions(argc, argv); + + if (HuffOnly && CBCOnly) { + llvm::errs() << "Can't select two compression mode at once." << '\n'; + return EXIT_FAILURE; + } + + auto input = llvm::MemoryBuffer::getSTDIN(); + + if (!input) { + llvm::errs() << input.getError().message() << '\n'; + return EXIT_FAILURE; + } + + llvm::StringRef inputContents = input.get()->getBuffer(); + + llvm::Regex maybeSymbol("_T[_a-zA-Z0-9$]+"); + llvm::SmallVector matches; + while (maybeSymbol.match(inputContents, &matches)) { + llvm::outs() << substrBefore(inputContents, matches.front()); + llvm::outs() << Compress(matches.front().str(), !DecompressMode); + inputContents = substrAfter(inputContents, matches.front()); + } + llvm::outs() << inputContents; + + return EXIT_SUCCESS; +} diff --git a/tools/swift-demangle/swift-demangle.cpp b/tools/swift-demangle/swift-demangle.cpp index 0a24b67bc0f1a..63196d6c5bc18 100644 --- a/tools/swift-demangle/swift-demangle.cpp +++ b/tools/swift-demangle/swift-demangle.cpp @@ -1,8 +1,8 @@ -//===-- swift-demangle.cpp - Swift Demangler app ---------------------------===// +//===--- swift-demangle.cpp - Swift Demangler app -------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/swift-ide-test/KnownObjCMethods.def b/tools/swift-ide-test/KnownObjCMethods.def index e43da62ba2905..4ecd53e372b90 100644 --- a/tools/swift-ide-test/KnownObjCMethods.def +++ b/tools/swift-ide-test/KnownObjCMethods.def @@ -1,8 +1,8 @@ -//===--- KnownMethods.def - Designated Initializers -------------*- C++ -*-===// +//===--- KnownObjCMethods.def - Designated Initializers ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -13,7 +13,7 @@ // This file defines the database of known methods for various // Objective-C classes, along with flags that describe how their // import into Swift should be altered. -// ===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // INSTANCE_METHOD(ClassName, Selector, Options) // CLASS_METHOD(ClassName, Selector, Options) diff --git a/tools/swift-ide-test/ModuleAPIDiff.cpp b/tools/swift-ide-test/ModuleAPIDiff.cpp index bea38fc3ab948..40e54e1c9c986 100644 --- a/tools/swift-ide-test/ModuleAPIDiff.cpp +++ b/tools/swift-ide-test/ModuleAPIDiff.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -730,7 +730,7 @@ class SMAModelGenerator : public DeclVisitor { sma::TypeName ResultTN; llvm::raw_string_ostream OS(ResultTN.Name); T.print(OS, Options); - return std::move(ResultTN); + return ResultTN; } llvm::Optional convertToOptionalTypeName(Type T) const { diff --git a/tools/swift-ide-test/XMLValidator.cpp b/tools/swift-ide-test/XMLValidator.cpp index 158afd5ec21c6..c81de46c7c973 100644 --- a/tools/swift-ide-test/XMLValidator.cpp +++ b/tools/swift-ide-test/XMLValidator.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/swift-ide-test/XMLValidator.h b/tools/swift-ide-test/XMLValidator.h index 4480f030d48cf..fefe5d4388b94 100644 --- a/tools/swift-ide-test/XMLValidator.h +++ b/tools/swift-ide-test/XMLValidator.h @@ -1,8 +1,8 @@ -//===-- XMLValidator.h - XML validation -----------------------------------===// +//===--- XMLValidator.h - XML validation ----------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp index bdb89fe0bd0aa..b9f29eff5c37c 100644 --- a/tools/swift-ide-test/swift-ide-test.cpp +++ b/tools/swift-ide-test/swift-ide-test.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -71,7 +71,6 @@ enum class ActionType { DumpCompletionCache, DumpImporterLookupTable, SyntaxColoring, - DumpAPI, DumpComments, Structure, Annotation, @@ -149,8 +148,6 @@ Action(llvm::cl::desc("Mode:"), llvm::cl::init(ActionType::None), "dump-importer-lookup-table", "Dump the Clang importer's lookup tables"), clEnumValN(ActionType::SyntaxColoring, "syntax-coloring", "Perform syntax coloring"), - clEnumValN(ActionType::DumpAPI, - "dump-api", "Dump the public API"), clEnumValN(ActionType::DumpComments, "dump-comments", "Dump documentation comments attached to decls"), clEnumValN(ActionType::Structure, @@ -271,11 +268,6 @@ ObjCForwardDeclarations("enable-objc-forward-declarations", llvm::cl::desc("Import Objective-C forward declarations when possible"), llvm::cl::init(false)); -static llvm::cl::opt -ImplicitProperties("enable-objc-implicit-properties", - llvm::cl::desc("Implicitly import Objective-C getter/setter pairs as properties"), - llvm::cl::init(false)); - static llvm::cl::opt InferDefaultArguments( "enable-infer-default-arguments", @@ -341,6 +333,11 @@ Typecheck("typecheck", llvm::cl::desc("Type check the AST"), llvm::cl::init(false)); +static llvm::cl::opt +Playground("playground", + llvm::cl::desc("Whether coloring in playground"), + llvm::cl::init(false)); + // AST printing options. static llvm::cl::opt @@ -548,7 +545,7 @@ static int doCodeCompletion(const CompilerInvocation &InitInvok, new ide::PrintingCodeCompletionConsumer( llvm::outs(), CodeCompletionKeywords)); - // Cerate a factory for code completion callbacks that will feed the + // Create a factory for code completion callbacks that will feed the // Consumer. std::unique_ptr CompletionCallbacksFactory( ide::makeCodeCompletionCallbacksFactory(CompletionContext, @@ -609,9 +606,9 @@ static int doREPLCodeCompletion(const CompilerInvocation &InitInvok, return 0; } -//============================================================================// +//===----------------------------------------------------------------------===// // Syntax Coloring -//============================================================================// +//===----------------------------------------------------------------------===// namespace { @@ -777,7 +774,8 @@ class PrintSyntaxColorWalker : public ide::SyntaxModelWalker { static int doSyntaxColoring(const CompilerInvocation &InitInvok, StringRef SourceFilename, bool TerminalOutput, - bool RunTypeChecker) { + bool RunTypeChecker, + bool Playground) { CompilerInvocation Invocation(InitInvok); Invocation.addInputFilename(SourceFilename); Invocation.getLangOptions().DisableAvailabilityChecking = false; @@ -787,6 +785,7 @@ static int doSyntaxColoring(const CompilerInvocation &InitInvok, // Display diagnostics to stderr. PrintingDiagnosticConsumer PrintDiags; CI.addDiagnosticConsumer(&PrintDiags); + Invocation.getLangOptions().Playground = Playground; if (CI.setup(Invocation)) return 1; if (!RunTypeChecker) @@ -811,146 +810,6 @@ static int doSyntaxColoring(const CompilerInvocation &InitInvok, return 0; } -//============================================================================// -// Dump API -//============================================================================// - -namespace { - -class DumpAPIWalker : public ASTWalker { -public: - SmallVector SourceRangesToDelete; - SmallVector CharSourceRangesToDelete; - - DumpAPIWalker() {} - - bool walkToDeclPre(Decl *D) override { - const bool exploreChildren = true; - const bool doneWithNode = false; - - // Ignore implicit Decls and don't descend into them; they often - // have a bogus source range that collides with something we'll - // want to keep. - if (D->isImplicit()) - return doneWithNode; - - const auto *VD = dyn_cast(D); - if (!VD) - return exploreChildren; // Look for a nested ValueDecl. - - if (VD->getFormalAccess() == Accessibility::Public) { - // Delete the bodies of public function and subscript decls - if (auto *AFD = dyn_cast(D)) { - SourceRangesToDelete.push_back(AFD->getBodySourceRange()); - return doneWithNode; - } else if (auto *SD = dyn_cast(D)) { - SourceRangesToDelete.push_back(SD->getBracesRange()); - return doneWithNode; - } - return exploreChildren; // Handle nested decls. - } - - // Delete entire non-public decls, including... - for (const auto &Single : VD->getRawComment().Comments) - CharSourceRangesToDelete.push_back(Single.Range); // attached comments - - VD->getAttrs().getAttrRanges(SourceRangesToDelete); // and attributes - - if (const auto *Var = dyn_cast(VD)) { - // VarDecls extend through their entire parent PatternBinding. - SourceRangesToDelete.push_back( - Var->getParentPatternBinding()->getSourceRange()); - } else { - SourceRangesToDelete.push_back(VD->getSourceRange()); - } - return doneWithNode; - } -}; -} - -static int doDumpAPI(const CompilerInvocation &InitInvok, - StringRef SourceFilename) { - CompilerInvocation Invocation(InitInvok); - Invocation.addInputFilename(SourceFilename); - Invocation.getLangOptions().DisableAvailabilityChecking = false; - - CompilerInstance CI; - - // Display diagnostics to stderr. - PrintingDiagnosticConsumer PrintDiags; - CI.addDiagnosticConsumer(&PrintDiags); - if (CI.setup(Invocation)) - return 1; - CI.performSema(); - - unsigned BufID = CI.getInputBufferIDs().back(); - SourceFile *SF = nullptr; - for (auto Unit : CI.getMainModule()->getFiles()) { - SF = dyn_cast(Unit); - if (SF) - break; - } - assert(SF && "no source file?"); - const auto &SM = CI.getSourceMgr(); - DumpAPIWalker Walker; - CI.getMainModule()->walk(Walker); - - //===--- rewriting ------------------------------------------------------===// - StringRef Input = SM.getLLVMSourceMgr().getMemoryBuffer(BufID)->getBuffer(); - clang::RewriteBuffer RewriteBuf; - RewriteBuf.Initialize(Input); - - // Convert all the accumulated SourceRanges into CharSourceRanges - auto &CharSourceRanges = Walker.CharSourceRangesToDelete; - for (const auto &SR : Walker.SourceRangesToDelete) { - auto End = Lexer::getLocForEndOfToken(SM, SR.End); - CharSourceRanges.push_back(CharSourceRange(SM, SR.Start, End)); - } - - // Drop any invalid ranges - CharSourceRanges.erase( - std::remove_if(CharSourceRanges.begin(), CharSourceRanges.end(), - [](const CharSourceRange CSR) { return !CSR.isValid(); }), - CharSourceRanges.end()); - - // Sort them so we can easily handle overlaps; the SourceManager - // doesn't cope well with overlapping deletions. - std::sort(CharSourceRanges.begin(), CharSourceRanges.end(), - [&](CharSourceRange LHS, CharSourceRange RHS) { - return SM.isBeforeInBuffer(LHS.getStart(), RHS.getStart()); - }); - - // A little function that we can re-use to delete a CharSourceRange - const auto Del = [&](CharSourceRange CR) { - const auto Start = SM.getLocOffsetInBuffer(CR.getStart(), BufID); - const auto End = SM.getLocOffsetInBuffer(CR.getEnd(), BufID); - RewriteBuf.RemoveText(Start, End - Start, true); - }; - - // Accumulate all overlapping ranges, deleting the previous one when - // no overlap is detected. - CharSourceRange Accumulator; - for (const auto CR : CharSourceRanges) { - if (!Accumulator.isValid()) { - Accumulator = CR; - } else if (Accumulator.overlaps(CR)) { - Accumulator.widen(CR); - } else { - Del(Accumulator); - Accumulator = CR; - } - } - - // The last valid range still needs to be deleted. - if (Accumulator.isValid()) - Del(Accumulator); - - // Write the edited buffer to stdout - RewriteBuf.write(llvm::outs()); - - return 0; -} - static int doDumpImporterLookupTables(const CompilerInvocation &InitInvok, StringRef SourceFilename) { if (options::ImportObjCHeader.empty()) { @@ -982,9 +841,9 @@ static int doDumpImporterLookupTables(const CompilerInvocation &InitInvok, return 0; } -//============================================================================// +//===----------------------------------------------------------------------===// // Structure Annotation -//============================================================================// +//===----------------------------------------------------------------------===// class StructureAnnotator : public ide::SyntaxModelWalker { SourceManager &SM; @@ -1153,9 +1012,9 @@ static int doStructureAnnotation(const CompilerInvocation &InitInvok, return 0; } -//============================================================================// +//===----------------------------------------------------------------------===// // Semantic Annotation -//============================================================================// +//===----------------------------------------------------------------------===// namespace { @@ -1412,9 +1271,9 @@ static int doInputCompletenessTest(StringRef SourceFilename) { return 0; } -//============================================================================// +//===----------------------------------------------------------------------===// // AST printing -//============================================================================// +//===----------------------------------------------------------------------===// static Module *getModuleByFullName(ASTContext &Context, StringRef ModuleName) { SmallVector, 4> @@ -1608,11 +1467,14 @@ static int doPrintLocalTypes(const CompilerInvocation &InitInvok, // Simulate already having mangled names for (auto LTD : LocalTypeDecls) { - SmallString<64> MangledName; - llvm::raw_svector_ostream Buffer(MangledName); - Mangle::Mangler Mangler(Buffer, /*DWARFMangling*/ true); - Mangler.mangleTypeForDebugger(LTD->getDeclaredType(), LTD->getDeclContext()); - MangledNames.push_back(Buffer.str()); + std::string MangledName; + { + Mangle::Mangler Mangler(/*DWARFMangling*/ true); + Mangler.mangleTypeForDebugger(LTD->getDeclaredType(), + LTD->getDeclContext()); + MangledName = Mangler.finalize(); + } + MangledNames.push_back(MangledName); } // Simulate the demangling / parsing process @@ -2274,9 +2136,9 @@ static int doPrintModuleImports(const CompilerInvocation &InitInvok, } -//============================================================================// +//===----------------------------------------------------------------------===// // Print type interfaces. -//============================================================================// +//===----------------------------------------------------------------------===// static int doPrintTypeInterface(const CompilerInvocation &InitInvok, const StringRef FileName, const StringRef LCPair) { @@ -2319,9 +2181,9 @@ static int doPrintTypeInterface(const CompilerInvocation &InitInvok, return 0; } -//============================================================================// +//===----------------------------------------------------------------------===// // Print USRs -//============================================================================// +//===----------------------------------------------------------------------===// namespace { @@ -2474,11 +2336,6 @@ int main(int argc, char *argv[]) { options::InputFilenames); } - if (options::Action == ActionType::GenerateModuleAPIDescription) { - llvm::errs() << "unimplemented\n"; - return 1; - } - if (options::Action == ActionType::DumpCompletionCache) { if (options::InputFilenames.empty()) { llvm::errs() << "-dump-completin-cache requires an input file\n"; @@ -2547,8 +2404,6 @@ int main(int argc, char *argv[]) { !options::DisableAccessControl; InitInvok.getLangOptions().CodeCompleteInitsInPostfixExpr |= options::CodeCompleteInitsInPostfixExpr; - InitInvok.getClangImporterOptions().InferImplicitProperties |= - options::ImplicitProperties; InitInvok.getClangImporterOptions().ImportForwardDeclarations |= options::ObjCForwardDeclarations; InitInvok.getClangImporterOptions().OmitNeedlessWords |= @@ -2653,11 +2508,8 @@ int main(int argc, char *argv[]) { ExitCode = doSyntaxColoring(InitInvok, options::SourceFilename, options::TerminalOutput, - options::Typecheck); - break; - - case ActionType::DumpAPI: - ExitCode = doDumpAPI(InitInvok, options::SourceFilename); + options::Typecheck, + options::Playground); break; case ActionType::DumpImporterLookupTable: diff --git a/tools/swift-llvm-opt/LLVMOpt.cpp b/tools/swift-llvm-opt/LLVMOpt.cpp index ccb37f752fb13..fb8f9cd9b90c7 100644 --- a/tools/swift-llvm-opt/LLVMOpt.cpp +++ b/tools/swift-llvm-opt/LLVMOpt.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -60,7 +60,6 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Target/TargetMachine.h" diff --git a/unittests/Basic/ADTTests.cpp b/unittests/Basic/ADTTests.cpp index 9439760472cc3..4d875f51f6ad6 100644 --- a/unittests/Basic/ADTTests.cpp +++ b/unittests/Basic/ADTTests.cpp @@ -1,4 +1,5 @@ #include "swift/Basic/OptionSet.h" +#include "swift/Basic/ValueEnumerator.h" #include "gtest/gtest.h" using namespace swift; @@ -99,3 +100,62 @@ TEST(OptionSet, intptr_t_isConstructible) { } +TEST(ValueEnumerator, basic) { + + { + ValueEnumerator Trans; + // Check that indexing is persistent. + EXPECT_EQ(Trans.getIndex(99), Trans.getIndex(99)); + EXPECT_EQ(Trans.getIndex(100), Trans.getIndex(100)); + + // Check that we don't have collisions. + bool SameIndex = Trans.getIndex(82) == Trans.getIndex(73); + EXPECT_FALSE(SameIndex); + + // Check that invalidation works. + // After invalidation the old index must not be equal to the new index. + size_t oldIndex = Trans.getIndex(99); + Trans.invalidateValue(99); + size_t newIndex = Trans.getIndex(99); + EXPECT_FALSE(newIndex == oldIndex); + } + + { + const char *string_1 = "hello"; + const char *string_2 = "goodbye"; + const char *string_3 = ":-)"; + ValueEnumerator Trans; + EXPECT_EQ(Trans.getIndex(nullptr), Trans.getIndex(nullptr)); + EXPECT_EQ(Trans.getIndex(string_1), Trans.getIndex(string_1)); + EXPECT_EQ(Trans.getIndex(string_2), Trans.getIndex(string_2)); + + // Check that invalidation works. + size_t oldIndex = Trans.getIndex(string_3); + Trans.invalidateValue(string_3); + size_t newIndex = Trans.getIndex(string_3); + EXPECT_FALSE(newIndex == oldIndex); + + // Check that different values don't give the same index. + EXPECT_FALSE(Trans.getIndex(string_2) == Trans.getIndex(string_3)); + } + + + { + ValueEnumerator Trans; + // Check a bunch of integers. + for (int i = 1; i < 10000; i++) { + EXPECT_TRUE(Trans.getIndex(0) != Trans.getIndex(i)); + } + + // Check that there are no accidental collisions. + for (int i = 0; i < 10000; i++) { + for (int j = 1; j < 10; j++) { + EXPECT_TRUE(Trans.getIndex(i) != Trans.getIndex(i + j)); + } + } + + // Check that indexing is still persistent. + EXPECT_EQ(Trans.getIndex(100), Trans.getIndex(100)); + } + +} diff --git a/unittests/Basic/BlotMapVectorTest.cpp b/unittests/Basic/BlotMapVectorTest.cpp index 6cdc65f43f4f8..a597e0e36800e 100644 --- a/unittests/Basic/BlotMapVectorTest.cpp +++ b/unittests/Basic/BlotMapVectorTest.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -117,7 +117,7 @@ class CtorTester { dump("Constructing Normal"); llvm::outs() << "\n"; EXPECT_TRUE(ConstructedTesters->insert(this)); - assert(!isIgnoreableTester()); + assert(!isIgnorableTester()); assert(isLive()); fflush(stdout); } @@ -126,7 +126,7 @@ class CtorTester { dump("Constructing Normal"); llvm::outs() << "\n"; EXPECT_TRUE(ConstructedTesters->insert(this)); - assert(!isIgnoreableTester()); + assert(!isIgnorableTester()); assert(isLive()); fflush(stdout); } @@ -135,7 +135,7 @@ class CtorTester { dump("CopyConstructing"); Arg.dump(" From"); llvm::outs() << "\n"; - if (!Arg.isIgnoreableTester()) { + if (!Arg.isIgnorableTester()) { EXPECT_TRUE(ConstructedTesters->insert(this)); fflush(stdout); } @@ -147,8 +147,8 @@ class CtorTester { llvm::outs() << "\n"; assert(Value); assert(Arg.Value); - // If Arg is not ignoreable, it will be now and we will not be. - if (!Arg.isIgnoreableTester()) { + // If Arg is not ignorable, it will be now and we will not be. + if (!Arg.isIgnorableTester()) { EXPECT_TRUE(ConstructedTesters->insert(this)); EXPECT_EQ(1u, ConstructedTesters->erase(&Arg)); } @@ -163,9 +163,9 @@ class CtorTester { assert(Value); assert(Arg.Value); - // If arg is not an ignoreable tester, but we are an ignoreable tester, we + // If arg is not an ignorable tester, but we are an ignorable tester, we // need to be inserted into the constructed testers set. - if (!Arg.isIgnoreableTester() && isIgnoreableTester()) { + if (!Arg.isIgnorableTester() && isIgnorableTester()) { EXPECT_TRUE(ConstructedTesters->insert(this)); } *Value.get() = Arg.getValue(); @@ -179,10 +179,10 @@ class CtorTester { llvm::outs() << "\n"; assert(Value); assert(Arg.Value); - if (!Arg.isIgnoreableTester() && isIgnoreableTester()) { + if (!Arg.isIgnorableTester() && isIgnorableTester()) { EXPECT_EQ(1u, ConstructedTesters->erase(&Arg)); EXPECT_TRUE(ConstructedTesters->insert(this)); - } else if (Arg.isIgnoreableTester() && !isIgnoreableTester()) { + } else if (Arg.isIgnorableTester() && !isIgnorableTester()) { EXPECT_EQ(1u, ConstructedTesters->erase(this)); EXPECT_TRUE(ConstructedTesters->insert(&Arg)); } @@ -193,13 +193,13 @@ class CtorTester { } ~CtorTester() { - bool IsIgnoreable = isIgnoreableTester(); + bool IsIgnorable = isIgnorableTester(); dump("Destroying"); llvm::outs() << "\n"; delete Value.get(); Value = nullptr; fflush(stdout); - if (ConstructedTesters->isClearing() || IsIgnoreable) + if (ConstructedTesters->isClearing() || IsIgnorable) return; EXPECT_EQ(1u, ConstructedTesters->erase(this)); } @@ -212,7 +212,7 @@ class CtorTester { return *Value.get() == *RHS.Value.get(); } - bool isIgnoreableTester() const { + bool isIgnorableTester() const { return *Value.get() >= -3 && *Value.get() < 0; } @@ -230,7 +230,7 @@ class CtorTester { void CtorTesterSet::dumpLiveTesters() const { for (auto *Tester : Constructed) { - if (Tester->isIgnoreableTester()) + if (Tester->isIgnorableTester()) continue; llvm::SmallString<64> Hex; std::string Addr = llvm::utohexstr(uintptr_t(Tester)); @@ -248,7 +248,7 @@ bool CtorTesterSet::hasLiveTesters() const { return std::any_of(Constructed.begin(), Constructed.end(), [](CtorTester *T) -> bool { assert(T); - return !T->isIgnoreableTester(); + return !T->isIgnorableTester(); }); } @@ -256,7 +256,7 @@ bool CtorTesterSet::numLiveTesters() const { return std::count_if(Constructed.begin(), Constructed.end(), [](CtorTester *T) -> bool { assert(T); - return !T->isIgnoreableTester(); + return !T->isIgnorableTester(); }); } diff --git a/unittests/Basic/CMakeLists.txt b/unittests/Basic/CMakeLists.txt index ea9c690ea1813..6e2fc0df436df 100644 --- a/unittests/Basic/CMakeLists.txt +++ b/unittests/Basic/CMakeLists.txt @@ -19,7 +19,8 @@ add_swift_unittest(SwiftBasicTests SuccessorMapTest.cpp Unicode.cpp BlotMapVectorTest.cpp - + PointerIntEnumTest.cpp + CompressionTests.cpp ${generated_tests} ) @@ -27,5 +28,6 @@ add_dependencies(SwiftBasicTests "${gyb_dependency_targets}") target_link_libraries(SwiftBasicTests swiftBasic + swiftABI clangBasic ) diff --git a/unittests/Basic/CompressionTests.cpp b/unittests/Basic/CompressionTests.cpp new file mode 100644 index 0000000000000..163884d033831 --- /dev/null +++ b/unittests/Basic/CompressionTests.cpp @@ -0,0 +1,90 @@ +//===--- CompressionTests.cpp - for swift/ABI/Compression.h ---------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +#include "swift/ABI/Compression.h" +#include "gtest/gtest.h" + +using namespace swift::Compress; + +const char* TestValues[] = {"AA", "r", "J", "Swift","A", "ArrayStringPrintable", + "AB","JA","YA","encodeCBCString", "HelloWorld", "long", "_TThisIsATestString" + "Done", "Smile","_S_S_S", "________", "_TSLZ","Lempel_Ziv", "Ziv_and_Lempel", + "JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ", + "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", + "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY", + "AllDone", "UnderWaterCordlessDrill","UnderWaterAngleGrinder", "Printable", "Clone", "Collection" + "__TwxxV14StdlibUnittest24MinimalForwardCollection", + "__TMPVs15ContiguousArray", + "__TIF14StdlibUnittest13checkSequenceu0_Rxs14CollectionType_s12SequenceTypeWx9Generator7Element_zW_9GeneratorS3__rFTxq", + "__TTSg5VSS13CharacterViewS_s14CollectionTypes_GVs17IndexingGeneratorS__GS1_S__s13GeneratorTypes_VS_5IndexS3_s16Forwar", + "__TMANameWith$dollar$inIt", + ""}; + +// Test that the code book compression round trips. +TEST(Compression, RoundTripCBC) { + for (const char* N : TestValues) { + std::string encoded = EncodeCBCString(N); + std::string decoded = DecodeCBCString(encoded); + EXPECT_EQ(decoded, std::string(N)); + } +} + +// Test flat (non variable length) encoding. +TEST(Compression, FlatEncoding) { + for (const char* input : TestValues) { + llvm::APInt flat_code = EncodeStringAsNumber(input, EncodingKind::Fixed); + std::string flat_input = DecodeStringFromNumber(flat_code, EncodingKind::Fixed); + EXPECT_EQ(flat_input, input); + } + + // Check that we can encode and decode all numbers and that we get the + // correct value after round trips. + for (int i = 0; i < 10000; i++) { + llvm::APInt num = llvm::APInt(64, i); + std::string encoded = DecodeStringFromNumber(num, EncodingKind::Fixed); + llvm::APInt decoded_num = EncodeStringAsNumber(encoded, EncodingKind::Fixed); + EXPECT_EQ(num.getZExtValue(), decoded_num.getZExtValue()); + } +} + +// Test variable length encoding. +TEST(Compression, VarEncoding) { + for (const char* input : TestValues) { + llvm::APInt var_code = EncodeStringAsNumber(input, EncodingKind::Variable); + std::string var_input = DecodeStringFromNumber(var_code, EncodingKind::Variable); + EXPECT_EQ(var_input, input); + } +} + +TEST(Compression, VariableLength) { + for (const char* input : TestValues) { + llvm::APInt code = EncodeStringAsNumber(input, EncodingKind::Variable); + + std::string encoded = DecodeStringFromNumber(code, EncodingKind::Fixed); + llvm::APInt code2 = EncodeStringAsNumber(encoded, EncodingKind::Fixed); + + std::string encoded2 = DecodeStringFromNumber(code2, EncodingKind::Fixed); + llvm::APInt code3 = EncodeStringAsNumber(encoded2, EncodingKind::Fixed); + EXPECT_EQ(code.toString(10, false), code2.toString(10, false)); + EXPECT_EQ(code3, code2); + + std::string decoded = DecodeStringFromNumber(code2, EncodingKind::Variable); + EXPECT_EQ(decoded, input); + } +} + +TEST(Compression, FullCompression) { + for (const char* input : TestValues) { + std::string compressed = CompressName(input); + std::string decompressed = DecompressName(compressed); + EXPECT_EQ(std::string(input), decompressed); + } +} diff --git a/unittests/Basic/FileSystemTests.cpp b/unittests/Basic/FileSystemTests.cpp index be13b4c3899c2..d7373c340107e 100644 --- a/unittests/Basic/FileSystemTests.cpp +++ b/unittests/Basic/FileSystemTests.cpp @@ -1,8 +1,8 @@ -//===- FileSystemTests.cpp - for swift/Basic/FileSystem.h -----------------===// +//===--- FileSystemTests.cpp - for swift/Basic/FileSystem.h ---------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/unittests/Basic/PointerIntEnumTest.cpp b/unittests/Basic/PointerIntEnumTest.cpp new file mode 100644 index 0000000000000..d109d4c653c50 --- /dev/null +++ b/unittests/Basic/PointerIntEnumTest.cpp @@ -0,0 +1,239 @@ +#include "swift/Basic/PointerIntEnum.h" +#include "llvm/ADT/ArrayRef.h" +#include "gtest/gtest.h" + +using namespace swift; + +namespace { + +enum class EnumTy : unsigned { + Ptr1 = 0, + Ptr2 = 1, + Ptr3 = 2, + FirstPointerKind = Ptr1, + LastPointerKind = Ptr3, + + // Index Projection Kinds + FirstIndexKind = 7, + Index1 = PointerIntEnumIndexKindValue<0, EnumTy>::value, + Index2 = PointerIntEnumIndexKindValue<1, EnumTy>::value, + Index3 = PointerIntEnumIndexKindValue<2, EnumTy>::value, + Index4 = PointerIntEnumIndexKindValue<3, EnumTy>::value, + Index5 = PointerIntEnumIndexKindValue<4, EnumTy>::value, + LastIndexKind = Index5, +}; + +using PointerIntEnumTy = + PointerIntEnum>; + +static_assert(std::is_trivially_copyable::value, + "PointerIntEnum type should be trivially copyable"); + +static constexpr uintptr_t InvalidStorage = uintptr_t(0) - 1; + +} // end anonymous namespace + +TEST(PointerIntEnumTest, DefaultConstructorYieldsInvalid) { + PointerIntEnumTy Enum; + EXPECT_FALSE(Enum.isValid()); + EXPECT_TRUE(Enum.getStorage() == InvalidStorage); +} + +TEST(PointerIntEnumTest, PointerConstructor) { + int *data = new int[1]; + PointerIntEnumTy Enum(EnumTy::Ptr1, data); + EXPECT_TRUE(Enum.isValid()); + EXPECT_EQ(*Enum.getKind(), EnumTy::Ptr1); + EXPECT_EQ(Enum.getPointer(), data); + + // Make sure that the value is laid out correctly in memory. + uintptr_t Value = uintptr_t(data) | uintptr_t(EnumTy::Ptr1); + EXPECT_EQ(Enum.getStorage(), Value); + + delete[] data; +} + +TEST(PointerIntEnumTest, IndexConstructor) { + // First test a case that we can represent. + { + PointerIntEnumTy Enum(EnumTy::Index3, 0xBEEF); + EXPECT_TRUE(Enum.isValid()); + EXPECT_EQ(*Enum.getKind(), EnumTy::Index3); + EXPECT_EQ(Enum.getIndex(), uintptr_t(0xBEEF)); + + // Make sure that the value is laid out correctly in memory. + uintptr_t Value = (uintptr_t(0xBEEF) << 7) | uintptr_t(EnumTy::Index3); + EXPECT_EQ(Enum.getStorage(), Value); + } + + // Then test the boundary from representable index to unrepresentable index. + uintptr_t MaxIndex = (uintptr_t(1) << (sizeof(uintptr_t) * CHAR_BIT - 7)) - 2; + { + PointerIntEnumTy Enum(EnumTy::Index3, MaxIndex + 1); + EXPECT_FALSE(Enum.isValid()); + EXPECT_FALSE(Enum.getKind()); + EXPECT_EQ(Enum.getStorage(), InvalidStorage); + } + + { + PointerIntEnumTy Enum(EnumTy::Index4, MaxIndex); + EXPECT_TRUE(Enum.isValid()); + EXPECT_EQ(*Enum.getKind(), EnumTy::Index4); + EXPECT_EQ(Enum.getIndex(), MaxIndex); + + // Make sure that the value is laid out correctly in memory. + uintptr_t Value = (uintptr_t(MaxIndex) << 7) | uintptr_t(EnumTy::Index4); + EXPECT_EQ(Enum.getStorage(), Value); + } +} + +TEST(PointerIntEnumTest, CopyConstructorAssignment) { + PointerIntEnumTy IntEnum(EnumTy::Index3, 0xBEEF); + uintptr_t IntEnumStorageValue = + (uintptr_t(0xBEEF) << 7) | uintptr_t(EnumTy::Index3); + int *data = new int[1]; + PointerIntEnumTy PtrEnum(EnumTy::Ptr2, data); + uintptr_t PtrEnumStorageValue = uintptr_t(data) | uintptr_t(EnumTy::Ptr2); + + PointerIntEnumTy Enum2(IntEnum); + PointerIntEnumTy Enum3 = IntEnum; + + EXPECT_TRUE(Enum2.isValid()); + EXPECT_EQ(*Enum2.getKind(), EnumTy::Index3); + EXPECT_EQ(Enum2.getIndex(), uintptr_t(0xBEEF)); + EXPECT_EQ(Enum2.getStorage(), IntEnumStorageValue); + EXPECT_EQ(IntEnum, Enum2); + EXPECT_NE(PtrEnum, Enum2); + + EXPECT_TRUE(Enum3.isValid()); + EXPECT_EQ(*Enum3.getKind(), EnumTy::Index3); + EXPECT_EQ(Enum3.getIndex(), uintptr_t(0xBEEF)); + EXPECT_EQ(Enum3.getStorage(), IntEnumStorageValue); + EXPECT_EQ(IntEnum, Enum3); + EXPECT_NE(PtrEnum, Enum3); + + Enum3 = PtrEnum; + PointerIntEnumTy Enum4(PtrEnum); + + EXPECT_TRUE(Enum3.isValid()); + EXPECT_EQ(*Enum3.getKind(), EnumTy::Ptr2); + EXPECT_EQ(Enum3.getPointer(), data); + EXPECT_EQ(Enum3.getStorage(), PtrEnumStorageValue); + EXPECT_EQ(Enum3, PtrEnum); + EXPECT_NE(Enum3, IntEnum); + + EXPECT_TRUE(Enum4.isValid()); + EXPECT_EQ(*Enum4.getKind(), EnumTy::Ptr2); + EXPECT_EQ(Enum4.getPointer(), data); + EXPECT_EQ(Enum4.getStorage(), PtrEnumStorageValue); + EXPECT_EQ(Enum4, PtrEnum); + EXPECT_NE(Enum4, IntEnum); + + // Round trip Enum3 + Enum3 = IntEnum; + EXPECT_TRUE(Enum3.isValid()); + EXPECT_EQ(*Enum3.getKind(), EnumTy::Index3); + EXPECT_EQ(Enum3.getIndex(), uintptr_t(0xBEEF)); + EXPECT_EQ(Enum3.getStorage(), IntEnumStorageValue); + EXPECT_EQ(IntEnum, Enum3); + EXPECT_NE(PtrEnum, Enum3); + + delete[] data; +} + +// We have a trivial move constructor, so we copy when we move. +TEST(PointerIntEnumTest, MoveConstructorAssignment) { + PointerIntEnumTy IntEnum(EnumTy::Index3, 0xBEEF); + uintptr_t IntEnumStorageValue = + (uintptr_t(0xBEEF) << 7) | uintptr_t(EnumTy::Index3); + int *data = new int[1]; + PointerIntEnumTy PtrEnum(EnumTy::Ptr2, data); + uintptr_t PtrEnumStorageValue = uintptr_t(data) | uintptr_t(EnumTy::Ptr2); + + PointerIntEnumTy Enum2(std::move(IntEnum)); + PointerIntEnumTy Enum3 = std::move(IntEnum); + + EXPECT_TRUE(Enum2.isValid()); + EXPECT_EQ(*Enum2.getKind(), EnumTy::Index3); + EXPECT_EQ(Enum2.getIndex(), uintptr_t(0xBEEF)); + EXPECT_EQ(Enum2.getStorage(), IntEnumStorageValue); + EXPECT_EQ(IntEnum, Enum2); + EXPECT_NE(PtrEnum, Enum2); + + EXPECT_TRUE(Enum3.isValid()); + EXPECT_EQ(*Enum3.getKind(), EnumTy::Index3); + EXPECT_EQ(Enum3.getIndex(), uintptr_t(0xBEEF)); + EXPECT_EQ(Enum3.getStorage(), IntEnumStorageValue); + EXPECT_EQ(IntEnum, Enum3); + EXPECT_NE(PtrEnum, Enum3); + + Enum3 = std::move(PtrEnum); + PointerIntEnumTy Enum4(std::move(PtrEnum)); + + EXPECT_TRUE(Enum3.isValid()); + EXPECT_EQ(*Enum3.getKind(), EnumTy::Ptr2); + EXPECT_EQ(Enum3.getPointer(), data); + EXPECT_EQ(Enum3.getStorage(), PtrEnumStorageValue); + EXPECT_EQ(Enum3, PtrEnum); + EXPECT_NE(Enum3, IntEnum); + + EXPECT_TRUE(Enum4.isValid()); + EXPECT_EQ(*Enum4.getKind(), EnumTy::Ptr2); + EXPECT_EQ(Enum4.getPointer(), data); + EXPECT_EQ(Enum4.getStorage(), PtrEnumStorageValue); + EXPECT_EQ(Enum4, PtrEnum); + EXPECT_NE(Enum4, IntEnum); + + // Round trip Enum3 + Enum3 = std::move(IntEnum); + EXPECT_TRUE(Enum3.isValid()); + EXPECT_EQ(*Enum3.getKind(), EnumTy::Index3); + EXPECT_EQ(Enum3.getIndex(), uintptr_t(0xBEEF)); + EXPECT_EQ(Enum3.getStorage(), IntEnumStorageValue); + EXPECT_EQ(IntEnum, Enum3); + EXPECT_NE(PtrEnum, Enum3); + + delete[] data; +} + +TEST(PointerIntEnumTest, Comparisons) { + PointerIntEnumTy IndexCase1(EnumTy::Index1, 5); + + // Make sure that enums with different cases but the same value always compare + // different. + PointerIntEnumTy IndexCase2(EnumTy::Index2, 5); + EXPECT_NE(IndexCase1, IndexCase2); + + // Make sure that enums with the same case and the same value compare equal. + PointerIntEnumTy IndexCase3(EnumTy::Index1, 5); + EXPECT_EQ(IndexCase1, IndexCase3); + + // Make sure that enums with the same case, but different values do not + // compare equal. + PointerIntEnumTy IndexCase4(EnumTy::Index1, 6); + EXPECT_NE(IndexCase1, IndexCase4); + + int *data1 = new int[1]; + int *data2 = new int[1]; + PointerIntEnumTy PtrCase1(EnumTy::Ptr1, data1); + + // Test that pointer enums with different cases but the same value compare + // different. + PointerIntEnumTy PtrCase2(EnumTy::Ptr2, data1); + EXPECT_NE(PtrCase1, PtrCase2); + + // Test that pointer enums with the same case and data are equal. + PointerIntEnumTy PtrCase3(EnumTy::Ptr1, data1); + EXPECT_EQ(PtrCase1, PtrCase3); + + // Test that pointer enums with the same case but different data are not + // equal. + PointerIntEnumTy PtrCase4(EnumTy::Ptr1, data2); + EXPECT_NE(PtrCase1, PtrCase4); + + // Test that pointers and indices compare differently. + EXPECT_NE(IndexCase1, PtrCase1); + + delete[] data2; + delete[] data1; +} diff --git a/unittests/Basic/UnicodeGraphemeBreakTest.cpp.gyb b/unittests/Basic/UnicodeGraphemeBreakTest.cpp.gyb index b30aaeac3307e..9450e46784901 100644 --- a/unittests/Basic/UnicodeGraphemeBreakTest.cpp.gyb +++ b/unittests/Basic/UnicodeGraphemeBreakTest.cpp.gyb @@ -7,7 +7,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/unittests/SourceKit/Support/FuzzyStringMatcherTest.cpp b/unittests/SourceKit/Support/FuzzyStringMatcherTest.cpp index 0a31d44a7434a..4bf0edb483b6e 100644 --- a/unittests/SourceKit/Support/FuzzyStringMatcherTest.cpp +++ b/unittests/SourceKit/Support/FuzzyStringMatcherTest.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/unittests/SourceKit/Support/ImmutableTextBufferTest.cpp b/unittests/SourceKit/Support/ImmutableTextBufferTest.cpp index 21790e4fb582b..b979787e2ddf1 100644 --- a/unittests/SourceKit/Support/ImmutableTextBufferTest.cpp +++ b/unittests/SourceKit/Support/ImmutableTextBufferTest.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp b/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp index 3c51cb60354c0..4ab36f3e56775 100644 --- a/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp +++ b/unittests/SourceKit/SwiftLang/CursorInfoTest.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/unittests/SwiftDemangle/DemangleTest.cpp b/unittests/SwiftDemangle/DemangleTest.cpp index 7944b76446630..9645badda4eb8 100644 --- a/unittests/SwiftDemangle/DemangleTest.cpp +++ b/unittests/SwiftDemangle/DemangleTest.cpp @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -27,7 +27,7 @@ TEST(FunctionNameDemangleTests, CorrectlyDemangles) { EXPECT_STREQ(DemangledName, OutputBuffer); EXPECT_EQ(Result, strlen(DemangledName)); - // Make sure the SynthesizeSugarOnTypes option is functioning + // Make sure the SynthesizeSugarOnTypes option is functioning. const char *FunctionNameWithSugar = "_TF4main3fooFT3argGSqGSaSi___T_"; const char *DemangledNameWithSugar = "main.foo (arg : [Swift.Int]?) -> ()"; diff --git a/unittests/runtime/Enum.cpp b/unittests/runtime/Enum.cpp index 7a37327dc7951..2bf7c0168513e 100644 --- a/unittests/runtime/Enum.cpp +++ b/unittests/runtime/Enum.cpp @@ -1,8 +1,8 @@ -//===- swift/unittests/runtime/Enum.cpp - Enum tests --------------------===// +//===--- Enum.cpp - Enum tests --------------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/unittests/runtime/Metadata.cpp b/unittests/runtime/Metadata.cpp index 48c425c801a19..e400d16c8d923 100644 --- a/unittests/runtime/Metadata.cpp +++ b/unittests/runtime/Metadata.cpp @@ -1,8 +1,8 @@ -//===- swift/unittests/runtime/Metadata.cpp - Metadata tests --------------===// +//===--- Metadata.cpp - Metadata tests ------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/unittests/runtime/Refcounting.cpp b/unittests/runtime/Refcounting.cpp index 462bfe240cb03..c856fdb70a18e 100644 --- a/unittests/runtime/Refcounting.cpp +++ b/unittests/runtime/Refcounting.cpp @@ -1,8 +1,8 @@ -//===swift/unittests/runtime/Refcounting.cpp - Reference-counting for swift===// +//===--- Refcounting.cpp - Reference-counting for Swift ---------*- C++ -*-===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -98,6 +98,13 @@ TEST(RefcountingTest, pin_pin_unpin_unpin) { EXPECT_EQ(1u, value); } +static unsigned _retainCount(HeapObject *object) { + return object->refCount.getCount(); +} +static unsigned _unownedRetainCount(HeapObject *object) { + return object->weakRefCount.getCount(); +} + TEST(RefcountingTest, retain_release_n) { size_t value = 0; auto object = allocTestObject(&value, 1); @@ -105,16 +112,16 @@ TEST(RefcountingTest, retain_release_n) { swift_retain_n(object, 32); swift_retain(object); EXPECT_EQ(0u, value); - EXPECT_EQ(34u, swift_retainCount(object)); + EXPECT_EQ(34u, _retainCount(object)); swift_release_n(object, 31); EXPECT_EQ(0u, value); - EXPECT_EQ(3u, swift_retainCount(object)); + EXPECT_EQ(3u, _retainCount(object)); swift_release(object); EXPECT_EQ(0u, value); - EXPECT_EQ(2u, swift_retainCount(object)); + EXPECT_EQ(2u, _retainCount(object)); swift_release_n(object, 1); EXPECT_EQ(0u, value); - EXPECT_EQ(1u, swift_retainCount(object)); + EXPECT_EQ(1u, _retainCount(object)); swift_release(object); EXPECT_EQ(1u, value); } @@ -126,16 +133,16 @@ TEST(RefcountingTest, unknown_retain_release_n) { swift_unknownRetain_n(object, 32); swift_unknownRetain(object); EXPECT_EQ(0u, value); - EXPECT_EQ(34u, swift_retainCount(object)); + EXPECT_EQ(34u, _retainCount(object)); swift_unknownRelease_n(object, 31); EXPECT_EQ(0u, value); - EXPECT_EQ(3u, swift_retainCount(object)); + EXPECT_EQ(3u, _retainCount(object)); swift_unknownRelease(object); EXPECT_EQ(0u, value); - EXPECT_EQ(2u, swift_retainCount(object)); + EXPECT_EQ(2u, _retainCount(object)); swift_unknownRelease_n(object, 1); EXPECT_EQ(0u, value); - EXPECT_EQ(1u, swift_retainCount(object)); + EXPECT_EQ(1u, _retainCount(object)); swift_unknownRelease(object); EXPECT_EQ(1u, value); } @@ -144,15 +151,15 @@ TEST(RefcountingTest, unowned_retain_release_n) { size_t value = 0; auto object = allocTestObject(&value, 1); EXPECT_EQ(0u, value); - swift_weakRetain_n(object, 32); - swift_weakRetain(object); - EXPECT_EQ(34u, swift_weakRetainCount(object)); - swift_weakRelease_n(object, 31); - EXPECT_EQ(3u, swift_weakRetainCount(object)); - swift_weakRelease(object); - EXPECT_EQ(2u, swift_weakRetainCount(object)); - swift_weakRelease_n(object, 1); - EXPECT_EQ(1u, swift_weakRetainCount(object)); + swift_unownedRetain_n(object, 32); + swift_unownedRetain(object); + EXPECT_EQ(34u, _unownedRetainCount(object)); + swift_unownedRelease_n(object, 31); + EXPECT_EQ(3u, _unownedRetainCount(object)); + swift_unownedRelease(object); + EXPECT_EQ(2u, _unownedRetainCount(object)); + swift_unownedRelease_n(object, 1); + EXPECT_EQ(1u, _unownedRetainCount(object)); swift_release(object); EXPECT_EQ(1u, value); } diff --git a/unittests/runtime/Refcounting.mm b/unittests/runtime/Refcounting.mm index a8067a716cafb..6bb3a75112210 100644 --- a/unittests/runtime/Refcounting.mm +++ b/unittests/runtime/Refcounting.mm @@ -1,8 +1,8 @@ -//=== swift/unittests/runtime/Refcounting.mm - Reference-counting for ObjC-===// +//===--- Refcounting.mm - Reference-counting for ObjC ---------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/unittests/runtime/weak.mm b/unittests/runtime/weak.mm index 3b440c44c5798..6c379e241def7 100644 --- a/unittests/runtime/weak.mm +++ b/unittests/runtime/weak.mm @@ -1,8 +1,8 @@ -//===- swift/unittests/runtime/weak.mm - Weak-pointer tests ---------------===// +//===--- weak.mm - Weak-pointer tests -------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -39,6 +39,10 @@ - (void) dealloc { // make_swift_object is defined in TestHelpers.swift as part of StdlibUnittest. extern "C" HeapObject *make_swift_object(); +static unsigned getUnownedRetainCount(HeapObject *object) { + return object->weakRefCount.getCount() - 1; +} + static void unknown_release(void *value) { objc_release((id) value); } @@ -285,19 +289,553 @@ static void unknown_release(void *value) { swift_unknownWeakDestroy(&ref1); } -TEST(WeakTest, objc_weak_release_after_strong_release) { - DestroyedObjCCount = 0; +TEST(WeakTest, objc_unowned_basic) { + UnownedReference ref; + void *objc1 = make_objc_object(); + void *objc2 = make_objc_object(); + HeapObject *swift1 = make_swift_object(); + HeapObject *swift2 = make_swift_object(); + + ASSERT_NE(objc1, objc2); + ASSERT_NE(swift1, swift2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + ASSERT_EQ(0U, getUnownedRetainCount(swift2)); + + void *result; + + // ref = swift1 + swift_unknownUnownedInit(&ref, swift1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref); + ASSERT_EQ(swift1, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + swift_unknownUnownedDestroy(&ref); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + + // ref = objc1 + swift_unknownUnownedInit(&ref, objc1); + result = swift_unknownUnownedLoadStrong(&ref); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref = objc1 (objc self transition) + swift_unknownUnownedAssign(&ref, objc1); + result = swift_unknownUnownedLoadStrong(&ref); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref = objc2 (objc -> objc transition) + swift_unknownUnownedAssign(&ref, objc2); + result = swift_unknownUnownedLoadStrong(&ref); + ASSERT_EQ(objc2, result); + swift_unknownRelease(result); + + // ref = swift1 (objc -> swift transition) + swift_unknownUnownedAssign(&ref, swift1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref); + ASSERT_EQ(swift1, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + + // ref = swift1 (swift self transition) + swift_unknownUnownedAssign(&ref, swift1); + result = swift_unknownUnownedLoadStrong(&ref); + ASSERT_EQ(swift1, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + + // ref = swift2 (swift -> swift transition) + swift_unknownUnownedAssign(&ref, swift2); + result = swift_unknownUnownedLoadStrong(&ref); + ASSERT_EQ(swift2, result); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + ASSERT_EQ(1U, getUnownedRetainCount(swift2)); + swift_unknownRelease(result); + + // ref = objc1 (swift -> objc transition) + swift_unknownUnownedAssign(&ref, objc1); + result = swift_unknownUnownedLoadStrong(&ref); + ASSERT_EQ(objc1, result); + ASSERT_EQ(0U, getUnownedRetainCount(swift2)); + swift_unknownRelease(result); + + swift_unknownUnownedDestroy(&ref); + + swift_unknownRelease(objc1); + swift_unknownRelease(objc2); + swift_unknownRelease(swift1); + swift_unknownRelease(swift2); +} - void *o = make_objc_object(); - // strong 1, unowned 0 +TEST(WeakTest, objc_unowned_takeStrong) { + UnownedReference ref; + void *objc1 = make_objc_object(); + HeapObject *swift1 = make_swift_object(); + + void *result; + + // ref = objc1 + swift_unknownUnownedInit(&ref, objc1); + result = swift_unknownUnownedTakeStrong(&ref); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref = swift1 + swift_unknownUnownedInit(&ref, swift1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedTakeStrong(&ref); + ASSERT_EQ(swift1, result); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + + swift_unknownRelease(objc1); + swift_unknownRelease(swift1); +} - swift_unknownWeakRetain(o); - // strong 1, unowned 1 +TEST(WeakTest, objc_unowned_copyInit_nil) { + UnownedReference ref1; + UnownedReference ref2; - swift_unknownRelease(o); - // strong 0, unowned 1 -- object gets greedily deallocated by ObjC runtime - ASSERT_EQ(1U, DestroyedObjCCount); - - swift_unknownWeakRelease(o); - // strong 0, unowned 0 + void *result; + + // ref1 = nil + swift_unknownUnownedInit(&ref1, nullptr); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(nullptr, result); + + // ref2 = ref1 (nil -> nil) + swift_unknownUnownedCopyInit(&ref2, &ref1); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(nullptr, result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(nullptr, result); + swift_unknownUnownedDestroy(&ref2); +} + +TEST(WeakTest, objc_unowned_copyInit_objc) { + UnownedReference ref1; + UnownedReference ref2; + + void *result; + void *objc1 = make_objc_object(); + + // ref1 = objc1 + swift_unknownUnownedInit(&ref1, objc1); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref2 = ref1 (objc -> objc) + swift_unknownUnownedCopyInit(&ref2, &ref1); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + swift_unknownUnownedDestroy(&ref2); + + swift_unknownUnownedDestroy(&ref1); + + swift_unknownRelease(objc1); +} + +TEST(WeakTest, objc_unowned_copyInit_swift) { + UnownedReference ref1; + UnownedReference ref2; + + void *result; + + HeapObject *swift1 = make_swift_object(); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + + // ref1 = swift1 + swift_unknownUnownedInit(&ref1, swift1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + + // ref2 = ref1 (swift -> swift) + swift_unknownUnownedCopyInit(&ref2, &ref1); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + swift_unknownUnownedDestroy(&ref2); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + + // ref2 = ref1 + // ref2 = nil + swift_unknownUnownedCopyInit(&ref2, &ref1); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + swift_unknownUnownedAssign(&ref2, nullptr); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(nullptr, result); + swift_unknownRelease(result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownUnownedDestroy(&ref2); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + + swift_unknownUnownedDestroy(&ref1); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + + swift_unknownRelease(swift1); +} + +TEST(WeakTest, objc_unowned_takeInit_nil) { + UnownedReference ref1; + UnownedReference ref2; + + void *result; + + // ref1 = nil + swift_unknownUnownedInit(&ref1, nullptr); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(nullptr, result); + + // ref2 = ref1 (nil -> nil) + swift_unknownUnownedTakeInit(&ref2, &ref1); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(nullptr, result); + swift_unknownUnownedDestroy(&ref2); +} + +TEST(WeakTest, objc_unowned_takeInit_objc) { + UnownedReference ref1; + UnownedReference ref2; + + void *result; + void *objc1 = make_objc_object(); + + // ref1 = objc1 + swift_unknownUnownedInit(&ref1, objc1); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref2 = ref1 (objc -> objc) + swift_unknownUnownedTakeInit(&ref2, &ref1); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + swift_unknownUnownedDestroy(&ref2); + + swift_unknownRelease(objc1); +} + +TEST(WeakTest, objc_unowned_takeInit_swift) { + UnownedReference ref1; + UnownedReference ref2; + + void *result; + + HeapObject *swift1 = make_swift_object(); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + + // ref1 = swift1 + swift_unknownUnownedInit(&ref1, swift1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + + // ref2 = ref1 (swift -> swift) + swift_unknownUnownedTakeInit(&ref2, &ref1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownUnownedDestroy(&ref2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + + // ref1 = swift1 + swift_unknownUnownedInit(&ref1, swift1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + + // ref2 = ref1 + // ref2 = nil + swift_unknownUnownedTakeInit(&ref2, &ref1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownUnownedAssign(&ref2, nullptr); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(nullptr, result); + + swift_unknownUnownedDestroy(&ref2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + + swift_unknownRelease(swift1); +} + +TEST(WeakTest, objc_unowned_copyAssign) { + UnownedReference ref1; + UnownedReference ref2; + void *objc1 = make_objc_object(); + void *objc2 = make_objc_object(); + HeapObject *swift1 = make_swift_object(); + HeapObject *swift2 = make_swift_object(); + + ASSERT_NE(objc1, objc2); + ASSERT_NE(swift1, swift2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + ASSERT_EQ(0U, getUnownedRetainCount(swift2)); + + void *result; + + // ref1 = objc1 + swift_unknownUnownedInit(&ref1, objc1); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref2 = objc1 + swift_unknownUnownedInit(&ref2, objc1); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref1 = ref2 (objc self transition) + swift_unknownUnownedCopyAssign(&ref1, &ref2); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref2 = objc2 + swift_unknownUnownedAssign(&ref2, objc2); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc2, result); + swift_unknownRelease(result); + + // ref1 = ref2 (objc -> objc transition) + swift_unknownUnownedCopyAssign(&ref1, &ref2); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc2, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc2, result); + swift_unknownRelease(result); + + // ref2 = swift1 + swift_unknownUnownedAssign(&ref2, swift1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift1, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + + // ref1 = ref2 (objc -> swift transition) + swift_unknownUnownedCopyAssign(&ref1, &ref2); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + + // ref2 = swift1 + swift_unknownUnownedAssign(&ref2, swift1); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + + // ref1 = ref2 (swift self transition) + swift_unknownUnownedCopyAssign(&ref1, &ref2); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift1, result); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + + // ref2 = swift2 + swift_unknownUnownedAssign(&ref2, swift2); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + ASSERT_EQ(1U, getUnownedRetainCount(swift2)); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift2, result); + swift_unknownRelease(result); + + // ref1 = ref2 (swift -> swift transition) + swift_unknownUnownedCopyAssign(&ref1, &ref2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + ASSERT_EQ(2U, getUnownedRetainCount(swift2)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift2, result); + ASSERT_EQ(2U, getUnownedRetainCount(swift2)); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift2, result); + ASSERT_EQ(2U, getUnownedRetainCount(swift2)); + swift_unknownRelease(result); + + // ref2 = objc1 + swift_unknownUnownedAssign(&ref2, objc1); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc1, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift2)); + swift_unknownRelease(result); + + // ref1 = ref2 (swift -> objc transition) + swift_unknownUnownedCopyAssign(&ref1, &ref2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + ASSERT_EQ(0U, getUnownedRetainCount(swift2)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + swift_unknownUnownedDestroy(&ref1); + swift_unknownUnownedDestroy(&ref2); + + swift_unknownRelease(objc1); + swift_unknownRelease(objc2); + swift_unknownRelease(swift1); + swift_unknownRelease(swift2); +} + +TEST(WeakTest, objc_unowned_takeAssign) { + UnownedReference ref1; + UnownedReference ref2; + void *objc1 = make_objc_object(); + void *objc2 = make_objc_object(); + HeapObject *swift1 = make_swift_object(); + HeapObject *swift2 = make_swift_object(); + + ASSERT_NE(objc1, objc2); + ASSERT_NE(swift1, swift2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + ASSERT_EQ(0U, getUnownedRetainCount(swift2)); + + void *result; + + // ref1 = objc1 + swift_unknownUnownedInit(&ref1, objc1); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref2 = objc1 + swift_unknownUnownedInit(&ref2, objc1); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref1 = ref2 (objc self transition) + swift_unknownUnownedTakeAssign(&ref1, &ref2); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + // ref2 = objc2 + swift_unknownUnownedInit(&ref2, objc2); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc2, result); + swift_unknownRelease(result); + + // ref1 = ref2 (objc -> objc transition) + swift_unknownUnownedTakeAssign(&ref1, &ref2); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc2, result); + swift_unknownRelease(result); + + // ref2 = swift1 + swift_unknownUnownedInit(&ref2, swift1); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift1, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + + // ref1 = ref2 (objc -> swift transition) + swift_unknownUnownedTakeAssign(&ref1, &ref2); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + + // ref2 = swift1 + swift_unknownUnownedInit(&ref2, swift1); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift1, result); + swift_unknownRelease(result); + ASSERT_EQ(2U, getUnownedRetainCount(swift1)); + + // ref1 = ref2 (swift self transition) + swift_unknownUnownedTakeAssign(&ref1, &ref2); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift1, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + swift_unknownRelease(result); + + // ref2 = swift2 + swift_unknownUnownedInit(&ref2, swift2); + ASSERT_EQ(1U, getUnownedRetainCount(swift1)); + ASSERT_EQ(1U, getUnownedRetainCount(swift2)); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(swift2, result); + swift_unknownRelease(result); + + // ref1 = ref2 (swift -> swift transition) + swift_unknownUnownedTakeAssign(&ref1, &ref2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + ASSERT_EQ(1U, getUnownedRetainCount(swift2)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(swift2, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift2)); + swift_unknownRelease(result); + + // ref2 = objc1 + swift_unknownUnownedInit(&ref2, objc1); + result = swift_unknownUnownedLoadStrong(&ref2); + ASSERT_EQ(objc1, result); + ASSERT_EQ(1U, getUnownedRetainCount(swift2)); + swift_unknownRelease(result); + + // ref1 = ref2 (swift -> objc transition) + swift_unknownUnownedTakeAssign(&ref1, &ref2); + ASSERT_EQ(0U, getUnownedRetainCount(swift1)); + ASSERT_EQ(0U, getUnownedRetainCount(swift2)); + result = swift_unknownUnownedLoadStrong(&ref1); + ASSERT_EQ(objc1, result); + swift_unknownRelease(result); + + swift_unknownUnownedDestroy(&ref1); + + swift_unknownRelease(objc1); + swift_unknownRelease(objc2); + swift_unknownRelease(swift1); + swift_unknownRelease(swift2); } diff --git a/utils/GYBUnicodeDataUtils.py b/utils/GYBUnicodeDataUtils.py index 37004d78671b8..2007e37e3cddb 100644 --- a/utils/GYBUnicodeDataUtils.py +++ b/utils/GYBUnicodeDataUtils.py @@ -2,7 +2,7 @@ ## ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information @@ -11,6 +11,8 @@ ##===----------------------------------------------------------------------===## import re +import sys +import codecs class UnicodeProperty(object): """Abstract base class for Unicode properties.""" @@ -64,11 +66,11 @@ def __init__(self, grapheme_break_property_file_name): # values to symbolic values. self.symbolic_values = \ [ None ] * (max(self.numeric_value_table.values()) + 1) - for k,v in self.numeric_value_table.iteritems(): + for k,v in self.numeric_value_table.items(): self.symbolic_values[v] = k # Load the data file. - with open(grapheme_break_property_file_name, 'rb') as f: + with codecs.open(grapheme_break_property_file_name, encoding='utf-8', errors='strict') as f: for line in f: # Strip comments. line = re.sub('#.*', '', line) @@ -248,7 +250,7 @@ def create_tables(self): # maximum Unicode code point value is not 2^21-1 (0x1fffff), it is # 0x10ffff. self.supp_first_level_index_max = \ - 0x10ffff >> (self.supp_second_level_index_bits + \ + 0x10ffff >> (self.supp_second_level_index_bits + self.supp_data_offset_bits) # A mapping from BMP first-level index to BMP data block index. @@ -329,7 +331,10 @@ def map_index(idx): else: return idx - return map(map_index, indexes) + # NOTE: Python 2's `map` function returns a list. Where Python 3's + # `map` function returns an iterator. To work around this the + # result of the `map` is explicitly converted to a `list`. + return list(map(map_index, indexes)) # If self.BMP_data contains identical data blocks, keep the first one, # remove duplicates and change the indexes in self.BMP_lookup to point to @@ -514,9 +519,9 @@ def _convert_line(line): # Match a list of code points. for token in line.split(" "): - if token == "÷": + if token == u"÷": boundaries += [ curr_bytes ] - elif token == "×": + elif token == u"×": pass else: code_point = int(token, 16) @@ -529,21 +534,21 @@ def _convert_line(line): # and test separately that we handle ill-formed UTF-8 sequences. if code_point >= 0xd800 and code_point <= 0xdfff: code_point = 0x200b - code_point = ('\U%(cp)08x' % { 'cp': code_point }).decode('unicode_escape') - as_UTF8_bytes = code_point.encode('utf8') - as_UTF8_escaped = ''.join(['\\x%(byte)02x' % { 'byte': ord(byte) } for byte in as_UTF8_bytes]) + code_point = (b'\U%(cp)08x' % { b'cp': code_point }).decode('unicode_escape', 'strict') + as_UTF8_bytes = bytearray(code_point.encode('utf8', 'strict')) + as_UTF8_escaped = ''.join(['\\x%(byte)02x' % { 'byte': byte } for byte in as_UTF8_bytes]) test += as_UTF8_escaped curr_bytes += len(as_UTF8_bytes) return (test, boundaries) # Self-test. - assert(_convert_line('÷ 0903 × 0308 ÷ AC01 ÷ # abc') == ('\\xe0\\xa4\\x83\\xcc\\x88\\xea\\xb0\\x81', [ 0, 5, 8 ])) - assert(_convert_line('÷ D800 ÷ # abc') == ('\\xe2\\x80\\x8b', [ 0, 3 ])) + assert(_convert_line(u'÷ 0903 × 0308 ÷ AC01 ÷ # abc') == ('\\xe0\\xa4\\x83\\xcc\\x88\\xea\\xb0\\x81', [ 0, 5, 8 ])) + assert(_convert_line(u'÷ D800 ÷ # abc') == ('\\xe2\\x80\\x8b', [ 0, 3 ])) result = [] - with open(grapheme_break_test_file_name, 'rb') as f: + with codecs.open(grapheme_break_test_file_name, encoding='utf-8', errors='strict') as f: for line in f: test = _convert_line(line) if test: diff --git a/utils/SwiftBuildSupport.py b/utils/SwiftBuildSupport.py index d87121c68b8ff..8842b10148d26 100644 --- a/utils/SwiftBuildSupport.py +++ b/utils/SwiftBuildSupport.py @@ -1,18 +1,20 @@ -#===--- SwiftBuildSupport.py - Utilities for Swift build scripts -----------===# +# utils/SwiftBuildSupport.py - Utilities for Swift build scripts -*- python -*- # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -# -#===------------------------------------------------------------------------===# from __future__ import print_function -import ConfigParser +try: + import ConfigParser # Python 2 +except ImportError: + import configparser as ConfigParser # Python 3 + import os import pipes import subprocess @@ -64,11 +66,6 @@ def print_with_argv0(message): print(sys.argv[0] + ": " + message) -def bad_usage(message): - print_with_argv0(message) - print("Run '" + pipes.quote(sys.argv[0]) + " --help' for more information.") - sys.exit(1) - def quote_shell_command(args): return " ".join([ pipes.quote(a) for a in args ]) @@ -129,12 +126,24 @@ def _load_preset_files_impl(preset_file_names, substitutions={}): def _get_preset_options_impl(config, substitutions, preset_name): section_name = _PRESET_PREFIX + preset_name if section_name not in config.sections(): - return (None, None) + return (None, None, None) build_script_opts = [] build_script_impl_opts = [] + missing_opts = [] dash_dash_seen = False - for o, a in config.items(section_name): + + for o in config.options(section_name): + try: + a = config.get(section_name, o) + except ConfigParser.InterpolationMissingOptionError as e: + # e.reference contains the correctly formatted option + missing_opts.append(e.reference) + continue + + if not a: + a = "" + if o in substitutions: continue @@ -143,10 +152,13 @@ def _get_preset_options_impl(config, substitutions, preset_name): # Split on newlines and filter out empty lines. mixins = filter(None, [m.strip() for m in a.splitlines()]) for mixin in mixins: - (base_build_script_opts, base_build_script_impl_opts) = \ + (base_build_script_opts, + base_build_script_impl_opts, + base_missing_opts) = \ _get_preset_options_impl(config, substitutions, mixin) build_script_opts += base_build_script_opts build_script_impl_opts += base_build_script_impl_opts + missing_opts += base_missing_opts elif o == "dash-dash": dash_dash_seen = True elif a == "": @@ -159,17 +171,22 @@ def _get_preset_options_impl(config, substitutions, preset_name): build_script_opts.append(opt) else: build_script_impl_opts.append(opt) - return (build_script_opts, build_script_impl_opts) + + return (build_script_opts, build_script_impl_opts, missing_opts) def get_preset_options(substitutions, preset_file_names, preset_name): config = _load_preset_files_impl(preset_file_names, substitutions) - (build_script_opts, build_script_impl_opts) = \ + (build_script_opts, build_script_impl_opts, missing_opts) = \ _get_preset_options_impl(config, substitutions, preset_name) - if build_script_opts is None: + if not build_script_opts: print_with_argv0("preset '" + preset_name + "' not found") sys.exit(1) + if missing_opts: + print_with_argv0("missing option(s) for preset '" + preset_name + + "': " + ", ".join(missing_opts)) + sys.exit(1) return build_script_opts + [ "--" ] + build_script_impl_opts @@ -194,4 +211,3 @@ def __enter__(self): def __exit__(self, type, value, traceback): os.chdir(self.old_cwd) - diff --git a/utils/SwiftIntTypes.py b/utils/SwiftIntTypes.py index 0d5fb0e9037fe..c43128e071d19 100644 --- a/utils/SwiftIntTypes.py +++ b/utils/SwiftIntTypes.py @@ -2,7 +2,7 @@ ## ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information diff --git a/utils/apply-fixit-edits.py b/utils/apply-fixit-edits.py index 674ee7745c0e1..0ca4cc0f39253 100755 --- a/utils/apply-fixit-edits.py +++ b/utils/apply-fixit-edits.py @@ -1,42 +1,38 @@ #!/usr/bin/env python - -#===--- apply-fixit-edits.py - Tool for applying edits from .remap files ---===# +# utils/apply-fixit-edits.py - Apply edits from .remap files -*- python -*- # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -# -#===------------------------------------------------------------------------===# +from __future__ import print_function -import subprocess import json import argparse import sys +import os def find_remap_files(path): - out = None - try: - out = subprocess.check_output(["find", path, "-name", "*.remap"]) - except subprocess.CalledProcessError: - return None - lines = out.split('\n') - lines.pop(-1) - return lines + for root, dirs, files in os.walk(path): + for filename in files: + if not filename.endswith(".remap"): + continue + yield os.path.join(root, filename) def apply_edits(path): remap_files = find_remap_files(path) if not remap_files: - print "No remap files found" - return 1; + print("No remap files found") + return 1 edits_set = set() for remap_file in remap_files: - json_data = open(remap_file).read() + with open(remap_file) as f: + json_data = f.read() json_data = json_data.replace(",\n }", "\n }") json_data = json_data.replace(",\n]", "\n]") curr_edits = json.loads(json_data) @@ -50,20 +46,22 @@ def apply_edits(path): edits_per_file = {} for ed in edits_set: fname = ed[0] - if not edits_per_file.has_key(fname): + if fname not in edits_per_file: edits_per_file[fname] = [] edits_per_file[fname].append((ed[1], ed[2], ed[3])) for fname, edits in edits_per_file.iteritems(): - print 'Updating', fname + print('Updating', fname) edits.sort(reverse=True) - file_data = open(fname).read() + with open(fname) as f: + file_data = f.read() for ed in edits: offset = ed[0] length = ed[1] text = ed[2] file_data = file_data[:offset] + str(text) + file_data[offset+length:] - open(fname, 'w').write(file_data) + with open(fname, 'w') as f: + f.write(file_data) return 0 def main(): diff --git a/utils/benchmark/Ackermann/Ackermann.cpp b/utils/benchmark/Ackermann/Ackermann.cpp deleted file mode 100644 index 6470c366a6fc7..0000000000000 --- a/utils/benchmark/Ackermann/Ackermann.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -*- mode: c++ -*- -// $Id: ackermann.g++,v 1.3 2001/06/20 03:20:02 doug Exp $ -// http://www.bagley.org/~doug/shootout/ -// -// With some modifications to improve timing. - -#include -#include -#include - -extern "C" { -#include -} - -using namespace std; - -int Ack(int M, int N) { - if (M == 0) return( N + 1 ); - if (N == 0) return( Ack(M - 1, 1) ); - return( Ack(M - 1, Ack(M, (N - 1))) ); -} - -int main(int argc, char *argv[]) { - // Only time Ack not buffering or c++ or anything like that. - uint64_t start = mach_absolute_time(); - volatile int result = Ack(3, 13); - uint64_t end = mach_absolute_time() - start; - - printf("%llu nanoseconds.\n", end); - return result; -} diff --git a/utils/benchmark/Ackermann/Ackermann.swift b/utils/benchmark/Ackermann/Ackermann.swift deleted file mode 100644 index 9e4206d21dcea..0000000000000 --- a/utils/benchmark/Ackermann/Ackermann.swift +++ /dev/null @@ -1 +0,0 @@ -benchAckermann() diff --git a/utils/benchmark/BST/bst.py b/utils/benchmark/BST/bst.py deleted file mode 100644 index 3427b26a57f70..0000000000000 --- a/utils/benchmark/BST/bst.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python -# -# A binary search tree. -class BST: - class Node: - left, right, key = None, None, 0 - - def __init__(self, key): - self.left = None - self.right = None - self.key = key - - def __init__(self): - self.root = None - - def insert(self, key): - if not self.root: - self.root = BST.Node(key) - return True - return self.insertInto(key, self.root) - - def insertInto(self, key, node): - if key == node.key: - return False - if key < node.key: - if node.left: - return self.insertInto(key, node.left) - else: - node.left = BST.Node(key) - return True - else: - if node.right: - return self.insertInto(key, node.right) - else: - node.right = BST.Node(key) - return True - - def find(self, key): - return self.findIn(key, self.root) - - def findIn(self, key, node): - if not node: - return False - if key == node.key: - return True - if key < node.key: - return self.findIn(node.left, key) - else: - return self.findIn(node.right, key) - - def minKey(self): - if not self.root: - return None - node = self.root - while (node.left): - node = node.left - return node.key - - def maxKey(self): - if not self.root: - return None - node = self.root - while (node.right): - node = node.right - return node.key - - def depth(self): - return self.depthIn(self.root) - - def depthIn(self, node): - if not node: - return 0 - leftDepth = self.depthIn(node.left) - rightDepth = self.depthIn(node.right) - return max(leftDepth, rightDepth) + 1 - - def size(self): - return self.sizeIn(self.root) - - def sizeIn(self, node): - if not node: - return 0 - return 1 + self.sizeIn(node.left) + self.sizeIn(node.right) - - def visitInorder(self, f): - self.visitInorderSubtree(f, self.root) - - def visitInorderSubtree(self, f, node): - if not node: - return - self.visitInorderSubtree(f, node.left) - f(node.key) - self.visitInorderSubtree(f, node.right) - -def printKey(key): - print key, - -def usage(): - print "Usage: bst " - -if __name__ == "__main__": - import sys, lfsr - if len(sys.argv) != 2: - usage() - sys.exit(1) - - bst = BST() - lfsr = lfsr.LFSR() - for i in range(0,int(sys.argv[1])): - bst.insert(lfsr.randInt()) - - print "Size:", bst.size() - print "Depth:", bst.depth() - print "Range:", bst.minKey(), "-", bst.maxKey() - print "Values:", - bst.visitInorder(printKey) diff --git a/utils/benchmark/BST/bst.swift b/utils/benchmark/BST/bst.swift deleted file mode 100644 index 33396b83aa149..0000000000000 --- a/utils/benchmark/BST/bst.swift +++ /dev/null @@ -1,145 +0,0 @@ -// A binary search tree. -// -// TODO: make it generic once we handle the basics. -class BST { - class Node { - var left:Node? - var right:Node? - var key:Int = 0 - - init(_ key:Int) { - self.key = key - } - } - - var root:Node? - - func insert(key:Int) -> Bool { - if !root { - root = BST.Node(key) - return true - } - return insertInto(key, node: root!) - } - - // Written this way for tail recursion. - func insertInto(key:Int, node:Node) -> Bool { - if key == node.key { - return false - } - if key < node.key { - if node.left { - return insertInto(key, node: node.left!) - } else { - node.left = BST.Node(key) - return true - } - } else { - if node.right { - return insertInto(key, node: node.right!) - } else { - node.right = BST.Node(key) - return true - } - } - } - - func find(key:Int) -> Bool { - return findIn(key, node: root) - } - - func findIn(key:Int, node:Node?) -> Bool { - if !node { - return false - } - let n = node! - if key == n.key { - return true - } - if key < n.key { - return self.findIn(key, node: n.left) - } else { - return self.findIn(key, node: n.right) - } - } - - func minKey() -> Int? { - if !root { - return nil - } - var node = root! - while (node.left) { - node = node.left! - } - return node.key - } - - func maxKey() -> Int? { - if !root { - return nil - } - var node = root! - while (node.right) { - node = node.right! - } - return node.key - } - - func depth() -> Int { - return depthIn(root) - } - - func depthIn(node:Node?) ->Int { - if !node { - return 0 - } - let n = node! - let leftDepth = depthIn(n.left) - let rightDepth = depthIn(n.right) - return max(leftDepth, rightDepth) + 1 - } - - func size() -> Int { - return sizeIn(root) - } - - func sizeIn(node:Node?) -> Int { - if let n = node { - return 1 + sizeIn(n.left) + sizeIn(n.right) - } - return 0 - } - - func visitInorder(f:(Int) -> ()) { - self.visitInorderSubtree(f, node: root) - } - func visitInorderSubtree(f:(Int) -> (), node:Node?) { - if let n = node { - self.visitInorderSubtree(f, node: n.left) - f(n.key) - self.visitInorderSubtree(f, node: n.right) - } - } -} - -import liblfsr - -func test(N:Int) { - var bst = BST() - var lfsr = LFSR() - for i in 0..N { - bst.insert(lfsr.randInt()) - } - print("Size \(bst.size())") - print("Depth \(bst.depth())") - if let min = bst.minKey() { - let max = bst.maxKey()! - print("Range \(min) - \(max)") - } - print("Values: ") - bst.visitInorder({print("\($0) ")}) - print("") -} - -// I'm embarassed that I don't know how to read cmd line args. -test(1000) diff --git a/utils/benchmark/BST/lfsr.py b/utils/benchmark/BST/lfsr.py deleted file mode 100644 index bfc7f1c3f7fe0..0000000000000 --- a/utils/benchmark/BST/lfsr.py +++ /dev/null @@ -1,29 +0,0 @@ -# Linear function shift register. -# -# This is just to drive benchmarks. I don't make any claim about its -# strength. According to Wikipedia, it has the maximal period for a -# 32-bit register. -class LFSR: - def __init__(self): - # set the register to some seed - self.lfsr = 0xb78978e7 - - def shift(self): - self.lfsr = (self.lfsr >> 1) ^ (-(self.lfsr & 1) & 0xD0000001) - - def randInt(self): - result = 0 - for i in range(0,32): - result = (result << 1) | self.lfsr & 1 - self.shift() - return result - -if __name__ == "__main__": - import sys, sets - lfsr = LFSR() - rands = sets.Set() - for i in range (0,int(sys.argv[1])): - r = lfsr.randInt() - assert r not in rands - rands.add(r) - print r diff --git a/utils/benchmark/BST/lfsr.swift b/utils/benchmark/BST/lfsr.swift deleted file mode 100644 index 3f986e3186e96..0000000000000 --- a/utils/benchmark/BST/lfsr.swift +++ /dev/null @@ -1,32 +0,0 @@ -// Linear function shift register. -// -// This is just to drive benchmarks. I don't make any claim about its -// strength. According to Wikipedia, it has the maximal period for a -// 32-bit register. -class LFSR { - // Set the register to some seed that I pulled out of a hat. - var lfsr = 0xb78978e7 - - func shift() { - lfsr = (lfsr >> 1) ^ (-(lfsr & 1) & 0xD0000001) - } - func randInt() -> Int { - var result = 0 - for i in 0..<32 { - result = (result << 1) | lfsr & 1 - shift() - } - return result - } -} - -func test() { - var lfsr = LFSR() - var rands = Dictionary() - for i in 0..<1000 { - let r = lfsr.randInt() - assert(!rands[r]) - rands[r] = true - print(r) - } -} diff --git a/utils/benchmark/Benchmark.swift b/utils/benchmark/Benchmark.swift deleted file mode 100644 index c86128b2b80ea..0000000000000 --- a/utils/benchmark/Benchmark.swift +++ /dev/null @@ -1,1272 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - - -//////////////////////////////////////////////////////////////////////////////// -// -// This file contains a small number of swift benchmarks. -// At the moment we can't serialize large chunks of the swift standard library, -// which prevents us from optimizing user code. In order to evaluate the -// performance of swift we decided to place some benchmarks in the standard -// library and evaluate the optimized versions. -// -// This file will be removed as soon as rdar://14747929 is fixed. -// -//////////////////////////////////////////////////////////////////////////////// -@_silgen_name("mach_absolute_time") func __mach_absolute_time__() -> UInt64 - -var stringBenchmarkWords: String[] = [ - "woodshed", - "lakism", - "gastroperiodynia", - "afetal", - "ramsch", - "Nickieben", - "undutifulness", - "birdglue", - "ungentlemanize", - "menacingly", - "heterophile", - "leoparde", - "Casearia", - "decorticate", - "neognathic", - "mentionable", - "tetraphenol", - "pseudonymal", - "dislegitimate", - "Discoidea", - "intitule", - "ionium", - "Lotuko", - "timbering", - "nonliquidating", - "oarialgia", - "Saccobranchus", - "reconnoiter", - "criminative", - "disintegratory", - "executer", - "Cylindrosporium", - "complimentation", - "Ixiama", - "Araceae", - "silaginoid", - "derencephalus", - "Lamiidae", - "marrowlike", - "ninepin", - "dynastid", - "lampfly", - "feint", - "trihemimer", - "semibarbarous", - "heresy", - "tritanope", - "indifferentist", - "confound", - "hyperbolaeon", - "planirostral", - "philosophunculist", - "existence", - "fretless", - "Leptandra", - "Amiranha", - "handgravure", - "gnash", - "unbelievability", - "orthotropic", - "Susumu", - "teleutospore", - "sleazy", - "shapeliness", - "hepatotomy", - "exclusivism", - "stifler", - "cunning", - "isocyanuric", - "pseudepigraphy", - "carpetbagger", - "respectiveness", - "Jussi", - "vasotomy", - "proctotomy", - "ovatotriangular", - "aesthetic", - "schizogamy", - "disengagement", - "foray", - "haplocaulescent", - "noncoherent", - "astrocyte", - "unreverberated", - "presenile", - "lanson", - "enkraal", - "contemplative", - "Syun", - "sartage", - "unforgot", - "wyde", - "homeotransplant", - "implicational", - "forerunnership", - "calcaneum", - "stomatodeum", - "pharmacopedia", - "preconcessive", - "trypanosomatic", - "intracollegiate", - "rampacious", - "secundipara", - "isomeric", - "treehair", - "pulmonal", - "uvate", - "dugway", - "glucofrangulin", - "unglory", - "Amandus", - "icterogenetic", - "quadrireme", - "Lagostomus", - "brakeroot", - "anthracemia", - "fluted", - "protoelastose", - "thro", - "pined", - "Saxicolinae", - "holidaymaking", - "strigil", - "uncurbed", - "starling", - "redeemeress", - "Liliaceae", - "imparsonee", - "obtusish", - "brushed", - "mesally", - "probosciformed", - "Bourbonesque", - "histological", - "caroba", - "digestion", - "Vindemiatrix", - "triactinal", - "tattling", - "arthrobacterium", - "unended", - "suspectfulness", - "movelessness", - "chartist", - "Corynebacterium", - "tercer", - "oversaturation", - "Congoleum", - "antiskeptical", - "sacral", - "equiradiate", - "whiskerage", - "panidiomorphic", - "unplanned", - "anilopyrine", - "Queres", - "tartronyl", - "Ing", - "notehead", - "finestiller", - "weekender", - "kittenhood", - "competitrix", - "premillenarian", - "convergescence", - "microcoleoptera", - "slirt", - "asteatosis", - "Gruidae", - "metastome", - "ambuscader", - "untugged", - "uneducated", - "redistill", - "rushlight", - "freakish", - "dosology", - "papyrine", - "iconologist", - "Bidpai", - "prophethood", - "pneumotropic", - "chloroformize", - "intemperance", - "spongiform", - "superindignant", - "divider", - "starlit", - "merchantish", - "indexless", - "unidentifiably", - "coumarone", - "nomism", - "diaphanous", - "salve", - "option", - "anallantoic", - "paint", - "thiofurfuran", - "baddeleyite", - "Donne", - "heterogenicity", - "decess", - "eschynite", - "mamma", - "unmonarchical", - "Archiplata", - "widdifow", - "apathic", - "overline", - "chaetophoraceous", - "creaky", - "trichosporange", - "uninterlined", - "cometwise", - "hermeneut", - "unbedraggled", - "tagged", - "Sminthurus", - "somniloquacious", - "aphasiac", - "Inoperculata", - "photoactivity", - "mobship", - "unblightedly", - "lievrite", - "Khoja", - "Falerian", - "milfoil", - "protectingly", - "householder", - "cathedra", - "calmingly", - "tordrillite", - "rearhorse", - "Leonard", - "maracock", - "youngish", - "kammererite", - "metanephric", - "Sageretia", - "diplococcoid", - "accelerative", - "choreal", - "metalogical", - "recombination", - "unimprison", - "invocation", - "syndetic", - "toadback", - "vaned", - "cupholder", - "metropolitanship", - "paramandelic", - "dermolysis", - "Sheriyat", - "rhabdus", - "seducee", - "encrinoid", - "unsuppliable", - "cololite", - "timesaver", - "preambulate", - "sampling", - "roaster", - "springald", - "densher", - "protraditional", - "naturalesque", - "Hydrodamalis", - "cytogenic", - "shortly", - "cryptogrammatical", - "squat", - "genual", - "backspier", - "solubleness", - "macroanalytical", - "overcovetousness", - "Natalie", - "cuprobismutite", - "phratriac", - "Montanize", - "hymnologist", - "karyomiton", - "podger", - "unofficiousness", - "antisplasher", - "supraclavicular", - "calidity", - "disembellish", - "antepredicament", - "recurvirostral", - "pulmonifer", - "coccidial", - "botonee", - "protoglobulose", - "isonym", - "myeloid", - "premiership", - "unmonopolize", - "unsesquipedalian", - "unfelicitously", - "theftbote", - "undauntable", - "lob", - "praenomen", - "underriver", - "gorfly", - "pluckage", - "radiovision", - "tyrantship", - "fraught", - "doppelkummel", - "rowan", - "allosyndetic", - "kinesiology", - "psychopath", - "arrent", - "amusively", - "preincorporation", - "Montargis", - "pentacron", - "neomedievalism", - "sima", - "lichenicolous", - "Ecclesiastes", - "woofed", - "cardinalist", - "sandaracin", - "gymnasial", - "lithoglyptics", - "centimeter", - "quadrupedous", - "phraseology", - "tumuli", - "ankylotomy", - "myrtol", - "cohibitive", - "lepospondylous", - "silvendy", - "inequipotential", - "entangle", - "raveling", - "Zeugobranchiata", - "devastating", - "grainage", - "amphisbaenian", - "blady", - "cirrose", - "proclericalism", - "governmentalist", - "carcinomorphic", - "nurtureship", - "clancular", - "unsteamed", - "discernibly", - "pleurogenic", - "impalpability", - "Azotobacterieae", - "sarcoplasmic", - "alternant", - "fitly", - "acrorrheuma", - "shrapnel", - "pastorize", - "gulflike", - "foreglow", - "unrelated", - "cirriped", - "cerviconasal", - "sexuale", - "pussyfooter", - "gadolinic", - "duplicature", - "codelinquency", - "trypanolysis", - "pathophobia", - "incapsulation", - "nonaerating", - "feldspar", - "diaphonic", - "epiglottic", - "depopulator", - "wisecracker", - "gravitational", - "kuba", - "lactesce", - "Toxotes", - "periomphalic", - "singstress", - "fannier", - "counterformula", - "Acemetae", - "repugnatorial", - "collimator", - "Acinetina", - "unpeace", - "drum", - "tetramorphic", - "descendentalism", - "cementer", - "supraloral", - "intercostal", - "Nipponize", - "negotiator", - "vacationless", - "synthol", - "fissureless", - "resoap", - "pachycarpous", - "reinspiration", - "misappropriation", - "disdiazo", - "unheatable", - "streng", - "Detroiter", - "infandous", - "loganiaceous", - "desugar", - "Matronalia", - "myxocystoma", - "Gandhiism", - "kiddier", - "relodge", - "counterreprisal", - "recentralize", - "foliously", - "reprinter", - "gender", - "edaciousness", - "chondriomite", - "concordant", - "stockrider", - "pedary", - "shikra", - "blameworthiness", - "vaccina", - "Thamnophilinae", - "wrongwise", - "unsuperannuated", - "convalescency", - "intransmutable", - "dropcloth", - "Ceriomyces", - "ponderal", - "unstentorian", - "mem", - "deceleration", - "ethionic", - "untopped", - "wetback", - "bebar", - "undecaying", - "shoreside", - "energize", - "presacral", - "undismay", - "agricolite", - "cowheart", - "hemibathybian", - "postexilian", - "Phacidiaceae", - "offing", - "redesignation", - "skeptically", - "physicianless", - "bronchopathy", - "marabuto", - "proprietory", - "unobtruded", - "funmaker", - "plateresque", - "preadventure", - "beseeching", - "cowpath", - "pachycephalia", - "arthresthesia", - "supari", - "lengthily", - "Nepa", - "liberation", - "nigrify", - "belfry", - "entoolitic", - "bazoo", - "pentachromic", - "distinguishable", - "slideable", - "galvanoscope", - "remanage", - "cetene", - "bocardo", - "consummation", - "boycottism", - "perplexity", - "astay", - "Gaetuli", - "periplastic", - "consolidator", - "sluggarding", - "coracoscapular", - "anangioid", - "oxygenizer", - "Hunanese", - "seminary", - "periplast", - "Corylus", - "unoriginativeness", - "persecutee", - "tweaker", - "silliness", - "Dabitis", - "facetiousness", - "thymy", - "nonimperial", - "mesoblastema", - "turbiniform", - "churchway", - "cooing", - "frithbot", - "concomitantly", - "stalwartize", - "clingfish", - "hardmouthed", - "parallelepipedonal", - "coracoacromial", - "factuality", - "curtilage", - "arachnoidean", - "semiaridity", - "phytobacteriology", - "premastery", - "hyperpurist", - "mobed", - "opportunistic", - "acclimature", - "outdistance", - "sophister", - "condonement", - "oxygenerator", - "acetonic", - "emanatory", - "periphlebitis", - "nonsociety", - "spectroradiometric", - "superaverage", - "cleanness", - "posteroventral", - "unadvised", - "unmistakedly", - "pimgenet", - "auresca", - "overimitate", - "dipnoan", - "chromoxylograph", - "triakistetrahedron", - "Suessiones", - "uncopiable", - "oligomenorrhea", - "fribbling", - "worriable", - "flot", - "ornithotrophy", - "phytoteratology", - "setup", - "lanneret", - "unbraceleted", - "gudemother", - "Spica", - "unconsolatory", - "recorruption", - "premenstrual", - "subretinal", - "millennialist", - "subjectibility", - "rewardproof", - "counterflight", - "pilomotor", - "carpetbaggery", - "macrodiagonal", - "slim", - "indiscernible", - "cuckoo", - "moted", - "controllingly", - "gynecopathy", - "porrectus", - "wanworth", - "lutfisk", - "semiprivate", - "philadelphy", - "abdominothoracic", - "coxcomb", - "dambrod", - "Metanemertini", - "balminess", - "homotypy", - "waremaker", - "absurdity", - "gimcrack", - "asquat", - "suitable", - "perimorphous", - "kitchenwards", - "pielum", - "salloo", - "paleontologic", - "Olson", - "Tellinidae", - "ferryman", - "peptonoid", - "Bopyridae", - "fallacy", - "ictuate", - "aguinaldo", - "rhyodacite", - "Ligydidae", - "galvanometric", - "acquisitor", - "muscology", - "hemikaryon", - "ethnobotanic", - "postganglionic", - "rudimentarily", - "replenish", - "phyllorhine", - "popgunnery", - "summar", - "quodlibetary", - "xanthochromia", - "autosymbolically", - "preloreal", - "extent", - "strawberry", - "immortalness", - "colicwort", - "frisca", - "electiveness", - "heartbroken", - "affrightingly", - "reconfiscation", - "jacchus", - "imponderably", - "semantics", - "beennut", - "paleometeorological", - "becost", - "timberwright", - "resuppose", - "syncategorematical", - "cytolymph", - "steinbok", - "explantation", - "hyperelliptic", - "antescript", - "blowdown", - "antinomical", - "caravanserai", - "unweariedly", - "isonymic", - "keratoplasty", - "vipery", - "parepigastric", - "endolymphatic", - "Londonese", - "necrotomy", - "angelship", - "Schizogregarinida", - "steeplebush", - "sparaxis", - "connectedness", - "tolerance", - "impingent", - "agglutinin", - "reviver", - "hieroglyphical", - "dialogize", - "coestate", - "declamatory", - "ventilation", - "tauromachy", - "cotransubstantiate", - "pome", - "underseas", - "triquadrantal", - "preconfinemnt", - "electroindustrial", - "selachostomous", - "nongolfer", - "mesalike", - "hamartiology", - "ganglioblast", - "unsuccessive", - "yallow", - "bacchanalianly", - "platydactyl", - "Bucephala", - "ultraurgent", - "penalist", - "catamenial", - "lynnhaven", - "unrelevant", - "lunkhead", - "metropolitan", - "hydro", - "outsoar", - "vernant", - "interlanguage", - "catarrhal", - "Ionicize", - "keelless", - "myomantic", - "booker", - "Xanthomonas", - "unimpeded", - "overfeminize", - "speronaro", - "diaconia", - "overholiness", - "liquefacient", - "Spartium", - "haggly", - "albumose", - "nonnecessary", - "sulcalization", - "decapitate", - "cellated", - "unguirostral", - "trichiurid", - "loveproof", - "amakebe", - "screet", - "arsenoferratin", - "unfrizz", - "undiscoverable", - "procollectivistic", - "tractile", - "Winona", - "dermostosis", - "eliminant", - "scomberoid", - "tensile", - "typesetting", - "xylic", - "dermatopathology", - "cycloplegic", - "revocable", - "fissate", - "afterplay", - "screwship", - "microerg", - "bentonite", - "stagecoaching", - "beglerbeglic", - "overcharitably", - "Plotinism", - "Veddoid", - "disequalize", - "cytoproct", - "trophophore", - "antidote", - "allerion", - "famous", - "convey", - "postotic", - "rapillo", - "cilectomy", - "penkeeper", - "patronym", - "bravely", - "ureteropyelitis", - "Hildebrandine", - "missileproof", - "Conularia", - "deadening", - "Conrad", - "pseudochylous", - "typologically", - "strummer", - "luxuriousness", - "resublimation", - "glossiness", - "hydrocauline", - "anaglyph", - "personifiable", - "seniority", - "formulator", - "datiscaceous", - "hydracrylate", - "Tyranni", - "Crawthumper", - "overprove", - "masher", - "dissonance", - "Serpentinian", - "malachite", - "interestless", - "stchi", - "ogum", - "polyspermic", - "archegoniate", - "precogitation", - "Alkaphrah", - "craggily", - "delightfulness", - "bioplast", - "diplocaulescent", - "neverland", - "interspheral", - "chlorhydric", - "forsakenly", - "scandium", - "detubation", - "telega", - "Valeriana", - "centraxonial", - "anabolite", - "neger", - "miscellanea", - "whalebacker", - "stylidiaceous", - "unpropelled", - "Kennedya", - "Jacksonite", - "ghoulish", - "Dendrocalamus", - "paynimhood", - "rappist", - "unluffed", - "falling", - "Lyctus", - "uncrown", - "warmly", - "pneumatism", - "Morisonian", - "notate", - "isoagglutinin", - "Pelidnota", - "previsit", - "contradistinctly", - "utter", - "porometer", - "gie", - "germanization", - "betwixt", - "prenephritic", - "underpier", - "Eleutheria", - "ruthenious", - "convertor", - "antisepsin", - "winterage", - "tetramethylammonium", - "Rockaway", - "Penaea", - "prelatehood", - "brisket", - "unwishful", - "Minahassa", - "Briareus", - "semiaxis", - "disintegrant", - "peastick", - "iatromechanical", - "fastus", - "thymectomy", - "ladyless", - "unpreened", - "overflutter", - "sicker", - "apsidally", - "thiazine", - "guideway", - "pausation", - "tellinoid", - "abrogative", - "foraminulate", - "omphalos", - "Monorhina", - "polymyarian", - "unhelpful", - "newslessness", - "oryctognosy", - "octoradial", - "doxology", - "arrhythmy", - "gugal", - "mesityl", - "hexaplaric", - "Cabirian", - "hordeiform", - "eddyroot", - "internarial", - "deservingness", - "jawbation", - "orographically", - "semiprecious", - "seasick", - "thermically", - "grew", - "tamability", - "egotistically", - "fip", - "preabsorbent", - "leptochroa", - "ethnobotany", - "podolite", - "egoistic", - "semitropical", - "cero", - "spinelessness", - "onshore", - "omlah", - "tintinnabulist", - "machila", - "entomotomy", - "nubile", - "nonscholastic", - "burnt", - "Alea", - "befume", - "doctorless", - "Napoleonic", - "scenting", - "apokreos", - "cresylene", - "paramide", - "rattery", - "disinterested", - "idiopathetic", - "negatory", - "fervid", - "quintato", - "untricked", - "Metrosideros", - "mescaline", - "midverse", - "Musophagidae", - "fictionary", - "branchiostegous", - "yoker", - "residuum", - "culmigenous", - "fleam", - "suffragism", - "Anacreon", - "sarcodous", - "parodistic", - "writmaking", - "conversationism", - "retroposed", - "tornillo", - "presuspect", - "didymous", - "Saumur", - "spicing", - "drawbridge", - "cantor", - "incumbrancer", - "heterospory", - "Turkeydom", - "anteprandial", - "neighbourship", - "thatchless", - "drepanoid", - "lusher", - "paling", - "ecthlipsis", - "heredosyphilitic", - "although", - "garetta", - "temporarily", - "Monotropa", - "proglottic", - "calyptro", - "persiflage", - "degradable", - "paraspecific", - "undecorative", - "Pholas", - "myelon", - "resteal", - "quadrantly", - "scrimped", - "airer", - "deviless", - "caliciform", - "Sefekhet", - "shastaite", - "togate", - "macrostructure", - "bipyramid", - "wey", - "didynamy", - "knacker", - "swage", - "supermanism", - "epitheton", - "overpresumptuous" - ] - -struct RC4 { - var State : UInt8[] - var I : UInt8 = 0 - var J : UInt8 = 0 - - init() { - State = new UInt8[256] - } - - mutating - func initialize(inout Key: UInt8[]) { - for i in 0..256 { - State[i] = UInt8(i) - } - - var j : UInt8 = 0 - for i in 0..256 { - var K : UInt8 = Key[i % Key.count] - var S : UInt8 = State[i] - j = j &+ S &+ K - swapByIndex(i, y: Int(j)) - } - } - - mutating - func swapByIndex(x: Int, y: Int) { - let T1 : UInt8 = State[x] - let T2 : UInt8 = State[y] - State[x] = T2 - State[y] = T1 - } - - mutating - func next() -> UInt8 { - I = I &+ 1 - J = J &+ State[Int(I)] - swapByIndex(Int(I), y:Int(J)) - return State[Int(State[Int(I)] &+ State[Int(J)]) & 0xFF] - } - - mutating - func encrypt(inout Data: UInt8[]) { - var cnt = Data.count - for i in 0..cnt { - Data[i] = Data[i] ^ next() - } - } -} - -func benchStringSort_internal(inout words: String[]) { - sort(&words) -} - -func benchStringSort() { - let start = __mach_absolute_time__() - for i in 0..50 { // do not change '50', we have historic perf data - // Notice that we _copy_ the array of words before we sort it. - benchStringSort_internal(&stringBenchmarkWords) - } - let delta = __mach_absolute_time__() - start - - print("\(delta) nanoseconds.") - print("\(Double(delta) / Double(50)) nanoseconds/lap") -} - -func benchRC4_internal(messageLen : Int, iterations : Int, validate : Bool) { - var Secret = "This is my secret message" - var Key = "This is my key" - var SecretData : UInt8[] = Array(Secret.utf8) - var KeyData : UInt8[] = Array(Key.utf8) - - var LongData : UInt8[] = new UInt8[messageLen] - - // Generate a long message. - for i in 0..messageLen { - LongData[i] = SecretData[i % SecretData.count] - } - - // Generate the Encryptor and Decryptor classes. - // FIXME: Passing KeyData to the c'tor does not type check. - var Enc = RC4() - var Dec = RC4() - Enc.initialize(&KeyData) - Dec.initialize(&KeyData) - - let start = __mach_absolute_time__() - - for i in 0..iterations { - Enc.encrypt(&LongData) - Dec.encrypt(&LongData) - } - - let delta = __mach_absolute_time__() - start - print("\(delta) nanoseconds.") - print("\(Double(delta) / Double(iterations)) nanoseconds/lap") - - - if (validate) { - print("Validating ...") - for i in 0..messageLen { - if (LongData[i] != SecretData[i % SecretData.count]) { - print("Error at \(i)"); - } - } - } -} - - -func benchRC4() { - benchRC4_internal(5000, 2000, false) // do not change 2nd param, we have historic perf data -} - -func benchStringComplexWalk() -> Int { - var s = "निरन्तरान्धकारिता-दिगन्तर-कन्दलदमन्द-सुधारस-बिन्दु-सान्द्रतर-घनाघन-वृन्द-सन्देहकर-स्यन्दमान-मकरन्द-बिन्दु-बन्धुरतर-माकन्द-तरु-कुल-तल्प-कल्प-मृदुल-सिकता-जाल-जटिल-मूल-तल-मरुवक-मिलदलघु-लघु-लय-कलित-रमणीय-पानीय-शालिका-बालिका-करार-विन्द-गलन्तिका-गलदेला-लवङ्ग-पाटल-घनसार-कस्तूरिकातिसौरभ-मेदुर-लघुतर-मधुर-शीतलतर-सलिलधारा-निराकरिष्णु-तदीय-विमल-विलोचन-मयूख-रेखापसारित-पिपासायास-पथिक-लोकान्" - - - let start = __mach_absolute_time__() - var count = 0 - let laps = 10000 // do not change this, we have historic perf data - for i in 0..laps { - for c in s.unicodeScalars { - count++ - } - } - let delta = __mach_absolute_time__() - start - print("\(delta) nanoseconds.") - print("\(Double(delta) / Double(laps)) nanoseconds/lap") - return count -} - -func benchStringWalk() -> Int { - let s = "siebenhundertsiebenundsiebzigtausendsiebenhundertsiebenundsiebzig" - - let start = __mach_absolute_time__() - var count = 0 - let laps = 100000 // do not change this, we have historic perf data - for i in 0..laps { - for c in s.unicodeScalars { - count++ - } - } - let delta = __mach_absolute_time__() - start - print("\(delta) nanoseconds.") - print("\(Double(delta) / Double(laps)) nanoseconds/lap") - return count -} - -// Source code for this benchmark was ported from the "Great Computer Language -// Shootout". http://dada.perl.it/shootout/objinst_allsrc.html -class Toggle { - var state : Bool = true - init(start_state : Bool) { - state = start_state - } - - func value() -> Bool { - return state - } - - func activate() -> Toggle { - state = !state - return self - } -} - -class NthToggle : Toggle { - var count_max : Int = 0 - var counter : Int = 0 - - init(start_state : Bool, max_counter : Int) { - super.init(start_state: start_state) - count_max = max_counter - counter = 0 - } - override func activate() -> NthToggle { - counter++ - if (counter >= count_max) { - state = !state - counter = 0 - } - return self - } -} - -func benchObjInst_internal(n : Int) { - var toggle1 = Toggle(start_state: true) - //for i in 0...5 { - // print(toggle1.activate().value()) - //} - - for i in 0..5 { - var t = Toggle(start_state: true) - } - - var ntoggle1 = NthToggle(start_state: true, max_counter: 3) - //for i in 0...5 { - // print(ntoggle1.activate().value()) - //} - - for i in 0..n { - var toggle = NthToggle(start_state: true, max_counter: 3) - } -} - -func benchObjInst() { - let start = __mach_absolute_time__() - benchObjInst_internal(100000000) - let delta = __mach_absolute_time__() - start - print("\(delta) nanoseconds.") -} - - -func Ackermann(M : Int, N : Int) -> Int { - if (M == 0) { return N + 1 } - if (N == 0) { return Ackermann(M - 1, 1) } - return Ackermann(M - 1, Ackermann(M, N - 1)) -} - -func benchAckermann() { - let start = __mach_absolute_time__() - print(Ackermann(3, 13)) - let delta = __mach_absolute_time__() - start - print("\(delta) nanoseconds.") -} - -func benchAll() { - print(" --- Ackermann --------------") - benchAckermann() - print(" --- ObjInst ----------------") - benchObjInst() - print(" --- RC4 ------------------- ") - benchRC4() - print(" --- String Sort ------------") - benchStringSort() - print(" --- String Walk ------------") - benchStringWalk() - print(" --- String Complex Walk ----") - benchStringComplexWalk() - print(" --- Prim MST ----") - print(" ----------------------------") -} - -benchAll() diff --git a/utils/benchmark/Graph/Makefile b/utils/benchmark/Graph/Makefile deleted file mode 100644 index 6cb2b071b40f7..0000000000000 --- a/utils/benchmark/Graph/Makefile +++ /dev/null @@ -1,30 +0,0 @@ - -SDK = macosx -CXX = $(shell xcrun -find clang++ -sdk $(SDK)) -SDKPATH = $(shell xcrun --show-sdk-path -sdk $(SDK)) -OPT_FLAGS = -O0 -g -CXXFLAGS = $(OPT_FLAGS) -std=c++11 -SWIFT_FLAGS = $(OPT_FLAGS) -SWIFT = swift - -%-cpp.o: %.cpp - $(CXX) $(OUTPUT_OPTIONS) -isysroot $(SDKPATH) $(LDFLAGS) $(CXXFLAGS) $^ -c - -%: %.o - $(CXX) -o $@ -isysroot $(SDKPATH) $(LDFLAGS) $(CXXFLAGS) $^ - -%-swift.o : %.swift - $(SWIFT) $(OUTPUT_OPTIONS) -sdk $(SDKPATH) -o $@ $(SWIFT_FLAGS) $^ - -prims-cpp: prims-cpp.o test-prims.o -prims-swift: prims-swift.o - -all: prims-cpp - -clean: - rm -vf *.o - rm -vf a.out - rm -vf prims - -.DEFAULT_GOAL = prims -.PHONY = all clean diff --git a/utils/benchmark/Graph/generate-data.py b/utils/benchmark/Graph/generate-data.py deleted file mode 100644 index c8dac15863f81..0000000000000 --- a/utils/benchmark/Graph/generate-data.py +++ /dev/null @@ -1,29 +0,0 @@ - -import pygraph.algorithms.generators as gen -import pygraph.algorithms.accessibility as acc -import pygraph.algorithms.minmax as minmax - -graph = gen.generate(5000, 10000, weight_range=(50, 2000)) -components = acc.connected_components(graph) -nodes = [g for g in graph if components[g] == 1] - -print "GRAPH NODES" -for n in graph.nodes(): - print n -print "GRAPH EDGES" -for e in graph.edges(): - if components[e[0]] == 1: - w = graph.edge_weight(e) - print (e[0], e[1], w) - -# MST = minmax.minimal_spanning_tree(graph) -# print "MST NODES" -# for n in MST.keys(): -# print n -# print "MST EDGES" -# for k in MST.keys(): -# if MST[k] is not None: -# print "(%d, %d)" % (k, MST[k]) -# else: -# print "(%d, %d)" % (k, k) - diff --git a/utils/benchmark/Graph/graph.h b/utils/benchmark/Graph/graph.h deleted file mode 100644 index e0fd080ae42a4..0000000000000 --- a/utils/benchmark/Graph/graph.h +++ /dev/null @@ -1,35 +0,0 @@ -//===--- Graph.h - Header for Graph based Benchmarks ------------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#include -#include - -namespace graph { - -// It is expected that the user uses a closure + data_index to perform -// comparisons. This will enable us to test closure computations. -struct Node { - Node(unsigned i) : Id(i), adjList() { } - /// The index in the data array of Node's data. - unsigned Id; - - /// The indices in the graph array of the nodes adjacent to node. - std::vector adjList; -}; - -/// Calculate the minimum spanning tree of the connected graph G using the -/// weight function Fun. Returns result in TreeEdges. -void prims(std::vector &Graph, - std::vector &TreeEdges, - std::function Fun); - -} // end namespace graph diff --git a/utils/benchmark/Graph/graph.swift b/utils/benchmark/Graph/graph.swift deleted file mode 100644 index 000c5960fd289..0000000000000 --- a/utils/benchmark/Graph/graph.swift +++ /dev/null @@ -1,12 +0,0 @@ -//===--- prims.swift - Implementation of Prims MST algorithm --------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - diff --git a/utils/benchmark/Graph/large-data b/utils/benchmark/Graph/large-data deleted file mode 100644 index 3c40563c13eb5..0000000000000 --- a/utils/benchmark/Graph/large-data +++ /dev/null @@ -1,24998 +0,0 @@ -GRAPH NODES -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -1000 -1001 -1002 -1003 -1004 -1005 -1006 -1007 -1008 -1009 -1010 -1011 -1012 -1013 -1014 -1015 -1016 -1017 -1018 -1019 -1020 -1021 -1022 -1023 -1024 -1025 -1026 -1027 -1028 -1029 -1030 -1031 -1032 -1033 -1034 -1035 -1036 -1037 -1038 -1039 -1040 -1041 -1042 -1043 -1044 -1045 -1046 -1047 -1048 -1049 -1050 -1051 -1052 -1053 -1054 -1055 -1056 -1057 -1058 -1059 -1060 -1061 -1062 -1063 -1064 -1065 -1066 -1067 -1068 -1069 -1070 -1071 -1072 -1073 -1074 -1075 -1076 -1077 -1078 -1079 -1080 -1081 -1082 -1083 -1084 -1085 -1086 -1087 -1088 -1089 -1090 -1091 -1092 -1093 -1094 -1095 -1096 -1097 -1098 -1099 -1100 -1101 -1102 -1103 -1104 -1105 -1106 -1107 -1108 -1109 -1110 -1111 -1112 -1113 -1114 -1115 -1116 -1117 -1118 -1119 -1120 -1121 -1122 -1123 -1124 -1125 -1126 -1127 -1128 -1129 -1130 -1131 -1132 -1133 -1134 -1135 -1136 -1137 -1138 -1139 -1140 -1141 -1142 -1143 -1144 -1145 -1146 -1147 -1148 -1149 -1150 -1151 -1152 -1153 -1154 -1155 -1156 -1157 -1158 -1159 -1160 -1161 -1162 -1163 -1164 -1165 -1166 -1167 -1168 -1169 -1170 -1171 -1172 -1173 -1174 -1175 -1176 -1177 -1178 -1179 -1180 -1181 -1182 -1183 -1184 -1185 -1186 -1187 -1188 -1189 -1190 -1191 -1192 -1193 -1194 -1195 -1196 -1197 -1198 -1199 -1200 -1201 -1202 -1203 -1204 -1205 -1206 -1207 -1208 -1209 -1210 -1211 -1212 -1213 -1214 -1215 -1216 -1217 -1218 -1219 -1220 -1221 -1222 -1223 -1224 -1225 -1226 -1227 -1228 -1229 -1230 -1231 -1232 -1233 -1234 -1235 -1236 -1237 -1238 -1239 -1240 -1241 -1242 -1243 -1244 -1245 -1246 -1247 -1248 -1249 -1250 -1251 -1252 -1253 -1254 -1255 -1256 -1257 -1258 -1259 -1260 -1261 -1262 -1263 -1264 -1265 -1266 -1267 -1268 -1269 -1270 -1271 -1272 -1273 -1274 -1275 -1276 -1277 -1278 -1279 -1280 -1281 -1282 -1283 -1284 -1285 -1286 -1287 -1288 -1289 -1290 -1291 -1292 -1293 -1294 -1295 -1296 -1297 -1298 -1299 -1300 -1301 -1302 -1303 -1304 -1305 -1306 -1307 -1308 -1309 -1310 -1311 -1312 -1313 -1314 -1315 -1316 -1317 -1318 -1319 -1320 -1321 -1322 -1323 -1324 -1325 -1326 -1327 -1328 -1329 -1330 -1331 -1332 -1333 -1334 -1335 -1336 -1337 -1338 -1339 -1340 -1341 -1342 -1343 -1344 -1345 -1346 -1347 -1348 -1349 -1350 -1351 -1352 -1353 -1354 -1355 -1356 -1357 -1358 -1359 -1360 -1361 -1362 -1363 -1364 -1365 -1366 -1367 -1368 -1369 -1370 -1371 -1372 -1373 -1374 -1375 -1376 -1377 -1378 -1379 -1380 -1381 -1382 -1383 -1384 -1385 -1386 -1387 -1388 -1389 -1390 -1391 -1392 -1393 -1394 -1395 -1396 -1397 -1398 -1399 -1400 -1401 -1402 -1403 -1404 -1405 -1406 -1407 -1408 -1409 -1410 -1411 -1412 -1413 -1414 -1415 -1416 -1417 -1418 -1419 -1420 -1421 -1422 -1423 -1424 -1425 -1426 -1427 -1428 -1429 -1430 -1431 -1432 -1433 -1434 -1435 -1436 -1437 -1438 -1439 -1440 -1441 -1442 -1443 -1444 -1445 -1446 -1447 -1448 -1449 -1450 -1451 -1452 -1453 -1454 -1455 -1456 -1457 -1458 -1459 -1460 -1461 -1462 -1463 -1464 -1465 -1466 -1467 -1468 -1469 -1470 -1471 -1472 -1473 -1474 -1475 -1476 -1477 -1478 -1479 -1480 -1481 -1482 -1483 -1484 -1485 -1486 -1487 -1488 -1489 -1490 -1491 -1492 -1493 -1494 -1495 -1496 -1497 -1498 -1499 -1500 -1501 -1502 -1503 -1504 -1505 -1506 -1507 -1508 -1509 -1510 -1511 -1512 -1513 -1514 -1515 -1516 -1517 -1518 -1519 -1520 -1521 -1522 -1523 -1524 -1525 -1526 -1527 -1528 -1529 -1530 -1531 -1532 -1533 -1534 -1535 -1536 -1537 -1538 -1539 -1540 -1541 -1542 -1543 -1544 -1545 -1546 -1547 -1548 -1549 -1550 -1551 -1552 -1553 -1554 -1555 -1556 -1557 -1558 -1559 -1560 -1561 -1562 -1563 -1564 -1565 -1566 -1567 -1568 -1569 -1570 -1571 -1572 -1573 -1574 -1575 -1576 -1577 -1578 -1579 -1580 -1581 -1582 -1583 -1584 -1585 -1586 -1587 -1588 -1589 -1590 -1591 -1592 -1593 -1594 -1595 -1596 -1597 -1598 -1599 -1600 -1601 -1602 -1603 -1604 -1605 -1606 -1607 -1608 -1609 -1610 -1611 -1612 -1613 -1614 -1615 -1616 -1617 -1618 -1619 -1620 -1621 -1622 -1623 -1624 -1625 -1626 -1627 -1628 -1629 -1630 -1631 -1632 -1633 -1634 -1635 -1636 -1637 -1638 -1639 -1640 -1641 -1642 -1643 -1644 -1645 -1646 -1647 -1648 -1649 -1650 -1651 -1652 -1653 -1654 -1655 -1656 -1657 -1658 -1659 -1660 -1661 -1662 -1663 -1664 -1665 -1666 -1667 -1668 -1669 -1670 -1671 -1672 -1673 -1674 -1675 -1676 -1677 -1678 -1679 -1680 -1681 -1682 -1683 -1684 -1685 -1686 -1687 -1688 -1689 -1690 -1691 -1692 -1693 -1694 -1695 -1696 -1697 -1698 -1699 -1700 -1701 -1702 -1703 -1704 -1705 -1706 -1707 -1708 -1709 -1710 -1711 -1712 -1713 -1714 -1715 -1716 -1717 -1718 -1719 -1720 -1721 -1722 -1723 -1724 -1725 -1726 -1727 -1728 -1729 -1730 -1731 -1732 -1733 -1734 -1735 -1736 -1737 -1738 -1739 -1740 -1741 -1742 -1743 -1744 -1745 -1746 -1747 -1748 -1749 -1750 -1751 -1752 -1753 -1754 -1755 -1756 -1757 -1758 -1759 -1760 -1761 -1762 -1763 -1764 -1765 -1766 -1767 -1768 -1769 -1770 -1771 -1772 -1773 -1774 -1775 -1776 -1777 -1778 -1779 -1780 -1781 -1782 -1783 -1784 -1785 -1786 -1787 -1788 -1789 -1790 -1791 -1792 -1793 -1794 -1795 -1796 -1797 -1798 -1799 -1800 -1801 -1802 -1803 -1804 -1805 -1806 -1807 -1808 -1809 -1810 -1811 -1812 -1813 -1814 -1815 -1816 -1817 -1818 -1819 -1820 -1821 -1822 -1823 -1824 -1825 -1826 -1827 -1828 -1829 -1830 -1831 -1832 -1833 -1834 -1835 -1836 -1837 -1838 -1839 -1840 -1841 -1842 -1843 -1844 -1845 -1846 -1847 -1848 -1849 -1850 -1851 -1852 -1853 -1854 -1855 -1856 -1857 -1858 -1859 -1860 -1861 -1862 -1863 -1864 -1865 -1866 -1867 -1868 -1869 -1870 -1871 -1872 -1873 -1874 -1875 -1876 -1877 -1878 -1879 -1880 -1881 -1882 -1883 -1884 -1885 -1886 -1887 -1888 -1889 -1890 -1891 -1892 -1893 -1894 -1895 -1896 -1897 -1898 -1899 -1900 -1901 -1902 -1903 -1904 -1905 -1906 -1907 -1908 -1909 -1910 -1911 -1912 -1913 -1914 -1915 -1916 -1917 -1918 -1919 -1920 -1921 -1922 -1923 -1924 -1925 -1926 -1927 -1928 -1929 -1930 -1931 -1932 -1933 -1934 -1935 -1936 -1937 -1938 -1939 -1940 -1941 -1942 -1943 -1944 -1945 -1946 -1947 -1948 -1949 -1950 -1951 -1952 -1953 -1954 -1955 -1956 -1957 -1958 -1959 -1960 -1961 -1962 -1963 -1964 -1965 -1966 -1967 -1968 -1969 -1970 -1971 -1972 -1973 -1974 -1975 -1976 -1977 -1978 -1979 -1980 -1981 -1982 -1983 -1984 -1985 -1986 -1987 -1988 -1989 -1990 -1991 -1992 -1993 -1994 -1995 -1996 -1997 -1998 -1999 -2000 -2001 -2002 -2003 -2004 -2005 -2006 -2007 -2008 -2009 -2010 -2011 -2012 -2013 -2014 -2015 -2016 -2017 -2018 -2019 -2020 -2021 -2022 -2023 -2024 -2025 -2026 -2027 -2028 -2029 -2030 -2031 -2032 -2033 -2034 -2035 -2036 -2037 -2038 -2039 -2040 -2041 -2042 -2043 -2044 -2045 -2046 -2047 -2048 -2049 -2050 -2051 -2052 -2053 -2054 -2055 -2056 -2057 -2058 -2059 -2060 -2061 -2062 -2063 -2064 -2065 -2066 -2067 -2068 -2069 -2070 -2071 -2072 -2073 -2074 -2075 -2076 -2077 -2078 -2079 -2080 -2081 -2082 -2083 -2084 -2085 -2086 -2087 -2088 -2089 -2090 -2091 -2092 -2093 -2094 -2095 -2096 -2097 -2098 -2099 -2100 -2101 -2102 -2103 -2104 -2105 -2106 -2107 -2108 -2109 -2110 -2111 -2112 -2113 -2114 -2115 -2116 -2117 -2118 -2119 -2120 -2121 -2122 -2123 -2124 -2125 -2126 -2127 -2128 -2129 -2130 -2131 -2132 -2133 -2134 -2135 -2136 -2137 -2138 -2139 -2140 -2141 -2142 -2143 -2144 -2145 -2146 -2147 -2148 -2149 -2150 -2151 -2152 -2153 -2154 -2155 -2156 -2157 -2158 -2159 -2160 -2161 -2162 -2163 -2164 -2165 -2166 -2167 -2168 -2169 -2170 -2171 -2172 -2173 -2174 -2175 -2176 -2177 -2178 -2179 -2180 -2181 -2182 -2183 -2184 -2185 -2186 -2187 -2188 -2189 -2190 -2191 -2192 -2193 -2194 -2195 -2196 -2197 -2198 -2199 -2200 -2201 -2202 -2203 -2204 -2205 -2206 -2207 -2208 -2209 -2210 -2211 -2212 -2213 -2214 -2215 -2216 -2217 -2218 -2219 -2220 -2221 -2222 -2223 -2224 -2225 -2226 -2227 -2228 -2229 -2230 -2231 -2232 -2233 -2234 -2235 -2236 -2237 -2238 -2239 -2240 -2241 -2242 -2243 -2244 -2245 -2246 -2247 -2248 -2249 -2250 -2251 -2252 -2253 -2254 -2255 -2256 -2257 -2258 -2259 -2260 -2261 -2262 -2263 -2264 -2265 -2266 -2267 -2268 -2269 -2270 -2271 -2272 -2273 -2274 -2275 -2276 -2277 -2278 -2279 -2280 -2281 -2282 -2283 -2284 -2285 -2286 -2287 -2288 -2289 -2290 -2291 -2292 -2293 -2294 -2295 -2296 -2297 -2298 -2299 -2300 -2301 -2302 -2303 -2304 -2305 -2306 -2307 -2308 -2309 -2310 -2311 -2312 -2313 -2314 -2315 -2316 -2317 -2318 -2319 -2320 -2321 -2322 -2323 -2324 -2325 -2326 -2327 -2328 -2329 -2330 -2331 -2332 -2333 -2334 -2335 -2336 -2337 -2338 -2339 -2340 -2341 -2342 -2343 -2344 -2345 -2346 -2347 -2348 -2349 -2350 -2351 -2352 -2353 -2354 -2355 -2356 -2357 -2358 -2359 -2360 -2361 -2362 -2363 -2364 -2365 -2366 -2367 -2368 -2369 -2370 -2371 -2372 -2373 -2374 -2375 -2376 -2377 -2378 -2379 -2380 -2381 -2382 -2383 -2384 -2385 -2386 -2387 -2388 -2389 -2390 -2391 -2392 -2393 -2394 -2395 -2396 -2397 -2398 -2399 -2400 -2401 -2402 -2403 -2404 -2405 -2406 -2407 -2408 -2409 -2410 -2411 -2412 -2413 -2414 -2415 -2416 -2417 -2418 -2419 -2420 -2421 -2422 -2423 -2424 -2425 -2426 -2427 -2428 -2429 -2430 -2431 -2432 -2433 -2434 -2435 -2436 -2437 -2438 -2439 -2440 -2441 -2442 -2443 -2444 -2445 -2446 -2447 -2448 -2449 -2450 -2451 -2452 -2453 -2454 -2455 -2456 -2457 -2458 -2459 -2460 -2461 -2462 -2463 -2464 -2465 -2466 -2467 -2468 -2469 -2470 -2471 -2472 -2473 -2474 -2475 -2476 -2477 -2478 -2479 -2480 -2481 -2482 -2483 -2484 -2485 -2486 -2487 -2488 -2489 -2490 -2491 -2492 -2493 -2494 -2495 -2496 -2497 -2498 -2499 -2500 -2501 -2502 -2503 -2504 -2505 -2506 -2507 -2508 -2509 -2510 -2511 -2512 -2513 -2514 -2515 -2516 -2517 -2518 -2519 -2520 -2521 -2522 -2523 -2524 -2525 -2526 -2527 -2528 -2529 -2530 -2531 -2532 -2533 -2534 -2535 -2536 -2537 -2538 -2539 -2540 -2541 -2542 -2543 -2544 -2545 -2546 -2547 -2548 -2549 -2550 -2551 -2552 -2553 -2554 -2555 -2556 -2557 -2558 -2559 -2560 -2561 -2562 -2563 -2564 -2565 -2566 -2567 -2568 -2569 -2570 -2571 -2572 -2573 -2574 -2575 -2576 -2577 -2578 -2579 -2580 -2581 -2582 -2583 -2584 -2585 -2586 -2587 -2588 -2589 -2590 -2591 -2592 -2593 -2594 -2595 -2596 -2597 -2598 -2599 -2600 -2601 -2602 -2603 -2604 -2605 -2606 -2607 -2608 -2609 -2610 -2611 -2612 -2613 -2614 -2615 -2616 -2617 -2618 -2619 -2620 -2621 -2622 -2623 -2624 -2625 -2626 -2627 -2628 -2629 -2630 -2631 -2632 -2633 -2634 -2635 -2636 -2637 -2638 -2639 -2640 -2641 -2642 -2643 -2644 -2645 -2646 -2647 -2648 -2649 -2650 -2651 -2652 -2653 -2654 -2655 -2656 -2657 -2658 -2659 -2660 -2661 -2662 -2663 -2664 -2665 -2666 -2667 -2668 -2669 -2670 -2671 -2672 -2673 -2674 -2675 -2676 -2677 -2678 -2679 -2680 -2681 -2682 -2683 -2684 -2685 -2686 -2687 -2688 -2689 -2690 -2691 -2692 -2693 -2694 -2695 -2696 -2697 -2698 -2699 -2700 -2701 -2702 -2703 -2704 -2705 -2706 -2707 -2708 -2709 -2710 -2711 -2712 -2713 -2714 -2715 -2716 -2717 -2718 -2719 -2720 -2721 -2722 -2723 -2724 -2725 -2726 -2727 -2728 -2729 -2730 -2731 -2732 -2733 -2734 -2735 -2736 -2737 -2738 -2739 -2740 -2741 -2742 -2743 -2744 -2745 -2746 -2747 -2748 -2749 -2750 -2751 -2752 -2753 -2754 -2755 -2756 -2757 -2758 -2759 -2760 -2761 -2762 -2763 -2764 -2765 -2766 -2767 -2768 -2769 -2770 -2771 -2772 -2773 -2774 -2775 -2776 -2777 -2778 -2779 -2780 -2781 -2782 -2783 -2784 -2785 -2786 -2787 -2788 -2789 -2790 -2791 -2792 -2793 -2794 -2795 -2796 -2797 -2798 -2799 -2800 -2801 -2802 -2803 -2804 -2805 -2806 -2807 -2808 -2809 -2810 -2811 -2812 -2813 -2814 -2815 -2816 -2817 -2818 -2819 -2820 -2821 -2822 -2823 -2824 -2825 -2826 -2827 -2828 -2829 -2830 -2831 -2832 -2833 -2834 -2835 -2836 -2837 -2838 -2839 -2840 -2841 -2842 -2843 -2844 -2845 -2846 -2847 -2848 -2849 -2850 -2851 -2852 -2853 -2854 -2855 -2856 -2857 -2858 -2859 -2860 -2861 -2862 -2863 -2864 -2865 -2866 -2867 -2868 -2869 -2870 -2871 -2872 -2873 -2874 -2875 -2876 -2877 -2878 -2879 -2880 -2881 -2882 -2883 -2884 -2885 -2886 -2887 -2888 -2889 -2890 -2891 -2892 -2893 -2894 -2895 -2896 -2897 -2898 -2899 -2900 -2901 -2902 -2903 -2904 -2905 -2906 -2907 -2908 -2909 -2910 -2911 -2912 -2913 -2914 -2915 -2916 -2917 -2918 -2919 -2920 -2921 -2922 -2923 -2924 -2925 -2926 -2927 -2928 -2929 -2930 -2931 -2932 -2933 -2934 -2935 -2936 -2937 -2938 -2939 -2940 -2941 -2942 -2943 -2944 -2945 -2946 -2947 -2948 -2949 -2950 -2951 -2952 -2953 -2954 -2955 -2956 -2957 -2958 -2959 -2960 -2961 -2962 -2963 -2964 -2965 -2966 -2967 -2968 -2969 -2970 -2971 -2972 -2973 -2974 -2975 -2976 -2977 -2978 -2979 -2980 -2981 -2982 -2983 -2984 -2985 -2986 -2987 -2988 -2989 -2990 -2991 -2992 -2993 -2994 -2995 -2996 -2997 -2998 -2999 -3000 -3001 -3002 -3003 -3004 -3005 -3006 -3007 -3008 -3009 -3010 -3011 -3012 -3013 -3014 -3015 -3016 -3017 -3018 -3019 -3020 -3021 -3022 -3023 -3024 -3025 -3026 -3027 -3028 -3029 -3030 -3031 -3032 -3033 -3034 -3035 -3036 -3037 -3038 -3039 -3040 -3041 -3042 -3043 -3044 -3045 -3046 -3047 -3048 -3049 -3050 -3051 -3052 -3053 -3054 -3055 -3056 -3057 -3058 -3059 -3060 -3061 -3062 -3063 -3064 -3065 -3066 -3067 -3068 -3069 -3070 -3071 -3072 -3073 -3074 -3075 -3076 -3077 -3078 -3079 -3080 -3081 -3082 -3083 -3084 -3085 -3086 -3087 -3088 -3089 -3090 -3091 -3092 -3093 -3094 -3095 -3096 -3097 -3098 -3099 -3100 -3101 -3102 -3103 -3104 -3105 -3106 -3107 -3108 -3109 -3110 -3111 -3112 -3113 -3114 -3115 -3116 -3117 -3118 -3119 -3120 -3121 -3122 -3123 -3124 -3125 -3126 -3127 -3128 -3129 -3130 -3131 -3132 -3133 -3134 -3135 -3136 -3137 -3138 -3139 -3140 -3141 -3142 -3143 -3144 -3145 -3146 -3147 -3148 -3149 -3150 -3151 -3152 -3153 -3154 -3155 -3156 -3157 -3158 -3159 -3160 -3161 -3162 -3163 -3164 -3165 -3166 -3167 -3168 -3169 -3170 -3171 -3172 -3173 -3174 -3175 -3176 -3177 -3178 -3179 -3180 -3181 -3182 -3183 -3184 -3185 -3186 -3187 -3188 -3189 -3190 -3191 -3192 -3193 -3194 -3195 -3196 -3197 -3198 -3199 -3200 -3201 -3202 -3203 -3204 -3205 -3206 -3207 -3208 -3209 -3210 -3211 -3212 -3213 -3214 -3215 -3216 -3217 -3218 -3219 -3220 -3221 -3222 -3223 -3224 -3225 -3226 -3227 -3228 -3229 -3230 -3231 -3232 -3233 -3234 -3235 -3236 -3237 -3238 -3239 -3240 -3241 -3242 -3243 -3244 -3245 -3246 -3247 -3248 -3249 -3250 -3251 -3252 -3253 -3254 -3255 -3256 -3257 -3258 -3259 -3260 -3261 -3262 -3263 -3264 -3265 -3266 -3267 -3268 -3269 -3270 -3271 -3272 -3273 -3274 -3275 -3276 -3277 -3278 -3279 -3280 -3281 -3282 -3283 -3284 -3285 -3286 -3287 -3288 -3289 -3290 -3291 -3292 -3293 -3294 -3295 -3296 -3297 -3298 -3299 -3300 -3301 -3302 -3303 -3304 -3305 -3306 -3307 -3308 -3309 -3310 -3311 -3312 -3313 -3314 -3315 -3316 -3317 -3318 -3319 -3320 -3321 -3322 -3323 -3324 -3325 -3326 -3327 -3328 -3329 -3330 -3331 -3332 -3333 -3334 -3335 -3336 -3337 -3338 -3339 -3340 -3341 -3342 -3343 -3344 -3345 -3346 -3347 -3348 -3349 -3350 -3351 -3352 -3353 -3354 -3355 -3356 -3357 -3358 -3359 -3360 -3361 -3362 -3363 -3364 -3365 -3366 -3367 -3368 -3369 -3370 -3371 -3372 -3373 -3374 -3375 -3376 -3377 -3378 -3379 -3380 -3381 -3382 -3383 -3384 -3385 -3386 -3387 -3388 -3389 -3390 -3391 -3392 -3393 -3394 -3395 -3396 -3397 -3398 -3399 -3400 -3401 -3402 -3403 -3404 -3405 -3406 -3407 -3408 -3409 -3410 -3411 -3412 -3413 -3414 -3415 -3416 -3417 -3418 -3419 -3420 -3421 -3422 -3423 -3424 -3425 -3426 -3427 -3428 -3429 -3430 -3431 -3432 -3433 -3434 -3435 -3436 -3437 -3438 -3439 -3440 -3441 -3442 -3443 -3444 -3445 -3446 -3447 -3448 -3449 -3450 -3451 -3452 -3453 -3454 -3455 -3456 -3457 -3458 -3459 -3460 -3461 -3462 -3463 -3464 -3465 -3466 -3467 -3468 -3469 -3470 -3471 -3472 -3473 -3474 -3475 -3476 -3477 -3478 -3479 -3480 -3481 -3482 -3483 -3484 -3485 -3486 -3487 -3488 -3489 -3490 -3491 -3492 -3493 -3494 -3495 -3496 -3497 -3498 -3499 -3500 -3501 -3502 -3503 -3504 -3505 -3506 -3507 -3508 -3509 -3510 -3511 -3512 -3513 -3514 -3515 -3516 -3517 -3518 -3519 -3520 -3521 -3522 -3523 -3524 -3525 -3526 -3527 -3528 -3529 -3530 -3531 -3532 -3533 -3534 -3535 -3536 -3537 -3538 -3539 -3540 -3541 -3542 -3543 -3544 -3545 -3546 -3547 -3548 -3549 -3550 -3551 -3552 -3553 -3554 -3555 -3556 -3557 -3558 -3559 -3560 -3561 -3562 -3563 -3564 -3565 -3566 -3567 -3568 -3569 -3570 -3571 -3572 -3573 -3574 -3575 -3576 -3577 -3578 -3579 -3580 -3581 -3582 -3583 -3584 -3585 -3586 -3587 -3588 -3589 -3590 -3591 -3592 -3593 -3594 -3595 -3596 -3597 -3598 -3599 -3600 -3601 -3602 -3603 -3604 -3605 -3606 -3607 -3608 -3609 -3610 -3611 -3612 -3613 -3614 -3615 -3616 -3617 -3618 -3619 -3620 -3621 -3622 -3623 -3624 -3625 -3626 -3627 -3628 -3629 -3630 -3631 -3632 -3633 -3634 -3635 -3636 -3637 -3638 -3639 -3640 -3641 -3642 -3643 -3644 -3645 -3646 -3647 -3648 -3649 -3650 -3651 -3652 -3653 -3654 -3655 -3656 -3657 -3658 -3659 -3660 -3661 -3662 -3663 -3664 -3665 -3666 -3667 -3668 -3669 -3670 -3671 -3672 -3673 -3674 -3675 -3676 -3677 -3678 -3679 -3680 -3681 -3682 -3683 -3684 -3685 -3686 -3687 -3688 -3689 -3690 -3691 -3692 -3693 -3694 -3695 -3696 -3697 -3698 -3699 -3700 -3701 -3702 -3703 -3704 -3705 -3706 -3707 -3708 -3709 -3710 -3711 -3712 -3713 -3714 -3715 -3716 -3717 -3718 -3719 -3720 -3721 -3722 -3723 -3724 -3725 -3726 -3727 -3728 -3729 -3730 -3731 -3732 -3733 -3734 -3735 -3736 -3737 -3738 -3739 -3740 -3741 -3742 -3743 -3744 -3745 -3746 -3747 -3748 -3749 -3750 -3751 -3752 -3753 -3754 -3755 -3756 -3757 -3758 -3759 -3760 -3761 -3762 -3763 -3764 -3765 -3766 -3767 -3768 -3769 -3770 -3771 -3772 -3773 -3774 -3775 -3776 -3777 -3778 -3779 -3780 -3781 -3782 -3783 -3784 -3785 -3786 -3787 -3788 -3789 -3790 -3791 -3792 -3793 -3794 -3795 -3796 -3797 -3798 -3799 -3800 -3801 -3802 -3803 -3804 -3805 -3806 -3807 -3808 -3809 -3810 -3811 -3812 -3813 -3814 -3815 -3816 -3817 -3818 -3819 -3820 -3821 -3822 -3823 -3824 -3825 -3826 -3827 -3828 -3829 -3830 -3831 -3832 -3833 -3834 -3835 -3836 -3837 -3838 -3839 -3840 -3841 -3842 -3843 -3844 -3845 -3846 -3847 -3848 -3849 -3850 -3851 -3852 -3853 -3854 -3855 -3856 -3857 -3858 -3859 -3860 -3861 -3862 -3863 -3864 -3865 -3866 -3867 -3868 -3869 -3870 -3871 -3872 -3873 -3874 -3875 -3876 -3877 -3878 -3879 -3880 -3881 -3882 -3883 -3884 -3885 -3886 -3887 -3888 -3889 -3890 -3891 -3892 -3893 -3894 -3895 -3896 -3897 -3898 -3899 -3900 -3901 -3902 -3903 -3904 -3905 -3906 -3907 -3908 -3909 -3910 -3911 -3912 -3913 -3914 -3915 -3916 -3917 -3918 -3919 -3920 -3921 -3922 -3923 -3924 -3925 -3926 -3927 -3928 -3929 -3930 -3931 -3932 -3933 -3934 -3935 -3936 -3937 -3938 -3939 -3940 -3941 -3942 -3943 -3944 -3945 -3946 -3947 -3948 -3949 -3950 -3951 -3952 -3953 -3954 -3955 -3956 -3957 -3958 -3959 -3960 -3961 -3962 -3963 -3964 -3965 -3966 -3967 -3968 -3969 -3970 -3971 -3972 -3973 -3974 -3975 -3976 -3977 -3978 -3979 -3980 -3981 -3982 -3983 -3984 -3985 -3986 -3987 -3988 -3989 -3990 -3991 -3992 -3993 -3994 -3995 -3996 -3997 -3998 -3999 -4000 -4001 -4002 -4003 -4004 -4005 -4006 -4007 -4008 -4009 -4010 -4011 -4012 -4013 -4014 -4015 -4016 -4017 -4018 -4019 -4020 -4021 -4022 -4023 -4024 -4025 -4026 -4027 -4028 -4029 -4030 -4031 -4032 -4033 -4034 -4035 -4036 -4037 -4038 -4039 -4040 -4041 -4042 -4043 -4044 -4045 -4046 -4047 -4048 -4049 -4050 -4051 -4052 -4053 -4054 -4055 -4056 -4057 -4058 -4059 -4060 -4061 -4062 -4063 -4064 -4065 -4066 -4067 -4068 -4069 -4070 -4071 -4072 -4073 -4074 -4075 -4076 -4077 -4078 -4079 -4080 -4081 -4082 -4083 -4084 -4085 -4086 -4087 -4088 -4089 -4090 -4091 -4092 -4093 -4094 -4095 -4096 -4097 -4098 -4099 -4100 -4101 -4102 -4103 -4104 -4105 -4106 -4107 -4108 -4109 -4110 -4111 -4112 -4113 -4114 -4115 -4116 -4117 -4118 -4119 -4120 -4121 -4122 -4123 -4124 -4125 -4126 -4127 -4128 -4129 -4130 -4131 -4132 -4133 -4134 -4135 -4136 -4137 -4138 -4139 -4140 -4141 -4142 -4143 -4144 -4145 -4146 -4147 -4148 -4149 -4150 -4151 -4152 -4153 -4154 -4155 -4156 -4157 -4158 -4159 -4160 -4161 -4162 -4163 -4164 -4165 -4166 -4167 -4168 -4169 -4170 -4171 -4172 -4173 -4174 -4175 -4176 -4177 -4178 -4179 -4180 -4181 -4182 -4183 -4184 -4185 -4186 -4187 -4188 -4189 -4190 -4191 -4192 -4193 -4194 -4195 -4196 -4197 -4198 -4199 -4200 -4201 -4202 -4203 -4204 -4205 -4206 -4207 -4208 -4209 -4210 -4211 -4212 -4213 -4214 -4215 -4216 -4217 -4218 -4219 -4220 -4221 -4222 -4223 -4224 -4225 -4226 -4227 -4228 -4229 -4230 -4231 -4232 -4233 -4234 -4235 -4236 -4237 -4238 -4239 -4240 -4241 -4242 -4243 -4244 -4245 -4246 -4247 -4248 -4249 -4250 -4251 -4252 -4253 -4254 -4255 -4256 -4257 -4258 -4259 -4260 -4261 -4262 -4263 -4264 -4265 -4266 -4267 -4268 -4269 -4270 -4271 -4272 -4273 -4274 -4275 -4276 -4277 -4278 -4279 -4280 -4281 -4282 -4283 -4284 -4285 -4286 -4287 -4288 -4289 -4290 -4291 -4292 -4293 -4294 -4295 -4296 -4297 -4298 -4299 -4300 -4301 -4302 -4303 -4304 -4305 -4306 -4307 -4308 -4309 -4310 -4311 -4312 -4313 -4314 -4315 -4316 -4317 -4318 -4319 -4320 -4321 -4322 -4323 -4324 -4325 -4326 -4327 -4328 -4329 -4330 -4331 -4332 -4333 -4334 -4335 -4336 -4337 -4338 -4339 -4340 -4341 -4342 -4343 -4344 -4345 -4346 -4347 -4348 -4349 -4350 -4351 -4352 -4353 -4354 -4355 -4356 -4357 -4358 -4359 -4360 -4361 -4362 -4363 -4364 -4365 -4366 -4367 -4368 -4369 -4370 -4371 -4372 -4373 -4374 -4375 -4376 -4377 -4378 -4379 -4380 -4381 -4382 -4383 -4384 -4385 -4386 -4387 -4388 -4389 -4390 -4391 -4392 -4393 -4394 -4395 -4396 -4397 -4398 -4399 -4400 -4401 -4402 -4403 -4404 -4405 -4406 -4407 -4408 -4409 -4410 -4411 -4412 -4413 -4414 -4415 -4416 -4417 -4418 -4419 -4420 -4421 -4422 -4423 -4424 -4425 -4426 -4427 -4428 -4429 -4430 -4431 -4432 -4433 -4434 -4435 -4436 -4437 -4438 -4439 -4440 -4441 -4442 -4443 -4444 -4445 -4446 -4447 -4448 -4449 -4450 -4451 -4452 -4453 -4454 -4455 -4456 -4457 -4458 -4459 -4460 -4461 -4462 -4463 -4464 -4465 -4466 -4467 -4468 -4469 -4470 -4471 -4472 -4473 -4474 -4475 -4476 -4477 -4478 -4479 -4480 -4481 -4482 -4483 -4484 -4485 -4486 -4487 -4488 -4489 -4490 -4491 -4492 -4493 -4494 -4495 -4496 -4497 -4498 -4499 -4500 -4501 -4502 -4503 -4504 -4505 -4506 -4507 -4508 -4509 -4510 -4511 -4512 -4513 -4514 -4515 -4516 -4517 -4518 -4519 -4520 -4521 -4522 -4523 -4524 -4525 -4526 -4527 -4528 -4529 -4530 -4531 -4532 -4533 -4534 -4535 -4536 -4537 -4538 -4539 -4540 -4541 -4542 -4543 -4544 -4545 -4546 -4547 -4548 -4549 -4550 -4551 -4552 -4553 -4554 -4555 -4556 -4557 -4558 -4559 -4560 -4561 -4562 -4563 -4564 -4565 -4566 -4567 -4568 -4569 -4570 -4571 -4572 -4573 -4574 -4575 -4576 -4577 -4578 -4579 -4580 -4581 -4582 -4583 -4584 -4585 -4586 -4587 -4588 -4589 -4590 -4591 -4592 -4593 -4594 -4595 -4596 -4597 -4598 -4599 -4600 -4601 -4602 -4603 -4604 -4605 -4606 -4607 -4608 -4609 -4610 -4611 -4612 -4613 -4614 -4615 -4616 -4617 -4618 -4619 -4620 -4621 -4622 -4623 -4624 -4625 -4626 -4627 -4628 -4629 -4630 -4631 -4632 -4633 -4634 -4635 -4636 -4637 -4638 -4639 -4640 -4641 -4642 -4643 -4644 -4645 -4646 -4647 -4648 -4649 -4650 -4651 -4652 -4653 -4654 -4655 -4656 -4657 -4658 -4659 -4660 -4661 -4662 -4663 -4664 -4665 -4666 -4667 -4668 -4669 -4670 -4671 -4672 -4673 -4674 -4675 -4676 -4677 -4678 -4679 -4680 -4681 -4682 -4683 -4684 -4685 -4686 -4687 -4688 -4689 -4690 -4691 -4692 -4693 -4694 -4695 -4696 -4697 -4698 -4699 -4700 -4701 -4702 -4703 -4704 -4705 -4706 -4707 -4708 -4709 -4710 -4711 -4712 -4713 -4714 -4715 -4716 -4717 -4718 -4719 -4720 -4721 -4722 -4723 -4724 -4725 -4726 -4727 -4728 -4729 -4730 -4731 -4732 -4733 -4734 -4735 -4736 -4737 -4738 -4739 -4740 -4741 -4742 -4743 -4744 -4745 -4746 -4747 -4748 -4749 -4750 -4751 -4752 -4753 -4754 -4755 -4756 -4757 -4758 -4759 -4760 -4761 -4762 -4763 -4764 -4765 -4766 -4767 -4768 -4769 -4770 -4771 -4772 -4773 -4774 -4775 -4776 -4777 -4778 -4779 -4780 -4781 -4782 -4783 -4784 -4785 -4786 -4787 -4788 -4789 -4790 -4791 -4792 -4793 -4794 -4795 -4796 -4797 -4798 -4799 -4800 -4801 -4802 -4803 -4804 -4805 -4806 -4807 -4808 -4809 -4810 -4811 -4812 -4813 -4814 -4815 -4816 -4817 -4818 -4819 -4820 -4821 -4822 -4823 -4824 -4825 -4826 -4827 -4828 -4829 -4830 -4831 -4832 -4833 -4834 -4835 -4836 -4837 -4838 -4839 -4840 -4841 -4842 -4843 -4844 -4845 -4846 -4847 -4848 -4849 -4850 -4851 -4852 -4853 -4854 -4855 -4856 -4857 -4858 -4859 -4860 -4861 -4862 -4863 -4864 -4865 -4866 -4867 -4868 -4869 -4870 -4871 -4872 -4873 -4874 -4875 -4876 -4877 -4878 -4879 -4880 -4881 -4882 -4883 -4884 -4885 -4886 -4887 -4888 -4889 -4890 -4891 -4892 -4893 -4894 -4895 -4896 -4897 -4898 -4899 -4900 -4901 -4902 -4903 -4904 -4905 -4906 -4907 -4908 -4909 -4910 -4911 -4912 -4913 -4914 -4915 -4916 -4917 -4918 -4919 -4920 -4921 -4922 -4923 -4924 -4925 -4926 -4927 -4928 -4929 -4930 -4931 -4932 -4933 -4934 -4935 -4936 -4937 -4938 -4939 -4940 -4941 -4942 -4943 -4944 -4945 -4946 -4947 -4948 -4949 -4950 -4951 -4952 -4953 -4954 -4955 -4956 -4957 -4958 -4959 -4960 -4961 -4962 -4963 -4964 -4965 -4966 -4967 -4968 -4969 -4970 -4971 -4972 -4973 -4974 -4975 -4976 -4977 -4978 -4979 -4980 -4981 -4982 -4983 -4984 -4985 -4986 -4987 -4988 -4989 -4990 -4991 -4992 -4993 -4994 -4995 -4996 -4997 -4998 -4999 -GRAPH EDGES -(4762, 3247, 768) -(1790, 2386, 1506) -(1567, 4614, 659) -(3927, 1562, 1052) -(4826, 2330, 1088) -(4735, 4895, 718) -(238, 2375, 890) -(3372, 1039, 1020) -(1395, 3726, 555) -(2433, 4367, 585) -(454, 1147, 373) -(3332, 3067, 1564) -(3613, 376, 151) -(1509, 4827, 1140) -(475, 3873, 77) -(4383, 3614, 743) -(3816, 2548, 736) -(720, 173, 1493) -(775, 1847, 1143) -(2805, 46, 556) -(4472, 3808, 323) -(1283, 3020, 1650) -(3529, 2017, 180) -(3828, 778, 332) -(488, 353, 547) -(1632, 3022, 713) -(3318, 17, 1326) -(1257, 3331, 1090) -(2045, 3434, 1535) -(2015, 1494, 492) -(4651, 4534, 501) -(1761, 4978, 1041) -(535, 3107, 1693) -(1027, 4306, 479) -(2912, 2799, 123) -(1133, 1736, 1156) -(4438, 1686, 833) -(3172, 1410, 111) -(4927, 1310, 1598) -(4498, 1625, 1226) -(1024, 4628, 1282) -(3622, 4912, 1092) -(4365, 4893, 788) -(1253, 4965, 1076) -(3984, 2469, 1215) -(4764, 1281, 507) -(587, 4069, 1299) -(4670, 3700, 827) -(1565, 4532, 952) -(542, 4200, 1430) -(2945, 878, 218) -(3984, 1953, 554) -(4269, 625, 112) -(3823, 3590, 1831) -(4702, 2170, 1616) -(4238, 3966, 191) -(473, 2433, 114) -(223, 2821, 352) -(2042, 1223, 696) -(1598, 1391, 1241) -(889, 103, 1719) -(2995, 1716, 165) -(1497, 2513, 1001) -(3499, 1360, 1296) -(3606, 3540, 1304) -(1146, 2235, 141) -(1466, 1190, 1818) -(67, 4141, 67) -(3871, 2788, 360) -(2827, 479, 894) -(2754, 1237, 1173) -(3714, 3378, 1836) -(4945, 2593, 1861) -(2692, 3771, 1032) -(1563, 2384, 1005) -(4655, 724, 657) -(4958, 3882, 651) -(4022, 4455, 670) -(3770, 3328, 695) -(1890, 3742, 770) -(3864, 3469, 1586) -(1929, 2951, 1825) -(3000, 4725, 628) -(4394, 4329, 1443) -(636, 1368, 185) -(4556, 3605, 1433) -(715, 4967, 1605) -(1773, 2254, 646) -(3555, 4321, 728) -(4309, 4191, 155) -(2119, 1082, 182) -(2876, 4658, 1144) -(4213, 214, 546) -(2860, 892, 850) -(3932, 2236, 117) -(3132, 4425, 1898) -(4603, 2003, 1386) -(1121, 2275, 1158) -(4909, 2360, 1288) -(2837, 4552, 1578) -(2889, 1198, 459) -(4597, 465, 796) -(4740, 2975, 769) -(4102, 2012, 1041) -(2019, 68, 1384) -(1159, 1366, 1825) -(2994, 2785, 1049) -(1093, 2307, 1646) -(4052, 2221, 1907) -(4380, 3442, 870) -(3226, 4405, 672) -(3619, 113, 1443) -(4505, 3742, 973) -(2714, 4628, 110) -(1266, 3321, 1078) -(3760, 1138, 1036) -(2905, 640, 1283) -(4178, 113, 545) -(201, 2905, 96) -(18, 583, 736) -(3539, 1647, 855) -(226, 1878, 1006) -(4971, 820, 76) -(2180, 3096, 1968) -(245, 326, 307) -(72, 2128, 270) -(1953, 3984, 554) -(2269, 615, 787) -(865, 1869, 711) -(4460, 4239, 1271) -(1989, 2154, 1149) -(3833, 564, 732) -(3852, 2267, 1469) -(1359, 3673, 965) -(3997, 3102, 138) -(216, 3003, 1061) -(3040, 3242, 1932) -(3320, 3141, 125) -(3043, 4798, 477) -(139, 4323, 1662) -(4626, 4391, 1980) -(2132, 4325, 228) -(251, 1098, 1936) -(4256, 3045, 1764) -(3889, 2138, 776) -(746, 715, 406) -(73, 4038, 1973) -(1332, 1070, 1587) -(4908, 2325, 191) -(2940, 1938, 527) -(1434, 812, 299) -(3654, 3282, 1462) -(703, 2899, 204) -(2559, 2456, 1894) -(4496, 443, 867) -(948, 4523, 621) -(1200, 1500, 1385) -(4872, 1921, 959) -(3438, 890, 414) -(3495, 159, 1234) -(671, 2905, 1052) -(1133, 2974, 433) -(696, 1173, 71) -(1554, 3006, 1671) -(3075, 4484, 1067) -(4992, 1783, 1253) -(1411, 3827, 62) -(1469, 4184, 1675) -(520, 4396, 214) -(4483, 1664, 571) -(1874, 859, 265) -(801, 1488, 1374) -(2099, 2861, 357) -(4864, 3949, 235) -(700, 1526, 836) -(1838, 934, 699) -(2338, 4352, 716) -(1217, 808, 1635) -(4792, 696, 1396) -(2320, 2138, 1138) -(978, 2000, 961) -(3590, 379, 261) -(4994, 856, 721) -(507, 284, 643) -(1247, 542, 665) -(4493, 4256, 1598) -(3395, 1797, 1008) -(4624, 1041, 479) -(2435, 111, 195) -(230, 4553, 1901) -(4105, 2623, 1569) -(57, 3761, 1860) -(1431, 2705, 376) -(4607, 622, 605) -(4209, 939, 726) -(512, 4431, 1173) -(816, 2178, 846) -(259, 4158, 1956) -(4153, 2503, 920) -(1575, 525, 251) -(2367, 3597, 1659) -(2669, 3898, 1283) -(3730, 393, 1366) -(4145, 3447, 473) -(1512, 870, 1869) -(2945, 2923, 1017) -(3096, 1493, 1119) -(1789, 780, 1283) -(1020, 69, 1880) -(4551, 2017, 728) -(890, 3438, 414) -(3062, 2680, 484) -(1936, 3007, 829) -(71, 1473, 1114) -(4486, 4074, 791) -(2293, 1821, 975) -(4676, 836, 950) -(2219, 3830, 1253) -(2989, 4743, 1078) -(1019, 2795, 350) -(345, 244, 1287) -(1829, 4988, 1991) -(2329, 3971, 829) -(3485, 3962, 543) -(4811, 4113, 935) -(1335, 3012, 179) -(4557, 3468, 586) -(2977, 1091, 728) -(2315, 1572, 56) -(1798, 1800, 1145) -(1180, 4875, 915) -(813, 4398, 1736) -(2651, 3804, 58) -(1805, 2788, 596) -(4278, 54, 1856) -(165, 306, 1742) -(1875, 731, 1954) -(945, 2609, 66) -(1451, 2903, 1802) -(3915, 1313, 1747) -(3746, 4428, 509) -(3002, 1676, 276) -(4860, 4554, 1319) -(52, 3658, 854) -(881, 79, 103) -(737, 1428, 56) -(4337, 4306, 509) -(3008, 3990, 1371) -(1429, 2932, 277) -(838, 3143, 266) -(2090, 3755, 817) -(632, 914, 464) -(372, 1173, 1028) -(4249, 2181, 696) -(4412, 1751, 94) -(100, 792, 621) -(1263, 3225, 763) -(4886, 2800, 1508) -(2651, 3526, 754) -(493, 1371, 283) -(4428, 3746, 509) -(2183, 3763, 1391) -(1019, 4746, 316) -(1506, 1417, 1070) -(2376, 1631, 1758) -(4449, 2109, 1556) -(2289, 1350, 1443) -(3052, 1034, 428) -(4001, 4331, 968) -(120, 1237, 172) -(1783, 1173, 747) -(3396, 4747, 418) -(4681, 4391, 1702) -(3882, 2527, 1395) -(3051, 4529, 1684) -(913, 4547, 286) -(4748, 3291, 1144) -(2199, 3857, 756) -(3688, 4406, 826) -(4877, 2340, 1010) -(4064, 628, 1562) -(3554, 3947, 1252) -(1294, 56, 495) -(3887, 847, 1188) -(3423, 1366, 1631) -(4356, 697, 1168) -(4746, 361, 1585) -(386, 2393, 608) -(4724, 770, 1995) -(4457, 376, 642) -(1761, 4555, 209) -(3573, 4301, 1886) -(3183, 730, 392) -(194, 1082, 1717) -(3237, 1438, 397) -(3710, 4641, 1227) -(104, 3928, 1690) -(376, 3613, 151) -(1971, 3613, 98) -(3882, 4281, 394) -(2721, 2523, 1842) -(2181, 2584, 545) -(580, 762, 668) -(3960, 4024, 1643) -(1690, 2379, 1360) -(2169, 4332, 1611) -(821, 1264, 1991) -(2409, 2303, 1874) -(2330, 731, 462) -(2129, 1552, 372) -(2372, 2768, 1041) -(4093, 4996, 1472) -(2514, 1098, 1163) -(2134, 4627, 1119) -(3545, 3049, 565) -(4693, 4559, 978) -(4539, 4020, 926) -(2710, 3384, 751) -(2350, 3499, 965) -(4751, 4323, 381) -(1541, 332, 956) -(4113, 4811, 935) -(3199, 1818, 1035) -(3700, 4670, 827) -(4889, 2931, 1439) -(1674, 1391, 1708) -(4351, 3464, 1700) -(3436, 1380, 93) -(2536, 3742, 1291) -(4867, 1350, 510) -(1594, 1898, 1561) -(4297, 434, 651) -(1463, 2235, 1506) -(3730, 4158, 1511) -(1248, 418, 691) -(1329, 4559, 113) -(2384, 1777, 1408) -(574, 3322, 844) -(515, 2083, 888) -(534, 3853, 309) -(4696, 2332, 864) -(45, 4931, 1420) -(4210, 2168, 1255) -(1514, 429, 450) -(1490, 1394, 1565) -(3939, 3604, 1964) -(556, 4824, 315) -(4031, 460, 1463) -(528, 2486, 887) -(3456, 4523, 1907) -(3065, 2875, 160) -(61, 3490, 913) -(4773, 2741, 1514) -(4874, 1985, 1644) -(1527, 1185, 838) -(831, 638, 330) -(3409, 1791, 115) -(2727, 3699, 1316) -(3901, 944, 79) -(2403, 3331, 1648) -(3353, 1098, 1712) -(2375, 238, 890) -(746, 2942, 926) -(3791, 1178, 862) -(4599, 4075, 558) -(3254, 1430, 1283) -(971, 3616, 1863) -(2268, 4790, 1735) -(822, 3758, 724) -(1566, 4177, 1000) -(386, 4854, 1372) -(4857, 961, 1401) -(4398, 1103, 1955) -(1369, 2583, 1272) -(3113, 4806, 1927) -(3842, 1457, 1816) -(4970, 564, 1346) -(2973, 550, 1340) -(2013, 2588, 1010) -(1743, 2743, 988) -(1186, 2569, 1845) -(4263, 225, 1956) -(1099, 1320, 1911) -(3013, 3153, 722) -(641, 240, 1443) -(2858, 486, 1389) -(1212, 2901, 1252) -(1484, 1722, 760) -(2682, 1982, 619) -(3423, 2967, 1319) -(4987, 4616, 1885) -(870, 2545, 987) -(2762, 3762, 718) -(3206, 751, 368) -(1367, 4871, 268) -(3111, 2205, 1758) -(4362, 2735, 967) -(2117, 230, 1612) -(2935, 2609, 1946) -(2016, 1931, 624) -(2687, 4972, 931) -(2529, 3610, 744) -(3892, 361, 1824) -(792, 354, 1205) -(885, 3274, 355) -(744, 123, 1322) -(1008, 4376, 762) -(1682, 1035, 1228) -(1401, 4375, 302) -(1203, 3368, 1360) -(338, 3648, 1248) -(1173, 372, 1028) -(4542, 2786, 168) -(4106, 1425, 1466) -(1378, 1065, 1180) -(4397, 3214, 1916) -(44, 25, 1825) -(3984, 2723, 809) -(2742, 4134, 857) -(1948, 1696, 609) -(802, 3613, 1703) -(1022, 3581, 371) -(1296, 1442, 1980) -(1050, 4329, 888) -(3355, 382, 939) -(1056, 2057, 1819) -(4196, 390, 1030) -(1159, 4835, 421) -(47, 214, 1243) -(3303, 4693, 99) -(4587, 4069, 1234) -(1992, 4417, 352) -(4214, 940, 1203) -(3710, 1577, 1031) -(254, 1122, 651) -(3986, 2843, 772) -(113, 2978, 902) -(2927, 479, 727) -(366, 4623, 136) -(1994, 3194, 1189) -(3418, 4272, 1442) -(531, 266, 546) -(1318, 3822, 1670) -(3654, 16, 348) -(458, 2, 1505) -(2007, 1924, 868) -(1916, 191, 1340) -(1005, 4503, 223) -(286, 788, 1639) -(1919, 2011, 759) -(2355, 4800, 64) -(648, 445, 1813) -(1731, 2086, 1641) -(2011, 550, 1534) -(435, 3507, 529) -(1648, 1776, 762) -(4341, 2796, 351) -(2408, 681, 1502) -(4888, 4512, 1026) -(1340, 2750, 1869) -(3462, 1320, 803) -(116, 1784, 1902) -(2833, 1152, 1595) -(2604, 224, 732) -(4046, 184, 1717) -(1905, 148, 1231) -(447, 1053, 383) -(2226, 2662, 1598) -(2882, 1201, 1385) -(3024, 2585, 334) -(704, 99, 706) -(4215, 3565, 256) -(4331, 460, 245) -(2032, 4042, 558) -(463, 3783, 1252) -(4981, 2798, 1133) -(3797, 2477, 1139) -(3074, 2077, 1488) -(3971, 2329, 829) -(3690, 113, 586) -(4231, 193, 1386) -(2051, 1024, 196) -(3581, 2488, 1340) -(3433, 232, 639) -(1910, 3066, 659) -(2222, 1287, 107) -(4175, 4831, 148) -(4386, 170, 1146) -(611, 2456, 174) -(2409, 1584, 563) -(3109, 3285, 1642) -(2870, 4039, 1723) -(227, 2803, 1009) -(406, 4957, 638) -(249, 2063, 90) -(2049, 3864, 1366) -(541, 4441, 1629) -(2218, 86, 351) -(2770, 555, 1101) -(4455, 4022, 670) -(388, 4787, 669) -(2632, 2444, 1640) -(3702, 3451, 849) -(2594, 4872, 1244) -(1726, 3726, 1848) -(2277, 3250, 356) -(1992, 4682, 224) -(431, 4262, 1075) -(3142, 1954, 670) -(4867, 1075, 1577) -(490, 3457, 686) -(782, 4035, 1916) -(1798, 2231, 1200) -(4919, 2086, 1876) -(3189, 2107, 1361) -(3765, 148, 1094) -(1304, 1776, 820) -(676, 4550, 195) -(2988, 2496, 429) -(2046, 867, 1793) -(4605, 745, 861) -(410, 554, 1957) -(3684, 452, 841) -(666, 4963, 551) -(83, 2286, 1824) -(4848, 4225, 1471) -(2959, 429, 1120) -(4616, 4700, 1931) -(1619, 3895, 1823) -(4248, 3211, 1439) -(1823, 81, 772) -(4263, 2504, 513) -(2262, 1728, 484) -(193, 3295, 1776) -(259, 4440, 832) -(145, 1445, 1632) -(1577, 2235, 636) -(4416, 661, 350) -(1967, 2591, 356) -(4240, 2591, 1756) -(2783, 1898, 1515) -(1082, 4951, 908) -(577, 1325, 617) -(2605, 2778, 675) -(982, 2064, 635) -(1730, 4266, 1631) -(2984, 2249, 629) -(3718, 276, 1503) -(4373, 4281, 1701) -(3254, 1973, 1782) -(2997, 2384, 897) -(2204, 3072, 1829) -(3228, 3707, 304) -(498, 3029, 853) -(2273, 3646, 1076) -(1252, 3390, 1496) -(3374, 3286, 1922) -(4883, 8, 62) -(2928, 138, 1647) -(244, 4696, 1096) -(3258, 2679, 107) -(4768, 1880, 614) -(787, 1595, 1513) -(4510, 1501, 627) -(2039, 3273, 764) -(186, 252, 50) -(2769, 4931, 711) -(1963, 2101, 742) -(2425, 1991, 527) -(1735, 2535, 697) -(712, 1147, 392) -(443, 2614, 1203) -(2589, 892, 725) -(2863, 1805, 1606) -(4769, 2230, 1860) -(535, 4362, 256) -(840, 441, 1703) -(3197, 4596, 1783) -(2804, 3785, 1101) -(2129, 2840, 164) -(2402, 2767, 479) -(372, 686, 1115) -(206, 3931, 1223) -(1432, 1806, 1072) -(954, 3550, 230) -(509, 2637, 927) -(3250, 3049, 1846) -(1173, 3153, 1231) -(3070, 978, 1990) -(470, 1952, 1830) -(724, 4716, 1344) -(3880, 1911, 989) -(4859, 3607, 1165) -(159, 4563, 1853) -(2092, 946, 1489) -(1956, 1412, 1288) -(1025, 1390, 1005) -(2416, 2914, 1652) -(4831, 922, 225) -(145, 257, 1767) -(2534, 3011, 1318) -(4477, 2817, 1803) -(2475, 2075, 1863) -(4161, 316, 88) -(550, 2011, 1534) -(3378, 168, 444) -(2095, 1134, 133) -(442, 1036, 259) -(583, 2377, 72) -(2709, 2286, 1601) -(1695, 3436, 282) -(2315, 2378, 1733) -(4536, 3400, 1788) -(1071, 4472, 1372) -(1742, 979, 869) -(4331, 2505, 768) -(883, 3323, 1500) -(2477, 3797, 1139) -(263, 4286, 447) -(2530, 1250, 1492) -(1280, 543, 830) -(2241, 4167, 772) -(1198, 2889, 459) -(1849, 4790, 985) -(4803, 1179, 1497) -(4419, 622, 883) -(4218, 783, 986) -(2158, 4649, 1377) -(381, 4327, 744) -(2396, 3121, 1201) -(874, 2262, 779) -(1736, 2350, 717) -(2057, 4981, 1625) -(4633, 3064, 694) -(3544, 2789, 637) -(320, 2086, 987) -(172, 4627, 592) -(1797, 877, 1851) -(4443, 4848, 200) -(4228, 3893, 1048) -(971, 2081, 594) -(408, 525, 891) -(3283, 4003, 568) -(3312, 1771, 1186) -(2538, 1530, 1320) -(2534, 1755, 646) -(2289, 1265, 1981) -(2090, 306, 513) -(2032, 2962, 1592) -(2480, 4396, 87) -(834, 4103, 1148) -(3522, 1623, 1319) -(1822, 3105, 69) -(4824, 680, 1729) -(1637, 3888, 1525) -(3155, 4445, 812) -(4540, 3997, 201) -(2669, 761, 1835) -(2869, 471, 329) -(1759, 954, 831) -(1155, 251, 302) -(4926, 3683, 1237) -(79, 3718, 1319) -(3799, 341, 1990) -(1643, 1759, 1957) -(4378, 2439, 1951) -(1265, 4374, 467) -(4806, 2221, 775) -(2650, 166, 251) -(3202, 1585, 292) -(3365, 1091, 71) -(1740, 4053, 1798) -(3920, 3846, 165) -(2767, 2402, 479) -(3176, 3931, 1944) -(2652, 4560, 1635) -(4070, 2172, 69) -(3964, 3543, 385) -(3332, 4836, 242) -(2168, 1861, 734) -(2304, 3271, 1140) -(671, 3535, 1864) -(1931, 4825, 240) -(3091, 1487, 1159) -(1352, 4632, 189) -(1208, 685, 1377) -(1003, 1517, 282) -(825, 527, 922) -(1664, 4393, 1631) -(4369, 4365, 1967) -(3252, 302, 1054) -(3215, 1882, 384) -(839, 3320, 739) -(1756, 3210, 430) -(245, 564, 1011) -(3298, 3214, 965) -(1961, 4035, 1988) -(1871, 2199, 1907) -(3251, 4230, 145) -(971, 343, 1271) -(1116, 2685, 1208) -(1635, 983, 457) -(626, 741, 590) -(3005, 1898, 1238) -(3714, 2349, 1881) -(2133, 1731, 142) -(2218, 2200, 525) -(1285, 187, 1514) -(507, 4753, 1597) -(4740, 1718, 993) -(3467, 4718, 1693) -(581, 859, 1049) -(530, 991, 171) -(3173, 1409, 1367) -(32, 1160, 1444) -(577, 3700, 906) -(2348, 926, 441) -(999, 4244, 1336) -(4840, 1550, 777) -(3089, 108, 1094) -(2232, 3079, 1879) -(392, 556, 1634) -(2453, 4193, 220) -(1338, 2397, 1999) -(1520, 1096, 200) -(3964, 1727, 658) -(3096, 2180, 1968) -(1109, 2718, 1762) -(1547, 1815, 1256) -(4534, 4242, 956) -(1953, 1628, 392) -(4196, 3669, 1103) -(4050, 3016, 1499) -(1330, 565, 1401) -(835, 81, 1267) -(4778, 803, 1305) -(1562, 2604, 477) -(1221, 2120, 1658) -(3976, 2440, 133) -(4185, 2449, 669) -(2082, 4969, 933) -(3600, 4578, 1710) -(1596, 3395, 68) -(3224, 3967, 1323) -(1400, 2454, 1724) -(37, 2214, 918) -(4340, 1479, 903) -(4295, 3888, 543) -(588, 286, 1573) -(1144, 2214, 1356) -(278, 1802, 162) -(1006, 1024, 1295) -(1424, 2449, 1736) -(2798, 4891, 1677) -(1120, 406, 882) -(3435, 4002, 676) -(1328, 3528, 1429) -(171, 1603, 683) -(1409, 3173, 1367) -(3998, 4401, 847) -(3654, 4439, 991) -(1812, 102, 606) -(1135, 137, 1637) -(2264, 4001, 1271) -(877, 905, 1555) -(1732, 840, 124) -(1931, 2956, 1044) -(1206, 4501, 1532) -(3702, 3379, 1660) -(3556, 4436, 289) -(2970, 65, 67) -(3171, 318, 1425) -(524, 3602, 1949) -(3676, 4138, 958) -(2026, 3321, 1296) -(1454, 3718, 1662) -(2750, 1340, 1869) -(3436, 1695, 282) -(4281, 2363, 770) -(533, 3722, 1185) -(4792, 311, 1833) -(1041, 599, 898) -(3942, 2193, 1353) -(4155, 3805, 1057) -(4262, 431, 1075) -(4871, 1367, 268) -(4078, 3505, 1307) -(1226, 4689, 802) -(2662, 342, 1167) -(14, 2648, 1830) -(2831, 2305, 570) -(3756, 3237, 533) -(275, 1452, 515) -(940, 2590, 535) -(1589, 2539, 703) -(1153, 4266, 308) -(3851, 196, 747) -(1344, 2883, 691) -(4931, 2769, 711) -(2291, 3927, 706) -(1427, 2949, 307) -(3990, 62, 1016) -(2972, 4159, 541) -(4569, 2654, 864) -(1326, 2206, 891) -(2120, 4673, 1684) -(4628, 3754, 1638) -(2528, 2450, 374) -(1375, 3642, 1507) -(3553, 3009, 1052) -(504, 867, 626) -(2916, 4556, 935) -(4334, 2241, 1675) -(4406, 3688, 826) -(4267, 910, 219) -(1825, 4614, 1651) -(3138, 1134, 1058) -(2434, 2404, 707) -(3628, 421, 1346) -(193, 1876, 1658) -(68, 2621, 168) -(2103, 2613, 1736) -(4874, 4581, 118) -(1757, 1991, 817) -(3260, 3537, 1607) -(4483, 1206, 622) -(3666, 352, 1004) -(1265, 1789, 604) -(244, 2496, 889) -(2343, 2323, 1424) -(704, 171, 818) -(3208, 4840, 1396) -(2064, 1178, 827) -(4795, 5, 904) -(2743, 518, 1258) -(1426, 478, 1110) -(2119, 1512, 1678) -(3159, 198, 138) -(330, 453, 209) -(3674, 667, 431) -(1395, 3347, 662) -(282, 120, 1316) -(2655, 4083, 190) -(892, 2860, 850) -(4201, 4841, 1810) -(2779, 2278, 1716) -(936, 2266, 270) -(1790, 3203, 1049) -(759, 2997, 1028) -(387, 1267, 104) -(3713, 135, 135) -(2197, 4883, 1777) -(4264, 3141, 1526) -(1737, 1465, 661) -(2226, 1345, 1285) -(2799, 652, 1776) -(1528, 4602, 495) -(3430, 1266, 944) -(166, 3421, 1711) -(2342, 2347, 1153) -(1430, 2348, 906) -(4783, 3678, 927) -(2548, 1140, 1266) -(4638, 3383, 184) -(1420, 486, 1982) -(3631, 3626, 1502) -(2262, 1838, 1376) -(3290, 3239, 1347) -(2083, 4606, 287) -(4740, 3127, 1199) -(2411, 2772, 1503) -(3621, 2752, 1011) -(286, 1008, 818) -(4219, 4002, 714) -(3, 740, 733) -(3037, 4624, 241) -(3099, 2298, 1968) -(113, 4243, 1792) -(4082, 1548, 1773) -(2663, 4143, 1279) -(4299, 2149, 138) -(3993, 4153, 797) -(4565, 947, 1646) -(3730, 1936, 1225) -(947, 2626, 366) -(300, 1188, 1541) -(4121, 1423, 1085) -(832, 2283, 1086) -(4451, 868, 832) -(972, 707, 202) -(1596, 14, 1139) -(2948, 2237, 175) -(1092, 2084, 939) -(2899, 4918, 1771) -(2796, 59, 687) -(4415, 2674, 55) -(3455, 1316, 770) -(3793, 413, 788) -(4309, 4695, 926) -(1757, 2538, 1531) -(2944, 1275, 1622) -(4512, 3495, 1598) -(2008, 3332, 1653) -(4803, 360, 125) -(1785, 2942, 1090) -(1521, 882, 672) -(2528, 3749, 711) -(2331, 318, 1187) -(3227, 3624, 1113) -(2417, 3823, 1082) -(4723, 2711, 1249) -(228, 2846, 1367) -(1903, 2609, 637) -(1063, 4804, 1569) -(437, 167, 1867) -(2944, 3838, 336) -(903, 115, 1988) -(1731, 2656, 936) -(2508, 2650, 1018) -(1308, 1239, 1305) -(1832, 1651, 720) -(4815, 3882, 1412) -(4516, 3450, 199) -(3813, 1716, 590) -(423, 1090, 233) -(254, 1381, 75) -(4451, 2951, 813) -(4288, 3229, 805) -(2118, 1616, 1463) -(1139, 3326, 950) -(654, 3932, 535) -(2946, 51, 822) -(2085, 581, 439) -(1034, 1706, 142) -(996, 3301, 1202) -(16, 3733, 980) -(4991, 2126, 1108) -(2381, 3802, 712) -(2581, 1712, 1350) -(3554, 3479, 210) -(4249, 2843, 1590) -(4813, 754, 348) -(159, 1303, 877) -(598, 3869, 314) -(1961, 4269, 1524) -(1201, 3440, 380) -(1929, 3787, 1349) -(2612, 2737, 1151) -(4578, 2545, 156) -(3629, 4683, 1967) -(2690, 510, 304) -(4104, 4750, 265) -(4962, 2867, 1969) -(3328, 1242, 689) -(2122, 3441, 439) -(2579, 4048, 439) -(906, 2512, 253) -(2465, 2800, 163) -(4450, 449, 937) -(935, 1287, 587) -(4878, 3565, 1656) -(4036, 3354, 125) -(3325, 150, 1215) -(3996, 4321, 341) -(3511, 4306, 815) -(1845, 144, 1525) -(2723, 61, 1174) -(4012, 2993, 212) -(1126, 4433, 145) -(3797, 1287, 1249) -(4367, 2512, 1509) -(3705, 2008, 289) -(1530, 3602, 1044) -(1110, 2530, 139) -(2034, 4739, 1914) -(4876, 3598, 491) -(1031, 2945, 1490) -(3455, 755, 1686) -(655, 3893, 1515) -(1969, 4449, 461) -(4515, 3838, 1242) -(1199, 4700, 1757) -(3333, 1145, 1729) -(3163, 2500, 1100) -(3581, 2925, 487) -(4196, 2269, 1149) -(4092, 3968, 157) -(3479, 4347, 1314) -(993, 1568, 1962) -(1497, 4871, 312) -(2792, 4192, 712) -(3036, 3494, 286) -(3764, 701, 568) -(4403, 4374, 1014) -(3292, 3684, 1749) -(2433, 473, 114) -(4813, 3647, 201) -(1714, 4047, 1537) -(2529, 3440, 1097) -(457, 2403, 1593) -(3448, 3738, 472) -(3429, 2098, 1415) -(1654, 1929, 1907) -(1895, 4293, 333) -(4576, 394, 1919) -(4268, 464, 1419) -(100, 4917, 830) -(28, 4154, 661) -(2737, 3920, 1288) -(4225, 1444, 1506) -(4167, 3905, 1881) -(2089, 4433, 1814) -(4477, 70, 1711) -(3684, 636, 377) -(1019, 3342, 669) -(1169, 3847, 410) -(2740, 3285, 1126) -(1516, 2266, 1152) -(2180, 2805, 160) -(257, 145, 1767) -(3273, 2039, 764) -(447, 2711, 1876) -(769, 3493, 986) -(4018, 4595, 1739) -(4195, 2694, 328) -(2309, 2877, 1659) -(897, 3894, 862) -(2044, 4583, 1212) -(4446, 1234, 1906) -(4350, 3783, 271) -(4141, 2092, 1793) -(3915, 1425, 353) -(2234, 556, 1665) -(3271, 4290, 1495) -(808, 4887, 1251) -(4597, 4475, 440) -(1366, 3423, 1631) -(3723, 3667, 1610) -(2358, 1050, 1972) -(4779, 1974, 1140) -(1373, 677, 110) -(1149, 4833, 1406) -(2574, 2554, 1685) -(4410, 4747, 145) -(1301, 56, 1657) -(4603, 382, 1718) -(4155, 3119, 1098) -(2621, 4441, 189) -(1084, 3271, 945) -(4877, 1771, 642) -(232, 453, 1900) -(2055, 4375, 881) -(4020, 4539, 926) -(2514, 4151, 1222) -(3582, 4257, 261) -(3856, 1104, 342) -(2685, 2898, 1043) -(1908, 4307, 623) -(4815, 4313, 1380) -(3925, 4354, 663) -(3535, 671, 1864) -(2709, 1182, 154) -(928, 2955, 1712) -(4930, 780, 431) -(3877, 2523, 561) -(1355, 4428, 945) -(4965, 3677, 1917) -(3716, 395, 1210) -(4598, 4473, 1026) -(1508, 4969, 564) -(4959, 2887, 1185) -(3623, 3916, 210) -(2985, 1670, 345) -(3676, 3479, 938) -(2203, 1141, 1470) -(1119, 378, 84) -(4348, 264, 1469) -(9, 381, 1889) -(3367, 1406, 1612) -(1596, 3476, 958) -(3354, 3104, 182) -(687, 3748, 392) -(4248, 566, 1334) -(4969, 1336, 1059) -(2411, 2477, 1061) -(3301, 674, 1866) -(117, 2573, 874) -(3640, 20, 1502) -(2708, 4941, 1975) -(4234, 1375, 1089) -(4243, 113, 1792) -(982, 2519, 1095) -(71, 2986, 1249) -(4904, 4686, 1003) -(538, 4503, 873) -(2336, 2392, 1244) -(543, 4305, 345) -(2021, 974, 177) -(3395, 3890, 911) -(127, 1277, 566) -(3137, 2621, 1749) -(4051, 3383, 254) -(4856, 3585, 1954) -(2346, 4928, 1485) -(4335, 3536, 198) -(413, 4733, 1595) -(475, 1152, 103) -(4675, 943, 805) -(3139, 1337, 771) -(4135, 4762, 1969) -(2342, 2813, 1500) -(1918, 681, 116) -(1141, 2203, 1470) -(1911, 4424, 1446) -(252, 3030, 1361) -(4732, 4806, 976) -(3153, 1173, 1231) -(3894, 2802, 1313) -(3949, 4864, 235) -(2549, 3408, 703) -(4146, 306, 591) -(4076, 925, 543) -(4012, 4522, 1230) -(4392, 4448, 1391) -(1101, 3370, 1937) -(1706, 2140, 1037) -(2357, 601, 386) -(2886, 2057, 587) -(4988, 187, 1993) -(2490, 2390, 1714) -(3083, 4067, 786) -(3510, 910, 121) -(1015, 372, 1553) -(2763, 3095, 1864) -(3130, 2942, 1093) -(1991, 1757, 817) -(22, 4456, 656) -(1703, 1873, 1199) -(147, 532, 637) -(2109, 3909, 1872) -(607, 3786, 1077) -(1321, 3207, 1279) -(1205, 1255, 89) -(4096, 1109, 123) -(3395, 4227, 704) -(2172, 2987, 886) -(1653, 1851, 1906) -(4466, 1253, 551) -(2861, 1551, 673) -(483, 4468, 713) -(321, 4465, 1891) -(3785, 87, 1205) -(405, 1641, 573) -(2747, 3674, 1633) -(1606, 3138, 1292) -(3034, 555, 513) -(363, 1775, 1582) -(3607, 2502, 1171) -(1670, 4993, 1233) -(2347, 2342, 1153) -(812, 4008, 373) -(3540, 2484, 1581) -(932, 3334, 952) -(1951, 3150, 1239) -(2947, 2775, 78) -(999, 134, 345) -(3106, 4788, 369) -(2236, 1858, 1467) -(4771, 2194, 1417) -(2703, 3149, 774) -(3891, 908, 376) -(3015, 562, 904) -(4580, 3907, 1985) -(1255, 465, 1348) -(2566, 3835, 1999) -(568, 3499, 328) -(3441, 991, 1777) -(4275, 3060, 1733) -(3731, 2026, 1841) -(3177, 533, 1057) -(556, 2012, 1520) -(1522, 1324, 934) -(1115, 4302, 626) -(4010, 4714, 523) -(963, 4713, 879) -(441, 2035, 1309) -(4656, 3837, 1912) -(1439, 4287, 1505) -(4462, 902, 403) -(4800, 2769, 1847) -(444, 2274, 1357) -(3753, 2768, 851) -(1189, 1167, 1318) -(615, 3487, 1922) -(3396, 2648, 543) -(2214, 1612, 669) -(851, 257, 290) -(4288, 2397, 1008) -(4165, 1757, 858) -(4010, 1544, 1655) -(3018, 3838, 1006) -(1435, 4976, 655) -(3712, 2382, 813) -(4989, 2324, 1488) -(4413, 1315, 410) -(4784, 1693, 603) -(44, 1926, 894) -(2683, 230, 1582) -(1711, 2495, 479) -(3064, 1309, 1543) -(2560, 37, 719) -(4874, 1366, 1191) -(512, 2759, 566) -(2286, 2709, 1601) -(1350, 2508, 1665) -(3900, 2663, 1698) -(4870, 2206, 1382) -(3983, 2992, 1850) -(544, 4290, 1622) -(4431, 3067, 1991) -(1010, 2893, 368) -(751, 3981, 622) -(1035, 1444, 1343) -(439, 3208, 1597) -(2348, 1609, 1755) -(4282, 317, 1137) -(4230, 2637, 1064) -(1998, 967, 1967) -(110, 3496, 419) -(2063, 4811, 870) -(3267, 3968, 169) -(2415, 2568, 976) -(2729, 3244, 1240) -(1908, 3592, 1277) -(1461, 4007, 670) -(3422, 4425, 436) -(2817, 1204, 302) -(170, 4386, 1146) -(537, 1629, 878) -(3301, 996, 1202) -(4072, 2496, 499) -(3444, 4780, 814) -(79, 1954, 286) -(1071, 2036, 1984) -(3212, 3833, 293) -(2614, 1265, 1517) -(3376, 4488, 214) -(504, 4004, 641) -(4680, 1554, 728) -(2079, 3254, 1820) -(2354, 3318, 897) -(922, 3396, 1486) -(2771, 982, 260) -(2475, 3663, 704) -(3562, 951, 1848) -(448, 3957, 1604) -(433, 4208, 1450) -(678, 4026, 1981) -(996, 129, 1407) -(1655, 4327, 925) -(300, 3822, 1801) -(565, 948, 1506) -(3030, 4333, 1193) -(4809, 3663, 928) -(157, 4713, 1741) -(1970, 3301, 155) -(1359, 1388, 280) -(2892, 4294, 587) -(4238, 109, 1408) -(3652, 4208, 107) -(1320, 3806, 939) -(4347, 4398, 1276) -(1505, 2365, 1451) -(931, 1107, 1967) -(2168, 3564, 1768) -(3006, 3981, 1820) -(939, 156, 807) -(2644, 2554, 862) -(3719, 1746, 785) -(2945, 3011, 1155) -(2794, 4609, 1238) -(1776, 1183, 1569) -(2814, 2990, 1262) -(172, 2829, 1858) -(1330, 3506, 1676) -(2777, 1916, 1917) -(372, 1015, 1553) -(4792, 1625, 686) -(769, 2405, 913) -(316, 1012, 688) -(4005, 58, 916) -(3569, 1164, 1291) -(3889, 333, 743) -(158, 4083, 1022) -(3804, 3993, 1789) -(4388, 4084, 1312) -(3275, 4973, 1050) -(4600, 1054, 1345) -(4600, 3442, 281) -(4121, 2328, 1181) -(3087, 4799, 342) -(2578, 3770, 1830) -(1309, 3329, 1076) -(1786, 1502, 525) -(1719, 3051, 387) -(1340, 2245, 1923) -(1077, 205, 558) -(867, 2046, 1793) -(4245, 595, 267) -(3766, 2359, 1070) -(3416, 3367, 403) -(1290, 3882, 1977) -(812, 1434, 299) -(318, 2462, 579) -(3007, 1936, 829) -(492, 4998, 1245) -(2151, 498, 1441) -(2681, 217, 1456) -(983, 1612, 578) -(766, 977, 1954) -(2923, 2945, 1017) -(1332, 2249, 853) -(4648, 3346, 218) -(3430, 108, 771) -(866, 1738, 1152) -(3098, 4723, 1946) -(1705, 4921, 1856) -(1237, 120, 172) -(1465, 4061, 1567) -(4869, 3199, 111) -(2314, 1173, 287) -(2359, 4803, 601) -(948, 565, 1506) -(963, 2533, 560) -(1774, 4857, 1724) -(902, 3594, 797) -(153, 2105, 1029) -(904, 691, 1029) -(4084, 1724, 101) -(2480, 917, 394) -(2322, 2108, 1486) -(1234, 4169, 1856) -(1312, 2020, 1286) -(4899, 4625, 498) -(110, 951, 106) -(1509, 3645, 1798) -(4089, 2689, 1557) -(3450, 3448, 1403) -(2805, 3727, 1530) -(274, 2723, 1780) -(289, 4505, 1776) -(4650, 1265, 1181) -(1076, 728, 1931) -(2357, 4054, 815) -(2815, 3342, 508) -(2645, 1219, 615) -(3316, 353, 1122) -(3826, 4743, 591) -(3411, 1551, 1763) -(3241, 1441, 156) -(555, 3227, 1792) -(276, 1992, 239) -(3382, 156, 1632) -(4904, 1680, 904) -(3677, 4965, 1917) -(775, 4515, 1833) -(4542, 2010, 1337) -(2909, 3784, 1820) -(1706, 4906, 1129) -(4135, 4940, 575) -(1712, 2723, 1979) -(4559, 4693, 978) -(1768, 4522, 1968) -(1495, 3572, 1156) -(3632, 54, 399) -(4645, 4852, 120) -(2305, 2249, 1024) -(3165, 4205, 157) -(2753, 839, 313) -(3914, 891, 412) -(351, 1918, 148) -(4092, 216, 1764) -(4772, 766, 1881) -(4763, 4029, 138) -(752, 2833, 67) -(3187, 274, 808) -(2955, 3544, 214) -(1006, 4245, 1440) -(2455, 3004, 106) -(1093, 4434, 1055) -(377, 4115, 1882) -(4716, 1363, 1157) -(3216, 1180, 1377) -(1378, 4672, 362) -(721, 4239, 792) -(248, 1912, 1723) -(4960, 997, 1636) -(4434, 497, 636) -(100, 4317, 99) -(2118, 460, 1406) -(3730, 2810, 476) -(3093, 4306, 1149) -(2776, 626, 1632) -(3085, 3510, 1256) -(2131, 417, 1240) -(4758, 1954, 257) -(782, 2474, 74) -(1600, 3925, 1226) -(2058, 4432, 287) -(3243, 1794, 580) -(1039, 3797, 1158) -(4497, 3166, 1843) -(3178, 1465, 1837) -(251, 1155, 302) -(2272, 1969, 1561) -(31, 3652, 1722) -(3447, 942, 251) -(1232, 3253, 888) -(3228, 3758, 1432) -(2527, 4756, 201) -(2239, 4914, 748) -(748, 3383, 1958) -(3144, 2212, 1743) -(2488, 1461, 657) -(1625, 4792, 686) -(1683, 3550, 1548) -(2425, 3722, 555) -(3896, 4624, 1347) -(1267, 4794, 85) -(4188, 1321, 1779) -(4964, 2478, 1910) -(2442, 3436, 1755) -(4075, 731, 339) -(757, 3504, 255) -(2149, 667, 1558) -(3222, 4747, 1260) -(539, 1033, 466) -(3302, 4112, 1899) -(3906, 1607, 1307) -(872, 2350, 820) -(3894, 4906, 1590) -(3449, 484, 572) -(73, 1167, 661) -(1526, 3564, 326) -(1285, 2764, 727) -(2963, 4529, 1793) -(88, 2148, 1762) -(1186, 183, 168) -(3286, 4836, 683) -(2190, 3770, 661) -(4191, 184, 553) -(4940, 2270, 1178) -(1413, 508, 251) -(29, 660, 1405) -(578, 39, 1223) -(468, 2167, 1950) -(3053, 983, 187) -(1170, 739, 1850) -(2220, 1515, 510) -(2362, 56, 611) -(2803, 720, 1650) -(2975, 2320, 985) -(606, 489, 789) -(1255, 647, 1213) -(2779, 4678, 1829) -(1176, 2052, 1971) -(4200, 192, 1186) -(1240, 547, 134) -(2161, 4387, 437) -(54, 4935, 213) -(1153, 740, 1992) -(1324, 4715, 1994) -(2988, 1387, 692) -(4465, 4105, 728) -(3605, 2862, 533) -(2491, 343, 770) -(3614, 2962, 442) -(2934, 2381, 138) -(4314, 823, 213) -(913, 2862, 1324) -(545, 1008, 326) -(3407, 2285, 793) -(4021, 4226, 310) -(3064, 4954, 1369) -(1014, 3493, 306) -(903, 4345, 1935) -(2794, 3791, 1365) -(1053, 1418, 158) -(395, 1868, 1211) -(3945, 1899, 1020) -(3787, 2836, 1254) -(1028, 1099, 783) -(3785, 1778, 1752) -(4599, 3252, 468) -(389, 759, 592) -(487, 2872, 1070) -(3877, 1929, 1249) -(2480, 2439, 748) -(4640, 1226, 1687) -(2883, 4568, 1546) -(3722, 1224, 137) -(1751, 4090, 1004) -(4328, 866, 1308) -(2008, 4724, 972) -(1265, 4650, 1181) -(3763, 2183, 1391) -(715, 4041, 1997) -(4282, 2051, 611) -(2645, 2669, 1974) -(3091, 1070, 1663) -(374, 334, 446) -(3344, 1432, 1641) -(1694, 1235, 1078) -(4996, 1015, 579) -(4973, 3255, 1663) -(502, 2119, 1307) -(4064, 4842, 1658) -(4628, 4499, 1003) -(1536, 3300, 1351) -(2007, 4655, 725) -(1788, 4014, 1307) -(1589, 1676, 1508) -(2181, 2594, 996) -(1634, 1716, 685) -(2157, 2123, 54) -(911, 4188, 993) -(2633, 1613, 744) -(889, 2379, 374) -(3028, 4554, 479) -(914, 632, 464) -(2973, 3874, 351) -(4457, 444, 1937) -(3465, 4378, 1866) -(794, 557, 248) -(4799, 2840, 942) -(3958, 3176, 709) -(1402, 128, 144) -(4029, 878, 414) -(3300, 1536, 1351) -(4075, 1484, 1787) -(1752, 1883, 1711) -(1802, 770, 692) -(4469, 2393, 311) -(169, 1600, 1146) -(2217, 4468, 1868) -(690, 418, 1285) -(4339, 49, 1770) -(339, 2116, 1558) -(2354, 2477, 1220) -(2163, 2848, 1494) -(2901, 638, 648) -(4976, 2975, 471) -(4541, 4077, 1534) -(1018, 1808, 1138) -(748, 3927, 1685) -(2448, 3608, 1825) -(2054, 3025, 1192) -(1173, 696, 71) -(4112, 3302, 1899) -(3345, 2867, 57) -(3091, 4156, 187) -(573, 616, 409) -(2417, 3805, 952) -(1133, 3724, 787) -(2810, 3194, 1371) -(2871, 2997, 1968) -(146, 594, 1435) -(1840, 3561, 979) -(4738, 4598, 438) -(1856, 997, 1282) -(1780, 3081, 681) -(3963, 1701, 86) -(566, 935, 988) -(2087, 3880, 1286) -(4467, 3147, 452) -(895, 3466, 180) -(3944, 98, 1021) -(3305, 1268, 249) -(1646, 4990, 1883) -(573, 3198, 555) -(2030, 4505, 473) -(976, 872, 1245) -(1733, 50, 935) -(1522, 4871, 492) -(1774, 1146, 1443) -(809, 1174, 497) -(2492, 4846, 1450) -(2564, 35, 389) -(5, 4795, 904) -(1464, 1153, 1109) -(4906, 3894, 1590) -(836, 4692, 1352) -(34, 1118, 1488) -(1727, 3964, 658) -(2603, 4263, 951) -(635, 538, 646) -(4842, 3574, 1979) -(4964, 2547, 1262) -(1306, 4392, 1516) -(2984, 438, 1997) -(2971, 2024, 970) -(4092, 1468, 450) -(2095, 3872, 602) -(2717, 713, 1925) -(1778, 3785, 1752) -(4321, 1547, 522) -(1159, 2917, 774) -(3351, 4992, 135) -(2339, 2086, 138) -(448, 38, 1337) -(503, 123, 1668) -(1300, 4048, 600) -(1129, 4761, 1330) -(14, 3569, 971) -(3161, 2807, 686) -(2645, 3534, 492) -(4706, 647, 575) -(4712, 1859, 597) -(1255, 1205, 89) -(973, 1955, 246) -(605, 2740, 1178) -(3722, 3462, 1687) -(258, 4203, 240) -(3728, 4875, 314) -(3572, 1611, 953) -(3920, 2268, 333) -(4987, 4675, 1583) -(2206, 4531, 1241) -(4543, 1494, 706) -(4770, 578, 877) -(4248, 4513, 806) -(1637, 3873, 78) -(687, 2322, 1495) -(4390, 973, 199) -(2929, 3172, 635) -(287, 1884, 1576) -(3347, 3935, 1554) -(4420, 3974, 1804) -(2936, 412, 922) -(2112, 686, 607) -(2211, 3002, 108) -(1564, 3932, 1964) -(557, 794, 248) -(483, 1458, 121) -(4306, 4337, 509) -(2606, 2696, 1980) -(1203, 1240, 1694) -(167, 437, 1867) -(245, 3114, 705) -(1724, 1486, 1315) -(1975, 2144, 1773) -(2025, 4005, 1598) -(2594, 2181, 996) -(1546, 3407, 277) -(2742, 2125, 1939) -(387, 597, 453) -(3707, 1419, 380) -(3582, 315, 237) -(4390, 3369, 373) -(3182, 2258, 983) -(4097, 2998, 1891) -(2226, 2393, 173) -(4249, 991, 1368) -(4602, 970, 1435) -(3827, 1411, 62) -(1637, 972, 259) -(3143, 4817, 1451) -(4180, 65, 134) -(4406, 4624, 1672) -(6, 1054, 54) -(332, 1541, 956) -(2372, 406, 1820) -(2008, 3830, 1757) -(4836, 3608, 189) -(1534, 996, 1571) -(656, 1299, 209) -(1043, 1889, 998) -(1783, 423, 1880) -(662, 565, 1264) -(1044, 1014, 1216) -(3063, 3460, 382) -(2774, 1753, 1431) -(3759, 4941, 1422) -(3424, 3158, 230) -(2943, 1266, 341) -(1258, 1002, 762) -(730, 4087, 780) -(2920, 366, 551) -(4723, 3098, 1946) -(1890, 2927, 759) -(2593, 4945, 1861) -(4877, 1563, 406) -(3963, 4101, 944) -(2215, 2565, 1373) -(3056, 4442, 167) -(4951, 1082, 908) -(1063, 3132, 1796) -(3615, 4707, 1237) -(1885, 740, 1238) -(1101, 2915, 337) -(3645, 219, 1220) -(1617, 562, 1370) -(981, 4890, 272) -(1715, 4854, 1329) -(3284, 3893, 1723) -(4247, 4971, 492) -(2213, 1627, 1528) -(4770, 4311, 1975) -(209, 2997, 1531) -(2500, 2252, 635) -(4940, 4432, 1632) -(2144, 2430, 142) -(4887, 808, 1251) -(3860, 273, 757) -(1818, 4377, 1483) -(1613, 1333, 693) -(1165, 1729, 583) -(1255, 4093, 1076) -(4722, 3884, 1676) -(923, 3854, 1944) -(4093, 1747, 1611) -(3981, 751, 622) -(3575, 3528, 1220) -(620, 4546, 1217) -(4682, 978, 472) -(4444, 1557, 1538) -(1138, 3760, 1036) -(618, 1877, 945) -(919, 4751, 1391) -(3847, 138, 1397) -(859, 581, 1049) -(3631, 787, 1513) -(424, 580, 531) -(3449, 4544, 1652) -(3762, 2762, 718) -(910, 4267, 219) -(1230, 3292, 871) -(3718, 3050, 270) -(4035, 289, 328) -(3092, 217, 1920) -(2799, 3543, 617) -(4756, 1656, 1033) -(942, 433, 535) -(2930, 3998, 729) -(2723, 3978, 1203) -(4512, 4888, 1026) -(2146, 1889, 544) -(2621, 3137, 1749) -(47, 4572, 124) -(3381, 2025, 1226) -(1643, 122, 1985) -(2015, 4237, 1173) -(1747, 3427, 633) -(3748, 4543, 1071) -(2721, 2415, 1049) -(4902, 3676, 1109) -(4853, 1965, 1216) -(79, 3084, 1433) -(3149, 4545, 851) -(1478, 4969, 292) -(2467, 4093, 1026) -(1208, 4477, 1480) -(794, 762, 337) -(4389, 3874, 1665) -(3141, 4370, 1780) -(2155, 3766, 465) -(1467, 1383, 1587) -(166, 3645, 172) -(2605, 1308, 1504) -(2776, 920, 905) -(978, 2849, 140) -(4383, 1113, 530) -(4162, 3663, 172) -(366, 3028, 1050) -(4272, 2195, 1509) -(912, 2872, 1393) -(4406, 3729, 677) -(3239, 1983, 1995) -(257, 2697, 1074) -(3127, 2579, 314) -(1560, 1800, 1823) -(4770, 2633, 1775) -(1867, 4328, 1658) -(1644, 1370, 1056) -(340, 4767, 388) -(1691, 115, 1542) -(4624, 4406, 1672) -(1363, 598, 88) -(3075, 3401, 324) -(3977, 241, 1093) -(4762, 1457, 1009) -(4193, 573, 885) -(2166, 2588, 172) -(4698, 51, 908) -(2025, 121, 889) -(2341, 4771, 1811) -(2381, 2934, 138) -(2031, 2523, 344) -(4482, 1037, 409) -(2758, 3482, 441) -(104, 77, 1323) -(2228, 4415, 735) -(2945, 1325, 864) -(2306, 85, 510) -(963, 1613, 1531) -(3808, 2578, 608) -(384, 615, 899) -(4156, 3091, 187) -(1657, 2234, 484) -(3989, 799, 1388) -(3762, 4371, 1353) -(2319, 3331, 1713) -(2481, 2509, 749) -(4649, 4551, 1583) -(3294, 3497, 1124) -(2810, 3730, 476) -(4198, 1607, 654) -(2705, 1431, 376) -(1217, 2876, 1502) -(4639, 2599, 1074) -(4101, 3120, 229) -(2619, 2168, 1174) -(1313, 3598, 1023) -(4303, 2238, 1457) -(4225, 3131, 965) -(1321, 188, 1853) -(3010, 957, 145) -(597, 4072, 1510) -(1687, 873, 1879) -(1588, 2218, 1961) -(3379, 4002, 1254) -(2376, 4184, 1430) -(3927, 3360, 1818) -(2670, 2669, 1097) -(836, 2539, 1972) -(3556, 4386, 1681) -(1350, 1937, 1896) -(3667, 3723, 1610) -(303, 186, 1983) -(2482, 2880, 1226) -(260, 3367, 695) -(3625, 3387, 1098) -(1079, 4209, 1881) -(2349, 196, 958) -(3700, 577, 906) -(112, 667, 994) -(1063, 183, 406) -(543, 3276, 1198) -(3717, 2415, 123) -(4801, 358, 485) -(4505, 289, 1776) -(4914, 4696, 1713) -(4281, 4373, 1701) -(2230, 4769, 1860) -(2344, 2800, 1839) -(2573, 757, 1787) -(2449, 4185, 669) -(2905, 1181, 627) -(4998, 1831, 424) -(3386, 2644, 1323) -(2774, 4173, 1313) -(2262, 3318, 623) -(2859, 904, 163) -(3491, 2420, 424) -(2096, 2091, 502) -(3374, 2285, 96) -(2175, 783, 403) -(1, 3442, 1260) -(3743, 3348, 849) -(307, 3298, 1741) -(2158, 2106, 1431) -(4823, 4271, 115) -(1868, 395, 1211) -(1908, 1256, 462) -(1887, 3369, 1486) -(4382, 2279, 774) -(1279, 894, 1357) -(1123, 2975, 1218) -(1651, 4245, 929) -(3545, 1802, 972) -(1377, 4129, 328) -(1536, 1199, 1494) -(4651, 990, 1998) -(3511, 817, 1807) -(1763, 2368, 1113) -(4908, 1991, 354) -(2518, 2682, 630) -(1174, 809, 497) -(2144, 583, 359) -(3608, 4836, 189) -(1126, 3828, 182) -(1012, 316, 688) -(1473, 1830, 1197) -(1202, 220, 294) -(439, 1690, 730) -(707, 1364, 1361) -(2519, 3052, 1905) -(3595, 2255, 1108) -(2830, 1897, 1951) -(68, 500, 1782) -(3828, 3854, 263) -(2426, 3289, 1933) -(4259, 3653, 1324) -(2759, 2007, 1153) -(1388, 2133, 107) -(2109, 4703, 1425) -(4820, 2134, 1129) -(2476, 525, 139) -(466, 891, 1017) -(1167, 607, 906) -(3315, 206, 1907) -(4035, 1478, 1776) -(1027, 40, 1552) -(2935, 2517, 1024) -(2380, 113, 94) -(1212, 2368, 1033) -(4112, 2053, 922) -(3687, 4918, 253) -(4488, 3376, 214) -(3332, 2529, 670) -(3705, 4087, 1297) -(2483, 1607, 554) -(817, 1194, 124) -(2600, 2608, 825) -(946, 2092, 1489) -(1955, 3295, 1160) -(3208, 2213, 1217) -(2186, 1325, 424) -(2439, 2017, 334) -(4022, 368, 1418) -(1538, 343, 1425) -(3590, 148, 664) -(1244, 3892, 1124) -(144, 1845, 1525) -(3242, 3881, 923) -(460, 4331, 245) -(3332, 2008, 1653) -(2080, 600, 1747) -(674, 838, 765) -(807, 1558, 1815) -(2863, 4689, 1623) -(1194, 2665, 535) -(4947, 2605, 1987) -(487, 3566, 577) -(2797, 34, 223) -(2488, 958, 1597) -(3724, 1133, 787) -(4633, 2168, 1050) -(1522, 2514, 743) -(2326, 496, 949) -(2255, 522, 1416) -(784, 4961, 1739) -(3160, 3438, 239) -(3123, 2914, 644) -(1137, 3945, 520) -(2862, 2326, 1854) -(2049, 2633, 859) -(2843, 2917, 1228) -(2319, 3945, 980) -(561, 4870, 480) -(2885, 3287, 325) -(1515, 2220, 510) -(616, 4804, 639) -(4434, 1440, 1869) -(4762, 4187, 1352) -(3051, 296, 1139) -(2303, 3923, 1961) -(1421, 1700, 1869) -(4787, 4177, 1109) -(1381, 465, 556) -(2284, 528, 1575) -(3933, 4331, 71) -(2342, 3310, 1491) -(4061, 4481, 113) -(1326, 3407, 629) -(1814, 4605, 1288) -(2876, 3437, 616) -(662, 2332, 1241) -(3264, 2050, 660) -(3536, 2855, 169) -(3020, 1928, 1028) -(3940, 285, 1992) -(4300, 309, 843) -(1182, 3674, 1257) -(1644, 1485, 1870) -(189, 74, 1957) -(3822, 1318, 1670) -(2701, 15, 634) -(2471, 2712, 1461) -(3286, 4865, 503) -(2181, 4819, 179) -(1630, 1448, 1418) -(1651, 1449, 1142) -(2762, 3067, 1168) -(753, 268, 113) -(170, 4015, 1551) -(91, 2121, 985) -(511, 3392, 1674) -(4106, 868, 1850) -(1050, 4687, 170) -(728, 1662, 1178) -(4600, 1012, 293) -(2505, 2651, 429) -(3756, 3890, 1117) -(2721, 2683, 1963) -(1934, 2311, 288) -(1321, 4057, 1260) -(356, 4524, 1619) -(4479, 4356, 710) -(4747, 4410, 145) -(2563, 3860, 1432) -(3407, 2215, 1146) -(1607, 2483, 554) -(4062, 2910, 568) -(2652, 3981, 824) -(3117, 850, 1092) -(118, 4065, 1043) -(525, 1995, 1984) -(2170, 3564, 98) -(3124, 3323, 1961) -(153, 4545, 1602) -(1090, 423, 233) -(1858, 2967, 308) -(2569, 3643, 1836) -(2191, 1216, 1385) -(357, 1104, 245) -(275, 4989, 226) -(4936, 2332, 796) -(4516, 2961, 1029) -(882, 1521, 672) -(1841, 4659, 912) -(1218, 3, 1227) -(3042, 3884, 1598) -(2062, 3154, 950) -(2427, 584, 1169) -(3166, 1817, 1199) -(917, 4519, 1252) -(1387, 2988, 692) -(2440, 4207, 982) -(562, 3191, 629) -(3549, 4711, 1165) -(3945, 1166, 1697) -(1677, 3501, 317) -(1686, 4438, 833) -(3680, 665, 1965) -(663, 1547, 1662) -(2855, 2183, 1482) -(3886, 2701, 1590) -(3277, 2929, 1216) -(1889, 1043, 998) -(224, 2181, 1912) -(4974, 1317, 92) -(38, 3771, 1022) -(3269, 161, 1593) -(718, 3113, 317) -(2581, 2739, 1609) -(3432, 811, 1051) -(637, 859, 1431) -(2064, 582, 819) -(967, 1998, 1967) -(3147, 2993, 1686) -(415, 295, 1313) -(2976, 3983, 336) -(4306, 962, 135) -(2307, 1514, 1134) -(2662, 3914, 1329) -(989, 3690, 267) -(56, 2362, 611) -(1964, 4965, 1172) -(1208, 2702, 1429) -(4882, 1687, 1808) -(1992, 2631, 756) -(429, 2995, 171) -(1551, 3411, 1763) -(4678, 2577, 858) -(484, 4766, 677) -(2168, 4210, 1255) -(948, 4109, 1502) -(1936, 422, 1163) -(1110, 473, 1884) -(3060, 4652, 1912) -(788, 4217, 1998) -(4774, 1768, 1241) -(1760, 3086, 1197) -(964, 1359, 114) -(2233, 863, 1663) -(2779, 1531, 483) -(37, 595, 475) -(1681, 2370, 1668) -(1307, 391, 151) -(1776, 2185, 1385) -(844, 4580, 395) -(2384, 2549, 1627) -(219, 1334, 868) -(415, 3714, 1218) -(1782, 2226, 401) -(3012, 2303, 1111) -(4692, 1284, 1448) -(3584, 2465, 1994) -(4416, 1499, 1051) -(4762, 4859, 835) -(782, 885, 1709) -(874, 1799, 1864) -(3092, 34, 594) -(1459, 2154, 1908) -(2632, 2474, 1456) -(2480, 2999, 201) -(3700, 4839, 1449) -(239, 359, 925) -(1102, 3107, 1279) -(1667, 1681, 1124) -(729, 3241, 1175) -(2067, 2622, 1258) -(294, 3717, 1664) -(268, 1615, 1141) -(724, 4473, 496) -(645, 1468, 1084) -(296, 3180, 457) -(4811, 820, 203) -(937, 3336, 1330) -(2887, 24, 554) -(3211, 4630, 1805) -(646, 1707, 167) -(2401, 4901, 1733) -(3245, 1138, 198) -(4485, 2312, 369) -(868, 4451, 832) -(2438, 2966, 600) -(667, 4040, 879) -(2280, 3046, 1249) -(1071, 2764, 1382) -(2053, 3395, 458) -(3122, 3424, 1194) -(2781, 4613, 1600) -(4219, 1629, 429) -(1519, 3788, 1503) -(1171, 4648, 285) -(1233, 4435, 1179) -(2378, 2315, 1733) -(1271, 4543, 717) -(3864, 2076, 134) -(3474, 3480, 1325) -(1753, 3448, 1562) -(4409, 303, 1103) -(4042, 2387, 1668) -(2074, 2887, 1485) -(582, 4117, 746) -(4505, 2682, 1045) -(3539, 3266, 385) -(2933, 712, 1396) -(1739, 853, 810) -(4189, 3310, 887) -(3455, 3198, 143) -(3266, 465, 1369) -(3591, 4564, 1913) -(1377, 3032, 1989) -(2884, 700, 551) -(2711, 3376, 167) -(865, 4716, 1254) -(3118, 4517, 1852) -(2382, 3308, 1498) -(2208, 1561, 316) -(2698, 4368, 1694) -(1464, 1030, 1990) -(1738, 2547, 344) -(3581, 1022, 371) -(938, 3023, 1103) -(3135, 1988, 277) -(4888, 927, 1888) -(1914, 3396, 868) -(3507, 86, 876) -(3982, 2382, 197) -(681, 2898, 893) -(1170, 2003, 522) -(4244, 1167, 541) -(721, 2738, 794) -(4855, 83, 529) -(4435, 540, 543) -(826, 4113, 1344) -(3066, 3363, 169) -(1913, 3032, 1900) -(3217, 1800, 459) -(4631, 610, 694) -(2083, 245, 1747) -(4114, 2407, 621) -(4850, 2141, 1713) -(422, 1187, 777) -(359, 1200, 478) -(1524, 1222, 1389) -(899, 637, 554) -(2736, 3801, 1056) -(4973, 1609, 1874) -(2527, 3934, 517) -(1064, 4432, 146) -(2452, 3534, 489) -(797, 3673, 785) -(4396, 2402, 1649) -(4443, 2249, 697) -(195, 524, 1453) -(3919, 3031, 1691) -(676, 1165, 1808) -(2863, 3033, 803) -(4899, 3867, 146) -(4019, 209, 1122) -(2367, 910, 1864) -(1680, 3314, 1247) -(2050, 3264, 660) -(4923, 529, 1558) -(2942, 1785, 1090) -(1180, 4800, 226) -(3205, 1814, 109) -(2186, 155, 788) -(3005, 1028, 1048) -(166, 2650, 251) -(3562, 2243, 986) -(2326, 2862, 1854) -(4249, 4449, 153) -(2165, 4668, 875) -(4828, 658, 1079) -(2897, 3155, 395) -(726, 822, 475) -(3513, 4005, 481) -(144, 808, 1839) -(866, 3332, 1890) -(1992, 4586, 488) -(722, 3793, 1951) -(4911, 1953, 1249) -(2889, 370, 863) -(3647, 4374, 478) -(405, 1599, 176) -(1045, 4202, 1679) -(4138, 2849, 823) -(1925, 3387, 813) -(1519, 3396, 1300) -(1330, 1320, 245) -(425, 3991, 1843) -(2996, 3024, 783) -(1348, 4573, 179) -(4897, 3224, 1745) -(1502, 1786, 525) -(4601, 305, 1575) -(4018, 2169, 1598) -(4916, 1976, 135) -(4711, 3340, 149) -(4261, 1297, 1525) -(4201, 4412, 84) -(1483, 951, 259) -(4331, 4001, 968) -(2460, 4897, 1647) -(3770, 2097, 622) -(2382, 3982, 197) -(2415, 3717, 123) -(4213, 3469, 1647) -(428, 2886, 1929) -(248, 2622, 1767) -(3089, 3101, 742) -(3087, 574, 1076) -(4823, 638, 1469) -(4501, 4792, 1274) -(4984, 3713, 1071) -(1532, 1359, 1650) -(1912, 1128, 271) -(730, 2033, 67) -(70, 374, 1291) -(3283, 631, 989) -(847, 3887, 1188) -(3136, 4188, 436) -(108, 2879, 1295) -(3695, 3260, 1210) -(1101, 3607, 1591) -(4798, 821, 1308) -(3980, 481, 1429) -(2120, 2347, 567) -(871, 890, 1735) -(293, 1138, 716) -(3845, 4029, 98) -(4263, 3804, 1345) -(787, 2735, 1569) -(3192, 1471, 138) -(2503, 2321, 1549) -(2218, 891, 1551) -(4408, 3787, 1623) -(1365, 4615, 340) -(2596, 2657, 873) -(2369, 3521, 568) -(3289, 3068, 1273) -(2890, 4436, 1761) -(4846, 2492, 1450) -(1235, 114, 607) -(2571, 625, 834) -(2220, 1377, 1542) -(3543, 287, 714) -(3870, 3637, 1314) -(699, 1495, 1457) -(424, 3049, 1960) -(723, 1756, 704) -(1675, 410, 1094) -(1727, 1965, 1931) -(1431, 736, 773) -(1997, 4638, 1194) -(1802, 2848, 145) -(2268, 833, 547) -(2467, 3889, 1033) -(311, 4792, 1833) -(2914, 4101, 1987) -(4957, 2374, 1914) -(4248, 318, 884) -(1976, 2579, 815) -(2666, 3595, 1920) -(3701, 4928, 703) -(545, 4759, 380) -(1262, 3191, 217) -(208, 1764, 1262) -(4290, 1965, 863) -(1763, 3422, 1041) -(3616, 2097, 672) -(4998, 4523, 1375) -(4064, 3728, 581) -(315, 3582, 237) -(153, 101, 1044) -(2349, 2451, 1294) -(25, 4185, 1976) -(4623, 366, 136) -(1215, 1407, 1233) -(4821, 3160, 1341) -(2923, 301, 1423) -(3495, 3427, 178) -(2568, 4256, 768) -(4979, 3772, 523) -(3880, 2087, 1286) -(1229, 2941, 1418) -(705, 4119, 902) -(1803, 1832, 604) -(3700, 4287, 86) -(4664, 1356, 633) -(3695, 2816, 999) -(2386, 3442, 582) -(3067, 1318, 887) -(1363, 1637, 767) -(1201, 322, 1276) -(2871, 2286, 1762) -(1600, 3152, 363) -(2502, 3607, 1171) -(2961, 756, 1847) -(4830, 2917, 1512) -(2803, 1504, 1844) -(3448, 2109, 308) -(4818, 661, 568) -(2348, 4664, 1487) -(1093, 3069, 1949) -(2660, 1771, 1289) -(1303, 159, 877) -(4682, 1992, 224) -(2370, 78, 1184) -(4888, 2887, 852) -(1084, 2768, 564) -(2537, 201, 195) -(3774, 3924, 1602) -(3764, 499, 1040) -(2329, 2412, 1791) -(883, 1317, 1334) -(194, 4823, 1929) -(4543, 3748, 1071) -(4041, 715, 1997) -(478, 1855, 641) -(4612, 2422, 421) -(1220, 4034, 387) -(1168, 761, 682) -(236, 4005, 1791) -(1386, 1666, 1696) -(4728, 1269, 697) -(1452, 1383, 82) -(1493, 3096, 1119) -(1651, 1832, 720) -(241, 3977, 1093) -(4271, 2977, 757) -(619, 3175, 555) -(2748, 4669, 943) -(1419, 2293, 1320) -(191, 2118, 1426) -(231, 3634, 473) -(559, 767, 790) -(4535, 4364, 1688) -(2797, 2684, 1851) -(1600, 160, 168) -(1102, 463, 1344) -(4072, 3222, 1016) -(157, 4323, 86) -(3150, 1951, 1239) -(754, 2101, 355) -(1337, 2471, 1522) -(1123, 3204, 559) -(1580, 3254, 56) -(4281, 2153, 763) -(3185, 4905, 1226) -(2478, 2257, 1779) -(2491, 1710, 1725) -(3913, 2959, 1304) -(4623, 3380, 1148) -(2754, 3432, 765) -(297, 169, 345) -(3587, 126, 956) -(1065, 3481, 1633) -(973, 3790, 151) -(1211, 2602, 94) -(2871, 3058, 1376) -(913, 87, 498) -(3531, 2744, 1814) -(1194, 480, 934) -(1895, 3880, 1307) -(3575, 903, 1125) -(1127, 1410, 1128) -(2134, 3560, 715) -(3382, 281, 1593) -(2639, 1870, 150) -(1976, 210, 578) -(821, 1499, 568) -(2838, 1403, 147) -(741, 626, 590) -(2917, 2322, 733) -(1289, 2985, 1897) -(2091, 342, 1698) -(2855, 863, 603) -(1445, 145, 1632) -(2988, 2820, 1130) -(4021, 1418, 1364) -(4105, 4465, 728) -(4359, 4668, 1563) -(3684, 3017, 1771) -(3162, 4550, 1869) -(1437, 4666, 1174) -(1393, 977, 1187) -(236, 328, 468) -(4399, 3227, 1079) -(4902, 3277, 1448) -(1736, 1133, 1156) -(1395, 3539, 185) -(2768, 3753, 851) -(2843, 4249, 1590) -(3491, 2164, 1433) -(3716, 2683, 67) -(2222, 4934, 382) -(4324, 634, 257) -(747, 534, 1156) -(2020, 1561, 411) -(1984, 2591, 1082) -(2523, 4360, 799) -(4968, 3430, 385) -(3900, 1223, 1114) -(4942, 777, 1434) -(525, 437, 498) -(2620, 4538, 526) -(506, 2895, 1276) -(1316, 1660, 251) -(3635, 1318, 1613) -(254, 1763, 1733) -(510, 3913, 1719) -(163, 3250, 269) -(4972, 761, 217) -(4919, 1982, 1916) -(873, 1687, 1879) -(2906, 2398, 1634) -(1973, 3786, 364) -(1987, 1118, 1029) -(4428, 1355, 945) -(115, 2464, 339) -(4294, 2892, 587) -(4834, 4142, 274) -(4631, 4918, 1121) -(49, 2034, 408) -(1935, 188, 1059) -(2783, 3005, 1823) -(4249, 1937, 156) -(2397, 3793, 1756) -(102, 1812, 606) -(1690, 439, 730) -(381, 9, 1889) -(2575, 823, 731) -(3291, 1638, 189) -(3895, 642, 566) -(974, 2803, 1582) -(4747, 3642, 1695) -(2318, 1722, 82) -(2863, 2006, 129) -(3074, 1324, 960) -(2615, 4863, 1790) -(991, 4249, 1368) -(1907, 512, 418) -(587, 1231, 1359) -(2390, 2113, 1583) -(996, 512, 1082) -(148, 1905, 1231) -(3131, 4189, 537) -(2029, 1005, 1989) -(3594, 902, 797) -(832, 4525, 1138) -(4705, 2353, 269) -(3562, 2578, 1121) -(2800, 4886, 1508) -(2546, 742, 1738) -(498, 9, 1657) -(1174, 3718, 1325) -(1799, 4566, 350) -(3243, 3737, 779) -(4245, 1651, 929) -(4460, 3093, 1716) -(4944, 1702, 1280) -(2041, 1872, 1010) -(2718, 1109, 1762) -(4023, 1276, 1565) -(97, 1805, 422) -(2946, 4949, 1765) -(4048, 1544, 819) -(783, 2175, 403) -(1935, 1962, 1016) -(1933, 2645, 1868) -(1478, 4035, 1776) -(2631, 4656, 1803) -(1858, 1433, 1251) -(1046, 44, 1281) -(973, 2037, 1795) -(2213, 3208, 1217) -(2747, 2496, 671) -(986, 4367, 1260) -(4129, 4984, 1827) -(1806, 1056, 132) -(4648, 2925, 1394) -(4725, 1077, 1550) -(4440, 4711, 501) -(1767, 1809, 742) -(590, 2118, 1491) -(2760, 521, 863) -(2549, 2384, 1627) -(4500, 3113, 1510) -(3853, 1264, 1731) -(3131, 4062, 831) -(809, 4156, 597) -(1599, 1759, 913) -(1069, 448, 1554) -(1134, 816, 768) -(2194, 4183, 1575) -(3026, 2656, 1094) -(4791, 4301, 1689) -(1927, 4917, 364) -(11, 1060, 1895) -(3139, 3379, 130) -(1605, 2946, 1759) -(962, 4306, 135) -(1681, 4299, 830) -(3496, 110, 419) -(3325, 673, 823) -(4846, 1377, 1870) -(2187, 219, 1062) -(4806, 4732, 976) -(1444, 1035, 1343) -(2792, 2532, 186) -(4567, 4804, 1769) -(2348, 2370, 1695) -(4044, 1826, 522) -(869, 4824, 153) -(2678, 4077, 1386) -(4931, 3727, 931) -(2243, 4121, 1040) -(2929, 2621, 1114) -(4367, 2433, 585) -(4297, 3421, 510) -(3479, 3554, 210) -(3781, 271, 1603) -(4827, 1509, 1140) -(3377, 2733, 966) -(2915, 2682, 55) -(3729, 1108, 978) -(1725, 1636, 613) -(4522, 2761, 367) -(2465, 319, 141) -(4565, 3070, 1819) -(122, 2894, 938) -(3004, 2455, 106) -(3174, 232, 1199) -(140, 2491, 104) -(4725, 4105, 1891) -(2398, 1187, 749) -(2238, 468, 1066) -(2699, 34, 1021) -(4206, 845, 1191) -(4982, 3310, 1224) -(3838, 3018, 1006) -(1067, 4422, 160) -(83, 2002, 359) -(1117, 1944, 387) -(4293, 4763, 510) -(1494, 4907, 872) -(81, 2992, 1040) -(3505, 4078, 1307) -(4125, 3141, 739) -(1687, 3279, 1312) -(2294, 1123, 104) -(4669, 2748, 943) -(2336, 2072, 1459) -(767, 2888, 263) -(3240, 1415, 771) -(3971, 2445, 1723) -(4846, 4580, 1647) -(3301, 332, 1467) -(4628, 4692, 765) -(4370, 4548, 252) -(1869, 1445, 1335) -(1053, 1569, 1796) -(2754, 1709, 185) -(2451, 2349, 1294) -(2735, 1720, 871) -(4793, 2856, 347) -(4376, 832, 657) -(2027, 4019, 1187) -(3729, 2121, 338) -(453, 2025, 1589) -(1129, 1312, 1969) -(2249, 4443, 697) -(2327, 1200, 1084) -(3083, 4734, 375) -(3223, 2730, 1602) -(3555, 2410, 1721) -(2558, 1186, 1165) -(1518, 966, 1904) -(1605, 2254, 260) -(1050, 4215, 1468) -(1324, 607, 1854) -(3617, 1811, 1543) -(514, 1809, 1317) -(2374, 4685, 1218) -(1839, 4675, 681) -(4914, 2239, 748) -(252, 3921, 1504) -(449, 875, 157) -(4975, 2586, 1141) -(3590, 3630, 1885) -(3240, 2638, 826) -(262, 2314, 1267) -(314, 2331, 618) -(902, 2152, 1864) -(231, 4577, 1885) -(2767, 2563, 295) -(3561, 1791, 1179) -(3099, 4793, 1224) -(448, 1069, 1554) -(2177, 3985, 1556) -(2653, 960, 1768) -(4339, 2629, 495) -(350, 4988, 1086) -(2131, 4098, 775) -(2334, 3914, 685) -(634, 4324, 257) -(4402, 3657, 324) -(2278, 2779, 1716) -(2998, 4097, 1891) -(3943, 3005, 1115) -(4325, 2370, 1852) -(3338, 2372, 736) -(3136, 3969, 617) -(3558, 4740, 1818) -(1750, 4546, 294) -(907, 3883, 149) -(4651, 2782, 425) -(4666, 3674, 323) -(573, 3124, 1161) -(4986, 1059, 1056) -(181, 1348, 122) -(3141, 3320, 125) -(1504, 3761, 1325) -(2051, 1705, 160) -(361, 3646, 1653) -(1724, 1843, 1524) -(3864, 2049, 1366) -(43, 1069, 133) -(2881, 4894, 1499) -(1908, 16, 988) -(4361, 4232, 255) -(4382, 3565, 535) -(1678, 1142, 660) -(4544, 4816, 1251) -(2715, 3607, 1553) -(1836, 3535, 231) -(686, 226, 1476) -(680, 2503, 1929) -(4334, 254, 262) -(2021, 4454, 624) -(866, 4328, 1308) -(4514, 2261, 1564) -(2445, 4220, 703) -(672, 2930, 1430) -(3200, 3468, 399) -(109, 1969, 1762) -(4872, 4246, 353) -(535, 3381, 717) -(1920, 297, 428) -(1763, 2791, 1438) -(3573, 2055, 1687) -(3645, 3482, 1684) -(512, 34, 1590) -(3125, 487, 1280) -(2147, 1295, 903) -(4038, 3975, 1318) -(1681, 1116, 920) -(3474, 4656, 1181) -(4897, 2460, 1647) -(145, 4480, 819) -(2170, 4702, 1616) -(1301, 3509, 1413) -(3051, 2429, 1188) -(142, 780, 1224) -(3319, 992, 1059) -(2472, 1842, 1484) -(78, 2370, 1184) -(1491, 3181, 669) -(3046, 2759, 203) -(4527, 83, 457) -(3514, 3282, 1912) -(579, 155, 416) -(2707, 1054, 428) -(3230, 4966, 751) -(3593, 3055, 60) -(2516, 2167, 1314) -(418, 4286, 349) -(4957, 3954, 1146) -(782, 1648, 1180) -(3927, 1034, 1703) -(4074, 1994, 137) -(1574, 3041, 51) -(3095, 2942, 816) -(2140, 1706, 1037) -(982, 2771, 260) -(4781, 2481, 1670) -(1415, 331, 1098) -(4556, 2916, 935) -(884, 4873, 1301) -(2579, 462, 1111) -(2780, 2683, 99) -(1070, 1332, 1587) -(3417, 2978, 1834) -(3466, 4374, 581) -(2826, 3587, 1970) -(2878, 4744, 1851) -(992, 3319, 1059) -(3243, 4301, 269) -(4578, 3600, 1710) -(2595, 194, 961) -(983, 3053, 187) -(4668, 3741, 903) -(1333, 2460, 1262) -(293, 1831, 1862) -(3196, 504, 546) -(2642, 2567, 1183) -(4470, 3803, 804) -(353, 488, 547) -(2602, 4974, 1044) -(189, 66, 1297) -(4803, 4979, 1711) -(4515, 1894, 95) -(664, 4684, 1548) -(1740, 2665, 448) -(4600, 1346, 1855) -(2335, 4540, 200) -(3858, 3904, 1185) -(4520, 4632, 1206) -(2659, 2572, 456) -(2882, 3929, 1329) -(3626, 720, 1705) -(910, 3641, 1823) -(4332, 2169, 1611) -(3682, 2228, 1346) -(1771, 4182, 139) -(443, 4496, 867) -(3362, 2102, 615) -(3742, 2696, 1736) -(976, 110, 549) -(2171, 4276, 1429) -(2325, 4908, 191) -(1432, 4544, 265) -(67, 868, 1191) -(4393, 2892, 1931) -(2564, 1344, 1459) -(2354, 2573, 710) -(4468, 44, 672) -(1842, 3043, 640) -(3524, 2374, 1308) -(4375, 4024, 950) -(3630, 3590, 1885) -(3464, 4351, 1700) -(4526, 3667, 383) -(3893, 4228, 1048) -(4257, 4595, 1957) -(3083, 2761, 183) -(802, 1100, 1542) -(719, 3017, 1978) -(1951, 3732, 185) -(2402, 600, 692) -(384, 3933, 142) -(825, 3689, 346) -(2089, 4282, 157) -(437, 4180, 1667) -(799, 2256, 173) -(3056, 709, 365) -(1817, 1629, 1513) -(3993, 2258, 1322) -(1659, 1583, 510) -(1766, 1985, 190) -(915, 1156, 704) -(2418, 3496, 217) -(1715, 5, 257) -(4786, 2055, 735) -(4289, 2789, 335) -(4034, 4077, 1907) -(1797, 3151, 1949) -(3499, 2350, 965) -(390, 2998, 545) -(3651, 327, 791) -(2674, 2522, 887) -(2377, 4856, 1776) -(3982, 989, 1605) -(968, 3132, 999) -(1091, 856, 1111) -(1128, 1912, 271) -(1377, 3958, 1251) -(3310, 496, 940) -(1613, 963, 1531) -(2614, 443, 1203) -(4374, 1265, 467) -(4141, 67, 67) -(1920, 3506, 995) -(2645, 1933, 1868) -(1167, 4244, 541) -(1417, 3312, 464) -(2342, 2306, 1766) -(3749, 1211, 884) -(3853, 4425, 325) -(3588, 1279, 562) -(113, 4123, 1000) -(2543, 1310, 1508) -(1870, 160, 1822) -(3087, 629, 60) -(3742, 1888, 222) -(1450, 3536, 302) -(4268, 3751, 431) -(2903, 4688, 318) -(4859, 4762, 835) -(3406, 520, 1224) -(4185, 25, 1976) -(2085, 1945, 1539) -(4555, 1761, 209) -(2925, 4648, 1394) -(534, 710, 346) -(3638, 1342, 1020) -(2079, 1185, 1098) -(806, 3343, 1610) -(4367, 986, 1260) -(359, 239, 925) -(327, 1023, 654) -(2634, 3998, 1552) -(2409, 3713, 721) -(4914, 1359, 202) -(746, 4848, 275) -(2222, 2169, 1252) -(1335, 4680, 894) -(3607, 1614, 1980) -(3499, 4982, 1602) -(1154, 4164, 1915) -(4608, 715, 248) -(3594, 3573, 426) -(410, 939, 1363) -(1701, 3963, 86) -(669, 2370, 1596) -(4890, 107, 629) -(652, 2494, 807) -(4871, 4995, 1593) -(16, 4069, 1531) -(2435, 4941, 1909) -(1334, 219, 868) -(1688, 1900, 710) -(3968, 2925, 698) -(2883, 3659, 136) -(4600, 1391, 1839) -(2790, 3587, 316) -(927, 2107, 159) -(2076, 513, 1817) -(3039, 3927, 1117) -(2324, 4307, 610) -(2735, 2931, 784) -(2191, 3492, 1843) -(859, 1602, 1663) -(91, 896, 1632) -(3858, 3808, 220) -(2058, 683, 531) -(140, 4846, 1331) -(227, 255, 1615) -(4446, 4934, 375) -(4779, 2283, 173) -(2885, 2002, 1248) -(3080, 4801, 1996) -(3530, 2329, 1779) -(1237, 1357, 1822) -(2616, 2361, 1868) -(271, 317, 168) -(2217, 1662, 809) -(248, 306, 921) -(2674, 4415, 55) -(4608, 1598, 126) -(2417, 2607, 1385) -(1663, 3726, 67) -(1901, 1341, 1384) -(2245, 2500, 1834) -(4615, 1365, 340) -(362, 2834, 676) -(3732, 1951, 185) -(2585, 4979, 1976) -(4601, 1977, 1527) -(674, 3479, 1900) -(2978, 3510, 260) -(478, 1117, 1444) -(4835, 1159, 421) -(3359, 4466, 164) -(963, 4186, 1411) -(4523, 3654, 1164) -(519, 1289, 1090) -(697, 3946, 1273) -(3447, 4979, 1452) -(1867, 849, 249) -(4652, 3905, 1327) -(4477, 2963, 1781) -(1863, 3308, 384) -(4636, 362, 357) -(4719, 4350, 1633) -(2500, 3880, 1422) -(1308, 3913, 1788) -(249, 4884, 1485) -(2172, 2525, 1483) -(3403, 1025, 1638) -(1354, 2075, 395) -(2230, 3741, 1607) -(2614, 3836, 1503) -(4658, 2826, 1281) -(2081, 3326, 79) -(2936, 1642, 585) -(3788, 3016, 780) -(1789, 1265, 604) -(4897, 995, 1901) -(4947, 3356, 1935) -(2215, 3407, 1146) -(600, 81, 1374) -(1211, 2799, 409) -(2091, 4642, 82) -(2071, 2174, 1555) -(1763, 254, 1733) -(3644, 4584, 794) -(2814, 4811, 446) -(1985, 1766, 190) -(1390, 4528, 1445) -(4381, 1187, 500) -(3285, 2758, 1966) -(3610, 2191, 1120) -(3250, 1174, 1432) -(1545, 3057, 1623) -(849, 2057, 1967) -(3465, 1396, 1927) -(3375, 3289, 255) -(3047, 1100, 426) -(2683, 2780, 99) -(2505, 4968, 140) -(345, 4179, 1085) -(3201, 142, 155) -(68, 461, 294) -(3937, 2152, 251) -(4078, 986, 1855) -(2741, 4773, 1514) -(4505, 852, 825) -(4269, 2003, 1400) -(4128, 3881, 835) -(2865, 3021, 603) -(2331, 1961, 1214) -(2037, 3024, 1219) -(4788, 1957, 53) -(2427, 2388, 1514) -(3374, 4405, 1049) -(3900, 2763, 677) -(1113, 2280, 348) -(3735, 4182, 1605) -(3980, 2564, 1412) -(3946, 2073, 307) -(595, 37, 475) -(1579, 2935, 89) -(179, 4002, 193) -(1134, 1018, 1343) -(2079, 1816, 198) -(4015, 170, 1551) -(2789, 4289, 335) -(2723, 3984, 809) -(908, 2218, 1003) -(943, 4111, 497) -(3781, 3945, 52) -(436, 4023, 321) -(707, 972, 202) -(3150, 2768, 1274) -(3050, 1425, 1088) -(2575, 2356, 1798) -(321, 2334, 843) -(1739, 2537, 1963) -(4614, 1567, 659) -(629, 3427, 557) -(4804, 141, 375) -(4970, 3733, 1038) -(2415, 3037, 884) -(3803, 1886, 414) -(1211, 3749, 884) -(3349, 1254, 1310) -(4776, 1894, 304) -(3489, 4939, 635) -(1514, 2307, 1134) -(440, 3213, 1412) -(1325, 2945, 864) -(606, 1409, 866) -(4649, 2691, 131) -(1824, 1290, 1125) -(4971, 1285, 1910) -(3708, 4029, 305) -(3069, 937, 1364) -(3132, 1664, 1923) -(2961, 2466, 506) -(1082, 2119, 182) -(3806, 1946, 570) -(2735, 2408, 1223) -(3478, 1413, 994) -(4683, 2510, 1328) -(510, 1288, 65) -(555, 2770, 1101) -(741, 3987, 484) -(3737, 1078, 492) -(1014, 1601, 1167) -(4852, 3227, 1245) -(4093, 4667, 1027) -(4760, 2269, 969) -(1660, 2366, 1792) -(3194, 360, 119) -(4530, 2191, 539) -(943, 4675, 805) -(2350, 1849, 84) -(3913, 1647, 523) -(4568, 1685, 806) -(2877, 1708, 186) -(872, 2896, 159) -(1774, 2906, 680) -(2018, 1228, 789) -(4485, 865, 1059) -(3901, 4868, 1989) -(416, 892, 1649) -(2204, 1158, 1748) -(3657, 3084, 1180) -(863, 3575, 1965) -(4981, 4654, 1833) -(116, 1625, 1580) -(444, 1361, 1823) -(1921, 249, 147) -(3401, 3303, 360) -(1131, 2757, 1045) -(4226, 3231, 1871) -(4242, 2939, 445) -(736, 4020, 571) -(4761, 4459, 1380) -(1140, 993, 1349) -(1854, 1917, 499) -(2617, 4327, 963) -(4270, 3404, 1489) -(1358, 4943, 422) -(3330, 1849, 897) -(1082, 3786, 364) -(443, 2642, 1829) -(501, 2833, 1874) -(1407, 1205, 1228) -(1551, 4912, 1834) -(3459, 1915, 1970) -(4751, 919, 1391) -(3581, 2342, 1551) -(2639, 3351, 426) -(1359, 2626, 1149) -(3351, 1279, 684) -(174, 580, 67) -(4169, 1320, 446) -(2285, 3407, 793) -(4681, 4553, 438) -(2500, 2811, 842) -(1674, 3335, 106) -(3490, 2902, 469) -(2359, 4684, 211) -(1605, 3098, 256) -(4419, 4576, 1350) -(197, 1790, 568) -(2679, 3258, 107) -(2069, 2043, 458) -(718, 3396, 261) -(1842, 2472, 1484) -(3005, 2783, 1823) -(290, 4235, 1397) -(875, 2115, 1481) -(3036, 3894, 191) -(4605, 1814, 1288) -(1898, 4597, 935) -(4771, 4265, 843) -(4984, 685, 1177) -(4513, 4265, 375) -(4431, 114, 1935) -(2827, 169, 1130) -(1001, 4376, 1884) -(2223, 2561, 1720) -(2082, 3703, 1267) -(2285, 514, 808) -(298, 1217, 1182) -(2705, 1602, 149) -(120, 371, 129) -(2279, 4123, 1569) -(2897, 128, 1762) -(1160, 32, 1444) -(3301, 1970, 155) -(2529, 3332, 670) -(1385, 1207, 1128) -(161, 4530, 55) -(4873, 2782, 1270) -(2998, 390, 545) -(2131, 1406, 648) -(4963, 666, 551) -(4800, 1180, 226) -(2057, 2150, 382) -(3699, 4939, 1910) -(4171, 4102, 1055) -(1850, 4239, 629) -(4313, 1117, 563) -(2643, 2217, 66) -(4132, 1535, 352) -(512, 846, 1929) -(486, 897, 1074) -(994, 3234, 1477) -(4862, 691, 577) -(4860, 3169, 450) -(2404, 246, 1141) -(4600, 2263, 1698) -(81, 3974, 956) -(744, 2639, 991) -(325, 414, 879) -(3171, 2882, 791) -(2893, 424, 132) -(4661, 3541, 959) -(3527, 2675, 1834) -(2935, 1579, 89) -(1100, 3047, 426) -(89, 3731, 1511) -(1759, 2640, 1971) -(1211, 842, 657) -(3833, 3212, 293) -(804, 1552, 532) -(3918, 2380, 1545) -(3878, 4706, 491) -(4523, 948, 621) -(4509, 2477, 1684) -(2091, 789, 1452) -(2788, 3871, 360) -(2939, 773, 1385) -(524, 195, 1453) -(2895, 519, 1643) -(113, 4178, 545) -(4399, 4278, 313) -(842, 769, 788) -(2666, 1134, 270) -(2990, 2814, 1262) -(884, 2453, 577) -(2860, 999, 1782) -(4408, 2260, 532) -(1034, 3052, 428) -(770, 4724, 1995) -(598, 1363, 88) -(3770, 2119, 929) -(4631, 4105, 1127) -(688, 1568, 827) -(3292, 2318, 676) -(1661, 2340, 1588) -(2635, 4985, 647) -(860, 4499, 1427) -(3928, 1258, 1307) -(223, 650, 1930) -(2494, 652, 807) -(1686, 2359, 1741) -(378, 3937, 1761) -(2565, 1579, 828) -(2016, 153, 68) -(3924, 642, 1136) -(1027, 394, 940) -(444, 4457, 1937) -(2250, 4566, 1673) -(4361, 2847, 1956) -(2326, 3753, 1539) -(1737, 209, 1042) -(4135, 2794, 406) -(3572, 3656, 1743) -(4952, 4150, 1717) -(615, 2269, 787) -(2651, 3932, 1645) -(3548, 3526, 922) -(1660, 3159, 1549) -(3002, 2543, 61) -(274, 3758, 55) -(4044, 1036, 606) -(4421, 1317, 389) -(2, 3627, 1326) -(1082, 3869, 1015) -(1562, 2659, 1881) -(2833, 3924, 194) -(3881, 3242, 923) -(1569, 2309, 1519) -(3510, 2978, 260) -(333, 3069, 1949) -(4874, 2049, 1604) -(3993, 1301, 515) -(532, 3506, 499) -(2390, 1130, 201) -(4716, 4087, 1889) -(3838, 4461, 1001) -(2575, 3479, 1762) -(4390, 2819, 1243) -(2611, 3356, 1382) -(312, 1035, 1953) -(2101, 1963, 742) -(4406, 4278, 881) -(1197, 2304, 588) -(505, 4854, 657) -(3941, 4135, 1999) -(1824, 1133, 327) -(4289, 4712, 734) -(4803, 2359, 601) -(4625, 4899, 498) -(952, 108, 155) -(461, 3262, 177) -(2619, 740, 525) -(2968, 2027, 1504) -(77, 693, 456) -(2545, 4036, 1794) -(642, 3924, 1136) -(1616, 2118, 1463) -(2061, 364, 300) -(3123, 337, 887) -(2998, 4023, 851) -(2640, 1215, 1685) -(1866, 2599, 614) -(1282, 776, 80) -(4865, 4400, 1936) -(4665, 3155, 1939) -(4118, 209, 413) -(169, 151, 1388) -(3124, 573, 1161) -(351, 187, 683) -(410, 1675, 1094) -(68, 4003, 1390) -(3607, 4859, 1165) -(2543, 3410, 279) -(4712, 4289, 734) -(4057, 1321, 1260) -(3586, 2129, 1009) -(228, 2886, 1466) -(4230, 2793, 729) -(2493, 1906, 1644) -(217, 3908, 1852) -(3336, 3404, 393) -(4993, 1197, 460) -(887, 2262, 1688) -(4709, 1127, 1187) -(3191, 1096, 749) -(4280, 2330, 256) -(4439, 4162, 1449) -(2945, 4833, 1412) -(2644, 1533, 1987) -(4775, 4211, 1688) -(1270, 713, 1071) -(4362, 3540, 456) -(752, 2577, 1698) -(2577, 752, 1698) -(3976, 3216, 89) -(211, 3103, 370) -(902, 4462, 403) -(2789, 2814, 200) -(861, 924, 1327) -(2626, 947, 366) -(2955, 2763, 1686) -(3246, 3006, 479) -(1465, 4261, 411) -(2893, 3663, 308) -(3015, 1287, 1577) -(230, 2683, 1582) -(3500, 4980, 1575) -(1134, 2095, 133) -(4440, 3266, 856) -(1036, 3851, 615) -(2168, 3852, 682) -(484, 4885, 1343) -(1655, 2459, 1248) -(2599, 4639, 1074) -(2519, 325, 942) -(1410, 668, 1633) -(4972, 3168, 1214) -(2326, 2011, 614) -(2956, 3354, 644) -(2606, 3214, 1224) -(3561, 1840, 979) -(862, 2237, 1666) -(1830, 1780, 1031) -(212, 1660, 519) -(710, 77, 1428) -(82, 3512, 1603) -(2082, 2287, 787) -(2392, 1613, 1037) -(1125, 1359, 1167) -(795, 3177, 1650) -(2263, 4600, 1698) -(4504, 347, 841) -(1469, 272, 1253) -(4178, 1000, 658) -(1148, 1029, 643) -(3520, 3041, 1119) -(4321, 3107, 344) -(1727, 3302, 1704) -(661, 4416, 350) -(1996, 1543, 1171) -(4376, 1008, 762) -(3490, 61, 913) -(2594, 3425, 355) -(4434, 1882, 329) -(1444, 4762, 1529) -(1534, 4970, 1000) -(4647, 586, 1175) -(1038, 686, 1074) -(1650, 4030, 1220) -(1166, 2231, 1210) -(3207, 1321, 1279) -(3129, 3900, 991) -(637, 4233, 639) -(3220, 4717, 1452) -(147, 1759, 308) -(278, 1513, 1696) -(2307, 2892, 172) -(2951, 3840, 1078) -(1123, 2294, 104) -(2344, 3180, 1367) -(2983, 3734, 633) -(3014, 1537, 1783) -(3747, 4897, 364) -(3172, 2929, 635) -(3754, 1324, 681) -(2961, 3775, 1228) -(1908, 733, 701) -(2422, 4612, 421) -(3347, 4962, 1596) -(1552, 2293, 1416) -(2384, 839, 1579) -(2998, 4102, 834) -(383, 520, 1879) -(4036, 2146, 191) -(4577, 4299, 1462) -(3444, 3409, 1846) -(1183, 1761, 1212) -(3109, 800, 156) -(3980, 3004, 1172) -(4453, 2285, 1176) -(127, 4602, 431) -(1203, 696, 1490) -(2931, 2735, 784) -(4739, 1202, 1798) -(4164, 1404, 303) -(3297, 1065, 523) -(332, 2154, 1445) -(1915, 4009, 1565) -(3804, 4263, 1345) -(4855, 4083, 1159) -(3250, 163, 269) -(3095, 1293, 1719) -(1149, 1597, 1540) -(2309, 121, 713) -(1387, 3944, 397) -(4795, 2895, 1334) -(452, 3680, 1612) -(129, 996, 1407) -(383, 3153, 1034) -(2194, 4359, 1435) -(2621, 68, 168) -(1613, 499, 1803) -(13, 3454, 1714) -(3317, 1964, 1652) -(4666, 4396, 1816) -(1541, 3055, 144) -(2884, 2877, 1433) -(3610, 4760, 259) -(1362, 2105, 572) -(4550, 966, 1698) -(2903, 1451, 1802) -(2975, 2030, 1798) -(1651, 177, 1378) -(2120, 3370, 806) -(361, 1564, 1576) -(2850, 3924, 1141) -(2643, 3081, 497) -(2497, 2856, 1947) -(4784, 2362, 1850) -(1034, 3927, 1703) -(2017, 4551, 728) -(3793, 405, 1441) -(4462, 1833, 641) -(4921, 419, 841) -(2967, 183, 369) -(1474, 188, 1604) -(2636, 1461, 1263) -(4982, 884, 688) -(4934, 2503, 562) -(3046, 2280, 1249) -(481, 2412, 1969) -(1434, 3208, 944) -(1021, 4169, 1602) -(4319, 3697, 1686) -(2287, 2300, 713) -(895, 3300, 450) -(3931, 739, 1537) -(1335, 1504, 292) -(2440, 3976, 133) -(3447, 1996, 309) -(3761, 303, 630) -(4729, 2562, 1380) -(3833, 4161, 1185) -(924, 101, 1289) -(670, 513, 642) -(3322, 4950, 1795) -(4812, 2126, 1989) -(2745, 1412, 1739) -(3878, 3204, 579) -(2633, 4770, 1775) -(1920, 4558, 136) -(3569, 14, 971) -(1262, 902, 659) -(455, 1285, 1553) -(3658, 1752, 1130) -(767, 621, 1352) -(468, 2364, 719) -(3546, 1419, 1305) -(2765, 1694, 643) -(1812, 2159, 1221) -(4526, 2967, 1980) -(4525, 832, 1138) -(1984, 1180, 765) -(2258, 352, 1186) -(1946, 3829, 356) -(1458, 483, 121) -(2162, 4460, 1603) -(2320, 2975, 985) -(2086, 3014, 505) -(3977, 584, 1988) -(718, 2814, 497) -(951, 110, 106) -(3715, 3253, 88) -(2091, 256, 1100) -(2748, 4923, 1971) -(2176, 4811, 185) -(2474, 782, 74) -(112, 3989, 1649) -(1865, 1987, 1719) -(2924, 1168, 1209) -(1870, 3907, 1506) -(1788, 3105, 1115) -(3330, 293, 953) -(3169, 267, 590) -(846, 4119, 523) -(2578, 3562, 1121) -(141, 598, 1210) -(3138, 3560, 1361) -(4071, 2266, 835) -(2526, 2836, 496) -(3056, 2947, 861) -(1065, 2729, 1384) -(3689, 893, 446) -(4183, 1443, 1693) -(878, 800, 412) -(2935, 4001, 356) -(1396, 3365, 1949) -(2934, 951, 760) -(2441, 51, 288) -(4350, 2380, 470) -(3320, 1427, 1265) -(3550, 954, 230) -(1824, 655, 1528) -(2154, 1459, 1908) -(49, 4938, 736) -(2110, 4073, 744) -(2201, 3987, 515) -(3453, 149, 502) -(52, 4971, 746) -(24, 1640, 1995) -(4414, 1209, 1878) -(983, 512, 737) -(871, 2346, 1887) -(4108, 1530, 1837) -(2649, 4354, 942) -(1768, 1254, 1910) -(2285, 4821, 1838) -(1685, 4568, 806) -(2721, 2960, 1063) -(4602, 1528, 495) -(487, 3118, 874) -(3974, 2834, 1706) -(395, 3716, 1210) -(780, 142, 1224) -(1751, 4412, 94) -(1225, 2805, 901) -(4360, 1211, 623) -(3841, 3259, 321) -(1773, 4371, 917) -(3501, 3772, 1527) -(2832, 4720, 452) -(4490, 1851, 1040) -(1160, 4863, 538) -(3823, 2264, 740) -(1291, 271, 170) -(1628, 1837, 1727) -(3032, 469, 1270) -(2250, 2038, 901) -(3808, 4829, 244) -(3530, 3420, 1302) -(2858, 9, 1877) -(934, 1838, 699) -(1359, 251, 1491) -(1397, 308, 122) -(1091, 1265, 1918) -(4252, 3857, 470) -(2607, 1762, 1363) -(4749, 4836, 1316) -(1766, 582, 921) -(2022, 4672, 1923) -(4371, 2693, 1823) -(1109, 3077, 646) -(3234, 2031, 320) -(1313, 1055, 829) -(1641, 405, 573) -(2337, 3743, 1738) -(948, 1773, 676) -(305, 1573, 892) -(3131, 2593, 1876) -(3911, 2080, 154) -(592, 703, 1950) -(384, 916, 1156) -(1929, 3106, 379) -(789, 2594, 406) -(1899, 764, 97) -(3958, 2245, 155) -(4609, 2794, 1238) -(3815, 816, 933) -(1796, 1302, 1740) -(3418, 3114, 734) -(4893, 238, 1847) -(2547, 599, 546) -(4622, 2792, 940) -(4716, 1155, 1134) -(4420, 960, 162) -(1314, 29, 1122) -(1595, 116, 655) -(3499, 1931, 1945) -(86, 1432, 559) -(4957, 4447, 101) -(1175, 1832, 1193) -(1422, 4664, 1942) -(4861, 523, 1133) -(822, 4420, 586) -(2, 2573, 351) -(232, 1576, 969) -(835, 371, 544) -(1640, 3809, 504) -(1500, 1639, 787) -(473, 470, 601) -(1431, 1831, 647) -(2961, 4516, 1029) -(2952, 4409, 717) -(3134, 3072, 1371) -(1887, 2354, 890) -(1302, 111, 937) -(628, 4693, 1675) -(2362, 3779, 109) -(381, 1779, 1601) -(2667, 3221, 1125) -(4819, 644, 1121) -(3291, 4947, 1332) -(2828, 4851, 1312) -(1257, 3223, 1120) -(1160, 1993, 1901) -(60, 4077, 1170) -(3873, 712, 1075) -(2760, 3404, 903) -(3632, 4474, 996) -(2806, 2173, 1311) -(3927, 2625, 1033) -(3888, 1637, 1525) -(4011, 3090, 210) -(4650, 150, 1501) -(140, 3657, 343) -(468, 846, 1342) -(3884, 1096, 512) -(4954, 3064, 1369) -(4292, 2791, 1933) -(4002, 3379, 1254) -(3005, 637, 1949) -(1475, 1453, 1764) -(2936, 2758, 942) -(3160, 429, 126) -(3442, 772, 568) -(1993, 1308, 1589) -(875, 449, 157) -(692, 221, 509) -(4890, 1992, 364) -(2657, 424, 1162) -(4690, 646, 1658) -(2711, 719, 1078) -(135, 4426, 810) -(960, 2121, 240) -(1193, 1182, 1847) -(3425, 3325, 1749) -(4087, 3705, 1297) -(4327, 1655, 925) -(659, 3285, 549) -(1119, 2187, 1803) -(4499, 860, 1427) -(4120, 1127, 1278) -(1875, 1213, 1923) -(2699, 2856, 1598) -(3773, 4585, 354) -(4866, 1687, 880) -(85, 756, 1970) -(1731, 2133, 142) -(3175, 1308, 1167) -(3686, 2073, 1062) -(1614, 3930, 1241) -(161, 1065, 503) -(2993, 1931, 261) -(4158, 740, 1712) -(3608, 2493, 439) -(1821, 1540, 1657) -(4371, 4970, 258) -(4179, 2741, 1369) -(1712, 2310, 1573) -(4716, 2393, 1903) -(2604, 3210, 1975) -(1612, 1138, 325) -(1508, 3822, 1247) -(56, 1301, 1657) -(122, 2232, 1736) -(4183, 4034, 875) -(2115, 2905, 787) -(368, 4022, 1418) -(3279, 4486, 1206) -(574, 1610, 576) -(3488, 1093, 1600) -(4952, 2274, 1185) -(1969, 3219, 668) -(4710, 113, 328) -(1173, 2314, 287) -(4531, 2529, 630) -(902, 4176, 813) -(2954, 4756, 350) -(4973, 3457, 818) -(835, 4546, 1258) -(521, 3323, 1242) -(3308, 1441, 674) -(3783, 3375, 1525) -(3914, 554, 1554) -(3787, 4408, 1623) -(2072, 2336, 1459) -(331, 3124, 143) -(3574, 1032, 1424) -(4912, 1551, 1834) -(368, 3732, 247) -(220, 4497, 856) -(508, 4076, 1489) -(3438, 215, 1478) -(301, 64, 991) -(3025, 4617, 1996) -(4317, 4038, 1147) -(2788, 2509, 1069) -(4488, 208, 593) -(2638, 415, 329) -(1213, 1875, 1923) -(2168, 3217, 99) -(4211, 4775, 1688) -(1468, 4092, 450) -(1582, 2872, 1429) -(3409, 3444, 1846) -(786, 2695, 1312) -(3300, 2423, 242) -(3532, 2596, 1350) -(2314, 1737, 936) -(4677, 1499, 745) -(3793, 1494, 1475) -(322, 1201, 1276) -(2080, 4704, 1442) -(1318, 4174, 1258) -(3834, 4495, 1154) -(3652, 3399, 152) -(4353, 3769, 457) -(3854, 3351, 1395) -(2629, 4294, 1050) -(3334, 932, 952) -(550, 1183, 1132) -(3773, 4832, 1384) -(4857, 1001, 257) -(4883, 1997, 1618) -(910, 2367, 1864) -(715, 2205, 1592) -(4549, 4477, 1915) -(2744, 4660, 1668) -(3321, 2026, 1296) -(1410, 4755, 1928) -(4508, 1566, 1173) -(4996, 2195, 1215) -(747, 2984, 1857) -(3832, 3078, 1087) -(2246, 198, 1254) -(1892, 639, 1257) -(1718, 4069, 279) -(4210, 1882, 627) -(1233, 1813, 159) -(4384, 784, 220) -(4920, 1933, 526) -(2859, 2318, 1613) -(1491, 1709, 1015) -(1417, 1330, 395) -(4123, 113, 1000) -(4994, 964, 1766) -(1579, 742, 1276) -(4865, 553, 1787) -(3850, 680, 746) -(4282, 488, 1397) -(4718, 2757, 631) -(1429, 2491, 994) -(2110, 547, 321) -(3678, 468, 831) -(3358, 4702, 1265) -(1544, 4010, 1655) -(123, 744, 1322) -(40, 1477, 1899) -(1249, 1587, 1889) -(2330, 2505, 1552) -(4271, 4371, 367) -(773, 2939, 1385) -(4109, 948, 1502) -(1549, 639, 1363) -(2474, 4293, 60) -(2663, 1506, 1836) -(4890, 4047, 1688) -(1761, 3861, 1482) -(754, 4813, 348) -(4088, 64, 410) -(2539, 836, 1972) -(804, 1254, 1625) -(4299, 2942, 1243) -(4941, 2435, 1909) -(4403, 4016, 409) -(833, 928, 1524) -(3576, 3526, 1196) -(1431, 3095, 515) -(2271, 3761, 1354) -(2720, 561, 345) -(1670, 3604, 983) -(4515, 1650, 1177) -(471, 2869, 329) -(2039, 4399, 1174) -(3231, 4226, 1871) -(4869, 795, 1696) -(1444, 1154, 1277) -(755, 2017, 494) -(4270, 744, 1356) -(3769, 1239, 657) -(239, 716, 486) -(4473, 2608, 1046) -(4350, 2594, 356) -(3120, 4101, 229) -(4593, 3381, 1793) -(3323, 4622, 389) -(640, 2905, 1283) -(4850, 2254, 293) -(443, 4236, 102) -(3304, 906, 195) -(1915, 2086, 1890) -(3438, 3160, 239) -(2016, 3657, 845) -(516, 3596, 977) -(3479, 4512, 372) -(4164, 1110, 549) -(3255, 865, 362) -(3651, 3696, 1388) -(1744, 3918, 165) -(2230, 2504, 1160) -(2875, 1705, 710) -(2376, 69, 1370) -(1346, 3425, 851) -(2352, 522, 1648) -(3084, 79, 1433) -(2795, 2521, 1761) -(2627, 3596, 297) -(161, 4183, 1199) -(3372, 3834, 784) -(3018, 3251, 1932) -(1320, 250, 1096) -(4691, 1720, 712) -(1026, 1088, 1043) -(4551, 1565, 1049) -(3600, 501, 483) -(683, 4460, 1598) -(1315, 4413, 410) -(1736, 1969, 1713) -(3948, 689, 923) -(3801, 1111, 1189) -(626, 4843, 695) -(2947, 3438, 867) -(4021, 2776, 375) -(2083, 3887, 964) -(3133, 1639, 1549) -(4051, 988, 72) -(3174, 3505, 1251) -(4790, 2331, 65) -(497, 3197, 815) -(4542, 3209, 1089) -(1911, 3880, 989) -(4426, 4997, 545) -(3933, 384, 142) -(2834, 3524, 1084) -(3297, 2706, 1773) -(1596, 25, 793) -(1548, 4191, 1119) -(2742, 4770, 1663) -(817, 3446, 1137) -(4814, 2933, 1150) -(108, 3114, 1431) -(3826, 4584, 567) -(74, 189, 1957) -(4560, 1432, 142) -(1645, 1973, 1306) -(3218, 778, 381) -(867, 504, 626) -(3064, 2073, 1320) -(3997, 4540, 201) -(3720, 1496, 196) -(3318, 2967, 673) -(188, 1321, 1853) -(3498, 554, 641) -(3361, 4570, 646) -(2675, 423, 1360) -(3572, 863, 1439) -(4773, 459, 1096) -(1461, 4586, 627) -(221, 2423, 1473) -(2855, 3536, 169) -(3989, 112, 1649) -(603, 2735, 1973) -(3443, 566, 300) -(1053, 4857, 632) -(1001, 2803, 1842) -(3442, 2603, 1105) -(2151, 4354, 1234) -(3653, 803, 392) -(2860, 706, 148) -(4270, 497, 956) -(930, 1511, 1406) -(4449, 4249, 153) -(343, 2244, 582) -(2856, 2497, 1947) -(945, 0, 1296) -(1287, 4077, 1631) -(1131, 3805, 1310) -(2162, 272, 1103) -(3826, 4957, 998) -(73, 337, 193) -(2179, 1820, 858) -(3589, 2232, 1347) -(661, 3600, 1403) -(3237, 2136, 509) -(2532, 738, 1279) -(3567, 1646, 1517) -(3574, 4234, 1978) -(1104, 2304, 1528) -(180, 3791, 323) -(2135, 3115, 571) -(2050, 1735, 125) -(4425, 3853, 325) -(502, 1137, 685) -(1573, 4639, 463) -(3672, 978, 1324) -(1947, 2130, 1578) -(3765, 2647, 1277) -(3348, 829, 1107) -(2341, 1913, 840) -(133, 4405, 1450) -(150, 3325, 1215) -(2419, 1933, 1324) -(606, 1491, 1475) -(3804, 3898, 104) -(1592, 4945, 96) -(4427, 2125, 1914) -(734, 4795, 806) -(2996, 343, 1021) -(4242, 2979, 948) -(1218, 4348, 811) -(716, 570, 418) -(1080, 4410, 1210) -(2678, 2565, 1061) -(2522, 3676, 111) -(4411, 4496, 870) -(3569, 1624, 186) -(2537, 1739, 1963) -(2108, 2322, 1486) -(3883, 494, 1124) -(4117, 582, 746) -(2424, 4029, 1165) -(4943, 1358, 422) -(1292, 3094, 788) -(3295, 4938, 447) -(3859, 2997, 1468) -(2200, 3273, 1305) -(3170, 3168, 532) -(532, 4100, 363) -(4960, 4975, 375) -(535, 90, 1294) -(3410, 2543, 279) -(3107, 4321, 344) -(3078, 1567, 1632) -(324, 558, 791) -(4474, 1874, 673) -(610, 1399, 1755) -(3077, 2380, 460) -(1894, 505, 191) -(547, 1705, 66) -(1807, 1402, 229) -(1254, 804, 1625) -(2346, 2522, 1465) -(3242, 3040, 1932) -(3339, 4562, 1866) -(1776, 1304, 820) -(4743, 1160, 1147) -(2408, 2735, 1223) -(840, 1732, 124) -(4316, 3045, 1444) -(3397, 2180, 1301) -(1432, 3344, 1641) -(3330, 4988, 521) -(2639, 3284, 1232) -(4511, 4121, 1932) -(821, 3388, 655) -(3335, 1674, 106) -(3702, 325, 89) -(1618, 1626, 1974) -(4699, 1546, 1584) -(2973, 4321, 1326) -(1656, 1071, 611) -(3363, 4521, 1058) -(53, 266, 765) -(4655, 2546, 52) -(2627, 3297, 621) -(1220, 1666, 78) -(2507, 2738, 1725) -(706, 36, 751) -(2556, 549, 1226) -(2184, 1092, 1456) -(2602, 1125, 1066) -(3631, 4581, 297) -(3197, 2635, 286) -(4519, 698, 484) -(3731, 438, 976) -(2359, 1000, 1086) -(1057, 1851, 1731) -(424, 341, 1598) -(3813, 436, 302) -(2797, 4654, 1958) -(379, 3537, 1512) -(1780, 2921, 1689) -(688, 2522, 154) -(253, 1528, 1667) -(4539, 741, 264) -(1956, 2713, 1246) -(4475, 530, 595) -(223, 2741, 416) -(3119, 2129, 1296) -(4103, 3444, 1389) -(2322, 4416, 514) -(1890, 4733, 979) -(163, 4153, 420) -(4156, 3870, 1243) -(192, 2580, 1772) -(4528, 4265, 1059) -(2939, 4242, 445) -(3165, 3775, 188) -(682, 1587, 284) -(2325, 1960, 849) -(3453, 1267, 1650) -(1417, 272, 1534) -(4966, 3255, 1210) -(1649, 4813, 1607) -(4267, 2680, 1794) -(1245, 900, 1697) -(3827, 3679, 463) -(4679, 4655, 1525) -(4162, 1050, 1635) -(3376, 305, 689) -(55, 4276, 1542) -(829, 1069, 484) -(4524, 3521, 1631) -(2848, 1402, 1659) -(2303, 3012, 1111) -(1212, 4874, 1895) -(4618, 3629, 1444) -(4461, 794, 858) -(4032, 1964, 315) -(2096, 4918, 1423) -(3797, 3465, 526) -(3252, 1071, 849) -(4930, 4910, 1644) -(1075, 4867, 1577) -(1851, 1057, 1731) -(2886, 1796, 591) -(4513, 2298, 1724) -(1182, 1193, 1847) -(4784, 3080, 1612) -(972, 2470, 702) -(983, 2978, 1713) -(2261, 1993, 1025) -(1642, 4341, 594) -(1137, 502, 685) -(678, 934, 184) -(297, 3327, 663) -(4220, 2445, 703) -(1647, 4147, 1493) -(1323, 3069, 664) -(3327, 1119, 726) -(4221, 496, 1051) -(1990, 304, 1409) -(2895, 4795, 1334) -(3985, 2177, 1556) -(1105, 4701, 1135) -(2793, 4929, 1135) -(4391, 442, 1424) -(4394, 618, 1818) -(3970, 1071, 1784) -(2944, 2158, 243) -(3949, 2884, 1026) -(4143, 1077, 578) -(3809, 1640, 504) -(2267, 4323, 1653) -(2339, 2633, 1654) -(1602, 1781, 717) -(3078, 3832, 1087) -(513, 2076, 1817) -(706, 4424, 1825) -(2656, 1731, 936) -(3652, 65, 1853) -(4154, 4243, 624) -(1973, 2782, 1409) -(1245, 4945, 1240) -(2863, 502, 1944) -(4716, 724, 1344) -(3209, 3604, 543) -(2213, 3057, 1401) -(4770, 4683, 1525) -(1544, 1023, 850) -(2471, 1337, 1522) -(1302, 979, 130) -(3725, 1948, 786) -(3263, 1837, 141) -(499, 1932, 757) -(937, 3548, 1040) -(3524, 1635, 1726) -(3149, 2703, 774) -(686, 372, 1115) -(3715, 917, 1831) -(187, 4931, 1562) -(1771, 3511, 521) -(125, 4246, 135) -(1590, 4834, 589) -(4077, 4034, 1907) -(1793, 3340, 693) -(4230, 2013, 1995) -(3377, 3911, 488) -(473, 1110, 1884) -(1982, 4919, 1916) -(3617, 1633, 249) -(584, 41, 1531) -(3033, 2381, 1041) -(4980, 1543, 696) -(639, 1549, 1363) -(633, 3880, 355) -(2162, 2113, 1463) -(3321, 3765, 1431) -(4250, 1418, 1007) -(4712, 1617, 594) -(1795, 4391, 1217) -(4764, 1290, 822) -(1709, 2859, 345) -(3342, 2815, 508) -(1687, 3090, 1071) -(4576, 3740, 504) -(4972, 117, 1002) -(4087, 2334, 1755) -(4888, 264, 77) -(2262, 3864, 401) -(2997, 2395, 1168) -(993, 2798, 158) -(1734, 1343, 82) -(2643, 2802, 1319) -(91, 3696, 954) -(3758, 3434, 642) -(2248, 3645, 147) -(863, 122, 1988) -(1393, 1892, 145) -(3424, 3076, 983) -(1457, 4762, 1009) -(3060, 4281, 1659) -(479, 3806, 994) -(2578, 4510, 1912) -(4715, 1324, 1994) -(880, 3525, 1088) -(3932, 932, 1455) -(2493, 3608, 439) -(514, 2825, 1709) -(3755, 933, 913) -(2220, 4986, 1522) -(183, 1186, 168) -(2882, 4055, 1927) -(1018, 4776, 373) -(784, 4384, 220) -(3390, 1638, 616) -(4371, 1773, 917) -(1941, 3665, 1435) -(2524, 1836, 546) -(3898, 2611, 1703) -(2854, 1605, 456) -(1485, 4381, 1703) -(2491, 97, 1334) -(3125, 1082, 261) -(1187, 422, 777) -(2921, 1780, 1689) -(2238, 1262, 1368) -(2392, 1478, 144) -(816, 506, 74) -(341, 3799, 1990) -(1084, 2569, 1944) -(4939, 2934, 1810) -(2310, 4894, 1822) -(3453, 4282, 581) -(2942, 3315, 813) -(2276, 2256, 518) -(4952, 847, 591) -(1715, 2443, 1145) -(1609, 1170, 1132) -(3782, 3660, 1083) -(996, 2432, 1148) -(2061, 1760, 858) -(979, 2037, 1184) -(1711, 476, 951) -(1076, 3929, 1814) -(519, 2895, 1643) -(4923, 4645, 98) -(1624, 3569, 186) -(3457, 4973, 818) -(537, 3539, 89) -(1851, 4490, 1040) -(1187, 670, 1001) -(1984, 4113, 72) -(4522, 2840, 1289) -(3685, 3892, 1581) -(4121, 1697, 797) -(4370, 2505, 1766) -(3957, 1867, 1708) -(1700, 4866, 1052) -(552, 1776, 1660) -(116, 1595, 655) -(1806, 310, 1597) -(3340, 2517, 1200) -(620, 2255, 156) -(1264, 616, 98) -(1414, 4647, 1847) -(3058, 2060, 601) -(1453, 4291, 1975) -(4603, 4472, 1152) -(1533, 2644, 1987) -(3795, 2381, 1809) -(2734, 2823, 1858) -(431, 4662, 1589) -(4390, 1728, 1619) -(3632, 3993, 1228) -(1229, 4519, 918) -(4893, 4365, 788) -(583, 3690, 87) -(2426, 1098, 1068) -(2266, 4071, 835) -(1409, 1309, 233) -(3114, 3485, 137) -(2155, 2732, 1769) -(1016, 2470, 1555) -(1526, 2398, 1951) -(2661, 3752, 862) -(2113, 632, 1648) -(4438, 1858, 582) -(3765, 3162, 911) -(1921, 1274, 99) -(2342, 4294, 1736) -(2025, 4950, 700) -(1904, 3650, 592) -(2541, 240, 639) -(1374, 824, 801) -(3873, 1637, 78) -(3835, 938, 703) -(3872, 1936, 296) -(957, 3010, 145) -(4267, 70, 1090) -(450, 4889, 170) -(665, 1730, 351) -(4675, 2620, 1870) -(4678, 2318, 55) -(61, 1285, 318) -(1867, 243, 1000) -(2322, 687, 1495) -(3380, 2230, 1859) -(1423, 4121, 1085) -(4511, 1540, 1674) -(2753, 3405, 771) -(3437, 19, 639) -(1612, 2470, 749) -(4467, 2808, 388) -(2451, 4768, 1834) -(2376, 1448, 1523) -(538, 1203, 1688) -(4481, 713, 782) -(2107, 1352, 1381) -(3175, 619, 555) -(4903, 2681, 713) -(2350, 712, 1789) -(3298, 2810, 193) -(3691, 3009, 409) -(3522, 4646, 659) -(2240, 4314, 1633) -(2439, 4378, 1951) -(4914, 1360, 1715) -(3900, 3129, 991) -(3766, 544, 1736) -(3877, 1816, 1978) -(2297, 455, 1246) -(3965, 3062, 902) -(790, 2212, 1355) -(3054, 3791, 1852) -(2121, 3729, 338) -(4245, 358, 639) -(1717, 4460, 926) -(4611, 4100, 1997) -(4159, 2972, 541) -(1286, 3908, 901) -(4740, 2530, 1938) -(4445, 3155, 812) -(4698, 4861, 1238) -(4376, 282, 353) -(3836, 2615, 428) -(2679, 995, 483) -(3598, 1313, 1023) -(1011, 25, 1287) -(706, 4058, 864) -(2320, 2164, 320) -(2768, 3150, 1274) -(2085, 2364, 267) -(1476, 95, 218) -(1051, 4553, 1255) -(491, 2789, 1321) -(4969, 2082, 933) -(2381, 3033, 1041) -(1808, 3995, 881) -(3069, 1093, 1949) -(260, 4887, 1664) -(3989, 4229, 583) -(1498, 2422, 310) -(4479, 4665, 376) -(3543, 1132, 1754) -(9, 2858, 1877) -(155, 579, 416) -(3479, 3012, 1425) -(2888, 1134, 1350) -(636, 3684, 377) -(2447, 1399, 1478) -(2701, 3736, 495) -(3232, 1302, 930) -(2975, 4740, 769) -(638, 398, 1247) -(4441, 1579, 870) -(3448, 3450, 1403) -(613, 952, 1489) -(2833, 2018, 599) -(3012, 1335, 179) -(894, 1279, 1357) -(2475, 2767, 210) -(971, 370, 861) -(3167, 4693, 418) -(2269, 4196, 1149) -(3508, 1819, 1917) -(1660, 1316, 251) -(2385, 1829, 1607) -(2007, 2759, 1153) -(386, 3209, 1542) -(644, 4819, 1121) -(4421, 4315, 1993) -(23, 4342, 229) -(4802, 459, 1102) -(3760, 2907, 1367) -(3576, 3315, 1959) -(2236, 968, 179) -(3584, 3718, 1156) -(2929, 3277, 1216) -(2723, 2586, 856) -(2834, 362, 676) -(2250, 764, 398) -(1583, 1297, 1179) -(264, 4348, 1469) -(3429, 1124, 396) -(3725, 2743, 362) -(4851, 4918, 1751) -(2620, 4675, 1870) -(1725, 2324, 412) -(4552, 2837, 1578) -(918, 4336, 640) -(341, 424, 1598) -(2796, 102, 233) -(543, 2604, 456) -(498, 3933, 1377) -(2475, 814, 1571) -(196, 4418, 83) -(2453, 2438, 873) -(4489, 2552, 946) -(1578, 2262, 1723) -(102, 1679, 242) -(2191, 3610, 1120) -(3920, 3340, 971) -(1161, 4330, 1528) -(1551, 4717, 909) -(590, 1168, 385) -(1700, 2106, 944) -(333, 1369, 1678) -(2507, 3369, 1303) -(300, 2463, 1718) -(2395, 2077, 1502) -(1852, 3848, 230) -(1695, 3396, 1831) -(118, 2377, 1175) -(1317, 4421, 389) -(4448, 4478, 1266) -(1607, 4554, 904) -(3059, 13, 1324) -(1476, 4373, 338) -(2814, 3551, 191) -(1110, 1610, 99) -(2606, 602, 1096) -(4821, 2285, 1838) -(2368, 1212, 1033) -(3530, 1662, 205) -(3382, 1783, 282) -(3834, 1876, 245) -(3063, 4458, 1849) -(2080, 3508, 890) -(1793, 2778, 1181) -(3088, 2728, 1717) -(2459, 2860, 615) -(536, 3471, 1446) -(4147, 1647, 1493) -(2925, 3575, 347) -(1359, 4914, 202) -(3033, 2863, 803) -(696, 1921, 1842) -(4418, 46, 565) -(1771, 4434, 133) -(3741, 612, 1710) -(4052, 590, 1425) -(4955, 2973, 1699) -(2788, 3591, 573) -(433, 942, 535) -(805, 3749, 943) -(4761, 2372, 55) -(3496, 1068, 1110) -(52, 2004, 576) -(2105, 153, 1029) -(2601, 1148, 1376) -(2042, 3007, 725) -(405, 2852, 407) -(4672, 730, 1375) -(1546, 2708, 1447) -(2960, 4602, 1910) -(2677, 3190, 1832) -(605, 1861, 1750) -(3702, 3381, 1779) -(859, 637, 1431) -(1478, 2227, 680) -(120, 3518, 838) -(2907, 4852, 1907) -(1906, 1673, 1212) -(4182, 589, 897) -(3022, 2323, 672) -(4683, 4770, 1525) -(3724, 3046, 1034) -(1359, 1125, 1167) -(462, 1798, 654) -(3735, 1551, 1912) -(3616, 971, 1863) -(1127, 4709, 1187) -(1164, 3569, 1291) -(4528, 1764, 462) -(3783, 971, 502) -(4168, 1574, 1834) -(4586, 1373, 1097) -(2841, 4711, 854) -(4307, 2324, 610) -(139, 1702, 418) -(1349, 3, 989) -(3662, 923, 837) -(3030, 2201, 835) -(3893, 4698, 1721) -(1096, 3191, 749) -(3472, 1798, 1884) -(244, 3317, 760) -(1894, 865, 843) -(882, 3908, 543) -(4186, 162, 1042) -(872, 670, 249) -(2235, 4202, 771) -(1022, 2250, 945) -(1628, 1953, 392) -(3948, 4286, 1091) -(1497, 1753, 151) -(4762, 1671, 1419) -(1732, 2111, 601) -(2462, 4888, 1235) -(4391, 4681, 1702) -(1429, 4020, 1031) -(2258, 3182, 983) -(4614, 1825, 1651) -(1660, 212, 519) -(2053, 4112, 922) -(4355, 960, 742) -(4632, 2427, 1808) -(4151, 2749, 375) -(822, 175, 553) -(1285, 717, 1575) -(1271, 4084, 56) -(625, 4269, 112) -(3564, 158, 925) -(4884, 1896, 1984) -(235, 2616, 1296) -(882, 4661, 1896) -(3851, 1036, 615) -(503, 1554, 1578) -(438, 1795, 1673) -(4488, 78, 1254) -(4307, 3196, 1595) -(4822, 1690, 892) -(2496, 244, 889) -(794, 823, 457) -(4074, 4486, 791) -(1948, 4297, 934) -(1082, 194, 1717) -(2635, 2487, 1709) -(4967, 3202, 213) -(3847, 4316, 73) -(38, 2572, 1536) -(3434, 2045, 1535) -(317, 271, 168) -(273, 4369, 1591) -(721, 260, 1318) -(2482, 764, 1799) -(2555, 3520, 379) -(3530, 2472, 759) -(1134, 2666, 270) -(3678, 4783, 927) -(3381, 22, 1782) -(477, 1169, 1237) -(599, 4840, 1245) -(4120, 4208, 118) -(2327, 271, 570) -(1321, 4188, 1779) -(3342, 3512, 1229) -(2833, 501, 1874) -(1831, 293, 1862) -(1871, 1480, 148) -(3898, 4551, 1484) -(2741, 122, 1746) -(721, 3792, 1392) -(2714, 2348, 647) -(3, 1349, 989) -(3762, 4685, 1127) -(1802, 3545, 972) -(4133, 784, 1914) -(4396, 4050, 1777) -(2987, 1481, 599) -(3627, 4124, 422) -(1513, 2322, 1296) -(1010, 4058, 323) -(4671, 4283, 1366) -(203, 2874, 493) -(3781, 3311, 1821) -(3057, 4057, 1385) -(4656, 3474, 1181) -(4998, 1196, 545) -(2036, 1071, 1984) -(996, 1131, 156) -(612, 3741, 1710) -(2571, 3943, 1423) -(1672, 256, 1357) -(3266, 3635, 1939) -(2745, 2180, 61) -(961, 215, 399) -(1618, 3471, 1261) -(1078, 3834, 673) -(1794, 3243, 580) -(2803, 974, 1582) -(1768, 904, 428) -(238, 687, 280) -(2380, 3077, 460) -(3075, 3815, 1308) -(4263, 2603, 951) -(2702, 898, 1057) -(3464, 2629, 582) -(1621, 4749, 988) -(3329, 2644, 1108) -(268, 488, 414) -(4702, 3617, 1970) -(4440, 3304, 1074) -(578, 3091, 1630) -(2937, 3505, 1584) -(1611, 4965, 511) -(2655, 4430, 1664) -(1842, 1390, 1352) -(654, 2808, 725) -(1700, 1936, 464) -(836, 3479, 716) -(1662, 4426, 1840) -(2671, 1672, 988) -(2075, 2475, 1863) -(291, 806, 82) -(918, 4108, 1158) -(333, 1010, 610) -(1687, 4882, 1808) -(931, 778, 186) -(4194, 1254, 1597) -(2814, 2176, 868) -(4704, 3252, 460) -(3558, 1771, 931) -(2478, 4964, 1910) -(3744, 1171, 1339) -(3451, 537, 1500) -(1237, 2754, 1173) -(592, 3906, 817) -(3290, 1673, 1413) -(271, 3713, 282) -(4836, 4749, 1316) -(1266, 3430, 944) -(1046, 500, 957) -(3511, 975, 1259) -(317, 1721, 70) -(2993, 6, 175) -(3192, 363, 930) -(2613, 4515, 1401) -(2057, 2886, 587) -(2197, 1677, 386) -(628, 2615, 184) -(1068, 3380, 1056) -(3827, 83, 923) -(4404, 1400, 1186) -(343, 360, 1564) -(1991, 4978, 519) -(3990, 3008, 1371) -(3820, 3236, 204) -(2786, 2947, 754) -(3395, 1614, 906) -(4775, 1788, 192) -(644, 4514, 667) -(2623, 4105, 1569) -(210, 2827, 1045) -(4093, 1779, 585) -(4080, 4108, 492) -(2114, 3431, 1892) -(2182, 3810, 933) -(698, 2580, 282) -(4020, 1429, 1031) -(4562, 2358, 1279) -(4432, 3619, 871) -(1, 420, 1310) -(3755, 508, 1275) -(2982, 2912, 1553) -(4672, 2022, 1923) -(4187, 3626, 500) -(4457, 955, 510) -(2077, 3074, 1488) -(2627, 3411, 485) -(2455, 204, 1084) -(1940, 4658, 958) -(1719, 614, 936) -(652, 1768, 76) -(2298, 3515, 142) -(295, 1133, 863) -(4278, 4406, 881) -(3053, 4537, 1296) -(4986, 1149, 1689) -(4403, 955, 159) -(3155, 1067, 1896) -(462, 667, 919) -(2275, 1121, 1158) -(4727, 2126, 1339) -(2473, 967, 842) -(142, 533, 1866) -(2945, 1031, 1490) -(4224, 4990, 1583) -(1882, 2387, 1308) -(4068, 4555, 399) -(1855, 2359, 532) -(1433, 2154, 490) -(1404, 767, 456) -(4970, 4823, 1130) -(1707, 1544, 1625) -(4004, 4210, 259) -(797, 4927, 1547) -(716, 239, 486) -(3580, 3240, 1377) -(102, 268, 1833) -(1636, 4245, 638) -(256, 2091, 1100) -(226, 4222, 1609) -(3263, 4024, 629) -(2431, 1030, 591) -(621, 2152, 1575) -(407, 1804, 852) -(4965, 3345, 133) -(1644, 4216, 143) -(4157, 858, 1840) -(1530, 4108, 1837) -(892, 3365, 1021) -(4724, 4279, 596) -(271, 2925, 700) -(385, 726, 1865) -(175, 2137, 123) -(415, 2638, 329) -(3520, 3412, 144) -(713, 1270, 1071) -(4687, 1130, 1963) -(834, 1853, 422) -(3246, 812, 388) -(570, 933, 390) -(2882, 3171, 791) -(3411, 2627, 485) -(1878, 2539, 962) -(1656, 3798, 1019) -(3887, 3461, 1470) -(4694, 4949, 254) -(2439, 2623, 1819) -(4742, 1540, 1099) -(2975, 3910, 1732) -(1344, 687, 1335) -(2422, 1498, 310) -(628, 3330, 1806) -(1177, 2360, 179) -(4432, 4157, 1115) -(1296, 1218, 291) -(4239, 522, 90) -(999, 761, 1305) -(2531, 1840, 88) -(4151, 3374, 952) -(599, 2287, 915) -(2183, 2428, 409) -(4820, 1709, 1956) -(2271, 1182, 376) -(4100, 4756, 1177) -(883, 3444, 598) -(3057, 4388, 1095) -(4969, 2759, 1759) -(4193, 2453, 220) -(3541, 4661, 959) -(2155, 4958, 1013) -(352, 4335, 742) -(538, 266, 904) -(3376, 2711, 167) -(4901, 1149, 63) -(3524, 3507, 937) -(3582, 49, 468) -(4136, 4115, 544) -(4690, 594, 481) -(1794, 3215, 1873) -(794, 4461, 858) -(2765, 3408, 441) -(1091, 3365, 71) -(1693, 2247, 1707) -(3797, 4506, 513) -(462, 1299, 1676) -(3861, 1761, 1482) -(1866, 3341, 55) -(2241, 4334, 1675) -(4628, 4576, 1967) -(3271, 3748, 1212) -(4988, 3330, 521) -(1555, 4938, 1507) -(1615, 781, 1378) -(3625, 1310, 644) -(3532, 3411, 380) -(1929, 3877, 1249) -(4742, 2939, 676) -(4986, 2220, 1522) -(2962, 3614, 442) -(4572, 57, 1153) -(1518, 4449, 271) -(2410, 2847, 1404) -(4180, 1498, 1070) -(3881, 4128, 835) -(1498, 4180, 1070) -(1075, 1862, 862) -(2349, 644, 172) -(1906, 125, 1019) -(250, 2851, 1041) -(2702, 1208, 1429) -(983, 649, 556) -(1425, 4106, 1466) -(3567, 3046, 1643) -(2032, 1446, 1234) -(2798, 4981, 1133) -(1132, 2510, 1336) -(1236, 4266, 1458) -(3399, 957, 1220) -(1967, 2055, 1216) -(4121, 2973, 941) -(9, 3470, 1198) -(845, 1608, 852) -(3892, 1202, 958) -(4866, 4526, 955) -(271, 1150, 1424) -(61, 2723, 1174) -(3049, 1846, 629) -(4869, 4813, 91) -(1638, 3390, 616) -(3976, 2377, 1888) -(2434, 4128, 1382) -(4496, 1467, 376) -(2375, 1845, 1418) -(1557, 3962, 356) -(1157, 4120, 1734) -(1497, 2914, 154) -(1747, 874, 340) -(1050, 4162, 1635) -(4434, 1771, 133) -(3450, 4018, 1493) -(3578, 3311, 492) -(4984, 4766, 1700) -(1969, 1736, 1713) -(1534, 2330, 899) -(2488, 3581, 1340) -(2063, 249, 90) -(2958, 2803, 872) -(310, 1806, 1597) -(398, 638, 1247) -(3560, 1749, 720) -(974, 2413, 196) -(3977, 4642, 664) -(2237, 862, 1666) -(1859, 419, 1527) -(3602, 3046, 1881) -(2565, 4032, 1067) -(1545, 2930, 1117) -(3527, 1643, 697) -(1033, 539, 466) -(995, 2679, 483) -(230, 2117, 1612) -(4198, 1294, 951) -(826, 120, 1069) -(799, 4614, 1531) -(1286, 3816, 1284) -(1746, 3257, 1634) -(4187, 207, 1144) -(34, 2699, 1021) -(1205, 724, 684) -(2500, 3163, 1100) -(378, 1119, 84) -(797, 3297, 1781) -(2367, 3949, 666) -(3929, 2732, 596) -(1178, 2064, 827) -(1964, 3223, 98) -(3937, 811, 114) -(3121, 4430, 689) -(2120, 666, 1950) -(2887, 194, 1747) -(4297, 3980, 79) -(4333, 3030, 1193) -(4783, 221, 259) -(1989, 1945, 1521) -(4930, 924, 1382) -(27, 4750, 1971) -(4959, 2785, 993) -(4003, 68, 1390) -(2361, 2616, 1868) -(53, 3458, 1154) -(404, 270, 1702) -(4654, 952, 1427) -(655, 829, 1997) -(835, 3900, 1813) -(1477, 2421, 1295) -(357, 2080, 526) -(3074, 4664, 1883) -(1928, 3812, 283) -(667, 3674, 431) -(597, 387, 453) -(3656, 3572, 1743) -(3819, 4241, 630) -(855, 1530, 651) -(2228, 3427, 1176) -(488, 268, 414) -(2064, 1131, 1189) -(4817, 3143, 1451) -(1899, 3945, 1020) -(558, 1435, 1600) -(729, 3627, 616) -(3573, 3594, 426) -(975, 1802, 1355) -(624, 2895, 1890) -(1080, 2795, 497) -(2468, 257, 1880) -(1491, 2699, 555) -(3212, 360, 927) -(1206, 4483, 622) -(1785, 3226, 81) -(2649, 3043, 723) -(3061, 2266, 1867) -(1793, 1445, 1223) -(210, 1976, 578) -(49, 3582, 468) -(3570, 1412, 1568) -(4269, 1961, 1524) -(1764, 208, 1262) -(1107, 1071, 1380) -(1921, 4872, 959) -(2256, 4480, 1102) -(4148, 1385, 1373) -(4895, 3074, 1157) -(1794, 1061, 1168) -(4794, 1267, 85) -(1975, 3762, 1514) -(4593, 3385, 408) -(547, 1240, 134) -(4032, 703, 1201) -(2713, 1956, 1246) -(4418, 196, 83) -(1952, 313, 337) -(3482, 3645, 1684) -(3436, 492, 1760) -(4179, 4436, 398) -(859, 3866, 571) -(1890, 2337, 537) -(2699, 3715, 802) -(4811, 2176, 185) -(3307, 4601, 1640) -(707, 25, 744) -(1410, 3172, 111) -(2470, 1016, 1555) -(3911, 3377, 488) -(1415, 4028, 1647) -(3720, 271, 389) -(1433, 3208, 400) -(940, 1372, 991) -(4447, 4576, 347) -(2282, 3033, 1811) -(1866, 1506, 638) -(3425, 2594, 355) -(1140, 2716, 1333) -(4682, 4746, 215) -(4940, 4135, 575) -(3011, 2945, 1155) -(4292, 750, 444) -(4801, 3080, 1996) -(4743, 2213, 597) -(4154, 651, 824) -(3017, 3684, 1771) -(2172, 3626, 852) -(3927, 2291, 706) -(784, 2357, 1529) -(2023, 2909, 1094) -(1230, 1160, 492) -(4400, 3874, 1296) -(4714, 3839, 205) -(3444, 3951, 384) -(1104, 3856, 342) -(119, 1489, 820) -(438, 4379, 96) -(4153, 3237, 585) -(3758, 274, 55) -(35, 276, 1158) -(3231, 2650, 694) -(3557, 2035, 477) -(446, 4427, 1618) -(2086, 1915, 1890) -(4310, 649, 838) -(2095, 269, 426) -(1600, 3608, 399) -(1745, 3450, 1457) -(3936, 53, 718) -(3442, 309, 1065) -(814, 2530, 433) -(3590, 3823, 1831) -(1058, 2628, 1558) -(2853, 1064, 264) -(2856, 1220, 599) -(2169, 3805, 1003) -(2878, 257, 1030) -(1255, 2965, 1925) -(3375, 3255, 1759) -(133, 1296, 829) -(2442, 3767, 1570) -(3811, 1313, 1089) -(85, 2306, 510) -(2500, 4966, 1452) -(1149, 4901, 63) -(4319, 996, 1254) -(2657, 808, 460) -(43, 897, 1267) -(520, 383, 1879) -(701, 3405, 686) -(2609, 4893, 89) -(2949, 2774, 1697) -(2794, 3042, 669) -(184, 4191, 553) -(3288, 4201, 1011) -(696, 1203, 1490) -(1313, 3811, 1089) -(249, 2974, 1067) -(353, 3148, 221) -(3104, 1652, 1181) -(2220, 3149, 1854) -(2896, 2531, 84) -(625, 2571, 834) -(4192, 2792, 712) -(183, 2967, 369) -(212, 3753, 193) -(3360, 2695, 1713) -(3442, 2386, 582) -(3505, 3364, 758) -(4760, 3392, 1595) -(3571, 2726, 299) -(4038, 4317, 1147) -(4652, 992, 420) -(977, 1393, 1187) -(2741, 223, 416) -(460, 2118, 1406) -(1042, 1286, 1322) -(3564, 2168, 1768) -(3396, 922, 1486) -(3600, 4059, 221) -(718, 2362, 1882) -(2604, 4529, 1204) -(558, 1362, 1497) -(320, 1161, 1117) -(1171, 4531, 908) -(1835, 761, 1007) -(4027, 2556, 716) -(3970, 2293, 463) -(4623, 2170, 159) -(4256, 2460, 662) -(2937, 368, 230) -(3356, 2756, 1740) -(1468, 2334, 483) -(1679, 1984, 1660) -(893, 3689, 446) -(4646, 1345, 1586) -(2447, 3125, 1199) -(188, 2719, 1916) -(4387, 3710, 885) -(3608, 3226, 201) -(4900, 2604, 560) -(1182, 2271, 376) -(4311, 4770, 1975) -(1297, 1179, 101) -(3778, 2788, 1372) -(2997, 3859, 1468) -(411, 4311, 803) -(892, 2589, 725) -(97, 2563, 1416) -(3606, 4855, 1218) -(4681, 1140, 865) -(1984, 1679, 1660) -(564, 4970, 1346) -(903, 1403, 1218) -(3669, 3483, 904) -(4078, 423, 1113) -(2746, 2908, 1019) -(4046, 1517, 1333) -(4939, 3699, 1910) -(1780, 2589, 565) -(3536, 1174, 361) -(4386, 2733, 1011) -(4852, 892, 1560) -(3363, 4499, 225) -(1347, 3718, 611) -(3473, 3415, 1806) -(829, 655, 1997) -(2591, 1984, 1082) -(2573, 117, 874) -(3576, 3103, 1405) -(361, 2855, 1356) -(4938, 49, 736) -(1884, 287, 1576) -(2106, 2158, 1431) -(1517, 290, 955) -(4271, 4823, 115) -(3141, 1289, 236) -(2413, 974, 196) -(3892, 1922, 653) -(2033, 730, 67) -(2491, 140, 104) -(1783, 2903, 147) -(4058, 706, 864) -(1418, 271, 314) -(2136, 1613, 328) -(292, 4342, 1112) -(2388, 690, 792) -(1153, 554, 660) -(704, 4254, 943) -(2449, 1424, 1736) -(1064, 1268, 1730) -(703, 4032, 1201) -(3132, 1063, 1796) -(3507, 2773, 521) -(2013, 4230, 1995) -(1952, 470, 1830) -(1935, 3315, 1119) -(43, 708, 1132) -(1760, 1327, 870) -(4233, 637, 639) -(3722, 848, 1189) -(3351, 296, 1742) -(3602, 1530, 1044) -(1352, 4158, 1146) -(1240, 2179, 1162) -(437, 2704, 450) -(3955, 839, 151) -(39, 2580, 1229) -(3285, 709, 166) -(3478, 3640, 1855) -(4002, 4219, 714) -(2016, 2195, 318) -(2066, 1066, 1050) -(4776, 2367, 1506) -(423, 4078, 1113) -(2940, 1052, 1628) -(1198, 3536, 1354) -(2930, 4446, 1346) -(3714, 415, 1218) -(3822, 1508, 1247) -(2469, 4236, 1751) -(1021, 2527, 51) -(1173, 3522, 1962) -(4210, 3556, 981) -(2532, 1621, 1627) -(4990, 4753, 1816) -(1787, 2817, 1381) -(4806, 2712, 176) -(1765, 1984, 107) -(1268, 1064, 1730) -(590, 4052, 1425) -(81, 1296, 274) -(2842, 2502, 1369) -(2938, 1171, 1543) -(983, 2567, 767) -(1847, 2002, 1602) -(4541, 1085, 341) -(2584, 2249, 1584) -(411, 2800, 1548) -(468, 268, 1523) -(2422, 4119, 550) -(1213, 3048, 869) -(2812, 3755, 835) -(3673, 1412, 1211) -(4788, 3106, 369) -(1837, 1476, 954) -(3399, 871, 1018) -(3074, 1157, 839) -(4710, 3811, 1023) -(3442, 1, 1260) -(1320, 220, 1314) -(2291, 4523, 862) -(4602, 2960, 1910) -(3527, 4790, 379) -(3417, 4855, 1599) -(4091, 1643, 1994) -(3310, 2635, 1792) -(3285, 2740, 1126) -(4990, 577, 336) -(2119, 3770, 929) -(2944, 3988, 1343) -(4389, 4577, 1058) -(3298, 2005, 809) -(64, 4088, 410) -(4254, 2184, 1781) -(1488, 801, 1374) -(1007, 3339, 576) -(3637, 3428, 1152) -(1174, 3250, 1432) -(2226, 700, 1627) -(870, 205, 712) -(4101, 3963, 944) -(3032, 1377, 1989) -(4387, 2161, 437) -(4747, 1285, 1393) -(2500, 2443, 467) -(4199, 2868, 824) -(333, 2049, 1140) -(4931, 3468, 557) -(1071, 3970, 1784) -(2860, 2459, 615) -(2816, 3398, 716) -(4210, 2127, 225) -(3127, 555, 861) -(3124, 4475, 824) -(1520, 2877, 1241) -(2134, 2896, 1719) -(4301, 80, 874) -(4451, 575, 373) -(1011, 2178, 67) -(259, 3123, 1636) -(2840, 2199, 1921) -(3026, 3346, 449) -(4330, 3195, 313) -(2721, 320, 329) -(2362, 4870, 1078) -(196, 3998, 1961) -(238, 4893, 1847) -(525, 2476, 139) -(4267, 465, 1895) -(1361, 444, 1823) -(3238, 4971, 1654) -(4456, 22, 656) -(2568, 81, 720) -(2642, 1938, 1668) -(4390, 697, 427) -(1494, 4543, 706) -(1846, 3049, 629) -(3796, 1852, 1648) -(3560, 2134, 715) -(3221, 2384, 1382) -(3842, 463, 940) -(1130, 2390, 201) -(960, 4355, 742) -(4342, 3486, 1733) -(4323, 4751, 381) -(2268, 3903, 365) -(484, 92, 118) -(4832, 43, 1423) -(4589, 2467, 1664) -(2794, 4135, 406) -(4641, 2238, 753) -(1214, 1762, 1381) -(358, 4245, 639) -(362, 4636, 357) -(2569, 2090, 1042) -(2584, 4174, 301) -(3263, 3894, 1743) -(2953, 4643, 55) -(485, 374, 475) -(1940, 1513, 317) -(4763, 3709, 1617) -(1511, 4264, 649) -(2743, 1743, 988) -(2318, 4331, 1255) -(2914, 2416, 1652) -(405, 1975, 1975) -(4662, 431, 1589) -(635, 910, 1996) -(3051, 389, 230) -(3710, 4387, 885) -(1894, 2751, 100) -(1392, 771, 204) -(4478, 4008, 157) -(1908, 203, 360) -(4987, 3027, 373) -(1385, 3370, 1690) -(2456, 611, 174) -(4706, 3878, 491) -(4112, 2010, 1532) -(1185, 202, 848) -(1887, 2691, 1687) -(1776, 3821, 516) -(1904, 3474, 1892) -(1746, 2034, 1525) -(4224, 2332, 1944) -(1136, 1558, 1923) -(2545, 4578, 156) -(4804, 1063, 1569) -(2739, 3561, 1708) -(3404, 4270, 1489) -(4892, 1739, 1051) -(3520, 3390, 703) -(2929, 4106, 1890) -(4237, 1766, 1144) -(4659, 2347, 1904) -(3550, 139, 996) -(3524, 2117, 528) -(2983, 830, 287) -(3186, 2694, 556) -(1996, 1489, 193) -(3941, 293, 1173) -(3072, 3679, 1176) -(554, 410, 1957) -(1736, 1606, 1653) -(1527, 1965, 570) -(42, 2234, 1746) -(803, 3653, 392) -(525, 3575, 430) -(3834, 129, 1895) -(1973, 505, 1193) -(2588, 2013, 1010) -(4459, 1724, 917) -(4947, 1306, 653) -(4188, 3136, 436) -(2572, 38, 1536) -(34, 3092, 594) -(4813, 1041, 1179) -(2282, 142, 1668) -(4826, 4676, 197) -(2531, 4125, 177) -(1807, 3428, 378) -(2893, 4283, 886) -(2065, 4100, 1457) -(3683, 3875, 1864) -(2610, 3422, 628) -(1187, 1260, 203) -(3933, 498, 1377) -(4857, 3597, 558) -(125, 1801, 594) -(941, 2884, 179) -(3884, 1356, 1070) -(1356, 505, 304) -(1675, 1155, 1129) -(2165, 1448, 1664) -(37, 3855, 451) -(1434, 1323, 877) -(1354, 2106, 1140) -(1556, 466, 1752) -(4317, 100, 99) -(659, 1332, 1643) -(3796, 795, 632) -(4801, 447, 1090) -(4077, 2678, 1386) -(1567, 3078, 1632) -(4107, 1565, 122) -(3661, 675, 139) -(4764, 4253, 67) -(1439, 915, 1687) -(3051, 3957, 1119) -(1501, 2090, 1902) -(2903, 1783, 147) -(2635, 3197, 286) -(2794, 4046, 1562) -(2030, 4896, 970) -(941, 4041, 873) -(2141, 4635, 1332) -(1722, 1484, 760) -(549, 2373, 1115) -(1119, 1564, 1320) -(2288, 1547, 1770) -(2909, 2023, 1094) -(3009, 2521, 797) -(534, 214, 1320) -(792, 3569, 1724) -(4074, 3826, 463) -(3401, 1315, 1629) -(650, 1011, 1200) -(375, 125, 422) -(1100, 2963, 543) -(1303, 583, 888) -(3070, 1984, 171) -(2144, 1975, 1773) -(2238, 2466, 275) -(1843, 2785, 135) -(2678, 1119, 617) -(2984, 747, 1857) -(3907, 3429, 655) -(1241, 1211, 853) -(2671, 2614, 1992) -(4229, 1990, 814) -(4670, 3328, 403) -(3935, 3347, 1554) -(328, 0, 67) -(1564, 361, 1576) -(4444, 4758, 1474) -(3188, 4416, 1078) -(4622, 3323, 389) -(4419, 4304, 451) -(4161, 3944, 1520) -(3103, 2509, 1602) -(1783, 4992, 1253) -(138, 257, 1724) -(504, 2774, 1550) -(2245, 3073, 1056) -(1753, 3177, 1355) -(1239, 1308, 1305) -(915, 1439, 1687) -(3387, 1865, 1360) -(3589, 2196, 285) -(2528, 669, 102) -(3768, 3940, 1395) -(3574, 863, 537) -(1356, 1286, 1348) -(444, 4341, 97) -(4891, 2040, 727) -(3873, 104, 494) -(2826, 1582, 1155) -(3511, 4397, 244) -(3428, 3637, 1152) -(3295, 1955, 1160) -(4521, 2182, 1275) -(1706, 3100, 914) -(4501, 1432, 448) -(2554, 2386, 1808) -(3116, 1602, 785) -(4890, 981, 272) -(4934, 2578, 502) -(3782, 1895, 1388) -(684, 4078, 1150) -(3039, 1865, 1895) -(2307, 2688, 526) -(2746, 4512, 486) -(492, 3436, 1760) -(4424, 706, 1825) -(2353, 4993, 1801) -(3061, 4798, 73) -(1742, 3107, 523) -(1478, 2392, 144) -(4661, 2411, 344) -(1378, 1400, 964) -(4943, 4272, 108) -(169, 4184, 1212) -(1938, 2642, 1668) -(3078, 1626, 1773) -(3911, 4687, 709) -(2993, 1525, 1380) -(838, 1391, 1876) -(3379, 2330, 326) -(236, 1484, 1793) -(1892, 1393, 145) -(864, 2225, 579) -(3942, 4468, 56) -(3731, 89, 1511) -(2941, 1229, 1418) -(2357, 784, 1529) -(3123, 259, 1636) -(4636, 890, 1626) -(2600, 2043, 1655) -(2856, 4793, 347) -(4091, 2487, 1751) -(3024, 3659, 521) -(2496, 832, 570) -(159, 3495, 1234) -(4537, 3263, 210) -(4314, 2240, 1633) -(3944, 1387, 397) -(435, 2226, 904) -(1603, 488, 1000) -(2993, 3029, 1883) -(1110, 2731, 72) -(398, 4756, 264) -(4962, 219, 870) -(4687, 1050, 170) -(4397, 3511, 244) -(1118, 1051, 811) -(3930, 1205, 871) -(3914, 2334, 685) -(1909, 4527, 800) -(4118, 1095, 1008) -(3872, 2095, 602) -(4293, 1707, 818) -(3604, 770, 662) -(2466, 2238, 275) -(655, 3776, 1046) -(730, 4672, 1375) -(1925, 3846, 141) -(449, 2945, 1655) -(4869, 654, 424) -(2691, 1887, 1687) -(2379, 1773, 974) -(4202, 2235, 771) -(2718, 4080, 589) -(3835, 2216, 514) -(1333, 1613, 693) -(246, 53, 218) -(487, 2121, 1813) -(2232, 4379, 201) -(4527, 4987, 122) -(4604, 4741, 836) -(3497, 539, 1331) -(227, 4911, 106) -(3753, 2326, 1539) -(2123, 4821, 1490) -(2542, 3320, 548) -(663, 1762, 809) -(3801, 4038, 1124) -(2754, 3974, 924) -(484, 3449, 572) -(567, 930, 1118) -(4742, 1974, 801) -(3743, 835, 517) -(4984, 4129, 1827) -(278, 2975, 1622) -(2102, 3777, 1040) -(1602, 2705, 149) -(2167, 383, 554) -(2823, 2836, 777) -(2206, 1106, 453) -(4471, 4959, 138) -(4574, 2837, 881) -(3519, 315, 1948) -(3166, 1854, 1126) -(2971, 4220, 1990) -(3370, 1101, 1937) -(2975, 3717, 539) -(770, 843, 386) -(3660, 3782, 1083) -(668, 1410, 1633) -(4967, 3838, 1118) -(4433, 3107, 415) -(4354, 2649, 942) -(2393, 386, 608) -(3493, 769, 986) -(978, 4682, 472) -(4259, 4091, 1908) -(1910, 190, 950) -(1157, 510, 891) -(761, 1835, 1007) -(1598, 4608, 126) -(1657, 3140, 258) -(1327, 3419, 1222) -(4109, 3361, 1097) -(1525, 4450, 292) -(669, 1332, 1400) -(615, 2648, 1221) -(3609, 2713, 1344) -(4739, 2078, 688) -(781, 2182, 1664) -(2647, 3715, 882) -(4232, 1240, 1853) -(611, 4350, 1637) -(402, 3945, 1270) -(1959, 4177, 1596) -(275, 489, 71) -(3365, 892, 1021) -(2974, 1133, 433) -(509, 4698, 1632) -(32, 3138, 579) -(3837, 4656, 1912) -(2872, 912, 1393) -(3754, 4015, 1825) -(1953, 2326, 504) -(453, 330, 209) -(299, 4683, 772) -(1182, 2709, 154) -(2789, 3846, 255) -(4027, 252, 596) -(41, 584, 1531) -(4562, 2126, 947) -(2195, 3355, 1343) -(4975, 330, 1631) -(1633, 3617, 249) -(2109, 4449, 1556) -(1937, 2264, 1818) -(4987, 1969, 74) -(1876, 3834, 245) -(4548, 3992, 1500) -(4769, 3361, 1066) -(1640, 2479, 507) -(4895, 2209, 1928) -(89, 3613, 1510) -(4523, 2291, 862) -(1088, 892, 1095) -(3049, 4623, 967) -(676, 805, 427) -(2348, 2714, 647) -(3024, 2996, 783) -(4401, 3998, 847) -(6, 2496, 387) -(3667, 4526, 383) -(4755, 1241, 974) -(22, 1683, 1251) -(4872, 4702, 1370) -(2450, 3910, 1500) -(1132, 2014, 788) -(2275, 3493, 1745) -(2245, 3958, 155) -(1294, 3721, 1072) -(4837, 55, 486) -(4286, 263, 447) -(2305, 4288, 1557) -(1965, 128, 678) -(4893, 2609, 89) -(3061, 3828, 101) -(4157, 422, 1201) -(996, 425, 81) -(1796, 2886, 591) -(446, 1870, 189) -(2857, 2357, 1027) -(2348, 2403, 443) -(934, 678, 184) -(2799, 1440, 1864) -(4010, 2083, 1760) -(1095, 4307, 854) -(4038, 3801, 1124) -(4276, 1916, 701) -(2578, 1665, 401) -(1550, 2005, 1682) -(4545, 3149, 851) -(726, 385, 1865) -(430, 3266, 980) -(2650, 2508, 1018) -(4724, 2008, 972) -(4062, 3131, 831) -(3236, 4202, 942) -(1931, 2346, 1234) -(108, 4524, 573) -(3731, 3740, 1157) -(1927, 1994, 1781) -(494, 197, 401) -(554, 3914, 1554) -(3162, 279, 400) -(4585, 936, 1453) -(4595, 882, 1728) -(3790, 1421, 1721) -(2121, 91, 985) -(2889, 3741, 453) -(2206, 3889, 1432) -(3034, 3038, 440) -(2550, 4384, 1696) -(3229, 1635, 1935) -(2716, 1140, 1333) -(274, 3605, 1464) -(1106, 2206, 453) -(2161, 3439, 443) -(1379, 4239, 686) -(671, 3622, 1886) -(1955, 973, 246) -(1102, 4409, 87) -(1618, 1210, 107) -(23, 2379, 623) -(886, 2897, 275) -(1951, 2757, 1880) -(2891, 4924, 1029) -(3075, 1115, 1251) -(1847, 775, 1143) -(2996, 4488, 1624) -(3701, 2688, 1494) -(125, 375, 422) -(3427, 1747, 633) -(2469, 3984, 1215) -(2921, 4254, 430) -(4981, 2877, 77) -(4410, 4559, 1220) -(1892, 3239, 1749) -(198, 2246, 1254) -(2049, 333, 1140) -(2817, 1787, 1381) -(3742, 861, 546) -(4972, 742, 1847) -(4341, 1598, 604) -(4534, 4651, 501) -(3696, 91, 954) -(3408, 464, 1364) -(2241, 3757, 181) -(1320, 2417, 1735) -(2785, 2528, 803) -(404, 4964, 1846) -(3869, 1082, 1015) -(302, 2696, 1480) -(905, 3585, 1073) -(3963, 2089, 351) -(2342, 3581, 1551) -(3243, 2751, 802) -(3154, 2062, 950) -(2443, 4730, 465) -(325, 2031, 92) -(3335, 1599, 563) -(974, 3349, 1486) -(18, 1368, 1748) -(2361, 3285, 1360) -(1337, 3139, 771) -(543, 1280, 830) -(121, 2025, 889) -(4534, 949, 1581) -(4520, 1859, 195) -(1232, 767, 1140) -(2515, 2941, 747) -(4064, 3480, 1690) -(2713, 3609, 1344) -(3051, 1719, 387) -(1797, 2612, 207) -(2785, 1843, 135) -(4080, 4666, 760) -(68, 2019, 1384) -(4345, 1487, 1778) -(3844, 4098, 1166) -(1825, 2731, 581) -(3711, 3904, 249) -(4020, 923, 849) -(3749, 1635, 1414) -(2468, 4605, 283) -(1818, 4536, 195) -(2890, 158, 1261) -(4555, 4068, 399) -(4573, 1672, 1162) -(3957, 448, 1604) -(2286, 83, 1824) -(714, 80, 116) -(2641, 192, 489) -(3147, 4969, 1016) -(477, 2506, 76) -(483, 3138, 261) -(3023, 938, 1103) -(4373, 4739, 448) -(3596, 4658, 384) -(4824, 869, 153) -(1509, 975, 804) -(3541, 1114, 93) -(731, 4075, 339) -(690, 41, 71) -(1576, 861, 1033) -(4353, 2859, 1473) -(2648, 3839, 495) -(3726, 3196, 1437) -(2330, 3990, 1329) -(2714, 4091, 879) -(1858, 2236, 1467) -(2563, 2767, 295) -(1252, 49, 1357) -(4726, 3249, 320) -(3817, 831, 907) -(187, 2221, 389) -(2232, 122, 1736) -(3783, 1105, 594) -(437, 1961, 1133) -(1957, 4628, 362) -(3251, 3929, 1682) -(3718, 2164, 1391) -(1432, 1383, 444) -(1638, 3291, 189) -(1815, 4617, 289) -(2430, 3452, 291) -(3075, 955, 261) -(3993, 3804, 1789) -(3402, 3775, 1411) -(2138, 2232, 848) -(229, 1734, 405) -(957, 3399, 1220) -(2256, 799, 173) -(2044, 2013, 278) -(4227, 2216, 1573) -(2098, 1818, 1613) -(3900, 821, 546) -(524, 3058, 1280) -(543, 3990, 139) -(2690, 2998, 1189) -(4514, 4748, 1768) -(3749, 2528, 711) -(807, 1585, 279) -(2658, 2653, 1141) -(4202, 1731, 1865) -(2200, 2698, 1553) -(1016, 276, 1990) -(3203, 1784, 195) -(3839, 4413, 803) -(4155, 603, 932) -(1131, 4037, 1489) -(3016, 3145, 191) -(892, 416, 1649) -(1061, 1794, 1168) -(1888, 3742, 222) -(1932, 499, 757) -(3714, 2068, 1270) -(1079, 2734, 1149) -(3974, 2754, 924) -(4436, 4179, 398) -(4301, 1822, 1751) -(1554, 4680, 728) -(1837, 42, 681) -(4931, 187, 1562) -(2712, 2689, 1162) -(186, 303, 1983) -(4199, 899, 352) -(2757, 548, 349) -(2939, 705, 219) -(1599, 4136, 731) -(3921, 1481, 55) -(1139, 4442, 1666) -(4795, 664, 1926) -(4944, 62, 618) -(124, 503, 1579) -(832, 4376, 657) -(3363, 4276, 920) -(4662, 3184, 1613) -(2373, 3711, 1342) -(2498, 2470, 572) -(1340, 2037, 1959) -(3035, 3704, 1398) -(1607, 1061, 1716) -(2040, 2189, 418) -(1917, 909, 236) -(3708, 4747, 1031) -(1169, 3267, 755) -(3020, 1961, 1524) -(4276, 55, 1542) -(3590, 2533, 1815) -(3234, 2951, 899) -(3753, 4071, 923) -(3487, 615, 1922) -(470, 4854, 1613) -(1249, 4077, 797) -(4561, 4768, 544) -(808, 4256, 1063) -(4233, 1568, 1190) -(620, 3974, 1768) -(1852, 1187, 1072) -(2253, 261, 716) -(3845, 2105, 1381) -(4711, 1034, 1237) -(3892, 296, 1777) -(4533, 3208, 1498) -(2025, 453, 1589) -(2059, 754, 778) -(4290, 2062, 1553) -(3832, 2517, 1426) -(4634, 525, 577) -(3793, 2857, 1308) -(1797, 2039, 1961) -(4901, 3242, 405) -(155, 3291, 1271) -(1551, 1035, 173) -(3187, 2548, 948) -(2053, 3212, 1271) -(2153, 4281, 763) -(3073, 380, 716) -(3023, 4989, 1975) -(4118, 903, 1992) -(2534, 182, 418) -(829, 857, 375) -(2004, 4194, 1567) -(937, 1938, 1604) -(2641, 1531, 854) -(830, 2983, 287) -(2216, 2266, 1892) -(1881, 439, 1966) -(1673, 3290, 1413) -(3466, 447, 1772) -(3304, 4440, 1074) -(3921, 806, 374) -(3972, 678, 163) -(4158, 628, 860) -(469, 353, 382) -(2500, 1368, 381) -(1215, 2640, 1685) -(1287, 3015, 1577) -(196, 1038, 123) -(348, 3234, 292) -(3235, 466, 1942) -(631, 981, 1509) -(4541, 2206, 386) -(1431, 4955, 261) -(3203, 880, 360) -(4721, 2093, 135) -(3916, 2743, 1624) -(766, 1759, 325) -(891, 2140, 1719) -(4973, 3275, 1050) -(1050, 1141, 1894) -(574, 4114, 342) -(1864, 1197, 635) -(566, 4248, 1334) -(3224, 639, 1172) -(1613, 1486, 1537) -(3095, 2763, 1864) -(4242, 1605, 549) -(2212, 3236, 1120) -(2873, 742, 227) -(3881, 2217, 1723) -(4276, 4448, 533) -(3634, 231, 473) -(2861, 1617, 1402) -(51, 1278, 744) -(3905, 4167, 1881) -(4143, 2001, 324) -(469, 3032, 1270) -(1860, 1622, 650) -(4887, 260, 1664) -(3514, 2485, 132) -(2756, 3356, 1740) -(924, 4977, 1700) -(1860, 3144, 621) -(1365, 1654, 1846) -(494, 1113, 1806) -(120, 826, 1069) -(902, 333, 657) -(1016, 1753, 1754) -(1904, 3680, 796) -(676, 185, 1595) -(3453, 4781, 398) -(718, 3712, 881) -(440, 833, 856) -(4995, 4871, 1593) -(4011, 1981, 1067) -(4111, 943, 497) -(988, 4051, 72) -(351, 705, 933) -(2977, 4338, 1634) -(857, 3248, 400) -(4426, 310, 1545) -(4460, 2523, 1711) -(83, 4527, 457) -(1719, 2940, 1992) -(1814, 799, 1102) -(1766, 2017, 644) -(3656, 224, 950) -(2774, 2991, 1941) -(1305, 3564, 1490) -(4374, 4403, 1014) -(262, 3426, 362) -(4035, 1961, 1988) -(1130, 2551, 135) -(1592, 2092, 734) -(3274, 2615, 1848) -(2105, 776, 1003) -(1448, 176, 1149) -(3617, 1941, 1294) -(4183, 2194, 1575) -(885, 2803, 1656) -(1250, 2992, 1549) -(4580, 3687, 1140) -(1570, 1171, 1567) -(693, 2336, 487) -(4213, 1143, 277) -(3244, 774, 1764) -(3617, 356, 1308) -(3929, 2882, 1329) -(2325, 1871, 479) -(2215, 2096, 1282) -(3100, 3086, 1023) -(3677, 1656, 1404) -(3680, 452, 1612) -(214, 2428, 1448) -(2332, 4936, 796) -(1093, 1718, 437) -(3481, 1065, 1633) -(505, 956, 838) -(4283, 1597, 569) -(1443, 1720, 1832) -(2441, 3136, 571) -(4275, 2345, 810) -(333, 2402, 1122) -(1377, 2220, 1542) -(3026, 3490, 255) -(952, 4654, 1427) -(4553, 230, 1901) -(1267, 4561, 657) -(1195, 4188, 795) -(2345, 4860, 1678) -(791, 4745, 1164) -(1676, 1745, 1865) -(400, 3774, 1954) -(2684, 2797, 1851) -(4202, 1045, 1679) -(1401, 1603, 267) -(1293, 3095, 1719) -(487, 3714, 102) -(3706, 3922, 248) -(3611, 608, 1023) -(1282, 3024, 868) -(2652, 3487, 995) -(712, 184, 835) -(4957, 3826, 998) -(1316, 4419, 963) -(1886, 1740, 1135) -(4398, 3900, 1303) -(201, 2537, 195) -(273, 3860, 757) -(4564, 1312, 102) -(1119, 2678, 617) -(2536, 3708, 500) -(4029, 1550, 415) -(509, 658, 650) -(4788, 2191, 1508) -(3908, 2017, 1339) -(1394, 4238, 648) -(331, 1415, 1098) -(4078, 465, 1851) -(4404, 4, 1741) -(279, 1215, 807) -(4834, 4085, 1242) -(4028, 3530, 1778) -(3194, 2810, 1371) -(3930, 1468, 793) -(1086, 315, 1407) -(4814, 4315, 1952) -(2695, 3475, 1676) -(162, 4419, 1676) -(4836, 3286, 683) -(3227, 3806, 61) -(3576, 1752, 425) -(3136, 2441, 571) -(899, 4199, 352) -(1352, 2106, 1165) -(824, 159, 1564) -(4792, 3924, 751) -(4107, 1232, 1554) -(1928, 2019, 1078) -(49, 4339, 1770) -(2695, 3360, 1713) -(2953, 833, 1998) -(1643, 2046, 1809) -(4001, 2935, 356) -(528, 1251, 463) -(2200, 4400, 892) -(4854, 2272, 412) -(2764, 1285, 727) -(2381, 3795, 1809) -(4981, 1233, 460) -(1610, 4395, 580) -(3802, 2381, 712) -(4982, 2190, 1613) -(39, 1238, 157) -(3814, 1604, 1937) -(4854, 505, 657) -(44, 4468, 672) -(2627, 2380, 1806) -(2733, 227, 1101) -(4527, 1909, 800) -(630, 4329, 1612) -(449, 2105, 1277) -(4684, 664, 1548) -(3633, 2466, 1498) -(1290, 3527, 904) -(50, 2945, 1943) -(860, 1718, 1075) -(91, 1343, 713) -(470, 3495, 979) -(224, 3656, 950) -(1761, 4321, 175) -(4120, 2278, 1065) -(1740, 1813, 577) -(2819, 3215, 1864) -(4923, 929, 1794) -(3303, 4259, 1173) -(338, 2924, 1252) -(149, 4160, 1907) -(2654, 526, 1292) -(4539, 952, 329) -(4945, 1245, 1240) -(3225, 1263, 763) -(4639, 1573, 463) -(589, 1509, 1948) -(1821, 2293, 975) -(1679, 102, 242) -(3461, 1631, 690) -(3977, 3646, 1878) -(4306, 3093, 1149) -(3940, 3094, 490) -(138, 3159, 489) -(3606, 3818, 379) -(340, 1873, 102) -(4287, 1439, 1505) -(3823, 2417, 1082) -(795, 1719, 584) -(214, 2738, 1403) -(4865, 3286, 503) -(1775, 1378, 1386) -(1710, 4179, 1709) -(3984, 4298, 1803) -(3016, 4050, 1499) -(1015, 2376, 51) -(559, 2278, 1514) -(280, 4271, 1868) -(3046, 3102, 1127) -(460, 3150, 723) -(1174, 1321, 466) -(3011, 2793, 1496) -(3904, 4453, 1661) -(2563, 4275, 1509) -(2883, 70, 619) -(614, 1161, 929) -(597, 716, 1728) -(634, 498, 1845) -(2286, 2871, 1762) -(689, 2737, 937) -(2706, 3297, 1773) -(270, 1142, 312) -(4696, 3440, 720) -(624, 704, 1789) -(2355, 3483, 1488) -(2739, 903, 1553) -(4389, 452, 1780) -(115, 1691, 1542) -(4330, 3671, 1698) -(968, 275, 1774) -(3938, 1467, 1376) -(2556, 2273, 966) -(128, 970, 708) -(952, 1366, 1866) -(1974, 4779, 1140) -(236, 260, 1770) -(3846, 1925, 141) -(2857, 1409, 1500) -(1889, 2146, 544) -(4394, 3048, 1449) -(3075, 866, 777) -(2554, 2574, 1685) -(4571, 2523, 252) -(1410, 73, 1233) -(2103, 881, 582) -(2275, 244, 1890) -(1103, 3420, 442) -(53, 246, 218) -(1165, 3651, 1099) -(4239, 1704, 387) -(2992, 2526, 126) -(2554, 2923, 429) -(1068, 3496, 1110) -(90, 535, 1294) -(833, 2689, 1734) -(4276, 2171, 1429) -(3303, 3401, 360) -(3081, 1018, 543) -(3196, 2815, 919) -(3512, 82, 1603) -(4837, 1830, 1178) -(4109, 4985, 544) -(578, 4770, 877) -(607, 1167, 906) -(1840, 508, 1789) -(4936, 3657, 683) -(4093, 3724, 1048) -(892, 4852, 1560) -(1382, 119, 1089) -(3090, 1713, 936) -(4994, 645, 116) -(2682, 4819, 653) -(4081, 3428, 1473) -(2140, 1048, 435) -(3487, 2652, 995) -(3657, 4936, 683) -(1236, 3940, 731) -(56, 923, 693) -(1983, 3239, 1995) -(2735, 1794, 180) -(4746, 4682, 215) -(1732, 2021, 1681) -(912, 2878, 818) -(3320, 839, 739) -(1724, 3817, 1766) -(3741, 2741, 1322) -(1018, 3081, 543) -(2005, 3469, 652) -(999, 2860, 1782) -(4871, 478, 752) -(4076, 2084, 1530) -(4702, 4799, 1500) -(1362, 3713, 1291) -(1353, 3730, 1688) -(2095, 4515, 265) -(4412, 4338, 857) -(145, 2861, 1635) -(3748, 1055, 1254) -(2603, 4345, 1111) -(535, 1558, 611) -(2018, 2833, 599) -(3751, 1940, 1949) -(518, 1043, 272) -(379, 250, 1177) -(2704, 3152, 474) -(812, 3246, 388) -(40, 1356, 217) -(1124, 4036, 718) -(3174, 3487, 762) -(845, 2853, 1334) -(1654, 4101, 318) -(1764, 4528, 462) -(3346, 2182, 858) -(1809, 2454, 1485) -(3221, 3686, 809) -(1346, 4600, 1855) -(3522, 1391, 857) -(272, 4997, 1869) -(1875, 417, 134) -(4848, 2061, 909) -(2350, 1736, 717) -(1597, 4283, 569) -(2302, 2241, 1444) -(1615, 2882, 851) -(3371, 1054, 1783) -(4208, 3652, 107) -(1425, 3050, 1088) -(3237, 3756, 533) -(2414, 1566, 272) -(4072, 597, 1510) -(3182, 2904, 179) -(1254, 3349, 1310) -(955, 3235, 1174) -(12, 4581, 1063) -(3021, 2865, 603) -(24, 1539, 561) -(2560, 997, 373) -(3057, 3737, 1352) -(693, 3595, 1960) -(2743, 3916, 1624) -(3045, 4316, 1444) -(154, 3494, 1995) -(2260, 4408, 532) -(2485, 348, 1626) -(1771, 3558, 931) -(1984, 2785, 1480) -(2412, 1720, 1366) -(4161, 2243, 1645) -(1124, 3721, 1021) -(1348, 1315, 247) -(53, 3936, 718) -(1802, 4870, 1474) -(4906, 499, 326) -(1155, 1675, 1129) -(1542, 21, 138) -(3408, 1500, 1940) -(4830, 4907, 1960) -(2903, 4750, 673) -(1071, 1069, 624) -(2967, 1858, 308) -(2854, 300, 1153) -(4236, 2135, 380) -(1284, 4692, 1448) -(1902, 23, 1538) -(4861, 4336, 962) -(4040, 4324, 1849) -(2995, 2440, 140) -(2578, 3808, 608) -(3922, 1773, 1552) -(3962, 3600, 421) -(722, 3587, 836) -(2815, 4455, 192) -(4400, 575, 310) -(4017, 1543, 1408) -(4415, 3268, 1801) -(3621, 337, 446) -(930, 4277, 1001) -(312, 2992, 1283) -(2241, 3553, 1090) -(531, 1711, 653) -(2955, 4891, 1401) -(1827, 4582, 84) -(4060, 4195, 1421) -(3763, 1920, 96) -(194, 2595, 961) -(2569, 2968, 1536) -(2955, 928, 1712) -(4168, 954, 642) -(4077, 1312, 428) -(2712, 3636, 1739) -(4140, 2196, 1004) -(3385, 3589, 119) -(2633, 2049, 859) -(709, 3056, 365) -(3257, 3263, 1893) -(2407, 3416, 994) -(1715, 2170, 1450) -(4680, 3669, 381) -(1364, 1687, 791) -(1041, 4624, 479) -(1199, 1953, 946) -(1622, 1860, 650) -(3460, 3063, 382) -(347, 4164, 1986) -(1544, 2930, 1675) -(1908, 3687, 1632) -(2566, 603, 123) -(318, 4248, 884) -(1830, 4837, 1178) -(4688, 4428, 614) -(2659, 4114, 409) -(522, 2255, 1416) -(715, 746, 406) -(1368, 18, 1748) -(1930, 4746, 881) -(1702, 139, 418) -(413, 681, 56) -(1985, 4874, 1644) -(385, 2276, 976) -(2154, 4146, 398) -(933, 1774, 999) -(4124, 911, 883) -(2592, 592, 645) -(1030, 3640, 198) -(526, 1795, 1142) -(3926, 4252, 168) -(474, 1722, 315) -(2500, 3713, 1959) -(4408, 635, 1364) -(2867, 3262, 1492) -(4576, 1678, 1240) -(4479, 4221, 1185) -(574, 3087, 1076) -(3179, 901, 1906) -(3612, 2743, 317) -(1063, 3725, 522) -(3054, 3655, 468) -(4291, 4648, 620) -(4365, 4369, 1967) -(4013, 764, 1868) -(321, 2579, 1199) -(1758, 4709, 1964) -(1939, 4173, 1252) -(2618, 4551, 554) -(291, 2279, 220) -(4512, 1635, 1642) -(1502, 3879, 82) -(318, 600, 1976) -(235, 3270, 1164) -(2118, 590, 1491) -(1539, 24, 561) -(2450, 2528, 374) -(1393, 1224, 1038) -(3406, 2015, 1062) -(4315, 4814, 1952) -(4037, 1131, 1489) -(4088, 1717, 1738) -(4965, 1964, 1172) -(1035, 745, 570) -(1764, 2673, 652) -(1402, 2277, 1238) -(3821, 1776, 516) -(4301, 21, 1381) -(2746, 2427, 200) -(4169, 1021, 1602) -(1845, 1476, 1616) -(1797, 1973, 1885) -(1921, 3484, 972) -(2614, 2310, 148) -(274, 3187, 808) -(3438, 2108, 643) -(4266, 1236, 1458) -(225, 2977, 1702) -(2262, 2115, 1537) -(1324, 4581, 1900) -(1763, 4335, 1132) -(4339, 3154, 82) -(4321, 3555, 728) -(615, 384, 899) -(935, 2922, 1462) -(508, 1840, 1789) -(2348, 4237, 637) -(931, 449, 1699) -(4702, 4872, 1370) -(4398, 813, 1736) -(2111, 3313, 1416) -(3642, 1375, 1507) -(1179, 737, 381) -(4487, 2896, 1115) -(131, 4830, 846) -(1297, 1068, 979) -(4059, 2288, 606) -(227, 1360, 723) -(2713, 3613, 1375) -(4437, 3215, 1360) -(1721, 2940, 1893) -(4485, 131, 611) -(2606, 924, 181) -(2118, 762, 787) -(4047, 4824, 774) -(3566, 487, 577) -(32, 2073, 1961) -(4269, 4473, 1857) -(4119, 2422, 550) -(3937, 1134, 133) -(2484, 1888, 1559) -(2188, 3941, 1916) -(3286, 1449, 574) -(1346, 4086, 1512) -(2462, 4720, 807) -(3073, 4547, 1070) -(368, 2937, 230) -(2137, 175, 123) -(425, 253, 1680) -(3041, 4670, 942) -(3183, 1775, 1712) -(1979, 2710, 581) -(3511, 1771, 521) -(1410, 1127, 1128) -(3663, 2893, 308) -(719, 45, 1426) -(2319, 3932, 1350) -(2932, 1429, 277) -(4733, 3625, 1268) -(1768, 4911, 875) -(1535, 2671, 394) -(1660, 2861, 1143) -(2979, 776, 686) -(622, 4419, 883) -(1048, 2019, 1728) -(1153, 851, 1600) -(3914, 4596, 1823) -(978, 3016, 1893) -(157, 4484, 731) -(4788, 177, 1495) -(1071, 1326, 458) -(2491, 2870, 1804) -(781, 3163, 1692) -(4135, 2429, 545) -(40, 4493, 1388) -(320, 2714, 669) -(3956, 3267, 1773) -(444, 3280, 894) -(4756, 4223, 1865) -(4820, 2014, 785) -(2882, 1920, 1120) -(789, 2788, 746) -(1599, 4696, 746) -(4791, 1199, 774) -(2608, 4404, 1758) -(3384, 2710, 751) -(2848, 4867, 586) -(3188, 2020, 1727) -(2126, 2045, 929) -(695, 1135, 1410) -(3474, 1904, 1892) -(519, 1312, 1843) -(2586, 3700, 675) -(1297, 1982, 439) -(778, 2758, 1758) -(105, 950, 1226) -(3479, 674, 1900) -(625, 191, 1993) -(4338, 4412, 857) -(4502, 4934, 1557) -(3854, 3828, 263) -(4995, 1776, 749) -(3069, 1323, 664) -(79, 4603, 873) -(1163, 2762, 1365) -(1820, 401, 1732) -(4073, 2772, 1344) -(4460, 2162, 1603) -(2237, 3102, 1519) -(3176, 3958, 709) -(1705, 2051, 160) -(3052, 2009, 1258) -(2232, 2138, 848) -(4092, 4163, 1723) -(3926, 4832, 1002) -(4024, 466, 1017) -(773, 3686, 993) -(120, 3160, 498) -(4025, 824, 507) -(3468, 2987, 755) -(2517, 4774, 1797) -(4304, 4754, 512) -(3431, 1599, 1033) -(4460, 1717, 926) -(2608, 2600, 825) -(2443, 2500, 467) -(777, 4993, 924) -(4551, 2618, 554) -(3240, 3278, 1257) -(4584, 3644, 794) -(774, 4489, 861) -(994, 1825, 403) -(512, 2866, 971) -(4424, 1911, 1446) -(3400, 4536, 1788) -(1100, 3377, 983) -(3360, 4202, 1068) -(1630, 3646, 903) -(70, 268, 1283) -(2639, 4215, 84) -(471, 1735, 802) -(4218, 4111, 1105) -(4627, 4499, 1918) -(3090, 1687, 1071) -(2434, 3760, 1229) -(3801, 2736, 1056) -(2576, 4964, 758) -(3256, 4532, 1979) -(3810, 2182, 933) -(3082, 1799, 1497) -(744, 3467, 192) -(1390, 1842, 1352) -(1637, 1363, 767) -(1852, 924, 1675) -(4880, 416, 1976) -(3784, 2909, 1820) -(3774, 1965, 295) -(3282, 3090, 1496) -(4409, 1102, 87) -(622, 1847, 1328) -(2331, 4790, 65) -(751, 3206, 368) -(3005, 2033, 676) -(4897, 3747, 364) -(4050, 4396, 1777) -(1964, 4032, 315) -(1030, 2431, 591) -(4738, 4098, 1651) -(4283, 4671, 1366) -(4282, 361, 544) -(2986, 3276, 1082) -(950, 105, 1226) -(4223, 2269, 1900) -(1774, 4271, 55) -(3062, 3965, 902) -(863, 3572, 1439) -(141, 3466, 394) -(3890, 3756, 1117) -(1558, 163, 1986) -(1740, 3330, 152) -(2160, 1995, 305) -(3998, 2930, 729) -(923, 3662, 837) -(387, 3606, 593) -(4931, 45, 1420) -(2218, 743, 875) -(3564, 2170, 98) -(2858, 3820, 707) -(1683, 974, 835) -(3260, 3695, 1210) -(3213, 4295, 1950) -(1308, 4513, 876) -(4554, 3028, 479) -(501, 3600, 483) -(2043, 2600, 1655) -(2676, 1545, 914) -(2869, 4588, 784) -(1696, 1948, 609) -(2170, 1715, 1450) -(1838, 2262, 1376) -(2279, 291, 220) -(2120, 696, 1014) -(2176, 1166, 1354) -(3875, 3683, 1864) -(3333, 4590, 386) -(2310, 2555, 999) -(1408, 4956, 653) -(1120, 2464, 1464) -(1, 4742, 1279) -(1702, 4012, 1112) -(545, 3616, 909) -(1954, 3374, 1393) -(3690, 989, 267) -(1644, 3843, 168) -(2741, 4179, 1369) -(916, 365, 98) -(3933, 2881, 193) -(1021, 3444, 1689) -(4427, 41, 1217) -(4453, 200, 417) -(3027, 4635, 173) -(505, 1356, 304) -(3616, 76, 340) -(3160, 120, 498) -(1397, 4069, 1705) -(4871, 4252, 902) -(46, 1673, 657) -(168, 900, 1547) -(1525, 4301, 1436) -(3686, 773, 993) -(2766, 604, 634) -(1036, 4044, 606) -(3142, 2343, 600) -(2283, 4779, 173) -(3786, 735, 1973) -(3396, 1519, 1300) -(2118, 1791, 68) -(1963, 4675, 852) -(4673, 2319, 1540) -(3191, 1262, 217) -(3896, 3042, 86) -(649, 4997, 872) -(2992, 312, 1283) -(754, 2059, 778) -(2913, 4673, 1850) -(876, 4931, 824) -(3868, 2846, 1861) -(4684, 885, 207) -(1965, 1727, 1931) -(40, 2878, 65) -(3542, 2587, 1674) -(3186, 657, 396) -(4735, 282, 1424) -(877, 4859, 1910) -(1655, 4052, 1043) -(127, 4333, 1534) -(416, 1535, 747) -(3114, 3418, 734) -(2813, 3417, 1074) -(4478, 3545, 245) -(1599, 405, 176) -(3727, 1040, 619) -(4874, 1212, 1895) -(3285, 659, 549) -(18, 2103, 457) -(1402, 1807, 229) -(2367, 358, 1584) -(3910, 2450, 1500) -(1703, 2639, 1146) -(4046, 990, 328) -(2546, 4655, 52) -(1391, 1507, 1455) -(4494, 3065, 1641) -(3990, 2330, 1329) -(23, 4791, 633) -(795, 3974, 704) -(1399, 3636, 1219) -(3611, 4455, 751) -(1418, 1045, 1767) -(113, 2380, 94) -(4593, 2583, 277) -(674, 3301, 1866) -(3196, 4268, 423) -(3370, 1026, 1207) -(2591, 1967, 356) -(99, 3202, 882) -(2527, 1021, 51) -(77, 710, 1428) -(2374, 4957, 1914) -(3064, 558, 231) -(453, 3494, 1818) -(750, 4292, 444) -(2946, 3413, 1931) -(2251, 821, 735) -(3014, 3253, 727) -(2075, 4141, 1651) -(1317, 46, 748) -(4463, 308, 398) -(1936, 3872, 296) -(2937, 3316, 1451) -(2422, 1660, 929) -(1147, 454, 373) -(731, 4841, 451) -(1129, 3207, 853) -(4516, 1854, 1434) -(3702, 1269, 307) -(4861, 4698, 1238) -(58, 3937, 1996) -(910, 2234, 1623) -(3374, 4151, 952) -(4566, 1196, 891) -(2772, 26, 1842) -(3075, 4160, 1293) -(60, 3562, 553) -(1557, 4444, 1538) -(1786, 4842, 1496) -(3330, 2735, 1789) -(3541, 1213, 95) -(1154, 4241, 1591) -(672, 1260, 1202) -(2097, 3118, 575) -(92, 4068, 671) -(3058, 2035, 1323) -(2662, 1461, 1028) -(2927, 851, 959) -(2726, 1499, 967) -(2010, 4112, 1532) -(1671, 1117, 759) -(3836, 3614, 1120) -(272, 2162, 1103) -(3161, 1482, 248) -(3502, 2588, 1913) -(3610, 513, 1311) -(2209, 4895, 1928) -(3494, 3036, 286) -(2793, 3011, 1496) -(2892, 1318, 1572) -(4313, 2924, 745) -(4474, 3714, 253) -(2129, 3586, 1009) -(3822, 300, 1801) -(3444, 4103, 1389) -(718, 2682, 359) -(3555, 3333, 1565) -(340, 3112, 394) -(1762, 2607, 1363) -(2465, 3584, 1994) -(1134, 3138, 1058) -(294, 2309, 948) -(3143, 2164, 211) -(3267, 335, 499) -(794, 3029, 319) -(3834, 1078, 673) -(4465, 2380, 1427) -(1364, 707, 1361) -(4384, 2550, 1696) -(1573, 305, 892) -(486, 3905, 1094) -(95, 4017, 255) -(2942, 3095, 816) -(512, 338, 1181) -(43, 4832, 1423) -(3138, 32, 579) -(2828, 431, 873) -(406, 2866, 784) -(2372, 4761, 55) -(2939, 4742, 676) -(4095, 1474, 717) -(4396, 2480, 87) -(3656, 2449, 817) -(3823, 819, 1986) -(4895, 4735, 718) -(853, 1690, 926) -(3127, 2564, 865) -(1971, 4735, 1860) -(1362, 1667, 693) -(3247, 1911, 986) -(4294, 2342, 1736) -(1270, 3372, 1199) -(3611, 3509, 409) -(4067, 2846, 345) -(2506, 2443, 1176) -(4207, 427, 1988) -(962, 2765, 518) -(1185, 3078, 1885) -(4762, 1444, 1529) -(703, 3618, 1929) -(3449, 687, 1702) -(1166, 3983, 1041) -(2470, 1612, 749) -(2072, 1067, 214) -(1239, 3769, 657) -(1400, 885, 1273) -(4139, 4499, 926) -(3284, 3216, 674) -(2711, 4723, 1249) -(3667, 2218, 1892) -(3274, 1926, 392) -(2468, 1673, 55) -(141, 1485, 556) -(2024, 2070, 1499) -(339, 1635, 260) -(4402, 2126, 521) -(2218, 908, 1003) -(4491, 1239, 567) -(2486, 3817, 794) -(3569, 1891, 239) -(2226, 435, 904) -(154, 1028, 1600) -(284, 507, 643) -(2450, 1151, 1364) -(1352, 2107, 1381) -(4672, 1480, 308) -(4846, 3464, 272) -(2096, 2215, 1282) -(4225, 4895, 1938) -(2318, 4107, 899) -(4119, 2512, 852) -(2245, 1340, 1923) -(2020, 3733, 840) -(654, 4869, 424) -(4351, 370, 1558) -(3654, 4523, 1164) -(597, 1665, 1749) -(1876, 2968, 662) -(944, 3901, 79) -(1014, 4905, 713) -(2265, 2540, 1194) -(1175, 4610, 170) -(816, 779, 710) -(4546, 620, 1217) -(3766, 897, 1255) -(2692, 2696, 1424) -(3404, 2760, 903) -(3020, 1283, 1650) -(4655, 2007, 725) -(3006, 3246, 479) -(3969, 538, 771) -(2343, 3142, 600) -(1981, 4575, 681) -(3993, 396, 415) -(2083, 139, 1054) -(1687, 1364, 791) -(2094, 451, 425) -(3382, 3113, 1260) -(1931, 2993, 261) -(2914, 1497, 154) -(1037, 2899, 925) -(4619, 1050, 1164) -(3717, 294, 1664) -(2803, 885, 1656) -(4523, 4998, 1375) -(1683, 926, 1481) -(4450, 1414, 809) -(82, 2819, 565) -(2625, 1527, 742) -(3483, 2355, 1488) -(4747, 3222, 1260) -(649, 983, 556) -(1427, 3320, 1265) -(505, 2797, 892) -(1381, 2831, 1993) -(32, 959, 1674) -(3221, 2667, 1125) -(486, 1420, 1982) -(3314, 3882, 1331) -(3470, 633, 537) -(3538, 2337, 1965) -(668, 1464, 58) -(3224, 4969, 1446) -(2791, 1763, 1438) -(2870, 191, 1262) -(471, 1627, 1145) -(4669, 4853, 915) -(839, 2753, 313) -(3853, 4378, 1055) -(3084, 736, 676) -(1427, 529, 274) -(3147, 4259, 1431) -(4875, 3728, 314) -(2235, 1645, 1213) -(240, 641, 1443) -(3196, 2868, 511) -(3755, 1589, 1862) -(2997, 209, 1531) -(1788, 4775, 192) -(2664, 4560, 773) -(2522, 243, 664) -(3689, 825, 346) -(3452, 2430, 291) -(520, 3406, 1224) -(4400, 2200, 892) -(1392, 4645, 424) -(1606, 1736, 1653) -(930, 3957, 1643) -(4335, 352, 742) -(156, 3382, 1632) -(4668, 2165, 875) -(1323, 1434, 877) -(3236, 4588, 1846) -(1477, 40, 1899) -(4215, 1050, 1468) -(639, 3224, 1172) -(3022, 2499, 297) -(4790, 3527, 379) -(4261, 2018, 1875) -(4091, 4259, 1908) -(2892, 2307, 172) -(1267, 387, 104) -(1372, 869, 1398) -(4844, 4423, 1133) -(3360, 1464, 923) -(923, 4020, 849) -(2077, 4093, 680) -(3425, 245, 1890) -(3856, 3678, 101) -(150, 1450, 324) -(3208, 439, 1597) -(2967, 3255, 1703) -(3591, 2002, 1547) -(4251, 4557, 431) -(990, 4651, 1998) -(2334, 1468, 483) -(2878, 40, 65) -(177, 483, 650) -(2832, 4494, 766) -(935, 566, 988) -(4510, 2578, 1912) -(4075, 3346, 371) -(3941, 2188, 1916) -(4586, 3940, 810) -(1825, 994, 403) -(4430, 3121, 689) -(449, 931, 1699) -(3531, 1237, 633) -(2941, 2515, 747) -(251, 1359, 1491) -(2804, 792, 1071) -(4384, 2093, 1278) -(590, 1016, 1710) -(1623, 3522, 1319) -(3412, 3520, 144) -(4327, 1331, 946) -(3374, 3553, 1592) -(1792, 1156, 1908) -(4069, 1718, 279) -(4968, 4674, 1358) -(2981, 4513, 1799) -(3937, 3659, 832) -(4531, 4862, 544) -(2436, 1385, 910) -(1471, 678, 135) -(4560, 2664, 773) -(4466, 3359, 164) -(465, 1381, 556) -(4261, 1574, 1451) -(3924, 2850, 1141) -(1718, 1713, 1397) -(1146, 2218, 57) -(708, 2382, 654) -(2318, 2319, 967) -(245, 4478, 1557) -(4151, 4526, 482) -(588, 3462, 1047) -(219, 2187, 1062) -(606, 2597, 1019) -(1546, 1088, 1181) -(490, 4215, 1945) -(1854, 4516, 1434) -(502, 2784, 682) -(2103, 2253, 1824) -(2391, 4637, 296) -(4964, 2576, 758) -(3967, 4577, 869) -(1844, 1615, 1301) -(1947, 1082, 374) -(3654, 1586, 572) -(26, 2772, 1842) -(4885, 3285, 897) -(997, 1856, 1282) -(4674, 4968, 1358) -(95, 1413, 1923) -(4904, 661, 1890) -(2323, 3022, 672) -(961, 1595, 1856) -(3536, 1217, 1708) -(2846, 4067, 345) -(1383, 1452, 82) -(4646, 3522, 659) -(1096, 4690, 1129) -(96, 3172, 1237) -(4202, 3360, 1068) -(3284, 2639, 1232) -(243, 2522, 664) -(1043, 2078, 219) -(3709, 4763, 1617) -(4686, 3722, 364) -(4210, 707, 1736) -(4990, 4224, 1583) -(712, 2350, 1789) -(2701, 3886, 1590) -(1549, 3076, 84) -(3387, 1925, 813) -(900, 241, 1333) -(1488, 4107, 1071) -(717, 3973, 630) -(2665, 1194, 535) -(3091, 578, 1630) -(1903, 103, 864) -(2449, 1776, 1082) -(4829, 3502, 386) -(878, 2945, 218) -(996, 3201, 1653) -(3957, 3051, 1119) -(2234, 1657, 484) -(1433, 3479, 1348) -(4341, 444, 97) -(3655, 3054, 468) -(2262, 887, 1688) -(4111, 4218, 1105) -(935, 4922, 1084) -(1487, 4345, 1778) -(2998, 3899, 1419) -(560, 2381, 698) -(373, 2452, 1340) -(80, 4356, 1380) -(290, 388, 1133) -(717, 1285, 1575) -(4902, 4501, 1599) -(120, 4548, 422) -(606, 1756, 80) -(2055, 478, 772) -(2648, 610, 1469) -(2011, 1919, 759) -(2356, 3695, 867) -(530, 20, 1108) -(4495, 3834, 1154) -(4587, 3693, 1576) -(423, 3875, 976) -(1485, 1644, 1870) -(2009, 2238, 809) -(1604, 3814, 1937) -(1964, 2427, 712) -(4550, 676, 195) -(1038, 196, 123) -(2810, 4777, 1667) -(4481, 2979, 674) -(2567, 2642, 1183) -(832, 3071, 1905) -(2986, 2527, 671) -(3271, 1084, 945) -(2525, 2393, 470) -(3983, 1166, 1041) -(717, 3007, 1513) -(2085, 2916, 1331) -(272, 4722, 1253) -(107, 2381, 1535) -(4332, 2466, 1371) -(1848, 2323, 1572) -(4927, 797, 1547) -(2298, 4513, 1724) -(2346, 871, 1887) -(2217, 3881, 1723) -(2724, 1168, 1212) -(3365, 1396, 1949) -(232, 3314, 1028) -(2963, 102, 351) -(741, 4539, 264) -(4831, 4149, 328) -(944, 1578, 446) -(1427, 4309, 1060) -(3925, 4611, 1966) -(4424, 227, 1478) -(4500, 2540, 400) -(2688, 53, 1472) -(1683, 2096, 1760) -(285, 1033, 1367) -(3551, 1454, 87) -(1091, 2977, 728) -(3610, 4508, 877) -(3765, 829, 1061) -(1872, 2041, 1010) -(3889, 3683, 1284) -(4555, 2548, 1082) -(2634, 1268, 443) -(4068, 2115, 986) -(252, 186, 50) -(1684, 3442, 1063) -(1479, 662, 1171) -(4151, 2189, 1952) -(3117, 437, 1298) -(1607, 3906, 1307) -(2923, 4877, 875) -(573, 1171, 1227) -(4675, 1839, 681) -(892, 4548, 286) -(1899, 3450, 1981) -(2283, 639, 111) -(893, 874, 1350) -(3078, 32, 1172) -(4575, 570, 280) -(465, 3266, 1369) -(1813, 3752, 882) -(4524, 356, 1619) -(0, 1957, 1215) -(2826, 4658, 1281) -(1062, 4269, 1873) -(1499, 4677, 745) -(4477, 1341, 167) -(1858, 4699, 673) -(3859, 4442, 1997) -(2789, 491, 1321) -(2377, 583, 72) -(4031, 491, 1788) -(1403, 4474, 1139) -(3994, 1078, 1976) -(3726, 1663, 67) -(3312, 4682, 1485) -(2420, 3491, 424) -(2003, 16, 316) -(756, 85, 1970) -(3755, 2812, 835) -(2768, 2372, 1041) -(4533, 267, 617) -(3827, 95, 1783) -(3891, 4165, 1270) -(4526, 4428, 1027) -(4434, 3766, 290) -(4851, 2828, 1312) -(2477, 4509, 1684) -(665, 655, 1171) -(3715, 2699, 802) -(3695, 2547, 205) -(3362, 2853, 1436) -(2476, 1308, 616) -(1727, 3807, 54) -(4262, 2094, 1916) -(306, 3511, 1805) -(120, 414, 109) -(4554, 4860, 1319) -(900, 4169, 902) -(4698, 4756, 269) -(3583, 3683, 1568) -(579, 3245, 569) -(1185, 4656, 750) -(406, 3066, 290) -(3880, 2453, 323) -(2739, 1851, 1172) -(4838, 2197, 765) -(215, 3438, 1478) -(1976, 1816, 768) -(206, 3133, 149) -(3841, 795, 1927) -(1867, 3957, 1708) -(170, 4797, 1599) -(3718, 1347, 611) -(3436, 2280, 927) -(4206, 1194, 1861) -(2203, 154, 1907) -(3895, 2235, 1365) -(2988, 4173, 1591) -(3887, 2083, 964) -(1077, 1707, 539) -(2061, 4848, 909) -(4305, 543, 345) -(4574, 836, 1831) -(3108, 2970, 337) -(4503, 1742, 604) -(2967, 2336, 625) -(916, 2214, 1280) -(868, 67, 1191) -(4239, 721, 792) -(3830, 2219, 1253) -(2743, 3725, 362) -(3874, 4389, 1665) -(419, 4921, 841) -(2332, 4696, 864) -(2834, 2455, 1163) -(1900, 4322, 100) -(271, 182, 78) -(4408, 3232, 1343) -(151, 2928, 1760) -(916, 2947, 787) -(2235, 2670, 834) -(661, 2262, 1765) -(3071, 832, 1905) -(2741, 1192, 270) -(4656, 1185, 750) -(1886, 1244, 313) -(3262, 2003, 70) -(988, 1371, 228) -(4987, 4527, 122) -(4842, 4064, 1658) -(1587, 1249, 1889) -(2541, 4874, 541) -(2501, 2600, 1292) -(1028, 3005, 1048) -(2285, 3457, 1350) -(3331, 2403, 1648) -(4038, 2310, 1388) -(150, 806, 278) -(1199, 1536, 1494) -(3747, 3243, 1956) -(498, 634, 1845) -(566, 3443, 300) -(1421, 1150, 758) -(3978, 2773, 202) -(1448, 2376, 1523) -(1120, 2981, 67) -(3514, 2762, 1462) -(2588, 3502, 1913) -(158, 2890, 1261) -(2925, 4405, 1346) -(4912, 3505, 1642) -(3123, 4947, 821) -(745, 4605, 861) -(2197, 1651, 1807) -(752, 4048, 939) -(371, 3380, 1626) -(2517, 2935, 1024) -(4331, 3740, 1087) -(2662, 99, 1977) -(4305, 4010, 741) -(3947, 2337, 1695) -(4568, 4807, 1472) -(1740, 1886, 1135) -(676, 2293, 1974) -(4651, 4839, 265) -(3700, 3632, 1086) -(4923, 2748, 1971) -(2336, 2967, 625) -(4077, 1287, 1631) -(594, 146, 1435) -(2453, 884, 577) -(933, 2826, 1784) -(3613, 4392, 1727) -(2583, 4593, 277) -(434, 3439, 1484) -(3205, 1818, 567) -(1872, 4404, 412) -(955, 4403, 159) -(3129, 3495, 643) -(2425, 4378, 306) -(4008, 4478, 157) -(3123, 1241, 327) -(4911, 1768, 875) -(3379, 3139, 130) -(3049, 1636, 214) -(2152, 902, 1864) -(1429, 4135, 854) -(3522, 3980, 1346) -(4461, 907, 1958) -(31, 860, 1144) -(4355, 1544, 1212) -(483, 177, 650) -(2976, 4085, 1943) -(2588, 1483, 449) -(2020, 2733, 1397) -(3854, 3300, 749) -(2240, 2699, 112) -(2266, 2537, 603) -(2886, 1456, 661) -(4517, 3118, 1852) -(2580, 39, 1229) -(205, 2311, 845) -(3769, 4353, 457) -(2708, 1546, 1447) -(4468, 200, 1652) -(41, 3429, 1729) -(3967, 3294, 1349) -(243, 1867, 1000) -(431, 2828, 873) -(4961, 1653, 310) -(1585, 4211, 751) -(3966, 4238, 191) -(2689, 4089, 1557) -(482, 3017, 768) -(409, 769, 66) -(2057, 4495, 635) -(521, 2760, 863) -(2522, 4682, 619) -(572, 950, 426) -(2164, 3339, 704) -(4071, 3753, 923) -(2688, 3701, 1494) -(2051, 4233, 1669) -(4940, 1777, 328) -(1935, 1415, 1222) -(1766, 4237, 1144) -(1007, 2067, 422) -(3438, 2947, 867) -(2192, 3150, 799) -(3007, 4465, 1950) -(3183, 210, 1994) -(2533, 963, 560) -(3501, 1677, 317) -(4336, 4977, 1274) -(4177, 4787, 1109) -(4374, 4215, 889) -(3114, 641, 1417) -(508, 3755, 1275) -(656, 2660, 1343) -(1268, 2528, 583) -(3482, 2758, 441) -(4406, 2160, 1094) -(3689, 188, 310) -(2327, 2185, 400) -(4586, 3288, 1621) -(4568, 2883, 1546) -(3346, 3974, 822) -(2057, 849, 1967) -(1268, 2466, 314) -(4025, 3950, 1082) -(1172, 2191, 1607) -(3074, 1850, 1761) -(4473, 4598, 1026) -(4750, 4104, 265) -(3924, 1360, 1604) -(2501, 1534, 1506) -(4902, 3236, 1133) -(4074, 1477, 271) -(2902, 3490, 469) -(3927, 1901, 673) -(4202, 3236, 942) -(3070, 4565, 1819) -(2784, 502, 682) -(296, 1302, 296) -(4277, 930, 1001) -(4707, 2251, 637) -(3016, 3788, 780) -(4138, 504, 1532) -(3973, 3459, 966) -(2188, 3108, 1900) -(1937, 4249, 156) -(4168, 3463, 969) -(3, 3325, 621) -(4936, 3345, 1733) -(1021, 4644, 1589) -(1010, 2635, 1016) -(2570, 2780, 204) -(3058, 2871, 1376) -(2015, 2483, 1833) -(3844, 2620, 1620) -(323, 140, 1217) -(4474, 2881, 507) -(1074, 3215, 167) -(4028, 1415, 1647) -(2021, 812, 845) -(2996, 4120, 1640) -(4, 721, 340) -(742, 2873, 227) -(458, 2969, 1961) -(1931, 2016, 624) -(1808, 2057, 121) -(1667, 1362, 693) -(2273, 4678, 1873) -(1696, 4234, 832) -(4825, 4500, 664) -(2653, 2658, 1141) -(329, 856, 1618) -(787, 4789, 1036) -(1412, 1451, 413) -(3965, 3931, 1349) -(844, 3669, 1245) -(3285, 2361, 1360) -(1116, 1777, 1037) -(2763, 2955, 1686) -(1500, 3408, 1940) -(3751, 2092, 383) -(1422, 3908, 180) -(402, 1234, 800) -(690, 2971, 1866) -(1882, 3868, 1306) -(2472, 3530, 759) -(2019, 1928, 1078) -(3152, 752, 342) -(3790, 973, 151) -(305, 3376, 689) -(3774, 3890, 1254) -(4367, 377, 1513) -(555, 3034, 513) -(4920, 3294, 560) -(1392, 1371, 913) -(4530, 4729, 779) -(4349, 1384, 700) -(452, 4389, 1780) -(1701, 785, 1505) -(2695, 3117, 998) -(1914, 4124, 1349) -(3921, 3263, 58) -(2883, 980, 1886) -(662, 1479, 1171) -(272, 1402, 1651) -(3181, 1491, 669) -(1264, 821, 1991) -(3252, 1711, 708) -(4120, 2996, 1640) -(4201, 1629, 563) -(4555, 3398, 1689) -(3583, 3051, 1251) -(3942, 1543, 326) -(3461, 3240, 300) -(1775, 860, 572) -(272, 1417, 1534) -(682, 400, 1119) -(2387, 1882, 1308) -(4119, 705, 902) -(4015, 3754, 1825) -(2288, 3777, 1590) -(2650, 1512, 794) -(4142, 4673, 71) -(963, 3465, 352) -(25, 44, 1825) -(2979, 3014, 207) -(351, 3587, 1024) -(3248, 857, 400) -(2592, 4629, 1394) -(660, 1455, 629) -(3046, 2682, 715) -(1197, 4993, 460) -(3490, 2789, 631) -(2379, 2918, 1085) -(807, 2932, 630) -(4700, 3020, 1994) -(4065, 118, 1043) -(1439, 1095, 305) -(1354, 1453, 1727) -(952, 613, 1489) -(488, 4282, 1397) -(4401, 994, 1608) -(4160, 4016, 1650) -(4956, 1408, 653) -(2981, 3446, 1853) -(1566, 2414, 272) -(2765, 415, 1562) -(3218, 4427, 226) -(3960, 4407, 144) -(1285, 1790, 473) -(3118, 2097, 575) -(1265, 4531, 1101) -(3586, 2035, 1594) -(3354, 4980, 559) -(1285, 4747, 1393) -(225, 4263, 1956) -(581, 3725, 1574) -(1806, 1432, 1072) -(1457, 3842, 1816) -(4310, 2500, 247) -(4950, 4930, 1655) -(1471, 3192, 138) -(1625, 116, 1580) -(3402, 4608, 1624) -(3742, 4505, 973) -(447, 512, 1852) -(2849, 1665, 830) -(4175, 1562, 1295) -(4266, 1730, 1631) -(4573, 454, 1238) -(371, 120, 129) -(2262, 4738, 386) -(1288, 72, 1894) -(405, 4936, 1656) -(122, 4257, 531) -(2152, 2821, 1646) -(4971, 3238, 1654) -(1102, 4167, 398) -(1281, 2225, 1332) -(2949, 1501, 1802) -(3683, 3583, 1568) -(2231, 1166, 1210) -(1538, 3116, 1961) -(3448, 556, 577) -(3526, 2651, 754) -(3919, 4595, 944) -(2877, 2884, 1433) -(1662, 172, 254) -(956, 505, 838) -(2518, 18, 673) -(3755, 263, 1536) -(1940, 3383, 348) -(4635, 3137, 1155) -(4812, 1227, 1503) -(2992, 2630, 1244) -(4682, 3312, 1485) -(1412, 1956, 1288) -(4020, 1390, 1056) -(3836, 2614, 1503) -(3225, 4265, 846) -(2565, 4755, 1620) -(4074, 2287, 1292) -(4379, 2919, 1705) -(2786, 4365, 989) -(4432, 3664, 126) -(2756, 2897, 712) -(2140, 891, 1719) -(909, 670, 56) -(3380, 4623, 1148) -(1894, 3614, 301) -(1001, 4857, 257) -(2707, 4670, 630) -(4274, 3498, 169) -(1307, 567, 129) -(2089, 3963, 351) -(244, 345, 1287) -(675, 3661, 139) -(548, 2757, 349) -(2547, 3117, 743) -(4500, 308, 1576) -(575, 4400, 310) -(3806, 4136, 1381) -(64, 4519, 847) -(4548, 3312, 1927) -(3680, 2000, 63) -(3316, 4585, 1199) -(917, 2480, 394) -(970, 4602, 1435) -(1742, 2164, 184) -(2579, 321, 1199) -(4032, 989, 948) -(1998, 3488, 673) -(2830, 3627, 1541) -(1030, 2110, 655) -(2277, 3620, 198) -(1554, 2902, 609) -(4124, 3627, 422) -(2625, 3927, 1033) -(2680, 2742, 1002) -(4357, 3367, 1678) -(1544, 4355, 1212) -(3198, 4235, 1276) -(894, 4762, 601) -(1854, 1029, 1220) -(2522, 688, 154) -(4197, 634, 242) -(3021, 4066, 239) -(1491, 1569, 1900) -(1223, 1794, 953) -(4430, 2966, 92) -(4858, 3449, 1619) -(4843, 4199, 607) -(1575, 3413, 1366) -(3554, 115, 1919) -(3830, 2008, 1757) -(2163, 582, 921) -(2901, 1481, 1395) -(2355, 4967, 1755) -(4993, 2353, 1801) -(3498, 4371, 50) -(2658, 4692, 689) -(1666, 1386, 1696) -(2579, 1976, 815) -(2881, 4474, 507) -(1245, 3575, 975) -(1279, 3351, 684) -(3868, 128, 1686) -(501, 3206, 1765) -(2051, 295, 165) -(2578, 4469, 647) -(978, 3070, 1990) -(2753, 385, 1487) -(2527, 3882, 1395) -(3055, 4667, 538) -(1792, 64, 896) -(1779, 2492, 1785) -(4651, 4295, 1568) -(462, 2579, 1111) -(1607, 4198, 654) -(4241, 1154, 1591) -(516, 1870, 114) -(1219, 2645, 615) -(567, 2988, 705) -(3987, 1129, 1840) -(384, 2757, 1112) -(3529, 433, 190) -(1234, 4658, 549) -(3329, 1309, 1076) -(3211, 4248, 1439) -(1811, 3617, 1543) -(465, 4078, 1851) -(3772, 4979, 523) -(3380, 1068, 1056) -(4997, 4426, 545) -(982, 2189, 1574) -(3751, 859, 965) -(1223, 3993, 1611) -(2055, 4786, 735) -(4350, 3224, 909) -(3166, 4497, 1843) -(4856, 703, 219) -(2167, 730, 1486) -(1529, 1583, 1472) -(101, 924, 1289) -(3966, 2150, 542) -(778, 931, 186) -(3020, 2870, 822) -(2591, 55, 1597) -(2917, 4830, 1512) -(3088, 4806, 1481) -(2689, 2712, 1162) -(2250, 1022, 945) -(1104, 357, 245) -(4170, 826, 1686) -(2857, 4342, 627) -(3722, 2425, 555) -(4762, 2242, 371) -(2460, 1333, 1262) -(2056, 4126, 1876) -(4561, 1267, 657) -(4666, 1409, 380) -(3487, 3971, 798) -(1152, 4163, 542) -(2450, 346, 700) -(3968, 509, 1338) -(3506, 532, 499) -(3546, 537, 606) -(705, 351, 933) -(2947, 2786, 754) -(3805, 1131, 1310) -(1760, 4717, 775) -(3217, 2168, 99) -(3970, 385, 437) -(3065, 1837, 771) -(3322, 574, 844) -(2696, 4573, 885) -(2896, 2134, 1719) -(1332, 659, 1643) -(3865, 1125, 1869) -(4813, 3262, 1597) -(1149, 2777, 916) -(4772, 3361, 302) -(439, 2887, 203) -(3957, 598, 632) -(4566, 2250, 1673) -(532, 2743, 392) -(579, 1784, 1270) -(3042, 4146, 1561) -(412, 3977, 1744) -(1119, 1710, 1884) -(4667, 2521, 1179) -(2223, 2757, 748) -(1277, 4156, 926) -(4907, 1494, 872) -(4290, 544, 1622) -(4433, 1603, 362) -(1396, 3465, 1927) -(3378, 828, 905) -(434, 4297, 651) -(4805, 3959, 1219) -(4097, 1722, 707) -(309, 4300, 843) -(4441, 2621, 189) -(3990, 543, 139) -(2517, 3832, 1426) -(3540, 3606, 1304) -(3336, 937, 1330) -(9, 4827, 1315) -(3271, 2304, 1140) -(3539, 1395, 185) -(1928, 3020, 1028) -(129, 3834, 1895) -(4442, 1139, 1666) -(217, 2681, 1456) -(4478, 4448, 1266) -(4766, 4984, 1700) -(973, 4390, 199) -(2195, 4272, 1509) -(2207, 2797, 1352) -(848, 2357, 1252) -(709, 3285, 166) -(557, 2387, 159) -(4767, 340, 388) -(391, 4464, 1698) -(505, 1298, 294) -(3020, 4700, 1994) -(944, 76, 726) -(928, 833, 1524) -(4482, 3088, 617) -(1868, 3206, 416) -(4999, 1621, 593) -(1477, 4074, 271) -(4633, 2148, 340) -(3582, 4270, 1711) -(3951, 3444, 384) -(2475, 4066, 457) -(3400, 1237, 148) -(4252, 3926, 168) -(4359, 2194, 1435) -(1600, 2834, 1608) -(1408, 330, 1146) -(3704, 599, 224) -(2864, 1166, 183) -(4520, 1030, 1388) -(3573, 3863, 1623) -(4204, 2422, 553) -(1609, 2348, 1755) -(2125, 2742, 1939) -(1433, 2301, 483) -(1360, 3499, 1296) -(3574, 4842, 1979) -(3468, 4557, 586) -(2301, 3081, 702) -(4334, 2361, 201) -(3960, 1328, 69) -(2183, 2855, 1482) -(1200, 2327, 1084) -(15, 2831, 1359) -(3600, 1409, 1358) -(258, 822, 1365) -(4904, 775, 1543) -(1312, 1129, 1969) -(2196, 2514, 1209) -(621, 767, 1352) -(2172, 4070, 69) -(3936, 4929, 951) -(282, 4376, 353) -(4910, 1265, 1889) -(1200, 202, 809) -(1635, 2349, 617) -(2580, 698, 282) -(2271, 4819, 1952) -(1598, 2690, 1709) -(2118, 191, 1426) -(2232, 648, 1895) -(908, 3891, 376) -(3264, 881, 317) -(1999, 669, 660) -(2670, 4128, 314) -(4718, 937, 1378) -(4239, 368, 1623) -(4009, 57, 611) -(3740, 3731, 1157) -(3317, 244, 760) -(2711, 447, 1876) -(2389, 4128, 600) -(4437, 3675, 114) -(1350, 4971, 786) -(1443, 4183, 1693) -(742, 1079, 1768) -(2777, 297, 527) -(3745, 2144, 1678) -(1763, 2879, 80) -(1956, 1015, 555) -(639, 717, 273) -(3748, 4953, 813) -(3652, 822, 1641) -(2097, 3770, 622) -(1004, 817, 1703) -(4469, 2578, 647) -(996, 1534, 1571) -(2054, 1720, 1295) -(3436, 373, 946) -(398, 3227, 262) -(2959, 3106, 866) -(390, 1188, 1309) -(4629, 3702, 1935) -(1759, 1811, 334) -(1069, 1071, 624) -(941, 2348, 844) -(2696, 3742, 1736) -(3797, 1039, 1158) -(2890, 2361, 1310) -(2671, 3721, 431) -(3689, 654, 806) -(1079, 774, 746) -(4465, 3007, 1950) -(3075, 3184, 1674) -(4904, 4922, 794) -(3603, 1724, 1030) -(4103, 2392, 1519) -(4798, 3061, 73) -(1222, 1524, 1389) -(339, 775, 358) -(1312, 3585, 736) -(1467, 1878, 959) -(137, 3849, 635) -(88, 4178, 1802) -(1801, 125, 594) -(2235, 3942, 1352) -(3058, 4520, 171) -(238, 3407, 194) -(3967, 418, 341) -(1140, 2548, 1266) -(1474, 847, 754) -(526, 1652, 603) -(4959, 1406, 688) -(883, 3974, 1113) -(2631, 1992, 756) -(701, 3764, 568) -(1200, 359, 478) -(4404, 2608, 1758) -(528, 2993, 1432) -(4259, 3951, 1441) -(4033, 664, 514) -(1585, 3202, 292) -(2458, 4849, 1484) -(1722, 4097, 707) -(1988, 1096, 989) -(364, 2061, 300) -(2213, 4743, 597) -(1589, 3755, 1862) -(1077, 515, 510) -(1436, 2344, 1426) -(3437, 2876, 616) -(2310, 2614, 148) -(1841, 3482, 147) -(1415, 3723, 259) -(602, 4109, 494) -(4917, 1927, 364) -(3783, 294, 367) -(1971, 43, 1177) -(4259, 37, 205) -(3929, 4477, 1330) -(1944, 1117, 387) -(258, 4956, 1235) -(3648, 2484, 210) -(2345, 1717, 1732) -(609, 176, 1416) -(2006, 2863, 129) -(3446, 2981, 1853) -(4617, 3025, 1996) -(417, 4069, 1985) -(2801, 2104, 1090) -(4695, 4309, 926) -(3383, 1760, 1406) -(172, 1662, 254) -(3627, 2830, 1541) -(3129, 3285, 145) -(3255, 4973, 1663) -(419, 74, 1034) -(524, 2631, 1455) -(3978, 1108, 1681) -(2769, 3058, 742) -(2621, 2929, 1114) -(1362, 558, 1497) -(1425, 1449, 283) -(4891, 2798, 1677) -(742, 1579, 1276) -(3984, 1287, 1716) -(3956, 2145, 1370) -(3545, 2106, 1922) -(2487, 4091, 1751) -(2826, 750, 759) -(1012, 73, 677) -(457, 2289, 1968) -(3172, 96, 1237) -(3567, 1929, 1563) -(2336, 693, 487) -(1465, 1737, 661) -(1882, 4434, 329) -(642, 3895, 566) -(1650, 4515, 1177) -(3420, 2123, 50) -(4570, 2054, 488) -(161, 3269, 1593) -(1777, 4527, 1663) -(558, 324, 791) -(312, 2560, 1148) -(3151, 2982, 846) -(676, 1499, 1625) -(4683, 2291, 181) -(2971, 2225, 1187) -(4584, 3826, 567) -(3321, 606, 1490) -(3326, 1139, 950) -(2134, 1831, 252) -(3041, 3520, 1119) -(4217, 2755, 620) -(3645, 1509, 1798) -(4996, 4093, 1472) -(1100, 802, 1542) -(1296, 2064, 367) -(2742, 2680, 1002) -(587, 4391, 1071) -(774, 3915, 1105) -(3442, 4600, 281) -(735, 48, 1831) -(4530, 1627, 1117) -(782, 2374, 404) -(2464, 1120, 1464) -(2496, 6, 387) -(2711, 140, 1238) -(4807, 2198, 726) -(3213, 440, 1412) -(721, 4, 340) -(947, 4565, 1646) -(1563, 4279, 354) -(3669, 2752, 998) -(3652, 4954, 422) -(640, 494, 1818) -(3916, 3623, 210) -(738, 4338, 1475) -(1929, 1590, 196) -(1456, 1019, 1221) -(3009, 3553, 1052) -(1242, 3607, 1955) -(4440, 259, 832) -(4333, 679, 1905) -(3041, 517, 1017) -(542, 389, 469) -(2410, 346, 355) -(3536, 1198, 1354) -(1830, 3162, 634) -(4832, 3773, 1384) -(2002, 1847, 1602) -(828, 3378, 905) -(139, 4138, 526) -(975, 1421, 338) -(953, 2206, 1705) -(2857, 2884, 274) -(417, 4428, 64) -(924, 861, 1327) -(2504, 2230, 1160) -(1652, 3711, 1074) -(2819, 2593, 1931) -(1853, 4636, 341) -(808, 702, 140) -(739, 2450, 970) -(4879, 2632, 1188) -(4453, 3904, 1661) -(263, 3755, 1536) -(4129, 1546, 1286) -(3401, 293, 1502) -(3034, 2349, 240) -(2121, 487, 1813) -(2510, 4683, 1328) -(3727, 1816, 206) -(4010, 4305, 741) -(1343, 91, 713) -(3358, 3145, 249) -(1986, 4658, 1678) -(2130, 1947, 1578) -(1400, 1378, 964) -(637, 1408, 1284) -(2616, 1608, 885) -(1581, 531, 241) -(769, 842, 788) -(2360, 4909, 1288) -(3563, 2610, 1275) -(3770, 2578, 1830) -(639, 2283, 111) -(4317, 391, 911) -(4743, 3826, 591) -(1150, 3822, 1682) -(3637, 1212, 273) -(4876, 268, 362) -(2003, 4958, 1080) -(2193, 4500, 468) -(2992, 124, 143) -(644, 2349, 172) -(523, 1496, 231) -(3560, 3138, 1361) -(967, 3845, 1610) -(376, 3969, 258) -(3200, 4424, 1096) -(3974, 81, 956) -(1719, 4242, 1143) -(4970, 2212, 1334) -(1207, 4542, 76) -(4548, 892, 286) -(3150, 2192, 799) -(4478, 245, 1557) -(4028, 458, 1485) -(3252, 4599, 468) -(4921, 3750, 240) -(1237, 3400, 148) -(2660, 656, 1343) -(681, 413, 56) -(2528, 1129, 1195) -(4372, 4978, 172) -(1366, 952, 1866) -(2908, 2746, 1019) -(586, 4647, 1175) -(283, 882, 140) -(2323, 456, 1138) -(1552, 2129, 372) -(182, 473, 1692) -(3476, 1308, 215) -(667, 2619, 1636) -(1129, 1396, 1230) -(2002, 3591, 1547) -(3237, 1325, 1410) -(3793, 1745, 1429) -(4648, 4040, 1569) -(865, 1894, 843) -(3520, 1407, 1895) -(1594, 4938, 1136) -(3875, 423, 976) -(900, 1970, 1472) -(271, 3781, 1603) -(4756, 398, 264) -(1372, 2963, 1677) -(4151, 452, 1373) -(227, 4424, 1478) -(4413, 3101, 933) -(3409, 73, 243) -(4146, 3480, 1205) -(2848, 2163, 1494) -(2004, 52, 576) -(1662, 1544, 1496) -(1803, 3768, 1676) -(3210, 3666, 1688) -(4537, 3053, 1296) -(2102, 4018, 727) -(1561, 545, 398) -(4746, 311, 304) -(4039, 2870, 1723) -(61, 3471, 813) -(843, 1900, 597) -(3999, 927, 1836) -(4441, 541, 1629) -(3232, 1147, 949) -(4865, 387, 1803) -(4265, 3407, 1751) -(1654, 1563, 841) -(3407, 4265, 1751) -(3575, 1922, 1506) -(2318, 4678, 55) -(4948, 3333, 867) -(3241, 3861, 1825) -(2329, 1051, 962) -(2233, 4270, 1268) -(2735, 4362, 967) -(2632, 988, 1925) -(1305, 894, 80) -(2831, 15, 1359) -(3683, 3889, 1284) -(690, 2388, 792) -(816, 3815, 933) -(2043, 3201, 449) -(417, 4908, 550) -(168, 2078, 1128) -(3530, 400, 1860) -(4284, 3831, 1163) -(2875, 3065, 160) -(546, 171, 1078) -(3207, 1074, 305) -(2012, 2472, 1691) -(3515, 2032, 1527) -(4479, 2939, 200) -(1222, 4258, 435) -(2773, 3978, 202) -(3442, 4380, 870) -(1281, 4764, 507) -(1471, 761, 1077) -(3066, 4393, 1969) -(1569, 1053, 1796) -(1840, 2531, 88) -(674, 2133, 115) -(1030, 1464, 1990) -(3596, 1186, 458) -(4685, 207, 627) -(1479, 4527, 709) -(790, 1101, 332) -(232, 526, 1154) -(268, 102, 1833) -(2917, 1159, 774) -(4036, 2545, 1794) -(1287, 2222, 107) -(29, 4136, 489) -(492, 4985, 1948) -(936, 4585, 1453) -(819, 3823, 1986) -(2923, 2554, 429) -(4970, 1534, 1000) -(334, 4608, 332) -(501, 3376, 630) -(2218, 1146, 57) -(1432, 86, 559) -(502, 4222, 1029) -(348, 3961, 575) -(4422, 1067, 160) -(461, 438, 1171) -(1445, 4402, 170) -(2431, 2664, 497) -(1597, 1149, 1540) -(4779, 798, 1396) -(3827, 4305, 1547) -(4630, 4816, 389) -(917, 3715, 1831) -(1709, 2926, 728) -(4382, 1297, 749) -(4195, 3356, 485) -(1711, 4914, 1757) -(4801, 2375, 1418) -(1163, 4984, 694) -(4979, 3447, 1452) -(288, 67, 1969) -(3250, 2277, 356) -(1449, 1425, 283) -(201, 1242, 316) -(4342, 2777, 1652) -(3893, 655, 1515) -(1391, 3522, 857) -(4964, 3112, 585) -(1690, 2839, 1720) -(697, 4390, 427) -(2419, 4730, 1752) -(2761, 3926, 500) -(3149, 2220, 1854) -(4757, 2664, 1409) -(2214, 916, 1280) -(2073, 32, 1961) -(2611, 3898, 1703) -(562, 1617, 1370) -(2819, 4390, 1243) -(1487, 3091, 1159) -(759, 236, 185) -(3540, 1753, 1626) -(1461, 2636, 1263) -(2126, 4727, 1339) -(3914, 4808, 1835) -(1050, 821, 1763) -(3167, 4999, 1944) -(4547, 1641, 1659) -(4342, 2555, 355) -(4655, 3838, 771) -(3671, 1969, 1610) -(1498, 1708, 294) -(192, 2641, 489) -(1792, 2118, 1036) -(3613, 802, 1703) -(793, 2913, 366) -(1709, 1491, 1015) -(3072, 932, 1263) -(1298, 505, 294) -(2015, 2433, 1928) -(3873, 1605, 1995) -(1410, 1181, 1820) -(495, 4120, 1236) -(208, 4522, 448) -(2638, 37, 1350) -(23, 4785, 1555) -(2604, 3961, 380) -(1933, 2419, 1324) -(2109, 4085, 1772) -(559, 255, 1519) -(4835, 4289, 1246) -(2266, 2216, 1892) -(4153, 1920, 550) -(3616, 2864, 309) -(390, 4196, 1030) -(3712, 4543, 1431) -(4967, 715, 1605) -(417, 4747, 763) -(3112, 340, 394) -(117, 4874, 228) -(2877, 1520, 1241) -(4789, 787, 1036) -(4290, 3271, 1495) -(4307, 2271, 1816) -(4373, 3872, 1434) -(4707, 3615, 1237) -(3922, 56, 1206) -(3726, 1726, 1848) -(317, 4501, 1976) -(3184, 870, 452) -(3302, 1886, 200) -(3163, 2192, 1851) -(4922, 4904, 794) -(1106, 3549, 1405) -(2284, 4708, 1264) -(1480, 1871, 148) -(4162, 2777, 1544) -(3263, 4537, 210) -(698, 4519, 484) -(3170, 3544, 1104) -(2835, 385, 1334) -(2945, 449, 1655) -(2064, 2668, 873) -(3429, 41, 1729) -(55, 222, 322) -(4359, 3962, 485) -(781, 3101, 505) -(4210, 4004, 259) -(2924, 338, 1252) -(2964, 2648, 1532) -(4061, 4076, 1396) -(3484, 1921, 972) -(1970, 3900, 189) -(3560, 39, 1851) -(1778, 4178, 72) -(1965, 3774, 295) -(964, 4994, 1766) -(1837, 3103, 1972) -(1635, 3524, 1726) -(2638, 3240, 826) -(196, 3851, 747) -(4497, 1106, 1179) -(4570, 2616, 211) -(4869, 1994, 1360) -(740, 2619, 525) -(2884, 3368, 869) -(667, 1490, 1793) -(2360, 4581, 1853) -(4272, 2946, 560) -(1011, 1774, 476) -(287, 3249, 74) -(1542, 3587, 277) -(4952, 4355, 1658) -(4261, 3098, 111) -(1780, 1830, 1031) -(2573, 4520, 261) -(791, 2347, 102) -(2975, 4899, 1129) -(4359, 509, 1572) -(4480, 2574, 1843) -(2474, 3804, 1206) -(3765, 2542, 80) -(700, 2226, 1627) -(4670, 3041, 942) -(4487, 2487, 103) -(4409, 132, 1043) -(2124, 1440, 1532) -(2873, 498, 663) -(2454, 1400, 1724) -(1966, 1554, 1261) -(4278, 4399, 313) -(1014, 1044, 1216) -(1987, 1865, 1719) -(3330, 1740, 152) -(3296, 3390, 1928) -(3259, 3490, 850) -(2797, 2207, 1352) -(2565, 381, 1759) -(3793, 4818, 582) -(4777, 4414, 1981) -(2866, 406, 784) -(4848, 746, 275) -(629, 3087, 60) -(100, 392, 1794) -(337, 810, 1425) -(2610, 3563, 1275) -(1641, 4547, 1659) -(2228, 3585, 1276) -(4194, 2004, 1567) -(963, 1855, 1592) -(4491, 3476, 501) -(204, 598, 1432) -(2628, 1058, 1558) -(1564, 1119, 1320) -(3740, 3689, 1697) -(1985, 4574, 224) -(3614, 1894, 301) -(2799, 1211, 409) -(3369, 1728, 748) -(4002, 3100, 1102) -(4199, 3546, 1352) -(2420, 3928, 198) -(2883, 1344, 691) -(2594, 789, 406) -(3850, 2010, 794) -(1222, 30, 287) -(4549, 1363, 703) -(1725, 1996, 1610) -(714, 1390, 601) -(2801, 2589, 993) -(1008, 911, 423) -(4623, 3049, 967) -(832, 1789, 889) -(3733, 1228, 1006) -(4577, 3967, 869) -(3716, 989, 177) -(1811, 1759, 334) -(66, 189, 1297) -(282, 1518, 1273) -(1618, 630, 1161) -(1349, 3728, 1181) -(4587, 3941, 1238) -(4731, 498, 865) -(4787, 388, 669) -(647, 1255, 1213) -(1487, 3306, 64) -(787, 3631, 1513) -(4188, 911, 993) -(1481, 3921, 55) -(1904, 3188, 1542) -(3879, 2812, 1068) -(3669, 844, 1245) -(4622, 1698, 1842) -(2843, 1820, 1764) -(4379, 438, 96) -(4928, 2346, 1485) -(1970, 791, 999) -(3140, 4042, 1336) -(297, 0, 1378) -(4036, 1124, 718) -(2311, 4371, 1378) -(821, 4506, 1228) -(2896, 3038, 1575) -(785, 2247, 1659) -(4710, 2475, 1607) -(1552, 804, 532) -(266, 314, 1256) -(3346, 4113, 1319) -(3927, 1833, 1995) -(3493, 4302, 1462) -(906, 3063, 893) -(4969, 3147, 1016) -(786, 4636, 1751) -(425, 996, 81) -(2196, 3589, 285) -(1994, 1760, 1799) -(1166, 3945, 1697) -(3597, 385, 1532) -(3328, 4795, 449) -(2115, 4529, 1640) -(3819, 4318, 1607) -(2665, 980, 1601) -(491, 4031, 1788) -(2279, 2403, 1855) -(4067, 3083, 786) -(3443, 229, 127) -(4419, 4296, 1775) -(1753, 4608, 437) -(3526, 3576, 1196) -(4390, 2698, 490) -(3714, 487, 102) -(2788, 3778, 1372) -(2827, 210, 1045) -(3374, 4968, 509) -(2840, 4799, 942) -(730, 3183, 392) -(3874, 4400, 1296) -(2427, 2746, 200) -(429, 2959, 1120) -(2450, 739, 970) -(4586, 1992, 488) -(2452, 373, 1340) -(356, 4402, 1229) -(3145, 3016, 191) -(266, 538, 904) -(2644, 3329, 1108) -(1626, 265, 600) -(1305, 3015, 1387) -(1195, 4704, 1208) -(2852, 405, 407) -(176, 667, 1180) -(2942, 746, 926) -(3736, 2701, 495) -(2106, 1700, 944) -(2235, 1146, 141) -(3206, 1100, 1973) -(2153, 3954, 340) -(1181, 2905, 627) -(2326, 1953, 504) -(2684, 2265, 1435) -(130, 148, 1066) -(2218, 3586, 1450) -(2969, 3914, 707) -(3698, 2855, 742) -(1044, 2647, 1017) -(1370, 1070, 203) -(3883, 907, 149) -(4726, 3405, 342) -(1793, 3127, 718) -(138, 3847, 1397) -(2919, 4379, 1705) -(68, 1732, 1589) -(3442, 1684, 1063) -(1861, 2168, 734) -(3508, 2080, 890) -(2879, 108, 1295) -(1883, 1752, 1711) -(1397, 2943, 1287) -(2622, 3231, 1832) -(4520, 3058, 171) -(1316, 2851, 942) -(2130, 3353, 100) -(2584, 1873, 291) -(4187, 1663, 95) -(130, 1476, 842) -(4388, 2878, 169) -(4646, 4366, 1645) -(2188, 4757, 1528) -(357, 2177, 1109) -(2429, 4135, 545) -(1484, 4075, 1787) -(1160, 2391, 1654) -(228, 549, 666) -(1723, 3788, 1055) -(2496, 2747, 671) -(668, 4405, 1440) -(2379, 23, 623) -(2548, 278, 829) -(1680, 2517, 373) -(4113, 826, 1344) -(4203, 850, 973) -(3617, 4702, 1970) -(2887, 439, 203) -(4027, 630, 1457) -(131, 4485, 611) -(2813, 2342, 1500) -(2113, 2162, 1463) -(2230, 1250, 1999) -(1358, 3397, 614) -(3663, 4162, 172) -(4090, 1242, 537) -(3841, 2874, 1845) -(750, 777, 1452) -(4818, 3172, 519) -(3703, 2082, 1267) -(4105, 4631, 1127) -(2283, 832, 1086) -(1994, 4074, 137) -(3855, 37, 451) -(3174, 2174, 446) -(1752, 650, 1605) -(3888, 4295, 543) -(2883, 677, 505) -(1835, 2833, 1277) -(2619, 667, 1636) -(3116, 1485, 1101) -(1310, 3625, 644) -(1586, 3889, 1799) -(2390, 1522, 273) -(4693, 4970, 971) -(548, 3032, 298) -(302, 3252, 1054) -(44, 4887, 181) -(4137, 1939, 1610) -(183, 1063, 406) -(3579, 2806, 658) -(4375, 1401, 302) -(3466, 895, 180) -(20, 530, 1108) -(2988, 3311, 1412) -(3438, 1954, 1253) -(3772, 555, 408) -(4568, 4046, 261) -(2092, 1592, 734) -(214, 47, 1243) -(2158, 1229, 345) -(1054, 1612, 1725) -(532, 3829, 580) -(374, 4914, 1809) -(4053, 2826, 1713) -(740, 1153, 1992) -(1180, 1984, 765) -(4091, 4968, 215) -(4409, 2952, 717) -(3037, 2415, 884) -(2759, 3046, 203) -(3718, 4531, 1060) -(2649, 3147, 1914) -(4182, 3735, 1605) -(141, 4804, 375) -(4521, 3363, 1058) -(2232, 3589, 1347) -(1606, 3433, 404) -(1066, 2066, 1050) -(3427, 1800, 184) -(4128, 1065, 1229) -(3730, 2614, 542) -(3544, 1170, 714) -(2512, 4119, 852) -(3029, 3344, 1730) -(667, 2149, 1558) -(4820, 1989, 1715) -(4862, 868, 1150) -(2051, 4282, 611) -(2896, 4487, 1115) -(2596, 125, 756) -(4819, 2271, 1952) -(3924, 3919, 916) -(4531, 3718, 1060) -(2915, 1101, 337) -(1629, 4201, 563) -(2332, 2717, 163) -(2271, 1157, 818) -(3286, 1114, 1660) -(2820, 2988, 1130) -(1693, 4784, 603) -(2512, 4367, 1509) -(2954, 4602, 150) -(127, 760, 513) -(1451, 1778, 1270) -(2012, 4102, 1041) -(3693, 925, 584) -(2992, 81, 1040) -(2064, 1296, 367) -(1391, 3288, 202) -(291, 4419, 1096) -(4590, 3333, 386) -(3906, 592, 817) -(1386, 3501, 1886) -(4178, 2226, 407) -(2174, 2071, 1555) -(3140, 1657, 258) -(3713, 2500, 1959) -(1142, 270, 312) -(2715, 3431, 520) -(3769, 1344, 1972) -(379, 3590, 261) -(45, 680, 240) -(2119, 3531, 1580) -(4572, 135, 234) -(4939, 3489, 635) -(2408, 3855, 949) -(2655, 961, 1269) -(606, 91, 59) -(3656, 1998, 795) -(2867, 1013, 1359) -(3590, 4605, 578) -(1652, 4291, 462) -(1791, 3561, 1179) -(4487, 769, 742) -(3553, 3374, 1592) -(3438, 1304, 552) -(1200, 553, 220) -(4431, 893, 1508) -(3913, 2590, 440) -(1055, 2935, 1003) -(2842, 913, 132) -(3542, 614, 521) -(4311, 411, 803) -(4711, 3549, 1165) -(2210, 1659, 1772) -(2764, 2102, 1597) -(57, 4572, 1153) -(2024, 2418, 1993) -(3440, 1201, 380) -(2193, 4362, 1896) -(2742, 4479, 900) -(3040, 1783, 1513) -(2307, 3188, 1099) -(2092, 3751, 383) -(4238, 1394, 648) -(2523, 4460, 1711) -(2766, 4568, 1079) -(2084, 2619, 1693) -(2484, 2718, 1504) -(1467, 4496, 376) -(3783, 4350, 271) -(1742, 794, 466) -(4818, 3793, 582) -(1625, 565, 1830) -(1465, 294, 262) -(2403, 2279, 1855) -(3522, 3793, 527) -(3758, 3228, 1432) -(526, 1201, 288) -(407, 1413, 338) -(826, 4603, 199) -(4432, 2058, 287) -(4606, 2179, 423) -(2491, 1429, 994) -(4166, 3423, 611) -(4158, 1352, 1146) -(474, 3042, 1688) -(3486, 4342, 1733) -(3247, 4762, 768) -(2330, 1534, 899) -(3926, 4629, 512) -(3535, 403, 785) -(3935, 629, 639) -(1759, 766, 325) -(1313, 3915, 1747) -(3909, 1181, 1651) -(4968, 303, 424) -(2255, 620, 156) -(3905, 4507, 267) -(487, 3553, 686) -(965, 3729, 1639) -(1731, 4202, 1865) -(2117, 2983, 1108) -(582, 575, 1278) -(2758, 3285, 1966) -(172, 3672, 1510) -(4169, 4882, 1725) -(3470, 2202, 56) -(3504, 757, 255) -(3669, 4680, 381) -(1854, 2629, 830) -(3409, 4471, 681) -(525, 1193, 1668) -(584, 2427, 1169) -(1869, 2971, 1978) -(3807, 1727, 54) -(3119, 3167, 1465) -(379, 445, 634) -(4478, 3771, 734) -(4327, 381, 744) -(899, 1100, 991) -(1893, 1829, 468) -(3556, 4084, 139) -(4153, 569, 1673) -(2946, 4272, 560) -(1940, 3751, 1949) -(202, 1200, 809) -(4398, 4347, 1276) -(1380, 4474, 206) -(2396, 1652, 1135) -(760, 127, 513) -(1051, 1118, 811) -(2393, 4469, 311) -(529, 4923, 1558) -(2294, 223, 1072) -(221, 692, 509) -(3518, 3981, 495) -(2522, 2674, 887) -(2586, 4975, 1141) -(226, 686, 1476) -(3742, 1890, 770) -(839, 1583, 1000) -(767, 4706, 734) -(2383, 2883, 1813) -(3870, 617, 837) -(145, 1387, 1244) -(1749, 3560, 720) -(1543, 4953, 1586) -(4846, 140, 1331) -(4151, 1326, 205) -(3014, 87, 1570) -(3328, 4670, 403) -(4977, 4336, 1274) -(3413, 1575, 1366) -(1419, 2706, 444) -(3526, 2938, 1483) -(4921, 420, 469) -(564, 245, 1011) -(738, 4232, 1904) -(4221, 4479, 1185) -(3702, 2639, 1653) -(2786, 257, 1822) -(2260, 3072, 317) -(2197, 521, 1919) -(743, 1893, 1894) -(2757, 384, 1112) -(4760, 1217, 1135) -(2210, 709, 1964) -(932, 3072, 1263) -(1114, 3286, 1660) -(4321, 1761, 175) -(660, 29, 1405) -(3188, 1904, 1542) -(4584, 2745, 791) -(1433, 1117, 670) -(4912, 3622, 1092) -(4608, 1753, 437) -(2304, 4878, 1241) -(2878, 4567, 936) -(4379, 4194, 823) -(904, 3496, 355) -(3376, 501, 630) -(4543, 1271, 717) -(2562, 4729, 1380) -(4090, 1751, 1004) -(1324, 4093, 174) -(1226, 4640, 1687) -(2108, 4007, 1891) -(61, 47, 658) -(3232, 2397, 1766) -(4776, 1018, 373) -(1402, 319, 1138) -(3088, 4848, 564) -(2497, 4185, 1642) -(4216, 743, 953) -(1917, 3283, 1541) -(4855, 1361, 1632) -(386, 463, 1891) -(3227, 4582, 959) -(3111, 1316, 1377) -(2983, 2117, 1108) -(1235, 4108, 1164) -(4246, 125, 135) -(3148, 3642, 1143) -(458, 4028, 1485) -(4134, 984, 1853) -(2838, 4404, 1957) -(2998, 2690, 1189) -(2357, 470, 583) -(3275, 3711, 1450) -(4277, 2315, 946) -(4628, 1024, 1282) -(4189, 3131, 537) -(683, 3094, 825) -(2810, 3298, 193) -(291, 2632, 1806) -(2505, 4331, 768) -(2115, 28, 1284) -(4993, 777, 924) -(2517, 1680, 373) -(2017, 2439, 334) -(984, 2604, 273) -(4481, 4061, 113) -(3419, 3388, 1434) -(3806, 3227, 61) -(4731, 1879, 1574) -(1599, 3335, 563) -(18, 2819, 132) -(2523, 4571, 252) -(4398, 2142, 352) -(126, 3587, 956) -(3076, 1330, 1216) -(2212, 3208, 836) -(1253, 4466, 551) -(2455, 2834, 1163) -(4774, 2517, 1797) -(4257, 4431, 896) -(4579, 895, 930) -(3927, 277, 1533) -(582, 2163, 921) -(276, 3718, 1503) -(4878, 1283, 1047) -(2249, 2584, 1584) -(2285, 2378, 229) -(3249, 4726, 320) -(1014, 2302, 1853) -(1609, 2676, 960) -(1364, 1165, 461) -(3717, 2975, 539) -(400, 682, 1119) -(1124, 3429, 396) -(505, 1894, 191) -(39, 1421, 1028) -(3149, 2133, 1699) -(2484, 3648, 210) -(2088, 2857, 1786) -(1410, 2528, 680) -(3757, 2241, 181) -(4542, 2575, 1337) -(4253, 260, 1910) -(4331, 2749, 1732) -(293, 3330, 953) -(2337, 1890, 537) -(2801, 2821, 176) -(1921, 696, 1842) -(3091, 1609, 458) -(4356, 1555, 1654) -(584, 3977, 1988) -(4113, 4522, 263) -(4307, 1095, 854) -(4383, 4046, 196) -(4900, 3300, 1925) -(2349, 2327, 1932) -(4091, 2630, 1582) -(2206, 3576, 97) -(1034, 4711, 1237) -(2818, 642, 1573) -(3571, 1770, 1569) -(4835, 1489, 1670) -(2622, 248, 1767) -(2635, 1010, 1016) -(1069, 43, 133) -(1285, 1150, 1913) -(3191, 3562, 288) -(2268, 3920, 333) -(2039, 4892, 1523) -(1705, 547, 66) -(3299, 212, 341) -(1227, 1827, 558) -(2977, 4271, 757) -(1554, 2928, 1067) -(2966, 2882, 1361) -(4306, 2524, 1502) -(1486, 1613, 1537) -(2534, 3038, 780) -(4833, 1149, 1406) -(1654, 1365, 1846) -(3459, 1752, 1477) -(4038, 2212, 1534) -(850, 3117, 1092) -(1100, 732, 522) -(533, 2267, 464) -(896, 4654, 270) -(1285, 4971, 1910) -(4713, 1200, 1519) -(77, 1468, 748) -(2819, 18, 132) -(113, 3619, 1443) -(862, 1712, 517) -(4895, 1140, 512) -(3625, 2130, 803) -(1886, 4580, 1406) -(441, 840, 1703) -(1157, 3074, 839) -(3560, 2394, 1629) -(2466, 2961, 506) -(736, 3084, 676) -(2318, 3530, 1207) -(2412, 481, 1969) -(3380, 371, 1626) -(980, 2883, 1886) -(2024, 2124, 564) -(1605, 4242, 549) -(1997, 4883, 1618) -(4272, 4061, 959) -(3426, 804, 62) -(4033, 3378, 1496) -(1265, 2072, 1227) -(267, 3169, 590) -(4040, 4594, 444) -(2035, 2662, 1774) -(653, 1193, 1752) -(2379, 889, 374) -(4951, 3480, 928) -(1316, 3455, 770) -(509, 4359, 1572) -(2156, 1345, 1841) -(1592, 1319, 518) -(3308, 3410, 538) -(2300, 3549, 395) -(2189, 970, 1043) -(4112, 4936, 705) -(529, 1427, 274) -(474, 2830, 194) -(2805, 2180, 160) -(3718, 1174, 1325) -(2031, 325, 92) -(2684, 4900, 1058) -(1928, 1036, 409) -(2796, 4341, 351) -(1738, 3135, 1478) -(1237, 2292, 1359) -(1416, 184, 1477) -(1540, 4774, 848) -(3657, 2644, 584) -(3519, 3369, 1276) -(3556, 4210, 981) -(3204, 1199, 1975) -(769, 3207, 1783) -(3583, 2170, 1548) -(4871, 1497, 312) -(3719, 1316, 1876) -(3306, 2357, 596) -(2475, 2177, 512) -(2887, 4959, 1185) -(4586, 2273, 431) -(848, 1774, 1945) -(123, 659, 1767) -(103, 889, 1719) -(4512, 2746, 486) -(4824, 556, 315) -(857, 829, 375) -(3543, 4805, 1947) -(3604, 3939, 1964) -(349, 3338, 1675) -(2309, 294, 948) -(3160, 4821, 1341) -(51, 4698, 908) -(58, 3318, 1826) -(2133, 674, 115) -(4136, 1599, 731) -(87, 3785, 1205) -(3383, 1940, 348) -(3049, 3275, 550) -(3046, 3567, 1643) -(4617, 1508, 1583) -(6, 2993, 175) -(4355, 741, 174) -(2503, 4934, 562) -(4954, 3652, 422) -(382, 3355, 939) -(539, 3497, 1331) -(4598, 4738, 438) -(506, 3419, 547) -(4740, 3558, 1818) -(2048, 175, 285) -(4636, 786, 1751) -(1821, 1343, 533) -(829, 3765, 1061) -(2143, 1370, 1061) -(3852, 2168, 682) -(3512, 749, 497) -(673, 3325, 823) -(4316, 3847, 73) -(4337, 3999, 828) -(4928, 765, 1056) -(3947, 1267, 369) -(65, 4180, 134) -(4718, 2486, 1031) -(4302, 1115, 626) -(2611, 4791, 427) -(4474, 1403, 1139) -(483, 1014, 1628) -(2155, 1765, 1371) -(3479, 3676, 938) -(2951, 4667, 1683) -(4152, 2873, 342) -(3800, 1692, 1211) -(2025, 4182, 1110) -(4730, 1064, 1608) -(261, 4211, 1411) -(153, 3994, 1298) -(1372, 4957, 1535) -(3196, 3726, 1437) -(1765, 1423, 347) -(2970, 3108, 337) -(2504, 4263, 513) -(2293, 1419, 1320) -(3604, 3209, 543) -(2235, 4482, 858) -(4410, 3590, 1459) -(3102, 4888, 1611) -(3076, 3424, 983) -(3425, 1346, 851) -(2393, 2525, 470) -(4648, 4291, 620) -(249, 903, 1172) -(1727, 1863, 382) -(4953, 3748, 813) -(2455, 305, 396) -(2698, 4390, 490) -(3808, 3775, 805) -(681, 2408, 1502) -(1380, 4085, 989) -(1979, 1930, 1433) -(125, 119, 387) -(2648, 615, 1221) -(1310, 3856, 1548) -(3377, 1100, 983) -(1489, 1996, 193) -(4175, 2881, 1661) -(4510, 888, 992) -(105, 2503, 318) -(191, 1916, 1340) -(3716, 997, 556) -(2861, 4588, 325) -(342, 1784, 260) -(787, 2911, 1467) -(3812, 1928, 283) -(4072, 417, 1384) -(4305, 2014, 204) -(2106, 3545, 1922) -(3485, 2134, 673) -(1906, 2544, 1622) -(3863, 3573, 1623) -(1366, 1159, 1825) -(2925, 271, 700) -(2025, 3381, 1226) -(4832, 4009, 571) -(4797, 1945, 1734) -(4522, 61, 1494) -(155, 2186, 788) -(756, 2961, 1847) -(1928, 1338, 1234) -(2847, 2410, 1404) -(1705, 4327, 258) -(2073, 3946, 307) -(718, 2186, 85) -(3390, 3520, 703) -(1242, 3328, 689) -(459, 4802, 1102) -(4211, 1585, 751) -(635, 3148, 1882) -(1951, 3407, 1384) -(3593, 4810, 54) -(3767, 1262, 561) -(4682, 1902, 1701) -(1188, 390, 1309) -(641, 3114, 1417) -(2298, 3099, 1968) -(1631, 959, 193) -(4245, 2005, 1521) -(1381, 3716, 1241) -(1581, 1858, 1382) -(3973, 2224, 1330) -(1027, 2399, 1729) -(3948, 1645, 1446) -(1803, 2732, 1730) -(3898, 4474, 902) -(3426, 3819, 50) -(4812, 2392, 784) -(3704, 1017, 1069) -(1234, 402, 800) -(341, 182, 1792) -(2949, 2505, 1397) -(4158, 3730, 1511) -(3768, 481, 1436) -(4559, 4410, 1220) -(1794, 1223, 953) -(4071, 2701, 1339) -(1345, 2156, 1841) -(2886, 228, 1466) -(1073, 3517, 1030) -(3579, 1101, 87) -(680, 3850, 746) -(1237, 3531, 633) -(289, 3282, 1100) -(3410, 3308, 538) -(1922, 844, 660) -(2349, 3454, 662) -(1145, 3363, 1975) -(1108, 3729, 978) -(4415, 3423, 1837) -(4753, 132, 815) -(2164, 2320, 320) -(4329, 1050, 888) -(3800, 3710, 211) -(4962, 3347, 1596) -(1249, 1675, 1399) -(4872, 2594, 1244) -(1771, 3537, 963) -(3575, 1245, 975) -(3879, 1502, 82) -(565, 4894, 738) -(3543, 1571, 1083) -(2075, 1354, 395) -(189, 29, 396) -(466, 1545, 352) -(913, 2842, 132) -(3585, 2228, 1276) -(3019, 3094, 1818) -(2451, 3475, 779) -(951, 3562, 1848) -(4414, 4492, 1740) -(3589, 1836, 1507) -(2559, 1263, 1283) -(28, 2115, 1284) -(1970, 900, 1472) -(2957, 4241, 1870) -(2226, 1782, 401) -(1557, 2985, 1458) -(47, 3464, 1692) -(2442, 189, 602) -(2812, 3879, 1068) -(670, 909, 56) -(2131, 4661, 1380) -(2724, 2823, 441) -(1603, 1337, 489) -(797, 4317, 200) -(1793, 3859, 178) -(2806, 3579, 658) -(1415, 3240, 771) -(504, 3196, 546) -(260, 721, 1318) -(2865, 2867, 747) -(2118, 1333, 1927) -(1332, 669, 1400) -(3460, 730, 1329) -(1315, 3401, 1629) -(70, 312, 206) -(54, 733, 1914) -(2150, 4022, 1427) -(2404, 2434, 707) -(3739, 4137, 250) -(3232, 3197, 1001) -(863, 1838, 1806) -(1235, 1694, 1078) -(3133, 2587, 1947) -(1014, 483, 1628) -(1178, 3791, 862) -(4896, 4923, 1146) -(3614, 3836, 1120) -(65, 3820, 583) -(822, 726, 475) -(978, 3672, 1324) -(3679, 3827, 463) -(1876, 193, 1658) -(4215, 3262, 368) -(3890, 4477, 1086) -(311, 2403, 1912) -(3352, 2856, 155) -(3531, 1588, 675) -(1973, 1797, 1885) -(1707, 1077, 539) -(47, 61, 658) -(3262, 420, 464) -(4909, 223, 1089) -(2004, 2449, 730) -(4726, 1313, 1943) -(697, 1148, 1373) -(4599, 3801, 562) -(1782, 2371, 1506) -(293, 3401, 1502) -(3242, 4901, 405) -(1720, 2054, 1295) -(4217, 788, 1998) -(2972, 1312, 143) -(1945, 2085, 1539) -(4014, 1074, 1826) -(3898, 3804, 104) -(2108, 3438, 643) -(2386, 2554, 1808) -(904, 3689, 1392) -(2252, 2500, 635) -(3600, 3962, 421) -(4654, 4981, 1833) -(4386, 495, 1733) -(4940, 1930, 1360) -(1775, 3183, 1712) -(401, 4377, 1530) -(2552, 4489, 946) -(4039, 2190, 554) -(168, 3160, 547) -(1269, 314, 949) -(346, 1652, 1088) -(1617, 4712, 594) -(4257, 122, 531) -(4975, 4960, 375) -(47, 3228, 736) -(1784, 173, 740) -(182, 37, 1142) -(1823, 3938, 1632) -(3490, 1976, 1928) -(4693, 3303, 99) -(3341, 1866, 55) -(3033, 215, 1108) -(4187, 4762, 1352) -(746, 360, 220) -(1791, 2118, 68) -(3426, 262, 362) -(1698, 3598, 1848) -(3715, 4182, 445) -(1268, 2634, 443) -(1506, 1866, 638) -(1887, 4335, 884) -(4714, 2361, 487) -(3263, 3921, 58) -(4550, 579, 1194) -(4648, 1171, 285) -(3729, 4406, 677) -(1945, 1989, 1521) -(3140, 1983, 413) -(2474, 1078, 1280) -(960, 2653, 1768) -(3244, 889, 561) -(2129, 3119, 1296) -(1543, 4980, 696) -(2329, 3530, 1779) -(2483, 2015, 1833) -(4760, 1992, 544) -(1131, 996, 156) -(4582, 693, 133) -(4563, 159, 1853) -(485, 486, 1801) -(3318, 58, 1826) -(1498, 4937, 1497) -(770, 1802, 692) -(4269, 1062, 1873) -(286, 4273, 989) -(4106, 3950, 328) -(3047, 240, 656) -(3451, 1894, 209) -(2995, 429, 171) -(3673, 797, 785) -(3613, 2713, 1375) -(4684, 2359, 211) -(41, 4947, 653) -(2718, 4135, 1728) -(540, 4435, 543) -(4146, 2154, 398) -(1107, 856, 1200) -(1161, 320, 1117) -(1233, 2111, 223) -(4522, 4113, 263) -(2142, 4398, 352) -(796, 2713, 94) -(269, 2095, 426) -(1299, 462, 1676) -(4617, 1815, 289) -(930, 567, 1118) -(635, 408, 1859) -(651, 4154, 824) -(410, 709, 871) -(2821, 1210, 1811) -(2639, 1703, 1146) -(4100, 4611, 1997) -(3419, 1327, 1222) -(2405, 769, 913) -(2604, 4937, 1778) -(3976, 3514, 1366) -(1150, 1421, 758) -(4381, 1485, 1703) -(120, 3978, 1553) -(2318, 3292, 676) -(488, 1603, 1000) -(1710, 1119, 1884) -(922, 2906, 1916) -(2569, 1186, 1845) -(3622, 671, 1886) -(3100, 3990, 465) -(173, 720, 1493) -(449, 3249, 1475) -(997, 2560, 373) -(2378, 2030, 1843) -(3478, 773, 1747) -(3672, 172, 1510) -(2039, 902, 596) -(3562, 60, 553) -(4400, 2919, 1204) -(439, 1881, 1966) -(779, 816, 710) -(635, 346, 1246) -(251, 3841, 1857) -(4425, 3094, 983) -(4379, 2094, 1017) -(2376, 1015, 51) -(4703, 2089, 1288) -(4629, 3926, 512) -(4834, 1992, 228) -(333, 3631, 657) -(4813, 4869, 91) -(3635, 2149, 689) -(2160, 4406, 1094) -(781, 1799, 262) -(820, 4811, 203) -(3030, 1341, 402) -(2605, 4947, 1987) -(764, 4013, 1868) -(1653, 1969, 975) -(1777, 2384, 1408) -(3537, 379, 1512) -(1910, 768, 1852) -(1433, 3169, 1001) -(4042, 2032, 558) -(2890, 4200, 515) -(2755, 194, 1828) -(4018, 2102, 727) -(2191, 2466, 423) -(744, 4270, 1356) -(1448, 2165, 1664) -(1993, 1160, 1901) -(3323, 2725, 1702) -(2419, 3294, 1256) -(3185, 3745, 1654) -(3088, 4482, 617) -(4436, 2890, 1761) -(4299, 4577, 1462) -(518, 4757, 1181) -(4329, 4394, 1443) -(2319, 2318, 967) -(2559, 2741, 1070) -(4405, 2925, 1346) -(4126, 4429, 488) -(3798, 1656, 1019) -(2164, 3812, 700) -(4751, 2678, 957) -(92, 484, 118) -(4744, 2878, 1851) -(2733, 3096, 1858) -(2365, 3752, 1311) -(1663, 4187, 95) -(3564, 890, 743) -(2349, 1635, 617) -(358, 2367, 1584) -(1922, 3575, 1506) -(3255, 4966, 1210) -(4887, 1582, 1296) -(723, 4607, 1133) -(1818, 3199, 1035) -(3570, 4637, 560) -(3253, 3014, 727) -(2162, 2184, 452) -(4265, 3775, 1256) -(863, 2855, 603) -(3235, 955, 1174) -(4196, 4864, 1199) -(2597, 606, 1019) -(4287, 4523, 1722) -(2913, 793, 366) -(1779, 1062, 1070) -(4081, 3924, 870) -(2986, 71, 1249) -(370, 2296, 513) -(3889, 2206, 1432) -(2596, 2983, 1796) -(989, 4032, 948) -(3243, 3747, 1956) -(730, 3460, 1329) -(459, 4174, 1553) -(1704, 2929, 1856) -(4666, 4080, 760) -(2572, 2659, 456) -(3283, 788, 1892) -(3907, 1870, 1506) -(405, 2517, 462) -(1336, 4969, 1059) -(2866, 512, 971) -(932, 3932, 1455) -(4520, 2573, 261) -(432, 2666, 1925) -(1981, 655, 345) -(2105, 1362, 572) -(1279, 1280, 1078) -(4295, 3213, 1950) -(8, 4213, 256) -(2903, 4503, 346) -(2761, 4522, 367) -(1663, 1572, 1191) -(2164, 3143, 211) -(1057, 902, 1588) -(146, 3516, 1744) -(3969, 3136, 617) -(1407, 1215, 1233) -(2802, 2837, 652) -(3295, 193, 1776) -(356, 3617, 1308) -(2679, 2230, 591) -(3071, 1418, 746) -(1882, 4210, 627) -(716, 597, 1728) -(3843, 2072, 363) -(4841, 1856, 1094) -(2297, 2987, 776) -(3247, 3479, 1400) -(14, 1596, 1139) -(1184, 2854, 1890) -(1513, 1615, 290) -(2617, 3041, 186) -(2710, 2959, 789) -(4404, 1950, 526) -(1716, 4605, 1546) -(1110, 4164, 549) -(169, 2827, 1130) -(4069, 16, 1531) -(3964, 302, 503) -(2130, 3625, 803) -(346, 2410, 355) -(2622, 2067, 1258) -(4378, 3853, 1055) -(4914, 4202, 789) -(3032, 1913, 1900) -(371, 4038, 448) -(1838, 4290, 1792) -(576, 3566, 626) -(1651, 1768, 505) -(4354, 2151, 1234) -(4250, 4258, 383) -(2740, 605, 1178) -(1775, 363, 1582) -(1436, 4116, 1674) -(3443, 2942, 111) -(3565, 4382, 535) -(3918, 2895, 1747) -(3864, 4203, 887) -(843, 1516, 665) -(2873, 4152, 342) -(3805, 3341, 480) -(2024, 1593, 1330) -(2463, 1867, 456) -(2397, 4871, 1534) -(4397, 1256, 1622) -(277, 2563, 1844) -(2516, 2168, 173) -(2191, 1172, 1607) -(4759, 1387, 658) -(3050, 3718, 270) -(2921, 2505, 1613) -(184, 4046, 1717) -(3417, 1760, 1701) -(4721, 246, 139) -(2380, 4350, 470) -(1568, 4233, 1190) -(16, 2003, 316) -(4030, 1650, 1220) -(911, 1008, 423) -(3620, 2078, 192) -(4546, 3207, 164) -(1239, 1460, 1475) -(2682, 718, 359) -(1403, 2779, 619) -(1254, 1768, 1910) -(762, 794, 337) -(470, 3163, 411) -(182, 4095, 831) -(161, 2875, 887) -(2190, 4039, 554) -(2061, 2501, 1364) -(2264, 3823, 740) -(972, 1637, 259) -(164, 442, 846) -(3752, 2365, 1311) -(1215, 279, 807) -(3986, 2729, 1578) -(388, 290, 1133) -(2206, 953, 1705) -(4649, 115, 910) -(3978, 2723, 1203) -(2764, 835, 79) -(1717, 4773, 162) -(4871, 1524, 143) -(2029, 3695, 426) -(3786, 582, 631) -(551, 1679, 808) -(3891, 678, 350) -(3005, 819, 175) -(2553, 1997, 1933) -(2129, 4752, 1235) -(3711, 2373, 1342) -(100, 763, 1708) -(3267, 4501, 92) -(3259, 3841, 321) -(614, 565, 1922) -(241, 1239, 1128) -(204, 3549, 458) -(431, 4773, 124) -(3080, 4293, 816) -(2361, 4714, 487) -(4774, 1540, 848) -(4434, 1093, 1055) -(4142, 4874, 1550) -(821, 1050, 1763) -(1867, 2814, 467) -(798, 1724, 1850) -(3908, 882, 543) -(3950, 4025, 1082) -(3216, 3976, 89) -(633, 2214, 215) -(4568, 2766, 1079) -(3835, 2566, 1999) -(720, 3410, 327) -(911, 4124, 883) -(3587, 351, 1024) -(2197, 1826, 299) -(4055, 2706, 519) -(1136, 4079, 1395) -(817, 3511, 1807) -(370, 4351, 1558) -(3444, 306, 671) -(4256, 2568, 768) -(1149, 4986, 1689) -(4850, 4481, 759) -(1120, 1450, 1270) -(2644, 3386, 1323) -(2288, 4059, 606) -(3959, 4805, 1219) -(3431, 2240, 1573) -(1322, 3444, 715) -(4425, 1839, 1664) -(845, 4206, 1191) -(1512, 1969, 1487) -(1118, 34, 1488) -(4501, 130, 1155) -(4739, 4373, 448) -(4279, 4724, 596) -(2491, 2457, 794) -(2294, 594, 1571) -(2941, 3441, 871) -(4474, 1380, 206) -(3429, 770, 873) -(4175, 2564, 289) -(1234, 4446, 1906) -(4407, 3960, 144) -(677, 1373, 110) -(1238, 4734, 117) -(1995, 2160, 305) -(4417, 1784, 1301) -(2055, 3573, 1687) -(3922, 4556, 503) -(3063, 906, 893) -(1305, 1635, 602) -(4914, 1790, 1967) -(0, 4888, 1316) -(3760, 2434, 1229) -(3900, 835, 1813) -(3210, 1756, 430) -(3017, 3498, 1438) -(4479, 2742, 900) -(2596, 3532, 1350) -(3145, 3358, 249) -(3446, 1437, 1645) -(1878, 3558, 1276) -(1413, 3478, 994) -(354, 965, 1020) -(2782, 4716, 1057) -(3103, 2432, 760) -(306, 3444, 671) -(677, 2883, 505) -(1973, 1262, 209) -(737, 1179, 381) -(4519, 64, 847) -(3328, 3770, 695) -(4901, 4971, 1933) -(635, 4408, 1364) -(3428, 1807, 378) -(4762, 4579, 1182) -(3647, 2182, 1636) -(2747, 4902, 884) -(570, 1212, 1406) -(2179, 4863, 562) -(4901, 1108, 1303) -(159, 2765, 781) -(1436, 2819, 1191) -(4951, 4762, 1960) -(4716, 2684, 1848) -(3230, 1732, 926) -(4060, 3911, 933) -(4467, 3191, 1357) -(2466, 3900, 641) -(3055, 4204, 1381) -(4399, 1883, 490) -(1348, 231, 443) -(1190, 3602, 400) -(2070, 4471, 215) -(3074, 1180, 803) -(4099, 3684, 1670) -(4746, 1930, 881) -(830, 4071, 687) -(3769, 4915, 1061) -(2009, 3052, 1258) -(4260, 4490, 1683) -(1668, 4122, 1894) -(3011, 93, 1952) -(1964, 3441, 1678) -(447, 2007, 1182) -(4656, 3247, 900) -(1829, 2385, 1607) -(2273, 4586, 431) -(4559, 1329, 113) -(890, 3564, 743) -(4512, 3479, 372) -(4596, 3544, 540) -(3729, 965, 1639) -(2576, 2507, 974) -(2594, 4350, 356) -(4268, 2849, 1436) -(4031, 4359, 166) -(3045, 297, 724) -(1461, 2454, 630) -(4961, 784, 1739) -(3, 1218, 1227) -(3407, 1546, 277) -(4356, 80, 1380) -(1762, 663, 809) -(1164, 3999, 190) -(1912, 248, 1723) -(2573, 2354, 710) -(2191, 4530, 539) -(4940, 818, 1890) -(792, 1995, 1982) -(492, 1528, 1393) -(429, 1514, 450) -(2377, 2040, 662) -(4405, 650, 1831) -(791, 4132, 654) -(27, 3194, 1333) -(1875, 399, 1388) -(2072, 1265, 1227) -(1220, 4257, 407) -(849, 1867, 249) -(3573, 3560, 1415) -(4783, 4481, 668) -(70, 2883, 619) -(190, 2353, 1675) -(3530, 2318, 1207) -(4729, 4530, 779) -(3496, 2418, 217) -(970, 4333, 1197) -(3090, 3282, 1496) -(2737, 2612, 1151) -(2876, 2188, 1811) -(350, 775, 1231) -(1487, 140, 763) -(2339, 3810, 1062) -(538, 4617, 1270) -(3536, 1450, 302) -(526, 2654, 1292) -(256, 1102, 664) -(4125, 1972, 658) -(465, 4267, 1895) -(128, 1965, 678) -(3878, 4128, 285) -(535, 3051, 466) -(3217, 309, 1832) -(1160, 4743, 1147) -(4447, 2659, 912) -(3641, 4802, 1716) -(1138, 1612, 325) -(3253, 3715, 88) -(2115, 4068, 986) -(2697, 1881, 1959) -(3762, 1975, 1514) -(2720, 1430, 1339) -(4790, 1849, 985) -(3432, 2754, 765) -(2507, 4222, 1624) -(2083, 4010, 1760) -(4614, 799, 1531) -(3048, 4394, 1449) -(3780, 1815, 957) -(3774, 4106, 348) -(30, 4415, 238) -(3954, 4238, 1543) -(4239, 1379, 686) -(549, 2556, 1226) -(3907, 3093, 356) -(615, 1320, 1449) -(4690, 532, 1164) -(447, 3466, 1772) -(4405, 3374, 1049) -(599, 2547, 546) -(3664, 4432, 126) -(495, 706, 443) -(1584, 2409, 563) -(2138, 209, 974) -(2442, 134, 173) -(4460, 1542, 423) -(3733, 1512, 1658) -(2881, 4175, 1661) -(4122, 1791, 406) -(18, 2518, 673) -(3591, 2418, 526) -(4503, 538, 873) -(3194, 1994, 1189) -(2152, 2353, 1761) -(3501, 2610, 1139) -(4559, 2190, 1668) -(4453, 2743, 757) -(4247, 4952, 680) -(1975, 405, 1975) -(4702, 3358, 1265) -(1383, 3748, 1925) -(4773, 431, 124) -(3572, 4131, 1174) -(608, 1655, 1848) -(1624, 2300, 737) -(1363, 2064, 1324) -(4080, 2718, 589) -(4503, 2903, 346) -(560, 599, 1976) -(4430, 3264, 451) -(4194, 3424, 552) -(2035, 3586, 1594) -(4517, 3535, 1129) -(2212, 790, 1355) -(1942, 1702, 1752) -(1783, 3040, 1513) -(4439, 3654, 991) -(2476, 714, 1368) -(3584, 322, 288) -(4688, 4519, 1860) -(2662, 2035, 1774) -(3938, 2003, 331) -(4358, 36, 1382) -(3696, 4841, 912) -(1494, 3793, 1475) -(3332, 1892, 1928) -(2975, 1123, 1218) -(4772, 757, 1363) -(456, 2323, 1138) -(3339, 2164, 704) -(2632, 4879, 1188) -(721, 1352, 1749) -(2523, 3877, 561) -(2795, 1080, 497) -(965, 354, 1020) -(2669, 436, 1473) -(1640, 1028, 1307) -(3748, 3271, 1212) -(4002, 179, 193) -(3148, 1449, 1422) -(679, 4333, 1905) -(4465, 321, 1891) -(1368, 2223, 1212) -(1991, 2425, 527) -(1048, 4849, 1421) -(4874, 117, 228) -(2439, 2480, 748) -(499, 1613, 1803) -(666, 3659, 1851) -(2374, 622, 1671) -(708, 43, 1132) -(4275, 2563, 1509) -(4588, 2869, 784) -(2935, 4894, 1667) -(464, 3408, 1364) -(1031, 321, 743) -(3749, 588, 314) -(3787, 1929, 1349) -(4819, 4219, 976) -(4499, 2725, 797) -(2486, 4779, 1848) -(2412, 145, 518) -(1371, 493, 283) -(1360, 2861, 1411) -(2877, 2309, 1659) -(3095, 4786, 1295) -(1692, 3800, 1211) -(4988, 1829, 1991) -(1277, 4501, 1847) -(2740, 1015, 215) -(786, 4062, 736) -(2209, 889, 1608) -(1702, 1402, 1402) -(4934, 4134, 542) -(2719, 4339, 1570) -(3598, 786, 1783) -(1037, 3386, 340) -(4808, 3914, 1835) -(3267, 1022, 1144) -(1642, 114, 1092) -(3982, 2689, 1724) -(551, 581, 901) -(1135, 2383, 908) -(3943, 1, 282) -(1647, 3539, 855) -(4593, 336, 737) -(372, 2064, 1286) -(4122, 946, 1342) -(1088, 1026, 1043) -(1766, 2713, 1497) -(2020, 2006, 1839) -(1275, 2944, 1622) -(1711, 3958, 787) -(4893, 3263, 976) -(1896, 2989, 805) -(851, 2927, 959) -(1720, 2735, 871) -(1941, 3617, 1294) -(1081, 403, 1445) -(86, 79, 1363) -(775, 4904, 1543) -(465, 4597, 796) -(1068, 2098, 1731) -(629, 3935, 639) -(2372, 4953, 852) -(1311, 1306, 1330) -(1854, 3166, 1126) -(360, 343, 1564) -(3457, 3284, 1319) -(4426, 3927, 710) -(2014, 1132, 788) -(4894, 2881, 1499) -(3565, 4215, 256) -(4342, 23, 229) -(900, 168, 1547) -(2191, 4788, 1508) -(721, 509, 1597) -(914, 3397, 1806) -(475, 117, 1745) -(2836, 2526, 496) -(1666, 1220, 78) -(3907, 1254, 1031) -(3592, 4801, 407) -(1924, 2007, 868) -(3309, 4647, 778) -(2361, 2373, 1035) -(4290, 3685, 349) -(4405, 3226, 672) -(4005, 328, 1470) -(1419, 3707, 380) -(2911, 2955, 755) -(50, 1733, 935) -(2174, 4026, 353) -(466, 3235, 1942) -(670, 2421, 780) -(2197, 97, 200) -(4875, 1180, 915) -(1356, 4664, 633) -(3597, 3782, 126) -(1372, 3214, 1192) -(1394, 1490, 1565) -(3499, 568, 328) -(3462, 716, 1170) -(4486, 3279, 1206) -(2201, 943, 190) -(4955, 2723, 305) -(2433, 2015, 1928) -(3765, 3321, 1431) -(403, 3535, 785) -(1189, 3045, 73) -(2064, 982, 635) -(3981, 2506, 84) -(208, 4488, 593) -(3306, 2489, 1249) -(2227, 1478, 680) -(2831, 4747, 731) -(4877, 4092, 1604) -(3636, 2712, 1739) -(73, 3409, 243) -(3966, 1957, 1992) -(3103, 211, 370) -(1247, 3348, 1219) -(3811, 3166, 725) -(1834, 2685, 1465) -(4876, 4764, 1851) -(4723, 3476, 1910) -(3641, 4137, 1395) -(2444, 2632, 1640) -(3836, 709, 1317) -(3982, 1233, 830) -(3762, 2060, 1924) -(2089, 3236, 1233) -(3483, 3669, 904) -(4428, 4688, 614) -(1964, 2361, 1928) -(4138, 2605, 893) -(266, 531, 546) -(4355, 3403, 812) -(3319, 2095, 1310) -(621, 1585, 940) -(4034, 1220, 387) -(4306, 19, 322) -(2548, 3187, 948) -(2363, 773, 1457) -(1217, 298, 1182) -(4913, 3821, 1298) -(4476, 679, 1934) -(1193, 653, 1752) -(4509, 1286, 226) -(4978, 1761, 1041) -(2123, 2157, 54) -(2102, 2764, 1597) -(2791, 4558, 114) -(2256, 3576, 1012) -(4098, 2131, 775) -(103, 1903, 864) -(2342, 189, 1835) -(2280, 3436, 927) -(4905, 1034, 675) -(1873, 2584, 291) -(469, 1354, 676) -(414, 325, 879) -(521, 2197, 1919) -(2933, 3427, 1943) -(2309, 1569, 1519) -(2720, 2440, 1500) -(1711, 766, 822) -(1036, 1928, 409) -(630, 1571, 753) -(3214, 1372, 1192) -(2216, 4227, 1573) -(1893, 743, 1894) -(3546, 4913, 515) -(2428, 1185, 1925) -(981, 3899, 981) -(1627, 4530, 1117) -(215, 961, 399) -(3983, 2976, 336) -(81, 835, 1267) -(3060, 4275, 1733) -(4866, 1570, 361) -(1000, 4178, 658) -(506, 816, 74) -(4445, 783, 1240) -(2511, 467, 1556) -(2928, 1554, 1067) -(3675, 1942, 1183) -(4661, 2131, 1380) -(2743, 4453, 757) -(4908, 3296, 1392) -(4177, 1566, 1000) -(1187, 2398, 749) -(4093, 1324, 174) -(812, 3987, 1878) -(4930, 2604, 1894) -(77, 104, 1323) -(1528, 492, 1393) -(3744, 3497, 516) -(4929, 3936, 951) -(3690, 32, 824) -(4374, 3647, 478) -(1179, 4803, 1497) -(3141, 4264, 1526) -(1353, 3783, 1869) -(4581, 1406, 344) -(4733, 1890, 979) -(2598, 1906, 1255) -(2166, 3501, 1064) -(3712, 718, 881) -(4384, 2003, 1654) -(2959, 3913, 1304) -(4120, 4564, 1201) -(3881, 736, 149) -(1252, 1673, 1185) -(1565, 4107, 122) -(4020, 4956, 409) -(1761, 1183, 1212) -(2579, 1889, 1498) -(2527, 1209, 107) -(4053, 841, 989) -(3968, 3267, 169) -(1297, 1381, 1701) -(4373, 1476, 338) -(224, 2056, 940) -(2080, 2298, 488) -(3970, 3017, 462) -(3943, 2571, 1423) -(3712, 3288, 1022) -(2221, 187, 389) -(4623, 323, 1345) -(1546, 4699, 1584) -(2891, 3867, 623) -(594, 4690, 481) -(2195, 2016, 318) -(4208, 1717, 699) -(4257, 3582, 261) -(1417, 2297, 1336) -(933, 2782, 1601) -(3625, 494, 605) -(4901, 453, 109) -(1906, 3033, 777) -(724, 1205, 684) -(3771, 4332, 1591) -(3117, 2547, 743) -(2247, 1400, 1703) -(869, 3960, 1093) -(903, 2739, 1553) -(2662, 2226, 1598) -(305, 4601, 1575) -(4327, 1745, 343) -(1718, 860, 1075) -(3814, 2353, 658) -(302, 418, 815) -(4101, 2914, 1987) -(4149, 2477, 1377) -(1832, 3279, 651) -(402, 1632, 302) -(2465, 2411, 712) -(3575, 863, 1965) -(4578, 2473, 1687) -(4379, 2232, 201) -(1653, 4961, 310) -(486, 2858, 1389) -(294, 1465, 262) -(385, 4207, 1039) -(4747, 3708, 1031) -(891, 2218, 1551) -(1352, 2696, 925) -(2270, 1349, 1011) -(921, 4677, 1261) -(490, 4283, 1960) -(3766, 3230, 1718) -(582, 2064, 819) -(491, 4845, 388) -(850, 4203, 973) -(1167, 2485, 420) -(3721, 1294, 1072) -(1613, 2136, 328) -(3565, 4878, 1656) -(2293, 3137, 893) -(733, 1908, 701) -(1554, 1966, 1261) -(3998, 3542, 1967) -(570, 4575, 280) -(4917, 2981, 181) -(1998, 4842, 1180) -(4322, 1900, 100) -(3702, 1421, 1683) -(609, 3365, 286) -(2547, 1738, 344) -(808, 144, 1839) -(704, 2365, 461) -(3019, 530, 1043) -(40, 2926, 1360) -(1470, 3436, 1631) -(3431, 4975, 1793) -(2872, 487, 1070) -(2212, 3144, 1743) -(306, 165, 1742) -(819, 3005, 175) -(2627, 2923, 710) -(99, 3294, 1821) -(4755, 2565, 1620) -(1309, 1409, 233) -(2003, 3938, 331) -(897, 2195, 550) -(3564, 663, 932) -(2526, 2992, 126) -(1170, 1609, 1132) -(2910, 4062, 568) -(2614, 3730, 542) -(2206, 4541, 386) -(2778, 2605, 675) -(2283, 3193, 1836) -(1406, 3367, 1612) -(4386, 3556, 1681) -(3370, 1385, 1690) -(3579, 3392, 1544) -(2089, 1216, 901) -(1078, 3994, 1976) -(170, 1451, 1482) -(4265, 4513, 375) -(2377, 118, 1175) -(2094, 4262, 1916) -(3591, 2788, 573) -(1856, 4841, 1094) -(476, 1711, 951) -(4149, 4831, 328) -(2783, 698, 1373) -(3377, 3963, 920) -(41, 690, 71) -(3596, 4970, 254) -(2455, 1894, 885) -(4423, 989, 1967) -(3284, 4433, 285) -(1938, 385, 495) -(2815, 3196, 919) -(108, 1506, 1037) -(2734, 3358, 401) -(4950, 3322, 1795) -(1417, 1974, 973) -(1366, 4874, 1191) -(4321, 3332, 1636) -(108, 2885, 614) -(322, 3584, 288) -(3733, 2020, 840) -(1294, 4931, 1249) -(3065, 4494, 1641) -(600, 2402, 692) -(2263, 2938, 1350) -(4361, 1861, 1319) -(4415, 30, 238) -(57, 4009, 611) -(638, 4823, 1469) -(1665, 597, 1749) -(856, 1107, 1200) -(4445, 3143, 364) -(4947, 3291, 1332) -(4522, 208, 448) -(4435, 1233, 1179) -(888, 2899, 638) -(271, 1418, 314) -(4048, 752, 939) -(2746, 4575, 1032) -(2510, 1132, 1336) -(1265, 2614, 1517) -(4405, 133, 1450) -(3236, 2089, 1233) -(4780, 1879, 1837) -(489, 275, 71) -(4035, 782, 1916) -(3840, 3804, 224) -(3710, 3468, 389) -(4091, 2714, 879) -(4573, 2696, 885) -(2177, 2362, 375) -(3091, 1914, 392) -(3275, 3049, 550) -(4773, 4051, 474) -(3508, 4061, 1116) -(3367, 4357, 1678) -(4163, 4092, 1723) -(789, 2091, 1452) -(2855, 3862, 1641) -(2177, 2475, 512) -(3385, 566, 1646) -(3141, 4125, 739) -(297, 4410, 1882) -(4204, 3919, 1422) -(4753, 2259, 798) -(3383, 748, 1958) -(1811, 4678, 963) -(2212, 4968, 1273) -(2823, 3212, 971) -(3002, 2211, 108) -(3006, 2306, 549) -(1651, 1862, 1156) -(1100, 3206, 1973) -(1728, 3369, 748) -(3754, 4628, 1638) -(1187, 4381, 500) -(3436, 2442, 1755) -(2745, 4584, 791) -(1402, 1702, 1402) -(4610, 827, 660) -(3498, 3017, 1438) -(2570, 900, 1121) -(115, 4649, 910) -(1190, 1639, 77) -(463, 3842, 940) -(2800, 2052, 1202) -(4158, 259, 1956) -(973, 2171, 1374) -(3742, 2536, 1291) -(1361, 2303, 245) -(1836, 3589, 1507) -(4401, 362, 892) -(2244, 343, 582) -(1534, 3082, 1802) -(3479, 2575, 1762) -(3553, 487, 686) -(2722, 3503, 1526) -(1988, 3135, 277) -(4756, 4100, 1177) -(3022, 1632, 713) -(1588, 429, 1815) -(3895, 1619, 1823) -(2057, 1056, 1819) -(4719, 4946, 463) -(295, 1558, 1797) -(598, 141, 1210) -(3650, 1904, 592) -(3134, 2979, 1093) -(4672, 782, 305) -(1345, 4784, 1443) -(4424, 3200, 1096) -(2976, 4429, 1710) -(2353, 4705, 269) -(1919, 4401, 1197) -(2158, 2944, 243) -(1712, 2101, 1880) -(1920, 2882, 1120) -(4802, 3961, 1242) -(50, 2258, 752) -(2596, 226, 769) -(1845, 2375, 1418) -(1421, 3702, 1683) -(2368, 1763, 1113) -(2885, 4035, 751) -(4752, 2129, 1235) -(2805, 1716, 1501) -(1551, 2861, 673) -(1462, 4557, 1660) -(2439, 812, 416) -(3942, 3740, 1555) -(4414, 4777, 1981) -(4369, 459, 899) -(628, 4158, 860) -(1445, 210, 649) -(1001, 3191, 628) -(3988, 3325, 98) -(3076, 566, 590) -(3839, 2648, 495) -(3511, 306, 1805) -(4632, 4951, 281) -(3768, 1803, 1676) -(3575, 2925, 347) -(3932, 2319, 1350) -(2435, 4270, 832) -(4060, 3150, 782) -(983, 3396, 1308) -(3700, 2586, 675) -(1217, 4760, 1135) -(3353, 203, 380) -(110, 976, 549) -(2531, 2285, 1235) -(3576, 2256, 1012) -(93, 2474, 1028) -(2332, 662, 1241) -(2693, 4371, 1823) -(3163, 781, 1692) -(2878, 4881, 661) -(745, 1035, 570) -(708, 3225, 1248) -(1743, 1671, 458) -(2749, 4151, 375) -(1710, 353, 1748) -(2995, 3196, 1786) -(3750, 3569, 1386) -(2494, 2418, 113) -(4464, 391, 1698) -(57, 3081, 1200) -(2528, 2785, 803) -(2153, 480, 1292) -(2342, 4818, 63) -(3716, 1289, 1106) -(1400, 2247, 1703) -(2551, 1130, 135) -(4472, 2197, 619) -(740, 0, 582) -(2473, 489, 1162) -(2774, 2949, 1697) -(4918, 2222, 1509) -(1464, 4206, 400) -(81, 600, 1374) -(416, 4880, 1976) -(504, 1741, 1487) -(1140, 4902, 703) -(1729, 1165, 583) -(600, 2080, 1747) -(4641, 1631, 768) -(275, 968, 1774) -(153, 1744, 1820) -(291, 3415, 1088) -(3525, 880, 1088) -(1665, 919, 1712) -(65, 3652, 1853) -(4752, 1282, 1817) -(4884, 4957, 858) -(1380, 3436, 93) -(2772, 4073, 1344) -(2509, 2788, 1069) -(3805, 2169, 1003) -(4072, 3441, 1527) -(244, 466, 1130) -(2598, 2481, 1154) -(3778, 3466, 844) -(4120, 4021, 677) -(2413, 2613, 131) -(4191, 3530, 1572) -(1773, 2379, 974) -(2340, 1661, 1588) -(2447, 1723, 463) -(1992, 4834, 228) -(1344, 3769, 1972) -(199, 3462, 1418) -(3312, 4548, 1927) -(3077, 1248, 1573) -(3203, 1790, 1049) -(826, 4170, 1686) -(2245, 3033, 702) -(4228, 471, 857) -(4646, 2882, 1407) -(4262, 1431, 1321) -(2278, 4120, 1065) -(1197, 1864, 635) -(2949, 1878, 1240) -(718, 105, 1039) -(4641, 3710, 1227) -(642, 2818, 1573) -(2780, 3198, 1975) -(3119, 4155, 1098) -(2777, 632, 1108) -(1373, 1553, 1294) -(4580, 844, 395) -(2585, 3024, 334) -(756, 331, 495) -(2415, 2721, 1049) -(3034, 1445, 930) -(839, 2384, 1579) -(1938, 937, 1604) -(742, 4972, 1847) -(1849, 3330, 897) -(2133, 3149, 1699) -(3229, 1744, 767) -(4523, 3456, 1907) -(2205, 1020, 1872) -(3051, 535, 466) -(4793, 2181, 1215) -(1320, 1099, 1911) -(4975, 2165, 1607) -(1493, 4611, 340) -(4970, 1103, 1637) -(761, 2669, 1835) -(1586, 3654, 572) -(1679, 551, 808) -(3062, 2188, 234) -(926, 1683, 1481) -(3226, 1785, 81) -(686, 2112, 607) -(4207, 1635, 290) -(832, 2496, 570) -(2814, 2789, 200) -(865, 3255, 362) -(2824, 2209, 1744) -(1032, 3574, 1424) -(149, 3453, 502) -(2034, 1746, 1525) -(2177, 357, 1109) -(959, 3757, 1039) -(1802, 3577, 445) -(3379, 3702, 1660) -(817, 2829, 880) -(3089, 208, 667) -(1061, 4787, 267) -(3409, 2447, 1028) -(4708, 2284, 1264) -(2823, 2724, 441) -(4086, 151, 910) -(2317, 3053, 1877) -(4424, 4609, 1564) -(1145, 3333, 1729) -(904, 2859, 163) -(623, 2229, 841) -(1959, 4632, 1344) -(2238, 1053, 1506) -(1065, 4128, 1229) -(1369, 333, 1678) -(2798, 993, 158) -(2991, 2774, 1941) -(4167, 2160, 1723) -(1117, 1433, 670) -(4382, 4293, 518) -(245, 3425, 1890) -(1747, 2965, 815) -(836, 4574, 1831) -(557, 1312, 553) -(4070, 3283, 1464) -(2266, 936, 270) -(4976, 176, 1799) -(4316, 1969, 1629) -(2330, 4826, 1088) -(1528, 4273, 178) -(4514, 359, 1430) -(4061, 3508, 1116) -(1570, 4866, 361) -(1113, 1473, 1082) -(4442, 4956, 1922) -(3601, 863, 988) -(3448, 1753, 1562) -(864, 3270, 850) -(1946, 3806, 570) -(751, 4583, 1477) -(1719, 795, 584) -(946, 4122, 1342) -(394, 1027, 940) -(940, 4214, 1203) -(3929, 1239, 470) -(4005, 3582, 1631) -(3636, 1399, 1219) -(3195, 3201, 403) -(933, 2858, 658) -(27, 1198, 266) -(3697, 3551, 83) -(1029, 4011, 1414) -(2356, 2101, 748) -(4523, 4287, 1722) -(4095, 182, 831) -(1129, 4376, 51) -(3180, 3518, 574) -(1451, 582, 54) -(1673, 2468, 55) -(1535, 4132, 352) -(130, 2744, 580) -(770, 3429, 873) -(154, 102, 876) -(3476, 2783, 267) -(1920, 1463, 373) -(3535, 1836, 231) -(3345, 4936, 1733) -(177, 1651, 1378) -(4721, 4294, 999) -(3072, 2260, 317) -(1356, 281, 601) -(273, 2208, 1555) -(4501, 2155, 1811) -(479, 2827, 894) -(761, 1168, 682) -(2410, 1049, 1248) -(2505, 3639, 851) -(1171, 3744, 1339) -(1480, 4023, 1885) -(2017, 1766, 644) -(1980, 1006, 1356) -(3558, 1878, 1276) -(496, 3310, 940) -(2688, 4172, 1856) -(3163, 470, 411) -(3219, 488, 1111) -(3405, 2753, 771) -(2392, 2336, 1244) -(1577, 14, 939) -(2603, 1867, 1676) -(3776, 655, 1046) -(4867, 2848, 586) -(4673, 286, 1996) -(1969, 2272, 1561) -(3659, 666, 1851) -(3381, 1896, 1327) -(5, 1715, 257) -(2662, 2093, 525) -(3527, 1290, 904) -(3297, 797, 1781) -(2477, 4159, 1534) -(1202, 3892, 958) -(4601, 3479, 177) -(3919, 4204, 1422) -(972, 3183, 1941) -(2197, 3631, 1879) -(4527, 1239, 200) -(2306, 4521, 1343) -(4521, 2306, 1343) -(4756, 2527, 201) -(3537, 1771, 963) -(4751, 4384, 1111) -(1577, 2524, 283) -(2301, 2261, 488) -(702, 2443, 207) -(1765, 1135, 1120) -(4458, 1179, 1967) -(2466, 4332, 1371) -(4855, 3606, 1218) -(816, 1134, 768) -(1348, 181, 122) -(4839, 4651, 265) -(1709, 4820, 1956) -(59, 2061, 1658) -(661, 4818, 568) -(651, 2323, 445) -(2124, 1443, 939) -(4658, 3596, 384) -(4236, 2789, 1684) -(2428, 3884, 110) -(3783, 463, 1252) -(1377, 2071, 669) -(1731, 3488, 1890) -(4603, 79, 873) -(1460, 2917, 599) -(4245, 1636, 638) -(1359, 964, 114) -(297, 1598, 1057) -(4468, 483, 713) -(203, 3353, 380) -(2278, 559, 1514) -(181, 3725, 907) -(400, 4455, 740) -(1656, 4756, 1033) -(3349, 974, 1486) -(406, 1120, 882) -(464, 1896, 1027) -(4384, 4751, 1111) -(4847, 4537, 981) -(98, 3944, 1021) -(2437, 3180, 1918) -(4109, 602, 494) -(3407, 1951, 1384) -(4399, 1628, 452) -(4985, 4109, 544) -(2905, 672, 1197) -(3117, 2695, 998) -(3274, 1787, 1247) -(2138, 3889, 776) -(2886, 428, 1929) -(3716, 3842, 839) -(4515, 2613, 1401) -(2409, 1848, 1421) -(4564, 816, 1707) -(833, 440, 856) -(1979, 3073, 1729) -(1718, 87, 120) -(2046, 352, 956) -(3699, 2727, 1316) -(3451, 4728, 1537) -(1604, 1710, 846) -(3449, 396, 1480) -(556, 3448, 577) -(1350, 4867, 510) -(843, 3227, 161) -(3321, 1266, 1078) -(1315, 1385, 429) -(839, 2283, 217) -(653, 1696, 1661) -(2912, 290, 630) -(336, 4593, 737) -(223, 3910, 842) -(1608, 2616, 885) -(3941, 4587, 1238) -(831, 3817, 907) -(3611, 460, 871) -(2997, 759, 1028) -(4938, 1555, 1507) -(4671, 835, 1255) -(2563, 277, 1844) -(2094, 3265, 1364) -(2701, 4071, 1339) -(2117, 2680, 53) -(3482, 1841, 147) -(2966, 2438, 600) -(4852, 4645, 120) -(3853, 1730, 527) -(470, 4961, 1824) -(2586, 1716, 1407) -(3311, 2988, 1412) -(1135, 406, 1847) -(1080, 2952, 781) -(368, 1962, 852) -(4026, 678, 1981) -(1220, 2856, 599) -(4720, 2462, 807) -(1509, 589, 1948) -(2469, 4312, 1719) -(4362, 535, 256) -(861, 3742, 546) -(3549, 204, 458) -(223, 4909, 1089) -(897, 486, 1074) -(4053, 1740, 1798) -(4523, 1145, 891) -(3254, 2079, 1820) -(25, 1596, 793) -(79, 881, 103) -(2719, 188, 1916) -(2759, 899, 309) -(4696, 4914, 1713) -(3054, 837, 1825) -(1171, 829, 1213) -(4689, 1226, 802) -(3724, 4093, 1048) -(692, 4488, 1590) -(2642, 443, 1829) -(4918, 2501, 1995) -(1769, 3562, 1680) -(3767, 2019, 1118) -(4293, 244, 1352) -(2362, 718, 1882) -(122, 1643, 1985) -(4569, 1396, 1808) -(1135, 1765, 1120) -(4749, 1621, 988) -(3964, 4935, 209) -(3121, 175, 1771) -(1905, 4658, 363) -(3747, 79, 1868) -(4954, 821, 732) -(789, 3855, 1445) -(4913, 3546, 515) -(3767, 2442, 1570) -(3057, 1877, 291) -(4641, 4493, 948) -(4804, 616, 639) -(2912, 588, 1702) -(3205, 1231, 788) -(110, 1103, 639) -(2683, 907, 1203) -(3263, 3257, 1893) -(479, 2927, 727) -(4485, 4348, 1584) -(3693, 4587, 1576) -(2547, 4692, 1363) -(4714, 4700, 1811) -(1341, 1901, 1384) -(2520, 2793, 674) -(2341, 745, 1300) -(2986, 222, 1672) -(2115, 3500, 173) -(3011, 2534, 1318) -(286, 588, 1573) -(2487, 2635, 1709) -(171, 546, 1078) -(1101, 4879, 1434) -(2968, 4663, 1947) -(3771, 819, 1302) -(2656, 3026, 1094) -(214, 1128, 1329) -(4419, 839, 547) -(4508, 3610, 877) -(3528, 1328, 1429) -(310, 3775, 1229) -(1504, 3394, 1093) -(3900, 629, 1579) -(2964, 2828, 1092) -(228, 3144, 1296) -(1055, 3748, 1254) -(309, 3442, 1065) -(58, 99, 1240) -(3270, 864, 850) -(3602, 3066, 564) -(171, 704, 818) -(1070, 1836, 118) -(4553, 1072, 1354) -(564, 809, 150) -(4338, 2977, 1634) -(4889, 450, 170) -(3006, 1554, 1671) -(441, 3062, 1629) -(1938, 2940, 527) -(1862, 1651, 1156) -(527, 3084, 1332) -(2829, 503, 1176) -(1065, 3297, 523) -(3537, 3260, 1607) -(1185, 1527, 838) -(4673, 4142, 71) -(624, 1091, 1197) -(4548, 4644, 1280) -(649, 4310, 838) -(767, 559, 790) -(4472, 1071, 1372) -(3250, 583, 321) -(1639, 83, 1721) -(4342, 2857, 627) -(3889, 2467, 1033) -(1543, 4017, 1408) -(2722, 2803, 1972) -(1948, 4871, 1986) -(1404, 1388, 747) -(2704, 3271, 1893) -(1798, 462, 654) -(3330, 2823, 1132) -(3286, 1556, 1164) -(4720, 2832, 452) -(1724, 4459, 917) -(2769, 4800, 1847) -(1277, 127, 566) -(819, 3771, 1302) -(1482, 3161, 248) -(4202, 4914, 789) -(1053, 2238, 1506) -(1662, 3530, 205) -(3539, 460, 1984) -(4377, 929, 1546) -(57, 116, 340) -(414, 120, 109) -(4747, 2831, 731) -(4799, 4702, 1500) -(1301, 4051, 1550) -(3029, 498, 853) -(2011, 182, 991) -(3227, 843, 161) -(4391, 4626, 1980) -(1383, 2285, 922) -(1099, 1028, 783) -(3737, 3057, 1352) -(582, 1766, 921) -(958, 4070, 1145) -(4180, 437, 1667) -(2382, 708, 654) -(2510, 3897, 1074) -(4934, 618, 1569) -(2073, 3686, 1062) -(4253, 4764, 67) -(4080, 247, 1781) -(1097, 1271, 1643) -(4722, 272, 1253) -(1737, 2302, 1594) -(4000, 1517, 204) -(4170, 3223, 1933) -(2399, 1027, 1729) -(3251, 3018, 1932) -(1413, 407, 338) -(3423, 4415, 1837) -(3451, 3702, 849) -(353, 1791, 433) -(1324, 3074, 960) -(1377, 4376, 1759) -(3575, 525, 430) -(500, 1046, 957) -(1873, 1703, 1199) -(1962, 368, 852) -(3245, 579, 569) -(3405, 1145, 861) -(3274, 885, 355) -(4750, 27, 1971) -(2350, 1452, 200) -(2681, 4903, 713) -(260, 236, 1770) -(1894, 2455, 885) -(4922, 1348, 1802) -(529, 3757, 828) -(894, 1305, 80) -(2523, 348, 1166) -(2367, 4927, 1048) -(3170, 984, 1877) -(4107, 1488, 1071) -(1877, 4084, 188) -(2757, 1951, 1880) -(4399, 856, 1180) -(3106, 1929, 379) -(162, 3984, 1561) -(525, 4634, 577) -(4666, 1437, 1174) -(3392, 3579, 1544) -(709, 3288, 954) -(3090, 1412, 1606) -(1472, 2534, 1623) -(707, 4210, 1736) -(4918, 2695, 1829) -(4199, 4031, 129) -(2956, 1931, 1044) -(4821, 2123, 1490) -(1800, 3217, 459) -(2803, 4222, 1826) -(106, 2902, 733) -(1315, 1348, 247) -(360, 3194, 119) -(169, 297, 345) -(580, 3687, 995) -(81, 3505, 800) -(1673, 46, 657) -(173, 4548, 1363) -(3113, 4500, 1510) -(4717, 909, 551) -(1892, 2962, 474) -(3381, 535, 717) -(3943, 1975, 570) -(345, 818, 1245) -(2874, 203, 493) -(4891, 286, 559) -(764, 2250, 398) -(763, 100, 1708) -(1631, 4641, 768) -(2325, 2157, 219) -(4717, 1760, 775) -(3773, 109, 1038) -(2507, 2576, 974) -(4713, 963, 879) -(2751, 4552, 122) -(3903, 448, 296) -(59, 2796, 687) -(3401, 3075, 324) -(3648, 4909, 762) -(4164, 347, 1986) -(4325, 13, 1018) -(2837, 4574, 881) -(970, 3669, 775) -(4930, 4950, 1655) -(108, 3089, 1094) -(2136, 1271, 818) -(4020, 736, 571) -(2597, 3158, 1240) -(1150, 271, 1424) -(2052, 2800, 1202) -(1677, 2197, 386) -(1696, 653, 1661) -(1234, 4652, 490) -(385, 3970, 437) -(41, 54, 72) -(821, 4954, 732) -(553, 4865, 1787) -(3148, 635, 1882) -(1889, 2071, 949) -(1096, 4517, 1731) -(1428, 737, 56) -(570, 716, 418) -(1892, 2592, 1418) -(4237, 1031, 91) -(3083, 3028, 1221) -(4359, 4031, 166) -(3044, 2089, 1365) -(2773, 3507, 521) -(876, 2889, 576) -(1652, 526, 603) -(1428, 3078, 1493) -(4777, 2810, 1667) -(3709, 39, 278) -(1801, 1934, 1969) -(4733, 413, 1595) -(2164, 3491, 1433) -(4573, 4115, 1291) -(473, 2770, 1181) -(3186, 3086, 1505) -(1302, 4426, 245) -(818, 4940, 1890) -(725, 1384, 1562) -(1598, 1995, 1175) -(4922, 935, 1084) -(971, 3601, 812) -(1566, 1309, 449) -(2897, 1591, 757) -(3562, 3191, 288) -(846, 468, 1342) -(3088, 1368, 683) -(1850, 3074, 1761) -(966, 3525, 1905) -(2081, 1954, 1018) -(2526, 4844, 124) -(3713, 4984, 1071) -(138, 3379, 1747) -(3753, 2830, 1753) -(3147, 3115, 478) -(1441, 3308, 674) -(2500, 4310, 247) -(4839, 1638, 1485) -(2056, 224, 940) -(4586, 1461, 627) -(3913, 1308, 1788) -(2008, 458, 1223) -(3937, 946, 866) -(2872, 1582, 1429) -(4578, 3446, 1992) -(1926, 3916, 1382) -(1320, 1330, 245) -(890, 1883, 600) -(4134, 2742, 857) -(4404, 3333, 1978) -(3742, 377, 76) -(3266, 430, 980) -(326, 1423, 233) -(2421, 1477, 1295) -(740, 1885, 1238) -(3464, 4846, 272) -(680, 4824, 1729) -(3777, 2102, 1040) -(397, 2776, 1088) -(1048, 2140, 435) -(2947, 916, 787) -(2259, 4753, 798) -(2316, 4953, 1083) -(1527, 228, 1153) -(2057, 3255, 1808) -(632, 2777, 1108) -(4500, 604, 404) -(3363, 1145, 1975) -(2086, 4919, 1876) -(1060, 1795, 1457) -(3619, 4432, 871) -(192, 1054, 1882) -(1190, 1466, 1818) -(434, 1675, 1268) -(956, 4711, 1684) -(3127, 4740, 1199) -(4231, 615, 492) -(1129, 2528, 1195) -(4228, 532, 268) -(3495, 4512, 1598) -(402, 2649, 545) -(2822, 3558, 445) -(4970, 4371, 258) -(871, 3399, 1018) -(1098, 3353, 1712) -(2768, 1084, 564) -(3971, 3487, 798) -(4950, 2025, 700) -(2902, 1554, 609) -(1177, 1710, 551) -(1777, 4940, 328) -(1035, 312, 1953) -(3143, 171, 1316) -(2216, 3835, 514) -(3901, 1871, 1099) -(3463, 4168, 969) -(913, 2212, 639) -(2701, 669, 1591) -(966, 1732, 1449) -(122, 2741, 1746) -(1104, 2074, 210) -(1799, 3082, 1497) -(3283, 1712, 1007) -(4283, 268, 1297) -(4182, 957, 685) -(1373, 4586, 1097) -(2121, 2743, 89) -(1700, 1421, 1869) -(2789, 4244, 1026) -(2834, 3974, 1706) -(1255, 4415, 883) -(4047, 1714, 1537) -(2098, 520, 612) -(2697, 1234, 1413) -(4644, 3938, 1480) -(449, 4672, 322) -(1896, 464, 1027) -(3302, 3023, 1237) -(3564, 1526, 326) -(3122, 3745, 1223) -(1540, 4742, 1099) -(2478, 977, 691) -(667, 462, 919) -(4805, 1394, 977) -(3534, 1239, 1074) -(2682, 2915, 55) -(1325, 3237, 1410) -(2993, 2772, 129) -(2188, 3062, 234) -(537, 3546, 606) -(2487, 3437, 882) -(1861, 843, 1574) -(3945, 1137, 520) -(4477, 1208, 1480) -(863, 3601, 988) -(2926, 40, 1360) -(1287, 3984, 1716) -(582, 1466, 1716) -(3988, 3067, 806) -(449, 4450, 937) -(3423, 4166, 611) -(897, 3766, 1255) -(4747, 3396, 418) -(254, 4334, 262) -(513, 3610, 1311) -(139, 767, 1256) -(4501, 317, 1976) -(889, 3244, 561) -(243, 3648, 1775) -(1324, 1522, 934) -(1171, 573, 1227) -(47, 3210, 427) -(3191, 1001, 628) -(2199, 4952, 875) -(4673, 2913, 1850) -(3899, 2998, 1419) -(4719, 2801, 1095) -(3605, 4556, 1433) -(1720, 4691, 712) -(3069, 4615, 1713) -(4858, 379, 1340) -(1931, 3499, 1945) -(2591, 2578, 1514) -(3078, 1428, 1493) -(4222, 226, 1609) -(2067, 2190, 680) -(4137, 3641, 1395) -(4084, 93, 160) -(2519, 355, 891) -(655, 1981, 345) -(2993, 4012, 212) -(1800, 1798, 1145) -(3340, 1793, 693) -(3306, 1487, 64) -(1966, 2935, 439) -(1395, 4560, 1495) -(3903, 2268, 365) -(1143, 4883, 1449) -(3110, 1065, 723) -(912, 106, 208) -(4914, 1711, 1757) -(4535, 4225, 1023) -(1770, 3571, 1569) -(1888, 708, 1233) -(3102, 3997, 138) -(1563, 4877, 406) -(4548, 173, 1363) -(4783, 4619, 1462) -(2556, 1423, 1973) -(3143, 3381, 1986) -(661, 4904, 1890) -(2782, 933, 1601) -(226, 4623, 924) -(3652, 31, 1722) -(4658, 1940, 958) -(3617, 3096, 159) -(823, 3749, 126) -(3438, 176, 868) -(1266, 2617, 1650) -(2914, 3123, 644) -(87, 1718, 120) -(2390, 2490, 1714) -(2177, 808, 289) -(1294, 4198, 951) -(787, 1080, 1005) -(4950, 3803, 129) -(1983, 3140, 413) -(3154, 4339, 82) -(1808, 1018, 1138) -(4777, 3324, 108) -(4892, 4096, 1203) -(3790, 1844, 293) -(3469, 4213, 1647) -(1517, 1248, 1503) -(2631, 3241, 1353) -(1260, 1417, 280) -(805, 676, 427) -(3125, 2447, 1199) -(1987, 3756, 1976) -(3435, 747, 271) -(933, 3755, 913) -(2833, 1835, 1277) -(3904, 3858, 1185) -(3707, 839, 825) -(2578, 4934, 502) -(1289, 3716, 1106) -(4951, 4838, 202) -(4969, 2456, 951) -(2212, 4159, 1371) -(1527, 3849, 365) -(4564, 4120, 1201) -(1954, 3142, 670) -(69, 1546, 1305) -(1244, 1886, 313) -(1838, 3272, 924) -(1213, 3681, 1775) -(3100, 1706, 914) -(2950, 1963, 1832) -(4283, 490, 1960) -(257, 2468, 1880) -(177, 2129, 1366) -(1809, 514, 1317) -(4970, 4693, 971) -(1143, 4213, 277) -(1577, 3710, 1031) -(960, 4420, 162) -(2253, 894, 624) -(1794, 4732, 1576) -(2326, 2526, 1991) -(546, 557, 201) -(1973, 916, 169) -(3152, 2704, 474) -(4529, 2604, 1204) -(3494, 132, 112) -(229, 2097, 1046) -(2884, 4207, 1338) -(3275, 4533, 1035) -(3075, 26, 1054) -(297, 3045, 724) -(1391, 221, 1446) -(3062, 1991, 1273) -(4229, 3989, 583) -(1605, 3873, 1995) -(3898, 2669, 1283) -(2061, 59, 1658) -(4774, 3408, 124) -(776, 2105, 1003) -(780, 4930, 431) -(2509, 3103, 1602) -(1781, 1760, 1405) -(3882, 3314, 1331) -(847, 1474, 754) -(865, 4485, 1059) -(1994, 1927, 1781) -(1953, 1598, 780) -(1264, 3752, 1348) -(2913, 1902, 1863) -(2177, 2792, 1091) -(4745, 791, 1164) -(4341, 1642, 594) -(3431, 2114, 1892) -(3483, 2974, 420) -(3563, 24, 53) -(4605, 219, 809) -(1614, 3607, 1980) -(4243, 542, 144) -(2390, 3166, 291) -(732, 1509, 341) -(1193, 525, 1668) -(219, 4104, 1285) -(2258, 2540, 1382) -(3860, 2563, 1432) -(2303, 2286, 1998) -(2361, 1414, 1323) -(2118, 1792, 1036) -(2947, 3166, 702) -(160, 1870, 1822) -(4667, 2951, 1683) -(2415, 857, 661) -(2893, 1010, 368) -(907, 2683, 1203) -(4220, 2971, 1990) -(2906, 4176, 591) -(1275, 2338, 526) -(1836, 2524, 546) -(422, 1936, 1163) -(2817, 2306, 1048) -(2234, 910, 1623) -(638, 4628, 1145) -(3684, 4099, 1670) -(1639, 1190, 77) -(820, 4971, 76) -(2495, 443, 690) -(4205, 1096, 542) -(1108, 4901, 1303) -(676, 450, 1855) -(1078, 2474, 1280) -(550, 2259, 1135) -(3873, 475, 77) -(1907, 2867, 1935) -(4632, 1959, 1344) -(509, 721, 1597) -(3079, 2252, 1124) -(4881, 2878, 661) -(2286, 110, 1756) -(2368, 2636, 450) -(1437, 3446, 1645) -(3550, 1683, 1548) -(2184, 4051, 1498) -(4707, 3545, 1637) -(2864, 949, 361) -(973, 1149, 1149) -(863, 2233, 1663) -(3505, 4912, 1642) -(2728, 3088, 1717) -(2613, 2610, 1217) -(1855, 478, 641) -(2222, 4918, 1509) -(3257, 3178, 946) -(2666, 432, 1925) -(4208, 4120, 118) -(1866, 4964, 1248) -(3508, 757, 1317) -(3488, 1998, 673) -(1377, 4846, 1870) -(1930, 4940, 1360) -(2580, 192, 1772) -(2743, 532, 392) -(1614, 1921, 1786) -(1421, 39, 1028) -(4918, 3687, 253) -(2732, 1803, 1730) -(3784, 60, 230) -(3531, 4664, 861) -(3289, 2426, 1933) -(4172, 2688, 1856) -(1332, 1166, 141) -(4223, 4756, 1865) -(711, 3267, 730) -(4134, 3122, 60) -(1993, 2261, 1025) -(1224, 3031, 953) -(328, 236, 468) -(522, 2352, 1648) -(1865, 3039, 1895) -(1896, 3381, 1327) -(2076, 1942, 362) -(1981, 4011, 1067) -(259, 4691, 1149) -(3297, 796, 881) -(1418, 4250, 1007) -(4691, 960, 1315) -(4397, 1289, 500) -(4985, 2055, 1986) -(3660, 2249, 1910) -(3376, 4309, 494) -(747, 3435, 271) -(900, 1245, 1697) -(4968, 2505, 140) -(4553, 1051, 1255) -(3148, 353, 221) -(4531, 1171, 908) -(2790, 4163, 1570) -(2649, 525, 979) -(114, 4431, 1935) -(2205, 4820, 992) -(788, 286, 1639) -(1752, 4336, 384) -(991, 3441, 1777) -(570, 1599, 1369) -(3465, 2877, 1833) -(1569, 1491, 1900) -(1760, 1994, 1799) -(2089, 4703, 1288) -(342, 2091, 1698) -(1248, 3077, 1573) -(1337, 1603, 489) -(1535, 416, 747) -(3081, 57, 1200) -(3534, 1021, 1592) -(3965, 423, 1285) -(2194, 4771, 1417) -(4419, 291, 1096) -(755, 3455, 1686) -(2931, 4889, 1439) -(3704, 3035, 1398) -(506, 1020, 1748) -(3614, 4383, 743) -(2285, 1691, 1286) -(4764, 437, 861) -(2962, 2032, 1592) -(3228, 47, 736) -(385, 2835, 1334) -(2169, 2222, 1252) -(3468, 3710, 389) -(4779, 129, 423) -(2319, 4673, 1540) -(4966, 4666, 445) -(1008, 4109, 87) -(1795, 3451, 276) -(4404, 1872, 412) -(4529, 2115, 1640) -(1201, 2882, 1385) -(2616, 2067, 595) -(4127, 2760, 407) -(3050, 1503, 419) -(846, 2693, 200) -(2203, 3637, 240) -(419, 832, 502) -(3008, 2765, 1939) -(4909, 4261, 890) -(3067, 3332, 1564) -(2171, 973, 1374) -(3320, 2542, 548) -(3963, 3377, 920) -(3771, 2692, 1032) -(4245, 1861, 1443) -(1262, 1973, 209) -(2626, 1359, 1149) -(3806, 479, 994) -(3794, 417, 583) -(1388, 1359, 280) -(4876, 4212, 1329) -(2359, 1855, 532) -(139, 3550, 996) -(3793, 2397, 1756) -(593, 3411, 768) -(3398, 2816, 716) -(1939, 2900, 779) -(81, 1823, 772) -(3692, 3685, 137) -(2461, 663, 165) -(1791, 4122, 406) -(4245, 1006, 1440) -(4787, 1061, 267) -(4477, 4549, 1915) -(2862, 913, 1324) -(4258, 1222, 435) -(2116, 339, 1558) -(2473, 4578, 1687) -(4354, 3925, 663) -(267, 1475, 1873) -(3411, 3532, 380) -(2617, 1266, 1650) -(1837, 1628, 1727) -(3543, 1301, 378) -(4611, 1493, 340) -(1707, 646, 167) -(2865, 44, 1557) -(1997, 2553, 1933) -(392, 100, 1794) -(851, 1153, 1600) -(4405, 1362, 1964) -(438, 2984, 1997) -(4695, 1488, 731) -(1569, 2851, 1173) -(4632, 4338, 1603) -(1926, 1444, 1854) -(1711, 3252, 708) -(3372, 3820, 1760) -(1994, 4869, 1360) -(281, 1356, 601) -(4678, 2264, 1492) -(246, 2404, 1141) -(4484, 4719, 931) -(2539, 1878, 962) -(4022, 2150, 1427) -(4458, 3063, 1849) -(863, 2559, 436) -(2030, 1597, 1729) -(3652, 2279, 919) -(672, 776, 505) -(1867, 2603, 1676) -(1933, 4920, 526) -(87, 913, 498) -(3804, 2474, 1206) -(3368, 4363, 1353) -(3601, 971, 812) -(2685, 1834, 1465) -(608, 1867, 1931) -(1553, 1716, 307) -(4098, 3844, 1166) -(4284, 3490, 1717) -(1192, 2088, 1693) -(1863, 1727, 382) -(2725, 3323, 1702) -(2078, 3620, 192) -(4486, 378, 814) -(3382, 1116, 774) -(1600, 1129, 187) -(1713, 3090, 936) -(839, 4419, 547) -(723, 818, 1231) -(254, 4608, 330) -(3919, 3924, 916) -(4466, 632, 462) -(3676, 4855, 606) -(1898, 1594, 1561) -(4126, 2056, 1876) -(2861, 1360, 1411) -(1503, 1681, 2000) -(271, 3720, 389) -(2555, 2310, 999) -(3733, 16, 980) -(2362, 4784, 1850) -(363, 3192, 930) -(4017, 95, 255) -(1038, 2114, 1148) -(1078, 3135, 514) -(2656, 2275, 1889) -(2622, 891, 1973) -(2593, 2819, 1931) -(2252, 1761, 849) -(2751, 3257, 1298) -(2256, 2276, 518) -(934, 3019, 1209) -(1723, 2447, 463) -(1140, 4895, 512) -(2963, 4477, 1781) -(2267, 3852, 1469) -(4154, 28, 661) -(2640, 2482, 424) -(1676, 3002, 276) -(1900, 3602, 949) -(3042, 726, 927) -(1069, 829, 484) -(3146, 1125, 1543) -(3713, 2409, 721) -(3535, 4517, 1129) -(1518, 3816, 904) -(4270, 4701, 664) -(215, 3033, 1108) -(1102, 1486, 1252) -(4904, 3864, 1097) -(2765, 962, 518) -(831, 4039, 838) -(4215, 490, 1945) -(888, 4510, 992) -(2409, 225, 1121) -(1050, 2358, 1972) -(2987, 2172, 886) -(837, 3054, 1825) -(2304, 1104, 1528) -(1118, 1701, 305) -(1030, 3884, 1198) -(1199, 3204, 1975) -(788, 306, 1657) -(1675, 434, 1268) -(1727, 2037, 1997) -(1253, 3714, 1744) -(4894, 2310, 1822) -(1151, 1483, 430) -(3419, 506, 547) -(1423, 1765, 347) -(3838, 4655, 771) -(209, 1737, 1042) -(2640, 1759, 1971) -(1, 3943, 282) -(4183, 4918, 1315) -(1799, 781, 262) -(1735, 2919, 1508) -(902, 2869, 1166) -(128, 2897, 1762) -(3674, 1182, 1257) -(249, 1921, 147) -(2836, 14, 1443) -(1748, 368, 1995) -(14, 1577, 939) -(1882, 4108, 745) -(3105, 1748, 533) -(360, 746, 220) -(1745, 3793, 1429) -(1588, 919, 1379) -(2540, 4500, 400) -(538, 635, 646) -(70, 4477, 1711) -(4271, 1258, 1586) -(581, 551, 901) -(767, 1232, 1140) -(120, 282, 1316) -(3945, 916, 1350) -(4342, 292, 1112) -(1768, 1651, 505) -(2565, 95, 1113) -(3041, 1574, 51) -(3775, 4855, 995) -(1158, 3821, 1961) -(1211, 4360, 623) -(2945, 2880, 872) -(4300, 2620, 1760) -(1423, 303, 78) -(2499, 3022, 297) -(583, 108, 1516) -(523, 3850, 1718) -(1897, 2830, 1951) -(3268, 774, 625) -(2348, 941, 844) -(1716, 1634, 685) -(715, 3170, 821) -(4085, 2109, 1772) -(4555, 2646, 814) -(2840, 4522, 1289) -(2061, 2300, 1031) -(3048, 4264, 1363) -(796, 3297, 881) -(3784, 1276, 1008) -(98, 2159, 870) -(951, 1403, 637) -(336, 2394, 571) -(1716, 1553, 307) -(1554, 660, 1687) -(113, 1689, 927) -(565, 1311, 543) -(3066, 406, 290) -(2238, 4303, 1457) -(2005, 4245, 1521) -(1561, 2020, 411) -(4910, 1357, 1137) -(4597, 188, 1831) -(3355, 2195, 1343) -(177, 4788, 1495) -(345, 4666, 1013) -(4132, 791, 654) -(525, 1575, 251) -(4083, 4855, 1159) -(4376, 1377, 1759) -(2973, 4121, 941) -(3090, 4011, 210) -(1624, 299, 1619) -(4638, 1997, 1194) -(3083, 1325, 231) -(1499, 4416, 1051) -(1974, 4742, 801) -(608, 3611, 1023) -(2694, 3186, 556) -(4953, 2372, 852) -(4635, 3893, 675) -(4426, 135, 810) -(52, 1442, 620) -(4183, 3793, 325) -(1161, 614, 929) -(1789, 3072, 1878) -(2967, 1635, 497) -(3820, 3372, 1760) -(4127, 941, 851) -(1061, 4954, 1357) -(2670, 1501, 979) -(1558, 807, 1815) -(1165, 1364, 461) -(728, 1076, 1931) -(595, 4245, 267) -(631, 3283, 989) -(1330, 4781, 672) -(2202, 3470, 56) -(1023, 1544, 850) -(3104, 3354, 182) -(2222, 1989, 1902) -(1765, 2155, 1371) -(610, 3071, 1672) -(406, 1135, 1847) -(2560, 312, 1148) -(2547, 4964, 1262) -(281, 1497, 1789) -(3961, 2604, 380) -(232, 3433, 639) -(3526, 4660, 1871) -(2574, 4257, 104) -(742, 2546, 1738) -(203, 1908, 360) -(3446, 4578, 1992) -(3167, 3119, 1465) -(4419, 1316, 963) -(158, 3564, 925) -(1925, 1700, 497) -(1169, 4019, 1939) -(4722, 3683, 1194) -(4877, 1411, 771) -(1920, 4153, 550) -(2718, 2484, 1504) -(2218, 3667, 1892) -(4764, 4200, 772) -(3665, 1941, 1435) -(3937, 1896, 405) -(107, 2657, 953) -(3078, 248, 565) -(2635, 3310, 1792) -(3310, 2447, 1715) -(3323, 521, 1242) -(1077, 4143, 578) -(1007, 3546, 293) -(4230, 3251, 145) -(3101, 3089, 742) -(2926, 1709, 728) -(1975, 639, 1897) -(818, 345, 1245) -(1391, 1908, 1095) -(795, 4869, 1696) -(4100, 1682, 833) -(2082, 4385, 1892) -(19, 3515, 1014) -(698, 2783, 1373) -(4840, 3208, 1396) -(4426, 1089, 1812) -(3072, 3134, 1371) -(3457, 490, 686) -(4076, 4247, 750) -(4982, 1098, 1427) -(4628, 3281, 74) -(3769, 4809, 222) -(1087, 1532, 1419) -(2109, 785, 1764) -(4494, 4248, 313) -(859, 3751, 965) -(1020, 2205, 1872) -(1918, 351, 148) -(4069, 587, 1299) -(2763, 3900, 677) -(3214, 4397, 1916) -(2629, 4339, 495) -(2781, 1854, 1108) -(4395, 2459, 1865) -(2811, 2500, 842) -(3341, 3805, 480) -(3529, 2271, 415) -(1867, 2463, 456) -(4446, 2930, 1346) -(3938, 1787, 579) -(2060, 1206, 954) -(3880, 2500, 1422) -(4506, 821, 1228) -(3974, 883, 1113) -(4728, 371, 1648) -(4645, 3334, 252) -(1454, 3551, 87) -(3361, 1205, 790) -(1261, 4634, 814) -(3284, 3457, 1319) -(770, 4820, 157) -(3470, 9, 1198) -(4768, 4561, 544) -(3540, 4362, 456) -(2336, 1632, 156) -(1646, 3567, 1517) -(1369, 3649, 1528) -(1320, 615, 1449) -(2751, 3243, 802) -(2115, 875, 1481) -(929, 3415, 1632) -(3769, 444, 1326) -(114, 1642, 1092) -(4628, 638, 1145) -(1632, 2336, 156) -(2321, 2503, 1549) -(4574, 1685, 665) -(1870, 446, 189) -(1571, 3543, 1083) -(242, 2414, 970) -(4877, 1286, 1413) -(1399, 610, 1755) -(4686, 4904, 1003) -(3, 968, 1251) -(420, 3262, 464) -(775, 350, 1231) -(3315, 3299, 1711) -(4195, 2301, 557) -(4871, 1948, 1986) -(1327, 4302, 1978) -(3362, 1274, 1648) -(1602, 859, 1663) -(494, 629, 552) -(1728, 2262, 484) -(159, 4125, 1019) -(557, 546, 201) -(860, 4030, 1313) -(2905, 671, 1052) -(4009, 4832, 571) -(2008, 3705, 289) -(3375, 966, 1383) -(846, 512, 1929) -(740, 3, 733) -(3974, 620, 1768) -(1954, 79, 286) -(862, 4498, 558) -(3256, 2186, 1139) -(3493, 2275, 1745) -(194, 2887, 1747) -(4998, 740, 1911) -(4296, 4419, 1775) -(3928, 104, 1690) -(1286, 4509, 226) -(4471, 2070, 215) -(786, 3598, 1783) -(3058, 2769, 742) -(3922, 3706, 248) -(34, 1207, 173) -(4094, 4348, 827) -(1989, 4820, 1715) -(2199, 1871, 1907) -(91, 606, 59) -(926, 4563, 626) -(1526, 700, 836) -(685, 2036, 104) -(3931, 3965, 1349) -(2892, 4393, 1931) -(4580, 4846, 1647) -(2262, 661, 1765) -(2300, 1624, 737) -(4957, 1372, 1535) -(3058, 524, 1280) -(4866, 3113, 265) -(439, 2385, 1682) -(3566, 4569, 694) -(555, 3772, 408) -(4416, 2322, 514) -(381, 2565, 1759) -(151, 169, 1388) -(3870, 4156, 1243) -(2315, 4277, 946) -(4456, 4434, 1322) -(3993, 21, 279) -(759, 1110, 833) -(480, 2205, 409) -(2129, 177, 1366) -(3454, 2349, 662) -(22, 958, 874) -(714, 3806, 1518) -(1085, 4541, 341) -(423, 2675, 1360) -(3017, 3970, 462) -(3777, 2199, 291) -(4120, 1157, 1734) -(2407, 4114, 621) -(4165, 3891, 1270) -(332, 3301, 1467) -(2979, 736, 399) -(1321, 3454, 1897) -(4209, 1079, 1881) -(114, 1235, 607) -(2695, 4918, 1829) -(868, 4862, 1150) -(3926, 798, 1798) -(4239, 4460, 1271) -(198, 2812, 1759) -(3234, 348, 292) -(1054, 4600, 1345) -(2608, 2916, 1337) -(691, 1203, 1723) -(3368, 1238, 346) -(541, 692, 1245) -(3792, 660, 1012) -(3648, 338, 1248) -(4552, 2751, 122) -(2741, 3741, 1322) -(2757, 4718, 631) -(2729, 3986, 1578) -(4496, 4411, 870) -(295, 2533, 874) -(1873, 340, 102) -(2898, 681, 893) -(2148, 88, 1762) -(1065, 161, 503) -(3429, 3907, 655) -(3638, 1601, 335) -(1787, 1961, 690) -(3907, 4580, 1985) -(119, 1382, 1089) -(1054, 192, 1882) -(2330, 4280, 256) -(337, 3123, 887) -(3785, 2804, 1101) -(3468, 3200, 399) -(2955, 2911, 755) -(759, 389, 592) -(2899, 881, 1882) -(1308, 1993, 1589) -(3081, 2301, 702) -(228, 1527, 1153) -(1018, 2289, 1214) -(490, 154, 1079) -(2972, 2490, 1412) -(4668, 4359, 1563) -(4084, 4388, 1312) -(1430, 2720, 1339) -(4572, 47, 124) -(532, 147, 637) -(4173, 2988, 1591) -(227, 1209, 809) -(937, 4718, 1378) -(3867, 3451, 1121) -(639, 1892, 1257) -(1204, 2817, 302) -(1091, 624, 1197) -(3465, 963, 352) -(3323, 883, 1500) -(2381, 560, 698) -(899, 3605, 642) -(3352, 2593, 909) -(4286, 3089, 1470) -(4546, 1750, 294) -(4032, 2565, 1067) -(2521, 3009, 797) -(4501, 3267, 92) -(3143, 4445, 364) -(2153, 4345, 456) -(2470, 1126, 1177) -(4923, 4896, 1146) -(3745, 3032, 813) -(777, 750, 1452) -(4399, 2039, 1174) -(30, 2350, 1984) -(1061, 2822, 163) -(2797, 505, 892) -(3382, 2895, 1388) -(4176, 1954, 351) -(3206, 501, 1765) -(4791, 2611, 427) -(2846, 3868, 1861) -(1752, 3459, 1477) -(4915, 3769, 1061) -(3897, 2510, 1074) -(3649, 1369, 1528) -(4183, 161, 1199) -(3490, 3026, 255) -(1157, 4156, 1885) -(2805, 4391, 1343) -(1310, 2543, 1508) -(1666, 4780, 1851) -(3116, 1538, 1961) -(896, 91, 1632) -(3084, 1332, 882) -(852, 4505, 825) -(1574, 4168, 1834) -(3925, 1600, 1226) -(2799, 4212, 888) -(3001, 4133, 369) -(4013, 4580, 1204) -(1237, 1643, 791) -(988, 2632, 1925) -(251, 2099, 1039) -(2789, 4851, 898) -(4318, 3819, 1607) -(925, 4076, 543) -(1916, 4276, 701) -(4774, 3191, 982) -(2958, 4789, 1336) -(2731, 693, 892) -(2859, 2040, 1688) -(1522, 2024, 1011) -(2530, 814, 433) -(4396, 3817, 1968) -(384, 2082, 982) -(3207, 4546, 164) -(4606, 4640, 1239) -(1101, 3579, 87) -(4714, 4010, 523) -(2882, 4646, 1407) -(2481, 2598, 1154) -(2130, 3865, 1175) -(4906, 1706, 1129) -(4494, 1682, 1935) -(2044, 2649, 888) -(1297, 4382, 749) -(2789, 3544, 637) -(4202, 1167, 1656) -(3270, 235, 1164) -(2345, 4951, 1486) -(2357, 848, 1252) -(855, 865, 531) -(1613, 2633, 744) -(4051, 1301, 1550) -(2772, 2993, 129) -(2477, 2411, 1061) -(2, 3175, 1981) -(880, 3563, 1484) -(4522, 3974, 711) -(1239, 991, 1761) -(1116, 2898, 1758) -(3263, 4656, 1596) -(1142, 1678, 660) -(3160, 2818, 61) -(2466, 2191, 423) -(3849, 3960, 766) -(2247, 4901, 1799) -(1173, 1874, 285) -(450, 676, 1855) -(2103, 18, 457) -(4789, 2958, 1336) -(1537, 2386, 1235) -(3820, 65, 583) -(3946, 2820, 84) -(4944, 982, 1371) -(1455, 660, 629) -(111, 2435, 195) -(3177, 4310, 1828) -(3689, 3740, 1697) -(1060, 4048, 180) -(4652, 1234, 490) -(486, 1209, 1963) -(2069, 31, 1770) -(49, 1252, 1357) -(56, 2070, 318) -(1035, 1682, 1228) -(3190, 3072, 1176) -(4923, 925, 796) -(1850, 2876, 143) -(1506, 108, 1037) -(2627, 2630, 593) -(4964, 1866, 1248) -(2969, 1938, 1428) -(385, 3597, 1532) -(4225, 4848, 1471) -(777, 2687, 1303) -(3560, 3573, 1415) -(196, 2349, 958) -(2147, 4137, 461) -(4024, 4375, 950) -(4864, 4196, 1199) -(2630, 4091, 1582) -(2024, 2971, 970) -(3341, 3455, 466) -(420, 1, 1310) -(4843, 626, 695) -(3229, 2000, 1939) -(2801, 4719, 1095) -(17, 4626, 320) -(4077, 1249, 797) -(476, 801, 683) -(4237, 2015, 1173) -(113, 4710, 328) -(4082, 1209, 326) -(414, 1571, 1298) -(2422, 4204, 553) -(1122, 254, 651) -(3507, 3524, 937) -(352, 2258, 1186) -(2398, 1526, 1951) -(3415, 291, 1088) -(1818, 3205, 567) -(1070, 1370, 203) -(4697, 2350, 1445) -(3441, 1964, 1678) -(1204, 1992, 73) -(2785, 1984, 1480) -(3408, 2612, 759) -(2901, 1212, 1252) -(453, 232, 1900) -(44, 4510, 1533) -(4507, 3905, 267) -(4951, 1802, 1374) -(1430, 3254, 1283) -(2033, 3005, 676) -(4929, 2800, 58) -(409, 2406, 70) -(1174, 3536, 361) -(1168, 3553, 1015) -(2307, 575, 1527) -(4481, 2405, 1191) -(145, 2412, 518) -(4510, 51, 1978) -(4088, 25, 535) -(466, 244, 1130) -(4923, 438, 730) -(2178, 816, 846) -(4603, 4954, 564) -(2016, 1280, 84) -(1613, 2392, 1037) -(296, 3351, 1742) -(4544, 3449, 1652) -(772, 3442, 568) -(4335, 1887, 884) -(1319, 4, 918) -(4591, 3777, 1641) -(3431, 4836, 400) -(1531, 2641, 854) -(4569, 3566, 694) -(2259, 382, 952) -(202, 1185, 848) -(2210, 3715, 953) -(2659, 1562, 1881) -(4582, 3841, 646) -(3562, 1769, 1680) -(3351, 3827, 1964) -(3306, 2442, 1730) -(4910, 1682, 743) -(2460, 900, 1281) -(3572, 1142, 1491) -(1142, 1292, 1112) -(2733, 2020, 1397) -(261, 2253, 716) -(2821, 2200, 643) -(13, 4325, 1018) -(4457, 2026, 1125) -(2447, 2982, 868) -(3775, 3165, 188) -(1140, 4681, 865) -(3158, 2597, 1240) -(2125, 3668, 1844) -(2895, 624, 1890) -(2037, 979, 1184) -(2454, 382, 1543) -(1681, 1667, 1124) -(1240, 1203, 1694) -(522, 222, 1450) -(1440, 2799, 1864) -(1671, 4762, 1419) -(3165, 1086, 399) -(2186, 718, 85) -(4047, 4890, 1688) -(2591, 4240, 1756) -(1690, 4878, 882) -(3695, 2770, 1854) -(48, 96, 1686) -(2752, 3621, 1011) -(4100, 2065, 1457) -(1639, 2922, 651) -(4153, 3993, 797) -(890, 871, 1735) -(4434, 4456, 1322) -(2110, 1030, 655) -(1271, 2902, 119) -(4909, 1056, 319) -(1664, 3132, 1923) -(2503, 628, 1541) -(3843, 4761, 1429) -(1777, 4809, 1427) -(974, 1683, 835) -(1036, 442, 259) -(881, 3264, 317) -(4137, 2147, 461) -(4411, 3980, 1869) -(4786, 4196, 357) -(1317, 883, 1334) -(1859, 4520, 195) -(616, 1264, 98) -(3216, 2266, 1863) -(441, 3476, 1748) -(2411, 4661, 344) -(4764, 4876, 1851) -(2827, 2910, 1013) -(1375, 4234, 1089) -(35, 2808, 530) -(4723, 575, 389) -(4503, 1005, 223) -(4138, 139, 526) -(83, 3827, 923) -(2011, 4789, 1590) -(2513, 1497, 1001) -(881, 1459, 670) -(4547, 3073, 1070) -(4072, 2325, 1017) -(107, 4890, 629) -(3921, 252, 1504) -(4557, 4251, 431) -(3076, 1549, 84) -(2098, 880, 1068) -(2483, 3010, 1215) -(3045, 4256, 1764) -(548, 4796, 1314) -(2387, 4042, 1668) -(1470, 486, 672) -(437, 525, 498) -(3928, 2420, 198) -(361, 4282, 544) -(2785, 2994, 1049) -(2598, 3272, 1161) -(3205, 3120, 935) -(3502, 4798, 160) -(65, 2970, 67) -(216, 198, 595) -(2146, 1163, 993) -(4362, 2181, 1977) -(261, 902, 763) -(3908, 1453, 907) -(1614, 3395, 906) -(4179, 1710, 1709) -(4638, 162, 931) -(2565, 2678, 1061) -(1495, 699, 1457) -(2104, 747, 51) -(1408, 637, 1284) -(2824, 1252, 1482) -(4113, 3346, 1319) -(1585, 659, 695) -(1732, 966, 1449) -(2729, 4116, 277) -(2124, 3981, 1374) -(2293, 2253, 604) -(4994, 1813, 718) -(3074, 4895, 1157) -(2729, 1065, 1384) -(3177, 1753, 1355) -(1370, 2143, 1061) -(1013, 4745, 422) -(222, 2986, 1672) -(4597, 1898, 935) -(4959, 4471, 138) -(3361, 4109, 1097) -(1981, 3481, 547) -(1509, 732, 341) -(352, 3666, 1004) -(1432, 4501, 448) -(1544, 1707, 1625) -(943, 1191, 1734) -(3517, 1073, 1030) -(4837, 868, 414) -(2669, 3415, 1462) -(2963, 1372, 1677) -(3204, 1123, 559) -(4159, 2477, 1534) -(1035, 3240, 1691) -(1053, 447, 383) -(569, 4153, 1673) -(4282, 2089, 157) -(2814, 1867, 467) -(2638, 2529, 1320) -(3077, 1109, 646) -(2101, 1712, 1880) -(3214, 2606, 1224) -(3106, 2959, 866) -(255, 227, 1615) -(1874, 1173, 285) -(3184, 4662, 1613) -(1283, 4878, 1047) -(128, 3868, 1686) -(1910, 3331, 1502) -(4358, 4841, 1392) -(3828, 108, 443) -(2181, 4793, 1215) -(1223, 2042, 696) -(4242, 3695, 428) -(4700, 4714, 1811) -(338, 4933, 1064) -(414, 308, 1141) -(2965, 3038, 681) -(3914, 2969, 707) -(1870, 680, 1322) -(421, 558, 814) -(2829, 817, 880) -(3728, 4064, 581) -(2795, 1019, 350) -(4241, 3819, 630) -(2615, 3596, 522) -(117, 4972, 1002) -(2765, 159, 781) -(3465, 825, 390) -(2318, 4982, 605) -(1823, 582, 816) -(2253, 2103, 1824) -(116, 57, 340) -(2967, 3423, 1319) -(2303, 2409, 1874) -(4647, 1414, 1847) -(571, 2970, 834) -(3723, 950, 573) -(1267, 3453, 1650) -(1308, 3476, 215) -(2277, 1402, 1238) -(3585, 905, 1073) -(1672, 4956, 675) -(4981, 3217, 1834) -(1188, 3764, 63) -(514, 4103, 1655) -(1822, 4301, 1751) -(961, 2655, 1269) -(2593, 3352, 909) -(2113, 2390, 1583) -(2259, 550, 1135) -(438, 461, 1171) -(4126, 110, 140) -(874, 1747, 340) -(580, 174, 67) -(3150, 460, 723) -(537, 3931, 104) -(3253, 3429, 1690) -(1450, 1120, 1270) -(132, 703, 1263) -(2597, 2435, 1499) -(1260, 1187, 203) -(782, 4672, 305) -(1228, 3733, 1006) -(1419, 3856, 1584) -(4029, 3708, 305) -(2942, 3130, 1093) -(4069, 2055, 1087) -(374, 70, 1291) -(445, 3912, 1123) -(4023, 2998, 851) -(3105, 1788, 1115) -(4970, 3596, 254) -(1271, 1097, 1643) -(1341, 3030, 402) -(3314, 1680, 1247) -(4135, 2718, 1728) -(784, 3618, 1635) -(420, 4921, 469) -(32, 3690, 824) -(716, 3462, 1170) -(3843, 3504, 1643) -(2389, 4967, 1381) -(2959, 4271, 1995) -(3622, 2671, 709) -(346, 2450, 700) -(3133, 206, 149) -(3427, 2933, 1943) -(4620, 4769, 517) -(3884, 3227, 1932) -(2092, 4141, 1793) -(431, 707, 685) -(4870, 1802, 1474) -(3642, 3148, 1143) -(3725, 581, 1574) -(3208, 1434, 944) -(4984, 4145, 1751) -(58, 4005, 916) -(2833, 752, 67) -(2719, 568, 718) -(4280, 3775, 112) -(348, 2523, 1166) -(13, 3059, 1324) -(4958, 2003, 1080) -(4518, 4044, 1566) -(2855, 361, 1356) -(3240, 3461, 300) -(2889, 3705, 1808) -(2819, 110, 1562) -(600, 2569, 1256) -(631, 2053, 1610) -(4988, 350, 1086) -(119, 125, 387) -(4886, 655, 468) -(2244, 2971, 1222) -(3614, 1238, 1279) -(298, 3918, 1814) -(2969, 270, 161) -(2385, 439, 1682) -(1689, 1109, 1104) -(898, 2702, 1057) -(1498, 85, 1762) -(2448, 2631, 858) -(768, 1910, 1852) -(378, 1652, 1045) -(2043, 2069, 458) -(4568, 1691, 1879) -(4700, 1884, 1391) -(1490, 667, 1793) -(4265, 3225, 846) -(2084, 1092, 939) -(4981, 2057, 1625) -(488, 3219, 1111) -(4522, 1204, 1728) -(3847, 1169, 410) -(2777, 4162, 1544) -(2107, 927, 159) -(642, 1262, 1321) -(39, 578, 1223) -(4926, 4358, 715) -(3563, 880, 1484) -(3744, 3886, 1041) -(2802, 3894, 1313) -(961, 3477, 217) -(3078, 1505, 644) -(1175, 605, 1987) -(3676, 4902, 1109) -(4698, 509, 1632) -(1683, 22, 1251) -(4102, 2998, 834) -(2394, 336, 571) -(4485, 1112, 350) -(780, 3416, 1639) -(2289, 526, 1846) -(1759, 1599, 913) -(2820, 3946, 84) -(4898, 669, 1572) -(2306, 2342, 1766) -(1709, 2754, 185) -(1120, 4474, 1551) -(3486, 2005, 1672) -(2982, 3151, 846) -(1768, 652, 76) -(3750, 4921, 240) -(1231, 587, 1359) -(3481, 827, 493) -(1720, 2412, 1366) -(3647, 4770, 141) -(1383, 1467, 1587) -(2128, 72, 270) -(192, 4200, 1186) -(4052, 1655, 1043) -(4870, 2362, 1078) -(4432, 2386, 299) -(3196, 4307, 1595) -(4723, 3445, 1148) -(4709, 1758, 1964) -(814, 2475, 1571) -(549, 228, 666) -(4947, 41, 653) -(2532, 2792, 186) -(2488, 4891, 154) -(1156, 3291, 437) -(1461, 2525, 937) -(2093, 4721, 135) -(4135, 1429, 854) -(3810, 2339, 1062) -(2392, 1615, 1960) -(3563, 4085, 440) -(632, 2113, 1648) -(3029, 2993, 1883) -(2474, 93, 1028) -(992, 4652, 420) -(3909, 2109, 1872) -(240, 3047, 656) -(3579, 2555, 1839) -(3815, 3075, 1308) -(4139, 414, 376) -(3514, 3976, 1366) -(3208, 2212, 836) -(556, 2234, 1665) -(4261, 291, 1898) -(3777, 4591, 1641) -(533, 3177, 1057) -(1596, 628, 155) -(3513, 1052, 1919) -(711, 3210, 1928) -(4998, 492, 1245) -(2331, 4770, 1852) -(1325, 2186, 424) -(2684, 1079, 560) -(4551, 4649, 1583) -(3422, 2610, 628) -(360, 4803, 125) -(929, 4923, 1794) -(2141, 4850, 1713) -(1364, 599, 797) -(1761, 2252, 849) -(1517, 4046, 1333) -(290, 3115, 1484) -(1038, 2425, 1092) -(4785, 23, 1555) -(1771, 4803, 604) -(2772, 2411, 1503) -(1213, 3541, 95) -(2699, 3095, 1368) -(1877, 618, 945) -(991, 1239, 1761) -(1617, 1009, 529) -(2365, 1731, 439) -(1172, 25, 192) -(2505, 2921, 1613) -(1774, 848, 1945) -(1575, 3287, 1565) -(486, 485, 1801) -(3439, 2161, 443) -(2134, 4820, 1129) -(1381, 1297, 1701) -(276, 35, 1158) -(4054, 3990, 1794) -(2786, 4542, 168) -(1125, 2602, 1066) -(1962, 1935, 1016) -(2965, 809, 515) -(3941, 372, 355) -(1265, 1091, 1918) -(3855, 2408, 949) -(62, 4944, 618) -(3835, 1573, 948) -(2817, 4477, 1803) -(4040, 667, 879) -(1791, 353, 433) -(3536, 3154, 1035) -(1133, 1824, 327) -(1886, 3302, 200) -(686, 1038, 1074) -(2628, 4444, 1193) -(1113, 4383, 530) -(4892, 2039, 1523) -(3985, 363, 725) -(2108, 2441, 1192) -(902, 1262, 659) -(4051, 4773, 474) -(4198, 3243, 1430) -(1016, 590, 1710) -(4043, 2858, 391) -(4392, 3613, 1727) -(1028, 1315, 1643) -(17, 631, 187) -(1406, 2131, 648) -(3770, 2190, 661) -(2793, 2520, 674) -(3200, 4901, 1447) -(1052, 3513, 1919) -(4035, 2885, 751) -(1331, 760, 690) -(376, 1160, 706) -(837, 3077, 1428) -(3813, 3504, 139) -(4635, 2141, 1332) -(1401, 3254, 1137) -(108, 583, 1516) -(943, 2201, 190) -(2261, 4514, 1564) -(615, 4231, 492) -(515, 1077, 510) -(4202, 3343, 1710) -(2056, 3646, 617) -(4115, 377, 1882) -(2161, 4310, 1083) -(562, 796, 249) -(4029, 2424, 1165) -(1768, 4774, 1241) -(3785, 4248, 1729) -(4845, 491, 388) -(3462, 199, 1418) -(1445, 2283, 864) -(2415, 1910, 351) -(4970, 774, 1885) -(4585, 1326, 1313) -(1922, 3892, 653) -(974, 2021, 177) -(1691, 4568, 1879) -(3597, 4857, 558) -(664, 4795, 1926) -(4631, 733, 1504) -(2344, 3175, 1724) -(1423, 2556, 1973) -(3429, 665, 276) -(3880, 1895, 1307) -(3740, 4576, 504) -(2984, 3152, 505) -(4482, 2235, 858) -(1664, 4483, 571) -(1188, 300, 1541) -(4301, 3243, 269) -(4281, 3882, 394) -(3608, 2686, 423) -(2350, 3234, 1364) -(4232, 738, 1904) -(4840, 599, 1245) -(618, 4394, 1818) -(1261, 2300, 938) -(4161, 2128, 486) -(1627, 3377, 1025) -(2708, 2123, 924) -(3190, 2677, 1832) -(343, 2996, 1021) -(2181, 4249, 696) -(1345, 4646, 1586) -(1734, 4152, 1181) -(3441, 2941, 871) -(1433, 1858, 1251) -(1711, 531, 653) -(4694, 513, 555) -(1449, 1651, 1142) -(2239, 1855, 167) -(2435, 2597, 1499) -(471, 4228, 857) -(4608, 4943, 772) -(989, 4423, 1967) -(3239, 3290, 1347) -(4011, 1029, 1414) -(2386, 4959, 340) -(3951, 4259, 1441) -(246, 4721, 139) -(2668, 2064, 873) -(3504, 413, 796) -(1977, 4601, 1527) -(1867, 608, 1931) -(442, 4391, 1424) -(379, 2929, 1784) -(1187, 1852, 1072) -(3450, 4516, 199) -(1330, 1417, 395) -(4199, 4843, 607) -(150, 4650, 1501) -(4770, 2331, 1852) -(4019, 2027, 1187) -(2739, 2581, 1609) -(1198, 27, 266) -(3587, 722, 836) -(3471, 536, 1446) -(2826, 1956, 926) -(3447, 4145, 473) -(3716, 1381, 1241) -(317, 4282, 1137) -(3685, 3692, 137) -(1487, 1423, 85) -(333, 3889, 743) -(1030, 1881, 1059) -(2037, 1727, 1997) -(4730, 2443, 465) -(3604, 1670, 983) -(3006, 2725, 942) -(4298, 3984, 1803) -(968, 4849, 1317) -(2361, 4334, 201) -(140, 2711, 1238) -(2940, 1721, 1893) -(4976, 2823, 1341) -(3716, 2592, 494) -(4030, 860, 1313) -(4456, 2499, 647) -(92, 452, 1151) -(566, 3076, 590) -(2589, 1780, 565) -(452, 3684, 841) -(2652, 1425, 1095) -(1106, 4497, 1179) -(417, 1875, 134) -(4406, 2345, 1795) -(4979, 2585, 1976) -(1773, 3922, 1552) -(3101, 781, 505) -(878, 1038, 818) -(1251, 528, 463) -(3841, 3150, 1715) -(2073, 2775, 248) -(1633, 4907, 1319) -(1147, 712, 392) -(309, 3117, 1924) -(3756, 1987, 1976) -(358, 2734, 1607) -(2657, 107, 953) -(2178, 1011, 67) -(638, 2901, 648) -(4416, 948, 567) -(1991, 4908, 354) -(2424, 3718, 1513) -(1662, 2217, 809) -(693, 4582, 133) -(2149, 500, 1824) -(3102, 2237, 1519) -(1926, 542, 74) -(2604, 2944, 167) -(822, 3652, 1641) -(3035, 1354, 728) -(4769, 2771, 502) -(2802, 2643, 1319) -(2888, 3761, 1274) -(3233, 2387, 1822) -(204, 2455, 1084) -(221, 1391, 1446) -(4806, 3088, 1481) -(3360, 3927, 1818) -(2629, 1854, 830) -(1403, 951, 637) -(2196, 4140, 1004) -(809, 564, 150) -(1030, 4520, 1388) -(3820, 418, 1305) -(3166, 2947, 702) -(502, 2863, 1944) -(2495, 4741, 325) -(3520, 2555, 379) -(3992, 4548, 1500) -(56, 1294, 495) -(3783, 1353, 1869) -(904, 1768, 428) -(3019, 934, 1209) -(371, 835, 544) -(2290, 4681, 1393) -(853, 1739, 810) -(272, 3077, 110) -(2999, 973, 1860) -(2577, 3204, 1451) -(844, 1922, 660) -(3854, 305, 139) -(1902, 4682, 1701) -(1571, 630, 753) -(2506, 477, 76) -(4660, 2744, 1668) -(3607, 1101, 1591) -(981, 631, 1509) -(2463, 2850, 186) -(2534, 1472, 1623) -(343, 1538, 1425) -(188, 4597, 1831) -(645, 4994, 116) -(3539, 537, 89) -(168, 3378, 444) -(1512, 2119, 1678) -(267, 4533, 617) -(2234, 42, 1746) -(303, 4968, 424) -(1787, 3274, 1247) -(2759, 4969, 1759) -(959, 32, 1674) -(2418, 2024, 1993) -(3333, 3555, 1565) -(4795, 3328, 449) -(1289, 4397, 500) -(1901, 3927, 673) -(3850, 523, 1718) -(4276, 3363, 920) -(1274, 3362, 1648) -(3819, 3426, 50) -(1812, 4855, 1626) -(4390, 512, 376) -(1888, 2577, 1039) -(1638, 4699, 417) -(4635, 2179, 979) -(2599, 1866, 614) -(2221, 4052, 1907) -(4396, 1244, 414) -(3501, 1386, 1886) -(4884, 249, 1485) -(2823, 3330, 1132) -(4877, 2923, 875) -(303, 3761, 630) -(1507, 1391, 1455) -(4849, 968, 1317) -(4430, 2655, 1664) -(1635, 4502, 1480) -(1499, 821, 568) -(3475, 2695, 1676) -(3595, 930, 1714) -(2440, 2720, 1500) -(3372, 1270, 1199) -(2805, 2846, 109) -(3714, 1728, 855) -(4273, 1528, 178) -(811, 3937, 114) -(3533, 2706, 1188) -(1149, 973, 1149) -(946, 562, 802) -(2608, 4473, 1046) -(415, 949, 322) -(1409, 606, 866) -(3147, 4467, 452) -(477, 3056, 698) -(4934, 2222, 382) -(4381, 3110, 1884) -(794, 1742, 466) -(75, 2372, 102) -(2380, 3918, 1545) -(3937, 378, 1761) -(880, 2098, 1068) -(3648, 243, 1775) -(2789, 4236, 1684) -(2524, 1577, 283) -(3340, 3920, 971) -(1166, 2864, 183) -(1258, 4271, 1586) -(950, 3723, 573) -(4564, 3591, 1913) -(1568, 688, 827) -(3658, 52, 854) -(2089, 3044, 1365) -(2176, 2814, 868) -(1690, 4822, 892) -(1812, 1775, 685) -(503, 2829, 1176) -(219, 4962, 870) -(819, 222, 689) -(3908, 1286, 901) -(4557, 1462, 1660) -(4513, 4248, 806) -(3139, 633, 1889) -(342, 2662, 1167) -(4965, 1253, 1076) -(808, 2657, 460) -(458, 2342, 935) -(1960, 2325, 849) -(320, 4779, 530) -(2537, 375, 778) -(2889, 746, 578) -(1019, 4007, 1006) -(4340, 169, 1501) -(3475, 2883, 1880) -(2146, 1465, 798) -(3715, 3229, 1484) -(37, 182, 1142) -(1866, 4736, 1714) -(4325, 2132, 228) -(41, 819, 1119) -(1302, 3232, 930) -(3262, 4813, 1597) -(4222, 2803, 1826) -(2623, 4454, 605) -(64, 1792, 896) -(3645, 2248, 147) -(544, 3766, 1736) -(4896, 2030, 970) -(3446, 817, 1137) -(2221, 563, 197) -(2481, 4781, 1670) -(4096, 1192, 1653) -(1855, 2841, 1058) -(161, 2449, 563) -(3212, 2053, 1271) -(3368, 1203, 1360) -(2662, 4983, 943) -(979, 1742, 869) -(3806, 4676, 854) -(1172, 1327, 1935) -(334, 374, 446) -(1357, 1237, 1822) -(3716, 2257, 1879) -(2307, 1093, 1646) -(2689, 1867, 369) -(513, 4694, 555) -(891, 1147, 1020) -(463, 386, 1891) -(1419, 506, 432) -(1205, 3361, 790) -(14, 2836, 1443) -(2633, 2339, 1654) -(2046, 4023, 123) -(3209, 386, 1542) -(1883, 4333, 1202) -(3277, 4902, 1448) -(2805, 1225, 901) -(2285, 1383, 922) -(251, 4356, 553) -(3251, 1059, 1131) -(2641, 4973, 1142) -(95, 1476, 218) -(4768, 2451, 1834) -(2265, 2684, 1435) -(4605, 3590, 578) -(1131, 2064, 1189) -(617, 3870, 837) -(2215, 2138, 166) -(4471, 3409, 681) -(453, 3921, 1895) -(4527, 1479, 709) -(3973, 717, 630) -(1667, 30, 1230) -(2809, 2699, 1977) -(4043, 4065, 1737) -(4400, 1589, 67) -(4553, 4100, 825) -(2486, 4718, 1031) -(110, 2819, 1562) -(435, 2647, 1756) -(2305, 2831, 570) -(3605, 274, 1464) -(4360, 2523, 799) -(3723, 1415, 259) -(3993, 3632, 1228) -(4068, 92, 671) -(3053, 2317, 1877) -(3444, 1322, 715) -(1769, 565, 829) -(4621, 996, 1097) -(4023, 1480, 1885) -(2923, 2874, 368) -(4161, 3236, 1495) -(1048, 3978, 389) -(1285, 61, 318) -(806, 4340, 145) -(1963, 2950, 1832) -(4302, 1327, 1978) -(4905, 3185, 1226) -(3938, 4644, 1480) -(3743, 2337, 1738) -(2843, 3040, 773) -(4286, 3948, 1091) -(51, 2441, 288) -(4928, 3701, 703) -(3208, 4533, 1498) -(652, 2799, 1776) -(1307, 3078, 871) -(3837, 619, 997) -(4068, 1760, 1433) -(4077, 60, 1170) -(4974, 2602, 1044) -(2857, 3793, 1308) -(2064, 372, 1286) -(1021, 3534, 1592) -(4797, 3641, 294) -(4485, 1147, 1520) -(1934, 1801, 1969) -(368, 4239, 1623) -(1784, 116, 1902) -(2315, 4784, 883) -(176, 609, 1416) -(3715, 2210, 953) -(1639, 3133, 1549) -(2752, 3669, 998) -(3503, 2722, 1526) -(2350, 30, 1984) -(252, 3362, 1203) -(4819, 2682, 653) -(3845, 967, 1610) -(1248, 1517, 1503) -(1596, 579, 1112) -(867, 4437, 1623) -(838, 1475, 1392) -(2214, 633, 215) -(1665, 2675, 1149) -(1984, 1765, 107) -(1583, 839, 1000) -(3543, 2799, 617) -(4156, 2233, 1196) -(4138, 3676, 958) -(125, 2596, 756) -(3268, 4415, 1801) -(4376, 1129, 51) -(1745, 904, 129) -(1240, 4232, 1853) -(1485, 141, 556) -(1585, 807, 279) -(4558, 2791, 114) -(4894, 2935, 1667) -(1154, 2836, 329) -(3034, 1865, 1641) -(3315, 3576, 1959) -(1233, 4981, 460) -(3190, 2393, 1701) -(2764, 1342, 636) -(399, 1875, 1388) -(2090, 1501, 1902) -(4547, 913, 286) -(3084, 3657, 1180) -(2221, 117, 1837) -(4530, 161, 55) -(4327, 1705, 258) -(3198, 3455, 143) -(2390, 1940, 716) -(3009, 3691, 409) -(4079, 587, 341) -(1239, 4491, 567) -(4002, 3435, 676) -(3984, 162, 1561) -(4481, 4783, 668) -(1781, 4420, 373) -(3202, 99, 882) -(893, 3128, 276) -(531, 1581, 241) -(2098, 2239, 1218) -(2930, 1544, 1675) -(318, 3171, 1425) -(4079, 4847, 1993) -(3175, 2, 1981) -(2002, 1706, 529) -(1029, 1854, 1220) -(4005, 2025, 1598) -(4400, 3395, 1423) -(4159, 3645, 1383) -(3674, 2747, 1633) -(2269, 4223, 1900) -(4834, 2441, 458) -(1370, 768, 1751) -(4908, 1708, 773) -(3958, 1711, 787) -(4213, 8, 256) -(2648, 3396, 543) -(4972, 2687, 931) -(1643, 4091, 1994) -(2476, 363, 1424) -(325, 3702, 89) -(4860, 4305, 117) -(4227, 2650, 1338) -(4121, 2243, 1040) -(4021, 4120, 677) -(30, 1222, 287) -(62, 3980, 796) -(296, 2744, 1073) -(2927, 1890, 759) -(3647, 4745, 1421) -(3831, 4284, 1163) -(3712, 1673, 1256) -(3143, 838, 266) -(45, 719, 1426) -(1066, 3539, 1494) -(468, 3678, 831) -(3495, 3737, 1131) -(2221, 4806, 775) -(1961, 1787, 690) -(2829, 4507, 545) -(4858, 433, 988) -(2155, 4501, 1811) -(1984, 3070, 171) -(4983, 2662, 943) -(1626, 1618, 1974) -(2697, 257, 1074) -(3378, 2245, 1945) -(2857, 2810, 1726) -(1489, 4421, 188) -(3862, 4506, 1675) -(4968, 3374, 509) -(2292, 1237, 1359) -(3746, 296, 716) -(3741, 4668, 903) -(4473, 724, 496) -(747, 984, 1408) -(2891, 2151, 840) -(4741, 2495, 325) -(709, 410, 871) -(3318, 806, 516) -(2460, 3437, 1784) -(3827, 3351, 1964) -(4600, 1963, 1177) -(256, 1672, 1357) -(2241, 2302, 1444) -(3294, 4920, 560) -(4937, 2604, 1778) -(4227, 3395, 704) -(3018, 4863, 195) -(971, 3783, 502) -(3085, 4920, 158) -(1072, 4553, 1354) -(3477, 961, 217) -(2982, 353, 1587) -(4647, 3309, 778) -(1312, 4077, 428) -(3882, 4815, 1412) -(4468, 3942, 56) -(2303, 2553, 629) -(4891, 2696, 1318) -(1050, 4619, 1164) -(4212, 2799, 888) -(2105, 449, 1277) -(4392, 1306, 1516) -(533, 142, 1866) -(3882, 4958, 651) -(2956, 667, 1037) -(1707, 4293, 818) -(3525, 966, 1905) -(4335, 1763, 1132) -(4531, 1265, 1101) -(1183, 1776, 1569) -(1371, 1392, 913) -(2985, 1557, 1458) -(1179, 1297, 101) -(2606, 687, 1453) -(3900, 4398, 1303) -(2862, 3605, 533) -(42, 4416, 1285) -(4762, 4135, 1969) -(352, 2046, 956) -(4016, 4403, 409) -(2939, 3021, 132) -(1370, 1644, 1056) -(2258, 3993, 1322) -(4855, 3775, 995) -(3738, 3448, 472) -(1064, 1763, 890) -(542, 3535, 1048) -(4150, 4952, 1717) -(2756, 4051, 1066) -(4225, 4535, 1023) -(2928, 3217, 1678) -(4338, 4632, 1603) -(3373, 2639, 635) -(3123, 2692, 720) -(527, 2474, 1922) -(2287, 2603, 1607) -(34, 2797, 223) -(182, 341, 1792) -(4124, 1914, 1349) -(2053, 631, 1610) -(4562, 3339, 1866) -(4069, 1100, 239) -(762, 580, 668) -(805, 4521, 1913) -(2370, 669, 1596) -(3974, 3346, 822) -(2432, 3103, 760) -(4347, 3479, 1314) -(2441, 4834, 458) -(2454, 1809, 1485) -(1682, 4910, 743) -(3708, 2536, 500) -(937, 3069, 1364) -(452, 4151, 1373) -(4581, 2360, 1853) -(979, 1302, 130) -(1839, 4425, 1664) -(4630, 3211, 1805) -(1501, 2009, 1655) -(2903, 2790, 1647) -(1954, 3438, 1253) -(3402, 3331, 1404) -(55, 2591, 1597) -(599, 4820, 662) -(4784, 2315, 883) -(3055, 1541, 144) -(3285, 2554, 1828) -(4683, 299, 772) -(2401, 3963, 452) -(835, 4671, 1255) -(130, 4501, 1155) -(580, 424, 531) -(764, 2883, 840) -(4811, 776, 1177) -(668, 1953, 212) -(148, 3590, 664) -(4475, 4597, 440) -(1185, 93, 1759) -(300, 1865, 509) -(3845, 652, 1886) -(1572, 2315, 56) -(615, 3732, 1795) -(3331, 2319, 1713) -(2405, 4452, 993) -(384, 1088, 515) -(4659, 2934, 271) -(20, 3640, 1502) -(1753, 1554, 955) -(2664, 4757, 1409) -(548, 4495, 687) -(1892, 3332, 1928) -(3338, 4204, 1008) -(394, 3129, 1689) -(2798, 3073, 1368) -(1611, 3572, 953) -(1239, 4527, 200) -(3776, 3038, 120) -(3894, 897, 862) -(540, 4584, 1461) -(3998, 2634, 1552) -(4183, 1010, 1019) -(961, 31, 1605) -(389, 542, 469) -(3210, 47, 427) -(4871, 2397, 1534) -(3444, 883, 598) -(1816, 2079, 198) -(2908, 3313, 1685) -(1024, 4435, 1176) -(3311, 3781, 1821) -(1256, 1908, 462) -(4595, 3919, 944) -(136, 307, 1283) -(3108, 2188, 1900) -(1745, 1676, 1865) -(1825, 2750, 344) -(1008, 545, 326) -(1357, 554, 353) -(3296, 467, 1911) -(4058, 3897, 935) -(4038, 371, 448) -(169, 461, 267) -(1800, 3427, 184) -(2975, 4976, 471) -(360, 3212, 927) -(1759, 147, 308) -(4622, 2958, 1742) -(4820, 599, 662) -(3639, 2505, 851) -(4784, 1345, 1443) -(3233, 3589, 408) -(3425, 4360, 1358) -(3579, 3137, 773) -(1638, 3704, 895) -(1953, 668, 212) -(3662, 814, 118) -(142, 3235, 629) -(417, 2528, 1937) -(4761, 3843, 1429) -(4322, 2011, 977) -(4260, 2270, 555) -(3368, 2884, 869) -(1147, 3232, 949) -(1486, 1724, 1315) -(4786, 342, 994) -(4254, 704, 943) -(53, 2688, 1472) -(739, 1741, 1239) -(1409, 4666, 380) -(2856, 2699, 1598) -(3330, 628, 1806) -(3900, 2466, 641) -(191, 2870, 1262) -(2010, 4542, 1337) -(2639, 744, 991) -(2392, 4812, 784) -(433, 4858, 988) -(1468, 3930, 793) -(806, 3921, 374) -(901, 4131, 887) -(1084, 3622, 831) -(1798, 2734, 1655) -(1018, 527, 1576) -(2758, 778, 1758) -(777, 4942, 1434) -(3215, 1074, 167) -(4787, 1501, 1679) -(4264, 3048, 1363) -(3947, 3554, 1252) -(2253, 2293, 604) -(3267, 3956, 1773) -(3924, 4203, 1158) -(2394, 3560, 1629) -(3569, 792, 1724) -(1166, 2176, 1354) -(1280, 1279, 1078) -(83, 4855, 529) -(3625, 2579, 996) -(1064, 4730, 1608) -(2790, 686, 1380) -(2004, 1882, 1328) -(1921, 1803, 851) -(599, 560, 1976) -(3480, 3474, 1325) -(1574, 4261, 1451) -(214, 534, 1320) -(1615, 1844, 1301) -(1315, 1028, 1643) -(4286, 418, 349) -(1421, 4410, 1410) -(602, 2606, 1096) -(2138, 4969, 810) -(713, 2717, 1925) -(4004, 1133, 313) -(4681, 2290, 1393) -(1100, 2590, 1876) -(2555, 2550, 537) -(2869, 902, 1166) -(2790, 2903, 1647) -(804, 3242, 1044) -(4984, 4827, 1727) -(3042, 474, 1688) -(4057, 3057, 1385) -(373, 2648, 303) -(102, 1510, 231) -(109, 4238, 1408) -(3596, 3578, 1962) -(4743, 2989, 1078) -(2304, 1197, 588) -(968, 3, 1251) -(2449, 2004, 730) -(234, 466, 655) -(3692, 4141, 1372) -(3198, 2780, 1975) -(461, 169, 267) -(2605, 4138, 893) -(3177, 2104, 194) -(4429, 2976, 1710) -(394, 354, 1560) -(4832, 3926, 1002) -(1659, 1467, 962) -(3378, 3714, 1836) -(3124, 930, 1898) -(3308, 1863, 384) -(1926, 3274, 392) -(202, 3059, 610) -(3436, 1470, 1631) -(3082, 2898, 676) -(2328, 4121, 1181) -(4473, 4269, 1857) -(4480, 2256, 1102) -(3315, 2942, 813) -(3695, 2356, 867) -(4203, 3864, 887) -(3109, 3770, 1753) -(3767, 1325, 207) -(2789, 3490, 631) -(4357, 4520, 951) -(211, 1352, 1761) -(2272, 4854, 412) -(3829, 532, 580) -(1093, 3488, 1600) -(1109, 4096, 123) -(4878, 1690, 882) -(3769, 3173, 1264) -(25, 4088, 535) -(2713, 1766, 1497) -(814, 2161, 1609) -(4109, 1008, 87) -(3021, 2939, 132) -(2564, 3127, 865) -(3369, 2507, 1303) -(2619, 2084, 1693) -(1869, 2896, 1085) -(4007, 3947, 1252) -(1547, 4321, 522) -(82, 4523, 521) -(545, 1561, 398) -(1586, 2959, 579) -(2992, 3983, 1850) -(716, 2754, 1823) -(4641, 2051, 840) -(877, 3789, 1029) -(216, 4092, 1764) -(438, 4923, 730) -(2359, 1686, 1741) -(1186, 2558, 1165) -(4255, 4304, 903) -(3646, 2056, 617) -(3028, 3083, 1221) -(220, 1320, 1314) -(4716, 2782, 1057) -(4363, 3368, 1353) -(2269, 4760, 969) -(842, 1520, 1806) -(2093, 4384, 1278) -(4594, 4040, 444) -(1621, 4999, 593) -(1820, 695, 1071) -(4340, 806, 145) -(1101, 790, 332) -(2633, 442, 1399) -(973, 2999, 1860) -(3775, 4265, 1256) -(3700, 692, 93) -(4711, 4440, 501) -(2657, 2596, 873) -(229, 3443, 127) -(2945, 50, 1943) -(943, 3723, 293) -(819, 41, 1119) -(1238, 3368, 346) -(4178, 1778, 72) -(3231, 2622, 1832) -(4142, 4009, 921) -(3914, 246, 913) -(1351, 1847, 726) -(1590, 405, 761) -(4102, 2963, 1080) -(909, 460, 379) -(4711, 1501, 1973) -(1922, 1107, 999) -(4460, 3995, 596) -(2050, 585, 752) -(3185, 4426, 368) -(95, 3827, 1783) -(3931, 537, 104) -(3029, 1501, 1922) -(4680, 1503, 799) -(1855, 2239, 167) -(2528, 1268, 583) -(424, 2657, 1162) -(3195, 4330, 313) -(2855, 2053, 1823) -(4818, 1673, 183) -(4582, 1199, 102) -(2819, 1436, 1191) -(2569, 600, 1256) -(39, 3560, 1851) -(297, 2777, 527) -(3405, 701, 686) -(614, 612, 728) -(2871, 3391, 290) -(3191, 2474, 683) -(338, 512, 1181) -(4793, 3045, 1779) -(1595, 2629, 1955) -(790, 1871, 1877) -(1870, 516, 114) -(2149, 3635, 689) -(2547, 3695, 205) -(1206, 2060, 954) -(536, 4129, 1058) -(2818, 3160, 61) -(4605, 2468, 283) -(2929, 379, 1784) -(2312, 4485, 369) -(4833, 2945, 1412) -(2974, 3483, 420) -(1328, 3960, 69) -(3041, 2617, 186) -(695, 3274, 774) -(4261, 1465, 411) -(1481, 2901, 1395) -(4855, 2589, 253) -(4375, 2055, 881) -(4984, 174, 1355) -(4717, 3220, 1452) -(3369, 3051, 564) -(784, 1239, 1238) -(3420, 3530, 1302) -(989, 3982, 1605) -(3818, 4448, 1899) -(3490, 261, 979) -(532, 4228, 268) -(4254, 2921, 430) -(4969, 2138, 810) -(803, 98, 1066) -(822, 258, 1365) -(132, 3494, 112) -(1180, 3216, 1377) -(2014, 4820, 785) -(1831, 4998, 424) -(4934, 4502, 1557) -(4738, 2262, 386) -(4205, 3165, 157) -(773, 2363, 1457) -(4435, 1024, 1176) -(3998, 196, 1961) -(179, 4332, 892) -(1559, 4632, 806) -(3958, 1377, 1251) -(733, 795, 769) -(3509, 1301, 1413) -(4084, 1271, 56) -(2906, 1774, 680) -(4997, 272, 1869) -(3613, 1971, 98) -(3327, 4115, 296) -(4328, 1867, 1658) -(4807, 4833, 535) -(1691, 2285, 1286) -(343, 971, 1271) -(2734, 4323, 1354) -(781, 3337, 1929) -(499, 4906, 326) -(3937, 3467, 1387) -(3292, 1230, 871) -(1394, 4805, 977) -(3974, 4420, 1804) -(286, 4673, 1996) -(58, 2132, 1517) -(4955, 1431, 261) -(4706, 767, 734) -(4692, 2658, 689) -(2040, 4891, 727) -(1744, 680, 214) -(3149, 2992, 1897) -(2623, 1999, 247) -(3897, 4058, 935) -(1871, 87, 1212) -(2754, 716, 1823) -(3536, 4335, 198) -(3961, 4802, 1242) -(363, 2476, 1424) -(2345, 2684, 1210) -(4691, 259, 1149) -(2917, 1460, 599) -(3072, 2204, 1829) -(4489, 3133, 865) -(4780, 4525, 306) -(1270, 1855, 1378) -(4005, 236, 1791) -(2894, 122, 938) -(3411, 4379, 1242) -(4046, 2794, 1562) -(4855, 1812, 1626) -(1686, 425, 1659) -(1547, 2433, 681) -(159, 824, 1564) -(1659, 1462, 942) -(1054, 2707, 428) -(1960, 4347, 1529) -(1861, 605, 1750) -(4801, 3592, 407) -(3668, 2125, 1844) -(3155, 2162, 1463) -(4857, 3843, 725) -(4332, 3771, 1591) -(4031, 4199, 129) -(1987, 4413, 100) -(4911, 227, 106) -(2037, 1340, 1959) -(3265, 2094, 1364) -(1753, 1497, 151) -(4626, 17, 320) -(4507, 2829, 545) -(2738, 214, 1403) -(3455, 1911, 1597) -(2322, 1513, 1296) -(1995, 15, 626) -(1943, 844, 1382) -(4777, 4859, 976) -(774, 3268, 625) -(4327, 2617, 963) -(4399, 2640, 1196) -(709, 3836, 1317) -(1704, 4239, 387) -(2722, 2638, 345) -(1638, 4839, 1485) -(910, 4037, 1419) -(54, 4278, 1856) -(1660, 2422, 929) -(4956, 4643, 1245) -(870, 3184, 452) -(4004, 2349, 1206) -(3073, 2245, 1056) -(4696, 3768, 181) -(918, 1800, 1254) -(931, 2071, 923) -(2978, 1903, 869) -(2274, 4952, 1185) -(1362, 4405, 1964) -(1703, 221, 1841) -(1794, 2735, 180) -(4323, 2734, 1354) -(1583, 1659, 510) -(2528, 736, 1176) -(3597, 1858, 1004) -(4848, 1546, 420) -(3740, 4331, 1087) -(3808, 4472, 323) -(2180, 3397, 1301) -(821, 3900, 546) -(4128, 2434, 1382) -(3079, 2232, 1879) -(714, 2476, 1368) -(2139, 454, 1560) -(1994, 3890, 621) -(4522, 943, 157) -(467, 2511, 1556) -(1675, 1249, 1399) -(1107, 931, 1967) -(1629, 1817, 1513) -(1467, 3938, 1376) -(3542, 1450, 389) -(126, 3911, 325) -(2466, 3633, 1498) -(2121, 960, 240) -(160, 1600, 168) -(4295, 4122, 1175) -(3696, 3913, 1394) -(1712, 862, 517) -(3066, 1910, 659) -(1789, 832, 889) -(4356, 4479, 710) -(1019, 1456, 1221) -(2880, 4358, 61) -(3293, 2221, 965) -(1241, 4738, 1899) -(4636, 1853, 341) -(275, 778, 1981) -(25, 2211, 1930) -(589, 1194, 681) -(414, 2537, 1886) -(3042, 3896, 86) -(4914, 3939, 1485) -(3023, 1100, 1627) -(2632, 291, 1806) -(1387, 145, 1244) -(2223, 1368, 1212) -(3730, 1353, 1688) -(1795, 438, 1673) -(227, 2733, 1101) -(2245, 3378, 1945) -(2499, 4404, 473) -(4917, 2397, 544) -(1588, 3531, 675) -(4820, 2205, 992) -(3343, 806, 1610) -(2080, 357, 526) -(66, 1804, 1641) -(3369, 3519, 1276) -(4519, 317, 532) -(4467, 1012, 985) -(1103, 4398, 1955) -(353, 3316, 1122) -(3805, 2787, 295) -(3014, 2979, 207) -(1384, 1848, 622) -(4100, 4553, 825) -(558, 421, 814) -(2687, 777, 1303) -(1775, 1812, 685) -(2464, 115, 339) -(3232, 4408, 1343) -(2868, 4199, 824) -(2186, 3256, 1139) -(4843, 3034, 1236) -(938, 3835, 703) -(1914, 3908, 1163) -(4638, 3364, 1665) -(742, 17, 1940) -(4426, 1302, 245) -(1100, 899, 991) -(1168, 2924, 1209) -(497, 4434, 636) -(4026, 4462, 339) -(4083, 2655, 190) -(3787, 1599, 53) -(289, 4035, 328) -(2123, 3420, 50) -(4668, 1142, 526) -(1136, 2935, 823) -(4352, 2338, 716) -(1489, 4835, 1670) -(1441, 3241, 156) -(3373, 3198, 1473) -(3267, 711, 730) -(3539, 1066, 1494) -(4256, 808, 1063) -(3504, 3813, 139) -(2233, 4156, 1196) -(1651, 2197, 1807) -(1708, 4908, 773) -(1028, 1421, 348) -(2102, 3362, 615) -(742, 2471, 633) -(4368, 2698, 1694) -(1156, 915, 704) -(4827, 4984, 1727) -(2456, 848, 1851) -(2005, 3298, 809) -(2490, 2972, 1412) -(3178, 3257, 946) -(3404, 982, 1855) -(4582, 1827, 84) -(4814, 1338, 686) -(3566, 576, 626) -(1482, 3105, 1501) -(2693, 846, 200) -(467, 3296, 1911) -(2497, 496, 671) -(3786, 607, 1077) -(1730, 665, 351) -(2430, 2453, 888) -(2392, 1222, 1979) -(2298, 2080, 488) -(4617, 3, 1613) -(2466, 1268, 314) -(1468, 1251, 953) -(3908, 1914, 1163) -(3602, 61, 422) -(4798, 4842, 291) -(4546, 835, 1258) -(4143, 2663, 1279) -(3646, 1630, 903) -(1963, 4600, 1177) -(1431, 4262, 1321) -(4859, 4777, 976) -(4853, 626, 1388) -(606, 3321, 1490) -(3306, 2756, 823) -(4314, 3855, 101) -(1015, 2740, 215) -(4632, 4520, 1206) -(46, 4799, 811) -(2274, 444, 1357) -(3788, 1723, 1055) -(784, 182, 717) -(1758, 1175, 1711) -(1814, 3205, 109) -(4174, 1318, 1258) -(1391, 4600, 1839) -(4799, 461, 1288) -(451, 2094, 425) -(3811, 4710, 1023) -(3663, 4809, 928) -(4607, 2552, 453) -(1847, 1351, 726) -(2884, 3949, 1026) -(520, 2098, 612) -(1677, 4972, 459) -(3392, 4760, 1595) -(1082, 1947, 374) -(3297, 2627, 621) -(3312, 2406, 1732) -(1216, 1433, 1028) -(2225, 1281, 1332) -(4682, 2522, 619) -(1716, 3813, 590) -(3782, 2432, 1366) -(4388, 2610, 666) -(1731, 1971, 1862) -(4432, 3003, 1369) -(2774, 504, 1550) -(156, 939, 807) -(209, 2521, 876) -(2930, 1545, 1117) -(3546, 4199, 1352) -(1286, 1356, 1348) -(3132, 968, 999) -(165, 2, 1846) -(1540, 4511, 1674) -(2543, 3002, 61) -(1599, 3787, 53) -(563, 2221, 197) -(108, 3828, 443) -(445, 498, 774) -(1450, 150, 324) -(1138, 293, 716) -(2046, 4296, 1289) -(1267, 3947, 369) -(2324, 1725, 412) -(1548, 4082, 1773) -(1357, 4910, 1137) -(2530, 1110, 139) -(1368, 482, 146) -(217, 3092, 1920) -(2857, 3551, 267) -(3940, 3768, 1395) -(2603, 2287, 1607) -(1991, 3062, 1273) -(4872, 3620, 1959) -(1990, 3279, 153) -(4134, 2373, 576) -(2824, 1476, 246) -(3086, 3100, 1023) -(4600, 51, 339) -(4879, 1101, 1434) -(891, 2622, 1973) -(3822, 1150, 1682) -(4084, 1877, 188) -(2565, 2215, 1373) -(1483, 2588, 449) -(877, 1797, 1851) -(1932, 4595, 1094) -(880, 3170, 459) -(2686, 3608, 423) -(2211, 25, 1930) -(4558, 1920, 136) -(188, 2138, 550) -(4953, 1506, 1879) -(1290, 1824, 1125) -(2040, 2859, 1688) -(3627, 729, 616) -(4324, 4545, 877) -(1973, 1645, 1306) -(1816, 1044, 1494) -(1636, 1725, 613) -(3057, 1861, 158) -(2030, 2378, 1843) -(4959, 2386, 340) -(185, 676, 1595) -(4115, 4573, 1291) -(1716, 2805, 1501) -(3629, 4618, 1444) -(4956, 1672, 675) -(2800, 411, 1548) -(2427, 4632, 1808) -(3821, 4188, 245) -(2741, 2559, 1070) -(3995, 798, 884) -(4678, 2779, 1829) -(4624, 3896, 1347) -(4146, 564, 1309) -(2527, 2986, 671) -(3009, 1983, 421) -(1096, 537, 1467) -(2270, 4940, 1178) -(15, 2701, 634) -(2443, 39, 240) -(3865, 2130, 1175) -(1676, 1589, 1508) -(1052, 2940, 1628) -(2651, 2505, 429) -(4141, 2075, 1651) -(771, 1392, 204) -(3981, 2652, 824) -(3476, 1596, 958) -(2397, 3232, 1766) -(2127, 4210, 225) -(3052, 3722, 805) -(4048, 2579, 439) -(561, 4027, 1031) -(3105, 1822, 69) -(562, 3015, 904) -(2659, 938, 337) -(1212, 3637, 273) -(3254, 1401, 1137) -(1501, 4711, 1973) -(2733, 3377, 966) -(1147, 891, 1020) -(2002, 2358, 961) -(3154, 3536, 1035) -(2733, 4386, 1011) -(4753, 3566, 1408) -(3127, 3153, 282) -(3993, 1280, 1901) -(3791, 2794, 1365) -(664, 835, 451) -(3504, 704, 998) -(3375, 3783, 1525) -(93, 3011, 1952) -(2783, 3476, 267) -(3101, 3675, 1167) -(3846, 3920, 165) -(45, 2144, 801) -(3714, 4474, 253) -(157, 2598, 121) -(1562, 4175, 1295) -(683, 2058, 531) -(3525, 3743, 870) -(1077, 4725, 1550) -(4642, 3977, 664) -(990, 4046, 328) -(1309, 1566, 449) -(1883, 890, 600) -(306, 248, 921) -(4242, 1771, 387) -(566, 3385, 1646) -(2376, 3828, 743) -(910, 635, 1996) -(3808, 4841, 524) -(4066, 3021, 239) -(4960, 2928, 1044) -(903, 249, 1172) -(2792, 2177, 1091) -(3381, 4593, 1793) -(4582, 3227, 959) -(1636, 3049, 214) -(3379, 138, 1747) -(4560, 2652, 1635) -(2199, 2840, 1921) -(1670, 2985, 345) -(3347, 1395, 662) -(2612, 3408, 759) -(281, 4643, 1830) -(4428, 417, 64) -(4449, 1518, 271) -(2366, 2830, 1128) -(2402, 4396, 1649) -(1800, 918, 1254) -(3236, 2212, 1120) -(3900, 1970, 189) -(3397, 1358, 614) -(4676, 4826, 197) -(3223, 2478, 1164) -(4812, 612, 1696) -(2198, 4807, 726) -(3954, 2153, 340) -(4495, 2057, 635) -(2405, 4481, 1191) -(2370, 4325, 1852) -(1308, 2476, 616) -(2514, 2196, 1209) -(3378, 4033, 1496) -(1862, 1075, 862) -(4184, 169, 1212) -(4603, 826, 199) -(2449, 3027, 1034) -(3316, 2937, 1451) -(2552, 766, 1722) -(1228, 2018, 789) -(512, 1907, 418) -(289, 2361, 398) -(2438, 2453, 873) -(4222, 2507, 1624) -(43, 1463, 1837) -(4700, 1199, 1757) -(4345, 2603, 1111) -(2930, 672, 1430) -(2522, 2346, 1465) -(4825, 1931, 240) -(2230, 2679, 591) -(4761, 1129, 1330) -(3826, 4074, 463) -(3637, 3870, 1314) -(3160, 168, 547) -(4235, 3198, 1276) -(963, 1271, 1282) -(1063, 2657, 1765) -(1632, 402, 302) -(4998, 1269, 1848) -(3988, 2944, 1343) -(1130, 4687, 1963) -(2577, 1888, 1039) -(4040, 4648, 1569) -(3748, 2956, 626) -(681, 1918, 116) -(629, 3416, 665) -(2846, 2805, 109) -(3234, 994, 1477) -(958, 22, 874) -(1525, 2993, 1380) -(2238, 2009, 809) -(3924, 4081, 870) -(21, 4301, 1381) -(4868, 3901, 1989) -(1404, 3058, 1746) -(1460, 2828, 761) -(1037, 4482, 409) -(4561, 1001, 1150) -(4913, 3997, 741) -(902, 1057, 1588) -(827, 3481, 493) -(2685, 1116, 1208) -(949, 2864, 361) -(182, 784, 717) -(4505, 4730, 595) -(299, 1624, 1619) -(514, 2285, 808) -(1537, 3014, 1783) -(4127, 4707, 318) -(2435, 1520, 731) -(3834, 3372, 784) -(348, 711, 1217) -(3475, 676, 1974) -(1227, 4812, 1503) -(3867, 4899, 146) -(1673, 1252, 1185) -(2144, 3745, 1678) -(3918, 298, 1814) -(2286, 2303, 1998) -(389, 3051, 230) -(1295, 2147, 903) -(2423, 4374, 193) -(1205, 4285, 658) -(2167, 468, 1950) -(290, 2912, 630) -(3669, 4196, 1103) -(1684, 549, 1985) -(4391, 587, 1071) -(1908, 1391, 1095) -(1067, 1457, 722) -(2095, 103, 436) -(1420, 3714, 1975) -(1124, 2886, 188) -(3882, 1290, 1977) -(2456, 4969, 951) -(3291, 4748, 1144) -(4466, 2450, 214) -(4676, 3806, 854) -(2923, 2627, 710) -(282, 4735, 1424) -(1673, 4818, 183) -(257, 851, 290) -(3285, 3109, 1642) -(2732, 2155, 1769) -(1390, 4020, 1056) -(21, 1542, 138) -(4279, 1563, 354) -(2943, 1397, 1287) -(1494, 2015, 492) -(946, 3937, 866) -(186, 1492, 1924) -(3515, 3764, 392) -(767, 139, 1256) -(4319, 1062, 1585) -(1308, 3403, 137) -(3562, 3992, 1426) -(3133, 4489, 865) -(776, 672, 505) -(2535, 1735, 697) -(1894, 4515, 95) -(1448, 1630, 1418) -(2192, 3163, 1851) -(4793, 3099, 1224) -(1320, 957, 1570) -(616, 573, 409) -(4105, 4725, 1891) -(1378, 1775, 1386) -(4971, 52, 746) -(1712, 3283, 1007) -(381, 3557, 552) -(4157, 4432, 1115) -(2001, 4143, 324) -(265, 1626, 600) -(1898, 2783, 1515) -(1342, 3638, 1020) -(2517, 3861, 1783) -(3509, 3611, 409) -(2277, 3889, 248) -(2240, 3431, 1573) -(702, 808, 140) -(37, 2638, 1350) -(2698, 2200, 1553) -(1390, 2881, 440) -(184, 712, 835) -(2226, 3761, 383) -(1181, 2691, 1698) -(848, 2456, 1851) -(554, 3498, 641) -(603, 2566, 123) -(4294, 2629, 1050) -(3772, 4110, 790) -(3711, 3275, 1450) -(1343, 1821, 533) -(337, 73, 193) -(3960, 3089, 1500) -(2837, 2802, 652) -(4742, 1, 1279) -(4291, 1453, 1975) -(3204, 2577, 1451) -(949, 4534, 1581) -(1419, 1722, 450) -(3728, 64, 1762) -(2024, 1522, 1011) -(2293, 1552, 1416) -(2068, 3714, 1270) -(2730, 3223, 1602) -(784, 4083, 1891) -(3494, 154, 1995) -(4526, 4151, 482) -(967, 2473, 842) -(301, 2923, 1423) -(4294, 4019, 596) -(3909, 1353, 877) -(2476, 3855, 459) -(176, 4976, 1799) -(1838, 863, 1806) -(3677, 829, 1973) -(4448, 4276, 533) -(1832, 1803, 604) -(2359, 3766, 1070) -(2629, 1595, 1955) -(1442, 52, 620) -(2956, 3748, 626) -(3381, 4871, 578) -(1755, 2534, 646) -(2310, 1712, 1573) -(1489, 119, 820) -(1567, 500, 599) -(4237, 1705, 331) -(4699, 1858, 673) -(1511, 930, 1406) -(37, 4259, 205) -(2933, 4814, 1150) -(3816, 1518, 904) -(4901, 2247, 1799) -(86, 2218, 351) -(4918, 4631, 1121) -(2849, 4268, 1436) -(3397, 2155, 1855) -(1033, 450, 1690) -(3061, 993, 786) -(3748, 3631, 1097) -(1732, 68, 1589) -(1327, 1760, 870) -(3346, 2178, 1964) -(3759, 3585, 1215) -(4935, 1676, 499) -(1849, 444, 1278) -(3099, 4175, 100) -(1926, 44, 894) -(1406, 4959, 688) -(3300, 3326, 1239) -(4968, 2212, 1273) -(2590, 1100, 1876) -(942, 945, 1273) -(3548, 937, 1040) -(2870, 3020, 822) -(3078, 1185, 1885) -(4584, 540, 1461) -(3808, 4443, 264) -(4045, 4464, 1044) -(777, 1546, 1488) -(512, 4390, 376) -(3479, 3247, 1400) -(3728, 1349, 1181) -(819, 4880, 805) -(2928, 632, 77) -(1795, 1060, 1457) -(1154, 1444, 1277) -(2629, 3464, 582) -(3310, 4982, 1224) -(496, 400, 989) -(4947, 3123, 821) -(3116, 1271, 1314) -(2887, 1260, 336) -(2600, 2501, 1292) -(4391, 952, 276) -(3515, 19, 1014) -(4871, 1522, 492) -(766, 2552, 1722) -(3202, 4967, 213) -(3043, 1842, 640) -(3263, 1101, 1076) -(1473, 71, 1114) -(4182, 1771, 139) -(3551, 2814, 191) -(106, 2230, 447) -(283, 387, 1223) -(1640, 4911, 1154) -(1185, 2079, 1098) -(4484, 157, 731) -(1483, 42, 417) -(3300, 4900, 1925) -(419, 1859, 1527) -(3696, 3807, 1738) -(2463, 3787, 1061) -(113, 3690, 586) -(3693, 3737, 1535) -(2592, 3716, 494) -(85, 1498, 1762) -(4018, 4964, 837) -(1896, 4884, 1984) -(3430, 4948, 666) -(3722, 533, 1185) -(3314, 3302, 1983) -(4746, 1019, 316) -(2465, 2473, 1638) -(368, 1748, 1995) -(4790, 2268, 1735) -(3551, 3697, 83) -(4327, 968, 402) -(2200, 2218, 525) -(697, 4527, 637) -(3792, 721, 1392) -(4745, 4045, 1609) -(90, 2677, 1870) -(55, 4837, 486) -(3113, 718, 317) -(2783, 2174, 959) -(3081, 1780, 681) -(4136, 3806, 1381) -(2870, 2491, 1804) -(3544, 2955, 214) -(4918, 2096, 1423) -(2475, 253, 323) -(3821, 1158, 1961) -(1549, 1713, 324) -(3631, 333, 657) -(29, 1314, 1122) -(4929, 2793, 1135) -(3487, 4889, 907) -(2990, 4387, 1749) -(232, 3174, 1199) -(1508, 4617, 1583) -(970, 2189, 1043) -(241, 900, 1333) -(3285, 3129, 145) -(4258, 4025, 1873) -(1411, 4877, 771) -(4226, 4021, 310) -(2071, 1889, 949) -(2334, 4087, 1755) -(114, 1068, 1297) -(4488, 692, 1590) -(1472, 2609, 254) -(2402, 333, 1122) -(698, 2814, 1555) -(4220, 737, 984) -(4736, 1866, 1714) -(4670, 2707, 630) -(804, 3426, 62) -(2616, 235, 1296) -(4415, 4608, 822) -(3279, 1687, 1312) -(2916, 2608, 1337) -(1160, 1230, 492) -(1992, 4760, 544) -(2803, 326, 703) -(4289, 3276, 92) -(32, 3078, 1172) -(2922, 935, 1462) -(2967, 3318, 673) -(619, 3837, 997) -(2925, 2908, 778) -(1257, 2878, 1371) -(2330, 2276, 1822) -(3664, 620, 857) -(1300, 4782, 1004) -(4177, 3876, 1627) -(3381, 3702, 1779) -(3183, 972, 1941) -(3082, 1534, 1802) -(4264, 1511, 649) -(905, 877, 1555) -(1527, 3804, 1552) -(3397, 914, 1806) -(1826, 2197, 299) -(2979, 4481, 674) -(3590, 4410, 1459) -(4018, 3450, 1493) -(1561, 2208, 316) -(3122, 4134, 60) -(1976, 3490, 1928) -(4829, 3000, 1845) -(1932, 2154, 1945) -(3461, 822, 1334) -(4069, 417, 1985) -(841, 4053, 989) -(418, 302, 815) -(2568, 2415, 976) -(2898, 3082, 676) -(2968, 2569, 1536) -(1945, 4797, 1734) -(2073, 3064, 1320) -(2433, 1547, 681) -(4624, 1436, 535) -(4317, 797, 200) -(1545, 2676, 914) -(3115, 2135, 571) -(1279, 3588, 562) -(3894, 3263, 1743) -(1017, 3704, 1069) -(1096, 3884, 512) -(1512, 3733, 1658) -(2174, 3174, 446) -(916, 384, 1156) -(2001, 1986, 1189) -(795, 3796, 632) -(23, 1902, 1538) -(2861, 2855, 1646) -(4420, 822, 586) -(3170, 2553, 595) -(1751, 2795, 215) -(2078, 1043, 219) -(69, 1020, 1880) -(1880, 4768, 614) -(2793, 4230, 729) -(2000, 978, 961) -(1287, 2676, 275) -(2696, 302, 1480) -(295, 3694, 1669) -(3177, 795, 1650) -(1417, 1506, 1070) -(2126, 4402, 521) -(3718, 3584, 1156) -(3313, 2111, 1416) -(4918, 4851, 1751) -(2932, 807, 630) -(752, 3152, 342) -(823, 2575, 731) -(4608, 3402, 1624) -(3871, 1058, 207) -(4271, 1774, 55) -(3301, 4471, 1467) -(3553, 2241, 1090) -(1943, 2802, 745) -(414, 4139, 376) -(1686, 1561, 1821) -(1258, 4918, 547) -(4415, 1255, 883) -(2977, 4844, 768) -(865, 855, 531) -(4, 911, 1116) -(1457, 1067, 722) -(1449, 3286, 574) -(2128, 4161, 486) -(373, 3436, 946) -(2269, 1655, 1109) -(1499, 676, 1625) -(1784, 342, 260) -(3067, 4431, 1991) -(198, 3159, 138) -(3038, 2534, 780) -(770, 3898, 1514) -(3342, 3098, 951) -(2334, 321, 843) -(4961, 470, 1824) -(4813, 1649, 1607) -(327, 3651, 791) -(693, 1686, 179) -(4745, 1013, 422) -(1710, 1177, 551) -(2104, 3177, 194) -(4130, 1520, 254) -(316, 2467, 1549) -(4481, 4850, 759) -(4101, 1654, 318) -(3695, 1021, 1570) -(4589, 1106, 1427) -(4333, 2024, 1072) -(1871, 3901, 1099) -(393, 3730, 1366) -(2579, 3127, 314) -(1016, 2923, 473) -(1551, 4720, 402) -(1645, 3701, 233) -(3291, 65, 1432) -(3889, 1586, 1799) -(1487, 3501, 1812) -(1835, 4676, 795) -(80, 714, 116) -(4684, 589, 1042) -(1722, 1419, 450) -(2766, 1874, 1795) -(1330, 3076, 1216) -(3120, 3205, 935) -(534, 747, 1156) -(2303, 4782, 880) -(1628, 4399, 452) -(2303, 1361, 245) -(2756, 3306, 823) -(4004, 504, 641) -(460, 829, 454) -(3480, 4064, 1690) -(3069, 333, 1949) -(2318, 2859, 1613) -(795, 3841, 1927) -(4009, 4142, 921) -(829, 3677, 1973) -(4237, 2840, 1596) -(1951, 1796, 368) -(62, 3990, 1016) -(408, 635, 1859) -(948, 2440, 1731) -(3403, 1308, 137) -(2168, 4633, 1050) -(1977, 34, 366) -(4238, 4954, 1662) -(2184, 2162, 452) -(1579, 4441, 870) -(2812, 198, 1759) -(3822, 1213, 1515) -(3424, 1788, 1362) -(4119, 846, 523) -(4338, 662, 109) -(4404, 2838, 1957) -(450, 1033, 1690) -(1125, 3865, 1869) -(3726, 1395, 555) -(942, 3447, 251) -(824, 1374, 801) -(1884, 4700, 1391) -(499, 2180, 1802) -(2293, 676, 1974) -(1844, 3790, 293) -(3331, 1257, 1090) -(3115, 334, 1093) -(4759, 545, 380) -(3589, 3233, 408) -(3169, 2368, 1441) -(1552, 2061, 492) -(1512, 2650, 794) -(2696, 2692, 1424) -(2938, 399, 284) -(40, 1027, 1552) -(4219, 4819, 976) -(1504, 4698, 1239) -(361, 3892, 1824) -(1199, 2747, 1863) -(938, 4240, 1203) -(2519, 982, 1095) -(3716, 3364, 109) -(3038, 3034, 440) -(3584, 2698, 1617) -(788, 3283, 1892) -(1294, 1492, 821) -(2354, 1887, 890) -(4891, 2655, 275) -(1572, 1663, 1191) -(4888, 0, 1316) -(2548, 4209, 245) -(2630, 2992, 1244) -(713, 4481, 782) -(495, 3734, 872) -(1826, 2886, 468) -(612, 614, 728) -(3931, 206, 1223) -(1501, 4787, 1679) -(2525, 3198, 403) -(4951, 4632, 281) -(2856, 3352, 155) -(2196, 2785, 1328) -(2913, 2385, 415) -(1871, 2026, 337) -(1616, 2006, 1130) -(628, 1596, 155) -(3673, 1359, 965) -(512, 983, 737) -(897, 43, 1267) -(720, 2803, 1650) -(855, 2919, 997) -(1773, 948, 676) -(4393, 1664, 1631) -(1496, 3720, 196) -(1520, 842, 1806) -(4655, 1076, 1996) -(2003, 1170, 522) -(4293, 1895, 333) -(1910, 2415, 351) -(4200, 2890, 515) -(1851, 2739, 1172) -(1179, 4458, 1967) -(1821, 2616, 223) -(1968, 1817, 1128) -(391, 4317, 911) -(2939, 4479, 200) -(874, 893, 1350) -(795, 733, 769) -(4839, 3700, 1449) -(4259, 4289, 942) -(1647, 1805, 1397) -(4374, 2423, 193) -(3225, 708, 1248) -(1464, 668, 58) -(3947, 4007, 1252) -(1805, 2863, 1606) -(1929, 1654, 1907) -(4803, 1771, 604) -(980, 2665, 1601) -(4559, 1661, 1631) -(1900, 843, 597) -(1079, 742, 1768) -(1542, 430, 422) -(1778, 1451, 1270) -(583, 1303, 888) -(3310, 4189, 887) -(792, 2804, 1071) -(4182, 3715, 445) -(2338, 1927, 816) -(2132, 2679, 1040) -(1833, 4462, 641) -(4240, 938, 1203) -(2906, 922, 1916) -(2367, 4776, 1506) -(4426, 909, 737) -(2254, 4850, 293) -(2985, 1289, 1897) -(2476, 4696, 1590) -(2279, 3652, 919) -(496, 2326, 949) -(1419, 3546, 1305) -(1640, 24, 1995) -(4658, 2876, 1144) -(1790, 1285, 473) -(1545, 4197, 826) -(4433, 1126, 145) -(1496, 523, 231) -(526, 232, 1154) -(3516, 146, 1744) -(400, 496, 989) -(2392, 4103, 1519) -(1924, 986, 873) -(3102, 3046, 1127) -(305, 3854, 139) -(2564, 4175, 289) -(4860, 2345, 1678) -(1986, 1869, 508) -(3793, 1332, 1869) -(1635, 4512, 1642) -(3437, 2460, 1784) -(72, 1288, 1894) -(3841, 4582, 646) -(3255, 3375, 1759) -(579, 4550, 1194) -(2609, 2935, 1946) -(773, 3478, 1747) -(4863, 2179, 562) -(3217, 2928, 1678) -(1915, 601, 828) -(293, 2312, 327) -(4431, 512, 1173) -(1982, 2682, 619) -(4007, 1461, 670) -(2741, 2874, 1085) -(3207, 769, 1783) -(1936, 3730, 1225) -(3086, 3186, 1505) -(3024, 1282, 868) -(667, 112, 994) -(3138, 2369, 1146) -(4730, 4971, 1664) -(4499, 3363, 225) -(2465, 307, 249) -(885, 4684, 207) -(2257, 2478, 1779) -(3489, 2177, 463) -(1373, 1028, 1910) -(3576, 2206, 97) -(4374, 3466, 581) -(720, 479, 1680) -(3671, 4330, 1698) -(1700, 1925, 497) -(1843, 4667, 549) -(1383, 3922, 1330) -(136, 1258, 256) -(608, 1387, 741) -(3285, 3487, 742) -(902, 2039, 596) -(2273, 2556, 966) -(1224, 1393, 1038) -(1251, 1468, 953) -(4427, 3218, 226) -(4066, 3748, 327) -(3686, 69, 999) -(2138, 2994, 639) -(4601, 3307, 1640) -(128, 1402, 144) -(4003, 3283, 568) -(588, 2912, 1702) -(2506, 3981, 84) -(781, 1615, 1378) -(919, 1588, 1379) -(2154, 1932, 1945) -(2249, 2305, 1024) -(1368, 2500, 381) -(3959, 1716, 1416) -(1539, 2623, 1070) -(1115, 2641, 427) -(3678, 3856, 101) -(377, 4367, 1513) -(19, 3072, 199) -(2715, 3295, 1273) -(1230, 3202, 1185) -(4333, 629, 1029) -(1452, 2350, 200) -(2886, 1124, 188) -(2676, 1609, 960) -(3237, 3345, 1121) -(2938, 2263, 1350) -(1920, 1730, 1477) -(4055, 2882, 1927) -(2177, 3489, 463) -(2477, 2354, 1220) -(4145, 4984, 1751) -(3318, 2354, 897) -(743, 2218, 875) -(1553, 1373, 1294) -(1855, 963, 1592) -(1103, 110, 639) -(3367, 4776, 934) -(3424, 4194, 552) -(399, 2938, 284) -(766, 4772, 1881) -(2389, 4922, 869) -(1018, 1134, 1343) -(3872, 4373, 1434) -(2373, 549, 1115) -(4448, 3818, 1899) -(655, 665, 1171) -(2538, 1757, 1531) -(3413, 2946, 1931) -(2042, 3980, 494) -(3361, 3684, 1127) -(369, 1953, 1075) -(4597, 1150, 966) -(2189, 3799, 1780) -(1534, 2501, 1506) -(1038, 878, 818) -(3352, 3937, 1163) -(3314, 232, 1028) -(3855, 789, 1445) -(1041, 3950, 1380) -(1418, 1053, 158) -(2552, 4607, 453) -(2144, 1741, 701) -(1722, 474, 315) -(1010, 333, 610) -(881, 2899, 1882) -(1906, 4844, 338) -(2202, 2042, 646) -(3920, 2600, 1337) -(2137, 275, 787) -(108, 952, 155) -(2800, 2465, 163) -(4133, 3001, 369) -(2903, 4334, 227) -(3024, 2037, 1219) -(2878, 912, 818) -(1847, 622, 1328) -(930, 3124, 1898) -(3978, 120, 1553) -(1335, 3506, 1376) -(3249, 287, 74) -(1895, 3782, 1388) -(413, 3793, 788) -(808, 1217, 1635) -(2114, 1480, 1568) -(1881, 1848, 728) -(816, 4564, 1707) -(2195, 4996, 1215) -(2992, 1250, 1549) -(2888, 767, 263) -(2919, 1735, 1508) -(2615, 628, 184) -(3829, 1946, 356) -(1559, 1647, 235) -(1589, 4400, 67) -(1301, 3543, 378) -(3105, 1482, 1501) -(3093, 4460, 1716) -(3604, 3044, 200) -(3685, 4290, 349) -(1492, 1294, 821) -(2609, 1903, 637) -(3841, 251, 1857) -(783, 2413, 560) -(3354, 2139, 1339) -(2555, 3579, 1839) -(1421, 3790, 1721) -(3522, 1173, 1962) -(1074, 4014, 1826) -(1321, 1174, 466) -(3828, 4862, 572) -(4257, 1220, 407) -(1957, 4788, 53) -(4602, 127, 431) -(4248, 4494, 313) -(2000, 3680, 63) -(214, 4213, 546) -(4738, 1241, 1899) -(620, 3664, 857) -(1338, 1895, 478) -(2357, 3306, 596) -(4527, 1777, 1663) -(2743, 3341, 162) -(4243, 4154, 624) -(4323, 2267, 1653) -(914, 3927, 452) -(1480, 4672, 308) -(3227, 4852, 1245) -(1431, 1193, 1327) -(2323, 2343, 1424) -(4519, 1229, 918) -(3884, 1030, 1198) -(2682, 4505, 1045) -(3067, 2762, 1168) -(4809, 1777, 1427) -(278, 3484, 745) -(3904, 3711, 249) -(2761, 179, 188) -(1290, 4764, 822) -(2388, 2427, 1514) -(667, 176, 1180) -(2021, 1732, 1681) -(4242, 4534, 956) -(3385, 4593, 408) -(2115, 2262, 1537) -(3266, 3539, 385) -(1049, 3255, 1629) -(803, 4778, 1305) -(4841, 4201, 1810) -(374, 485, 475) -(1652, 3104, 1181) -(3166, 3811, 725) -(3279, 1990, 153) -(2380, 2627, 1806) -(2556, 4896, 1676) -(3270, 3547, 1946) -(4993, 1670, 1233) -(4058, 1010, 323) -(3690, 3459, 1791) -(3014, 1061, 763) -(708, 1888, 1233) -(3960, 3849, 766) -(1721, 317, 70) -(1082, 3125, 261) -(3810, 2268, 188) -(4570, 3361, 646) -(3526, 3548, 922) -(572, 3619, 1693) -(2146, 2967, 1677) -(1728, 4390, 1619) -(1076, 807, 1310) -(2964, 2793, 1942) -(3476, 4491, 501) -(857, 751, 503) -(3624, 3227, 1113) -(4711, 2841, 854) -(2426, 4691, 361) -(240, 3873, 1967) -(941, 4127, 851) -(1349, 906, 977) -(3190, 3736, 876) -(2905, 1855, 163) -(2803, 1584, 1076) -(1950, 4404, 526) -(2553, 2303, 629) -(582, 1823, 816) -(1440, 4434, 1869) -(955, 3075, 261) -(1288, 510, 65) -(1105, 3702, 646) -(2555, 4342, 355) -(321, 1031, 743) -(1942, 2076, 362) -(1980, 2375, 1099) -(497, 4270, 956) -(4027, 2083, 1334) -(3191, 562, 629) -(1324, 3754, 681) -(993, 3061, 786) -(4665, 4115, 66) -(4500, 4825, 664) -(4396, 4666, 1816) -(1830, 1473, 1197) -(3155, 2897, 395) -(798, 3926, 1798) -(1820, 2292, 76) -(2234, 939, 1819) -(4979, 4803, 1711) -(2181, 224, 1912) -(4442, 3056, 167) -(382, 2259, 952) -(2902, 106, 733) -(1065, 3110, 723) -(1119, 3327, 726) -(1028, 4038, 242) -(1466, 582, 1716) -(2086, 39, 353) -(1832, 1175, 1193) -(308, 1397, 122) -(148, 130, 1066) -(479, 720, 1680) -(3098, 4261, 111) -(757, 2573, 1787) -(2358, 4562, 1279) -(3905, 486, 1094) -(4959, 170, 1195) -(4281, 3060, 1659) -(1181, 1410, 1820) -(2276, 2330, 1822) -(2951, 3234, 899) -(4057, 3063, 1832) -(1964, 3317, 1652) -(1232, 4107, 1554) -(3007, 717, 1513) -(1099, 1384, 783) -(3553, 1168, 1015) -(2682, 2518, 630) -(1555, 4356, 1654) -(3914, 2662, 1329) -(915, 2725, 1757) -(4917, 100, 830) -(4314, 203, 607) -(3946, 697, 1273) -(3187, 4055, 1308) -(4364, 4535, 1688) -(293, 1427, 1962) -(2503, 680, 1929) -(2674, 4936, 1386) -(3927, 3039, 1117) -(1297, 4261, 1525) -(1224, 3578, 1835) -(2675, 1665, 1149) -(3505, 3174, 1251) -(4128, 3878, 285) -(1079, 2684, 560) -(4607, 723, 1133) -(1798, 2058, 1325) -(4956, 4442, 1922) -(4236, 2469, 1751) -(2691, 4649, 131) -(2848, 1802, 145) -(2592, 1892, 1418) -(4501, 4902, 1599) -(1831, 2134, 252) -(1388, 1404, 747) -(3775, 3808, 805) -(4301, 3573, 1886) -(630, 1618, 1161) -(787, 3168, 1628) -(2959, 2710, 789) -(3194, 27, 1333) -(1949, 3923, 1932) -(148, 3765, 1094) -(510, 2690, 304) -(175, 2048, 285) -(4538, 2620, 526) -(2855, 3698, 742) -(3495, 3129, 643) -(2858, 933, 658) -(308, 2284, 1671) -(1346, 4547, 1656) -(3779, 798, 328) -(806, 150, 278) -(1661, 4559, 1631) -(2241, 1088, 1681) -(3080, 4784, 1612) -(1914, 3091, 392) -(1650, 789, 373) -(909, 4717, 551) -(4248, 3785, 1729) -(2699, 2240, 112) -(3761, 2888, 1274) -(4980, 3500, 1575) -(894, 1455, 822) -(4308, 1118, 1093) -(3483, 359, 1819) -(1788, 3424, 1362) -(2026, 3312, 62) -(4576, 4628, 1967) -(2349, 3034, 240) -(455, 2297, 1246) -(3287, 1140, 1488) -(843, 3383, 629) -(1845, 4, 466) -(2604, 4900, 560) -(818, 723, 1231) -(3351, 2639, 426) -(817, 1004, 1703) -(2549, 4683, 839) -(1744, 153, 1820) -(514, 760, 797) -(2225, 864, 579) -(2538, 4777, 1670) -(431, 4684, 1020) -(4055, 3187, 1308) -(1969, 1512, 1487) -(1631, 3461, 690) -(1155, 4716, 1134) -(2979, 3134, 1093) -(2800, 2344, 1839) -(4667, 3055, 538) -(3492, 2191, 1843) -(1211, 1241, 853) -(2854, 1184, 1890) -(418, 3820, 1305) -(4771, 2341, 1811) -(3427, 3495, 178) -(325, 2519, 942) -(4464, 4045, 1044) -(2347, 4659, 1904) -(4532, 1565, 952) -(340, 1837, 604) -(3417, 2813, 1074) -(111, 1302, 937) -(1603, 4433, 362) -(293, 3941, 1173) -(3100, 2507, 303) -(3728, 3876, 455) -(4108, 1882, 745) -(1432, 4560, 142) -(4931, 4180, 574) -(4071, 830, 687) -(650, 4405, 1831) -(2257, 2915, 1758) -(2052, 1176, 1971) -(2132, 58, 1517) -(187, 351, 683) -(2237, 2948, 175) -(2604, 543, 456) -(2977, 225, 1702) -(4725, 3000, 628) -(3204, 864, 693) -(3150, 4060, 782) -(4954, 4238, 1662) -(1869, 1986, 508) -(868, 4106, 1850) -(3929, 3251, 1682) -(530, 4475, 595) -(4556, 3922, 503) -(184, 1416, 1477) -(3572, 1481, 437) -(3075, 926, 1686) -(3820, 2858, 707) -(2821, 2152, 1646) -(1098, 4982, 1427) -(2090, 2569, 1042) -(3506, 1335, 1376) -(1100, 3023, 1627) -(4652, 3060, 1912) -(673, 1398, 341) -(2098, 1068, 1731) -(4497, 1244, 436) -(2174, 2783, 959) -(3689, 904, 1392) -(1167, 4202, 1656) -(2344, 456, 771) -(1716, 617, 1750) -(4781, 3453, 398) -(2723, 1712, 1979) -(4321, 2973, 1326) -(1214, 3956, 1223) -(2225, 2971, 1187) -(80, 4301, 874) -(4847, 4079, 1993) -(4378, 3465, 1866) -(4673, 4434, 558) -(4395, 1610, 580) -(454, 4573, 1238) -(2473, 2465, 1638) -(2037, 4290, 1584) -(492, 1200, 78) -(1546, 385, 336) -(4410, 297, 1882) -(1706, 2002, 529) -(2256, 1398, 1134) -(54, 41, 72) -(803, 4190, 1763) -(2456, 2559, 1894) -(2769, 2295, 1934) -(4769, 2634, 1596) -(4128, 2389, 600) -(3761, 2271, 1354) -(882, 4595, 1728) -(3278, 3240, 1257) -(839, 3955, 151) -(1349, 2270, 1011) -(4857, 1053, 632) -(3094, 3940, 490) -(2550, 2555, 537) -(1864, 309, 452) -(4536, 1818, 195) -(3282, 3514, 1912) -(330, 4975, 1631) -(1566, 4508, 1173) -(693, 319, 1357) -(3145, 4254, 1598) -(3874, 2973, 351) -(1040, 3727, 619) -(2958, 4622, 1742) -(1705, 2875, 710) -(4076, 508, 1489) -(3915, 774, 1105) -(2593, 3529, 1595) -(4748, 4514, 1768) -(2759, 512, 566) -(1776, 1648, 762) -(421, 4485, 756) -(2190, 2067, 680) -(1275, 76, 399) -(1865, 3034, 1641) -(3073, 2798, 1368) -(2182, 4521, 1275) -(4090, 3772, 594) -(1917, 1854, 499) -(2464, 1200, 1845) -(4544, 1432, 265) -(1402, 2848, 1659) -(4550, 3162, 1869) -(2743, 3612, 317) -(3063, 4057, 1832) -(4183, 2852, 869) -(610, 4631, 694) -(1338, 4814, 686) -(46, 1317, 748) -(1209, 2527, 107) -(3294, 99, 1821) -(240, 2541, 639) -(2889, 876, 576) -(3590, 3257, 863) -(1463, 610, 1988) -(4129, 1377, 328) -(806, 291, 82) -(4513, 2981, 1799) -(2757, 2223, 748) -(4566, 1799, 350) -(3355, 1327, 163) -(1745, 1430, 343) -(4023, 2046, 123) -(3361, 4769, 1066) -(2689, 833, 1734) -(3661, 4566, 1455) -(207, 4187, 1144) -(4184, 2376, 1430) -(4293, 2474, 60) -(2828, 3022, 620) -(1435, 558, 1600) -(1929, 3567, 1563) -(3496, 904, 355) -(667, 2956, 1037) -(3804, 1527, 1552) -(1421, 975, 338) -(1497, 281, 1789) -(2803, 2958, 872) -(4982, 2318, 605) -(1737, 2314, 936) -(658, 509, 650) -(4834, 1590, 589) -(209, 4118, 413) -(4936, 2674, 1386) -(2896, 1076, 78) -(3641, 4797, 294) -(2626, 3397, 1242) -(1992, 276, 239) -(1717, 45, 1528) -(1453, 3908, 907) -(3242, 804, 1044) -(3645, 166, 172) -(4163, 4399, 1667) -(3437, 2487, 882) -(3298, 307, 1741) -(3510, 3085, 1256) -(4934, 3900, 76) -(1695, 4046, 131) -(4612, 2888, 961) -(1748, 3105, 533) -(1999, 2623, 247) -(1862, 949, 157) -(4966, 3230, 751) -(4034, 4183, 875) -(3751, 4268, 431) -(4971, 1350, 786) -(3071, 610, 1672) -(4781, 1330, 672) -(4664, 3531, 861) -(2496, 4072, 499) -(3830, 872, 1410) -(2258, 311, 804) -(314, 1269, 949) -(1999, 4237, 1490) -(2762, 1163, 1365) -(2656, 2458, 1529) -(1708, 1498, 294) -(2140, 1847, 116) -(1061, 1607, 1716) -(4953, 2316, 1083) -(1333, 2118, 1927) -(46, 4418, 565) -(2700, 1713, 100) -(4484, 4566, 1034) -(970, 128, 708) -(1708, 2877, 186) -(444, 2023, 188) -(955, 4457, 510) -(11, 3340, 957) -(228, 2662, 572) -(1015, 4996, 579) -(4756, 4698, 269) -(3864, 4904, 1097) -(3875, 108, 1556) -(2615, 3274, 1848) -(2659, 4447, 912) -(460, 909, 379) -(2896, 1869, 1085) -(4215, 4374, 889) -(2574, 4480, 1843) -(1937, 2529, 1060) -(2505, 1180, 647) -(1363, 4549, 703) -(3869, 598, 314) -(1028, 154, 1600) -(2948, 3227, 1382) -(2859, 4353, 1473) -(273, 4947, 1421) -(1491, 606, 1475) -(1152, 4511, 339) -(248, 3078, 565) -(454, 2139, 1560) -(2537, 414, 1886) -(2910, 4793, 586) -(1167, 1189, 1318) -(910, 3510, 121) -(3849, 538, 1278) -(2238, 4641, 753) -(3280, 1701, 834) -(1023, 327, 654) -(3113, 4866, 265) -(2074, 1104, 210) -(2306, 3006, 549) -(3995, 4460, 596) -(3745, 3185, 1654) -(2397, 4288, 1008) -(3592, 1908, 1277) -(3254, 1580, 56) -(3479, 1824, 945) -(639, 1975, 1897) -(814, 3662, 118) -(1877, 3057, 291) -(4644, 4548, 1280) -(39, 3709, 278) -(909, 4426, 737) -(3733, 119, 1962) -(1744, 4167, 1117) -(695, 3417, 1166) -(4910, 2811, 1272) -(4305, 4860, 117) -(1396, 4569, 1808) -(3990, 4054, 1794) -(1745, 1319, 958) -(1418, 3453, 1988) -(108, 3875, 1556) -(2168, 2619, 1174) -(3505, 1086, 956) -(807, 1076, 1310) -(4823, 194, 1929) -(4402, 1445, 170) -(2682, 1381, 1929) -(3471, 61, 813) -(4952, 2199, 875) -(2117, 3030, 1515) -(4061, 2553, 397) -(4114, 2659, 409) -(4442, 3859, 1997) -(3518, 120, 838) -(2859, 1709, 345) -(4780, 4687, 1977) -(445, 648, 1813) -(1579, 2565, 828) -(4350, 611, 1637) -(83, 1639, 1721) -(3459, 3690, 1791) -(731, 1875, 1954) -(1656, 826, 507) -(607, 1324, 1854) -(4079, 2468, 833) -(939, 2234, 1819) -(3725, 1063, 522) -(3619, 572, 1693) -(4215, 2639, 84) -(2768, 4409, 304) -(2640, 3155, 580) -(570, 4774, 99) -(3924, 2833, 194) -(959, 1631, 193) -(1391, 3959, 121) -(4293, 4382, 518) -(926, 2348, 441) -(2013, 2044, 278) -(3817, 435, 1009) -(3260, 3435, 1614) -(2827, 837, 1479) -(564, 568, 911) -(807, 83, 1100) -(3956, 1214, 1223) -(738, 2532, 1279) -(4971, 4247, 492) -(3775, 310, 1229) -(2035, 441, 1309) -(316, 4161, 88) -(1753, 3540, 1626) -(663, 3564, 932) -(4758, 4444, 1474) -(2190, 4982, 1613) -(1067, 3155, 1896) -(3107, 1102, 1279) -(3653, 4259, 1324) -(2312, 3503, 882) -(1468, 645, 1084) -(4792, 4501, 1274) -(2579, 3625, 996) -(1520, 1349, 1445) -(161, 396, 947) -(1706, 1034, 142) -(2714, 320, 669) -(1071, 3392, 1981) -(334, 1485, 1340) -(4323, 139, 1662) -(2308, 2861, 218) -(4757, 518, 1181) -(4073, 4912, 1904) -(1878, 226, 1006) -(2479, 1640, 507) -(326, 245, 307) -(16, 1908, 988) -(3294, 2419, 1256) -(4723, 2391, 937) -(4573, 1348, 179) -(3415, 2669, 1462) -(4978, 4372, 172) -(371, 2829, 1415) -(385, 2753, 1487) -(4841, 3808, 524) -(1829, 1893, 468) -(3980, 4411, 1869) -(1568, 486, 1964) -(4891, 2488, 154) -(1603, 171, 683) -(1056, 4909, 319) -(442, 2633, 1399) -(3586, 2218, 1450) -(2071, 931, 923) -(537, 3451, 1500) -(1990, 4229, 814) -(4493, 40, 1388) -(562, 946, 802) -(129, 4477, 1708) -(3465, 3797, 526) -(2012, 556, 1520) -(210, 1445, 649) -(1111, 3801, 1189) -(1413, 95, 1923) -(4931, 876, 824) -(929, 4377, 1546) -(3180, 2344, 1367) -(3924, 4792, 751) -(3056, 477, 698) -(3137, 3579, 773) -(4206, 1464, 400) -(1954, 2081, 1018) -(2337, 3538, 1965) -(2654, 4569, 864) -(657, 882, 963) -(4162, 674, 1907) -(2901, 1414, 1773) -(3725, 2146, 1896) -(4643, 2953, 55) -(349, 2914, 150) -(542, 1926, 74) -(835, 664, 451) -(4703, 2109, 1425) -(3578, 1224, 1835) -(2825, 514, 1709) -(829, 1171, 1213) -(1874, 4474, 673) -(2840, 4633, 891) -(1045, 1418, 1767) -(2758, 2936, 942) -(3078, 1307, 871) -(760, 514, 797) -(2011, 4322, 977) -(2453, 946, 1053) -(3670, 2581, 1432) -(1055, 1313, 829) -(2524, 4306, 1502) -(2217, 2643, 66) -(1871, 2325, 479) -(2878, 4928, 1239) -(4253, 4136, 826) -(926, 3075, 1686) -(2650, 3072, 1933) -(2761, 3083, 183) -(2342, 458, 935) -(4044, 4518, 1566) -(3294, 4125, 761) -(4859, 877, 1910) -(1199, 6, 1900) -(65, 3291, 1432) -(344, 1775, 1131) -(637, 899, 554) -(4092, 4877, 1604) -(3937, 58, 1996) -(712, 4296, 1006) -(281, 3382, 1593) -(3117, 309, 1924) -(4628, 1957, 362) -(684, 564, 568) -(3223, 4170, 1933) -(3950, 4106, 328) -(4282, 2327, 1897) -(2337, 4133, 585) -(3340, 4711, 149) -(2855, 2861, 1646) -(2689, 3982, 1724) -(3992, 3562, 1426) -(4854, 595, 1739) -(4912, 4073, 1904) -(1102, 1210, 115) -(3967, 3224, 1323) -(1623, 1900, 1314) -(4931, 444, 1234) -(429, 1588, 1815) -(952, 4391, 276) -(3348, 1247, 1219) -(4443, 3808, 264) -(4515, 2095, 265) -(2117, 3524, 528) -(4130, 4710, 1985) -(2021, 1349, 1084) -(4294, 2749, 609) -(4474, 3898, 902) -(2840, 2129, 164) -(4608, 334, 332) -(3265, 947, 1235) -(4949, 2946, 1765) -(4227, 2141, 1692) -(1816, 3727, 206) -(305, 3233, 1841) -(4678, 3689, 1945) -(3287, 2885, 325) -(4116, 2729, 277) -(446, 3261, 1664) -(773, 2528, 110) -(614, 3542, 521) -(1291, 2159, 481) -(769, 1920, 380) -(3749, 823, 126) -(2699, 1491, 555) -(2145, 3956, 1370) -(1824, 3479, 945) -(3884, 3042, 1598) -(19, 4306, 322) -(847, 4952, 591) -(2521, 209, 876) -(2010, 2753, 1202) -(2393, 2226, 173) -(3044, 1455, 1889) -(3302, 1727, 1704) -(2525, 1461, 937) -(721, 884, 1451) -(382, 2454, 1543) -(3416, 2407, 994) -(1906, 2493, 1644) -(2371, 1843, 194) -(1286, 4877, 1413) -(3640, 1030, 198) -(3974, 795, 704) -(1350, 2289, 1443) -(4823, 4970, 1130) -(388, 143, 168) -(4676, 1835, 795) -(185, 737, 1397) -(1049, 2410, 1248) -(318, 2331, 1187) -(2826, 933, 1784) -(2503, 105, 318) -(837, 2827, 1479) -(4161, 4878, 1075) -(4455, 4557, 924) -(228, 3387, 714) -(4951, 2580, 1721) -(1034, 277, 741) -(975, 1181, 1130) -(3291, 1156, 437) -(4576, 4447, 347) -(4155, 4799, 155) -(4394, 3959, 343) -(1476, 130, 842) -(3596, 2615, 522) -(1795, 526, 1142) -(3241, 2631, 1353) -(220, 1202, 294) -(3843, 4857, 725) -(3277, 4205, 1178) -(1530, 855, 651) -(3545, 4707, 1637) -(4675, 4987, 1583) -(3388, 821, 655) -(2819, 82, 565) -(3455, 3341, 466) -(2897, 886, 275) -(4124, 27, 163) -(4664, 2348, 1487) -(3927, 748, 1685) -(1517, 1650, 1627) -(2915, 2257, 1758) -(4689, 2863, 1623) -(4051, 2184, 1498) -(2287, 599, 915) -(2283, 1445, 864) -(1583, 1529, 1472) -(128, 1614, 1727) -(629, 3900, 1579) -(4265, 4771, 843) -(3453, 1418, 1988) -(3210, 2604, 1975) -(2877, 4981, 77) -(3449, 1314, 1393) -(3384, 1475, 1832) -(415, 2765, 1562) -(1870, 2639, 150) -(1012, 4467, 985) -(1545, 466, 352) -(2682, 3046, 715) -(2087, 1480, 1172) -(4741, 4604, 836) -(4824, 3593, 1473) -(1342, 2764, 636) -(3615, 4605, 594) -(1894, 4776, 304) -(2982, 1163, 1205) -(3175, 2344, 1724) -(4012, 1228, 501) -(2144, 45, 801) -(2255, 2319, 947) -(109, 3773, 1038) -(823, 4314, 213) -(2003, 4384, 1654) -(4928, 2878, 1239) -(2828, 1460, 761) -(3426, 2458, 1280) -(1326, 4151, 205) -(650, 4668, 1512) -(1115, 3075, 1251) -(2188, 4360, 251) -(3893, 3284, 1723) -(4271, 280, 1868) -(603, 4155, 932) -(4600, 2631, 1023) -(2271, 3529, 415) -(4798, 3043, 477) -(4051, 2756, 1066) -(583, 18, 736) -(996, 4621, 1097) -(2482, 2640, 424) -(2861, 1660, 1143) -(2827, 4020, 650) -(4720, 1551, 402) -(864, 3204, 693) -(3224, 4897, 1745) -(4500, 2193, 468) -(4308, 4878, 1898) -(4502, 1635, 1480) -(4628, 2714, 110) -(1153, 1464, 1109) -(76, 1275, 399) -(2373, 4134, 576) -(1752, 1013, 1620) -(4345, 903, 1935) -(4358, 4926, 715) -(4162, 4439, 1449) -(4194, 4379, 823) -(612, 4812, 1696) -(2148, 4633, 340) -(1186, 3596, 458) -(2981, 1120, 67) -(4128, 2670, 314) -(4560, 1395, 1495) -(48, 735, 1831) -(884, 721, 1451) -(2609, 945, 66) -(783, 4218, 986) -(4306, 3511, 815) -(1920, 769, 380) -(4581, 3631, 297) -(3861, 2517, 1783) -(1043, 518, 272) -(1741, 739, 1239) -(2010, 3850, 794) -(4831, 4175, 148) -(2361, 1964, 1928) -(1953, 1199, 946) -(812, 2021, 845) -(2830, 474, 194) -(2306, 2817, 1048) -(3868, 1882, 1306) -(2669, 3306, 787) -(2528, 1410, 680) -(3796, 1142, 471) -(4385, 2082, 1892) -(2735, 603, 1973) -(304, 4760, 1956) -(3025, 2054, 1192) -(422, 4157, 1201) -(527, 1018, 1576) -(4466, 3983, 1756) -(982, 3404, 1855) -(1553, 2293, 1192) -(3095, 1431, 515) -(2080, 3911, 154) -(4499, 4139, 926) -(2003, 4603, 1386) -(1718, 4740, 993) -(4637, 2391, 296) -(4468, 2217, 1868) -(295, 415, 1313) -(4763, 4293, 510) -(4122, 4295, 1175) -(2603, 3442, 1105) -(3445, 4723, 1148) -(945, 942, 1273) -(1563, 1654, 841) -(906, 3304, 195) -(860, 31, 1144) -(4933, 338, 1064) -(1913, 2341, 840) -(461, 68, 294) -(2002, 3246, 1941) -(3446, 4399, 1157) -(747, 2883, 1358) -(190, 1910, 950) -(2086, 1731, 1641) -(3217, 4602, 1307) -(1354, 469, 676) -(4878, 2304, 1241) -(4690, 1096, 1129) -(3604, 2629, 1155) -(4474, 3632, 996) -(4807, 662, 1862) -(1544, 4048, 819) -(3285, 4885, 897) -(1318, 3635, 1613) -(423, 3965, 1285) -(2816, 3695, 999) -(4873, 884, 1301) -(206, 3315, 1907) -(4091, 79, 1037) -(3873, 240, 1967) -(1854, 2781, 1108) -(672, 3793, 1615) -(1740, 772, 1113) -(2654, 197, 1156) -(2247, 785, 1659) -(3585, 3201, 1437) -(3927, 914, 452) -(1818, 2098, 1613) -(740, 4158, 1712) -(4701, 1105, 1135) -(1080, 4311, 1746) -(871, 1024, 400) -(737, 4220, 984) -(1280, 3993, 1901) -(2366, 4852, 1657) -(2911, 1817, 1121) -(3480, 1381, 882) -(2639, 3702, 1653) -(4070, 958, 1145) -(4734, 3083, 375) -(949, 1862, 157) -(3911, 126, 325) -(3065, 1291, 1277) -(3169, 1433, 1001) -(1790, 197, 568) -(4179, 345, 1085) -(2001, 4730, 434) -(2266, 3216, 1863) -(463, 1102, 1344) -(3057, 400, 1049) -(1214, 385, 86) -(4046, 4383, 196) -(489, 606, 789) -(3859, 1793, 178) -(703, 132, 1263) -(3397, 2626, 1242) -(4155, 1743, 400) -(895, 2992, 1360) -(2824, 3444, 942) -(3169, 2738, 1213) -(1065, 1378, 1180) -(1171, 1570, 1567) -(4441, 1602, 308) -(4935, 54, 213) -(2706, 1419, 444) -(1798, 3472, 1884) -(2249, 3660, 1910) -(1995, 525, 1984) -(1701, 1118, 305) -(123, 503, 1668) -(3131, 3962, 137) -(4854, 386, 1372) -(1791, 4242, 667) -(3345, 1861, 567) -(951, 1483, 259) -(1385, 1315, 429) -(3595, 4515, 1805) -(4691, 4654, 1428) -(3132, 1768, 1616) -(715, 4608, 248) -(1831, 1431, 647) -(407, 1653, 1636) -(268, 753, 113) -(4069, 1397, 1705) -(291, 4261, 1898) -(4204, 3338, 1008) -(4290, 2037, 1584) -(3578, 3596, 1962) -(3479, 4601, 177) -(2880, 2945, 872) -(2474, 527, 1922) -(589, 4684, 1042) -(2965, 1255, 1925) -(527, 825, 922) -(1614, 499, 834) -(3717, 2481, 802) -(1276, 4023, 1565) -(1484, 236, 1793) -(893, 4431, 1508) -(1645, 2235, 1213) -(443, 746, 605) -(2521, 4667, 1179) -(2003, 4269, 1400) -(3493, 1014, 306) -(2162, 3155, 1463) -(251, 1289, 1113) -(1561, 1686, 1821) -(3066, 3602, 564) -(4210, 4470, 1918) -(3000, 4829, 1845) -(2469, 1202, 1551) -(124, 2992, 143) -(1127, 4120, 1278) -(1714, 4507, 1885) -(315, 1086, 1407) -(3394, 1504, 1093) -(3813, 4767, 646) -(1068, 1297, 979) -(1642, 2936, 585) -(31, 2069, 1770) -(2982, 2447, 868) -(2935, 1055, 1003) -(4672, 449, 322) -(2481, 3717, 802) -(3549, 2300, 395) -(389, 4874, 833) -(1216, 2191, 1385) -(2770, 473, 1181) -(901, 3179, 1906) -(1003, 268, 192) -(2423, 221, 1473) -(1384, 725, 1562) -(4852, 2366, 1657) -(3356, 4195, 485) -(2406, 3312, 1732) -(4925, 3510, 643) -(2676, 1287, 275) -(4084, 667, 1872) -(3096, 2733, 1858) -(2459, 4395, 1865) -(3751, 4099, 1218) -(951, 2934, 760) -(1133, 2795, 1182) -(2350, 872, 820) -(1297, 1583, 1179) -(2154, 1989, 1149) -(2177, 1526, 1938) -(2900, 1939, 779) -(1151, 2450, 1364) -(557, 4547, 1715) -(4156, 809, 597) -(277, 3927, 1533) -(4399, 3446, 1157) -(4781, 665, 97) -(1427, 4568, 392) -(1652, 2396, 1135) -(2762, 3514, 1462) -(3388, 3419, 1434) -(3772, 4090, 594) -(0, 328, 67) -(499, 3764, 1040) -(2020, 1312, 1286) -(286, 4891, 559) -(2262, 1578, 1723) -(311, 2256, 74) -(67, 288, 1969) -(1815, 1547, 1256) -(2929, 43, 661) -(4853, 1986, 194) -(2799, 1806, 1020) -(1878, 2949, 1240) -(1180, 3074, 803) -(3683, 4722, 1194) -(3722, 4686, 364) -(4073, 2110, 744) -(3994, 153, 1298) -(1820, 2843, 1764) -(391, 1307, 151) -(2086, 3899, 1035) -(2301, 1433, 483) -(2009, 1501, 1655) -(4667, 4093, 1027) -(187, 4988, 1993) -(2725, 347, 1741) -(4156, 1157, 1885) -(1406, 4581, 344) -(93, 4543, 1827) -(1771, 2660, 1289) -(1759, 1643, 1957) -(1543, 3942, 326) -(2051, 4641, 840) -(2391, 1160, 1654) -(2762, 1004, 182) -(2154, 1433, 490) -(4685, 2374, 1218) -(1173, 1783, 747) -(1741, 2144, 701) -(1971, 3331, 518) -(3587, 2790, 316) -(4543, 3712, 1431) -(1969, 109, 1762) -(1685, 739, 1336) -(3922, 1383, 1330) -(3938, 3782, 1007) -(761, 999, 1305) -(4907, 4830, 1960) -(1016, 4263, 1570) -(1312, 4564, 102) -(3210, 711, 1928) -(3787, 2463, 1061) -(421, 3628, 1346) -(2123, 2708, 924) -(2880, 2482, 1226) -(4311, 1080, 1746) -(3239, 1892, 1749) -(4673, 2120, 1684) -(2292, 1820, 76) -(1851, 1653, 1906) -(3772, 3501, 1527) -(1713, 1549, 324) -(2628, 2559, 1765) -(958, 2488, 1597) -(885, 1400, 1273) -(2070, 2024, 1499) -(2814, 698, 1555) -(1349, 2021, 1084) -(4180, 4931, 574) -(3033, 2245, 702) -(2690, 1598, 1709) -(309, 1864, 452) -(2005, 3486, 1672) -(650, 1752, 1605) -(3793, 672, 1615) -(604, 4500, 404) -(3209, 4542, 1089) -(3299, 3315, 1711) -(4656, 3348, 1631) -(2224, 3973, 1330) -(732, 1100, 522) -(4939, 3558, 931) -(4683, 3629, 1967) -(280, 3337, 232) -(1451, 170, 1482) -(1522, 2390, 273) -(4304, 4255, 903) -(1067, 2072, 214) -(3544, 4596, 540) -(4691, 2426, 361) -(2126, 4562, 947) -(1387, 4759, 658) -(2212, 4970, 1334) -(3802, 1925, 1892) -(2421, 670, 780) -(3416, 780, 1639) -(2831, 1381, 1993) -(4841, 4358, 1392) -(4921, 1705, 1856) -(568, 2719, 718) -(3479, 1433, 1348) -(2498, 3229, 1073) -(4654, 3732, 1055) -(466, 4623, 369) -(4066, 2475, 457) -(2971, 690, 1866) -(2443, 2506, 1176) -(2700, 1298, 84) -(1476, 1837, 954) -(3, 4617, 1613) -(2631, 2448, 858) -(4776, 3367, 934) -(3049, 3545, 565) -(1627, 471, 1145) -(3332, 4321, 1636) -(3710, 3800, 211) -(4909, 3926, 1685) -(4046, 4568, 261) -(2181, 4362, 1977) -(4490, 4260, 1683) -(1464, 1820, 122) -(210, 3183, 1994) -(151, 4086, 910) -(97, 2491, 1334) -(2924, 4313, 745) -(1106, 3249, 1842) -(1761, 4530, 1889) -(3504, 3843, 1643) -(1205, 1407, 1228) -(3408, 2549, 703) -(3127, 1793, 718) -(3437, 2921, 229) -(3940, 1236, 731) -(3458, 53, 1154) -(3197, 497, 815) -(1215, 677, 1080) -(4969, 1508, 564) -(749, 3512, 497) -(3921, 453, 1895) -(4572, 4087, 996) -(1612, 2214, 669) -(3515, 2298, 142) -(1468, 77, 748) -(1145, 4523, 891) -(3041, 3049, 1323) -(4548, 120, 422) -(1869, 865, 711) -(1629, 537, 878) -(2652, 953, 310) -(4999, 227, 1641) -(1448, 2974, 1273) -(4698, 1504, 1239) -(4270, 2233, 1268) -(418, 690, 1285) -(1312, 557, 553) -(2836, 3787, 1254) -(2386, 4432, 299) -(2300, 2287, 713) -(4762, 894, 601) -(3642, 4747, 1695) -(2587, 3542, 1674) -(2373, 2361, 1035) -(193, 4231, 1386) -(3911, 4060, 933) -(1398, 673, 341) -(3332, 4788, 1498) -(2505, 2330, 1552) -(4029, 4763, 138) -(1532, 1087, 1419) -(4086, 1346, 1512) -(4581, 4874, 118) -(2857, 737, 1256) -(3325, 3988, 98) -(3396, 718, 261) -(1414, 2901, 1773) -(2767, 271, 815) -(821, 4798, 1308) -(3351, 3854, 1395) -(1724, 4084, 101) -(1645, 3561, 148) -(4207, 2884, 1338) -(1059, 4986, 1056) -(3752, 2661, 862) -(2988, 567, 705) -(3889, 2351, 848) -(1280, 2016, 84) -(2895, 3382, 1388) -(2327, 4282, 1897) -(311, 4746, 304) -(3674, 4666, 323) -(4588, 2861, 325) -(2523, 2031, 344) -(2867, 3345, 57) -(498, 4731, 865) -(2003, 4747, 1013) -(4226, 4224, 1833) -(2374, 2838, 1965) -(2447, 3310, 1715) -(3558, 2822, 445) -(4613, 2781, 1600) -(528, 2284, 1575) -(3853, 534, 309) -(2750, 1825, 344) -(680, 1870, 1322) -(343, 1306, 1750) -(966, 4550, 1698) -(4360, 3425, 1358) -(3383, 843, 629) -(3777, 2288, 1590) -(3631, 2197, 1879) -(3031, 1224, 953) -(1193, 1431, 1327) -(231, 1348, 443) -(2646, 4555, 814) -(1034, 1941, 714) -(4842, 1998, 1180) -(4203, 3924, 1158) -(4185, 2497, 1642) -(2183, 625, 877) -(4528, 1390, 1445) -(2020, 3188, 1727) -(3708, 4605, 892) -(3701, 1645, 233) -(1672, 2671, 988) -(2287, 4074, 1292) -(2258, 50, 752) -(1150, 4597, 966) -(1273, 3090, 1919) -(977, 2478, 691) -(4874, 2541, 541) -(4326, 3498, 1968) -(3910, 2975, 1732) -(2588, 2166, 172) -(4332, 179, 892) -(4431, 4257, 896) -(4606, 2083, 287) -(1423, 326, 233) -(3461, 3887, 1470) -(3098, 1605, 256) -(22, 3381, 1782) -(4863, 4322, 774) -(3848, 1852, 230) -(143, 388, 168) -(950, 572, 426) -(2938, 3526, 1483) -(3658, 3811, 126) -(3243, 4198, 1430) -(4841, 3815, 1688) -(1961, 3020, 1524) -(3988, 812, 1078) -(315, 2347, 674) -(4510, 44, 1533) -(138, 2928, 1647) -(2302, 1737, 1594) -(2055, 4985, 1986) -(538, 3849, 1278) -(2440, 948, 1731) -(1417, 10, 1589) -(4862, 4531, 544) -(4841, 3696, 912) -(4557, 4455, 924) -(2852, 2041, 1023) -(1615, 2392, 1960) -(1817, 3166, 1199) -(461, 4799, 1288) -(3791, 3054, 1852) -(4024, 3263, 629) -(1765, 163, 1444) -(2528, 417, 1937) -(4530, 2752, 1659) -(3950, 1041, 1380) -(724, 3780, 808) -(622, 4607, 605) -(1599, 3431, 1033) -(2306, 3913, 1001) -(3899, 981, 981) -(1942, 3675, 1183) -(598, 204, 1432) -(1319, 1592, 518) -(1445, 1869, 1335) -(1118, 4308, 1093) -(375, 2537, 778) -(2159, 1812, 1221) -(2931, 3225, 1022) -(3034, 4843, 1236) -(1403, 2838, 147) -(1578, 944, 446) -(2840, 4237, 1596) -(2696, 4891, 1318) -(4114, 574, 342) -(927, 3999, 1836) -(140, 323, 1217) -(2583, 1369, 1272) -(2720, 4225, 923) -(1609, 4973, 1874) -(4841, 731, 451) -(3613, 89, 1510) -(244, 2275, 1890) -(993, 1140, 1349) -(2252, 3079, 1124) -(3517, 4191, 1525) -(2311, 1934, 288) -(4333, 1883, 1202) -(1802, 4951, 1374) -(4475, 4362, 1179) -(2648, 2964, 1532) -(3929, 1076, 1814) -(1662, 3806, 1970) -(2219, 399, 1959) -(736, 2979, 399) -(2418, 2494, 113) -(3108, 299, 1445) -(1797, 3395, 1008) -(2777, 1149, 916) -(1286, 1042, 1322) -(250, 379, 1177) -(768, 1370, 1751) -(2380, 4465, 1427) -(4820, 770, 157) -(539, 3737, 1410) -(4853, 4669, 915) -(2723, 4955, 305) -(4693, 628, 1675) -(1974, 1417, 973) -(963, 1769, 1265) -(2556, 4027, 716) -(1813, 1233, 159) -(996, 4319, 1254) -(691, 4862, 577) -(4246, 4872, 353) -(2899, 703, 204) -(4447, 4957, 101) -(1443, 2124, 939) -(1825, 3741, 1112) -(4924, 2891, 1029) -(1817, 2911, 1121) -(4985, 492, 1948) -(2810, 2857, 1726) -(523, 4861, 1133) -(3514, 4488, 1446) -(3023, 3302, 1237) -(3871, 2200, 910) -(737, 2857, 1256) -(2810, 1233, 1691) -(3266, 4440, 856) -(1096, 1520, 200) -(3779, 2362, 109) -(79, 4091, 1037) -(2133, 1388, 107) -(3131, 4225, 965) -(2619, 3778, 1723) -(2935, 1136, 823) -(952, 4539, 329) -(1228, 4012, 501) -(2427, 1964, 712) -(115, 3554, 1919) -(1665, 1252, 606) -(3091, 3307, 203) -(271, 2327, 570) -(2457, 2491, 794) -(99, 2662, 1977) -(2612, 1797, 207) -(2023, 240, 1660) -(1435, 1570, 1718) -(3484, 1272, 1462) -(2905, 201, 96) -(3261, 446, 1664) -(657, 3186, 396) -(2423, 3300, 242) -(1598, 1953, 780) -(984, 840, 1013) -(4908, 417, 550) -(4566, 3661, 1455) -(182, 2011, 991) -(4862, 3828, 572) -(2724, 4623, 642) -(4085, 4834, 1242) -(1520, 4130, 254) -(2449, 161, 563) -(4232, 4361, 255) -(1352, 211, 1761) -(3737, 539, 1410) -(3058, 1404, 1746) -(4640, 4606, 1239) -(315, 3519, 1948) -(3780, 724, 808) -(680, 1744, 214) -(3950, 2711, 1611) -(678, 3891, 350) -(4732, 1794, 1576) -(4142, 4834, 274) -(4421, 1489, 188) -(1513, 1940, 317) -(4177, 1959, 1596) -(4799, 46, 811) -(631, 17, 187) -(2629, 3604, 1155) -(296, 3892, 1777) -(438, 3731, 976) -(1501, 4510, 627) -(4693, 3167, 418) -(3454, 13, 1714) -(4314, 1968, 254) -(2119, 502, 1307) -(4, 4404, 1741) -(667, 4508, 300) -(1717, 4088, 1738) -(3577, 1802, 445) -(3890, 3774, 1254) -(560, 1584, 1981) -(2120, 1221, 1658) -(3618, 784, 1635) -(1565, 4415, 171) -(1546, 4848, 420) -(4514, 1749, 535) -(306, 4146, 591) -(4501, 1277, 1847) -(4611, 3925, 1966) -(3681, 4616, 336) -(3659, 3937, 832) -(2005, 1550, 1682) -(3240, 3580, 1377) -(4429, 4126, 488) -(209, 4019, 1122) -(2677, 90, 1870) -(2070, 56, 318) -(4857, 205, 652) -(3107, 535, 1693) -(1021, 4276, 1824) -(4841, 3779, 1256) -(1107, 1922, 999) -(2017, 3908, 1339) -(3159, 1660, 1549) -(1310, 4927, 1598) -(3135, 1738, 1478) -(3227, 4399, 1079) -(135, 4572, 234) -(4782, 1300, 1004) -(3273, 2200, 1305) -(1517, 1003, 282) -(1742, 4503, 604) -(44, 1046, 1281) -(162, 4186, 1042) -(2604, 4930, 1894) -(1776, 552, 1660) -(1787, 3938, 579) -(4954, 4724, 59) -(4854, 470, 1613) -(296, 3051, 1139) -(674, 4162, 1907) -(272, 1469, 1253) -(3908, 1422, 180) -(3211, 2934, 98) -(3286, 3374, 1922) -(904, 1745, 129) -(2819, 3145, 1402) -(1480, 1085, 1260) -(583, 3250, 321) -(1150, 1285, 1913) -(1991, 2737, 1374) -(2838, 1483, 1250) -(567, 1307, 129) -(1024, 2051, 196) -(417, 1934, 130) -(2777, 4342, 1652) -(4580, 1886, 1406) -(1871, 790, 1877) -(907, 4461, 1958) -(1418, 3071, 746) -(2580, 4951, 1721) -(4774, 570, 99) -(458, 2539, 1625) -(103, 2095, 436) -(764, 1899, 97) -(3791, 180, 323) -(1064, 2853, 264) -(3283, 1917, 1541) -(1199, 4582, 102) -(2764, 1171, 946) -(2458, 3426, 1280) -(3698, 2608, 391) -(1796, 4972, 1484) -(2644, 3657, 584) -(76, 4771, 431) -(2710, 4989, 528) -(2403, 311, 1912) -(2447, 3409, 1028) -(444, 1849, 1278) -(3610, 2529, 744) -(4138, 1343, 1989) -(4176, 902, 813) -(3383, 4638, 184) -(812, 3988, 1078) -(4309, 3376, 494) -(1652, 378, 1045) -(3142, 459, 1294) -(809, 2965, 515) -(3049, 424, 1960) -(140, 1487, 763) -(1061, 1775, 1282) -(4477, 3890, 1086) -(989, 3716, 177) -(3575, 3339, 1487) -(1570, 1435, 1718) -(4909, 3648, 762) -(769, 409, 66) -(3793, 722, 1951) -(279, 2142, 1211) -(2620, 4300, 1760) -(3387, 3625, 1098) -(632, 4466, 462) -(4872, 887, 1976) -(4943, 4608, 772) -(420, 2064, 1240) -(3598, 4876, 491) -(4818, 2342, 63) -(1445, 3034, 930) -(601, 2357, 386) -(1177, 936, 1736) -(412, 2936, 922) -(3307, 3091, 203) -(4789, 2011, 1590) -(551, 4067, 1458) -(487, 3125, 1280) -(236, 759, 185) -(137, 1135, 1637) -(2302, 1417, 788) -(3051, 3369, 564) -(1078, 3737, 492) -(3546, 1007, 293) -(1989, 2222, 1902) -(188, 1474, 1604) -(2146, 3725, 1896) -(3987, 812, 1878) -(2179, 4414, 405) -(4487, 764, 1983) -(1202, 4739, 1798) -(240, 2023, 1660) -(2559, 863, 436) -(2673, 1764, 652) -(295, 2051, 165) -(4806, 3113, 1927) -(4543, 93, 1827) -(4782, 2303, 880) -(3072, 1789, 1878) -(1203, 538, 1688) -(4134, 618, 187) -(3427, 2228, 1176) -(1207, 34, 173) -(3153, 383, 1034) -(2670, 2235, 834) -(216, 1230, 728) -(634, 4197, 242) -(1954, 4758, 257) -(2683, 3716, 67) -(2634, 4769, 1596) -(19, 3437, 639) -(2023, 444, 188) -(354, 792, 1205) -(4251, 3554, 329) -(2851, 1316, 942) -(2179, 4635, 979) -(1724, 3603, 1030) -(34, 1977, 366) -(1652, 346, 1088) -(1109, 3631, 181) -(2467, 316, 1549) -(975, 3511, 1259) -(1691, 622, 1581) -(1071, 3252, 849) -(4936, 405, 1656) -(2206, 3550, 347) -(2529, 2638, 1320) -(1475, 267, 1873) -(3711, 1652, 1074) -(3114, 245, 705) -(233, 3707, 535) -(3392, 511, 1674) -(2460, 4256, 662) -(1212, 570, 1406) -(3363, 3066, 169) -(1291, 3065, 1277) -(399, 3003, 1101) -(885, 782, 1709) -(4409, 2768, 304) -(4842, 4798, 291) -(3957, 1216, 1665) -(3077, 272, 110) -(2149, 4299, 138) -(3441, 2122, 439) -(525, 2649, 979) -(3022, 729, 1562) -(887, 4872, 1976) -(3288, 175, 680) -(3521, 2369, 568) -(2178, 3346, 1964) -(2648, 14, 1830) -(1516, 843, 665) -(571, 591, 1671) -(209, 2138, 974) -(3332, 866, 1890) -(513, 670, 642) -(2567, 983, 767) -(2895, 506, 1276) -(1769, 963, 1265) -(1375, 3560, 577) -(2055, 1967, 1216) -(3331, 1910, 1502) -(1262, 2238, 1368) -(4335, 1076, 1575) -(800, 878, 412) -(1421, 1028, 348) -(3367, 3416, 403) -(3456, 3538, 1814) -(1345, 2226, 1285) -(2904, 3182, 179) -(3913, 510, 1719) -(2981, 4917, 181) -(2506, 2911, 901) -(587, 4079, 341) -(310, 4426, 1545) -(35, 2564, 389) -(2867, 1907, 1935) -(520, 1257, 1128) -(1645, 3948, 1446) -(4350, 4719, 1633) -(4413, 3839, 803) -(4212, 4692, 1152) -(2678, 4751, 957) -(209, 737, 1730) -(2061, 1552, 492) -(4819, 2181, 179) -(2910, 2827, 1013) -(2963, 1100, 543) -(4330, 1161, 1528) -(4315, 4421, 1993) -(774, 3244, 1764) -(4880, 819, 805) -(1457, 1006, 623) -(1735, 471, 802) -(3334, 4645, 252) -(4511, 1152, 339) -(4575, 3580, 871) -(2374, 3524, 1308) -(4954, 4603, 564) -(1942, 2749, 1808) -(1000, 2359, 1086) -(687, 3449, 1702) -(2347, 2120, 567) -(3696, 3651, 1388) -(1523, 1393, 281) -(1739, 4892, 1051) -(2278, 1568, 1570) -(4023, 436, 321) -(3228, 4578, 1877) -(3630, 2362, 1024) -(3497, 3294, 1124) -(3305, 4817, 964) -(3983, 4466, 1756) -(903, 4118, 1992) -(3102, 3419, 1157) -(1510, 1476, 1981) -(3981, 2124, 1374) -(3674, 3054, 217) -(2762, 1252, 1252) -(2031, 3234, 320) -(178, 1685, 190) -(1028, 1640, 1307) -(2603, 476, 1483) -(3659, 2883, 136) -(460, 3539, 1984) -(2164, 1742, 184) -(418, 1248, 691) -(1969, 4987, 74) -(3647, 4813, 201) -(459, 3142, 1294) -(769, 4487, 742) -(1923, 3435, 1820) -(1612, 983, 578) -(284, 3737, 1902) -(3846, 2789, 255) -(3659, 3024, 521) -(826, 1656, 507) -(4913, 2024, 718) -(1160, 376, 706) -(2362, 2177, 375) -(1105, 3783, 594) -(3335, 3596, 1178) -(3153, 3127, 282) -(2345, 4406, 1795) -(350, 4765, 1849) -(3255, 2057, 1808) -(1225, 3602, 1372) -(2647, 3765, 1277) -(833, 2953, 1998) -(1142, 957, 1654) -(1969, 3671, 1610) -(1608, 845, 852) -(2356, 2798, 51) -(197, 2654, 1156) -(939, 4209, 726) -(2874, 3841, 1845) -(3439, 4847, 234) -(2141, 4227, 1692) -(3916, 1926, 1382) -(2834, 1600, 1608) -(1476, 752, 1879) -(179, 3928, 886) -(3017, 482, 768) -(417, 2131, 1240) -(1518, 1295, 1739) -(87, 1871, 1212) -(4087, 730, 780) -(1098, 2426, 1068) -(3503, 2312, 882) -(3338, 349, 1675) -(76, 732, 410) -(1753, 2774, 1431) -(2608, 3698, 391) -(2737, 1874, 1594) -(2533, 3590, 1815) -(4061, 1465, 1567) -(175, 3288, 680) -(433, 3529, 190) -(2598, 157, 121) -(2155, 3397, 1855) -(798, 3779, 328) -(655, 1824, 1528) -(456, 2344, 771) -(4847, 745, 1272) -(4312, 2469, 1719) -(4540, 2335, 200) -(3602, 2877, 1813) -(98, 803, 1066) -(3867, 2891, 623) -(4169, 900, 902) -(2505, 2949, 1397) -(1020, 506, 1748) -(2946, 1605, 1759) -(2150, 3966, 542) -(2478, 3223, 1164) -(306, 788, 1657) -(4583, 751, 1477) -(376, 4457, 642) -(1456, 2886, 661) -(4698, 3893, 1721) -(1582, 2826, 1155) -(3188, 2307, 1099) -(1598, 4341, 604) -(406, 2372, 1820) -(730, 2167, 1486) -(3094, 1292, 788) -(3411, 593, 768) -(2814, 718, 497) -(496, 4221, 1051) -(1224, 3722, 137) -(319, 2465, 141) -(2173, 2806, 1311) -(4191, 4309, 155) -(2464, 4432, 1185) -(3272, 1838, 924) -(1911, 3247, 986) -(3471, 1618, 1261) -(1250, 2530, 1492) -(1213, 3822, 1515) -(4333, 127, 1534) -(4239, 1850, 629) -(966, 1518, 1904) -(1475, 3384, 1832) -(2836, 1335, 541) -(1425, 3915, 353) -(961, 4857, 1401) -(2203, 3630, 1972) -(2396, 2677, 714) -(884, 1599, 1515) -(822, 3461, 1334) -(4222, 502, 1029) -(2463, 300, 1718) -(4741, 57, 719) -(2154, 3156, 1318) -(510, 1157, 891) -(2372, 3338, 736) -(954, 685, 296) -(2114, 1038, 1148) -(3558, 3215, 1101) -(2064, 420, 1240) -(2529, 4531, 630) -(707, 431, 685) -(2054, 4570, 488) -(3569, 3750, 1386) -(212, 3299, 341) -(3718, 823, 732) -(3828, 3061, 101) -(1506, 2037, 695) -(3637, 2203, 240) -(3498, 4274, 169) -(2698, 4104, 1744) -(2975, 278, 1622) -(1852, 3796, 1648) -(2735, 3330, 1789) -(711, 348, 1217) -(3823, 4563, 1339) -(880, 3203, 360) -(4964, 404, 1846) -(3051, 3583, 1251) -(2836, 3467, 447) -(3213, 86, 1721) -(170, 4959, 1195) -(297, 1920, 428) -(4106, 3774, 348) -(3890, 3395, 911) -(2109, 3448, 308) -(4426, 1662, 1840) -(3152, 3140, 1515) -(982, 4944, 1371) -(2868, 3196, 511) -(4895, 699, 1691) -(2826, 4053, 1713) -(927, 4888, 1888) -(4421, 800, 567) -(4125, 2531, 177) -(706, 495, 443) -(4306, 1027, 479) -(3105, 4395, 932) -(598, 3957, 632) -(3732, 615, 1795) -(880, 2303, 406) -(810, 337, 1425) -(4360, 2188, 251) -(2947, 4343, 851) -(1257, 520, 1128) -(1356, 3884, 1070) -(291, 4532, 1262) -(111, 4895, 321) -(1483, 2838, 1250) -(2014, 758, 1472) -(3012, 3479, 1425) -(1202, 4486, 921) -(2218, 1588, 1961) -(3169, 4860, 450) -(1527, 2625, 742) -(205, 4857, 652) -(4268, 3196, 423) -(2157, 2325, 219) -(3718, 1454, 1662) -(4242, 1719, 1143) -(2170, 4623, 159) -(2706, 3533, 1188) -(233, 2947, 1325) -(3545, 4478, 245) -(2289, 457, 1968) -(33, 3686, 221) -(268, 4876, 362) -(1813, 4994, 718) -(1269, 4728, 697) -(4433, 3284, 285) -(4104, 2698, 1744) -(4739, 2034, 1914) -(2084, 4076, 1530) -(4362, 4475, 1179) -(4545, 4324, 877) -(290, 1517, 955) -(99, 58, 1240) -(554, 2887, 1888) -(3144, 228, 1296) -(2821, 223, 352) -(1673, 3712, 1256) -(2262, 874, 779) -(4084, 3556, 139) -(1168, 2724, 1212) -(3945, 2319, 980) -(4377, 1818, 1483) -(4563, 3823, 1339) -(4935, 3964, 209) -(4395, 3105, 932) -(1712, 2581, 1350) -(4083, 158, 1022) -(3495, 470, 979) -(762, 2118, 787) -(1371, 988, 228) -(78, 4488, 1254) -(3282, 289, 1100) -(3450, 1899, 1981) -(4724, 4954, 59) -(573, 4193, 885) -(2631, 524, 1455) -(1377, 4688, 1724) -(924, 1852, 1675) -(2882, 2966, 1361) -(3899, 2086, 1035) -(3427, 629, 557) -(3981, 3518, 495) -(4176, 752, 1186) -(322, 2382, 351) -(182, 2534, 418) -(4160, 149, 1907) -(823, 3718, 732) -(872, 976, 1245) -(4866, 1700, 1052) -(3737, 284, 1902) -(3687, 1908, 1632) -(3004, 3980, 1172) -(424, 2893, 132) -(4377, 401, 1530) -(2841, 1855, 1058) -(1837, 3065, 771) -(25, 1172, 192) -(598, 3913, 1727) -(941, 405, 1301) -(4137, 3933, 1907) -(4393, 1515, 265) -(3588, 3065, 1585) -(3227, 555, 1792) -(2369, 4995, 598) -(984, 4134, 1853) -(1861, 3057, 158) -(4364, 3292, 837) -(499, 1614, 834) -(4888, 2462, 1235) -(1650, 1517, 1627) -(1556, 3286, 1164) -(169, 4340, 1501) -(2965, 1275, 1921) -(253, 425, 1680) -(882, 283, 140) -(4437, 867, 1623) -(2637, 4230, 1064) -(677, 1215, 1080) -(4763, 3723, 1568) -(3222, 4072, 1016) -(1361, 4855, 1632) -(3096, 3617, 159) -(3052, 2519, 1905) -(3707, 233, 535) -(3236, 4161, 1495) -(4103, 514, 1655) -(500, 3092, 1170) -(189, 2342, 1835) -(3224, 4350, 909) -(4336, 1184, 1169) -(481, 3980, 1429) -(1774, 933, 999) -(3383, 4051, 254) -(3033, 1906, 777) -(4877, 4132, 502) -(2284, 308, 1671) -(4743, 562, 385) -(3999, 1164, 190) -(2169, 4018, 1598) -(3115, 290, 1484) -(3434, 3758, 642) -(2698, 3540, 1790) -(4523, 82, 521) -(3247, 4656, 900) -(3168, 3170, 532) -(2117, 2600, 273) -(1312, 2972, 143) -(2970, 571, 834) -(2878, 1505, 1462) -(648, 2232, 1895) -(4882, 4169, 1725) -(4894, 565, 738) -(1783, 3382, 282) -(778, 275, 1981) -(3435, 1923, 1820) -(4756, 2954, 350) -(3788, 4895, 558) -(840, 984, 1013) -(1102, 256, 664) -(3931, 3176, 1944) -(2876, 1850, 143) -(3638, 778, 407) -(1992, 1204, 73) -(3356, 4947, 1935) -(4855, 3417, 1599) -(4207, 1004, 1019) -(4575, 1981, 681) -(105, 718, 1039) -(409, 3473, 1983) -(4079, 1136, 1395) -(4423, 4844, 1133) -(3914, 2285, 486) -(2365, 704, 461) -(4745, 3647, 1421) -(588, 3749, 314) -(3003, 216, 1061) -(1133, 295, 863) -(1939, 4137, 1610) -(113, 3120, 1730) -(2200, 2821, 643) -(4521, 805, 1913) -(4307, 1908, 623) -(1757, 4165, 858) -(2637, 509, 927) -(2511, 1755, 1514) -(3302, 3314, 1983) -(36, 4358, 1382) -(617, 1716, 1750) -(4798, 3502, 160) -(1200, 4713, 1519) -(3201, 3195, 403) -(1710, 1208, 169) -(2, 458, 1505) -(4067, 551, 1458) -(372, 3941, 355) -(507, 4580, 363) -(811, 3432, 1051) -(1959, 412, 566) -(2638, 2722, 345) -(3534, 2452, 489) -(25, 707, 744) -(4064, 3516, 1225) -(1505, 546, 1414) -(3345, 3237, 1121) -(1800, 1560, 1823) -(4475, 3124, 824) -(3931, 4206, 1156) -(4324, 4040, 1849) -(1409, 3600, 1358) -(176, 1448, 1149) -(2584, 2181, 545) -(670, 872, 249) -(3505, 81, 800) -(2650, 3231, 694) -(2205, 715, 1592) -(2003, 3262, 70) -(633, 2292, 148) -(2934, 3211, 98) -(2823, 4976, 1341) -(4018, 2282, 1942) -(2445, 3971, 1723) -(894, 2253, 624) -(2189, 982, 1574) -(1865, 3387, 1360) -(460, 3611, 871) -(1601, 1014, 1167) -(2731, 1825, 581) -(200, 4468, 1652) -(4688, 1377, 1724) -(86, 2050, 543) -(3734, 2983, 633) -(902, 261, 763) -(672, 2905, 1197) -(345, 3102, 1888) -(3042, 2794, 669) -(2330, 3379, 326) -(3732, 368, 247) -(304, 1990, 1409) -(1368, 636, 185) -(1597, 2030, 1729) -(4629, 2592, 1394) -(752, 1476, 1879) -(872, 3830, 1410) -(1598, 297, 1057) -(2830, 2366, 1128) -(4454, 2623, 605) -(1934, 417, 130) -(856, 4399, 1180) -(3786, 1973, 364) -(4765, 4503, 860) -(3657, 140, 343) -(323, 4623, 1345) -(968, 2236, 179) -(1269, 4998, 1848) -(2548, 4274, 689) -(3687, 580, 995) -(3732, 4654, 1055) -(4999, 3167, 1944) -(1157, 1854, 1396) -(2235, 1463, 1506) -(736, 2528, 1176) -(1125, 3146, 1543) -(56, 3922, 1206) -(1888, 2484, 1559) -(679, 4476, 1934) -(2857, 2088, 1786) -(4753, 4990, 1816) -(721, 1800, 457) -(2093, 2662, 525) -(2867, 4962, 1969) -(1971, 1731, 1862) -(2899, 1037, 925) -(1216, 2089, 901) -(3945, 3781, 52) -(4029, 3845, 98) -(2496, 2988, 429) -(4595, 4257, 1957) -(1317, 4974, 92) -(4920, 3085, 158) -(784, 4133, 1914) -(763, 4526, 1362) -(3156, 2154, 1318) -(1327, 1172, 1935) -(709, 2210, 1964) -(3300, 3854, 749) -(2582, 3909, 1960) -(3045, 4793, 1779) -(1384, 4349, 700) -(106, 912, 208) -(1455, 3044, 1889) -(4519, 4688, 1860) -(3044, 3604, 200) -(2312, 293, 327) -(3817, 4396, 1968) -(2125, 4427, 1914) -(1815, 3140, 752) -(731, 2330, 462) -(2744, 296, 1073) -(1602, 4441, 308) -(1142, 3572, 1491) -(2264, 4678, 1492) -(705, 2939, 219) -(4257, 2574, 104) -(2453, 3880, 323) -(2418, 3591, 526) -(1465, 2146, 798) -(3743, 3174, 1413) -(2662, 228, 572) -(4795, 734, 806) -(1142, 4668, 526) -(3864, 2262, 401) -(3466, 1842, 658) -(261, 3490, 979) -(2671, 3622, 709) -(4506, 3797, 513) -(481, 3768, 1436) -(4700, 2165, 1516) -(4141, 3692, 1372) -(3147, 2649, 1914) -(2858, 4043, 391) -(4497, 220, 856) -(1302, 1796, 1740) -(4949, 4694, 254) -(884, 4706, 1892) -(2942, 3433, 1914) -(4379, 3411, 1242) -(4918, 2899, 1771) -(3257, 1746, 1634) -(3913, 3696, 1394) -(3103, 3576, 1405) -(1867, 2689, 369) -(739, 3931, 1537) -(307, 2465, 249) -(1685, 178, 190) -(500, 1567, 599) -(3961, 348, 575) -(2229, 1139, 386) -(3419, 3102, 1157) -(1257, 3277, 1458) -(4623, 226, 924) -(2391, 4723, 937) -(4452, 2405, 993) -(1412, 3090, 1606) -(2885, 108, 614) -(693, 2731, 892) -(4706, 884, 1892) -(4012, 1702, 1112) -(2574, 4716, 318) -(1391, 838, 1876) -(3193, 2283, 1836) -(3600, 661, 1403) -(1399, 2447, 1478) -(3892, 3685, 1581) -(2515, 1527, 1658) -(1011, 650, 1200) -(274, 1274, 221) -(69, 2376, 1370) -(306, 2090, 513) -(1886, 3803, 414) -(537, 1690, 830) -(3962, 1557, 356) -(3959, 4394, 343) -(24, 2887, 554) -(665, 3429, 276) -(4952, 2076, 709) -(1199, 1760, 545) -(54, 3632, 399) -(2205, 480, 409) -(2613, 2413, 131) -(4855, 3676, 606) -(4804, 4567, 1769) -(2364, 468, 719) -(1847, 3552, 1936) -(4025, 4258, 1873) -(2470, 972, 702) -(4183, 3782, 1513) -(3598, 1698, 1848) -(4958, 2155, 1013) -(1676, 4935, 499) -(1503, 3050, 419) -(1282, 4752, 1817) -(1138, 3245, 198) -(134, 999, 345) -(3168, 787, 1628) -(1349, 1520, 1445) -(4753, 507, 1597) -(4954, 4503, 340) -(3113, 3382, 1260) -(2350, 4697, 1445) -(3364, 3716, 109) -(714, 3323, 587) -(2631, 4231, 738) -(2261, 2301, 488) -(3342, 1019, 669) -(10, 1417, 1589) -(200, 4453, 417) -(4085, 3563, 440) -(4242, 1791, 667) -(1004, 2762, 182) -(2231, 1798, 1200) -(1025, 3403, 1638) -(2877, 3602, 1813) -(3552, 1847, 1936) -(1882, 3215, 384) -(2594, 4439, 1512) -(3566, 4753, 1408) -(2902, 1271, 119) -(991, 530, 171) -(4680, 1335, 894) -(1205, 3930, 871) -(270, 2969, 161) -(3219, 1969, 668) -(2561, 2223, 1720) -(4951, 2345, 1486) -(4417, 1992, 352) -(1200, 2464, 1845) -(3803, 4470, 804) -(3480, 4951, 928) -(2974, 249, 1067) -(3404, 3336, 393) -(4371, 4271, 367) -(4728, 3451, 1537) -(2765, 3008, 1939) -(4863, 2615, 1790) -(1776, 2449, 1082) -(2792, 4622, 940) -(1117, 1671, 759) -(3067, 3988, 806) -(733, 4631, 1504) -(115, 903, 1988) -(4672, 1378, 362) -(2058, 1798, 1325) -(4291, 1652, 462) -(4791, 23, 633) -(547, 2110, 321) -(2429, 3051, 1188) -(3741, 2230, 1607) -(549, 1684, 1985) -(2919, 4400, 1204) -(2134, 3485, 673) -(922, 3946, 1616) -(494, 3625, 605) -(3828, 1126, 182) -(2018, 4261, 1875) -(554, 4453, 1630) -(2502, 2842, 1369) -(3476, 441, 1748) -(3626, 3631, 1502) -(4717, 4504, 1775) -(4957, 4884, 858) -(1148, 2601, 1376) -(737, 209, 1730) -(3129, 394, 1689) -(4526, 763, 1362) -(2040, 2377, 662) -(984, 3170, 1877) -(2578, 2591, 1514) -(2340, 1602, 1855) -(4107, 1644, 277) -(3400, 4026, 1990) -(3890, 1994, 621) -(798, 4779, 1396) -(3889, 2277, 248) -(2362, 3630, 1024) -(4093, 2077, 680) -(1777, 1116, 1037) -(3741, 2889, 453) -(2613, 2103, 1736) -(3957, 930, 1643) -(3361, 313, 66) -(221, 1462, 1525) -(2775, 2947, 78) -(3086, 2181, 1488) -(614, 1719, 936) -(4848, 4443, 200) -(706, 2860, 148) -(4498, 862, 558) -(994, 4401, 1608) -(2242, 4762, 371) -(260, 4253, 1910) -(337, 3621, 446) -(4874, 389, 833) -(4807, 1405, 389) -(1671, 1743, 458) -(2992, 895, 1360) -(665, 4781, 97) -(3231, 996, 535) -(591, 571, 1671) -(3295, 2715, 1273) -(1239, 3534, 1074) -(4297, 1948, 934) -(4207, 385, 1039) -(1665, 2578, 401) -(835, 3743, 517) -(2947, 233, 1325) -(3880, 633, 355) -(3121, 2396, 1201) -(2096, 1683, 1760) -(1880, 1749, 131) -(2348, 1430, 906) -(1461, 2488, 657) -(2361, 289, 398) -(1986, 2001, 1189) -(3137, 4635, 1155) -(4684, 431, 1020) -(3475, 2451, 779) -(1687, 4866, 880) -(2078, 4739, 688) -(227, 4983, 872) -(1430, 1745, 343) -(4338, 4891, 1259) -(4358, 2880, 61) -(3415, 929, 1632) -(348, 2485, 1626) -(2942, 4299, 1243) -(4167, 1744, 1117) -(448, 3903, 296) -(2669, 2670, 1097) -(4188, 3821, 245) -(1879, 4731, 1574) -(3337, 563, 271) -(1313, 4726, 1943) -(2983, 2596, 1796) -(4299, 1681, 830) -(1116, 1681, 920) -(3390, 3296, 1928) -(2778, 1793, 1181) -(2206, 1326, 891) -(2648, 373, 303) -(61, 4522, 1494) -(2508, 1350, 1665) -(444, 4931, 1234) -(1177, 1575, 1652) -(3854, 923, 1944) -(1086, 3505, 956) -(3723, 4763, 1568) -(1853, 834, 422) -(4767, 3813, 646) -(4581, 12, 1063) -(1784, 3203, 195) -(4360, 302, 462) -(3326, 2081, 79) -(3191, 4467, 1357) -(595, 4854, 1739) -(442, 1207, 1666) -(3913, 598, 1727) -(18, 210, 1530) -(3817, 2486, 794) -(433, 564, 239) -(4583, 2044, 1212) -(2279, 4382, 774) -(4024, 3960, 1643) -(43, 1971, 1177) -(2083, 4723, 87) -(3340, 11, 957) -(3806, 1662, 1970) -(899, 2759, 309) -(3396, 1695, 1831) -(1582, 4887, 1296) -(1034, 4905, 675) -(2803, 1001, 1842) -(4918, 4183, 1315) -(1359, 1986, 1357) -(3679, 1083, 1759) -(2660, 1170, 507) -(617, 2001, 1293) -(4506, 3862, 1675) -(4624, 3037, 241) -(4849, 1048, 1421) -(2179, 4606, 423) -(423, 1783, 1880) -(3150, 3841, 1715) -(1858, 4438, 582) -(4643, 4956, 1245) -(1635, 339, 260) -(689, 3948, 923) -(2332, 4224, 1944) -(880, 121, 1463) -(3214, 3298, 965) -(1505, 2878, 1462) -(4233, 2051, 1669) -(986, 1924, 873) -(1587, 1704, 1244) -(3974, 3816, 1925) -(1969, 4316, 1629) -(868, 4837, 414) -(3704, 1638, 895) -(1776, 4995, 749) -(2993, 3147, 1686) -(2631, 4600, 1023) -(2139, 3354, 1339) -(4829, 2566, 1774) -(51, 4600, 339) -(3518, 3292, 1484) -(2340, 4311, 768) -(3715, 2647, 882) -(1041, 4813, 1179) -(4793, 3048, 1733) -(884, 4982, 688) -(104, 4462, 695) -(3217, 1512, 1522) -(102, 2963, 351) -(3291, 155, 1271) -(3551, 2857, 267) -(729, 3022, 1562) -(3093, 3907, 356) -(2940, 1719, 1992) -(4399, 4533, 287) -(3324, 4777, 108) -(1207, 1385, 1128) -(2836, 2823, 777) -(3987, 2201, 515) -(2528, 773, 110) -(2347, 315, 674) -(820, 4563, 826) -(3506, 1330, 1676) -(3981, 3006, 1820) -(29, 189, 396) -(998, 1946, 1816) -(2843, 3986, 772) -(1210, 1618, 107) -(1861, 4361, 1319) -(4605, 3708, 892) -(1628, 4860, 1670) -(1836, 1070, 118) -(4488, 2996, 1624) -(1263, 2559, 1283) -(4261, 4909, 890) -(4902, 1140, 703) -(3510, 4925, 643) -(2917, 2843, 1228) -(1271, 3116, 1314) -(3339, 1007, 576) -(1858, 3717, 1659) -(4448, 4392, 1391) -(1222, 2392, 1979) -(311, 2258, 804) -(1301, 3763, 1971) -(1390, 714, 601) -(154, 2203, 1907) -(3529, 2593, 1595) -(4532, 3256, 1979) -(3989, 4417, 1533) -(1163, 2146, 993) -(4336, 4861, 962) -(2271, 2426, 1396) -(3557, 381, 552) -(2509, 2481, 749) -(3310, 225, 1997) -(4343, 2947, 851) -(1143, 4399, 839) -(1541, 1969, 1424) -(80, 4590, 1139) -(2830, 3753, 1753) -(3490, 3259, 850) -(226, 2596, 769) -(1763, 233, 1151) -(925, 4923, 796) -(3229, 2257, 1101) -(3748, 1383, 1925) -(4529, 3051, 1684) -(1647, 1559, 235) -(1229, 2158, 345) -(2623, 1539, 1070) -(2614, 2671, 1992) -(1140, 3287, 1488) -(2800, 4929, 58) -(1717, 2345, 1732) -(2855, 4725, 1756) -(916, 3945, 1350) -(3062, 1853, 1597) -(857, 2415, 661) -(3681, 1213, 1775) -(3202, 1230, 1185) -(616, 3215, 447) -(2378, 3332, 1585) -(957, 1142, 1654) -(2344, 1436, 1426) -(4769, 4620, 517) -(99, 704, 706) -(3675, 4437, 114) -(3128, 893, 276) -(669, 2528, 102) -(557, 3701, 423) -(3995, 1808, 881) -(250, 1320, 1096) -(1803, 1921, 851) -(518, 2743, 1258) -(4003, 3389, 1402) -(3585, 1312, 736) -(1612, 1054, 1725) -(317, 1990, 1557) -(4329, 4493, 1681) -(17, 742, 1940) -(740, 4998, 1911) -(2590, 940, 535) -(3467, 744, 192) -(1167, 73, 661) -(2138, 2215, 166) -(770, 3604, 662) -(2743, 2121, 89) -(2694, 4195, 328) -(3862, 2855, 1641) -(1614, 128, 1727) -(279, 3162, 400) -(2966, 60, 1477) -(724, 4655, 657) -(2641, 1115, 427) -(2297, 1417, 1336) -(1200, 492, 78) -(2489, 3306, 1249) -(3980, 3522, 1346) -(457, 3767, 1663) -(2511, 4389, 988) -(3115, 3147, 478) -(2287, 2082, 787) -(3585, 3759, 1215) -(3155, 2640, 580) -(3412, 2215, 764) -(1250, 2230, 1999) -(277, 1034, 741) -(4484, 3075, 1067) -(4200, 4764, 772) -(1318, 3067, 887) -(1412, 3673, 1211) -(4936, 4112, 705) -(4577, 4389, 1058) -(4810, 3593, 54) -(3473, 409, 1983) -(1527, 2515, 1658) -(1320, 4169, 446) -(3838, 2944, 336) -(4069, 4587, 1234) -(2271, 4307, 1816) -(1520, 2435, 731) -(3201, 2043, 449) -(1427, 293, 1962) -(1618, 1401, 1840) -(3954, 4957, 1146) -(3912, 445, 1123) -(1486, 2580, 1297) -(2064, 1363, 1324) -(1156, 1792, 1908) -(1848, 2409, 1421) -(3530, 4040, 82) -(526, 2289, 1846) -(1722, 2318, 82) -(4716, 2574, 318) -(401, 1820, 1732) -(1896, 3937, 405) -(4717, 1551, 909) -(1423, 1322, 1645) -(2725, 915, 1757) -(651, 104, 589) -(3279, 1832, 651) -(2803, 227, 1009) -(3640, 3478, 1855) -(764, 4487, 1983) -(1771, 4877, 642) -(4520, 4357, 951) -(966, 285, 1717) -(3235, 142, 629) -(3606, 387, 593) -(3252, 4704, 460) -(692, 3700, 93) -(3392, 1071, 1981) -(2500, 2245, 1834) -(4178, 88, 1802) -(3306, 2669, 787) -(4524, 108, 573) -(3784, 981, 1625) -(4276, 1021, 1824) -(9, 498, 1657) -(936, 1177, 1736) -(3038, 2896, 1575) -(1957, 0, 1215) -(512, 996, 1082) -(3300, 895, 450) -(2247, 1693, 1707) -(573, 2757, 1934) -(3763, 1301, 1971) -(505, 1973, 1193) -(221, 4783, 259) -(42, 1483, 417) -(1318, 2892, 1572) -(110, 4126, 140) -(69, 3686, 999) -(4668, 650, 1512) -(4370, 3141, 1780) -(3358, 2734, 401) -(542, 1247, 665) -(4829, 3808, 244) -(1446, 2032, 1234) -(3309, 2140, 1717) -(3288, 4586, 1621) -(3428, 4081, 1473) -(2197, 4838, 765) -(3868, 2407, 972) -(2349, 3714, 1881) -(3048, 4793, 1733) -(2811, 2324, 1165) -(3159, 138, 489) -(761, 1471, 1077) -(4474, 1120, 1551) -(1816, 3877, 1978) -(4667, 1843, 549) -(2971, 2244, 1222) -(2293, 1553, 1192) -(2045, 2126, 929) -(879, 2611, 1909) -(4827, 9, 1315) -(4434, 4673, 558) -(1194, 589, 681) -(2951, 4451, 813) -(84, 3351, 696) -(1931, 4817, 1424) -(3866, 859, 571) -(4205, 3277, 1178) -(2249, 1332, 853) -(745, 4847, 1272) -(1605, 2854, 456) -(1114, 3541, 93) -(1881, 1030, 1059) -(1771, 3312, 1186) -(824, 4025, 507) -(1202, 4633, 1102) -(704, 3504, 998) -(579, 1596, 1112) -(2370, 2348, 1695) -(1335, 1985, 186) -(64, 3728, 1762) -(3337, 280, 232) -(31, 961, 1605) -(4563, 820, 826) -(504, 4138, 1532) -(975, 1210, 836) -(3180, 296, 457) -(326, 2803, 703) -(1635, 4207, 290) -(2829, 172, 1858) -(2999, 2480, 201) -(2212, 4038, 1534) -(673, 204, 964) -(4014, 1788, 1307) -(3502, 1709, 254) -(4996, 3278, 1970) -(3842, 3993, 1556) -(3333, 4404, 1978) -(1603, 1401, 267) -(4707, 4807, 698) -(4763, 2472, 70) -(2545, 870, 987) -(2905, 2115, 787) -(939, 1631, 1805) -(4576, 4419, 1350) -(4348, 4094, 827) -(2360, 1177, 179) -(2150, 2057, 382) -(1507, 2257, 1440) -(2296, 370, 513) -(3749, 805, 943) -(3422, 1763, 1041) -(486, 1568, 1964) -(3415, 3473, 1806) -(1749, 4514, 535) -(2460, 2787, 779) -(192, 3985, 264) -(1258, 3928, 1307) -(1433, 1216, 1028) -(3838, 4967, 1118) -(2993, 528, 1432) -(3969, 376, 258) -(2081, 971, 594) -(4455, 2815, 192) -(320, 2721, 329) -(4393, 3066, 1969) -(2723, 274, 1780) -(2875, 161, 887) -(358, 4801, 485) -(4237, 1999, 1490) -(319, 1402, 1138) -(134, 734, 499) -(1274, 274, 221) -(4336, 918, 640) -(1210, 2821, 1811) -(4462, 4026, 339) -(4841, 959, 244) -(1272, 1078, 109) -(717, 639, 273) -(685, 1845, 322) -(3055, 3593, 60) -(2646, 931, 165) -(2351, 3889, 848) -(4191, 1548, 1119) -(4009, 1915, 1565) -(2180, 499, 1802) -(4427, 446, 1618) -(1242, 4090, 537) -(3554, 4251, 329) -(2684, 2345, 1210) -(865, 593, 92) -(4153, 163, 420) -(4655, 4679, 1525) -(1354, 3035, 728) -(1621, 2532, 1627) -(591, 4292, 505) -(3545, 4392, 190) -(4989, 275, 226) -(478, 4871, 752) -(1546, 777, 1488) -(4696, 244, 1096) -(655, 4886, 468) -(2097, 3616, 672) -(3103, 3048, 1988) -(4830, 131, 846) -(2680, 2117, 53) -(26, 3075, 1054) -(486, 1470, 672) -(1054, 3371, 1783) -(4660, 3526, 1871) -(575, 2307, 1527) -(1168, 590, 385) -(687, 238, 280) -(2771, 4769, 502) -(2859, 1035, 1451) -(4387, 2990, 1749) -(3846, 2835, 1252) -(599, 1364, 797) -(594, 2294, 1571) -(3227, 398, 262) -(1906, 2598, 1255) -(625, 2183, 877) -(1269, 3702, 307) -(2177, 4461, 301) -(4203, 258, 240) -(3743, 3525, 870) -(712, 2933, 1396) -(2146, 4097, 1980) -(2876, 1217, 1502) -(2323, 1848, 1572) -(1474, 4095, 717) -(3294, 3402, 447) -(1941, 1034, 714) -(76, 944, 726) -(752, 4176, 1186) -(1558, 295, 1797) -(4846, 1015, 1139) -(4488, 3514, 1446) -(4666, 345, 1013) -(4821, 4755, 494) -(589, 4182, 897) -(2874, 2741, 1085) -(3501, 1487, 1812) -(4789, 1910, 1840) -(2208, 4145, 858) -(2495, 1711, 479) -(948, 4416, 567) -(2531, 2896, 84) -(2564, 3980, 1412) -(1743, 4155, 400) -(2300, 2061, 1031) -(3723, 943, 293) -(2111, 1233, 223) -(1489, 561, 1811) -(3198, 3373, 1473) -(556, 392, 1634) -(630, 1593, 606) -(3223, 1257, 1120) -(1503, 4680, 799) -(4551, 3898, 1484) -(1260, 672, 1202) -(4399, 4163, 1667) -(1391, 1598, 1241) -(1653, 407, 1636) -(60, 2966, 1477) -(2760, 4127, 407) -(498, 2151, 1441) -(271, 1291, 170) -(3333, 4948, 867) -(3086, 1760, 1197) -(1054, 6, 54) -(1705, 326, 1034) -(2349, 4004, 1206) -(4244, 2789, 1026) -(3249, 1106, 1842) -(4736, 2304, 356) -(776, 1282, 80) -(550, 2973, 1340) -(1301, 3993, 515) -(2916, 2085, 1331) -(3476, 1823, 684) -(1196, 4998, 545) -(4934, 4446, 375) -(3663, 2475, 704) -(1452, 275, 515) -(4627, 2134, 1119) -(1241, 4755, 974) -(1681, 1503, 2000) -(1662, 728, 1178) -(1076, 4335, 1575) -(4852, 2907, 1907) -(3033, 2282, 1811) -(4522, 1768, 1968) -(1741, 504, 1487) -(2782, 4873, 1270) -(1012, 4600, 293) -(1689, 113, 927) -(3420, 1103, 442) -(3460, 2828, 433) -(3595, 693, 1960) -(2849, 4138, 823) -(2567, 4240, 1461) -(1076, 4655, 1996) -(3643, 2569, 1836) -(1276, 1931, 1708) -(271, 2767, 815) -(1927, 2338, 816) -(4131, 901, 887) -(1218, 1296, 291) -(1610, 574, 576) -(1775, 344, 1131) -(1591, 2897, 757) -(182, 271, 78) -(4860, 1628, 1670) -(2881, 1390, 440) -(3197, 3232, 1001) -(1987, 168, 1219) -(399, 2219, 1959) -(4632, 1352, 189) -(1095, 1439, 305) -(4321, 3996, 341) -(3774, 400, 1954) -(3816, 1286, 1284) -(1326, 4585, 1313) -(1790, 4914, 1967) -(3206, 1868, 416) -(2734, 4284, 356) -(1678, 4576, 1240) -(2163, 2802, 1053) -(2322, 4492, 701) -(294, 3783, 367) -(2006, 2020, 1839) -(4152, 1734, 1181) -(4282, 3453, 581) -(4797, 170, 1599) -(2345, 2320, 1444) -(1276, 3784, 1008) -(2793, 2192, 807) -(4508, 667, 300) -(4579, 4762, 1182) -(4910, 4930, 1644) -(2853, 3362, 1436) -(2291, 4683, 181) -(3502, 4829, 386) -(4883, 2197, 1777) -(4847, 2764, 393) -(4461, 2177, 301) -(3646, 2273, 1076) -(2683, 2721, 1963) -(3010, 2483, 1215) -(3807, 3696, 1738) -(42, 1837, 681) -(2052, 3068, 902) -(977, 766, 1954) -(3752, 1813, 882) -(3229, 4288, 805) -(308, 414, 1141) -(2184, 4254, 1781) -(2639, 3373, 635) -(4685, 3762, 1127) -(1106, 4589, 1427) -(370, 2889, 863) -(2226, 4178, 407) -(3288, 3712, 1022) -(3416, 629, 665) -(3469, 2005, 652) -(859, 4182, 1325) -(1756, 606, 80) -(1465, 3178, 1837) -(4301, 4791, 1689) -(2523, 2721, 1842) -(4494, 2832, 766) -(4972, 1796, 1484) -(1002, 1258, 762) -(2257, 3716, 1879) -(2887, 4888, 852) -(3799, 2510, 246) -(2414, 3400, 1577) -(4596, 3914, 1823) -(4886, 1897, 1923) -(4588, 3236, 1846) -(652, 3845, 1886) -(946, 2453, 1053) -(1628, 4664, 1397) -(3589, 3385, 119) -(4773, 3261, 1835) -(1013, 2867, 1359) -(629, 494, 552) -(4191, 4107, 66) -(2375, 4801, 1418) -(1819, 3508, 1917) -(177, 2441, 413) -(3521, 4524, 1631) -(404, 3194, 1984) -(3112, 4964, 585) -(2604, 984, 273) -(2788, 1805, 596) -(1221, 1334, 1299) -(2852, 4183, 869) -(3454, 1642, 1861) -(331, 756, 495) -(3518, 3180, 574) -(1731, 2365, 439) -(4495, 548, 687) -(1593, 2024, 1330) -(2410, 3555, 1721) -(4581, 4637, 1493) -(3507, 435, 529) -(1327, 3355, 163) -(1554, 1753, 955) -(2757, 1131, 1045) -(4654, 4691, 1428) -(2877, 3465, 1833) -(3334, 3521, 1059) -(3462, 3722, 1687) -(3734, 495, 872) -(489, 2473, 1162) -(245, 2083, 1747) -(2630, 2627, 593) -(2553, 4061, 397) -(934, 3458, 1457) -(3476, 4723, 1910) -(3216, 3284, 674) -(1948, 3725, 786) -(4054, 3420, 1940) -(2487, 4487, 103) -(2795, 1133, 1182) -(1015, 1956, 555) -(4813, 655, 1362) -(299, 3108, 1445) -(4585, 3316, 1199) -(916, 1973, 169) -(3980, 2042, 494) -(1062, 4319, 1585) -(1820, 2179, 858) -(417, 3794, 583) -(3119, 4107, 1414) -(4976, 1435, 655) -(4027, 561, 1031) -(1098, 251, 1936) -(3618, 703, 1929) -(1129, 3987, 1840) -(2397, 1338, 1999) -(2839, 1351, 460) -(2925, 185, 552) -(1088, 2241, 1681) -(2257, 1507, 1440) -(1895, 1338, 478) -(960, 4691, 1315) -(225, 3310, 1997) -(1784, 579, 1270) -(770, 1697, 1918) -(4704, 1195, 1208) -(3270, 724, 1960) -(3939, 4914, 1485) -(952, 3480, 1354) -(2883, 764, 840) -(4262, 2136, 359) -(1546, 4129, 1286) -(3516, 4064, 1225) -(1266, 2943, 341) -(3107, 4433, 415) -(3679, 3072, 1176) -(3714, 1420, 1975) -(334, 3115, 1093) -(3479, 836, 716) -(4863, 1160, 538) -(3480, 4146, 1205) -(1231, 3205, 788) -(3627, 2, 1326) -(1774, 1011, 476) -(3369, 1887, 1486) -(891, 466, 1017) -(2787, 3805, 295) -(4983, 227, 872) -(2747, 1199, 1863) -(920, 2776, 905) -(309, 3217, 1832) -(4087, 4716, 1889) -(45, 1717, 1528) -(1957, 3966, 1992) -(3755, 2090, 817) -(4519, 917, 1252) -(623, 120, 1880) -(2095, 3319, 1310) -(2254, 1605, 260) -(2060, 3762, 1924) -(4125, 318, 142) -(4643, 281, 1830) -(1192, 4096, 1653) -(3898, 770, 1514) -(1853, 3062, 1597) -(2795, 1751, 215) -(3031, 3919, 1691) -(1480, 2087, 1172) -(3857, 2199, 756) -(3323, 3124, 1961) -(1292, 1142, 1112) -(4796, 548, 1314) -(3204, 3878, 579) -(135, 3713, 135) -(1847, 2140, 116) -(843, 770, 386) -(4039, 977, 232) -(4896, 2556, 1676) -(3140, 3152, 1515) -(3924, 3774, 1602) -(3356, 2611, 1382) -(2548, 4555, 1082) -(610, 2648, 1469) -(3306, 4471, 1488) -(3310, 2342, 1491) -(2925, 3968, 698) -(1325, 3083, 231) -(2525, 2172, 1483) -(700, 2884, 551) -(3813, 2314, 463) -(2007, 447, 1182) -(4048, 1060, 180) -(4107, 4191, 66) -(4692, 2175, 765) -(659, 1585, 695) -(1209, 486, 1963) -(4259, 3147, 1431) -(4425, 3422, 436) -(4369, 273, 1591) -(2167, 2516, 1314) -(4182, 859, 1325) -(2808, 35, 530) -(3966, 4042, 1421) -(2954, 859, 676) -(494, 640, 1818) -(2091, 2096, 502) -(1643, 1237, 791) -(2083, 4027, 1334) -(1088, 1546, 1181) -(4176, 2906, 591) -(764, 2482, 1799) -(2717, 2332, 163) -(1085, 1480, 1260) -(405, 1590, 761) -(1158, 2204, 1748) -(2544, 1906, 1622) -(930, 3595, 1714) -(3705, 2889, 1808) -(3737, 3693, 1535) -(8, 4883, 62) -(207, 4685, 627) -(4477, 129, 1708) -(1381, 3094, 1625) -(4969, 3224, 1446) -(4711, 956, 1684) -(4392, 3545, 190) -(252, 4027, 596) -(1316, 3719, 1876) -(2038, 2250, 901) -(2911, 2506, 901) -(3236, 4902, 1133) -(2159, 98, 870) -(1008, 286, 818) -(4899, 2975, 1129) -(2419, 785, 1960) -(3806, 1320, 939) -(1360, 4914, 1715) -(3173, 3769, 1264) -(142, 3201, 155) -(1185, 2428, 1925) -(3346, 3026, 449) -(3223, 1964, 98) -(3736, 3190, 876) -(2442, 3306, 1730) -(3561, 2739, 1708) -(789, 1650, 373) -(1732, 3230, 926) -(3417, 695, 1166) -(3501, 2166, 1064) -(79, 86, 1363) -(3469, 3864, 1586) -(453, 4901, 109) -(525, 408, 891) -(1117, 478, 1444) -(3348, 3743, 849) -(2997, 2871, 1968) -(3914, 3308, 504) -(1599, 570, 1369) -(975, 1509, 804) -(2749, 1942, 1808) -(480, 2153, 1292) -(268, 468, 1523) -(2441, 177, 413) -(93, 1185, 1759) -(4883, 1143, 1449) -(860, 1775, 572) -(303, 1423, 78) -(2973, 4955, 1699) -(1486, 4251, 209) -(4204, 3055, 1381) -(1244, 4396, 414) -(3215, 1794, 1873) -(2737, 1991, 1374) -(1446, 4107, 184) -(2363, 4281, 770) -(1809, 1767, 742) -(3817, 1724, 1766) -(3103, 1837, 1972) -(1655, 608, 1848) -(1385, 2436, 910) -(3480, 1929, 1396) -(4287, 3700, 86) -(638, 831, 330) -(1837, 3263, 141) -(4333, 970, 1197) -(2880, 4464, 987) -(1139, 2229, 386) -(1990, 317, 1557) -(4997, 649, 872) -(175, 822, 553) -(1995, 1598, 1175) -(4485, 421, 756) -(959, 4841, 244) -(3985, 192, 264) -(364, 3769, 352) -(2449, 3656, 817) -(1287, 935, 587) -(4719, 4484, 931) -(1878, 1467, 959) -(41, 4427, 1217) -(800, 3109, 156) -(1438, 3237, 397) -(2539, 1589, 703) -(1308, 2605, 1504) -(564, 3833, 732) -(1095, 4118, 1008) -(2757, 2391, 741) -(3620, 2277, 198) -(4530, 1761, 1889) -(1697, 4121, 797) -(3778, 2619, 1723) -(2521, 2795, 1761) -(3857, 4252, 470) -(2192, 2793, 807) -(4371, 2311, 1378) -(2593, 3131, 1876) -(188, 3689, 310) -(4040, 3530, 82) -(792, 100, 621) -(361, 4746, 1585) -(2347, 791, 102) -(3635, 3266, 1939) -(4016, 4160, 1650) -(4195, 4060, 1421) -(2324, 2811, 1165) -(2825, 4772, 1527) -(821, 2251, 735) -(3990, 3100, 465) -(4692, 836, 1352) -(1779, 4093, 585) -(1506, 2663, 1836) -(760, 1331, 690) -(4578, 3228, 1877) -(1239, 241, 1128) -(4285, 1205, 658) -(3424, 3122, 1194) -(4688, 2903, 318) -(1953, 4911, 1249) -(1359, 1532, 1650) -(4585, 3773, 354) -(3089, 3960, 1500) -(1595, 961, 1856) -(3271, 2704, 1893) -(4824, 4047, 774) -(4513, 1308, 876) -(2680, 3062, 484) -(2433, 4480, 1285) -(4212, 3652, 1724) -(1407, 3520, 1895) -(113, 1936, 1684) -(2374, 782, 404) -(3531, 2119, 1580) -(470, 473, 601) -(1467, 1659, 962) -(538, 3969, 771) -(1304, 3438, 552) -(3617, 2266, 189) -(2821, 2801, 176) -(4857, 1774, 1724) -(3620, 4872, 1959) -(1921, 1614, 1786) -(4799, 3087, 342) -(3999, 4337, 828) -(15, 1995, 626) -(3135, 1078, 514) -(3596, 516, 977) -(3669, 970, 775) -(997, 4960, 1636) -(3933, 4137, 1907) -(2027, 2968, 1504) -(2802, 2163, 1053) -(1233, 3982, 830) -(3028, 366, 1050) -(4888, 3102, 1611) -(1462, 221, 1525) -(3607, 1242, 1955) -(2782, 1973, 1409) -(2474, 2632, 1456) -(1861, 3345, 567) -(1360, 227, 723) -(1615, 1513, 290) -(314, 266, 1256) -(3249, 449, 1475) -(4596, 3197, 1783) -(3100, 4002, 1102) -(2406, 409, 70) -(2516, 1705, 1293) -(216, 4350, 1209) -(2024, 4913, 718) -(3462, 588, 1047) -(1132, 3543, 1754) -(628, 4064, 1562) -(2776, 4021, 375) -(1451, 1412, 413) -(3702, 4629, 1935) -(3348, 4656, 1631) -(2026, 1871, 337) -(2823, 2734, 1858) -(3267, 1169, 755) -(3812, 3731, 763) -(1760, 1199, 545) -(4450, 1525, 292) -(3318, 2262, 623) -(761, 4972, 217) -(2185, 1776, 1385) -(4271, 2959, 1995) -(405, 941, 1301) -(4501, 1206, 1532) -(4310, 3177, 1828) -(2425, 1038, 1092) -(2923, 2719, 200) -(3274, 695, 774) -(1083, 3679, 1759) -(3775, 3402, 1411) -(2026, 4457, 1125) -(741, 4355, 174) -(3920, 2737, 1288) -(3199, 4869, 111) -(4772, 2825, 1527) -(4301, 1525, 1436) -(4471, 3306, 1488) -(418, 3967, 341) -(2019, 3767, 1118) -(1501, 3029, 1922) -(3155, 4665, 1939) -(565, 1769, 829) -(4747, 417, 763) -(1930, 1979, 1433) -(2126, 4812, 1989) -(3289, 3375, 255) -(3104, 2741, 328) -(2895, 3918, 1747) -(1891, 3569, 239) -(24, 1205, 1142) -(4984, 1163, 694) -(49, 370, 1450) -(4456, 4323, 686) -(3684, 3292, 1749) -(1199, 4791, 774) -(4707, 4127, 318) -(4913, 10, 1091) -(1202, 2469, 1551) -(1655, 2269, 1109) -(188, 1935, 1059) -(509, 3968, 1338) -(2966, 4430, 92) -(3449, 4858, 1619) -(2540, 2258, 1382) -(4432, 2464, 1185) -(4696, 1599, 746) -(630, 4027, 1457) -(705, 3232, 353) -(4892, 1336, 309) -(658, 4828, 1079) -(1492, 186, 1924) -(2616, 1821, 223) -(2586, 2723, 856) -(4338, 738, 1475) -(4605, 3615, 594) -(225, 2409, 1121) -(379, 4858, 1340) -(943, 4522, 157) -(2590, 3913, 440) -(783, 4445, 1240) -(2781, 3886, 1026) -(2573, 2, 351) -(2477, 4149, 1377) -(2214, 37, 918) -(3395, 1596, 68) -(3487, 3174, 762) -(1528, 253, 1667) -(676, 3475, 1974) -(2041, 2852, 1023) -(4816, 4630, 389) -(839, 3707, 825) -(104, 651, 589) -(300, 2854, 1153) -(1391, 1674, 1708) -(1752, 3576, 425) -(866, 3075, 777) -(4580, 507, 363) -(4432, 1064, 146) -(2787, 2460, 779) -(863, 3574, 537) -(3717, 1858, 1659) -(3354, 2956, 644) -(3494, 453, 1818) -(3493, 3742, 567) -(446, 248, 1826) -(968, 163, 1605) -(774, 4970, 1885) -(4844, 2977, 768) -(861, 1576, 1033) -(2310, 4038, 1388) -(2916, 421, 738) -(162, 4638, 931) -(2501, 2061, 1364) -(498, 2873, 663) -(2358, 2002, 961) -(194, 2755, 1828) -(778, 3828, 332) -(1717, 4208, 699) -(767, 1404, 456) -(309, 102, 1564) -(1954, 4176, 351) -(3849, 1527, 365) -(1444, 4225, 1506) -(4108, 918, 1158) -(4132, 4877, 502) -(696, 2120, 1014) -(1855, 1270, 1378) -(1058, 3871, 207) -(4076, 4061, 1396) -(2328, 1424, 221) -(3731, 3812, 763) -(4553, 4681, 438) -(185, 2925, 552) -(313, 1952, 337) -(4816, 4544, 1251) -(2462, 318, 579) -(3262, 461, 177) -(4692, 2547, 1363) -(1760, 4068, 1433) -(2942, 3443, 111) -(4634, 1261, 814) -(1698, 4622, 1842) -(4969, 1478, 292) -(4224, 4226, 1833) -(447, 4801, 1090) -(1656, 3677, 1404) -(2692, 3123, 720) -(3721, 2671, 431) -(712, 3873, 1075) -(2563, 97, 1416) -(3420, 4054, 1940) -(0, 945, 1296) -(1033, 285, 1367) -(2864, 3616, 309) -(870, 1512, 1869) -(3861, 3241, 1825) -(1320, 3462, 803) -(3816, 3974, 1925) -(778, 3218, 381) -(3626, 2172, 852) -(2011, 2326, 614) -(307, 136, 1283) -(1152, 2833, 1595) -(1546, 69, 1305) -(1129, 1600, 187) -(3905, 4652, 1327) -(4236, 443, 102) -(1272, 3484, 1462) -(4414, 2179, 405) -(3431, 2715, 520) -(1624, 796, 1966) -(2353, 190, 1675) -(2384, 1563, 1005) -(1024, 871, 400) -(3701, 557, 423) -(1544, 1662, 1496) -(4609, 4424, 1564) -(4389, 2511, 988) -(1396, 1129, 1230) -(1686, 693, 179) -(44, 2865, 1557) -(2967, 4045, 982) -(159, 4480, 1064) -(1236, 1198, 538) -(4856, 2377, 1776) -(2725, 3006, 942) -(2949, 1427, 307) -(3292, 3518, 1484) -(1701, 3280, 834) -(1125, 2798, 1922) -(3047, 3308, 1429) -(222, 55, 322) -(3686, 33, 221) -(1894, 3451, 209) -(221, 1703, 1841) -(4136, 29, 489) -(4608, 4415, 822) -(517, 3041, 1017) -(2403, 2348, 443) -(2861, 1556, 98) -(2387, 3233, 1822) -(4747, 2003, 1013) -(1735, 2050, 125) -(2732, 3929, 596) -(4906, 3704, 1909) -(575, 582, 1278) -(4615, 3069, 1713) -(3918, 1744, 165) -(4026, 3400, 1990) -(104, 3873, 494) -(466, 4024, 1017) -(4633, 2840, 891) -(2414, 242, 970) -(1112, 4485, 350) -(890, 4636, 1626) -(318, 4125, 142) -(60, 3784, 230) -(865, 306, 811) -(2770, 3695, 1854) -(2017, 755, 494) -(3467, 2836, 447) -(3389, 4003, 1402) -(686, 2790, 1380) -(699, 4895, 1691) -(4847, 3439, 234) -(3150, 1725, 1160) -(4844, 2526, 124) -(4914, 374, 1809) -(4499, 4627, 1918) -(0, 740, 582) -(4087, 4572, 996) -(2432, 996, 1148) -(522, 4239, 90) -(4566, 4484, 1034) -(452, 92, 1151) -(2835, 3846, 1252) -(1843, 2371, 194) -(4602, 3217, 1307) -(4107, 3119, 1414) -(61, 3602, 422) -(1659, 2210, 1772) -(2046, 562, 869) -(2907, 3760, 1367) -(1845, 685, 322) -(2086, 2339, 138) -(2466, 1565, 814) -(4595, 4018, 1739) -(1035, 2859, 1451) -(3528, 3575, 1220) -(4658, 1986, 1678) -(1092, 2184, 1456) -(4186, 963, 1411) -(2032, 3515, 1527) -(4779, 2486, 1848) -(1575, 1177, 1652) -(4907, 1633, 1319) -(132, 4409, 1043) -(175, 3121, 1771) -(93, 4084, 160) -(4378, 2425, 306) -(856, 329, 1618) -(1460, 1239, 1475) -(1476, 1510, 1981) -(3893, 4635, 675) -(3398, 4555, 1689) -(2896, 872, 159) -(174, 4984, 1355) -(1403, 903, 1218) -(739, 1170, 1850) -(342, 4786, 994) -(2586, 4299, 259) -(3886, 3744, 1041) -(2838, 2374, 1965) -(565, 614, 1922) -(2353, 3814, 658) -(3046, 3724, 1034) -(3151, 1797, 1949) -(565, 1330, 1401) -(3451, 1795, 276) -(4103, 834, 1148) -(3490, 4284, 1717) -(1414, 659, 620) -(2934, 4659, 271) -(729, 4464, 1883) -(4985, 2635, 647) -(1071, 1656, 611) -(2793, 2964, 1942) -(2443, 702, 207) -(1061, 3014, 763) -(3689, 4678, 1945) -(2378, 2285, 229) -(3608, 2448, 1825) -(1897, 4886, 1923) -(1464, 1220, 1932) -(3399, 3652, 152) -(4713, 157, 1741) -(4026, 2174, 353) -(3048, 1213, 869) -(4039, 831, 838) -(2182, 781, 1664) -(3909, 2582, 1960) -(3386, 1037, 340) -(997, 3716, 556) -(2285, 3914, 486) -(3207, 1129, 853) -(2564, 253, 322) -(3930, 1614, 1241) -(1665, 2849, 830) -(3049, 3041, 1323) -(2684, 4716, 1848) -(3923, 2303, 1961) -(4159, 2212, 1371) -(3564, 1305, 1490) -(4217, 2835, 502) -(3362, 252, 1203) -(4654, 2797, 1958) -(3991, 425, 1843) -(2978, 983, 1713) -(1024, 4738, 894) -(1030, 3769, 1054) -(646, 4690, 1658) -(4649, 3486, 673) -(2738, 721, 794) -(3308, 3914, 504) -(2107, 3189, 1361) -(4805, 3543, 1947) -(1285, 455, 1553) -(1531, 2779, 483) -(2861, 2308, 218) -(2035, 3058, 1323) -(3737, 3243, 779) -(353, 1710, 1748) -(2887, 2074, 1485) -(2432, 3782, 1366) -(3913, 2306, 1001) -(2089, 949, 1022) -(678, 1471, 135) -(2503, 4153, 920) -(3713, 1362, 1291) -(1062, 1779, 1070) -(392, 72, 1833) -(3685, 3290, 1000) -(1409, 2857, 1500) -(268, 1003, 192) -(2289, 1018, 1214) -(1757, 2297, 303) -(4104, 219, 1285) -(3440, 4696, 720) -(1181, 3909, 1651) -(736, 1431, 773) -(1697, 770, 1918) -(1325, 577, 617) -(2499, 4456, 647) -(2304, 4736, 356) -(3927, 4426, 710) -(1133, 4004, 313) -(4645, 4923, 98) -(659, 123, 1767) -(1268, 3305, 249) -(785, 2419, 1960) -(2384, 3221, 1382) -(2640, 4399, 1196) -(36, 706, 751) -(1461, 2662, 1028) -(2878, 4388, 169) -(1463, 43, 1837) -(4835, 475, 1518) -(1356, 40, 217) -(622, 1691, 1581) -(97, 2197, 200) -(3928, 179, 886) -(4533, 4399, 287) -(1210, 3517, 1733) -(3923, 1949, 1932) -(2782, 4651, 425) -(1752, 3658, 1130) -(582, 1451, 54) -(2828, 3460, 433) -(1395, 1443, 117) -(4108, 4080, 492) -(664, 4033, 514) -(4968, 4091, 215) -(39, 2086, 353) -(1096, 1988, 989) -(2353, 2152, 1761) -(4444, 2628, 1193) -(2030, 2975, 1798) -(3775, 4280, 112) -(977, 4039, 232) -(4657, 1917, 773) -(4270, 3582, 1711) -(4402, 356, 1229) -(3007, 2042, 725) -(1022, 3267, 1144) -(4978, 1991, 519) -(2407, 3868, 972) -(558, 3064, 231) -(4289, 4835, 1246) -(3934, 2527, 517) -(3695, 4242, 428) -(4173, 1939, 1252) -(521, 2962, 351) -(1998, 3391, 1779) -(1536, 3075, 1964) -(2235, 1577, 636) -(1916, 2777, 1917) -(437, 3117, 1298) -(51, 4510, 1978) -(2101, 2356, 748) -(2620, 3844, 1620) -(1965, 4290, 863) -(2712, 2471, 1461) -(2365, 1505, 1451) -(4167, 2241, 772) -(4131, 3572, 1174) -(4509, 534, 1386) -(1271, 963, 1282) -(774, 1079, 746) -(4632, 1559, 806) -(2911, 787, 1467) -(1481, 2987, 599) -(4838, 4951, 202) -(984, 747, 1408) -(1262, 642, 1321) -(2161, 814, 1609) -(3201, 3585, 1437) -(3232, 705, 353) -(1006, 1980, 1356) -(1680, 4904, 904) -(4771, 76, 431) -(4770, 3647, 141) -(1855, 2905, 163) -(4098, 4738, 1651) -(1986, 4853, 194) -(2610, 4388, 666) -(371, 4728, 1648) -(302, 3964, 503) -(4760, 304, 1956) -(435, 3817, 1009) -(4136, 4253, 826) -(4, 1845, 466) -(4259, 3303, 1173) -(2749, 4294, 609) -(737, 185, 1397) -(1298, 2700, 84) -(2706, 4055, 519) -(778, 3144, 1341) -(2757, 4388, 101) -(4529, 2963, 1793) -(719, 2711, 1078) -(4965, 1611, 511) -(3017, 719, 1978) -(1562, 3927, 1052) -(3201, 996, 1653) -(622, 2374, 1671) -(2067, 2616, 595) -(4296, 2046, 1289) -(4878, 4161, 1075) -(266, 53, 765) -(3771, 4478, 734) -(1599, 884, 1515) -(1604, 546, 1320) -(1308, 3175, 1167) -(4308, 3505, 1522) -(4823, 2514, 1459) -(2587, 3133, 1947) -(3226, 3608, 201) -(2808, 4467, 388) -(1848, 1384, 622) -(2024, 4333, 1072) -(1705, 4237, 331) -(4156, 1277, 926) -(1515, 4393, 265) -(189, 2442, 602) -(2764, 4847, 393) -(1554, 1178, 1778) -(4464, 729, 1883) -(1704, 1587, 1244) -(4891, 2955, 1401) -(4461, 3838, 1001) -(2819, 263, 1545) -(2688, 2307, 526) -(695, 376, 377) -(3364, 4638, 1665) -(4240, 2567, 1461) -(1976, 4916, 135) -(3408, 4774, 124) -(2188, 2876, 1811) -(1909, 3738, 875) -(3038, 3776, 120) -(4656, 3263, 1596) -(57, 4741, 719) -(2971, 4761, 1042) -(3364, 3505, 758) -(610, 1463, 1988) -(3464, 47, 1692) -(806, 3318, 516) -(827, 4610, 660) -(2607, 2417, 1385) -(1262, 3767, 561) -(2230, 3380, 1859) -(3805, 4155, 1057) -(204, 2863, 311) -(2884, 2857, 274) -(296, 3746, 716) -(685, 1208, 1377) -(276, 1016, 1990) -(1753, 1016, 1754) -(3225, 2931, 1022) -(396, 3993, 415) -(1488, 4695, 731) -(1558, 1136, 1923) -(1859, 4712, 597) -(3821, 4913, 1298) -(4945, 1592, 96) -(949, 415, 322) -(933, 570, 390) -(465, 4505, 837) -(2788, 789, 746) -(1117, 4313, 563) -(534, 1262, 569) -(1201, 526, 288) -(285, 3940, 1992) -(1635, 3749, 1414) -(2881, 4738, 1823) -(1074, 3207, 305) -(3294, 3967, 1349) -(2755, 4217, 620) -(1191, 943, 1734) -(1938, 2969, 1428) -(1068, 114, 1297) -(1485, 334, 1340) -(4254, 3145, 1598) -(2285, 4453, 1176) -(4699, 1638, 417) -(2734, 1798, 1655) -(1335, 2836, 541) -(2320, 2345, 1444) -(4244, 999, 1336) -(1573, 3835, 948) -(244, 4293, 1352) -(1381, 2682, 1929) -(1239, 3929, 470) -(4663, 2968, 1947) -(3975, 4038, 1318) -(4125, 159, 1019) -(4391, 2805, 1343) -(1239, 784, 1238) -(2266, 3617, 189) -(4889, 3487, 907) -(2243, 3562, 986) -(421, 2916, 738) -(3560, 1375, 577) -(1735, 2212, 1012) -(4123, 2279, 1569) -(829, 460, 454) -(2182, 3346, 858) -(4948, 3430, 666) -(1476, 1845, 1616) -(3704, 4906, 1909) -(687, 2606, 1453) -(2393, 3190, 1701) -(2323, 651, 445) -(564, 2267, 345) -(4396, 520, 214) -(4486, 1202, 921) -(1244, 4497, 436) -(4428, 4526, 1027) -(923, 56, 693) -(564, 433, 239) -(4146, 3042, 1561) -(3602, 1190, 400) -(3544, 3170, 1104) -(3587, 1542, 277) -(2846, 228, 1367) -(1937, 315, 507) -(2443, 1715, 1145) -(3208, 1433, 400) -(726, 3042, 927) -(4042, 3140, 1336) -(3110, 4381, 1884) -(3622, 1084, 831) -(2507, 3100, 303) -(3771, 38, 1022) -(1848, 1881, 728) -(2882, 1615, 851) -(1404, 4164, 303) -(1443, 1395, 117) -(4602, 2954, 150) -(3049, 3250, 1846) -(4234, 1696, 832) -(4147, 3265, 806) -(3369, 4390, 373) -(1518, 282, 1273) -(2076, 4952, 709) -(3884, 2428, 110) -(1921, 4428, 1119) -(4811, 2814, 446) -(3625, 4733, 1268) -(4019, 1169, 1939) -(2899, 888, 638) -(4078, 684, 1150) -(3265, 4147, 806) -(2785, 2196, 1328) -(857, 3284, 783) -(3444, 2824, 942) -(3993, 3842, 1556) -(3908, 217, 1852) -(4941, 2708, 1975) -(2195, 897, 550) -(508, 1413, 251) -(3029, 794, 319) -(880, 1602, 1055) -(4977, 924, 1700) -(3170, 880, 459) -(4129, 536, 1058) -(3478, 3281, 437) -(1627, 2213, 1528) -(4256, 4493, 1598) -(430, 1542, 422) -(1021, 3695, 1570) -(562, 4743, 385) -(1348, 4922, 1802) -(1713, 2700, 100) -(4696, 2476, 1590) -(4270, 2435, 832) -(3365, 609, 286) -(2356, 2575, 1798) -(562, 2046, 869) -(1550, 4840, 777) -(1343, 4138, 1989) -(2319, 2255, 947) -(3616, 545, 909) -(660, 3792, 1012) -(2914, 349, 150) -(3046, 3602, 1881) -(3602, 524, 1949) -(4492, 2322, 701) -(1936, 1700, 464) -(4692, 4212, 1152) -(396, 3449, 1480) -(2099, 251, 1039) -(3726, 4461, 603) -(4350, 216, 1209) -(4779, 320, 530) -(823, 794, 457) -(4216, 1644, 143) -(3290, 2631, 470) -(660, 1554, 1687) -(3714, 1253, 1744) -(3799, 2189, 1780) -(1728, 3714, 855) -(1760, 1943, 1435) -(1610, 770, 1520) -(1973, 3254, 1782) -(121, 880, 1463) -(1332, 3084, 882) -(247, 4080, 1781) -(3908, 3, 802) -(3856, 1310, 1548) -(3233, 305, 1841) -(370, 49, 1450) -(4401, 1919, 1197) -(257, 138, 1724) -(1666, 2245, 1106) -(3782, 4183, 1513) -(604, 2766, 634) -(564, 4146, 1309) -(2375, 1980, 1099) -(270, 404, 1702) -(1748, 1327, 262) -(3292, 4364, 837) -(1929, 3480, 1396) -(3196, 2995, 1786) -(1381, 254, 75) -(1252, 2762, 1252) -(2331, 314, 618) -(1760, 1781, 1405) -(2430, 2144, 142) -(1481, 3572, 437) -(503, 124, 1579) -(3761, 1504, 1325) -(2529, 1937, 1060) -(3198, 2525, 403) -(3782, 3938, 1007) -(3805, 2417, 952) -(1332, 3793, 1869) -(693, 77, 456) -(4492, 4414, 1740) -(1779, 381, 1601) -(2417, 1320, 1735) -(1911, 3455, 1597) -(4102, 4171, 1055) -(4577, 231, 1885) -(3962, 3485, 543) -(3152, 2984, 505) -(1152, 475, 103) -(3361, 4772, 302) -(3166, 2390, 291) -(3351, 84, 696) -(2209, 2824, 1744) -(3236, 3820, 204) -(1309, 3064, 1543) -(2199, 3777, 291) -(1256, 4397, 1622) -(1910, 4789, 1840) -(1181, 975, 1130) -(4505, 465, 837) -(73, 1410, 1233) -(4113, 1984, 72) -(3932, 1564, 1964) -(2450, 4466, 214) -(859, 2954, 676) -(836, 4676, 950) -(3768, 4696, 181) -(2602, 1211, 94) -(1644, 4107, 277) -(4042, 3383, 247) -(427, 4207, 1988) -(3584, 867, 1857) -(1802, 278, 162) -(3, 3908, 802) -(3466, 141, 394) -(219, 3645, 1220) -(2680, 4267, 1794) -(2097, 229, 1046) -(4836, 3431, 400) -(4817, 3305, 964) -(3015, 1305, 1387) -(1336, 1020, 797) -(335, 3267, 499) -(663, 2461, 165) -(4525, 4780, 306) -(2441, 2108, 1192) -(4635, 3027, 173) -(3458, 934, 1457) -(1520, 2324, 1583) -(3395, 4400, 1423) -(4371, 3498, 50) -(2526, 2326, 1991) -(4849, 2458, 1484) -(2540, 2265, 1194) -(4931, 1294, 1249) -(1178, 1554, 1778) -(4311, 2340, 768) -(2441, 2189, 1109) -(4471, 3301, 1467) -(204, 673, 964) -(429, 3160, 126) -(3283, 4070, 1464) -(2636, 2368, 450) -(3014, 2086, 505) -(132, 4753, 815) -(268, 70, 1283) -(4456, 2313, 590) -(924, 4930, 1382) -(1806, 2799, 1020) -(4308, 4038, 1519) -(1360, 3924, 1604) -(4347, 1960, 1529) -(2002, 83, 359) -(442, 164, 846) -(2878, 1257, 1371) -(3255, 1049, 1629) -(2965, 1747, 815) -(2802, 1943, 745) -(4493, 4641, 948) -(317, 4519, 532) -(680, 45, 240) -(2978, 3417, 1834) -(3675, 3101, 1167) -(1494, 923, 1198) -(3288, 709, 954) -(2267, 533, 464) -(4675, 1963, 852) -(3367, 260, 695) -(1059, 3251, 1131) -(2798, 2356, 51) -(3272, 2598, 1161) -(365, 916, 98) -(3597, 2367, 1659) -(2276, 385, 976) -(2383, 1135, 908) -(3383, 4042, 247) -(938, 2659, 337) -(1702, 4944, 1280) -(2655, 4891, 275) -(799, 1814, 1102) -(2798, 1125, 1922) -(2428, 2183, 409) -(4876, 1308, 1778) -(27, 4124, 163) -(1550, 4029, 415) -(1417, 2302, 788) -(4417, 3989, 1533) -(2200, 2376, 1537) -(1360, 4223, 883) -(3325, 3425, 1749) -(4083, 784, 1891) -(28, 3082, 1264) -(4299, 3401, 248) -(1004, 4207, 1019) -(3048, 3103, 1988) -(1254, 3907, 1031) -(3094, 4425, 983) -(3680, 1904, 796) -(4439, 2594, 1512) -(37, 2560, 719) -(2151, 2891, 840) -(1725, 3150, 1160) -(947, 3265, 1235) -(3803, 4950, 129) -(1556, 2861, 98) -(3072, 3190, 1176) -(2309, 1380, 1209) -(848, 3722, 1189) -(957, 1320, 1570) -(1817, 1968, 1128) -(1401, 1618, 1840) -(1616, 2563, 1337) -(2752, 4530, 1659) -(3505, 4308, 1522) -(2037, 973, 1795) -(1763, 1064, 890) -(4956, 4020, 409) -(805, 1440, 910) -(4683, 2549, 839) -(4817, 1931, 1424) -(1238, 39, 157) -(1653, 259, 531) -(669, 2701, 1591) -(1998, 3656, 795) -(3849, 137, 635) -(2696, 2606, 1980) -(4388, 3057, 1095) -(117, 475, 1745) -(3974, 4522, 711) -(1383, 1432, 444) -(3402, 3294, 447) -(3769, 364, 352) -(4953, 1543, 1586) -(3003, 4432, 1369) -(2803, 2722, 1972) -(1146, 1774, 1443) -(1363, 4716, 1157) -(1207, 442, 1666) -(4901, 2401, 1733) -(4701, 4270, 664) -(3894, 3036, 191) -(2062, 4290, 1553) -(3900, 4934, 76) -(758, 2014, 1472) -(4059, 3600, 221) -(2116, 661, 602) -(697, 4356, 1168) -(3339, 3575, 1487) -(2413, 783, 560) -(2725, 4499, 797) -(1322, 1423, 1645) -(2470, 2498, 572) -(3215, 616, 447) -(3331, 1971, 518) -(3350, 3948, 117) -(1166, 1332, 141) -(4065, 4043, 1737) -(688, 3975, 163) -(1238, 3614, 1279) -(3400, 2414, 1577) -(4975, 3431, 1793) -(1289, 251, 1113) -(1843, 1724, 1524) -(3608, 1600, 399) -(1278, 51, 744) -(1124, 3027, 1216) -(3089, 4286, 1470) -(4664, 3074, 1883) -(3774, 3752, 340) -(2034, 49, 408) -(3245, 3621, 927) -(458, 2008, 1223) -(3290, 3685, 1000) -(4441, 3099, 737) -(1001, 4561, 1150) -(1220, 1464, 1932) -(2505, 4370, 1766) -(1101, 3263, 1076) -(561, 1489, 1811) -(1400, 4404, 1186) -(163, 968, 1605) -(2212, 1735, 1012) -(739, 1685, 1336) -(2239, 2098, 1218) -(4134, 4934, 542) -(3517, 1210, 1733) -(4041, 941, 873) -(3099, 4441, 737) -(2078, 168, 1128) -(2912, 2982, 1553) -(1134, 3937, 133) -(2088, 1192, 1693) -(1306, 343, 1750) -(724, 3270, 1960) -(957, 4182, 685) -(4464, 2880, 987) -(4266, 3556, 787) -(378, 4486, 814) -(2987, 3468, 755) -(1013, 1752, 1620) -(248, 446, 1826) -(2126, 4991, 1108) -(3752, 3774, 340) -(1781, 1602, 717) -(347, 2725, 1741) -(3713, 271, 282) -(747, 2104, 51) -(4874, 4142, 1550) -(1440, 805, 910) -(4552, 2976, 1958) -(176, 3438, 868) -(1771, 4242, 387) -(4366, 4646, 1645) -(1992, 4890, 364) -(4433, 2089, 1814) -(2384, 81, 1157) -(4967, 2389, 1381) -(1705, 2516, 1293) -(2285, 2531, 1235) -(2581, 3670, 1432) -(1635, 2967, 497) -(4121, 4511, 1932) -(3770, 3109, 1753) -(4200, 542, 1430) -(2696, 1352, 925) -(2180, 2745, 61) -(1475, 838, 1392) -(4093, 2467, 1026) -(2270, 4260, 555) -(2649, 2044, 888) -(102, 154, 876) -(4206, 3931, 1156) -(4954, 1061, 1357) -(4376, 1001, 1884) -(4174, 459, 1553) -(3657, 2016, 845) -(4042, 3966, 1421) -(4560, 1706, 822) -(1956, 2826, 926) -(808, 2177, 289) -(3212, 2823, 971) -(4537, 4847, 981) -(624, 3165, 1679) -(2824, 1283, 1229) -(1718, 1093, 437) -(253, 2475, 323) -(4415, 2228, 735) -(4085, 1380, 989) -(3152, 1600, 363) -(2898, 1116, 1758) -(3450, 1745, 1457) -(4453, 554, 1630) -(4616, 4987, 1885) -(257, 2878, 1030) -(1865, 300, 509) -(1524, 982, 1243) -(1296, 81, 274) -(3137, 2293, 893) -(3068, 2052, 902) -(637, 3005, 1949) -(2631, 3290, 470) -(1985, 1335, 186) -(867, 3584, 1857) -(2245, 1666, 1106) -(812, 2439, 416) -(4547, 557, 1715) -(3694, 295, 1669) -(2974, 1448, 1273) -(1571, 414, 1298) -(385, 1546, 336) -(385, 1938, 495) -(4956, 258, 1235) -(856, 1091, 1111) -(4470, 4210, 1918) -(3886, 2781, 1026) -(1314, 3449, 1393) -(710, 534, 346) -(4477, 3929, 1330) -(856, 4994, 721) -(2863, 204, 311) -(4038, 1028, 242) -(1485, 3116, 1101) -(1203, 691, 1723) -(173, 1784, 740) -(1917, 4657, 773) -(565, 662, 1264) -(2000, 3229, 1939) -(3184, 3075, 1674) -(1682, 4100, 833) -(770, 1610, 1520) -(1672, 4573, 1162) -(900, 2460, 1281) -(3926, 2761, 500) -(3932, 654, 535) -(4460, 683, 1598) -(4169, 1234, 1856) -(1996, 3447, 309) -(2337, 3947, 1695) -(2101, 754, 355) -(1134, 2888, 1350) -(233, 1763, 1151) -(2369, 3138, 1146) -(43, 2929, 661) -(268, 4283, 1297) -(1165, 676, 1808) -(1611, 1404, 640) -(2928, 151, 1760) -(4454, 2021, 624) -(922, 4831, 225) -(312, 70, 206) -(2440, 2995, 140) -(2411, 2465, 712) -(633, 3470, 537) -(4811, 2063, 870) -(833, 2268, 547) -(3278, 4996, 1970) -(3652, 4212, 1724) -(1593, 630, 606) -(1265, 2289, 1981) -(1024, 1006, 1295) -(4574, 1985, 224) -(931, 2646, 165) -(3602, 1900, 949) -(1415, 1935, 1222) -(3215, 2819, 1864) -(2848, 1875, 312) -(3498, 4326, 1968) -(625, 3230, 1312) -(2849, 978, 140) -(3276, 543, 1198) -(3766, 4434, 290) -(4901, 3200, 1447) -(2029, 3458, 467) -(4201, 3288, 1011) -(2382, 322, 351) -(735, 3786, 1973) -(3686, 3221, 809) -(2364, 2085, 267) -(1183, 550, 1132) -(2165, 4975, 1607) -(1486, 1102, 1252) -(4404, 2499, 473) -(4971, 4901, 1933) -(1462, 1659, 942) -(1148, 697, 1373) -(1260, 2887, 336) -(2616, 4570, 211) -(205, 1077, 558) -(2181, 3086, 1488) -(2311, 205, 845) -(939, 410, 1363) -(275, 2137, 787) -(2704, 437, 450) -(4730, 4505, 595) -(1147, 4485, 1520) -(4938, 1594, 1136) -(3657, 4402, 324) -(3607, 2715, 1553) -(3842, 3716, 839) -(1629, 4219, 429) -(2580, 1486, 1297) -(1643, 3527, 697) -(4038, 73, 1973) -(2152, 621, 1575) -(1209, 227, 809) -(3170, 715, 821) -(3547, 3270, 1946) -(4989, 2710, 528) -(3230, 625, 1312) -(1631, 2376, 1758) -(2190, 4559, 1668) -(4773, 1717, 162) -(3849, 4484, 613) -(3962, 4359, 485) -(4649, 2158, 1377) -(2472, 4763, 70) -(2002, 2885, 1248) -(4531, 2206, 1241) -(1444, 1926, 1854) -(2537, 2266, 603) -(1965, 1527, 570) -(1096, 4205, 542) -(685, 4984, 1177) -(3350, 3428, 1464) -(2922, 1639, 651) -(1851, 4367, 638) -(4581, 1324, 1900) -(1126, 2470, 1177) -(108, 3430, 771) -(4575, 2746, 1032) -(746, 443, 605) -(3718, 79, 1319) -(3480, 952, 1354) -(1430, 765, 540) -(1880, 2060, 1603) -(2663, 3900, 1698) -(4045, 4745, 1609) -(3651, 1165, 1099) -(387, 283, 1223) -(4273, 1988, 1442) -(2925, 3581, 487) -(3057, 2213, 1401) -(2647, 435, 1756) -(179, 2761, 188) -(1442, 1296, 1980) -(3435, 3260, 1614) -(4231, 2631, 738) -(1053, 1547, 873) -(2340, 4877, 1010) -(3396, 1914, 868) -(3458, 2029, 467) -(142, 2282, 1668) -(3227, 2948, 1382) -(2325, 4072, 1017) -(2106, 1354, 1140) -(4133, 2337, 585) -(1626, 3078, 1773) -(849, 2350, 1454) -(1915, 3459, 1970) -(1504, 1335, 292) -(163, 1765, 1444) -(2297, 1757, 303) -(2350, 849, 1454) -(3587, 2826, 1970) -(4046, 1695, 131) -(3345, 4965, 133) -(3331, 3402, 1404) -(2254, 1773, 646) -(2664, 2431, 497) -(3261, 4773, 1835) -(4677, 921, 1261) -(1858, 3597, 1004) -(3428, 3350, 1464) -(2542, 3765, 80) -(1366, 4556, 1638) -(3631, 3748, 1097) -(482, 1368, 146) -(869, 1372, 1398) -(129, 4779, 423) -(4517, 1096, 1731) -(1088, 384, 515) -(2283, 839, 217) -(778, 3638, 407) -(3264, 4430, 451) -(3538, 3456, 1814) -(4223, 1360, 883) -(4174, 2584, 301) -(4895, 111, 321) -(2791, 4292, 1933) -(1390, 1025, 1005) -(97, 3868, 1144) -(2548, 3816, 736) -(2004, 261, 540) -(1450, 3542, 389) -(4637, 4581, 1493) -(2386, 1790, 1506) -(2229, 623, 841) -(2251, 4707, 637) -(3313, 2908, 1685) -(10, 4913, 1091) -(3353, 2130, 100) -(1289, 519, 1090) -(2471, 742, 633) -(2303, 880, 406) -(425, 1686, 1659) -(51, 2946, 822) -(4283, 2893, 886) -(4323, 4456, 686) -(601, 1915, 828) -(1688, 621, 1203) -(925, 3693, 584) -(3828, 2376, 743) -(39, 2443, 240) -(844, 1943, 1382) -(2510, 3799, 246) -(2737, 689, 937) -(953, 2652, 310) -(355, 2519, 891) -(4288, 2305, 1557) -(4238, 3954, 1543) -(2083, 515, 888) -(1476, 2824, 246) -(4461, 3726, 603) -(2657, 1063, 1765) -(3296, 4908, 1392) -(2517, 405, 462) -(3806, 714, 1518) -(3683, 4926, 1237) -(4503, 4954, 340) -(179, 2477, 863) -(4484, 3849, 613) -(4504, 4717, 1775) -(4345, 2153, 456) -(4197, 1545, 826) -(757, 3508, 1317) -(400, 3530, 1860) -(4416, 3188, 1078) -(1271, 2136, 818) -(4472, 4603, 1152) -(3097, 4051, 185) -(3960, 869, 1093) -(2853, 845, 1334) -(4809, 3769, 222) -(3140, 1815, 752) -(4505, 2030, 473) -(3253, 1232, 888) -(110, 2286, 1756) -(736, 3881, 149) -(1071, 1107, 1380) -(1325, 3767, 207) -(2098, 3429, 1415) -(4937, 1498, 1497) -(2929, 1704, 1856) -(3215, 4437, 1360) -(3194, 404, 1984) -(3065, 3588, 1585) -(3761, 2226, 383) -(1471, 3302, 883) -(2156, 688, 445) -(3722, 3052, 805) -(546, 1505, 1414) -(4563, 926, 626) -(122, 863, 1988) -(1352, 721, 1749) -(2208, 273, 1555) -(909, 1917, 236) -(868, 4857, 394) -(4623, 2724, 642) -(4234, 3574, 1978) -(6, 1199, 1900) -(4054, 2357, 815) -(765, 1430, 540) -(246, 3914, 913) -(4085, 2976, 1943) -(3812, 2164, 700) -(4334, 2903, 227) -(4791, 4630, 1750) -(38, 448, 1337) -(3082, 28, 1264) -(2453, 2430, 888) -(4799, 4155, 155) -(2711, 3950, 1611) -(1889, 2579, 1498) -(1171, 2764, 946) -(4293, 3080, 816) -(285, 966, 1717) -(4533, 3275, 1035) -(4887, 44, 181) -(1445, 1793, 1223) -(3407, 238, 194) -(4387, 3473, 71) -(3725, 181, 907) -(1602, 3116, 785) -(3027, 2449, 1034) -(1568, 993, 1962) -(1209, 4082, 326) -(3257, 3590, 863) -(3811, 3658, 126) -(210, 18, 1530) -(2671, 1535, 394) -(4209, 2548, 245) -(954, 1759, 831) -(665, 3680, 1965) -(2164, 3718, 1391) -(4425, 3132, 1898) -(3987, 741, 484) -(2861, 2099, 357) -(1784, 4417, 1301) -(1209, 4414, 1878) -(87, 3014, 1570) -(1760, 3383, 1406) -(1020, 1336, 797) -(2921, 3437, 229) -(4415, 1565, 171) -(4730, 2001, 434) -(4106, 2929, 1890) -(1145, 3405, 861) -(1709, 3502, 254) -(4096, 2849, 1418) -(4137, 3739, 250) -(2533, 295, 874) -(2799, 2912, 123) -(1595, 787, 1513) -(4191, 3517, 1525) -(4851, 2789, 898) -(3473, 4387, 71) -(785, 2109, 1764) -(328, 4005, 1470) -(3287, 1575, 1565) -(219, 4605, 809) -(3572, 1495, 1156) -(2484, 3540, 1581) -(4793, 2910, 586) -(4163, 2790, 1570) -(1385, 4148, 1373) -(171, 3143, 1316) -(3421, 4297, 510) -(829, 3348, 1107) -(3145, 2819, 1402) -(4273, 286, 989) -(4237, 2348, 637) -(2268, 3810, 188) -(1287, 3797, 1249) -(2874, 2923, 368) -(892, 1088, 1095) -(1600, 169, 1146) -(2610, 2613, 1217) -(302, 4360, 462) -(3500, 2115, 173) -(1109, 1689, 1104) -(1392, 3384, 1760) -(3549, 1106, 1405) -(3038, 2965, 681) -(2395, 2997, 1168) -(3977, 3495, 93) -(2467, 4589, 1664) -(2968, 1876, 662) -(460, 4031, 1463) -(629, 4333, 1029) -(1995, 792, 1982) -(3944, 4161, 1520) -(3779, 4841, 1256) -(1565, 2466, 814) -(3839, 4714, 205) -(2154, 332, 1445) -(2675, 3527, 1834) -(1372, 940, 991) -(647, 4706, 575) -(1820, 1464, 122) -(3101, 4413, 933) -(3138, 1606, 1292) -(362, 4401, 892) -(1510, 102, 231) -(3596, 3335, 1178) -(1192, 2741, 270) -(2828, 2964, 1092) -(4738, 2881, 1823) -(4211, 261, 1411) -(2094, 4379, 1017) -(264, 4888, 77) -(2205, 3111, 1758) -(2149, 4664, 588) -(1768, 3132, 1616) -(2501, 4918, 1995) -(4869, 239, 1368) -(306, 865, 811) -(3980, 4297, 79) -(3459, 3973, 966) -(4927, 2367, 1048) -(73, 1012, 677) -(3390, 1252, 1496) -(626, 2776, 1632) -(1827, 1227, 558) -(222, 522, 1450) -(1015, 4846, 1139) -(1283, 2824, 1229) -(3892, 1244, 1124) -(4723, 2083, 87) -(46, 2805, 556) -(3946, 922, 1616) -(330, 1408, 1146) -(3593, 4824, 1473) -(1449, 3148, 1422) -(2959, 1586, 579) -(3144, 1860, 621) -(650, 223, 1930) -(3869, 3484, 266) -(1005, 2029, 1989) -(2649, 402, 545) -(459, 4773, 1096) -(575, 4723, 389) -(2575, 4542, 1337) -(1089, 4426, 1812) -(2037, 1506, 695) -(3484, 278, 745) -(2179, 1240, 1162) -(3540, 2698, 1790) -(1414, 2361, 1323) -(4710, 4130, 1985) -(3281, 3478, 437) -(4272, 4943, 108) -(420, 4184, 1940) -(1568, 2278, 1570) -(2677, 2396, 714) -(3346, 4075, 371) -(4780, 3444, 814) -(3062, 441, 1629) -(1110, 759, 833) -(3045, 1189, 73) -(3753, 212, 193) -(3757, 529, 828) -(4633, 1202, 1102) -(966, 3375, 1383) -(3646, 361, 1653) -(1762, 1214, 1381) -(1142, 3796, 471) -(4304, 4419, 451) -(1730, 1920, 1477) -(72, 392, 1833) -(1412, 2745, 1739) -(2372, 75, 102) -(3782, 3597, 126) -(3229, 3715, 1484) -(1306, 4947, 653) -(2978, 3409, 1394) -(4938, 3295, 447) -(4410, 1080, 1210) -(2314, 3813, 463) -(2952, 1080, 781) -(346, 635, 1246) -(4331, 3933, 71) -(2053, 2855, 1823) -(1242, 201, 316) -(191, 625, 1993) -(1338, 1928, 1234) -(4971, 4730, 1664) -(2391, 2757, 741) -(4980, 3354, 559) -(2735, 787, 1569) -(3666, 3210, 1688) -(1585, 621, 940) -(385, 1214, 86) -(2919, 855, 997) -(3945, 4295, 1412) -(382, 4603, 1718) -(4367, 1851, 638) -(1210, 1102, 115) -(125, 1906, 1019) -(3077, 837, 1428) -(1425, 2652, 1095) -(1500, 1200, 1385) -(2136, 4262, 359) -(3910, 223, 842) -(3144, 778, 1341) -(1874, 2737, 1594) -(3605, 899, 642) -(4480, 159, 1064) -(2967, 4526, 1980) -(4116, 1436, 1674) -(3620, 4792, 613) -(2563, 1616, 1337) -(4410, 1421, 1410) -(4989, 3023, 1975) -(4750, 2903, 673) -(4292, 591, 505) -(4863, 3018, 195) -(198, 216, 595) -(3940, 4586, 810) -(1874, 2766, 1795) -(1078, 1272, 109) -(1404, 1611, 640) -(1755, 2511, 1514) -(3486, 4649, 673) -(3840, 2951, 1078) -(2883, 747, 1358) -(2808, 654, 725) -(2928, 4960, 1044) -(2908, 2925, 778) -(1900, 1623, 1314) -(1308, 4876, 1778) -(81, 2384, 1157) -(1690, 537, 830) -(568, 564, 911) -(3120, 113, 1730) -(4110, 3772, 790) -(1642, 3454, 1861) -(2741, 3104, 328) -(2719, 2923, 200) -(107, 3327, 617) -(4405, 668, 1440) -(2428, 214, 1448) -(981, 3784, 1625) -(3793, 3522, 527) -(2275, 2656, 1889) -(3695, 2029, 426) -(669, 4898, 1572) -(2492, 1779, 1785) -(3932, 2651, 1645) -(530, 3019, 1043) -(3391, 1998, 1779) -(3165, 624, 1679) -(466, 234, 655) -(1010, 4183, 1019) -(4115, 3327, 296) -(3441, 4072, 1527) -(3073, 1979, 1729) -(4905, 1014, 713) -(3997, 4913, 741) -(2236, 3932, 117) -(4539, 4979, 640) -(1383, 50, 251) -(203, 4314, 607) -(4135, 3941, 1999) -(1943, 1760, 1435) -(227, 4999, 1641) -(0, 297, 1378) -(3326, 3300, 1239) -(4436, 3556, 289) -(2992, 3149, 1897) -(1029, 1148, 643) -(1880, 2388, 1163) -(4432, 4940, 1632) -(1969, 1541, 1424) -(3263, 4893, 976) -(1296, 133, 829) -(3312, 2026, 62) -(121, 2309, 713) -(1682, 4494, 1935) -(3764, 1188, 63) -(2393, 4716, 1903) -(2994, 2138, 639) -(4895, 3788, 558) -(4388, 2757, 101) -(498, 445, 774) -(704, 624, 1789) -(3630, 2240, 956) -(3262, 2867, 1492) -(1353, 3909, 877) -(2626, 2890, 1761) -(2785, 4959, 993) -(4122, 1668, 1894) -(2215, 3412, 764) -(1006, 1457, 623) -(2398, 2906, 1634) -(1694, 2765, 643) -(2623, 2439, 1819) -(1258, 136, 256) -(3075, 1536, 1964) -(4196, 4786, 357) -(1436, 4624, 535) -(1459, 881, 670) -(3027, 4987, 373) -(234, 530, 1664) -(3444, 1021, 1689) -(2, 165, 1846) -(223, 2294, 1072) -(480, 1194, 934) -(4493, 4329, 1681) -(895, 4579, 930) -(4184, 420, 1940) -(3059, 202, 610) -(470, 2357, 583) -(1028, 1373, 1910) -(4391, 1795, 1217) -(3937, 3352, 1163) -(2699, 2809, 1977) -(2346, 1931, 1234) -(1551, 3735, 1912) -(4329, 630, 1612) -(1455, 894, 822) -(1805, 1647, 1397) -(4642, 2091, 82) -(1499, 2726, 967) -(1026, 3370, 1207) -(436, 2669, 1473) -(1816, 1976, 768) -(3868, 97, 1144) -(3718, 2424, 1513) -(3804, 2651, 58) -(4766, 484, 677) -(2105, 3845, 1381) -(1116, 3382, 774) -(2368, 3169, 1441) -(16, 3654, 348) -(1316, 3111, 1377) -(2779, 1403, 619) -(2267, 564, 345) -(376, 695, 377) -(1464, 3360, 923) -(3524, 2834, 1084) -(618, 4134, 187) -(2182, 3647, 1636) -(4, 1319, 918) -(3198, 573, 555) -(2449, 4255, 1642) -(2884, 941, 179) -(2611, 879, 1909) -(2376, 2200, 1537) -(3646, 3977, 1878) -(2887, 554, 1888) -(1319, 1745, 958) -(1223, 3900, 1114) -(3433, 2942, 1914) -(473, 182, 1692) -(4355, 4952, 1658) -(2647, 1044, 1017) -(1009, 1617, 529) -(3377, 1627, 1025) -(3098, 3342, 951) -(2077, 2395, 1502) -(4871, 3381, 578) -(859, 1874, 265) -(465, 1255, 1348) -(4730, 201, 719) -(2185, 2327, 400) -(1306, 1311, 1330) -(1554, 503, 1578) -(4271, 157, 595) -(4455, 400, 740) -(968, 4327, 402) -(21, 3993, 279) -(4247, 4076, 750) -(253, 2564, 322) -(599, 3704, 224) -(3180, 616, 1780) -(3468, 4931, 557) -(4755, 4821, 494) -(1210, 975, 836) -(4786, 3095, 1295) -(2189, 4151, 1952) -(3276, 4289, 92) -(3090, 1273, 1919) -(4990, 1646, 1883) -(4322, 4863, 774) -(1180, 2505, 647) -(4836, 3332, 242) -(3626, 4187, 500) -(3980, 62, 796) -(2839, 1690, 1720) -(394, 4576, 1919) -(4982, 3499, 1602) -(3876, 3728, 455) -(4514, 644, 667) -(445, 379, 634) -(4208, 433, 1450) -(1710, 1604, 846) -(396, 161, 947) -(2042, 2202, 646) -(4455, 3611, 751) -(4235, 290, 1397) -(593, 865, 92) -(4922, 2389, 869) -(4885, 484, 1343) -(1414, 4450, 809) -(1128, 214, 1329) -(3959, 1391, 121) -(4313, 4815, 1380) -(2289, 378, 376) -(4995, 2369, 598) -(24, 3563, 53) -(734, 134, 499) -(1881, 2697, 1959) -(3764, 3515, 392) -(3466, 3778, 844) -(257, 2786, 1822) -(2976, 4552, 1958) -(168, 1987, 1219) -(2867, 2865, 747) -(1517, 4000, 204) -(86, 3213, 1721) -(3257, 2751, 1298) -(2710, 1979, 581) -(1920, 3763, 96) -(3771, 3609, 1988) -(4658, 1905, 363) -(4255, 2449, 1642) -(4664, 1422, 1942) -(4265, 4528, 1059) -(403, 1081, 1445) -(3521, 3334, 1059) -(287, 3543, 714) -(305, 2455, 396) -(2947, 3056, 861) -(343, 2491, 770) -(3407, 1326, 629) -(2206, 4870, 1382) -(4449, 1969, 461) -(3793, 4183, 325) -(3084, 527, 1332) -(3757, 959, 1039) -(3833, 4273, 1165) -(2019, 1048, 1728) -(1745, 4327, 343) -(3702, 1105, 646) -(1031, 4237, 91) -(1744, 3229, 767) -(553, 1200, 220) -(4120, 495, 1236) -(3697, 4319, 1686) -(3315, 1935, 1119) -(3234, 2350, 1364) -(4665, 4479, 376) -(1542, 4460, 423) -(3488, 1731, 1890) -(3241, 729, 1175) -(1060, 11, 1895) -(383, 2167, 554) -(4617, 538, 1270) -(1710, 2491, 1725) -(4941, 3759, 1422) -(3284, 857, 783) -(670, 1187, 1001) -(1194, 817, 124) -(695, 1820, 1071) -(4807, 4568, 1472) -(187, 1285, 1514) -(3727, 2805, 1530) -(685, 954, 296) -(3993, 1223, 1611) -(4400, 4865, 1936) -(949, 2089, 1022) -(757, 4772, 1363) -(468, 2238, 1066) -(4356, 251, 553) -(4842, 1786, 1496) -(1800, 721, 457) -(3102, 345, 1888) -(3487, 3285, 742) -(4661, 882, 1896) -(2146, 4036, 191) -(2665, 1740, 448) -(3395, 2053, 458) -(201, 4730, 719) -(3602, 1225, 1372) -(2266, 3061, 1867) -(564, 684, 568) -(1135, 695, 1410) -(4426, 3185, 368) -(1163, 2982, 1205) -(4664, 2149, 588) -(4979, 4539, 640) -(1086, 3165, 399) -(4610, 1175, 170) -(2366, 1660, 1792) -(628, 2503, 1541) -(1194, 4206, 1861) -(380, 3073, 716) -(4459, 4761, 1380) -(4087, 2305, 851) -(4902, 2747, 884) -(745, 2341, 1300) -(4757, 2188, 1528) -(3542, 3998, 1967) -(3963, 2401, 452) -(1540, 1821, 1657) -(791, 1970, 999) -(3005, 3943, 1115) -(4637, 3570, 560) -(2264, 1937, 1818) -(2322, 2917, 733) -(3876, 4177, 1627) -(2486, 528, 887) -(4792, 3620, 613) -(1080, 787, 1005) -(2142, 279, 1211) -(3391, 2871, 290) -(4062, 786, 736) -(2477, 179, 863) -(3057, 1545, 1623) -(1264, 3853, 1731) -(1975, 3943, 570) -(4545, 153, 1602) -(1615, 268, 1141) -(3788, 1519, 1503) -(1311, 565, 543) -(3308, 2382, 1498) -(3217, 4981, 1834) -(1327, 1748, 262) -(2667, 130, 1833) -(1513, 278, 1696) -(2397, 4917, 544) -(2060, 1880, 1603) -(3609, 3771, 1988) -(4207, 2440, 982) -(1826, 4044, 522) -(2472, 2012, 1691) -(1823, 3476, 684) -(4918, 1258, 547) -(2201, 3030, 835) -(3240, 1035, 1691) -(2890, 2626, 1761) -(3421, 166, 1711) -(2749, 4331, 1732) -(1558, 535, 611) -(655, 4813, 1362) -(4780, 1666, 1851) -(2753, 2010, 1202) -(4966, 2500, 1452) -(4848, 3088, 564) -(3769, 1030, 1054) -(2967, 2146, 1677) -(1361, 2079, 1125) -(333, 902, 657) -(2175, 4692, 765) -(2039, 1797, 1961) -(801, 476, 683) -(1647, 3913, 523) -(3094, 3019, 1818) -(3276, 2986, 1082) -(575, 4451, 373) -(4666, 4966, 445) -(3405, 4726, 342) -(353, 469, 382) -(4166, 41, 1797) -(3043, 2649, 723) -(633, 3139, 1889) -(1961, 437, 1133) -(561, 2720, 345) -(1368, 3088, 683) -(3808, 3858, 220) -(3288, 1391, 202) -(4037, 910, 1419) -(2861, 145, 1635) -(315, 1937, 507) -(2384, 2997, 897) -(923, 1494, 1198) -(780, 1789, 1283) -(4895, 4225, 1938) -(3684, 3361, 1127) -(3530, 4028, 1778) -(4258, 4250, 383) -(563, 3337, 271) -(900, 2570, 1121) -(81, 2568, 720) -(4489, 774, 861) -(720, 3626, 1705) -(1274, 1921, 99) -(1747, 4093, 1611) -(4007, 1019, 1006) -(2301, 4195, 557) -(2302, 1014, 1853) -(197, 494, 401) -(3512, 3342, 1229) -(1858, 1581, 1382) -(772, 1740, 1113) -(3733, 4970, 1038) -(313, 3361, 66) -(1716, 2995, 165) -(2514, 1522, 743) -(222, 819, 689) -(3351, 2537, 1299) -(2978, 113, 902) -(366, 2920, 551) -(2726, 3571, 299) -(4807, 4707, 698) -(3585, 4856, 1954) -(835, 2764, 79) -(412, 1959, 566) -(4038, 4308, 1519) -(843, 1861, 1574) -(1931, 1276, 1708) -(3775, 2961, 1228) -(4957, 406, 638) -(3069, 1825, 1987) -(1524, 4871, 143) -(3721, 1124, 1021) -(2691, 1181, 1698) -(3945, 402, 1270) -(3346, 4648, 218) -(4413, 1987, 100) -(4309, 1427, 1060) -(3332, 2378, 1585) -(1791, 3409, 115) -(2403, 457, 1593) -(1543, 2656, 1656) -(1118, 1987, 1029) -(3027, 1124, 1216) -(3094, 683, 825) -(3016, 978, 1893) -(560, 2231, 1600) -(1685, 4574, 665) -(555, 3127, 861) -(661, 2116, 602) -(1405, 4807, 389) -(2656, 1543, 1656) -(3855, 2476, 459) -(2140, 3309, 1717) -(4878, 4308, 1898) -(1424, 2328, 221) -(4623, 466, 369) -(2017, 3529, 180) -(2046, 1643, 1809) -(616, 3180, 1780) -(4399, 1143, 839) -(4291, 1942, 1233) -(3938, 1823, 1632) -(437, 4764, 861) -(2305, 4087, 851) -(4263, 1016, 1570) -(1720, 1443, 1832) -(2980, 1435, 1691) -(1098, 2514, 1163) -(1972, 4125, 658) -(3543, 3964, 385) -(1418, 4021, 1364) -(800, 4421, 567) -(878, 4029, 414) -(2387, 557, 159) -(308, 4463, 398) -(4336, 1752, 384) -(2886, 1826, 468) -(4462, 104, 695) -(2475, 4710, 1607) -(4654, 896, 270) -(4097, 2146, 1980) -(982, 1524, 1243) -(1584, 560, 1981) -(667, 4084, 1872) -(4290, 1838, 1792) -(2295, 2769, 1934) -(1706, 4560, 822) -(2609, 1472, 254) -(25, 1011, 1287) -(3227, 3884, 1932) -(3094, 1381, 1625) -(1833, 3927, 1995) -(542, 4243, 144) -(891, 3914, 412) -(1635, 1305, 602) -(1799, 874, 1864) -(4295, 4651, 1568) -(2135, 4236, 380) -(3748, 4066, 327) -(1584, 2803, 1076) -(478, 1426, 1110) -(2757, 573, 1934) -(1417, 1260, 280) -(3040, 2843, 773) -(1903, 2978, 869) -(101, 153, 1044) -(3302, 1471, 883) -(2679, 2132, 1040) -(775, 339, 358) -(4296, 712, 1006) -(662, 4807, 1862) -(4952, 4247, 680) -(1331, 4327, 946) -(4007, 2108, 1891) -(4310, 2161, 1083) -(889, 2209, 1608) -(1936, 113, 1684) -(4212, 4876, 1329) -(4184, 1469, 1675) -(1940, 2390, 716) -(4532, 291, 1262) -(3556, 4266, 787) -(3838, 4515, 1242) -(2293, 3970, 463) -(4738, 1024, 894) -(2082, 384, 982) -(1108, 3978, 1681) -(1982, 1297, 439) -(2835, 4217, 502) -(263, 2819, 1545) -(3505, 2937, 1584) -(4802, 3641, 1716) -(3676, 2522, 111) -(2923, 1016, 473) -(3277, 1257, 1458) -(319, 693, 1357) -(2764, 1071, 1382) -(1837, 340, 604) -(1690, 853, 926) -(1336, 4892, 309) -(2514, 4823, 1459) -(3374, 1954, 1393) -(4630, 4791, 1750) -(1882, 2004, 1328) -(1969, 1653, 975) -(1412, 3570, 1568) -(2512, 906, 253) -(3727, 4931, 931) -(3737, 3495, 1131) -(3440, 2529, 1097) -(983, 1635, 457) -(605, 1175, 1987) -(4590, 80, 1139) -(1435, 2980, 1691) -(4416, 42, 1285) -(1530, 2538, 1320) -(2049, 4874, 1604) -(832, 419, 502) -(3162, 1830, 634) -(4678, 2273, 1873) -(2744, 130, 580) -(1393, 1523, 281) -(4371, 3762, 1353) -(4659, 1841, 912) -(4428, 1921, 1119) -(4266, 1153, 308) -(2076, 3864, 134) -(3506, 1920, 995) -(4163, 1152, 542) -(3308, 3047, 1429) -(3485, 3114, 137) -(4687, 3911, 709) -(3281, 4628, 74) -(4777, 2538, 1670) -(1387, 608, 741) -(662, 4338, 109) -(3387, 228, 714) -(2695, 786, 1312) -(2189, 2441, 1109) -(1196, 4566, 891) -(1526, 2177, 1938) -(4788, 3332, 1498) -(117, 2221, 1837) -(2897, 2756, 712) -(2807, 3161, 686) -(1547, 2288, 1770) -(3561, 1645, 148) -(3738, 1909, 875) -(3962, 3131, 137) -(4019, 4294, 596) -(2811, 4910, 1272) -(1760, 3417, 1701) -(74, 419, 1034) -(2313, 4456, 590) -(387, 4865, 1803) -(3118, 487, 874) -(2256, 311, 74) -(205, 870, 712) -(2255, 3595, 1108) -(1730, 3853, 527) -(3282, 3654, 1462) -(1505, 3078, 644) -(4822, 4518, 604) -(2934, 4939, 1810) -(1617, 2861, 1402) -(2517, 3340, 1200) -(1842, 3466, 658) -(1749, 1880, 131) -(2883, 2383, 1813) -(2610, 3501, 1139) -(4365, 2786, 989) -(4716, 865, 1254) -(4161, 3833, 1185) -(476, 2603, 1483) -(1453, 1475, 1764) -(3396, 983, 1308) -(496, 2497, 671) -(2212, 913, 639) -(3255, 2967, 1703) -(4972, 1677, 459) -(2385, 2913, 415) -(2067, 1007, 422) -(4911, 1640, 1154) -(2221, 3293, 965) -(3325, 3, 621) -(436, 3813, 302) -(2042, 1773, 865) -(1775, 1061, 1282) -(2370, 1681, 1668) -(2124, 2024, 564) -(798, 3995, 884) -(3022, 2828, 620) -(500, 68, 1782) -(2285, 3374, 96) -(3748, 687, 392) -(1051, 2329, 962) -(4412, 4201, 84) -(4522, 4012, 1230) -(1312, 519, 1843) -(4480, 145, 819) -(4616, 3681, 336) -(2589, 4855, 253) -(4992, 3351, 135) -(3582, 4005, 1631) -(4077, 4541, 1534) -(1289, 3141, 236) -(2324, 1520, 1583) -(4730, 2419, 1752) -(4656, 2631, 1803) -(1734, 229, 405) -(1815, 3780, 957) -(4175, 3099, 100) -(4167, 1102, 398) -(2193, 3942, 1353) -(2554, 2644, 862) -(4542, 1207, 76) -(2459, 1655, 1248) -(3949, 2367, 666) -(4048, 1300, 600) -(3621, 3245, 927) -(3124, 331, 143) -(139, 2083, 1054) -(4284, 2734, 356) -(4844, 1906, 338) -(2898, 2685, 1043) -(3158, 3424, 230) -(1141, 1050, 1894) -(4515, 775, 1833) -(500, 2149, 1824) -(4241, 2957, 1870) -(903, 3575, 1125) -(2713, 796, 94) -(494, 3883, 1124) -(1804, 66, 1641) -(4419, 162, 1676) -(1453, 1354, 1727) -(1547, 663, 1662) -(3558, 4939, 931) -(2338, 1275, 526) -(4348, 1218, 811) -(4008, 812, 373) -(3180, 2437, 1918) -(3312, 1417, 464) -(3467, 3937, 1387) -(1234, 2697, 1413) -(3786, 1082, 364) -(2300, 1261, 938) -(532, 4690, 1164) -(1295, 1518, 1739) -(2888, 4612, 961) -(1039, 3372, 1020) -(2751, 1894, 100) -(4093, 1255, 1076) -(2292, 633, 148) -(4107, 2318, 899) -(4527, 697, 637) -(3484, 3869, 266) -(4225, 2720, 923) -(359, 4514, 1430) -(154, 490, 1079) -(4374, 2544, 1751) -(2079, 1361, 1125) -(2426, 2271, 1396) -(2159, 1291, 481) -(4299, 2586, 259) -(1184, 4336, 1169) -(1713, 1718, 1397) -(2883, 3475, 1880) -(4627, 172, 592) -(2881, 3933, 193) -(3818, 3606, 379) -(2775, 2073, 248) -(825, 3465, 390) -(2170, 3583, 1548) -(691, 904, 1029) -(2600, 3920, 1337) -(2214, 1144, 1356) -(4870, 561, 480) -(4556, 1366, 1638) -(666, 2120, 1950) -(2240, 3630, 956) -(1217, 3536, 1708) -(632, 2928, 77) -(2006, 1616, 1130) -(4108, 1235, 1164) -(354, 394, 1560) -(3687, 4580, 1140) -(2658, 3936, 1125) -(2055, 4069, 1087) -(924, 2606, 181) -(2962, 521, 351) -(911, 4, 1116) -(1609, 3091, 458) -(478, 2055, 772) -(2377, 3976, 1888) -(2822, 1061, 163) -(2361, 2890, 1310) -(550, 3172, 1539) -(4547, 1346, 1656) -(363, 3985, 725) -(583, 2144, 359) -(2962, 1892, 474) -(1543, 1996, 1171) -(1241, 3123, 327) -(1760, 2061, 858) -(255, 559, 1519) -(2797, 4123, 1851) -(2767, 2475, 210) -(4755, 1410, 1928) -(1648, 782, 1180) -(1501, 2670, 979) -(2266, 1516, 1152) -(3311, 3578, 492) -(2951, 1929, 1825) -(208, 3089, 667) -(3337, 781, 1929) -(3481, 1981, 547) -(239, 4869, 1368) -(499, 838, 293) -(1252, 2824, 1482) -(4946, 4719, 463) -(1171, 2938, 1543) -(3384, 1392, 1760) -(2282, 4018, 1942) -(1208, 1710, 169) -(1230, 216, 728) -(4770, 2742, 1663) -(4331, 2318, 1255) -(3172, 4818, 519) -(1402, 272, 1651) -(3408, 2765, 441) -(466, 1556, 1752) -(3495, 3977, 93) -(2036, 685, 104) -(4567, 2878, 936) -(2851, 1569, 1173) -(4947, 273, 1421) -(2604, 1562, 477) -(130, 2667, 1833) -(120, 623, 1880) -(2138, 188, 550) -(954, 4168, 642) -(1463, 1920, 373) -(1861, 4245, 1443) -(2379, 1690, 1360) -(2969, 458, 1961) -(3766, 2155, 465) -(1440, 2124, 1532) -(370, 971, 861) -(1602, 2340, 1855) -(2200, 3871, 910) -(3815, 4841, 1688) -(4678, 1811, 963) -(692, 541, 1245) -(750, 2826, 759) -(3430, 4968, 385) -(3410, 720, 327) -(554, 1357, 353) -(2026, 3731, 1841) -(3403, 4355, 812) -(1381, 3480, 882) -(3740, 3942, 1555) -(4580, 4013, 1204) -(4967, 2355, 1755) -(4182, 2025, 1110) -(1113, 494, 1806) -(3439, 434, 1484) -(2712, 4806, 176) -(2744, 3531, 1814) -(688, 2156, 445) -(444, 3769, 1326) -(2918, 2379, 1085) -(3968, 4092, 157) -(1716, 2586, 1407) -(1157, 2271, 818) -(4302, 3493, 1462) -(1631, 939, 1805) -(1169, 477, 1237) -(3631, 1109, 181) -(2544, 4374, 1751) -(1334, 1221, 1299) -(4700, 4616, 1931) -(733, 54, 1914) -(1204, 4522, 1728) -(3323, 714, 587) -(4115, 4665, 66) -(3344, 3029, 1730) -(2382, 3712, 813) -(3767, 457, 1663) -(919, 1665, 1712) -(1233, 2810, 1691) -(3030, 252, 1361) -(4323, 157, 86) -(1900, 1688, 710) -(475, 4835, 1518) -(3855, 4314, 101) -(1076, 2896, 78) -(4480, 2433, 1285) -(2554, 3285, 1828) -(2243, 4161, 1645) -(2577, 4678, 858) -(4251, 1486, 209) -(1170, 3544, 714) -(2187, 1119, 1803) -(3072, 19, 199) -(1275, 2965, 1921) -(86, 3507, 876) -(506, 1419, 432) -(3003, 399, 1101) -(554, 1153, 660) -(1804, 407, 852) -(3752, 1264, 1348) -(2734, 1079, 1149) -(4173, 2774, 1313) -(3926, 4909, 1685) -(3595, 2666, 1920) -(2485, 1167, 420) -(377, 3742, 76) -(1937, 1350, 1896) -(2847, 4361, 1956) -(4765, 350, 1849) -(3246, 2002, 1941) -(2357, 2857, 1027) -(4761, 2971, 1042) -(2669, 2645, 1974) -(4274, 2548, 689) -(1825, 3069, 1987) -(3280, 444, 894) -(2327, 2349, 1932) -(1480, 2114, 1568) -(703, 592, 1950) -(4001, 2264, 1271) -(4305, 3827, 1547) -(1953, 369, 1075) -(3789, 877, 1029) -(2189, 2040, 418) -(102, 2796, 233) -(2228, 3682, 1346) -(2053, 2248, 961) -(2086, 320, 987) -(83, 807, 1100) -(261, 2004, 540) -(4566, 445, 458) -(3550, 2206, 347) -(654, 3689, 806) -(3081, 2643, 497) -(41, 4166, 1797) -(3936, 2658, 1125) -(4295, 3945, 1412) -(4718, 3467, 1693) -(3856, 1419, 1584) -(4900, 2684, 1058) -(3451, 3867, 1121) -(2963, 4102, 1080) -(4503, 4765, 860) -(906, 1349, 977) -(2537, 3351, 1299) -(4854, 1715, 1329) -(1986, 1359, 1357) -(4075, 4599, 558) -(4857, 868, 394) -(1854, 1157, 1396) -(4658, 1234, 549) -(4160, 3075, 1293) -(2248, 2053, 961) -(546, 1604, 1320) -(2197, 4472, 619) -(3630, 2203, 1972) -(3580, 4575, 871) -(530, 234, 1664) -(766, 1711, 822) -(3172, 550, 1539) -(751, 857, 503) -(1070, 3091, 1663) -(2458, 2656, 1529) -(2035, 3557, 477) -(2324, 4989, 1488) -(1380, 2309, 1209) -(986, 4078, 1855) -(3975, 688, 163) -(3107, 1742, 523) -(1879, 4780, 1837) -(4595, 1932, 1094) -(996, 3231, 535) -(1983, 3009, 421) -(1942, 4291, 1233) -(3327, 107, 617) -(1961, 2331, 1214) -(1384, 1099, 783) -(4188, 1195, 795) -(3370, 2120, 806) -(1625, 4498, 1226) -(2780, 2570, 204) -(776, 4811, 1177) -(2849, 4096, 1418) -(2731, 1110, 72) -(3168, 4972, 1214) -(3884, 4722, 1676) -(1565, 4551, 1049) -(1326, 1071, 458) -(3354, 4036, 125) -(2879, 1763, 80) -(3843, 1644, 168) -(4734, 1238, 117) -(3068, 3289, 1273) -(537, 1096, 1467) -(2738, 3169, 1213) -(4096, 4892, 1203) -(4115, 4136, 544) -(1746, 3719, 785) -(326, 1705, 1034) -(696, 4792, 1396) -(4554, 1607, 904) -(3095, 2699, 1368) -(2165, 4700, 1516) -(582, 3786, 631) -(4420, 1781, 373) -(4515, 3595, 1805) -(2944, 2604, 167) -(30, 1667, 1230) -(3054, 3674, 217) -(881, 2103, 582) -(1198, 1236, 538) -(4725, 2855, 1756) -(2851, 250, 1041) -(1501, 2949, 1802) -(413, 3504, 796) -(838, 499, 293) -(565, 1625, 1830) -(3341, 2743, 162) -(2001, 617, 1293) -(4762, 4951, 1960) -(858, 4157, 1840) -(4692, 4628, 765) -(3174, 3743, 1413) -(4162, 4426, 359) -(3409, 2978, 1394) -(2553, 3170, 595) -(1254, 4194, 1597) -(703, 4856, 219) -(3761, 57, 1860) -(1639, 1500, 787) -(4833, 4807, 535) -(4499, 4628, 1003) -(1898, 3005, 1238) -(2386, 1537, 1235) -(2836, 1154, 329) -(4644, 1021, 1589) -(796, 562, 249) -(1421, 4831, 1909) -(495, 4386, 1733) -(1044, 1816, 1494) -(79, 3747, 1868) -(3645, 4159, 1383) -(3064, 4633, 694) -(2935, 1966, 439) -(4123, 2797, 1851) -(2850, 2463, 186) -(417, 4072, 1384) -(4051, 3097, 185) -(17, 3318, 1326) -(3534, 2645, 492) -(3457, 2285, 1350) -(4294, 4721, 999) -(3433, 1606, 404) -(4289, 4259, 942) -(2235, 3895, 1365) -(4426, 4162, 359) -(1479, 4340, 903) -(4568, 1427, 392) -(95, 2565, 1113) -(1601, 3638, 335) -(1506, 4953, 1879) -(347, 4504, 841) -(2615, 3836, 428) -(1988, 4273, 1442) -(445, 4566, 458) -(1473, 1113, 1082) -(2979, 4242, 948) -(96, 48, 1686) -(3229, 2498, 1073) -(3742, 3493, 567) -(4619, 4783, 1462) -(669, 1999, 660) -(3244, 2729, 1240) -(1796, 1951, 368) -(3530, 4191, 1572) -(1813, 1740, 577) -(1716, 3959, 1416) -(732, 76, 410) -(3072, 2650, 1933) -(4664, 1628, 1397) -(2111, 1732, 601) -(1252, 1665, 606) -(4145, 2208, 858) -(308, 4500, 1576) -(2412, 2329, 1791) -(2072, 3843, 363) -(2060, 3058, 601) -(3401, 4299, 248) -(3138, 483, 261) -(4107, 1446, 184) -(3804, 3840, 224) -(2698, 3584, 1617) -(1587, 682, 284) -(2987, 2297, 776) -(4339, 2719, 1570) -(2539, 458, 1625) -(4704, 2080, 1442) -(2231, 560, 1600) -(581, 2085, 439) -(1773, 2042, 865) -(3690, 583, 87) -(2257, 3229, 1101) -(4020, 2827, 650) -(3632, 3700, 1086) -(1398, 2256, 1134) -(3942, 2235, 1352) -(2829, 371, 1415) -(1602, 880, 1055) -(512, 447, 1852) -(3032, 3745, 813) -(2138, 2320, 1138) -(3381, 3143, 1986) -(2738, 2507, 1725) -(1351, 2839, 460) -(2280, 1113, 348) -(678, 3972, 163) -(1343, 1734, 82) -(2230, 106, 447) -(1341, 4477, 167) -(2388, 1880, 1163) -(1299, 656, 209) -(1673, 1906, 1212) -(3535, 542, 1048) -(995, 4897, 1901) -(2650, 4227, 1338) -(4190, 803, 1763) -(2014, 4305, 204) -(592, 2592, 645) -(810, 1659, 1895) -(4061, 4272, 959) -(378, 2289, 376) -(359, 3483, 1819) -(2971, 1869, 1978) -(4099, 3751, 1218) -(4526, 4866, 955) -(2468, 4079, 833) -(882, 657, 963) -(3429, 3253, 1690) -(278, 2548, 829) -(134, 2442, 173) -(1216, 3957, 1665) -(2989, 1896, 805) -(3327, 297, 663) -(2104, 2801, 1090) -(4964, 4018, 837) -(776, 2979, 686) -(1635, 3229, 1935) -(687, 1344, 1335) -(4760, 3610, 259) -(1170, 2660, 507) -(34, 512, 1590) -(3215, 3558, 1101) -(842, 1211, 657) -(4273, 3833, 1165) -(4518, 4822, 604) -(2474, 3191, 683) -(4164, 1154, 1915) -(3707, 3228, 304) -(1205, 24, 1142) -(796, 1624, 1966) -(785, 1701, 1505) -(4687, 1270, 171) -(799, 3989, 1388) -(4362, 2193, 1896) -(1504, 2803, 1844) -(3262, 4215, 368) -(1659, 810, 1895) -(1103, 4970, 1637) -(3032, 548, 298) -(1100, 4069, 239) -(1590, 1929, 196) -(838, 674, 765) -(746, 2889, 578) -(2071, 1377, 669) -(1512, 3217, 1522) -(405, 3793, 1441) -(157, 4271, 595) -(1265, 4910, 1889) -(4800, 2355, 64) -(2160, 4167, 1723) -(4272, 3418, 1442) -(3153, 3013, 722) -(1724, 798, 1850) -(659, 1414, 620) -(2589, 2801, 993) -(4548, 4370, 252) -(4507, 1714, 1885) -(3162, 3765, 911) -(2569, 1084, 1944) -(2734, 358, 1607) -(2566, 4829, 1774) -(2057, 1808, 121) -(4831, 1421, 1909) -(1925, 3802, 1892) -(534, 4509, 1386) -(3230, 3766, 1718) -(577, 4990, 336) -(2454, 1461, 630) -(2381, 107, 1535) -(1610, 1110, 99) -(599, 1041, 898) -(2559, 2628, 1765) -(618, 4934, 1569) -(4605, 1716, 1546) -(464, 4268, 1419) -(3237, 4153, 585) -(4973, 2641, 1142) -(3343, 4202, 1710) -(1547, 1053, 873) -(4005, 3513, 481) -(3641, 910, 1823) -(1344, 2564, 1459) -(1875, 2848, 312) -(353, 2982, 1587) -(2345, 4275, 810) -(2249, 2984, 629) -(1262, 534, 569) -(4348, 4485, 1584) -(3092, 500, 1170) -(163, 1558, 1986) -(303, 4409, 1103) -(4125, 3294, 761) -(4735, 1971, 1860) -(4891, 4338, 1259) -(2314, 262, 1267) -(64, 301, 991) -(102, 309, 1564) -(585, 2050, 752) -(2106, 1352, 1165) -(119, 3733, 1962) -(1849, 2350, 84) -(1302, 296, 296) -(2168, 2516, 173) -(443, 2495, 690) -(626, 4853, 1388) -(1756, 723, 704) -(1738, 866, 1152) -(600, 318, 1976) -(3497, 3744, 516) -(459, 4369, 899) -(621, 1688, 1203) -(1035, 1551, 173) -(2152, 3937, 251) -(1883, 4399, 490) -(76, 3616, 340) -(765, 4928, 1056) -(259, 1653, 531) -(3745, 3122, 1223) -(1576, 232, 969) -(1968, 4314, 254) -(3977, 412, 1744) -(1996, 1725, 1610) -(3978, 1048, 389) -(1946, 998, 1816) -(3948, 3350, 117) -(400, 3057, 1049) -(1805, 97, 422) -(2485, 3514, 132) -(2371, 1782, 1506) -(1483, 1151, 430) -(2136, 3237, 509) -(224, 2604, 732) -(743, 4216, 953) -(153, 2016, 68) -(4045, 2967, 982) -(2776, 397, 1088) -(1702, 1942, 1752) -(4252, 4871, 902) -(4100, 532, 363) -(2530, 4740, 1938) -(4151, 2514, 1222) -(3758, 822, 724) -(2960, 2721, 1063) -(1175, 1758, 1711) -(4645, 1392, 424) -(3741, 1825, 1112) -(70, 4267, 1090) -(2015, 3406, 1062) -(1802, 975, 1355) -(1270, 4687, 171) -(3114, 108, 1431) -(3030, 2117, 1515) -(1423, 1487, 85) -(50, 1383, 251) -(4754, 4304, 512) -(1902, 2913, 1863) -(1965, 4853, 1216) -(2050, 86, 543) -(1056, 1806, 132) -(4687, 4780, 1977) -(4608, 254, 330) -(3191, 4774, 982) -(2600, 2117, 273) -(3454, 1321, 1897) -(3596, 2627, 297) -(3801, 4599, 562) diff --git a/utils/benchmark/Graph/medium-data b/utils/benchmark/Graph/medium-data deleted file mode 100644 index dd575df6dfa4c..0000000000000 --- a/utils/benchmark/Graph/medium-data +++ /dev/null @@ -1,8004 +0,0 @@ -GRAPH NODES -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -GRAPH EDGES -(316, 956, 278) -(658, 867, 615) -(634, 977, 1992) -(218, 319, 1281) -(395, 388, 869) -(812, 915, 226) -(390, 419, 471) -(746, 696, 1634) -(446, 657, 1142) -(467, 57, 1532) -(55, 872, 756) -(569, 463, 622) -(642, 495, 882) -(271, 19, 1064) -(515, 474, 1184) -(731, 77, 1981) -(277, 653, 1216) -(810, 713, 1286) -(327, 879, 347) -(297, 538, 1368) -(136, 920, 1630) -(563, 348, 1267) -(980, 694, 222) -(581, 601, 1365) -(927, 676, 1933) -(732, 874, 101) -(15, 30, 1375) -(475, 934, 81) -(899, 373, 1704) -(167, 804, 113) -(496, 950, 792) -(852, 635, 948) -(463, 599, 645) -(126, 56, 394) -(273, 367, 855) -(255, 601, 1206) -(973, 962, 206) -(815, 436, 126) -(193, 77, 1547) -(411, 946, 1553) -(889, 175, 953) -(303, 128, 372) -(865, 710, 1909) -(641, 900, 544) -(329, 970, 1832) -(309, 164, 1653) -(916, 508, 1570) -(921, 833, 1304) -(457, 5, 664) -(850, 648, 1557) -(707, 986, 1957) -(301, 704, 1901) -(731, 439, 1358) -(513, 888, 191) -(251, 649, 600) -(957, 413, 681) -(971, 43, 1646) -(577, 871, 671) -(147, 733, 1218) -(169, 930, 1115) -(900, 641, 544) -(334, 274, 1112) -(726, 969, 1682) -(154, 617, 454) -(748, 722, 1688) -(674, 813, 1825) -(437, 863, 759) -(505, 711, 979) -(549, 277, 1245) -(36, 739, 1208) -(392, 22, 1021) -(720, 494, 644) -(900, 961, 180) -(754, 357, 1675) -(225, 660, 1446) -(828, 942, 1686) -(979, 136, 503) -(572, 764, 344) -(895, 658, 955) -(396, 288, 1047) -(91, 931, 1226) -(914, 344, 1420) -(608, 339, 713) -(111, 725, 219) -(19, 644, 827) -(366, 93, 1004) -(314, 937, 1213) -(488, 42, 60) -(83, 960, 209) -(597, 260, 346) -(815, 445, 1455) -(157, 962, 325) -(178, 225, 1816) -(860, 602, 706) -(822, 988, 1725) -(328, 432, 781) -(382, 839, 302) -(915, 362, 196) -(347, 733, 715) -(991, 28, 95) -(719, 955, 239) -(667, 378, 531) -(297, 507, 486) -(889, 113, 1214) -(210, 153, 1348) -(981, 731, 1042) -(139, 456, 1111) -(266, 387, 394) -(177, 288, 1732) -(270, 734, 1533) -(342, 976, 1520) -(128, 615, 309) -(346, 543, 1807) -(149, 799, 805) -(240, 179, 1772) -(551, 407, 1287) -(812, 784, 1636) -(264, 262, 728) -(472, 74, 765) -(548, 384, 1948) -(196, 36, 209) -(26, 399, 572) -(951, 414, 812) -(940, 464, 76) -(514, 319, 1021) -(645, 432, 1197) -(221, 896, 124) -(902, 395, 1957) -(386, 450, 1379) -(164, 216, 1229) -(194, 980, 1948) -(284, 3, 1590) -(855, 425, 1739) -(416, 454, 278) -(896, 327, 395) -(181, 202, 821) -(823, 655, 333) -(55, 122, 1053) -(189, 153, 900) -(176, 677, 1637) -(352, 227, 1883) -(812, 412, 1890) -(705, 382, 891) -(941, 704, 1508) -(943, 172, 393) -(880, 331, 1623) -(505, 400, 524) -(308, 612, 745) -(179, 412, 1129) -(915, 678, 798) -(218, 442, 1922) -(976, 584, 1749) -(664, 60, 1754) -(341, 481, 1961) -(483, 553, 1713) -(505, 257, 83) -(451, 134, 811) -(567, 811, 611) -(694, 779, 999) -(20, 580, 1424) -(111, 944, 191) -(276, 91, 152) -(519, 489, 702) -(103, 788, 240) -(775, 462, 1341) -(652, 129, 1778) -(410, 737, 663) -(634, 547, 1561) -(417, 592, 1224) -(126, 194, 1756) -(435, 292, 326) -(272, 642, 457) -(310, 261, 1044) -(592, 417, 1224) -(901, 697, 1850) -(298, 654, 808) -(888, 429, 141) -(706, 204, 895) -(136, 711, 561) -(812, 167, 1163) -(375, 475, 1888) -(527, 462, 931) -(569, 265, 1983) -(119, 127, 1625) -(4, 781, 1359) -(424, 824, 261) -(645, 458, 535) -(408, 188, 284) -(194, 918, 627) -(110, 727, 1778) -(411, 594, 1465) -(430, 88, 240) -(360, 575, 981) -(752, 860, 714) -(401, 981, 706) -(512, 101, 453) -(787, 665, 871) -(654, 352, 1959) -(526, 669, 409) -(868, 898, 1297) -(851, 257, 831) -(944, 429, 769) -(522, 456, 896) -(892, 24, 1981) -(341, 441, 1091) -(161, 547, 478) -(504, 694, 189) -(402, 569, 881) -(718, 542, 827) -(704, 941, 1508) -(991, 622, 234) -(482, 225, 1483) -(762, 828, 139) -(703, 415, 1337) -(355, 857, 149) -(233, 368, 1209) -(413, 215, 524) -(584, 893, 600) -(697, 620, 539) -(489, 932, 1823) -(843, 853, 703) -(25, 990, 541) -(609, 672, 530) -(947, 893, 1320) -(74, 868, 666) -(781, 454, 1783) -(707, 290, 228) -(546, 518, 1255) -(871, 544, 123) -(457, 889, 1163) -(737, 500, 922) -(804, 261, 195) -(547, 43, 1843) -(806, 170, 456) -(528, 647, 1867) -(59, 454, 1307) -(919, 393, 354) -(426, 213, 1632) -(82, 38, 1281) -(724, 905, 1751) -(615, 834, 1479) -(194, 857, 1464) -(857, 194, 1464) -(397, 980, 895) -(415, 407, 959) -(387, 153, 1757) -(578, 755, 1235) -(6, 360, 1936) -(742, 29, 774) -(481, 341, 1961) -(910, 690, 1388) -(620, 697, 539) -(452, 782, 1530) -(70, 213, 1945) -(53, 131, 220) -(471, 660, 832) -(926, 218, 226) -(3, 284, 1590) -(884, 198, 527) -(977, 428, 1917) -(992, 894, 1289) -(732, 982, 1019) -(338, 584, 1250) -(691, 513, 1073) -(28, 761, 184) -(983, 242, 958) -(819, 385, 1280) -(383, 168, 927) -(826, 628, 1357) -(275, 230, 1721) -(539, 629, 1447) -(611, 576, 1566) -(352, 413, 1620) -(815, 949, 1736) -(9, 585, 1987) -(943, 202, 1059) -(761, 841, 1802) -(567, 718, 418) -(91, 542, 704) -(664, 1, 411) -(60, 449, 590) -(445, 592, 1294) -(422, 216, 982) -(697, 298, 1252) -(853, 884, 1173) -(927, 616, 1493) -(162, 393, 1822) -(436, 314, 1389) -(630, 944, 314) -(846, 856, 1303) -(205, 421, 188) -(155, 106, 463) -(599, 32, 261) -(470, 549, 1221) -(236, 61, 408) -(107, 440, 652) -(456, 368, 1246) -(735, 416, 1550) -(167, 180, 578) -(613, 265, 684) -(61, 92, 208) -(407, 389, 1097) -(172, 193, 1520) -(959, 615, 119) -(411, 846, 911) -(160, 206, 614) -(950, 496, 792) -(505, 425, 608) -(793, 960, 1893) -(113, 867, 1709) -(387, 444, 1245) -(98, 524, 1364) -(335, 274, 1289) -(669, 526, 409) -(928, 542, 1201) -(412, 428, 309) -(318, 876, 1254) -(507, 291, 1502) -(839, 866, 764) -(953, 522, 1991) -(129, 899, 685) -(495, 728, 857) -(593, 892, 1448) -(942, 828, 1686) -(336, 73, 467) -(841, 981, 952) -(154, 957, 1277) -(760, 396, 1828) -(266, 364, 1154) -(195, 414, 604) -(736, 101, 1993) -(584, 513, 638) -(457, 580, 1221) -(350, 115, 1789) -(794, 144, 646) -(335, 575, 334) -(216, 164, 1229) -(923, 316, 404) -(9, 665, 1131) -(945, 292, 1939) -(50, 375, 1044) -(235, 132, 464) -(790, 486, 935) -(58, 979, 865) -(403, 625, 402) -(244, 513, 1398) -(499, 315, 1201) -(706, 362, 717) -(601, 909, 839) -(448, 727, 925) -(797, 766, 691) -(586, 634, 1632) -(878, 483, 1751) -(623, 723, 116) -(534, 831, 1040) -(259, 667, 1415) -(425, 855, 1739) -(484, 86, 308) -(392, 483, 1888) -(444, 841, 178) -(929, 295, 1724) -(452, 231, 83) -(350, 235, 326) -(385, 997, 1352) -(888, 643, 1763) -(775, 261, 1840) -(899, 218, 1784) -(446, 787, 673) -(805, 874, 1411) -(341, 492, 814) -(676, 769, 663) -(676, 927, 1933) -(623, 506, 871) -(550, 814, 991) -(612, 653, 1258) -(573, 647, 1445) -(176, 17, 1386) -(116, 214, 1379) -(852, 984, 149) -(980, 194, 1948) -(658, 712, 560) -(610, 402, 1713) -(794, 485, 100) -(894, 477, 1061) -(291, 507, 1502) -(71, 196, 1572) -(642, 768, 1903) -(755, 578, 1235) -(627, 313, 776) -(510, 927, 1463) -(955, 719, 239) -(416, 550, 1938) -(563, 148, 1003) -(378, 281, 1333) -(745, 401, 1589) -(107, 240, 436) -(613, 985, 996) -(200, 312, 1489) -(881, 390, 724) -(220, 126, 1793) -(20, 3, 1200) -(864, 692, 380) -(441, 204, 1764) -(559, 767, 1182) -(890, 105, 721) -(944, 706, 1786) -(984, 494, 1102) -(985, 480, 1427) -(931, 124, 778) -(523, 854, 301) -(145, 364, 618) -(738, 376, 932) -(548, 777, 1951) -(468, 239, 944) -(867, 814, 1673) -(300, 85, 1800) -(212, 858, 1546) -(858, 212, 1546) -(180, 899, 1315) -(158, 604, 1170) -(382, 707, 1612) -(580, 273, 573) -(632, 942, 1779) -(670, 255, 637) -(546, 268, 1374) -(857, 79, 405) -(470, 988, 1532) -(622, 713, 424) -(58, 876, 649) -(438, 821, 703) -(2, 634, 1879) -(538, 239, 1259) -(739, 111, 1260) -(831, 509, 1082) -(399, 850, 1370) -(230, 614, 905) -(359, 326, 84) -(749, 239, 1245) -(180, 673, 932) -(487, 999, 1041) -(970, 185, 1310) -(453, 659, 356) -(918, 329, 427) -(146, 393, 1415) -(117, 432, 315) -(428, 471, 433) -(799, 149, 805) -(378, 147, 1207) -(651, 924, 1163) -(116, 150, 1087) -(587, 176, 1089) -(143, 828, 1091) -(561, 282, 1615) -(312, 200, 1489) -(989, 658, 479) -(901, 837, 842) -(350, 213, 1301) -(702, 14, 1078) -(261, 241, 1004) -(357, 754, 1675) -(691, 238, 1670) -(768, 642, 1903) -(141, 241, 678) -(473, 379, 185) -(1, 422, 160) -(76, 747, 272) -(203, 501, 1872) -(186, 761, 195) -(216, 422, 982) -(968, 77, 173) -(566, 888, 887) -(290, 754, 1678) -(699, 312, 475) -(358, 219, 990) -(862, 873, 1894) -(684, 556, 780) -(810, 883, 1425) -(555, 714, 1228) -(522, 953, 1991) -(317, 214, 1722) -(580, 757, 844) -(193, 659, 710) -(100, 547, 1099) -(876, 307, 1723) -(363, 565, 543) -(549, 470, 1221) -(513, 932, 530) -(459, 843, 1508) -(254, 331, 136) -(852, 204, 118) -(525, 301, 1732) -(85, 160, 1176) -(982, 406, 1873) -(108, 954, 1867) -(307, 154, 88) -(362, 582, 493) -(861, 778, 533) -(860, 822, 464) -(793, 384, 1807) -(758, 178, 1343) -(942, 512, 1857) -(447, 308, 210) -(981, 401, 706) -(486, 977, 647) -(584, 976, 1749) -(694, 832, 1779) -(272, 103, 1740) -(424, 626, 1718) -(641, 450, 1957) -(2, 733, 1929) -(57, 467, 1532) -(224, 853, 542) -(647, 698, 1676) -(541, 286, 1968) -(193, 176, 1109) -(193, 763, 1696) -(506, 764, 1076) -(342, 110, 929) -(416, 657, 1230) -(219, 42, 1073) -(917, 831, 1575) -(470, 5, 162) -(658, 611, 1400) -(758, 491, 870) -(775, 75, 1107) -(852, 868, 333) -(686, 919, 103) -(800, 834, 1615) -(267, 429, 1418) -(783, 502, 204) -(345, 43, 869) -(292, 435, 326) -(760, 654, 323) -(576, 697, 1524) -(385, 493, 1241) -(23, 997, 348) -(315, 441, 1306) -(854, 782, 1492) -(161, 90, 878) -(143, 93, 357) -(273, 3, 1745) -(567, 544, 1150) -(948, 550, 1077) -(461, 25, 1129) -(434, 472, 1193) -(591, 229, 1145) -(39, 744, 1608) -(996, 128, 822) -(879, 327, 347) -(544, 438, 1295) -(102, 425, 1098) -(297, 629, 685) -(655, 823, 333) -(5, 457, 664) -(418, 616, 1094) -(508, 749, 715) -(952, 892, 738) -(963, 235, 1251) -(6, 675, 1161) -(98, 704, 1715) -(561, 99, 1028) -(874, 852, 1734) -(263, 682, 833) -(141, 169, 1758) -(195, 752, 1672) -(966, 465, 1993) -(723, 170, 842) -(504, 634, 1476) -(742, 557, 1039) -(609, 537, 490) -(543, 448, 1915) -(976, 491, 1886) -(280, 744, 785) -(871, 794, 809) -(100, 712, 1854) -(728, 177, 146) -(290, 347, 1899) -(912, 250, 325) -(609, 823, 54) -(949, 893, 776) -(567, 290, 1658) -(680, 506, 1279) -(167, 812, 1163) -(130, 269, 1793) -(459, 449, 694) -(847, 680, 423) -(461, 872, 1980) -(431, 99, 1321) -(301, 308, 999) -(821, 687, 248) -(267, 51, 1405) -(72, 339, 996) -(676, 989, 474) -(659, 127, 223) -(616, 187, 928) -(917, 880, 1829) -(166, 157, 278) -(612, 360, 1014) -(496, 873, 126) -(278, 108, 1797) -(185, 175, 1732) -(804, 775, 162) -(619, 285, 474) -(378, 31, 879) -(213, 521, 1857) -(749, 508, 715) -(42, 943, 1041) -(148, 584, 1704) -(331, 175, 964) -(495, 46, 1151) -(867, 113, 1709) -(995, 603, 1701) -(372, 347, 1930) -(561, 559, 204) -(321, 258, 1661) -(910, 817, 70) -(268, 340, 451) -(88, 477, 1846) -(597, 800, 1499) -(235, 350, 326) -(606, 302, 558) -(322, 130, 605) -(648, 458, 124) -(957, 64, 621) -(500, 462, 1304) -(852, 874, 1734) -(889, 736, 1324) -(73, 716, 316) -(103, 618, 939) -(877, 595, 1178) -(416, 105, 456) -(859, 447, 1213) -(436, 815, 126) -(453, 887, 710) -(124, 695, 1073) -(3, 46, 395) -(232, 290, 1564) -(798, 59, 597) -(744, 280, 785) -(429, 888, 141) -(47, 441, 248) -(848, 722, 1816) -(677, 269, 1019) -(233, 307, 1009) -(934, 475, 81) -(295, 414, 216) -(791, 165, 579) -(632, 429, 585) -(189, 237, 117) -(634, 586, 1632) -(46, 3, 395) -(248, 625, 1386) -(639, 128, 715) -(424, 859, 339) -(548, 294, 1742) -(733, 347, 715) -(399, 396, 517) -(146, 224, 1649) -(497, 550, 1981) -(478, 26, 139) -(336, 169, 1332) -(100, 210, 1279) -(456, 218, 567) -(284, 393, 1170) -(505, 153, 1121) -(485, 536, 1922) -(548, 826, 1897) -(199, 286, 425) -(755, 470, 120) -(900, 408, 768) -(888, 982, 893) -(444, 441, 1127) -(407, 551, 1287) -(487, 31, 1986) -(17, 840, 94) -(787, 83, 1611) -(986, 707, 1957) -(941, 813, 259) -(314, 608, 1889) -(596, 723, 424) -(6, 959, 823) -(596, 382, 1312) -(816, 956, 528) -(690, 199, 1632) -(191, 918, 127) -(268, 433, 633) -(17, 985, 1533) -(56, 716, 606) -(365, 340, 194) -(459, 915, 730) -(227, 399, 1491) -(172, 943, 393) -(763, 193, 1696) -(713, 244, 846) -(791, 477, 1858) -(34, 159, 713) -(682, 409, 728) -(633, 31, 1802) -(201, 438, 1107) -(84, 455, 1515) -(884, 800, 803) -(884, 157, 1439) -(975, 139, 743) -(789, 127, 841) -(118, 744, 554) -(502, 733, 291) -(744, 118, 554) -(160, 745, 114) -(305, 287, 759) -(344, 597, 456) -(418, 740, 1225) -(628, 880, 1581) -(665, 400, 1537) -(956, 356, 158) -(515, 225, 928) -(722, 748, 1688) -(842, 232, 431) -(648, 850, 1557) -(62, 678, 1048) -(966, 128, 1875) -(255, 524, 484) -(255, 91, 1250) -(918, 194, 627) -(135, 94, 1942) -(293, 738, 1374) -(3, 273, 1745) -(580, 898, 1207) -(557, 830, 1632) -(710, 865, 1909) -(599, 621, 587) -(871, 200, 1118) -(229, 669, 1487) -(81, 770, 1512) -(660, 471, 832) -(625, 403, 402) -(474, 27, 1826) -(402, 780, 364) -(311, 330, 1521) -(316, 418, 1366) -(776, 86, 826) -(850, 69, 63) -(799, 637, 801) -(891, 326, 345) -(763, 835, 490) -(321, 530, 818) -(127, 449, 1884) -(481, 271, 1986) -(738, 241, 466) -(56, 247, 1911) -(402, 360, 530) -(88, 20, 1378) -(727, 667, 167) -(761, 28, 184) -(58, 260, 1743) -(615, 340, 1674) -(452, 541, 763) -(374, 537, 495) -(9, 899, 257) -(677, 592, 959) -(345, 859, 1019) -(792, 396, 1415) -(592, 445, 1294) -(577, 15, 850) -(246, 146, 990) -(46, 495, 1151) -(302, 160, 58) -(342, 673, 1913) -(606, 146, 351) -(438, 544, 1295) -(955, 480, 1420) -(495, 28, 1686) -(78, 369, 1333) -(338, 835, 997) -(48, 255, 169) -(302, 606, 558) -(985, 613, 996) -(654, 665, 1847) -(514, 395, 298) -(516, 333, 1845) -(111, 235, 1565) -(757, 580, 844) -(696, 504, 1955) -(761, 974, 110) -(558, 832, 1835) -(117, 16, 1927) -(9, 191, 931) -(814, 867, 1673) -(356, 543, 110) -(547, 100, 1099) -(456, 921, 1129) -(608, 118, 1954) -(551, 302, 1747) -(885, 663, 835) -(572, 657, 1500) -(244, 728, 1969) -(443, 56, 912) -(100, 748, 676) -(249, 198, 1448) -(319, 815, 196) -(468, 619, 589) -(195, 725, 1557) -(452, 954, 1423) -(565, 19, 1996) -(861, 599, 1392) -(364, 145, 618) -(728, 495, 857) -(384, 548, 1948) -(302, 734, 1650) -(634, 652, 842) -(376, 116, 904) -(653, 310, 448) -(748, 610, 319) -(909, 908, 927) -(995, 241, 1605) -(14, 287, 1554) -(536, 497, 1625) -(955, 505, 1543) -(577, 433, 295) -(231, 403, 985) -(856, 846, 1303) -(779, 694, 999) -(145, 218, 1266) -(91, 255, 1250) -(14, 377, 1150) -(422, 257, 1981) -(573, 592, 244) -(646, 157, 60) -(868, 298, 372) -(806, 877, 1951) -(796, 964, 1615) -(135, 778, 569) -(893, 584, 600) -(468, 373, 1715) -(144, 926, 187) -(715, 949, 1555) -(551, 295, 160) -(607, 849, 491) -(442, 735, 1226) -(656, 944, 636) -(61, 482, 234) -(615, 959, 119) -(483, 198, 1003) -(929, 223, 1718) -(512, 323, 442) -(750, 727, 1158) -(927, 510, 1463) -(364, 707, 1171) -(240, 806, 636) -(112, 65, 1852) -(538, 998, 875) -(923, 53, 269) -(742, 843, 324) -(889, 645, 855) -(896, 30, 335) -(656, 93, 458) -(129, 744, 405) -(343, 318, 120) -(365, 809, 197) -(788, 103, 240) -(86, 484, 308) -(827, 4, 1203) -(60, 910, 153) -(683, 661, 1869) -(423, 60, 724) -(868, 322, 547) -(464, 51, 368) -(86, 489, 289) -(25, 206, 1111) -(233, 167, 820) -(105, 890, 721) -(342, 889, 1930) -(859, 989, 1969) -(843, 459, 1508) -(662, 781, 1225) -(131, 983, 335) -(787, 333, 721) -(150, 975, 1411) -(747, 622, 173) -(961, 900, 180) -(301, 870, 1158) -(893, 577, 615) -(35, 827, 1030) -(126, 605, 1720) -(128, 639, 715) -(889, 150, 988) -(368, 793, 400) -(862, 324, 198) -(592, 275, 1624) -(262, 312, 607) -(828, 537, 1867) -(244, 558, 303) -(309, 80, 288) -(444, 786, 1999) -(672, 936, 141) -(904, 215, 1829) -(964, 979, 1819) -(342, 603, 1816) -(592, 520, 1558) -(609, 686, 420) -(493, 549, 1512) -(186, 329, 450) -(316, 565, 568) -(962, 973, 206) -(373, 426, 1861) -(741, 808, 1491) -(448, 543, 1915) -(392, 502, 716) -(258, 362, 1142) -(804, 287, 414) -(152, 340, 733) -(808, 645, 587) -(533, 348, 534) -(584, 338, 1250) -(519, 884, 604) -(974, 860, 858) -(370, 45, 93) -(782, 135, 1587) -(199, 163, 206) -(231, 198, 568) -(12, 844, 1184) -(507, 396, 568) -(364, 421, 1364) -(535, 579, 1376) -(275, 2, 1574) -(441, 315, 1306) -(665, 654, 1847) -(333, 851, 1357) -(64, 489, 284) -(905, 741, 1380) -(928, 803, 1466) -(577, 143, 248) -(748, 886, 1359) -(750, 952, 1159) -(604, 88, 1276) -(987, 320, 201) -(271, 49, 1048) -(878, 657, 1498) -(327, 125, 1460) -(549, 409, 126) -(795, 175, 146) -(195, 827, 1596) -(816, 104, 920) -(36, 919, 95) -(277, 52, 446) -(986, 55, 226) -(533, 906, 1080) -(550, 600, 1488) -(58, 817, 575) -(605, 169, 835) -(21, 273, 1221) -(868, 852, 333) -(83, 811, 267) -(737, 169, 1418) -(980, 397, 895) -(73, 439, 1302) -(604, 305, 1166) -(125, 861, 632) -(936, 406, 520) -(221, 436, 1269) -(997, 435, 1207) -(213, 758, 1102) -(962, 887, 1169) -(525, 220, 313) -(428, 977, 1917) -(624, 724, 1043) -(253, 78, 659) -(950, 220, 451) -(898, 868, 1297) -(702, 877, 1682) -(793, 368, 400) -(547, 305, 1181) -(559, 397, 546) -(872, 461, 1980) -(818, 57, 352) -(340, 152, 733) -(692, 738, 479) -(166, 102, 1638) -(606, 343, 595) -(960, 83, 209) -(735, 442, 1226) -(285, 1, 529) -(4, 69, 558) -(48, 757, 1736) -(894, 590, 1262) -(723, 717, 664) -(587, 706, 1657) -(767, 522, 749) -(718, 826, 298) -(988, 805, 441) -(493, 385, 1241) -(55, 837, 1096) -(476, 731, 1907) -(81, 956, 1029) -(957, 563, 591) -(688, 41, 1861) -(959, 819, 1664) -(763, 171, 355) -(672, 280, 1197) -(620, 454, 149) -(525, 893, 1266) -(253, 257, 1266) -(73, 336, 467) -(608, 368, 1497) -(348, 515, 1601) -(167, 522, 1953) -(403, 653, 1935) -(701, 590, 1279) -(740, 418, 1225) -(497, 315, 1219) -(963, 981, 1592) -(39, 717, 1871) -(429, 267, 1418) -(506, 623, 871) -(819, 959, 1664) -(91, 276, 152) -(878, 869, 1306) -(590, 894, 1262) -(957, 191, 1546) -(904, 53, 1776) -(43, 547, 1843) -(299, 502, 209) -(452, 716, 773) -(394, 987, 1122) -(881, 314, 126) -(647, 528, 1867) -(510, 914, 1444) -(920, 149, 56) -(811, 83, 267) -(578, 945, 139) -(225, 607, 516) -(9, 410, 1356) -(615, 931, 1915) -(75, 388, 489) -(301, 23, 1064) -(615, 10, 1606) -(310, 653, 448) -(470, 827, 296) -(905, 135, 1408) -(373, 200, 198) -(202, 889, 131) -(349, 967, 1439) -(979, 547, 1624) -(599, 463, 645) -(229, 603, 1862) -(213, 70, 1945) -(880, 540, 1538) -(867, 658, 615) -(565, 716, 222) -(697, 956, 129) -(628, 976, 1125) -(459, 970, 1008) -(477, 487, 989) -(334, 607, 1201) -(300, 539, 769) -(445, 19, 1712) -(945, 458, 1593) -(547, 161, 478) -(569, 985, 361) -(586, 921, 116) -(931, 91, 1226) -(770, 791, 219) -(952, 750, 1159) -(482, 61, 234) -(518, 55, 1424) -(462, 500, 1304) -(210, 373, 1145) -(49, 987, 1369) -(432, 135, 1165) -(842, 165, 995) -(205, 591, 248) -(471, 799, 551) -(475, 375, 1888) -(760, 294, 1458) -(387, 746, 1836) -(686, 174, 702) -(100, 145, 687) -(543, 529, 860) -(983, 131, 335) -(839, 382, 302) -(626, 956, 321) -(842, 705, 1143) -(954, 560, 1715) -(812, 489, 1546) -(152, 618, 1328) -(562, 362, 693) -(228, 317, 1258) -(294, 548, 1742) -(556, 856, 1245) -(733, 901, 866) -(966, 870, 1220) -(399, 227, 1491) -(147, 378, 1207) -(130, 478, 734) -(295, 551, 160) -(595, 632, 1144) -(524, 255, 484) -(899, 9, 257) -(727, 448, 925) -(323, 349, 350) -(36, 20, 1948) -(972, 886, 1651) -(457, 588, 1611) -(441, 343, 423) -(866, 839, 764) -(80, 70, 208) -(318, 343, 120) -(517, 839, 707) -(407, 208, 753) -(462, 944, 326) -(429, 632, 585) -(818, 34, 412) -(910, 851, 1142) -(967, 941, 1761) -(568, 965, 1508) -(91, 993, 270) -(934, 660, 1696) -(514, 958, 147) -(500, 104, 1128) -(85, 300, 1800) -(142, 678, 1256) -(748, 233, 387) -(362, 706, 717) -(400, 145, 1494) -(22, 965, 1099) -(421, 357, 137) -(974, 453, 262) -(537, 374, 495) -(869, 684, 435) -(980, 417, 1880) -(546, 212, 1757) -(802, 74, 1851) -(470, 755, 120) -(804, 314, 1105) -(624, 507, 1919) -(537, 609, 490) -(757, 305, 1155) -(558, 777, 137) -(857, 663, 627) -(317, 506, 264) -(154, 967, 116) -(600, 628, 868) -(304, 17, 1252) -(268, 546, 1374) -(158, 257, 1368) -(810, 876, 1924) -(952, 274, 570) -(308, 139, 1999) -(53, 923, 269) -(826, 311, 1877) -(848, 419, 680) -(922, 611, 668) -(99, 747, 1368) -(557, 912, 71) -(82, 410, 945) -(27, 752, 817) -(780, 402, 364) -(305, 547, 1181) -(203, 256, 347) -(395, 909, 1688) -(221, 677, 537) -(864, 168, 312) -(130, 322, 605) -(943, 42, 1041) -(494, 92, 1136) -(464, 299, 1724) -(54, 487, 1818) -(800, 303, 1383) -(584, 55, 1691) -(369, 724, 491) -(750, 851, 1101) -(569, 709, 594) -(554, 492, 1695) -(38, 213, 1875) -(576, 684, 1512) -(413, 126, 1931) -(577, 563, 363) -(870, 301, 1158) -(939, 127, 891) -(981, 294, 498) -(710, 881, 51) -(223, 929, 1718) -(894, 679, 854) -(324, 862, 198) -(777, 518, 880) -(917, 526, 393) -(40, 78, 1613) -(157, 632, 841) -(689, 615, 131) -(200, 373, 198) -(943, 862, 1898) -(679, 785, 1077) -(699, 758, 1978) -(289, 816, 1068) -(52, 267, 1196) -(471, 148, 1078) -(290, 640, 1729) -(698, 261, 299) -(368, 608, 1497) -(791, 751, 1501) -(332, 11, 1008) -(441, 552, 791) -(869, 10, 99) -(835, 763, 490) -(450, 401, 1931) -(782, 587, 1592) -(89, 509, 1517) -(825, 126, 737) -(644, 19, 827) -(610, 338, 285) -(956, 797, 445) -(166, 796, 896) -(19, 445, 1712) -(409, 682, 728) -(707, 382, 1612) -(622, 747, 173) -(386, 930, 273) -(747, 215, 383) -(488, 392, 955) -(508, 916, 1570) -(969, 670, 413) -(537, 46, 1197) -(986, 619, 1070) -(765, 532, 1522) -(745, 817, 875) -(928, 571, 1002) -(32, 21, 1331) -(975, 150, 1411) -(215, 904, 1829) -(148, 257, 664) -(54, 166, 720) -(495, 353, 1185) -(852, 903, 1795) -(900, 877, 1487) -(407, 34, 220) -(874, 97, 1593) -(359, 657, 630) -(324, 457, 510) -(507, 994, 696) -(619, 986, 1070) -(477, 894, 1061) -(840, 22, 1881) -(95, 732, 268) -(42, 488, 60) -(78, 113, 564) -(810, 886, 1438) -(483, 886, 1351) -(374, 571, 1316) -(124, 842, 458) -(160, 312, 1612) -(378, 261, 458) -(861, 43, 1581) -(259, 495, 322) -(204, 68, 1121) -(575, 738, 1527) -(689, 890, 852) -(997, 385, 1352) -(417, 980, 1880) -(144, 794, 646) -(485, 359, 1864) -(821, 267, 1934) -(77, 461, 378) -(629, 539, 1447) -(151, 481, 861) -(279, 150, 969) -(128, 996, 822) -(220, 525, 313) -(817, 417, 1557) -(854, 101, 1010) -(26, 892, 1842) -(846, 394, 1772) -(915, 812, 226) -(568, 591, 59) -(437, 432, 527) -(845, 19, 592) -(442, 496, 334) -(890, 456, 1901) -(150, 799, 734) -(669, 229, 1487) -(410, 82, 945) -(301, 790, 524) -(214, 149, 1889) -(619, 67, 1768) -(563, 577, 363) -(971, 958, 1837) -(657, 878, 1498) -(239, 742, 62) -(408, 431, 1044) -(385, 865, 347) -(724, 125, 1853) -(13, 310, 661) -(547, 979, 1624) -(782, 597, 312) -(569, 623, 1055) -(454, 620, 149) -(805, 988, 441) -(221, 730, 733) -(681, 793, 230) -(59, 214, 265) -(934, 96, 1518) -(27, 474, 1826) -(918, 446, 1536) -(707, 364, 1171) -(694, 477, 1115) -(910, 990, 1835) -(51, 464, 368) -(766, 791, 1796) -(270, 569, 1169) -(805, 18, 1234) -(94, 861, 397) -(684, 869, 435) -(41, 688, 1861) -(771, 185, 1701) -(238, 691, 1670) -(435, 375, 140) -(764, 506, 1076) -(487, 727, 1571) -(329, 186, 450) -(458, 648, 124) -(185, 80, 459) -(403, 9, 901) -(223, 71, 1895) -(560, 895, 1689) -(577, 951, 885) -(248, 657, 530) -(653, 612, 1258) -(232, 384, 243) -(610, 832, 1127) -(409, 549, 126) -(60, 998, 975) -(54, 73, 441) -(570, 670, 103) -(40, 893, 470) -(863, 119, 1146) -(557, 94, 1418) -(743, 541, 565) -(958, 125, 1331) -(67, 494, 1216) -(140, 981, 452) -(298, 831, 1391) -(751, 791, 1501) -(990, 910, 1835) -(735, 516, 1468) -(39, 966, 1289) -(765, 515, 1693) -(814, 550, 991) -(946, 208, 392) -(765, 128, 368) -(659, 22, 801) -(375, 435, 140) -(990, 25, 541) -(711, 505, 979) -(975, 782, 1353) -(135, 532, 227) -(176, 587, 1089) -(254, 178, 1430) -(770, 443, 533) -(458, 129, 488) -(881, 43, 724) -(937, 662, 799) -(538, 297, 1368) -(204, 741, 337) -(208, 667, 274) -(83, 601, 637) -(128, 966, 1875) -(120, 861, 1789) -(62, 735, 1153) -(151, 247, 464) -(818, 102, 716) -(509, 442, 1864) -(804, 215, 1168) -(990, 315, 1288) -(846, 913, 1123) -(460, 116, 1045) -(832, 949, 1469) -(475, 94, 755) -(941, 312, 337) -(204, 706, 895) -(168, 383, 927) -(710, 481, 1355) -(379, 473, 185) -(213, 38, 1875) -(920, 205, 419) -(43, 821, 100) -(285, 171, 1267) -(312, 804, 600) -(603, 995, 1701) -(603, 342, 1816) -(767, 353, 1164) -(567, 836, 808) -(236, 495, 1805) -(647, 573, 1445) -(726, 493, 1861) -(316, 55, 479) -(917, 283, 1281) -(138, 332, 322) -(528, 255, 903) -(514, 845, 1724) -(924, 741, 1232) -(610, 541, 1729) -(200, 871, 1118) -(864, 937, 1725) -(648, 582, 1333) -(831, 917, 1575) -(996, 609, 1877) -(632, 382, 219) -(29, 742, 774) -(28, 991, 95) -(531, 753, 1011) -(509, 792, 1815) -(808, 908, 1811) -(218, 599, 268) -(415, 703, 1337) -(438, 442, 1073) -(208, 407, 753) -(171, 285, 1267) -(985, 430, 1080) -(83, 719, 1824) -(599, 693, 659) -(284, 385, 1358) -(984, 759, 1038) -(603, 229, 1862) -(680, 498, 175) -(1, 832, 737) -(182, 330, 242) -(554, 291, 1565) -(865, 385, 347) -(6, 203, 560) -(331, 880, 1623) -(353, 341, 729) -(855, 557, 970) -(396, 889, 876) -(213, 426, 1632) -(80, 309, 288) -(716, 867, 1069) -(389, 384, 966) -(817, 58, 575) -(525, 329, 1472) -(674, 78, 1630) -(451, 260, 458) -(696, 746, 1634) -(749, 672, 991) -(933, 707, 99) -(308, 301, 999) -(879, 123, 703) -(368, 555, 91) -(630, 823, 269) -(647, 778, 61) -(578, 95, 584) -(375, 637, 1376) -(946, 411, 1553) -(176, 418, 1829) -(286, 541, 1968) -(785, 321, 1547) -(634, 504, 1476) -(381, 878, 266) -(617, 981, 976) -(844, 461, 697) -(255, 184, 1570) -(906, 754, 1029) -(611, 922, 668) -(353, 505, 1322) -(250, 111, 111) -(949, 815, 1736) -(761, 484, 1853) -(402, 610, 1713) -(348, 125, 1768) -(862, 820, 1505) -(125, 659, 1521) -(421, 318, 1008) -(100, 848, 1609) -(335, 244, 1044) -(379, 324, 241) -(142, 829, 1545) -(127, 659, 223) -(471, 428, 433) -(432, 117, 315) -(883, 810, 1425) -(863, 437, 759) -(629, 338, 751) -(901, 733, 866) -(813, 619, 1354) -(929, 197, 749) -(304, 74, 460) -(127, 939, 891) -(914, 37, 1056) -(400, 104, 344) -(146, 187, 1216) -(55, 578, 1368) -(294, 318, 892) -(334, 812, 1626) -(79, 285, 1625) -(593, 716, 1061) -(657, 923, 287) -(982, 139, 1270) -(504, 285, 819) -(549, 887, 1612) -(967, 40, 489) -(272, 851, 201) -(775, 804, 162) -(809, 365, 197) -(611, 2, 1896) -(77, 791, 1268) -(443, 628, 1301) -(26, 541, 1337) -(338, 610, 285) -(95, 717, 326) -(310, 959, 1328) -(342, 590, 1647) -(878, 59, 774) -(937, 427, 418) -(538, 36, 1815) -(460, 240, 1253) -(745, 504, 303) -(62, 914, 1763) -(157, 197, 286) -(103, 194, 68) -(117, 589, 1025) -(515, 428, 611) -(804, 167, 113) -(601, 581, 1365) -(317, 449, 339) -(665, 274, 1977) -(540, 887, 162) -(888, 16, 847) -(228, 529, 1470) -(410, 9, 1356) -(283, 269, 281) -(191, 908, 1782) -(69, 697, 227) -(135, 117, 1457) -(932, 323, 1135) -(492, 554, 1695) -(574, 761, 720) -(612, 308, 745) -(957, 154, 1277) -(902, 176, 1774) -(65, 238, 1926) -(135, 905, 1408) -(617, 154, 454) -(728, 382, 405) -(285, 359, 1184) -(837, 901, 842) -(396, 507, 568) -(162, 466, 308) -(721, 836, 1872) -(589, 36, 515) -(187, 531, 1596) -(536, 74, 120) -(632, 569, 966) -(717, 777, 1953) -(651, 705, 900) -(402, 289, 1781) -(198, 249, 1448) -(560, 990, 1512) -(217, 949, 277) -(374, 8, 1530) -(59, 0, 868) -(4, 330, 419) -(704, 219, 1588) -(906, 550, 585) -(800, 884, 803) -(582, 569, 1018) -(623, 544, 1539) -(215, 413, 524) -(987, 428, 1348) -(507, 755, 785) -(716, 56, 606) -(536, 505, 639) -(183, 163, 123) -(442, 901, 397) -(96, 997, 1315) -(560, 954, 1715) -(723, 470, 94) -(698, 923, 573) -(104, 400, 344) -(451, 251, 128) -(329, 685, 554) -(65, 505, 1311) -(571, 928, 1002) -(329, 525, 1472) -(53, 948, 51) -(256, 288, 1101) -(193, 172, 1520) -(224, 943, 1803) -(957, 147, 1518) -(832, 558, 1835) -(375, 584, 1973) -(219, 756, 686) -(766, 797, 691) -(468, 960, 1372) -(360, 257, 408) -(658, 989, 479) -(290, 707, 228) -(803, 467, 1104) -(954, 682, 1181) -(591, 205, 248) -(888, 907, 57) -(856, 724, 1713) -(918, 721, 1683) -(551, 236, 636) -(728, 244, 1969) -(194, 103, 68) -(153, 947, 1827) -(296, 805, 926) -(944, 111, 191) -(328, 151, 1586) -(267, 821, 1934) -(204, 385, 560) -(84, 590, 99) -(186, 899, 1566) -(188, 995, 191) -(483, 392, 1888) -(85, 580, 1766) -(432, 437, 527) -(587, 782, 1592) -(684, 810, 1375) -(713, 914, 1901) -(473, 85, 1371) -(664, 576, 88) -(239, 272, 1165) -(431, 334, 1390) -(974, 861, 633) -(4, 448, 1956) -(596, 749, 770) -(832, 694, 1779) -(797, 956, 445) -(827, 112, 1875) -(928, 949, 842) -(230, 680, 1034) -(428, 987, 1348) -(955, 472, 427) -(947, 415, 902) -(731, 476, 1907) -(235, 2, 623) -(778, 906, 1910) -(842, 499, 1064) -(379, 650, 1272) -(774, 835, 1862) -(351, 278, 1339) -(939, 481, 1261) -(650, 219, 1142) -(318, 421, 1008) -(174, 686, 702) -(447, 826, 936) -(892, 26, 1842) -(678, 142, 1256) -(968, 37, 1697) -(145, 100, 687) -(606, 900, 1901) -(939, 612, 1622) -(920, 136, 1630) -(813, 941, 259) -(595, 774, 1769) -(243, 925, 663) -(10, 615, 1606) -(579, 535, 1376) -(448, 51, 182) -(194, 126, 1756) -(640, 332, 308) -(986, 575, 1876) -(74, 536, 120) -(697, 576, 1524) -(734, 302, 1650) -(116, 619, 1793) -(496, 271, 214) -(888, 513, 191) -(378, 667, 531) -(959, 382, 911) -(192, 8, 1735) -(121, 680, 1057) -(871, 546, 1958) -(639, 801, 982) -(358, 627, 941) -(532, 765, 1522) -(569, 272, 1958) -(343, 133, 198) -(932, 489, 1823) -(418, 316, 1366) -(771, 470, 1911) -(720, 356, 1023) -(573, 94, 755) -(595, 49, 1024) -(310, 841, 1380) -(279, 642, 1345) -(745, 342, 1485) -(227, 352, 1883) -(656, 475, 598) -(394, 846, 1772) -(87, 128, 834) -(929, 126, 979) -(695, 26, 1690) -(184, 278, 545) -(353, 767, 1164) -(683, 993, 714) -(22, 392, 1021) -(615, 852, 452) -(716, 565, 222) -(637, 295, 809) -(714, 555, 1228) -(13, 280, 1232) -(514, 722, 90) -(125, 958, 1331) -(241, 971, 1644) -(493, 58, 589) -(874, 805, 1411) -(968, 572, 755) -(795, 167, 1059) -(113, 889, 1214) -(119, 597, 1098) -(113, 413, 1026) -(31, 633, 1802) -(837, 694, 936) -(839, 153, 784) -(808, 741, 1491) -(720, 903, 139) -(19, 565, 1996) -(295, 142, 1228) -(23, 944, 1389) -(628, 443, 1301) -(409, 826, 188) -(543, 356, 110) -(340, 127, 1877) -(359, 429, 1414) -(270, 903, 1820) -(136, 979, 503) -(204, 687, 1881) -(749, 558, 1913) -(955, 516, 1278) -(974, 352, 621) -(595, 621, 1117) -(944, 462, 326) -(817, 539, 1119) -(746, 387, 1836) -(486, 816, 80) -(233, 748, 387) -(677, 771, 632) -(416, 769, 175) -(347, 372, 1930) -(205, 920, 419) -(556, 896, 1495) -(960, 793, 1893) -(302, 551, 1747) -(869, 455, 1053) -(465, 62, 159) -(65, 920, 501) -(43, 861, 1581) -(711, 985, 241) -(322, 761, 768) -(51, 47, 512) -(444, 868, 1595) -(660, 934, 1696) -(457, 324, 510) -(592, 677, 959) -(481, 939, 1261) -(794, 755, 1414) -(724, 624, 1043) -(637, 401, 757) -(677, 176, 1637) -(759, 323, 1679) -(937, 67, 1558) -(342, 745, 1485) -(188, 67, 750) -(426, 306, 1866) -(500, 477, 1035) -(120, 46, 244) -(377, 14, 1150) -(86, 776, 826) -(214, 317, 1722) -(949, 715, 1555) -(45, 370, 93) -(146, 126, 1280) -(827, 35, 1030) -(665, 759, 1795) -(593, 882, 544) -(577, 405, 1115) -(150, 889, 988) -(615, 128, 309) -(174, 5, 82) -(741, 905, 1380) -(656, 926, 1012) -(624, 136, 371) -(329, 918, 427) -(632, 595, 1144) -(53, 904, 1776) -(595, 875, 353) -(431, 408, 1044) -(685, 82, 1656) -(368, 994, 1747) -(910, 307, 132) -(505, 854, 1378) -(198, 325, 1059) -(94, 557, 1418) -(334, 86, 427) -(628, 826, 1357) -(393, 162, 1822) -(956, 881, 1619) -(78, 638, 778) -(993, 91, 270) -(95, 184, 1119) -(93, 883, 1069) -(874, 339, 1593) -(273, 209, 1039) -(948, 477, 887) -(590, 342, 1647) -(597, 500, 132) -(716, 452, 773) -(609, 6, 584) -(537, 828, 1867) -(441, 47, 248) -(745, 609, 79) -(999, 177, 183) -(995, 858, 385) -(49, 271, 1048) -(500, 686, 1797) -(88, 222, 603) -(269, 951, 1094) -(787, 147, 1785) -(182, 173, 158) -(820, 922, 888) -(403, 231, 985) -(564, 970, 1111) -(799, 697, 763) -(941, 80, 152) -(761, 186, 195) -(193, 50, 1226) -(799, 507, 670) -(193, 936, 946) -(68, 204, 1121) -(643, 70, 144) -(252, 539, 1508) -(570, 266, 1061) -(272, 569, 1958) -(41, 486, 632) -(478, 77, 176) -(759, 665, 1795) -(280, 393, 94) -(977, 486, 647) -(79, 127, 1858) -(584, 375, 1973) -(657, 359, 630) -(380, 861, 1605) -(425, 102, 1098) -(846, 129, 1659) -(972, 403, 1332) -(277, 707, 587) -(25, 461, 1129) -(868, 55, 110) -(615, 517, 1601) -(806, 447, 573) -(501, 101, 802) -(980, 307, 1148) -(121, 687, 454) -(30, 740, 384) -(931, 602, 233) -(889, 951, 986) -(517, 615, 1601) -(736, 279, 799) -(996, 278, 1246) -(990, 396, 732) -(404, 428, 951) -(481, 534, 1030) -(245, 96, 1793) -(687, 121, 454) -(500, 597, 132) -(415, 145, 1040) -(407, 620, 1432) -(238, 65, 1926) -(883, 345, 1170) -(900, 803, 1704) -(406, 11, 1601) -(523, 239, 1750) -(145, 415, 1040) -(304, 18, 1934) -(877, 845, 846) -(694, 884, 1873) -(382, 705, 891) -(366, 944, 1773) -(934, 573, 151) -(497, 74, 1483) -(886, 748, 1359) -(548, 410, 292) -(88, 716, 1376) -(356, 720, 1023) -(638, 124, 189) -(939, 594, 815) -(731, 932, 1135) -(808, 818, 717) -(181, 976, 712) -(771, 285, 1020) -(516, 405, 283) -(520, 592, 1558) -(560, 621, 938) -(10, 969, 1143) -(856, 606, 166) -(854, 505, 1378) -(104, 877, 522) -(892, 593, 1448) -(14, 240, 1780) -(731, 981, 1042) -(717, 452, 1584) -(75, 777, 1344) -(781, 876, 1329) -(151, 807, 790) -(810, 684, 1375) -(557, 742, 1039) -(101, 854, 1010) -(174, 352, 1179) -(503, 673, 755) -(967, 636, 454) -(305, 582, 58) -(785, 912, 723) -(199, 93, 575) -(716, 73, 316) -(793, 74, 1588) -(222, 684, 1578) -(546, 622, 1396) -(465, 966, 1993) -(562, 492, 1509) -(46, 229, 1702) -(563, 957, 591) -(447, 492, 1688) -(197, 391, 287) -(769, 676, 663) -(435, 997, 1207) -(238, 59, 913) -(261, 698, 299) -(771, 41, 994) -(81, 185, 889) -(280, 407, 1040) -(836, 610, 623) -(448, 931, 1794) -(236, 551, 636) -(513, 244, 1398) -(712, 658, 560) -(643, 888, 1763) -(695, 595, 587) -(637, 799, 801) -(132, 235, 464) -(722, 194, 348) -(826, 579, 644) -(321, 785, 1547) -(124, 931, 778) -(212, 190, 280) -(34, 407, 220) -(752, 27, 817) -(663, 129, 1025) -(276, 562, 920) -(758, 1, 393) -(407, 280, 1040) -(562, 276, 920) -(817, 745, 875) -(910, 636, 239) -(643, 369, 307) -(713, 622, 424) -(331, 254, 136) -(805, 355, 389) -(728, 643, 835) -(347, 751, 339) -(573, 116, 1375) -(574, 98, 76) -(869, 212, 1531) -(575, 986, 1876) -(190, 214, 1500) -(122, 744, 1609) -(377, 352, 622) -(429, 359, 1414) -(174, 477, 880) -(568, 620, 1416) -(788, 338, 313) -(570, 653, 1629) -(185, 771, 1701) -(665, 9, 1131) -(404, 91, 715) -(667, 727, 167) -(463, 918, 247) -(725, 111, 219) -(822, 860, 464) -(746, 164, 752) -(305, 604, 1166) -(675, 685, 637) -(214, 59, 265) -(483, 372, 158) -(200, 661, 766) -(517, 856, 1148) -(477, 174, 880) -(558, 577, 360) -(26, 478, 139) -(376, 76, 1684) -(502, 299, 209) -(730, 720, 177) -(116, 460, 1045) -(584, 148, 1704) -(586, 195, 1128) -(680, 847, 423) -(329, 1, 1694) -(455, 84, 1515) -(75, 775, 1107) -(884, 567, 61) -(967, 349, 1439) -(80, 671, 926) -(778, 647, 61) -(585, 9, 1987) -(197, 504, 1087) -(659, 453, 356) -(218, 456, 567) -(560, 0, 1390) -(238, 911, 560) -(21, 32, 1331) -(3, 518, 718) -(669, 228, 1314) -(727, 487, 1571) -(817, 964, 979) -(597, 119, 1098) -(378, 719, 1313) -(90, 536, 1996) -(732, 95, 268) -(290, 230, 499) -(915, 339, 900) -(627, 358, 941) -(223, 619, 1203) -(612, 498, 1504) -(723, 666, 1408) -(918, 191, 127) -(151, 328, 1586) -(942, 632, 1779) -(887, 962, 1169) -(528, 988, 253) -(176, 193, 1109) -(657, 248, 530) -(875, 577, 207) -(103, 333, 1045) -(272, 239, 1165) -(765, 521, 1606) -(720, 953, 1936) -(430, 985, 1080) -(919, 749, 1098) -(539, 252, 1508) -(740, 30, 384) -(5, 253, 331) -(119, 863, 1146) -(390, 659, 546) -(48, 577, 968) -(374, 930, 1292) -(30, 15, 1375) -(639, 423, 1108) -(407, 341, 355) -(198, 43, 1120) -(506, 680, 1279) -(925, 243, 663) -(129, 846, 1659) -(421, 205, 188) -(684, 691, 1828) -(456, 522, 896) -(707, 594, 1992) -(504, 834, 1189) -(835, 774, 1862) -(836, 306, 1475) -(903, 720, 139) -(17, 304, 1252) -(914, 62, 1763) -(806, 240, 636) -(383, 458, 1768) -(423, 639, 1108) -(994, 368, 1747) -(188, 408, 284) -(856, 525, 821) -(542, 928, 1201) -(905, 724, 1751) -(194, 722, 348) -(136, 863, 1355) -(341, 407, 355) -(986, 99, 1659) -(531, 187, 1596) -(456, 895, 1818) -(286, 777, 1850) -(871, 348, 1757) -(295, 805, 1576) -(333, 787, 721) -(225, 178, 1816) -(418, 838, 1916) -(449, 459, 694) -(856, 556, 1245) -(202, 943, 1059) -(822, 542, 1067) -(70, 275, 1661) -(146, 992, 434) -(518, 410, 782) -(234, 881, 1282) -(59, 238, 913) -(611, 525, 434) -(102, 166, 1638) -(357, 354, 700) -(949, 673, 671) -(462, 775, 1341) -(454, 59, 1307) -(266, 473, 285) -(838, 323, 636) -(82, 685, 1656) -(129, 663, 1025) -(987, 49, 1369) -(487, 54, 1818) -(795, 150, 145) -(457, 484, 1757) -(998, 60, 975) -(976, 181, 712) -(294, 529, 298) -(74, 802, 1851) -(558, 119, 1435) -(652, 387, 272) -(194, 698, 1044) -(966, 39, 1289) -(605, 536, 126) -(733, 147, 1218) -(145, 906, 453) -(111, 538, 1198) -(295, 845, 1001) -(207, 586, 1068) -(281, 378, 1333) -(698, 999, 853) -(836, 567, 808) -(637, 375, 1376) -(505, 353, 1322) -(675, 6, 1161) -(821, 43, 100) -(718, 567, 418) -(612, 939, 1622) -(222, 953, 129) -(868, 74, 666) -(833, 56, 562) -(906, 990, 829) -(869, 938, 1060) -(727, 362, 1634) -(436, 221, 1269) -(234, 333, 1862) -(452, 260, 1991) -(73, 54, 441) -(572, 968, 755) -(770, 57, 1512) -(931, 448, 1794) -(663, 165, 1746) -(832, 368, 686) -(334, 431, 1390) -(82, 188, 1521) -(484, 761, 1853) -(717, 39, 1871) -(197, 157, 286) -(876, 931, 495) -(437, 25, 105) -(798, 258, 550) -(793, 958, 1870) -(202, 572, 344) -(99, 493, 768) -(797, 990, 883) -(540, 880, 1538) -(63, 166, 1902) -(913, 351, 1588) -(198, 483, 1003) -(36, 538, 1815) -(163, 146, 1615) -(953, 251, 783) -(534, 487, 1056) -(498, 680, 175) -(171, 824, 1716) -(80, 787, 51) -(145, 400, 1494) -(910, 60, 153) -(343, 606, 595) -(254, 800, 430) -(435, 966, 1349) -(493, 99, 768) -(170, 723, 842) -(808, 19, 654) -(653, 149, 1265) -(266, 120, 846) -(441, 444, 1127) -(164, 309, 1653) -(899, 186, 1566) -(297, 8, 616) -(24, 597, 1047) -(505, 955, 1543) -(833, 820, 1033) -(425, 807, 229) -(561, 338, 1710) -(919, 36, 95) -(373, 468, 1715) -(559, 341, 1363) -(341, 955, 829) -(308, 447, 210) -(550, 906, 585) -(536, 485, 1922) -(857, 355, 149) -(849, 607, 491) -(132, 109, 1233) -(260, 58, 1743) -(405, 516, 283) -(134, 535, 747) -(428, 338, 493) -(799, 546, 1757) -(853, 843, 703) -(305, 858, 1350) -(512, 414, 1268) -(126, 825, 737) -(199, 488, 724) -(769, 980, 186) -(934, 46, 1710) -(458, 383, 1768) -(756, 58, 1642) -(9, 403, 901) -(480, 954, 137) -(62, 373, 657) -(743, 321, 95) -(546, 799, 1757) -(600, 550, 1488) -(670, 969, 413) -(759, 984, 1038) -(971, 861, 1366) -(608, 113, 1293) -(119, 678, 153) -(94, 593, 1931) -(175, 453, 167) -(519, 560, 1577) -(720, 743, 155) -(495, 259, 322) -(595, 877, 1178) -(27, 662, 880) -(104, 816, 920) -(12, 54, 1135) -(382, 728, 405) -(143, 396, 756) -(470, 771, 1911) -(424, 811, 196) -(330, 4, 419) -(511, 402, 341) -(518, 390, 1974) -(922, 704, 1047) -(355, 577, 631) -(979, 964, 1819) -(924, 278, 1469) -(49, 628, 926) -(46, 934, 1710) -(178, 519, 1557) -(17, 176, 1386) -(220, 32, 1573) -(384, 873, 245) -(198, 231, 568) -(41, 659, 514) -(755, 794, 1414) -(318, 294, 892) -(121, 413, 1211) -(705, 651, 900) -(344, 567, 1362) -(906, 145, 453) -(658, 857, 85) -(60, 873, 1750) -(280, 559, 1002) -(243, 421, 1764) -(794, 991, 1230) -(944, 630, 314) -(173, 348, 1467) -(197, 929, 749) -(326, 433, 1226) -(662, 27, 880) -(827, 470, 296) -(757, 46, 1197) -(704, 86, 902) -(868, 444, 1595) -(635, 852, 948) -(323, 512, 442) -(303, 995, 1038) -(579, 383, 1301) -(142, 295, 1228) -(176, 902, 1774) -(130, 312, 868) -(818, 808, 717) -(678, 62, 1048) -(415, 831, 577) -(507, 765, 665) -(799, 150, 734) -(85, 47, 1138) -(937, 864, 1725) -(826, 718, 298) -(594, 707, 1992) -(239, 523, 1750) -(480, 985, 1427) -(927, 512, 132) -(906, 778, 1910) -(231, 210, 66) -(620, 568, 1416) -(288, 177, 1732) -(219, 650, 1142) -(323, 649, 984) -(751, 520, 1207) -(312, 130, 868) -(644, 771, 1844) -(958, 793, 1870) -(577, 875, 207) -(196, 71, 1572) -(576, 664, 88) -(306, 426, 1866) -(988, 528, 253) -(936, 193, 946) -(439, 54, 1086) -(80, 948, 1967) -(976, 354, 491) -(723, 596, 424) -(981, 841, 952) -(929, 435, 60) -(213, 874, 1346) -(180, 755, 1626) -(626, 424, 1718) -(1, 285, 529) -(21, 952, 687) -(977, 914, 666) -(289, 511, 652) -(357, 421, 137) -(837, 16, 1264) -(164, 982, 152) -(948, 53, 51) -(967, 251, 1899) -(785, 960, 105) -(202, 181, 821) -(203, 86, 1480) -(521, 765, 1606) -(332, 306, 462) -(830, 531, 1241) -(520, 751, 1207) -(563, 406, 1330) -(836, 856, 188) -(546, 47, 746) -(31, 931, 676) -(659, 833, 453) -(676, 993, 1907) -(733, 261, 1639) -(412, 494, 1722) -(185, 970, 1310) -(812, 981, 127) -(317, 228, 1258) -(846, 842, 1598) -(751, 347, 339) -(887, 540, 162) -(835, 554, 627) -(432, 328, 781) -(767, 122, 1588) -(72, 116, 1297) -(807, 478, 450) -(202, 302, 1452) -(934, 631, 695) -(496, 442, 334) -(757, 48, 1736) -(388, 181, 1975) -(540, 474, 1967) -(541, 452, 763) -(743, 253, 237) -(218, 145, 1266) -(801, 639, 982) -(316, 703, 1391) -(551, 274, 166) -(877, 300, 1362) -(435, 929, 60) -(276, 35, 376) -(274, 665, 1977) -(721, 938, 1940) -(691, 532, 126) -(132, 111, 1132) -(774, 230, 1101) -(317, 362, 1849) -(944, 23, 1389) -(851, 910, 1142) -(393, 919, 354) -(305, 757, 1155) -(325, 687, 185) -(569, 270, 1169) -(424, 594, 1135) -(790, 694, 446) -(129, 458, 488) -(384, 389, 966) -(858, 990, 1817) -(888, 618, 982) -(799, 471, 551) -(687, 204, 1881) -(545, 373, 195) -(191, 957, 1546) -(31, 487, 1986) -(244, 725, 1829) -(163, 183, 123) -(808, 107, 1100) -(919, 823, 738) -(408, 900, 768) -(206, 123, 879) -(761, 77, 1973) -(83, 441, 1292) -(393, 702, 983) -(393, 284, 1170) -(820, 808, 704) -(840, 17, 94) -(470, 97, 1019) -(953, 803, 78) -(273, 46, 372) -(749, 596, 770) -(954, 690, 1691) -(22, 995, 962) -(853, 224, 542) -(261, 804, 195) -(795, 276, 994) -(265, 399, 1083) -(323, 759, 1679) -(506, 317, 264) -(857, 595, 1463) -(932, 592, 603) -(348, 533, 534) -(292, 759, 1097) -(750, 218, 1990) -(403, 972, 1332) -(206, 160, 614) -(425, 937, 373) -(395, 616, 105) -(834, 504, 1189) -(543, 382, 1967) -(730, 659, 632) -(51, 267, 1405) -(164, 746, 752) -(65, 112, 1852) -(165, 842, 995) -(169, 737, 1418) -(520, 855, 1913) -(413, 113, 1026) -(522, 167, 1953) -(522, 752, 1051) -(726, 463, 1876) -(167, 233, 820) -(823, 919, 738) -(322, 823, 664) -(198, 884, 527) -(34, 781, 1862) -(225, 515, 928) -(970, 564, 1111) -(78, 253, 659) -(369, 410, 1422) -(499, 842, 1064) -(456, 890, 1901) -(989, 885, 649) -(871, 425, 68) -(504, 233, 825) -(105, 416, 456) -(79, 805, 55) -(931, 876, 495) -(344, 914, 1420) -(175, 331, 964) -(312, 699, 475) -(153, 633, 548) -(596, 459, 903) -(597, 451, 1893) -(134, 451, 811) -(835, 338, 997) -(580, 491, 1409) -(2, 448, 470) -(362, 727, 1634) -(650, 379, 1272) -(364, 247, 430) -(94, 969, 1938) -(257, 158, 1368) -(458, 124, 1027) -(149, 920, 56) -(296, 676, 1486) -(99, 431, 1321) -(320, 987, 201) -(724, 812, 1270) -(744, 39, 1608) -(175, 185, 1732) -(362, 941, 527) -(732, 316, 537) -(805, 621, 106) -(306, 836, 1475) -(690, 575, 1793) -(636, 13, 557) -(833, 659, 453) -(752, 741, 1780) -(118, 829, 70) -(472, 637, 803) -(273, 580, 573) -(491, 141, 675) -(733, 646, 1001) -(476, 690, 1696) -(424, 269, 573) -(946, 635, 1573) -(741, 752, 1780) -(481, 151, 861) -(851, 272, 201) -(173, 515, 978) -(120, 266, 846) -(413, 352, 1620) -(380, 604, 348) -(61, 236, 408) -(977, 634, 1992) -(314, 881, 126) -(269, 677, 1019) -(278, 924, 1469) -(390, 881, 724) -(159, 385, 1367) -(873, 89, 773) -(375, 50, 1044) -(909, 395, 1688) -(214, 116, 1379) -(253, 892, 728) -(749, 919, 1098) -(861, 125, 632) -(147, 957, 1518) -(537, 146, 296) -(974, 772, 745) -(498, 14, 1811) -(577, 558, 360) -(541, 21, 1931) -(707, 277, 587) -(947, 802, 673) -(947, 153, 1827) -(415, 162, 574) -(58, 493, 589) -(43, 198, 1120) -(30, 896, 335) -(670, 570, 103) -(528, 133, 1751) -(124, 638, 189) -(159, 332, 672) -(109, 132, 1233) -(873, 496, 126) -(960, 785, 105) -(695, 124, 1073) -(318, 522, 1786) -(135, 432, 1165) -(46, 757, 1197) -(450, 386, 1379) -(127, 340, 1877) -(250, 912, 325) -(911, 238, 560) -(126, 146, 1280) -(751, 304, 206) -(184, 95, 1119) -(404, 55, 132) -(426, 427, 680) -(407, 415, 959) -(372, 483, 158) -(284, 458, 666) -(395, 514, 298) -(394, 518, 661) -(235, 963, 1251) -(310, 484, 921) -(845, 295, 1001) -(721, 918, 1683) -(294, 760, 1458) -(985, 17, 1533) -(617, 754, 309) -(944, 366, 1773) -(434, 410, 1748) -(11, 332, 1008) -(837, 509, 183) -(451, 334, 793) -(866, 476, 803) -(749, 726, 67) -(2, 275, 1574) -(722, 976, 1364) -(222, 675, 1002) -(960, 686, 1900) -(858, 473, 1664) -(268, 32, 746) -(814, 807, 603) -(104, 500, 1128) -(684, 576, 1512) -(255, 792, 1326) -(0, 735, 1518) -(241, 695, 1267) -(330, 311, 1521) -(441, 341, 1091) -(756, 559, 1635) -(116, 356, 464) -(889, 472, 569) -(409, 188, 237) -(636, 910, 239) -(366, 971, 1416) -(621, 663, 683) -(570, 823, 181) -(954, 480, 137) -(222, 55, 604) -(738, 692, 479) -(523, 401, 244) -(360, 402, 530) -(273, 21, 1221) -(491, 580, 1409) -(274, 43, 185) -(827, 195, 1596) -(311, 82, 906) -(188, 82, 1521) -(445, 519, 931) -(194, 777, 312) -(871, 577, 671) -(290, 195, 1558) -(124, 458, 1027) -(344, 645, 616) -(127, 79, 1858) -(199, 690, 1632) -(369, 643, 307) -(826, 409, 188) -(561, 492, 1165) -(960, 468, 1372) -(212, 869, 1531) -(754, 906, 1029) -(569, 632, 966) -(415, 490, 1608) -(951, 889, 986) -(680, 121, 1057) -(945, 676, 1605) -(511, 806, 1227) -(36, 196, 209) -(494, 720, 644) -(432, 463, 400) -(577, 279, 1991) -(59, 798, 597) -(409, 133, 1443) -(873, 419, 728) -(30, 136, 1481) -(433, 628, 1077) -(929, 623, 1154) -(877, 806, 1951) -(532, 135, 227) -(201, 43, 1669) -(232, 842, 431) -(206, 25, 1111) -(828, 762, 139) -(177, 999, 183) -(243, 215, 546) -(351, 862, 884) -(962, 910, 1693) -(941, 362, 527) -(912, 785, 723) -(125, 348, 1768) -(568, 115, 675) -(182, 728, 1796) -(74, 497, 1483) -(972, 640, 1988) -(239, 468, 944) -(478, 807, 450) -(421, 364, 1364) -(956, 316, 278) -(633, 153, 548) -(869, 878, 1306) -(874, 213, 1346) -(770, 81, 1512) -(637, 472, 803) -(108, 208, 982) -(46, 537, 1197) -(348, 871, 1757) -(165, 791, 579) -(495, 346, 91) -(208, 108, 982) -(886, 483, 1351) -(530, 83, 1237) -(604, 380, 348) -(725, 66, 1737) -(175, 889, 953) -(52, 277, 446) -(89, 517, 304) -(453, 44, 120) -(536, 90, 1996) -(576, 588, 1624) -(974, 59, 662) -(723, 194, 1737) -(33, 761, 1903) -(547, 634, 1561) -(143, 577, 248) -(420, 893, 617) -(756, 940, 900) -(777, 558, 137) -(43, 971, 1646) -(924, 651, 1163) -(796, 240, 1292) -(998, 284, 870) -(546, 373, 1767) -(296, 746, 372) -(657, 158, 905) -(70, 544, 1241) -(324, 379, 241) -(362, 562, 693) -(256, 203, 347) -(419, 521, 629) -(536, 146, 888) -(334, 451, 793) -(488, 199, 724) -(579, 826, 644) -(565, 363, 543) -(330, 734, 931) -(395, 902, 1957) -(825, 444, 1261) -(694, 980, 222) -(60, 664, 1754) -(953, 222, 129) -(295, 929, 1724) -(352, 377, 622) -(352, 174, 1179) -(586, 326, 1730) -(444, 758, 946) -(601, 135, 1701) -(945, 578, 139) -(251, 967, 1899) -(178, 758, 1343) -(948, 713, 89) -(154, 124, 1756) -(823, 609, 54) -(792, 509, 1815) -(396, 792, 1415) -(775, 616, 1752) -(831, 415, 577) -(924, 984, 305) -(176, 646, 1442) -(303, 56, 193) -(140, 622, 1650) -(168, 919, 404) -(113, 608, 1293) -(274, 334, 1112) -(224, 146, 1649) -(8, 297, 616) -(634, 357, 1895) -(202, 526, 1931) -(286, 773, 1036) -(285, 771, 1020) -(504, 197, 1087) -(162, 728, 699) -(312, 786, 889) -(644, 350, 692) -(112, 583, 815) -(367, 273, 855) -(242, 983, 958) -(96, 822, 127) -(336, 400, 1270) -(778, 75, 850) -(338, 428, 493) -(283, 238, 1979) -(119, 627, 1294) -(214, 190, 1500) -(505, 536, 639) -(253, 138, 1463) -(231, 8, 1758) -(69, 717, 1712) -(384, 241, 843) -(315, 990, 1288) -(851, 333, 1357) -(780, 298, 168) -(599, 429, 295) -(912, 557, 71) -(322, 868, 547) -(219, 704, 1588) -(861, 380, 1605) -(555, 561, 1587) -(629, 960, 1145) -(116, 376, 904) -(777, 130, 1257) -(635, 946, 1573) -(561, 555, 1587) -(965, 568, 1508) -(692, 864, 380) -(987, 711, 582) -(453, 175, 167) -(880, 917, 1829) -(990, 560, 1512) -(148, 563, 1003) -(405, 577, 1115) -(187, 616, 928) -(721, 301, 1560) -(99, 986, 1659) -(78, 674, 1630) -(447, 28, 1690) -(486, 41, 632) -(253, 743, 237) -(476, 866, 803) -(285, 504, 819) -(836, 721, 1872) -(441, 83, 1292) -(463, 726, 1876) -(173, 795, 741) -(373, 62, 657) -(46, 140, 355) -(28, 495, 1686) -(267, 52, 1196) -(516, 955, 1278) -(308, 338, 325) -(680, 283, 1977) -(893, 971, 147) -(755, 180, 1626) -(149, 653, 1265) -(439, 786, 1428) -(258, 794, 1443) -(832, 1, 737) -(959, 6, 823) -(887, 549, 1612) -(194, 723, 1737) -(781, 120, 1666) -(215, 243, 546) -(805, 295, 1576) -(933, 242, 1470) -(932, 846, 1924) -(518, 3, 718) -(595, 857, 1463) -(577, 806, 337) -(162, 415, 574) -(616, 775, 1752) -(266, 570, 1061) -(124, 263, 722) -(51, 97, 1903) -(307, 980, 1148) -(841, 761, 1802) -(970, 329, 1832) -(110, 342, 929) -(774, 595, 1769) -(591, 269, 204) -(175, 795, 146) -(669, 30, 1570) -(255, 528, 903) -(602, 668, 1667) -(968, 319, 1919) -(641, 719, 1072) -(106, 155, 463) -(577, 893, 615) -(613, 3, 985) -(611, 307, 981) -(349, 376, 1077) -(673, 238, 878) -(799, 575, 1209) -(232, 207, 1901) -(765, 507, 665) -(827, 551, 847) -(608, 314, 1889) -(675, 222, 1002) -(79, 793, 1968) -(596, 564, 1489) -(82, 484, 1847) -(49, 245, 1761) -(626, 178, 1083) -(240, 14, 1780) -(861, 120, 1789) -(739, 36, 1208) -(195, 586, 1128) -(71, 223, 1895) -(889, 202, 131) -(873, 384, 245) -(340, 217, 1997) -(105, 609, 1646) -(791, 563, 981) -(876, 781, 1329) -(676, 945, 1605) -(18, 805, 1234) -(899, 180, 1315) -(645, 344, 616) -(472, 955, 427) -(906, 533, 1080) -(781, 765, 458) -(678, 915, 798) -(545, 953, 432) -(725, 963, 294) -(931, 615, 1915) -(127, 657, 1549) -(952, 21, 687) -(866, 117, 828) -(184, 255, 1570) -(494, 412, 1722) -(810, 997, 278) -(663, 621, 683) -(209, 137, 1061) -(191, 9, 931) -(304, 521, 1265) -(945, 541, 1230) -(734, 270, 1533) -(531, 676, 1095) -(74, 793, 1588) -(222, 831, 1289) -(613, 32, 514) -(740, 952, 693) -(998, 538, 875) -(128, 765, 368) -(32, 599, 261) -(783, 305, 1146) -(642, 272, 457) -(379, 665, 812) -(368, 645, 1342) -(257, 505, 83) -(539, 341, 1006) -(850, 399, 1370) -(8, 374, 1530) -(741, 204, 337) -(427, 937, 418) -(500, 737, 922) -(46, 120, 244) -(920, 40, 992) -(765, 171, 1853) -(88, 430, 240) -(433, 326, 1226) -(205, 983, 747) -(132, 285, 1088) -(402, 511, 341) -(739, 999, 190) -(43, 345, 869) -(203, 210, 136) -(743, 610, 682) -(314, 436, 1389) -(157, 646, 60) -(746, 296, 372) -(305, 712, 1365) -(56, 303, 193) -(604, 158, 1170) -(943, 224, 1803) -(910, 962, 1693) -(312, 262, 607) -(767, 521, 354) -(494, 984, 1102) -(403, 939, 1254) -(484, 503, 725) -(198, 812, 1643) -(943, 712, 1253) -(560, 519, 1577) -(341, 48, 946) -(329, 965, 1474) -(255, 670, 637) -(952, 704, 435) -(607, 735, 372) -(719, 378, 1313) -(3, 613, 985) -(940, 629, 1065) -(228, 669, 1314) -(480, 955, 1420) -(887, 453, 710) -(7, 992, 1498) -(133, 343, 198) -(969, 94, 1938) -(725, 244, 1829) -(914, 977, 666) -(38, 451, 586) -(859, 424, 339) -(239, 749, 1245) -(280, 13, 1232) -(761, 33, 1903) -(941, 296, 1515) -(854, 523, 301) -(563, 791, 981) -(178, 254, 1430) -(363, 627, 1130) -(721, 745, 1717) -(491, 976, 1886) -(148, 922, 1366) -(148, 471, 1078) -(331, 875, 103) -(940, 667, 613) -(778, 135, 569) -(193, 574, 1058) -(260, 328, 1016) -(217, 615, 377) -(428, 515, 611) -(414, 195, 604) -(612, 867, 438) -(349, 323, 350) -(691, 684, 1828) -(399, 766, 808) -(545, 521, 166) -(485, 350, 1693) -(489, 64, 284) -(824, 424, 261) -(881, 838, 296) -(754, 290, 1678) -(384, 793, 1807) -(642, 61, 442) -(702, 393, 983) -(316, 732, 537) -(163, 709, 610) -(498, 612, 1504) -(409, 775, 298) -(102, 323, 60) -(32, 613, 514) -(842, 846, 1598) -(606, 382, 1712) -(326, 891, 345) -(257, 768, 651) -(369, 78, 1333) -(646, 176, 1442) -(58, 756, 1642) -(962, 560, 1724) -(745, 160, 114) -(446, 778, 60) -(104, 141, 920) -(726, 749, 67) -(802, 169, 396) -(291, 554, 1565) -(937, 425, 373) -(2, 545, 616) -(131, 53, 220) -(149, 214, 1889) -(541, 610, 1729) -(686, 960, 1900) -(526, 917, 393) -(505, 34, 1410) -(413, 121, 1211) -(396, 151, 211) -(345, 408, 1786) -(607, 225, 516) -(937, 314, 1213) -(956, 626, 321) -(985, 569, 361) -(586, 742, 1667) -(150, 279, 969) -(887, 42, 85) -(591, 987, 1773) -(606, 87, 980) -(781, 4, 1359) -(653, 403, 1935) -(964, 817, 979) -(737, 58, 885) -(634, 988, 1386) -(255, 652, 1215) -(982, 732, 1019) -(411, 870, 922) -(85, 871, 216) -(301, 874, 645) -(433, 913, 1797) -(712, 943, 1253) -(261, 733, 1639) -(845, 877, 846) -(848, 100, 1609) -(938, 807, 1274) -(889, 342, 1930) -(169, 336, 1332) -(429, 944, 769) -(744, 122, 1609) -(438, 347, 773) -(765, 812, 944) -(286, 199, 425) -(570, 569, 988) -(329, 356, 1083) -(384, 388, 379) -(130, 184, 528) -(683, 546, 628) -(7, 354, 993) -(201, 849, 1419) -(609, 610, 856) -(341, 559, 1363) -(766, 399, 808) -(971, 366, 1416) -(659, 390, 546) -(161, 590, 1134) -(241, 331, 960) -(623, 569, 1055) -(993, 676, 1907) -(549, 493, 1512) -(116, 573, 1375) -(136, 30, 1481) -(65, 104, 87) -(504, 696, 1955) -(926, 144, 187) -(710, 694, 1092) -(877, 702, 1682) -(927, 230, 712) -(952, 740, 693) -(677, 221, 537) -(287, 318, 1552) -(111, 250, 111) -(385, 159, 1367) -(495, 236, 1805) -(354, 976, 491) -(328, 260, 1016) -(997, 810, 278) -(464, 20, 740) -(525, 56, 1547) -(601, 255, 1206) -(397, 559, 546) -(162, 491, 1989) -(932, 731, 1135) -(752, 306, 255) -(572, 117, 148) -(899, 479, 951) -(756, 391, 1456) -(518, 546, 1255) -(61, 642, 442) -(299, 230, 1986) -(119, 577, 1529) -(338, 159, 890) -(636, 967, 454) -(182, 510, 1969) -(66, 725, 1737) -(621, 595, 1117) -(418, 176, 1829) -(55, 222, 604) -(790, 23, 1848) -(673, 949, 671) -(239, 538, 1259) -(154, 829, 1335) -(484, 81, 907) -(953, 720, 1936) -(470, 723, 94) -(180, 167, 578) -(609, 105, 1646) -(373, 210, 1145) -(634, 2, 1879) -(120, 725, 1736) -(538, 111, 1198) -(191, 42, 1952) -(908, 808, 1811) -(401, 450, 1931) -(885, 989, 649) -(247, 565, 1178) -(16, 837, 1264) -(990, 858, 1817) -(697, 799, 763) -(275, 592, 1624) -(274, 952, 570) -(132, 847, 1722) -(313, 627, 776) -(575, 335, 334) -(766, 152, 1615) -(415, 947, 902) -(908, 191, 1782) -(442, 438, 1073) -(624, 244, 487) -(861, 526, 1216) -(343, 441, 423) -(458, 227, 234) -(222, 88, 603) -(133, 409, 1443) -(759, 292, 1097) -(443, 503, 484) -(135, 782, 1587) -(368, 392, 604) -(356, 329, 1083) -(141, 104, 920) -(393, 146, 1415) -(752, 195, 1672) -(384, 232, 243) -(40, 920, 992) -(893, 949, 776) -(645, 889, 855) -(769, 687, 691) -(991, 794, 1230) -(163, 199, 206) -(140, 298, 446) -(507, 297, 486) -(89, 873, 773) -(806, 174, 164) -(578, 55, 1368) -(921, 944, 1602) -(867, 588, 339) -(278, 184, 545) -(685, 675, 637) -(979, 271, 1488) -(686, 659, 973) -(577, 119, 1529) -(582, 351, 326) -(361, 105, 176) -(643, 18, 82) -(521, 419, 629) -(257, 422, 1981) -(477, 88, 1846) -(995, 519, 1190) -(151, 396, 211) -(399, 265, 1083) -(467, 884, 1650) -(412, 179, 1129) -(502, 392, 716) -(469, 377, 83) -(326, 586, 1730) -(20, 464, 740) -(546, 683, 628) -(6, 609, 584) -(939, 617, 903) -(976, 628, 1125) -(174, 806, 164) -(80, 185, 459) -(177, 728, 146) -(765, 823, 1958) -(558, 244, 303) -(535, 908, 1006) -(376, 349, 1077) -(295, 637, 809) -(388, 75, 489) -(118, 478, 156) -(511, 289, 652) -(541, 945, 1230) -(28, 447, 1690) -(302, 202, 1452) -(582, 648, 1333) -(605, 126, 1720) -(401, 637, 757) -(953, 184, 1151) -(511, 677, 1212) -(827, 44, 686) -(623, 803, 500) -(807, 151, 790) -(406, 563, 1330) -(748, 397, 1634) -(852, 615, 452) -(708, 377, 859) -(410, 548, 292) -(563, 534, 389) -(712, 305, 1365) -(487, 534, 1056) -(897, 990, 871) -(589, 117, 1025) -(238, 29, 535) -(866, 263, 1784) -(918, 803, 452) -(265, 613, 684) -(649, 251, 600) -(406, 215, 278) -(111, 132, 1132) -(375, 593, 1310) -(104, 65, 87) -(711, 987, 582) -(433, 576, 388) -(529, 747, 72) -(569, 582, 1018) -(241, 88, 1511) -(477, 791, 1858) -(667, 259, 1415) -(990, 797, 883) -(347, 290, 1899) -(830, 557, 1632) -(339, 874, 1593) -(963, 725, 294) -(443, 770, 533) -(913, 433, 1797) -(768, 257, 651) -(115, 568, 675) -(497, 591, 1421) -(26, 695, 1690) -(541, 26, 1337) -(312, 941, 337) -(919, 686, 103) -(987, 394, 1122) -(492, 561, 1165) -(215, 804, 1168) -(661, 683, 1869) -(332, 138, 322) -(886, 810, 1438) -(338, 788, 313) -(617, 236, 1440) -(758, 699, 1978) -(339, 72, 996) -(391, 756, 1456) -(964, 796, 1615) -(367, 737, 764) -(881, 234, 1282) -(812, 198, 1643) -(350, 8, 1920) -(775, 409, 298) -(45, 305, 1602) -(230, 290, 499) -(308, 82, 1436) -(729, 456, 1700) -(540, 645, 81) -(153, 189, 900) -(137, 768, 316) -(993, 683, 714) -(51, 496, 1907) -(876, 58, 649) -(859, 345, 1019) -(660, 225, 1446) -(988, 822, 1725) -(111, 65, 972) -(184, 953, 1151) -(665, 333, 1861) -(958, 970, 1174) -(261, 378, 458) -(843, 742, 324) -(703, 714, 674) -(566, 966, 80) -(843, 689, 1597) -(777, 75, 1344) -(108, 278, 1797) -(489, 812, 1546) -(99, 965, 1945) -(74, 95, 1033) -(187, 865, 1086) -(956, 81, 1029) -(495, 343, 1884) -(995, 22, 962) -(614, 230, 905) -(994, 612, 1379) -(229, 332, 1113) -(450, 641, 1957) -(315, 499, 1201) -(287, 876, 1786) -(697, 205, 577) -(492, 447, 1688) -(654, 298, 808) -(974, 629, 219) -(668, 602, 1667) -(135, 601, 1701) -(64, 957, 621) -(284, 998, 870) -(673, 180, 932) -(340, 365, 194) -(396, 399, 517) -(91, 404, 715) -(967, 154, 116) -(458, 945, 1593) -(592, 932, 603) -(737, 410, 663) -(167, 795, 1059) -(260, 452, 1991) -(795, 140, 1274) -(444, 387, 1245) -(725, 195, 1557) -(229, 46, 1702) -(158, 657, 905) -(141, 477, 328) -(217, 340, 1997) -(627, 119, 1294) -(425, 871, 68) -(524, 98, 1364) -(762, 501, 1519) -(781, 567, 1131) -(140, 795, 1274) -(56, 126, 394) -(325, 198, 1059) -(204, 441, 1764) -(823, 765, 1958) -(2, 235, 623) -(441, 492, 381) -(277, 419, 202) -(849, 98, 235) -(400, 505, 524) -(266, 254, 1913) -(462, 527, 931) -(686, 500, 1797) -(811, 146, 692) -(896, 556, 1495) -(588, 457, 1611) -(550, 656, 241) -(399, 26, 572) -(493, 726, 1861) -(519, 995, 1190) -(574, 193, 1058) -(575, 360, 981) -(704, 922, 1047) -(544, 623, 1539) -(743, 129, 1795) -(618, 103, 939) -(693, 599, 659) -(766, 183, 1773) -(768, 818, 761) -(808, 820, 704) -(436, 29, 1312) -(113, 629, 734) -(662, 937, 799) -(455, 869, 1053) -(370, 723, 1479) -(777, 548, 1951) -(290, 232, 1564) -(778, 256, 1292) -(778, 861, 533) -(948, 80, 1967) -(428, 649, 1843) -(417, 514, 1733) -(1, 664, 411) -(843, 177, 1689) -(495, 642, 882) -(333, 516, 1845) -(0, 59, 868) -(543, 346, 1807) -(690, 954, 1691) -(784, 801, 1915) -(931, 722, 534) -(127, 119, 1625) -(348, 173, 1467) -(350, 644, 692) -(645, 540, 81) -(666, 198, 1107) -(61, 922, 1420) -(260, 574, 1624) -(483, 878, 1751) -(908, 174, 1544) -(504, 745, 303) -(85, 473, 1371) -(340, 268, 451) -(43, 201, 1669) -(8, 350, 1920) -(607, 334, 1201) -(865, 187, 1086) -(593, 94, 1931) -(21, 541, 1931) -(19, 808, 654) -(652, 255, 1215) -(67, 937, 1558) -(619, 116, 1793) -(893, 525, 1266) -(640, 393, 1815) -(876, 810, 1924) -(678, 721, 1252) -(305, 783, 1146) -(278, 711, 896) -(37, 968, 1697) -(467, 803, 1104) -(995, 303, 1038) -(407, 421, 1968) -(559, 280, 1002) -(599, 218, 268) -(525, 611, 434) -(985, 325, 1547) -(550, 416, 1938) -(74, 505, 1387) -(510, 182, 1969) -(996, 60, 447) -(995, 188, 191) -(282, 561, 1615) -(279, 577, 1991) -(247, 364, 430) -(393, 933, 409) -(599, 294, 1663) -(285, 79, 1625) -(954, 108, 1867) -(228, 474, 806) -(236, 277, 174) -(933, 393, 409) -(458, 645, 535) -(38, 82, 1281) -(991, 200, 593) -(847, 130, 1512) -(150, 795, 145) -(190, 212, 280) -(671, 80, 926) -(509, 837, 183) -(452, 717, 1584) -(306, 752, 255) -(201, 75, 1340) -(463, 569, 622) -(598, 510, 858) -(135, 968, 1517) -(616, 211, 979) -(489, 86, 289) -(895, 456, 1818) -(736, 794, 157) -(515, 173, 978) -(274, 335, 1289) -(768, 137, 316) -(448, 4, 1956) -(80, 189, 1088) -(278, 944, 342) -(373, 899, 1704) -(709, 569, 594) -(636, 527, 534) -(685, 375, 1213) -(987, 907, 931) -(694, 61, 124) -(629, 497, 1677) -(20, 36, 1948) -(298, 159, 1818) -(444, 543, 1150) -(375, 415, 191) -(31, 378, 879) -(821, 438, 703) -(255, 48, 169) -(717, 69, 1712) -(992, 7, 1498) -(908, 909, 927) -(481, 83, 618) -(120, 781, 1666) -(542, 112, 1009) -(266, 464, 1266) -(907, 888, 57) -(445, 815, 1455) -(913, 846, 1123) -(842, 124, 458) -(328, 911, 486) -(219, 381, 697) -(438, 468, 1003) -(791, 766, 1796) -(984, 656, 1244) -(280, 637, 196) -(461, 77, 378) -(390, 518, 1974) -(690, 56, 1792) -(874, 301, 645) -(527, 373, 538) -(571, 374, 1316) -(602, 860, 706) -(640, 972, 1988) -(733, 502, 291) -(983, 205, 747) -(831, 534, 1040) -(990, 906, 829) -(314, 804, 1105) -(350, 485, 1693) -(261, 310, 1044) -(3, 557, 1827) -(525, 856, 821) -(687, 769, 691) -(247, 56, 1911) -(653, 277, 1216) -(712, 100, 1854) -(714, 703, 674) -(767, 559, 1182) -(145, 435, 145) -(580, 85, 1766) -(437, 704, 1577) -(332, 640, 308) -(866, 31, 1460) -(594, 424, 1135) -(486, 790, 935) -(98, 574, 76) -(66, 289, 616) -(704, 98, 1715) -(154, 885, 1554) -(340, 615, 1674) -(489, 702, 1344) -(454, 781, 1783) -(880, 628, 1581) -(791, 77, 1268) -(265, 210, 536) -(939, 403, 1254) -(81, 484, 907) -(597, 782, 312) -(999, 739, 190) -(356, 956, 158) -(949, 928, 842) -(34, 818, 412) -(2, 611, 1896) -(74, 304, 460) -(823, 630, 269) -(75, 201, 1340) -(183, 766, 1773) -(353, 495, 1185) -(62, 465, 159) -(357, 634, 1895) -(558, 749, 1913) -(205, 866, 1642) -(396, 760, 1828) -(932, 513, 530) -(149, 281, 1434) -(298, 868, 372) -(464, 266, 1266) -(266, 906, 1629) -(512, 942, 1857) -(640, 216, 192) -(489, 278, 251) -(730, 844, 509) -(884, 519, 604) -(224, 16, 984) -(459, 596, 903) -(615, 689, 131) -(139, 308, 1999) -(714, 194, 518) -(346, 495, 91) -(91, 151, 407) -(897, 344, 1352) -(863, 773, 857) -(884, 694, 1873) -(59, 974, 662) -(451, 597, 1893) -(527, 636, 534) -(92, 321, 1784) -(621, 560, 938) -(19, 845, 592) -(166, 634, 781) -(285, 619, 474) -(80, 941, 152) -(796, 166, 896) -(725, 120, 1736) -(185, 81, 889) -(211, 616, 979) -(70, 643, 144) -(392, 368, 604) -(380, 881, 1043) -(414, 512, 1268) -(881, 956, 1619) -(860, 752, 714) -(863, 868, 890) -(112, 542, 1009) -(882, 593, 544) -(518, 394, 661) -(137, 209, 1061) -(723, 539, 961) -(634, 166, 781) -(882, 556, 694) -(269, 424, 573) -(304, 751, 206) -(456, 157, 867) -(0, 620, 327) -(976, 722, 1364) -(799, 695, 1544) -(657, 446, 1142) -(5, 585, 76) -(10, 869, 99) -(484, 457, 1757) -(339, 915, 900) -(691, 166, 1573) -(620, 0, 327) -(692, 917, 1598) -(784, 660, 524) -(418, 372, 729) -(76, 376, 1684) -(477, 694, 1115) -(965, 22, 1099) -(745, 721, 1717) -(283, 680, 1977) -(778, 892, 687) -(656, 984, 1244) -(253, 5, 331) -(805, 296, 926) -(761, 67, 290) -(833, 921, 1304) -(575, 690, 1793) -(26, 122, 581) -(300, 877, 1362) -(271, 481, 1986) -(340, 225, 1995) -(431, 351, 611) -(288, 396, 1047) -(507, 624, 1919) -(368, 832, 686) -(717, 723, 664) -(997, 23, 348) -(874, 732, 101) -(304, 199, 1884) -(639, 348, 1802) -(397, 748, 1634) -(659, 41, 514) -(1, 758, 393) -(914, 812, 669) -(205, 697, 577) -(258, 885, 294) -(888, 592, 1011) -(856, 836, 188) -(528, 737, 1938) -(910, 545, 420) -(359, 485, 1864) -(901, 673, 1772) -(78, 40, 1613) -(505, 551, 1348) -(388, 384, 379) -(635, 992, 1412) -(686, 732, 1986) -(393, 640, 1815) -(416, 735, 1550) -(748, 782, 1419) -(287, 305, 759) -(982, 164, 152) -(287, 804, 414) -(220, 950, 451) -(791, 770, 219) -(832, 610, 1127) -(278, 996, 1246) -(355, 348, 1531) -(690, 476, 1696) -(659, 193, 710) -(606, 856, 166) -(348, 563, 1267) -(396, 990, 732) -(55, 868, 110) -(546, 871, 1958) -(522, 318, 1786) -(83, 787, 1611) -(861, 971, 1366) -(339, 608, 713) -(590, 161, 1134) -(684, 222, 1578) -(316, 923, 404) -(944, 921, 1602) -(428, 412, 309) -(817, 910, 70) -(530, 321, 818) -(362, 258, 1142) -(15, 577, 850) -(351, 582, 326) -(455, 448, 51) -(646, 733, 1001) -(258, 690, 1202) -(334, 458, 333) -(695, 241, 1267) -(706, 587, 1657) -(32, 268, 746) -(876, 287, 1786) -(41, 771, 994) -(382, 543, 1967) -(237, 189, 117) -(346, 529, 1729) -(629, 113, 734) -(629, 940, 1065) -(280, 672, 1197) -(354, 507, 57) -(243, 907, 436) -(464, 940, 76) -(781, 662, 1225) -(456, 729, 1700) -(432, 645, 1197) -(752, 522, 1051) -(803, 918, 452) -(989, 73, 970) -(936, 672, 141) -(351, 913, 1588) -(209, 98, 1696) -(816, 539, 1744) -(391, 197, 287) -(619, 468, 589) -(298, 697, 1252) -(433, 268, 633) -(521, 767, 354) -(174, 381, 1715) -(721, 678, 1252) -(550, 497, 1981) -(458, 284, 666) -(701, 432, 1641) -(404, 816, 346) -(573, 934, 151) -(580, 457, 1221) -(987, 942, 747) -(153, 387, 1757) -(892, 778, 687) -(690, 258, 1202) -(491, 758, 870) -(419, 277, 202) -(534, 563, 389) -(497, 629, 1677) -(481, 710, 1355) -(44, 126, 512) -(890, 689, 852) -(449, 317, 339) -(233, 504, 825) -(8, 231, 1758) -(711, 136, 561) -(381, 219, 697) -(933, 297, 741) -(917, 692, 1598) -(823, 166, 1102) -(991, 615, 637) -(652, 634, 842) -(599, 861, 1392) -(545, 910, 420) -(30, 669, 1570) -(472, 889, 569) -(126, 220, 1793) -(753, 531, 1011) -(771, 348, 1623) -(297, 933, 741) -(685, 329, 554) -(354, 357, 700) -(529, 543, 860) -(482, 859, 111) -(118, 608, 1954) -(301, 525, 1732) -(656, 550, 241) -(396, 143, 756) -(687, 325, 185) -(306, 332, 462) -(142, 172, 690) -(885, 258, 294) -(153, 505, 1121) -(889, 396, 876) -(65, 111, 972) -(727, 110, 1778) -(734, 330, 931) -(343, 945, 1824) -(307, 611, 981) -(803, 727, 1165) -(988, 634, 1386) -(32, 220, 1573) -(98, 209, 1696) -(319, 968, 1919) -(984, 924, 305) -(609, 996, 1877) -(910, 419, 1880) -(47, 9, 1399) -(305, 45, 1602) -(893, 420, 617) -(567, 781, 1131) -(803, 900, 1704) -(762, 883, 1519) -(128, 87, 834) -(807, 425, 229) -(94, 475, 755) -(36, 589, 515) -(117, 135, 1457) -(885, 154, 1554) -(922, 148, 1366) -(558, 746, 1065) -(976, 342, 1520) -(484, 82, 1847) -(283, 917, 1281) -(126, 413, 1931) -(932, 990, 1402) -(550, 948, 1077) -(513, 691, 1073) -(884, 617, 1946) -(42, 191, 1952) -(116, 72, 1297) -(260, 597, 346) -(199, 304, 1884) -(375, 685, 1213) -(893, 947, 1320) -(949, 217, 277) -(80, 552, 1561) -(146, 163, 1615) -(738, 575, 1527) -(8, 192, 1735) -(815, 319, 196) -(213, 350, 1301) -(287, 14, 1554) -(328, 306, 1585) -(753, 908, 1922) -(735, 0, 1518) -(168, 656, 721) -(278, 351, 1339) -(208, 946, 392) -(315, 886, 1884) -(230, 895, 1327) -(783, 229, 1960) -(982, 888, 893) -(811, 567, 611) -(181, 182, 1118) -(867, 612, 438) -(899, 129, 685) -(796, 262, 1333) -(136, 190, 110) -(663, 885, 835) -(48, 341, 946) -(907, 987, 931) -(512, 927, 132) -(431, 489, 1206) -(235, 111, 1565) -(859, 482, 111) -(654, 760, 323) -(172, 142, 690) -(989, 688, 832) -(545, 2, 616) -(565, 247, 1178) -(841, 310, 1380) -(565, 316, 568) -(345, 883, 1170) -(414, 951, 812) -(988, 470, 1532) -(716, 755, 1168) -(623, 929, 1154) -(627, 96, 1357) -(497, 536, 1625) -(747, 529, 72) -(996, 566, 1990) -(484, 310, 921) -(448, 2, 470) -(698, 194, 1044) -(323, 932, 1135) -(251, 451, 128) -(531, 830, 1241) -(489, 519, 702) -(399, 780, 1280) -(348, 639, 1802) -(536, 605, 126) -(59, 878, 774) -(406, 982, 1873) -(777, 194, 312) -(616, 395, 105) -(669, 671, 402) -(502, 783, 204) -(112, 827, 1875) -(893, 11, 848) -(805, 79, 55) -(831, 298, 1391) -(607, 985, 503) -(574, 260, 1624) -(868, 863, 890) -(724, 369, 491) -(410, 434, 1748) -(157, 166, 278) -(732, 686, 1986) -(656, 168, 721) -(622, 991, 234) -(944, 656, 636) -(724, 730, 1425) -(974, 761, 110) -(225, 935, 644) -(298, 780, 168) -(830, 637, 1177) -(523, 253, 1543) -(210, 231, 66) -(447, 859, 1213) -(301, 721, 1560) -(659, 686, 973) -(966, 566, 80) -(698, 647, 1676) -(271, 979, 1488) -(312, 160, 1612) -(628, 49, 926) -(793, 681, 230) -(95, 74, 1033) -(578, 794, 1649) -(225, 482, 1483) -(667, 759, 1502) -(83, 530, 1237) -(671, 7, 1406) -(802, 681, 1246) -(638, 78, 778) -(187, 146, 1216) -(435, 145, 145) -(806, 511, 1227) -(94, 573, 755) -(394, 927, 1311) -(159, 932, 1731) -(834, 615, 1479) -(615, 991, 637) -(210, 265, 536) -(372, 418, 729) -(945, 890, 140) -(442, 509, 1864) -(930, 443, 670) -(307, 876, 1723) -(660, 784, 524) -(622, 715, 1487) -(844, 879, 774) -(97, 470, 1019) -(922, 820, 888) -(373, 539, 1961) -(559, 756, 1635) -(292, 945, 1939) -(690, 910, 1388) -(124, 521, 954) -(841, 444, 178) -(621, 805, 106) -(289, 402, 1781) -(492, 562, 1509) -(37, 914, 1056) -(77, 968, 173) -(595, 695, 587) -(136, 624, 371) -(856, 821, 1857) -(323, 344, 1003) -(396, 591, 564) -(864, 920, 1135) -(645, 368, 1342) -(310, 13, 661) -(722, 848, 1816) -(73, 989, 970) -(846, 932, 1924) -(759, 854, 778) -(190, 136, 110) -(956, 816, 528) -(710, 404, 1102) -(86, 704, 902) -(16, 117, 1927) -(786, 444, 1999) -(130, 847, 1512) -(990, 932, 1402) -(535, 134, 747) -(421, 407, 1968) -(146, 811, 692) -(273, 608, 873) -(82, 311, 906) -(102, 818, 716) -(50, 451, 951) -(764, 315, 1969) -(397, 792, 1179) -(803, 928, 1466) -(146, 536, 888) -(844, 12, 1184) -(460, 534, 1502) -(258, 321, 1661) -(719, 641, 1072) -(958, 971, 1837) -(621, 94, 248) -(392, 488, 955) -(926, 656, 1012) -(449, 60, 590) -(25, 437, 105) -(86, 203, 1480) -(452, 578, 566) -(622, 546, 1396) -(761, 322, 768) -(915, 459, 730) -(577, 355, 631) -(262, 264, 728) -(579, 982, 232) -(230, 774, 1101) -(746, 39, 358) -(585, 936, 664) -(895, 560, 1689) -(117, 866, 828) -(145, 767, 677) -(453, 974, 262) -(169, 802, 396) -(679, 894, 854) -(539, 817, 1119) -(901, 442, 397) -(480, 868, 71) -(733, 2, 1929) -(908, 535, 1006) -(449, 127, 1884) -(747, 76, 272) -(786, 439, 1428) -(704, 952, 435) -(625, 552, 312) -(553, 483, 1713) -(994, 489, 1271) -(253, 523, 1543) -(922, 64, 1656) -(689, 843, 1597) -(688, 989, 832) -(126, 929, 979) -(210, 100, 1279) -(42, 887, 85) -(839, 517, 707) -(382, 959, 911) -(1, 329, 1694) -(311, 826, 1877) -(494, 67, 1216) -(719, 83, 1824) -(277, 236, 174) -(99, 561, 1028) -(889, 457, 1163) -(475, 656, 598) -(198, 666, 1107) -(872, 55, 756) -(713, 948, 89) -(823, 49, 1528) -(92, 61, 208) -(572, 202, 344) -(518, 777, 880) -(281, 149, 1434) -(816, 289, 1068) -(230, 299, 1986) -(229, 783, 1960) -(67, 188, 750) -(782, 452, 1530) -(206, 943, 1704) -(307, 910, 132) -(792, 255, 1326) -(723, 370, 1479) -(778, 446, 60) -(88, 604, 1276) -(123, 879, 703) -(659, 730, 632) -(586, 518, 673) -(916, 235, 1334) -(298, 140, 446) -(333, 103, 1045) -(673, 901, 1772) -(383, 579, 1301) -(47, 51, 512) -(620, 407, 1432) -(414, 295, 216) -(640, 290, 1729) -(492, 341, 814) -(661, 200, 766) -(75, 778, 850) -(359, 285, 1184) -(849, 201, 1419) -(390, 129, 1180) -(564, 596, 1489) -(981, 617, 976) -(269, 283, 281) -(0, 560, 1390) -(241, 281, 904) -(95, 578, 584) -(534, 460, 1502) -(847, 132, 1722) -(831, 222, 1289) -(210, 203, 136) -(907, 243, 436) -(709, 163, 610) -(503, 484, 725) -(965, 329, 1474) -(288, 672, 987) -(970, 459, 1008) -(128, 303, 372) -(628, 600, 868) -(649, 323, 984) -(990, 897, 871) -(757, 317, 201) -(812, 765, 944) -(513, 201, 1712) -(382, 606, 1712) -(552, 625, 312) -(444, 825, 1261) -(446, 918, 1536) -(594, 939, 815) -(534, 481, 1030) -(649, 428, 1843) -(723, 623, 116) -(427, 426, 680) -(49, 595, 1024) -(875, 331, 103) -(893, 40, 470) -(179, 240, 1772) -(786, 312, 889) -(509, 831, 1082) -(992, 146, 434) -(829, 118, 70) -(883, 93, 1069) -(809, 43, 1562) -(318, 287, 1552) -(321, 92, 1784) -(551, 827, 847) -(585, 5, 76) -(362, 317, 1849) -(16, 888, 847) -(567, 344, 1362) -(456, 139, 1111) -(182, 181, 1118) -(22, 840, 1881) -(555, 368, 91) -(813, 674, 1825) -(617, 884, 1946) -(697, 69, 227) -(637, 830, 1177) -(66, 555, 922) -(29, 436, 1312) -(975, 9, 260) -(602, 931, 233) -(923, 698, 573) -(694, 837, 936) -(241, 995, 1605) -(442, 218, 1922) -(419, 873, 728) -(477, 141, 328) -(201, 513, 1712) -(5, 470, 162) -(794, 871, 809) -(853, 39, 221) -(963, 868, 1306) -(591, 568, 59) -(984, 852, 149) -(586, 207, 1068) -(908, 753, 1922) -(218, 750, 1990) -(516, 390, 489) -(129, 652, 1778) -(259, 621, 760) -(811, 424, 196) -(995, 343, 1953) -(340, 770, 1036) -(873, 60, 1750) -(958, 514, 147) -(344, 323, 1003) -(330, 987, 1572) -(532, 691, 126) -(659, 36, 1557) -(755, 716, 1168) -(811, 313, 920) -(226, 891, 919) -(578, 452, 566) -(597, 344, 456) -(609, 745, 79) -(621, 599, 587) -(160, 85, 1176) -(90, 161, 878) -(659, 125, 1521) -(218, 899, 1784) -(883, 762, 1519) -(368, 456, 1246) -(918, 463, 247) -(332, 166, 980) -(521, 124, 954) -(794, 258, 1443) -(834, 800, 1615) -(521, 545, 166) -(873, 862, 1894) -(376, 738, 932) -(31, 866, 1460) -(479, 899, 951) -(951, 269, 1094) -(271, 496, 214) -(627, 363, 1130) -(93, 656, 458) -(684, 904, 443) -(629, 974, 219) -(777, 717, 1953) -(77, 478, 176) -(552, 80, 1561) -(64, 922, 1656) -(47, 546, 746) -(122, 26, 581) -(12, 602, 924) -(826, 447, 936) -(694, 63, 1863) -(385, 819, 1280) -(546, 561, 1215) -(890, 945, 140) -(341, 353, 729) -(728, 182, 1796) -(393, 280, 94) -(837, 55, 1096) -(117, 572, 148) -(923, 889, 72) -(552, 441, 791) -(643, 728, 835) -(992, 635, 1412) -(204, 667, 526) -(79, 857, 405) -(80, 649, 807) -(485, 794, 100) -(239, 297, 212) -(999, 487, 1041) -(580, 20, 1424) -(31, 17, 1568) -(931, 31, 676) -(782, 975, 1353) -(515, 348, 1601) -(720, 730, 177) -(662, 157, 1550) -(591, 233, 1671) -(439, 731, 1358) -(443, 930, 670) -(221, 715, 923) -(338, 308, 325) -(301, 320, 1982) -(288, 256, 1101) -(52, 857, 1700) -(56, 690, 1792) -(881, 380, 1043) -(588, 576, 1624) -(55, 316, 479) -(896, 221, 124) -(518, 586, 673) -(981, 140, 452) -(542, 822, 1067) -(561, 546, 1215) -(727, 803, 1165) -(583, 112, 815) -(765, 781, 458) -(694, 710, 1092) -(381, 174, 1715) -(680, 230, 1034) -(240, 460, 1253) -(771, 644, 1844) -(702, 489, 1344) -(645, 808, 587) -(244, 624, 487) -(816, 486, 80) -(407, 126, 1519) -(665, 787, 871) -(66, 115, 327) -(657, 572, 1500) -(621, 259, 760) -(395, 154, 504) -(987, 591, 1773) -(125, 724, 1853) -(772, 974, 745) -(421, 243, 1764) -(55, 518, 1424) -(649, 80, 807) -(313, 811, 920) -(154, 395, 504) -(101, 501, 802) -(800, 254, 430) -(360, 6, 1936) -(711, 278, 896) -(496, 51, 1907) -(878, 381, 266) -(834, 443, 1884) -(241, 261, 1004) -(828, 95, 1754) -(204, 852, 118) -(812, 334, 1626) -(870, 966, 1220) -(482, 927, 823) -(820, 833, 1033) -(238, 673, 878) -(514, 737, 1805) -(566, 686, 964) -(642, 279, 1345) -(290, 877, 1766) -(665, 379, 812) -(312, 653, 1296) -(388, 395, 869) -(39, 746, 358) -(685, 617, 904) -(338, 629, 751) -(355, 805, 389) -(265, 569, 1983) -(965, 99, 1945) -(175, 908, 1508) -(542, 91, 704) -(400, 336, 1270) -(111, 739, 1260) -(935, 225, 644) -(884, 853, 1173) -(77, 761, 1973) -(577, 48, 968) -(43, 809, 1562) -(373, 546, 1767) -(616, 927, 1493) -(11, 893, 848) -(267, 471, 1818) -(838, 818, 1978) -(235, 916, 1334) -(803, 883, 1268) -(164, 707, 1420) -(93, 366, 1004) -(590, 84, 99) -(59, 418, 1792) -(295, 573, 1094) -(829, 154, 1335) -(943, 206, 1704) -(861, 974, 633) -(165, 663, 1746) -(802, 947, 673) -(159, 338, 890) -(930, 169, 1115) -(14, 702, 1078) -(761, 574, 720) -(56, 443, 912) -(785, 679, 1077) -(55, 584, 1691) -(294, 981, 498) -(478, 118, 156) -(667, 208, 274) -(812, 914, 669) -(889, 923, 72) -(306, 328, 1585) -(128, 616, 890) -(418, 59, 1792) -(454, 336, 58) -(94, 621, 248) -(95, 828, 1754) -(351, 326, 886) -(812, 724, 1270) -(722, 931, 534) -(616, 418, 1094) -(779, 615, 1440) -(122, 55, 1053) -(177, 843, 1689) -(969, 726, 1682) -(987, 147, 989) -(823, 322, 664) -(105, 361, 176) -(238, 283, 1979) -(333, 665, 1861) -(257, 360, 408) -(671, 669, 402) -(166, 823, 1102) -(406, 936, 520) -(816, 404, 346) -(247, 6, 1500) -(980, 804, 1014) -(96, 934, 1518) -(141, 491, 675) -(44, 453, 120) -(356, 116, 464) -(400, 326, 356) -(94, 135, 1942) -(653, 570, 1629) -(11, 406, 1601) -(343, 995, 1953) -(254, 266, 1913) -(474, 228, 806) -(40, 967, 489) -(981, 963, 1592) -(319, 514, 1021) -(349, 467, 1424) -(209, 273, 1039) -(700, 945, 1316) -(230, 275, 1721) -(540, 160, 1837) -(269, 130, 1793) -(36, 659, 1557) -(152, 766, 1615) -(793, 79, 1968) -(539, 300, 769) -(456, 771, 170) -(247, 151, 464) -(544, 70, 1241) -(728, 856, 1404) -(451, 38, 586) -(930, 386, 273) -(711, 665, 722) -(113, 78, 564) -(994, 507, 696) -(903, 852, 1795) -(219, 358, 990) -(611, 658, 1400) -(790, 301, 524) -(653, 312, 1296) -(341, 539, 1006) -(88, 241, 1511) -(930, 72, 1128) -(877, 900, 1487) -(178, 626, 1083) -(474, 515, 1184) -(454, 416, 278) -(981, 812, 127) -(240, 796, 1292) -(849, 898, 848) -(257, 253, 1266) -(207, 232, 1901) -(62, 144, 497) -(997, 96, 1315) -(49, 823, 1528) -(694, 504, 189) -(387, 266, 394) -(860, 974, 858) -(807, 814, 603) -(331, 241, 960) -(296, 941, 1515) -(417, 817, 1557) -(904, 684, 443) -(744, 129, 405) -(262, 796, 1333) -(157, 884, 1439) -(47, 85, 1138) -(858, 995, 385) -(820, 862, 1505) -(18, 304, 1934) -(218, 926, 226) -(862, 351, 884) -(256, 778, 1292) -(960, 629, 1145) -(326, 359, 84) -(244, 335, 1044) -(510, 598, 858) -(463, 432, 400) -(965, 94, 1813) -(363, 537, 1605) -(327, 896, 395) -(130, 777, 1257) -(20, 88, 1378) -(478, 130, 734) -(157, 662, 1550) -(84, 682, 1281) -(13, 636, 557) -(838, 418, 1916) -(415, 375, 191) -(951, 577, 885) -(400, 665, 1537) -(989, 676, 474) -(666, 723, 1408) -(646, 464, 1975) -(225, 340, 1995) -(797, 242, 735) -(464, 646, 1975) -(447, 806, 573) -(428, 404, 951) -(673, 342, 1913) -(413, 957, 681) -(676, 296, 1486) -(126, 407, 1519) -(491, 162, 1989) -(753, 587, 836) -(945, 700, 1316) -(195, 290, 1558) -(839, 711, 1250) -(5, 174, 82) -(279, 736, 799) -(959, 310, 1328) -(637, 280, 196) -(241, 141, 678) -(521, 304, 1265) -(551, 505, 1348) -(582, 305, 58) -(769, 852, 1990) -(717, 95, 326) -(77, 193, 1547) -(940, 756, 900) -(387, 652, 272) -(804, 980, 1014) -(906, 266, 1629) -(724, 856, 1713) -(432, 701, 1641) -(828, 143, 1091) -(595, 995, 865) -(352, 654, 1959) -(290, 567, 1658) -(438, 201, 1107) -(189, 80, 1088) -(42, 219, 1073) -(526, 202, 1931) -(602, 12, 924) -(850, 156, 1510) -(289, 66, 616) -(126, 44, 512) -(971, 241, 1644) -(845, 514, 1724) -(147, 787, 1785) -(886, 972, 1651) -(515, 765, 1693) -(320, 301, 1982) -(653, 549, 865) -(351, 431, 611) -(782, 748, 1419) -(823, 570, 181) -(682, 954, 1181) -(419, 848, 680) -(612, 994, 1379) -(60, 423, 724) -(23, 301, 1064) -(667, 188, 1688) -(575, 799, 1209) -(544, 567, 1150) -(559, 561, 204) -(564, 68, 564) -(72, 930, 1128) -(468, 438, 1003) -(727, 750, 1158) -(795, 173, 741) -(818, 838, 1978) -(505, 65, 1311) -(769, 416, 175) -(127, 789, 841) -(677, 511, 1212) -(898, 580, 1207) -(419, 910, 1880) -(591, 497, 1421) -(473, 266, 285) -(903, 270, 1820) -(373, 527, 538) -(694, 790, 446) -(377, 708, 859) -(673, 503, 755) -(892, 253, 728) -(107, 808, 1100) -(215, 406, 278) -(773, 286, 1036) -(60, 996, 447) -(474, 540, 1967) -(274, 551, 166) -(629, 297, 685) -(332, 159, 672) -(871, 85, 216) -(971, 893, 147) -(166, 691, 1573) -(263, 124, 722) -(159, 298, 1818) -(216, 640, 192) -(168, 864, 312) -(821, 856, 1857) -(730, 724, 1425) -(96, 245, 1793) -(133, 528, 1751) -(886, 315, 1884) -(554, 835, 627) -(764, 572, 344) -(672, 749, 991) -(747, 99, 1368) -(735, 607, 372) -(569, 570, 988) -(777, 286, 1850) -(625, 248, 1386) -(715, 622, 1487) -(529, 228, 1470) -(55, 986, 226) -(758, 444, 946) -(631, 934, 695) -(652, 988, 825) -(742, 239, 62) -(505, 74, 1387) -(655, 155, 1937) -(69, 4, 558) -(587, 753, 836) -(877, 290, 1766) -(401, 745, 1589) -(336, 454, 58) -(57, 818, 352) -(477, 948, 887) -(556, 684, 780) -(704, 301, 1901) -(544, 871, 123) -(147, 987, 989) -(174, 908, 1544) -(33, 947, 1438) -(877, 104, 522) -(759, 667, 1502) -(56, 833, 562) -(364, 266, 1154) -(330, 182, 242) -(115, 350, 1789) -(522, 767, 749) -(617, 685, 904) -(146, 606, 351) -(854, 759, 778) -(593, 997, 653) -(325, 985, 1547) -(144, 62, 497) -(401, 523, 244) -(987, 330, 1572) -(348, 355, 1531) -(332, 229, 1113) -(619, 813, 1354) -(743, 720, 155) -(86, 334, 427) -(529, 346, 1729) -(503, 443, 484) -(487, 477, 989) -(921, 456, 1129) -(326, 400, 356) -(954, 452, 1423) -(591, 396, 564) -(269, 591, 204) -(632, 157, 841) -(9, 47, 1399) -(212, 546, 1757) -(471, 267, 1818) -(17, 31, 1568) -(74, 472, 765) -(277, 549, 1245) -(347, 438, 773) -(741, 924, 1232) -(927, 394, 1311) -(782, 854, 1492) -(22, 659, 801) -(39, 905, 1702) -(18, 643, 82) -(999, 698, 853) -(24, 892, 1981) -(513, 584, 638) -(466, 162, 308) -(610, 609, 856) -(139, 982, 1270) -(681, 802, 1246) -(315, 497, 1219) -(915, 707, 1560) -(422, 1, 160) -(576, 611, 1566) -(519, 445, 931) -(333, 234, 1862) -(919, 168, 404) -(98, 849, 235) -(707, 933, 99) -(173, 182, 158) -(908, 175, 1508) -(261, 775, 1840) -(967, 1, 1817) -(736, 889, 1324) -(54, 12, 1135) -(737, 528, 1938) -(626, 567, 176) -(539, 723, 961) -(57, 770, 1512) -(119, 558, 1435) -(941, 967, 1761) -(338, 561, 1710) -(927, 482, 823) -(704, 437, 1577) -(824, 171, 1716) -(748, 100, 676) -(236, 617, 1440) -(257, 148, 664) -(472, 434, 1193) -(921, 586, 116) -(55, 404, 132) -(461, 844, 697) -(43, 881, 724) -(163, 86, 1879) -(257, 851, 831) -(517, 89, 304) -(802, 904, 418) -(730, 221, 733) -(362, 915, 196) -(880, 151, 1514) -(716, 88, 1376) -(771, 456, 170) -(294, 599, 1663) -(619, 223, 1203) -(923, 657, 287) -(139, 975, 743) -(58, 737, 885) -(567, 626, 176) -(171, 763, 355) -(879, 844, 774) -(93, 199, 575) -(885, 784, 1591) -(557, 3, 1827) -(855, 520, 1913) -(227, 458, 234) -(742, 586, 1667) -(230, 927, 712) -(985, 711, 241) -(622, 140, 1650) -(678, 119, 153) -(610, 748, 319) -(419, 390, 471) -(616, 128, 890) -(43, 274, 185) -(154, 307, 88) -(82, 308, 1436) -(792, 397, 1179) -(672, 609, 530) -(801, 536, 525) -(125, 327, 1460) -(894, 992, 1289) -(146, 537, 296) -(844, 730, 509) -(555, 66, 922) -(519, 653, 1800) -(594, 411, 1465) -(560, 962, 1724) -(744, 308, 1498) -(229, 591, 1145) -(103, 272, 1740) -(34, 505, 1410) -(804, 312, 600) -(509, 89, 1517) -(592, 888, 1011) -(382, 632, 219) -(630, 437, 1164) -(663, 857, 627) -(800, 597, 1499) -(159, 34, 713) -(391, 634, 1410) -(985, 607, 503) -(857, 658, 85) -(166, 63, 1902) -(920, 864, 1135) -(492, 441, 381) -(770, 340, 1036) -(348, 771, 1623) -(433, 577, 295) -(539, 816, 1744) -(556, 882, 694) -(672, 288, 987) -(707, 915, 1560) -(942, 987, 747) -(945, 343, 1824) -(29, 238, 535) -(862, 943, 1898) -(285, 132, 1088) -(822, 96, 127) -(787, 446, 673) -(610, 743, 682) -(989, 859, 1969) -(628, 433, 1077) -(601, 83, 637) -(69, 850, 63) -(23, 790, 1848) -(767, 145, 677) -(713, 810, 1286) -(153, 210, 1348) -(746, 558, 1065) -(404, 710, 1102) -(259, 93, 612) -(705, 842, 1143) -(151, 91, 407) -(891, 226, 919) -(892, 952, 738) -(263, 866, 1784) -(784, 812, 1636) -(982, 579, 232) -(895, 230, 1327) -(881, 710, 51) -(385, 284, 1358) -(477, 500, 1035) -(241, 738, 466) -(851, 750, 1101) -(194, 714, 518) -(181, 388, 1975) -(618, 888, 982) -(541, 743, 565) -(911, 328, 486) -(343, 495, 1884) -(308, 744, 1498) -(440, 107, 652) -(665, 711, 722) -(425, 505, 608) -(758, 213, 1102) -(868, 480, 71) -(299, 464, 1724) -(706, 944, 1786) -(780, 399, 1280) -(140, 46, 355) -(489, 431, 1206) -(489, 994, 1271) -(382, 596, 1312) -(955, 341, 829) -(755, 507, 785) -(4, 827, 1203) -(77, 731, 1981) -(61, 694, 124) -(63, 694, 1863) -(617, 939, 903) -(728, 162, 699) -(242, 933, 1470) -(51, 448, 182) -(160, 540, 1837) -(590, 701, 1279) -(549, 653, 865) -(794, 736, 157) -(867, 716, 1069) -(281, 241, 904) -(716, 593, 1061) -(129, 743, 1795) -(169, 141, 1758) -(875, 595, 353) -(905, 39, 1702) -(608, 273, 873) -(19, 271, 1064) -(803, 953, 78) -(319, 218, 1281) -(868, 963, 1306) -(634, 391, 1410) -(410, 518, 782) -(490, 415, 1608) -(846, 411, 911) -(146, 246, 990) -(385, 204, 560) -(539, 373, 1961) -(687, 821, 248) -(278, 489, 251) -(703, 316, 1391) -(682, 263, 833) -(16, 224, 984) -(56, 525, 1547) -(92, 494, 1136) -(94, 965, 1813) -(166, 332, 980) -(773, 863, 857) -(315, 764, 1969) -(801, 784, 1915) -(597, 24, 1047) -(7, 681, 1132) -(543, 444, 1150) -(156, 850, 1510) -(68, 564, 564) -(914, 713, 1901) -(676, 531, 1095) -(542, 718, 827) -(861, 94, 397) -(667, 940, 613) -(241, 384, 843) -(521, 213, 1857) -(160, 302, 58) -(938, 869, 1060) -(794, 578, 1649) -(368, 233, 1209) -(944, 278, 342) -(856, 728, 1404) -(858, 305, 1350) -(658, 895, 955) -(151, 880, 1514) -(988, 652, 825) -(756, 219, 686) -(245, 49, 1761) -(968, 135, 1517) -(412, 812, 1890) -(157, 456, 867) -(93, 259, 612) -(582, 362, 493) -(909, 601, 839) -(326, 351, 886) -(866, 205, 1642) -(200, 991, 593) -(936, 585, 664) -(169, 605, 835) -(115, 66, 327) -(97, 51, 1903) -(6, 247, 1500) -(995, 595, 865) -(101, 736, 1993) -(501, 203, 1872) -(83, 481, 618) -(377, 469, 83) -(838, 881, 296) -(947, 33, 1438) -(737, 514, 1805) -(240, 107, 436) -(251, 953, 783) -(44, 827, 686) -(722, 514, 90) -(155, 655, 1937) -(980, 769, 186) -(711, 839, 1250) -(567, 884, 61) -(566, 996, 1990) -(573, 295, 1094) -(129, 390, 1180) -(826, 548, 1897) -(593, 375, 1310) -(829, 142, 1545) -(888, 566, 887) -(389, 407, 1097) -(707, 164, 1420) -(516, 735, 1468) -(526, 861, 1216) -(473, 858, 1664) -(307, 233, 1009) -(618, 152, 1328) -(437, 630, 1164) -(352, 974, 621) -(96, 627, 1357) -(258, 798, 550) -(667, 204, 526) -(682, 84, 1281) -(615, 217, 377) -(122, 767, 1588) -(876, 318, 1254) -(1, 967, 1817) -(784, 885, 1591) -(735, 62, 1153) -(101, 512, 453) -(956, 697, 129) -(900, 606, 1901) -(354, 7, 993) -(390, 516, 489) -(962, 157, 325) -(429, 599, 295) -(260, 451, 458) -(233, 591, 1671) -(215, 747, 383) -(592, 573, 244) -(439, 73, 1302) -(576, 433, 388) -(426, 373, 1861) -(7, 671, 1406) -(410, 369, 1422) -(321, 743, 95) -(781, 34, 1862) -(507, 354, 57) -(153, 839, 784) -(588, 867, 339) -(681, 7, 1132) -(969, 10, 1143) -(39, 853, 221) -(904, 802, 418) -(9, 975, 260) -(303, 800, 1383) -(514, 417, 1733) -(715, 221, 923) -(569, 402, 881) -(458, 334, 333) -(276, 795, 994) -(884, 467, 1650) -(997, 593, 653) -(615, 779, 1440) -(50, 193, 1226) -(360, 612, 1014) -(966, 435, 1349) -(803, 623, 500) -(970, 958, 1174) -(54, 439, 1086) -(857, 52, 1700) -(275, 70, 1661) -(922, 61, 1420) -(170, 806, 456) -(852, 769, 1990) -(323, 102, 60) -(448, 455, 51) -(231, 452, 83) -(451, 50, 951) -(930, 374, 1292) -(806, 577, 337) -(70, 80, 208) -(536, 801, 525) -(738, 293, 1374) -(188, 409, 237) -(818, 768, 761) -(46, 273, 372) -(123, 206, 879) -(949, 832, 1469) -(787, 80, 51) -(697, 901, 1850) -(67, 761, 290) -(3, 20, 1200) -(519, 178, 1557) -(610, 836, 623) -(408, 345, 1786) -(686, 609, 420) -(653, 519, 1800) -(898, 849, 848) -(323, 838, 636) -(686, 566, 964) -(507, 799, 670) -(932, 159, 1731) -(914, 510, 1444) -(93, 143, 357) -(203, 6, 560) -(883, 803, 1268) -(138, 253, 1463) -(86, 163, 1879) -(771, 677, 632) -(557, 855, 970) -(501, 762, 1519) -(754, 617, 309) -(657, 416, 1230) -(14, 498, 1811) -(35, 276, 376) -(87, 606, 980) -(317, 757, 201) -(920, 65, 501) -(242, 797, 735) -(529, 294, 298) -(244, 713, 846) -(188, 667, 1688) -(124, 154, 1756) -(870, 411, 922) -(737, 367, 764) -(443, 834, 1884) -(695, 799, 1544) -(537, 363, 1605) -(863, 136, 1355) -(938, 721, 1940) -(297, 239, 212) -(373, 545, 195) -(979, 58, 865) -(467, 349, 1424) -(856, 517, 1148) -(657, 127, 1549) -(184, 130, 528) -(807, 938, 1274) -(166, 54, 720) -(97, 874, 1593) -(171, 765, 1853) -(344, 897, 1352) -(67, 619, 1768) -(150, 116, 1087) -(953, 545, 432) -MST NODES -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -MST EDGES -(0, 0) -(1, 664) -(2, 448) -(3, 46) -(4, 69) -(5, 470) -(6, 203) -(7, 354) -(8, 297) -(9, 899) -(10, 869) -(11, 893) -(12, 602) -(13, 636) -(14, 702) -(15, 577) -(16, 888) -(17, 304) -(18, 643) -(19, 808) -(20, 464) -(21, 952) -(22, 659) -(23, 997) -(24, 597) -(25, 437) -(26, 478) -(27, 752) -(28, 991) -(29, 742) -(30, 896) -(31, 931) -(32, 599) -(33, 947) -(34, 159) -(35, 276) -(36, 919) -(37, 914) -(38, 451) -(39, 853) -(40, 967) -(41, 659) -(42, 887) -(43, 274) -(44, 453) -(45, 370) -(46, 140) -(47, 441) -(48, 255) -(49, 595) -(50, 451) -(51, 47) -(52, 277) -(53, 948) -(54, 73) -(55, 316) -(56, 303) -(57, 818) -(58, 817) -(59, 798) -(60, 910) -(61, 694) -(62, 144) -(63, 694) -(64, 489) -(65, 104) -(66, 289) -(67, 761) -(68, 564) -(69, 697) -(70, 80) -(71, 196) -(72, 339) -(73, 336) -(74, 536) -(75, 388) -(76, 747) -(77, 478) -(78, 253) -(79, 805) -(80, 941) -(81, 185) -(82, 410) -(83, 811) -(84, 590) -(85, 871) -(86, 489) -(87, 128) -(88, 222) -(89, 517) -(90, 161) -(91, 151) -(92, 61) -(93, 143) -(94, 621) -(95, 732) -(96, 822) -(97, 470) -(98, 849) -(99, 493) -(100, 748) -(101, 512) -(102, 323) -(103, 194) -(104, 400) -(105, 416) -(106, 155) -(107, 240) -(108, 208) -(109, 132) -(110, 342) -(111, 944) -(112, 542) -(113, 78) -(114, 114) -(115, 66) -(116, 356) -(117, 572) -(118, 744) -(119, 678) -(120, 46) -(121, 687) -(122, 26) -(123, 879) -(124, 842) -(125, 861) -(126, 56) -(127, 659) -(128, 615) -(129, 458) -(130, 184) -(131, 53) -(132, 235) -(133, 343) -(134, 451) -(135, 778) -(136, 624) -(137, 768) -(138, 332) -(139, 975) -(140, 298) -(141, 241) -(142, 172) -(143, 577) -(144, 926) -(145, 906) -(146, 537) -(147, 987) -(148, 257) -(149, 920) -(150, 795) -(151, 396) -(152, 340) -(153, 839) -(154, 307) -(155, 655) -(156, 850) -(157, 166) -(158, 657) -(159, 332) -(160, 745) -(161, 547) -(162, 415) -(163, 199) -(164, 982) -(165, 791) -(166, 54) -(167, 804) -(168, 919) -(169, 605) -(170, 806) -(171, 763) -(172, 943) -(173, 182) -(174, 5) -(175, 453) -(176, 587) -(177, 728) -(178, 626) -(179, 412) -(180, 167) -(181, 976) -(182, 330) -(183, 163) -(184, 278) -(185, 80) -(186, 761) -(187, 616) -(188, 409) -(189, 153) -(190, 136) -(191, 918) -(192, 8) -(193, 659) -(194, 777) -(195, 414) -(196, 36) -(197, 157) -(198, 884) -(199, 93) -(200, 373) -(201, 438) -(202, 889) -(203, 210) -(204, 852) -(205, 920) -(206, 160) -(207, 586) -(208, 667) -(209, 273) -(210, 231) -(211, 616) -(212, 190) -(213, 758) -(214, 59) -(215, 406) -(216, 640) -(217, 615) -(218, 599) -(219, 381) -(220, 950) -(221, 677) -(222, 953) -(223, 619) -(224, 853) -(225, 607) -(226, 891) -(227, 458) -(228, 474) -(229, 332) -(230, 290) -(231, 198) -(232, 384) -(233, 748) -(234, 881) -(235, 2) -(236, 61) -(237, 189) -(238, 29) -(239, 297) -(240, 806) -(241, 738) -(242, 797) -(243, 215) -(244, 558) -(245, 49) -(246, 146) -(247, 151) -(248, 657) -(249, 198) -(250, 111) -(251, 451) -(252, 539) -(253, 5) -(254, 331) -(255, 670) -(256, 203) -(257, 360) -(258, 885) -(259, 93) -(260, 597) -(261, 804) -(262, 312) -(263, 124) -(264, 262) -(265, 210) -(266, 473) -(267, 52) -(268, 433) -(269, 591) -(270, 569) -(271, 496) -(272, 642) -(273, 46) -(274, 551) -(275, 2) -(276, 91) -(277, 236) -(278, 944) -(279, 736) -(280, 393) -(281, 241) -(282, 561) -(283, 269) -(284, 458) -(285, 1) -(286, 199) -(287, 804) -(288, 672) -(289, 511) -(290, 707) -(291, 507) -(292, 435) -(293, 738) -(294, 529) -(295, 551) -(296, 746) -(297, 507) -(298, 868) -(299, 502) -(300, 539) -(301, 790) -(302, 160) -(303, 128) -(304, 74) -(305, 582) -(306, 752) -(307, 910) -(308, 338) -(309, 80) -(310, 13) -(311, 82) -(312, 941) -(313, 811) -(314, 881) -(315, 499) -(316, 923) -(317, 449) -(318, 343) -(319, 514) -(320, 987) -(321, 743) -(322, 868) -(323, 512) -(324, 457) -(325, 687) -(326, 400) -(327, 896) -(328, 911) -(329, 918) -(330, 4) -(331, 875) -(332, 306) -(333, 787) -(334, 86) -(335, 575) -(336, 454) -(337, 337) -(338, 788) -(339, 608) -(340, 268) -(341, 407) -(342, 745) -(343, 606) -(344, 645) -(345, 43) -(346, 495) -(347, 751) -(348, 533) -(349, 323) -(350, 235) -(351, 582) -(352, 974) -(353, 341) -(354, 507) -(355, 805) -(356, 956) -(357, 421) -(358, 627) -(359, 326) -(360, 402) -(361, 105) -(362, 915) -(363, 565) -(364, 247) -(365, 340) -(366, 93) -(367, 737) -(368, 392) -(369, 643) -(370, 723) -(371, 371) -(372, 483) -(373, 545) -(374, 537) -(375, 435) -(376, 116) -(377, 352) -(378, 261) -(379, 324) -(380, 881) -(381, 878) -(382, 632) -(383, 168) -(384, 873) -(385, 204) -(386, 930) -(387, 266) -(388, 384) -(389, 384) -(390, 419) -(391, 197) -(392, 502) -(393, 919) -(394, 518) -(395, 514) -(396, 591) -(397, 980) -(398, 398) -(399, 396) -(400, 505) -(401, 981) -(402, 780) -(403, 625) -(404, 55) -(405, 516) -(406, 936) -(407, 34) -(408, 188) -(409, 826) -(410, 518) -(411, 870) -(412, 428) -(413, 215) -(414, 295) -(415, 375) -(416, 454) -(417, 592) -(418, 372) -(419, 277) -(420, 893) -(421, 205) -(422, 1) -(423, 60) -(424, 859) -(425, 807) -(426, 427) -(427, 937) -(428, 338) -(429, 888) -(430, 88) -(431, 351) -(432, 117) -(433, 577) -(434, 472) -(435, 145) -(436, 815) -(437, 432) -(438, 821) -(439, 54) -(440, 107) -(441, 343) -(442, 496) -(443, 503) -(444, 758) -(445, 519) -(446, 778) -(447, 308) -(448, 51) -(449, 60) -(450, 386) -(451, 260) -(452, 231) -(453, 974) -(454, 620) -(455, 448) -(456, 218) -(457, 5) -(458, 334) -(459, 449) -(460, 116) -(461, 77) -(462, 944) -(463, 432) -(464, 51) -(465, 62) -(466, 162) -(467, 803) -(468, 619) -(469, 377) -(470, 723) -(471, 428) -(472, 889) -(473, 379) -(474, 515) -(475, 656) -(476, 866) -(477, 141) -(478, 118) -(479, 899) -(480, 868) -(481, 83) -(482, 61) -(483, 198) -(484, 86) -(485, 794) -(486, 816) -(487, 477) -(488, 42) -(489, 278) -(490, 415) -(491, 141) -(492, 441) -(493, 58) -(494, 720) -(495, 259) -(496, 873) -(497, 315) -(498, 680) -(499, 842) -(500, 597) -(501, 101) -(502, 733) -(503, 484) -(504, 694) -(505, 257) -(506, 317) -(507, 396) -(508, 749) -(509, 837) -(510, 914) -(511, 402) -(512, 927) -(513, 888) -(514, 722) -(515, 428) -(516, 390) -(517, 839) -(518, 3) -(519, 884) -(520, 751) -(521, 545) -(522, 767) -(523, 401) -(524, 255) -(525, 220) -(526, 669) -(527, 636) -(528, 988) -(529, 747) -(530, 321) -(531, 676) -(532, 135) -(533, 906) -(534, 563) -(535, 134) -(536, 505) -(537, 609) -(538, 998) -(539, 723) -(540, 645) -(541, 743) -(542, 91) -(543, 356) -(544, 871) -(545, 953) -(546, 683) -(547, 100) -(548, 410) -(549, 409) -(550, 656) -(551, 236) -(552, 441) -(553, 483) -(554, 835) -(555, 368) -(556, 684) -(557, 912) -(558, 577) -(559, 397) -(560, 621) -(561, 559) -(562, 362) -(563, 577) -(564, 970) -(565, 716) -(566, 888) -(567, 626) -(568, 591) -(569, 985) -(570, 823) -(571, 928) -(572, 202) -(573, 934) -(574, 98) -(575, 360) -(576, 433) -(577, 806) -(578, 452) -(579, 826) -(580, 273) -(581, 601) -(582, 362) -(583, 112) -(584, 893) -(585, 5) -(586, 518) -(587, 753) -(588, 867) -(589, 36) -(590, 161) -(591, 205) -(592, 573) -(593, 882) -(594, 939) -(595, 875) -(596, 723) -(597, 344) -(598, 510) -(599, 429) -(600, 628) -(601, 83) -(602, 931) -(603, 995) -(604, 380) -(605, 536) -(606, 146) -(607, 985) -(608, 273) -(609, 745) -(610, 338) -(611, 525) -(612, 867) -(613, 32) -(614, 230) -(615, 852) -(616, 395) -(617, 154) -(618, 103) -(619, 285) -(620, 0) -(621, 599) -(622, 747) -(623, 803) -(624, 244) -(625, 552) -(626, 956) -(627, 313) -(628, 49) -(629, 974) -(630, 823) -(631, 934) -(632, 429) -(633, 153) -(634, 166) -(635, 852) -(636, 910) -(637, 280) -(638, 124) -(639, 128) -(640, 332) -(641, 900) -(642, 61) -(643, 70) -(644, 350) -(645, 458) -(646, 157) -(647, 778) -(648, 458) -(649, 251) -(650, 219) -(651, 705) -(652, 387) -(653, 310) -(654, 298) -(655, 823) -(656, 93) -(657, 923) -(658, 857) -(659, 453) -(660, 471) -(661, 200) -(662, 937) -(663, 857) -(664, 576) -(665, 711) -(666, 198) -(667, 204) -(668, 602) -(669, 671) -(670, 570) -(671, 80) -(672, 609) -(673, 949) -(674, 78) -(675, 685) -(676, 989) -(677, 771) -(678, 915) -(679, 894) -(680, 230) -(681, 793) -(682, 409) -(683, 993) -(684, 904) -(685, 329) -(686, 609) -(687, 821) -(688, 989) -(689, 615) -(690, 258) -(691, 532) -(692, 864) -(693, 599) -(694, 980) -(695, 595) -(696, 746) -(697, 956) -(698, 261) -(699, 312) -(700, 945) -(701, 590) -(702, 393) -(703, 714) -(704, 952) -(705, 382) -(706, 362) -(707, 933) -(708, 377) -(709, 569) -(710, 881) -(711, 136) -(712, 658) -(713, 622) -(714, 194) -(715, 221) -(716, 73) -(717, 95) -(718, 567) -(719, 955) -(720, 743) -(721, 678) -(722, 194) -(723, 623) -(724, 369) -(725, 111) -(726, 749) -(727, 667) -(728, 382) -(729, 456) -(730, 720) -(731, 981) -(732, 316) -(733, 347) -(734, 330) -(735, 607) -(736, 794) -(737, 410) -(738, 692) -(739, 999) -(740, 30) -(741, 204) -(742, 239) -(743, 253) -(744, 129) -(745, 504) -(746, 39) -(747, 215) -(748, 610) -(749, 596) -(750, 851) -(751, 304) -(752, 860) -(753, 531) -(754, 617) -(755, 470) -(756, 219) -(757, 317) -(758, 1) -(759, 854) -(760, 654) -(761, 28) -(762, 828) -(763, 835) -(764, 572) -(765, 128) -(766, 797) -(767, 521) -(768, 257) -(769, 416) -(770, 443) -(771, 456) -(772, 974) -(773, 863) -(774, 230) -(775, 409) -(776, 86) -(777, 558) -(778, 861) -(779, 694) -(780, 298) -(781, 765) -(782, 597) -(783, 502) -(784, 660) -(785, 960) -(786, 312) -(787, 80) -(788, 103) -(789, 127) -(790, 694) -(791, 770) -(792, 397) -(793, 368) -(794, 144) -(795, 175) -(796, 166) -(797, 956) -(798, 258) -(799, 471) -(800, 254) -(801, 536) -(802, 169) -(803, 918) -(804, 775) -(805, 621) -(806, 174) -(807, 478) -(808, 645) -(809, 365) -(810, 997) -(811, 424) -(812, 981) -(813, 941) -(814, 807) -(815, 319) -(816, 404) -(817, 910) -(818, 34) -(819, 385) -(820, 808) -(821, 43) -(822, 860) -(823, 609) -(824, 424) -(825, 126) -(826, 718) -(827, 470) -(828, 143) -(829, 118) -(830, 637) -(831, 415) -(832, 368) -(833, 659) -(834, 504) -(835, 338) -(836, 856) -(837, 901) -(838, 323) -(839, 382) -(840, 17) -(841, 444) -(842, 232) -(843, 742) -(844, 730) -(845, 19) -(846, 411) -(847, 680) -(848, 419) -(849, 607) -(850, 69) -(851, 272) -(852, 868) -(853, 843) -(854, 523) -(855, 557) -(856, 606) -(857, 355) -(858, 995) -(859, 482) -(860, 602) -(861, 94) -(862, 324) -(863, 437) -(864, 168) -(865, 385) -(866, 839) -(867, 658) -(868, 55) -(869, 684) -(870, 301) -(871, 425) -(872, 55) -(873, 419) -(874, 732) -(875, 577) -(876, 931) -(877, 104) -(878, 59) -(879, 327) -(880, 151) -(881, 838) -(882, 556) -(883, 93) -(884, 567) -(885, 989) -(886, 483) -(887, 540) -(888, 907) -(889, 923) -(890, 945) -(891, 326) -(892, 778) -(893, 40) -(894, 477) -(895, 658) -(896, 221) -(897, 990) -(898, 849) -(899, 129) -(900, 408) -(901, 442) -(902, 176) -(903, 720) -(904, 802) -(905, 741) -(906, 550) -(907, 243) -(908, 909) -(909, 601) -(910, 545) -(911, 238) -(912, 250) -(913, 846) -(914, 977) -(915, 812) -(916, 235) -(917, 526) -(918, 463) -(919, 686) -(920, 65) -(921, 586) -(922, 611) -(923, 53) -(924, 984) -(925, 243) -(926, 218) -(927, 230) -(928, 949) -(929, 435) -(930, 443) -(931, 722) -(932, 513) -(933, 393) -(934, 475) -(935, 225) -(936, 672) -(937, 425) -(938, 869) -(939, 127) -(940, 464) -(941, 362) -(942, 987) -(943, 42) -(944, 630) -(945, 578) -(946, 208) -(947, 802) -(948, 713) -(949, 217) -(950, 496) -(951, 414) -(952, 274) -(953, 803) -(954, 480) -(955, 472) -(956, 316) -(957, 563) -(958, 514) -(959, 615) -(960, 83) -(961, 900) -(962, 157) -(963, 725) -(964, 817) -(965, 22) -(966, 566) -(967, 154) -(968, 77) -(969, 670) -(970, 459) -(971, 893) -(972, 403) -(973, 962) -(974, 761) -(975, 9) -(976, 354) -(977, 486) -(978, 978) -(979, 136) -(980, 769) -(981, 140) -(982, 579) -(983, 131) -(984, 852) -(985, 711) -(986, 55) -(987, 711) -(988, 805) -(989, 658) -(990, 25) -(991, 622) -(992, 146) -(993, 91) -(994, 507) -(995, 188) -(996, 60) -(997, 593) -(998, 284) -(999, 177) diff --git a/utils/benchmark/Graph/prim.driver.swift b/utils/benchmark/Graph/prim.driver.swift deleted file mode 100644 index c51627abd274d..0000000000000 --- a/utils/benchmark/Graph/prim.driver.swift +++ /dev/null @@ -1,13 +0,0 @@ -//===--- prims.swift - Implementation of Prims MST algorithm --------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -benchPrims() diff --git a/utils/benchmark/Graph/prims.cpp b/utils/benchmark/Graph/prims.cpp deleted file mode 100644 index d9fe5a72bf159..0000000000000 --- a/utils/benchmark/Graph/prims.cpp +++ /dev/null @@ -1,246 +0,0 @@ -//===--- prims.cpp - Implementation of Prims MST algorithm ----------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#include -#include - -#include "graph.h" - -namespace { - -enum { UnknownIndex = -1 }; - -struct CostQueueElt { - unsigned NodeId; - double Cost; -}; -static_assert(std::is_pod::value, "CostQueueElt must be a POD " - "type."); - -static unsigned getLeftChildIndex(unsigned Index) { - return Index*2 + 1; -} - -static unsigned getRightChildIndex(unsigned Index) { - return (Index + 1)*2; -} - -static unsigned getParentIndex(unsigned ChildIndex) { - return (ChildIndex - 1)/2; -} - -/// A simple priority queue implementation based off of a binary heap that is -/// also able to use a map to enable fast update operations. -struct PriorityQueue { - std::vector Heap; - std::vector GraphIndexToHeapIndexMap; - - CostQueueElt popHeap(); - bool updateCostIfLessThan(unsigned Id, double NewCost); - unsigned updateHeapAtIndex(unsigned Index); - void dump() { -#if 0 - dump_debug() -#endif - } - void dump_debug() { - printf("QUEUE\n"); - for (unsigned i = 0, e = Heap.size(); i != e; ++i) { - printf("(%u, %f)\n", Heap[i].NodeId, Heap[i].Cost); - } - } - - void check_invariants() { -#if 0 - std::vector Stack; - Stack.push_back(0); - - while (!Stack.empty()) { - unsigned Index = Stack.back(); - Stack.pop_back(); - - unsigned LeftChild = getLeftChildIndex(Index); - unsigned RightChild = getRightChildIndex(Index); - - if (LeftChild < Heap.size()) { - assert(Heap[LeftChild].Cost >= Heap[Index].Cost); - Stack.push_back(LeftChild); - } - if (RightChild < Heap.size()) { - assert(Heap[RightChild].Cost >= Heap[Index].Cost); - Stack.push_back(LeftChild); - } - } -#endif - } -}; - -} // end anonymous namespace. - -/// Pop off the smallest cost element, updating all data structures along the -/// way. -CostQueueElt -PriorityQueue::popHeap() { - assert(!Heap.empty() && "This method should only be called if the heap is " - "known non-empty."); - - // Copy the current heap head before doing anything. - CostQueueElt Result = Heap.front(); - - // Swap the heap head with the last heap element and pop the heap. - std::swap(Heap.front(), Heap.back()); - Heap.pop_back(); - - // Invalidate the graph index of our old head and update the graph index of - // the new head value. - GraphIndexToHeapIndexMap[Heap.front().NodeId] = 0; - GraphIndexToHeapIndexMap[Result.NodeId] = UnknownIndex; - - // Re-establish the heap property. - unsigned HeapIndex = 0, SmallestIndex; - while (true) { - SmallestIndex = updateHeapAtIndex(HeapIndex); - if (SmallestIndex == HeapIndex) - break; - HeapIndex = SmallestIndex; - } - - // Return the copy. - return Result; -} - -/// Find the cost associated with GraphIndex. If NewCost is less than that -/// value, map GraphIndex to NewCost instead and return true. Return false -/// otherwise. -bool -PriorityQueue::updateCostIfLessThan(unsigned GraphIndex, double NewCost) { - // Look up the heap index corresponding to GraphIndex. - unsigned HeapIndex = GraphIndexToHeapIndexMap[GraphIndex]; - - // If graph index is not in the heap, return false. - if (HeapIndex == UnknownIndex) - return false; - - // Otherwise, look up the cost of GraphIndex. - auto &QueueElt = Heap[HeapIndex]; - - // If NewCost >= QueueElt.cost, dont update anything and return false. - if (NewCost >= QueueElt.Cost) - return false; - - // Replace QueueElt.Cost with NewCost, update all relevant data structures, - // and return true. - QueueElt.Cost = NewCost; - - while (HeapIndex > 0 && HeapIndex != UnknownIndex) { - HeapIndex = getParentIndex(HeapIndex); - updateHeapAtIndex(HeapIndex); - } - - return true; -} - -/// Restore the heap property at Index. -unsigned -PriorityQueue::updateHeapAtIndex(unsigned Index) { - unsigned LeftChildIndex = getLeftChildIndex(Index); - unsigned RightChildIndex = getRightChildIndex(Index); - unsigned SmallestIndex; - if (LeftChildIndex < Heap.size() && Heap[LeftChildIndex].Cost < Heap[Index].Cost) - SmallestIndex = LeftChildIndex; - else - SmallestIndex = Index; - - if (RightChildIndex < Heap.size() && Heap[RightChildIndex].Cost < Heap[SmallestIndex].Cost) - SmallestIndex = RightChildIndex; - - if (SmallestIndex != Index) { - std::swap(GraphIndexToHeapIndexMap[Heap[Index].NodeId], - GraphIndexToHeapIndexMap[Heap[SmallestIndex].NodeId]); - std::swap(Heap[Index], Heap[SmallestIndex]); - } - return SmallestIndex; -} - -/// Compute the minimum spanning tree of the connected graph Graph. -/// -/// Graph is the graph. -/// -/// TreeEdges is the resulting set of tree edges mapping a node to its parent in -/// the tree. -/// -/// Fun is the weight function. It is assumed that it uses data injected via a -/// closure. -void graph::prims(std::vector &Graph, - std::vector &TreeEdges, - std::function Fun) { - assert(Graph.size() < UnknownIndex && "We do not support more than " - "(unsigned)-1 sized graphs since we use -1 as a sentinel value."); - PriorityQueue Queue; - Queue.dump(); - - // Initialize our data structures. They will contain at most Graph.size() - // elements, so just reserve that space now. - unsigned GraphSize = Graph.size(); - Queue.Heap.reserve(GraphSize); - Queue.GraphIndexToHeapIndexMap.reserve(GraphSize); - TreeEdges.reserve(GraphSize); - - // Create our queue, selecting the first element of the graph as the root of - // our tree for simplicity. - Queue.Heap.push_back({0, 0.0}); - Queue.GraphIndexToHeapIndexMap.push_back(0); - // Make the minimum spanning tree root its own parent for simplicity. - TreeEdges.push_back(0); - - //printf("Creating graph...\n"); - for (unsigned i = 1; i < GraphSize; ++i) { - Queue.Heap.push_back({i, INFINITY}); - Queue.GraphIndexToHeapIndexMap.push_back(i); - Queue.dump(); - TreeEdges.push_back(UnknownIndex); - } - - //printf("\nPerforming Algorithm...\n"); - // Until our queue is empty... - while (!Queue.Heap.empty()) { - // Extract the minimum element of the queue (i.e. the last one). - CostQueueElt E = Queue.popHeap(); - Queue.check_invariants(); - unsigned NodeId = E.NodeId; - - // For each AdjIndex in the adjacentcy list of the node... - for (unsigned AdjNodeIndex : Graph[NodeId]->adjList) { - // Compute the distance from NodeIndex to AdjNodeIndex. If the distance in - // between the two nodes is closer than the current set distance to the - // spanning tree of the adjacent node, set NodeIndex to be the parent of - // AdjNodeIndex and set V's set distance to be that value. - if (Queue.updateCostIfLessThan(AdjNodeIndex, - Fun(Graph[NodeId]->Id, - Graph[AdjNodeIndex]->Id))) - TreeEdges[AdjNodeIndex] = NodeId; - Queue.check_invariants(); - } - - Queue.check_invariants(); - Queue.dump(); - } - -#if 0 - // Make sure that every node is assigned a parent. - for (unsigned i = 0, e = TreeEdges.size(); i != e; ++i) { - unsigned ParentIndex = TreeEdges[i]; - assert(ParentIndex != UnknownIndex && "Found node with unknown parent index" - " set."); - } -#endif -} diff --git a/utils/benchmark/Graph/prims.swift b/utils/benchmark/Graph/prims.swift deleted file mode 100644 index f56facbb12d4e..0000000000000 --- a/utils/benchmark/Graph/prims.swift +++ /dev/null @@ -1,804 +0,0 @@ -//===--- prims.swift - Implementation of Prims MST algorithm --------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See http://swift.org/LICENSE.txt for license information -// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -@_silgen_name("mach_absolute_time") func __mach_absolute_time__() -> UInt64 - -struct Node { - var id : Int - var adjList : Array - - init(i : Int) { - id = i - adjList = Array() - } -} - -struct NodeCost { - var nodeId : Int - var cost : Double -} - -func getLeftChildIndex(index : Int) -> Int { - return index*2 + 1 -} - -func getRightChildIndex(index : Int) -> Int { - return (index + 1)*2 -} - -func getParentIndex(childIndex : Int) -> Int { - return (childIndex - 1)/2 -} - -class PriorityQueue { - var heap : Array - var graphIndexToHeapIndexMap : Array - - init() { - heap = Array() - graphIndexToHeapIndexMap = Array() - } - - // This should only be called when initializing an uninitialized queue. - func append(n : NodeCost?) { - heap.append(n) - graphIndexToHeapIndexMap.append(n!.nodeId) - } - - func dumpDebug() { - print("QUEUE") - for nodeCost in heap { - let nodeId : Int = nodeCost!.nodeId - let cost : Double = nodeCost!.cost - print("(\(nodeId), \(cost))") - } - } - - func contains(i : Int) -> Bool { - for nodeCost in heap { - if nodeCost!.nodeId == i { - return true - } - } - return false - } - - func checkInvariants(graph : Array) { - // If the heap is empty, skip everything. - if heap.isEmpty { - return - } - - var s = Array() - s.append(0) - - while !s.isEmpty { - let index = s.popLast(); - - let leftChild = getLeftChildIndex(index); - let rightChild = getRightChildIndex(index); - - if (leftChild < heap.count) { - if heap[leftChild]!.cost < heap[index]!.cost { - print("Left: \(heap[leftChild]!.cost); Parent: \(heap[index]!.cost)") - } - assert(heap[leftChild]!.cost >= heap[index]!.cost); - s.append(leftChild); - } - if (rightChild < heap.count) { - if heap[rightChild]!.cost < heap[index]!.cost { - print("Right: \(heap[rightChild]!.cost); Parent: \(heap[index]!.cost)") - } - assert(heap[rightChild]!.cost >= heap[index]!.cost); - s.append(rightChild); - } - } - - // Make sure that each element in the graph that is not in the heap has - // its index set to .None - for i in 0..graph.count { - if contains(i) { - assert(graphIndexToHeapIndexMap[i] != .None, - "All items contained in the heap must have an index assigned in map.") - } else { - assert(graphIndexToHeapIndexMap[i] == .None, - "All items not in heap must not have an index assigned in map.") - } - } - } - - // Pop off the smallest cost element, updating all data structures along the - // way. - func popHeap() -> NodeCost { - // If we only have one element, just return it. - if heap.count == 1 { - return heap.popLast()! - } - - // Otherwise swap the heap head with the last element of the heap and pop - // the heap. - swap(&heap[0], &heap[heap.count-1]) - let result = heap.popLast() - - // Invalidate the graph index of our old head and update the graph index of - // the new head value. - graphIndexToHeapIndexMap[heap[0]!.nodeId] = .Some(0) - graphIndexToHeapIndexMap[result!.nodeId] = .None - - // Re-establish the heap property. - var heapIndex = 0 - var smallestIndex : Int - while true { - smallestIndex = updateHeapAtIndex(heapIndex) - if smallestIndex == heapIndex { - break - } - heapIndex = smallestIndex - } - - // Return result. - return result! - } - - func updateCostIfLessThan(graphIndex : Int, newCost : Double) -> Bool { - // Look up the heap index corresponding to the input graph index. - var heapIndex : Int? = graphIndexToHeapIndexMap[graphIndex] - - // If the graph index is not in the heap, return false. - if heapIndex == .None { - return false - } - - // Otherwise, look up the cost of the node. - let nodeCost = heap[heapIndex!] - - // If newCost >= nodeCost.1, don't update anything and return false. - if newCost >= nodeCost!.cost { - return false - } - - // Ok, we know that newCost < nodeCost.1 so replace nodeCost.1 with - // newCost and update all relevant data structures. Return true. - heap[heapIndex!] = .Some(NodeCost(nodeCost!.nodeId, newCost)) - - while heapIndex != .None && heapIndex! > 0 { - heapIndex = .Some(getParentIndex(heapIndex!)) - updateHeapAtIndex(heapIndex!) - } - - return true - } - - - func updateHeapAtIndex(index : Int) -> Int { - let leftChildIndex : Int = getLeftChildIndex(index) - let rightChildIndex : Int = getRightChildIndex(index) - - var smallestIndex : Int = 0 - if leftChildIndex < heap.count && - heap[leftChildIndex]!.cost < heap[index]!.cost { - smallestIndex = leftChildIndex - } else { - smallestIndex = index - } - - if rightChildIndex < heap.count && - heap[rightChildIndex]!.cost < heap[smallestIndex]!.cost { - smallestIndex = rightChildIndex - } - - if smallestIndex != index { - swap(&graphIndexToHeapIndexMap[heap[index]!.nodeId], - &graphIndexToHeapIndexMap[heap[smallestIndex]!.nodeId]) - swap(&heap[index], &heap[smallestIndex]) - } - - return smallestIndex - } - - func isEmpty() -> Bool { - return heap.isEmpty - } -} - -func prim( - graph : Array, - fun : (Int, Int) -> Double) -> Array { - - var treeEdges = Array() - - // Create our queue, selecting the first element of the grpah as the root of - // our tree for simplciity. - var queue = PriorityQueue() - queue.append(.Some(NodeCost(0, 0.0))) - - // Make the minimum spanning tree root its own parent for simplicity. - treeEdges.append(.Some(0)) - - // Create the graph. - for i in 1..graph.count { - queue.append(.Some(NodeCost(i, Double.inf()))) - treeEdges.append(.None) - } - - while !queue.isEmpty() { - let e = queue.popHeap() - let nodeId = e.nodeId - for adjNodeIndex in graph[nodeId].adjList { - if queue.updateCostIfLessThan(adjNodeIndex, fun(graph[nodeId].id, - graph[adjNodeIndex].id)) { - treeEdges[adjNodeIndex] = .Some(nodeId) - } - } - } - - return treeEdges -} - -struct Edge : Equatable { - var start : Int - var end : Int -} - -func ==(lhs: Edge, rhs: Edge) -> Bool { - return lhs.start == rhs.start && lhs.end == rhs.end -} - -extension Edge : Hashable { - func hashValue() -> Int { - return start.hashValue() ^ end.hashValue() - } -} - -func benchPrimsInternal(iterations: Int) { - for i in 0..iterations { - var graph = Array() - - var nodes : Int[] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99 ] - - var edges : (Int, Int, Double)[] = [ - (26, 47, 921), - (20, 25, 971), - (92, 59, 250), - (33, 55, 1391), - (78, 39, 313), - (7, 25, 637), - (18, 19, 1817), - (33, 41, 993), - (64, 41, 926), - (88, 86, 574), - (93, 15, 1462), - (86, 33, 1649), - (37, 35, 841), - (98, 51, 1160), - (15, 30, 1125), - (65, 78, 1052), - (58, 12, 1273), - (12, 17, 285), - (45, 61, 1608), - (75, 53, 545), - (99, 48, 410), - (97, 0, 1303), - (48, 17, 1807), - (1, 54, 1491), - (15, 34, 807), - (94, 98, 646), - (12, 69, 136), - (65, 11, 983), - (63, 83, 1604), - (78, 89, 1828), - (61, 63, 845), - (18, 36, 1626), - (68, 52, 1324), - (14, 50, 690), - (3, 11, 943), - (21, 68, 914), - (19, 44, 1762), - (85, 80, 270), - (59, 92, 250), - (86, 84, 1431), - (19, 18, 1817), - (52, 68, 1324), - (16, 29, 1108), - (36, 80, 395), - (67, 18, 803), - (63, 88, 1717), - (68, 21, 914), - (75, 82, 306), - (49, 82, 1292), - (73, 45, 1876), - (89, 82, 409), - (45, 47, 272), - (22, 83, 597), - (61, 12, 1791), - (44, 68, 1229), - (50, 51, 917), - (14, 53, 355), - (77, 41, 138), - (54, 21, 1870), - (93, 70, 1582), - (76, 2, 1658), - (83, 73, 1162), - (6, 1, 482), - (11, 65, 983), - (81, 90, 1024), - (19, 1, 970), - (8, 58, 1131), - (60, 42, 477), - (86, 29, 258), - (69, 59, 903), - (34, 15, 807), - (37, 2, 1451), - (7, 73, 754), - (47, 86, 184), - (67, 17, 449), - (18, 67, 803), - (25, 4, 595), - (3, 31, 1337), - (64, 31, 1928), - (9, 43, 237), - (83, 63, 1604), - (47, 45, 272), - (86, 88, 574), - (87, 74, 934), - (98, 94, 646), - (20, 1, 642), - (26, 92, 1344), - (18, 17, 565), - (47, 11, 595), - (10, 59, 1558), - (2, 76, 1658), - (77, 74, 1277), - (42, 60, 477), - (80, 36, 395), - (35, 23, 589), - (50, 37, 203), - (6, 96, 481), - (78, 65, 1052), - (1, 52, 127), - (65, 23, 1932), - (46, 51, 213), - (59, 89, 89), - (15, 93, 1462), - (69, 3, 1305), - (17, 37, 1177), - (30, 3, 193), - (9, 15, 818), - (75, 95, 977), - (86, 47, 184), - (10, 12, 1736), - (80, 27, 1010), - (12, 10, 1736), - (86, 1, 1958), - (60, 12, 1240), - (43, 71, 683), - (91, 65, 1519), - (33, 86, 1649), - (62, 26, 1773), - (1, 13, 1187), - (2, 10, 1018), - (91, 29, 351), - (69, 12, 136), - (43, 9, 237), - (29, 86, 258), - (17, 48, 1807), - (31, 64, 1928), - (68, 61, 1936), - (76, 38, 1724), - (1, 6, 482), - (53, 14, 355), - (51, 50, 917), - (54, 13, 815), - (19, 29, 883), - (35, 87, 974), - (70, 96, 511), - (23, 35, 589), - (39, 69, 1588), - (93, 73, 1093), - (13, 73, 435), - (5, 60, 1619), - (42, 41, 1523), - (66, 58, 1596), - (1, 67, 431), - (17, 67, 449), - (30, 95, 906), - (71, 43, 683), - (5, 87, 190), - (12, 78, 891), - (30, 97, 402), - (28, 17, 1131), - (7, 97, 1356), - (58, 66, 1596), - (20, 37, 1294), - (73, 76, 514), - (54, 8, 613), - (68, 35, 1252), - (92, 32, 701), - (3, 90, 652), - (99, 46, 1576), - (13, 54, 815), - (20, 87, 1390), - (36, 18, 1626), - (51, 26, 1146), - (2, 23, 581), - (29, 7, 1558), - (88, 59, 173), - (17, 1, 1071), - (37, 49, 1011), - (18, 6, 696), - (88, 33, 225), - (58, 38, 802), - (87, 50, 1744), - (29, 91, 351), - (6, 71, 1053), - (45, 24, 1720), - (65, 91, 1519), - (37, 50, 203), - (11, 3, 943), - (72, 65, 1330), - (45, 50, 339), - (25, 20, 971), - (15, 9, 818), - (14, 54, 1353), - (69, 95, 393), - (8, 66, 1213), - (52, 2, 1608), - (50, 14, 690), - (50, 45, 339), - (1, 37, 1273), - (45, 93, 1650), - (39, 78, 313), - (1, 86, 1958), - (17, 28, 1131), - (35, 33, 1667), - (23, 2, 581), - (51, 66, 245), - (17, 54, 924), - (41, 49, 1629), - (60, 5, 1619), - (56, 93, 1110), - (96, 13, 461), - (25, 7, 637), - (11, 69, 370), - (90, 3, 652), - (39, 71, 1485), - (65, 51, 1529), - (20, 6, 1414), - (80, 85, 270), - (73, 83, 1162), - (0, 97, 1303), - (13, 33, 826), - (29, 71, 1788), - (33, 12, 461), - (12, 58, 1273), - (69, 39, 1588), - (67, 75, 1504), - (87, 20, 1390), - (88, 97, 526), - (33, 88, 225), - (95, 69, 393), - (2, 52, 1608), - (5, 25, 719), - (34, 78, 510), - (53, 99, 1074), - (33, 35, 1667), - (57, 30, 361), - (87, 58, 1574), - (13, 90, 1030), - (79, 74, 91), - (4, 86, 1107), - (64, 94, 1609), - (11, 12, 167), - (30, 45, 272), - (47, 91, 561), - (37, 17, 1177), - (77, 49, 883), - (88, 23, 1747), - (70, 80, 995), - (62, 77, 907), - (18, 4, 371), - (73, 93, 1093), - (11, 47, 595), - (44, 23, 1990), - (20, 0, 512), - (3, 69, 1305), - (82, 3, 1815), - (20, 88, 368), - (44, 45, 364), - (26, 51, 1146), - (7, 65, 349), - (71, 39, 1485), - (56, 88, 1954), - (94, 69, 1397), - (12, 28, 544), - (95, 75, 977), - (32, 90, 789), - (53, 1, 772), - (54, 14, 1353), - (49, 77, 883), - (92, 26, 1344), - (17, 18, 565), - (97, 88, 526), - (48, 80, 1203), - (90, 32, 789), - (71, 6, 1053), - (87, 35, 974), - (55, 90, 1808), - (12, 61, 1791), - (1, 96, 328), - (63, 10, 1681), - (76, 34, 871), - (41, 64, 926), - (42, 97, 482), - (25, 5, 719), - (23, 65, 1932), - (54, 1, 1491), - (28, 12, 544), - (89, 10, 108), - (27, 33, 143), - (67, 1, 431), - (32, 45, 52), - (79, 33, 1871), - (6, 55, 717), - (10, 58, 459), - (67, 39, 393), - (10, 4, 1808), - (96, 6, 481), - (1, 19, 970), - (97, 7, 1356), - (29, 16, 1108), - (1, 53, 772), - (30, 15, 1125), - (4, 6, 634), - (6, 20, 1414), - (88, 56, 1954), - (87, 64, 1950), - (34, 76, 871), - (17, 12, 285), - (55, 59, 321), - (61, 68, 1936), - (50, 87, 1744), - (84, 44, 952), - (41, 33, 993), - (59, 18, 1352), - (33, 27, 143), - (38, 32, 1210), - (55, 70, 1264), - (38, 58, 802), - (1, 20, 642), - (73, 13, 435), - (80, 48, 1203), - (94, 64, 1609), - (38, 28, 414), - (73, 23, 1113), - (78, 12, 891), - (26, 62, 1773), - (87, 43, 579), - (53, 6, 95), - (59, 95, 285), - (88, 63, 1717), - (17, 5, 633), - (66, 8, 1213), - (41, 42, 1523), - (83, 22, 597), - (95, 30, 906), - (51, 65, 1529), - (17, 49, 1727), - (64, 87, 1950), - (86, 4, 1107), - (37, 98, 1102), - (32, 92, 701), - (60, 94, 198), - (73, 98, 1749), - (4, 18, 371), - (96, 70, 511), - (7, 29, 1558), - (35, 37, 841), - (27, 64, 384), - (12, 33, 461), - (36, 38, 529), - (69, 16, 1183), - (91, 47, 561), - (85, 29, 1676), - (3, 82, 1815), - (69, 58, 1579), - (93, 45, 1650), - (97, 42, 482), - (37, 1, 1273), - (61, 4, 543), - (96, 1, 328), - (26, 0, 1993), - (70, 64, 878), - (3, 30, 193), - (58, 69, 1579), - (4, 25, 595), - (31, 3, 1337), - (55, 6, 717), - (39, 67, 393), - (78, 34, 510), - (75, 67, 1504), - (6, 53, 95), - (51, 79, 175), - (28, 91, 1040), - (89, 78, 1828), - (74, 93, 1587), - (45, 32, 52), - (10, 2, 1018), - (49, 37, 1011), - (63, 61, 845), - (0, 20, 512), - (1, 17, 1071), - (99, 53, 1074), - (37, 20, 1294), - (10, 89, 108), - (33, 92, 946), - (23, 73, 1113), - (23, 88, 1747), - (49, 17, 1727), - (88, 20, 368), - (21, 54, 1870), - (70, 93, 1582), - (59, 88, 173), - (32, 38, 1210), - (89, 59, 89), - (23, 44, 1990), - (38, 76, 1724), - (30, 57, 361), - (94, 60, 198), - (59, 10, 1558), - (55, 64, 1996), - (12, 11, 167), - (36, 24, 1801), - (97, 30, 402), - (52, 1, 127), - (58, 87, 1574), - (54, 17, 924), - (93, 74, 1587), - (24, 36, 1801), - (2, 37, 1451), - (91, 28, 1040), - (59, 55, 321), - (69, 11, 370), - (8, 54, 613), - (29, 85, 1676), - (44, 19, 1762), - (74, 79, 91), - (93, 56, 1110), - (58, 10, 459), - (41, 50, 1559), - (66, 51, 245), - (80, 19, 1838), - (33, 79, 1871), - (76, 73, 514), - (98, 37, 1102), - (45, 44, 364), - (16, 69, 1183), - (49, 41, 1629), - (19, 80, 1838), - (71, 57, 500), - (6, 4, 634), - (64, 27, 384), - (84, 86, 1431), - (5, 17, 633), - (96, 88, 334), - (87, 5, 190), - (70, 21, 1619), - (55, 33, 1391), - (10, 63, 1681), - (11, 62, 1339), - (33, 13, 826), - (64, 70, 878), - (65, 72, 1330), - (70, 55, 1264), - (64, 55, 1996), - (50, 41, 1559), - (46, 99, 1576), - (88, 96, 334), - (51, 20, 868), - (73, 7, 754), - (80, 70, 995), - (44, 84, 952), - (29, 19, 883), - (59, 69, 903), - (57, 53, 1575), - (90, 13, 1030), - (28, 38, 414), - (12, 60, 1240), - (85, 58, 573), - (90, 55, 1808), - (4, 10, 1808), - (68, 44, 1229), - (92, 33, 946), - (90, 81, 1024), - (53, 75, 545), - (45, 30, 272), - (41, 77, 138), - (21, 70, 1619), - (45, 73, 1876), - (35, 68, 1252), - (13, 96, 461), - (53, 57, 1575), - (82, 89, 409), - (28, 61, 449), - (58, 61, 78), - (27, 80, 1010), - (61, 58, 78), - (38, 36, 529), - (80, 30, 397), - (18, 59, 1352), - (62, 11, 1339), - (95, 59, 285), - (51, 98, 1160), - (6, 18, 696), - (30, 80, 397), - (69, 94, 1397), - (58, 85, 573), - (48, 99, 410), - (51, 46, 213), - (57, 71, 500), - (91, 30, 104), - (65, 7, 349), - (79, 51, 175), - (47, 26, 921), - (4, 61, 543), - (98, 73, 1749), - (74, 77, 1277), - (61, 28, 449), - (58, 8, 1131), - (61, 45, 1608), - (74, 87, 934), - (71, 29, 1788), - (30, 91, 104), - (13, 1, 1187), - (0, 26, 1993), - (82, 49, 1292), - (43, 87, 579), - (24, 45, 1720), - (20, 51, 868), - (77, 62, 907), - (82, 75, 306), - ] - - for n in nodes { - graph.append(Node(n)) - } - - var map = Dictionary() - for tup in edges { - map.add(Edge(tup.0, tup.1), tup.2) - graph[tup.0].adjList.append(tup.1) - } - - let treeEdges = prim(graph, { (start: Int, end: Int) in - return map[Edge(start, end)] - }) - - //for i in 0...treeEdges.count { - // print("Node: \(i). Parent: \(treeEdges[i]!)") - //} - } -} - -func benchPrims() { - let start = __mach_absolute_time__() - benchPrimsInternal(100) - let delta = __mach_absolute_time__() - start - print("\(delta) nanoseconds.") -} - -benchPrims() diff --git a/utils/benchmark/Graph/small-data b/utils/benchmark/Graph/small-data deleted file mode 100644 index 1cc25c2230004..0000000000000 --- a/utils/benchmark/Graph/small-data +++ /dev/null @@ -1,602 +0,0 @@ -GRAPH NODES -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -GRAPH EDGES -(26, 47, 921) -(20, 25, 971) -(92, 59, 250) -(33, 55, 1391) -(78, 39, 313) -(7, 25, 637) -(18, 19, 1817) -(33, 41, 993) -(64, 41, 926) -(88, 86, 574) -(93, 15, 1462) -(86, 33, 1649) -(37, 35, 841) -(98, 51, 1160) -(15, 30, 1125) -(65, 78, 1052) -(58, 12, 1273) -(12, 17, 285) -(45, 61, 1608) -(75, 53, 545) -(99, 48, 410) -(97, 0, 1303) -(48, 17, 1807) -(1, 54, 1491) -(15, 34, 807) -(94, 98, 646) -(12, 69, 136) -(65, 11, 983) -(63, 83, 1604) -(78, 89, 1828) -(61, 63, 845) -(18, 36, 1626) -(68, 52, 1324) -(14, 50, 690) -(3, 11, 943) -(21, 68, 914) -(19, 44, 1762) -(85, 80, 270) -(59, 92, 250) -(86, 84, 1431) -(19, 18, 1817) -(52, 68, 1324) -(16, 29, 1108) -(36, 80, 395) -(67, 18, 803) -(63, 88, 1717) -(68, 21, 914) -(75, 82, 306) -(49, 82, 1292) -(73, 45, 1876) -(89, 82, 409) -(45, 47, 272) -(22, 83, 597) -(61, 12, 1791) -(44, 68, 1229) -(50, 51, 917) -(14, 53, 355) -(77, 41, 138) -(54, 21, 1870) -(93, 70, 1582) -(76, 2, 1658) -(83, 73, 1162) -(6, 1, 482) -(11, 65, 983) -(81, 90, 1024) -(19, 1, 970) -(8, 58, 1131) -(60, 42, 477) -(86, 29, 258) -(69, 59, 903) -(34, 15, 807) -(37, 2, 1451) -(7, 73, 754) -(47, 86, 184) -(67, 17, 449) -(18, 67, 803) -(25, 4, 595) -(3, 31, 1337) -(64, 31, 1928) -(9, 43, 237) -(83, 63, 1604) -(47, 45, 272) -(86, 88, 574) -(87, 74, 934) -(98, 94, 646) -(20, 1, 642) -(26, 92, 1344) -(18, 17, 565) -(47, 11, 595) -(10, 59, 1558) -(2, 76, 1658) -(77, 74, 1277) -(42, 60, 477) -(80, 36, 395) -(35, 23, 589) -(50, 37, 203) -(6, 96, 481) -(78, 65, 1052) -(1, 52, 127) -(65, 23, 1932) -(46, 51, 213) -(59, 89, 89) -(15, 93, 1462) -(69, 3, 1305) -(17, 37, 1177) -(30, 3, 193) -(9, 15, 818) -(75, 95, 977) -(86, 47, 184) -(10, 12, 1736) -(80, 27, 1010) -(12, 10, 1736) -(86, 1, 1958) -(60, 12, 1240) -(43, 71, 683) -(91, 65, 1519) -(33, 86, 1649) -(62, 26, 1773) -(1, 13, 1187) -(2, 10, 1018) -(91, 29, 351) -(69, 12, 136) -(43, 9, 237) -(29, 86, 258) -(17, 48, 1807) -(31, 64, 1928) -(68, 61, 1936) -(76, 38, 1724) -(1, 6, 482) -(53, 14, 355) -(51, 50, 917) -(54, 13, 815) -(19, 29, 883) -(35, 87, 974) -(70, 96, 511) -(23, 35, 589) -(39, 69, 1588) -(93, 73, 1093) -(13, 73, 435) -(5, 60, 1619) -(42, 41, 1523) -(66, 58, 1596) -(1, 67, 431) -(17, 67, 449) -(30, 95, 906) -(71, 43, 683) -(5, 87, 190) -(12, 78, 891) -(30, 97, 402) -(28, 17, 1131) -(7, 97, 1356) -(58, 66, 1596) -(20, 37, 1294) -(73, 76, 514) -(54, 8, 613) -(68, 35, 1252) -(92, 32, 701) -(3, 90, 652) -(99, 46, 1576) -(13, 54, 815) -(20, 87, 1390) -(36, 18, 1626) -(51, 26, 1146) -(2, 23, 581) -(29, 7, 1558) -(88, 59, 173) -(17, 1, 1071) -(37, 49, 1011) -(18, 6, 696) -(88, 33, 225) -(58, 38, 802) -(87, 50, 1744) -(29, 91, 351) -(6, 71, 1053) -(45, 24, 1720) -(65, 91, 1519) -(37, 50, 203) -(11, 3, 943) -(72, 65, 1330) -(45, 50, 339) -(25, 20, 971) -(15, 9, 818) -(14, 54, 1353) -(69, 95, 393) -(8, 66, 1213) -(52, 2, 1608) -(50, 14, 690) -(50, 45, 339) -(1, 37, 1273) -(45, 93, 1650) -(39, 78, 313) -(1, 86, 1958) -(17, 28, 1131) -(35, 33, 1667) -(23, 2, 581) -(51, 66, 245) -(17, 54, 924) -(41, 49, 1629) -(60, 5, 1619) -(56, 93, 1110) -(96, 13, 461) -(25, 7, 637) -(11, 69, 370) -(90, 3, 652) -(39, 71, 1485) -(65, 51, 1529) -(20, 6, 1414) -(80, 85, 270) -(73, 83, 1162) -(0, 97, 1303) -(13, 33, 826) -(29, 71, 1788) -(33, 12, 461) -(12, 58, 1273) -(69, 39, 1588) -(67, 75, 1504) -(87, 20, 1390) -(88, 97, 526) -(33, 88, 225) -(95, 69, 393) -(2, 52, 1608) -(5, 25, 719) -(34, 78, 510) -(53, 99, 1074) -(33, 35, 1667) -(57, 30, 361) -(87, 58, 1574) -(13, 90, 1030) -(79, 74, 91) -(4, 86, 1107) -(64, 94, 1609) -(11, 12, 167) -(30, 45, 272) -(47, 91, 561) -(37, 17, 1177) -(77, 49, 883) -(88, 23, 1747) -(70, 80, 995) -(62, 77, 907) -(18, 4, 371) -(73, 93, 1093) -(11, 47, 595) -(44, 23, 1990) -(20, 0, 512) -(3, 69, 1305) -(82, 3, 1815) -(20, 88, 368) -(44, 45, 364) -(26, 51, 1146) -(7, 65, 349) -(71, 39, 1485) -(56, 88, 1954) -(94, 69, 1397) -(12, 28, 544) -(95, 75, 977) -(32, 90, 789) -(53, 1, 772) -(54, 14, 1353) -(49, 77, 883) -(92, 26, 1344) -(17, 18, 565) -(97, 88, 526) -(48, 80, 1203) -(90, 32, 789) -(71, 6, 1053) -(87, 35, 974) -(55, 90, 1808) -(12, 61, 1791) -(1, 96, 328) -(63, 10, 1681) -(76, 34, 871) -(41, 64, 926) -(42, 97, 482) -(25, 5, 719) -(23, 65, 1932) -(54, 1, 1491) -(28, 12, 544) -(89, 10, 108) -(27, 33, 143) -(67, 1, 431) -(32, 45, 52) -(79, 33, 1871) -(6, 55, 717) -(10, 58, 459) -(67, 39, 393) -(10, 4, 1808) -(96, 6, 481) -(1, 19, 970) -(97, 7, 1356) -(29, 16, 1108) -(1, 53, 772) -(30, 15, 1125) -(4, 6, 634) -(6, 20, 1414) -(88, 56, 1954) -(87, 64, 1950) -(34, 76, 871) -(17, 12, 285) -(55, 59, 321) -(61, 68, 1936) -(50, 87, 1744) -(84, 44, 952) -(41, 33, 993) -(59, 18, 1352) -(33, 27, 143) -(38, 32, 1210) -(55, 70, 1264) -(38, 58, 802) -(1, 20, 642) -(73, 13, 435) -(80, 48, 1203) -(94, 64, 1609) -(38, 28, 414) -(73, 23, 1113) -(78, 12, 891) -(26, 62, 1773) -(87, 43, 579) -(53, 6, 95) -(59, 95, 285) -(88, 63, 1717) -(17, 5, 633) -(66, 8, 1213) -(41, 42, 1523) -(83, 22, 597) -(95, 30, 906) -(51, 65, 1529) -(17, 49, 1727) -(64, 87, 1950) -(86, 4, 1107) -(37, 98, 1102) -(32, 92, 701) -(60, 94, 198) -(73, 98, 1749) -(4, 18, 371) -(96, 70, 511) -(7, 29, 1558) -(35, 37, 841) -(27, 64, 384) -(12, 33, 461) -(36, 38, 529) -(69, 16, 1183) -(91, 47, 561) -(85, 29, 1676) -(3, 82, 1815) -(69, 58, 1579) -(93, 45, 1650) -(97, 42, 482) -(37, 1, 1273) -(61, 4, 543) -(96, 1, 328) -(26, 0, 1993) -(70, 64, 878) -(3, 30, 193) -(58, 69, 1579) -(4, 25, 595) -(31, 3, 1337) -(55, 6, 717) -(39, 67, 393) -(78, 34, 510) -(75, 67, 1504) -(6, 53, 95) -(51, 79, 175) -(28, 91, 1040) -(89, 78, 1828) -(74, 93, 1587) -(45, 32, 52) -(10, 2, 1018) -(49, 37, 1011) -(63, 61, 845) -(0, 20, 512) -(1, 17, 1071) -(99, 53, 1074) -(37, 20, 1294) -(10, 89, 108) -(33, 92, 946) -(23, 73, 1113) -(23, 88, 1747) -(49, 17, 1727) -(88, 20, 368) -(21, 54, 1870) -(70, 93, 1582) -(59, 88, 173) -(32, 38, 1210) -(89, 59, 89) -(23, 44, 1990) -(38, 76, 1724) -(30, 57, 361) -(94, 60, 198) -(59, 10, 1558) -(55, 64, 1996) -(12, 11, 167) -(36, 24, 1801) -(97, 30, 402) -(52, 1, 127) -(58, 87, 1574) -(54, 17, 924) -(93, 74, 1587) -(24, 36, 1801) -(2, 37, 1451) -(91, 28, 1040) -(59, 55, 321) -(69, 11, 370) -(8, 54, 613) -(29, 85, 1676) -(44, 19, 1762) -(74, 79, 91) -(93, 56, 1110) -(58, 10, 459) -(41, 50, 1559) -(66, 51, 245) -(80, 19, 1838) -(33, 79, 1871) -(76, 73, 514) -(98, 37, 1102) -(45, 44, 364) -(16, 69, 1183) -(49, 41, 1629) -(19, 80, 1838) -(71, 57, 500) -(6, 4, 634) -(64, 27, 384) -(84, 86, 1431) -(5, 17, 633) -(96, 88, 334) -(87, 5, 190) -(70, 21, 1619) -(55, 33, 1391) -(10, 63, 1681) -(11, 62, 1339) -(33, 13, 826) -(64, 70, 878) -(65, 72, 1330) -(70, 55, 1264) -(64, 55, 1996) -(50, 41, 1559) -(46, 99, 1576) -(88, 96, 334) -(51, 20, 868) -(73, 7, 754) -(80, 70, 995) -(44, 84, 952) -(29, 19, 883) -(59, 69, 903) -(57, 53, 1575) -(90, 13, 1030) -(28, 38, 414) -(12, 60, 1240) -(85, 58, 573) -(90, 55, 1808) -(4, 10, 1808) -(68, 44, 1229) -(92, 33, 946) -(90, 81, 1024) -(53, 75, 545) -(45, 30, 272) -(41, 77, 138) -(21, 70, 1619) -(45, 73, 1876) -(35, 68, 1252) -(13, 96, 461) -(53, 57, 1575) -(82, 89, 409) -(28, 61, 449) -(58, 61, 78) -(27, 80, 1010) -(61, 58, 78) -(38, 36, 529) -(80, 30, 397) -(18, 59, 1352) -(62, 11, 1339) -(95, 59, 285) -(51, 98, 1160) -(6, 18, 696) -(30, 80, 397) -(69, 94, 1397) -(58, 85, 573) -(48, 99, 410) -(51, 46, 213) -(57, 71, 500) -(91, 30, 104) -(65, 7, 349) -(79, 51, 175) -(47, 26, 921) -(4, 61, 543) -(98, 73, 1749) -(74, 77, 1277) -(61, 28, 449) -(58, 8, 1131) -(61, 45, 1608) -(74, 87, 934) -(71, 29, 1788) -(30, 91, 104) -(13, 1, 1187) -(0, 26, 1993) -(82, 49, 1292) -(43, 87, 579) -(24, 45, 1720) -(20, 51, 868) -(77, 62, 907) -(82, 75, 306) diff --git a/utils/benchmark/Graph/test-prims.cpp b/utils/benchmark/Graph/test-prims.cpp deleted file mode 100644 index 201e835fef2f5..0000000000000 --- a/utils/benchmark/Graph/test-prims.cpp +++ /dev/null @@ -1,558 +0,0 @@ - -#include -#include -#include -#include - -#include "graph.h" -using namespace graph; - -static bool scan_header(FILE *f, const char *str1, const char *str2) { - char buf1[128], buf2[128]; - if (2 != fscanf(f, "%s %s\n", buf1, buf2) || - strcmp(buf1, str1) != 0 || - strcmp(buf2, str2) != 0) { - return false; - } - - return true; -} - -int main(int argc, char *argv[]) { - // Use predefined small dataset. - std::vector nodes = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99 }; - - std::vector, double>> edges = { - {{26, 47}, 921}, - {{20, 25}, 971}, - {{92, 59}, 250}, - {{33, 55}, 1391}, - {{78, 39}, 313}, - {{7, 25}, 637}, - {{18, 19}, 1817}, - {{33, 41}, 993}, - {{64, 41}, 926}, - {{88, 86}, 574}, - {{93, 15}, 1462}, - {{86, 33}, 1649}, - {{37, 35}, 841}, - {{98, 51}, 1160}, - {{15, 30}, 1125}, - {{65, 78}, 1052}, - {{58, 12}, 1273}, - {{12, 17}, 285}, - {{45, 61}, 1608}, - {{75, 53}, 545}, - {{99, 48}, 410}, - {{97, 0}, 1303}, - {{48, 17}, 1807}, - {{1, 54}, 1491}, - {{15, 34}, 807}, - {{94, 98}, 646}, - {{12, 69}, 136}, - {{65, 11}, 983}, - {{63, 83}, 1604}, - {{78, 89}, 1828}, - {{61, 63}, 845}, - {{18, 36}, 1626}, - {{68, 52}, 1324}, - {{14, 50}, 690}, - {{3, 11}, 943}, - {{21, 68}, 914}, - {{19, 44}, 1762}, - {{85, 80}, 270}, - {{59, 92}, 250}, - {{86, 84}, 1431}, - {{19, 18}, 1817}, - {{52, 68}, 1324}, - {{16, 29}, 1108}, - {{36, 80}, 395}, - {{67, 18}, 803}, - {{63, 88}, 1717}, - {{68, 21}, 914}, - {{75, 82}, 306}, - {{49, 82}, 1292}, - {{73, 45}, 1876}, - {{89, 82}, 409}, - {{45, 47}, 272}, - {{22, 83}, 597}, - {{61, 12}, 1791}, - {{44, 68}, 1229}, - {{50, 51}, 917}, - {{14, 53}, 355}, - {{77, 41}, 138}, - {{54, 21}, 1870}, - {{93, 70}, 1582}, - {{76, 2}, 1658}, - {{83, 73}, 1162}, - {{6, 1}, 482}, - {{11, 65}, 983}, - {{81, 90}, 1024}, - {{19, 1}, 970}, - {{8, 58}, 1131}, - {{60, 42}, 477}, - {{86, 29}, 258}, - {{69, 59}, 903}, - {{34, 15}, 807}, - {{37, 2}, 1451}, - {{7, 73}, 754}, - {{47, 86}, 184}, - {{67, 17}, 449}, - {{18, 67}, 803}, - {{25, 4}, 595}, - {{3, 31}, 1337}, - {{64, 31}, 1928}, - {{9, 43}, 237}, - {{83, 63}, 1604}, - {{47, 45}, 272}, - {{86, 88}, 574}, - {{87, 74}, 934}, - {{98, 94}, 646}, - {{20, 1}, 642}, - {{26, 92}, 1344}, - {{18, 17}, 565}, - {{47, 11}, 595}, - {{10, 59}, 1558}, - {{2, 76}, 1658}, - {{77, 74}, 1277}, - {{42, 60}, 477}, - {{80, 36}, 395}, - {{35, 23}, 589}, - {{50, 37}, 203}, - {{6, 96}, 481}, - {{78, 65}, 1052}, - {{1, 52}, 127}, - {{65, 23}, 1932}, - {{46, 51}, 213}, - {{59, 89}, 89}, - {{15, 93}, 1462}, - {{69, 3}, 1305}, - {{17, 37}, 1177}, - {{30, 3}, 193}, - {{9, 15}, 818}, - {{75, 95}, 977}, - {{86, 47}, 184}, - {{10, 12}, 1736}, - {{80, 27}, 1010}, - {{12, 10}, 1736}, - {{86, 1}, 1958}, - {{60, 12}, 1240}, - {{43, 71}, 683}, - {{91, 65}, 1519}, - {{33, 86}, 1649}, - {{62, 26}, 1773}, - {{1, 13}, 1187}, - {{2, 10}, 1018}, - {{91, 29}, 351}, - {{69, 12}, 136}, - {{43, 9}, 237}, - {{29, 86}, 258}, - {{17, 48}, 1807}, - {{31, 64}, 1928}, - {{68, 61}, 1936}, - {{76, 38}, 1724}, - {{1, 6}, 482}, - {{53, 14}, 355}, - {{51, 50}, 917}, - {{54, 13}, 815}, - {{19, 29}, 883}, - {{35, 87}, 974}, - {{70, 96}, 511}, - {{23, 35}, 589}, - {{39, 69}, 1588}, - {{93, 73}, 1093}, - {{13, 73}, 435}, - {{5, 60}, 1619}, - {{42, 41}, 1523}, - {{66, 58}, 1596}, - {{1, 67}, 431}, - {{17, 67}, 449}, - {{30, 95}, 906}, - {{71, 43}, 683}, - {{5, 87}, 190}, - {{12, 78}, 891}, - {{30, 97}, 402}, - {{28, 17}, 1131}, - {{7, 97}, 1356}, - {{58, 66}, 1596}, - {{20, 37}, 1294}, - {{73, 76}, 514}, - {{54, 8}, 613}, - {{68, 35}, 1252}, - {{92, 32}, 701}, - {{3, 90}, 652}, - {{99, 46}, 1576}, - {{13, 54}, 815}, - {{20, 87}, 1390}, - {{36, 18}, 1626}, - {{51, 26}, 1146}, - {{2, 23}, 581}, - {{29, 7}, 1558}, - {{88, 59}, 173}, - {{17, 1}, 1071}, - {{37, 49}, 1011}, - {{18, 6}, 696}, - {{88, 33}, 225}, - {{58, 38}, 802}, - {{87, 50}, 1744}, - {{29, 91}, 351}, - {{6, 71}, 1053}, - {{45, 24}, 1720}, - {{65, 91}, 1519}, - {{37, 50}, 203}, - {{11, 3}, 943}, - {{72, 65}, 1330}, - {{45, 50}, 339}, - {{25, 20}, 971}, - {{15, 9}, 818}, - {{14, 54}, 1353}, - {{69, 95}, 393}, - {{8, 66}, 1213}, - {{52, 2}, 1608}, - {{50, 14}, 690}, - {{50, 45}, 339}, - {{1, 37}, 1273}, - {{45, 93}, 1650}, - {{39, 78}, 313}, - {{1, 86}, 1958}, - {{17, 28}, 1131}, - {{35, 33}, 1667}, - {{23, 2}, 581}, - {{51, 66}, 245}, - {{17, 54}, 924}, - {{41, 49}, 1629}, - {{60, 5}, 1619}, - {{56, 93}, 1110}, - {{96, 13}, 461}, - {{25, 7}, 637}, - {{11, 69}, 370}, - {{90, 3}, 652}, - {{39, 71}, 1485}, - {{65, 51}, 1529}, - {{20, 6}, 1414}, - {{80, 85}, 270}, - {{73, 83}, 1162}, - {{0, 97}, 1303}, - {{13, 33}, 826}, - {{29, 71}, 1788}, - {{33, 12}, 461}, - {{12, 58}, 1273}, - {{69, 39}, 1588}, - {{67, 75}, 1504}, - {{87, 20}, 1390}, - {{88, 97}, 526}, - {{33, 88}, 225}, - {{95, 69}, 393}, - {{2, 52}, 1608}, - {{5, 25}, 719}, - {{34, 78}, 510}, - {{53, 99}, 1074}, - {{33, 35}, 1667}, - {{57, 30}, 361}, - {{87, 58}, 1574}, - {{13, 90}, 1030}, - {{79, 74}, 91}, - {{4, 86}, 1107}, - {{64, 94}, 1609}, - {{11, 12}, 167}, - {{30, 45}, 272}, - {{47, 91}, 561}, - {{37, 17}, 1177}, - {{77, 49}, 883}, - {{88, 23}, 1747}, - {{70, 80}, 995}, - {{62, 77}, 907}, - {{18, 4}, 371}, - {{73, 93}, 1093}, - {{11, 47}, 595}, - {{44, 23}, 1990}, - {{20, 0}, 512}, - {{3, 69}, 1305}, - {{82, 3}, 1815}, - {{20, 88}, 368}, - {{44, 45}, 364}, - {{26, 51}, 1146}, - {{7, 65}, 349}, - {{71, 39}, 1485}, - {{56, 88}, 1954}, - {{94, 69}, 1397}, - {{12, 28}, 544}, - {{95, 75}, 977}, - {{32, 90}, 789}, - {{53, 1}, 772}, - {{54, 14}, 1353}, - {{49, 77}, 883}, - {{92, 26}, 1344}, - {{17, 18}, 565}, - {{97, 88}, 526}, - {{48, 80}, 1203}, - {{90, 32}, 789}, - {{71, 6}, 1053}, - {{87, 35}, 974}, - {{55, 90}, 1808}, - {{12, 61}, 1791}, - {{1, 96}, 328}, - {{63, 10}, 1681}, - {{76, 34}, 871}, - {{41, 64}, 926}, - {{42, 97}, 482}, - {{25, 5}, 719}, - {{23, 65}, 1932}, - {{54, 1}, 1491}, - {{28, 12}, 544}, - {{89, 10}, 108}, - {{27, 33}, 143}, - {{67, 1}, 431}, - {{32, 45}, 52}, - {{79, 33}, 1871}, - {{6, 55}, 717}, - {{10, 58}, 459}, - {{67, 39}, 393}, - {{10, 4}, 1808}, - {{96, 6}, 481}, - {{1, 19}, 970}, - {{97, 7}, 1356}, - {{29, 16}, 1108}, - {{1, 53}, 772}, - {{30, 15}, 1125}, - {{4, 6}, 634}, - {{6, 20}, 1414}, - {{88, 56}, 1954}, - {{87, 64}, 1950}, - {{34, 76}, 871}, - {{17, 12}, 285}, - {{55, 59}, 321}, - {{61, 68}, 1936}, - {{50, 87}, 1744}, - {{84, 44}, 952}, - {{41, 33}, 993}, - {{59, 18}, 1352}, - {{33, 27}, 143}, - {{38, 32}, 1210}, - {{55, 70}, 1264}, - {{38, 58}, 802}, - {{1, 20}, 642}, - {{73, 13}, 435}, - {{80, 48}, 1203}, - {{94, 64}, 1609}, - {{38, 28}, 414}, - {{73, 23}, 1113}, - {{78, 12}, 891}, - {{26, 62}, 1773}, - {{87, 43}, 579}, - {{53, 6}, 95}, - {{59, 95}, 285}, - {{88, 63}, 1717}, - {{17, 5}, 633}, - {{66, 8}, 1213}, - {{41, 42}, 1523}, - {{83, 22}, 597}, - {{95, 30}, 906}, - {{51, 65}, 1529}, - {{17, 49}, 1727}, - {{64, 87}, 1950}, - {{86, 4}, 1107}, - {{37, 98}, 1102}, - {{32, 92}, 701}, - {{60, 94}, 198}, - {{73, 98}, 1749}, - {{4, 18}, 371}, - {{96, 70}, 511}, - {{7, 29}, 1558}, - {{35, 37}, 841}, - {{27, 64}, 384}, - {{12, 33}, 461}, - {{36, 38}, 529}, - {{69, 16}, 1183}, - {{91, 47}, 561}, - {{85, 29}, 1676}, - {{3, 82}, 1815}, - {{69, 58}, 1579}, - {{93, 45}, 1650}, - {{97, 42}, 482}, - {{37, 1}, 1273}, - {{61, 4}, 543}, - {{96, 1}, 328}, - {{26, 0}, 1993}, - {{70, 64}, 878}, - {{3, 30}, 193}, - {{58, 69}, 1579}, - {{4, 25}, 595}, - {{31, 3}, 1337}, - {{55, 6}, 717}, - {{39, 67}, 393}, - {{78, 34}, 510}, - {{75, 67}, 1504}, - {{6, 53}, 95}, - {{51, 79}, 175}, - {{28, 91}, 1040}, - {{89, 78}, 1828}, - {{74, 93}, 1587}, - {{45, 32}, 52}, - {{10, 2}, 1018}, - {{49, 37}, 1011}, - {{63, 61}, 845}, - {{0, 20}, 512}, - {{1, 17}, 1071}, - {{99, 53}, 1074}, - {{37, 20}, 1294}, - {{10, 89}, 108}, - {{33, 92}, 946}, - {{23, 73}, 1113}, - {{23, 88}, 1747}, - {{49, 17}, 1727}, - {{88, 20}, 368}, - {{21, 54}, 1870}, - {{70, 93}, 1582}, - {{59, 88}, 173}, - {{32, 38}, 1210}, - {{89, 59}, 89}, - {{23, 44}, 1990}, - {{38, 76}, 1724}, - {{30, 57}, 361}, - {{94, 60}, 198}, - {{59, 10}, 1558}, - {{55, 64}, 1996}, - {{12, 11}, 167}, - {{36, 24}, 1801}, - {{97, 30}, 402}, - {{52, 1}, 127}, - {{58, 87}, 1574}, - {{54, 17}, 924}, - {{93, 74}, 1587}, - {{24, 36}, 1801}, - {{2, 37}, 1451}, - {{91, 28}, 1040}, - {{59, 55}, 321}, - {{69, 11}, 370}, - {{8, 54}, 613}, - {{29, 85}, 1676}, - {{44, 19}, 1762}, - {{74, 79}, 91}, - {{93, 56}, 1110}, - {{58, 10}, 459}, - {{41, 50}, 1559}, - {{66, 51}, 245}, - {{80, 19}, 1838}, - {{33, 79}, 1871}, - {{76, 73}, 514}, - {{98, 37}, 1102}, - {{45, 44}, 364}, - {{16, 69}, 1183}, - {{49, 41}, 1629}, - {{19, 80}, 1838}, - {{71, 57}, 500}, - {{6, 4}, 634}, - {{64, 27}, 384}, - {{84, 86}, 1431}, - {{5, 17}, 633}, - {{96, 88}, 334}, - {{87, 5}, 190}, - {{70, 21}, 1619}, - {{55, 33}, 1391}, - {{10, 63}, 1681}, - {{11, 62}, 1339}, - {{33, 13}, 826}, - {{64, 70}, 878}, - {{65, 72}, 1330}, - {{70, 55}, 1264}, - {{64, 55}, 1996}, - {{50, 41}, 1559}, - {{46, 99}, 1576}, - {{88, 96}, 334}, - {{51, 20}, 868}, - {{73, 7}, 754}, - {{80, 70}, 995}, - {{44, 84}, 952}, - {{29, 19}, 883}, - {{59, 69}, 903}, - {{57, 53}, 1575}, - {{90, 13}, 1030}, - {{28, 38}, 414}, - {{12, 60}, 1240}, - {{85, 58}, 573}, - {{90, 55}, 1808}, - {{4, 10}, 1808}, - {{68, 44}, 1229}, - {{92, 33}, 946}, - {{90, 81}, 1024}, - {{53, 75}, 545}, - {{45, 30}, 272}, - {{41, 77}, 138}, - {{21, 70}, 1619}, - {{45, 73}, 1876}, - {{35, 68}, 1252}, - {{13, 96}, 461}, - {{53, 57}, 1575}, - {{82, 89}, 409}, - {{28, 61}, 449}, - {{58, 61}, 78}, - {{27, 80}, 1010}, - {{61, 58}, 78}, - {{38, 36}, 529}, - {{80, 30}, 397}, - {{18, 59}, 1352}, - {{62, 11}, 1339}, - {{95, 59}, 285}, - {{51, 98}, 1160}, - {{6, 18}, 696}, - {{30, 80}, 397}, - {{69, 94}, 1397}, - {{58, 85}, 573}, - {{48, 99}, 410}, - {{51, 46}, 213}, - {{57, 71}, 500}, - {{91, 30}, 104}, - {{65, 7}, 349}, - {{79, 51}, 175}, - {{47, 26}, 921}, - {{4, 61}, 543}, - {{98, 73}, 1749}, - {{74, 77}, 1277}, - {{61, 28}, 449}, - {{58, 8}, 1131}, - {{61, 45}, 1608}, - {{74, 87}, 934}, - {{71, 29}, 1788}, - {{30, 91}, 104}, - {{13, 1}, 1187}, - {{0, 26}, 1993}, - {{82, 49}, 1292}, - {{43, 87}, 579}, - {{24, 45}, 1720}, - {{20, 51}, 868}, - {{77, 62}, 907}, - {{82, 75}, 306}, - }; - - for (unsigned i = 0; i < 10000; i++) { - // Match how the swift version will be instantiating the graph list and edge - // list for every iteration. - std::vector graph; - for (unsigned Index : nodes) { - graph.push_back(new Node(Index)); - } - std::map, double> weight_map; - for (auto P : edges) { - weight_map[P.first] = P.second; - } - - // Our closure uses our weight_map to look up the weight in between ndoeindex - // and adj_node_index. - std::vector TreeEdges; - prims(graph, TreeEdges, [&weight_map] (unsigned ind1, unsigned ind2) -> double { - return weight_map[{ind1, ind2}]; - }); - - for (auto *n : graph) - delete n; - } - - return 0; -} diff --git a/utils/benchmark/Julia/Julia.m b/utils/benchmark/Julia/Julia.m deleted file mode 100644 index 55c9fcbdba492..0000000000000 --- a/utils/benchmark/Julia/Julia.m +++ /dev/null @@ -1,167 +0,0 @@ - -#import - -#import -#import - -#define WIDTH 500 -#define HEIGHT 500 - -void drawJulia(CGContextRef context, CGRect frame, int maxc) { - - NSRect rRect = NSMakeRect(10, 10, 4, 4); - NSColor *color = [NSColor blueColor]; - // [color set]; - // [NSBezierPath fillRect:rRect]; - - NSArray *basicColorSet = @[ - [NSColor lightGrayColor], - [NSColor blueColor], - [NSColor greenColor], - [NSColor redColor], - [NSColor yellowColor], - [NSColor orangeColor], - [NSColor brownColor], - [NSColor darkGrayColor] - ]; - NSMutableArray *gradedColorSet = [[NSMutableArray alloc] init]; - - for (int c = 100; c<255; c++) { - [gradedColorSet addObject:[NSColor colorWithRed:c/255.0 green:c/255.0 blue:c/255.0 alpha:1.0]]; - } - - NSMutableArray *psychedelicColorSet = [[NSMutableArray alloc] init]; - for (int c = 0; c<100; c++) { - [psychedelicColorSet addObject:[NSColor colorWithHue:c/100.0 saturation:1.0 brightness:1.0 alpha:1.0]]; - } - - NSArray *colorSet; - - int type = 2; - switch (type) { - case 0: - colorSet = basicColorSet; - break; - case 1: - colorSet = gradedColorSet; - break; - case 2: - colorSet = psychedelicColorSet; - break; - default: - colorSet = gradedColorSet; - break; - } - - int loopCountForPerf = 0; - double at1 = 0.15; - double at2 = 0.35; - double rat = 0.01*0.01; - double xloc = -1.5; - double yloc = -1.25; - double yhigh = 1.25; - double mag = 380.0/(yhigh - yloc); - double cr=0.27334; - double ci=0.00712; - double r; - double i; - double rh; - - NSDate *methodStart = [NSDate date]; - double maxX = frame.size.width; - double maxY = frame.size.height; - - for (int x=1; x 100) { - break; - } - if (((r-at1)*(r-at1) + (i-at2)*(i-at2)) <= rat) { - break; - } - loopCountForPerf++; - } - color = colorSet[countA % [colorSet count]]; - if (countA >= maxc) { - color = [NSColor blackColor]; - } - // Draw the point - CGContextSetFillColorWithColor(context, color.CGColor); - CGContextFillRect(context, (CGRect){{x, y}, {4, 4}}); - } - } - NSLog(@"Total loop count %d", loopCountForPerf); - NSDate *methodFinish = [NSDate date]; - NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart]; - NSLog(@"Execution time: %f", executionTime); -} - -int main(int argc, char *argv[]) { - - if (argc != 2) { - fprintf(stderr, "Invalid Argument!\n%s {small, normal, large}!\n", argv[0]); - exit(-1); - } - - int maxc; - char *out_name; - if (!strcmp(argv[1], "small")) { - maxc = 100; - out_name = "small.png"; - } else if (!strcmp(argv[1], "normal")) { - maxc = 1000; - out_name = "normal.png"; - } else if (!strcmp(argv[1], "large")) { - maxc = 10000; - out_name = "large.png"; - } else { - fprintf(stderr, "Invalid Argument!\n%s {small, normal, large}!\n", argv[0]); - exit(-1); - } - - CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - size_t width = WIDTH; - size_t height = HEIGHT; - size_t bytesPerRow = width * 4; - assert(colorSpace != NULL); - void *bitmapData = calloc(bytesPerRow*height, 1); - CGContextRef context = CGBitmapContextCreate(bitmapData, WIDTH, HEIGHT, 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); - assert(context != NULL); - - CGRect Rect = { .origin = { 0, 0 }, .size = { WIDTH, HEIGHT } }; - - CGContextSetRGBFillColor(context, 0, 0, 0, 1); - CGContextFillRect(context, Rect); - - drawJulia(context, Rect, maxc); - - CGImageRef image = CGBitmapContextCreateImage(context); - NSURL *URL = [[NSURL fileURLWithPath:[NSString stringWithCString:out_name encoding:NSASCIIStringEncoding]] absoluteURL]; - NSLog(@"%@", URL); - assert(image); - assert(URL); - CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)URL, kUTTypePNG, 1, NULL); - assert(destination); - CGImageDestinationAddImage(destination, image, NULL); - if (!CGImageDestinationFinalize(destination)) - NSLog(@"Failed to write image!"); - - CGContextRelease(context); - CGColorSpaceRelease(colorSpace); - free(bitmapData); - - return 0; -} diff --git a/utils/benchmark/Julia/Julia.swift b/utils/benchmark/Julia/Julia.swift deleted file mode 100644 index a5bfae3c5f9c5..0000000000000 --- a/utils/benchmark/Julia/Julia.swift +++ /dev/null @@ -1,172 +0,0 @@ - -import Cocoa - -let ImageWidth : CGFloat = 500 -let ImageHeight : CGFloat = 500 - -enum ProblemSize { - case Small - case Normal - case Large -} - -let PSize = ProblemSize.Small - -func drawJulia(context : CGContextRef, frame : CGRect) { - var rRect : NSRect = NSRect(10, 10, 4, 4) - var color = NSColor() - - // Set up color arrays - var basicColorSet : Array = Array() - // basicColorSet = [NSColor.lightGrayColor(), NSColor.blueColor(), NSColor.greenColor(), NSColor.redColor(), NSColor.yellowColor(), NSColor.orangeColor(), NSColor.brownColor(), NSColor.darkGrayColor()] - basicColorSet.append(NSColor.lightGrayColor()) - basicColorSet.append(NSColor.blueColor()) - basicColorSet.append(NSColor.greenColor()) - basicColorSet.append(NSColor.redColor()) - basicColorSet.append(NSColor.yellowColor()) - basicColorSet.append(NSColor.orangeColor()) - basicColorSet.append(NSColor.brownColor()) - basicColorSet.append(NSColor.darkGrayColor()) - - var gradedColorSet : Array = Array() - var aColor = NSColor.colorWithRed(0.5, green:0.5, blue:0.5, alpha:1.0) - for c in 100..255 { - gradedColorSet.append(NSColor.colorWithRed(Double(c)/255.0, green: Double(c)/255.0, blue: Double(c)/255.0, alpha:1.0)) - } - - var psychedelicColorSet : Array = Array() - for c in 0..100 { - psychedelicColorSet.append(NSColor.colorWithHue(Double(c)/100.0, saturation:1.0, brightness:1.0, alpha:1.0)) - } - var colorSet : Array = Array() - - switch 2 { - case 0: - colorSet = basicColorSet - case 1: - colorSet = gradedColorSet - case 2: - colorSet = psychedelicColorSet - default: - colorSet = psychedelicColorSet - } - - // Main Julia set algorithm - - var loopCountForPerf : Int = 0 - var maxc = 0 - switch PSize { - case .Small: - maxc = 100 - case .Normal: - maxc = 1000 - case .Large: - maxc = 10000 - } - - let at1 : Double = 0.15; - let at2 : Double = 0.35; - let rat : Double = 0.01*0.01; - let xloc : Double = -1.5; - let yloc : Double = -1.25; - let yhigh : Double = 1.25; - let mag : Double = 380.0/(yhigh - yloc) - let cr : Double = 0.27334 - let ci : Double = 0.00712; - - var r : Double = 0.0 - var i : Double = 0.0 - var rh : Double = 0.0 - - let methodStart : NSDate = NSDate() - let xMax : Int = Int(frame.size.width) - let yMax : Int = Int(frame.size.height) - for x in 1..xMax { - for y in 1..yMax { - r = (Double(x)/mag) + xloc - i = (Double(y)/mag) + yloc - // cr = r ; ci = i - - // Initial color white - color = NSColor.whiteColor() - var countA=1; - for iter in 1..maxc { - rh = r*r - i*i - i = 2*r*i - r = rh - r = r + cr - i = i + ci - if ((r*r + i*i) > 100) { - break - } - if (((r-at1)*(r-at1) + (i-at2)*(i-at2)) <= rat) { - break - } - countA++ - loopCountForPerf++ - } - color = colorSet[countA % colorSet.count] - if (countA >= maxc) { - color = NSColor.blackColor() - } - // Draw the point - rRect = CGRect(CGFloat(x), CGFloat(y), 4, 4); - // rRect = NSRect(CGPoint(CGFloat(x),CGFloat(y)), CGSize(4.0, 4.0)) - assert(context != CGContextRef()) - CGContextSetFillColorWithColor(context, color.CGColor()) - CGContextFillRect(context, rRect) - } - } - print("Total loop count: \(loopCountForPerf)") - let methodFinish : NSDate = NSDate() - var executionTime : NSTimeInterlet = methodFinish.timeIntervalSinceDate(anotherDate: methodStart) - print("Execution time: \(executionTime)") -} - -// Create the image bitmap context. -print("Initializing CGBitmapContext.\n") -var colorSpace = NSColor.redColor().colorSpace.CGColorSpace -assert(colorSpace != CGColorSpaceRef()) -let width : Swift.UInt = 500 -let height : Swift.UInt = 500 -var bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.PremultipliedLast.rawValue)! -var data = malloc(width*4*height) -var context = CGBitmapContextCreate(data, width, height, 8, width*4, colorSpace, bitmapInfo) -assert(context != CGContextRef()) - -var rect : CGRect = CGRect(0, 0, ImageWidth, ImageHeight) -CGContextClearRect(context, rect) -CGContextSetRGBFillColor(context, 1, 1, 1, 1) -CGContextFillRect(context, rect) - -// Draw the image. -print("Drawing Julia.\n") -drawJulia(context, rect) - -let CFStringEncoding_ASCII : UInt32 = 0x0600 - -// Write the image to disk. -func writeImageToDisk(context : CGContextRef, outPath : NSString) -> Bool { - var image = CGBitmapContextCreateImage(context) - let encoding : NSStringEncoding = NSASCIIStringEncoding - let path = CFStringCreateWithCString(CFAllocatorRef(), outPath.cStringUsingEncoding(encoding), CFStringEncoding_ASCII) - assert(path != CFStringRef()) - var url = CFURLCreateWithString(CFAllocatorRef(), path, CFURLRef()) - assert(url != CFURLRef()) - var destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, CFDictionaryRef()) - assert(destination != CGImageDestinationRef()) - CGImageDestinationAddImage(destination, image, COpaquePointer()) - if !CGImageDestinationFinalize(destination) { - print("Failed to write image") - return (false) - } - return (true) -} - -var outPath = NSURL.fileURLWithPath("out.png").absoluteString -writeImageToDisk(context, outPath! as NSString) - -// Cleanup. -free(data) -CGContextRelease(context) -CGColorSpaceRelease(colorSpace) diff --git a/utils/benchmark/Julia/large-ref.png b/utils/benchmark/Julia/large-ref.png deleted file mode 100644 index 0b96f5fcacfce..0000000000000 Binary files a/utils/benchmark/Julia/large-ref.png and /dev/null differ diff --git a/utils/benchmark/Julia/normal-ref.png b/utils/benchmark/Julia/normal-ref.png deleted file mode 100644 index e1f0cea8787f7..0000000000000 Binary files a/utils/benchmark/Julia/normal-ref.png and /dev/null differ diff --git a/utils/benchmark/Julia/small-ref.png b/utils/benchmark/Julia/small-ref.png deleted file mode 100644 index 4e74e21c3d28d..0000000000000 Binary files a/utils/benchmark/Julia/small-ref.png and /dev/null differ diff --git a/utils/benchmark/LinkedList/link.m b/utils/benchmark/LinkedList/link.m deleted file mode 100644 index e2529e79342f0..0000000000000 --- a/utils/benchmark/LinkedList/link.m +++ /dev/null @@ -1,42 +0,0 @@ -#import -#include -#include - -@interface MyNode:NSObject -@property int data; -@property(retain) MyNode *next; -@end - -@implementation MyNode -@synthesize data, next; -@end - - -int main() { - printf("Creating list\n"); - MyNode *head = [[MyNode alloc] init]; - - for (int i = 0; i < 100; i++) { - MyNode *next = [[MyNode alloc] init]; - [next setNext:[head next]]; - [next setData:i]; - [head setNext:next]; - } - - printf("Summing list\n"); - int sum = 0; - uint64_t start = mach_absolute_time(); - MyNode *ptr = head; - for (int i = 0; i < 100000; i++) { - ptr = head; - while (ptr) { - sum += [ptr data]; - ptr = [ptr next]; - } - } - uint64_t delta = mach_absolute_time() - start; - printf("%f ns\n", (double)delta); - - printf("sum = %d\n", sum); - return 0; -} diff --git a/utils/benchmark/LinkedList/link.python b/utils/benchmark/LinkedList/link.python deleted file mode 100644 index 7d5710e5afdaf..0000000000000 --- a/utils/benchmark/LinkedList/link.python +++ /dev/null @@ -1,26 +0,0 @@ -from Foundation import * - -class Node: - def __init__(self, next, data): - self.next = next - self.data = data - -print "Creating list" -head = Node(None, 0) -for i in range(100): - head = Node(head , i) - -start = NSProcessInfo.processInfo().systemUptime() * 1e9 - -print "Summing list" -sum = 0 -pts = head -for i in xrange(100000): - ptr = head - while(ptr.next): - sum += ptr.data - ptr = ptr.next - -end = NSProcessInfo.processInfo().systemUptime() * 1e9 -print "Sum = %d" % sum -print "%f ns" % int(end - start) diff --git a/utils/benchmark/LinkedList/link.swift b/utils/benchmark/LinkedList/link.swift deleted file mode 100644 index 63fc47309bd71..0000000000000 --- a/utils/benchmark/LinkedList/link.swift +++ /dev/null @@ -1,33 +0,0 @@ -@_silgen_name("mach_absolute_time") func __mach_absolute_time__() -> UInt64 - -@final class Node { - var next: Node? - var data: Int - - init(n: Node?, d: Int) { - next = n - data = d - } -} - -print("Creating list\n") -var head = Node(nil, 0) -for i in 0..100 { - head = Node(head, i) -} - -let start = __mach_absolute_time__() -print("Summing list\n") -var sum = 0 -var ptr = head -for i in 0..100000 { - ptr = head - while let nxt = ptr.next { - sum += ptr.data - ptr = nxt - } -} - -let delta = __mach_absolute_time__() - start -print("sum = \(sum)\n") -print("\(delta) nanoseconds.") diff --git a/utils/benchmark/ObjInst/ObjInst.cpp b/utils/benchmark/ObjInst/ObjInst.cpp deleted file mode 100644 index 35b22c6221f76..0000000000000 --- a/utils/benchmark/ObjInst/ObjInst.cpp +++ /dev/null @@ -1,77 +0,0 @@ - -#include -#include - -extern "C" { -#include -} - -class Toggle { -public: - bool state = true; - Toggle(bool start_state) { - state = start_state; - } - - bool value() { - return state; - } - - Toggle *activate() { - state = !state; - return this ; - } -}; - -class NthToggle : Toggle { -public: - int count_max; - int counter; - - NthToggle(bool start_state, int max_counter) : Toggle(start_state) { - count_max = max_counter; - counter = 0; - } - NthToggle *activate() { - counter += 1; - if (counter >= count_max) { - state = !state; - counter = 0; - } - return this; - } -}; - -int main() { - - uint64_t start = mach_absolute_time(); - - int n = 100000000; - - Toggle *toggle1 = new Toggle(true); - //for (int i=0; i<5; i++) { - // Console.WriteLine((toggle1.activate().value()) ? "true" : "false"); - //} - - for (int i=0; i -#include -#include -#include "Phonebook.h" -// clang -O3 Phonebook.m -o Phonebook.bin -framework Foundation -fobjc-arc - -@implementation Record -- (NSString*) Firstname { return First; } -- (NSString*) Lastname { return Last; } - -- (id) init { - if ( self = [super init]) { - [self setFirst:First]; - [self setLast:Last]; - } - return self; -} - -- (NSComparisonResult)compare:(Record *)otherObject { - NSComparisonResult FirstComp = - [self->Last compare:otherObject->Last]; - if (FirstComp != NSOrderedSame) - return FirstComp; - - return [self->First compare:otherObject->First]; -} - -- (void) setFirst: (NSString*)input { First = input; } -- (void) setLast: (NSString*)input { Last = input; } -@end - -int main(void) { - - NSArray *myArray = @[ - @"James", @"John", @"Robert", @"Michael", @"William", @"David", @"Richard", @"Joseph", - @"Charles", @"Thomas", @"Christopher", @"Daniel", @"Matthew", @"Donald", @"Anthony", - @"Paul", @"Mark", @"George", @"Steven", @"Kenneth", @"Andrew", @"Edward", @"Brian", - @"Joshua", @"Kevin", @"Ronald", @"Timothy", @"Jason", @"Jeffrey", @"Gary", @"Ryan", - @"Nicholas", @"Eric", @"Stephen", @"Jacob", @"Larry", @"Frank", @"Jonathan", @"Scott", - @"Justin", @"Raymond", @"Brandon", @"Gregory", @"Samuel", @"Patrick", @"Benjamin", - @"Jack", @"Dennis", @"Jerry", @"Alexander", @"Tyler", @"Douglas", @"Henry", @"Peter", - @"Walter", @"Aaron", @"Jose", @"Adam", @"Harold", @"Zachary", @"Nathan", @"Carl", - @"Kyle", @"Arthur", @"Gerald", @"Lawrence", @"Roger", @"Albert", @"Keith", @"Jeremy", - @"Terry", @"Joe", @"Sean", @"Willie", @"Jesse", @"Ralph", @"Billy", @"Austin", @"Bruce", - @"Christian", @"Roy", @"Bryan", @"Eugene", @"Louis", @"Harry", @"Wayne", @"Ethan", - @"Jordan", @"Russell", @"Alan", @"Philip", @"Randy", @"Juan", @"Howard", @"Vincent", - @"Bobby", @"Dylan", @"Johnny", @"Phillip", @"Craig"]; - - NSMutableArray *PhoneBook = [[NSMutableArray alloc] init]; - - int size = [myArray count]; - for (int i=0; i < size; i++) { - for (int j=0; j < size; j++) { - NSString *First = [myArray objectAtIndex: i]; - NSString *Last = [myArray objectAtIndex: j]; - Record *entry = [[Record alloc] init]; - [entry setFirst: First]; - [entry setLast: Last]; - [PhoneBook addObject: entry]; - } - } - - uint64_t count = 0; - uint64_t start = mach_absolute_time(); - for (unsigned i = 0; i < 100; i++) { - NSMutableArray *NMA = [PhoneBook mutableCopy]; - [NMA sortUsingSelector: @selector(compare:)]; -#if 0 - for (int i=0; i < size; i++) { - Record *rec = [NMA objectAtIndex: i]; - printf("%s %s\n", [[rec Lastname] UTF8String], [[rec Firstname] UTF8String]); - } -#endif - } - uint64_t delta = mach_absolute_time() - start; - - - printf("%f ns\n", - (double)delta); - return 0; -} diff --git a/utils/benchmark/Phonebook/Phonebook.py b/utils/benchmark/Phonebook/Phonebook.py deleted file mode 100644 index 6cf3ebec7ed95..0000000000000 --- a/utils/benchmark/Phonebook/Phonebook.py +++ /dev/null @@ -1,41 +0,0 @@ - -words=[ - u"James", u"John", u"Robert", u"Michael", u"William", u"David", u"Richard", u"Joseph", - u"Charles", u"Thomas", u"Christopher", u"Daniel", u"Matthew", u"Donald", u"Anthony", - u"Paul", u"Mark", u"George", u"Steven", u"Kenneth", u"Andrew", u"Edward", u"Brian", - u"Joshua", u"Kevin", u"Ronald", u"Timothy", u"Jason", u"Jeffrey", u"Gary", u"Ryan", - u"Nicholas", u"Eric", u"Stephen", u"Jacob", u"Larry", u"Frank", u"Jonathan", u"Scott", - u"Justin", u"Raymond", u"Brandon", u"Gregory", u"Samuel", u"Patrick", u"Benjamin", - u"Jack", u"Dennis", u"Jerry", u"Alexander", u"Tyler", u"Douglas", u"Henry", u"Peter", - u"Walter", u"Aaron", u"Jose", u"Adam", u"Harold", u"Zachary", u"Nathan", u"Carl", - u"Kyle", u"Arthur", u"Gerald", u"Lawrence", u"Roger", u"Albert", u"Keith", u"Jeremy", - u"Terry", u"Joe", u"Sean", u"Willie", u"Jesse", u"Ralph", u"Billy", u"Austin", u"Bruce", - u"Christian", u"Roy", u"Bryan", u"Eugene", u"Louis", u"Harry", u"Wayne", u"Ethan", - u"Jordan", u"Russell", u"Alan", u"Philip", u"Randy", u"Juan", u"Howard", u"Vincent", - u"Bobby", u"Dylan", u"Johnny", u"Phillip", u"Craig"] - -# This is a phone book record. -class Record: - def __init__(self, firstname, lastname): - self.first = firstname - self.last = lastname - - def __lt__(self, other): - if self.last < other.last: - return True - if self.last > other.last: - return False - return self.first < other.first - -Records = [] - -for first in words: - for last in words: - Records.append(Record(first, last)) - -for i in xrange(100): - y = Records[:] - y = sorted(y) - #for w in y: - # print w.first, w.last - diff --git a/utils/benchmark/Phonebook/Phonebook.rb b/utils/benchmark/Phonebook/Phonebook.rb deleted file mode 100644 index 5f011ad421d36..0000000000000 --- a/utils/benchmark/Phonebook/Phonebook.rb +++ /dev/null @@ -1,54 +0,0 @@ - -words=[ -"James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", -"Charles", "Thomas", "Christopher", "Daniel", "Matthew", "Donald", "Anthony", -"Paul", "Mark", "George", "Steven", "Kenneth", "Andrew", "Edward", "Brian", -"Joshua", "Kevin", "Ronald", "Timothy", "Jason", "Jeffrey", "Gary", "Ryan", -"Nicholas", "Eric", "Stephen", "Jacob", "Larry", "Frank", "Jonathan", "Scott", -"Justin", "Raymond", "Brandon", "Gregory", "Samuel", "Patrick", "Benjamin", -"Jack", "Dennis", "Jerry", "Alexander", "Tyler", "Douglas", "Henry", "Peter", -"Walter", "Aaron", "Jose", "Adam", "Harold", "Zachary", "Nathan", "Carl", -"Kyle", "Arthur", "Gerald", "Lawrence", "Roger", "Albert", "Keith", "Jeremy", -"Terry", "Joe", "Sean", "Willie", "Jesse", "Ralph", "Billy", "Austin", "Bruce", -"Christian", "Roy", "Bryan", "Eugene", "Louis", "Harry", "Wayne", "Ethan", -"Jordan", "Russell", "Alan", "Philip", "Randy", "Juan", "Howard", "Vincent", -"Bobby", "Dylan", "Johnny", "Phillip", "Craig"] - -# This is a phone book record. -class Record - def initialize(firstname, lastname) - @first = firstname - @last = lastname - end - def first - return @first - end - def last - return @last - end - - def <=>(other) - comp = self.last <=> other.last - if comp != 0 - return comp - end - return self.first <=> other.first - end -end - -Names = [] - -words.each do |first| - words.each do |last| - Names.push(Record.new(first, last)) - end -end - -(0..100).each do |i| - y = Array.new(Names) - y.sort! {|a,b| a <=> b} - #y.each do |r| - # puts r.last + " " + r.first - #end -end - diff --git a/utils/benchmark/Phonebook/Phonebook.swift b/utils/benchmark/Phonebook/Phonebook.swift deleted file mode 100644 index 21b7b9c368eae..0000000000000 --- a/utils/benchmark/Phonebook/Phonebook.swift +++ /dev/null @@ -1,68 +0,0 @@ -@_silgen_name("mach_absolute_time") func __mach_absolute_time__() -> UInt64 - -var words=[ -"James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", -"Charles", "Thomas", "Christopher", "Daniel", "Matthew", "Donald", "Anthony", -"Paul", "Mark", "George", "Steven", "Kenneth", "Andrew", "Edward", "Brian", -"Joshua", "Kevin", "Ronald", "Timothy", "Jason", "Jeffrey", "Gary", "Ryan", -"Nicholas", "Eric", "Stephen", "Jacob", "Larry", "Frank", "Jonathan", "Scott", -"Justin", "Raymond", "Brandon", "Gregory", "Samuel", "Patrick", "Benjamin", -"Jack", "Dennis", "Jerry", "Alexander", "Tyler", "Douglas", "Henry", "Peter", -"Walter", "Aaron", "Jose", "Adam", "Harold", "Zachary", "Nathan", "Carl", -"Kyle", "Arthur", "Gerald", "Lawrence", "Roger", "Albert", "Keith", "Jeremy", -"Terry", "Joe", "Sean", "Willie", "Jesse", "Ralph", "Billy", "Austin", "Bruce", -"Christian", "Roy", "Bryan", "Eugene", "Louis", "Harry", "Wayne", "Ethan", -"Jordan", "Russell", "Alan", "Philip", "Randy", "Juan", "Howard", "Vincent", -"Bobby", "Dylan", "Johnny", "Phillip", "Craig"] - -// This is a phone book record. -struct Record : Comparable { - var first : String - var last : String - - init(_ first_ : String,_ last_ : String) { - first = first_ - last = last_ - } -} -func ==(lhs: Record, rhs: Record) -> Bool { - return lhs.last.compare(rhs.last) == 0 && - lhs.first.compare(rhs.first) == 0 -} -func <(lhs: Record, rhs: Record) -> Bool { - let lastComp = lhs.last.compare(rhs.last) - if lastComp == -1 { - return true - } - if lastComp == 1 { - return false - } - - let firstComp = lhs.first.compare(rhs.first) - if firstComp == -1 { - return true - } - - return false -} - -// The list of names in the phonebook. -var Names : Record[] = [] -for first in words { - for last in words { - Names.append(Record(first, last)) - } -} - -func benchStringSort() { - let start = __mach_absolute_time__() - for (var i = 0; i < 100; i++) { - var t = Names; - sort(&t) - } - let delta = __mach_absolute_time__() - start - - print("\(delta) nanoseconds.") -} - -benchStringSort() diff --git a/utils/benchmark/RC4/RC4.cpp b/utils/benchmark/RC4/RC4.cpp deleted file mode 100644 index 5facaf9bd1a9b..0000000000000 --- a/utils/benchmark/RC4/RC4.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include - -// Turn off logging if we only want to time the routine. -#ifndef LOG -#define LOG(x) x -#else -#undef LOG -#define LOG(x) -#endif - -extern "C" { -#include -} - -struct RC4 { - std::vector State; - int I; - int J; - - RC4() { I = 0; J = 0; } - - void initialize(std::vector &Key) { - State.clear(); - for (int i = 0; i < 256; i++) - State.push_back(i); - - int j = 0; - for (int i=0; i < 256; i++) { - uint8_t K = Key[i % Key.size()]; - uint8_t S = State[i]; - j = (j + S + K) %256; - swapByIndex(i, j); - } - } - - void swapByIndex(int x, int y) { - uint8_t T1 = State[x]; - uint8_t T2 = State[y]; - State[x] = T2; - State[y] = T1; - } - - uint8_t next() { - I = (I + 1) % 256; - J = (J + State[I]) % 256; - swapByIndex(I, J); - return State[(State[I] + State[J]) & 0xFF]; - } - - void encrypt(std::vector &Data) { - int cnt = Data.size(); - for (int i = 0; i < cnt; i++) - Data[i] = Data[i] ^ next(); - } -}; - -void benchRC4(int messageLen, int iterations, bool validate) { - char *Secret = "This is my secret message"; - char *Key = "This is my key"; - - std::vector SecretData(&Secret[0], &Secret[strlen(Secret)]); - std::vector KeyData(&Key[0], &Key[strlen(Key)]); - - std::vector LongData(messageLen, 0); - - LOG(std::cout << "Generating data ... " << std::endl); - - for (int i = 0; i < messageLen ; i++) - LongData[i] = SecretData[i % SecretData.size()]; - - RC4 Enc; - RC4 Dec; - Enc.initialize(KeyData); - Dec.initialize(KeyData); - - LOG(std::cout << "Starting benchmark..." << std::endl); - uint64_t start = mach_absolute_time(); - for (int i=0; i < iterations; i++) { - Enc.encrypt(LongData); - Dec.encrypt(LongData); - } - uint64_t end = mach_absolute_time() - start; - printf("%llu nanoseconds.\n", end); - - if (validate) { - LOG(std::cout << "Validating..." << std::endl); - for (int i = 0; i < messageLen ; i++) - if (LongData[i] != SecretData[i % SecretData.size()]) { - LOG(std::cout << "Error at " << i << "!!!" << std::endl); - } - } - LOG(std::cout << "done" << std::endl); -} - -int main() { - benchRC4(5000, 2000, false); -} diff --git a/utils/benchmark/RC4/RC4.h b/utils/benchmark/RC4/RC4.h deleted file mode 100644 index 905f8be08fc24..0000000000000 --- a/utils/benchmark/RC4/RC4.h +++ /dev/null @@ -1,16 +0,0 @@ -@interface RC4 : NSObject { - uint8_t _i; - uint8_t _j; - uint8_t *_state; -} - -- (id)initWithKey:(const unsigned char *)key length:(unsigned)len; - -- (void)swapByIndex:(unsigned)x andIndex:(unsigned)y; - -- (unsigned char) next; - -@end - - - diff --git a/utils/benchmark/RC4/RC4.m b/utils/benchmark/RC4/RC4.m deleted file mode 100644 index d445827665dbb..0000000000000 --- a/utils/benchmark/RC4/RC4.m +++ /dev/null @@ -1,101 +0,0 @@ -#import -#include -#include -#include "RC4.h" - -@implementation RC4 - -- (id) init { - return [self initWithKey:nil length:0]; -} - -- (id)initWithKey:(const unsigned char *)key length:(unsigned)len { - if (self = [super init]) { - _i = 0; - _j = 0; - - _state = (uint8_t *) calloc(256, sizeof(uint8_t)); - - // Allocation failed. - if (!_state) - return self; - - if (key) { - for (unsigned i = 0; i < 256; ++i) - _state[i] = i; - - uint8_t j = 0; - for (unsigned i = 0; i < 256; i++) { - uint8_t k = key[i % len]; - uint8_t s = _state[i]; - j = j + s + k; - [self swapByIndex: i andIndex: j]; - } - } else { - for (unsigned i = 0; i < 256; ++i) - _state[i] = 0; - } - } - - return self; -} - -- (void) dealloc { - free(_state); -} - -- (void) swapByIndex:(unsigned)x andIndex:(unsigned)y { - uint8_t t1 = _state[x]; - uint8_t t2 = _state[y]; - - _state[x] = t2; - _state[y] = t1; -} - -- (unsigned char) next { - _i = _i + 1; - _j = _j + _state[_i]; - - [self swapByIndex:_i andIndex:_j]; - - return _state[(_state[_i] + _state[_j]) & 0xFF]; -} - -- (void) encrypt: (unsigned char *)data length:(unsigned)len { - for (int i = 0; i < len; i++) - data[i] = data[i] ^ [self next]; -} - -@end - -void benchRC4(int messageLen, int numIterations, bool validate) { - const char *Secret = "This is my secret message"; - unsigned SecretLen = strlen(Secret); - const char *Key = "This is my key"; - unsigned KeyLen = strlen(Key); - - unsigned char *LongData = calloc(messageLen, sizeof(unsigned char)); - for (int i = 0; i < messageLen ; i++) { - LongData[i] = (unsigned char)Secret[i % SecretLen]; - } - - RC4 *Enc = [[RC4 alloc] initWithKey:(unsigned char*)Key length:KeyLen]; - - uint64_t start = mach_absolute_time(); - - for (int i=0; i < numIterations; i++) { - [Enc encrypt:LongData length:messageLen]; - } - - uint64_t end = mach_absolute_time() - start; - - printf("%llu nanoseconds.\n", end); - printf("%lf nanoseconds.\n", end/(double)numIterations); - - free(LongData); -} - -int main(int argc, char **argv) { - benchRC4(5000, 100000, false); - return 0; -} diff --git a/utils/benchmark/RC4/RC4.py b/utils/benchmark/RC4/RC4.py deleted file mode 100644 index de38b6136a8f2..0000000000000 --- a/utils/benchmark/RC4/RC4.py +++ /dev/null @@ -1,47 +0,0 @@ - -class RC4: - def __init__(self): - self.state = [0] * 256 - self.I = 0 - self.J = 0 - - def init(self, key): - for i in xrange(256): - self.state[i] = i - - j = 0 - for i in xrange(256): - K = ord(key[i % len(key)]) - S = self.state[i] - j = (j + S + K) % 256 - self.swapByIndex(i, j) - - def swapByIndex(self, i, j): - self.state[i], self.state[j] = self.state[j], self.state[i] - - def next(self): - self.I = (self.I + 1) % 256 - self.J = (self.J + self.state[self.I]) % 256 - self.swapByIndex(self.I, self.J) - return self.state[(self.state[self.I] + self.state[self.J]) % 256] - - def encrypt(self, data): - for i in xrange(len(data)): - data[i] = data[i] ^ self.next() - - -def benchRC4_internal(messageLen, iterations): - Secret = "This is my secret message" - Key = "This is my key" - LongData = [0] * messageLen - - for i in xrange(messageLen): - LongData[i] = ord(Secret[i % len(Secret)]) - - Enc = RC4() - Enc.init(Key) - - for i in xrange(iterations): - Enc.encrypt(LongData) - -benchRC4_internal(5000, 100000) diff --git a/utils/benchmark/RC4/RC4.swift b/utils/benchmark/RC4/RC4.swift deleted file mode 100644 index 41bc981c03fa4..0000000000000 --- a/utils/benchmark/RC4/RC4.swift +++ /dev/null @@ -1,84 +0,0 @@ -@_silgen_name("mach_absolute_time") func __mach_absolute_time__() -> UInt64 - -struct RC4 { - var State : UInt8[] - var I : UInt8 = 0 - var J : UInt8 = 0 - - init() { - State = new UInt8[256] - } - - mutating - func initialize(Key: UInt8[]) { - for (var i = 0; i < 256; i++) { - State[i] = UInt8(i) - } - - var j : UInt8 = 0 - for (var i = 0; i < 256; i++) { - var K : UInt8 = Key[i % Key.count] - var S : UInt8 = State[i] - j = j &+ S &+ K - swapByIndex(i, y: Int(j)) - } - } - - mutating - func swapByIndex(x: Int, y: Int) { - let T1 : UInt8 = State[x] - let T2 : UInt8 = State[y] - State[x] = T2 - State[y] = T1 - } - - mutating - func next() -> UInt8 { - I = I &+ 1 - J = J &+ State[Int(I)] - swapByIndex(Int(I), y: Int(J)) - return State[Int(State[Int(I)] &+ State[Int(J)]) & 0xFF] - } - - mutating - func encrypt(inout Data: UInt8[]) { - var cnt = Data.count - for (var i = 0; i < cnt; i++) { - Data[i] = Data[i] ^ next() - } - } -} - -func benchRC4_internal(messageLen : Int, iterations : Int) { - let Secret = "This is my secret message" - let Key = "This is my key" - let SecretData : UInt8[] = Array(Secret.utf8) - let KeyData : UInt8[] = Array(Key.utf8) - - var LongData : UInt8[] = new UInt8[messageLen] - - // Generate a long message. - for (var i = 0; i < messageLen; i++) { - LongData[i] = SecretData[i % SecretData.count] - } - - var Enc = RC4() - Enc.initialize(KeyData) - - let start = __mach_absolute_time__() - - for (var i = 0; i < iterations; i++) { - Enc.encrypt(&LongData) - } - - let delta = __mach_absolute_time__() - start - print("\(delta) nanoseconds. \(LongData[0])") - print("\(Double(delta) / Double(iterations)) nanoseconds/lap") -} - - -func benchRC4() { - benchRC4_internal(5000, 100000) -} - -benchRC4() diff --git a/utils/benchmark/Richards/richards.js b/utils/benchmark/Richards/richards.js deleted file mode 100644 index e8fdf3bb81f1e..0000000000000 --- a/utils/benchmark/Richards/richards.js +++ /dev/null @@ -1,539 +0,0 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -// This is a JavaScript implementation of the Richards -// benchmark from: -// -// http://www.cl.cam.ac.uk/~mr10/Bench.html -// -// The benchmark was originally implemented in BCPL by -// Martin Richards. - - -var Richards = new BenchmarkSuite('Richards', [35302], [ - new Benchmark("Richards", true, false, runRichards) -]); - - -/** - * The Richards benchmark simulates the task dispatcher of an - * operating system. - **/ -function runRichards() { - var scheduler = new Scheduler(); - scheduler.addIdleTask(ID_IDLE, 0, null, COUNT); - - var queue = new Packet(null, ID_WORKER, KIND_WORK); - queue = new Packet(queue, ID_WORKER, KIND_WORK); - scheduler.addWorkerTask(ID_WORKER, 1000, queue); - - queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE); - queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE); - queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE); - scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue); - - queue = new Packet(null, ID_DEVICE_B, KIND_DEVICE); - queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE); - queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE); - scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue); - - scheduler.addDeviceTask(ID_DEVICE_A, 4000, null); - - scheduler.addDeviceTask(ID_DEVICE_B, 5000, null); - - scheduler.schedule(); - - if (scheduler.queueCount != EXPECTED_QUEUE_COUNT || - scheduler.holdCount != EXPECTED_HOLD_COUNT) { - var msg = - "Error during execution: queueCount = " + scheduler.queueCount + - ", holdCount = " + scheduler.holdCount + "."; - throw new Error(msg); - } -} - -var COUNT = 1000; - -/** - * These two constants specify how many times a packet is queued and - * how many times a task is put on hold in a correct run of richards. - * They don't have any meaning a such but are characteristic of a - * correct run so if the actual queue or hold count is different from - * the expected there must be a bug in the implementation. - **/ -var EXPECTED_QUEUE_COUNT = 2322; -var EXPECTED_HOLD_COUNT = 928; - - -/** - * A scheduler can be used to schedule a set of tasks based on their relative - * priorities. Scheduling is done by maintaining a list of task control blocks - * which holds tasks and the data queue they are processing. - * @constructor - */ -function Scheduler() { - this.queueCount = 0; - this.holdCount = 0; - this.blocks = new Array(NUMBER_OF_IDS); - this.list = null; - this.currentTcb = null; - this.currentId = null; -} - -var ID_IDLE = 0; -var ID_WORKER = 1; -var ID_HANDLER_A = 2; -var ID_HANDLER_B = 3; -var ID_DEVICE_A = 4; -var ID_DEVICE_B = 5; -var NUMBER_OF_IDS = 6; - -var KIND_DEVICE = 0; -var KIND_WORK = 1; - -/** - * Add an idle task to this scheduler. - * @param {int} id the identity of the task - * @param {int} priority the task's priority - * @param {Packet} queue the queue of work to be processed by the task - * @param {int} count the number of times to schedule the task - */ -Scheduler.prototype.addIdleTask = function (id, priority, queue, count) { - this.addRunningTask(id, priority, queue, new IdleTask(this, 1, count)); -}; - -/** - * Add a work task to this scheduler. - * @param {int} id the identity of the task - * @param {int} priority the task's priority - * @param {Packet} queue the queue of work to be processed by the task - */ -Scheduler.prototype.addWorkerTask = function (id, priority, queue) { - this.addTask(id, priority, queue, new WorkerTask(this, ID_HANDLER_A, 0)); -}; - -/** - * Add a handler task to this scheduler. - * @param {int} id the identity of the task - * @param {int} priority the task's priority - * @param {Packet} queue the queue of work to be processed by the task - */ -Scheduler.prototype.addHandlerTask = function (id, priority, queue) { - this.addTask(id, priority, queue, new HandlerTask(this)); -}; - -/** - * Add a handler task to this scheduler. - * @param {int} id the identity of the task - * @param {int} priority the task's priority - * @param {Packet} queue the queue of work to be processed by the task - */ -Scheduler.prototype.addDeviceTask = function (id, priority, queue) { - this.addTask(id, priority, queue, new DeviceTask(this)) -}; - -/** - * Add the specified task and mark it as running. - * @param {int} id the identity of the task - * @param {int} priority the task's priority - * @param {Packet} queue the queue of work to be processed by the task - * @param {Task} task the task to add - */ -Scheduler.prototype.addRunningTask = function (id, priority, queue, task) { - this.addTask(id, priority, queue, task); - this.currentTcb.setRunning(); -}; - -/** - * Add the specified task to this scheduler. - * @param {int} id the identity of the task - * @param {int} priority the task's priority - * @param {Packet} queue the queue of work to be processed by the task - * @param {Task} task the task to add - */ -Scheduler.prototype.addTask = function (id, priority, queue, task) { - this.currentTcb = new TaskControlBlock(this.list, id, priority, queue, task); - this.list = this.currentTcb; - this.blocks[id] = this.currentTcb; -}; - -/** - * Execute the tasks managed by this scheduler. - */ -Scheduler.prototype.schedule = function () { - this.currentTcb = this.list; - while (this.currentTcb != null) { - if (this.currentTcb.isHeldOrSuspended()) { - this.currentTcb = this.currentTcb.link; - } else { - this.currentId = this.currentTcb.id; - this.currentTcb = this.currentTcb.run(); - } - } -}; - -/** - * Release a task that is currently blocked and return the next block to run. - * @param {int} id the id of the task to suspend - */ -Scheduler.prototype.release = function (id) { - var tcb = this.blocks[id]; - if (tcb == null) return tcb; - tcb.markAsNotHeld(); - if (tcb.priority > this.currentTcb.priority) { - return tcb; - } else { - return this.currentTcb; - } -}; - -/** - * Block the currently executing task and return the next task control block - * to run. The blocked task will not be made runnable until it is explicitly - * released, even if new work is added to it. - */ -Scheduler.prototype.holdCurrent = function () { - this.holdCount++; - this.currentTcb.markAsHeld(); - return this.currentTcb.link; -}; - -/** - * Suspend the currently executing task and return the next task control block - * to run. If new work is added to the suspended task it will be made runnable. - */ -Scheduler.prototype.suspendCurrent = function () { - this.currentTcb.markAsSuspended(); - return this.currentTcb; -}; - -/** - * Add the specified packet to the end of the worklist used by the task - * associated with the packet and make the task runnable if it is currently - * suspended. - * @param {Packet} packet the packet to add - */ -Scheduler.prototype.queue = function (packet) { - var t = this.blocks[packet.id]; - if (t == null) return t; - this.queueCount++; - packet.link = null; - packet.id = this.currentId; - return t.checkPriorityAdd(this.currentTcb, packet); -}; - -/** - * A task control block manages a task and the queue of work packages associated - * with it. - * @param {TaskControlBlock} link the preceding block in the linked block list - * @param {int} id the id of this block - * @param {int} priority the priority of this block - * @param {Packet} queue the queue of packages to be processed by the task - * @param {Task} task the task - * @constructor - */ -function TaskControlBlock(link, id, priority, queue, task) { - this.link = link; - this.id = id; - this.priority = priority; - this.queue = queue; - this.task = task; - if (queue == null) { - this.state = STATE_SUSPENDED; - } else { - this.state = STATE_SUSPENDED_RUNNABLE; - } -} - -/** - * The task is running and is currently scheduled. - */ -var STATE_RUNNING = 0; - -/** - * The task has packets left to process. - */ -var STATE_RUNNABLE = 1; - -/** - * The task is not currently running. The task is not blocked as such and may -* be started by the scheduler. - */ -var STATE_SUSPENDED = 2; - -/** - * The task is blocked and cannot be run until it is explicitly released. - */ -var STATE_HELD = 4; - -var STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE; -var STATE_NOT_HELD = ~STATE_HELD; - -TaskControlBlock.prototype.setRunning = function () { - this.state = STATE_RUNNING; -}; - -TaskControlBlock.prototype.markAsNotHeld = function () { - this.state = this.state & STATE_NOT_HELD; -}; - -TaskControlBlock.prototype.markAsHeld = function () { - this.state = this.state | STATE_HELD; -}; - -TaskControlBlock.prototype.isHeldOrSuspended = function () { - return (this.state & STATE_HELD) != 0 || (this.state == STATE_SUSPENDED); -}; - -TaskControlBlock.prototype.markAsSuspended = function () { - this.state = this.state | STATE_SUSPENDED; -}; - -TaskControlBlock.prototype.markAsRunnable = function () { - this.state = this.state | STATE_RUNNABLE; -}; - -/** - * Runs this task, if it is ready to be run, and returns the next task to run. - */ -TaskControlBlock.prototype.run = function () { - var packet; - if (this.state == STATE_SUSPENDED_RUNNABLE) { - packet = this.queue; - this.queue = packet.link; - if (this.queue == null) { - this.state = STATE_RUNNING; - } else { - this.state = STATE_RUNNABLE; - } - } else { - packet = null; - } - return this.task.run(packet); -}; - -/** - * Adds a packet to the worklist of this block's task, marks this as runnable if - * necessary, and returns the next runnable object to run (the one - * with the highest priority). - */ -TaskControlBlock.prototype.checkPriorityAdd = function (task, packet) { - if (this.queue == null) { - this.queue = packet; - this.markAsRunnable(); - if (this.priority > task.priority) return this; - } else { - this.queue = packet.addTo(this.queue); - } - return task; -}; - -TaskControlBlock.prototype.toString = function () { - return "tcb { " + this.task + "@" + this.state + " }"; -}; - -/** - * An idle task doesn't do any work itself but cycles control between the two - * device tasks. - * @param {Scheduler} scheduler the scheduler that manages this task - * @param {int} v1 a seed value that controls how the device tasks are scheduled - * @param {int} count the number of times this task should be scheduled - * @constructor - */ -function IdleTask(scheduler, v1, count) { - this.scheduler = scheduler; - this.v1 = v1; - this.count = count; -} - -IdleTask.prototype.run = function (packet) { - this.count--; - if (this.count == 0) return this.scheduler.holdCurrent(); - if ((this.v1 & 1) == 0) { - this.v1 = this.v1 >> 1; - return this.scheduler.release(ID_DEVICE_A); - } else { - this.v1 = (this.v1 >> 1) ^ 0xD008; - return this.scheduler.release(ID_DEVICE_B); - } -}; - -IdleTask.prototype.toString = function () { - return "IdleTask" -}; - -/** - * A task that suspends itself after each time it has been run to simulate - * waiting for data from an external device. - * @param {Scheduler} scheduler the scheduler that manages this task - * @constructor - */ -function DeviceTask(scheduler) { - this.scheduler = scheduler; - this.v1 = null; -} - -DeviceTask.prototype.run = function (packet) { - if (packet == null) { - if (this.v1 == null) return this.scheduler.suspendCurrent(); - var v = this.v1; - this.v1 = null; - return this.scheduler.queue(v); - } else { - this.v1 = packet; - return this.scheduler.holdCurrent(); - } -}; - -DeviceTask.prototype.toString = function () { - return "DeviceTask"; -}; - -/** - * A task that manipulates work packets. - * @param {Scheduler} scheduler the scheduler that manages this task - * @param {int} v1 a seed used to specify how work packets are manipulated - * @param {int} v2 another seed used to specify how work packets are manipulated - * @constructor - */ -function WorkerTask(scheduler, v1, v2) { - this.scheduler = scheduler; - this.v1 = v1; - this.v2 = v2; -} - -WorkerTask.prototype.run = function (packet) { - if (packet == null) { - return this.scheduler.suspendCurrent(); - } else { - if (this.v1 == ID_HANDLER_A) { - this.v1 = ID_HANDLER_B; - } else { - this.v1 = ID_HANDLER_A; - } - packet.id = this.v1; - packet.a1 = 0; - for (var i = 0; i < DATA_SIZE; i++) { - this.v2++; - if (this.v2 > 26) this.v2 = 1; - packet.a2[i] = this.v2; - } - return this.scheduler.queue(packet); - } -}; - -WorkerTask.prototype.toString = function () { - return "WorkerTask"; -}; - -/** - * A task that manipulates work packets and then suspends itself. - * @param {Scheduler} scheduler the scheduler that manages this task - * @constructor - */ -function HandlerTask(scheduler) { - this.scheduler = scheduler; - this.v1 = null; - this.v2 = null; -} - -HandlerTask.prototype.run = function (packet) { - if (packet != null) { - if (packet.kind == KIND_WORK) { - this.v1 = packet.addTo(this.v1); - } else { - this.v2 = packet.addTo(this.v2); - } - } - if (this.v1 != null) { - var count = this.v1.a1; - var v; - if (count < DATA_SIZE) { - if (this.v2 != null) { - v = this.v2; - this.v2 = this.v2.link; - v.a1 = this.v1.a2[count]; - this.v1.a1 = count + 1; - return this.scheduler.queue(v); - } - } else { - v = this.v1; - this.v1 = this.v1.link; - return this.scheduler.queue(v); - } - } - return this.scheduler.suspendCurrent(); -}; - -HandlerTask.prototype.toString = function () { - return "HandlerTask"; -}; - -/* --- * - * P a c k e t - * --- */ - -var DATA_SIZE = 4; - -/** - * A simple package of data that is manipulated by the tasks. The exact layout - * of the payload data carried by a packet is not importaint, and neither is the - * nature of the work performed on packets by the tasks. - * - * Besides carrying data, packets form linked lists and are hence used both as - * data and worklists. - * @param {Packet} link the tail of the linked list of packets - * @param {int} id an ID for this packet - * @param {int} kind the type of this packet - * @constructor - */ -function Packet(link, id, kind) { - this.link = link; - this.id = id; - this.kind = kind; - this.a1 = 0; - this.a2 = new Array(DATA_SIZE); -} - -/** - * Add this packet to the end of a worklist, and return the worklist. - * @param {Packet} queue the worklist to add this packet to - */ -Packet.prototype.addTo = function (queue) { - this.link = null; - if (queue == null) return this; - var peek, next = queue; - while ((peek = next.link) != null) - next = peek; - next.link = this; - return queue; -}; - -Packet.prototype.toString = function () { - return "Packet"; -}; diff --git a/utils/benchmark/Richards/richards.swift b/utils/benchmark/Richards/richards.swift deleted file mode 100644 index b5349b0da5602..0000000000000 --- a/utils/benchmark/Richards/richards.swift +++ /dev/null @@ -1,510 +0,0 @@ -// This is an OS kernel simulator, originally written in BCPL. -// -// Author: M. J. Jordan Cambridge Computer Laboratory. -// -// Modified by: M. Richards, Nov 1996 -// to be ANSI C and runnable on 64 bit machines + other minor changes -// Modified by: M. Richards, 20 Oct 1998 -// made minor corrections to improve ANSI compliance (suggested -// by David Levine) -// -// The swift implementation is bizarre mix of rigid system design and -// powerful language features. Strong compiler optimization have been -// shown to be essential on this benchmark for JavaScript. This -// benchmark was also chosen to evaluate a certain style of enum usage -// and optional operations. Initially we mimick the C implementation -// for a fair comparison. I envision multiple versions of this -// benchmark with progressively more advanced design. -// -// TODO: Gradually make this more swift-esque as we fix performance. -// Create Task subclasses. -// Convert the function pointers into dynamic dispatch on task subtype. -// Use enum option sets when they become available. - -let BufSize = 4 - -class Packet { - enum Kind { - case Dev - case Work - } - - var link: Packet? - var id: Int - var kind: Kind - var a1: UInt32 = 0 - var a2: [UInt8] = [UInt8](count:BufSize, repeatedValue:UInt8(0)) - - // This stands in for the original pkt() function. - init(link: Packet?, id: Int, kind: Kind) { - self.link = link - self.id = id - self.kind = kind - } - - func dump() { - print("PACKET") - if link { - print("link \(link!.id)") - } - print("id \(id)") - print("a1 \(a1)") - print("a2 ") - for a in a2 { - print("\(a) ") - } - print() - } -} - -// Task State Bitmask -let TSPktBit:UInt8 = 1 -let TSWaitBit:UInt8 = 2 -let TSHoldBit:UInt8 = 4 -let TSNotHoldBit:UInt8 = 0xfb -let TSRun:UInt8 = 0 -let TSRunPkt:UInt8 = 1 -let TSWait:UInt8 = 2 -let TSWaitPkt:UInt8 = 3 -let TSHold:UInt8 = 4 -let TSHoldPkt:UInt8 = 5 -let TSHoldWait:UInt8 = 6 -let TSHoldWaitPkt:UInt8 = 7 - -// Indices into a task table. -let TIIdle = 1 -let TIWork = 2 -let TIHandlerA = 3 -let TIHandlerB = 4 -let TIDevA = 5 -let TIDevB = 6 - -class Task { - // Bitmask - enum State { - case Bits(UInt8) - var bits: UInt8 { - switch self { - case .Bits(var i): - return i - } - } - } - enum Val1 { - case None - case TaskID(Int) - case Worklist(Packet) - - var taskid: Int { - get { - switch self { - case TaskID(var i): - return i - default: - fatalError("Task value is not a task ID") - return 0 - } - } - set(newid) { - self = TaskID(newid) - } - } - var packet: Packet? { - get { - switch self { - case Worklist(var wkq): - return wkq - case None: - return .None - default: - fatalError("Task value is not a worklist") - return .None - } - } - set(newpacket) { - self = !newpacket ? None : Worklist(newpacket!) - } - } - } - // Instead of an enum, Val2 could be a field of the task subclass. - enum Val2 { - case None - case Count(Int) // number of times this task should be scheduled. - case Worklist(Packet) - - var count: Int { - get { - switch self { - case Count(var i): - return i - default: - fatalError("Task value is not a count") - return 0 - } - } - set(newcount) { - self = Count(newcount) - } - } - var packet: Packet? { - get { - switch self { - case Worklist(var wkq): - return wkq - case None: - return .None - default: - fatalError("Task value is not a worklist") - return .None - } - } - set(newpacket) { - self = !newpacket ? None : Worklist(newpacket!) - } - } - } - var link: Task? - var id: Int // Array index - var pri: Int32 - var wkq: Packet? - var state: State - var fn: (Packet?) -> Task? - var v1: Val1 = .None - var v2: Val2 = .None - - init(link:Task?, id:Int, pri:Int32, wkq:Packet?, state:State, - fn:(Packet?) -> Task?, v1:Val1, v2:Val2) { - self.link=link - self.id=id - self.pri=pri - self.wkq=wkq - self.state=state - self.fn=fn - self.v1=v1 - self.v2=v2; - } -} - -struct Richards { - var tasktab: [Task?] = [Task?](count:11, repeatedValue:nil) - var tasklist: Task? = .None - - // We could have each type of Task know how to create itself given - // an id, priority, and queue. Then have a function that merely adds - // the task to the system. For now, we intentionally mimick the C - // implementation which passes through a large param list. - mutating func createTask( - id: Int, - pri: Int32, - wkq: Packet?, - state: Task.State, - fn: (Packet?) -> Task?, - v1: Task.Val1, - v2: Task.Val2) { - - var newtask = Task( - link:tasklist, - id:id, - pri:pri, - wkq:wkq, - state:state, - fn:fn, - v1:v1, - v2:v2) - - tasktab[id] = newtask - tasklist = newtask - } - - var layout = 0 - - mutating func trace(a: UnicodeScalar) { - if --layout <= 0 { - print() - layout = 50; - } - print("\(a)"); - } - - var tcb: Task? = .None - var taskid: Int? = .None - var v1: Task.Val1 = .None - var v2: Task.Val2 = .None - var tracing = false - - mutating func schedule() { - while tcb { - debug("TCB \(tcb!.id) state \(tcb!.state.bits)") - - var pkt:Packet? = .None - var newtcb: Task? = .None - - switch tcb!.state { - case .Bits(TSWaitPkt): - pkt = tcb!.wkq - tcb!.wkq = pkt!.link - tcb!.state = Task.State.Bits(!tcb!.wkq ? TSRun : TSRunPkt) - fallthrough - case .Bits(TSRun), - .Bits(TSRunPkt): - taskid = tcb!.id - v1 = tcb!.v1 - v2 = tcb!.v2 - if tracing { - trace(UnicodeScalar(UInt32(taskid!)+"0".value)) - } - newtcb = tcb!.fn(pkt) - tcb!.v1 = v1 - tcb!.v2 = v2 - tcb = newtcb - // break - case .Bits(TSWait), - .Bits(TSHold), - .Bits(TSHoldPkt), - .Bits(TSHoldWait), - .Bits(TSHoldWaitPkt): - tcb = tcb!.link; - default: - return - } - } - } - - func Wait() -> Task { - tcb!.state = Task.State.Bits(tcb!.state.bits | TSWaitBit) - return tcb! - } - - var holdcount = 0 - - mutating func holdself() -> Task? { - ++holdcount - tcb!.state = Task.State.Bits(tcb!.state.bits | TSHoldBit) - return tcb!.link - } - - func findtcb(id: Int) -> Task? { - var t: Task? = .None - if 1 <= id && id <= 10 { - t = tasktab[id] - } - if !t { - print() - print("Bad task id \(id)") - } - return t - } - - func release(id: Int) -> Task? { - var t = findtcb(id) - if !t { - return t - } - t!.state = Task.State.Bits(t!.state.bits & TSNotHoldBit) - if t!.pri > tcb!.pri { - return t - } - return tcb! - } - - var qpktcount = 0 - - mutating func qpkt(pkt: Packet) -> Task? { - let tt = findtcb(pkt.id) - if !tt { - return tt - } - let t = tt! - ++qpktcount - pkt.link = .None - pkt.id = taskid! - if !t.wkq { - t.wkq = pkt - t.state = Task.State.Bits(t.state.bits | TSPktBit) - if t.pri > tcb!.pri { - return t - } - } - else { - append(pkt, ptr: t.wkq) - } - return tcb - } - - // This could be a method on subclass IdleTask. - // For IdleTask v2 is a count - mutating func idlefn(pkt: Packet?) -> Task? { - debug("IDLE") - --v2.count - if v2.count == 0 { - return holdself() - } - // Orignal C impl masks with MAXINT. Why? - if (v1.taskid & 1) == 0 { - v1 = Task.Val1.TaskID(v1.taskid >> 1) - return release(TIDevA) - } - else { - v1 = Task.Val1.TaskID((v1.taskid >> 1) ^ 0xD008) - return release(TIDevB) - } - } - - let alphabet: [UInt8] = Array("0ABCDEFGHIJKLMNOPQRSTUVWXYZ".utf8) - - mutating func workfn(pkt: Packet?) -> Task? { - debug("WORK") - if !pkt { - return Wait() - } - v1 = Task.Val1.TaskID(TIHandlerA + TIHandlerB - v1.taskid) - pkt!.id = v1.taskid - pkt!.a1 = 0 - switch v2 { - case .None: - v2 = Task.Val2.Count(0) - case .Count: - break - default: - fatalError("Task value is not a count") - } - for i in 0.. 26 { - v2.count = 1 - } - pkt!.a2[i] = alphabet[v2.count] - } - return qpkt(pkt!) - } - - mutating func handlerfn(pkt: Packet?) -> Task? { - debug("HANDLE") - if pkt { - debug({pkt!.dump()}) - switch pkt!.kind { - case .Work: - v1.packet = append(pkt!, ptr:v1.packet) - default: - v2.packet = append(pkt!, ptr:v2.packet) - } - } - if v1.packet { - let workpkt = v1.packet! - let count = Int(workpkt.a1) - if count >= BufSize { - v1.packet = workpkt.link - return qpkt(workpkt) - } - if v2.packet { - var devpkt = v2.packet! - v2.packet = v2.packet!.link - devpkt.a1 = UInt32(v1.packet!.a2[count]) - v1.packet!.a1 = UInt32(count + 1) - return qpkt(devpkt) - } - } - return Wait() - } - - mutating func devfn(pkt: Packet?) -> Task? { - debug("DEV") - if !pkt { - if !v1.packet { - return Wait() - } - var pkt = v1.packet - v1.packet = .None - return qpkt(pkt!) - } - v1.packet = pkt! - if tracing { - trace(UnicodeScalar(pkt!.a1)) - } - return holdself() - } - - // The C benchmark does some horrible type punning here by passing - // the address of the queue (assuming the packet's link is the first - // field at offset 0). Instead, we return the new queue. - func append(pkt: Packet, ptr: Packet?) -> Packet { - pkt.link = .None - if !ptr { - return pkt - } - var next = ptr! - while next.link { - next = next.link! - } - next.link = pkt - return ptr! - } - - mutating func main() -> Int { - // Small problem size. - let Count = 1000*1000 - let Qpktcountval = 2326410 - let Holdcountval = 930563 - - print("Bench mark starting") - var wkq: Packet? = .None - createTask(TIIdle, pri:0, wkq:wkq, state:Task.State.Bits(TSRun), fn:idlefn, - v1:Task.Val1.TaskID(1), v2:Task.Val2.Count(Count)) - - wkq = Packet(link:.None, id:0, kind:Packet.Kind.Work) - wkq = Packet(link:wkq, id:0, kind:Packet.Kind.Work) - - createTask(TIWork, pri:1000, wkq:wkq, state:Task.State.Bits(TSWaitPkt), - fn:workfn, v1:Task.Val1.TaskID(TIHandlerA), v2:Task.Val2.None) - - wkq = Packet(link:.None, id:TIDevA, kind:Packet.Kind.Dev) - wkq = Packet(link:wkq, id:TIDevA, kind:Packet.Kind.Dev) - wkq = Packet(link:wkq, id:TIDevA, kind:Packet.Kind.Dev) - - createTask(TIHandlerA, pri:2000, wkq:wkq, state:Task.State.Bits(TSWaitPkt), - fn:handlerfn, v1:Task.Val1.None, v2:Task.Val2.None) - - wkq = Packet(link:.None, id:TIDevB, kind:Packet.Kind.Dev) - wkq = Packet(link:wkq, id:TIDevB, kind:Packet.Kind.Dev) - wkq = Packet(link:wkq, id:TIDevB, kind:Packet.Kind.Dev) - - createTask(TIHandlerB, pri:3000, wkq:wkq, state:Task.State.Bits(TSWaitPkt), - fn:handlerfn, v1:Task.Val1.None, v2:Task.Val2.None) - - wkq = .None - - createTask(TIDevA, pri:4000, wkq:wkq, state:Task.State.Bits(TSWait), - fn:devfn, v1:Task.Val1.None, v2:Task.Val2.None) - createTask(TIDevB, pri:5000, wkq:wkq, state:Task.State.Bits(TSWait), - fn:devfn, v1:Task.Val1.None, v2:Task.Val2.None) - - tcb = tasklist - - print("Starting") - - schedule() - - print("Finished") - - print("qpkt count = \(qpktcount) holdcount = \(holdcount)") - - print("These results are ") - var retval:Int - if qpktcount == Qpktcountval && holdcount == Holdcountval { - print("correct") - retval = 0 - } - else { - print("incorrect") - retval = 1 - } - print("end of run") - return retval - } - - func debug(m:String) {} - func debug(block: () -> ()) {} -} - -var r = Richards() -r.main() diff --git a/utils/benchmark/Richards/richards_benchmark.c b/utils/benchmark/Richards/richards_benchmark.c deleted file mode 100644 index 5382f2b048c49..0000000000000 --- a/utils/benchmark/Richards/richards_benchmark.c +++ /dev/null @@ -1,437 +0,0 @@ - -/* C version of the systems programming language benchmark -** Author: M. J. Jordan Cambridge Computer Laboratory. -** -** Modified by: M. Richards, Nov 1996 -** to be ANSI C and runnable on 64 bit machines + other minor changes -** Modified by: M. Richards, 20 Oct 1998 -** made minor corrections to improve ANSI compliance (suggested -** by David Levine) -** -** Compile with, say -** -** gcc -o bench bench.c -** -** or -** -** gcc -o bench100 -Dbench100 bench.c (for a version that obeys -** the main loop 100x more often) -*/ - -#include -#include - -#ifdef NDEBUG -#define DEBUG(...) -#define DEBUG_DO(x) -#else -#define DEBUG(...) printf(__VA_ARGS__) -#define DEBUG_DO(x) {x;} -#endif - -#ifdef SMALL_PROBLEM_SIZE -#define Count 1000*1000 -#define Qpktcountval 2326410 -#define Holdcountval 930563 -#else -#define Count 10000*1000 -#define Qpktcountval 23263894 -#define Holdcountval 9305557 -#endif - - -#define TRUE 1 -#define FALSE 0 -#define MAXINT 32767 - -#define BUFSIZE 3 -#define I_IDLE 1 -#define I_WORK 2 -#define I_HANDLERA 3 -#define I_HANDLERB 4 -#define I_DEVA 5 -#define I_DEVB 6 -#define PKTBIT 1 -#define WAITBIT 2 -#define HOLDBIT 4 -#define NOTPKTBIT !1 -#define NOTWAITBIT !2 -#define NOTHOLDBIT 0XFFFB - -#define S_RUN 0 -#define S_RUNPKT 1 -#define S_WAIT 2 -#define S_WAITPKT 3 -#define S_HOLD 4 -#define S_HOLDPKT 5 -#define S_HOLDWAIT 6 -#define S_HOLDWAITPKT 7 - -#define K_DEV 1000 -#define K_WORK 1001 - -struct packet -{ - struct packet *p_link; - int p_id; - int p_kind; - int p_a1; - char p_a2[4]; -}; - -void printpkt(struct packet *pkt) { - printf("PACKET\n"); - if (pkt->p_link) { - printf("link %d\n", pkt->p_link->p_id); - } - printf("id %d\n", pkt->p_id); - printf("a1 %d\n", pkt->p_a1); - printf("a2 "); - for (int i = 0; i <= BUFSIZE; ++i) { - printf("%d ", pkt->p_a2[i]); - } - printf("\n"); -} - -struct task -{ - struct task *t_link; - int t_id; - int t_pri; - struct packet *t_wkq; - int t_state; - struct task *(*t_fn)(struct packet *); - long t_v1; - long t_v2; -}; - -char alphabet[28] = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -struct task *tasktab[11] = {0,0,0,0,0,0,0,0,0,0,0}; -struct task *tasklist = 0; -struct task *tcb; -long taskid; -long v1; -long v2; -int qpktcount = 0; -int holdcount = 0; -int tracing = 1; -int layout = 0; - -void append(struct packet *pkt, struct packet *ptr); - -void createtask(int id, - int pri, - struct packet *wkq, - int state, - struct task *(*fn)(struct packet *), - long v1, - long v2) -{ - struct task *t = (struct task *)malloc(sizeof(struct task)); - - tasktab[id] = t; - t->t_link = tasklist; - t->t_id = id; - t->t_pri = pri; - t->t_wkq = wkq; - t->t_state = state; - t->t_fn = fn; - t->t_v1 = v1; - t->t_v2 = v2; - tasklist = t; -} - -struct packet *pkt(struct packet *link, int id, int kind) -{ - int i; - struct packet *p = (struct packet *)malloc(sizeof(struct packet)); - - for (i=0; i<=BUFSIZE; i++) - p->p_a2[i] = 0; - - p->p_link = link; - p->p_id = id; - p->p_kind = kind; - p->p_a1 = 0; - - return (p); -} - -void trace(char a) -{ - if ( --layout <= 0 ) - { - printf("\n"); - layout = 50; - } - - printf("%c", a); -} - -void schedule() -{ - while ( tcb != 0 ) - { - DEBUG("TCB %d state %d\n", tcb->t_id, tcb->t_state); - - struct packet *pkt; - struct task *newtcb; - - pkt=0; - - switch ( tcb->t_state ) - { - case S_WAITPKT: - pkt = tcb->t_wkq; - tcb->t_wkq = pkt->p_link; - tcb->t_state = tcb->t_wkq == 0 ? S_RUN : S_RUNPKT; - - case S_RUN: - case S_RUNPKT: - taskid = tcb->t_id; - v1 = tcb->t_v1; - v2 = tcb->t_v2; - if (tracing==TRUE) trace(taskid+'0'); - - newtcb = (*(tcb->t_fn))(pkt); - tcb->t_v1 = v1; - tcb->t_v2 = v2; - tcb = newtcb; - break; - - case S_WAIT: - case S_HOLD: - case S_HOLDPKT: - case S_HOLDWAIT: - case S_HOLDWAITPKT: - tcb = tcb->t_link; - break; - - default: - return; - } - } -} - -struct task *Wait(void) -{ - tcb->t_state |= WAITBIT; - return (tcb); -} - -struct task *holdself(void) -{ - ++holdcount; - tcb->t_state |= HOLDBIT; - return (tcb->t_link) ; -} - -struct task *findtcb(int id) -{ - struct task *t = 0; - - if (1<=id && id<=(long)10) - t = tasktab[id]; - if (t==0) printf("\nBad task id %d\n", id); - return(t); -} - -struct task *release(int id) -{ - struct task *t; - - t = findtcb(id); - if ( t==0 ) return (0); - - t->t_state &= NOTHOLDBIT; - if ( t->t_pri > tcb->t_pri ) return (t); - - return (tcb) ; -} - - -struct task *qpkt(struct packet *pkt) -{ - struct task *t; - - t = findtcb(pkt->p_id); - if (t==0) return (t); - - qpktcount++; - - pkt->p_link = 0; - pkt->p_id = taskid; - - if (t->t_wkq==0) - { - t->t_wkq = pkt; - t->t_state |= PKTBIT; - if (t->t_pri > tcb->t_pri) return (t); - } - else - { - append(pkt, (struct packet *)&(t->t_wkq)); - } - - return (tcb); -} - -struct task *idlefn(struct packet *pkt) -{ - DEBUG("IDLE\n"); - --v2; - if ( v2==0 ) return ( holdself() ); - - if ( (v1&1) == 0 ) - { - v1 = ( v1>>1) & MAXINT; - return ( release(I_DEVA) ); - } - else - { - v1 = ( (v1>>1) & MAXINT) ^ 0XD008; - return ( release(I_DEVB) ); - } -} - -struct task *workfn(struct packet *pkt) -{ - DEBUG("WORK\n"); - if ( pkt==0 ) return ( Wait() ); - else - { - int i; - - v1 = I_HANDLERA + I_HANDLERB - v1; - pkt->p_id = v1; - - pkt->p_a1 = 0; - for (i=0; i<=BUFSIZE; i++) - { - v2++; - if ( v2 > 26 ) v2 = 1; - (pkt->p_a2)[i] = alphabet[v2]; - } - return ( qpkt(pkt) ); - } -} - -struct task *handlerfn(struct packet *pkt) -{ - DEBUG("HANDLE\n"); - if ( pkt!=0) { - DEBUG_DO(printpkt(pkt)); - append(pkt, (struct packet *)(pkt->p_kind==K_WORK ? &v1 : &v2)); - } - if ( v1!=0 ) - { - int count; - struct packet *workpkt = (struct packet *)v1; - count = workpkt->p_a1; - - if ( count > BUFSIZE ) - { - v1 = (long)(((struct packet *)v1)->p_link); - return ( qpkt(workpkt) ); - } - - if ( v2!=0 ) - { - struct packet *devpkt; - - devpkt = (struct packet *)v2; - v2 = (long)(((struct packet *)v2)->p_link); - devpkt->p_a1 = workpkt->p_a2[count]; - workpkt->p_a1 = count+1; - return( qpkt(devpkt) ); - } - } - return ( Wait() ); -} - -struct task *devfn(struct packet *pkt) -{ - DEBUG("DEV\n"); - if ( pkt==0 ) - { - if ( v1==0 ) return ( Wait() ); - pkt = (struct packet *)v1; - v1 = 0; - return ( qpkt(pkt) ); - } - else - { - v1 = (long)pkt; - if (tracing==TRUE) trace(pkt->p_a1); - return ( holdself() ); - } -} - -void append(struct packet *pkt, struct packet *ptr) -{ - pkt->p_link = 0; - - while ( ptr->p_link ) ptr = ptr->p_link; - - ptr->p_link = pkt; -} - -int main() -{ - struct packet *wkq = 0; - int retval; - - printf("Bench mark starting\n"); - - createtask(I_IDLE, 0, wkq, S_RUN, idlefn, 1, Count); - - wkq = pkt(0, 0, K_WORK); - wkq = pkt(wkq, 0, K_WORK); - - createtask(I_WORK, 1000, wkq, S_WAITPKT, workfn, I_HANDLERA, 0); - - wkq = pkt(0, I_DEVA, K_DEV); - wkq = pkt(wkq, I_DEVA, K_DEV); - wkq = pkt(wkq, I_DEVA, K_DEV); - - createtask(I_HANDLERA, 2000, wkq, S_WAITPKT, handlerfn, 0, 0); - - wkq = pkt(0, I_DEVB, K_DEV); - wkq = pkt(wkq, I_DEVB, K_DEV); - wkq = pkt(wkq, I_DEVB, K_DEV); - - createtask(I_HANDLERB, 3000, wkq, S_WAITPKT, handlerfn, 0, 0); - - wkq = 0; - createtask(I_DEVA, 4000, wkq, S_WAIT, devfn, 0, 0); - createtask(I_DEVB, 5000, wkq, S_WAIT, devfn, 0, 0); - - tcb = tasklist; - - qpktcount = holdcount = 0; - - printf("Starting\n"); - - tracing = FALSE; - layout = 0; - - schedule(); - - printf("finished\n"); - - printf("qpkt count = %d holdcount = %d\n", - qpktcount, holdcount); - - printf("These results are "); - if (qpktcount == Qpktcountval && holdcount == Holdcountval) { - printf("correct"); - retval = 0; - } else { - printf("incorrect"); - retval = 1; - } - - printf("\nend of run\n"); - return retval; -} - diff --git a/utils/benchmark/Strings/CPPStringBench.cpp b/utils/benchmark/Strings/CPPStringBench.cpp deleted file mode 100644 index ca053df27c9c7..0000000000000 --- a/utils/benchmark/Strings/CPPStringBench.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -#define LAPS 10000000 - -std::wstring s = L"siebenhundertsiebenundsiebzigtausendsiebenhundertsiebenundsiebzig"; - -int -main(void) { - uint64_t count = 0; - uint64_t start = mach_absolute_time(); - for (auto i = 0; i < LAPS; i++) { - for (auto c : s) { - count++; - asm volatile("" : "+r" (count)); - } - } - uint64_t delta = mach_absolute_time() - start; - printf("%f nanoseconds\n", (double)delta); - printf("%f ns/lap\n", (double)delta / (double)LAPS); - - return 0; -} diff --git a/utils/benchmark/Strings/CPPStringSort.cpp b/utils/benchmark/Strings/CPPStringSort.cpp deleted file mode 100644 index 0f3d7da9c7c94..0000000000000 --- a/utils/benchmark/Strings/CPPStringSort.cpp +++ /dev/null @@ -1,1024 +0,0 @@ -#include -#include -#include -#include - -// Remember to build with C++11 - -int -main(void) { - std::vector words { - L"woodshed", - L"lakism", - L"gastroperiodynia", - L"afetal", - L"ramsch", - L"Nickieben", - L"undutifulness", - L"birdglue", - L"ungentlemanize", - L"menacingly", - L"heterophile", - L"leoparde", - L"Casearia", - L"decorticate", - L"neognathic", - L"mentionable", - L"tetraphenol", - L"pseudonymal", - L"dislegitimate", - L"Discoidea", - L"intitule", - L"ionium", - L"Lotuko", - L"timbering", - L"nonliquidating", - L"oarialgia", - L"Saccobranchus", - L"reconnoiter", - L"criminative", - L"disintegratory", - L"executer", - L"Cylindrosporium", - L"complimentation", - L"Ixiama", - L"Araceae", - L"silaginoid", - L"derencephalus", - L"Lamiidae", - L"marrowlike", - L"ninepin", - L"dynastid", - L"lampfly", - L"feint", - L"trihemimer", - L"semibarbarous", - L"heresy", - L"tritanope", - L"indifferentist", - L"confound", - L"hyperbolaeon", - L"planirostral", - L"philosophunculist", - L"existence", - L"fretless", - L"Leptandra", - L"Amiranha", - L"handgravure", - L"gnash", - L"unbelievability", - L"orthotropic", - L"Susumu", - L"teleutospore", - L"sleazy", - L"shapeliness", - L"hepatotomy", - L"exclusivism", - L"stifler", - L"cunning", - L"isocyanuric", - L"pseudepigraphy", - L"carpetbagger", - L"respectiveness", - L"Jussi", - L"vasotomy", - L"proctotomy", - L"ovatotriangular", - L"aesthetic", - L"schizogamy", - L"disengagement", - L"foray", - L"haplocaulescent", - L"noncoherent", - L"astrocyte", - L"unreverberated", - L"presenile", - L"lanson", - L"enkraal", - L"contemplative", - L"Syun", - L"sartage", - L"unforgot", - L"wyde", - L"homeotransplant", - L"implicational", - L"forerunnership", - L"calcaneum", - L"stomatodeum", - L"pharmacopedia", - L"preconcessive", - L"trypanosomatic", - L"intracollegiate", - L"rampacious", - L"secundipara", - L"isomeric", - L"treehair", - L"pulmonal", - L"uvate", - L"dugway", - L"glucofrangulin", - L"unglory", - L"Amandus", - L"icterogenetic", - L"quadrireme", - L"Lagostomus", - L"brakeroot", - L"anthracemia", - L"fluted", - L"protoelastose", - L"thro", - L"pined", - L"Saxicolinae", - L"holidaymaking", - L"strigil", - L"uncurbed", - L"starling", - L"redeemeress", - L"Liliaceae", - L"imparsonee", - L"obtusish", - L"brushed", - L"mesally", - L"probosciformed", - L"Bourbonesque", - L"histological", - L"caroba", - L"digestion", - L"Vindemiatrix", - L"triactinal", - L"tattling", - L"arthrobacterium", - L"unended", - L"suspectfulness", - L"movelessness", - L"chartist", - L"Corynebacterium", - L"tercer", - L"oversaturation", - L"Congoleum", - L"antiskeptical", - L"sacral", - L"equiradiate", - L"whiskerage", - L"panidiomorphic", - L"unplanned", - L"anilopyrine", - L"Queres", - L"tartronyl", - L"Ing", - L"notehead", - L"finestiller", - L"weekender", - L"kittenhood", - L"competitrix", - L"premillenarian", - L"convergescence", - L"microcoleoptera", - L"slirt", - L"asteatosis", - L"Gruidae", - L"metastome", - L"ambuscader", - L"untugged", - L"uneducated", - L"redistill", - L"rushlight", - L"freakish", - L"dosology", - L"papyrine", - L"iconologist", - L"Bidpai", - L"prophethood", - L"pneumotropic", - L"chloroformize", - L"intemperance", - L"spongiform", - L"superindignant", - L"divider", - L"starlit", - L"merchantish", - L"indexless", - L"unidentifiably", - L"coumarone", - L"nomism", - L"diaphanous", - L"salve", - L"option", - L"anallantoic", - L"paint", - L"thiofurfuran", - L"baddeleyite", - L"Donne", - L"heterogenicity", - L"decess", - L"eschynite", - L"mamma", - L"unmonarchical", - L"Archiplata", - L"widdifow", - L"apathic", - L"overline", - L"chaetophoraceous", - L"creaky", - L"trichosporange", - L"uninterlined", - L"cometwise", - L"hermeneut", - L"unbedraggled", - L"tagged", - L"Sminthurus", - L"somniloquacious", - L"aphasiac", - L"Inoperculata", - L"photoactivity", - L"mobship", - L"unblightedly", - L"lievrite", - L"Khoja", - L"Falerian", - L"milfoil", - L"protectingly", - L"householder", - L"cathedra", - L"calmingly", - L"tordrillite", - L"rearhorse", - L"Leonard", - L"maracock", - L"youngish", - L"kammererite", - L"metanephric", - L"Sageretia", - L"diplococcoid", - L"accelerative", - L"choreal", - L"metalogical", - L"recombination", - L"unimprison", - L"invocation", - L"syndetic", - L"toadback", - L"vaned", - L"cupholder", - L"metropolitanship", - L"paramandelic", - L"dermolysis", - L"Sheriyat", - L"rhabdus", - L"seducee", - L"encrinoid", - L"unsuppliable", - L"cololite", - L"timesaver", - L"preambulate", - L"sampling", - L"roaster", - L"springald", - L"densher", - L"protraditional", - L"naturalesque", - L"Hydrodamalis", - L"cytogenic", - L"shortly", - L"cryptogrammatical", - L"squat", - L"genual", - L"backspier", - L"solubleness", - L"macroanalytical", - L"overcovetousness", - L"Natalie", - L"cuprobismutite", - L"phratriac", - L"Montanize", - L"hymnologist", - L"karyomiton", - L"podger", - L"unofficiousness", - L"antisplasher", - L"supraclavicular", - L"calidity", - L"disembellish", - L"antepredicament", - L"recurvirostral", - L"pulmonifer", - L"coccidial", - L"botonee", - L"protoglobulose", - L"isonym", - L"myeloid", - L"premiership", - L"unmonopolize", - L"unsesquipedalian", - L"unfelicitously", - L"theftbote", - L"undauntable", - L"lob", - L"praenomen", - L"underriver", - L"gorfly", - L"pluckage", - L"radiovision", - L"tyrantship", - L"fraught", - L"doppelkummel", - L"rowan", - L"allosyndetic", - L"kinesiology", - L"psychopath", - L"arrent", - L"amusively", - L"preincorporation", - L"Montargis", - L"pentacron", - L"neomedievalism", - L"sima", - L"lichenicolous", - L"Ecclesiastes", - L"woofed", - L"cardinalist", - L"sandaracin", - L"gymnasial", - L"lithoglyptics", - L"centimeter", - L"quadrupedous", - L"phraseology", - L"tumuli", - L"ankylotomy", - L"myrtol", - L"cohibitive", - L"lepospondylous", - L"silvendy", - L"inequipotential", - L"entangle", - L"raveling", - L"Zeugobranchiata", - L"devastating", - L"grainage", - L"amphisbaenian", - L"blady", - L"cirrose", - L"proclericalism", - L"governmentalist", - L"carcinomorphic", - L"nurtureship", - L"clancular", - L"unsteamed", - L"discernibly", - L"pleurogenic", - L"impalpability", - L"Azotobacterieae", - L"sarcoplasmic", - L"alternant", - L"fitly", - L"acrorrheuma", - L"shrapnel", - L"pastorize", - L"gulflike", - L"foreglow", - L"unrelated", - L"cirriped", - L"cerviconasal", - L"sexuale", - L"pussyfooter", - L"gadolinic", - L"duplicature", - L"codelinquency", - L"trypanolysis", - L"pathophobia", - L"incapsulation", - L"nonaerating", - L"feldspar", - L"diaphonic", - L"epiglottic", - L"depopulator", - L"wisecracker", - L"gravitational", - L"kuba", - L"lactesce", - L"Toxotes", - L"periomphalic", - L"singstress", - L"fannier", - L"counterformula", - L"Acemetae", - L"repugnatorial", - L"collimator", - L"Acinetina", - L"unpeace", - L"drum", - L"tetramorphic", - L"descendentalism", - L"cementer", - L"supraloral", - L"intercostal", - L"Nipponize", - L"negotiator", - L"vacationless", - L"synthol", - L"fissureless", - L"resoap", - L"pachycarpous", - L"reinspiration", - L"misappropriation", - L"disdiazo", - L"unheatable", - L"streng", - L"Detroiter", - L"infandous", - L"loganiaceous", - L"desugar", - L"Matronalia", - L"myxocystoma", - L"Gandhiism", - L"kiddier", - L"relodge", - L"counterreprisal", - L"recentralize", - L"foliously", - L"reprinter", - L"gender", - L"edaciousness", - L"chondriomite", - L"concordant", - L"stockrider", - L"pedary", - L"shikra", - L"blameworthiness", - L"vaccina", - L"Thamnophilinae", - L"wrongwise", - L"unsuperannuated", - L"convalescency", - L"intransmutable", - L"dropcloth", - L"Ceriomyces", - L"ponderal", - L"unstentorian", - L"mem", - L"deceleration", - L"ethionic", - L"untopped", - L"wetback", - L"bebar", - L"undecaying", - L"shoreside", - L"energize", - L"presacral", - L"undismay", - L"agricolite", - L"cowheart", - L"hemibathybian", - L"postexilian", - L"Phacidiaceae", - L"offing", - L"redesignation", - L"skeptically", - L"physicianless", - L"bronchopathy", - L"marabuto", - L"proprietory", - L"unobtruded", - L"funmaker", - L"plateresque", - L"preadventure", - L"beseeching", - L"cowpath", - L"pachycephalia", - L"arthresthesia", - L"supari", - L"lengthily", - L"Nepa", - L"liberation", - L"nigrify", - L"belfry", - L"entoolitic", - L"bazoo", - L"pentachromic", - L"distinguishable", - L"slideable", - L"galvanoscope", - L"remanage", - L"cetene", - L"bocardo", - L"consummation", - L"boycottism", - L"perplexity", - L"astay", - L"Gaetuli", - L"periplastic", - L"consolidator", - L"sluggarding", - L"coracoscapular", - L"anangioid", - L"oxygenizer", - L"Hunanese", - L"seminary", - L"periplast", - L"Corylus", - L"unoriginativeness", - L"persecutee", - L"tweaker", - L"silliness", - L"Dabitis", - L"facetiousness", - L"thymy", - L"nonimperial", - L"mesoblastema", - L"turbiniform", - L"churchway", - L"cooing", - L"frithbot", - L"concomitantly", - L"stalwartize", - L"clingfish", - L"hardmouthed", - L"parallelepipedonal", - L"coracoacromial", - L"factuality", - L"curtilage", - L"arachnoidean", - L"semiaridity", - L"phytobacteriology", - L"premastery", - L"hyperpurist", - L"mobed", - L"opportunistic", - L"acclimature", - L"outdistance", - L"sophister", - L"condonement", - L"oxygenerator", - L"acetonic", - L"emanatory", - L"periphlebitis", - L"nonsociety", - L"spectroradiometric", - L"superaverage", - L"cleanness", - L"posteroventral", - L"unadvised", - L"unmistakedly", - L"pimgenet", - L"auresca", - L"overimitate", - L"dipnoan", - L"chromoxylograph", - L"triakistetrahedron", - L"Suessiones", - L"uncopiable", - L"oligomenorrhea", - L"fribbling", - L"worriable", - L"flot", - L"ornithotrophy", - L"phytoteratology", - L"setup", - L"lanneret", - L"unbraceleted", - L"gudemother", - L"Spica", - L"unconsolatory", - L"recorruption", - L"premenstrual", - L"subretinal", - L"millennialist", - L"subjectibility", - L"rewardproof", - L"counterflight", - L"pilomotor", - L"carpetbaggery", - L"macrodiagonal", - L"slim", - L"indiscernible", - L"cuckoo", - L"moted", - L"controllingly", - L"gynecopathy", - L"porrectus", - L"wanworth", - L"lutfisk", - L"semiprivate", - L"philadelphy", - L"abdominothoracic", - L"coxcomb", - L"dambrod", - L"Metanemertini", - L"balminess", - L"homotypy", - L"waremaker", - L"absurdity", - L"gimcrack", - L"asquat", - L"suitable", - L"perimorphous", - L"kitchenwards", - L"pielum", - L"salloo", - L"paleontologic", - L"Olson", - L"Tellinidae", - L"ferryman", - L"peptonoid", - L"Bopyridae", - L"fallacy", - L"ictuate", - L"aguinaldo", - L"rhyodacite", - L"Ligydidae", - L"galvanometric", - L"acquisitor", - L"muscology", - L"hemikaryon", - L"ethnobotanic", - L"postganglionic", - L"rudimentarily", - L"replenish", - L"phyllorhine", - L"popgunnery", - L"summar", - L"quodlibetary", - L"xanthochromia", - L"autosymbolically", - L"preloreal", - L"extent", - L"strawberry", - L"immortalness", - L"colicwort", - L"frisca", - L"electiveness", - L"heartbroken", - L"affrightingly", - L"reconfiscation", - L"jacchus", - L"imponderably", - L"semantics", - L"beennut", - L"paleometeorological", - L"becost", - L"timberwright", - L"resuppose", - L"syncategorematical", - L"cytolymph", - L"steinbok", - L"explantation", - L"hyperelliptic", - L"antescript", - L"blowdown", - L"antinomical", - L"caravanserai", - L"unweariedly", - L"isonymic", - L"keratoplasty", - L"vipery", - L"parepigastric", - L"endolymphatic", - L"Londonese", - L"necrotomy", - L"angelship", - L"Schizogregarinida", - L"steeplebush", - L"sparaxis", - L"connectedness", - L"tolerance", - L"impingent", - L"agglutinin", - L"reviver", - L"hieroglyphical", - L"dialogize", - L"coestate", - L"declamatory", - L"ventilation", - L"tauromachy", - L"cotransubstantiate", - L"pome", - L"underseas", - L"triquadrantal", - L"preconfinemnt", - L"electroindustrial", - L"selachostomous", - L"nongolfer", - L"mesalike", - L"hamartiology", - L"ganglioblast", - L"unsuccessive", - L"yallow", - L"bacchanalianly", - L"platydactyl", - L"Bucephala", - L"ultraurgent", - L"penalist", - L"catamenial", - L"lynnhaven", - L"unrelevant", - L"lunkhead", - L"metropolitan", - L"hydro", - L"outsoar", - L"vernant", - L"interlanguage", - L"catarrhal", - L"Ionicize", - L"keelless", - L"myomantic", - L"booker", - L"Xanthomonas", - L"unimpeded", - L"overfeminize", - L"speronaro", - L"diaconia", - L"overholiness", - L"liquefacient", - L"Spartium", - L"haggly", - L"albumose", - L"nonnecessary", - L"sulcalization", - L"decapitate", - L"cellated", - L"unguirostral", - L"trichiurid", - L"loveproof", - L"amakebe", - L"screet", - L"arsenoferratin", - L"unfrizz", - L"undiscoverable", - L"procollectivistic", - L"tractile", - L"Winona", - L"dermostosis", - L"eliminant", - L"scomberoid", - L"tensile", - L"typesetting", - L"xylic", - L"dermatopathology", - L"cycloplegic", - L"revocable", - L"fissate", - L"afterplay", - L"screwship", - L"microerg", - L"bentonite", - L"stagecoaching", - L"beglerbeglic", - L"overcharitably", - L"Plotinism", - L"Veddoid", - L"disequalize", - L"cytoproct", - L"trophophore", - L"antidote", - L"allerion", - L"famous", - L"convey", - L"postotic", - L"rapillo", - L"cilectomy", - L"penkeeper", - L"patronym", - L"bravely", - L"ureteropyelitis", - L"Hildebrandine", - L"missileproof", - L"Conularia", - L"deadening", - L"Conrad", - L"pseudochylous", - L"typologically", - L"strummer", - L"luxuriousness", - L"resublimation", - L"glossiness", - L"hydrocauline", - L"anaglyph", - L"personifiable", - L"seniority", - L"formulator", - L"datiscaceous", - L"hydracrylate", - L"Tyranni", - L"Crawthumper", - L"overprove", - L"masher", - L"dissonance", - L"Serpentinian", - L"malachite", - L"interestless", - L"stchi", - L"ogum", - L"polyspermic", - L"archegoniate", - L"precogitation", - L"Alkaphrah", - L"craggily", - L"delightfulness", - L"bioplast", - L"diplocaulescent", - L"neverland", - L"interspheral", - L"chlorhydric", - L"forsakenly", - L"scandium", - L"detubation", - L"telega", - L"Valeriana", - L"centraxonial", - L"anabolite", - L"neger", - L"miscellanea", - L"whalebacker", - L"stylidiaceous", - L"unpropelled", - L"Kennedya", - L"Jacksonite", - L"ghoulish", - L"Dendrocalamus", - L"paynimhood", - L"rappist", - L"unluffed", - L"falling", - L"Lyctus", - L"uncrown", - L"warmly", - L"pneumatism", - L"Morisonian", - L"notate", - L"isoagglutinin", - L"Pelidnota", - L"previsit", - L"contradistinctly", - L"utter", - L"porometer", - L"gie", - L"germanization", - L"betwixt", - L"prenephritic", - L"underpier", - L"Eleutheria", - L"ruthenious", - L"convertor", - L"antisepsin", - L"winterage", - L"tetramethylammonium", - L"Rockaway", - L"Penaea", - L"prelatehood", - L"brisket", - L"unwishful", - L"Minahassa", - L"Briareus", - L"semiaxis", - L"disintegrant", - L"peastick", - L"iatromechanical", - L"fastus", - L"thymectomy", - L"ladyless", - L"unpreened", - L"overflutter", - L"sicker", - L"apsidally", - L"thiazine", - L"guideway", - L"pausation", - L"tellinoid", - L"abrogative", - L"foraminulate", - L"omphalos", - L"Monorhina", - L"polymyarian", - L"unhelpful", - L"newslessness", - L"oryctognosy", - L"octoradial", - L"doxology", - L"arrhythmy", - L"gugal", - L"mesityl", - L"hexaplaric", - L"Cabirian", - L"hordeiform", - L"eddyroot", - L"internarial", - L"deservingness", - L"jawbation", - L"orographically", - L"semiprecious", - L"seasick", - L"thermically", - L"grew", - L"tamability", - L"egotistically", - L"fip", - L"preabsorbent", - L"leptochroa", - L"ethnobotany", - L"podolite", - L"egoistic", - L"semitropical", - L"cero", - L"spinelessness", - L"onshore", - L"omlah", - L"tintinnabulist", - L"machila", - L"entomotomy", - L"nubile", - L"nonscholastic", - L"burnt", - L"Alea", - L"befume", - L"doctorless", - L"Napoleonic", - L"scenting", - L"apokreos", - L"cresylene", - L"paramide", - L"rattery", - L"disinterested", - L"idiopathetic", - L"negatory", - L"fervid", - L"quintato", - L"untricked", - L"Metrosideros", - L"mescaline", - L"midverse", - L"Musophagidae", - L"fictionary", - L"branchiostegous", - L"yoker", - L"residuum", - L"culmigenous", - L"fleam", - L"suffragism", - L"Anacreon", - L"sarcodous", - L"parodistic", - L"writmaking", - L"conversationism", - L"retroposed", - L"tornillo", - L"presuspect", - L"didymous", - L"Saumur", - L"spicing", - L"drawbridge", - L"cantor", - L"incumbrancer", - L"heterospory", - L"Turkeydom", - L"anteprandial", - L"neighbourship", - L"thatchless", - L"drepanoid", - L"lusher", - L"paling", - L"ecthlipsis", - L"heredosyphilitic", - L"although", - L"garetta", - L"temporarily", - L"Monotropa", - L"proglottic", - L"calyptro", - L"persiflage", - L"degradable", - L"paraspecific", - L"undecorative", - L"Pholas", - L"myelon", - L"resteal", - L"quadrantly", - L"scrimped", - L"airer", - L"deviless", - L"caliciform", - L"Sefekhet", - L"shastaite", - L"togate", - L"macrostructure", - L"bipyramid", - L"wey", - L"didynamy", - L"knacker", - L"swage", - L"supermanism", - L"epitheton", - L"overpresumptuous" - }; - - asm volatile("" ::: "memory"); - - uint64_t start = mach_absolute_time(); - sort(words.begin(), words.end()); - uint64_t delta = mach_absolute_time() - start; - - asm volatile("" : "+m" (words)); - - printf("%llu nanoseconds\n", delta); - - return 0; -} diff --git a/utils/benchmark/Strings/NSStringBench.m b/utils/benchmark/Strings/NSStringBench.m deleted file mode 100644 index bf759d08b59f7..0000000000000 --- a/utils/benchmark/Strings/NSStringBench.m +++ /dev/null @@ -1,46 +0,0 @@ -#import -#include -#include - -// NOTE: compile with ARC enabled -// clang -fobjc-arc -O3 NSStringBench.m -o NSStringBench.bin - -#define LAPS 10000 - -int -main(void) { - - NSString *complex = @"निरन्तरान्धकारिता-दिगन्तर-कन्दलदमन्द-सुधारस-बिन्दु-सान्द्रतर-घनाघन-वृन्द-सन्देहकर-स्यन्दमान-मकरन्द-बिन्दु-बन्धुरतर-माकन्द-तरु-कुल-तल्प-कल्प-मृदुल-सिकता-जाल-जटिल-मूल-तल-मरुवक-मिलदलघु-लघु-लय-कलित-रमणीय-पानीय-शालिका-बालिका-करार-विन्द-गलन्तिका-गलदेला-लवङ्ग-पाटल-घनसार-कस्तूरिकातिसौरभ-मेदुर-लघुतर-मधुर-शीतलतर-सलिलधारा-निराकरिष्णु-तदीय-विमल-विलोचन-मयूख-रेखापसारित-पिपासायास-पथिक-लोकान्"; - - NSString *s = @"siebenhundertsiebenundsiebzigtausendsiebenhundertsiebenundsiebzig"; - //s = complex; - uint64_t count = 0; - uint64_t start = mach_absolute_time(); - for (unsigned i = 0; i < LAPS; i++) { - for (NSUInteger j = 0, sLen = [s length]; j < sLen; j++) { - [s characterAtIndex: j]; - count++; - } - } - uint64_t delta = mach_absolute_time() - start; - printf("%f ns\n", (double)delta); - printf("%f ns/lap\n", (double)delta / (double)LAPS); - - NSString *url = @"http://www.apple.com/iphone-5s/built-in-apps/"; - start = mach_absolute_time(); - for (unsigned i = 0; i < LAPS; i++) { - NSString *proto = nil; - NSString *rest = nil; - for (NSUInteger j = 0, sLen = [s length]; j < sLen; j++) { - if ([s characterAtIndex: j] == ':') { - proto = [url substringToIndex: j]; - rest = [url substringFromIndex: j + 1]; - break; - } - } - } - delta = mach_absolute_time() - start; - printf("URL parsing: %f ns/lap\n", (double)delta / (double)LAPS); - - return 0; -} diff --git a/utils/benchmark/Strings/SortStrings.cpp b/utils/benchmark/Strings/SortStrings.cpp deleted file mode 100644 index 0376e12653dd4..0000000000000 --- a/utils/benchmark/Strings/SortStrings.cpp +++ /dev/null @@ -1,370 +0,0 @@ -#include -#include -#include -#include -#include - -#define LAPS 50 - -const char *data[] = { - "woodshed", "lakism", "gastroperiodynia", - "afetal", "ramsch", "Nickieben", - "undutifulness", "birdglue", "ungentlemanize", - "menacingly", "heterophile", "leoparde", - "Casearia", "decorticate", "neognathic", - "mentionable", "tetraphenol", "pseudonymal", - "dislegitimate", "Discoidea", "intitule", - "ionium", "Lotuko", "timbering", - "nonliquidating", "oarialgia", "Saccobranchus", - "reconnoiter", "criminative", "disintegratory", - "executer", "Cylindrosporium", "complimentation", - "Ixiama", "Araceae", "silaginoid", - "derencephalus", "Lamiidae", "marrowlike", - "ninepin", "dynastid", "lampfly", - "feint", "trihemimer", "semibarbarous", - "heresy", "tritanope", "indifferentist", - "confound", "hyperbolaeon", "planirostral", - "philosophunculist", "existence", "fretless", - "Leptandra", "Amiranha", "handgravure", - "gnash", "unbelievability", "orthotropic", - "Susumu", "teleutospore", "sleazy", - "shapeliness", "hepatotomy", "exclusivism", - "stifler", "cunning", "isocyanuric", - "pseudepigraphy", "carpetbagger", "respectiveness", - "Jussi", "vasotomy", "proctotomy", - "ovatotriangular", "aesthetic", "schizogamy", - "disengagement", "foray", "haplocaulescent", - "noncoherent", "astrocyte", "unreverberated", - "presenile", "lanson", "enkraal", - "contemplative", "Syun", "sartage", - "unforgot", "wyde", "homeotransplant", - "implicational", "forerunnership", "calcaneum", - "stomatodeum", "pharmacopedia", "preconcessive", - "trypanosomatic", "intracollegiate", "rampacious", - "secundipara", "isomeric", "treehair", - "pulmonal", "uvate", "dugway", - "glucofrangulin", "unglory", "Amandus", - "icterogenetic", "quadrireme", "Lagostomus", - "brakeroot", "anthracemia", "fluted", - "protoelastose", "thro", "pined", - "Saxicolinae", "holidaymaking", "strigil", - "uncurbed", "starling", "redeemeress", - "Liliaceae", "imparsonee", "obtusish", - "brushed", "mesally", "probosciformed", - "Bourbonesque", "histological", "caroba", - "digestion", "Vindemiatrix", "triactinal", - "tattling", "arthrobacterium", "unended", - "suspectfulness", "movelessness", "chartist", - "Corynebacterium", "tercer", "oversaturation", - "Congoleum", "antiskeptical", "sacral", - "equiradiate", "whiskerage", "panidiomorphic", - "unplanned", "anilopyrine", "Queres", - "tartronyl", "Ing", "notehead", - "finestiller", "weekender", "kittenhood", - "competitrix", "premillenarian", "convergescence", - "microcoleoptera", "slirt", "asteatosis", - "Gruidae", "metastome", "ambuscader", - "untugged", "uneducated", "redistill", - "rushlight", "freakish", "dosology", - "papyrine", "iconologist", "Bidpai", - "prophethood", "pneumotropic", "chloroformize", - "intemperance", "spongiform", "superindignant", - "divider", "starlit", "merchantish", - "indexless", "unidentifiably", "coumarone", - "nomism", "diaphanous", "salve", - "option", "anallantoic", "paint", - "thiofurfuran", "baddeleyite", "Donne", - "heterogenicity", "decess", "eschynite", - "mamma", "unmonarchical", "Archiplata", - "widdifow", "apathic", "overline", - "chaetophoraceous", "creaky", "trichosporange", - "uninterlined", "cometwise", "hermeneut", - "unbedraggled", "tagged", "Sminthurus", - "somniloquacious", "aphasiac", "Inoperculata", - "photoactivity", "mobship", "unblightedly", - "lievrite", "Khoja", "Falerian", - "milfoil", "protectingly", "householder", - "cathedra", "calmingly", "tordrillite", - "rearhorse", "Leonard", "maracock", - "youngish", "kammererite", "metanephric", - "Sageretia", "diplococcoid", "accelerative", - "choreal", "metalogical", "recombination", - "unimprison", "invocation", "syndetic", - "toadback", "vaned", "cupholder", - "metropolitanship", "paramandelic", "dermolysis", - "Sheriyat", "rhabdus", "seducee", - "encrinoid", "unsuppliable", "cololite", - "timesaver", "preambulate", "sampling", - "roaster", "springald", "densher", - "protraditional", "naturalesque", "Hydrodamalis", - "cytogenic", "shortly", "cryptogrammatical", - "squat", "genual", "backspier", - "solubleness", "macroanalytical", "overcovetousness", - "Natalie", "cuprobismutite", "phratriac", - "Montanize", "hymnologist", "karyomiton", - "podger", "unofficiousness", "antisplasher", - "supraclavicular", "calidity", "disembellish", - "antepredicament", "recurvirostral", "pulmonifer", - "coccidial", "botonee", "protoglobulose", - "isonym", "myeloid", "premiership", - "unmonopolize", "unsesquipedalian", "unfelicitously", - "theftbote", "undauntable", "lob", - "praenomen", "underriver", "gorfly", - "pluckage", "radiovision", "tyrantship", - "fraught", "doppelkummel", "rowan", - "allosyndetic", "kinesiology", "psychopath", - "arrent", "amusively", "preincorporation", - "Montargis", "pentacron", "neomedievalism", - "sima", "lichenicolous", "Ecclesiastes", - "woofed", "cardinalist", "sandaracin", - "gymnasial", "lithoglyptics", "centimeter", - "quadrupedous", "phraseology", "tumuli", - "ankylotomy", "myrtol", "cohibitive", - "lepospondylous", "silvendy", "inequipotential", - "entangle", "raveling", "Zeugobranchiata", - "devastating", "grainage", "amphisbaenian", - "blady", "cirrose", "proclericalism", - "governmentalist", "carcinomorphic", "nurtureship", - "clancular", "unsteamed", "discernibly", - "pleurogenic", "impalpability", "Azotobacterieae", - "sarcoplasmic", "alternant", "fitly", - "acrorrheuma", "shrapnel", "pastorize", - "gulflike", "foreglow", "unrelated", - "cirriped", "cerviconasal", "sexuale", - "pussyfooter", "gadolinic", "duplicature", - "codelinquency", "trypanolysis", "pathophobia", - "incapsulation", "nonaerating", "feldspar", - "diaphonic", "epiglottic", "depopulator", - "wisecracker", "gravitational", "kuba", - "lactesce", "Toxotes", "periomphalic", - "singstress", "fannier", "counterformula", - "Acemetae", "repugnatorial", "collimator", - "Acinetina", "unpeace", "drum", - "tetramorphic", "descendentalism", "cementer", - "supraloral", "intercostal", "Nipponize", - "negotiator", "vacationless", "synthol", - "fissureless", "resoap", "pachycarpous", - "reinspiration", "misappropriation", "disdiazo", - "unheatable", "streng", "Detroiter", - "infandous", "loganiaceous", "desugar", - "Matronalia", "myxocystoma", "Gandhiism", - "kiddier", "relodge", "counterreprisal", - "recentralize", "foliously", "reprinter", - "gender", "edaciousness", "chondriomite", - "concordant", "stockrider", "pedary", - "shikra", "blameworthiness", "vaccina", - "Thamnophilinae", "wrongwise", "unsuperannuated", - "convalescency", "intransmutable", "dropcloth", - "Ceriomyces", "ponderal", "unstentorian", - "mem", "deceleration", "ethionic", - "untopped", "wetback", "bebar", - "undecaying", "shoreside", "energize", - "presacral", "undismay", "agricolite", - "cowheart", "hemibathybian", "postexilian", - "Phacidiaceae", "offing", "redesignation", - "skeptically", "physicianless", "bronchopathy", - "marabuto", "proprietory", "unobtruded", - "funmaker", "plateresque", "preadventure", - "beseeching", "cowpath", "pachycephalia", - "arthresthesia", "supari", "lengthily", - "Nepa", "liberation", "nigrify", - "belfry", "entoolitic", "bazoo", - "pentachromic", "distinguishable", "slideable", - "galvanoscope", "remanage", "cetene", - "bocardo", "consummation", "boycottism", - "perplexity", "astay", "Gaetuli", - "periplastic", "consolidator", "sluggarding", - "coracoscapular", "anangioid", "oxygenizer", - "Hunanese", "seminary", "periplast", - "Corylus", "unoriginativeness", "persecutee", - "tweaker", "silliness", "Dabitis", - "facetiousness", "thymy", "nonimperial", - "mesoblastema", "turbiniform", "churchway", - "cooing", "frithbot", "concomitantly", - "stalwartize", "clingfish", "hardmouthed", - "parallelepipedonal", "coracoacromial", "factuality", - "curtilage", "arachnoidean", "semiaridity", - "phytobacteriology", "premastery", "hyperpurist", - "mobed", "opportunistic", "acclimature", - "outdistance", "sophister", "condonement", - "oxygenerator", "acetonic", "emanatory", - "periphlebitis", "nonsociety", "spectroradiometric", - "superaverage", "cleanness", "posteroventral", - "unadvised", "unmistakedly", "pimgenet", - "auresca", "overimitate", "dipnoan", - "chromoxylograph", "triakistetrahedron", "Suessiones", - "uncopiable", "oligomenorrhea", "fribbling", - "worriable", "flot", "ornithotrophy", - "phytoteratology", "setup", "lanneret", - "unbraceleted", "gudemother", "Spica", - "unconsolatory", "recorruption", "premenstrual", - "subretinal", "millennialist", "subjectibility", - "rewardproof", "counterflight", "pilomotor", - "carpetbaggery", "macrodiagonal", "slim", - "indiscernible", "cuckoo", "moted", - "controllingly", "gynecopathy", "porrectus", - "wanworth", "lutfisk", "semiprivate", - "philadelphy", "abdominothoracic", "coxcomb", - "dambrod", "Metanemertini", "balminess", - "homotypy", "waremaker", "absurdity", - "gimcrack", "asquat", "suitable", - "perimorphous", "kitchenwards", "pielum", - "salloo", "paleontologic", "Olson", - "Tellinidae", "ferryman", "peptonoid", - "Bopyridae", "fallacy", "ictuate", - "aguinaldo", "rhyodacite", "Ligydidae", - "galvanometric", "acquisitor", "muscology", - "hemikaryon", "ethnobotanic", "postganglionic", - "rudimentarily", "replenish", "phyllorhine", - "popgunnery", "summar", "quodlibetary", - "xanthochromia", "autosymbolically", "preloreal", - "extent", "strawberry", "immortalness", - "colicwort", "frisca", "electiveness", - "heartbroken", "affrightingly", "reconfiscation", - "jacchus", "imponderably", "semantics", - "beennut", "paleometeorological", "becost", - "timberwright", "resuppose", "syncategorematical", - "cytolymph", "steinbok", "explantation", - "hyperelliptic", "antescript", "blowdown", - "antinomical", "caravanserai", "unweariedly", - "isonymic", "keratoplasty", "vipery", - "parepigastric", "endolymphatic", "Londonese", - "necrotomy", "angelship", "Schizogregarinida", - "steeplebush", "sparaxis", "connectedness", - "tolerance", "impingent", "agglutinin", - "reviver", "hieroglyphical", "dialogize", - "coestate", "declamatory", "ventilation", - "tauromachy", "cotransubstantiate", "pome", - "underseas", "triquadrantal", "preconfinemnt", - "electroindustrial", "selachostomous", "nongolfer", - "mesalike", "hamartiology", "ganglioblast", - "unsuccessive", "yallow", "bacchanalianly", - "platydactyl", "Bucephala", "ultraurgent", - "penalist", "catamenial", "lynnhaven", - "unrelevant", "lunkhead", "metropolitan", - "hydro", "outsoar", "vernant", - "interlanguage", "catarrhal", "Ionicize", - "keelless", "myomantic", "booker", - "Xanthomonas", "unimpeded", "overfeminize", - "speronaro", "diaconia", "overholiness", - "liquefacient", "Spartium", "haggly", - "albumose", "nonnecessary", "sulcalization", - "decapitate", "cellated", "unguirostral", - "trichiurid", "loveproof", "amakebe", - "screet", "arsenoferratin", "unfrizz", - "undiscoverable", "procollectivistic", "tractile", - "Winona", "dermostosis", "eliminant", - "scomberoid", "tensile", "typesetting", - "xylic", "dermatopathology", "cycloplegic", - "revocable", "fissate", "afterplay", - "screwship", "microerg", "bentonite", - "stagecoaching", "beglerbeglic", "overcharitably", - "Plotinism", "Veddoid", "disequalize", - "cytoproct", "trophophore", "antidote", - "allerion", "famous", "convey", - "postotic", "rapillo", "cilectomy", - "penkeeper", "patronym", "bravely", - "ureteropyelitis", "Hildebrandine", "missileproof", - "Conularia", "deadening", "Conrad", - "pseudochylous", "typologically", "strummer", - "luxuriousness", "resublimation", "glossiness", - "hydrocauline", "anaglyph", "personifiable", - "seniority", "formulator", "datiscaceous", - "hydracrylate", "Tyranni", "Crawthumper", - "overprove", "masher", "dissonance", - "Serpentinian", "malachite", "interestless", - "stchi", "ogum", "polyspermic", - "archegoniate", "precogitation", "Alkaphrah", - "craggily", "delightfulness", "bioplast", - "diplocaulescent", "neverland", "interspheral", - "chlorhydric", "forsakenly", "scandium", - "detubation", "telega", "Valeriana", - "centraxonial", "anabolite", "neger", - "miscellanea", "whalebacker", "stylidiaceous", - "unpropelled", "Kennedya", "Jacksonite", - "ghoulish", "Dendrocalamus", "paynimhood", - "rappist", "unluffed", "falling", - "Lyctus", "uncrown", "warmly", - "pneumatism", "Morisonian", "notate", - "isoagglutinin", "Pelidnota", "previsit", - "contradistinctly", "utter", "porometer", - "gie", "germanization", "betwixt", - "prenephritic", "underpier", "Eleutheria", - "ruthenious", "convertor", "antisepsin", - "winterage", "tetramethylammonium", "Rockaway", - "Penaea", "prelatehood", "brisket", - "unwishful", "Minahassa", "Briareus", - "semiaxis", "disintegrant", "peastick", - "iatromechanical", "fastus", "thymectomy", - "ladyless", "unpreened", "overflutter", - "sicker", "apsidally", "thiazine", - "guideway", "pausation", "tellinoid", - "abrogative", "foraminulate", "omphalos", - "Monorhina", "polymyarian", "unhelpful", - "newslessness", "oryctognosy", "octoradial", - "doxology", "arrhythmy", "gugal", - "mesityl", "hexaplaric", "Cabirian", - "hordeiform", "eddyroot", "internarial", - "deservingness", "jawbation", "orographically", - "semiprecious", "seasick", "thermically", - "grew", "tamability", "egotistically", - "fip", "preabsorbent", "leptochroa", - "ethnobotany", "podolite", "egoistic", - "semitropical", "cero", "spinelessness", - "onshore", "omlah", "tintinnabulist", - "machila", "entomotomy", "nubile", - "nonscholastic", "burnt", "Alea", - "befume", "doctorless", "Napoleonic", - "scenting", "apokreos", "cresylene", - "paramide", "rattery", "disinterested", - "idiopathetic", "negatory", "fervid", - "quintato", "untricked", "Metrosideros", - "mescaline", "midverse", "Musophagidae", - "fictionary", "branchiostegous", "yoker", - "residuum", "culmigenous", "fleam", - "suffragism", "Anacreon", "sarcodous", - "parodistic", "writmaking", "conversationism", - "retroposed", "tornillo", "presuspect", - "didymous", "Saumur", "spicing", - "drawbridge", "cantor", "incumbrancer", - "heterospory", "Turkeydom", "anteprandial", - "neighbourship", "thatchless", "drepanoid", - "lusher", "paling", "ecthlipsis", - "heredosyphilitic", "although", "garetta", - "temporarily", "Monotropa", "proglottic", - "calyptro", "persiflage", "degradable", - "paraspecific", "undecorative", "Pholas", - "myelon", "resteal", "quadrantly", - "scrimped", "airer", "deviless", - "caliciform", "Sefekhet", "shastaite", - "togate", "macrostructure", "bipyramid", - "wey", "didynamy", "knacker", - "swage", "supermanism", "epitheton", - "overpresumptuous", 0 -}; - -// Notice that we copy the data below: -void copy_and_sort(std::vector data) { - std::sort(data.begin(), data.end()); -} - -int main() { - // Init the data. - std::vector string_array; - int i = 0; - while (data[i]) { - string_array.push_back(data[i]); - i++; - } - - printf("benchSortString:\n"); - uint64_t count = 0; - uint64_t start = mach_absolute_time(); - for (int i = 0; i < LAPS; i++) { - copy_and_sort(string_array); - } - uint64_t delta = mach_absolute_time() - start; - printf("%f nanoseconds\n", (double)delta); - printf("%f ns/lap\n", (double)delta / (double)LAPS); - return 0; -} diff --git a/utils/benchmark/Strings/StringComplexWalk.swift b/utils/benchmark/Strings/StringComplexWalk.swift deleted file mode 100644 index 79370c6bed0f5..0000000000000 --- a/utils/benchmark/Strings/StringComplexWalk.swift +++ /dev/null @@ -1 +0,0 @@ -benchStringComplexWalk() diff --git a/utils/benchmark/Strings/StringWalk.swift b/utils/benchmark/Strings/StringWalk.swift deleted file mode 100644 index 1f937344cbcb0..0000000000000 --- a/utils/benchmark/Strings/StringWalk.swift +++ /dev/null @@ -1 +0,0 @@ -benchStringWalk() diff --git a/utils/benchmark/build.sh b/utils/benchmark/build.sh deleted file mode 100755 index 809c9b29c2a27..0000000000000 --- a/utils/benchmark/build.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash - -if [[ -n "$LLVM_DIR" ]]; then - BUILD_DIR="$LLVM_DIR/build" -fi - -if [[ -z "$BUILD_DIR" ]]; then - echo "Error! BUILD_DIR not set! Don't know how to find swift binary." - exit 1 -fi - -SWIFT="$BUILD_DIR/bin/swift" -CLANG="$BUILD_DIR/bin/clang" -CLANGPP="$BUILD_DIR/bin/clang++" -SDKROOT=$(xcrun --show-sdk-path -sdk macosx) || exit 1 - -benchmark() { - local NAME=$1 - - echo "Compiling swift/cpp for benchmark $NAME" - - set -e - set -x - - # Remove old object files/binaries. - rm -rfv $NAME.*.o $NAME.*_bin - - # Compile swift benchmark. - $SWIFT -O $NAME.swift -o $NAME.swift.o -c - $CLANG $NAME.swift.o -o $NAME.swift_bin -Wl,-rpath -Wl,"$BUILD_DIR/lib/swift/macosx" -L "$BUILD_DIR/lib/swift/macosx" - - # Compile CXX benchmark. - $CLANGPP -O3 -c $NAME.cpp -o $NAME.cpp.o -isysroot "$SDKROOT" $CFLAGS $CXXFLAGS -DLOG=0 - $CLANGPP -O3 $NAME.cpp.o -o $NAME.cpp_bin -isysroot "$SDKROOT" $CFLAGS $CXXFLAGS - - # Run swift benchmark. - ./$NAME.swift_bin - - # Compile CXX benchmark - ./$NAME.cpp_bin - - set +x - set +e -} - -(cd RC4 && benchmark RC4) -(cd ObjInst && benchmark ObjInst) -(cd Ackermann && benchmark Ackermann) diff --git a/utils/build-presets.ini b/utils/build-presets.ini index 412a159aef100..e73b681ec04b5 100644 --- a/utils/build-presets.ini +++ b/utils/build-presets.ini @@ -2,7 +2,7 @@ # ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information @@ -52,52 +52,6 @@ installable-package=%(installable_package)s # If someone uses this for incremental builds, force reconfiguration. reconfigure - -[preset: buildbot,tools=RA,stdlib=DA] -mixin-preset= - mixin_buildbot_trunk_base - mixin_buildbot_install_components - -# Build Release without debug info, because it is faster to build. -release -assertions - -dash-dash - -swift-stdlib-build-type=Debug -swift-stdlib-enable-assertions=true - -[preset: buildbot,tools=RA,stdlib=RD] -mixin-preset= - mixin_buildbot_trunk_base - mixin_buildbot_install_components - -# Build Release without debug info, because it is faster to build. -release -assertions - -dash-dash - -swift-stdlib-build-type=RelWithDebInfo -swift-stdlib-enable-assertions=false - -[preset: buildbot,tools=RA,stdlib=RDA] -mixin-preset= - mixin_buildbot_trunk_base - mixin_buildbot_install_components - -# Build Release without debug info, because it is faster to build. -release -assertions - -dash-dash - -swift-stdlib-build-type=RelWithDebInfo -swift-stdlib-enable-assertions=true - -# This is a release non-incremental build. Run sil-verify-all. -sil-verify-all - [preset: buildbot,tools=RA,stdlib=RD,test=no] mixin-preset= mixin_buildbot_trunk_base @@ -463,6 +417,7 @@ swift-runtime-enable-leak-checker=1 # compiler significantly. [preset: mixin_lightweight_assertions] assertions +no-swift-stdlib-assertions # FIXME: This should be: # no-assertions @@ -491,12 +446,12 @@ install-llbuild install-swiftpm install-xctest install-prefix=/usr -swift-install-components=compiler;clang-builtin-headers;stdlib;sdk-overlay;dev +swift-install-components=compiler;clang-builtin-headers;stdlib;sdk-overlay;license build-swift-static-stdlib=1 skip-test-lldb=1 # Executes the lit tests for the installable package that is created -# Assumes the swift-package-tests repo is checked out +# Assumes the swift-integration-tests repo is checked out test-installable-package=1 # Path to the root of the installation filesystem. @@ -505,8 +460,7 @@ install-destdir=%(install_destdir)s # Path to the .tar.gz package we would create. installable-package=%(installable_package)s -# This preset builds foundation -[preset: buildbot_linux_1510] +[preset: buildbot_linux] mixin-preset=mixin_linux_installation build-subdir=buildbot_linux lldb @@ -520,20 +474,13 @@ dash-dash install-foundation reconfigure -# This preset does not build Foundation due to unavailable ICU versions on Ubuntu 14.04 -[preset: buildbot_linux_1404] -mixin-preset=mixin_linux_installation -build-subdir=buildbot_linux -lldb -release -test -validation-test -foundation - -dash-dash +# Ubuntu 15.10 preset for backwards compat and future customizations. +[preset: buildbot_linux_1510] +mixin-preset=buildbot_linux -install-foundation -reconfigure +# Ubuntu 14.04 preset for backwards compat and future customizations. +[preset: buildbot_linux_1404] +mixin-preset=buildbot_linux #===------------------------------------------------------------------------===# # OS X Package Builders @@ -578,8 +525,8 @@ install-symroot=%(install_symroot)s install-prefix=%(install_toolchain_dir)s/usr # Executes the lit tests for the installable package that is created -# Assumes the swift-package-tests repo is checked out -# test-installable-package=0 +# Assumes the swift-integration-tests repo is checked out +test-installable-package=1 # If someone uses this for incremental builds, force reconfiguration. reconfigure @@ -608,7 +555,7 @@ mixin-preset= dash-dash -swift-install-components=compiler;clang-builtin-headers;stdlib;sdk-overlay;sourcekit-xpc-service +swift-install-components=compiler;clang-builtin-headers;stdlib;sdk-overlay;license;sourcekit-xpc-service llvm-install-components=libclang;clang-headers # Path to the .tar.gz package we would create. @@ -617,8 +564,37 @@ installable-package=%(installable_package)s # Path to the .tar.gz symbols package symbols-package=%(symbols_package)s -# Info.plist +# Info.plist darwin-toolchain-bundle-identifier=%(darwin_toolchain_bundle_identifier)s darwin-toolchain-display-name=%(darwin_toolchain_display_name)s darwin-toolchain-name=%(darwin_toolchain_xctoolchain_name)s darwin-toolchain-version=%(darwin_toolchain_version)s + +#===------------------------------------------------------------------------===# +# LLDB build configurations +# +# Use to build the compiler sources nested in LLDB. +# +# This is only used from Xcode, and expects the following configuration: +## an argument, swift_install_destdir=[path for Swift installed products] +## an environment variable, SWIFT_SOURCE_ROOT=[parent of swift/] +## an environment variable, SWIFT_BUILD_ROOT=[parent of Swift build directory] +#===------------------------------------------------------------------------===# + +[preset: LLDB_Nested] +dash-dash +build-swift-perf-testsuite=0 +install-destdir=%(swift_install_destdir)s + +[preset: LLDB_Swift_DebugAssert] +mixin-preset= + LLDB_Nested + +assertions + +[preset: LLDB_Swift_ReleaseAssert] +mixin-preset= + LLDB_Nested + +release-debuginfo +assertions diff --git a/utils/build-script b/utils/build-script index 839edd76f1c71..83f0d006011c7 100755 --- a/utils/build-script +++ b/utils/build-script @@ -1,27 +1,43 @@ #!/usr/bin/env python -#===--- build-script - The ultimate tool for building Swift ----------------===# +# utils/build-script - The ultimate tool for building Swift -*- python -*- # -## This source file is part of the Swift.org open source project -## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors -## Licensed under Apache License v2.0 with Runtime Library Exception -## -## See http://swift.org/LICENSE.txt for license information -## See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# This source file is part of the Swift.org open source project # -#===------------------------------------------------------------------------===# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors from __future__ import print_function import argparse +import multiprocessing import os import shutil import sys import textwrap +# FIXME: Instead of modifying the system path in order to enable imports from +# other directories, all Python modules related to the build script +# should be moved to the `swift_build_support` module. +# For additional information, see: https://bugs.swift.org/browse/SR-237. sys.path.append(os.path.dirname(__file__)) - -from SwiftBuildSupport import * +from SwiftBuildSupport import ( + HOME, + SWIFT_BUILD_ROOT, + SWIFT_SOURCE_ROOT, + check_call, + get_all_preset_names, + get_preset_options, + print_with_argv0, + quote_shell_command, +) + +sys.path.append(os.path.join(os.path.dirname(__file__), 'swift_build_support')) +import swift_build_support.clang +import swift_build_support.cmake +from swift_build_support.migration import migrate_impl_args # Main entry point for the preset mode. @@ -193,7 +209,7 @@ To build a debuggable Swift standard library: [~/src/s]$ ./swift/utils/build-script -R --debug-swift-stdlib -iOS build targets are always configured and present, but are not build by +iOS build targets are always configured and present, but are not built by default. To build the standard library for OS X, iOS simulator and iOS device: [~/src/s]$ ./swift/utils/build-script -R -i @@ -295,10 +311,13 @@ details of the setups of other systems or automated environments.""") dest="build_foundation") extra_actions_group = parser.add_argument_group( - title="Extra actions to perform before building") + title="Extra actions to perform before or in addition to building") extra_actions_group.add_argument("-c", "--clean", help="do a clean build", action="store_true") + extra_actions_group.add_argument("--export-compile-commands", + help="generate compilation databases in addition to building", + action="store_true") build_variant_group = parser.add_mutually_exclusive_group(required=False) build_variant_group.add_argument("-d", "--debug", @@ -477,17 +496,35 @@ also build for Apple watchos, but disallow tests that require an watchOS device" name of the directory under $SWIFT_BUILD_ROOT where the build products will be placed""", metavar="PATH") + + parser.add_argument("-j", "--jobs", + help=""" +the number of parallel build jobs to use""", + type=int, + dest="build_jobs", + default=multiprocessing.cpu_count()) + + parser.add_argument("--darwin-xcrun-toolchain", + help="the name of the toolchain to use on Darwin", + default="default") + parser.add_argument("--cmake", + help="the path to a CMake executable that will be " + "used to build Swift") + parser.add_argument("--extra-swift-args", help=textwrap.dedent(""" Pass through extra flags to swift in the form of a cmake list 'module_regexp;flag'. Can be called multiple times to add multiple such module_regexp flag pairs. All semicolons - in flags must be scaped with a '\'"""), + in flags must be escaped with a '\'"""), action="append", dest="extra_swift_args", default=[]) parser.add_argument("build_script_impl_args", help="", nargs="*") - args = parser.parse_args() + args = parser.parse_args(migrate_impl_args(sys.argv[1:], [ + '--darwin-xcrun-toolchain', + '--cmake', + ])) # Build cmark if any cmark-related options were specified. if (args.cmark_build_variant is not None): @@ -552,6 +589,11 @@ placed""", build_script_impl_inferred_args = [] + if args.export_compile_commands: + build_script_impl_inferred_args += [ + "--export-compile-commands" + ] + if args.cmake_generator == "XcodeIDEOnly": args.cmake_generator = "Xcode" build_script_impl_inferred_args += [ @@ -604,27 +646,6 @@ placed""", build_script_impl_inferred_args += [ "--skip-build-lldb" ] - else: - import platform - if platform.system() == "Darwin": - # Validate the LLDB build variant, exiting the - # build if it is not supported. - supported_variants = [ - "Debug", - "Release" - ] - if args.lldb_build_variant is not None: - lldb_build_variant = args.lldb_build_variant - else: - lldb_build_variant = args.build_variant - if lldb_build_variant not in supported_variants: - sys.stderr.write( - "The Swift LLDB build does not support build variant %s\n" - % lldb_build_variant) - sys.stderr.write( - "Please select one of the following variants: %s\n" % - ", ".join(supported_variants)) - sys.exit(1) if not args.build_llbuild: build_script_impl_inferred_args += [ @@ -707,9 +728,27 @@ placed""", if args.clean: shutil.rmtree(build_dir) + host_clang = swift_build_support.clang.host_clang( + xcrun_toolchain=args.darwin_xcrun_toolchain) + if not host_clang: + print_with_argv0( + "Can't find clang. Please install clang-3.5 or a later version.") + return 1 + + host_cmake = args.cmake + if not host_cmake: + host_cmake = swift_build_support.cmake.host_cmake( + args.darwin_xcrun_toolchain) + if not host_cmake: + print_with_argv0("Can't find CMake. Please install CMake.") + return 1 build_script_impl_args = [ os.path.join(SWIFT_SOURCE_ROOT, "swift", "utils", "build-script-impl"), "--build-dir", build_dir, + "--host-cc", host_clang.cc, + "--host-cxx", host_clang.cxx, + "--darwin-xcrun-toolchain", args.darwin_xcrun_toolchain, + "--cmake", host_cmake, "--cmark-build-type", args.cmark_build_variant, "--llvm-build-type", args.llvm_build_variant, "--swift-build-type", args.swift_build_variant, @@ -719,6 +758,7 @@ placed""", "--swift-enable-assertions", str(args.swift_assertions).lower(), "--swift-stdlib-enable-assertions", str(args.swift_stdlib_assertions).lower(), "--cmake-generator", args.cmake_generator, + "--build-jobs", str(args.build_jobs), "--workspace", SWIFT_SOURCE_ROOT ] if args.build_foundation: diff --git a/utils/build-script-impl b/utils/build-script-impl index c6e8e6fd1cd19..dfd63023c4ade 100755 --- a/utils/build-script-impl +++ b/utils/build-script-impl @@ -3,7 +3,7 @@ # ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information @@ -51,12 +51,14 @@ LLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" # components). # # Each variable name is re-exported into this script in uppercase, where dashes -# are substituded by underscores. For example, `swift-install-components` is +# are substituted by underscores. For example, `swift-install-components` is # referred to as `SWIFT_INSTALL_COMPONENTS` in the remainder of this script. KNOWN_SETTINGS=( # name default description build-args "" "arguments to the build tool; defaults to -j8 when CMake generator is \"Unix Makefiles\"" build-dir "" "out-of-tree build directory; default is in-tree. **This argument is required**" + host-cc "" "the path to CC, the 'clang' compiler for the host platform. **This argument is required**" + host-cxx "" "the path to CXX, the 'clang++' compiler for the host platform. **This argument is required**" darwin-xcrun-toolchain "default" "the name of the toolchain to use on Darwin" build-ninja "" "build the Ninja tool" cmark-build-type "Debug" "the CMake build variant for CommonMark (Debug, RelWithDebInfo, Release, MinSizeRel). Defaults to Debug." @@ -111,10 +113,10 @@ KNOWN_SETTINGS=( skip-build-watchos-device "" "set to skip building Swift stdlibs for Apple watchOS devices (i.e. build simulators only)" skip-build-watchos-simulator "" "set to skip building Swift stdlibs for Apple watchOS simulators (i.e. build devices only)" skip-build-lldb "" "set to skip building LLDB" - skip-build-llbuild "" "set to skip buildling llbuild" - skip-build-swiftpm "" "set to skip buildling swiftpm" - skip-build-xctest "" "set to skip buildling xctest" - skip-build-foundation "" "set to skip buildling foundation" + skip-build-llbuild "" "set to skip building llbuild" + skip-build-swiftpm "" "set to skip building swiftpm" + skip-build-xctest "" "set to skip building xctest" + skip-build-foundation "" "set to skip building foundation" skip-test-cmark "" "set to skip testing CommonMark" skip-test-lldb "" "set to skip testing lldb" skip-test-swift "" "set to skip testing Swift" @@ -147,6 +149,8 @@ KNOWN_SETTINGS=( native-clang-tools-path "" "directory that contains Clang tools that are executable on the build machine" native-swift-tools-path "" "directory that contains Swift tools that are executable on the build machine" compiler-vendor "none" "compiler vendor name [none,apple]" + clang-user-visible-version "3.8.0" "user-visible version of the embedded Clang and LLVM compilers" + swift-user-visible-version "2.2" "user-visible version of the Swift language" swift-compiler-version "" "string that indicates a compiler version for Swift" clang-compiler-version "" "string that indicates a compiler version for Clang" embed-bitcode-section "0" "embed an LLVM bitcode section in stdlib/overlay binaries for supported platforms" @@ -183,7 +187,9 @@ KNOWN_SETTINGS=( darwin-toolchain-application-cert "" "Application Cert name to codesign xctoolchain" darwin-toolchain-installer-cert "" "Installer Cert name to create installer pkg" darwin-toolchain-installer-package "" "The path to installer pkg" - + build-jobs "" "The number of parallel build jobs to use" + darwin-toolchain-alias "swift" "Swift alias for toolchain" + export-compile-commands "" "set to generate JSON compilation databases for each build product" ) function toupper() { @@ -194,26 +200,6 @@ function to_varname() { toupper "${1//-/_}" } -function get_make_parallelism() { - case "$(uname -s)" in - Linux) - nproc - ;; - - Darwin) - sysctl -n hw.activecpu - ;; - - *) - echo 8 - ;; - esac -} - -function get_dsymutil_parallelism() { - get_make_parallelism -} - function set_lldb_build_mode() { LLDB_BUILD_MODE="CustomSwift-${LLDB_BUILD_TYPE}" } @@ -224,10 +210,16 @@ function set_deployment_target_based_options() { cmark_cmake_options=() swiftpm_bootstrap_options=() - case $deployment_target in + case ${deployment_target} in linux-x86_64) SWIFT_HOST_VARIANT_ARCH="x86_64" ;; + linux-armv7) + SWIFT_HOST_VARIANT_ARCH="armv7" + ;; + linux-aarch64) + SWIFT_HOST_VARIANT_ARCH="aarch64" + ;; freebsd-x86_64) SWIFT_HOST_VARIANT_ARCH="x86_64" ;; @@ -241,13 +233,13 @@ function set_deployment_target_based_options() { llvm_target_arch="" cmake_osx_deployment_target="${DARWIN_DEPLOYMENT_VERSION_OSX}" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" -DCMAKE_OSX_DEPLOYMENT_TARGET="${cmake_osx_deployment_target}" ) swiftpm_bootstrap_options=( - --sysroot="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + --sysroot="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) ;; iphonesimulator-i386) @@ -256,9 +248,9 @@ function set_deployment_target_based_options() { llvm_target_arch="X86" cmake_osx_deployment_target="" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) swift_cmake_options=( -DSWIFT_HOST_VARIANT="iphonesimulator" @@ -272,9 +264,9 @@ function set_deployment_target_based_options() { llvm_target_arch="X86" cmake_osx_deployment_target="" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) swift_cmake_options=( -DSWIFT_HOST_VARIANT="iphonesimulator" @@ -288,9 +280,9 @@ function set_deployment_target_based_options() { llvm_target_arch="ARM" cmake_osx_deployment_target="" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) swift_cmake_options=( -DSWIFT_HOST_VARIANT="iphoneos" @@ -304,9 +296,9 @@ function set_deployment_target_based_options() { llvm_target_arch="AArch64" cmake_osx_deployment_target="" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) swift_cmake_options=( -DSWIFT_HOST_VARIANT="iphoneos" @@ -320,9 +312,9 @@ function set_deployment_target_based_options() { llvm_target_arch="X86" cmake_osx_deployment_target="" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) swift_cmake_options=( -DSWIFT_HOST_VARIANT="appletvsimulator" @@ -336,9 +328,9 @@ function set_deployment_target_based_options() { llvm_target_arch="AArch64" cmake_osx_deployment_target="" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) swift_cmake_options=( -DSWIFT_HOST_VARIANT="appletvos" @@ -352,9 +344,9 @@ function set_deployment_target_based_options() { llvm_target_arch="X86" cmake_osx_deployment_target="" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) swift_cmake_options=( -DSWIFT_HOST_VARIANT="watchsimulator" @@ -368,9 +360,9 @@ function set_deployment_target_based_options() { llvm_target_arch="ARM" cmake_osx_deployment_target="" cmark_cmake_options=( - -DCMAKE_C_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(cmark_c_flags $deployment_target)" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_C_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(cmark_c_flags ${deployment_target})" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" ) swift_cmake_options=( -DSWIFT_HOST_VARIANT="watchos" @@ -384,10 +376,9 @@ function set_deployment_target_based_options() { ;; esac - native_llvm_build=$(build_directory macosx-x86_64 llvm) llvm_cmake_options=( -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING="${cmake_osx_deployment_target}" - -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk $xcrun_sdk_name --show-sdk-path)" + -DCMAKE_OSX_SYSROOT:PATH="$(xcrun --sdk ${xcrun_sdk_name} --show-sdk-path)" -DLLVM_HOST_TRIPLE:STRING="${llvm_host_triple}" ) swift_cmake_options=( @@ -440,7 +431,7 @@ function set_deployment_target_based_options() { ;; *) - echo "Unknown compiler deployment target: $deployment_target" + echo "Unknown compiler deployment target: ${deployment_target}" exit 1 ;; esac @@ -560,7 +551,7 @@ while [[ "$1" ]] ; do shift done -if [[ "$SKIP_BUILD" ]]; then +if [[ "${SKIP_BUILD}" ]]; then SKIP_BUILD_CMARK=1 SKIP_BUILD_LLVM=1 SKIP_BUILD_SWIFT=1 @@ -581,7 +572,7 @@ if [[ "$SKIP_BUILD" ]]; then SKIP_BUILD_FOUNDATION=1 fi -if [[ "$SKIP_IOS" ]] ; then +if [[ "${SKIP_IOS}" ]] ; then SKIP_BUILD_IOS=1 SKIP_BUILD_IOS_DEVICE=1 SKIP_BUILD_IOS_SIMULATOR=1 @@ -589,7 +580,7 @@ if [[ "$SKIP_IOS" ]] ; then SKIP_TEST_IOS_SIMULATOR=1 fi -if [[ "$SKIP_TVOS" ]] ; then +if [[ "${SKIP_TVOS}" ]] ; then SKIP_BUILD_TVOS=1 SKIP_BUILD_TVOS_DEVICE=1 SKIP_BUILD_TVOS_SIMULATOR=1 @@ -597,7 +588,7 @@ if [[ "$SKIP_TVOS" ]] ; then SKIP_TEST_TVOS_SIMULATOR=1 fi -if [[ "$SKIP_WATCHOS" ]] ; then +if [[ "${SKIP_WATCHOS}" ]] ; then SKIP_BUILD_WATCHOS=1 SKIP_BUILD_WATCHOS_DEVICE=1 SKIP_BUILD_WATCHOS_SIMULATOR=1 @@ -605,7 +596,7 @@ if [[ "$SKIP_WATCHOS" ]] ; then SKIP_TEST_WATCHOS_SIMULATOR=1 fi -if [[ "$SKIP_BUILD_IOS" ]] ; then +if [[ "${SKIP_BUILD_IOS}" ]] ; then SKIP_BUILD_IOS=1 SKIP_BUILD_IOS_DEVICE=1 SKIP_BUILD_IOS_SIMULATOR=1 @@ -613,7 +604,7 @@ if [[ "$SKIP_BUILD_IOS" ]] ; then SKIP_TEST_IOS_SIMULATOR=1 fi -if [[ "$SKIP_BUILD_TVOS" ]] ; then +if [[ "${SKIP_BUILD_TVOS}" ]] ; then SKIP_BUILD_TVOS=1 SKIP_BUILD_TVOS_DEVICE=1 SKIP_BUILD_TVOS_SIMULATOR=1 @@ -621,7 +612,7 @@ if [[ "$SKIP_BUILD_TVOS" ]] ; then SKIP_TEST_TVOS_SIMULATOR=1 fi -if [[ "$SKIP_BUILD_WATCHOS" ]] ; then +if [[ "${SKIP_BUILD_WATCHOS}" ]] ; then SKIP_BUILD_WATCHOS=1 SKIP_BUILD_WATCHOS_DEVICE=1 SKIP_BUILD_WATCHOS_SIMULATOR=1 @@ -629,46 +620,48 @@ if [[ "$SKIP_BUILD_WATCHOS" ]] ; then SKIP_TEST_WATCHOS_SIMULATOR=1 fi -if [[ "$SKIP_BUILD_IOS_DEVICE" ]] ; then +if [[ "${SKIP_BUILD_IOS_DEVICE}" ]] ; then SKIP_BUILD_IOS_DEVICE=1 fi -if [[ "$SKIP_BUILD_TVOS_DEVICE" ]] ; then +if [[ "${SKIP_BUILD_TVOS_DEVICE}" ]] ; then SKIP_BUILD_TVOS_DEVICE=1 fi -if [[ "$SKIP_BUILD_WATCHOS_DEVICE" ]] ; then +if [[ "${SKIP_BUILD_WATCHOS_DEVICE}" ]] ; then SKIP_BUILD_WATCHOS_DEVICE=1 fi -if [[ "$SKIP_BUILD_IOS_SIMULATOR" ]] ; then +if [[ "${SKIP_BUILD_IOS_SIMULATOR}" ]] ; then SKIP_BUILD_IOS_SIMULATOR=1 SKIP_TEST_IOS_SIMULATOR=1 fi -if [[ "$SKIP_BUILD_TVOS_SIMULATOR" ]] ; then +if [[ "${SKIP_BUILD_TVOS_SIMULATOR}" ]] ; then SKIP_BUILD_TVOS_SIMULATOR=1 SKIP_TEST_TVOS_SIMULATOR=1 fi -if [[ "$SKIP_BUILD_WATCHOS_SIMULATOR" ]] ; then +if [[ "${SKIP_BUILD_WATCHOS_SIMULATOR}" ]] ; then SKIP_BUILD_WATCHOS_SIMULATOR=1 SKIP_TEST_WATCHOS_SIMULATOR=1 fi -if [[ "$SKIP_TEST_IOS" ]] ; then +if [[ "${SKIP_TEST_IOS}" ]] ; then SKIP_TEST_IOS_SIMULATOR=1 fi -if [[ "$SKIP_TEST_TVOS" ]] ; then +if [[ "${SKIP_TEST_TVOS}" ]] ; then SKIP_TEST_TVOS_SIMULATOR=1 fi -if [[ "$SKIP_TEST_WATCHOS" ]] ; then +if [[ "${SKIP_TEST_WATCHOS}" ]] ; then SKIP_TEST_WATCHOS_SIMULATOR=1 fi -if [[ "${CMAKE_GENERATOR}" == "Ninja" ]] && [[ -z "$(which ninja)" ]] ; then +if [[ "${CMAKE_GENERATOR}" == "Ninja" && \ + -z "$(which ninja 2>/dev/null)" && + -z "$(which ninja-build 2>/dev/null)" ]] ; then BUILD_NINJA=1 fi @@ -710,8 +703,21 @@ case "${SYMBOLS_PACKAGE}" in esac # WORKSPACE must exist -if [ ! -e "$WORKSPACE" ] ; then - echo "Workspace does not exist (tried $WORKSPACE)" +if [ ! -e "${WORKSPACE}" ] ; then + echo "Workspace does not exist (tried ${WORKSPACE})" + exit 1 +fi + +# FIXME: HOST_CC and CMAKE are set, and their presence is validated by, +# utils/build-script. These checks are redundant, but must remain until +# build-script-impl is merged completely with utils/build-script. +# For additional information, see: https://bugs.swift.org/browse/SR-237 +if [ -z "${HOST_CC}" ] ; then + echo "Can't find clang. Please install clang-3.5 or a later version." + exit 1 +fi +if [ -z "${CMAKE}" ] ; then + echo "Environment variable CMAKE must be specified." exit 1 fi @@ -727,10 +733,10 @@ function not() { function true_false() { case "$1" in - false | 0) + false | FALSE | 0) echo "FALSE" ;; - true | 1) + true | TRUE | 1) echo "TRUE" ;; *) @@ -744,14 +750,6 @@ function true_false() { # Set default values for command-line parameters. # -if [[ "${CMAKE}" == "" ]] ; then - if [[ "$(uname -s)" == "Darwin" ]] ; then - CMAKE="$(xcrun_find_tool cmake)" - else - CMAKE="$(which cmake || echo /usr/local/bin/cmake)" - fi -fi - if [[ "${INSTALL_PREFIX}" == "" ]] ; then if [[ "$(uname -s)" == "Darwin" ]] ; then INSTALL_PREFIX="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr" @@ -764,8 +762,8 @@ if [[ "$(uname -s)" == "Darwin" ]] ; then TOOLCHAIN_PREFIX=$(echo ${INSTALL_PREFIX} | sed -E 's/\/usr$//') fi -# A list of deployment targets to compile the Swift host tools for, in case when -# we can run the resulting binaries natively on the build machine. +# A list of deployment targets to compile the Swift host tools for, in cases +# where we can run the resulting binaries natively on the build machine. NATIVE_TOOLS_DEPLOYMENT_TARGETS=() # A list of deployment targets to cross-compile the Swift host tools for. @@ -774,20 +772,29 @@ CROSS_TOOLS_DEPLOYMENT_TARGETS=() # Determine the native deployment target for the build machine, that will be # used to jumpstart the standard library build when cross-compiling. -case "$(uname -s)" in - Linux) +case "$(uname -s -m)" in + Linux\ x86_64) NATIVE_TOOLS_DEPLOYMENT_TARGETS=( "linux-x86_64" ) ;; - - Darwin) + Linux\ armv7*) + NATIVE_TOOLS_DEPLOYMENT_TARGETS=( + "linux-armv7" + ) + ;; + Linux\ aarch64) + NATIVE_TOOLS_DEPLOYMENT_TARGETS=( + "linux-aarch64" + ) + ;; + Darwin\ x86_64) NATIVE_TOOLS_DEPLOYMENT_TARGETS=( "macosx-x86_64" ) ;; - FreeBSD) + FreeBSD\ amd64) NATIVE_TOOLS_DEPLOYMENT_TARGETS=( "freebsd-x86_64" ) @@ -813,7 +820,7 @@ for t in ${CROSS_COMPILE_TOOLS_DEPLOYMENT_TARGETS} ; do ) ;; *) - echo "Unknown deployment target" + echo "Unknown deployment target: ${t}" exit 1 ;; esac @@ -840,16 +847,24 @@ function is_cross_tools_deployment_target() { # A list of deployment targets that we compile or cross-compile the # Swift standard library for. STDLIB_DEPLOYMENT_TARGETS=() - -case "$(uname -s)" in - Linux) +case "$(uname -s -m)" in + Linux\ x86_64) STDLIB_DEPLOYMENT_TARGETS=( "linux-x86_64" "android-armv7" ) ;; - - Darwin) + Linux\ armv7*) + STDLIB_DEPLOYMENT_TARGETS=( + "linux-armv7" + ) + ;; + Linux\ aarch64) + STDLIB_DEPLOYMENT_TARGETS=( + "linux-aarch64" + ) + ;; + Darwin\ x86_64) STDLIB_DEPLOYMENT_TARGETS=( "macosx-x86_64" "iphonesimulator-i386" @@ -866,7 +881,7 @@ case "$(uname -s)" in ) ;; - FreeBSD) + FreeBSD\ amd64) STDLIB_DEPLOYMENT_TARGETS=( "freebsd-x86_64" ) @@ -881,39 +896,51 @@ esac # # Calculate source directories for each product. # -NINJA_SOURCE_DIR="$WORKSPACE/ninja" -SWIFT_SOURCE_DIR="$WORKSPACE/swift" -LLVM_SOURCE_DIR="$WORKSPACE/llvm" -CMARK_SOURCE_DIR="$WORKSPACE/cmark" -LLDB_SOURCE_DIR="$WORKSPACE/lldb" -LLBUILD_SOURCE_DIR="$WORKSPACE/llbuild" -SWIFTPM_SOURCE_DIR="$WORKSPACE/swiftpm" -XCTEST_SOURCE_DIR="$WORKSPACE/swift-corelibs-xctest" -FOUNDATION_SOURCE_DIR="$WORKSPACE/swift-corelibs-foundation" - -if [[ ! -d $CMARK_SOURCE_DIR ]]; then - echo "$CMARK_SOURCE_DIR not found. Attempting to clone ..." - git clone https://github.com/apple/swift-cmark.git "$CMARK_SOURCE_DIR" || \ - (echo "Couldn't clone cmark. Please check README.md and visit https://github.com/apple/swift-cmark for details." && \ - exit 1) +NINJA_SOURCE_DIR="${WORKSPACE}/ninja" +SWIFT_SOURCE_DIR="${WORKSPACE}/swift" +LLVM_SOURCE_DIR="${WORKSPACE}/llvm" +CMARK_SOURCE_DIR="${WORKSPACE}/cmark" +LLDB_SOURCE_DIR="${WORKSPACE}/lldb" +LLBUILD_SOURCE_DIR="${WORKSPACE}/llbuild" +SWIFTPM_SOURCE_DIR="${WORKSPACE}/swiftpm" +XCTEST_SOURCE_DIR="${WORKSPACE}/swift-corelibs-xctest" +FOUNDATION_SOURCE_DIR="${WORKSPACE}/swift-corelibs-foundation" + +if [[ ! -d ${CMARK_SOURCE_DIR} ]]; then + echo "Couldn't find cmark source directory." + exit 1 fi -if [[ ! "$SKIP_BUILD_LLBUILD" && ! -d $LLBUILD_SOURCE_DIR ]]; then +# Migration code for the cmark repository. Can be removed in February 2016. +pushd ${CMARK_SOURCE_DIR} > /dev/null +if git show 077611288ad990bf5962b3e1d844172392d3e8d8 > /dev/null 2>&1 ; then + echo "" + echo "You have an old copy of the cmark repository." + echo "You need to remove it and clone again:" + echo "" + echo " $ rm -rf ${CMARK_SOURCE_DIR}" + echo " $ ${SWIFT_SOURCE_DIR}/utils/update-checkout --clone" + echo "" + exit 1 +fi +popd > /dev/null + +if [[ ! "${SKIP_BUILD_LLBUILD}" && ! -d ${LLBUILD_SOURCE_DIR} ]]; then echo "Couldn't find llbuild source directory." exit 1 fi -if [[ ! "$SKIP_BUILD_SWIFTPM" && ! -d $SWIFTPM_SOURCE_DIR ]]; then +if [[ ! "${SKIP_BUILD_SWIFTPM}" && ! -d ${SWIFTPM_SOURCE_DIR} ]]; then echo "Couldn't find swiftpm source directory." exit 1 fi -if [[ ! "$SKIP_BUILD_XCTEST" && ! -d $XCTEST_SOURCE_DIR ]]; then +if [[ ! "${SKIP_BUILD_XCTEST}" && ! -d ${XCTEST_SOURCE_DIR} ]]; then echo "Couldn't find XCTest source directory." exit 1 fi -if [[ ! "$SKIP_BUILD_FOUNDATION" && ! -d $FOUNDATION_SOURCE_DIR ]]; then +if [[ ! "${SKIP_BUILD_FOUNDATION}" && ! -d ${FOUNDATION_SOURCE_DIR} ]]; then echo "Couldn't find Foundation source directory." exit 1 fi @@ -949,11 +976,13 @@ if [[ ! "${SKIP_BUILD_FOUNDATION}" ]] ; then fi SWIFT_STDLIB_TARGETS=() +SWIFT_PERFTEST_TARGETS=() SWIFT_TEST_TARGETS=() for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do build_for_this_target=1 + perftest_this_target= test_this_target=1 - case $deployment_target in + case ${deployment_target} in linux-*) build_for_this_target=1 test_this_target=1 @@ -963,68 +992,77 @@ for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do test_this_target=1 ;; macosx-*) - build_for_this_target=$(not $SKIP_BUILD_OSX) - test_this_target=$(not $SKIP_TEST_OSX) + build_for_this_target=$(not ${SKIP_BUILD_OSX}) + perftest_this_target=$(not ${SKIP_BUILD_OSX}) + test_this_target=$(not ${SKIP_TEST_OSX}) ;; iphoneos-*) - build_for_this_target=$(not $SKIP_BUILD_IOS_DEVICE) + build_for_this_target=$(not ${SKIP_BUILD_IOS_DEVICE}) + perftest_this_target=$(not ${SKIP_BUILD_IOS_DEVICE}) test_this_target= ;; iphonesimulator-*) - build_for_this_target=$(not $SKIP_BUILD_IOS_SIMULATOR) - test_this_target=$(not $SKIP_TEST_IOS_SIMULATOR) + build_for_this_target=$(not ${SKIP_BUILD_IOS_SIMULATOR}) + test_this_target=$(not ${SKIP_TEST_IOS_SIMULATOR}) ;; appletvos-*) - build_for_this_target=$(not $SKIP_BUILD_TVOS_DEVICE) + build_for_this_target=$(not ${SKIP_BUILD_TVOS_DEVICE}) + perftest_this_target=$(not ${SKIP_BUILD_TVOS_DEVICE}) test_this_target= ;; appletvsimulator-*) - build_for_this_target=$(not $SKIP_BUILD_TVOS_SIMULATOR) - test_this_target=$(not $SKIP_TEST_TVOS_SIMULATOR) + build_for_this_target=$(not ${SKIP_BUILD_TVOS_SIMULATOR}) + test_this_target=$(not ${SKIP_TEST_TVOS_SIMULATOR}) ;; watchos-*) - build_for_this_target=$(not $SKIP_BUILD_WATCHOS_DEVICE) + build_for_this_target=$(not ${SKIP_BUILD_WATCHOS_DEVICE}) + perftest_this_target=$(not ${SKIP_BUILD_WATCHOS_DEVICE}) test_this_target= ;; watchsimulator-*) - build_for_this_target=$(not $SKIP_BUILD_WATCHOS_SIMULATOR) - test_this_target=$(not $SKIP_TEST_WATCHOS_SIMULATOR) + build_for_this_target=$(not ${SKIP_BUILD_WATCHOS_SIMULATOR}) + test_this_target=$(not ${SKIP_TEST_WATCHOS_SIMULATOR}) ;; android-*) build_for_this_target=1 test_this_target=1 ;; *) - echo "Unknown compiler deployment target: $deployment_target" + echo "Unknown compiler deployment target: ${deployment_target}" exit 1 ;; esac - if [[ "$build_for_this_target" ]] ; then + if [[ "${build_for_this_target}" ]] ; then SWIFT_STDLIB_TARGETS=( "${SWIFT_STDLIB_TARGETS[@]}" "swift-stdlib-${deployment_target}") fi - if [[ "$test_this_target" ]] ; then - if [[ "$SKIP_TEST_VALIDATION" ]] ; then + if [[ "${perftest_this_target}" ]] ; then + SWIFT_PERFTEST_TARGETS=( + "${SWIFT_PERFTEST_TARGETS[@]}" "swift-perftest-${deployment_target}") + fi + if [[ "${test_this_target}" ]] ; then + if [[ "${SKIP_TEST_VALIDATION}" ]] ; then SWIFT_TEST_TARGETS=( "${SWIFT_TEST_TARGETS[@]}" "check-swift-${deployment_target}") - if [[ $(not $SKIP_TEST_OPTIMIZED) ]] ; then + if [[ $(not ${SKIP_TEST_OPTIMIZED}) ]] ; then SWIFT_TEST_TARGETS=( "${SWIFT_TEST_TARGETS[@]}" "check-swift-optimize-${deployment_target}") fi else SWIFT_TEST_TARGETS=( "${SWIFT_TEST_TARGETS[@]}" "check-swift-all-${deployment_target}") - if [[ $(not $SKIP_TEST_OPTIMIZED) ]] ; then + if [[ $(not ${SKIP_TEST_OPTIMIZED}) ]] ; then SWIFT_TEST_TARGETS=( "${SWIFT_TEST_TARGETS[@]}" "check-swift-all-optimize-${deployment_target}") fi - fi fi done echo "Building the standard library for: ${SWIFT_STDLIB_TARGETS[@]}" -echo "Running Swift tests for: ${SWIFT_TEST_TARGETS[@]}" +if [[ "${SWIFT_TEST_TARGETS[@]}" ]] && ! [[ "${SKIP_TEST_SWIFT}" ]]; then + echo "Running Swift tests for: ${SWIFT_TEST_TARGETS[@]}" +fi echo # CMake options used for all targets, including LLVM/Clang @@ -1033,7 +1071,6 @@ COMMON_CMAKE_OPTIONS=( ) COMMON_C_FLAGS="" -COMMON_CXX_FLAGS="" if [[ "${ENABLE_ASAN}" ]] ; then COMMON_CMAKE_OPTIONS=( @@ -1042,26 +1079,14 @@ if [[ "${ENABLE_ASAN}" ]] ; then ) fi -if [ -z "${HOST_CC}" ] ; then - if [ "$(uname -s)" == "Darwin" ] ; then - HOST_CC="$(xcrun_find_tool clang)" - HOST_CXX="$(xcrun_find_tool clang++)" - else - for clang_candidate_suffix in "" "-3.8" "-3.7" "-3.6" "-3.5" ; do - if which "clang${clang_candidate_suffix}" > /dev/null ; then - HOST_CC="clang${clang_candidate_suffix}" - HOST_CXX="clang++${clang_candidate_suffix}" - break - fi - done - fi -fi -if [ -z "${HOST_CC}" ] ; then - echo "Can't find clang. Please install clang-3.5 or a later version." - exit 1 +if [[ "${EXPORT_COMPILE_COMMANDS}" ]] ; then + COMMON_CMAKE_OPTIONS=( + "${COMMON_CMAKE_OPTIONS[@]}" + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + ) fi -if [[ "$DISTCC" ]] ; then +if [[ "${DISTCC}" ]] ; then # On some platforms, 'pump' may be unrelated to distcc, in which case it's # called 'distcc-pump'. DISTCC_PUMP="$(which distcc-pump || which pump)" @@ -1080,18 +1105,19 @@ else ) fi -if [[ "$DISTCC" ]] ; then +if [[ "${DISTCC}" ]] ; then BUILD_ARGS="${BUILD_ARGS} -j $(distcc -j)" fi case "${CMAKE_GENERATOR}" in Ninja) + BUILD_ARGS="${BUILD_ARGS} -j${BUILD_JOBS}" if [[ "${VERBOSE_BUILD}" ]] ; then BUILD_ARGS="${BUILD_ARGS} -v" fi ;; 'Unix Makefiles') - BUILD_ARGS="${BUILD_ARGS:--j$(get_make_parallelism)}" + BUILD_ARGS="${BUILD_ARGS} -j${BUILD_JOBS}" if [[ "${VERBOSE_BUILD}" ]] ; then BUILD_ARGS="${BUILD_ARGS} VERBOSE=1" fi @@ -1101,6 +1127,7 @@ case "${CMAKE_GENERATOR}" in # but since we're not using proper Xcode 4 schemes, this is the # only way to get target-level parallelism. BUILD_ARGS="${BUILD_ARGS} -parallelizeTargets" + BUILD_ARGS="${BUILD_ARGS} -jobs ${BUILD_JOBS}" BUILD_TARGET_FLAG="-target" COMMON_CMAKE_OPTIONS=( "${COMMON_CMAKE_OPTIONS[@]}" @@ -1130,17 +1157,17 @@ fi # # Record SDK and tools versions for posterity # -if [[ "$SHOW_SDKS" ]] ; then +if [[ "${SHOW_SDKS}" ]] ; then echo "--- SDK versions ---" xcodebuild -version || : echo - if [[ ! "$SKIP_IOS" ]] ; then + if [[ ! "${SKIP_IOS}" ]] ; then xcodebuild -version -sdk iphonesimulator || : fi - if [[ ! "$SKIP_TVOS" ]] ; then + if [[ ! "${SKIP_TVOS}" ]] ; then xcodebuild -version -sdk appletvsimulator || : fi - if [[ ! "$SKIP_WATCHOS" ]] ; then + if [[ ! "${SKIP_WATCHOS}" ]] ; then xcodebuild -version -sdk watchsimulator || : fi fi @@ -1148,15 +1175,15 @@ fi function build_directory() { deployment_target=$1 product=$2 - echo "$BUILD_DIR/$product-$deployment_target" + echo "${BUILD_DIR}/${product}-${deployment_target}" } function build_directory_bin() { deployment_target=$1 product=$2 - root="$(build_directory $deployment_target $product)" + root="$(build_directory ${deployment_target} ${product})" if [[ "${CMAKE_GENERATOR}" == "Xcode" ]] ; then - case $product in + case ${product} in cmark) echo "${root}/${CMARK_BUILD_TYPE}/bin" ;; @@ -1239,7 +1266,7 @@ function llvm_c_flags() { function cmark_c_flags() { echo -n " $(common_cross_c_flags $1)" - if [[ $(is_cmake_release_build_type "${LLVM_BUILD_TYPE}") ]] ; then + if [[ $(is_cmake_release_build_type "${CMARK_BUILD_TYPE}") ]] ; then echo -n " -fno-stack-protector" fi } @@ -1259,7 +1286,7 @@ function cmake_config_opt() { if [[ "${CMAKE_GENERATOR}" == "Xcode" ]] ; then # CMake automatically adds --target ALL_BUILD if we don't pass this. echo "--target ZERO_CHECK " - case $product in + case ${product} in cmark) echo "--config ${CMARK_BUILD_TYPE}" ;; @@ -1291,22 +1318,13 @@ function cmake_config_opt() { fi } -function should_build_perftestsuite() { - if [ "$(uname -s)" != Darwin ]; then - echo "FALSE" - return - fi - - echo $(true_false "${BUILD_SWIFT_PERF_TESTSUITE}") -} - function set_swiftpm_bootstrap_command() { swiftpm_bootstrap_command=() - SWIFTC_BIN="$(build_directory_bin $deployment_target swift)/swiftc" - LLBUILD_BIN="$(build_directory_bin $deployment_target llbuild)/swift-build-tool" + SWIFTC_BIN="$(build_directory_bin ${deployment_target} swift)/swiftc" + LLBUILD_BIN="$(build_directory_bin ${deployment_target} llbuild)/swift-build-tool" if [[ ! "${SKIP_BUILD_XCTEST}" ]] ; then - XCTEST_BUILD_DIR=$(build_directory $deployment_target xctest) + XCTEST_BUILD_DIR=$(build_directory ${deployment_target} xctest) fi if [ ! -e "${LLBUILD_BIN}" ]; then echo "Error: Cannot build swiftpm without llbuild (swift-build-tool)." @@ -1368,10 +1386,6 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ none) ;; apple) - # User-visible versions of the compiler. - CLANG_USER_VISIBLE_VERSION="6.1.0" - SWIFT_USER_VISIBLE_VERSION="2.2" - llvm_cmake_options=( "${llvm_cmake_options[@]}" -DCLANG_VENDOR=Apple @@ -1430,6 +1444,11 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ ) fi + swift_cmake_options=( + "${swift_cmake_options[@]}" + -DSWIFT_DARWIN_XCRUN_TOOLCHAIN:STRING="${DARWIN_XCRUN_TOOLCHAIN}" + ) + if [[ "${DARWIN_STDLIB_INSTALL_NAME_DIR}" ]] ; then swift_cmake_options=( "${swift_cmake_options[@]}" @@ -1444,30 +1463,22 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ ) fi - if [[ $(should_build_perftestsuite) == "TRUE" ]]; then - swift_cmake_options=( - "${swift_cmake_options[@]}" - -DSWIFT_INCLUDE_PERF_TESTSUITE=YES - ) - fi - swift_cmake_options=( "${swift_cmake_options[@]}" -DSWIFT_AST_VERIFIER:BOOL=$(true_false "${SWIFT_ENABLE_AST_VERIFIER}") -DSWIFT_VERIFY_ALL:BOOL=$(true_false "${SIL_VERIFY_ALL}") -DSWIFT_RUNTIME_ENABLE_DTRACE:BOOL=$(true_false "${SWIFT_RUNTIME_ENABLE_DTRACE}") -DSWIFT_RUNTIME_ENABLE_LEAK_CHECKER:BOOL=$(true_false "${SWIFT_RUNTIME_ENABLE_LEAK_CHECKER}") - -DSWIFT_ENABLE_TARGET_LINUX:BOOL=$(true_false "${SWIFT_ENABLE_TARGET_LINUX}") ) for product in "${PRODUCTS[@]}"; do unset skip_build - build_dir=$(build_directory $deployment_target $product) + build_dir=$(build_directory ${deployment_target} ${product}) build_targets=(all) cmake_options=("${COMMON_CMAKE_OPTIONS[@]}") # Add in gold linker support if requested. - if [[ "$USE_GOLD_LINKER" ]]; then + if [[ "${USE_GOLD_LINKER}" ]]; then echo "${product}: using gold linker" if [[ "${product}" != "swift" ]]; then # All other projects override the linker flags to add in @@ -1482,34 +1493,34 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ echo "${product}: using standard linker" fi - PRODUCT=$(toupper $product) - llvm_build_dir=$(build_directory $deployment_target llvm) + PRODUCT=$(toupper ${product}) + llvm_build_dir=$(build_directory ${deployment_target} llvm) module_cache="${build_dir}/module-cache" swift_cmake_options=( "${swift_cmake_options[@]}" -DCMAKE_INSTALL_PREFIX:PATH="${INSTALL_PREFIX}" - -DLLVM_CONFIG:PATH="$(build_directory_bin $deployment_target llvm)/llvm-config" + -DLLVM_CONFIG:PATH="$(build_directory_bin ${deployment_target} llvm)/llvm-config" -D${PRODUCT}_PATH_TO_CLANG_SOURCE:PATH="${CLANG_SOURCE_DIR}" -D${PRODUCT}_PATH_TO_CLANG_BUILD:PATH="${llvm_build_dir}" -D${PRODUCT}_PATH_TO_LLVM_SOURCE:PATH="${LLVM_SOURCE_DIR}" -D${PRODUCT}_PATH_TO_LLVM_BUILD:PATH="${llvm_build_dir}" -D${PRODUCT}_PATH_TO_CMARK_SOURCE:PATH="${CMARK_SOURCE_DIR}" - -D${PRODUCT}_PATH_TO_CMARK_BUILD:PATH="$(build_directory $deployment_target cmark)" + -D${PRODUCT}_PATH_TO_CMARK_BUILD:PATH="$(build_directory ${deployment_target} cmark)" ) - if [[ "${CMAKE_GENERATOR}" != "Ninja" ]] ; then + if [[ "${CMAKE_GENERATOR}" == "Xcode" ]] ; then swift_cmake_options=( "${swift_cmake_options[@]-}" - -D${PRODUCT}_CMARK_LIBRARY_DIR:PATH=$(build_directory $deployment_target cmark)/src/$CMARK_BUILD_TYPE + -D${PRODUCT}_CMARK_LIBRARY_DIR:PATH=$(build_directory ${deployment_target} cmark)/src/${CMARK_BUILD_TYPE} ) else swift_cmake_options=( "${swift_cmake_options[@]-}" - -D${PRODUCT}_CMARK_LIBRARY_DIR:PATH=$(build_directory $deployment_target cmark)/src + -D${PRODUCT}_CMARK_LIBRARY_DIR:PATH=$(build_directory ${deployment_target} cmark)/src ) fi - case $product in + case ${product} in cmark) cmake_options=( "${cmake_options[@]}" @@ -1517,7 +1528,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ "${cmark_cmake_options[@]}" "${CMARK_SOURCE_DIR}" ) - skip_build=$SKIP_BUILD_CMARK + skip_build=${SKIP_BUILD_CMARK} build_targets=(all) ;; @@ -1541,8 +1552,8 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ # llvm/tools, e.g. to build LLDB. cmake_options=( "${cmake_options[@]}" - -DCMAKE_C_FLAGS="$(llvm_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(llvm_c_flags $deployment_target)" + -DCMAKE_C_FLAGS="$(llvm_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(llvm_c_flags ${deployment_target})" -DCMAKE_BUILD_TYPE:STRING="${LLVM_BUILD_TYPE}" -DLLVM_ENABLE_ASSERTIONS:BOOL=$(true_false "${LLVM_ENABLE_ASSERTIONS}") -DLLVM_TOOL_SWIFT_BUILD:BOOL=NO @@ -1552,7 +1563,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ "${llvm_cmake_options[@]}" "${LLVM_SOURCE_DIR}" ) - if [[ $(is_cross_tools_deployment_target $deployment_target) ]] ; then + if [[ $(is_cross_tools_deployment_target ${deployment_target}) ]] ; then # FIXME: don't hardcode macosx-x86_64. cmake_options=( "${cmake_options[@]}" @@ -1564,8 +1575,8 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ ;; swift) - cmake_options=(${COMMON_CMAKE_OPTIONS[@]}) - if [[ "$USE_GOLD_LINKER" ]]; then + cmake_options=("${COMMON_CMAKE_OPTIONS[@]}") + if [[ "${USE_GOLD_LINKER}" ]]; then # Swift will selectively use the gold linker on all # parts except building the standard library. We # let the Swift cmake setup figure out how to apply @@ -1579,7 +1590,9 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ native_llvm_tools_path="" native_clang_tools_path="" native_swift_tools_path="" - if [[ $(is_cross_tools_deployment_target $deployment_target) ]] ; then + if [[ $(is_cross_tools_deployment_target ${deployment_target}) ]] ; then + # Don't build benchmarks and tests when building cross compiler. + build_perf_testsuite_this_time=false build_tests_this_time=false # FIXME: don't hardcode macosx-x86_64. @@ -1589,13 +1602,14 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ cmake_options=( "${cmake_options[@]}" - -DLLVM_TOOLS_BINARY_DIR:PATH=$(build_directory $deployment_target llvm)/bin - -DLLVM_LIBRARY_DIR:PATH=$(build_directory $deployment_target llvm)/lib - -DLLVM_MAIN_INCLUDE_DIR:PATH=$(build_directory $deployment_target llvm)/include - -DLLVM_BINARY_DIR:PATH=$(build_directory $deployment_target llvm) + -DLLVM_TOOLS_BINARY_DIR:PATH=$(build_directory ${deployment_target} llvm)/bin + -DLLVM_LIBRARY_DIR:PATH=$(build_directory ${deployment_target} llvm)/lib + -DLLVM_MAIN_INCLUDE_DIR:PATH=$(build_directory ${deployment_target} llvm)/include + -DLLVM_BINARY_DIR:PATH=$(build_directory ${deployment_target} llvm) -DLLVM_MAIN_SRC_DIR:PATH="${LLVM_SOURCE_DIR}" ) else + build_perf_testsuite_this_time=$(true_false "${BUILD_SWIFT_PERF_TESTSUITE}") build_tests_this_time=${SOURCE_TREE_INCLUDES_TESTS} fi @@ -1617,15 +1631,15 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ -DLLVM_TOOLS_BINARY_DIR:PATH=/tmp/dummy -DLLVM_LIBRARY_DIR:PATH="${build_dir}" -DLLVM_MAIN_INCLUDE_DIR:PATH=/tmp/dummy - -DLLVM_BINARY_DIR:PATH=$(build_directory $deployment_target llvm) + -DLLVM_BINARY_DIR:PATH=$(build_directory ${deployment_target} llvm) -DLLVM_MAIN_SRC_DIR:PATH="${LLVM_SOURCE_DIR}" ) fi cmake_options=( "${cmake_options[@]}" - -DCMAKE_C_FLAGS="$(swift_c_flags $deployment_target)" - -DCMAKE_CXX_FLAGS="$(swift_c_flags $deployment_target)" + -DCMAKE_C_FLAGS="$(swift_c_flags ${deployment_target})" + -DCMAKE_CXX_FLAGS="$(swift_c_flags ${deployment_target})" -DCMAKE_BUILD_TYPE:STRING="${SWIFT_BUILD_TYPE}" -DLLVM_ENABLE_ASSERTIONS:BOOL=$(true_false "${SWIFT_ENABLE_ASSERTIONS}") -DSWIFT_STDLIB_BUILD_TYPE:STRING="${SWIFT_STDLIB_BUILD_TYPE}" @@ -1637,6 +1651,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ -DSWIFT_BUILD_STDLIB:BOOL=$(true_false "${BUILD_SWIFT_STDLIB}") -DSWIFT_BUILD_SDK_OVERLAY:BOOL=$(true_false "${BUILD_SWIFT_SDK_OVERLAY}") -DSWIFT_BUILD_STATIC_STDLIB:BOOL=$(true_false "${BUILD_SWIFT_STATIC_STDLIB}") + -DSWIFT_BUILD_PERF_TESTSUITE:BOOL=$(true_false "${build_perf_testsuite_this_time}") -DSWIFT_BUILD_EXAMPLES:BOOL=$(true_false "${BUILD_SWIFT_EXAMPLES}") -DSWIFT_INCLUDE_TESTS:BOOL=$(true_false "${build_tests_this_time}") -DSWIFT_INSTALL_COMPONENTS:STRING="${SWIFT_INSTALL_COMPONENTS}" @@ -1659,14 +1674,20 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ fi build_targets=(all "${SWIFT_STDLIB_TARGETS[@]}") - if [[ $(should_build_perftestsuite) == "TRUE" ]]; then - build_targets=("${build_targets[@]}" benchmark-swift) + if [[ $(true_false "${build_perf_testsuite_this_time}") == "TRUE" ]]; then + native_swift_tools_path=$(build_directory macosx-x86_64 swift)/bin + cmake_options=( + "${cmake_options[@]}" + -DSWIFT_EXEC:STRING="${native_swift_tools_path}/swiftc" + ) + build_targets=("${build_targets[@]}" + "${SWIFT_PERFTEST_TARGETS[@]}") fi - skip_build=$SKIP_BUILD_SWIFT + skip_build=${SKIP_BUILD_SWIFT} ;; lldb) - if [ ! -d "$LLDB_SOURCE_DIR" ]; then + if [ ! -d "${LLDB_SOURCE_DIR}" ]; then echo "error: lldb not found in ${LLDB_SOURCE_DIR}" exit 1 fi @@ -1674,28 +1695,28 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ echo "error: lldb can only build with ninja" exit 1 fi - cmark_build_dir=$(build_directory $deployment_target cmark) - lldb_build_dir=$(build_directory $deployment_target lldb) - swift_build_dir=$(build_directory $deployment_target swift) + cmark_build_dir=$(build_directory ${deployment_target} cmark) + lldb_build_dir=$(build_directory ${deployment_target} lldb) + swift_build_dir=$(build_directory ${deployment_target} swift) # Add any lldb extra cmake arguments here. - if [ ! -z "$LLDB_EXTRA_CMAKE_ARGS" ]; then + if [ ! -z "${LLDB_EXTRA_CMAKE_ARGS}" ]; then cmake_options=( "${cmake_options[@]}" - $LLDB_EXTRA_CMAKE_ARGS + ${LLDB_EXTRA_CMAKE_ARGS} ) fi # Figure out if we think this is a buildbot build. # This will influence the lldb version line. - if [ ! -z "$JENKINS_HOME" -a ! -z "$JOB_NAME" -a ! -z "$BUILD_NUMBER" ]; then + if [ ! -z "${JENKINS_HOME}" -a ! -z "${JOB_NAME}" -a ! -z "${BUILD_NUMBER}" ]; then LLDB_IS_BUILDBOT_BUILD=1 else LLDB_IS_BUILDBOT_BUILD=0 fi # Get the build date - LLDB_BUILD_DATE=`date +%Y-%m-%d` + LLDB_BUILD_DATE=$(date +%Y-%m-%d) case "$(uname -s)" in Linux) @@ -1712,6 +1733,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ -DLLDB_PATH_TO_CMARK_BUILD:PATH="${cmark_build_dir}" -DLLDB_IS_BUILDBOT_BUILD="${LLDB_IS_BUILDBOT_BUILD}" -DLLDB_BUILD_DATE:STRING="\"${LLDB_BUILD_DATE}\"" + -DLLDB_ALLOW_STATIC_BINDINGS=1 "${LLDB_SOURCE_DIR}" ) ;; @@ -1729,6 +1751,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ -DLLDB_PATH_TO_CMARK_BUILD:PATH="${cmark_build_dir}" -DLLDB_IS_BUILDBOT_BUILD="${LLDB_IS_BUILDBOT_BUILD}" -DLLDB_BUILD_DATE:STRING="\"${LLDB_BUILD_DATE}\"" + -DLLDB_ALLOW_STATIC_BINDINGS=1 "${LLDB_SOURCE_DIR}" ) ;; @@ -1773,7 +1796,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ "${cmake_options[@]}" -DCMAKE_INSTALL_PREFIX:PATH="${INSTALL_PREFIX}" -DLIT_EXECUTABLE:PATH="${LLVM_SOURCE_DIR}/utils/lit/lit.py" - -DFILECHECK_EXECUTABLE:PATH="$(build_directory_bin $deployment_target llvm)/FileCheck" + -DFILECHECK_EXECUTABLE:PATH="$(build_directory_bin ${deployment_target} llvm)/FileCheck" -DCMAKE_BUILD_TYPE:STRING="${LLBUILD_BUILD_TYPE}" -DLLVM_ENABLE_ASSERTIONS:BOOL=$(true_false "${LLBUILD_ENABLE_ASSERTIONS}") "${LLBUILD_SOURCE_DIR}" @@ -1789,10 +1812,10 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ continue ;; xctest) - SWIFTC_BIN="$(build_directory_bin $deployment_target swift)/swiftc" - SWIFT_BUILD_PATH="$(build_directory $deployment_target swift)" + SWIFTC_BIN="$(build_directory_bin ${deployment_target} swift)/swiftc" + SWIFT_BUILD_PATH="$(build_directory ${deployment_target} swift)" set -x - "$XCTEST_SOURCE_DIR"/build_script.py --swiftc="${SWIFTC_BIN}" --build-dir="${build_dir}" --swift-build-dir="${SWIFT_BUILD_PATH}" + "${XCTEST_SOURCE_DIR}"/build_script.py --swiftc="${SWIFTC_BIN}" --build-dir="${build_dir}" --swift-build-dir="${SWIFT_BUILD_PATH}" { set +x; } 2>/dev/null # XCTest builds itself and doesn't rely on cmake @@ -1800,11 +1823,11 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ ;; foundation) # the configuration script requires knowing about XCTest's location for building and running the tests - XCTEST_BUILD_DIR=$(build_directory $deployment_target xctest) - SWIFTC_BIN="$(build_directory_bin $deployment_target swift)/swiftc" - SWIFT_BIN="$(build_directory_bin $deployment_target swift)/swift" - SWIFT_BUILD_PATH="$(build_directory $deployment_target swift)" - LLVM_BIN="$(build_directory_bin $deployment_target llvm)" + XCTEST_BUILD_DIR=$(build_directory ${deployment_target} xctest) + SWIFTC_BIN="$(build_directory_bin ${deployment_target} swift)/swiftc" + SWIFT_BIN="$(build_directory_bin ${deployment_target} swift)/swift" + SWIFT_BUILD_PATH="$(build_directory ${deployment_target} swift)" + LLVM_BIN="$(build_directory_bin ${deployment_target} llvm)" NINJA_BIN="ninja" if [[ "${BUILD_NINJA}" ]]; then @@ -1816,7 +1839,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ pushd "${FOUNDATION_SOURCE_DIR}" SWIFTC="${SWIFTC_BIN}" CLANG="${LLVM_BIN}"/clang SWIFT="${SWIFT_BIN}" \ SDKROOT="${SWIFT_BUILD_PATH}" BUILD_DIR="${build_dir}" DSTROOT="${INSTALL_DESTDIR}" PREFIX="${INSTALL_PREFIX}" ./configure "${FOUNDATION_BUILD_TYPE}" -DXCTEST_BUILD_DIR=${XCTEST_BUILD_DIR} - $NINJA_BIN + ${NINJA_BIN} popd { set +x; } 2>/dev/null @@ -1848,7 +1871,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ ( ! -z "${generator_output_path}" && ! -f "${generator_output_path}" ) ]] ; then mkdir -p "${build_dir}" set -x - (cd "${build_dir}" && "$CMAKE" "${cmake_options[@]}" ${USER_CONFIG_ARGS}) + (cd "${build_dir}" && "${CMAKE}" "${cmake_options[@]}" ${USER_CONFIG_ARGS}) { set +x; } 2>/dev/null fi @@ -1863,12 +1886,12 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ # Xcode can't restart itself if it turns out we need to reconfigure. # Do an advance build to handle that. set -x - ${DISTCC_PUMP} "$CMAKE" --build "${build_dir}" $(cmake_config_opt $product) + ${DISTCC_PUMP} "${CMAKE}" --build "${build_dir}" $(cmake_config_opt ${product}) { set +x; } 2>/dev/null fi set -x - ${DISTCC_PUMP} "$CMAKE" --build "${build_dir}" $(cmake_config_opt $product) -- ${BUILD_ARGS} ${build_targets[@]} + ${DISTCC_PUMP} "${CMAKE}" --build "${build_dir}" $(cmake_config_opt ${product}) -- ${BUILD_ARGS} ${build_targets[@]} { set +x; } 2>/dev/null fi done @@ -1883,26 +1906,26 @@ tests_busted () } for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do - case $deployment_target in + case ${deployment_target} in linux-* | freebsd-* | macosx-*) # OK, we can run tests directly. ;; iphoneos-* | iphonesimulator-* | appletvos-* | appletvsimulator-* | watchos-* | watchsimulator-* | android-* ) # FIXME: remove this - # echo "Don't know how to run tests for $deployment_target" + # echo "Don't know how to run tests for ${deployment_target}" continue ;; *) - echo "Unknown compiler deployment target: $deployment_target" + echo "Unknown compiler deployment target: ${deployment_target}" exit 1 ;; esac # Run the tests for each product for product in "${PRODUCTS[@]}"; do - case $product in + case ${product} in cmark) - if [[ "$SKIP_TEST_CMARK" ]]; then + if [[ "${SKIP_TEST_CMARK}" ]]; then continue fi executable_target=api_test @@ -1916,12 +1939,12 @@ for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do continue # We don't test LLVM ;; swift) - if [[ "$SKIP_TEST_SWIFT" ]]; then + if [[ "${SKIP_TEST_SWIFT}" ]]; then continue fi executable_target=SwiftUnitTests results_targets=("${SWIFT_TEST_TARGETS[@]}") - if [[ "$STRESS_TEST_SOURCEKIT" ]]; then + if [[ "${STRESS_TEST_SOURCEKIT}" ]]; then results_targets=( "${results_targets[@]}" stress-SourceKit @@ -1929,53 +1952,55 @@ for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do fi ;; lldb) - if [[ "$SKIP_TEST_LLDB" ]]; then + if [[ "${SKIP_TEST_LLDB}" ]]; then continue fi - lldb_build_dir=$(build_directory $deployment_target lldb) - swift_build_dir=$(build_directory $deployment_target swift) + lldb_build_dir=$(build_directory ${deployment_target} lldb) + swift_build_dir=$(build_directory ${deployment_target} swift) # Setup lldb executable path if [[ "$(uname -s)" == "Darwin" ]] ; then - lldb_executable="$lldb_build_dir"/$LLDB_BUILD_MODE/lldb + lldb_executable="${lldb_build_dir}"/${LLDB_BUILD_MODE}/lldb else - lldb_executable="$lldb_build_dir"/bin/lldb + lldb_executable="${lldb_build_dir}"/bin/lldb fi - results_dir="$lldb_build_dir/test-results" - mkdir -p "$results_dir" - pushd "$results_dir" + results_dir="${lldb_build_dir}/test-results" + mkdir -p "${results_dir}" + pushd "${results_dir}" # Handle test results formatter - if [[ "$LLDB_TEST_WITH_CURSES" ]]; then + if [[ "${LLDB_TEST_WITH_CURSES}" ]]; then # Setup the curses results formatter. LLDB_FORMATTER_OPTS="\ --results-formatter lldbsuite.test.curses_results.Curses \ --results-file /dev/stdout" else - LLDB_FORMATTER_OPTS="--results-file $results_dir/results.xml \ - -O--xpass=ignore" + LLDB_FORMATTER_OPTS="\ + --results-formatter lldbsuite.test.xunit_formatter.XunitFormatter \ + --results-file ${results_dir}/results.xml \ + -O--xpass=ignore" # Setup the xUnit results formatter. if [[ "$(uname -s)" != "Darwin" ]] ; then # On non-Darwin, we ignore skipped tests entirely # so that they don't pollute our xUnit results with # non-actionable content. - LLDB_FORMATTER_OPTS="$LLDB_FORMATTER_OPTS -O-ndsym -O-rdebugserver -O-rlibc\\\\+\\\\+ -O-rlong.running -O-rbenchmarks -O-rrequires.one?.of.darwin" + LLDB_FORMATTER_OPTS="${LLDB_FORMATTER_OPTS} -O-ndsym -O-rdebugserver -O-rlibc\\\\+\\\\+ -O-rlong.running -O-rbenchmarks -O-rrequires.one?.of.darwin" fi fi - SWIFTCC="$swift_build_dir/bin/swiftc" SWIFTLIBS="$swift_build_dir/lib/swift" "$LLDB_SOURCE_DIR"/test/dotest.py --executable "$lldb_executable" -C $HOST_CC $LLDB_FORMATTER_OPTS + SWIFTCC="${swift_build_dir}/bin/swiftc" SWIFTLIBS="${swift_build_dir}/lib/swift" "${LLDB_SOURCE_DIR}"/test/dotest.py --executable "${lldb_executable}" --rerun-all-issues -C ${HOST_CC} ${LLDB_FORMATTER_OPTS} popd continue ;; llbuild) - if [[ "$SKIP_TEST_LLBUILD" ]]; then + if [[ "${SKIP_TEST_LLBUILD}" ]]; then continue fi results_targets=("test") executable_target="" ;; swiftpm) - if [[ "$SKIP_TEST_SWIFTPM" ]]; then + if [[ "${SKIP_TEST_SWIFTPM}" ]]; then continue fi echo "--- Running tests for ${product} ---" @@ -1986,23 +2011,26 @@ for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do continue ;; xctest) - if [[ "$SKIP_TEST_XCTEST" ]]; then + if [[ "${SKIP_TEST_XCTEST}" ]]; then continue fi # FIXME: We don't test xctest, yet... continue ;; foundation) - if [[ "$SKIP_TEST_FOUNDATION" ]]; then + if [[ "${SKIP_TEST_FOUNDATION}" ]]; then continue fi echo "--- Running tests for ${product} ---" - build_dir=$(build_directory $deployment_target $product) - XCTEST_BUILD_DIR=$(build_directory $deployment_target xctest) + set -x + build_dir=$(build_directory ${deployment_target} ${product}) + XCTEST_BUILD_DIR=$(build_directory ${deployment_target} xctest) pushd "${FOUNDATION_SOURCE_DIR}" - $NINJA_BIN TestFoundation - LD_LIBRARY_PATH="${INSTALL_DESTDIR}"/"${INSTALL_PREFIX}"/lib/swift/:"${build_dir}/Foundation":"${XCTEST_BUILD_DIR}":$LD_LIBRARY_PATH "${build_dir}"/TestFoundation/TestFoundation + ${NINJA_BIN} TestFoundation + LD_LIBRARY_PATH="${INSTALL_DESTDIR}"/"${INSTALL_PREFIX}"/lib/swift/:"${build_dir}/Foundation":"${XCTEST_BUILD_DIR}":${LD_LIBRARY_PATH} "${build_dir}"/TestFoundation/TestFoundation popd + { set +x; } 2>/dev/null + echo "--- Finished tests for ${product} ---" continue ;; *) @@ -2012,8 +2040,8 @@ for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do esac trap "tests_busted ${product} ''" ERR - build_dir=$(build_directory $deployment_target $product) - build_cmd=("$CMAKE" --build "${build_dir}" $(cmake_config_opt $product) -- ${BUILD_ARGS}) + build_dir=$(build_directory ${deployment_target} ${product}) + build_cmd=("${CMAKE}" --build "${build_dir}" $(cmake_config_opt ${product}) -- ${BUILD_ARGS}) if [[ "${executable_target}" != "" ]]; then echo "--- Building tests for ${product} ---" @@ -2024,7 +2052,7 @@ for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do echo "--- Running tests for ${product} ---" for target in "${results_targets[@]}"; do - echo "--- $target ---" + echo "--- ${target} ---" trap "tests_busted ${product} '(${target})'" ERR if [[ "${CMAKE_GENERATOR}" == Ninja ]] && !( "${build_cmd[@]}" --version 2>&1 | grep -i -q llbuild ); then # Ninja buffers command output to avoid scrambling the output @@ -2039,7 +2067,7 @@ for deployment_target in "${STDLIB_DEPLOYMENT_TARGETS[@]}"; do "${build_cmd[@]}" ${BUILD_TARGET_FLAG} ${target} { set +x; } 2>/dev/null fi - echo "-- $target finished --" + echo "-- ${target} finished --" done trap - ERR @@ -2054,7 +2082,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ INSTALL_TARGETS="install" - case $product in + case ${product} in cmark) if [[ -z "${INSTALL_CMARK}" ]] ; then continue @@ -2116,16 +2144,16 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ continue fi LIB_TARGET="linux" - if [[ `uname -s` == "FreeBSD" ]]; then + if [[ $(uname -s) == "FreeBSD" ]]; then LIB_TARGET="freebsd" fi - if [[ `uname -s` == "Darwin" ]]; then + if [[ $(uname -s) == "Darwin" ]]; then LIB_TARGET="macosx" fi XCTEST_INSTALL_PREFIX="${INSTALL_DESTDIR}"/"${INSTALL_PREFIX}"/lib/swift/"${LIB_TARGET}" echo "--- Installing ${product} ---" set -x - "$XCTEST_SOURCE_DIR"/build_script.py --swiftc="${SWIFTC_BIN}" \ + "${XCTEST_SOURCE_DIR}"/build_script.py --swiftc="${SWIFTC_BIN}" \ --build-dir="${build_dir}" \ --library-install-path="${XCTEST_INSTALL_PREFIX}" \ --module-install-path="${XCTEST_INSTALL_PREFIX}"/"${SWIFT_HOST_VARIANT_ARCH}" \ @@ -2140,10 +2168,10 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ continue fi echo "--- Installing ${product} ---" - build_dir=$(build_directory $deployment_target $product) + build_dir=$(build_directory ${deployment_target} ${product}) set -x pushd "${FOUNDATION_SOURCE_DIR}" - $NINJA_BIN install + ${NINJA_BIN} install popd { set +x; } 2>/dev/null @@ -2161,7 +2189,7 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ exit 1 fi - if [ "$CROSS_COMPILE_TOOLS_DEPLOYMENT_TARGETS" ] ; then + if [ "${CROSS_COMPILE_TOOLS_DEPLOYMENT_TARGETS}" ] ; then # If cross compiling tools, install into a deployment target specific subdirectory. if [[ ! "${SKIP_MERGE_LIPO_CROSS_COMPILE_TOOLS}" ]] ; then target_install_destdir="${BUILD_DIR}"/intermediate-install/"${deployment_target}" @@ -2173,11 +2201,11 @@ for deployment_target in "${NATIVE_TOOLS_DEPLOYMENT_TARGETS[@]}" "${CROSS_TOOLS_ fi echo "--- Installing ${product} ---" - build_dir=$(build_directory $deployment_target $product) + build_dir=$(build_directory ${deployment_target} ${product}) set -x - DESTDIR="${target_install_destdir}" "$CMAKE" --build "${build_dir}" -- ${INSTALL_TARGETS} + DESTDIR="${target_install_destdir}" "${CMAKE}" --build "${build_dir}" -- ${INSTALL_TARGETS} { set +x; } 2>/dev/null done @@ -2210,13 +2238,13 @@ if [[ "${DARWIN_INSTALL_EXTRACT_SYMBOLS}" ]] ; then grep -v swift-stdlib-tool | \ grep -v crashlog.py | \ grep -v symbolication.py | \ - xargs -n 1 -P $(get_dsymutil_parallelism) $(xcrun_find_tool dsymutil)) + xargs -n 1 -P ${BUILD_JOBS} $(xcrun_find_tool dsymutil)) # Strip executables, shared libraries and static libraries in # INSTALL_DESTDIR. find "${INSTALL_DESTDIR}"/"${TOOLCHAIN_PREFIX}" \ \( -perm -0111 -or -name "*.a" \) -type f -print | \ - xargs -n 1 -P $(get_dsymutil_parallelism) $(xcrun_find_tool strip) -S + xargs -n 1 -P ${BUILD_JOBS} $(xcrun_find_tool strip) -S { set +x; } 2>/dev/null fi @@ -2246,6 +2274,8 @@ if [[ "${INSTALLABLE_PACKAGE}" ]] ; then ${PLISTBUDDY_BIN} -c "Add CFBundleIdentifier string '${DARWIN_TOOLCHAIN_BUNDLE_IDENTIFIER}'" "${DARWIN_TOOLCHAIN_INFO_PLIST}" ${PLISTBUDDY_BIN} -c "Add ReportProblemURL string '${DARWIN_TOOLCHAIN_REPORT_URL}'" "${DARWIN_TOOLCHAIN_INFO_PLIST}" ${PLISTBUDDY_BIN} -c "Add OverrideEnvironment::DYLD_LIBRARY_PATH string '${DARWIN_TOOLCHAIN_INSTALL_LOCATION}/usr/lib'" "${DARWIN_TOOLCHAIN_INFO_PLIST}" + ${PLISTBUDDY_BIN} -c "Add Aliases array" "${DARWIN_TOOLCHAIN_INFO_PLIST}" + ${PLISTBUDDY_BIN} -c "Add Aliases:0 string '${DARWIN_TOOLCHAIN_ALIAS}'" "${DARWIN_TOOLCHAIN_INFO_PLIST}" chmod a+r "${DARWIN_TOOLCHAIN_INFO_PLIST}" if [[ "${DARWIN_TOOLCHAIN_APPLICATION_CERT}" ]] ; then @@ -2266,18 +2296,25 @@ if [[ "${INSTALLABLE_PACKAGE}" ]] ; then tar -c -z -f "${INSTALLABLE_PACKAGE}" --owner=0 --group=0 "${INSTALL_PREFIX/#\/}") fi if [[ "${TEST_INSTALLABLE_PACKAGE}" ]] ; then - PKG_TESTS_SOURCE_DIR="${WORKSPACE}/swift-package-tests" - PKG_TESTS_SANDBOX="/tmp/swift_package_sandbox" - LIT_EXECUTABLE_PATH="${LLVM_SOURCE_DIR}/utils/lit/lit.py" - FILECHECK_EXECUTABLE_PATH="$(build_directory_bin $deployment_target llvm)/FileCheck" + PKG_TESTS_SOURCE_DIR="${WORKSPACE}/swift-integration-tests" + PKG_TESTS_SANDBOX_PARENT="$(build_directory swift_package_sandbox none)" + + if [[ "$(uname -s)" == "Darwin" ]] ; then + PKG_TESTS_SANDBOX="${PKG_TESTS_SANDBOX_PARENT}"/"${TOOLCHAIN_PREFIX}" + else # Linux + PKG_TESTS_SANDBOX="${PKG_TESTS_SANDBOX_PARENT}" + fi - rm -rf "${PKG_TESTS_SANDBOX}" - mkdir "${PKG_TESTS_SANDBOX}" - pushd "${PKG_TESTS_SANDBOX}" + LIT_EXECUTABLE_PATH="${LLVM_SOURCE_DIR}/utils/lit/lit.py" + FILECHECK_EXECUTABLE_PATH="$(build_directory_bin ${deployment_target} llvm)/FileCheck" + echo "-- Test Installable Package --" + set -x + rm -rf "${PKG_TESTS_SANDBOX_PARENT}" + mkdir -p "${PKG_TESTS_SANDBOX}" + pushd "${PKG_TESTS_SANDBOX_PARENT}" tar xzf "${INSTALLABLE_PACKAGE}" popd - set -x (cd "${PKG_TESTS_SOURCE_DIR}" && python "${LIT_EXECUTABLE_PATH}" . -sv --param package-path="${PKG_TESTS_SANDBOX}" --param filecheck="${FILECHECK_EXECUTABLE_PATH}") { set +x; } 2>/dev/null diff --git a/utils/buildbot-release-notes.txt b/utils/buildbot-release-notes.txt deleted file mode 100644 index dc6e43265f0f9..0000000000000 --- a/utils/buildbot-release-notes.txt +++ /dev/null @@ -1,2067 +0,0 @@ -Latest ------- -* Three new doc comment fields, namely "- keyword:", "- recommended:" - and "- recommendedover:", allow Swift users to cooperate with code - completion engine to deliver more effective code completion results. - The "- keyword:" field specifies concepts that are not fully manifested in - declaration names. "- recommended:" indicates other declarations are preferred - to the one decorated; to the contrary, "- recommendedover:" indicates - the decorated declaration is preferred to those declarations whose names - are specified. - -* Designated class initializers declared as failable or throwing may now - return nil or throw an error, respectively, before the object has been - fully initialized. For example: - - class Widget : Gadget { - let complexity: Int - - init(complexity: Int, elegance: Int) throws { - if complexity > 3 { throw WidgetError.TooComplex } - self.complexity = complexity - - try super.init(elegance: elegance) - } - } - -* All slice types now have removeFirst() and removeLast() methods. - -* ArraySlice.removeFirst() now preserves element indices. - -* Global anyGenerator() functions have been changed into initializers on - AnyGenerator, making the API more intuitive and idiomatic. - -* Closures appearing inside generic types and generic methods can now be - converted to C function pointers as long as no generic type parameters - are referenced in the closure's argument list or body. A conversion of - a closure that references generic type parameters now produces a - diagnostic instead of crashing. - - (rdar://problem/22204968) - -* Anonymously-typed members of C structs and unions can now be accessed - from Swift. For example, given the following struct 'Pie', the 'crust' - and 'filling' members are now imported: - - struct Pie { - struct { bool crispy; } crust; - union { int fruit; } filling; - } - - Since Swift does not support anonymous structs, these fields are - imported as properties named 'crust' and 'filling' having nested types - named 'Pie.__Unnamed_crust' and 'Pie.__Unnamed_filling'. - - (rdar://problem/21683348) - -*** Time warp: Changes between Xcode 6.1 (Swift 1.1) through Xcode 7.1 -(Swift 2.1) have been lost. Contributions to rectify this would be -welcome. - - -2014-10-09 [Roughly Xcode 6.1, and Swift 1.1] ----------- - -* 'HeapBuffer', 'HeapBufferStorage', and - 'OnHeap' were never really useful, because their APIs were - insufficiently public. They have been replaced with a single class, - 'ManagedBuffer'. See also the new function - 'isUniquelyReferenced(x)' which is often useful in conjunction with - 'ManagedBuffer'. - -* The 'Character' enum has been turned into a struct, to avoid - exposing its internal implementation details. - -* The 'countElements' function has been renamed 'count', for better - consistency with our naming conventions. - -* Mixed-sign addition and subtraction operations, that were - unintentionally allowed in previous versions, now cause a - compilation error. - -* OS X apps can now apply the @NSApplicationMain attribute to their app delegate - class in order to generate an implicit "main" for the app. This works like - the @UIApplicationMain attribute for iOS apps. - -* Objective-C init and factory methods are now imported as failable - initializers when they can return nil. In the absence of information - about a potentially-nil result, an Objective-C init or factory - method will be imported as "init!". - - As part of this change, factory methods that have NSError** - parameters, such as +[NSString - stringWithContentsOfFile:encoding:error:], will now be imported as - (failable) initializers, e.g., - - init?(contentsOfFile path: String, - encoding: NSStringEncoding, - error: NSErrorPointer) - -* Nested classes explicitly marked @objc will now properly be included in a - target's generated header as long as the containing context is also - (implicitly or explicitly) @objc. Nested classes not explicitly marked @objc - will never be printed in the generated header, even if they extend an - Objective-C class. - -* All of the *LiteralConvertible protocols, as well as - StringInterpolationConvertible, now use initializers for their - requirements rather than static methods starting with - "convertFrom". For example, IntegerLiteralConvertible now as the - following initializer requirement: - - init(integerLiteral value: IntegerLiteralType) - - Any type that previously conformed to one of these protocols will - need to replace its "convertFromXXX" static methods with the - corresponding initializer. - -2014-09-15 ----------- - -* Initializers can now fail by returning 'nil'. A failable initializer is - declared with 'init?' (to return an explicit optional) or 'init!' (to return - an implicitly-unwrapped optional). For example, you could implement - String.toInt as a failable initializer of Int like this: - - extension Int { - init?(fromString: String) { - if let i = fromString.toInt() { - // Initialize - self = i - } else { - // Discard self and return 'nil'. - return nil - } - } - } - - The result of constructing a value using a failable initializer then becomes - optional: - - if let twentytwo = Int(fromString: "22") { - println("the number is \(twentytwo)") - } else { - println("not a number") - } - - In the current implementation, struct and enum initializers can return nil - at any point inside the initializer, but class initializers can only return - nil after all of the stored properties of the object have been initialized - and 'self.init' or 'super.init' has been called. If 'self.init' or - 'super.init' is used to delegate to a failable initializer, then the 'nil' - return is implicitly propagated through the current initializer if the - called initializer fails. - -* The RawRepresentable protocol that enums with raw types implicitly conform - to has been redefined to take advantage of failable initializers. The - "fromRaw(RawValue)" static method has been replaced with an initializer - "init?(rawValue: RawValue)", and the "toRaw()" method has been replaced with - a "rawValue" property. Enums with raw types can now be used like this: - - enum Foo: Int { case A = 0, B = 1, C = 2 } - let foo = Foo(rawValue: 2)! // formerly 'Foo.fromRaw(2)!' - println(foo.rawValue) // formerly 'foo.toRaw()' - -2014-09-02 ----------- - -* Characters can no longer be concatenated using "+". Use String(c1) + - String(c2) instead. - -2014-08-18 ---------- - -* When force-casting between arrays of class or @objc protocol types - using "a as [C]", type checking is now deferred until the moment - each element is accessed. Because bridging conversions from NSArray - are equivalent to force-casts from [NSArray], this makes certain - Array round-trips through Objective-C code O(1) instead of O(N). - -2014-08-04 ----------- - -* 'RawOptionSetType' now implements 'BitwiseOperationsType', so imported - NS_OPTIONS now support the bitwise assignment operators '|=', '&=', - and '^='. It also no longer implements 'BooleanType'; to check if an option - set is empty, compare it to 'nil'. - -* Types implementing 'BitwiseOperationsType' now automatically support - the bitwise assignment operators '|=', '&=', and '^='. - -* Optionals can now be coalesced with default values using the '??' operator. - '??' is a short-circuiting operator that takes an optional on the left and - a non-optional expression on the right. If the optional has a value, its - value is returned as a non-optional; otherwise, the expression on the right - is evaluated and returned: - - var sequence: [Int] = [] - sequence.first ?? 0 // produces 0, because sequence.first is nil - sequence.append(22) - sequence.first ?? 0 // produces 22, the value of sequence.first - -* The optional chaining '?' operator can now be mutated through, like '!'. - The assignment and the evaluation of the right-hand side of the operator - are conditional on the presence of the optional value: - - var sequences = ["fibonacci": [1, 1, 2, 3, 4], "perfect": [6, 28, 496]] - sequences["fibonacci"]?[4]++ // Increments element 4 of key "fibonacci" - sequences["perfect"]?.append(8128) // Appends to key "perfect" - - sequences["cubes"]?[3] = 3*3*3 // Does nothing; no "cubes" key - - Note that optional chaining still flows to the right, so prefix increment - operators are *not* included in the chain, so this won't type-check: - - ++sequences["fibonacci"]?[4] // Won't type check, can't '++' Int? - -2014-07-28 ----------- - -* The swift command line interface is now divided into an interactive driver - 'swift', and a batch compiler 'swiftc': - - swift [options] input-file [program-arguments] - Runs the script 'input-file' immediately, passing any program-arguments - to the script. Without any input files, invokes the repl. - - swiftc [options] input-filenames - The familiar swift compiler interface: compiles the input-files according - to the mode options like -emit-object, -emit-executable, etc. - -* For greater clarity and explicitness when bypassing the type system, - reinterpretCast has been renamed unsafeBitCast, and it has acquired - a (required) explicit type parameter. So - - let x: T = reinterpretCast(y) - - becomes - - let x = unsafeBitCast(y, T.self) - -* Because their semantics were unclear, the methods "asUnsigned" (on - the signed integer types) and "asSigned" (on the unsigned integer - types) have been replaced. The new idiom is explicit construction - of the target type using the "bitPattern:" argument label. So, - - myInt.asUnsigned() - - has become - - UInt(bitPattern: myInt) - -* To better follow Cocoa naming conventions and to encourage - immutability, The following pointer types were renamed: - - UnsafePointer => UnsafeMutablePointer - ConstUnsafePointer => UnsafePointer - AutoreleasingUnsafePointer => AutoreleasingUnsafeMutablePointer - - Note that the meaning of "UnsafePointer" has changed from mutable to - immutable. As a result, some of your code may fail to compile when - assigning to an UnsafePointer's ".memory" property. The fix is to - change your UnsafePointer into an UnsafeMutablePointer. - -* The optional unwrapping operator 'x!' can now be assigned through, and - mutating methods and operators can be applied through it: - - var x: Int! = 0 - x! = 2 - x!++ - - // Nested dictionaries can now be mutated directly: - var sequences = ["fibonacci": [1, 1, 2, 3, 0]] - sequences["fibonacci"]![4] = 5 - sequences["fibonacci"]!.append(8) - -* The @auto_closure attribute has been renamed to @autoclosure. - -* There is a new 'dynamic' declaration modifier. When applied to a method, - property, subscript, or initializer, it guarantees that references to the - declaration are always dynamically dispatched and never inlined or - devirtualized, and that the method binding can be reliably changed at runtime. - The implementation currently relies on the Objective-C runtime, so 'dynamic' - can only be applied to @objc-compatible declarations for now. '@objc' now - only makes a declaration visible to Objective-C; the compiler may now use - vtable lookup or direct access to access (non-dynamic) @objc declarations. - - class Foo { - // Always accessed by objc_msgSend - dynamic var x: Int - - // Accessed by objc_msgSend from ObjC; may be accessed by vtable - // or by static reference in Swift - @objc var y: Int - - // Not exposed to ObjC (unless Foo inherits NSObject) - var z: Int - } - - 'dynamic' enables KVO, proxying, and other advanced Cocoa features to work - reliably with Swift declarations. - -* Clang submodules can now be imported: - - import UIKit.UIGestureRecognizerSubclass - -* The numeric optimization levels -O[0-3] have been removed in favor of the - named levels -Onone and -O. - -* The -Ofast optimization flag has been renamed to -Ounchecked. We will accept - both names for now and remove -Ofast in a later build. - -* An initializer that overrides a designated initializer from its - superclass must be marked with the 'override' keyword, so that all - overrides in the language consistently require the use of - 'override'. For example: - - class A { - init() { } - } - - class B : A { - override init() { super.init() } - } - -* Required initializers are now more prominent in several ways. First, - a (non-final) class that conforms to a protocol that contains an - initializer requirement must provide a required initializer to - satisfy that requirement. This ensures that subclasses will also - conform to the protocol, and will be most visible with classes that - conform to NSCoding: - - class MyClass : NSObject, NSCoding { - required init(coder aDecoder: NSCoder!) { /*... */ } - func encodeWithCoder(aCoder: NSCoder!) { /* ... */ } - } - - Second, because 'required' places a significant requirement on all - subclasses, the 'required' keyword must be placed on overrides of a - required initializer: - - class MySubClass : MyClass { - var title: String = "Untitled" - - required init(coder aDecoder: NSCoder!) { /*... */ } - override func encodeWithCoder(aCoder: NSCoder!) { /* ... */ } - } - - Finally, required initializers can now be inherited like any other - initializer: - - class MySimpleSubClass : MyClass { } // inherits the required init(coder:). - -2014-07-21 ----------- - -* Access control has been implemented. - - - 'public' declarations can be accessed from any module. - - 'internal' declarations (the default) can be accessed from within the - current module. - - 'private' declarations can be accessed only from within the current file. - - There are still details to iron out here, but the model is in place. - The general principle is that an entity cannot be defined in terms of another - entity with less accessibility. - - Along with this, the generated header for a framework will only include - public declarations. Generated headers for applications will include public - and internal declarations. - -* CGFloat is now a distinct floating-point type that wraps either a - Float (on 32-bit architectures) or a Double (on 64-bit - architectures). It provides all of the same comparison and - arithmetic operations of Float and Double, and can be created using - numeric literals. - -* The immediate mode 'swift -i' now works for writing #! scripts that take - command line arguments. The '-i' option to the swift driver must now come at - the end of the compiler arguments, directly before the input filename. Any - arguments that come after -i and the input filename are treated as arguments - to the interpreted file and forwarded to Process.arguments. - -* Type inference for for..in loops has been improved to consider the - sequence along with the element pattern. For example, this accepts - the following loops that were previously rejected: - - for i: Int8 in 0..<10 { } - for i: Float in 0.0...10.0 { } - -* Introduced the new BooleanLiteralConvertible protocol, which allows - user-defined types to support Boolean literals. "true" and "false" - are now Boolean constants and keywords. - -* The "@final", "@lazy", "@required" and "@optional" attributes are now - considered to be declaration modifiers - they no longer require (or allow) an - @ sign. - -* The "@prefix", "@infix", and "@postfix" attributes have been changed to - declaration modifiers, so they are no longer spelled with an @ sign. Operator - declarations have been rearranged from "operator prefix +" to - "prefix operator +" for consistency. - -2014-07-03 ----------- - -* C function pointer types are now imported as CFunctionPointer, where 'T' - is a Swift function type. CFunctionPointer and COpaquePointer can be - explicitly constructed from one another, but they do not freely convert, nor - is CFunctionPointer compatible with Swift closures. - - Example: "int (*)(void)" becomes "CFunctionPointer<(Int) -> Void>". - -* The interop model for pointers in C APIs has been simplified. Most code that - calls C functions by passing arrays, UnsafePointers, or the addresses of - variables with '&x' does not need to change. However, the CConstPointer and - CMutablePointer bridging types have been removed, and functions and methods - are now imported as and overridden by taking UnsafePointer and - ConstUnsafePointer directly. Void pointers are now imported as - (Const)UnsafePointer; COpaquePointer is only imported for opaque types - now. - -* Array types are now spelled with the brackets surrounding the - element type. For example, an array of Int is written as:: - - var array: [Int] - -* Dictionary types can now be spelled with the syntax [K : V], where K - is the key type and V is the value type. For example: - - var dict: [String : Int] = ["Hello" : 1, "World" : 2] - - The type [K : V] is syntactic sugar for Dictionary; nothing - else has changed. - -* The @IBOutlet attribute no longer implicitly (and invisibly) changes the type - of the declaration it is attached to. It no longer implicitly makes variables - be an implicitly unwrapped optional and no longer defaults them to weak. - -* The \x, \u and \U escape sequences in string literals have been consolidated - into a single and less error prone \u{123456} syntax. - - -2014-06-23 ---------- - -* The half-open range operator has been renamed from ".." to "..<" to reduce - confusion. The ..< operator is precedented in Groovy (among other languages) - and makes it much more clear that it doesn't include the endpoint. - -* Class objects such as 'NSObject.self' can now be converted to 'AnyObject' and - used as object values. - -* Objective-C protocol objects such as 'NSCopying.self' can now be used as - instances of the 'Protocol' class, such as in APIs such as XPC. - -* Arrays now have full value semantics: both assignment and - initialization create a logically-distinct object - -* The "sort" function and array method modify the target in-place. A - new "sorted" function and array method are non-mutating, creating - and returning a new collection. - -2014-05-19 ----------- - -* sort, map, filter, and reduce methods on Arrays accept trailing - closures: - - let a = [5, 6, 1, 3, 9] - a.sort{ $0 > $1 } - println(a) // [9, 6, 5, 3, 1] - println(a.map{ $0 * 2 }) // [18, 12, 10, 6, 2] - println(a.map{ $0 * 2 }.filter{ $0 < 10}) // [6, 2] - println(a.reduce(1000){ $0 + $1 }) // 1024 (no kidding) - -* A lazy map() function in the standard library works on any Sequence. - Example: - - class X { - var value: Int - - init(_ value: Int) { - self.value = value - println("created X(\(value))") - } - } - - // logically, this sequence is X(0), X(1), X(2), ... X(50) - let lazyXs = map(0..50){ X($0) } - - // Prints "created X(...)" 4 times - for x in lazyXs { - if x.value == 4 { - break - } - } - -* There's a similar lazy filter() function: - - // 0, 10, 20, 30, 40 - let tens = filter(0..50) { $0 % 10 == 0 } - let tenX = map(tens){ X($0) } // 5 lazy Xs - let tenXarray = Array(tenX) // Actually creates those Xs - -* Weak pointers of classbound protocol type work now. - -* IBOutlets now default to weak pointers with implicit optional type (T!). - -* NSArray* parameters and result types of Objective-C APIs are now - imported as AnyObject[]!, i.e., an implicitly unwrapped optional - array storing AnyObject values. For example, NSView's constraints - property - - @property (readonly) NSArray *constraints; - - is now imported as - - var constraints: AnyObject[]! - - Note that one can implicitly convert between an AnyObject[] and an - NSArray (in both directions), so (for example) one can still - explicitly use NSArray if desired: - - var array: NSArray = view.constraints - - Swift arrays bridge to NSArray similarly to the way Swift - strings bridge to NSString. - -* ObjCMutablePointer has been renamed AutoreleasingUnsafePointer. - -* UnsafePointer (and AutoreleasingUnsafePointer)'s "set()" and "get()" - have been replaced with a property called "memory". - - - Previously you would write: - - val = p.get() - p.set(val) - - - Now you write: - - val = p.memory - p.memory = val - -* Removed shorthand "x as T!"; instead use "(x as T)!" - - - "x as T!" now means "x as implicitly unwrapped optional". - -* Range operators ".." and "..." have been switched. - - - 1..3 now means 1,2 - - 1...3 now means 1,2,3 - -* The pound sign (#) is now used instead of the back-tick (`) to mark - an argument name as a keyword argument, e.g., - - func moveTo(#x: Int, #y: Int) { ... } - moveTo(x: 5, y: 7) - -* Objective-C factory methods are now imported as initializers. For - example, NSColor's +colorWithRed:green:blue:alpha becomes - - init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) - - which allows an NSColor to be created as, e.g., - - NSColor(red: 0.5, green: 0.25, blue: 0.25, alpha: 0.5) - - Factory methods are identified by their kind (class methods), name - (starts with words that match the words that end the class name), - and result type (instancetype or the class type). - -* Objective-C properties of some CF type are no longer imported as Unmanaged. - -* REPL mode now uses LLDB, for a greatly-expanded set of features. The colon - prefix now treats the rest of the line as a command for LLDB, and entering - a single colon will drop you into the debugging command prompt. Most - importantly, crashes in the REPL will now drop you into debugging mode to - see what went wrong. - - If you do have a need for the previous REPL, pass -integrated-repl. - -* In a UIKit-based application, you can now eliminate your 'main.swift' file - and instead apply the '@UIApplicationMain' attribute to your - UIApplicationDelegate class. This will cause the 'main' entry point to the - application to be automatically generated as follows: - - UIApplicationMain(argc, argv, nil, - NSStringFromClass(YourApplicationDelegate.self)) - - If you need nontrivial logic in your application entry point, you can still - write out a main.swift. Note that @UIApplicationMain and main.swift are - mutually exclusive. - -2014-05-13 ----------- - -* weak pointers now work with implicitly unchecked optionals, enabling usecases - where you don't want to ! every use of a weak pointer. For example: - - weak var myView : NSView! - - of course, they still work with explicitly checked optionals like "NSView?" - -* Dictionary subscripting now takes/returns an optional type. This allows - querying a dictionary via subscripting to gracefully fail. It also enables - the idiom of removing values from a dictionary using 'dict[key] = nil'. - As part of this, 'deleteKey' is no longer available. - -* Stored properties may now be marked with the @lazy attribute, which causes - their initializer to be evaluated the first time the property is touched - instead of when the enclosing type is initialized. For example: - - func myInitializer() -> Int { println("hello\n"); return 42 } - class MyClass { - @lazy var aProperty = myInitializer() - } - - var c = MyClass() // doesn't print hello - var tmp = c.aProperty // prints hello on first access - tmp = c.aProperty // doesn't print on subsequent loads. - - c = MyClass() // doesn't print hello - c.aProperty = 57 // overwriting the value prevents it from ever running - - Because lazy properties inherently rely on mutation of the property, they - cannot be 'let's. They are currently also limited to being members of structs - and classes (they aren't allowed as local or global variables yet) and cannot - be observed with willSet/didSet yet. - -* Closures can now specify a capture list to indicate with what strength they - want to capture a value, and to bind a particular field value if they want to. - - Closure capture lists are square-bracket delimited and specified before the - (optional) argument list in a closure. Each entry may be specified as "weak" - or "unowned" to capture the value with a weak or unowned pointer, and may - contain an explicit expression if desired. Some examples: - - takeClosure { print(self.title) } // strong capture - takeClosure { [weak self] in print(self!.title) } // weak capture - takeClosure { [unowned self] in print(self.title) } // unowned capture - - You can also bind arbitrary expression to named values in the capture list. - The expression is evaluated when the closure is formed, and captured with the - specified strength. For example: - - // weak capture of "self.parent" - takeClosure { [weak tmp = self.parent] in print(tmp!.title) } - - The full form of a closure can take a signature (an argument list and - optionally a return type) if needed. To use either the capture list or the - signature, you must specify the context sensitive 'in' keyword. Here is a - (weird because there is no need for unowned) example of a closure with both: - - myNSSet.enumerateObjectsUsingBlock { [unowned self] (obj, stop) in - self.considerWorkingWith(obj) - } - -* The word "with" is now removed from the first keyword argument name - if an initialized imported from Objective-C. For example, instead of - building UIColor as: - - UIColor(withRed: r, green: g, blue: b, alpha: a) - - it will now be: - - UIColor(red: r, green: g, blue: b, alpha: a) - -* `Dictionary` can be bridged to `NSDictionary` and vice versa: - - - `NSDictionary` has an implicit conversion to `Dictionary`. It bridges in O(1), without memory allocation. - - - `Dictionary` has an implicit conversion to `NSDictionary`. - `Dictionary` bridges to `NSDictionary` iff both `K` and `V` are - bridged. Otherwise, a runtime error is raised. - - Depending on `K` and `V` the operation can be `O(1)` without memory - allocation, or `O(N)` with memory allocation. - -* Single-quoted literals are no longer recognized. Use double-quoted literals - and an explicit type annotation to define Characters and UnicodeScalars: - - var ch: Character = "a" - var us: UnicodeScalar = "a" - -2014-05-09 ----------- - -* The use of keyword arguments is now strictly enforced at the call - site. For example, consider this method along with a call to it: - - class MyColor { - func mixColorWithRed(red: Float, green: Float, blue: Float) { /* ... */ } - } - - func mix(color: MyColor, r: Float, g: Float, b: Float) { - color.mixColorWithRed(r, g, b) - } - - The compiler will now complain about the missing "green:" and - "blue:" labels, with a Fix-It to correct the code: - - color.swift:6:24: error: missing argument labels 'green:blue:' in call - color.mixColorWithRed(r, g, b) - ^ - green: blue: - - The compiler handles missing, extraneous, and incorrectly-typed - argument labels in the same manner. Recall that one can make a - parameter a keyword argument with the back-tick or remove a keyword - argument with the underscore. - - class MyColor { - func mixColor(`red: Float, green: Float, blue: Float) { /* ... */ } - func mixColorGuess(red: Float, _ green: Float, _ blue: Float) { /* ... */ } - } - - func mix(color: MyColor, r: Float, g: Float, b: Float) { - color.mixColor(red: r, green: g, blue: b) // okay: all keyword arguments - color.mixColorGuess(r, g, b) // okay: no keyword arguments - } - - Arguments cannot be re-ordered unless the corresponding parameters - have default arguments. For example, given: - - func printNumber(`number: Int, radix: Int = 10, separator: String = ",") { } - - The following three calls are acceptable because only the arguments for - defaulted parameters are re-ordered relative to each other: - - printNumber(number: 256, radix: 16, separator: "_") - printNumber(number: 256, separator: "_") - printNumber(number: 256, separator: ",", radix: 16) - - However, this call: - - printNumber(separator: ",", radix: 16, number: 256) - - results in an error due to the re-ordering: - - printnum.swift:7:40: error: argument 'number' must precede argument 'separator' - printNumber(separator: ",", radix: 16, number: 256) - ~~~~~~~~~~~~~~ ^ ~~~ - -* ";" can no longer be used to demarkate an empty case in a switch statement, - use "break" instead. - -2014-05-07 ----------- - -* The compiler's ability to diagnose many common kinds of type check errors has - improved. ("expression does not type-check" has been retired.) - -* Ranges can be formed with floating point numbers, e.g. "0.0 .. 100.0". - -* Convenience initializers are now spelled as "convenience init" instead of with - the "-> Self" syntax. For example: - - class Foo { - init(x : Int) {} // designated initializer - - convenience init() { self.init(42) } // convenience initializer - } - - You still cannot declare designated initializers in extensions, only - convenience initializers are allowed. - -* Reference types using the CoreFoundation runtime are now imported as - class types. This means that Swift will automatically manage the - lifetime of a CFStringRef the same way that it manages the lifetime - of an NSString. - - In many common cases, this will just work. Unfortunately, values - are returned from CF-style APIs in a wide variety of ways, and - unlike Objective C methods, there simply isn't enough consistency - for Swift to be able to safely apply the documented conventions - universally. The framework teams have already audited many of the - most important CF-style APIs, and those APIs should be imported - without a hitch into Swift. For all the APIs which haven't yet - been audited, we must import return types using the Unmanaged type. - This type allows the programmer to control exactly how the object - is passed. - - For example: - - // CFBundleGetAllBundles() returns an Unmanaged. - // From the documentation, we know that it returns a +0 value. - let bundles = CFBundleGetAllBundles().takeUnretainedValue() - - // CFRunLoopCopyAllModes() returns an Unmanaged. - // From the documentation, we know that it returns a +1 value. - let modes = CFRunLoopCopyAllModes(CFRunLoopGetMain()).takeRetainedValue() - - You can also use Unmanaged types to pass and return objects - indirectly, as well as to generate unbalanced retains and releases - if you really require them. - - The API of the Unmanaged type is still in flux, and your feedback - would be greatly appreciated. - -2014-05-03 ----------- - -* The @NSManaged attribute can be applied to the properties of an - NSManagedObject subclass to indicate that they should be handled by - CoreData: - - class Employee : NSManagedObject { - @NSManaged var name: String - @NSManaged var department: Department - } - -* The @weak and @unowned attributes have become context sensitive keywords - instead of attributes. To declare a weak or unowned pointer, use: - - weak var someOtherWindow : NSWindow? - unowned var someWindow : NSWindow - - ... with no @ on the weak/unowned. - -2014-04-30 ----------- - -* Swift now supports a #elseif form for build configurations, e.g.: - - #if os(OSX) - typealias SKColor = NSColor - #elseif os(iOS) - typealias SKColor = UIColor - #else - typealias SKColor = Green - #endif - -* You can now use the "true" and "false" constants in build configurations, - allowing you to emulate the C idioms of "#if 0" (but spelled "#if false"). - -* 'break' now breaks out of switch statements. - -* It is no longer possible to specify "@mutating" as an attribute, you may only - use it as a keyword, e.g.: - - struct Pair { - var x, y : Int - mutating func nuke() { x = 0; y = 0 } - } - - The former "@!mutating" syntax used to mark setters as non-mutating is now - spelled with the "nonmutating" keyword. Both mutating and nonmutating are - context sensitive keywords. - -* NSLog is now available from Swift code. - -* The parser now correctly handles expressions like "var x = Int[]()" to - create an empty array of integers. Previously you'd have to use syntax like - "Array()" to get this. Now that this is all working, please prefer to - use Int[] consistently instead of Array. - -* 'Character' is the new character literal type: - - var x = 'a' // Infers 'Character' type - - You can force inference of UnicodeScalar like this: - - var scalar: UnicodeScalar = 'a' - - 'Character' type represents a Unicode extended grapheme cluster (to put it - simply, a grapheme cluster is what users think of as a character: a base plus - any combining marks, or other cases explained in Unicode Standard Annex #29). - -2014-04-22 ----------- - -* Loops and switch statements can now carry labels, and you can break/continue - to those labels. These use conventional C-style label syntax, and should be - dedented relative to the code they are in. An example: - - func breakContinue(x : Int) -> Int { - Outer: - for a in 0..1000 { - - Switch: - switch x { - case 42: break Outer - case 97: continue Outer - case 102: break Switch - case 13: continue // continue always works on loops. - case 139: break // break will break out of the switch (but see below) - } - } - } - -* We are changing the behavior of 'break' to provide C-style semantics, to allow - breaking out of a switch statement. Previously, break completely ignored - switches so that it would break out of the nearest loop. In the example above, - 'case 139' would break out of the "Outer" loop, not the "Switch". - - In order to avoid breaking existing code, we're making this a compile time - error instead of a silent behavior change. If you need a solution for the - previous behavior, use labeled break. - - This error will be removed in a week or two. - -* Cocoa methods and properties that are annotated with the - NS_RETURNS_INNER_POINTER attribute, including -[NSData bytes] and - -[{NS,UI}Color CGColor], are now safe to use and follow the same lifetime - extension semantics as ARC. - -2014-04-18 ----------- -* Enabling/disabling of asserts - - assert(condition, msg) - - is enabled/disabled dependent on the optimization level. In debug mode at - "-O0" asserts are enabled. At higher optimization levels asserts are disabled - and no code is generated for them. However, asserts are always type checked - even at higher optimization levels. - - Alternatively, assertions can be disabled/enabled by using the frontend flag - "-assert-config Debug", or "-assert-config Release". - -* Added optimization flag "-Ofast". It disables all assertions (assert), and - runtime overflow and type checks. - -* The "selector-style" function and initializer declaration syntax is - being phased out. For example, this: - - init withRed(red: CGFloat) green(CGFloat) blue(CGFloat) alpha(CGFloat) - - will now be written as: - - init(withRed red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) - - For each parameter, one can have both an argument API name (i.e., - "withRed", which comes first and is used at the call site) and an - internal parameter name that follows it (i.e. "red", which comes - second and is used in the implementation). When the two names are - the same, one can simply write the name once and it will be used for - both roles (as with "green", "blue", and "alpha" above). The - underscore ("_") can be used to mean "no name", as when the - following function/method: - - func murderInRoom(room:String) withWeapon(weapon: String) - - is translated to: - - func murderInRoom(_ room: String, withWeapon weapon: String) - - The compiler now complains when it sees the selector-style syntax - and will provide Fix-Its to rewrite to the newer syntax. - - Note that the final form of selector syntax is still being hammered - out, but only having one declaration syntax, which will be very - close to this, is a known. - -* Stored properties can now be marked with the @NSCopying attribute, which - causes their setter to be synthesized with a copy to copyWithZone:. This may - only be used with types that conform to the NSCopying protocol, or option - types thereof. For example: - - @NSCopying var myURL : NSURL - - This fills the same niche as the (copy) attribute on Objective-C properties. - - -2014-04-16 ----------- - -* Optional variables and properties are now default-initialized to nil: - - class MyClass { - var cachedTitle: String? // "= nil" is implied - } - -* @IBOutlet has been improved in a few ways: - - - IBOutlets can now be @unchecked optional. - - - An IBOutlet declared as non-optional, i.e., - - @IBOutlet var button: NSButton - - will be treated as an @unchecked optional. This is considered to - be the best practice way to write an outlet, unless you want to explicitly - handle the null case - in which case, use "NSButton?" as the type. Either - way, the "= nil" that was formerly required is now implicit. - -* The precedence of 'is' and 'as' is now higher than comparisons, allowing the - following sorts of things to be written without parens: - - if x is NSButton && y is NSButtonCell { ... } - - if 3/4 as Float == 6/8 as Float { ... } - -* Objective-C blocks are now transparently bridged to Swift closures. You never - have to write @objc_block when writing Objective-C-compatible methods anymore. - Block parameters are now imported as unchecked optional closure types, - allowing 'nil' to be passed. - -2014-04-09 ----------- - -* Dictionary changes: - - - Elements are now tuples, so you can write - - for (k, v) in d { - // ... - } - - - "keys" and "values" properties, which are Collections projecting - the corresponding aspect of each element. Dictionary indices are - usable with their keys and values properties, so: - - for i in indices(d) { - let (k, v) = d[i] - assert(k == d.keys[i]) - assert(v == d.values[i]) - } - -* Semicolon can be used as a single no-op statement in otherwise empty cases in - switch statements: - - switch x { - case 1, 2, 3: - print("x is 1, 2 or 3") - default: - ; - } - -* 'override' is now a context sensitive keyword, instead of an attribute: - - class Base { - var property: Int { return 0 } - func instanceFunc() {} - class func classFunc() {} - } - class Derived : Base { - override var property: Int { return 1 } - override func instanceFunc() {} - override class func classFunc() {} - } - -2014-04-02 ----------- - -* Prefix splitting for imported enums has been revised again due to feedback: - - If stripping off a prefix would leave an invalid identifier (like "10_4"), - leave one more word in the result than would otherwise be there - ("Behavior10_4"). - - If all enumerators have a 'k' prefix (for "constant") and the enum doesn't, - the 'k' should not be considered when finding the common prefix. - - If the enum name is a plural (like "NSSomethingOptions") and the enumerator - names use the singular form ("NSSomethingOptionMagic"), this is considered - a matching prefix (but only if nothing follows the plural). - -* Cocoa APIs that take pointers to plain C types as arguments now get imported - as taking the new 'CMutablePointer' and 'CConstPointer' types instead - of 'UnsafePointer'. These new types allow implicit conversions from - Swift 'inout' parameters and from Swift arrays: - - let rgb = CGColorSpaceCreateDeviceRGB() - // CGColorRef CGColorCreate(CGColorSpaceRef, const CGFloat*); - let white = CGColorCreate(rgb, [1.0, 1.0, 1.0]) - - var s = 0.0, c = 0.0 - // void sincos(double, double*, double*); - sincos(M_PI/2, &s, &c) - - Pointers to pointers to ObjC classes, such as 'NSError**', get imported as - 'ObjCMutablePointer'. This type doesn't work with arrays, but - accepts inouts or 'nil': - - var error: NSError? = nil - let words = NSString.stringWithContentsOfFile("/usr/share/dict/words", - encoding: .UTF8StringEncoding, - error: &error) - - Void pointer parameters can be passed an array or inout of any type: - - // + (NSData*)dataWithBytes:(const void*)bytes length:(NSUInteger)length; - let data = NSData.dataWithBytes([1.5, 2.25, 3.125], - length: sizeof(Double.self) * 3) - var fromData = [0.0, 0.0, 0.0] - // - (void)getBytes:(void*)bytes length:(NSUInteger)length; - data.getBytes(&fromData, length: sizeof(Double.self) * 3) - - Note that we don't know whether an API reads or writes the C pointer, so - you need to explicitly initialize values (like "s" and "c" above) even if - you know that the API overwrites them. - - This pointer bridging only applies to arguments, and only works with well- - behaved C and ObjC APIs that don't keep the pointers they receive as - arguments around or do other dirty pointer tricks. Nonstandard use of pointer - arguments still requires UnsafePointer. - -* Objective-C pointer types now get imported by default as the '@unchecked T?' - optional type. Swift class types no longer implicitly include 'nil'. - - A value of '@unchecked T?' can be implicitly used as a value of 'T'. - Swift will implicitly cause a reliable failure if the value is 'nil', - rather than introducing undefined behavior (as in Objective-C ivar - accesses or everything in C/C++) or silently ignoring the operation - (as in Objective-C message sends). - - A value of '@unchecked T?' can also be implicitly used as a value of 'T?', - allowing you explicitly handle the case of a 'nil' value. For example, - if you would like to just silently ignore a message send a la Objective-C, - you can use the postfix '?' operator like so: - - fieldsForKeys[kHeroFieldKey]?.setEditable(true) - - This design allows you to isolate and handle 'nil' values in Swift code - without requiring excessive "bookkeeping" boilerplate to use values that - you expect to be non-nil. - - For now, we will continue to import C pointers as non-optional - UnsafePointer and C*Pointer types; that will be evaluated separately. - - We intend to provide attributes for Clang to allow APIs to opt in to - importing specific parameters, return types, etc. as either the - explicit optional type 'T?' or the simple non-optional type 'T'. - -* The "separated" call syntax, i.e., - - NSColor.colorWithRed(r) green(g) blue(b) alpha(a) - UIColor.init withRed(r) green(g) blue(b) alpha(a) - - is being removed. The compiler will now produce an error and provide - Fix-Its to rewrite calls to the "keyword-argument" syntax: - - NSColor.colorWithRed(r, green: g, blue: b, alpha: a) - UIColor(withRed: r, green:g, blue:b, alpha: a) - -* The 'objc' attribute now optionally accepts a name, which can be - used to provide the name for an entity as seen in Objective-C. For - example: - - class MyType { - var enabled: Bool { - @objc(isEnabled) get { - // ... - } - } - } - - The @objc attribute can be used to name initializers, methods, - getters, setters, classes, and protocols. - -* Methods, properties and subscripts in classes can now be marked with the - @final attribute. This attribute prevents overriding the declaration in any - subclass, and provides better performance (since dynamic dispatch is avoided - in many cases). - - -2014-03-26 ----------- - -* Attributes on declarations are no longer comma separated. - - Old syntax: - - @_silgen_name("foo"), @objc func bar() {} - - New syntax: - - @_silgen_name("foo") @objc - - - The ',' was vestigial when the attribute syntax consisted of bracked lists. - -* 'switch' now always requires a statement after a 'case' or 'default'. - - Old syntax: - - switch x { - case .A: - case .B(1): - println(".A or .B(1)") - default: - // Ignore it. - } - - New syntax: - - switch x { - case .A, .B(1): - println(".A or .B(1)") - default: - () // Ignore it. - } - - The following syntax can be used to introduce guard expressions for patterns - inside the 'case': - - switch x { - case .A where isFoo(), - .B(1) where isBar(): - ... - } - -* Observing properties can now @override properties in a base class, so you can - observe changes that happen to them. - - class MyAwesomeView : SomeBasicView { - @override - var enabled : Bool { - didSet { - println("Something changed") - } - } - ... - } - - Observing properties still invoke the base class getter/setter (or storage) - when accessed. - - -* An 'as' cast can now be forced using the postfix '!' operator without using - parens: - - class B {} - class D {} - - let b: B = D() - - // Before - let d1: D = (b as D)! - // After - let d2: D = b as D! - - Casts can also be chained without parens: - - // Before - let b2: B = (((D() as B) as D)!) as B - // After - let b3: B = D() as B as D! as B - -* 'as' can now be used in 'switch' cases to match the result of a checked cast: - - func printHand(hand: Any) { - switch hand { - case 1 as Int: - print("ace") - case 11 as Int: - print("jack") - case 12 as Int: - print("queen") - case 13 as Int: - print("king") - case let numberCard as Int: - print("\(numberCard)") - case let (a, b) as (Int, Int) where a == b: - print("two ") - printHand(a) - print("s") - case let (a, b) as (Int, Int): - printHand(a) - print(" and a ") - printHand(b) - case let (a, b, c) as (Int, Int, Int) where a == b && b == c: - print("three ") - printHand(a) - print("s") - case let (a, b, c) as (Int, Int, Int): - printHand(a) - print(", ") - printHand(b) - print(", and a ") - printHand(c) - default: - print("unknown hand") - } - } - printHand(1, 1, 1) // prints "three aces" - printHand(12, 13) // prints "queen and a king" - -* Enums and option sets imported from C/Objective-C still strip common - prefixes, but the name of the enum itself is now taken into consideration as - well. This keeps us from dropping important parts of a name that happen to be - shared by all members. - - // NSFileManager.h - typedef NS_OPTIONS(NSUInteger, NSDirectoryEnumerationOptions) { - NSDirectoryEnumerationSkipsSubdirectoryDescendants = 1UL << 0, - NSDirectoryEnumerationSkipsPackageDescendants = 1UL << 1, - NSDirectoryEnumerationSkipsHiddenFiles = 1UL << 2 - } NS_ENUM_AVAILABLE(10_6, 4_0); - - // Swift - let opts: NSDirectoryEnumerationOptions = .SkipsPackageDescendants - -* Init methods in Objective-C protocols are now imported as - initializers. To conform to NSCoding, you will now need to provide - - init withCoder(aDecoder: NSCoder) { ... } - - rather than - - func initWithCoder(aDecoder: NSCoder) { ... } - - -2014-03-19 ----------- - -* When a class provides no initializers of its own but has default - values for all of its stored properties, it will automatically - inherit all of the initializers of its superclass. For example: - - class Document { - var title: String - - init() -> Self { - self.init(withTitle: "Default title") - } - - init withTitle(title: String) { - self.title = title - } - } - - class VersionedDocument : Document { - var version = 0 - - // inherits 'init' and 'init withTitle:' from Document - } - - When one does provide a designated initializer in a subclass, as in - the following example: - - class SecureDocument : Document { - var key: CryptoKey - - init withKey(key: CryptoKey) -> Self { - self.init(withKey: key, title: "Default title") - } - - init withKey(key: CryptoKey) title(String) { - self.key = key - super.init(withTitle: title) - } - } - - the compiler emits Objective-C method stubs for all of the - designated initializers of the parent class that will abort at - runtime if called, and which indicate which initializer needs to be - implemented. This provides memory safety for cases where an - Objective-C initializer (such as -[Document init] in this example) - appears to be inherited, but isn't actually implemented. - -* 'nil' may now be used as a Selector value. This allows calls to Cocoa methods that accept `nil` selectors. - -* [] and [:] can now be used as the empty array and dictionary literal, - respectively. Because these carry no information about their element types, - they may only be used in a context that provides this information through type - inference (e.g. when passing a function argument). - -* Properties defined in classes are now dynamically dispatched and can be - overriden with @override. Currently @override only works with computed properties - overriding other computed properties, but this will be enhanced in coming weeks. - - -2014-03-12 ----------- - -* The 'didSet' accessor of an observing property now gets passed in the old value, - so you can easily implement an action for when a property changes value. For - example: - - class MyAwesomeView : UIView { - var enabled : Bool = false { - didSet(oldValue): - if oldValue != enabled { - self.needsDisplay = true - } - } - ... - } - -* The implicit argument name for set and willSet property specifiers has been - renamed from "(value)" to "(newValue)". For example: - - var i : Int { - get { - return 42 - } - set { // defaults to (newValue) instead of (value) - print(newValue) - } - } - -* The magic identifier __FUNCTION__ can now be used to get the name of the - current function as a string. Like __FILE__ and __LINE__, if __FUNCTION__ - is used as a default argument, the function name of the caller is passed as - the argument. - - func malkovich() { - println(__FUNCTION__) - } - malkovich() // prints "malkovich" - - func nameCaller(name: String = __FUNCTION__) -> String { - return name - } - - func foo() { - println(nameCaller()) // prints "foo" - } - - func foo(x: Int) bar(y: Int) { - println(nameCaller()) // prints "foo:bar:" - } - - At top level, __FUNCTION__ gives the module name: - - println(nameCaller()) // prints your module name - -* Selector-style methods can now be referenced without applying arguments - using member syntax "foo.bar:bas:", for instance, to test for the availability - of an optional protocol method: - - func getFrameOfObjectValueForColumn(ds: NSTableViewDataSource, - tableView: NSTableView, - column: NSTableColumn, - row: Int) -> AnyObject? { - if let getObjectValue = ds.tableView:objectValueForTableColumn:row: { - return getObjectValue(tableView, column, row) - } - return nil - } - - * The compiler now warns about cases where a variable is inferred to have - AnyObject, AnyClass, or "()" type, since type inferrence can turn a simple - mistake (e.g. failing to cast an AnyObject when you meant to) into something - with ripple effects. Here is a simple example: - - t.swift:4:5: warning: variable 'fn' inferred to have type '()', which may be unexpected - var fn = abort() - ^ - t.swift:4:5: note: add an explicit type annotation to silence this warning - var fn = abort() - ^ - : () - - If you actually did intend to declare a variable of one of these types, you - can silence this warning by adding an explicit type (indicated by the Fixit). - See rdar://15263687 and rdar://16252090 for more rationale. - -* 'x.type' has been renamed to 'x.dynamicType', and you can use 'type' as a - regular identifier again. - -2014-03-05 ----------- - -* C macros that expand to a single constant string are now imported as global - constants. Normal string literals are imported as CString; NSString literals - are imported as String. - -* All values now have a 'self' property, exactly equivalent to the value - itself: - - let x = 0 - let x2 = x.self - - Types also have a 'self' property that is the type object for that - type: - - let theClass = NSObject.self - let theObj = theClass() - - References to type names are now disallowed outside of a constructor call - or member reference; to get a type object as a value, "T.self" is required. - This prevents the mistake of intending to construct an instance of a - class but forgetting the parens and ending up with the class object instead: - - let x = MyObject // oops, I meant MyObject()... - return x.description() // ...and I accidentally called +description - // instead of -description - -* Initializers are now classified as "designated initializers", which - are responsible for initializing the current class object and - chaining via 'super.init', and "convenience initializers", which - delegate to another initializer and can be inherited. For example: - - class A { - var str: String - - init() -> Self { // convenience initializer - self.init(withString: "hello") - } - - init withString(str: String) { // designated initializer - self.str = str - } - } - - When a subclass overrides all of its superclass's designated - initializers, the convenience initializers are inherited: - - class B { - init withString(str: String) { // designated initializer - super.init(withString: str) - } - - // inherits A.init() - } - - Objective-C classes that provide NS_DESIGNATED_INITIALIZER - annotations will have their init methods mapped to designated - initializers or convenience initializers as appropriate; Objective-C - classes without NS_DESIGNATED_INITIALIZER annotations have all of - their init methods imported as designated initializers, which is - safe (but can be verbose for subclasses). Note that the syntax and - terminology is still somewhat in flux. - -* Initializers can now be marked as 'required' with an attribute, - meaning that every subclass is required to provide that initializer - either directly or by inheriting it from a superclass. To construct - - class View { - @required init withFrame(frame: CGRect) { ... } - } - - func buildView(subclassObj: View.Type, frame: CGRect) -> View { - return subclassObj(withFrame: frame) - } - - class MyView : View { - @required init withFrame(frame: CGRect) { - super.init(withFrame: frame) - } - } - - class MyOtherView : View { - // error: must override init withFrame(CGRect). - } - -* Properties in Objective-C protocols are now correctly imported as properties. - (Previously the getter and setter were imported as methods.) - -* Simple enums with no payloads, including NS_ENUMs imported - from Cocoa, now implicitly conform to the Equatable and Hashable protocols. - This means they can be compared with the '==' and '!=' operators and can - be used as Dictionary keys: - - enum Flavor { - case Lemon, Banana, Cherry - } - - assert(Flavor.Lemon == .Lemon) - assert(Flavor.Banana != .Lemon) - - struct Profile { - var sweet, sour: Bool - } - - let flavorProfiles: Dictionary = [ - .Lemon: Profile(sweet: false, sour: true ), - .Banana: Profile(sweet: true, sour: false), - .Cherry: Profile(sweet: true, sour: true ), - ] - assert(flavorProfiles[.Lemon].sour) - -* 'val' has been removed. Long live 'let'! - -* Values whose names clash with Swift keywords, such as Cocoa methods or - properties named "class", "protocol", "type", etc., can now be defined and - accessed by wrapping reserved keywords in backticks to suppress their builtin - meaning: - - let `class` = 0 - let `type` = 1 - let `protocol` = 2 - println(`class`) - println(`type`) - println(`protocol`) - - func foo(Int) `class`(Int) {} - foo(0, `class`: 1) - -2014-02-26 ----------- - -* The 'override' attribute is now required when overriding a method, - property, or subscript from a superclass. For example: - - class A { - func foo() { } - } - - class B : A { - @override func foo() { } // 'override' is required here - } - -* We're renaming 'val' back to 'let'. The compiler accepts both for this week, - next week it will just accept 'let'. Please migrate your code this week, sorry - for the back and forth on this. - -* Swift now supports "#if", "#else" and "#endif" blocks, along with target - configuration expressions, to allow for conditional compilation within - declaration and statement contexts. - - Target configurations represent certain static information about the - compile-time build environment. They are implicit, hard-wired into the - compiler, and can only be referenced within the conditional expression of an - "#if" block. - - Target configurations are tested against their values via a pseudo-function - invocation expression, taking a single argument expressed as an identitifer. - The argument represents certain static build-time information. - - There are currently two supported target configurations: - "os", which can have the values OSX or iOS - "arch", which can have the values i386, x86_64, arm and arm64 - - Within the context of an "#if" block's conditional expression, a target - configuration expression can evaluate to either 'true' or 'false'. - - For example: - - #if arch(x86_64) - println("Building for x86_64") - #else - println("Not building for x86_64") - #endif - - class C { - #if os(OSX) - func foo() { - // OSX stuff goes here - } - #else - func foo() { - // non-OSX stuff goes here - } - #endif - } - - The conditional expression of an "#if" block can be composed of one or more of - the following expression types: - - A unary expression, using '!' - - A binary expression, using '&&' or '||' - - A parenthesized expression - - A target configuration expression - - For example: - - #if os(iOS) && !arch(I386) - ... - #endif - - Note that #if/#else/#endif blocks do not constitute a preprocessor, and must - form valid and complete expressions or statements. Hence, the following - produces a parser error: - - class C { - - #if os(iOS) - func foo() {} - } - #else - func bar() {} - func baz() {} - } - #endif - - Also note that "active" code will be parsed, typechecked and emitted, while - "inactive" code will only be parsed. This is why code in an inactive #if or - #else block will produce parser errors for malformed code. This allows the - compiler to detect basic errors in inactive regions. - - This is the first step to getting functionality parity with the important - subset of the C preprocessor. Further refinements are planned for later. - -* Swift now has both fully-closed ranges, which include their endpoint, and - half-open ranges, which don't. - - (swift) for x in 0...5 { print(x) } ; print('\n') // half-open range - 01234 - (swift) for x in 0..5 { print(x) } ; print('\n') // fully-closed range - 012345 - -* Property accessors have a new brace-based syntax, instead of using the former - "label like" syntax. The new syntax is: - - var computedProperty: Int { - get { - return _storage - } - set { - _storage = value - } - } - - var implicitGet: Int { // This form still works. - return 42 - } - - var storedPropertyWithObservingAccessors: Int = 0 { - willSet { ... } - didSet { ... } - } - -* Properties and subscripts now work in protocols, allowing you to do things - like: - - protocol Subscriptable { - subscript(idx1: Int, idx2: Int) -> Int { get set } - var prop: Int { get } - } - - func foo(s: Subscriptable) { - return s.prop + s[42, 19] - } - - These can be used for generic algorithms now as well. - -* The syntax for referring to the type of a type, 'T.metatype', has been - changed to 'T.Type'. The syntax for getting the type of a value, 'typeof(x)', - has been changed to 'x.type'. - -* 'DynamicSelf' is now called 'Self'; the semantics are unchanged. - -* 'destructor' has been replaced with 'deinit', to emphasize that it - is related to 'init'. We will refer to these as - 'deinitializers'. We've also dropped the parentheses, i.e.: - - class MyClass { - deinit { - // release any resources we might have acquired, etc. - } - } - -* Class methods defined within extensions of Objective-C classes can - now refer to 'self', including using 'instancetype' methods. As a - result, NSMutableString, NSMutableArray, and NSMutableDictionary - objects can now be created with their respective literals, i.e., - - var dict: NSMutableDictionary = ["a" : 1, "b" : 2] - - -2014-02-19 ----------- - -* The "Stream" protocol has been renamed back to "Generator," which is - precedented in other languages and causes less confusion with I/O - streaming. - -* The "type" keyword was split into two: "static" and "class". One can define - static functions and static properties in structs and enums like this: - - struct S { - static func foo() {} - static var bar: Int = 0 - } - enum E { - static func foo() {} - } - - "class" keyword allows one to define class properties and class methods in - classes and protocols: - - class C { - class func foo() {} - class var bar: Int = 0 - } - protocol P { - class func foo() {} - class var bar: Int = 0 - } - - When using "class" and "static" in the extension, the choice of keyword - depends on the type being extended: - - extension S { - static func baz() {} - } - extension C { - class func baz() {} - } - -* The 'let' keyword is no longer recognized. Please move to 'val'. - -* The standard library has been renamed to 'Swift' (instead of 'swift') to be - more consistent with other modules on our platforms. - -* 'NSInteger' and other types that are layout-compatible with Swift standard - library types are now imported directly as those standard library types. - -* Optional types now support a convenience method named "cache" to cache the - result of a closure. For example: - - class Foo { - var _lazyProperty: Int? - var property: Int { - return _lazyProperty.cache { computeLazyProperty() } - } - } - -2014-02-12 ----------- - -* We are experimenting with a new message send syntax. For example: - - SKAction.colorizeWithColor(SKColor.whiteColor()) colorBlendFactor(1.0) duration(0.0) - - When the message send is too long to fit on a single line, subsequent lines - must be indented from the start of the statement or declaration. For - example, this is a single message send: - - SKAction.colorizeWithColor(SKColor.whiteColor()) - colorBlendFactor(1.0) - duration(0.0) - - while this is a message send to colorizeWithColor: followed by calls - to 'colorBlendFactor' and 'duration' (on self or to a global function): - - SKAction.colorizeWithColor(SKColor.whiteColor()) - colorBlendFactor(1.0) // call to 'colorBlendFactor' - duration(0.0) // call to 'duration' - -* We are renaming the 'let' keyword to 'val'. The 'let' keyword didn't work - out primarily because it is not a noun, so "defining a let" never sounded - right. We chose 'val' over 'const' and other options because 'var' and 'val - have similar semantics (making syntactic similarity useful), because 'const' - has varied and sordid connotations in C that we don't want to bring over, and - because we don't want to punish the "preferred" case with a longer keyword. - - For migration purposes, the compiler now accepts 'let' and 'val' as synonyms, - 'let' will be removed next week. - -* Selector arguments in function arguments with only a type are now implicitly - named after the selector chunk that contains them. For example, instead of: - - func addIntsWithFirst(first : Int) second(second : Int) -> Int { - return first+second - } - - you can now write: - - func addIntsWithFirst(first : Int) second(Int) -> Int { - return first+second - } - - if you want to explicitly want to ignore an argument, it is recommended that - you continue to use the "_" to discard it, as in: - - func addIntsWithFirst(first : Int) second(_ : Int) -> Int {...} - -* The @inout attribute in argument lists has been promoted to a - context-sensitive keyword. Where before you might have written: - - func swap(a : @inout T, b : @inout T) { - (a,b) = (b,a) - } - - You are now required to write: - func swap(inout a : T, inout b : T) { - (a,b) = (b,a) - } - - We made this change because "inout" is a fundamental part of the type - system, which attributes are a poor match for. The inout keyword is - also orthogonal to the var and let keywords (which may be specified in - the same place), so it fits naturally there. - -* The "@mutating" attribute (which can be used on functions in structs, - enums, and protocols) has been promoted to a context-sensitive keyword. - Mutating struct methods are now written as: - struct SomeStruct { - mutating func f() {} - } - -* Half-open ranges (those that don't include their endpoint) are now - spelled with three '.'s instead of two, for consistency with Ruby. - - (swift) for x in 0...5 { print(x) } ; print('\n') // new syntax - 01234 - - Next week, we'll introduce a fully-closed range which does include - its endpoint. This will provide: - - (swift) for x in 0..5 { print(x) } ; print('\n') // coming soon - 012345 - - These changes are being released separately so that users have a - chance to update their code before its semantics changes. - -* Objective-C properties with custom getters/setters are now imported - into Swift as properties. For example, the Objective-C property - - @property (getter=isEnabled) BOOL enabled; - - was previously imported as getter (isEnabled) and setter - (setEnabled) methods. Now, it is imported as a property (enabled). - -* didSet/willSet properties may now have an initial value specified: - - class MyAwesomeView : UIView { - var enabled : Bool = false { // Initial value. - didSet: self.needsDisplay = true - } - ... - } - - they can also be used as non-member properties now, e.g. as a global - variable or a local variable in a function. - -* Objective-C instancetype methods are now imported as methods that - return Swift's "DynamicSelf" type. While DynamicSelf is not - generally useful for defining methods in Swift, importing to it - eliminates the need for casting with the numerous instancetype APIs, - e.g., - - let tileNode: SKSpriteNode = SKSpriteNode.spriteNodeWithTexture(tileAtlas.textureNamed("tile\(tileNumber).png"))! - - becomes - - let tileNode = SKSpriteNode.spriteNodeWithTexture(tileAtlas.textureNamed("tile\(tileNumber).png")) - - DynamicSelf will become more interesting in the coming weeks. - -2014-02-05 ----------- - -* 'if' and 'while' statements can now conditionally bind variables. If the - condition of an 'if' or 'while' statement is a 'let' declaration, then the - right-hand expression is evaluated as an Optional value, and control flow - proceeds by considering the binding to be true if the Optional contains a - value, or false if it is empty, and the variables are available in the true - branch. This allows for elegant testing of dynamic types, methods, nullable - pointers, and other Optional things: - - class B : NSObject {} - class D : B { - func foo() { println("we have a D") } - } - var b: B = D() - if let d = b as D { - d.foo() - } - var id: AnyObject = D() - if let foo = id.foo { - foo() - } - -* When referring to a member of an 'AnyObject' (or 'AnyClass') object - and using it directly (such as calling it, subscripting, or - accessing a property on it), one no longer has to write the '?' or - '!'. The run-time check will be performed implicitly. For example: - - func doSomethingOnViews(views: NSArray) { - for view in views { - view.updateLayer() // no '!' needed - } - } - - Note that one can still test whether the member is available at - runtime using '?', testing the optional result, or conditionally - binding a variable to the resulting member. - -* The "swift" command line tool can now create executables and libraries - directly, just like Clang. Use "swift main.swift" to create an executable and - "swift -emit-library -o foo.dylib foo.swift" to create a library. - -* Object files emitted by Swift are not debuggable on their own, even if you - compiled them with the "-g" option. This was already true if you had multiple - files in your project. To produce a debuggable Swift binary from the command - line, you must compile and link in a single step with "swift", or pass object - files AND swiftmodule files back into "swift" after compilation. - (Or use Xcode.) - -* 'import' will no longer import other source files, only built modules. - -* The current directory is no longer implicitly an import path. Use "-I ." if - you have modules in your current directory. - - -2014-01-29 ----------- - -* Properties in structs and classes may now have "willSet:" and "didSet:" - observing accessors defined on them: - - For example, where before you may have written something like this in a class: - - class MyAwesomeView : UIView { - var _enabled : Bool // storage - var enabled : Bool { // computed property - get: - return _enabled - set: - _enabled = value - self.needDisplay = true - } - ... - } - - you can now simply write: - - class MyAwesomeView : UIView { - var enabled : Bool { // Has storage & observing methods - didSet: self.needDisplay = true - } - ... - } - - Similarly, if you want notification before the value is stored, you can use - willSet, which gets the incoming value before it is stored: - - var x : Int { - willSet(value): // value is the default and may be elided, as with set: - println("changing from \(x) to \(value)") - didSet: - println("we've got a value of \(x) now.\n") - } - - The willSet/didSet observers are triggered on any store to the property, - except stores from init(), destructors, or from within the observers - themselves. - - Overall, a property now may either be "stored" (the default), "computed" - (have a get: and optionally a set: specifier), or a observed - (willSet/didSet) property. It is not possible to have a custom getter - or setter on a observed property, since they have storage. - - Two known-missing bits are: - didSet/willSet variables need to allow initializers - support non-member didset/willset properties - - Because of the first one, for now, you need to explicitly store an initial - value to the property in your init() method. - -* Objective-C properties with custom getter or setter names are (temporarily) - not imported into Swift; the getter and setter will be imported individually - as methods instead. Previously, they would appear as properties within the - Objective-C class, but attempting to use the accessor with the customized - name would result in a crash. - - The long-term fix is tracked as . - -* Computed 'type' properties (that is, properties of types, rather - than of values of the type) are now permitted on classes, on generic - structs and enums, and in extensions. Stored 'type' properties in - these contexts remain unimplemented. - - The implementation of stored 'type' properties is tracked as - (for classes) and - (for generic types). - -* The following command-line flags have been deprecated in favor of new - spellings. The old spellings will be removed in the following week's build: - - -emit-llvm -> -emit-ir - -triple -> -target - -serialize-diagnostics -> -serialize-diagnostics-path - -* Imported NS_OPTIONS types now have a default initializer which produces a - value with no options set. They can also be initialized to the empty set with - 'nil'. These are equivalent: - - var x = NSMatchingOptions() - var y: NSMatchingOptions = nil - - -Release notes for older releases are available at - diff --git a/utils/cmpcodesize b/utils/cmpcodesize deleted file mode 100755 index f197b184bc150..0000000000000 --- a/utils/cmpcodesize +++ /dev/null @@ -1,414 +0,0 @@ -#!/usr/bin/env python - -import re -import sys -import os -import os.path -import glob -import subprocess -import collections -from operator import itemgetter - -def help(): - print """\ -cmpcodesize [options] [--] - -Compares code sizes of "new" files, taking "old" files as a reference. - -Options: - -a Show sizes of additional sections - -c Show functions by category - -l List all functions (can be a very long list) - -s Summarize the sizes of multiple files instead of listing each file separatly - -Environment variables: - SWIFT_NEW_BUILDDIR The old build-dir -E.g. $HOME/swift-work/build/Ninja-ReleaseAssert+stdlib-Release/swift-macosx-x86_64 - SWIFT_OLD_BUILDDIR The new build-dir -E.g. $HOME/swift-reference/build/Ninja-ReleaseAssert+stdlib-Release/swift-macosx-x86_64 - -How to specify files: -1) No files: - Compares codesize of the PerfTests_* executables and the swiftCore dylib in the new and old build-dirs. - Example: - cmpcodesize - -2) One ore more pathes relative to the build-dirs (can be a pattern): - Compares that files in the new and old build-dirs. - Aliases: - O => bin/PerfTests_O - Ounchecked => bin/PerfTests_Ounchecked - Onone => bin/PerfTests_Onone - dylib => lib/swift/macosx/x86_64/libswiftCore.dylib - Examples: - cmpcodesize Onone - cmpcodesize benchmark/PerfTestSuite/O/*.o - -3) Two files: - Compares these two files (the first is the old file). - Example: - cmpcodesize test.o newversion.o - -4) Two lists of files, separated by '--': - Compares a set a files. - Example: - cmpcodesize olddir/*.o -- newdir/*.o - -5) One file (only available with the -l option): - Lists function sizes for that file - Example: - cmpcodesize -l test.o -""" - -Prefixes = { - # Cpp - "__Z" : "CPP", - "_swift" : "CPP", - "__swift" : "CPP", - - # Objective-C - "+[" : "ObjC", - "-[" : "ObjC", - - # Swift - "__TP" : "Partial Apply", - "__TTW" : "Protocol Witness", - "__Tw" : "Value Witness", - "__TM" : "Type Metadata", - "__TF" : "Swift Function", - "__TTSg" : "Generic Spec", - "__TTSf" : "FuncSig Spec", - "__TZF" : "Static Func", - # Function signature specialization of a generic specialization. - "__TTSGF" : "FuncSigGen Spec", - "__TTo" : "Swift @objc Func", -} - -Infixes = { - #Swift - "q_" : "Generic Function" -} - -GenericFunctionPrefix = "__TTSg" - -SortedPrefixes = sorted(Prefixes) -SortedInfixes = sorted(Infixes) - -def addFunction(sizes, function, startAddr, endAddr, groupByPrefix): - if not function or startAddr == None or endAddr == None: - return - - size = endAddr - startAddr - - if groupByPrefix: - for infix in SortedInfixes: - if infix in function: - if not GenericFunctionPrefix in function: - sizes[Infixes[infix]] += size - return - for prefix in SortedPrefixes: - if function.startswith(prefix): - # Special handling for function signature specializations - # of generic specializations. - if prefix == "__TTSf" and GenericFunctionPrefix in function: - prefix = "__TTSGF" - sizes[Prefixes[prefix]] += size - return - sizes["Unknown"] += size - else: - sizes[function] += size - -def flatten(*args): - for x in args: - if hasattr(x, '__iter__'): - for y in flatten(*x): - yield y - else: - yield x - -def readSizes(sizes, fileName, functionDetails, groupByPrefix): - # Check if multiple architectures are supported by the object file. - # Prefer arm64 if available. - architectures = subprocess.check_output(["otool", "-V", "-f", fileName]).split("\n") - arch = None - archPattern = re.compile('architecture ([\S]+)') - for architecture in architectures: - archMatch = archPattern.match(architecture) - if archMatch: - if arch is None: - arch = archMatch.group(1) - if "arm64" in arch: - arch = "arm64" - if arch is not None: - archParams = ["-arch", arch] - else: - archParams = [] - - if functionDetails: - content = subprocess.check_output(flatten(["otool", archParams, "-l", "-v", "-t", fileName])).split("\n") - content += subprocess.check_output(flatten(["otool", archParams, "-v", "-s", "__TEXT", "__textcoal_nt", fileName])).split("\n") - else: - content = subprocess.check_output(flatten(["otool", archParams, "-l", fileName])).split("\n") - - sectName = None - currFunc = None - startAddr = None - endAddr = None - - sectionPattern = re.compile(' +sectname ([\S]+)') - sizePattern = re.compile(' +size ([\da-fx]+)') - asmlinePattern = re.compile('^([0-9a-fA-F]+)\s') - labelPattern = re.compile('^((\-*\[[^\]]*\])|[^\/\s]+):$') - - for line in content: - asmlineMatch = asmlinePattern.match(line) - if asmlineMatch: - addr = int(asmlineMatch.group(1), 16) - if startAddr == None: - startAddr = addr - endAddr = addr - elif line == "Section": - sectName = None - else: - labelMatch = labelPattern.match(line) - sizeMatch = sizePattern.match(line) - sectionMatch = sectionPattern.match(line) - if labelMatch: - funcName = labelMatch.group(1) - addFunction(sizes, currFunc, startAddr, endAddr, groupByPrefix) - currFunc = funcName - startAddr = None - endAddr = None - elif sizeMatch and sectName and groupByPrefix: - size = int(sizeMatch.group(1), 16) - sizes[sectName] += size - elif sectionMatch: - sectName = sectionMatch.group(1) - if sectName == "__textcoal_nt": - sectName = "__text" - - addFunction(sizes, currFunc, startAddr, endAddr, groupByPrefix) - -def compareSizes(oldSizes, newSizes, nameKey, title): - oldSize = oldSizes[nameKey] - newSize = newSizes[nameKey] - if oldSize != None and newSize != None: - if oldSize != 0: - perc = "%.1f%%" % ((1.0 - float(newSize) / float(oldSize)) * 100.0) - else: - perc = "- " - print "%-26s%16s: %8d %8d %6s" % (title, nameKey, oldSize, newSize, perc) - -def compareSizesOfFile(oldFiles, newFiles, allSections, listCategories): - oldSizes = collections.defaultdict(int) - newSizes = collections.defaultdict(int) - for oldFile in oldFiles: - readSizes(oldSizes, oldFile, listCategories, True) - for newFile in newFiles: - readSizes(newSizes, newFile, listCategories, True) - - if len(oldFiles) == 1 and len(newFiles) == 1: - oldBase = os.path.basename(oldFiles[0]) - newBase = os.path.basename(newFiles[0]) - title = oldBase - if oldBase != newBase: - title += "-" + newBase - else: - title = "old-new" - - compareSizes(oldSizes, newSizes, "__text", title) - if listCategories: - prev = None - for categoryName in sorted(Prefixes.values()) + sorted(Infixes.values())+ ["Unknown"]: - if categoryName != prev: - compareSizes(oldSizes, newSizes, categoryName, "") - prev = categoryName - - if allSections: - sectionTitle = " section" - compareSizes(oldSizes, newSizes, "__textcoal_nt", sectionTitle) - compareSizes(oldSizes, newSizes, "__stubs", sectionTitle) - compareSizes(oldSizes, newSizes, "__const", sectionTitle) - compareSizes(oldSizes, newSizes, "__cstring", sectionTitle) - compareSizes(oldSizes, newSizes, "__objc_methname", sectionTitle) - compareSizes(oldSizes, newSizes, "__const", sectionTitle) - compareSizes(oldSizes, newSizes, "__objc_const", sectionTitle) - compareSizes(oldSizes, newSizes, "__data", sectionTitle) - compareSizes(oldSizes, newSizes, "__swift1_proto", sectionTitle) - compareSizes(oldSizes, newSizes, "__common", sectionTitle) - compareSizes(oldSizes, newSizes, "__bss", sectionTitle) - -def listFunctionSizes(sizeArray): - for pair in sorted(sizeArray, key=itemgetter(1)): - name = pair[0] - size = pair[1] - print "%8d %s" % (size, name) - -def compareFunctionSizes(oldFiles, newFiles): - oldSizes = collections.defaultdict(int) - newSizes = collections.defaultdict(int) - for name in oldFiles: - readSizes(oldSizes, name, True, False) - for name in newFiles: - readSizes(newSizes, name, True, False) - - onlyInFile1 = [] - onlyInFile2 = [] - inBoth = [] - - onlyInFile1Size = 0 - onlyInFile2Size = 0 - inBothSize = 0 - - for func, oldSize in oldSizes.items(): - newSize = newSizes[func] - if newSize != 0: - inBoth.append((func, oldSize, newSize)) - else: - onlyInFile1.append((func, oldSize)) - onlyInFile1Size += oldSize - - for func, newSize in newSizes.items(): - oldSize = oldSizes[func] - if oldSize == 0: - onlyInFile2.append((func, newSize)) - onlyInFile2Size += newSize - - if onlyInFile1: - print "Only in old file(s)" - listFunctionSizes(onlyInFile1) - print "Total size of functions only in old file: {}".format(onlyInFile1Size) - print - - if onlyInFile2: - print "Only in new files(s)" - listFunctionSizes(onlyInFile2) - print "Total size of functions only in new file: {}".format(onlyInFile2Size) - print - - if inBoth: - sizeIncrease = 0 - sizeDecrease = 0 - print "%8s %8s %8s" % ("old", "new", "diff") - for triple in sorted(inBoth, key=lambda tup: (tup[2] - tup[1], tup[1])): - func = triple[0] - oldSize = triple[1] - newSize = triple[2] - diff = newSize - oldSize - if diff > 0: - sizeIncrease += diff - else: - sizeDecrease -= diff - if diff == 0: - inBothSize += newSize - print "%8d %8d %8d %s" %(oldSize, newSize, newSize - oldSize, func) - print "Total size of functions with the same size in both files: {}".format(inBothSize) - print "Total size of functions that got smaller: {}".format(sizeDecrease) - print "Total size of functions that got bigger: {}".format(sizeIncrease) - print "Total size change of functions present in both files: {}".format(sizeIncrease - sizeDecrease) - -def main(): - allSections = False - listCategories = False - listFunctions = False - separatorFound = False - sumSizes = False - oldFileArgs = [] - newFileArgs = [] - curFiles = oldFileArgs - for arg in sys.argv[1:]: - if arg == "-a": - allSections = True - elif arg == "-c": - listCategories = True - elif arg == "-s": - sumSizes = True - elif arg == "-l": - listFunctions = True - elif arg == "--": - curFiles = newFileArgs - separatorFound = True - elif arg == "-h": - help() - return - elif arg.startswith("-"): - sys.exit("Unknown option. Use -h to display usage.") - else: - curFiles.append(arg) - - - oldBuildDir = os.environ.get("SWIFT_OLD_BUILDDIR") - newBuildDir = os.environ.get("SWIFT_NEW_BUILDDIR") - - if separatorFound: - oldFiles = oldFileArgs - newFiles = newFileArgs - else: - if not oldFileArgs: - if listFunctions: - sys.exit("Must specify file for the -l option") - if not oldBuildDir: - sys.exit("$SWIFT_OLD_BUILDDIR not specified") - if not newBuildDir: - die("$SWIFT_NEW_BUILDDIR not specified") - oldFileArgs = [ "O", "Ounchecked", "Onone", "dylib" ] - oldFiles = [] - newFiles = [] - numExpanded = 0 - for file in oldFileArgs: - shortcuts = { - "O" : "bin/PerfTests_O", - "Ounchecked" : "bin/PerfTests_Ounchecked", - "Onone" : "bin/PerfTests_Onone", - "dylib" : "lib/swift/macosx/x86_64/libswiftCore.dylib" - } - if file in shortcuts: - file = shortcuts[file] - - if not file.startswith("./") and oldBuildDir and newBuildDir: - oldExpanded = glob.glob(oldBuildDir + "/" + file) - newExpanded = glob.glob(newBuildDir + "/" + file) - if oldExpanded and newExpanded: - oldFiles.extend(oldExpanded) - newFiles.extend(newExpanded) - numExpanded += 1 - - if numExpanded != 0 and numExpanded != len(oldFileArgs): - sys.exit("mix of expanded/not-expanded arguments") - if numExpanded == 0: - if len(oldFileArgs) > 2: - sys.exit("too many arguments") - oldFiles = oldFileArgs[0:1] - newFiles = oldFileArgs[1:2] - - for file in (oldFiles + newFiles): - if not os.path.isfile(file): - sys.exit("file " + file + " not found") - - if listFunctions: - if allSections or listCategories: - print >> sys.stderr, "Warning: options -a and -c ignored when using -l" - if not newFiles: - sizes = collections.defaultdict(int) - for file in oldFiles: - readSizes(sizes, file, True, False) - listFunctionSizes(sizes.items()) - else: - compareFunctionSizes(oldFiles, newFiles) - else: - print "%-26s%16s %8s %8s %s" % ("", "Section", "Old", "New", "Percent") - if sumSizes: - compareSizesOfFile(oldFiles, newFiles, allSections, listCategories) - else: - if len(oldFiles) != len(newFiles): - sys.exit("number of new files must be the same of old files") - - oldFiles.sort - newFiles.sort - - for idx, oldFile in enumerate(oldFiles): - newFile = newFiles[idx] - compareSizesOfFile([oldFile], [newFile], allSections, listCategories) - -main() - diff --git a/utils/cmpcodesize/.gitignore b/utils/cmpcodesize/.gitignore new file mode 100644 index 0000000000000..2a90995930641 --- /dev/null +++ b/utils/cmpcodesize/.gitignore @@ -0,0 +1,26 @@ +# Compile artifacts +__pycache__/ +*.py[cod] +*$py.class + +# Distribution/packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt diff --git a/utils/cmpcodesize/cmpcodesize.py b/utils/cmpcodesize/cmpcodesize.py new file mode 100755 index 0000000000000..a0dfa744a5fd5 --- /dev/null +++ b/utils/cmpcodesize/cmpcodesize.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# cmpcodesize.py - Compare sizes of built products -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +from cmpcodesize.main import main + +if __name__ == '__main__': + main() diff --git a/utils/cmpcodesize/cmpcodesize/__init__.py b/utils/cmpcodesize/cmpcodesize/__init__.py new file mode 100644 index 0000000000000..757cc54b1190d --- /dev/null +++ b/utils/cmpcodesize/cmpcodesize/__init__.py @@ -0,0 +1,23 @@ +# cmpcodesize/__init__.py - Compare sizes of built products -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# This file needs to be here in order for Python to treat the +# utils/cmpcodesize/cmpcodesize directory as a module. +# +# ---------------------------------------------------------------------------- + +__author__ = 'Brian Gesiak' +__email__ = 'modocache@gmail.com' +__versioninfo__ = (0, 1, 0) +__version__ = '.'.join(str(v) for v in __versioninfo__) + +__all__ = [] diff --git a/utils/cmpcodesize/cmpcodesize/compare.py b/utils/cmpcodesize/cmpcodesize/compare.py new file mode 100644 index 0000000000000..f511db62b2dd7 --- /dev/null +++ b/utils/cmpcodesize/cmpcodesize/compare.py @@ -0,0 +1,271 @@ +# cmpcodesize/compare.py - Compare sizes of built products -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +from __future__ import print_function + +import re +import os +import subprocess +import collections +from operator import itemgetter + +Prefixes = { + # Cpp + "__Z" : "CPP", + "_swift" : "CPP", + "__swift" : "CPP", + + # Objective-C + "+[" : "ObjC", + "-[" : "ObjC", + + # Swift + "__TP" : "Partial Apply", + "__TTW" : "Protocol Witness", + "__Tw" : "Value Witness", + "__TM" : "Type Metadata", + "__TF" : "Swift Function", + "__TTSg" : "Generic Spec", + "__TTSf" : "FuncSig Spec", + "__TZF" : "Static Func", + # Function signature specialization of a generic specialization. + "__TTSGF" : "FuncSigGen Spec", + "__TTo" : "Swift @objc Func", +} + +Infixes = { + #Swift + "q_" : "Generic Function" +} + +GenericFunctionPrefix = "__TTSg" + +SortedPrefixes = sorted(Prefixes) +SortedInfixes = sorted(Infixes) + + +def addFunction(sizes, function, startAddr, endAddr, groupByPrefix): + if not function or startAddr is None or endAddr is None: + return + + size = endAddr - startAddr + + if groupByPrefix: + for infix in SortedInfixes: + if infix in function: + if GenericFunctionPrefix not in function: + sizes[Infixes[infix]] += size + return + for prefix in SortedPrefixes: + if function.startswith(prefix): + # Special handling for function signature specializations + # of generic specializations. + if prefix == "__TTSf" and GenericFunctionPrefix in function: + prefix = "__TTSGF" + sizes[Prefixes[prefix]] += size + return + sizes["Unknown"] += size + else: + sizes[function] += size + + +def flatten(*args): + for x in args: + if hasattr(x, '__iter__'): + for y in flatten(*x): + yield y + else: + yield x + + +def readSizes(sizes, fileName, functionDetails, groupByPrefix): + # Check if multiple architectures are supported by the object file. + # Prefer arm64 if available. + architectures = subprocess.check_output(["otool", "-V", "-f", fileName]).split("\n") + arch = None + archPattern = re.compile('architecture ([\S]+)') + for architecture in architectures: + archMatch = archPattern.match(architecture) + if archMatch: + if arch is None: + arch = archMatch.group(1) + if "arm64" in arch: + arch = "arm64" + if arch is not None: + archParams = ["-arch", arch] + else: + archParams = [] + + if functionDetails: + content = subprocess.check_output(flatten(["otool", archParams, "-l", "-v", "-t", fileName])).split("\n") + content += subprocess.check_output(flatten(["otool", archParams, "-v", "-s", "__TEXT", "__textcoal_nt", fileName])).split("\n") + else: + content = subprocess.check_output(flatten(["otool", archParams, "-l", fileName])).split("\n") + + sectName = None + currFunc = None + startAddr = None + endAddr = None + + sectionPattern = re.compile(' +sectname ([\S]+)') + sizePattern = re.compile(' +size ([\da-fx]+)') + asmlinePattern = re.compile('^([0-9a-fA-F]+)\s') + labelPattern = re.compile('^((\-*\[[^\]]*\])|[^\/\s]+):$') + + for line in content: + asmlineMatch = asmlinePattern.match(line) + if asmlineMatch: + addr = int(asmlineMatch.group(1), 16) + if startAddr is None: + startAddr = addr + endAddr = addr + elif line == "Section": + sectName = None + else: + labelMatch = labelPattern.match(line) + sizeMatch = sizePattern.match(line) + sectionMatch = sectionPattern.match(line) + if labelMatch: + funcName = labelMatch.group(1) + addFunction(sizes, currFunc, startAddr, endAddr, groupByPrefix) + currFunc = funcName + startAddr = None + endAddr = None + elif sizeMatch and sectName and groupByPrefix: + size = int(sizeMatch.group(1), 16) + sizes[sectName] += size + elif sectionMatch: + sectName = sectionMatch.group(1) + if sectName == "__textcoal_nt": + sectName = "__text" + + addFunction(sizes, currFunc, startAddr, endAddr, groupByPrefix) + + +def compareSizes(oldSizes, newSizes, nameKey, title): + oldSize = oldSizes[nameKey] + newSize = newSizes[nameKey] + if oldSize is not None and newSize is not None: + if oldSize != 0: + perc = "%.1f%%" % ((1.0 - float(newSize) / float(oldSize)) * 100.0) + else: + perc = "- " + print("%-26s%16s: %8d %8d %6s" % (title, nameKey, oldSize, newSize, perc)) + + +def compareSizesOfFile(oldFiles, newFiles, allSections, listCategories): + oldSizes = collections.defaultdict(int) + newSizes = collections.defaultdict(int) + for oldFile in oldFiles: + readSizes(oldSizes, oldFile, listCategories, True) + for newFile in newFiles: + readSizes(newSizes, newFile, listCategories, True) + + if len(oldFiles) == 1 and len(newFiles) == 1: + oldBase = os.path.basename(oldFiles[0]) + newBase = os.path.basename(newFiles[0]) + title = oldBase + if oldBase != newBase: + title += "-" + newBase + else: + title = "old-new" + + compareSizes(oldSizes, newSizes, "__text", title) + if listCategories: + prev = None + for categoryName in sorted(Prefixes.values()) + sorted(Infixes.values())+ ["Unknown"]: + if categoryName != prev: + compareSizes(oldSizes, newSizes, categoryName, "") + prev = categoryName + + if allSections: + sectionTitle = " section" + compareSizes(oldSizes, newSizes, "__textcoal_nt", sectionTitle) + compareSizes(oldSizes, newSizes, "__stubs", sectionTitle) + compareSizes(oldSizes, newSizes, "__const", sectionTitle) + compareSizes(oldSizes, newSizes, "__cstring", sectionTitle) + compareSizes(oldSizes, newSizes, "__objc_methname", sectionTitle) + compareSizes(oldSizes, newSizes, "__const", sectionTitle) + compareSizes(oldSizes, newSizes, "__objc_const", sectionTitle) + compareSizes(oldSizes, newSizes, "__data", sectionTitle) + compareSizes(oldSizes, newSizes, "__swift1_proto", sectionTitle) + compareSizes(oldSizes, newSizes, "__common", sectionTitle) + compareSizes(oldSizes, newSizes, "__bss", sectionTitle) + + +def listFunctionSizes(sizeArray): + for pair in sorted(sizeArray, key=itemgetter(1)): + name = pair[0] + size = pair[1] + return "%8d %s" % (size, name) + + +def compareFunctionSizes(oldFiles, newFiles): + oldSizes = collections.defaultdict(int) + newSizes = collections.defaultdict(int) + for name in oldFiles: + readSizes(oldSizes, name, True, False) + for name in newFiles: + readSizes(newSizes, name, True, False) + + onlyInFile1 = [] + onlyInFile2 = [] + inBoth = [] + + onlyInFile1Size = 0 + onlyInFile2Size = 0 + inBothSize = 0 + + for func, oldSize in oldSizes.items(): + newSize = newSizes[func] + if newSize != 0: + inBoth.append((func, oldSize, newSize)) + else: + onlyInFile1.append((func, oldSize)) + onlyInFile1Size += oldSize + + for func, newSize in newSizes.items(): + oldSize = oldSizes[func] + if oldSize == 0: + onlyInFile2.append((func, newSize)) + onlyInFile2Size += newSize + + if onlyInFile1: + print("Only in old file(s)") + print(listFunctionSizes(onlyInFile1)) + print("Total size of functions only in old file: {}".format(onlyInFile1Size)) + print() + + if onlyInFile2: + print("Only in new files(s)") + print(listFunctionSizes(onlyInFile2)) + print("Total size of functions only in new file: {}".format(onlyInFile2Size)) + print() + + if inBoth: + sizeIncrease = 0 + sizeDecrease = 0 + print("%8s %8s %8s" % ("old", "new", "diff")) + for triple in sorted(inBoth, key=lambda tup: (tup[2] - tup[1], tup[1])): + func = triple[0] + oldSize = triple[1] + newSize = triple[2] + diff = newSize - oldSize + if diff > 0: + sizeIncrease += diff + else: + sizeDecrease -= diff + if diff == 0: + inBothSize += newSize + print("%8d %8d %8d %s" %(oldSize, newSize, newSize - oldSize, func)) + print("Total size of functions with the same size in both files: {}".format(inBothSize)) + print("Total size of functions that got smaller: {}".format(sizeDecrease)) + print("Total size of functions that got bigger: {}".format(sizeIncrease)) + print("Total size change of functions present in both files: {}".format(sizeIncrease - sizeDecrease)) diff --git a/utils/cmpcodesize/cmpcodesize/main.py b/utils/cmpcodesize/cmpcodesize/main.py new file mode 100644 index 0000000000000..d3d7271c9d1b6 --- /dev/null +++ b/utils/cmpcodesize/cmpcodesize/main.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# cmpcodesize/main.py - Command-line entry point for cmpcodesize -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +from __future__ import print_function + +import argparse +import sys +import os +import glob +import collections + +from cmpcodesize.compare import \ + compareFunctionSizes, compareSizesOfFile, listFunctionSizes, readSizes + + +SHORTCUTS = { + "O": "bin/PerfTests_O", + "Ounchecked": "bin/PerfTests_Ounchecked", + "Onone": "bin/PerfTests_Onone", + "dylib": "lib/swift/macosx/x86_64/libswiftCore.dylib", +} + + +def main(): + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description=""" +Compares code sizes of "new" files, taking "old" files as a reference. + +Environment variables: + SWIFT_NEW_BUILDDIR The old build-dir +E.g. $HOME/swift-work/build/Ninja-ReleaseAssert+stdlib-Release/swift-macosx-x86_64 + SWIFT_OLD_BUILDDIR The new build-dir +E.g. $HOME/swift-reference/build/Ninja-ReleaseAssert+stdlib-Release/swift-macosx-x86_64 + +How to specify files: +1) No files: + Compares codesize of the PerfTests_* executables and the swiftCore dylib in the new and old build-dirs. + Example: + cmpcodesize + +2) One or more paths relative to the build-dirs (can be a pattern): + Compares the files in the new and old build-dirs. + Aliases: + O => bin/PerfTests_O + Ounchecked => bin/PerfTests_Ounchecked + Onone => bin/PerfTests_Onone + dylib => lib/swift/macosx/x86_64/libswiftCore.dylib + Examples: + cmpcodesize Onone + cmpcodesize benchmark/PerfTestSuite/O/*.o + +3) Two files: + Compares these two files (the first is the old file). + Example: + cmpcodesize test.o newversion.o + +4) Two lists of files, separated by '--': + Compares a set a files. + Example: + cmpcodesize olddir/*.o -- newdir/*.o + +5) One file (only available with the -l option): + Lists function sizes for that file + Example: + cmpcodesize -l test.o""") + + # Optional arguments. + parser.add_argument('-a', '--additional-sections', + help='Show sizes of additional sections.', + action='store_true', + dest='all_sections', + default=False) + parser.add_argument('-c', '--category', + help='Show functions by category.', + action='store_true', + dest='list_categories', + default=False) + parser.add_argument('-l', '--list', + help='List all functions (can be a very long list). ' + + 'Cannot be used in conjunction with ' + + '--additional-sections or --category. ' + + 'You must specify between one and two files ' + + 'when using this option.', + action='store_true', + dest='list_functions', + default=False) + parser.add_argument('-s', '--summarize', + help='Summarize the sizes of multiple files instead ' + + 'of listing each file separately.', + action='store_true', + dest='sum_sizes', + default=False) + + # Positional arguments. + # These can be specified in means beyond what argparse supports, + # so we gather them in a list and parse them manually. + parser.add_argument('files', nargs='*', + help='A list of old and new files.') + + # argparse can't handle an '--' argument, so we replace it with + # a custom identifier. + separator_token = '*-*-*' + parsed_arguments = parser.parse_args( + [separator_token if arg == '--' else arg for arg in sys.argv[1:]]) + + if parsed_arguments.list_functions: + # --list is mutually exclusive with both --additional-sections + # and --category. argparse is only capable of expressing mutual + # exclusivity among options, not among groups of options, so + # we detect this case manually. + assert (not parsed_arguments.all_sections and + not parsed_arguments.list_categories), \ + 'Incorrect usage: --list cannot be specified in conjunction ' + \ + 'with --additional-sections or --category.' + # A file must be specified when using --list. + assert parsed_arguments.files, \ + 'Incorrect usage: Must specify between one and two files when ' + \ + 'using --list, but you specified no files.' + + if separator_token in parsed_arguments.files: + separator_index = parsed_arguments.files.index(separator_token) + oldFiles = parsed_arguments.files[:separator_index] + newFiles = parsed_arguments.files[separator_index + 1:] + else: + oldFileArgs = parsed_arguments.files + + oldBuildDir = os.environ.get("SWIFT_OLD_BUILDDIR") + newBuildDir = os.environ.get("SWIFT_NEW_BUILDDIR") + + if not parsed_arguments.files: + assert oldBuildDir and newBuildDir, \ + 'Incorrect usage: You must specify either a list of ' + \ + 'files, or have both $SWIFT_OLD_BUILDDIR and ' + \ + '$SWIFT_NEW_BUILDDIR environment variables set.\n' + \ + '$SWIFT_OLD_BUILDDIR = {0}\n$SWIFT_NEW_BUILDDIR = {1}'.format( + oldBuildDir, newBuildDir) + oldFileArgs = list(SHORTCUTS.keys()) + + oldFiles = [] + newFiles = [] + numExpanded = 0 + for file in oldFileArgs: + if file in SHORTCUTS: + file = SHORTCUTS[file] + + if not file.startswith("./") and oldBuildDir and newBuildDir: + oldExpanded = glob.glob(os.path.join(oldBuildDir, file)) + newExpanded = glob.glob(os.path.join(newBuildDir, file)) + if oldExpanded and newExpanded: + oldFiles.extend(oldExpanded) + newFiles.extend(newExpanded) + numExpanded += 1 + + if numExpanded != 0 and numExpanded != len(oldFileArgs): + sys.exit("mix of expanded/not-expanded arguments") + if numExpanded == 0: + if len(oldFileArgs) > 2: + sys.exit("too many arguments") + oldFiles = oldFileArgs[0:1] + newFiles = oldFileArgs[1:2] + + for file in (oldFiles + newFiles): + if not os.path.isfile(file): + sys.exit("file " + file + " not found") + + if parsed_arguments.list_functions: + if not newFiles: + sizes = collections.defaultdict(int) + for file in oldFiles: + readSizes(sizes, file, True, False) + print(listFunctionSizes(sizes.items())) + else: + compareFunctionSizes(oldFiles, newFiles) + else: + print("%-26s%16s %8s %8s %s" % ("", "Section", "Old", "New", "Percent")) + if parsed_arguments.sum_sizes: + compareSizesOfFile(oldFiles, newFiles, + parsed_arguments.all_sections, + parsed_arguments.list_categories) + else: + if len(oldFiles) != len(newFiles): + sys.exit("number of new files must be the same of old files") + + oldFiles.sort + newFiles.sort + + for idx, oldFile in enumerate(oldFiles): + newFile = newFiles[idx] + compareSizesOfFile([oldFile], [newFile], + parsed_arguments.all_sections, + parsed_arguments.list_categories) + +if __name__ == '__main__': + main() diff --git a/utils/cmpcodesize/setup.py b/utils/cmpcodesize/setup.py new file mode 100644 index 0000000000000..e1b44bd127ba6 --- /dev/null +++ b/utils/cmpcodesize/setup.py @@ -0,0 +1,53 @@ +# cmpcodesize/setup.py - Install script for cmpcodesize -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +import os +import setuptools + +import cmpcodesize + +# setuptools expects to be invoked from within the directory of setup.py, +# but it is nice to allow `python path/to/setup.py install` to work +# (for scripts, etc.) +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +setuptools.setup( + name="cmpcodesize", + version=cmpcodesize.__version__, + + author=cmpcodesize.__author__, + author_email=cmpcodesize.__email__, + url='http://swift.org', + license='Apache', + + description="A tool to compare the size of Swift compiler build products.", + keywords='compare size swift', + + test_suite='tests', + + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Topic :: Software Development :: Compilers', + ], + + zip_safe=False, + packages=setuptools.find_packages(), + entry_points={ + 'console_scripts': [ + 'cmpcodesize = cmpcodesize:main', + ], + } +) diff --git a/utils/cmpcodesize/tests/__init__.py b/utils/cmpcodesize/tests/__init__.py new file mode 100644 index 0000000000000..ee2feec059548 --- /dev/null +++ b/utils/cmpcodesize/tests/__init__.py @@ -0,0 +1,16 @@ +# cmpcodesize/tests/__init__.py - Unit tests for cmpcodesize -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# This file needs to be here in order for Python to treat the +# utils/cmpcodesize/tests/ directory as a module. +# +# ---------------------------------------------------------------------------- diff --git a/utils/cmpcodesize/tests/test_list_function_sizes.py b/utils/cmpcodesize/tests/test_list_function_sizes.py new file mode 100644 index 0000000000000..e697a9ee05c8e --- /dev/null +++ b/utils/cmpcodesize/tests/test_list_function_sizes.py @@ -0,0 +1,26 @@ +# test_list_function_sizes.py - Unit tests for listFunctionSizes -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +import unittest + +from cmpcodesize.compare import listFunctionSizes + + +class ListFunctionSizesTestCase(unittest.TestCase): + def test_when_size_array_is_none_raises(self): + with self.assertRaises(TypeError): + listFunctionSizes(None) + + def test_when_size_array_is_empty_returns_none(self): + self.assertIsNone(listFunctionSizes([])) + + +if __name__ == '__main__': + unittest.main() diff --git a/utils/darwin-installer-scripts/postinstall b/utils/darwin-installer-scripts/postinstall index 273073c826dd9..d10ed38ad9d07 100755 --- a/utils/darwin-installer-scripts/postinstall +++ b/utils/darwin-installer-scripts/postinstall @@ -3,7 +3,7 @@ # ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information diff --git a/utils/demo-tool b/utils/demo-tool deleted file mode 100755 index 31b553ba7553a..0000000000000 --- a/utils/demo-tool +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env python - -import json -import optparse -import subprocess -import time -import random -import sys - -def send_to_screen(screen_name, arg0=None, command='stuff'): - args = ['screen', '-S', screen_name, '-p', '0', - '-X', command] - if arg0 is not None: - args.append(arg0) - p = subprocess.Popen(args) - p.communicate() - -def load_as_transcript(f): - def add_block(clearScreen=False,noReturn=False): - # If so, add the current block after trimming leading and trailing blank - # lines. - while current_block and current_block[0].isspace(): - current_block.pop(0) - while current_block and current_block[-1].isspace(): - current_block.pop() - - # Add the block if it is non-empty. - if current_block or comment_block: - # Form the joined script.. - script = ''.join(current_block) - comment = ''.join(comment_block) - - # Strip off any trailing newline. - if script.endswith('\n'): - script = script[:-1] - demo_script.append({ 'command' : script, - 'comment' : comment, - 'clearScreen' : clearScreen, - 'noReturn' : noReturn }) - - # Clear the block and comment block. - del current_block[:] - del comment_block[:] - - f.seek(0) - - demo_script = [] - current_block = [] - comment_block = [] - for ln in f: - # Check if this is a block delimiter. - if ln.strip() == '>>>': - add_block() - continue - - # Check if this is a block delimiter - # but marked to clear the screen. - if ln.strip() == '>>>CLEAR': - add_block(clearScreen=True) - continue - - # Check if this is a block delimiter - # but marked to not insert a newline. - if ln.strip() == '>>>NORETURN': - add_block(noReturn=True) - continue - - # Check if the line starts with a '#' - # to indicate a prompter comment. - if ln.startswith('#'): - comment_block.append(ln) - continue - - # Check for backspace. - if ln.strip() == '>>>BACKSPACE': - current_block.append('\b') - continue - - # Otherwise, add the line to the current block. - current_block.append(ln) - - return demo_script - -def main(): - parser = optparse.OptionParser("""\ -usage: %%prog [options] - -Run a command line demo script using 'screen'. The script file should be either -a JSON document listing the commands to run, as in:: - - [ - { "command" : "ls" }, - { "command" : "echo Hello" } - ] - -or, alternately, it should be a text filed delimited by '>>>', as in:: - - >>> - ls - - >>> - echo Hello - -where leading and trailing blank lines around each block will be discarded. - -The script requires the 'screen' session to have been started in another window, -for example:: - - $ screen -S demo -""") - - # Determine up front if the terminal supports color. - hasColor = sys.stdout.isatty() - - def prompterPrint(string): - if hasColor: - attr = [ '32', '1' ] - print '\x1b[%sm%s\x1b[0m' % (';'.join(attr), string) - else: - print string - - def send(*args, **kwargs): - return send_to_screen(opts.screen_name, *args, **kwargs) - parser.add_option("-S", "--screen-name", dest="screen_name", metavar="NAME", - help="name of the screen sesison to use [%default]", - action="store", default="demo") - - opts, args = parser.parse_args() - - if len(args) == 1: - path, = args - else: - parser.error("invalid number of arguments") - - # Read in the demo script. - with open(path) as f: - try: - demo_script = json.load(f) - except ValueError: - demo_script = load_as_transcript(f) - - # Validate the entries. - for item in demo_script: - command = str(item.get('command')) - if not isinstance(command, str): - raise SystemError("error: invalid item in script: %r" % ( - item,)) - - # Notify screen that we are starting the demo. - raw_input('press enter to begin demo...') - - # Iterate over each command, sending it and waiting for user direction to - # continue. - for item in demo_script: - shouldClear = bool(item['clearScreen']) - noReturn = bool(item['noReturn']) - command = str(item['command']) - comment = str(item['comment']) - - if comment: - prompterPrint(comment) - - if command: - # Send the command slowly, as if it was typed. - print "sending command: %r" % (command.replace('\n', ''),) - for c in command: - send(c) - if c == "\n": - time.sleep(0.1) - else: - time.sleep(random.random() * 0.03) - - if not noReturn: - # Wait for user input, then send a return. - raw_input('press enter to send return...') - send('\n') - - if item is not demo_script[-1]: - raw_input('press enter to continue to next command...') - # Send the command slowly, as if it was typed. - if shouldClear: - print "clearing screen" - send(command="clear") - send('\n') - - # Notify screen that the demo is over, after a small wait period. -# time.sleep(0.1) -# send('Demo session is over.', command='wall') - -if __name__ == '__main__': - main() diff --git a/utils/find-unused-diagnostics.sh b/utils/find-unused-diagnostics.sh index 8100f2253fdb5..7580350b9ece4 100755 --- a/utils/find-unused-diagnostics.sh +++ b/utils/find-unused-diagnostics.sh @@ -5,7 +5,7 @@ # # Gather all diagnostic identifiers. -ALL_DIAGS=$(grep -E --only-matching --no-filename 'ERROR\([a-z_]+,' include/swift/AST/Diagnostics.def | sed -e 's/ERROR(//' -e 's/,//') +ALL_DIAGS=$(grep -E --only-matching --no-filename 'ERROR\([a-z_]+,' include/swift/AST/Diagnostics*.def | sed -e 's/ERROR(//' -e 's/,//') # Now look for all potential identifiers in the source files. ALL_SOURCES=$(find lib include tools -name \*.cpp -or -name \*.h) diff --git a/utils/gyb.py b/utils/gyb.py index f0533fa568991..ba0d76ce1f1a6 100755 --- a/utils/gyb.py +++ b/utils/gyb.py @@ -2,8 +2,13 @@ # GYB: Generate Your Boilerplate (improved names welcome; at least # this one's short). See -h output for instructions +from __future__ import print_function + import re -from cStringIO import StringIO +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO import tokenize import textwrap from bisect import bisect @@ -133,7 +138,8 @@ def tokenizePythonToUnmatchedCloseCurly(sourceText, start, lineStarts): if nesting < 0: return tokenPosToIndex(tokenStart, start, lineStarts) - except tokenize.TokenError, (message, errorPos): + except tokenize.TokenError as error: + (message, errorPos) = error.args return tokenPosToIndex(errorPos, start, lineStarts) return len(sourceText) @@ -302,7 +308,7 @@ def splitGybLines(sourceLines): dedents = 0 try: for tokenKind, tokenText, tokenStart, (tokenEndLine, tokenEndCol), lineText \ - in tokenize.generate_tokens(sourceLines.__iter__().next): + in tokenize.generate_tokens(lambda i = iter(sourceLines): next(i)): if tokenKind in (tokenize.COMMENT, tokenize.ENDMARKER): continue @@ -322,7 +328,7 @@ def splitGybLines(sourceLines): lastTokenText,lastTokenKind = tokenText,tokenKind - except tokenize.TokenError, (message, errorPos): + except tokenize.TokenError: return [] # Let the later compile() call report the error if lastTokenText == ':': @@ -345,7 +351,7 @@ def codeStartsWithDedentKeyword(sourceLines): """ tokenText = None for tokenKind, tokenText, _, _, _ \ - in tokenize.generate_tokens(sourceLines.__iter__().next): + in tokenize.generate_tokens(lambda i = iter(sourceLines): next(i)): if tokenKind != tokenize.COMMENT and tokenText.strip() != '': break @@ -362,9 +368,13 @@ class ParseContext: tokens = None # The rest of the tokens closeLines = False - def __init__(self, filename, template = None): + def __init__(self, filename, template=None): self.filename = os.path.abspath(filename) - self.template = template or open(filename).read() + if template is None: + with open(filename) as f: + self.template = f.read() + else: + self.template = template self.lineStarts = getLineStarts(self.template) self.tokens = self.tokenGenerator(tokenizeTemplate(self.template)) self.nextToken() @@ -464,7 +474,8 @@ def tokenGenerator(self, baseTokens): if (kind == 'gybBlockOpen'): # Absorb any '}% \n' m2 = gybBlockClose.match(self.template, closePos) - assert m2, "Invalid block closure" # FIXME: need proper error handling here. + if not m2: + raise ValueError("Invalid block closure") nextPos = m2.end(0) else: assert kind == 'substitutionOpen' @@ -476,7 +487,6 @@ def tokenGenerator(self, baseTokens): elif kind == 'gybLines': self.codeStartLine = self.posToLine(self.tokenMatch.start('gybLines')) - codeStartPos = self.tokenMatch.end('_indent') indentation = self.tokenMatch.group('_indent') # Strip off the leading indentation and %-sign @@ -655,7 +665,9 @@ def execute(self, context): # Execute the code with our __children__ in scope context.localBindings['__children__'] = self.children result = eval(self.code, context.localBindings) - assert context.localBindings['__children__'] is self.children + + if context.localBindings['__children__'] is not self.children: + raise ValueError("The code is not allowed to mutate __children__") # Restore the bindings context.localBindings['__children__'] = saveChildren @@ -1051,8 +1063,8 @@ def succ(a): bindings = dict( x.split('=', 1) for x in args.defines ) ast = parseTemplate(args.file.name, args.file.read()) if args.dump: - print ast + print(ast) # Allow the template to import .py files from its own directory sys.path = [os.path.split(args.file.name)[0] or '.'] + sys.path diff --git a/utils/inferior-swift-mode.el b/utils/inferior-swift-mode.el index fa0d729bf53ed..7d6c542c23e2a 100644 --- a/utils/inferior-swift-mode.el +++ b/utils/inferior-swift-mode.el @@ -2,7 +2,7 @@ ; ; This source file is part of the Swift.org open source project ; -; Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +; Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ; Licensed under Apache License v2.0 with Runtime Library Exception ; ; See http://swift.org/LICENSE.txt for license information diff --git a/utils/install-package-helper.sh b/utils/install-package-helper.sh deleted file mode 100755 index 9de8e0be2276b..0000000000000 --- a/utils/install-package-helper.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -# A helper script that only installs or uninstalls a Swift package built -# by the buildbot. The _jenkins bot should be allowed to sudo this. - -# Must be root to install packages. -if [ "$(id -u)" != 0 ]; then - echo "Must install package as root!" - exit 1 -fi - -MODE="$1" -PACKAGE="$2" - -if [ \! "$PACKAGE" ]; then - echo "No package name! Usage: $0 [install|uninstall] package.tar.gz" - exit 1 -fi - -case "$MODE" in -install) - darwinup install "$PACKAGE" - exit $? - ;; -uninstall) - darwinup uninstall "$(basename "$PACKAGE")" - exit $? - ;; -*) - echo "Mode must be install or uninstall!" - echo "Usage: $0 [install|uninstall] package.tar.gz" - exit 1 - ;; -esac - diff --git a/utils/install-test-script.sh b/utils/install-test-script.sh deleted file mode 100755 index 5e2a545c7ae00..0000000000000 --- a/utils/install-test-script.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/sh -x - -# Smoke tests a Swift installation package. -# Set these to the paths of the OS X SDK and toolchain. -SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -TOOLCHAIN=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain - -# FIXME: OSX 10.9 bug : TMPDIR doesn't get set sometimes. -if [ ! "$TMPDIR" ]; then - TMPDIR=/tmp -fi - -# Wipe out stale module caches. -find "$TMPDIR" -name "*.pcm" -exec rm '{}' ';' -find /var/tmp -name "*.pcm" -exec rm '{}' ';' -find /tmp -name "*.pcm" -exec rm '{}' ';' -find "$(getconf DARWIN_USER_CACHE_DIR)" -name "*.pcm" -exec rm '{}' ';' - -# The package name should be given as the first argument. -PACKAGE_NAME="$1" - -if [ \! "$PACKAGE_NAME" ]; then - echo "No package name given! Usage: $0 package.tar.gz" - exit 1 -elif [ \! -f "$PACKAGE_NAME" ]; then - echo "Package $PACKAGE_NAME does not exist!" - exit 1 -fi - -# We use a sudoable script to darwinup install and uninstall the -# package. -INSTALL_PACKAGE_HELPER="$(dirname "$0")/install-package-helper.sh" - -if [ \! -x "$INSTALL_PACKAGE_HELPER" ]; then - echo "Unable to find package installer helper $INSTALL_PACKAGE_HELPER!" - exit 1 -fi - -# Install the package. -if ! sudo -n "$INSTALL_PACKAGE_HELPER" install "$PACKAGE_NAME"; then - echo "Failed to install package!" - exit 1 -fi - -# -# Do tests. -# - -# Ensure that basic REPL stuff works. -# FIXME: REPL bug--when stdout is redirected but stderr is a terminal, no -# output appears on stdout. -RESULT=0 - -if ! /usr/bin/swift -repl 2>"$TMPDIR/test_repl_1_err_$$" >"$TMPDIR/test_repl_1_$$" <"$TMPDIR/test_repl_2_err_$$" >"$TMPDIR/test_repl_2_$$" <"$TMPDIR/test_compile_$$.swift" < 15 and len(p[0]) > 3, lst) + return lst + +def getTokens(line): + """ + Split the incoming line into independent parts. The tokenizer has rules for + extracting identifiers (strings that start with digits followed by letters), + rules for detecting words (strings that start with upper case letters and + continue with lower case letters) and rules to glue swift mangling tokens + into subsequent words. + """ + # String builder. + sb = "" + # The last character. + Last = "" + for ch in line: + if Last.isupper(): + # Uppercase letter to digits -> starts a new token. + if ch.isdigit(): + if len(sb) > 3: + yield sb + sb = "" + sb += ch + Last = ch + continue + # Uppercase letter to lowercase or uppercase -> continue. + Last = ch + sb += ch + continue + + # Digit -> continue. + if Last.isdigit(): + Last = ch + sb += ch + continue + + # Lowercase letter to digit or uppercase letter -> stop. + if Last.islower(): + if ch.isdigit() or ch.isupper(): + if len(sb) > 4: + yield sb + sb = "" + sb += ch + Last = ch + continue + Last = ch + sb += ch + continue + + # Just append unclassified characters to the token. + if len(sb) > 3: + yield sb + sb = "" + sb += ch + Last = ch + yield sb + +def addLine(line): + """ + Extract all of the possible substrings from \p line and insert them into + the substring dictionary. This method knows to ignore the _T swift prefix. + """ + if not line.startswith("__T"): return + + # Strip the "__T" for the prefix calculations. + line = line[3:] + + # Add all of the tokens in the word to the histogram. + for tok in getTokens(line): + hist[tok] += 1 + +# Read all of the input files and add the substrings into the table. +for f in filenames: + for line in open(f): + addLine(line.strip('\n').strip()) + +# Use these characters as escape chars. +escape_char0 = 'Y' +escape_char1 = 'J' + +# notice that Y and J are missing because they are escape chars: +charset = r"0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXZ$" +encoders = [c for c in charset] # alphabet without the escape chars. +enc_len = len(encoders) + +# Take the most frequent entries from the table that fit into the range of +# our indices (assuming two characters for indices). +table = collect_top_entries(enc_len * enc_len) + +# Calculate the reverse mapping between the char to its index. +index_of_char = ["-1"] * 256 +idx = 0 +for c in charset: + index_of_char[ord(c)] = str(idx) + idx+=1 + +class Trie: + """ + This Trie data structure can generate C code for searching if a string is stored in the tree + and what is the TableIdx that is associated with that string. + """ + def __init__(self): + self.TableIdx = None + self.children = {} + + def add(self, word, TableIdx): + # Place the table index at the end of strings. + if len(word) == 0: + self.TableIdx = TableIdx + return + + first_letter = word[0] + + # Create a new entry in the Trie node if needed. + if first_letter not in self.children: + self.children[first_letter] = Trie() + + # Insert the rest of the string recursively. + self.children[first_letter].add(word[1:], TableIdx) + + def generateHeader(self): + return "// Returns the index of the longest substring in \p str that's shorter than \p n.\n" +\ + "int matchStringSuffix(const char* str, int n) {" + def generateFooter(self): + return "return -1; \n}" + + def generate(self, depth): + """ + Generate a search procedure for the Trie datastructure. + """ + sb = "" + space = " " * depth + for opt,node in self.children.iteritems(): + sb += space + "if ((%d < n) && (str[%d] == '%s')) {\n" % (depth, depth, opt) + sb += space + node.generate(depth + 1) + sb += space + "}\n" + if self.TableIdx: + sb += space + "return " + str(self.TableIdx) + ";\n" + return sb + +# Take only the key values, not the hit count +key_values = [p[0] for p in table] +# Array of string lengths. +string_length_table = map(lambda x: str(len(x)), key_values) +# Stringify the list of words that we use as substrings. +string_key_list = map(lambda x: "\""+ x + "\"", key_values) + +# Add all of the substrings that we'll use for compression into the Trie. +TrieHead = Trie() +for i in xrange(len(key_values)): TrieHead.add(key_values[i], i) + + +# Generate the header file. + +print "#ifndef SWIFT_MANGLER_CBC_TABLE_H" +print "#define SWIFT_MANGLER_CBC_TABLE_H" + +print "// This file is autogenerated. Do not modify this file." +print "// Processing text files:", " ".join([os.path.basename(f) for f in filenames]) + +print "namespace CBC {" +print "// The charset that the fragment indices can use:" +print "const unsigned CharsetLength = %d;" % len(charset) +print "const char *Charset = \"%s\";" % charset +print "const int IndexOfChar[] = {", ",".join(index_of_char),"};" +print "const char EscapeChar0 = '%s';" % escape_char0 +print "const char EscapeChar1 = '%s';" % escape_char1 +print "// The Fragments:" +print "const unsigned NumFragments = ", len(string_key_list), ";" +print "const char* CodeBook[] = {", ",".join(string_key_list),"};" +print "const unsigned CodeBookLen[] = {", ",".join(string_length_table),"};" +print TrieHead.generateHeader() +print TrieHead.generate(0) +print TrieHead.generateFooter() +print "} // namespace" +print "#endif /* SWIFT_MANGLER_CBC_TABLE_H */" diff --git a/utils/name-compression/HuffGen.py b/utils/name-compression/HuffGen.py new file mode 100644 index 0000000000000..c8ca8d76642f2 --- /dev/null +++ b/utils/name-compression/HuffGen.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python + +import sys +import os +from heapq import heappush, heappop +from collections import defaultdict + +filenames = sys.argv[1:] +if len(filenames) == 0: + print "-- Huffman encoding generation tool -- " + print "Usage: ./HuffGen.py file1.txt file2.txt file3.txt ..." + sys.exit(1) + +hist = defaultdict(int) + +def addLine(line): + """ + Analyze the frequency of letters in \p line. + """ + for c in line: hist[c] += 1 + +# Read all of the input files and analyze the content of the files. +for f in filenames: + for line in open(f): + addLine(line.rstrip('\n').strip()) + +# Sort all of the characters by their appearance frequency. +sorted_chars = sorted(hist.items(), key=lambda x: x[1] * len(x[0]) , reverse=True) + +class Node: + """ This is a node in the Huffman tree """ + def __init__(self, hits, value = None, l = None, r = None): + self.hit = hits # Number of occurrences for this node. + self.left = l # Left subtree. + self.right = r # Right subtree. + self.val = value # Character value for leaf nodes. + + def merge(Left, Right): + """ This is the merge phase of the huffman encoding algorithm + This (static) method creates a new node that combines \p Left and \p Right. + """ + return Node(Left.hit + Right.hit, None, Left, Right) + + def __cmp__(self, other): + """ Compare this node to another node based on their frequency. """ + return self.hit > other.hit + + def getMaxEncodingLength(self): + """ Return the length of the longest possible encoding word""" + v = 0 + if self.left: v = max(v, 1 + self.left .getMaxEncodingLength()) + if self.right: v = max(v, 1 + self.right.getMaxEncodingLength()) + return v + + def generate_decoder(self, depth): + """ + Generate the CPP code for the decoder. + """ + space = " " * depth + + if self.val: + return space + "num = num.lshr(%d);\n" % depth +\ + space + "return \'" + str(self.val) + "\';" + + T = """{0}if ((tailbits & 1) == {1}) {{\n{0} tailbits/=2;\n{2}\n{0}}}""" + sb = "" + if self.left: sb += T.format(space, 0, self.left .generate_decoder(depth + 1)) + "\n" + if self.right: sb += T.format(space, 1, self.right.generate_decoder(depth + 1)) + return sb + + def generate_encoder(self, stack): + """ + Generate the CPP code for the encoder. + """ + if self.val: + sb = "if (ch == '" + str(self.val) +"') {" + sb += "/*" + "".join(map(str, reversed(stack))) + "*/ " + # Encode the bit stream as a numeric value. Updating the APInt in one go + # is much faster than inserting one bit at a time. + numeric_val = 0 + for bit in reversed(stack): numeric_val = numeric_val * 2 + bit + # num_bits - the number of bits that we use in the bitstream. + # bits - the numeric value of the bits that we encode in the bitstream. + sb += "bits = %d; num_bits = %d; " % (numeric_val, len(stack)) + sb += "return; }\n" + return sb + sb = "" + if (self.left): sb += self.left .generate_encoder(stack + [0]) + if (self.right): sb += self.right.generate_encoder(stack + [1]) + return sb + +# Only accept these characters into the tree. +charset = r"0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$" + +# Convert the characters and frequencies to a list of trees +# where each tree is a node that holds a single character. +nodes = [] +for c in sorted_chars: + if c[0] in charset: + n = Node(c[1],c[0]) + heappush(nodes, n) + +# This is the Merge phase of the Huffman algorithm: +while len(nodes) > 1: + v1 = heappop(nodes) + v2 = heappop(nodes) + nv = Node.merge(v1, v2) + heappush(nodes, nv) + +print "#ifndef SWIFT_MANGLER_HUFFMAN_H" +print "#define SWIFT_MANGLER_HUFFMAN_H" +print "#include " +print "#include \"llvm/ADT/APInt.h\"" +print "using APInt = llvm::APInt;" +print "// This file is autogenerated. Do not modify this file." +print "// Processing text files:", " ".join([os.path.basename(f) for f in filenames]) +print "namespace Huffman {" +print "// The charset that the fragment indices can use:" +print "const unsigned CharsetLength = %d;" % len(charset) +print "const unsigned LongestEncodingLength = %d;" % (nodes[0].getMaxEncodingLength()) +print "const char *Charset = \"%s\";" % charset +print "char variable_decode(APInt &num) {\n uint64_t tailbits = *num.getRawData();\n", nodes[0].generate_decoder(0), "\n assert(false); return 0;\n}" +print "void variable_encode(uint64_t &bits, uint64_t &num_bits, char ch) {\n", nodes[0].generate_encoder([]),"assert(false);\n}" +print "} // namespace" +print "#endif /* SWIFT_MANGLER_HUFFMAN_H */" + diff --git a/utils/omit-needless-words.py b/utils/omit-needless-words.py index 4a6f0f13d6b5a..4bb6caa1538e6 100755 --- a/utils/omit-needless-words.py +++ b/utils/omit-needless-words.py @@ -4,145 +4,86 @@ # heuristics that omit 'needless' words from APIs imported from Clang # into Swift. -import getopt -import sys +from __future__ import print_function + +import argparse import subprocess -# Print help -def help(): - print('omit-needless-words.py [options] -m ') - print('') - print('Summary:') - print("\tDetermines the effects of omitting 'needless' words from imported APIs") - print('') - print('Options:') - print('\t-s \t\t\tThe SDK to use (e.g., macosx)') - print("\t--sdk='\t\tDefaults to 'macosx'") - print('') - print('\t-t \t\t\tThe target triple to use (e.g., x86_64-apple-macosx10.10)') - print("\t--target='\t\tDefaults to 'x86_64-apple-macosx10.10'") - print('') - print('\t-i \t\t\tThe swift-ide-test executable') - print("\t--swift-ide-test=\tDefaults to 'swift-ide-test'") - print('') - print('\t-d \t\t\tThe tool to use to diff the results') - print("\t--diff_tool=\tDefaults to 'opendiff'") - print('') - print('\t-b\t\t\t\tOnly omit the "before" result') - print('\t--only-before') - print('') - print('\t-a\t\t\t\tOnly omit the "after" result') - print('\t--only-after') - print('Examples:') - print('\tpython omit-needless-words.py -m AppKit') - -# Configuration information -sdk = 'macosx' -target = '' -module = '' -source_filename = 'omit-needless-words.swift' -swift_ide_test = 'swift-ide-test' -diff_tool = 'opendiff' -only_before=0 -only_after=0 - -# Parse command-line arguments. -try: - opts, args = getopt.getopt(sys.argv[1:], 'hs:t:m:i:d:ba', - ['help', 'sdk=', 'target=', 'module=', - 'swift-ide-test=','diff_tool=','only-before', - 'only-after']) -except getopt.GetoptError: - help() - sys.exit(2) - -for opt, arg in opts: - if opt in ('-h', '--help'): - help() - sys.exit() - - if opt in ('-s', '--sdk'): - sdk = arg - continue - - if opt in ('-t', '--target'): - target = arg - continue - - if opt in ('-m', '--module'): - module = arg - continue - - if opt in ('-i', '--swift-ide-test'): - swift_ide_test = arg - continue - - if opt in ('-d', '--diff_tool'): - diff_tool = arg - continue - - if opt in ('-b', '--only-before'): - only_before=1 - continue - - if opt in ('-a', '--only-after'): - only_after=1 - continue - - help() - sys.exit(2) - -if module == '': - help() - sys.exit(2) - -if target == '': - if sdk == 'macosx': - target = 'x86_64-apple-macosx10.10' - if sdk == 'iphoneos': - target = 'arm64-apple-ios8.0' - if sdk == 'iphonesimulator': - target = 'x86_64-apple-ios8.0' - if sdk == 'watchos': - target = 'armv7k-apple-watchos2.0' - if sdk == 'watchos.simulator': - target = 'i386-apple-watchos2.0' - if sdk == 'appletvos': - target = 'arm64-apple-tvos9' - if sdk == 'appletvos.simulator': - target = 'x86_64-apple-tvos9' - -# Figure out the SDK root for the requested SDK -sdkroot = subprocess.check_output(['xcrun', '--show-sdk-path', '--sdk', sdk]).rstrip() -print('SDK Root = %s' % (sdkroot)) - -swift_ide_test_cmd = [swift_ide_test, '-print-module', '-source-filename', source_filename, '-sdk', sdkroot, '-target', target, '-module-print-skip-overlay', '-skip-unavailable', '-module-print-submodules', '-skip-parameter-names', '-skip-imports', '-module-to-print=%s' % (module)] -omit_needless_words_args = ['-enable-omit-needless-words', '-enable-infer-default-arguments'] - -# Determine the output files. -before_filename = '%s.before.txt' % (module) -after_filename = '%s.after.txt' % (module) - -# Create a .swift file we can feed into swift-ide-test -subprocess.call(['touch', source_filename]) - -if only_after == 0: - # Print the interface without omitting needless words - print('Writing %s...' % before_filename) - before_file = open(before_filename, 'w') - subprocess.call(swift_ide_test_cmd, stdout=before_file) - before_file.close() - -if only_before == 0: - # Print the interface omitting needless words - print('Writing %s...' % after_filename) - after_file = open(after_filename, 'w') - subprocess.call(swift_ide_test_cmd + omit_needless_words_args, stdout=after_file) - after_file.close() - -# Remove the .swift file we fed into swift-ide-test -subprocess.call(['rm', '-f', source_filename]) - -# Diff them. -if diff_tool != '': - subprocess.call([diff_tool, before_filename, after_filename]) +DEFAULT_TARGET_BASED_ON_SDK = { + 'macosx' : 'x86_64-apple-macosx10.11', + 'iphoneos' : 'arm64-apple-ios9.0', + 'iphonesimulator' : 'x86_64-apple-ios9.0', + 'watchos' : 'armv7k-apple-watchos2.0', + 'watchos.simulator' : 'i386-apple-watchos2.0', + 'appletvos' : 'arm64-apple-tvos9', + 'appletvos.simulator' : 'x86_64-apple-tvos9', +} + +def create_parser(): + parser = argparse.ArgumentParser( + description="Determines the effects of omitting 'needless' words from imported APIs", + prog='omit-needless-words.py', + usage='python omit-needless-words.py -m AppKit') + parser.add_argument('-m', '--module', required=True, help='The module name.') + parser.add_argument('-s', '--sdk', default='macosx', help="The SDK to use.") + parser.add_argument('-t', '--target', help="The target triple to use.") + parser.add_argument('-i', '--swift-ide-test', default='swift-ide-test', help="The swift-ide-test executable.") + parser.add_argument('-d', '--diff_tool', default='opendiff', help="The tool to use to diff the results.") + parser.add_argument('-b', '--only-before', action='store_true', help='Only emit the "before" result.') + parser.add_argument('--before-file', help='Emit "before" results to the given file [defaults to .before.txt].') + parser.add_argument('-a', '--only-after', action='store_true', help='Only emit the "after" result.') + parser.add_argument('--after-file', help='Emit "after" results to the given file [defaults to .after.txt].') + parser.add_argument('-q', '--quiet', action='store_true', help='Suppress printing of status messages.') + return parser + +def output_command_result_to_file(command_args, filename): + with open(filename, 'w') as output_file: + subprocess.call(command_args, stdout=output_file) + +def main(): + source_filename = 'omit-needless-words.swift' + parser = create_parser() + args = parser.parse_args() + if not args.target: + args.target = DEFAULT_TARGET_BASED_ON_SDK[args.sdk] + + # Figure out the SDK root for the requested SDK + sdkroot = subprocess.check_output(['xcrun', '--show-sdk-path', '--sdk', args.sdk]).rstrip() + if not args.quiet: + print('SDK Root = %s' % (sdkroot)) + + swift_ide_test_cmd = [args.swift_ide_test, '-print-module', '-source-filename', source_filename, '-sdk', sdkroot, '-target', args.target, '-module-print-skip-overlay', '-skip-unavailable', '-module-print-submodules', '-skip-imports', '-module-to-print=%s' % (args.module)] + omit_needless_words_args = ['-enable-omit-needless-words', '-enable-infer-default-arguments'] + + # Determine the output files. + # No good way with argparse to set default value based on dependency of other arg. + if not args.before_file: + args.before_file = '%s.before.txt' % (args.module) + if not args.after_file: + args.after_file = '%s.after.txt' % (args.module) + + # Create a .swift file we can feed into swift-ide-test + subprocess.call(['touch', source_filename]) + + if not args.only_after: + # Print the interface without omitting needless words + if not args.quiet: + print('Writing %s...' % args.before_file) + output_command_result_to_file(swift_ide_test_cmd, args.before_file) + + if not args.only_before: + # Print the interface omitting needless words + if not args.quiet: + print('Writing %s...' % args.after_file) + output_command_result_to_file(swift_ide_test_cmd + omit_needless_words_args, args.after_file) + + # Remove the .swift file we fed into swift-ide-test + subprocess.call(['rm', '-f', source_filename]) + + # Diff them + if args.diff_tool != "": + subprocess.call([args.diff_tool, args.before_file, args.after_file]) + +if __name__ == '__main__': + main() + diff --git a/utils/pass-pipeline/scripts/pipeline_generator.py b/utils/pass-pipeline/scripts/pipeline_generator.py index befbd3413f61f..4b7ad6c094e13 100755 --- a/utils/pass-pipeline/scripts/pipeline_generator.py +++ b/utils/pass-pipeline/scripts/pipeline_generator.py @@ -3,7 +3,6 @@ import os import sys import argparse -import itertools import json import textwrap @@ -31,7 +30,7 @@ disabled_passpipelines = sum(args.disable_passpipeline, []) # First filter out pipelines. -normal_pipeline_generated = [x.generate() for x in normal_pipeline if not x.identifier in disabled_passpipelines] +normal_pipeline_generated = [x.generate() for x in normal_pipeline if x.identifier not in disabled_passpipelines] # Then filter out specific passes. for i in range(len(normal_pipeline_generated)): diff --git a/utils/pass-pipeline/scripts/pipelines_build_script.py b/utils/pass-pipeline/scripts/pipelines_build_script.py index 1adee8b7e59bb..3644e3fbb3754 100755 --- a/utils/pass-pipeline/scripts/pipelines_build_script.py +++ b/utils/pass-pipeline/scripts/pipelines_build_script.py @@ -9,7 +9,6 @@ # Append the src dir sys.path.append(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'src')) -import pass_pipeline_library import passes # TODO: This should not be hard coded. diff --git a/utils/pass-pipeline/src/pass_pipeline.py b/utils/pass-pipeline/src/pass_pipeline.py index c47eccf5a52a8..fa713fb67670f 100644 --- a/utils/pass-pipeline/src/pass_pipeline.py +++ b/utils/pass-pipeline/src/pass_pipeline.py @@ -1,8 +1,3 @@ - -import sys -import json -import itertools - class Pass(object): def __init__(self, name): self.name = name diff --git a/utils/pass-pipeline/src/pass_pipeline_library.py b/utils/pass-pipeline/src/pass_pipeline_library.py index 34b8baf907fc5..0c6ab78a38a30 100644 --- a/utils/pass-pipeline/src/pass_pipeline_library.py +++ b/utils/pass-pipeline/src/pass_pipeline_library.py @@ -102,10 +102,6 @@ def lower_passlist(): def normal_passpipelines(): result = [] - x = ppipe.PassPipeline('PreSpecialize', {'name': 'run_to_fixed_point'}) - x.addPass(specialization_passlist()) - result.append(x) - x = ppipe.PassPipeline('HighLevel', {'name': 'run_n_times', 'count': 2}) x.addPass(ssapass_passlist('high')) result.append(x) diff --git a/utils/pass-pipeline/src/passes.py b/utils/pass-pipeline/src/passes.py index 7d6a35dabcd2a..0c6f3975b5bba 100644 --- a/utils/pass-pipeline/src/passes.py +++ b/utils/pass-pipeline/src/passes.py @@ -18,7 +18,6 @@ DeadFunctionElimination = Pass('DeadFunctionElimination') DeadObjectElimination = Pass('DeadObjectElimination') DefiniteInitialization = Pass('DefiniteInitialization') -Devirtualizer = Pass('SpeculativeDevirtualizer') DiagnoseUnreachable = Pass('DiagnoseUnreachable') DiagnosticConstantPropagation = Pass('DiagnosticConstantPropagation') EarlyInliner = Pass('EarlyInliner') @@ -46,6 +45,7 @@ SILLinker = Pass('SILLinker') SROA = Pass('SROA') SimplifyCFG = Pass('SimplifyCFG') +SpeculativeDevirtualizer = Pass('SpeculativeDevirtualizer') SplitAllCriticalEdges = Pass('SplitAllCriticalEdges') SplitNonCondBrCriticalEdges = Pass('SplitNonCondBrCriticalEdges') StripDebugInfo = Pass('StripDebugInfo') @@ -67,7 +67,6 @@ DeadFunctionElimination, DeadObjectElimination, DefiniteInitialization, - SpeculativeDevirtualizer, DiagnoseUnreachable, DiagnosticConstantPropagation, EarlyInliner, @@ -95,6 +94,7 @@ SILLinker, SROA, SimplifyCFG, + SpeculativeDevirtualizer, SplitAllCriticalEdges, SplitNonCondBrCriticalEdges, StripDebugInfo, diff --git a/utils/pre-commit-benchmark b/utils/pre-commit-benchmark index b87df62362452..52ad4ec65a0f2 100755 --- a/utils/pre-commit-benchmark +++ b/utils/pre-commit-benchmark @@ -8,11 +8,12 @@ # this script somewhere outside the source tree and then move it back # when your changes are finished. +from __future__ import print_function + import subprocess import sys import os import re -import shutil import argparse from pipes import quote as shell_quote @@ -33,8 +34,8 @@ def print_call(*args, **kw): if isinstance(args[0], (str, unicode)): args = [args] - print '$ ' + ' '.join(shell_quote(x) for x in args[0]) + ' # %r, %r' % (args[1:], kw) + print('$ ' + ' '.join(shell_quote(x) for x in args[0]) + ' # %r, %r' % (args[1:], kw)) def check_call(*args, **kw): print_call(*args, **kw) try: @@ -132,7 +133,8 @@ def collectBenchmarks(exeNames, treeish = None, repeat = 3, build_script_args = rebuilt = True else: - timingsText = open(timingsFile).read() + with open(timingsFile) as f: + timingsText = f.read() oldRepeat = timingsText.count('\nTotal') if oldRepeat < repeat: print('Only %s repeats in existing %s timings file' % (oldRepeat, exe)) @@ -145,8 +147,9 @@ def collectBenchmarks(exeNames, treeish = None, repeat = 3, build_script_args = output = check_output(os.path.join(binDir, exe)) print(output) timingsText += output - - open(timingsFile, 'w').write(timingsText) + + with open(timingsFile, 'w') as outfile: + outfile.write(timingsText) print('done.') return cacheDir @@ -165,7 +168,7 @@ def parseFloat(word): try: return float(word) except: - raise ScoreParserException("Expected float val, not "+word) + raise Exception("Expected float val, not {}".format(word)) def getScores(fname): scores = {} @@ -173,7 +176,8 @@ def getScores(fname): f = open(fname) try: for line in f: - if VERBOSE: print "Parsing", line, + if VERBOSE: + print("Parsing", line) m = SCORERE.match(line) if not m: continue @@ -214,12 +218,14 @@ def compareTimingsFiles(file1, file2): scores1, runs1 = getScores(file1) scores2, runs2 = getScores(file2) runs = min(runs1, runs2) - if VERBOSE: print scores1; print scores2 keys = [f for f in set(scores1.keys() + scores2.keys())] + if VERBOSE: + print(scores1) + print(scores2) keys.sort() if VERBOSE: - print "comparing ", file1, "vs", file2, "=", - print file1, "/", file2 + print("comparing ", file1, "vs", file2, "=", end='') + print(file1, "/", file2) rows = [["benchmark"]] for i in range(0,runs): @@ -229,11 +235,11 @@ def compareTimingsFiles(file1, file2): rows[0] += ["delta", "speedup"] for key in keys: - if not key in scores1: - print key, "not in", file1 + if key not in scores1: + print(key, "not in", file1) continue - if not key in scores2: - print key, "not in", file2 + if key not in scores2: + print(key, "not in", file2) continue rows.append(compareScores(key, scores1[key], scores2[key], runs)) @@ -247,9 +253,9 @@ def compareTimingsFiles(file1, file2): for row in rows: for n, x in enumerate(row): if n != 0: - print ',', - print ((widths[n] - len(x)) * ' ') + x, - print '' + print(',', end='') + print(((widths[n] - len(x)) * ' ') + x, end='') + print() def checkAndUpdatePerfTestSuite(sourceDir): """Check that the performance testsuite directory is in its appropriate @@ -284,7 +290,7 @@ if __name__ == '__main__': action='append', help='Optimization levels to test') parser.add_argument(dest='baseline', nargs='?', metavar='tree-ish', default='origin/master', help='the baseline Git commit to compare with.') - parser.add_argument(dest='build_script_args', nargs=argparse.REMAINDER, metavar='build-script-args', default=[] + parser.add_argument(dest='build_script_args', nargs=argparse.REMAINDER, metavar='build-script-args', default=[], help='additional arguments to build script, e.g. -- --distcc --build-args=-j30') args = parser.parse_args() @@ -303,7 +309,7 @@ if __name__ == '__main__': print('No changes between work tree and %s; nothing to compare.' % args.baseline) else: for exe in exeNames: - print '=' * 20, exe, '=' * 20 + print('=' * 20, exe, '=' * 20) timingsFileName = exe + '.out' compareTimingsFiles( os.path.join(baselineCacheDir, timingsFileName), diff --git a/utils/protocol_graph.py b/utils/protocol_graph.py index 9e39a6916cadf..62242e3919d7f 100644 --- a/utils/protocol_graph.py +++ b/utils/protocol_graph.py @@ -2,7 +2,7 @@ # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information @@ -22,6 +22,8 @@ # && open /tmp/protocols.svg #===----------------------------------------------------------------------===# +from __future__ import print_function + import re import sys import os @@ -74,7 +76,8 @@ def bodyLines(bodyText): comments = r'//.* | /[*] (.|\n)*? [*]/' # FIXME: doesn't respect strings or comment nesting) # read source, stripping all comments -sourceSansComments = re.sub(comments, '', open(args[1]).read(), flags=reFlags) +with open(args[1]) as src: + sourceSansComments = re.sub(comments, '', src.read(), flags=reFlags) genericParameterConstraint = interpolate(r' (%(identifier)s) \s* : \s* (%(identifier)s) ') @@ -139,17 +142,17 @@ def parseProtocol(m): for s in elements for t in graph[s] if t in elements) -print 'digraph ProtocolHierarchies {' -print ' mclimit = 100; ranksep=1.5; ' # ; packmode="array1" -print ' edge [dir="back"];' -print ' node [shape = box, fontname = Helvetica, fontsize = 10];' +print('digraph ProtocolHierarchies {') +print(' mclimit = 100; ranksep=1.5; ') # ; packmode="array1" +print(' edge [dir="back"];') +print(' node [shape = box, fontname = Helvetica, fontsize = 10];') for c in sorted(clusters): - print ' subgraph "cluster_%s" {' % c + print(' subgraph "cluster_%s" {' % c) for (s, t) in sorted(clusterEdges): if s in clusters[c]: - print '%s -> %s [weight=100];' % (s, t) - print '}' + print('%s -> %s [weight=100];' % (s, t)) + print('}') for node in sorted(graph.keys()): requirements = body.get(node, []) @@ -164,12 +167,12 @@ def parseProtocol(m): divider, '\n'.join('%s' % g for g in generics))) - print interpolate(' %(node)s [style = %(style)s, label=<%(label)s>]') + print(interpolate(' %(node)s [style = %(style)s, label=<%(label)s>]')) for (parent, children) in sorted(graph.items()): - print ' %s -> {' % parent, - print '; '.join( - sorted(child for child in children if not (parent, child) in clusterEdges)), - print '}' + print(' %s -> {' % parent, end=' ') + print('; '.join( + sorted(child for child in children if not (parent, child) in clusterEdges)), end=' ') + print('}') -print '}' +print('}') diff --git a/utils/pygments/swift.py b/utils/pygments/swift.py index b626e53f22daa..9be7f262b13c3 100644 --- a/utils/pygments/swift.py +++ b/utils/pygments/swift.py @@ -2,8 +2,23 @@ import re -from pygments.lexer import Lexer, RegexLexer, include, bygroups, using, this, do_insertions -from pygments.token import * +from pygments.lexer import ( + RegexLexer, + bygroups, + include, +) +from pygments.token import ( + Comment, + Generic, + Keyword, + Name, + Number, + Operator, + Punctuation, + String, + Text, + Whitespace, +) __all__ = ['SwiftLexer', 'SwiftConsoleLexer'] diff --git a/utils/recursive-lipo b/utils/recursive-lipo index e2a4a3cac3a9d..a7b5ce5407ef6 100755 --- a/utils/recursive-lipo +++ b/utils/recursive-lipo @@ -1,12 +1,14 @@ #!/usr/bin/env python +from __future__ import print_function + import argparse import os.path import filecmp import os import shutil -from SwiftBuildSupport import * +from SwiftBuildSupport import check_call def merge_file_lists(src_root_dirs, skip_files, skip_subpaths): """Merges the file lists recursively from all src_root_dirs supplied, @@ -47,7 +49,7 @@ def merge_lipo_files(src_root_dirs, file_list, copy_verbatim_subpaths, file_paths = [os.path.join(dir, file) for dir in src_root_dirs if os.path.exists(os.path.join(dir, file))] if len(file_paths) == 0: - print "-- Warning: Can't locate source file %s" % file + print("-- Warning: Can't locate source file %s" % file) continue destPath = os.path.join(dest_root_dir, os.path.relpath(file_paths[0], @@ -55,39 +57,39 @@ def merge_lipo_files(src_root_dirs, file_list, copy_verbatim_subpaths, if all([os.path.islink(item) for item in file_paths]): #It's a symlink in all found instances, copy the link. - print "-- Creating symlink %s" % destPath + print("-- Creating symlink %s" % destPath) os.symlink(os.readlink(file_paths[0]), destPath) elif all([os.path.isdir(item) for item in file_paths]): # It's a subdir in all found instances. # See if we should copy verbatim or create the destination subdir. if file in copy_verbatim_subpaths: - print "-- Copying subdir verbatim %s" % destPath + print("-- Copying subdir verbatim %s" % destPath) if os.path.isdir(destPath): shutil.rmtree(destPath) shutil.copytree(file_paths[0], destPath, symlinks=True) else: - print "-- Creating subdir %s" % destPath + print("-- Creating subdir %s" % destPath) if not os.path.isdir(destPath): os.makedirs(destPath) elif all([os.path.isfile(item) for item in file_paths]): # It's a regular file in all found instances, see if they're identical. if all([filecmp.cmp(item, file_paths[0]) for item in file_paths]): # All instances are identical, just copy the unique file. - print "-- Copying file %s" % destPath + print("-- Copying file %s" % destPath) shutil.copy2(file_paths[0], destPath) elif all([os.access(item, os.X_OK) for item in file_paths]): # Multiple instances are different and executable, try lipo. if verbose: - print "-- Running lipo %s to %s" % (file_paths, destPath) + print("-- Running lipo %s to %s" % (file_paths, destPath)) else: - print "-- Running lipo %s" % destPath + print("-- Running lipo %s" % destPath) check_call(lipo_cmd + ["-output", destPath] + file_paths, print_command=verbose, verbose=verbose) else: # Multiple instances are different, and they're not executable. - print "-- Warning: non-executable source files are different, skipping: %s" % file_paths + print("-- Warning: non-executable source files are different, skipping: %s" % file_paths) else: - print "-- Warning: Unsupport file type, skipping: %s" % file_paths + print("-- Warning: Unsupport file type, skipping: %s" % file_paths) def main(): @@ -116,7 +118,7 @@ verbatim. This is useful if some subdirectories already contain fat binaries. help="Files to ignore and skip merge/copy, default is \".DS_Store\"") parser.add_argument("--copy-subdirs", metavar="", default="", - help="Optional list of subdirecory paths that should be copied verbatim") + help="Optional list of subdirectory paths that should be copied verbatim") required_group = parser.add_argument_group("required arguments") required_group.add_argument("--destination", metavar="", @@ -135,7 +137,7 @@ verbatim. This is useful if some subdirectories already contain fat binaries. copy_verbatim_subpaths) if args.verbose: - print "Discovered files and dirs: %s" % file_list + print("Discovered files and dirs: %s" % file_list) merge_lipo_files(args.src_root_dirs, file_list, copy_verbatim_subpaths, args.destination, args.verbose, args.lipo) diff --git a/utils/runtime_statistics.d b/utils/runtime_statistics.d index eee5038ea4daa..6fb92a7ad283a 100644 --- a/utils/runtime_statistics.d +++ b/utils/runtime_statistics.d @@ -1,30 +1,20 @@ -swift*:::retain +pid$target:*:swift_retain:entry { - @counts["num retain calls"] = count(); + @counts["swift_retain"] = count(); } -swift*:::release +pid$target:*:swift_release:entry { - @counts["num release calls"] = count(); + @counts["swift_release"] = count(); } -swift*:::allocateObject +pid$target:*:objc_retain:entry { - @counts["num allocated objects"] = count(); + @counts["objc_retain"] = count(); } -swift*:::deallocateObject +pid$target:*:objc_release:entry { - @counts["num deallocated objects"] = count(); -} - -swift*:::isUniquelyReferenced -{ - @counts["num calls to isUniquelyReferenced"] = count(); -} - -swift*:::isUniquelyReferencedOrPinned -{ - @counts["num calls to isUniquelyReferencedOrPinned"] = count(); + @counts["objc_release"] = count(); } diff --git a/utils/sil-mode.el b/utils/sil-mode.el index 9bab85219af92..e332dd3ff43fd 100644 --- a/utils/sil-mode.el +++ b/utils/sil-mode.el @@ -2,7 +2,7 @@ ; ; This source file is part of the Swift.org open source project ; -; Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +; Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ; Licensed under Apache License v2.0 with Runtime Library Exception ; ; See http://swift.org/LICENSE.txt for license information @@ -64,12 +64,12 @@ "index_addr" "index_raw_pointer" "to") 'words) . font-lock-keyword-face) ;; SIL Instructions - Reference Counting. - `(,(regexp-opt '("strong_retain" "strong_retain_autoreleased" + `(,(regexp-opt '("strong_retain" "strong_release" "strong_retain_unowned" "unowned_retain" "unowned_release" "ref_to_unmanaged" "unmanaged_to_ref" "load_weak" "store_weak" "fix_lifetime" "mark_dependence" - "strong_unpin" "strong_pin") + "strong_unpin" "strong_pin" "is_unique" "is_unique_or_pinned") 'words) . font-lock-keyword-face) ;; Literals `(,(regexp-opt '("function_ref" @@ -137,10 +137,10 @@ `(,(regexp-opt '("cond_fail") 'words) . font-lock-keyword-face) ;; Terminators - `(,(regexp-opt '("unreachable" "return" "autorelease_return" "br" + `(,(regexp-opt '("unreachable" "return" "br" "cond_br" "switch_value" "switch_enum" "switch_enum_addr" "dynamic_method_br" - "checked_cast_br" "throw") + "checked_cast_br" "throw" "checked_cast_addr_br") 'words) . font-lock-keyword-face) ;; Blocks `(,(regexp-opt '("project_block_storage" "init_block_storage_header" @@ -162,7 +162,7 @@ (unless sil-mode-syntax-table (progn (setq sil-mode-syntax-table (make-syntax-table)) - (mapcar (function (lambda (n) + (mapc (function (lambda (n) (modify-syntax-entry (aref n 0) (aref n 1) sil-mode-syntax-table))) diff --git a/utils/sil-opt-verify-all-modules.py b/utils/sil-opt-verify-all-modules.py index 0bc6f9fed7400..366549b572018 100755 --- a/utils/sil-opt-verify-all-modules.py +++ b/utils/sil-opt-verify-all-modules.py @@ -1,15 +1,13 @@ #!/usr/bin/env python -#===------------------------------------------------------------------------===# +# utils/sil-opt-verify-all-modules.py - Verifies Swift modules -*- python -*- # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -# -#===------------------------------------------------------------------------===# from __future__ import print_function @@ -17,7 +15,6 @@ import glob import multiprocessing import os -import shutil import subprocess import sys import tempfile @@ -76,11 +73,6 @@ def get_verify_resource_dir_modules_commands( commands = [] module_cache_dir = tempfile.mkdtemp(prefix="swift-testsuite-clang-module-cache") for (subdir, arch, triple) in known_platforms: - platform_frameworks_dir = os.path.join( - subprocess.check_output([ - 'xcrun', '--toolchain', toolchain_name, '--show-sdk-platform-path' - ]).strip(), - 'Developer', 'Library', 'Frameworks') modules_dir = os.path.join(resource_dir, subdir, arch) print(modules_dir) modules = glob.glob(os.path.join(modules_dir, '*.swiftmodule')) @@ -119,9 +111,8 @@ def run_commands_in_parallel(commands): makefile += "all: " + " ".join(targets) + "\n" temp_dir = tempfile.mkdtemp(prefix="swift-testsuite-main") - makefile_file = open(os.path.join(temp_dir, 'Makefile'), 'w') - makefile_file.write(makefile) - makefile_file.close() + with open(os.path.join(temp_dir, 'Makefile'), 'w') as makefile_file: + makefile_file.write(makefile) max_processes = multiprocessing.cpu_count() subprocess.check_call([ diff --git a/utils/submit-benchmark-results b/utils/submit-benchmark-results index 45d7218907ab1..bdd08a2bacf5f 100755 --- a/utils/submit-benchmark-results +++ b/utils/submit-benchmark-results @@ -4,7 +4,10 @@ Utility script for submitting benchmark results to an LNT server. """ +from __future__ import print_function + import datetime +import errno import json import optparse import subprocess @@ -31,7 +34,7 @@ def capture_with_result(args, include_stderr=False): p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=stderr) except OSError,e: if e.errno == errno.ENOENT: - fatal('no such file or directory: %r when running %s.' % ( + sys.exit('no such file or directory: %r when running %s.' % ( args[0], ' '.join(args))) raise out,_ = p.communicate() @@ -59,13 +62,13 @@ def submit_results_to_server(results_data, submit_url): return json.loads(result_data) except: import traceback - print "Unable to load result, not a valid JSON object." - print - print "Traceback:" + print("Unable to load result, not a valid JSON object.") + print() + print("Traceback:") traceback.print_exc() - print - print "Result:" - print result_data + print() + print("Result:") + print(result_data) return ### diff --git a/utils/swift-bench.py b/utils/swift-bench.py index 893ddbca28354..d18173830d422 100644 --- a/utils/swift-bench.py +++ b/utils/swift-bench.py @@ -3,7 +3,7 @@ ## ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information @@ -26,7 +26,7 @@ # o When all files are compiled, the harness begins to run the tests. The # harness chooses a number of iterations for each tests to achieve the best # accuracy in the given time limit (in order to do that, it performs several -# auxiliary test runs). When the iteration number is chosen, the measurent +# auxiliary test runs). When the iteration number is chosen, the measurement # of execution time is actually performed. # o At this point everything is ready, and the harness simply reports the # results. @@ -34,9 +34,10 @@ # Ideas for the harness improvement and development are welcomed here: # rdar://problem/18072938 +from __future__ import print_function + import subprocess import numpy -import time import re import os import sys @@ -153,9 +154,8 @@ def processSource(self, name): """ benchRE = re.compile("^\s*func\s\s*bench_([a-zA-Z0-9_]+)\s*\(\s*\)\s*->\s*Int\s*({)?\s*$") - f = open(name) - lines = f.readlines() - f.close() + with open(name) as f: + lines = list(f) output = header lookingForCurlyBrace = False testNames = [] @@ -189,9 +189,8 @@ def processSource(self, name): output += mainBody % (n, n) processedName = 'processed_' + os.path.basename(name) output += mainEnd - f = open(processedName, 'w') - f.write(output) - f.close() + with open(processedName, 'w') as f: + f.write(output) for n in testNames: self.tests[name+":"+n].processedSource = processedName @@ -209,9 +208,8 @@ def compileOpaqueCFile(self): extern "C" int32_t opaqueGetInt32(int32_t x) { return x; } extern "C" int64_t opaqueGetInt64(int64_t x) { return x; } """ - f = open('opaque.cpp', 'w') - f.write(fileBody) - f.close() + with open('opaque.cpp', 'w') as f: + f.write(fileBody) # TODO: Handle subprocess.CalledProcessError for this call: self.runCommand(['clang++', 'opaque.cpp', '-o', 'opaque.o', '-c', '-O2']) @@ -297,7 +295,6 @@ def runBench(self, name): return samples = [] self.log("Running bench: %s, numsamples: %d" % (name, numSamples), 2) - output = "" for i in range(0,numSamples): try: r = self.runCommand([self.tests[name].binary, str(iterScale), diff --git a/utils/swift-mode.el b/utils/swift-mode.el index 9c65da7376e26..bda9dcc73af64 100644 --- a/utils/swift-mode.el +++ b/utils/swift-mode.el @@ -2,7 +2,7 @@ ; ; This source file is part of the Swift.org open source project ; -; Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +; Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ; Licensed under Apache License v2.0 with Runtime Library Exception ; ; See http://swift.org/LICENSE.txt for license information @@ -43,12 +43,13 @@ ;; Decl and type keywords `(,(regexp-opt '("class" "init" "deinit" "extension" "func" "import" "let" "protocol" "static" "struct" "subscript" - "typealias" "enum" "var" "where" + "typealias" "enum" "var" "lazy" "where" "private" "public" "internal" "override" "throws") 'words) . font-lock-keyword-face) ;; Statements `(,(regexp-opt '("if" "guard" "in" "else" "for" "do" "repeat" "while" "return" - "break" "continue" "switch" "case" "throw" "try" "catch") + "break" "continue" "switch" "case" "default" + "throw" "try" "catch") 'words) . font-lock-keyword-face) ;; Expressions `(,(regexp-opt '("new") 'words) . font-lock-keyword-face) diff --git a/utils/swift-project-settings.el b/utils/swift-project-settings.el index 6ee75292bb421..9ab3fe62bb204 100644 --- a/utils/swift-project-settings.el +++ b/utils/swift-project-settings.el @@ -2,7 +2,7 @@ ; ; This source file is part of the Swift.org open source project ; -; Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +; Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ; Licensed under Apache License v2.0 with Runtime Library Exception ; ; See http://swift.org/LICENSE.txt for license information @@ -156,7 +156,7 @@ Swift header should look like. "// // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/utils/swift-stdlib-tool-substitute b/utils/swift-stdlib-tool-substitute index bee61afc9b806..4893f21aada27 100755 --- a/utils/swift-stdlib-tool-substitute +++ b/utils/swift-stdlib-tool-substitute @@ -4,7 +4,7 @@ # ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information @@ -20,7 +20,7 @@ self_path=$0 tool="$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-stdlib-tool" -if [[ ! -fx "$tool" ]]; then +if [ ! -f "$tool" -o ! -x "$tool" ]; then echo "$self_path: error: couldn't find swift-stdlib-tool at $tool" exit 1 fi @@ -35,17 +35,17 @@ argv=("$@") have_source_libraries=NO platform="" set -- "$@" -while [[ $# > 0 ]]; do +while [[ $# -gt 0 ]]; do case "$1" in --source-libraries) shift - if [[ $# > 0 ]]; then + if [[ $# -gt 0 ]]; then have_source_libraries=YES fi ;; --platform) shift - if [[ $# > 0 ]]; then + if [[ $# -gt 0 ]]; then platform="$1" fi ;; @@ -63,10 +63,10 @@ elif [[ "$platform" = "" ]]; then exit 1 else # Construct a new --source-libraries argument. - bindir=`dirname "$self_path"` - usrdir=`dirname "$bindir"` + bindir=$(dirname "$self_path") + usrdir=$(dirname "$bindir") source_libraries="$usrdir/lib/swift/$platform" - if [[ ! -dx "$source_libraries" ]]; then + if [ ! -d "$source_libraries" -o ! -x "$source_libraries" ]; then echo "$self_path: error: platform path inaccessible: $source_libraries" exit 1 fi diff --git a/utils/swift_build_support/README.md b/utils/swift_build_support/README.md new file mode 100644 index 0000000000000..5746cb0174ced --- /dev/null +++ b/utils/swift_build_support/README.md @@ -0,0 +1,10 @@ +# swift_build_support + +`swift_build_support` is a Python module containing functions and data +structures used by the Swift build script. + +You may run unit tests for `swift_build_support` from the command line: + +```sh +apple/swift $ python -m unittest discover -s utils/swift_build_support +``` diff --git a/utils/swift_build_support/swift_build_support/__init__.py b/utils/swift_build_support/swift_build_support/__init__.py new file mode 100644 index 0000000000000..33ec3faf84cdb --- /dev/null +++ b/utils/swift_build_support/swift_build_support/__init__.py @@ -0,0 +1,16 @@ +# swift_build_support/__init__.py - Helpers for building Swift -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# This file needs to be here in order for Python to treat the +# utils/swift_build_support/ directory as a module. +# +# ---------------------------------------------------------------------------- diff --git a/utils/swift_build_support/swift_build_support/clang.py b/utils/swift_build_support/swift_build_support/clang.py new file mode 100644 index 0000000000000..97da55dd052de --- /dev/null +++ b/utils/swift_build_support/swift_build_support/clang.py @@ -0,0 +1,90 @@ +# swift_build_support/clang.py - Detect host machine's Clang -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# Find the path to a Clang executable on the host machine that is most +# suitable for building Swift. +# +# ---------------------------------------------------------------------------- + +from __future__ import absolute_import + +import collections +import platform +import subprocess + +from . import xcrun +from .which import which + + +# A named tuple consisting of two paths: +# 1. 'cc' is the path to a program used for compiling C. +# 2. 'cxx' is the path to a program used for compiling C++. +CompilerExecutable = collections.namedtuple('CompilerExecutable', 'cc cxx') + + +def _freebsd_release_date(): + """ + Return the release date for FreeBSD operating system on this host. + If the release date cannot be ascertained, return None. + """ + try: + # For details on `sysctl`, see: + # http://www.freebsd.org/cgi/man.cgi?sysctl(8) + return int(subprocess.check_output( + ['sysctl', '-n', 'kern.osreldate']).rstrip()) + except subprocess.CalledProcessError: + return None + + +def _first_clang(suffixes): + """ + Return a CompilerExecutable with the first available versions of clang + and clang++, searching in the order of the given suffixes. + + If no Clang executables are found, return None. + """ + for suffix in suffixes: + cc_path = which('clang{}'.format(suffix)) + cxx_path = which('clang++{}'.format(suffix)) + if cc_path and cxx_path: + return CompilerExecutable(cc=cc_path, cxx=cxx_path) + + return None + + +def host_clang(xcrun_toolchain): + """ + Return a CompilerExecutable for the host platform. + If no appropriate compilers can be found, return None. + """ + if platform.system() == 'Darwin': + cc = xcrun.find(xcrun_toolchain, 'clang') + cxx = xcrun.find(xcrun_toolchain, 'clang++') + if cc and cxx: + return CompilerExecutable(cc=cc, cxx=cxx) + else: + return None + elif platform.system() == 'FreeBSD': + # See: https://github.com/apple/swift/pull/169 + # Building Swift from source requires a recent version of the Clang + # compiler with C++14 support. + freebsd_release_date = _freebsd_release_date() + if freebsd_release_date and freebsd_release_date >= 1100000: + # On newer releases of FreeBSD, the default Clang is sufficient. + return CompilerExecutable(cc='clang', cxx='clang++') + else: + # On older releases, or on releases for which we cannot determine + # the release date, we search for the most modern version + # available. + return _first_clang(['38', '37', '36', '35']) + else: + return _first_clang(['', '-3.8', '-3.7', '-3.6', '-3.5']) diff --git a/utils/swift_build_support/swift_build_support/cmake.py b/utils/swift_build_support/swift_build_support/cmake.py new file mode 100644 index 0000000000000..b964c35f71fb6 --- /dev/null +++ b/utils/swift_build_support/swift_build_support/cmake.py @@ -0,0 +1,36 @@ +# swift_build_support/cmake.py - Detect host machine's CMake -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# Find the path to a CMake executable on the host machine. +# +# ---------------------------------------------------------------------------- + +import platform + +from . import xcrun +from .which import which + + +def host_cmake(xcrun_toolchain): + """ + Return the path to `cmake`, using tools provided by the host platform. + If `cmake` cannot be found on OS X, return None. + If `cmake` cannot be found on Linux, return a probable path. + """ + if platform.system() == 'Darwin': + return xcrun.find(xcrun_toolchain, 'cmake') + else: + cmake = which('cmake') + if cmake: + return cmake + else: + return '/usr/local/bin/cmake' diff --git a/utils/swift_build_support/swift_build_support/migration.py b/utils/swift_build_support/swift_build_support/migration.py new file mode 100644 index 0000000000000..7af2cffd0c4ae --- /dev/null +++ b/utils/swift_build_support/swift_build_support/migration.py @@ -0,0 +1,56 @@ +# swift_build_support/migration.py - Migrating build-script -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# utils/build-script takes arguments for its argument parser, as well as +# arguments that are meant to be passed directly to utils/build-script-impl. +# In order to gradually migrate away from build-script-impl, this module +# provides tools to handle parsing of these args. +# +# ---------------------------------------------------------------------------- + + +def migrate_impl_args(argv, migrate_args): + """ + Given a list of arguments of the form: + + --foo --bar=baz -- --flim=flam + + And a list of arguments to migrate, return a list in which the arguments + to migrate come before the '--' separator. For example, were we to migrate + '--flim', we would return: + + --foo --bar=baz --flim=flam -- + + Note that we do not attempt to remove the '--' separator if it is no longer + necessary, nor do we replace '--flim' if it already appears before the + separator. In these cases, argparse "does the right thing": it can handle + a trailing separator, and when options that are specified twice argparse + uses the second value. + """ + try: + split_index = argv.index('--') + except ValueError: + # If there is no separator, then we have nothing to migrate. + return argv + + args = argv[:split_index] + impl_args = argv[split_index:] + impl_args_to_remove = [] + for index, impl_arg in enumerate(impl_args): + if impl_arg.split('=')[0] in migrate_args: + args.append(impl_arg) + impl_args_to_remove.append(impl_arg) + + for impl_arg_to_remove in impl_args_to_remove: + impl_args.remove(impl_arg_to_remove) + + return args + impl_args diff --git a/utils/swift_build_support/swift_build_support/which.py b/utils/swift_build_support/swift_build_support/which.py new file mode 100644 index 0000000000000..0d76c87d12085 --- /dev/null +++ b/utils/swift_build_support/swift_build_support/which.py @@ -0,0 +1,36 @@ +# swift_build_support/which.py - shutil.which() for Python 2.7 -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# A naive reimplementation of shutil.which() for Python 2.7. This can be +# removed if shutil.which() is backported, or if the Swift build toolchain +# migrates completely to Python 3.3+. +# +# ---------------------------------------------------------------------------- + +import subprocess + + +def which(cmd): + """ + Return the path to an executable which would be run if + the given cmd was called. If no cmd would be called, return None. + + Python 3.3+ provides this behavior via the shutil.which() function; + see: https://docs.python.org/3.3/library/shutil.html#shutil.which + + We provide our own implementation because shutil.which() has not + been backported to Python 2.7, which we support. + """ + try: + return subprocess.check_output(['which', cmd]).rstrip() + except subprocess.CalledProcessError: + return None diff --git a/utils/swift_build_support/swift_build_support/xcrun.py b/utils/swift_build_support/swift_build_support/xcrun.py new file mode 100644 index 0000000000000..79cd54bbd4417 --- /dev/null +++ b/utils/swift_build_support/swift_build_support/xcrun.py @@ -0,0 +1,34 @@ +# swift_build_support/xcrun.py - Invoke xcrun from Python -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# Python wrappers for invoking `xcrun` on the command-line. +# +# ---------------------------------------------------------------------------- + +import subprocess + + +def find(toolchain, tool): + """ + Return the path for the given tool, according to `xcrun --find`, using + the given toolchain. If `xcrun --find` cannot find the tool, return None. + """ + try: + # `xcrun --find` prints to stderr when it fails to find the + # given tool. We swallow that output with a pipe. + out = subprocess.check_output(['xcrun', '--sdk', 'macosx', + '--toolchain', toolchain, + '--find', tool], + stderr=subprocess.PIPE) + return out.rstrip() + except subprocess.CalledProcessError: + return None diff --git a/utils/swift_build_support/tests/__init__.py b/utils/swift_build_support/tests/__init__.py new file mode 100644 index 0000000000000..b794f13198552 --- /dev/null +++ b/utils/swift_build_support/tests/__init__.py @@ -0,0 +1,16 @@ +# swift_build_support/tests/__init__.py - Test module -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# This file needs to be here in order for Python to treat the +# utils/swift_build_support/tests/ directory as a module. +# +# ---------------------------------------------------------------------------- diff --git a/utils/swift_build_support/tests/test_clang.py b/utils/swift_build_support/tests/test_clang.py new file mode 100644 index 0000000000000..82c6723ea3cf7 --- /dev/null +++ b/utils/swift_build_support/tests/test_clang.py @@ -0,0 +1,31 @@ +# test_clang.py - Unit tests for swift_build_support.clang -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +import os +import unittest + +from swift_build_support.clang import host_clang + + +class HostClangTestCase(unittest.TestCase): + def test_clang_available_on_this_platform(self): + # Test that Clang is installed on this platform, as a means of + # testing host_clang(). + clang = host_clang(xcrun_toolchain='default') + + # The CC and CXX from host_clang() should be of the form + # 'path/to/clang', where 'clang' may have a trailing version + # number. + self.assertTrue(os.path.split(clang.cc)[-1].startswith('clang')) + self.assertTrue(os.path.split(clang.cxx)[-1].startswith('clang++')) + + +if __name__ == '__main__': + unittest.main() diff --git a/utils/swift_build_support/tests/test_cmake.py b/utils/swift_build_support/tests/test_cmake.py new file mode 100644 index 0000000000000..35881d296a159 --- /dev/null +++ b/utils/swift_build_support/tests/test_cmake.py @@ -0,0 +1,26 @@ +# test_cmake.py - Unit tests for swift_build_support.cmake -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +import os +import unittest + +from swift_build_support.cmake import host_cmake + + +class HostCMakeTestCase(unittest.TestCase): + def test_cmake_available_on_this_platform(self): + # Test that CMake is installed on this platform, as a means of + # testing host_cmake(). + cmake = host_cmake(xcrun_toolchain='default') + self.assertEqual(os.path.split(cmake)[-1], 'cmake') + + +if __name__ == '__main__': + unittest.main() diff --git a/utils/swift_build_support/tests/test_migration.py b/utils/swift_build_support/tests/test_migration.py new file mode 100644 index 0000000000000..8a3e7ba3a09a9 --- /dev/null +++ b/utils/swift_build_support/tests/test_migration.py @@ -0,0 +1,31 @@ +# test_migration.py - Tests for swift_build_support.migration -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +import unittest + +from swift_build_support.migration import migrate_impl_args + + +class MigrateImplArgsTestCase(unittest.TestCase): + def test_args_moved_before_separator(self): + # Tests that '-RT --foo=bar -- --foo=baz --flim' is parsed as + # '-RT --foo=bar --foo=baz -- --flim' + args = migrate_impl_args( + ['-RT', '--darwin-xcrun-toolchain=foo', '--', + '--darwin-xcrun-toolchain=bar', '--other'], + ['--darwin-xcrun-toolchain']) + + self.assertEqual( + args, + ['-RT', '--darwin-xcrun-toolchain=foo', + '--darwin-xcrun-toolchain=bar', '--', '--other']) + +if __name__ == '__main__': + unittest.main() diff --git a/utils/swift_build_support/tests/test_which.py b/utils/swift_build_support/tests/test_which.py new file mode 100644 index 0000000000000..b6d6f269778bb --- /dev/null +++ b/utils/swift_build_support/tests/test_which.py @@ -0,0 +1,26 @@ +# test_which.py - Unit tests for swift_build_support.which -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +import os +import unittest + +from swift_build_support.which import which + + +class WhichTestCase(unittest.TestCase): + def test_when_cmd_not_found_returns_none(self): + self.assertIsNone(which('a-tool-that-doesnt-exist')) + + def test_when_cmd_found_returns_path(self): + self.assertEquals(os.path.split(which('ls'))[-1], 'ls') + + +if __name__ == '__main__': + unittest.main() diff --git a/utils/swift_build_support/tests/test_xcrun.py b/utils/swift_build_support/tests/test_xcrun.py new file mode 100644 index 0000000000000..d56e76602839a --- /dev/null +++ b/utils/swift_build_support/tests/test_xcrun.py @@ -0,0 +1,32 @@ +# test_xcrun.py - Unit tests for swift_build_support.xcrun -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +import platform +import unittest + +from swift_build_support import xcrun + + +class FindTestCase(unittest.TestCase): + def setUp(self): + if platform.system() != 'Darwin': + self.skipTest('XCRun tests should only be run on OS X') + + def test_when_tool_not_found_returns_none(self): + self.assertIsNone(xcrun.find( + toolchain='default', tool='a-tool-that-isnt-on-osx')) + + def test_when_tool_found_returns_path(self): + self.assertTrue(xcrun.find( + toolchain='default', tool='clang').endswith('/clang')) + + +if __name__ == '__main__': + unittest.main() diff --git a/utils/toolchain-codesign b/utils/toolchain-codesign index 2d8ba94ee246a..057b50809e1fa 100755 --- a/utils/toolchain-codesign +++ b/utils/toolchain-codesign @@ -3,7 +3,7 @@ # ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information diff --git a/utils/toolchain-installer b/utils/toolchain-installer index f3e3902383df0..202de8854b534 100755 --- a/utils/toolchain-installer +++ b/utils/toolchain-installer @@ -3,7 +3,7 @@ # ## This source file is part of the Swift.org open source project ## -## Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +## Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors ## Licensed under Apache License v2.0 with Runtime Library Exception ## ## See http://swift.org/LICENSE.txt for license information diff --git a/utils/update-checkout b/utils/update-checkout index 94d952340607a..a0ba5d896075b 100755 --- a/utils/update-checkout +++ b/utils/update-checkout @@ -1,15 +1,13 @@ #!/usr/bin/env python -#===--- update-checkout - Utility to update your local checkouts -----------===# +# utils/update-checkout - Utility to update your local checkouts -*- python -*- # # This source file is part of the Swift.org open source project # -# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See http://swift.org/LICENSE.txt for license information # See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -# -#===------------------------------------------------------------------------===# from __future__ import print_function @@ -19,25 +17,11 @@ import sys sys.path.append(os.path.dirname(__file__)) -from SwiftBuildSupport import * - - -def update_git_svn(repo_path): - with WorkingDirectory(repo_path): - use_stash = (check_output([ "git", "status", "--porcelain" ]) != "") - if use_stash: - check_call([ "git", "stash", "save", "--all"]) - - # Try first to pull from an upstream Git repo, assuming there is one - if check_output([ "git", "remote" ]) != "": - check_call([ "git", "pull", "--rebase" ]) - check_call([ "git", "svn", "rebase", "-l" ]) - else: - check_call([ "git", "svn", "rebase" ]) - - if use_stash: - check_call([ "git", "stash", "pop" ]) - +from SwiftBuildSupport import ( + SWIFT_SOURCE_ROOT, + WorkingDirectory, + check_call, +) def update_working_copy(repo_path): if not os.path.isdir(repo_path): @@ -45,13 +29,33 @@ def update_working_copy(repo_path): print("--- Updating '" + repo_path + "' ---") with WorkingDirectory(repo_path): - if os.path.isdir(os.path.join(".git", "svn")): - update_git_svn(repo_path) - elif os.path.isdir(".git"): - check_call([ "git", "pull" ]) - else: - check_call([ "svn", "update" ]) - + # Prior to Git 2.6, this is the way to do a "git pull + # --rebase" that respects rebase.autostash. See + # http://stackoverflow.com/a/30209750/125349 + check_call([ "git", "fetch" ]) + check_call([ "git", "rebase", "FETCH_HEAD" ]) + +def obtain_additional_swift_sources(opts = {'with_ssh': False}): + additional_repos = { + 'llvm': 'apple/swift-llvm', + 'clang': 'apple/swift-clang', + 'lldb': 'apple/swift-lldb', + 'cmark': 'apple/swift-cmark', + 'llbuild': 'apple/swift-llbuild', + 'swiftpm': 'apple/swift-package-manager', + 'swift-corelibs-xctest': 'apple/swift-corelibs-xctest', + 'swift-corelibs-foundation': 'apple/swift-corelibs-foundation', + 'swift-integration-tests': 'apple/swift-integration-tests', + } + for dir_name, repo in additional_repos.items(): + with WorkingDirectory(SWIFT_SOURCE_ROOT): + if not os.path.isdir(os.path.join(dir_name, ".git")): + print("--- Cloning '" + dir_name + "' ---") + if opts['with_ssh'] is True: + remote = "git@github.com:" + repo + '.git' + else: + remote = "https://github.com/" + repo + '.git' + check_call(['git', 'clone', remote, dir_name]) def main(): parser = argparse.ArgumentParser( @@ -63,8 +67,22 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""") parser.add_argument("-a", "--all", help="also update checkouts of llbuild, LLVM, and Clang", action="store_true") + parser.add_argument("--clone", + help="Obtain Sources for Swift and Related Projects", + action="store_true") + parser.add_argument("--clone-with-ssh", + help="Obtain Sources for Swift and Related Projects via SSH", + action="store_true") args = parser.parse_args() + if args.clone: + obtain_additional_swift_sources() + return 0 + + if args.clone_with_ssh: + obtain_additional_swift_sources({'with_ssh': True}) + return 0 + if args.all: update_working_copy(os.path.join(SWIFT_SOURCE_ROOT, "llbuild")) update_working_copy(os.path.join(SWIFT_SOURCE_ROOT, "llvm")) @@ -79,6 +97,7 @@ By default, updates your checkouts of Swift, SourceKit, LLDB, and SwiftPM.""") update_working_copy(os.path.join(SWIFT_SOURCE_ROOT, "swiftpm")) update_working_copy(os.path.join(SWIFT_SOURCE_ROOT, "swift-corelibs-foundation")) update_working_copy(os.path.join(SWIFT_SOURCE_ROOT, "swift-corelibs-xctest")) + update_working_copy(os.path.join(SWIFT_SOURCE_ROOT, "swift-integration-tests")) return 0 diff --git a/utils/viewcfg b/utils/viewcfg index 9935da52d900f..fcf7e08df9aa0 100755 --- a/utils/viewcfg +++ b/utils/viewcfg @@ -1,35 +1,47 @@ #!/usr/bin/env python - -# A script for viewing the CFG of SIL and llvm IR. - -# For vim users: use the following lines in .vimrc +# viewcfg - A script for viewing the CFG of SIL and LLVM IR -*- python -*- +# +# This source file is part of the Swift.org open source project +# +# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +# Licensed under Apache License v2.0 with Runtime Library Exception +# +# See http://swift.org/LICENSE.txt for license information +# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +# +# ---------------------------------------------------------------------------- +# +# For vim users: use the following lines in .vimrc... # # com! -nargs=? Funccfg silent ?{$?,/^}/w !viewcfg # com! -range -nargs=? Viewcfg silent ,w !viewcfg # -# to add these commands: +# ...to add these commands: # -# :Funccfg displays the CFG of the current SIL/llvm function. +# :Funccfg displays the CFG of the current SIL/LLVM function. # :Viewcfg displays the sub-CFG of the selected range. # # Note: viewcfg should be in the $PATH and .dot files should be associated # with the Graphviz app. +# +# ---------------------------------------------------------------------------- + +from __future__ import print_function import re import sys import tempfile import subprocess -import os def help(): - print """\ + print("""\ Usage: viewcfg [output-suffix] < file By default all CFGs are opened in the same window. Use the a unique output-suffix to open a CFG in a new window. -""" +""") class Block: @@ -119,7 +131,7 @@ def main(): newBlocks = { } for name, block in blocks.iteritems(): for adjName in (block.preds + block.getSuccs()): - if not adjName in blocks: + if adjName not in blocks: newBlocks[adjName] = Block(adjName, None) blocks = dict(blocks.items() + newBlocks.items()) @@ -130,37 +142,33 @@ def main(): for name, block in blocks.iteritems(): for predName in block.preds: predBlock = blocks[predName] - if not name in predBlock.getSuccs(): + if name not in predBlock.getSuccs(): predBlock.getSuccs().append(name) # Write the output dot file. fileName = tempfile.gettempdir() + "/viewcfg" + suffix + ".dot" - outFile = open(fileName, "w") - - outFile.write('digraph "CFG" {\n') - for name, block in blocks.iteritems(): - if block.content is not None: - outFile.write("\tNode" + str(block.index) + \ - " [shape=record,label=\"{" + block.content + "}\"];\n") - else: - outFile.write("\tNode" + str(block.index) + \ - " [shape=record,color=gray,fontcolor=gray,label=\"{" + \ - block.name + "}\"];\n") - - for succName in block.getSuccs(): - succBlock = blocks[succName] - outFile.write("\tNode" + str(block.index) + " -> Node" + \ - str(succBlock.index) + ";\n") - - outFile.write("}\n") - outFile.flush() - os.fsync(outFile.fileno()) - outFile.close + with open(fileName, 'w') as outFile: + outFile.write('digraph "CFG" {\n') + for name, block in blocks.iteritems(): + if block.content is not None: + outFile.write("\tNode" + str(block.index) + + " [shape=record,label=\"{" + block.content + "}\"];\n") + else: + outFile.write("\tNode" + str(block.index) + + " [shape=record,color=gray,fontcolor=gray,label=\"{" + + block.name + "}\"];\n") + + for succName in block.getSuccs(): + succBlock = blocks[succName] + outFile.write("\tNode" + str(block.index) + " -> Node" + + str(succBlock.index) + ";\n") + + outFile.write("}\n") # Open the dot file (should be done with Graphviz). subprocess.call(["open", fileName]) -main() - +if __name__ == '__main__': + main() diff --git a/utils/vim/ftdetect/sil.vim b/utils/vim/ftdetect/sil.vim new file mode 100644 index 0000000000000..3d856ed3b8280 --- /dev/null +++ b/utils/vim/ftdetect/sil.vim @@ -0,0 +1 @@ +au BufNewFile,BufRead *.sil set ft=sil diff --git a/utils/vim/syntax/sil.vim b/utils/vim/syntax/sil.vim index 747429290815d..9a41c65d66bde 100644 --- a/utils/vim/syntax/sil.vim +++ b/utils/vim/syntax/sil.vim @@ -25,7 +25,7 @@ syn keyword swiftKeyword getter setter allocator initializer enumelt destroyer g syn keyword swiftKeyword alloc_stack alloc_ref alloc_ref_dynamic alloc_box dealloc_stack dealloc_box dealloc_ref skipwhite syn keyword swiftKeyword debug_value debug_value_addr skipwhite syn keyword swiftKeyword load store assign mark_uninitialized mark_function_escape copy_addr destroy_addr index_addr index_raw_pointer to skipwhite -syn keyword swiftKeyword strong_retain strong_retain_autoreleased strong_release strong_retain_unowned ref_to_unowned unowned_to_ref unowned_retain unowned_release load_weak store_weak fix_lifetime skipwhite +syn keyword swiftKeyword strong_retain strong_release strong_retain_unowned ref_to_unowned unowned_to_ref unowned_retain unowned_release load_weak store_weak fix_lifetime skipwhite syn keyword swiftKeyword function_ref integer_literal float_literal string_literal global_addr skipwhite syn keyword swiftKeyword class_method super_method witness_method dynamic_method skipwhite syn keyword swiftKeyword apply partial_apply builtin skipwhite @@ -36,7 +36,7 @@ syn keyword swiftKeyword init_existential_addr deinit_existential_addr open_exis syn keyword swiftKeyword upcast address_to_pointer pointer_to_address unchecked_addr_cast unchecked_ref_cast ref_to_raw_pointer raw_pointer_to_ref convert_function thick_to_objc_metatype objc_to_thick_metatype thin_to_thick_function is_nonnull unchecked_ref_bit_cast unchecked_trivial_bit_cast skipwhite syn keyword swiftKeyword unconditional_checked_cast skipwhite syn keyword swiftKeyword cond_fail skipwhite -syn keyword swiftKeyword unreachable return autorelease_return br cond_br switch_value select_value switch_enum switch_enum_addr dynamic_method_br checked_cast_br skipwhite +syn keyword swiftKeyword unreachable return br cond_br switch_value select_value switch_enum switch_enum_addr dynamic_method_br checked_cast_br skipwhite syn keyword swiftKeyword project_block_storage init_block_storage_header copy_block skipwhite syn keyword swiftTypeDefinition class extension protocol struct typealias enum skipwhite nextgroup=swiftTypeName diff --git a/utils/vim/syntax/swift.vim b/utils/vim/syntax/swift.vim index fad03cf579ef7..407aed1280d30 100644 --- a/utils/vim/syntax/swift.vim +++ b/utils/vim/syntax/swift.vim @@ -45,8 +45,8 @@ syn keyword swiftBoolean true false syn region swiftString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=swiftInterpolation syn region swiftInterpolation start=/\\(/ end=/)/ contained -syn region swiftComment start="/\*" end="\*/" contains=swiftComment -syn region swiftLineComment start="//" end="$" +syn region swiftComment start="/\*" end="\*/" contains=swiftComment,swiftLineComment,swiftTodo +syn region swiftLineComment start="//" end="$" contains=swiftComment,swiftTodo syn match swiftDecimal /[+\-]\?\<\([0-9][0-9_]*\)\([.][0-9_]*\)\?\([eE][+\-]\?[0-9][0-9_]*\)\?\>/ syn match swiftHex /[+\-]\?\<0x[0-9A-Fa-f][0-9A-Fa-f_]*\(\([.][0-9A-Fa-f_]*\)\?[pP][+\-]\?[0-9][0-9_]*\)\?\>/ @@ -64,6 +64,8 @@ syn match swiftPreproc /^#\\|^#\/ syn match swiftAttribute /@\<\w\+\>/ skipwhite +syn keyword swiftTodo TODO FIXME contained + hi def link swiftImport Include hi def link swiftImportModule Title hi def link swiftImportComponent Identifier @@ -98,5 +100,6 @@ hi def link swiftNew Operator hi def link swiftMutating Statement hi def link swiftPreproc PreCondit hi def link swiftAttribute Type +hi def link swiftTodo Todo let b:current_syntax = "swift" diff --git a/validation-test/IDE/crashers/001-swift-ide-removecodecompletiontokens.swift b/validation-test/IDE/crashers/001-swift-ide-removecodecompletiontokens.swift new file mode 100644 index 0000000000000..dd9862a9c3bd4 --- /dev/null +++ b/validation-test/IDE/crashers/001-swift-ide-removecodecompletiontokens.swift @@ -0,0 +1,2 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +#^ diff --git a/validation-test/IDE/crashers/002-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/IDE/crashers/002-swift-diagnosticengine-emitdiagnostic.swift new file mode 100644 index 0000000000000..4f7dfc79b8251 --- /dev/null +++ b/validation-test/IDE/crashers/002-swift-diagnosticengine-emitdiagnostic.swift @@ -0,0 +1,2 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +let a{protocol A{struct B{class a{#^A^# diff --git a/validation-test/IDE/crashers/003-swift-typebase-getcanonicaltype.swift b/validation-test/IDE/crashers/003-swift-typebase-getcanonicaltype.swift new file mode 100644 index 0000000000000..05c1ba8171bb0 --- /dev/null +++ b/validation-test/IDE/crashers/003-swift-typebase-getcanonicaltype.swift @@ -0,0 +1,2 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +extension{struct E{enum C{let a{#^A^# diff --git a/validation-test/IDE/crashers/006-swift-declcontext-getprotocolself.swift b/validation-test/IDE/crashers/006-swift-declcontext-getprotocolself.swift new file mode 100644 index 0000000000000..e859fc986649c --- /dev/null +++ b/validation-test/IDE/crashers/006-swift-declcontext-getprotocolself.swift @@ -0,0 +1,3 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +extension{protocol a{func p)struct A{protocol c +let a{#^A^# \ No newline at end of file diff --git a/validation-test/IDE/crashers/007-swift-configureimplicitself.swift b/validation-test/IDE/crashers/007-swift-configureimplicitself.swift new file mode 100644 index 0000000000000..bf0a1ebdcc892 --- /dev/null +++ b/validation-test/IDE/crashers/007-swift-configureimplicitself.swift @@ -0,0 +1,2 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +extension{enum c{func a:#^A^# \ No newline at end of file diff --git a/validation-test/IDE/crashers/008-swift-typechecker-typecheckfunctionbodyuntil.swift b/validation-test/IDE/crashers/008-swift-typechecker-typecheckfunctionbodyuntil.swift new file mode 100644 index 0000000000000..5036251ca2306 --- /dev/null +++ b/validation-test/IDE/crashers/008-swift-typechecker-typecheckfunctionbodyuntil.swift @@ -0,0 +1,2 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +func a(={#^A^# \ No newline at end of file diff --git a/validation-test/IDE/crashers/009-swift-performdelayedparsing.swift b/validation-test/IDE/crashers/009-swift-performdelayedparsing.swift new file mode 100644 index 0000000000000..70008648493aa --- /dev/null +++ b/validation-test/IDE/crashers/009-swift-performdelayedparsing.swift @@ -0,0 +1,2 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +enum b:a{var f={static#^A^# \ No newline at end of file diff --git a/validation-test/IDE/crashers/010-swift-archetypebuilder-addrequirement.swift b/validation-test/IDE/crashers/010-swift-archetypebuilder-addrequirement.swift new file mode 100644 index 0000000000000..1fd2cd1b70f53 --- /dev/null +++ b/validation-test/IDE/crashers/010-swift-archetypebuilder-addrequirement.swift @@ -0,0 +1,7 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +// REQUIRES: asserts +#^A^#{" +protocol c{ +func a +typealias b:c +typealias e:c \ No newline at end of file diff --git a/validation-test/IDE/crashers/011-swift-lookupvisibledecls.swift b/validation-test/IDE/crashers/011-swift-lookupvisibledecls.swift new file mode 100644 index 0000000000000..7fdf59e4e9cfe --- /dev/null +++ b/validation-test/IDE/crashers/011-swift-lookupvisibledecls.swift @@ -0,0 +1,3 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +// REQUIRES: asserts +enum Sstruct B \ No newline at end of file diff --git a/validation-test/IDE/crashers/023-swift-archetypebuilder-addgenericparameter.swift b/validation-test/IDE/crashers/023-swift-archetypebuilder-addgenericparameter.swift new file mode 100644 index 0000000000000..769b270b96adb --- /dev/null +++ b/validation-test/IDE/crashers/023-swift-archetypebuilder-addgenericparameter.swift @@ -0,0 +1,3 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +// REQUIRES: asserts +var a{protocol A{struct a{func dstruct B[Void{#^A^# \ No newline at end of file diff --git a/validation-test/IDE/crashers/056-swift-archetypebuilder-getallarchetypes.swift b/validation-test/IDE/crashers/056-swift-archetypebuilder-getallarchetypes.swift new file mode 100644 index 0000000000000..81231409912f9 --- /dev/null +++ b/validation-test/IDE/crashers/056-swift-archetypebuilder-getallarchetypes.swift @@ -0,0 +1,9 @@ +// RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s +// REQUIRES: asserts +var e{ +protocol A{ +func b:e protocol e{ +typealias e:e:protocol e{ +enum a{ +func a( diff --git a/validation-test/SIL/crashers/005-swift-silfunction-verify.sil b/validation-test/SIL/crashers/005-swift-silfunction-verify.sil new file mode 100644 index 0000000000000..d3c647dea6d26 --- /dev/null +++ b/validation-test/SIL/crashers/005-swift-silfunction-verify.sil @@ -0,0 +1,3 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +sil shared_external@a:$()->() diff --git a/validation-test/SIL/crashers/006-swift-syntaxsugartype-getimplementationtype.sil b/validation-test/SIL/crashers/006-swift-syntaxsugartype-getimplementationtype.sil new file mode 100644 index 0000000000000..94f12e441790c --- /dev/null +++ b/validation-test/SIL/crashers/006-swift-syntaxsugartype-getimplementationtype.sil @@ -0,0 +1,4 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +class C +struct e{weak var x:C \ No newline at end of file diff --git a/validation-test/SIL/crashers/007-swift-abstractstoragedecl-makecomputed.sil b/validation-test/SIL/crashers/007-swift-abstractstoragedecl-makecomputed.sil new file mode 100644 index 0000000000000..c6e5191e35b1a --- /dev/null +++ b/validation-test/SIL/crashers/007-swift-abstractstoragedecl-makecomputed.sil @@ -0,0 +1,3 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +protocol a{@sil_stored var e:a{get \ No newline at end of file diff --git a/validation-test/SIL/crashers/008-swift-genericparamlist-getasgenericsignatureelements.sil b/validation-test/SIL/crashers/008-swift-genericparamlist-getasgenericsignatureelements.sil new file mode 100644 index 0000000000000..651bdb260eeed --- /dev/null +++ b/validation-test/SIL/crashers/008-swift-genericparamlist-getasgenericsignatureelements.sil @@ -0,0 +1,3 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +sil@__:$<__ where τ:k>()->( \ No newline at end of file diff --git a/validation-test/SIL/crashers/009-swift-parser-parsedeclsil.sil b/validation-test/SIL/crashers/009-swift-parser-parsedeclsil.sil new file mode 100644 index 0000000000000..34cc04e9f84a1 --- /dev/null +++ b/validation-test/SIL/crashers/009-swift-parser-parsedeclsil.sil @@ -0,0 +1,3 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +sil private@s:$()->() \ No newline at end of file diff --git a/validation-test/SIL/crashers/010-swift-typechecker-addimplicitconstructors.sil b/validation-test/SIL/crashers/010-swift-typechecker-addimplicitconstructors.sil new file mode 100644 index 0000000000000..c14ba2b1764e9 --- /dev/null +++ b/validation-test/SIL/crashers/010-swift-typechecker-addimplicitconstructors.sil @@ -0,0 +1,4 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +class C{@NSManaged var S +var h \ No newline at end of file diff --git a/validation-test/SIL/crashers/011-swift-typechecker-validatetype.sil b/validation-test/SIL/crashers/011-swift-typechecker-validatetype.sil new file mode 100644 index 0000000000000..a2f45e50ef1bc --- /dev/null +++ b/validation-test/SIL/crashers/011-swift-typechecker-validatetype.sil @@ -0,0 +1,2 @@ +// RUN: not --crash %target-sil-opt %s +sil@s:$()->(@owned T c:t \ No newline at end of file diff --git a/validation-test/SIL/crashers/012-swift-dependentgenerictyperesolver-resolveselfassociatedtype.sil b/validation-test/SIL/crashers/012-swift-dependentgenerictyperesolver-resolveselfassociatedtype.sil new file mode 100644 index 0000000000000..4e3aa945d2c67 --- /dev/null +++ b/validation-test/SIL/crashers/012-swift-dependentgenerictyperesolver-resolveselfassociatedtype.sil @@ -0,0 +1,2 @@ +// RUN: not --crash %target-sil-opt %s +protocol O{func f(a{return:}class a \ No newline at end of file diff --git a/validation-test/SIL/crashers/017-swift-decl-walk.sil b/validation-test/SIL/crashers/017-swift-decl-walk.sil new file mode 100644 index 0000000000000..877fd654724ca --- /dev/null +++ b/validation-test/SIL/crashers/017-swift-decl-walk.sil @@ -0,0 +1,4 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +// REQUIRES: swift_ast_verifier +import Swift func g(@opened(Any diff --git a/validation-test/SIL/crashers/018-swift-valuedecl-getinterfacetype.sil b/validation-test/SIL/crashers/018-swift-valuedecl-getinterfacetype.sil new file mode 100644 index 0000000000000..9d15bd200d087 --- /dev/null +++ b/validation-test/SIL/crashers/018-swift-valuedecl-getinterfacetype.sil @@ -0,0 +1,3 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +@objc protocol P{func t throw \ No newline at end of file diff --git a/validation-test/SIL/crashers/019-swift-parser-parseexprpostfix.sil b/validation-test/SIL/crashers/019-swift-parser-parseexprpostfix.sil new file mode 100644 index 0000000000000..480f5bb1c7bcf --- /dev/null +++ b/validation-test/SIL/crashers/019-swift-parser-parseexprpostfix.sil @@ -0,0 +1,2 @@ +// RUN: not --crash %target-sil-opt %s +C<@convention()>{ \ No newline at end of file diff --git a/validation-test/SIL/crashers/020-swift-moduledecl-lookupconformance.sil b/validation-test/SIL/crashers/020-swift-moduledecl-lookupconformance.sil new file mode 100644 index 0000000000000..4450c8e1b7fc0 --- /dev/null +++ b/validation-test/SIL/crashers/020-swift-moduledecl-lookupconformance.sil @@ -0,0 +1,3 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +enum l:V \ No newline at end of file diff --git a/validation-test/SIL/crashers/021-swift-typechecker-typecheckdecl.sil b/validation-test/SIL/crashers/021-swift-typechecker-typecheckdecl.sil new file mode 100644 index 0000000000000..a6a1455751b4c --- /dev/null +++ b/validation-test/SIL/crashers/021-swift-typechecker-typecheckdecl.sil @@ -0,0 +1,3 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +protocol P{var e:()->( \ No newline at end of file diff --git a/validation-test/SIL/crashers/023-swift-parser-parseexpridentifier.sil b/validation-test/SIL/crashers/023-swift-parser-parseexpridentifier.sil new file mode 100644 index 0000000000000..c7603974e854b --- /dev/null +++ b/validation-test/SIL/crashers/023-swift-parser-parseexpridentifier.sil @@ -0,0 +1,3 @@ +// RUN: not --crash %target-sil-opt %s +// REQUIRES: asserts +enum n{func p \ No newline at end of file diff --git a/validation-test/compiler_crashers/0226-swift-lowering-silgenfunction-emitcurrythunk.swift b/validation-test/compiler_crashers/00226-swift-lowering-silgenfunction-emitcurrythunk.swift similarity index 100% rename from validation-test/compiler_crashers/0226-swift-lowering-silgenfunction-emitcurrythunk.swift rename to validation-test/compiler_crashers/00226-swift-lowering-silgenfunction-emitcurrythunk.swift diff --git a/validation-test/compiler_crashers/0314-swift-lowering-typeconverter-getloweredastfunctiontype.swift b/validation-test/compiler_crashers/00314-swift-lowering-typeconverter-getloweredastfunctiontype.swift similarity index 100% rename from validation-test/compiler_crashers/0314-swift-lowering-typeconverter-getloweredastfunctiontype.swift rename to validation-test/compiler_crashers/00314-swift-lowering-typeconverter-getloweredastfunctiontype.swift diff --git a/validation-test/compiler_crashers/0494-swift-metatypetype-get.swift b/validation-test/compiler_crashers/00494-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers/0494-swift-metatypetype-get.swift rename to validation-test/compiler_crashers/00494-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers/0697-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers/00697-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers/0697-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers/00697-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers/1766-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers/01766-swift-typechecker-validatedecl.swift similarity index 100% rename from validation-test/compiler_crashers/1766-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers/01766-swift-typechecker-validatedecl.swift diff --git a/validation-test/compiler_crashers/1817-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers/01817-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers/1817-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers/01817-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers/0211-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers/0211-swift-completegenerictyperesolver-resolvedependentmembertype.swift deleted file mode 100644 index cb216dd77f33c..0000000000000 --- a/validation-test/compiler_crashers/0211-swift-completegenerictyperesolver-resolvedependentmembertype.swift +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing -// Distributed under the terms of the MIT license - -func c() -> (e, e -> e) -> e { - f b f.f =c { -} -struct f() -> (f, f -> f) -> f { - g e {} -struct g V { -class d Int { -class A { -class func f { -init (e: A.B) { -} -static -func c() -> (g, g -> g) -> g { -d b d.f = { -} -{ -g) { -i } -} -i c { -} -class d: c{ class func f {} -struct d diff --git a/validation-test/compiler_crashers/0539-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers/0539-swift-nominaltypedecl-getdeclaredtypeincontext.swift deleted file mode 100644 index ccebdfa368b49..0000000000000 --- a/validation-test/compiler_crashers/0539-swift-nominaltypedecl-getdeclaredtypeincontext.swift +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class B T -> V, f: String { -struct e = { -} -deinit { -enum S:T \ No newline at end of file diff --git a/validation-test/compiler_crashers/0637-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers/0637-swift-lexer-getlocforendoftoken.swift deleted file mode 100644 index 071c333603a2f..0000000000000 --- a/validation-test/compiler_crashers/0637-swift-lexer-getlocforendoftoken.swift +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func b { -func f: I.e = ") -} -} -var d = { diff --git a/validation-test/compiler_crashers/0647-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers/0647-std-function-func-swift-type-subst.swift deleted file mode 100644 index d5579adc4660d..0000000000000 --- a/validation-test/compiler_crashers/0647-std-function-func-swift-type-subst.swift +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol P { -protocol A { -static let c: B) -} -func g: A? = .Type) -> { -let c((" -typealias B() diff --git a/validation-test/compiler_crashers/0740-swift-metatypetype-get.swift b/validation-test/compiler_crashers/0740-swift-metatypetype-get.swift deleted file mode 100644 index 96d0c3c115882..0000000000000 --- a/validation-test/compiler_crashers/0740-swift-metatypetype-get.swift +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct S { -b> { -protocol d where I) -> String { -class A { -} -} -deinit { -} -} -var b() -> S:T.j \ No newline at end of file diff --git a/validation-test/compiler_crashers/0890-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers/0890-swift-completegenerictyperesolver-resolvedependentmembertype.swift deleted file mode 100644 index 4aa47855de579..0000000000000 --- a/validation-test/compiler_crashers/0890-swift-completegenerictyperesolver-resolvedependentmembertype.swift +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct d { -c: C { -} -override init() { -struct d V { -class func g: I.c : T>() -> Int = 0) { -} -} -typealias F = D> { -} -return b diff --git a/validation-test/compiler_crashers/1035-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers/1035-swift-completegenerictyperesolver-resolvedependentmembertype.swift deleted file mode 100644 index 016b29be8ad4e..0000000000000 --- a/validation-test/compiler_crashers/1035-swift-completegenerictyperesolver-resolvedependentmembertype.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct Q T : NSManagedObject { -class a { -deinit { -struct c = { _, g == a!): -} -protocol a { -typealias F>() { -} -func b: T.e(start: diff --git a/validation-test/compiler_crashers/10659-swift-printingdiagnosticconsumer-handlediagnostic.timeout.swift b/validation-test/compiler_crashers/10659-swift-printingdiagnosticconsumer-handlediagnostic.timeout.swift new file mode 100644 index 0000000000000..01e8a74630394 --- /dev/null +++ b/validation-test/compiler_crashers/10659-swift-printingdiagnosticconsumer-handlediagnostic.timeout.swift @@ -0,0 +1,10 @@ +// RUN: not --crash %target-swift-frontend %s -parse +// REQUIRES: asserts + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol c:A +protocol A:d +protocol d:d diff --git a/validation-test/compiler_crashers/1085-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers/1085-swift-declcontext-lookupqualified.swift deleted file mode 100644 index 7e0b3eb5ec3ad..0000000000000 --- a/validation-test/compiler_crashers/1085-swift-declcontext-lookupqualified.swift +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct B { -func f() -> (g, g -> g) -> g { -d j d.i = { -} -{ -g) { -h } -} -protocol f { -} -class d: f{ class func i {} -struct d { -} -} -protocol a { -typeal= D>(e: A.B) { -} -} -} -override func d() -> String { -func} -func b((Any, c))(Any, AnyObject -func g(f: B) { -} -struct c == S.Generator.Element> diff --git a/validation-test/compiler_crashers/1268-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers/1268-swift-lexer-lexidentifier.swift deleted file mode 100644 index 90795d69187d6..0000000000000 --- a/validation-test/compiler_crashers/1268-swift-lexer-lexidentifier.swift +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol k { -typealias m -} -struct e {n: j -let i: j.m -} -func g() -> (f, f -> f) -> f { -g e {} -struct g() -> (g, g -> g) -> g { -d j d.i = { -} -{ -g) { -h } -} -protocol f { -} -struct d diff --git a/validation-test/compiler_crashers/1487-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers/1487-std-function-func-swift-type-subst.swift deleted file mode 100644 index 54560f0a88193..0000000000000 --- a/validation-test/compiler_crashers/1487-std-function-func-swift-type-subst.swift +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func b: a { -protocol C { -func a: A(T -override func f(") -typealias B { -} -deinit { -typealias B { -} -} -b: c> { -} -} -protocol A { -struct A { -} -let t: B) diff --git a/validation-test/compiler_crashers/16694-swift-constraints-constraintsystem-opentype.swift b/validation-test/compiler_crashers/16694-swift-constraints-constraintsystem-opentype.swift new file mode 100644 index 0000000000000..0262c4be819dc --- /dev/null +++ b/validation-test/compiler_crashers/16694-swift-constraints-constraintsystem-opentype.swift @@ -0,0 +1,8 @@ +// RUN: not --crash %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +// Crash type: memory error ("Invalid read of size 4") +var a{class d{var b=B{}let c=(x:d:a diff --git a/validation-test/compiler_crashers/1741-swift-constraints-constraintsystem-simplifymemberconstraint.swift b/validation-test/compiler_crashers/1741-swift-constraints-constraintsystem-simplifymemberconstraint.swift deleted file mode 100644 index f484c51efa649..0000000000000 --- a/validation-test/compiler_crashers/1741-swift-constraints-constraintsystem-simplifymemberconstraint.swift +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -([() -enum B : A { -f(x) -> { -} -} -protocol A { -protocol a { -} -func d -typealias b : b = b[1 -s diff --git a/validation-test/compiler_crashers/2030-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers/2030-std-function-func-swift-type-subst.swift deleted file mode 100644 index e260aa75e6218..0000000000000 --- a/validation-test/compiler_crashers/2030-std-function-func-swift-type-subst.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: not --crash %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol C { -typealias d.advance(s: C> [unowned self) -return """"ab""").b { -class func b(b, () -> Any in -protocol a { -} -enum a Any) { -} -protocol b { -let h : d>("""" diff --git a/validation-test/compiler_crashers/24394-swift-typevariabletype-implementation-getrepresentative.swift b/validation-test/compiler_crashers/24394-swift-typevariabletype-implementation-getrepresentative.swift index 3c022a115c12c..37c7eae4b193f 100644 --- a/validation-test/compiler_crashers/24394-swift-typevariabletype-implementation-getrepresentative.swift +++ b/validation-test/compiler_crashers/24394-swift-typevariabletype-implementation-getrepresentative.swift @@ -4,6 +4,7 @@ // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing +// Crash type: memory error ("Invalid read of size 8") [Void{}}struct A protocol A{typealias b:A func b class A { + let s : X +} diff --git a/validation-test/compiler_crashers/25458-swift-archetypetype-getnestedtype.swift b/validation-test/compiler_crashers/25458-swift-archetypetype-getnestedtype.swift index 31c97a901d7c9..f235a07b3ee17 100644 --- a/validation-test/compiler_crashers/25458-swift-archetypetype-getnestedtype.swift +++ b/validation-test/compiler_crashers/25458-swift-archetypetype-getnestedtype.swift @@ -4,6 +4,7 @@ // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing +// Crash type: memory error ("Invalid read of size 8") class a{ class c class B:A diff --git a/validation-test/compiler_crashers/25962-swift-archetypebuilder-getallarchetypes.swift b/validation-test/compiler_crashers/25962-swift-archetypebuilder-getallarchetypes.swift new file mode 100644 index 0000000000000..1a73eeb6239aa --- /dev/null +++ b/validation-test/compiler_crashers/25962-swift-archetypebuilder-getallarchetypes.swift @@ -0,0 +1,8 @@ +// RUN: not --crash %target-swift-frontend %s -parse +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/adocyn (adocyn) + +extension CollectionType { + func f() { + } +} diff --git a/validation-test/compiler_crashers/26303-llvm-llvm-unreachable-internal.swift b/validation-test/compiler_crashers/26303-llvm-llvm-unreachable-internal.swift new file mode 100644 index 0000000000000..9d568fd3b05ab --- /dev/null +++ b/validation-test/compiler_crashers/26303-llvm-llvm-unreachable-internal.swift @@ -0,0 +1,12 @@ +// RUN: not --crash %target-swift-frontend %s -emit-silgen +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/airspeedswift (airspeedswift) + +struct S { + var a: [T] = [] +} +extension S { + init(other: [T]) { + a = other + } +} diff --git a/validation-test/compiler_crashers/26813-generic-enum-tuple-optional-payload.swift b/validation-test/compiler_crashers/26813-generic-enum-tuple-optional-payload.swift new file mode 100644 index 0000000000000..11be37c4cb1a9 --- /dev/null +++ b/validation-test/compiler_crashers/26813-generic-enum-tuple-optional-payload.swift @@ -0,0 +1,13 @@ +// RUN: not --crash %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/austinzheng (Austin Zheng) + +enum A { + case Just(T) + case Error +} + +func foo() -> A<(String, String?)> { + return A.Just("abc", "def") +} diff --git a/validation-test/compiler_crashers/27203-swift-typeloc-iserror.swift b/validation-test/compiler_crashers/27203-swift-typeloc-iserror.swift index 2c9a97bb832b3..b336d90595c79 100644 --- a/validation-test/compiler_crashers/27203-swift-typeloc-iserror.swift +++ b/validation-test/compiler_crashers/27203-swift-typeloc-iserror.swift @@ -4,4 +4,5 @@ // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing +// Crash type: memory error ("Invalid read of size 4") class n{protocol a:d var d={class b:a diff --git a/validation-test/compiler_crashers/27443-matchwitness.swift b/validation-test/compiler_crashers/27443-matchwitness.swift index 667040c0cf33f..e3abefd1819c2 100644 --- a/validation-test/compiler_crashers/27443-matchwitness.swift +++ b/validation-test/compiler_crashers/27443-matchwitness.swift @@ -4,6 +4,7 @@ // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing +// Crash type: memory error ("Invalid read of size 8") {e struct B:a{let t:a} protocol a{let t:a diff --git a/validation-test/compiler_crashers/27754-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers/27754-swift-typechecker-resolvetypeincontext.swift index 4d6f6e503e3e2..af1a11782c941 100644 --- a/validation-test/compiler_crashers/27754-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers/27754-swift-typechecker-resolvetypeincontext.swift @@ -4,4 +4,5 @@ // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing +// Crash type: memory error ("Invalid read of size 8") class d{let f=a< class a{extension{struct Q +struct B diff --git a/validation-test/compiler_crashers/28155-swift-typechecker-validategenericfuncsignature.swift b/validation-test/compiler_crashers/28155-swift-typechecker-validategenericfuncsignature.swift new file mode 100644 index 0000000000000..fe042ce20cfb2 --- /dev/null +++ b/validation-test/compiler_crashers/28155-swift-typechecker-validategenericfuncsignature.swift @@ -0,0 +1,8 @@ +// RUN: not --crash %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +// Crash type: memory error ("Invalid read of size 2") +class A{func b->Self{{{}}class B Void in + self?.b(c) + } + } + func d(e: ((AnyObject)->Void)) { + } + func b(f: AnyObject, g: AnyObject) { + } +} diff --git a/validation-test/compiler_crashers/28188-swift-removeoverriddendecls.timeout.swift b/validation-test/compiler_crashers/28188-swift-removeoverriddendecls.timeout.swift new file mode 100644 index 0000000000000..ad16e35d253fe --- /dev/null +++ b/validation-test/compiler_crashers/28188-swift-removeoverriddendecls.timeout.swift @@ -0,0 +1,8 @@ +// RUN: not --crash %target-swift-frontend %s -parse +// REQUIRES: asserts + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class A:A{init() diff --git a/validation-test/compiler_crashers/28189-swift-valuedecl-settype.swift b/validation-test/compiler_crashers/28189-swift-valuedecl-settype.swift new file mode 100644 index 0000000000000..d444fa9830686 --- /dev/null +++ b/validation-test/compiler_crashers/28189-swift-valuedecl-settype.swift @@ -0,0 +1,8 @@ +// RUN: not --crash %target-swift-frontend %s -parse +// REQUIRES: asserts + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func f{{for b{}{String($0 diff --git a/validation-test/compiler_crashers/28190-swift-conformancelookuptable-expandimpliedconformances.swift b/validation-test/compiler_crashers/28190-swift-conformancelookuptable-expandimpliedconformances.swift new file mode 100644 index 0000000000000..b8c5465465d8a --- /dev/null +++ b/validation-test/compiler_crashers/28190-swift-conformancelookuptable-expandimpliedconformances.swift @@ -0,0 +1,11 @@ +// RUN: not --crash %target-swift-frontend %s -parse +// REQUIRES: asserts + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol A:A +protocol a:A +struct c:a{ +let h=D diff --git a/validation-test/compiler_crashers/28191-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers/28191-swift-typebase-getcanonicaltype.swift new file mode 100644 index 0000000000000..a1847ba64cd60 --- /dev/null +++ b/validation-test/compiler_crashers/28191-swift-typebase-getcanonicaltype.swift @@ -0,0 +1,10 @@ +// RUN: not --crash %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol a:A.e +protocol A{typealias e:a +class A:e +func b:A diff --git a/validation-test/compiler_crashers/28192-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers/28192-swift-genericfunctiontype-get.swift new file mode 100644 index 0000000000000..b235d6b8af5ed --- /dev/null +++ b/validation-test/compiler_crashers/28192-swift-genericfunctiontype-get.swift @@ -0,0 +1,8 @@ +// RUN: not --crash %target-swift-frontend %s -parse +// REQUIRES: asserts + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +{struct Q : GeneratorType { return nil } let ret = elements[pos] - ++pos + pos += 1 return ret } } diff --git a/validation-test/compiler_crashers_2_fixed/0004-rdar20564605.swift b/validation-test/compiler_crashers_2_fixed/0004-rdar20564605.swift index 0608883c009c4..4d6eaf293dea0 100644 --- a/validation-test/compiler_crashers_2_fixed/0004-rdar20564605.swift +++ b/validation-test/compiler_crashers_2_fixed/0004-rdar20564605.swift @@ -36,7 +36,7 @@ extension Q_SequenceDefaultsType { var g = self.generate() while let element = g.next() { p.initialize(element) - ++p + p += 1 } } @@ -138,7 +138,7 @@ public struct Q_IndexingGenerator : GeneratorType { return nil } let ret = elements[pos] - ++pos + pos += 1 return ret } } diff --git a/validation-test/compiler_crashers_2_fixed/0006-rdar20588474.swift b/validation-test/compiler_crashers_2_fixed/0006-rdar20588474.swift index 64ca6d90d27f2..c5fcbac894fac 100644 --- a/validation-test/compiler_crashers_2_fixed/0006-rdar20588474.swift +++ b/validation-test/compiler_crashers_2_fixed/0006-rdar20588474.swift @@ -36,7 +36,7 @@ extension Q_SequenceDefaultsType { var g = self.generate() while let element = g.next() { p.initialize(element) - ++p + p += 1 } } @@ -130,7 +130,7 @@ public struct Q_IndexingGenerator : GeneratorType { return nil } let ret = elements[pos] - ++pos + pos += 1 return ret } } diff --git a/validation-test/compiler_crashers_2_fixed/0010-rdar20638881.swift b/validation-test/compiler_crashers_2_fixed/0010-rdar20638881.swift index 5415c6139f31c..3885b21a1b879 100644 --- a/validation-test/compiler_crashers_2_fixed/0010-rdar20638881.swift +++ b/validation-test/compiler_crashers_2_fixed/0010-rdar20638881.swift @@ -37,7 +37,7 @@ extension Q_SequenceDefaultsType { var g = self.generate() while let element? = g.next() { p.initialize(element) - ++p + p += 1 } } @@ -134,7 +134,7 @@ public struct Q_IndexingGenerator : Q_ConcreteGeneratorType return nil } let ret = elements[pos] - ++pos + pos += 1 return ret } } diff --git a/validation-test/compiler_crashers_2_fixed/0019-rdar21511651.swift b/validation-test/compiler_crashers_2_fixed/0019-rdar21511651.swift index b00e5324f758c..73a5de8b86e78 100644 --- a/validation-test/compiler_crashers_2_fixed/0019-rdar21511651.swift +++ b/validation-test/compiler_crashers_2_fixed/0019-rdar21511651.swift @@ -29,7 +29,7 @@ extension SequenceType /// If `self` is multi-pass (i.e., a `CollectionType`), invoke /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. - public func _preprocessingPass(preprocess: (Self)->R) -> R? { + public func _preprocessingPass(@noescape preprocess: (Self) -> R) -> R? { return _base._preprocessingPass { _ in preprocess(self) } } @@ -146,7 +146,7 @@ public extension SequenceType // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/validation-test/compiler_crashers_2_fixed/0020-rdar21598514.swift b/validation-test/compiler_crashers_2_fixed/0020-rdar21598514.swift index 35ecbd514b054..438bce41a9768 100644 --- a/validation-test/compiler_crashers_2_fixed/0020-rdar21598514.swift +++ b/validation-test/compiler_crashers_2_fixed/0020-rdar21598514.swift @@ -133,7 +133,7 @@ extension LoggingSequenceType { /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. public func _preprocessingPass( - preprocess: (Self)->R + @noescape preprocess: (Self) -> R ) -> R? { ++SequenceLog._preprocessingPass[selfType] return base._preprocessingPass { _ in preprocess(self) } diff --git a/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift b/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift index e8da4a9d0ee25..8aa452729618e 100644 --- a/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift +++ b/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift @@ -29,11 +29,11 @@ public class TypeIndexed : Resettable { internal var defaultValue: Value } -//===--- LoggingWrappers.swift ---------------------------------------===// +//===--- LoggingWrappers.swift --------------------------------------------===// // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -146,7 +146,7 @@ extension LoggingSequenceType /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. public func _preprocessingPass( - preprocess: (Self)->R + @noescape preprocess: (Self) -> R ) -> R? { ++Log._preprocessingPass[selfType] return base._preprocessingPass { _ in preprocess(self) } diff --git a/validation-test/compiler_crashers_2_fixed/0027-rdar21514140.swift b/validation-test/compiler_crashers_2_fixed/0027-rdar21514140.swift index a6bec9b2ae4a6..39c2f1839de5d 100644 --- a/validation-test/compiler_crashers_2_fixed/0027-rdar21514140.swift +++ b/validation-test/compiler_crashers_2_fixed/0027-rdar21514140.swift @@ -30,7 +30,7 @@ extension SequenceType /// If `self` is multi-pass (i.e., a `CollectionType`), invoke /// `preprocess` on `self` and return its result. Otherwise, return /// `nil`. - public func _preprocessingPass(preprocess: (Self)->R) -> R? { + public func _preprocessingPass(@noescape preprocess: (Self) -> R) -> R? { return _base._preprocessingPass { _ in preprocess(self) } } @@ -147,7 +147,7 @@ public extension SequenceType // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information diff --git a/validation-test/compiler_crashers_2_fixed/0036-rdar23719809.swift b/validation-test/compiler_crashers_2_fixed/0036-rdar23719809.swift new file mode 100644 index 0000000000000..84684763144b2 --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/0036-rdar23719809.swift @@ -0,0 +1,12 @@ +// RUN: not %target-swift-frontend %s -parse + +// rdar://problem/23719809&23720006 + +func ~=() {} +func ~=(_: Int) {} +func ~=(_: () -> ()) {} + +switch 0 { +case 0: + break +} diff --git a/validation-test/compiler_crashers_2_fixed/0037-SILWitnessVisitor.swift b/validation-test/compiler_crashers_2_fixed/0037-SILWitnessVisitor.swift new file mode 100644 index 0000000000000..95a3a4cad133a --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/0037-SILWitnessVisitor.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -emit-silgen + +protocol FooType { + func bar(b: Int) +} + +extension FooType { + func bar(a: Int, b: Int) {} +} + +struct Foo : FooType {} diff --git a/validation-test/compiler_crashers_fixed/0001-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/00001-swift-typeloc-iserror.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0001-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/00001-swift-typeloc-iserror.swift diff --git a/validation-test/compiler_crashers_fixed/0002-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00002-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0002-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00002-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0003-profilearchetypeconstraints.swift b/validation-test/compiler_crashers_fixed/00003-profilearchetypeconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0003-profilearchetypeconstraints.swift rename to validation-test/compiler_crashers_fixed/00003-profilearchetypeconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/0004-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00004-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0004-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00004-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0005-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00005-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0005-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00005-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0006-swift-mangle-mangler-manglecontext.swift b/validation-test/compiler_crashers_fixed/00006-swift-mangle-mangler-manglecontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0006-swift-mangle-mangler-manglecontext.swift rename to validation-test/compiler_crashers_fixed/00006-swift-mangle-mangler-manglecontext.swift diff --git a/validation-test/compiler_crashers_fixed/0007-convenience-init-in-extension.swift b/validation-test/compiler_crashers_fixed/00007-convenience-init-in-extension.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0007-convenience-init-in-extension.swift rename to validation-test/compiler_crashers_fixed/00007-convenience-init-in-extension.swift diff --git a/validation-test/compiler_crashers_fixed/0008-llvm-foldingset-llvm-attributesetnode-nodeequals.swift b/validation-test/compiler_crashers_fixed/00008-llvm-foldingset-llvm-attributesetnode-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0008-llvm-foldingset-llvm-attributesetnode-nodeequals.swift rename to validation-test/compiler_crashers_fixed/00008-llvm-foldingset-llvm-attributesetnode-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/0009-class-referencing-protocol-referencing-class.swift b/validation-test/compiler_crashers_fixed/00009-class-referencing-protocol-referencing-class.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0009-class-referencing-protocol-referencing-class.swift rename to validation-test/compiler_crashers_fixed/00009-class-referencing-protocol-referencing-class.swift diff --git a/validation-test/compiler_crashers_fixed/0010-circular-protocol-reference.swift b/validation-test/compiler_crashers_fixed/00010-circular-protocol-reference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0010-circular-protocol-reference.swift rename to validation-test/compiler_crashers_fixed/00010-circular-protocol-reference.swift diff --git a/validation-test/compiler_crashers_fixed/0011-swift-nominaltypedecl-getprotocols.swift b/validation-test/compiler_crashers_fixed/00011-swift-nominaltypedecl-getprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0011-swift-nominaltypedecl-getprotocols.swift rename to validation-test/compiler_crashers_fixed/00011-swift-nominaltypedecl-getprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/0012-emitdirecttypemetadataref.swift b/validation-test/compiler_crashers_fixed/00012-emitdirecttypemetadataref.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0012-emitdirecttypemetadataref.swift rename to validation-test/compiler_crashers_fixed/00012-emitdirecttypemetadataref.swift diff --git a/validation-test/compiler_crashers_fixed/0013-llvm-getelementptrinst-getindexedtype.swift b/validation-test/compiler_crashers_fixed/00013-llvm-getelementptrinst-getindexedtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0013-llvm-getelementptrinst-getindexedtype.swift rename to validation-test/compiler_crashers_fixed/00013-llvm-getelementptrinst-getindexedtype.swift diff --git a/validation-test/compiler_crashers_fixed/0014-enum-in-generic-type.swift b/validation-test/compiler_crashers_fixed/00014-enum-in-generic-type.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0014-enum-in-generic-type.swift rename to validation-test/compiler_crashers_fixed/00014-enum-in-generic-type.swift diff --git a/validation-test/compiler_crashers_fixed/00015-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00015-no-stacktrace.swift new file mode 100644 index 0000000000000..c5cd49ddea3d5 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00015-no-stacktrace.swift @@ -0,0 +1,9 @@ +// RUN: not %target-swift-frontend %s -emit-silgen + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// http://www.openradar.me/17225563 + +enum a { + case s(T, a) +} diff --git a/validation-test/compiler_crashers_fixed/0016-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00016-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0016-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00016-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0017-llvm-foldingset-llvm-attributesetnode-nodeequals.swift b/validation-test/compiler_crashers_fixed/00017-llvm-foldingset-llvm-attributesetnode-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0017-llvm-foldingset-llvm-attributesetnode-nodeequals.swift rename to validation-test/compiler_crashers_fixed/00017-llvm-foldingset-llvm-attributesetnode-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/0018-swift-irgen-emitpolymorphicarguments.swift b/validation-test/compiler_crashers_fixed/00018-swift-irgen-emitpolymorphicarguments.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0018-swift-irgen-emitpolymorphicarguments.swift rename to validation-test/compiler_crashers_fixed/00018-swift-irgen-emitpolymorphicarguments.swift diff --git a/validation-test/compiler_crashers_fixed/0019-llvm-instvisitor.swift b/validation-test/compiler_crashers_fixed/00019-llvm-instvisitor.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0019-llvm-instvisitor.swift rename to validation-test/compiler_crashers_fixed/00019-llvm-instvisitor.swift diff --git a/validation-test/compiler_crashers_fixed/0020-swift-typechecker-conformstoprotocol.swift b/validation-test/compiler_crashers_fixed/00020-swift-typechecker-conformstoprotocol.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0020-swift-typechecker-conformstoprotocol.swift rename to validation-test/compiler_crashers_fixed/00020-swift-typechecker-conformstoprotocol.swift diff --git a/validation-test/compiler_crashers_fixed/0021-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00021-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0021-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00021-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0022-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00022-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0022-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00022-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0023-getcallerdefaultarg.swift b/validation-test/compiler_crashers_fixed/00023-getcallerdefaultarg.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0023-getcallerdefaultarg.swift rename to validation-test/compiler_crashers_fixed/00023-getcallerdefaultarg.swift diff --git a/validation-test/compiler_crashers_fixed/0024-emitdirecttypemetadataref.swift b/validation-test/compiler_crashers_fixed/00024-emitdirecttypemetadataref.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0024-emitdirecttypemetadataref.swift rename to validation-test/compiler_crashers_fixed/00024-emitdirecttypemetadataref.swift diff --git a/validation-test/compiler_crashers_fixed/0025-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00025-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0025-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00025-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0027-void-map-over-sequence.swift b/validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0027-void-map-over-sequence.swift rename to validation-test/compiler_crashers_fixed/00027-void-map-over-sequence.swift diff --git a/validation-test/compiler_crashers_fixed/0029-class-with-anyobject-type-constraint.swift b/validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0029-class-with-anyobject-type-constraint.swift rename to validation-test/compiler_crashers_fixed/00029-class-with-anyobject-type-constraint.swift diff --git a/validation-test/compiler_crashers_fixed/0030-string-as-extensibe-collection.script.swift b/validation-test/compiler_crashers_fixed/00030-string-as-extensibe-collection.script.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0030-string-as-extensibe-collection.script.swift rename to validation-test/compiler_crashers_fixed/00030-string-as-extensibe-collection.script.swift diff --git a/validation-test/compiler_crashers_fixed/0031-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00031-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0031-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00031-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0032-swift-irgen-irgenfunction-emittypemetadataref.swift b/validation-test/compiler_crashers_fixed/00032-swift-irgen-irgenfunction-emittypemetadataref.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0032-swift-irgen-irgenfunction-emittypemetadataref.swift rename to validation-test/compiler_crashers_fixed/00032-swift-irgen-irgenfunction-emittypemetadataref.swift diff --git a/validation-test/compiler_crashers_fixed/0033-error.swift b/validation-test/compiler_crashers_fixed/00033-error.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0033-error.swift rename to validation-test/compiler_crashers_fixed/00033-error.swift diff --git a/validation-test/compiler_crashers_fixed/0034-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00034-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0034-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00034-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/00035-cerror.swift b/validation-test/compiler_crashers_fixed/00035-cerror.swift new file mode 100644 index 0000000000000..e940d68d21769 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00035-cerror.swift @@ -0,0 +1,18 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// rdar://17242486 + +protocol a { + typealias d + typealias e = d + typealias f = d +} +class b : a { +} +class b { +} +protocol c { + typealias g +} diff --git a/validation-test/compiler_crashers_fixed/0036-szone-malloc-should-clear.swift b/validation-test/compiler_crashers_fixed/00036-szone-malloc-should-clear.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0036-szone-malloc-should-clear.swift rename to validation-test/compiler_crashers_fixed/00036-szone-malloc-should-clear.swift diff --git a/validation-test/compiler_crashers_fixed/0037-no-stacktrace.script.swift b/validation-test/compiler_crashers_fixed/00037-no-stacktrace.script.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0037-no-stacktrace.script.swift rename to validation-test/compiler_crashers_fixed/00037-no-stacktrace.script.swift diff --git a/validation-test/compiler_crashers_fixed/0038-hang-on-init-of-recursive-generic-type.timeout.swift b/validation-test/compiler_crashers_fixed/00038-hang-on-init-of-recursive-generic-type.timeout.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0038-hang-on-init-of-recursive-generic-type.timeout.swift rename to validation-test/compiler_crashers_fixed/00038-hang-on-init-of-recursive-generic-type.timeout.swift diff --git a/validation-test/compiler_crashers_fixed/0039-string-join.script.swift b/validation-test/compiler_crashers_fixed/00039-string-join.script.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0039-string-join.script.swift rename to validation-test/compiler_crashers_fixed/00039-string-join.script.swift diff --git a/validation-test/compiler_crashers_fixed/0040-std-function-func-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0040-std-function-func-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/00040-std-function-func-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0041-szone-malloc-should-clear.swift b/validation-test/compiler_crashers_fixed/00041-szone-malloc-should-clear.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0041-szone-malloc-should-clear.swift rename to validation-test/compiler_crashers_fixed/00041-szone-malloc-should-clear.swift diff --git a/validation-test/compiler_crashers_fixed/0042-nested-pattern-match-with-type-cast.timeout.swift b/validation-test/compiler_crashers_fixed/00042-nested-pattern-match-with-type-cast.timeout.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0042-nested-pattern-match-with-type-cast.timeout.swift rename to validation-test/compiler_crashers_fixed/00042-nested-pattern-match-with-type-cast.timeout.swift diff --git a/validation-test/compiler_crashers_fixed/0043-substdependenttypes.swift b/validation-test/compiler_crashers_fixed/00043-substdependenttypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0043-substdependenttypes.swift rename to validation-test/compiler_crashers_fixed/00043-substdependenttypes.swift diff --git a/validation-test/compiler_crashers_fixed/00045-swift-lowering-adjustfunctiontype.swift b/validation-test/compiler_crashers_fixed/00045-swift-lowering-adjustfunctiontype.swift new file mode 100644 index 0000000000000..d36be81b60892 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00045-swift-lowering-adjustfunctiontype.swift @@ -0,0 +1,9 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// http://www.openradar.me/17317691 + +func f() { + ({}) +} diff --git a/validation-test/compiler_crashers_fixed/0046-any-array-containing-ints.repl.swift b/validation-test/compiler_crashers_fixed/00046-any-array-containing-ints.repl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0046-any-array-containing-ints.repl.swift rename to validation-test/compiler_crashers_fixed/00046-any-array-containing-ints.repl.swift diff --git a/validation-test/compiler_crashers_fixed/0047-emitdirecttypemetadataref.swift b/validation-test/compiler_crashers_fixed/00047-emitdirecttypemetadataref.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0047-emitdirecttypemetadataref.swift rename to validation-test/compiler_crashers_fixed/00047-emitdirecttypemetadataref.swift diff --git a/validation-test/compiler_crashers_fixed/0048-no-stacktrace.random.runtime.swift b/validation-test/compiler_crashers_fixed/00048-no-stacktrace.random.runtime.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0048-no-stacktrace.random.runtime.swift rename to validation-test/compiler_crashers_fixed/00048-no-stacktrace.random.runtime.swift diff --git a/validation-test/compiler_crashers_fixed/00049-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/00049-swift-nominaltypedecl-getmembers.swift new file mode 100644 index 0000000000000..6c0e143367979 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00049-swift-nominaltypedecl-getmembers.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -emit-sil + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/rnapier (Rob Napier) + +var f = 1 +var e: Int -> Int = { + return $0 +} +let d: Int = { c, b in +}(f, e) diff --git a/validation-test/compiler_crashers_fixed/0050-protocols-with-circular-typealiases.swift b/validation-test/compiler_crashers_fixed/00050-protocols-with-circular-typealiases.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0050-protocols-with-circular-typealiases.swift rename to validation-test/compiler_crashers_fixed/00050-protocols-with-circular-typealiases.swift diff --git a/validation-test/compiler_crashers_fixed/0051-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00051-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0051-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00051-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0052-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00052-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0052-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00052-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0053-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0053-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/00053-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/0054-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/00054-swift-substitutedtype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0054-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/00054-swift-substitutedtype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0055-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00055-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0055-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00055-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0056-addminimumprotocols.swift b/validation-test/compiler_crashers_fixed/00056-addminimumprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0056-addminimumprotocols.swift rename to validation-test/compiler_crashers_fixed/00056-addminimumprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/0057-get-type-of-member-reference.swift b/validation-test/compiler_crashers_fixed/00057-get-type-of-member-reference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0057-get-type-of-member-reference.swift rename to validation-test/compiler_crashers_fixed/00057-get-type-of-member-reference.swift diff --git a/validation-test/compiler_crashers_fixed/0058-get-self-type-for-container.swift b/validation-test/compiler_crashers_fixed/00058-get-self-type-for-container.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0058-get-self-type-for-container.swift rename to validation-test/compiler_crashers_fixed/00058-get-self-type-for-container.swift diff --git a/validation-test/compiler_crashers_fixed/0059-fold-sequence.swift b/validation-test/compiler_crashers_fixed/00059-fold-sequence.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0059-fold-sequence.swift rename to validation-test/compiler_crashers_fixed/00059-fold-sequence.swift diff --git a/validation-test/compiler_crashers_fixed/0060-adjust-function-type.swift b/validation-test/compiler_crashers_fixed/00060-adjust-function-type.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0060-adjust-function-type.swift rename to validation-test/compiler_crashers_fixed/00060-adjust-function-type.swift diff --git a/validation-test/compiler_crashers_fixed/0062-ioctl.swift b/validation-test/compiler_crashers_fixed/00062-ioctl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0062-ioctl.swift rename to validation-test/compiler_crashers_fixed/00062-ioctl.swift diff --git a/validation-test/compiler_crashers_fixed/0063-tiny-malloc-from-free-list.swift b/validation-test/compiler_crashers_fixed/00063-tiny-malloc-from-free-list.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0063-tiny-malloc-from-free-list.swift rename to validation-test/compiler_crashers_fixed/00063-tiny-malloc-from-free-list.swift diff --git a/validation-test/compiler_crashers_fixed/0064-bool.swift b/validation-test/compiler_crashers_fixed/00064-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0064-bool.swift rename to validation-test/compiler_crashers_fixed/00064-bool.swift diff --git a/validation-test/compiler_crashers_fixed/0065-cerror.swift b/validation-test/compiler_crashers_fixed/00065-cerror.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0065-cerror.swift rename to validation-test/compiler_crashers_fixed/00065-cerror.swift diff --git a/validation-test/compiler_crashers/00066-diagnoseunknowntype.swift b/validation-test/compiler_crashers_fixed/00066-diagnoseunknowntype.swift similarity index 79% rename from validation-test/compiler_crashers/00066-diagnoseunknowntype.swift rename to validation-test/compiler_crashers_fixed/00066-diagnoseunknowntype.swift index d0e7a15bf4d17..62ddd0b087a69 100644 --- a/validation-test/compiler_crashers/00066-diagnoseunknowntype.swift +++ b/validation-test/compiler_crashers_fixed/00066-diagnoseunknowntype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/0067-szone-malloc-should-clear.swift b/validation-test/compiler_crashers_fixed/00067-szone-malloc-should-clear.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0067-szone-malloc-should-clear.swift rename to validation-test/compiler_crashers_fixed/00067-szone-malloc-should-clear.swift diff --git a/validation-test/compiler_crashers_fixed/0068-foldsequence.swift b/validation-test/compiler_crashers_fixed/00068-foldsequence.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0068-foldsequence.swift rename to validation-test/compiler_crashers_fixed/00068-foldsequence.swift diff --git a/validation-test/compiler_crashers_fixed/0069-swift-typevisitor.swift b/validation-test/compiler_crashers_fixed/00069-swift-typevisitor.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0069-swift-typevisitor.swift rename to validation-test/compiler_crashers_fixed/00069-swift-typevisitor.swift diff --git a/validation-test/compiler_crashers_fixed/0070-getgenericparam.swift b/validation-test/compiler_crashers_fixed/00070-getgenericparam.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0070-getgenericparam.swift rename to validation-test/compiler_crashers_fixed/00070-getgenericparam.swift diff --git a/validation-test/compiler_crashers_fixed/0071-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00071-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0071-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00071-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0072-llvm-bitstreamcursor-readrecord.swift b/validation-test/compiler_crashers_fixed/00072-llvm-bitstreamcursor-readrecord.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0072-llvm-bitstreamcursor-readrecord.swift rename to validation-test/compiler_crashers_fixed/00072-llvm-bitstreamcursor-readrecord.swift diff --git a/validation-test/compiler_crashers_fixed/0073-llvm-errs.swift b/validation-test/compiler_crashers_fixed/00073-llvm-errs.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0073-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/00073-llvm-errs.swift diff --git a/validation-test/compiler_crashers_fixed/0074-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/00074-swift-typeloc-iserror.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0074-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/00074-swift-typeloc-iserror.swift diff --git a/validation-test/compiler_crashers_fixed/0075-llvm-foldingset-swift-boundgenerictype-nodeequals.swift b/validation-test/compiler_crashers_fixed/00075-llvm-foldingset-swift-boundgenerictype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0075-llvm-foldingset-swift-boundgenerictype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/00075-llvm-foldingset-swift-boundgenerictype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/0076-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift b/validation-test/compiler_crashers_fixed/00076-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0076-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift rename to validation-test/compiler_crashers_fixed/00076-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/0077-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/00077-swift-typechecker-validatedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0077-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/00077-swift-typechecker-validatedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0078-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/00078-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0078-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/00078-llvm-foldingset-swift-tupletype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/0079-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/00079-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0079-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/00079-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/0080-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift b/validation-test/compiler_crashers_fixed/00080-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0080-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift rename to validation-test/compiler_crashers_fixed/00080-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift diff --git a/validation-test/compiler_crashers_fixed/0081-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00081-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0081-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00081-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0082-std-function-func-containsprotocolself.swift b/validation-test/compiler_crashers_fixed/00082-std-function-func-containsprotocolself.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0082-std-function-func-containsprotocolself.swift rename to validation-test/compiler_crashers_fixed/00082-std-function-func-containsprotocolself.swift diff --git a/validation-test/compiler_crashers_fixed/0083-std-function-func-mapsignaturetype.swift b/validation-test/compiler_crashers_fixed/00083-std-function-func-mapsignaturetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0083-std-function-func-mapsignaturetype.swift rename to validation-test/compiler_crashers_fixed/00083-std-function-func-mapsignaturetype.swift diff --git a/validation-test/compiler_crashers_fixed/0084-std-function-func-swift-archetypebuilder-maptypeintocontext.swift b/validation-test/compiler_crashers_fixed/00084-std-function-func-swift-archetypebuilder-maptypeintocontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0084-std-function-func-swift-archetypebuilder-maptypeintocontext.swift rename to validation-test/compiler_crashers_fixed/00084-std-function-func-swift-archetypebuilder-maptypeintocontext.swift diff --git a/validation-test/compiler_crashers_fixed/0085-swift-typechecker-typecheckpattern.swift b/validation-test/compiler_crashers_fixed/00085-swift-typechecker-typecheckpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0085-swift-typechecker-typecheckpattern.swift rename to validation-test/compiler_crashers_fixed/00085-swift-typechecker-typecheckpattern.swift diff --git a/validation-test/compiler_crashers_fixed/0086-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00086-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0086-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/00086-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/0087-swift-archetypebuilder-resolvearchetype.swift b/validation-test/compiler_crashers_fixed/00087-swift-archetypebuilder-resolvearchetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0087-swift-archetypebuilder-resolvearchetype.swift rename to validation-test/compiler_crashers_fixed/00087-swift-archetypebuilder-resolvearchetype.swift diff --git a/validation-test/compiler_crashers_fixed/0088-swift-archetypetype-getnestedtype.swift b/validation-test/compiler_crashers_fixed/00088-swift-archetypetype-getnestedtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0088-swift-archetypetype-getnestedtype.swift rename to validation-test/compiler_crashers_fixed/00088-swift-archetypetype-getnestedtype.swift diff --git a/validation-test/compiler_crashers_fixed/0089-swift-archetypetype-setnestedtypes.swift b/validation-test/compiler_crashers_fixed/00089-swift-archetypetype-setnestedtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0089-swift-archetypetype-setnestedtypes.swift rename to validation-test/compiler_crashers_fixed/00089-swift-archetypetype-setnestedtypes.swift diff --git a/validation-test/compiler_crashers_fixed/0090-swift-astcontext-getidentifier.swift b/validation-test/compiler_crashers_fixed/00090-swift-astcontext-getidentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0090-swift-astcontext-getidentifier.swift rename to validation-test/compiler_crashers_fixed/00090-swift-astcontext-getidentifier.swift diff --git a/validation-test/compiler_crashers_fixed/0091-swift-astprinter-printname.swift b/validation-test/compiler_crashers_fixed/00091-swift-astprinter-printname.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0091-swift-astprinter-printname.swift rename to validation-test/compiler_crashers_fixed/00091-swift-astprinter-printname.swift diff --git a/validation-test/compiler_crashers_fixed/0092-swift-availabilityattr-isunavailable.swift b/validation-test/compiler_crashers_fixed/00092-swift-availabilityattr-isunavailable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0092-swift-availabilityattr-isunavailable.swift rename to validation-test/compiler_crashers_fixed/00092-swift-availabilityattr-isunavailable.swift diff --git a/validation-test/compiler_crashers_fixed/0093-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/00093-swift-boundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0093-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/00093-swift-boundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0094-swift-bracestmt-create.swift b/validation-test/compiler_crashers_fixed/00094-swift-bracestmt-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0094-swift-bracestmt-create.swift rename to validation-test/compiler_crashers_fixed/00094-swift-bracestmt-create.swift diff --git a/validation-test/compiler_crashers_fixed/0095-swift-clangimporter-implementation-mergepropinfointoaccessor.swift b/validation-test/compiler_crashers_fixed/00095-swift-clangimporter-implementation-mergepropinfointoaccessor.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0095-swift-clangimporter-implementation-mergepropinfointoaccessor.swift rename to validation-test/compiler_crashers_fixed/00095-swift-clangimporter-implementation-mergepropinfointoaccessor.swift diff --git a/validation-test/compiler_crashers_fixed/0096-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/00096-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0096-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/00096-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/0097-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/00097-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0097-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/00097-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/0098-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/00098-swift-constraints-constraintgraph-addconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0098-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/00098-swift-constraints-constraintgraph-addconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/0099-swift-constraints-constraintgraph-change-undo.swift b/validation-test/compiler_crashers_fixed/00099-swift-constraints-constraintgraph-change-undo.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0099-swift-constraints-constraintgraph-change-undo.swift rename to validation-test/compiler_crashers_fixed/00099-swift-constraints-constraintgraph-change-undo.swift diff --git a/validation-test/compiler_crashers_fixed/0100-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift b/validation-test/compiler_crashers_fixed/00100-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0100-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift rename to validation-test/compiler_crashers_fixed/00100-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift diff --git a/validation-test/compiler_crashers_fixed/0101-swift-constraints-constraintsystem-applysolution.swift b/validation-test/compiler_crashers_fixed/00101-swift-constraints-constraintsystem-applysolution.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0101-swift-constraints-constraintsystem-applysolution.swift rename to validation-test/compiler_crashers_fixed/00101-swift-constraints-constraintsystem-applysolution.swift diff --git a/validation-test/compiler_crashers_fixed/0102-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/00102-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0102-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/00102-swift-constraints-constraintsystem-assignfixedtype.swift diff --git a/validation-test/compiler_crashers_fixed/0103-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift b/validation-test/compiler_crashers_fixed/00103-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0103-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift rename to validation-test/compiler_crashers_fixed/00103-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/0104-swift-constraints-constraintsystem-finalize.swift b/validation-test/compiler_crashers_fixed/00104-swift-constraints-constraintsystem-finalize.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0104-swift-constraints-constraintsystem-finalize.swift rename to validation-test/compiler_crashers_fixed/00104-swift-constraints-constraintsystem-finalize.swift diff --git a/validation-test/compiler_crashers_fixed/0105-swift-constraints-constraintsystem-getconstraintlocator.swift b/validation-test/compiler_crashers_fixed/00105-swift-constraints-constraintsystem-getconstraintlocator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0105-swift-constraints-constraintsystem-getconstraintlocator.swift rename to validation-test/compiler_crashers_fixed/00105-swift-constraints-constraintsystem-getconstraintlocator.swift diff --git a/validation-test/compiler_crashers_fixed/0106-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00106-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0106-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00106-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0107-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00107-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0107-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00107-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0108-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift b/validation-test/compiler_crashers_fixed/00108-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0108-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift rename to validation-test/compiler_crashers_fixed/00108-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0109-swift-constraints-constraintsystem-matchfunctiontypes.swift b/validation-test/compiler_crashers_fixed/00109-swift-constraints-constraintsystem-matchfunctiontypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0109-swift-constraints-constraintsystem-matchfunctiontypes.swift rename to validation-test/compiler_crashers_fixed/00109-swift-constraints-constraintsystem-matchfunctiontypes.swift diff --git a/validation-test/compiler_crashers_fixed/0110-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/00110-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0110-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/00110-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/0111-swift-constraints-constraintsystem-simplifyconstraint.swift b/validation-test/compiler_crashers_fixed/00111-swift-constraints-constraintsystem-simplifyconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0111-swift-constraints-constraintsystem-simplifyconstraint.swift rename to validation-test/compiler_crashers_fixed/00111-swift-constraints-constraintsystem-simplifyconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/0112-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/00112-swift-constraints-constraintsystem-simplifytype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0112-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/00112-swift-constraints-constraintsystem-simplifytype.swift diff --git a/validation-test/compiler_crashers_fixed/0113-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/00113-swift-constraints-constraintsystem-solve.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0113-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/00113-swift-constraints-constraintsystem-solve.swift diff --git a/validation-test/compiler_crashers_fixed/0114-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00114-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0114-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/00114-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0115-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00115-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0115-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00115-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0116-swift-declname-printpretty.swift b/validation-test/compiler_crashers_fixed/00116-swift-declname-printpretty.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0116-swift-declname-printpretty.swift rename to validation-test/compiler_crashers_fixed/00116-swift-declname-printpretty.swift diff --git a/validation-test/compiler_crashers_fixed/0117-swift-declrefexpr-setgenericargs.swift b/validation-test/compiler_crashers_fixed/00117-swift-declrefexpr-setgenericargs.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0117-swift-declrefexpr-setgenericargs.swift rename to validation-test/compiler_crashers_fixed/00117-swift-declrefexpr-setgenericargs.swift diff --git a/validation-test/compiler_crashers_fixed/0118-swift-dependentgenerictyperesolver-resolvegenerictypeparamtype.swift b/validation-test/compiler_crashers_fixed/00118-swift-dependentgenerictyperesolver-resolvegenerictypeparamtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0118-swift-dependentgenerictyperesolver-resolvegenerictypeparamtype.swift rename to validation-test/compiler_crashers_fixed/00118-swift-dependentgenerictyperesolver-resolvegenerictypeparamtype.swift diff --git a/validation-test/compiler_crashers_fixed/0119-swift-dependentmembertype-get.swift b/validation-test/compiler_crashers_fixed/00119-swift-dependentmembertype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0119-swift-dependentmembertype-get.swift rename to validation-test/compiler_crashers_fixed/00119-swift-dependentmembertype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0120-swift-derivedconformance-deriveequatable.swift b/validation-test/compiler_crashers_fixed/00120-swift-derivedconformance-deriveequatable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0120-swift-derivedconformance-deriveequatable.swift rename to validation-test/compiler_crashers_fixed/00120-swift-derivedconformance-deriveequatable.swift diff --git a/validation-test/compiler_crashers_fixed/0121-swift-diagnosticengine-diagnose.swift b/validation-test/compiler_crashers_fixed/00121-swift-diagnosticengine-diagnose.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0121-swift-diagnosticengine-diagnose.swift rename to validation-test/compiler_crashers_fixed/00121-swift-diagnosticengine-diagnose.swift diff --git a/validation-test/compiler_crashers_fixed/0122-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/00122-swift-typechecker-coercepatterntotype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0122-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/00122-swift-typechecker-coercepatterntotype.swift diff --git a/validation-test/compiler_crashers_fixed/0123-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/00123-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0123-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/00123-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0124-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/00124-swift-genericfunctiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0124-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/00124-swift-genericfunctiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0125-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/00125-swift-genericparamlist-addnestedarchetypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0125-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/00125-swift-genericparamlist-addnestedarchetypes.swift diff --git a/validation-test/compiler_crashers_fixed/0126-swift-generictypetoarchetyperesolver-resolvegenerictypeparamtype.swift b/validation-test/compiler_crashers_fixed/00126-swift-generictypetoarchetyperesolver-resolvegenerictypeparamtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0126-swift-generictypetoarchetyperesolver-resolvegenerictypeparamtype.swift rename to validation-test/compiler_crashers_fixed/00126-swift-generictypetoarchetyperesolver-resolvegenerictypeparamtype.swift diff --git a/validation-test/compiler_crashers_fixed/0127-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/00127-swift-inflightdiagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0127-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/00127-swift-inflightdiagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0128-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/00128-swift-lexer-getlocforendoftoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0128-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/00128-swift-lexer-getlocforendoftoken.swift diff --git a/validation-test/compiler_crashers_fixed/0129-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/00129-swift-lexer-lexidentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0129-swift-lexer-lexidentifier.swift rename to validation-test/compiler_crashers_fixed/00129-swift-lexer-lexidentifier.swift diff --git a/validation-test/compiler_crashers_fixed/0130-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/00130-swift-lexer-leximpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0130-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/00130-swift-lexer-leximpl.swift diff --git a/validation-test/compiler_crashers_fixed/0131-swift-lexer-lexnumber.swift b/validation-test/compiler_crashers_fixed/00131-swift-lexer-lexnumber.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0131-swift-lexer-lexnumber.swift rename to validation-test/compiler_crashers_fixed/00131-swift-lexer-lexnumber.swift diff --git a/validation-test/compiler_crashers_fixed/0132-swift-lexer-lexoperatoridentifier.swift b/validation-test/compiler_crashers_fixed/00132-swift-lexer-lexoperatoridentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0132-swift-lexer-lexoperatoridentifier.swift rename to validation-test/compiler_crashers_fixed/00132-swift-lexer-lexoperatoridentifier.swift diff --git a/validation-test/compiler_crashers_fixed/0133-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/00133-swift-typechecker-resolvetypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0133-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/00133-swift-typechecker-resolvetypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0134-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/00134-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0134-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/00134-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0135-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/00135-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0135-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/00135-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0136-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/00136-swift-modulefile-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0136-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/00136-swift-modulefile-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/0137-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/00137-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0137-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/00137-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/0138-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/00138-swift-modulefile-maybereadpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0138-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/00138-swift-modulefile-maybereadpattern.swift diff --git a/validation-test/compiler_crashers_fixed/0139-swift-typechecker-resolveidentifiertype.swift b/validation-test/compiler_crashers_fixed/00139-swift-typechecker-resolveidentifiertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0139-swift-typechecker-resolveidentifiertype.swift rename to validation-test/compiler_crashers_fixed/00139-swift-typechecker-resolveidentifiertype.swift diff --git a/validation-test/compiler_crashers_fixed/0140-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/00140-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0140-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/00140-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/0141-swift-nominaltypedecl-getextensions.swift b/validation-test/compiler_crashers_fixed/00141-swift-nominaltypedecl-getextensions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0141-swift-nominaltypedecl-getextensions.swift rename to validation-test/compiler_crashers_fixed/00141-swift-nominaltypedecl-getextensions.swift diff --git a/validation-test/compiler_crashers_fixed/00142-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/00142-swift-nominaltypedecl-preparelookuptable.swift new file mode 100644 index 0000000000000..b2ae7497ac8d6 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00142-swift-nominaltypedecl-preparelookuptable.swift @@ -0,0 +1,35 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +) +func n() -> (w, w -> w) -> w { + o m o.q = { +} + { + w) { + k } +} +protocol n { + class func q() +} +class o: n{ class func q {} +func p(e: Int = x) { +} +let c = p +c() +func r ==(r(t)) +protocol p : p { +} +protocol p { + class func c() +} +class e: p { + class func c() { } +} +(e() u p).v.c() +k e.w == l> { +} +func p(c: Any, m: Any) -> (((Any, Any) -> Any) -> Any) { diff --git a/validation-test/compiler_crashers_fixed/0143-swift-parentype-get.swift b/validation-test/compiler_crashers_fixed/00143-swift-parentype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0143-swift-parentype-get.swift rename to validation-test/compiler_crashers_fixed/00143-swift-parentype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0144-swift-parser-consumetoken.swift b/validation-test/compiler_crashers_fixed/00144-swift-parser-consumetoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0144-swift-parser-consumetoken.swift rename to validation-test/compiler_crashers_fixed/00144-swift-parser-consumetoken.swift diff --git a/validation-test/compiler_crashers_fixed/0145-swift-parser-parsebraceitems.swift b/validation-test/compiler_crashers_fixed/00145-swift-parser-parsebraceitems.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0145-swift-parser-parsebraceitems.swift rename to validation-test/compiler_crashers_fixed/00145-swift-parser-parsebraceitems.swift diff --git a/validation-test/compiler_crashers_fixed/0146-swift-parser-parseexpridentifier.swift b/validation-test/compiler_crashers_fixed/00146-swift-parser-parseexpridentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0146-swift-parser-parseexpridentifier.swift rename to validation-test/compiler_crashers_fixed/00146-swift-parser-parseexpridentifier.swift diff --git a/validation-test/compiler_crashers_fixed/0147-swift-parser-parseexprstringliteral.swift b/validation-test/compiler_crashers_fixed/00147-swift-parser-parseexprstringliteral.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0147-swift-parser-parseexprstringliteral.swift rename to validation-test/compiler_crashers_fixed/00147-swift-parser-parseexprstringliteral.swift diff --git a/validation-test/compiler_crashers_fixed/0148-swift-parser-parseexprunary.swift b/validation-test/compiler_crashers_fixed/00148-swift-parser-parseexprunary.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0148-swift-parser-parseexprunary.swift rename to validation-test/compiler_crashers_fixed/00148-swift-parser-parseexprunary.swift diff --git a/validation-test/compiler_crashers_fixed/0149-swift-typechecker-callwitness.swift b/validation-test/compiler_crashers_fixed/00149-swift-typechecker-callwitness.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0149-swift-typechecker-callwitness.swift rename to validation-test/compiler_crashers_fixed/00149-swift-typechecker-callwitness.swift diff --git a/validation-test/compiler_crashers_fixed/0015-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/0015-no-stacktrace.swift deleted file mode 100644 index 8241bbfe88f09..0000000000000 --- a/validation-test/compiler_crashers_fixed/0015-no-stacktrace.swift +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: not %target-swift-frontend %s -emit-silgen - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// http://www.openradar.me/17225563 - -enum a { - case s(T, a) -} diff --git a/validation-test/compiler_crashers_fixed/0150-swift-parser-parseparameterclause.swift b/validation-test/compiler_crashers_fixed/00150-swift-parser-parseparameterclause.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0150-swift-parser-parseparameterclause.swift rename to validation-test/compiler_crashers_fixed/00150-swift-parser-parseparameterclause.swift diff --git a/validation-test/compiler_crashers_fixed/0151-swift-parser-parsetype.swift b/validation-test/compiler_crashers_fixed/00151-swift-parser-parsetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0151-swift-parser-parsetype.swift rename to validation-test/compiler_crashers_fixed/00151-swift-parser-parsetype.swift diff --git a/validation-test/compiler_crashers_fixed/00152-swift-parser-parsetypeidentifier.swift b/validation-test/compiler_crashers_fixed/00152-swift-parser-parsetypeidentifier.swift new file mode 100644 index 0000000000000..381eb3d3cc9ec --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00152-swift-parser-parsetypeidentifier.swift @@ -0,0 +1,104 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol kj : gf { func gf +class t { +} +protocol qp { + r on + r t = on + r lk = on +} +class gf : qp { +} +class gf { +} +protocol kj { + r vu +} +ed vu = sr +ed ts: o -> o = { + fe $gf +} +l on: o = { (kj: o, lk: o -> o) -> o po + fe lk(kj) +}(vu, ts) +l qp: o = { kj, lk po + fe lk(kj) +}(vu, ts) +class qp { +} +protocol gf { + r on + r t +} +struct kj : gf { + r on = kj + r t = qp, on> +} +func qp(kj: v, ji: v) -> (((v, v) -> v) -> v) { + fe { + (ut: (v, v) -> v) -> v po + fe ut(kj, ji) + } +} +func gf(p: (((v, v) -> v) -> v)) -> v { + fe p({ + (ut: v, fe:v) -> v po + fe ut + }) +} +gf(qp(sr, qp(s, w))) +protocol t { + r n + func gf(n) +} +struct cb : t { + on k on.t = { +} + { + vu) { + kj } +} +protocol lk { + class func t() +} +class on: lk{ class func t {} +protocol qp { + class func kj() +} +class gf: qp { + class func kj() { } +} +(gf() x qp).ji.gf vu.kj == lk.kj> { +} +protocol t { + r kj +} +func lk() { + ({}) +} +protocol t { + r n +} +class lk { + rq (t: t.n) { + nm gf = gf +} +protocol t { + r k +} +struct n { + l kj: u + l t: u.k +} +protocol lk { + r ml + func >) +} +struct dc : lk { + r ml = o + func vu< u.k == ml>(lk: n) diff --git a/validation-test/compiler_crashers_fixed/0153-swift-parser-parsetypesimple.swift b/validation-test/compiler_crashers_fixed/00153-swift-parser-parsetypesimple.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0153-swift-parser-parsetypesimple.swift rename to validation-test/compiler_crashers_fixed/00153-swift-parser-parsetypesimple.swift diff --git a/validation-test/compiler_crashers_fixed/0154-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/00154-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0154-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/00154-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0155-swift-protocoldecl-requiresclassslow.swift b/validation-test/compiler_crashers_fixed/00155-swift-protocoldecl-requiresclassslow.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0155-swift-protocoldecl-requiresclassslow.swift rename to validation-test/compiler_crashers_fixed/00155-swift-protocoldecl-requiresclassslow.swift diff --git a/validation-test/compiler_crashers_fixed/0156-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/00156-swift-protocoltype-canonicalizeprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0156-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/00156-swift-protocoltype-canonicalizeprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/0157-swift-sourcefile-getcache.swift b/validation-test/compiler_crashers_fixed/00157-swift-sourcefile-getcache.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0157-swift-sourcefile-getcache.swift rename to validation-test/compiler_crashers_fixed/00157-swift-sourcefile-getcache.swift diff --git a/validation-test/compiler_crashers_fixed/0158-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/00158-swift-streamprinter-printtext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0158-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/00158-swift-streamprinter-printtext.swift diff --git a/validation-test/compiler_crashers_fixed/0160-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/00160-swift-substitutedtype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0160-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/00160-swift-substitutedtype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0161-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/00161-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0161-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/00161-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0162-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/00162-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0162-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/00162-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/0163-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00163-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0163-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00163-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0164-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00164-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0164-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00164-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0165-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/00165-swift-typebase-getdesugaredtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0165-swift-typebase-getdesugaredtype.swift rename to validation-test/compiler_crashers_fixed/00165-swift-typebase-getdesugaredtype.swift diff --git a/validation-test/compiler_crashers_fixed/0166-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/00166-swift-typebase-isequal.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0166-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/00166-swift-typebase-isequal.swift diff --git a/validation-test/compiler_crashers_fixed/0167-swift-typebase-isexistentialtype.swift b/validation-test/compiler_crashers_fixed/00167-swift-typebase-isexistentialtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0167-swift-typebase-isexistentialtype.swift rename to validation-test/compiler_crashers_fixed/00167-swift-typebase-isexistentialtype.swift diff --git a/validation-test/compiler_crashers_fixed/0168-swift-typebase-isspecialized.swift b/validation-test/compiler_crashers_fixed/00168-swift-typebase-isspecialized.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0168-swift-typebase-isspecialized.swift rename to validation-test/compiler_crashers_fixed/00168-swift-typebase-isspecialized.swift diff --git a/validation-test/compiler_crashers_fixed/0169-swift-typebase-operator.swift b/validation-test/compiler_crashers_fixed/00169-swift-typebase-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0169-swift-typebase-operator.swift rename to validation-test/compiler_crashers_fixed/00169-swift-typebase-operator.swift diff --git a/validation-test/compiler_crashers_fixed/0170-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/00170-swift-parser-skipsingle.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0170-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/00170-swift-parser-skipsingle.swift diff --git a/validation-test/compiler_crashers_fixed/0171-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/00171-std-function-func-swift-constraints-constraintsystem-simplifytype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0171-std-function-func-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/00171-std-function-func-swift-constraints-constraintsystem-simplifytype.swift diff --git a/validation-test/compiler_crashers_fixed/0172-swift-archetypebuilder-inferrequirementswalker-walktotypepost.swift b/validation-test/compiler_crashers_fixed/00172-swift-archetypebuilder-inferrequirementswalker-walktotypepost.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0172-swift-archetypebuilder-inferrequirementswalker-walktotypepost.swift rename to validation-test/compiler_crashers_fixed/00172-swift-archetypebuilder-inferrequirementswalker-walktotypepost.swift diff --git a/validation-test/compiler_crashers_fixed/0173-swift-typealiasdecl-typealiasdecl.swift b/validation-test/compiler_crashers_fixed/00173-swift-typealiasdecl-typealiasdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0173-swift-typealiasdecl-typealiasdecl.swift rename to validation-test/compiler_crashers_fixed/00173-swift-typealiasdecl-typealiasdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0174-swift-scopeinfo-addtoscope.swift b/validation-test/compiler_crashers_fixed/00174-swift-scopeinfo-addtoscope.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0174-swift-scopeinfo-addtoscope.swift rename to validation-test/compiler_crashers_fixed/00174-swift-scopeinfo-addtoscope.swift diff --git a/validation-test/compiler_crashers_fixed/0175-swift-parser-parseexprlist.swift b/validation-test/compiler_crashers_fixed/00175-swift-parser-parseexprlist.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0175-swift-parser-parseexprlist.swift rename to validation-test/compiler_crashers_fixed/00175-swift-parser-parseexprlist.swift diff --git a/validation-test/compiler_crashers_fixed/0176-vtable.swift b/validation-test/compiler_crashers_fixed/00176-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0176-vtable.swift rename to validation-test/compiler_crashers_fixed/00176-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/0177-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/00177-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0177-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/00177-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/0178-llvm-foldingset-swift-genericsignature-nodeequals.swift b/validation-test/compiler_crashers_fixed/00178-llvm-foldingset-swift-genericsignature-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0178-llvm-foldingset-swift-genericsignature-nodeequals.swift rename to validation-test/compiler_crashers_fixed/00178-llvm-foldingset-swift-genericsignature-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/0179-swift-protocolcompositiontype-build.swift b/validation-test/compiler_crashers_fixed/00179-swift-protocolcompositiontype-build.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0179-swift-protocolcompositiontype-build.swift rename to validation-test/compiler_crashers_fixed/00179-swift-protocolcompositiontype-build.swift diff --git a/validation-test/compiler_crashers_fixed/0180-szone-free-definite-size.swift b/validation-test/compiler_crashers_fixed/00180-szone-free-definite-size.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0180-szone-free-definite-size.swift rename to validation-test/compiler_crashers_fixed/00180-szone-free-definite-size.swift diff --git a/validation-test/compiler_crashers_fixed/0181-swift-parser-parseexprclosure.swift b/validation-test/compiler_crashers_fixed/00181-swift-parser-parseexprclosure.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0181-swift-parser-parseexprclosure.swift rename to validation-test/compiler_crashers_fixed/00181-swift-parser-parseexprclosure.swift diff --git a/validation-test/compiler_crashers_fixed/0182-swift-astcontext-getconformance.swift b/validation-test/compiler_crashers_fixed/00182-swift-astcontext-getconformance.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0182-swift-astcontext-getconformance.swift rename to validation-test/compiler_crashers_fixed/00182-swift-astcontext-getconformance.swift diff --git a/validation-test/compiler_crashers_fixed/0183-swift-inflightdiagnostic-fixitreplacechars.swift b/validation-test/compiler_crashers_fixed/00183-swift-inflightdiagnostic-fixitreplacechars.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0183-swift-inflightdiagnostic-fixitreplacechars.swift rename to validation-test/compiler_crashers_fixed/00183-swift-inflightdiagnostic-fixitreplacechars.swift diff --git a/validation-test/compiler_crashers_fixed/0184-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/00184-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0184-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/00184-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/0185-swift-completegenerictyperesolver-resolvegenerictypeparamtype.swift b/validation-test/compiler_crashers_fixed/00185-swift-completegenerictyperesolver-resolvegenerictypeparamtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0185-swift-completegenerictyperesolver-resolvegenerictypeparamtype.swift rename to validation-test/compiler_crashers_fixed/00185-swift-completegenerictyperesolver-resolvegenerictypeparamtype.swift diff --git a/validation-test/compiler_crashers_fixed/0186-swift-genericsignature-profile.swift b/validation-test/compiler_crashers_fixed/00186-swift-genericsignature-profile.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0186-swift-genericsignature-profile.swift rename to validation-test/compiler_crashers_fixed/00186-swift-genericsignature-profile.swift diff --git a/validation-test/compiler_crashers_fixed/0187-swift-lowering-typeconverter-getfunctiontypewithcaptures.swift b/validation-test/compiler_crashers_fixed/00187-swift-lowering-typeconverter-getfunctiontypewithcaptures.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0187-swift-lowering-typeconverter-getfunctiontypewithcaptures.swift rename to validation-test/compiler_crashers_fixed/00187-swift-lowering-typeconverter-getfunctiontypewithcaptures.swift diff --git a/validation-test/compiler_crashers_fixed/0188-swift-removeshadoweddecls.swift b/validation-test/compiler_crashers_fixed/00188-swift-removeshadoweddecls.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0188-swift-removeshadoweddecls.swift rename to validation-test/compiler_crashers_fixed/00188-swift-removeshadoweddecls.swift diff --git a/validation-test/compiler_crashers_fixed/0189-swift-tuplepattern-create.swift b/validation-test/compiler_crashers_fixed/00189-swift-tuplepattern-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0189-swift-tuplepattern-create.swift rename to validation-test/compiler_crashers_fixed/00189-swift-tuplepattern-create.swift diff --git a/validation-test/compiler_crashers_fixed/0190-swift-constraints-constraintgraph-unbindtypevariable.swift b/validation-test/compiler_crashers_fixed/00190-swift-constraints-constraintgraph-unbindtypevariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0190-swift-constraints-constraintgraph-unbindtypevariable.swift rename to validation-test/compiler_crashers_fixed/00190-swift-constraints-constraintgraph-unbindtypevariable.swift diff --git a/validation-test/compiler_crashers_fixed/0191-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/00191-swift-astprinter-printtextimpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0191-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/00191-swift-astprinter-printtextimpl.swift diff --git a/validation-test/compiler_crashers_fixed/0192-swift-astcontext-setconformsto.swift b/validation-test/compiler_crashers_fixed/00192-swift-astcontext-setconformsto.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0192-swift-astcontext-setconformsto.swift rename to validation-test/compiler_crashers_fixed/00192-swift-astcontext-setconformsto.swift diff --git a/validation-test/compiler_crashers_fixed/0193-swift-typebase-gettypevariables.swift b/validation-test/compiler_crashers_fixed/00193-swift-typebase-gettypevariables.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0193-swift-typebase-gettypevariables.swift rename to validation-test/compiler_crashers_fixed/00193-swift-typebase-gettypevariables.swift diff --git a/validation-test/compiler_crashers_fixed/0194-swift-parser-parseexprsequence.swift b/validation-test/compiler_crashers_fixed/00194-swift-parser-parseexprsequence.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0194-swift-parser-parseexprsequence.swift rename to validation-test/compiler_crashers_fixed/00194-swift-parser-parseexprsequence.swift diff --git a/validation-test/compiler_crashers_fixed/0195-swift-namelookup-lookupinmodule.swift b/validation-test/compiler_crashers_fixed/00195-swift-namelookup-lookupinmodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0195-swift-namelookup-lookupinmodule.swift rename to validation-test/compiler_crashers_fixed/00195-swift-namelookup-lookupinmodule.swift diff --git a/validation-test/compiler_crashers_fixed/0196-swift-constraints-constraint-create.swift b/validation-test/compiler_crashers_fixed/00196-swift-constraints-constraint-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0196-swift-constraints-constraint-create.swift rename to validation-test/compiler_crashers_fixed/00196-swift-constraints-constraint-create.swift diff --git a/validation-test/compiler_crashers_fixed/0197-swift-performstmtdiagnostics.swift b/validation-test/compiler_crashers_fixed/00197-swift-performstmtdiagnostics.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0197-swift-performstmtdiagnostics.swift rename to validation-test/compiler_crashers_fixed/00197-swift-performstmtdiagnostics.swift diff --git a/validation-test/compiler_crashers_fixed/0198-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/00198-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0198-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/00198-swift-constraints-constraintgraph-gatherconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/0199-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/00199-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0199-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/00199-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/0200-swift-parser-parsestmtreturn.swift b/validation-test/compiler_crashers_fixed/00200-swift-parser-parsestmtreturn.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0200-swift-parser-parsestmtreturn.swift rename to validation-test/compiler_crashers_fixed/00200-swift-parser-parsestmtreturn.swift diff --git a/validation-test/compiler_crashers_fixed/0201-swift-parser-parsetoken.swift b/validation-test/compiler_crashers_fixed/00201-swift-parser-parsetoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0201-swift-parser-parsetoken.swift rename to validation-test/compiler_crashers_fixed/00201-swift-parser-parsetoken.swift diff --git a/validation-test/compiler_crashers_fixed/0202-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/00202-swift-parser-parseexprpostfix.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0202-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/00202-swift-parser-parseexprpostfix.swift diff --git a/validation-test/compiler_crashers_fixed/0203-swift-type-print.swift b/validation-test/compiler_crashers_fixed/00203-swift-type-print.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0203-swift-type-print.swift rename to validation-test/compiler_crashers_fixed/00203-swift-type-print.swift diff --git a/validation-test/compiler_crashers_fixed/0204-swift-parser-parsedeclprotocol.swift b/validation-test/compiler_crashers_fixed/00204-swift-parser-parsedeclprotocol.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0204-swift-parser-parsedeclprotocol.swift rename to validation-test/compiler_crashers_fixed/00204-swift-parser-parsedeclprotocol.swift diff --git a/validation-test/compiler_crashers_fixed/0205-swift-exprhandle-get.swift b/validation-test/compiler_crashers_fixed/00205-swift-exprhandle-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0205-swift-exprhandle-get.swift rename to validation-test/compiler_crashers_fixed/00205-swift-exprhandle-get.swift diff --git a/validation-test/compiler_crashers_fixed/0206-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00206-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0206-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/00206-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/0207-swift-parser-parseexprcallsuffix.swift b/validation-test/compiler_crashers_fixed/00207-swift-parser-parseexprcallsuffix.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0207-swift-parser-parseexprcallsuffix.swift rename to validation-test/compiler_crashers_fixed/00207-swift-parser-parseexprcallsuffix.swift diff --git a/validation-test/compiler_crashers_fixed/0208-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/00208-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0208-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/00208-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/0209-swift-parser-parseclosuresignatureifpresent.swift b/validation-test/compiler_crashers_fixed/00209-swift-parser-parseclosuresignatureifpresent.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0209-swift-parser-parseclosuresignatureifpresent.swift rename to validation-test/compiler_crashers_fixed/00209-swift-parser-parseclosuresignatureifpresent.swift diff --git a/validation-test/compiler_crashers_fixed/0210-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift b/validation-test/compiler_crashers_fixed/00210-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0210-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift rename to validation-test/compiler_crashers_fixed/00210-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/00211-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/00211-swift-completegenerictyperesolver-resolvedependentmembertype.swift new file mode 100644 index 0000000000000..1ff17d237fd93 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00211-swift-completegenerictyperesolver-resolvedependentmembertype.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing +// Distributed under the terms of the MIT license + +func c() -> (e, e -> e) -> e { + f b f.f =c { +} +struct f o { + r q { +} +protocol p { + typealias m = q +} +m r : p { +} +func r (s: o) { +} +func r (s: s) { +} +m s

{ +} +class t : q { +} +class t { +} +protocol s { + func r() { + } +} +func t(s) ->

(() -> p) { +} +class q Self { + return b(self.dynamicType) + } +} +func b(t: AnyObject.Type) -> T! { + return nil +} diff --git a/validation-test/compiler_crashers_fixed/0273-swift-constraints-constraintgraphnode-getadjacency.swift b/validation-test/compiler_crashers_fixed/00273-swift-constraints-constraintgraphnode-getadjacency.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0273-swift-constraints-constraintgraphnode-getadjacency.swift rename to validation-test/compiler_crashers_fixed/00273-swift-constraints-constraintgraphnode-getadjacency.swift diff --git a/validation-test/compiler_crashers_fixed/0274-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/00274-swift-typechecker-checkinheritanceclause.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0274-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/00274-swift-typechecker-checkinheritanceclause.swift diff --git a/validation-test/compiler_crashers_fixed/0275-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/00275-swift-parser-parseexprpostfix.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0275-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/00275-swift-parser-parseexprpostfix.swift diff --git a/validation-test/compiler_crashers_fixed/0276-llvm-errs.swift b/validation-test/compiler_crashers_fixed/00276-llvm-errs.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0276-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/00276-llvm-errs.swift diff --git a/validation-test/compiler_crashers_fixed/00277-swift-typechecker-getinterfacetypefrominternaltype.swift b/validation-test/compiler_crashers_fixed/00277-swift-typechecker-getinterfacetypefrominternaltype.swift new file mode 100644 index 0000000000000..a23356886f667 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00277-swift-typechecker-getinterfacetypefrominternaltype.swift @@ -0,0 +1,46 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func n() -> (a, a -> a) -> a { + p m p.u = { +} + { + a) { + dc } +} +protocol n { +} +class p: n{ class func u {} +func t(a: Int = cb) { +} +let m = t +class m { + func a((x, m))(t: (x, a)) { + } +} +p w: Int -> Int = { +} +let dc: Int = { (o: Int, n: Int -> Int) -> Int r +}(u, w) +let b: Int = { o, n r +}(u, w) +protocol t : t { +} +func t() -> (y, y -> y) -> y { +} +protocol t { +} +protocol a : t { +} +protocol m : t { +} +protocol p { +} +n o : p { +} +func u (m: o) { +} +func u() -> (f, f -> f) -> f { + g e {} +struct g Int { +class A { +func g.b : Int { +typealias B() +init(false))() { +} +return d +} +case b { +var c: AnyObject.E == T>]((" +protocol P { +print() -> (n: A? = b U, b in a { +return { c: T>() { +return self.E == nil +} +import Foundation +enum A where T) ->(array: AnyObject, object1, AnyObject) -> [T: String { +} +let v: a = [T> Void>>>(c>Bool) +func call("A> Self { +protocol P { +typealias e == D>(false) +} +return nil +b: C) -> U, f.E +let c, V>(t: T) -> S("\() -> V>() +return self.d.b = F>() +let i: a { +var b in a { +typealias F +} +super.init(") +struct c = e: a = { +import Foundation +class func b: c> : C> () +typealias R = 0) +func b: NSObject { +typealias R +return g, U) +} +return $0 +struct e == F +func g.a("") +} +for b in +protocol A : T +enum S() { +} +} +import Foundation +self.d +f = 0 +} +} +} +}(t: T -> { +private let h> { +func a(c) { +} +if c == { c: B() +init ) +} +return nil +let g = { +typealias E +return [unowned self.init(g: T { +} +return g: A? { +let c(f(t: AnyObject, g: NSObject { +0 +class A : NSManagedObject { +protocol C { +d.Type) -> { +} +var e: C { +S(c +} +} +return $0) +func a(array: C>) { +struct D : A? = A? = Int +protocol c == "") +typealias h> U, object1, AnyObject) -> Void>() -> T) -> { +typealias E +struct e = { +protocol A { +import Foundation +} +return self.e where T>) -> Void>(x: P { +return b ()"A? = { +} +init() +var b { +} +} +struct e { +} +typealias h> T) -> { +var b = 0 +typealias F>: NSObject { +} +struct c == nil +return d +import Foundation +} +} +return "A> { +protocol P { +} +typealias R = T.d +} +let d +} +struct B : A"") +typealias h: I.h +} +typealias F = b +var b() +var f = B) -> { +} +} +func compose() +} +let d() { +} +enum S : a { -} -class b { -} -protocol c { - typealias g -} diff --git a/validation-test/compiler_crashers_fixed/0350-swift-constraints-constraintsystem-simplify.swift b/validation-test/compiler_crashers_fixed/00350-swift-constraints-constraintsystem-simplify.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0350-swift-constraints-constraintsystem-simplify.swift rename to validation-test/compiler_crashers_fixed/00350-swift-constraints-constraintsystem-simplify.swift diff --git a/validation-test/compiler_crashers_fixed/0351-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/00351-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0351-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/00351-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0352-swift-archetypebuilder-resolvearchetype.swift b/validation-test/compiler_crashers_fixed/00352-swift-archetypebuilder-resolvearchetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0352-swift-archetypebuilder-resolvearchetype.swift rename to validation-test/compiler_crashers_fixed/00352-swift-archetypebuilder-resolvearchetype.swift diff --git a/validation-test/compiler_crashers_fixed/0353-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00353-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0353-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00353-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0354-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/00354-swift-modulefile-maybereadpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0354-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/00354-swift-modulefile-maybereadpattern.swift diff --git a/validation-test/compiler_crashers_fixed/0355-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00355-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0355-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00355-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0356-swift-parser-parsegenericarguments.swift b/validation-test/compiler_crashers_fixed/00356-swift-parser-parsegenericarguments.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0356-swift-parser-parsegenericarguments.swift rename to validation-test/compiler_crashers_fixed/00356-swift-parser-parsegenericarguments.swift diff --git a/validation-test/compiler_crashers_fixed/0357-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/00357-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0357-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/00357-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/0358-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift b/validation-test/compiler_crashers_fixed/00358-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0358-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift rename to validation-test/compiler_crashers_fixed/00358-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0359-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00359-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0359-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00359-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0360-swift-parser-parseexprlist.swift b/validation-test/compiler_crashers_fixed/00360-swift-parser-parseexprlist.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0360-swift-parser-parseexprlist.swift rename to validation-test/compiler_crashers_fixed/00360-swift-parser-parseexprlist.swift diff --git a/validation-test/compiler_crashers_fixed/0361-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/00361-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0361-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/00361-swift-constraints-constraintgraph-gatherconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/0362-clang-stmt-statisticsenabled.swift b/validation-test/compiler_crashers_fixed/00362-clang-stmt-statisticsenabled.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0362-clang-stmt-statisticsenabled.swift rename to validation-test/compiler_crashers_fixed/00362-clang-stmt-statisticsenabled.swift diff --git a/validation-test/compiler_crashers_fixed/0363-swift-scopeinfo-addtoscope.swift b/validation-test/compiler_crashers_fixed/00363-swift-scopeinfo-addtoscope.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0363-swift-scopeinfo-addtoscope.swift rename to validation-test/compiler_crashers_fixed/00363-swift-scopeinfo-addtoscope.swift diff --git a/validation-test/compiler_crashers_fixed/0364-swift-typechecker-isrepresentableinobjc.swift b/validation-test/compiler_crashers_fixed/00364-swift-typechecker-isrepresentableinobjc.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0364-swift-typechecker-isrepresentableinobjc.swift rename to validation-test/compiler_crashers_fixed/00364-swift-typechecker-isrepresentableinobjc.swift diff --git a/validation-test/compiler_crashers_fixed/0365-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00365-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0365-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00365-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0366-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00366-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0366-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00366-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0367-llvm-errs.swift b/validation-test/compiler_crashers_fixed/00367-llvm-errs.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0367-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/00367-llvm-errs.swift diff --git a/validation-test/compiler_crashers_fixed/0368-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00368-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0368-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00368-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0369-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00369-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0369-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00369-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0370-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/00370-swift-completegenerictyperesolver-resolvedependentmembertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0370-swift-completegenerictyperesolver-resolvedependentmembertype.swift rename to validation-test/compiler_crashers_fixed/00370-swift-completegenerictyperesolver-resolvedependentmembertype.swift diff --git a/validation-test/compiler_crashers_fixed/00371-swift-archetypetype-setnestedtypes.swift b/validation-test/compiler_crashers_fixed/00371-swift-archetypetype-setnestedtypes.swift new file mode 100644 index 0000000000000..45c8764b1c964 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00371-swift-archetypetype-setnestedtypes.swift @@ -0,0 +1,40 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func g { +typealias R = b: a { +struct d T! { +} +static let t: d = b) -> Int = b +} +protocol P { +typealias e : a { +protocol a { +c(self.b = nil +if true { +func call(array: e: c: T where H.e where H.a +func b +} +typealias F = a +func call(x: A() +} +[T>("")("") +S) -> Int = nil +} +let d.B V { +class d) { +} +protocol d = { +} +} +} +class func a(n: C { +} +protocol P { +struct e = { +} +let i: d { +} +typealias e : e = D> { +} +var b: Int diff --git a/validation-test/compiler_crashers_fixed/0411-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00411-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0411-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00411-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0412-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00412-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0412-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00412-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0413-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00413-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0413-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/00413-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0414-swift-archetypebuilder-resolvearchetype.swift b/validation-test/compiler_crashers_fixed/00414-swift-archetypebuilder-resolvearchetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0414-swift-archetypebuilder-resolvearchetype.swift rename to validation-test/compiler_crashers_fixed/00414-swift-archetypebuilder-resolvearchetype.swift diff --git a/validation-test/compiler_crashers_fixed/0415-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00415-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0415-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00415-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0416-swift-typechecker-conformstoprotocol.swift b/validation-test/compiler_crashers_fixed/00416-swift-typechecker-conformstoprotocol.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0416-swift-typechecker-conformstoprotocol.swift rename to validation-test/compiler_crashers_fixed/00416-swift-typechecker-conformstoprotocol.swift diff --git a/validation-test/compiler_crashers_fixed/0417-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00417-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0417-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00417-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0418-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00418-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0418-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00418-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0419-llvm-raw-fd-ostream-write-impl.swift b/validation-test/compiler_crashers_fixed/00419-llvm-raw-fd-ostream-write-impl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0419-llvm-raw-fd-ostream-write-impl.swift rename to validation-test/compiler_crashers_fixed/00419-llvm-raw-fd-ostream-write-impl.swift diff --git a/validation-test/compiler_crashers_fixed/0420-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00420-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0420-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00420-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0421-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00421-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0421-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00421-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0422-void.swift b/validation-test/compiler_crashers_fixed/00422-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0422-void.swift rename to validation-test/compiler_crashers_fixed/00422-void.swift diff --git a/validation-test/compiler_crashers_fixed/0423-swift-archetypebuilder-resolvearchetype.swift b/validation-test/compiler_crashers_fixed/00423-swift-archetypebuilder-resolvearchetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0423-swift-archetypebuilder-resolvearchetype.swift rename to validation-test/compiler_crashers_fixed/00423-swift-archetypebuilder-resolvearchetype.swift diff --git a/validation-test/compiler_crashers_fixed/0424-no-stacktrace.random.swift b/validation-test/compiler_crashers_fixed/00424-no-stacktrace.random.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0424-no-stacktrace.random.swift rename to validation-test/compiler_crashers_fixed/00424-no-stacktrace.random.swift diff --git a/validation-test/compiler_crashers_fixed/0425-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00425-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0425-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00425-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0426-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00426-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0426-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00426-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0427-void.swift b/validation-test/compiler_crashers_fixed/00427-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0427-void.swift rename to validation-test/compiler_crashers_fixed/00427-void.swift diff --git a/validation-test/compiler_crashers_fixed/0428-getcallerdefaultarg.swift b/validation-test/compiler_crashers_fixed/00428-getcallerdefaultarg.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0428-getcallerdefaultarg.swift rename to validation-test/compiler_crashers_fixed/00428-getcallerdefaultarg.swift diff --git a/validation-test/compiler_crashers_fixed/0429-vtable.swift b/validation-test/compiler_crashers_fixed/00429-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0429-vtable.swift rename to validation-test/compiler_crashers_fixed/00429-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/0430-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00430-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0430-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00430-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0431-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00431-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0431-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00431-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0432-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00432-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0432-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00432-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0433-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00433-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0433-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00433-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0434-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00434-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0434-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00434-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0435-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00435-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0435-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00435-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0436-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00436-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0436-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00436-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0437-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00437-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0437-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00437-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0438-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/00438-swift-genericsignature-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0438-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/00438-swift-genericsignature-get.swift diff --git a/validation-test/compiler_crashers_fixed/0439-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00439-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0439-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00439-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/00440-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00440-resolvetypedecl.swift new file mode 100644 index 0000000000000..a1f47686fd2c2 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00440-resolvetypedecl.swift @@ -0,0 +1,13 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +let i: a { +func f: d { +let g = B(v: P { +} +} +struct B Int = { - return $0 -} -let d: Int = { c, b in -}(f, e) diff --git a/validation-test/compiler_crashers_fixed/0490-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/00490-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0490-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/00490-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0491-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/00491-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0491-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/00491-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/00492-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/00492-swift-metatypetype-get.swift new file mode 100644 index 0000000000000..1af87aad815db --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00492-swift-metatypetype-get.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func g Int { +class A { +class func f { +init (e: A.B) { +} +static +func c() -> (g, g -> g) -> g { +d b d.f = { +} +{ +g) { +i } +} +i c { +} +class d: c{ class func f {} +struct d diff --git a/validation-test/compiler_crashers_fixed/0531-llvm-foldingsetnodeid-operator.swift b/validation-test/compiler_crashers_fixed/00531-llvm-foldingsetnodeid-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0531-llvm-foldingsetnodeid-operator.swift rename to validation-test/compiler_crashers_fixed/00531-llvm-foldingsetnodeid-operator.swift diff --git a/validation-test/compiler_crashers_fixed/0532-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/00532-swift-constraints-solution-solution.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0532-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/00532-swift-constraints-solution-solution.swift diff --git a/validation-test/compiler_crashers_fixed/0533-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00533-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0533-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00533-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0534-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00534-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0534-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00534-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0535-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/00535-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0535-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/00535-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/0536-vtable.swift b/validation-test/compiler_crashers_fixed/00536-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0536-vtable.swift rename to validation-test/compiler_crashers_fixed/00536-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/0537-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00537-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0537-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/00537-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/00538-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/00538-swift-clangmoduleunit-getadaptermodule.swift new file mode 100644 index 0000000000000..eb2b14291fc37 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00538-swift-clangmoduleunit-getadaptermodule.swift @@ -0,0 +1,20 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +import Foundation +func b: A() +protocol A { +protocol P { +for b = { c: NSManagedObject { +} +} +} +protocol P { +struct Q T -> V, f: String { +struct e = { +} +deinit { +enum S T : T where g() +print() { +typealias e { +} +protocol C { +typealias e = a +struct e = D>) { +} +protocol a { +let i: e) diff --git a/validation-test/compiler_crashers_fixed/0551-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00551-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0551-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00551-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0552-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00552-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0552-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00552-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0553-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00553-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0553-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00553-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0554-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00554-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0554-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00554-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0555-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/00555-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0555-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/00555-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/0556-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00556-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0556-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00556-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0557-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00557-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0557-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00557-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0558-ioctl.swift b/validation-test/compiler_crashers_fixed/00558-ioctl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0558-ioctl.swift rename to validation-test/compiler_crashers_fixed/00558-ioctl.swift diff --git a/validation-test/compiler_crashers_fixed/0559-void.swift b/validation-test/compiler_crashers_fixed/00559-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0559-void.swift rename to validation-test/compiler_crashers_fixed/00559-void.swift diff --git a/validation-test/compiler_crashers_fixed/0560-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00560-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0560-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00560-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0561-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00561-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0561-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00561-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0562-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/00562-swift-typechecker-typecheckexpression.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0562-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/00562-swift-typechecker-typecheckexpression.swift diff --git a/validation-test/compiler_crashers_fixed/0563-cerror.swift b/validation-test/compiler_crashers_fixed/00563-cerror.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0563-cerror.swift rename to validation-test/compiler_crashers_fixed/00563-cerror.swift diff --git a/validation-test/compiler_crashers_fixed/0564-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00564-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0564-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00564-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0565-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/00565-swift-lexer-getlocforendoftoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0565-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/00565-swift-lexer-getlocforendoftoken.swift diff --git a/validation-test/compiler_crashers_fixed/0566-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00566-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0566-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00566-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0567-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/00567-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0567-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/00567-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/0568-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00568-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0568-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00568-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0569-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00569-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0569-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00569-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0570-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00570-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0570-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00570-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0571-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00571-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0571-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00571-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0572-resolvetypedecl.random.swift b/validation-test/compiler_crashers_fixed/00572-resolvetypedecl.random.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0572-resolvetypedecl.random.swift rename to validation-test/compiler_crashers_fixed/00572-resolvetypedecl.random.swift diff --git a/validation-test/compiler_crashers_fixed/0573-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/00573-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0573-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/00573-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0574-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00574-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0574-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00574-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0575-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/00575-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0575-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/00575-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0576-llvm-errs.swift b/validation-test/compiler_crashers_fixed/00576-llvm-errs.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0576-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/00576-llvm-errs.swift diff --git a/validation-test/compiler_crashers_fixed/0577-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00577-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0577-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00577-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0578-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00578-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0578-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00578-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0579-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/00579-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0579-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/00579-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/0580-vtable.swift b/validation-test/compiler_crashers_fixed/00580-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0580-vtable.swift rename to validation-test/compiler_crashers_fixed/00580-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/0581-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00581-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0581-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00581-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0582-a.swift b/validation-test/compiler_crashers_fixed/00582-a.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0582-a.swift rename to validation-test/compiler_crashers_fixed/00582-a.swift diff --git a/validation-test/compiler_crashers_fixed/0583-swift-funcdecl-setdeserializedsignature.swift b/validation-test/compiler_crashers_fixed/00583-swift-funcdecl-setdeserializedsignature.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0583-swift-funcdecl-setdeserializedsignature.swift rename to validation-test/compiler_crashers_fixed/00583-swift-funcdecl-setdeserializedsignature.swift diff --git a/validation-test/compiler_crashers_fixed/0584-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/00584-swift-constraints-constraintlocator-profile.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0584-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/00584-swift-constraints-constraintlocator-profile.swift diff --git a/validation-test/compiler_crashers_fixed/0585-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00585-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0585-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00585-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0586-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00586-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0586-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00586-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0587-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/00587-swift-pattern-foreachvariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0587-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/00587-swift-pattern-foreachvariable.swift diff --git a/validation-test/compiler_crashers_fixed/0588-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00588-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0588-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00588-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0589-swift-diagnosticengine-diagnose.swift b/validation-test/compiler_crashers_fixed/00589-swift-diagnosticengine-diagnose.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0589-swift-diagnosticengine-diagnose.swift rename to validation-test/compiler_crashers_fixed/00589-swift-diagnosticengine-diagnose.swift diff --git a/validation-test/compiler_crashers_fixed/0590-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00590-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0590-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00590-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0591-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00591-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0591-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00591-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0592-swift-parser-parseexpridentifier.swift b/validation-test/compiler_crashers_fixed/00592-swift-parser-parseexpridentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0592-swift-parser-parseexpridentifier.swift rename to validation-test/compiler_crashers_fixed/00592-swift-parser-parseexpridentifier.swift diff --git a/validation-test/compiler_crashers_fixed/0593-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00593-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0593-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00593-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0594-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00594-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0594-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00594-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0595-swift-scopeinfo-addtoscope.swift b/validation-test/compiler_crashers_fixed/00595-swift-scopeinfo-addtoscope.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0595-swift-scopeinfo-addtoscope.swift rename to validation-test/compiler_crashers_fixed/00595-swift-scopeinfo-addtoscope.swift diff --git a/validation-test/compiler_crashers_fixed/0596-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/00596-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0596-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/00596-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/0597-llvm-prettystacktraceentry-prettystacktraceentry.swift b/validation-test/compiler_crashers_fixed/00597-llvm-prettystacktraceentry-prettystacktraceentry.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0597-llvm-prettystacktraceentry-prettystacktraceentry.swift rename to validation-test/compiler_crashers_fixed/00597-llvm-prettystacktraceentry-prettystacktraceentry.swift diff --git a/validation-test/compiler_crashers_fixed/0598-clang-sema-lookupname.swift b/validation-test/compiler_crashers_fixed/00598-clang-sema-lookupname.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0598-clang-sema-lookupname.swift rename to validation-test/compiler_crashers_fixed/00598-clang-sema-lookupname.swift diff --git a/validation-test/compiler_crashers_fixed/0599-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/00599-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0599-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/00599-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/0601-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00601-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0601-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00601-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0602-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/00602-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0602-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/00602-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/0603-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00603-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0603-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00603-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0604-swift-typebase-operator.swift b/validation-test/compiler_crashers_fixed/00604-swift-typebase-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0604-swift-typebase-operator.swift rename to validation-test/compiler_crashers_fixed/00604-swift-typebase-operator.swift diff --git a/validation-test/compiler_crashers_fixed/0605-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/00605-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0605-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/00605-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/0606-swift-typechecker-conformstoprotocol.swift b/validation-test/compiler_crashers_fixed/00606-swift-typechecker-conformstoprotocol.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0606-swift-typechecker-conformstoprotocol.swift rename to validation-test/compiler_crashers_fixed/00606-swift-typechecker-conformstoprotocol.swift diff --git a/validation-test/compiler_crashers_fixed/0607-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00607-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0607-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00607-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0608-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/00608-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0608-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/00608-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/0609-llvm-prettystacktraceentry-prettystacktraceentry.swift b/validation-test/compiler_crashers_fixed/00609-llvm-prettystacktraceentry-prettystacktraceentry.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0609-llvm-prettystacktraceentry-prettystacktraceentry.swift rename to validation-test/compiler_crashers_fixed/00609-llvm-prettystacktraceentry-prettystacktraceentry.swift diff --git a/validation-test/compiler_crashers_fixed/0610-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/00610-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0610-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/00610-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0611-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/00611-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0611-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/00611-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/0612-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/00612-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0612-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/00612-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0613-connectedcomponentsdfs.swift b/validation-test/compiler_crashers_fixed/00613-connectedcomponentsdfs.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0613-connectedcomponentsdfs.swift rename to validation-test/compiler_crashers_fixed/00613-connectedcomponentsdfs.swift diff --git a/validation-test/compiler_crashers_fixed/0614-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00614-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0614-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00614-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0615-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00615-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0615-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00615-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0616-swift-parser-parsedecl.swift b/validation-test/compiler_crashers_fixed/00616-swift-parser-parsedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0616-swift-parser-parsedecl.swift rename to validation-test/compiler_crashers_fixed/00616-swift-parser-parsedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0617-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/00617-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0617-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/00617-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/0618-swift-parser-parseexprsequence.swift b/validation-test/compiler_crashers_fixed/00618-swift-parser-parseexprsequence.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0618-swift-parser-parseexprsequence.swift rename to validation-test/compiler_crashers_fixed/00618-swift-parser-parseexprsequence.swift diff --git a/validation-test/compiler_crashers_fixed/0619-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00619-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0619-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00619-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0620-llvm-bitstreamcursor-readabbreviatedfield.swift b/validation-test/compiler_crashers_fixed/00620-llvm-bitstreamcursor-readabbreviatedfield.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0620-llvm-bitstreamcursor-readabbreviatedfield.swift rename to validation-test/compiler_crashers_fixed/00620-llvm-bitstreamcursor-readabbreviatedfield.swift diff --git a/validation-test/compiler_crashers_fixed/0621-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00621-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0621-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00621-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0622-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00622-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0622-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00622-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0623-validateattributes.swift b/validation-test/compiler_crashers_fixed/00623-validateattributes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0623-validateattributes.swift rename to validation-test/compiler_crashers_fixed/00623-validateattributes.swift diff --git a/validation-test/compiler_crashers_fixed/0624-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/00624-swift-constraints-solution-solution.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0624-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/00624-swift-constraints-solution-solution.swift diff --git a/validation-test/compiler_crashers_fixed/0625-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00625-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0625-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00625-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers/00626-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/00626-swift-lexer-lexidentifier.swift similarity index 81% rename from validation-test/compiler_crashers/00626-swift-lexer-lexidentifier.swift rename to validation-test/compiler_crashers_fixed/00626-swift-lexer-lexidentifier.swift index cf0afd39e53bf..c3da82631019d 100644 --- a/validation-test/compiler_crashers/00626-swift-lexer-lexidentifier.swift +++ b/validation-test/compiler_crashers_fixed/00626-swift-lexer-lexidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/0627-bool.swift b/validation-test/compiler_crashers_fixed/00627-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0627-bool.swift rename to validation-test/compiler_crashers_fixed/00627-bool.swift diff --git a/validation-test/compiler_crashers_fixed/0628-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/00628-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0628-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/00628-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/0629-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00629-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0629-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00629-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0630-llvm-smalldensemap-swift-constraints-constraint.swift b/validation-test/compiler_crashers_fixed/00630-llvm-smalldensemap-swift-constraints-constraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0630-llvm-smalldensemap-swift-constraints-constraint.swift rename to validation-test/compiler_crashers_fixed/00630-llvm-smalldensemap-swift-constraints-constraint.swift diff --git a/validation-test/compiler_crashers_fixed/0631-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00631-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0631-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00631-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0632-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/00632-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0632-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/00632-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/0633-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00633-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0633-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/00633-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0634-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00634-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0634-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00634-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0635-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/00635-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0635-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/00635-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/0636-llvm-twine-str.swift b/validation-test/compiler_crashers_fixed/00636-llvm-twine-str.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0636-llvm-twine-str.swift rename to validation-test/compiler_crashers_fixed/00636-llvm-twine-str.swift diff --git a/validation-test/compiler_crashers_fixed/00637-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/00637-swift-lexer-getlocforendoftoken.swift new file mode 100644 index 0000000000000..f1c725d361f84 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00637-swift-lexer-getlocforendoftoken.swift @@ -0,0 +1,14 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func b { +func f: I.e = ") +} +} +var d = { diff --git a/validation-test/compiler_crashers_fixed/0638-swift-typechecker-typecheckexpressionshallow.swift b/validation-test/compiler_crashers_fixed/00638-swift-typechecker-typecheckexpressionshallow.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0638-swift-typechecker-typecheckexpressionshallow.swift rename to validation-test/compiler_crashers_fixed/00638-swift-typechecker-typecheckexpressionshallow.swift diff --git a/validation-test/compiler_crashers_fixed/0639-void.swift b/validation-test/compiler_crashers_fixed/00639-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0639-void.swift rename to validation-test/compiler_crashers_fixed/00639-void.swift diff --git a/validation-test/compiler_crashers_fixed/0640-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/00640-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0640-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/00640-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0641-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/00641-swift-constraints-constraintsystem-solve.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0641-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/00641-swift-constraints-constraintsystem-solve.swift diff --git a/validation-test/compiler_crashers_fixed/0642-llvm-errs.swift b/validation-test/compiler_crashers_fixed/00642-llvm-errs.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0642-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/00642-llvm-errs.swift diff --git a/validation-test/compiler_crashers_fixed/0643-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/00643-swift-completegenerictyperesolver-resolvedependentmembertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0643-swift-completegenerictyperesolver-resolvedependentmembertype.swift rename to validation-test/compiler_crashers_fixed/00643-swift-completegenerictyperesolver-resolvedependentmembertype.swift diff --git a/validation-test/compiler_crashers_fixed/0644-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00644-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0644-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00644-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/00645-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00645-resolvetypedecl.swift new file mode 100644 index 0000000000000..29d3d35eda26b --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00645-resolvetypedecl.swift @@ -0,0 +1,9 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class func g(f: d = "A? = B(c: C> String { +struct d) +} +func g: A? = .Type) -> { +let c((" +typealias B() diff --git a/validation-test/compiler_crashers_fixed/0648-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00648-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0648-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00648-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0649-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/00649-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0649-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/00649-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0650-szone-malloc-should-clear.swift b/validation-test/compiler_crashers_fixed/00650-szone-malloc-should-clear.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0650-szone-malloc-should-clear.swift rename to validation-test/compiler_crashers_fixed/00650-szone-malloc-should-clear.swift diff --git a/validation-test/compiler_crashers_fixed/0651-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00651-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0651-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00651-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0652-swift-constraints-constraintgraphnode-addconstraint.swift b/validation-test/compiler_crashers_fixed/00652-swift-constraints-constraintgraphnode-addconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0652-swift-constraints-constraintgraphnode-addconstraint.swift rename to validation-test/compiler_crashers_fixed/00652-swift-constraints-constraintgraphnode-addconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/0653-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/00653-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0653-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/00653-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/0654-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00654-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0654-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00654-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0655-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/00655-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0655-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/00655-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/0656-swift-astcontext-getidentifier.swift b/validation-test/compiler_crashers_fixed/00656-swift-astcontext-getidentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0656-swift-astcontext-getidentifier.swift rename to validation-test/compiler_crashers_fixed/00656-swift-astcontext-getidentifier.swift diff --git a/validation-test/compiler_crashers_fixed/0657-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00657-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0657-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00657-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0658-swift-constraints-constraint-create.swift b/validation-test/compiler_crashers_fixed/00658-swift-constraints-constraint-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0658-swift-constraints-constraint-create.swift rename to validation-test/compiler_crashers_fixed/00658-swift-constraints-constraint-create.swift diff --git a/validation-test/compiler_crashers_fixed/0659-s.swift b/validation-test/compiler_crashers_fixed/00659-s.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0659-s.swift rename to validation-test/compiler_crashers_fixed/00659-s.swift diff --git a/validation-test/compiler_crashers_fixed/0660-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/00660-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0660-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/00660-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0661-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00661-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0661-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00661-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0662-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/00662-swift-typebase-isequal.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0662-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/00662-swift-typebase-isequal.swift diff --git a/validation-test/compiler_crashers_fixed/0663-swift-module-lookupconformance.swift b/validation-test/compiler_crashers_fixed/00663-swift-module-lookupconformance.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0663-swift-module-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/00663-swift-module-lookupconformance.swift diff --git a/validation-test/compiler_crashers_fixed/0664-swift-pattern-operator.swift b/validation-test/compiler_crashers_fixed/00664-swift-pattern-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0664-swift-pattern-operator.swift rename to validation-test/compiler_crashers_fixed/00664-swift-pattern-operator.swift diff --git a/validation-test/compiler_crashers_fixed/0665-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/00665-swift-streamprinter-printtext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0665-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/00665-swift-streamprinter-printtext.swift diff --git a/validation-test/compiler_crashers_fixed/0666-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00666-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0666-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00666-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0667-swift-typedecl-getdeclaredtype.swift b/validation-test/compiler_crashers_fixed/00667-swift-typedecl-getdeclaredtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0667-swift-typedecl-getdeclaredtype.swift rename to validation-test/compiler_crashers_fixed/00667-swift-typedecl-getdeclaredtype.swift diff --git a/validation-test/compiler_crashers_fixed/0668-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00668-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0668-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00668-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0669-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/00669-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0669-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/00669-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0670-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00670-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0670-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00670-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0671-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00671-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0671-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/00671-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0672-swift-diagnosticengine-diagnose.swift b/validation-test/compiler_crashers_fixed/00672-swift-diagnosticengine-diagnose.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0672-swift-diagnosticengine-diagnose.swift rename to validation-test/compiler_crashers_fixed/00672-swift-diagnosticengine-diagnose.swift diff --git a/validation-test/compiler_crashers_fixed/0673-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00673-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0673-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00673-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0674-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00674-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0674-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00674-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0675-swift-astcontext-getprotocol.swift b/validation-test/compiler_crashers_fixed/00675-swift-astcontext-getprotocol.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0675-swift-astcontext-getprotocol.swift rename to validation-test/compiler_crashers_fixed/00675-swift-astcontext-getprotocol.swift diff --git a/validation-test/compiler_crashers_fixed/00676-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00676-std-function-func-swift-type-subst.swift new file mode 100644 index 0000000000000..34acbc68176f0 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00676-std-function-func-swift-type-subst.swift @@ -0,0 +1,27 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func call(object1, e)-> { +struct c { +struct A { +func c { +typealias F = A String { +protocol d : T] { +} +} +} +} +if true { +} +protocol c { +typealias f = a"\(AnyObject.init(a(b +case A>?) { +} +protocol a { +i() -> { +} +typealias R = f, ""] diff --git a/validation-test/compiler_crashers_fixed/0677-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/00677-swift-typebase-isequal.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0677-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/00677-swift-typebase-isequal.swift diff --git a/validation-test/compiler_crashers_fixed/0678-swift-availabilityattr-isunavailable.swift b/validation-test/compiler_crashers_fixed/00678-swift-availabilityattr-isunavailable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0678-swift-availabilityattr-isunavailable.swift rename to validation-test/compiler_crashers_fixed/00678-swift-availabilityattr-isunavailable.swift diff --git a/validation-test/compiler_crashers_fixed/0679-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/00679-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0679-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/00679-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/0680-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00680-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0680-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00680-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0681-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00681-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0681-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00681-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0682-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00682-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0682-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00682-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0683-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/00683-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0683-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/00683-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0684-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00684-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0684-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00684-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0685-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00685-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0685-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00685-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0686-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00686-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0686-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00686-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0687-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/00687-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0687-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/00687-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0688-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00688-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0688-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00688-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0689-b.swift b/validation-test/compiler_crashers_fixed/00689-b.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0689-b.swift rename to validation-test/compiler_crashers_fixed/00689-b.swift diff --git a/validation-test/compiler_crashers_fixed/0690-swift-declname-declname.swift b/validation-test/compiler_crashers_fixed/00690-swift-declname-declname.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0690-swift-declname-declname.swift rename to validation-test/compiler_crashers_fixed/00690-swift-declname-declname.swift diff --git a/validation-test/compiler_crashers_fixed/00691-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/00691-swift-inflightdiagnostic.swift new file mode 100644 index 0000000000000..15289a065592f --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00691-swift-inflightdiagnostic.swift @@ -0,0 +1,37 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +dynamic +) +func n() -> (w, w -> w) -> w { +o m o.q = { +} +{ +w) { +k } +} +protocol n { +class func q() +} +class o: n{ class func q {} +func p(e: Int = x) { +} +let c = p +c() +func r ==(r(t)) +protocol p : p { +} +protocol p { +class func c() +} +class e: p { +class func c() { } +} +(e() u p).v.c() +k e.w == l> { +} +func p(c: Any, init(b: c) { +: e, diff --git a/validation-test/compiler_crashers_fixed/0692-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00692-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0692-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00692-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0693-swift-typechecker-validatetype.swift b/validation-test/compiler_crashers_fixed/00693-swift-typechecker-validatetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0693-swift-typechecker-validatetype.swift rename to validation-test/compiler_crashers_fixed/00693-swift-typechecker-validatetype.swift diff --git a/validation-test/compiler_crashers_fixed/0694-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00694-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0694-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00694-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0695-swift-availabilityattr-isunavailable.swift b/validation-test/compiler_crashers_fixed/00695-swift-availabilityattr-isunavailable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0695-swift-availabilityattr-isunavailable.swift rename to validation-test/compiler_crashers_fixed/00695-swift-availabilityattr-isunavailable.swift diff --git a/validation-test/compiler_crashers_fixed/00696-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00696-std-function-func-swift-type-subst.swift new file mode 100644 index 0000000000000..1f714b1f4ba66 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00696-std-function-func-swift-type-subst.swift @@ -0,0 +1,13 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol C { +protocol B { +typealias C = b() +} +typealias e where S) { +} +typealias b = B diff --git a/validation-test/compiler_crashers_fixed/0698-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/00698-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0698-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/00698-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/0699-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/00699-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0699-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/00699-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/0700-swift-constraints-constraintsystem-matchdeepequalitytypes.swift b/validation-test/compiler_crashers_fixed/00700-swift-constraints-constraintsystem-matchdeepequalitytypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0700-swift-constraints-constraintsystem-matchdeepequalitytypes.swift rename to validation-test/compiler_crashers_fixed/00700-swift-constraints-constraintsystem-matchdeepequalitytypes.swift diff --git a/validation-test/compiler_crashers_fixed/0701-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00701-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0701-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00701-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0702-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/00702-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0702-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/00702-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/0703-swift-sourcemanager-addnewsourcebuffer.swift b/validation-test/compiler_crashers_fixed/00703-swift-sourcemanager-addnewsourcebuffer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0703-swift-sourcemanager-addnewsourcebuffer.swift rename to validation-test/compiler_crashers_fixed/00703-swift-sourcemanager-addnewsourcebuffer.swift diff --git a/validation-test/compiler_crashers_fixed/0704-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00704-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0704-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00704-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0705-swift-typechecker-validategenericfuncsignature.swift b/validation-test/compiler_crashers_fixed/00705-swift-typechecker-validategenericfuncsignature.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0705-swift-typechecker-validategenericfuncsignature.swift rename to validation-test/compiler_crashers_fixed/00705-swift-typechecker-validategenericfuncsignature.swift diff --git a/validation-test/compiler_crashers_fixed/0706-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/00706-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0706-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/00706-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/0707-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/00707-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0707-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/00707-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0708-swift-parser-parsetoken.swift b/validation-test/compiler_crashers_fixed/00708-swift-parser-parsetoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0708-swift-parser-parsetoken.swift rename to validation-test/compiler_crashers_fixed/00708-swift-parser-parsetoken.swift diff --git a/validation-test/compiler_crashers_fixed/0709-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00709-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0709-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00709-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0710-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/00710-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0710-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/00710-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/0711-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00711-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0711-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00711-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0712-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/00712-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0712-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/00712-swift-constraints-constraintgraph-gatherconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/0713-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00713-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0713-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00713-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0714-void.swift b/validation-test/compiler_crashers_fixed/00714-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0714-void.swift rename to validation-test/compiler_crashers_fixed/00714-void.swift diff --git a/validation-test/compiler_crashers_fixed/0715-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/00715-swift-constraints-constraintsystem-solve.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0715-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/00715-swift-constraints-constraintsystem-solve.swift diff --git a/validation-test/compiler_crashers_fixed/0716-swift-archetypetype-setnestedtypes.swift b/validation-test/compiler_crashers_fixed/00716-swift-archetypetype-setnestedtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0716-swift-archetypetype-setnestedtypes.swift rename to validation-test/compiler_crashers_fixed/00716-swift-archetypetype-setnestedtypes.swift diff --git a/validation-test/compiler_crashers_fixed/0717-swift-diagnosticengine-diagnose.swift b/validation-test/compiler_crashers_fixed/00717-swift-diagnosticengine-diagnose.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0717-swift-diagnosticengine-diagnose.swift rename to validation-test/compiler_crashers_fixed/00717-swift-diagnosticengine-diagnose.swift diff --git a/validation-test/compiler_crashers_fixed/0718-swift-parentype-get.swift b/validation-test/compiler_crashers_fixed/00718-swift-parentype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0718-swift-parentype-get.swift rename to validation-test/compiler_crashers_fixed/00718-swift-parentype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0719-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00719-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0719-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00719-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0720-szone-malloc-should-clear.swift b/validation-test/compiler_crashers_fixed/00720-szone-malloc-should-clear.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0720-szone-malloc-should-clear.swift rename to validation-test/compiler_crashers_fixed/00720-szone-malloc-should-clear.swift diff --git a/validation-test/compiler_crashers_fixed/0721-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00721-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0721-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00721-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0722-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00722-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0722-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00722-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0723-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00723-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0723-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00723-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0724-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/00724-swift-typechecker-coercepatterntotype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0724-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/00724-swift-typechecker-coercepatterntotype.swift diff --git a/validation-test/compiler_crashers_fixed/0725-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00725-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0725-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00725-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0726-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/00726-swift-typechecker-resolvetypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0726-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/00726-swift-typechecker-resolvetypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0727-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/00727-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0727-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/00727-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/0728-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00728-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0728-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00728-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0729-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/00729-swift-pattern-foreachvariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0729-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/00729-swift-pattern-foreachvariable.swift diff --git a/validation-test/compiler_crashers_fixed/0730-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/00730-swift-modulefile-maybereadgenericparams.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0730-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/00730-swift-modulefile-maybereadgenericparams.swift diff --git a/validation-test/compiler_crashers_fixed/0731-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/00731-swift-typebase-isequal.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0731-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/00731-swift-typebase-isequal.swift diff --git a/validation-test/compiler_crashers_fixed/0732-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00732-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0732-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00732-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/00733-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00733-resolvetypedecl.swift new file mode 100644 index 0000000000000..d0da84b3e440c --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00733-resolvetypedecl.swift @@ -0,0 +1,12 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func compose { +b> { +protocol d where I) -> String { +class A { +} +} +deinit { +} +} +var b() -> S U>("a(b: NSManagedObject { +enum b { +} +func b(a() +func a: b diff --git a/validation-test/compiler_crashers_fixed/0761-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/00761-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0761-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/00761-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0762-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/00762-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0762-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/00762-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/0763-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00763-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0763-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00763-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0764-as.swift b/validation-test/compiler_crashers_fixed/00764-as.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0764-as.swift rename to validation-test/compiler_crashers_fixed/00764-as.swift diff --git a/validation-test/compiler_crashers_fixed/0765-swift-langoptions-gettargetconfigoption.swift b/validation-test/compiler_crashers_fixed/00765-swift-langoptions-gettargetconfigoption.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0765-swift-langoptions-gettargetconfigoption.swift rename to validation-test/compiler_crashers_fixed/00765-swift-langoptions-gettargetconfigoption.swift diff --git a/validation-test/compiler_crashers_fixed/0766-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00766-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0766-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00766-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0767-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/00767-swift-constraints-constraintsystem-solve.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0767-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/00767-swift-constraints-constraintsystem-solve.swift diff --git a/validation-test/compiler_crashers_fixed/0768-llvm-bitstreamcursor-readrecord.swift b/validation-test/compiler_crashers_fixed/00768-llvm-bitstreamcursor-readrecord.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0768-llvm-bitstreamcursor-readrecord.swift rename to validation-test/compiler_crashers_fixed/00768-llvm-bitstreamcursor-readrecord.swift diff --git a/validation-test/compiler_crashers_fixed/0769-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/00769-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0769-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/00769-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0770-swift-astvisitor.swift b/validation-test/compiler_crashers_fixed/00770-swift-astvisitor.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0770-swift-astvisitor.swift rename to validation-test/compiler_crashers_fixed/00770-swift-astvisitor.swift diff --git a/validation-test/compiler_crashers_fixed/0771-x.swift b/validation-test/compiler_crashers_fixed/00771-x.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0771-x.swift rename to validation-test/compiler_crashers_fixed/00771-x.swift diff --git a/validation-test/compiler_crashers_fixed/0772-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/00772-swift-substitutedtype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0772-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/00772-swift-substitutedtype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0773-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00773-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0773-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00773-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/00774-unowned.swift b/validation-test/compiler_crashers_fixed/00774-unowned.swift new file mode 100644 index 0000000000000..0b4b5989ae022 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00774-unowned.swift @@ -0,0 +1,16 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol A : a { +} +protocol a { +func e: b { +} +func c(() -> Any) { +} +protocol A { +} +typealias d : e: C { diff --git a/validation-test/compiler_crashers_fixed/0775-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00775-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0775-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00775-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0776-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00776-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0776-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00776-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0777-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00777-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0777-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00777-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0778-swift-dependentmembertype-get.swift b/validation-test/compiler_crashers_fixed/00778-swift-dependentmembertype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0778-swift-dependentmembertype-get.swift rename to validation-test/compiler_crashers_fixed/00778-swift-dependentmembertype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0779-swift-parser-parsetoken.swift b/validation-test/compiler_crashers_fixed/00779-swift-parser-parsetoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0779-swift-parser-parsetoken.swift rename to validation-test/compiler_crashers_fixed/00779-swift-parser-parsetoken.swift diff --git a/validation-test/compiler_crashers_fixed/00780-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00780-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..3cf4e52efd588 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00780-getselftypeforcontainer.swift @@ -0,0 +1,38 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +let h: d { +struct S : H) { +A, Any) { +} +} +init() -> { +} +let foo as String) -> [$0) +assert("cd"")() +protocol b { +protocol P { +let d() -> { +} +typealias A : a : a { +enum b = true as a") +func a) +enum A { +} +} +struct c { +} +} +case c: a { +} +let a { +protocol b = g.Element>() { c> String) +} +} +override init(() -> (A) { +} +protocol c { +func a(b diff --git a/validation-test/compiler_crashers_fixed/0781-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift b/validation-test/compiler_crashers_fixed/00781-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0781-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift rename to validation-test/compiler_crashers_fixed/00781-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/0782-d.swift b/validation-test/compiler_crashers_fixed/00782-d.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0782-d.swift rename to validation-test/compiler_crashers_fixed/00782-d.swift diff --git a/validation-test/compiler_crashers_fixed/0783-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00783-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0783-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00783-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0784-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00784-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0784-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00784-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0785-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00785-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0785-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00785-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0786-end.swift b/validation-test/compiler_crashers_fixed/00786-end.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0786-end.swift rename to validation-test/compiler_crashers_fixed/00786-end.swift diff --git a/validation-test/compiler_crashers_fixed/00787-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00787-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..20f71aa0d334f --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00787-getselftypeforcontainer.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +struct B { +} +typealias R = compose U -> { +} +let c in c == c> { +var b(n: T) -> { +} +var e> { +} +} +protocol d : b = B String { +} +protocol a = e: A { +case .h: d { +} +typealias b { +typealias A { +} +} +} +var f : SequenceType where A, U) -> Bool { +print() +} +class A { +struct c in c { +enum a") +} +protocol A : a { +func a(T diff --git a/validation-test/compiler_crashers_fixed/0792-swift-parser-parseexprarray.swift b/validation-test/compiler_crashers_fixed/00792-swift-parser-parseexprarray.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0792-swift-parser-parseexprarray.swift rename to validation-test/compiler_crashers_fixed/00792-swift-parser-parseexprarray.swift diff --git a/validation-test/compiler_crashers_fixed/0793-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00793-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0793-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00793-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0794-swift-typebase-isspecialized.swift b/validation-test/compiler_crashers_fixed/00794-swift-typebase-isspecialized.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0794-swift-typebase-isspecialized.swift rename to validation-test/compiler_crashers_fixed/00794-swift-typebase-isspecialized.swift diff --git a/validation-test/compiler_crashers_fixed/0795-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/00795-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0795-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/00795-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/0796-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00796-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0796-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00796-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0797-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00797-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0797-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00797-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0798-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/00798-swift-typechecker-coercepatterntotype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0798-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/00798-swift-typechecker-coercepatterntotype.swift diff --git a/validation-test/compiler_crashers_fixed/0799-e.swift b/validation-test/compiler_crashers_fixed/00799-e.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0799-e.swift rename to validation-test/compiler_crashers_fixed/00799-e.swift diff --git a/validation-test/compiler_crashers_fixed/0800-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/00800-swift-typebase-isequal.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0800-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/00800-swift-typebase-isequal.swift diff --git a/validation-test/compiler_crashers_fixed/0801-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/00801-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0801-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/00801-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0802-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00802-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0802-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00802-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0803-void.swift b/validation-test/compiler_crashers_fixed/00803-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0803-void.swift rename to validation-test/compiler_crashers_fixed/00803-void.swift diff --git a/validation-test/compiler_crashers_fixed/0804-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/00804-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0804-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/00804-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/0806-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/00806-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0806-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/00806-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/0807-swift-archetypebuilder-resolvearchetype.swift b/validation-test/compiler_crashers_fixed/00807-swift-archetypebuilder-resolvearchetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0807-swift-archetypebuilder-resolvearchetype.swift rename to validation-test/compiler_crashers_fixed/00807-swift-archetypebuilder-resolvearchetype.swift diff --git a/validation-test/compiler_crashers_fixed/0808-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00808-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0808-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00808-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0809-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00809-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0809-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00809-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0810-a-cd-x.swift b/validation-test/compiler_crashers_fixed/00810-a-cd-x.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0810-a-cd-x.swift rename to validation-test/compiler_crashers_fixed/00810-a-cd-x.swift diff --git a/validation-test/compiler_crashers_fixed/0811-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/00811-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0811-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/00811-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0812-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/00812-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0812-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/00812-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/0813-swift-tupleexpr-create.swift b/validation-test/compiler_crashers_fixed/00813-swift-tupleexpr-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0813-swift-tupleexpr-create.swift rename to validation-test/compiler_crashers_fixed/00813-swift-tupleexpr-create.swift diff --git a/validation-test/compiler_crashers_fixed/0814-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00814-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0814-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00814-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0815-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00815-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0815-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00815-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0816-swift-isplatformactive.swift b/validation-test/compiler_crashers_fixed/00816-swift-isplatformactive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0816-swift-isplatformactive.swift rename to validation-test/compiler_crashers_fixed/00816-swift-isplatformactive.swift diff --git a/validation-test/compiler_crashers_fixed/0818-c.swift b/validation-test/compiler_crashers_fixed/00818-c.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0818-c.swift rename to validation-test/compiler_crashers_fixed/00818-c.swift diff --git a/validation-test/compiler_crashers_fixed/0819-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/00819-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0819-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/00819-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/0820-x.swift b/validation-test/compiler_crashers_fixed/00820-x.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0820-x.swift rename to validation-test/compiler_crashers_fixed/00820-x.swift diff --git a/validation-test/compiler_crashers_fixed/00822-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00822-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..06b74ba463cc8 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00822-getselftypeforcontainer.swift @@ -0,0 +1,20 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol B : B { +c: C { +} +override init() { +struct d V { +class func g: I.c : T>() -> Int = 0) { +} +} +typealias F = D> { +} +return b diff --git a/validation-test/compiler_crashers_fixed/0891-a.swift b/validation-test/compiler_crashers_fixed/00891-a.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0891-a.swift rename to validation-test/compiler_crashers_fixed/00891-a.swift diff --git a/validation-test/compiler_crashers_fixed/0892-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/00892-swift-protocoltype-canonicalizeprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0892-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/00892-swift-protocoltype-canonicalizeprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/0893-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00893-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0893-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00893-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0894-std-function-func-swift-archetypebuilder-maptypeintocontext.swift b/validation-test/compiler_crashers_fixed/00894-std-function-func-swift-archetypebuilder-maptypeintocontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0894-std-function-func-swift-archetypebuilder-maptypeintocontext.swift rename to validation-test/compiler_crashers_fixed/00894-std-function-func-swift-archetypebuilder-maptypeintocontext.swift diff --git a/validation-test/compiler_crashers_fixed/0895-swift-tuplepattern-create.swift b/validation-test/compiler_crashers_fixed/00895-swift-tuplepattern-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0895-swift-tuplepattern-create.swift rename to validation-test/compiler_crashers_fixed/00895-swift-tuplepattern-create.swift diff --git a/validation-test/compiler_crashers_fixed/0896-void.swift b/validation-test/compiler_crashers_fixed/00896-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0896-void.swift rename to validation-test/compiler_crashers_fixed/00896-void.swift diff --git a/validation-test/compiler_crashers_fixed/0897-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/00897-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0897-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/00897-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/0898-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/00898-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0898-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/00898-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0899-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00899-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0899-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00899-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0900-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/00900-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0900-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/00900-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0901-ab.swift b/validation-test/compiler_crashers_fixed/00901-ab.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0901-ab.swift rename to validation-test/compiler_crashers_fixed/00901-ab.swift diff --git a/validation-test/compiler_crashers_fixed/00902-c.swift b/validation-test/compiler_crashers_fixed/00902-c.swift new file mode 100644 index 0000000000000..4c5a0050a6465 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00902-c.swift @@ -0,0 +1,8 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +enum S(T>(true as String +protocol A { +enum a { +} +} +extension A diff --git a/validation-test/compiler_crashers_fixed/0906-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00906-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0906-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00906-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0907-c-t.swift b/validation-test/compiler_crashers_fixed/00907-c-t.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0907-c-t.swift rename to validation-test/compiler_crashers_fixed/00907-c-t.swift diff --git a/validation-test/compiler_crashers_fixed/0908-l.swift b/validation-test/compiler_crashers_fixed/00908-l.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0908-l.swift rename to validation-test/compiler_crashers_fixed/00908-l.swift diff --git a/validation-test/compiler_crashers_fixed/0909-a.swift b/validation-test/compiler_crashers_fixed/00909-a.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0909-a.swift rename to validation-test/compiler_crashers_fixed/00909-a.swift diff --git a/validation-test/compiler_crashers_fixed/0910-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00910-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0910-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00910-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0911-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00911-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0911-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00911-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0912-a.swift b/validation-test/compiler_crashers_fixed/00912-a.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0912-a.swift rename to validation-test/compiler_crashers_fixed/00912-a.swift diff --git a/validation-test/compiler_crashers_fixed/0913-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00913-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0913-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00913-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0914-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/00914-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0914-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/00914-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0915-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00915-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0915-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00915-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0916-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/00916-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0916-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/00916-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0917-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/00917-swift-lexer-leximpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0917-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/00917-swift-lexer-leximpl.swift diff --git a/validation-test/compiler_crashers_fixed/0919-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00919-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0919-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00919-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0920-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/00920-swift-typechecker-typecheckexpression.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0920-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/00920-swift-typechecker-typecheckexpression.swift diff --git a/validation-test/compiler_crashers_fixed/0921-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00921-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0921-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00921-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0922-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/00922-swift-lexer-getlocforendoftoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0922-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/00922-swift-lexer-getlocforendoftoken.swift diff --git a/validation-test/compiler_crashers_fixed/0923-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00923-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0923-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00923-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0925-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00925-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0925-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00925-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0926-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/00926-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0926-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/00926-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/0927-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00927-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0927-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/00927-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0928-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/00928-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0928-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/00928-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0929-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/00929-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0929-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/00929-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0930-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00930-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0930-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00930-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0931-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00931-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0931-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00931-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0932-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/00932-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0932-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/00932-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0933-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00933-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0933-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00933-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0934-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00934-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0934-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00934-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0935-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/00935-swift-constraints-constraintsystem-solve.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0935-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/00935-swift-constraints-constraintsystem-solve.swift diff --git a/validation-test/compiler_crashers_fixed/0936-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00936-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0936-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00936-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0937-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00937-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0937-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00937-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0938-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/00938-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0938-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/00938-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/0939-swift-typechecker-typecheckpattern.swift b/validation-test/compiler_crashers_fixed/00939-swift-typechecker-typecheckpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0939-swift-typechecker-typecheckpattern.swift rename to validation-test/compiler_crashers_fixed/00939-swift-typechecker-typecheckpattern.swift diff --git a/validation-test/compiler_crashers_fixed/0940-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/00940-swift-typechecker-validatedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0940-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/00940-swift-typechecker-validatedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0941-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/00941-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0941-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/00941-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/0942-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00942-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0942-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00942-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0943-swift-diagnosticengine-diagnose.swift b/validation-test/compiler_crashers_fixed/00943-swift-diagnosticengine-diagnose.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0943-swift-diagnosticengine-diagnose.swift rename to validation-test/compiler_crashers_fixed/00943-swift-diagnosticengine-diagnose.swift diff --git a/validation-test/compiler_crashers_fixed/00944-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00944-std-function-func-swift-type-subst.swift new file mode 100644 index 0000000000000..c0c523db782fa --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00944-std-function-func-swift-type-subst.swift @@ -0,0 +1,18 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol P { +class func d(Any) -> { +} +protocol a { +typealias F = e: a { +} +} +typealias e where g +struct B() -> Void>(b(bytes: a { +}(T.startIndex) +super.B>) in x in 0)) +let h: a { diff --git a/validation-test/compiler_crashers_fixed/0945-swift-lexer-lexstringliteral.swift b/validation-test/compiler_crashers_fixed/00945-swift-lexer-lexstringliteral.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0945-swift-lexer-lexstringliteral.swift rename to validation-test/compiler_crashers_fixed/00945-swift-lexer-lexstringliteral.swift diff --git a/validation-test/compiler_crashers_fixed/0946-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/00946-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0946-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/00946-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0947-void.swift b/validation-test/compiler_crashers_fixed/00947-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0947-void.swift rename to validation-test/compiler_crashers_fixed/00947-void.swift diff --git a/validation-test/compiler_crashers_fixed/0948-swift-modulefile-readmembers.swift b/validation-test/compiler_crashers_fixed/00948-swift-modulefile-readmembers.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0948-swift-modulefile-readmembers.swift rename to validation-test/compiler_crashers_fixed/00948-swift-modulefile-readmembers.swift diff --git a/validation-test/compiler_crashers_fixed/00949-d.swift b/validation-test/compiler_crashers_fixed/00949-d.swift new file mode 100644 index 0000000000000..67899605c8a49 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00949-d.swift @@ -0,0 +1,27 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol a { +func a(self.C) { +switch x in x in x { +} +} +protocol c { +S) -> { +class b { +typealias A { +} +} +} +typealias A : a { +struct X ((") +} +} +func f: a { diff --git a/validation-test/compiler_crashers_fixed/0950-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00950-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0950-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00950-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0951-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00951-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0951-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00951-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0952-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/00952-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0952-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/00952-swift-constraints-constraintgraph-gatherconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/0953-swift-inflightdiagnostic-highlight.swift b/validation-test/compiler_crashers_fixed/00953-swift-inflightdiagnostic-highlight.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0953-swift-inflightdiagnostic-highlight.swift rename to validation-test/compiler_crashers_fixed/00953-swift-inflightdiagnostic-highlight.swift diff --git a/validation-test/compiler_crashers_fixed/0954-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/00954-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0954-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/00954-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/0955-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/00955-swift-genericparamlist-addnestedarchetypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0955-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/00955-swift-genericparamlist-addnestedarchetypes.swift diff --git a/validation-test/compiler_crashers_fixed/0956-swift-type-print.swift b/validation-test/compiler_crashers_fixed/00956-swift-type-print.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0956-swift-type-print.swift rename to validation-test/compiler_crashers_fixed/00956-swift-type-print.swift diff --git a/validation-test/compiler_crashers_fixed/0957-void.swift b/validation-test/compiler_crashers_fixed/00957-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0957-void.swift rename to validation-test/compiler_crashers_fixed/00957-void.swift diff --git a/validation-test/compiler_crashers_fixed/00958-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00958-swift-nominaltypedecl-getdeclaredtypeincontext.swift new file mode 100644 index 0000000000000..68e8a04c7403c --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00958-swift-nominaltypedecl-getdeclaredtypeincontext.swift @@ -0,0 +1,39 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func q() -> (dc, dc -> dc) -> dc { +t m t.w = { +} +{ +dc) { +k } +} +protocol q { +} +protocol A { +func b(b: X.s) { +} +y(m: x) { +} +func v() -> [dc] { +} +class b : v { +} +class b { +} +protocol dc { +} +class A: A { +} +class r : C { +} +func ^(v: q, o) -> o { +} +class v { +} +protocol b { +} +struct dc : b diff --git a/validation-test/compiler_crashers_fixed/0959-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/00959-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0959-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/00959-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0960-swift-funcdecl-setdeserializedsignature.swift b/validation-test/compiler_crashers_fixed/00960-swift-funcdecl-setdeserializedsignature.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0960-swift-funcdecl-setdeserializedsignature.swift rename to validation-test/compiler_crashers_fixed/00960-swift-funcdecl-setdeserializedsignature.swift diff --git a/validation-test/compiler_crashers_fixed/0961-bool.swift b/validation-test/compiler_crashers_fixed/00961-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0961-bool.swift rename to validation-test/compiler_crashers_fixed/00961-bool.swift diff --git a/validation-test/compiler_crashers_fixed/0962-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/00962-swift-protocoltype-canonicalizeprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0962-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/00962-swift-protocoltype-canonicalizeprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/0963-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/00963-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0963-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/00963-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0964-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00964-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0964-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00964-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0965-swift-availabilityattr-isunavailable.swift b/validation-test/compiler_crashers_fixed/00965-swift-availabilityattr-isunavailable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0965-swift-availabilityattr-isunavailable.swift rename to validation-test/compiler_crashers_fixed/00965-swift-availabilityattr-isunavailable.swift diff --git a/validation-test/compiler_crashers_fixed/0966-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/00966-swift-astprinter-printtextimpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0966-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/00966-swift-astprinter-printtextimpl.swift diff --git a/validation-test/compiler_crashers_fixed/0967-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00967-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0967-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00967-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0968-swift-typebase-isexistentialtype.swift b/validation-test/compiler_crashers_fixed/00968-swift-typebase-isexistentialtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0968-swift-typebase-isexistentialtype.swift rename to validation-test/compiler_crashers_fixed/00968-swift-typebase-isexistentialtype.swift diff --git a/validation-test/compiler_crashers_fixed/0969-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/00969-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0969-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/00969-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0970-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/00970-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0970-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/00970-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0971-swift-parser-parsebraceitems.swift b/validation-test/compiler_crashers_fixed/00971-swift-parser-parsebraceitems.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0971-swift-parser-parsebraceitems.swift rename to validation-test/compiler_crashers_fixed/00971-swift-parser-parsebraceitems.swift diff --git a/validation-test/compiler_crashers_fixed/0972-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00972-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0972-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00972-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/00973-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/00973-std-function-func-swift-type-subst.swift new file mode 100644 index 0000000000000..dd30288d72923 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/00973-std-function-func-swift-type-subst.swift @@ -0,0 +1,14 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol d : c { +protocol a { +return { +return { c(") +typealias R = e: B, g.d diff --git a/validation-test/compiler_crashers_fixed/0974-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00974-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0974-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00974-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0975-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/00975-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0975-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/00975-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/0976-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/00976-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0976-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/00976-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/0977-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/00977-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0977-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/00977-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/0978-llvm-foldingset-swift-structtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/00978-llvm-foldingset-swift-structtype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0978-llvm-foldingset-swift-structtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/00978-llvm-foldingset-swift-structtype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/0979-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/00979-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0979-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/00979-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/0980-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/00980-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0980-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/00980-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/0981-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/00981-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0981-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/00981-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0982-b.swift b/validation-test/compiler_crashers_fixed/00982-b.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0982-b.swift rename to validation-test/compiler_crashers_fixed/00982-b.swift diff --git a/validation-test/compiler_crashers_fixed/0983-a.swift b/validation-test/compiler_crashers_fixed/00983-a.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0983-a.swift rename to validation-test/compiler_crashers_fixed/00983-a.swift diff --git a/validation-test/compiler_crashers_fixed/0984-swift-constraints-constraintsystem-simplifyconstraint.swift b/validation-test/compiler_crashers_fixed/00984-swift-constraints-constraintsystem-simplifyconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0984-swift-constraints-constraintsystem-simplifyconstraint.swift rename to validation-test/compiler_crashers_fixed/00984-swift-constraints-constraintsystem-simplifyconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/0985-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/00985-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0985-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/00985-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/0986-swift-unboundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/00986-swift-unboundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0986-swift-unboundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/00986-swift-unboundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0987-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/00987-swift-typechecker-validatedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0987-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/00987-swift-typechecker-validatedecl.swift diff --git a/validation-test/compiler_crashers_fixed/0988-swift-typechecker-typecheckdecl.swift b/validation-test/compiler_crashers_fixed/00988-swift-typechecker-typecheckdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0988-swift-typechecker-typecheckdecl.swift rename to validation-test/compiler_crashers_fixed/00988-swift-typechecker-typecheckdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0989-swift-typechecker-computecaptures.swift b/validation-test/compiler_crashers_fixed/00989-swift-typechecker-computecaptures.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0989-swift-typechecker-computecaptures.swift rename to validation-test/compiler_crashers_fixed/00989-swift-typechecker-computecaptures.swift diff --git a/validation-test/compiler_crashers_fixed/0990-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/00990-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0990-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/00990-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0991-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/00991-swift-typebase-isequal.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0991-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/00991-swift-typebase-isequal.swift diff --git a/validation-test/compiler_crashers_fixed/0992-swift-typebase-gettypevariables.swift b/validation-test/compiler_crashers_fixed/00992-swift-typebase-gettypevariables.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0992-swift-typebase-gettypevariables.swift rename to validation-test/compiler_crashers_fixed/00992-swift-typebase-gettypevariables.swift diff --git a/validation-test/compiler_crashers_fixed/0993-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/00993-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0993-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/00993-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/0994-swift-typealiasdecl.swift b/validation-test/compiler_crashers_fixed/00994-swift-typealiasdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0994-swift-typealiasdecl.swift rename to validation-test/compiler_crashers_fixed/00994-swift-typealiasdecl.swift diff --git a/validation-test/compiler_crashers_fixed/0995-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/00995-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0995-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/00995-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/0996-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/00996-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0996-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/00996-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/0997-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/00997-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0997-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/00997-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/0998-bool.swift b/validation-test/compiler_crashers_fixed/00998-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0998-bool.swift rename to validation-test/compiler_crashers_fixed/00998-bool.swift diff --git a/validation-test/compiler_crashers_fixed/0999-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/00999-swift-parser-skipsingle.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/0999-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/00999-swift-parser-skipsingle.swift diff --git a/validation-test/compiler_crashers_fixed/1000-swift-parser-parsetypeidentifier.swift b/validation-test/compiler_crashers_fixed/01000-swift-parser-parsetypeidentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1000-swift-parser-parsetypeidentifier.swift rename to validation-test/compiler_crashers_fixed/01000-swift-parser-parsetypeidentifier.swift diff --git a/validation-test/compiler_crashers_fixed/1001-swift-parser-parsedeclimport.swift b/validation-test/compiler_crashers_fixed/01001-swift-parser-parsedeclimport.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1001-swift-parser-parsedeclimport.swift rename to validation-test/compiler_crashers_fixed/01001-swift-parser-parsedeclimport.swift diff --git a/validation-test/compiler_crashers_fixed/1002-swift-parentype-get.swift b/validation-test/compiler_crashers_fixed/01002-swift-parentype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1002-swift-parentype-get.swift rename to validation-test/compiler_crashers_fixed/01002-swift-parentype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1003-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01003-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1003-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01003-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1004-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/01004-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1004-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/01004-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/1005-swift-nominaltype-get.swift b/validation-test/compiler_crashers_fixed/01005-swift-nominaltype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1005-swift-nominaltype-get.swift rename to validation-test/compiler_crashers_fixed/01005-swift-nominaltype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1006-swift-modulefile-resolvecrossreference.swift b/validation-test/compiler_crashers_fixed/01006-swift-modulefile-resolvecrossreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1006-swift-modulefile-resolvecrossreference.swift rename to validation-test/compiler_crashers_fixed/01006-swift-modulefile-resolvecrossreference.swift diff --git a/validation-test/compiler_crashers_fixed/1007-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/01007-swift-modulefile-maybereadpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1007-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/01007-swift-modulefile-maybereadpattern.swift diff --git a/validation-test/compiler_crashers_fixed/1008-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/01008-swift-modulefile-maybereadgenericparams.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1008-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/01008-swift-modulefile-maybereadgenericparams.swift diff --git a/validation-test/compiler_crashers_fixed/1009-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01009-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1009-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01009-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1010-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/01010-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1010-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/01010-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/1011-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01011-swift-modulefile-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1011-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/01011-swift-modulefile-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/1012-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01012-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1012-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01012-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1013-swift-module-lookupconformance.swift b/validation-test/compiler_crashers_fixed/01013-swift-module-lookupconformance.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1013-swift-module-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/01013-swift-module-lookupconformance.swift diff --git a/validation-test/compiler_crashers_fixed/1014-swift-inouttype-get.swift b/validation-test/compiler_crashers_fixed/01014-swift-inouttype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1014-swift-inouttype-get.swift rename to validation-test/compiler_crashers_fixed/01014-swift-inouttype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1015-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/01015-swift-inflightdiagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1015-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/01015-swift-inflightdiagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/1016-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/01016-swift-genericsignature-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1016-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/01016-swift-genericsignature-get.swift diff --git a/validation-test/compiler_crashers_fixed/1017-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift b/validation-test/compiler_crashers_fixed/01017-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1017-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift rename to validation-test/compiler_crashers_fixed/01017-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/1018-diagnoseunknowntype.swift b/validation-test/compiler_crashers_fixed/01018-diagnoseunknowntype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1018-diagnoseunknowntype.swift rename to validation-test/compiler_crashers_fixed/01018-diagnoseunknowntype.swift diff --git a/validation-test/compiler_crashers_fixed/1019-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01019-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1019-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01019-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1020-swift-lexer-lexoperatoridentifier.swift b/validation-test/compiler_crashers_fixed/01020-swift-lexer-lexoperatoridentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1020-swift-lexer-lexoperatoridentifier.swift rename to validation-test/compiler_crashers_fixed/01020-swift-lexer-lexoperatoridentifier.swift diff --git a/validation-test/compiler_crashers_fixed/1021-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01021-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1021-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01021-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1022-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/01022-swift-genericsignature-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1022-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/01022-swift-genericsignature-get.swift diff --git a/validation-test/compiler_crashers_fixed/1023-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01023-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1023-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01023-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/1024-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01024-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1024-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01024-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1025-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01025-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1025-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01025-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1026-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01026-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1026-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01026-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1027-llvm-foldingset-swift-genericsignature-nodeequals.swift b/validation-test/compiler_crashers_fixed/01027-llvm-foldingset-swift-genericsignature-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1027-llvm-foldingset-swift-genericsignature-nodeequals.swift rename to validation-test/compiler_crashers_fixed/01027-llvm-foldingset-swift-genericsignature-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/1028-swift-camel-case-getfirstword.swift b/validation-test/compiler_crashers_fixed/01028-swift-camel-case-getfirstword.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1028-swift-camel-case-getfirstword.swift rename to validation-test/compiler_crashers_fixed/01028-swift-camel-case-getfirstword.swift diff --git a/validation-test/compiler_crashers_fixed/1029-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/01029-swift-modulefile-maybereadgenericparams.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1029-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/01029-swift-modulefile-maybereadgenericparams.swift diff --git a/validation-test/compiler_crashers_fixed/1030-swift-declname-printpretty.swift b/validation-test/compiler_crashers_fixed/01030-swift-declname-printpretty.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1030-swift-declname-printpretty.swift rename to validation-test/compiler_crashers_fixed/01030-swift-declname-printpretty.swift diff --git a/validation-test/compiler_crashers_fixed/01031-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01031-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..8d87b66b346f9 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01031-getselftypeforcontainer.swift @@ -0,0 +1,22 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol b : C { +} +let start = b, let t.c { +typealias d>(n: b { +protocol C = 0] = """\())] = c: e? = T) -> A { +} +protocol A : a { +} +protocol a { +func e: b { +} +func c(() -> Any) { +} +protocol A { +} +typealias d : e: C { diff --git a/validation-test/compiler_crashers_fixed/1032-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/01032-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1032-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/01032-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/1033-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01033-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1033-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01033-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1034-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01034-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1034-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01034-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/01035-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/01035-swift-completegenerictyperesolver-resolvedependentmembertype.swift new file mode 100644 index 0000000000000..d7e549e969f52 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01035-swift-completegenerictyperesolver-resolvedependentmembertype.swift @@ -0,0 +1,16 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +struct Q T : NSManagedObject { +class a { +deinit { +struct c = { _, g == a!): +} +protocol a { +typealias F>() { +} +func b: T.e(start: diff --git a/validation-test/compiler_crashers_fixed/1036-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01036-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1036-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01036-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1037-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/01037-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1037-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/01037-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/1038-swift-constraints-constraintsystem-simplifyconstraint.swift b/validation-test/compiler_crashers_fixed/01038-swift-constraints-constraintsystem-simplifyconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1038-swift-constraints-constraintsystem-simplifyconstraint.swift rename to validation-test/compiler_crashers_fixed/01038-swift-constraints-constraintsystem-simplifyconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1039-swift-typechecker-conformstoprotocol.swift b/validation-test/compiler_crashers_fixed/01039-swift-typechecker-conformstoprotocol.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1039-swift-typechecker-conformstoprotocol.swift rename to validation-test/compiler_crashers_fixed/01039-swift-typechecker-conformstoprotocol.swift diff --git a/validation-test/compiler_crashers_fixed/1040-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/01040-swift-constraints-constraintsystem-simplifytype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1040-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/01040-swift-constraints-constraintsystem-simplifytype.swift diff --git a/validation-test/compiler_crashers_fixed/1041-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01041-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1041-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01041-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1042-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01042-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1042-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01042-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1043-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift b/validation-test/compiler_crashers_fixed/01043-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1043-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift rename to validation-test/compiler_crashers_fixed/01043-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1044-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01044-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1044-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01044-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1045-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01045-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1045-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01045-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1046-swift-constraints-constraintsystem-simplify.swift b/validation-test/compiler_crashers_fixed/01046-swift-constraints-constraintsystem-simplify.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1046-swift-constraints-constraintsystem-simplify.swift rename to validation-test/compiler_crashers_fixed/01046-swift-constraints-constraintsystem-simplify.swift diff --git a/validation-test/compiler_crashers_fixed/1047-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/01047-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1047-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/01047-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/1048-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01048-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1048-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01048-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1049-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/01049-swift-constraints-solution-solution.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1049-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/01049-swift-constraints-solution-solution.swift diff --git a/validation-test/compiler_crashers_fixed/1050-swift-generictypeparamdecl-generictypeparamdecl.swift b/validation-test/compiler_crashers_fixed/01050-swift-generictypeparamdecl-generictypeparamdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1050-swift-generictypeparamdecl-generictypeparamdecl.swift rename to validation-test/compiler_crashers_fixed/01050-swift-generictypeparamdecl-generictypeparamdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1051-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01051-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1051-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01051-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1052-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/01052-swift-genericsignature-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1052-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/01052-swift-genericsignature-get.swift diff --git a/validation-test/compiler_crashers_fixed/1053-swift-inouttype-get.swift b/validation-test/compiler_crashers_fixed/01053-swift-inouttype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1053-swift-inouttype-get.swift rename to validation-test/compiler_crashers_fixed/01053-swift-inouttype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1054-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01054-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1054-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01054-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1055-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/01055-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1055-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/01055-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1056-swift-typechecker-conformstoprotocol.swift b/validation-test/compiler_crashers_fixed/01056-swift-typechecker-conformstoprotocol.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1056-swift-typechecker-conformstoprotocol.swift rename to validation-test/compiler_crashers_fixed/01056-swift-typechecker-conformstoprotocol.swift diff --git a/validation-test/compiler_crashers_fixed/1057-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01057-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1057-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01057-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1058-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01058-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1058-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01058-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1059-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/01059-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1059-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/01059-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/1060-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01060-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1060-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01060-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/01061-swift-typebase-gettypeofmember.swift b/validation-test/compiler_crashers_fixed/01061-swift-typebase-gettypeofmember.swift new file mode 100644 index 0000000000000..756d7ab7d5a6c --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01061-swift-typebase-gettypeofmember.swift @@ -0,0 +1,13 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol A : l.c { +typealias d>(Any) { +return """"".B) +} +extension A { +protocol d == true } +enum a: T, A { diff --git a/validation-test/compiler_crashers_fixed/1062-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/01062-swift-typechecker-resolvetypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1062-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/01062-swift-typechecker-resolvetypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1063-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/01063-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1063-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/01063-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/1064-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/01064-swift-genericsignature-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1064-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/01064-swift-genericsignature-get.swift diff --git a/validation-test/compiler_crashers_fixed/1065-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/01065-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1065-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/01065-swift-constraints-constraintsystem-assignfixedtype.swift diff --git a/validation-test/compiler_crashers_fixed/01066-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01066-swift-typebase-getcanonicaltype.swift new file mode 100644 index 0000000000000..eea1e72d08d4f --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01066-swift-typebase-getcanonicaltype.swift @@ -0,0 +1,30 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol b { +struct e = e> () { +class C) { +} +} +class A { +func x(seq: Int = Swift.Generator.d(b { +} +typealias d>(() -> String { +func c, """ +protocol A { +}) +protocol a { +} +typealias e : d = F>) +} +} +var e(b diff --git a/validation-test/compiler_crashers_fixed/1067-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01067-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1067-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01067-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1068-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01068-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1068-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01068-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1069-swift-nominaltypedecl-getprotocols.swift b/validation-test/compiler_crashers_fixed/01069-swift-nominaltypedecl-getprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1069-swift-nominaltypedecl-getprotocols.swift rename to validation-test/compiler_crashers_fixed/01069-swift-nominaltypedecl-getprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/1070-void.swift b/validation-test/compiler_crashers_fixed/01070-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1070-void.swift rename to validation-test/compiler_crashers_fixed/01070-void.swift diff --git a/validation-test/compiler_crashers_fixed/1071-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01071-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1071-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01071-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1072-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01072-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1072-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01072-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1073-swift-constraints-constraintgraphnode-addconstraint.swift b/validation-test/compiler_crashers_fixed/01073-swift-constraints-constraintgraphnode-addconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1073-swift-constraints-constraintgraphnode-addconstraint.swift rename to validation-test/compiler_crashers_fixed/01073-swift-constraints-constraintgraphnode-addconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1074-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/01074-swift-lexer-getlocforendoftoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1074-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/01074-swift-lexer-getlocforendoftoken.swift diff --git a/validation-test/compiler_crashers_fixed/1075-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01075-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1075-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01075-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1076-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/01076-swift-lexer-getlocforendoftoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1076-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/01076-swift-lexer-getlocforendoftoken.swift diff --git a/validation-test/compiler_crashers_fixed/1077-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01077-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1077-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01077-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1078-void.swift b/validation-test/compiler_crashers_fixed/01078-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1078-void.swift rename to validation-test/compiler_crashers_fixed/01078-void.swift diff --git a/validation-test/compiler_crashers_fixed/1079-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/01079-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1079-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/01079-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/1080-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/01080-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1080-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/01080-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/1081-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01081-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1081-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01081-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1082-llvm-foldingsetnodeid-operator.swift b/validation-test/compiler_crashers_fixed/01082-llvm-foldingsetnodeid-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1082-llvm-foldingsetnodeid-operator.swift rename to validation-test/compiler_crashers_fixed/01082-llvm-foldingsetnodeid-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1083-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/01083-swift-typechecker-typecheckexpression.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1083-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/01083-swift-typechecker-typecheckexpression.swift diff --git a/validation-test/compiler_crashers_fixed/1084-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01084-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1084-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01084-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/01085-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01085-swift-declcontext-lookupqualified.swift new file mode 100644 index 0000000000000..dda8468900b51 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01085-swift-declcontext-lookupqualified.swift @@ -0,0 +1,31 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +struct B { +func f() -> (g, g -> g) -> g { +d j d.i = { +} +{ +g) { +h } +} +protocol f { +} +class d: f{ class func i {} +struct d { +} +} +protocol a { +typeal= D>(e: A.B) { +} +} +} +override func d() -> String { +func} +func b((Any, c))(Any, AnyObject +func g(f: B) { +} +struct c == S.Generator.Element> diff --git a/validation-test/compiler_crashers_fixed/1086-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/01086-swift-parser-parseexprpostfix.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1086-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/01086-swift-parser-parseexprpostfix.swift diff --git a/validation-test/compiler_crashers_fixed/1087-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01087-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1087-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01087-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1088-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01088-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1088-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01088-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1089-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/01089-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1089-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/01089-llvm-foldingset-swift-tupletype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/1090-swift-parser-parsebraceitems.swift b/validation-test/compiler_crashers_fixed/01090-swift-parser-parsebraceitems.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1090-swift-parser-parsebraceitems.swift rename to validation-test/compiler_crashers_fixed/01090-swift-parser-parsebraceitems.swift diff --git a/validation-test/compiler_crashers_fixed/1091-getcallerdefaultarg.swift b/validation-test/compiler_crashers_fixed/01091-getcallerdefaultarg.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1091-getcallerdefaultarg.swift rename to validation-test/compiler_crashers_fixed/01091-getcallerdefaultarg.swift diff --git a/validation-test/compiler_crashers_fixed/1092-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01092-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1092-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01092-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1093-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01093-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1093-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01093-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1094-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01094-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1094-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01094-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1095-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01095-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1095-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01095-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1096-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/01096-swift-typechecker-validatedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1096-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/01096-swift-typechecker-validatedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1097-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/01097-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1097-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/01097-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/1098-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/01098-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1098-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/01098-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/1099-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01099-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1099-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01099-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1100-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01100-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1100-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01100-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1101-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/01101-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1101-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/01101-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/01102-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01102-resolvetypedecl.swift new file mode 100644 index 0000000000000..f3f8399ca7569 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01102-resolvetypedecl.swift @@ -0,0 +1,32 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func c() -> (e -> e) -> e { +e, e -> e) ->)func d(f: b) -> (() -> e) -> b { +struct c { +var b: [c] { +} +protocol a { +} +class b: a { +} +func f(b: T) { +} +func e() { +} +} +protocol c : b { func b +otocol A { +} +struct } +} +class a { +} +protocol b { +typealias d +typealias e = a, d> +} +struct c { +let enum S : P { +func f() -> T -> T { +return { x in x 1 { +} +} +class A { +class func a() -> String { +let d: String = { +}() +} +} +s} +} +class d : e { +} +class d { +} +protocol i { +} +protocol e { +} +protocol i : d { func d diff --git a/validation-test/compiler_crashers_fixed/1169-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/01169-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1169-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/01169-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/01170-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01170-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..b8a0185b76856 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01170-getselftypeforcontainer.swift @@ -0,0 +1,59 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class k: d { +var f: g +init(f: g) { +l. d { +typealias j = je: Int -> Int = { +} +let d: Int = { c, b in +}(f, e) +} +class d { +func l(l: j) { +} +func i(k: b) -> (() -> j) -> b { +} +class j { +func y((Any, j))(v: (Any, AnyObject)) { +} +} +func w(j: () -> ()) { +} +class v { +l _ = w() { +} +} +func v() -> (x, x -> x) -> x { +l y j s { +} +o l { +} +y q { +} +o n { +} +class r { +func s() -> p { +} +} +class w: r, n { +} +func b : e { +} +class d { +} +protocol i { +} +protocol e { +} +protocol i : d { func d diff --git a/validation-test/compiler_crashers_fixed/1171-swift-parentype-get.swift b/validation-test/compiler_crashers_fixed/01171-swift-parentype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1171-swift-parentype-get.swift rename to validation-test/compiler_crashers_fixed/01171-swift-parentype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1172-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01172-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1172-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01172-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1173-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/01173-swift-completegenerictyperesolver-resolvedependentmembertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1173-swift-completegenerictyperesolver-resolvedependentmembertype.swift rename to validation-test/compiler_crashers_fixed/01173-swift-completegenerictyperesolver-resolvedependentmembertype.swift diff --git a/validation-test/compiler_crashers_fixed/1174-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01174-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1174-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01174-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1175-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/01175-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1175-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/01175-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/1176-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/01176-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1176-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/01176-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/1177-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01177-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1177-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/01177-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/1178-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01178-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1178-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01178-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1179-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01179-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1179-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01179-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1180-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/01180-swift-nominaltypedecl-preparelookuptable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1180-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/01180-swift-nominaltypedecl-preparelookuptable.swift diff --git a/validation-test/compiler_crashers_fixed/1181-swift-unqualifiedlookup-unqualifiedlookup.swift b/validation-test/compiler_crashers_fixed/01181-swift-unqualifiedlookup-unqualifiedlookup.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1181-swift-unqualifiedlookup-unqualifiedlookup.swift rename to validation-test/compiler_crashers_fixed/01181-swift-unqualifiedlookup-unqualifiedlookup.swift diff --git a/validation-test/compiler_crashers_fixed/1182-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01182-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1182-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01182-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1183-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01183-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1183-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01183-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1184-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/01184-swift-lexer-lexidentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1184-swift-lexer-lexidentifier.swift rename to validation-test/compiler_crashers_fixed/01184-swift-lexer-lexidentifier.swift diff --git a/validation-test/compiler_crashers_fixed/01185-swift-parser-parsetypeidentifier.swift b/validation-test/compiler_crashers_fixed/01185-swift-parser-parsetypeidentifier.swift new file mode 100644 index 0000000000000..54f4be8330f75 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01185-swift-parser-parsetypeidentifier.swift @@ -0,0 +1,93 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func b : r { +func j(j: j.n) { +} +} +enum q { let k: v +} +protocol y { +} +struct D : y { +func y { +} +} +func l(m: (l, c) -> c) -> (l, c) -> c { +f { i +}, k) +class l { +class func m { +b let k: String = { +}() +struct q { +} +o q: n = { m, i j +l { +k m p { +} +struct j { +} +func a() -> [j] { +} +func f() -> (l, l -> l) -> l { +l j l.n = { +} +{ +l) { +n } +} +protocol f { +} +class l: f{ class func n {} +func a() { +b b { +} +} +class a { +} +protocol b { +} +struct j : b { +} +enum e : d { +func c() -> b { +} +} +protocol d { +} +enum A : String { +} +if c == .b { +} +struct c { +var b: [c] { +g []e f() { +} +} +protocol c : b { func b +class j { +func y((Any, j))(v: (Any, AnyObject)) { +} diff --git a/validation-test/compiler_crashers_fixed/1186-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01186-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1186-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01186-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1187-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01187-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1187-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01187-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1188-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/01188-swift-genericfunctiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1188-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/01188-swift-genericfunctiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1189-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/01189-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1189-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/01189-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1190-swift-completegenerictyperesolver-resolvegenerictypeparamtype.swift b/validation-test/compiler_crashers_fixed/01190-swift-completegenerictyperesolver-resolvegenerictypeparamtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1190-swift-completegenerictyperesolver-resolvegenerictypeparamtype.swift rename to validation-test/compiler_crashers_fixed/01190-swift-completegenerictyperesolver-resolvegenerictypeparamtype.swift diff --git a/validation-test/compiler_crashers_fixed/1191-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01191-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1191-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01191-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1192-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01192-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1192-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01192-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1193-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/01193-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1193-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/01193-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/1194-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01194-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1194-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01194-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1195-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01195-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1195-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01195-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1196-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01196-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1196-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01196-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1197-swift-typechecker-validatetype.swift b/validation-test/compiler_crashers_fixed/01197-swift-typechecker-validatetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1197-swift-typechecker-validatetype.swift rename to validation-test/compiler_crashers_fixed/01197-swift-typechecker-validatetype.swift diff --git a/validation-test/compiler_crashers_fixed/01198-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01198-resolvetypedecl.swift new file mode 100644 index 0000000000000..15158e0a15dbf --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01198-resolvetypedecl.swift @@ -0,0 +1,66 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func a(x: Any, y: Any) -> (((Any, Any) -> Any) -> Any) { +return { +} +struct X : A { +func b(b: X.Type) { +} +} +class d: NSObject { +init(b: c) { +} +} +protocol a { +} +class b : a { +} +class b { +} +protocol c { +} +protocol a : a { +} +class A : A { +} +class B : C { +} +class c { +func b((Any, c))(a: (Any, AnyObject)) { +} +} +protocol b { +} +struct c { +func e() { +} +} +func d == b.Generat(() -> d) { +} +protocol A { +} +class B { +func d() -> String { +} +} +class C: B, A { +override func d() -> String { +} +func c() -> String { +} +} +func e(t: T) { +} +enum S : P { +func f() -> T -> T { +} +} +protocol P { +} +func a(b: Int = 0) { +} +struct c ()) +func p(l: Any, g: Any) -> (((Any, Any) -> Any) -> Any) { +return { +(p: (Any, Any) -> Any) -> Any in +func n { +} +protocol e { +} +func f BooleanType>(b: T) { +} +f( func b(b: X.Type) { +} +class d : e { +} +class d { +} +protocol i { +} +protocol e { +} +protocol i : d diff --git a/validation-test/compiler_crashers_fixed/1264-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01264-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1264-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01264-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1265-getcallerdefaultarg.swift b/validation-test/compiler_crashers_fixed/01265-getcallerdefaultarg.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1265-getcallerdefaultarg.swift rename to validation-test/compiler_crashers_fixed/01265-getcallerdefaultarg.swift diff --git a/validation-test/compiler_crashers_fixed/1266-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01266-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1266-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01266-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1267-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/01267-swift-protocoltype-canonicalizeprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1267-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/01267-swift-protocoltype-canonicalizeprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/01268-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/01268-swift-lexer-lexidentifier.swift new file mode 100644 index 0000000000000..a465402f59f79 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01268-swift-lexer-lexidentifier.swift @@ -0,0 +1,15 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol k { +typealias m +} +struct e {n: j +let i: j.m +} +func g() -> (f, f -> f) -> f { +g e {} +struct g Any) -> Any)) -> Any { +return z({ +(p: Any, q:Any) -> Any in +nType, Bool) -> Bool { +} +protocol A { +} +class C { +init (e: A.B) { +} +} +struct d { +} +protocol e { +} +func b(c) -> (() -> d) { +} +protocol A { +} +struct X : A { +func b(b: X.Type) { +} +} +protocol a { +} +class b : a { +} +struct c { diff --git a/validation-test/compiler_crashers_fixed/1275-swift-diagnosticengine-diagnose.swift b/validation-test/compiler_crashers_fixed/01275-swift-diagnosticengine-diagnose.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1275-swift-diagnosticengine-diagnose.swift rename to validation-test/compiler_crashers_fixed/01275-swift-diagnosticengine-diagnose.swift diff --git a/validation-test/compiler_crashers_fixed/1276-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01276-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1276-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01276-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/01277-diagnoseunknowntype.swift b/validation-test/compiler_crashers_fixed/01277-diagnoseunknowntype.swift new file mode 100644 index 0000000000000..16e0c97602c39 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01277-diagnoseunknowntype.swift @@ -0,0 +1,16 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func f() -> (g, g -> g) -> g { +d j d.i = { +} +{ +g) { +h } +} +protocol f { +} +struct d diff --git a/validation-test/compiler_crashers_fixed/1278-swift-modulefile-maybereadconformance.swift b/validation-test/compiler_crashers_fixed/01278-swift-modulefile-maybereadconformance.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1278-swift-modulefile-maybereadconformance.swift rename to validation-test/compiler_crashers_fixed/01278-swift-modulefile-maybereadconformance.swift diff --git a/validation-test/compiler_crashers_fixed/1279-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01279-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1279-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01279-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1280-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01280-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1280-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01280-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1281-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/01281-swift-lexer-leximpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1281-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/01281-swift-lexer-leximpl.swift diff --git a/validation-test/compiler_crashers_fixed/1282-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01282-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1282-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01282-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1283-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01283-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1283-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01283-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1284-swift-parser-parseidentifier.swift b/validation-test/compiler_crashers_fixed/01284-swift-parser-parseidentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1284-swift-parser-parseidentifier.swift rename to validation-test/compiler_crashers_fixed/01284-swift-parser-parseidentifier.swift diff --git a/validation-test/compiler_crashers_fixed/1285-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01285-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1285-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01285-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1286-swift-parser-parseexpridentifier.swift b/validation-test/compiler_crashers_fixed/01286-swift-parser-parseexpridentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1286-swift-parser-parseexpridentifier.swift rename to validation-test/compiler_crashers_fixed/01286-swift-parser-parseexpridentifier.swift diff --git a/validation-test/compiler_crashers_fixed/1287-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/01287-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1287-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/01287-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/1288-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01288-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1288-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01288-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1289-void.swift b/validation-test/compiler_crashers_fixed/01289-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1289-void.swift rename to validation-test/compiler_crashers_fixed/01289-void.swift diff --git a/validation-test/compiler_crashers_fixed/1290-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/01290-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1290-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/01290-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/01291-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01291-swift-type-walk.swift new file mode 100644 index 0000000000000..e8373fb5dc162 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01291-swift-type-walk.swift @@ -0,0 +1,70 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func f() -> (e, e -> e) -> e { +{ +{ +} +} +protocol f { +} +class e: f { +class funT>: NSObject { +init(foo: T) { +B>(t: T) { +} x +x) { +} +class a { +var _ = i() { +} +} +func i(c: () -> ()) { +} +class a { +var _ = i() { +} +} +} +class d : e { +} +class d { +} +protocol i { +} +} +func n() { +b b { +} +} +func n(j: Any, t: Any) -> (((Any, Any) -> Any) -> Any) { +k { +} +} +var d = b +protocol a { +} +protocol b : a { +} +protocol c : a { +} +protocol d { +} +struct e : d { +} +func i (n: k) { +} +func i (n: l) { +} +protocol b { +} +struct c { +func e() { +} +} +struct c { +} +func b(g: f) -> (()-> e) -> i diff --git a/validation-test/compiler_crashers_fixed/1292-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01292-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1292-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01292-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1293-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01293-swift-modulefile-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1293-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/01293-swift-modulefile-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/1294-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01294-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1294-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01294-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1295-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01295-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1295-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01295-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/01296-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01296-resolvetypedecl.swift new file mode 100644 index 0000000000000..6b2824be71595 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01296-resolvetypedecl.swift @@ -0,0 +1,38 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func f() -> (l, l -> l) -> l { +l j l.n = { +} +{ +l) { +n } +} +protocol f { +} +class l: f{ class func n {} +func a() { +b b { +} +} +class a { +} +protocol b { +} +struct j : b { +} +typealias +d = i +} +class d : e { +} +class d { +} +protocol i { +} +protocol e { +} +protocol i : d { diff --git a/validation-test/compiler_crashers_fixed/1297-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01297-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1297-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01297-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1298-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01298-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1298-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01298-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/01299-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01299-resolvetypedecl.swift new file mode 100644 index 0000000000000..1f06d89aaba51 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01299-resolvetypedecl.swift @@ -0,0 +1,24 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class a { +} +class i: d{ class func f {} +func c() -> (i, i -> i) -> i { +k b k.i = { +} +{ +i) { +k } +} +protocol c { +} +class k: c{ class func i { +} +}lass func c() +} +var x1 = 1 +=1 as a=1 diff --git a/validation-test/compiler_crashers_fixed/1300-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01300-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1300-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01300-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1301-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01301-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1301-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01301-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1302-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01302-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1302-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01302-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1303-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01303-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1303-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01303-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1304-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01304-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1304-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01304-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1305-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01305-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1305-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01305-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1306-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/01306-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1306-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/01306-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/01307-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01307-swift-clangmoduleunit-getimportedmodules.swift new file mode 100644 index 0000000000000..b73b92305bf15 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01307-swift-clangmoduleunit-getimportedmodules.swift @@ -0,0 +1,23 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +import Foundation +func n() -> (w, w -> w) -> w { +o m o.q = { +} +{ +w) { +k } +} +protocol n { +} +class o: n{ class func q {} +func p(e: Int = x) { +} +let c = p +protocol p : p { +} +protocol p { diff --git a/validation-test/compiler_crashers_fixed/1308-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01308-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1308-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/01308-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/1309-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01309-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1309-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01309-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1310-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01310-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1310-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01310-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1311-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/01311-swift-completegenerictyperesolver-resolvedependentmembertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1311-swift-completegenerictyperesolver-resolvedependentmembertype.swift rename to validation-test/compiler_crashers_fixed/01311-swift-completegenerictyperesolver-resolvedependentmembertype.swift diff --git a/validation-test/compiler_crashers_fixed/1312-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01312-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1312-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01312-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1313-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01313-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1313-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01313-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1314-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01314-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1314-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01314-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1315-swift-parser-parsebraceitems.swift b/validation-test/compiler_crashers_fixed/01315-swift-parser-parsebraceitems.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1315-swift-parser-parsebraceitems.swift rename to validation-test/compiler_crashers_fixed/01315-swift-parser-parsebraceitems.swift diff --git a/validation-test/compiler_crashers_fixed/1316-swift-typechecker-validatetype.swift b/validation-test/compiler_crashers_fixed/01316-swift-typechecker-validatetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1316-swift-typechecker-validatetype.swift rename to validation-test/compiler_crashers_fixed/01316-swift-typechecker-validatetype.swift diff --git a/validation-test/compiler_crashers_fixed/1317-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/01317-swift-modulefile-maybereadgenericparams.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1317-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/01317-swift-modulefile-maybereadgenericparams.swift diff --git a/validation-test/compiler_crashers_fixed/1318-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/01318-swift-constraints-constraintgraph-addconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1318-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/01318-swift-constraints-constraintgraph-addconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1319-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/01319-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1319-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/01319-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/01320-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01320-resolvetypedecl.swift new file mode 100644 index 0000000000000..468535c5a40c0 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01320-resolvetypedecl.swift @@ -0,0 +1,9 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +struct c T +func g Any))" +typealias A : d { +struct d.init() -> Any, e> S) { +} +protocol c { +struct c(x: a { +} +self)() { +} +} +typealias f = A> (Any) { +} +} +} +protocol b { +struct A { +} +func b: C { +func f: (") +typealias f : b.E == diff --git a/validation-test/compiler_crashers_fixed/1369-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01369-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1369-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01369-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1370-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01370-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1370-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01370-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1371-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/01371-swift-constraints-constraintsystem-simplifytype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1371-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/01371-swift-constraints-constraintsystem-simplifytype.swift diff --git a/validation-test/compiler_crashers_fixed/1372-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/01372-swift-boundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1372-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/01372-swift-boundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1373-swift-valuedecl-getinterfacetype.swift b/validation-test/compiler_crashers_fixed/01373-swift-valuedecl-getinterfacetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1373-swift-valuedecl-getinterfacetype.swift rename to validation-test/compiler_crashers_fixed/01373-swift-valuedecl-getinterfacetype.swift diff --git a/validation-test/compiler_crashers_fixed/1374-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01374-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1374-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01374-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1375-clang-declvisitor-base-clang-declvisitor-make-const-ptr.swift b/validation-test/compiler_crashers_fixed/01375-clang-declvisitor-base-clang-declvisitor-make-const-ptr.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1375-clang-declvisitor-base-clang-declvisitor-make-const-ptr.swift rename to validation-test/compiler_crashers_fixed/01375-clang-declvisitor-base-clang-declvisitor-make-const-ptr.swift diff --git a/validation-test/compiler_crashers_fixed/1376-swift-parser-parsetoken.swift b/validation-test/compiler_crashers_fixed/01376-swift-parser-parsetoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1376-swift-parser-parsetoken.swift rename to validation-test/compiler_crashers_fixed/01376-swift-parser-parsetoken.swift diff --git a/validation-test/compiler_crashers_fixed/1377-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/01377-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1377-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/01377-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/1378-swift-typechecker-typecheckpattern.swift b/validation-test/compiler_crashers_fixed/01378-swift-typechecker-typecheckpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1378-swift-typechecker-typecheckpattern.swift rename to validation-test/compiler_crashers_fixed/01378-swift-typechecker-typecheckpattern.swift diff --git a/validation-test/compiler_crashers_fixed/1379-swift-parser-parsedeclinit.swift b/validation-test/compiler_crashers_fixed/01379-swift-parser-parsedeclinit.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1379-swift-parser-parsedeclinit.swift rename to validation-test/compiler_crashers_fixed/01379-swift-parser-parsedeclinit.swift diff --git a/validation-test/compiler_crashers_fixed/1380-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01380-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1380-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01380-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1381-bool.swift b/validation-test/compiler_crashers_fixed/01381-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1381-bool.swift rename to validation-test/compiler_crashers_fixed/01381-bool.swift diff --git a/validation-test/compiler_crashers_fixed/1382-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01382-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1382-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01382-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/1383-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01383-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1383-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/01383-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/1384-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01384-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1384-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01384-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1385-swift-typedecl-getdeclaredtype.swift b/validation-test/compiler_crashers_fixed/01385-swift-typedecl-getdeclaredtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1385-swift-typedecl-getdeclaredtype.swift rename to validation-test/compiler_crashers_fixed/01385-swift-typedecl-getdeclaredtype.swift diff --git a/validation-test/compiler_crashers_fixed/1386-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/01386-swift-substitutedtype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1386-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/01386-swift-substitutedtype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1387-swift-astcontext-setconformsto.swift b/validation-test/compiler_crashers_fixed/01387-swift-astcontext-setconformsto.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1387-swift-astcontext-setconformsto.swift rename to validation-test/compiler_crashers_fixed/01387-swift-astcontext-setconformsto.swift diff --git a/validation-test/compiler_crashers_fixed/1388-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01388-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1388-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01388-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1389-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01389-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1389-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01389-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1390-swift-typebase-gettypevariables.swift b/validation-test/compiler_crashers_fixed/01390-swift-typebase-gettypevariables.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1390-swift-typebase-gettypevariables.swift rename to validation-test/compiler_crashers_fixed/01390-swift-typebase-gettypevariables.swift diff --git a/validation-test/compiler_crashers_fixed/1391-swift-typechecker-callwitness.swift b/validation-test/compiler_crashers_fixed/01391-swift-typechecker-callwitness.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1391-swift-typechecker-callwitness.swift rename to validation-test/compiler_crashers_fixed/01391-swift-typechecker-callwitness.swift diff --git a/validation-test/compiler_crashers_fixed/1392-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01392-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1392-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01392-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1393-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/01393-swift-genericfunctiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1393-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/01393-swift-genericfunctiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1394-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/01394-swift-typechecker-typecheckexpression.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1394-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/01394-swift-typechecker-typecheckexpression.swift diff --git a/validation-test/compiler_crashers_fixed/1395-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/01395-swift-parser-skipsingle.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1395-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/01395-swift-parser-skipsingle.swift diff --git a/validation-test/compiler_crashers_fixed/1396-swift-availabilityattr-isunavailable.swift b/validation-test/compiler_crashers_fixed/01396-swift-availabilityattr-isunavailable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1396-swift-availabilityattr-isunavailable.swift rename to validation-test/compiler_crashers_fixed/01396-swift-availabilityattr-isunavailable.swift diff --git a/validation-test/compiler_crashers_fixed/1397-swift-availabilityattr-isunavailable.swift b/validation-test/compiler_crashers_fixed/01397-swift-availabilityattr-isunavailable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1397-swift-availabilityattr-isunavailable.swift rename to validation-test/compiler_crashers_fixed/01397-swift-availabilityattr-isunavailable.swift diff --git a/validation-test/compiler_crashers_fixed/1398-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01398-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1398-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01398-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1399-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01399-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1399-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01399-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1400-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/01400-swift-inflightdiagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1400-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/01400-swift-inflightdiagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/1401-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/01401-swift-typebase-getdesugaredtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1401-swift-typebase-getdesugaredtype.swift rename to validation-test/compiler_crashers_fixed/01401-swift-typebase-getdesugaredtype.swift diff --git a/validation-test/compiler_crashers_fixed/1402-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/01402-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1402-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/01402-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/1403-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01403-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1403-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01403-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1404-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/01404-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1404-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/01404-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1405-swift-clangimporter-implementation-finishloadingclangmodule.swift b/validation-test/compiler_crashers_fixed/01405-swift-clangimporter-implementation-finishloadingclangmodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1405-swift-clangimporter-implementation-finishloadingclangmodule.swift rename to validation-test/compiler_crashers_fixed/01405-swift-clangimporter-implementation-finishloadingclangmodule.swift diff --git a/validation-test/compiler_crashers_fixed/1406-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/01406-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1406-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/01406-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/1407-swift-declname-printpretty.swift b/validation-test/compiler_crashers_fixed/01407-swift-declname-printpretty.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1407-swift-declname-printpretty.swift rename to validation-test/compiler_crashers_fixed/01407-swift-declname-printpretty.swift diff --git a/validation-test/compiler_crashers_fixed/1408-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01408-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1408-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01408-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1409-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01409-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1409-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01409-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1410-swift-constraints-constraintsystem-lookupmember.swift b/validation-test/compiler_crashers_fixed/01410-swift-constraints-constraintsystem-lookupmember.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1410-swift-constraints-constraintsystem-lookupmember.swift rename to validation-test/compiler_crashers_fixed/01410-swift-constraints-constraintsystem-lookupmember.swift diff --git a/validation-test/compiler_crashers_fixed/1411-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01411-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1411-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01411-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1412-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/01412-swift-constraints-constraintlocator-profile.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1412-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/01412-swift-constraints-constraintlocator-profile.swift diff --git a/validation-test/compiler_crashers_fixed/01413-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/01413-std-function-func-swift-constraints-constraintsystem-simplifytype.swift new file mode 100644 index 0000000000000..11a89e1d9c549 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01413-std-function-func-swift-constraints-constraintsystem-simplifytype.swift @@ -0,0 +1,17 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class A { +func c) -> Self { +} +} +} +} +var b: b { +let start = c: Se diff --git a/validation-test/compiler_crashers_fixed/1414-swift-genericparamlist-create.swift b/validation-test/compiler_crashers_fixed/01414-swift-genericparamlist-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1414-swift-genericparamlist-create.swift rename to validation-test/compiler_crashers_fixed/01414-swift-genericparamlist-create.swift diff --git a/validation-test/compiler_crashers_fixed/1415-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/01415-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1415-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/01415-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/1416-swift-constraints-constraintgraphscope-constraintgraphscope.swift b/validation-test/compiler_crashers_fixed/01416-swift-constraints-constraintgraphscope-constraintgraphscope.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1416-swift-constraints-constraintgraphscope-constraintgraphscope.swift rename to validation-test/compiler_crashers_fixed/01416-swift-constraints-constraintgraphscope-constraintgraphscope.swift diff --git a/validation-test/compiler_crashers_fixed/1417-swift-extensiondecl-create.swift b/validation-test/compiler_crashers_fixed/01417-swift-extensiondecl-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1417-swift-extensiondecl-create.swift rename to validation-test/compiler_crashers_fixed/01417-swift-extensiondecl-create.swift diff --git a/validation-test/compiler_crashers_fixed/1418-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01418-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1418-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01418-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1419-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/01419-swift-modulefile-maybereadgenericparams.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1419-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/01419-swift-modulefile-maybereadgenericparams.swift diff --git a/validation-test/compiler_crashers_fixed/0142-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/0142-swift-nominaltypedecl-preparelookuptable.swift deleted file mode 100644 index 0b00ea9dfa083..0000000000000 --- a/validation-test/compiler_crashers_fixed/0142-swift-nominaltypedecl-preparelookuptable.swift +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -) -func n() -> (w, w -> w) -> w { - o m o.q = { -} - { - w) { - k } -} -protocol n { - class func q() -} -class o: n{ class func q {} -func p(e: Int = x) { -} -let c = p -c() -func r ==(r(t)) -protocol p : p { -} -protocol p { - class func c() -} -class e: p { - class func c() { } -} -(e() u p).v.c() -k e.w == l> { -} -func p(c: Any, m: Any) -> (((Any, Any) -> Any) -> Any) { diff --git a/validation-test/compiler_crashers_fixed/1420-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/01420-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1420-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/01420-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/1421-void.swift b/validation-test/compiler_crashers_fixed/01421-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1421-void.swift rename to validation-test/compiler_crashers_fixed/01421-void.swift diff --git a/validation-test/compiler_crashers_fixed/1422-swift-parser-parsestmtreturn.swift b/validation-test/compiler_crashers_fixed/01422-swift-parser-parsestmtreturn.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1422-swift-parser-parsestmtreturn.swift rename to validation-test/compiler_crashers_fixed/01422-swift-parser-parsestmtreturn.swift diff --git a/validation-test/compiler_crashers_fixed/1423-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/01423-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1423-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/01423-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/01424-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01424-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..b025ca96e733d --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01424-getselftypeforcontainer.swift @@ -0,0 +1,19 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +let x { +protocol a { +func f Any) { +} +protocol A { +typealias B : b(v: d.h == [[]]() -> String { +return "[Byte]) +func b: C = " +} +} +class B, T) -> { +} +var b, range: a { diff --git a/validation-test/compiler_crashers_fixed/1425-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01425-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1425-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01425-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/1426-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/01426-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1426-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/01426-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/1427-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01427-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1427-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01427-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1428-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01428-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1428-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01428-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1429-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01429-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1429-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01429-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1430-swift-expr-getsourcerange.swift b/validation-test/compiler_crashers_fixed/01430-swift-expr-getsourcerange.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1430-swift-expr-getsourcerange.swift rename to validation-test/compiler_crashers_fixed/01430-swift-expr-getsourcerange.swift diff --git a/validation-test/compiler_crashers_fixed/1431-swift-unboundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/01431-swift-unboundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1431-swift-unboundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/01431-swift-unboundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1432-swift-bracestmt-create.swift b/validation-test/compiler_crashers_fixed/01432-swift-bracestmt-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1432-swift-bracestmt-create.swift rename to validation-test/compiler_crashers_fixed/01432-swift-bracestmt-create.swift diff --git a/validation-test/compiler_crashers_fixed/1433-swift-constraints-solution-simplifytype.swift b/validation-test/compiler_crashers_fixed/01433-swift-constraints-solution-simplifytype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1433-swift-constraints-solution-simplifytype.swift rename to validation-test/compiler_crashers_fixed/01433-swift-constraints-solution-simplifytype.swift diff --git a/validation-test/compiler_crashers_fixed/1434-std-function-func-swift-typebase-gettypevariables.swift b/validation-test/compiler_crashers_fixed/01434-std-function-func-swift-typebase-gettypevariables.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1434-std-function-func-swift-typebase-gettypevariables.swift rename to validation-test/compiler_crashers_fixed/01434-std-function-func-swift-typebase-gettypevariables.swift diff --git a/validation-test/compiler_crashers_fixed/1435-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/01435-swift-genericparamlist-addnestedarchetypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1435-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/01435-swift-genericparamlist-addnestedarchetypes.swift diff --git a/validation-test/compiler_crashers_fixed/1436-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01436-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1436-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01436-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1437-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/01437-swift-astprinter-printtextimpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1437-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/01437-swift-astprinter-printtextimpl.swift diff --git a/validation-test/compiler_crashers_fixed/1438-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/01438-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1438-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/01438-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/1439-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/01439-swift-boundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1439-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/01439-swift-boundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1440-swift-parser-parsetoken.swift b/validation-test/compiler_crashers_fixed/01440-swift-parser-parsetoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1440-swift-parser-parsetoken.swift rename to validation-test/compiler_crashers_fixed/01440-swift-parser-parsetoken.swift diff --git a/validation-test/compiler_crashers_fixed/1441-swift-constraints-constraintgraph-removeconstraint.swift b/validation-test/compiler_crashers_fixed/01441-swift-constraints-constraintgraph-removeconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1441-swift-constraints-constraintgraph-removeconstraint.swift rename to validation-test/compiler_crashers_fixed/01441-swift-constraints-constraintgraph-removeconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1442-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/01442-swift-genericfunctiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1442-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/01442-swift-genericfunctiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1443-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/01443-swift-lexer-leximpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1443-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/01443-swift-lexer-leximpl.swift diff --git a/validation-test/compiler_crashers_fixed/1444-getcallerdefaultarg.swift b/validation-test/compiler_crashers_fixed/01444-getcallerdefaultarg.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1444-getcallerdefaultarg.swift rename to validation-test/compiler_crashers_fixed/01444-getcallerdefaultarg.swift diff --git a/validation-test/compiler_crashers_fixed/1445-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01445-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1445-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01445-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1446-swift-genericparamlist-deriveallarchetypes.swift b/validation-test/compiler_crashers_fixed/01446-swift-genericparamlist-deriveallarchetypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1446-swift-genericparamlist-deriveallarchetypes.swift rename to validation-test/compiler_crashers_fixed/01446-swift-genericparamlist-deriveallarchetypes.swift diff --git a/validation-test/compiler_crashers_fixed/1447-swift-parentype-get.swift b/validation-test/compiler_crashers_fixed/01447-swift-parentype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1447-swift-parentype-get.swift rename to validation-test/compiler_crashers_fixed/01447-swift-parentype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1448-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01448-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1448-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01448-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1449-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01449-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1449-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01449-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1450-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/01450-swift-modulefile-maybereadgenericparams.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1450-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/01450-swift-modulefile-maybereadgenericparams.swift diff --git a/validation-test/compiler_crashers_fixed/1451-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01451-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1451-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01451-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1452-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01452-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1452-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01452-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1453-swift-constraints-constraintgraph-change-undo.swift b/validation-test/compiler_crashers_fixed/01453-swift-constraints-constraintgraph-change-undo.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1453-swift-constraints-constraintgraph-change-undo.swift rename to validation-test/compiler_crashers_fixed/01453-swift-constraints-constraintgraph-change-undo.swift diff --git a/validation-test/compiler_crashers_fixed/1454-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/01454-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1454-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/01454-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/1455-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/01455-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1455-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/01455-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/1456-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01456-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1456-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01456-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1457-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01457-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1457-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01457-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1458-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/01458-swift-modulefile-maybereadpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1458-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/01458-swift-modulefile-maybereadpattern.swift diff --git a/validation-test/compiler_crashers_fixed/1459-swift-abstractstoragedecl-makecomputed.swift b/validation-test/compiler_crashers_fixed/01459-swift-abstractstoragedecl-makecomputed.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1459-swift-abstractstoragedecl-makecomputed.swift rename to validation-test/compiler_crashers_fixed/01459-swift-abstractstoragedecl-makecomputed.swift diff --git a/validation-test/compiler_crashers_fixed/1460-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01460-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1460-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01460-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1461-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01461-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1461-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01461-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1462-swift-archetypebuilder-resolvearchetype.swift b/validation-test/compiler_crashers_fixed/01462-swift-archetypebuilder-resolvearchetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1462-swift-archetypebuilder-resolvearchetype.swift rename to validation-test/compiler_crashers_fixed/01462-swift-archetypebuilder-resolvearchetype.swift diff --git a/validation-test/compiler_crashers_fixed/1463-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01463-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1463-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01463-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1464-llvm-bitstreamcursor-readabbreviatedfield.swift b/validation-test/compiler_crashers_fixed/01464-llvm-bitstreamcursor-readabbreviatedfield.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1464-llvm-bitstreamcursor-readabbreviatedfield.swift rename to validation-test/compiler_crashers_fixed/01464-llvm-bitstreamcursor-readabbreviatedfield.swift diff --git a/validation-test/compiler_crashers_fixed/1465-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/01465-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1465-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/01465-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/1466-swift-archetypetype-setnestedtypes.swift b/validation-test/compiler_crashers_fixed/01466-swift-archetypetype-setnestedtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1466-swift-archetypetype-setnestedtypes.swift rename to validation-test/compiler_crashers_fixed/01466-swift-archetypetype-setnestedtypes.swift diff --git a/validation-test/compiler_crashers_fixed/1467-swift-inouttype-get.swift b/validation-test/compiler_crashers_fixed/01467-swift-inouttype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1467-swift-inouttype-get.swift rename to validation-test/compiler_crashers_fixed/01467-swift-inouttype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1468-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01468-swift-modulefile-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1468-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/01468-swift-modulefile-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/1469-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01469-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1469-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01469-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1470-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01470-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1470-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01470-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1471-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01471-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1471-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/01471-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/1472-swift-modulefile-configurestorage.swift b/validation-test/compiler_crashers_fixed/01472-swift-modulefile-configurestorage.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1472-swift-modulefile-configurestorage.swift rename to validation-test/compiler_crashers_fixed/01472-swift-modulefile-configurestorage.swift diff --git a/validation-test/compiler_crashers_fixed/1473-swift-typebase-gettypevariables.swift b/validation-test/compiler_crashers_fixed/01473-swift-typebase-gettypevariables.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1473-swift-typebase-gettypevariables.swift rename to validation-test/compiler_crashers_fixed/01473-swift-typebase-gettypevariables.swift diff --git a/validation-test/compiler_crashers_fixed/1474-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/01474-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1474-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/01474-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1475-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/01475-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1475-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/01475-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1476-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/01476-swift-lexer-getlocforendoftoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1476-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/01476-swift-lexer-getlocforendoftoken.swift diff --git a/validation-test/compiler_crashers_fixed/1477-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01477-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1477-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01477-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1478-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/01478-swift-boundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1478-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/01478-swift-boundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1479-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01479-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1479-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01479-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1480-swift-typebase-getcanonicaltype-edited.swift b/validation-test/compiler_crashers_fixed/01480-swift-typebase-getcanonicaltype-edited.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1480-swift-typebase-getcanonicaltype-edited.swift rename to validation-test/compiler_crashers_fixed/01480-swift-typebase-getcanonicaltype-edited.swift diff --git a/validation-test/compiler_crashers_fixed/1480-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01480-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1480-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01480-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1481-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01481-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1481-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01481-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1482-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01482-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1482-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01482-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1483-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01483-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1483-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01483-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1484-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/01484-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1484-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/01484-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/1485-swift-constraints-constraintsystem-addconstraint.swift b/validation-test/compiler_crashers_fixed/01485-swift-constraints-constraintsystem-addconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1485-swift-constraints-constraintsystem-addconstraint.swift rename to validation-test/compiler_crashers_fixed/01485-swift-constraints-constraintsystem-addconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/01487-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01487-std-function-func-swift-type-subst.swift new file mode 100644 index 0000000000000..0f00d99430616 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01487-std-function-func-swift-type-subst.swift @@ -0,0 +1,26 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func b: a { +protocol C { +func a: A(T +override func f(") +typealias B { +} +deinit { +typealias B { +} +} +b: c> { +} +} +protocol A { +struct A { +} +let t: B) diff --git a/validation-test/compiler_crashers_fixed/1488-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/01488-swift-lexer-leximpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1488-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/01488-swift-lexer-leximpl.swift diff --git a/validation-test/compiler_crashers_fixed/1489-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/01489-swift-lexer-lexidentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1489-swift-lexer-lexidentifier.swift rename to validation-test/compiler_crashers_fixed/01489-swift-lexer-lexidentifier.swift diff --git a/validation-test/compiler_crashers_fixed/1490-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01490-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1490-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01490-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1491-llvm-raw-ostream-write.swift b/validation-test/compiler_crashers_fixed/01491-llvm-raw-ostream-write.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1491-llvm-raw-ostream-write.swift rename to validation-test/compiler_crashers_fixed/01491-llvm-raw-ostream-write.swift diff --git a/validation-test/compiler_crashers_fixed/1492-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/01492-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1492-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/01492-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/1493-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/01493-swift-constraints-constraintlocator-profile.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1493-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/01493-swift-constraints-constraintlocator-profile.swift diff --git a/validation-test/compiler_crashers_fixed/1495-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/01495-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1495-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/01495-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1496-swift-nominaltypedecl-getprotocols.swift b/validation-test/compiler_crashers_fixed/01496-swift-nominaltypedecl-getprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1496-swift-nominaltypedecl-getprotocols.swift rename to validation-test/compiler_crashers_fixed/01496-swift-nominaltypedecl-getprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/1497-swift-bracestmt-create.swift b/validation-test/compiler_crashers_fixed/01497-swift-bracestmt-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1497-swift-bracestmt-create.swift rename to validation-test/compiler_crashers_fixed/01497-swift-bracestmt-create.swift diff --git a/validation-test/compiler_crashers_fixed/1498-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01498-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1498-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01498-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1499-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/01499-swift-typechecker-coercepatterntotype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1499-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/01499-swift-typechecker-coercepatterntotype.swift diff --git a/validation-test/compiler_crashers_fixed/1501-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/01501-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1501-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/01501-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/1502-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/01502-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1502-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/01502-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/1503-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/01503-swift-constraints-constraintlocator-profile.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1503-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/01503-swift-constraints-constraintlocator-profile.swift diff --git a/validation-test/compiler_crashers_fixed/1504-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/01504-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1504-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/01504-llvm-foldingset-swift-tupletype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/1505-swift-constraints-constraintsystem-simplifymemberconstraint.swift b/validation-test/compiler_crashers_fixed/01505-swift-constraints-constraintsystem-simplifymemberconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1505-swift-constraints-constraintsystem-simplifymemberconstraint.swift rename to validation-test/compiler_crashers_fixed/01505-swift-constraints-constraintsystem-simplifymemberconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1506-swift-typechecker-validategenericfuncsignature.swift b/validation-test/compiler_crashers_fixed/01506-swift-typechecker-validategenericfuncsignature.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1506-swift-typechecker-validategenericfuncsignature.swift rename to validation-test/compiler_crashers_fixed/01506-swift-typechecker-validategenericfuncsignature.swift diff --git a/validation-test/compiler_crashers_fixed/1507-swift-constraints-matchcallarguments.swift b/validation-test/compiler_crashers_fixed/01507-swift-constraints-matchcallarguments.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1507-swift-constraints-matchcallarguments.swift rename to validation-test/compiler_crashers_fixed/01507-swift-constraints-matchcallarguments.swift diff --git a/validation-test/compiler_crashers_fixed/1508-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01508-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1508-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01508-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1509-bool-edited.swift b/validation-test/compiler_crashers_fixed/01509-bool-edited.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1509-bool-edited.swift rename to validation-test/compiler_crashers_fixed/01509-bool-edited.swift diff --git a/validation-test/compiler_crashers_fixed/1509-bool.swift b/validation-test/compiler_crashers_fixed/01509-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1509-bool.swift rename to validation-test/compiler_crashers_fixed/01509-bool.swift diff --git a/validation-test/compiler_crashers_fixed/1510-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01510-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1510-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01510-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1512-swift-optional-swift-infixoperatordecl.swift b/validation-test/compiler_crashers_fixed/01512-swift-optional-swift-infixoperatordecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1512-swift-optional-swift-infixoperatordecl.swift rename to validation-test/compiler_crashers_fixed/01512-swift-optional-swift-infixoperatordecl.swift diff --git a/validation-test/compiler_crashers_fixed/1513-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01513-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1513-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01513-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1514-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/01514-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1514-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/01514-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1515-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01515-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1515-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01515-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1516-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01516-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1516-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01516-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1517-swift-declname-printpretty.swift b/validation-test/compiler_crashers_fixed/01517-swift-declname-printpretty.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1517-swift-declname-printpretty.swift rename to validation-test/compiler_crashers_fixed/01517-swift-declname-printpretty.swift diff --git a/validation-test/compiler_crashers_fixed/1518-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/01518-swift-typebase-getdesugaredtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1518-swift-typebase-getdesugaredtype.swift rename to validation-test/compiler_crashers_fixed/01518-swift-typebase-getdesugaredtype.swift diff --git a/validation-test/compiler_crashers_fixed/1519-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01519-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1519-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01519-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/0152-swift-parser-parsetypeidentifier.swift b/validation-test/compiler_crashers_fixed/0152-swift-parser-parsetypeidentifier.swift deleted file mode 100644 index 548e34e127295..0000000000000 --- a/validation-test/compiler_crashers_fixed/0152-swift-parser-parsetypeidentifier.swift +++ /dev/null @@ -1,105 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol kj : gf { func gf -class t { -} -protocol qp { - r on - r t = on - r lk = on -} -class gf : qp { -} -class gf { -} -protocol kj { - r vu -} -ed vu = sr -ed ts: o -> o = { - fe $gf -} -l on: o = { (kj: o, lk: o -> o) -> o po - fe lk(kj) -}(vu, ts) -l qp: o = { kj, lk po - fe lk(kj) -}(vu, ts) -class qp { -} -protocol gf { - r on - r t -} -struct kj : gf { - r on = kj - r t = qp, on> -} -func qp(kj: v, ji: v) -> (((v, v) -> v) -> v) { - fe { - (ut: (v, v) -> v) -> v po - fe ut(kj, ji) - } -} -func gf(p: (((v, v) -> v) -> v)) -> v { - fe p({ - (ut: v, fe:v) -> v po - fe ut - }) -} -gf(qp(sr, qp(s, w))) -protocol t { - r n - func gf(n) -} -struct cb : t { - on k on.t = { -} - { - vu) { - kj } -} -protocol lk { - class func t() -} -class on: lk{ class func t {} -protocol qp { - class func kj() -} -class gf: qp { - class func kj() { } -} -(gf() x qp).ji.gf vu.kj == lk.kj> { -} -protocol t { - r kj -} -func lk() { - ({}) -} -protocol t { - r n -} -class lk { - rq (t: t.n) { - nm gf = gf -} -protocol t { - r k -} -struct n { - l kj: u - l t: u.k -} -protocol lk { - r ml - func >) -} -struct dc : lk { - r ml = o - func vu< u.k == ml>(lk: n) diff --git a/validation-test/compiler_crashers_fixed/1520-llvm-bitstreamcursor-readrecord.swift b/validation-test/compiler_crashers_fixed/01520-llvm-bitstreamcursor-readrecord.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1520-llvm-bitstreamcursor-readrecord.swift rename to validation-test/compiler_crashers_fixed/01520-llvm-bitstreamcursor-readrecord.swift diff --git a/validation-test/compiler_crashers_fixed/1521-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01521-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1521-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01521-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1522-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01522-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1522-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01522-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1523-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01523-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1523-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01523-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/01524-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01524-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..1edcc356bff64 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01524-getselftypeforcontainer.swift @@ -0,0 +1,12 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func a() -> { +protocol c { +enum a +protocol a { +class func b() +typealias f : b diff --git a/validation-test/compiler_crashers_fixed/1525-swift-astvisitor.swift b/validation-test/compiler_crashers_fixed/01525-swift-astvisitor.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1525-swift-astvisitor.swift rename to validation-test/compiler_crashers_fixed/01525-swift-astvisitor.swift diff --git a/validation-test/compiler_crashers_fixed/1526-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01526-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1526-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01526-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/01527-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01527-resolvetypedecl.swift new file mode 100644 index 0000000000000..2662a902d0304 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01527-resolvetypedecl.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +private class a +} +func b(t: C { diff --git a/validation-test/compiler_crashers_fixed/1528-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01528-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1528-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01528-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1530-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01530-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1530-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01530-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1531-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01531-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1531-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01531-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1532-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01532-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1532-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01532-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1533-vtable.swift b/validation-test/compiler_crashers_fixed/01533-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1533-vtable.swift rename to validation-test/compiler_crashers_fixed/01533-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/1534-bool.swift b/validation-test/compiler_crashers_fixed/01534-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1534-bool.swift rename to validation-test/compiler_crashers_fixed/01534-bool.swift diff --git a/validation-test/compiler_crashers_fixed/1535-swift-constraints-constraintgraph-removeconstraint.swift b/validation-test/compiler_crashers_fixed/01535-swift-constraints-constraintgraph-removeconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1535-swift-constraints-constraintgraph-removeconstraint.swift rename to validation-test/compiler_crashers_fixed/01535-swift-constraints-constraintgraph-removeconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1536-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01536-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1536-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01536-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1537-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01537-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1537-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01537-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1538-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01538-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1538-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01538-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1539-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01539-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1539-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01539-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1540-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/01540-swift-constraints-solution-solution.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1540-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/01540-swift-constraints-solution-solution.swift diff --git a/validation-test/compiler_crashers_fixed/1541-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01541-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1541-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01541-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1542-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01542-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1542-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01542-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1543-bool.swift b/validation-test/compiler_crashers_fixed/01543-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1543-bool.swift rename to validation-test/compiler_crashers_fixed/01543-bool.swift diff --git a/validation-test/compiler_crashers_fixed/1544-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/01544-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1544-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/01544-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/1545-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/01545-swift-streamprinter-printtext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1545-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/01545-swift-streamprinter-printtext.swift diff --git a/validation-test/compiler_crashers_fixed/1546-vtable.swift b/validation-test/compiler_crashers_fixed/01546-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1546-vtable.swift rename to validation-test/compiler_crashers_fixed/01546-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/1547-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01547-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1547-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01547-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1548-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/01548-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1548-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/01548-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/1549-llvm-foldingset-swift-declname-compounddeclname-nodeequals.swift b/validation-test/compiler_crashers_fixed/01549-llvm-foldingset-swift-declname-compounddeclname-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1549-llvm-foldingset-swift-declname-compounddeclname-nodeequals.swift rename to validation-test/compiler_crashers_fixed/01549-llvm-foldingset-swift-declname-compounddeclname-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/1550-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/01550-swift-genericfunctiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1550-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/01550-swift-genericfunctiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1551-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01551-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1551-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01551-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1552-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/01552-swift-constraints-solution-solution.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1552-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/01552-swift-constraints-solution-solution.swift diff --git a/validation-test/compiler_crashers_fixed/1553-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01553-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1553-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01553-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1554-swift-typealiasdecl-typealiasdecl.swift b/validation-test/compiler_crashers_fixed/01554-swift-typealiasdecl-typealiasdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1554-swift-typealiasdecl-typealiasdecl.swift rename to validation-test/compiler_crashers_fixed/01554-swift-typealiasdecl-typealiasdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1555-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/01555-swift-constraints-constraintsystem-simplifytype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1555-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/01555-swift-constraints-constraintsystem-simplifytype.swift diff --git a/validation-test/compiler_crashers_fixed/1556-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01556-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1556-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01556-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1557-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01557-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1557-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01557-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1558-swift-parser-parseexprunary.swift b/validation-test/compiler_crashers_fixed/01558-swift-parser-parseexprunary.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1558-swift-parser-parseexprunary.swift rename to validation-test/compiler_crashers_fixed/01558-swift-parser-parseexprunary.swift diff --git a/validation-test/compiler_crashers_fixed/1559-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01559-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1559-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01559-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1560-vtable.swift b/validation-test/compiler_crashers_fixed/01560-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1560-vtable.swift rename to validation-test/compiler_crashers_fixed/01560-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/1561-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/01561-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1561-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/01561-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/1562-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01562-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1562-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01562-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1563-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01563-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1563-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01563-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1564-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01564-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1564-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01564-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/1565-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01565-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1565-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/01565-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/1566-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01566-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1566-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01566-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1567-swift-tuplepattern-createsimple.swift b/validation-test/compiler_crashers_fixed/01567-swift-tuplepattern-createsimple.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1567-swift-tuplepattern-createsimple.swift rename to validation-test/compiler_crashers_fixed/01567-swift-tuplepattern-createsimple.swift diff --git a/validation-test/compiler_crashers_fixed/1568-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01568-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1568-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01568-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1569-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/01569-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1569-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/01569-swift-printingdiagnosticconsumer-handlediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/1570-llvm-foldingsetnodeid-operator.swift b/validation-test/compiler_crashers_fixed/01570-llvm-foldingsetnodeid-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1570-llvm-foldingsetnodeid-operator.swift rename to validation-test/compiler_crashers_fixed/01570-llvm-foldingsetnodeid-operator.swift diff --git a/validation-test/compiler_crashers_fixed/01571-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01571-swift-type-walk.swift new file mode 100644 index 0000000000000..7f152dcd031bb --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01571-swift-type-walk.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class B diff --git a/validation-test/compiler_crashers_fixed/1572-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/01572-swift-constraints-solution-solution.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1572-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/01572-swift-constraints-solution-solution.swift diff --git a/validation-test/compiler_crashers_fixed/1573-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01573-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1573-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01573-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1574-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01574-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1574-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01574-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1575-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01575-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1575-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01575-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1576-swift-generictypeparamdecl-generictypeparamdecl.swift b/validation-test/compiler_crashers_fixed/01576-swift-generictypeparamdecl-generictypeparamdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1576-swift-generictypeparamdecl-generictypeparamdecl.swift rename to validation-test/compiler_crashers_fixed/01576-swift-generictypeparamdecl-generictypeparamdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1577-getcallerdefaultarg.swift b/validation-test/compiler_crashers_fixed/01577-getcallerdefaultarg.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1577-getcallerdefaultarg.swift rename to validation-test/compiler_crashers_fixed/01577-getcallerdefaultarg.swift diff --git a/validation-test/compiler_crashers_fixed/1578-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01578-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1578-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01578-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1579-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01579-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1579-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01579-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1580-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01580-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1580-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01580-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1581-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/01581-swift-pattern-foreachvariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1581-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/01581-swift-pattern-foreachvariable.swift diff --git a/validation-test/compiler_crashers_fixed/1582-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/01582-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1582-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/01582-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/1583-llvm-prettystacktraceentry-prettystacktraceentry.swift b/validation-test/compiler_crashers_fixed/01583-llvm-prettystacktraceentry-prettystacktraceentry.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1583-llvm-prettystacktraceentry-prettystacktraceentry.swift rename to validation-test/compiler_crashers_fixed/01583-llvm-prettystacktraceentry-prettystacktraceentry.swift diff --git a/validation-test/compiler_crashers_fixed/1584-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01584-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1584-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01584-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/1585-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01585-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1585-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01585-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1586-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/01586-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1586-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/01586-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/01587-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01587-swift-nominaltypedecl-getdeclaredtypeincontext.swift new file mode 100644 index 0000000000000..6668903621dce --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01587-swift-nominaltypedecl-getdeclaredtypeincontext.swift @@ -0,0 +1,12 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class B(AnyObject> U -> : P> { +return ") +class func a { +} +func a: B : CollectionType where g(c : (" +protocol A { +protocol d : C diff --git a/validation-test/compiler_crashers_fixed/1645-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/01645-swift-typebase-getdesugaredtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1645-swift-typebase-getdesugaredtype.swift rename to validation-test/compiler_crashers_fixed/01645-swift-typebase-getdesugaredtype.swift diff --git a/validation-test/compiler_crashers_fixed/1646-super-inside-an-autoclosure.swift b/validation-test/compiler_crashers_fixed/01646-super-inside-an-autoclosure.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1646-super-inside-an-autoclosure.swift rename to validation-test/compiler_crashers_fixed/01646-super-inside-an-autoclosure.swift diff --git a/validation-test/compiler_crashers_fixed/1647-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/01647-no-stacktrace.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1647-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/01647-no-stacktrace.swift diff --git a/validation-test/compiler_crashers_fixed/1648-global-is-external.swift b/validation-test/compiler_crashers_fixed/01648-global-is-external.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1648-global-is-external.swift rename to validation-test/compiler_crashers_fixed/01648-global-is-external.swift diff --git a/validation-test/compiler_crashers_fixed/1649-swift-constraints-constraintgraph-change-undo.swift b/validation-test/compiler_crashers_fixed/01649-swift-constraints-constraintgraph-change-undo.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1649-swift-constraints-constraintgraph-change-undo.swift rename to validation-test/compiler_crashers_fixed/01649-swift-constraints-constraintgraph-change-undo.swift diff --git a/validation-test/compiler_crashers_fixed/1650-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/01650-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1650-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/01650-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/01651-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01651-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..4c9929c18c8f9 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01651-getselftypeforcontainer.swift @@ -0,0 +1,20 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + + Any) -> V, length: AnyObject) { +let i<1 { +protocol a { +return { c: (Any) -> String { +extension NSSet { +} +} +typealias f : a { +} +} +} +print().c where A, a(T, A = { } +struct c in 0.Type +struct S String +} +case C(start: b in c = i() { +} +func ^([c] = T: T +} +enum S { +} +func a((a!(() -> d +typealias d.b { +switch x }) +} +func compose() -> S : C(h: c: c("] +} +class B (array: P> Any) { +protocol B : B diff --git a/validation-test/compiler_crashers_fixed/1673-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/01673-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1673-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/01673-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/1674-swift-constraints-constraintsystem-simplifyconstraint.swift b/validation-test/compiler_crashers_fixed/01674-swift-constraints-constraintsystem-simplifyconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1674-swift-constraints-constraintsystem-simplifyconstraint.swift rename to validation-test/compiler_crashers_fixed/01674-swift-constraints-constraintsystem-simplifyconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1675-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/01675-swift-streamprinter-printtext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1675-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/01675-swift-streamprinter-printtext.swift diff --git a/validation-test/compiler_crashers_fixed/1676-swift-parser-parseexprsequence.swift b/validation-test/compiler_crashers_fixed/01676-swift-parser-parseexprsequence.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1676-swift-parser-parseexprsequence.swift rename to validation-test/compiler_crashers_fixed/01676-swift-parser-parseexprsequence.swift diff --git a/validation-test/compiler_crashers_fixed/1677-swift-dependentmembertype-get.swift b/validation-test/compiler_crashers_fixed/01677-swift-dependentmembertype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1677-swift-dependentmembertype-get.swift rename to validation-test/compiler_crashers_fixed/01677-swift-dependentmembertype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1678-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01678-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1678-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01678-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1679-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/01679-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1679-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/01679-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1681-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/01681-swift-nominaltypedecl-preparelookuptable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1681-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/01681-swift-nominaltypedecl-preparelookuptable.swift diff --git a/validation-test/compiler_crashers_fixed/1682-swift-parser-parsedecl.swift b/validation-test/compiler_crashers_fixed/01682-swift-parser-parsedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1682-swift-parser-parsedecl.swift rename to validation-test/compiler_crashers_fixed/01682-swift-parser-parsedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1683-swift-nominaltype-get.swift b/validation-test/compiler_crashers_fixed/01683-swift-nominaltype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1683-swift-nominaltype-get.swift rename to validation-test/compiler_crashers_fixed/01683-swift-nominaltype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1685-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/01685-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1685-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/01685-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/1686-swift-astcontext-setconformsto.swift b/validation-test/compiler_crashers_fixed/01686-swift-astcontext-setconformsto.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1686-swift-astcontext-setconformsto.swift rename to validation-test/compiler_crashers_fixed/01686-swift-astcontext-setconformsto.swift diff --git a/validation-test/compiler_crashers_fixed/1687-swift-constraints-constraintgraph-removeconstraint.swift b/validation-test/compiler_crashers_fixed/01687-swift-constraints-constraintgraph-removeconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1687-swift-constraints-constraintgraph-removeconstraint.swift rename to validation-test/compiler_crashers_fixed/01687-swift-constraints-constraintgraph-removeconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1688-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/01688-swift-constraints-constraintsystem-matchtypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1688-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/01688-swift-constraints-constraintsystem-matchtypes.swift diff --git a/validation-test/compiler_crashers_fixed/1689-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01689-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1689-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01689-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1691-clang-astcontext-getrecordtype.swift b/validation-test/compiler_crashers_fixed/01691-clang-astcontext-getrecordtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1691-clang-astcontext-getrecordtype.swift rename to validation-test/compiler_crashers_fixed/01691-clang-astcontext-getrecordtype.swift diff --git a/validation-test/compiler_crashers_fixed/1692-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01692-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1692-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01692-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1693-swift-typealiasdecl-typealiasdecl.swift b/validation-test/compiler_crashers_fixed/01693-swift-typealiasdecl-typealiasdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1693-swift-typealiasdecl-typealiasdecl.swift rename to validation-test/compiler_crashers_fixed/01693-swift-typealiasdecl-typealiasdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1694-void.swift b/validation-test/compiler_crashers_fixed/01694-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1694-void.swift rename to validation-test/compiler_crashers_fixed/01694-void.swift diff --git a/validation-test/compiler_crashers_fixed/1695-swift-pattern-operator.swift b/validation-test/compiler_crashers_fixed/01695-swift-pattern-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1695-swift-pattern-operator.swift rename to validation-test/compiler_crashers_fixed/01695-swift-pattern-operator.swift diff --git a/validation-test/compiler_crashers_fixed/01696-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01696-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..3d7032ee7e652 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01696-getselftypeforcontainer.swift @@ -0,0 +1,21 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +var f : AnyObject, AnyObject, range: a { +e where B { +return m: String { +func g T -> Int { +} +} +} +print() -> { +} +protocol a { +protocol A { +typealias A : a: SequenceType where T>(" +func a +return x in x } +func a: A, g diff --git a/validation-test/compiler_crashers_fixed/1698-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01698-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1698-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01698-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1699-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/01699-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1699-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/01699-llvm-foldingset-swift-tupletype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/1700-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/01700-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1700-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/01700-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/1701-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01701-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1701-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01701-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/1702-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01702-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1702-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01702-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1703-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/01703-swift-constraints-constraintlocator-profile.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1703-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/01703-swift-constraints-constraintlocator-profile.swift diff --git a/validation-test/compiler_crashers_fixed/01704-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01704-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..13dabd9b7045f --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01704-getselftypeforcontainer.swift @@ -0,0 +1,17 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +struct B(" +} +var f = c: diff --git a/validation-test/compiler_crashers_fixed/1705-vtable.swift b/validation-test/compiler_crashers_fixed/01705-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1705-vtable.swift rename to validation-test/compiler_crashers_fixed/01705-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/1706-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01706-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1706-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01706-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1707-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/01707-swift-genericsignature-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1707-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/01707-swift-genericsignature-get.swift diff --git a/validation-test/compiler_crashers_fixed/1708-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01708-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1708-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01708-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1709-vtable.swift b/validation-test/compiler_crashers_fixed/01709-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1709-vtable.swift rename to validation-test/compiler_crashers_fixed/01709-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/1710-swift-typechecker-callwitness.swift b/validation-test/compiler_crashers_fixed/01710-swift-typechecker-callwitness.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1710-swift-typechecker-callwitness.swift rename to validation-test/compiler_crashers_fixed/01710-swift-typechecker-callwitness.swift diff --git a/validation-test/compiler_crashers_fixed/1711-swift-module-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01711-swift-module-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1711-swift-module-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01711-swift-module-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1712-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/01712-swift-boundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1712-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/01712-swift-boundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1713-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01713-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1713-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01713-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1714-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01714-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1714-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01714-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1715-void.swift b/validation-test/compiler_crashers_fixed/01715-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1715-void.swift rename to validation-test/compiler_crashers_fixed/01715-void.swift diff --git a/validation-test/compiler_crashers_fixed/1716-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01716-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1716-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01716-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1717-getcallerdefaultarg.swift b/validation-test/compiler_crashers_fixed/01717-getcallerdefaultarg.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1717-getcallerdefaultarg.swift rename to validation-test/compiler_crashers_fixed/01717-getcallerdefaultarg.swift diff --git a/validation-test/compiler_crashers_fixed/1718-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/01718-swift-nominaltypedecl-preparelookuptable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1718-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/01718-swift-nominaltypedecl-preparelookuptable.swift diff --git a/validation-test/compiler_crashers_fixed/1719-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/01719-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1719-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/01719-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/1720-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01720-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1720-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/01720-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/1721-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01721-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1721-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01721-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1722-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01722-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1722-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01722-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1723-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/01723-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1723-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/01723-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1724-llvm-tinyptrvector-swift-valuedecl-push-back.swift b/validation-test/compiler_crashers_fixed/01724-llvm-tinyptrvector-swift-valuedecl-push-back.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1724-llvm-tinyptrvector-swift-valuedecl-push-back.swift rename to validation-test/compiler_crashers_fixed/01724-llvm-tinyptrvector-swift-valuedecl-push-back.swift diff --git a/validation-test/compiler_crashers_fixed/1725-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01725-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1725-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01725-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1726-getmemberforbasetype.swift b/validation-test/compiler_crashers_fixed/01726-getmemberforbasetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1726-getmemberforbasetype.swift rename to validation-test/compiler_crashers_fixed/01726-getmemberforbasetype.swift diff --git a/validation-test/compiler_crashers_fixed/1728-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/01728-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1728-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/01728-llvm-foldingset-swift-tupletype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/1729-swift-parser-parsetoken.swift b/validation-test/compiler_crashers_fixed/01729-swift-parser-parsetoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1729-swift-parser-parsetoken.swift rename to validation-test/compiler_crashers_fixed/01729-swift-parser-parsetoken.swift diff --git a/validation-test/compiler_crashers_fixed/1730-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/01730-swift-completegenerictyperesolver-resolvedependentmembertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1730-swift-completegenerictyperesolver-resolvedependentmembertype.swift rename to validation-test/compiler_crashers_fixed/01730-swift-completegenerictyperesolver-resolvedependentmembertype.swift diff --git a/validation-test/compiler_crashers_fixed/1731-swift-dictionarytype-get.swift b/validation-test/compiler_crashers_fixed/01731-swift-dictionarytype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1731-swift-dictionarytype-get.swift rename to validation-test/compiler_crashers_fixed/01731-swift-dictionarytype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1732-swift-parser-parsebraceitemlist.swift b/validation-test/compiler_crashers_fixed/01732-swift-parser-parsebraceitemlist.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1732-swift-parser-parsebraceitemlist.swift rename to validation-test/compiler_crashers_fixed/01732-swift-parser-parsebraceitemlist.swift diff --git a/validation-test/compiler_crashers_fixed/1733-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/01733-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1733-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/01733-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1734-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01734-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1734-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01734-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1735-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01735-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1735-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01735-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/1736-void.swift b/validation-test/compiler_crashers_fixed/01736-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1736-void.swift rename to validation-test/compiler_crashers_fixed/01736-void.swift diff --git a/validation-test/compiler_crashers_fixed/1737-swift-constraints-constraintgraphscope-constraintgraphscope.swift b/validation-test/compiler_crashers_fixed/01737-swift-constraints-constraintgraphscope-constraintgraphscope.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1737-swift-constraints-constraintgraphscope-constraintgraphscope.swift rename to validation-test/compiler_crashers_fixed/01737-swift-constraints-constraintgraphscope-constraintgraphscope.swift diff --git a/validation-test/compiler_crashers_fixed/1738-vtable.swift b/validation-test/compiler_crashers_fixed/01738-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1738-vtable.swift rename to validation-test/compiler_crashers_fixed/01738-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/1740-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01740-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1740-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01740-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/01741-swift-constraints-constraintsystem-simplifymemberconstraint.swift b/validation-test/compiler_crashers_fixed/01741-swift-constraints-constraintsystem-simplifymemberconstraint.swift new file mode 100644 index 0000000000000..c318dfff752cd --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01741-swift-constraints-constraintsystem-simplifymemberconstraint.swift @@ -0,0 +1,17 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +([() +enum B : A { +f(x) -> { +} +} +protocol A { +protocol a { +} +func d +typealias b : b = b[1 +s diff --git a/validation-test/compiler_crashers_fixed/1742-swift-arrayslicetype-get.swift b/validation-test/compiler_crashers_fixed/01742-swift-arrayslicetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1742-swift-arrayslicetype-get.swift rename to validation-test/compiler_crashers_fixed/01742-swift-arrayslicetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1743-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/01743-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1743-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/01743-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/1745-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01745-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1745-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01745-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1746-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift b/validation-test/compiler_crashers_fixed/01746-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1746-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift rename to validation-test/compiler_crashers_fixed/01746-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1747-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/01747-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1747-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/01747-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/1748-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/01748-swift-typebase-getanyoptionalobjecttype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1748-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/01748-swift-typebase-getanyoptionalobjecttype.swift diff --git a/validation-test/compiler_crashers_fixed/1749-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01749-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1749-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01749-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1750-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/01750-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1750-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/01750-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/1751-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01751-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1751-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01751-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1752-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/01752-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1752-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/01752-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/1753-swift-lexer-lexstringliteral.swift b/validation-test/compiler_crashers_fixed/01753-swift-lexer-lexstringliteral.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1753-swift-lexer-lexstringliteral.swift rename to validation-test/compiler_crashers_fixed/01753-swift-lexer-lexstringliteral.swift diff --git a/validation-test/compiler_crashers_fixed/1754-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01754-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1754-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01754-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1755-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/01755-swift-streamprinter-printtext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1755-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/01755-swift-streamprinter-printtext.swift diff --git a/validation-test/compiler_crashers_fixed/1756-swift-constraints-constraintsystem-matchfunctiontypes.swift b/validation-test/compiler_crashers_fixed/01756-swift-constraints-constraintsystem-matchfunctiontypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1756-swift-constraints-constraintsystem-matchfunctiontypes.swift rename to validation-test/compiler_crashers_fixed/01756-swift-constraints-constraintsystem-matchfunctiontypes.swift diff --git a/validation-test/compiler_crashers_fixed/1757-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01757-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1757-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01757-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1758-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01758-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1758-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01758-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1759-bool.swift b/validation-test/compiler_crashers_fixed/01759-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1759-bool.swift rename to validation-test/compiler_crashers_fixed/01759-bool.swift diff --git a/validation-test/compiler_crashers_fixed/1760-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01760-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1760-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01760-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1761-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/01761-swift-genericfunctiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1761-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/01761-swift-genericfunctiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1762-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/01762-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1762-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/01762-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/1763-swift-archetypebuilder-resolvearchetype.swift b/validation-test/compiler_crashers_fixed/01763-swift-archetypebuilder-resolvearchetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1763-swift-archetypebuilder-resolvearchetype.swift rename to validation-test/compiler_crashers_fixed/01763-swift-archetypebuilder-resolvearchetype.swift diff --git a/validation-test/compiler_crashers_fixed/1764-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/01764-swift-astprinter-printtextimpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1764-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/01764-swift-astprinter-printtextimpl.swift diff --git a/validation-test/compiler_crashers_fixed/1765-swift-inflightdiagnostic-highlight.swift b/validation-test/compiler_crashers_fixed/01765-swift-inflightdiagnostic-highlight.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1765-swift-inflightdiagnostic-highlight.swift rename to validation-test/compiler_crashers_fixed/01765-swift-inflightdiagnostic-highlight.swift diff --git a/validation-test/compiler_crashers_fixed/1767-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01767-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1767-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01767-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1768-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01768-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1768-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01768-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1769-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01769-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1769-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01769-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1770-swift-typechecker-buildarrayinjectionfnref.swift b/validation-test/compiler_crashers_fixed/01770-swift-typechecker-buildarrayinjectionfnref.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1770-swift-typechecker-buildarrayinjectionfnref.swift rename to validation-test/compiler_crashers_fixed/01770-swift-typechecker-buildarrayinjectionfnref.swift diff --git a/validation-test/compiler_crashers_fixed/1771-swift-sourcefile-getcache.swift b/validation-test/compiler_crashers_fixed/01771-swift-sourcefile-getcache.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1771-swift-sourcefile-getcache.swift rename to validation-test/compiler_crashers_fixed/01771-swift-sourcefile-getcache.swift diff --git a/validation-test/compiler_crashers_fixed/1772-void.swift b/validation-test/compiler_crashers_fixed/01772-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1772-void.swift rename to validation-test/compiler_crashers_fixed/01772-void.swift diff --git a/validation-test/compiler_crashers_fixed/1773-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01773-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1773-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01773-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1774-getmemberforbasetype.swift b/validation-test/compiler_crashers_fixed/01774-getmemberforbasetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1774-getmemberforbasetype.swift rename to validation-test/compiler_crashers_fixed/01774-getmemberforbasetype.swift diff --git a/validation-test/compiler_crashers_fixed/1775-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01775-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1775-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01775-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1776-swift-availabilityattr-isunavailable.swift b/validation-test/compiler_crashers_fixed/01776-swift-availabilityattr-isunavailable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1776-swift-availabilityattr-isunavailable.swift rename to validation-test/compiler_crashers_fixed/01776-swift-availabilityattr-isunavailable.swift diff --git a/validation-test/compiler_crashers_fixed/1777-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01777-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1777-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01777-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1778-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01778-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1778-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01778-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1779-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/01779-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1779-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/01779-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/1780-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01780-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1780-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01780-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1781-swift-optional-std-pair-swift-api-notes-contextid.swift b/validation-test/compiler_crashers_fixed/01781-swift-optional-std-pair-swift-api-notes-contextid.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1781-swift-optional-std-pair-swift-api-notes-contextid.swift rename to validation-test/compiler_crashers_fixed/01781-swift-optional-std-pair-swift-api-notes-contextid.swift diff --git a/validation-test/compiler_crashers_fixed/1782-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/01782-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1782-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/01782-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/01783-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01783-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..b15e1c86b52b4 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01783-getselftypeforcontainer.swift @@ -0,0 +1,15 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol c { +protocol b { +func a) +typealias d: a { +} +} +} +class A { +let end = c] diff --git a/validation-test/compiler_crashers_fixed/1784-swift-constraints-constraintgraph-lookupnode.swift b/validation-test/compiler_crashers_fixed/01784-swift-constraints-constraintgraph-lookupnode.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1784-swift-constraints-constraintgraph-lookupnode.swift rename to validation-test/compiler_crashers_fixed/01784-swift-constraints-constraintgraph-lookupnode.swift diff --git a/validation-test/compiler_crashers_fixed/1785-swift-scopeinfo-addtoscope.swift b/validation-test/compiler_crashers_fixed/01785-swift-scopeinfo-addtoscope.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1785-swift-scopeinfo-addtoscope.swift rename to validation-test/compiler_crashers_fixed/01785-swift-scopeinfo-addtoscope.swift diff --git a/validation-test/compiler_crashers_fixed/1786-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01786-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1786-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/01786-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/1787-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01787-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1787-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/01787-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/1788-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01788-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1788-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01788-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1789-swift-generictypeparamtype-get.swift b/validation-test/compiler_crashers_fixed/01789-swift-generictypeparamtype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1789-swift-generictypeparamtype-get.swift rename to validation-test/compiler_crashers_fixed/01789-swift-generictypeparamtype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1790-swift-constraints-constraintgraph-unbindtypevariable.swift b/validation-test/compiler_crashers_fixed/01790-swift-constraints-constraintgraph-unbindtypevariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1790-swift-constraints-constraintgraph-unbindtypevariable.swift rename to validation-test/compiler_crashers_fixed/01790-swift-constraints-constraintgraph-unbindtypevariable.swift diff --git a/validation-test/compiler_crashers_fixed/1791-swift-typedecl-getdeclaredtype.swift b/validation-test/compiler_crashers_fixed/01791-swift-typedecl-getdeclaredtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1791-swift-typedecl-getdeclaredtype.swift rename to validation-test/compiler_crashers_fixed/01791-swift-typedecl-getdeclaredtype.swift diff --git a/validation-test/compiler_crashers_fixed/1792-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/01792-swift-genericsignature-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1792-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/01792-swift-genericsignature-get.swift diff --git a/validation-test/compiler_crashers_fixed/1794-swift-astcontext-setconformsto.swift b/validation-test/compiler_crashers_fixed/01794-swift-astcontext-setconformsto.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1794-swift-astcontext-setconformsto.swift rename to validation-test/compiler_crashers_fixed/01794-swift-astcontext-setconformsto.swift diff --git a/validation-test/compiler_crashers_fixed/1795-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/01795-swift-pattern-foreachvariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1795-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/01795-swift-pattern-foreachvariable.swift diff --git a/validation-test/compiler_crashers_fixed/1796-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01796-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1796-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01796-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1797-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01797-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1797-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01797-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1798-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/01798-swift-typechecker-coercepatterntotype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1798-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/01798-swift-typechecker-coercepatterntotype.swift diff --git a/validation-test/compiler_crashers_fixed/1799-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01799-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1799-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01799-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1800-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/01800-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1800-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/01800-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1801-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01801-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1801-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01801-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1802-swift-astvisitor.swift b/validation-test/compiler_crashers_fixed/01802-swift-astvisitor.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1802-swift-astvisitor.swift rename to validation-test/compiler_crashers_fixed/01802-swift-astvisitor.swift diff --git a/validation-test/compiler_crashers_fixed/1803-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/01803-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1803-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/01803-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/1804-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/01804-swift-modulefile-maybereadpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1804-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/01804-swift-modulefile-maybereadpattern.swift diff --git a/validation-test/compiler_crashers_fixed/1805-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01805-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1805-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01805-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1806-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/01806-swift-typechecker-validatedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1806-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/01806-swift-typechecker-validatedecl.swift diff --git a/validation-test/compiler_crashers_fixed/01807-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01807-resolvetypedecl.swift new file mode 100644 index 0000000000000..423da3f5757ee --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01807-resolvetypedecl.swift @@ -0,0 +1,12 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol b { +enum S String { +return { self.R +protocol A { +})) +} +} +func b +} +} +var e(true as a: St diff --git a/validation-test/compiler_crashers_fixed/1835-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01835-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1835-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01835-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1836-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01836-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1836-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01836-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1837-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01837-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1837-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01837-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1838-void.swift b/validation-test/compiler_crashers_fixed/01838-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1838-void.swift rename to validation-test/compiler_crashers_fixed/01838-void.swift diff --git a/validation-test/compiler_crashers_fixed/1839-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/01839-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1839-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/01839-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/1840-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01840-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1840-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01840-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1841-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01841-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1841-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01841-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1842-swift-associatedtypedecl-associatedtypedecl.swift b/validation-test/compiler_crashers_fixed/01842-swift-associatedtypedecl-associatedtypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1842-swift-associatedtypedecl-associatedtypedecl.swift rename to validation-test/compiler_crashers_fixed/01842-swift-associatedtypedecl-associatedtypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1843-llvm-bitstreamcursor-readrecord.swift b/validation-test/compiler_crashers_fixed/01843-llvm-bitstreamcursor-readrecord.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1843-llvm-bitstreamcursor-readrecord.swift rename to validation-test/compiler_crashers_fixed/01843-llvm-bitstreamcursor-readrecord.swift diff --git a/validation-test/compiler_crashers_fixed/1844-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/01844-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1844-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/01844-swift-constraints-constraintsystem-assignfixedtype.swift diff --git a/validation-test/compiler_crashers_fixed/1845-swift-typebase-gettypeofmember.swift b/validation-test/compiler_crashers_fixed/01845-swift-typebase-gettypeofmember.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1845-swift-typebase-gettypeofmember.swift rename to validation-test/compiler_crashers_fixed/01845-swift-typebase-gettypeofmember.swift diff --git a/validation-test/compiler_crashers_fixed/1846-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/01846-swift-parser-parseexprpostfix.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1846-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/01846-swift-parser-parseexprpostfix.swift diff --git a/validation-test/compiler_crashers_fixed/1847-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01847-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1847-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/01847-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/1848-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/01848-swift-completegenerictyperesolver-resolvedependentmembertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1848-swift-completegenerictyperesolver-resolvedependentmembertype.swift rename to validation-test/compiler_crashers_fixed/01848-swift-completegenerictyperesolver-resolvedependentmembertype.swift diff --git a/validation-test/compiler_crashers_fixed/1849-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01849-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1849-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01849-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1850-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01850-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1850-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01850-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1851-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/01851-swift-genericparamlist-addnestedarchetypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1851-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/01851-swift-genericparamlist-addnestedarchetypes.swift diff --git a/validation-test/compiler_crashers_fixed/1852-swift-constraints-constraintsystem-getconstraintlocator.swift b/validation-test/compiler_crashers_fixed/01852-swift-constraints-constraintsystem-getconstraintlocator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1852-swift-constraints-constraintsystem-getconstraintlocator.swift rename to validation-test/compiler_crashers_fixed/01852-swift-constraints-constraintsystem-getconstraintlocator.swift diff --git a/validation-test/compiler_crashers_fixed/1853-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/01853-swift-lexer-lexidentifier.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1853-swift-lexer-lexidentifier.swift rename to validation-test/compiler_crashers_fixed/01853-swift-lexer-lexidentifier.swift diff --git a/validation-test/compiler_crashers_fixed/1854-llvm-foldingset-swift-boundgenerictype-nodeequals.swift b/validation-test/compiler_crashers_fixed/01854-llvm-foldingset-swift-boundgenerictype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1854-llvm-foldingset-swift-boundgenerictype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/01854-llvm-foldingset-swift-boundgenerictype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/1855-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/01855-swift-pattern-foreachvariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1855-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/01855-swift-pattern-foreachvariable.swift diff --git a/validation-test/compiler_crashers_fixed/1856-swift-parser-parsetypesimple.swift b/validation-test/compiler_crashers_fixed/01856-swift-parser-parsetypesimple.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1856-swift-parser-parsetypesimple.swift rename to validation-test/compiler_crashers_fixed/01856-swift-parser-parsetypesimple.swift diff --git a/validation-test/compiler_crashers_fixed/01857-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01857-std-function-func-swift-type-subst.swift new file mode 100644 index 0000000000000..23eb1a13765e4 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01857-std-function-func-swift-type-subst.swift @@ -0,0 +1,16 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func g() -> T.c() { +return ""ab"] +} +typealias g { +} +class func d +enum A = T) -> String { +func a")() -> Any, () -> Void>(bytes: X T : c, Any, A { +class B == d..b["A +class a { +func b T, q:Any) { +func g: NSObject { +struct d.E == Swift.h: T) { +typealias F = c: S () { +} +} +if true { +} +} +init { +f: A { +let a { +var b: A? = Swift.c, T : (c]).startIndex)") +} +struct c) -> U) { +} +} +protocol P { +} +func a: String { +pri diff --git a/validation-test/compiler_crashers_fixed/1872-void.swift b/validation-test/compiler_crashers_fixed/01872-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1872-void.swift rename to validation-test/compiler_crashers_fixed/01872-void.swift diff --git a/validation-test/compiler_crashers_fixed/1873-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/01873-swift-pattern-foreachvariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1873-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/01873-swift-pattern-foreachvariable.swift diff --git a/validation-test/compiler_crashers_fixed/1874-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01874-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1874-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01874-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1875-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/01875-swift-modulefile-gettype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1875-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/01875-swift-modulefile-gettype.swift diff --git a/validation-test/compiler_crashers_fixed/1876-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01876-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1876-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01876-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1877-swift-typebase-isexistentialtype.swift b/validation-test/compiler_crashers_fixed/01877-swift-typebase-isexistentialtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1877-swift-typebase-isexistentialtype.swift rename to validation-test/compiler_crashers_fixed/01877-swift-typebase-isexistentialtype.swift diff --git a/validation-test/compiler_crashers_fixed/1878-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01878-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1878-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01878-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1879-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01879-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1879-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01879-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1880-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/01880-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1880-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/01880-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/1881-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/01881-swift-structtype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1881-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/01881-swift-structtype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1882-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift b/validation-test/compiler_crashers_fixed/01882-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1882-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift rename to validation-test/compiler_crashers_fixed/01882-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1883-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01883-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1883-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01883-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1884-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/01884-swift-typechecker-resolvetypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1884-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/01884-swift-typechecker-resolvetypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1885-swift-constraints-solution-simplifytype.swift b/validation-test/compiler_crashers_fixed/01885-swift-constraints-solution-simplifytype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1885-swift-constraints-solution-simplifytype.swift rename to validation-test/compiler_crashers_fixed/01885-swift-constraints-solution-simplifytype.swift diff --git a/validation-test/compiler_crashers_fixed/1886-swift-typebase-operator.swift b/validation-test/compiler_crashers_fixed/01886-swift-typebase-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1886-swift-typebase-operator.swift rename to validation-test/compiler_crashers_fixed/01886-swift-typebase-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1887-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01887-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1887-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01887-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1888-vtable.swift b/validation-test/compiler_crashers_fixed/01888-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1888-vtable.swift rename to validation-test/compiler_crashers_fixed/01888-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/1889-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01889-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1889-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01889-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/01890-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/01890-swift-clangmoduleunit-getadaptermodule.swift new file mode 100644 index 0000000000000..8e4a96524b7f3 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01890-swift-clangmoduleunit-getadaptermodule.swift @@ -0,0 +1,15 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +import Foundation +protocol c { +protocol a : a { +func f { +assert(.d.init(" +} +class func a: b: b diff --git a/validation-test/compiler_crashers_fixed/1893-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01893-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1893-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01893-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1894-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01894-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1894-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01894-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1895-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/01895-swift-typechecker-validatedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1895-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/01895-swift-typechecker-validatedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1896-swift-parser-parsedecl.swift b/validation-test/compiler_crashers_fixed/01896-swift-parser-parsedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1896-swift-parser-parsedecl.swift rename to validation-test/compiler_crashers_fixed/01896-swift-parser-parsedecl.swift diff --git a/validation-test/compiler_crashers_fixed/01897-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01897-resolvetypedecl.swift new file mode 100644 index 0000000000000..3cfb109eb46cc --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01897-resolvetypedecl.swift @@ -0,0 +1,13 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +let c { +struct A { +func g> T { +})) +var b: A.startIndex, range.advance() +} +struct A String { +} +protocol e where I) ->, Any, e where f))))-> { +} +var d { +} +func e: a { +func b: X("ab"") +protocol b { +} +typealias b : b: Int { diff --git a/validation-test/compiler_crashers_fixed/1946-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01946-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1946-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01946-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1947-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01947-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1947-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01947-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1948-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01948-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1948-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01948-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1949-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/01949-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1949-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/01949-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift diff --git a/validation-test/compiler_crashers_fixed/1950-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01950-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1950-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01950-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1951-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/01951-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1951-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/01951-swift-constraints-constraintsystem-assignfixedtype.swift diff --git a/validation-test/compiler_crashers_fixed/1952-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/01952-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1952-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/01952-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1953-swift-module-lookupconformance.swift b/validation-test/compiler_crashers_fixed/01953-swift-module-lookupconformance.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1953-swift-module-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/01953-swift-module-lookupconformance.swift diff --git a/validation-test/compiler_crashers_fixed/1954-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/01954-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1954-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/01954-swift-constraints-constraintsystem-assignfixedtype.swift diff --git a/validation-test/compiler_crashers_fixed/1955-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01955-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1955-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/01955-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/1956-method-declared-to-return-its-own-name.swift b/validation-test/compiler_crashers_fixed/01956-method-declared-to-return-its-own-name.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1956-method-declared-to-return-its-own-name.swift rename to validation-test/compiler_crashers_fixed/01956-method-declared-to-return-its-own-name.swift diff --git a/validation-test/compiler_crashers_fixed/1957-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/01957-swift-typechecker-resolvetypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1957-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/01957-swift-typechecker-resolvetypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/01958-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01958-std-function-func-swift-type-subst.swift new file mode 100644 index 0000000000000..d61c05b571d6e --- /dev/null +++ b/validation-test/compiler_crashers_fixed/01958-std-function-func-swift-type-subst.swift @@ -0,0 +1,18 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +let b { +protocol a { +func i() -> e: ExtensibleCollectionType>([0x31] = 0 +for (" +protocol a { +var d : NSObject { +} +let v: e> Any) -> Any in +protocol a { +} +} +typealias e : d = a(c { diff --git a/validation-test/compiler_crashers_fixed/1960-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01960-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1960-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01960-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1961-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01961-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1961-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01961-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1962-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/01962-swift-genericfunctiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1962-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/01962-swift-genericfunctiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1963-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/01963-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1963-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/01963-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/1964-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01964-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1964-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01964-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1965-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift b/validation-test/compiler_crashers_fixed/01965-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1965-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift rename to validation-test/compiler_crashers_fixed/01965-swift-constraints-constraintsystem-diagnosefailurefromconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/1966-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/01966-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1966-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/01966-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/1967-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/01967-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1967-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/01967-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/1968-bool.swift b/validation-test/compiler_crashers_fixed/01968-bool.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1968-bool.swift rename to validation-test/compiler_crashers_fixed/01968-bool.swift diff --git a/validation-test/compiler_crashers_fixed/1969-getmemberforbasetype.swift b/validation-test/compiler_crashers_fixed/01969-getmemberforbasetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1969-getmemberforbasetype.swift rename to validation-test/compiler_crashers_fixed/01969-getmemberforbasetype.swift diff --git a/validation-test/compiler_crashers_fixed/1970-void.swift b/validation-test/compiler_crashers_fixed/01970-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1970-void.swift rename to validation-test/compiler_crashers_fixed/01970-void.swift diff --git a/validation-test/compiler_crashers_fixed/1971-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/01971-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1971-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/01971-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1972-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01972-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1972-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01972-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1973-void.swift b/validation-test/compiler_crashers_fixed/01973-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1973-void.swift rename to validation-test/compiler_crashers_fixed/01973-void.swift diff --git a/validation-test/compiler_crashers_fixed/1974-swift-declname-declname.swift b/validation-test/compiler_crashers_fixed/01974-swift-declname-declname.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1974-swift-declname-declname.swift rename to validation-test/compiler_crashers_fixed/01974-swift-declname-declname.swift diff --git a/validation-test/compiler_crashers_fixed/1975-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/01975-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1975-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/01975-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/1976-llvm-yaml-scalartraits-float-input.swift b/validation-test/compiler_crashers_fixed/01976-llvm-yaml-scalartraits-float-input.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1976-llvm-yaml-scalartraits-float-input.swift rename to validation-test/compiler_crashers_fixed/01976-llvm-yaml-scalartraits-float-input.swift diff --git a/validation-test/compiler_crashers_fixed/1977-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/01977-swift-constraints-constraintgraph-addconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1977-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/01977-swift-constraints-constraintgraph-addconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/1978-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/01978-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1978-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/01978-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/1979-swift-parser-parseexprclosure.swift b/validation-test/compiler_crashers_fixed/01979-swift-parser-parseexprclosure.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1979-swift-parser-parseexprclosure.swift rename to validation-test/compiler_crashers_fixed/01979-swift-parser-parseexprclosure.swift diff --git a/validation-test/compiler_crashers_fixed/1980-swift-typebase-operator.swift b/validation-test/compiler_crashers_fixed/01980-swift-typebase-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1980-swift-typebase-operator.swift rename to validation-test/compiler_crashers_fixed/01980-swift-typebase-operator.swift diff --git a/validation-test/compiler_crashers_fixed/1981-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/01981-swift-modulefile-maybereadgenericparams.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1981-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/01981-swift-modulefile-maybereadgenericparams.swift diff --git a/validation-test/compiler_crashers_fixed/1982-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/01982-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1982-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/01982-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/1983-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/01983-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1983-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/01983-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/1984-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/01984-swift-protocoltype-canonicalizeprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1984-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/01984-swift-protocoltype-canonicalizeprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/1985-swift-parser-parsestmtforeach.swift b/validation-test/compiler_crashers_fixed/01985-swift-parser-parsestmtforeach.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1985-swift-parser-parsestmtforeach.swift rename to validation-test/compiler_crashers_fixed/01985-swift-parser-parsestmtforeach.swift diff --git a/validation-test/compiler_crashers_fixed/1986-swift-parser-parseexprunary.swift b/validation-test/compiler_crashers_fixed/01986-swift-parser-parseexprunary.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1986-swift-parser-parseexprunary.swift rename to validation-test/compiler_crashers_fixed/01986-swift-parser-parseexprunary.swift diff --git a/validation-test/compiler_crashers_fixed/1987-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/01987-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1987-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/01987-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1988-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01988-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1988-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01988-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1989-void.swift b/validation-test/compiler_crashers_fixed/01989-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1989-void.swift rename to validation-test/compiler_crashers_fixed/01989-void.swift diff --git a/validation-test/compiler_crashers_fixed/1990-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/01990-swift-modulefile-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1990-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/01990-swift-modulefile-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/1991-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/01991-swift-declcontext-lookupqualified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1991-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/01991-swift-declcontext-lookupqualified.swift diff --git a/validation-test/compiler_crashers_fixed/1992-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/01992-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1992-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/01992-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/1993-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/01993-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1993-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/01993-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/1994-swift-parser-consumetoken.swift b/validation-test/compiler_crashers_fixed/01994-swift-parser-consumetoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1994-swift-parser-consumetoken.swift rename to validation-test/compiler_crashers_fixed/01994-swift-parser-consumetoken.swift diff --git a/validation-test/compiler_crashers_fixed/1995-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/01995-swift-constraints-constraintsystem-solve.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1995-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/01995-swift-constraints-constraintsystem-solve.swift diff --git a/validation-test/compiler_crashers_fixed/1996-swift-parser-parsedeclenumcase.swift b/validation-test/compiler_crashers_fixed/01996-swift-parser-parsedeclenumcase.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1996-swift-parser-parsedeclenumcase.swift rename to validation-test/compiler_crashers_fixed/01996-swift-parser-parsedeclenumcase.swift diff --git a/validation-test/compiler_crashers_fixed/1997-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/01997-swift-typechecker-checksubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1997-swift-typechecker-checksubstitutions.swift rename to validation-test/compiler_crashers_fixed/01997-swift-typechecker-checksubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/1998-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/01998-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1998-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/01998-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/1999-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/01999-swift-lexer-leximpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/1999-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/01999-swift-lexer-leximpl.swift diff --git a/validation-test/compiler_crashers_fixed/2000-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/02000-swift-constraints-constraintsystem-opengeneric.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2000-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/02000-swift-constraints-constraintsystem-opengeneric.swift diff --git a/validation-test/compiler_crashers_fixed/2001-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/02001-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2001-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/02001-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/2002-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02002-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2002-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/02002-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/2003-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift b/validation-test/compiler_crashers_fixed/02003-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2003-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift rename to validation-test/compiler_crashers_fixed/02003-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift diff --git a/validation-test/compiler_crashers_fixed/2004-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/02004-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2004-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/02004-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/2005-swift-parser-parsedeclvargetset.swift b/validation-test/compiler_crashers_fixed/02005-swift-parser-parsedeclvargetset.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2005-swift-parser-parsedeclvargetset.swift rename to validation-test/compiler_crashers_fixed/02005-swift-parser-parsedeclvargetset.swift diff --git a/validation-test/compiler_crashers_fixed/2006-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/02006-swift-typebase-getdesugaredtype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2006-swift-typebase-getdesugaredtype.swift rename to validation-test/compiler_crashers_fixed/02006-swift-typebase-getdesugaredtype.swift diff --git a/validation-test/compiler_crashers_fixed/2007-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02007-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2007-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02007-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2008-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/02008-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2008-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/02008-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2009-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02009-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2009-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02009-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2010-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02010-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2010-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/02010-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/02011-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/02011-swift-lexer-lexidentifier.swift new file mode 100644 index 0000000000000..96a92792fd0ee --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02011-swift-lexer-lexidentifier.swift @@ -0,0 +1,27 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class c Void>>(e> { +typealias f = [Int>) { +typealias f = B>) { +} +}) +protocol a { +var b, (s: B, T : H.init(array: d = f(g +({ +} +struct c { +} +} +enum S) { +} +} +func diff --git a/validation-test/compiler_crashers_fixed/2012-inferdynamic.swift b/validation-test/compiler_crashers_fixed/02012-inferdynamic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2012-inferdynamic.swift rename to validation-test/compiler_crashers_fixed/02012-inferdynamic.swift diff --git a/validation-test/compiler_crashers_fixed/2013-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/02013-swift-lexer-leximpl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2013-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/02013-swift-lexer-leximpl.swift diff --git a/validation-test/compiler_crashers_fixed/2014-swift-parser-parsetypesimple.swift b/validation-test/compiler_crashers_fixed/02014-swift-parser-parsetypesimple.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2014-swift-parser-parsetypesimple.swift rename to validation-test/compiler_crashers_fixed/02014-swift-parser-parsetypesimple.swift diff --git a/validation-test/compiler_crashers_fixed/2015-swift-typebase-gettypeofmember.swift b/validation-test/compiler_crashers_fixed/02015-swift-typebase-gettypeofmember.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2015-swift-typebase-gettypeofmember.swift rename to validation-test/compiler_crashers_fixed/02015-swift-typebase-gettypeofmember.swift diff --git a/validation-test/compiler_crashers_fixed/2016-swift-tuplepattern-create.swift b/validation-test/compiler_crashers_fixed/02016-swift-tuplepattern-create.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2016-swift-tuplepattern-create.swift rename to validation-test/compiler_crashers_fixed/02016-swift-tuplepattern-create.swift diff --git a/validation-test/compiler_crashers_fixed/2017-swift-astcontext-getdictionarydecl.swift b/validation-test/compiler_crashers_fixed/02017-swift-astcontext-getdictionarydecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2017-swift-astcontext-getdictionarydecl.swift rename to validation-test/compiler_crashers_fixed/02017-swift-astcontext-getdictionarydecl.swift diff --git a/validation-test/compiler_crashers_fixed/2018-swift-declname-printpretty.swift b/validation-test/compiler_crashers_fixed/02018-swift-declname-printpretty.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2018-swift-declname-printpretty.swift rename to validation-test/compiler_crashers_fixed/02018-swift-declname-printpretty.swift diff --git a/validation-test/compiler_crashers_fixed/2019-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/02019-swift-protocoltype-canonicalizeprotocols.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2019-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/02019-swift-protocoltype-canonicalizeprotocols.swift diff --git a/validation-test/compiler_crashers_fixed/2020-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/02020-swift-lexer-getlocforendoftoken.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2020-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/02020-swift-lexer-getlocforendoftoken.swift diff --git a/validation-test/compiler_crashers_fixed/2021-std-function-func-swift-archetypebuilder-maptypeintocontext.swift b/validation-test/compiler_crashers_fixed/02021-std-function-func-swift-archetypebuilder-maptypeintocontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2021-std-function-func-swift-archetypebuilder-maptypeintocontext.swift rename to validation-test/compiler_crashers_fixed/02021-std-function-func-swift-archetypebuilder-maptypeintocontext.swift diff --git a/validation-test/compiler_crashers_fixed/2022-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/02022-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2022-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/02022-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/2023-void.swift b/validation-test/compiler_crashers_fixed/02023-void.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2023-void.swift rename to validation-test/compiler_crashers_fixed/02023-void.swift diff --git a/validation-test/compiler_crashers_fixed/2024-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02024-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2024-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/02024-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/2025-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02025-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2025-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/02025-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/2026-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/02026-swift-pattern-foreachvariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2026-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/02026-swift-pattern-foreachvariable.swift diff --git a/validation-test/compiler_crashers_fixed/2027-swift-unboundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/02027-swift-unboundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2027-swift-unboundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/02027-swift-unboundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2028-swift-constraints-constraintsystem-simplify.swift b/validation-test/compiler_crashers_fixed/02028-swift-constraints-constraintsystem-simplify.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2028-swift-constraints-constraintsystem-simplify.swift rename to validation-test/compiler_crashers_fixed/02028-swift-constraints-constraintsystem-simplify.swift diff --git a/validation-test/compiler_crashers_fixed/2029-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02029-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2029-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/02029-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/02030-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/02030-std-function-func-swift-type-subst.swift new file mode 100644 index 0000000000000..1f3922758bddd --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02030-std-function-func-swift-type-subst.swift @@ -0,0 +1,16 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol C { +typealias d.advance(s: C> [unowned self) +return """"ab""").b { +class func b(b, () -> Any in +protocol a { +} +enum a Any) { +} +protocol b { +let h : d>("""" diff --git a/validation-test/compiler_crashers_fixed/2031-llvm-foldingset-swift-boundgenerictype-nodeequals.swift b/validation-test/compiler_crashers_fixed/02031-llvm-foldingset-swift-boundgenerictype-nodeequals.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2031-llvm-foldingset-swift-boundgenerictype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/02031-llvm-foldingset-swift-boundgenerictype-nodeequals.swift diff --git a/validation-test/compiler_crashers_fixed/2032-swift-typechecker-resolveidentifiertype.swift b/validation-test/compiler_crashers_fixed/02032-swift-typechecker-resolveidentifiertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2032-swift-typechecker-resolveidentifiertype.swift rename to validation-test/compiler_crashers_fixed/02032-swift-typechecker-resolveidentifiertype.swift diff --git a/validation-test/compiler_crashers_fixed/2033-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/02033-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2033-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/02033-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/2034-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/02034-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2034-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/02034-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/2035-swift-constraints-constraintsystem-matchdeepequalitytypes.swift b/validation-test/compiler_crashers_fixed/02035-swift-constraints-constraintsystem-matchdeepequalitytypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2035-swift-constraints-constraintsystem-matchdeepequalitytypes.swift rename to validation-test/compiler_crashers_fixed/02035-swift-constraints-constraintsystem-matchdeepequalitytypes.swift diff --git a/validation-test/compiler_crashers_fixed/2036-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02036-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2036-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/02036-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/2037-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02037-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2037-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02037-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2038-llvm-bitstreamcursor-readvbr.swift b/validation-test/compiler_crashers_fixed/02038-llvm-bitstreamcursor-readvbr.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2038-llvm-bitstreamcursor-readvbr.swift rename to validation-test/compiler_crashers_fixed/02038-llvm-bitstreamcursor-readvbr.swift diff --git a/validation-test/compiler_crashers_fixed/2039-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02039-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2039-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02039-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/02040-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02040-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..991f10bb981cb --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02040-getselftypeforcontainer.swift @@ -0,0 +1,15 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol A : a { +protocol b : T, B +protocol B : Int { +func a([c: BooleanType)) +func f: A""") +protocol b : A> { +} +protocol A { +struct A diff --git a/validation-test/compiler_crashers_fixed/2043-std-function-func-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/02043-std-function-func-swift-constraints-solution-computesubstitutions.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2043-std-function-func-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/02043-std-function-func-swift-constraints-solution-computesubstitutions.swift diff --git a/validation-test/compiler_crashers_fixed/2044-swift-typechecker-typecheckpattern.swift b/validation-test/compiler_crashers_fixed/02044-swift-typechecker-typecheckpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2044-swift-typechecker-typecheckpattern.swift rename to validation-test/compiler_crashers_fixed/02044-swift-typechecker-typecheckpattern.swift diff --git a/validation-test/compiler_crashers_fixed/2045-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02045-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2045-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02045-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2046-swift-pattern-operator.swift b/validation-test/compiler_crashers_fixed/02046-swift-pattern-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2046-swift-pattern-operator.swift rename to validation-test/compiler_crashers_fixed/02046-swift-pattern-operator.swift diff --git a/validation-test/compiler_crashers_fixed/2047-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02047-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2047-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02047-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2048-swift-enumdecl-issimpleenum.swift b/validation-test/compiler_crashers_fixed/02048-swift-enumdecl-issimpleenum.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2048-swift-enumdecl-issimpleenum.swift rename to validation-test/compiler_crashers_fixed/02048-swift-enumdecl-issimpleenum.swift diff --git a/validation-test/compiler_crashers_fixed/2049-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/02049-swift-pattern-foreachvariable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2049-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/02049-swift-pattern-foreachvariable.swift diff --git a/validation-test/compiler_crashers_fixed/2050-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02050-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2050-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02050-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2051-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/02051-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2051-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/02051-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2052-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/02052-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2052-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/02052-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/2053-swift-modulefile-maybereadsubstitution.swift b/validation-test/compiler_crashers_fixed/02053-swift-modulefile-maybereadsubstitution.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2053-swift-modulefile-maybereadsubstitution.swift rename to validation-test/compiler_crashers_fixed/02053-swift-modulefile-maybereadsubstitution.swift diff --git a/validation-test/compiler_crashers_fixed/2054-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/02054-swift-diagnosticengine-flushactivediagnostic.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2054-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/02054-swift-diagnosticengine-flushactivediagnostic.swift diff --git a/validation-test/compiler_crashers_fixed/2055-llvm-foldingsetnodeid-operator.swift b/validation-test/compiler_crashers_fixed/02055-llvm-foldingsetnodeid-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2055-llvm-foldingsetnodeid-operator.swift rename to validation-test/compiler_crashers_fixed/02055-llvm-foldingsetnodeid-operator.swift diff --git a/validation-test/compiler_crashers_fixed/2056-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02056-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2056-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02056-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2057-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/02057-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2057-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/02057-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/2058-swift-constraints-constraintsystem-solvesimplified.swift b/validation-test/compiler_crashers_fixed/02058-swift-constraints-constraintsystem-solvesimplified.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2058-swift-constraints-constraintsystem-solvesimplified.swift rename to validation-test/compiler_crashers_fixed/02058-swift-constraints-constraintsystem-solvesimplified.swift diff --git a/validation-test/compiler_crashers_fixed/2059-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02059-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2059-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/02059-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/2060-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/02060-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2060-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/02060-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/2061-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/02061-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2061-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/02061-swift-constraints-constraintgraph-gatherconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/2062-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02062-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2062-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/02062-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/2063-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/02063-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2063-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/02063-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/2064-swift-diagnosticengine-diagnose.swift b/validation-test/compiler_crashers_fixed/02064-swift-diagnosticengine-diagnose.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2064-swift-diagnosticengine-diagnose.swift rename to validation-test/compiler_crashers_fixed/02064-swift-diagnosticengine-diagnose.swift diff --git a/validation-test/compiler_crashers_fixed/2065-swift-constraints-constraintsystem-getconstraintlocator.swift b/validation-test/compiler_crashers_fixed/02065-swift-constraints-constraintsystem-getconstraintlocator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2065-swift-constraints-constraintsystem-getconstraintlocator.swift rename to validation-test/compiler_crashers_fixed/02065-swift-constraints-constraintsystem-getconstraintlocator.swift diff --git a/validation-test/compiler_crashers_fixed/2066-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/02066-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2066-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/02066-swift-constraints-constraintsystem-getfixedtyperecursive.swift diff --git a/validation-test/compiler_crashers_fixed/2067-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02067-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2067-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/02067-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/02068-swift-parser-parsedeclfunc.swift b/validation-test/compiler_crashers_fixed/02068-swift-parser-parsedeclfunc.swift new file mode 100644 index 0000000000000..9265e3a0b9456 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02068-swift-parser-parsedeclfunc.swift @@ -0,0 +1,22 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +deinit { +return { +typealias R = B, range: Array() { +struct A? = """ +} +func c({ +return " +} +} +} +struct d()) +} +d +func d diff --git a/validation-test/compiler_crashers_fixed/2069-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/02069-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2069-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/02069-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/2072-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/02072-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2072-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/02072-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2073-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/02073-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2073-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/02073-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/2074-swift-constraints-constraintlocatorbuilder-trysimplifytoexpr.swift b/validation-test/compiler_crashers_fixed/02074-swift-constraints-constraintlocatorbuilder-trysimplifytoexpr.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2074-swift-constraints-constraintlocatorbuilder-trysimplifytoexpr.swift rename to validation-test/compiler_crashers_fixed/02074-swift-constraints-constraintlocatorbuilder-trysimplifytoexpr.swift diff --git a/validation-test/compiler_crashers_fixed/2075-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/02075-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2075-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/02075-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/2076-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/02076-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2076-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/02076-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/2077-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/02077-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2077-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/02077-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/2078-swift-parser-parsedeclinit.swift b/validation-test/compiler_crashers_fixed/02078-swift-parser-parsedeclinit.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2078-swift-parser-parsedeclinit.swift rename to validation-test/compiler_crashers_fixed/02078-swift-parser-parsedeclinit.swift diff --git a/validation-test/compiler_crashers_fixed/2079-swift-module-lookupvalue.swift b/validation-test/compiler_crashers_fixed/02079-swift-module-lookupvalue.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2079-swift-module-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/02079-swift-module-lookupvalue.swift diff --git a/validation-test/compiler_crashers_fixed/2080-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02080-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2080-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02080-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2081-swift-inouttype-get.swift b/validation-test/compiler_crashers_fixed/02081-swift-inouttype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2081-swift-inouttype-get.swift rename to validation-test/compiler_crashers_fixed/02081-swift-inouttype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2082-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/02082-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2082-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/02082-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/2084-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02084-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2084-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/02084-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/2085-swift-range-swift-nestedgenericparamlistiterator-swift-archetypetype.swift b/validation-test/compiler_crashers_fixed/02085-swift-range-swift-nestedgenericparamlistiterator-swift-archetypetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2085-swift-range-swift-nestedgenericparamlistiterator-swift-archetypetype.swift rename to validation-test/compiler_crashers_fixed/02085-swift-range-swift-nestedgenericparamlistiterator-swift-archetypetype.swift diff --git a/validation-test/compiler_crashers_fixed/2086-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/02086-swift-modulefile-getdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2086-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/02086-swift-modulefile-getdecl.swift diff --git a/validation-test/compiler_crashers_fixed/2087-swift-generictypeparamdecl-generictypeparamdecl.swift b/validation-test/compiler_crashers_fixed/02087-swift-generictypeparamdecl-generictypeparamdecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2087-swift-generictypeparamdecl-generictypeparamdecl.swift rename to validation-test/compiler_crashers_fixed/02087-swift-generictypeparamdecl-generictypeparamdecl.swift diff --git a/validation-test/compiler_crashers_fixed/2088-swift-constraints-constraintsystem-matchfunctiontypes.swift b/validation-test/compiler_crashers_fixed/02088-swift-constraints-constraintsystem-matchfunctiontypes.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2088-swift-constraints-constraintsystem-matchfunctiontypes.swift rename to validation-test/compiler_crashers_fixed/02088-swift-constraints-constraintsystem-matchfunctiontypes.swift diff --git a/validation-test/compiler_crashers_fixed/2089-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/02089-swift-typechecker-resolvetypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2089-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/02089-swift-typechecker-resolvetypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/2090-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02090-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2090-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02090-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2091-swift-constraints-constraintsystem-finalize.swift b/validation-test/compiler_crashers_fixed/02091-swift-constraints-constraintsystem-finalize.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2091-swift-constraints-constraintsystem-finalize.swift rename to validation-test/compiler_crashers_fixed/02091-swift-constraints-constraintsystem-finalize.swift diff --git a/validation-test/compiler_crashers_fixed/2092-swift-abstractstoragedecl-makecomputed.swift b/validation-test/compiler_crashers_fixed/02092-swift-abstractstoragedecl-makecomputed.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2092-swift-abstractstoragedecl-makecomputed.swift rename to validation-test/compiler_crashers_fixed/02092-swift-abstractstoragedecl-makecomputed.swift diff --git a/validation-test/compiler_crashers_fixed/2093-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/02093-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2093-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/02093-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2094-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/02094-swift-typechecker-resolvetypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2094-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/02094-swift-typechecker-resolvetypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/2095-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift b/validation-test/compiler_crashers_fixed/02095-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2095-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift rename to validation-test/compiler_crashers_fixed/02095-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift diff --git a/validation-test/compiler_crashers_fixed/2096-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/02096-swift-functiontype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2096-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/02096-swift-functiontype-get.swift diff --git a/validation-test/compiler_crashers_fixed/02097-swift-singlerawcomment-singlerawcomment.swift b/validation-test/compiler_crashers_fixed/02097-swift-singlerawcomment-singlerawcomment.swift new file mode 100644 index 0000000000000..d99aaca4e7afd --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02097-swift-singlerawcomment-singlerawcomment.swift @@ -0,0 +1,90 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +se C +} +} +return self.B) +class a!.a: c { +public var b : d where l.Type) { +func a() +} +var b) { +func d +d() { +} +let c : d { +} +} +} +func f: a { +var d == { } +return NSData([Byte]) +} +enum b = d +protocol a { +func a(T] = g, U) { +func f String { +} +} +func c) -> { +typealias A { +let t: Int = a +} +typealias F = g e Any, f, A, Any, g : String { +} +} +" +protocol a {} +class b, b { +get { +typealias d.startIndex, self.g : a { +} +var b(b(self) +let foo as a(n: b { +c: [T: NSManagedObject { +} +map(T>(n: Array) { +case C(Any) { +} +func c(c {} +func c(x, range.a: String { +var _ = b { +func c +} +func b[Byte] +case .A, k : B T : [l: d { self] { +var c, range.E == a"\(e!) +protocol f f = a

{ +} +} +}()] = b +static let a { +} +var e: a { +} +enum j { +} +protocol a { +func b: d: P { +c: B? = b> ((")(true { +typealias A : e() -> T diff --git a/validation-test/compiler_crashers_fixed/2102-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/02102-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2102-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/02102-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/2103-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/02103-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2103-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/02103-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/02104-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02104-resolvetypedecl.swift new file mode 100644 index 0000000000000..16761a63d7ee3 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02104-resolvetypedecl.swift @@ -0,0 +1,20 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func i: A? { +class func f: U : A> { +} +func f: a { +} +class f: NSObject { +} +struct d([1 +e = h> Any)(b[B diff --git a/validation-test/compiler_crashers_fixed/2118-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/02118-swift-typechecker-checkinheritanceclause.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2118-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/02118-swift-typechecker-checkinheritanceclause.swift diff --git a/validation-test/compiler_crashers_fixed/2119-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/02119-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2119-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/02119-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2120-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02120-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2120-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02120-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/02121-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02121-getselftypeforcontainer.swift new file mode 100644 index 0000000000000..ed72917854a2a --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02121-getselftypeforcontainer.swift @@ -0,0 +1,19 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol a { +protocol b { +typealias e : A,) -> T { +} +protocol A : b() { +func a: q l { +} +} +func b: U) { +} +} +} +func ^(start: a { diff --git a/validation-test/compiler_crashers_fixed/2122-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/02122-swift-modulefile-maybereadgenericparams.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2122-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/02122-swift-modulefile-maybereadgenericparams.swift diff --git a/validation-test/compiler_crashers_fixed/2123-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/02123-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2123-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/02123-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/2124-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/02124-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2124-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/02124-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/2125-swift-completegenerictyperesolver-resolvedependentmembertype.swift b/validation-test/compiler_crashers_fixed/02125-swift-completegenerictyperesolver-resolvedependentmembertype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2125-swift-completegenerictyperesolver-resolvedependentmembertype.swift rename to validation-test/compiler_crashers_fixed/02125-swift-completegenerictyperesolver-resolvedependentmembertype.swift diff --git a/validation-test/compiler_crashers_fixed/2126-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/02126-swift-metatypetype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2126-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/02126-swift-metatypetype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2127-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/02127-swift-modulefile-maybereadpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2127-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/02127-swift-modulefile-maybereadpattern.swift diff --git a/validation-test/compiler_crashers_fixed/2128-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/02128-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2128-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/02128-swift-nominaltypedecl-getdeclaredtypeincontext.swift diff --git a/validation-test/compiler_crashers_fixed/2129-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/02129-swift-clangmoduleunit-getimportedmodules.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2129-swift-clangmoduleunit-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/02129-swift-clangmoduleunit-getimportedmodules.swift diff --git a/validation-test/compiler_crashers_fixed/2130-vtable.swift b/validation-test/compiler_crashers_fixed/02130-vtable.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2130-vtable.swift rename to validation-test/compiler_crashers_fixed/02130-vtable.swift diff --git a/validation-test/compiler_crashers_fixed/2131-swift-parser-parsedeclclass.swift b/validation-test/compiler_crashers_fixed/02131-swift-parser-parsedeclclass.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2131-swift-parser-parsedeclclass.swift rename to validation-test/compiler_crashers_fixed/02131-swift-parser-parsedeclclass.swift diff --git a/validation-test/compiler_crashers_fixed/2132-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02132-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2132-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/02132-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/02133-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02133-resolvetypedecl.swift new file mode 100644 index 0000000000000..8589ea1566034 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02133-resolvetypedecl.swift @@ -0,0 +1,14 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class b : S.Generator.sr { +var b> ("], +if true { +class A : Any, AnyObject) -> U) { +} +protocol C { +} +struct Q { +} +public var b: A)) { +class A"foo"" +var a: b { +} +func b +protocol d : String { +} +typealias e : a { +func a"A? { +class A = diff --git a/validation-test/compiler_crashers_fixed/2138-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/02138-swift-modulefile-maybereadpattern.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2138-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/02138-swift-modulefile-maybereadpattern.swift diff --git a/validation-test/compiler_crashers_fixed/2139-swift-constraints-constraintgraphnode-addconstraint.swift b/validation-test/compiler_crashers_fixed/02139-swift-constraints-constraintgraphnode-addconstraint.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2139-swift-constraints-constraintgraphnode-addconstraint.swift rename to validation-test/compiler_crashers_fixed/02139-swift-constraints-constraintgraphnode-addconstraint.swift diff --git a/validation-test/compiler_crashers_fixed/2140-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02140-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2140-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/02140-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/2141-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/02141-swift-parser-skipsingle.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2141-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/02141-swift-parser-skipsingle.swift diff --git a/validation-test/compiler_crashers_fixed/2142-formatdiagnostictext.swift b/validation-test/compiler_crashers_fixed/02142-formatdiagnostictext.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2142-formatdiagnostictext.swift rename to validation-test/compiler_crashers_fixed/02142-formatdiagnostictext.swift diff --git a/validation-test/compiler_crashers_fixed/2143-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/02143-swift-structtype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2143-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/02143-swift-structtype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2144-swift-parser-parsestmt.swift b/validation-test/compiler_crashers_fixed/02144-swift-parser-parsestmt.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2144-swift-parser-parsestmt.swift rename to validation-test/compiler_crashers_fixed/02144-swift-parser-parsestmt.swift diff --git a/validation-test/compiler_crashers_fixed/2145-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/02145-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2145-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/02145-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/2146-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/02146-swift-type-transform.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2146-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/02146-swift-type-transform.swift diff --git a/validation-test/compiler_crashers_fixed/2147-swift-diagnosticengine-diagnose.swift b/validation-test/compiler_crashers_fixed/02147-swift-diagnosticengine-diagnose.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2147-swift-diagnosticengine-diagnose.swift rename to validation-test/compiler_crashers_fixed/02147-swift-diagnosticengine-diagnose.swift diff --git a/validation-test/compiler_crashers_fixed/2148-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/02148-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2148-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/02148-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/2149-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/02149-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2149-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/02149-swift-constraints-constraintgraph-gatherconstraints.swift diff --git a/validation-test/compiler_crashers_fixed/2150-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/02150-swift-typechecker-coercepatterntotype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2150-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/02150-swift-typechecker-coercepatterntotype.swift diff --git a/validation-test/compiler_crashers_fixed/2151-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/02151-swift-tupletype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2151-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/02151-swift-tupletype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2153-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/02153-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2153-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/02153-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/02154-swift-sourcefile-getcache.swift b/validation-test/compiler_crashers_fixed/02154-swift-sourcefile-getcache.swift new file mode 100644 index 0000000000000..b5532f85709c5 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02154-swift-sourcefile-getcache.swift @@ -0,0 +1,41 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +enum S T, AnyObject, Any) -> String { +} +typealias b { +} +protocol A { +var b = { +} +} +return x = b: b { +} +func c([c) -> Any) -> (g (bytes: a: A? = B) +func b() -> Any) -> Any) ->("foobar"cd"\() +func d.Generator.c { +func ^(x: NSObject { +typealias d.endIndex - range.h> Any) -> S : AnyObject> { +} +enum A { +struct c in x { +func i> { +} +} +} +} +} +func c) -> { +protocol a { +} +} +func b: d: A. diff --git a/validation-test/compiler_crashers_fixed/2155-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/02155-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2155-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/02155-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/2156-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/02156-swift-typebase-getcanonicaltype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2156-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/02156-swift-typebase-getcanonicaltype.swift diff --git a/validation-test/compiler_crashers_fixed/2157-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/02157-swift-nominaltypedecl-computetype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2157-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/02157-swift-nominaltypedecl-computetype.swift diff --git a/validation-test/compiler_crashers_fixed/2158-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02158-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2158-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02158-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2159-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/02159-swift-typechecker-typecheckexpression.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2159-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/02159-swift-typechecker-typecheckexpression.swift diff --git a/validation-test/compiler_crashers_fixed/2161-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02161-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2161-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02161-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2162-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/02162-swift-type-walk.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2162-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/02162-swift-type-walk.swift diff --git a/validation-test/compiler_crashers_fixed/2163-swift-parser-parseexprlist.swift b/validation-test/compiler_crashers_fixed/02163-swift-parser-parseexprlist.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2163-swift-parser-parseexprlist.swift rename to validation-test/compiler_crashers_fixed/02163-swift-parser-parseexprlist.swift diff --git a/validation-test/compiler_crashers_fixed/02164-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/02164-swift-typechecker-checksubstitutions.swift new file mode 100644 index 0000000000000..39007370e23ab --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02164-swift-typechecker-checksubstitutions.swift @@ -0,0 +1,16 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +struct d T : X.C(.B() -> == b(()) -> { +} +protocol c == B { +} +let g == B T> : a { +func a +() -> S) -> T.init() { +struct c: String { +} +public var b: d { +} +} +} +} +func c: C { diff --git a/validation-test/compiler_crashers_fixed/02195-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/02195-swift-nominaltypedecl-getdeclaredtypeincontext.swift new file mode 100644 index 0000000000000..dba650e7ae265 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02195-swift-nominaltypedecl-getdeclaredtypeincontext.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +protocol a { +private class A : A>], c: d where S a { +}(""" +return x } +func c(a diff --git a/validation-test/compiler_crashers_fixed/2196-swift-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/02196-swift-optional-swift-diagnostic-operator.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2196-swift-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/02196-swift-optional-swift-diagnostic-operator.swift diff --git a/validation-test/compiler_crashers_fixed/2197-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02197-resolvetypedecl.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2197-resolvetypedecl.swift rename to validation-test/compiler_crashers_fixed/02197-resolvetypedecl.swift diff --git a/validation-test/compiler_crashers_fixed/2198-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/02198-std-function-func-swift-constraints-constraintsystem-simplifytype.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2198-std-function-func-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/02198-std-function-func-swift-constraints-constraintsystem-simplifytype.swift diff --git a/validation-test/compiler_crashers_fixed/2199-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02199-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2199-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/02199-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/2200-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/02200-getselftypeforcontainer.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2200-getselftypeforcontainer.swift rename to validation-test/compiler_crashers_fixed/02200-getselftypeforcontainer.swift diff --git a/validation-test/compiler_crashers_fixed/2201-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/02201-std-function-func-swift-type-subst.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2201-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/02201-std-function-func-swift-type-subst.swift diff --git a/validation-test/compiler_crashers_fixed/2202-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/02202-swift-boundgenerictype-get.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2202-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/02202-swift-boundgenerictype-get.swift diff --git a/validation-test/compiler_crashers_fixed/2203-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/02203-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2203-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/02203-swift-constraints-constraintsystem-gettypeofmemberreference.swift diff --git a/validation-test/compiler_crashers_fixed/2204-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/02204-swift-clangmoduleunit-getadaptermodule.swift similarity index 100% rename from validation-test/compiler_crashers_fixed/2204-swift-clangmoduleunit-getadaptermodule.swift rename to validation-test/compiler_crashers_fixed/02204-swift-clangmoduleunit-getadaptermodule.swift diff --git a/validation-test/compiler_crashers_fixed/02205-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/02205-resolvetypedecl.swift new file mode 100644 index 0000000000000..65d4df4a1a6ed --- /dev/null +++ b/validation-test/compiler_crashers_fixed/02205-resolvetypedecl.swift @@ -0,0 +1,15 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +ic class A { +func f, range.E == b> Void>, k : A.d.init() { +typealias F = B() +func a: ExtensibleCollectionType>({ +print() -> == e([] +protocol b { +let start = ") +} +struct c o { - r q { -} -protocol p { - typealias m = q -} -m r : p { -} -func r (s: o) { -} -func r (s: s) { -} -m s

{ -} -class t : q { -} -class t { -} -protocol s { - func r() { - } -} -func t(s) ->

(() -> p) { -} -class q Self { - return b(self.dynamicType) - } -} -func b(t: AnyObject.Type) -> T! { - return nil -} diff --git a/validation-test/compiler_crashers_fixed/0277-swift-typechecker-getinterfacetypefrominternaltype.swift b/validation-test/compiler_crashers_fixed/0277-swift-typechecker-getinterfacetypefrominternaltype.swift deleted file mode 100644 index 35a9a9664b7ad..0000000000000 --- a/validation-test/compiler_crashers_fixed/0277-swift-typechecker-getinterfacetypefrominternaltype.swift +++ /dev/null @@ -1,47 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func n() -> (a, a -> a) -> a { - p m p.u = { -} - { - a) { - dc } -} -protocol n { -} -class p: n{ class func u {} -func t(a: Int = cb) { -} -let m = t -class m { - func a((x, m))(t: (x, a)) { - } -} -p w: Int -> Int = { -} -let dc: Int = { (o: Int, n: Int -> Int) -> Int r -}(u, w) -let b: Int = { o, n r -}(u, w) -protocol t : t { -} -func t() -> (y, y -> y) -> y { -} -protocol t { -} -protocol a : t { -} -protocol m : t { -} -protocol p { -} -n o : p { -} -func u (m: o) { -} -func u Int { -class A { -func g.b : Int { -typealias B() -init(false))() { -} -return d -} -case b { -var c: AnyObject.E == T>]((" -protocol P { -print() -> (n: A? = b U, b in a { -return { c: T>() { -return self.E == nil -} -import Foundation -enum A where T) ->(array: AnyObject, object1, AnyObject) -> [T: String { -} -let v: a = [T> Void>>>(c>Bool) -func call("A> Self { -protocol P { -typealias e == D>(false) -} -return nil -b: C) -> U, f.E -let c, V>(t: T) -> S("\() -> V>() -return self.d.b = F>() -let i: a { -var b in a { -typealias F -} -super.init(") -struct c = e: a = { -import Foundation -class func b: c> : C> () -typealias R = 0) -func b: NSObject { -typealias R -return g, U) -} -return $0 -struct e == F -func g.a("") -} -for b in -protocol A : T -enum S() { -} -} -import Foundation -self.d -f = 0 -} -} -} -}(t: T -> { -private let h> { -func a(c) { -} -if c == { c: B() -init ) -} -return nil -let g = { -typealias E -return [unowned self.init(g: T { -} -return g: A? { -let c(f(t: AnyObject, g: NSObject { -0 -class A : NSManagedObject { -protocol C { -d.Type) -> { -} -var e: C { -S(c -} -} -return $0) -func a(array: C>) { -struct D : A? = A? = Int -protocol c == "") -typealias h> U, object1, AnyObject) -> Void>() -> T) -> { -typealias E -struct e = { -protocol A { -import Foundation -} -return self.e where T>) -> Void>(x: P { -return b ()"A? = { -} -init() -var b { -} -} -struct e { -} -typealias h> T) -> { -var b = 0 -typealias F>: NSObject { -} -struct c == nil -return d -import Foundation -} -} -return "A> { -protocol P { -} -typealias R = T.d -} -let d -} -struct B : A"") -typealias h: I.h -} -typealias F = b -var b() -var f = B) -> { -} -} -func compose() -} -let d() { -} -enum S : a { -} -class b { -} -protocol c { - typealias g -} diff --git a/validation-test/compiler_crashers_fixed/0371-swift-archetypetype-setnestedtypes.swift b/validation-test/compiler_crashers_fixed/0371-swift-archetypetype-setnestedtypes.swift deleted file mode 100644 index b7720e7c94e4b..0000000000000 --- a/validation-test/compiler_crashers_fixed/0371-swift-archetypetype-setnestedtypes.swift +++ /dev/null @@ -1,41 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func g { -typealias R = b: a { -struct d T! { -} -static let t: d = b) -> Int = b -} -protocol P { -typealias e : a { -protocol a { -c(self.b = nil -if true { -func call(array: e: c: T where H.e where H.a -func b -} -typealias F = a -func call(x: A() -} -[T>("")("") -S) -> Int = nil -} -let d.B) { -} -protocol d = { -} -} -} -class func a(n: C { -} -protocol P { -struct e = { -} -let i: d { -} -typealias e : e = D> { -} -var b: Int diff --git a/validation-test/compiler_crashers_fixed/0440-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/0440-resolvetypedecl.swift deleted file mode 100644 index d11ad81603f13..0000000000000 --- a/validation-test/compiler_crashers_fixed/0440-resolvetypedecl.swift +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -let i: a { -func f: d { -let g = B(v: P { -} -} -struct B T : T where g() -print() { -typealias e { -} -protocol C { -typealias e = a -struct e = D>) { -} -protocol a { -let i: e) diff --git a/validation-test/compiler_crashers/06207-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/06207-swift-diagnosticengine-flushactivediagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/06207-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/06207-swift-diagnosticengine-flushactivediagnostic.swift index 0d88e58f63ce0..a602108198cfc 100644 --- a/validation-test/compiler_crashers/06207-swift-diagnosticengine-flushactivediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/06207-swift-diagnosticengine-flushactivediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/06252-swift-typechecker-conformstoprotocol.swift b/validation-test/compiler_crashers_fixed/06252-swift-typechecker-conformstoprotocol.swift new file mode 100644 index 0000000000000..39dfe99b58056 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/06252-swift-typechecker-conformstoprotocol.swift @@ -0,0 +1,7 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +enum S{init(){enum S:T diff --git a/validation-test/compiler_crashers_fixed/0645-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/0645-resolvetypedecl.swift deleted file mode 100644 index b14e609f1911c..0000000000000 --- a/validation-test/compiler_crashers_fixed/0645-resolvetypedecl.swift +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class func g(f: d = "A? = B(c: C> String { -struct d { -struct c { -struct A { -func c { -typealias F = A String { -protocol d : T] { -} -} -} -} -if true { -} -protocol c { -typealias f = a"\(AnyObject.init(a(b -case A>?) { -} -protocol a { -i() -> { -} -typealias R = f, ""] diff --git a/validation-test/compiler_crashers_fixed/0691-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/0691-swift-inflightdiagnostic.swift deleted file mode 100644 index 4c74396aba3fd..0000000000000 --- a/validation-test/compiler_crashers_fixed/0691-swift-inflightdiagnostic.swift +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -dynamic -) -func n() -> (w, w -> w) -> w { -o m o.q = { -} -{ -w) { -k } -} -protocol n { -class func q() -} -class o: n{ class func q {} -func p(e: Int = x) { -} -let c = p -c() -func r ==(r(t)) -protocol p : p { -} -protocol p { -class func c() -} -class e: p { -class func c() { } -} -(e() u p).v.c() -k e.w == l> { -} -func p(c: Any, init(b: c) { -: e, diff --git a/validation-test/compiler_crashers_fixed/0696-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/0696-std-function-func-swift-type-subst.swift deleted file mode 100644 index bb094edcacb25..0000000000000 --- a/validation-test/compiler_crashers_fixed/0696-std-function-func-swift-type-subst.swift +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol C { -protocol B { -typealias C = b() -} -typealias e where S) { -} -typealias b = B diff --git a/validation-test/compiler_crashers/07285-swift-astprinter-printname.swift b/validation-test/compiler_crashers_fixed/07285-swift-astprinter-printname.swift similarity index 83% rename from validation-test/compiler_crashers/07285-swift-astprinter-printname.swift rename to validation-test/compiler_crashers_fixed/07285-swift-astprinter-printname.swift index fe3501de78503..60e94473c51e7 100644 --- a/validation-test/compiler_crashers/07285-swift-astprinter-printname.swift +++ b/validation-test/compiler_crashers_fixed/07285-swift-astprinter-printname.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/0733-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/0733-resolvetypedecl.swift deleted file mode 100644 index e4be1e16967be..0000000000000 --- a/validation-test/compiler_crashers_fixed/0733-resolvetypedecl.swift +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func compose U>("a(b: NSManagedObject { -enum b { -} -func b(a() -func a: b diff --git a/validation-test/compiler_crashers_fixed/0774-unowned.swift b/validation-test/compiler_crashers_fixed/0774-unowned.swift deleted file mode 100644 index ae8416d299e04..0000000000000 --- a/validation-test/compiler_crashers_fixed/0774-unowned.swift +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol A : a { -} -protocol a { -func e: b { -} -func c(() -> Any) { -} -protocol A { -} -typealias d : e: C { diff --git a/validation-test/compiler_crashers_fixed/0780-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/0780-getselftypeforcontainer.swift deleted file mode 100644 index 3654783c67b8e..0000000000000 --- a/validation-test/compiler_crashers_fixed/0780-getselftypeforcontainer.swift +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -let h: d { -struct S : H) { -A, Any) { -} -} -init() -> { -} -let foo as String) -> [$0) -assert("cd"")() -protocol b { -protocol P { -let d() -> { -} -typealias A : a : a { -enum b = true as a") -func a) -enum A { -} -} -struct c { -} -} -case c: a { -} -let a { -protocol b = g.Element>() { c> String) -} -} -override init(() -> (A) { -} -protocol c { -func a(b diff --git a/validation-test/compiler_crashers_fixed/0787-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/0787-getselftypeforcontainer.swift deleted file mode 100644 index 9fa61ff9c953b..0000000000000 --- a/validation-test/compiler_crashers_fixed/0787-getselftypeforcontainer.swift +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct B { -} -typealias R = compose U -> { -} -let c in c == c> { -var b(n: T) -> { -} -var e> { -} -} -protocol d : b = B String { -} -protocol a = e: A { -case .h: d { -} -typealias b { -typealias A { -} -} -} -var f : SequenceType where A, U) -> Bool { -print() -} -class A { -struct c in c { -enum a") -} -protocol A : a { -func a(T diff --git a/validation-test/compiler_crashers_fixed/0805-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/0805-swift-constraints-constraintsystem-opengeneric.swift deleted file mode 100644 index e25dba470880f..0000000000000 --- a/validation-test/compiler_crashers_fixed/0805-swift-constraints-constraintsystem-opengeneric.swift +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -enum S { -return b diff --git a/validation-test/compiler_crashers_fixed/0822-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/0822-getselftypeforcontainer.swift deleted file mode 100644 index 044ccbdcacc7f..0000000000000 --- a/validation-test/compiler_crashers_fixed/0822-getselftypeforcontainer.swift +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol B : B:T.j diff --git a/validation-test/compiler_crashers_fixed/0902-c.swift b/validation-test/compiler_crashers_fixed/0902-c.swift deleted file mode 100644 index 91d32b20f09b5..0000000000000 --- a/validation-test/compiler_crashers_fixed/0902-c.swift +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse - -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -enum S(T>(true as String -protocol A { -enum a { -} -} -extension A diff --git a/validation-test/compiler_crashers_fixed/0924-swift-parser-consumetoken.swift b/validation-test/compiler_crashers_fixed/0924-swift-parser-consumetoken.swift deleted file mode 100644 index 8508351c0f63b..0000000000000 --- a/validation-test/compiler_crashers_fixed/0924-swift-parser-consumetoken.swift +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct A { -let a { -} -var b: Array A { -} -return !.init(h: P { -} -func f { -protocol c { -} -} -typealias f = { -func a diff --git a/validation-test/compiler_crashers/09354-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/09354-swift-nominaltypedecl-computetype.swift similarity index 83% rename from validation-test/compiler_crashers/09354-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/09354-swift-nominaltypedecl-computetype.swift index 70eeee2b5d0f4..91984b8b8eb31 100644 --- a/validation-test/compiler_crashers/09354-swift-nominaltypedecl-computetype.swift +++ b/validation-test/compiler_crashers_fixed/09354-swift-nominaltypedecl-computetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/09385-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/09385-swift-structtype-get.swift similarity index 82% rename from validation-test/compiler_crashers/09385-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/09385-swift-structtype-get.swift index 8d99147e79d08..2aa7f3313d83d 100644 --- a/validation-test/compiler_crashers/09385-swift-structtype-get.swift +++ b/validation-test/compiler_crashers_fixed/09385-swift-structtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/0944-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/0944-std-function-func-swift-type-subst.swift deleted file mode 100644 index 0c56ef45a08f8..0000000000000 --- a/validation-test/compiler_crashers_fixed/0944-std-function-func-swift-type-subst.swift +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol P { -class func d(Any) -> { -} -protocol a { -typealias F = e: a { -} -} -typealias e where g -struct B() -> Void>(b(bytes: a { -}(T.startIndex) -super.B>) in x in 0)) -let h: a { diff --git a/validation-test/compiler_crashers_fixed/0949-d.swift b/validation-test/compiler_crashers_fixed/0949-d.swift deleted file mode 100644 index 6c180af5d4538..0000000000000 --- a/validation-test/compiler_crashers_fixed/0949-d.swift +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol a { -func a(self.C) { -switch x in x in x { -} -} -protocol c { -S) -> { -class b { -typealias A { -} -} -} -typealias A : a { -struct X ((") -} -} -func f: a { diff --git a/validation-test/compiler_crashers_fixed/0958-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/0958-swift-nominaltypedecl-getdeclaredtypeincontext.swift deleted file mode 100644 index 532788a4b91a2..0000000000000 --- a/validation-test/compiler_crashers_fixed/0958-swift-nominaltypedecl-getdeclaredtypeincontext.swift +++ /dev/null @@ -1,40 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func q() -> (dc, dc -> dc) -> dc { -t m t.w = { -} -{ -dc) { -k } -} -protocol q { -} -protocol A { -func b(b: X.s) { -} -y(m: x) { -} -func v() -> [dc] { -} -class b : v { -} -class b { -} -protocol dc { -} -class A: A { -} -class r : C { -} -func ^(v: q, o) -> o { -} -class v { -} -protocol b { -} -struct dc : b diff --git a/validation-test/compiler_crashers/09650-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/09650-swift-typebase-getcanonicaltype.swift similarity index 80% rename from validation-test/compiler_crashers/09650-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/09650-swift-typebase-getcanonicaltype.swift index 7bf274b3aed7d..de500f1a155c1 100644 --- a/validation-test/compiler_crashers/09650-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/09650-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/0973-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/0973-std-function-func-swift-type-subst.swift deleted file mode 100644 index 4b5002d4f0020..0000000000000 --- a/validation-test/compiler_crashers_fixed/0973-std-function-func-swift-type-subst.swift +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol d : c { -protocol a { -return { -return { c(") -typealias R = e: B, g.d diff --git a/validation-test/compiler_crashers/09990-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/09990-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/09990-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/09990-std-function-func-swift-type-subst.swift index bf5729bdfec48..9c14e0319c2f6 100644 --- a/validation-test/compiler_crashers/09990-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/09990-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/10023-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/10023-swift-typebase-getcanonicaltype.swift similarity index 80% rename from validation-test/compiler_crashers/10023-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/10023-swift-typebase-getcanonicaltype.swift index 4686322a69d41..e1f28caa3499e 100644 --- a/validation-test/compiler_crashers/10023-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/10023-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/10248-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/10248-swift-streamprinter-printtext.swift similarity index 80% rename from validation-test/compiler_crashers/10248-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/10248-swift-streamprinter-printtext.swift index ad72e635f1021..8d26bb26b74a5 100644 --- a/validation-test/compiler_crashers/10248-swift-streamprinter-printtext.swift +++ b/validation-test/compiler_crashers_fixed/10248-swift-streamprinter-printtext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/1031-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/1031-getselftypeforcontainer.swift deleted file mode 100644 index a86b70002f5e1..0000000000000 --- a/validation-test/compiler_crashers_fixed/1031-getselftypeforcontainer.swift +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol b : C { -} -let start = b, let t.c { -typealias d>(n: b { -protocol C = 0] = """\())] = c: e? = T) -> A { -} -protocol A : a { -} -protocol a { -func e: b { -} -func c(() -> Any) { -} -protocol A { -} -typealias d : e: C { diff --git a/validation-test/compiler_crashers_fixed/1061-swift-typebase-gettypeofmember.swift b/validation-test/compiler_crashers_fixed/1061-swift-typebase-gettypeofmember.swift deleted file mode 100644 index 8a30bbb22bc97..0000000000000 --- a/validation-test/compiler_crashers_fixed/1061-swift-typebase-gettypeofmember.swift +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol A : l.c { -typealias d>(Any) { -return """"".B) -} -extension A { -protocol d == true } -enum a: T, A { diff --git a/validation-test/compiler_crashers_fixed/1066-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/1066-swift-typebase-getcanonicaltype.swift deleted file mode 100644 index 427db03a2cdee..0000000000000 --- a/validation-test/compiler_crashers_fixed/1066-swift-typebase-getcanonicaltype.swift +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol b { -struct e = e> () { -class C) { -} -} -class A { -func x(seq: Int = Swift.Generator.d(b { -} -typealias d>(() -> String { -func c, """ -protocol A { -}) -protocol a { -} -typealias e : d = F>) -} -} -var e(b diff --git a/validation-test/compiler_crashers_fixed/1102-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1102-resolvetypedecl.swift deleted file mode 100644 index 27e5c12de3aec..0000000000000 --- a/validation-test/compiler_crashers_fixed/1102-resolvetypedecl.swift +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func c() -> (e -> e) -> e { -e, e -> e) ->)func d(f: b) -> (() -> e) -> b { -struct c { -var b: [c] { -} -protocol a { -} -class b: a { -} -func f(b: T) { -} -func e() { -} -} -protocol c : b { func b -otocol A { -} -struct } -} -class a { -} -protocol b { -typealias d -typealias e = a, d> -} -struct c { -let enum S : P { -func f() -> T -> T { -return { x in x 1 { -} -} -class A { -class func a() -> String { -let d: String = { -}() -} -} -s} -} -class d : e { -} -class d { -} -protocol i { -} -protocol e { -} -protocol i : d { func d diff --git a/validation-test/compiler_crashers_fixed/1170-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/1170-getselftypeforcontainer.swift deleted file mode 100644 index a0d7027a7d667..0000000000000 --- a/validation-test/compiler_crashers_fixed/1170-getselftypeforcontainer.swift +++ /dev/null @@ -1,60 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class k: d { -var f: g -init(f: g) { -l. d { -typealias j = je: Int -> Int = { -} -let d: Int = { c, b in -}(f, e) -} -class d { -func l(l: j) { -} -func i(k: b) -> (() -> j) -> b { -} -class j { -func y((Any, j))(v: (Any, AnyObject)) { -} -} -func w(j: () -> ()) { -} -class v { -l _ = w() { -} -} -func v() -> (x, x -> x) -> x { -l y j s { -} -o l { -} -y q { -} -o n { -} -class r { -func s() -> p { -} -} -class w: r, n { -} -func b : e { -} -class d { -} -protocol i { -} -protocol e { -} -protocol i : d { func d diff --git a/validation-test/compiler_crashers_fixed/1185-swift-parser-parsetypeidentifier.swift b/validation-test/compiler_crashers_fixed/1185-swift-parser-parsetypeidentifier.swift deleted file mode 100644 index 70e0fca454a70..0000000000000 --- a/validation-test/compiler_crashers_fixed/1185-swift-parser-parsetypeidentifier.swift +++ /dev/null @@ -1,94 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func b : r { -func j(j: j.n) { -} -} -enum q { let k: v -} -protocol y { -} -struct D : y { -func y { -} -} -func l(m: (l, c) -> c) -> (l, c) -> c { -f { i -}, k) -class l { -class func m { -b let k: String = { -}() -struct q { -} -o q: n = { m, i j -l { -k m p { -} -struct j { -} -func a() -> [j] { -} -func f() -> (l, l -> l) -> l { -l j l.n = { -} -{ -l) { -n } -} -protocol f { -} -class l: f{ class func n {} -func a() { -b b { -} -} -class a { -} -protocol b { -} -struct j : b { -} -enum e : d { -func c() -> b { -} -} -protocol d { -} -enum A : String { -} -if c == .b { -} -struct c { -var b: [c] { -g []e f() { -} -} -protocol c : b { func b -class j { -func y((Any, j))(v: (Any, AnyObject)) { -} diff --git a/validation-test/compiler_crashers_fixed/1198-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1198-resolvetypedecl.swift deleted file mode 100644 index 4b9fbf0d86721..0000000000000 --- a/validation-test/compiler_crashers_fixed/1198-resolvetypedecl.swift +++ /dev/null @@ -1,67 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func a(x: Any, y: Any) -> (((Any, Any) -> Any) -> Any) { -return { -} -struct X : A { -func b(b: X.Type) { -} -} -class d: NSObject { -init(b: c) { -} -} -protocol a { -} -class b : a { -} -class b { -} -protocol c { -} -protocol a : a { -} -class A : A { -} -class B : C { -} -class c { -func b((Any, c))(a: (Any, AnyObject)) { -} -} -protocol b { -} -struct c { -func e() { -} -} -func d == b.Generat(() -> d) { -} -protocol A { -} -class B { -func d() -> String { -} -} -class C: B, A { -override func d() -> String { -} -func c() -> String { -} -} -func e(t: T) { -} -enum S : P { -func f() -> T -> T { -} -} -protocol P { -} -func a(b: Int = 0) { -} -struct c ()) -func p(l: Any, g: Any) -> (((Any, Any) -> Any) -> Any) { -return { -(p: (Any, Any) -> Any) -> Any in -func n { -} -protocol e { -} -func f BooleanType>(b: T) { -} -f( func b(b: X.Type) { -} -class d : e { -} -class d { -} -protocol i { -} -protocol e { -} -protocol i : d diff --git a/validation-test/compiler_crashers_fixed/1274-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1274-resolvetypedecl.swift deleted file mode 100644 index e0d29059fa04d..0000000000000 --- a/validation-test/compiler_crashers_fixed/1274-resolvetypedecl.swift +++ /dev/null @@ -1,35 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func b(z: (((Any, Any) -> Any) -> Any)) -> Any { -return z({ -(p: Any, q:Any) -> Any in -nType, Bool) -> Bool { -} -protocol A { -} -class C { -init (e: A.B) { -} -} -struct d { -} -protocol e { -} -func b(c) -> (() -> d) { -} -protocol A { -} -struct X : A { -func b(b: X.Type) { -} -} -protocol a { -} -class b : a { -} -struct c { diff --git a/validation-test/compiler_crashers_fixed/1291-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/1291-swift-type-walk.swift deleted file mode 100644 index 8f68f25249c4f..0000000000000 --- a/validation-test/compiler_crashers_fixed/1291-swift-type-walk.swift +++ /dev/null @@ -1,71 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func f() -> (e, e -> e) -> e { -{ -{ -} -} -protocol f { -} -class e: f { -class funT>: NSObject { -init(foo: T) { -B>(t: T) { -} x -x) { -} -class a { -var _ = i() { -} -} -func i(c: () -> ()) { -} -class a { -var _ = i() { -} -} -} -class d : e { -} -class d { -} -protocol i { -} -} -func n() { -b b { -} -} -func n(j: Any, t: Any) -> (((Any, Any) -> Any) -> Any) { -k { -} -} -var d = b -protocol a { -} -protocol b : a { -} -protocol c : a { -} -protocol d { -} -struct e : d { -} -func i (n: k) { -} -func i (n: l) { -} -protocol b { -} -struct c { -func e() { -} -} -struct c { -} -func b(g: f) -> (()-> e) -> i diff --git a/validation-test/compiler_crashers_fixed/1296-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1296-resolvetypedecl.swift deleted file mode 100644 index e58b027473c96..0000000000000 --- a/validation-test/compiler_crashers_fixed/1296-resolvetypedecl.swift +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func f() -> (l, l -> l) -> l { -l j l.n = { -} -{ -l) { -n } -} -protocol f { -} -class l: f{ class func n {} -func a() { -b b { -} -} -class a { -} -protocol b { -} -struct j : b { -} -typealias -d = i -} -class d : e { -} -class d { -} -protocol i { -} -protocol e { -} -protocol i : d { diff --git a/validation-test/compiler_crashers_fixed/1299-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1299-resolvetypedecl.swift deleted file mode 100644 index fa1debe5274d2..0000000000000 --- a/validation-test/compiler_crashers_fixed/1299-resolvetypedecl.swift +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class a { -} -class i: d{ class func f {} -func c() -> (i, i -> i) -> i { -k b k.i = { -} -{ -i) { -k } -} -protocol c { -} -class k: c{ class func i { -} -}lass func c() -} -var x1 = 1 -=1 as a=1 diff --git a/validation-test/compiler_crashers/13000-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/13000-swift-constraints-constraintsystem-matchtypes.swift similarity index 83% rename from validation-test/compiler_crashers/13000-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/13000-swift-constraints-constraintsystem-matchtypes.swift index 6108474dc8c51..cae1998ebc9b3 100644 --- a/validation-test/compiler_crashers/13000-swift-constraints-constraintsystem-matchtypes.swift +++ b/validation-test/compiler_crashers_fixed/13000-swift-constraints-constraintsystem-matchtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/1307-swift-clangmoduleunit-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/1307-swift-clangmoduleunit-getimportedmodules.swift deleted file mode 100644 index f2b17ef3569c0..0000000000000 --- a/validation-test/compiler_crashers_fixed/1307-swift-clangmoduleunit-getimportedmodules.swift +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -import Foundation -func n() -> (w, w -> w) -> w { -o m o.q = { -} -{ -w) { -k } -} -protocol n { -} -class o: n{ class func q {} -func p(e: Int = x) { -} -let c = p -protocol p : p { -} -protocol p { diff --git a/validation-test/compiler_crashers_fixed/1320-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1320-resolvetypedecl.swift deleted file mode 100644 index c607088efd4b5..0000000000000 --- a/validation-test/compiler_crashers_fixed/1320-resolvetypedecl.swift +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct c T -func g Any))" -typealias A : d { -struct d.init() -> Any, e> S) { -} -protocol c { -struct c(x: a { -} -self)() { -} -} -typealias f = A> (Any) { -} -} -} -protocol b { -struct A { -} -func b: C { -func f: (") -typealias f : b.E == diff --git a/validation-test/compiler_crashers/13737-swift-availabilityattr-isunavailable.swift b/validation-test/compiler_crashers_fixed/13737-swift-availabilityattr-isunavailable.swift similarity index 81% rename from validation-test/compiler_crashers/13737-swift-availabilityattr-isunavailable.swift rename to validation-test/compiler_crashers_fixed/13737-swift-availabilityattr-isunavailable.swift index ee5d01c17c360..9fc24fada7e76 100644 --- a/validation-test/compiler_crashers/13737-swift-availabilityattr-isunavailable.swift +++ b/validation-test/compiler_crashers_fixed/13737-swift-availabilityattr-isunavailable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/1413-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/1413-std-function-func-swift-constraints-constraintsystem-simplifytype.swift deleted file mode 100644 index fef8e7a18b17b..0000000000000 --- a/validation-test/compiler_crashers_fixed/1413-std-function-func-swift-constraints-constraintsystem-simplifytype.swift +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class A { -func c) -> Self { -} -} -} -} -var b: b { -let start = c: Se diff --git a/validation-test/compiler_crashers_fixed/1424-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/1424-getselftypeforcontainer.swift deleted file mode 100644 index eed04744a82be..0000000000000 --- a/validation-test/compiler_crashers_fixed/1424-getselftypeforcontainer.swift +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -let x { -protocol a { -func f Any) { -} -protocol A { -typealias B : b(v: d.h == [[]]() -> String { -return "[Byte]) -func b: C = " -} -} -class B, T) -> { -} -var b, range: a { diff --git a/validation-test/compiler_crashers_fixed/1524-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/1524-getselftypeforcontainer.swift deleted file mode 100644 index 0945e7527a228..0000000000000 --- a/validation-test/compiler_crashers_fixed/1524-getselftypeforcontainer.swift +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func a() -> { -protocol c { -enum a -protocol a { -class func b() -typealias f : b diff --git a/validation-test/compiler_crashers_fixed/1527-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1527-resolvetypedecl.swift deleted file mode 100644 index e38f365a5e8b9..0000000000000 --- a/validation-test/compiler_crashers_fixed/1527-resolvetypedecl.swift +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -private class a -} -func b(t: C { diff --git a/validation-test/compiler_crashers_fixed/1571-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/1571-swift-type-walk.swift deleted file mode 100644 index 84ab804cb1955..0000000000000 --- a/validation-test/compiler_crashers_fixed/1571-swift-type-walk.swift +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse - -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class B diff --git a/validation-test/compiler_crashers_fixed/1587-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/1587-swift-nominaltypedecl-getdeclaredtypeincontext.swift deleted file mode 100644 index 0e42991d2b1f3..0000000000000 --- a/validation-test/compiler_crashers_fixed/1587-swift-nominaltypedecl-getdeclaredtypeincontext.swift +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class B(AnyObject> U -> : P> { -return ") -class func a { -} -func a: B : CollectionType where g(c : (" -protocol A { -protocol d : C diff --git a/validation-test/compiler_crashers_fixed/1651-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/1651-getselftypeforcontainer.swift deleted file mode 100644 index 31bc8e2ff439d..0000000000000 --- a/validation-test/compiler_crashers_fixed/1651-getselftypeforcontainer.swift +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - - Any) -> V, length: AnyObject) { -let i<1 { -protocol a { -return { c: (Any) -> String { -extension NSSet { -} -} -typealias f : a { -} -} -} -print().c where A, a(T, A = { } -struct c in 0.Type -struct S String -} -case C(start: b in c = i() { -} -func ^([c] = T: T -} -enum S { -} -func a((a!(() -> d -typealias d.b { -switch x }) -} -func compose() -> S : C(h: c: c("] -} -class B (array: P> Any) { -protocol B : B diff --git a/validation-test/compiler_crashers_fixed/1696-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/1696-getselftypeforcontainer.swift deleted file mode 100644 index 2882b399d4002..0000000000000 --- a/validation-test/compiler_crashers_fixed/1696-getselftypeforcontainer.swift +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -var f : AnyObject, AnyObject, range: a { -e where B { -return m: String { -func g T -> Int { -} -} -} -print() -> { -} -protocol a { -protocol A { -typealias A : a: SequenceType where T>(" -func a -return x in x } -func a: A, g diff --git a/validation-test/compiler_crashers_fixed/1704-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/1704-getselftypeforcontainer.swift deleted file mode 100644 index d535f442f4b9c..0000000000000 --- a/validation-test/compiler_crashers_fixed/1704-getselftypeforcontainer.swift +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct B(" -} -var f = c: diff --git a/validation-test/compiler_crashers_fixed/1739-swift-constraints-constraintsystem-solvesimplified.swift b/validation-test/compiler_crashers_fixed/1739-swift-constraints-constraintsystem-solvesimplified.swift deleted file mode 100644 index 2d97b9d675270..0000000000000 --- a/validation-test/compiler_crashers_fixed/1739-swift-constraints-constraintsystem-solvesimplified.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class a { -} -func f Bool { -class A { -func c: a { -print() -> V>Bool) { -print(T>() { -} -func f((v: BooleanType>Bool]() -}() { c>(z(b() diff --git a/validation-test/compiler_crashers_fixed/1783-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/1783-getselftypeforcontainer.swift deleted file mode 100644 index 8614c34c179d8..0000000000000 --- a/validation-test/compiler_crashers_fixed/1783-getselftypeforcontainer.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol c { -protocol b { -func a) -typealias d: a { -} -} -} -class A { -let end = c] diff --git a/validation-test/compiler_crashers_fixed/1807-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1807-resolvetypedecl.swift deleted file mode 100644 index 9dec679be010e..0000000000000 --- a/validation-test/compiler_crashers_fixed/1807-resolvetypedecl.swift +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol b { -enum S String { -return { self.R -protocol A { -})) -} -} -func b -} -} -var e(true as a: St diff --git a/validation-test/compiler_crashers_fixed/1857-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/1857-std-function-func-swift-type-subst.swift deleted file mode 100644 index 2ce24d20e137f..0000000000000 --- a/validation-test/compiler_crashers_fixed/1857-std-function-func-swift-type-subst.swift +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func g() -> T.c() { -return ""ab"] -} -typealias g { -} -class func d -enum A = T) -> String { -func a")() -> Any, () -> Void>(bytes: X T : c, Any, A { -class B == d..b["A -class a { -func b T, q:Any) { -func g: NSObject { -struct d.E == Swift.h: T) { -typealias F = c: S () { -} -} -if true { -} -} -init { -f: A { -let a { -var b: A? = Swift.c, T : (c]).startIndex)") -} -struct c) -> U) { -} -} -protocol P { -} -func a: String { -pri diff --git a/validation-test/compiler_crashers_fixed/1890-swift-clangmoduleunit-getadaptermodule.swift b/validation-test/compiler_crashers_fixed/1890-swift-clangmoduleunit-getadaptermodule.swift deleted file mode 100644 index 27256fcc48178..0000000000000 --- a/validation-test/compiler_crashers_fixed/1890-swift-clangmoduleunit-getadaptermodule.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -import Foundation -protocol c { -protocol a : a { -func f { -assert(.d.init(" -} -class func a: b: b diff --git a/validation-test/compiler_crashers_fixed/1897-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/1897-resolvetypedecl.swift deleted file mode 100644 index 0584217a6ebb6..0000000000000 --- a/validation-test/compiler_crashers_fixed/1897-resolvetypedecl.swift +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -let c { -struct A { -func g> T { -})) -var b: A.startIndex, range.advance() -} -struct A String { -} -protocol e where I) ->, Any, e where f))))-> { -} -var d { -} -func e: a { -func b: X("ab"") -protocol b { -} -typealias b : b: Int { diff --git a/validation-test/compiler_crashers_fixed/1958-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/1958-std-function-func-swift-type-subst.swift deleted file mode 100644 index b24c8f6e7dff9..0000000000000 --- a/validation-test/compiler_crashers_fixed/1958-std-function-func-swift-type-subst.swift +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -let b { -protocol a { -func i() -> e: ExtensibleCollectionType>([0x31] = 0 -for (" -protocol a { -var d : NSObject { -} -let v: e> Any) -> Any in -protocol a { -} -} -typealias e : d = a(c { diff --git a/validation-test/compiler_crashers_fixed/2011-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/2011-swift-lexer-lexidentifier.swift deleted file mode 100644 index 881ed9e93fda3..0000000000000 --- a/validation-test/compiler_crashers_fixed/2011-swift-lexer-lexidentifier.swift +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class c Void>>(e> { -typealias f = [Int>) { -typealias f = B>) { -} -}) -protocol a { -var b, (s: B, T : H.init(array: d = f(g -({ -} -struct c { -} -} -enum S) { -} -} -func diff --git a/validation-test/compiler_crashers_fixed/2040-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/2040-getselftypeforcontainer.swift deleted file mode 100644 index 10a87eb42d648..0000000000000 --- a/validation-test/compiler_crashers_fixed/2040-getselftypeforcontainer.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol A : a { -protocol b : T, B -protocol B : Int { -func a([c: BooleanType)) -func f: A""") -protocol b : A> { -} -protocol A { -struct A diff --git a/validation-test/compiler_crashers_fixed/2068-swift-parser-parsedeclfunc.swift b/validation-test/compiler_crashers_fixed/2068-swift-parser-parsedeclfunc.swift deleted file mode 100644 index f2590679b116c..0000000000000 --- a/validation-test/compiler_crashers_fixed/2068-swift-parser-parsedeclfunc.swift +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -deinit { -return { -typealias R = B, range: Array() { -struct A? = """ -} -func c({ -return " -} -} -} -struct d()) -} -d -func d diff --git a/validation-test/compiler_crashers_fixed/2097-swift-singlerawcomment-singlerawcomment.swift b/validation-test/compiler_crashers_fixed/2097-swift-singlerawcomment-singlerawcomment.swift deleted file mode 100644 index d4c31d6e5cacc..0000000000000 --- a/validation-test/compiler_crashers_fixed/2097-swift-singlerawcomment-singlerawcomment.swift +++ /dev/null @@ -1,91 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -se C -} -} -return self.B) -class a!.a: c { -public var b : d where l.Type) { -func a() -} -var b) { -func d -d() { -} -let c : d { -} -} -} -func f: a { -var d == { } -return NSData([Byte]) -} -enum b = d -protocol a { -func a(T] = g, U) { -func f String { -} -} -func c) -> { -typealias A { -let t: Int = a -} -typealias F = g e Any, f, A, Any, g : String { -} -} -" -protocol a {} -class b, b { -get { -typealias d.startIndex, self.g : a { -} -var b(b(self) -let foo as a(n: b { -c: [T: NSManagedObject { -} -map(T>(n: Array) { -case C(Any) { -} -func c(c {} -func c(x, range.a: String { -var _ = b { -func c -} -func b[Byte] -case .A, k : B T : [l: d { self] { -var c, range.E == a"\(e!) -protocol f f = a

{ -} -} -}()] = b -static let a { -} -var e: a { -} -enum j { -} -protocol a { -func b: d: P { -c: B? = b> ((")(true { -typealias A : e() -> T diff --git a/validation-test/compiler_crashers_fixed/2104-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/2104-resolvetypedecl.swift deleted file mode 100644 index 65fdfec2e3727..0000000000000 --- a/validation-test/compiler_crashers_fixed/2104-resolvetypedecl.swift +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -func i: A? { -class func f: U : A> { -} -func f: a { -} -class f: NSObject { -} -struct d([1 -e = h> Any)(b[B diff --git a/validation-test/compiler_crashers_fixed/2121-getselftypeforcontainer.swift b/validation-test/compiler_crashers_fixed/2121-getselftypeforcontainer.swift deleted file mode 100644 index 13c26dd6abd4d..0000000000000 --- a/validation-test/compiler_crashers_fixed/2121-getselftypeforcontainer.swift +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol a { -protocol b { -typealias e : A,) -> T { -} -protocol A : b() { -func a: q l { -} -} -func b: U) { -} -} -} -func ^(start: a { diff --git a/validation-test/compiler_crashers_fixed/2133-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/2133-resolvetypedecl.swift deleted file mode 100644 index 1b37aef2408a0..0000000000000 --- a/validation-test/compiler_crashers_fixed/2133-resolvetypedecl.swift +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -class b : S.Generator.sr { -var b> ("], -if true { -class A : Any, AnyObject) -> U) { -} -protocol C { -} -struct Q { -} -public var b: A)) { -class A"foo"" -var a: b { -} -func b -protocol d : String { -} -typealias e : a { -func a"A? { -class A = diff --git a/validation-test/compiler_crashers_fixed/2154-swift-sourcefile-getcache.swift b/validation-test/compiler_crashers_fixed/2154-swift-sourcefile-getcache.swift deleted file mode 100644 index b6229e270c0ee..0000000000000 --- a/validation-test/compiler_crashers_fixed/2154-swift-sourcefile-getcache.swift +++ /dev/null @@ -1,42 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -enum S T, AnyObject, Any) -> String { -} -typealias b { -} -protocol A { -var b = { -} -} -return x = b: b { -} -func c([c) -> Any) -> (g (bytes: a: A? = B) -func b() -> Any) -> Any) ->("foobar"cd"\() -func d.Generator.c { -func ^(x: NSObject { -typealias d.endIndex - range.h> Any) -> S : AnyObject> { -} -enum A { -struct c in x { -func i> { -} -} -} -} -} -func c) -> { -protocol a { -} -} -func b: d: A. diff --git a/validation-test/compiler_crashers_fixed/2164-swift-typechecker-checksubstitutions.swift b/validation-test/compiler_crashers_fixed/2164-swift-typechecker-checksubstitutions.swift deleted file mode 100644 index f179c53569106..0000000000000 --- a/validation-test/compiler_crashers_fixed/2164-swift-typechecker-checksubstitutions.swift +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -struct d T : X.C(.B() -> == b(()) -> { -} -protocol c == B { -} -let g == B T> : a { -func a -() -> S) -> T.init() { -struct c: String { -} -public var b: d { -} -} -} -} -func c: C { diff --git a/validation-test/compiler_crashers_fixed/2195-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/2195-swift-nominaltypedecl-getdeclaredtypeincontext.swift deleted file mode 100644 index 96cf0eabf5ba6..0000000000000 --- a/validation-test/compiler_crashers_fixed/2195-swift-nominaltypedecl-getdeclaredtypeincontext.swift +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -protocol a { -private class A : A>], c: d where S a { -}(""" -return x } -func c(a diff --git a/validation-test/compiler_crashers_fixed/2205-resolvetypedecl.swift b/validation-test/compiler_crashers_fixed/2205-resolvetypedecl.swift deleted file mode 100644 index e53584757c8dc..0000000000000 --- a/validation-test/compiler_crashers_fixed/2205-resolvetypedecl.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: not %target-swift-frontend %s -parse -// REQUIRES: asserts - -// Distributed under the terms of the MIT license -// Test case submitted to project by https://github.com/practicalswift (practicalswift) -// Test case found by fuzzing - -ic class A { -func f, range.E == b> Void>, k : A.d.init() { -typealias F = B() -func a: ExtensibleCollectionType>({ -print() -> == e([] -protocol b { -let start = ") -} -struct c() -> Bool { + let a: D.B? = nil +} diff --git a/validation-test/compiler_crashers/24900-swift-typebase-getmembersubstitutions.swift b/validation-test/compiler_crashers_fixed/24900-swift-typebase-getmembersubstitutions.swift similarity index 80% rename from validation-test/compiler_crashers/24900-swift-typebase-getmembersubstitutions.swift rename to validation-test/compiler_crashers_fixed/24900-swift-typebase-getmembersubstitutions.swift index ca87e8be39cfb..f75a81d66bfe8 100644 --- a/validation-test/compiler_crashers/24900-swift-typebase-getmembersubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/24900-swift-typebase-getmembersubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/24947-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/24947-swift-lexer-leximpl.swift similarity index 79% rename from validation-test/compiler_crashers/24947-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/24947-swift-lexer-leximpl.swift index 76981a3c499e4..bcd93581856b6 100644 --- a/validation-test/compiler_crashers/24947-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/24947-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/24960-swift-typedecl-getdeclaredinterfacetype.swift b/validation-test/compiler_crashers_fixed/24960-swift-typedecl-getdeclaredinterfacetype.swift similarity index 79% rename from validation-test/compiler_crashers/24960-swift-typedecl-getdeclaredinterfacetype.swift rename to validation-test/compiler_crashers_fixed/24960-swift-typedecl-getdeclaredinterfacetype.swift index 3a6cf9cca725a..c7925665cae78 100644 --- a/validation-test/compiler_crashers/24960-swift-typedecl-getdeclaredinterfacetype.swift +++ b/validation-test/compiler_crashers_fixed/24960-swift-typedecl-getdeclaredinterfacetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25009-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/25009-swift-typechecker-resolvetypeincontext.swift similarity index 81% rename from validation-test/compiler_crashers/25009-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/25009-swift-typechecker-resolvetypeincontext.swift index 8bcad26043839..9e7749d326453 100644 --- a/validation-test/compiler_crashers/25009-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/25009-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25011-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/25011-swift-constraints-constraintsystem-opengeneric.swift similarity index 79% rename from validation-test/compiler_crashers/25011-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/25011-swift-constraints-constraintsystem-opengeneric.swift index 046ddd5fccc3c..dd5a228ae1c7a 100644 --- a/validation-test/compiler_crashers/25011-swift-constraints-constraintsystem-opengeneric.swift +++ b/validation-test/compiler_crashers_fixed/25011-swift-constraints-constraintsystem-opengeneric.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25128-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/25128-swift-type-transform.swift similarity index 79% rename from validation-test/compiler_crashers/25128-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/25128-swift-type-transform.swift index bd13e14c27171..3356c860452eb 100644 --- a/validation-test/compiler_crashers/25128-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/25128-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25152-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/25152-swift-typechecker-resolvetypeincontext.swift similarity index 80% rename from validation-test/compiler_crashers/25152-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/25152-swift-typechecker-resolvetypeincontext.swift index 0f5f67680ef30..2f2111b9c4b37 100644 --- a/validation-test/compiler_crashers/25152-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/25152-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25154-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/25154-swift-constraints-constraintsystem-opengeneric.swift similarity index 82% rename from validation-test/compiler_crashers/25154-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/25154-swift-constraints-constraintsystem-opengeneric.swift index 59ad5270d0474..247244dbb3035 100644 --- a/validation-test/compiler_crashers/25154-swift-constraints-constraintsystem-opengeneric.swift +++ b/validation-test/compiler_crashers_fixed/25154-swift-constraints-constraintsystem-opengeneric.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25163-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/25163-swift-constraints-constraintsystem-opengeneric.swift similarity index 81% rename from validation-test/compiler_crashers/25163-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/25163-swift-constraints-constraintsystem-opengeneric.swift index e44260f7007bc..b72d5ab611f4e 100644 --- a/validation-test/compiler_crashers/25163-swift-constraints-constraintsystem-opengeneric.swift +++ b/validation-test/compiler_crashers_fixed/25163-swift-constraints-constraintsystem-opengeneric.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25327-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/25327-swift-metatypetype-get.swift similarity index 80% rename from validation-test/compiler_crashers/25327-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/25327-swift-metatypetype-get.swift index 2a739532110ee..13c6d6c4fc465 100644 --- a/validation-test/compiler_crashers/25327-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/25327-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25329-swift-typebase-getmembersubstitutions.swift b/validation-test/compiler_crashers_fixed/25329-swift-typebase-getmembersubstitutions.swift similarity index 81% rename from validation-test/compiler_crashers/25329-swift-typebase-getmembersubstitutions.swift rename to validation-test/compiler_crashers_fixed/25329-swift-typebase-getmembersubstitutions.swift index 9cf59f6892dff..0e865f8962c63 100644 --- a/validation-test/compiler_crashers/25329-swift-typebase-getmembersubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/25329-swift-typebase-getmembersubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25342-swift-sourcemanager-getbytedistance.swift b/validation-test/compiler_crashers_fixed/25342-swift-sourcemanager-getbytedistance.swift similarity index 79% rename from validation-test/compiler_crashers/25342-swift-sourcemanager-getbytedistance.swift rename to validation-test/compiler_crashers_fixed/25342-swift-sourcemanager-getbytedistance.swift index ac43c86a8f295..ee16c227e6b63 100644 --- a/validation-test/compiler_crashers/25342-swift-sourcemanager-getbytedistance.swift +++ b/validation-test/compiler_crashers_fixed/25342-swift-sourcemanager-getbytedistance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25349-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/25349-swift-typechecker-validatedecl.swift similarity index 80% rename from validation-test/compiler_crashers/25349-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/25349-swift-typechecker-validatedecl.swift index a9499b6f6289a..4aa1bfe3ea487 100644 --- a/validation-test/compiler_crashers/25349-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/25349-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25358-llvm-foldingset-swift-classtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/25358-llvm-foldingset-swift-classtype-nodeequals.swift similarity index 81% rename from validation-test/compiler_crashers/25358-llvm-foldingset-swift-classtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/25358-llvm-foldingset-swift-classtype-nodeequals.swift index a7221d02ac4e8..d85b3114b5317 100644 --- a/validation-test/compiler_crashers/25358-llvm-foldingset-swift-classtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/25358-llvm-foldingset-swift-classtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25384-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/25384-swift-constraints-constraintsystem-opengeneric.swift similarity index 81% rename from validation-test/compiler_crashers/25384-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/25384-swift-constraints-constraintsystem-opengeneric.swift index 2b8a5a653267c..ee68cc94e1705 100644 --- a/validation-test/compiler_crashers/25384-swift-constraints-constraintsystem-opengeneric.swift +++ b/validation-test/compiler_crashers_fixed/25384-swift-constraints-constraintsystem-opengeneric.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25387-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/25387-swift-typebase-getsuperclass.swift similarity index 81% rename from validation-test/compiler_crashers/25387-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/25387-swift-typebase-getsuperclass.swift index 78037a7a56c70..910f2bfe56a9f 100644 --- a/validation-test/compiler_crashers/25387-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/25387-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25409-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/25409-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 80% rename from validation-test/compiler_crashers/25409-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/25409-llvm-foldingset-swift-tupletype-nodeequals.swift index dbbe8dd2107b8..22725df9b90cb 100644 --- a/validation-test/compiler_crashers/25409-llvm-foldingset-swift-tupletype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/25409-llvm-foldingset-swift-tupletype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25445-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/25445-swift-type-transform.swift similarity index 81% rename from validation-test/compiler_crashers/25445-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/25445-swift-type-transform.swift index d79c78d836dee..5363486ab3117 100644 --- a/validation-test/compiler_crashers/25445-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/25445-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25449-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/25449-swift-lexer-leximpl.swift similarity index 78% rename from validation-test/compiler_crashers/25449-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/25449-swift-lexer-leximpl.swift index 47a2313c86ace..b4797cd601b40 100644 --- a/validation-test/compiler_crashers/25449-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/25449-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25451-swift-scopeinfo-addtoscope.swift b/validation-test/compiler_crashers_fixed/25451-swift-scopeinfo-addtoscope.swift similarity index 78% rename from validation-test/compiler_crashers/25451-swift-scopeinfo-addtoscope.swift rename to validation-test/compiler_crashers_fixed/25451-swift-scopeinfo-addtoscope.swift index 8a5346b9ee84f..4cc0edd04299c 100644 --- a/validation-test/compiler_crashers/25451-swift-scopeinfo-addtoscope.swift +++ b/validation-test/compiler_crashers_fixed/25451-swift-scopeinfo-addtoscope.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25459-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/25459-swift-declcontext-lookupqualified.swift similarity index 79% rename from validation-test/compiler_crashers/25459-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/25459-swift-declcontext-lookupqualified.swift index 841fff8f25f80..62857ae056e0a 100644 --- a/validation-test/compiler_crashers/25459-swift-declcontext-lookupqualified.swift +++ b/validation-test/compiler_crashers_fixed/25459-swift-declcontext-lookupqualified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25460-swift-expr-walk.swift b/validation-test/compiler_crashers_fixed/25460-swift-expr-walk.swift similarity index 80% rename from validation-test/compiler_crashers/25460-swift-expr-walk.swift rename to validation-test/compiler_crashers_fixed/25460-swift-expr-walk.swift index 62885a4426be0..d54f2ba8f774c 100644 --- a/validation-test/compiler_crashers/25460-swift-expr-walk.swift +++ b/validation-test/compiler_crashers_fixed/25460-swift-expr-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25462-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/25462-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/25462-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/25462-swift-printingdiagnosticconsumer-handlediagnostic.swift index 9812ca56cf989..3b6ca7c660344 100644 --- a/validation-test/compiler_crashers/25462-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/25462-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25465-swift-namelookup-lookupinmodule.swift b/validation-test/compiler_crashers_fixed/25465-swift-namelookup-lookupinmodule.swift similarity index 79% rename from validation-test/compiler_crashers/25465-swift-namelookup-lookupinmodule.swift rename to validation-test/compiler_crashers_fixed/25465-swift-namelookup-lookupinmodule.swift index 08eccec1c4de9..c3fd75e43cbb1 100644 --- a/validation-test/compiler_crashers/25465-swift-namelookup-lookupinmodule.swift +++ b/validation-test/compiler_crashers_fixed/25465-swift-namelookup-lookupinmodule.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25474-swift-parser-diagnose.swift b/validation-test/compiler_crashers_fixed/25474-swift-parser-diagnose.swift similarity index 79% rename from validation-test/compiler_crashers/25474-swift-parser-diagnose.swift rename to validation-test/compiler_crashers_fixed/25474-swift-parser-diagnose.swift index 7a61da2ba2043..846401d06ae0d 100644 --- a/validation-test/compiler_crashers/25474-swift-parser-diagnose.swift +++ b/validation-test/compiler_crashers_fixed/25474-swift-parser-diagnose.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25481-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/25481-swift-modulefile-getimportedmodules.swift similarity index 79% rename from validation-test/compiler_crashers/25481-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/25481-swift-modulefile-getimportedmodules.swift index 1552326f86457..1f4113dc4166d 100644 --- a/validation-test/compiler_crashers/25481-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/25481-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25485-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/25485-swift-patternbindingdecl-setpattern.swift similarity index 83% rename from validation-test/compiler_crashers/25485-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/25485-swift-patternbindingdecl-setpattern.swift index 0708555b4d9ca..8e020e87e3c58 100644 --- a/validation-test/compiler_crashers/25485-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/25485-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25488-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/25488-std-function-func-swift-type-subst.swift similarity index 80% rename from validation-test/compiler_crashers/25488-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/25488-std-function-func-swift-type-subst.swift index c34dbe015ed9e..d3715cdaf02a9 100644 --- a/validation-test/compiler_crashers/25488-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/25488-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25507-void.swift b/validation-test/compiler_crashers_fixed/25507-void.swift similarity index 79% rename from validation-test/compiler_crashers/25507-void.swift rename to validation-test/compiler_crashers_fixed/25507-void.swift index 922025d8d8590..fe5f519882dff 100644 --- a/validation-test/compiler_crashers/25507-void.swift +++ b/validation-test/compiler_crashers_fixed/25507-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25514-bool.swift b/validation-test/compiler_crashers_fixed/25514-bool.swift similarity index 78% rename from validation-test/compiler_crashers/25514-bool.swift rename to validation-test/compiler_crashers_fixed/25514-bool.swift index 28d9a86850449..b29f3cbe99aed 100644 --- a/validation-test/compiler_crashers/25514-bool.swift +++ b/validation-test/compiler_crashers_fixed/25514-bool.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25516-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/25516-swift-diagnosticengine-emitdiagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/25516-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/25516-swift-diagnosticengine-emitdiagnostic.swift index 53b7428b2f8b8..4644d5c6ff7f7 100644 --- a/validation-test/compiler_crashers/25516-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/25516-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25518-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/25518-swift-lexer-leximpl.swift similarity index 78% rename from validation-test/compiler_crashers/25518-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/25518-swift-lexer-leximpl.swift index 0acc8b7e9b611..6a1d1ac34fb11 100644 --- a/validation-test/compiler_crashers/25518-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/25518-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25522-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/25522-swift-typebase-getsuperclass.swift similarity index 80% rename from validation-test/compiler_crashers/25522-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/25522-swift-typebase-getsuperclass.swift index 81c2bb92b87d3..6a6517ef2cda3 100644 --- a/validation-test/compiler_crashers/25522-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/25522-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25531-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/25531-swift-abstractclosureexpr-setparams.swift similarity index 83% rename from validation-test/compiler_crashers/25531-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/25531-swift-abstractclosureexpr-setparams.swift index da8feda5c7600..dd3c508c7a966 100644 --- a/validation-test/compiler_crashers/25531-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/25531-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25533-bool.swift b/validation-test/compiler_crashers_fixed/25533-bool.swift similarity index 78% rename from validation-test/compiler_crashers/25533-bool.swift rename to validation-test/compiler_crashers_fixed/25533-bool.swift index 32f01de729b5d..5c11fe8c59eaf 100644 --- a/validation-test/compiler_crashers/25533-bool.swift +++ b/validation-test/compiler_crashers_fixed/25533-bool.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25534-swift-archetypebuilder-potentialarchetype-gettype.swift b/validation-test/compiler_crashers_fixed/25534-swift-archetypebuilder-potentialarchetype-gettype.swift similarity index 80% rename from validation-test/compiler_crashers/25534-swift-archetypebuilder-potentialarchetype-gettype.swift rename to validation-test/compiler_crashers_fixed/25534-swift-archetypebuilder-potentialarchetype-gettype.swift index 90e3398e34ef6..16b7bf2963ea6 100644 --- a/validation-test/compiler_crashers/25534-swift-archetypebuilder-potentialarchetype-gettype.swift +++ b/validation-test/compiler_crashers_fixed/25534-swift-archetypebuilder-potentialarchetype-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25541-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/25541-swift-lexer-getlocforendoftoken.swift similarity index 78% rename from validation-test/compiler_crashers/25541-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/25541-swift-lexer-getlocforendoftoken.swift index 549789735dbb1..0d7dad31b060d 100644 --- a/validation-test/compiler_crashers/25541-swift-lexer-getlocforendoftoken.swift +++ b/validation-test/compiler_crashers_fixed/25541-swift-lexer-getlocforendoftoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25543-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/25543-swift-typechecker-typecheckexpression.swift similarity index 79% rename from validation-test/compiler_crashers/25543-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/25543-swift-typechecker-typecheckexpression.swift index f515e4873a5fb..b02cb9eefadd3 100644 --- a/validation-test/compiler_crashers/25543-swift-typechecker-typecheckexpression.swift +++ b/validation-test/compiler_crashers_fixed/25543-swift-typechecker-typecheckexpression.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25565-swift-modulefile-loadextensions.swift b/validation-test/compiler_crashers_fixed/25565-swift-modulefile-loadextensions.swift similarity index 79% rename from validation-test/compiler_crashers/25565-swift-modulefile-loadextensions.swift rename to validation-test/compiler_crashers_fixed/25565-swift-modulefile-loadextensions.swift index 5ee08e74e1f7b..58f591494d0d9 100644 --- a/validation-test/compiler_crashers/25565-swift-modulefile-loadextensions.swift +++ b/validation-test/compiler_crashers_fixed/25565-swift-modulefile-loadextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25570-std-function-func-mapsignaturetype.swift b/validation-test/compiler_crashers_fixed/25570-std-function-func-mapsignaturetype.swift similarity index 80% rename from validation-test/compiler_crashers/25570-std-function-func-mapsignaturetype.swift rename to validation-test/compiler_crashers_fixed/25570-std-function-func-mapsignaturetype.swift index c65b817d20b03..f638f1272273e 100644 --- a/validation-test/compiler_crashers/25570-std-function-func-mapsignaturetype.swift +++ b/validation-test/compiler_crashers_fixed/25570-std-function-func-mapsignaturetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25575-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/25575-swift-streamprinter-printtext.swift similarity index 81% rename from validation-test/compiler_crashers/25575-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/25575-swift-streamprinter-printtext.swift index ea8d9e523e08b..4d89e385ba3a0 100644 --- a/validation-test/compiler_crashers/25575-swift-streamprinter-printtext.swift +++ b/validation-test/compiler_crashers_fixed/25575-swift-streamprinter-printtext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25591-std-function-func-swift-archetypebuilder-maptypeintocontext.swift b/validation-test/compiler_crashers_fixed/25591-std-function-func-swift-archetypebuilder-maptypeintocontext.swift similarity index 80% rename from validation-test/compiler_crashers/25591-std-function-func-swift-archetypebuilder-maptypeintocontext.swift rename to validation-test/compiler_crashers_fixed/25591-std-function-func-swift-archetypebuilder-maptypeintocontext.swift index d1996330e27a0..9044cc9cc21ad 100644 --- a/validation-test/compiler_crashers/25591-std-function-func-swift-archetypebuilder-maptypeintocontext.swift +++ b/validation-test/compiler_crashers_fixed/25591-std-function-func-swift-archetypebuilder-maptypeintocontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25599-swift-iterabledeclcontext-getmembers.swift b/validation-test/compiler_crashers_fixed/25599-swift-iterabledeclcontext-getmembers.swift similarity index 85% rename from validation-test/compiler_crashers/25599-swift-iterabledeclcontext-getmembers.swift rename to validation-test/compiler_crashers_fixed/25599-swift-iterabledeclcontext-getmembers.swift index b529d6ba2da76..a03b6c85bd76b 100644 --- a/validation-test/compiler_crashers/25599-swift-iterabledeclcontext-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/25599-swift-iterabledeclcontext-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25600-swift-declname-printpretty.swift b/validation-test/compiler_crashers_fixed/25600-swift-declname-printpretty.swift similarity index 79% rename from validation-test/compiler_crashers/25600-swift-declname-printpretty.swift rename to validation-test/compiler_crashers_fixed/25600-swift-declname-printpretty.swift index 564ff3241777a..52f0959e8d4e9 100644 --- a/validation-test/compiler_crashers/25600-swift-declname-printpretty.swift +++ b/validation-test/compiler_crashers_fixed/25600-swift-declname-printpretty.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25601-resolveidenttypecomponent.swift b/validation-test/compiler_crashers_fixed/25601-resolveidenttypecomponent.swift similarity index 79% rename from validation-test/compiler_crashers/25601-resolveidenttypecomponent.swift rename to validation-test/compiler_crashers_fixed/25601-resolveidenttypecomponent.swift index 7d6aac1c37a0d..825f711867d94 100644 --- a/validation-test/compiler_crashers/25601-resolveidenttypecomponent.swift +++ b/validation-test/compiler_crashers_fixed/25601-resolveidenttypecomponent.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25605-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift b/validation-test/compiler_crashers_fixed/25605-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift similarity index 78% rename from validation-test/compiler_crashers/25605-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift rename to validation-test/compiler_crashers_fixed/25605-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift index 2e60d4818d666..fad37243386dd 100644 --- a/validation-test/compiler_crashers/25605-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift +++ b/validation-test/compiler_crashers_fixed/25605-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25609-swift-inouttype-get.swift b/validation-test/compiler_crashers_fixed/25609-swift-inouttype-get.swift similarity index 79% rename from validation-test/compiler_crashers/25609-swift-inouttype-get.swift rename to validation-test/compiler_crashers_fixed/25609-swift-inouttype-get.swift index e19240f1043be..791eb49db7d1a 100644 --- a/validation-test/compiler_crashers/25609-swift-inouttype-get.swift +++ b/validation-test/compiler_crashers_fixed/25609-swift-inouttype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25610-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/25610-swift-metatypetype-get.swift similarity index 79% rename from validation-test/compiler_crashers/25610-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/25610-swift-metatypetype-get.swift index 98acab898f486..987ce85d8483d 100644 --- a/validation-test/compiler_crashers/25610-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/25610-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25613-llvm-foldingset-swift-classtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/25613-llvm-foldingset-swift-classtype-nodeequals.swift similarity index 79% rename from validation-test/compiler_crashers/25613-llvm-foldingset-swift-classtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/25613-llvm-foldingset-swift-classtype-nodeequals.swift index f8293a8718834..bc5c94d333d57 100644 --- a/validation-test/compiler_crashers/25613-llvm-foldingset-swift-classtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/25613-llvm-foldingset-swift-classtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25618-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/25618-swift-constraints-constraintsystem-simplifytype.swift similarity index 79% rename from validation-test/compiler_crashers/25618-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/25618-swift-constraints-constraintsystem-simplifytype.swift index 88e6ed1c94fb7..640c20304eef6 100644 --- a/validation-test/compiler_crashers/25618-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/25618-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25643-swift-markasobjc.swift b/validation-test/compiler_crashers_fixed/25643-swift-markasobjc.swift similarity index 78% rename from validation-test/compiler_crashers/25643-swift-markasobjc.swift rename to validation-test/compiler_crashers_fixed/25643-swift-markasobjc.swift index 9d730aa89a78b..6723e39fb17d5 100644 --- a/validation-test/compiler_crashers/25643-swift-markasobjc.swift +++ b/validation-test/compiler_crashers_fixed/25643-swift-markasobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25674-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/25674-swift-typechecker-validatedecl.swift similarity index 80% rename from validation-test/compiler_crashers/25674-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/25674-swift-typechecker-validatedecl.swift index 1bdb6539b9e07..e85950fab0274 100644 --- a/validation-test/compiler_crashers/25674-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/25674-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25699-swift-sourcefile-getcache.swift b/validation-test/compiler_crashers_fixed/25699-swift-sourcefile-getcache.swift similarity index 79% rename from validation-test/compiler_crashers/25699-swift-sourcefile-getcache.swift rename to validation-test/compiler_crashers_fixed/25699-swift-sourcefile-getcache.swift index f6b66dc614a63..b01631f6ac2de 100644 --- a/validation-test/compiler_crashers/25699-swift-sourcefile-getcache.swift +++ b/validation-test/compiler_crashers_fixed/25699-swift-sourcefile-getcache.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25704-vtable.swift b/validation-test/compiler_crashers_fixed/25704-vtable.swift similarity index 81% rename from validation-test/compiler_crashers/25704-vtable.swift rename to validation-test/compiler_crashers_fixed/25704-vtable.swift index 6c78ad81dd37d..e02384fb69403 100644 --- a/validation-test/compiler_crashers/25704-vtable.swift +++ b/validation-test/compiler_crashers_fixed/25704-vtable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25708-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/25708-swift-typechecker-resolvetypeincontext.swift similarity index 78% rename from validation-test/compiler_crashers/25708-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/25708-swift-typechecker-resolvetypeincontext.swift index 4b296c79202ae..3ba5abd605953 100644 --- a/validation-test/compiler_crashers/25708-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/25708-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25736-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/25736-swift-lexer-lexidentifier.swift similarity index 79% rename from validation-test/compiler_crashers/25736-swift-lexer-lexidentifier.swift rename to validation-test/compiler_crashers_fixed/25736-swift-lexer-lexidentifier.swift index 51d9b85e3d41b..8c224664566b7 100644 --- a/validation-test/compiler_crashers/25736-swift-lexer-lexidentifier.swift +++ b/validation-test/compiler_crashers_fixed/25736-swift-lexer-lexidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25770-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/25770-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 79% rename from validation-test/compiler_crashers/25770-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/25770-llvm-foldingset-swift-tupletype-nodeequals.swift index 7055c7f10f96b..d7053db680b6e 100644 --- a/validation-test/compiler_crashers/25770-llvm-foldingset-swift-tupletype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/25770-llvm-foldingset-swift-tupletype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25806-swift-derivedfileunit-lookupvalue.swift b/validation-test/compiler_crashers_fixed/25806-swift-derivedfileunit-lookupvalue.swift similarity index 78% rename from validation-test/compiler_crashers/25806-swift-derivedfileunit-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/25806-swift-derivedfileunit-lookupvalue.swift index 8ddf051e84ff2..dae51c69fbaf3 100644 --- a/validation-test/compiler_crashers/25806-swift-derivedfileunit-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/25806-swift-derivedfileunit-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25809-swift-sourcemanager-extracttext.swift b/validation-test/compiler_crashers_fixed/25809-swift-sourcemanager-extracttext.swift similarity index 82% rename from validation-test/compiler_crashers/25809-swift-sourcemanager-extracttext.swift rename to validation-test/compiler_crashers_fixed/25809-swift-sourcemanager-extracttext.swift index 4f3fdc81d313c..85bd5641bf441 100644 --- a/validation-test/compiler_crashers/25809-swift-sourcemanager-extracttext.swift +++ b/validation-test/compiler_crashers_fixed/25809-swift-sourcemanager-extracttext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25819-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/25819-std-function-func-swift-type-subst.swift similarity index 80% rename from validation-test/compiler_crashers/25819-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/25819-std-function-func-swift-type-subst.swift index 491ba79afe47b..109929286b470 100644 --- a/validation-test/compiler_crashers/25819-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/25819-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25822-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/25822-swift-typechecker-coercepatterntotype.swift similarity index 81% rename from validation-test/compiler_crashers/25822-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/25822-swift-typechecker-coercepatterntotype.swift index 6db18e34272e7..44d8001932149 100644 --- a/validation-test/compiler_crashers/25822-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/25822-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25832-resolveidenttypecomponent.swift b/validation-test/compiler_crashers_fixed/25832-resolveidenttypecomponent.swift similarity index 84% rename from validation-test/compiler_crashers/25832-resolveidenttypecomponent.swift rename to validation-test/compiler_crashers_fixed/25832-resolveidenttypecomponent.swift index ccf4809bfd9ac..3d22cf0be81a2 100644 --- a/validation-test/compiler_crashers/25832-resolveidenttypecomponent.swift +++ b/validation-test/compiler_crashers_fixed/25832-resolveidenttypecomponent.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25835-swift-genericsignature-profile.swift b/validation-test/compiler_crashers_fixed/25835-swift-genericsignature-profile.swift similarity index 80% rename from validation-test/compiler_crashers/25835-swift-genericsignature-profile.swift rename to validation-test/compiler_crashers_fixed/25835-swift-genericsignature-profile.swift index ea18a24879103..bcc55c50b5ef5 100644 --- a/validation-test/compiler_crashers/25835-swift-genericsignature-profile.swift +++ b/validation-test/compiler_crashers_fixed/25835-swift-genericsignature-profile.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25836-resolveidenttypecomponent.swift b/validation-test/compiler_crashers_fixed/25836-resolveidenttypecomponent.swift similarity index 78% rename from validation-test/compiler_crashers/25836-resolveidenttypecomponent.swift rename to validation-test/compiler_crashers_fixed/25836-resolveidenttypecomponent.swift index 2faab60cdb830..741e76076ee54 100644 --- a/validation-test/compiler_crashers/25836-resolveidenttypecomponent.swift +++ b/validation-test/compiler_crashers_fixed/25836-resolveidenttypecomponent.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25897-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/25897-swift-typebase-getsuperclass.swift similarity index 80% rename from validation-test/compiler_crashers/25897-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/25897-swift-typebase-getsuperclass.swift index 4f82469ae9107..cdfbe20b325d8 100644 --- a/validation-test/compiler_crashers/25897-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/25897-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/25908-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/25908-swift-constraints-solution-computesubstitutions.swift index 2dce03905da17..61faa48760707 100644 --- a/validation-test/compiler_crashers_fixed/25908-swift-constraints-solution-computesubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/25908-swift-constraints-solution-computesubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25960-std-function-func-setboundvarstypeerror.swift b/validation-test/compiler_crashers_fixed/25960-std-function-func-setboundvarstypeerror.swift similarity index 80% rename from validation-test/compiler_crashers/25960-std-function-func-setboundvarstypeerror.swift rename to validation-test/compiler_crashers_fixed/25960-std-function-func-setboundvarstypeerror.swift index 2fece60572b7d..31ed43ed023b7 100644 --- a/validation-test/compiler_crashers/25960-std-function-func-setboundvarstypeerror.swift +++ b/validation-test/compiler_crashers_fixed/25960-std-function-func-setboundvarstypeerror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/25980-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/25980-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 82% rename from validation-test/compiler_crashers/25980-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/25980-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift index d305277c8783c..dec26eaaaff44 100644 --- a/validation-test/compiler_crashers/25980-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift +++ b/validation-test/compiler_crashers_fixed/25980-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/25988-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/25988-swift-typebase-getcanonicaltype.swift similarity index 81% rename from validation-test/compiler_crashers/25988-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/25988-swift-typebase-getcanonicaltype.swift index 6a83e116dffa9..301bab4c9f716 100644 --- a/validation-test/compiler_crashers/25988-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/25988-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/25992-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/25992-swift-typebase-getsuperclass.swift similarity index 81% rename from validation-test/compiler_crashers/25992-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/25992-swift-typebase-getsuperclass.swift index e0e99251c220c..7769d32cf0229 100644 --- a/validation-test/compiler_crashers/25992-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/25992-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/25999-swift-nominaltype-get.swift b/validation-test/compiler_crashers_fixed/25999-swift-nominaltype-get.swift similarity index 81% rename from validation-test/compiler_crashers/25999-swift-nominaltype-get.swift rename to validation-test/compiler_crashers_fixed/25999-swift-nominaltype-get.swift index e8c01f908e05f..b37dec6b17068 100644 --- a/validation-test/compiler_crashers/25999-swift-nominaltype-get.swift +++ b/validation-test/compiler_crashers_fixed/25999-swift-nominaltype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26002-swift-nominaltype-get.swift b/validation-test/compiler_crashers_fixed/26002-swift-nominaltype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26002-swift-nominaltype-get.swift rename to validation-test/compiler_crashers_fixed/26002-swift-nominaltype-get.swift index 983f1d390d553..14bf2a8aae675 100644 --- a/validation-test/compiler_crashers/26002-swift-nominaltype-get.swift +++ b/validation-test/compiler_crashers_fixed/26002-swift-nominaltype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26006-swift-typechecker-checkdeclarationavailability.swift b/validation-test/compiler_crashers_fixed/26006-swift-typechecker-checkdeclarationavailability.swift similarity index 81% rename from validation-test/compiler_crashers/26006-swift-typechecker-checkdeclarationavailability.swift rename to validation-test/compiler_crashers_fixed/26006-swift-typechecker-checkdeclarationavailability.swift index 999be39c7f4dd..7df5b3e889fbe 100644 --- a/validation-test/compiler_crashers/26006-swift-typechecker-checkdeclarationavailability.swift +++ b/validation-test/compiler_crashers_fixed/26006-swift-typechecker-checkdeclarationavailability.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26029-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26029-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/26029-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26029-std-function-func-swift-type-subst.swift index e31cbca75521d..0e2b735a20af4 100644 --- a/validation-test/compiler_crashers/26029-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26029-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26057-swift-valuedecl-settype.swift b/validation-test/compiler_crashers_fixed/26057-swift-valuedecl-settype.swift similarity index 97% rename from validation-test/compiler_crashers/26057-swift-valuedecl-settype.swift rename to validation-test/compiler_crashers_fixed/26057-swift-valuedecl-settype.swift index 377308c59987d..2d06728f58ed9 100644 --- a/validation-test/compiler_crashers/26057-swift-valuedecl-settype.swift +++ b/validation-test/compiler_crashers_fixed/26057-swift-valuedecl-settype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26059-std-function-func-mapsignaturetype.swift b/validation-test/compiler_crashers_fixed/26059-std-function-func-mapsignaturetype.swift similarity index 80% rename from validation-test/compiler_crashers/26059-std-function-func-mapsignaturetype.swift rename to validation-test/compiler_crashers_fixed/26059-std-function-func-mapsignaturetype.swift index 2b3e6000df3ec..5a7f7116c1122 100644 --- a/validation-test/compiler_crashers/26059-std-function-func-mapsignaturetype.swift +++ b/validation-test/compiler_crashers_fixed/26059-std-function-func-mapsignaturetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26061-swift-removeshadoweddecls.swift b/validation-test/compiler_crashers_fixed/26061-swift-removeshadoweddecls.swift similarity index 81% rename from validation-test/compiler_crashers/26061-swift-removeshadoweddecls.swift rename to validation-test/compiler_crashers_fixed/26061-swift-removeshadoweddecls.swift index 92c6d0b99fff3..61880844f4887 100644 --- a/validation-test/compiler_crashers/26061-swift-removeshadoweddecls.swift +++ b/validation-test/compiler_crashers_fixed/26061-swift-removeshadoweddecls.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26076-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/26076-swift-parser-skipsingle.swift similarity index 83% rename from validation-test/compiler_crashers/26076-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/26076-swift-parser-skipsingle.swift index 43dcb81b12cac..9d8ba081c08a8 100644 --- a/validation-test/compiler_crashers/26076-swift-parser-skipsingle.swift +++ b/validation-test/compiler_crashers_fixed/26076-swift-parser-skipsingle.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26079-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/26079-swift-parser-parseexprpostfix.swift similarity index 79% rename from validation-test/compiler_crashers/26079-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/26079-swift-parser-parseexprpostfix.swift index 74be6532ea403..b36e54d783e50 100644 --- a/validation-test/compiler_crashers/26079-swift-parser-parseexprpostfix.swift +++ b/validation-test/compiler_crashers_fixed/26079-swift-parser-parseexprpostfix.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26084-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/26084-swift-typebase-getsuperclass.swift similarity index 81% rename from validation-test/compiler_crashers/26084-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/26084-swift-typebase-getsuperclass.swift index 0060c54de55d0..6714034e8ecec 100644 --- a/validation-test/compiler_crashers/26084-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/26084-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26086-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/26086-swift-typebase-getsuperclass.swift similarity index 82% rename from validation-test/compiler_crashers/26086-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/26086-swift-typebase-getsuperclass.swift index 39b61437596a5..6559867c855f0 100644 --- a/validation-test/compiler_crashers/26086-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/26086-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26090-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/26090-swift-constraints-constraintsystem-opengeneric.swift similarity index 81% rename from validation-test/compiler_crashers/26090-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/26090-swift-constraints-constraintsystem-opengeneric.swift index 0ea6383fb04a2..eb5d585087815 100644 --- a/validation-test/compiler_crashers/26090-swift-constraints-constraintsystem-opengeneric.swift +++ b/validation-test/compiler_crashers_fixed/26090-swift-constraints-constraintsystem-opengeneric.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26094-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/26094-swift-typebase-getsuperclass.swift similarity index 80% rename from validation-test/compiler_crashers/26094-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/26094-swift-typebase-getsuperclass.swift index 0877e13c96de7..7cdf1f13e586c 100644 --- a/validation-test/compiler_crashers/26094-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/26094-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26096-llvm-errs.swift b/validation-test/compiler_crashers_fixed/26096-llvm-errs.swift similarity index 81% rename from validation-test/compiler_crashers/26096-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/26096-llvm-errs.swift index f66a2afee16a3..c56244b2df099 100644 --- a/validation-test/compiler_crashers/26096-llvm-errs.swift +++ b/validation-test/compiler_crashers_fixed/26096-llvm-errs.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26098-swift-funcdecl-setdeserializedsignature.swift b/validation-test/compiler_crashers_fixed/26098-swift-funcdecl-setdeserializedsignature.swift similarity index 83% rename from validation-test/compiler_crashers/26098-swift-funcdecl-setdeserializedsignature.swift rename to validation-test/compiler_crashers_fixed/26098-swift-funcdecl-setdeserializedsignature.swift index 322bd9eef462a..aea585d7779f5 100644 --- a/validation-test/compiler_crashers/26098-swift-funcdecl-setdeserializedsignature.swift +++ b/validation-test/compiler_crashers_fixed/26098-swift-funcdecl-setdeserializedsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26099-swift-constraints-constraintsystem-getconstraintlocator.swift b/validation-test/compiler_crashers_fixed/26099-swift-constraints-constraintsystem-getconstraintlocator.swift similarity index 81% rename from validation-test/compiler_crashers/26099-swift-constraints-constraintsystem-getconstraintlocator.swift rename to validation-test/compiler_crashers_fixed/26099-swift-constraints-constraintsystem-getconstraintlocator.swift index 65da91fc589e8..a8b68e65f6089 100644 --- a/validation-test/compiler_crashers/26099-swift-constraints-constraintsystem-getconstraintlocator.swift +++ b/validation-test/compiler_crashers_fixed/26099-swift-constraints-constraintsystem-getconstraintlocator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26102-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/26102-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 80% rename from validation-test/compiler_crashers/26102-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/26102-swift-typechecker-overapproximateosversionsatlocation.swift index e28a6fdc3d8b1..c908f60b9fb5d 100644 --- a/validation-test/compiler_crashers/26102-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/26102-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26103-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/26103-swift-constraints-constraintsystem-solve.swift similarity index 83% rename from validation-test/compiler_crashers/26103-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/26103-swift-constraints-constraintsystem-solve.swift index 5e1b31bdda46c..424f075c1b218 100644 --- a/validation-test/compiler_crashers/26103-swift-constraints-constraintsystem-solve.swift +++ b/validation-test/compiler_crashers_fixed/26103-swift-constraints-constraintsystem-solve.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26106-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/26106-swift-typebase-getsuperclass.swift similarity index 82% rename from validation-test/compiler_crashers/26106-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/26106-swift-typebase-getsuperclass.swift index d3198b24892b5..67100e07c8da2 100644 --- a/validation-test/compiler_crashers/26106-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/26106-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26108-swift-genericparamlist-deriveallarchetypes.swift b/validation-test/compiler_crashers_fixed/26108-swift-genericparamlist-deriveallarchetypes.swift similarity index 79% rename from validation-test/compiler_crashers/26108-swift-genericparamlist-deriveallarchetypes.swift rename to validation-test/compiler_crashers_fixed/26108-swift-genericparamlist-deriveallarchetypes.swift index 80eff8b4f2139..1b360e0061e51 100644 --- a/validation-test/compiler_crashers/26108-swift-genericparamlist-deriveallarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/26108-swift-genericparamlist-deriveallarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26111-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/26111-swift-modulefile-maybereadpattern.swift similarity index 82% rename from validation-test/compiler_crashers/26111-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/26111-swift-modulefile-maybereadpattern.swift index 1036d3cca3962..48a337d65053f 100644 --- a/validation-test/compiler_crashers/26111-swift-modulefile-maybereadpattern.swift +++ b/validation-test/compiler_crashers_fixed/26111-swift-modulefile-maybereadpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26112-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/26112-swift-genericsignature-get.swift similarity index 80% rename from validation-test/compiler_crashers/26112-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/26112-swift-genericsignature-get.swift index a4e7727ec6409..73bafafe4c2e1 100644 --- a/validation-test/compiler_crashers/26112-swift-genericsignature-get.swift +++ b/validation-test/compiler_crashers_fixed/26112-swift-genericsignature-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26118-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/26118-swift-lexer-leximpl.swift similarity index 80% rename from validation-test/compiler_crashers/26118-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/26118-swift-lexer-leximpl.swift index ca8513327e969..58eff207642f9 100644 --- a/validation-test/compiler_crashers/26118-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/26118-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26119-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/26119-swift-typeloc-iserror.swift similarity index 81% rename from validation-test/compiler_crashers/26119-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/26119-swift-typeloc-iserror.swift index 337e0ef554134..610a2e878588a 100644 --- a/validation-test/compiler_crashers/26119-swift-typeloc-iserror.swift +++ b/validation-test/compiler_crashers_fixed/26119-swift-typeloc-iserror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26123-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/26123-swift-metatypetype-get.swift similarity index 79% rename from validation-test/compiler_crashers/26123-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/26123-swift-metatypetype-get.swift index 92458d0254f0a..acd90001d4af9 100644 --- a/validation-test/compiler_crashers/26123-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/26123-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26124-swift-genericparamlist-deriveallarchetypes.swift b/validation-test/compiler_crashers_fixed/26124-swift-genericparamlist-deriveallarchetypes.swift similarity index 82% rename from validation-test/compiler_crashers/26124-swift-genericparamlist-deriveallarchetypes.swift rename to validation-test/compiler_crashers_fixed/26124-swift-genericparamlist-deriveallarchetypes.swift index f49ff83ed0062..fd6d62def73a1 100644 --- a/validation-test/compiler_crashers/26124-swift-genericparamlist-deriveallarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/26124-swift-genericparamlist-deriveallarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26125-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26125-swift-modulefile-lookupvalue.swift similarity index 82% rename from validation-test/compiler_crashers/26125-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26125-swift-modulefile-lookupvalue.swift index 025203dcc65c3..db1cb9579c2fa 100644 --- a/validation-test/compiler_crashers/26125-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26125-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26130-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/26130-swift-tupletype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26130-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/26130-swift-tupletype-get.swift index a96b6a7309269..bb9e5c2828e73 100644 --- a/validation-test/compiler_crashers/26130-swift-tupletype-get.swift +++ b/validation-test/compiler_crashers_fixed/26130-swift-tupletype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26131-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26131-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 84% rename from validation-test/compiler_crashers/26131-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26131-swift-printingdiagnosticconsumer-handlediagnostic.swift index bbabbb52191e6..d3cef3854d00b 100644 --- a/validation-test/compiler_crashers/26131-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26131-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26132-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/26132-swift-boundgenerictype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26132-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/26132-swift-boundgenerictype-get.swift index 98b3a3aaa3849..cf00f75983746 100644 --- a/validation-test/compiler_crashers/26132-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/26132-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26133-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift b/validation-test/compiler_crashers_fixed/26133-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift similarity index 80% rename from validation-test/compiler_crashers/26133-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift rename to validation-test/compiler_crashers_fixed/26133-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift index 5bfda1eb82b9d..c57c4a8991c0c 100644 --- a/validation-test/compiler_crashers/26133-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/26133-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26137-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift b/validation-test/compiler_crashers_fixed/26137-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift similarity index 82% rename from validation-test/compiler_crashers/26137-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift rename to validation-test/compiler_crashers_fixed/26137-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift index e97cce98331f1..8f112b392a4e5 100644 --- a/validation-test/compiler_crashers/26137-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift +++ b/validation-test/compiler_crashers_fixed/26137-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26138-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/26138-swift-typebase-getcanonicaltype.swift similarity index 81% rename from validation-test/compiler_crashers/26138-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/26138-swift-typebase-getcanonicaltype.swift index e85bfc671ac0e..a218fbcc7a8b2 100644 --- a/validation-test/compiler_crashers/26138-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/26138-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26140-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/26140-swift-modulefile-getdecl.swift similarity index 82% rename from validation-test/compiler_crashers/26140-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/26140-swift-modulefile-getdecl.swift index f9013dc9f25e5..e45327bbc4c06 100644 --- a/validation-test/compiler_crashers/26140-swift-modulefile-getdecl.swift +++ b/validation-test/compiler_crashers_fixed/26140-swift-modulefile-getdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26141-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/26141-swift-lexer-getlocforendoftoken.swift similarity index 81% rename from validation-test/compiler_crashers/26141-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/26141-swift-lexer-getlocforendoftoken.swift index 1db3efab60fc2..a402f771069f4 100644 --- a/validation-test/compiler_crashers/26141-swift-lexer-getlocforendoftoken.swift +++ b/validation-test/compiler_crashers_fixed/26141-swift-lexer-getlocforendoftoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26143-swift-declattribute-canattributeappearondeclkind.swift b/validation-test/compiler_crashers_fixed/26143-swift-declattribute-canattributeappearondeclkind.swift similarity index 81% rename from validation-test/compiler_crashers/26143-swift-declattribute-canattributeappearondeclkind.swift rename to validation-test/compiler_crashers_fixed/26143-swift-declattribute-canattributeappearondeclkind.swift index 27df9026cb83b..e9ca4c01d88a4 100644 --- a/validation-test/compiler_crashers/26143-swift-declattribute-canattributeappearondeclkind.swift +++ b/validation-test/compiler_crashers_fixed/26143-swift-declattribute-canattributeappearondeclkind.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26145-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/26145-swift-lexer-getlocforendoftoken.swift similarity index 80% rename from validation-test/compiler_crashers/26145-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/26145-swift-lexer-getlocforendoftoken.swift index 729ba81bad956..b94555524eb6f 100644 --- a/validation-test/compiler_crashers/26145-swift-lexer-getlocforendoftoken.swift +++ b/validation-test/compiler_crashers_fixed/26145-swift-lexer-getlocforendoftoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26147-llvm-foldingset-swift-classtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/26147-llvm-foldingset-swift-classtype-nodeequals.swift similarity index 82% rename from validation-test/compiler_crashers/26147-llvm-foldingset-swift-classtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/26147-llvm-foldingset-swift-classtype-nodeequals.swift index fb808d79016cc..70c59f38a250c 100644 --- a/validation-test/compiler_crashers/26147-llvm-foldingset-swift-classtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/26147-llvm-foldingset-swift-classtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26149-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/26149-swift-boundgenerictype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26149-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/26149-swift-boundgenerictype-get.swift index 99764715e0639..fc79bed8e0f93 100644 --- a/validation-test/compiler_crashers/26149-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/26149-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26151-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/26151-swift-genericfunctiontype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26151-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/26151-swift-genericfunctiontype-get.swift index c14b321954d6a..458f834c3ff3a 100644 --- a/validation-test/compiler_crashers/26151-swift-genericfunctiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/26151-swift-genericfunctiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26153-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/26153-swift-astprinter-printtextimpl.swift similarity index 82% rename from validation-test/compiler_crashers/26153-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/26153-swift-astprinter-printtextimpl.swift index df7d8e1daaad1..85709830959dc 100644 --- a/validation-test/compiler_crashers/26153-swift-astprinter-printtextimpl.swift +++ b/validation-test/compiler_crashers_fixed/26153-swift-astprinter-printtextimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26154-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/26154-swift-typebase-getcanonicaltype.swift similarity index 82% rename from validation-test/compiler_crashers/26154-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/26154-swift-typebase-getcanonicaltype.swift index 6fd8fc6bc3047..f8e8bcb5e815e 100644 --- a/validation-test/compiler_crashers/26154-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/26154-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26157-resolveidenttypecomponent.swift b/validation-test/compiler_crashers_fixed/26157-resolveidenttypecomponent.swift similarity index 80% rename from validation-test/compiler_crashers/26157-resolveidenttypecomponent.swift rename to validation-test/compiler_crashers_fixed/26157-resolveidenttypecomponent.swift index db91b3a2ce801..cd5bd6dbe3ca0 100644 --- a/validation-test/compiler_crashers/26157-resolveidenttypecomponent.swift +++ b/validation-test/compiler_crashers_fixed/26157-resolveidenttypecomponent.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26159-llvm-foldingset-swift-structtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/26159-llvm-foldingset-swift-structtype-nodeequals.swift similarity index 79% rename from validation-test/compiler_crashers/26159-llvm-foldingset-swift-structtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/26159-llvm-foldingset-swift-structtype-nodeequals.swift index bc8daa3c739f5..ccebc5b8d2c99 100644 --- a/validation-test/compiler_crashers/26159-llvm-foldingset-swift-structtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/26159-llvm-foldingset-swift-structtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26160-swift-astcontext-getidentifier.swift b/validation-test/compiler_crashers_fixed/26160-swift-astcontext-getidentifier.swift similarity index 82% rename from validation-test/compiler_crashers/26160-swift-astcontext-getidentifier.swift rename to validation-test/compiler_crashers_fixed/26160-swift-astcontext-getidentifier.swift index 370fd0fbbf6cc..9fb674b7904c4 100644 --- a/validation-test/compiler_crashers/26160-swift-astcontext-getidentifier.swift +++ b/validation-test/compiler_crashers_fixed/26160-swift-astcontext-getidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26164-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26164-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/26164-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26164-std-function-func-swift-type-subst.swift index 61e6668e22ae2..cde52601f3794 100644 --- a/validation-test/compiler_crashers/26164-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26164-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26165-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/26165-swift-diagnosticengine-emitdiagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/26165-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/26165-swift-diagnosticengine-emitdiagnostic.swift index 551b1b7a79456..c6a3931238a37 100644 --- a/validation-test/compiler_crashers/26165-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26165-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26166-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26166-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/26166-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26166-swift-printingdiagnosticconsumer-handlediagnostic.swift index 387967de92aa7..ce4f7a1b44b41 100644 --- a/validation-test/compiler_crashers/26166-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26166-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26168-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/26168-swift-modulefile-maybereadpattern.swift similarity index 83% rename from validation-test/compiler_crashers/26168-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/26168-swift-modulefile-maybereadpattern.swift index de5c22ea0a79f..28485ffefae2b 100644 --- a/validation-test/compiler_crashers/26168-swift-modulefile-maybereadpattern.swift +++ b/validation-test/compiler_crashers_fixed/26168-swift-modulefile-maybereadpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26171-swift-astcontext-allocate.swift b/validation-test/compiler_crashers_fixed/26171-swift-astcontext-allocate.swift similarity index 81% rename from validation-test/compiler_crashers/26171-swift-astcontext-allocate.swift rename to validation-test/compiler_crashers_fixed/26171-swift-astcontext-allocate.swift index 530047a8d87ce..db75d5b682f18 100644 --- a/validation-test/compiler_crashers/26171-swift-astcontext-allocate.swift +++ b/validation-test/compiler_crashers_fixed/26171-swift-astcontext-allocate.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26172-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26172-swift-modulefile-lookupvalue.swift similarity index 82% rename from validation-test/compiler_crashers/26172-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26172-swift-modulefile-lookupvalue.swift index ef645300d9501..90833d3237602 100644 --- a/validation-test/compiler_crashers/26172-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26172-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26173-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26173-swift-typechecker-validatedecl.swift similarity index 81% rename from validation-test/compiler_crashers/26173-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26173-swift-typechecker-validatedecl.swift index 2f98bfee7bae6..8102b9a1ea178 100644 --- a/validation-test/compiler_crashers/26173-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26173-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26177-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/26177-swift-typechecker-typecheckexpression.swift similarity index 83% rename from validation-test/compiler_crashers/26177-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/26177-swift-typechecker-typecheckexpression.swift index 3fb7e69fe1f10..b9466657da65a 100644 --- a/validation-test/compiler_crashers/26177-swift-typechecker-typecheckexpression.swift +++ b/validation-test/compiler_crashers_fixed/26177-swift-typechecker-typecheckexpression.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26180-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/26180-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 79% rename from validation-test/compiler_crashers/26180-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/26180-llvm-foldingset-swift-tupletype-nodeequals.swift index 58b9ae53f5144..ef511469566b8 100644 --- a/validation-test/compiler_crashers/26180-llvm-foldingset-swift-tupletype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/26180-llvm-foldingset-swift-tupletype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26183-swift-constraints-constraintgraphnode-addconstraint.swift b/validation-test/compiler_crashers_fixed/26183-swift-constraints-constraintgraphnode-addconstraint.swift similarity index 81% rename from validation-test/compiler_crashers/26183-swift-constraints-constraintgraphnode-addconstraint.swift rename to validation-test/compiler_crashers_fixed/26183-swift-constraints-constraintgraphnode-addconstraint.swift index 8f64e4711205b..ed11fbfa20891 100644 --- a/validation-test/compiler_crashers/26183-swift-constraints-constraintgraphnode-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/26183-swift-constraints-constraintgraphnode-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26184-llvm-yaml-input-preflightkey.swift b/validation-test/compiler_crashers_fixed/26184-llvm-yaml-input-preflightkey.swift similarity index 84% rename from validation-test/compiler_crashers/26184-llvm-yaml-input-preflightkey.swift rename to validation-test/compiler_crashers_fixed/26184-llvm-yaml-input-preflightkey.swift index 74dfba815677a..caa172f64df90 100644 --- a/validation-test/compiler_crashers/26184-llvm-yaml-input-preflightkey.swift +++ b/validation-test/compiler_crashers_fixed/26184-llvm-yaml-input-preflightkey.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26186-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/26186-swift-modulefile-gettype.swift similarity index 81% rename from validation-test/compiler_crashers/26186-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/26186-swift-modulefile-gettype.swift index 39cf3d357ec13..bcc65b86a2285 100644 --- a/validation-test/compiler_crashers/26186-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/26186-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26191-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift b/validation-test/compiler_crashers_fixed/26191-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift similarity index 81% rename from validation-test/compiler_crashers/26191-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift rename to validation-test/compiler_crashers_fixed/26191-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift index 272ea3151879a..16a27d6088047 100644 --- a/validation-test/compiler_crashers/26191-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift +++ b/validation-test/compiler_crashers_fixed/26191-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26192-swift-maybeaddaccessorstovariable.swift b/validation-test/compiler_crashers_fixed/26192-swift-maybeaddaccessorstovariable.swift similarity index 80% rename from validation-test/compiler_crashers/26192-swift-maybeaddaccessorstovariable.swift rename to validation-test/compiler_crashers_fixed/26192-swift-maybeaddaccessorstovariable.swift index b10956f1b7774..4cf90039102f3 100644 --- a/validation-test/compiler_crashers/26192-swift-maybeaddaccessorstovariable.swift +++ b/validation-test/compiler_crashers_fixed/26192-swift-maybeaddaccessorstovariable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26194-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/26194-swift-constraints-constraintsystem-simplifytype.swift similarity index 79% rename from validation-test/compiler_crashers/26194-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/26194-swift-constraints-constraintsystem-simplifytype.swift index 4a11a61ecfee3..f183a5a259820 100644 --- a/validation-test/compiler_crashers/26194-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/26194-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26196-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/26196-swift-metatypetype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26196-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/26196-swift-metatypetype-get.swift index a19a3bff16799..efecd7c55eaad 100644 --- a/validation-test/compiler_crashers/26196-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/26196-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26198-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/26198-swift-inflightdiagnostic.swift similarity index 80% rename from validation-test/compiler_crashers/26198-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/26198-swift-inflightdiagnostic.swift index 75089e5bde840..c703f86a074e9 100644 --- a/validation-test/compiler_crashers/26198-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26198-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26199-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26199-swift-modulefile-lookupvalue.swift similarity index 82% rename from validation-test/compiler_crashers/26199-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26199-swift-modulefile-lookupvalue.swift index 9eff9639deb66..7fa8e0e63a7b0 100644 --- a/validation-test/compiler_crashers/26199-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26199-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26201-swift-astcontext-allocate.swift b/validation-test/compiler_crashers_fixed/26201-swift-astcontext-allocate.swift similarity index 80% rename from validation-test/compiler_crashers/26201-swift-astcontext-allocate.swift rename to validation-test/compiler_crashers_fixed/26201-swift-astcontext-allocate.swift index 40b964904270e..5d2f3b2a283d2 100644 --- a/validation-test/compiler_crashers/26201-swift-astcontext-allocate.swift +++ b/validation-test/compiler_crashers_fixed/26201-swift-astcontext-allocate.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26206-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/26206-swift-constraints-constraintsystem-opengeneric.swift similarity index 80% rename from validation-test/compiler_crashers/26206-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/26206-swift-constraints-constraintsystem-opengeneric.swift index e9ede8f7a1a82..66249a012a28e 100644 --- a/validation-test/compiler_crashers/26206-swift-constraints-constraintsystem-opengeneric.swift +++ b/validation-test/compiler_crashers_fixed/26206-swift-constraints-constraintsystem-opengeneric.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26207-swift-astcontext-allocate.swift b/validation-test/compiler_crashers_fixed/26207-swift-astcontext-allocate.swift similarity index 82% rename from validation-test/compiler_crashers/26207-swift-astcontext-allocate.swift rename to validation-test/compiler_crashers_fixed/26207-swift-astcontext-allocate.swift index 0ed141eaf0407..b7589823094f1 100644 --- a/validation-test/compiler_crashers/26207-swift-astcontext-allocate.swift +++ b/validation-test/compiler_crashers_fixed/26207-swift-astcontext-allocate.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26210-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/26210-swift-boundgenerictype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26210-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/26210-swift-boundgenerictype-get.swift index 7628ae2e2cf36..230c9d30ccefe 100644 --- a/validation-test/compiler_crashers/26210-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/26210-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26211-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/26211-swift-typechecker-coercepatterntotype.swift similarity index 83% rename from validation-test/compiler_crashers/26211-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/26211-swift-typechecker-coercepatterntotype.swift index 2d6eadb880ac7..f758e4a9e3923 100644 --- a/validation-test/compiler_crashers/26211-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/26211-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26212-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/26212-swift-modulefile-getimportedmodules.swift similarity index 82% rename from validation-test/compiler_crashers/26212-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/26212-swift-modulefile-getimportedmodules.swift index 14bbf2ff74b1c..f4568fc0e2d5f 100644 --- a/validation-test/compiler_crashers/26212-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/26212-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26213-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/26213-swift-typechecker-resolvetypeincontext.swift similarity index 80% rename from validation-test/compiler_crashers/26213-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/26213-swift-typechecker-resolvetypeincontext.swift index 455a4b50fd679..92936a015c96d 100644 --- a/validation-test/compiler_crashers/26213-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/26213-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26214-swift-conformancelookuptable-getconformance.swift b/validation-test/compiler_crashers_fixed/26214-swift-conformancelookuptable-getconformance.swift similarity index 81% rename from validation-test/compiler_crashers/26214-swift-conformancelookuptable-getconformance.swift rename to validation-test/compiler_crashers_fixed/26214-swift-conformancelookuptable-getconformance.swift index 54dca5706793c..a61a39fa4d4a9 100644 --- a/validation-test/compiler_crashers/26214-swift-conformancelookuptable-getconformance.swift +++ b/validation-test/compiler_crashers_fixed/26214-swift-conformancelookuptable-getconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26217-swift-typebase-gettypevariables.swift b/validation-test/compiler_crashers_fixed/26217-swift-typebase-gettypevariables.swift similarity index 81% rename from validation-test/compiler_crashers/26217-swift-typebase-gettypevariables.swift rename to validation-test/compiler_crashers_fixed/26217-swift-typebase-gettypevariables.swift index 06563dbccde4b..6eacba2daef95 100644 --- a/validation-test/compiler_crashers/26217-swift-typebase-gettypevariables.swift +++ b/validation-test/compiler_crashers_fixed/26217-swift-typebase-gettypevariables.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26222-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/26222-swift-genericfunctiontype-get.swift similarity index 80% rename from validation-test/compiler_crashers/26222-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/26222-swift-genericfunctiontype-get.swift index cac9e57ce643c..65722f311d652 100644 --- a/validation-test/compiler_crashers/26222-swift-genericfunctiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/26222-swift-genericfunctiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26223-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26223-swift-typechecker-validatedecl.swift similarity index 82% rename from validation-test/compiler_crashers/26223-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26223-swift-typechecker-validatedecl.swift index 8d4b1bc8dc8b5..7eb6c67f77e1e 100644 --- a/validation-test/compiler_crashers/26223-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26223-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26226-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/26226-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 81% rename from validation-test/compiler_crashers/26226-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/26226-swift-constraints-constraintsystem-assignfixedtype.swift index 80998cf3d17e2..827fabeba0355 100644 --- a/validation-test/compiler_crashers/26226-swift-constraints-constraintsystem-assignfixedtype.swift +++ b/validation-test/compiler_crashers_fixed/26226-swift-constraints-constraintsystem-assignfixedtype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26228-void.swift b/validation-test/compiler_crashers_fixed/26228-void.swift similarity index 82% rename from validation-test/compiler_crashers/26228-void.swift rename to validation-test/compiler_crashers_fixed/26228-void.swift index 7a061354995ff..d0a73b2efffb5 100644 --- a/validation-test/compiler_crashers/26228-void.swift +++ b/validation-test/compiler_crashers_fixed/26228-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26232-swift-tuplepattern-create.swift b/validation-test/compiler_crashers_fixed/26232-swift-tuplepattern-create.swift similarity index 80% rename from validation-test/compiler_crashers/26232-swift-tuplepattern-create.swift rename to validation-test/compiler_crashers_fixed/26232-swift-tuplepattern-create.swift index 5e2252a84f5b8..6733044c76cf2 100644 --- a/validation-test/compiler_crashers/26232-swift-tuplepattern-create.swift +++ b/validation-test/compiler_crashers_fixed/26232-swift-tuplepattern-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26234-swift-sourcemanager-extracttext.swift b/validation-test/compiler_crashers_fixed/26234-swift-sourcemanager-extracttext.swift similarity index 82% rename from validation-test/compiler_crashers/26234-swift-sourcemanager-extracttext.swift rename to validation-test/compiler_crashers_fixed/26234-swift-sourcemanager-extracttext.swift index 391dbf0e1cd46..4d1e1d223c0bf 100644 --- a/validation-test/compiler_crashers/26234-swift-sourcemanager-extracttext.swift +++ b/validation-test/compiler_crashers_fixed/26234-swift-sourcemanager-extracttext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26235-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/26235-swift-modulefile-getimportedmodules.swift similarity index 79% rename from validation-test/compiler_crashers/26235-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/26235-swift-modulefile-getimportedmodules.swift index 72cc74c8ff63e..40a86640b2cf5 100644 --- a/validation-test/compiler_crashers/26235-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/26235-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26237-swift-modulefile-maybereadforeignerrorconvention.swift b/validation-test/compiler_crashers_fixed/26237-swift-modulefile-maybereadforeignerrorconvention.swift similarity index 82% rename from validation-test/compiler_crashers/26237-swift-modulefile-maybereadforeignerrorconvention.swift rename to validation-test/compiler_crashers_fixed/26237-swift-modulefile-maybereadforeignerrorconvention.swift index 5272e02b8f358..3b296a54beecc 100644 --- a/validation-test/compiler_crashers/26237-swift-modulefile-maybereadforeignerrorconvention.swift +++ b/validation-test/compiler_crashers_fixed/26237-swift-modulefile-maybereadforeignerrorconvention.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26240-swift-astcontext-allocate.swift b/validation-test/compiler_crashers_fixed/26240-swift-astcontext-allocate.swift similarity index 82% rename from validation-test/compiler_crashers/26240-swift-astcontext-allocate.swift rename to validation-test/compiler_crashers_fixed/26240-swift-astcontext-allocate.swift index 6518cf0ce4c8b..627cbf58c6ced 100644 --- a/validation-test/compiler_crashers/26240-swift-astcontext-allocate.swift +++ b/validation-test/compiler_crashers_fixed/26240-swift-astcontext-allocate.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26242-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26242-swift-typechecker-validatedecl.swift similarity index 81% rename from validation-test/compiler_crashers/26242-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26242-swift-typechecker-validatedecl.swift index ae8bcf5cb9940..892f90248c937 100644 --- a/validation-test/compiler_crashers/26242-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26242-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26251-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/26251-swift-modulefile-gettype.swift similarity index 82% rename from validation-test/compiler_crashers/26251-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/26251-swift-modulefile-gettype.swift index 0ec52b2cce4f5..7e4c36090c6af 100644 --- a/validation-test/compiler_crashers/26251-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/26251-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26256-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26256-swift-typechecker-validatedecl.swift similarity index 81% rename from validation-test/compiler_crashers/26256-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26256-swift-typechecker-validatedecl.swift index e832b96a75fc7..a5b442738e2f0 100644 --- a/validation-test/compiler_crashers/26256-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26256-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26263-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/26263-swift-protocoltype-canonicalizeprotocols.swift similarity index 80% rename from validation-test/compiler_crashers/26263-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/26263-swift-protocoltype-canonicalizeprotocols.swift index 646dff90405b2..eaebb5884657b 100644 --- a/validation-test/compiler_crashers/26263-swift-protocoltype-canonicalizeprotocols.swift +++ b/validation-test/compiler_crashers_fixed/26263-swift-protocoltype-canonicalizeprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26265-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/26265-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 83% rename from validation-test/compiler_crashers/26265-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/26265-swift-constraints-constraintsystem-getfixedtyperecursive.swift index 3e16d979477b0..8272801129bd3 100644 --- a/validation-test/compiler_crashers/26265-swift-constraints-constraintsystem-getfixedtyperecursive.swift +++ b/validation-test/compiler_crashers_fixed/26265-swift-constraints-constraintsystem-getfixedtyperecursive.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26267-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/26267-swift-astprinter-printtextimpl.swift similarity index 82% rename from validation-test/compiler_crashers/26267-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/26267-swift-astprinter-printtextimpl.swift index 1e2bb82c81abd..3634976197bcd 100644 --- a/validation-test/compiler_crashers/26267-swift-astprinter-printtextimpl.swift +++ b/validation-test/compiler_crashers_fixed/26267-swift-astprinter-printtextimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26274-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/26274-swift-typebase-getanyoptionalobjecttype.swift similarity index 81% rename from validation-test/compiler_crashers/26274-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/26274-swift-typebase-getanyoptionalobjecttype.swift index 6c0a0526e9823..4554db778535c 100644 --- a/validation-test/compiler_crashers/26274-swift-typebase-getanyoptionalobjecttype.swift +++ b/validation-test/compiler_crashers_fixed/26274-swift-typebase-getanyoptionalobjecttype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26277-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/26277-swift-typechecker-resolvetypeincontext.swift similarity index 80% rename from validation-test/compiler_crashers/26277-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/26277-swift-typechecker-resolvetypeincontext.swift index ed7d22f36208c..61f8888290b0b 100644 --- a/validation-test/compiler_crashers/26277-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/26277-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26278-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/26278-swift-conformancelookuptable-updatelookuptable.swift similarity index 83% rename from validation-test/compiler_crashers/26278-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/26278-swift-conformancelookuptable-updatelookuptable.swift index 08063c1a8f46f..c724d799c79dc 100644 --- a/validation-test/compiler_crashers/26278-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/26278-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26280-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26280-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/26280-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26280-swift-printingdiagnosticconsumer-handlediagnostic.swift index 41f57b6c32066..bd47cc5dc298e 100644 --- a/validation-test/compiler_crashers/26280-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26280-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26282-swift-genericsignature-genericsignature.swift b/validation-test/compiler_crashers_fixed/26282-swift-genericsignature-genericsignature.swift similarity index 81% rename from validation-test/compiler_crashers/26282-swift-genericsignature-genericsignature.swift rename to validation-test/compiler_crashers_fixed/26282-swift-genericsignature-genericsignature.swift index 9c64d436d401d..95b8b83aaafcb 100644 --- a/validation-test/compiler_crashers/26282-swift-genericsignature-genericsignature.swift +++ b/validation-test/compiler_crashers_fixed/26282-swift-genericsignature-genericsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26284-swift-inflightdiagnostic-fixitreplacechars.swift b/validation-test/compiler_crashers_fixed/26284-swift-inflightdiagnostic-fixitreplacechars.swift similarity index 80% rename from validation-test/compiler_crashers/26284-swift-inflightdiagnostic-fixitreplacechars.swift rename to validation-test/compiler_crashers_fixed/26284-swift-inflightdiagnostic-fixitreplacechars.swift index 0d7eccdeeedbe..4594dd028f9b4 100644 --- a/validation-test/compiler_crashers/26284-swift-inflightdiagnostic-fixitreplacechars.swift +++ b/validation-test/compiler_crashers_fixed/26284-swift-inflightdiagnostic-fixitreplacechars.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26290-swift-inouttype-get.swift b/validation-test/compiler_crashers_fixed/26290-swift-inouttype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26290-swift-inouttype-get.swift rename to validation-test/compiler_crashers_fixed/26290-swift-inouttype-get.swift index dbea69070de81..3ed936a5c7c37 100644 --- a/validation-test/compiler_crashers/26290-swift-inouttype-get.swift +++ b/validation-test/compiler_crashers_fixed/26290-swift-inouttype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26291-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/26291-swift-diagnosticengine-emitdiagnostic.swift similarity index 83% rename from validation-test/compiler_crashers/26291-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/26291-swift-diagnosticengine-emitdiagnostic.swift index e019b7248753a..c277979be0c77 100644 --- a/validation-test/compiler_crashers/26291-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26291-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26292-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/26292-swift-modulefile-getimportedmodules.swift similarity index 79% rename from validation-test/compiler_crashers/26292-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/26292-swift-modulefile-getimportedmodules.swift index 1069d35928070..52220a5cb7ebd 100644 --- a/validation-test/compiler_crashers/26292-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/26292-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26293-swift-conformancelookuptable-getconformance.swift b/validation-test/compiler_crashers_fixed/26293-swift-conformancelookuptable-getconformance.swift similarity index 81% rename from validation-test/compiler_crashers/26293-swift-conformancelookuptable-getconformance.swift rename to validation-test/compiler_crashers_fixed/26293-swift-conformancelookuptable-getconformance.swift index f3a6c400ea703..05737b5c8b8a7 100644 --- a/validation-test/compiler_crashers/26293-swift-conformancelookuptable-getconformance.swift +++ b/validation-test/compiler_crashers_fixed/26293-swift-conformancelookuptable-getconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26294-void.swift b/validation-test/compiler_crashers_fixed/26294-void.swift similarity index 80% rename from validation-test/compiler_crashers/26294-void.swift rename to validation-test/compiler_crashers_fixed/26294-void.swift index 2f9db3a3df7b8..082709bdfcf2e 100644 --- a/validation-test/compiler_crashers/26294-void.swift +++ b/validation-test/compiler_crashers_fixed/26294-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers_fixed/26296-duplicate-subscript-declaration.swift b/validation-test/compiler_crashers_fixed/26296-duplicate-subscript-declaration.swift new file mode 100644 index 0000000000000..52ef5dcdae953 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/26296-duplicate-subscript-declaration.swift @@ -0,0 +1,15 @@ +// RUN: not %target-swift-frontend %s -parse + +// rdar://22007370 + +class Foo { + subscript(key: String) -> String { + get { a } + set { b } + } + + subscript(key: String) -> String { + get { a } + set { b } + } +} diff --git a/validation-test/compiler_crashers_fixed/26298-llvm-densemapbase.swift b/validation-test/compiler_crashers_fixed/26298-llvm-densemapbase.swift new file mode 100644 index 0000000000000..ee2f70a8c4d64 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/26298-llvm-densemapbase.swift @@ -0,0 +1,5 @@ +// RUN: %target-swift-frontend %s -emit-silgen +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/airspeedswift (airspeedswift) + +["1"].map { String($0) } diff --git a/validation-test/compiler_crashers/26314-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/26314-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 80% rename from validation-test/compiler_crashers/26314-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/26314-swift-typechecker-overapproximateosversionsatlocation.swift index 2e77916f71ccf..94d74819ee4d5 100644 --- a/validation-test/compiler_crashers/26314-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/26314-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26318-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/26318-swift-substitutedtype-get.swift similarity index 80% rename from validation-test/compiler_crashers/26318-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/26318-swift-substitutedtype-get.swift index 426240fdcd2de..5250cf810aa88 100644 --- a/validation-test/compiler_crashers/26318-swift-substitutedtype-get.swift +++ b/validation-test/compiler_crashers_fixed/26318-swift-substitutedtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26321-swift-genericparamlist-create.swift b/validation-test/compiler_crashers_fixed/26321-swift-genericparamlist-create.swift similarity index 81% rename from validation-test/compiler_crashers/26321-swift-genericparamlist-create.swift rename to validation-test/compiler_crashers_fixed/26321-swift-genericparamlist-create.swift index 40bfd1d536fa3..6bc8bf291d376 100644 --- a/validation-test/compiler_crashers/26321-swift-genericparamlist-create.swift +++ b/validation-test/compiler_crashers_fixed/26321-swift-genericparamlist-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26337-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/26337-swift-modulefile-maybereadgenericparams.swift similarity index 82% rename from validation-test/compiler_crashers/26337-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/26337-swift-modulefile-maybereadgenericparams.swift index a3a4987d53a14..25240c7503c6c 100644 --- a/validation-test/compiler_crashers/26337-swift-modulefile-maybereadgenericparams.swift +++ b/validation-test/compiler_crashers_fixed/26337-swift-modulefile-maybereadgenericparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26342-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26342-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/26342-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26342-swift-printingdiagnosticconsumer-handlediagnostic.swift index 04fa0df7b7108..5e35eb5b0dcc3 100644 --- a/validation-test/compiler_crashers/26342-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26342-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26344-swift-parser-parseexprclosure.swift b/validation-test/compiler_crashers_fixed/26344-swift-parser-parseexprclosure.swift similarity index 81% rename from validation-test/compiler_crashers/26344-swift-parser-parseexprclosure.swift rename to validation-test/compiler_crashers_fixed/26344-swift-parser-parseexprclosure.swift index da9fd31183351..4d682b21305b0 100644 --- a/validation-test/compiler_crashers/26344-swift-parser-parseexprclosure.swift +++ b/validation-test/compiler_crashers_fixed/26344-swift-parser-parseexprclosure.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26345-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/26345-swift-constraints-solution-solution.swift similarity index 81% rename from validation-test/compiler_crashers/26345-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/26345-swift-constraints-solution-solution.swift index 90c3951efde6b..c77d693c87d78 100644 --- a/validation-test/compiler_crashers/26345-swift-constraints-solution-solution.swift +++ b/validation-test/compiler_crashers_fixed/26345-swift-constraints-solution-solution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26355-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift b/validation-test/compiler_crashers_fixed/26355-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift similarity index 81% rename from validation-test/compiler_crashers/26355-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift rename to validation-test/compiler_crashers_fixed/26355-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift index d2aeb9a892454..511abed7a6fcb 100644 --- a/validation-test/compiler_crashers/26355-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift +++ b/validation-test/compiler_crashers_fixed/26355-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26358-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/26358-swift-typechecker-checkinheritanceclause.swift similarity index 81% rename from validation-test/compiler_crashers/26358-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/26358-swift-typechecker-checkinheritanceclause.swift index 042dbd9ccfe0c..22878e4eb9ba4 100644 --- a/validation-test/compiler_crashers/26358-swift-typechecker-checkinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/26358-swift-typechecker-checkinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26365-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/26365-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 83% rename from validation-test/compiler_crashers/26365-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/26365-swift-constraints-constraintgraph-gatherconstraints.swift index 5427468dcbfa7..7ce00f609a6fb 100644 --- a/validation-test/compiler_crashers/26365-swift-constraints-constraintgraph-gatherconstraints.swift +++ b/validation-test/compiler_crashers_fixed/26365-swift-constraints-constraintgraph-gatherconstraints.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26366-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/26366-swift-nominaltypedecl-preparelookuptable.swift similarity index 80% rename from validation-test/compiler_crashers/26366-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/26366-swift-nominaltypedecl-preparelookuptable.swift index 43577b029a46c..6d037097f2ed6 100644 --- a/validation-test/compiler_crashers/26366-swift-nominaltypedecl-preparelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/26366-swift-nominaltypedecl-preparelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26369-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/26369-swift-substitutedtype-get.swift similarity index 85% rename from validation-test/compiler_crashers/26369-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/26369-swift-substitutedtype-get.swift index a6b41b6594403..3438fa73c62de 100644 --- a/validation-test/compiler_crashers/26369-swift-substitutedtype-get.swift +++ b/validation-test/compiler_crashers_fixed/26369-swift-substitutedtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26371-swift-typechecker-validatetype.swift b/validation-test/compiler_crashers_fixed/26371-swift-typechecker-validatetype.swift similarity index 82% rename from validation-test/compiler_crashers/26371-swift-typechecker-validatetype.swift rename to validation-test/compiler_crashers_fixed/26371-swift-typechecker-validatetype.swift index 89ecf4fbdaa22..f832bce008c4d 100644 --- a/validation-test/compiler_crashers/26371-swift-typechecker-validatetype.swift +++ b/validation-test/compiler_crashers_fixed/26371-swift-typechecker-validatetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26376-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/26376-swift-metatypetype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26376-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/26376-swift-metatypetype-get.swift index e346345632f81..7a5fbd0604705 100644 --- a/validation-test/compiler_crashers/26376-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/26376-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26377-swift-astcontext-allocate.swift b/validation-test/compiler_crashers_fixed/26377-swift-astcontext-allocate.swift similarity index 82% rename from validation-test/compiler_crashers/26377-swift-astcontext-allocate.swift rename to validation-test/compiler_crashers_fixed/26377-swift-astcontext-allocate.swift index 783644c7d2b12..8d3ea156140b3 100644 --- a/validation-test/compiler_crashers/26377-swift-astcontext-allocate.swift +++ b/validation-test/compiler_crashers_fixed/26377-swift-astcontext-allocate.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26386-swift-typevisitor.swift b/validation-test/compiler_crashers_fixed/26386-swift-typevisitor.swift similarity index 79% rename from validation-test/compiler_crashers/26386-swift-typevisitor.swift rename to validation-test/compiler_crashers_fixed/26386-swift-typevisitor.swift index ab1b37249fa02..a4133e0116b86 100644 --- a/validation-test/compiler_crashers/26386-swift-typevisitor.swift +++ b/validation-test/compiler_crashers_fixed/26386-swift-typevisitor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26390-swift-mangle-mangler-mangledeclname.swift b/validation-test/compiler_crashers_fixed/26390-swift-mangle-mangler-mangledeclname.swift similarity index 82% rename from validation-test/compiler_crashers/26390-swift-mangle-mangler-mangledeclname.swift rename to validation-test/compiler_crashers_fixed/26390-swift-mangle-mangler-mangledeclname.swift index 00ea5d43aaae5..66ca0d190dbc7 100644 --- a/validation-test/compiler_crashers/26390-swift-mangle-mangler-mangledeclname.swift +++ b/validation-test/compiler_crashers_fixed/26390-swift-mangle-mangler-mangledeclname.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26391-swift-scopeinfo-addtoscope.swift b/validation-test/compiler_crashers_fixed/26391-swift-scopeinfo-addtoscope.swift similarity index 82% rename from validation-test/compiler_crashers/26391-swift-scopeinfo-addtoscope.swift rename to validation-test/compiler_crashers_fixed/26391-swift-scopeinfo-addtoscope.swift index 5af1ba2da8fb6..d5d1462056065 100644 --- a/validation-test/compiler_crashers/26391-swift-scopeinfo-addtoscope.swift +++ b/validation-test/compiler_crashers_fixed/26391-swift-scopeinfo-addtoscope.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26392-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/26392-swift-abstractclosureexpr-setparams.swift similarity index 84% rename from validation-test/compiler_crashers/26392-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/26392-swift-abstractclosureexpr-setparams.swift index f7ea2eac38dd7..35e5acc4ab20c 100644 --- a/validation-test/compiler_crashers/26392-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/26392-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26395-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift b/validation-test/compiler_crashers_fixed/26395-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift similarity index 81% rename from validation-test/compiler_crashers/26395-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift rename to validation-test/compiler_crashers_fixed/26395-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift index f735ac8cff586..605ad9fbd2901 100644 --- a/validation-test/compiler_crashers/26395-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift +++ b/validation-test/compiler_crashers_fixed/26395-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26399-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/26399-swift-genericparamlist-addnestedarchetypes.swift similarity index 81% rename from validation-test/compiler_crashers/26399-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/26399-swift-genericparamlist-addnestedarchetypes.swift index 6d642983b1816..82dc7dbcde343 100644 --- a/validation-test/compiler_crashers/26399-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/26399-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26405-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26405-swift-typechecker-validatedecl.swift similarity index 84% rename from validation-test/compiler_crashers/26405-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26405-swift-typechecker-validatedecl.swift index dff2de4eea486..4dd1b0660d013 100644 --- a/validation-test/compiler_crashers/26405-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26405-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26420-swift-astcontext-getidentifier.swift b/validation-test/compiler_crashers_fixed/26420-swift-astcontext-getidentifier.swift similarity index 82% rename from validation-test/compiler_crashers/26420-swift-astcontext-getidentifier.swift rename to validation-test/compiler_crashers_fixed/26420-swift-astcontext-getidentifier.swift index 9c2ac093a5bd6..89d435f51ae21 100644 --- a/validation-test/compiler_crashers/26420-swift-astcontext-getidentifier.swift +++ b/validation-test/compiler_crashers_fixed/26420-swift-astcontext-getidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26422-swift-typevariabletype-implementation-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/26422-swift-typevariabletype-implementation-assignfixedtype.swift similarity index 81% rename from validation-test/compiler_crashers/26422-swift-typevariabletype-implementation-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/26422-swift-typevariabletype-implementation-assignfixedtype.swift index bdd9c28defd14..fcce0ae0ff39a 100644 --- a/validation-test/compiler_crashers/26422-swift-typevariabletype-implementation-assignfixedtype.swift +++ b/validation-test/compiler_crashers_fixed/26422-swift-typevariabletype-implementation-assignfixedtype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26430-swift-expr-walk.swift b/validation-test/compiler_crashers_fixed/26430-swift-expr-walk.swift similarity index 81% rename from validation-test/compiler_crashers/26430-swift-expr-walk.swift rename to validation-test/compiler_crashers_fixed/26430-swift-expr-walk.swift index 51f8e70c88f84..2373a2a44e631 100644 --- a/validation-test/compiler_crashers/26430-swift-expr-walk.swift +++ b/validation-test/compiler_crashers_fixed/26430-swift-expr-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26438-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/26438-swift-typebase-isequal.swift similarity index 82% rename from validation-test/compiler_crashers/26438-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/26438-swift-typebase-isequal.swift index a724a9e3792a2..8c97022b2729d 100644 --- a/validation-test/compiler_crashers/26438-swift-typebase-isequal.swift +++ b/validation-test/compiler_crashers_fixed/26438-swift-typebase-isequal.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26450-swift-constraints-constraintsystem-applysolution.swift b/validation-test/compiler_crashers_fixed/26450-swift-constraints-constraintsystem-applysolution.swift similarity index 79% rename from validation-test/compiler_crashers/26450-swift-constraints-constraintsystem-applysolution.swift rename to validation-test/compiler_crashers_fixed/26450-swift-constraints-constraintsystem-applysolution.swift index d489b88d1bd88..31fdee9d066c3 100644 --- a/validation-test/compiler_crashers/26450-swift-constraints-constraintsystem-applysolution.swift +++ b/validation-test/compiler_crashers_fixed/26450-swift-constraints-constraintsystem-applysolution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26453-swift-astcontext-getloadedmodule.swift b/validation-test/compiler_crashers_fixed/26453-swift-astcontext-getloadedmodule.swift similarity index 82% rename from validation-test/compiler_crashers/26453-swift-astcontext-getloadedmodule.swift rename to validation-test/compiler_crashers_fixed/26453-swift-astcontext-getloadedmodule.swift index 0992ea5c1dc04..ed434240b2f6b 100644 --- a/validation-test/compiler_crashers/26453-swift-astcontext-getloadedmodule.swift +++ b/validation-test/compiler_crashers_fixed/26453-swift-astcontext-getloadedmodule.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26462-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/26462-swift-modulefile-getdecl.swift similarity index 81% rename from validation-test/compiler_crashers/26462-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/26462-swift-modulefile-getdecl.swift index f5b3ee430ea45..bea847577aba0 100644 --- a/validation-test/compiler_crashers/26462-swift-modulefile-getdecl.swift +++ b/validation-test/compiler_crashers_fixed/26462-swift-modulefile-getdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26468-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/26468-swift-lexer-leximpl.swift similarity index 86% rename from validation-test/compiler_crashers/26468-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/26468-swift-lexer-leximpl.swift index 14d5ef62f8391..bacdd5c1b14f1 100644 --- a/validation-test/compiler_crashers/26468-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/26468-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26471-swift-iterabledeclcontext-getmembers.swift b/validation-test/compiler_crashers_fixed/26471-swift-iterabledeclcontext-getmembers.swift similarity index 85% rename from validation-test/compiler_crashers/26471-swift-iterabledeclcontext-getmembers.swift rename to validation-test/compiler_crashers_fixed/26471-swift-iterabledeclcontext-getmembers.swift index ba6966ed44c26..90e2fd9e88727 100644 --- a/validation-test/compiler_crashers/26471-swift-iterabledeclcontext-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/26471-swift-iterabledeclcontext-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26473-swift-constraints-constraint-constraint.swift b/validation-test/compiler_crashers_fixed/26473-swift-constraints-constraint-constraint.swift similarity index 82% rename from validation-test/compiler_crashers/26473-swift-constraints-constraint-constraint.swift rename to validation-test/compiler_crashers_fixed/26473-swift-constraints-constraint-constraint.swift index 399368720c313..f6fca3c589882 100644 --- a/validation-test/compiler_crashers/26473-swift-constraints-constraint-constraint.swift +++ b/validation-test/compiler_crashers_fixed/26473-swift-constraints-constraint-constraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26474-std-function-func-swift-typechecker-validategenericfuncsignature.swift b/validation-test/compiler_crashers_fixed/26474-std-function-func-swift-typechecker-validategenericfuncsignature.swift similarity index 82% rename from validation-test/compiler_crashers/26474-std-function-func-swift-typechecker-validategenericfuncsignature.swift rename to validation-test/compiler_crashers_fixed/26474-std-function-func-swift-typechecker-validategenericfuncsignature.swift index ccdf07bf40efa..4f8bb2b5d4f19 100644 --- a/validation-test/compiler_crashers/26474-std-function-func-swift-typechecker-validategenericfuncsignature.swift +++ b/validation-test/compiler_crashers_fixed/26474-std-function-func-swift-typechecker-validategenericfuncsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26486-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/26486-swift-modulefile-maybereadpattern.swift similarity index 80% rename from validation-test/compiler_crashers/26486-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/26486-swift-modulefile-maybereadpattern.swift index 7db36ffb3e497..4557122786629 100644 --- a/validation-test/compiler_crashers/26486-swift-modulefile-maybereadpattern.swift +++ b/validation-test/compiler_crashers_fixed/26486-swift-modulefile-maybereadpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26491-swift-abstractstoragedecl-makecomputed.swift b/validation-test/compiler_crashers_fixed/26491-swift-abstractstoragedecl-makecomputed.swift similarity index 83% rename from validation-test/compiler_crashers/26491-swift-abstractstoragedecl-makecomputed.swift rename to validation-test/compiler_crashers_fixed/26491-swift-abstractstoragedecl-makecomputed.swift index c19e128a8d539..8d8f3ad49a7ab 100644 --- a/validation-test/compiler_crashers/26491-swift-abstractstoragedecl-makecomputed.swift +++ b/validation-test/compiler_crashers_fixed/26491-swift-abstractstoragedecl-makecomputed.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26494-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/26494-swift-diagnosticengine-flushactivediagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/26494-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/26494-swift-diagnosticengine-flushactivediagnostic.swift index 1dab288d4e1c2..7c0007d09cace 100644 --- a/validation-test/compiler_crashers/26494-swift-diagnosticengine-flushactivediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26494-swift-diagnosticengine-flushactivediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26496-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/26496-swift-parser-skipsingle.swift similarity index 84% rename from validation-test/compiler_crashers/26496-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/26496-swift-parser-skipsingle.swift index bcd88f67d1603..b1c78007f7159 100644 --- a/validation-test/compiler_crashers/26496-swift-parser-skipsingle.swift +++ b/validation-test/compiler_crashers_fixed/26496-swift-parser-skipsingle.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26497-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/26497-swift-diagnosticengine-emitdiagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/26497-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/26497-swift-diagnosticengine-emitdiagnostic.swift index 2c18cbc599dcd..4b6df707ae6e0 100644 --- a/validation-test/compiler_crashers/26497-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26497-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26498-swift-sourcefile-lookupcache-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26498-swift-sourcefile-lookupcache-lookupvalue.swift similarity index 80% rename from validation-test/compiler_crashers/26498-swift-sourcefile-lookupcache-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26498-swift-sourcefile-lookupcache-lookupvalue.swift index 64e3d7e317770..a1c547d894a3b 100644 --- a/validation-test/compiler_crashers/26498-swift-sourcefile-lookupcache-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26498-swift-sourcefile-lookupcache-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26499-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/26499-swift-constraints-constraintgraph-addconstraint.swift similarity index 82% rename from validation-test/compiler_crashers/26499-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/26499-swift-constraints-constraintgraph-addconstraint.swift index a8366aeb04bdf..ebd4745c97845 100644 --- a/validation-test/compiler_crashers/26499-swift-constraints-constraintgraph-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/26499-swift-constraints-constraintgraph-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26501-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/26501-swift-lexer-leximpl.swift similarity index 86% rename from validation-test/compiler_crashers/26501-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/26501-swift-lexer-leximpl.swift index a79b649c82b4a..c3b0779dbc453 100644 --- a/validation-test/compiler_crashers/26501-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/26501-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26507-swift-sourcemanager-extracttext.swift b/validation-test/compiler_crashers_fixed/26507-swift-sourcemanager-extracttext.swift similarity index 83% rename from validation-test/compiler_crashers/26507-swift-sourcemanager-extracttext.swift rename to validation-test/compiler_crashers_fixed/26507-swift-sourcemanager-extracttext.swift index 8e30bf4dd1864..4fbd77cd2506a 100644 --- a/validation-test/compiler_crashers/26507-swift-sourcemanager-extracttext.swift +++ b/validation-test/compiler_crashers_fixed/26507-swift-sourcemanager-extracttext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26514-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/26514-swift-parser-skipsingle.swift similarity index 85% rename from validation-test/compiler_crashers/26514-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/26514-swift-parser-skipsingle.swift index fea62e38c488c..624b092f0fa4d 100644 --- a/validation-test/compiler_crashers/26514-swift-parser-skipsingle.swift +++ b/validation-test/compiler_crashers_fixed/26514-swift-parser-skipsingle.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26515-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/26515-swift-metatypetype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26515-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/26515-swift-metatypetype-get.swift index 07e3ca66432d6..0c37878e6542f 100644 --- a/validation-test/compiler_crashers/26515-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/26515-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26516-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/26516-swift-boundgenerictype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26516-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/26516-swift-boundgenerictype-get.swift index bee087f6ae3aa..d4859c90345be 100644 --- a/validation-test/compiler_crashers/26516-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/26516-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26518-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/26518-swift-diagnosticengine-flushactivediagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/26518-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/26518-swift-diagnosticengine-flushactivediagnostic.swift index 1a065c3c02323..befbd16e80a5d 100644 --- a/validation-test/compiler_crashers/26518-swift-diagnosticengine-flushactivediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26518-swift-diagnosticengine-flushactivediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26521-swift-modulefile-getdeclcontext.swift b/validation-test/compiler_crashers_fixed/26521-swift-modulefile-getdeclcontext.swift similarity index 81% rename from validation-test/compiler_crashers/26521-swift-modulefile-getdeclcontext.swift rename to validation-test/compiler_crashers_fixed/26521-swift-modulefile-getdeclcontext.swift index 66a94f5e6385e..0790c79c968cf 100644 --- a/validation-test/compiler_crashers/26521-swift-modulefile-getdeclcontext.swift +++ b/validation-test/compiler_crashers_fixed/26521-swift-modulefile-getdeclcontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26523-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/26523-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 81% rename from validation-test/compiler_crashers/26523-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/26523-swift-constraints-constraintgraph-gatherconstraints.swift index 56086d782bcd0..320aa6a12c21b 100644 --- a/validation-test/compiler_crashers/26523-swift-constraints-constraintgraph-gatherconstraints.swift +++ b/validation-test/compiler_crashers_fixed/26523-swift-constraints-constraintgraph-gatherconstraints.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26528-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26528-swift-modulefile-lookupvalue.swift similarity index 80% rename from validation-test/compiler_crashers/26528-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26528-swift-modulefile-lookupvalue.swift index de58f00648cf4..f559d85781420 100644 --- a/validation-test/compiler_crashers/26528-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26528-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26529-swift-typechecker-validatetype.swift b/validation-test/compiler_crashers_fixed/26529-swift-typechecker-validatetype.swift similarity index 81% rename from validation-test/compiler_crashers/26529-swift-typechecker-validatetype.swift rename to validation-test/compiler_crashers_fixed/26529-swift-typechecker-validatetype.swift index b45291807dd33..a29439048ee52 100644 --- a/validation-test/compiler_crashers/26529-swift-typechecker-validatetype.swift +++ b/validation-test/compiler_crashers_fixed/26529-swift-typechecker-validatetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26538-swift-parser-parsegetsetimpl.swift b/validation-test/compiler_crashers_fixed/26538-swift-parser-parsegetsetimpl.swift similarity index 82% rename from validation-test/compiler_crashers/26538-swift-parser-parsegetsetimpl.swift rename to validation-test/compiler_crashers_fixed/26538-swift-parser-parsegetsetimpl.swift index b7b7b553c5007..d7f3d59382927 100644 --- a/validation-test/compiler_crashers/26538-swift-parser-parsegetsetimpl.swift +++ b/validation-test/compiler_crashers_fixed/26538-swift-parser-parsegetsetimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26544-swift-sourcefile-lookupcache-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26544-swift-sourcefile-lookupcache-lookupvalue.swift similarity index 81% rename from validation-test/compiler_crashers/26544-swift-sourcefile-lookupcache-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26544-swift-sourcefile-lookupcache-lookupvalue.swift index 6dbd01fe1a60d..ac0c073f3366c 100644 --- a/validation-test/compiler_crashers/26544-swift-sourcefile-lookupcache-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26544-swift-sourcefile-lookupcache-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26546-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/26546-swift-parser-skipsingle.swift similarity index 85% rename from validation-test/compiler_crashers/26546-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/26546-swift-parser-skipsingle.swift index 355c468629a42..5e34cd1c68a05 100644 --- a/validation-test/compiler_crashers/26546-swift-parser-skipsingle.swift +++ b/validation-test/compiler_crashers_fixed/26546-swift-parser-skipsingle.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26549-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/26549-swift-typechecker-resolvetypeincontext.swift similarity index 80% rename from validation-test/compiler_crashers/26549-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/26549-swift-typechecker-resolvetypeincontext.swift index 62d29d12712b3..ce06065be9ee2 100644 --- a/validation-test/compiler_crashers/26549-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/26549-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26555-swift-typechecker-checkgenericarguments.swift b/validation-test/compiler_crashers_fixed/26555-swift-typechecker-checkgenericarguments.swift similarity index 82% rename from validation-test/compiler_crashers/26555-swift-typechecker-checkgenericarguments.swift rename to validation-test/compiler_crashers_fixed/26555-swift-typechecker-checkgenericarguments.swift index 0c5cbf961dc90..7f0c8001eec9a 100644 --- a/validation-test/compiler_crashers/26555-swift-typechecker-checkgenericarguments.swift +++ b/validation-test/compiler_crashers_fixed/26555-swift-typechecker-checkgenericarguments.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26561-swift-sourcemanager-extracttext.swift b/validation-test/compiler_crashers_fixed/26561-swift-sourcemanager-extracttext.swift similarity index 82% rename from validation-test/compiler_crashers/26561-swift-sourcemanager-extracttext.swift rename to validation-test/compiler_crashers_fixed/26561-swift-sourcemanager-extracttext.swift index 289ad959bb428..04b13d2262402 100644 --- a/validation-test/compiler_crashers/26561-swift-sourcemanager-extracttext.swift +++ b/validation-test/compiler_crashers_fixed/26561-swift-sourcemanager-extracttext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26564-swift-parser-parsedecl.swift b/validation-test/compiler_crashers_fixed/26564-swift-parser-parsedecl.swift similarity index 82% rename from validation-test/compiler_crashers/26564-swift-parser-parsedecl.swift rename to validation-test/compiler_crashers_fixed/26564-swift-parser-parsedecl.swift index dcf120d024718..9cceae5406baa 100644 --- a/validation-test/compiler_crashers/26564-swift-parser-parsedecl.swift +++ b/validation-test/compiler_crashers_fixed/26564-swift-parser-parsedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26565-swift-constraints-constraintsystem-salvage.swift b/validation-test/compiler_crashers_fixed/26565-swift-constraints-constraintsystem-salvage.swift similarity index 82% rename from validation-test/compiler_crashers/26565-swift-constraints-constraintsystem-salvage.swift rename to validation-test/compiler_crashers_fixed/26565-swift-constraints-constraintsystem-salvage.swift index 58e1cc4621226..9081ad630e853 100644 --- a/validation-test/compiler_crashers/26565-swift-constraints-constraintsystem-salvage.swift +++ b/validation-test/compiler_crashers_fixed/26565-swift-constraints-constraintsystem-salvage.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26566-swift-parser-parsedecl.swift b/validation-test/compiler_crashers_fixed/26566-swift-parser-parsedecl.swift similarity index 82% rename from validation-test/compiler_crashers/26566-swift-parser-parsedecl.swift rename to validation-test/compiler_crashers_fixed/26566-swift-parser-parsedecl.swift index 12c333ac5ae89..9c4cebb4f614c 100644 --- a/validation-test/compiler_crashers/26566-swift-parser-parsedecl.swift +++ b/validation-test/compiler_crashers_fixed/26566-swift-parser-parsedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26568-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26568-swift-typechecker-validatedecl.swift similarity index 81% rename from validation-test/compiler_crashers/26568-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26568-swift-typechecker-validatedecl.swift index aa0f4c979474d..9096b2ff06f5a 100644 --- a/validation-test/compiler_crashers/26568-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26568-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26572-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/26572-swift-typechecker-checkinheritanceclause.swift similarity index 85% rename from validation-test/compiler_crashers/26572-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/26572-swift-typechecker-checkinheritanceclause.swift index 3ca76bf37b1ea..bbee31165b823 100644 --- a/validation-test/compiler_crashers/26572-swift-typechecker-checkinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/26572-swift-typechecker-checkinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26573-swift-parser-parseanyidentifier.swift b/validation-test/compiler_crashers_fixed/26573-swift-parser-parseanyidentifier.swift similarity index 82% rename from validation-test/compiler_crashers/26573-swift-parser-parseanyidentifier.swift rename to validation-test/compiler_crashers_fixed/26573-swift-parser-parseanyidentifier.swift index 39c301a725ca8..f687811f671dd 100644 --- a/validation-test/compiler_crashers/26573-swift-parser-parseanyidentifier.swift +++ b/validation-test/compiler_crashers_fixed/26573-swift-parser-parseanyidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26579-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/26579-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 80% rename from validation-test/compiler_crashers/26579-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/26579-swift-typechecker-overapproximateosversionsatlocation.swift index 35d0a0923c04d..d913309f8d169 100644 --- a/validation-test/compiler_crashers/26579-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/26579-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26583-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26583-swift-typechecker-validatedecl.swift similarity index 80% rename from validation-test/compiler_crashers/26583-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26583-swift-typechecker-validatedecl.swift index e9d4d828e84dc..e5b028ccac1f0 100644 --- a/validation-test/compiler_crashers/26583-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26583-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26587-swift-typechecker-computeaccessibility.swift b/validation-test/compiler_crashers_fixed/26587-swift-typechecker-computeaccessibility.swift similarity index 81% rename from validation-test/compiler_crashers/26587-swift-typechecker-computeaccessibility.swift rename to validation-test/compiler_crashers_fixed/26587-swift-typechecker-computeaccessibility.swift index 2b11daf3429ea..b7845b06549a6 100644 --- a/validation-test/compiler_crashers/26587-swift-typechecker-computeaccessibility.swift +++ b/validation-test/compiler_crashers_fixed/26587-swift-typechecker-computeaccessibility.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26593-void.swift b/validation-test/compiler_crashers_fixed/26593-void.swift similarity index 81% rename from validation-test/compiler_crashers/26593-void.swift rename to validation-test/compiler_crashers_fixed/26593-void.swift index 11b7338a9e7f1..37c4686af65d3 100644 --- a/validation-test/compiler_crashers/26593-void.swift +++ b/validation-test/compiler_crashers_fixed/26593-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26597-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/26597-swift-typebase-isequal.swift similarity index 84% rename from validation-test/compiler_crashers/26597-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/26597-swift-typebase-isequal.swift index 70b05ea2d5942..365f1c72c3b21 100644 --- a/validation-test/compiler_crashers/26597-swift-typebase-isequal.swift +++ b/validation-test/compiler_crashers_fixed/26597-swift-typebase-isequal.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26606-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/26606-swift-genericsignature-get.swift similarity index 81% rename from validation-test/compiler_crashers/26606-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/26606-swift-genericsignature-get.swift index 20a8a74e159ec..5a8057cd0f0da 100644 --- a/validation-test/compiler_crashers/26606-swift-genericsignature-get.swift +++ b/validation-test/compiler_crashers_fixed/26606-swift-genericsignature-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26623-std-function-func-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/26623-std-function-func-swift-constraints-solution-computesubstitutions.swift similarity index 83% rename from validation-test/compiler_crashers/26623-std-function-func-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/26623-std-function-func-swift-constraints-solution-computesubstitutions.swift index 270ff57dada08..c10677d912182 100644 --- a/validation-test/compiler_crashers/26623-std-function-func-swift-constraints-solution-computesubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/26623-std-function-func-swift-constraints-solution-computesubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26625-swift-typechecker-resolveinheritanceclause.swift b/validation-test/compiler_crashers_fixed/26625-swift-typechecker-resolveinheritanceclause.swift similarity index 80% rename from validation-test/compiler_crashers/26625-swift-typechecker-resolveinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/26625-swift-typechecker-resolveinheritanceclause.swift index 507e24922a9f2..2dda0291956b5 100644 --- a/validation-test/compiler_crashers/26625-swift-typechecker-resolveinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/26625-swift-typechecker-resolveinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26631-swift-sourcemanager-getbytedistance.swift b/validation-test/compiler_crashers_fixed/26631-swift-sourcemanager-getbytedistance.swift similarity index 80% rename from validation-test/compiler_crashers/26631-swift-sourcemanager-getbytedistance.swift rename to validation-test/compiler_crashers_fixed/26631-swift-sourcemanager-getbytedistance.swift index eac5879ad30cb..27dbb171cce08 100644 --- a/validation-test/compiler_crashers/26631-swift-sourcemanager-getbytedistance.swift +++ b/validation-test/compiler_crashers_fixed/26631-swift-sourcemanager-getbytedistance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26636-swift-tuplepattern-create.swift b/validation-test/compiler_crashers_fixed/26636-swift-tuplepattern-create.swift similarity index 79% rename from validation-test/compiler_crashers/26636-swift-tuplepattern-create.swift rename to validation-test/compiler_crashers_fixed/26636-swift-tuplepattern-create.swift index 9a15c9840227a..708f4440878a4 100644 --- a/validation-test/compiler_crashers/26636-swift-tuplepattern-create.swift +++ b/validation-test/compiler_crashers_fixed/26636-swift-tuplepattern-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26640-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/26640-swift-functiontype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26640-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/26640-swift-functiontype-get.swift index fb979cac3db7d..304048dbbe243 100644 --- a/validation-test/compiler_crashers/26640-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/26640-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26642-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/26642-swift-genericsignature-get.swift similarity index 82% rename from validation-test/compiler_crashers/26642-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/26642-swift-genericsignature-get.swift index cde38d4372335..7ed48478ae0db 100644 --- a/validation-test/compiler_crashers/26642-swift-genericsignature-get.swift +++ b/validation-test/compiler_crashers_fixed/26642-swift-genericsignature-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26643-resolveidenttypecomponent.swift b/validation-test/compiler_crashers_fixed/26643-resolveidenttypecomponent.swift similarity index 79% rename from validation-test/compiler_crashers/26643-resolveidenttypecomponent.swift rename to validation-test/compiler_crashers_fixed/26643-resolveidenttypecomponent.swift index 177df443aef8c..1dd64082ce254 100644 --- a/validation-test/compiler_crashers/26643-resolveidenttypecomponent.swift +++ b/validation-test/compiler_crashers_fixed/26643-resolveidenttypecomponent.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26649-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/26649-swift-lexer-leximpl.swift similarity index 87% rename from validation-test/compiler_crashers/26649-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/26649-swift-lexer-leximpl.swift index 22f8a79d1adae..20b53fa4a2658 100644 --- a/validation-test/compiler_crashers/26649-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/26649-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26652-std-function-func-mapsignaturetype.swift b/validation-test/compiler_crashers_fixed/26652-std-function-func-mapsignaturetype.swift similarity index 83% rename from validation-test/compiler_crashers/26652-std-function-func-mapsignaturetype.swift rename to validation-test/compiler_crashers_fixed/26652-std-function-func-mapsignaturetype.swift index 8539a58ef17b0..44fa9925b209b 100644 --- a/validation-test/compiler_crashers/26652-std-function-func-mapsignaturetype.swift +++ b/validation-test/compiler_crashers_fixed/26652-std-function-func-mapsignaturetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26653-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26653-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/26653-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26653-swift-printingdiagnosticconsumer-handlediagnostic.swift index 7a636003fb8df..cf261210bfd18 100644 --- a/validation-test/compiler_crashers/26653-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26653-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26657-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/26657-swift-tupletype-get.swift similarity index 80% rename from validation-test/compiler_crashers/26657-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/26657-swift-tupletype-get.swift index 6874af96b5000..4ceb9f9ead60b 100644 --- a/validation-test/compiler_crashers/26657-swift-tupletype-get.swift +++ b/validation-test/compiler_crashers_fixed/26657-swift-tupletype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26661-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/26661-swift-typechecker-coercepatterntotype.swift similarity index 79% rename from validation-test/compiler_crashers/26661-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/26661-swift-typechecker-coercepatterntotype.swift index e69c1b0509e94..35a789ee7b03c 100644 --- a/validation-test/compiler_crashers/26661-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/26661-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26673-llvm-triple-getosname.swift b/validation-test/compiler_crashers_fixed/26673-llvm-triple-getosname.swift similarity index 81% rename from validation-test/compiler_crashers/26673-llvm-triple-getosname.swift rename to validation-test/compiler_crashers_fixed/26673-llvm-triple-getosname.swift index 393bcf559f37b..994d3698d5998 100644 --- a/validation-test/compiler_crashers/26673-llvm-triple-getosname.swift +++ b/validation-test/compiler_crashers_fixed/26673-llvm-triple-getosname.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26678-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/26678-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 80% rename from validation-test/compiler_crashers/26678-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/26678-swift-typechecker-overapproximateosversionsatlocation.swift index 97b2213171fca..f0fa166a4e18a 100644 --- a/validation-test/compiler_crashers/26678-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/26678-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26681-swift-sourcemanager-getbytedistance.swift b/validation-test/compiler_crashers_fixed/26681-swift-sourcemanager-getbytedistance.swift similarity index 82% rename from validation-test/compiler_crashers/26681-swift-sourcemanager-getbytedistance.swift rename to validation-test/compiler_crashers_fixed/26681-swift-sourcemanager-getbytedistance.swift index 3ab06f372ad57..d959a8d34e68b 100644 --- a/validation-test/compiler_crashers/26681-swift-sourcemanager-getbytedistance.swift +++ b/validation-test/compiler_crashers_fixed/26681-swift-sourcemanager-getbytedistance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26685-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26685-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 83% rename from validation-test/compiler_crashers/26685-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26685-swift-printingdiagnosticconsumer-handlediagnostic.swift index 2e80a674bd5e1..91adcf13386e2 100644 --- a/validation-test/compiler_crashers/26685-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26685-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26686-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/26686-swift-substitutedtype-get.swift similarity index 83% rename from validation-test/compiler_crashers/26686-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/26686-swift-substitutedtype-get.swift index a6eb95426dcda..39456cc86d1ad 100644 --- a/validation-test/compiler_crashers/26686-swift-substitutedtype-get.swift +++ b/validation-test/compiler_crashers_fixed/26686-swift-substitutedtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26687-bool.swift b/validation-test/compiler_crashers_fixed/26687-bool.swift similarity index 78% rename from validation-test/compiler_crashers/26687-bool.swift rename to validation-test/compiler_crashers_fixed/26687-bool.swift index b25911e2a6ec9..04d61f9d8149c 100644 --- a/validation-test/compiler_crashers/26687-bool.swift +++ b/validation-test/compiler_crashers_fixed/26687-bool.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26691-swift-serialization-serializer-writedecl.swift b/validation-test/compiler_crashers_fixed/26691-swift-serialization-serializer-writedecl.swift similarity index 82% rename from validation-test/compiler_crashers/26691-swift-serialization-serializer-writedecl.swift rename to validation-test/compiler_crashers_fixed/26691-swift-serialization-serializer-writedecl.swift index 1b8f6f80058ea..648ea5570698b 100644 --- a/validation-test/compiler_crashers/26691-swift-serialization-serializer-writedecl.swift +++ b/validation-test/compiler_crashers_fixed/26691-swift-serialization-serializer-writedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26692-swift-astcontext-getloadedmodule.swift b/validation-test/compiler_crashers_fixed/26692-swift-astcontext-getloadedmodule.swift similarity index 81% rename from validation-test/compiler_crashers/26692-swift-astcontext-getloadedmodule.swift rename to validation-test/compiler_crashers_fixed/26692-swift-astcontext-getloadedmodule.swift index 542a87a342701..6ba34da1b9624 100644 --- a/validation-test/compiler_crashers/26692-swift-astcontext-getloadedmodule.swift +++ b/validation-test/compiler_crashers_fixed/26692-swift-astcontext-getloadedmodule.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26704-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/26704-swift-substitutedtype-get.swift similarity index 79% rename from validation-test/compiler_crashers/26704-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/26704-swift-substitutedtype-get.swift index 9e80ca0af0371..ea7232fce005e 100644 --- a/validation-test/compiler_crashers/26704-swift-substitutedtype-get.swift +++ b/validation-test/compiler_crashers_fixed/26704-swift-substitutedtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26706-swift-constraints-constraintgraphscope-constraintgraphscope.swift b/validation-test/compiler_crashers_fixed/26706-swift-constraints-constraintgraphscope-constraintgraphscope.swift similarity index 82% rename from validation-test/compiler_crashers/26706-swift-constraints-constraintgraphscope-constraintgraphscope.swift rename to validation-test/compiler_crashers_fixed/26706-swift-constraints-constraintgraphscope-constraintgraphscope.swift index 7e8ce8d430c52..92033c1f597b6 100644 --- a/validation-test/compiler_crashers/26706-swift-constraints-constraintgraphscope-constraintgraphscope.swift +++ b/validation-test/compiler_crashers_fixed/26706-swift-constraints-constraintgraphscope-constraintgraphscope.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26713-swift-removeshadoweddecls.swift b/validation-test/compiler_crashers_fixed/26713-swift-removeshadoweddecls.swift similarity index 80% rename from validation-test/compiler_crashers/26713-swift-removeshadoweddecls.swift rename to validation-test/compiler_crashers_fixed/26713-swift-removeshadoweddecls.swift index 5896ba122f29a..debefe886e887 100644 --- a/validation-test/compiler_crashers/26713-swift-removeshadoweddecls.swift +++ b/validation-test/compiler_crashers_fixed/26713-swift-removeshadoweddecls.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26718-swift-parser-parsedeclvar.swift b/validation-test/compiler_crashers_fixed/26718-swift-parser-parsedeclvar.swift similarity index 78% rename from validation-test/compiler_crashers/26718-swift-parser-parsedeclvar.swift rename to validation-test/compiler_crashers_fixed/26718-swift-parser-parsedeclvar.swift index 5a08356635831..5783b1bae8da0 100644 --- a/validation-test/compiler_crashers/26718-swift-parser-parsedeclvar.swift +++ b/validation-test/compiler_crashers_fixed/26718-swift-parser-parsedeclvar.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26720-void.swift b/validation-test/compiler_crashers_fixed/26720-void.swift similarity index 81% rename from validation-test/compiler_crashers/26720-void.swift rename to validation-test/compiler_crashers_fixed/26720-void.swift index 423f5d95d1432..2275b573011f8 100644 --- a/validation-test/compiler_crashers/26720-void.swift +++ b/validation-test/compiler_crashers_fixed/26720-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26732-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26732-std-function-func-swift-type-subst.swift similarity index 79% rename from validation-test/compiler_crashers/26732-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26732-std-function-func-swift-type-subst.swift index a7e2b0ebd2bdc..f127ac8abab9a 100644 --- a/validation-test/compiler_crashers/26732-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26732-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26741-swift-abstractstoragedecl-makecomputed.swift b/validation-test/compiler_crashers_fixed/26741-swift-abstractstoragedecl-makecomputed.swift similarity index 82% rename from validation-test/compiler_crashers/26741-swift-abstractstoragedecl-makecomputed.swift rename to validation-test/compiler_crashers_fixed/26741-swift-abstractstoragedecl-makecomputed.swift index 2867eda51ecd0..8bcb4c2291a65 100644 --- a/validation-test/compiler_crashers/26741-swift-abstractstoragedecl-makecomputed.swift +++ b/validation-test/compiler_crashers_fixed/26741-swift-abstractstoragedecl-makecomputed.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26742-swift-nominaltypedecl-prepareextensions.swift b/validation-test/compiler_crashers_fixed/26742-swift-nominaltypedecl-prepareextensions.swift similarity index 81% rename from validation-test/compiler_crashers/26742-swift-nominaltypedecl-prepareextensions.swift rename to validation-test/compiler_crashers_fixed/26742-swift-nominaltypedecl-prepareextensions.swift index 1de3cf0344790..f39461560986c 100644 --- a/validation-test/compiler_crashers/26742-swift-nominaltypedecl-prepareextensions.swift +++ b/validation-test/compiler_crashers_fixed/26742-swift-nominaltypedecl-prepareextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26744-bool.swift b/validation-test/compiler_crashers_fixed/26744-bool.swift similarity index 81% rename from validation-test/compiler_crashers/26744-bool.swift rename to validation-test/compiler_crashers_fixed/26744-bool.swift index c2563fdc277ab..9fec281cbefee 100644 --- a/validation-test/compiler_crashers/26744-bool.swift +++ b/validation-test/compiler_crashers_fixed/26744-bool.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26752-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/26752-swift-typeloc-iserror.swift similarity index 82% rename from validation-test/compiler_crashers/26752-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/26752-swift-typeloc-iserror.swift index 9ad6458148271..9472699869801 100644 --- a/validation-test/compiler_crashers/26752-swift-typeloc-iserror.swift +++ b/validation-test/compiler_crashers_fixed/26752-swift-typeloc-iserror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26753-swift-parser-parsegenericwhereclause.swift b/validation-test/compiler_crashers_fixed/26753-swift-parser-parsegenericwhereclause.swift similarity index 79% rename from validation-test/compiler_crashers/26753-swift-parser-parsegenericwhereclause.swift rename to validation-test/compiler_crashers_fixed/26753-swift-parser-parsegenericwhereclause.swift index 2d09dbf9b7a51..3a75311349fd8 100644 --- a/validation-test/compiler_crashers/26753-swift-parser-parsegenericwhereclause.swift +++ b/validation-test/compiler_crashers_fixed/26753-swift-parser-parsegenericwhereclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26756-swift-unqualifiedlookup-unqualifiedlookup.swift b/validation-test/compiler_crashers_fixed/26756-swift-unqualifiedlookup-unqualifiedlookup.swift similarity index 81% rename from validation-test/compiler_crashers/26756-swift-unqualifiedlookup-unqualifiedlookup.swift rename to validation-test/compiler_crashers_fixed/26756-swift-unqualifiedlookup-unqualifiedlookup.swift index f4f9f7e62dd58..473cd76d04a88 100644 --- a/validation-test/compiler_crashers/26756-swift-unqualifiedlookup-unqualifiedlookup.swift +++ b/validation-test/compiler_crashers_fixed/26756-swift-unqualifiedlookup-unqualifiedlookup.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26762-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/26762-swift-constraints-constraintgraph-addconstraint.swift similarity index 81% rename from validation-test/compiler_crashers/26762-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/26762-swift-constraints-constraintgraph-addconstraint.swift index 46a613f0c846c..f1164d1850520 100644 --- a/validation-test/compiler_crashers/26762-swift-constraints-constraintgraph-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/26762-swift-constraints-constraintgraph-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26763-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/26763-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 79% rename from validation-test/compiler_crashers/26763-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/26763-swift-typechecker-overapproximateosversionsatlocation.swift index a8077cc1f3851..edb5479e5fe97 100644 --- a/validation-test/compiler_crashers/26763-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/26763-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26782-swift-genericfunctiontype-partialsubstgenericargs.swift b/validation-test/compiler_crashers_fixed/26782-swift-genericfunctiontype-partialsubstgenericargs.swift similarity index 84% rename from validation-test/compiler_crashers/26782-swift-genericfunctiontype-partialsubstgenericargs.swift rename to validation-test/compiler_crashers_fixed/26782-swift-genericfunctiontype-partialsubstgenericargs.swift index 6fac045012ca5..ab13e1a97e981 100644 --- a/validation-test/compiler_crashers/26782-swift-genericfunctiontype-partialsubstgenericargs.swift +++ b/validation-test/compiler_crashers_fixed/26782-swift-genericfunctiontype-partialsubstgenericargs.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26788-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/26788-swift-typebase-getsuperclass.swift similarity index 81% rename from validation-test/compiler_crashers/26788-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/26788-swift-typebase-getsuperclass.swift index 3a6dbe76d8746..85765620ead38 100644 --- a/validation-test/compiler_crashers/26788-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/26788-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26791-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26791-swift-typechecker-validatedecl.swift similarity index 81% rename from validation-test/compiler_crashers/26791-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26791-swift-typechecker-validatedecl.swift index c7e7980a7b04c..4e1149ba43fb1 100644 --- a/validation-test/compiler_crashers/26791-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26791-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26792-swift-classtype-get.swift b/validation-test/compiler_crashers_fixed/26792-swift-classtype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26792-swift-classtype-get.swift rename to validation-test/compiler_crashers_fixed/26792-swift-classtype-get.swift index 36742d8891910..95f02c2daf760 100644 --- a/validation-test/compiler_crashers/26792-swift-classtype-get.swift +++ b/validation-test/compiler_crashers_fixed/26792-swift-classtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26803-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/26803-swift-parser-skipsingle.swift similarity index 86% rename from validation-test/compiler_crashers/26803-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/26803-swift-parser-skipsingle.swift index eacac4bb6b965..214a18caed870 100644 --- a/validation-test/compiler_crashers/26803-swift-parser-skipsingle.swift +++ b/validation-test/compiler_crashers_fixed/26803-swift-parser-skipsingle.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) // Test case found by fuzzing diff --git a/validation-test/compiler_crashers/26816-checkenumrawvalues.swift b/validation-test/compiler_crashers_fixed/26816-checkenumrawvalues.swift similarity index 79% rename from validation-test/compiler_crashers/26816-checkenumrawvalues.swift rename to validation-test/compiler_crashers_fixed/26816-checkenumrawvalues.swift index c2f291834ee20..d90b8c01d2b5b 100644 --- a/validation-test/compiler_crashers/26816-checkenumrawvalues.swift +++ b/validation-test/compiler_crashers_fixed/26816-checkenumrawvalues.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26817-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26817-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/26817-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26817-swift-printingdiagnosticconsumer-handlediagnostic.swift index 4db07ad316c05..9dfcfb3a90f67 100644 --- a/validation-test/compiler_crashers/26817-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26817-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26818-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/26818-swift-typechecker-coercepatterntotype.swift similarity index 81% rename from validation-test/compiler_crashers/26818-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/26818-swift-typechecker-coercepatterntotype.swift index 2f0297704b6de..9177353ded113 100644 --- a/validation-test/compiler_crashers/26818-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/26818-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26819-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/26819-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 81% rename from validation-test/compiler_crashers/26819-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/26819-swift-typechecker-overapproximateosversionsatlocation.swift index df32ef47878b5..403fc1dbc8ab6 100644 --- a/validation-test/compiler_crashers/26819-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/26819-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26821-swift-declcontext-getlocalconformances.swift b/validation-test/compiler_crashers_fixed/26821-swift-declcontext-getlocalconformances.swift similarity index 81% rename from validation-test/compiler_crashers/26821-swift-declcontext-getlocalconformances.swift rename to validation-test/compiler_crashers_fixed/26821-swift-declcontext-getlocalconformances.swift index 560505b9bdf3b..57566971d80c6 100644 --- a/validation-test/compiler_crashers/26821-swift-declcontext-getlocalconformances.swift +++ b/validation-test/compiler_crashers_fixed/26821-swift-declcontext-getlocalconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26822-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/26822-swift-modulefile-getdecl.swift similarity index 80% rename from validation-test/compiler_crashers/26822-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/26822-swift-modulefile-getdecl.swift index e8468c75feed7..cd77414cef5d9 100644 --- a/validation-test/compiler_crashers/26822-swift-modulefile-getdecl.swift +++ b/validation-test/compiler_crashers_fixed/26822-swift-modulefile-getdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26823-swift-typebase-getmembersubstitutions.swift b/validation-test/compiler_crashers_fixed/26823-swift-typebase-getmembersubstitutions.swift similarity index 81% rename from validation-test/compiler_crashers/26823-swift-typebase-getmembersubstitutions.swift rename to validation-test/compiler_crashers_fixed/26823-swift-typebase-getmembersubstitutions.swift index 2c734c3ef3bcd..a5133ee5f0a52 100644 --- a/validation-test/compiler_crashers/26823-swift-typebase-getmembersubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/26823-swift-typebase-getmembersubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26824-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/26824-swift-modulefile-getimportedmodules.swift similarity index 82% rename from validation-test/compiler_crashers/26824-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/26824-swift-modulefile-getimportedmodules.swift index c79a4be5fc492..cc295f438e54b 100644 --- a/validation-test/compiler_crashers/26824-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/26824-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26825-std-function-func-mapsignaturetype.swift b/validation-test/compiler_crashers_fixed/26825-std-function-func-mapsignaturetype.swift similarity index 80% rename from validation-test/compiler_crashers/26825-std-function-func-mapsignaturetype.swift rename to validation-test/compiler_crashers_fixed/26825-std-function-func-mapsignaturetype.swift index c7f29886b24e9..73f3a77f0e844 100644 --- a/validation-test/compiler_crashers/26825-std-function-func-mapsignaturetype.swift +++ b/validation-test/compiler_crashers_fixed/26825-std-function-func-mapsignaturetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26827-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/26827-swift-typebase-getcanonicaltype.swift similarity index 79% rename from validation-test/compiler_crashers/26827-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/26827-swift-typebase-getcanonicaltype.swift index 6ba9d6c8b478f..0724e44063a86 100644 --- a/validation-test/compiler_crashers/26827-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/26827-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26828-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/26828-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 80% rename from validation-test/compiler_crashers/26828-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/26828-llvm-foldingset-swift-tupletype-nodeequals.swift index 8039b7b2e5caa..ef50d59a2fcb6 100644 --- a/validation-test/compiler_crashers/26828-llvm-foldingset-swift-tupletype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/26828-llvm-foldingset-swift-tupletype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26829-swift-declcontext-getlocalconformances.swift b/validation-test/compiler_crashers_fixed/26829-swift-declcontext-getlocalconformances.swift similarity index 83% rename from validation-test/compiler_crashers/26829-swift-declcontext-getlocalconformances.swift rename to validation-test/compiler_crashers_fixed/26829-swift-declcontext-getlocalconformances.swift index d3dcdad2f03b4..c5d17b4a5f5a0 100644 --- a/validation-test/compiler_crashers/26829-swift-declcontext-getlocalconformances.swift +++ b/validation-test/compiler_crashers_fixed/26829-swift-declcontext-getlocalconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26830-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26830-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/26830-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26830-swift-printingdiagnosticconsumer-handlediagnostic.swift index 802b52b1b6d53..9ab9ef8a2d5c3 100644 --- a/validation-test/compiler_crashers/26830-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26830-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26831-llvm-densemapbase-llvm-smalldensemap-swift-typevariabletype.swift b/validation-test/compiler_crashers_fixed/26831-llvm-densemapbase-llvm-smalldensemap-swift-typevariabletype.swift similarity index 80% rename from validation-test/compiler_crashers/26831-llvm-densemapbase-llvm-smalldensemap-swift-typevariabletype.swift rename to validation-test/compiler_crashers_fixed/26831-llvm-densemapbase-llvm-smalldensemap-swift-typevariabletype.swift index e39edabf54917..d70590ec1093c 100644 --- a/validation-test/compiler_crashers/26831-llvm-densemapbase-llvm-smalldensemap-swift-typevariabletype.swift +++ b/validation-test/compiler_crashers_fixed/26831-llvm-densemapbase-llvm-smalldensemap-swift-typevariabletype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26833-llvm-mapvector-swift-declcontext.swift b/validation-test/compiler_crashers_fixed/26833-llvm-mapvector-swift-declcontext.swift similarity index 97% rename from validation-test/compiler_crashers/26833-llvm-mapvector-swift-declcontext.swift rename to validation-test/compiler_crashers_fixed/26833-llvm-mapvector-swift-declcontext.swift index acfa6a5d15c89..f30a372cec8e4 100644 --- a/validation-test/compiler_crashers/26833-llvm-mapvector-swift-declcontext.swift +++ b/validation-test/compiler_crashers_fixed/26833-llvm-mapvector-swift-declcontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26834-swift-constraints-constraintsystem-generateconstraints.swift b/validation-test/compiler_crashers_fixed/26834-swift-constraints-constraintsystem-generateconstraints.swift similarity index 79% rename from validation-test/compiler_crashers/26834-swift-constraints-constraintsystem-generateconstraints.swift rename to validation-test/compiler_crashers_fixed/26834-swift-constraints-constraintsystem-generateconstraints.swift index 73e74a4709bfe..ac06dddd38d5a 100644 --- a/validation-test/compiler_crashers/26834-swift-constraints-constraintsystem-generateconstraints.swift +++ b/validation-test/compiler_crashers_fixed/26834-swift-constraints-constraintsystem-generateconstraints.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26835-llvm-foldingset-swift-classtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/26835-llvm-foldingset-swift-classtype-nodeequals.swift similarity index 80% rename from validation-test/compiler_crashers/26835-llvm-foldingset-swift-classtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/26835-llvm-foldingset-swift-classtype-nodeequals.swift index af5d005f167ef..7dc5fc78e9012 100644 --- a/validation-test/compiler_crashers/26835-llvm-foldingset-swift-classtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/26835-llvm-foldingset-swift-classtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26837-swift-abstractfunctiondecl-getobjcselector.swift b/validation-test/compiler_crashers_fixed/26837-swift-abstractfunctiondecl-getobjcselector.swift similarity index 84% rename from validation-test/compiler_crashers/26837-swift-abstractfunctiondecl-getobjcselector.swift rename to validation-test/compiler_crashers_fixed/26837-swift-abstractfunctiondecl-getobjcselector.swift index 7e4e026aed9bf..eaaf4afa52c18 100644 --- a/validation-test/compiler_crashers/26837-swift-abstractfunctiondecl-getobjcselector.swift +++ b/validation-test/compiler_crashers_fixed/26837-swift-abstractfunctiondecl-getobjcselector.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26838-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/26838-swift-patternbindingdecl-setpattern.swift similarity index 84% rename from validation-test/compiler_crashers/26838-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/26838-swift-patternbindingdecl-setpattern.swift index 541eabbb6f688..0dceac60565bd 100644 --- a/validation-test/compiler_crashers/26838-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/26838-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26840-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26840-swift-typechecker-validatedecl.swift similarity index 82% rename from validation-test/compiler_crashers/26840-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26840-swift-typechecker-validatedecl.swift index 5377dcbdf894b..08bc65be7d651 100644 --- a/validation-test/compiler_crashers/26840-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26840-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26841-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26841-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/26841-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26841-std-function-func-swift-type-subst.swift index 68e9a6771b8f8..c16b9252d9ee1 100644 --- a/validation-test/compiler_crashers/26841-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26841-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26842-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/26842-swift-streamprinter-printtext.swift similarity index 82% rename from validation-test/compiler_crashers/26842-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/26842-swift-streamprinter-printtext.swift index febd55e087068..eb20f466fd0d4 100644 --- a/validation-test/compiler_crashers/26842-swift-streamprinter-printtext.swift +++ b/validation-test/compiler_crashers_fixed/26842-swift-streamprinter-printtext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26843-std-function-func-mapsignaturetype.swift b/validation-test/compiler_crashers_fixed/26843-std-function-func-mapsignaturetype.swift similarity index 82% rename from validation-test/compiler_crashers/26843-std-function-func-mapsignaturetype.swift rename to validation-test/compiler_crashers_fixed/26843-std-function-func-mapsignaturetype.swift index f3e860cb063ea..e092f51dd6b23 100644 --- a/validation-test/compiler_crashers/26843-std-function-func-mapsignaturetype.swift +++ b/validation-test/compiler_crashers_fixed/26843-std-function-func-mapsignaturetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26844-swift-typechecker-isdeclavailable.swift b/validation-test/compiler_crashers_fixed/26844-swift-typechecker-isdeclavailable.swift similarity index 80% rename from validation-test/compiler_crashers/26844-swift-typechecker-isdeclavailable.swift rename to validation-test/compiler_crashers_fixed/26844-swift-typechecker-isdeclavailable.swift index 1beaf69daeec7..dabf70ae64e44 100644 --- a/validation-test/compiler_crashers/26844-swift-typechecker-isdeclavailable.swift +++ b/validation-test/compiler_crashers_fixed/26844-swift-typechecker-isdeclavailable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26845-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/26845-swift-substitutedtype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26845-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/26845-swift-substitutedtype-get.swift index f62deb258911f..54eb2ec88b272 100644 --- a/validation-test/compiler_crashers/26845-swift-substitutedtype-get.swift +++ b/validation-test/compiler_crashers_fixed/26845-swift-substitutedtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26846-formatdiagnostictext.swift b/validation-test/compiler_crashers_fixed/26846-formatdiagnostictext.swift similarity index 81% rename from validation-test/compiler_crashers/26846-formatdiagnostictext.swift rename to validation-test/compiler_crashers_fixed/26846-formatdiagnostictext.swift index f3be3a9e64633..747b7a7a5f7d0 100644 --- a/validation-test/compiler_crashers/26846-formatdiagnostictext.swift +++ b/validation-test/compiler_crashers_fixed/26846-formatdiagnostictext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26848-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/26848-swift-metatypetype-get.swift similarity index 80% rename from validation-test/compiler_crashers/26848-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/26848-swift-metatypetype-get.swift index 558d0d6030e85..5a80f9ca5ece1 100644 --- a/validation-test/compiler_crashers/26848-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/26848-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26849-swift-constraints-constraintsystem-generateconstraints.swift b/validation-test/compiler_crashers_fixed/26849-swift-constraints-constraintsystem-generateconstraints.swift similarity index 81% rename from validation-test/compiler_crashers/26849-swift-constraints-constraintsystem-generateconstraints.swift rename to validation-test/compiler_crashers_fixed/26849-swift-constraints-constraintsystem-generateconstraints.swift index f79afd99324f3..fd243fbb53c28 100644 --- a/validation-test/compiler_crashers/26849-swift-constraints-constraintsystem-generateconstraints.swift +++ b/validation-test/compiler_crashers_fixed/26849-swift-constraints-constraintsystem-generateconstraints.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26850-swift-existentialmetatypetype-get.swift b/validation-test/compiler_crashers_fixed/26850-swift-existentialmetatypetype-get.swift similarity index 79% rename from validation-test/compiler_crashers/26850-swift-existentialmetatypetype-get.swift rename to validation-test/compiler_crashers_fixed/26850-swift-existentialmetatypetype-get.swift index 607a908ac5d4b..b578931f3b888 100644 --- a/validation-test/compiler_crashers/26850-swift-existentialmetatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/26850-swift-existentialmetatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26851-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26851-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 78% rename from validation-test/compiler_crashers/26851-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26851-swift-printingdiagnosticconsumer-handlediagnostic.swift index b1f9429cfd1f0..59aa0d95b58be 100644 --- a/validation-test/compiler_crashers/26851-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26851-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26852-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26852-swift-modulefile-lookupvalue.swift similarity index 80% rename from validation-test/compiler_crashers/26852-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26852-swift-modulefile-lookupvalue.swift index e16f11c0bbf1f..9a9a9fa367c45 100644 --- a/validation-test/compiler_crashers/26852-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26852-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26853-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26853-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/26853-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26853-std-function-func-swift-type-subst.swift index 2c5216fd37b0f..a050a253987ee 100644 --- a/validation-test/compiler_crashers/26853-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26853-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26855-swift-nominaltypedecl-prepareextensions.swift b/validation-test/compiler_crashers_fixed/26855-swift-nominaltypedecl-prepareextensions.swift similarity index 79% rename from validation-test/compiler_crashers/26855-swift-nominaltypedecl-prepareextensions.swift rename to validation-test/compiler_crashers_fixed/26855-swift-nominaltypedecl-prepareextensions.swift index bebfbbd41a6a7..f0e9cf77b7f8c 100644 --- a/validation-test/compiler_crashers/26855-swift-nominaltypedecl-prepareextensions.swift +++ b/validation-test/compiler_crashers_fixed/26855-swift-nominaltypedecl-prepareextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26856-swift-constraints-constraintsystem-solverec.swift b/validation-test/compiler_crashers_fixed/26856-swift-constraints-constraintsystem-solverec.swift similarity index 80% rename from validation-test/compiler_crashers/26856-swift-constraints-constraintsystem-solverec.swift rename to validation-test/compiler_crashers_fixed/26856-swift-constraints-constraintsystem-solverec.swift index 55f31d1128c7f..bb6aa4c8b9b2a 100644 --- a/validation-test/compiler_crashers/26856-swift-constraints-constraintsystem-solverec.swift +++ b/validation-test/compiler_crashers_fixed/26856-swift-constraints-constraintsystem-solverec.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26858-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/26858-swift-streamprinter-printtext.swift similarity index 82% rename from validation-test/compiler_crashers/26858-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/26858-swift-streamprinter-printtext.swift index c1fe800db8a7c..b84cd6015e589 100644 --- a/validation-test/compiler_crashers/26858-swift-streamprinter-printtext.swift +++ b/validation-test/compiler_crashers_fixed/26858-swift-streamprinter-printtext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26859-swift-classdecl-classdecl.swift b/validation-test/compiler_crashers_fixed/26859-swift-classdecl-classdecl.swift similarity index 81% rename from validation-test/compiler_crashers/26859-swift-classdecl-classdecl.swift rename to validation-test/compiler_crashers_fixed/26859-swift-classdecl-classdecl.swift index ddfe3c26e7fa1..5a9d57b29ef88 100644 --- a/validation-test/compiler_crashers/26859-swift-classdecl-classdecl.swift +++ b/validation-test/compiler_crashers_fixed/26859-swift-classdecl-classdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26863-swift-constraints-constraintsystem-simplifyconstraint.swift b/validation-test/compiler_crashers_fixed/26863-swift-constraints-constraintsystem-simplifyconstraint.swift similarity index 77% rename from validation-test/compiler_crashers/26863-swift-constraints-constraintsystem-simplifyconstraint.swift rename to validation-test/compiler_crashers_fixed/26863-swift-constraints-constraintsystem-simplifyconstraint.swift index 48c5abc3fc4e3..058f49d6d39a3 100644 --- a/validation-test/compiler_crashers/26863-swift-constraints-constraintsystem-simplifyconstraint.swift +++ b/validation-test/compiler_crashers_fixed/26863-swift-constraints-constraintsystem-simplifyconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26865-swift-conformancelookuptable-getimplicitprotocols.swift b/validation-test/compiler_crashers_fixed/26865-swift-conformancelookuptable-getimplicitprotocols.swift similarity index 80% rename from validation-test/compiler_crashers/26865-swift-conformancelookuptable-getimplicitprotocols.swift rename to validation-test/compiler_crashers_fixed/26865-swift-conformancelookuptable-getimplicitprotocols.swift index 487bd60f2174d..e8259dcfb3feb 100644 --- a/validation-test/compiler_crashers/26865-swift-conformancelookuptable-getimplicitprotocols.swift +++ b/validation-test/compiler_crashers_fixed/26865-swift-conformancelookuptable-getimplicitprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26866-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/26866-swift-nominaltypedecl-getmembers.swift similarity index 86% rename from validation-test/compiler_crashers/26866-swift-nominaltypedecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/26866-swift-nominaltypedecl-getmembers.swift index d7f89dad5e8c0..d95419c109c4e 100644 --- a/validation-test/compiler_crashers/26866-swift-nominaltypedecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/26866-swift-nominaltypedecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26867-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26867-std-function-func-swift-type-subst.swift similarity index 83% rename from validation-test/compiler_crashers/26867-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26867-std-function-func-swift-type-subst.swift index 3a8d8e675f386..57fb7d8442878 100644 --- a/validation-test/compiler_crashers/26867-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26867-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26868-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26868-std-function-func-swift-type-subst.swift similarity index 80% rename from validation-test/compiler_crashers/26868-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26868-std-function-func-swift-type-subst.swift index bf648a4d52f7b..5d1caeafbd703 100644 --- a/validation-test/compiler_crashers/26868-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26868-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26870-swift-mangle-mangler-mangleidentifier.swift b/validation-test/compiler_crashers_fixed/26870-swift-mangle-mangler-mangleidentifier.swift similarity index 81% rename from validation-test/compiler_crashers/26870-swift-mangle-mangler-mangleidentifier.swift rename to validation-test/compiler_crashers_fixed/26870-swift-mangle-mangler-mangleidentifier.swift index c1bda1e688578..8e897557d1c18 100644 --- a/validation-test/compiler_crashers/26870-swift-mangle-mangler-mangleidentifier.swift +++ b/validation-test/compiler_crashers_fixed/26870-swift-mangle-mangler-mangleidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26873-void.swift b/validation-test/compiler_crashers_fixed/26873-void.swift similarity index 80% rename from validation-test/compiler_crashers/26873-void.swift rename to validation-test/compiler_crashers_fixed/26873-void.swift index 03848f6ea8912..bc7ebc6d53b2b 100644 --- a/validation-test/compiler_crashers/26873-void.swift +++ b/validation-test/compiler_crashers_fixed/26873-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26875-swift-typechecker-checkunsupportedprotocoltype.swift b/validation-test/compiler_crashers_fixed/26875-swift-typechecker-checkunsupportedprotocoltype.swift similarity index 79% rename from validation-test/compiler_crashers/26875-swift-typechecker-checkunsupportedprotocoltype.swift rename to validation-test/compiler_crashers_fixed/26875-swift-typechecker-checkunsupportedprotocoltype.swift index f47fee782ba2e..4d6085916a5ae 100644 --- a/validation-test/compiler_crashers/26875-swift-typechecker-checkunsupportedprotocoltype.swift +++ b/validation-test/compiler_crashers_fixed/26875-swift-typechecker-checkunsupportedprotocoltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26876-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/26876-swift-inflightdiagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/26876-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/26876-swift-inflightdiagnostic.swift index 7ecb4e630f489..abee4a0df85e9 100644 --- a/validation-test/compiler_crashers/26876-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26876-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26877-swift-constraints-constraint-create.swift b/validation-test/compiler_crashers_fixed/26877-swift-constraints-constraint-create.swift similarity index 81% rename from validation-test/compiler_crashers/26877-swift-constraints-constraint-create.swift rename to validation-test/compiler_crashers_fixed/26877-swift-constraints-constraint-create.swift index 8ec00b37078f6..3b8ef5e7e6c60 100644 --- a/validation-test/compiler_crashers/26877-swift-constraints-constraint-create.swift +++ b/validation-test/compiler_crashers_fixed/26877-swift-constraints-constraint-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26878-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/26878-swift-conformancelookuptable-updatelookuptable.swift similarity index 80% rename from validation-test/compiler_crashers/26878-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/26878-swift-conformancelookuptable-updatelookuptable.swift index 667f472685b19..3ea960929295c 100644 --- a/validation-test/compiler_crashers/26878-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/26878-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26880-swift-astvisitor.random.swift b/validation-test/compiler_crashers_fixed/26880-swift-astvisitor.random.swift similarity index 81% rename from validation-test/compiler_crashers/26880-swift-astvisitor.random.swift rename to validation-test/compiler_crashers_fixed/26880-swift-astvisitor.random.swift index 63d6448f1e93f..37f30dc157a0d 100644 --- a/validation-test/compiler_crashers/26880-swift-astvisitor.random.swift +++ b/validation-test/compiler_crashers_fixed/26880-swift-astvisitor.random.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26881-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26881-std-function-func-swift-type-subst.swift similarity index 80% rename from validation-test/compiler_crashers/26881-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26881-std-function-func-swift-type-subst.swift index 2886bbfd59b43..3437c28b89b79 100644 --- a/validation-test/compiler_crashers/26881-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26881-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26882-swift-typechecker-definedefaultconstructor.swift b/validation-test/compiler_crashers_fixed/26882-swift-typechecker-definedefaultconstructor.swift similarity index 80% rename from validation-test/compiler_crashers/26882-swift-typechecker-definedefaultconstructor.swift rename to validation-test/compiler_crashers_fixed/26882-swift-typechecker-definedefaultconstructor.swift index cbacf05b37154..0e04d210084fc 100644 --- a/validation-test/compiler_crashers/26882-swift-typechecker-definedefaultconstructor.swift +++ b/validation-test/compiler_crashers_fixed/26882-swift-typechecker-definedefaultconstructor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26884-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/26884-std-function-func-swift-constraints-constraintsystem-simplifytype.swift similarity index 81% rename from validation-test/compiler_crashers/26884-std-function-func-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/26884-std-function-func-swift-constraints-constraintsystem-simplifytype.swift index 1ac41ec38dfa4..ab26bebeefafa 100644 --- a/validation-test/compiler_crashers/26884-std-function-func-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/26884-std-function-func-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26885-swift-constraints-constraintgraph-removeconstraint.swift b/validation-test/compiler_crashers_fixed/26885-swift-constraints-constraintgraph-removeconstraint.swift similarity index 79% rename from validation-test/compiler_crashers/26885-swift-constraints-constraintgraph-removeconstraint.swift rename to validation-test/compiler_crashers_fixed/26885-swift-constraints-constraintgraph-removeconstraint.swift index 1735c93ee4993..48d813b78eb69 100644 --- a/validation-test/compiler_crashers/26885-swift-constraints-constraintgraph-removeconstraint.swift +++ b/validation-test/compiler_crashers_fixed/26885-swift-constraints-constraintgraph-removeconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26887-swift-generictypeparamtype-get.swift b/validation-test/compiler_crashers_fixed/26887-swift-generictypeparamtype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26887-swift-generictypeparamtype-get.swift rename to validation-test/compiler_crashers_fixed/26887-swift-generictypeparamtype-get.swift index e4d463f51ec7a..3c96e5d020ddf 100644 --- a/validation-test/compiler_crashers/26887-swift-generictypeparamtype-get.swift +++ b/validation-test/compiler_crashers_fixed/26887-swift-generictypeparamtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26888-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/26888-swift-nominaltypedecl-preparelookuptable.swift similarity index 81% rename from validation-test/compiler_crashers/26888-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/26888-swift-nominaltypedecl-preparelookuptable.swift index 6eb4cca801ed1..c7c3dccc1e5bb 100644 --- a/validation-test/compiler_crashers/26888-swift-nominaltypedecl-preparelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/26888-swift-nominaltypedecl-preparelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26889-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/26889-swift-tupletype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26889-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/26889-swift-tupletype-get.swift index 4e3951912b1dd..b349065aab1de 100644 --- a/validation-test/compiler_crashers/26889-swift-tupletype-get.swift +++ b/validation-test/compiler_crashers_fixed/26889-swift-tupletype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26890-swift-typechecker-isdeclavailable.swift b/validation-test/compiler_crashers_fixed/26890-swift-typechecker-isdeclavailable.swift similarity index 81% rename from validation-test/compiler_crashers/26890-swift-typechecker-isdeclavailable.swift rename to validation-test/compiler_crashers_fixed/26890-swift-typechecker-isdeclavailable.swift index 6b4f41e8e39be..20c6a01d53473 100644 --- a/validation-test/compiler_crashers/26890-swift-typechecker-isdeclavailable.swift +++ b/validation-test/compiler_crashers_fixed/26890-swift-typechecker-isdeclavailable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26891-vtable.swift b/validation-test/compiler_crashers_fixed/26891-vtable.swift similarity index 82% rename from validation-test/compiler_crashers/26891-vtable.swift rename to validation-test/compiler_crashers_fixed/26891-vtable.swift index 16d9644985bd4..b6e85f6829a87 100644 --- a/validation-test/compiler_crashers/26891-vtable.swift +++ b/validation-test/compiler_crashers_fixed/26891-vtable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26893-swift-constraints-constraintgraphscope-constraintgraphscope.swift b/validation-test/compiler_crashers_fixed/26893-swift-constraints-constraintgraphscope-constraintgraphscope.swift similarity index 81% rename from validation-test/compiler_crashers/26893-swift-constraints-constraintgraphscope-constraintgraphscope.swift rename to validation-test/compiler_crashers_fixed/26893-swift-constraints-constraintgraphscope-constraintgraphscope.swift index 607d98d948572..06986c42baab5 100644 --- a/validation-test/compiler_crashers/26893-swift-constraints-constraintgraphscope-constraintgraphscope.swift +++ b/validation-test/compiler_crashers_fixed/26893-swift-constraints-constraintgraphscope-constraintgraphscope.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26895-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/26895-swift-lexer-lexidentifier.swift similarity index 78% rename from validation-test/compiler_crashers/26895-swift-lexer-lexidentifier.swift rename to validation-test/compiler_crashers_fixed/26895-swift-lexer-lexidentifier.swift index bcd3192008c80..72a3af182ed33 100644 --- a/validation-test/compiler_crashers/26895-swift-lexer-lexidentifier.swift +++ b/validation-test/compiler_crashers_fixed/26895-swift-lexer-lexidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26896-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/26896-swift-diagnosticengine-emitdiagnostic.swift similarity index 80% rename from validation-test/compiler_crashers/26896-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/26896-swift-diagnosticengine-emitdiagnostic.swift index 0f73e29fe3003..98d649b08be48 100644 --- a/validation-test/compiler_crashers/26896-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26896-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26897-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/26897-swift-constraints-constraintsystem-simplifytype.swift similarity index 79% rename from validation-test/compiler_crashers/26897-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/26897-swift-constraints-constraintsystem-simplifytype.swift index 66f3a584df852..13e10dae986e5 100644 --- a/validation-test/compiler_crashers/26897-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/26897-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26899-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/26899-std-function-func-swift-constraints-constraintsystem-simplifytype.swift similarity index 79% rename from validation-test/compiler_crashers/26899-std-function-func-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/26899-std-function-func-swift-constraints-constraintsystem-simplifytype.swift index 54866d096da70..116bdc52c835c 100644 --- a/validation-test/compiler_crashers/26899-std-function-func-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/26899-std-function-func-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26900-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/26900-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 80% rename from validation-test/compiler_crashers/26900-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/26900-swift-typechecker-overapproximateosversionsatlocation.swift index a0f34db233159..bd73982df65b0 100644 --- a/validation-test/compiler_crashers/26900-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/26900-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26902-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/26902-swift-typechecker-resolvetypeincontext.swift similarity index 80% rename from validation-test/compiler_crashers/26902-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/26902-swift-typechecker-resolvetypeincontext.swift index 9108bc15bb745..776357c225dab 100644 --- a/validation-test/compiler_crashers/26902-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/26902-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26905-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/26905-swift-type-transform.swift similarity index 80% rename from validation-test/compiler_crashers/26905-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/26905-swift-type-transform.swift index f02247efcaf49..3f74a33c94922 100644 --- a/validation-test/compiler_crashers/26905-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/26905-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26908-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/26908-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/26908-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/26908-swift-printingdiagnosticconsumer-handlediagnostic.swift index bd3114ec943a2..e5309de9d9e36 100644 --- a/validation-test/compiler_crashers/26908-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26908-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26909-swift-constraints-constraintsystem-solverec.swift b/validation-test/compiler_crashers_fixed/26909-swift-constraints-constraintsystem-solverec.swift similarity index 81% rename from validation-test/compiler_crashers/26909-swift-constraints-constraintsystem-solverec.swift rename to validation-test/compiler_crashers_fixed/26909-swift-constraints-constraintsystem-solverec.swift index 359406e92709f..095368f91b6c4 100644 --- a/validation-test/compiler_crashers/26909-swift-constraints-constraintsystem-solverec.swift +++ b/validation-test/compiler_crashers_fixed/26909-swift-constraints-constraintsystem-solverec.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26910-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/26910-swift-type-transform.swift similarity index 79% rename from validation-test/compiler_crashers/26910-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/26910-swift-type-transform.swift index fb4e3dab7f401..5b6c7c45767cd 100644 --- a/validation-test/compiler_crashers/26910-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/26910-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26911-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/26911-swift-modulefile-getimportedmodules.swift similarity index 81% rename from validation-test/compiler_crashers/26911-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/26911-swift-modulefile-getimportedmodules.swift index 11c7238b63cc0..01bbfc4189dc4 100644 --- a/validation-test/compiler_crashers/26911-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/26911-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26912-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/26912-swift-patternbindingdecl-setpattern.swift similarity index 86% rename from validation-test/compiler_crashers/26912-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/26912-swift-patternbindingdecl-setpattern.swift index 01cbba4baad75..181fa3137ef68 100644 --- a/validation-test/compiler_crashers/26912-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/26912-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26913-swift-markasobjc.swift b/validation-test/compiler_crashers_fixed/26913-swift-markasobjc.swift similarity index 80% rename from validation-test/compiler_crashers/26913-swift-markasobjc.swift rename to validation-test/compiler_crashers_fixed/26913-swift-markasobjc.swift index 176be1822f0da..5e62d5ece8bd4 100644 --- a/validation-test/compiler_crashers/26913-swift-markasobjc.swift +++ b/validation-test/compiler_crashers_fixed/26913-swift-markasobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26915-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/26915-std-function-func-swift-constraints-constraintsystem-simplifytype.swift similarity index 78% rename from validation-test/compiler_crashers/26915-std-function-func-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/26915-std-function-func-swift-constraints-constraintsystem-simplifytype.swift index 998ca42708e59..b36646bcd7905 100644 --- a/validation-test/compiler_crashers/26915-std-function-func-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/26915-std-function-func-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26916-swift-typechecker-definedefaultconstructor.swift b/validation-test/compiler_crashers_fixed/26916-swift-typechecker-definedefaultconstructor.swift similarity index 79% rename from validation-test/compiler_crashers/26916-swift-typechecker-definedefaultconstructor.swift rename to validation-test/compiler_crashers_fixed/26916-swift-typechecker-definedefaultconstructor.swift index 49875445faa3c..cdedf75108c55 100644 --- a/validation-test/compiler_crashers/26916-swift-typechecker-definedefaultconstructor.swift +++ b/validation-test/compiler_crashers_fixed/26916-swift-typechecker-definedefaultconstructor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26917-swift-nominaltype-get.swift b/validation-test/compiler_crashers_fixed/26917-swift-nominaltype-get.swift similarity index 79% rename from validation-test/compiler_crashers/26917-swift-nominaltype-get.swift rename to validation-test/compiler_crashers_fixed/26917-swift-nominaltype-get.swift index d2916c492faed..101e28f167d50 100644 --- a/validation-test/compiler_crashers/26917-swift-nominaltype-get.swift +++ b/validation-test/compiler_crashers_fixed/26917-swift-nominaltype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26918-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/26918-swift-constraints-constraintlocator-profile.swift similarity index 82% rename from validation-test/compiler_crashers/26918-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/26918-swift-constraints-constraintlocator-profile.swift index 1a77ebc907cd7..05788f2a1e897 100644 --- a/validation-test/compiler_crashers/26918-swift-constraints-constraintlocator-profile.swift +++ b/validation-test/compiler_crashers_fixed/26918-swift-constraints-constraintlocator-profile.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26919-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/26919-swift-type-walk.swift similarity index 81% rename from validation-test/compiler_crashers/26919-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/26919-swift-type-walk.swift index 530c799bbe963..a87d94938c026 100644 --- a/validation-test/compiler_crashers/26919-swift-type-walk.swift +++ b/validation-test/compiler_crashers_fixed/26919-swift-type-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26920-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/26920-swift-typebase-getanyoptionalobjecttype.swift similarity index 80% rename from validation-test/compiler_crashers/26920-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/26920-swift-typebase-getanyoptionalobjecttype.swift index 7ee5f5a2cacd3..d561c554a4fd3 100644 --- a/validation-test/compiler_crashers/26920-swift-typebase-getanyoptionalobjecttype.swift +++ b/validation-test/compiler_crashers_fixed/26920-swift-typebase-getanyoptionalobjecttype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26922-swift-constraints-constraintsystem-opengeneric.swift b/validation-test/compiler_crashers_fixed/26922-swift-constraints-constraintsystem-opengeneric.swift similarity index 80% rename from validation-test/compiler_crashers/26922-swift-constraints-constraintsystem-opengeneric.swift rename to validation-test/compiler_crashers_fixed/26922-swift-constraints-constraintsystem-opengeneric.swift index 7b57550536148..9e3aba3b42586 100644 --- a/validation-test/compiler_crashers/26922-swift-constraints-constraintsystem-opengeneric.swift +++ b/validation-test/compiler_crashers_fixed/26922-swift-constraints-constraintsystem-opengeneric.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26923-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/26923-swift-typechecker-typecheckexpression.swift similarity index 79% rename from validation-test/compiler_crashers/26923-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/26923-swift-typechecker-typecheckexpression.swift index 74b67538069d0..1cd14ed5b642e 100644 --- a/validation-test/compiler_crashers/26923-swift-typechecker-typecheckexpression.swift +++ b/validation-test/compiler_crashers_fixed/26923-swift-typechecker-typecheckexpression.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26924-mapsignaturefunctiontype.swift b/validation-test/compiler_crashers_fixed/26924-mapsignaturefunctiontype.swift similarity index 81% rename from validation-test/compiler_crashers/26924-mapsignaturefunctiontype.swift rename to validation-test/compiler_crashers_fixed/26924-mapsignaturefunctiontype.swift index 8d39eb6bab4b0..85296920614fb 100644 --- a/validation-test/compiler_crashers/26924-mapsignaturefunctiontype.swift +++ b/validation-test/compiler_crashers_fixed/26924-mapsignaturefunctiontype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26925-swift-constraints-constraintgraph-computeconnectedcomponents.swift b/validation-test/compiler_crashers_fixed/26925-swift-constraints-constraintgraph-computeconnectedcomponents.swift similarity index 80% rename from validation-test/compiler_crashers/26925-swift-constraints-constraintgraph-computeconnectedcomponents.swift rename to validation-test/compiler_crashers_fixed/26925-swift-constraints-constraintgraph-computeconnectedcomponents.swift index 73ec4e6e79cca..2a218f4c73320 100644 --- a/validation-test/compiler_crashers/26925-swift-constraints-constraintgraph-computeconnectedcomponents.swift +++ b/validation-test/compiler_crashers_fixed/26925-swift-constraints-constraintgraph-computeconnectedcomponents.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26927-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/26927-swift-modulefile-maybereadgenericparams.swift similarity index 83% rename from validation-test/compiler_crashers/26927-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/26927-swift-modulefile-maybereadgenericparams.swift index c6af55054bf16..b67b1898afb05 100644 --- a/validation-test/compiler_crashers/26927-swift-modulefile-maybereadgenericparams.swift +++ b/validation-test/compiler_crashers_fixed/26927-swift-modulefile-maybereadgenericparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26928-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/26928-swift-typebase-isequal.swift similarity index 81% rename from validation-test/compiler_crashers/26928-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/26928-swift-typebase-isequal.swift index 5fb64ed0e31fb..923304b48b0ff 100644 --- a/validation-test/compiler_crashers/26928-swift-typebase-isequal.swift +++ b/validation-test/compiler_crashers_fixed/26928-swift-typebase-isequal.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26929-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/26929-swift-modulefile-maybereadpattern.swift similarity index 81% rename from validation-test/compiler_crashers/26929-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/26929-swift-modulefile-maybereadpattern.swift index 9ab16180dae8a..162a886ef55fa 100644 --- a/validation-test/compiler_crashers/26929-swift-modulefile-maybereadpattern.swift +++ b/validation-test/compiler_crashers_fixed/26929-swift-modulefile-maybereadpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26931-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26931-swift-modulefile-lookupvalue.swift similarity index 80% rename from validation-test/compiler_crashers/26931-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26931-swift-modulefile-lookupvalue.swift index bcf0c3182ba78..dd90e7c227d46 100644 --- a/validation-test/compiler_crashers/26931-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26931-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26933-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/26933-swift-typechecker-coercepatterntotype.swift similarity index 81% rename from validation-test/compiler_crashers/26933-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/26933-swift-typechecker-coercepatterntotype.swift index d44043a4c86bc..810656a01724e 100644 --- a/validation-test/compiler_crashers/26933-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/26933-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26934-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/26934-swift-lexer-leximpl.swift similarity index 84% rename from validation-test/compiler_crashers/26934-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/26934-swift-lexer-leximpl.swift index e5dd5d074455f..d463b9a4862d3 100644 --- a/validation-test/compiler_crashers/26934-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/26934-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26937-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/26937-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 80% rename from validation-test/compiler_crashers/26937-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/26937-llvm-foldingset-swift-tupletype-nodeequals.swift index 433c9b1f18c70..cf483db09583b 100644 --- a/validation-test/compiler_crashers/26937-llvm-foldingset-swift-tupletype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/26937-llvm-foldingset-swift-tupletype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26938-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/26938-swift-diagnosticengine-flushactivediagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/26938-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/26938-swift-diagnosticengine-flushactivediagnostic.swift index d32518ea70211..4ed7985f1390a 100644 --- a/validation-test/compiler_crashers/26938-swift-diagnosticengine-flushactivediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/26938-swift-diagnosticengine-flushactivediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26939-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/26939-swift-patternbindingdecl-setpattern.swift similarity index 83% rename from validation-test/compiler_crashers/26939-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/26939-swift-patternbindingdecl-setpattern.swift index 089e692f7f922..19d815d0b4032 100644 --- a/validation-test/compiler_crashers/26939-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/26939-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26940-swift-conformancelookuptable-getconformance.swift b/validation-test/compiler_crashers_fixed/26940-swift-conformancelookuptable-getconformance.swift similarity index 81% rename from validation-test/compiler_crashers/26940-swift-conformancelookuptable-getconformance.swift rename to validation-test/compiler_crashers_fixed/26940-swift-conformancelookuptable-getconformance.swift index 1d823e2883220..44eb041bfda3f 100644 --- a/validation-test/compiler_crashers/26940-swift-conformancelookuptable-getconformance.swift +++ b/validation-test/compiler_crashers_fixed/26940-swift-conformancelookuptable-getconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26941-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/26941-swift-typechecker-checkinheritanceclause.swift similarity index 80% rename from validation-test/compiler_crashers/26941-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/26941-swift-typechecker-checkinheritanceclause.swift index a072afe371587..f88dab19563b6 100644 --- a/validation-test/compiler_crashers/26941-swift-typechecker-checkinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/26941-swift-typechecker-checkinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26942-swift-nominaltypedecl-computeinterfacetype.swift b/validation-test/compiler_crashers_fixed/26942-swift-nominaltypedecl-computeinterfacetype.swift similarity index 79% rename from validation-test/compiler_crashers/26942-swift-nominaltypedecl-computeinterfacetype.swift rename to validation-test/compiler_crashers_fixed/26942-swift-nominaltypedecl-computeinterfacetype.swift index 8acaa8181b95f..b94c7db930596 100644 --- a/validation-test/compiler_crashers/26942-swift-nominaltypedecl-computeinterfacetype.swift +++ b/validation-test/compiler_crashers_fixed/26942-swift-nominaltypedecl-computeinterfacetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26943-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/26943-swift-typebase-getsuperclass.swift similarity index 82% rename from validation-test/compiler_crashers/26943-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/26943-swift-typebase-getsuperclass.swift index 0a90309f6328a..ad3ee1d8604ad 100644 --- a/validation-test/compiler_crashers/26943-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/26943-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26944-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/26944-swift-astprinter-printtextimpl.swift similarity index 82% rename from validation-test/compiler_crashers/26944-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/26944-swift-astprinter-printtextimpl.swift index a553348aef207..b98aa43e94a6d 100644 --- a/validation-test/compiler_crashers/26944-swift-astprinter-printtextimpl.swift +++ b/validation-test/compiler_crashers_fixed/26944-swift-astprinter-printtextimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26945-swift-typebase-getmembersubstitutions.swift b/validation-test/compiler_crashers_fixed/26945-swift-typebase-getmembersubstitutions.swift similarity index 81% rename from validation-test/compiler_crashers/26945-swift-typebase-getmembersubstitutions.swift rename to validation-test/compiler_crashers_fixed/26945-swift-typebase-getmembersubstitutions.swift index 1f72bc15de68f..d9b8076176f18 100644 --- a/validation-test/compiler_crashers/26945-swift-typebase-getmembersubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/26945-swift-typebase-getmembersubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26947-swift-constraints-constraintsystem-getconstraintlocator.swift b/validation-test/compiler_crashers_fixed/26947-swift-constraints-constraintsystem-getconstraintlocator.swift similarity index 83% rename from validation-test/compiler_crashers/26947-swift-constraints-constraintsystem-getconstraintlocator.swift rename to validation-test/compiler_crashers_fixed/26947-swift-constraints-constraintsystem-getconstraintlocator.swift index 7d986cd012044..b3a621efdd858 100644 --- a/validation-test/compiler_crashers/26947-swift-constraints-constraintsystem-getconstraintlocator.swift +++ b/validation-test/compiler_crashers_fixed/26947-swift-constraints-constraintsystem-getconstraintlocator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26948-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/26948-swift-nominaltypedecl-getmembers.swift similarity index 86% rename from validation-test/compiler_crashers/26948-swift-nominaltypedecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/26948-swift-nominaltypedecl-getmembers.swift index 6d9a8cf18444b..433e6e529f80d 100644 --- a/validation-test/compiler_crashers/26948-swift-nominaltypedecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/26948-swift-nominaltypedecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26949-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/26949-swift-typeloc-iserror.swift similarity index 81% rename from validation-test/compiler_crashers/26949-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/26949-swift-typeloc-iserror.swift index d66ead47e6db0..8b9e1c601c4f8 100644 --- a/validation-test/compiler_crashers/26949-swift-typeloc-iserror.swift +++ b/validation-test/compiler_crashers_fixed/26949-swift-typeloc-iserror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26950-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/26950-swift-constraints-constraintsystem-solve.swift similarity index 79% rename from validation-test/compiler_crashers/26950-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/26950-swift-constraints-constraintsystem-solve.swift index 1fab8a5ed27f3..2d0b0a7db4397 100644 --- a/validation-test/compiler_crashers/26950-swift-constraints-constraintsystem-solve.swift +++ b/validation-test/compiler_crashers_fixed/26950-swift-constraints-constraintsystem-solve.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26951-swift-modulefile-resolvecrossreference.swift b/validation-test/compiler_crashers_fixed/26951-swift-modulefile-resolvecrossreference.swift similarity index 80% rename from validation-test/compiler_crashers/26951-swift-modulefile-resolvecrossreference.swift rename to validation-test/compiler_crashers_fixed/26951-swift-modulefile-resolvecrossreference.swift index 19c72dcde81a7..7352ad3251e9c 100644 --- a/validation-test/compiler_crashers/26951-swift-modulefile-resolvecrossreference.swift +++ b/validation-test/compiler_crashers_fixed/26951-swift-modulefile-resolvecrossreference.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26953-std-function-func-mapsignaturetype.swift b/validation-test/compiler_crashers_fixed/26953-std-function-func-mapsignaturetype.swift similarity index 81% rename from validation-test/compiler_crashers/26953-std-function-func-mapsignaturetype.swift rename to validation-test/compiler_crashers_fixed/26953-std-function-func-mapsignaturetype.swift index 457c59e97c8e9..1caf6804e073d 100644 --- a/validation-test/compiler_crashers/26953-std-function-func-mapsignaturetype.swift +++ b/validation-test/compiler_crashers_fixed/26953-std-function-func-mapsignaturetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26954-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/26954-swift-functiontype-get.swift similarity index 79% rename from validation-test/compiler_crashers/26954-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/26954-swift-functiontype-get.swift index 12de2bc25e384..3e0245adef6a4 100644 --- a/validation-test/compiler_crashers/26954-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/26954-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26955-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/26955-swift-boundgenerictype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26955-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/26955-swift-boundgenerictype-get.swift index f0a5ee3c0fb7d..b2a7e3402bff4 100644 --- a/validation-test/compiler_crashers/26955-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/26955-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26956-swift-constructordecl-constructordecl.swift b/validation-test/compiler_crashers_fixed/26956-swift-constructordecl-constructordecl.swift similarity index 81% rename from validation-test/compiler_crashers/26956-swift-constructordecl-constructordecl.swift rename to validation-test/compiler_crashers_fixed/26956-swift-constructordecl-constructordecl.swift index 16a35634e10e8..1a0017700b3cc 100644 --- a/validation-test/compiler_crashers/26956-swift-constructordecl-constructordecl.swift +++ b/validation-test/compiler_crashers_fixed/26956-swift-constructordecl-constructordecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26958-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/26958-swift-typebase-isequal.swift similarity index 81% rename from validation-test/compiler_crashers/26958-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/26958-swift-typebase-isequal.swift index 9763fc2fdb924..c80c387fc414c 100644 --- a/validation-test/compiler_crashers/26958-swift-typebase-isequal.swift +++ b/validation-test/compiler_crashers_fixed/26958-swift-typebase-isequal.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26959-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26959-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/26959-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26959-std-function-func-swift-type-subst.swift index 31505734b37a6..9fc698ebda8fd 100644 --- a/validation-test/compiler_crashers/26959-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26959-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26960-void.swift b/validation-test/compiler_crashers_fixed/26960-void.swift similarity index 80% rename from validation-test/compiler_crashers/26960-void.swift rename to validation-test/compiler_crashers_fixed/26960-void.swift index e789d3b92c22d..843979eea0d75 100644 --- a/validation-test/compiler_crashers/26960-void.swift +++ b/validation-test/compiler_crashers_fixed/26960-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26961-llvm-foldingset-swift-classtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/26961-llvm-foldingset-swift-classtype-nodeequals.swift similarity index 82% rename from validation-test/compiler_crashers/26961-llvm-foldingset-swift-classtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/26961-llvm-foldingset-swift-classtype-nodeequals.swift index 37b6fc316a48e..b97324954a01b 100644 --- a/validation-test/compiler_crashers/26961-llvm-foldingset-swift-classtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/26961-llvm-foldingset-swift-classtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26962-swift-typechecker-validategenericfuncsignature.swift b/validation-test/compiler_crashers_fixed/26962-swift-typechecker-validategenericfuncsignature.swift similarity index 81% rename from validation-test/compiler_crashers/26962-swift-typechecker-validategenericfuncsignature.swift rename to validation-test/compiler_crashers_fixed/26962-swift-typechecker-validategenericfuncsignature.swift index 3912f9432ea6a..ce7caa734fc1c 100644 --- a/validation-test/compiler_crashers/26962-swift-typechecker-validategenericfuncsignature.swift +++ b/validation-test/compiler_crashers_fixed/26962-swift-typechecker-validategenericfuncsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26963-checkenumrawvalues.swift b/validation-test/compiler_crashers_fixed/26963-checkenumrawvalues.swift similarity index 79% rename from validation-test/compiler_crashers/26963-checkenumrawvalues.swift rename to validation-test/compiler_crashers_fixed/26963-checkenumrawvalues.swift index 0f703884ddd99..6f4217ee8ac14 100644 --- a/validation-test/compiler_crashers/26963-checkenumrawvalues.swift +++ b/validation-test/compiler_crashers_fixed/26963-checkenumrawvalues.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26964-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/26964-swift-type-transform.swift similarity index 80% rename from validation-test/compiler_crashers/26964-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/26964-swift-type-transform.swift index f17320c5c0f7f..c56acf199c1c2 100644 --- a/validation-test/compiler_crashers/26964-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/26964-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26965-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/26965-swift-functiontype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26965-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/26965-swift-functiontype-get.swift index d78ef0c265a06..800e1bcbc80b3 100644 --- a/validation-test/compiler_crashers/26965-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/26965-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26967-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26967-swift-typechecker-validatedecl.swift similarity index 82% rename from validation-test/compiler_crashers/26967-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26967-swift-typechecker-validatedecl.swift index 5e2f1f99809d1..20bf77bd1567f 100644 --- a/validation-test/compiler_crashers/26967-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26967-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26968-swift-typechecker-isdeclavailable.swift b/validation-test/compiler_crashers_fixed/26968-swift-typechecker-isdeclavailable.swift similarity index 84% rename from validation-test/compiler_crashers/26968-swift-typechecker-isdeclavailable.swift rename to validation-test/compiler_crashers_fixed/26968-swift-typechecker-isdeclavailable.swift index b2e8072f243ce..b2a5e64e1c36a 100644 --- a/validation-test/compiler_crashers/26968-swift-typechecker-isdeclavailable.swift +++ b/validation-test/compiler_crashers_fixed/26968-swift-typechecker-isdeclavailable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26969-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/26969-swift-modulefile-lookupvalue.swift similarity index 82% rename from validation-test/compiler_crashers/26969-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/26969-swift-modulefile-lookupvalue.swift index ea3f8d4cc00b9..f3a8593cef453 100644 --- a/validation-test/compiler_crashers/26969-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/26969-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26971-swift-constraints-constraintsystem-solvesimplified.swift b/validation-test/compiler_crashers_fixed/26971-swift-constraints-constraintsystem-solvesimplified.swift similarity index 80% rename from validation-test/compiler_crashers/26971-swift-constraints-constraintsystem-solvesimplified.swift rename to validation-test/compiler_crashers_fixed/26971-swift-constraints-constraintsystem-solvesimplified.swift index 61888351d6db3..66f3ea919c80c 100644 --- a/validation-test/compiler_crashers/26971-swift-constraints-constraintsystem-solvesimplified.swift +++ b/validation-test/compiler_crashers_fixed/26971-swift-constraints-constraintsystem-solvesimplified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26972-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/26972-swift-type-transform.swift similarity index 80% rename from validation-test/compiler_crashers/26972-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/26972-swift-type-transform.swift index c4870ea73c7cd..f8c033a0bddbc 100644 --- a/validation-test/compiler_crashers/26972-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/26972-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26973-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/26973-swift-boundgenerictype-get.swift similarity index 81% rename from validation-test/compiler_crashers/26973-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/26973-swift-boundgenerictype-get.swift index 45ec90fd49852..d4911e5c55276 100644 --- a/validation-test/compiler_crashers/26973-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/26973-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26974-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/26974-swift-typechecker-checkinheritanceclause.swift similarity index 81% rename from validation-test/compiler_crashers/26974-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/26974-swift-typechecker-checkinheritanceclause.swift index e219b73d89290..ae5da540b977d 100644 --- a/validation-test/compiler_crashers/26974-swift-typechecker-checkinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/26974-swift-typechecker-checkinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26976-swift-constraints-constraintsystem-opentype.swift b/validation-test/compiler_crashers_fixed/26976-swift-constraints-constraintsystem-opentype.swift similarity index 81% rename from validation-test/compiler_crashers/26976-swift-constraints-constraintsystem-opentype.swift rename to validation-test/compiler_crashers_fixed/26976-swift-constraints-constraintsystem-opentype.swift index 5de0fe38a91d8..10e79cb3d6439 100644 --- a/validation-test/compiler_crashers/26976-swift-constraints-constraintsystem-opentype.swift +++ b/validation-test/compiler_crashers_fixed/26976-swift-constraints-constraintsystem-opentype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26977-checkenumrawvalues.swift b/validation-test/compiler_crashers_fixed/26977-checkenumrawvalues.swift similarity index 80% rename from validation-test/compiler_crashers/26977-checkenumrawvalues.swift rename to validation-test/compiler_crashers_fixed/26977-checkenumrawvalues.swift index 40be4c970e5ce..87798d18f10b7 100644 --- a/validation-test/compiler_crashers/26977-checkenumrawvalues.swift +++ b/validation-test/compiler_crashers_fixed/26977-checkenumrawvalues.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26979-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/26979-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/26979-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/26979-std-function-func-swift-type-subst.swift index 01eed4ca03f60..fa49f2ca3e078 100644 --- a/validation-test/compiler_crashers/26979-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/26979-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26980-swift-conformancelookuptable-lookupconformance.swift b/validation-test/compiler_crashers_fixed/26980-swift-conformancelookuptable-lookupconformance.swift similarity index 81% rename from validation-test/compiler_crashers/26980-swift-conformancelookuptable-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/26980-swift-conformancelookuptable-lookupconformance.swift index f9ea80cb9bb9f..fb0df31635309 100644 --- a/validation-test/compiler_crashers/26980-swift-conformancelookuptable-lookupconformance.swift +++ b/validation-test/compiler_crashers_fixed/26980-swift-conformancelookuptable-lookupconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26981-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/26981-swift-typechecker-validatedecl.swift similarity index 81% rename from validation-test/compiler_crashers/26981-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/26981-swift-typechecker-validatedecl.swift index cdf40b97986d3..9fc47ef5764ed 100644 --- a/validation-test/compiler_crashers/26981-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/26981-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26982-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/26982-swift-nominaltypedecl-getmembers.swift similarity index 83% rename from validation-test/compiler_crashers/26982-swift-nominaltypedecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/26982-swift-nominaltypedecl-getmembers.swift index 7c64d3980df61..eff68c2c742f4 100644 --- a/validation-test/compiler_crashers/26982-swift-nominaltypedecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/26982-swift-nominaltypedecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26984-swift-dependentmembertype-get.swift b/validation-test/compiler_crashers_fixed/26984-swift-dependentmembertype-get.swift similarity index 80% rename from validation-test/compiler_crashers/26984-swift-dependentmembertype-get.swift rename to validation-test/compiler_crashers_fixed/26984-swift-dependentmembertype-get.swift index 95281b8ad7ba1..cb1379518239a 100644 --- a/validation-test/compiler_crashers/26984-swift-dependentmembertype-get.swift +++ b/validation-test/compiler_crashers_fixed/26984-swift-dependentmembertype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26985-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/26985-swift-genericparamlist-addnestedarchetypes.swift similarity index 80% rename from validation-test/compiler_crashers/26985-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/26985-swift-genericparamlist-addnestedarchetypes.swift index a19eff35d29a4..d77df3dd73889 100644 --- a/validation-test/compiler_crashers/26985-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/26985-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26987-swift-constraints-constraintsystem-addconstraint.swift b/validation-test/compiler_crashers_fixed/26987-swift-constraints-constraintsystem-addconstraint.swift similarity index 78% rename from validation-test/compiler_crashers/26987-swift-constraints-constraintsystem-addconstraint.swift rename to validation-test/compiler_crashers_fixed/26987-swift-constraints-constraintsystem-addconstraint.swift index 1dcc251994f51..050ebe54176db 100644 --- a/validation-test/compiler_crashers/26987-swift-constraints-constraintsystem-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/26987-swift-constraints-constraintsystem-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26988-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/26988-swift-modulefile-getimportedmodules.swift similarity index 80% rename from validation-test/compiler_crashers/26988-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/26988-swift-modulefile-getimportedmodules.swift index 5337471da7bf4..05e103176f724 100644 --- a/validation-test/compiler_crashers/26988-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/26988-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26989-swift-typechecker-definedefaultconstructor.swift b/validation-test/compiler_crashers_fixed/26989-swift-typechecker-definedefaultconstructor.swift similarity index 81% rename from validation-test/compiler_crashers/26989-swift-typechecker-definedefaultconstructor.swift rename to validation-test/compiler_crashers_fixed/26989-swift-typechecker-definedefaultconstructor.swift index 794133f0ea756..e88867aa60704 100644 --- a/validation-test/compiler_crashers/26989-swift-typechecker-definedefaultconstructor.swift +++ b/validation-test/compiler_crashers_fixed/26989-swift-typechecker-definedefaultconstructor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26991-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/26991-swift-abstractclosureexpr-setparams.swift similarity index 84% rename from validation-test/compiler_crashers/26991-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/26991-swift-abstractclosureexpr-setparams.swift index 5878d5360c4fb..6b4a205d4a88f 100644 --- a/validation-test/compiler_crashers/26991-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/26991-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26994-swift-nominaltypedecl-prepareextensions.swift b/validation-test/compiler_crashers_fixed/26994-swift-nominaltypedecl-prepareextensions.swift similarity index 81% rename from validation-test/compiler_crashers/26994-swift-nominaltypedecl-prepareextensions.swift rename to validation-test/compiler_crashers_fixed/26994-swift-nominaltypedecl-prepareextensions.swift index 4a59c603211b2..77f3a2f600e6b 100644 --- a/validation-test/compiler_crashers/26994-swift-nominaltypedecl-prepareextensions.swift +++ b/validation-test/compiler_crashers_fixed/26994-swift-nominaltypedecl-prepareextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26995-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/26995-swift-typebase-isequal.swift similarity index 79% rename from validation-test/compiler_crashers/26995-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/26995-swift-typebase-isequal.swift index 040fe07cef6d0..3cec62efb1570 100644 --- a/validation-test/compiler_crashers/26995-swift-typebase-isequal.swift +++ b/validation-test/compiler_crashers_fixed/26995-swift-typebase-isequal.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26996-swift-classtype-get.swift b/validation-test/compiler_crashers_fixed/26996-swift-classtype-get.swift similarity index 82% rename from validation-test/compiler_crashers/26996-swift-classtype-get.swift rename to validation-test/compiler_crashers_fixed/26996-swift-classtype-get.swift index 686f0ea782f3c..f2695afa607ca 100644 --- a/validation-test/compiler_crashers/26996-swift-classtype-get.swift +++ b/validation-test/compiler_crashers_fixed/26996-swift-classtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/26997-swift-stmt-walk.swift b/validation-test/compiler_crashers_fixed/26997-swift-stmt-walk.swift similarity index 82% rename from validation-test/compiler_crashers/26997-swift-stmt-walk.swift rename to validation-test/compiler_crashers_fixed/26997-swift-stmt-walk.swift index b3726ba9c6731..6dd011f84a68a 100644 --- a/validation-test/compiler_crashers/26997-swift-stmt-walk.swift +++ b/validation-test/compiler_crashers_fixed/26997-swift-stmt-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27001-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/27001-swift-constraints-solution-solution.swift similarity index 79% rename from validation-test/compiler_crashers/27001-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/27001-swift-constraints-solution-solution.swift index 6c8a87e9c664e..892f9afe4290c 100644 --- a/validation-test/compiler_crashers/27001-swift-constraints-solution-solution.swift +++ b/validation-test/compiler_crashers_fixed/27001-swift-constraints-solution-solution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27003-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/27003-swift-typebase-getcanonicaltype.swift similarity index 81% rename from validation-test/compiler_crashers/27003-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/27003-swift-typebase-getcanonicaltype.swift index e9ae5b0ad01a8..55cff5d6729d5 100644 --- a/validation-test/compiler_crashers/27003-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/27003-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27004-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/27004-swift-constraints-constraintsystem-matchtypes.swift similarity index 82% rename from validation-test/compiler_crashers/27004-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/27004-swift-constraints-constraintsystem-matchtypes.swift index 7368a12988405..371ca06f14138 100644 --- a/validation-test/compiler_crashers/27004-swift-constraints-constraintsystem-matchtypes.swift +++ b/validation-test/compiler_crashers_fixed/27004-swift-constraints-constraintsystem-matchtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27007-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27007-swift-type-transform.swift similarity index 82% rename from validation-test/compiler_crashers/27007-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27007-swift-type-transform.swift index db27439579b2c..775d0015850a1 100644 --- a/validation-test/compiler_crashers/27007-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27007-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27009-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/27009-swift-abstractclosureexpr-setparams.swift similarity index 81% rename from validation-test/compiler_crashers/27009-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/27009-swift-abstractclosureexpr-setparams.swift index a1fc4ce2fa7b4..1652bca515438 100644 --- a/validation-test/compiler_crashers/27009-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/27009-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27010-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/27010-swift-patternbindingdecl-setpattern.swift similarity index 90% rename from validation-test/compiler_crashers/27010-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/27010-swift-patternbindingdecl-setpattern.swift index f4f0239053331..640a99533c693 100644 --- a/validation-test/compiler_crashers/27010-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/27010-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27014-swift-modulefile-loadextensions.swift b/validation-test/compiler_crashers_fixed/27014-swift-modulefile-loadextensions.swift similarity index 82% rename from validation-test/compiler_crashers/27014-swift-modulefile-loadextensions.swift rename to validation-test/compiler_crashers_fixed/27014-swift-modulefile-loadextensions.swift index 100bd18774b28..abab9034f25d9 100644 --- a/validation-test/compiler_crashers/27014-swift-modulefile-loadextensions.swift +++ b/validation-test/compiler_crashers_fixed/27014-swift-modulefile-loadextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27015-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27015-swift-typechecker-validatedecl.swift similarity index 82% rename from validation-test/compiler_crashers/27015-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27015-swift-typechecker-validatedecl.swift index e74e513728bf9..8b38aa2245a9d 100644 --- a/validation-test/compiler_crashers/27015-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27015-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27016-swift-constraints-constraintsystem-solverec.swift b/validation-test/compiler_crashers_fixed/27016-swift-constraints-constraintsystem-solverec.swift similarity index 82% rename from validation-test/compiler_crashers/27016-swift-constraints-constraintsystem-solverec.swift rename to validation-test/compiler_crashers_fixed/27016-swift-constraints-constraintsystem-solverec.swift index 225e9cfe6c759..db90f511cdc6d 100644 --- a/validation-test/compiler_crashers/27016-swift-constraints-constraintsystem-solverec.swift +++ b/validation-test/compiler_crashers_fixed/27016-swift-constraints-constraintsystem-solverec.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27017-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift b/validation-test/compiler_crashers_fixed/27017-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift similarity index 80% rename from validation-test/compiler_crashers/27017-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift rename to validation-test/compiler_crashers_fixed/27017-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift index 020d8fe9e7152..0cd995e3cf615 100644 --- a/validation-test/compiler_crashers/27017-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift +++ b/validation-test/compiler_crashers_fixed/27017-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27018-swift-conformancelookuptable-getallprotocols.swift b/validation-test/compiler_crashers_fixed/27018-swift-conformancelookuptable-getallprotocols.swift similarity index 80% rename from validation-test/compiler_crashers/27018-swift-conformancelookuptable-getallprotocols.swift rename to validation-test/compiler_crashers_fixed/27018-swift-conformancelookuptable-getallprotocols.swift index 79bcf4205a36b..5daefb4f5937a 100644 --- a/validation-test/compiler_crashers/27018-swift-conformancelookuptable-getallprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27018-swift-conformancelookuptable-getallprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27019-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/27019-swift-genericfunctiontype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27019-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/27019-swift-genericfunctiontype-get.swift index 269977fe8fc65..50f6d21435371 100644 --- a/validation-test/compiler_crashers/27019-swift-genericfunctiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27019-swift-genericfunctiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27020-llvm-foldingset-swift-tupletype-getnodeprofile.swift b/validation-test/compiler_crashers_fixed/27020-llvm-foldingset-swift-tupletype-getnodeprofile.swift similarity index 82% rename from validation-test/compiler_crashers/27020-llvm-foldingset-swift-tupletype-getnodeprofile.swift rename to validation-test/compiler_crashers_fixed/27020-llvm-foldingset-swift-tupletype-getnodeprofile.swift index 4cebce84c2e01..9070f160a47a0 100644 --- a/validation-test/compiler_crashers/27020-llvm-foldingset-swift-tupletype-getnodeprofile.swift +++ b/validation-test/compiler_crashers_fixed/27020-llvm-foldingset-swift-tupletype-getnodeprofile.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27022-swift-classtype-get.swift b/validation-test/compiler_crashers_fixed/27022-swift-classtype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27022-swift-classtype-get.swift rename to validation-test/compiler_crashers_fixed/27022-swift-classtype-get.swift index 34603789fe21c..7bcca5509d6b5 100644 --- a/validation-test/compiler_crashers/27022-swift-classtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27022-swift-classtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27023-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27023-swift-typechecker-validatedecl.swift similarity index 80% rename from validation-test/compiler_crashers/27023-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27023-swift-typechecker-validatedecl.swift index a9499b6f6289a..4aa1bfe3ea487 100644 --- a/validation-test/compiler_crashers/27023-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27023-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27024-swift-constraints-solution-simplifytype.swift b/validation-test/compiler_crashers_fixed/27024-swift-constraints-solution-simplifytype.swift similarity index 81% rename from validation-test/compiler_crashers/27024-swift-constraints-solution-simplifytype.swift rename to validation-test/compiler_crashers_fixed/27024-swift-constraints-solution-simplifytype.swift index a739464db052e..3bc837819697d 100644 --- a/validation-test/compiler_crashers/27024-swift-constraints-solution-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/27024-swift-constraints-solution-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27025-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/27025-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 82% rename from validation-test/compiler_crashers/27025-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/27025-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift index ee0c3629ec817..6a539481275b3 100644 --- a/validation-test/compiler_crashers/27025-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift +++ b/validation-test/compiler_crashers_fixed/27025-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27026-void.swift b/validation-test/compiler_crashers_fixed/27026-void.swift similarity index 82% rename from validation-test/compiler_crashers/27026-void.swift rename to validation-test/compiler_crashers_fixed/27026-void.swift index 7c91d4f04cdb6..8a5a56b843935 100644 --- a/validation-test/compiler_crashers/27026-void.swift +++ b/validation-test/compiler_crashers_fixed/27026-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27027-swift-namelookup-lookupinmodule.swift b/validation-test/compiler_crashers_fixed/27027-swift-namelookup-lookupinmodule.swift similarity index 80% rename from validation-test/compiler_crashers/27027-swift-namelookup-lookupinmodule.swift rename to validation-test/compiler_crashers_fixed/27027-swift-namelookup-lookupinmodule.swift index 57802e162cc8f..c0fdfa6d69faa 100644 --- a/validation-test/compiler_crashers/27027-swift-namelookup-lookupinmodule.swift +++ b/validation-test/compiler_crashers_fixed/27027-swift-namelookup-lookupinmodule.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27029-swift-typebase-isemptyexistentialcomposition.swift b/validation-test/compiler_crashers_fixed/27029-swift-typebase-isemptyexistentialcomposition.swift similarity index 80% rename from validation-test/compiler_crashers/27029-swift-typebase-isemptyexistentialcomposition.swift rename to validation-test/compiler_crashers_fixed/27029-swift-typebase-isemptyexistentialcomposition.swift index 718de302d1073..392ced7a3bcee 100644 --- a/validation-test/compiler_crashers/27029-swift-typebase-isemptyexistentialcomposition.swift +++ b/validation-test/compiler_crashers_fixed/27029-swift-typebase-isemptyexistentialcomposition.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27030-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27030-std-function-func-swift-type-subst.swift similarity index 80% rename from validation-test/compiler_crashers/27030-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27030-std-function-func-swift-type-subst.swift index 1d4f280857c3b..d5157ac96f6e8 100644 --- a/validation-test/compiler_crashers/27030-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27030-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27031-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/27031-swift-genericparamlist-addnestedarchetypes.swift similarity index 83% rename from validation-test/compiler_crashers/27031-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/27031-swift-genericparamlist-addnestedarchetypes.swift index 8fa2a399fafa6..71272677f7f08 100644 --- a/validation-test/compiler_crashers/27031-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27031-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27032-swift-nominaltypedecl-computeinterfacetype.swift b/validation-test/compiler_crashers_fixed/27032-swift-nominaltypedecl-computeinterfacetype.swift similarity index 82% rename from validation-test/compiler_crashers/27032-swift-nominaltypedecl-computeinterfacetype.swift rename to validation-test/compiler_crashers_fixed/27032-swift-nominaltypedecl-computeinterfacetype.swift index 1382e834436b2..f17315466ca6e 100644 --- a/validation-test/compiler_crashers/27032-swift-nominaltypedecl-computeinterfacetype.swift +++ b/validation-test/compiler_crashers_fixed/27032-swift-nominaltypedecl-computeinterfacetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27033-swift-mangle-mangler-mangleidentifier.swift b/validation-test/compiler_crashers_fixed/27033-swift-mangle-mangler-mangleidentifier.swift similarity index 81% rename from validation-test/compiler_crashers/27033-swift-mangle-mangler-mangleidentifier.swift rename to validation-test/compiler_crashers_fixed/27033-swift-mangle-mangler-mangleidentifier.swift index 9fcf19a38fd45..c68a940e342a9 100644 --- a/validation-test/compiler_crashers/27033-swift-mangle-mangler-mangleidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27033-swift-mangle-mangler-mangleidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27037-swift-nominaltype-get.swift b/validation-test/compiler_crashers_fixed/27037-swift-nominaltype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27037-swift-nominaltype-get.swift rename to validation-test/compiler_crashers_fixed/27037-swift-nominaltype-get.swift index 94aa98c83db34..9b5ee853d599a 100644 --- a/validation-test/compiler_crashers/27037-swift-nominaltype-get.swift +++ b/validation-test/compiler_crashers_fixed/27037-swift-nominaltype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27038-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/27038-swift-constraints-constraintsystem-matchtypes.swift similarity index 83% rename from validation-test/compiler_crashers/27038-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/27038-swift-constraints-constraintsystem-matchtypes.swift index bf91042bddd94..b4d404c81519b 100644 --- a/validation-test/compiler_crashers/27038-swift-constraints-constraintsystem-matchtypes.swift +++ b/validation-test/compiler_crashers_fixed/27038-swift-constraints-constraintsystem-matchtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27039-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27039-swift-typechecker-validatedecl.swift similarity index 83% rename from validation-test/compiler_crashers/27039-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27039-swift-typechecker-validatedecl.swift index 7a640a5843db0..20717401bf2b5 100644 --- a/validation-test/compiler_crashers/27039-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27039-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27043-swift-typechecker-typecheckexpressionshallow.swift b/validation-test/compiler_crashers_fixed/27043-swift-typechecker-typecheckexpressionshallow.swift similarity index 80% rename from validation-test/compiler_crashers/27043-swift-typechecker-typecheckexpressionshallow.swift rename to validation-test/compiler_crashers_fixed/27043-swift-typechecker-typecheckexpressionshallow.swift index 9dc07f0c19c55..c1e9dbad85006 100644 --- a/validation-test/compiler_crashers/27043-swift-typechecker-typecheckexpressionshallow.swift +++ b/validation-test/compiler_crashers_fixed/27043-swift-typechecker-typecheckexpressionshallow.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27044-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/27044-swift-functiontype-get.swift similarity index 80% rename from validation-test/compiler_crashers/27044-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/27044-swift-functiontype-get.swift index f583a9f41a736..06b059999bd10 100644 --- a/validation-test/compiler_crashers/27044-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27044-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27045-swift-lexer-diagnose.swift b/validation-test/compiler_crashers_fixed/27045-swift-lexer-diagnose.swift similarity index 87% rename from validation-test/compiler_crashers/27045-swift-lexer-diagnose.swift rename to validation-test/compiler_crashers_fixed/27045-swift-lexer-diagnose.swift index d90d411791cd4..6574735f3a366 100644 --- a/validation-test/compiler_crashers/27045-swift-lexer-diagnose.swift +++ b/validation-test/compiler_crashers_fixed/27045-swift-lexer-diagnose.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27046-swift-declcontext-getlocalconformances.swift b/validation-test/compiler_crashers_fixed/27046-swift-declcontext-getlocalconformances.swift similarity index 82% rename from validation-test/compiler_crashers/27046-swift-declcontext-getlocalconformances.swift rename to validation-test/compiler_crashers_fixed/27046-swift-declcontext-getlocalconformances.swift index 4448ad3c74ac8..e8c731f5788de 100644 --- a/validation-test/compiler_crashers/27046-swift-declcontext-getlocalconformances.swift +++ b/validation-test/compiler_crashers_fixed/27046-swift-declcontext-getlocalconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27048-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/27048-swift-modulefile-getimportedmodules.swift similarity index 81% rename from validation-test/compiler_crashers/27048-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/27048-swift-modulefile-getimportedmodules.swift index 9009c18a2e422..2d812a3df4923 100644 --- a/validation-test/compiler_crashers/27048-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/27048-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27050-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/27050-swift-typechecker-coercepatterntotype.swift similarity index 81% rename from validation-test/compiler_crashers/27050-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/27050-swift-typechecker-coercepatterntotype.swift index 1309391a5a95a..57352fff1736b 100644 --- a/validation-test/compiler_crashers/27050-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/27050-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27051-swift-constraints-constraint-create.swift b/validation-test/compiler_crashers_fixed/27051-swift-constraints-constraint-create.swift similarity index 81% rename from validation-test/compiler_crashers/27051-swift-constraints-constraint-create.swift rename to validation-test/compiler_crashers_fixed/27051-swift-constraints-constraint-create.swift index 9fa22198738ec..990d3140db286 100644 --- a/validation-test/compiler_crashers/27051-swift-constraints-constraint-create.swift +++ b/validation-test/compiler_crashers_fixed/27051-swift-constraints-constraint-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27052-swift-moduledecl-lookupconformance.swift b/validation-test/compiler_crashers_fixed/27052-swift-moduledecl-lookupconformance.swift similarity index 82% rename from validation-test/compiler_crashers/27052-swift-moduledecl-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/27052-swift-moduledecl-lookupconformance.swift index b4e2094a28df8..5f976c8aba1f3 100644 --- a/validation-test/compiler_crashers/27052-swift-moduledecl-lookupconformance.swift +++ b/validation-test/compiler_crashers_fixed/27052-swift-moduledecl-lookupconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27053-swift-typechecker-checkdeclarationavailability.swift b/validation-test/compiler_crashers_fixed/27053-swift-typechecker-checkdeclarationavailability.swift similarity index 80% rename from validation-test/compiler_crashers/27053-swift-typechecker-checkdeclarationavailability.swift rename to validation-test/compiler_crashers_fixed/27053-swift-typechecker-checkdeclarationavailability.swift index 5edb9470afe3f..b547979466b0d 100644 --- a/validation-test/compiler_crashers/27053-swift-typechecker-checkdeclarationavailability.swift +++ b/validation-test/compiler_crashers_fixed/27053-swift-typechecker-checkdeclarationavailability.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27054-void.swift b/validation-test/compiler_crashers_fixed/27054-void.swift similarity index 80% rename from validation-test/compiler_crashers/27054-void.swift rename to validation-test/compiler_crashers_fixed/27054-void.swift index ae7088c123752..b51346ff3322f 100644 --- a/validation-test/compiler_crashers/27054-void.swift +++ b/validation-test/compiler_crashers_fixed/27054-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27055-swift-constraints-constraintgraph-computeconnectedcomponents.swift b/validation-test/compiler_crashers_fixed/27055-swift-constraints-constraintgraph-computeconnectedcomponents.swift similarity index 80% rename from validation-test/compiler_crashers/27055-swift-constraints-constraintgraph-computeconnectedcomponents.swift rename to validation-test/compiler_crashers_fixed/27055-swift-constraints-constraintgraph-computeconnectedcomponents.swift index bf4fefb68e3de..f727e8e833901 100644 --- a/validation-test/compiler_crashers/27055-swift-constraints-constraintgraph-computeconnectedcomponents.swift +++ b/validation-test/compiler_crashers_fixed/27055-swift-constraints-constraintgraph-computeconnectedcomponents.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27056-swift-classtype-get.swift b/validation-test/compiler_crashers_fixed/27056-swift-classtype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27056-swift-classtype-get.swift rename to validation-test/compiler_crashers_fixed/27056-swift-classtype-get.swift index 63c9edf92db1c..109752cb539dc 100644 --- a/validation-test/compiler_crashers/27056-swift-classtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27056-swift-classtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27058-llvm-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/27058-llvm-optional-swift-diagnostic-operator.swift similarity index 79% rename from validation-test/compiler_crashers/27058-llvm-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/27058-llvm-optional-swift-diagnostic-operator.swift index aa5066e578e39..e5c0383554920 100644 --- a/validation-test/compiler_crashers/27058-llvm-optional-swift-diagnostic-operator.swift +++ b/validation-test/compiler_crashers_fixed/27058-llvm-optional-swift-diagnostic-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27059-swift-optionaltype-get.swift b/validation-test/compiler_crashers_fixed/27059-swift-optionaltype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27059-swift-optionaltype-get.swift rename to validation-test/compiler_crashers_fixed/27059-swift-optionaltype-get.swift index b4730ab7b59db..4e22a894c8d6e 100644 --- a/validation-test/compiler_crashers/27059-swift-optionaltype-get.swift +++ b/validation-test/compiler_crashers_fixed/27059-swift-optionaltype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27060-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27060-swift-inflightdiagnostic.swift similarity index 86% rename from validation-test/compiler_crashers/27060-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27060-swift-inflightdiagnostic.swift index ff05191fe2579..9d27191259627 100644 --- a/validation-test/compiler_crashers/27060-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27060-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27062-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27062-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/27062-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27062-std-function-func-swift-type-subst.swift index 63c4688b0143d..3e3972afc8a54 100644 --- a/validation-test/compiler_crashers/27062-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27062-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27063-swift-conformancelookuptable-lookupconformances.swift b/validation-test/compiler_crashers_fixed/27063-swift-conformancelookuptable-lookupconformances.swift similarity index 82% rename from validation-test/compiler_crashers/27063-swift-conformancelookuptable-lookupconformances.swift rename to validation-test/compiler_crashers_fixed/27063-swift-conformancelookuptable-lookupconformances.swift index 91276da7a5519..b94492d17c4d1 100644 --- a/validation-test/compiler_crashers/27063-swift-conformancelookuptable-lookupconformances.swift +++ b/validation-test/compiler_crashers_fixed/27063-swift-conformancelookuptable-lookupconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27064-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/27064-swift-conformancelookuptable-updatelookuptable.swift similarity index 80% rename from validation-test/compiler_crashers/27064-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/27064-swift-conformancelookuptable-updatelookuptable.swift index 936b9d8958181..54819f4417be6 100644 --- a/validation-test/compiler_crashers/27064-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27064-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27065-swift-typechecker-typecheckclosurebody.swift b/validation-test/compiler_crashers_fixed/27065-swift-typechecker-typecheckclosurebody.swift similarity index 81% rename from validation-test/compiler_crashers/27065-swift-typechecker-typecheckclosurebody.swift rename to validation-test/compiler_crashers_fixed/27065-swift-typechecker-typecheckclosurebody.swift index d5d70c7f585bf..36948c87d3b15 100644 --- a/validation-test/compiler_crashers/27065-swift-typechecker-typecheckclosurebody.swift +++ b/validation-test/compiler_crashers_fixed/27065-swift-typechecker-typecheckclosurebody.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27066-swift-constraints-constraintsystem-applysolution.swift b/validation-test/compiler_crashers_fixed/27066-swift-constraints-constraintsystem-applysolution.swift similarity index 85% rename from validation-test/compiler_crashers/27066-swift-constraints-constraintsystem-applysolution.swift rename to validation-test/compiler_crashers_fixed/27066-swift-constraints-constraintsystem-applysolution.swift index 18e81bf0e0b56..aeaa25f50e539 100644 --- a/validation-test/compiler_crashers/27066-swift-constraints-constraintsystem-applysolution.swift +++ b/validation-test/compiler_crashers_fixed/27066-swift-constraints-constraintsystem-applysolution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27067-swift-valuedecl-settype.swift b/validation-test/compiler_crashers_fixed/27067-swift-valuedecl-settype.swift similarity index 81% rename from validation-test/compiler_crashers/27067-swift-valuedecl-settype.swift rename to validation-test/compiler_crashers_fixed/27067-swift-valuedecl-settype.swift index 0730b766f0b1c..f739137ef9296 100644 --- a/validation-test/compiler_crashers/27067-swift-valuedecl-settype.swift +++ b/validation-test/compiler_crashers_fixed/27067-swift-valuedecl-settype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27068-swift-conformancelookuptable-conformancelookuptable.swift b/validation-test/compiler_crashers_fixed/27068-swift-conformancelookuptable-conformancelookuptable.swift similarity index 80% rename from validation-test/compiler_crashers/27068-swift-conformancelookuptable-conformancelookuptable.swift rename to validation-test/compiler_crashers_fixed/27068-swift-conformancelookuptable-conformancelookuptable.swift index f086c36ed0f9b..519cac4fb400e 100644 --- a/validation-test/compiler_crashers/27068-swift-conformancelookuptable-conformancelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27068-swift-conformancelookuptable-conformancelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27070-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/27070-no-stacktrace.swift similarity index 83% rename from validation-test/compiler_crashers/27070-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/27070-no-stacktrace.swift index 100b61d05eec1..b63d60e62a7c9 100644 --- a/validation-test/compiler_crashers/27070-no-stacktrace.swift +++ b/validation-test/compiler_crashers_fixed/27070-no-stacktrace.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27073-swift-constraints-constraint-create.swift b/validation-test/compiler_crashers_fixed/27073-swift-constraints-constraint-create.swift similarity index 79% rename from validation-test/compiler_crashers/27073-swift-constraints-constraint-create.swift rename to validation-test/compiler_crashers_fixed/27073-swift-constraints-constraint-create.swift index 7ea7373c9c9e4..a9673effa5780 100644 --- a/validation-test/compiler_crashers/27073-swift-constraints-constraint-create.swift +++ b/validation-test/compiler_crashers_fixed/27073-swift-constraints-constraint-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27074-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/27074-swift-nominaltypedecl-preparelookuptable.swift similarity index 81% rename from validation-test/compiler_crashers/27074-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/27074-swift-nominaltypedecl-preparelookuptable.swift index 152009d9296f4..6829574a0f05c 100644 --- a/validation-test/compiler_crashers/27074-swift-nominaltypedecl-preparelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27074-swift-nominaltypedecl-preparelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27075-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27075-swift-type-transform.swift similarity index 80% rename from validation-test/compiler_crashers/27075-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27075-swift-type-transform.swift index 7d086fd8975e2..17a43fa7852e2 100644 --- a/validation-test/compiler_crashers/27075-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27075-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27077-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27077-swift-modulefile-gettype.swift similarity index 82% rename from validation-test/compiler_crashers/27077-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27077-swift-modulefile-gettype.swift index 709845ddeaf12..81819bfa8ca67 100644 --- a/validation-test/compiler_crashers/27077-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27077-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27079-swift-clangmoduleunit-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27079-swift-clangmoduleunit-lookupvalue.swift similarity index 79% rename from validation-test/compiler_crashers/27079-swift-clangmoduleunit-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27079-swift-clangmoduleunit-lookupvalue.swift index 7cf8e0ef41941..f7d809a489340 100644 --- a/validation-test/compiler_crashers/27079-swift-clangmoduleunit-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27079-swift-clangmoduleunit-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27081-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/27081-swift-protocoltype-canonicalizeprotocols.swift similarity index 80% rename from validation-test/compiler_crashers/27081-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/27081-swift-protocoltype-canonicalizeprotocols.swift index 51e5b7bcc00a2..c565c215316f5 100644 --- a/validation-test/compiler_crashers/27081-swift-protocoltype-canonicalizeprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27081-swift-protocoltype-canonicalizeprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27082-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/27082-swift-constraints-constraintgraph-addconstraint.swift similarity index 80% rename from validation-test/compiler_crashers/27082-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/27082-swift-constraints-constraintgraph-addconstraint.swift index 534ed5f81bc64..cb23b4f23c1df 100644 --- a/validation-test/compiler_crashers/27082-swift-constraints-constraintgraph-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27082-swift-constraints-constraintgraph-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27083-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/27083-swift-typechecker-coercepatterntotype.swift similarity index 81% rename from validation-test/compiler_crashers/27083-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/27083-swift-typechecker-coercepatterntotype.swift index 970ed607472fd..e1413365705b2 100644 --- a/validation-test/compiler_crashers/27083-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/27083-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27084-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/27084-swift-abstractclosureexpr-setparams.swift similarity index 81% rename from validation-test/compiler_crashers/27084-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/27084-swift-abstractclosureexpr-setparams.swift index 92e2811522ac6..0582450d6317d 100644 --- a/validation-test/compiler_crashers/27084-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/27084-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27086-llvm-bitstreamcursor-read.swift b/validation-test/compiler_crashers_fixed/27086-llvm-bitstreamcursor-read.swift similarity index 80% rename from validation-test/compiler_crashers/27086-llvm-bitstreamcursor-read.swift rename to validation-test/compiler_crashers_fixed/27086-llvm-bitstreamcursor-read.swift index 233ad5ea564dd..c350e190ba3c4 100644 --- a/validation-test/compiler_crashers/27086-llvm-bitstreamcursor-read.swift +++ b/validation-test/compiler_crashers_fixed/27086-llvm-bitstreamcursor-read.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27088-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27088-swift-modulefile-gettype.swift similarity index 81% rename from validation-test/compiler_crashers/27088-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27088-swift-modulefile-gettype.swift index 904750728b43f..7facac63944fe 100644 --- a/validation-test/compiler_crashers/27088-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27088-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27090-swift-conformancelookuptable-expandimpliedconformances.swift b/validation-test/compiler_crashers_fixed/27090-swift-conformancelookuptable-expandimpliedconformances.swift similarity index 80% rename from validation-test/compiler_crashers/27090-swift-conformancelookuptable-expandimpliedconformances.swift rename to validation-test/compiler_crashers_fixed/27090-swift-conformancelookuptable-expandimpliedconformances.swift index b2f7c87601c7a..edbb328759165 100644 --- a/validation-test/compiler_crashers/27090-swift-conformancelookuptable-expandimpliedconformances.swift +++ b/validation-test/compiler_crashers_fixed/27090-swift-conformancelookuptable-expandimpliedconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27092-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/27092-swift-typeloc-iserror.swift similarity index 81% rename from validation-test/compiler_crashers/27092-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/27092-swift-typeloc-iserror.swift index 7c21adafb274a..8fb34200a709f 100644 --- a/validation-test/compiler_crashers/27092-swift-typeloc-iserror.swift +++ b/validation-test/compiler_crashers_fixed/27092-swift-typeloc-iserror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27093-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/27093-swift-constraints-constraintsystem-solve.swift similarity index 84% rename from validation-test/compiler_crashers/27093-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/27093-swift-constraints-constraintsystem-solve.swift index 5ee63c6f4bc61..084e074b7fee6 100644 --- a/validation-test/compiler_crashers/27093-swift-constraints-constraintsystem-solve.swift +++ b/validation-test/compiler_crashers_fixed/27093-swift-constraints-constraintsystem-solve.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27094-resolveidenttypecomponent.swift b/validation-test/compiler_crashers_fixed/27094-resolveidenttypecomponent.swift similarity index 80% rename from validation-test/compiler_crashers/27094-resolveidenttypecomponent.swift rename to validation-test/compiler_crashers_fixed/27094-resolveidenttypecomponent.swift index ae033733c3300..1a66235fad16b 100644 --- a/validation-test/compiler_crashers/27094-resolveidenttypecomponent.swift +++ b/validation-test/compiler_crashers_fixed/27094-resolveidenttypecomponent.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27095-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/27095-swift-nominaltypedecl-getmembers.swift similarity index 83% rename from validation-test/compiler_crashers/27095-swift-nominaltypedecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/27095-swift-nominaltypedecl-getmembers.swift index 30bf9a0667cef..462b3de31fa3e 100644 --- a/validation-test/compiler_crashers/27095-swift-nominaltypedecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/27095-swift-nominaltypedecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27097-swift-constraints-constraintgraph-change-undo.swift b/validation-test/compiler_crashers_fixed/27097-swift-constraints-constraintgraph-change-undo.swift similarity index 81% rename from validation-test/compiler_crashers/27097-swift-constraints-constraintgraph-change-undo.swift rename to validation-test/compiler_crashers_fixed/27097-swift-constraints-constraintgraph-change-undo.swift index a613eade04fa0..53d488e134f8e 100644 --- a/validation-test/compiler_crashers/27097-swift-constraints-constraintgraph-change-undo.swift +++ b/validation-test/compiler_crashers_fixed/27097-swift-constraints-constraintgraph-change-undo.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27098-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27098-swift-type-transform.swift similarity index 80% rename from validation-test/compiler_crashers/27098-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27098-swift-type-transform.swift index 5c080e95521ad..561245b28460f 100644 --- a/validation-test/compiler_crashers/27098-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27098-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27099-swift-decl-walk.swift b/validation-test/compiler_crashers_fixed/27099-swift-decl-walk.swift similarity index 82% rename from validation-test/compiler_crashers/27099-swift-decl-walk.swift rename to validation-test/compiler_crashers_fixed/27099-swift-decl-walk.swift index a80c8112e76ce..3668e0ab1ea8a 100644 --- a/validation-test/compiler_crashers/27099-swift-decl-walk.swift +++ b/validation-test/compiler_crashers_fixed/27099-swift-decl-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27102-void.swift b/validation-test/compiler_crashers_fixed/27102-void.swift similarity index 79% rename from validation-test/compiler_crashers/27102-void.swift rename to validation-test/compiler_crashers_fixed/27102-void.swift index a1f1c83150bb1..9dca262e9d9ec 100644 --- a/validation-test/compiler_crashers/27102-void.swift +++ b/validation-test/compiler_crashers_fixed/27102-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27104-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27104-swift-modulefile-lookupvalue.swift similarity index 81% rename from validation-test/compiler_crashers/27104-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27104-swift-modulefile-lookupvalue.swift index df9ade74d09e6..9f55822a46360 100644 --- a/validation-test/compiler_crashers/27104-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27104-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27105-swift-typebase-gettypevariables.swift b/validation-test/compiler_crashers_fixed/27105-swift-typebase-gettypevariables.swift similarity index 81% rename from validation-test/compiler_crashers/27105-swift-typebase-gettypevariables.swift rename to validation-test/compiler_crashers_fixed/27105-swift-typebase-gettypevariables.swift index a777ba8bec8a3..dd320464bbca1 100644 --- a/validation-test/compiler_crashers/27105-swift-typebase-gettypevariables.swift +++ b/validation-test/compiler_crashers_fixed/27105-swift-typebase-gettypevariables.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27106-llvm-foldingset-swift-structtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27106-llvm-foldingset-swift-structtype-nodeequals.swift similarity index 81% rename from validation-test/compiler_crashers/27106-llvm-foldingset-swift-structtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27106-llvm-foldingset-swift-structtype-nodeequals.swift index a4ed8e1f23c06..9ace0dfbbb9ab 100644 --- a/validation-test/compiler_crashers/27106-llvm-foldingset-swift-structtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27106-llvm-foldingset-swift-structtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27107-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/27107-swift-typeloc-iserror.swift similarity index 80% rename from validation-test/compiler_crashers/27107-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/27107-swift-typeloc-iserror.swift index e430c73050c5f..b64887bb30749 100644 --- a/validation-test/compiler_crashers/27107-swift-typeloc-iserror.swift +++ b/validation-test/compiler_crashers_fixed/27107-swift-typeloc-iserror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27108-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/27108-swift-conformancelookuptable-updatelookuptable.swift similarity index 81% rename from validation-test/compiler_crashers/27108-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/27108-swift-conformancelookuptable-updatelookuptable.swift index 85eed6b131c6b..3786d86dd60c9 100644 --- a/validation-test/compiler_crashers/27108-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27108-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27110-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/27110-swift-patternbindingdecl-setpattern.swift similarity index 86% rename from validation-test/compiler_crashers/27110-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/27110-swift-patternbindingdecl-setpattern.swift index 45aa2da9aa7e4..929b7a6e44fde 100644 --- a/validation-test/compiler_crashers/27110-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/27110-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27112-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27112-swift-typechecker-validatedecl.swift similarity index 80% rename from validation-test/compiler_crashers/27112-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27112-swift-typechecker-validatedecl.swift index acae56fe70fc9..28f93a9e443eb 100644 --- a/validation-test/compiler_crashers/27112-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27112-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27113-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/27113-swift-nominaltypedecl-getmembers.swift similarity index 86% rename from validation-test/compiler_crashers/27113-swift-nominaltypedecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/27113-swift-nominaltypedecl-getmembers.swift index 2ad94a5f947ff..841a915a4119a 100644 --- a/validation-test/compiler_crashers/27113-swift-nominaltypedecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/27113-swift-nominaltypedecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27114-swift-valuedecl-settype.swift b/validation-test/compiler_crashers_fixed/27114-swift-valuedecl-settype.swift similarity index 81% rename from validation-test/compiler_crashers/27114-swift-valuedecl-settype.swift rename to validation-test/compiler_crashers_fixed/27114-swift-valuedecl-settype.swift index e01d5a0ebfca7..b164ff16819cd 100644 --- a/validation-test/compiler_crashers/27114-swift-valuedecl-settype.swift +++ b/validation-test/compiler_crashers_fixed/27114-swift-valuedecl-settype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27116-swift-constraints-constraintgraph-unbindtypevariable.swift b/validation-test/compiler_crashers_fixed/27116-swift-constraints-constraintgraph-unbindtypevariable.swift similarity index 84% rename from validation-test/compiler_crashers/27116-swift-constraints-constraintgraph-unbindtypevariable.swift rename to validation-test/compiler_crashers_fixed/27116-swift-constraints-constraintgraph-unbindtypevariable.swift index 24a0bd1b0d657..666afb2857db4 100644 --- a/validation-test/compiler_crashers/27116-swift-constraints-constraintgraph-unbindtypevariable.swift +++ b/validation-test/compiler_crashers_fixed/27116-swift-constraints-constraintgraph-unbindtypevariable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27117-swift-clangimporter-implementation-importdeclimpl.swift b/validation-test/compiler_crashers_fixed/27117-swift-clangimporter-implementation-importdeclimpl.swift similarity index 82% rename from validation-test/compiler_crashers/27117-swift-clangimporter-implementation-importdeclimpl.swift rename to validation-test/compiler_crashers_fixed/27117-swift-clangimporter-implementation-importdeclimpl.swift index a91a97d64f4e8..34d26a9ed9586 100644 --- a/validation-test/compiler_crashers/27117-swift-clangimporter-implementation-importdeclimpl.swift +++ b/validation-test/compiler_crashers_fixed/27117-swift-clangimporter-implementation-importdeclimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27120-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift b/validation-test/compiler_crashers_fixed/27120-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift similarity index 81% rename from validation-test/compiler_crashers/27120-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27120-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift index 483b2c48cfff8..0d645efb921af 100644 --- a/validation-test/compiler_crashers/27120-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27120-llvm-foldingset-swift-constraints-constraintlocator-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27121-vtable.swift b/validation-test/compiler_crashers_fixed/27121-vtable.swift similarity index 79% rename from validation-test/compiler_crashers/27121-vtable.swift rename to validation-test/compiler_crashers_fixed/27121-vtable.swift index c6aa1826282f6..f5480ff5b36a0 100644 --- a/validation-test/compiler_crashers/27121-vtable.swift +++ b/validation-test/compiler_crashers_fixed/27121-vtable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27122-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/27122-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 81% rename from validation-test/compiler_crashers/27122-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/27122-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift index 116f766166de6..5dca264c7e121 100644 --- a/validation-test/compiler_crashers/27122-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift +++ b/validation-test/compiler_crashers_fixed/27122-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27124-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27124-swift-modulefile-lookupvalue.swift similarity index 82% rename from validation-test/compiler_crashers/27124-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27124-swift-modulefile-lookupvalue.swift index a339148e6220f..383c136d42bc0 100644 --- a/validation-test/compiler_crashers/27124-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27124-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27125-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/27125-swift-typechecker-coercepatterntotype.swift similarity index 82% rename from validation-test/compiler_crashers/27125-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/27125-swift-typechecker-coercepatterntotype.swift index 708a243299c7d..1fb10bc65268f 100644 --- a/validation-test/compiler_crashers/27125-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/27125-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27126-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/27126-swift-constraints-solution-solution.swift similarity index 80% rename from validation-test/compiler_crashers/27126-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/27126-swift-constraints-solution-solution.swift index 4d9983489dea9..730c90b5c5159 100644 --- a/validation-test/compiler_crashers/27126-swift-constraints-solution-solution.swift +++ b/validation-test/compiler_crashers_fixed/27126-swift-constraints-solution-solution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27127-swift-constraints-constraintgraph-change-undo.swift b/validation-test/compiler_crashers_fixed/27127-swift-constraints-constraintgraph-change-undo.swift similarity index 81% rename from validation-test/compiler_crashers/27127-swift-constraints-constraintgraph-change-undo.swift rename to validation-test/compiler_crashers_fixed/27127-swift-constraints-constraintgraph-change-undo.swift index e977e7dcab23f..d5f6fa910ecdb 100644 --- a/validation-test/compiler_crashers/27127-swift-constraints-constraintgraph-change-undo.swift +++ b/validation-test/compiler_crashers_fixed/27127-swift-constraints-constraintgraph-change-undo.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27128-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/27128-swift-nominaltypedecl-preparelookuptable.swift similarity index 82% rename from validation-test/compiler_crashers/27128-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/27128-swift-nominaltypedecl-preparelookuptable.swift index c6051a93ac260..5250001e422cb 100644 --- a/validation-test/compiler_crashers/27128-swift-nominaltypedecl-preparelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27128-swift-nominaltypedecl-preparelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27129-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/27129-swift-typebase-getcanonicaltype.swift similarity index 82% rename from validation-test/compiler_crashers/27129-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/27129-swift-typebase-getcanonicaltype.swift index 3c0e52e1909a6..b8a8acde53a73 100644 --- a/validation-test/compiler_crashers/27129-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/27129-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27130-swift-typechecker-validatetype.swift b/validation-test/compiler_crashers_fixed/27130-swift-typechecker-validatetype.swift similarity index 81% rename from validation-test/compiler_crashers/27130-swift-typechecker-validatetype.swift rename to validation-test/compiler_crashers_fixed/27130-swift-typechecker-validatetype.swift index 6aaf486e01884..eb94d0efbaa78 100644 --- a/validation-test/compiler_crashers/27130-swift-typechecker-validatetype.swift +++ b/validation-test/compiler_crashers_fixed/27130-swift-typechecker-validatetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27133-swift-genericparamlist-getasgenericsignatureelements.swift b/validation-test/compiler_crashers_fixed/27133-swift-genericparamlist-getasgenericsignatureelements.swift similarity index 83% rename from validation-test/compiler_crashers/27133-swift-genericparamlist-getasgenericsignatureelements.swift rename to validation-test/compiler_crashers_fixed/27133-swift-genericparamlist-getasgenericsignatureelements.swift index f98464c887df1..847ea9870372c 100644 --- a/validation-test/compiler_crashers/27133-swift-genericparamlist-getasgenericsignatureelements.swift +++ b/validation-test/compiler_crashers_fixed/27133-swift-genericparamlist-getasgenericsignatureelements.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27134-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/27134-swift-structtype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27134-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/27134-swift-structtype-get.swift index 167661b16ebad..378489d9932d4 100644 --- a/validation-test/compiler_crashers/27134-swift-structtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27134-swift-structtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27137-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/27137-swift-typechecker-coercepatterntotype.swift similarity index 81% rename from validation-test/compiler_crashers/27137-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/27137-swift-typechecker-coercepatterntotype.swift index 3b4e365382cd0..a5165ac02e111 100644 --- a/validation-test/compiler_crashers/27137-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/27137-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27139-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27139-swift-type-subst.swift similarity index 84% rename from validation-test/compiler_crashers/27139-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27139-swift-type-subst.swift index c700d78b226fc..15d782c2c424a 100644 --- a/validation-test/compiler_crashers/27139-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27139-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27140-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/27140-swift-metatypetype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27140-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27140-swift-metatypetype-get.swift index b9729a94e0740..7fb575a9bd635 100644 --- a/validation-test/compiler_crashers/27140-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27140-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27141-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27141-swift-inflightdiagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/27141-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27141-swift-inflightdiagnostic.swift index 7bfbf012500e6..b8c256a36acff 100644 --- a/validation-test/compiler_crashers/27141-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27141-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27143-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27143-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27143-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27143-swift-printingdiagnosticconsumer-handlediagnostic.swift index 16c4c2db12950..eb8375eef8ed6 100644 --- a/validation-test/compiler_crashers/27143-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27143-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27144-swift-typebase-getsuperclass.swift b/validation-test/compiler_crashers_fixed/27144-swift-typebase-getsuperclass.swift similarity index 80% rename from validation-test/compiler_crashers/27144-swift-typebase-getsuperclass.swift rename to validation-test/compiler_crashers_fixed/27144-swift-typebase-getsuperclass.swift index ce89569d3c6cc..92db4f89da6d5 100644 --- a/validation-test/compiler_crashers/27144-swift-typebase-getsuperclass.swift +++ b/validation-test/compiler_crashers_fixed/27144-swift-typebase-getsuperclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27145-swift-archetypebuilder-addgenericsignature.swift b/validation-test/compiler_crashers_fixed/27145-swift-archetypebuilder-addgenericsignature.swift similarity index 81% rename from validation-test/compiler_crashers/27145-swift-archetypebuilder-addgenericsignature.swift rename to validation-test/compiler_crashers_fixed/27145-swift-archetypebuilder-addgenericsignature.swift index 9108748b67a8a..5cc9a0519f109 100644 --- a/validation-test/compiler_crashers/27145-swift-archetypebuilder-addgenericsignature.swift +++ b/validation-test/compiler_crashers_fixed/27145-swift-archetypebuilder-addgenericsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27147-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/27147-swift-boundgenerictype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27147-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/27147-swift-boundgenerictype-get.swift index ac74e49fc2bf7..641a4077196ac 100644 --- a/validation-test/compiler_crashers/27147-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/27147-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27148-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27148-swift-typechecker-validatedecl.swift similarity index 82% rename from validation-test/compiler_crashers/27148-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27148-swift-typechecker-validatedecl.swift index b4b1187b7e982..4094cde9fdd2f 100644 --- a/validation-test/compiler_crashers/27148-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27148-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27149-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/27149-swift-typeloc-iserror.swift similarity index 81% rename from validation-test/compiler_crashers/27149-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/27149-swift-typeloc-iserror.swift index 62f7cf05528dd..5f227943ec916 100644 --- a/validation-test/compiler_crashers/27149-swift-typeloc-iserror.swift +++ b/validation-test/compiler_crashers_fixed/27149-swift-typeloc-iserror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27150-swift-constraints-constraintsystem-gettypeofmemberreference.swift b/validation-test/compiler_crashers_fixed/27150-swift-constraints-constraintsystem-gettypeofmemberreference.swift similarity index 80% rename from validation-test/compiler_crashers/27150-swift-constraints-constraintsystem-gettypeofmemberreference.swift rename to validation-test/compiler_crashers_fixed/27150-swift-constraints-constraintsystem-gettypeofmemberreference.swift index f74aceb770562..559c9e0d8dede 100644 --- a/validation-test/compiler_crashers/27150-swift-constraints-constraintsystem-gettypeofmemberreference.swift +++ b/validation-test/compiler_crashers_fixed/27150-swift-constraints-constraintsystem-gettypeofmemberreference.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27151-swift-expr-walk.swift b/validation-test/compiler_crashers_fixed/27151-swift-expr-walk.swift similarity index 79% rename from validation-test/compiler_crashers/27151-swift-expr-walk.swift rename to validation-test/compiler_crashers_fixed/27151-swift-expr-walk.swift index fc219503d10cd..68c232c7278d3 100644 --- a/validation-test/compiler_crashers/27151-swift-expr-walk.swift +++ b/validation-test/compiler_crashers_fixed/27151-swift-expr-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27153-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/27153-swift-conformancelookuptable-updatelookuptable.swift similarity index 82% rename from validation-test/compiler_crashers/27153-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/27153-swift-conformancelookuptable-updatelookuptable.swift index 195278c514038..fe635bd943a81 100644 --- a/validation-test/compiler_crashers/27153-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27153-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27154-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/27154-swift-modulefile-getdecl.swift similarity index 81% rename from validation-test/compiler_crashers/27154-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/27154-swift-modulefile-getdecl.swift index a8dc16eb23223..1b5b4d2502776 100644 --- a/validation-test/compiler_crashers/27154-swift-modulefile-getdecl.swift +++ b/validation-test/compiler_crashers_fixed/27154-swift-modulefile-getdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27155-swift-attributebase-operator.swift b/validation-test/compiler_crashers_fixed/27155-swift-attributebase-operator.swift similarity index 83% rename from validation-test/compiler_crashers/27155-swift-attributebase-operator.swift rename to validation-test/compiler_crashers_fixed/27155-swift-attributebase-operator.swift index 006fb37e5ef43..f62c4ccd8aec3 100644 --- a/validation-test/compiler_crashers/27155-swift-attributebase-operator.swift +++ b/validation-test/compiler_crashers_fixed/27155-swift-attributebase-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27157-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27157-swift-type-transform.swift similarity index 82% rename from validation-test/compiler_crashers/27157-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27157-swift-type-transform.swift index e49b3cea0fc19..79da366f4c035 100644 --- a/validation-test/compiler_crashers/27157-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27157-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27158-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27158-swift-inflightdiagnostic.swift similarity index 84% rename from validation-test/compiler_crashers/27158-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27158-swift-inflightdiagnostic.swift index d5689f351d652..712a2b57cd61d 100644 --- a/validation-test/compiler_crashers/27158-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27158-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27160-swift-classtype-get.swift b/validation-test/compiler_crashers_fixed/27160-swift-classtype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27160-swift-classtype-get.swift rename to validation-test/compiler_crashers_fixed/27160-swift-classtype-get.swift index 340e41b1fd427..e6993046b2577 100644 --- a/validation-test/compiler_crashers/27160-swift-classtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27160-swift-classtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27161-swift-typechecker-typecheckpattern.swift b/validation-test/compiler_crashers_fixed/27161-swift-typechecker-typecheckpattern.swift similarity index 80% rename from validation-test/compiler_crashers/27161-swift-typechecker-typecheckpattern.swift rename to validation-test/compiler_crashers_fixed/27161-swift-typechecker-typecheckpattern.swift index 443a8d4f9404d..0d1f5fe56045e 100644 --- a/validation-test/compiler_crashers/27161-swift-typechecker-typecheckpattern.swift +++ b/validation-test/compiler_crashers_fixed/27161-swift-typechecker-typecheckpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27162-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27162-swift-type-transform.swift similarity index 79% rename from validation-test/compiler_crashers/27162-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27162-swift-type-transform.swift index c0210fbb6e7cd..539a87e31db24 100644 --- a/validation-test/compiler_crashers/27162-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27162-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27163-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/27163-swift-abstractclosureexpr-setparams.swift similarity index 91% rename from validation-test/compiler_crashers/27163-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/27163-swift-abstractclosureexpr-setparams.swift index 6c27f5cd57803..a2218f77020bf 100644 --- a/validation-test/compiler_crashers/27163-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/27163-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27164-swift-parser-parsetypeidentifier.swift b/validation-test/compiler_crashers_fixed/27164-swift-parser-parsetypeidentifier.swift similarity index 79% rename from validation-test/compiler_crashers/27164-swift-parser-parsetypeidentifier.swift rename to validation-test/compiler_crashers_fixed/27164-swift-parser-parsetypeidentifier.swift index 45091e9b2b947..075d0181e982b 100644 --- a/validation-test/compiler_crashers/27164-swift-parser-parsetypeidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27164-swift-parser-parsetypeidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27165-swift-typechecker-checkunsupportedprotocoltype.swift b/validation-test/compiler_crashers_fixed/27165-swift-typechecker-checkunsupportedprotocoltype.swift similarity index 85% rename from validation-test/compiler_crashers/27165-swift-typechecker-checkunsupportedprotocoltype.swift rename to validation-test/compiler_crashers_fixed/27165-swift-typechecker-checkunsupportedprotocoltype.swift index 922d08aa42fb4..b6f26d894d5e5 100644 --- a/validation-test/compiler_crashers/27165-swift-typechecker-checkunsupportedprotocoltype.swift +++ b/validation-test/compiler_crashers_fixed/27165-swift-typechecker-checkunsupportedprotocoltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27166-swift-typebase-isspecialized.swift b/validation-test/compiler_crashers_fixed/27166-swift-typebase-isspecialized.swift similarity index 83% rename from validation-test/compiler_crashers/27166-swift-typebase-isspecialized.swift rename to validation-test/compiler_crashers_fixed/27166-swift-typebase-isspecialized.swift index ccb3fc3c66bbd..df4776ad24ea4 100644 --- a/validation-test/compiler_crashers/27166-swift-typebase-isspecialized.swift +++ b/validation-test/compiler_crashers_fixed/27166-swift-typebase-isspecialized.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27168-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/27168-swift-constraints-constraintsystem-matchtypes.swift similarity index 80% rename from validation-test/compiler_crashers/27168-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/27168-swift-constraints-constraintsystem-matchtypes.swift index 2912ff27eed18..d85931b36b2c3 100644 --- a/validation-test/compiler_crashers/27168-swift-constraints-constraintsystem-matchtypes.swift +++ b/validation-test/compiler_crashers_fixed/27168-swift-constraints-constraintsystem-matchtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27169-swift-typechecker-validategenericfuncsignature.swift b/validation-test/compiler_crashers_fixed/27169-swift-typechecker-validategenericfuncsignature.swift similarity index 81% rename from validation-test/compiler_crashers/27169-swift-typechecker-validategenericfuncsignature.swift rename to validation-test/compiler_crashers_fixed/27169-swift-typechecker-validategenericfuncsignature.swift index 7f92bf453cc5d..d5440f893ac68 100644 --- a/validation-test/compiler_crashers/27169-swift-typechecker-validategenericfuncsignature.swift +++ b/validation-test/compiler_crashers_fixed/27169-swift-typechecker-validategenericfuncsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27171-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/27171-swift-typebase-getanyoptionalobjecttype.swift similarity index 81% rename from validation-test/compiler_crashers/27171-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/27171-swift-typebase-getanyoptionalobjecttype.swift index 95bc1066ef17b..6cdc1c88db86e 100644 --- a/validation-test/compiler_crashers/27171-swift-typebase-getanyoptionalobjecttype.swift +++ b/validation-test/compiler_crashers_fixed/27171-swift-typebase-getanyoptionalobjecttype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27172-swift-typebase-isemptyexistentialcomposition.swift b/validation-test/compiler_crashers_fixed/27172-swift-typebase-isemptyexistentialcomposition.swift similarity index 82% rename from validation-test/compiler_crashers/27172-swift-typebase-isemptyexistentialcomposition.swift rename to validation-test/compiler_crashers_fixed/27172-swift-typebase-isemptyexistentialcomposition.swift index cabe6169769ea..ccd207a19d5b0 100644 --- a/validation-test/compiler_crashers/27172-swift-typebase-isemptyexistentialcomposition.swift +++ b/validation-test/compiler_crashers_fixed/27172-swift-typebase-isemptyexistentialcomposition.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27173-swift-namelookup-findlocalval-visitbracestmt.swift b/validation-test/compiler_crashers_fixed/27173-swift-namelookup-findlocalval-visitbracestmt.swift similarity index 79% rename from validation-test/compiler_crashers/27173-swift-namelookup-findlocalval-visitbracestmt.swift rename to validation-test/compiler_crashers_fixed/27173-swift-namelookup-findlocalval-visitbracestmt.swift index 868402ad65bfc..422798c6072e8 100644 --- a/validation-test/compiler_crashers/27173-swift-namelookup-findlocalval-visitbracestmt.swift +++ b/validation-test/compiler_crashers_fixed/27173-swift-namelookup-findlocalval-visitbracestmt.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27174-swift-valuedecl-getoverloadsignature.swift b/validation-test/compiler_crashers_fixed/27174-swift-valuedecl-getoverloadsignature.swift similarity index 81% rename from validation-test/compiler_crashers/27174-swift-valuedecl-getoverloadsignature.swift rename to validation-test/compiler_crashers_fixed/27174-swift-valuedecl-getoverloadsignature.swift index 4136ceef2ca11..fd61b2daae11e 100644 --- a/validation-test/compiler_crashers/27174-swift-valuedecl-getoverloadsignature.swift +++ b/validation-test/compiler_crashers_fixed/27174-swift-valuedecl-getoverloadsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27176-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/27176-swift-streamprinter-printtext.swift similarity index 82% rename from validation-test/compiler_crashers/27176-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/27176-swift-streamprinter-printtext.swift index 65864aa091176..c93714ac9b0b9 100644 --- a/validation-test/compiler_crashers/27176-swift-streamprinter-printtext.swift +++ b/validation-test/compiler_crashers_fixed/27176-swift-streamprinter-printtext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27178-vtable.swift b/validation-test/compiler_crashers_fixed/27178-vtable.swift similarity index 80% rename from validation-test/compiler_crashers/27178-vtable.swift rename to validation-test/compiler_crashers_fixed/27178-vtable.swift index a73c3d7966c2c..0b8d53ed52d11 100644 --- a/validation-test/compiler_crashers/27178-vtable.swift +++ b/validation-test/compiler_crashers_fixed/27178-vtable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27179-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27179-swift-modulefile-gettype.swift similarity index 82% rename from validation-test/compiler_crashers/27179-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27179-swift-modulefile-gettype.swift index 5cc7abf239aaa..9d7e0b941f144 100644 --- a/validation-test/compiler_crashers/27179-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27179-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27180-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/27180-swift-constraints-constraintsystem-simplifytype.swift similarity index 80% rename from validation-test/compiler_crashers/27180-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/27180-swift-constraints-constraintsystem-simplifytype.swift index 4cb3dd4ff520b..b89973e35f307 100644 --- a/validation-test/compiler_crashers/27180-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/27180-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27181-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/27181-swift-patternbindingdecl-setpattern.swift similarity index 81% rename from validation-test/compiler_crashers/27181-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/27181-swift-patternbindingdecl-setpattern.swift index e05108ff9b844..91e185ef5fb72 100644 --- a/validation-test/compiler_crashers/27181-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/27181-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27182-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/27182-swift-lexer-leximpl.swift similarity index 83% rename from validation-test/compiler_crashers/27182-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/27182-swift-lexer-leximpl.swift index fb4fa1c56375a..e17c78c529e43 100644 --- a/validation-test/compiler_crashers/27182-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/27182-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27183-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/27183-swift-diagnosticengine-flushactivediagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/27183-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/27183-swift-diagnosticengine-flushactivediagnostic.swift index 4c5bf8ba636cb..254db4847d9cc 100644 --- a/validation-test/compiler_crashers/27183-swift-diagnosticengine-flushactivediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27183-swift-diagnosticengine-flushactivediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27184-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/27184-swift-lexer-getlocforendoftoken.swift similarity index 81% rename from validation-test/compiler_crashers/27184-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/27184-swift-lexer-getlocforendoftoken.swift index e8b2f28f3be83..cf9b6b8804ce0 100644 --- a/validation-test/compiler_crashers/27184-swift-lexer-getlocforendoftoken.swift +++ b/validation-test/compiler_crashers_fixed/27184-swift-lexer-getlocforendoftoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27185-swift-astcontext-getbridgedtoobjc.swift b/validation-test/compiler_crashers_fixed/27185-swift-astcontext-getbridgedtoobjc.swift similarity index 82% rename from validation-test/compiler_crashers/27185-swift-astcontext-getbridgedtoobjc.swift rename to validation-test/compiler_crashers_fixed/27185-swift-astcontext-getbridgedtoobjc.swift index 0733cc81b99fa..131876f46a916 100644 --- a/validation-test/compiler_crashers/27185-swift-astcontext-getbridgedtoobjc.swift +++ b/validation-test/compiler_crashers_fixed/27185-swift-astcontext-getbridgedtoobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27186-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/27186-swift-diagnosticengine-emitdiagnostic.swift similarity index 83% rename from validation-test/compiler_crashers/27186-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27186-swift-diagnosticengine-emitdiagnostic.swift index 187d69c4faefd..adbaeb416f76d 100644 --- a/validation-test/compiler_crashers/27186-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27186-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27187-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/27187-swift-protocoltype-canonicalizeprotocols.swift similarity index 80% rename from validation-test/compiler_crashers/27187-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/27187-swift-protocoltype-canonicalizeprotocols.swift index fd3a747e80771..c43aa718d557a 100644 --- a/validation-test/compiler_crashers/27187-swift-protocoltype-canonicalizeprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27187-swift-protocoltype-canonicalizeprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27188-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/27188-swift-diagnosticengine-emitdiagnostic.swift similarity index 83% rename from validation-test/compiler_crashers/27188-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27188-swift-diagnosticengine-emitdiagnostic.swift index 4138a9e6d90c3..8da1bd0ddab7e 100644 --- a/validation-test/compiler_crashers/27188-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27188-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27190-swift-typechecker-checkunsupportedprotocoltype.swift b/validation-test/compiler_crashers_fixed/27190-swift-typechecker-checkunsupportedprotocoltype.swift similarity index 82% rename from validation-test/compiler_crashers/27190-swift-typechecker-checkunsupportedprotocoltype.swift rename to validation-test/compiler_crashers_fixed/27190-swift-typechecker-checkunsupportedprotocoltype.swift index 7884b3096b234..07ba813ea5f89 100644 --- a/validation-test/compiler_crashers/27190-swift-typechecker-checkunsupportedprotocoltype.swift +++ b/validation-test/compiler_crashers_fixed/27190-swift-typechecker-checkunsupportedprotocoltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27191-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/27191-swift-metatypetype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27191-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27191-swift-metatypetype-get.swift index e8167c29a8e37..00a1f548ba550 100644 --- a/validation-test/compiler_crashers/27191-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27191-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27192-swift-dependentmembertype-get.swift b/validation-test/compiler_crashers_fixed/27192-swift-dependentmembertype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27192-swift-dependentmembertype-get.swift rename to validation-test/compiler_crashers_fixed/27192-swift-dependentmembertype-get.swift index 2be2e82baf113..68eefd56b30f9 100644 --- a/validation-test/compiler_crashers/27192-swift-dependentmembertype-get.swift +++ b/validation-test/compiler_crashers_fixed/27192-swift-dependentmembertype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27193-swift-typeloc-iserror.swift b/validation-test/compiler_crashers_fixed/27193-swift-typeloc-iserror.swift similarity index 83% rename from validation-test/compiler_crashers/27193-swift-typeloc-iserror.swift rename to validation-test/compiler_crashers_fixed/27193-swift-typeloc-iserror.swift index 806f53ea9938f..404efc4c152e8 100644 --- a/validation-test/compiler_crashers/27193-swift-typeloc-iserror.swift +++ b/validation-test/compiler_crashers_fixed/27193-swift-typeloc-iserror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27194-swift-pattern-foreachvariable.swift b/validation-test/compiler_crashers_fixed/27194-swift-pattern-foreachvariable.swift similarity index 97% rename from validation-test/compiler_crashers/27194-swift-pattern-foreachvariable.swift rename to validation-test/compiler_crashers_fixed/27194-swift-pattern-foreachvariable.swift index a985b2831787c..39fe64474d694 100644 --- a/validation-test/compiler_crashers/27194-swift-pattern-foreachvariable.swift +++ b/validation-test/compiler_crashers_fixed/27194-swift-pattern-foreachvariable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27195-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/27195-swift-protocoltype-canonicalizeprotocols.swift similarity index 83% rename from validation-test/compiler_crashers/27195-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/27195-swift-protocoltype-canonicalizeprotocols.swift index 221ca06f5fd92..ee9b111fba02a 100644 --- a/validation-test/compiler_crashers/27195-swift-protocoltype-canonicalizeprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27195-swift-protocoltype-canonicalizeprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27196-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/27196-swift-typebase-getanyoptionalobjecttype.swift similarity index 82% rename from validation-test/compiler_crashers/27196-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/27196-swift-typebase-getanyoptionalobjecttype.swift index 6912e71c41bae..43df55864c9b9 100644 --- a/validation-test/compiler_crashers/27196-swift-typebase-getanyoptionalobjecttype.swift +++ b/validation-test/compiler_crashers_fixed/27196-swift-typebase-getanyoptionalobjecttype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27197-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27197-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/27197-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27197-std-function-func-swift-type-subst.swift index 1b70c044edfaa..4b3f5ce811a59 100644 --- a/validation-test/compiler_crashers/27197-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27197-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27198-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/27198-swift-substitutedtype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27198-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/27198-swift-substitutedtype-get.swift index cac7be77965bb..3149237216be5 100644 --- a/validation-test/compiler_crashers/27198-swift-substitutedtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27198-swift-substitutedtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27199-swift-conformancelookuptable-lookupconformances.swift b/validation-test/compiler_crashers_fixed/27199-swift-conformancelookuptable-lookupconformances.swift similarity index 84% rename from validation-test/compiler_crashers/27199-swift-conformancelookuptable-lookupconformances.swift rename to validation-test/compiler_crashers_fixed/27199-swift-conformancelookuptable-lookupconformances.swift index 16e8a6c55d9b3..00de103f2afef 100644 --- a/validation-test/compiler_crashers/27199-swift-conformancelookuptable-lookupconformances.swift +++ b/validation-test/compiler_crashers_fixed/27199-swift-conformancelookuptable-lookupconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27200-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/27200-swift-abstractclosureexpr-setparams.swift similarity index 81% rename from validation-test/compiler_crashers/27200-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/27200-swift-abstractclosureexpr-setparams.swift index 46b4b755161bf..7f22a80eff18d 100644 --- a/validation-test/compiler_crashers/27200-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/27200-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27201-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/27201-swift-diagnosticengine-emitdiagnostic.swift similarity index 80% rename from validation-test/compiler_crashers/27201-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27201-swift-diagnosticengine-emitdiagnostic.swift index 10014cf96acb2..3780228c0c9c8 100644 --- a/validation-test/compiler_crashers/27201-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27201-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27202-swift-parser-consumetoken.swift b/validation-test/compiler_crashers_fixed/27202-swift-parser-consumetoken.swift similarity index 82% rename from validation-test/compiler_crashers/27202-swift-parser-consumetoken.swift rename to validation-test/compiler_crashers_fixed/27202-swift-parser-consumetoken.swift index 1d2c85cf6d715..63e7f8f86ca15 100644 --- a/validation-test/compiler_crashers/27202-swift-parser-consumetoken.swift +++ b/validation-test/compiler_crashers_fixed/27202-swift-parser-consumetoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27204-swift-expr-getloc.swift b/validation-test/compiler_crashers_fixed/27204-swift-expr-getloc.swift similarity index 81% rename from validation-test/compiler_crashers/27204-swift-expr-getloc.swift rename to validation-test/compiler_crashers_fixed/27204-swift-expr-getloc.swift index a302c52a33c52..ab671e4b1084f 100644 --- a/validation-test/compiler_crashers/27204-swift-expr-getloc.swift +++ b/validation-test/compiler_crashers_fixed/27204-swift-expr-getloc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27205-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/27205-swift-nominaltypedecl-getmembers.swift similarity index 82% rename from validation-test/compiler_crashers/27205-swift-nominaltypedecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/27205-swift-nominaltypedecl-getmembers.swift index 7a04beb788da7..ebc1d12c083f8 100644 --- a/validation-test/compiler_crashers/27205-swift-nominaltypedecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/27205-swift-nominaltypedecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27206-llvm-foldingset-swift-classtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27206-llvm-foldingset-swift-classtype-nodeequals.swift similarity index 82% rename from validation-test/compiler_crashers/27206-llvm-foldingset-swift-classtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27206-llvm-foldingset-swift-classtype-nodeequals.swift index c384cd2eb6f97..9246956a0b882 100644 --- a/validation-test/compiler_crashers/27206-llvm-foldingset-swift-classtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27206-llvm-foldingset-swift-classtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27207-swift-stmt-walk.swift b/validation-test/compiler_crashers_fixed/27207-swift-stmt-walk.swift similarity index 80% rename from validation-test/compiler_crashers/27207-swift-stmt-walk.swift rename to validation-test/compiler_crashers_fixed/27207-swift-stmt-walk.swift index 421420ca9f5c6..8df4df6ff84d6 100644 --- a/validation-test/compiler_crashers/27207-swift-stmt-walk.swift +++ b/validation-test/compiler_crashers_fixed/27207-swift-stmt-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27209-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27209-swift-type-transform.swift similarity index 82% rename from validation-test/compiler_crashers/27209-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27209-swift-type-transform.swift index ce272e6e6f014..3e0cc1cf3a2bf 100644 --- a/validation-test/compiler_crashers/27209-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27209-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27210-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/27210-swift-diagnosticengine-emitdiagnostic.swift similarity index 83% rename from validation-test/compiler_crashers/27210-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27210-swift-diagnosticengine-emitdiagnostic.swift index 7c303a391182d..ad1e57cf529b9 100644 --- a/validation-test/compiler_crashers/27210-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27210-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27211-llvm-foldingsetnodeid-operator.swift b/validation-test/compiler_crashers_fixed/27211-llvm-foldingsetnodeid-operator.swift similarity index 81% rename from validation-test/compiler_crashers/27211-llvm-foldingsetnodeid-operator.swift rename to validation-test/compiler_crashers_fixed/27211-llvm-foldingsetnodeid-operator.swift index a0e1772bf8b13..9384128c29696 100644 --- a/validation-test/compiler_crashers/27211-llvm-foldingsetnodeid-operator.swift +++ b/validation-test/compiler_crashers_fixed/27211-llvm-foldingsetnodeid-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27212-swift-removeshadoweddecls.swift b/validation-test/compiler_crashers_fixed/27212-swift-removeshadoweddecls.swift similarity index 81% rename from validation-test/compiler_crashers/27212-swift-removeshadoweddecls.swift rename to validation-test/compiler_crashers_fixed/27212-swift-removeshadoweddecls.swift index 479a18e048145..02712502cac8a 100644 --- a/validation-test/compiler_crashers/27212-swift-removeshadoweddecls.swift +++ b/validation-test/compiler_crashers_fixed/27212-swift-removeshadoweddecls.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27213-llvm-foldingset-swift-structtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27213-llvm-foldingset-swift-structtype-nodeequals.swift similarity index 80% rename from validation-test/compiler_crashers/27213-llvm-foldingset-swift-structtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27213-llvm-foldingset-swift-structtype-nodeequals.swift index f1f61e297a58e..49b77ef5475fa 100644 --- a/validation-test/compiler_crashers/27213-llvm-foldingset-swift-structtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27213-llvm-foldingset-swift-structtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27214-checkenumrawvalues.swift b/validation-test/compiler_crashers_fixed/27214-checkenumrawvalues.swift similarity index 81% rename from validation-test/compiler_crashers/27214-checkenumrawvalues.swift rename to validation-test/compiler_crashers_fixed/27214-checkenumrawvalues.swift index 6eb276f93b16b..62803bc8d10cd 100644 --- a/validation-test/compiler_crashers/27214-checkenumrawvalues.swift +++ b/validation-test/compiler_crashers_fixed/27214-checkenumrawvalues.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27216-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/27216-swift-typebase-getcanonicaltype.swift similarity index 81% rename from validation-test/compiler_crashers/27216-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/27216-swift-typebase-getcanonicaltype.swift index 72880ed836dde..293c7e53299a6 100644 --- a/validation-test/compiler_crashers/27216-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/27216-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27217-swift-funcdecl-setdeserializedsignature.swift b/validation-test/compiler_crashers_fixed/27217-swift-funcdecl-setdeserializedsignature.swift similarity index 82% rename from validation-test/compiler_crashers/27217-swift-funcdecl-setdeserializedsignature.swift rename to validation-test/compiler_crashers_fixed/27217-swift-funcdecl-setdeserializedsignature.swift index c1c71b0f56f25..b1644b3dda15a 100644 --- a/validation-test/compiler_crashers/27217-swift-funcdecl-setdeserializedsignature.swift +++ b/validation-test/compiler_crashers_fixed/27217-swift-funcdecl-setdeserializedsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27218-swift-vardecl-getparentpattern.swift b/validation-test/compiler_crashers_fixed/27218-swift-vardecl-getparentpattern.swift similarity index 82% rename from validation-test/compiler_crashers/27218-swift-vardecl-getparentpattern.swift rename to validation-test/compiler_crashers_fixed/27218-swift-vardecl-getparentpattern.swift index 7a8c88adb88b9..4861e5cdefc1d 100644 --- a/validation-test/compiler_crashers/27218-swift-vardecl-getparentpattern.swift +++ b/validation-test/compiler_crashers_fixed/27218-swift-vardecl-getparentpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27219-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27219-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27219-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27219-swift-printingdiagnosticconsumer-handlediagnostic.swift index e3afaf15fa799..283cbd6c19c17 100644 --- a/validation-test/compiler_crashers/27219-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27219-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27220-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/27220-swift-constraints-constraintsystem-matchtypes.swift similarity index 81% rename from validation-test/compiler_crashers/27220-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/27220-swift-constraints-constraintsystem-matchtypes.swift index d0c3adccb447b..32f1f37b89bd3 100644 --- a/validation-test/compiler_crashers/27220-swift-constraints-constraintsystem-matchtypes.swift +++ b/validation-test/compiler_crashers_fixed/27220-swift-constraints-constraintsystem-matchtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27221-swift-typechecker-lookupunqualified.swift b/validation-test/compiler_crashers_fixed/27221-swift-typechecker-lookupunqualified.swift similarity index 80% rename from validation-test/compiler_crashers/27221-swift-typechecker-lookupunqualified.swift rename to validation-test/compiler_crashers_fixed/27221-swift-typechecker-lookupunqualified.swift index d4a551bc7168c..3f61db56d3512 100644 --- a/validation-test/compiler_crashers/27221-swift-typechecker-lookupunqualified.swift +++ b/validation-test/compiler_crashers_fixed/27221-swift-typechecker-lookupunqualified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27222-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/27222-swift-typebase-getanyoptionalobjecttype.swift similarity index 79% rename from validation-test/compiler_crashers/27222-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/27222-swift-typebase-getanyoptionalobjecttype.swift index 884e5cb36c8e7..6ab67e1d65b12 100644 --- a/validation-test/compiler_crashers/27222-swift-typebase-getanyoptionalobjecttype.swift +++ b/validation-test/compiler_crashers_fixed/27222-swift-typebase-getanyoptionalobjecttype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27223-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/27223-swift-typechecker-checkinheritanceclause.swift similarity index 81% rename from validation-test/compiler_crashers/27223-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/27223-swift-typechecker-checkinheritanceclause.swift index eea643bbd24bc..9bb0c5584d483 100644 --- a/validation-test/compiler_crashers/27223-swift-typechecker-checkinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/27223-swift-typechecker-checkinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27224-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/27224-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 80% rename from validation-test/compiler_crashers/27224-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/27224-swift-constraints-constraintgraph-gatherconstraints.swift index 2045fcf09f812..5d4ce62815feb 100644 --- a/validation-test/compiler_crashers/27224-swift-constraints-constraintgraph-gatherconstraints.swift +++ b/validation-test/compiler_crashers_fixed/27224-swift-constraints-constraintgraph-gatherconstraints.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27226-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/27226-swift-lexer-leximpl.swift similarity index 79% rename from validation-test/compiler_crashers/27226-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/27226-swift-lexer-leximpl.swift index 0122f8ee38a84..de75782660f2c 100644 --- a/validation-test/compiler_crashers/27226-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/27226-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27227-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift b/validation-test/compiler_crashers_fixed/27227-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift similarity index 79% rename from validation-test/compiler_crashers/27227-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift rename to validation-test/compiler_crashers_fixed/27227-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift index 4e1399982842b..9b25034b88270 100644 --- a/validation-test/compiler_crashers/27227-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift +++ b/validation-test/compiler_crashers_fixed/27227-swift-constraints-constraintsystem-lookthroughimplicitlyunwrappedoptionaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27228-swift-conformancelookuptable-addprotocol.swift b/validation-test/compiler_crashers_fixed/27228-swift-conformancelookuptable-addprotocol.swift similarity index 81% rename from validation-test/compiler_crashers/27228-swift-conformancelookuptable-addprotocol.swift rename to validation-test/compiler_crashers_fixed/27228-swift-conformancelookuptable-addprotocol.swift index b3ee165325e5c..df45d55eb6909 100644 --- a/validation-test/compiler_crashers/27228-swift-conformancelookuptable-addprotocol.swift +++ b/validation-test/compiler_crashers_fixed/27228-swift-conformancelookuptable-addprotocol.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27230-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/27230-swift-declcontext-lookupqualified.swift similarity index 82% rename from validation-test/compiler_crashers/27230-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/27230-swift-declcontext-lookupqualified.swift index 90b83e26e3c74..d9d529ec50bc7 100644 --- a/validation-test/compiler_crashers/27230-swift-declcontext-lookupqualified.swift +++ b/validation-test/compiler_crashers_fixed/27230-swift-declcontext-lookupqualified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27231-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/27231-std-function-func-swift-constraints-constraintsystem-simplifytype.swift similarity index 81% rename from validation-test/compiler_crashers/27231-std-function-func-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/27231-std-function-func-swift-constraints-constraintsystem-simplifytype.swift index 536fedc941c40..cef7d399e5fdd 100644 --- a/validation-test/compiler_crashers/27231-std-function-func-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/27231-std-function-func-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27232-swift-funcdecl-isunaryoperator.swift b/validation-test/compiler_crashers_fixed/27232-swift-funcdecl-isunaryoperator.swift similarity index 82% rename from validation-test/compiler_crashers/27232-swift-funcdecl-isunaryoperator.swift rename to validation-test/compiler_crashers_fixed/27232-swift-funcdecl-isunaryoperator.swift index fcc564003686f..2dee3e548d5b8 100644 --- a/validation-test/compiler_crashers/27232-swift-funcdecl-isunaryoperator.swift +++ b/validation-test/compiler_crashers_fixed/27232-swift-funcdecl-isunaryoperator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27233-swift-modulefile-loadextensions.swift b/validation-test/compiler_crashers_fixed/27233-swift-modulefile-loadextensions.swift similarity index 80% rename from validation-test/compiler_crashers/27233-swift-modulefile-loadextensions.swift rename to validation-test/compiler_crashers_fixed/27233-swift-modulefile-loadextensions.swift index cb0ba7745359f..6e54ed2973862 100644 --- a/validation-test/compiler_crashers/27233-swift-modulefile-loadextensions.swift +++ b/validation-test/compiler_crashers_fixed/27233-swift-modulefile-loadextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27235-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/27235-swift-lexer-getlocforendoftoken.swift similarity index 83% rename from validation-test/compiler_crashers/27235-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/27235-swift-lexer-getlocforendoftoken.swift index f7ddae042b931..24edf832f7f27 100644 --- a/validation-test/compiler_crashers/27235-swift-lexer-getlocforendoftoken.swift +++ b/validation-test/compiler_crashers_fixed/27235-swift-lexer-getlocforendoftoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27237-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/27237-swift-metatypetype-get.swift similarity index 80% rename from validation-test/compiler_crashers/27237-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27237-swift-metatypetype-get.swift index d88e513345cf8..c161ef75b0e15 100644 --- a/validation-test/compiler_crashers/27237-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27237-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27238-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27238-swift-typechecker-validatedecl.swift similarity index 80% rename from validation-test/compiler_crashers/27238-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27238-swift-typechecker-validatedecl.swift index 9332831418cbd..fff73728b3106 100644 --- a/validation-test/compiler_crashers/27238-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27238-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27239-swift-typechecker-definedefaultconstructor.swift b/validation-test/compiler_crashers_fixed/27239-swift-typechecker-definedefaultconstructor.swift similarity index 80% rename from validation-test/compiler_crashers/27239-swift-typechecker-definedefaultconstructor.swift rename to validation-test/compiler_crashers_fixed/27239-swift-typechecker-definedefaultconstructor.swift index a70b560de9eea..29a8e1061d3bc 100644 --- a/validation-test/compiler_crashers/27239-swift-typechecker-definedefaultconstructor.swift +++ b/validation-test/compiler_crashers_fixed/27239-swift-typechecker-definedefaultconstructor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27240-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/27240-no-stacktrace.swift similarity index 80% rename from validation-test/compiler_crashers/27240-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/27240-no-stacktrace.swift index 9bd02ba95b3b4..3eb28c674bd5c 100644 --- a/validation-test/compiler_crashers/27240-no-stacktrace.swift +++ b/validation-test/compiler_crashers_fixed/27240-no-stacktrace.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27241-swift-constraints-constraintsystem-recordopenedtypes.swift b/validation-test/compiler_crashers_fixed/27241-swift-constraints-constraintsystem-recordopenedtypes.swift similarity index 80% rename from validation-test/compiler_crashers/27241-swift-constraints-constraintsystem-recordopenedtypes.swift rename to validation-test/compiler_crashers_fixed/27241-swift-constraints-constraintsystem-recordopenedtypes.swift index 77d35a71f424e..22ce46ad4d7fd 100644 --- a/validation-test/compiler_crashers/27241-swift-constraints-constraintsystem-recordopenedtypes.swift +++ b/validation-test/compiler_crashers_fixed/27241-swift-constraints-constraintsystem-recordopenedtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27242-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/27242-swift-genericparamlist-addnestedarchetypes.swift similarity index 83% rename from validation-test/compiler_crashers/27242-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/27242-swift-genericparamlist-addnestedarchetypes.swift index 68076cfab4bc2..c048ff6adfaa8 100644 --- a/validation-test/compiler_crashers/27242-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27242-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27243-swift-typebase-gettypevariables.swift b/validation-test/compiler_crashers_fixed/27243-swift-typebase-gettypevariables.swift similarity index 78% rename from validation-test/compiler_crashers/27243-swift-typebase-gettypevariables.swift rename to validation-test/compiler_crashers_fixed/27243-swift-typebase-gettypevariables.swift index cd0fb285ee996..14b10ad7490b9 100644 --- a/validation-test/compiler_crashers/27243-swift-typebase-gettypevariables.swift +++ b/validation-test/compiler_crashers_fixed/27243-swift-typebase-gettypevariables.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27244-swift-lexer-lexoperatoridentifier.swift b/validation-test/compiler_crashers_fixed/27244-swift-lexer-lexoperatoridentifier.swift similarity index 78% rename from validation-test/compiler_crashers/27244-swift-lexer-lexoperatoridentifier.swift rename to validation-test/compiler_crashers_fixed/27244-swift-lexer-lexoperatoridentifier.swift index 2d15b2df04f72..008679b87d943 100644 --- a/validation-test/compiler_crashers/27244-swift-lexer-lexoperatoridentifier.swift +++ b/validation-test/compiler_crashers_fixed/27244-swift-lexer-lexoperatoridentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27245-swift-archetypebuilder-addconformancerequirement.swift b/validation-test/compiler_crashers_fixed/27245-swift-archetypebuilder-addconformancerequirement.swift similarity index 81% rename from validation-test/compiler_crashers/27245-swift-archetypebuilder-addconformancerequirement.swift rename to validation-test/compiler_crashers_fixed/27245-swift-archetypebuilder-addconformancerequirement.swift index 11cda612eb42f..b891935a83b20 100644 --- a/validation-test/compiler_crashers/27245-swift-archetypebuilder-addconformancerequirement.swift +++ b/validation-test/compiler_crashers_fixed/27245-swift-archetypebuilder-addconformancerequirement.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27246-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/27246-swift-genericsignature-get.swift similarity index 81% rename from validation-test/compiler_crashers/27246-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/27246-swift-genericsignature-get.swift index a74e534762dd8..b183f3bdc4db3 100644 --- a/validation-test/compiler_crashers/27246-swift-genericsignature-get.swift +++ b/validation-test/compiler_crashers_fixed/27246-swift-genericsignature-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27248-swift-conformancelookuptable-lookupconformance.swift b/validation-test/compiler_crashers_fixed/27248-swift-conformancelookuptable-lookupconformance.swift similarity index 83% rename from validation-test/compiler_crashers/27248-swift-conformancelookuptable-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/27248-swift-conformancelookuptable-lookupconformance.swift index 64c33626c2b76..6ff6517d79f73 100644 --- a/validation-test/compiler_crashers/27248-swift-conformancelookuptable-lookupconformance.swift +++ b/validation-test/compiler_crashers_fixed/27248-swift-conformancelookuptable-lookupconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27249-std-function-func.swift b/validation-test/compiler_crashers_fixed/27249-std-function-func.swift similarity index 80% rename from validation-test/compiler_crashers/27249-std-function-func.swift rename to validation-test/compiler_crashers_fixed/27249-std-function-func.swift index ab855e9b7401a..164f5f72f5a50 100644 --- a/validation-test/compiler_crashers/27249-std-function-func.swift +++ b/validation-test/compiler_crashers_fixed/27249-std-function-func.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27250-swift-nominaltype-get.swift b/validation-test/compiler_crashers_fixed/27250-swift-nominaltype-get.swift similarity index 83% rename from validation-test/compiler_crashers/27250-swift-nominaltype-get.swift rename to validation-test/compiler_crashers_fixed/27250-swift-nominaltype-get.swift index 7df3decd05dc8..268761d7898a9 100644 --- a/validation-test/compiler_crashers/27250-swift-nominaltype-get.swift +++ b/validation-test/compiler_crashers_fixed/27250-swift-nominaltype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27251-swift-nominaltype-get.swift b/validation-test/compiler_crashers_fixed/27251-swift-nominaltype-get.swift similarity index 83% rename from validation-test/compiler_crashers/27251-swift-nominaltype-get.swift rename to validation-test/compiler_crashers_fixed/27251-swift-nominaltype-get.swift index f00f744af8d84..1043f4647a712 100644 --- a/validation-test/compiler_crashers/27251-swift-nominaltype-get.swift +++ b/validation-test/compiler_crashers_fixed/27251-swift-nominaltype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27252-swift-moduledecl-lookupconformance.swift b/validation-test/compiler_crashers_fixed/27252-swift-moduledecl-lookupconformance.swift similarity index 83% rename from validation-test/compiler_crashers/27252-swift-moduledecl-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/27252-swift-moduledecl-lookupconformance.swift index fae5ad9e8e17b..44e9657765643 100644 --- a/validation-test/compiler_crashers/27252-swift-moduledecl-lookupconformance.swift +++ b/validation-test/compiler_crashers_fixed/27252-swift-moduledecl-lookupconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27253-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/27253-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 81% rename from validation-test/compiler_crashers/27253-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/27253-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift index d12f6bcd4d709..72556ae1b42fe 100644 --- a/validation-test/compiler_crashers/27253-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift +++ b/validation-test/compiler_crashers_fixed/27253-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27254-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/27254-swift-functiontype-get.swift similarity index 79% rename from validation-test/compiler_crashers/27254-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/27254-swift-functiontype-get.swift index 9eab424344a46..4fd5bcbba10fc 100644 --- a/validation-test/compiler_crashers/27254-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27254-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27256-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/27256-swift-constraints-constraintlocator-profile.swift similarity index 81% rename from validation-test/compiler_crashers/27256-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/27256-swift-constraints-constraintlocator-profile.swift index f4da6fe77d676..c43f59b8e4bdc 100644 --- a/validation-test/compiler_crashers/27256-swift-constraints-constraintlocator-profile.swift +++ b/validation-test/compiler_crashers_fixed/27256-swift-constraints-constraintlocator-profile.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27257-swift-lexer-kindofidentifier.swift b/validation-test/compiler_crashers_fixed/27257-swift-lexer-kindofidentifier.swift similarity index 86% rename from validation-test/compiler_crashers/27257-swift-lexer-kindofidentifier.swift rename to validation-test/compiler_crashers_fixed/27257-swift-lexer-kindofidentifier.swift index 30407bdb43d1c..21d71e44998c3 100644 --- a/validation-test/compiler_crashers/27257-swift-lexer-kindofidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27257-swift-lexer-kindofidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27258-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/27258-swift-abstractclosureexpr-setparams.swift similarity index 82% rename from validation-test/compiler_crashers/27258-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/27258-swift-abstractclosureexpr-setparams.swift index d8ef71d052db0..1e3a9657a597f 100644 --- a/validation-test/compiler_crashers/27258-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/27258-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27259-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27259-std-function-func-swift-type-subst.swift similarity index 82% rename from validation-test/compiler_crashers/27259-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27259-std-function-func-swift-type-subst.swift index b022e50f9c184..11f416acf5b32 100644 --- a/validation-test/compiler_crashers/27259-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27259-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27260-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/27260-swift-constraints-constraintlocator-profile.swift similarity index 83% rename from validation-test/compiler_crashers/27260-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/27260-swift-constraints-constraintlocator-profile.swift index efc691a43d1ce..55b49d12119b9 100644 --- a/validation-test/compiler_crashers/27260-swift-constraints-constraintlocator-profile.swift +++ b/validation-test/compiler_crashers_fixed/27260-swift-constraints-constraintlocator-profile.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27261-swift-modulefile-getcommentfordecl.swift b/validation-test/compiler_crashers_fixed/27261-swift-modulefile-getcommentfordecl.swift similarity index 82% rename from validation-test/compiler_crashers/27261-swift-modulefile-getcommentfordecl.swift rename to validation-test/compiler_crashers_fixed/27261-swift-modulefile-getcommentfordecl.swift index b3037fc61272c..0920d0a4073b2 100644 --- a/validation-test/compiler_crashers/27261-swift-modulefile-getcommentfordecl.swift +++ b/validation-test/compiler_crashers_fixed/27261-swift-modulefile-getcommentfordecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27262-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/27262-swift-modulefile-getdecl.swift similarity index 81% rename from validation-test/compiler_crashers/27262-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/27262-swift-modulefile-getdecl.swift index 623d523042d83..1272058fe891c 100644 --- a/validation-test/compiler_crashers/27262-swift-modulefile-getdecl.swift +++ b/validation-test/compiler_crashers_fixed/27262-swift-modulefile-getdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27263-swift-constraints-constraintgraphscope-constraintgraphscope.swift b/validation-test/compiler_crashers_fixed/27263-swift-constraints-constraintgraphscope-constraintgraphscope.swift similarity index 81% rename from validation-test/compiler_crashers/27263-swift-constraints-constraintgraphscope-constraintgraphscope.swift rename to validation-test/compiler_crashers_fixed/27263-swift-constraints-constraintgraphscope-constraintgraphscope.swift index bf8c0c4262c25..3c3cf95d02047 100644 --- a/validation-test/compiler_crashers/27263-swift-constraints-constraintgraphscope-constraintgraphscope.swift +++ b/validation-test/compiler_crashers_fixed/27263-swift-constraints-constraintgraphscope-constraintgraphscope.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27265-resolveidenttypecomponent.swift b/validation-test/compiler_crashers_fixed/27265-resolveidenttypecomponent.swift similarity index 80% rename from validation-test/compiler_crashers/27265-resolveidenttypecomponent.swift rename to validation-test/compiler_crashers_fixed/27265-resolveidenttypecomponent.swift index 6a5bc89932d28..5d5fe71e6d9fb 100644 --- a/validation-test/compiler_crashers/27265-resolveidenttypecomponent.swift +++ b/validation-test/compiler_crashers_fixed/27265-resolveidenttypecomponent.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27266-swift-constraints-constraintsystem-solverec.swift b/validation-test/compiler_crashers_fixed/27266-swift-constraints-constraintsystem-solverec.swift similarity index 81% rename from validation-test/compiler_crashers/27266-swift-constraints-constraintsystem-solverec.swift rename to validation-test/compiler_crashers_fixed/27266-swift-constraints-constraintsystem-solverec.swift index 34286e61aab7b..cfe9eff1e424e 100644 --- a/validation-test/compiler_crashers/27266-swift-constraints-constraintsystem-solverec.swift +++ b/validation-test/compiler_crashers_fixed/27266-swift-constraints-constraintsystem-solverec.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27267-swift-genericparamlist-create.swift b/validation-test/compiler_crashers_fixed/27267-swift-genericparamlist-create.swift similarity index 81% rename from validation-test/compiler_crashers/27267-swift-genericparamlist-create.swift rename to validation-test/compiler_crashers_fixed/27267-swift-genericparamlist-create.swift index d3be97d5cbd9c..cee72036b5502 100644 --- a/validation-test/compiler_crashers/27267-swift-genericparamlist-create.swift +++ b/validation-test/compiler_crashers_fixed/27267-swift-genericparamlist-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27268-swift-astcontext-getsubstitutions.swift b/validation-test/compiler_crashers_fixed/27268-swift-astcontext-getsubstitutions.swift similarity index 81% rename from validation-test/compiler_crashers/27268-swift-astcontext-getsubstitutions.swift rename to validation-test/compiler_crashers_fixed/27268-swift-astcontext-getsubstitutions.swift index 93c3a41f8e241..dd0f49190d8f6 100644 --- a/validation-test/compiler_crashers/27268-swift-astcontext-getsubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/27268-swift-astcontext-getsubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27271-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27271-swift-typechecker-validatedecl.swift similarity index 97% rename from validation-test/compiler_crashers/27271-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27271-swift-typechecker-validatedecl.swift index 03bb05271f932..458fc195a1aee 100644 --- a/validation-test/compiler_crashers/27271-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27271-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27272-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/27272-swift-constraints-constraintgraph-addconstraint.swift similarity index 81% rename from validation-test/compiler_crashers/27272-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/27272-swift-constraints-constraintgraph-addconstraint.swift index 6620f857800d5..c658a2c7cecd0 100644 --- a/validation-test/compiler_crashers/27272-swift-constraints-constraintgraph-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27272-swift-constraints-constraintgraph-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27273-swift-constraints-constraintsystem-solvesimplified.swift b/validation-test/compiler_crashers_fixed/27273-swift-constraints-constraintsystem-solvesimplified.swift similarity index 79% rename from validation-test/compiler_crashers/27273-swift-constraints-constraintsystem-solvesimplified.swift rename to validation-test/compiler_crashers_fixed/27273-swift-constraints-constraintsystem-solvesimplified.swift index 9dc9329acdef8..279e767602cf2 100644 --- a/validation-test/compiler_crashers/27273-swift-constraints-constraintsystem-solvesimplified.swift +++ b/validation-test/compiler_crashers_fixed/27273-swift-constraints-constraintsystem-solvesimplified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27274-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/27274-swift-functiontype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27274-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/27274-swift-functiontype-get.swift index ac83361cbb047..ffb1be605da5d 100644 --- a/validation-test/compiler_crashers/27274-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27274-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27275-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/27275-swift-genericfunctiontype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27275-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/27275-swift-genericfunctiontype-get.swift index b2a51c3f256fb..35006a0d7f11d 100644 --- a/validation-test/compiler_crashers/27275-swift-genericfunctiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27275-swift-genericfunctiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27276-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift b/validation-test/compiler_crashers_fixed/27276-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift similarity index 82% rename from validation-test/compiler_crashers/27276-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift rename to validation-test/compiler_crashers_fixed/27276-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift index 6f5724cd1d2aa..2379c2c0dc71d 100644 --- a/validation-test/compiler_crashers/27276-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27276-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27277-swift-stmt-walk.swift b/validation-test/compiler_crashers_fixed/27277-swift-stmt-walk.swift similarity index 83% rename from validation-test/compiler_crashers/27277-swift-stmt-walk.swift rename to validation-test/compiler_crashers_fixed/27277-swift-stmt-walk.swift index 0b38bed1e34b6..2545fdf13a635 100644 --- a/validation-test/compiler_crashers/27277-swift-stmt-walk.swift +++ b/validation-test/compiler_crashers_fixed/27277-swift-stmt-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27278-swift-constraints-constraintgraph-computeconnectedcomponents.swift b/validation-test/compiler_crashers_fixed/27278-swift-constraints-constraintgraph-computeconnectedcomponents.swift similarity index 83% rename from validation-test/compiler_crashers/27278-swift-constraints-constraintgraph-computeconnectedcomponents.swift rename to validation-test/compiler_crashers_fixed/27278-swift-constraints-constraintgraph-computeconnectedcomponents.swift index a113fe2d3bae2..14a6ba0817b83 100644 --- a/validation-test/compiler_crashers/27278-swift-constraints-constraintgraph-computeconnectedcomponents.swift +++ b/validation-test/compiler_crashers_fixed/27278-swift-constraints-constraintgraph-computeconnectedcomponents.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27279-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27279-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 80% rename from validation-test/compiler_crashers/27279-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27279-swift-printingdiagnosticconsumer-handlediagnostic.swift index 2acbbd2a1821c..e986b7252ba0d 100644 --- a/validation-test/compiler_crashers/27279-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27279-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27280-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27280-swift-type-transform.swift similarity index 81% rename from validation-test/compiler_crashers/27280-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27280-swift-type-transform.swift index 72fb8d07abba5..0fba90f1dd803 100644 --- a/validation-test/compiler_crashers/27280-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27280-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27281-swift-constraints-simplifylocator.swift b/validation-test/compiler_crashers_fixed/27281-swift-constraints-simplifylocator.swift similarity index 81% rename from validation-test/compiler_crashers/27281-swift-constraints-simplifylocator.swift rename to validation-test/compiler_crashers_fixed/27281-swift-constraints-simplifylocator.swift index e0511d8ad7b9a..9e841a517df77 100644 --- a/validation-test/compiler_crashers/27281-swift-constraints-simplifylocator.swift +++ b/validation-test/compiler_crashers_fixed/27281-swift-constraints-simplifylocator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27282-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/27282-swift-boundgenerictype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27282-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/27282-swift-boundgenerictype-get.swift index faa7786fa6e36..952c8f1a3bfe5 100644 --- a/validation-test/compiler_crashers/27282-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/27282-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27283-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27283-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/27283-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27283-swift-printingdiagnosticconsumer-handlediagnostic.swift index 07bea3bb8fd9f..f72589f6c0c0b 100644 --- a/validation-test/compiler_crashers/27283-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27283-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27285-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/27285-swift-typechecker-resolvetypeincontext.swift similarity index 82% rename from validation-test/compiler_crashers/27285-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/27285-swift-typechecker-resolvetypeincontext.swift index fab04842150f6..03583dc97e33d 100644 --- a/validation-test/compiler_crashers/27285-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/27285-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27287-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27287-swift-inflightdiagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27287-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27287-swift-inflightdiagnostic.swift index 6e2bc061ba7a5..2386a58660096 100644 --- a/validation-test/compiler_crashers/27287-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27287-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27288-swift-typechecker-getinterfacetypefrominternaltype.swift b/validation-test/compiler_crashers_fixed/27288-swift-typechecker-getinterfacetypefrominternaltype.swift similarity index 81% rename from validation-test/compiler_crashers/27288-swift-typechecker-getinterfacetypefrominternaltype.swift rename to validation-test/compiler_crashers_fixed/27288-swift-typechecker-getinterfacetypefrominternaltype.swift index 59fb29384dcef..1119563eb3ccc 100644 --- a/validation-test/compiler_crashers/27288-swift-typechecker-getinterfacetypefrominternaltype.swift +++ b/validation-test/compiler_crashers_fixed/27288-swift-typechecker-getinterfacetypefrominternaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27289-swift-unqualifiedlookup-unqualifiedlookup.swift b/validation-test/compiler_crashers_fixed/27289-swift-unqualifiedlookup-unqualifiedlookup.swift similarity index 80% rename from validation-test/compiler_crashers/27289-swift-unqualifiedlookup-unqualifiedlookup.swift rename to validation-test/compiler_crashers_fixed/27289-swift-unqualifiedlookup-unqualifiedlookup.swift index 500cd552f79aa..5d20cf89257e9 100644 --- a/validation-test/compiler_crashers/27289-swift-unqualifiedlookup-unqualifiedlookup.swift +++ b/validation-test/compiler_crashers_fixed/27289-swift-unqualifiedlookup-unqualifiedlookup.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27290-vtable.swift b/validation-test/compiler_crashers_fixed/27290-vtable.swift similarity index 84% rename from validation-test/compiler_crashers/27290-vtable.swift rename to validation-test/compiler_crashers_fixed/27290-vtable.swift index 71aa7afa5b9fa..b19d9ecfaab80 100644 --- a/validation-test/compiler_crashers/27290-vtable.swift +++ b/validation-test/compiler_crashers_fixed/27290-vtable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27291-swift-modulefile-getdeclcontext.swift b/validation-test/compiler_crashers_fixed/27291-swift-modulefile-getdeclcontext.swift similarity index 86% rename from validation-test/compiler_crashers/27291-swift-modulefile-getdeclcontext.swift rename to validation-test/compiler_crashers_fixed/27291-swift-modulefile-getdeclcontext.swift index 54c5e192e9cf9..7a9fea12e2e5d 100644 --- a/validation-test/compiler_crashers/27291-swift-modulefile-getdeclcontext.swift +++ b/validation-test/compiler_crashers_fixed/27291-swift-modulefile-getdeclcontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27292-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/27292-swift-abstractclosureexpr-setparams.swift similarity index 84% rename from validation-test/compiler_crashers/27292-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/27292-swift-abstractclosureexpr-setparams.swift index 81ec4df23343f..2f3646ce834dc 100644 --- a/validation-test/compiler_crashers/27292-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/27292-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27293-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/27293-swift-metatypetype-get.swift similarity index 80% rename from validation-test/compiler_crashers/27293-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27293-swift-metatypetype-get.swift index b1bce77d94f07..aa6e19a8f736e 100644 --- a/validation-test/compiler_crashers/27293-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27293-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27295-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/27295-swift-structtype-get.swift similarity index 84% rename from validation-test/compiler_crashers/27295-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/27295-swift-structtype-get.swift index 2046b8ba3259f..ca4d4060dfedf 100644 --- a/validation-test/compiler_crashers/27295-swift-structtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27295-swift-structtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27296-swift-astcontext-getstringdecl.swift b/validation-test/compiler_crashers_fixed/27296-swift-astcontext-getstringdecl.swift similarity index 81% rename from validation-test/compiler_crashers/27296-swift-astcontext-getstringdecl.swift rename to validation-test/compiler_crashers_fixed/27296-swift-astcontext-getstringdecl.swift index 593d7f268b096..705337e632f79 100644 --- a/validation-test/compiler_crashers/27296-swift-astcontext-getstringdecl.swift +++ b/validation-test/compiler_crashers_fixed/27296-swift-astcontext-getstringdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27297-llvm-bitstreamcursor-readrecord.swift b/validation-test/compiler_crashers_fixed/27297-llvm-bitstreamcursor-readrecord.swift similarity index 97% rename from validation-test/compiler_crashers/27297-llvm-bitstreamcursor-readrecord.swift rename to validation-test/compiler_crashers_fixed/27297-llvm-bitstreamcursor-readrecord.swift index d002790584a33..8785fd1ea9ee3 100644 --- a/validation-test/compiler_crashers/27297-llvm-bitstreamcursor-readrecord.swift +++ b/validation-test/compiler_crashers_fixed/27297-llvm-bitstreamcursor-readrecord.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27298-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27298-swift-modulefile-gettype.swift similarity index 97% rename from validation-test/compiler_crashers/27298-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27298-swift-modulefile-gettype.swift index 6edede4dde96a..412354d9eda0e 100644 --- a/validation-test/compiler_crashers/27298-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27298-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27299-swift-enumtype-get.swift b/validation-test/compiler_crashers_fixed/27299-swift-enumtype-get.swift similarity index 79% rename from validation-test/compiler_crashers/27299-swift-enumtype-get.swift rename to validation-test/compiler_crashers_fixed/27299-swift-enumtype-get.swift index f5568d1ee9fea..b568aa3c6a54f 100644 --- a/validation-test/compiler_crashers/27299-swift-enumtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27299-swift-enumtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27301-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/27301-swift-type-walk.swift similarity index 80% rename from validation-test/compiler_crashers/27301-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/27301-swift-type-walk.swift index f529f486d9772..2c7ed11c73327 100644 --- a/validation-test/compiler_crashers/27301-swift-type-walk.swift +++ b/validation-test/compiler_crashers_fixed/27301-swift-type-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27302-swift-conformancelookuptable-conformancelookuptable.swift b/validation-test/compiler_crashers_fixed/27302-swift-conformancelookuptable-conformancelookuptable.swift similarity index 82% rename from validation-test/compiler_crashers/27302-swift-conformancelookuptable-conformancelookuptable.swift rename to validation-test/compiler_crashers_fixed/27302-swift-conformancelookuptable-conformancelookuptable.swift index ba379728f3b07..da0ced51186d6 100644 --- a/validation-test/compiler_crashers/27302-swift-conformancelookuptable-conformancelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27302-swift-conformancelookuptable-conformancelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27303-swift-typechecker-substituteinputsugartypeforresult.swift b/validation-test/compiler_crashers_fixed/27303-swift-typechecker-substituteinputsugartypeforresult.swift similarity index 81% rename from validation-test/compiler_crashers/27303-swift-typechecker-substituteinputsugartypeforresult.swift rename to validation-test/compiler_crashers_fixed/27303-swift-typechecker-substituteinputsugartypeforresult.swift index 8ba7e1a934bd8..5dfb4ddbfcd38 100644 --- a/validation-test/compiler_crashers/27303-swift-typechecker-substituteinputsugartypeforresult.swift +++ b/validation-test/compiler_crashers_fixed/27303-swift-typechecker-substituteinputsugartypeforresult.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27304-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/27304-swift-patternbindingdecl-setpattern.swift similarity index 85% rename from validation-test/compiler_crashers/27304-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/27304-swift-patternbindingdecl-setpattern.swift index 60e9a1bd87bd2..1b9b9e84612c8 100644 --- a/validation-test/compiler_crashers/27304-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/27304-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27305-swift-markasobjc.swift b/validation-test/compiler_crashers_fixed/27305-swift-markasobjc.swift similarity index 81% rename from validation-test/compiler_crashers/27305-swift-markasobjc.swift rename to validation-test/compiler_crashers_fixed/27305-swift-markasobjc.swift index a0348bccb5e27..238c1cbed668f 100644 --- a/validation-test/compiler_crashers/27305-swift-markasobjc.swift +++ b/validation-test/compiler_crashers_fixed/27305-swift-markasobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27306-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27306-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/27306-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27306-swift-printingdiagnosticconsumer-handlediagnostic.swift index ec1acb7ae3129..99f54b3c144b6 100644 --- a/validation-test/compiler_crashers/27306-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27306-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27308-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27308-swift-inflightdiagnostic.swift similarity index 80% rename from validation-test/compiler_crashers/27308-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27308-swift-inflightdiagnostic.swift index 0ab8e90a6b5e7..e2798aea1a965 100644 --- a/validation-test/compiler_crashers/27308-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27308-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27309-swift-constraints-constraintgraph-computeconnectedcomponents.swift b/validation-test/compiler_crashers_fixed/27309-swift-constraints-constraintgraph-computeconnectedcomponents.swift similarity index 83% rename from validation-test/compiler_crashers/27309-swift-constraints-constraintgraph-computeconnectedcomponents.swift rename to validation-test/compiler_crashers_fixed/27309-swift-constraints-constraintgraph-computeconnectedcomponents.swift index f8b4e1276d401..fee3b150e27d0 100644 --- a/validation-test/compiler_crashers/27309-swift-constraints-constraintgraph-computeconnectedcomponents.swift +++ b/validation-test/compiler_crashers_fixed/27309-swift-constraints-constraintgraph-computeconnectedcomponents.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27310-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27310-swift-modulefile-gettype.swift similarity index 82% rename from validation-test/compiler_crashers/27310-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27310-swift-modulefile-gettype.swift index 90a575059a30a..f416507aa8ff3 100644 --- a/validation-test/compiler_crashers/27310-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27310-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27311-swift-typechecker-typecheckexpression.swift b/validation-test/compiler_crashers_fixed/27311-swift-typechecker-typecheckexpression.swift similarity index 82% rename from validation-test/compiler_crashers/27311-swift-typechecker-typecheckexpression.swift rename to validation-test/compiler_crashers_fixed/27311-swift-typechecker-typecheckexpression.swift index be28aa2386784..fe0f5c7fab11b 100644 --- a/validation-test/compiler_crashers/27311-swift-typechecker-typecheckexpression.swift +++ b/validation-test/compiler_crashers_fixed/27311-swift-typechecker-typecheckexpression.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27312-swift-substitutedtype-get.swift b/validation-test/compiler_crashers_fixed/27312-swift-substitutedtype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27312-swift-substitutedtype-get.swift rename to validation-test/compiler_crashers_fixed/27312-swift-substitutedtype-get.swift index de5a9a13fcfd1..7e7c6890d88d2 100644 --- a/validation-test/compiler_crashers/27312-swift-substitutedtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27312-swift-substitutedtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27313-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/27313-swift-genericfunctiontype-get.swift similarity index 83% rename from validation-test/compiler_crashers/27313-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/27313-swift-genericfunctiontype-get.swift index 94dc1d5b882af..56c63f7021008 100644 --- a/validation-test/compiler_crashers/27313-swift-genericfunctiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27313-swift-genericfunctiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27315-swift-tupletype-get.swift b/validation-test/compiler_crashers_fixed/27315-swift-tupletype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27315-swift-tupletype-get.swift rename to validation-test/compiler_crashers_fixed/27315-swift-tupletype-get.swift index 5ea01ec424068..670f65b5be0ed 100644 --- a/validation-test/compiler_crashers/27315-swift-tupletype-get.swift +++ b/validation-test/compiler_crashers_fixed/27315-swift-tupletype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27316-swift-constraints-constraintsystem-solverscope-solverscope.swift b/validation-test/compiler_crashers_fixed/27316-swift-constraints-constraintsystem-solverscope-solverscope.swift similarity index 81% rename from validation-test/compiler_crashers/27316-swift-constraints-constraintsystem-solverscope-solverscope.swift rename to validation-test/compiler_crashers_fixed/27316-swift-constraints-constraintsystem-solverscope-solverscope.swift index 070894d5a5860..b818d6629d0c8 100644 --- a/validation-test/compiler_crashers/27316-swift-constraints-constraintsystem-solverscope-solverscope.swift +++ b/validation-test/compiler_crashers_fixed/27316-swift-constraints-constraintsystem-solverscope-solverscope.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27317-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/27317-swift-genericparamlist-addnestedarchetypes.swift similarity index 84% rename from validation-test/compiler_crashers/27317-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/27317-swift-genericparamlist-addnestedarchetypes.swift index 263a6b413df4d..36ba742d218ba 100644 --- a/validation-test/compiler_crashers/27317-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27317-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27318-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/27318-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 83% rename from validation-test/compiler_crashers/27318-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/27318-swift-nominaltypedecl-getdeclaredtypeincontext.swift index 6f9b8157e34a5..297af3afc31db 100644 --- a/validation-test/compiler_crashers/27318-swift-nominaltypedecl-getdeclaredtypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/27318-swift-nominaltypedecl-getdeclaredtypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27319-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27319-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 80% rename from validation-test/compiler_crashers/27319-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27319-swift-printingdiagnosticconsumer-handlediagnostic.swift index a34dab55f033c..a2c67ac1ea899 100644 --- a/validation-test/compiler_crashers/27319-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27319-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27320-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/27320-swift-boundgenerictype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27320-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/27320-swift-boundgenerictype-get.swift index 9e1d5f2693d78..28878d097a527 100644 --- a/validation-test/compiler_crashers/27320-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/27320-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27321-swift-createimplicitconstructor.swift b/validation-test/compiler_crashers_fixed/27321-swift-createimplicitconstructor.swift similarity index 82% rename from validation-test/compiler_crashers/27321-swift-createimplicitconstructor.swift rename to validation-test/compiler_crashers_fixed/27321-swift-createimplicitconstructor.swift index 25d7b26136a36..4b3fd489fad4a 100644 --- a/validation-test/compiler_crashers/27321-swift-createimplicitconstructor.swift +++ b/validation-test/compiler_crashers_fixed/27321-swift-createimplicitconstructor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27322-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/27322-swift-constraints-constraintgraph-addconstraint.swift similarity index 82% rename from validation-test/compiler_crashers/27322-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/27322-swift-constraints-constraintgraph-addconstraint.swift index d84adc6eb9702..a50407a8a0adc 100644 --- a/validation-test/compiler_crashers/27322-swift-constraints-constraintgraph-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27322-swift-constraints-constraintgraph-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27323-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/27323-swift-constraints-constraintgraph-addconstraint.swift similarity index 82% rename from validation-test/compiler_crashers/27323-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/27323-swift-constraints-constraintgraph-addconstraint.swift index 99b7fef1301af..858c0e4cdbe5c 100644 --- a/validation-test/compiler_crashers/27323-swift-constraints-constraintgraph-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27323-swift-constraints-constraintgraph-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27324-swift-constraints-constraintsystem-finalize.swift b/validation-test/compiler_crashers_fixed/27324-swift-constraints-constraintsystem-finalize.swift similarity index 80% rename from validation-test/compiler_crashers/27324-swift-constraints-constraintsystem-finalize.swift rename to validation-test/compiler_crashers_fixed/27324-swift-constraints-constraintsystem-finalize.swift index 86624388fe501..cfa352fe24860 100644 --- a/validation-test/compiler_crashers/27324-swift-constraints-constraintsystem-finalize.swift +++ b/validation-test/compiler_crashers_fixed/27324-swift-constraints-constraintsystem-finalize.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27325-swift-maybeaddaccessorstovariable.swift b/validation-test/compiler_crashers_fixed/27325-swift-maybeaddaccessorstovariable.swift similarity index 80% rename from validation-test/compiler_crashers/27325-swift-maybeaddaccessorstovariable.swift rename to validation-test/compiler_crashers_fixed/27325-swift-maybeaddaccessorstovariable.swift index ba5ec8f993eb6..82fe63f999ad5 100644 --- a/validation-test/compiler_crashers/27325-swift-maybeaddaccessorstovariable.swift +++ b/validation-test/compiler_crashers_fixed/27325-swift-maybeaddaccessorstovariable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27326-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/27326-swift-conformancelookuptable-updatelookuptable.swift similarity index 79% rename from validation-test/compiler_crashers/27326-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/27326-swift-conformancelookuptable-updatelookuptable.swift index fe7d56113e527..493e458714811 100644 --- a/validation-test/compiler_crashers/27326-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27326-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27327-swift-genericparamlist-deriveallarchetypes.swift b/validation-test/compiler_crashers_fixed/27327-swift-genericparamlist-deriveallarchetypes.swift similarity index 80% rename from validation-test/compiler_crashers/27327-swift-genericparamlist-deriveallarchetypes.swift rename to validation-test/compiler_crashers_fixed/27327-swift-genericparamlist-deriveallarchetypes.swift index 4e3945192e2a3..5809e1fce4631 100644 --- a/validation-test/compiler_crashers/27327-swift-genericparamlist-deriveallarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27327-swift-genericparamlist-deriveallarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27328-swift-moduledecl-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27328-swift-moduledecl-lookupvalue.swift similarity index 85% rename from validation-test/compiler_crashers/27328-swift-moduledecl-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27328-swift-moduledecl-lookupvalue.swift index e414e3c84d270..a8c8e998c17f6 100644 --- a/validation-test/compiler_crashers/27328-swift-moduledecl-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27328-swift-moduledecl-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27329-llvm-foldingset-swift-classtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27329-llvm-foldingset-swift-classtype-nodeequals.swift similarity index 83% rename from validation-test/compiler_crashers/27329-llvm-foldingset-swift-classtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27329-llvm-foldingset-swift-classtype-nodeequals.swift index 596012d88e2f0..e7696364a9a42 100644 --- a/validation-test/compiler_crashers/27329-llvm-foldingset-swift-classtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27329-llvm-foldingset-swift-classtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27331-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/27331-swift-patternbindingdecl-setpattern.swift similarity index 88% rename from validation-test/compiler_crashers/27331-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/27331-swift-patternbindingdecl-setpattern.swift index 439bc914dc24d..0e186beae6e17 100644 --- a/validation-test/compiler_crashers/27331-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/27331-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27332-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/27332-swift-constraints-constraintsystem-simplifytype.swift similarity index 81% rename from validation-test/compiler_crashers/27332-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/27332-swift-constraints-constraintsystem-simplifytype.swift index 777d197bdbdda..0f9cad11cba31 100644 --- a/validation-test/compiler_crashers/27332-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/27332-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27333-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/27333-swift-constraints-constraintsystem-solve.swift similarity index 81% rename from validation-test/compiler_crashers/27333-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/27333-swift-constraints-constraintsystem-solve.swift index da769f010b5c7..b84e5b91504b1 100644 --- a/validation-test/compiler_crashers/27333-swift-constraints-constraintsystem-solve.swift +++ b/validation-test/compiler_crashers_fixed/27333-swift-constraints-constraintsystem-solve.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27334-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift b/validation-test/compiler_crashers_fixed/27334-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift similarity index 80% rename from validation-test/compiler_crashers/27334-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift rename to validation-test/compiler_crashers_fixed/27334-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift index e7951b56c6f86..f70f5659b4004 100644 --- a/validation-test/compiler_crashers/27334-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift +++ b/validation-test/compiler_crashers_fixed/27334-swift-archetypebuilder-potentialarchetype-getarchetypeanchor.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27335-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/27335-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 82% rename from validation-test/compiler_crashers/27335-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/27335-swift-constraints-constraintsystem-assignfixedtype.swift index 523f023a8c612..68aa98f9415b6 100644 --- a/validation-test/compiler_crashers/27335-swift-constraints-constraintsystem-assignfixedtype.swift +++ b/validation-test/compiler_crashers_fixed/27335-swift-constraints-constraintsystem-assignfixedtype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27336-swift-existentialmetatypetype-get.swift b/validation-test/compiler_crashers_fixed/27336-swift-existentialmetatypetype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27336-swift-existentialmetatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27336-swift-existentialmetatypetype-get.swift index bac7643dc53e4..6aaf1f5250001 100644 --- a/validation-test/compiler_crashers/27336-swift-existentialmetatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27336-swift-existentialmetatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27337-swift-valuedecl-overwritetype.swift b/validation-test/compiler_crashers_fixed/27337-swift-valuedecl-overwritetype.swift similarity index 86% rename from validation-test/compiler_crashers/27337-swift-valuedecl-overwritetype.swift rename to validation-test/compiler_crashers_fixed/27337-swift-valuedecl-overwritetype.swift index 85474605b49cf..2bef8c1395b17 100644 --- a/validation-test/compiler_crashers/27337-swift-valuedecl-overwritetype.swift +++ b/validation-test/compiler_crashers_fixed/27337-swift-valuedecl-overwritetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27338-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27338-swift-inflightdiagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27338-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27338-swift-inflightdiagnostic.swift index dbcb9271ac62b..5d9eb9fdce85a 100644 --- a/validation-test/compiler_crashers/27338-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27338-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27339-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27339-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 83% rename from validation-test/compiler_crashers/27339-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27339-llvm-foldingset-swift-tupletype-nodeequals.swift index 5334342ee35df..e13633d3dbfeb 100644 --- a/validation-test/compiler_crashers/27339-llvm-foldingset-swift-tupletype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27339-llvm-foldingset-swift-tupletype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27340-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/27340-swift-constraints-constraintsystem-simplifytype.swift similarity index 83% rename from validation-test/compiler_crashers/27340-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/27340-swift-constraints-constraintsystem-simplifytype.swift index fd03310082581..e46e304bbe13f 100644 --- a/validation-test/compiler_crashers/27340-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/27340-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27341-swift-conformancelookuptable-getallprotocols.swift b/validation-test/compiler_crashers_fixed/27341-swift-conformancelookuptable-getallprotocols.swift similarity index 82% rename from validation-test/compiler_crashers/27341-swift-conformancelookuptable-getallprotocols.swift rename to validation-test/compiler_crashers_fixed/27341-swift-conformancelookuptable-getallprotocols.swift index 7c4a07bd7066f..525312cb5aa0f 100644 --- a/validation-test/compiler_crashers/27341-swift-conformancelookuptable-getallprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27341-swift-conformancelookuptable-getallprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27342-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/27342-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 80% rename from validation-test/compiler_crashers/27342-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/27342-swift-constraints-constraintsystem-getfixedtyperecursive.swift index cb6a33ef068f3..9f36674ddc3ca 100644 --- a/validation-test/compiler_crashers/27342-swift-constraints-constraintsystem-getfixedtyperecursive.swift +++ b/validation-test/compiler_crashers_fixed/27342-swift-constraints-constraintsystem-getfixedtyperecursive.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27343-llvm-smallvectorimpl-swift-protocolconformance-operator.swift b/validation-test/compiler_crashers_fixed/27343-llvm-smallvectorimpl-swift-protocolconformance-operator.swift similarity index 81% rename from validation-test/compiler_crashers/27343-llvm-smallvectorimpl-swift-protocolconformance-operator.swift rename to validation-test/compiler_crashers_fixed/27343-llvm-smallvectorimpl-swift-protocolconformance-operator.swift index 5b538993fed5a..012385bcc5aed 100644 --- a/validation-test/compiler_crashers/27343-llvm-smallvectorimpl-swift-protocolconformance-operator.swift +++ b/validation-test/compiler_crashers_fixed/27343-llvm-smallvectorimpl-swift-protocolconformance-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27344-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27344-swift-inflightdiagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27344-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27344-swift-inflightdiagnostic.swift index d9ae88863b52d..d8eec88144b40 100644 --- a/validation-test/compiler_crashers/27344-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27344-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27345-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/27345-swift-modulefile-maybereadpattern.swift similarity index 81% rename from validation-test/compiler_crashers/27345-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/27345-swift-modulefile-maybereadpattern.swift index 5173e74762526..cd61f618d25dc 100644 --- a/validation-test/compiler_crashers/27345-swift-modulefile-maybereadpattern.swift +++ b/validation-test/compiler_crashers_fixed/27345-swift-modulefile-maybereadpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27346-swift-markasobjc.swift b/validation-test/compiler_crashers_fixed/27346-swift-markasobjc.swift similarity index 81% rename from validation-test/compiler_crashers/27346-swift-markasobjc.swift rename to validation-test/compiler_crashers_fixed/27346-swift-markasobjc.swift index 2720a33ce47d7..662a5746f674c 100644 --- a/validation-test/compiler_crashers/27346-swift-markasobjc.swift +++ b/validation-test/compiler_crashers_fixed/27346-swift-markasobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27347-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27347-swift-inflightdiagnostic.swift similarity index 85% rename from validation-test/compiler_crashers/27347-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27347-swift-inflightdiagnostic.swift index a705bf59d3b5d..55bbb76696a08 100644 --- a/validation-test/compiler_crashers/27347-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27347-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27348-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/27348-swift-constraints-constraintsystem-solve.swift similarity index 83% rename from validation-test/compiler_crashers/27348-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/27348-swift-constraints-constraintsystem-solve.swift index 0dcee5b0bd6ad..6491923196dd2 100644 --- a/validation-test/compiler_crashers/27348-swift-constraints-constraintsystem-solve.swift +++ b/validation-test/compiler_crashers_fixed/27348-swift-constraints-constraintsystem-solve.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27349-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/27349-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 83% rename from validation-test/compiler_crashers/27349-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/27349-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift index 820b7d31d6d20..ac684a526db7e 100644 --- a/validation-test/compiler_crashers/27349-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift +++ b/validation-test/compiler_crashers_fixed/27349-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27350-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/27350-swift-metatypetype-get.swift similarity index 84% rename from validation-test/compiler_crashers/27350-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27350-swift-metatypetype-get.swift index 1a598b3afad7d..a444a04d8e3e2 100644 --- a/validation-test/compiler_crashers/27350-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27350-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27351-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27351-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 82% rename from validation-test/compiler_crashers/27351-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27351-llvm-foldingset-swift-tupletype-nodeequals.swift index 7a9afe890fa00..7c05620e140a2 100644 --- a/validation-test/compiler_crashers/27351-llvm-foldingset-swift-tupletype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27351-llvm-foldingset-swift-tupletype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27353-void.swift b/validation-test/compiler_crashers_fixed/27353-void.swift similarity index 78% rename from validation-test/compiler_crashers/27353-void.swift rename to validation-test/compiler_crashers_fixed/27353-void.swift index 779ca99a61d6e..a271518358071 100644 --- a/validation-test/compiler_crashers/27353-void.swift +++ b/validation-test/compiler_crashers_fixed/27353-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27354-swift-typebase-getmembersubstitutions.swift b/validation-test/compiler_crashers_fixed/27354-swift-typebase-getmembersubstitutions.swift similarity index 81% rename from validation-test/compiler_crashers/27354-swift-typebase-getmembersubstitutions.swift rename to validation-test/compiler_crashers_fixed/27354-swift-typebase-getmembersubstitutions.swift index 91c4c69621147..e50373b654fd0 100644 --- a/validation-test/compiler_crashers/27354-swift-typebase-getmembersubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/27354-swift-typebase-getmembersubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27355-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/27355-swift-typebase-getcanonicaltype.swift similarity index 83% rename from validation-test/compiler_crashers/27355-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/27355-swift-typebase-getcanonicaltype.swift index af18d73fc3e63..5952f0eae706a 100644 --- a/validation-test/compiler_crashers/27355-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/27355-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27356-swift-constraints-constraintgraph-addconstraint.swift b/validation-test/compiler_crashers_fixed/27356-swift-constraints-constraintgraph-addconstraint.swift similarity index 80% rename from validation-test/compiler_crashers/27356-swift-constraints-constraintgraph-addconstraint.swift rename to validation-test/compiler_crashers_fixed/27356-swift-constraints-constraintgraph-addconstraint.swift index f34a8610961b9..cd7243fb260b1 100644 --- a/validation-test/compiler_crashers/27356-swift-constraints-constraintgraph-addconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27356-swift-constraints-constraintgraph-addconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27357-swift-constraints-constraintsystem-lookupmember.swift b/validation-test/compiler_crashers_fixed/27357-swift-constraints-constraintsystem-lookupmember.swift similarity index 80% rename from validation-test/compiler_crashers/27357-swift-constraints-constraintsystem-lookupmember.swift rename to validation-test/compiler_crashers_fixed/27357-swift-constraints-constraintsystem-lookupmember.swift index 27b690221c540..b6f5b1b3c315a 100644 --- a/validation-test/compiler_crashers/27357-swift-constraints-constraintsystem-lookupmember.swift +++ b/validation-test/compiler_crashers_fixed/27357-swift-constraints-constraintsystem-lookupmember.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27358-swift-constraints-constraintgraph-removeconstraint.swift b/validation-test/compiler_crashers_fixed/27358-swift-constraints-constraintgraph-removeconstraint.swift similarity index 81% rename from validation-test/compiler_crashers/27358-swift-constraints-constraintgraph-removeconstraint.swift rename to validation-test/compiler_crashers_fixed/27358-swift-constraints-constraintgraph-removeconstraint.swift index 7184a27484589..0cac29d12459e 100644 --- a/validation-test/compiler_crashers/27358-swift-constraints-constraintgraph-removeconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27358-swift-constraints-constraintgraph-removeconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27359-swift-valuedecl-settype.swift b/validation-test/compiler_crashers_fixed/27359-swift-valuedecl-settype.swift similarity index 82% rename from validation-test/compiler_crashers/27359-swift-valuedecl-settype.swift rename to validation-test/compiler_crashers_fixed/27359-swift-valuedecl-settype.swift index aca43136a9437..dc4b70af1ad5e 100644 --- a/validation-test/compiler_crashers/27359-swift-valuedecl-settype.swift +++ b/validation-test/compiler_crashers_fixed/27359-swift-valuedecl-settype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27360-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27360-swift-modulefile-gettype.swift similarity index 83% rename from validation-test/compiler_crashers/27360-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27360-swift-modulefile-gettype.swift index 2c9d34592275e..e35885e4486d0 100644 --- a/validation-test/compiler_crashers/27360-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27360-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27362-swift-stmt-walk.swift b/validation-test/compiler_crashers_fixed/27362-swift-stmt-walk.swift similarity index 81% rename from validation-test/compiler_crashers/27362-swift-stmt-walk.swift rename to validation-test/compiler_crashers_fixed/27362-swift-stmt-walk.swift index 8ecb08947fb9f..b3a0c48067243 100644 --- a/validation-test/compiler_crashers/27362-swift-stmt-walk.swift +++ b/validation-test/compiler_crashers_fixed/27362-swift-stmt-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27363-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27363-swift-type-transform.swift similarity index 85% rename from validation-test/compiler_crashers/27363-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27363-swift-type-transform.swift index 732289eb686db..db41174036323 100644 --- a/validation-test/compiler_crashers/27363-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27363-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27364-swift-typechecker-conformstoprotocol.swift b/validation-test/compiler_crashers_fixed/27364-swift-typechecker-conformstoprotocol.swift similarity index 81% rename from validation-test/compiler_crashers/27364-swift-typechecker-conformstoprotocol.swift rename to validation-test/compiler_crashers_fixed/27364-swift-typechecker-conformstoprotocol.swift index 6970affc80e77..805e7aee171c5 100644 --- a/validation-test/compiler_crashers/27364-swift-typechecker-conformstoprotocol.swift +++ b/validation-test/compiler_crashers_fixed/27364-swift-typechecker-conformstoprotocol.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27365-swift-modulefile-getcommentfordecl.swift b/validation-test/compiler_crashers_fixed/27365-swift-modulefile-getcommentfordecl.swift similarity index 81% rename from validation-test/compiler_crashers/27365-swift-modulefile-getcommentfordecl.swift rename to validation-test/compiler_crashers_fixed/27365-swift-modulefile-getcommentfordecl.swift index 009f80ae5ee33..5387dfc74ef50 100644 --- a/validation-test/compiler_crashers/27365-swift-modulefile-getcommentfordecl.swift +++ b/validation-test/compiler_crashers_fixed/27365-swift-modulefile-getcommentfordecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27366-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27366-swift-type-transform.swift similarity index 81% rename from validation-test/compiler_crashers/27366-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27366-swift-type-transform.swift index 2039ce582521b..c6d47210f22dc 100644 --- a/validation-test/compiler_crashers/27366-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27366-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27369-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27369-swift-type-transform.swift similarity index 92% rename from validation-test/compiler_crashers/27369-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27369-swift-type-transform.swift index d30efb6227f54..eb2705a8275d5 100644 --- a/validation-test/compiler_crashers/27369-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27369-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27370-swift-constraints-constraintsystem-getconstraintlocator.swift b/validation-test/compiler_crashers_fixed/27370-swift-constraints-constraintsystem-getconstraintlocator.swift similarity index 81% rename from validation-test/compiler_crashers/27370-swift-constraints-constraintsystem-getconstraintlocator.swift rename to validation-test/compiler_crashers_fixed/27370-swift-constraints-constraintsystem-getconstraintlocator.swift index 81125e20a121d..88930c5cb6a1c 100644 --- a/validation-test/compiler_crashers/27370-swift-constraints-constraintsystem-getconstraintlocator.swift +++ b/validation-test/compiler_crashers_fixed/27370-swift-constraints-constraintsystem-getconstraintlocator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27371-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27371-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/27371-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27371-std-function-func-swift-type-subst.swift index acde8446c9ac6..12ca88e832cd3 100644 --- a/validation-test/compiler_crashers/27371-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27371-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27372-void.swift b/validation-test/compiler_crashers_fixed/27372-void.swift similarity index 81% rename from validation-test/compiler_crashers/27372-void.swift rename to validation-test/compiler_crashers_fixed/27372-void.swift index 3a22940273dbb..83ff0d8fbd98d 100644 --- a/validation-test/compiler_crashers/27372-void.swift +++ b/validation-test/compiler_crashers_fixed/27372-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27373-swift-conformancelookuptable-lookupconformances.swift b/validation-test/compiler_crashers_fixed/27373-swift-conformancelookuptable-lookupconformances.swift similarity index 81% rename from validation-test/compiler_crashers/27373-swift-conformancelookuptable-lookupconformances.swift rename to validation-test/compiler_crashers_fixed/27373-swift-conformancelookuptable-lookupconformances.swift index 2d92a6d62d19f..521fe0d6c0b2f 100644 --- a/validation-test/compiler_crashers/27373-swift-conformancelookuptable-lookupconformances.swift +++ b/validation-test/compiler_crashers_fixed/27373-swift-conformancelookuptable-lookupconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27374-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/27374-swift-structtype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27374-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/27374-swift-structtype-get.swift index c84e6494684b1..9a4e257a87f67 100644 --- a/validation-test/compiler_crashers/27374-swift-structtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27374-swift-structtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27375-swift-unqualifiedlookup-unqualifiedlookup.swift b/validation-test/compiler_crashers_fixed/27375-swift-unqualifiedlookup-unqualifiedlookup.swift similarity index 82% rename from validation-test/compiler_crashers/27375-swift-unqualifiedlookup-unqualifiedlookup.swift rename to validation-test/compiler_crashers_fixed/27375-swift-unqualifiedlookup-unqualifiedlookup.swift index e1f49597f1c76..9e2c1bae6c888 100644 --- a/validation-test/compiler_crashers/27375-swift-unqualifiedlookup-unqualifiedlookup.swift +++ b/validation-test/compiler_crashers_fixed/27375-swift-unqualifiedlookup-unqualifiedlookup.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27376-swift-abstractstoragedecl-getobjcgetterselector.swift b/validation-test/compiler_crashers_fixed/27376-swift-abstractstoragedecl-getobjcgetterselector.swift similarity index 82% rename from validation-test/compiler_crashers/27376-swift-abstractstoragedecl-getobjcgetterselector.swift rename to validation-test/compiler_crashers_fixed/27376-swift-abstractstoragedecl-getobjcgetterselector.swift index 7c8cac18d14ce..3470318e89193 100644 --- a/validation-test/compiler_crashers/27376-swift-abstractstoragedecl-getobjcgetterselector.swift +++ b/validation-test/compiler_crashers_fixed/27376-swift-abstractstoragedecl-getobjcgetterselector.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27377-swift-typechecker-isdeclavailable.swift b/validation-test/compiler_crashers_fixed/27377-swift-typechecker-isdeclavailable.swift similarity index 82% rename from validation-test/compiler_crashers/27377-swift-typechecker-isdeclavailable.swift rename to validation-test/compiler_crashers_fixed/27377-swift-typechecker-isdeclavailable.swift index 43698388e03c2..5d2394875d85f 100644 --- a/validation-test/compiler_crashers/27377-swift-typechecker-isdeclavailable.swift +++ b/validation-test/compiler_crashers_fixed/27377-swift-typechecker-isdeclavailable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27378-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/27378-swift-modulefile-maybereadpattern.swift similarity index 80% rename from validation-test/compiler_crashers/27378-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/27378-swift-modulefile-maybereadpattern.swift index bbbe384c31b9f..6474d508f2060 100644 --- a/validation-test/compiler_crashers/27378-swift-modulefile-maybereadpattern.swift +++ b/validation-test/compiler_crashers_fixed/27378-swift-modulefile-maybereadpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27379-swift-constraints-constraintgraphnode-getadjacency.swift b/validation-test/compiler_crashers_fixed/27379-swift-constraints-constraintgraphnode-getadjacency.swift similarity index 81% rename from validation-test/compiler_crashers/27379-swift-constraints-constraintgraphnode-getadjacency.swift rename to validation-test/compiler_crashers_fixed/27379-swift-constraints-constraintgraphnode-getadjacency.swift index 3ff0a0222fe74..cf9f476542c8a 100644 --- a/validation-test/compiler_crashers/27379-swift-constraints-constraintgraphnode-getadjacency.swift +++ b/validation-test/compiler_crashers_fixed/27379-swift-constraints-constraintgraphnode-getadjacency.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27381-std-function-func-mapsignaturetype.swift b/validation-test/compiler_crashers_fixed/27381-std-function-func-mapsignaturetype.swift similarity index 81% rename from validation-test/compiler_crashers/27381-std-function-func-mapsignaturetype.swift rename to validation-test/compiler_crashers_fixed/27381-std-function-func-mapsignaturetype.swift index a7f0fda9670d3..97a2996615e8a 100644 --- a/validation-test/compiler_crashers/27381-std-function-func-mapsignaturetype.swift +++ b/validation-test/compiler_crashers_fixed/27381-std-function-func-mapsignaturetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27382-void.swift b/validation-test/compiler_crashers_fixed/27382-void.swift similarity index 81% rename from validation-test/compiler_crashers/27382-void.swift rename to validation-test/compiler_crashers_fixed/27382-void.swift index 7e0ebc513f904..45703852e1392 100644 --- a/validation-test/compiler_crashers/27382-void.swift +++ b/validation-test/compiler_crashers_fixed/27382-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27383-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/27383-swift-declcontext-lookupqualified.swift similarity index 80% rename from validation-test/compiler_crashers/27383-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/27383-swift-declcontext-lookupqualified.swift index b725907985aa5..916cf82b8f226 100644 --- a/validation-test/compiler_crashers/27383-swift-declcontext-lookupqualified.swift +++ b/validation-test/compiler_crashers_fixed/27383-swift-declcontext-lookupqualified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27385-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/27385-swift-modulefile-getdecl.swift similarity index 80% rename from validation-test/compiler_crashers/27385-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/27385-swift-modulefile-getdecl.swift index 58225f20c3c76..50244dc1b0bff 100644 --- a/validation-test/compiler_crashers/27385-swift-modulefile-getdecl.swift +++ b/validation-test/compiler_crashers_fixed/27385-swift-modulefile-getdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27387-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/27387-swift-structtype-get.swift similarity index 80% rename from validation-test/compiler_crashers/27387-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/27387-swift-structtype-get.swift index a08bc633721c6..419bac3460aeb 100644 --- a/validation-test/compiler_crashers/27387-swift-structtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27387-swift-structtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27388-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/27388-swift-metatypetype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27388-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27388-swift-metatypetype-get.swift index 9ed68aa49415d..48c4ddc8c9f8a 100644 --- a/validation-test/compiler_crashers/27388-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27388-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27389-swift-typeexpr-typeexpr.swift b/validation-test/compiler_crashers_fixed/27389-swift-typeexpr-typeexpr.swift similarity index 81% rename from validation-test/compiler_crashers/27389-swift-typeexpr-typeexpr.swift rename to validation-test/compiler_crashers_fixed/27389-swift-typeexpr-typeexpr.swift index f2a1cabdb0e4c..a8a40d52e6d2a 100644 --- a/validation-test/compiler_crashers/27389-swift-typeexpr-typeexpr.swift +++ b/validation-test/compiler_crashers_fixed/27389-swift-typeexpr-typeexpr.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27390-swift-typechecker-computeaccessibility.swift b/validation-test/compiler_crashers_fixed/27390-swift-typechecker-computeaccessibility.swift similarity index 83% rename from validation-test/compiler_crashers/27390-swift-typechecker-computeaccessibility.swift rename to validation-test/compiler_crashers_fixed/27390-swift-typechecker-computeaccessibility.swift index 342aa544d731e..ca920eefb1c68 100644 --- a/validation-test/compiler_crashers/27390-swift-typechecker-computeaccessibility.swift +++ b/validation-test/compiler_crashers_fixed/27390-swift-typechecker-computeaccessibility.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27391-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/27391-swift-typechecker-checkinheritanceclause.swift similarity index 81% rename from validation-test/compiler_crashers/27391-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/27391-swift-typechecker-checkinheritanceclause.swift index c56039246dcd1..37237009b14b2 100644 --- a/validation-test/compiler_crashers/27391-swift-typechecker-checkinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/27391-swift-typechecker-checkinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27393-swift-archetypebuilder-potentialarchetype-gettype.swift b/validation-test/compiler_crashers_fixed/27393-swift-archetypebuilder-potentialarchetype-gettype.swift similarity index 81% rename from validation-test/compiler_crashers/27393-swift-archetypebuilder-potentialarchetype-gettype.swift rename to validation-test/compiler_crashers_fixed/27393-swift-archetypebuilder-potentialarchetype-gettype.swift index 955b702ea8f1f..5cc55f60578d8 100644 --- a/validation-test/compiler_crashers/27393-swift-archetypebuilder-potentialarchetype-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27393-swift-archetypebuilder-potentialarchetype-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27394-swift-type-transform.swift b/validation-test/compiler_crashers_fixed/27394-swift-type-transform.swift similarity index 80% rename from validation-test/compiler_crashers/27394-swift-type-transform.swift rename to validation-test/compiler_crashers_fixed/27394-swift-type-transform.swift index d1212897bc4e3..0a9a3596b550a 100644 --- a/validation-test/compiler_crashers/27394-swift-type-transform.swift +++ b/validation-test/compiler_crashers_fixed/27394-swift-type-transform.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27395-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/27395-swift-nominaltypedecl-preparelookuptable.swift similarity index 82% rename from validation-test/compiler_crashers/27395-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/27395-swift-nominaltypedecl-preparelookuptable.swift index 01367a1e62289..d608b711fbb9b 100644 --- a/validation-test/compiler_crashers/27395-swift-nominaltypedecl-preparelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27395-swift-nominaltypedecl-preparelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27396-swift-typebase-getimplicitlyunwrappedoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/27396-swift-typebase-getimplicitlyunwrappedoptionalobjecttype.swift similarity index 80% rename from validation-test/compiler_crashers/27396-swift-typebase-getimplicitlyunwrappedoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/27396-swift-typebase-getimplicitlyunwrappedoptionalobjecttype.swift index bc3fdcadde77e..1946a96ac6549 100644 --- a/validation-test/compiler_crashers/27396-swift-typebase-getimplicitlyunwrappedoptionalobjecttype.swift +++ b/validation-test/compiler_crashers_fixed/27396-swift-typebase-getimplicitlyunwrappedoptionalobjecttype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27397-swift-patternbindingdecl-setpattern.swift b/validation-test/compiler_crashers_fixed/27397-swift-patternbindingdecl-setpattern.swift similarity index 86% rename from validation-test/compiler_crashers/27397-swift-patternbindingdecl-setpattern.swift rename to validation-test/compiler_crashers_fixed/27397-swift-patternbindingdecl-setpattern.swift index 8560c4efd7d64..3fe59eef69936 100644 --- a/validation-test/compiler_crashers/27397-swift-patternbindingdecl-setpattern.swift +++ b/validation-test/compiler_crashers_fixed/27397-swift-patternbindingdecl-setpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27398-swift-declcontext-getlocalconformances.swift b/validation-test/compiler_crashers_fixed/27398-swift-declcontext-getlocalconformances.swift similarity index 83% rename from validation-test/compiler_crashers/27398-swift-declcontext-getlocalconformances.swift rename to validation-test/compiler_crashers_fixed/27398-swift-declcontext-getlocalconformances.swift index 4038bb9157b82..1527464d3fbb3 100644 --- a/validation-test/compiler_crashers/27398-swift-declcontext-getlocalconformances.swift +++ b/validation-test/compiler_crashers_fixed/27398-swift-declcontext-getlocalconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27399-swift-constraints-constraintsystem-getfixedtyperecursive.swift b/validation-test/compiler_crashers_fixed/27399-swift-constraints-constraintsystem-getfixedtyperecursive.swift similarity index 83% rename from validation-test/compiler_crashers/27399-swift-constraints-constraintsystem-getfixedtyperecursive.swift rename to validation-test/compiler_crashers_fixed/27399-swift-constraints-constraintsystem-getfixedtyperecursive.swift index 7de41a4a3582a..4f0555c7b7960 100644 --- a/validation-test/compiler_crashers/27399-swift-constraints-constraintsystem-getfixedtyperecursive.swift +++ b/validation-test/compiler_crashers_fixed/27399-swift-constraints-constraintsystem-getfixedtyperecursive.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27400-swift-protocolconformance-getinheritedconformance.swift b/validation-test/compiler_crashers_fixed/27400-swift-protocolconformance-getinheritedconformance.swift similarity index 81% rename from validation-test/compiler_crashers/27400-swift-protocolconformance-getinheritedconformance.swift rename to validation-test/compiler_crashers_fixed/27400-swift-protocolconformance-getinheritedconformance.swift index dee3c312372bb..da124935ad8a2 100644 --- a/validation-test/compiler_crashers/27400-swift-protocolconformance-getinheritedconformance.swift +++ b/validation-test/compiler_crashers_fixed/27400-swift-protocolconformance-getinheritedconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27401-void.swift b/validation-test/compiler_crashers_fixed/27401-void.swift similarity index 82% rename from validation-test/compiler_crashers/27401-void.swift rename to validation-test/compiler_crashers_fixed/27401-void.swift index 22ee51fd0778a..ebff79becb092 100644 --- a/validation-test/compiler_crashers/27401-void.swift +++ b/validation-test/compiler_crashers_fixed/27401-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27403-swift-typechecker-resolveinheritanceclause.swift b/validation-test/compiler_crashers_fixed/27403-swift-typechecker-resolveinheritanceclause.swift similarity index 82% rename from validation-test/compiler_crashers/27403-swift-typechecker-resolveinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/27403-swift-typechecker-resolveinheritanceclause.swift index 31c048fe30d28..5be8e732f466b 100644 --- a/validation-test/compiler_crashers/27403-swift-typechecker-resolveinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/27403-swift-typechecker-resolveinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27405-swift-constraints-constraintsystem-simplifyconstraint.swift b/validation-test/compiler_crashers_fixed/27405-swift-constraints-constraintsystem-simplifyconstraint.swift similarity index 83% rename from validation-test/compiler_crashers/27405-swift-constraints-constraintsystem-simplifyconstraint.swift rename to validation-test/compiler_crashers_fixed/27405-swift-constraints-constraintsystem-simplifyconstraint.swift index eb867ce8f96ce..9e2353d0e49e4 100644 --- a/validation-test/compiler_crashers/27405-swift-constraints-constraintsystem-simplifyconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27405-swift-constraints-constraintsystem-simplifyconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27406-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/27406-swift-protocoltype-canonicalizeprotocols.swift similarity index 83% rename from validation-test/compiler_crashers/27406-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/27406-swift-protocoltype-canonicalizeprotocols.swift index d2aed19f5204a..aaccce1e46a6d 100644 --- a/validation-test/compiler_crashers/27406-swift-protocoltype-canonicalizeprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27406-swift-protocoltype-canonicalizeprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27407-swift-constraints-simplifylocator.swift b/validation-test/compiler_crashers_fixed/27407-swift-constraints-simplifylocator.swift similarity index 82% rename from validation-test/compiler_crashers/27407-swift-constraints-simplifylocator.swift rename to validation-test/compiler_crashers_fixed/27407-swift-constraints-simplifylocator.swift index 33f5ffa28d0cd..a2c8bd1fcfe72 100644 --- a/validation-test/compiler_crashers/27407-swift-constraints-simplifylocator.swift +++ b/validation-test/compiler_crashers_fixed/27407-swift-constraints-simplifylocator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27408-swift-removeshadoweddecls.swift b/validation-test/compiler_crashers_fixed/27408-swift-removeshadoweddecls.swift similarity index 84% rename from validation-test/compiler_crashers/27408-swift-removeshadoweddecls.swift rename to validation-test/compiler_crashers_fixed/27408-swift-removeshadoweddecls.swift index e7d9e8f71ddf4..b61060402ca4e 100644 --- a/validation-test/compiler_crashers/27408-swift-removeshadoweddecls.swift +++ b/validation-test/compiler_crashers_fixed/27408-swift-removeshadoweddecls.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27409-llvm-foldingset-swift-enumtype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27409-llvm-foldingset-swift-enumtype-nodeequals.swift similarity index 81% rename from validation-test/compiler_crashers/27409-llvm-foldingset-swift-enumtype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27409-llvm-foldingset-swift-enumtype-nodeequals.swift index db1582b4f471a..d665c021de574 100644 --- a/validation-test/compiler_crashers/27409-llvm-foldingset-swift-enumtype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27409-llvm-foldingset-swift-enumtype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27410-swift-constraints-constraintgraph-computeconnectedcomponents.swift b/validation-test/compiler_crashers_fixed/27410-swift-constraints-constraintgraph-computeconnectedcomponents.swift similarity index 82% rename from validation-test/compiler_crashers/27410-swift-constraints-constraintgraph-computeconnectedcomponents.swift rename to validation-test/compiler_crashers_fixed/27410-swift-constraints-constraintgraph-computeconnectedcomponents.swift index 32abf6b3e5c31..999ba2303f806 100644 --- a/validation-test/compiler_crashers/27410-swift-constraints-constraintgraph-computeconnectedcomponents.swift +++ b/validation-test/compiler_crashers_fixed/27410-swift-constraints-constraintgraph-computeconnectedcomponents.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27411-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/27411-swift-constraints-constraintsystem-simplifytype.swift similarity index 81% rename from validation-test/compiler_crashers/27411-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/27411-swift-constraints-constraintsystem-simplifytype.swift index 0e655636a85fa..abde46917b9fe 100644 --- a/validation-test/compiler_crashers/27411-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/27411-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27412-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27412-swift-typechecker-validatedecl.swift similarity index 84% rename from validation-test/compiler_crashers/27412-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27412-swift-typechecker-validatedecl.swift index 82e8c9bb650f2..668c1e2b9ccf9 100644 --- a/validation-test/compiler_crashers/27412-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27412-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27413-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/27413-swift-modulefile-getimportedmodules.swift similarity index 82% rename from validation-test/compiler_crashers/27413-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/27413-swift-modulefile-getimportedmodules.swift index 8df96564797a9..934b4b412f7de 100644 --- a/validation-test/compiler_crashers/27413-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/27413-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27414-llvm-errs.swift b/validation-test/compiler_crashers_fixed/27414-llvm-errs.swift similarity index 79% rename from validation-test/compiler_crashers/27414-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/27414-llvm-errs.swift index 01be8b89f39c9..f0a2ccaf29a18 100644 --- a/validation-test/compiler_crashers/27414-llvm-errs.swift +++ b/validation-test/compiler_crashers_fixed/27414-llvm-errs.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27415-swift-namelookup-lookupinmodule.swift b/validation-test/compiler_crashers_fixed/27415-swift-namelookup-lookupinmodule.swift similarity index 80% rename from validation-test/compiler_crashers/27415-swift-namelookup-lookupinmodule.swift rename to validation-test/compiler_crashers_fixed/27415-swift-namelookup-lookupinmodule.swift index 20dc8a637eabb..f20be3dc41838 100644 --- a/validation-test/compiler_crashers/27415-swift-namelookup-lookupinmodule.swift +++ b/validation-test/compiler_crashers_fixed/27415-swift-namelookup-lookupinmodule.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27416-swift-archetypebuilder-potentialarchetype-gettype.swift b/validation-test/compiler_crashers_fixed/27416-swift-archetypebuilder-potentialarchetype-gettype.swift similarity index 83% rename from validation-test/compiler_crashers/27416-swift-archetypebuilder-potentialarchetype-gettype.swift rename to validation-test/compiler_crashers_fixed/27416-swift-archetypebuilder-potentialarchetype-gettype.swift index 813a8912ff990..a8a22edb21ca1 100644 --- a/validation-test/compiler_crashers/27416-swift-archetypebuilder-potentialarchetype-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27416-swift-archetypebuilder-potentialarchetype-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27417-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift b/validation-test/compiler_crashers_fixed/27417-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift similarity index 80% rename from validation-test/compiler_crashers/27417-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift rename to validation-test/compiler_crashers_fixed/27417-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift index 5393202de9aaa..c57acd6fa30d9 100644 --- a/validation-test/compiler_crashers/27417-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27417-swift-constraints-constraintsystem-simplifyconformstoconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27418-swift-typechecker-lookupmember.swift b/validation-test/compiler_crashers_fixed/27418-swift-typechecker-lookupmember.swift similarity index 82% rename from validation-test/compiler_crashers/27418-swift-typechecker-lookupmember.swift rename to validation-test/compiler_crashers_fixed/27418-swift-typechecker-lookupmember.swift index be056fb7e7cd5..d6d9c1527bec9 100644 --- a/validation-test/compiler_crashers/27418-swift-typechecker-lookupmember.swift +++ b/validation-test/compiler_crashers_fixed/27418-swift-typechecker-lookupmember.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27419-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/27419-swift-boundgenerictype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27419-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/27419-swift-boundgenerictype-get.swift index 682c36bcf8e36..e73e7362c8140 100644 --- a/validation-test/compiler_crashers/27419-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/27419-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27420-llvm-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/27420-llvm-optional-swift-diagnostic-operator.swift similarity index 82% rename from validation-test/compiler_crashers/27420-llvm-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/27420-llvm-optional-swift-diagnostic-operator.swift index f9234f8036fbd..09ff2e6fa0207 100644 --- a/validation-test/compiler_crashers/27420-llvm-optional-swift-diagnostic-operator.swift +++ b/validation-test/compiler_crashers_fixed/27420-llvm-optional-swift-diagnostic-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27421-formatdiagnostictext.swift b/validation-test/compiler_crashers_fixed/27421-formatdiagnostictext.swift similarity index 85% rename from validation-test/compiler_crashers/27421-formatdiagnostictext.swift rename to validation-test/compiler_crashers_fixed/27421-formatdiagnostictext.swift index 5fd64ff1fbb52..ba8db3007cc7f 100644 --- a/validation-test/compiler_crashers/27421-formatdiagnostictext.swift +++ b/validation-test/compiler_crashers_fixed/27421-formatdiagnostictext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27422-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/27422-swift-lexer-leximpl.swift similarity index 87% rename from validation-test/compiler_crashers/27422-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/27422-swift-lexer-leximpl.swift index b9c9d8a2bb633..71df626d80eae 100644 --- a/validation-test/compiler_crashers/27422-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/27422-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27423-swift-constraints-constraintsystem-finalize.swift b/validation-test/compiler_crashers_fixed/27423-swift-constraints-constraintsystem-finalize.swift similarity index 83% rename from validation-test/compiler_crashers/27423-swift-constraints-constraintsystem-finalize.swift rename to validation-test/compiler_crashers_fixed/27423-swift-constraints-constraintsystem-finalize.swift index 7d7741c40557d..28769ea6e3bcf 100644 --- a/validation-test/compiler_crashers/27423-swift-constraints-constraintsystem-finalize.swift +++ b/validation-test/compiler_crashers_fixed/27423-swift-constraints-constraintsystem-finalize.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27424-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/27424-swift-genericparamlist-addnestedarchetypes.swift similarity index 80% rename from validation-test/compiler_crashers/27424-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/27424-swift-genericparamlist-addnestedarchetypes.swift index d098074e5cf92..487abf772aae9 100644 --- a/validation-test/compiler_crashers/27424-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27424-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27427-swift-protocolcompositiontyperepr-create.swift b/validation-test/compiler_crashers_fixed/27427-swift-protocolcompositiontyperepr-create.swift similarity index 81% rename from validation-test/compiler_crashers/27427-swift-protocolcompositiontyperepr-create.swift rename to validation-test/compiler_crashers_fixed/27427-swift-protocolcompositiontyperepr-create.swift index 2a9bc714fd561..45f883093229d 100644 --- a/validation-test/compiler_crashers/27427-swift-protocolcompositiontyperepr-create.swift +++ b/validation-test/compiler_crashers_fixed/27427-swift-protocolcompositiontyperepr-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27428-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/27428-swift-diagnosticengine-emitdiagnostic.swift similarity index 83% rename from validation-test/compiler_crashers/27428-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27428-swift-diagnosticengine-emitdiagnostic.swift index 0d28a4a7a4809..fc76608340f28 100644 --- a/validation-test/compiler_crashers/27428-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27428-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27429-swift-typechecker-typecheckexpressionshallow.swift b/validation-test/compiler_crashers_fixed/27429-swift-typechecker-typecheckexpressionshallow.swift similarity index 81% rename from validation-test/compiler_crashers/27429-swift-typechecker-typecheckexpressionshallow.swift rename to validation-test/compiler_crashers_fixed/27429-swift-typechecker-typecheckexpressionshallow.swift index f4b8a10d560aa..53a3284c92dee 100644 --- a/validation-test/compiler_crashers/27429-swift-typechecker-typecheckexpressionshallow.swift +++ b/validation-test/compiler_crashers_fixed/27429-swift-typechecker-typecheckexpressionshallow.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27430-swift-boundgenerictype-getsubstitutions.swift b/validation-test/compiler_crashers_fixed/27430-swift-boundgenerictype-getsubstitutions.swift similarity index 81% rename from validation-test/compiler_crashers/27430-swift-boundgenerictype-getsubstitutions.swift rename to validation-test/compiler_crashers_fixed/27430-swift-boundgenerictype-getsubstitutions.swift index a4d15d4e502cc..e7116b3d0413c 100644 --- a/validation-test/compiler_crashers/27430-swift-boundgenerictype-getsubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/27430-swift-boundgenerictype-getsubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27431-swift-constraints-constraintsystem-finalize.swift b/validation-test/compiler_crashers_fixed/27431-swift-constraints-constraintsystem-finalize.swift similarity index 84% rename from validation-test/compiler_crashers/27431-swift-constraints-constraintsystem-finalize.swift rename to validation-test/compiler_crashers_fixed/27431-swift-constraints-constraintsystem-finalize.swift index b9251fc205674..7def68660bf66 100644 --- a/validation-test/compiler_crashers/27431-swift-constraints-constraintsystem-finalize.swift +++ b/validation-test/compiler_crashers_fixed/27431-swift-constraints-constraintsystem-finalize.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27432-swift-typechecker-validatetype.swift b/validation-test/compiler_crashers_fixed/27432-swift-typechecker-validatetype.swift similarity index 82% rename from validation-test/compiler_crashers/27432-swift-typechecker-validatetype.swift rename to validation-test/compiler_crashers_fixed/27432-swift-typechecker-validatetype.swift index 28f5666d6e73c..4acdad931bb27 100644 --- a/validation-test/compiler_crashers/27432-swift-typechecker-validatetype.swift +++ b/validation-test/compiler_crashers_fixed/27432-swift-typechecker-validatetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27433-std-function-func-swift-parser-parsenominaldeclmembers.swift b/validation-test/compiler_crashers_fixed/27433-std-function-func-swift-parser-parsenominaldeclmembers.swift similarity index 81% rename from validation-test/compiler_crashers/27433-std-function-func-swift-parser-parsenominaldeclmembers.swift rename to validation-test/compiler_crashers_fixed/27433-std-function-func-swift-parser-parsenominaldeclmembers.swift index 0d393c0503ffe..ef7f114b0f01f 100644 --- a/validation-test/compiler_crashers/27433-std-function-func-swift-parser-parsenominaldeclmembers.swift +++ b/validation-test/compiler_crashers_fixed/27433-std-function-func-swift-parser-parsenominaldeclmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27434-swift-parser-diagnose.swift b/validation-test/compiler_crashers_fixed/27434-swift-parser-diagnose.swift similarity index 83% rename from validation-test/compiler_crashers/27434-swift-parser-diagnose.swift rename to validation-test/compiler_crashers_fixed/27434-swift-parser-diagnose.swift index 7cb4951e58c76..02cc66e4d8021 100644 --- a/validation-test/compiler_crashers/27434-swift-parser-diagnose.swift +++ b/validation-test/compiler_crashers_fixed/27434-swift-parser-diagnose.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27436-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27436-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 80% rename from validation-test/compiler_crashers/27436-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27436-swift-printingdiagnosticconsumer-handlediagnostic.swift index 73c42ea54945f..7aec232875728 100644 --- a/validation-test/compiler_crashers/27436-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27436-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27439-swift-funcdecl-setdeserializedsignature.swift b/validation-test/compiler_crashers_fixed/27439-swift-funcdecl-setdeserializedsignature.swift similarity index 81% rename from validation-test/compiler_crashers/27439-swift-funcdecl-setdeserializedsignature.swift rename to validation-test/compiler_crashers_fixed/27439-swift-funcdecl-setdeserializedsignature.swift index a273cd94bb19a..9ee2414de2e5b 100644 --- a/validation-test/compiler_crashers/27439-swift-funcdecl-setdeserializedsignature.swift +++ b/validation-test/compiler_crashers_fixed/27439-swift-funcdecl-setdeserializedsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27440-void.swift b/validation-test/compiler_crashers_fixed/27440-void.swift similarity index 82% rename from validation-test/compiler_crashers/27440-void.swift rename to validation-test/compiler_crashers_fixed/27440-void.swift index ad2d76362b436..155a7f615fbee 100644 --- a/validation-test/compiler_crashers/27440-void.swift +++ b/validation-test/compiler_crashers_fixed/27440-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27442-swift-parser-parseexprclosure.swift b/validation-test/compiler_crashers_fixed/27442-swift-parser-parseexprclosure.swift similarity index 80% rename from validation-test/compiler_crashers/27442-swift-parser-parseexprclosure.swift rename to validation-test/compiler_crashers_fixed/27442-swift-parser-parseexprclosure.swift index 75c8cea5b845c..80741972fb9ab 100644 --- a/validation-test/compiler_crashers/27442-swift-parser-parseexprclosure.swift +++ b/validation-test/compiler_crashers_fixed/27442-swift-parser-parseexprclosure.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27444-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/27444-swift-typebase-getanyoptionalobjecttype.swift similarity index 82% rename from validation-test/compiler_crashers/27444-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/27444-swift-typebase-getanyoptionalobjecttype.swift index cb023d9cfb0fb..6cae6d304e672 100644 --- a/validation-test/compiler_crashers/27444-swift-typebase-getanyoptionalobjecttype.swift +++ b/validation-test/compiler_crashers_fixed/27444-swift-typebase-getanyoptionalobjecttype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27446-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/27446-swift-conformancelookuptable-updatelookuptable.swift similarity index 84% rename from validation-test/compiler_crashers/27446-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/27446-swift-conformancelookuptable-updatelookuptable.swift index 4d7208d5e41e5..2f4c6ea3de76a 100644 --- a/validation-test/compiler_crashers/27446-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27446-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27447-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/27447-swift-diagnosticengine-flushactivediagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27447-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/27447-swift-diagnosticengine-flushactivediagnostic.swift index 25a2df4255df7..23b00947d2436 100644 --- a/validation-test/compiler_crashers/27447-swift-diagnosticengine-flushactivediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27447-swift-diagnosticengine-flushactivediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27450-bool.swift b/validation-test/compiler_crashers_fixed/27450-bool.swift similarity index 79% rename from validation-test/compiler_crashers/27450-bool.swift rename to validation-test/compiler_crashers_fixed/27450-bool.swift index 047543bd72aa5..44a0e8b040c26 100644 --- a/validation-test/compiler_crashers/27450-bool.swift +++ b/validation-test/compiler_crashers_fixed/27450-bool.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27451-swift-parser-parsedeclstruct.swift b/validation-test/compiler_crashers_fixed/27451-swift-parser-parsedeclstruct.swift similarity index 81% rename from validation-test/compiler_crashers/27451-swift-parser-parsedeclstruct.swift rename to validation-test/compiler_crashers_fixed/27451-swift-parser-parsedeclstruct.swift index 2a3285d89f934..2795aef2b6903 100644 --- a/validation-test/compiler_crashers/27451-swift-parser-parsedeclstruct.swift +++ b/validation-test/compiler_crashers_fixed/27451-swift-parser-parsedeclstruct.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27452-swift-nominaltypedecl-computetype.swift b/validation-test/compiler_crashers_fixed/27452-swift-nominaltypedecl-computetype.swift similarity index 85% rename from validation-test/compiler_crashers/27452-swift-nominaltypedecl-computetype.swift rename to validation-test/compiler_crashers_fixed/27452-swift-nominaltypedecl-computetype.swift index 9500e0ba06328..87d50fef73435 100644 --- a/validation-test/compiler_crashers/27452-swift-nominaltypedecl-computetype.swift +++ b/validation-test/compiler_crashers_fixed/27452-swift-nominaltypedecl-computetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27453-diagnoseredundantaccessors.swift b/validation-test/compiler_crashers_fixed/27453-diagnoseredundantaccessors.swift similarity index 84% rename from validation-test/compiler_crashers/27453-diagnoseredundantaccessors.swift rename to validation-test/compiler_crashers_fixed/27453-diagnoseredundantaccessors.swift index 8dc192396cd07..4575193785a65 100644 --- a/validation-test/compiler_crashers/27453-diagnoseredundantaccessors.swift +++ b/validation-test/compiler_crashers_fixed/27453-diagnoseredundantaccessors.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27454-swift-parser-parsetoken.swift b/validation-test/compiler_crashers_fixed/27454-swift-parser-parsetoken.swift similarity index 78% rename from validation-test/compiler_crashers/27454-swift-parser-parsetoken.swift rename to validation-test/compiler_crashers_fixed/27454-swift-parser-parsetoken.swift index 200ac60a42728..dd9736b610177 100644 --- a/validation-test/compiler_crashers/27454-swift-parser-parsetoken.swift +++ b/validation-test/compiler_crashers_fixed/27454-swift-parser-parsetoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27458-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/27458-swift-constraints-constraintsystem-solve.swift similarity index 81% rename from validation-test/compiler_crashers/27458-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/27458-swift-constraints-constraintsystem-solve.swift index 58f4f48cb00c7..5ae5802b245ec 100644 --- a/validation-test/compiler_crashers/27458-swift-constraints-constraintsystem-solve.swift +++ b/validation-test/compiler_crashers_fixed/27458-swift-constraints-constraintsystem-solve.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27459-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/27459-swift-genericsignature-get.swift similarity index 79% rename from validation-test/compiler_crashers/27459-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/27459-swift-genericsignature-get.swift index b62d7cb5128e2..25cf8a19917ca 100644 --- a/validation-test/compiler_crashers/27459-swift-genericsignature-get.swift +++ b/validation-test/compiler_crashers_fixed/27459-swift-genericsignature-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27460-swift-protocoltype-compareprotocols.swift b/validation-test/compiler_crashers_fixed/27460-swift-protocoltype-compareprotocols.swift similarity index 79% rename from validation-test/compiler_crashers/27460-swift-protocoltype-compareprotocols.swift rename to validation-test/compiler_crashers_fixed/27460-swift-protocoltype-compareprotocols.swift index fddfbe6f94d56..76df3d4f36956 100644 --- a/validation-test/compiler_crashers/27460-swift-protocoltype-compareprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27460-swift-protocoltype-compareprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27461-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/27461-swift-genericparamlist-addnestedarchetypes.swift similarity index 82% rename from validation-test/compiler_crashers/27461-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/27461-swift-genericparamlist-addnestedarchetypes.swift index c20d67f220ccb..a556c0916a251 100644 --- a/validation-test/compiler_crashers/27461-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27461-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27462-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27462-swift-modulefile-lookupvalue.swift similarity index 81% rename from validation-test/compiler_crashers/27462-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27462-swift-modulefile-lookupvalue.swift index b8d044701f541..650ba6f440688 100644 --- a/validation-test/compiler_crashers/27462-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27462-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27463-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/27463-swift-parser-parseexprpostfix.swift similarity index 79% rename from validation-test/compiler_crashers/27463-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/27463-swift-parser-parseexprpostfix.swift index 6b0b7b6f01d69..423e4f93dc148 100644 --- a/validation-test/compiler_crashers/27463-swift-parser-parseexprpostfix.swift +++ b/validation-test/compiler_crashers_fixed/27463-swift-parser-parseexprpostfix.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27464-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/27464-swift-typebase-isequal.swift similarity index 82% rename from validation-test/compiler_crashers/27464-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/27464-swift-typebase-isequal.swift index 31f37e2af5c7c..d4359deede900 100644 --- a/validation-test/compiler_crashers/27464-swift-typebase-isequal.swift +++ b/validation-test/compiler_crashers_fixed/27464-swift-typebase-isequal.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27465-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift b/validation-test/compiler_crashers_fixed/27465-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift similarity index 83% rename from validation-test/compiler_crashers/27465-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift rename to validation-test/compiler_crashers_fixed/27465-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift index 8b3b3c8684028..b531afa558b07 100644 --- a/validation-test/compiler_crashers/27465-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift +++ b/validation-test/compiler_crashers_fixed/27465-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27466-swift-lexer-lexidentifier.swift b/validation-test/compiler_crashers_fixed/27466-swift-lexer-lexidentifier.swift similarity index 83% rename from validation-test/compiler_crashers/27466-swift-lexer-lexidentifier.swift rename to validation-test/compiler_crashers_fixed/27466-swift-lexer-lexidentifier.swift index c0a8a360c4a6a..a8e8f79c0dde5 100644 --- a/validation-test/compiler_crashers/27466-swift-lexer-lexidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27466-swift-lexer-lexidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27469-swift-patternbindingdecl-create.swift b/validation-test/compiler_crashers_fixed/27469-swift-patternbindingdecl-create.swift similarity index 82% rename from validation-test/compiler_crashers/27469-swift-patternbindingdecl-create.swift rename to validation-test/compiler_crashers_fixed/27469-swift-patternbindingdecl-create.swift index 6c077264b7d9e..8ca025385ebd1 100644 --- a/validation-test/compiler_crashers/27469-swift-patternbindingdecl-create.swift +++ b/validation-test/compiler_crashers_fixed/27469-swift-patternbindingdecl-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27470-swift-constraints-constraintsystem-solverec.swift b/validation-test/compiler_crashers_fixed/27470-swift-constraints-constraintsystem-solverec.swift similarity index 82% rename from validation-test/compiler_crashers/27470-swift-constraints-constraintsystem-solverec.swift rename to validation-test/compiler_crashers_fixed/27470-swift-constraints-constraintsystem-solverec.swift index c87d5825ec765..8a936aec44b70 100644 --- a/validation-test/compiler_crashers/27470-swift-constraints-constraintsystem-solverec.swift +++ b/validation-test/compiler_crashers_fixed/27470-swift-constraints-constraintsystem-solverec.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27471-swift-unqualifiedlookup-unqualifiedlookup.swift b/validation-test/compiler_crashers_fixed/27471-swift-unqualifiedlookup-unqualifiedlookup.swift similarity index 81% rename from validation-test/compiler_crashers/27471-swift-unqualifiedlookup-unqualifiedlookup.swift rename to validation-test/compiler_crashers_fixed/27471-swift-unqualifiedlookup-unqualifiedlookup.swift index 14d754164e0cc..da64df5f439dd 100644 --- a/validation-test/compiler_crashers/27471-swift-unqualifiedlookup-unqualifiedlookup.swift +++ b/validation-test/compiler_crashers_fixed/27471-swift-unqualifiedlookup-unqualifiedlookup.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27472-swift-decl-walk.swift b/validation-test/compiler_crashers_fixed/27472-swift-decl-walk.swift similarity index 84% rename from validation-test/compiler_crashers/27472-swift-decl-walk.swift rename to validation-test/compiler_crashers_fixed/27472-swift-decl-walk.swift index d742ea7676a06..938c1da0b9e81 100644 --- a/validation-test/compiler_crashers/27472-swift-decl-walk.swift +++ b/validation-test/compiler_crashers_fixed/27472-swift-decl-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27473-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27473-swift-inflightdiagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27473-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27473-swift-inflightdiagnostic.swift index 09a1b126bc718..f51f1c8e61065 100644 --- a/validation-test/compiler_crashers/27473-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27473-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27474-swift-typechecker-checkdeclarationavailability.swift b/validation-test/compiler_crashers_fixed/27474-swift-typechecker-checkdeclarationavailability.swift similarity index 80% rename from validation-test/compiler_crashers/27474-swift-typechecker-checkdeclarationavailability.swift rename to validation-test/compiler_crashers_fixed/27474-swift-typechecker-checkdeclarationavailability.swift index 222f543eea976..101179a1a6c95 100644 --- a/validation-test/compiler_crashers/27474-swift-typechecker-checkdeclarationavailability.swift +++ b/validation-test/compiler_crashers_fixed/27474-swift-typechecker-checkdeclarationavailability.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27476-swift-modulefile-maybereadforeignerrorconvention.swift b/validation-test/compiler_crashers_fixed/27476-swift-modulefile-maybereadforeignerrorconvention.swift similarity index 81% rename from validation-test/compiler_crashers/27476-swift-modulefile-maybereadforeignerrorconvention.swift rename to validation-test/compiler_crashers_fixed/27476-swift-modulefile-maybereadforeignerrorconvention.swift index 39e8627222a8c..be2b377ae095e 100644 --- a/validation-test/compiler_crashers/27476-swift-modulefile-maybereadforeignerrorconvention.swift +++ b/validation-test/compiler_crashers_fixed/27476-swift-modulefile-maybereadforeignerrorconvention.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27478-llvm-errs.swift b/validation-test/compiler_crashers_fixed/27478-llvm-errs.swift similarity index 81% rename from validation-test/compiler_crashers/27478-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/27478-llvm-errs.swift index 670270fd3a575..e5e3e94ad4b3e 100644 --- a/validation-test/compiler_crashers/27478-llvm-errs.swift +++ b/validation-test/compiler_crashers_fixed/27478-llvm-errs.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27479-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27479-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/27479-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27479-swift-type-subst.swift index 3edaa08f1cb66..03e3fb2f20b9e 100644 --- a/validation-test/compiler_crashers/27479-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27479-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27481-swift-conformancelookuptable-resolveconformances.swift b/validation-test/compiler_crashers_fixed/27481-swift-conformancelookuptable-resolveconformances.swift similarity index 80% rename from validation-test/compiler_crashers/27481-swift-conformancelookuptable-resolveconformances.swift rename to validation-test/compiler_crashers_fixed/27481-swift-conformancelookuptable-resolveconformances.swift index e66828f1c7dff..f1a05d375dab5 100644 --- a/validation-test/compiler_crashers/27481-swift-conformancelookuptable-resolveconformances.swift +++ b/validation-test/compiler_crashers_fixed/27481-swift-conformancelookuptable-resolveconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27482-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/27482-swift-parser-parseexprpostfix.swift similarity index 80% rename from validation-test/compiler_crashers/27482-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/27482-swift-parser-parseexprpostfix.swift index 5c53bc02979b0..6da7ef40f635d 100644 --- a/validation-test/compiler_crashers/27482-swift-parser-parseexprpostfix.swift +++ b/validation-test/compiler_crashers_fixed/27482-swift-parser-parseexprpostfix.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27483-swift-namelookup-findlocalval-visitbracestmt.swift b/validation-test/compiler_crashers_fixed/27483-swift-namelookup-findlocalval-visitbracestmt.swift similarity index 82% rename from validation-test/compiler_crashers/27483-swift-namelookup-findlocalval-visitbracestmt.swift rename to validation-test/compiler_crashers_fixed/27483-swift-namelookup-findlocalval-visitbracestmt.swift index 3f56a4b9c3d60..c05173b4c18d0 100644 --- a/validation-test/compiler_crashers/27483-swift-namelookup-findlocalval-visitbracestmt.swift +++ b/validation-test/compiler_crashers_fixed/27483-swift-namelookup-findlocalval-visitbracestmt.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27484-swift-typebase-isspecialized.swift b/validation-test/compiler_crashers_fixed/27484-swift-typebase-isspecialized.swift similarity index 83% rename from validation-test/compiler_crashers/27484-swift-typebase-isspecialized.swift rename to validation-test/compiler_crashers_fixed/27484-swift-typebase-isspecialized.swift index 260a468b55bb0..06c1b469092bc 100644 --- a/validation-test/compiler_crashers/27484-swift-typebase-isspecialized.swift +++ b/validation-test/compiler_crashers_fixed/27484-swift-typebase-isspecialized.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27486-swift-constraints-constraintsystem-findbestsolution.swift b/validation-test/compiler_crashers_fixed/27486-swift-constraints-constraintsystem-findbestsolution.swift similarity index 82% rename from validation-test/compiler_crashers/27486-swift-constraints-constraintsystem-findbestsolution.swift rename to validation-test/compiler_crashers_fixed/27486-swift-constraints-constraintsystem-findbestsolution.swift index 259dd69b59347..2e2c8b34d74b7 100644 --- a/validation-test/compiler_crashers/27486-swift-constraints-constraintsystem-findbestsolution.swift +++ b/validation-test/compiler_crashers_fixed/27486-swift-constraints-constraintsystem-findbestsolution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27488-swift-conformancelookuptable-expandimpliedconformances.swift b/validation-test/compiler_crashers_fixed/27488-swift-conformancelookuptable-expandimpliedconformances.swift similarity index 82% rename from validation-test/compiler_crashers/27488-swift-conformancelookuptable-expandimpliedconformances.swift rename to validation-test/compiler_crashers_fixed/27488-swift-conformancelookuptable-expandimpliedconformances.swift index 422fd6e8cfe8d..e76f532035637 100644 --- a/validation-test/compiler_crashers/27488-swift-conformancelookuptable-expandimpliedconformances.swift +++ b/validation-test/compiler_crashers_fixed/27488-swift-conformancelookuptable-expandimpliedconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27490-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27490-swift-inflightdiagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27490-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27490-swift-inflightdiagnostic.swift index 25bb8411b24d6..9ac6dd77f4784 100644 --- a/validation-test/compiler_crashers/27490-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27490-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27491-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/27491-swift-modulefile-maybereadgenericparams.swift similarity index 82% rename from validation-test/compiler_crashers/27491-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/27491-swift-modulefile-maybereadgenericparams.swift index aa547608f47ae..d35bf49102631 100644 --- a/validation-test/compiler_crashers/27491-swift-modulefile-maybereadgenericparams.swift +++ b/validation-test/compiler_crashers_fixed/27491-swift-modulefile-maybereadgenericparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27492-swift-inouttype-get.swift b/validation-test/compiler_crashers_fixed/27492-swift-inouttype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27492-swift-inouttype-get.swift rename to validation-test/compiler_crashers_fixed/27492-swift-inouttype-get.swift index e1e3112ab2981..0a62bb455ef8f 100644 --- a/validation-test/compiler_crashers/27492-swift-inouttype-get.swift +++ b/validation-test/compiler_crashers_fixed/27492-swift-inouttype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27493-swift-parser-consumetoken.swift b/validation-test/compiler_crashers_fixed/27493-swift-parser-consumetoken.swift similarity index 81% rename from validation-test/compiler_crashers/27493-swift-parser-consumetoken.swift rename to validation-test/compiler_crashers_fixed/27493-swift-parser-consumetoken.swift index 6e4a3dbd5b42e..17b4dc445361d 100644 --- a/validation-test/compiler_crashers/27493-swift-parser-consumetoken.swift +++ b/validation-test/compiler_crashers_fixed/27493-swift-parser-consumetoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27494-swift-conformancelookuptable-lookupconformance.swift b/validation-test/compiler_crashers_fixed/27494-swift-conformancelookuptable-lookupconformance.swift similarity index 81% rename from validation-test/compiler_crashers/27494-swift-conformancelookuptable-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/27494-swift-conformancelookuptable-lookupconformance.swift index a846df5ea38d6..8a72f8e680d46 100644 --- a/validation-test/compiler_crashers/27494-swift-conformancelookuptable-lookupconformance.swift +++ b/validation-test/compiler_crashers_fixed/27494-swift-conformancelookuptable-lookupconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27495-swift-typechecker-addimplicitconstructors.swift b/validation-test/compiler_crashers_fixed/27495-swift-typechecker-addimplicitconstructors.swift similarity index 81% rename from validation-test/compiler_crashers/27495-swift-typechecker-addimplicitconstructors.swift rename to validation-test/compiler_crashers_fixed/27495-swift-typechecker-addimplicitconstructors.swift index b5bd0e41f296a..31530f2a1c60c 100644 --- a/validation-test/compiler_crashers/27495-swift-typechecker-addimplicitconstructors.swift +++ b/validation-test/compiler_crashers_fixed/27495-swift-typechecker-addimplicitconstructors.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27496-swift-modulefile-declcommenttableinfo-readdata.swift b/validation-test/compiler_crashers_fixed/27496-swift-modulefile-declcommenttableinfo-readdata.swift similarity index 81% rename from validation-test/compiler_crashers/27496-swift-modulefile-declcommenttableinfo-readdata.swift rename to validation-test/compiler_crashers_fixed/27496-swift-modulefile-declcommenttableinfo-readdata.swift index 516ad9e2ad05d..236f1e6982b07 100644 --- a/validation-test/compiler_crashers/27496-swift-modulefile-declcommenttableinfo-readdata.swift +++ b/validation-test/compiler_crashers_fixed/27496-swift-modulefile-declcommenttableinfo-readdata.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27501-swift-namelookup-lookupinmodule.swift b/validation-test/compiler_crashers_fixed/27501-swift-namelookup-lookupinmodule.swift similarity index 82% rename from validation-test/compiler_crashers/27501-swift-namelookup-lookupinmodule.swift rename to validation-test/compiler_crashers_fixed/27501-swift-namelookup-lookupinmodule.swift index f932ce43db2d0..b67961670f1bf 100644 --- a/validation-test/compiler_crashers/27501-swift-namelookup-lookupinmodule.swift +++ b/validation-test/compiler_crashers_fixed/27501-swift-namelookup-lookupinmodule.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27502-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/27502-swift-typebase-getdesugaredtype.swift similarity index 81% rename from validation-test/compiler_crashers/27502-swift-typebase-getdesugaredtype.swift rename to validation-test/compiler_crashers_fixed/27502-swift-typebase-getdesugaredtype.swift index 50e2fd8858041..2cbb941368735 100644 --- a/validation-test/compiler_crashers/27502-swift-typebase-getdesugaredtype.swift +++ b/validation-test/compiler_crashers_fixed/27502-swift-typebase-getdesugaredtype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27503-swift-conformancelookuptable-expandimpliedconformances.swift b/validation-test/compiler_crashers_fixed/27503-swift-conformancelookuptable-expandimpliedconformances.swift similarity index 82% rename from validation-test/compiler_crashers/27503-swift-conformancelookuptable-expandimpliedconformances.swift rename to validation-test/compiler_crashers_fixed/27503-swift-conformancelookuptable-expandimpliedconformances.swift index f639722c39880..f7386c9f93bb4 100644 --- a/validation-test/compiler_crashers/27503-swift-conformancelookuptable-expandimpliedconformances.swift +++ b/validation-test/compiler_crashers_fixed/27503-swift-conformancelookuptable-expandimpliedconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27504-swift-typebase-getmembersubstitutions.swift b/validation-test/compiler_crashers_fixed/27504-swift-typebase-getmembersubstitutions.swift similarity index 81% rename from validation-test/compiler_crashers/27504-swift-typebase-getmembersubstitutions.swift rename to validation-test/compiler_crashers_fixed/27504-swift-typebase-getmembersubstitutions.swift index 971ad4b21a8c8..e707c3c4efa2f 100644 --- a/validation-test/compiler_crashers/27504-swift-typebase-getmembersubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/27504-swift-typebase-getmembersubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27505-swift-diagnosticengine-emitdiagnostic.swift b/validation-test/compiler_crashers_fixed/27505-swift-diagnosticengine-emitdiagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/27505-swift-diagnosticengine-emitdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27505-swift-diagnosticengine-emitdiagnostic.swift index 6a0826eebb20c..3b57557a7f02a 100644 --- a/validation-test/compiler_crashers/27505-swift-diagnosticengine-emitdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27505-swift-diagnosticengine-emitdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27507-swift-modulefile-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27507-swift-modulefile-lookupvalue.swift similarity index 81% rename from validation-test/compiler_crashers/27507-swift-modulefile-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27507-swift-modulefile-lookupvalue.swift index 67d0e3e06f06b..04e25ed7f6222 100644 --- a/validation-test/compiler_crashers/27507-swift-modulefile-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27507-swift-modulefile-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27508-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/27508-swift-typebase-getdesugaredtype.swift similarity index 83% rename from validation-test/compiler_crashers/27508-swift-typebase-getdesugaredtype.swift rename to validation-test/compiler_crashers_fixed/27508-swift-typebase-getdesugaredtype.swift index e3745e87821f5..0149adc4326ec 100644 --- a/validation-test/compiler_crashers/27508-swift-typebase-getdesugaredtype.swift +++ b/validation-test/compiler_crashers_fixed/27508-swift-typebase-getdesugaredtype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27510-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/27510-swift-boundgenerictype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27510-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/27510-swift-boundgenerictype-get.swift index 5bddbfed915dc..d6e22e3db7111 100644 --- a/validation-test/compiler_crashers/27510-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/27510-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27511-swift-constraints-constraintsystem-performmemberlookup.swift b/validation-test/compiler_crashers_fixed/27511-swift-constraints-constraintsystem-performmemberlookup.swift similarity index 83% rename from validation-test/compiler_crashers/27511-swift-constraints-constraintsystem-performmemberlookup.swift rename to validation-test/compiler_crashers_fixed/27511-swift-constraints-constraintsystem-performmemberlookup.swift index 122238705eadb..28d8b0ed5789a 100644 --- a/validation-test/compiler_crashers/27511-swift-constraints-constraintsystem-performmemberlookup.swift +++ b/validation-test/compiler_crashers_fixed/27511-swift-constraints-constraintsystem-performmemberlookup.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27512-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27512-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift similarity index 82% rename from validation-test/compiler_crashers/27512-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27512-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift index cf2738059f04c..abfd8937c081e 100644 --- a/validation-test/compiler_crashers/27512-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27512-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27515-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/27515-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 82% rename from validation-test/compiler_crashers/27515-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/27515-swift-typechecker-overapproximateosversionsatlocation.swift index 63255c4938d95..8601287f36ab9 100644 --- a/validation-test/compiler_crashers/27515-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/27515-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27516-swift-nominaltypedecl-classifyasoptionaltype.swift b/validation-test/compiler_crashers_fixed/27516-swift-nominaltypedecl-classifyasoptionaltype.swift similarity index 80% rename from validation-test/compiler_crashers/27516-swift-nominaltypedecl-classifyasoptionaltype.swift rename to validation-test/compiler_crashers_fixed/27516-swift-nominaltypedecl-classifyasoptionaltype.swift index 890d13c29d5b5..1dc3ea085f1ce 100644 --- a/validation-test/compiler_crashers/27516-swift-nominaltypedecl-classifyasoptionaltype.swift +++ b/validation-test/compiler_crashers_fixed/27516-swift-nominaltypedecl-classifyasoptionaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27517-swift-valuedecl-overwritetype.swift b/validation-test/compiler_crashers_fixed/27517-swift-valuedecl-overwritetype.swift similarity index 83% rename from validation-test/compiler_crashers/27517-swift-valuedecl-overwritetype.swift rename to validation-test/compiler_crashers_fixed/27517-swift-valuedecl-overwritetype.swift index d228a736bb2b0..58cdf2752bb5b 100644 --- a/validation-test/compiler_crashers/27517-swift-valuedecl-overwritetype.swift +++ b/validation-test/compiler_crashers_fixed/27517-swift-valuedecl-overwritetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27518-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27518-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift similarity index 81% rename from validation-test/compiler_crashers/27518-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27518-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift index 03d18b485eb7d..0aa1b9a48894a 100644 --- a/validation-test/compiler_crashers/27518-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27518-llvm-foldingset-swift-genericfunctiontype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27519-swift-pattern-buildforwardingrefexpr.swift b/validation-test/compiler_crashers_fixed/27519-swift-pattern-buildforwardingrefexpr.swift similarity index 83% rename from validation-test/compiler_crashers/27519-swift-pattern-buildforwardingrefexpr.swift rename to validation-test/compiler_crashers_fixed/27519-swift-pattern-buildforwardingrefexpr.swift index 09c5cfd4ba4c9..c3d196a1ee529 100644 --- a/validation-test/compiler_crashers/27519-swift-pattern-buildforwardingrefexpr.swift +++ b/validation-test/compiler_crashers_fixed/27519-swift-pattern-buildforwardingrefexpr.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27520-swift-typechecker-substituteinputsugartypeforresult.swift b/validation-test/compiler_crashers_fixed/27520-swift-typechecker-substituteinputsugartypeforresult.swift similarity index 80% rename from validation-test/compiler_crashers/27520-swift-typechecker-substituteinputsugartypeforresult.swift rename to validation-test/compiler_crashers_fixed/27520-swift-typechecker-substituteinputsugartypeforresult.swift index 2df94e396d8f2..f7357e5cc6602 100644 --- a/validation-test/compiler_crashers/27520-swift-typechecker-substituteinputsugartypeforresult.swift +++ b/validation-test/compiler_crashers_fixed/27520-swift-typechecker-substituteinputsugartypeforresult.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27521-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/27521-swift-parser-parseexprpostfix.swift similarity index 82% rename from validation-test/compiler_crashers/27521-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/27521-swift-parser-parseexprpostfix.swift index 0f69d76318371..96f187655d543 100644 --- a/validation-test/compiler_crashers/27521-swift-parser-parseexprpostfix.swift +++ b/validation-test/compiler_crashers_fixed/27521-swift-parser-parseexprpostfix.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27522-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27522-swift-typechecker-validatedecl.swift similarity index 83% rename from validation-test/compiler_crashers/27522-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27522-swift-typechecker-validatedecl.swift index cc7af1eb57428..9cad1880af339 100644 --- a/validation-test/compiler_crashers/27522-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27522-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27523-swift-lexer-leximpl.swift b/validation-test/compiler_crashers_fixed/27523-swift-lexer-leximpl.swift similarity index 88% rename from validation-test/compiler_crashers/27523-swift-lexer-leximpl.swift rename to validation-test/compiler_crashers_fixed/27523-swift-lexer-leximpl.swift index afbd20663e64f..9f218a76d91f6 100644 --- a/validation-test/compiler_crashers/27523-swift-lexer-leximpl.swift +++ b/validation-test/compiler_crashers_fixed/27523-swift-lexer-leximpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27524-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27524-swift-type-subst.swift similarity index 83% rename from validation-test/compiler_crashers/27524-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27524-swift-type-subst.swift index e019114319a7f..558ea11b83371 100644 --- a/validation-test/compiler_crashers/27524-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27524-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27525-swift-constraints-constraintsystem-matchtupletypes.swift b/validation-test/compiler_crashers_fixed/27525-swift-constraints-constraintsystem-matchtupletypes.swift similarity index 80% rename from validation-test/compiler_crashers/27525-swift-constraints-constraintsystem-matchtupletypes.swift rename to validation-test/compiler_crashers_fixed/27525-swift-constraints-constraintsystem-matchtupletypes.swift index d48e55d896b5e..8dede146ea691 100644 --- a/validation-test/compiler_crashers/27525-swift-constraints-constraintsystem-matchtupletypes.swift +++ b/validation-test/compiler_crashers_fixed/27525-swift-constraints-constraintsystem-matchtupletypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27526-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/27526-swift-structtype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27526-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/27526-swift-structtype-get.swift index 81463f024b5cb..d907f9887e1f7 100644 --- a/validation-test/compiler_crashers/27526-swift-structtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27526-swift-structtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27527-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/27527-swift-nominaltypedecl-getmembers.swift similarity index 85% rename from validation-test/compiler_crashers/27527-swift-nominaltypedecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/27527-swift-nominaltypedecl-getmembers.swift index ea9b1900aaddf..857da4d55d958 100644 --- a/validation-test/compiler_crashers/27527-swift-nominaltypedecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/27527-swift-nominaltypedecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27528-swift-constraints-constraintsystem-solve.swift b/validation-test/compiler_crashers_fixed/27528-swift-constraints-constraintsystem-solve.swift similarity index 85% rename from validation-test/compiler_crashers/27528-swift-constraints-constraintsystem-solve.swift rename to validation-test/compiler_crashers_fixed/27528-swift-constraints-constraintsystem-solve.swift index 7d43eac5887f5..076656a08026d 100644 --- a/validation-test/compiler_crashers/27528-swift-constraints-constraintsystem-solve.swift +++ b/validation-test/compiler_crashers_fixed/27528-swift-constraints-constraintsystem-solve.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27530-resolveidenttypecomponent.swift b/validation-test/compiler_crashers_fixed/27530-resolveidenttypecomponent.swift similarity index 79% rename from validation-test/compiler_crashers/27530-resolveidenttypecomponent.swift rename to validation-test/compiler_crashers_fixed/27530-resolveidenttypecomponent.swift index 521883a604455..f3daadd8634f2 100644 --- a/validation-test/compiler_crashers/27530-resolveidenttypecomponent.swift +++ b/validation-test/compiler_crashers_fixed/27530-resolveidenttypecomponent.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27531-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/27531-swift-typechecker-coercepatterntotype.swift similarity index 81% rename from validation-test/compiler_crashers/27531-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/27531-swift-typechecker-coercepatterntotype.swift index 1a19b4f764365..a016eecad017b 100644 --- a/validation-test/compiler_crashers/27531-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/27531-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27532-swift-constraints-constraintsystem-matchdeepequalitytypes.swift b/validation-test/compiler_crashers_fixed/27532-swift-constraints-constraintsystem-matchdeepequalitytypes.swift similarity index 79% rename from validation-test/compiler_crashers/27532-swift-constraints-constraintsystem-matchdeepequalitytypes.swift rename to validation-test/compiler_crashers_fixed/27532-swift-constraints-constraintsystem-matchdeepequalitytypes.swift index 54b3f2b5bf3b3..4fc7c579f2f75 100644 --- a/validation-test/compiler_crashers/27532-swift-constraints-constraintsystem-matchdeepequalitytypes.swift +++ b/validation-test/compiler_crashers_fixed/27532-swift-constraints-constraintsystem-matchdeepequalitytypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27533-swift-ide-printdeclusr.swift b/validation-test/compiler_crashers_fixed/27533-swift-ide-printdeclusr.swift similarity index 83% rename from validation-test/compiler_crashers/27533-swift-ide-printdeclusr.swift rename to validation-test/compiler_crashers_fixed/27533-swift-ide-printdeclusr.swift index 3cacf6f0eb914..4f2b275b06459 100644 --- a/validation-test/compiler_crashers/27533-swift-ide-printdeclusr.swift +++ b/validation-test/compiler_crashers_fixed/27533-swift-ide-printdeclusr.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27534-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/27534-swift-genericparamlist-addnestedarchetypes.swift similarity index 81% rename from validation-test/compiler_crashers/27534-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/27534-swift-genericparamlist-addnestedarchetypes.swift index 055365f4f02b3..4f9aa549d8102 100644 --- a/validation-test/compiler_crashers/27534-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27534-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27535-swift-diagnosticengine-flushactivediagnostic.swift b/validation-test/compiler_crashers_fixed/27535-swift-diagnosticengine-flushactivediagnostic.swift similarity index 85% rename from validation-test/compiler_crashers/27535-swift-diagnosticengine-flushactivediagnostic.swift rename to validation-test/compiler_crashers_fixed/27535-swift-diagnosticengine-flushactivediagnostic.swift index 22ffb0d3cb9b4..5f2e0b8635942 100644 --- a/validation-test/compiler_crashers/27535-swift-diagnosticengine-flushactivediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27535-swift-diagnosticengine-flushactivediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27537-swift-clangimporter-implementation-finishpendingactions.swift b/validation-test/compiler_crashers_fixed/27537-swift-clangimporter-implementation-finishpendingactions.swift similarity index 83% rename from validation-test/compiler_crashers/27537-swift-clangimporter-implementation-finishpendingactions.swift rename to validation-test/compiler_crashers_fixed/27537-swift-clangimporter-implementation-finishpendingactions.swift index 83fcd74aa9b68..38d68bd573eb6 100644 --- a/validation-test/compiler_crashers/27537-swift-clangimporter-implementation-finishpendingactions.swift +++ b/validation-test/compiler_crashers_fixed/27537-swift-clangimporter-implementation-finishpendingactions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27538-swift-typebase-getanyoptionalobjecttype.swift b/validation-test/compiler_crashers_fixed/27538-swift-typebase-getanyoptionalobjecttype.swift similarity index 83% rename from validation-test/compiler_crashers/27538-swift-typebase-getanyoptionalobjecttype.swift rename to validation-test/compiler_crashers_fixed/27538-swift-typebase-getanyoptionalobjecttype.swift index 692f4f02fa4d4..6c8138c853635 100644 --- a/validation-test/compiler_crashers/27538-swift-typebase-getanyoptionalobjecttype.swift +++ b/validation-test/compiler_crashers_fixed/27538-swift-typebase-getanyoptionalobjecttype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27539-swift-parser-parsetoken.swift b/validation-test/compiler_crashers_fixed/27539-swift-parser-parsetoken.swift similarity index 81% rename from validation-test/compiler_crashers/27539-swift-parser-parsetoken.swift rename to validation-test/compiler_crashers_fixed/27539-swift-parser-parsetoken.swift index 3af8085e4ec25..d471459eadfd4 100644 --- a/validation-test/compiler_crashers/27539-swift-parser-parsetoken.swift +++ b/validation-test/compiler_crashers_fixed/27539-swift-parser-parsetoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27540-swift-type-walk.swift b/validation-test/compiler_crashers_fixed/27540-swift-type-walk.swift similarity index 82% rename from validation-test/compiler_crashers/27540-swift-type-walk.swift rename to validation-test/compiler_crashers_fixed/27540-swift-type-walk.swift index fceab8e7417b1..12371ec95c2c5 100644 --- a/validation-test/compiler_crashers/27540-swift-type-walk.swift +++ b/validation-test/compiler_crashers_fixed/27540-swift-type-walk.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27541-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/27541-swift-modulefile-maybereadgenericparams.swift similarity index 83% rename from validation-test/compiler_crashers/27541-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/27541-swift-modulefile-maybereadgenericparams.swift index 380e2cb1407e0..7ef905216bc22 100644 --- a/validation-test/compiler_crashers/27541-swift-modulefile-maybereadgenericparams.swift +++ b/validation-test/compiler_crashers_fixed/27541-swift-modulefile-maybereadgenericparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27542-swift-genericfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/27542-swift-genericfunctiontype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27542-swift-genericfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/27542-swift-genericfunctiontype-get.swift index f7f30d4dee7d5..370b052e3ff8d 100644 --- a/validation-test/compiler_crashers/27542-swift-genericfunctiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27542-swift-genericfunctiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27543-swift-typechecker-checkgenericarguments.swift b/validation-test/compiler_crashers_fixed/27543-swift-typechecker-checkgenericarguments.swift similarity index 83% rename from validation-test/compiler_crashers/27543-swift-typechecker-checkgenericarguments.swift rename to validation-test/compiler_crashers_fixed/27543-swift-typechecker-checkgenericarguments.swift index 9e291e5ee40e0..0ef16033f1ff9 100644 --- a/validation-test/compiler_crashers/27543-swift-typechecker-checkgenericarguments.swift +++ b/validation-test/compiler_crashers_fixed/27543-swift-typechecker-checkgenericarguments.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27544-bool.swift b/validation-test/compiler_crashers_fixed/27544-bool.swift similarity index 82% rename from validation-test/compiler_crashers/27544-bool.swift rename to validation-test/compiler_crashers_fixed/27544-bool.swift index 08b959c7fe822..5e6344ddbf3f2 100644 --- a/validation-test/compiler_crashers/27544-bool.swift +++ b/validation-test/compiler_crashers_fixed/27544-bool.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27546-swift-clangimporter-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27546-swift-clangimporter-lookupvalue.swift similarity index 81% rename from validation-test/compiler_crashers/27546-swift-clangimporter-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27546-swift-clangimporter-lookupvalue.swift index 2219da06bcaa6..211947f98b7a1 100644 --- a/validation-test/compiler_crashers/27546-swift-clangimporter-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27546-swift-clangimporter-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27547-swift-constraints-constraintsystem-getalternativeliteraltypes.swift b/validation-test/compiler_crashers_fixed/27547-swift-constraints-constraintsystem-getalternativeliteraltypes.swift similarity index 81% rename from validation-test/compiler_crashers/27547-swift-constraints-constraintsystem-getalternativeliteraltypes.swift rename to validation-test/compiler_crashers_fixed/27547-swift-constraints-constraintsystem-getalternativeliteraltypes.swift index ef2d49139ea51..8aeabb76616a3 100644 --- a/validation-test/compiler_crashers/27547-swift-constraints-constraintsystem-getalternativeliteraltypes.swift +++ b/validation-test/compiler_crashers_fixed/27547-swift-constraints-constraintsystem-getalternativeliteraltypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27548-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/27548-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 84% rename from validation-test/compiler_crashers/27548-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/27548-swift-constraints-constraintsystem-assignfixedtype.swift index 0622cbf523408..78d87d4cdfb81 100644 --- a/validation-test/compiler_crashers/27548-swift-constraints-constraintsystem-assignfixedtype.swift +++ b/validation-test/compiler_crashers_fixed/27548-swift-constraints-constraintsystem-assignfixedtype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27549-swift-namelookup-findlocalval-visitbracestmt.swift b/validation-test/compiler_crashers_fixed/27549-swift-namelookup-findlocalval-visitbracestmt.swift similarity index 81% rename from validation-test/compiler_crashers/27549-swift-namelookup-findlocalval-visitbracestmt.swift rename to validation-test/compiler_crashers_fixed/27549-swift-namelookup-findlocalval-visitbracestmt.swift index 2bce0d90a4e43..b6d0eaa5cf4a3 100644 --- a/validation-test/compiler_crashers/27549-swift-namelookup-findlocalval-visitbracestmt.swift +++ b/validation-test/compiler_crashers_fixed/27549-swift-namelookup-findlocalval-visitbracestmt.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27550-swift-moduledecl-lookupconformance.swift b/validation-test/compiler_crashers_fixed/27550-swift-moduledecl-lookupconformance.swift similarity index 82% rename from validation-test/compiler_crashers/27550-swift-moduledecl-lookupconformance.swift rename to validation-test/compiler_crashers_fixed/27550-swift-moduledecl-lookupconformance.swift index fa53f7c2ddaa9..47ff141144ae0 100644 --- a/validation-test/compiler_crashers/27550-swift-moduledecl-lookupconformance.swift +++ b/validation-test/compiler_crashers_fixed/27550-swift-moduledecl-lookupconformance.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27551-swift-protocoldecl-existentialtypesupportedslow.swift b/validation-test/compiler_crashers_fixed/27551-swift-protocoldecl-existentialtypesupportedslow.swift similarity index 85% rename from validation-test/compiler_crashers/27551-swift-protocoldecl-existentialtypesupportedslow.swift rename to validation-test/compiler_crashers_fixed/27551-swift-protocoldecl-existentialtypesupportedslow.swift index 90ac7db805060..3e5d3ae4693b4 100644 --- a/validation-test/compiler_crashers/27551-swift-protocoldecl-existentialtypesupportedslow.swift +++ b/validation-test/compiler_crashers_fixed/27551-swift-protocoldecl-existentialtypesupportedslow.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27552-swift-constraints-constraintsystem-solverstate-solverstate.swift b/validation-test/compiler_crashers_fixed/27552-swift-constraints-constraintsystem-solverstate-solverstate.swift similarity index 83% rename from validation-test/compiler_crashers/27552-swift-constraints-constraintsystem-solverstate-solverstate.swift rename to validation-test/compiler_crashers_fixed/27552-swift-constraints-constraintsystem-solverstate-solverstate.swift index 8f528d68bcc5f..43e39304adc98 100644 --- a/validation-test/compiler_crashers/27552-swift-constraints-constraintsystem-solverstate-solverstate.swift +++ b/validation-test/compiler_crashers_fixed/27552-swift-constraints-constraintsystem-solverstate-solverstate.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27554-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27554-swift-modulefile-gettype.swift similarity index 80% rename from validation-test/compiler_crashers/27554-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27554-swift-modulefile-gettype.swift index 2452aecd5de77..40d6a3de75906 100644 --- a/validation-test/compiler_crashers/27554-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27554-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27555-swift-constraints-constraintgraph-lookupnode.swift b/validation-test/compiler_crashers_fixed/27555-swift-constraints-constraintgraph-lookupnode.swift similarity index 82% rename from validation-test/compiler_crashers/27555-swift-constraints-constraintgraph-lookupnode.swift rename to validation-test/compiler_crashers_fixed/27555-swift-constraints-constraintgraph-lookupnode.swift index 6b109cd39e07d..c964d5113a077 100644 --- a/validation-test/compiler_crashers/27555-swift-constraints-constraintgraph-lookupnode.swift +++ b/validation-test/compiler_crashers_fixed/27555-swift-constraints-constraintgraph-lookupnode.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27557-swift-parser-parseidentifier.swift b/validation-test/compiler_crashers_fixed/27557-swift-parser-parseidentifier.swift similarity index 82% rename from validation-test/compiler_crashers/27557-swift-parser-parseidentifier.swift rename to validation-test/compiler_crashers_fixed/27557-swift-parser-parseidentifier.swift index 228e18fa119f5..32b89e96981e7 100644 --- a/validation-test/compiler_crashers/27557-swift-parser-parseidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27557-swift-parser-parseidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27558-swift-parser-parsetypeidentifier.swift b/validation-test/compiler_crashers_fixed/27558-swift-parser-parsetypeidentifier.swift similarity index 85% rename from validation-test/compiler_crashers/27558-swift-parser-parsetypeidentifier.swift rename to validation-test/compiler_crashers_fixed/27558-swift-parser-parsetypeidentifier.swift index 360180097af45..082259369fca8 100644 --- a/validation-test/compiler_crashers/27558-swift-parser-parsetypeidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27558-swift-parser-parsetypeidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27559-swift-modulefile-maybereadforeignerrorconvention.swift b/validation-test/compiler_crashers_fixed/27559-swift-modulefile-maybereadforeignerrorconvention.swift similarity index 82% rename from validation-test/compiler_crashers/27559-swift-modulefile-maybereadforeignerrorconvention.swift rename to validation-test/compiler_crashers_fixed/27559-swift-modulefile-maybereadforeignerrorconvention.swift index e4e8eb35c9078..9b99821f7ffd2 100644 --- a/validation-test/compiler_crashers/27559-swift-modulefile-maybereadforeignerrorconvention.swift +++ b/validation-test/compiler_crashers_fixed/27559-swift-modulefile-maybereadforeignerrorconvention.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27560-swift-typechecker-addimplicitconstructors.swift b/validation-test/compiler_crashers_fixed/27560-swift-typechecker-addimplicitconstructors.swift similarity index 82% rename from validation-test/compiler_crashers/27560-swift-typechecker-addimplicitconstructors.swift rename to validation-test/compiler_crashers_fixed/27560-swift-typechecker-addimplicitconstructors.swift index 342bed2f85d2b..a59d09c25f4d8 100644 --- a/validation-test/compiler_crashers/27560-swift-typechecker-addimplicitconstructors.swift +++ b/validation-test/compiler_crashers_fixed/27560-swift-typechecker-addimplicitconstructors.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27561-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/27561-swift-functiontype-get.swift similarity index 84% rename from validation-test/compiler_crashers/27561-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/27561-swift-functiontype-get.swift index 60fcba9d9fa2b..24b0e79bf15a3 100644 --- a/validation-test/compiler_crashers/27561-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27561-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27562-swift-genericsignature-get.swift b/validation-test/compiler_crashers_fixed/27562-swift-genericsignature-get.swift similarity index 80% rename from validation-test/compiler_crashers/27562-swift-genericsignature-get.swift rename to validation-test/compiler_crashers_fixed/27562-swift-genericsignature-get.swift index a04748fc89b2a..6a4f115a80110 100644 --- a/validation-test/compiler_crashers/27562-swift-genericsignature-get.swift +++ b/validation-test/compiler_crashers_fixed/27562-swift-genericsignature-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27563-swift-funcdecl-isunaryoperator.swift b/validation-test/compiler_crashers_fixed/27563-swift-funcdecl-isunaryoperator.swift similarity index 82% rename from validation-test/compiler_crashers/27563-swift-funcdecl-isunaryoperator.swift rename to validation-test/compiler_crashers_fixed/27563-swift-funcdecl-isunaryoperator.swift index ae279aa6736fe..0ccd6089895f0 100644 --- a/validation-test/compiler_crashers/27563-swift-funcdecl-isunaryoperator.swift +++ b/validation-test/compiler_crashers_fixed/27563-swift-funcdecl-isunaryoperator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27564-swift-constraints-constraintsystem-matchfunctiontypes.swift b/validation-test/compiler_crashers_fixed/27564-swift-constraints-constraintsystem-matchfunctiontypes.swift similarity index 81% rename from validation-test/compiler_crashers/27564-swift-constraints-constraintsystem-matchfunctiontypes.swift rename to validation-test/compiler_crashers_fixed/27564-swift-constraints-constraintsystem-matchfunctiontypes.swift index 0dbc5da8fdf45..d5c5d33b7b29b 100644 --- a/validation-test/compiler_crashers/27564-swift-constraints-constraintsystem-matchfunctiontypes.swift +++ b/validation-test/compiler_crashers_fixed/27564-swift-constraints-constraintsystem-matchfunctiontypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27565-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/27565-swift-typechecker-checkinheritanceclause.swift similarity index 81% rename from validation-test/compiler_crashers/27565-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/27565-swift-typechecker-checkinheritanceclause.swift index 85c0e580e8639..3236c8a9df2e8 100644 --- a/validation-test/compiler_crashers/27565-swift-typechecker-checkinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/27565-swift-typechecker-checkinheritanceclause.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27567-swift-constraints-constraintsystem-addoverloadset.swift b/validation-test/compiler_crashers_fixed/27567-swift-constraints-constraintsystem-addoverloadset.swift similarity index 83% rename from validation-test/compiler_crashers/27567-swift-constraints-constraintsystem-addoverloadset.swift rename to validation-test/compiler_crashers_fixed/27567-swift-constraints-constraintsystem-addoverloadset.swift index d7d61b9011b4f..9a2710458e828 100644 --- a/validation-test/compiler_crashers/27567-swift-constraints-constraintsystem-addoverloadset.swift +++ b/validation-test/compiler_crashers_fixed/27567-swift-constraints-constraintsystem-addoverloadset.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27568-swift-polymorphicfunctiontype-get.swift b/validation-test/compiler_crashers_fixed/27568-swift-polymorphicfunctiontype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27568-swift-polymorphicfunctiontype-get.swift rename to validation-test/compiler_crashers_fixed/27568-swift-polymorphicfunctiontype-get.swift index 55e1cfe0f3768..a4ae4afc72dcc 100644 --- a/validation-test/compiler_crashers/27568-swift-polymorphicfunctiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27568-swift-polymorphicfunctiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27569-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27569-swift-typechecker-validatedecl.swift similarity index 85% rename from validation-test/compiler_crashers/27569-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27569-swift-typechecker-validatedecl.swift index 258618a68a969..0f46b50b0fa04 100644 --- a/validation-test/compiler_crashers/27569-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27569-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27570-checkenumrawvalues.swift b/validation-test/compiler_crashers_fixed/27570-checkenumrawvalues.swift similarity index 80% rename from validation-test/compiler_crashers/27570-checkenumrawvalues.swift rename to validation-test/compiler_crashers_fixed/27570-checkenumrawvalues.swift index 8dbfa491142cc..05950bc040404 100644 --- a/validation-test/compiler_crashers/27570-checkenumrawvalues.swift +++ b/validation-test/compiler_crashers_fixed/27570-checkenumrawvalues.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27572-swift-nominaltypedecl-getdeclaredtypeincontext.swift b/validation-test/compiler_crashers_fixed/27572-swift-nominaltypedecl-getdeclaredtypeincontext.swift similarity index 81% rename from validation-test/compiler_crashers/27572-swift-nominaltypedecl-getdeclaredtypeincontext.swift rename to validation-test/compiler_crashers_fixed/27572-swift-nominaltypedecl-getdeclaredtypeincontext.swift index a35956621f167..52aeb481066b7 100644 --- a/validation-test/compiler_crashers/27572-swift-nominaltypedecl-getdeclaredtypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/27572-swift-nominaltypedecl-getdeclaredtypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27573-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/27573-swift-modulefile-maybereadpattern.swift similarity index 82% rename from validation-test/compiler_crashers/27573-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/27573-swift-modulefile-maybereadpattern.swift index 0f089da99e225..bd8b8668d6032 100644 --- a/validation-test/compiler_crashers/27573-swift-modulefile-maybereadpattern.swift +++ b/validation-test/compiler_crashers_fixed/27573-swift-modulefile-maybereadpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27575-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27575-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/27575-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27575-swift-type-subst.swift index 30b9916d63680..60576e2a8919f 100644 --- a/validation-test/compiler_crashers/27575-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27575-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27576-swift-markasobjc.swift b/validation-test/compiler_crashers_fixed/27576-swift-markasobjc.swift similarity index 82% rename from validation-test/compiler_crashers/27576-swift-markasobjc.swift rename to validation-test/compiler_crashers_fixed/27576-swift-markasobjc.swift index 10ee61aa1e0d4..bc01a5af9fa71 100644 --- a/validation-test/compiler_crashers/27576-swift-markasobjc.swift +++ b/validation-test/compiler_crashers_fixed/27576-swift-markasobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27577-swift-funcdecl-setdeserializedsignature.swift b/validation-test/compiler_crashers_fixed/27577-swift-funcdecl-setdeserializedsignature.swift similarity index 81% rename from validation-test/compiler_crashers/27577-swift-funcdecl-setdeserializedsignature.swift rename to validation-test/compiler_crashers_fixed/27577-swift-funcdecl-setdeserializedsignature.swift index fb1c371007a18..a38bb5f8227c1 100644 --- a/validation-test/compiler_crashers/27577-swift-funcdecl-setdeserializedsignature.swift +++ b/validation-test/compiler_crashers_fixed/27577-swift-funcdecl-setdeserializedsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27578-void.swift b/validation-test/compiler_crashers_fixed/27578-void.swift similarity index 82% rename from validation-test/compiler_crashers/27578-void.swift rename to validation-test/compiler_crashers_fixed/27578-void.swift index 050c84e58e838..b0e4eb5cd15a0 100644 --- a/validation-test/compiler_crashers/27578-void.swift +++ b/validation-test/compiler_crashers_fixed/27578-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27579-vtable.swift b/validation-test/compiler_crashers_fixed/27579-vtable.swift similarity index 78% rename from validation-test/compiler_crashers/27579-vtable.swift rename to validation-test/compiler_crashers_fixed/27579-vtable.swift index 5fecc2a36a8c2..1e4b7233030aa 100644 --- a/validation-test/compiler_crashers/27579-vtable.swift +++ b/validation-test/compiler_crashers_fixed/27579-vtable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27580-swift-typebase-getmembersubstitutions.swift b/validation-test/compiler_crashers_fixed/27580-swift-typebase-getmembersubstitutions.swift similarity index 89% rename from validation-test/compiler_crashers/27580-swift-typebase-getmembersubstitutions.swift rename to validation-test/compiler_crashers_fixed/27580-swift-typebase-getmembersubstitutions.swift index a06065402a057..700781572903f 100644 --- a/validation-test/compiler_crashers/27580-swift-typebase-getmembersubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/27580-swift-typebase-getmembersubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27581-swift-modulefile-maybereadgenericparams.swift b/validation-test/compiler_crashers_fixed/27581-swift-modulefile-maybereadgenericparams.swift similarity index 80% rename from validation-test/compiler_crashers/27581-swift-modulefile-maybereadgenericparams.swift rename to validation-test/compiler_crashers_fixed/27581-swift-modulefile-maybereadgenericparams.swift index 765cd9645770b..1fe01ff069909 100644 --- a/validation-test/compiler_crashers/27581-swift-modulefile-maybereadgenericparams.swift +++ b/validation-test/compiler_crashers_fixed/27581-swift-modulefile-maybereadgenericparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27582-swift-valuedecl-settype.swift b/validation-test/compiler_crashers_fixed/27582-swift-valuedecl-settype.swift similarity index 82% rename from validation-test/compiler_crashers/27582-swift-valuedecl-settype.swift rename to validation-test/compiler_crashers_fixed/27582-swift-valuedecl-settype.swift index 05f418f6f60a3..f36d67c0b0f49 100644 --- a/validation-test/compiler_crashers/27582-swift-valuedecl-settype.swift +++ b/validation-test/compiler_crashers_fixed/27582-swift-valuedecl-settype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27583-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/27583-swift-functiontype-get.swift similarity index 84% rename from validation-test/compiler_crashers/27583-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/27583-swift-functiontype-get.swift index 8efd32330745b..ca7e6fd6ece91 100644 --- a/validation-test/compiler_crashers/27583-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27583-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27585-swift-astcontext-loadextensions.swift b/validation-test/compiler_crashers_fixed/27585-swift-astcontext-loadextensions.swift similarity index 82% rename from validation-test/compiler_crashers/27585-swift-astcontext-loadextensions.swift rename to validation-test/compiler_crashers_fixed/27585-swift-astcontext-loadextensions.swift index 3ffa8520167d0..d4a6034ea720e 100644 --- a/validation-test/compiler_crashers/27585-swift-astcontext-loadextensions.swift +++ b/validation-test/compiler_crashers_fixed/27585-swift-astcontext-loadextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27586-swift-parser-consumetoken.swift b/validation-test/compiler_crashers_fixed/27586-swift-parser-consumetoken.swift similarity index 82% rename from validation-test/compiler_crashers/27586-swift-parser-consumetoken.swift rename to validation-test/compiler_crashers_fixed/27586-swift-parser-consumetoken.swift index f8b724edc8fbc..5405d8eb5427e 100644 --- a/validation-test/compiler_crashers/27586-swift-parser-consumetoken.swift +++ b/validation-test/compiler_crashers_fixed/27586-swift-parser-consumetoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27589-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27589-swift-typechecker-validatedecl.swift similarity index 83% rename from validation-test/compiler_crashers/27589-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27589-swift-typechecker-validatedecl.swift index 20a3efa921366..0da094e393866 100644 --- a/validation-test/compiler_crashers/27589-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27589-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27591-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27591-swift-modulefile-gettype.swift similarity index 81% rename from validation-test/compiler_crashers/27591-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27591-swift-modulefile-gettype.swift index 6116a063f075a..1238a2da8bfe5 100644 --- a/validation-test/compiler_crashers/27591-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27591-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27592-swift-genericparamlist-addnestedarchetypes.swift b/validation-test/compiler_crashers_fixed/27592-swift-genericparamlist-addnestedarchetypes.swift similarity index 83% rename from validation-test/compiler_crashers/27592-swift-genericparamlist-addnestedarchetypes.swift rename to validation-test/compiler_crashers_fixed/27592-swift-genericparamlist-addnestedarchetypes.swift index ff1a861b08ed0..5032c8279cc86 100644 --- a/validation-test/compiler_crashers/27592-swift-genericparamlist-addnestedarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27592-swift-genericparamlist-addnestedarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27593-swift-genericparamlist-deriveallarchetypes.swift b/validation-test/compiler_crashers_fixed/27593-swift-genericparamlist-deriveallarchetypes.swift similarity index 83% rename from validation-test/compiler_crashers/27593-swift-genericparamlist-deriveallarchetypes.swift rename to validation-test/compiler_crashers_fixed/27593-swift-genericparamlist-deriveallarchetypes.swift index 133a909b249bb..0f58495dd08be 100644 --- a/validation-test/compiler_crashers/27593-swift-genericparamlist-deriveallarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27593-swift-genericparamlist-deriveallarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27594-swift-getbuiltinvaluedecl.swift b/validation-test/compiler_crashers_fixed/27594-swift-getbuiltinvaluedecl.swift similarity index 82% rename from validation-test/compiler_crashers/27594-swift-getbuiltinvaluedecl.swift rename to validation-test/compiler_crashers_fixed/27594-swift-getbuiltinvaluedecl.swift index b673cc37610bd..97e72c407efee 100644 --- a/validation-test/compiler_crashers/27594-swift-getbuiltinvaluedecl.swift +++ b/validation-test/compiler_crashers_fixed/27594-swift-getbuiltinvaluedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27595-swift-parser-parsedeclvar.swift b/validation-test/compiler_crashers_fixed/27595-swift-parser-parsedeclvar.swift similarity index 81% rename from validation-test/compiler_crashers/27595-swift-parser-parsedeclvar.swift rename to validation-test/compiler_crashers_fixed/27595-swift-parser-parsedeclvar.swift index 67e56dec47e5e..bec97e4880d7c 100644 --- a/validation-test/compiler_crashers/27595-swift-parser-parsedeclvar.swift +++ b/validation-test/compiler_crashers_fixed/27595-swift-parser-parsedeclvar.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27597-swift-modulefile-maybereadpattern.swift b/validation-test/compiler_crashers_fixed/27597-swift-modulefile-maybereadpattern.swift similarity index 81% rename from validation-test/compiler_crashers/27597-swift-modulefile-maybereadpattern.swift rename to validation-test/compiler_crashers_fixed/27597-swift-modulefile-maybereadpattern.swift index 3f31ef31a71ad..e88acf3464555 100644 --- a/validation-test/compiler_crashers/27597-swift-modulefile-maybereadpattern.swift +++ b/validation-test/compiler_crashers_fixed/27597-swift-modulefile-maybereadpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27598-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/27598-swift-typechecker-coercepatterntotype.swift similarity index 81% rename from validation-test/compiler_crashers/27598-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/27598-swift-typechecker-coercepatterntotype.swift index f10af8a1750b3..756e592199ece 100644 --- a/validation-test/compiler_crashers/27598-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/27598-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27599-llvm-foldingset-swift-boundgenerictype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27599-llvm-foldingset-swift-boundgenerictype-nodeequals.swift similarity index 82% rename from validation-test/compiler_crashers/27599-llvm-foldingset-swift-boundgenerictype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27599-llvm-foldingset-swift-boundgenerictype-nodeequals.swift index 68f0c9edd56cf..cc036f718eac8 100644 --- a/validation-test/compiler_crashers/27599-llvm-foldingset-swift-boundgenerictype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27599-llvm-foldingset-swift-boundgenerictype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27600-swift-constraints-constraintsystem-recordopenedtypes.swift b/validation-test/compiler_crashers_fixed/27600-swift-constraints-constraintsystem-recordopenedtypes.swift similarity index 80% rename from validation-test/compiler_crashers/27600-swift-constraints-constraintsystem-recordopenedtypes.swift rename to validation-test/compiler_crashers_fixed/27600-swift-constraints-constraintsystem-recordopenedtypes.swift index 9a124e8668813..2f67590c288f2 100644 --- a/validation-test/compiler_crashers/27600-swift-constraints-constraintsystem-recordopenedtypes.swift +++ b/validation-test/compiler_crashers_fixed/27600-swift-constraints-constraintsystem-recordopenedtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27603-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/27603-swift-typechecker-validatedecl.swift similarity index 83% rename from validation-test/compiler_crashers/27603-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/27603-swift-typechecker-validatedecl.swift index fb48bdfd403de..0b2f1760874be 100644 --- a/validation-test/compiler_crashers/27603-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/27603-swift-typechecker-validatedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27604-swift-valuedecl-getoverloadsignature.swift b/validation-test/compiler_crashers_fixed/27604-swift-valuedecl-getoverloadsignature.swift similarity index 83% rename from validation-test/compiler_crashers/27604-swift-valuedecl-getoverloadsignature.swift rename to validation-test/compiler_crashers_fixed/27604-swift-valuedecl-getoverloadsignature.swift index 8da067957fa40..189353c5066cd 100644 --- a/validation-test/compiler_crashers/27604-swift-valuedecl-getoverloadsignature.swift +++ b/validation-test/compiler_crashers_fixed/27604-swift-valuedecl-getoverloadsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27605-swift-parser-parsedeclprotocol.swift b/validation-test/compiler_crashers_fixed/27605-swift-parser-parsedeclprotocol.swift similarity index 82% rename from validation-test/compiler_crashers/27605-swift-parser-parsedeclprotocol.swift rename to validation-test/compiler_crashers_fixed/27605-swift-parser-parsedeclprotocol.swift index 252aca2c6d33b..df1b15d1cbfb3 100644 --- a/validation-test/compiler_crashers/27605-swift-parser-parsedeclprotocol.swift +++ b/validation-test/compiler_crashers_fixed/27605-swift-parser-parsedeclprotocol.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27606-swift-astcontext-addedexternaldecl.swift b/validation-test/compiler_crashers_fixed/27606-swift-astcontext-addedexternaldecl.swift similarity index 82% rename from validation-test/compiler_crashers/27606-swift-astcontext-addedexternaldecl.swift rename to validation-test/compiler_crashers_fixed/27606-swift-astcontext-addedexternaldecl.swift index 601f12d03aa8a..0691974355c48 100644 --- a/validation-test/compiler_crashers/27606-swift-astcontext-addedexternaldecl.swift +++ b/validation-test/compiler_crashers_fixed/27606-swift-astcontext-addedexternaldecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27607-swift-constraints-constraintsystem-matchfunctiontypes.swift b/validation-test/compiler_crashers_fixed/27607-swift-constraints-constraintsystem-matchfunctiontypes.swift similarity index 82% rename from validation-test/compiler_crashers/27607-swift-constraints-constraintsystem-matchfunctiontypes.swift rename to validation-test/compiler_crashers_fixed/27607-swift-constraints-constraintsystem-matchfunctiontypes.swift index 9460f58f98696..10571960a9ee4 100644 --- a/validation-test/compiler_crashers/27607-swift-constraints-constraintsystem-matchfunctiontypes.swift +++ b/validation-test/compiler_crashers_fixed/27607-swift-constraints-constraintsystem-matchfunctiontypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27608-llvm-errs.swift b/validation-test/compiler_crashers_fixed/27608-llvm-errs.swift similarity index 79% rename from validation-test/compiler_crashers/27608-llvm-errs.swift rename to validation-test/compiler_crashers_fixed/27608-llvm-errs.swift index 5985293609020..4147981b8db27 100644 --- a/validation-test/compiler_crashers/27608-llvm-errs.swift +++ b/validation-test/compiler_crashers_fixed/27608-llvm-errs.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27609-std-function-func-checkaccessibility.swift b/validation-test/compiler_crashers_fixed/27609-std-function-func-checkaccessibility.swift similarity index 84% rename from validation-test/compiler_crashers/27609-std-function-func-checkaccessibility.swift rename to validation-test/compiler_crashers_fixed/27609-std-function-func-checkaccessibility.swift index a6e9b9d4c3cc2..be30585903698 100644 --- a/validation-test/compiler_crashers/27609-std-function-func-checkaccessibility.swift +++ b/validation-test/compiler_crashers_fixed/27609-std-function-func-checkaccessibility.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27611-swift-parser-parsegetsetimpl.swift b/validation-test/compiler_crashers_fixed/27611-swift-parser-parsegetsetimpl.swift similarity index 84% rename from validation-test/compiler_crashers/27611-swift-parser-parsegetsetimpl.swift rename to validation-test/compiler_crashers_fixed/27611-swift-parser-parsegetsetimpl.swift index a71b0fce07efe..07021731f4d2e 100644 --- a/validation-test/compiler_crashers/27611-swift-parser-parsegetsetimpl.swift +++ b/validation-test/compiler_crashers_fixed/27611-swift-parser-parsegetsetimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27612-swift-typechecker-checkunsupportedprotocoltype.swift b/validation-test/compiler_crashers_fixed/27612-swift-typechecker-checkunsupportedprotocoltype.swift similarity index 82% rename from validation-test/compiler_crashers/27612-swift-typechecker-checkunsupportedprotocoltype.swift rename to validation-test/compiler_crashers_fixed/27612-swift-typechecker-checkunsupportedprotocoltype.swift index e05a90b5477bd..264a4e8499b25 100644 --- a/validation-test/compiler_crashers/27612-swift-typechecker-checkunsupportedprotocoltype.swift +++ b/validation-test/compiler_crashers_fixed/27612-swift-typechecker-checkunsupportedprotocoltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27614-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/27614-swift-typebase-getcanonicaltype.swift similarity index 82% rename from validation-test/compiler_crashers/27614-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/27614-swift-typebase-getcanonicaltype.swift index 13bc18ed1e63c..161ea9e3b0391 100644 --- a/validation-test/compiler_crashers/27614-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/27614-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27615-swift-nominaltypedecl-prepareextensions.swift b/validation-test/compiler_crashers_fixed/27615-swift-nominaltypedecl-prepareextensions.swift similarity index 84% rename from validation-test/compiler_crashers/27615-swift-nominaltypedecl-prepareextensions.swift rename to validation-test/compiler_crashers_fixed/27615-swift-nominaltypedecl-prepareextensions.swift index 8a0e2d4180cf1..3650865e3351e 100644 --- a/validation-test/compiler_crashers/27615-swift-nominaltypedecl-prepareextensions.swift +++ b/validation-test/compiler_crashers_fixed/27615-swift-nominaltypedecl-prepareextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27616-swift-nominaltypedecl-getmembers.swift b/validation-test/compiler_crashers_fixed/27616-swift-nominaltypedecl-getmembers.swift similarity index 83% rename from validation-test/compiler_crashers/27616-swift-nominaltypedecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/27616-swift-nominaltypedecl-getmembers.swift index 91cd0fbe13509..a0b67624722cc 100644 --- a/validation-test/compiler_crashers/27616-swift-nominaltypedecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/27616-swift-nominaltypedecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27617-swift-markasobjc.swift b/validation-test/compiler_crashers_fixed/27617-swift-markasobjc.swift similarity index 81% rename from validation-test/compiler_crashers/27617-swift-markasobjc.swift rename to validation-test/compiler_crashers_fixed/27617-swift-markasobjc.swift index 86b4aec616578..3909cba31dd8c 100644 --- a/validation-test/compiler_crashers/27617-swift-markasobjc.swift +++ b/validation-test/compiler_crashers_fixed/27617-swift-markasobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27618-swift-modulefile-getimportedmodules.swift b/validation-test/compiler_crashers_fixed/27618-swift-modulefile-getimportedmodules.swift similarity index 82% rename from validation-test/compiler_crashers/27618-swift-modulefile-getimportedmodules.swift rename to validation-test/compiler_crashers_fixed/27618-swift-modulefile-getimportedmodules.swift index 9f1bcd38eeca6..a9090e90f8e0a 100644 --- a/validation-test/compiler_crashers/27618-swift-modulefile-getimportedmodules.swift +++ b/validation-test/compiler_crashers_fixed/27618-swift-modulefile-getimportedmodules.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27620-swift-genericsignature-genericsignature.swift b/validation-test/compiler_crashers_fixed/27620-swift-genericsignature-genericsignature.swift similarity index 82% rename from validation-test/compiler_crashers/27620-swift-genericsignature-genericsignature.swift rename to validation-test/compiler_crashers_fixed/27620-swift-genericsignature-genericsignature.swift index 67291ec7c04f7..77ce9224a19f2 100644 --- a/validation-test/compiler_crashers/27620-swift-genericsignature-genericsignature.swift +++ b/validation-test/compiler_crashers_fixed/27620-swift-genericsignature-genericsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27621-swift-getbuiltinvaluedecl.swift b/validation-test/compiler_crashers_fixed/27621-swift-getbuiltinvaluedecl.swift similarity index 82% rename from validation-test/compiler_crashers/27621-swift-getbuiltinvaluedecl.swift rename to validation-test/compiler_crashers_fixed/27621-swift-getbuiltinvaluedecl.swift index daf12d54a3bf3..45cc346c5ab49 100644 --- a/validation-test/compiler_crashers/27621-swift-getbuiltinvaluedecl.swift +++ b/validation-test/compiler_crashers_fixed/27621-swift-getbuiltinvaluedecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27622-swift-typebase-isemptyexistentialcomposition.swift b/validation-test/compiler_crashers_fixed/27622-swift-typebase-isemptyexistentialcomposition.swift similarity index 81% rename from validation-test/compiler_crashers/27622-swift-typebase-isemptyexistentialcomposition.swift rename to validation-test/compiler_crashers_fixed/27622-swift-typebase-isemptyexistentialcomposition.swift index b2a9caf00a607..6686a53e0a6b3 100644 --- a/validation-test/compiler_crashers/27622-swift-typebase-isemptyexistentialcomposition.swift +++ b/validation-test/compiler_crashers_fixed/27622-swift-typebase-isemptyexistentialcomposition.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27623-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/27623-swift-boundgenerictype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27623-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/27623-swift-boundgenerictype-get.swift index a5cda1ef2fe6f..b56c69ee69d40 100644 --- a/validation-test/compiler_crashers/27623-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/27623-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27624-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/27624-swift-typebase-isequal.swift similarity index 80% rename from validation-test/compiler_crashers/27624-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/27624-swift-typebase-isequal.swift index b4d4298893f07..217fe02c9433a 100644 --- a/validation-test/compiler_crashers/27624-swift-typebase-isequal.swift +++ b/validation-test/compiler_crashers_fixed/27624-swift-typebase-isequal.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27625-swift-typechecker-typecheckpattern.swift b/validation-test/compiler_crashers_fixed/27625-swift-typechecker-typecheckpattern.swift similarity index 82% rename from validation-test/compiler_crashers/27625-swift-typechecker-typecheckpattern.swift rename to validation-test/compiler_crashers_fixed/27625-swift-typechecker-typecheckpattern.swift index 86271edb48712..6a201aa1c11ac 100644 --- a/validation-test/compiler_crashers/27625-swift-typechecker-typecheckpattern.swift +++ b/validation-test/compiler_crashers_fixed/27625-swift-typechecker-typecheckpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27626-llvm-smdiagnostic-smdiagnostic.swift b/validation-test/compiler_crashers_fixed/27626-llvm-smdiagnostic-smdiagnostic.swift similarity index 79% rename from validation-test/compiler_crashers/27626-llvm-smdiagnostic-smdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27626-llvm-smdiagnostic-smdiagnostic.swift index c9f6c86120c03..d44959d864ed7 100644 --- a/validation-test/compiler_crashers/27626-llvm-smdiagnostic-smdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27626-llvm-smdiagnostic-smdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27627-swift-typechecker-checkdeclarationavailability.swift b/validation-test/compiler_crashers_fixed/27627-swift-typechecker-checkdeclarationavailability.swift similarity index 82% rename from validation-test/compiler_crashers/27627-swift-typechecker-checkdeclarationavailability.swift rename to validation-test/compiler_crashers_fixed/27627-swift-typechecker-checkdeclarationavailability.swift index 884c09b2003a2..041c9d2053dca 100644 --- a/validation-test/compiler_crashers/27627-swift-typechecker-checkdeclarationavailability.swift +++ b/validation-test/compiler_crashers_fixed/27627-swift-typechecker-checkdeclarationavailability.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27628-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/27628-swift-abstractclosureexpr-setparams.swift similarity index 97% rename from validation-test/compiler_crashers/27628-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/27628-swift-abstractclosureexpr-setparams.swift index 52f555701ef7b..9c26341bdc9e0 100644 --- a/validation-test/compiler_crashers/27628-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/27628-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27630-swift-scopeinfo-addtoscope.swift b/validation-test/compiler_crashers_fixed/27630-swift-scopeinfo-addtoscope.swift similarity index 81% rename from validation-test/compiler_crashers/27630-swift-scopeinfo-addtoscope.swift rename to validation-test/compiler_crashers_fixed/27630-swift-scopeinfo-addtoscope.swift index 5e4b981f9766f..fbbe09a667606 100644 --- a/validation-test/compiler_crashers/27630-swift-scopeinfo-addtoscope.swift +++ b/validation-test/compiler_crashers_fixed/27630-swift-scopeinfo-addtoscope.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27633-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27633-swift-inflightdiagnostic.swift similarity index 83% rename from validation-test/compiler_crashers/27633-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27633-swift-inflightdiagnostic.swift index b1a2d78e61c1b..c1b8083b30a8c 100644 --- a/validation-test/compiler_crashers/27633-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27633-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27634-swift-lexer-kindofidentifier.swift b/validation-test/compiler_crashers_fixed/27634-swift-lexer-kindofidentifier.swift similarity index 80% rename from validation-test/compiler_crashers/27634-swift-lexer-kindofidentifier.swift rename to validation-test/compiler_crashers_fixed/27634-swift-lexer-kindofidentifier.swift index 8a132e96011d3..8d6a058f77c52 100644 --- a/validation-test/compiler_crashers/27634-swift-lexer-kindofidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27634-swift-lexer-kindofidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27635-swift-protocoltype-canonicalizeprotocols.swift b/validation-test/compiler_crashers_fixed/27635-swift-protocoltype-canonicalizeprotocols.swift similarity index 82% rename from validation-test/compiler_crashers/27635-swift-protocoltype-canonicalizeprotocols.swift rename to validation-test/compiler_crashers_fixed/27635-swift-protocoltype-canonicalizeprotocols.swift index 972938796d257..5a842f885b838 100644 --- a/validation-test/compiler_crashers/27635-swift-protocoltype-canonicalizeprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27635-swift-protocoltype-canonicalizeprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27638-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/27638-swift-structtype-get.swift similarity index 83% rename from validation-test/compiler_crashers/27638-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/27638-swift-structtype-get.swift index 4b1daae5247d1..84ab2860cb7b5 100644 --- a/validation-test/compiler_crashers/27638-swift-structtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27638-swift-structtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27639-swift-enumtype-get.swift b/validation-test/compiler_crashers_fixed/27639-swift-enumtype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27639-swift-enumtype-get.swift rename to validation-test/compiler_crashers_fixed/27639-swift-enumtype-get.swift index bc2a2cd508d70..1cc2e41a1a764 100644 --- a/validation-test/compiler_crashers/27639-swift-enumtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27639-swift-enumtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27640-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/27640-swift-functiontype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27640-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/27640-swift-functiontype-get.swift index 1eb7a04ce4dde..9e059ee56c823 100644 --- a/validation-test/compiler_crashers/27640-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27640-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27641-swift-parser-parseexprpostfix.swift b/validation-test/compiler_crashers_fixed/27641-swift-parser-parseexprpostfix.swift similarity index 82% rename from validation-test/compiler_crashers/27641-swift-parser-parseexprpostfix.swift rename to validation-test/compiler_crashers_fixed/27641-swift-parser-parseexprpostfix.swift index 18c463b634ec9..7dcfb178d24dd 100644 --- a/validation-test/compiler_crashers/27641-swift-parser-parseexprpostfix.swift +++ b/validation-test/compiler_crashers_fixed/27641-swift-parser-parseexprpostfix.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27642-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27642-swift-inflightdiagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/27642-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27642-swift-inflightdiagnostic.swift index f74e8e02a6dbe..d929348b1aa59 100644 --- a/validation-test/compiler_crashers/27642-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27642-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27643-swift-valuedecl-settype.swift b/validation-test/compiler_crashers_fixed/27643-swift-valuedecl-settype.swift similarity index 80% rename from validation-test/compiler_crashers/27643-swift-valuedecl-settype.swift rename to validation-test/compiler_crashers_fixed/27643-swift-valuedecl-settype.swift index ebc9a9d09797e..ab3c1707a836f 100644 --- a/validation-test/compiler_crashers/27643-swift-valuedecl-settype.swift +++ b/validation-test/compiler_crashers_fixed/27643-swift-valuedecl-settype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27644-llvm-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/27644-llvm-optional-swift-diagnostic-operator.swift similarity index 81% rename from validation-test/compiler_crashers/27644-llvm-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/27644-llvm-optional-swift-diagnostic-operator.swift index f1bd036e624f8..b438fe5d20952 100644 --- a/validation-test/compiler_crashers/27644-llvm-optional-swift-diagnostic-operator.swift +++ b/validation-test/compiler_crashers_fixed/27644-llvm-optional-swift-diagnostic-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27645-swift-typechecker-lookupunqualified.swift b/validation-test/compiler_crashers_fixed/27645-swift-typechecker-lookupunqualified.swift similarity index 82% rename from validation-test/compiler_crashers/27645-swift-typechecker-lookupunqualified.swift rename to validation-test/compiler_crashers_fixed/27645-swift-typechecker-lookupunqualified.swift index bbb4d2e54d577..7583d29135083 100644 --- a/validation-test/compiler_crashers/27645-swift-typechecker-lookupunqualified.swift +++ b/validation-test/compiler_crashers_fixed/27645-swift-typechecker-lookupunqualified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27646-swift-markasobjc.swift b/validation-test/compiler_crashers_fixed/27646-swift-markasobjc.swift similarity index 81% rename from validation-test/compiler_crashers/27646-swift-markasobjc.swift rename to validation-test/compiler_crashers_fixed/27646-swift-markasobjc.swift index 36e2d9945612a..b19295754f8f6 100644 --- a/validation-test/compiler_crashers/27646-swift-markasobjc.swift +++ b/validation-test/compiler_crashers_fixed/27646-swift-markasobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27647-swift-tuplepattern-createsimple.swift b/validation-test/compiler_crashers_fixed/27647-swift-tuplepattern-createsimple.swift similarity index 83% rename from validation-test/compiler_crashers/27647-swift-tuplepattern-createsimple.swift rename to validation-test/compiler_crashers_fixed/27647-swift-tuplepattern-createsimple.swift index 88a8141f54c6d..0fce7370a71f0 100644 --- a/validation-test/compiler_crashers/27647-swift-tuplepattern-createsimple.swift +++ b/validation-test/compiler_crashers_fixed/27647-swift-tuplepattern-createsimple.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27648-llvm-smallvectorimpl-swift-decl-insert.swift b/validation-test/compiler_crashers_fixed/27648-llvm-smallvectorimpl-swift-decl-insert.swift similarity index 84% rename from validation-test/compiler_crashers/27648-llvm-smallvectorimpl-swift-decl-insert.swift rename to validation-test/compiler_crashers_fixed/27648-llvm-smallvectorimpl-swift-decl-insert.swift index bb7520c77843a..d45ad7274f673 100644 --- a/validation-test/compiler_crashers/27648-llvm-smallvectorimpl-swift-decl-insert.swift +++ b/validation-test/compiler_crashers_fixed/27648-llvm-smallvectorimpl-swift-decl-insert.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27649-swift-constraints-constraintsystem-finalize.swift b/validation-test/compiler_crashers_fixed/27649-swift-constraints-constraintsystem-finalize.swift similarity index 82% rename from validation-test/compiler_crashers/27649-swift-constraints-constraintsystem-finalize.swift rename to validation-test/compiler_crashers_fixed/27649-swift-constraints-constraintsystem-finalize.swift index fa16b7fe4d1ce..75b571623a4e9 100644 --- a/validation-test/compiler_crashers/27649-swift-constraints-constraintsystem-finalize.swift +++ b/validation-test/compiler_crashers_fixed/27649-swift-constraints-constraintsystem-finalize.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27650-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/27650-swift-metatypetype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27650-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27650-swift-metatypetype-get.swift index 4669e2a6d3307..4645adc751245 100644 --- a/validation-test/compiler_crashers/27650-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27650-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27651-swift-genericparamlist-deriveallarchetypes.swift b/validation-test/compiler_crashers_fixed/27651-swift-genericparamlist-deriveallarchetypes.swift similarity index 81% rename from validation-test/compiler_crashers/27651-swift-genericparamlist-deriveallarchetypes.swift rename to validation-test/compiler_crashers_fixed/27651-swift-genericparamlist-deriveallarchetypes.swift index f24a4ffebadda..c402ecdbbab9e 100644 --- a/validation-test/compiler_crashers/27651-swift-genericparamlist-deriveallarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27651-swift-genericparamlist-deriveallarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27652-swift-typechecker-checkdeclattributes.swift b/validation-test/compiler_crashers_fixed/27652-swift-typechecker-checkdeclattributes.swift similarity index 83% rename from validation-test/compiler_crashers/27652-swift-typechecker-checkdeclattributes.swift rename to validation-test/compiler_crashers_fixed/27652-swift-typechecker-checkdeclattributes.swift index 600380439d253..7846781545f5d 100644 --- a/validation-test/compiler_crashers/27652-swift-typechecker-checkdeclattributes.swift +++ b/validation-test/compiler_crashers_fixed/27652-swift-typechecker-checkdeclattributes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27653-swift-archetypebuilder-getallarchetypes.swift b/validation-test/compiler_crashers_fixed/27653-swift-archetypebuilder-getallarchetypes.swift similarity index 79% rename from validation-test/compiler_crashers/27653-swift-archetypebuilder-getallarchetypes.swift rename to validation-test/compiler_crashers_fixed/27653-swift-archetypebuilder-getallarchetypes.swift index 8efa1dde7df3a..7c8f219251df9 100644 --- a/validation-test/compiler_crashers/27653-swift-archetypebuilder-getallarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27653-swift-archetypebuilder-getallarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27654-swift-streamprinter-printtext.swift b/validation-test/compiler_crashers_fixed/27654-swift-streamprinter-printtext.swift similarity index 84% rename from validation-test/compiler_crashers/27654-swift-streamprinter-printtext.swift rename to validation-test/compiler_crashers_fixed/27654-swift-streamprinter-printtext.swift index a296a95ef548d..c9b384c81e2ca 100644 --- a/validation-test/compiler_crashers/27654-swift-streamprinter-printtext.swift +++ b/validation-test/compiler_crashers_fixed/27654-swift-streamprinter-printtext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27655-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/27655-swift-constraints-solution-solution.swift similarity index 81% rename from validation-test/compiler_crashers/27655-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/27655-swift-constraints-solution-solution.swift index e102e4986ea6f..d05c11eb18a58 100644 --- a/validation-test/compiler_crashers/27655-swift-constraints-solution-solution.swift +++ b/validation-test/compiler_crashers_fixed/27655-swift-constraints-solution-solution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27656-swift-abstractfunctiondecl-getobjcselector.swift b/validation-test/compiler_crashers_fixed/27656-swift-abstractfunctiondecl-getobjcselector.swift similarity index 85% rename from validation-test/compiler_crashers/27656-swift-abstractfunctiondecl-getobjcselector.swift rename to validation-test/compiler_crashers_fixed/27656-swift-abstractfunctiondecl-getobjcselector.swift index 202da98fb1bdf..ee0f67c3d8b6b 100644 --- a/validation-test/compiler_crashers/27656-swift-abstractfunctiondecl-getobjcselector.swift +++ b/validation-test/compiler_crashers_fixed/27656-swift-abstractfunctiondecl-getobjcselector.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27657-llvm-foldingset-swift-boundgenerictype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27657-llvm-foldingset-swift-boundgenerictype-nodeequals.swift similarity index 83% rename from validation-test/compiler_crashers/27657-llvm-foldingset-swift-boundgenerictype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27657-llvm-foldingset-swift-boundgenerictype-nodeequals.swift index 8b6180deef53d..33f6e094af867 100644 --- a/validation-test/compiler_crashers/27657-llvm-foldingset-swift-boundgenerictype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27657-llvm-foldingset-swift-boundgenerictype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27658-swift-constraints-constraintgraph-removeconstraint.swift b/validation-test/compiler_crashers_fixed/27658-swift-constraints-constraintgraph-removeconstraint.swift similarity index 81% rename from validation-test/compiler_crashers/27658-swift-constraints-constraintgraph-removeconstraint.swift rename to validation-test/compiler_crashers_fixed/27658-swift-constraints-constraintgraph-removeconstraint.swift index d98d512faad88..0ea717a224438 100644 --- a/validation-test/compiler_crashers/27658-swift-constraints-constraintgraph-removeconstraint.swift +++ b/validation-test/compiler_crashers_fixed/27658-swift-constraints-constraintgraph-removeconstraint.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27659-swift-parser-parsedeclclass.swift b/validation-test/compiler_crashers_fixed/27659-swift-parser-parsedeclclass.swift similarity index 83% rename from validation-test/compiler_crashers/27659-swift-parser-parsedeclclass.swift rename to validation-test/compiler_crashers_fixed/27659-swift-parser-parsedeclclass.swift index 35b132a43f30b..c7569cc9c5543 100644 --- a/validation-test/compiler_crashers/27659-swift-parser-parsedeclclass.swift +++ b/validation-test/compiler_crashers_fixed/27659-swift-parser-parsedeclclass.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27661-std-function-func-swift-constraints-constraintsystem-simplifytype.swift b/validation-test/compiler_crashers_fixed/27661-std-function-func-swift-constraints-constraintsystem-simplifytype.swift similarity index 79% rename from validation-test/compiler_crashers/27661-std-function-func-swift-constraints-constraintsystem-simplifytype.swift rename to validation-test/compiler_crashers_fixed/27661-std-function-func-swift-constraints-constraintsystem-simplifytype.swift index a3f347aef1847..a2d8934835697 100644 --- a/validation-test/compiler_crashers/27661-std-function-func-swift-constraints-constraintsystem-simplifytype.swift +++ b/validation-test/compiler_crashers_fixed/27661-std-function-func-swift-constraints-constraintsystem-simplifytype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27662-swift-valuedecl-settype.swift b/validation-test/compiler_crashers_fixed/27662-swift-valuedecl-settype.swift similarity index 81% rename from validation-test/compiler_crashers/27662-swift-valuedecl-settype.swift rename to validation-test/compiler_crashers_fixed/27662-swift-valuedecl-settype.swift index 40be7f905dcaa..b672ca1cd4e12 100644 --- a/validation-test/compiler_crashers/27662-swift-valuedecl-settype.swift +++ b/validation-test/compiler_crashers_fixed/27662-swift-valuedecl-settype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27663-swift-nominaltypedecl-prepareextensions.swift b/validation-test/compiler_crashers_fixed/27663-swift-nominaltypedecl-prepareextensions.swift similarity index 81% rename from validation-test/compiler_crashers/27663-swift-nominaltypedecl-prepareextensions.swift rename to validation-test/compiler_crashers_fixed/27663-swift-nominaltypedecl-prepareextensions.swift index 4e4606e722113..8580c16d1ae3d 100644 --- a/validation-test/compiler_crashers/27663-swift-nominaltypedecl-prepareextensions.swift +++ b/validation-test/compiler_crashers_fixed/27663-swift-nominaltypedecl-prepareextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27664-swift-nominaltypedecl-prepareextensions.swift b/validation-test/compiler_crashers_fixed/27664-swift-nominaltypedecl-prepareextensions.swift similarity index 82% rename from validation-test/compiler_crashers/27664-swift-nominaltypedecl-prepareextensions.swift rename to validation-test/compiler_crashers_fixed/27664-swift-nominaltypedecl-prepareextensions.swift index c946806173978..7a435fb71e92d 100644 --- a/validation-test/compiler_crashers/27664-swift-nominaltypedecl-prepareextensions.swift +++ b/validation-test/compiler_crashers_fixed/27664-swift-nominaltypedecl-prepareextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27665-swift-conformancelookuptable-getallprotocols.swift b/validation-test/compiler_crashers_fixed/27665-swift-conformancelookuptable-getallprotocols.swift similarity index 81% rename from validation-test/compiler_crashers/27665-swift-conformancelookuptable-getallprotocols.swift rename to validation-test/compiler_crashers_fixed/27665-swift-conformancelookuptable-getallprotocols.swift index e64c735e801f6..a328bd5d75520 100644 --- a/validation-test/compiler_crashers/27665-swift-conformancelookuptable-getallprotocols.swift +++ b/validation-test/compiler_crashers_fixed/27665-swift-conformancelookuptable-getallprotocols.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27666-swift-modulefile-loadextensions.swift b/validation-test/compiler_crashers_fixed/27666-swift-modulefile-loadextensions.swift similarity index 81% rename from validation-test/compiler_crashers/27666-swift-modulefile-loadextensions.swift rename to validation-test/compiler_crashers_fixed/27666-swift-modulefile-loadextensions.swift index 33d5fb9342793..7ed0375fa1ca2 100644 --- a/validation-test/compiler_crashers/27666-swift-modulefile-loadextensions.swift +++ b/validation-test/compiler_crashers_fixed/27666-swift-modulefile-loadextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27667-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/27667-swift-modulefile-getdecl.swift similarity index 80% rename from validation-test/compiler_crashers/27667-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/27667-swift-modulefile-getdecl.swift index 67fe366b7ca30..045476fb45a6a 100644 --- a/validation-test/compiler_crashers/27667-swift-modulefile-getdecl.swift +++ b/validation-test/compiler_crashers_fixed/27667-swift-modulefile-getdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27668-swift-boundgenerictype-get.swift b/validation-test/compiler_crashers_fixed/27668-swift-boundgenerictype-get.swift similarity index 80% rename from validation-test/compiler_crashers/27668-swift-boundgenerictype-get.swift rename to validation-test/compiler_crashers_fixed/27668-swift-boundgenerictype-get.swift index 84703711e8c4e..96c905407a3a4 100644 --- a/validation-test/compiler_crashers/27668-swift-boundgenerictype-get.swift +++ b/validation-test/compiler_crashers_fixed/27668-swift-boundgenerictype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27669-swift-parser-skipsingle.swift b/validation-test/compiler_crashers_fixed/27669-swift-parser-skipsingle.swift similarity index 83% rename from validation-test/compiler_crashers/27669-swift-parser-skipsingle.swift rename to validation-test/compiler_crashers_fixed/27669-swift-parser-skipsingle.swift index da50f82cfbe36..aba6ef01e3a12 100644 --- a/validation-test/compiler_crashers/27669-swift-parser-skipsingle.swift +++ b/validation-test/compiler_crashers_fixed/27669-swift-parser-skipsingle.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27670-swift-unqualifiedlookup-unqualifiedlookup.swift b/validation-test/compiler_crashers_fixed/27670-swift-unqualifiedlookup-unqualifiedlookup.swift similarity index 79% rename from validation-test/compiler_crashers/27670-swift-unqualifiedlookup-unqualifiedlookup.swift rename to validation-test/compiler_crashers_fixed/27670-swift-unqualifiedlookup-unqualifiedlookup.swift index 73215dd4f190a..a05bc42c01f89 100644 --- a/validation-test/compiler_crashers/27670-swift-unqualifiedlookup-unqualifiedlookup.swift +++ b/validation-test/compiler_crashers_fixed/27670-swift-unqualifiedlookup-unqualifiedlookup.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27671-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift b/validation-test/compiler_crashers_fixed/27671-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift similarity index 83% rename from validation-test/compiler_crashers/27671-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift rename to validation-test/compiler_crashers_fixed/27671-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift index 86ab05ba6f6f0..06149fd6e55aa 100644 --- a/validation-test/compiler_crashers/27671-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift +++ b/validation-test/compiler_crashers_fixed/27671-llvm-smallvectorimpl-swift-diagnosticargument-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27673-swift-parser-parseidentifier.swift b/validation-test/compiler_crashers_fixed/27673-swift-parser-parseidentifier.swift similarity index 79% rename from validation-test/compiler_crashers/27673-swift-parser-parseidentifier.swift rename to validation-test/compiler_crashers_fixed/27673-swift-parser-parseidentifier.swift index 87a0c094f18c1..c49ad6f3ceba8 100644 --- a/validation-test/compiler_crashers/27673-swift-parser-parseidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27673-swift-parser-parseidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27674-swift-extensiondecl-getmembers.swift b/validation-test/compiler_crashers_fixed/27674-swift-extensiondecl-getmembers.swift similarity index 83% rename from validation-test/compiler_crashers/27674-swift-extensiondecl-getmembers.swift rename to validation-test/compiler_crashers_fixed/27674-swift-extensiondecl-getmembers.swift index e98b2cfb388e6..b7cfdfea5afba 100644 --- a/validation-test/compiler_crashers/27674-swift-extensiondecl-getmembers.swift +++ b/validation-test/compiler_crashers_fixed/27674-swift-extensiondecl-getmembers.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27676-swift-moduledecl-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27676-swift-moduledecl-lookupvalue.swift similarity index 80% rename from validation-test/compiler_crashers/27676-swift-moduledecl-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27676-swift-moduledecl-lookupvalue.swift index 0f858bf793706..d83a855d25307 100644 --- a/validation-test/compiler_crashers/27676-swift-moduledecl-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27676-swift-moduledecl-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27678-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27678-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 80% rename from validation-test/compiler_crashers/27678-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27678-swift-printingdiagnosticconsumer-handlediagnostic.swift index 65254a6f96a12..59d34692e0e89 100644 --- a/validation-test/compiler_crashers/27678-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27678-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27679-swift-constraints-constraintsystem-solverstate-solverstate.swift b/validation-test/compiler_crashers_fixed/27679-swift-constraints-constraintsystem-solverstate-solverstate.swift similarity index 82% rename from validation-test/compiler_crashers/27679-swift-constraints-constraintsystem-solverstate-solverstate.swift rename to validation-test/compiler_crashers_fixed/27679-swift-constraints-constraintsystem-solverstate-solverstate.swift index b24752bae0694..757cdf06af861 100644 --- a/validation-test/compiler_crashers/27679-swift-constraints-constraintsystem-solverstate-solverstate.swift +++ b/validation-test/compiler_crashers_fixed/27679-swift-constraints-constraintsystem-solverstate-solverstate.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27681-swift-constraints-constraintsystem-assignfixedtype.swift b/validation-test/compiler_crashers_fixed/27681-swift-constraints-constraintsystem-assignfixedtype.swift similarity index 80% rename from validation-test/compiler_crashers/27681-swift-constraints-constraintsystem-assignfixedtype.swift rename to validation-test/compiler_crashers_fixed/27681-swift-constraints-constraintsystem-assignfixedtype.swift index cb8a862df1055..9754f68c768f3 100644 --- a/validation-test/compiler_crashers/27681-swift-constraints-constraintsystem-assignfixedtype.swift +++ b/validation-test/compiler_crashers_fixed/27681-swift-constraints-constraintsystem-assignfixedtype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27682-swift-removeshadoweddecls.swift b/validation-test/compiler_crashers_fixed/27682-swift-removeshadoweddecls.swift similarity index 82% rename from validation-test/compiler_crashers/27682-swift-removeshadoweddecls.swift rename to validation-test/compiler_crashers_fixed/27682-swift-removeshadoweddecls.swift index 1626e86c6b621..aebb77adc7095 100644 --- a/validation-test/compiler_crashers/27682-swift-removeshadoweddecls.swift +++ b/validation-test/compiler_crashers_fixed/27682-swift-removeshadoweddecls.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27683-swift-tuplepattern-create.swift b/validation-test/compiler_crashers_fixed/27683-swift-tuplepattern-create.swift similarity index 82% rename from validation-test/compiler_crashers/27683-swift-tuplepattern-create.swift rename to validation-test/compiler_crashers_fixed/27683-swift-tuplepattern-create.swift index ed2fe9174d62f..ca10f1e019091 100644 --- a/validation-test/compiler_crashers/27683-swift-tuplepattern-create.swift +++ b/validation-test/compiler_crashers_fixed/27683-swift-tuplepattern-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27684-swift-constraints-constraintsystem-getalternativeliteraltypes.swift b/validation-test/compiler_crashers_fixed/27684-swift-constraints-constraintsystem-getalternativeliteraltypes.swift similarity index 81% rename from validation-test/compiler_crashers/27684-swift-constraints-constraintsystem-getalternativeliteraltypes.swift rename to validation-test/compiler_crashers_fixed/27684-swift-constraints-constraintsystem-getalternativeliteraltypes.swift index 5f7f04fc70e63..ba93a2bd03d2a 100644 --- a/validation-test/compiler_crashers/27684-swift-constraints-constraintsystem-getalternativeliteraltypes.swift +++ b/validation-test/compiler_crashers_fixed/27684-swift-constraints-constraintsystem-getalternativeliteraltypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27686-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/27686-swift-conformancelookuptable-updatelookuptable.swift similarity index 81% rename from validation-test/compiler_crashers/27686-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/27686-swift-conformancelookuptable-updatelookuptable.swift index ccf4ea1b5a24c..3e62bf7100e7e 100644 --- a/validation-test/compiler_crashers/27686-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27686-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27687-swift-classtype-get.swift b/validation-test/compiler_crashers_fixed/27687-swift-classtype-get.swift similarity index 83% rename from validation-test/compiler_crashers/27687-swift-classtype-get.swift rename to validation-test/compiler_crashers_fixed/27687-swift-classtype-get.swift index 1d22dd6ad9278..546a0655be196 100644 --- a/validation-test/compiler_crashers/27687-swift-classtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27687-swift-classtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27688-swift-vardecl-isanonclosureparam.swift b/validation-test/compiler_crashers_fixed/27688-swift-vardecl-isanonclosureparam.swift similarity index 83% rename from validation-test/compiler_crashers/27688-swift-vardecl-isanonclosureparam.swift rename to validation-test/compiler_crashers_fixed/27688-swift-vardecl-isanonclosureparam.swift index 1fbe796714ce6..e96aa96a2f040 100644 --- a/validation-test/compiler_crashers/27688-swift-vardecl-isanonclosureparam.swift +++ b/validation-test/compiler_crashers_fixed/27688-swift-vardecl-isanonclosureparam.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27689-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift b/validation-test/compiler_crashers_fixed/27689-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift similarity index 84% rename from validation-test/compiler_crashers/27689-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift rename to validation-test/compiler_crashers_fixed/27689-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift index b812047dcf8b6..60c58e4e3f7a6 100644 --- a/validation-test/compiler_crashers/27689-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift +++ b/validation-test/compiler_crashers_fixed/27689-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27690-swift-typechecker-substituteinputsugartypeforresult.swift b/validation-test/compiler_crashers_fixed/27690-swift-typechecker-substituteinputsugartypeforresult.swift similarity index 83% rename from validation-test/compiler_crashers/27690-swift-typechecker-substituteinputsugartypeforresult.swift rename to validation-test/compiler_crashers_fixed/27690-swift-typechecker-substituteinputsugartypeforresult.swift index 93b979d7299b8..1f54ece907bef 100644 --- a/validation-test/compiler_crashers/27690-swift-typechecker-substituteinputsugartypeforresult.swift +++ b/validation-test/compiler_crashers_fixed/27690-swift-typechecker-substituteinputsugartypeforresult.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27692-swift-constraints-simplifylocator.swift b/validation-test/compiler_crashers_fixed/27692-swift-constraints-simplifylocator.swift similarity index 83% rename from validation-test/compiler_crashers/27692-swift-constraints-simplifylocator.swift rename to validation-test/compiler_crashers_fixed/27692-swift-constraints-simplifylocator.swift index 9006d045ddae4..c49c7e2c57b52 100644 --- a/validation-test/compiler_crashers/27692-swift-constraints-simplifylocator.swift +++ b/validation-test/compiler_crashers_fixed/27692-swift-constraints-simplifylocator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27694-swift-nominaltypedecl-preparelookuptable.swift b/validation-test/compiler_crashers_fixed/27694-swift-nominaltypedecl-preparelookuptable.swift similarity index 82% rename from validation-test/compiler_crashers/27694-swift-nominaltypedecl-preparelookuptable.swift rename to validation-test/compiler_crashers_fixed/27694-swift-nominaltypedecl-preparelookuptable.swift index d146195ee4ca0..4aa0f44763045 100644 --- a/validation-test/compiler_crashers/27694-swift-nominaltypedecl-preparelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27694-swift-nominaltypedecl-preparelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27695-swift-constraints-constraintsystem-performmemberlookup.swift b/validation-test/compiler_crashers_fixed/27695-swift-constraints-constraintsystem-performmemberlookup.swift similarity index 83% rename from validation-test/compiler_crashers/27695-swift-constraints-constraintsystem-performmemberlookup.swift rename to validation-test/compiler_crashers_fixed/27695-swift-constraints-constraintsystem-performmemberlookup.swift index f1514dfbf4507..61b5d4b8ff9ac 100644 --- a/validation-test/compiler_crashers/27695-swift-constraints-constraintsystem-performmemberlookup.swift +++ b/validation-test/compiler_crashers_fixed/27695-swift-constraints-constraintsystem-performmemberlookup.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27696-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/27696-swift-constraints-constraintsystem-matchtypes.swift similarity index 82% rename from validation-test/compiler_crashers/27696-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/27696-swift-constraints-constraintsystem-matchtypes.swift index 3519470c4e604..64f859454354f 100644 --- a/validation-test/compiler_crashers/27696-swift-constraints-constraintsystem-matchtypes.swift +++ b/validation-test/compiler_crashers_fixed/27696-swift-constraints-constraintsystem-matchtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27697-std-function-func-setboundvarstypeerror.swift b/validation-test/compiler_crashers_fixed/27697-std-function-func-setboundvarstypeerror.swift similarity index 81% rename from validation-test/compiler_crashers/27697-std-function-func-setboundvarstypeerror.swift rename to validation-test/compiler_crashers_fixed/27697-std-function-func-setboundvarstypeerror.swift index 6c81b2eb679c7..abd93f1025dcc 100644 --- a/validation-test/compiler_crashers/27697-std-function-func-setboundvarstypeerror.swift +++ b/validation-test/compiler_crashers_fixed/27697-std-function-func-setboundvarstypeerror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27698-swift-parser-parseexprimpl.swift b/validation-test/compiler_crashers_fixed/27698-swift-parser-parseexprimpl.swift similarity index 83% rename from validation-test/compiler_crashers/27698-swift-parser-parseexprimpl.swift rename to validation-test/compiler_crashers_fixed/27698-swift-parser-parseexprimpl.swift index f6de945a4d5c3..83350a95b0a0e 100644 --- a/validation-test/compiler_crashers/27698-swift-parser-parseexprimpl.swift +++ b/validation-test/compiler_crashers_fixed/27698-swift-parser-parseexprimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27699-swift-typebase-isemptyexistentialcomposition.swift b/validation-test/compiler_crashers_fixed/27699-swift-typebase-isemptyexistentialcomposition.swift similarity index 80% rename from validation-test/compiler_crashers/27699-swift-typebase-isemptyexistentialcomposition.swift rename to validation-test/compiler_crashers_fixed/27699-swift-typebase-isemptyexistentialcomposition.swift index a416cb8a3c410..761ee8fd54cc2 100644 --- a/validation-test/compiler_crashers/27699-swift-typebase-isemptyexistentialcomposition.swift +++ b/validation-test/compiler_crashers_fixed/27699-swift-typebase-isemptyexistentialcomposition.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27701-swift-getllvmintrinsicid.swift b/validation-test/compiler_crashers_fixed/27701-swift-getllvmintrinsicid.swift similarity index 84% rename from validation-test/compiler_crashers/27701-swift-getllvmintrinsicid.swift rename to validation-test/compiler_crashers_fixed/27701-swift-getllvmintrinsicid.swift index 9f0b328ab863f..3ce1f1cf4a69a 100644 --- a/validation-test/compiler_crashers/27701-swift-getllvmintrinsicid.swift +++ b/validation-test/compiler_crashers_fixed/27701-swift-getllvmintrinsicid.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27702-swift-conformancelookuptable-resolveconformances.swift b/validation-test/compiler_crashers_fixed/27702-swift-conformancelookuptable-resolveconformances.swift similarity index 79% rename from validation-test/compiler_crashers/27702-swift-conformancelookuptable-resolveconformances.swift rename to validation-test/compiler_crashers_fixed/27702-swift-conformancelookuptable-resolveconformances.swift index 251aa8bf409e4..6857fbdc0e454 100644 --- a/validation-test/compiler_crashers/27702-swift-conformancelookuptable-resolveconformances.swift +++ b/validation-test/compiler_crashers_fixed/27702-swift-conformancelookuptable-resolveconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27703-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/27703-swift-astprinter-printtextimpl.swift similarity index 82% rename from validation-test/compiler_crashers/27703-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/27703-swift-astprinter-printtextimpl.swift index 463210e330a8a..1fad1312f8a6f 100644 --- a/validation-test/compiler_crashers/27703-swift-astprinter-printtextimpl.swift +++ b/validation-test/compiler_crashers_fixed/27703-swift-astprinter-printtextimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27704-swift-modulefile-declcommenttableinfo-readdata.swift b/validation-test/compiler_crashers_fixed/27704-swift-modulefile-declcommenttableinfo-readdata.swift similarity index 83% rename from validation-test/compiler_crashers/27704-swift-modulefile-declcommenttableinfo-readdata.swift rename to validation-test/compiler_crashers_fixed/27704-swift-modulefile-declcommenttableinfo-readdata.swift index 176c3bf92316c..d6c6eaeba5463 100644 --- a/validation-test/compiler_crashers/27704-swift-modulefile-declcommenttableinfo-readdata.swift +++ b/validation-test/compiler_crashers_fixed/27704-swift-modulefile-declcommenttableinfo-readdata.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27705-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/27705-swift-lexer-getlocforendoftoken.swift similarity index 80% rename from validation-test/compiler_crashers/27705-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/27705-swift-lexer-getlocforendoftoken.swift index 8729fa5560b8d..ed54520f7b8d9 100644 --- a/validation-test/compiler_crashers/27705-swift-lexer-getlocforendoftoken.swift +++ b/validation-test/compiler_crashers_fixed/27705-swift-lexer-getlocforendoftoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27706-swift-availabilityinference-applyinferredavailableattrs.swift b/validation-test/compiler_crashers_fixed/27706-swift-availabilityinference-applyinferredavailableattrs.swift similarity index 83% rename from validation-test/compiler_crashers/27706-swift-availabilityinference-applyinferredavailableattrs.swift rename to validation-test/compiler_crashers_fixed/27706-swift-availabilityinference-applyinferredavailableattrs.swift index 6073ad7b67c7e..909460b2e63f6 100644 --- a/validation-test/compiler_crashers/27706-swift-availabilityinference-applyinferredavailableattrs.swift +++ b/validation-test/compiler_crashers_fixed/27706-swift-availabilityinference-applyinferredavailableattrs.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27707-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/27707-swift-typebase-getcanonicaltype.swift similarity index 82% rename from validation-test/compiler_crashers/27707-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/27707-swift-typebase-getcanonicaltype.swift index 4a6cdbd06467c..89ce2a9ecdae5 100644 --- a/validation-test/compiler_crashers/27707-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/27707-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27708-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/27708-swift-constraints-solution-solution.swift similarity index 82% rename from validation-test/compiler_crashers/27708-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/27708-swift-constraints-solution-solution.swift index b006b46b6f907..931ac57746324 100644 --- a/validation-test/compiler_crashers/27708-swift-constraints-solution-solution.swift +++ b/validation-test/compiler_crashers_fixed/27708-swift-constraints-solution-solution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27709-swift-removeshadoweddecls.swift b/validation-test/compiler_crashers_fixed/27709-swift-removeshadoweddecls.swift similarity index 80% rename from validation-test/compiler_crashers/27709-swift-removeshadoweddecls.swift rename to validation-test/compiler_crashers_fixed/27709-swift-removeshadoweddecls.swift index a280860467313..dc9420171bf6b 100644 --- a/validation-test/compiler_crashers/27709-swift-removeshadoweddecls.swift +++ b/validation-test/compiler_crashers_fixed/27709-swift-removeshadoweddecls.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27710-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/27710-swift-lexer-getlocforendoftoken.swift similarity index 78% rename from validation-test/compiler_crashers/27710-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/27710-swift-lexer-getlocforendoftoken.swift index b5438a9c810bf..ca43c14529198 100644 --- a/validation-test/compiler_crashers/27710-swift-lexer-getlocforendoftoken.swift +++ b/validation-test/compiler_crashers_fixed/27710-swift-lexer-getlocforendoftoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27711-swift-declcontext-getlocalconformances.swift b/validation-test/compiler_crashers_fixed/27711-swift-declcontext-getlocalconformances.swift similarity index 83% rename from validation-test/compiler_crashers/27711-swift-declcontext-getlocalconformances.swift rename to validation-test/compiler_crashers_fixed/27711-swift-declcontext-getlocalconformances.swift index d500001af8c38..f0af13ac00bea 100644 --- a/validation-test/compiler_crashers/27711-swift-declcontext-getlocalconformances.swift +++ b/validation-test/compiler_crashers_fixed/27711-swift-declcontext-getlocalconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27712-swift-constraints-constraintsystem-solvesimplified.swift b/validation-test/compiler_crashers_fixed/27712-swift-constraints-constraintsystem-solvesimplified.swift similarity index 82% rename from validation-test/compiler_crashers/27712-swift-constraints-constraintsystem-solvesimplified.swift rename to validation-test/compiler_crashers_fixed/27712-swift-constraints-constraintsystem-solvesimplified.swift index 791db3089fdab..20c51c3f15873 100644 --- a/validation-test/compiler_crashers/27712-swift-constraints-constraintsystem-solvesimplified.swift +++ b/validation-test/compiler_crashers_fixed/27712-swift-constraints-constraintsystem-solvesimplified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27713-swift-constraints-constraintgraph-gatherconstraints.swift b/validation-test/compiler_crashers_fixed/27713-swift-constraints-constraintgraph-gatherconstraints.swift similarity index 86% rename from validation-test/compiler_crashers/27713-swift-constraints-constraintgraph-gatherconstraints.swift rename to validation-test/compiler_crashers_fixed/27713-swift-constraints-constraintgraph-gatherconstraints.swift index 6ddbcebdcdb38..dc35181eef177 100644 --- a/validation-test/compiler_crashers/27713-swift-constraints-constraintgraph-gatherconstraints.swift +++ b/validation-test/compiler_crashers_fixed/27713-swift-constraints-constraintgraph-gatherconstraints.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27714-llvm-optional-swift-diagnostic-operator.swift b/validation-test/compiler_crashers_fixed/27714-llvm-optional-swift-diagnostic-operator.swift similarity index 81% rename from validation-test/compiler_crashers/27714-llvm-optional-swift-diagnostic-operator.swift rename to validation-test/compiler_crashers_fixed/27714-llvm-optional-swift-diagnostic-operator.swift index 0597138ef7c91..efba886477fb4 100644 --- a/validation-test/compiler_crashers/27714-llvm-optional-swift-diagnostic-operator.swift +++ b/validation-test/compiler_crashers_fixed/27714-llvm-optional-swift-diagnostic-operator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27716-swift-lexer-getlocforendoftoken.swift b/validation-test/compiler_crashers_fixed/27716-swift-lexer-getlocforendoftoken.swift similarity index 79% rename from validation-test/compiler_crashers/27716-swift-lexer-getlocforendoftoken.swift rename to validation-test/compiler_crashers_fixed/27716-swift-lexer-getlocforendoftoken.swift index 818b3b5fe9412..18ae2c130104f 100644 --- a/validation-test/compiler_crashers/27716-swift-lexer-getlocforendoftoken.swift +++ b/validation-test/compiler_crashers_fixed/27716-swift-lexer-getlocforendoftoken.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27717-swift-constraints-constraintsystem-matchtypes.swift b/validation-test/compiler_crashers_fixed/27717-swift-constraints-constraintsystem-matchtypes.swift similarity index 82% rename from validation-test/compiler_crashers/27717-swift-constraints-constraintsystem-matchtypes.swift rename to validation-test/compiler_crashers_fixed/27717-swift-constraints-constraintsystem-matchtypes.swift index 43cfb598c890e..30d3d61950597 100644 --- a/validation-test/compiler_crashers/27717-swift-constraints-constraintsystem-matchtypes.swift +++ b/validation-test/compiler_crashers_fixed/27717-swift-constraints-constraintsystem-matchtypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27718-swift-parser-parseidentifier.swift b/validation-test/compiler_crashers_fixed/27718-swift-parser-parseidentifier.swift similarity index 82% rename from validation-test/compiler_crashers/27718-swift-parser-parseidentifier.swift rename to validation-test/compiler_crashers_fixed/27718-swift-parser-parseidentifier.swift index c5f39c4d3b499..0fce1148f6921 100644 --- a/validation-test/compiler_crashers/27718-swift-parser-parseidentifier.swift +++ b/validation-test/compiler_crashers_fixed/27718-swift-parser-parseidentifier.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27719-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27719-std-function-func-swift-type-subst.swift similarity index 82% rename from validation-test/compiler_crashers/27719-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27719-std-function-func-swift-type-subst.swift index 5d88fc96faed4..f3274a3f4345c 100644 --- a/validation-test/compiler_crashers/27719-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27719-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27720-swift-valuedecl-overwritetype.swift b/validation-test/compiler_crashers_fixed/27720-swift-valuedecl-overwritetype.swift similarity index 82% rename from validation-test/compiler_crashers/27720-swift-valuedecl-overwritetype.swift rename to validation-test/compiler_crashers_fixed/27720-swift-valuedecl-overwritetype.swift index 780a9ca9fb696..ca09c8a02168f 100644 --- a/validation-test/compiler_crashers/27720-swift-valuedecl-overwritetype.swift +++ b/validation-test/compiler_crashers_fixed/27720-swift-valuedecl-overwritetype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27721-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/27721-swift-typebase-getcanonicaltype.swift similarity index 81% rename from validation-test/compiler_crashers/27721-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/27721-swift-typebase-getcanonicaltype.swift index f962064c40134..dd2f601d53628 100644 --- a/validation-test/compiler_crashers/27721-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/27721-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27722-swift-removeshadoweddecls.swift b/validation-test/compiler_crashers_fixed/27722-swift-removeshadoweddecls.swift similarity index 82% rename from validation-test/compiler_crashers/27722-swift-removeshadoweddecls.swift rename to validation-test/compiler_crashers_fixed/27722-swift-removeshadoweddecls.swift index 37ddecc1ed289..272461fa18fd8 100644 --- a/validation-test/compiler_crashers/27722-swift-removeshadoweddecls.swift +++ b/validation-test/compiler_crashers_fixed/27722-swift-removeshadoweddecls.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27723-swift-constraints-constraint-createbindoverload.swift b/validation-test/compiler_crashers_fixed/27723-swift-constraints-constraint-createbindoverload.swift similarity index 84% rename from validation-test/compiler_crashers/27723-swift-constraints-constraint-createbindoverload.swift rename to validation-test/compiler_crashers_fixed/27723-swift-constraints-constraint-createbindoverload.swift index 718378c44473a..9f83d929b584f 100644 --- a/validation-test/compiler_crashers/27723-swift-constraints-constraint-createbindoverload.swift +++ b/validation-test/compiler_crashers_fixed/27723-swift-constraints-constraint-createbindoverload.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27724-swift-constraints-constraintgraph-change-undo.swift b/validation-test/compiler_crashers_fixed/27724-swift-constraints-constraintgraph-change-undo.swift similarity index 80% rename from validation-test/compiler_crashers/27724-swift-constraints-constraintgraph-change-undo.swift rename to validation-test/compiler_crashers_fixed/27724-swift-constraints-constraintgraph-change-undo.swift index 9dc42559d506c..b02d71136bdca 100644 --- a/validation-test/compiler_crashers/27724-swift-constraints-constraintgraph-change-undo.swift +++ b/validation-test/compiler_crashers_fixed/27724-swift-constraints-constraintgraph-change-undo.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27725-swift-printingdiagnosticconsumer-handlediagnostic.swift b/validation-test/compiler_crashers_fixed/27725-swift-printingdiagnosticconsumer-handlediagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27725-swift-printingdiagnosticconsumer-handlediagnostic.swift rename to validation-test/compiler_crashers_fixed/27725-swift-printingdiagnosticconsumer-handlediagnostic.swift index 5dc164b1c8917..62204c1f0e2f5 100644 --- a/validation-test/compiler_crashers/27725-swift-printingdiagnosticconsumer-handlediagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27725-swift-printingdiagnosticconsumer-handlediagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27726-swift-modulefile-declcommenttableinfo-readdata.swift b/validation-test/compiler_crashers_fixed/27726-swift-modulefile-declcommenttableinfo-readdata.swift similarity index 81% rename from validation-test/compiler_crashers/27726-swift-modulefile-declcommenttableinfo-readdata.swift rename to validation-test/compiler_crashers_fixed/27726-swift-modulefile-declcommenttableinfo-readdata.swift index d7d85d69ffef4..26d4d5182f4dd 100644 --- a/validation-test/compiler_crashers/27726-swift-modulefile-declcommenttableinfo-readdata.swift +++ b/validation-test/compiler_crashers_fixed/27726-swift-modulefile-declcommenttableinfo-readdata.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27727-swift-abstractclosureexpr-setparams.swift b/validation-test/compiler_crashers_fixed/27727-swift-abstractclosureexpr-setparams.swift similarity index 84% rename from validation-test/compiler_crashers/27727-swift-abstractclosureexpr-setparams.swift rename to validation-test/compiler_crashers_fixed/27727-swift-abstractclosureexpr-setparams.swift index a835b60256541..995515fdf7dc7 100644 --- a/validation-test/compiler_crashers/27727-swift-abstractclosureexpr-setparams.swift +++ b/validation-test/compiler_crashers_fixed/27727-swift-abstractclosureexpr-setparams.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27728-swift-modulefile-loadextensions.swift b/validation-test/compiler_crashers_fixed/27728-swift-modulefile-loadextensions.swift similarity index 81% rename from validation-test/compiler_crashers/27728-swift-modulefile-loadextensions.swift rename to validation-test/compiler_crashers_fixed/27728-swift-modulefile-loadextensions.swift index 78e59b5170ce6..1a34051e6d14c 100644 --- a/validation-test/compiler_crashers/27728-swift-modulefile-loadextensions.swift +++ b/validation-test/compiler_crashers_fixed/27728-swift-modulefile-loadextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27729-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/27729-swift-typechecker-coercepatterntotype.swift similarity index 82% rename from validation-test/compiler_crashers/27729-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/27729-swift-typechecker-coercepatterntotype.swift index 712a3b428dad2..6bc6ab8d3b0be 100644 --- a/validation-test/compiler_crashers/27729-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/27729-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27730-swift-modulefile-resolvecrossreference.swift b/validation-test/compiler_crashers_fixed/27730-swift-modulefile-resolvecrossreference.swift similarity index 83% rename from validation-test/compiler_crashers/27730-swift-modulefile-resolvecrossreference.swift rename to validation-test/compiler_crashers_fixed/27730-swift-modulefile-resolvecrossreference.swift index 9c623e24deb44..46a0f9d038d0f 100644 --- a/validation-test/compiler_crashers/27730-swift-modulefile-resolvecrossreference.swift +++ b/validation-test/compiler_crashers_fixed/27730-swift-modulefile-resolvecrossreference.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27733-swift-constraints-constraintsystem-constraintsystem.swift b/validation-test/compiler_crashers_fixed/27733-swift-constraints-constraintsystem-constraintsystem.swift similarity index 84% rename from validation-test/compiler_crashers/27733-swift-constraints-constraintsystem-constraintsystem.swift rename to validation-test/compiler_crashers_fixed/27733-swift-constraints-constraintsystem-constraintsystem.swift index ad9efadc25f67..0d6634c0ec2e9 100644 --- a/validation-test/compiler_crashers/27733-swift-constraints-constraintsystem-constraintsystem.swift +++ b/validation-test/compiler_crashers_fixed/27733-swift-constraints-constraintsystem-constraintsystem.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27734-swift-typechecker-coercepatterntotype.swift b/validation-test/compiler_crashers_fixed/27734-swift-typechecker-coercepatterntotype.swift similarity index 83% rename from validation-test/compiler_crashers/27734-swift-typechecker-coercepatterntotype.swift rename to validation-test/compiler_crashers_fixed/27734-swift-typechecker-coercepatterntotype.swift index 96e9a18bb05bd..28500fc0b3ef2 100644 --- a/validation-test/compiler_crashers/27734-swift-typechecker-coercepatterntotype.swift +++ b/validation-test/compiler_crashers_fixed/27734-swift-typechecker-coercepatterntotype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27735-llvm-foldingset-swift-tupletype-nodeequals.swift b/validation-test/compiler_crashers_fixed/27735-llvm-foldingset-swift-tupletype-nodeequals.swift similarity index 82% rename from validation-test/compiler_crashers/27735-llvm-foldingset-swift-tupletype-nodeequals.swift rename to validation-test/compiler_crashers_fixed/27735-llvm-foldingset-swift-tupletype-nodeequals.swift index 20abb6af6821f..8fbd7f0596a95 100644 --- a/validation-test/compiler_crashers/27735-llvm-foldingset-swift-tupletype-nodeequals.swift +++ b/validation-test/compiler_crashers_fixed/27735-llvm-foldingset-swift-tupletype-nodeequals.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27737-swift-parentype-get.swift b/validation-test/compiler_crashers_fixed/27737-swift-parentype-get.swift similarity index 82% rename from validation-test/compiler_crashers/27737-swift-parentype-get.swift rename to validation-test/compiler_crashers_fixed/27737-swift-parentype-get.swift index 86174369ed826..34a677f13b1e6 100644 --- a/validation-test/compiler_crashers/27737-swift-parentype-get.swift +++ b/validation-test/compiler_crashers_fixed/27737-swift-parentype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27738-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27738-swift-inflightdiagnostic.swift similarity index 81% rename from validation-test/compiler_crashers/27738-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27738-swift-inflightdiagnostic.swift index 71ab75c77b7dd..56446ae7a95e0 100644 --- a/validation-test/compiler_crashers/27738-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27738-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27739-swift-conformancelookuptable-resolveconformances.swift b/validation-test/compiler_crashers_fixed/27739-swift-conformancelookuptable-resolveconformances.swift similarity index 81% rename from validation-test/compiler_crashers/27739-swift-conformancelookuptable-resolveconformances.swift rename to validation-test/compiler_crashers_fixed/27739-swift-conformancelookuptable-resolveconformances.swift index fc805f2f1969c..9d5fc10a409cb 100644 --- a/validation-test/compiler_crashers/27739-swift-conformancelookuptable-resolveconformances.swift +++ b/validation-test/compiler_crashers_fixed/27739-swift-conformancelookuptable-resolveconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27740-swift-modulefile-getdeclcontext.swift b/validation-test/compiler_crashers_fixed/27740-swift-modulefile-getdeclcontext.swift similarity index 81% rename from validation-test/compiler_crashers/27740-swift-modulefile-getdeclcontext.swift rename to validation-test/compiler_crashers_fixed/27740-swift-modulefile-getdeclcontext.swift index 598d40902311e..7e2c01a95e82d 100644 --- a/validation-test/compiler_crashers/27740-swift-modulefile-getdeclcontext.swift +++ b/validation-test/compiler_crashers_fixed/27740-swift-modulefile-getdeclcontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27741-swift-structtype-get.swift b/validation-test/compiler_crashers_fixed/27741-swift-structtype-get.swift similarity index 83% rename from validation-test/compiler_crashers/27741-swift-structtype-get.swift rename to validation-test/compiler_crashers_fixed/27741-swift-structtype-get.swift index 8565de2bd53db..3e6cbea14f85a 100644 --- a/validation-test/compiler_crashers/27741-swift-structtype-get.swift +++ b/validation-test/compiler_crashers_fixed/27741-swift-structtype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27744-swift-astprinter-printtextimpl.swift b/validation-test/compiler_crashers_fixed/27744-swift-astprinter-printtextimpl.swift similarity index 84% rename from validation-test/compiler_crashers/27744-swift-astprinter-printtextimpl.swift rename to validation-test/compiler_crashers_fixed/27744-swift-astprinter-printtextimpl.swift index 2eae35bc41a47..5cdb7f14d0a78 100644 --- a/validation-test/compiler_crashers/27744-swift-astprinter-printtextimpl.swift +++ b/validation-test/compiler_crashers_fixed/27744-swift-astprinter-printtextimpl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27745-swift-modulefile-getdecl.swift b/validation-test/compiler_crashers_fixed/27745-swift-modulefile-getdecl.swift similarity index 79% rename from validation-test/compiler_crashers/27745-swift-modulefile-getdecl.swift rename to validation-test/compiler_crashers_fixed/27745-swift-modulefile-getdecl.swift index 5c462be2d4c26..7eae1a9dfda07 100644 --- a/validation-test/compiler_crashers/27745-swift-modulefile-getdecl.swift +++ b/validation-test/compiler_crashers_fixed/27745-swift-modulefile-getdecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27746-void.swift b/validation-test/compiler_crashers_fixed/27746-void.swift similarity index 81% rename from validation-test/compiler_crashers/27746-void.swift rename to validation-test/compiler_crashers_fixed/27746-void.swift index 7be56248d68b5..7c731405629ee 100644 --- a/validation-test/compiler_crashers/27746-void.swift +++ b/validation-test/compiler_crashers_fixed/27746-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27747-swift-typebase-getcanonicaltype.swift b/validation-test/compiler_crashers_fixed/27747-swift-typebase-getcanonicaltype.swift similarity index 81% rename from validation-test/compiler_crashers/27747-swift-typebase-getcanonicaltype.swift rename to validation-test/compiler_crashers_fixed/27747-swift-typebase-getcanonicaltype.swift index 5fd4915ddcc0b..f1a1217080d0b 100644 --- a/validation-test/compiler_crashers/27747-swift-typebase-getcanonicaltype.swift +++ b/validation-test/compiler_crashers_fixed/27747-swift-typebase-getcanonicaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27749-swift-archetypetype-getnew.swift b/validation-test/compiler_crashers_fixed/27749-swift-archetypetype-getnew.swift similarity index 82% rename from validation-test/compiler_crashers/27749-swift-archetypetype-getnew.swift rename to validation-test/compiler_crashers_fixed/27749-swift-archetypetype-getnew.swift index 89f009bb06537..766b319e1c5e1 100644 --- a/validation-test/compiler_crashers/27749-swift-archetypetype-getnew.swift +++ b/validation-test/compiler_crashers_fixed/27749-swift-archetypetype-getnew.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27750-swift-metatypetype-get.swift b/validation-test/compiler_crashers_fixed/27750-swift-metatypetype-get.swift similarity index 80% rename from validation-test/compiler_crashers/27750-swift-metatypetype-get.swift rename to validation-test/compiler_crashers_fixed/27750-swift-metatypetype-get.swift index 8bf7a91f326db..7f6a8a83c0a54 100644 --- a/validation-test/compiler_crashers/27750-swift-metatypetype-get.swift +++ b/validation-test/compiler_crashers_fixed/27750-swift-metatypetype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27751-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/27751-swift-functiontype-get.swift similarity index 81% rename from validation-test/compiler_crashers/27751-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/27751-swift-functiontype-get.swift index bab55cc53f06d..2ef798c9155b3 100644 --- a/validation-test/compiler_crashers/27751-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/27751-swift-functiontype-get.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27752-swift-parser-parsebraceitems.swift b/validation-test/compiler_crashers_fixed/27752-swift-parser-parsebraceitems.swift similarity index 84% rename from validation-test/compiler_crashers/27752-swift-parser-parsebraceitems.swift rename to validation-test/compiler_crashers_fixed/27752-swift-parser-parsebraceitems.swift index f31081f840903..a20f1e35f4e16 100644 --- a/validation-test/compiler_crashers/27752-swift-parser-parsebraceitems.swift +++ b/validation-test/compiler_crashers_fixed/27752-swift-parser-parsebraceitems.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27753-std-function-func-setboundvarstypeerror.swift b/validation-test/compiler_crashers_fixed/27753-std-function-func-setboundvarstypeerror.swift similarity index 80% rename from validation-test/compiler_crashers/27753-std-function-func-setboundvarstypeerror.swift rename to validation-test/compiler_crashers_fixed/27753-std-function-func-setboundvarstypeerror.swift index a70e3025533db..7dcac5a5dcf18 100644 --- a/validation-test/compiler_crashers/27753-std-function-func-setboundvarstypeerror.swift +++ b/validation-test/compiler_crashers_fixed/27753-std-function-func-setboundvarstypeerror.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27756-swift-modulefile-gettype.swift b/validation-test/compiler_crashers_fixed/27756-swift-modulefile-gettype.swift similarity index 79% rename from validation-test/compiler_crashers/27756-swift-modulefile-gettype.swift rename to validation-test/compiler_crashers_fixed/27756-swift-modulefile-gettype.swift index 778871fe1e161..fa76f403becbd 100644 --- a/validation-test/compiler_crashers/27756-swift-modulefile-gettype.swift +++ b/validation-test/compiler_crashers_fixed/27756-swift-modulefile-gettype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27757-swift-parser-parsebraceitems.swift b/validation-test/compiler_crashers_fixed/27757-swift-parser-parsebraceitems.swift similarity index 80% rename from validation-test/compiler_crashers/27757-swift-parser-parsebraceitems.swift rename to validation-test/compiler_crashers_fixed/27757-swift-parser-parsebraceitems.swift index 330ff45882461..7fe480f07cc7a 100644 --- a/validation-test/compiler_crashers/27757-swift-parser-parsebraceitems.swift +++ b/validation-test/compiler_crashers_fixed/27757-swift-parser-parsebraceitems.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27758-std-function-func-swift-type-subst.swift b/validation-test/compiler_crashers_fixed/27758-std-function-func-swift-type-subst.swift similarity index 81% rename from validation-test/compiler_crashers/27758-std-function-func-swift-type-subst.swift rename to validation-test/compiler_crashers_fixed/27758-std-function-func-swift-type-subst.swift index 8951222556587..d67c9d05e59aa 100644 --- a/validation-test/compiler_crashers/27758-std-function-func-swift-type-subst.swift +++ b/validation-test/compiler_crashers_fixed/27758-std-function-func-swift-type-subst.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27759-swift-constraints-constraintsystem-diagnosefailureforexpr.swift b/validation-test/compiler_crashers_fixed/27759-swift-constraints-constraintsystem-diagnosefailureforexpr.swift similarity index 86% rename from validation-test/compiler_crashers/27759-swift-constraints-constraintsystem-diagnosefailureforexpr.swift rename to validation-test/compiler_crashers_fixed/27759-swift-constraints-constraintsystem-diagnosefailureforexpr.swift index 06849f42f23a8..13ef595788fc9 100644 --- a/validation-test/compiler_crashers/27759-swift-constraints-constraintsystem-diagnosefailureforexpr.swift +++ b/validation-test/compiler_crashers_fixed/27759-swift-constraints-constraintsystem-diagnosefailureforexpr.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27760-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27760-swift-inflightdiagnostic.swift similarity index 86% rename from validation-test/compiler_crashers/27760-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27760-swift-inflightdiagnostic.swift index 206fed2bbc9b7..30cca38e0f76e 100644 --- a/validation-test/compiler_crashers/27760-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27760-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27762-swift-typechecker-validategenericfuncsignature.swift b/validation-test/compiler_crashers_fixed/27762-swift-typechecker-validategenericfuncsignature.swift similarity index 81% rename from validation-test/compiler_crashers/27762-swift-typechecker-validategenericfuncsignature.swift rename to validation-test/compiler_crashers_fixed/27762-swift-typechecker-validategenericfuncsignature.swift index 3a4031f6c456d..b8e885a28dc31 100644 --- a/validation-test/compiler_crashers/27762-swift-typechecker-validategenericfuncsignature.swift +++ b/validation-test/compiler_crashers_fixed/27762-swift-typechecker-validategenericfuncsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27763-swift-constraints-constraintgraph-computeconnectedcomponents.swift b/validation-test/compiler_crashers_fixed/27763-swift-constraints-constraintgraph-computeconnectedcomponents.swift similarity index 81% rename from validation-test/compiler_crashers/27763-swift-constraints-constraintgraph-computeconnectedcomponents.swift rename to validation-test/compiler_crashers_fixed/27763-swift-constraints-constraintgraph-computeconnectedcomponents.swift index e354e15d5e844..114b39c5bd474 100644 --- a/validation-test/compiler_crashers/27763-swift-constraints-constraintgraph-computeconnectedcomponents.swift +++ b/validation-test/compiler_crashers_fixed/27763-swift-constraints-constraintgraph-computeconnectedcomponents.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27764-swift-constraints-simplifylocator.swift b/validation-test/compiler_crashers_fixed/27764-swift-constraints-simplifylocator.swift similarity index 82% rename from validation-test/compiler_crashers/27764-swift-constraints-simplifylocator.swift rename to validation-test/compiler_crashers_fixed/27764-swift-constraints-simplifylocator.swift index 8d9434316a7d4..8a56154a38a75 100644 --- a/validation-test/compiler_crashers/27764-swift-constraints-simplifylocator.swift +++ b/validation-test/compiler_crashers_fixed/27764-swift-constraints-simplifylocator.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27765-swift-typechecker-typecheckpatternbinding.swift b/validation-test/compiler_crashers_fixed/27765-swift-typechecker-typecheckpatternbinding.swift similarity index 82% rename from validation-test/compiler_crashers/27765-swift-typechecker-typecheckpatternbinding.swift rename to validation-test/compiler_crashers_fixed/27765-swift-typechecker-typecheckpatternbinding.swift index f4a397998bfba..44c561b0e19e8 100644 --- a/validation-test/compiler_crashers/27765-swift-typechecker-typecheckpatternbinding.swift +++ b/validation-test/compiler_crashers_fixed/27765-swift-typechecker-typecheckpatternbinding.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27766-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/27766-swift-constraints-solution-solution.swift similarity index 79% rename from validation-test/compiler_crashers/27766-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/27766-swift-constraints-solution-solution.swift index 5236dc45a86b0..b64d55cafb5f1 100644 --- a/validation-test/compiler_crashers/27766-swift-constraints-solution-solution.swift +++ b/validation-test/compiler_crashers_fixed/27766-swift-constraints-solution-solution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27769-swift-patternbindingdecl-create.swift b/validation-test/compiler_crashers_fixed/27769-swift-patternbindingdecl-create.swift similarity index 81% rename from validation-test/compiler_crashers/27769-swift-patternbindingdecl-create.swift rename to validation-test/compiler_crashers_fixed/27769-swift-patternbindingdecl-create.swift index ff9271634780a..fb91b60fab1c9 100644 --- a/validation-test/compiler_crashers/27769-swift-patternbindingdecl-create.swift +++ b/validation-test/compiler_crashers_fixed/27769-swift-patternbindingdecl-create.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27772-swift-modulefile-loadextensions.swift b/validation-test/compiler_crashers_fixed/27772-swift-modulefile-loadextensions.swift similarity index 85% rename from validation-test/compiler_crashers/27772-swift-modulefile-loadextensions.swift rename to validation-test/compiler_crashers_fixed/27772-swift-modulefile-loadextensions.swift index 62d47a8e41c31..078a2acf30380 100644 --- a/validation-test/compiler_crashers/27772-swift-modulefile-loadextensions.swift +++ b/validation-test/compiler_crashers_fixed/27772-swift-modulefile-loadextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27773-swift-typechecker-getinterfacetypefrominternaltype.swift b/validation-test/compiler_crashers_fixed/27773-swift-typechecker-getinterfacetypefrominternaltype.swift similarity index 80% rename from validation-test/compiler_crashers/27773-swift-typechecker-getinterfacetypefrominternaltype.swift rename to validation-test/compiler_crashers_fixed/27773-swift-typechecker-getinterfacetypefrominternaltype.swift index 0801cbc1da4e5..474a87ac1f374 100644 --- a/validation-test/compiler_crashers/27773-swift-typechecker-getinterfacetypefrominternaltype.swift +++ b/validation-test/compiler_crashers_fixed/27773-swift-typechecker-getinterfacetypefrominternaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27774-filtervalues.swift b/validation-test/compiler_crashers_fixed/27774-filtervalues.swift similarity index 80% rename from validation-test/compiler_crashers/27774-filtervalues.swift rename to validation-test/compiler_crashers_fixed/27774-filtervalues.swift index 896714610cb51..998b7f1bac1aa 100644 --- a/validation-test/compiler_crashers/27774-filtervalues.swift +++ b/validation-test/compiler_crashers_fixed/27774-filtervalues.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27775-swift-typechecker-typecheckpattern.swift b/validation-test/compiler_crashers_fixed/27775-swift-typechecker-typecheckpattern.swift similarity index 80% rename from validation-test/compiler_crashers/27775-swift-typechecker-typecheckpattern.swift rename to validation-test/compiler_crashers_fixed/27775-swift-typechecker-typecheckpattern.swift index 68a792d6cd5a5..25fd2cf2c6023 100644 --- a/validation-test/compiler_crashers/27775-swift-typechecker-typecheckpattern.swift +++ b/validation-test/compiler_crashers_fixed/27775-swift-typechecker-typecheckpattern.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27777-swift-clangimporter-loadextensions.swift b/validation-test/compiler_crashers_fixed/27777-swift-clangimporter-loadextensions.swift similarity index 79% rename from validation-test/compiler_crashers/27777-swift-clangimporter-loadextensions.swift rename to validation-test/compiler_crashers_fixed/27777-swift-clangimporter-loadextensions.swift index 78e7110b0ebf0..640fe4b9809ff 100644 --- a/validation-test/compiler_crashers/27777-swift-clangimporter-loadextensions.swift +++ b/validation-test/compiler_crashers_fixed/27777-swift-clangimporter-loadextensions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27778-swift-astcontext-getbridgedtoobjc.swift b/validation-test/compiler_crashers_fixed/27778-swift-astcontext-getbridgedtoobjc.swift similarity index 84% rename from validation-test/compiler_crashers/27778-swift-astcontext-getbridgedtoobjc.swift rename to validation-test/compiler_crashers_fixed/27778-swift-astcontext-getbridgedtoobjc.swift index 9652ee382045a..f1f4cf3157dba 100644 --- a/validation-test/compiler_crashers/27778-swift-astcontext-getbridgedtoobjc.swift +++ b/validation-test/compiler_crashers_fixed/27778-swift-astcontext-getbridgedtoobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27780-swift-conformancelookuptable-lookupconformances.swift b/validation-test/compiler_crashers_fixed/27780-swift-conformancelookuptable-lookupconformances.swift similarity index 80% rename from validation-test/compiler_crashers/27780-swift-conformancelookuptable-lookupconformances.swift rename to validation-test/compiler_crashers_fixed/27780-swift-conformancelookuptable-lookupconformances.swift index bdc34707fff29..c3afe56cae7fb 100644 --- a/validation-test/compiler_crashers/27780-swift-conformancelookuptable-lookupconformances.swift +++ b/validation-test/compiler_crashers_fixed/27780-swift-conformancelookuptable-lookupconformances.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27781-swift-typechecker-resolvetypeincontext.swift b/validation-test/compiler_crashers_fixed/27781-swift-typechecker-resolvetypeincontext.swift similarity index 84% rename from validation-test/compiler_crashers/27781-swift-typechecker-resolvetypeincontext.swift rename to validation-test/compiler_crashers_fixed/27781-swift-typechecker-resolvetypeincontext.swift index 7e57e92bae1b3..9d65fcd512bc5 100644 --- a/validation-test/compiler_crashers/27781-swift-typechecker-resolvetypeincontext.swift +++ b/validation-test/compiler_crashers_fixed/27781-swift-typechecker-resolvetypeincontext.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27782-swift-genericsignature-profile.swift b/validation-test/compiler_crashers_fixed/27782-swift-genericsignature-profile.swift similarity index 81% rename from validation-test/compiler_crashers/27782-swift-genericsignature-profile.swift rename to validation-test/compiler_crashers_fixed/27782-swift-genericsignature-profile.swift index 8861e63fa42fa..19190b969c490 100644 --- a/validation-test/compiler_crashers/27782-swift-genericsignature-profile.swift +++ b/validation-test/compiler_crashers_fixed/27782-swift-genericsignature-profile.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27783-swift-genericparamlist-deriveallarchetypes.swift b/validation-test/compiler_crashers_fixed/27783-swift-genericparamlist-deriveallarchetypes.swift similarity index 78% rename from validation-test/compiler_crashers/27783-swift-genericparamlist-deriveallarchetypes.swift rename to validation-test/compiler_crashers_fixed/27783-swift-genericparamlist-deriveallarchetypes.swift index 33813175bffcc..eb97dcd0adb5a 100644 --- a/validation-test/compiler_crashers/27783-swift-genericparamlist-deriveallarchetypes.swift +++ b/validation-test/compiler_crashers_fixed/27783-swift-genericparamlist-deriveallarchetypes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27785-swift-typechecker-getinterfacetypefrominternaltype.swift b/validation-test/compiler_crashers_fixed/27785-swift-typechecker-getinterfacetypefrominternaltype.swift similarity index 82% rename from validation-test/compiler_crashers/27785-swift-typechecker-getinterfacetypefrominternaltype.swift rename to validation-test/compiler_crashers_fixed/27785-swift-typechecker-getinterfacetypefrominternaltype.swift index dd03137bccfdc..117030bd96ce2 100644 --- a/validation-test/compiler_crashers/27785-swift-typechecker-getinterfacetypefrominternaltype.swift +++ b/validation-test/compiler_crashers_fixed/27785-swift-typechecker-getinterfacetypefrominternaltype.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27786-swift-inflightdiagnostic.swift b/validation-test/compiler_crashers_fixed/27786-swift-inflightdiagnostic.swift similarity index 82% rename from validation-test/compiler_crashers/27786-swift-inflightdiagnostic.swift rename to validation-test/compiler_crashers_fixed/27786-swift-inflightdiagnostic.swift index 56b6ce9965856..a4cac0632ec02 100644 --- a/validation-test/compiler_crashers/27786-swift-inflightdiagnostic.swift +++ b/validation-test/compiler_crashers_fixed/27786-swift-inflightdiagnostic.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27787-swift-typechecker-overapproximateosversionsatlocation.swift b/validation-test/compiler_crashers_fixed/27787-swift-typechecker-overapproximateosversionsatlocation.swift similarity index 79% rename from validation-test/compiler_crashers/27787-swift-typechecker-overapproximateosversionsatlocation.swift rename to validation-test/compiler_crashers_fixed/27787-swift-typechecker-overapproximateosversionsatlocation.swift index 298a95f924011..bdf6b51be436a 100644 --- a/validation-test/compiler_crashers/27787-swift-typechecker-overapproximateosversionsatlocation.swift +++ b/validation-test/compiler_crashers_fixed/27787-swift-typechecker-overapproximateosversionsatlocation.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27788-swift-constraints-solution-solution.swift b/validation-test/compiler_crashers_fixed/27788-swift-constraints-solution-solution.swift similarity index 84% rename from validation-test/compiler_crashers/27788-swift-constraints-solution-solution.swift rename to validation-test/compiler_crashers_fixed/27788-swift-constraints-solution-solution.swift index 0b41a536e1d9b..6a853d6475bba 100644 --- a/validation-test/compiler_crashers/27788-swift-constraints-solution-solution.swift +++ b/validation-test/compiler_crashers_fixed/27788-swift-constraints-solution-solution.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27789-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift b/validation-test/compiler_crashers_fixed/27789-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift similarity index 82% rename from validation-test/compiler_crashers/27789-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift rename to validation-test/compiler_crashers_fixed/27789-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift index e98df361101bc..2757955731665 100644 --- a/validation-test/compiler_crashers/27789-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift +++ b/validation-test/compiler_crashers_fixed/27789-swift-constraints-constraintsystem-addtypevariableconstraintstoworklist.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27790-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift b/validation-test/compiler_crashers_fixed/27790-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift similarity index 82% rename from validation-test/compiler_crashers/27790-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift rename to validation-test/compiler_crashers_fixed/27790-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift index 5c4970463c362..b33159231f931 100644 --- a/validation-test/compiler_crashers/27790-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift +++ b/validation-test/compiler_crashers_fixed/27790-llvm-ondiskchainedhashtable-swift-modulefile-decltableinfo-find.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27791-swift-conformancelookuptable-updatelookuptable.swift b/validation-test/compiler_crashers_fixed/27791-swift-conformancelookuptable-updatelookuptable.swift similarity index 80% rename from validation-test/compiler_crashers/27791-swift-conformancelookuptable-updatelookuptable.swift rename to validation-test/compiler_crashers_fixed/27791-swift-conformancelookuptable-updatelookuptable.swift index de0dceb0efbb7..ad012496a89ce 100644 --- a/validation-test/compiler_crashers/27791-swift-conformancelookuptable-updatelookuptable.swift +++ b/validation-test/compiler_crashers_fixed/27791-swift-conformancelookuptable-updatelookuptable.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27792-swift-funcdecl-setdeserializedsignature.swift b/validation-test/compiler_crashers_fixed/27792-swift-funcdecl-setdeserializedsignature.swift similarity index 81% rename from validation-test/compiler_crashers/27792-swift-funcdecl-setdeserializedsignature.swift rename to validation-test/compiler_crashers_fixed/27792-swift-funcdecl-setdeserializedsignature.swift index 0ff48efcc0d70..bfa4824ad4c81 100644 --- a/validation-test/compiler_crashers/27792-swift-funcdecl-setdeserializedsignature.swift +++ b/validation-test/compiler_crashers_fixed/27792-swift-funcdecl-setdeserializedsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27793-swift-typechecker-checkdeclattributes.swift b/validation-test/compiler_crashers_fixed/27793-swift-typechecker-checkdeclattributes.swift similarity index 83% rename from validation-test/compiler_crashers/27793-swift-typechecker-checkdeclattributes.swift rename to validation-test/compiler_crashers_fixed/27793-swift-typechecker-checkdeclattributes.swift index f969ca0cf54c9..585503b51217c 100644 --- a/validation-test/compiler_crashers/27793-swift-typechecker-checkdeclattributes.swift +++ b/validation-test/compiler_crashers_fixed/27793-swift-typechecker-checkdeclattributes.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27794-swift-constraints-constraintlocator-profile.swift b/validation-test/compiler_crashers_fixed/27794-swift-constraints-constraintlocator-profile.swift similarity index 82% rename from validation-test/compiler_crashers/27794-swift-constraints-constraintlocator-profile.swift rename to validation-test/compiler_crashers_fixed/27794-swift-constraints-constraintlocator-profile.swift index 2eae9a2350fb1..5b4b40be89fde 100644 --- a/validation-test/compiler_crashers/27794-swift-constraints-constraintlocator-profile.swift +++ b/validation-test/compiler_crashers_fixed/27794-swift-constraints-constraintlocator-profile.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27795-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/27795-swift-typebase-isequal.swift similarity index 78% rename from validation-test/compiler_crashers/27795-swift-typebase-isequal.swift rename to validation-test/compiler_crashers_fixed/27795-swift-typebase-isequal.swift index a9785d1710e5b..d3696de4e7722 100644 --- a/validation-test/compiler_crashers/27795-swift-typebase-isequal.swift +++ b/validation-test/compiler_crashers_fixed/27795-swift-typebase-isequal.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27796-swift-modulefile-maybereadforeignerrorconvention.swift b/validation-test/compiler_crashers_fixed/27796-swift-modulefile-maybereadforeignerrorconvention.swift similarity index 79% rename from validation-test/compiler_crashers/27796-swift-modulefile-maybereadforeignerrorconvention.swift rename to validation-test/compiler_crashers_fixed/27796-swift-modulefile-maybereadforeignerrorconvention.swift index 8762d6b1972d2..b86e93478f0db 100644 --- a/validation-test/compiler_crashers/27796-swift-modulefile-maybereadforeignerrorconvention.swift +++ b/validation-test/compiler_crashers_fixed/27796-swift-modulefile-maybereadforeignerrorconvention.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27797-swift-typechecker-typecheckbinding.swift b/validation-test/compiler_crashers_fixed/27797-swift-typechecker-typecheckbinding.swift similarity index 82% rename from validation-test/compiler_crashers/27797-swift-typechecker-typecheckbinding.swift rename to validation-test/compiler_crashers_fixed/27797-swift-typechecker-typecheckbinding.swift index 7a58ac851f2e3..81b34998c66c6 100644 --- a/validation-test/compiler_crashers/27797-swift-typechecker-typecheckbinding.swift +++ b/validation-test/compiler_crashers_fixed/27797-swift-typechecker-typecheckbinding.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27801-swift-clangimporter-lookupvalue.swift b/validation-test/compiler_crashers_fixed/27801-swift-clangimporter-lookupvalue.swift similarity index 83% rename from validation-test/compiler_crashers/27801-swift-clangimporter-lookupvalue.swift rename to validation-test/compiler_crashers_fixed/27801-swift-clangimporter-lookupvalue.swift index 0c93ee74d7da2..f126cfd45d8f7 100644 --- a/validation-test/compiler_crashers/27801-swift-clangimporter-lookupvalue.swift +++ b/validation-test/compiler_crashers_fixed/27801-swift-clangimporter-lookupvalue.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27802-swift-constraints-constraintsystem-finalize.swift b/validation-test/compiler_crashers_fixed/27802-swift-constraints-constraintsystem-finalize.swift similarity index 81% rename from validation-test/compiler_crashers/27802-swift-constraints-constraintsystem-finalize.swift rename to validation-test/compiler_crashers_fixed/27802-swift-constraints-constraintsystem-finalize.swift index a39966443dee2..4f37a78594044 100644 --- a/validation-test/compiler_crashers/27802-swift-constraints-constraintsystem-finalize.swift +++ b/validation-test/compiler_crashers_fixed/27802-swift-constraints-constraintsystem-finalize.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27805-swift-markasobjc.swift b/validation-test/compiler_crashers_fixed/27805-swift-markasobjc.swift similarity index 84% rename from validation-test/compiler_crashers/27805-swift-markasobjc.swift rename to validation-test/compiler_crashers_fixed/27805-swift-markasobjc.swift index 2e5541e93a896..87dd5ff732cef 100644 --- a/validation-test/compiler_crashers/27805-swift-markasobjc.swift +++ b/validation-test/compiler_crashers_fixed/27805-swift-markasobjc.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27806-swift-declcontext-lookupqualified.swift b/validation-test/compiler_crashers_fixed/27806-swift-declcontext-lookupqualified.swift similarity index 81% rename from validation-test/compiler_crashers/27806-swift-declcontext-lookupqualified.swift rename to validation-test/compiler_crashers_fixed/27806-swift-declcontext-lookupqualified.swift index 055f71b333880..86803bef32160 100644 --- a/validation-test/compiler_crashers/27806-swift-declcontext-lookupqualified.swift +++ b/validation-test/compiler_crashers_fixed/27806-swift-declcontext-lookupqualified.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27807-swift-scopeinfo-addtoscope.swift b/validation-test/compiler_crashers_fixed/27807-swift-scopeinfo-addtoscope.swift similarity index 82% rename from validation-test/compiler_crashers/27807-swift-scopeinfo-addtoscope.swift rename to validation-test/compiler_crashers_fixed/27807-swift-scopeinfo-addtoscope.swift index 244d3675d2455..5e104fc606b15 100644 --- a/validation-test/compiler_crashers/27807-swift-scopeinfo-addtoscope.swift +++ b/validation-test/compiler_crashers_fixed/27807-swift-scopeinfo-addtoscope.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27808-swift-constructordecl-constructordecl.swift b/validation-test/compiler_crashers_fixed/27808-swift-constructordecl-constructordecl.swift similarity index 82% rename from validation-test/compiler_crashers/27808-swift-constructordecl-constructordecl.swift rename to validation-test/compiler_crashers_fixed/27808-swift-constructordecl-constructordecl.swift index 886848169c9cd..b5072c600bafe 100644 --- a/validation-test/compiler_crashers/27808-swift-constructordecl-constructordecl.swift +++ b/validation-test/compiler_crashers_fixed/27808-swift-constructordecl-constructordecl.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27809-void.swift b/validation-test/compiler_crashers_fixed/27809-void.swift similarity index 82% rename from validation-test/compiler_crashers/27809-void.swift rename to validation-test/compiler_crashers_fixed/27809-void.swift index 529995a38b443..c7c88e51e3a1f 100644 --- a/validation-test/compiler_crashers/27809-void.swift +++ b/validation-test/compiler_crashers_fixed/27809-void.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27810-swift-sourcefile-getcache.swift b/validation-test/compiler_crashers_fixed/27810-swift-sourcefile-getcache.swift similarity index 79% rename from validation-test/compiler_crashers/27810-swift-sourcefile-getcache.swift rename to validation-test/compiler_crashers_fixed/27810-swift-sourcefile-getcache.swift index 2aecd2960c4e4..768a7ca898009 100644 --- a/validation-test/compiler_crashers/27810-swift-sourcefile-getcache.swift +++ b/validation-test/compiler_crashers_fixed/27810-swift-sourcefile-getcache.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27811-swift-constraints-solution-computesubstitutions.swift b/validation-test/compiler_crashers_fixed/27811-swift-constraints-solution-computesubstitutions.swift similarity index 82% rename from validation-test/compiler_crashers/27811-swift-constraints-solution-computesubstitutions.swift rename to validation-test/compiler_crashers_fixed/27811-swift-constraints-solution-computesubstitutions.swift index 7f24421a6a348..cac80e1fdd3e8 100644 --- a/validation-test/compiler_crashers/27811-swift-constraints-solution-computesubstitutions.swift +++ b/validation-test/compiler_crashers_fixed/27811-swift-constraints-solution-computesubstitutions.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27812-swift-archetypebuilder-addgenericsignature.swift b/validation-test/compiler_crashers_fixed/27812-swift-archetypebuilder-addgenericsignature.swift similarity index 81% rename from validation-test/compiler_crashers/27812-swift-archetypebuilder-addgenericsignature.swift rename to validation-test/compiler_crashers_fixed/27812-swift-archetypebuilder-addgenericsignature.swift index 79665c1229bf2..4be39294f4157 100644 --- a/validation-test/compiler_crashers/27812-swift-archetypebuilder-addgenericsignature.swift +++ b/validation-test/compiler_crashers_fixed/27812-swift-archetypebuilder-addgenericsignature.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27813-no-stacktrace.swift b/validation-test/compiler_crashers_fixed/27813-no-stacktrace.swift similarity index 81% rename from validation-test/compiler_crashers/27813-no-stacktrace.swift rename to validation-test/compiler_crashers_fixed/27813-no-stacktrace.swift index ce02179bfe66a..46256aa892822 100644 --- a/validation-test/compiler_crashers/27813-no-stacktrace.swift +++ b/validation-test/compiler_crashers_fixed/27813-no-stacktrace.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27814-swift-parser-parseexprclosure.swift b/validation-test/compiler_crashers_fixed/27814-swift-parser-parseexprclosure.swift similarity index 79% rename from validation-test/compiler_crashers/27814-swift-parser-parseexprclosure.swift rename to validation-test/compiler_crashers_fixed/27814-swift-parser-parseexprclosure.swift index ccf89a9755e0f..bbf2fb5dbd066 100644 --- a/validation-test/compiler_crashers/27814-swift-parser-parseexprclosure.swift +++ b/validation-test/compiler_crashers_fixed/27814-swift-parser-parseexprclosure.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers/27815-swift-archetypetype-getnew.swift b/validation-test/compiler_crashers_fixed/27815-swift-archetypetype-getnew.swift similarity index 81% rename from validation-test/compiler_crashers/27815-swift-archetypetype-getnew.swift rename to validation-test/compiler_crashers_fixed/27815-swift-archetypetype-getnew.swift index c42c88f42b20d..f6be2e11bd63c 100644 --- a/validation-test/compiler_crashers/27815-swift-archetypetype-getnew.swift +++ b/validation-test/compiler_crashers_fixed/27815-swift-archetypetype-getnew.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse // Distributed under the terms of the MIT license // Test case submitted to project by https://github.com/practicalswift (practicalswift) diff --git a/validation-test/compiler_crashers_fixed/27818-swift-astvisitor.swift b/validation-test/compiler_crashers_fixed/27818-swift-astvisitor.swift new file mode 100644 index 0000000000000..2c4ab83eaed29 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/27818-swift-astvisitor.swift @@ -0,0 +1,16 @@ +// RUN: %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/zats (Sash Zats) +// Radar: http://openradar.appspot.com/22917580 + +class B { +} + +class A: B { + override init() { + defer { + super.init() + } + } +} diff --git a/validation-test/compiler_crashers_fixed/27821-swift-typechecker-definedefaultconstructor.swift b/validation-test/compiler_crashers_fixed/27821-swift-typechecker-definedefaultconstructor.swift new file mode 100644 index 0000000000000..1a51d1c87ee56 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/27821-swift-typechecker-definedefaultconstructor.swift @@ -0,0 +1,7 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +func a{class A{struct Q{struct d{struct c{struct Q{struct Q{{}}}}}}}}class S:B}}class S:A{enum k:T.c{ +class c{struct S{{} +class p{ +struct S{ +class +a diff --git a/validation-test/compiler_crashers_fixed/27969-void.swift b/validation-test/compiler_crashers_fixed/27969-void.swift new file mode 100644 index 0000000000000..72765ec588298 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/27969-void.swift @@ -0,0 +1,7 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +class A{deinit{class a{struct A{class A{enum a{protocol c}}}}}class S(" +class A{{d +enum B{ +enum S(b=1 +var f{class a}}}b}}}struct S(b< +var f=1 +let f=1 +{ +}}}struct S{{ +func bV{class b} diff --git a/validation-test/compiler_crashers_fixed/28008-swift-builtinunit-lookupcache-lookupvalue.swift b/validation-test/compiler_crashers_fixed/28008-swift-builtinunit-lookupcache-lookupvalue.swift new file mode 100644 index 0000000000000..6ee52aec77ef1 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/28008-swift-builtinunit-lookupcache-lookupvalue.swift @@ -0,0 +1,11 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +true +let a={s:{ +protocol P{ +struct c var : >(}{class a{enum B{enum A{class b T{return}{{class S String { +}}}}}class S +where { +a c{ +} +} +{ +{ +{ +{ +{:: +{}} } +{ +{ +{ +{ }}}}}}class Svar a{let a={let a{{b a diff --git a/validation-test/compiler_crashers_fixed/28124-swift-typevisitor.swift b/validation-test/compiler_crashers_fixed/28124-swift-typevisitor.swift new file mode 100644 index 0000000000000..bfaeaf4a7dc5d --- /dev/null +++ b/validation-test/compiler_crashers_fixed/28124-swift-typevisitor.swift @@ -0,0 +1,8 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case submitted to project by https://github.com/practicalswift (practicalswift) +// Test case found by fuzzing + +import a{let s{class S:CollectionType +struct S{ +struct S{ +struct S{ +enum E String { + return "" + } +} +func b() { + guard let c = A.a as? String else { + return + } +} diff --git a/validation-test/compiler_crashers_fixed/28182-anonymous-namespace-favorcalloverloads.swift b/validation-test/compiler_crashers_fixed/28182-anonymous-namespace-favorcalloverloads.swift new file mode 100644 index 0000000000000..17887a0f72b7d --- /dev/null +++ b/validation-test/compiler_crashers_fixed/28182-anonymous-namespace-favorcalloverloads.swift @@ -0,0 +1,7 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case found by https://github.com/jtbandes (Jacob Bandes-Storch) +// + +func~=switch 0{case 0 diff --git a/validation-test/compiler_crashers_fixed/28183-swift-typebase-isequal.swift b/validation-test/compiler_crashers_fixed/28183-swift-typebase-isequal.swift new file mode 100644 index 0000000000000..2babfb76a7c7b --- /dev/null +++ b/validation-test/compiler_crashers_fixed/28183-swift-typebase-isequal.swift @@ -0,0 +1,7 @@ +// RUN: not %target-swift-frontend %s -parse + +// Distributed under the terms of the MIT license +// Test case found by https://github.com/jtbandes (Jacob Bandes-Storch) +// + +func~=(()->(}switch 0{case 0 diff --git a/validation-test/compiler_crashers_fixed/28186-swift-silwitnessvisitor-visitprotocoldecl.swift b/validation-test/compiler_crashers_fixed/28186-swift-silwitnessvisitor-visitprotocoldecl.swift new file mode 100644 index 0000000000000..eb54d56ea52ae --- /dev/null +++ b/validation-test/compiler_crashers_fixed/28186-swift-silwitnessvisitor-visitprotocoldecl.swift @@ -0,0 +1,25 @@ +// RUN: not %target-swift-frontend %s -parse +// REQUIRES: objc_interop + +// Distributed under the terms of the MIT license +// Test case found by https://github.com/PartiallyFinite (Greg Omelaenko) + +import Foundation + +protocol P { + static func f() -> Self + static func g() -> Self +} + +extension P { + static func f() -> P { + return g() + } +} + +extension NSData: P { + static func g() -> Self { + return self.init() + } +} + diff --git a/validation-test/execution/Inputs/custom-modules/foo.h b/validation-test/execution/Inputs/custom-modules/foo.h new file mode 100644 index 0000000000000..a4b08f2109c33 --- /dev/null +++ b/validation-test/execution/Inputs/custom-modules/foo.h @@ -0,0 +1 @@ +int test(); diff --git a/validation-test/execution/Inputs/custom-modules/module.modulemap b/validation-test/execution/Inputs/custom-modules/module.modulemap new file mode 100644 index 0000000000000..4693963338eeb --- /dev/null +++ b/validation-test/execution/Inputs/custom-modules/module.modulemap @@ -0,0 +1,4 @@ +module foo { + header "foo.h" + link "foo" +} diff --git a/validation-test/execution/interpret-with-dependencies-linux.swift b/validation-test/execution/interpret-with-dependencies-linux.swift new file mode 100644 index 0000000000000..1bce744e6b058 --- /dev/null +++ b/validation-test/execution/interpret-with-dependencies-linux.swift @@ -0,0 +1,26 @@ +// REQUIRES: OS=linux-gnu +// RUN: rm -rf %t && mkdir %t + +// RUN: echo 'int abc = 42;' | %clang -x c - -shared -fPIC -o %t/libabc.so +// RUN: echo 'int test() { extern int abc; return abc; }' | %clang -x c - -L%t -shared -fPIC -labc -o %t/libfoo.so + +// RUN: %swift_driver -I %S/Inputs/custom-modules -L%t %s | FileCheck %s +// CHECK: {{okay}} + +// Now test a dependency on a library in the compiler's resource directory. +// RUN: mkdir -p %t/rsrc/%target-sdk-name/ +// RUN: ln -s %t/libabc.so %t/rsrc/%target-sdk-name/ +// RUN: ln -s %platform-module-dir/../* %t/rsrc/%target-sdk-name/ +// RUN: ln -s %platform-module-dir/../../shims %t/rsrc/ +// RUN: mkdir -p %t/other +// RUN: ln -s %t/libfoo.so %t/other + +// RUN: %swift_driver -I %S/Inputs/custom-modules -L%t/other -resource-dir %t/rsrc/ %s | FileCheck %s + +import foo + +if test() == 42 { + print("okay") +} else { + print("problem") +} diff --git a/validation-test/execution/interpret-with-dependencies.swift b/validation-test/execution/interpret-with-dependencies.swift new file mode 100644 index 0000000000000..75bd2b9757f37 --- /dev/null +++ b/validation-test/execution/interpret-with-dependencies.swift @@ -0,0 +1,26 @@ +// REQUIRES: OS=macosx +// RUN: rm -rf %t && mkdir %t + +// RUN: echo 'int abc = 42;' | %clang -x c - -dynamiclib -Xlinker -install_name -Xlinker libabc.dylib -o %t/libabc.dylib +// RUN: echo 'int test() { extern int abc; return abc; }' | %clang -x c - -L%t -dynamiclib -labc -o %t/libfoo.dylib + +// RUN: %swift_driver -I %S/Inputs/custom-modules -L%t %s | FileCheck %s +// CHECK: {{okay}} + +// Now test a dependency on a library in the compiler's resource directory. +// RUN: mkdir -p %t/rsrc/%target-sdk-name/ +// RUN: ln -s %t/libabc.dylib %t/rsrc/%target-sdk-name/ +// RUN: ln -s %platform-module-dir/../* %t/rsrc/%target-sdk-name/ +// RUN: ln -s %platform-module-dir/../../shims %t/rsrc/ +// RUN: mkdir -p %t/other +// RUN: ln -s %t/libfoo.dylib %t/other + +// RUN: %swift_driver -I %S/Inputs/custom-modules -L%t/other -resource-dir %t/rsrc/ %s | FileCheck %s + +import foo + +if test() == 42 { + print("okay") +} else { + print("problem") +} diff --git a/validation-test/lit.site.cfg.in b/validation-test/lit.site.cfg.in index 77429eef93f75..c4fd908003f3e 100644 --- a/validation-test/lit.site.cfg.in +++ b/validation-test/lit.site.cfg.in @@ -14,6 +14,7 @@ config.target_triple = "@TARGET_TRIPLE@" config.targets_to_build = "@TARGETS_TO_BUILD@" config.variant_triple = "@VARIANT_TRIPLE@" config.variant_sdk = "@VARIANT_SDK@" +config.darwin_xcrun_toolchain = "@SWIFT_DARWIN_XCRUN_TOOLCHAIN@" if "@SWIFT_ASAN_BUILD@" == "TRUE": config.available_features.add("asan") diff --git a/validation-test/stdlib/Algorithm.swift b/validation-test/stdlib/Algorithm.swift index d01e0ef625669..b24ccab9192b1 100644 --- a/validation-test/stdlib/Algorithm.swift +++ b/validation-test/stdlib/Algorithm.swift @@ -5,6 +5,13 @@ import StdlibUnittest import SwiftPrivate +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +#if _runtime(_ObjC) +import ObjectiveC +#endif + var Algorithm = TestSuite("Algorithm") // FIXME(prext): remove this conformance. @@ -18,14 +25,58 @@ public func == ( // FIXME(prext): move this struct to the point of use. Algorithm.test("min,max") { - expectEqual(2, min(3, 2)) - expectEqual(3, min(3, 7, 5)) - expectEqual(3, max(3, 2)) - expectEqual(7, max(3, 7, 5)) - - // FIXME: add tests that check that min/max return the - // first element of the sequence (by reference equailty) that satisfy the - // condition. + // Identities are unique in this set. + let a1 = MinimalComparableValue(0, identity: 1) + let a2 = MinimalComparableValue(0, identity: 2) + let a3 = MinimalComparableValue(0, identity: 3) + let b1 = MinimalComparableValue(1, identity: 4) + let b2 = MinimalComparableValue(1, identity: 5) + let b3 = MinimalComparableValue(1, identity: 6) + let c1 = MinimalComparableValue(2, identity: 7) + let c2 = MinimalComparableValue(2, identity: 8) + let c3 = MinimalComparableValue(2, identity: 9) + + // 2-arg min() + expectEqual(a1.identity, min(a1, b1).identity) + expectEqual(a1.identity, min(b1, a1).identity) + expectEqual(a1.identity, min(a1, a2).identity) + + // 2-arg max() + expectEqual(c1.identity, max(c1, b1).identity) + expectEqual(c1.identity, max(b1, c1).identity) + expectEqual(c1.identity, max(c2, c1).identity) + + // 3-arg min() + expectEqual(a1.identity, min(a1, b1, c1).identity) + expectEqual(a1.identity, min(b1, a1, c1).identity) + expectEqual(a1.identity, min(c1, b1, a1).identity) + expectEqual(a1.identity, min(c1, a1, b1).identity) + expectEqual(a1.identity, min(a1, a2, a3).identity) + expectEqual(a1.identity, min(a1, a2, b1).identity) + expectEqual(a1.identity, min(a1, b1, a2).identity) + expectEqual(a1.identity, min(b1, a1, a2).identity) + + // 3-arg max() + expectEqual(c1.identity, max(c1, b1, a1).identity) + expectEqual(c1.identity, max(a1, c1, b1).identity) + expectEqual(c1.identity, max(b1, a1, c1).identity) + expectEqual(c1.identity, max(b1, c1, a1).identity) + expectEqual(c1.identity, max(c3, c2, c1).identity) + expectEqual(c1.identity, max(c2, c1, b1).identity) + expectEqual(c1.identity, max(c2, b1, c1).identity) + expectEqual(c1.identity, max(b1, c2, c1).identity) + + // 4-arg min() + expectEqual(a1.identity, min(a1, b1, a2, b2).identity) + expectEqual(a1.identity, min(b1, a1, a2, b2).identity) + expectEqual(a1.identity, min(c1, b1, b2, a1).identity) + expectEqual(a1.identity, min(c1, b1, a1, a2).identity) + + // 4-arg max() + expectEqual(c1.identity, max(c2, b1, c1, b2).identity) + expectEqual(c1.identity, max(b1, c2, c1, b2).identity) + expectEqual(c1.identity, max(a1, b1, b2, c1).identity) + expectEqual(c1.identity, max(a1, b1, c2, c1).identity) } Algorithm.test("sorted/strings") diff --git a/validation-test/stdlib/ArrayNew.swift.gyb b/validation-test/stdlib/ArrayNew.swift.gyb index 964fe41c7097d..05bdd9a8481f6 100644 --- a/validation-test/stdlib/ArrayNew.swift.gyb +++ b/validation-test/stdlib/ArrayNew.swift.gyb @@ -11,6 +11,15 @@ import Darwin import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import StdlibUnittestFoundationExtras import Foundation @@ -157,7 +166,7 @@ ArrayTestSuite.test("${array_type}/init(SequenceType)") { ArrayTestSuite.test("${array_type}/Sliceable/Enums") { typealias E = EnumWithoutPayloads - if true { + do { let expected = [ E.A, E.B, E.C, E.D ] let sliceable = ${array_type}(expected) checkSliceableWithBidirectionalIndex(expected, sliceable) @@ -165,7 +174,7 @@ ArrayTestSuite.test("${array_type}/Sliceable/Enums") { /* FIXME: add this test when Array can be conditionally Equatable. - if true { + do { let expected = [ [ E.A, E.B ], [ E.B, E.C ], [ E.D ], [ E.A, E.B, E.D ] ] let sliceable = ${array_type}(expected) checkSliceableWithBidirectionalIndex( @@ -202,7 +211,7 @@ ArrayTestSuite.test("${array_type}/emptyAllocation") { } ArrayTestSuite.test("${array_type}/filter") { - if true { + do { let arr: ${array_type} = [] var result = arr.filter() { (x: Int) -> Bool in @@ -213,19 +222,19 @@ ArrayTestSuite.test("${array_type}/filter") { expectEqual([], result) expectEqual(0, result.capacity) } - if true { + do { let arr: ${array_type} = [ 0, 30, 10, 90 ] let result = arr.filter() { (x: Int) -> Bool in true } expectEqual([ 0, 30, 10, 90 ], result) expectGE(2 * result.count, result.capacity) } - if true { + do { let arr: ${array_type} = [ 0, 30, 10, 90 ] let result = arr.filter() { (x: Int) -> Bool in false } expectEqual([], result) expectGE(2 * result.count, result.capacity) } - if true { + do { let arr: ${array_type} = [ 0, 30, 10, 90 ] let result = arr.filter() { $0 % 3 == 0 } expectEqual([ 0, 30, 90 ], result) @@ -234,7 +243,7 @@ ArrayTestSuite.test("${array_type}/filter") { } ArrayTestSuite.test("${array_type}/map") { - if true { + do { let arr: ${array_type} = [] var result = arr.map() { (x: Int) -> Int16 in @@ -245,7 +254,7 @@ ArrayTestSuite.test("${array_type}/map") { expectEqual([], result) expectEqual(0, result.capacity) } - if true { + do { let arr: ${array_type} = [ 0, 30, 10, 90 ] let result = arr.map() { $0 + 1 } expectEqual([ 1, 31, 11, 91 ], result) @@ -313,14 +322,14 @@ ArrayTestSuite.test("${array_type}/Mirror") { % for Kind in ['Array', 'ContiguousArray']: ArrayTestSuite.test("${Kind}/popLast") { // Empty - if true { + do { var a = ${Kind}() let popped = a.popLast() expectEmpty(popped) expectTrue(a.isEmpty) } - if true { + do { var popped = [Int]() var a: ${Kind} = [1010, 2020, 3030] while let element = a.popLast() { @@ -335,12 +344,12 @@ ArrayTestSuite.test("${Kind}/popLast") { // Check how removeFirst() affects indices. % for Kind in ['Array', 'ContiguousArray']: ArrayTestSuite.test("${Kind}/removeFirst") { - if true { + do { var a: ${Kind}> = ${Kind}([ 1 ].map(OpaqueValue.init)) a.removeFirst() expectEqual(0, a.startIndex) } - if true { + do { var a: ${Kind}> = ${Kind}([ 1, 2 ].map(OpaqueValue.init)) a.removeFirst() expectEqual(0, a.startIndex) @@ -349,14 +358,14 @@ ArrayTestSuite.test("${Kind}/removeFirst") { % end ArrayTestSuite.test("ArraySlice/removeFirst") { - if true { + do { let a: [OpaqueValue] = [ 99, 1010, 99 ].map(OpaqueValue.init) var s = a[1..<2] expectEqual(1, s.startIndex) s.removeFirst() expectEqual(2, s.startIndex) } - if true { + do { let a: [OpaqueValue] = [ 99, 1010, 2020, 99 ].map(OpaqueValue.init) var s = a[1..<2] expectEqual(1, s.startIndex) @@ -393,7 +402,7 @@ let withUnsafeMutableBufferPointerIfSupportedTests = [ ArrayTestSuite.test("${array_type}/_withUnsafeMutableBufferPointerIfSupported") { for test in withUnsafeMutableBufferPointerIfSupportedTests { var a = getFresh${array_type}(test.sequence.map(OpaqueValue.init)) - if true { + do { // Read. var result = a._withUnsafeMutableBufferPointerIfSupported { (baseAddress, count) -> OpaqueValue<[OpaqueValue]> in @@ -405,7 +414,7 @@ ArrayTestSuite.test("${array_type}/_withUnsafeMutableBufferPointerIfSupported") expectEqualSequence(test.sequence, result!.value.map { $0.value }) expectEqualSequence(test.sequence, a.map { $0.value }) } - if true { + do { // Read and write. var result = a._withUnsafeMutableBufferPointerIfSupported { (baseAddress, count) -> OpaqueValue>> in @@ -674,7 +683,7 @@ ArrayTestSuite.test("${array_type}<${element_type}>/subscript(_: Range)/COW //===----------------------------------------------------------------------===// func isNativeArray(a: Array) -> Bool { - return a._getArrayPropertyIsNative() + return a._hoistableIsNativeTypeChecked() } func isCocoaArray(a: Array) -> Bool { @@ -727,7 +736,7 @@ class CustomImmutableNSArray : NSArray { @objc override func objectAtIndex(index: Int) -> AnyObject { - ++CustomImmutableNSArray.timesObjectAtIndexWasCalled + CustomImmutableNSArray.timesObjectAtIndexWasCalled += 1 return _data[index] } @@ -763,7 +772,7 @@ class CustomImmutableNSArray : NSArray { } ArrayTestSuite.test("BridgedFromObjC.Verbatim.BridgeUsingAs") { - if true { + do { let source = [ 10, 20, 30 ] let nsa = getAsNSArray(source) var result = nsa as Array @@ -773,7 +782,7 @@ ArrayTestSuite.test("BridgedFromObjC.Verbatim.BridgeUsingAs") { ($0 as! TestObjCValueTy).value == ($1 as! TestObjCValueTy).value } } - if true { + do { let source = [ 10, 20, 30 ] let nsa = getAsNSArray(source) var result = nsa as! Array @@ -1515,7 +1524,7 @@ ArrayTestSuite.test("BridgedToObjC.Verbatim.RoundtripThroughSwiftArray") { % ('Array', 'as'), % ('Array', 'as!'), % ]: - if true { + do { let nsa: NSArray = getAsImmutableNSArray([ 10, 20, 30 ]) let a: ${MiddleType} = _convertNSArrayToArray(nsa) let bridgedBack = _convertArrayToNSArray(a) @@ -1528,7 +1537,7 @@ ArrayTestSuite.test("BridgedToObjC.Verbatim.RoundtripThroughSwiftArray") { _fixLifetime(a) _fixLifetime(bridgedBack) } - if true { + do { let nsa: NSArray = getAsImmutableNSArray([ 10, 20, 30 ]) let a = nsa ${AsCast} ${MiddleType} let bridgedBack: NSArray = a as NSArray @@ -1545,14 +1554,14 @@ ArrayTestSuite.test("BridgedToObjC.Verbatim.RoundtripThroughSwiftArray") { } ArrayTestSuite.test("BridgedToObjC.Nonverbatim.RoundtripThroughSwiftArray") { - if true { + do { TestBridgedValueTy.bridgeOperations = 0 let nsa: NSArray = getAsImmutableNSArray([ 10, 20, 30 ]) let a: Array = _convertNSArrayToArray(nsa) let bridgedBack = _convertArrayToNSArray(a) expectEqual(3, TestBridgedValueTy.bridgeOperations) } - if true { + do { TestBridgedValueTy.bridgeOperations = 0 let nsa: NSArray = getAsImmutableNSArray([ 10, 20, 30 ]) let a = nsa as! Array @@ -1731,13 +1740,13 @@ for (step, evilBoundsCheck) in [ (1, true), (-1, false), (-1, true) ] { ArrayTestSuite.test("${array_type}/map") { // This code used to crash because it generated an array of Void with // stride == 0. - if true { + do { let input: ${array_type} = [ (), (), () ] let result = input.map { (_) -> Void in return () } expectEqual(3, result.count) } - if true { + do { let input: ${array_type}> = [ OpaqueValue(10), OpaqueValue(20), OpaqueValue(30) ] diff --git a/validation-test/stdlib/Assert.swift b/validation-test/stdlib/Assert.swift index 6a039862602f2..b0afd15da4f6c 100644 --- a/validation-test/stdlib/Assert.swift +++ b/validation-test/stdlib/Assert.swift @@ -30,13 +30,13 @@ func testTrapsAreNoreturn(i: Int) -> Int { // are @noreturn. switch i { case 2: - preconditionFailure("can not happen") + preconditionFailure("cannot happen") case 3: - _preconditionFailure("can not happen") + _preconditionFailure("cannot happen") case 4: - _debugPreconditionFailure("can not happen") + _debugPreconditionFailure("cannot happen") case 5: - _sanityCheckFailure("can not happen") + _sanityCheckFailure("cannot happen") default: return 0 diff --git a/validation-test/stdlib/AtomicInt.swift b/validation-test/stdlib/AtomicInt.swift index 29bf3dbda7e96..846c59333af05 100644 --- a/validation-test/stdlib/AtomicInt.swift +++ b/validation-test/stdlib/AtomicInt.swift @@ -16,6 +16,11 @@ import SwiftPrivatePthreadExtras #if _runtime(_ObjC) import ObjectiveC #endif +#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) +import Darwin +#elseif os(Linux) +import Glibc +#endif final class HeapBool { var value: Bool @@ -725,7 +730,7 @@ struct AtomicInitializeARCRefRaceTest : RaceTestWithPerTrialDataType { ) -> Observation { var observation = Observation4UInt(0, 0, 0, 0) var initializerDestroyed = HeapBool(false) - if true { + do { let initializer = DummyObject( destroyedFlag: initializerDestroyed, randomInt: threadLocalData.randomInt()) @@ -767,10 +772,10 @@ struct AtomicInitializeARCRefRaceTest : RaceTestWithPerTrialDataType { switch (observation.data1, observation.data4) { case (1, 0): // Won race, value not destroyed. - ++wonRace + wonRace += 1 case (0, 1): // Lost race, value destroyed. - ++lostRace + lostRace += 1 default: sink(.FailureInteresting(String(observation))) } diff --git a/validation-test/stdlib/CollectionType.swift.gyb b/validation-test/stdlib/CollectionType.swift.gyb index 8892996dda9cf..7e88787c0ce43 100644 --- a/validation-test/stdlib/CollectionType.swift.gyb +++ b/validation-test/stdlib/CollectionType.swift.gyb @@ -324,11 +324,11 @@ ${LazyFlatMapTest} //===----------------------------------------------------------------------===// CollectionTypeTests.test("underestimateCount/CollectionType/DefaultImplementation") { - if true { + do { let s = CollectionWithDefaultUnderestimateCount(count: 0) expectEqual(0, callGenericUnderestimatedCount(s)) } - if true { + do { let s = CollectionWithDefaultUnderestimateCount(count: 5) expectEqual(5, callGenericUnderestimatedCount(s)) } @@ -368,11 +368,11 @@ struct CollectionWithCustomUnderestimateCount : CollectionType { } CollectionTypeTests.test("underestimateCount/CollectionType/CustomImplementation") { - if true { + do { let s = CollectionWithCustomUnderestimateCount(underestimatedCount: 0) expectEqual(0, callGenericUnderestimatedCount(s)) } - if true { + do { let s = CollectionWithCustomUnderestimateCount(underestimatedCount: 5) expectEqual(5, callGenericUnderestimatedCount(s)) } @@ -411,7 +411,7 @@ CollectionTypeTests.test("CollectionType.generate()/DefaultImplementation") { for count in [ 0, 5 ] { let collection = MinimalForwardCollectionWithDefaultGenerator(count: count) - if true { + do { // Check the return type of the function when called statically. var generator = collection.generate() expectType( @@ -419,7 +419,7 @@ CollectionTypeTests.test("CollectionType.generate()/DefaultImplementation") { &generator) } - if true { + do { // Check the return type of the function when called generically. var generator = callGenericGenerate(collection) expectType( @@ -468,7 +468,7 @@ CollectionTypeTests.test("CollectionType.generate()/CustomImplementation") { for count in [ 0, 5 ] { let collection = MinimalForwardCollectionWithCustomGenerator(count: count) - if true { + do { // Check the return type of the function when called statically. MinimalForwardCollectionWithCustomGenerator.timesGenerateWasCalled = 0 var generator = collection.generate() @@ -478,7 +478,7 @@ CollectionTypeTests.test("CollectionType.generate()/CustomImplementation") { expectEqual(1, MinimalForwardCollectionWithCustomGenerator.timesGenerateWasCalled) } - if true { + do { MinimalForwardCollectionWithCustomGenerator.timesGenerateWasCalled = 0 // Check the return type of the function when called generically. var generator = callGenericGenerate(collection) @@ -719,7 +719,7 @@ CollectionTypeTests.test("_withUnsafeMutableBufferPointerIfSupported/dispatch") % Base = "%s%s%sCollection" % (base_kind, traversal, 'Mutable' if mutable else '') // Test collections using value types as elements. -if true { +do { var checksAdded: Box> = Box([]) var resiliencyChecks = CollectionMisuseResiliencyChecks.all resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .ExpectationFailure @@ -762,7 +762,7 @@ if true { } // Test collections using a reference type as element. -if true { +do { var checksAdded: Box> = Box([]) var resiliencyChecks = CollectionMisuseResiliencyChecks.all resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .ExpectationFailure diff --git a/validation-test/stdlib/Concatenate.swift b/validation-test/stdlib/Concatenate.swift index db271e478467d..558109b15b5c2 100644 --- a/validation-test/stdlib/Concatenate.swift +++ b/validation-test/stdlib/Concatenate.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -14,6 +14,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var ConcatenateTests = TestSuite("ConcatenateTests") // Help the type checker ( Slow type deduction) diff --git a/validation-test/stdlib/CoreAudio.swift b/validation-test/stdlib/CoreAudio.swift index fedab5585b50e..ebcbbfdd85c35 100644 --- a/validation-test/stdlib/CoreAudio.swift +++ b/validation-test/stdlib/CoreAudio.swift @@ -5,6 +5,15 @@ // UNSUPPORTED: OS=watchos import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import CoreAudio // Used in tests below. @@ -26,7 +35,7 @@ let ablHeaderSize = 8 #endif CoreAudioTestSuite.test("UnsafeBufferPointer.init(_: AudioBuffer)") { - if true { + do { let audioBuffer = AudioBuffer( mNumberChannels: 0, mDataByteSize: 0, mData: nil) let result: UnsafeBufferPointer = UnsafeBufferPointer(audioBuffer) @@ -34,7 +43,7 @@ CoreAudioTestSuite.test("UnsafeBufferPointer.init(_: AudioBuffer)") { expectEqual(0, result.count) } - if true { + do { let audioBuffer = AudioBuffer( mNumberChannels: 2, mDataByteSize: 1024, mData: UnsafeMutablePointer(bitPattern: 0x1234_5678)) @@ -47,7 +56,7 @@ CoreAudioTestSuite.test("UnsafeBufferPointer.init(_: AudioBuffer)") { } CoreAudioTestSuite.test("UnsafeMutableBufferPointer.init(_: AudioBuffer)") { - if true { + do { let audioBuffer = AudioBuffer( mNumberChannels: 0, mDataByteSize: 0, mData: nil) let result: UnsafeMutableBufferPointer = @@ -56,7 +65,7 @@ CoreAudioTestSuite.test("UnsafeMutableBufferPointer.init(_: AudioBuffer)") { expectEqual(0, result.count) } - if true { + do { let audioBuffer = AudioBuffer( mNumberChannels: 2, mDataByteSize: 1024, mData: UnsafeMutablePointer(bitPattern: 0x1234_5678)) @@ -71,7 +80,7 @@ CoreAudioTestSuite.test("UnsafeMutableBufferPointer.init(_: AudioBuffer)") { CoreAudioTestSuite.test( "AudioBuffer.init(_: UnsafeMutableBufferPointer, numberOfChannels: Int)") { - if true { + do { // NULL pointer. let buffer = UnsafeMutableBufferPointer(start: nil, count: 0) let result = AudioBuffer(buffer, numberOfChannels: 2) @@ -79,7 +88,7 @@ CoreAudioTestSuite.test( expectEqual(0, result.mDataByteSize) expectEqual(nil, result.mData) } - if true { + do { // Non-NULL pointer. let buffer = UnsafeMutableBufferPointer( start: UnsafeMutablePointer(bitPattern: 0x1234_5678), count: 0) @@ -129,12 +138,12 @@ CoreAudioTestSuite.test("AudioBufferList.sizeInBytes(maximumBuffers: Int)/trap/o } CoreAudioTestSuite.test("AudioBufferList.allocate(maximumBuffers: Int)") { - if true { + do { let ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 1) expectEqual(1, ablPtrWrapper.count) free(ablPtrWrapper.unsafeMutablePointer) } - if true { + do { let ablPtrWrapper = AudioBufferList.allocate(maximumBuffers: 16) expectEqual(16, ablPtrWrapper.count) free(ablPtrWrapper.unsafeMutablePointer) @@ -161,13 +170,13 @@ CoreAudioTestSuite.test( "UnsafeMutableAudioBufferListPointer.init(_: UnsafeMutablePointer)," + "UnsafeMutableAudioBufferListPointer.unsafePointer," + "UnsafeMutableAudioBufferListPointer.unsafeMutablePointer") { - if true { + do { let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(nil) expectEqual(nil, ablPtrWrapper.unsafePointer) expectEqual(nil, ablPtrWrapper.unsafeMutablePointer) } - if true { + do { let ablPtrWrapper = UnsafeMutableAudioBufferListPointer( UnsafeMutablePointer(bitPattern: 0x1234_5678)) expectEqual( @@ -208,7 +217,7 @@ CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer.subscript(_: Int)") // the subscript has a nonmutating setter. let ablPtrWrapper = UnsafeMutableAudioBufferListPointer(ablPtr) - if true { + do { // Test getter. let audioBuffer = AudioBuffer( mNumberChannels: 2, mDataByteSize: 1024, @@ -223,7 +232,7 @@ CoreAudioTestSuite.test("UnsafeMutableAudioBufferListPointer.subscript(_: Int)") expectEqual(audioBuffer.mData, ablPtrWrapper[0].mData) } - if true { + do { // Test setter. let audioBuffer = AudioBuffer( mNumberChannels: 5, mDataByteSize: 256, diff --git a/validation-test/stdlib/Dictionary.swift b/validation-test/stdlib/Dictionary.swift index ac01ec8e38fcd..512d633fc080e 100644 --- a/validation-test/stdlib/Dictionary.swift +++ b/validation-test/stdlib/Dictionary.swift @@ -229,7 +229,7 @@ DictionaryTestSuite.test("COW.Fast.SubscriptWithKeyDoesNotReallocate") { assert(d[30]! == 1030) assert(d[40]! == 2040) - if true { + do { var d2: [MinimalHashableValue : OpaqueValue] = [:] MinimalHashableValue.timesEqualEqualWasCalled = 0 MinimalHashableValue.timesHashValueWasCalled = 0 @@ -283,7 +283,7 @@ DictionaryTestSuite.test("COW.Slow.SubscriptWithKeyDoesNotReallocate") { assert(d[TestKeyTy(30)]!.value == 1030) assert(d[TestKeyTy(40)]!.value == 2040) - if true { + do { var d2: [MinimalHashableClass : OpaqueValue] = [:] MinimalHashableClass.timesEqualEqualWasCalled = 0 MinimalHashableClass.timesHashValueWasCalled = 0 @@ -299,7 +299,7 @@ DictionaryTestSuite.test("COW.Slow.SubscriptWithKeyDoesNotReallocate") { DictionaryTestSuite.test("COW.Fast.UpdateValueForKeyDoesNotReallocate") { - if true { + do { var d1 = getCOWFastDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -314,7 +314,7 @@ DictionaryTestSuite.test("COW.Fast.UpdateValueForKeyDoesNotReallocate") { assert(d1[10]! == 2010) } - if true { + do { var d1 = getCOWFastDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -344,7 +344,7 @@ DictionaryTestSuite.test("COW.Fast.UpdateValueForKeyDoesNotReallocate") { _fixLifetime(d2) } - if true { + do { var d1 = getCOWFastDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -374,7 +374,7 @@ DictionaryTestSuite.test("COW.Fast.UpdateValueForKeyDoesNotReallocate") { } DictionaryTestSuite.test("COW.Slow.AddDoesNotReallocate") { - if true { + do { var d1 = getCOWSlowDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -391,7 +391,7 @@ DictionaryTestSuite.test("COW.Slow.AddDoesNotReallocate") { assert(d1[TestKeyTy(10)]!.value == 2010) } - if true { + do { var d1 = getCOWSlowDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -421,7 +421,7 @@ DictionaryTestSuite.test("COW.Slow.AddDoesNotReallocate") { _fixLifetime(d2) } - if true { + do { var d1 = getCOWSlowDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -456,7 +456,7 @@ DictionaryTestSuite.test("COW.Fast.IndexForKeyDoesNotReallocate") { var identity1 = unsafeBitCast(d, Int.self) // Find an existing key. - if true { + do { var foundIndex1 = d.indexForKey(10)! assert(identity1 == unsafeBitCast(d, Int.self)) @@ -469,13 +469,13 @@ DictionaryTestSuite.test("COW.Fast.IndexForKeyDoesNotReallocate") { } // Try to find a key that is not present. - if true { + do { var foundIndex1 = d.indexForKey(1111) assert(foundIndex1 == nil) assert(identity1 == unsafeBitCast(d, Int.self)) } - if true { + do { var d2: [MinimalHashableValue : OpaqueValue] = [:] MinimalHashableValue.timesEqualEqualWasCalled = 0 MinimalHashableValue.timesHashValueWasCalled = 0 @@ -493,7 +493,7 @@ DictionaryTestSuite.test("COW.Slow.IndexForKeyDoesNotReallocate") { var identity1 = unsafeBitCast(d, Int.self) // Find an existing key. - if true { + do { var foundIndex1 = d.indexForKey(TestKeyTy(10))! assert(identity1 == unsafeBitCast(d, Int.self)) @@ -506,13 +506,13 @@ DictionaryTestSuite.test("COW.Slow.IndexForKeyDoesNotReallocate") { } // Try to find a key that is not present. - if true { + do { var foundIndex1 = d.indexForKey(TestKeyTy(1111)) assert(foundIndex1 == nil) assert(identity1 == unsafeBitCast(d, Int.self)) } - if true { + do { var d2: [MinimalHashableClass : OpaqueValue] = [:] MinimalHashableClass.timesEqualEqualWasCalled = 0 MinimalHashableClass.timesHashValueWasCalled = 0 @@ -527,7 +527,7 @@ DictionaryTestSuite.test("COW.Slow.IndexForKeyDoesNotReallocate") { DictionaryTestSuite.test("COW.Fast.RemoveAtIndexDoesNotReallocate") { - if true { + do { var d = getCOWFastDictionary() var identity1 = unsafeBitCast(d, Int.self) @@ -545,7 +545,7 @@ DictionaryTestSuite.test("COW.Fast.RemoveAtIndexDoesNotReallocate") { assert(d.indexForKey(10) == nil) } - if true { + do { var d1 = getCOWFastDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -570,7 +570,7 @@ DictionaryTestSuite.test("COW.Fast.RemoveAtIndexDoesNotReallocate") { } DictionaryTestSuite.test("COW.Slow.RemoveAtIndexDoesNotReallocate") { - if true { + do { var d = getCOWSlowDictionary() var identity1 = unsafeBitCast(d, Int.self) @@ -588,7 +588,7 @@ DictionaryTestSuite.test("COW.Slow.RemoveAtIndexDoesNotReallocate") { assert(d.indexForKey(TestKeyTy(10)) == nil) } - if true { + do { var d1 = getCOWSlowDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -612,7 +612,7 @@ DictionaryTestSuite.test("COW.Slow.RemoveAtIndexDoesNotReallocate") { DictionaryTestSuite.test("COW.Fast.RemoveValueForKeyDoesNotReallocate") { - if true { + do { var d1 = getCOWFastDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -628,7 +628,7 @@ DictionaryTestSuite.test("COW.Fast.RemoveValueForKeyDoesNotReallocate") { _fixLifetime(d1) } - if true { + do { var d1 = getCOWFastDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -650,7 +650,7 @@ DictionaryTestSuite.test("COW.Fast.RemoveValueForKeyDoesNotReallocate") { } DictionaryTestSuite.test("COW.Slow.RemoveValueForKeyDoesNotReallocate") { - if true { + do { var d1 = getCOWSlowDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -666,7 +666,7 @@ DictionaryTestSuite.test("COW.Slow.RemoveValueForKeyDoesNotReallocate") { _fixLifetime(d1) } - if true { + do { var d1 = getCOWSlowDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -689,14 +689,14 @@ DictionaryTestSuite.test("COW.Slow.RemoveValueForKeyDoesNotReallocate") { DictionaryTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { - if true { + do { var d = getCOWFastDictionary() let originalCapacity = d._variantStorage.native.capacity assert(d.count == 3) assert(d[10]! == 1010) d.removeAll() - // We can not assert that identity changed, since the new buffer of smaller + // We cannot assert that identity changed, since the new buffer of smaller // size can be allocated at the same address as the old one. var identity1 = unsafeBitCast(d, Int.self) assert(d._variantStorage.native.capacity < originalCapacity) @@ -709,7 +709,7 @@ DictionaryTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { assert(d[10] == nil) } - if true { + do { var d = getCOWFastDictionary() var identity1 = unsafeBitCast(d, Int.self) let originalCapacity = d._variantStorage.native.capacity @@ -729,7 +729,7 @@ DictionaryTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { assert(d[10] == nil) } - if true { + do { var d1 = getCOWFastDictionary() var identity1 = unsafeBitCast(d1, Int.self) assert(d1.count == 3) @@ -750,7 +750,7 @@ DictionaryTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { _fixLifetime(d2) } - if true { + do { var d1 = getCOWFastDictionary() var identity1 = unsafeBitCast(d1, Int.self) let originalCapacity = d1._variantStorage.native.capacity @@ -775,14 +775,14 @@ DictionaryTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { } DictionaryTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate") { - if true { + do { var d = getCOWSlowDictionary() let originalCapacity = d._variantStorage.native.capacity assert(d.count == 3) assert(d[TestKeyTy(10)]!.value == 1010) d.removeAll() - // We can not assert that identity changed, since the new buffer of smaller + // We cannot assert that identity changed, since the new buffer of smaller // size can be allocated at the same address as the old one. var identity1 = unsafeBitCast(d, Int.self) assert(d._variantStorage.native.capacity < originalCapacity) @@ -795,7 +795,7 @@ DictionaryTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate") { assert(d[TestKeyTy(10)] == nil) } - if true { + do { var d = getCOWSlowDictionary() var identity1 = unsafeBitCast(d, Int.self) let originalCapacity = d._variantStorage.native.capacity @@ -815,7 +815,7 @@ DictionaryTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate") { assert(d[TestKeyTy(10)] == nil) } - if true { + do { var d1 = getCOWSlowDictionary() var identity1 = unsafeBitCast(d1, Int.self) assert(d1.count == 3) @@ -836,7 +836,7 @@ DictionaryTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate") { _fixLifetime(d2) } - if true { + do { var d1 = getCOWSlowDictionary() var identity1 = unsafeBitCast(d1, Int.self) let originalCapacity = d1._variantStorage.native.capacity @@ -1082,18 +1082,18 @@ DictionaryTestSuite.test("deleteChainCollisionRandomized") { } DictionaryTestSuite.test("init(dictionaryLiteral:)") { - if true { + do { var empty = Dictionary() assert(empty.count == 0) assert(empty[1111] == nil) } - if true { + do { var d = Dictionary(dictionaryLiteral: (10, 1010)) assert(d.count == 1) assert(d[10]! == 1010) assert(d[1111] == nil) } - if true { + do { var d = Dictionary(dictionaryLiteral: (10, 1010), (20, 1020)) assert(d.count == 2) @@ -1101,7 +1101,7 @@ DictionaryTestSuite.test("init(dictionaryLiteral:)") { assert(d[20]! == 1020) assert(d[1111] == nil) } - if true { + do { var d = Dictionary(dictionaryLiteral: (10, 1010), (20, 1020), (30, 1030)) assert(d.count == 3) @@ -1110,7 +1110,7 @@ DictionaryTestSuite.test("init(dictionaryLiteral:)") { assert(d[30]! == 1030) assert(d[1111] == nil) } - if true { + do { var d = Dictionary(dictionaryLiteral: (10, 1010), (20, 1020), (30, 1030), (40, 1040)) assert(d.count == 4) @@ -1120,7 +1120,7 @@ DictionaryTestSuite.test("init(dictionaryLiteral:)") { assert(d[40]! == 1040) assert(d[1111] == nil) } - if true { + do { var d: Dictionary = [ 10: 1010, 20: 1020, 30: 1030 ] assert(d.count == 3) assert(d[10]! == 1010) @@ -1339,7 +1339,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.DictionaryIsCopied") { assert(isCocoaDictionary(d)) // Find an existing key. - if true { + do { var kv = d[d.indexForKey(TestObjCKeyTy(10))!] assert(kv.0 == TestObjCKeyTy(10)) assert(kv.1.value == 1010) @@ -1351,7 +1351,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.DictionaryIsCopied") { assert(nsd[TestObjCKeyTy(10)] == nil) // Find an existing key, again. - if true { + do { var kv = d[d.indexForKey(TestObjCKeyTy(10))!] assert(kv.0 == TestObjCKeyTy(10)) assert(kv.1.value == 1010) @@ -1364,7 +1364,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.DictionaryIsCopied") { assert(isNativeDictionary(d)) // Find an existing key. - if true { + do { var kv = d[d.indexForKey(TestBridgedKeyTy(10))!] assert(kv.0 == TestBridgedKeyTy(10)) assert(kv.1.value == 1010) @@ -1376,7 +1376,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.DictionaryIsCopied") { assert(nsd[TestBridgedKeyTy(10)] == nil) // Find an existing key, again. - if true { + do { var kv = d[d.indexForKey(TestBridgedKeyTy(10))!] assert(kv.0 == TestBridgedKeyTy(10)) assert(kv.1.value == 1010) @@ -1476,7 +1476,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.IndexForKey") { assert(isCocoaDictionary(d)) // Find an existing key. - if true { + do { var kv = d[d.indexForKey(TestObjCKeyTy(10))!] assert(kv.0 == TestObjCKeyTy(10)) assert(kv.1.value == 1010) @@ -1501,7 +1501,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.IndexForKey") { assert(isNativeDictionary(d)) // Find an existing key. - if true { + do { var kv = d[d.indexForKey(TestBridgedKeyTy(10))!] assert(kv.0 == TestBridgedKeyTy(10)) assert(kv.1.value == 1010) @@ -1726,7 +1726,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.SubscriptWithKey") { DictionaryTestSuite.test("BridgedFromObjC.Verbatim.UpdateValueForKey") { // Insert a new key-value pair. - if true { + do { var d = getBridgedVerbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isCocoaDictionary(d)) @@ -1746,7 +1746,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.UpdateValueForKey") { } // Overwrite a value in existing binding. - if true { + do { var d = getBridgedVerbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isCocoaDictionary(d)) @@ -1768,7 +1768,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.UpdateValueForKey") { DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.UpdateValueForKey") { // Insert a new key-value pair. - if true { + do { var d = getBridgedNonverbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isNativeDictionary(d)) @@ -1788,7 +1788,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.UpdateValueForKey") { } // Overwrite a value in existing binding. - if true { + do { var d = getBridgedNonverbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isNativeDictionary(d)) @@ -1849,7 +1849,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAtIndex") { DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveValueForKey") { - if true { + do { var d = getBridgedVerbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isCocoaDictionary(d)) @@ -1872,7 +1872,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveValueForKey") { assert(identity2 == unsafeBitCast(d, Int.self)) } - if true { + do { var d1 = getBridgedVerbatimDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -1908,7 +1908,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveValueForKey") { } DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveValueForKey") { - if true { + do { var d = getBridgedNonverbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isNativeDictionary(d)) @@ -1931,7 +1931,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveValueForKey") { assert(identity2 == unsafeBitCast(d, Int.self)) } - if true { + do { var d1 = getBridgedNonverbatimDictionary() var identity1 = unsafeBitCast(d1, Int.self) @@ -1968,7 +1968,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveValueForKey") { DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { - if true { + do { var d = getBridgedVerbatimDictionary([:]) var identity1 = unsafeBitCast(d, Int.self) assert(isCocoaDictionary(d)) @@ -1979,7 +1979,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { assert(d.count == 0) } - if true { + do { var d = getBridgedVerbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isCocoaDictionary(d)) @@ -1994,7 +1994,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { assert(d[TestObjCKeyTy(10)] == nil) } - if true { + do { var d = getBridgedVerbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isCocoaDictionary(d)) @@ -2009,7 +2009,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { assert(d[TestObjCKeyTy(10)] == nil) } - if true { + do { var d1 = getBridgedVerbatimDictionary() var identity1 = unsafeBitCast(d1, Int.self) assert(isCocoaDictionary(d1)) @@ -2029,7 +2029,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { assert(d2[TestObjCKeyTy(10)] == nil) } - if true { + do { var d1 = getBridgedVerbatimDictionary() var identity1 = unsafeBitCast(d1, Int.self) assert(isCocoaDictionary(d1)) @@ -2051,7 +2051,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { } DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { - if true { + do { var d = getBridgedNonverbatimDictionary([:]) var identity1 = unsafeBitCast(d, Int.self) assert(isNativeDictionary(d)) @@ -2062,7 +2062,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { assert(d.count == 0) } - if true { + do { var d = getBridgedNonverbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isNativeDictionary(d)) @@ -2077,7 +2077,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { assert(d[TestBridgedKeyTy(10)] == nil) } - if true { + do { var d = getBridgedNonverbatimDictionary() var identity1 = unsafeBitCast(d, Int.self) assert(isNativeDictionary(d)) @@ -2092,7 +2092,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { assert(d[TestBridgedKeyTy(10)] == nil) } - if true { + do { var d1 = getBridgedNonverbatimDictionary() var identity1 = unsafeBitCast(d1, Int.self) assert(isNativeDictionary(d1)) @@ -2112,7 +2112,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { assert(d2[TestBridgedKeyTy(10)] == nil) } - if true { + do { var d1 = getBridgedNonverbatimDictionary() var identity1 = unsafeBitCast(d1, Int.self) assert(isNativeDictionary(d1)) @@ -2199,7 +2199,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.Generate_Empty") { assert(isCocoaDictionary(d)) var gen = d.generate() - // Can not write code below because of + // Cannot write code below because of // Optional tuples are broken as optionals regarding == comparison // assert(gen.next() == .None) assert(gen.next() == nil) @@ -2217,7 +2217,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Nonverbatim.Generate_Empty") { assert(isNativeDictionary(d)) var gen = d.generate() - // Can not write code below because of + // Cannot write code below because of // Optional tuples are broken as optionals regarding == comparison // assert(gen.next() == .None) assert(gen.next() == nil) @@ -2392,7 +2392,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.EqualityTest_Small") { var identity2 = unsafeBitCast(d2, Int.self) assert(isCocoaDictionary(d2)) - if true { + do { let eq1 = (d1 == d2) assert(eq1 == expectedEq) @@ -2414,7 +2414,7 @@ DictionaryTestSuite.test("BridgedFromObjC.Verbatim.EqualityTest_Small") { assert(identity2 != unsafeBitCast(d2, Int.self)) identity2 = unsafeBitCast(d2, Int.self) - if true { + do { let eq1 = (d1 == d2) assert(eq1 == expectedEq) @@ -2876,7 +2876,7 @@ DictionaryTestSuite.test("BridgingRoundtrip") { // NSDictionary -> Dictionary implicit conversion. //===--- -DictionaryTestSuite.test("NSDictionaryToDictionaryCoversion") { +DictionaryTestSuite.test("NSDictionaryToDictionaryConversion") { let keys = [ 10, 20, 30 ].map { TestObjCKeyTy($0) } let values = [ 1010, 1020, 1030 ].map { TestObjCValueTy($0) } @@ -2892,7 +2892,7 @@ DictionaryTestSuite.test("NSDictionaryToDictionaryCoversion") { assert(equalsUnordered(pairs, [ (10, 1010), (20, 1020), (30, 1030) ])) } -DictionaryTestSuite.test("DictionaryToNSDictionaryCoversion") { +DictionaryTestSuite.test("DictionaryToNSDictionaryConversion") { var d = Dictionary(minimumCapacity: 32) d[TestObjCKeyTy(10)] = TestObjCValueTy(1010) d[TestObjCKeyTy(20)] = TestObjCValueTy(1020) @@ -2956,7 +2956,7 @@ DictionaryTestSuite.test("DictionaryUpcastBridgedEntryPoint") { d[TestBridgedKeyTy(20)] = TestBridgedValueTy(1020) d[TestBridgedKeyTy(30)] = TestBridgedValueTy(1030) - if true { + do { var dOO: Dictionary = _dictionaryBridgeToObjectiveC(d) assert(dOO.count == 3) @@ -2970,7 +2970,7 @@ DictionaryTestSuite.test("DictionaryUpcastBridgedEntryPoint") { assert((v! as! TestBridgedValueTy).value == 1030) } - if true { + do { var dOV: Dictionary = _dictionaryBridgeToObjectiveC(d) @@ -2985,7 +2985,7 @@ DictionaryTestSuite.test("DictionaryUpcastBridgedEntryPoint") { assert(v!.value == 1030) } - if true { + do { var dVO: Dictionary = _dictionaryBridgeToObjectiveC(d) @@ -3007,7 +3007,7 @@ DictionaryTestSuite.test("DictionaryUpcastBridged") { d[TestBridgedKeyTy(20)] = TestBridgedValueTy(1020) d[TestBridgedKeyTy(30)] = TestBridgedValueTy(1030) - if true { + do { var dOO: Dictionary = d assert(dOO.count == 3) @@ -3021,7 +3021,7 @@ DictionaryTestSuite.test("DictionaryUpcastBridged") { assert((v! as! TestBridgedValueTy).value == 1030) } - if true { + do { var dOV: Dictionary = d assert(dOV.count == 3) @@ -3035,7 +3035,7 @@ DictionaryTestSuite.test("DictionaryUpcastBridged") { assert(v!.value == 1030) } - if true { + do { var dVO: Dictionary = d assert(dVO.count == 3) @@ -3163,7 +3163,7 @@ DictionaryTestSuite.test("DictionaryBridgeFromObjectiveCEntryPoint") { // Successful downcast. let dCV: Dictionary = _dictionaryBridgeFromObjectiveC(d) - if true { + do { assert(dCV.count == 3) var v = dCV[TestObjCKeyTy(10)] assert(v!.value == 1010) @@ -3178,7 +3178,7 @@ DictionaryTestSuite.test("DictionaryBridgeFromObjectiveCEntryPoint") { // Successful downcast. let dVC: Dictionary = _dictionaryBridgeFromObjectiveC(d) - if true { + do { assert(dVC.count == 3) var v = dVC[TestBridgedKeyTy(10)] assert(v!.value == 1010) @@ -3193,7 +3193,7 @@ DictionaryTestSuite.test("DictionaryBridgeFromObjectiveCEntryPoint") { // Successful downcast. let dVV: Dictionary = _dictionaryBridgeFromObjectiveC(d) - if true { + do { assert(dVV.count == 3) var v = dVV[TestBridgedKeyTy(10)] assert(v!.value == 1010) @@ -3214,7 +3214,7 @@ DictionaryTestSuite.test("DictionaryBridgeFromObjectiveC") { // Successful downcast. let dCV = d as! Dictionary - if true { + do { assert(dCV.count == 3) var v = dCV[TestObjCKeyTy(10)] assert(v!.value == 1010) @@ -3228,7 +3228,7 @@ DictionaryTestSuite.test("DictionaryBridgeFromObjectiveC") { // Successful downcast. let dVC = d as! Dictionary - if true { + do { assert(dVC.count == 3) var v = dVC[TestBridgedKeyTy(10)] assert(v!.value == 1010) @@ -3242,7 +3242,7 @@ DictionaryTestSuite.test("DictionaryBridgeFromObjectiveC") { // Successful downcast. let dVV = d as! Dictionary - if true { + do { assert(dVV.count == 3) var v = dVV[TestBridgedKeyTy(10)] assert(v!.value == 1010) @@ -3457,11 +3457,11 @@ func getMockDictionaryWithCustomCount(count count: Int) } DictionaryDerivedAPIs.test("isEmpty") { - if true { + do { var empty = Dictionary() expectTrue(empty.isEmpty) } - if true { + do { var d = getDerivedAPIsDictionary() expectFalse(d.isEmpty) } @@ -3472,26 +3472,26 @@ func callGenericIsEmpty(collection: C) -> Bool { } DictionaryDerivedAPIs.test("isEmpty/ImplementationIsCustomized") { - if true { + do { var d = getMockDictionaryWithCustomCount(count: 0) MockDictionaryWithCustomCount.timesCountWasCalled = 0 expectTrue(d.isEmpty) expectEqual(1, MockDictionaryWithCustomCount.timesCountWasCalled) } - if true { + do { var d = getMockDictionaryWithCustomCount(count: 0) MockDictionaryWithCustomCount.timesCountWasCalled = 0 expectTrue(callGenericIsEmpty(d)) expectEqual(1, MockDictionaryWithCustomCount.timesCountWasCalled) } - if true { + do { var d = getMockDictionaryWithCustomCount(count: 4) MockDictionaryWithCustomCount.timesCountWasCalled = 0 expectFalse(d.isEmpty) expectEqual(1, MockDictionaryWithCustomCount.timesCountWasCalled) } - if true { + do { var d = getMockDictionaryWithCustomCount(count: 4) MockDictionaryWithCustomCount.timesCountWasCalled = 0 expectFalse(callGenericIsEmpty(d)) @@ -3500,12 +3500,12 @@ DictionaryDerivedAPIs.test("isEmpty/ImplementationIsCustomized") { } DictionaryDerivedAPIs.test("keys") { - if true { + do { var empty = Dictionary() var keys = Array(empty.keys) expectTrue(equalsUnordered(keys, [])) } - if true { + do { var d = getDerivedAPIsDictionary() var keys = Array(d.keys) expectTrue(equalsUnordered(keys, [ 10, 20, 30 ])) @@ -3513,12 +3513,12 @@ DictionaryDerivedAPIs.test("keys") { } DictionaryDerivedAPIs.test("values") { - if true { + do { var empty = Dictionary() var values = Array(empty.values) expectTrue(equalsUnordered(values, [])) } - if true { + do { var d = getDerivedAPIsDictionary() var values = Array(d.values) @@ -3540,7 +3540,7 @@ class ObjCThunksHelper : NSObject { } dynamic func acceptArrayBridgedNonverbatim(array: [TestBridgedValueTy]) { - // Can not check elements because doing so would bridge them. + // Cannot check elements because doing so would bridge them. expectEqual(3, array.count) } @@ -3565,7 +3565,7 @@ class ObjCThunksHelper : NSObject { dynamic func acceptDictionaryBridgedNonverbatim( d: [TestBridgedKeyTy : TestBridgedValueTy]) { expectEqual(3, d.count) - // Can not check elements because doing so would bridge them. + // Cannot check elements because doing so would bridge them. } dynamic func returnDictionaryBridgedVerbatim() -> @@ -3590,11 +3590,11 @@ class ObjCThunksHelper : NSObject { ObjCThunks.test("Array/Accept") { var helper = ObjCThunksHelper() - if true { + do { helper.acceptArrayBridgedVerbatim( [ TestObjCValueTy(10), TestObjCValueTy(20), TestObjCValueTy(30) ]) } - if true { + do { TestBridgedValueTy.bridgeOperations = 0 helper.acceptArrayBridgedNonverbatim( [ TestBridgedValueTy(10), TestBridgedValueTy(20), @@ -3606,13 +3606,13 @@ ObjCThunks.test("Array/Accept") { ObjCThunks.test("Array/Return") { var helper = ObjCThunksHelper() - if true { + do { let a = helper.returnArrayBridgedVerbatim() expectEqual(10, a[0].value) expectEqual(20, a[1].value) expectEqual(30, a[2].value) } - if true { + do { TestBridgedValueTy.bridgeOperations = 0 let a = helper.returnArrayBridgedNonverbatim() expectEqual(0, TestBridgedValueTy.bridgeOperations) @@ -3628,13 +3628,13 @@ ObjCThunks.test("Array/Return") { ObjCThunks.test("Dictionary/Accept") { var helper = ObjCThunksHelper() - if true { + do { helper.acceptDictionaryBridgedVerbatim( [ TestObjCKeyTy(10): TestObjCValueTy(1010), TestObjCKeyTy(20): TestObjCValueTy(1020), TestObjCKeyTy(30): TestObjCValueTy(1030) ]) } - if true { + do { TestBridgedKeyTy.bridgeOperations = 0 TestBridgedValueTy.bridgeOperations = 0 helper.acceptDictionaryBridgedNonverbatim( @@ -3649,14 +3649,14 @@ ObjCThunks.test("Dictionary/Accept") { ObjCThunks.test("Dictionary/Return") { var helper = ObjCThunksHelper() - if true { + do { let d = helper.returnDictionaryBridgedVerbatim() expectEqual(3, d.count) expectEqual(1010, d[TestObjCKeyTy(10)]!.value) expectEqual(1020, d[TestObjCKeyTy(20)]!.value) expectEqual(1030, d[TestObjCKeyTy(30)]!.value) } - if true { + do { TestBridgedKeyTy.bridgeOperations = 0 TestBridgedValueTy.bridgeOperations = 0 let d = helper.returnDictionaryBridgedNonverbatim() @@ -3737,7 +3737,7 @@ DictionaryTestSuite.test( //===--- DictionaryTestSuite.test("misc") { - if true { + do { // Dictionary literal var dict = [ "Hello": 1, "World": 2 ] @@ -3758,7 +3758,7 @@ DictionaryTestSuite.test("misc") { expectEmpty(dict["Universe"]) } - if true { + do { // Dictionaries with other types var d = [ 1.2: 1, 2.6: 2 ] d[3.3] = 3 @@ -3767,7 +3767,7 @@ DictionaryTestSuite.test("misc") { expectOptionalEqual(3, d[3.3]) } - if true { + do { var d = Dictionary(minimumCapacity: 13) d["one"] = 1 d["two"] = 2 @@ -3806,13 +3806,13 @@ DictionaryTestSuite.test("dropsBridgedCache") { // implementation. // This test will only fail in address sanitizer. var dict = [0:10] - if true { + do { var bridged: NSDictionary = dict expectEqual(10, bridged[0] as! Int) } dict[0] = 11 - if true { + do { var bridged: NSDictionary = dict expectEqual(11, bridged[0] as! Int) } @@ -3843,13 +3843,13 @@ DictionaryTestSuite.test("getObjects:andKeys:") { DictionaryTestSuite.test("popFirst") { // Empty - if true { + do { var d = [Int: Int]() let popped = d.popFirst() expectEmpty(popped) } - if true { + do { var popped = [(Int, Int)]() var d: [Int: Int] = [ 1010: 1010, diff --git a/validation-test/stdlib/ErrorType.swift b/validation-test/stdlib/ErrorType.swift index 9eb398222724c..3592a8b4a731d 100644 --- a/validation-test/stdlib/ErrorType.swift +++ b/validation-test/stdlib/ErrorType.swift @@ -7,6 +7,14 @@ import SwiftPrivate import StdlibUnittest import Foundation +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivatePthreadExtras +#if _runtime(_ObjC) +import ObjectiveC +#endif + enum SomeError : ErrorType { case GoneToFail } diff --git a/validation-test/stdlib/FixedPoint.swift.gyb b/validation-test/stdlib/FixedPoint.swift.gyb index 80dc152d97343..7fb0da54149bf 100644 --- a/validation-test/stdlib/FixedPoint.swift.gyb +++ b/validation-test/stdlib/FixedPoint.swift.gyb @@ -5,6 +5,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var FixedPoint = TestSuite("FixedPoint") %{ @@ -83,7 +91,7 @@ FixedPoint.test("${Dst}(truncatingBitPattern:)") { % % for bit_pattern in test_bit_patterns: - if true { + do { % input = prepare_bit_pattern(bit_pattern, src_ty.bits, src_ty.is_signed) let input = get${Src}(${input}) % input = prepare_bit_pattern(input, src_ty.bits, False) @@ -154,7 +162,7 @@ FixedPoint.test("${Dst}(bitPattern: ${Src})") { % for bit_pattern in test_bit_patterns: - if true { + do { % input = prepare_bit_pattern(bit_pattern, src_ty.bits, src_ty.is_signed) let input = get${Src}(${input}) % input = prepare_bit_pattern(input, src_ty.bits, False) @@ -163,7 +171,7 @@ FixedPoint.test("${Dst}(bitPattern: ${Src})") { expectEqual(expected, output) } - if true { + do { % input = prepare_bit_pattern(bit_pattern, src_ty.bits, src_ty.is_signed) let input = get${Src}(${input}) @@ -226,7 +234,7 @@ FixedPoint.test("${Self}.hashValue") { % for bit_pattern in test_bit_patterns: - if true { + do { % input = prepare_bit_pattern(bit_pattern, self_ty.bits, self_ty.is_signed) let input = get${Self}(${input}) let output = getInt(input.hashValue) @@ -329,11 +337,11 @@ FixedPoint.test("byteSwapped") { var BoolTestSuite = TestSuite("Bool") BoolTestSuite.test("literals") { - if true { + do { var v = false expectType(Bool.self, &v) } - if true { + do { var v = true expectType(Bool.self, &v) } @@ -349,34 +357,34 @@ struct Booleanish : BooleanType { } BoolTestSuite.test("init(_:)") { - if true { + do { let v = Bool(Booleanish(boolValue: false)) expectFalse(v) } - if true { + do { let v = Bool(Booleanish(boolValue: true)) expectTrue(v) } } BoolTestSuite.test("BooleanType") { - if true { + do { var v: Bool = false expectIsBooleanType(&v) expectFalse(v.boolValue) } - if true { + do { var v: Bool = true expectTrue(v.boolValue) } } BoolTestSuite.test("CustomStringConvertible") { - if true { + do { let v: Bool = false expectEqual("false", String(v)) } - if true { + do { let v: Bool = true expectEqual("true", String(v)) } @@ -391,13 +399,13 @@ BoolTestSuite.test("Equatable,Hashable") { } BoolTestSuite.test("!") { - if true { + do { let v: Bool = false var r = !v expectType(Bool.self, &r) expectTrue(r) } - if true { + do { let v: Bool = true var r = !v expectType(Bool.self, &r) @@ -407,11 +415,11 @@ BoolTestSuite.test("!") { BoolTestSuite.test("==,!=") { let v: Bool = false - if true { + do { var r = (v == v) expectType(Bool.self, &r) } - if true { + do { var r = (v != v) expectType(Bool.self, &r) } diff --git a/validation-test/stdlib/FixedPointArithmeticTraps.swift.gyb b/validation-test/stdlib/FixedPointArithmeticTraps.swift.gyb index 58d7dc95f7da5..c5f9ddd26a3a5 100644 --- a/validation-test/stdlib/FixedPointArithmeticTraps.swift.gyb +++ b/validation-test/stdlib/FixedPointArithmeticTraps.swift.gyb @@ -19,13 +19,13 @@ import ObjectiveC #endif // Note: in this file, we need to go through opaque functions to load -// constants. This is to to check runtime behaviour and ensure the constant is +// constants. This is to check runtime behaviour and ensure the constant is // not folded. func expectOverflow( res: (T, overflow: Bool), //===--- TRACE boilerplate ----------------------------------------------===// - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__ @@ -38,7 +38,7 @@ func expectOverflow( func expectNoOverflow( res: (T, overflow: Bool), //===--- TRACE boilerplate ----------------------------------------------===// - @autoclosure _ message: ()->String = "", + @autoclosure _ message: () -> String = "", showFrame: Bool = true, stackTrace: SourceLocStack = SourceLocStack(), file: String = __FILE__, line: UInt = __LINE__ @@ -151,7 +151,7 @@ FixedPointArithmeticTraps.test("Subtraction/${IntTy}") { // Test multiplication for ${IntTy} // -FixedPointArithmeticTraps.test("Multplication/${IntTy}") { +FixedPointArithmeticTraps.test("Multiplication/${IntTy}") { var a = get${IntTy}(${IntTy}.max / 3) expectNoOverflow(${IntTy}.multiplyWithOverflow(a, get${IntTy}(2))) @@ -325,7 +325,7 @@ FixedPointTruncationTraps.test("SignedToUnsignedTruncation/src=-1") { _blackHole(result) } -FixedPointTruncationTraps.test("SignedToUnignedSameSize/src=min") { +FixedPointTruncationTraps.test("SignedToUnsignedSameSize/src=min") { var x = getInt8(-128) expectCrashLater() var result = UInt16(x) diff --git a/validation-test/stdlib/FixedPointDiagnostics.swift.gyb b/validation-test/stdlib/FixedPointDiagnostics.swift.gyb index f9ab6588a678e..54734b5c51d70 100644 --- a/validation-test/stdlib/FixedPointDiagnostics.swift.gyb +++ b/validation-test/stdlib/FixedPointDiagnostics.swift.gyb @@ -81,7 +81,7 @@ func testMixedSignArithmetic() { // allow mixed-sign arithmetic to compile. We create a deliberate // ambiguity in these cases. % for T in "UInt UInt64 UInt32 UInt16 UInt8".split(): - if true { + do { typealias Stride = ${T}.Stride ${T}(1) + 0 // OK 0 + ${T}(1) // OK diff --git a/validation-test/stdlib/FloatingPointConversionTraps.swift.gyb b/validation-test/stdlib/FloatingPointConversionTraps.swift.gyb index 19c08362578a0..87018d2423ea5 100644 --- a/validation-test/stdlib/FloatingPointConversionTraps.swift.gyb +++ b/validation-test/stdlib/FloatingPointConversionTraps.swift.gyb @@ -76,11 +76,11 @@ var FloatingPointConversion = TestSuite("FloatingPointConversion") FloatingPointConversion.test("${FloatSelf}/${IntSelf}/+inf") .xfail(.Custom({ "${FloatSelf}" == "Float80" }, reason: " Int(Float80.quietNaN) is garbage")) .crashOutputMatches(getInfiniteOrNaNMessage("${FloatSelf}")).code { - if true { + do { var a = get${IntSelf}(${IntSelf}(get${FloatSelf}(0.0))) expectEqual(0, a) } - if true { + do { var a = get${IntSelf}(${IntSelf}(get${FloatSelf}(123.0))) expectEqual(123, a) } @@ -94,11 +94,11 @@ FloatingPointConversion.test("${FloatSelf}/${IntSelf}/+inf") FloatingPointConversion.test("${FloatSelf}/${IntSelf}/-inf") .xfail(.Custom({ "${FloatSelf}" == "Float80" }, reason: " Int(Float80.quietNaN) is garbage")) .crashOutputMatches(getInfiniteOrNaNMessage("${FloatSelf}")).code { - if true { + do { var a = get${IntSelf}(${IntSelf}(get${FloatSelf}(-0.0))) expectEqual(0, a) } - if true { + do { var a = get${IntSelf}(${IntSelf}(get${FloatSelf}(-123.0))) expectEqual(-123, a) } diff --git a/validation-test/stdlib/GameplayKit.swift b/validation-test/stdlib/GameplayKit.swift index fb749e361d41e..e2c482dc0fd18 100644 --- a/validation-test/stdlib/GameplayKit.swift +++ b/validation-test/stdlib/GameplayKit.swift @@ -24,7 +24,7 @@ GamePlayKitTests.test("GKEntity.componentForClass()") { let entity = GKEntity() entity.addComponent(TestComponent()) - if true { + do { var componentForTestComponent = entity.componentForClass(TestComponent.self) var componentForOtherTestComponent_nil = @@ -39,7 +39,7 @@ GamePlayKitTests.test("GKEntity.componentForClass()") { entity.removeComponentForClass(TestComponent.self) entity.addComponent(OtherTestComponent()) - if true { + do { var componentForOtherTestComponent = entity.componentForClass(OtherTestComponent.self) var componentForTestComponent_nil = @@ -53,7 +53,7 @@ GamePlayKitTests.test("GKEntity.componentForClass()") { } GamePlayKitTests.test("GKStateMachine.stateForClass()") { - if true { + do { // Construct a state machine with a custom subclass as the only state. let stateMachine = GKStateMachine( states: [TestState1()]) @@ -69,7 +69,7 @@ GamePlayKitTests.test("GKStateMachine.stateForClass()") { expectEmpty(stateForTestState2_nil) } - if true { + do { // Construct a state machine with a custom subclass as the only state. let stateMachine = GKStateMachine( states: [TestState2()]) diff --git a/validation-test/stdlib/Hashing.swift b/validation-test/stdlib/Hashing.swift index e26b4d1ba19aa..60fd36fb383a8 100644 --- a/validation-test/stdlib/Hashing.swift +++ b/validation-test/stdlib/Hashing.swift @@ -5,6 +5,13 @@ import Swift import SwiftPrivate import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +#if _runtime(_ObjC) +import ObjectiveC +#endif + var HashingTestSuite = TestSuite("Hashing") HashingTestSuite.test("_mixUInt32/GoldenValues") { diff --git a/validation-test/stdlib/NumericDiagnostics.swift.gyb b/validation-test/stdlib/NumericDiagnostics.swift.gyb index 63f779f3711e2..9b3fda661c9cd 100644 --- a/validation-test/stdlib/NumericDiagnostics.swift.gyb +++ b/validation-test/stdlib/NumericDiagnostics.swift.gyb @@ -30,7 +30,7 @@ func testIteratedOperations() { % "// expected-note{{add an explicit type annotation}} expected-warning{{inferred to have type}}"\ % if (op in all_integer_assignment_operator_names() + all_integer_or_real_assignment_operator_names())\ % else "" #FIXME Temporary workaround for rdar://15928178 gyb miscompiles nested if elif - if true { // ${count} + do { // ${count} var x1_${T1}: ${T1} = 0 var x2_${T2}: ${T2} = 0 var result = x1_${T1} ${op} x2_${T2} ${theDiagnostic} diff --git a/validation-test/stdlib/OpenCLSDKOverlay.swift b/validation-test/stdlib/OpenCLSDKOverlay.swift index 7e13de5b25a11..10ee799571a02 100644 --- a/validation-test/stdlib/OpenCLSDKOverlay.swift +++ b/validation-test/stdlib/OpenCLSDKOverlay.swift @@ -132,7 +132,7 @@ tests.test("clSetKernelArgsListAPPLE") { // Create the compute program from the source buffer // program = KernelSource.withCString { - (s: UnsafePointer)->cl_program in + (s: UnsafePointer) -> cl_program in var s = s return withUnsafeMutablePointer(&s) { return clCreateProgramWithSource(context, 1, $0, nil, &err) @@ -246,7 +246,7 @@ tests.test("clSetKernelArgsListAPPLE") { for(i = 0; i < count; i++) { if(results[i] == data[i] * data[i]){ - correct++ + correct += 1 } } diff --git a/validation-test/stdlib/SceneKit.swift b/validation-test/stdlib/SceneKit.swift index 64f6896274451..68ab1e85ec08e 100644 --- a/validation-test/stdlib/SceneKit.swift +++ b/validation-test/stdlib/SceneKit.swift @@ -301,7 +301,7 @@ if #available(iOS 8.0, *) { allowLossyConversion: true)! let sceneSource = SCNSceneSource(data: sceneData, options: nil)! - if true { + do { var unarchivedPlaneGeometry = sceneSource.entryWithIdentifier("plane", withClass: SCNGeometry.self) var unarchivedPlaneNode_nil = @@ -313,7 +313,7 @@ if #available(iOS 8.0, *) { expectEmpty(unarchivedPlaneNode_nil) } - if true { + do { var unarchivedBoxGeometry = sceneSource.entryWithIdentifier("box", withClass: SCNGeometry.self) var unarchivedBoxGeometry_nil = @@ -325,7 +325,7 @@ if #available(iOS 8.0, *) { expectEmpty(unarchivedBoxGeometry_nil) } - if true { + do { var unarchivedBoxNode = sceneSource.entryWithIdentifier("box-node", withClass: SCNNode.self) var unarchivedBoxNode_nil = diff --git a/validation-test/stdlib/SequenceType.swift.gyb b/validation-test/stdlib/SequenceType.swift.gyb index 9414feabe1928..dd156b6496756 100644 --- a/validation-test/stdlib/SequenceType.swift.gyb +++ b/validation-test/stdlib/SequenceType.swift.gyb @@ -12,7 +12,7 @@ import SwiftPrivate // Extend LoggingSequence to shadow the new operation. When // requirements are added to a protocol 'P', there should be an -// implementation in 'InstrumentedP' that does some bookeeping for +// implementation in 'InstrumentedP' that does some bookkeeping for // testing (like counting calls to the operation) and then dispatches // to the same operation on its 'base' member. InstrumentedSequence // already contains implementations of all the SequenceType @@ -150,7 +150,7 @@ SequenceTypeTests.test("Demonstration/NotCustomizable") { } SequenceTypeTests.test("GeneratorSequence/GeneratorType/empty") { - if true { + do { let data: [OpaqueValue] = [] let base = MinimalGenerator(data) var g = GeneratorSequence(base) @@ -159,7 +159,7 @@ SequenceTypeTests.test("GeneratorSequence/GeneratorType/empty") { &g) checkGenerator(data, g, resiliencyChecks: .none) { $0.value == $1.value } } - if true { + do { let data: [OpaqueValue] = [] let base = data.generate() var g = GeneratorSequence(base) @@ -171,7 +171,7 @@ SequenceTypeTests.test("GeneratorSequence/GeneratorType/empty") { } SequenceTypeTests.test("GeneratorSequence/GeneratorType") { - if true { + do { let data: [OpaqueValue] = [] let base = MinimalGenerator(data) var g = GeneratorSequence(base) @@ -180,7 +180,7 @@ SequenceTypeTests.test("GeneratorSequence/GeneratorType") { &g) checkGenerator(data, g, resiliencyChecks: .none) { $0.value == $1.value } } - if true { + do { let data: [OpaqueValue] = [] let base = data.generate() var g = GeneratorSequence(base) @@ -192,7 +192,7 @@ SequenceTypeTests.test("GeneratorSequence/GeneratorType") { } SequenceTypeTests.test("GeneratorSequence/SequenceType/empty") { - if true { + do { let data = [ 10, 20, 30 ].map(OpaqueValue.init) let base = MinimalGenerator(data) var g = GeneratorSequence(base) @@ -201,7 +201,7 @@ SequenceTypeTests.test("GeneratorSequence/SequenceType/empty") { &g) checkSequence(data, g, resiliencyChecks: .none) { $0.value == $1.value } } - if true { + do { let data = [ 10, 20, 30 ].map(OpaqueValue.init) let base = data.generate() var g = GeneratorSequence(base) @@ -213,7 +213,7 @@ SequenceTypeTests.test("GeneratorSequence/SequenceType/empty") { } SequenceTypeTests.test("GeneratorSequence/SequenceType") { - if true { + do { let data = [ 10, 20, 30 ].map(OpaqueValue.init) let base = MinimalGenerator(data) var g = GeneratorSequence(base) @@ -222,7 +222,7 @@ SequenceTypeTests.test("GeneratorSequence/SequenceType") { &g) checkSequence(data, g, resiliencyChecks: .none) { $0.value == $1.value } } - if true { + do { let data = [ 10, 20, 30 ].map(OpaqueValue.init) let base = data.generate() var g = GeneratorSequence(base) @@ -280,7 +280,7 @@ SequenceTypeTests.test("enumerate") { SequenceTypeTests.test("startsWith/WhereElementIsEquatable") { for test in startsWithTests { - if true { + do { let s = MinimalSequence( elements: test.sequence.map(MinimalEquatableValue.init)) let prefix = MinimalSequence( @@ -298,7 +298,7 @@ SequenceTypeTests.test("startsWith/WhereElementIsEquatable") { } // Use different types for the sequence and prefix. - if true { + do { let s = MinimalForwardCollection( elements: test.sequence.map(MinimalEquatableValue.init)) let prefix = MinimalSequence( @@ -319,7 +319,7 @@ SequenceTypeTests.test("startsWith/WhereElementIsEquatable") { SequenceTypeTests.test("startsWith/Predicate") { for test in startsWithTests { - if true { + do { let s = MinimalSequence>( elements: test.sequence.map(OpaqueValue.init)) let prefix = MinimalSequence>( @@ -335,7 +335,7 @@ SequenceTypeTests.test("startsWith/Predicate") { test.expectedLeftoverPrefix, prefix.map { $0.value }, stackTrace: SourceLocStack().with(test.loc)) } - if true { + do { let s = MinimalSequence>( elements: test.sequence.map { OpaqueValue($0 * 2) }) let prefix = MinimalSequence>( @@ -353,7 +353,7 @@ SequenceTypeTests.test("startsWith/Predicate") { } // Use different types for the sequence and prefix. - if true { + do { let s = MinimalForwardCollection>( elements: test.sequence.map(OpaqueValue.init)) let prefix = MinimalSequence>( @@ -378,7 +378,7 @@ SequenceTypeTests.test("startsWith/Predicate") { SequenceTypeTests.test("elementsEqual/WhereElementIsEquatable") { for test in elementsEqualTests { - if true { + do { let s = MinimalSequence( elements: test.sequence.map(MinimalEquatableValue.init)) let other = MinimalSequence( @@ -396,7 +396,7 @@ SequenceTypeTests.test("elementsEqual/WhereElementIsEquatable") { } // Use different types for the sequence and other. - if true { + do { let s = MinimalForwardCollection( elements: test.sequence.map(MinimalEquatableValue.init)) let other = MinimalSequence( @@ -417,7 +417,7 @@ SequenceTypeTests.test("elementsEqual/WhereElementIsEquatable") { SequenceTypeTests.test("elementsEqual/Predicate") { for test in elementsEqualTests { - if true { + do { let s = MinimalSequence>( elements: test.sequence.map(OpaqueValue.init)) let other = MinimalSequence>( @@ -435,7 +435,7 @@ SequenceTypeTests.test("elementsEqual/Predicate") { } // Use different types for the sequence and other. - if true { + do { let s = MinimalForwardCollection>( elements: test.sequence.map(OpaqueValue.init)) let other = MinimalSequence>( @@ -460,7 +460,7 @@ SequenceTypeTests.test("elementsEqual/Predicate") { SequenceTypeTests.test("lexicographicalCompare/WhereElementIsComparable") { for test in lexicographicalCompareTests { - if true { + do { let s = MinimalSequence( elements: test.sequence.map(MinimalComparableValue.init)) let other = MinimalSequence( @@ -478,7 +478,7 @@ SequenceTypeTests.test("lexicographicalCompare/WhereElementIsComparable") { } // Use different types for the sequence and other. - if true { + do { let s = MinimalForwardCollection( elements: test.sequence.map(MinimalComparableValue.init)) let other = MinimalSequence( @@ -499,7 +499,7 @@ SequenceTypeTests.test("lexicographicalCompare/WhereElementIsComparable") { SequenceTypeTests.test("lexicographicalCompare/Predicate") { for test in lexicographicalCompareTests { - if true { + do { let s = MinimalSequence>( elements: test.sequence.map(OpaqueValue.init)) let other = MinimalSequence>( @@ -517,7 +517,7 @@ SequenceTypeTests.test("lexicographicalCompare/Predicate") { } // Use different types for the sequence and other. - if true { + do { let s = MinimalForwardCollection>( elements: test.sequence.map(OpaqueValue.init)) let other = MinimalSequence>( @@ -1089,11 +1089,11 @@ struct SequenceWithCustomUnderestimateCount : SequenceType { } SequenceTypeTests.test("underestimateCount/SequenceType/CustomImplementation") { - if true { + do { let s = SequenceWithCustomUnderestimateCount(underestimatedCount: 5) expectEqual(5, callGenericUnderestimatedCount(s)) } - if true { + do { let s = SequenceWithCustomUnderestimateCount(underestimatedCount: 42) expectEqual(42, callGenericUnderestimatedCount(s)) } @@ -1120,7 +1120,7 @@ SequenceTypeTests.test("_copyToNativeArrayBuffer/OverestimatedCount") //===----------------------------------------------------------------------===// % for Base in [ 'DefaultedSequence', 'MinimalSequence' ]: -if true { +do { let checksAdded: Box> = Box([]) let resiliencyChecks = CollectionMisuseResiliencyChecks.all diff --git a/validation-test/stdlib/Set.swift b/validation-test/stdlib/Set.swift index 7cf0b2f8b973c..e3ec6c02e83e0 100644 --- a/validation-test/stdlib/Set.swift +++ b/validation-test/stdlib/Set.swift @@ -93,8 +93,7 @@ func helperDeleteThree(k1: TestKeyTy, _ k2: TestKeyTy, _ k3: TestKeyTy) { } func uniformRandom(max: Int) -> Int { - // FIXME: this is not uniform. - return random() % max + return Int(arc4random_uniform(UInt32(max))) } func pickRandom(a: [T]) -> T { @@ -391,7 +390,7 @@ SetTestSuite.test("COW.Fast.ContainsDoesNotReallocate") { expectTrue(s.contains(1010)) expectEqual(identity1, unsafeBitCast(s, Int.self)) - if true { + do { var s2: Set = [] MinimalHashableValue.timesEqualEqualWasCalled = 0 MinimalHashableValue.timesHashValueWasCalled = 0 @@ -436,7 +435,7 @@ SetTestSuite.test("COW.Slow.ContainsDoesNotReallocate") { expectTrue(s.contains(TestKeyTy(3030))) expectTrue(s.contains(TestKeyTy(4040))) - if true { + do { var s2: Set = [] MinimalHashableClass.timesEqualEqualWasCalled = 0 MinimalHashableClass.timesHashValueWasCalled = 0 @@ -468,7 +467,7 @@ SetTestSuite.test("COW.Fast.InsertDoesNotReallocate") { } SetTestSuite.test("COW.Slow.InsertDoesNotReallocate") { - if true { + do { var s1 = getCOWSlowSet() let identity1 = unsafeBitCast(s1, Int.self) @@ -486,7 +485,7 @@ SetTestSuite.test("COW.Slow.InsertDoesNotReallocate") { expectEqual(identity1, unsafeBitCast(s1, Int.self)) } - if true { + do { var s1 = getCOWSlowSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -515,7 +514,7 @@ SetTestSuite.test("COW.Slow.InsertDoesNotReallocate") { _fixLifetime(s2) } - if true { + do { var s1 = getCOWSlowSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -549,7 +548,7 @@ SetTestSuite.test("COW.Fast.IndexForMemberDoesNotReallocate") { var identity1 = unsafeBitCast(s, Int.self) // Find an existing key. - if true { + do { var foundIndex1 = s.indexOf(1010)! expectEqual(identity1, unsafeBitCast(s, Int.self)) @@ -561,13 +560,13 @@ SetTestSuite.test("COW.Fast.IndexForMemberDoesNotReallocate") { } // Try to find a key that is not present. - if true { + do { var foundIndex1 = s.indexOf(1111) expectEmpty(foundIndex1) expectEqual(identity1, unsafeBitCast(s, Int.self)) } - if true { + do { var s2: Set = [] MinimalHashableValue.timesEqualEqualWasCalled = 0 MinimalHashableValue.timesHashValueWasCalled = 0 @@ -585,7 +584,7 @@ SetTestSuite.test("COW.Slow.IndexForMemberDoesNotReallocate") { var identity1 = unsafeBitCast(s, Int.self) // Find an existing key. - if true { + do { var foundIndex1 = s.indexOf(TestKeyTy(1010))! expectEqual(identity1, unsafeBitCast(s, Int.self)) @@ -597,13 +596,13 @@ SetTestSuite.test("COW.Slow.IndexForMemberDoesNotReallocate") { } // Try to find a key that is not present. - if true { + do { var foundIndex1 = s.indexOf(TestKeyTy(1111)) expectEmpty(foundIndex1) expectEqual(identity1, unsafeBitCast(s, Int.self)) } - if true { + do { var s2: Set = [] MinimalHashableClass.timesEqualEqualWasCalled = 0 MinimalHashableClass.timesHashValueWasCalled = 0 @@ -617,7 +616,7 @@ SetTestSuite.test("COW.Slow.IndexForMemberDoesNotReallocate") { } SetTestSuite.test("COW.Fast.RemoveAtIndexDoesNotReallocate") { - if true { + do { var s = getCOWFastSet() var identity1 = unsafeBitCast(s, Int.self) @@ -633,7 +632,7 @@ SetTestSuite.test("COW.Fast.RemoveAtIndexDoesNotReallocate") { expectEmpty(s.indexOf(1010)) } - if true { + do { var s1 = getCOWFastSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -656,7 +655,7 @@ SetTestSuite.test("COW.Fast.RemoveAtIndexDoesNotReallocate") { } SetTestSuite.test("COW.Slow.RemoveAtIndexDoesNotReallocate") { - if true { + do { var s = getCOWSlowSet() var identity1 = unsafeBitCast(s, Int.self) @@ -672,7 +671,7 @@ SetTestSuite.test("COW.Slow.RemoveAtIndexDoesNotReallocate") { expectEmpty(s.indexOf(TestKeyTy(1010))) } - if true { + do { var s1 = getCOWSlowSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -695,7 +694,7 @@ SetTestSuite.test("COW.Slow.RemoveAtIndexDoesNotReallocate") { } SetTestSuite.test("COW.Fast.RemoveDoesNotReallocate") { - if true { + do { var s1 = getCOWFastSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -711,7 +710,7 @@ SetTestSuite.test("COW.Fast.RemoveDoesNotReallocate") { _fixLifetime(s1) } - if true { + do { var s1 = getCOWFastSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -733,7 +732,7 @@ SetTestSuite.test("COW.Fast.RemoveDoesNotReallocate") { } SetTestSuite.test("COW.Slow.RemoveDoesNotReallocate") { - if true { + do { var s1 = getCOWSlowSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -749,7 +748,7 @@ SetTestSuite.test("COW.Slow.RemoveDoesNotReallocate") { _fixLifetime(s1) } - if true { + do { var s1 = getCOWSlowSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -788,14 +787,14 @@ SetTestSuite.test("COW.Fast.UnionInPlaceSmallSetDoesNotReallocate") { } SetTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { - if true { + do { var s = getCOWFastSet() let originalCapacity = s._variantStorage.native.capacity expectEqual(3, s.count) expectTrue(s.contains(1010)) s.removeAll() - // We can not expectTrue that identity changed, since the new buffer of + // We cannot expectTrue that identity changed, since the new buffer of // smaller size can be allocated at the same address as the old one. var identity1 = unsafeBitCast(s, Int.self) expectTrue(s._variantStorage.native.capacity < originalCapacity) @@ -808,7 +807,7 @@ SetTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { expectFalse(s.contains(1010)) } - if true { + do { var s = getCOWFastSet() var identity1 = unsafeBitCast(s, Int.self) let originalCapacity = s._variantStorage.native.capacity @@ -828,7 +827,7 @@ SetTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { expectFalse(s.contains(1010)) } - if true { + do { var s1 = getCOWFastSet() var identity1 = unsafeBitCast(s1, Int.self) expectEqual(3, s1.count) @@ -849,7 +848,7 @@ SetTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { _fixLifetime(s2) } - if true { + do { var s1 = getCOWFastSet() var identity1 = unsafeBitCast(s1, Int.self) let originalCapacity = s1._variantStorage.native.capacity @@ -874,14 +873,14 @@ SetTestSuite.test("COW.Fast.RemoveAllDoesNotReallocate") { } SetTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate") { - if true { + do { var s = getCOWSlowSet() let originalCapacity = s._variantStorage.native.capacity expectEqual(3, s.count) expectTrue(s.contains(TestKeyTy(1010))) s.removeAll() - // We can not expectTrue that identity changed, since the new buffer of + // We cannot expectTrue that identity changed, since the new buffer of // smaller size can be allocated at the same address as the old one. var identity1 = unsafeBitCast(s, Int.self) expectTrue(s._variantStorage.native.capacity < originalCapacity) @@ -894,7 +893,7 @@ SetTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate") { expectFalse(s.contains(TestKeyTy(1010))) } - if true { + do { var s = getCOWSlowSet() var identity1 = unsafeBitCast(s, Int.self) let originalCapacity = s._variantStorage.native.capacity @@ -914,7 +913,7 @@ SetTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate") { expectFalse(s.contains(TestKeyTy(1010))) } - if true { + do { var s1 = getCOWSlowSet() var identity1 = unsafeBitCast(s1, Int.self) expectEqual(3, s1.count) @@ -935,7 +934,7 @@ SetTestSuite.test("COW.Slow.RemoveAllDoesNotReallocate") { _fixLifetime(s2) } - if true { + do { var s1 = getCOWSlowSet() var identity1 = unsafeBitCast(s1, Int.self) let originalCapacity = s1._variantStorage.native.capacity @@ -1320,7 +1319,7 @@ SetTestSuite.test("BridgedFromObjC.Nonverbatim.IndexForMember") { var s = getBridgedNonverbatimSet() var identity1 = unsafeBitCast(s, Int.self) - if true { + do { var member = s[s.indexOf(TestBridgedKeyTy(1010))!] expectEqual(TestBridgedKeyTy(1010), member) @@ -1336,7 +1335,7 @@ SetTestSuite.test("BridgedFromObjC.Nonverbatim.IndexForMember") { } SetTestSuite.test("BridgedFromObjC.Verbatim.Insert") { - if true { + do { var s = getBridgedVerbatimSet() var identity1 = unsafeBitCast(s, Int.self) expectTrue(isCocoaSet(s)) @@ -1357,7 +1356,7 @@ SetTestSuite.test("BridgedFromObjC.Verbatim.Insert") { } SetTestSuite.test("BridgedFromObjC.Nonverbatim.Insert") { - if true { + do { var s = getBridgedNonverbatimSet() var identity1 = unsafeBitCast(s, Int.self) expectTrue(isNativeSet(s)) @@ -1621,7 +1620,7 @@ SetTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAtIndex") { } SetTestSuite.test("BridgedFromObjC.Verbatim.Remove") { - if true { + do { var s = getBridgedVerbatimSet() var identity1 = unsafeBitCast(s, Int.self) expectTrue(isCocoaSet(s)) @@ -1644,7 +1643,7 @@ SetTestSuite.test("BridgedFromObjC.Verbatim.Remove") { expectEqual(identity2, unsafeBitCast(s, Int.self)) } - if true { + do { var s1 = getBridgedVerbatimSet() var identity1 = unsafeBitCast(s1, Int.self) @@ -1681,7 +1680,7 @@ SetTestSuite.test("BridgedFromObjC.Verbatim.Remove") { } SetTestSuite.test("BridgedFromObjC.Nonverbatim.Remove") { - if true { + do { var s = getBridgedNonverbatimSet() var identity1 = unsafeBitCast(s, Int.self) expectTrue(isNativeSet(s)) @@ -1713,7 +1712,7 @@ SetTestSuite.test("BridgedFromObjC.Nonverbatim.Remove") { expectEqual(identity2, unsafeBitCast(s, Int.self)) } - if true { + do { var s1 = getBridgedNonverbatimSet() let identity1 = unsafeBitCast(s1, Int.self) @@ -1749,7 +1748,7 @@ SetTestSuite.test("BridgedFromObjC.Nonverbatim.Remove") { } SetTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { - if true { + do { var s = getBridgedVerbatimSet([]) var identity1 = unsafeBitCast(s, Int.self) expectTrue(isCocoaSet(s)) @@ -1760,7 +1759,7 @@ SetTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { expectEqual(0, s.count) } - if true { + do { var s = getBridgedVerbatimSet() var identity1 = unsafeBitCast(s, Int.self) expectTrue(isCocoaSet(s)) @@ -1772,7 +1771,7 @@ SetTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { expectFalse(s.contains(TestBridgedKeyTy(1010))) } - if true { + do { var s1 = getBridgedVerbatimSet() var identity1 = unsafeBitCast(s1, Int.self) expectTrue(isCocoaSet(s1)) @@ -1790,7 +1789,7 @@ SetTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { expectFalse(s2.contains(TestBridgedKeyTy(1010))) } - if true { + do { var s1 = getBridgedVerbatimSet() var identity1 = unsafeBitCast(s1, Int.self) expectTrue(isCocoaSet(s1)) @@ -1810,7 +1809,7 @@ SetTestSuite.test("BridgedFromObjC.Verbatim.RemoveAll") { } SetTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { - if true { + do { var s = getBridgedNonverbatimSet([]) var identity1 = unsafeBitCast(s, Int.self) expectTrue(isNativeSet(s)) @@ -1821,7 +1820,7 @@ SetTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { expectEqual(0, s.count) } - if true { + do { var s = getBridgedNonverbatimSet() var identity1 = unsafeBitCast(s, Int.self) expectTrue(isNativeSet(s)) @@ -1833,7 +1832,7 @@ SetTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { expectFalse(s.contains(TestBridgedKeyTy(1010))) } - if true { + do { var s1 = getBridgedNonverbatimSet() var identity1 = unsafeBitCast(s1, Int.self) expectTrue(isNativeSet(s1)) @@ -1851,7 +1850,7 @@ SetTestSuite.test("BridgedFromObjC.Nonverbatim.RemoveAll") { expectFalse(s2.contains(TestBridgedKeyTy(1010))) } - if true { + do { var s1 = getBridgedNonverbatimSet() var identity1 = unsafeBitCast(s1, Int.self) expectTrue(isNativeSet(s1)) @@ -2397,7 +2396,7 @@ SetTestSuite.test("SetUpcastBridgedEntryPoint") { s.insert(TestBridgedKeyTy(i)) } - if true { + do { var s: Set = _setBridgeToObjectiveC(s) expectTrue(s.contains(TestBridgedKeyTy(1010))) @@ -2405,7 +2404,7 @@ SetTestSuite.test("SetUpcastBridgedEntryPoint") { expectTrue(s.contains(TestBridgedKeyTy(3030))) } - if true { + do { var s: Set = _setBridgeToObjectiveC(s) expectEqual(3, s.count) @@ -2421,7 +2420,7 @@ SetTestSuite.test("SetUpcastBridged") { s.insert(TestBridgedKeyTy(i)) } - if true { + do { var s: Set = s expectEqual(3, s.count) @@ -2430,7 +2429,7 @@ SetTestSuite.test("SetUpcastBridged") { expectTrue(s.contains(TestBridgedKeyTy(3030))) } - if true { + do { var s: Set = s expectEqual(3, s.count) @@ -2530,7 +2529,7 @@ SetTestSuite.test("SetBridgeFromObjectiveCEntryPoint") { // Successful downcast. let sCV: Set = _setBridgeFromObjectiveC(s) - if true { + do { expectEqual(3, sCV.count) expectTrue(sCV.contains(TestBridgedKeyTy(1010))) expectTrue(sCV.contains(TestBridgedKeyTy(2020))) @@ -2546,7 +2545,7 @@ SetTestSuite.test("SetBridgeFromObjectiveC") { // Successful downcast. let sCV = s as! Set - if true { + do { expectEqual(3, sCV.count) expectTrue(sCV.contains(TestObjCKeyTy(1010))) expectTrue(sCV.contains(TestObjCKeyTy(2020))) @@ -2555,7 +2554,7 @@ SetTestSuite.test("SetBridgeFromObjectiveC") { // Successful downcast. let sVC = s as! Set - if true { + do { expectEqual(3, sVC.count) expectTrue(sVC.contains(TestBridgedKeyTy(1010))) expectTrue(sVC.contains(TestBridgedKeyTy(2020))) @@ -3451,26 +3450,26 @@ SetTestSuite.test("isEmpty") { } SetTestSuite.test("isEmpty/ImplementationIsCustomized") { - if true { + do { var d = getMockSetWithCustomCount(count: 0) MockSetWithCustomCount.timesCountWasCalled = 0 expectTrue(d.isEmpty) expectEqual(1, MockSetWithCustomCount.timesCountWasCalled) } - if true { + do { var d = getMockSetWithCustomCount(count: 0) MockSetWithCustomCount.timesCountWasCalled = 0 expectTrue(callGenericIsEmpty(d)) expectEqual(1, MockSetWithCustomCount.timesCountWasCalled) } - if true { + do { var d = getMockSetWithCustomCount(count: 4) MockSetWithCustomCount.timesCountWasCalled = 0 expectFalse(d.isEmpty) expectEqual(1, MockSetWithCustomCount.timesCountWasCalled) } - if true { + do { var d = getMockSetWithCustomCount(count: 4) MockSetWithCustomCount.timesCountWasCalled = 0 expectFalse(callGenericIsEmpty(d)) @@ -3509,14 +3508,14 @@ SetTestSuite.test("indexOf") { SetTestSuite.test("popFirst") { // Empty - if true { + do { var s = Set() let popped = s.popFirst() expectEmpty(popped) expectTrue(s.isEmpty) } - if true { + do { var popped = [Int]() var s = Set([1010, 2020, 3030]) let expected = Array(s) @@ -3596,7 +3595,7 @@ SetTestSuite.test("absorption") { SetTestSuite.test("misc") { // Set with other types - if true { + do { var s = Set([1.1, 2.2, 3.3]) s.insert(4.4) expectTrue(s.contains(1.1)) @@ -3604,7 +3603,7 @@ SetTestSuite.test("misc") { expectTrue(s.contains(3.3)) } - if true { + do { var s = Set(["Hello", "world"]) expectTrue(s.contains("Hello")) expectTrue(s.contains("world")) diff --git a/validation-test/stdlib/Slice.swift.gyb b/validation-test/stdlib/Slice.swift.gyb index 818e17a9aa164..80ca96463f75c 100644 --- a/validation-test/stdlib/Slice.swift.gyb +++ b/validation-test/stdlib/Slice.swift.gyb @@ -8,6 +8,13 @@ import StdlibUnittest import SwiftPrivate +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") //===----------------------------------------------------------------------===// @@ -16,7 +23,7 @@ var SliceTests = TestSuite("CollectionType") SliceTests.test("Slice/AssociatedTypes") { %for traversal in [ 'Forward', 'Bidirectional', 'RandomAccess' ]: - if true { + do { typealias Base = Minimal${traversal}Collection> typealias ${traversal}Slice = Slice expectSliceType(${traversal}Slice.self) @@ -129,7 +136,7 @@ SliceTests.test("Slice.subscript(_: Range)") { SliceTests.test("MutableSlice/AssociatedTypes") { %for traversal in [ 'Forward', 'Bidirectional', 'RandomAccess' ]: - if true { + do { typealias Base = Minimal${traversal}MutableCollection> typealias ${traversal}MutableSlice = MutableSlice diff --git a/validation-test/stdlib/Slice/Inputs/GenerateSliceTests.py b/validation-test/stdlib/Slice/Inputs/GenerateSliceTests.py index 4f05f56a9a54e..5181927649ec4 100644 --- a/validation-test/stdlib/Slice/Inputs/GenerateSliceTests.py +++ b/validation-test/stdlib/Slice/Inputs/GenerateSliceTests.py @@ -19,8 +19,8 @@ ]: Base = '%s%s%sCollection' % (base_kind, traversal, 'Mutable' if mutable else '') testFilename = WrapperType + '_Of_' + Base + '_' + name + '.swift' - testFile = open(testFilename + '.gyb', 'w') - testFile.write(""" + with open(testFilename + '.gyb', 'w') as testFile: + testFile.write(""" //// Automatically Generated From validation-test/stdlib/Inputs/GenerateSliceTests.py //////// Do Not Edit Directly! // -*- swift -*- @@ -35,6 +35,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb @@ -61,9 +69,3 @@ prefix=prefix, suffix=suffix )) - testFile.close() - - - - - diff --git a/validation-test/stdlib/Slice/Inputs/slice.gyb b/validation-test/stdlib/Slice/Inputs/slice.gyb index d561a09a0adfb..aeef61277c980 100644 --- a/validation-test/stdlib/Slice/Inputs/slice.gyb +++ b/validation-test/stdlib/Slice/Inputs/slice.gyb @@ -3,7 +3,7 @@ % Base = "%s%s%sCollection" % (base_kind, traversal, 'Mutable' if mutable else '') -if true { +do { let prefix: [Int] = ${prefix} let suffix: [Int] = ${suffix} diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_FullWidth.swift.gyb index cd8713baf56de..179194a9bdb40 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithPrefix.swift.gyb index 8462ab86f8dd7..bb73146f9dd6b 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb index 48d747da08a7c..cb2db311327bf 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithSuffix.swift.gyb index 679d8982e8448..d72ec302153d7 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedBidirectionalMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_FullWidth.swift.gyb index 6a88d6906856d..a4525fa1164e1 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithPrefix.swift.gyb index 56f3cedf410c3..c4a3648e43cfd 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithPrefixAndSuffix.swift.gyb index bf9c55825112e..9b29b8c412245 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithSuffix.swift.gyb index ed38d1bc33f32..8c6759794fe86 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedForwardMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_FullWidth.swift.gyb index 371ee9bf2bbbc..83047063d8472 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithPrefix.swift.gyb index 363ecdabfeede..9bda6dc2dd672 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb index d059260df645f..1cc8ad9873ab4 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithSuffix.swift.gyb index 4208ad5bbdef8..c83cb983805ab 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_DefaultedRandomAccessMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_FullWidth.swift.gyb index b332b73d9a6fd..3a2ea48f5dbd5 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithPrefix.swift.gyb index b4dc32f9e23ae..c207329f3d9e7 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb index 3ab14f24ed427..86485b574d138 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithSuffix.swift.gyb index ad16eaa30c4a1..31c80a0e62a99 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalBidirectionalMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_FullWidth.swift.gyb index 85c77e49b60de..45ffb0b485fe3 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithPrefix.swift.gyb index 1ecbc1c6f9ba9..14d346f56f8bb 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithPrefixAndSuffix.swift.gyb index 71e9cd9e0eca9..0bd9abf3f58ce 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithSuffix.swift.gyb index 978bff2702926..6becb8095886c 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalForwardMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_FullWidth.swift.gyb index b08af1d2128c4..11e501c00f3bb 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithPrefix.swift.gyb index 50eaa92a3341a..c75366503868a 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb index 454929f739418..bf3e6aefe099f 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithSuffix.swift.gyb index 9c1e31bb5303a..e676339bcf640 100644 --- a/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/MutableSlice_Of_MinimalRandomAccessMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_FullWidth.swift.gyb index 4e9302ca562a1..9f67db5d6e898 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithPrefix.swift.gyb index b4ac103e452fc..c6eb25eb071b3 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithPrefixAndSuffix.swift.gyb index 06b0c8d08fdd7..00c15618bd759 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithSuffix.swift.gyb index 725a8ec46b714..7c029a10591a2 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_FullWidth.swift.gyb index 842dca8a50ac1..0e850ec3a3c3c 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithPrefix.swift.gyb index 89bd604b4525b..ddae62b5d1f3d 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb index ea5ed34adb894..22effdc9550ac 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithSuffix.swift.gyb index f5607598058e4..f31b54b49b47f 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedBidirectionalMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_FullWidth.swift.gyb index 390ce7c41a802..6c62133c8b037 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithPrefix.swift.gyb index a62f9822b147c..7e9ba5b4a9ae6 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithPrefixAndSuffix.swift.gyb index 1a1662c8bfcf6..f70e9e9d61861 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithSuffix.swift.gyb index e916c62f979a9..409b813cbd847 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_FullWidth.swift.gyb index 1112619918b9a..159e2f86c68da 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithPrefix.swift.gyb index 816d5b5f7007d..9c02bc5cc41d1 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithPrefixAndSuffix.swift.gyb index bd5914a953608..c4cece9a4aceb 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithSuffix.swift.gyb index 4e598c407b7ad..f7aa1cb621a9d 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedForwardMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_FullWidth.swift.gyb index 7f9cd6fc5b283..e905feb3a41f3 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithPrefix.swift.gyb index 40e1a590ee24a..0ffe537d30f74 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithPrefixAndSuffix.swift.gyb index 3aa5907289b24..2dbd69e674467 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithSuffix.swift.gyb index 624fdc2f31b05..69a5ae838f657 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_FullWidth.swift.gyb index a5cfa45b8b21a..50eba559e781a 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithPrefix.swift.gyb index 9854c3035d53f..a27ec8d4f7984 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb index a92f6d5b76fa6..e38186061335b 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithSuffix.swift.gyb index 5f32058a946b2..4f96d38aa229c 100644 --- a/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_DefaultedRandomAccessMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_FullWidth.swift.gyb index 86fbf7584f903..3f04b5da96e65 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithPrefix.swift.gyb index 1f97987f161e4..db38ce5bff42d 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithPrefixAndSuffix.swift.gyb index c46062c42310d..799b55550d3b4 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithSuffix.swift.gyb index 2f775557106a4..3099e01ee9cf8 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_FullWidth.swift.gyb index e937e9e250f52..6b14baf4e63e4 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithPrefix.swift.gyb index fe5dbdd33230a..e4101aec9a56f 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb index b46a23cbd32be..9118e011bf7dc 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithSuffix.swift.gyb index d6f6eedfa5bbf..5ef75cc58a56d 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalBidirectionalMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_FullWidth.swift.gyb index 3e59e781f836c..a6e82e41fdc88 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithPrefix.swift.gyb index 851d6dcb3d0c7..90f7ccd430f98 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithPrefixAndSuffix.swift.gyb index 937ec0e177a4a..773d530182b1f 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithSuffix.swift.gyb index 4348297673d45..35635af902d49 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_FullWidth.swift.gyb index e9528874315e8..b403a8eb6eea2 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithPrefix.swift.gyb index f1e7134f2cd24..ab18373ad99a6 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithPrefixAndSuffix.swift.gyb index 9d1de1536c491..cc77762bba345 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithSuffix.swift.gyb index efe98dad94027..70388852d73dd 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalForwardMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_FullWidth.swift.gyb index f1e4610ee2233..759fcca756ceb 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithPrefix.swift.gyb index 127efe48de839..4582499bb6320 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithPrefixAndSuffix.swift.gyb index c60592c1055a5..430167d1f4809 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithSuffix.swift.gyb index 7039c46e141ce..e5daf01cfbc2c 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_FullWidth.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_FullWidth.swift.gyb index 79215a84eb4e3..71973a764a862 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_FullWidth.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_FullWidth.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithPrefix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithPrefix.swift.gyb index 89ad6035b0303..8a9335c1781c1 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithPrefix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithPrefix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb index 1f2d85f0ad6a7..ce232a99db6d5 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithPrefixAndSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithSuffix.swift.gyb b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithSuffix.swift.gyb index 9adffcc6c1bfc..fb073f0b9d2e2 100644 --- a/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithSuffix.swift.gyb +++ b/validation-test/stdlib/Slice/Slice_Of_MinimalRandomAccessMutableCollection_WithSuffix.swift.gyb @@ -13,6 +13,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var SliceTests = TestSuite("CollectionType") % import gyb diff --git a/validation-test/stdlib/StdlibUnittest.swift b/validation-test/stdlib/StdlibUnittest.swift index 7422a8784c475..6a64199119e45 100644 --- a/validation-test/stdlib/StdlibUnittest.swift +++ b/validation-test/stdlib/StdlibUnittest.swift @@ -4,6 +4,13 @@ import SwiftPrivate import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +#if _runtime(_ObjC) +import ObjectiveC +#endif + _setOverrideOSVersion(.OSX(major: 10, minor: 9, bugFix: 3)) _setTestSuiteFailedCallback() { print("abort()") } diff --git a/validation-test/stdlib/StdlibUnittestCommandLine.swift b/validation-test/stdlib/StdlibUnittestCommandLine.swift new file mode 100644 index 0000000000000..22e163dbd6c10 --- /dev/null +++ b/validation-test/stdlib/StdlibUnittestCommandLine.swift @@ -0,0 +1,28 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: %target-build-swift %s -o %t/main.out +// RUN: %target-run %t/main.out | FileCheck -check-prefix=CHECK-EMPTY %s +// RUN: %target-run %t/main.out --abc | FileCheck -check-prefix=CHECK-1 %s +// RUN: %target-run %t/main.out --abc def | FileCheck -check-prefix=CHECK-2 %s +// RUN: %target-run %t/main.out a --bcd efghijk | FileCheck -check-prefix=CHECK-3 %s +// REQUIRES: executable_test + +import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +#if _runtime(_ObjC) +import ObjectiveC +#endif + +var CommandLineArguments = TestSuite("CommandLineArguments") +CommandLineArguments.test("printCommandLineArguments") { + debugPrint(Process.arguments) +} +// CHECK-EMPTY: {{^}}out>>> ["{{[^"]+}}", "--stdlib-unittest-run-child"]{{$}} +// CHECK-1: {{^}}out>>> ["{{[^"]+}}", "--stdlib-unittest-run-child", "--abc"]{{$}} +// CHECK-2: {{^}}out>>> ["{{[^"]+}}", "--stdlib-unittest-run-child", "--abc", "def"]{{$}} +// CHECK-3: {{^}}out>>> ["{{[^"]+}}", "--stdlib-unittest-run-child", "a", "--bcd", "efghijk"]{{$}} + +runAllTests() + diff --git a/validation-test/stdlib/StdlibUnittestCrashingTests.swift b/validation-test/stdlib/StdlibUnittestCrashingTests.swift index e1f6ae98c10df..61c41428bbcbc 100644 --- a/validation-test/stdlib/StdlibUnittestCrashingTests.swift +++ b/validation-test/stdlib/StdlibUnittestCrashingTests.swift @@ -3,6 +3,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + _setOverrideOSVersion(.OSX(major: 10, minor: 9, bugFix: 3)) _setTestSuiteFailedCallback() { print("abort()") } diff --git a/validation-test/stdlib/StdlibUnittestFilter.swift b/validation-test/stdlib/StdlibUnittestFilter.swift index f0f37ba9186a1..edb68f5a0b1b8 100644 --- a/validation-test/stdlib/StdlibUnittestFilter.swift +++ b/validation-test/stdlib/StdlibUnittestFilter.swift @@ -19,6 +19,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + var FilterTestSuite = TestSuite("Filter") FilterTestSuite.test("abc") { diff --git a/validation-test/stdlib/StdlibUnittestFoundationExtras.swift b/validation-test/stdlib/StdlibUnittestFoundationExtras.swift index 8cc7642a90a34..3bbc04b29827c 100644 --- a/validation-test/stdlib/StdlibUnittestFoundationExtras.swift +++ b/validation-test/stdlib/StdlibUnittestFoundationExtras.swift @@ -4,6 +4,15 @@ // REQUIRES: objc_interop import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import Foundation import StdlibUnittestFoundationExtras @@ -12,7 +21,7 @@ var FoundationExtrasTests = TestSuite("FoundationExtras") FoundationExtrasTests.test("withOverriddenNSLocaleCurrentLocale(NSLocale)") { // Check two locales to make sure the behavior is correct even if one of // these locales happens to be the same as the actual current locale. - if true { + do { let result = withOverriddenNSLocaleCurrentLocale( NSLocale(localeIdentifier: "en_US")) { () -> Int in @@ -21,7 +30,7 @@ FoundationExtrasTests.test("withOverriddenNSLocaleCurrentLocale(NSLocale)") { } expectEqual(42, result) } - if true { + do { let result = withOverriddenNSLocaleCurrentLocale( NSLocale(localeIdentifier: "uk")) { () -> Int in @@ -51,7 +60,7 @@ FoundationExtrasTests.test("withOverriddenNSLocaleCurrentLocale(NSLocale)/nested FoundationExtrasTests.test("withOverriddenNSLocaleCurrentLocale(String)") { // Check two locales to make sure the behavior is correct even if one of // these locales happens to be the same as the actual current locale. - if true { + do { let result = withOverriddenNSLocaleCurrentLocale("en_US") { () -> Int in expectEqual("en_US", NSLocale.currentLocale().localeIdentifier) @@ -59,7 +68,7 @@ FoundationExtrasTests.test("withOverriddenNSLocaleCurrentLocale(String)") { } expectEqual(42, result) } - if true { + do { let result = withOverriddenNSLocaleCurrentLocale("uk") { () -> Int in expectEqual("uk", NSLocale.currentLocale().localeIdentifier) diff --git a/validation-test/stdlib/StdlibUnittestIOS.swift b/validation-test/stdlib/StdlibUnittestIOS.swift index 4cf9d9b4b031c..9abeb3319507f 100644 --- a/validation-test/stdlib/StdlibUnittestIOS.swift +++ b/validation-test/stdlib/StdlibUnittestIOS.swift @@ -4,6 +4,14 @@ import Swift import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + _setOverrideOSVersion(.iOS(major: 10, minor: 9, bugFix: 3)) _setTestSuiteFailedCallback() { print("abort()") } diff --git a/validation-test/stdlib/StdlibUnittestIOSSimulator.swift b/validation-test/stdlib/StdlibUnittestIOSSimulator.swift index 906524f757e60..39eb326c2f58c 100644 --- a/validation-test/stdlib/StdlibUnittestIOSSimulator.swift +++ b/validation-test/stdlib/StdlibUnittestIOSSimulator.swift @@ -4,6 +4,14 @@ import Swift import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + _setOverrideOSVersion(.iOSSimulator) _setTestSuiteFailedCallback() { print("abort()") } diff --git a/validation-test/stdlib/StdlibUnittestLinux.swift b/validation-test/stdlib/StdlibUnittestLinux.swift index 27fe452fe92f2..d3911633fe579 100644 --- a/validation-test/stdlib/StdlibUnittestLinux.swift +++ b/validation-test/stdlib/StdlibUnittestLinux.swift @@ -4,6 +4,14 @@ import Swift import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + _setOverrideOSVersion(.Linux) _setTestSuiteFailedCallback() { print("abort()") } diff --git a/validation-test/stdlib/StdlibUnittestRaceTest.swift b/validation-test/stdlib/StdlibUnittestRaceTest.swift index e79d7e6cf6129..dd42044a2a26e 100644 --- a/validation-test/stdlib/StdlibUnittestRaceTest.swift +++ b/validation-test/stdlib/StdlibUnittestRaceTest.swift @@ -3,6 +3,15 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +import SwiftPrivatePthreadExtras +#if _runtime(_ObjC) +import ObjectiveC +#endif + _setTestSuiteFailedCallback() { print("abort()") } struct RaceTest1 : RaceTestWithPerTrialDataType { diff --git a/validation-test/stdlib/StdlibUnittestRunAllTestsCalledTwice.swift b/validation-test/stdlib/StdlibUnittestRunAllTestsCalledTwice.swift index 217ba74c752dc..a58649b453db0 100644 --- a/validation-test/stdlib/StdlibUnittestRunAllTestsCalledTwice.swift +++ b/validation-test/stdlib/StdlibUnittestRunAllTestsCalledTwice.swift @@ -3,6 +3,14 @@ import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + _setTestSuiteFailedCallback() { print("abort()") } // diff --git a/validation-test/stdlib/StdlibUnittestSequencesCollections.swift.gyb b/validation-test/stdlib/StdlibUnittestSequencesCollections.swift.gyb index 516690e90f45d..a5d4c55299762 100644 --- a/validation-test/stdlib/StdlibUnittestSequencesCollections.swift.gyb +++ b/validation-test/stdlib/StdlibUnittestSequencesCollections.swift.gyb @@ -8,6 +8,14 @@ import SwiftPrivate import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +#if _runtime(_ObjC) +import ObjectiveC +import Foundation +#endif + %for traversal in [ 'Forward', 'Bidirectional', 'RandomAccess' ]: // This comment is a workaround for gyb miscompiles nested loops % for mutable in [ False, True ]: @@ -284,7 +292,7 @@ ${Self}TestSuite.test("removeAll()/IndexInvalidation") { var SequenceTypeAlgorithms = TestSuite("SequenceTypeAlgorithms") SequenceTypeAlgorithms.test("forAllPermutations") { - if true { + do { var permutations: [[Int]] = [] forAllPermutations(0) { permutations.append($0) @@ -292,7 +300,7 @@ SequenceTypeAlgorithms.test("forAllPermutations") { expectEqualSequence([] as [[Int]], permutations) { $0 == $1 } } - if true { + do { var permutations: [[Int]] = [] forAllPermutations(1) { permutations.append($0) @@ -300,7 +308,7 @@ SequenceTypeAlgorithms.test("forAllPermutations") { expectEqualSequence([[ 0 ]] as [[Int]], permutations) { $0 == $1 } } - if true { + do { var permutations: [[Int]] = [] forAllPermutations(2) { permutations.append($0) @@ -309,7 +317,7 @@ SequenceTypeAlgorithms.test("forAllPermutations") { [[ 0, 1 ], [ 1, 0 ]] as [[Int]], permutations) { $0 == $1 } } - if true { + do { var permutations: [[Int]] = [] forAllPermutations(3) { permutations.append($0) @@ -326,7 +334,7 @@ SequenceTypeAlgorithms.test("forAllPermutations") { permutations) { $0 == $1 } } - if true { + do { var permutations: [[Int]] = [] forAllPermutations([ 10, 20, 30 ]) { permutations.append($0) diff --git a/validation-test/stdlib/StdlibUnittestStdin.swift b/validation-test/stdlib/StdlibUnittestStdin.swift index 3f11a23066e20..ff4efdee2f56b 100644 --- a/validation-test/stdlib/StdlibUnittestStdin.swift +++ b/validation-test/stdlib/StdlibUnittestStdin.swift @@ -2,6 +2,15 @@ // REQUIRES: executable_test import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + #if os(OSX) || os(iOS) || os(tvOS) || os(watchOS) import Darwin #elseif os(Linux) diff --git a/validation-test/stdlib/String.swift b/validation-test/stdlib/String.swift index 5dfec56f32a59..11af737155261 100644 --- a/validation-test/stdlib/String.swift +++ b/validation-test/stdlib/String.swift @@ -5,6 +5,15 @@ // XFAIL: linux import StdlibUnittest + +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + import Foundation extension String { @@ -28,7 +37,7 @@ StringTests.test("sizeof") { func checkUnicodeScalarViewIteration( expectedScalars: [UInt32], _ str: String ) { - if true { + do { var us = str.unicodeScalars var i = us.startIndex let end = us.endIndex @@ -40,7 +49,7 @@ func checkUnicodeScalarViewIteration( } expectEqual(expectedScalars, decoded) } - if true { + do { var us = str.unicodeScalars let start = us.startIndex var i = us.endIndex @@ -94,14 +103,14 @@ StringTests.test("ForeignIndexes/Valid") { // // Design, document, implement invalidation model // for foreign String indexes - if true { + do { let donor = "abcdef" let acceptor = "uvwxyz" expectEqual("u", acceptor[donor.startIndex]) expectEqual("wxy", acceptor[donor.startIndex.advancedBy(2).. = nil var sharedString: String = "" -var slaveString: String = "" +var secondaryString: String = "" func barrier() { var ret = _stdlib_pthread_barrier_wait(barrierVar) @@ -41,7 +48,7 @@ func barrier() { func sliceConcurrentAppendThread(tid: ThreadID) { for i in 0..<100 { barrier() - if tid == .Master { + if tid == .Primary { // Get a fresh buffer. sharedString = "" sharedString.appendContentsOf("abc") @@ -57,7 +64,7 @@ func sliceConcurrentAppendThread(tid: ThreadID) { barrier() // Append to the private string. - if tid == .Master { + if tid == .Primary { privateString.appendContentsOf("def") } else { privateString.appendContentsOf("ghi") @@ -66,7 +73,7 @@ func sliceConcurrentAppendThread(tid: ThreadID) { barrier() // Verify that contents look good. - if tid == .Master { + if tid == .Primary { expectEqual("abcdef", privateString) } else { expectEqual("abcghi", privateString) @@ -74,14 +81,14 @@ func sliceConcurrentAppendThread(tid: ThreadID) { expectEqual("abc", sharedString) // Verify that only one thread took ownership of the buffer. - if tid == .Slave { - slaveString = privateString + if tid == .Secondary { + secondaryString = privateString } barrier() - if tid == .Master { + if tid == .Primary { expectTrue( (privateString.bufferID == sharedString.bufferID) != - (slaveString.bufferID == sharedString.bufferID)) + (secondaryString.bufferID == sharedString.bufferID)) } } } @@ -93,9 +100,9 @@ StringTestSuite.test("SliceConcurrentAppend") { expectEqual(0, ret) let (createRet1, tid1) = _stdlib_pthread_create_block( - nil, sliceConcurrentAppendThread, .Master) + nil, sliceConcurrentAppendThread, .Primary) let (createRet2, tid2) = _stdlib_pthread_create_block( - nil, sliceConcurrentAppendThread, .Slave) + nil, sliceConcurrentAppendThread, .Secondary) expectEqual(0, createRet1) expectEqual(0, createRet2) diff --git a/validation-test/stdlib/StringViews.swift b/validation-test/stdlib/StringViews.swift index 1a5f1d3ad908f..a0bc12bd1dfb5 100644 --- a/validation-test/stdlib/StringViews.swift +++ b/validation-test/stdlib/StringViews.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -15,6 +15,14 @@ import Swift import StdlibUnittest +// Also import modules which are used by StdlibUnittest internally. This +// workaround is needed to link all required libraries in case we compile +// StdlibUnittest with -sil-serialize-all. +import SwiftPrivate +#if _runtime(_ObjC) +import ObjectiveC +#endif + // CHECK: testing... print("testing...") @@ -275,7 +283,7 @@ tests.test("index-mapping/utf16-to-unicode-scalar") { summer.utf16.endIndex.samePositionIn(summer.unicodeScalars)!) } -//===--- To UTF16 ----------------------------------------------------------===// +//===--- To UTF16 ---------------------------------------------------------===// tests.test("index-mapping/character-to-utf16") { expectEqualSequence( [ @@ -490,7 +498,7 @@ tests.test("index-mapping/utf16-to-unicode-scalar") { summer.utf16.endIndex.samePositionIn(summer.unicodeScalars)!) } -//===--- To Character -------------------------------------------------===// +//===--- To Character -----------------------------------------------------===// tests.test("index-mapping/unicode-scalar-to-character") { let winterUnicodeScalarCharacters: [Character?] = [ "🏂", "☃", "❅", "❆", "❄︎", nil, "⛄️", nil, "❄️", nil, @@ -536,7 +544,7 @@ tests.test("index-mapping/utf8-to-character") { expectEqualSequence( winterUtf8Characters, winter.utf8.indices.map { - (i:String.UTF8Index)->Character? in i.samePositionIn(winter).map { + (i:String.UTF8Index) -> Character? in i.samePositionIn(winter).map { winter[$0] } }, sameValue: ==) diff --git a/validation-test/stdlib/Unicode.swift b/validation-test/stdlib/Unicode.swift index cba14f086e727..1d24be5eb4e82 100644 --- a/validation-test/stdlib/Unicode.swift +++ b/validation-test/stdlib/Unicode.swift @@ -17,37 +17,37 @@ UTF16APIs.test("width") { } UTF16APIs.test("leadSurrogate,trailSurrogate") { - if true { + do { let us: UnicodeScalar = "𝄞" expectEqual(0xD834, UTF16.leadSurrogate(us)) expectEqual(0xDD1E, UTF16.trailSurrogate(us)) } - if true { + do { let us: UnicodeScalar = "\u{10000}" expectEqual(0xD800, UTF16.leadSurrogate(us)) expectEqual(0xDC00, UTF16.trailSurrogate(us)) } - if true { + do { let us: UnicodeScalar = "\u{20000}" expectEqual(0xD840, UTF16.leadSurrogate(us)) expectEqual(0xDC00, UTF16.trailSurrogate(us)) } - if true { + do { let us: UnicodeScalar = "\u{80000}" expectEqual(0xD9C0, UTF16.leadSurrogate(us)) expectEqual(0xDC00, UTF16.trailSurrogate(us)) } - if true { + do { let us: UnicodeScalar = "\u{F0000}" expectEqual(0xDB80, UTF16.leadSurrogate(us)) expectEqual(0xDC00, UTF16.trailSurrogate(us)) } - if true { + do { let us: UnicodeScalar = "\u{100000}" expectEqual(0xDBC0, UTF16.leadSurrogate(us)) expectEqual(0xDC00, UTF16.trailSurrogate(us)) } - if true { + do { let us: UnicodeScalar = "\u{10FFFF}" expectEqual(0xDBFF, UTF16.leadSurrogate(us)) expectEqual(0xDFFF, UTF16.trailSurrogate(us)) @@ -101,7 +101,7 @@ class EOFCountingGenerator : GeneratorType { func next() -> T? { if index == array.count { - ++numTimesReturnedEOF + numTimesReturnedEOF += 1 return .None } return array[index++] @@ -112,7 +112,7 @@ func checkDecodeUTF( codec: Codec.Type, _ expectedHead: [UInt32], _ expectedRepairedTail: [UInt32], _ utfStr: [Codec.CodeUnit] ) -> AssertionResult { - if true { + do { var decoded = [UInt32]() let output: (UInt32) -> Void = { decoded.append($0) } let g = EOFCountingGenerator(utfStr) @@ -126,7 +126,7 @@ func checkDecodeUTF( } } - if true { + do { var expected = expectedHead expected += expectedRepairedTail @@ -749,19 +749,19 @@ let UTF16Tests = [ var UnicodeScalarTests = TestSuite("UnicodeScalarTests") UnicodeScalarTests.test("literal") { - if true { + do { // U+0041 LATIN CAPITAL LETTER A let us: UnicodeScalar = "A" expectEqual(0x0041, us.value) } - if true { + do { // U+3042 HIRAGANA LETTER A let us: UnicodeScalar = "あ" expectEqual(0x3042, us.value) } - if true { + do { // U+4F8B CJK UNIFIED IDEOGRAPH-4F8B let us: UnicodeScalar = "例" expectEqual(0x4F8B, us.value) @@ -1895,7 +1895,7 @@ UTF8Decoder.test("Noncharacters") { var UTF16Decoder = TestSuite("UTF16Decoder") UTF16Decoder.test("measure") { - if true { + do { var u8: [UTF8.CodeUnit] = [ 0, 1, 2, 3, 4, 5 ] let (count, isASCII) = UTF16.measure( UTF8.self, input: u8.generate(), repairIllFormedSequences: false)! @@ -1903,7 +1903,7 @@ UTF16Decoder.test("measure") { expectTrue(isASCII) } - if true { + do { // "€" == U+20AC. var u8: [UTF8.CodeUnit] = [ 0xF0, 0xA4, 0xAD, 0xA2 ] let (count, isASCII) = UTF16.measure( @@ -1912,7 +1912,7 @@ UTF16Decoder.test("measure") { expectFalse(isASCII) } - if true { + do { let u16: [UTF16.CodeUnit] = [ 6, 7, 8, 9, 10, 11 ] let (count, isASCII) = UTF16.measure( UTF16.self, input: u16.generate(), repairIllFormedSequences: false)! @@ -2263,7 +2263,7 @@ StringCookedViews.test("UTF8ForNonContiguousUTF16") { StringCookedViews.test("UTF8ForNonContiguousUTF16Extra") { // These tests don't add much additional value as long as tests above // actually test the code path we care about. - if true { + do { var bytes: [UInt8] = [ 97, 98, 99 ] var cfstring: CFString = CFStringCreateWithBytesNoCopy( kCFAllocatorDefault, bytes, bytes.count, @@ -2287,7 +2287,7 @@ StringCookedViews.test("UTF8ForNonContiguousUTF16Extra") { _fixLifetime(bytes) } - if true { + do { var bytes: [UInt8] = [ 97, 98, 99 ] var cfstring: CFString = CFStringCreateWithBytes(kCFAllocatorDefault, bytes, bytes.count, CFStringBuiltInEncodings.MacRoman.rawValue, false) diff --git a/validation-test/stdlib/UnicodeTrie.swift.gyb b/validation-test/stdlib/UnicodeTrie.swift.gyb index 0732935de4d6e..a95d06a370df7 100644 --- a/validation-test/stdlib/UnicodeTrie.swift.gyb +++ b/validation-test/stdlib/UnicodeTrie.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information @@ -159,7 +159,7 @@ UnicodeTrie.test("GraphemeClusterSegmentation/UnicodeSpec") { // specification. % for code_points,expected_boundaries in grapheme_cluster_break_tests: - if true { + do { let scalars: [UInt32] = [ ${", ".join([ str(cp) for cp in code_points ])} ] let expectedBoundaries: [Int] = diff --git a/validation-test/stdlib/UnicodeTrieGenerator.gyb b/validation-test/stdlib/UnicodeTrieGenerator.gyb index b466c8cbfc3e6..dbf359b3c7b91 100644 --- a/validation-test/stdlib/UnicodeTrieGenerator.gyb +++ b/validation-test/stdlib/UnicodeTrieGenerator.gyb @@ -2,6 +2,8 @@ # RUN: rm -rf %t && mkdir -p %t && %S/../../utils/gyb %s | FileCheck %s +from __future__ import print_function + from GYBUnicodeDataUtils import * def test_trie_generation(property_table, configure_generator=None): @@ -14,7 +16,7 @@ def test_trie_generation(property_table, configure_generator=None): trie_generator.freeze() trie_generator.verify(property_table) trie_generator.serialize(property_table) - print ( + print(( trie_generator.BMP_first_level_index_bits, trie_generator.BMP_data_offset_bits, trie_generator.supp_first_level_index_bits, @@ -33,7 +35,7 @@ def test_trie_generation(property_table, configure_generator=None): trie_generator.supp_lookup1_bytes_offset - trie_generator.BMP_data_bytes_offset, trie_generator.supp_lookup2_bytes_offset - trie_generator.supp_lookup1_bytes_offset, trie_generator.supp_data_bytes_offset - trie_generator.supp_lookup2_bytes_offset, - len(trie_generator.trie_bytes) - trie_generator.supp_data_bytes_offset) + len(trie_generator.trie_bytes) - trie_generator.supp_data_bytes_offset)) class PerfectlyCompressableProperty(UnicodeProperty): def __init__(self): @@ -53,7 +55,7 @@ class PerfectlyCompressableProperty(UnicodeProperty): def get_numeric_value(self, cp): return self.to_numeric_value(self.get_value(cp)) -print 'PerfectlyCompressableProperty' +print('PerfectlyCompressableProperty') test_trie_generation(PerfectlyCompressableProperty()) # CHECK-LABEL: PerfectlyCompressableProperty # CHECK: (8, 8, 5, 8, 8, 1, 1, 1, 1, 1, 1041, 256, 256, 17, 256, 256) @@ -77,7 +79,7 @@ class UncompressableProperty(UnicodeProperty): def get_value(self, cp): # Split Unicode codespace into 128-entry "pages". Start each page with # a unique sequence of property values (page number) so that the result - # can not be compressed. + # cannot be compressed. page_number = cp >> 7 if cp % 0x80 == 1: return page_number & 0xff @@ -93,7 +95,7 @@ class UncompressableProperty(UnicodeProperty): def get_numeric_value(self, cp): return self.to_numeric_value(self.get_value(cp)) -print 'UncompressableProperty, default trie parameters' +print('UncompressableProperty, default trie parameters') test_trie_generation(UncompressableProperty()) # CHECK-LABEL: UncompressableProperty, default trie parameters # CHECK: (8, 8, 5, 8, 8, 2, 1, 1, 2, 1, 1123601, 512, 65536, 17, 8704, 1048832) @@ -112,7 +114,7 @@ def configure_generator_for_16_bit_indexes(trie_generator): trie_generator.supp_first_level_index_bits = 10 trie_generator.supp_second_level_index_bits = 2 -print 'UncompressableProperty, 16-bit indexes' +print('UncompressableProperty, 16-bit indexes') test_trie_generation(UncompressableProperty(), configure_generator_for_16_bit_indexes) # CHECK-LABEL: UncompressableProperty, 16-bit indexes @@ -130,7 +132,7 @@ test_trie_generation(UncompressableProperty(), # gyb will print line markers after our output, so make sure that those # don't accidentally match any other CHECK lines. -print 'THE END' +print('THE END') # CHECK-LABEL: THE END }% diff --git a/www/Examples.rst b/www/Examples.rst deleted file mode 100644 index 101860c2909ad..0000000000000 --- a/www/Examples.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. @raise litre.TestsAreMissing -.. _Examples: - -Example Swift Programs -====================== - -A collection of small apps that show various things. - - -uniq(1) -------- - -Why not? - diff --git a/www/FAQ.rst b/www/FAQ.rst deleted file mode 100644 index e659571e1f5e7..0000000000000 --- a/www/FAQ.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. @raise litre.TestsAreMissing -.. _FAQ: - -Frequently Asked Questions about Swift -====================================== - -Obviously many more questions can be added. - - - -Do you plan to rewrite the Swift compiler in Swift? ---------------------------------------------------- - -Not in the short term. C++ is a very pragmatic language for implementing -compilers, since it has good performance characteristics and allows higher-level -programming idioms than C. - -That said, we do expect Swift to be a better language than C++ in a number of ways, -so why don't we implement the compiler itself in Swift? There are a couple of -reasons that bootstrapping is not a good idea, at least in the short term: - - * This complicates bringup of the compiler, because you have to move both the - compiled language and the compiler at the same time as the language evolves. - * We want the language evolution and direction to be driven by general purpose - programming challenges, not by the specific needs of compiler hackers. The - urge to "scratch our own itch" might be too great. - -That said, we are writing the runtime library in Swift itself. We may also -decide to rewrite the compiler in Swift sometime in the distant future when the -language settles down. At that point, it may be a good opportunity to revisit -previous (internal to the compiler) design decisions, and we do expect and hope -Swift to be a great language for doing many things, including implementing -compilers. - - -Won't the design and evolution of Swift be warped by being too C++-centric? ---------------------------------------------------------------------------- - -This is a common question from Objective-C programmers, primarily those who -really dislike C++. For many reasons you can have hope that Swift -will end up being a great "successor to Objective-C" instead of a "C++ -replacement": - - * The compiler team has expert-level knowledge of Objective-C (the language), - having implemented the compiler for it from the ground-up. We probably know - its dark corners better than anyone. - * The Swift team has broad experience with a number of other programming - languages, including C/C++/Objective-C, Python, Haskell, Java, JavaScript, - C#, ... - * We know C++ well enough to not want to repeat its mistakes. - - -It turns out that there are a lot of reasons to dislike C++, and those people -who spend a lot of time writing C++ code are some of the most expert people at -explaining its varied faults. Don't consider use of C++ to be the same as -"love" for it. :) - diff --git a/www/LanguageFeatures.rst b/www/LanguageFeatures.rst deleted file mode 100644 index e2f6f739a55d1..0000000000000 --- a/www/LanguageFeatures.rst +++ /dev/null @@ -1,8 +0,0 @@ -.. @raise litre.TestsAreMissing -.. _LanguageFeatures: - -Swift Language Features -======================= - - -Highlight some of the hotness. diff --git a/www/Makefile b/www/Makefile deleted file mode 100644 index 8998fb12d9c2e..0000000000000 --- a/www/Makefile +++ /dev/null @@ -1,155 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -W -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -all: html - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/lld.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/lld.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/lld" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/lld" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/www/Philosophies.rst b/www/Philosophies.rst deleted file mode 100644 index 854b8ec62b397..0000000000000 --- a/www/Philosophies.rst +++ /dev/null @@ -1,121 +0,0 @@ -.. @raise litre.TestsAreMissing -.. _Philosophies: - -Pervasive Philosophies Guiding the Swift Language Design -======================================================== - -These are just notes, in no particular order. - -Don't Repeat Yourself ---------------------- - -Eliminate semicolons, header files, type annotations, @ signs, make properties -simple, etc. - -Expressive APIs ---------------- - -Beyond repetition, it is important to be able to express intent without getting -bogged down in unnecessary syntax. This really drives at being able to define -expressive APIs, which can be used cleanly and consistently. The goal for -Swift is not to be more expressive than C++ or Objective-C, it is to be more -expressive than Ruby, Python, or Javascript. - -Closures, multiple return values, generics, features for large-scale design -(stolen from ObjC), etc. - -Strong Conventions and Consistency ----------------------------------- - -We want strong "coding conventions", including naming, indentation, etc like -Objective-C and Java. It would be great to have a code reformatter like Go -that everyone uses that has no options :). - -Batteries Included ------------------- - -Standard library should be useful out of the box, with functionality comparable -to popular scripting languages. This includes a variety of "unix level" -functionality as well as basic data-types. - -Familiarity to Programmers in the C Family of Languages -------------------------------------------------------- - -"Semicolon and curly brace" languages are very popular, including C, -Objective-C, C++ etc, but also Java, Javascript, Ruby, and many other languages. -For this reason, we want the basic expression and statements in Swift to be -similar to these languages and/or an obvious small leap over them when it makes -sense. - -This is why we don't want to use python-style indentation rules, for example. - -We do deviate when there is a strong reason to do so. The C declarator syntax -is a complete disaster (write the prototype for 'signal' with no typedefs), so -we must change it. - -Innovation is not a Goal Unto Itself ------------------------------------- - -Being different from all other languages is not a goal. Language design -is not a new field. It is better to borrow good, proven, ideas from other -languages than it is to be novel in areas that don't need to change. This -is pragmatic language implementation, not open-ended language research. - - -Portability ------------ - -Swift code should be portable across architectures (unless "unsafe" -functionality is used) and it should be possible to port the swift compiler -and runtime to run on multiple OS's. - -Safe By Default ---------------- - -Memory safe, but also correct defaults. Not expose something as public API by -default. - - -Performance ------------ - -Swift is intended for systems programming, and performance matters at every -level (inefficiencies multiply their factors in large systems). Swift does -"spend" performance, but only when we get something for it. This is C++'s -"only pay for what you use" concept. - -Safety is something that we're willing to spend performance on. It implies: - - * array bounds checks - * no undefined behavior - * automatic memory management - -However, you can disable these and can use completely unsafe facilities if you -want (including malloc and free!). - -The second part of performance is being able to have a simple mental model when -you're programming, to understand what the cost is. It is ok that protocols are -completely dynamically dispatched (and thus "slow"), because you can avoid them -if that's not acceptable for your application. - -We implemented the compiler optimizer too, so we have realistic expectations of -what it can do and what it can be reasonably expected to do. We don't want to -rely on a "sufficiently smart" (that will never realistically happen) compiler -optimizer for basic sanity. - - -Designed for Support System-Level Programming ---------------------------------------------- - -Statically compiled, runtime checks for safety can be turned off, -performance, no garbage collector required, and light runtime. - - -Designed for a Modern Context ------------------------------ - -Learn from many examples, assume robust compiler optimization based on LLVM (but -expect realistic things, not magic), assume 64-bit targets will be the main -audience (so int being 64-bits is fine). - - diff --git a/www/_static/favicon.ico b/www/_static/favicon.ico deleted file mode 100644 index 724ad6e12dd40..0000000000000 Binary files a/www/_static/favicon.ico and /dev/null differ diff --git a/www/_static/swift.css b/www/_static/swift.css deleted file mode 100644 index 826b89b23a536..0000000000000 --- a/www/_static/swift.css +++ /dev/null @@ -1,77 +0,0 @@ -/* Common styles */ -.body { color: black; background: white; margin: 0 0 0 0 } - -/* No borders on image links */ -a:link img, a:visited img { border-style: none } - -address img { float: right; width: 88px; height: 31px; } -address { clear: right; } - - -table { border: 2px solid black; - border-collapse: collapse; margin-top: 1em; margin-left: 1em; - margin-right: 1em; margin-bottom: 1em; } -tr, td { border: 2px solid gray; padding: 4pt 4pt 2pt 2pt; } -th { border: 2px solid gray; font-weight: bold; font-size: 105%; - background: url("http://llvm.org/img/lines.gif"); - font-family: "Georgia,Palatino,Times,Roman,SanSerif"; - text-align: center; vertical-align: middle; } - - -/* Common for title and header */ -h1, h2 { - color: black; background: url("http://llvm.org/img/lines.gif"); - font-family: "Georgia,Palatino,Times,Roman,SanSerif"; font-weight: bold; - border-width: 1px; - border-style: solid none solid none; - text-align: center; - vertical-align: middle; -/* padding-left: 0pt;*/ - padding-top: 1px; - padding-bottom: 2px -} - - -h1 { - text-align: center; font-size: 22pt; - margin: 20pt 0pt 0pt 0pt; -} - -.doc_title, .title { text-align: left; font-size: 25pt } - -h2, .doc_subsection { width: 100%; - text-align: left; font-size: 12pt; - padding: 4pt 4pt 4pt 4pt; - margin: 1.5em 5em 0.5em 0em -} - -h3 { - margin: 2.0em 0.5em 0.5em 0em; - font-weight: bold; font-style: oblique; - border-bottom: 1px solid #999999; font-size: 12pt; - width: 75%; - clear:both; -} - -body p { - margin: 1em 0pt 0pt 15pt; -} - - -pre.grammar, pre.stdlib { - background: #FFFFE0; - padding: 1em 0 0 0; -} - -pre.example { - background: #F0F0F0; - padding: 1em 0 0 0; -} - -.commentary { - float: right; - width: 33%; - background: #C0C0FF; - padding: 1em 1em 1em 1em; - margin: 0em 0em 0em 1em; -} diff --git a/www/conf.py b/www/conf.py deleted file mode 100644 index 1472a0591022b..0000000000000 --- a/www/conf.py +++ /dev/null @@ -1,251 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Swift documentation build configuration file. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Swift' -copyright = u'2012, LLVM Project' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '3.2' -# The full version, including alpha/beta/rc tags. -release = '3.2' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -today_fmt = '%Y-%m-%d' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -show_authors = True - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'friendly' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'haiku' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ["."] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -html_favicon = 'favicon.ico' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -html_last_updated_fmt = '%Y-%m-%d' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {'index': 'indexsidebar.html'} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Swiftdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'Swift.tex', u'Swift Documentation', - u'LLVM project', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'Swift', u'Swift Documentation', - [u'LLVM project'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'Swift', u'Swift Documentation', - u'LLVM project', 'Swift', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - - -# FIXME: Define intersphinx configration. -intersphinx_mapping = {} - - -# -- Options for extensions ---------------------------------------------------- - -# Enable this if you want TODOs to show up in the generated documentation. -todo_include_todos = True diff --git a/www/index.rst b/www/index.rst deleted file mode 100644 index 2ebf82d7c0241..0000000000000 --- a/www/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. @raise litre.TestsAreMissing -.. _index: - -Index -===== - -.. toctree:: - :maxdepth: 1 - - Nothing here yet

The type being annotated must be materializable. - The type after annotation is never materializable. + The type after annotation is never materializable.